Shop OBEX P1 Docs P2 Docs Learn Events
PBASIC I2C protocol issue — Parallax Forums

PBASIC I2C protocol issue

I've been tearing my hair out for two weeks over this one. I'm using the BASIC Stamp 2pe to get data from a sensor that communicates via I2C. I was getting really sporadic results from it for no apparent reason. The sensor manufacturer was at a loss to explain what was happening. Signals were clean, timing was spot-on, no noise or sags, and the device was behaving normally, except that it was returning mostly zeroes instead of good data.

So I connected the device to a Propeller and wrote some I2C methods to access it. 'Got perfect data! What was the difference? My Spin routines always send a NAK after the last byte read in a sequence. The BS2pe ACKs after every byte read, including the last one, which goes against the I2C spec. Now most I2C devices don't care, since the subsequent STOP condition resets the protocol engine anyway. But when I changed my Spin code to ACK after the last byte, the device behaved as it did with the BS2pe. So I guess, with some devices the ACK/NAK situation does matter.

I've gone ahead and hand-coded some I2C routines in the BS2pe, and now I get good data with that chip as well. But I'm curious as to why the BS2pe's hard-coded I2C routines do not NAK the last byte read.

-Phil

Comments

  • It sounds like a bug in the basic stamp. Can you confirm with a scope that a valid STOP is seen under these conditions? If the next byte is coming out from the sensor due to the ACK and is holding SDA low, then perhaps the STOP is not seen?
  • That's a really good question. I'll have to check that tomorrow.

    -Phil
  • KeithE wrote: »
    It sounds like a bug in the basic stamp. Can you confirm with a scope that a valid STOP is seen under these conditions? If the next byte is coming out from the sensor due to the ACK and is holding SDA low, then perhaps the STOP is not seen?

    I'm curious about that too. If the SCL signal is cycled far enough, then I can imagine what KeithE said is a possibility, but I don't remember if the BASIC Stamp cycles it beyond the sample edge when delivering the ACK or not.

    The "NAK after the last byte is read" was a feature of I2C that was ambiguously written in the protocol spec when we reviewed it the first time, and even more recently (a couple years ago, I think), giving us the impression that it was truly optional and only perhaps necessary if you want the slave device to know that it can switch to a low-power mode again (or something like that). We hadn't seen any problems with the I2C devices we had tested and used over the years.

    I didn't write the I2C routines in the BASIC Stamp firmware, but as it happens, I wrote an I2C object for the Propeller that defaults to ACK but later added an optional NAK after a read... I think because I wasn't sure if ACK would work in every case. I made it optional because I was concerned about cycle time in that example and it takes extra effort from a routine to check for and indicate it's reading the last byte in a sequence.


  • If a PBASIC bug, it's been a long time lurking. Do you want to say what sensor it is? I know from our pm, but it is not a common one that I have here to try out.

    I hope you have hair left, not all yet torn out!
  • In the BS2pe, I2CIN leaves SCL high after its last ACK, then lets go of SDA for the STOP condition. As a consequence, the slave device does not see a low on SCL, which would enable it to impose a bit on SDA. So that's not the issue.

    The problem I was having seems to be a combination of two issues:

    1. The BS2pe's ACK after the last byte, and

    2. The slave device expecting another byte read as a consequence and not resetting its protocol engine after a legitimate STOP.

    -Phil
  • Guys,

    All I2C data transactions are 8-bit and require 8 clocks. After the 8th clock, the master sends a 9th clock in which time the slave has the opportunity to respond with a NACK/ACK.

    This 9th clock is part of the I2C spec and is mandatory.

    The master does not "send" a NACK/ACK on the SDA line.

    During the time of the 9th clock, SDA (which is supposed to be a bi-directional line) should sample and detect the slave's NACK/ACK.

    Check out page 10 (3.6 Acknowledge...) of the attached I2C spec.

    DJ
  • Phil Pilgrim (PhiPi)Phil Pilgrim (PhiPi) Posts: 23,514
    edited 2016-09-27 20:54
    Dave James wrote:
    The master does not "send" a NACK/ACK on the SDA line.
    Not true. The device that's receiving bytes -- master or slave -- sends the ACK/NAK. So when the master is receiving bytes from the slave device, the master has to assert ACK or NAK on the ninth bit.

    -Phil
  • > The master does not "send" a NACK/ACK on the SDA line.
    >Check out page 10 (3.6 Acknowledge...) of the attached I2C spec.

    If the master is reading data from a slave then it is the receiver, then it is therefore master's responsibility to send the ACK/NACK for each byte. If the master is writing data, then the slave is the receiver and it is the slave's responsibility.

    Regarding the NACK, it seems pretty well spelled out in 3.6.

    "There are five conditions that lead to the generation of a NACK:
    ...
    5. A master-receiver needs to signal the end of the transfer to the slave transmitter."

    Based on what Phil says, it's my opinion that the Basic Stamp is violating the protocol, but most slaves can deal with it. I guess that the sensor in question isn't using I2C STOP to reset its protocol state machine from all states. When I last did an I2C slave I was always looking for I2C start/stop regardless of state. You want to make it as easy as possible for I2C masters to reset the bus in the event of an anomoly.

    BTW: as far as I know Rev. 6 — 4 April 2014 is the latest revision of the I2C specification. I'm not sure what changed as the revision history gets a bit vague. (There's also an I3C specification now, but that's from MIPI ;-)
  • Tracy AllenTracy Allen Posts: 6,664
    edited 2016-09-28 16:06
    i think the main fault/bug lies with the device in this case, less so on the BS2. Correct handling of Stop and Start conditions Is the prime directive of i2c, and the spec takes the trouble to point out how some devices do it easily in hardware, however, orhers that implement i2c in microcode on a uP have to sample/poll fast enough to always detect those conditions. True they should handle the NACK on a read, but they should always and unconditionally abort and reset on Stop.

  • KeithEKeithE Posts: 957
    edited 2016-09-28 20:11
    Based on what Phil said, the only reason that the BS2 hasn't had problem with more I2C slaves, it's that it's not sending the 9th SCL pulse as defined in the I2C specification. I haven't seen any documentation that this is an option, so it appears to be a protocol violation. If it were sending a complete rising/falling clock pulse, then not sending the NACK would have been disasterous. This is because the slave would be driving out another data byte, and a zero data bit would prevent the STOP condition from being sent by the master.

    Also a statement from an NXP data sheet (SC16IS740/750/760 I2C UART):

    "There are two exceptions to the ‘acknowledge after every byte’ rule. The first occurs when a master is a receiver: it must signal an end of data to the transmitter by not signalling an acknowledge on the last byte that has been clocked out of the slave. The acknowledge related clock, generated by the master should still take place, but the SDA line will not be pulled down. In order to indicate that this is an active and intentional lack of acknowledgement, we shall term this special condition as a ‘negative acknowledge’.

    The second exception is that a slave will send a negative acknowledge when it can no longer accept additional data bytes. This occurs after an attempted transfer that cannot be accepted."
    838 x 285 - 49K
Sign In or Register to comment.