#ifndef __LKS32MC09X_CMP_H__
#define __LKS32MC09X_CMP_H__
#include "lks32mc09x_reg.h"

/**
 *@brief CMP初始化结构体句柄，初始化时请定义该句柄，并用其它地址来传参
 */
typedef struct
{
    u16 SELP;               /**< 比较器信号正端选择*/
    u16 SELN;               /**< 比较器信号负端选择*/
    u32 FIL_CLK_DIV16;      /**< 比较器012滤波系数，赋值范围0-0xF */
    u32 FIL_CLK_DIV2;       /**< 比较器012滤波系数，0x0:1分频，0x1:2分频,0x2:4分频,0x3:8分频，0x4:16分频，0x5:32分频,0x6:64分频,0x7:128分频*/
    u16 POL;                /**< 比较器有效输出极性选择*/
    u16 W_PWM_POL;          /**< 比较器开窗 PWM 信号极性选择,比较器 0/1 */
    u16 IRQ_TRIG;           /**< 比较器边沿/电平触发中断选择 0电平触发 1边沿触发*/
    FuncState EN;           /**< 比较器使能\n DISABLE:失能，ENABLE：使能*/
    FuncState IE;           /**< 比较器中断使能，DISABLE:失能，ENABLE：使能*/
    FuncState RE;           /**< 比较器DMA 请求使能，DISABLE:失能，ENABLE：使能*/
    FuncState CHN3P_PWM_EN; /**< MCPWM 模块 CHN3_P 通道使能比较器 0/1 开窗，DISABLE:失能，ENABLE：使能*/
    FuncState CHN2P_PWM_EN; /**< MCPWM 模块 CHN2_P 通道使能比较器 0/1 开窗，DISABLE:失能，ENABLE：使能*/
    FuncState CHN1P_PWM_EN; /**< MCPWM 模块 CHN1_P 通道使能比较器 0/1 开窗，DISABLE:失能，ENABLE：使能*/
    FuncState CHN0P_PWM_EN; /**< MCPWM 模块 CHN0_P 通道使能比较器 0/1 开窗，DISABLE:失能，ENABLE：使能*/
} CMP_SingleTypeDef;
typedef struct
{
    u8 HYS;                     /**< 比较器回差选择*/
    u32 CLK_COM_DIV;            /**< 比较器共用分频系数，取值0-4*/
    CMP_SingleTypeDef CMP0_CFG; /**< CMP0配置*/
    CMP_SingleTypeDef CMP1_CFG; /**< CMP1配置*/
} CMP_InitTypeDef;

#define CMP_CHN_0 0
#define CMP_CHN_1 1
// 比较器模拟部分配置
// 比较器 1 正端信号选择
#define CMP_SELP_1_OPA2_IP     0  ///< 0000: OPA2_IP
#define CMP_SELP_1_OPA3_IP     1  ///< 0001: OPA3_IP
#define CMP_SELP_1_OPA2_OUTP   2  ///< 0010: OPA2_OUTP   , OPA2 差分输出正端
#define CMP_SELP_1_OPA3_OUTP   3  ///< 0011: OPA3_OUTP   , OPA3 差分输出正端
#define CMP_SELP_1_CMP1_IP0    4  ///< 0100: CMP1_IP0
#define CMP_SELP_1_CMP1_IP1    5  ///< 0101: CMP1_IP1
#define CMP_SELP_1_CMP1_IP2    6  ///< 0110: CMP1_IP2
#define CMP_SELP_1_CMP1_IP3    7  ///< 0111: CMP1_IP3
#define CMP_SELP_1_DAC1_OUT    9  ///< 1001: DAC1_OUT
#define CMP_SELP_1_OPA_OUT_CMP 10 ///< 1010: OPA_OUT_CMP
#define CMP_SELP_1_CMP0_IP1    11 ///< 1011: CMP0_IP1
#define CMP_SELP_1_CMP0_IP2    12 ///< 1100: CMP0_IP2
#define CMP_SELP_1_CMP0_IP3    13 ///< 1101: CMP0_IP3

