#ifndef __LKS32MC09X_ADC_H__
#define __LKS32MC09X_ADC_H__

#include "lks32mc09x_reg.h"

/**
 * @brief ADC初始化结构体定义
 */
typedef struct
{
    uint16_t IE;         ///< 中断使能
    uint16_t RE;         ///< DMA请求使能
    uint16_t NSMP;       ///< 两段采样使能
    uint16_t DATA_ALIGN; ///< DAT右对齐使能
    uint16_t CSMP;       ///< 连续采样使能
    uint16_t TCNT;       ///< 触发一次采样所需的事件数
    uint16_t TROVS;      ///< 手动触发过采样使能，开启后一次采样需要多次触发
    uint16_t OVSR;       ///< 过采样率
    uint32_t TRIG;       ///< 触发信号
    uint16_t S1;         ///< 第一段常规采样次数，1表示触发1次采样1次，2表示触发1次采样2次
    uint16_t S2;         ///< 第二段常规采样次数
    uint16_t IS1;        ///< 空闲采样次数
    uint16_t GAIN;       ///< 低增益（7.2V量程）使能
    uint16_t LTH;        ///< ADC 模拟看门狗 0 下阈值
    uint16_t HTH;        ///< ADC 模拟看门狗 0 上阈值
    uint16_t GEN;        ///< ADC 模拟看门狗 0 对应使能位
    uint16_t IDLE_PRI;   ///< 空闲触发高优先级使能，默认为0，空闲触发优先级低于常规触发
} ADC_InitTypeDef;

/**
 * @brief DMA请求使能宏定义
 */
#define ADC_RE_ISF  BIT15 ///< 空闲采样完成 DMA 请求使能
#define ADC_RE_HERR BIT14 ///< 硬件触发发生在非空闲状态 DMA 请求使能
#define ADC_RE_SERR BIT13 ///< 软件触发发生在非空闲状态 DMA 请求使能
#define ADC_RE_AWD0 BIT10 ///< 阈值监测 0 超限 DMA 请求使能
#define ADC_RE_SF2  BIT9  ///< 第二段采样完成 DMA 请求使能
#define ADC_RE_SF1  BIT8  ///< 第一段采样完成 DMA 请求使能

/**
 * @brief DMA中断使能宏定义
 */
#define ADC_IE_ISF  BIT7 ///< 空闲采样完成中断使能
#define ADC_IE_HERR BIT6 ///< 硬件触发发生在非空闲状态中断使能
#define ADC_IE_SERR BIT5 ///< 软件触发发生在非空闲状态中断使能
#define ADC_IE_AWD0 BIT2 ///< 阈值监测 0 超限中断使能
#define ADC_IE_SF2  BIT1 ///< 第二段常规采样完成中断使能
#define ADC_IE_SF1  BIT0 ///< 第一段常规采样完成中断使能

/**
 * @brief 中断标志位宏定义
 */
#define ADC_IF_ISF  BIT7   ///< 空闲采样完成中断标志
#define ADC_IF_HERR BIT6   ///< 硬件触发发生在非空闲状态中断标志
#define ADC_IF_SERR BIT5   ///< 软件触发发生在非空闲状态中断标志
#define ADC_IF_AWD0 BIT2   ///< 阈值监测 0 超限中断标志
#define ADC_IF_SF2  BIT1   ///< 第二段常规采样完成中断标志
#define ADC_IF_SF1  BIT0   ///< 第一段常规采样完成中断标志
#define ADC_IF_ALL  (0x7f) ///< ADC全部中断标志位——可用于初始化

/**
 * @brief 空闲采样使能宏定义
 */
