Skip to main content
Associate III
July 18, 2024
Question

I get same Capture Value when using input capture mode on the same timer

Hi,

 

I basically have two PWM signals going into two pin that are set to be TIM4_CH1 and TIM4_CH2.

I setup both channels in slave mode and enabled the input capture mode on Rising mode.

When I enable only channel 1 and the code below get executed I retrieve the correct CCR1 values and consecutively I calculate the correct duty cycle.

Problem: When I enable both channels I get the same CCR1 and CCR2 value, all the time, so the duty cycle is always 100%

 

Input capture mode on "Both_Edges" mode work strangely because instead of getting the rising and falling edge captures consecutively I get them randomly: sometimes I just get the falling, sometimes only the rising and most of the time random pattern ( ex. rising, rising, falling, rising). So I opted to switch edge detection mode everytime I capture the value.

 

 

 

void TIM4_IRQ_PWM(void)
{
	if (TIM_GetITStatus(TIM4, TIM_IT_CC1) != RESET) {
			tmyPWMInput *pPWM4_1 = &myCTRL.myHW.myPortDCfg.myPWM4_1; //PIN12
			 // Clear TIM8 Capture Compare1 interrupt pending bit
			TIM_ClearITPendingBit(TIM4, TIM_IT_CC1);

			if ( is_rising_ch1 )
			{
				pPWM4_1->FullPeriod = TIM_GetCapture1(TIM4);

				TIM_CH1_ICInitStructure.TIM_Channel 		= TIM_Channel_1;
				TIM_CH1_ICInitStructure.TIM_ICPolarity 		= TIM_ICPolarity_Falling;
				TIM_CH1_ICInitStructure.TIM_ICSelection 	= TIM_ICSelection_DirectTI;
				TIM_CH1_ICInitStructure.TIM_ICPrescaler 	= TIM_ICPSC_DIV1;
				TIM_CH1_ICInitStructure.TIM_ICFilter 		= 0x0;
				TIM_ICInit(TIM4, &TIM_CH1_ICInitStructure);
				is_rising_ch1 = 0;

			}
			else
			{
				pPWM4_1->HighPeriod = TIM_GetCapture1(TIM4);

				TIM_CH1_ICInitStructure.TIM_Channel 		= TIM_Channel_1;
				TIM_CH1_ICInitStructure.TIM_ICPolarity 		= TIM_ICPolarity_Rising;
				TIM_CH1_ICInitStructure.TIM_ICSelection 	= TIM_ICSelection_DirectTI;
				TIM_CH1_ICInitStructure.TIM_ICPrescaler 	= TIM_ICPSC_DIV1;
				TIM_CH1_ICInitStructure.TIM_ICFilter 		= 0x0;
				TIM_ICInit(TIM4, &TIM_CH1_ICInitStructure);
				is_rising_ch1 = 1;
			}

			//To prevent division by 0 on duty cycle calculation
			if ( pPWM4_1->FullPeriod != 0 )
				myPWMCalc(pPWM4_1);


	}
	if (TIM_GetITStatus(TIM4, TIM_IT_CC2) != RESET) {
			tmyPWMInput *pPWM4_2 = &myCTRL.myHW.myPortDCfg.myPWM4_2; //PIN13
			 // Clear TIM8 Capture Compare1 interrupt pending bit
			TIM_ClearITPendingBit(TIM4, TIM_IT_CC2);

			if ( is_rising_ch2 )
			{
				pPWM4_2->FullPeriod = TIM_GetCapture2(TIM4);

				TIM_CH2_ICInitStructure.TIM_Channel 		= TIM_Channel_2;
				TIM_CH2_ICInitStructure.TIM_ICPolarity 		= TIM_ICPolarity_Falling;
				TIM_CH2_ICInitStructure.TIM_ICSelection 	= TIM_ICSelection_DirectTI;
				TIM_CH2_ICInitStructure.TIM_ICPrescaler 	= TIM_ICPSC_DIV1;
				TIM_CH2_ICInitStructure.TIM_ICFilter 		= 0x0;
				TIM_ICInit(TIM4, &TIM_CH2_ICInitStructure);
				is_rising_ch2 = 0;

			}
			else
			{
				pPWM4_2->HighPeriod = TIM_GetCapture2(TIM4);

				TIM_CH2_ICInitStructure.TIM_Channel 		= TIM_Channel_2;
				TIM_CH2_ICInitStructure.TIM_ICPolarity 		= TIM_ICPolarity_Rising;
				TIM_CH2_ICInitStructure.TIM_ICSelection 	= TIM_ICSelection_DirectTI;
				TIM_CH2_ICInitStructure.TIM_ICPrescaler 	= TIM_ICPSC_DIV1;
				TIM_CH2_ICInitStructure.TIM_ICFilter 		= 0x0;
				TIM_ICInit(TIM4, &TIM_CH2_ICInitStructure);
				is_rising_ch2 = 1;
			}

			//To prevent division by 0 on duty cycle calculation
			if ( pPWM4_2->FullPeriod != 0 )
					myPWMCalc(pPWM4_2);
					
	}

}

 

 

 

