cancel
Showing results for 
Search instead for 
Did you mean: 

Direct Input Capture Interrupt too slow - STM32 L476RG

LBouz.1
Associate II

I'm trying to align an input 15 kHz signal with a 20% duty cycle with an output 15 kHz signal with a 50% duty cycle. To do this I'm hooking up the input signal to a direct capture interrupt and Timer 1 Channel 4 and using the HAL_TIM_IC_CaptureCallback function to begin my PWM timer. In doing this I notice a significant delay of 6ms as shown in the picture below. I need the delay to be on the order of 1-2µs not 6ms. Is this possible using the STM32 L476RG operating at 80 MHz? Otherwise, what are some common solutions to meeting these kinds of timing requirements?

Here is my ISR for reference:

void HAL_TIM_IC_CaptureCallback(TIM_HandleTypeDef *htim) {
	if (htim->Channel == HAL_TIM_ACTIVE_CHANNEL_4) {
		if (num_pulses == 0) {
			HAL_GPIO_WritePin(GPIOA, GPIO_PIN_12, state);
			HAL_TIM_PWM_Start(&htim2, TIM_CHANNEL_1);
			++num_pulses;
		}
		else if (num_pulses == 50) {
			if (state = 0) {
				state = 1;
			}
			else {
				state = 0;
			}
			num_pulses = 0;
		}
		else {
			++num_pulses;
		}
	}
}

Here is the delay on the logic analyzer:

0693W00000D1PsqQAF.png 

Thank you!

1 ACCEPTED SOLUTION

Accepted Solutions
TDK
Guru

There has to be something else going on. The IRQ delay isn't 6ms even with HAL overhead.

Are you sure the timer IC is ready at the time you start the other PWM signal?

Another way to do this would be to trigger the TIM2_CH1 to start when the other signal goes high. Look at the trigger slave mode for how to do this. You will still have some small fixed delay which you could eliminate by adjusting the starting CNT value.

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

View solution in original post

12 REPLIES 12
TDK
Guru

There has to be something else going on. The IRQ delay isn't 6ms even with HAL overhead.

Are you sure the timer IC is ready at the time you start the other PWM signal?

Another way to do this would be to trigger the TIM2_CH1 to start when the other signal goes high. Look at the trigger slave mode for how to do this. You will still have some small fixed delay which you could eliminate by adjusting the starting CNT value.

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

How can I make sure the timer IC is ready? The only line of code I have outside of the default and ISR is HAL_TIM_IC_Start_IT(&htim1, TIM_CHANNEL_4) which I call in the main function before the loop. Here are my timer 1 settings:

0693W00000D1QRWQA3.png0693W00000D1QSKQA3.png 

The trigger slave mode seems like a solution but the only problem is I also have to set a GPIO pin high/low at the same time so I believe I need an ISR.

> How can I make sure the timer IC is ready?

Call HAL_TIM_IC_Start_IT before you start the PWM.

You can set a pin high using another channel of the timer using trigger slave mode.

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

I'm already doing that in the main function. Am I supposed to call it more than once?

No. Must be something else going on. Perhaps the system is busy in another interrupt.
6ms at 80 MHz is 480000 ticks. It must be doing something else during that time.
But regardless, if your timing is critical, I would pursue the slave mode path and probably access timer registers directly in order to set it up.
If you feel a post has answered your question, please click "Accept as Solution".
MM..1
Chief II

Maybe your num_pulses isnt initialised to 0 , when for example 1 ...

Using the slave mode path, what type of Trigger Output (TRGO) should be used for an input capture timer? The only options are output capture ones.

It looks like "Compare Pulse (OC1)" is the correct selection here, but is only available on channel 1, at least on the chip I have up currently.

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

> Using the slave mode path, what type of Trigger Output (TRGO) should be used for an input capture timer? The only options are output capture ones.

Use "Compare Pulse" (0b11 in TIMx_CR2.MMS). It's incredibly badly named, but it sets TRGO to output a pulse whenever CC1IF is set, whether it's because of Input Capture or Output Compare. Only CH1 can be used for this purpose.

But you don't need to do that. As TDK said above, set up the timer for the PWM output but don't enable it in TIMx_CR1.CEN and connect the input signal to a channel which can trigger the Slave-mode controller set to Trigger mode (again, only CH1 and CH2 can be used). Set a third channel to Output Compare, Active on Match, and that will serve you as the pin which you want to set when the edge is detected.

JW