Question
I2C Busy flag set when going from bootloader to application
Posted on July 11, 2014 at 10:51
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!