#include "lks32mc09x_timer.h"
#include "lks32mc09x_sys.h"

/**
 * @brief Timer初始化
 * @param TIMERx Timer实例指针
 * @param TIMER_InitStruct Timer初始化结构体指针
 */
void TIMER_Init(TIMER_TypeDef *TIMERx, TIMER_TimerInitTypeDef *TIMER_InitStruct)
{
    uint32_t th = TIMER_InitStruct->TH;
    TIMER_Enable(TIMERx);
    if (TIMERx != TIMER2) // 只有timer2是32位定时器
    {
        if (th > 0xffff)
        {
            th = 0xffff;
        }
        else
        {
            __NOP();
        }
    }
    else
    {
        __NOP();
    }
    // 配置Timer寄存器
    TIMERx->CFG2 = (TIMER_InitStruct->EN << 15) |
                   (TIMER_InitStruct->ONE_TRIG << 9) |
                   (TIMER_InitStruct->CENTER << 8) |
                   (TIMER_InitStruct->DIR << 6) |
                   (TIMER_InitStruct->ClockDiv << 4) |
                   (TIMER_InitStruct->ETON << 3) |
                   (TIMER_InitStruct->GATE_EN << 2) |
                   (TIMER_InitStruct->RL_EN << 1) |
                   TIMER_InitStruct->XCLK_EN;

    TIMERx->CFG0 = (TIMER_InitStruct->CMP0_TRIGGER_MODE << 9) |
                   (TIMER_InitStruct->CAP0_CLR_EN << 8) |
                   (TIMER_InitStruct->SRC0 << 4) |
                   (TIMER_InitStruct->CH0Output << 3) |
                   (TIMER_InitStruct->CH0_WorkMode << 2) |
                   (TIMER_InitStruct->CH0_FE_CAP_EN << 1) |
                   (TIMER_InitStruct->CH0_RE_CAP_EN << 0);

    TIMERx->CFG1 = (TIMER_InitStruct->CMP1_TRIGGER_MODE << 9) |
                   (TIMER_InitStruct->CAP1_CLR_EN << 8) |
                   (TIMER_InitStruct->SRC1 << 4) |
                   (TIMER_InitStruct->CH1Output << 3) |
                   (TIMER_InitStruct->CH1_WorkMode << 2) |
                   (TIMER_InitStruct->CH1_FE_CAP_EN << 1) |
                   (TIMER_InitStruct->CH1_RE_CAP_EN << 0);

    TIMERx->CHN0 = TIMER_InitStruct->CHN0;
    TIMERx->CHN1 = TIMER_InitStruct->CHN1;
    TIMERx->TH   = th;
    TIMERx->CNT  = TIMER_InitStruct->CNT;
    TIMERx->EVT  = TIMER_InitStruct->EVT;
    TIMERx->FLT  = TIMER_InitStruct->FLT;
    TIMERx->IE   = TIMER_InitStruct->IE;

    TIMERx->IO = (TIMER_InitStruct->HALT_PRT << 7) |
                 (TIMER_InitStruct->CH0_DEFAULT << 8) |
                 (TIMER_InitStruct->CH1_DEFAULT << 9) |
                 (TIMER_InitStruct->MOE << 6) |
                 (TIMER_InitStruct->FAIL_SEL << 2) |
                 (TIMER_InitStruct->FAIL_POL << 1) |
                 (TIMER_InitStruct->FAIL_EN << 0);

    // 影子寄存器配置
    TIMERx->CFG2 |= (TIMER_InitStruct->SHADOW << 10);
}

/**
 * @brief Timer结构体初始化
 * @param TIMER_InitStruct Timer初始化结构体指针
 */
void TIMER_StructInit(TIMER_TimerInitTypeDef *TIMER_InitStruct)
{
    for (int i = 0; i < sizeof(TIMER_TimerInitTypeDef) / sizeof(uint32_t); i++)
    {
        ((uint32_t *)TIMER_InitStruct)[i] = 0;
    }
}

/**
 * @brief Timer使能/失能
 * @param TIMERx Timer实例指针
 * @param state 使能或失能状态
 */
void TIMER_TimerCmd(TIMER_TypeDef *TIMERx, uint8_t state)
{
    if (state == ENABLE)
    {
        TIMERx->CFG2 |= (1 << 15);
    }
    else
    {
        TIMERx->CFG2 &= ~(1 << 15);
    }
}

