The issue that I am having is with two lines of code that uses GPIO_->BSRRH to control the output pins of an STM32F407. This works very well for thousands to 100K+ consecutive cycles, then misses once at an apparent random interval. This controls some leds, and the occasional flash is very irritating. I have been fighting this on and off for some time and have not found anything similar.
LEDs are turned in during a timer ISR running 70 times per second. This starts a second timer and turns on LEDs as needed:
TIM2->CR1 = 1; // start the led timer if(mg[MG1_BUI_LedBlue]) GPIOH->BSRRL = 0x0004; // blue led turn on if(mg[MG1_BUI_LedGreen]) GPIOG->BSRRL = 0x0040; // green led turn on if(mg[MG1_BUI_LedYellow]) GPIOG->BSRRL = 0x0080; // yellow led turn on if(mg[MG1_BUI_LedRed]) GPIOG->BSRRL = 0x0100; // red led turn on
When the second timer times out, an ISR turns the LEDs off:
void TIM2_IRQHandler(void) { GPIOH->BSRRH = 0x0004; // blue led turn off GPIOG->BSRRH = 0x01C0; // G,Y,R led turn off TIM2->CR1 = 0; // stop the timer if(TIM2->SR) TIM2->SR = 0; // clear UIF flag }
I have verified that there is ALWAYS a second ISR for every turn-on, that it performs the write, and that the contents of the GPIO_->ODR have been properly cleared to zero. But, on extremely rare occasions, the output pins are set again shortly afterwards. I have searched through code, and have not found any other places where these GPIO registers are used. Has anyone else experienced any issues with the BSRRH?
So the penultimate root cause was turning on in one process and turning off in another. I should remember learning this lesson 100 years ago. Although this did all the right things, it occasionally did not do them in the right order. Your comments about clocking the outputs and the pipelining were helpful and got me on the right path. In hindsight, it is all so simple.
The ultimate root case, as always, was trying to rush stuff out as quickly as possible.
Once again, my thanks!