1#include "stm32_can.hpp"
3#ifdef HAL_CAN_MODULE_ENABLED
7STM32CAN* STM32CAN::map[STM32_CAN_NUMBER] = {
nullptr};
15stm32_can_id_t STM32_CAN_GetID(CAN_TypeDef* addr)
20 return stm32_can_id_t::STM32_CAN_ID_ERROR;
23 else if (addr == CAN1)
25 return stm32_can_id_t::STM32_CAN1;
29 else if (addr == CAN2)
31 return stm32_can_id_t::STM32_CAN2;
35 else if (addr == CAN3)
37 return stm32_can_id_t::STM32_CAN3;
42 return stm32_can_id_t::STM32_CAN_ID_ERROR;
48 :
CAN(), hcan_(hcan), id_(STM32_CAN_GetID(hcan->Instance)), tx_pool_(pool_size)
56 CAN_FilterTypeDef can_filter = {};
58 can_filter.FilterIdHigh = 0;
59 can_filter.FilterIdLow = 0;
60 can_filter.FilterMode = CAN_FILTERMODE_IDMASK;
61 can_filter.FilterScale = CAN_FILTERSCALE_32BIT;
62 can_filter.FilterMaskIdHigh = 0;
63 can_filter.FilterMaskIdLow = 0;
64 can_filter.FilterFIFOAssignment = fifo_;
65 can_filter.FilterActivation = ENABLE;
67 if (id_ == STM32_CAN1)
69 can_filter.FilterBank = 0;
70 can_filter.SlaveStartFilterBank = 14;
73 else if (id_ == STM32_CAN2)
75 can_filter.FilterBank = 14;
76 can_filter.SlaveStartFilterBank = 14;
79 else if (id_ == STM32_CAN3)
81 can_filter.FilterBank = 3;
86 if (id_ == STM32_CAN1)
88 can_filter.FilterBank = 0;
89 can_filter.SlaveStartFilterBank = 14;
92 else if (id_ == STM32_CAN2)
94 can_filter.FilterBank = 14;
95 can_filter.SlaveStartFilterBank = 14;
99 if (id_ == STM32_CAN1)
101 can_filter.FilterBank = 0;
102 can_filter.SlaveStartFilterBank = 14;
103 fifo_ = CAN_RX_FIFO0;
110 return ErrorCode::FAILED;
112 can_filter.FilterFIFOAssignment = fifo_;
114 if (HAL_CAN_ConfigFilter(hcan_, &can_filter) != HAL_OK)
116 return ErrorCode::FAILED;
119 if (HAL_CAN_Start(hcan_) != HAL_OK)
121 return ErrorCode::FAILED;
124 if (fifo_ == CAN_RX_FIFO0)
126 HAL_CAN_ActivateNotification(hcan_, CAN_IT_RX_FIFO0_MSG_PENDING);
130 HAL_CAN_ActivateNotification(hcan_, CAN_IT_RX_FIFO1_MSG_PENDING);
133 HAL_CAN_ActivateNotification(hcan_, CAN_IT_ERROR);
134 HAL_CAN_ActivateNotification(hcan_, CAN_IT_TX_MAILBOX_EMPTY);
136 return ErrorCode::OK;
141 CAN_TxHeaderTypeDef txHeader;
143 txHeader.DLC =
sizeof(pack.data);
148 txHeader.IDE = CAN_ID_STD;
149 txHeader.RTR = CAN_RTR_DATA;
152 txHeader.IDE = CAN_ID_EXT;
153 txHeader.RTR = CAN_RTR_DATA;
156 txHeader.IDE = CAN_ID_STD;
157 txHeader.RTR = CAN_RTR_REMOTE;
160 txHeader.IDE = CAN_ID_EXT;
161 txHeader.RTR = CAN_RTR_REMOTE;
165 return ErrorCode::FAILED;
169 txHeader.TransmitGlobalTime = DISABLE;
175 if (HAL_CAN_AddTxMessage(hcan_, &txHeader, pack.data, &txMailbox) != HAL_OK)
177 if (tx_pool_.
Put(pack, slot) != ErrorCode::OK)
179 return ErrorCode::FULL;
184 return ErrorCode::OK;
187 if (bus_busy_.load(std::memory_order_acquire) == 0 &&
194 return ErrorCode::OK;
201 while (HAL_CAN_GetRxMessage(hcan_, fifo_, &rx_buff_.header, rx_buff_.pack.data) ==
204 if (rx_buff_.header.IDE == CAN_ID_STD)
206 if (rx_buff_.header.StdId == 2046)
210 rx_buff_.pack.id = rx_buff_.header.StdId;
215 rx_buff_.pack.id = rx_buff_.header.ExtId;
219 if (rx_buff_.header.RTR == CAN_RTR_REMOTE)
230 OnMessage(rx_buff_.pack,
true);
236 if (tx_pool_.
Get(tx_buff_.pack) == ErrorCode::OK)
238 tx_buff_.header.DLC =
sizeof(tx_buff_.pack.data);
239 switch (tx_buff_.pack.type)
242 tx_buff_.header.IDE = CAN_ID_STD;
243 tx_buff_.header.RTR = CAN_RTR_DATA;
246 tx_buff_.header.IDE = CAN_ID_EXT;
247 tx_buff_.header.RTR = CAN_RTR_DATA;
250 tx_buff_.header.IDE = CAN_ID_STD;
251 tx_buff_.header.RTR = CAN_RTR_REMOTE;
254 tx_buff_.header.IDE = CAN_ID_EXT;
255 tx_buff_.header.RTR = CAN_RTR_REMOTE;
261 tx_buff_.header.StdId = (tx_buff_.pack.type ==
Type::EXTENDED) ? 0 : tx_buff_.pack.id;
262 tx_buff_.header.ExtId = (tx_buff_.pack.type ==
Type::EXTENDED) ? tx_buff_.pack.id : 0;
263 tx_buff_.header.TransmitGlobalTime = DISABLE;
265 HAL_CAN_AddTxMessage(hcan_, &tx_buff_.header, tx_buff_.pack.data, &txMailbox);
267 bus_busy_.store(UINT32_MAX, std::memory_order_release);
271 uint32_t tsr = READ_REG(hcan_->Instance->TSR);
273 if (((tsr & CAN_TSR_TME0) != 0U) && ((tsr & CAN_TSR_TME1) != 0U) &&
274 ((tsr & CAN_TSR_TME2) != 0U))
276 bus_busy_.store(0, std::memory_order_release);
280 bus_busy_.store(UINT32_MAX, std::memory_order_release);
285extern "C" void HAL_CAN_RxFifo0MsgPendingCallback(CAN_HandleTypeDef* hcan)
287 STM32CAN* can = STM32CAN::map[STM32_CAN_GetID(hcan->Instance)];
294extern "C" void HAL_CAN_RxFifo1MsgPendingCallback(CAN_HandleTypeDef* hcan)
296 STM32CAN* can = STM32CAN::map[STM32_CAN_GetID(hcan->Instance)];
303extern "C" void HAL_CAN_ErrorCallback(CAN_HandleTypeDef* hcan)
305 HAL_CAN_ResetError(hcan);
308extern "C" void HAL_CAN_TxMailbox0CompleteCallback(CAN_HandleTypeDef* hcan)
310 STM32CAN* can = STM32CAN::map[STM32_CAN_GetID(hcan->Instance)];
317extern "C" void HAL_CAN_TxMailbox1CompleteCallback(CAN_HandleTypeDef* hcan)
319 STM32CAN* can = STM32CAN::map[STM32_CAN_GetID(hcan->Instance)];
326extern "C" void HAL_CAN_TxMailbox2CompleteCallback(CAN_HandleTypeDef* hcan)
328 STM32CAN* can = STM32CAN::map[STM32_CAN_GetID(hcan->Instance)];
CAN通信接口,定义标准CAN通信结构,支持不同类型的消息 (CAN communication interface that defines a standard CAN structure supp...
@ EXTENDED
扩展 CAN 消息 (Extended CAN message).
@ REMOTE_EXTENDED
远程扩展 CAN 消息 (Remote extended CAN message).
@ STANDARD
标准 CAN 消息 (Standard CAN message).
@ REMOTE_STANDARD
远程标准 CAN 消息 (Remote standard CAN message).
ErrorCode RecycleSlot(uint32_t index)
回收指定槽位 / Recycle a slot
ErrorCode Put(const Data &data)
向池中放入一个元素 / Put an element into the pool
ErrorCode Get(Data &data)
从池中取出一个元素 / Retrieve an element from the pool
STM32CAN 类,用于处理 STM32 系统的 CAN 通道。 Provides handling for STM32 CAN channels.
STM32CAN(CAN_HandleTypeDef *hcan, uint32_t pool_size)
STM32CAN 类,用于处理 STM32 系统的 CAN 通道。 Provides handling for STM32 CAN.
ErrorCode AddMessage(const ClassicPack &pack) override
添加 CAN 消息到系统 (Adds a CAN message to the system).
void ProcessRxInterrupt()
处理接收中断
void ProcessTxInterrupt()
处理发送中断