/*
  ******************************************************************************
  * @ app.h
  *  Time base Demo source code.
  ******************************************************************************
*/
#include "app.h" 
#include "fxx_it.h"

#define PERIOD_MAX_VALUE   0xFFFFU  

TIM_Base_InitTypeDef TIM_TimeBaseStructure;    
TIM_IC_InitTypeDef Tim_IC_Init_Para;     

void Clock_Configuration(void);
void GPIO_Configuration(void);
void NVIC_Configuration(void);   

void NVIC_Configuration(void)
{
    NVIC_ClearPendingIRQ(TIM1_CC_IRQn);   
	NVIC_EnableIRQ(TIM1_CC_IRQn);  
} 

void Clock_Configuration(void)
{
    System_Module_Enable(EN_TIM1);   
}  

GPIO_InitTypeDef gpio_init;  
void GPIO_Configuration(void)  
{	
	gpio_init.Pin = GPIO_PIN_8;  //TIM1_CH1  
	gpio_init.Mode = GPIO_MODE_AF_PP;          
	gpio_init.Pull = GPIO_NOPULL;    
	gpio_init.Alternate = GPIO_FUNCTION_2;         
	GPIO_Init(GPIOC, &gpio_init);    // PC8     
}

/**********************************************************************************************
* Function    : TIM1_IC1_Init      
* Description : timer capture by channel 1 initiation, includes clock, gpio, capture channel.  
* Input       : none    
* Output      : none 
* Author      : xwl                       
******************************************************************************************************/  
void TIM1_IC1_Init(void)  
{       	    
	Tim_IC_Init_Para.TIFilter = TIM_TI1_FILTER_LVL(0);    // no filter    
	Tim_IC_Init_Para.ICPolarity = TIM_SLAVE_CAPTURE_ACTIVE_FALLING;         
	Tim_IC_Init_Para.ICPrescaler = TIM_IC1_PRESCALER_1; 
	Tim_IC_Init_Para.ICSelection = TIM_ICSELECTION_DIRECTTI;     // TI1FP1 	 
	TIM_ICInit(TIM1, &Tim_IC_Init_Para,  TIM_CHANNEL_1);      		 
} 

/****************************************************************************************************
* Function    : TIM1_IC2_Init      
* Description : timer capture by channel 2 initiation, includes clock, gpio, capture channel.    
* Input       : none    
* Output      : none 
* Author      : xwl                       
******************************************************************************************************/ 
void TIM1_IC2_Init(void)  
{        
	Tim_IC_Init_Para.TIFilter = TIM_TI1_FILTER_LVL(0);    // filter configuration     
	Tim_IC_Init_Para.ICPolarity = TIM_SLAVE_CAPTURE_ACTIVE_FALLING;         
	Tim_IC_Init_Para.ICPrescaler = TIM_IC2_PRESCALER_1; 
	Tim_IC_Init_Para.ICSelection = TIM_ICSELECTION_INDIRECTTI;     // TI1FP2->IC2, it is indirect way  	   
    TIM_ICInit(TIM1, &Tim_IC_Init_Para,  TIM_CHANNEL_2);    
}  

void TIM1_Base_Init(void)  
{
    uint32_t timer_clock;    
    
    timer_clock = System_Get_APBClock();     
    if (System_Get_SystemClock() != timer_clock)  // if hclk/pclk != 1, then timer clk = pclk * 2  
    {
       timer_clock =  System_Get_APBClock() << 1;    
    }
    
	TIM_TimeBaseStructure.ClockDivision = TIM_CLOCKDIVISION_DIV1; 
	TIM_TimeBaseStructure.CounterMode = TIM_COUNTERMODE_UP; 
	TIM_TimeBaseStructure.RepetitionCounter = 0;  
	TIM_TimeBaseStructure.Prescaler = 0;  

	TIM_TimeBaseStructure.Period = PERIOD_MAX_VALUE;  // period = 10us       	    
	TIM_TimeBase_Init(TIM1, &TIM_TimeBaseStructure);        
                 
}  

