2025-01-16 01:12 PM
Hello everyone, I am writing some code to control an IS31FL3736 LED Matrix Driver which communicates over I2C. I am using a Nucleo H563 as the devboard. I have 4.7k pullup resistors on the SDA and SCL lines. I am using I2C4 with PG6 & PG7 as the SDA & SCL pins respectively.
The problem I am running into is that occasionally when I try to call HAL_I2C_Master_Transmit(), both the data and clock lines get pulled low by the microcontroller. The original call to HAL_I2C_Master_Transmit() fails because of a timeout, and all successive calls to HAL_I2C_Master_Transmit() timeout. The only status bits I see set in the peripheral's I2C_ISR are TXE and BUSY. I didn't see any behavior like this listed in the errata, as well as I couldn't find any references to this behavior elsewhere online.
The exact configuration of I2C4 is as follows (all code was generated by CubeMX):
The code snippet:
static void led_unlockCMD() {
uint8_t txbuf[2] = { 0xFE, 0xC5 };
HAL_I2C_Master_Transmit( &hi2c4, 0xA6, txbuf, 2, 20 );
}
I've tried different baud rates, disabling clock stretching, and soldering directly to the dev board instead of using jumpers and a breadboard. I've also tried some different clock configurations and found that lower clock rates tend to cause this error less, but they still do occur.
I verified this behavior using a digital logic analyzer, and I made sure it was the microcontroller by disconnecting the clock and data jumper wires, which caused the lines to return high, so I'm pretty sure it's something with the microcontroller, whether it's software or hardware I don't know. Additionally, I do have a second Nucleo H563 which exhibited the same behavior when flashed with the same software.
Any feedback is appreciated!
2025-01-16 01:26 PM
Here's some screenshots of the digital logic analyzer showing normal (but still unusual) behavior, and a lockup.
Regular Behavior:
Note that there is about 130us between the clock falling the first time and the actual clock pulses, then there's an unusually long pulse pulling SCL low ~600us after the transmission and holding low for ~7ms. That all seems strange.
Lockup Behavior:
As you can see, both the clock and data lines are pulled low.
2025-01-16 07:43 PM
Scope analog signals. Is there noise? Try to tweak the analog and digital filters of the I2C (see the RM).
2025-01-17 06:12 AM - edited 2025-01-17 06:13 AM
I hooked the system up to one of my job's analog scopes and I'm not seeing any unusual noise, or really any noise.
I did try some more debugging and found that when I hit the reset button on the Nucleo board, I have yet to see the peripheral actually work. Of the 10 or so times that I tried scoping the SDA/SCL lines while using the reset button on the board, all of them failed to work.
When I was debugging using my IDE (VSCode with the STM32 plugin and related additional plugins), doing a core reset and single-stepping over the call to HAL_I2C_Master_Transmit()worked more often than not, but still occasionally exhibited the lockup behavior.
2025-01-17 07:03 AM
I'm still open to actual solutions, but for now, I can make some assumptions to make a temporary fix.
In the case of my system, the LED drivers don't transmit anything unless I read from them. The H5 is the only bus master, so the bus can't actually be busy unless the H5 is actively transmitting.
Therefore, if the bus is marked as busy after attempting to send the slave address and an arbitrary time period has elapsed, I can assume that the transmitter got stuck and I can reset the I2C peripheral.
I skimmed the I2C section of the reference manual for the H563 and it doesn't seem too hard to interface with the I2C peripheral without the HAL so I should be able to make a custom abstraction layer for my application.
2025-01-17 08:53 AM - edited 2025-01-17 09:03 AM
>I'm still open to actual solutions
Well, i have no solution - i just can tell my experiences , with I2C and I2C on STM32 :
- i made a 4-layer board with H7xx (743, 733, 7A3 , 753 ) cpu and I2C : eeprom + sensors onboard ;
board is running without any noticeable errors (on I2C etc.) , now > 1000 pcs , 24/7 around the world.
- on some first tests with different sensors on free air wires connected to I2C : a lot of problems, I2C seems to hang up in some strange way (this might be, what you see also.)
- on an other board connected with about 40mm wires to next board with I2C slave , i had sometimes errors and after some time running these "hang up" , that i just could remove/recover by reset the cpu.
Speed on 100 or 400kHz not much difference, but at 400 had less errors.
Same cpu (H743) and I2C slaves now together on one board with ground plane shows no errors (since 2 months now), at 400kHz speed.
+ on a cheap STC15W408 , that has no native I2C , i had to write my own, simple i2c-read and write commands (and the clock stretching also) , wired free air to sensor, eeprom and RTC clock chip : never a problem since 2 years, running all time. (and reading rtc and sensor every 2 sec, so about 31 Mio i2c actions.)
--> so the I2C on stm32 seems very fragile and unreliable (at least, if not on same board with ground plane);
it might be very sensible to any few-ns-spike and hang up then in curious state.
So try (if you not already did) : in Cube/I2C set : analog filter ON, and digital filter: to some high value .
And short connection , maybe screened, with good and short ground also.
Or try your own bit-bang soft I2C - it might work better.
2025-01-17 08:57 AM
Thanks for the suggestion!
I don't have the complete custom PCB for this project yet, so I am still using breadboards. So the ground plane could be the issue. I'll give that a try and post the results. I have other things I need to work on, so I might not be able to test until Monday.