Direct Input Capture Interrupt too slow - STM32 L476RG
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content
‎2021-08-03 7:31 AM
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:
Thank you!
Solved! Go to Solution.
- Labels:
-
STM32Cube MCU Packages
-
STM32L4 Series
-
TIM
Accepted Solutions
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content
‎2021-08-03 8:15 AM
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.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content
‎2021-08-03 8:15 AM
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.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content
‎2021-08-03 8:34 AM
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:
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.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content
‎2021-08-03 8:41 AM
> 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.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content
‎2021-08-03 8:45 AM
I'm already doing that in the main function. Am I supposed to call it more than once?
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content
‎2021-08-03 8:58 AM
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.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content
‎2021-08-03 10:21 AM
Maybe your num_pulses isnt initialised to 0 , when for example 1 ...
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content
‎2021-08-03 10:51 AM
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.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content
‎2021-08-03 12:28 PM
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.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content
‎2021-08-03 12:39 PM
> 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
