cancel
Showing results for 
Search instead for 
Did you mean: 

Problem with I2C on STM32H7A3IIK6

Miglio
Associate II

Hi, i'm developing a project on STM32H7A3IIK6 [cortex M7] and i'm having a problem using the I2C peripheral with the ST HAL functions. I've initialized the peripheral and enabled the Event and Error Inpterrupt with TX and RX DMA and, sometimes, i have a problem when the HAL function "I2C_Mem_ISR_DMA" [placed in stm32h7xx_hal_i2c.c] is called. If the peripheral is locked [lock and unlock of the peripheral are managed by the HAL functions] the "I2C_Mem_ISR_DMA" always fails [is not able to clean the interrupt flag] and the interrupt handler [HAL_I2C_EV_IRQHandler] is not able to detect that the "I2C_Mem_ISR_DMA" is failing [resource locked] because its return value is not checked. I think it's a bug in the H7 package. Will it be fixed in a next revision?

15 REPLIES 15
S.Ma
Principal

I2C Master or Slave mode?

Miglio
Associate II

Master Mode

Miglio
Associate II

I have a problem using the I2C HAL functions [stm32h7xx_hal_i2c.c] with event and error interrupt enabled. If the function "HAL_I2C_Mem_Write_DMA" is called by the application task to enable the I2C write the I2C resource is locked and, after that, the TXDR register is written. Sometimes the data, written in the TXDR register, is sent before the resource unlock and so a new event interrupt is generated. When the new interrupt calls its handler the I2C resource is still locked and the handler is not able to serve the interrupt anymore.

I've noticed this problem porting an application firmware from F4 family to H7 family without changing the priority level for application task and I2C interrupt [in the F4 family there was not a check regarding the I2C lock state inside the interrupt handler]. Will it be fixed in a new version of the H7 firmware package?

Otherwise the only way to fix this problem is to have, for the I2C Event interrupt, a priority lower than the task which calls the write and read functions.

Nothing will be fixed unless you provide a good test project (small as possible, clear).

How an interrupt can be lower priority than a task?

Note that the HAL "locks" are not really locks. They are used only to check for reentrancy between thread and interrupt context code. If you want to use I2C from several RTOS tasks, this needs a real RTOS-level lock (or other sync method).

Miglio
Associate II

What do you mean for "good test project"? Sorry for the "lower", what i meant was that to fix this problem the solution is to give to the I2C Event interrupt a priority value of 5 or higher

Aha, then it is the well known trivia of FreeRTOS: if an interrupt handler calls a RTOS function, the interrupt priority must be lower (value greater) than a threshold parameter in the FreeRTOS config file. Maybe this threshold is different in your F4 and H7 projects.

>What do you mean for "good test project"?

https://stackoverflow.com/help/minimal-reproducible-example

> They are used only to check for reentrancy between thread and interrupt context code.

That was the intention, but in reality they do not provide even that, because they are broken.

https://community.st.com/s/question/0D50X0000C5Tns8SQC/bug-stm32-hal-driver-lock-mechanism-is-not-interrupt-safe

Miglio
Associate II

My problem is that the I2C hal, auto generated for the H7 device, is not "interrupt safe". In particular, sometimes, i have a problem when my "eeprom manager task" [the H7 MCU talks with an external EEPROM via I2C] calls the "HAL_I2C_Mem_Read_DMA".

This function makes the following actions :

  1. Locks the I2C handle
    1. Prepares the parameters for the transfer [like the function "I2C_Mem_ISR_DMA" to manage the transfer end]
    2. Writes the TXDR register
    3. Enables the I2C transfer calling the function "I2C_TransferConfig"
    4. Unlocks the handle.
    5. Enables the transmission interrupt [NEVER DISABLED BEFORE] with an internal commet which says that the interrupt must be enabled after the "unlock" to avoid the risk of an interrupt execution

Sometimes, after point 4, the TX I2C Event Interrupt is generated but, finding the resource locked, is not able to serve the interrupt request and so the interrupt will be generated forever blocking the device.

Why the interrupt, enabled in point 6, has never been disabled before?

To fix just this problem [the HAL I2C module is for sure "NOT INTERRUPT SAFE"] my idea is to modify the HAL I2C module [not the "LOCK/UNLOCK" macros]. Are you planning to fix the autogenerated HAL in order to make it "interrupt safe" or not? Is it possible to share with you the modification i'm talking about [really quite simple] to understand with you if you see any kind of other problems in this modification?