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!

12 REPLIES 12

These are my timer settings. I have TIM1 as an input capture on channel 1 with the trigger output set to Compare Pulse (OC1). I put TIM2 in trigger mode with the source as ITR0 and PWM on channel 1. I'm toggling a GPIO in the input capture interrupt still so I know that timer is working but I'm unable to observe anything on the TIM2 PWM line.

0693W00000D1RlIQAV.png0693W00000D1Rm1QAF.png

I'm confused what you mean by "set up the timer for the PWM output but don't enable it in TIMx_CR1.CEN"? Also, how can I connect the input signal to a trigger without using the Compare Pulse?

> I'm confused what you mean by "set up the timer for the PWM output

Set TIMx_ARR to the period you desire (including TIMx_PSC if needed, keeping in mind that PSC is uncondionally preloaded). Set the chosen output channel's TIMx_CCRx according to required duty, in respective TIMx_CCMRx leave CCxS at its default 0b00 for Output Compare and set OCxM to 0b110 or 0b111 depending on which PWM mode you've chosen. Finally, enable given channel by setting its respective TIMx_CCER.CCxE bit and if this is one of the Advanced Timers (TIM1, TIM8 and others which have complementary outputs), set TIMx_BDTR.MOE.

You probably usually solve all this by some clicking in CubeMX, I don't use that, as not everything can be clicked.

> but don't enable it in TIMx_CR1.CEN"

Well, literally that, leave TIMx_CR1.CEN cleared. It's then the Slave-mode controller in Trigger mode, which will set it, when the trigger arrives.

> Also, how can I connect the input signal to a trigger without using the Compare Pulse?

"Compare Pulse" is a mode how to output an input channel (namely CH1) onto TRGO, which is an output of given TIMx module towards *other* TIMy module. You don't need to trigger an *other* TIMy module - you can if you wish to do so, but it's unnecessary.

To trigger TIMx's Slave mode controller, set the chosen channel (CH1 or CH2) to Input Capture mode by setting the respective TIMx_CCMRx.CCxS to 0b01 (or 0b10 if you wish to trigger "the other" channel, but leave that for later if things will be more clear). There's no need to actually enable the capture in TIMx_CCER, if you don't want to perform the capture, but you can do so if you want. You can select the desired edge using TIMx_CCER.CCxP/CCxNP (note that these bits don't form a continguous bitfield). You can also set a digital filter on the channel in TIMx_CCMRx.ICxF. Now in TIMx_SMCR.TS select input to the Slave-mode Controller, 0b101 if you use CH1 or 0b110 if you use CH2; and then in TIMx_SMS select the Trigger mode.

All above assumes you have properly set the TIMx_CHx pins in GPIO, i.e. set then to AF in GPIO_MODER and selected proper AF number in GPIO_AFR[]. Again, you probably click in CubeMX.

JW