2016-04-25 06:27 AM
We're currently talking to a few I2C devices on the same bus using latest STM32F7 HAL drivers.
All works fine for a while (minutes or hours) and the bus debug on our scope looks perfect, however, every so often we have a strange ''bug'' where the I2C read appears to get out of sync with what we see on the scope.Once in this mode, all subsequent device reads become corrupted.eg.When communication is all good, this is typical write/read sequence:Write 0 to IO expander to tell it we want to read port 0Read 0x40 backWrite 1 to expander for port 1Read 0x02 backAfter the intermittent bug happens all reads are like this:Write 0 to IO expander to tell it we want to read port 0Read 0x00 backWrite 1 to expander for port 1Read 0x40 back (the number which should have been in the RXDR read register on the previous read)The BUS on our scope still look fine, it's as though there is an I2C read buffer which has got it's pointers mixed up.We've made sure not to make any calls to I2C inside an ISR and aren't using an RTOSAny thoughts on what might cause this or how to recover from it ? #i2c #stm32f72016-04-26 03:41 AM
Hi teal.andy,
When the problem occurs, are there any I2C error flags set?-Mayla-To give better visibility on the answered topics, please click on Accept as Solution on the reply which solved your issue or answered your question.
2016-04-26 06:34 AM
No errors returned. we wait in a retry loop now for HAL_I2C_Master_Transmit and HAL_I2C_Master_Receive to return HAL_OK.
Changing the code to this did not make any difference.We've just managed to trace the i2c messages before the glitch happens and there appears to be an additional read 1 byte which is causing a problem - this read is not in our code and seems to happen autonomously. The device we are talking to is a touchscreen, not the IO expandereg:1. write 2 bytes to device to pick register to read2. read 1 byte3. if that byte has bit 7 set (touch pressed), then: 4. read 5 more bytes (touch position)when the problem occured we saw a very long delay (6.5ms) after step 2 and getting to step 4 on the scope (normally the 4 steps happen one after the other).At step 4 we saw a spurious single byte read, followed by the 5 byte read that should have happened...It looks like the slave device is doing what it's told but the STM is inserting a byte read when it isn't asked to do so.Really hope you can help us debug and fix this problem.Are there any recent updates to the HAL library related to I2C ?ThanksAndy2017-01-12 02:36 AM
For anyone else who has this problem it would appear that itif the HAL I2C call fails with not HAL_OK then you need to re-initialize the peripheral in HAL.
I found this code in the latest HAL examples for STM32L476 disco (stm32l476g_discovery.c) ... we had already done something similar ourselves to re-read or ignore the readings when they get out of sync.
Just a note that this problem appears much more frequently if you have a lot of interrupts happening from inputs, DMA's and timers - maybe there is a bug in the HAL somewhere whichcorruptsthe I2Ccode when jumping in and out constantly?
static HAL_StatusTypeDef I2C1_WriteBuffer(uint16_t Addr, uint16_t Reg, uint16_t RegSize, uint8_t *pBuffer, uint16_t Length)
{
HAL_StatusTypeDef status = HAL_OK;
status = HAL_I2C_Mem_Write(&I2c1Handle, Addr, (uint16_t)Reg, RegSize, pBuffer, Length, I2c1Timeout);
/* Check the communication status */
if(status != HAL_OK)
{
/* Re-Initiaize the BUS */
I2C1_Error();
}
return status;
}�?�?�?�?�?�?�?�?�?�?�?�?�?
static void I2C1_Error (void)
{
/* De-initialize the I2C communication BUS */
HAL_I2C_DeInit(&I2c1Handle);
/* Re- Initiaize the I2C communication BUS */
I2C1_Init();
}�?�?�?�?�?�?�?�?
2017-11-14 10:25 AM
Thanks for this.
This seems to be the same issue being discussed in
.