#ifndef EWDRIVER_H
#define EWDRIVER_H
#include "base/define.h"

#define EW_DMODE_FRAME_SIZE 136

#
typedef  enum {
	SINGLE_MOD = (uint8_t)0,
	DIFF_MOD   =  (uint8_t)1,
	OFF_MOD    =  (uint8_t)2,
} EWBus_Mod_en;


typedef enum{
	BEGIN_FRAME = (uint8_t)0,
	END_FRAME 	= (uint8_t)1,
	DATA_FRAME 	= (uint8_t)2,
	COMPLETE_FRAME = (uint8_t)3,
}EW_SINGLE_FRAME_TYPE_en;
#pragma pack(1)
//系统运行时配置
typedef union {
struct{
uint8_t fire_mos_sw 	  : 2;//起爆mos开关选择 0 内部 1 外部   （默认0）
uint8_t vbus_rx_sg		  : 2;//接收数据信号 1 vbuss_rxh 2 vbuss_rxl 3 vbusd_rx (默认 3)
uint8_t vbus_mode		    : 2;//通讯类型判断 01 差分 10 单端。00 11 根据总线电压判断 （默认 01）
uint8_t reserve01       : 2;//保留
uint8_t reset_run_step  : 3;//打点周期 0 不打点 1 5ms 2 10ms 3 20ms 4 50ms 5 100ms 6 150ms 7 200ms(默认 0)
uint8_t uid_len         : 3;//uid长度 uid_len + 7(默认 1)
uint8_t pwd_len         : 2;//密码长度 pwd_len + 4（默认0）
uint8_t version         : 5;//模块版本
uint8_t reserve02       : 3;//保留
uint8_t crc8			: 8;//校验位
} runcfg_st;
uint32_t run_param;
uint8_t  run_cfg_buf[4];
}RunCfg_un;

typedef union{
//系统状态标志结构体
volatile struct
{
	
  uint8_t timeramend_flag       : 1;        //时钟校准标志      0
  uint8_t saveinfo_flag         : 1;        //保存延时设置信息  1
  uint8_t pswd_flag             : 1;        //密码验证完成标志  2
  uint8_t delay_time            : 1;        //延时设置完成标志  3

  uint8_t addr_set              : 1;        //网络地址已设置
  uint8_t set_super_t           : 1;        //开启软件复位     5
  uint8_t erprom_error          : 1;        //系统存储错误     6
  uint8_t sys_error             : 1;        //系统运行异常 	  7

  
  uint8_t charge_8v             : 1;        //充电电压大于8V      8
  uint8_t charge_16V	        : 1;        //充电电压大于16V标志 9
  uint8_t charge_20v            : 1;        //充电电压大于20V     10
  uint8_t fireline_flag         : 1;         //桥丝检测         11


  uint8_t charge_ctrl_flag      : 1;        //充放电开关检测   12
  uint8_t mosfet_flag           : 1;        //MOS开关检测标志  13
  uint8_t charge_cmd            : 1;        //已经发送充电命令 14
  uint8_t fire_flag             : 1;        //已点火			  15


  uint8_t comm_frame            : 1;		//通讯帧结束标志
  uint8_t factory_check         : 1;        //工厂自检
  uint8_t comm_mode             : 1;        //通讯模式
  uint8_t vbusd_invert          : 1;        //VBUSD 的极性

 
  uint8_t comm_timeout          : 1;      //通信超时
  uint8_t reserve10             : 1;
  uint8_t reserve09             : 1;
  uint8_t reserve08             : 1;
  
  uint8_t reserve07             : 1;
  uint8_t reserve06             : 1;
  uint8_t reserve05             : 1;
  uint8_t reserve04             : 1;
  
  uint8_t reserve03             : 1;
  uint8_t reserve02             : 1;
  uint8_t reserve01             : 1;
  uint8_t reserve00             : 1;
} State_st;


	volatile uint32_t data;
	volatile uint16_t us_data[2];
	volatile uint8_t datas[4];
}System_State_un;

#pragma pack()

#define EW_WA_CFG_WRITE			 20 //写配置寄存器（掉电不保存）
#define EW_WA_SET_COMMADDR          21 //设置网络地址
#define EW_WA_FAST_CFG	             22 //快速配置地址，延时，密码验证
#define EW_WA_SET_DELAY			 23 //设置延时
#define EW_RA_VERIFY_PWD			 24 //密码验证
#define EW_W_ON_FIRE				 25 //起爆
#define EW_W_CHARGE                 26 //充电
#define EW_W_DISCHARGE              27 //放电
#define EW_RA_GET_STATE             28 //读状态
#define EW_W_AMEND  				 29 //时钟校准
#define EW_RA_INSPECT				 30 //巡检
#define EW_RA_CHECK_CFG       		 31 //配置区验证
#define EW_R_ELECT_TEST		     32 //电性能检测
#define EW_W_SAVE_FIRE_SET          33 //保存起爆测试
#define EW_RA_READ_DELAY       34 //读延时
#define EW_R_TX_CFG				     35 //反码配置
#define EW_WR_UPDATE_ADDR      36 //更新网络地址
#define EW_RA_AMEND_VALUE			 37 //读校准值
#define EW_RA_CFG_INFO				 38 //读配置信息
#define EW_W_AUTO_ADDR				 39 //自动分配地址
#define EW_EN_MTP				       40 //使失能MTP
#define EW_RA_UID              41 //读UID

