2014-02-09 12:59 PM
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);
}
2014-02-09 01:41 PM
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.2014-02-14 12:18 PM
Thank you clive!