#ifndef __LKS32MC09X_UART_H__
#define __LKS32MC09X_UART_H__

#include "lks32mc09x_reg.h"

/// UART 奇偶校验配置枚举成员
typedef enum
{
    UART_Parity_NO   = 0x00, ///< 无校验
    UART_Parity_EVEN = 0x01, ///< 偶校验
    UART_Parity_ODD  = 0x02  ///< 奇校验
} UART_ParityMode;

/// UART 初始化结构体定义
typedef struct
{
    uint32_t BaudRate;          ///< 波特率
    uint8_t WordLength;         ///< 数据长度
    uint8_t StopBits;           ///< 停止位长度
    uint8_t FirstSend;          ///< 发送数据大小端设置
    UART_ParityMode ParityMode; ///< 奇偶校验
    uint8_t MultiDropEna;       ///< 使能Multi-drop, 0:Disable 1:Enable
    uint8_t Bit9Value;          ///< Multi-drop Master模式时, 第9个数据位值
    uint8_t DUPLEX;             ///< 双工选择, 0:全双工 1:半双工
    uint16_t Match485Addr;      ///< 用作485通信时的匹配地址
    uint16_t IRQEna;            ///< 中断使能寄存器
    uint8_t DMARE;              ///< DMA 请求使能
    uint8_t RXD_INV;            ///< 接收电平取反
    uint8_t TXD_INV;            ///< 发送电平取反
    uint8_t ABD_EN;             ///< LIN波特率自适应使能
    uint8_t LBDL;               ///< LIN同步段检测长度 0:10bits 1:11bits
    uint8_t LIN_EN;             ///< LIN 模式使能
    uint8_t CK_EN;              ///< 数据校验开关
} UART_InitTypeDef;

/// 数据长度定义
#define UART_WORDLENGTH_8b 0 ///< 8位数据位
#define UART_WORDLENGTH_9b 1 ///< 9位数据位

/// 停止位长度定义
#define UART_STOPBITS_1b 0 ///< 无停止位
#define UART_STOPBITS_2b 1 ///< 1位停止位

/// 发送数据大小端设置
#define UART_FIRSTSEND_LSB 0 ///< 低端先发送
#define UART_FIRSTSEND_MSB 1 ///< 高端先发送

/// 中断使能定义
#define UART_IRQEna_SendOver      BIT0 ///< 使能发送完成中断
#define UART_IRQEna_RcvOver       BIT1 ///< 使能接收完成中断
#define UART_IRQEna_SendBuffEmpty BIT2 ///< 使能发送缓冲区空中断
#define UART_IRQEna_StopError     BIT3 ///< 使能停止位错误中断
#define UART_IRQEna_CheckError    BIT4 ///< 使能校验错误中断
#define UART_IRQEna_TX_OV         BIT5 ///< 发送缓冲区溢出中断使能
#define UART_IRQEna_RX_OV         BIT6 ///< 接收缓冲区溢出中断使能
#define UART_IRQEna_LBD           BIT7 ///< LIN同步间隔场检测中断使能
#define UART_IRQEna_IDLE          BIT8 ///< 空闲帧中断使能 在串口接收完成后再等待10个baud的时间后触发
#define UART_IRQEna_ABD           BIT9 ///< 波特率自适应使能中断

/// DMA 请求使能定义
#define TX_DMA_RE     BIT0 ///< 发送完成DMA请求使能
#define RX_DMA_RE     BIT1 ///< 接收完成DMA请求使能
#define TX_BUF_DMA_RE BIT2 ///< 发送缓冲区空DMA请求使能

/// 中断标志定义
#define UART_IF_SendOver     BIT0 ///< 发送完成中断标志
#define UART_IF_RcvOver      BIT1 ///< 接收完成中断标志
#define UART_IF_SendBufEmpty BIT2 ///< 发送缓冲区空中断标志
#define UART_IF_StopError    BIT3 ///< 停止位错误中断标志
#define UART_IF_CheckError   BIT4 ///< 校验错误中断标志
#define UART_IF_TX_OV        BIT5 ///< 发送缓冲区溢出中断标志
#define UART_IF_RX_OV        BIT6 ///< 接收缓冲区溢出中断标志
#define UART_IF_LBD          BIT7 ///< LIN break character 检测中断标志
#define UART_IF_IDLE         BIT8 ///< 空闲帧中断标志
#define UART_IF_ABD          BIT9 ///< 波特率自适应使能中断标志

/// 函数声明

/**
 * @brief 初始化UART模块
 * @param UARTx UART模块指针
 * @param UART_InitStruct 初始化结构体指针
 */
void UART_Init(UART_TypeDef *UARTx, UART_InitTypeDef *UART_InitStruct);

/**
 * @brief 初始化UART结构体为默认值
 * @param UART_InitStruct 初始化结构体指针
 */
void UART_StructInit(UART_InitTypeDef *UART_InitStruct);

/**
 * @brief 发送数据
 * @param UARTx UART模块指针
 * @param n 要发送的数据
 */
void UART_SendData(UART_TypeDef *UARTx, uint32_t n);

/**
 * @brief 读取接收到的数据
 * @param UARTx UART模块指针
 * @return 接收到的数据
 */
uint32_t UART_ReadData(UART_TypeDef *UARTx);

/**
 * @brief 发送指定长度的数据
 * @param UARTx UART模块指针
 * @param sendData 要发送的数据指针
 * @param len 数据长度
 */
void UART_SendnData(UART_TypeDef *UARTx, char *sendData, uint32_t len);

/**
 * @brief 接收指定长度的数据
 * @param UARTx UART模块指针
 * @param recvData 接收数据缓冲区指针
 * @param maxlen 最大接收长度
 */
void UART_RecvnData(UART_TypeDef *UARTx, char *recvData, uint32_t maxlen);

/**
 * @brief 清除指定的中断标志
 * @param UARTx UART模块指针
 * @param tempFlag 要清除的中断标志
 */
void UART_ClearIRQFlag(UART_TypeDef *UARTx, uint32_t tempFlag);

/**
 * @brief 获取指定的中断标志状态
 * @param UARTx UART模块指针
 * @param tempFlag 要获取的中断标志
 * @return 中断标志状态
 */
uint32_t UART_GetIRQFlag(UART_TypeDef *UARTx, uint32_t tempFlag);

/**
 * @brief 在485模式下发送地址
 * @param UARTx UART模块指针
 * @param n 要发送的地址
 * @return 发送状态
 */
uint8_t UART_SendAddr_485(UART_TypeDef *UARTx, uint8_t n);

/**
 * @brief 在485模式下发送数据
 * @param UARTx UART模块指针
 * @param n 要发送的数据
 * @return 发送状态
 */
uint8_t UART_SendData_485(UART_TypeDef *UARTx, uint8_t n);

/**
 * @brief 设置波特率
 * @param UARTx UART模块
 * @param Baud 波特率范围
 * @return 实际波特率（不考虑时钟误差）
 */
uint32_t UART_SetBaud(UART_TypeDef *UARTx, uint32_t Baud);

/**
 * @brief 设置uart时钟分频
 * @param div 分频系数，0对应不分频，1对应2分频
 */
void UART_SetClkDiv(uint32_t div);

#endif // __LKS32MC09X_UART_H__
