/****************************************************************************
*
* 文件名: usart_api.h
* 内容简述: 串口模块头文件。
*/

#ifndef __USART_API_H__
#define __USART_API_H__

#include "usart.h"
#include "datatypes.h"
//#include "adc.h"

extern u8 RollChar;// = 0x00; //串口接收到的有效转动字符，例如：R、r、U、u等
extern u8 RollChar_Flag;

#define PROTOCOL_DATA_MAX	(80)		//通信协议数据包最大长度
const static u8 RECV_HEAD[][10] = {"ABCDe:",""};

#if ARCH_MODE == ESP8266_Station_Mode || ARCH_MODE == CC254x_Slave_Mode
#define WifiATRespKeyWordColLen  20

//wifi AT指令返回响应结果
const static u8 WifiATRespKeyWord[][WifiATRespKeyWordColLen] = {
	//指令：AT+CWJAP="ssid","passwd"
#if ARCH_MODE == ESP8266_Station_Mode        
	"WIFI DISCONNECT",  	//当前路由器 连接成功
	"WIFI CONNECTED",  	//当前路由器 连接成功
	"WIFI GOT IP",  	//当前路由器 获取IP成功
	"FAIL",				//当前路由器 连接失败  路由器SSID或密码错误
	
	//指令：AT+CWJAP?
	"+CWJAP:",  	//当前路由器 连接成功
	"No AP",		//当前路由器 连接失败  路由器SSID或密码错误
	
	//指令：AT+CIFSR
	"+CIFSR:APIP,\"",
	"+CIFSR:APMAC,\"",
	"+CIFSR:STAIP,\"",
	"+CIFSR:STAMAC,\"",
	
	//指令：AT+CIPSTART=1,"UDP","192.168.10.104",3721
	",CONNECT",  			//TCP/UDP 连接成功
	"ALREADY CONNECTED",   	//重复连接 成功
	"Linked",			//TCP/UDP链接 连接成功
	"Link typ ERROR",		//TCP/UDP 链接类型参数错误
	//"ERROR",				//链接错误，通用，不做依据
	
	//指令：AT+CIPSEND=1,8    发送数据
	"ip error",  			//TCP/UDP 连接不成功会导致发送数据失败
	
	//指令：其他
	"CLOSED",			//当前链接断开
	//"busy p...", 		//wifi 正在执行上一条指令，忙碌 ，容易导致收发死循环，屏蔽
#endif	
	
	"MSF103C8",			//来自主控F103C8的自定义指令
	"MSF103R8",			//来自主控F103R8的自定义指令
	"ready",			//来自主控F103R8的自定义指令
};

typedef enum
{
	WIFI_STATUS_MIN=-1,
#if ARCH_MODE == ESP8266_Station_Mode        
	WIFI_STATUS_WIFI_DISCONNECT,
	WIFI_STATUS_WIFI_CONNECTED,
	WIFI_STATUS_WIFI_GOT_IP,
	WIFI_STATUS_WIFI_CONNECT_FAIL,
	
	WIFI_STATUS_CWJAP_OK,
	WIFI_STATUS_CWJAP_NO_AP,
	
	WIFI_STATUS_CIFSR_APIP,
	WIFI_STATUS_CIFSR_APMAC,
	WIFI_STATUS_CIFSR_STAIP,
	WIFI_STATUS_CIFSR_STAMAC,
	
	WIFI_STATUS_TCUDP_CONNECT,      
	WIFI_STATUS_TCUDP_ARD_CONNECTED,
	WIFI_STATUS_TCUDP_LINKED,       
	WIFI_STATUS_TCUDP_LINK_TYP_ERR, 
	
	WIFI_STATUS_CIP_SEND_IP_ERR,  
	
	WIFI_STATUS_CON_CLOSED,
#endif	
	WIFI_STATUS_MSF103C8_CMD,
	WIFI_STATUS_MSF103R8_CMD,
	WIFI_STATUS_READY,
	
	WIFI_STATUS_MAX
}WIFI_STATUS_ENUM;

#endif

#define sRollQueueMax  128
#if ARCH_MODE == ESP8266_Station_Mode
#define sAddrOfAppMax  16
#endif
typedef struct
{
#if ARCH_MODE == ESP8266_Station_Mode
	u8 sAddrOfApp[sAddrOfAppMax];
#endif
	u8 sRollQueue[sRollQueueMax];
	u16 cRollQueueHead;
	u16 cRollQueueTail;
}DATA_RECEIVE_VIA_NET_STRUCT;