#define EW_COMM_TEST				   60 //通信测试没问题
#define EW_BOOTLOADER_RUN      61 //运行bootloader
#define EW_RA_REGISTER				 62 //读MTP
#define EW_WA_REGISTER				 63 //写MTP


extern uint16_t EW_FreeBack_MaxCur,EW_FreeBack_MinCur;
extern uint16_t EW_FreeBack_MaxTime,EW_FreeBack_MinTime;

//通信监控变量初始化
void EW_FreeBack_Prapare(void);

/*
@brief 发送校准脉冲
@param cycle 周期
@param duty 总线高电平时间
@param count 脉冲个数

*/
void EW_SendTrimSquare(uint16_t cycle,uint16_t duty,  uint32_t count);


/*
@brief 差分模式读取为应答
@param count 读取的数量
@param 接收数据缓存
*/
void DMod_ReadInspect_Data(uint16_t count,uint8_t* buf);

/*
@brief 单端第二版，差分接收数据
@param *buf 数据缓存指针
@param len 读取数据长度
@param time_out 超时脉冲数（约1bit数据时间）
@rtv 0 成功 否则失败
*/
uint8_t DMod_FireBusReadDatasV2(uint8_t* buf, uint8_t len, uint32_t time_out);

/*
@brief 差分模式数据发送
@param buf 发送数据缓存
@param len 发送长度
@param pre 数据脉冲周期

*/
void DMod_SendBytes(uint8_t* buf, uint8_t len, uint16_t pre,uint8_t rw_flag);
void DMod_SendBytesXor(uint8_t* buf, uint8_t len, uint8_t rw_flag);
uint8_t DMod_ReadBytesXor(uint8_t* buf, uint8_t len,uint16_t retry_times);

/*
@breif 通信测试
*/
uint8_t EW_CommTest(uint8_t* buf,uint16_t len,uint16_t cycle);
/*
@brief 使能MTP写
@param addr 通信地址
@param 使能开关
@rtv 执行结果
*/
uint8_t EW_EnWriteMTP(uint16_t addr ,uint8_t en_flag);
/*
@brief 读MTP
@param addr 通信地址
@param mtpaddr MTP地址/4
@param buf 写入数据的缓存
@param len 数据长度
*/
uint8_t EW_WriteMTP(uint16_t addr,uint8_t mtpaddr,uint8_t* buf,uint8_t len);
/*
@brief 读MTP
@param addr 通信地址
@param mtpaddr MTP地址/4
@param buf 读出数据的缓存
@param len 数据长度
*/
uint8_t EW_ReadMTP(uint16_t addr,uint8_t mtpaddr,uint8_t* buf,uint8_t len);
/*
@brief 运行BootLoader程序
@param addr 通信地址
@param reboot 仅重启标准 1 有效
@rtv 返回执行结果 0 成功
*/
uint8_t EW_RunBootLoader(uint16_t addr,uint8_t reboot);
/*
@brief 写运行配置，写入MTP中
@param  addr 通信地址
@param 	runcfg 配置结构体
@rtv    返回执行结果
*/
uint8_t EW_WriteRunCfg(uint16_t addr,RunCfg_un* runcfg);
/*
@brief  快速分配通信地址
@param  通信地址
@param 	UID
@param  uid_len UID长度
@param ack_data 应答数据 包括2bytes延时和2bytes状态
@rtv    执行结果
*/

uint8_t EW_SetAddrByUID(uint16_t addr,uint8_t* uid,uint8_t uid_len);
/*
@brief  快速分配通信地址
@param  通信地址
@param  设置延时 
@param 	UID
@param  UID长度
@param  应答数据 包括2bytes延时和2bytes状态
@rtv    执行结果
*/

