cancel
Showing results for 
Search instead for 
Did you mean: 

delay inside a EXTI9_5 callback function

SergeantYork
Associate II

I have been trying to create a asynchronous serial UART communication on GPIOA pin 9 and pin 8

pin9- is Rx

Pin8- is Tx

in order to sample the message at the right time I have create a dealy function using the DWT mechanism, the idea is to wait 1.5*(1/baudrate) in order to collect the message in the middle of the bit transmission in order to sample a stable line.

while I am doing so i found out that disabling the NVIC and than enabling is causing the program to Enter the interrupt again although no event has occurred on the line?

can any one explained why this is happing.

I am toggling a pin inside the interrupt and then i can see it on the logic analyzer being toggled after a long time.

here is the code

void Delay_Microsec(uint32_t delayMicroSec){

DWT->CTRL |= 1 ; // enable the counter

DWT->CYCCNT = 0; // reset the counter

volatile uint32_t cycles = (SystemCoreClock/1000000L)*delayMicroSec;

volatile uint32_t start = DWT->CYCCNT;

do {

} while(DWT->CYCCNT - start < cycles);

DWT->CTRL &= 0;

}

void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin)

{

if(GPIO_Pin == GPIO_PIN_9) // If The INT Source Is EXTI Line9 (A9 Pin)

{

HAL_GPIO_TogglePin(GPIOA, GPIO_PIN_8); // Toggle The Output

HAL_GPIO_TogglePin(GPIOA, GPIO_PIN_8); // Toggle The Output

HAL_NVIC_DisableIRQ(EXTI9_5_IRQn);

Delay_Microsec(5600);

HAL_NVIC_ClearPendingIRQ(EXTI9_5_IRQn);

HAL_NVIC_EnableIRQ(EXTI9_5_IRQn);

}

}

8 REPLIES 8
TDK
Guru

HAL_NVIC_ClearPendingIRQ clears the NVIC bit, but not the bit on the STM32 side, so it will just be set again. You want __HAL_GPIO_EXTI_CLEAR_IT(GPIO_Pin).

Since CYCCNT is a 32-bit counter, you can keep it free-running and simply use the difference of the start and end tick. The overflow works out because it is 32-bits.

No need to disable the interrupt here as an interrupt cannot preempt itself.

If you feel a post has answered your question, please click "Accept as Solution".
S.Ma
Principal

If you use a timer capture with dma, latency and jitter mostly goes away... TX with compares and off you go

how can I reset the clock counter when using tim2 interrupt do you think doing TIM->CNT will work or there is another way

SergeantYork
Associate II

it worked thanks, I am doing bare metal no DMA or HAL allowed :)

You are allowed to change CNT directly, yes.

If you feel a post has answered your question, please click "Accept as Solution".

which one is better clearing the flag of timer TIM3->SR &=~(SR_UIF);

or TIM->CNT =0 ? all in order to make the timer start counting in the moment it is enabled inside the code

> which one is better clearing the flag of timer TIM3->SR &=~(SR_UIF);

or TIM->CNT =0 ?

CNT = 0 doesn't clear any flags.

> TIM3->SR &=~(SR_UIF);

This doesn't compile as you're missing TIM_, but even then it's bad form. To clear the update flag, use:

TIM3->SR = ~TIM_SR_UIF;

> all in order to make the timer start counting in the moment it is enabled inside the code

It's not clear if your intention is to clear the update flag or set CNT=0, or possibly generate an update event.

If you feel a post has answered your question, please click "Accept as Solution".

Thanks