2008-11-21 01:30 AM
STM32 I2C glitch
2011-05-17 03:53 AM
We are currently using the STM32 Cortex (STM32F101T6U6) processor on a product and we have a slight problem that I would like assistance on.
We are using an LCD that is driven over I2C. This display is running in low power mode and needs to have an I2C clock of around 25kHz. Generally, this is all working fine. However, the complication is that the STM32 is being run at two different core clock speeds depending on whether it is running on battery or on mains. When the device detects the mains charger, it ups the clock to 8MHz from the low power 40kHz mode. Sometimes at this point, the LCD freezes and we cannot get it back without cycling the power. I was wondering if there was anything we should be doing regarding the I2C peripheral during this clock domain change. e.g. disable I2C and then re-initialise it? Does the STM32 handle the clock changes for all the peripherals or is there a chance that the I2C lines could end up at the wrong speed temporarily? Any help would be much appreciated2011-05-17 03:53 AM
I do not know what is the nature of your problem. But of course, it is not good to change the system clock while I2C communication is on going. Especially, you changes the clock frequency a lot, from 40kHz to 8MHz. It is 200 times faster, so do I2C clock.
Why not you disable the I2C module while switching the system clock.2011-05-17 03:53 AM
An idea:
Why not either: 1) Poll the I2C status bits for the idle condition before executing RCC changes? Something like: while(I2C_Busy){} RCC_Change; 2) Set a global flag at start of your communication, or other timing sensitive fuction, and reset it after transaction completed, and poll the flag before RCC change, to make sure no peripheral are busy, and the no multi-part communications are on process. (I2C might go back to idle, but if it's between bytes of a multi-byte message, it may still screw up communications). 3) Make the RCC change a non-interrupt function with a delay. -Detect Vin change -Start delay (25 ms) -RCC Change The non-interruption mean you can put the function somewhere you know no comm are used, the delay just to make sure any ongoing comm are finished. -relaxe