/*************************** (C) COPYRIGHT 2017 CXHY ****************************
 * 文件名  pc_protocol.c
 * 描  述  ：上位机协议处理程序
 * 版  本  ：V1.0
 * 作  者  ：XuZhongPing
 * 日  期  ：2017/03/16 
*********************************************************************************/
#include "pc_protocol.h"
#include "delay.h"
#include "timer.h"
#include "usart1.h"
#include "usart3.h"
#include "string.h"
#include "stdlib.h"  
#include "data_typedef.h"
#include "device.h"
#include "gsm_uart_conf.h"
#include "gsm_gprs.h"

uint8_t PC_PRO_RX_BUF[PC_PRO_RECV_LEN];     	//接收缓冲
uint8_t PC_PRO_TX_BUF[PC_PRO_SEND_LEN];				//发送缓冲


static void PC_ProCommandRun(uint8_t *pRxBuf, uint8_t *pTxBuf);

/*
***********************************************************************
*	函 数 名: show
*	功能说明: 以十六进制显示数组里的内容
*	形    参:	无
*	返 回 值: 无
***********************************************************************
*/
void showHex(uint8_t num[], uint8_t n)
{
    uint8_t i;
		printf("\r\n");
    for(i=0; i<n; i++)
		{
      printf("%02X ",num[i]);
		}
		printf("\r\n");
}

/*
***********************************************************************
*	函 数 名: PC_ProDataPackingAndSend
*	功能说明: 上下位机通信数据打包及发送
*	形    参:	*pdata -> 需要打包的数据地址，dataLen -> 数据长度
*	返 回 值: 无
***********************************************************************
*/
void PC_ProDataPackingAndSend(uint8_t *pdata, uint16_t dataLen)
{
	uint16_t i;
	uint8_t CS = 0;
	uint16_t TX_Size = 0;
	
	uint8_t tempSendDataBuf[256];
	uint16_t dataAddrIndex = 0;
	
	tempSendDataBuf[dataAddrIndex++] = 0xFE; 				//发送前导字节
	tempSendDataBuf[dataAddrIndex++] = 0xFE; 			
	tempSendDataBuf[dataAddrIndex++] = 0xFE; 
	
	tempSendDataBuf[dataAddrIndex++] = 0x68; 				//发送帧头
	CS += 0x68;
	
	tempSendDataBuf[dataAddrIndex++] = *(pdata+0); 	//发送地址
	CS += *pdata;
	
	tempSendDataBuf[dataAddrIndex++] = 0x68; 				//发送帧头
	CS += 0x68;
	
	tempSendDataBuf[dataAddrIndex++] = *(pdata+1); 	//发送帧命令
	CS += *(pdata+1);
	
	tempSendDataBuf[dataAddrIndex++] = *(pdata+2); 	//发送数据长度（高8位）
	CS += *(pdata+2);
	tempSendDataBuf[dataAddrIndex++] = *(pdata+3); 	//发送数据长度（低8位）
	CS += *(pdata+3);
	
	TX_Size = (*(pdata+2) << 8) | (*(pdata+3));			//取出通讯数据长度
	for(i=0; i<TX_Size; i++) 												//加载发送数据
	{
		tempSendDataBuf[dataAddrIndex++] = *(pdata+4+i);
		CS += (*(pdata+4+i));
	}
	tempSendDataBuf[dataAddrIndex++] = CS; 					//发送校验字节
	tempSendDataBuf[dataAddrIndex++] = 0x16;
	
// 	showHex(sendDataBuf, dataAddrIndex);

	USART4_SendFrameData(tempSendDataBuf, dataAddrIndex);
}

