cancel
Showing results for 
Search instead for 
Did you mean: 

STM32G4 Timer 1 Input Capture Channel 2 to tim_trgo

mariankeller
Associate II

Hello,

I'm trying to trigger another timer from a rising edge on PA9. I tried to do this by using input capture from timer1 and generating a trigger out, but there seems to be some configuration issue. Triggering a DMA transfer using channel 2 input capture works just fine, triggering the other timer just using PWM mode channel 2 also works, but for input capture channel 2 to trigger out, nothing happens. The code below works for channel 1:

 

 

	GPIO_InitStruct.Pin = GPIO_PIN_8;
	GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
	GPIO_InitStruct.Pull = GPIO_NOPULL;
	GPIO_InitStruct.Speed = GPIO_SPEED_LOW;
	GPIO_InitStruct.Alternate = GPIO_AF6_TIM1;
	HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);

	// Timer 1 Configuration
	TIM1->CR2 &= ~TIM_CR2_MMS; // Clear MMS bits
	TIM1->CR2 |= TIM_TRGO_OC1; // use CC1 event for TRGO

	TIM1->CCMR1 &= ~(TIM_CCMR1_CC1S); // Clear CC1S bits
	TIM1->CCMR1 |= TIM_CCMR1_CC1S_0; // Set CC1 as input, IC1 mapped on TI1

	TIM1->CCER |= TIM_CCER_CC1E; // Enable capture on channel 1

	// Ensure TIM1 is enabled
	TIM1->CR1 |= TIM_CR1_CEN;

 

 

 But this code doesn't work for channel 2:

 

 

	GPIO_InitStruct.Pin = GPIO_PIN_9;
	GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
	GPIO_InitStruct.Pull = GPIO_NOPULL;
	GPIO_InitStruct.Speed = GPIO_SPEED_LOW;
	GPIO_InitStruct.Alternate = GPIO_AF6_TIM1;
	HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);

	// Timer 1 Configuration
	TIM1->CR2 &= ~TIM_CR2_MMS; // Clear MMS bits
	TIM1->CR2 |= TIM_TRGO_OC2REF; // Set MMS to 101 to use CC2 event as TRGO

	TIM1->CCMR1 &= ~(TIM_CCMR1_CC2S); // Clear CC2S bits
	TIM1->CCMR1 |= TIM_CCMR1_CC2S_0; // Set CC2 as input, IC2 mapped on TI2

	TIM1->CCER |= TIM_CCER_CC2E; // Enable capture on channel 2

	// Ensure TIM1 is enabled
	TIM1->CR1 |= TIM_CR1_CEN;

 

 

Strangely, for channel 1, it only works with the define TIM_TRGO_OC1 which maps to Compare Pulse Master Mode, not with TIM_TRGO_OC1REF, which maps to Compare tim_oc1refc.

This code does successfully generate DMA requests:

GPIO_InitStruct.Pin = GPIO_PIN_9;
	GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
	GPIO_InitStruct.Pull = GPIO_NOPULL;
	GPIO_InitStruct.Speed = GPIO_SPEED_LOW;
	GPIO_InitStruct.Alternate = GPIO_AF6_TIM1;
	HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);

	TIM1->CCMR1 |= (TIM_ICSELECTION_DIRECTTI << 8U);
	TIM1->DIER = TIM_DIER_CC2DE; //UDE Update DMA request enable
	TIM1->CCER |= TIM_CCER_CC2E; // Enable capture on channel 2

 

1 ACCEPTED SOLUTION

Accepted Solutions

Only CH1 Capture can be used as TRGO source. This is an inherent limitation, see description of TIMx_CR2.MMS in RM (although this selection, 0b0011, is very incorrectly called "Compare Pulse" there, the remainder of description correctly includes Capture).

OCxRef is output of the Compare's comparator.

One way to tackle this is to use the "channel redirection", i.e. set TIMx_CCMR1.CC1S to 0b10; in that way the signal on the CH2 pin is used to capture in CH1, and that then can be used as TRGO. Otherwise, you should design your hardware to match the capabilities of the mcu.

Btw. using Cube/HAL-defined symbols in register access is a bad idea, they often don't have the value what you think they do based on their names. Better stick to whatever is defined in the CMSIS-mandated device header, use numerical constants, or define your own symbols.

JW

 

View solution in original post

1 REPLY 1

Only CH1 Capture can be used as TRGO source. This is an inherent limitation, see description of TIMx_CR2.MMS in RM (although this selection, 0b0011, is very incorrectly called "Compare Pulse" there, the remainder of description correctly includes Capture).

OCxRef is output of the Compare's comparator.

One way to tackle this is to use the "channel redirection", i.e. set TIMx_CCMR1.CC1S to 0b10; in that way the signal on the CH2 pin is used to capture in CH1, and that then can be used as TRGO. Otherwise, you should design your hardware to match the capabilities of the mcu.

Btw. using Cube/HAL-defined symbols in register access is a bad idea, they often don't have the value what you think they do based on their names. Better stick to whatever is defined in the CMSIS-mandated device header, use numerical constants, or define your own symbols.

JW