cancel
Showing results for 
Search instead for 
Did you mean: 

Does GPIO_Init require a short delay to take effect?

dj
Associate II
Posted on February 09, 2014 at 21:59

Hi! First, I have to say that this forum has been super helpful with designing our new product based on the STM32F2. Even though this is my first post, I have been using this forum for months for reference. Also, hats off to Clive, because you sir - are the true ARM guru! I'm blown away at your knowledge and patience.

Okay, so my question is regarding GPIO_Init. Our product changes the I/O direction of a pin often. After performing a very simple GPIO_Init(), such as....

GPIO_InitTypeDef GPIO_InitStructure; 
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; 
GPIO_InitStructure.GPIO_PuPd = PuPd; 
GPIO_InitStructure.GPIO_Pin = pin; 
GPIO_InitStructure.GPIO_Mode = direction; 
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz; 
GPIO_Init(bank, &GPIO_InitStructure); 

Should I DELAY for a number of cycles before the change takes effect? Or should I expect it to be immediate? For example, I am currently delaying for 40 cycles after I change the I/O function of a pin. To be honest, I am not sure why I started doing that. Today it got me thinking, do I even need to pause after changing the I/O function of a pin? This is what I'm currently doing, and I don't think I need too - it's good to verify.

void SetIODirection(GPIO_TypeDef *bank, int16 pin, GPIOMode_TypeDef direction, GPIOPuPd_TypeDef PuPd) { 
GPIO_InitTypeDef GPIO_InitStructure; 
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; 
GPIO_InitStructure.GPIO_PuPd = PuPd; 
GPIO_InitStructure.GPIO_Pin = pin; 
GPIO_InitStructure.GPIO_Mode = direction; 
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz; 
GPIO_Init(bank, &GPIO_InitStructure); 
DelayCycles(40); 
} 

2 REPLIES 2
Posted on February 09, 2014 at 22:41

No, you don't need a delay, the memory writes (and reads) occur in program order, but might have some latency as they are committed to write buffers, and buses might clock as dissimilar speeds.

The one area this has a potential issue is between enabling an APB/AHB peripheral clock, and writing to a register within that unit. You'd have to try really hard in C to do that.  Basically two operations back-to-back

  RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOF,ENABLE);

  GPIO_Init(GPIOF, &GPIO_InitStructure);

Though the library, and the compiler, would probably still be too slow to see the violation.

The main area you might encounter an issue is with clearing interrupts on a peripheral, that propagating to the NVIC, and to the Tail Chaining decision. You should try to clear the interrupt early in the service routing, and qualify the source on entry, so as not to be caught by a spurious re-entry.
Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
dj
Associate II
Posted on February 14, 2014 at 21:18

Thank you clive!