optical/SEW-EXA1/Users/Func/canwork.c
2025-09-04 09:45:08 +08:00

197 lines
8.1 KiB
C
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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