Skip to main content
added 1256 characters in body
Source Link
danmcb
  • 7.9k
  • 19
  • 36

I2C frames each group of message bytes in START and STOP conditions, defined as SDA changing state 1>0 or 0>1 (respectively) while SCL is high, as described here.

I am writing interrupt driven handlers for PIC32MX170, and I got quite far using the STOP bit as the signal to the software that the message is done. This then allows for things like checking the rx/tx byte count and so on. I found testing the STOP flag in software to be quite reliable, with the combination of hardware and clock that I used.

However, I now discover that it is not reliable at all : either using a faster clock or slower driver means that the ISR can exit and miss the STOP bit completely. Worse, as the next byte will be START of a new message, there is no way to know if it ever arrived (unless you sit there polling the bus, which is not really the kind of thing I want in an ISR, even with timeout).

However, code that depends on flaky combinations of hardware and clocks is also pretty bad, so I am facing a redesign that assumes STOP bits to be unreliable (luckily I don't try to do variable byte counts).

(Some uC's always raise an interrupt on STOP, but unfortunately not this one, as far as I can tell.)

But this raises the question : should an ISR wait on the STOP bit? If so, for how long? Is there anything in the spec about this?

EDIT: I am adding some information, as perhaps I did not express myself completely clearly in my original. My question was really about the means of detecting the message start and stop, which of course is essential. (We have some discussion below about related matters such as where in the code the decoding is done - also very valuable but not what I was asking.)

The issue is basically that, although START and STOP (S and P) conditions (actually the status bits that signal them on the device) are not always set when the ISR runs, even though this might be the last time for the message. (There is also the question of whether the ISR needs to look at those bits, which I think is more about system design, but also interesting and relevant.)

As well as S/P flags, there are also flags which tell you what kind of byte you just received: Address R/W and Data R/W. Address Write always signals the start of a message. After this point a certain structure must be observed, which may involve repeated S conditions and so on. Depending on how you design your message protocol (especially whether you support variable length or not) these can also be used to understand the structure of the message. This is what the question is about.

I2C frames each group of message bytes in START and STOP conditions, defined as SDA changing state 1>0 or 0>1 (respectively) while SCL is high, as described here.

I am writing interrupt driven handlers for PIC32MX170, and I got quite far using the STOP bit as the signal to the software that the message is done. This then allows for things like checking the rx/tx byte count and so on. I found testing the STOP flag in software to be quite reliable, with the combination of hardware and clock that I used.

However, I now discover that it is not reliable at all : either using a faster clock or slower driver means that the ISR can exit and miss the STOP bit completely. Worse, as the next byte will be START of a new message, there is no way to know if it ever arrived (unless you sit there polling the bus, which is not really the kind of thing I want in an ISR, even with timeout).

However, code that depends on flaky combinations of hardware and clocks is also pretty bad, so I am facing a redesign that assumes STOP bits to be unreliable (luckily I don't try to do variable byte counts).

(Some uC's always raise an interrupt on STOP, but unfortunately not this one, as far as I can tell.)

But this raises the question : should an ISR wait on the STOP bit? If so, for how long? Is there anything in the spec about this?

I2C frames each group of message bytes in START and STOP conditions, defined as SDA changing state 1>0 or 0>1 (respectively) while SCL is high, as described here.

I am writing interrupt driven handlers for PIC32MX170, and I got quite far using the STOP bit as the signal to the software that the message is done. This then allows for things like checking the rx/tx byte count and so on. I found testing the STOP flag in software to be quite reliable, with the combination of hardware and clock that I used.

However, I now discover that it is not reliable at all : either using a faster clock or slower driver means that the ISR can exit and miss the STOP bit completely. Worse, as the next byte will be START of a new message, there is no way to know if it ever arrived (unless you sit there polling the bus, which is not really the kind of thing I want in an ISR, even with timeout).

However, code that depends on flaky combinations of hardware and clocks is also pretty bad, so I am facing a redesign that assumes STOP bits to be unreliable (luckily I don't try to do variable byte counts).

(Some uC's always raise an interrupt on STOP, but unfortunately not this one, as far as I can tell.)

But this raises the question : should an ISR wait on the STOP bit? If so, for how long? Is there anything in the spec about this?

EDIT: I am adding some information, as perhaps I did not express myself completely clearly in my original. My question was really about the means of detecting the message start and stop, which of course is essential. (We have some discussion below about related matters such as where in the code the decoding is done - also very valuable but not what I was asking.)

The issue is basically that, although START and STOP (S and P) conditions (actually the status bits that signal them on the device) are not always set when the ISR runs, even though this might be the last time for the message. (There is also the question of whether the ISR needs to look at those bits, which I think is more about system design, but also interesting and relevant.)

As well as S/P flags, there are also flags which tell you what kind of byte you just received: Address R/W and Data R/W. Address Write always signals the start of a message. After this point a certain structure must be observed, which may involve repeated S conditions and so on. Depending on how you design your message protocol (especially whether you support variable length or not) these can also be used to understand the structure of the message. This is what the question is about.

Source Link
danmcb
  • 7.9k
  • 19
  • 36

how long should an I2C slave wait for a STOP bit (if at all)?

I2C frames each group of message bytes in START and STOP conditions, defined as SDA changing state 1>0 or 0>1 (respectively) while SCL is high, as described here.

I am writing interrupt driven handlers for PIC32MX170, and I got quite far using the STOP bit as the signal to the software that the message is done. This then allows for things like checking the rx/tx byte count and so on. I found testing the STOP flag in software to be quite reliable, with the combination of hardware and clock that I used.

However, I now discover that it is not reliable at all : either using a faster clock or slower driver means that the ISR can exit and miss the STOP bit completely. Worse, as the next byte will be START of a new message, there is no way to know if it ever arrived (unless you sit there polling the bus, which is not really the kind of thing I want in an ISR, even with timeout).

However, code that depends on flaky combinations of hardware and clocks is also pretty bad, so I am facing a redesign that assumes STOP bits to be unreliable (luckily I don't try to do variable byte counts).

(Some uC's always raise an interrupt on STOP, but unfortunately not this one, as far as I can tell.)

But this raises the question : should an ISR wait on the STOP bit? If so, for how long? Is there anything in the spec about this?