Delay in processing the external GPIO interrupts
I am using the STM32 GO71RB for motor control, My objective is to calculate the position of the motor while its running. I am trying to find the forward/reverse position of the motor using the encoder feedback; the encoder I am using is HEDS-550.
For this, I have taken two encoder signals as External GPIO interrupts in STM controller and from the phase shift in the encoder signals, I am able to calculate my forward and reverse position correctly. I have properly tested the positioning of the motor at a speed of 250 rpm.
How ever, If I am rotating the motor at rpm of 500 and above, I am observing a delay in processing the GPIO interrupts and as a result I am observing misses in the position calculation.
I have enabled rising and falling edge detection for the above said GPIO interrupts.
In the EXTI4_15_IRQHandler, I am checking for the rising and falling edges of the GPIOs using the EXTI->RPR1 and EXTI->FPR1 registers. Based on the order in which the rising and falling edges are coming, I am calculating the forward/reverse position.
As I said earlier, the issue I am facing is that there is a delay in processing the edge interrupts and this delay is occurring occasionally only and at these times, I am missing my position calculation.
To identify the issue, I have used a GPIO pin to mimic the status of the interrupts received and when probed, I have observed that sometimes a there is a delay (60-80 microseconds at 500 rpm) in the GPIO output, ie sometimes GPIO status is changing only after a delay after the change of interrupt status. Normally, this delay is less than 10 microseconds. Also, at lower rpms like 250 rpm, this much delay is not observed.
My external interrupts are processed as follows:
void EXTI4_15_IRQHandler(void)
{
/* USER CODE BEGIN EXTI4_15_IRQn 0 */
#if 0
Test_dummy = 0;
if ((__HAL_GPIO_EXTI_GET_FALLING_IT(GPIO_PIN_7)) != 0x00u) //EF on Channel 1 (Yellow) on MSO
{
HAL_GPIO_WritePin(GPIOD, GPIO_PIN_5, RESET); // Channel 3 (Pink) in MSO
Test_dummy++;
Prev_E = B_FALL;
__HAL_GPIO_EXTI_CLEAR_FALLING_IT(GPIO_PIN_7);
}
if ((__HAL_GPIO_EXTI_GET_RISING_IT(GPIO_PIN_7)) != 0x00u) //ER on Channel 1 (Yellow) in MSO
{
HAL_GPIO_WritePin(GPIOD, GPIO_PIN_5, SET); // Channel 3 (Pink) in MSO
Test_dummy++;
if(Prev_E == A_RISE)
{
posCount_X++;
}
Prev_E = B_RISE;
__HAL_GPIO_EXTI_CLEAR_RISING_IT(GPIO_PIN_7);
}
if((__HAL_GPIO_EXTI_GET_RISING_IT(GPIO_PIN_8)) != 0x00u) //ER on Channel 2 (Blue) in MSO
{
HAL_GPIO_WritePin(GPIOC, GPIO_PIN_2, SET); // Channel 3 (Green) in MSO
Test_dummy++;
Prev_E = A_RISE;
__HAL_GPIO_EXTI_CLEAR_RISING_IT(GPIO_PIN_8);
}
if((__HAL_GPIO_EXTI_GET_FALLING_IT(GPIO_PIN_8)) != 0x00u) //EF on Channel 2 (Blue) in MSO
{
HAL_GPIO_WritePin(GPIOC, GPIO_PIN_2, RESET); // Channel 3 (Green) in MSO
Test_dummy++;
if(Prev_E == B_FALL)
{
posCount_X--;
}
Prev_E = A_FALL;
__HAL_GPIO_EXTI_CLEAR_FALLING_IT(GPIO_PIN_8);
}
if(Test_dummy>1)
{
}
#endif
/* USER CODE END EXTI4_15_IRQn 0 */
//HAL_GPIO_EXTI_IRQHandler(GPIO_PIN_7);
//HAL_GPIO_EXTI_IRQHandler(GPIO_PIN_8);
/* USER CODE BEGIN EXTI4_15_IRQn 1 */
/* USER CODE END EXTI4_15_IRQn 1 */
}
The oscilloscope trace is as follows:
Now here the the channel 3 is supposed to follow channel 1 and Channel 4 is supposed to follow channel 2... but as you can see there is an instance in channel 3 where there is a considerable delay (right around the middle) which is almost 60us... this is a random behavior and the delay values also vary. this ideally shouldn't happen.. even worse case issue is when the delay exceeds the next edge change, in which case i can totally miss an edge.
i am using this to calculate the number of edges so this is causing a lot of issues.
Can anyone throw some support on this to identify the reason for delay in processing the GPIO interrupts.
