#ifndef __LKS32MC09X_QEP_H__
#define __LKS32MC09X_QEP_H__

#include "lks32mc09x_reg.h"

/**
 * @brief QEP初始化结构体定义
 */
typedef struct
{
    uint32_t Mode;      ///< 编码器模式选择
    uint32_t FE_CNT_EN; ///< 下降沿计数使能（上升沿始终计数），ENABLE使能 DISABLE失能
    uint16_t TH;        ///< QEP计数门限寄存器
    uint32_t ClockDiv;  ///< 时钟分频
    uint32_t Filter;    ///< 信号输入滤波，设置为1时滤波宽度是1*8个时钟，取值范围0-15
    uint32_t IRQEna;    ///< 中断使能
    uint32_t ZC;        ///< Z信号配置
} QEP_InitTypeDef;

/**
 * @brief QEP时钟分频宏定义
 */
#define QEP_CLK_DIV1   0x00 ///< QEP计数器频率1分频
#define QEP_CLK_DIV2   0x01 ///< QEP计数器频率2分频
#define QEP_CLK_DIV4   0x02 ///< QEP计数器频率4分频
#define QEP_CLK_DIV8   0x03 ///< QEP计数器频率8分频
#define QEP_CLK_DIV16  0x04 ///< QEP计数器频率16分频
#define QEP_CLK_DIV32  0x05 ///< QEP计数器频率32分频
#define QEP_CLK_DIV64  0x06 ///< QEP计数器频率64分频
#define QEP_CLK_DIV128 0x07 ///< QEP计数器频率128分频

/**
 * @brief QEP中断使能宏定义
 */
#define QEP_IRQEna_None      0    ///< 无使能
#define QEP_IRQEna_UnderFlow BIT0 ///< 使能下溢中断
#define QEP_IRQEna_OverFlow  BIT1 ///< 使能上溢中断

/**
 * @brief 编码器中断标志定义
 */
#define QEP_IF_UNDERFLOW BIT0 ///< Encoder下溢中断
#define QEP_IF_OVERFLOW  BIT1 ///< Encoder上溢中断

/**
 * @brief QEP模式选择宏定义
 */
#define QEP_Mode_T1             ((uint32_t)0x00) ///< counting on T1
#define QEP_Mode_T1_T2          ((uint32_t)0x01) ///< counting on T1&T2
#define QEP_Mode_CCWSIGN_UpDown ((uint32_t)0x02) ///< CCW+SIGN 符号加脉冲信号计数模式, 若需要计数信号的上下沿，则QEP_FE_CNT_EN置1
#define QEP_Mode_CCWCW_UpDown   ((uint32_t)0x03) ///< CCW+CW 双向计数模式，a和b分别为递增和递减脉冲 a信号变化则cnt递增，b信号变化则cnt递减

/**
 * @brief Z信号配置选择
 */
#define QEP_ZC_NONE     (0x0) ///< 不使用
#define QEP_ZC_EDEG_P   (0x5) ///< 上升沿清零
#define QEP_ZC_EDEG_N   (0x9) ///< 下降沿清零
#define QEP_ZC_EDEG_ALL (0xd) ///< 上升沿&下降沿清零
#define QEP_ZC_LEVEL_H  (0xa) ///< 高电平清零
#define QEP_ZC_LEVEL_L  (0x6) ///< 低电平清零

/**
 * @brief QEP初始化函数（初始化完成后会自动使能，并使能timer2）
 * @param QEPx QEP模块指针
 * @param TIM_QEPInitStruct 初始化结构体指针
 */
void QEP_Init(QEP_TypeDef *QEPx, QEP_InitTypeDef *TIM_QEPInitStruct);

/**
 * @brief QEP结构体初始化函数
 * @param TIM_QEPInitStruct 初始化结构体指针
 */
void QEP_StructInit(QEP_InitTypeDef *TIM_QEPInitStruct);

/**
 * @brief QEP使能/失能函数
 * @param QEPx QEP模块指针
 * @param state 使能/失能状态
 */
void QEP_Cmd(QEP_TypeDef *QEPx, uint8_t state);

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

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

/**
 * @brief 获取QEP中断标志状态
 * @param QEPx QEP模块指针
 * @param QEP_IF_x 中断标志类型
 * @return 中断标志状态
 */
uint16_t QEP_GetIRQFlag(QEP_TypeDef *QEPx, uint32_t QEP_IF_x);

/**
 * @brief 获取QEP状态标志
 * @param QEPx QEP模块指针
 * @param QEP_IF_x 状态标志类型
 * @return 状态标志
 */
uint16_t QEP_GetFlag(QEP_TypeDef *QEPx, uint32_t QEP_IF_x);

/**
 * @brief 获取QEP状态标志
 * @param QEPx QEP模块指针
 * @param QEP_MODE_x 编码器工作模式
 */
void QEP_SetMode(QEP_TypeDef *QEPx, uint32_t QEP_MODE_x);

#endif
