#ifndef __Viper_H
#define __Viper_H

#include <string.h>
#include "uart_helper.h"
#include "uart_interface.h"
// #include "config.h"

#define  Viper_DEMO           0  /*sn 读取位置不一样*/
#define  Viper_Rcv_Buf_Size   (3+244+2) 
#define  Viper_Command_Number       3

#define Viper_FLAG_MASK_BUSY ((uint32_t)1<<(uint32_t)0)
#define Viper_FLAG_MASK_RECVED_SN ((uint32_t)1<<(uint32_t)1)
#define Viper_FLAG_MASK_RECVED_WL ((uint32_t)1<<(uint32_t)2)
#define Viper_FLAG_MASK_RECVED_DATA ((uint32_t)1<<(uint32_t)3)
// #define Viper_FLAG_MASK_RECVED_WL_1 ((uint32_t)1<<(uint32_t)3)
// #define Viper_FLAG_MASK_RECVED_DATA_0 ((uint32_t)1<<(uint32_t)4)
// #define Viper_FLAG_MASK_RECVED_DATA_1 ((uint32_t)1<<(uint32_t)5)
 

typedef enum 
{
    MODULE_Viper_STATE_WAIT,
    MODULE_Viper_STATE_START,
    MODULE_Viper_STATE_GET_SN,
    MODULE_Viper_STATE_CHECK_SN,
    MODULE_Viper_STATE_GET_WL_0,
    MODULE_Viper_STATE_GET_WL_1,
    MODULE_Viper_STATE_GET_WL_2,
    MODULE_Viper_STATE_CHECK_WL,
    MODULE_Viper_STATE_Ready_GET_DATA,
    MODULE_Viper_STATE_START_DATA,
    MODULE_Viper_STATE_GET_DATA_0,
    MODULE_Viper_STATE_GET_DATA_1,
    MODULE_Viper_STATE_GET_DATA_2,
    MODULE_Viper_STATE_CHECK_DATA,
    MODULE_Viper_STATE_OK,
    MODULE_Viper_STATE_ERROR,
    MODULE_Viper_STATE_STOP
} MODULE_Viper_WORK_STATE;

typedef struct 
{
	  UartHelper_TypeDef *uarthelper;
    volatile MODULE_Viper_WORK_STATE state;

    volatile uint8_t flag;     /* Viper_FLAG_MASK_ SN WL1 WL2  DATA1  DATA2 ，*/
    volatile uint8_t send_flag;  		/* 发送标志位 */
    volatile Uart_Status_TypeDef send_status;  /* 发送状态 1：正在发送 busy，0：发送ok，*/
    volatile Uart_Status_TypeDef status;  /* 发送状态 0: ready , 1：正在发送 busy，2：发送ok，*/

    uint8_t interface_type; /* 0: common, 1: 485 ,2:3160*/
    uint8_t *send_buf;
    uint16_t size_send;
    uint8_t *rcv_buf;
    uint16_t size_rcv;


	  uint8_t mode_232_485; /* 0: common, 1: 485  */
    uint8_t trans_type;  /* 0 :polling, 1: IT  2: DMA*/
    uint8_t rcv_type;  /* 0 :polling, 1: IT  2: DMA*/
    uint8_t idle_enable_disable;    /* 0 不开启空闲中断 ， 1 开启空闲中断 */
	  uint8_t trans_mode;         /* 0 :polling, 1: IT  2: DMA*/

    volatile uint8_t step;             /* 0 : normal , 1 : get wavelength ,  2 : get sn   3: 空*/
    volatile uint8_t command_seq ;      /* 命令序号 */

    uint16_t sn;

    uint8_t sn_buf[15];
    uint8_t Viper_Wavelength_Buf[3][ Viper_Rcv_Buf_Size ];
    uint8_t Viper_Data_Buf[3][ Viper_Rcv_Buf_Size ];

    // uint8_t rcv_ok;                 /* 接收数据完整可以处理 */
    // uint8_t data_begin_flag;                 /* 接收数据完整可以处理 */
    uint8_t error;                 /* 接收数据完整可以处理 */
    uint8_t data_ok;                 /* 接收数据完整可以处理 */
    volatile uint16_t size_received;                  

    uint64_t timebase;
    uint64_t timeout_ms;
    uint64_t timeout_enable;

}Viper_TypeDef;