#define ADC_TRIG_CL_IT3          BIT27 ///< CL_OUTPUT[3]触发 ADC 空闲采样使能，高有效
#define ADC_TRIG_CL_IT2          BIT26 ///< CL_OUTPUT[2]触发 ADC 空闲采样使能，高有效
#define ADC_TRIG_CL_IT1          BIT25 ///< CL_OUTPUT[1]触发 ADC 空闲采样使能，高有效
#define ADC_TRIG_CL_IT0          BIT24 ///< CL_OUTPUT[0]触发 ADC 空闲采样使能，高有效
#define ADC_TRIG_TIMER2_CMP1_IEN BIT23 ///< TIMER2/TIMER1 比较/捕获事件 1 触发 ADC 空闲采样使能，高有效
#define ADC_TRIG_TIMER2_CMP0_IEN BIT22 ///< TIMER2/TIMER1 比较/捕获事件 0 触发 ADC 空闲采样使能，高有效
#define ADC_TRIG_TIMER0_CMP1_IEN BIT21 ///< TIMER1/TIMER0 比较/捕获事件 1 触发 ADC 空闲采样使能，高有效
#define ADC_TRIG_TIMER0_CMP0_IEN BIT20 ///< TIMER0 比较/捕获事件 0 触发 ADC 空闲采样使能，高有效
#define ADC_TRIG_MCPWM0_T3_IEN   BIT19 ///< MCPWM0 T3 事件触发 ADC 空闲采样使能，高有效
#define ADC_TRIG_MCPWM0_T2_IEN   BIT18 ///< MCPWM0 T2 事件触发 ADC 空闲采样使能，高有效
#define ADC_TRIG_MCPWM0_T1_IEN   BIT17 ///< MCPWM0 T1 事件触发 ADC 空闲采样使能，高有效
#define ADC_TRIG_MCPWM0_T0_IEN   BIT16 ///< MCPWM0 T0 事件触发 ADC 空闲采样使能，高有效

/**
 * @brief 常规采样使能宏定义
 */
#define ADC_TRIG_CL_NT3      BIT11 ///< CL_OUTPUT[3]触发 ADC 常规采样
#define ADC_TRIG_CL_NT2      BIT10 ///< CL_OUTPUT[2]触发 ADC 常规采样
#define ADC_TRIG_CL_NT1      BIT9  ///< CL_OUTPUT[1]触发 ADC 常规采样
#define ADC_TRIG_CL_NT0      BIT8  ///< CL_OUTPUT[0]触发 ADC 常规采样
#define ADC_TRIG_TIMER1_CMP1 BIT7  ///< TIMER1 比较事件 1 触发 ADC 常规采样
#define ADC_TRIG_TIMER1_CMP0 BIT6  ///< TIMER1 比较事件 0 触发 ADC 常规采样
#define ADC_TRIG_TIMER0_CMP1 BIT5  ///< TIMER0 比较事件 1 触发 ADC 常规采样
#define ADC_TRIG_TIMER0_CMP0 BIT4  ///< TIMER0 比较事件 0 触发 ADC 常规采样
#define ADC_TRIG_MCPWM0_T3   BIT3  ///< MCPWM0 T3 事件触发 ADC 常规采样
#define ADC_TRIG_MCPWM0_T2   BIT2  ///< MCPWM0 T2 事件触发 ADC 常规采样
#define ADC_TRIG_MCPWM0_T1   BIT1  ///< MCPWM0 T1 事件触发 ADC 常规采样
#define ADC_TRIG_MCPWM0_T0   BIT0  ///< MCPWM0 T0 事件触发 ADC 常规采样
#define ADC_TRIG_SOFT        0     ///< 仅软件触发 ADC 常规采样

/**
 * @brief ADC采样通道序号枚举定义
 */