// 比较器 0 正端信号选择
#define CMP_SELP_0_OPA0_IP     0  ///< 0000: OPA0_IP
#define CMP_SELP_0_OPA1_IP     1  ///< 0001: OPA1_IP
#define CMP_SELP_0_OPA0_OUTP   2  ///< 0010: OPA0_OUTP, OPA0 差分输出正端
#define CMP_SELP_0_OPA1_OUTP   3  ///< 0011: OPA1_OUTP, OPA1 差分输出正端
#define CMP_SELP_0_CMP0_IP0    4  ///< 0100: CMP0_IP0
#define CMP_SELP_0_CMP0_IP1    5  ///< 0101: CMP0_IP1
#define CMP_SELP_0_CMP0_IP2    6  ///< 0110: IP_CMP0_IP2
#define CMP_SELP_0_CMP0_IP3    7  ///< 0111: IP_CMP0_IP3
#define CMP_SELP_0_CMP0_IP4    8  ///< 1000: IP_CMP0_IP4
#define CMP_SELP_0_DAC0_OUT    9  ///< 1001: DAC0_OUT
#define CMP_SELP_0_OUT_OPA_CMP 10 ///< 1010: OUT_OPA_CMP
#define CMP_SELP_0_CMP1_IP1    11 ///< 1011: IP_CMP1_IP1
#define CMP_SELP_0_CMP1_IP2    12 ///< 1100: IP_CMP1_IP2
#define CMP_SELP_0_CMP1_IP3    13 ///< 1101: IP_CMP1_IP3

// 比较器回差选择
#define CMP_HYS_20mV 0 // 0:20mv
#define CMP_HYS_0mV  1 // 0:20mv

// 比较器 1 信号负端选择
#define CMP_SELN_1_IN_CMP1 0 ///< 000: 连 IN_CMP1
#define CMP_SELN_1_VBGP    1 ///< 001: 连 VBGP
#define CMP_SELN_1_DAC1    2 ///< 010: 连 DAC1 OUT
#define CMP_SELN_1_DAC0    3 ///< 011: 连 DAC0 OUT
#define CMP_SELN_1_HS_MID1 4 ///< 100: 连 HS_MID1 （中性点的电阻阻值增加为约 30k）

// 比较器 0 信号负端选择
#define CMP_SELN_0_IN_CMP0 0 ///< 000: 连 IN_CMP0
#define CMP_SELN_0_VBGP    1 ///< 001: 连 VBGP
#define CMP_SELN_0_DAC1    2 ///< 010: 连 DAC1 OUT
#define CMP_SELN_0_DAC0    3 ///< 011: 连 DAC0 OUT
#define CMP_SELN_0_HS_MID0 4 ///< 100: 连 HS_MID0 （中性点的电阻阻值增加为约 30k）

// 比较器数字部分配置
// 中断标志位
#define CMP_IF_CMP0 BIT0
#define CMP_IF_CMP1 BIT1
// 中断使能
#define CMP_IE_CMP0 BIT0
#define CMP_IE_CMP1 BIT1
// CMP事件DMA 请求使能
#define CMP_RE_CMP0 BIT8
#define CMP_RE_CMP1 BIT9

// 滤波宽度 1-2048可选，不再提供宏定义
// 模块时钟分频系数
#define CMP_CLK_DIV_0 0 ///< 不分频
#define CMP_CLK_DIV_1 1 ///< 1分频
#define CMP_CLK_DIV_2 2 ///< 2分频
#define CMP_CLK_DIV_3 3 ///< 3分频
#define CMP_CLK_DIV_4 4 ///< 4分频

// 比较器中断信号选择
#define CMP_SIGNAL_NONE    0                    // 不产生中断信号
#define CMP_SIGNAL_EDGE_P  (BIT2 | BIT1)        // 上升沿时产生中断信号
#define CMP_SIGNAL_EDGE_N  (BIT2 | BIT1 | BIT0) // 下降沿时产生中断信号
#define CMP_SIGNAL_LEVEL_H (BIT1)               // 高电平时产生中断信号，此时除非高电平电平信号消失，否则中断一直存在
#define CMP_SIGNAL_LEVEL_L (BIT1 | BIT0)        // 低电平时产生中断信号，此时除非高电平电平信号消失，否则中断一直存在

// 比较器开窗控制（开窗控制同时影响MCPWM模块的FAIL信号和比较器本身的数字处理）
#define CMP_WIN_SIGNAL_NONE     0      // 所有时刻比较器都运行
#define CMP_WIN_SIGNAL_MCPWM0_0 (BIT0) // 在MCPWM0_0上管/关闭时不工作
#define CMP_WIN_SIGNAL_MCPWM0_1 (BIT1) // 在MCPWM0_1上管/关闭时不工作
#define CMP_WIN_SIGNAL_MCPWM0_2 (BIT2) // 在MCPWM0_2上管/关闭时不工作
#define CMP_WIN_SIGNAL_MCPWM0_3 (BIT3) // 在MCPWM0_3上管/关闭时不工作
#define CMP_WIN_LEVEL_H         (1)    // 上管打开时比较器不工作
#define CMP_WIN_LEVEL_L         (0)    // 上管关闭时比较器不工作