/*
***********************************************************************
*	函 数 名: PC_ProCommandRun
*	功能说明: 上下位机通讯命令执行
*	形    参:	*pRxBuf -> 接收缓存的地址，*pTxBuf -> 发送数据缓存地址 
*	返 回 值: 无
***********************************************************************
*/
static void PC_ProCommandRun(uint8_t *pRxBuf, uint8_t *pTxBuf)
{
	uint8_t pc_proNum = 0;
	uint16_t temp16BitData = 0;
	
	pc_proNum = *(pRxBuf+1);
	
	printf("\r\nPC <-- 0x%02X\r\n", pc_proNum);
	switch(pc_proNum)														//通讯命令译码
	{
		case 0x01:
			break;
		
		case 0x02:		//打开投口指令
			openDoorNumber = *(pRxBuf+5);
			if(openDoorNumber == 0)
			{
				openDoorNumber = 255;
				rspPCDoorNumber = 255;
				if((fullMark1 == 0) || (fullMark2 == 0) ||
					 (fullMark3 == 0) || (fullMark4 == 0))
				{
					pcRequestOpenDoorMark = 1;
				}
			}else{
				rspPCDoorNumber = openDoorNumber;
				
				switch(openDoorNumber)
				{
					case 1:
						if(fullMark1 == 0)								//当此通道没有装满才可以打开
						{
							pcRequestOpenDoorMark = 1;
						}
						break;
						
					case 2:
						if(fullMark2 == 0)								//当此通道没有装满才可以打开
						{
							pcRequestOpenDoorMark = 1;
						}
						break;

					case 3:
						if(fullMark3 == 0)
						{
							pcRequestOpenDoorMark = 1;
						}
						break;

					case 4:
						if(fullMark4 == 0)
						{
							pcRequestOpenDoorMark = 1;
						}
						break;
						
						
					default:
						break;
				}
			}
			
			PC_ProCommandSend(pc_proNum);
// 			printf("\r\n收到上位机应答指令0x02\r\n");
			break;
			
		case 0x03:		//关闭投口指令
			pcRequestClooseDoorMark = 1;
			PC_ProCommandSend(pc_proNum);
// 			printf("\r\n收到上位机应答指令0x02\r\n");
			break;
			
		case 0x04:		//打开收运锁指令
// 			openDoorNumber = *(pRxBuf+5);
// 			if(openDoorNumber == 0)
// 			{
// 				openDoorNumber = 255;
// 				rspPCDoorNumber = 255;
// 			}else{
// 				rspPCDoorNumber = openDoorNumber;
// 			}
			
			boxOpenMark = 1;
			PC_ProCommandSend(pc_proNum);
			break;
			
		case 0x20:		//重量查询指令
			rspPCWeightNumber = *(pRxBuf+5);
			if(rspPCWeightNumber == 0)
			{
				rspPCWeightNumber = 255;
			}
			
			PC_ProCommandSend(pc_proNum);
			break;
			
		case 0x21:		//满溢状态查询
			rspPCDistanceNumber = *(pRxBuf+5);
			if(rspPCDistanceNumber == 0)
			{
				rspPCDistanceNumber = 255;
			}
			
			PC_ProCommandSend(pc_proNum);
			break;
			
		case 0x22:		//温度查询指令
			rspPCTemperatureNumber = *(pRxBuf+5);
			if(rspPCTemperatureNumber == 0)
			{
				rspPCTemperatureNumber = 255;
			}
			
			PC_ProCommandSend(pc_proNum);
			break;
			
		case 0x23:		//收运门关闭状态查询指令
			PC_ProCommandSend(pc_proNum);
			break;
			
		case 0x30:		//获取下位机软件版本号指令
			PC_ProCommandSend(pc_proNum);
			break;
			
		case 0x31:		//获取IMEI号指令
			PC_ProCommandSend(pc_proNum);
			break;
			
		case 0x91:		//设备时间同步
			timestamp_s = *(pRxBuf+5) << 24;
			timestamp_s |= *(pRxBuf+6) << 16;
			timestamp_s |= *(pRxBuf+7) << 8;
			timestamp_s |= *(pRxBuf+8);
			getDateTimeMark = 1;
			break;
			
		case 0x92:		//上位机设备状态同步
			temp16BitData |= *(pRxBuf+5) << 8;
			temp16BitData |= *(pRxBuf+6);
			
			switch(temp16BitData)
			{
				case 0x0001:
					netStatus = *(pRxBuf+7) << 8;
					netStatus |= *(pRxBuf+8);
					break;
					
				case 0x0002:
					devRunnigStatus = *(pRxBuf+7) << 8;
					devRunnigStatus |= *(pRxBuf+8);
					break;
					
				default:
					break;
			}
			break;
			
		default: 			//其他命令
			break;
	}
}

