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

/**
 * @brief QEP初始化函数（初始化完成后会自动使能，并使能timer2）
 * @param QEPx QEP模块指针
 * @param TIM_QEPInitStruct 初始化结构体指针
 */
void QEP_Init(QEP_TypeDef *QEPx, QEP_InitTypeDef *TIM_QEPInitStruct)
{
    // 使能QEP模块时钟
    if (QEPx == QEP0)
    {
        SYS_ModuleClockCmd(SYS_MODULE_QEP0, ENABLE);
        TIMER_Enable(TIMER2);
    }
    else
    {
        __NOP();
    }
    // QEP配置寄存器
    QEPx->CFG = BIT15 |
                (TIM_QEPInitStruct->Filter << 16) |
                (TIM_QEPInitStruct->FE_CNT_EN << 10) |
                (TIM_QEPInitStruct->Mode << 8) |
                (TIM_QEPInitStruct->ZC);

    // 设置计数门限
    QEPx->TH = TIM_QEPInitStruct->TH;

    // 设置中断使能
    QEPx->IE = TIM_QEPInitStruct->IRQEna;
}

/**
 * @brief QEP结构体初始化函数
 * @param TIM_QEPInitStruct 初始化结构体指针
 */
void QEP_StructInit(QEP_InitTypeDef *TIM_QEPInitStruct)
{
    for (int i = 0; i < sizeof(QEP_InitTypeDef) / sizeof(uint32_t); i++)
    {
        ((uint32_t *)TIM_QEPInitStruct)[i] = 0;
    }
}

/**
 * @brief QEP使能/失能函数
 * @param QEPx QEP模块指针
 * @param state 使能/失能状态
 */
void QEP_Cmd(QEP_TypeDef *QEPx, uint8_t state)
{
    if (state == ENABLE)
    {
        QEPx->CFG |= (1 << 15); // 使能QEP模块
        TIMER_Enable(TIMER2);   // 使用QEP时会自动使能timer2
    }
    else
    {
        QEPx->CFG &= ~(1 << 15); // 失能QEP模块
    }
}

/**
 * @brief 获取QEP计数器当前值
 * @param QEPx QEP模块指针
 * @return 计数器当前值
 */
uint16_t QEP_GetCount(QEP_TypeDef *QEPx)
{
    return QEPx->CNT;
}

/**
 * @brief 清除QEP中断标志
 * @param QEPx QEP模块指针
 * @param tempFlag 要清除的中断标志
 */
void QEP_ClearIRQFlag(QEP_TypeDef *QEPx, uint32_t tempFlag)
{
    QEPx->IF = tempFlag;
}

/**
 * @brief 获取QEP中断标志状态
 * @param QEPx QEP模块指针
 * @param QEP_IF_x 中断标志类型
 * @return 中断标志状态
 */
uint16_t QEP_GetIRQFlag(QEP_TypeDef *QEPx, uint32_t QEP_IF_x)
{
    return (QEPx->IF & QEP_IF_x) ? 1 : 0;
}

/**
 * @brief 获取QEP状态标志
 * @param QEPx QEP模块指针
 * @param QEP_IF_x 状态标志类型
 * @return 状态标志
 */
uint16_t QEP_GetFlag(QEP_TypeDef *QEPx, uint32_t QEP_IF_x)
{
    return (QEPx->IF & QEP_IF_x) ? 1 : 0;
}

/**
 * @brief 获取QEP状态标志
 * @param QEPx QEP模块指针
 * @param QEP_MODE_x 编码器工作模式
 */
void QEP_SetMode(QEP_TypeDef *QEPx, uint32_t QEP_MODE_x)
{
    QEPx->CFG = (QEPx->CFG & (~(0x3 << 8))) | (QEP_MODE_x << 8);
}
