/**
 * @file Ramses.h
 * @author Esea (info@eseaoptics.com)
 * @brief Ramses 光谱仪驱动
 * @version 1.0
 * @date 2023-08-27
 * 
 * @copyright ESEA (c) 2020
 * 
 */
#ifndef TRIOS_REMSES_H_
#define TRIOS_REMSES_H_
#include <stddef.h>
#include <stdint.h>
#include <string.h>
#include "uart_helper.h"
#include "uart_interface.h"

#define Ramses_CMD_SIZE (8)
#define Ramses_DATA_SIZE (64+8)
#define Ramses_DATA_NUM (8)
#define Ramses_IP_SIZE (16+8)
#define Ramses_INFO_SIZE (8+8)

#define  Ramses_Rcv_Buf_Size   (1024) 
#define  Ramses_Command_Number       2

#define Ramses_FLAG_MASK_BUSY ((uint32_t)1<<(uint32_t)0)
#define Ramses_FLAG_MASK_RECVED_IP ((uint32_t)1<<(uint32_t)1)
#define Ramses_FLAG_MASK_RECVED_DATA ((uint32_t)1<<(uint32_t)2)
#define Ramses_FLAG_MASK_RECVED_INFO ((uint32_t)1<<(uint32_t)3)

typedef int (*Ramses_send_fun)(void *send_class,uint8_t *buf,uint32_t size);

typedef enum 
{
    MODULE_RAMSESE_STATE_WAIT,
    MODULE_RAMSESE_STATE_START,
    MODULE_RAMSESE_STATE_SEND_CMD,
    MODULE_RAMSESE_STATE_CHECK_SENSOR,
    MODULE_RAMSESE_STATE_GET_DATA,
    MODULE_RAMSESE_STATE_OK,
    MODULE_RAMSESE_STATE_ERROR,
    MODULE_RAMSESE_STATE_STOP
} MODULE_RAMSESE_WORK_STATE;

enum trios_integration_time{
    TRIOS_INTEGRATION_TIME_AUTO,
    TRIOS_INTEGRATION_TIME_4MS,
    TRIOS_INTEGRATION_TIME_8MS,
    TRIOS_INTEGRATION_TIME_16MS,
    TRIOS_INTEGRATION_TIME_32MS,
    TRIOS_INTEGRATION_TIME_64MS,
    TRIOS_INTEGRATION_TIME_128MS,
    TRIOS_INTEGRATION_TIME_256MS,
    TRIOS_INTEGRATION_TIME_512MS,
    TRIOS_INTEGRATION_TIME_1024MS,
    TRIOS_INTEGRATION_TIME_2048MS,
    TRIOS_INTEGRATION_TIME_4096MS,
    TRIOS_INTEGRATION_TIME_8192MS
};
struct Ramses_data
{
    uint16_t dev_id;
    uint8_t module_id;
    uint8_t framebyte;
    uint8_t data_size;
    uint8_t *data;
    uint8_t raw[Ramses_DATA_SIZE];
};
struct Ramses_ip
{
    uint16_t dev_id;
    uint8_t module_id;
    uint8_t framebyte;
    uint8_t data_size;
    uint8_t *data;
    uint8_t raw[Ramses_IP_SIZE];
};

struct Ramses_infomation
{
    uint16_t dev_id;
    uint8_t module_id;
    uint16_t serial_number;
    uint8_t firmware_number[2];
    uint8_t individual_information[Ramses_INFO_SIZE-8];
};

typedef struct trios_ramses
{
	// UartHelper_TypeDef *uarthelper;
    volatile MODULE_RAMSESE_WORK_STATE state;
    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，*/
    volatile uint8_t step;             /* 0 : normal , 1 : get wavelength ,  2 : get sn   3: 空*/
    // volatile uint8_t command_seq ;      /* 命令序号 */

    uint8_t flag;
    uint8_t flag_ip;
    uint8_t data_index;
    uint8_t recv_buf_p;
    uint8_t data_size;
    uint8_t recv_flag_40;
    uint8_t cmd_buf[Ramses_CMD_SIZE];

    struct Ramses_infomation infomation;
    struct Ramses_ip ip;
    struct Ramses_data data[Ramses_DATA_NUM];
    uint8_t recv_buf[Ramses_DATA_SIZE];
    uint16_t sn; 
    uint8_t error;

    uint8_t data_ok;                 /* 接收数据完整可以处理 */
    volatile uint16_t size_received;            
    uint64_t timebase;
    uint64_t timeout_ms;
    uint64_t timeout_enable;

    void *send_class;
    Ramses_send_fun send_fun;

}Ramses_TypeDef;
extern Ramses_TypeDef *ramses ;






static inline void Ramses_clean_data_recved_flag(Ramses_TypeDef *ramses)
{
    ramses->flag&=~Ramses_FLAG_MASK_RECVED_DATA;
}
static inline void Ramses_clean_ip_recved_flag(Ramses_TypeDef *ramses)
{
    ramses->flag&=~Ramses_FLAG_MASK_RECVED_IP;
}
static inline void Ramses_clean_info_recved_flag(Ramses_TypeDef *ramses)
{
    ramses->flag&=~Ramses_FLAG_MASK_RECVED_INFO;
}