/*
***********************************************************************
*	函 数 名: PC_ProDataPacking
*	功能说明: 下位机向上位机发送数据打包
*	形    参:	protocolNo -> 协议号
*	返 回 值: 无
***********************************************************************
*/
void PC_ProDataPacking(uint8_t protocolNo)
{
	uint16_t dataAddr = 0;														//发送的数据坐标索引					

	uint32_t temp = 0;
	uint16_t len = 0;
	
	uint16_t tmpeData = 0;
	uint8_t tempData1 = 0;
	uint8_t tempAddr = 0;
	uint8_t dataCunt = 0;
	
	PC_PRO_TX_BUF[dataAddr++] = 0x00; 												//设置从机通讯地址
	PC_PRO_TX_BUF[dataAddr++] = protocolNo;										//存入命令码
	
	PC_PRO_TX_BUF[dataAddr++] = 0x00;													//发送的数据长度（数据加载完成后输入）
	PC_PRO_TX_BUF[dataAddr++] = 0x00;
	
	printf("\r\nPC --> 0x%02X\r\n", protocolNo);
	
	switch(protocolNo)
	{
		case 0x01:		//用户身份识别
			PC_PRO_TX_BUF[dataAddr++] = 0x01;												//协议版本号
			
			PC_PRO_TX_BUF[dataAddr++] = sendPutInType;							//识别方式
			PC_PRO_TX_BUF[dataAddr++] = sendDataLength;							//内容长度
			memcpy(&PC_PRO_TX_BUF[dataAddr], sendDataBuf, sendDataLength);		//身份内容
			dataAddr += sendDataLength;
			break;
			
		case 0x02:		//上位机请求打开投口回应
			PC_PRO_TX_BUF[dataAddr++] = 0x01;												//协议版本号
			
			if(rspPCDoorNumber == 255)
			{
				PC_PRO_TX_BUF[dataAddr++] = 4;													//投口数量
				
				PC_PRO_TX_BUF[dataAddr++] = 1;													//投口1
				PC_PRO_TX_BUF[dataAddr++] = fullMark1;									//当前箱体状态
				
				PC_PRO_TX_BUF[dataAddr++] = 2;													//投口2
				PC_PRO_TX_BUF[dataAddr++] = fullMark2;									//当前箱体状态
				
				PC_PRO_TX_BUF[dataAddr++] = 3;													//投口3
				PC_PRO_TX_BUF[dataAddr++] = fullMark3;									//当前箱体状态
				
				PC_PRO_TX_BUF[dataAddr++] = 4;													//投口4
				PC_PRO_TX_BUF[dataAddr++] = fullMark4;									//当前箱体状态
				
			}else{
				PC_PRO_TX_BUF[dataAddr++] = 1;													//投口数量
				PC_PRO_TX_BUF[dataAddr++] = rspPCDoorNumber;
				switch(rspPCDoorNumber)
				{
					case 1:
						PC_PRO_TX_BUF[dataAddr++] = fullMark1;							//当前箱体状态
						break;
						
					case 2:
						PC_PRO_TX_BUF[dataAddr++] = fullMark2;
						break;

					case 3:
						PC_PRO_TX_BUF[dataAddr++] = fullMark3;
						break;

					case 4:
						PC_PRO_TX_BUF[dataAddr++] = fullMark4;
						break;
						
					default:
						PC_PRO_TX_BUF[dataAddr++] = 0x00;
						break;
				}									
			}
			break;
			
		case 0x03:
			PC_PRO_TX_BUF[dataAddr++] = 0x01;												//协议版本号
			break;
			
		case 0x04:		//上位机请求打开收运门回应
			PC_PRO_TX_BUF[dataAddr++] = 0x01;												//协议版本号
			
			PC_PRO_TX_BUF[dataAddr++] = 1;													//收运门数量
			PC_PRO_TX_BUF[dataAddr++] = 1;
			PC_PRO_TX_BUF[dataAddr++] = 0x00;												//当前箱体状态
			break;
			
		case 0x08:
			break;
			
		case 0x09:
			break;
			
		case 0x20:		//上位机请求当前秤盘重量回应
//			模拟测试数据
// 			weight1 = 0x1234;
// 			weight2 = 0x2345;
// 			weight3 = 0x3456;
// 			weight4 = 0x4567;
			
			PC_PRO_TX_BUF[dataAddr++] = 0x01;												//协议版本号
			
			switch(rspPCWeightNumber)
			{
				case 1:
					PC_PRO_TX_BUF[dataAddr++] = 1;													//投口数量
					PC_PRO_TX_BUF[dataAddr++] = rspPCWeightNumber;
					PC_PRO_TX_BUF[dataAddr++] = weight1 >> 8;								//当前重量
					PC_PRO_TX_BUF[dataAddr++] = weight1;
					break;
					
				case 2:
					PC_PRO_TX_BUF[dataAddr++] = 1;													//投口数量
					PC_PRO_TX_BUF[dataAddr++] = rspPCWeightNumber;
					PC_PRO_TX_BUF[dataAddr++] = weight2 >> 8;								//当前重量
					PC_PRO_TX_BUF[dataAddr++] = weight2;
					break;
					
				case 3:
					PC_PRO_TX_BUF[dataAddr++] = 1;													//投口数量
					PC_PRO_TX_BUF[dataAddr++] = rspPCWeightNumber;
					PC_PRO_TX_BUF[dataAddr++] = weight3 >> 8;								//当前重量
					PC_PRO_TX_BUF[dataAddr++] = weight3;
					break;
					
				case 4:
					PC_PRO_TX_BUF[dataAddr++] = 1;													//投口数量
					PC_PRO_TX_BUF[dataAddr++] = rspPCWeightNumber;
					PC_PRO_TX_BUF[dataAddr++] = weight4 >> 8;								//当前重量
					PC_PRO_TX_BUF[dataAddr++] = weight4;
					break;
					
				case 255:
					PC_PRO_TX_BUF[dataAddr++] = 4;													//投口数量
					
					PC_PRO_TX_BUF[dataAddr++] = 1;													//投口1
					PC_PRO_TX_BUF[dataAddr++] = weight1 >> 8;								//当前重量
					PC_PRO_TX_BUF[dataAddr++] = weight1;
					
					PC_PRO_TX_BUF[dataAddr++] = 2;													//投口2
					PC_PRO_TX_BUF[dataAddr++] = weight2 >> 8;								//当前重量
					PC_PRO_TX_BUF[dataAddr++] = weight2;
					
					PC_PRO_TX_BUF[dataAddr++] = 3;													//投口3
					PC_PRO_TX_BUF[dataAddr++] = weight3 >> 8;								//当前重量
					PC_PRO_TX_BUF[dataAddr++] = weight3;
					
					PC_PRO_TX_BUF[dataAddr++] = 4;													//投口4
					PC_PRO_TX_BUF[dataAddr++] = weight4 >> 8;								//当前重量
					PC_PRO_TX_BUF[dataAddr++] = weight4;
					break;
					
				default:
					break;
			}
			break;
			
		case 0x21:		//上位机请求当前满溢状态回应
//			模拟测试数据
// 			getDistance1 = 0x15;
// 			getDistance2 = 0x25;
// 			getDistance3 = 0x35;
// 			getDistance4 = 0x45;
			
			PC_PRO_TX_BUF[dataAddr++] = 0x01;												//协议版本号
			
			switch(rspPCDistanceNumber)
			{
				case 1:
					PC_PRO_TX_BUF[dataAddr++] = 1;													//投口数量
					PC_PRO_TX_BUF[dataAddr++] = rspPCDistanceNumber;
					PC_PRO_TX_BUF[dataAddr++] = outputDistance1;								//当前测距值
					break;
					
				case 2:
					PC_PRO_TX_BUF[dataAddr++] = 1;													//投口数量
					PC_PRO_TX_BUF[dataAddr++] = rspPCDistanceNumber;
					PC_PRO_TX_BUF[dataAddr++] = outputDistance2;								//当前测距值
					break;
					
				case 3:
					PC_PRO_TX_BUF[dataAddr++] = 1;													//投口数量
					PC_PRO_TX_BUF[dataAddr++] = rspPCDistanceNumber;
					PC_PRO_TX_BUF[dataAddr++] = outputDistance3;							//当前测距值
					break;
					
				case 4:
					PC_PRO_TX_BUF[dataAddr++] = 1;													//投口数量
					PC_PRO_TX_BUF[dataAddr++] = rspPCDistanceNumber;
					PC_PRO_TX_BUF[dataAddr++] = outputDistance4;							//当前测距值
					break;
					
				case 255:
					PC_PRO_TX_BUF[dataAddr++] = 4;													//投口数量
					
					PC_PRO_TX_BUF[dataAddr++] = 1;													//投口1
					PC_PRO_TX_BUF[dataAddr++] = outputDistance1;								//当前测距值
					
					PC_PRO_TX_BUF[dataAddr++] = 2;													//投口2
					PC_PRO_TX_BUF[dataAddr++] = outputDistance2;								//当前测距值
					
					PC_PRO_TX_BUF[dataAddr++] = 3;													//投口3
					PC_PRO_TX_BUF[dataAddr++] = outputDistance3;							//当前测距值
					
					PC_PRO_TX_BUF[dataAddr++] = 4;													//投口4
					PC_PRO_TX_BUF[dataAddr++] = outputDistance4;							//当前测距值
					break;
					
				default:
					break;
			}
			break;
			
		case 0x22:		//上位机请求当前温度值回应			
			PC_PRO_TX_BUF[dataAddr++] = 0x01;												//协议版本号
			switch(rspPCTemperatureNumber)
			{
				case 1:
					PC_PRO_TX_BUF[dataAddr++] = 1;													//投口数量
					PC_PRO_TX_BUF[dataAddr++] = rspPCTemperatureNumber;
					PC_PRO_TX_BUF[dataAddr++] = 0x00;												//温度符号
					tmpeData = temperature*10;															//上传数据放大10倍
					PC_PRO_TX_BUF[dataAddr++] = tmpeData >> 8;							//温度高8位
					PC_PRO_TX_BUF[dataAddr++] = tmpeData;										//温度低8位
					break;
					
				case 2:
					PC_PRO_TX_BUF[dataAddr++] = 1;													//投口数量
					PC_PRO_TX_BUF[dataAddr++] = rspPCTemperatureNumber;
					PC_PRO_TX_BUF[dataAddr++] = 0x00;												//温度符号
					tmpeData = temperature*10;															//上传数据放大10倍
					PC_PRO_TX_BUF[dataAddr++] = tmpeData >> 8;							//温度高8位
					PC_PRO_TX_BUF[dataAddr++] = tmpeData;										//温度低8位
					break;
					
				case 3:
					PC_PRO_TX_BUF[dataAddr++] = 1;													//投口数量
					PC_PRO_TX_BUF[dataAddr++] = rspPCTemperatureNumber;
					PC_PRO_TX_BUF[dataAddr++] = 0x00;												//温度符号
					tmpeData = temperature*10;															//上传数据放大10倍
					PC_PRO_TX_BUF[dataAddr++] = tmpeData >> 8;							//温度高8位
					PC_PRO_TX_BUF[dataAddr++] = tmpeData;										//温度低8位
					break;
					
				case 4:
					PC_PRO_TX_BUF[dataAddr++] = 1;													//投口数量
					PC_PRO_TX_BUF[dataAddr++] = rspPCTemperatureNumber;
					PC_PRO_TX_BUF[dataAddr++] = 0x00;												//温度符号
					tmpeData = temperature*10;															//上传数据放大10倍
					PC_PRO_TX_BUF[dataAddr++] = tmpeData >> 8;							//温度高8位
					PC_PRO_TX_BUF[dataAddr++] = tmpeData;										//温度低8位
					break;
					
				case 255:
					PC_PRO_TX_BUF[dataAddr++] = 4;													//投口数量
					
					PC_PRO_TX_BUF[dataAddr++] = 1;													//投口1
					PC_PRO_TX_BUF[dataAddr++] = 0x00;												//温度符号
					tmpeData = temperature*10;															//上传数据放大10倍
					PC_PRO_TX_BUF[dataAddr++] = tmpeData >> 8;							//温度高8位
					PC_PRO_TX_BUF[dataAddr++] = tmpeData;										//温度低8位
					
					PC_PRO_TX_BUF[dataAddr++] = 2;													//投口2
					PC_PRO_TX_BUF[dataAddr++] = 0x00;												//温度符号
					tmpeData = temperature*10;															//上传数据放大10倍
					PC_PRO_TX_BUF[dataAddr++] = tmpeData >> 8;							//温度高8位
					PC_PRO_TX_BUF[dataAddr++] = tmpeData;										//温度低8位
					
					PC_PRO_TX_BUF[dataAddr++] = 3;													//投口3
					PC_PRO_TX_BUF[dataAddr++] = 0x00;												//温度符号
					tmpeData = temperature*10;															//上传数据放大10倍
					PC_PRO_TX_BUF[dataAddr++] = tmpeData >> 8;							//温度高8位
					PC_PRO_TX_BUF[dataAddr++] = tmpeData;										//温度低8位
					
					PC_PRO_TX_BUF[dataAddr++] = 4;													//投口4
					PC_PRO_TX_BUF[dataAddr++] = 0x00;												//温度符号
					tmpeData = temperature*10;															//上传数据放大10倍
					PC_PRO_TX_BUF[dataAddr++] = tmpeData >> 8;							//温度高8位
					PC_PRO_TX_BUF[dataAddr++] = tmpeData;										//温度低8位
					break;
					
				default:
					break;
			}
			break;
			
		case 0x23:		//收运门状态输出
			PC_PRO_TX_BUF[dataAddr++] = 0x01;												//协议版本号
			
			PC_PRO_TX_BUF[dataAddr++] = 0x01;												//投口数量
			
			PC_PRO_TX_BUF[dataAddr++] = 1;													//投口编号
			PC_PRO_TX_BUF[dataAddr++] = recycleClearDoorMark;				//收运门状态
			break;
			
		case 0x30:		//获取下位机软件版本号
			PC_PRO_TX_BUF[dataAddr++] = 0x01;												//协议版本号
			len = strlen(VersionNumber);
			PC_PRO_TX_BUF[dataAddr++] = len;												//软件版本号长度
			memcpy(&PC_PRO_TX_BUF[dataAddr], VersionNumber, len);
			dataAddr += len;
			break;
			
		case 0x31:		//获取IMEI号
			PC_PRO_TX_BUF[dataAddr++] = 0x01;												//协议版本号
			PC_PRO_TX_BUF[dataAddr++] = 15;													//IMEI号长度
			memcpy(&PC_PRO_TX_BUF[dataAddr], gsm_msg.IMEI, 15);
			dataAddr += 15;
			break;
			
		case 0x60:		//关门倒计时显示
			PC_PRO_TX_BUF[dataAddr++] = 0x01;												//协议版本号
			PC_PRO_TX_BUF[dataAddr++] = remainingTimer;	
			break;
			
		case 0x61:		//投放数据上传
			PC_PRO_TX_BUF[dataAddr++] = 0x01;												//协议版本号
			switch(deviceType)
			{
				case DOUBLE_CLASSIFICATION:		//两分类
					PC_PRO_TX_BUF[dataAddr++] = 2;											//数据量
					
					//第1组数据
					PC_PRO_TX_BUF[dataAddr++] = 1;											//投品编号
					
					PC_PRO_TX_BUF[dataAddr++] = getWeight1 >> 8;				//本次投放重量
					PC_PRO_TX_BUF[dataAddr++] = getWeight1;
					
					PC_PRO_TX_BUF[dataAddr++] = getWeightBefore1 >> 8;	//投放前重量
					PC_PRO_TX_BUF[dataAddr++] = getWeightBefore1;
					
					PC_PRO_TX_BUF[dataAddr++] = getWeightAfter1 >> 8;		//投放后重量
					PC_PRO_TX_BUF[dataAddr++] = getWeightAfter1;
					
					PC_PRO_TX_BUF[dataAddr++] = outputDistance1;						//测距值
					
					//第2组数据
					PC_PRO_TX_BUF[dataAddr++] = 2;											//投品编号
					
					PC_PRO_TX_BUF[dataAddr++] = getWeight2 >> 8;				//本次投放重量
					PC_PRO_TX_BUF[dataAddr++] = getWeight2;
					
					PC_PRO_TX_BUF[dataAddr++] = getWeightBefore2 >> 8;	//投放前重量
					PC_PRO_TX_BUF[dataAddr++] = getWeightBefore2;
					
					PC_PRO_TX_BUF[dataAddr++] = getWeightAfter2 >> 8;		//投放后重量
					PC_PRO_TX_BUF[dataAddr++] = getWeightAfter2;
					
					PC_PRO_TX_BUF[dataAddr++] = outputDistance2;						//测距值
					break;

				case FOUR_CLASSIFICATION:
					PC_PRO_TX_BUF[dataAddr++] = 4;

					PC_PRO_TX_BUF[dataAddr++] = 1;
					PC_PRO_TX_BUF[dataAddr++] = getWeight1 >> 8;
					PC_PRO_TX_BUF[dataAddr++] = getWeight1;
					PC_PRO_TX_BUF[dataAddr++] = getWeightBefore1 >> 8;
					PC_PRO_TX_BUF[dataAddr++] = getWeightBefore1;
					PC_PRO_TX_BUF[dataAddr++] = getWeightAfter1 >> 8;
					PC_PRO_TX_BUF[dataAddr++] = getWeightAfter1;
					PC_PRO_TX_BUF[dataAddr++] = outputDistance1;

					PC_PRO_TX_BUF[dataAddr++] = 2;
					PC_PRO_TX_BUF[dataAddr++] = getWeight2 >> 8;
					PC_PRO_TX_BUF[dataAddr++] = getWeight2;
					PC_PRO_TX_BUF[dataAddr++] = getWeightBefore2 >> 8;
					PC_PRO_TX_BUF[dataAddr++] = getWeightBefore2;
					PC_PRO_TX_BUF[dataAddr++] = getWeightAfter2 >> 8;
					PC_PRO_TX_BUF[dataAddr++] = getWeightAfter2;
					PC_PRO_TX_BUF[dataAddr++] = outputDistance2;

					PC_PRO_TX_BUF[dataAddr++] = 3;
					PC_PRO_TX_BUF[dataAddr++] = getWeight3 >> 8;
					PC_PRO_TX_BUF[dataAddr++] = getWeight3;
					PC_PRO_TX_BUF[dataAddr++] = getWeightBefore3 >> 8;
					PC_PRO_TX_BUF[dataAddr++] = getWeightBefore3;
					PC_PRO_TX_BUF[dataAddr++] = getWeightAfter3 >> 8;
					PC_PRO_TX_BUF[dataAddr++] = getWeightAfter3;
					PC_PRO_TX_BUF[dataAddr++] = outputDistance3;

					PC_PRO_TX_BUF[dataAddr++] = 4;
					PC_PRO_TX_BUF[dataAddr++] = getWeight4 >> 8;
					PC_PRO_TX_BUF[dataAddr++] = getWeight4;
					PC_PRO_TX_BUF[dataAddr++] = getWeightBefore4 >> 8;
					PC_PRO_TX_BUF[dataAddr++] = getWeightBefore4;
					PC_PRO_TX_BUF[dataAddr++] = getWeightAfter4 >> 8;
					PC_PRO_TX_BUF[dataAddr++] = getWeightAfter4;
					PC_PRO_TX_BUF[dataAddr++] = outputDistance4;
					break;
					
				default:break;				
			}
			
			printf("\r\n0x61 Update D1=%d, D2=%d, D3=%d, D4=%d\r\n",
						 outputDistance1, outputDistance2, outputDistance3, outputDistance4);
			break;
			
		case 0x62:
			PC_PRO_TX_BUF[dataAddr++] = 0x01;												//协议版本号
			switch(deviceType)
			{
				case DOUBLE_CLASSIFICATION:		//两分类
					PC_PRO_TX_BUF[dataAddr++] = 2;											//投口数量
					
					//通道1
					PC_PRO_TX_BUF[dataAddr++] = 0x01;										//投口编号
					
					PC_PRO_TX_BUF[dataAddr++] = 0x00;
					tmpeData = temperature*10;
					PC_PRO_TX_BUF[dataAddr++] = tmpeData >> 8;					//温度高8位
					PC_PRO_TX_BUF[dataAddr++] = tmpeData;								//温度低8位
					
					PC_PRO_TX_BUF[dataAddr++] = outputDistance1;						//测距值	
					
					//通道2
					PC_PRO_TX_BUF[dataAddr++] = 0x02;										//投口编号
					
					PC_PRO_TX_BUF[dataAddr++] = 0x00;
					tmpeData = temperature*10;
					PC_PRO_TX_BUF[dataAddr++] = tmpeData >> 8;					//温度高8位
					PC_PRO_TX_BUF[dataAddr++] = tmpeData;								//温度低8位
					
					PC_PRO_TX_BUF[dataAddr++] = outputDistance2;						//测距值
					break;

				case FOUR_CLASSIFICATION:
					PC_PRO_TX_BUF[dataAddr++] = 4;
					tmpeData = temperature*10;

					PC_PRO_TX_BUF[dataAddr++] = 0x01;
					PC_PRO_TX_BUF[dataAddr++] = 0x00;
					PC_PRO_TX_BUF[dataAddr++] = tmpeData >> 8;
					PC_PRO_TX_BUF[dataAddr++] = tmpeData;
					PC_PRO_TX_BUF[dataAddr++] = outputDistance1;

					PC_PRO_TX_BUF[dataAddr++] = 0x02;
					PC_PRO_TX_BUF[dataAddr++] = 0x00;
					PC_PRO_TX_BUF[dataAddr++] = tmpeData >> 8;
					PC_PRO_TX_BUF[dataAddr++] = tmpeData;
					PC_PRO_TX_BUF[dataAddr++] = outputDistance2;

					PC_PRO_TX_BUF[dataAddr++] = 0x03;
					PC_PRO_TX_BUF[dataAddr++] = 0x00;
					PC_PRO_TX_BUF[dataAddr++] = tmpeData >> 8;
					PC_PRO_TX_BUF[dataAddr++] = tmpeData;
					PC_PRO_TX_BUF[dataAddr++] = outputDistance3;

					PC_PRO_TX_BUF[dataAddr++] = 0x04;
					PC_PRO_TX_BUF[dataAddr++] = 0x00;
					PC_PRO_TX_BUF[dataAddr++] = tmpeData >> 8;
					PC_PRO_TX_BUF[dataAddr++] = tmpeData;
					PC_PRO_TX_BUF[dataAddr++] = outputDistance4;
					break;
					
				default: break;
			}
			printf("\r\n0x62 OF = %d, %d, %d, %d\r\n",
						 outputDistance1, outputDistance2, outputDistance3, outputDistance4);
			break;
			
		case 0x63:		//按键检测
			PC_PRO_TX_BUF[dataAddr++] = 0x01;												//协议版本号
			PC_PRO_TX_BUF[dataAddr++] = keyNum;
			PC_PRO_TX_BUF[dataAddr++] = keyStatus;
			break;
			
		case 0x64:		//红外开关状态输出
			PC_PRO_TX_BUF[dataAddr++] = 0x01;												//协议版本号
			PC_PRO_TX_BUF[dataAddr++] = 1;													//感应开关编号
			PC_PRO_TX_BUF[dataAddr++] = humanSensingKeyStatus;
			break;
			
		case 0x65:		//烟雾报警状态输出
			PC_PRO_TX_BUF[dataAddr++] = 0x01;												//协议版本号
			PC_PRO_TX_BUF[dataAddr++] = 0x01;												//传感器数量
			PC_PRO_TX_BUF[dataAddr++] = 1;													//烟雾报警器编号
			PC_PRO_TX_BUF[dataAddr++] = smokeAlarmStatus;
			break;
			
		case 0x66:		//投放口关闭状态输出
			PC_PRO_TX_BUF[dataAddr++] = 0x01;												//协议版本号
			
			//临时占位，加载完数据后写入
			tempAddr = dataAddr;
			PC_PRO_TX_BUF[dataAddr++] = 0x00;												//投口数量
			
			dataCunt = 0;
			if(dropOffPortMark1 == 1)
			{
				dropOffPortMark1 = 0;
				PC_PRO_TX_BUF[dataAddr++] = 1;													//投口编号
				PC_PRO_TX_BUF[dataAddr++] = dropPortClosedStatus1;			//投口关闭状态
				
				dataCunt++;
			}
			
			if(dropOffPortMark2 == 1)
			{
				dropOffPortMark2 = 0;
				PC_PRO_TX_BUF[dataAddr++] = 2;													//投口编号
				PC_PRO_TX_BUF[dataAddr++] = dropPortClosedStatus2;			//投口关闭状态
				
				dataCunt++;
			}
			PC_PRO_TX_BUF[tempAddr] = dataCunt;					//填补数据量
			break;
			
		case 0x67:		//GPS定位输出
			PC_PRO_TX_BUF[dataAddr++] = 0x01;												//协议版本号
			PC_PRO_TX_BUF[dataAddr++] = gpsStatus;									//定位状态
			PC_PRO_TX_BUF[dataAddr++] = gpsEW;											//经度方向（0->E-东,W-西）
			PC_PRO_TX_BUF[dataAddr++] = gpsLon >> 24;								//经度
			PC_PRO_TX_BUF[dataAddr++] = gpsLon >> 16;	
			PC_PRO_TX_BUF[dataAddr++] = gpsLon >> 8;	
			PC_PRO_TX_BUF[dataAddr++] = gpsLon;
			
			PC_PRO_TX_BUF[dataAddr++] = gpsNS;											//纬度方向（0->N-北,1->S-南）
			PC_PRO_TX_BUF[dataAddr++] = gpsLat >> 24;								//纬度
			PC_PRO_TX_BUF[dataAddr++] = gpsLat >> 16;	
			PC_PRO_TX_BUF[dataAddr++] = gpsLat >> 8;	
			PC_PRO_TX_BUF[dataAddr++] = gpsLat;
			break;
			
		case 0x90:		//握手同步信号
			PC_PRO_TX_BUF[dataAddr++] = 0x01;												//协议版本号
			len = strlen("connect");
			memcpy(&PC_PRO_TX_BUF[dataAddr], "connect", len);
			dataAddr += len;
			break;
			
		default:
			printf("\r\n未知指令！\r\n");
			break;
	}
	
	len = dataAddr - 4;																			//计算当前通讯的数据长度
	PC_PRO_TX_BUF[2] = (uint8_t)(len >> 8);									//存入通讯数据长度字字（高8位）
	PC_PRO_TX_BUF[3] = (uint8_t)len;												//存入通讯数据长度字字（低8位）
	
	PC_ProDataPackingAndSend(PC_PRO_TX_BUF, dataAddr); 			//按指定规则打包数据然后发送
}

