Skip to main content
franck23
Associate III
April 27, 2016
Question

I2C Stop after Address

  • April 27, 2016
  • 2 replies
  • 1657 views
Posted on April 27, 2016 at 13:45

Hello,

I am trying to handle I2C bus errors on the master side => get the I2C bus working again after detecting an error. (MCU: STM32F407) In the following test, the master send an Address + Read command to a none existing slave address. The firmwaredetect the none responding slave with a 20us time-out and try to reset the bus. But after trying several methods to reset the bus, I always get the same problem: Next time I try an Address + Read, the master send a stop condition mediately after the Slave NACK (or ACK if the slave is connected) Any idea on what could get the master to send a stop condition after sending an address? I tried to disable the stop condition just before sending the address, no change. Thanks!


/* Start condition */

I2C_GenerateSTART(I2Cx, ENABLE);

while
(!I2C_CheckEvent(I2Cx, I2C_EVENT_MASTER_MODE_SELECT));


/* Address + Read */

I2C_Send7bitAddress(I2Cx, Addr, I2C_Direction_Receiver);


/* Wait for Slave ack or time-out */

Tempo_StartTimeOut(WAIT_ACK);

while
(!I2C_GetFlagStatus(I2Cx, I2C_FLAG_ADDR))

{

if
(Tempo_IsTimeOut())

{

(
void
)(I2Cx->SR1); 
// Clear ADDR flag

(
void
)(I2Cx->SR2);

ResetBus();

return
false
;

}

}

#i2c-error-handling
This topic has been closed for replies.

2 replies

Walid FTITI_O
Visitor II
April 27, 2016
Posted on April 27, 2016 at 17:31

Hi Franck80,

I invite to check this limitation in the

http://www2.st.com/content/ccc/resource/technical/document/errata_sheet/7d/02/75/64/17/fc/4d/fd/CD00190pdf/files/CD00190pdf/jcr:content/translations/en.CD00190pdf

:

2.4 Wrong behavior of I2C peripheral in master mode after a misplaced Stop

-Hannibal-

Hello,

I am trying to handle I2C bus errors on the master side => get the I2C bus working again after detecting an error. (MCU: STM32F407) In the following test, the master send an Address + Read command to a none existing slave address. The firmwaredetect the none responding slave with a 20us time-out and try to reset the bus. But after trying several methods to reset the bus, I always get the same problem: Next time I try an Address + Read, the master send a stop condition mediately after the Slave NACK (or ACK if the slave is connected) Any idea on what could get the master to send a stop condition after sending an address? I tried to disable the stop condition just before sending the address, no change. Thanks!


/* Start condition */

I2C_GenerateSTART(I2Cx, ENABLE);

while
(!I2C_CheckEvent(I2Cx, I2C_EVENT_MASTER_MODE_SELECT));


/* Address + Read */

I2C_Send7bitAddress(I2Cx, Addr, I2C_Direction_Receiver);


/* Wait for Slave ack or time-out */

Tempo_StartTimeOut(WAIT_ACK);

while
(!I2C_GetFlagStatus(I2Cx, I2C_FLAG_ADDR))

{

if
(Tempo_IsTimeOut())

{

(
void
)(I2Cx->SR1); 
// Clear ADDR flag

(
void
)(I2Cx->SR2);

ResetBus();

return
false
;

}

}

franck23
franck23Author
Associate III
April 28, 2016
Posted on April 28, 2016 at 04:47

Hi Hannibal,

Thanks for the answer.

A similar limitation is present on the STM32F407.

In my case there is no misplace stop, the stop is generated by the master after sending the address and receiving an ack or a nack.

However, I did found the problem.

I have the I2C DMA enable. The DMA is only used to send and receive data, but it seems that it is still doing something when the address is sent, not sure why...

The solution is to disable and re-enable the I2C DMA when a bus exception happens, even if the error happens before receiving/sending any data.

Franck.