Closed collinmay closed 10 months ago
I've created a smaller test project to reproduce the error. It also seems to be important that SYSCLK
is increased from the default. This project has the clock configured for 168 MHz.
5
bytes from address 0xf
.5
bytes from address 0xf
.Expected behavior: String "hello" is sent over the bus in step 5 as well as step 6.
Actual behavior:
String "hello" ({h68, h65, h6c, h6c, h6f}
) is sent over the bus in step 5,
string "ello" ({h65, h6c, h6c, h6f}
) is sent in step 6 and bus master is left waiting for 5th byte.
We also had troubles with I2C slave on F4 when using HAL_I2C_Slave_Transmit_IT
.
Sometimes the slave would not finish the transaction and kill the bus forever because it pulls SCL low. I suspect this could be the same issue.
As a workaround we are now using a software watchdog which will force reset the i2c peripheral if it detects a lockup, a proper fix would be very much welcomed.
ST Internal Reference: 120630
Has there been any update on this bug? I'm experiencing it at the moment and it's making HAL I2C IT impossible to use.
hello! I'm having this issue as well with a board I've been developing for >1 year.
It shows that this is 'to release' (as of 8 months ago) and not 'done' on the dashboard-- did this fix make it into one of the newer STM32Cube packages for the F series? Thanks!
hello! I'm having this issue as well with a board I've been developing for >1 year.
It shows that this is 'to release' (as of 8 months ago) and not 'done' on the dashboard-- did this fix make it into one of the newer STM32Cube packages for the F series? Thanks!
I actually found out that there is no bug, it's just that the HAL is terribly documented. Here are the things I found:
Start with the slave calling: HAL_I2C_EnableListen_IT
in HAL_I2C_ListenCpltCallback call HAL_I2C_EnableListen_IT so it keeps listening
When a master sends something, the slave will get: HAL_I2C_AddrCallback called.
In there, do: HAL_I2C_Slave_Seq_Receive_IT or HAL_I2C_Slave_Seq_Transmit_IT depending on the setting of TransferDirection, which when finished will call: HAL_I2C_SlaveRxCpltCallback Where you can either call: HAL_I2C_Slave_Seq_Receive_IT to continue receiving from the master, or: __HAL_I2C_GENERATE_NACK or just ignore it entirely.
So the main issue is just not using the correct API to do things.
Until I switched to the above calls, nothing was ever working properly. Now it's as solid as a rock. It's just that the HAL docs are absolutely terrible at explaining how they want you to do things.
@etheory Thank you so so much, this comment (and this thread) absolutely saved me hours and hours of debugging!
I was having similar, difficult to track down issues with HAL_I2C_Slave_Transmit_IT killing the bus randomly, now it's looking solid. I've been pulling my hair out for several days on this one. Huge thanks!!
Describe the set-up
Describe the bug If
HAL_I2C_SlaveTxCpltCallback
arranges forHAL_I2C_Slave_Transmit_IT
to be called in quick succession, the driver can get confused by aTXE
flag from the hardware and prematurely consume the first byte of the second transfer before the device is ever addressed for a second transfer, causing the subsequent transfer to never complete.How To Reproduce
HAL_I2C_Slave_Transmit_IT
(size 3 bytes) and waits for the master to receive the data.HAL_I2C_SlaveTxCpltCallback
is called, a flag is set.HAL_I2C_Slave_Transmit_IT
again (size still 3 bytes) to make the next set of data available for the master to receive.Additional context Size doesn't matter. I originally observed the bug on 28 bytes, reproduced it on 29, and later reduced it to 3 so the entire transaction would fit better on my logic analyzer display.
This bug seems to be quite timing sensitive and doesn't seem to reproduce in the presence of breakpoints or printf statements, so it's been hard for me to investigate. I added a quick buffer to store various events I thought interesting to trace that I could then read out using the debugger after the bug occurred. This is the sequence of events I observed:
HAL_I2C_SlaveTxCpltCallback
. The bug does not reproduce if I set a breakpoint here.HAL_I2C_Slave_Transmit_IT
to be called later, outside of an ISR. Not sure whether this is relevant or not or whether the bug would reproduce withHAL_I2C_Slave_Transmit_IT
called directly from the callback. I can try to test this later.(it is important to note that I only traced
I2C_SlaveTransmit_TXE
calls whenXferCount != 0
, otherwise my trace buffer would fill up)Note that I did not use the logic analyzer to begin another transaction; the call to
I2C_SlaveTransmit_TXE
occurs after the second call toHAL_I2C_Slave_Transmit_IT
, but before the device is actually addressed. This causesXferCount
to be decremented to2
, so when I try to begin another transaction with the logic analyzer, it only receives 2 bytes and is left waiting forever for the third, while the STM enters an interrupt loop with theBTF
flag set.I'm not sure why
I2C_SlaveTransmit_TXE
is being called late, but I suspect that's what's causing the bug.