
#include "exbfiletrans.h"

#include "delay.h"
#include "crc16.h"
#include "extendboards.h"

#if (CUR_CORE_BOARD	== CORE_BOARD_APP)
#include "workctrl.h"
#endif

// 数据包转换,从操作箱数据包转换成发给外围板的CAN数据包
void FileHeadFromOperToCan(u8 fileType, BoardFileCtrl * pBoardFile)
{
	// 机头板协议,界面发送的nodeid仅为0广播或对应的机头号,不需要知道具体的节点ID
	if (pBoardFile->fileHead.protocol == BN_PROTOCOL_HEAD)
	{
#if (MAX_SUPPORT_HEAD > 0)
		HeadControl * head = GetHeadFromList(1);		// 默认广播发送
		HeadControl * temp = NULL;					// 临时存储
		int hdnm = pBoardFile->fileHead.nodeid;		// 机头号,0为广播
		if (hdnm != 0)
		{// 非广播,找到对应节点
			for(int i = 1; i < MAX_SUPPORT_HEAD+1; i++)
			{
				temp = GetHeadFromList(i+1);
				if (temp->nodeTye == pBoardFile->fileHead.nodeType)
				{
					if (hdnm <= 1)
					{
						head = temp;
						break;
					}
					else
					{
						hdnm--;
					}
				}
			}
		}
		int timeout = 10;
		while(timeout > 0)
		{
			if (head->transFlag == 0)
			{
				head->transFlag = 1;
				memset(&pBoardFile->filepkt, 0, sizeof(BoardFilePacketCtrl));

				// 数据包头
				memcpy(pBoardFile->filepkt.pktHead.head.sync, CDP_SYNC, CDPSYNC_LEN);
				pBoardFile->filepkt.pktHead.head.pktId = FILE_HEAD_ID;
				pBoardFile->filepkt.pktHead.head.fnum = 6;				// 文件头数据内容共6个CAN数据帧

				// 数据内容
				// 文件名称
				for (int i = 0; i < 4; i++)
				{
					for (int j = 0; j < 8; j++)
					{
						pBoardFile->filepkt.pktData[i].data[j] = pBoardFile->fileHead.fileName[i*8+j];
					}
				}
				pBoardFile->filepkt.pktData[4].check.datasize = pBoardFile->fileHead.dataSize;
				pBoardFile->filepkt.pktData[4].check.dataChecksum = pBoardFile->fileHead.dataChecksum;
				pBoardFile->filepkt.pktData[5].info.fileType = fileType;
				pBoardFile->filepkt.pktData[5].info.nodeType = pBoardFile->fileHead.nodeType;

				pBoardFile->filepkt.pktHead.head.crc = CalcCrc16((u8*)&pBoardFile->filepkt.pktData, pBoardFile->filepkt.pktHead.head.fnum*CAN_DATA_LEN);

				break;
			}
			DelayRef(100);
			timeout--;
			if (timeout <= 0)
			{// CAN通讯超时
				printf("FileHeadFromOperToCan err\r\n");
			}
		}
#endif
	}
	else if (pBoardFile->fileHead.protocol == BN_PROTOCOL_COLOR)
	{// 换色板协议 因此协议不参与遍历 且节点ID为固定值 故nodeid为第几块 0仍然为广播
#if (MAX_SUPPORT_COLOR > 0)
		ColorControl * color = GetColorFromList(pBoardFile->fileHead.nodeid+1);
		int timeout = 10;
		while(timeout > 0)
		{
			if (color->transFlag == 0)
			{
				color->transFlag = 1;
				memset(&pBoardFile->filepkt, 0, sizeof(BoardFilePacketCtrl));

				// 数据包头
				memcpy(pBoardFile->filepkt.pktHead.head.sync, CDP_SYNC, CDPSYNC_LEN);
				pBoardFile->filepkt.pktHead.head.pktId = FILE_HEAD_ID;
				pBoardFile->filepkt.pktHead.head.fnum = 6;				// 文件头数据内容共6个CAN数据帧

				// 数据内容
				// 文件名称
				for (int i = 0; i < 4; i++)
				{
					for (int j = 0; j < 8; j++)
					{
						pBoardFile->filepkt.pktData[i].data[j] = pBoardFile->fileHead.fileName[i*8+j];
					}
				}
				pBoardFile->filepkt.pktData[4].check.datasize = pBoardFile->fileHead.dataSize;
				pBoardFile->filepkt.pktData[4].check.dataChecksum = pBoardFile->fileHead.dataChecksum;
				pBoardFile->filepkt.pktData[5].data[0] = fileType;

				pBoardFile->filepkt.pktHead.head.crc = CalcCrc16((u8*)&pBoardFile->filepkt.pktData, pBoardFile->filepkt.pktHead.head.fnum*CAN_DATA_LEN);

				break;
			}
			DelayRef(100);
			timeout--;
			if (timeout <= 0)
			{// CAN通讯超时
				printf("FileHeadFromOperToCan err\r\n");
			}
		}
#endif
	}
	else if (pBoardFile->fileHead.protocol == BN_PROTOCOL_EXTIO)
	{// IO扩展板协议 因此协议不参与遍历 且节点ID为固定值 故nodeid为第几块 0仍然为广播
#if (MAX_SUPPORT_EXTIO > 0)
		ExtIOControl * extio = GetExtIOFromList(pBoardFile->fileHead.nodeid+1);
		int timeout = 10;
		while(timeout > 0)
		{
			if (extio->transFlag == 0)
			{
				extio->transFlag = 1;
				memset(&pBoardFile->filepkt, 0, sizeof(BoardFilePacketCtrl));

				// 数据包头
				memcpy(pBoardFile->filepkt.pktHead.head.sync, CDP_SYNC, CDPSYNC_LEN);
				pBoardFile->filepkt.pktHead.head.pktId = FILE_HEAD_ID;
				pBoardFile->filepkt.pktHead.head.fnum = 6;				// 文件头数据内容共6个CAN数据帧

				// 数据内容
				// 文件名称
				for (int i = 0; i < 4; i++)
				{
					for (int j = 0; j < 8; j++)
					{
						pBoardFile->filepkt.pktData[i].data[j] = pBoardFile->fileHead.fileName[i*8+j];
					}
				}
				pBoardFile->filepkt.pktData[4].check.datasize = pBoardFile->fileHead.dataSize;
				pBoardFile->filepkt.pktData[4].check.dataChecksum = pBoardFile->fileHead.dataChecksum;
				pBoardFile->filepkt.pktData[5].data[0] = fileType;

				pBoardFile->filepkt.pktHead.head.crc = CalcCrc16((u8*)&pBoardFile->filepkt.pktData, pBoardFile->filepkt.pktHead.head.fnum*CAN_DATA_LEN);

				break;
			}
			DelayRef(100);
			timeout--;
			if (timeout <= 0)
			{// CAN通讯超时
				printf("FileHeadFromOperToCan err\r\n");
			}
		}
#endif
	}
}

