libxr 1.0
Want to be the best embedded framework
Loading...
Searching...
No Matches
stm32_can.hpp
1#pragma once
2
3#include "main.h"
4
5#ifdef HAL_CAN_MODULE_ENABLED
6
7#ifdef CAN
8#undef CAN
9#endif
10
11#include "can.hpp"
12#include "libxr.hpp"
13
14typedef enum
15{
16#ifdef CAN1
17 STM32_CAN1,
18#endif
19#ifdef CAN2
20 STM32_CAN2,
21#endif
22#ifdef CAN3
23 STM32_CAN3,
24#endif
25 STM32_CAN_NUMBER,
26 STM32_CAN_ID_ERROR
27} stm32_can_id_t;
28
29stm32_can_id_t STM32_CAN_GetID(CAN_TypeDef* addr); // NOLINT
30
31namespace LibXR
32{
38class STM32CAN : public CAN
39{
40 public:
48 STM32CAN(CAN_HandleTypeDef* hcan, const char* tp_name, uint32_t queue_size)
49 : CAN(tp_name),
50 hcan_(hcan),
51 id_(STM32_CAN_GetID(hcan->Instance)),
52 tx_queue_(queue_size)
53 {
54 map[id_] = this;
55 Init();
56 }
57
63 ErrorCode Init(void)
64 {
65 CAN_FilterTypeDef can_filter = {};
66
67 can_filter.FilterIdHigh = 0;
68 can_filter.FilterIdLow = 0;
69 can_filter.FilterMode = CAN_FILTERMODE_IDMASK;
70 can_filter.FilterScale = CAN_FILTERSCALE_32BIT;
71 can_filter.FilterMaskIdHigh = 0;
72 can_filter.FilterMaskIdLow = 0;
73 can_filter.FilterFIFOAssignment = fifo_;
74 can_filter.FilterActivation = ENABLE;
75#ifdef CAN3
76 if (id_ == STM32_CAN1)
77 {
78 can_filter.FilterBank = 0;
79 can_filter.SlaveStartFilterBank = 14;
80 fifo_ = CAN_RX_FIFO0;
81 }
82 else if (id_ == STM32_CAN2)
83 {
84 can_filter.FilterBank = 14;
85 can_filter.SlaveStartFilterBank = 14;
86 fifo_ = CAN_RX_FIFO0;
87 }
88 else if (id_ == STM32_CAN3)
89 {
90 can_filter.FilterBank = 3;
91 fifo_ = CAN_RX_FIFO1;
92 }
93#else
94#ifdef CAN2
95 if (id_ == STM32_CAN1)
96 {
97 can_filter.FilterBank = 0;
98 can_filter.SlaveStartFilterBank = 14;
99 fifo_ = CAN_RX_FIFO0;
100 }
101 else if (id_ == STM32_CAN2)
102 {
103 can_filter.FilterBank = 14;
104 can_filter.SlaveStartFilterBank = 14;
105 fifo_ = CAN_RX_FIFO1;
106 }
107#else
108 if (id_ == STM32_CAN1)
109 {
110 can_filter.FilterBank = 0;
111 can_filter.SlaveStartFilterBank = 14;
112 fifo_ = CAN_RX_FIFO0;
113 }
114#endif
115#endif
116 else
117 {
118 ASSERT(false);
119 return ErrorCode::FAILED;
120 }
121 can_filter.FilterFIFOAssignment = fifo_;
122
123 if (HAL_CAN_ConfigFilter(hcan_, &can_filter) != HAL_OK)
124 {
125 return ErrorCode::FAILED;
126 }
127
128 if (HAL_CAN_Start(hcan_) != HAL_OK)
129 {
130 return ErrorCode::FAILED;
131 }
132
133 if (fifo_ == CAN_RX_FIFO0)
134 {
135 HAL_CAN_ActivateNotification(hcan_, CAN_IT_RX_FIFO0_MSG_PENDING);
136 }
137 else
138 {
139 HAL_CAN_ActivateNotification(hcan_, CAN_IT_RX_FIFO1_MSG_PENDING);
140 }
141
142 HAL_CAN_ActivateNotification(hcan_, CAN_IT_ERROR);
143 HAL_CAN_ActivateNotification(hcan_, CAN_IT_TX_MAILBOX_EMPTY);
144
145 return ErrorCode::OK;
146 }
147
148 ErrorCode AddMessage(const ClassicPack& pack) override
149 {
150 CAN_TxHeaderTypeDef txHeader; // NOLINT
151
152 txHeader.DLC = sizeof(pack.data);
153
154 switch (pack.type)
155 {
156 case Type::STANDARD:
157 txHeader.IDE = CAN_ID_STD;
158 txHeader.RTR = CAN_RTR_DATA;
159 break;
160 case Type::EXTENDED:
161 txHeader.IDE = CAN_ID_EXT;
162 txHeader.RTR = CAN_RTR_DATA;
163 break;
165 txHeader.IDE = CAN_ID_STD;
166 txHeader.RTR = CAN_RTR_REMOTE;
167 break;
169 txHeader.IDE = CAN_ID_EXT;
170 txHeader.RTR = CAN_RTR_REMOTE;
171 break;
172 }
173 txHeader.StdId = (pack.type == Type::EXTENDED) ? 0 : pack.id;
174 txHeader.ExtId = (pack.type == Type::EXTENDED) ? pack.id : 0;
175 txHeader.TransmitGlobalTime = DISABLE;
176
177 if (HAL_CAN_AddTxMessage(hcan_, &txHeader, pack.data, &txMailbox) != HAL_OK)
178 {
179 if (tx_queue_.Push(pack) != ErrorCode::OK)
180 {
181 return ErrorCode::FULL;
182 }
183 }
184
185 return ErrorCode::OK;
186 }
187
193 {
194 while (HAL_CAN_GetRxMessage(hcan_, fifo_, &rx_buff_.header, rx_buff_.pack.data) ==
195 HAL_OK)
196 {
197 if (rx_buff_.header.IDE == CAN_ID_STD)
198 {
199 rx_buff_.pack.id = rx_buff_.header.StdId;
200 rx_buff_.pack.type = Type::STANDARD;
201 }
202 else
203 {
204 rx_buff_.pack.id = rx_buff_.header.ExtId;
205 rx_buff_.pack.type = Type::EXTENDED;
206 }
207
208 if (rx_buff_.header.RTR == CAN_RTR_REMOTE)
209 {
210 if (rx_buff_.pack.type == Type::STANDARD)
211 {
212 rx_buff_.pack.type = Type::REMOTE_STANDARD;
213 }
214 else
215 {
216 rx_buff_.pack.type = Type::REMOTE_EXTENDED;
217 }
218 }
219
220 classic_tp_.PublishFromCallback(rx_buff_.pack, true);
221 }
222 }
223
229 {
230 if (tx_queue_.Peek(tx_buff_.pack) == ErrorCode::OK)
231 {
232 tx_buff_.header.DLC = sizeof(tx_buff_.pack.data);
233 switch (tx_buff_.pack.type)
234 {
235 case Type::STANDARD:
236 tx_buff_.header.IDE = CAN_ID_STD;
237 tx_buff_.header.RTR = CAN_RTR_DATA;
238 break;
239 case Type::EXTENDED:
240 tx_buff_.header.IDE = CAN_ID_EXT;
241 tx_buff_.header.RTR = CAN_RTR_DATA;
242 break;
244 tx_buff_.header.IDE = CAN_ID_STD;
245 tx_buff_.header.RTR = CAN_RTR_REMOTE;
246 break;
248 tx_buff_.header.IDE = CAN_ID_EXT;
249 tx_buff_.header.RTR = CAN_RTR_REMOTE;
250 break;
251 }
252 tx_buff_.header.StdId =
253 (tx_buff_.pack.type == Type::EXTENDED) ? 0 : tx_buff_.pack.id;
254 tx_buff_.header.ExtId =
255 (tx_buff_.pack.type == Type::EXTENDED) ? tx_buff_.pack.id : 0;
256 tx_buff_.header.TransmitGlobalTime = DISABLE;
257
258 if (HAL_CAN_AddTxMessage(hcan_, &tx_buff_.header, tx_buff_.pack.data, &txMailbox) ==
259 HAL_OK)
260 {
261 tx_queue_.Pop();
262 }
263 }
264 }
265
266 CAN_HandleTypeDef* hcan_;
267
268 stm32_can_id_t id_;
270 uint32_t fifo_;
271 static STM32CAN* map[STM32_CAN_NUMBER]; // NOLINT
272
273 struct
274 {
275 CAN_RxHeaderTypeDef header;
276 ClassicPack pack;
277 } rx_buff_;
278
279 struct
280 {
281 CAN_TxHeaderTypeDef header;
282 ClassicPack pack;
283 } tx_buff_;
284
285 uint32_t txMailbox;
286};
287} // namespace LibXR
288
289#endif
CAN通信接口,定义标准CAN通信结构,支持不同类型的消息 (CAN communication interface that defines a standard CAN structure supp...
Definition can.hpp:14
@ EXTENDED
扩展 CAN 消息 (Extended CAN message).
@ REMOTE_EXTENDED
远程扩展 CAN 消息 (Remote extended CAN message).
@ STANDARD
标准 CAN 消息 (Standard CAN message).
@ REMOTE_STANDARD
远程标准 CAN 消息 (Remote standard CAN message).
Topic classic_tp_
经典 CAN 消息的主题 (Topic for classic CAN messages).
Definition can.hpp:48
无锁队列实现 / Lock-free queue implementation
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
STM32CAN 类,用于处理 STM32 系统的 CAN 通道。 Provides handling for STM32 CAN channels.
Definition stm32_can.hpp:39
ErrorCode AddMessage(const ClassicPack &pack) override
添加 CAN 消息到系统 (Adds a CAN message to the system).
STM32CAN(CAN_HandleTypeDef *hcan, const char *tp_name, uint32_t queue_size)
STM32CAN 类,用于处理 STM32 系统的 CAN 通道。 Provides handling for STM32 CAN.
Definition stm32_can.hpp:48
ErrorCode Init(void)
初始化
Definition stm32_can.hpp:63
void ProcessRxInterrupt()
处理接收中断
void ProcessTxInterrupt()
处理发送中断
void PublishFromCallback(Data &data, bool in_isr)
从回调函数发布数据 Publishes data from a callback function
Definition message.hpp:661
LibXR Color Control Library / LibXR终端颜色控制库