//-------------------------------------------------------------------------------
// File Name:	canwork.c
// Brief:
// Version:		1.0.0
// Create Date: 2024/10/17
// Create by: 	W.X
// Copyright:
//				TIANJIN GETONAGAIN TECHNOLOGY CO., LIMITED
//				All rights reserved.
//
// Modify by:	W.X
// Modify Date:	2024/10/17
//-------------------------------------------------------------------------------

#include "canwork.h"

#if (CONTROL_BUS == COMM_CAN)

void ExA1CanFilter(u8 fifo);

void InitCAN(void)
{
	// CAN 节点
	g_workCtrl.hostId = 1;

	g_workCtrl.device = BN_DEVICE_EXA1;
	g_workCtrl.nodeId = CUR_EXA1_NODE_ID;

	g_workCtrl.workSta = 2;

	printf("g_workCtrl.nodeId is %d\r\n",g_workCtrl.nodeId);

	RegistFilter(ExA1CanFilter);

	InitCanCtrl();
	InitSewHeadControl(&g_workCtrl.curBdCtrl);
}


void ExA1CanFilter(u8 fifo)
{
	CAN_FilterTypeDef CAN_FilterInitStructure;

	// 请求本节点状态变化的远程帧和控制本节点命令的数据帧
	CAN_FilterInitStructure.FilterBank = 0;												// 设置过滤器组0，范围为0~13
	CAN_FilterInitStructure.FilterMode = CAN_FILTERMODE_IDLIST;								// 过滤器组0为标识符列表模式
	CAN_FilterInitStructure.FilterScale = CAN_FILTERSCALE_32BIT;							// 过滤器组0位宽为32位
	CAN_FilterInitStructure.FilterIdHigh = HIWORD(MAKE_FILTER(MAKE_EXID(g_workCtrl.device, g_workCtrl.nodeId, 0, BN_CMD_EXSTA), CAN_RTR_REMOTE));	// 设定第一个过滤器高16位
	CAN_FilterInitStructure.FilterIdLow = LOWORD(MAKE_FILTER(MAKE_EXID(g_workCtrl.device, g_workCtrl.nodeId, 0, BN_CMD_EXSTA), CAN_RTR_REMOTE));	// 设定第一个过滤器低16位
	CAN_FilterInitStructure.FilterMaskIdHigh = HIWORD(MAKE_FILTER(MAKE_EXID(g_workCtrl.device, g_workCtrl.nodeId, 0, BN_CMD_EXSTA), CAN_RTR_DATA));	// 设定第二个过滤器高16位
	CAN_FilterInitStructure.FilterMaskIdLow = LOWORD(MAKE_FILTER(MAKE_EXID(g_workCtrl.device, g_workCtrl.nodeId, 0, BN_CMD_EXSTA), CAN_RTR_DATA));	// 设定第二个过滤器低16位
	CAN_FilterInitStructure.FilterFIFOAssignment = fifo;							// 关联到接收FIFO
	CAN_FilterInitStructure.FilterActivation = ENABLE;								// 使能过滤器
	HAL_CAN_ConfigFilter(&HCAN,&CAN_FilterInitStructure);											// 写入设置

	// 广播命令，远程帧和数据帧
	CAN_FilterInitStructure.FilterBank = 1;												// 设置过滤器组1，范围为0~13
	CAN_FilterInitStructure.FilterMode = CAN_FILTERMODE_IDLIST;								// 过滤器组1为标识符列表模式
	CAN_FilterInitStructure.FilterScale = CAN_FILTERSCALE_32BIT;							// 过滤器组1位宽为32位
	CAN_FilterInitStructure.FilterIdHigh = HIWORD(MAKE_FILTER(BROADCAST_EXID, CAN_RTR_REMOTE));		// 设定第三个过滤器高16位
	CAN_FilterInitStructure.FilterIdLow = LOWORD(MAKE_FILTER(BROADCAST_EXID, CAN_RTR_REMOTE));		// 设定第三个过滤器低16位
	CAN_FilterInitStructure.FilterMaskIdHigh = HIWORD(MAKE_FILTER(BNMASK_PRT, CAN_RTR_DATA));	// 设定第四个过滤器高16位
	CAN_FilterInitStructure.FilterMaskIdLow = LOWORD(MAKE_FILTER(BNMASK_PRT, CAN_RTR_DATA));	// 设定第四个过滤器低16位
	CAN_FilterInitStructure.FilterFIFOAssignment = fifo;							// 关联到接收FIFO
	CAN_FilterInitStructure.FilterActivation = ENABLE;								// 使能过滤器
	HAL_CAN_ConfigFilter(&HCAN,&CAN_FilterInitStructure);											// 写入设置

	// 针对本类设备的所有ID的广播的远程帧和数据帧
	CAN_FilterInitStructure.FilterBank = 2;							// 设置过滤器组2，范围为0~13
	CAN_FilterInitStructure.FilterMode = CAN_FILTERMODE_IDLIST;			// 过滤器组2为标识符屏蔽位模式
	CAN_FilterInitStructure.FilterScale = CAN_FILTERSCALE_32BIT;		// 过滤器位宽为1个32位过滤器
	CAN_FilterInitStructure.FilterIdHigh = HIWORD(MAKE_FILTER(MAKE_EXID(g_workCtrl.device, BN_ID_BROADCAST, 0, 0), 0));		// 设定过滤器标识符（32位位宽时为其高段位，16位位宽时为第一个）
	CAN_FilterInitStructure.FilterIdLow = LOWORD(MAKE_FILTER(MAKE_EXID(g_workCtrl.device, BN_ID_BROADCAST, 0, 0), 0));		// 设定过滤器标识符（32位位宽时为其低段位，16位位宽时为第二个）
	CAN_FilterInitStructure.FilterMaskIdHigh = HIWORD(MAKE_FILTER(BNMASK_PRT|BNMASK_TID, 0));							// 设定过滤器屏蔽标识符或者过滤器标识符（32位位宽时为其高段位，16位位宽时为第一个）
	CAN_FilterInitStructure.FilterMaskIdLow = LOWORD(MAKE_FILTER(BNMASK_PRT|BNMASK_TID, 0));								// 设定过滤器屏蔽标识符或者过滤器标识符（32位位宽时为其低段位，16位位宽时为第二个)
	CAN_FilterInitStructure.FilterFIFOAssignment = fifo;				// 关联到接收FIFO
	CAN_FilterInitStructure.FilterActivation = ENABLE;					// 使能过滤器
	HAL_CAN_ConfigFilter(&HCAN,&CAN_FilterInitStructure);								// 写入设置

	// 针对本类设备的本节点控制的远程帧和数据帧
	CAN_FilterInitStructure.FilterBank = 3;							// 设置过滤器组2，范围为0~13
	CAN_FilterInitStructure.FilterMode = CAN_FILTERMODE_IDLIST;			// 过滤器组2为标识符屏蔽位模式
	CAN_FilterInitStructure.FilterScale = CAN_FILTERSCALE_32BIT;		// 过滤器位宽为1个32位过滤器
	CAN_FilterInitStructure.FilterIdHigh = HIWORD(MAKE_FILTER(MAKE_EXID(g_workCtrl.device, g_workCtrl.nodeId, 0, 0), 0));		// 设定过滤器标识符（32位位宽时为其高段位，16位位宽时为第一个）
	CAN_FilterInitStructure.FilterIdLow = LOWORD(MAKE_FILTER(MAKE_EXID(g_workCtrl.device, g_workCtrl.nodeId, 0, 0), 0));		// 设定过滤器标识符（32位位宽时为其低段位，16位位宽时为第二个）
	CAN_FilterInitStructure.FilterMaskIdHigh = HIWORD(MAKE_FILTER(BNMASK_PRT|BNMASK_TID, 0));							// 设定过滤器屏蔽标识符或者过滤器标识符（32位位宽时为其高段位，16位位宽时为第一个）
	CAN_FilterInitStructure.FilterMaskIdLow = LOWORD(MAKE_FILTER(BNMASK_PRT|BNMASK_TID, 0));								// 设定过滤器屏蔽标识符或者过滤器标识符（32位位宽时为其低段位，16位位宽时为第二个)
	CAN_FilterInitStructure.FilterFIFOAssignment = fifo;				// 关联到接收FIFO
	CAN_FilterInitStructure.FilterActivation = ENABLE;					// 使能过滤器
	HAL_CAN_ConfigFilter(&HCAN,&CAN_FilterInitStructure);
}

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

