2019-12-02 12:44 PM
I'm using an STM32F429ZIT6 chip.
In my program, the BUSY bit within I2C->CR2 becomes set and never returns to clear. I have verified on a scope that both the SDA and SCL lines remain high during this time and yet the bit remains set. The SR1 register and all other bits within the SR2 register are 0, which would indicate no error is occurring on the line.
After some debugging, I have determined that initializing the SDRAM before initializing the I2C prevented this error from occurring, whereas doing the reverse caused it to happen.
The BUSY bit gets set when the program is somewhere within the HAL_SDRAM_Init call. I2C operations before this work correctly. Nothing in this call touches the pins on the I2C line or the I2C peripheral. I've disabled interrupts during this process to ensure nothing is happening within an interrupt.
I didn't see anything in the errata sheet:
After searching, I did see this problem mentioned for the STM32F1 series:
https://electronics.stackexchange.com/questions/267972/i2c-busy-flag-strange-behaviour
The errata sheet for the STM32F1 series has this limitation mentioned in "2.14.7 I2C analog filter may provide wrong value, locking BUSY flag and
preventing master mode entry":
Okay, sure seems like that's the case here. The errata sheet also provides a lengthy workaround:
1. Disable the I2C peripheral by clearing the PE bit in I2Cx_CR1 register.
2. Configure the SCL and SDA I/Os as General Purpose Output Open-Drain, High level
(Write 1 to GPIOx_ODR).
3. Check SCL and SDA High level in GPIOx_IDR.
4. Configure the SDA I/O as General Purpose Output Open-Drain, Low level (Write 0 to
GPIOx_ODR).
5. Check SDA Low level in GPIOx_IDR.
6. Configure the SCL I/O as General Purpose Output Open-Drain, Low level (Write 0 to
GPIOx_ODR).
7. Check SCL Low level in GPIOx_IDR.
8. Configure the SCL I/O as General Purpose Output Open-Drain, High level (Write 1 to
GPIOx_ODR).
9. Check SCL High level in GPIOx_IDR.
10. Configure the SDA I/O as General Purpose Output Open-Drain , High level (Write 1 to
GPIOx_ODR).
11. Check SDA High level in GPIOx_IDR.
12. Configure the SCL and SDA I/Os as Alternate function Open-Drain.
13. Set SWRST bit in I2Cx_CR1 register.
14. Clear SWRST bit in I2Cx_CR1 register.
15. Enable the I2C peripheral by setting the PE bit in I2Cx_CR1 register.
It is possible (IMO) that the additional current required for driving the SDRAM causes an incredibly short edge on the SDA and/or SCL lines, which causes the analog filter to get into a bad state. This happens despite putting decoupling caps at all power input pins as well as bulk capacitance on the board itself. I'm guessing. I'm also curious how an "analog filter" can possibly get stuck in a different state than the input driving it.
In my case, the workaround was to initialize the SDRAM first.
ST, can you confirm the STM32F4 has this same limitation as the STM32F1 and update the STM32F429 errata sheet to reflect this deficiency?
2019-12-02 02:33 PM
You use Cube/HAL? Start perhaps with dropping it, and writing your own I2C code, so you are in full control of it.
Observe VDD vs. GND (placing probe as close to mcu as possible, ideally directly onto pins, including GND) during the SDRAM statup. Observe SDA/SCL during SDRAM startup. Try lower value pullups on SDA/SCL.
JW
2021-03-24 04:07 PM
did you ever solve this problem? It's mentioned countless times on the internet and this forum. I'm using STM32L476, and I think it's happening on it too. I tried out the solution for F1 on L476RG written in this post https://electronics.stackexchange.com/questions/267972/i2c-busy-flag-strange-behaviour and I can't reproduce the bug anymore, so I think it solves the issue.
2021-03-24 08:55 PM
2024-04-16 04:16 AM
Hi! Can you tell me where I can the SD initialization code? I couldn't find it on my CUBE IDE project