// 模拟部分
/**
 * @brief 使能比较器
 * @param CMP_CHN_x: 比较器通道选择，CMP_CHN_0, CMP_CHN_1
 */
void CMP_Enable(uint8_t CMP_CHN_x);
/**
 * @brief 失能比较器
 * @param CMP_CHN_x: 比较器通道选择，CMP_CHN_0, CMP_CHN_1
 */
void CMP_Disable(uint8_t CMP_CHN_x);
/**
 * @brief 设置比较器信号来源
 * @param CMP_CHN_x: 比较器通道选择，CMP_CHN_0, CMP_CHN_1
 * @param CMP_SELN_x_x: 信号负端选择，注意，由于比较器的各个通道不完全一样，所以这里需要指明使用的比较器
 * @param CMP_SELP_x_x: 信号正端选择，注意，由于比较器的各个通道不完全一样，所以这里需要指明使用的比较器
 */
void CMP_SetSignal(uint8_t CMP_CHN_x, uint8_t CMP_SELN_x_x, uint8_t CMP_SELP_x_x);

/**
 * @brief 设置比较器回差(两个比较器共用同一个回差)
 * @param CMP_HYS_x: 回差选择，CMP_HYS_20mV, CMP_HYS_0mV
 */
void CMP_SetHysteresis(uint8_t CMP_HYS_x);

// 数字部分
/**
 * @brief 设置比较器开窗信号
 * @param CMP_CHN_x: 比较器通道选择，CMP_CHN_0, CMP_CHN_1
 * @param CMP_WIN_x: 开窗信号选择，CMP_WIN_SIGNAL_NONE, CMP_WIN_SIGNAL_MCPWM0_0
 * @param CMP_WIN_LEVEL_x: 开窗电平选择，CMP_WIN_LEVEL_H, CMP_WIN_LEVEL_L
 */
void CMP_SetWindowSignal(uint8_t CMP_CHN_x, uint8_t CMP_WIN_x, uint8_t CMP_WIN_LEVEL_x);
/**
 * @brief 设置比较器的滤波宽度
 * @param CMP_CLK_DIV_x: 比较器时钟分频系数，CMP_CLK_DIV_0, CMP_CLK_DIV_1, CMP_CLK_DIV_2, CMP_CLK_DIV_3, CMP_CLK_DIV_4
 * @param CMP0_FIL_x: 比较器0滤波宽度，取值范围0-2047，0表示关闭信号的输入
 * @param CMP1_FIL_x: 比较器1滤波宽度，取值范围0-2047，0表示关闭信号的输入
 */
void CMP_SetFilterWidth(uint8_t CMP_CLK_DIV_x, uint16_t CMP0_FIL_x, uint16_t CMP1_FIL_x);

/**
 * @brief 设置比较器中断信号
 * @param CMP_CHN_x: 比较器通道选择，CMP_CHN_0, CMP_CHN_1
 * @param CMP_SIGNAL_x: 中断信号选择，CMP_SIGNAL_NONE, CMP_SIGNAL_EDGE_P, CMP_SIGNAL_EDGE_N, CMP_SIGNAL_LEVEL_H, CMP_SIGNAL_LEVEL_L
 */
void CMP_SetIRQSignal(uint8_t CMP_CHN_x, uint8_t CMP_SIGNAL_x);
/**
 * @brief 清除CMP中断标志
 * @param CMP_CHN_x: 比较器通道选择，CMP_CHN_0, CMP_CHN_1
 */
void CMP_ClearIRQFlag(uint8_t CMP_CHN_x);

/**
 * @brief 读取CMP中断标志
 * @param CMP_CHN_x: 比较器通道选择，CMP_CHN_0, CMP_CHN_1
 * @return: 中断标志状态
 */
uint8_t CMP_GetIRQFlag(uint8_t CMP_CHN_x);

/**
 * @brief 读取滤波后的比较器值
 * @return: 滤波后的比较器值
 */
uint8_t CMP_GetFilterValue(uint8_t CMP_CHN_x);

/**
 * @brief 读取未滤波的比较器值
 * @return: 未滤波的比较器值
 */
uint8_t CMP_GetValue(uint8_t CMP_CHN_x);

void CMP_StructInit(CMP_InitTypeDef *CMP_InitStruct); /* CMP结构体初始化*/
void CMP_Init(CMP_InitTypeDef *CMP_InitStruct);       /* CMP初始化*/
#endif
