2021-10-20 03: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.
2021-10-20 08: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
2021-10-20 03: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....
2021-10-20 04: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
2021-10-20 06: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?
2021-10-20 06: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
2021-10-20 06: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.
2021-10-20 08: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
2021-10-20 08:18 AM
Vector Table in RAM Crashes
.isr_vector :
{
. = ALIGN(4);
KEEP(*(.isr_vector)) /* Startup code */
. = ALIGN(4);
} >RAM
Thanks
2021-10-20 08: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?
2021-10-20 08: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