1#include "stm32_canfd.hpp"
3#ifdef HAL_FDCAN_MODULE_ENABLED
7STM32CANFD* STM32CANFD::map[STM32_FDCAN_NUMBER] = {
nullptr};
15stm32_fdcan_id_t STM32_FDCAN_GetID(FDCAN_GlobalTypeDef* addr)
19 return stm32_fdcan_id_t::STM32_FDCAN_ID_ERROR;
22 else if (addr == FDCAN1)
24 return stm32_fdcan_id_t::STM32_FDCAN1;
28 else if (addr == FDCAN2)
30 return stm32_fdcan_id_t::STM32_FDCAN2;
34 else if (addr == FDCAN3)
36 return stm32_fdcan_id_t::STM32_FDCAN3;
41 return stm32_fdcan_id_t::STM32_FDCAN_ID_ERROR;
48 id_(STM32_FDCAN_GetID(hcan->Instance)),
50 tx_pool_fd_(queue_size)
58 FDCAN_FilterTypeDef can_filter = {};
59 can_filter.IdType = FDCAN_STANDARD_ID;
60 can_filter.FilterType = FDCAN_FILTER_MASK;
61 can_filter.FilterID1 = 0x0000;
62 can_filter.FilterID2 = 0x0000;
63 can_filter.FilterIndex = 0;
66 if (id_ == STM32_FDCAN1)
68 can_filter.FilterConfig = FDCAN_FILTER_TO_RXFIFO0;
70 else if (id_ == STM32_FDCAN2)
72 can_filter.FilterConfig = FDCAN_FILTER_TO_RXFIFO1;
74 else if (id_ == STM32_FDCAN3)
76 can_filter.FilterConfig = FDCAN_FILTER_TO_RXFIFO1;
80 if (id_ == STM32_FDCAN1)
82 can_filter.FilterConfig = FDCAN_FILTER_TO_RXFIFO0;
84 else if (id_ == STM32_FDCAN2)
86 can_filter.FilterConfig = FDCAN_FILTER_TO_RXFIFO1;
89 can_filter.FilterConfig = FDCAN_FILTER_TO_RXFIFO0;
93 if (HAL_FDCAN_ConfigFilter(hcan_, &can_filter) != HAL_OK)
95 return ErrorCode::FAILED;
98 can_filter.IdType = FDCAN_EXTENDED_ID;
100 if (HAL_FDCAN_ConfigFilter(hcan_, &can_filter) != HAL_OK)
102 return ErrorCode::FAILED;
105 if (HAL_FDCAN_Start(hcan_) != HAL_OK)
107 return ErrorCode::FAILED;
110 if (can_filter.FilterConfig == FDCAN_FILTER_TO_RXFIFO0)
112 HAL_FDCAN_ActivateNotification(hcan_, FDCAN_IT_RX_FIFO0_NEW_MESSAGE, 0);
116 HAL_FDCAN_ActivateNotification(hcan_, FDCAN_IT_RX_FIFO1_NEW_MESSAGE, 0);
119 HAL_FDCAN_ActivateNotification(hcan_, FDCAN_IT_TX_FIFO_EMPTY, 0);
121 return ErrorCode::OK;
126 FDCAN_TxHeaderTypeDef header;
128 header.Identifier = pack.id;
133 ASSERT(pack.id <= 0x7FF);
134 header.IdType = FDCAN_STANDARD_ID;
135 header.TxFrameType = FDCAN_DATA_FRAME;
139 ASSERT(pack.id <= 0x1FFFFFFF);
140 header.IdType = FDCAN_EXTENDED_ID;
141 header.TxFrameType = FDCAN_DATA_FRAME;
145 ASSERT(pack.id <= 0x7FF);
146 header.IdType = FDCAN_STANDARD_ID;
147 header.TxFrameType = FDCAN_REMOTE_FRAME;
151 ASSERT(pack.id <= 0x1FFFFFFF);
152 header.IdType = FDCAN_EXTENDED_ID;
153 header.TxFrameType = FDCAN_REMOTE_FRAME;
157 return ErrorCode::FAILED;
160 header.DataLength = FDCAN_DLC_BYTES_8;
161 header.ErrorStateIndicator = FDCAN_ESI_PASSIVE;
162 header.BitRateSwitch = FDCAN_BRS_OFF;
163 header.FDFormat = FDCAN_CLASSIC_CAN;
164 header.TxEventFifoControl = FDCAN_NO_TX_EVENTS;
165 header.MessageMarker = 0x01;
171 if (HAL_FDCAN_AddMessageToTxFifoQ(hcan_, &header, pack.data) != HAL_OK)
173 if (tx_pool_.
Put(pack, slot) != ErrorCode::OK)
175 return ErrorCode::FAILED;
180 return ErrorCode::OK;
183 if (bus_busy_.load(std::memory_order_acquire) == 0 &&
190 return ErrorCode::OK;
197 FDCAN_TxHeaderTypeDef header;
198 ASSERT(pack.len <= 64);
200 header.Identifier = pack.id;
205 ASSERT(pack.id <= 0x7FF);
206 header.IdType = FDCAN_STANDARD_ID;
207 header.TxFrameType = FDCAN_DATA_FRAME;
211 ASSERT(pack.id <= 0x1FFFFFFF);
212 header.IdType = FDCAN_EXTENDED_ID;
213 header.TxFrameType = FDCAN_DATA_FRAME;
220 return ErrorCode::FAILED;
225 header.DataLength = FDCAN_PACK_LEN_MAP[pack.len];
227 else if (pack.len <= 24)
229 header.DataLength = FDCAN_PACK_LEN_MAP[(pack.len - 9) / 4 + 1 + 8];
231 else if (pack.len < 32)
233 header.DataLength = FDCAN_DLC_BYTES_32;
235 else if (pack.len < 48)
237 header.DataLength = FDCAN_DLC_BYTES_48;
241 header.DataLength = FDCAN_DLC_BYTES_64;
244 header.ErrorStateIndicator = FDCAN_ESI_PASSIVE;
245 header.BitRateSwitch = FDCAN_BRS_ON;
246 header.FDFormat = FDCAN_FD_CAN;
247 header.TxEventFifoControl = FDCAN_NO_TX_EVENTS;
248 header.MessageMarker = 0x00;
254 if (HAL_FDCAN_AddMessageToTxFifoQ(hcan_, &header, pack.data) != HAL_OK)
256 if (tx_pool_fd_.
Put(pack, slot) != ErrorCode::OK)
258 return ErrorCode::FAILED;
263 return ErrorCode::OK;
266 if (bus_busy_.load(std::memory_order_acquire) == 0 &&
273 return ErrorCode::OK;
280 if (HAL_FDCAN_GetRxMessage(hcan_, fifo, &rx_buff_.header, rx_buff_.pack_fd.data) ==
283 if (rx_buff_.header.FDFormat == FDCAN_FD_CAN)
285 rx_buff_.pack_fd.id = rx_buff_.header.Identifier;
286 rx_buff_.pack_fd.type =
289 if (rx_buff_.header.RxFrameType != FDCAN_DATA_FRAME)
301 rx_buff_.pack_fd.len = rx_buff_.header.DataLength;
303 for (uint32_t i = 0; i < 16; i++)
305 if (rx_buff_.pack_fd.len == FDCAN_PACK_LEN_MAP[i])
307 rx_buff_.pack_fd.len = FDCAN_PACK_LEN_TO_INT_MAP[i];
312 OnMessage(rx_buff_.pack_fd,
true);
316 rx_buff_.pack.id = rx_buff_.header.Identifier;
320 if (rx_buff_.header.RxFrameType != FDCAN_DATA_FRAME)
333 memcpy(rx_buff_.pack.data, rx_buff_.pack_fd.data, 8);
336 OnMessage(rx_buff_.pack,
true);
343 if (tx_pool_fd_.
Get(tx_buff_.pack_fd) == ErrorCode::OK)
345 tx_buff_.header.Identifier = tx_buff_.pack_fd.id;
346 switch (tx_buff_.pack_fd.type)
349 tx_buff_.header.IdType = FDCAN_STANDARD_ID;
350 tx_buff_.header.TxFrameType = FDCAN_DATA_FRAME;
354 tx_buff_.header.IdType = FDCAN_EXTENDED_ID;
355 tx_buff_.header.TxFrameType = FDCAN_DATA_FRAME;
359 tx_buff_.header.IdType = FDCAN_STANDARD_ID;
360 tx_buff_.header.TxFrameType = FDCAN_REMOTE_FRAME;
364 tx_buff_.header.IdType = FDCAN_EXTENDED_ID;
365 tx_buff_.header.TxFrameType = FDCAN_REMOTE_FRAME;
371 tx_buff_.header.DataLength = tx_buff_.pack_fd.len;
372 tx_buff_.header.ErrorStateIndicator = FDCAN_ESI_PASSIVE;
373 tx_buff_.header.BitRateSwitch = FDCAN_BRS_ON;
374 tx_buff_.header.FDFormat = FDCAN_FD_CAN;
375 tx_buff_.header.TxEventFifoControl = FDCAN_NO_TX_EVENTS;
376 tx_buff_.header.MessageMarker = 0x00;
378 HAL_FDCAN_AddMessageToTxFifoQ(hcan_, &tx_buff_.header, tx_buff_.pack_fd.data);
379 bus_busy_.store(UINT32_MAX, std::memory_order_release);
381 else if (tx_pool_.
Get(tx_buff_.pack) == ErrorCode::OK)
383 tx_buff_.header.Identifier = tx_buff_.pack.id;
384 switch (tx_buff_.pack.type)
387 tx_buff_.header.IdType = FDCAN_STANDARD_ID;
388 tx_buff_.header.TxFrameType = FDCAN_DATA_FRAME;
392 tx_buff_.header.IdType = FDCAN_EXTENDED_ID;
393 tx_buff_.header.TxFrameType = FDCAN_DATA_FRAME;
397 tx_buff_.header.IdType = FDCAN_STANDARD_ID;
398 tx_buff_.header.TxFrameType = FDCAN_REMOTE_FRAME;
402 tx_buff_.header.IdType = FDCAN_EXTENDED_ID;
403 tx_buff_.header.TxFrameType = FDCAN_REMOTE_FRAME;
409 tx_buff_.header.DataLength = 8;
410 tx_buff_.header.FDFormat = FDCAN_CLASSIC_CAN;
411 tx_buff_.header.TxFrameType = FDCAN_DATA_FRAME;
412 tx_buff_.header.TxEventFifoControl = FDCAN_NO_TX_EVENTS;
413 tx_buff_.header.MessageMarker = 0x00;
414 tx_buff_.header.ErrorStateIndicator = FDCAN_ESI_PASSIVE;
415 tx_buff_.header.BitRateSwitch = FDCAN_BRS_OFF;
417 HAL_FDCAN_AddMessageToTxFifoQ(hcan_, &tx_buff_.header, tx_buff_.pack.data);
418 bus_busy_.store(UINT32_MAX, std::memory_order_release);
421 if (hcan_->Init.TxFifoQueueElmtsNbr - HAL_FDCAN_GetTxFifoFreeLevel(hcan_) == 0)
423 bus_busy_.store(0, std::memory_order_release);
427extern "C" void HAL_FDCAN_ErrorCallback(FDCAN_HandleTypeDef* hcan)
429 hcan->ErrorCode = HAL_FDCAN_ERROR_NONE;
430 auto can = STM32CANFD::map[STM32_FDCAN_GetID(hcan->Instance)];
433 can->ProcessTxInterrupt();
437extern "C" void HAL_FDCAN_ErrorStatusCallback(FDCAN_HandleTypeDef* hfdcan,
438 uint32_t ErrorStatusITs)
440 if ((ErrorStatusITs & FDCAN_IT_BUS_OFF) != RESET)
442 FDCAN_ProtocolStatusTypeDef protocol_status = {};
443 HAL_FDCAN_GetProtocolStatus(hfdcan, &protocol_status);
444 if (protocol_status.BusOff)
446 CLEAR_BIT(hfdcan->Instance->CCCR, FDCAN_CCCR_INIT);
450 auto can = STM32CANFD::map[STM32_FDCAN_GetID(hfdcan->Instance)];
453 can->ProcessTxInterrupt();
457extern "C" void HAL_FDCAN_TxBufferCompleteCallback(FDCAN_HandleTypeDef* hcan,
458 uint32_t BufferIndexes)
460 UNUSED(BufferIndexes);
461 auto can = STM32CANFD::map[STM32_FDCAN_GetID(hcan->Instance)];
464 can->ProcessTxInterrupt();
468extern "C" void HAL_FDCAN_TxFifoEmptyCallback(FDCAN_HandleTypeDef* hcan)
470 auto can = STM32CANFD::map[STM32_FDCAN_GetID(hcan->Instance)];
473 can->ProcessTxInterrupt();
477extern "C" void HAL_FDCAN_RxFifo0Callback(FDCAN_HandleTypeDef* hcan, uint32_t RxFifo0ITs)
480 auto can = STM32CANFD::map[STM32_FDCAN_GetID(hcan->Instance)];
483 can->ProcessRxInterrupt(FDCAN_RX_FIFO0);
487extern "C" void HAL_FDCAN_RxFifo1Callback(FDCAN_HandleTypeDef* hcan, uint32_t RxFifo1ITs)
490 auto can = STM32CANFD::map[STM32_FDCAN_GetID(hcan->Instance)];
493 can->ProcessRxInterrupt(FDCAN_RX_FIFO1);
@ EXTENDED
扩展 CAN 消息 (Extended CAN message).
@ REMOTE_EXTENDED
远程扩展 CAN 消息 (Remote extended CAN message).
@ STANDARD
标准 CAN 消息 (Standard CAN message).
@ REMOTE_STANDARD
远程标准 CAN 消息 (Remote standard CAN message).
FDCAN 通信接口,扩展 CAN 功能,支持灵活数据速率(FD)CAN 消息 (FDCAN communication interface that extends CAN functionality...
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
STM32CANFD 类,用于处理 STM32 系统的 CANFD 通道。 Provides handling for STM32 CANFD.
void ProcessRxInterrupt(uint32_t fifo)
处理接收中断
STM32CANFD(FDCAN_HandleTypeDef *hcan, uint32_t queue_size)
STM32CANFD 类,用于处理 STM32 系统的 CANFD 通道。 Provides handling for STM32 CANFD.
ErrorCode AddMessage(const ClassicPack &pack) override
添加 CAN 消息到系统 (Adds a CAN message to the system).
void ProcessTxInterrupt()
处理发送中断