STM32G030 Interrupt latency
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content
‎2021-10-20 3:07 AM
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
Solved! Go to Solution.
- Labels:
-
Interrupt
-
STM32G0 Series
Accepted Solutions
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content
‎2021-10-20 8:47 AM
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
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content
‎2021-10-20 3:22 AM
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
I dont know how much time this will save you....
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content
‎2021-10-20 4:47 AM
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
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content
‎2021-10-20 6:05 AM
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?
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content
‎2021-10-20 6:26 AM
>>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
Up vote any posts that you find helpful, it shows what's working..
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content
‎2021-10-20 6:44 AM
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.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content
‎2021-10-20 8:14 AM
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
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content
‎2021-10-20 8:18 AM
Vector Table in RAM Crashes
.isr_vector :
{
. = ALIGN(4);
KEEP(*(.isr_vector)) /* Startup code */
. = ALIGN(4);
} >RAM
Thanks
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content
‎2021-10-20 8:32 AM
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?
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content
‎2021-10-20 8:47 AM
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