extern Viper_TypeDef *viper ;

uint8_t Viper_Init(   );

void Viper_Set_Uarthelper(Viper_TypeDef *viper, UartHelper_TypeDef *uarthelper);
void Viper_Set_Interface(Viper_TypeDef *viper, UartInterface_TypeDef *interface);

void Viper_Set_Huart( Viper_TypeDef * oscar,  UART_HandleTypeDef * huart  );
void Viper_Set_RsMode_232_485( Viper_TypeDef * oscar,  Uart_RS_Mode_TypeDef rs_232_485  );

void Viper_Set_Trans_Type( Viper_TypeDef *viper,  Uart_Transmode_TypeDef trans_type  );
void Viper_Set_Rcv_Type( Viper_TypeDef *viper,  Uart_Transmode_TypeDef rcv_type  );
void Viper_Set_Idle_Enable( Viper_TypeDef *viper,  Uart_IDLE_Enable_TypeDef idle_enable_disable  );
void Viper_Set_TransMode( Viper_TypeDef *viper,  Uart_Transmode_TypeDef trans_mode  );
 
void Viper_Set_Timeout( Viper_TypeDef *viper,    uint16_t timeout_ms );
void Viper_Set_Sendbuf( Viper_TypeDef *viper,  uint8_t * buf, uint16_t size );
void Viper_Set_Rcvbuf( Viper_TypeDef *viper,  uint8_t * buf, uint16_t size );





void Viper_Set_Timeout( Viper_TypeDef * oscar,    uint16_t timeout_ms );

// void Viper_Set_Sendbuf( Viper_TypeDef * oscar,  uint8_t * buf, uint16_t size );
// void Viper_Set_Rcvbuf( Viper_TypeDef * oscar,  uint8_t * buf, uint16_t size );

int Viper_Get_Timeout( Viper_TypeDef * oscar );

int Viper_Transmit( Viper_TypeDef * oscar,  uint8_t * buf, uint16_t size );
int Viper_Begin_Rcv( Viper_TypeDef * oscar,  uint8_t * buf, uint16_t size );

int Viper_Set_UartHelper_Status( Viper_TypeDef * oscar  ,Uart_Status_TypeDef status);
Uart_Status_TypeDef Viper_Get_UartHelper_Status( Viper_TypeDef * oscar  );
 

int  Viper_Get_Data_OK(Viper_TypeDef * oscar   );
void Viper_Set_Send_Flag(  Viper_TypeDef * oscar );

void Viper_callback( Viper_TypeDef * oscar,  uint8_t * buf, uint16_t size );
void Viper_Set_GPIO_For_TC_Cplt( Viper_TypeDef * oscar );

void Viper_clean_flag(Viper_TypeDef * oscar,uint8_t mask);
uint8_t Viper_get_flag(Viper_TypeDef * oscar,uint8_t mask);

uint16_t Viper_get_serial_number(Viper_TypeDef * oscar );

// int Viper_copy(uint8_t *targer_buf, uint8_t *src_buf,uint32_t buf_size);
int Viper_copy(Viper_TypeDef * oscar ,uint16_t size);
void Viper_Error( Viper_TypeDef * oscar, char* str );
 
// MODULE_Viper_WORK_STATE Set_State( MODULE_Viper_WORK_STATE state );
void Viper_Set_State( MODULE_Viper_WORK_STATE state  );

// int Viper_Send( Viper_TypeDef * oscar,  uint8_t * buf, uint16_t size);
// void Viper_Begin_Rcv(Viper_TypeDef * oscar,  uint8_t * buf, uint16_t size);

// extern  void Viper_Rcv_Cplt_Callback( Viper_TypeDef * oscar  );
// extern  void Viper_Send_Cplt_Callback(  Viper_TypeDef * oscar );

