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)),
49 tx_queue_(queue_size),
50 tx_queue_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;
167 if (HAL_FDCAN_AddMessageToTxFifoQ(hcan_, &header, pack.data) != HAL_OK)
170 if (tx_queue_.
Push(pack) != ErrorCode::OK)
172 return ErrorCode::FAILED;
176 return ErrorCode::OK;
181 FDCAN_TxHeaderTypeDef header;
182 ASSERT(pack.len <= 64);
184 header.Identifier = pack.id;
189 ASSERT(pack.id <= 0x7FF);
190 header.IdType = FDCAN_STANDARD_ID;
191 header.TxFrameType = FDCAN_DATA_FRAME;
195 ASSERT(pack.id <= 0x1FFFFFFF);
196 header.IdType = FDCAN_EXTENDED_ID;
197 header.TxFrameType = FDCAN_DATA_FRAME;
204 return ErrorCode::FAILED;
209 header.DataLength = FDCAN_PACK_LEN_MAP[pack.len];
211 else if (pack.len <= 24)
213 header.DataLength = FDCAN_PACK_LEN_MAP[(pack.len - 9) / 4 + 1 + 8];
215 else if (pack.len < 32)
217 header.DataLength = FDCAN_DLC_BYTES_32;
219 else if (pack.len < 48)
221 header.DataLength = FDCAN_DLC_BYTES_48;
225 header.DataLength = FDCAN_DLC_BYTES_64;
228 header.ErrorStateIndicator = FDCAN_ESI_PASSIVE;
229 header.BitRateSwitch = FDCAN_BRS_ON;
230 header.FDFormat = FDCAN_FD_CAN;
231 header.TxEventFifoControl = FDCAN_NO_TX_EVENTS;
232 header.MessageMarker = 0x00;
234 if (HAL_FDCAN_AddMessageToTxFifoQ(hcan_, &header, pack.data) != HAL_OK)
237 if (tx_queue_fd_.
Push(pack) != ErrorCode::OK)
239 return ErrorCode::FAILED;
243 return ErrorCode::OK;
248 if (HAL_FDCAN_GetRxMessage(hcan_, fifo, &rx_buff_.header, rx_buff_.pack_fd.data) ==
251 if (rx_buff_.header.FDFormat == FDCAN_FD_CAN)
253 rx_buff_.pack_fd.id = rx_buff_.header.Identifier;
254 rx_buff_.pack_fd.type =
257 if (rx_buff_.header.RxFrameType != FDCAN_DATA_FRAME)
269 rx_buff_.pack_fd.len = rx_buff_.header.DataLength;
271 for (uint32_t i = 0; i < 16; i++)
273 if (rx_buff_.pack_fd.len == FDCAN_PACK_LEN_MAP[i])
275 rx_buff_.pack_fd.len = FDCAN_PACK_LEN_TO_INT_MAP[i];
280 OnMessage(rx_buff_.pack_fd,
true);
284 rx_buff_.pack.id = rx_buff_.header.Identifier;
288 if (rx_buff_.header.RxFrameType != FDCAN_DATA_FRAME)
301 memcpy(rx_buff_.pack.data, rx_buff_.pack_fd.data, 8);
304 OnMessage(rx_buff_.pack,
true);
311 if (tx_queue_fd_.
Peek(tx_buff_.pack_fd) == ErrorCode::OK)
313 tx_buff_.header.Identifier = tx_buff_.pack_fd.id;
314 switch (tx_buff_.pack_fd.type)
317 tx_buff_.header.IdType = FDCAN_STANDARD_ID;
318 tx_buff_.header.TxFrameType = FDCAN_DATA_FRAME;
322 tx_buff_.header.IdType = FDCAN_EXTENDED_ID;
323 tx_buff_.header.TxFrameType = FDCAN_DATA_FRAME;
327 tx_buff_.header.IdType = FDCAN_STANDARD_ID;
328 tx_buff_.header.TxFrameType = FDCAN_REMOTE_FRAME;
332 tx_buff_.header.IdType = FDCAN_EXTENDED_ID;
333 tx_buff_.header.TxFrameType = FDCAN_REMOTE_FRAME;
339 tx_buff_.header.DataLength = tx_buff_.pack_fd.len;
340 tx_buff_.header.ErrorStateIndicator = FDCAN_ESI_PASSIVE;
341 tx_buff_.header.BitRateSwitch = FDCAN_BRS_ON;
342 tx_buff_.header.FDFormat = FDCAN_FD_CAN;
343 tx_buff_.header.TxEventFifoControl = FDCAN_NO_TX_EVENTS;
344 tx_buff_.header.MessageMarker = 0x00;
346 if (HAL_FDCAN_AddMessageToTxFifoQ(hcan_, &tx_buff_.header, tx_buff_.pack_fd.data) ==
352 else if (tx_queue_.
Peek(tx_buff_.pack) == ErrorCode::OK)
354 tx_buff_.header.Identifier = tx_buff_.pack.id;
355 switch (tx_buff_.pack.type)
358 tx_buff_.header.IdType = FDCAN_STANDARD_ID;
359 tx_buff_.header.TxFrameType = FDCAN_DATA_FRAME;
363 tx_buff_.header.IdType = FDCAN_EXTENDED_ID;
364 tx_buff_.header.TxFrameType = FDCAN_DATA_FRAME;
368 tx_buff_.header.IdType = FDCAN_STANDARD_ID;
369 tx_buff_.header.TxFrameType = FDCAN_REMOTE_FRAME;
373 tx_buff_.header.IdType = FDCAN_EXTENDED_ID;
374 tx_buff_.header.TxFrameType = FDCAN_REMOTE_FRAME;
380 tx_buff_.header.DataLength = 8;
381 tx_buff_.header.FDFormat = FDCAN_CLASSIC_CAN;
382 tx_buff_.header.TxFrameType = FDCAN_DATA_FRAME;
383 tx_buff_.header.TxEventFifoControl = FDCAN_NO_TX_EVENTS;
384 tx_buff_.header.MessageMarker = 0x00;
385 tx_buff_.header.ErrorStateIndicator = FDCAN_ESI_PASSIVE;
386 tx_buff_.header.BitRateSwitch = FDCAN_BRS_OFF;
388 if (HAL_FDCAN_AddMessageToTxFifoQ(hcan_, &tx_buff_.header, tx_buff_.pack.data) ==
396extern "C" void HAL_FDCAN_ErrorCallback(FDCAN_HandleTypeDef* hcan)
398 hcan->ErrorCode = HAL_FDCAN_ERROR_NONE;
399 auto can = STM32CANFD::map[STM32_FDCAN_GetID(hcan->Instance)];
402 can->ProcessTxInterrupt();
406extern "C" void HAL_FDCAN_ErrorStatusCallback(FDCAN_HandleTypeDef* hfdcan,
407 uint32_t ErrorStatusITs)
409 if ((ErrorStatusITs & FDCAN_IT_BUS_OFF) != RESET)
411 FDCAN_ProtocolStatusTypeDef protocol_status = {};
412 HAL_FDCAN_GetProtocolStatus(hfdcan, &protocol_status);
413 if (protocol_status.BusOff)
415 CLEAR_BIT(hfdcan->Instance->CCCR, FDCAN_CCCR_INIT);
419 auto can = STM32CANFD::map[STM32_FDCAN_GetID(hfdcan->Instance)];
422 can->ProcessTxInterrupt();
426extern "C" void HAL_FDCAN_TxBufferCompleteCallback(FDCAN_HandleTypeDef* hcan,
427 uint32_t BufferIndexes)
429 UNUSED(BufferIndexes);
430 auto can = STM32CANFD::map[STM32_FDCAN_GetID(hcan->Instance)];
433 can->ProcessTxInterrupt();
437extern "C" void HAL_FDCAN_TxFifoEmptyCallback(FDCAN_HandleTypeDef* hcan)
439 auto can = STM32CANFD::map[STM32_FDCAN_GetID(hcan->Instance)];
442 can->ProcessTxInterrupt();
446extern "C" void HAL_FDCAN_RxFifo0Callback(FDCAN_HandleTypeDef* hcan, uint32_t RxFifo0ITs)
449 auto can = STM32CANFD::map[STM32_FDCAN_GetID(hcan->Instance)];
452 can->ProcessRxInterrupt(FDCAN_RX_FIFO0);
456extern "C" void HAL_FDCAN_RxFifo1Callback(FDCAN_HandleTypeDef* hcan, uint32_t RxFifo1ITs)
459 auto can = STM32CANFD::map[STM32_FDCAN_GetID(hcan->Instance)];
462 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 Pop(ElementData &item)
从队列中弹出数据 / Pops data from the queue
ErrorCode Push(ElementData &&item)
向队列中推入数据 / Pushes data into the queue
ErrorCode Peek(Data &item)
获取队列头部数据但不弹出 / Retrieves the front data of the queue without popping
互斥锁的 RAII 机制封装 (RAII-style mechanism for automatic mutex management).
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()
处理发送中断