cancel
Showing results for 
Search instead for 
Did you mean: 

HAL_I2C_GetError() reporting error codes

KGryn.1
Associate II
Hello,
 
We have noticed communication errors with STM32 that is working in our device. The device includes STM32 (master) and TI's battery monitor BQ76952 (slave).
Using the same device and same software we noticed three situations that occur randomly:
  1. After boot write commands are not returning any errors and further communication is correct.
  2.  After boot few initial write commands are returning error and further communication is correct. However, we have noticed that some devices lost communication after longer perdiod (for example two months) and we don't know what is the reason for it. Only after rebooting STM32 communication is correct.
  3. Sometimes after boot few initial write commands are returning error and I2C peripheral locks up. In such a case all communication is failing. Only after rebooting STM32 communication is correct.
HAL_I2C_GetError() reports following error codes: 0x02 (ARLO), 0x04 (ACKF).
There are only two devices on I2C bus: stm32 (master), bq76952 (slave). I2C has 100 kHz clock. We're using HAL library for I2C communication.
It happens in two different configurations with STM32L432 and STM32G0B1.
 
Looking forward to your reply.
10 REPLIES 10

> Apart from the pull-ups value can you estimate difference and disadvantages of sending more than 9 clock pulses at the beginning of the transmission?

The idea behind this is, that if SDA is blocked, that's a slave amidst a read (i.e. slave transmits) - and 9 pulses should ensure the slave transmits the whole byte and then sees a NACK from the released SDA, which results it stop the read. However, there are various deviant I2C slave implementations, as well as situations like slave is amidst an ACK to write (in which case blindly issuing 9 pulses will bring it to just another ACK), and various situations resulting in faulty behaviour of multiple devices on the bus.

So the real goal here should be to achieve free bus (i.e. both SDA and SCL high), and then issue a STOP, upon which all conforming slaves should reset their internal state machine. Assuming relatively sane slaves, this may happen sooner than but not later than in 9 pulses, so the correct description is, issue up to 9 pulses, and as soon as the bus is free, issue a STOP.

If SCL is blocked (and it's not temporary due to slave stretching clock), all chances are off and the only way to release bus is to reset the slaves, either through reset pin provided they have one, or through power cycle.

> As a workaround we are toggling PE bit to 0 and back to 1 if we detect transmission error and BUSY flag is still set after transmission. Is any disadvantages could be caused by this method?

This and this may be a problem with this in the I2Cv2 (I2Cv1 as in 'F1..'F4 has a different set of issues).

JW