cancel
Showing results for 
Search instead for 
Did you mean: 

stm32f4 GPIO clock enable delay

galens
Associate II
Posted on May 17, 2015 at 01:06

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, &sharp56] ; (8000440 <main+0x3c>) 8000406: 4a0f ldr r2, [pc, &sharp60] ; (8000444 <main+0x40>) 8000408: 6b0b ldr r3, [r1, &sharp48] ; 0x30 800040a: f04f 6080 mov.w r0, &sharp67108864 ; 0x4000000 800040e: f043 0308 orr.w r3, r3, &sharp8 8000412: 630b str r3, [r1, &sharp48] ; 0x30 8000414: b082 sub sp, &sharp8 8000416: 6010 str r0, [r2, &sharp0] 8000418: 4614 mov r4, r2 800041a: f241 7053 movw r0, &sharp5971 ; 0x1753 800041e: f44f 71fa mov.w r1, &sharp500 ; 0x1f4 8000422: 9001 str r0, [sp, &sharp4] 8000424: e000 b.n 8000428 <main+0x24> 8000426: bf00 nop 8000428: 9b01 ldr r3, [sp, &sharp4] 800042a: 1e5a subs r2, r3, &sharp1 800042c: 2b00 cmp r3, &sharp0 800042e: 9201 str r2, [sp, &sharp4] 8000430: dcf9 bgt.n 8000426 <main+0x22> 8000432: 3901 subs r1, &sharp1 8000434: d1f5 bne.n 8000422 <main+0x1e> 8000436: 6963 ldr r3, [r4, &sharp20] 8000438: f483 5300 eor.w r3, r3, &sharp8192 ; 0x2000 800043c: 6163 str r3, [r4, &sharp20] 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

#stm32f4 #discovery
7 REPLIES 7
Posted on May 17, 2015 at 04:37

What you want is the

http://www.st.com/web/en/resource/technical/document/errata_sheet/DM00037591.pdf

, which discusses this hazard on page 16

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
Posted on May 17, 2015 at 16:28

Honestly, this one does not belong to the Errata. And of course there are more such and similar, e.g. [DEAD LINK /public/STe2ecommunities/mcu/Lists/cortex_mx_stm32/Flat.aspx?RootFolder=/public/STe2ecommunities/mcu/Lists/cortex_mx_stm32/Enabling%20LSE&FolderCTID=0x01200200770978C69A1141439FE559EB459D7580009C4E14902C3CDE46A77F0FFD06506F5B&currentviews=385]this one, the interrupt-source-clear issue Clive has to explain so often, and sure there are more such and similar.

This is a painful way to realize that these are not the microcontrolers built to easily down-to-the-tick predictible anymore. These are SoC, a processor core a bunch of peripherals and an interconnect matrix, all in form of IPs, more or less losely stitched together, and marketed agressively without mentioning the drawbacks. There is a lot of handwaving  when it comes to timing issues, and very little solid and binding information. I understand, these are not simple issues, but since when is engineering supposed to be simple and easy.

JW
Posted on May 17, 2015 at 17:23

It's one of those subtle interactions when you have pipelined logic, write buffers and buses with disparate speeds. That this flaw is there is not entirely surprising. You can throw a lot of silicon at fixing/hiding these things, Intel's got lots of silicon to hide things and create interlocks for some extremely obscure circumstances. ARM's approach is to let you walk on the cliff's edge, knowing the danger, making you think about the wisdom of that, rather than spoil the view with idiot fences for the suburbanites.

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
galens
Associate II
Posted on May 17, 2015 at 17:31

Well, that's embarrassing.  I've definitely read the errata, but that one obviously didn't register.  I do tend to agree with Jan, in that it might be better if this info were directly in the datasheet.  I'm guessing that it is unlikely that this errata will ever be fixed.

thanks again,

galen

Posted on May 17, 2015 at 17:45

Even if you fixed it, you'd create two sets of devices, those with the issue, and those without, you'd still have to program defensively so you don't get bitten when purchasing gets a batch of chips from brokers that still has the issue..

If you push the clock enabling code for all your peripherals into a subroutine, this hazard disappears into all the other read/write/execute interactions.

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
Posted on May 17, 2015 at 22:24

> ARM's approach is to let you walk on the cliff's edge, knowing the danger, making you think about the wisdom of that, rather than spoil the view with idiot fences for the suburbanites.

:D

Thanks Clive, it made my day!

May I quote you?

Jan

Posted on May 18, 2015 at 00:47

Certainly

I live near a beautiful State Park, every weekend during the summer I expect the rescue crew to be there dealing with someone who fell in one of the canyons (Midwest 75-100ft ones), some times at sites where fences have been erected, so they really tried, and sometimes in pairs.

RISC processors can be full of these hazards, Intel's Itanium was designed with them, and it was the linkers job to do instruction sequencing and allocation to avoid/prevent them. ie you had to initiate a LOAD several cycles ahead of where you used the register you were loading, and it would stuff NOP's or pull forward other unrelated instructions.

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..