typedef enum
{
    ADC_CHN_0 = 0, ///< 采样通道序号
    ADC_CHN_1,     ///< 采样通道序号
    ADC_CHN_2,     ///< 采样通道序号
    ADC_CHN_3,     ///< 采样通道序号
    ADC_CHN_4,     ///< 采样通道序号
    ADC_CHN_5,     ///< 采样通道序号
    ADC_CHN_6,     ///< 采样通道序号
    ADC_CHN_7,     ///< 采样通道序号
    ADC_CHN_8,     ///< 采样通道序号
    ADC_CHN_9,     ///< 采样通道序号
    ADC_CHN_10,    ///< 采样通道序号
    ADC_CHN_11,    ///< 采样通道序号
    ADC_CHN_12,    ///< 采样通道序号
    ADC_CHN_13,    ///< 采样通道序号
    ADC_CHN_14,    ///< 采样通道序号
    ADC_CHN_15,    ///< 采样通道序号
    // ADC0
    ADC0_CHN_OPA0       = ADC_CHN_0,  ///< ADC0采样通道序号
    ADC0_CHN_OPA1       = ADC_CHN_1,  ///< ADC0采样通道序号
    ADC0_CHN_OPA2       = ADC_CHN_2,  ///< ADC0采样通道序号
    ADC0_CHN_OPA3       = ADC_CHN_3,  ///< ADC0采样通道序号
    ADC0_CHN_ADC01_CH4  = ADC_CHN_4,  ///< ADC0采样通道序号
    ADC0_CHN_ADC01_CH5  = ADC_CHN_5,  ///< ADC0采样通道序号
    ADC0_CHN_ADC01_CH6  = ADC_CHN_6,  ///< ADC0采样通道序号
    ADC0_CHN_ADC01_CH7  = ADC_CHN_7,  ///< ADC0采样通道序号
    ADC0_CHN_ADC0_CH8   = ADC_CHN_8,  ///< ADC0采样通道序号
    ADC0_CHN_REF24      = ADC_CHN_9,  ///< ADC0采样通道序号
    ADC0_CHN_ADC01_CH10 = ADC_CHN_10, ///< ADC0采样通道序号
    ADC0_CHN_ADC01_CH11 = ADC_CHN_11, ///< ADC0采样通道序号
    ADC0_CHN_ADC0_CH12  = ADC_CHN_12, ///< ADC0采样通道序号
    ADC0_CHN_ADC0_CH13  = ADC_CHN_13, ///< ADC0采样通道序号
    ADC0_CHN_DAC        = ADC_CHN_14, ///< ADC0采样通道序号
    ADC0_CHN_AVSS       = ADC_CHN_15, ///< ADC0采样通道序号
    // ADC1
    ADC1_CHN_OPA0       = ADC_CHN_0,  ///< ADC1采样通道序号
    ADC1_CHN_OPA1       = ADC_CHN_1,  ///< ADC1采样通道序号
    ADC1_CHN_OPA2       = ADC_CHN_2,  ///< ADC1采样通道序号
    ADC1_CHN_OPA3       = ADC_CHN_3,  ///< ADC1采样通道序号
    ADC1_CHN_ADC01_CH4  = ADC_CHN_4,  ///< ADC1采样通道序号
    ADC1_CHN_ADC01_CH5  = ADC_CHN_5,  ///< ADC1采样通道序号
    ADC1_CHN_ADC01_CH6  = ADC_CHN_6,  ///< ADC1采样通道序号
    ADC1_CHN_ADC01_CH7  = ADC_CHN_7,  ///< ADC1采样通道序号
    ADC1_CHN_ADC1_CH8   = ADC_CHN_8,  ///< ADC1采样通道序号
    ADC1_CHN_ADC1_CH9   = ADC_CHN_9,  ///< ADC1采样通道序号
    ADC1_CHN_ADC01_CH10 = ADC_CHN_10, ///< ADC1采样通道序号
    ADC1_CHN_ADC01_CH11 = ADC_CHN_11, ///< ADC1采样通道序号
    ADC1_CHN_ADC1_CH12  = ADC_CHN_12, ///< ADC1采样通道序号
    ADC1_CHN_ADC1_CH13  = ADC_CHN_13, ///< ADC1采样通道序号
    ADC1_CHN_TMP        = ADC_CHN_14, ///< ADC1采样通道序号
    ADC1_CHN_AVDD       = ADC_CHN_15, ///< ADC1采样通道序号
} ADC_CHN_x;

/**
 * @brief ADC数据寄存器序号枚举定义
 */
typedef enum
{
    ADC_DAT_0 = 0, ///< 第0次采样信号对应结果寄存器序号
    ADC_DAT_1,     ///< 第1次采样信号对应结果寄存器序号
    ADC_DAT_2,     ///< 第2次采样信号对应结果寄存器序号
    ADC_DAT_3,     ///< 第3次采样信号对应结果寄存器序号
    ADC_DAT_4,     ///< 第4次采样信号对应结果寄存器序号
    ADC_DAT_5,     ///< 第5次采样信号对应结果寄存器序号
    ADC_DAT_6,     ///< 第6次采样信号对应结果寄存器序号
    ADC_DAT_7,     ///< 第7次采样信号对应结果寄存器序号
    ADC_DAT_8,     ///< 第8次采样信号对应结果寄存器序号
    ADC_DAT_9,     ///< 第9次采样信号对应结果寄存器序号
    ADC_DAT_10,    ///< 第10次采样信号对应结果寄存器序号
    ADC_DAT_11,    ///< 第11次采样信号对应结果寄存器序号
} ADC_DAT_x;

/**
 * @brief ADC增益序号枚举定义
 */
typedef enum
{
    ADC_GAIN_3V6 = 0, ///< 3.6V 量程
    ADC_GAIN_7V2 = 1, ///< 7.2V 量程
} ADC_GAIN_x;

/**
 * @brief ADC基准枚举定义
 */
