1 /*!
2 \file gd32e50x_can.c
3 \brief CAN driver
4
5 \version 2020-03-10, V1.0.0, firmware for GD32E50x
6 \version 2021-03-23, V1.2.0, firmware for GD32E50x
7 */
8
9 /*
10 Copyright (c) 2021, GigaDevice Semiconductor Inc.
11
12 Redistribution and use in source and binary forms, with or without modification,
13 are permitted provided that the following conditions are met:
14
15 1. Redistributions of source code must retain the above copyright notice, this
16 list of conditions and the following disclaimer.
17 2. Redistributions in binary form must reproduce the above copyright notice,
18 this list of conditions and the following disclaimer in the documentation
19 and/or other materials provided with the distribution.
20 3. Neither the name of the copyright holder nor the names of its contributors
21 may be used to endorse or promote products derived from this software without
22 specific prior written permission.
23
24 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
25 AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
26 WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
27 IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
28 INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
29 NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
30 PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
31 WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
32 ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
33 OF SUCH DAMAGE.
34 */
35
36 #include "gd32e50x_can.h"
37 #include <stdlib.h>
38
39 #define CAN_ERROR_HANDLE(s) do{}while(1)
40
41 #ifdef GD32E508
42 /* BS1[6:0] + BS2[4:0] */
43 #define DEV_CAN_BT_SEG_MAX 158U
44 #define DEV_CAN_BT_SEG_MIN 3U
45
46 /* BS1[3:0] + BS2[2:0] */
47 #define DEV_CAN_FD_BT_SEG_MAX 22U
48 #define DEV_CAN_FD_BT_SEG_MIN 3U
49
50 /* CAN related register mask */
51 #define DEV_CAN_BS1_MASK 0x000F0000U
52 #define DEV_CAN_BS2_MASK 0x00700000U
53 #define DEV_CAN_FD_SJW_MASK 0x07000000U
54 #else
55 /* BS1[3:0] + BS2[2:0] */
56 #define DEV_CAN_BT_SEG_MAX 22U
57 #define DEV_CAN_BT_SEG_MIN 3U
58 #endif /* GD32E508 */
59
60 /* CAN related register mask */
61 #define DEV_CAN_BAUDPSC_MASK 0x000003FFU
62 #define DEV_CAN_SJW_MASK 0x1F000000U
63
64
65 /* This table can be used to calculate data length in FD mode */
66 const uint8_t g_can_fdlength_table[] = {12, 16, 20, 24, 32, 48, 64};
67
68 #ifdef GD32E508
69 /* This table can be used to calculate bit time: timing_pts{BS1[3:0], BS2[2:0]} */
70 static const uint32_t timing_pts[23][2] = {
71 {0x0, 0x0}, /* 2, 50% */
72 {0x1, 0x0}, /* 3, 67% */
73 {0x2, 0x0}, /* 4, 75% */
74 {0x3, 0x0}, /* 5, 80% */
75 {0x3, 0x1}, /* 6, 67% */
76 {0x4, 0x1}, /* 7, 71% */
77 {0x5, 0x1}, /* 8, 75% */
78 {0x6, 0x1}, /* 9, 78% */
79 {0x6, 0x2}, /* 10, 70% */
80 {0x7, 0x2}, /* 11, 73% */
81 {0x8, 0x2}, /* 12, 75% */
82 {0x9, 0x2}, /* 13, 77% */
83 {0x9, 0x3}, /* 14, 71% */
84 {0xA, 0x3}, /* 15, 73% */
85 {0xB, 0x3}, /* 16, 75% */
86 {0xC, 0x3}, /* 17, 76% */
87 {0xD, 0x3}, /* 18, 78% */
88 {0xD, 0x4}, /* 19, 74% */
89 {0xE, 0x4}, /* 20, 75% */
90 {0xF, 0x4}, /* 21, 76% */
91 {0xF, 0x5}, /* 22, 73% */
92 {0xF, 0x6}, /* 23, 70% */
93 {0xF, 0x7}, /* 24, 67% */
94 };
95 #endif /* GD32E508 */
96
97 static unsigned int dev_can_baudrate_set(uint32_t freq);
98 #ifdef GD32E508
99 static unsigned int dev_can_fd_baudrate_set(uint32_t freq);
100 #endif /* GD32E508 */
101 /*!
102 \brief deinitialize CAN
103 \param[in] can_periph
104 \arg CANx(x=0,1,2),the CAN2 only for GD32E50X_CL and GD32E508
105 \param[out] none
106 \retval none
107 */
can_deinit(uint32_t can_periph)108 void can_deinit(uint32_t can_periph)
109 {
110 #if defined(GD32E50X_CL) || defined(GD32E508)
111 switch(can_periph){
112 case CAN0:
113 rcu_periph_reset_enable(RCU_CAN0RST);
114 rcu_periph_reset_disable(RCU_CAN0RST);
115 break;
116 case CAN1:
117 rcu_periph_reset_enable(RCU_CAN1RST);
118 rcu_periph_reset_disable(RCU_CAN1RST);
119 break;
120 case CAN2:
121 rcu_periph_reset_enable(RCU_CAN2RST);
122 rcu_periph_reset_disable(RCU_CAN2RST);
123 break;
124 default:
125 break;
126 }
127 #else
128 switch(can_periph){
129 case CAN0:
130 rcu_periph_reset_enable(RCU_CAN0RST);
131 rcu_periph_reset_disable(RCU_CAN0RST);
132 break;
133 case CAN1:
134 rcu_periph_reset_enable(RCU_CAN1RST);
135 rcu_periph_reset_disable(RCU_CAN1RST);
136 break;
137 default:
138 break;
139 }
140 #endif
141 }
142
143 /*!
144 \brief initialize CAN parameter struct
145 \param[in] type: the type of CAN parameter struct
146 only one parameter can be selected which is shown as below:
147 \arg CAN_INIT_STRUCT: the CAN initial struct
148 \arg CAN_FILTER_STRUCT: the CAN filter struct
149 \arg CAN_FD_FRAME_STRUCT: the CAN FD initial struct
150 \arg CAN_TX_MESSAGE_STRUCT: the CAN TX message struct
151 \arg CAN_RX_MESSAGE_STRUCT: the CAN RX message struct
152 \param[in] p_struct: the pointer of the specific struct
153 \param[out] none
154 \retval none
155 */
can_struct_para_init(can_struct_type_enum type,void * p_struct)156 void can_struct_para_init(can_struct_type_enum type, void* p_struct)
157 {
158 uint8_t i;
159
160 if(NULL == p_struct){
161 CAN_ERROR_HANDLE("struct parameter can not be NULL \r\n");
162 }
163 /* get type of the struct */
164 switch(type){
165 /* used for can_init() */
166 case CAN_INIT_STRUCT:
167 ((can_parameter_struct*)p_struct)->auto_bus_off_recovery = DISABLE;
168 ((can_parameter_struct*)p_struct)->auto_retrans = DISABLE;
169 ((can_parameter_struct*)p_struct)->auto_wake_up = DISABLE;
170 ((can_parameter_struct*)p_struct)->prescaler = 0x0400U;
171 ((can_parameter_struct*)p_struct)->rec_fifo_overwrite = DISABLE;
172 ((can_parameter_struct*)p_struct)->resync_jump_width = CAN_BT_SJW_1TQ;
173 ((can_parameter_struct*)p_struct)->time_segment_1 = CAN_BT_BS1_3TQ;
174 ((can_parameter_struct*)p_struct)->time_segment_2 = CAN_BT_BS2_1TQ;
175 ((can_parameter_struct*)p_struct)->time_triggered = DISABLE;
176 ((can_parameter_struct*)p_struct)->trans_fifo_order = DISABLE;
177 ((can_parameter_struct*)p_struct)->working_mode = CAN_NORMAL_MODE;
178
179 break;
180 /* used for can_filter_init() */
181 case CAN_FILTER_STRUCT:
182 ((can_filter_parameter_struct*)p_struct)->filter_bits = CAN_FILTERBITS_32BIT;
183 ((can_filter_parameter_struct*)p_struct)->filter_enable = DISABLE;
184 ((can_filter_parameter_struct*)p_struct)->filter_fifo_number = CAN_FIFO0;
185 ((can_filter_parameter_struct*)p_struct)->filter_list_high = 0x0000U;
186 ((can_filter_parameter_struct*)p_struct)->filter_list_low = 0x0000U;
187 ((can_filter_parameter_struct*)p_struct)->filter_mask_high = 0x0000U;
188 ((can_filter_parameter_struct*)p_struct)->filter_mask_low = 0x0000U;
189 ((can_filter_parameter_struct*)p_struct)->filter_mode = CAN_FILTERMODE_MASK;
190 ((can_filter_parameter_struct*)p_struct)->filter_number = 0U;
191
192 break;
193 #ifdef GD32E508
194 /* used for can_fd_init() */
195 case CAN_FD_FRAME_STRUCT:
196 ((can_fdframe_struct*)p_struct)->data_prescaler = 0x0400U;
197 ((can_fdframe_struct*)p_struct)->data_resync_jump_width = 1U - 1U;
198 ((can_fdframe_struct*)p_struct)->data_time_segment_1 = 3U - 1U;
199 ((can_fdframe_struct*)p_struct)->data_time_segment_2 = 2U - 1U;
200 ((can_fdframe_struct*)p_struct)->delay_compensation = DISABLE;
201 ((can_fdframe_struct*)p_struct)->esi_mode = CAN_ESIMOD_HARDWARE;
202 ((can_fdframe_struct*)p_struct)->excp_event_detect = ENABLE;
203 ((can_fdframe_struct*)p_struct)->fd_frame = DISABLE;
204 ((can_fdframe_struct*)p_struct)->iso_bosch = CAN_FDMOD_ISO;
205 ((can_fdframe_struct*)p_struct)->p_delay_compensation = 0U;
206
207 break;
208 /* used for can_message_transmit() */
209 case CAN_TX_MESSAGE_STRUCT:
210 ((can_trasnmit_message_struct*)p_struct)->fd_brs = CAN_BRS_DISABLE;
211 ((can_trasnmit_message_struct*)p_struct)->fd_esi = CAN_ESI_DOMINANT;
212 ((can_trasnmit_message_struct*)p_struct)->fd_flag = CAN_FDF_CLASSIC;
213
214 for(i = 0U; i < 64U; i++){
215 ((can_trasnmit_message_struct*)p_struct)->tx_data[i] = 0U;
216 }
217
218 ((can_trasnmit_message_struct*)p_struct)->tx_dlen = 0u;
219 ((can_trasnmit_message_struct*)p_struct)->tx_efid = 0U;
220 ((can_trasnmit_message_struct*)p_struct)->tx_ff = (uint8_t)CAN_FF_STANDARD;
221 ((can_trasnmit_message_struct*)p_struct)->tx_ft = (uint8_t)CAN_FT_DATA;
222 ((can_trasnmit_message_struct*)p_struct)->tx_sfid = 0U;
223
224 break;
225 /* used for can_message_receive() */
226 case CAN_RX_MESSAGE_STRUCT:
227 ((can_receive_message_struct*)p_struct)->fd_brs = CAN_BRS_DISABLE;
228 ((can_receive_message_struct*)p_struct)->fd_esi = CAN_ESI_DOMINANT;
229 ((can_receive_message_struct*)p_struct)->fd_flag = CAN_FDF_CLASSIC;
230
231 for(i = 0U; i < 64U; i++){
232 ((can_receive_message_struct*)p_struct)->rx_data[i] = 0U;
233 }
234
235 ((can_receive_message_struct*)p_struct)->rx_dlen = 0U;
236 ((can_receive_message_struct*)p_struct)->rx_efid = 0U;
237 ((can_receive_message_struct*)p_struct)->rx_ff = (uint8_t)CAN_FF_STANDARD;
238 ((can_receive_message_struct*)p_struct)->rx_fi = 0U;
239 ((can_receive_message_struct*)p_struct)->rx_ft = (uint8_t)CAN_FT_DATA;
240 ((can_receive_message_struct*)p_struct)->rx_sfid = 0U;
241
242 break;
243 #else
244 /* used for can_message_transmit() */
245 case CAN_TX_MESSAGE_STRUCT:
246 for(i = 0U; i < 8U; i++){
247 ((can_trasnmit_message_struct*)p_struct)->tx_data[i] = 0U;
248 }
249
250 ((can_trasnmit_message_struct*)p_struct)->tx_dlen = 0u;
251 ((can_trasnmit_message_struct*)p_struct)->tx_efid = 0U;
252 ((can_trasnmit_message_struct*)p_struct)->tx_ff = (uint8_t)CAN_FF_STANDARD;
253 ((can_trasnmit_message_struct*)p_struct)->tx_ft = (uint8_t)CAN_FT_DATA;
254 ((can_trasnmit_message_struct*)p_struct)->tx_sfid = 0U;
255
256 break;
257 /* used for can_message_receive() */
258 case CAN_RX_MESSAGE_STRUCT:
259 for(i = 0U; i < 8U; i++){
260 ((can_receive_message_struct*)p_struct)->rx_data[i] = 0U;
261 }
262
263 ((can_receive_message_struct*)p_struct)->rx_dlen = 0U;
264 ((can_receive_message_struct*)p_struct)->rx_efid = 0U;
265 ((can_receive_message_struct*)p_struct)->rx_ff = (uint8_t)CAN_FF_STANDARD;
266 ((can_receive_message_struct*)p_struct)->rx_fi = 0U;
267 ((can_receive_message_struct*)p_struct)->rx_ft = (uint8_t)CAN_FT_DATA;
268 ((can_receive_message_struct*)p_struct)->rx_sfid = 0U;
269
270 break;
271
272 #endif /* GD32E508 */
273 default:
274 CAN_ERROR_HANDLE("parameter is invalid \r\n");
275 }
276 }
277
278 /*!
279 \brief initialize CAN
280 \param[in] can_periph
281 \arg CANx(x=0,1,2),the CAN2 only for GD32E50X_CL and GD32E508
282 \param[in] can_parameter_init: parameters for CAN initializtion
283 \arg working_mode: CAN_NORMAL_MODE, CAN_LOOPBACK_MODE, CAN_SILENT_MODE, CAN_SILENT_LOOPBACK_MODE
284 \arg resync_jump_width: 0x00 - 0x07
285 \arg time_segment_1: 0x00 - 0x7F
286 \arg time_segment_2: 0x00 - 0x1F
287 \arg time_triggered: ENABLE or DISABLE
288 \arg auto_bus_off_recovery: ENABLE or DISABLE
289 \arg auto_wake_up: ENABLE or DISABLE
290 \arg auto_retrans: ENABLE or DISABLE
291 \arg rec_fifo_overwrite: ENABLE or DISABLE
292 \arg trans_fifo_order: ENABLE or DISABLE
293 \arg prescaler: 0x0001 - 0x0400
294 \param[out] none
295 \retval ErrStatus: SUCCESS or ERROR
296 */
can_init(uint32_t can_periph,can_parameter_struct * can_parameter_init)297 ErrStatus can_init(uint32_t can_periph, can_parameter_struct* can_parameter_init)
298 {
299 uint32_t timeout = CAN_TIMEOUT;
300 ErrStatus flag = ERROR;
301 #ifdef GD32E508
302 uint32_t fdctl_status;
303 #endif /* GD32E508 */
304
305 /* disable sleep mode */
306 CAN_CTL(can_periph) &= ~CAN_CTL_SLPWMOD;
307 /* enable initialize mode */
308 CAN_CTL(can_periph) |= CAN_CTL_IWMOD;
309 /* wait ACK */
310 while((CAN_STAT_IWS != (CAN_STAT(can_periph) & CAN_STAT_IWS)) && (0U != timeout)){
311 timeout--;
312 }
313 /* check initialize working success */
314 if(CAN_STAT_IWS != (CAN_STAT(can_periph) & CAN_STAT_IWS)){
315 flag = ERROR;
316 }else{
317 #ifdef GD32E508
318 /* set the bit timing register */
319 fdctl_status = CAN_FDCTL(can_periph);
320 if(CAN_FDCTL_FDEN != (fdctl_status&CAN_FDCTL_FDEN)){
321 /* CAN FD disable, should frist enable, then write */
322 fdctl_status = fdctl_status | CAN_FDCTL_FDEN;
323 CAN_FDCTL(can_periph) = fdctl_status;
324 CAN_BT(can_periph) = (BT_MODE((uint32_t)can_parameter_init->working_mode) | \
325 BT_SJW((uint32_t)can_parameter_init->resync_jump_width) | \
326 BT_BS1((uint32_t)can_parameter_init->time_segment_1) | \
327 BT_BS2((uint32_t)can_parameter_init->time_segment_2) | \
328 BT_BAUDPSC(((uint32_t)(can_parameter_init->prescaler) - 1U)));
329 fdctl_status = fdctl_status & (~CAN_FDCTL_FDEN);
330 CAN_FDCTL(can_periph) = fdctl_status;
331 }else{
332 /* CAN FD enable */
333 CAN_BT(can_periph) = (BT_MODE((uint32_t)can_parameter_init->working_mode) | \
334 BT_SJW((uint32_t)can_parameter_init->resync_jump_width) | \
335 BT_BS1((uint32_t)can_parameter_init->time_segment_1) | \
336 BT_BS2((uint32_t)can_parameter_init->time_segment_2) | \
337 BT_BAUDPSC(((uint32_t)(can_parameter_init->prescaler) - 1U)));
338 }
339 #else
340 /* set the bit timing register */
341 CAN_BT(can_periph) = (BT_MODE((uint32_t)can_parameter_init->working_mode) | \
342 BT_SJW((uint32_t)can_parameter_init->resync_jump_width) | \
343 BT_BS1((uint32_t)can_parameter_init->time_segment_1) | \
344 BT_BS2((uint32_t)can_parameter_init->time_segment_2) | \
345 BT_BAUDPSC(((uint32_t)(can_parameter_init->prescaler) - 1U)));
346
347 #endif /* GD32E508 */
348 /* time trigger communication mode */
349 if(ENABLE == can_parameter_init->time_triggered){
350 CAN_CTL(can_periph) |= CAN_CTL_TTC;
351 }else{
352 CAN_CTL(can_periph) &= ~CAN_CTL_TTC;
353 }
354 /* automatic bus-off managment */
355 if(ENABLE == can_parameter_init->auto_bus_off_recovery){
356 CAN_CTL(can_periph) |= CAN_CTL_ABOR;
357 }else{
358 CAN_CTL(can_periph) &= ~CAN_CTL_ABOR;
359 }
360 /* automatic wakeup mode */
361 if(ENABLE == can_parameter_init->auto_wake_up){
362 CAN_CTL(can_periph) |= CAN_CTL_AWU;
363 }else{
364 CAN_CTL(can_periph) &= ~CAN_CTL_AWU;
365 }
366 /* automatic retransmission mode */
367 if(ENABLE == can_parameter_init->auto_retrans){
368 CAN_CTL(can_periph) &= ~CAN_CTL_ARD;
369 }else{
370 CAN_CTL(can_periph) |= CAN_CTL_ARD;
371 }
372 /* receive fifo overwrite mode */
373 if(ENABLE == can_parameter_init->rec_fifo_overwrite){
374 CAN_CTL(can_periph) |= CAN_CTL_RFOD;
375 }else{
376 CAN_CTL(can_periph) &= ~CAN_CTL_RFOD;
377 }
378 /* transmit fifo order */
379 if(ENABLE == can_parameter_init->trans_fifo_order){
380 CAN_CTL(can_periph) |= CAN_CTL_TFO;
381 }else{
382 CAN_CTL(can_periph) &= ~CAN_CTL_TFO;
383 }
384 /* disable initialize mode */
385 CAN_CTL(can_periph) &= ~CAN_CTL_IWMOD;
386 timeout = CAN_TIMEOUT;
387 /* wait the ACK */
388 while((CAN_STAT_IWS == (CAN_STAT(can_periph) & CAN_STAT_IWS)) && (0U != timeout)){
389 timeout--;
390 }
391 /* check exit initialize mode */
392 if(0U != timeout){
393 flag = SUCCESS;
394 }
395 }
396 return flag;
397 }
398
399 /*!
400 \brief initialize CAN filter
401 \param[in] can_periph
402 \arg CANx(x=0,2),the CAN2 only for GD32E50X_CL and GD32E508
403 \param[in] can_filter_parameter_init: struct for CAN filter initialization
404 \arg filter_list_high: 0x0000 - 0xFFFF
405 \arg filter_list_low: 0x0000 - 0xFFFF
406 \arg filter_mask_high: 0x0000 - 0xFFFF
407 \arg filter_mask_low: 0x0000 - 0xFFFF
408 \arg filter_fifo_number: CAN_FIFO0, CAN_FIFO1
409 \arg filter_number: In CAN0(0 - 27), In CAN2(0 - 14)
410 \arg filter_mode: CAN_FILTERMODE_MASK, CAN_FILTERMODE_LIST
411 \arg filter_bits: CAN_FILTERBITS_32BIT, CAN_FILTERBITS_16BIT
412 \arg filter_enable: ENABLE or DISABLE
413 \param[out] none
414 \retval none
415 */
can_filter_init(uint32_t can_periph,can_filter_parameter_struct * can_filter_parameter_init)416 void can_filter_init(uint32_t can_periph, can_filter_parameter_struct* can_filter_parameter_init)
417 {
418 uint32_t val = 0U;
419
420 val = ((uint32_t)1) << (can_filter_parameter_init->filter_number);
421 /* filter lock disable */
422 CAN_FCTL(can_periph) |= CAN_FCTL_FLD;
423 /* disable filter */
424 CAN_FW(can_periph) &= ~(uint32_t)val;
425
426 /* filter 16 bits */
427 if(CAN_FILTERBITS_16BIT == can_filter_parameter_init->filter_bits){
428 /* set filter 16 bits */
429 CAN_FSCFG(can_periph) &= ~(uint32_t)val;
430 /* first 16 bits list and first 16 bits mask or first 16 bits list and second 16 bits list */
431 CAN_FDATA0(can_periph, can_filter_parameter_init->filter_number) = \
432 FDATA_MASK_HIGH((can_filter_parameter_init->filter_mask_low) & CAN_FILTER_MASK_16BITS) | \
433 FDATA_MASK_LOW((can_filter_parameter_init->filter_list_low) & CAN_FILTER_MASK_16BITS);
434 /* second 16 bits list and second 16 bits mask or third 16 bits list and fourth 16 bits list */
435 CAN_FDATA1(can_periph, can_filter_parameter_init->filter_number) = \
436 FDATA_MASK_HIGH((can_filter_parameter_init->filter_mask_high) & CAN_FILTER_MASK_16BITS) | \
437 FDATA_MASK_LOW((can_filter_parameter_init->filter_list_high) & CAN_FILTER_MASK_16BITS);
438 }
439 /* filter 32 bits */
440 if(CAN_FILTERBITS_32BIT == can_filter_parameter_init->filter_bits){
441 /* set filter 32 bits */
442 CAN_FSCFG(can_periph) |= (uint32_t)val;
443 /* 32 bits list or first 32 bits list */
444 CAN_FDATA0(can_periph, can_filter_parameter_init->filter_number) = \
445 FDATA_MASK_HIGH((can_filter_parameter_init->filter_list_high) & CAN_FILTER_MASK_16BITS) |
446 FDATA_MASK_LOW((can_filter_parameter_init->filter_list_low) & CAN_FILTER_MASK_16BITS);
447 /* 32 bits mask or second 32 bits list */
448 CAN_FDATA1(can_periph, can_filter_parameter_init->filter_number) = \
449 FDATA_MASK_HIGH((can_filter_parameter_init->filter_mask_high) & CAN_FILTER_MASK_16BITS) |
450 FDATA_MASK_LOW((can_filter_parameter_init->filter_mask_low) & CAN_FILTER_MASK_16BITS);
451 }
452
453 /* filter mode */
454 if(CAN_FILTERMODE_MASK == can_filter_parameter_init->filter_mode){
455 /* mask mode */
456 CAN_FMCFG(can_periph) &= ~(uint32_t)val;
457 }else{
458 /* list mode */
459 CAN_FMCFG(can_periph) |= (uint32_t)val;
460 }
461
462 /* filter FIFO */
463 if(CAN_FIFO0 == (can_filter_parameter_init->filter_fifo_number)){
464 /* FIFO0 */
465 CAN_FAFIFO(can_periph) &= ~(uint32_t)val;
466 }else{
467 /* FIFO1 */
468 CAN_FAFIFO(can_periph) |= (uint32_t)val;
469 }
470
471 /* filter working */
472 if(ENABLE == can_filter_parameter_init->filter_enable){
473
474 CAN_FW(can_periph) |= (uint32_t)val;
475 }
476
477 /* filter lock enable */
478 CAN_FCTL(can_periph) &= ~CAN_FCTL_FLD;
479 }
480
481 /*!
482 \brief CAN filter mask mode initialization
483 \param[in] can_periph
484 \arg CANx(x=0,2),the CAN2 only for GD32E50X_CL and GD32E508
485 \param[in] id: extended(11-bits) or standard(29-bits) identifier
486 \arg 0x00000000 - 0x1FFFFFFF
487 \param[in] mask: extended(11-bits) or standard(29-bits) identifier mask
488 \arg 0x00000000 - 0x1FFFFFFF
489 \param[in] format_fifo: format and fifo states
490 only one parameter can be selected which is shown as below:
491 \arg CAN_STANDARD_FIFO0
492 \arg CAN_STANDARD_FIFO1
493 \arg CAN_EXTENDED_FIFO0
494 \arg CAN_EXTENDED_FIFO1
495 \param[in] filter_number: filter sequence number
496 \arg In CAN0:0 - 27 ,In CAN2:0 - 14
497 \param[out] none
498 \retval none
499 */
can_filter_mask_mode_init(uint32_t can_periph,uint32_t id,uint32_t mask,can_format_fifo_enum format_fifo,uint16_t filter_number)500 void can_filter_mask_mode_init(uint32_t can_periph, uint32_t id, uint32_t mask, can_format_fifo_enum format_fifo, uint16_t filter_number)
501 {
502 can_filter_parameter_struct can_filter;
503
504 /* Initialize the filter structure */
505 can_struct_para_init(CAN_FILTER_STRUCT, &can_filter);
506
507 /* filter config */
508 can_filter.filter_number = filter_number;
509 can_filter.filter_mode = CAN_FILTERMODE_MASK;
510 can_filter.filter_bits = CAN_FILTERBITS_32BIT;
511 can_filter.filter_enable = ENABLE;
512
513 switch(format_fifo){
514 /* standard FIFO 0 */
515 case CAN_STANDARD_FIFO0:
516 can_filter.filter_fifo_number = CAN_FIFO0;
517 /* configure SFID[10:0] */
518 can_filter.filter_list_high = (uint16_t)id << 5;
519 can_filter.filter_list_low = 0x0000U;
520 /* configure SFID[10:0] mask */
521 can_filter.filter_mask_high = (uint16_t)mask << 5;
522 /* both data and remote frames can be received */
523 can_filter.filter_mask_low = 0x0000U;
524
525 break;
526 /* standard FIFO 1 */
527 case CAN_STANDARD_FIFO1:
528 can_filter.filter_fifo_number = CAN_FIFO1;
529 /* configure SFID[10:0] */
530 can_filter.filter_list_high = (uint16_t)id << 5;
531 can_filter.filter_list_low = 0x0000U;
532 /* configure SFID[10:0] mask */
533 can_filter.filter_mask_high = (uint16_t)mask << 5;
534 /* both data and remote frames can be received */
535 can_filter.filter_mask_low = 0x0000U;
536
537 break;
538 /* extended FIFO 0 */
539 case CAN_EXTENDED_FIFO0:
540 can_filter.filter_fifo_number = CAN_FIFO0;
541 /* configure EFID[28:13] */
542 can_filter.filter_list_high = (uint16_t)(id >> 13);
543 /* configure EFID[12:0] and frame format bit set */
544 can_filter.filter_list_low = ((uint16_t)(id << 3)) | (1U << 2);
545 /* configure EFID[28:13] mask */
546 can_filter.filter_mask_high = (uint16_t)(mask >> 13);
547 /* configure EFID[12:0] and frame format bit mask */
548 /* both data and remote frames can be received */
549 can_filter.filter_mask_low = ((uint16_t)(mask << 3)) | (1U << 2);
550
551 break;
552 /* extended FIFO 1 */
553 case CAN_EXTENDED_FIFO1:
554 can_filter.filter_fifo_number = CAN_FIFO1;
555 /* configure EFID[28:13] */
556 can_filter.filter_list_high = (uint16_t)(id >> 13);
557 /* configure EFID[12:0] and frame format bit set */
558 can_filter.filter_list_low = ((uint16_t)(id << 3)) | (1U << 2);
559 /* configure EFID[28:13] mask */
560 can_filter.filter_mask_high = (uint16_t)(mask >> 13);
561 /* configure EFID[12:0] and frame format bit mask */
562 /* both data and remote frames can be received */
563 can_filter.filter_mask_low = ((uint16_t)(mask << 3)) | (1U << 2);
564
565 break;
566 default:
567 CAN_ERROR_HANDLE("parameter is invalid \r\n");
568 }
569
570 can_filter_init(can_periph, &can_filter);
571 }
572
573 /*!
574 \brief CAN communication mode configure
575 \param[in] can_periph
576 \arg CANx(x=0,1,2),the CAN2 only for GD32E50X_CL and GD32E508
577 \param[in] mode: communication mode
578 only one parameter can be selected which is shown as below:
579 \arg CAN_NORMAL_MODE
580 \arg CAN_LOOPBACK_MODE
581 \arg CAN_SILENT_MODE
582 \arg CAN_SILENT_LOOPBACK_MODE
583 \param[out] none
584 \retval ErrStatus: SUCCESS or ERROR
585 */
can_monitor_mode_set(uint32_t can_periph,uint8_t mode)586 ErrStatus can_monitor_mode_set(uint32_t can_periph, uint8_t mode)
587 {
588 ErrStatus reval = SUCCESS;
589 uint32_t timeout = CAN_TIMEOUT;
590
591 if(mode == (mode & CAN_SILENT_LOOPBACK_MODE)){
592 /* disable sleep mode */
593 CAN_CTL(can_periph) &= (~(uint32_t)CAN_CTL_SLPWMOD);
594 /* set initialize mode */
595 CAN_CTL(can_periph) |= (uint8_t)CAN_CTL_IWMOD;
596 /* wait the acknowledge */
597 timeout = CAN_TIMEOUT;
598 while((CAN_STAT_IWS != (CAN_STAT(can_periph) & CAN_STAT_IWS)) && (0U != timeout)){
599 timeout--;
600 }
601
602 if(CAN_STAT_IWS != (CAN_STAT(can_periph) & CAN_STAT_IWS)){
603 reval = ERROR;
604 }else{
605 CAN_BT(can_periph) &= ~BT_MODE(3);
606 CAN_BT(can_periph) |= BT_MODE(mode);
607
608 timeout = CAN_TIMEOUT;
609 /* enter normal mode */
610 CAN_CTL(can_periph) &= ~(uint32_t)(CAN_CTL_SLPWMOD | CAN_CTL_IWMOD);
611 /* wait the acknowledge */
612 while((0U != (CAN_STAT(can_periph) & (CAN_STAT_IWS | CAN_STAT_SLPWS))) && (0U != timeout)){
613 timeout--;
614 }
615 if(0U != (CAN_STAT(can_periph) & (CAN_STAT_IWS | CAN_STAT_SLPWS))){
616 reval = ERROR;
617 }
618 }
619 }else{
620 reval = ERROR;
621 }
622
623 return reval;
624 }
625
626 #ifdef GD32E508
627 /*!
628 \brief initialize CAN FD function
629 \param[in] can_periph
630 \arg CANx(x=0,1,2),the CAN2 only for GD32E50X_CL and GD32E508
631 \param[in] can_fdframe_init: parameters for CAN FD initializtion
632 \arg fd_frame: ENABLE or DISABLE
633 \arg excp_event_detect: ENABLE or DISABLE
634 \arg delay_compensation: ENABLE or DISABLE
635 \arg p_delay_compensation: the pointer of tdc struct
636 can_fd_tdc_struct:
637 tdc_mode: CAN_TDCMOD_CALC_AND_OFFSET or CAN_TDCMOD_OFFSET
638 tdc_filter: 0x00 - 0x07
639 tdc_offset: 0x00 - 0x07
640 \arg iso_bosch: CAN_FDMOD_ISO or CAN_FDMOD_BOSCH
641 \arg esi_mode: CAN_ESIMOD_HARDWARE or CAN_ESIMOD_SOFTWARE
642 \arg data_resync_jump_width: 0x00 - 0x07
643 \arg data_time_segment_1: 0x00 - 0x0F
644 \arg data_time_segment_2: 0x00 - 0x07
645 \arg data_prescaler: 0x0001 - 0x0400
646 \param[out] none
647 \retval ErrStatus: SUCCESS or ERROR
648 */
can_fd_init(uint32_t can_periph,can_fdframe_struct * can_fdframe_init)649 ErrStatus can_fd_init(uint32_t can_periph, can_fdframe_struct* can_fdframe_init)
650 {
651 uint32_t timeout = CAN_TIMEOUT;
652 uint32_t tempreg = 0U;
653
654 /* check null pointer */
655 if(0 == can_fdframe_init){
656 return ERROR;
657 }
658 /* disable sleep mode */
659 CAN_CTL(can_periph) &= ~CAN_CTL_SLPWMOD;
660 /* enable initialize mode */
661 CAN_CTL(can_periph) |= CAN_CTL_IWMOD;
662 /* wait ACK */
663 while((CAN_STAT_IWS != (CAN_STAT(can_periph) & CAN_STAT_IWS)) && (0U != timeout)){
664 timeout--;
665 }
666 /* check initialize working success */
667 if(CAN_STAT_IWS != (CAN_STAT(can_periph) & CAN_STAT_IWS)){
668 return ERROR;
669 }else{
670 /* set the data bit timing register */
671 CAN_DBT(can_periph) = (BT_DSJW((uint32_t)can_fdframe_init->data_resync_jump_width) | \
672 BT_DBS1((uint32_t)can_fdframe_init->data_time_segment_1) | \
673 BT_DBS2((uint32_t)can_fdframe_init->data_time_segment_2) | \
674 BT_BAUDPSC(((uint32_t)can_fdframe_init->data_prescaler) - 1U));
675
676 tempreg = can_fdframe_init->esi_mode | can_fdframe_init->iso_bosch;
677
678 /* Protocol exception event detection */
679 if(ENABLE == can_fdframe_init->excp_event_detect){
680 tempreg &= ~CAN_FDCTL_PRED;
681 }else{
682 tempreg |= CAN_FDCTL_PRED;
683 }
684
685 /* Transmitter delay compensation mode */
686 if(ENABLE == can_fdframe_init->delay_compensation){
687 tempreg |= CAN_FDCTL_TDCEN;
688 /* p_delay_compensation pointer should be config when TDC mode is enabled */
689 if(0 != can_fdframe_init->p_delay_compensation){
690 tempreg |= (can_fdframe_init->p_delay_compensation->tdc_mode & CAN_FDCTL_TDCMOD);
691 CAN_FDTDC(can_periph) = (FDTDC_TDCF(can_fdframe_init->p_delay_compensation->tdc_filter) | FDTDC_TDCO(can_fdframe_init->p_delay_compensation->tdc_offset));
692 }else{
693 return ERROR;
694 }
695 }else{
696 /* Transmitter delay compensation mode is disabled */
697 tempreg &= ~CAN_FDCTL_TDCEN;
698 }
699
700 /* FD operation mode */
701 if(ENABLE == can_fdframe_init->fd_frame){
702 tempreg |= CAN_FDCTL_FDEN;
703 }else{
704 tempreg &= ~CAN_FDCTL_FDEN;
705 }
706 CAN_FDCTL(can_periph) = tempreg;
707
708 /* disable initialize mode */
709 CAN_CTL(can_periph) &= ~CAN_CTL_IWMOD;
710 timeout = CAN_TIMEOUT;
711 /* wait the ACK */
712 while((CAN_STAT_IWS == (CAN_STAT(can_periph) & CAN_STAT_IWS)) && (0U != timeout)){
713 timeout--;
714 }
715 /* check exit initialize mode */
716 if(0U == timeout){
717 return ERROR;
718 }
719 }
720
721 return SUCCESS;
722 }
723
724 /*!
725 \brief CAN baud rate configure in classic mode
726 \param[in] can_periph
727 \arg CANx(x=0,1,2),the CAN2 only for GD32E50X_CL and GD32E508
728 \param[in] hz: frequency, range from 1 to 1000000 Hz
729 \param[out] none
730 \retval ErrStatus: SUCCESS or ERROR
731 */
can_frequency_set(uint32_t can_periph,uint32_t hz)732 ErrStatus can_frequency_set(uint32_t can_periph, uint32_t hz)
733 {
734 ErrStatus reval = SUCCESS;
735 uint32_t reg_temp;
736 uint32_t fdctl_status;
737 /* The maximum baud rate support to 1M */
738 if(hz <= 1000000U) {
739 if(SUCCESS == can_working_mode_set(can_periph, GD32_CAN_MODE_INITIALIZE)){
740 reg_temp = CAN_BT(can_periph);
741 reg_temp &= (CAN_BT_LCMOD | CAN_BT_SCMOD);
742 fdctl_status = CAN_FDCTL(can_periph);
743 if(CAN_FDCTL_FDEN != (fdctl_status&CAN_FDCTL_FDEN)){
744 /* CAN FD disable, should frist enable, then write */
745 fdctl_status = fdctl_status | CAN_FDCTL_FDEN;
746 CAN_FDCTL(can_periph) = fdctl_status;
747 CAN_BT(can_periph) = reg_temp | dev_can_baudrate_set(hz);
748 fdctl_status = fdctl_status & (~CAN_FDCTL_FDEN);
749 CAN_FDCTL(can_periph) = fdctl_status;
750 }else{
751 /* CAN FD enable */
752 CAN_BT(can_periph) = reg_temp | dev_can_baudrate_set(hz);
753 }
754 }else {
755 reval = ERROR;
756 }
757
758 if(SUCCESS != can_working_mode_set(can_periph, GD32_CAN_MODE_NORMAL)){
759 reval = ERROR;
760 }
761 }else{
762 reval = ERROR;
763 }
764
765 return reval;
766 }
767
768 /*!
769 \brief CAN baud rate configure in FD mode
770 \param[in] can_periph
771 \arg CANx(x=0,1,2),the CAN2 only for GD32E50X_CL and GD32E508
772 \param[in] hz: frequency
773 \param[out] none
774 \retval ErrStatus: SUCCESS or ERROR
775 */
can_fd_frequency_set(uint32_t can_periph,uint32_t hz)776 ErrStatus can_fd_frequency_set(uint32_t can_periph, uint32_t hz)
777 {
778 ErrStatus reval = SUCCESS;
779
780 if(SUCCESS == can_working_mode_set(can_periph, GD32_CAN_MODE_INITIALIZE)){
781 CAN_DBT(can_periph) = dev_can_fd_baudrate_set(hz);
782 }else {
783 reval = ERROR;
784 }
785
786 if(SUCCESS != can_working_mode_set(can_periph, GD32_CAN_MODE_NORMAL)){
787 reval = ERROR;
788 }
789
790 return reval;
791 }
792
793 /*!
794 \brief CAN FD frame function enable
795 \param[in] can_periph
796 \arg CANx(x=0,1,2),the CAN2 only for GD32E50X_CL and GD32E508
797 \param[out] none
798 \retval none
799 */
can_fd_function_enable(uint32_t can_periph)800 void can_fd_function_enable(uint32_t can_periph)
801 {
802 CAN_FDCTL(can_periph) |= CAN_FDCTL_FDEN;
803 }
804
805 /*!
806 \brief CAN FD frame function disable
807 \param[in] can_periph
808 \arg CANx(x=0,1,2),the CAN2 only for GD32E50X_CL
809 \param[out] none
810 \retval none
811 */
can_fd_function_disable(uint32_t can_periph)812 void can_fd_function_disable(uint32_t can_periph)
813 {
814 CAN_FDCTL(can_periph) &= ~CAN_FDCTL_FDEN;
815 }
816 #else
817 /*!
818 \brief CAN baud rate configure in classic mode
819 \param[in] can_periph
820 \arg CANx(x=0,1,2),the CAN2 only for GD32E50X_CL and GD32E508
821 \param[in] hz: frequency, range from 1 to 1000000 Hz
822 \param[out] none
823 \retval ErrStatus: SUCCESS or ERROR
824 */
can_frequency_set(uint32_t can_periph,uint32_t hz)825 ErrStatus can_frequency_set(uint32_t can_periph, uint32_t hz)
826 {
827 ErrStatus reval = SUCCESS;
828 uint32_t reg_temp;
829
830 /* The maximum baud rate support to 1M */
831 if(hz <= 1000000U) {
832 if(SUCCESS == can_working_mode_set(can_periph, GD32_CAN_MODE_INITIALIZE)){
833 reg_temp = CAN_BT(can_periph);
834 reg_temp &= (CAN_BT_LCMOD | CAN_BT_SCMOD);
835
836 CAN_BT(can_periph) = reg_temp | dev_can_baudrate_set(hz);
837 }else {
838 reval = ERROR;
839 }
840
841 if(SUCCESS != can_working_mode_set(can_periph, GD32_CAN_MODE_NORMAL)){
842 reval = ERROR;
843 }
844 }else{
845 reval = ERROR;
846 }
847
848 return reval;
849 }
850 #endif /* GD32E508 */
851
852 /*!
853 \brief set CAN1 fliter start bank number
854 \param[in] start_bank: CAN1 start bank number
855 only one parameter can be selected which is shown as below:
856 \arg (1..27)
857 \param[out] none
858 \retval none
859 */
can1_filter_start_bank(uint8_t start_bank)860 void can1_filter_start_bank(uint8_t start_bank)
861 {
862 /* filter lock disable */
863 CAN_FCTL(CAN0) |= CAN_FCTL_FLD;
864 /* set CAN1 filter start number */
865 CAN_FCTL(CAN0) &= ~(uint32_t)CAN_FCTL_HBC1F;
866 CAN_FCTL(CAN0) |= FCTL_HBC1F(start_bank);
867 /* filter lock enable */
868 CAN_FCTL(CAN0) &= ~CAN_FCTL_FLD;
869 }
870
871 /*!
872 \brief enable CAN debug freeze
873 \param[in] can_periph
874 \arg CANx(x=0,1,2),the CAN2 only for GD32E50X_CL and GD32E508
875 \param[out] none
876 \retval none
877 */
can_debug_freeze_enable(uint32_t can_periph)878 void can_debug_freeze_enable(uint32_t can_periph)
879 {
880 /* set DFZ bit */
881 CAN_CTL(can_periph) |= CAN_CTL_DFZ;
882 #ifdef GD32E50X_CL
883 switch(can_periph){
884 case CAN0:
885 dbg_periph_enable(DBG_CAN0_HOLD);
886 break;
887 case CAN1:
888 dbg_periph_enable(DBG_CAN1_HOLD);
889 break;
890 case CAN2:
891 dbg_periph_enable(DBG_CAN2_HOLD);
892 break;
893 default:
894 break;
895 }
896 #else
897 switch(can_periph){
898 case CAN0:
899 dbg_periph_enable(DBG_CAN0_HOLD);
900 break;
901 case CAN1:
902 dbg_periph_enable(DBG_CAN1_HOLD);
903 break;
904 default:
905 break;
906 }
907 #endif
908 }
909
910 /*!
911 \brief disable CAN debug freeze
912 \param[in] can_periph
913 \arg CANx(x=0,1,2),the CAN2 only for GD32E50X_CL and GD32E508
914 \param[out] none
915 \retval none
916 */
can_debug_freeze_disable(uint32_t can_periph)917 void can_debug_freeze_disable(uint32_t can_periph)
918 {
919 /* set DFZ bit */
920 CAN_CTL(can_periph) &= ~CAN_CTL_DFZ;
921 #ifdef GD32E50X_CL
922 switch(can_periph){
923 case CAN0:
924 dbg_periph_disable(DBG_CAN0_HOLD);
925 break;
926 case CAN1:
927 dbg_periph_disable(DBG_CAN1_HOLD);
928 break;
929 case CAN2:
930 dbg_periph_disable(DBG_CAN2_HOLD);
931 break;
932 default:
933 break;
934 #else
935 switch(can_periph){
936 case CAN0:
937 dbg_periph_disable(DBG_CAN0_HOLD);
938 break;
939 case CAN1:
940 dbg_periph_disable(DBG_CAN1_HOLD);
941 break;
942 default:
943 break;
944 #endif
945 }
946 }
947
948 /*!
949 \brief enable CAN time trigger mode
950 \param[in] can_periph
951 \arg CANx(x=0,1,2),the CAN2 only for GD32E50X_CL and GD32E508
952 \param[out] none
953 \retval none
954 */
955 void can_time_trigger_mode_enable(uint32_t can_periph)
956 {
957 uint8_t mailbox_number;
958
959 /* enable the tcc mode */
960 CAN_CTL(can_periph) |= CAN_CTL_TTC;
961 /* enable time stamp */
962 for(mailbox_number = 0U; mailbox_number < 3U; mailbox_number++){
963 CAN_TMP(can_periph, mailbox_number) |= CAN_TMP_TSEN;
964 }
965 }
966
967 /*!
968 \brief disable CAN time trigger mode
969 \param[in] can_periph
970 \arg CANx(x=0,1,2),the CAN2 only for GD32E50X_CL and GD32E508
971 \param[out] none
972 \retval none
973 */
974 void can_time_trigger_mode_disable(uint32_t can_periph)
975 {
976 uint8_t mailbox_number;
977
978 /* disable the TCC mode */
979 CAN_CTL(can_periph) &= ~CAN_CTL_TTC;
980 /* reset TSEN bits */
981 for(mailbox_number = 0U; mailbox_number < 3U; mailbox_number++){
982 CAN_TMP(can_periph, mailbox_number) &= ~CAN_TMP_TSEN;
983 }
984 }
985
986 /*!
987 \brief transmit CAN message
988 \param[in] can_periph
989 \arg CANx(x=0,1,2),the CAN2 only for GD32E50X_CL and GD32E508
990 \param[in] transmit_message: struct for CAN transmit message
991 \arg tx_sfid: 0x00000000 - 0x000007FF
992 \arg tx_efid: 0x00000000 - 0x1FFFFFFF
993 \arg tx_ff: CAN_FF_STANDARD, CAN_FF_EXTENDED
994 \arg tx_ft: CAN_FT_DATA, CAN_FT_REMOTE
995 \arg tx_dlen: 0 - 8 (FD mode: 0 - 8, or 12, 16, 20, 24, 32, 48, 64)
996 \arg tx_data[]: 0x00 - 0xFF
997 \param[out] none
998 \retval mailbox_number
999 */
1000 uint8_t can_message_transmit(uint32_t can_periph, can_trasnmit_message_struct* transmit_message)
1001 {
1002 uint8_t mailbox_number = CAN_MAILBOX0;
1003 volatile uint32_t p_temp;
1004 #ifdef GD32E508
1005 uint8_t i = 0U;
1006 uint8_t hit = 0U;
1007 uint32_t canfd_en = 0U;
1008 uint32_t reg_temp = 0U;
1009 #endif /* GD32E508 */
1010
1011 /* select one empty mailbox */
1012 if(CAN_TSTAT_TME0 == (CAN_TSTAT(can_periph)&CAN_TSTAT_TME0)){
1013 mailbox_number = CAN_MAILBOX0;
1014 }else if(CAN_TSTAT_TME1 == (CAN_TSTAT(can_periph)&CAN_TSTAT_TME1)){
1015 mailbox_number = CAN_MAILBOX1;
1016 }else if(CAN_TSTAT_TME2 == (CAN_TSTAT(can_periph)&CAN_TSTAT_TME2)){
1017 mailbox_number = CAN_MAILBOX2;
1018 }else{
1019 mailbox_number = CAN_NOMAILBOX;
1020 }
1021 /* return no mailbox empty */
1022 if(CAN_NOMAILBOX == mailbox_number){
1023 return CAN_NOMAILBOX;
1024 }
1025
1026 CAN_TMI(can_periph, mailbox_number) &= CAN_TMI_TEN;
1027 if(CAN_FF_STANDARD == transmit_message->tx_ff){
1028 /* set transmit mailbox standard identifier */
1029 CAN_TMI(can_periph, mailbox_number) |= (uint32_t)(TMI_SFID(transmit_message->tx_sfid) | \
1030 transmit_message->tx_ft);
1031 }else{
1032 /* set transmit mailbox extended identifier */
1033 CAN_TMI(can_periph, mailbox_number) |= (uint32_t)(TMI_EFID(transmit_message->tx_efid) | \
1034 transmit_message->tx_ff | \
1035 transmit_message->tx_ft);
1036 }
1037
1038 #ifdef GD32E508
1039 if(CAN_FDF_CLASSIC == transmit_message->fd_flag){
1040 /* set the data length */
1041 CAN_TMP(can_periph, mailbox_number) &= ~(CAN_TMP_DLENC|CAN_TMP_ESI|CAN_TMP_BRS|CAN_TMP_FDF);
1042 CAN_TMP(can_periph, mailbox_number) |= transmit_message->tx_dlen;
1043 /* set the data */
1044 CAN_TMDATA0(can_periph, mailbox_number) = TMDATA0_DB3(transmit_message->tx_data[3]) | \
1045 TMDATA0_DB2(transmit_message->tx_data[2]) | \
1046 TMDATA0_DB1(transmit_message->tx_data[1]) | \
1047 TMDATA0_DB0(transmit_message->tx_data[0]);
1048 CAN_TMDATA1(can_periph, mailbox_number) = TMDATA1_DB7(transmit_message->tx_data[7]) | \
1049 TMDATA1_DB6(transmit_message->tx_data[6]) | \
1050 TMDATA1_DB5(transmit_message->tx_data[5]) | \
1051 TMDATA1_DB4(transmit_message->tx_data[4]);
1052 }else{
1053 canfd_en = CAN_FDCTL(can_periph) & CAN_FDCTL_FDEN;
1054 /* check FD funciton has been enabled */
1055 if(canfd_en){
1056 if(transmit_message->tx_dlen <= 8U){
1057 /* set the data length */
1058 reg_temp |= transmit_message->tx_dlen;
1059 }else{
1060 /* data length greater than 8 */
1061 for(i = 0U; i < 7U; i++){
1062 if(transmit_message->tx_dlen == g_can_fdlength_table[i]){
1063 hit = 1U;
1064 break;
1065 }
1066 }
1067 /* data length is valid */
1068 if(1U == hit){
1069 reg_temp |= 9U + i;
1070 }else{
1071 CAN_ERROR_HANDLE("dlen is invalid \r\n");
1072 }
1073 }
1074 reg_temp |= (((uint32_t)transmit_message->fd_brs << 5U) | ((uint32_t)transmit_message->fd_esi << 4U) | ((uint32_t)transmit_message->fd_flag << 7U));
1075 CAN_TMP(can_periph, mailbox_number) = reg_temp;
1076
1077 /* set the data */
1078 i = transmit_message->tx_dlen / 4U;
1079
1080 /* data length is 5-7 need send 2 word */
1081 if((1U==i) && (4U!=transmit_message->tx_dlen)){
1082 i++;
1083 }
1084 p_temp = (uint32_t)transmit_message->tx_data;
1085 if((0U==i)){
1086 CAN_TMDATA0(can_periph, mailbox_number) = *(uint32_t *)p_temp;
1087 }else{
1088 for(; i>0U; i--){
1089 CAN_TMDATA0(can_periph, mailbox_number) = *(uint32_t *)p_temp;
1090 p_temp = ((uint32_t)((uint32_t)p_temp + 4U));
1091 }
1092 }
1093
1094 }else{
1095 CAN_ERROR_HANDLE("CAN FD function disabled \r\n");
1096 }
1097 }
1098 #else
1099 /* set the data length */
1100 CAN_TMP(can_periph, mailbox_number) &= ~CAN_TMP_DLENC;
1101 CAN_TMP(can_periph, mailbox_number) |= transmit_message->tx_dlen;
1102 /* set the data */
1103 CAN_TMDATA0(can_periph, mailbox_number) = TMDATA0_DB3(transmit_message->tx_data[3]) | \
1104 TMDATA0_DB2(transmit_message->tx_data[2]) | \
1105 TMDATA0_DB1(transmit_message->tx_data[1]) | \
1106 TMDATA0_DB0(transmit_message->tx_data[0]);
1107 CAN_TMDATA1(can_periph, mailbox_number) = TMDATA1_DB7(transmit_message->tx_data[7]) | \
1108 TMDATA1_DB6(transmit_message->tx_data[6]) | \
1109 TMDATA1_DB5(transmit_message->tx_data[5]) | \
1110 TMDATA1_DB4(transmit_message->tx_data[4]);
1111 #endif /* GD32E508 */
1112 /* enable transmission */
1113 CAN_TMI(can_periph, mailbox_number) |= CAN_TMI_TEN;
1114
1115 return mailbox_number;
1116 }
1117
1118 /*!
1119 \brief get CAN transmit state
1120 \param[in] can_periph
1121 \arg CANx(x=0,1,2),the CAN2 only for GD32E50X_CL and GD32E508
1122 \param[in] mailbox_number
1123 only one parameter can be selected which is shown as below:
1124 \arg CAN_MAILBOX(x=0,1,2)
1125 \param[out] none
1126 \retval can_transmit_state_enum
1127 */
1128 can_transmit_state_enum can_transmit_states(uint32_t can_periph, uint8_t mailbox_number)
1129 {
1130 can_transmit_state_enum state = CAN_TRANSMIT_FAILED;
1131 uint32_t val = 0U;
1132
1133 /* check selected mailbox state */
1134 switch(mailbox_number){
1135 /* mailbox0 */
1136 case CAN_MAILBOX0:
1137 val = CAN_TSTAT(can_periph) & (CAN_TSTAT_MTF0 | CAN_TSTAT_MTFNERR0 | CAN_TSTAT_TME0);
1138 break;
1139 /* mailbox1 */
1140 case CAN_MAILBOX1:
1141 val = CAN_TSTAT(can_periph) & (CAN_TSTAT_MTF1 | CAN_TSTAT_MTFNERR1 | CAN_TSTAT_TME1);
1142 break;
1143 /* mailbox2 */
1144 case CAN_MAILBOX2:
1145 val = CAN_TSTAT(can_periph) & (CAN_TSTAT_MTF2 | CAN_TSTAT_MTFNERR2 | CAN_TSTAT_TME2);
1146 break;
1147 default:
1148 val = CAN_TRANSMIT_FAILED;
1149 break;
1150 }
1151
1152 switch(val){
1153 /* transmit pending */
1154 case (CAN_STATE_PENDING):
1155 state = CAN_TRANSMIT_PENDING;
1156 break;
1157 /* mailbox0 transmit succeeded */
1158 case (CAN_TSTAT_MTF0 | CAN_TSTAT_MTFNERR0 | CAN_TSTAT_TME0):
1159 state = CAN_TRANSMIT_OK;
1160 break;
1161 /* mailbox1 transmit succeeded */
1162 case (CAN_TSTAT_MTF1 | CAN_TSTAT_MTFNERR1 | CAN_TSTAT_TME1):
1163 state = CAN_TRANSMIT_OK;
1164 break;
1165 /* mailbox2 transmit succeeded */
1166 case (CAN_TSTAT_MTF2 | CAN_TSTAT_MTFNERR2 | CAN_TSTAT_TME2):
1167 state = CAN_TRANSMIT_OK;
1168 break;
1169 /* transmit failed */
1170 default:
1171 state = CAN_TRANSMIT_FAILED;
1172 break;
1173 }
1174 return state;
1175 }
1176
1177 /*!
1178 \brief stop CAN transmission
1179 \param[in] can_periph
1180 \arg CANx(x=0,1,2),the CAN2 only for GD32E50X_CL and GD32E508
1181 \param[in] mailbox_number
1182 only one parameter can be selected which is shown as below:
1183 \arg CAN_MAILBOXx(x=0,1,2)
1184 \param[out] none
1185 \retval none
1186 */
1187 void can_transmission_stop(uint32_t can_periph, uint8_t mailbox_number)
1188 {
1189 if(CAN_MAILBOX0 == mailbox_number){
1190 CAN_TSTAT(can_periph) |= CAN_TSTAT_MST0;
1191 while(CAN_TSTAT_MST0 == (CAN_TSTAT(can_periph) & CAN_TSTAT_MST0)){
1192 }
1193 }else if(CAN_MAILBOX1 == mailbox_number){
1194 CAN_TSTAT(can_periph) |= CAN_TSTAT_MST1;
1195 while(CAN_TSTAT_MST1 == (CAN_TSTAT(can_periph) & CAN_TSTAT_MST1)){
1196 }
1197 }else if(CAN_MAILBOX2 == mailbox_number){
1198 CAN_TSTAT(can_periph) |= CAN_TSTAT_MST2;
1199 while(CAN_TSTAT_MST2 == (CAN_TSTAT(can_periph) & CAN_TSTAT_MST2)){
1200 }
1201 }else{
1202 /* illegal parameters */
1203 }
1204 }
1205
1206 /*!
1207 \brief CAN receive message
1208 \param[in] can_periph
1209 \arg CANx(x=0,1,2),the CAN2 only for GD32E50X_CL and GD32E508
1210 \param[in] fifo_number
1211 \arg CAN_FIFOx(x=0,1)
1212 \param[out] receive_message: struct for CAN receive message
1213 \arg rx_sfid: 0x00000000 - 0x000007FF
1214 \arg rx_efid: 0x00000000 - 0x1FFFFFFF
1215 \arg rx_ff: CAN_FF_STANDARD, CAN_FF_EXTENDED
1216 \arg rx_ft: CAN_FT_DATA, CAN_FT_REMOTE
1217 \arg rx_dlen: 0 - 8 (FD mode: 0 - 8, or 12, 16, 20, 24, 32, 48, 64)
1218 \arg rx_data[]: 0x00 - 0xFF
1219 \arg rx_fi: 0 - 27
1220 \retval none
1221 */
1222 void can_message_receive(uint32_t can_periph, uint8_t fifo_number, can_receive_message_struct* receive_message)
1223 {
1224 volatile uint32_t p_temp;
1225 #ifdef GD32E508
1226 uint32_t canfd_en = 0U;
1227 uint32_t data_temp;
1228 uint8_t canfd_recv_cnt = 0U;
1229 uint8_t i;
1230 #endif /* GD32E508 */
1231
1232 /* get the frame format */
1233 receive_message->rx_ff = (uint8_t)(CAN_RFIFOMI_FF & CAN_RFIFOMI(can_periph, fifo_number));
1234 if(CAN_FF_STANDARD == receive_message->rx_ff){
1235 /* get standard identifier */
1236 receive_message->rx_sfid = (uint32_t)(GET_RFIFOMI_SFID(CAN_RFIFOMI(can_periph, fifo_number)));
1237 }else{
1238 /* get extended identifier */
1239 receive_message->rx_efid = (uint32_t)(GET_RFIFOMI_EFID(CAN_RFIFOMI(can_periph, fifo_number)));
1240 }
1241
1242 /* get frame type */
1243 receive_message->rx_ft = (uint8_t)(CAN_RFIFOMI_FT & CAN_RFIFOMI(can_periph, fifo_number));
1244 /* filtering index */
1245 receive_message->rx_fi = (uint8_t)(GET_RFIFOMP_FI(CAN_RFIFOMP(can_periph, fifo_number)));
1246
1247 #ifdef GD32E508
1248 receive_message->fd_flag = (uint8_t)((CAN_RFIFOMP_FDF & CAN_RFIFOMP(can_periph, fifo_number))>>7);
1249
1250 canfd_en = CAN_FDCTL(can_periph) & CAN_FDCTL_FDEN;
1251 if(!canfd_en){
1252 if(CAN_FDF_CLASSIC == receive_message->fd_flag){
1253 /* get recevie data length */
1254 receive_message->rx_dlen = (uint8_t)(GET_RFIFOMP_DLENC(CAN_RFIFOMP(can_periph, fifo_number)));
1255 /* receive data */
1256 receive_message->rx_data[0] = (uint8_t)(GET_RFIFOMDATA0_DB0(CAN_RFIFOMDATA0(can_periph, fifo_number)));
1257 receive_message->rx_data[1] = (uint8_t)(GET_RFIFOMDATA0_DB1(CAN_RFIFOMDATA0(can_periph, fifo_number)));
1258 receive_message->rx_data[2] = (uint8_t)(GET_RFIFOMDATA0_DB2(CAN_RFIFOMDATA0(can_periph, fifo_number)));
1259 receive_message->rx_data[3] = (uint8_t)(GET_RFIFOMDATA0_DB3(CAN_RFIFOMDATA0(can_periph, fifo_number)));
1260 receive_message->rx_data[4] = (uint8_t)(GET_RFIFOMDATA1_DB4(CAN_RFIFOMDATA1(can_periph, fifo_number)));
1261 receive_message->rx_data[5] = (uint8_t)(GET_RFIFOMDATA1_DB5(CAN_RFIFOMDATA1(can_periph, fifo_number)));
1262 receive_message->rx_data[6] = (uint8_t)(GET_RFIFOMDATA1_DB6(CAN_RFIFOMDATA1(can_periph, fifo_number)));
1263 receive_message->rx_data[7] = (uint8_t)(GET_RFIFOMDATA1_DB7(CAN_RFIFOMDATA1(can_periph, fifo_number)));
1264 }else{
1265 CAN_ERROR_HANDLE("CAN FD function disabled \r\n");
1266 }
1267 }else{
1268 /* check FD funciton has been enabled */
1269 /* get recevie data length */
1270 canfd_recv_cnt = (uint8_t)(GET_RFIFOMP_DLENC(CAN_RFIFOMP(can_periph, fifo_number)));
1271
1272 if(canfd_recv_cnt <= 8U){
1273 /* set the data length */
1274 receive_message->rx_dlen = canfd_recv_cnt;
1275 }else{
1276 receive_message->rx_dlen = g_can_fdlength_table[canfd_recv_cnt - 9U];
1277 }
1278
1279 receive_message->fd_brs = (uint8_t)((CAN_RFIFOMP(can_periph, fifo_number) & CAN_RFIFOMP_BRS) >> 5);
1280 receive_message->fd_esi = (uint8_t)((CAN_RFIFOMP(can_periph, fifo_number) & CAN_RFIFOMP_ESI) >> 4);
1281
1282 /* get the data */
1283 i = receive_message->rx_dlen / 4U;
1284
1285 /* data length is 5-7 need receive 2 word */
1286 if((1U==i) && (4U!=receive_message->rx_dlen)){
1287 i++;
1288 }
1289 p_temp = (uint32_t)(uint32_t)receive_message->rx_data;
1290 if(0U==i){
1291 data_temp = CAN_RFIFOMDATA0(can_periph, fifo_number);
1292 *(uint32_t *)p_temp = data_temp;
1293 }else{
1294 /* get the data by reading from CAN_RFIFOMDATA0 register*/
1295 for(; i>0U; i--){
1296 data_temp = CAN_RFIFOMDATA0(can_periph, fifo_number);
1297 *(uint32_t *)p_temp = data_temp;
1298 p_temp = ((uint32_t)((uint32_t)p_temp + 4U));
1299 }
1300 }
1301 }
1302 #else
1303 /* get recevie data length */
1304 receive_message->rx_dlen = (uint8_t)(GET_RFIFOMP_DLENC(CAN_RFIFOMP(can_periph, fifo_number)));
1305
1306 /* receive data */
1307 receive_message -> rx_data[0] = (uint8_t)(GET_RFIFOMDATA0_DB0(CAN_RFIFOMDATA0(can_periph, fifo_number)));
1308 receive_message -> rx_data[1] = (uint8_t)(GET_RFIFOMDATA0_DB1(CAN_RFIFOMDATA0(can_periph, fifo_number)));
1309 receive_message -> rx_data[2] = (uint8_t)(GET_RFIFOMDATA0_DB2(CAN_RFIFOMDATA0(can_periph, fifo_number)));
1310 receive_message -> rx_data[3] = (uint8_t)(GET_RFIFOMDATA0_DB3(CAN_RFIFOMDATA0(can_periph, fifo_number)));
1311 receive_message -> rx_data[4] = (uint8_t)(GET_RFIFOMDATA1_DB4(CAN_RFIFOMDATA1(can_periph, fifo_number)));
1312 receive_message -> rx_data[5] = (uint8_t)(GET_RFIFOMDATA1_DB5(CAN_RFIFOMDATA1(can_periph, fifo_number)));
1313 receive_message -> rx_data[6] = (uint8_t)(GET_RFIFOMDATA1_DB6(CAN_RFIFOMDATA1(can_periph, fifo_number)));
1314 receive_message -> rx_data[7] = (uint8_t)(GET_RFIFOMDATA1_DB7(CAN_RFIFOMDATA1(can_periph, fifo_number)));
1315
1316 #endif /* GD32E508 */
1317 /* release FIFO */
1318 if(CAN_FIFO0 == fifo_number){
1319 CAN_RFIFO0(can_periph) |= CAN_RFIFO0_RFD0;
1320 }else{
1321 CAN_RFIFO1(can_periph) |= CAN_RFIFO1_RFD1;
1322 }
1323 }
1324
1325 /*!
1326 \brief release FIFO0
1327 \param[in] can_periph
1328 \arg CANx(x=0,1,2),the CAN2 only for GD32E50X_CL and GD32E508
1329 \param[in] fifo_number
1330 only one parameter can be selected which is shown as below:
1331 \arg CAN_FIFOx(x=0,1)
1332 \param[out] none
1333 \retval none
1334 */
1335 void can_fifo_release(uint32_t can_periph, uint8_t fifo_number)
1336 {
1337 if(CAN_FIFO0 == fifo_number){
1338 CAN_RFIFO0(can_periph) |= CAN_RFIFO0_RFD0;
1339 }else if(CAN_FIFO1 == fifo_number){
1340 CAN_RFIFO1(can_periph) |= CAN_RFIFO1_RFD1;
1341 }else{
1342 /* illegal parameters */
1343 CAN_ERROR_HANDLE("CAN FIFO NUM is invalid \r\n");
1344 }
1345 }
1346
1347 /*!
1348 \brief CAN receive message length
1349 \param[in] can_periph
1350 \arg CANx(x=0,1,2),the CAN2 only for GD32E50X_CL and GD32E508
1351 \param[in] fifo_number
1352 only one parameter can be selected which is shown as below:
1353 \arg CAN_FIFOx(x=0,1)
1354 \param[out] none
1355 \retval message length
1356 */
1357 uint8_t can_receive_message_length_get(uint32_t can_periph, uint8_t fifo_number)
1358 {
1359 uint8_t val = 0U;
1360
1361 if(CAN_FIFO0 == fifo_number){
1362 /* FIFO0 */
1363 val = (uint8_t)(CAN_RFIFO0(can_periph) & CAN_RFIF_RFL_MASK);
1364 }else if(CAN_FIFO1 == fifo_number){
1365 /* FIFO1 */
1366 val = (uint8_t)(CAN_RFIFO1(can_periph) & CAN_RFIF_RFL_MASK);
1367 }else{
1368 /* illegal parameters */
1369 }
1370 return val;
1371 }
1372
1373 /*!
1374 \brief set CAN working mode
1375 \param[in] can_periph
1376 \arg CANx(x=0,1,2),the CAN2 only for GD32E50X_CL and GD32E508
1377 \param[in] can_working_mode
1378 only one parameter can be selected which is shown as below:
1379 \arg GD32_CAN_MODE_INITIALIZE
1380 \arg GD32_CAN_MODE_NORMAL
1381 \arg GD32_CAN_MODE_SLEEP
1382 \param[out] none
1383 \retval ErrStatus: SUCCESS or ERROR
1384 */
1385 ErrStatus can_working_mode_set(uint32_t can_periph, uint8_t working_mode)
1386 {
1387 ErrStatus flag = ERROR;
1388 /* timeout for IWS or also for SLPWS bits */
1389 uint32_t timeout = CAN_TIMEOUT;
1390
1391 if(GD32_CAN_MODE_INITIALIZE == working_mode){
1392 /* disable sleep mode */
1393 CAN_CTL(can_periph) &= (~(uint32_t)CAN_CTL_SLPWMOD);
1394 /* set initialize mode */
1395 CAN_CTL(can_periph) |= (uint8_t)CAN_CTL_IWMOD;
1396 /* wait the acknowledge */
1397 while((CAN_STAT_IWS != (CAN_STAT(can_periph) & CAN_STAT_IWS)) && (0U != timeout)){
1398 timeout--;
1399 }
1400 if(CAN_STAT_IWS != (CAN_STAT(can_periph) & CAN_STAT_IWS)){
1401 flag = ERROR;
1402 }else{
1403 flag = SUCCESS;
1404 }
1405 }else if(GD32_CAN_MODE_NORMAL == working_mode){
1406 /* enter normal mode */
1407 CAN_CTL(can_periph) &= ~(uint32_t)(CAN_CTL_SLPWMOD | CAN_CTL_IWMOD);
1408 /* wait the acknowledge */
1409 while((0U != (CAN_STAT(can_periph) & (CAN_STAT_IWS | CAN_STAT_SLPWS))) && (0U != timeout)){
1410 timeout--;
1411 }
1412 if(0U != (CAN_STAT(can_periph) & (CAN_STAT_IWS | CAN_STAT_SLPWS))){
1413 flag = ERROR;
1414 }else{
1415 flag = SUCCESS;
1416 }
1417 }else if(GD32_CAN_MODE_SLEEP == working_mode){
1418 /* disable initialize mode */
1419 CAN_CTL(can_periph) &= (~(uint32_t)CAN_CTL_IWMOD);
1420 /* set sleep mode */
1421 CAN_CTL(can_periph) |= (uint8_t)CAN_CTL_SLPWMOD;
1422 /* wait the acknowledge */
1423 while((CAN_STAT_SLPWS != (CAN_STAT(can_periph) & CAN_STAT_SLPWS)) && (0U != timeout)){
1424 timeout--;
1425 }
1426 if(CAN_STAT_SLPWS != (CAN_STAT(can_periph) & CAN_STAT_SLPWS)){
1427 flag = ERROR;
1428 }else{
1429 flag = SUCCESS;
1430 }
1431 }else{
1432 flag = ERROR;
1433 }
1434 return flag;
1435 }
1436
1437 /*!
1438 \brief wake up CAN
1439 \param[in] can_periph
1440 \arg CANx(x=0,1,2),the CAN2 only for GD32E50X_CL and GD32E508
1441 \param[out] none
1442 \retval ErrStatus: SUCCESS or ERROR
1443 */
1444 ErrStatus can_wakeup(uint32_t can_periph)
1445 {
1446 ErrStatus flag = ERROR;
1447 uint32_t timeout = CAN_TIMEOUT;
1448
1449 /* wakeup */
1450 CAN_CTL(can_periph) &= ~CAN_CTL_SLPWMOD;
1451
1452 while((0U != (CAN_STAT(can_periph) & CAN_STAT_SLPWS)) && (0x00U != timeout)){
1453 timeout--;
1454 }
1455 /* check state */
1456 if(0U != (CAN_STAT(can_periph) & CAN_STAT_SLPWS)){
1457 flag = ERROR;
1458 }else{
1459 flag = SUCCESS;
1460 }
1461 return flag;
1462 }
1463
1464 /*!
1465 \brief get CAN error type
1466 \param[in] can_periph
1467 \arg CANx(x=0,1,2),the CAN2 only for GD32E50X_CL and GD32E508
1468 \param[out] none
1469 \retval can_error_enum
1470 \arg CAN_ERROR_NONE: no error
1471 \arg CAN_ERROR_FILL: fill error
1472 \arg CAN_ERROR_FORMATE: format error
1473 \arg CAN_ERROR_ACK: ACK error
1474 \arg CAN_ERROR_BITRECESSIVE: bit recessive
1475 \arg CAN_ERROR_BITDOMINANTER: bit dominant error
1476 \arg CAN_ERROR_CRC: CRC error
1477 \arg CAN_ERROR_SOFTWARECFG: software configure
1478 */
1479 can_error_enum can_error_get(uint32_t can_periph)
1480 {
1481 can_error_enum error;
1482 error = CAN_ERROR_NONE;
1483
1484 /* get error type */
1485 error = (can_error_enum)(GET_ERR_ERRN(CAN_ERR(can_periph)));
1486 return error;
1487 }
1488
1489 /*!
1490 \brief get CAN receive error number
1491 \param[in] can_periph
1492 \arg CANx(x=0,1,2),the CAN2 only for GD32E50X_CL
1493 \param[out] none
1494 \retval error number
1495 */
1496 uint8_t can_receive_error_number_get(uint32_t can_periph)
1497 {
1498 uint8_t val;
1499
1500 /* get error count */
1501 val = (uint8_t)(GET_ERR_RECNT(CAN_ERR(can_periph)));
1502 return val;
1503 }
1504
1505 /*!
1506 \brief get CAN transmit error number
1507 \param[in] can_periph
1508 \arg CANx(x=0,1,2),the CAN2 only for GD32E50X_CL and GD32E508
1509 \param[out] none
1510 \retval error number
1511 */
1512 uint8_t can_transmit_error_number_get(uint32_t can_periph)
1513 {
1514 uint8_t val;
1515
1516 val = (uint8_t)(GET_ERR_TECNT(CAN_ERR(can_periph)));
1517 return val;
1518 }
1519
1520 /*!
1521 \brief enable CAN interrupt
1522 \param[in] can_periph
1523 \arg CANx(x=0,1,2),the CAN2 only for GD32E50X_CL and GD32E508
1524 \param[in] interrupt
1525 one or more parameters can be selected which are shown as below:
1526 \arg CAN_INT_TME: transmit mailbox empty interrupt enable
1527 \arg CAN_INT_RFNE0: receive FIFO0 not empty interrupt enable
1528 \arg CAN_INT_RFF0: receive FIFO0 full interrupt enable
1529 \arg CAN_INT_RFO0: receive FIFO0 overfull interrupt enable
1530 \arg CAN_INT_RFNE1: receive FIFO1 not empty interrupt enable
1531 \arg CAN_INT_RFF1: receive FIFO1 full interrupt enable
1532 \arg CAN_INT_RFO1: receive FIFO1 overfull interrupt enable
1533 \arg CAN_INT_WERR: warning error interrupt enable
1534 \arg CAN_INT_PERR: passive error interrupt enable
1535 \arg CAN_INT_BO: bus-off interrupt enable
1536 \arg CAN_INT_ERRN: error number interrupt enable
1537 \arg CAN_INT_ERR: error interrupt enable
1538 \arg CAN_INT_WU: wakeup interrupt enable
1539 \arg CAN_INT_SLPW: sleep working interrupt enable
1540 \param[out] none
1541 \retval none
1542 */
1543 void can_interrupt_enable(uint32_t can_periph, uint32_t interrupt)
1544 {
1545 CAN_INTEN(can_periph) |= interrupt;
1546 }
1547
1548 /*!
1549 \brief disable CAN interrupt
1550 \param[in] can_periph
1551 \arg CANx(x=0,1,2),the CAN2 only for GD32E50X_CL and GD32E508
1552 \param[in] interrupt
1553 one or more parameters can be selected which are shown as below:
1554 \arg CAN_INT_TME: transmit mailbox empty interrupt enable
1555 \arg CAN_INT_RFNE0: receive FIFO0 not empty interrupt enable
1556 \arg CAN_INT_RFF0: receive FIFO0 full interrupt enable
1557 \arg CAN_INT_RFO0: receive FIFO0 overfull interrupt enable
1558 \arg CAN_INT_RFNE1: receive FIFO1 not empty interrupt enable
1559 \arg CAN_INT_RFF1: receive FIFO1 full interrupt enable
1560 \arg CAN_INT_RFO1: receive FIFO1 overfull interrupt enable
1561 \arg CAN_INT_WERR: warning error interrupt enable
1562 \arg CAN_INT_PERR: passive error interrupt enable
1563 \arg CAN_INT_BO: bus-off interrupt enable
1564 \arg CAN_INT_ERRN: error number interrupt enable
1565 \arg CAN_INT_ERR: error interrupt enable
1566 \arg CAN_INT_WU: wakeup interrupt enable
1567 \arg CAN_INT_SLPW: sleep working interrupt enable
1568 \param[out] none
1569 \retval none
1570 */
1571 void can_interrupt_disable(uint32_t can_periph, uint32_t interrupt)
1572 {
1573 CAN_INTEN(can_periph) &= ~interrupt;
1574 }
1575
1576 /*!
1577 \brief get CAN flag state
1578 \param[in] can_periph
1579 \arg CANx(x=0,1,2),the CAN2 only for GD32E50X_CL and GD32E508
1580 \param[in] flag: CAN flags, refer to can_flag_enum
1581 only one parameter can be selected which is shown as below:
1582 \arg CAN_FLAG_RXL: RX level
1583 \arg CAN_FLAG_LASTRX: last sample value of RX pin
1584 \arg CAN_FLAG_RS: receiving state
1585 \arg CAN_FLAG_TS: transmitting state
1586 \arg CAN_FLAG_SLPIF: status change flag of entering sleep working mode
1587 \arg CAN_FLAG_WUIF: status change flag of wakeup from sleep working mode
1588 \arg CAN_FLAG_ERRIF: error flag
1589 \arg CAN_FLAG_SLPWS: sleep working state
1590 \arg CAN_FLAG_IWS: initial working state
1591 \arg CAN_FLAG_TMLS2: transmit mailbox 2 last sending in Tx FIFO
1592 \arg CAN_FLAG_TMLS1: transmit mailbox 1 last sending in Tx FIFO
1593 \arg CAN_FLAG_TMLS0: transmit mailbox 0 last sending in Tx FIFO
1594 \arg CAN_FLAG_TME2: transmit mailbox 2 empty
1595 \arg CAN_FLAG_TME1: transmit mailbox 1 empty
1596 \arg CAN_FLAG_TME0: transmit mailbox 0 empty
1597 \arg CAN_FLAG_MTE2: mailbox 2 transmit error
1598 \arg CAN_FLAG_MTE1: mailbox 1 transmit error
1599 \arg CAN_FLAG_MTE0: mailbox 0 transmit error
1600 \arg CAN_FLAG_MAL2: mailbox 2 arbitration lost
1601 \arg CAN_FLAG_MAL1: mailbox 1 arbitration lost
1602 \arg CAN_FLAG_MAL0: mailbox 0 arbitration lost
1603 \arg CAN_FLAG_MTFNERR2: mailbox 2 transmit finished with no error
1604 \arg CAN_FLAG_MTFNERR1: mailbox 1 transmit finished with no error
1605 \arg CAN_FLAG_MTFNERR0: mailbox 0 transmit finished with no error
1606 \arg CAN_FLAG_MTF2: mailbox 2 transmit finished
1607 \arg CAN_FLAG_MTF1: mailbox 1 transmit finished
1608 \arg CAN_FLAG_MTF0: mailbox 0 transmit finished
1609 \arg CAN_FLAG_RFO0: receive FIFO0 overfull
1610 \arg CAN_FLAG_RFF0: receive FIFO0 full
1611 \arg CAN_FLAG_RFO1: receive FIFO1 overfull
1612 \arg CAN_FLAG_RFF1: receive FIFO1 full
1613 \arg CAN_FLAG_BOERR: bus-off error
1614 \arg CAN_FLAG_PERR: passive error
1615 \arg CAN_FLAG_WERR: warning error
1616 \param[out] none
1617 \retval FlagStatus: SET or RESET
1618 */
1619 FlagStatus can_flag_get(uint32_t can_periph, can_flag_enum flag)
1620 {
1621 /* get flag and interrupt enable state */
1622 if(RESET != (CAN_REG_VAL(can_periph, flag) & BIT(CAN_BIT_POS(flag)))){
1623 return SET;
1624 }else{
1625 return RESET;
1626 }
1627 }
1628
1629 /*!
1630 \brief clear CAN flag state
1631 \param[in] can_periph
1632 \arg CANx(x=0,1,2),the CAN2 only for GD32E50X_CL and GD32E508
1633 \param[in] flag: CAN flags, refer to can_flag_enum
1634 only one parameter can be selected which is shown as below:
1635 \arg CAN_FLAG_SLPIF: status change flag of entering sleep working mode
1636 \arg CAN_FLAG_WUIF: status change flag of wakeup from sleep working mode
1637 \arg CAN_FLAG_ERRIF: error flag
1638 \arg CAN_FLAG_MTE2: mailbox 2 transmit error
1639 \arg CAN_FLAG_MTE1: mailbox 1 transmit error
1640 \arg CAN_FLAG_MTE0: mailbox 0 transmit error
1641 \arg CAN_FLAG_MAL2: mailbox 2 arbitration lost
1642 \arg CAN_FLAG_MAL1: mailbox 1 arbitration lost
1643 \arg CAN_FLAG_MAL0: mailbox 0 arbitration lost
1644 \arg CAN_FLAG_MTFNERR2: mailbox 2 transmit finished with no error
1645 \arg CAN_FLAG_MTFNERR1: mailbox 1 transmit finished with no error
1646 \arg CAN_FLAG_MTFNERR0: mailbox 0 transmit finished with no error
1647 \arg CAN_FLAG_MTF2: mailbox 2 transmit finished
1648 \arg CAN_FLAG_MTF1: mailbox 1 transmit finished
1649 \arg CAN_FLAG_MTF0: mailbox 0 transmit finished
1650 \arg CAN_FLAG_RFO0: receive FIFO0 overfull
1651 \arg CAN_FLAG_RFF0: receive FIFO0 full
1652 \arg CAN_FLAG_RFO1: receive FIFO1 overfull
1653 \arg CAN_FLAG_RFF1: receive FIFO1 full
1654 \param[out] none
1655 \retval none
1656 */
1657 void can_flag_clear(uint32_t can_periph, can_flag_enum flag)
1658 {
1659 CAN_REG_VAL(can_periph, flag) |= BIT(CAN_BIT_POS(flag));
1660 }
1661
1662 /*!
1663 \brief get CAN interrupt flag state
1664 \param[in] can_periph
1665 \arg CANx(x=0,1,2),the CAN2 only for GD32E50X_CL and GD32E508
1666 \param[in] int_flag: CAN interrupt flags, refer to can_interrupt_flag_enum
1667 only one parameter can be selected which is shown as below:
1668 \arg CAN_INT_FLAG_SLPIF: status change interrupt flag of sleep working mode entering
1669 \arg CAN_INT_FLAG_WUIF: status change interrupt flag of wakeup from sleep working mode
1670 \arg CAN_INT_FLAG_ERRIF: error interrupt flag
1671 \arg CAN_INT_FLAG_MTF2: mailbox 2 transmit finished interrupt flag
1672 \arg CAN_INT_FLAG_MTF1: mailbox 1 transmit finished interrupt flag
1673 \arg CAN_INT_FLAG_MTF0: mailbox 0 transmit finished interrupt flag
1674 \arg CAN_INT_FLAG_RFO0: receive FIFO0 overfull interrupt flag
1675 \arg CAN_INT_FLAG_RFF0: receive FIFO0 full interrupt flag
1676 \arg CAN_INT_FLAG_RFL0: receive FIFO0 not empty interrupt flag
1677 \arg CAN_INT_FLAG_RFO1: receive FIFO1 overfull interrupt flag
1678 \arg CAN_INT_FLAG_RFF1: receive FIFO1 full interrupt flag
1679 \arg CAN_INT_FLAG_RFL1: receive FIFO1 not empty interrupt flag
1680 \arg CAN_INT_FLAG_ERRN: error number interrupt flag
1681 \arg CAN_INT_FLAG_BOERR: bus-off error interrupt flag
1682 \arg CAN_INT_FLAG_PERR: passive error interrupt flag
1683 \arg CAN_INT_FLAG_WERR: warning error interrupt flag
1684 \param[out] none
1685 \retval FlagStatus: SET or RESET
1686 */
1687 FlagStatus can_interrupt_flag_get(uint32_t can_periph, can_interrupt_flag_enum int_flag)
1688 {
1689 uint32_t ret1 = RESET;
1690 uint32_t ret2 = RESET;
1691
1692 /* get the staus of interrupt flag */
1693 if (int_flag == CAN_INT_FLAG_RFL0) {
1694 ret1 = can_receive_message_length_get(can_periph, CAN_FIFO0);
1695 } else if (int_flag == CAN_INT_FLAG_RFL1) {
1696 ret1 = can_receive_message_length_get(can_periph, CAN_FIFO1);
1697 } else if (int_flag == CAN_INT_FLAG_ERRN) {
1698 ret1 = can_error_get(can_periph);
1699 } else {
1700 ret1 = CAN_REG_VALS(can_periph, int_flag) & BIT(CAN_BIT_POS0(int_flag));
1701 }
1702 /* get the staus of interrupt enale bit */
1703 ret2 = CAN_INTEN(can_periph) & BIT(CAN_BIT_POS1(int_flag));
1704 if(ret1 && ret2){
1705 return SET;
1706 }else{
1707 return RESET;
1708 }
1709 }
1710
1711 /*!
1712 \brief clear CAN interrupt flag state
1713 \param[in] can_periph
1714 \arg CANx(x=0,1,2),the CAN2 only for GD32E50X_CL and GD32E508
1715 \param[in] int_flag: CAN interrupt flags, refer to can_interrupt_flag_enum
1716 only one parameter can be selected which is shown as below:
1717 \arg CAN_INT_FLAG_SLPIF: status change interrupt flag of sleep working mode entering
1718 \arg CAN_INT_FLAG_WUIF: status change interrupt flag of wakeup from sleep working mode
1719 \arg CAN_INT_FLAG_ERRIF: error interrupt flag
1720 \arg CAN_INT_FLAG_MTF2: mailbox 2 transmit finished interrupt flag
1721 \arg CAN_INT_FLAG_MTF1: mailbox 1 transmit finished interrupt flag
1722 \arg CAN_INT_FLAG_MTF0: mailbox 0 transmit finished interrupt flag
1723 \arg CAN_INT_FLAG_RFO0: receive FIFO0 overfull interrupt flag
1724 \arg CAN_INT_FLAG_RFF0: receive FIFO0 full interrupt flag
1725 \arg CAN_INT_FLAG_RFO1: receive FIFO1 overfull interrupt flag
1726 \arg CAN_INT_FLAG_RFF1: receive FIFO1 full interrupt flag
1727 \param[out] none
1728 \retval none
1729 */
1730 void can_interrupt_flag_clear(uint32_t can_periph, can_interrupt_flag_enum int_flag)
1731 {
1732 CAN_REG_VALS(can_periph, int_flag) |= BIT(CAN_BIT_POS0(int_flag));
1733 }
1734
1735 /*!
1736 \brief auto config can baud rate by frequency
1737 \param[in] freq: the frequency of the baud rate
1738 \param[out] none
1739 \retval CAN_BT register set value
1740 */
1741 static unsigned int dev_can_baudrate_set(uint32_t freq)
1742 {
1743 uint32_t reval;
1744 uint32_t baud_psc_min;
1745 uint32_t baud_psc;
1746 uint32_t temp;
1747 uint32_t bt_reg_config;
1748 uint32_t bits = 0U;
1749 uint32_t bs_div_value = 0U;
1750
1751 struct brate_data_str{
1752 uint32_t bits;
1753 uint32_t baud_psc;
1754 uint32_t min_num;
1755 };
1756
1757 struct brate_data_str brate_data = {0U, 0U, 0xFFFFFFFFU};
1758
1759 /* computes the value that the CAN_BT register needs to be configured */
1760 /* for CAN:(BAUDPSC[9:0] + 1) * ((BS1[3:0] + 1) + (BS2[2:0] + 1) + SJW(always 1)) */
1761 /* for CAN-FD:(BAUDPSC[9:0] + 1) * ((BS1[6:0] + 1) + (BS2[4:0] + 1) + SJW(always 1)) */
1762 bt_reg_config = (rcu_clock_freq_get(CK_APB1) / freq);
1763 /* BAUDPSC[9:0] minimum value */
1764 baud_psc_min = bt_reg_config / DEV_CAN_BT_SEG_MAX;
1765 /* BAUDPSC[9:0] maximum value */
1766 baud_psc = bt_reg_config / DEV_CAN_BT_SEG_MIN;
1767
1768 /* preference for larger baud_psc */
1769 while((baud_psc >= baud_psc_min) && (baud_psc < 0xFFFFU)){
1770 for(bits=0u; bits<=DEV_CAN_BT_SEG_MAX; bits++){
1771 temp = (bits + 3U) * (baud_psc + 1U);
1772
1773 /* get the combination of smallest difference */
1774 /* calculation the difference */
1775 if(temp>bt_reg_config){
1776 temp = temp - bt_reg_config;
1777 }else{
1778 temp = bt_reg_config - temp;
1779 }
1780 /* set the combination with small difference */
1781 if(temp<brate_data.min_num){
1782 brate_data.baud_psc = baud_psc;
1783 brate_data.bits = bits;
1784 brate_data.min_num = temp;
1785 }
1786 }
1787 baud_psc--;
1788 }
1789
1790 /* BS1 is 5 times of BS2 */
1791 bs_div_value = brate_data.bits / 5U;
1792 reval = (BT_BS1(brate_data.bits-bs_div_value))
1793 | (BT_BS2(bs_div_value))
1794 | ((0U << 24) & DEV_CAN_SJW_MASK)
1795 | ((brate_data.baud_psc) & DEV_CAN_BAUDPSC_MASK);
1796
1797 return reval;
1798 }
1799
1800 #ifdef GD32E508
1801 /*!
1802 \brief auto config can fd baud rate by frequency
1803 \param[in] freq: the frequency of the baud rate
1804 \param[out] none
1805 \retval CAN_BT register set value
1806 */
1807 static unsigned int dev_can_fd_baudrate_set(uint32_t freq)
1808 {
1809 uint32_t reval;
1810 uint32_t baud_psc;
1811 uint32_t baud_psc_max;
1812 uint32_t temp;
1813 uint32_t bt_reg_config;
1814 uint8_t flag;
1815 uint32_t bits = 0U;
1816
1817 struct brate_data_str{
1818 uint32_t bits;
1819 uint32_t baud_psc;
1820 uint32_t min_num;
1821 };
1822
1823 struct brate_data_str brate_data = {0U, 0U, 0xFFFFFFFFU};
1824
1825 flag = 0U;
1826 /* computes the value that the CAN_BT register needs to be configured */
1827 /* (BAUDPSC[9:0] + 1) * ((BS1[3:0] + 1) + (BS2[2:0] + 1) + SJW(always 1)) */
1828 bt_reg_config = (rcu_clock_freq_get(CK_APB1) / freq);
1829 /* BAUDPSC[9:0] minimum value */
1830 baud_psc = bt_reg_config / DEV_CAN_FD_BT_SEG_MAX;
1831 /* BAUDPSC[9:0] maximum value */
1832 baud_psc_max = bt_reg_config / DEV_CAN_FD_BT_SEG_MIN;
1833
1834 while((!flag) && (baud_psc < baud_psc_max)){
1835 for(bits=0u; bits<=DEV_CAN_FD_BT_SEG_MAX; bits++){
1836 temp = (bits + 3U) * (baud_psc + 1U);
1837
1838 /* get the combination of smallest difference */
1839 if(temp == bt_reg_config){
1840 flag = 1U;
1841 break;
1842 }else{
1843 /* calculation the difference */
1844 if(temp>bt_reg_config){
1845 temp = temp - bt_reg_config;
1846 }else{
1847 temp = bt_reg_config - temp;
1848 }
1849 /* set the combination with small difference */
1850 if(temp<brate_data.min_num){
1851 brate_data.baud_psc = baud_psc;
1852 brate_data.bits = bits;
1853 brate_data.min_num = temp;
1854 }
1855 }
1856 }
1857 if(flag){
1858 break;
1859 }
1860 baud_psc++;
1861 }
1862
1863 /* set the combination value */
1864 if(flag){
1865 reval = ((timing_pts[bits][1] << 20) & DEV_CAN_BS2_MASK)
1866 | ((timing_pts[bits][0] << 16) & DEV_CAN_BS1_MASK)
1867 | ((0U << 24) & DEV_CAN_FD_SJW_MASK)
1868 | ((baud_psc) & DEV_CAN_BAUDPSC_MASK);
1869 }else{
1870 reval = ((timing_pts[brate_data.bits][1] << 20) & DEV_CAN_BS2_MASK)
1871 | ((timing_pts[brate_data.bits][0] << 16) & DEV_CAN_BS1_MASK)
1872 | ((0U << 24) & DEV_CAN_FD_SJW_MASK)
1873 | ((brate_data.baud_psc) & DEV_CAN_BAUDPSC_MASK);
1874 }
1875
1876 return reval;
1877 }
1878 #endif /* GD32E508 */
1879