cancel
Showing results for 
Search instead for 
Did you mean: 

STM32L4: Two I2C Channels on same Bus - SCL stucks at ground until Timeout

And_reas
Associate II

Hello,

we have currently some issues where the I2C bus got stuck (SCL stuck and Ground) until the configured timeout (in the STM32L4) is reached. I was able to reproduce the issue quite often in a stress test setup.

 

Stress Test Setup description:

The STM32L4 uses two I2C Channels (Ch2 and Ch4), both as I2C Master in DMA mode on the same bus. In addition, there is an external I2C Master also on the same bus. 

As an stress test all I2C masters tries to send messages as fast as possible. From time to time, to bus got stuck (SCL stays at Ground) until the configured timeout (in the STM32L4 I2C) e.g. 5ms is reached. After the timeout is reached, everything works again.

Observation

The issue only occurs when both I2C channels of STM32 are active in parallel. For example, when using a software mutex, to make sure only one channel at the time is active, we dont see any issues.

In addition, when using a different I2C speed for the two STM32 I2C Channels (e.g. Ch2 in Fast Mode, Ch4 in FastPlus Mode) there are also no issues. Thus, the bus gets only stuck, when both channels run on the same speed and are active in parallel.

Background Info

- When increasing or decreasing the I2C timeout time in the STM32L4 I2C registers the time the bus stucks will also increase or decrease for the same duration. Thus, it seems that in fact the I2C peripheral of the STM32L4 blocks the bus.

- In the current implementation we use two I2C channels, because in general there are two seperat buses. Just in some scenarios there is an active bridge that connects both buses. 

Question

Since we dont see the issue happening with only one active I2C channel at time, we would like to know if there is any known issue, where the I2C bus gets stuck, when running two STM32 I2C channels on the same bus with the same speed?

 

 

9 REPLIES 9
Issamos
Lead II

Hello @And_reas 

I'm not aware of any specific known issues. I suggest you to use an oscilloscope to visualise real time values. That may help you discovering the issue.

Best regards.

II

LCE
Principal

I have only used the STM32 as a single master - I didn't even know I2C is multi master capable...

Just checked the www:

"If you plan to use a multimaster device on a bus it is essential that all masters are multimasters."

So does the STM32 I2C has settings for that, and did you activate that?

Hello @Issamos ,

I have used a logic anaylzer to record several measurements. Please note that for this measurement I changed the timeout value to 4 ms.

This images shows a lot of visible situations where we had an timeout occuring.

AlotOfTImeouts.png

Here, the bus got stuck during reading from an address. (First images shows the timeout -> SCL was kept low. Second images shows the zoom at the start)

BusGotStuck.pngBusGotStuck_Zoomed.png

In this image you see the same transmission than above, without an timeout:

RegularAccess.png

In some situations an already active Bus (accessed by the external I2C Master that runs in normal mode) got blocked by the STM32L4 for 4ms during an active transmission (First image shows start of transmission. Second image shows end of transmission):

StuckInsideClock.pngStuckInsideClock_End.png

When changing our firmware that only one I2C channel was active at a time - or that both channel uses a different speed, e.g. Fast Mode and FastPlus mode - the timeout where not observed (observation time: a few hours).

Best regards,

Andreas

Bob S
Principal

Since you mention using a mutex that you are using an RTOS.  In that case, you MUST use a mutex to prevent both I2C ports from trying to access the (single) I2C bus at the same time.  Though I am at a loss as to why you need 2 I2C ports connected to the same bus, instead of using a single I2C port and a mutex (which you need anyway) to allow multiple tasks to access the single port.

The ST HAL code checks to see if the bus is free before starting a transaction. But once it passes that check the code presumes it has exclusive access to that I2C bus FROM THIS CHIP.  Other, external I2C masters may be present, and if they start sending the address byte at then same time, the normal I2C arbitration will let one continue and the other will fail and have to retry later.  But with 2 bus maters on the same CPU, it is possible for the RTOS to switch to the other I2C task after that "bus free" check and before the I2C transaction starts.  The 2nd task then starts a transaction (and gets past the address byte), the RTOS switches back to the first I2C task and then it starts sending - thus corrupting the bus.

 

Hello @LCE,

according to the RM0394 for STM32L41xxx/42xxx/43xxx/44xxx/45xxx/46xxx, the I2C has Multimaster capabilities.

But I did not find any information, if they I2C peripheral can also two channels as master on the same bus.

 

In general, we will change the firmware any way in order that only one I2C channel is active at a time, since they share the hardware resource anyway. It would be just nice to have a conformation that this actually is the root issue.

BR,

Andreas

Hello @Bob S,

thanks for my feedback. That was also my guess and you are absolut right. We already changed the handling (in case the I2C Bridge is closed) to only have one active channel per chip. 
Ideally, I would get a conformation that this in fact is an issue.

We are using an autosar OS, but we also uses I2C in DMA mode and starting the transfer using enabling the interupts with LL_I2C_EnableIT_TC() function, followed by LL_I2C_HandleTransfer() function. Thus, the complete handling of arbitration should be handled in hardware?

TDK
Guru

> The STM32L4 uses two I2C Channels (Ch2 and Ch4), both as I2C Master in DMA mode on the same bus.

Not sure such a thing exists. Can you explain exactly how you're setting up multiple I2C channels? Do you mean DMA channels with different I2C peripherals? The word "channel" does not appear in the I2C section in the reference manual.

Feel like there's a fundamental misunderstanding here.

If you feel a post has answered your question, please click "Accept as Solution".

Hello @TDK,

I am sorry if I did not correctly described which peripherals we are using.

We are using I2C peripheral I2C2 and I2C4. As DMA we use DMA1 channel 4/5 for  I2C2_TX/I2C2_RX and DMA2 channel 1/2 for  I2C4_RX/I2C4_TX.

To activate the I2C sequence we use the following APIs:

LL_DMA_DisableChannel()
LL_DMA_SetMemoryAddress()
LL_DMA_SetDataLength()
LL_DMA_EnableChannel()
LL_I2C_EnableIT_TC()
LL_I2C_HandleTransfer()
-> Wait for 
IsrI2c2Ev/IsrI2c4Ev or IsrI2c2Err/IsrI2c4Err isrs.
 
Since the used OS is an preemptive OS, the task context could be switched during any of those API calls above. 

BR, Andreas

TDK
Guru

Using I2C2 and I2C4 on the same bus has no advantages over using only I2C2. I would recommend using only I2C2 to make the programming more straightforward.

If you feel a post has answered your question, please click "Accept as Solution".