This topic has been closed for replies.

2 replies

TDK
July 18, 2024
"If you feel a post has answered your question, please click ""Accept as Solution""."
Associate III
July 19, 2024

Hardware:

  • Test bench that generates two PWM signals ( A and B )
  • Cable that connect the test bench to the other board
  • Other board that retrieves the PWM signals (Port D pin 12 and 13 ) and has to calculate Duty Cycle and Frequency.

Library: Standard Peripheral Library ( I have to use this one )

What I did:

  • Enabled Input Capture Mode on CH1 on Rising Edge ( Note that BothEdge gave me some problems so I opted to not use it), SlaveMode_Reset, Enabled CC1 interrupt
  • Enabled Input Capture Mode on CH2 on Rising Edge ( Note that BothEdge gave me some problems so I opted to not use it), SlaveMode_Reset, Enabled CC2 interrupt
  • Inside the IRQ I clear the flag, read the captured value and switch capture mode to rising or falling , depending on the previous state.

Problem: When Enabling only CH1 the captured values are different and the calculated Duty Cycle is correct, but as soon as I enable the CH2 as well the CCR1 and CCR2 I get to read are the same for all captures ( I basically read only the rising edge)

 

Pin 12 Configuration Code:

 

void myPWM4_Config_1(tmyPWMInput *me)
{
 RCC_ClocksTypeDef __RCC_CLOCK;

 myPWMInputCtor(me);

 RCC_GetClocksFreq(&__RCC_CLOCK);
 me->clock = __RCC_CLOCK.PCLK1_Frequency * 2; //APB1

 RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM4, ENABLE);
 RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOD, ENABLE);

 me->GPIO_InitStructure.GPIO_Pin = GPIO_Pin_12;
 me->GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
 me->GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;
 me->GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
 me->GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;

 GPIO_Init(GPIOD, &me->GPIO_InitStructure);

 GPIO_PinAFConfig(GPIOD, GPIO_PinSource12, GPIO_AF_TIM4);

 TIM4_IRQHandler_ptf = TIM4_IRQ_PWM;
 me->NVIC_InitStructure.NVIC_IRQChannel = TIM4_IRQn;
 me->NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;
 me->NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
 me->NVIC_InitStructure.NVIC_IRQChannelCmd = 1;
 NVIC_Init(&me->NVIC_InitStructure);

 me->TIM_TimeBaseStructure.TIM_Period = 0xFFFF;
 me->TIM_TimeBaseStructure.TIM_Prescaler = 840 - 1;
 me->TIM_TimeBaseStructure.TIM_CounterMode=TIM_CounterMode_Up;
 me->TIM_TimeBaseStructure.TIM_ClockDivision= TIM_CKD_DIV1;
 me->TIM_TimeBaseStructure.TIM_RepetitionCounter = 0;

 TIM_TimeBaseInit(TIM4, &me->TIM_TimeBaseStructure);

 me->TIM_CH1_ICInitStructure.TIM_Channel = TIM_Channel_1;
 me->TIM_CH1_ICInitStructure.TIM_ICPolarity = TIM_ICPolarity_BothEdge;
 me->TIM_CH1_ICInitStructure.TIM_ICSelection = TIM_ICSelection_DirectTI;
 me->TIM_CH1_ICInitStructure.TIM_ICPrescaler = TIM_ICPSC_DIV1;
 me->TIM_CH1_ICInitStructure.TIM_ICFilter = 0x0;

 TIM_ICInit(TIM4, &me->TIM_CH1_ICInitStructure);
 //TIM_PWMIConfig(TIM4, &me->TIM_CH1_ICInitStructure);
 // Select the TIM4Input Trigger: TI1FP1
 TIM_SelectInputTrigger(TIM4, TIM_TS_TI1FP1);
 // Select the slave Mode: Reset Mode
 TIM_SelectSlaveMode(TIM4, TIM_SlaveMode_Reset);

 TIM_SelectMasterSlaveMode(TIM4, TIM_MasterSlaveMode_Enable);
 // Enables TIM4 peripheral Preload register on ARR.
 TIM_ARRPreloadConfig(TIM4, ENABLE);
 // Configures the TIM8 Update Request Interrupt source (SETS the CR1->URS bit)
 //TIM_UpdateRequestConfig(TIM4, TIM_UpdateSource_Regular);

 // Enable the CC1 and the update Interrupt Request
 TIM_ITConfig(TIM4, TIM_IT_CC1, ENABLE);

 TIM_ClearFlag(TIM4, TIM_FLAG_Update);
 TIM_Cmd(TIM4, ENABLE);
}

 

 

