AnsweredAssumed Answered

I2C Busy flag set when going from bootloader to application

Question asked by Wood.Robert on Jul 11, 2014
Latest reply on Jul 21, 2014 by afzal.uzair
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!



Outcomes