/*
***********************************************************************
*	函 数 名: PC_ProCommandSend
*	功能说明: 下位机向上位机发送数据通讯命令
*	形    参:	protocolNo -> 协议号
*	返 回 值: 无
***********************************************************************
*/
void PC_ProCommandSend(uint8_t protocolNo)
{
	pcCmdMsg.msgType = protocolNo;
	MessageSend(MSG_FIFO_PC_CMD, pcCmdMsg);
}

/*
***********************************************************************
*	函 数 名: PC_ProCommandSendHandler
*	功能说明: 下位机向上位机发送数据通讯处理
*	形    参:	protocolNo -> 协议号
*	返 回 值: 无
***********************************************************************
*/
static void PC_ProCommandSendHandler(void)
{
	static uint8_t currentStatus = 0;
	static uint8_t nextStatus = 0;
	
	static MESSAGE *pMsg;
	
	static timer waitingTimer;
	
	static uint8_t timer_ok = 0;
	if(timer_ok == 0)
	{
		timer_ok = 1;
		timer_set(&waitingTimer, 2);
	}
	
	currentStatus = nextStatus;
	switch(currentStatus)
	{
		case 0x00:
			pMsg = MessageGet(MSG_FIFO_PC_CMD);
			if(pMsg)
			{
				PC_ProDataPacking((uint8_t)pMsg->msgType);
				timer_restart(&waitingTimer);
				nextStatus = 0x01;
				break;
			}
			break;
			
		case 0x01:
			if(timer_expired(&waitingTimer))
			{
				nextStatus = 0x00;
				break;
			}
			break;
			
		default:
			nextStatus = 0x00;
			break;
	}
}

/*
***********************************************************************
*	函 数 名: PC_ProDecodeTask
*	功能说明: 上下位机通讯协议处理任务
*	形    参:	无
*	返 回 值: 无
***********************************************************************
*/
void PC_ProDecodeTask(void)
{
	if(USART4_RX_STA == 0xfd)													//有接收到主机发送的数据
	{
		PC_ProCommandRun(USART4_RX_BUF, USART4_TX_BUF); 	//解释返回的数据
		
		memset(USART4_RX_BUF, 0x00, USART4_RECV_LEN);									//清除缓存内容
		USART4_RX_STA = 0;
	}
	
	PC_ProCommandSendHandler();
}

/******************** (C) COPYRIGHT 2017 CXHY *****END OF FILE*******************/ 