Pin 13 Configuration Code:

 

void myPWM4_Config_2(tmyPWMInput *me)
{
 RCC_ClocksTypeDef __RCC_CLOCK;

 myPWMInputCtor(me);

 RCC_GetClocksFreq(&__RCC_CLOCK);
 me->clock = __RCC_CLOCK.PCLK1_Frequency * 2; //APB1

 RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM4, ENABLE);
 RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOD, ENABLE);

 me->GPIO_InitStructure.GPIO_Pin = GPIO_Pin_13;
 me->GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
 me->GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;
 me->GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
 me->GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;

 GPIO_Init(GPIOD, &me->GPIO_InitStructure);

 GPIO_PinAFConfig(GPIOD, GPIO_PinSource13, GPIO_AF_TIM4);

 TIM4_IRQHandler_ptf = TIM4_IRQ_PWM;
 me->NVIC_InitStructure.NVIC_IRQChannel = TIM4_IRQn;
 me->NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;
 me->NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
 me->NVIC_InitStructure.NVIC_IRQChannelCmd = 1;
 NVIC_Init(&me->NVIC_InitStructure);

 me->TIM_TimeBaseStructure.TIM_Period = 0xFFFF;
 me->TIM_TimeBaseStructure.TIM_Prescaler = 840 - 1;
 me->TIM_TimeBaseStructure.TIM_CounterMode=TIM_CounterMode_Up;
 me->TIM_TimeBaseStructure.TIM_ClockDivision= TIM_CKD_DIV1;
 me->TIM_TimeBaseStructure.TIM_RepetitionCounter = 0;

 TIM_TimeBaseInit(TIM4, &me->TIM_TimeBaseStructure);

 me->TIM_CH2_ICInitStructure.TIM_Channel = TIM_Channel_2;
 me->TIM_CH2_ICInitStructure.TIM_ICPolarity = TIM_ICPolarity_BothEdge;
 me->TIM_CH2_ICInitStructure.TIM_ICSelection = TIM_ICSelection_DirectTI;
 me->TIM_CH2_ICInitStructure.TIM_ICPrescaler = TIM_ICPSC_DIV1;
 me->TIM_CH2_ICInitStructure.TIM_ICFilter = 0x0;

 TIM_ICInit(TIM4, &me->TIM_CH2_ICInitStructure);
 //TIM_PWMIConfig(TIM4, &me->TIM_CH2_ICInitStructure);
 // Select the TIM4Input Trigger: TI2FP2
 TIM_SelectInputTrigger(TIM4, TIM_TS_TI2FP2);
 // Select the slave Mode: Reset Mode
 TIM_SelectSlaveMode(TIM4, TIM_SlaveMode_Reset);

 TIM_SelectMasterSlaveMode(TIM4, TIM_MasterSlaveMode_Enable);
 // Enables TIM4peripheral Preload register on ARR.
 TIM_ARRPreloadConfig(TIM4, ENABLE);
 // Configures the TIM8 Update Request Interrupt source (SETS the CR1->URS bit)
 TIM_UpdateRequestConfig(TIM4, TIM_UpdateSource_Regular);

 // Enable the CC1 and the update Interrupt Request
 TIM_ITConfig(TIM4, TIM_IT_CC2, ENABLE);

 TIM_ClearFlag(TIM4, TIM_FLAG_Update);
 TIM_Cmd(TIM4, ENABLE);
}

 