/**********************************************************************************************
* Function    : TIM1_IC1_Capture_IT       
* Description : start timer capture by channel 1, read data in interrupt servic 
* Input       : none    
* Output      : none 
* Author      : xwl                       
******************************************************************************************************/  
void TIM1_IC1_Capture_IT(void)     
{
    uint16_t delta[CAPTURE_TIMES_TOTAL-1];         
    uint32_t i;     
    
    capture_times = 0;        
    for(i = 0; i < (CAPTURE_TIMES_TOTAL-1); i++)  
    {
        delta[i] = 0;    
    }   
    
    TIM_ClearFlag(TIM1, TIMER_SR_CC1IF);     
    TIM_ITConfig(TIM1, TIM_IT_CC1, ENABLE);  
    /* TIM1 enable capture */    
    TIM_CCxCmd(TIM1, TIM_CHANNEL_1, TIM_CCx_Enable);       
    /* TIM1 enable counter */    
    TIM_Cmd(TIM1, ENABLE);   
    
    while(1)
	{	
        if (capture_times >= CAPTURE_TIMES_TOTAL)   
        {
            TIM_ITConfig(TIM1, TIM_IT_CC1, DISABLE);     
            TIM_CCxCmd(TIM1, TIM_CHANNEL_1, TIM_CCx_Disable);       
            
            for(i = 0; i < (CAPTURE_TIMES_TOTAL-1); i++)  
            {
               delta[i] = Capture_data[TIM_CHANNEL_1][i+1] - Capture_data[TIM_CHANNEL_1][i];    
            }
            for(i = 0; i < (CAPTURE_TIMES_TOTAL-1); i++)   
            {
                 printfS("IC1 capture test, i=%d, Delta[i]:%u\n", i, delta[i]);            
            }
            
            TIM_ClearFlag(TIM1, TIMER_SR_CC1IF);     
            break;   
        }            		
	}
} 


/**********************************************************************************************
* Function    : TIM1_IC2_Capture_IT       
* Description : start timer capture by channel 2, read data in interrupt servic 
* Input       : none    
* Output      : none 
* Author      : xwl                       
******************************************************************************************************/  
void TIM1_IC2_Capture_IT(void)     
{
    uint16_t delta[CAPTURE_TIMES_TOTAL-1];         
    uint32_t i;     
    
    capture_times = 0;        
    for(i = 0; i < (CAPTURE_TIMES_TOTAL-1); i++)  
    {
        delta[i] = 0;    
    }   
    
    TIM_ClearFlag(TIM1, TIMER_SR_CC2IF);     
    TIM_ITConfig(TIM1, TIM_IT_CC2, ENABLE);  
    /* TIM1 enable capture */    
    TIM_CCxCmd(TIM1, TIM_CHANNEL_2, TIM_CCx_Enable);       
    /* TIM1 enable counter */    
    TIM_Cmd(TIM1, ENABLE);   
    
    while(1)
	{	
        if (capture_times >= CAPTURE_TIMES_TOTAL)   
        {
            TIM_ITConfig(TIM1, TIM_IT_CC2, DISABLE);     
            TIM_CCxCmd(TIM1, TIM_CHANNEL_2, TIM_CCx_Disable);       
            
            for(i = 0; i < (CAPTURE_TIMES_TOTAL-1); i++)  
            {
               delta[i] = Capture_data[TIM_CHANNEL_2][i+1] - Capture_data[TIM_CHANNEL_2][i];    
            }
            for(i = 0; i < (CAPTURE_TIMES_TOTAL-1); i++)   
            {
                 printfS("IC2 capture test, i=%d, Delta[i]:%u\n", i, delta[i]);            
            }
            
            TIM_ClearFlag(TIM1, TIMER_SR_CC2IF);     
            break;   
        }            		
	}
} 


/**********************************************************************************************
* Function    : Timer_Capture_Test      
* Description : capture test entry
* Input       : capture_channel: CAPTURE_CHANNEL_1, CAPTURE_CHANNEL_2        
* Output      : none 
* Author      : xwl                       
******************************************************************************************************/  
void Timer_Capture_Test(uint32_t capture_channel)    
{
    /*Clocks Configuration */
    Clock_Configuration();    
    /*NVIC configuration */
    NVIC_Configuration();  
    /*IO configuration */   
    GPIO_Configuration();   
    
    System_Set_Buzzer_Divider(8000, FUNC_ENABLE); 
    
	TIM1_Base_Init();   
    
    switch(capture_channel)
    {
        case CAPTURE_CHANNEL_1:  
        TIM1_IC1_Init();   
        TIM1_IC1_Capture_IT();                  
        break;  
        
        case CAPTURE_CHANNEL_2:    
        TIM1_IC2_Init();   
        TIM1_IC2_Capture_IT();       
        break;  
        
        default: 
        printfS("Application not supported \n");   
        break;  
    }
             
	while(1)   
	{

	}
}


