#include "tim1_drivers.h"
#if APP_TIM1_ENABLE
/********************************************************
**  函数名  void TIM1_Init(void)
**  描述    定时器1初始化
**  传入    ：无
**  返回    ：无
*********************************************************/
void TIM1_Init(void)
{
    LL_TIM_InitTypeDef TimHandle = {0};
    uint32_t Prescale;
    uint32_t Autoreload;
    uint32_t Frequency = 1000000 / TIM1_TIMING_TIME;
    /*  测试GPIO翻转        */
#if (TIM1_DEBUG_GPIO != NO_PIN && TIM1_DEBUG)
    GPIO_Init(TIM1_DEBUG_GPIO, OUTPUT | PUSHPULL);
    GPIO_ClearBit(TIM1_DEBUG_GPIO);
#endif
    for (Prescale = 1U; Prescale < 0xFFFFU; Prescale++) /* prescale could be 0~0xFFFF */
    {
        Autoreload = (RCC_Clock.PCLK1_Frequency / Frequency) / Prescale;
        /* If target value is larger than CNR, need to use a larger prescaler */
        if (Autoreload < (0x10000U))
        {
            break;
        }
    }
    /* Enable TIM1 clock */
    LL_APB1_GRP2_EnableClock(LL_APB1_GRP2_PERIPH_TIM1);
    /* TIM Config */
    TimHandle.ClockDivision = LL_TIM_CLOCKDIVISION_DIV1; /* Clock division: tDTS=tCK_INT */
    TimHandle.CounterMode = LL_TIM_COUNTERMODE_UP;       /* CounterMode:Up */
    TimHandle.RepetitionCounter = 0;                     /* repetition counter value:1-1 */
    TimHandle.Autoreload = Autoreload - 1;               /* Auto reload value： */
    TimHandle.Prescaler = Prescale - 1;                  /* Prescaler:24 - 1 */
    /* Initialize TIM1 */
    LL_TIM_Init(TIM1, &TimHandle);
    /* Enable the TIM Update interrupt */
    LL_TIM_EnableIT_UPDATE(TIM1);
    /* Enable TIM1  */
    LL_TIM_EnableCounter(TIM1);
#if TIM1_IRQ_ENABLE
    /* Set the interrupt priority */
    NVIC_SetPriority(TIM1_BRK_UP_TRG_COM_IRQn, TIM1_IRQ_PRIORITY);
    /* Enable TIM Break, Update, Trigger and Commutation Interrupts */
    NVIC_EnableIRQ(TIM1_BRK_UP_TRG_COM_IRQn);
#endif
}
/********************************************************
**  函数名  void TIM1_PeriodElapsedCallback(void)
**  描述    定时器1中断回调函数
**  传入    ：无
**  返回    ：无
*********************************************************/
__weak void TIM1_PeriodElapsedCallback(void)
{
}
/********************************************************
**  函数名  void TIM1_BRK_UP_TRG_COM_IRQHandler(void)
**  描述    定时器1中断入口
**  传入    ：无
**  返回    ：无
*********************************************************/
void TIM1_BRK_UP_TRG_COM_IRQHandler(void)
{
    /* TIM Update event */
    if (LL_TIM_IsActiveFlag_UPDATE(TIM1) != 0)
    {
        LL_TIM_ClearFlag_UPDATE(TIM1);
        /*  测试GPIO翻转        */
#if (TIM1_DEBUG_GPIO != NO_PIN && TIM1_DEBUG)
        GPIO_ToggleBit(TIM1_DEBUG_GPIO);
#endif
        TIM1_PeriodElapsedCallback();
    }
}
#elif APP_TIM1_PWM_ENABLE
static LL_TIM_OC_InitTypeDef TIM_OC_Initstruct = {0};
static uint32_t TIM1_Autoreload;
/********************************************************
**  函数名  void TIM1_PWM_Init(void)
**  描述    定时器1用做PWM初始化
**  传入    ：无
**  返回    ：无
*********************************************************/
void TIM1_PWM_Init(void)
{
    /* Configure TIM1 */
    LL_TIM_InitTypeDef TIM1CountInit = {0};
    uint32_t Prescale;
    for (Prescale = 1U; Prescale < 0xFFFFU; Prescale++) /* prescale could be 0~0xFFFF */
    {
        TIM1_Autoreload = (RCC_Clock.PCLK1_Frequency / TIM1_PWM_FREQUENCE) / Prescale;
        /* If target value is larger than CNR, need to use a larger prescaler */
        if (TIM1_Autoreload < (0x10000U))
        {
            break;
        }
    }
    /* Enable TIM1 peripheral clock */
    LL_APB1_GRP2_EnableClock(LL_APB1_GRP2_PERIPH_TIM1);
    TIM1CountInit.ClockDivision = LL_TIM_CLOCKDIVISION_DIV1; /* Set divider:tDTS=tCK_INT  */
    TIM1CountInit.CounterMode = LL_TIM_COUNTERMODE_UP;       /* count mode：up count      */
    TIM1CountInit.Autoreload = TIM1_Autoreload - 1;          /* auto-reload value：1000   */
    TIM1CountInit.Prescaler = Prescale - 1;                  /* clock prescaler：2400     */
    TIM1CountInit.RepetitionCounter = 0;                     /* recount：0                */
    /* Initialize TIM1 */
    LL_TIM_Init(TIM1, &TIM1CountInit);
    /* Set PWM channel */
    TIM_OC_Initstruct.OCMode = LL_TIM_OCMODE_PWM1;          /* channle mode：PWM2         */
    TIM_OC_Initstruct.OCState = LL_TIM_OCSTATE_ENABLE;      /* Enable selected channle    */
#if TIM1_ACTIVE
    TIM_OC_Initstruct.OCPolarity = LL_TIM_OCPOLARITY_HIGH;  /* channle active level：high */
    TIM_OC_Initstruct.OCIdleState = LL_TIM_OCIDLESTATE_LOW; /* channle idle polarity：low */
#else
    TIM_OC_Initstruct.OCPolarity = LL_TIM_OCPOLARITY_LOW;  /* channle active level：high */
    TIM_OC_Initstruct.OCIdleState = LL_TIM_OCIDLESTATE_HIGH; /* channle idle polarity：low */
#endif
	TIM_OC_Initstruct.OCNState = LL_TIM_OCSTATE_ENABLE;      /* Enable selected channle    */
#if (TIM1N_ACTIVE == 0)
    TIM_OC_Initstruct.OCNPolarity = LL_TIM_OCPOLARITY_HIGH;  /* channle active level：high */
    TIM_OC_Initstruct.OCNIdleState = LL_TIM_OCIDLESTATE_LOW; /* channle idle polarity：low */
#else
    TIM_OC_Initstruct.OCNPolarity = LL_TIM_OCPOLARITY_LOW;  /* channle active level：high */
    TIM_OC_Initstruct.OCNIdleState = LL_TIM_OCIDLESTATE_HIGH; /* channle idle polarity：low */
#endif
#if TIM1_CH1_ENABLE
	#if (TIM1_CH1_PIN < 26)
		#if (TIM1_CH1_PIN == 7)
			GPIO_Init(TIM1_CH1_PIN, ALTERNATE | GPIO_TIM1_AF5);
		#else
			GPIO_Init(TIM1_CH1_PIN, ALTERNATE | GPIO_TIM1_AF2);
		#endif
	#endif
	#if (TIM1_CH1N_PIN < 26)
		TIM_OC_Initstruct.OCNState = LL_TIM_OCSTATE_ENABLE;      /* Enable selected channle    */
		#if (TIM1_CH1N_PIN == 0)//PA0
			GPIO_Init(TIM1_CH1N_PIN, ALTERNATE | GPIO_TIM1_AF5);
		#else
			GPIO_Init(TIM1_CH1N_PIN, ALTERNATE | GPIO_TIM1_AF2);
		#endif
	#else
		TIM_OC_Initstruct.OCNState = LL_TIM_OCSTATE_DISABLE;      /* Enable selected channle    */
	#endif
	TIM1_PWM_Pulse(LL_TIM_CHANNEL_CH1, TIM1_DUTY1_CYCLE);
	LL_TIM_OC_Init(TIM1, LL_TIM_CHANNEL_CH1, &TIM_OC_Initstruct);
#endif
#if TIM1_CH2_ENABLE
	#if (TIM1_CH2_PIN < 26)
		#if (TIM1_CH2_PIN == 16)
			GPIO_Init(TIM1_CH2_PIN, ALTERNATE | GPIO_TIM1_AF5);
		#else
			GPIO_Init(TIM1_CH2_PIN, ALTERNATE | GPIO_TIM1_AF2);
		#endif
	#endif
	#if (TIM1_CH2N_PIN < 26)
		TIM_OC_Initstruct.OCNState = LL_TIM_OCSTATE_ENABLE;      /* Enable selected channle    */
		#if (TIM1_CH2N_PIN == 1)//PA1
			GPIO_Init(TIM1_CH2N_PIN, ALTERNATE | GPIO_TIM1_AF5);
		#else
			GPIO_Init(TIM1_CH2N_PIN, ALTERNATE | GPIO_TIM1_AF2);
		#endif
	#else
		TIM_OC_Initstruct.OCNState = LL_TIM_OCSTATE_DISABLE;      /* Enable selected channle    */
	#endif
    TIM1_PWM_Pulse(LL_TIM_CHANNEL_CH2, TIM1_DUTY2_CYCLE);
	LL_TIM_OC_Init(TIM1, LL_TIM_CHANNEL_CH2, &TIM_OC_Initstruct);
#endif
#if TIM1_CH3_ENABLE
	#if (TIM1_CH3_PIN < 26)
		GPIO_Init(TIM1_CH3_PIN, ALTERNATE | GPIO_TIM1_AF2);
	#endif
	#if (TIM1_CH3N_PIN < 26)
		TIM_OC_Initstruct.OCNState = LL_TIM_OCSTATE_ENABLE;      /* Enable selected channle    */
		GPIO_Init(TIM1_CH3N_PIN, ALTERNATE | GPIO_TIM1_AF2);
	#else
		TIM_OC_Initstruct.OCNState = LL_TIM_OCSTATE_DISABLE;      /* Enable selected channle    */
	#endif
    TIM1_PWM_Pulse(LL_TIM_CHANNEL_CH3, TIM1_DUTY3_CYCLE);
	LL_TIM_OC_Init(TIM1, LL_TIM_CHANNEL_CH3, &TIM_OC_Initstruct);
#endif
#if TIM1_CH4_ENABLE
	#if (TIM1_CH4_PIN == 15)
		GPIO_Init(TIM1_CH4_PIN, ALTERNATE | GPIO_TIM1_AF5);
	#else
		GPIO_Init(TIM1_CH4_PIN, ALTERNATE | GPIO_TIM1_AF2);
	#endif
    TIM1_PWM_Pulse(LL_TIM_CHANNEL_CH4, TIM1_DUTY4_CYCLE);
	LL_TIM_OC_Init(TIM1, LL_TIM_CHANNEL_CH4, &TIM_OC_Initstruct);
#endif
    /* Enable output */
    LL_TIM_EnableAllOutputs(TIM1);
    /* Enable TIM1 */
    LL_TIM_EnableCounter(TIM1);
}
/********************************************************
**  函数名  void TIM1_PWM_Pulse(uint32_t CHx,uint16_t percent)
**  描述    定时器1-PWM占空比设置
**  传入    ：  CHx 通道号  LL_TIM_CHANNEL_CH1~LL_TIM_CHANNEL_CH4，
                percent     输出百分比
**  返回    ：无
*********************************************************/
void TIM1_PWM_Pulse(uint32_t CHx, uint16_t percent)
{
    /* CH1 compare value:250 */
    TIM_OC_Initstruct.CompareValue = TIM1_Autoreload * percent / TIM1_RESOLUTION;
    switch (CHx)
    {
    case LL_TIM_CHANNEL_CH1:
        TIM1->CCR1 = TIM_OC_Initstruct.CompareValue;
        break;
    case LL_TIM_CHANNEL_CH2:
        TIM1->CCR2 = TIM_OC_Initstruct.CompareValue;
        break;
    case LL_TIM_CHANNEL_CH3:
        TIM1->CCR3 = TIM_OC_Initstruct.CompareValue;
        break;
    case LL_TIM_CHANNEL_CH4:
        TIM1->CCR4 = TIM_OC_Initstruct.CompareValue;
        break;
    }
}
#elif APP_TIM1_INPUTCAPTURE_ENABLE
/********************************************************
**  函数名  ：void TIM1_InputCapture_Init(void)
**  描述    ：定时器1输入捕获初始化
**  传入    ：无
**  返回    ：无
*********************************************************/
void TIM1_InputCapture_Init(void)
{
    /* Configure TIM1 */
    LL_TIM_InitTypeDef TIM1CountInit = {0};
    /* Enable TIM1 clock */
    LL_APB1_GRP2_EnableClock(LL_APB1_GRP2_PERIPH_TIM1);
#if (TIM1_CAP_PIN == 7)
    GPIO_Init(TIM1_CAP_PIN, ALTERNATE | GPIO_TIM1_AF5 | PULL_UP);
#else
    GPIO_Init(TIM1_CAP_PIN, ALTERNATE | GPIO_TIM1_AF2 | PULL_UP);
#endif
#if (HSI_FREQUENCE == 24000000UL)
    TIM1CountInit.ClockDivision       = LL_TIM_CLOCKDIVISION_DIV1;  /* divider:tDTS=tCK_INT   */
#else
	TIM1CountInit.ClockDivision       = LL_TIM_CLOCKDIVISION_DIV2;  /* divider:tDTS=tCK_INT   */
#endif
    TIM1CountInit.CounterMode         = LL_TIM_COUNTERMODE_UP;      /* count mode :up count   */
    TIM1CountInit.Prescaler           = 1 - 1;                        /* prescaler：1           */;//
    TIM1CountInit.Autoreload          = 65536 - 1;                  /* auto-rload:65536       */
    TIM1CountInit.RepetitionCounter   = 0;                          /* recount：0             */
    /* Initialize TIM1 */
    LL_TIM_Init(TIM1, &TIM1CountInit);
    LL_TIM_IC_SetActiveInput(TIM1, LL_TIM_CHANNEL_CH1, LL_TIM_ACTIVEINPUT_DIRECTTI);
    LL_TIM_IC_SetPolarity(TIM1, LL_TIM_CHANNEL_CH1, LL_TIM_IC_POLARITY_RISING);
    LL_TIM_IC_SetActiveInput(TIM1, LL_TIM_CHANNEL_CH2, LL_TIM_ACTIVEINPUT_INDIRECTTI);
    LL_TIM_IC_SetPolarity(TIM1, LL_TIM_CHANNEL_CH2, LL_TIM_IC_POLARITY_FALLING);
    LL_TIM_SetSlaveMode(TIM1, LL_TIM_SLAVEMODE_RESET);
    LL_TIM_SetTriggerInput(TIM1, LL_TIM_TS_TI1FP1);
    LL_TIM_CC_EnableChannel(TIM1, LL_TIM_CHANNEL_CH1);
    LL_TIM_CC_EnableChannel(TIM1, LL_TIM_CHANNEL_CH2);
    LL_TIM_EnableCounter(TIM1);
}
/********************************************************
**  函数名  ：uint8_t TIM1_GetCapture(CaptureType *Capture)
**  描述    ：获取定时器1输入捕获的占空比
**  传入    ：无
**  返回    ：1：捕获完成	0：捕获失败
*********************************************************/
uint8_t TIM1_GetCapture(CaptureType *Capture)
{
    static uint8_t fiter_count;
    static uint32_t max_fre;
    static uint32_t min_fre;
    static uint32_t sum_fre;
    static uint8_t max_duty;
    static uint8_t min_duty;
    static uint32_t sum_duty;
    static uint8_t uppsc = 0;
    static uint16_t HoldCnt = 0;
    uint32_t Freq;
    uint8_t Duty;
    uint16_t TPC;       // 总脉宽计数
    uint16_t HPW;       // 高电平脉宽计数
    volatile uint32_t SR = TIM1->SR;
    TIM1->SR = 0;
    HoldCnt++;
    if (GPIO_ReadBit(TIM1_CAP_PIN))
    {
        if ((uppsc & 0X02) == 0)
        {
            HoldCnt = 0;
        }
        uppsc |= 0X02;
    }
    else
    {
        if (uppsc & 0X02)
        {
            HoldCnt = 0;
        }
        uppsc &= ~0X02;
    }
	/*	最慢识别1HZ	*/
    if (HoldCnt > 1100 && TIM1->PSC >= 16384)
    {
        HoldCnt = 0;
        if (uppsc & 0X02)
            Capture->Duty = 100; // 占空比100%
        else
            Capture->Duty = 0;   // 占空比0%
        Capture->Freq = 0;
        return 1;
    }
    else if (SR & TIM_SR_TIF)
    {
        if (TIM1->CCR1 < 1000 && TIM1->PSC) //最快速度
        {
            TIM1->PSC >>= 1;
            fiter_count = 0;
			HoldCnt = 0;
			log_printf("DN PSC:%d\n",TIM1->PSC);
        }
        else
        {
			HoldCnt = 0;
            TPC = (TIM1->CCR1 + 1);     // 总脉宽计数
            HPW = (TIM1->CCR2 + 1);     // 高电平脉宽计数
            Duty = HPW * 100 / TPC;                        // 占空比
            Freq = ((24000000 / (TIM1->PSC + 1)) + (TPC >> 1))/ TPC;                         // 频率=主频/总计数
            fiter_count++;
            if (fiter_count == 1)
            {
                max_duty = Duty;
                min_duty = Duty;
                sum_duty = 0;
                max_fre = Freq;
                min_fre = Freq;
                sum_fre = 0;
            }
            if (max_duty < Duty)
                max_duty = Duty;
            if (min_duty > Duty)
                min_duty = Duty;
            sum_duty += Duty;
            if (max_fre < Freq)
                max_fre = Freq;
            if (min_fre > Freq)
                min_fre = Freq;
            sum_fre += Freq;
            if (fiter_count == 4)
            {
                fiter_count = 0;
				/*	捕获得到的频率最大最小相差小于5认为正确	*/
                if ((max_fre - min_fre) < 2)
                {
                    Capture->Freq = (sum_fre - (max_fre + min_fre)) >> 1;
                    Capture->Duty = (sum_duty - (max_duty + min_duty)) >> 1;
					/*	占空比小于100认为正确	*/
                    if (Capture->Duty <= 100 && Capture->Duty > 0)
                        return 1;
                }
                return 0;
            }
        }
    }
	else if (TIM1->CNT > 30000)
    {
        if (TIM1->PSC < 16384)
		{
			if(TIM1->PSC == 0)
				TIM1->PSC = 1;
			else
				TIM1->PSC <<= 1;
			HoldCnt = 0;
			log_printf("UP PSC:%d\n",TIM1->PSC);
        }
		TIM1->CNT = 0;
        fiter_count = 0;
    }
    return 0;
}
#endif
