/**
 * @file wk2114.h
 * @author Chen Jihang (embedded@eseaoptics.com)
 * @brief WK2114串口拓展芯片驱动
 * @version 1.0
 * @date 2023-01-04
 * 
 * @copyright ESEA (c) 2020
 * 
 */
#ifndef WK2114_H_
#define WK2114_H_
#include <stdint.h>
#include <stddef.h>
#include "FreeRTOS.h"
#include "task.h"
#include "cmsis_os.h"
#include "main.h"

#define WK2114_CLOCK_HZ (12000000U)

#define WK2114_CMD_IS_WRITE(cmd) (((cmd>>6)&1)==0)
#define WK2114_CMD_IS_READ(cmd) (((cmd>>6)&1)==1)
#define WK2114_CMD_IS_REG(cmd) (((cmd>>7)&1)==0)
#define WK2114_CMD_IS_FIFO(cmd) (((cmd>>7)&1)==1)
#define WK2114_CMD_GET_ADDR(cmd) (cmd&0x3f)
#define WK2114_CMD_GET_SIZE(cmd) ((cmd&0x0f)+1)
#define WK2114_CMD_GET_CMD(cmd) (cmd>>6)
#define WK2114_CMD_GET_SUB_UART(cmd) ((cmd>>4)&0x03)
#define WK2114_REG_IS_GLOBAL(reg) ((reg&0x0f)<=0x02?1:0)
#define WK2114_BUILD_SUB_REG(sub_uart,reg) ((sub_uart<<4)|(reg&0x0f))

#define WK2114_S_UART_FLAG_MASK_IDLE (1<<0)     //< 子串口标志位 接收到串口空闲中断
#define WK2114_S_UART_FLAG_MASK_PAGE (1<<1)     //< 子串口标志位 设置的寄存器页
#define WK2114_S_UART_FLAG_MASK_PAGE_D (1<<2)   //< 子串口标志位 当前寄存器页
#define WK2114_S_UART_FLAG_MASK_ENABLE (1<<3)   //< 子串口标志位 使能

#define WK2114_G_FLAG_MASK_BUSY (1<<0)      //< wk2114标志位 正在等待接收
#define WK2114_G_FLAG_MASK_INTER (1<<1)     //< wk2114标志位 正在处理中断
#define WK2114_G_FLAG_MASK_SENDING (1<<2)   //< wk2114标志位 正在发送

#define WK2114_G_REG_GIFR_MASK_UT1INT (1<<0)    //< 串口1中断
#define WK2114_G_REG_GIFR_MASK_UT2INT (1<<1)    //< 串口2中断
#define WK2114_G_REG_GIFR_MASK_UT3INT (1<<2)    //< 串口3中断
#define WK2114_G_REG_GIFR_MASK_UT4INT (1<<3)    //< 串口4中断

#define WK2114_S_REG_SIFR_MASK_RFTRIG_INT (1<<0)   //< 接收FIFO触点中断
#define WK2114_S_REG_SIFR_MASK_RXOVT_INT (1<<1)    //< 接收FIFO超时中断
#define WK2114_S_REG_SIFR_MASK_TFTRIG_INT (1<<2)   //< 发送FIFO触点中断
#define WK2114_S_REG_SIFR_MASK_TFEMPTY_INT (1<<3)  //< 发送FIFO空中断
#define WK2114_S_REG_SIFR_MASK_FERR_INT (1<<7)     //< 接收FIFO错误中断

#define WK2114_SUB_UART_MODE_MASK_RX ((uint8_t)1<<0)    //< 子串口模式 接收
#define WK2114_SUB_UART_MODE_MASK_TX ((uint8_t)1<<1)    //< 子串口模式 发送
#define WK2114_SUB_UART_MODE_MASK_SLEEP ((uint8_t)1<<2) //< 子串口模式 允许睡眠

#define WK2114_SUB_UART_FIFO_MODE_MASK_RX ((uint8_t)1<<2)   //< 子串口FIFO模式 接收
#define WK2114_SUB_UART_FIFO_MODE_MASK_TX ((uint8_t)1<<3)   //< 子串口FIFO模式 发送

