2014-07-11 01:51 AM
Folks,
All below is on an STM32F107. I have managed to get a bootloader going in a stripped down version of FreeRTOS that then boots into the main application once the image has been updated. However, when the bootloader goes into the main app, even if I reset the I2C peripheral, I always get stuck at some point reading the busy flag and the application just hangs. I've tried all sorts of variations on the code below: ----------------------------------- I2C_SoftwareResetCmd(I2C1,DISABLE); for (i=0;i<0xFF;i++); I2C_SoftwareResetCmd(I2C1,ENABLE); I2C_EE_Init(); --------------------------- /* Reset I2C1 IP */ RCC_APB1PeriphResetCmd(RCC_APB1Periph_I2C1, ENABLE); /* Release reset signal of I2C1 IP */ RCC_APB1PeriphResetCmd(RCC_APB1Periph_I2C1, DISABLE); I2C_EE_Init(); -------------------------------------- However, I always end up getting stuck at some point in one of the accesses to read or write to the EEPROM. If I power down and back up the device, or reset it with the debugger, it always boots gracefully into the bootloader than out to the proper app. When I go from bootloader to app I execute the following code: FLASH->CR |= FLASH_CR_LOCK; // Relock the flash i = GetBootloaderByte(); i |= NEW_IMAGE_LOADED_BIT; SetBootloaderByte(i); JumpToNormalApplication(); ------------------------------------------------------------------------- Even tried adding the code below just before JumpToNormalApplication() for (i=0;i<0xFFFF;i++); // Let the EEPROM write finish? while ((I2C1->SR1 & 0x02) == 0x02); i = GetBootloaderByte(); I2C_Cmd(I2C1, DISABLE); RCC_APB1PeriphClockCmd(I2C_EE_CLK, DISABLE); // These two lines reset the I2C and stop it hanging when going into App? --------------------------------------------------------- And for completeness' sake, here's how I jump from bootloader to app. void JumpToNormalApplication(void) { volatile unsigned long JumpAddress; SysTick_CounterCmd(SysTick_Counter_Disable); SCB_VTOR = (unsigned long)0x8008000; JumpAddress = *(volatile unsigned long*) (0x8008000 + 4); Jump_To_Application = (pFunction) JumpAddress; // SET_MSP(0x8003000); Jump_To_Application(); } ------------------------------------------------------------------------------------- So, can anyone think why I'd be getting this condition and what I can do to stop it please? I'd seen other, similar things on the forum, but they'd solved it by resetting the I2C peripheral. I am assuming it is the processor getting its knickers in a twist, because of the fact a reboot solves it (which to me suggests it's not the EEPROM that is affecting the busy line). I'm using the STM3210C-EVAL board which has the EEPROM#s ~WC pin grounded and only uses SDA, SCL. There's no reset pin or anything like that. Many thanks!2014-07-11 04:16 AM
The I2C peripheral is rather sensitive to the order in which things are initialized, and the perceived state of the pins.
If you are using the I2C peripheral successfully in the boot loader, don't reconfigure it, and the associated pins. Do you have external pull-ups on the SDA/SCL? Does the SystemInit() on the App side reconfigure the clocks and PLL all over again? Does it use the same settings/configuration as the Boot Loader? Is there a point in doing that?2014-07-21 12:45 AM
I had the same issue once. In bootloader I2C works fine but in application it stucks even if you do not reinitialize I2C in application part which is very strange. I figured out that if you deinit() all gpio ports(becareful , not portA which has JTAG connection) in application part,every thing works fine. By the way STM32 I2C hardware and software is really very bad designed as i had lot of problem in using I2C specially I2C_BUSY_FLAG. I hope ST reconsider I2C design issues.