cancel
Showing results for 
Search instead for 
Did you mean: 

Stm32L4: I2C: Slave transmitter: How to check for end of transmission ?

FKaes.1
Associate II

Hello,

at I2C slave transmission, the master stops the communication with a NACK and some µseconds later followed by a STOP.

If my slave uC is slowly clocked this works. The calling of the I2C Irq handler takes enough time, to see NACK and STOP at the same time. In that case, I know that it is an expected behaviour and the NACK isn't an error.

My question is, if I run the uC at full speed, I assume there is the risk, that the slave will see only NACK, because the stop event is still not detected. Then slave would handle it wrongly as an error.

 

FKaes1_0-1735816940819.png

 

Therefore, I assume checking for NACK + STOP isn't 100% correct ?
Are there other options ?
E.g. I'm using DMA, so could I used NACK + (DMA.counter == 0) ?

1 ACCEPTED SOLUTION

Accepted Solutions

> How the slave knows, that the NACK on the 4th byte is ok, but a NACK on the 3rd byte would be an error ?

If you are using DMA, look at NDTR to find out how many bytes have been sent. If all bytes are sent, it will be 0. If you are using interrupts, you should be keeping track each time you send a byte.

On the STM32 side, a NACK anywhere will set the NACK flag. It's up to you to interpret if it's acceptable or not.

> I like to avoid busy waiting for a STOP in the I2C irq.

So don't. STOP will trigger an interrupt (if STOPIE is set). You can handle the transaction cleanup there.

> Because in my case, after a NACK a STOP is always expected.

If you don't use repeated start, waiting for STOP is sufficient. You can check the NACK flag there if needed. In that case you should disable the NACK interrupt (NACKIE=0)

If you feel a post has answered your question, please click "Accept as Solution".

View solution in original post

3 REPLIES 3
TDK
Guru

You should check for NACK or STOP. Either one signifies the end of the transaction. If NACK happens, no need to wait around for STOP to occur to clean up. Since STOP always happens (barring repeated STARTs), eventually, you could also just wait for that, but sometimes handling NACK can be informative, for example if the master terminates the transaction sooner than expected.

> My question is, if I run the uC at full speed, I assume there is the risk, that the slave will see only NACK, because the stop event is still not detected. Then slave would handle it wrongly as an error.

You say above you know NACK is not an error. How is the slave handling it as an error here? I don't see a risk here.

 

If you feel a post has answered your question, please click "Accept as Solution".
FKaes.1
Associate II

Hello,

e.g. if 4 bytes are transmitted, byte 1,2 and 3 are ACKed and byte 4 is NACKed by the master. I want to know, if all 4 bytes were transmitted on slave side. How the slave knows, that the NACK on the 4th byte is ok, but a NACK on the 3rd byte would be an error ?

Because slave isn't using NBYTES. And I2C_ISR->TC is set only for master.

I like to avoid busy waiting for a STOP in the I2C irq. Because in my case, after a NACK a STOP is always expected. I don't use repeated start.

DMA is used. I will try to use DMA flags to avoid busy waiting.

e.g.

 - if a NACK is received by the slave, and DMA.TC isn't set and DMA.counter is 1, then I know only 3 of 4 bytes were transmitted. => error

- if a NACK is received by the slave, and DMA.TC is set and DMA.counter is 0, then I know all bytes were transmitted. => no error

 

 

 

 

> How the slave knows, that the NACK on the 4th byte is ok, but a NACK on the 3rd byte would be an error ?

If you are using DMA, look at NDTR to find out how many bytes have been sent. If all bytes are sent, it will be 0. If you are using interrupts, you should be keeping track each time you send a byte.

On the STM32 side, a NACK anywhere will set the NACK flag. It's up to you to interpret if it's acceptable or not.

> I like to avoid busy waiting for a STOP in the I2C irq.

So don't. STOP will trigger an interrupt (if STOPIE is set). You can handle the transaction cleanup there.

> Because in my case, after a NACK a STOP is always expected.

If you don't use repeated start, waiting for STOP is sufficient. You can check the NACK flag there if needed. In that case you should disable the NACK interrupt (NACKIE=0)

If you feel a post has answered your question, please click "Accept as Solution".