enum wk31661_cmd{
    WK2114_CMD_WRITE_REG=0x00, //< 写寄存器
    WK2114_CMD_READ_REG=0x01,  //< 读寄存器
    WK2114_CMD_WRITE_FIFO=0x02,//< 写FIFO
    WK2114_CMD_READ_FIFO=0x03  //< 读FIFO
};
enum wk2114_g_reg{
    WK2114_G_REG_GENA=0x00,    //< 全局控制寄存器
    WK2114_G_REG_GRST=0x01,    //< 全局子串口复位寄存器
    WK2114_G_REG_GMUT=0x02,    //< 全局主串口控制寄存器
    WK2114_G_REG_GIER=0x10,    //< 全局中断寄存器
    WK2114_G_REG_GIFR=0x11     //< 全局中断标志寄存器
};
enum wk2114_s_reg{
    WK2114_S_REG_SPAGE=0x03,   //< 子串口页控制寄存器
    WK2114_S_REG_SCR=0x04,     //< PAGE0: 子串口控制寄存器
    WK2114_S_REG_LCR=0x05,     //< PAGE0: 子串口配置寄存器
    WK2114_S_REG_FCR=0x06,     //< PAGE0: 子串口FIFO控制寄存器
    WK2114_S_REG_SIER=0x07,    //< PAGE0: 子串口中断使能寄存器
    WK2114_S_REG_SIFR=0x08,    //< PAGE0: 子串口中断标志寄存器
    WK2114_S_REG_TFCNT=0x09,   //< PAGE0: 子串口发送FIFO计数寄存器
    WK2114_S_REG_RFCNT=0x0a,   //< PAGE0: 子串口接收FIFO计数寄存器
    WK2114_S_REG_FSR=0x0b,     //< PAGE0: 子串口FIFO状态寄存器
    WK2114_S_REG_LSR=0x0c,     //< PAGE0: 子串口接收状态寄存器
    WK2114_S_REG_FDAT=0x0d,    //< PAGE0: 子串口FIFO数据寄存器
    WK2114_S_REG_BUAD1=0x04,   //< PAGE1: 子串口波特率配置寄存器高字节
    WK2114_S_REG_BUAD0=0x05,   //< PAGE1: 子串口波特率配置寄存器低字节
    WK2114_S_REG_PRES=0x06,    //< PAGE1: 子串口波特率配置寄存器小数部分
    WK2114_S_REG_RFTL=0x07,    //< PAGE1: 子串口接收FIFO中断触发点配置寄存器
    WK2114_S_REG_TFTL=0x08     //< PAGE1: 子串口发送FIFO中断触发点配置寄存器
};

enum wk2114_s_uart{
    WK2114_S_UART_1=0x00,      //< 子串口1
    WK2114_S_UART_2=0x01,      //< 子串口2
    WK2114_S_UART_3=0x02,      //< 子串口3
    WK2114_S_UART_4=0x03       //< 子串口4
};

enum wk2114_uart_parity{
    WK2114_UART_PARITY_NONE=0x00,  //< 无校验
    WK2114_UART_PARITY_ZERO=0x08,  //< 强制零校验
    WK2114_UART_PARITY_ODD=0x0a,   //< 奇校验
    WK2114_UART_PARITY_EVEN=0x0c,  //< 偶校验
    WK2114_UART_PARITY_ONE=0x0e    //< 强制一校验
};

enum wk2114_uart_stop_bits{
    WK2114_UART_STOP_BITS_1=0,  //< 1位停止位
    WK2114_UART_STOP_BITS_2=1   //< 2位停止位
};

typedef void (*wk2114_sub_uart_recv_fun)(void *recv_class,uint8_t *buf,uint32_t size);  //< 子串口接收数据回调函数
typedef int (*wk2114_send_fun)(void *send_class,uint8_t *buf,uint32_t size);   
         //< wk2114发送函数

/**
 * @brief 发送记录
 * 
 */
struct wk2114_send_record
{
    uint32_t size;
    uint8_t *p_data;
};

typedef struct __wk2114     WK2114_TypeDef;
typedef struct __wk2114_sub_uart     WK2114_Sub_Uart_TypeDef;

struct __wk2114
{
    volatile uint8_t flag;                           //< 标志位
    uint8_t cmd;                            //< 上一次的全局寄存器读命令
    uint8_t reg;                            //< 上一次接收到的全局寄存器
	osMessageQueueId_t cmd_queue;				//< 命令队列 
    // struct queue cmd_queue;                 //< 命令队列
    WK2114_Sub_Uart_TypeDef *sub_uart[4];    //< 子串口

    uint8_t cmd_queue_msg[2] ;

    uint8_t cmd_buf[64][2];                 //< 命令队列缓冲区
    uint8_t send_buf[18];                   //< 发送缓冲区   2+16
    void *send_class;                       //< 发送函数的第一个参数
    uint32_t dev_clock_hz;                  //< wk2114时钟源频率
    wk2114_send_fun send_fun;               //< 发送函数
}  ;