typedef enum
{
	COM_RECV_FORMATE_TYPE_MIN=0,
	COM_RECV_FORMATE_TYPE_ESP,
	COM_RECV_FORMATE_TYPE_AT_STAIP,
	COM_RECV_FORMATE_TYPE_AT_STAMAC,
	COM_RECV_FORMATE_TYPE_AT_APIP,
	COM_RECV_FORMATE_TYPE_AT_APMAC,
	COM_RECV_FORMATE_TYPE_AT_CWJAP,
	COM_RECV_FORMATE_TYPE_MAX
}COM_RECV_FORMATE_TYPE_ENUM;

/***********************************************************************/
#define ROLL_DETECT_ITEM_MAX  		256		/*缓冲队列最大长度*/
typedef struct
{
	u16 time;		//u32 时间戳
	u8 side;		//转动面
	u16 angle;		//转动角度
}ROLL_DETECT_ITEM_STRUCT;	//转动检测项
	
typedef struct
{
	ROLL_DETECT_ITEM_STRUCT roll[ROLL_DETECT_ITEM_MAX];	//队列转动数据
	u16 head;		//队列头偏移量
	u16 tail;		//队列尾偏移量，写入时递增
}ROLL_DETECT_QUEUE_STRUCT;


/***********************************************************************/
#define iB2BEndMax    2		//板对板串口通讯结束符
#define iB2BDataMax   (PROTOCOL_DATA_MAX) 		//版地板通讯数据缓冲上限
typedef struct
{
	COM_NUM_ENUM com;
	u8  sB2BEnd[iB2BEndMax];
	u16 iB2BEndCnt;

	u8  sB2BData[iB2BDataMax];
	u16 iB2BDataLen;
	u16 iB2BDataCnt;
	
	u8 cB2BRxTemp;
}B2B_SERIAL_DATA_STRUCT;  	//板对板串口通讯数据结构

extern 	u16 RxCnt;
extern  B2B_SERIAL_DATA_STRUCT sd1;
extern  DATA_RECEIVE_VIA_NET_STRUCT ledRollQueue,ledShinePort,ledShinePin;


#define APIP_MAX  17
#define APMAC_MAX  24
#define STAIP_MAX  17
#define STAMAC_MAX  24
typedef struct
{
#if ARCH_MODE == ESP8266_Station_Mode || ARCH_MODE == CC254x_Slave_Mode
	WIFI_STATUS_ENUM prev_status; 	//上次链接状态
	WIFI_STATUS_ENUM status;		//最新链接状态
#endif	
	u8 APIP[APIP_MAX];		//station IP地址
	u16 APIP_LEN;				//station IP字符串长度
	u8 APMAC[APMAC_MAX];		//station MAC地址
	u16 APMAC_LEN; 			//station MAC字符串长度
	u8 STAIP[STAIP_MAX];		//station IP地址
	u16 STAIP_LEN;				//station IP字符串长度
	u8 STAMAC[STAMAC_MAX];		//station MAC地址
	u16 STAMAC_LEN; 			//station MAC字符串长度
}WIFI_INFO_STRUCT;

#define iDataBufMax  (PROTOCOL_DATA_MAX)		//网络数据长度

typedef struct
{
	u8 cCmdCode;			//命令码
	u16 iDataLenMax;		//sDataBuf中数据有效长度
	u8 sDataBuf[iDataBufMax];//网路数据暂存数组
}NET_DATA_STRUCT;

#if ARCH_MODE == CC254x_Slave_Mode
#define MSXX_CMD_MAX  16
typedef struct
{
	u8 MSXX_CMD[MSXX_CMD_MAX];   //主控板
	u16 MSXX_CMD_Len;  //
}MSXX_CMD_STRUCT;

#endif

/*********************************************************
*********************************************************/

extern u16 getStrLen(char *sDataBuf);
extern void clearCharBuf(char *buf, int ibuflen); //清空Char 数组所有成员数据为0x0
extern void clearUCharBuf(unsigned char *buf, int ibuflen); //清空Char 数组所有成员数据为0x0
#if ARCH_MODE == CC254x_Slave_Mode
void initMSXX_CMD_data(void); //初始化MSXX_CMD_STRUCT 成员
#endif
extern void initWifiInfo_data(void); //初始化WIFI_INFO_STRUCT wifi_info 成员

extern void RfSend(u16 Cmd,char *str,u16 istrlen);	 //
extern void SlvSend(u16 Cmd,char *str,u16 istrlen);	 //
extern u8 periodDetectComCycle(void);