int Ramses_init( );
int Ramses_send_cmd(Ramses_TypeDef *ramses,uint16_t dev_id,uint8_t module_id,uint8_t instruction,uint8_t parameter1,uint8_t parameter2);
int Ramses_cmd_messung(Ramses_TypeDef *ramses,uint8_t module_id);
int Ramses_cmd_set_integration_time(Ramses_TypeDef *ramses,enum trios_integration_time integration_time);
int Ramses_cmd_get_infomation(Ramses_TypeDef *ramses,uint8_t module_id);
uint32_t Ramses_get_ip_raw(Ramses_TypeDef *ramses,uint8_t *buf,uint32_t size);
uint32_t Ramses_get_data_raw(Ramses_TypeDef *ramses,uint8_t *buf,uint32_t size);
uint32_t Ramses_get_data(Ramses_TypeDef *ramses,int16_t *data,uint32_t num);
double Ramses_get_x_inclination_angle(Ramses_TypeDef *ramses,double incl_xgain,double incl_xoffset);
double Ramses_get_y_inclination_angle(Ramses_TypeDef *ramses,double incl_ygain,double incl_yoffset);
double Ramses_get_inclination_angle(double x_inclination_angle,double y_inclination_angle);
double Ramses_get_pressure(Ramses_TypeDef *ramses,double incl_kref,double incl_kbg,double press_gain,double press_surface_bar,double press_sens_mv_bar_1ma,double press_sens_mv_bar_4ma);
double Ramses_get_depth_m(double pressure);
uint16_t Ramses_get_serial_number(Ramses_TypeDef *ramses);
void Ramses_receive_callback(Ramses_TypeDef *ramses,uint8_t *buf,uint32_t size);
void Ramses_clean_flag(Ramses_TypeDef *ramses,uint8_t mask);
uint8_t Ramses_get_flag(Ramses_TypeDef *ramses,uint8_t mask);

void Ramses_Set_Timeout(Ramses_TypeDef *ramses,    uint16_t timeout_ms );
int Ramses_Get_Timeout( Ramses_TypeDef *ramses );

void Ramses_Set_Sendbuf( Ramses_TypeDef *ramses,  uint8_t * buf, uint16_t size );
void Ramses_Set_Rcvbuf( Ramses_TypeDef *ramses,  uint8_t * buf, uint16_t size );

void Ramses_Set_State (Ramses_TypeDef *ramses, MODULE_RAMSESE_WORK_STATE state);

// void Ramses_Setup ();
void Ramses_Port ();
void Ramses_Task(void * argument);
int Ramses_copy(Ramses_TypeDef *ramses ,uint16_t size);
/* 再封装演示 */ 
typedef struct 
{
	uint8_t (*init)( );			 
	uint8_t (*port)(void);	

    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: common, 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: 启用空闲/
 
    SC6_TypeDef *sample; /*不是常量  不能直接初始化*/

}My_Ramses_TypeDef;
extern My_Ramses_TypeDef myramses ;
#endif















// typedef struct 
// {
// 	UartHelper_TypeDef *uarthelper;
//     UART_HandleTypeDef *huart;
//     uint8_t interface_type; /* 0: common, 1: 485 ,2:3160*/
// 	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*/

// 	uint8_t *send_buf;
// 	uint16_t size_send;
// 	uint8_t *rcv_buf;
// 	uint16_t size_rcv;

// 	volatile uint8_t send_flag;  		/* 发送标志位 */
// 	Uart_Status_TypeDef send_status;  /* 发送状态 1：正在发送 busy，0：发送ok，*/
// 	Uart_Status_TypeDef status;  /* 发送状态 1：正在发送 busy，0：发送ok，*/

//     uint8_t command_seq ;      /* 命令序号 */
//     uint8_t mode;  /* 0 : normal , 1 : get wavelength ,  2 : get sn  */

//   uint8_t result_Buf[SC6_Rcv_Buf_Size];
//   uint8_t SC6_Data_Buf[SC6_Rcv_Buf_Size*2];
//   uint8_t SC6_Raw_Buf[SC6_Rcv_Buf_Size*3];

//   uint8_t *data_start_tag;
//   uint8_t *data_end_tag;

//   uint8_t start_cmd_valid ;
//   uint8_t stop_cmd_valid ;
//   uint8_t *start_cmd_buf;
//   uint8_t *stop_cmd_buf;

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



// 	uint32_t timebase;
// 	uint16_t timeout_ms;

// 	uint8_t (*Init)(void);			//初始化触摸屏控制器
// 	// uint8_t (*Setup)( );				//扫描触摸屏.0,屏幕扫描;1,物理坐标;	 
// 	uint8_t (*Port)( );				//扫描触摸屏.0,屏幕扫描;1,物理坐标;	 

// }SC6_TypeDef;