/*************************** (C) COPYRIGHT 2020 Ping ****************************
 * 文件名  ：m_s_comm.c
 * 描  述  ：主从MCU通讯处理程序
 * 版  本  ：V1.0
 * 作  者  ：XuZhongPing
 * 日  期  ：2020/03/31
*********************************************************************************/
#include "m_s_comm.h"
#include "device.h"
#include "data_typedef.h"
#include "gps.h"

uint8_t M_S_RX_BUF[M_S_RECV_LEN];     		//接收缓冲
uint8_t M_S_TX_BUF[M_S_SEND_LEN];					//发送缓冲

static void M_S_DataDecode(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");
}

/*
***********************************************************************
*	函 数 名: M_S_DataPackingAndSend
*	功能说明: 主从机通讯数据打包及发送
*	形    参:	*pdata -> 需要打包的数据地址，dataLen -> 数据长度
*	返 回 值: 无
***********************************************************************
*/
void M_S_DataPackingAndSend(uint8_t *pdata, uint16_t dataLen)
{
	uint8_t i;
	uint8_t CS = 0x68;
	uint8_t TX_Size = 0;
	
	uint8_t sendDataBuf[128];
	uint8_t dataAddrIndex = 0;
	uint8_t sendDataLen = 0;
	
	sendDataBuf[dataAddrIndex++] = 0xfe; 			//发送前导字节
	sendDataBuf[dataAddrIndex++] = 0xfe; 			
	sendDataBuf[dataAddrIndex++] = 0xfe; 		
	sendDataBuf[dataAddrIndex++] = 0x68; 			//发送帧头
	
	sendDataBuf[dataAddrIndex++] = *pdata; 		//发送地址
	CS += *pdata;
	sendDataBuf[dataAddrIndex++] = 0x68; 			//发送帧头
	CS += 0x68;
	sendDataBuf[dataAddrIndex++] = *(pdata+1); 	//发送帧命令
	CS += *(pdata+1);
	TX_Size = *(pdata+2);											//取出通讯数据长度
	sendDataBuf[dataAddrIndex++] = TX_Size; 	//发送数据长度
	CS += *(pdata+2);
	for(i=0; i<TX_Size; i++) 									//加载发送数据
	{
		sendDataBuf[dataAddrIndex++] = *(pdata+i+3);
		CS += (*(pdata+i+3));
	}
	sendDataBuf[dataAddrIndex++] = CS; 				//发送校验字节
	sendDataBuf[dataAddrIndex++] = 0x16; 			//发送帧尾
	
	sendDataLen = dataAddrIndex;
	
// 	showHex(sendDataBuf, sendDataLen);

	USART2_SendFrameData(sendDataBuf, sendDataLen);
}

