#ifndef __LKS32MC09X_SPI_H__
#define __LKS32MC09X_SPI_H__

#include "lks32mc09x_reg.h"

/**
 * @brief SPI模块主从模式枚举
 */
typedef enum
{
    SPI_Master = 0x01, ///< 主模式
    SPI_Slave  = 0x00  ///< 从模式
} SPI_Mode;

/**
 * @brief SPI模块全双工/半双工模式枚举
 */
typedef enum
{
    SPI_Full    = 0x00, ///< 全双工模式
    SPI_Half_Tx = 0x02, ///< 半双工模式，仅发送
    SPI_Half_Rx = 0x03  ///< 半双工模式，仅接收
} SPI_Duplex;

/**
 * @brief SPI模块初始化结构体
 */
typedef struct
{
    SPI_Duplex Duplex;  ///< 数据传输模式选择
    uint8_t CS;         ///< 从设备下片选信号来源：0，恒为0；1，来源于主设备
    SPI_Mode Mode;      ///< 主从模式选择
    uint8_t CPHA;       ///< 相位选择
    uint8_t CPOL;       ///< 极性选择
    uint8_t ENDIAN;     ///< 传输顺序选择：0对应MSB高位先传输；1对应LSB低位先传输
    uint8_t EN;         ///< 模块使能
    uint8_t IRQEna;     ///< 中断使能
    uint8_t Trig;       ///< 传输触发方式选择：1，外部触发；0，内部自动执行（仅主模式有效）
    uint8_t TRANS_MODE; ///< 数据搬移方式选择：0，DMA搬运；1，MCU搬运
    uint16_t BaudRate;  ///< 波特率设置，取值范围3-4095
    uint8_t ByteLength; ///< 数据长度
} SPI_InitTypeDef;

/**
 * @brief SPI数据传输顺序宏定义
 */
#define SPI_FIRSTSEND_LSB 1 ///< 低位先传
#define SPI_FIRSTSEND_MSB 0 ///< 高位先传

/**
 * @brief SPI数据搬移方式宏定义
 */
#define SPI_DMA_ENABLE  0 ///< 使能DMA搬运
#define SPI_DMA_DISABLE 1 ///< 禁止DMA搬运

/**
 * @brief SPI中断使能位定义
 */
#define SPI_IRQEna_Enable   BIT7 ///< SPI中断使能
#define SPI_IRQEna_TranDone BIT6 ///< 传输完成中断使能
#define SPI_IRQEna_SSErr    BIT5 ///< 传输异常事件中断使能
#define SPI_IRQEna_DataOver BIT4 ///< 传输溢出事件中断使能

/**
 * @brief SPI中断标志位定义
 */
#define SPI_IF_TranDone BIT2 ///< 传输完成中断标志位
#define SPI_IF_SSErr    BIT1 ///< 传输异常中断标志位
#define SPI_IF_DataOver BIT0 ///< 传输溢出中断标志位

/**
 * @brief SPI模块初始化函数
 * @param SPIx SPI模块指针
 * @param SPI_InitStruct 指向SPI初始化结构体的指针
 */
void SPI_Init(SPI_TypeDef *SPIx, SPI_InitTypeDef *SPI_InitStruct);

/**
 * @brief SPI初始化结构体默认配置函数
 * @param SPI_InitStruct 指向SPI初始化结构体的指针
 */
void SPI_StructInit(SPI_InitTypeDef *SPI_InitStruct);

/**
 * @brief SPI发送数据函数
 * @param SPIx SPI模块指针
 * @param n 要发送的数据
 */
void SPI_SendData(SPI_TypeDef *SPIx, uint8_t n);

/**
 * @brief SPI读取数据函数
 * @param SPIx SPI模块指针
 * @return 读取到的数据
 */
uint8_t SPI_ReadData(SPI_TypeDef *SPIx);

/**
 * @brief 获取SPI中断标志位状态函数
 * @param SPIx SPI模块指针
 * @param IRQ_Flag 中断标志位
 * @return 中断标志位状态
 */
uint8_t SPI_GetIRQFlag(SPI_TypeDef *SPIx, uint8_t IRQ_Flag);

/**
 * @brief 清除SPI中断标志位函数
 * @param SPIx SPI模块指针
 * @param IRQ_Flag 要清除的中断标志位
 */
void SPI_ClearIRQFlag(SPI_TypeDef *SPIx, uint8_t IRQ_Flag);

#endif // __LKS32MC09X_SPI_H__
