//------------------------------------------------------------------------------- // 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