Skip to main content
ferrario
Associate III
October 20, 2021
Solved

STM32G030 Interrupt latency

I am experiencing a vey long external interrupt latency up to 2 microseconds.

Clock is internal PLL, 64MHz.

void HAL_GPIO_EXTI_Rising_Callback(uint16_t GPIO_Pin)

{

   if (GPIO_Pin == TRIGGER_Pin)

      {

           __disable_irq();

            LL_GPIO_ResetOutputPin(S2_GPIO_Port, S2_Pin);         

            __enable_irq();

      }

}

how can I speed it up, I need it to be <1 microsecond

Thanks

This topic has been closed for replies.
ferrario
ferrarioBest answer
Associate III
October 20, 2021

Thanks to all

void EXTI0_1_IRQHandler(void)

{

 /* USER CODE BEGIN EXTI0_1_IRQn 0 */

      if (__HAL_GPIO_EXTI_GET_RISING_IT(GPIO_PIN_0 ) != 0x00u)

       {

       // LL_GPIO_ResetOutputPin(S2_GPIO_Port, S2_Pin);

         S2_GPIO_Port->BRR= S2_Pin;

        // delay_us(Delays[WAIT]);

         // LL_GPIO_SetOutputPin(S1_GPIO_Port, S1_Pin); //HOLD

         S1_GPIO_Port->BSRR=S1_Pin;

         __HAL_GPIO_EXTI_CLEAR_RISING_IT(GPIO_PIN_0);

       }

       if (__HAL_GPIO_EXTI_GET_FALLING_IT(GPIO_PIN_0) != 0x00u)

       {

         __HAL_GPIO_EXTI_CLEAR_FALLING_IT(GPIO_PIN_0);

         // HAL_GPIO_EXTI_Falling_Callback(GPIO_Pin);

         // LL_GPIO_ResetOutputPin(S1_GPIO_Port, S1_Pin); //HOLD

         S1_GPIO_Port->BRR=S1_Pin;

         // LL_GPIO_ResetOutputPin(S2_GPIO_Port, S2_Pin);

         S2_GPIO_Port->BRR=S2_Pin;

           HAL_ADC_Start_IT(&hadc1);

       }

 /* USER CODE END EXTI0_1_IRQn 0 */

 // HAL_GPIO_EXTI_IRQHandler(GPIO_PIN_0);

 /* USER CODE BEGIN EXTI0_1_IRQn 1 */

 /* USER CODE END EXTI0_1_IRQn 1 */

}

So

1- code written in the ISR

2- removed even LL calls, wrote the BRR

latency is now 760ns.

Thanks once again

11 replies

Javier1
Principal
October 20, 2021

For reseting your pin you use LL_GPIO_ResetOutputPin(S2_GPIO_Port, S2_Pin);       

You could do it faster by writting the corresponding bit in the BSRR register https://electronics.stackexchange.com/questions/343538/how-does-the-bsrr-register-work

I used BSRR for softwarepwm here

Also you could set the GPIO SPEED to very high

0693W00000FD8csQAD.pngI dont know how much time this will save you....

hit me up in https://www.linkedin.com/in/javiermuñoz/
ferrario
ferrarioAuthor
Associate III
October 20, 2021

Dear Javier,

this is indeed what the LL call does.

__STATIC_INLINE void LL_GPIO_ResetOutputPin(GPIO_TypeDef *GPIOx, uint32_t PinMask)

{

 WRITE_REG(GPIOx->BRR, PinMask);

}

I think the problem lies somewhere else, but I can't find it

Javier1
Principal
October 20, 2021

I dont really know if 2us delay is a lot to serve an interruption.

you could place the vector table in sram instead of Flash?

hit me up in https://www.linkedin.com/in/javiermuñoz/
ferrario
ferrarioAuthor
Associate III
October 20, 2021

Vector Table in RAM Crashes

 .isr_vector :

 {

   . = ALIGN(4);

   KEEP(*(.isr_vector)) /* Startup code */

   . = ALIGN(4);

 } >RAM

Thanks

Tesla DeLorean
Guru
October 20, 2021

>>how can I speed it up, I need it to be <1 microsecond

Run with less clutter. Implement code IN the IRQHandler

Not clear why interrupts need disabling. Lower priority ones are implicitly blocked, and the write to the BRR is singular and atomic. Callbacks are done in interrupt context

Tips, Buy me a coffee, or three.. PayPal Venmo (See Profile) Up vote any posts that you find helpful, it shows what's working..
ferrario
ferrarioAuthor
Associate III
October 20, 2021

Thanks a lot. Disabling interrupts has been removed with minor improvement.

WRITE_REG is a macro, actually writes the BRR

Implementing in the ISR let me save only 200ns.

Confused

TDK
October 20, 2021

HAL_GPIO_EXTI_Rising_Callback is not the IRQ handler. In this case, EXTI4_15_IRQHandler is the handler, so write your code in there instead. Don't use HAL if you can't live with a small delay.

<2us is more than doable at 64 MHz clock speed.

"If you feel a post has answered your question, please click ""Accept as Solution""."
ferrario
ferrarioAuthor
Associate III
October 20, 2021

Upon interrupt the void HAL_GPIO_EXTI_IRQHandler(uint16_t GPIO_Pin) is called.

This in turns calls the callbacks.

How can I get rid of HAL in this case, this is the direct interrupt callback?

TDK
October 20, 2021
Like I said, the handler in the vector table is EXTI4_15_IRQHandler. You can view the call stack during the interrupt to verify this. Find that function in your program and put the code there instead.
"If you feel a post has answered your question, please click ""Accept as Solution""."
ferrario
ferrarioAuthorBest answer
Associate III
October 20, 2021

Thanks to all

void EXTI0_1_IRQHandler(void)

{

 /* USER CODE BEGIN EXTI0_1_IRQn 0 */

      if (__HAL_GPIO_EXTI_GET_RISING_IT(GPIO_PIN_0 ) != 0x00u)

       {

       // LL_GPIO_ResetOutputPin(S2_GPIO_Port, S2_Pin);

         S2_GPIO_Port->BRR= S2_Pin;

        // delay_us(Delays[WAIT]);

         // LL_GPIO_SetOutputPin(S1_GPIO_Port, S1_Pin); //HOLD

         S1_GPIO_Port->BSRR=S1_Pin;

         __HAL_GPIO_EXTI_CLEAR_RISING_IT(GPIO_PIN_0);

       }

       if (__HAL_GPIO_EXTI_GET_FALLING_IT(GPIO_PIN_0) != 0x00u)

       {

         __HAL_GPIO_EXTI_CLEAR_FALLING_IT(GPIO_PIN_0);

         // HAL_GPIO_EXTI_Falling_Callback(GPIO_Pin);

         // LL_GPIO_ResetOutputPin(S1_GPIO_Port, S1_Pin); //HOLD

         S1_GPIO_Port->BRR=S1_Pin;

         // LL_GPIO_ResetOutputPin(S2_GPIO_Port, S2_Pin);

         S2_GPIO_Port->BRR=S2_Pin;

           HAL_ADC_Start_IT(&hadc1);

       }

 /* USER CODE END EXTI0_1_IRQn 0 */

 // HAL_GPIO_EXTI_IRQHandler(GPIO_PIN_0);

 /* USER CODE BEGIN EXTI0_1_IRQn 1 */

 /* USER CODE END EXTI0_1_IRQn 1 */

}

So

1- code written in the ISR

2- removed even LL calls, wrote the BRR

latency is now 760ns.

Thanks once again