/*******************************************************************************
* Copyright (C) 2021-2025, All Rights Reserved.
*
* File:        hal_spi_slave.h
* Description  hal spi slave 模块头文件
* Version      V0.1
* Date         2023-07-27
* Author       swx
*******************************************************************************/
#ifndef __HAL_SPI_SLAVE_H__
#define __HAL_SPI_SLAVE_H__

/*******************************************************************************
* 1.Included files
*******************************************************************************/
#include "tau_dsi_datatype.h"
#include "tau_common.h"

/*******************************************************************************
* 2.Global constant and macro definitions using #define
*******************************************************************************/

/*******************************************************************************
* 3.Global structures, unions and enumerations using typedef
*******************************************************************************/
/**
* @brief  spi slave event type
*/
typedef enum
{
    SPIS_EVENT_RCV_FULL    = 0x2,                /* 数据接收完全 */
    SPIS_EVENT_RCV_CNT     = 0x4,                /* 数据接收指定阈值 */
    SPIS_EVENT_RCV_CS_RISE = 0x40,               /* CS上升沿 */
    SPIS_EVENT_RCV_CS_FALL = 0x80,               /* CS下降沿 */
    SPIS_EVENT_ALL_MISS    = 0X100,              /* ALL MISS中断*/
} hal_spis_event_e;

/**
* @brief  spi 硬件快速回复配置结构体
*/
typedef struct hal_spis_hw_ack_info_t
{
    uint8_t  index;
    uint8_t  cmp_data[4];   /* 匹配最长4byte */
    uint8_t  cmp_len;       /* 0 - 3 */
    bool     cmp_en;        /* 匹配enable */
    uint8_t  delay_clk;     /* 匹配成功后延迟数据恢复的clk数量,最小设置0,延迟1 clk */
    uint8_t *ack_address;   /* 匹配成功回复数据地址 */
    uint32_t ack_length;    /* 匹配成功回复数据长度 */
} hal_spis_hw_ack_info_t;

/**
* @brief  spi 事件 packet info
*/
typedef struct hal_spis_packet_info_t
{
    uint8_t           *rx_buffer;          /* 接收buffer   */
    uint32_t           rx_buffer_size;     /* 接收buffer size   */
    const uint8_t     *tx_buffer;          /* 发送buffer   */
    uint32_t           tx_buffer_size;     /* 发送buffer size   */
    bool               tx_circle;          /* 发送circle mode */
    uint32_t           packet_size;        /* packet size : RCV FULL事件 = rx buffer size, CS_RISE事件时为整个传输过程中SPIM发送packet的总量 */
} hal_spis_packet_info_t;

typedef void (*hal_spis_cb)(hal_spis_event_e event, hal_spis_packet_info_t *packet_info);

/*******************************************************************************
* 4.Global variable extern declarations
*******************************************************************************/

/*******************************************************************************
* 5.Global function prototypes
*******************************************************************************/
/*
SPIS启动流程:
1：hal_spis_init
2：hal_spis_update_rx_buffer & hal_spis_update_tx_buffer
3：hal_spis_register_callback
4：hal_spis_start
等待回调函数并从packet_info获取数据

Event:
SPI_EVENT_RCV_FULL,表示RX buffer接收满 , packet_info.packet_size = rx_buffer_size
SPI_EVENT_RCV_CS_HIGH,表示CS 拉高,一帧传输数据结束，此时packet_info.packet_size 为当前packet传输的所有byte数量

有可能存在只有SPI_EVENT_RCV_CS_HIGH而没有SPI_EVENT_RCV_FULL的情况,此时表示SPIM发送的数据不足于填满RX buffer
eg: rx_buffer_size = 10, SPIM实际只发送了2byte数据

接收到SPI_EVENT_RCV_CS_HIGH后可通过hal_spis_update_tx_buffer更新下一帧需要发送的数据
也可以通过hal_spis_update_rx_buffer更新接收数据的buffer

*/

/**
* @brief  初始化spi slave 模块
* @param  cpha: 相位配置
* @param  cpol: 极性配置
* @param
* @retval none
*/
void hal_spis_init(uint8_t cpha, uint8_t cpol);

/**
* @brief  spi slave 模块去初始化
* @param  none
* @retval none
*/
void hal_spis_deinit(void);

/**
* @brief  spi slave 注册回调函数
* @param  cb：call back
* @param  event_mask：接收事件掩码(eg:SPIS_EVENT_RCV_FULL|SPIS_EVENT_RCV_CS_RISE)
* @param  data_intcnt：SPIS_EVENT_RCV_CNT事件触发参数,当rx buffer接收到data_intcnt数据时.产生RCV_CNT事件
* @retval
*/
void hal_spis_register_callback(hal_spis_cb cb, uint32_t event_mask, uint16_t data_intcnt);

/**
* @brief  spi slave 设置RX DMA传输数据中断阈值
* @param  data_intcnt：SPIS_EVENT_RCV_CNT事件触发参数,当rx buffer接收到data_intcnt数据时.产生RCV_CNT事件
* @retval none
*/
void hal_spis_set_rx_dma_intcnt(uint16_t data_intcnt);

/**
* @brief  spi slave 配置接收buffer, 底层自动接收数据后调用callback
* @param  buffer：自动模式数据接收buffer
* @param  size：   自动模式数据接收buffer size
* @retval
*/
void hal_spis_update_rx_buffer(uint8_t *buffer, uint32_t size);

/**
* @brief  spi slave 配置自动发送buffer
* @param  buffer：自动模式数据发送buffer
* @param  size：   自动模式数据发收buffer size
* @param  circle：circle mode，重复发送buffer的数据
* @retval
*/
void hal_spis_update_tx_buffer(const uint8_t *buffer, uint32_t size, bool circle);

/**
* @brief  spi slave 启动
* @param  none
* @retval
*/
void hal_spis_start(void);

/**
* @brief  spi slave 停止
* @param  none
* @retval true/false
*/
void hal_spis_stop(void);

/**
* @brief  spi slave flush fifo
* @param  none
* @retval true/false
*/
void hal_spis_flush(void);

/**
* @brief  获取SPIS busy状态
* @param  none
* @retval true: CS拉低状态, false:CS拉高状态
*/
bool hal_spis_busy(void);

/**
* @brief  读取rx fifo缓冲数据
* @param  buffer:读取数据的缓冲区
* @param  count:需要读取的字节数
* @retval uint8_t:实际读取的字节数
*/
uint8_t hal_spis_read_data(uint8_t *buffer, uint8_t count);

/**
* @brief  spi slave cpu写一个数据
* @param  data:写的数据
* @retval true/false
*/
bool hal_spis_write_data(uint8_t data);

/**
* @brief  获取rx fifo状态
* @param  none
* @retval true/false
*/
bool hal_spis_get_rxfifo(void);

/**
* @brief  设置SPIS硬件快速回复功能使能状态
* @param  en:硬件快速回复功能使能
* @param  header_default:硬件快速回复功能的默认回复值
* @retval none
*/
void hal_spis_set_hw_ack_enable(bool en, uint8_t header_default);

/**
* @brief  获取SPIS硬件快速回复功能使能状态
* @param  void
* @retval bool
*/
bool hal_spis_get_hw_ack_enable(void);

/**
* @brief  设置SPIS硬件快速回复header参数
* @param  info:spi硬件快速回复配置结构体数组
* @param  size:设置size组参数
* @retval none
*/
void hal_spis_set_hw_ack_info(hal_spis_hw_ack_info_t *info, uint8_t size);

#endif /* __HAL_SPI_SLAVE_H__*/