// 数据包转换,从操作箱数据包转换成发给外围板的CAN数据包
void FileDataFromOperToCan(OperPacket * pPkt, BoardFileCtrl * pBoardFile)
{
	if (pBoardFile->fileHead.protocol == BN_PROTOCOL_HEAD)
	{// 机头板协议,界面发送的nodeid仅为0广播或对应的机头号,不需要知道具体的节点ID
#if (MAX_SUPPORT_HEAD > 0)
		HeadControl * head = GetHeadFromList(1);		// 默认广播发送
		HeadControl * temp = NULL;					// 临时存储
		int hdnm = pBoardFile->fileHead.nodeid;		// 机头号,0为广播
		if (hdnm != 0)
		{
			for(int i = 1; i < MAX_SUPPORT_HEAD+1; i++)
			{
				temp = GetHeadFromList(i+1);
				if (temp->nodeTye == pBoardFile->fileHead.nodeType)
				{
					if (hdnm <= 1)
					{
						head = temp;
						break;
					}
					else
					{
						hdnm--;
					}
				}
			}
		}
		int timeout = 10;
		while(timeout > 0)
		{
			if (head->transFlag == 0)
			{
				head->transFlag = 1;
				memset(&pBoardFile->filepkt, 0, sizeof(BoardFilePacketCtrl));

				// 数据包头
				memcpy(pBoardFile->filepkt.pktHead.head.sync, CDP_SYNC, CDPSYNC_LEN);
				pBoardFile->filepkt.pktHead.head.pktId = pPkt->transFileData.pktIdx;
				pBoardFile->filepkt.pktHead.head.fnum = (pPkt->transFileData.exLen + CAN_DATA_LEN - 1) / CAN_DATA_LEN;

				// 数据内容
				// 文件名称
				for (int i = 0; i < pBoardFile->filepkt.pktHead.head.fnum; i++)
				{
					memcpy(&pBoardFile->filepkt.pktData[i].data[0], &pPkt->transFileData.exData[i*CAN_DATA_LEN], CAN_DATA_LEN);
				}

				pBoardFile->filepkt.pktHead.head.crc = CalcCrc16((u8*)pBoardFile->filepkt.pktData, pBoardFile->filepkt.pktHead.head.fnum*CAN_DATA_LEN);

				break;
			}
			DelayRef(100);
			timeout--;
			if (timeout <= 0)
			{// CAN通讯超时
				printf("FileDataFromOperToCan err\r\n");
			}
		}
#endif
	}
	else if (pBoardFile->fileHead.protocol == BN_PROTOCOL_COLOR)
	{// 换色板协议 因此协议不参与遍历 且节点ID为固定值 故nodeid为第几块 0仍然为广播
#if (MAX_SUPPORT_COLOR > 0)
		ColorControl * color = GetColorFromList(pBoardFile->fileHead.nodeid+1);
		int timeout = 10;
		while(timeout > 0)
		{
			if (color->transFlag == 0)
			{
				color->transFlag = 1;
				memset(&pBoardFile->filepkt, 0, sizeof(BoardFilePacketCtrl));

				// 数据包头
				memcpy(pBoardFile->filepkt.pktHead.head.sync, CDP_SYNC, CDPSYNC_LEN);
				pBoardFile->filepkt.pktHead.head.pktId = pPkt->transFileData.pktIdx;
				pBoardFile->filepkt.pktHead.head.fnum = (pPkt->transFileData.exLen + CAN_DATA_LEN - 1) / CAN_DATA_LEN;

				// 数据内容
				// 文件名称
				for (int i = 0; i < pBoardFile->filepkt.pktHead.head.fnum; i++)
				{
					memcpy(&pBoardFile->filepkt.pktData[i].data[0], &pPkt->transFileData.exData[i*CAN_DATA_LEN], CAN_DATA_LEN);
				}

				pBoardFile->filepkt.pktHead.head.crc = CalcCrc16((u8*)pBoardFile->filepkt.pktData, pBoardFile->filepkt.pktHead.head.fnum*8);

				break;
			}
			DelayRef(100);
			timeout--;
			if (timeout <= 0)
			{// CAN通讯超时
				printf("FileDataFromOperToCan err\r\n");
			}
		}
#endif
	}
	else if (pBoardFile->fileHead.protocol == BN_PROTOCOL_EXTIO)
	{// IO扩展板协议 因此协议不参与遍历 且节点ID为固定值 故nodeid为第几块 0仍然为广播
#if (MAX_SUPPORT_EXTIO > 0)
		ExtIOControl * extio = GetExtIOFromList(pBoardFile->fileHead.nodeid+1);
		int timeout = 10;
		while(timeout > 0)
		{
			if (extio->transFlag == 0)
			{
				extio->transFlag = 1;
				memset(&pBoardFile->filepkt, 0, sizeof(BoardFilePacketCtrl));

				// 数据包头
				memcpy(pBoardFile->filepkt.pktHead.head.sync, CDP_SYNC, CDPSYNC_LEN);
				pBoardFile->filepkt.pktHead.head.pktId = pPkt->transFileData.pktIdx;
				pBoardFile->filepkt.pktHead.head.fnum = (pPkt->transFileData.exLen + CAN_DATA_LEN - 1) / CAN_DATA_LEN;

				// 数据内容
				// 文件名称
				for (int i = 0; i < pBoardFile->filepkt.pktHead.head.fnum; i++)
				{
					memcpy(&pBoardFile->filepkt.pktData[i].data[0], &pPkt->transFileData.exData[i*CAN_DATA_LEN], CAN_DATA_LEN);
				}

				pBoardFile->filepkt.pktHead.head.crc = CalcCrc16((u8*)pBoardFile->filepkt.pktData, pBoardFile->filepkt.pktHead.head.fnum*8);

				break;
			}
			DelayRef(100);
			timeout--;
			if (timeout <= 0)
			{// CAN通讯超时
				printf("FileDataFromOperToCan err\r\n");
			}
		}
#endif
	}
}

// 用CAN数据帧的格式发送数据包
void SendPacketWithCanData(u32 exid, BoardFileCtrl * pBoardFile)
{
	CanTxMsg txMsg;
	txMsg.canTxhead.ExtId = exid;
	txMsg.canTxhead.RTR = CAN_RTR_DATA;			// 数据帧
	txMsg.canTxhead.IDE = CAN_ID_EXT;			// 扩展帧
	txMsg.canTxhead.DLC = CAN_DATA_LEN;			// 数据场长度

	for (int idx = 0; idx < pBoardFile->filepkt.pktHead.head.fnum+1; idx++)
	{
		memcpy(&txMsg.data, ((u8*)&pBoardFile->filepkt.pktHead)+idx*CAN_DATA_LEN, CAN_DATA_LEN);	// 填充数据场
		SendACANDataPacket(&txMsg);
		DelayMs(1);
	}
}

