cancel
Showing results for 
Search instead for 
Did you mean: 

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

EmbeddedPepe
Associate III

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);
					
	}

}

 

 

 

2 REPLIES 2
TDK
Guru

Related/duplicate:

Reading two PWM signals using only two channels. - STMicroelectronics Community

 

If you feel a post has answered your question, please click "Accept as Solution".
EmbeddedPepe
Associate III

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);

    }