/**
 * @brief 设置Timer通道0比较值
 * @param TIMERx Timer实例指针
 * @param temp 比较值
 */
void TIMER_CMP0(TIMER_TypeDef *TIMERx, uint32_t temp)
{
    TIMERx->CHN0 = temp;
}

/**
 * @brief 设置Timer通道1比较值
 * @param TIMERx Timer实例指针
 * @param temp 比较值
 */
void TIMER_CMP1(TIMER_TypeDef *TIMERx, uint32_t temp)
{
    TIMERx->CHN1 = temp;
}

/**
 * @brief 获取Timer通道0比较值
 * @param TIMERx Timer实例指针
 * @return 比较值
 */
uint32_t TIMER_Timer_GetCMPT0(TIMER_TypeDef *TIMERx)
{
    return TIMERx->CHN0;
}

/**
 * @brief 获取Timer通道1比较值
 * @param TIMERx Timer实例指针
 * @return 比较值
 */
uint32_t TIMER_Timer_GetCMPT1(TIMER_TypeDef *TIMERx)
{
    return TIMERx->CHN1;
}

/**
 * @brief 清除Timer中断标志
 * @param TIMERx Timer实例指针
 * @param tempFlag 要清除的中断标志
 */
void TIMER_ClearIRQFlag(TIMER_TypeDef *TIMERx, uint32_t tempFlag)
{
    TIMERx->IF = tempFlag;
}

/**
 * @brief 获取Timer中断标志状态
 * @param TIMERx Timer实例指针
 * @param TIMER_IF_x 中断标志位
 * @return 中断标志状态
 */
uint16_t TIMER_GetIRQFlag(TIMER_TypeDef *TIMERx, uint32_t TIMER_IF_x)
{
    return (TIMERx->IF & TIMER_IF_x) ? 1 : 0;
}

/**
 * @brief 获取Timer状态标志
 * @param TIMERx Timer实例指针
 * @param TIMER_IF_x 状态标志位
 * @return 状态标志
 */
uint16_t TIMER_GetFlag(TIMER_TypeDef *TIMERx, uint32_t TIMER_IF_x)
{
    return (TIMERx->IF & TIMER_IF_x) ? 1 : 0;
}

/**
 * @brief 获取Timer当前计数值
 * @param TIMERx Timer实例指针
 * @return 当前计数值
 */
uint32_t TIMER_Timer_GetCount(TIMER_TypeDef *TIMERx)
{
    return TIMERx->CNT;
}

/**
 * @brief 使能Timer
 * @param TIMERx Timer实例指针
 */
void TIMER_Enable(TIMER_TypeDef *TIMERx)
{
    if (TIMERx == TIMER0)
    {
        SYS_ModuleClockCmd(SYS_MODULE_TIMER0, ENABLE);
    }
    else if (TIMERx == TIMER1)
    {
        SYS_ModuleClockCmd(SYS_MODULE_TIMER1, ENABLE);
    }
    else if (TIMERx == TIMER2)
    {
        SYS_ModuleClockCmd(SYS_MODULE_TIMER2, ENABLE);
    }
    else
    {
        __NOP();
    }
}

/**
 * @brief 失能Timer
 * @param TIMERx Timer实例指针
 */
void TIMER_Disable(TIMER_TypeDef *TIMERx)
{
    if (TIMERx == TIMER0)
    {
        SYS_ModuleClockCmd(SYS_MODULE_TIMER0, DISABLE);
    }
    else if (TIMERx == TIMER1)
    {
        SYS_ModuleClockCmd(SYS_MODULE_TIMER1, DISABLE);
    }
    else if (TIMERx == TIMER2)
    {
        SYS_ModuleClockCmd(SYS_MODULE_TIMER2, DISABLE);
    }
    else
    {
        __NOP();
    }
}

/**
 * @brief 设置输出状态
 * @param TIMERx Timer实例指针
 * @param state 输出状态，0关闭pwm输出，其他值，打开pwm输出
 */
void TIMER_SetOutputState(TIMER_TypeDef *TIMERx, uint8_t state)
{
    if (state == 0)
    {
        TIMERx->IO &= ~BIT6;
    }
    else
    {
        TIMERx->IO |= BIT6;
    }
}
