AnsweredAssumed Answered

stm32f4 GPIO clock enable delay

Question asked by galens on May 17, 2015
Latest reply on May 18, 2015 by Clive One
Hi,

I just wanted to blink an LED on my STM32F4 discovery board.  It should be easy, right?  I grabbed Ross Wolin's blinky code off of github.
  https://github.com/rowol/stm32_discovery_arm_gcc

Here's the code of interest:

 //Flash orange LED at about 1hz int main(void) {     RCC->AHB1ENR |= RCC_AHB1ENR_GPIODEN;  // enable the clock to GPIOD     GPIOD->MODER = (1 << 26);             // set pin 13 to be general purpose output     for (;;) {        ms_delay(500);        GPIOD->ODR ^= (1 << 13);           // Toggle the pin     } }

I built blinky using this gcc release from ARM: 
 
arm-none-eabi-gcc (GNU Tools for ARM Embedded Processors) 4.9.3 20150303 
(release) [ARM/embedded-4_9-branch revision 221220]

Here's the disassembly of the resulting code: 
 
08000404 <main>: 
 8000404:       490e            ldr     r1, [pc, #56]   ; (8000440 
<main+0x3c>) 
 8000406:       4a0f            ldr     r2, [pc, #60]   ; (8000444 
<main+0x40>) 
 8000408:       6b0b            ldr     r3, [r1, #48]   ; 0x30 
 800040a:       f04f 6080       mov.w   r0, #67108864   ; 0x4000000 
 800040e:       f043 0308       orr.w   r3, r3, #8 
 8000412:       630b            str     r3, [r1, #48]   ; 0x30 
 8000414:       b082            sub     sp, #8 
 8000416:       6010            str     r0, [r2, #0] 
 8000418:       4614            mov     r4, r2 
 800041a:       f241 7053       movw    r0, #5971       ; 0x1753 
 800041e:       f44f 71fa       mov.w   r1, #500        ; 0x1f4 
 8000422:       9001            str     r0, [sp, #4] 
 8000424:       e000            b.n     8000428 <main+0x24> 
 8000426:       bf00            nop 
 8000428:       9b01            ldr     r3, [sp, #4] 
 800042a:       1e5a            subs    r2, r3, #1 
 800042c:       2b00            cmp     r3, #0 
 800042e:       9201            str     r2, [sp, #4] 
 8000430:       dcf9            bgt.n   8000426 <main+0x22> 
 8000432:       3901            subs    r1, #1 
 8000434:       d1f5            bne.n   8000422 <main+0x1e> 
 8000436:       6963            ldr     r3, [r4, #20] 
 8000438:       f483 5300       eor.w   r3, r3, #8192   ; 0x2000 
 800043c:       6163            str     r3, [r4, #20] 
 800043e:       e7ee            b.n     800041e <main+0x1a> 
 8000440:       40023800        .word   0x40023800 
 8000444:       40020c00        .word   0x40020c00


Of course, it doesn't work, or I wouldn't be posting to the forum.  It appears that the write to GPIOD MODER occurs too soon after the enable of the GPIOD peripheral clock.  Note that there is only one instruction between the store to AHB1ENR and the store to MODER.  If I change the C code such that the compiler places more instructions between these two stores, the code functions properly.

Is there any documentation regarding any delays that might be necessary after enabling the clock to a peripheral?  I have had no success with my searches of the reference manual. 
In the interests of full disclosure, I will note that the F407 on my discovery board has been replaced with an F427.  I am assuming that this is not relevant to this problem.

thanks,
galen

Outcomes