cancel
Showing results for 
Search instead for 
Did you mean: 

STM32G030 Interrupt latency

ferrario
Associate III

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

1 ACCEPTED SOLUTION

Accepted Solutions
ferrario
Associate III

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

View solution in original post

11 REPLIES 11
Javier1
Principal

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....

we dont need to firmware by ourselves, lets talk
ferrario
Associate III

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

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?

we dont need to firmware by ourselves, lets talk

>>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
Up vote any posts that you find helpful, it shows what's working..
TDK
Guru

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".

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

Vector Table in RAM Crashes

 .isr_vector :

 {

   . = ALIGN(4);

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

   . = ALIGN(4);

 } >RAM

Thanks

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?

ferrario
Associate III

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