void CanBusTask(void)
{
	int rslt;
	int sendflag;
	CanRxMsg rxMsg;
	CanTxMsg txMsg;
	int dev, tid, sid, cmd;

	sendflag = 0;

	// 检查CAN数据
	rslt = GetACanDataPacket(&rxMsg);
	if (rslt == 0)
	{
		dev = GET_PRT_FROM_EXID(rxMsg.canRxhead.ExtId);
		tid = GET_TID_FROM_EXID(rxMsg.canRxhead.ExtId);
		sid = GET_SID_FROM_EXID(rxMsg.canRxhead.ExtId);
		cmd = GET_CMD_FROM_EXID(rxMsg.canRxhead.ExtId);

		if (rxMsg.canRxhead.RTR == CAN_RTR_REMOTE)	// 远程帧
		{
			if ((dev == BN_PROTOCOL_ALL || dev == g_workCtrl.device) && 		// 全部设备或本设备
				(tid == BN_ID_BROADCAST || tid == g_workCtrl.nodeId)	)	// 全部ID或本板
			{
				if (cmd == BN_CMD_EXSTA)		// 状态命令
				{
					sendflag = 1;		// 发送状态
					printf("receive sta request packet\r\n");
				}
				else
				{
					printf("other Remote cmd, cmd=0x%x\r\n", cmd);
				}
			}
			else
			{
				printf("other Remote packet, exid=0x%x\r\n", (int)rxMsg.canRxhead.ExtId);
			}
		}
		else // if (rxMsg.canRxhead.RTR == CAN_RTR_DATA)		// 数据帧
		{
			if ((dev == BN_PROTOCOL_ALL ||dev == g_workCtrl.device) && 	// exa1
				(tid == BN_ID_BROADCAST || tid == g_workCtrl.nodeId)	)	// 全部ID或本板
			{
				if (cmd == BN_CMD_EXCTRL ||		// 控制命令
					cmd == BN_CMD_TRAVERSE ||	// 遍历命令
					0	)
				{
					g_workCtrl.curBdCtrl.ctrlCmd.cancomm.exId.id = rxMsg.canRxhead.ExtId;
					memcpy(g_workCtrl.curBdCtrl.ctrlCmd.cancomm.data.buff, rxMsg.data, CAN_DATA_LEN);	// 填充数据场
					g_workCtrl.curBdCtrl.cmdFlag = 1;		// 新命令标志
				//	printf("get ex ctrl cmd\r\n");
				}
				else
				{
					printf("get other data cmd=0x%x\r\n", cmd);
				}
			}
			else
			{
				printf("other data packet, dev=0x%x, tid=%d, exid=0x%x\r\n", dev, (int)tid, (int)rxMsg.canRxhead.ExtId);
			}
		}
	}

	if (sendflag == 0)
	{
		sid = g_workCtrl.hostId;
	}

	// 发送状态信息
	if (g_workCtrl.curBdCtrl.staFlag != 0)
	{
		g_workCtrl.curBdCtrl.staFlag = 0;
		sendflag = 1;		// 发送状态
	}

	if (sendflag == 1)
	{
		if(g_workCtrl.workSta == 1)
		{
			txMsg.canTxhead.ExtId = MAKE_EXID(g_workCtrl.device, g_workCtrl.nodeId, sid, BN_CMD_TRAVERSE);	// 状态命令
		}
		else
		{
			txMsg.canTxhead.ExtId = MAKE_EXID(g_workCtrl.device, g_workCtrl.nodeId, sid, BN_CMD_EXSTA);	// 状态命令
		}
		txMsg.canTxhead.RTR = CAN_RTR_DATA;				// 数据帧
		txMsg.canTxhead.IDE = CAN_ID_EXT;					// 扩展帧
		txMsg.canTxhead.DLC = CAN_DATA_LEN;				// 数据场长度
		memcpy(txMsg.data, g_workCtrl.curBdCtrl.exbSta.cancomm.data.buff, CAN_DATA_LEN);	// 填充数据场
		rslt = SendACANDataPacket(&txMsg);

		//printf("send sta data by can, exid=0x%x\r\n", (int)txMsg.ExtId);
	}
}

#endif