typedef enum
{
    ADC_RANGE_3_3      = 0, ///< 3.3V基准
    ADC_RANGE_3_6      = 1, ///< 3.6V基准
    ADC_RANGE_EXTERNAL = 2, ///< 外部基准
} ADC_RANGE_x;
/**
 * @brief 使能ADC模块
 * @param ADCx: ADC模块指针，指向ADC0或ADC1
 */
void ADC_Enable(ADC_TypeDef *ADCx);

/**
 * @brief 禁用ADC模块
 * @param ADCx: ADC模块指针，指向ADC0或ADC1
 */
void ADC_Disable(ADC_TypeDef *ADCx);

/**
 * @brief 复位ADC模块
 * @param ADCx: ADC模块指针，指向ADC0或ADC1
 */
void ADC_Reset(ADC_TypeDef *ADCx);

/**
 * @brief 初始化ADC模块
 * @param ADCx: ADC模块指针，指向ADC0或ADC1
 * @param ADC_InitStruct: 指向ADC初始化结构体的指针
 */
void ADC_Init(ADC_TypeDef *ADCx, ADC_InitTypeDef *ADC_InitStruct);

/**
 * @brief 将ADC初始化结构体置为默认值
 * @param ADC_InitStruct: 指向ADC初始化结构体的指针
 */
void ADC_StructInit(ADC_InitTypeDef *ADC_InitStruct);

/**
 * @brief 获取ADC中断标志位状态
 * @param ADCx: ADC模块指针，指向ADC0或ADC1
 * @param INT_flag: 中断标志位，可以是ADC_IF_ISF等
 * @return 中断标志位状态
 */
uint16_t ADC_GetIRQFlag(ADC_TypeDef *ADCx, uint16_t INT_flag);

/**
 * @brief 清除ADC中断标志位
 * @param ADCx: ADC模块指针，指向ADC0或ADC1
 * @param INT_flag: 中断标志位，可以是ADC_IF_ISF等
 */
void ADC_ClearIRQFlag(ADC_TypeDef *ADCx, uint16_t INT_flag);

/**
 * @brief 设置ADC通道的增益
 * @param ADCx: ADC模块指针，指向ADC0或ADC1
 * @param DATNum: 数据寄存器序号，如ADC_DAT_0
 * @param gainx: 增益选择，如ADC_GAIN_3V6
 */
void ADC_SetGain(ADC_TypeDef *ADCx, ADC_DAT_x DATNum, ADC_GAIN_x gainx);

/**
 * @brief 获取ADC通道的转换值
 * @param ADCx: ADC模块指针，指向ADC0或ADC1
 * @param DATNum: 数据寄存器序号，如ADC_DAT_0
 * @return 转换值
 */
s16 ADC_GetConversionValue(ADC_TypeDef *ADCx, ADC_DAT_x DATNum);

/**
 * @brief 获取ADC通道的转换值(按int32返回，用来采样adc通道4、5、6、7)
 * @param ADCx: ADC模块指针，指向ADC0或ADC1
 * @param DATNum: 数据寄存器序号，如ADC_DAT_0
 * @return 转换值
 */
int32_t ADC_GetConversionValueS32(ADC_TypeDef *ADCx, ADC_DAT_x DATNum);

/**
 * @brief 执行软件触发ADC采样，采样次数取决于ADC_InitTypeDef里的S1的配置
 * @param ADCx: ADC模块指针，指向ADC0或ADC1
 */
void ADC_SoftTrig(ADC_TypeDef *ADCx);

/**
 * @brief 执行软件触发ADC空闲采样
 * @param ADCx: ADC模块指针，指向ADC0
 */
void ADC_SoftIdleTrig(ADC_TypeDef *ADCx);

/**
 * @brief 设置第每次的采样通道，例如ADC_SetChn(ADC0,ADC_DAT_0,ADC_CHN_0),把adc第一次采样的通道设置为通道0
 * @param ADCx: ADC模块指针，指向ADC0或ADC1
 * @param datx: 数据寄存器序号，如ADC_DAT_0
 * @param chnx: ADC采样通道序号枚举定义，如ADC_CHN_0
 */
void ADC_SetChn(ADC_TypeDef *ADCx, ADC_DAT_x datx, ADC_CHN_x chnx);

/**
 * @brief 设置ADC基准电压
 * @param ADCx ADC模块指针，指向ADC0或ADC1
 * @param rangex 基准选择
 */
void ADC_SetRange(ADC_TypeDef *ADCx, ADC_RANGE_x rangex);
#endif // __LKS32MC09X_ADC_H__