Hardware:

  • Test bench that generates two PWM signals ( A and B )
  • Cable that connect the test bench to the other board
  • Other board that retrieves the PWM signals (Port D pin 12 and 13 ) and has to calculate Duty Cycle and Frequency.

Library: Standard Peripheral Library ( I have to use this one )

What I did:

  • Enabled Input Capture Mode on CH1 on Rising Edge ( Note that BothEdge gave me some problems so I opted to not use it), SlaveMode_Reset, Enabled CC1 interrupt
  • Enabled Input Capture Mode on CH2 on Rising Edge ( Note that BothEdge gave me some problems so I opted to not use it), SlaveMode_Reset, Enabled CC2 interrupt
  • Inside the IRQ I clear the flag, read the captured value and switch capture mode to rising or falling , depending on the previous state.

Problem: When Enabling only CH1 the captured values are different and the calculated Duty Cycle is correct, but as soon as I enable the CH2 as well the CCR1 and CCR2 I get to read are the same for all captures ( I basically read only the rising edge)

Pin 12 Configuration Code:

void myPWM4_Config_1(tmyPWMInput *me)
{
 RCC_ClocksTypeDef __RCC_CLOCK;

 myPWMInputCtor(me);

 RCC_GetClocksFreq(&__RCC_CLOCK);
 me->clock = __RCC_CLOCK.PCLK1_Frequency * 2; //APB1

 RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM4, ENABLE);
 RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOD, ENABLE);

 me->GPIO_InitStructure.GPIO_Pin = GPIO_Pin_12;
 me->GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
 me->GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;
 me->GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
 me->GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;

 GPIO_Init(GPIOD, &me->GPIO_InitStructure);

 GPIO_PinAFConfig(GPIOD, GPIO_PinSource12, GPIO_AF_TIM4);

 TIM4_IRQHandler_ptf = TIM4_IRQ_PWM;
 me->NVIC_InitStructure.NVIC_IRQChannel = TIM4_IRQn;
 me->NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;
 me->NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
 me->NVIC_InitStructure.NVIC_IRQChannelCmd = 1;
 NVIC_Init(&me->NVIC_InitStructure);

 me->TIM_TimeBaseStructure.TIM_Period = 0xFFFF;
 me->TIM_TimeBaseStructure.TIM_Prescaler = 840 - 1;
 me->TIM_TimeBaseStructure.TIM_CounterMode=TIM_CounterMode_Up;
 me->TIM_TimeBaseStructure.TIM_ClockDivision= TIM_CKD_DIV1;
 me->TIM_TimeBaseStructure.TIM_RepetitionCounter = 0;

 TIM_TimeBaseInit(TIM4, &me->TIM_TimeBaseStructure);

 me->TIM_CH1_ICInitStructure.TIM_Channel = TIM_Channel_1;
 me->TIM_CH1_ICInitStructure.TIM_ICPolarity = TIM_ICPolarity_BothEdge;
 me->TIM_CH1_ICInitStructure.TIM_ICSelection = TIM_ICSelection_DirectTI;
 me->TIM_CH1_ICInitStructure.TIM_ICPrescaler = TIM_ICPSC_DIV1;
 me->TIM_CH1_ICInitStructure.TIM_ICFilter = 0x0;

 TIM_ICInit(TIM4, &me->TIM_CH1_ICInitStructure);
 //TIM_PWMIConfig(TIM4, &me->TIM_CH1_ICInitStructure);
 // Select the TIM4Input Trigger: TI1FP1
 TIM_SelectInputTrigger(TIM4, TIM_TS_TI1FP1);
 // Select the slave Mode: Reset Mode
 TIM_SelectSlaveMode(TIM4, TIM_SlaveMode_Reset);

 TIM_SelectMasterSlaveMode(TIM4, TIM_MasterSlaveMode_Enable);
 // Enables TIM4 peripheral Preload register on ARR.
 TIM_ARRPreloadConfig(TIM4, ENABLE);
 // Configures the TIM8 Update Request Interrupt source (SETS the CR1->URS bit)
 //TIM_UpdateRequestConfig(TIM4, TIM_UpdateSource_Regular);

 // Enable the CC1 and the update Interrupt Request
 TIM_ITConfig(TIM4, TIM_IT_CC1, ENABLE);

 TIM_ClearFlag(TIM4, TIM_FLAG_Update);
 TIM_Cmd(TIM4, ENABLE);
}