/*
***********************************************************************
*	函 数 名: M_S_CommandSend
*	功能说明: 从机向主机发送数据通讯命令
*	形    参:	comNum -> 指令号
*	返 回 值: 无
***********************************************************************
*/
void M_S_CommandSend(uint8_t comNum)
{
	uint8_t dataLen = 0;												//打包后的协议总长度
	uint8_t dataIndex = 0;											//发送的数据下标索引
	
	M_S_TX_BUF[0] = 0x00; 											//设置通讯地址
	M_S_TX_BUF[1] = comNum;											//存入命令码
	
	dataIndex += 3;															//从地址、命令、长度后开始算起
	
	printf("\r\nS->M --> 0x%02X\r\n", comNum);
	
	switch(comNum)
	{
		case 0x01:		//发送MCU2检测到的称重、测距、光电开关状态数据
			//称重数据
			M_S_TX_BUF[dataIndex++] = weight1 >> 8;
			M_S_TX_BUF[dataIndex++] = weight1;
			M_S_TX_BUF[dataIndex++] = weight2 >> 8;
			M_S_TX_BUF[dataIndex++] = weight2;
			M_S_TX_BUF[dataIndex++] = weight3 >> 8;
			M_S_TX_BUF[dataIndex++] = weight3;
			M_S_TX_BUF[dataIndex++] = weight4 >> 8;
			M_S_TX_BUF[dataIndex++] = weight4;
			
			//测距数据
			M_S_TX_BUF[dataIndex++] = getDistance1;
			M_S_TX_BUF[dataIndex++] = getDistance2;
			M_S_TX_BUF[dataIndex++] = getDistance3;
			M_S_TX_BUF[dataIndex++] = getDistance4;
			
			//主板温度
			M_S_TX_BUF[dataIndex++] = temperature;
			
			//输入接口状态
			M_S_TX_BUF[dataIndex++] = OPTO_KEY;
			
			//外部温度
			M_S_TX_BUF[dataIndex++] = temperature_A;
			
			//接近开关状态
			M_S_TX_BUF[dataIndex++] = SW_KEY1;
			M_S_TX_BUF[dataIndex++] = SW_KEY2;
			break;
			
		case 0x02:		//即时发送MCU2检测到的光电开关状态数据（用于当按键使用）
			//光电开关状态
			M_S_TX_BUF[dataIndex++] = optoKeyStatus;
			break;
			
		case 0x03:		//GPS定位上传
			M_S_TX_BUF[dataIndex++] = gpsConnectSta;						//硬件状态
			M_S_TX_BUF[dataIndex++] = gpsGNGGA.sig;							//定位状态
			M_S_TX_BUF[dataIndex++] = gpsInfo.u_ew;							//东西经方向
			M_S_TX_BUF[dataIndex++] = gpsInfo.u_lon >> 24;			//经度
			M_S_TX_BUF[dataIndex++] = gpsInfo.u_lon >> 16;
			M_S_TX_BUF[dataIndex++] = gpsInfo.u_lon >> 8;
			M_S_TX_BUF[dataIndex++] = gpsInfo.u_lon;
			
			M_S_TX_BUF[dataIndex++] = gpsInfo.u_ns;							//南北纬方向
			M_S_TX_BUF[dataIndex++] = gpsInfo.u_lat >> 24;			//纬度
			M_S_TX_BUF[dataIndex++] = gpsInfo.u_lat >> 16;
			M_S_TX_BUF[dataIndex++] = gpsInfo.u_lat >> 8;
			M_S_TX_BUF[dataIndex++] = gpsInfo.u_lat;
			break;
			
		case 0xA2:		//发送取得校准零点
			M_S_TX_BUF[dataIndex++] = sendScaleNum;
			break;
	
		case 0xA3:		//发送校准完成
			M_S_TX_BUF[dataIndex++] = sendScaleNum;
			break;
		
		default:
			break;
	}
	
	//存入通信数据长度
	M_S_TX_BUF[2] = dataIndex - 3;									//存入通讯数据长度字节
	dataLen = dataIndex;
	
//	printf("\r\nlen = %d\r\n", dataLen);
	M_S_DataPackingAndSend(M_S_TX_BUF, dataLen); 		//按指定规则打包数据然后发送
}
	
/*
***********************************************************************
*	函 数 名: M_S_DataDecode
*	功能说明: 主从机通讯数据解析
*	形    参:	*pRxBuf -> 接收缓存的地址，*pTxBuf -> 发送数据缓存地址 
*	返 回 值: 无
***********************************************************************
*/
static void M_S_DataDecode(uint8_t *pRxBuf, uint8_t *pTxBuf)
{
	uint8_t comNum = 0;							//主从机指令码
	
	comNum = *(pRxBuf+1);
	
	printf("\r\nM->S <-- 0x%02X\r\n", comNum);
	switch(comNum)														//通讯命令译码
	{			
		case 0x01:			//收到上位机发下发的用户验证信息
			if(*(pRxBuf+3) == 1)		//人脸识别绑定的IC卡号
			{
			
			}
			break;
		
		case 0x02:
			break;
			
		case 0xA1:		//称盘校准
			calibrationScaleNum = *(pRxBuf+3);
			if((calibrationScaleNum > 0) && (calibrationScaleNum < 3))
			{
				SendCalibraCmd(calibrationScaleNum);
			}
			break;
			
		case 0xA5:		//校准失败
			calibrationErrorMark = 1;
			break;
			
		default: 			//其他命令
			break;
	}
}

/*
***********************************************************************
*	函 数 名: M_S_DataDecodeTask
*	功能说明: 主从机数据通讯解析处理任务
*	形    参:	无
*	返 回 值: 无
***********************************************************************
*/
void M_S_DataDecodeTask(void)
{
	if(USART2_RX_STA == 0xfd)													//有接收到主机发送的数据
	{
		M_S_DataDecode(USART2_RX_BUF, USART2_TX_BUF); 	//解释返回的数据
		
		memset(USART2_RX_BUF, 0x00, USART2_RECV_LEN);		//清除缓存内容
		USART2_RX_STA = 0;
	}
}

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