AnsweredAssumed Answered

STM32F4 GPIO init delay?/sanity check

Question asked by SHilbert on Feb 14, 2015
Latest reply on Feb 16, 2015 by SHilbert
Hi all,

I'm playing around with an STM32F4 Discovery board, and I ran into an interesting issue. I'm using the GCC embedded ARM toolchain. This is the main code in question:

#include <stm32f407xx.h>
 
int main (void)
{
    RCC->AHB1ENR |= RCC_AHB1ENR_GPIODEN;
 
    GPIOD->MODER = (1 << 26) | (1 << 24) | (1<<30);
 
    while (1)
    {
        GPIOD->ODR ^= (1 << 13);
        GPIOD->ODR ^= (1 << 12);
        GPIOD->ODR ^= (1 << 15);
    }
}

Now, the interesting part: when I compile without any optimization -O flag, or with -Os or -O1, everything works great: the orange, green and blue LEDs flash at some 100s of kHz.

However, when I compile with -O2, the code doesn't work at all -- the LEDs are all off. Inspecting with gdb, it seems that GPIOD->MODER is zero. The ODR register is correctly being changed but since MODER is zero it has no effect on the output. However, if I single step through the initialization using gdb it works fine! I also tried putting a __NOP(), or a write to a volatile int, before setting GPIOD->MODER and that also works fine. Writing to MODER twice in a row also works.

I looked at the machine code GCC is outputting and it looks fine. The main difference is that for -O2, there is only 1 move instruction between the store instruction that enables the clock to the GPIO peripheral and the store instruction that writes to MODER. When I use -Os for example it outputs code with at least 1 extra instruction inbetween.

This all makes me suspect that there's a timing issue between when I enable the clock to the GPIOD module and when I try to set its registers.

So this is my question: is it reasonable to expect that a few clocks have to pass between enabling clock to the GPIO module and writing to its registers? Or does this indicate something else might be wrong?

BTW, this is all running off the internet RC oscillator at 16 MHz.

Outcomes