extern uint16_t initSerialData(B2B_SERIAL_DATA_STRUCT *sd);
/*********************************************************
*********************************************************/
extern int process_app_data_buf(B2B_SERIAL_DATA_STRUCT *sd, u16 dataBegin);
#if ARCH_MODE == ESP8266_Station_Mode || ARCH_MODE == CC254x_Slave_Mode
#if PROTOCOL_DATA_SOURCE == PROTOCOL_DATA_SOURCE_UART
/*********************************************************
*********************************************************/
extern int process_wifi_data_buf(B2B_SERIAL_DATA_STRUCT *sd);

extern uint8_t COMB2BSerialCycleDetect(B2B_SERIAL_DATA_STRUCT *sd, u8 COMPort);
/**********************************************************
  通过wifi串口 App发送的应用数据 字符串协议解析程序
**********************************************************/
extern uint8_t COMWifiCmdCheckByte(u8 *cdata, u16 len);

#endif
#endif
/**********************************************************
	App发送的应用数据 字符串协议解析程序
**********************************************************/
extern uint8_t ProtocolCmdCheckByte(u8 *cdata);
/********************************************************
  BLE接收数据解析
********************************************************/
extern uint8_t BLECycleDetect(B2B_SERIAL_DATA_STRUCT *sd, uint8_t data);
/****************************************************
	检测BLE接收的数据协议
****************************************************/
extern u8 detectDataFromBLE(uint8_t *p_data, uint16_t length);

extern int parse_cmd_from_app(void);
extern uint8_t COMSerialRev(u8 COMPort);
extern uint8_t COMRevHexDisp(u8 COMPort);
extern uint8_t CheckComRcv(u8 COMPort);
extern void HexDisp(u16 Xpos,u16 Ypos,u16 SUM,u8 *ComRxBuf);

#if ARCH_MODE == CC254x_Slave_Mode

u8 process_MSF103R8_CMD(COM_NUM_ENUM com, MSXX_CMD_STRUCT *msCmd);
u8 ProAllPositionResAndUpload(COM_NUM_ENUM com, MSXX_CMD_STRUCT *msCmd);
extern void SeqNum_Convert_to_ColorSideSign(	u16 SeqNum,    //电阻全局编号  【1,48】
                                                u16 SeqNumGet  //电阻编号对应的颜色面符号【U,R,D,L,F,B】
                                                );

void initsAllColorBuf(void);
#endif
/**************************************************************
	上传所有面块电阻颜色首字母代号
**************************************************************/
#if ARCH_MODE == NRF52832_Slave_Mode
extern int send_all_res_directly(void);
#endif

extern void SendToMS(u8 *str);

//-----存放指示灯转动队列 循环队列-----
extern void InitRollQueue(DATA_RECEIVE_VIA_NET_STRUCT *dataStruct);
extern void ClearRollQueue(DATA_RECEIVE_VIA_NET_STRUCT *dataStruct);
extern u16 GetRollQueueLen(DATA_RECEIVE_VIA_NET_STRUCT *dataStruct);
extern u8 PutRollQueue(DATA_RECEIVE_VIA_NET_STRUCT *dataStruct, u8 *str, u8 strLen);
extern u8 GetRollQueue(DATA_RECEIVE_VIA_NET_STRUCT *dataStruct, u8 *chr);

/**************************************************************
	基于转动的应用检测执行
**************************************************************/
s8 rotation_based_app_process(u32 time, u8 side, u16 angle);

u8 SendRotationToAppByNum(u8 cmdCode, u32 time, u8 side, u16 angle);
u8 SendRotationToAppByStr(u8 cmdCode, u8 *cmd, u16 dataLen, u8 side, u8 sideOffset);
int UploadRotationData(u8 cmdCode);
int UploadRotationDataDirectly(u8 cmdCode);


//初始化队列
void InitRollDetQue(ROLL_DETECT_QUEUE_STRUCT *dataS);
//获取队列长度
u16 GetRollDetQueLen(ROLL_DETECT_QUEUE_STRUCT *dataS);
//写入一个数据到队列
u8 PutRollDetQue(ROLL_DETECT_QUEUE_STRUCT *dataS, u32 *time, u8 *side, u16 *angle, u8 dataLen);
//获取队列中队首一个成员，改变读head
u8 GetRollDetQue(ROLL_DETECT_QUEUE_STRUCT *dataS, u32 *time, u8 *side, u16 *angle);
//获取队列中所有成员，不改变读head
u8 GetRollDetQueAll(ROLL_DETECT_QUEUE_STRUCT *dataS, u32 *time, u8 *side, u16 *angle, u16 *dataLen);

#endif

//----------------------------------
