// filename: timer.c
// RealSYS KCO 2010.6.5
#include "common.h"

u16 cap1_cnt=0, cap1_r_new=0, cap1_r_old=0, cap1_f=0;
u16 pul1_width=0,pul1_period=0;

u16 cap2_cnt=0, cap2_r_new=0, cap2_r_old=0, cap2_f=0;
u16 pul2_width=0,pul2_period=0;

#define CAP31_PIN         (GPIOA->IDR & GPIO_Pin_6)         /* Timer3 ch1 pin: PA6 */
#define CAP31_POL_RISING  (TIM3->CCER &= ~TIM_CCER_CC1P)    /* Timer3 ch1: rising edge */
#define CAP31_POL_FALLING (TIM3->CCER |= TIM_CCER_CC1P)     /* Timer3 ch1: falling edge */

#define CAP32_PIN         (GPIOA->IDR & GPIO_Pin_7)         /* Timer3 ch2 pin: PA7 */
#define CAP32_POL_RISING  (TIM3->CCER &= ~TIM_CCER_CC2P);   /* Timer3 ch2: rising edge */
#define CAP32_POL_FALLING (TIM3->CCER |= TIM_CCER_CC2P);    /* Timer3 ch2: falling edge */

void init_tim_cap(void){
GPIO_InitTypeDef GPIO_InitStructure;
NVIC_InitTypeDef NVIC_InitStructure;
TIM_ICInitTypeDef  TIM_ICInitStructure;
TIM_TimeBaseInitTypeDef  TIM_TimeBaseStructure;

    /* TIM3 clock enable */
    RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE);
    /* GPIOA  clock enable */
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
    
    /* Enable the TIM3 global Interrupt */
    NVIC_InitStructure.NVIC_IRQChannel = TIM3_IRQn;
    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
    NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
    NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
    NVIC_Init(&NVIC_InitStructure);
    
    /* TIM3_ch1(PA6),TIM3_ch2(PA7) configuration */
    GPIO_InitStructure.GPIO_Pin =  GPIO_Pin_6 | GPIO_Pin_7;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_Init(GPIOA, &GPIO_InitStructure);

    /* Time base configuration */
    TIM_TimeBaseStructure.TIM_Period = 65535;
    TIM_TimeBaseStructure.TIM_Prescaler = 72-1; // 1 usec for 72MHz clock
    TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1;
    TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
    TIM_TimeBaseInit(TIM3, &TIM_TimeBaseStructure);
    
    TIM_ICInitStructure.TIM_ICPolarity = TIM_ICPolarity_Rising;
    TIM_ICInitStructure.TIM_ICSelection = TIM_ICSelection_DirectTI;
    TIM_ICInitStructure.TIM_ICPrescaler = TIM_ICPSC_DIV1;
    TIM_ICInitStructure.TIM_ICFilter = 0x0;
    TIM_ICInitStructure.TIM_Channel = TIM_Channel_1;
    TIM_ICInit(TIM3, &TIM_ICInitStructure);

    TIM_ICInitStructure.TIM_Channel = TIM_Channel_2;
    TIM_ICInit(TIM3, &TIM_ICInitStructure);

    /* TIM enable counter */
    TIM_Cmd(TIM3, ENABLE);
    
    /* Enable the CC2 Interrupt Request */
    TIM_ITConfig(TIM3, TIM_IT_CC1 | TIM_IT_CC2, ENABLE);
}

void TIM3_IRQHandler(void){ 
    if((TIM3->SR & TIM_IT_CC1)&&(TIM3->DIER & TIM_IT_CC1)){
        cap1_cnt++;
        TIM3->SR = (u16)~TIM_IT_CC1;    // clear flag
        if(CAP31_PIN){  // Timer3 Ch1 pin(PA6) is High
            cap1_r_new = TIM3->CCR1; // read capture data
            pul1_period = (u32)(cap1_r_new - cap1_r_old);
            cap1_r_old = cap1_r_new;
            CAP31_POL_FALLING;  // to falling edge
        }
        else{   // Timer3 Ch1 pin(PA6) is Low
            cap1_f = TIM3->CCR1; // read capture data
            pul1_width = (u32)(cap1_f - cap1_r_new);
            CAP31_POL_RISING;   // to rising edge
        }
    }
    
    if((TIM3->SR & TIM_IT_CC2)&&(TIM3->DIER & TIM_IT_CC2)){
        cap2_cnt++;
        TIM3->SR = (u16)~TIM_IT_CC2;    // clear flag
        if(CAP32_PIN){  // Timer3 Ch2 pin(PA7) is High
            cap2_r_new = TIM3->CCR2; // read capture data
            pul2_period = (u32)(cap2_r_new - cap2_r_old);
            cap2_r_old = cap2_r_new;
            CAP32_POL_FALLING;  // to falling edge
        }
        else{   // Timer3 Ch2 pin(PA7) is Low
            cap2_f = TIM3->CCR2; // read capture data
            pul2_width = (u32)(cap2_f - cap2_r_new);
            CAP32_POL_RISING;   // to rising edge
        }
    }
}