Skip to main content
Explorer II
July 18, 2024
Question

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

  • July 18, 2024
  • 2 replies
  • 983 views

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

    Super User
    July 18, 2024
    Explorer II
    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);
    
     }