Skip to main content
Visitor II
May 21, 2024
Question

HAL_I2C_GetError() reporting error codes

  • May 21, 2024
  • 4 replies
  • 5110 views
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.
    This topic has been closed for replies.

    4 replies

    Super User
    May 21, 2024

    Have you used an oscilloscope to see what's happening on the wires? Also check that power supplies are clean & stable before attempting to start comms.

    KGryn.1Author
    Visitor II
    May 21, 2024

    Hello,

    Thank you for the reply.

    We'll do further electrical measurements and paste them later but from the previous measurements I remember no difference with the I2C electrical signal at the start (when problem occurs) and at the working system (when the problem does not occur).

    What can be done to make to disappear these  errors: 0x02 (ARLO), 0x04 (ACKF)? Or if it's not possible, how to unblock communication apart from restarting STM?

    STM and I2C communication is started only when 3.3V output is with active power good flag from power supply and there's a long delay (>1s) from the start of the power good signal to start the communication.

    The most common situation when these errors occurs is at the programming running setup: when the STM is forced to reset and I2C is running.

    Super User
    May 21, 2024

    On recovering from I2C errors:

    https://community.st.com/t5/stm32-mcus-products/stm32h745i-i2c-recovery-after-addressing-nonexistent-device/m-p/660263/highlight/true#M240602

     


    @KGryn.1 wrote:

    The most common situation when these errors occurs is at the programming running setup: when the STM is forced to reset and I2C is running.


    So you could be in the middle of an I2C transaction when this reset occurs? Could well "confuse" the slave...

     

    KGryn.1Author
    Visitor II
    May 21, 2024

    Thanks for the link: we tried this nine clock pulses tip some time ago but with no posotive results. 

    But we did implementation on our own - maybe it was faulty - do you have functional code with this I2C recovery method?

    Technical Moderator
    May 22, 2024

    Hello @KGryn.1 

     

    Did you add pull-up resistors to the SDA and SCL lines? The typical values are between 4.7kΩ and 10kΩ

    KGryn.1Author
    Visitor II
    May 22, 2024

    Hello,


    Today we continued testing and measurements.

    1. Yes there are pull-ups on SDA and SCL, we started testing with 10k and also lower values to the 4k7 with no difference.
    2. We noticed that slave pulls down SDA line to the GND at the reset from time to time (not at all resets). We implemented method with clock pulses prior to the HAL start. We noticed that nine clock pulses improves starting the communication (less errors) but we also tested more than 9 clock pulses: 20 pulses with better results. Is any disadvantage of sending more than 9 pulses or is there any upper limit? Both setups were with implementation of the start sequence and stop sequence. When 20 times is acceptable, we'll stay with it.
    3. HAL during normal operation has a problem with handling communication faults e.g. short between SDA and SCL (e.g. enviromental pollution between pull-ups). Do you have tips for handling this issue? 
    4. BTW - the slave IC (BQ) has external reset pin that we can't use because using it causes loosing some starting configuration that we can't loose - we checked it in tests.

    Regards

    Technical Moderator
    May 22, 2024

    Hello @KGryn.1 

    >HAL during normal operation has a problem with handling communication faults

    To recover I2C communication after encountering errors such as 0x02 (ARLO) or 0x04 (ACKF), you can perform an abort, de-initialization, and re-initialization of the I2C peripheral. This process will reset the I2C hardware block within the STM32 microcontroller and clear any error conditions, allowing you to attempt communication again.

    Super User
    January 13, 2025

    > 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