Pin 13 Configuration Code:

void myPWM4_Config_2(tmyPWMInput *me)
{
 RCC_ClocksTypeDef __RCC_CLOCK;

 myPWMInputCtor(me);

 RCC_GetClocksFreq(&__RCC_CLOCK);
 me->clock = __RCC_CLOCK.PCLK1_Frequency * 2; //APB1

 RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM4, ENABLE);
 RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOD, ENABLE);

 me->GPIO_InitStructure.GPIO_Pin = GPIO_Pin_13;
 me->GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
 me->GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;
 me->GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
 me->GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;

 GPIO_Init(GPIOD, &me->GPIO_InitStructure);

 GPIO_PinAFConfig(GPIOD, GPIO_PinSource13, GPIO_AF_TIM4);

 TIM4_IRQHandler_ptf = TIM4_IRQ_PWM;
 me->NVIC_InitStructure.NVIC_IRQChannel = TIM4_IRQn;
 me->NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;
 me->NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
 me->NVIC_InitStructure.NVIC_IRQChannelCmd = 1;
 NVIC_Init(&me->NVIC_InitStructure);

 me->TIM_TimeBaseStructure.TIM_Period = 0xFFFF;
 me->TIM_TimeBaseStructure.TIM_Prescaler = 840 - 1;
 me->TIM_TimeBaseStructure.TIM_CounterMode=TIM_CounterMode_Up;
 me->TIM_TimeBaseStructure.TIM_ClockDivision= TIM_CKD_DIV1;
 me->TIM_TimeBaseStructure.TIM_RepetitionCounter = 0;

 TIM_TimeBaseInit(TIM4, &me->TIM_TimeBaseStructure);

 me->TIM_CH2_ICInitStructure.TIM_Channel = TIM_Channel_2;
 me->TIM_CH2_ICInitStructure.TIM_ICPolarity = TIM_ICPolarity_BothEdge;
 me->TIM_CH2_ICInitStructure.TIM_ICSelection = TIM_ICSelection_DirectTI;
 me->TIM_CH2_ICInitStructure.TIM_ICPrescaler = TIM_ICPSC_DIV1;
 me->TIM_CH2_ICInitStructure.TIM_ICFilter = 0x0;

 TIM_ICInit(TIM4, &me->TIM_CH2_ICInitStructure);
 //TIM_PWMIConfig(TIM4, &me->TIM_CH2_ICInitStructure);
 // Select the TIM4Input Trigger: TI2FP2
 TIM_SelectInputTrigger(TIM4, TIM_TS_TI2FP2);
 // Select the slave Mode: Reset Mode
 TIM_SelectSlaveMode(TIM4, TIM_SlaveMode_Reset);

 TIM_SelectMasterSlaveMode(TIM4, TIM_MasterSlaveMode_Enable);
 // Enables TIM4peripheral Preload register on ARR.
 TIM_ARRPreloadConfig(TIM4, ENABLE);
 // Configures the TIM8 Update Request Interrupt source (SETS the CR1->URS bit)
 TIM_UpdateRequestConfig(TIM4, TIM_UpdateSource_Regular);

 // Enable the CC1 and the update Interrupt Request
 TIM_ITConfig(TIM4, TIM_IT_CC2, ENABLE);

 TIM_ClearFlag(TIM4, TIM_FLAG_Update);
 TIM_Cmd(TIM4, ENABLE);
}