uint8_t EW_FastSetByUID(uint16_t addr,uint16_t delay,uint8_t* uid,uint8_t uid_len,uint8_t* ack_data);
/*
@brief 设置延时
@param  addr 通信地址
@param 	延期时间
@rtv    返回执行结果
*/
uint8_t EW_SetDelay(uint16_t addr,uint16_t delay);
/*
@brief  密码验证
@param  addr 通信地址
@param 	密码数据
@param  密码长度
@rtv    返回执行结果
*/
uint8_t EW_VerfyPWD(uint16_t addr,uint8_t* pwd,uint8_t pwd_len);
/*
@brief  密码验证
@param  addr 通信地址
@param 	延迟起爆时间*50ms
@rtv    返回执行结果
*/
uint8_t EW_Boom(uint16_t addr,uint8_t delay_count);
/*
@brief  分组充电
@param  addr 通信地址
@param 	充电挡位 0：直通 1 ：16V 2:20V 3：2.5V
@param  分组挡位 addr = group*4  大于addr的可以充电
@rtv    返回执行结果
*/
uint8_t EW_Charge(uint16_t addr,uint8_t chg_class,uint8_t group);
/*
@brief  放电
@param  addr 通信地址
*/
uint8_t EW_DisCharge(uint16_t addr);
/*
@brief 读状态信息
@param addr 通信地址
@param *delay 返回延时数据
@param *state 返回状态码
@param len 数据长度
*/
uint8_t EW_ReadState(uint16_t addr,uint8_t* state);
/*
@brief  校准地址
@param  addr 通信地址
@param  cycle 校准周期 us
@param  plus_count 脉冲个数
*/
uint8_t EW_ClkAmend(uint16_t addr ,uint16_t cycle,uint16_t plus_count);
/*
@brief  巡检
@param  addr 通信地址
@param  cycle 校准周期 us
@param  plus_count 脉冲个数
*/
uint8_t EW_Inspect(uint16_t bgaddr ,uint16_t endaddr,uint16_t state,uint8_t* buf);
/*
@brief  配置验证
@param  addr 通信地址
@param  cfg_mask 源掩码信息
@param  比较信息 (EW_Cfg & cfg_mask) == cfg_state 
@param  反码状态 0 比较通过不反码 1 比较通过反码
@param  
*/
uint8_t EW_CheckRunCfg(uint16_t addr,uint32_t cfg_mask ,uint32_t cfg_state,uint8_t* rtv);
/*
@brief  配置验证
@param  addr 通信地址
@param  check_class 检测模式 0 基本自检 1 起爆开关检测 2 电容检测 4 读电容检测时间
@param  *buf 读出测试结果
*/
uint8_t EW_ChecSelf(uint16_t addr,uint8_t check_class,uint8_t* buf);
/*
@brief  保持起爆配置信息和使能起爆
*/
uint8_t EW_SaveFireInfo(uint16_t addr);
/*
@brief  读延时和状态值
@param addr 通信地址
@param delay 返回延时
*/
uint8_t EW_ReadDelay(uint16_t addr,uint16_t* delay);
/*
@brief  通信反码配置
@param addr 通信地址
@param speed 通信挡位 0:10K 1:7K  2:5K 3:4.5K 4: 4K 4+n:4-0.5*n 
@param cur 电流挡位 0：1mA 1:2mA 2:4mA 3:8mA
*/
uint8_t EW_SetReportCfg(uint8_t speed,uint8_t cur);
/*
@brief 更新网络地址
@param addr 通信地址
@param new_addr 新地址
*/
uint8_t EW_UpdateCommAddr(uint8_t addr,uint16_t new_addr);
/*
@brief  读校准值
@param addr 通信地址
@param clk_amend 校准信息
*/
uint8_t EW_ReadClkAmend(uint16_t addr,uint32_t* clk_amend);
/*
@brief  读校准值
@param addr 通信地址
@param clk_amend 校准信息
*/
uint8_t EW_ReadRunCfgVersion(uint16_t addr,uint8_t* run_cfg,uint16_t* version);
/*
@brief  自动分配地址
@param  max_addr 分配的最大地址
@param  fac_addr 分配因子
*/
uint8_t EW_AutoSetAddr(uint16_t max_addr,uint16_t fac_addr);
/*
@brief  读校准值
@param addr 通信地址
@param UID数据
*/
uint8_t EW_ReadUID(uint16_t addr,uint8_t* uid,uint8_t uid_len);
/*******************************************************************************************/
/*
@brief 充放电控制
@param chg_flag 充电控制开关 1 充电 0 放电
@rtv 0 执行成功 1失败
*/
uint8_t EWB_ChgCtrl(uint8_t chg_flag);
/*
@brief 擦除指定空间
@param 起始地址
@param 结束地址
@rtv   返回值 0 成功 1 失败
*/
uint8_t EWB_EraseMTP(uint16_t bgaddr,uint16_t endaddr);
/*
@brief 擦除代码空间
@rtv   返回值 0 成功 1 失败
*/
uint8_t EWB_EraseCode(void);
/*
@breif 获取Crc32
@param 起始地址
@param 结束地址
@param *rt_crc32存储区域
@rtv   返回值 0 成功 1 失败
*/
uint8_t EWB_CacluCrc32(uint16_t bgaddr,uint16_t endaddr, uint32_t* rt_crc32);
/*
@brief 读取MTP数据
@param 起始地址
@param 读取长度
@param *read_buf 读取数据缓存
@rtv   返回值 0 成功 1 失败
*/
uint8_t EWB_ReadMTP(uint16_t bgaddr,uint8_t read_len, uint8_t* read_buf);
/*
brief 强制跳转用户区
@rtv 返回值 0 成功 1 失败
*/
uint8_t EWB_RunApp(void);
/*
@brief 擦除指定空间
@param 起始地址
@param 写入数据缓存
@param 写入数据长度
@rtv   返回值 0 成功 1 失败
*/
uint8_t EWB_WriteMTP(uint16_t bgaddr,const uint8_t* w_buf,uint8_t len);
#endif 
