2016-04-27 04:45 AM
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
2016-04-27 08:31 AM
Hi Franck80,
I invite to check this limitation in the
:
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
;
}
}
2016-04-27 07:47 PM
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.