IRQ Code:

 

if (TIM_GetITStatus(TIM4, TIM_IT_CC1) != RESET) {
 tmyPWMInput *pPWM4_1 = &myCTRL.myHW.myPortDCfg.myPWM4_1; //PIN12
 // Clear TIM8 Capture Compare1 interrupt pending bit
 TIM_ClearITPendingBit(TIM4, TIM_IT_CC1);

 if ( is_rising_ch1 )
 {
 pPWM4_1->FullPeriod = TIM_GetCapture1(TIM4);

 TIM_CH1_ICInitStructure.TIM_Channel = TIM_Channel_1;
 TIM_CH1_ICInitStructure.TIM_ICPolarity = TIM_ICPolarity_Falling;
 TIM_CH1_ICInitStructure.TIM_ICSelection = TIM_ICSelection_DirectTI;
 TIM_CH1_ICInitStructure.TIM_ICPrescaler = TIM_ICPSC_DIV1;
 TIM_CH1_ICInitStructure.TIM_ICFilter = 0x0;
 TIM_ICInit(TIM4, &TIM_CH1_ICInitStructure);
 is_rising_ch1 = 0;

 }
 else
 {
 pPWM4_1->HighPeriod = TIM_GetCapture1(TIM4);

 TIM_CH1_ICInitStructure.TIM_Channel = TIM_Channel_1;
 TIM_CH1_ICInitStructure.TIM_ICPolarity = TIM_ICPolarity_Rising;
 TIM_CH1_ICInitStructure.TIM_ICSelection = TIM_ICSelection_DirectTI;
 TIM_CH1_ICInitStructure.TIM_ICPrescaler = TIM_ICPSC_DIV1;
 TIM_CH1_ICInitStructure.TIM_ICFilter = 0x0;
 TIM_ICInit(TIM4, &TIM_CH1_ICInitStructure);
 is_rising_ch1 = 1;
 }

 //To prevent division by 0 on duty cycle calculation
 if ( pPWM4_1->FullPeriod != 0 )
 myPWMCalc(pPWM4_1);


 }
 if (TIM_GetITStatus(TIM4, TIM_IT_CC2) != RESET) {
 tmyPWMInput *pPWM4_2 = &myCTRL.myHW.myPortDCfg.myPWM4_2; //PIN13
 // Clear TIM8 Capture Compare1 interrupt pending bit
 TIM_ClearITPendingBit(TIM4, TIM_IT_CC2);

 if ( is_rising_ch2 )
 {
 pPWM4_2->FullPeriod = TIM_GetCapture2(TIM4);

 TIM_CH2_ICInitStructure.TIM_Channel = TIM_Channel_2;
 TIM_CH2_ICInitStructure.TIM_ICPolarity = TIM_ICPolarity_Falling;
 TIM_CH2_ICInitStructure.TIM_ICSelection = TIM_ICSelection_DirectTI;
 TIM_CH2_ICInitStructure.TIM_ICPrescaler = TIM_ICPSC_DIV1;
 TIM_CH2_ICInitStructure.TIM_ICFilter = 0x0;
 TIM_ICInit(TIM4, &TIM_CH2_ICInitStructure);
 is_rising_ch2 = 0;

 }
 else
 {
 pPWM4_2->HighPeriod = TIM_GetCapture2(TIM4);

 TIM_CH2_ICInitStructure.TIM_Channel = TIM_Channel_2;
 TIM_CH2_ICInitStructure.TIM_ICPolarity = TIM_ICPolarity_Rising;
 TIM_CH2_ICInitStructure.TIM_ICSelection = TIM_ICSelection_DirectTI;
 TIM_CH2_ICInitStructure.TIM_ICPrescaler = TIM_ICPSC_DIV1;
 TIM_CH2_ICInitStructure.TIM_ICFilter = 0x0;
 TIM_ICInit(TIM4, &TIM_CH2_ICInitStructure);
 is_rising_ch2 = 1;
 }

 //To prevent division by 0 on duty cycle calculation
 if ( pPWM4_2->FullPeriod != 0 )
 myPWMCalc(pPWM4_2);

 }