struct   __wk2114_sub_uart
{
    uint8_t flag;                               //< 标志位
    uint8_t cmd;                                //< 上一次的子串口寄存器读命令
    uint8_t reg;                                //< 上一次接收到的子串口寄存器
    uint8_t uart_index;                         //< 串口地址
    void *recv_class;                           //< 接收回调函数的第一个参数
    wk2114_sub_uart_recv_fun recv_fun;          //< 接收回调函数
	osMessageQueueId_t send_queue;				//< 发送队列 ?? 子串口待发送出去的？还是通过主串口发回来的
    // struct queue send_queue;                    //< 发送队列
    uint8_t *recv_buf;                          //< 接收缓冲区
    uint8_t *send_buf;                          //< 当前发送数据指针
    uint32_t recv_buf_p;                        //< 接收缓冲区计数
    uint32_t recv_buf_size;                     //< 接收缓冲区大小
    WK2114_TypeDef *wk2114;                      //< wk2114结构指针
    uint32_t send_buf_p;                        //< 发送缓冲区计数
    struct wk2114_send_record send_record[8];   //< 发送记录
} ;

extern WK2114_TypeDef *wk2114;

int WK2114_Init( );

int wk2114_send(WK2114_TypeDef *wk2114);
int wk2114_read_reg(WK2114_TypeDef *wk2114,uint8_t reg_addr);
int wk2114_write_reg(WK2114_TypeDef *wk2114,uint8_t reg_addr,uint8_t reg);
int wk2114_read_fifo(WK2114_TypeDef *wk2114,enum wk2114_s_uart sub_uart,uint8_t size);
int wk2114_write_fifo(WK2114_TypeDef *wk2114,enum wk2114_s_uart sub_uart,uint8_t *buf,uint8_t size);
int wk2114_sub_uart_set_page(WK2114_Sub_Uart_TypeDef*sub_uart,uint8_t page);
int wk2114_flush_gena(WK2114_TypeDef *wk2114);
int wk2114_flush_gier(WK2114_TypeDef *wk2114);
int wk2114_sub_uart_set_inter(WK2114_Sub_Uart_TypeDef*sub_uart,uint8_t inter_flag);
int wk2114_sub_uart_set_fifo_trigger(WK2114_Sub_Uart_TypeDef*sub_uart,uint8_t tx_trigger,uint8_t rx_trigger);
void wk2114_reg_recv_callback(WK2114_TypeDef *wk2114);

int wk2114_set_baud( WK2114_TypeDef *wk2114 );
int wk2114_set_uart(WK2114_TypeDef *wk2114,enum wk2114_uart_parity party,enum wk2114_uart_stop_bits stop_bits);
int wk2114_set_sub_uart(WK2114_Sub_Uart_TypeDef*sub_uart,uint32_t buad,enum wk2114_uart_parity party,enum wk2114_uart_stop_bits stop_bits);
int wk2114_sub_uart_set_mode(WK2114_Sub_Uart_TypeDef*sub_uart,uint8_t mode);
int wk2114_sub_uart_set_fifo_mode(WK2114_Sub_Uart_TypeDef*sub_uart,uint8_t mode);
int wk2114_sub_uart_enable(WK2114_Sub_Uart_TypeDef*sub_uart);
int wk2114_sub_uart_disable(WK2114_Sub_Uart_TypeDef*sub_uart);
int wk2114_sub_uart_reset(WK2114_Sub_Uart_TypeDef*sub_uart);

WK2114_TypeDef * wk2114_init(WK2114_TypeDef *wk2114,uint32_t dev_clock_hz,void *send_class,wk2114_send_fun send_fun);
int wk2114_sub_uart_register(WK2114_TypeDef *wk2114,WK2114_Sub_Uart_TypeDef*sub_uart,enum wk2114_s_uart uart_addr,uint8_t *recv_buf,uint32_t recv_buf_size,void *recv_class,wk2114_sub_uart_recv_fun recv_fun);
int wk2114_sub_uart_init(WK2114_Sub_Uart_TypeDef*sub_uart,uint32_t buad,uint8_t mode,uint8_t fifo_mode,enum wk2114_uart_parity party,enum wk2114_uart_stop_bits stop_bits);
int wk2114_sub_uart_chenge_recv_fun(WK2114_Sub_Uart_TypeDef*sub_uart,void *recv_class,wk2114_sub_uart_recv_fun recv_fun);
int wk2114_sub_uart_send(WK2114_Sub_Uart_TypeDef*sub_uart,uint8_t *buf,uint32_t size);
int wk2114_sub_uart_isbusy(WK2114_Sub_Uart_TypeDef*sub_uart);
void wk2114_recv_callback(WK2114_TypeDef *wk2114,uint8_t *buf,uint32_t size);
void wk2114_inter_callback(WK2114_TypeDef *wk2114);
void wk2114_send_completed_callback(WK2114_TypeDef *wk2114);

#endif

/*
逻辑：

如pH 传感器使用 子串口1
pH里面回调函数 PH_Callback 注册到子串口1

1. 子串口1发送
		调用主串口， 做好主串口的发送队列

2. 子串口接收，由外部中断启动，最后调用了PH_callback 将数据写回

*/