// void Viper_Set_Interface_Type( Viper_TypeDef * oscar,   Uart_Interface_Typedef interface_type  );
// void Viper_Set_Trans_Type( Viper_TypeDef * oscar,  Uart_Transmode_TypeDef trans_type  );
// void Viper_Set_Rcv_Type( Viper_TypeDef * oscar,  Uart_Transmode_TypeDef rcv_type  );
// void Viper_Set_Idle_Enable( Viper_TypeDef * oscar,  Uart_IDLE_Enable_TypeDef idle_enable_disable  );
// void Viper_Set_TransMode( Viper_TypeDef * oscar,  Uart_Transmode_TypeDef trans_mode  );
// void Viper_Set_RsMode_232_485( Viper_TypeDef * oscar,  Uart_RS_Mode_TypeDef rs_232_485  );

// extern void Viper_Setup(    );
extern void Viper_Port( );
// extern void Viper_SN( );
// extern void Viper_Wavelength( );
void Viper_Task( void* argument);
 
/* 再封装演示 */ 
typedef struct 
{
	uint8_t (*init)( );			 
	void (*port)(void);	
  void  (*Set_State)(MODULE_Viper_WORK_STATE state );
  // MODULE_Viper_WORK_STATE  (*Set_State)( MODULE_Viper_WORK_STATE state );

    GPIO_TypeDef *sel_gpio;	 
    GPIO_TypeDef *dplx_gpio;	 
    GPIO_TypeDef *de_gpio;	 
    uint16_t sel_pin;
    uint16_t dplx_pin;
    uint16_t de_pin;

    Uart_Interface_Type_Typedef interface_type; /* 0: default(ttl 232), 1: 485 ,2:3160*/
    Uart_RS_Mode_TypeDef mode_232_485;       /* 0 commome  1:485*/
    Uart_Transmode_TypeDef trans_type;     /* 0 :polling, 1: IT  2: DMA*/
    Uart_Transmode_TypeDef rcv_type;     /* 0 :polling, 1: IT  2: DMA*/
    Uart_IDLE_Enable_TypeDef idle_enable_disable;     /* 0 :不启用空闲 , 1: 启用空闲*/
 
    Viper_TypeDef *viper; /*不是常量  不能直接初始化*/

}My_Viper_TypeDef;
extern My_Viper_TypeDef myviper;

#endif

/**
 * 调用  
 * init:  Viper_Setup( );  Viper_SN( );  Viper_Wavelength( );
 * call:  Viper_Port( ); 
 * 
 * sn 波长部分，？？ 单独拉出来初始化，然后任务， 还是一起放任务里头？
 * 多个任务放一个统一开始的开关？ 用一个字节的多个位表示？
 * @register:  viper
    DataBeginAddress: 2614
    SNAddress: 2980,10
    SNLen: 5
    WLBeginAddress: 2102
    count: 3
    functioncode: 3
    slaveaddress: 1
    122   122*4+5  = 493

  wl:
    01 03 08 36 00 7A 26 47    (2102  122)
    01 03 08 B0 00 7A C7 AE    (2224  122)
    01 03 09 2A 00 7A E6 7D    (2346  122)

  data: 
    01 03 0A 36 00 7A 27 FF    (2614  122)
    01 03 0A B0 00 7A C6 16    (2736  122)
    01 03 0B 2A 00 7A E7 C5    (2758  122)

  01 03 0B A4 00 05 C6 0E    (SN  2980 5  demo)
  01 03 00 0A 00 05 A5 CB    (SN  10   5   实际)
 * 
 */

/**
 * @register:   viper
    DataBeginAddress: 2614
    SNAddress: 2840
    SNLen: 5
    WLBeginAddress: 2102
    count: 2
    functioncode: 3
    slaveaddress: 1
    wl:
    01 03 08 36 00 7A 26 47    (2102  122)
    01 03 08 B0 00 7A C7 AE    (2224  122)
 

  data: 
    01 03 0A 36 00 7A 27 FF    (2614  122)
    01 03 0A B0 00 7A C6 16    (2736  122)
 

    01 03 0B 18 00 05 07 EA    (SN  2840 5  demo)
    01 03 00 0A 00 05 A5 CB    (SN  10 5   实际)
 * 
 */