1 /*!
2 \file gd32vf103_can.c
3 \brief CAN driver
4
5 \version 2019-06-05, V1.0.0, firmware for GD32VF103
6 \version 2019-11-27, V1.0.1, firmware for GD32VF103
7 \version 2020-07-14, V1.0.2, firmware for GD32VF103
8 \version 2020-08-04, V1.1.0, firmware for GD32VF103
9 \version 2020-12-14, V1.1.1, firmware for GD32VF103
10 */
11
12 /*
13 Copyright (c) 2020, GigaDevice Semiconductor Inc.
14
15 Redistribution and use in source and binary forms, with or without modification,
16 are permitted provided that the following conditions are met:
17
18 1. Redistributions of source code must retain the above copyright notice, this
19 list of conditions and the following disclaimer.
20 2. Redistributions in binary form must reproduce the above copyright notice,
21 this list of conditions and the following disclaimer in the documentation
22 and/or other materials provided with the distribution.
23 3. Neither the name of the copyright holder nor the names of its contributors
24 may be used to endorse or promote products derived from this software without
25 specific prior written permission.
26
27 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
28 AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
29 WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
30 IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
31 INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
32 NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
33 PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
34 WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
35 ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
36 OF SUCH DAMAGE.
37 */
38
39 #include "gd32vf103_can.h"
40
41 #define CAN_ERROR_HANDLE(s) do{}while(1)
42
43 /*!
44 \brief deinitialize CAN
45 \param[in] can_periph
46 \arg CANx(x=0,1)
47 \param[out] none
48 \retval none
49 */
can_deinit(uint32_t can_periph)50 void can_deinit(uint32_t can_periph)
51 {
52 if(CAN0 == can_periph){
53 rcu_periph_reset_enable(RCU_CAN0RST);
54 rcu_periph_reset_disable(RCU_CAN0RST);
55 }else{
56 rcu_periph_reset_enable(RCU_CAN1RST);
57 rcu_periph_reset_disable(RCU_CAN1RST);
58 }
59 }
60
61 /*!
62 \brief initialize CAN parameter struct with a default value
63 \param[in] type: the type of CAN parameter struct
64 only one parameter can be selected which is shown as below:
65 \arg CAN_INIT_STRUCT: the CAN initial struct
66 \arg CAN_FILTER_STRUCT: the CAN filter struct
67 \arg CAN_TX_MESSAGE_STRUCT: the CAN TX message struct
68 \arg CAN_RX_MESSAGE_STRUCT: the CAN RX message struct
69 \param[in] p_struct: the pointer of the specific struct
70 \param[out] none
71 \retval none
72 */
can_struct_para_init(can_struct_type_enum type,void * p_struct)73 void can_struct_para_init(can_struct_type_enum type, void* p_struct)
74 {
75 uint8_t i;
76
77 /* get type of the struct */
78 switch(type){
79 /* used for can_init() */
80 case CAN_INIT_STRUCT:
81 ((can_parameter_struct*)p_struct)->auto_bus_off_recovery = DISABLE;
82 ((can_parameter_struct*)p_struct)->no_auto_retrans = DISABLE;
83 ((can_parameter_struct*)p_struct)->auto_wake_up = DISABLE;
84 ((can_parameter_struct*)p_struct)->prescaler = 0x03FFU;
85 ((can_parameter_struct*)p_struct)->rec_fifo_overwrite = DISABLE;
86 ((can_parameter_struct*)p_struct)->resync_jump_width = CAN_BT_SJW_1TQ;
87 ((can_parameter_struct*)p_struct)->time_segment_1 = CAN_BT_BS1_3TQ;
88 ((can_parameter_struct*)p_struct)->time_segment_2 = CAN_BT_BS2_1TQ;
89 ((can_parameter_struct*)p_struct)->time_triggered = DISABLE;
90 ((can_parameter_struct*)p_struct)->trans_fifo_order = DISABLE;
91 ((can_parameter_struct*)p_struct)->working_mode = GD32_CAN_NORMAL_MODE;
92
93 break;
94 /* used for can_filter_init() */
95 case CAN_FILTER_STRUCT:
96 ((can_filter_parameter_struct*)p_struct)->filter_bits = CAN_FILTERBITS_32BIT;
97 ((can_filter_parameter_struct*)p_struct)->filter_enable = DISABLE;
98 ((can_filter_parameter_struct*)p_struct)->filter_fifo_number = CAN_FIFO0;
99 ((can_filter_parameter_struct*)p_struct)->filter_list_high = 0x0000U;
100 ((can_filter_parameter_struct*)p_struct)->filter_list_low = 0x0000U;
101 ((can_filter_parameter_struct*)p_struct)->filter_mask_high = 0x0000U;
102 ((can_filter_parameter_struct*)p_struct)->filter_mask_low = 0x0000U;
103 ((can_filter_parameter_struct*)p_struct)->filter_mode = CAN_FILTERMODE_MASK;
104 ((can_filter_parameter_struct*)p_struct)->filter_number = 0U;
105
106 break;
107 /* used for can_message_transmit() */
108 case CAN_TX_MESSAGE_STRUCT:
109 for(i = 0U; i < 8U; i++){
110 ((can_trasnmit_message_struct*)p_struct)->tx_data[i] = 0U;
111 }
112
113 ((can_trasnmit_message_struct*)p_struct)->tx_dlen = 0u;
114 ((can_trasnmit_message_struct*)p_struct)->tx_efid = 0U;
115 ((can_trasnmit_message_struct*)p_struct)->tx_ff = (uint8_t)CAN_FF_STANDARD;
116 ((can_trasnmit_message_struct*)p_struct)->tx_ft = (uint8_t)CAN_FT_DATA;
117 ((can_trasnmit_message_struct*)p_struct)->tx_sfid = 0U;
118
119 break;
120 /* used for can_message_receive() */
121 case CAN_RX_MESSAGE_STRUCT:
122 for(i = 0U; i < 8U; i++){
123 ((can_receive_message_struct*)p_struct)->rx_data[i] = 0U;
124 }
125
126 ((can_receive_message_struct*)p_struct)->rx_dlen = 0U;
127 ((can_receive_message_struct*)p_struct)->rx_efid = 0U;
128 ((can_receive_message_struct*)p_struct)->rx_ff = (uint8_t)CAN_FF_STANDARD;
129 ((can_receive_message_struct*)p_struct)->rx_fi = 0U;
130 ((can_receive_message_struct*)p_struct)->rx_ft = (uint8_t)CAN_FT_DATA;
131 ((can_receive_message_struct*)p_struct)->rx_sfid = 0U;
132
133 break;
134
135 default:
136 CAN_ERROR_HANDLE("parameter is invalid \r\n");
137 }
138 }
139
140 /*!
141 \brief initialize CAN
142 \param[in] can_periph
143 \arg CANx(x=0,1)
144 \param[in] can_parameter_init: parameters for CAN initializtion
145 \arg working_mode: GD32_CAN_NORMAL_MODE, GD32_CAN_LOOPBACK_MODE, GD32_CAN_SILENT_MODE, GD32_CAN_SILENT_LOOPBACK_MODE
146 \arg resync_jump_width: CAN_BT_SJW_xTQ(x=1, 2, 3, 4)
147 \arg time_segment_1: CAN_BT_BS1_xTQ(1..16)
148 \arg time_segment_2: CAN_BT_BS2_xTQ(1..8)
149 \arg time_triggered: ENABLE or DISABLE
150 \arg auto_bus_off_recovery: ENABLE or DISABLE
151 \arg auto_wake_up: ENABLE or DISABLE
152 \arg no_auto_retrans: ENABLE or DISABLE
153 \arg rec_fifo_overwrite: ENABLE or DISABLE
154 \arg trans_fifo_order: ENABLE or DISABLE
155 \arg prescaler: 0x0001 - 0x0400
156 \param[out] none
157 \retval ErrStatus: SUCCESS or ERROR
158 */
can_init(uint32_t can_periph,can_parameter_struct * can_parameter_init)159 ErrStatus can_init(uint32_t can_periph, can_parameter_struct* can_parameter_init)
160 {
161 uint32_t timeout = GD32_CAN_TIMEOUT;
162 ErrStatus flag = ERROR;
163
164 /* disable sleep mode */
165 CAN_CTL(can_periph) &= ~CAN_CTL_SLPWMOD;
166 /* enable initialize mode */
167 CAN_CTL(can_periph) |= CAN_CTL_IWMOD;
168 /* wait ACK */
169 while((CAN_STAT_IWS != (CAN_STAT(can_periph) & CAN_STAT_IWS)) && (0U != timeout)){
170 timeout--;
171 }
172 /* check initialize working success */
173 if(CAN_STAT_IWS != (CAN_STAT(can_periph) & CAN_STAT_IWS)){
174 flag = ERROR;
175 }else{
176 /* set the bit timing register */
177 CAN_BT(can_periph) = (BT_MODE((uint32_t)can_parameter_init->working_mode) | \
178 BT_SJW((uint32_t)can_parameter_init->resync_jump_width) | \
179 BT_BS1((uint32_t)can_parameter_init->time_segment_1) | \
180 BT_BS2((uint32_t)can_parameter_init->time_segment_2) | \
181 BT_BAUDPSC(((uint32_t)(can_parameter_init->prescaler) - 1U)));
182
183 /* time trigger communication mode */
184 if(ENABLE == can_parameter_init->time_triggered){
185 CAN_CTL(can_periph) |= CAN_CTL_TTC;
186 }else{
187 CAN_CTL(can_periph) &= ~CAN_CTL_TTC;
188 }
189 /* automatic bus-off managment */
190 if(ENABLE == can_parameter_init->auto_bus_off_recovery){
191 CAN_CTL(can_periph) |= CAN_CTL_ABOR;
192 }else{
193 CAN_CTL(can_periph) &= ~CAN_CTL_ABOR;
194 }
195 /* automatic wakeup mode */
196 if(ENABLE == can_parameter_init->auto_wake_up){
197 CAN_CTL(can_periph) |= CAN_CTL_AWU;
198 }else{
199 CAN_CTL(can_periph) &= ~CAN_CTL_AWU;
200 }
201 /* automatic retransmission mode disable */
202 if(ENABLE == can_parameter_init->no_auto_retrans){
203 CAN_CTL(can_periph) |= CAN_CTL_ARD;
204 }else{
205 CAN_CTL(can_periph) &= ~CAN_CTL_ARD;
206 }
207 /* receive fifo overwrite mode */
208 if(ENABLE == can_parameter_init->rec_fifo_overwrite){
209 CAN_CTL(can_periph) |= CAN_CTL_RFOD;
210 }else{
211 CAN_CTL(can_periph) &= ~CAN_CTL_RFOD;
212 }
213 /* transmit fifo order */
214 if(ENABLE == can_parameter_init->trans_fifo_order){
215 CAN_CTL(can_periph) |= CAN_CTL_TFO;
216 }else{
217 CAN_CTL(can_periph) &= ~CAN_CTL_TFO;
218 }
219 /* disable initialize mode */
220 CAN_CTL(can_periph) &= ~CAN_CTL_IWMOD;
221 timeout = GD32_CAN_TIMEOUT;
222 /* wait the ACK */
223 while((CAN_STAT_IWS == (CAN_STAT(can_periph) & CAN_STAT_IWS)) && (0U != timeout)){
224 timeout--;
225 }
226 /* check exit initialize mode */
227 if(0U != timeout){
228 flag = SUCCESS;
229 }
230 }
231 return flag;
232 }
233
234 /*!
235 \brief initialize CAN filter
236 \param[in] can_filter_parameter_init: struct for CAN filter initialization
237 \arg filter_list_high: 0x0000 - 0xFFFF
238 \arg filter_list_low: 0x0000 - 0xFFFF
239 \arg filter_mask_high: 0x0000 - 0xFFFF
240 \arg filter_mask_low: 0x0000 - 0xFFFF
241 \arg filter_fifo_number: CAN_FIFO0, CAN_FIFO1
242 \arg filter_number: 0 - 27
243 \arg filter_mode: CAN_FILTERMODE_MASK, CAN_FILTERMODE_LIST
244 \arg filter_bits: CAN_FILTERBITS_32BIT, CAN_FILTERBITS_16BIT
245 \arg filter_enable: ENABLE or DISABLE
246 \param[out] none
247 \retval none
248 */
can_filter_init(can_filter_parameter_struct * can_filter_parameter_init)249 void can_filter_init(can_filter_parameter_struct* can_filter_parameter_init)
250 {
251 uint32_t val = 0U;
252
253 val = ((uint32_t)1) << (can_filter_parameter_init->filter_number);
254 /* filter lock disable */
255 CAN_FCTL(CAN0) |= CAN_FCTL_FLD;
256 /* disable filter */
257 CAN_FW(CAN0) &= ~(uint32_t)val;
258
259 /* filter 16 bits */
260 if(CAN_FILTERBITS_16BIT == can_filter_parameter_init->filter_bits){
261 /* set filter 16 bits */
262 CAN_FSCFG(CAN0) &= ~(uint32_t)val;
263 /* first 16 bits list and first 16 bits mask or first 16 bits list and second 16 bits list */
264 CAN_FDATA0(CAN0, can_filter_parameter_init->filter_number) = \
265 FDATA_MASK_HIGH((can_filter_parameter_init->filter_mask_low) & CAN_FILTER_MASK_16BITS) | \
266 FDATA_MASK_LOW((can_filter_parameter_init->filter_list_low) & CAN_FILTER_MASK_16BITS);
267 /* second 16 bits list and second 16 bits mask or third 16 bits list and fourth 16 bits list */
268 CAN_FDATA1(CAN0, can_filter_parameter_init->filter_number) = \
269 FDATA_MASK_HIGH((can_filter_parameter_init->filter_mask_high) & CAN_FILTER_MASK_16BITS) | \
270 FDATA_MASK_LOW((can_filter_parameter_init->filter_list_high) & CAN_FILTER_MASK_16BITS);
271 }
272 /* filter 32 bits */
273 if(CAN_FILTERBITS_32BIT == can_filter_parameter_init->filter_bits){
274 /* set filter 32 bits */
275 CAN_FSCFG(CAN0) |= (uint32_t)val;
276 /* 32 bits list or first 32 bits list */
277 CAN_FDATA0(CAN0, can_filter_parameter_init->filter_number) = \
278 FDATA_MASK_HIGH((can_filter_parameter_init->filter_list_high) & CAN_FILTER_MASK_16BITS) |
279 FDATA_MASK_LOW((can_filter_parameter_init->filter_list_low) & CAN_FILTER_MASK_16BITS);
280 /* 32 bits mask or second 32 bits list */
281 CAN_FDATA1(CAN0, can_filter_parameter_init->filter_number) = \
282 FDATA_MASK_HIGH((can_filter_parameter_init->filter_mask_high) & CAN_FILTER_MASK_16BITS) |
283 FDATA_MASK_LOW((can_filter_parameter_init->filter_mask_low) & CAN_FILTER_MASK_16BITS);
284 }
285
286 /* filter mode */
287 if(CAN_FILTERMODE_MASK == can_filter_parameter_init->filter_mode){
288 /* mask mode */
289 CAN_FMCFG(CAN0) &= ~(uint32_t)val;
290 }else{
291 /* list mode */
292 CAN_FMCFG(CAN0) |= (uint32_t)val;
293 }
294
295 /* filter FIFO */
296 if(CAN_FIFO0 == (can_filter_parameter_init->filter_fifo_number)){
297 /* FIFO0 */
298 CAN_FAFIFO(CAN0) &= ~(uint32_t)val;
299 }else{
300 /* FIFO1 */
301 CAN_FAFIFO(CAN0) |= (uint32_t)val;
302 }
303
304 /* filter working */
305 if(ENABLE == can_filter_parameter_init->filter_enable){
306
307 CAN_FW(CAN0) |= (uint32_t)val;
308 }
309
310 /* filter lock enable */
311 CAN_FCTL(CAN0) &= ~CAN_FCTL_FLD;
312 }
313
314 /*!
315 \brief set CAN1 fliter start bank number
316 \param[in] start_bank: CAN1 start bank number
317 only one parameter can be selected which is shown as below:
318 \arg (1..27)
319 \param[out] none
320 \retval none
321 */
can1_filter_start_bank(uint8_t start_bank)322 void can1_filter_start_bank(uint8_t start_bank)
323 {
324 /* filter lock disable */
325 CAN_FCTL(CAN0) |= CAN_FCTL_FLD;
326 /* set CAN1 filter start number */
327 CAN_FCTL(CAN0) &= ~(uint32_t)CAN_FCTL_HBC1F;
328 CAN_FCTL(CAN0) |= FCTL_HBC1F(start_bank);
329 /* filter lock enaable */
330 CAN_FCTL(CAN0) &= ~CAN_FCTL_FLD;
331 }
332
333 /*!
334 \brief enable CAN debug freeze
335 \param[in] can_periph
336 \arg CANx(x=0,1)
337 \param[out] none
338 \retval none
339 */
can_debug_freeze_enable(uint32_t can_periph)340 void can_debug_freeze_enable(uint32_t can_periph)
341 {
342 /* set DFZ bit */
343 CAN_CTL(can_periph) |= CAN_CTL_DFZ;
344 if(CAN0 == can_periph){
345 dbg_periph_enable(DBG_CAN0_HOLD);
346 }else{
347 dbg_periph_enable(DBG_CAN1_HOLD);
348 }
349 }
350
351 /*!
352 \brief disable CAN debug freeze
353 \param[in] can_periph
354 \arg CANx(x=0,1)
355 \param[out] none
356 \retval none
357 */
can_debug_freeze_disable(uint32_t can_periph)358 void can_debug_freeze_disable(uint32_t can_periph)
359 {
360 /* set DFZ bit */
361 CAN_CTL(can_periph) &= ~CAN_CTL_DFZ;
362 if(CAN0 == can_periph){
363 dbg_periph_disable(DBG_CAN0_HOLD);
364 }else{
365 dbg_periph_disable(DBG_CAN1_HOLD);
366 }
367 }
368
369 /*!
370 \brief enable CAN time trigger mode
371 \param[in] can_periph
372 \arg CANx(x=0,1)
373 \param[out] none
374 \retval none
375 */
can_time_trigger_mode_enable(uint32_t can_periph)376 void can_time_trigger_mode_enable(uint32_t can_periph)
377 {
378 uint8_t mailbox_number;
379
380 /* enable the tcc mode */
381 CAN_CTL(can_periph) |= CAN_CTL_TTC;
382 /* enable time stamp */
383 for(mailbox_number = 0U; mailbox_number < 3U; mailbox_number++){
384 CAN_TMP(can_periph, mailbox_number) |= CAN_TMP_TSEN;
385 }
386 }
387
388 /*!
389 \brief disable CAN time trigger mode
390 \param[in] can_periph
391 \arg CANx(x=0,1)
392 \param[out] none
393 \retval none
394 */
can_time_trigger_mode_disable(uint32_t can_periph)395 void can_time_trigger_mode_disable(uint32_t can_periph)
396 {
397 uint8_t mailbox_number;
398
399 /* disable the TCC mode */
400 CAN_CTL(can_periph) &= ~CAN_CTL_TTC;
401 /* reset TSEN bits */
402 for(mailbox_number = 0U; mailbox_number < 3U; mailbox_number++){
403 CAN_TMP(can_periph, mailbox_number) &= ~CAN_TMP_TSEN;
404 }
405 }
406
407 /*!
408 \brief transmit CAN message
409 \param[in] can_periph
410 \arg CANx(x=0,1)
411 \param[in] transmit_message: struct for CAN transmit message
412 \arg tx_sfid: 0x00000000 - 0x000007FF
413 \arg tx_efid: 0x00000000 - 0x1FFFFFFF
414 \arg tx_ff: CAN_FF_STANDARD, CAN_FF_EXTENDED
415 \arg tx_ft: CAN_FT_DATA, CAN_FT_REMOTE
416 \arg tx_dlen: 0 - 8
417 \arg tx_data[]: 0x00 - 0xFF
418 \param[out] none
419 \retval mailbox_number
420 */
can_message_transmit(uint32_t can_periph,can_trasnmit_message_struct * transmit_message)421 uint8_t can_message_transmit(uint32_t can_periph, can_trasnmit_message_struct* transmit_message)
422 {
423 uint8_t mailbox_number = CAN_MAILBOX0;
424
425 /* select one empty mailbox */
426 if(CAN_TSTAT_TME0 == (CAN_TSTAT(can_periph)&CAN_TSTAT_TME0)){
427 mailbox_number = CAN_MAILBOX0;
428 }else if(CAN_TSTAT_TME1 == (CAN_TSTAT(can_periph)&CAN_TSTAT_TME1)){
429 mailbox_number = CAN_MAILBOX1;
430 }else if(CAN_TSTAT_TME2 == (CAN_TSTAT(can_periph)&CAN_TSTAT_TME2)){
431 mailbox_number = CAN_MAILBOX2;
432 }else{
433 mailbox_number = CAN_NOMAILBOX;
434 }
435 /* return no mailbox empty */
436 if(CAN_NOMAILBOX == mailbox_number){
437 return CAN_NOMAILBOX;
438 }
439
440 CAN_TMI(can_periph, mailbox_number) &= CAN_TMI_TEN;
441 if(CAN_FF_STANDARD == transmit_message->tx_ff){
442 /* set transmit mailbox standard identifier */
443 CAN_TMI(can_periph, mailbox_number) |= (uint32_t)(TMI_SFID(transmit_message->tx_sfid) | \
444 transmit_message->tx_ft);
445 }else{
446 /* set transmit mailbox extended identifier */
447 CAN_TMI(can_periph, mailbox_number) |= (uint32_t)(TMI_EFID(transmit_message->tx_efid) | \
448 transmit_message->tx_ff | \
449 transmit_message->tx_ft);
450 }
451 /* set the data length */
452 CAN_TMP(can_periph, mailbox_number) &= ~CAN_TMP_DLENC;
453 CAN_TMP(can_periph, mailbox_number) |= transmit_message->tx_dlen;
454 /* set the data */
455 CAN_TMDATA0(can_periph, mailbox_number) = TMDATA0_DB3(transmit_message->tx_data[3]) | \
456 TMDATA0_DB2(transmit_message->tx_data[2]) | \
457 TMDATA0_DB1(transmit_message->tx_data[1]) | \
458 TMDATA0_DB0(transmit_message->tx_data[0]);
459 CAN_TMDATA1(can_periph, mailbox_number) = TMDATA1_DB7(transmit_message->tx_data[7]) | \
460 TMDATA1_DB6(transmit_message->tx_data[6]) | \
461 TMDATA1_DB5(transmit_message->tx_data[5]) | \
462 TMDATA1_DB4(transmit_message->tx_data[4]);
463 /* enable transmission */
464 CAN_TMI(can_periph, mailbox_number) |= CAN_TMI_TEN;
465
466 return mailbox_number;
467 }
468
469 /*!
470 \brief get CAN transmit state
471 \param[in] can_periph
472 \arg CANx(x=0,1)
473 \param[in] mailbox_number
474 only one parameter can be selected which is shown as below:
475 \arg CAN_MAILBOX(x=0,1,2)
476 \param[out] none
477 \retval can_transmit_state_enum
478 */
can_transmit_states(uint32_t can_periph,uint8_t mailbox_number)479 can_transmit_state_enum can_transmit_states(uint32_t can_periph, uint8_t mailbox_number)
480 {
481 can_transmit_state_enum state = CAN_TRANSMIT_FAILED;
482 uint32_t val = 0U;
483
484 /* check selected mailbox state */
485 switch(mailbox_number){
486 /* mailbox0 */
487 case CAN_MAILBOX0:
488 val = CAN_TSTAT(can_periph) & (CAN_TSTAT_MTF0 | CAN_TSTAT_MTFNERR0 | CAN_TSTAT_TME0);
489 break;
490 /* mailbox1 */
491 case CAN_MAILBOX1:
492 val = CAN_TSTAT(can_periph) & (CAN_TSTAT_MTF1 | CAN_TSTAT_MTFNERR1 | CAN_TSTAT_TME1);
493 break;
494 /* mailbox2 */
495 case CAN_MAILBOX2:
496 val = CAN_TSTAT(can_periph) & (CAN_TSTAT_MTF2 | CAN_TSTAT_MTFNERR2 | CAN_TSTAT_TME2);
497 break;
498 default:
499 val = CAN_TRANSMIT_FAILED;
500 break;
501 }
502
503 switch(val){
504 /* transmit pending */
505 case (CAN_STATE_PENDING):
506 state = CAN_TRANSMIT_PENDING;
507 break;
508 /* mailbox0 transmit succeeded */
509 case (CAN_TSTAT_MTF0 | CAN_TSTAT_MTFNERR0 | CAN_TSTAT_TME0):
510 state = CAN_TRANSMIT_OK;
511 break;
512 /* mailbox1 transmit succeeded */
513 case (CAN_TSTAT_MTF1 | CAN_TSTAT_MTFNERR1 | CAN_TSTAT_TME1):
514 state = CAN_TRANSMIT_OK;
515 break;
516 /* mailbox2 transmit succeeded */
517 case (CAN_TSTAT_MTF2 | CAN_TSTAT_MTFNERR2 | CAN_TSTAT_TME2):
518 state = CAN_TRANSMIT_OK;
519 break;
520 /* transmit failed */
521 default:
522 state = CAN_TRANSMIT_FAILED;
523 break;
524 }
525 return state;
526 }
527
528 /*!
529 \brief stop CAN transmission
530 \param[in] can_periph
531 \arg CANx(x=0,1)
532 \param[in] mailbox_number
533 only one parameter can be selected which is shown as below:
534 \arg CAN_MAILBOXx(x=0,1,2)
535 \param[out] none
536 \retval none
537 */
can_transmission_stop(uint32_t can_periph,uint8_t mailbox_number)538 void can_transmission_stop(uint32_t can_periph, uint8_t mailbox_number)
539 {
540 if(CAN_MAILBOX0 == mailbox_number){
541 CAN_TSTAT(can_periph) |= CAN_TSTAT_MST0;
542 while(CAN_TSTAT_MST0 == (CAN_TSTAT(can_periph) & CAN_TSTAT_MST0)){
543 }
544 }else if(CAN_MAILBOX1 == mailbox_number){
545 CAN_TSTAT(can_periph) |= CAN_TSTAT_MST1;
546 while(CAN_TSTAT_MST1 == (CAN_TSTAT(can_periph) & CAN_TSTAT_MST1)){
547 }
548 }else if(CAN_MAILBOX2 == mailbox_number){
549 CAN_TSTAT(can_periph) |= CAN_TSTAT_MST2;
550 while(CAN_TSTAT_MST2 == (CAN_TSTAT(can_periph) & CAN_TSTAT_MST2)){
551 }
552 }else{
553 /* illegal parameters */
554 }
555 }
556
557 /*!
558 \brief CAN receive message
559 \param[in] can_periph
560 \arg CANx(x=0,1)
561 \param[in] fifo_number
562 \arg CAN_FIFOx(x=0,1)
563 \param[out] receive_message: struct for CAN receive message
564 \arg rx_sfid: 0x00000000 - 0x000007FF
565 \arg rx_efid: 0x00000000 - 0x1FFFFFFF
566 \arg rx_ff: CAN_FF_STANDARD, CAN_FF_EXTENDED
567 \arg rx_ft: CAN_FT_DATA, CAN_FT_REMOTE
568 \arg rx_dlen: 0 - 8
569 \arg rx_data[]: 0x00 - 0xFF
570 \arg rx_fi: 0 - 27
571 \retval none
572 */
can_message_receive(uint32_t can_periph,uint8_t fifo_number,can_receive_message_struct * receive_message)573 void can_message_receive(uint32_t can_periph, uint8_t fifo_number, can_receive_message_struct* receive_message)
574 {
575 /* get the frame format */
576 receive_message->rx_ff = (uint8_t)(CAN_RFIFOMI_FF & CAN_RFIFOMI(can_periph, fifo_number));
577 if(CAN_FF_STANDARD == receive_message->rx_ff){
578 /* get standard identifier */
579 receive_message->rx_sfid = (uint32_t)(GET_RFIFOMI_SFID(CAN_RFIFOMI(can_periph, fifo_number)));
580 }else{
581 /* get extended identifier */
582 receive_message->rx_efid = (uint32_t)(GET_RFIFOMI_EFID(CAN_RFIFOMI(can_periph, fifo_number)));
583 }
584
585 /* get frame type */
586 receive_message->rx_ft = (uint8_t)(CAN_RFIFOMI_FT & CAN_RFIFOMI(can_periph, fifo_number));
587 /* filtering index */
588 receive_message->rx_fi = (uint8_t)(GET_RFIFOMP_FI(CAN_RFIFOMP(can_periph, fifo_number)));
589 /* get recevie data length */
590 receive_message->rx_dlen = (uint8_t)(GET_RFIFOMP_DLENC(CAN_RFIFOMP(can_periph, fifo_number)));
591
592 /* receive data */
593 receive_message -> rx_data[0] = (uint8_t)(GET_RFIFOMDATA0_DB0(CAN_RFIFOMDATA0(can_periph, fifo_number)));
594 receive_message -> rx_data[1] = (uint8_t)(GET_RFIFOMDATA0_DB1(CAN_RFIFOMDATA0(can_periph, fifo_number)));
595 receive_message -> rx_data[2] = (uint8_t)(GET_RFIFOMDATA0_DB2(CAN_RFIFOMDATA0(can_periph, fifo_number)));
596 receive_message -> rx_data[3] = (uint8_t)(GET_RFIFOMDATA0_DB3(CAN_RFIFOMDATA0(can_periph, fifo_number)));
597 receive_message -> rx_data[4] = (uint8_t)(GET_RFIFOMDATA1_DB4(CAN_RFIFOMDATA1(can_periph, fifo_number)));
598 receive_message -> rx_data[5] = (uint8_t)(GET_RFIFOMDATA1_DB5(CAN_RFIFOMDATA1(can_periph, fifo_number)));
599 receive_message -> rx_data[6] = (uint8_t)(GET_RFIFOMDATA1_DB6(CAN_RFIFOMDATA1(can_periph, fifo_number)));
600 receive_message -> rx_data[7] = (uint8_t)(GET_RFIFOMDATA1_DB7(CAN_RFIFOMDATA1(can_periph, fifo_number)));
601
602 /* release FIFO */
603 if(CAN_FIFO0 == fifo_number){
604 CAN_RFIFO0(can_periph) |= CAN_RFIFO0_RFD0;
605 }else{
606 CAN_RFIFO1(can_periph) |= CAN_RFIFO1_RFD1;
607 }
608 }
609
610 /*!
611 \brief release FIFO0
612 \param[in] can_periph
613 \arg CANx(x=0,1)
614 \param[in] fifo_number
615 only one parameter can be selected which is shown as below:
616 \arg CAN_FIFOx(x=0,1)
617 \param[out] none
618 \retval none
619 */
can_fifo_release(uint32_t can_periph,uint8_t fifo_number)620 void can_fifo_release(uint32_t can_periph, uint8_t fifo_number)
621 {
622 if(CAN_FIFO0 == fifo_number){
623 CAN_RFIFO0(can_periph) |= CAN_RFIFO0_RFD0;
624 }else if(CAN_FIFO1 == fifo_number){
625 CAN_RFIFO1(can_periph) |= CAN_RFIFO1_RFD1;
626 }else{
627 /* illegal parameters */
628 CAN_ERROR_HANDLE("CAN FIFO NUM is invalid \r\n");
629 }
630 }
631
632 /*!
633 \brief CAN receive message length
634 \param[in] can_periph
635 \arg CANx(x=0,1)
636 \param[in] fifo_number
637 only one parameter can be selected which is shown as below:
638 \arg CAN_FIFOx(x=0,1)
639 \param[out] none
640 \retval message length
641 */
can_receive_message_length_get(uint32_t can_periph,uint8_t fifo_number)642 uint8_t can_receive_message_length_get(uint32_t can_periph, uint8_t fifo_number)
643 {
644 uint8_t val = 0U;
645
646 if(CAN_FIFO0 == fifo_number){
647 /* FIFO0 */
648 val = (uint8_t)(CAN_RFIFO0(can_periph) & CAN_RFIF_RFL_MASK);
649 }else if(CAN_FIFO1 == fifo_number){
650 /* FIFO1 */
651 val = (uint8_t)(CAN_RFIFO1(can_periph) & CAN_RFIF_RFL_MASK);
652 }else{
653 /* illegal parameters */
654 }
655 return val;
656 }
657
658 /*!
659 \brief set CAN working mode
660 \param[in] can_periph
661 \arg CANx(x=0,1)
662 \param[in] can_working_mode
663 only one parameter can be selected which is shown as below:
664 \arg CAN_MODE_INITIALIZE
665 \arg CAN_MODE_NORMAL
666 \arg CAN_MODE_SLEEP
667 \param[out] none
668 \retval ErrStatus: SUCCESS or ERROR
669 */
can_working_mode_set(uint32_t can_periph,uint8_t working_mode)670 ErrStatus can_working_mode_set(uint32_t can_periph, uint8_t working_mode)
671 {
672 ErrStatus flag = ERROR;
673 /* timeout for IWS or also for SLPWS bits */
674 uint32_t timeout = GD32_CAN_TIMEOUT;
675
676 if(CAN_MODE_INITIALIZE == working_mode){
677 /* disable sleep mode */
678 CAN_CTL(can_periph) &= (~(uint32_t)CAN_CTL_SLPWMOD);
679 /* set initialize mode */
680 CAN_CTL(can_periph) |= (uint8_t)CAN_CTL_IWMOD;
681 /* wait the acknowledge */
682 while((CAN_STAT_IWS != (CAN_STAT(can_periph) & CAN_STAT_IWS)) && (0U != timeout)){
683 timeout--;
684 }
685 if(CAN_STAT_IWS != (CAN_STAT(can_periph) & CAN_STAT_IWS)){
686 flag = ERROR;
687 }else{
688 flag = SUCCESS;
689 }
690 }else if(CAN_MODE_NORMAL == working_mode){
691 /* enter normal mode */
692 CAN_CTL(can_periph) &= ~(uint32_t)(CAN_CTL_SLPWMOD | CAN_CTL_IWMOD);
693 /* wait the acknowledge */
694 while((0U != (CAN_STAT(can_periph) & (CAN_STAT_IWS | CAN_STAT_SLPWS))) && (0U != timeout)){
695 timeout--;
696 }
697 if(0U != (CAN_STAT(can_periph) & (CAN_STAT_IWS | CAN_STAT_SLPWS))){
698 flag = ERROR;
699 }else{
700 flag = SUCCESS;
701 }
702 }else if(CAN_MODE_SLEEP == working_mode){
703 /* disable initialize mode */
704 CAN_CTL(can_periph) &= (~(uint32_t)CAN_CTL_IWMOD);
705 /* set sleep mode */
706 CAN_CTL(can_periph) |= (uint8_t)CAN_CTL_SLPWMOD;
707 /* wait the acknowledge */
708 while((CAN_STAT_SLPWS != (CAN_STAT(can_periph) & CAN_STAT_SLPWS)) && (0U != timeout)){
709 timeout--;
710 }
711 if(CAN_STAT_SLPWS != (CAN_STAT(can_periph) & CAN_STAT_SLPWS)){
712 flag = ERROR;
713 }else{
714 flag = SUCCESS;
715 }
716 }else{
717 flag = ERROR;
718 }
719 return flag;
720 }
721
722 /*!
723 \brief wake up CAN
724 \param[in] can_periph
725 \arg CANx(x=0,1)
726 \param[out] none
727 \retval ErrStatus: SUCCESS or ERROR
728 */
can_wakeup(uint32_t can_periph)729 ErrStatus can_wakeup(uint32_t can_periph)
730 {
731 ErrStatus flag = ERROR;
732 uint32_t timeout = GD32_CAN_TIMEOUT;
733
734 /* wakeup */
735 CAN_CTL(can_periph) &= ~CAN_CTL_SLPWMOD;
736
737 while((0U != (CAN_STAT(can_periph) & CAN_STAT_SLPWS)) && (0x00U != timeout)){
738 timeout--;
739 }
740 /* check state */
741 if(0U != (CAN_STAT(can_periph) & CAN_STAT_SLPWS)){
742 flag = ERROR;
743 }else{
744 flag = SUCCESS;
745 }
746 return flag;
747 }
748
749 /*!
750 \brief get CAN error type
751 \param[in] can_periph
752 \arg CANx(x=0,1)
753 \param[out] none
754 \retval can_error_enum
755 \arg CAN_ERROR_NONE: no error
756 \arg CAN_ERROR_FILL: fill error
757 \arg CAN_ERROR_FORMATE: format error
758 \arg CAN_ERROR_ACK: ACK error
759 \arg CAN_ERROR_BITRECESSIVE: bit recessive
760 \arg CAN_ERROR_BITDOMINANTER: bit dominant error
761 \arg CAN_ERROR_CRC: CRC error
762 \arg CAN_ERROR_SOFTWARECFG: software configure
763 */
can_error_get(uint32_t can_periph)764 can_error_enum can_error_get(uint32_t can_periph)
765 {
766 can_error_enum error;
767 error = CAN_ERROR_NONE;
768
769 /* get error type */
770 error = (can_error_enum)(GET_ERR_ERRN(CAN_ERR(can_periph)));
771 return error;
772 }
773
774 /*!
775 \brief get CAN receive error number
776 \param[in] can_periph
777 \arg CANx(x=0,1)
778 \param[out] none
779 \retval error number
780 */
can_receive_error_number_get(uint32_t can_periph)781 uint8_t can_receive_error_number_get(uint32_t can_periph)
782 {
783 uint8_t val;
784
785 /* get error count */
786 val = (uint8_t)(GET_ERR_RECNT(CAN_ERR(can_periph)));
787 return val;
788 }
789
790 /*!
791 \brief get CAN transmit error number
792 \param[in] can_periph
793 \arg CANx(x=0,1)
794 \param[out] none
795 \retval error number
796 */
can_transmit_error_number_get(uint32_t can_periph)797 uint8_t can_transmit_error_number_get(uint32_t can_periph)
798 {
799 uint8_t val;
800
801 val = (uint8_t)(GET_ERR_TECNT(CAN_ERR(can_periph)));
802 return val;
803 }
804
805 /*!
806 \brief enable CAN interrupt
807 \param[in] can_periph
808 \arg CANx(x=0,1)
809 \param[in] interrupt
810 one or more parameters can be selected which are shown as below:
811 \arg CAN_INT_TME: transmit mailbox empty interrupt enable
812 \arg CAN_INT_RFNE0: receive FIFO0 not empty interrupt enable
813 \arg CAN_INT_RFF0: receive FIFO0 full interrupt enable
814 \arg CAN_INT_RFO0: receive FIFO0 overfull interrupt enable
815 \arg CAN_INT_RFNE1: receive FIFO1 not empty interrupt enable
816 \arg CAN_INT_RFF1: receive FIFO1 full interrupt enable
817 \arg CAN_INT_RFO1: receive FIFO1 overfull interrupt enable
818 \arg CAN_INT_WERR: warning error interrupt enable
819 \arg CAN_INT_PERR: passive error interrupt enable
820 \arg CAN_INT_BO: bus-off interrupt enable
821 \arg CAN_INT_ERRN: error number interrupt enable
822 \arg CAN_INT_ERR: error interrupt enable
823 \arg CAN_INT_WU: wakeup interrupt enable
824 \arg CAN_INT_SLPW: sleep working interrupt enable
825 \param[out] none
826 \retval none
827 */
can_interrupt_enable(uint32_t can_periph,uint32_t interrupt)828 void can_interrupt_enable(uint32_t can_periph, uint32_t interrupt)
829 {
830 CAN_INTEN(can_periph) |= interrupt;
831 }
832
833 /*!
834 \brief disable CAN interrupt
835 \param[in] can_periph
836 \arg CANx(x=0,1)
837 \param[in] interrupt
838 one or more parameters can be selected which are shown as below:
839 \arg CAN_INT_TME: transmit mailbox empty interrupt enable
840 \arg CAN_INT_RFNE0: receive FIFO0 not empty interrupt enable
841 \arg CAN_INT_RFF0: receive FIFO0 full interrupt enable
842 \arg CAN_INT_RFO0: receive FIFO0 overfull interrupt enable
843 \arg CAN_INT_RFNE1: receive FIFO1 not empty interrupt enable
844 \arg CAN_INT_RFF1: receive FIFO1 full interrupt enable
845 \arg CAN_INT_RFO1: receive FIFO1 overfull interrupt enable
846 \arg CAN_INT_WERR: warning error interrupt enable
847 \arg CAN_INT_PERR: passive error interrupt enable
848 \arg CAN_INT_BO: bus-off interrupt enable
849 \arg CAN_INT_ERRN: error number interrupt enable
850 \arg CAN_INT_ERR: error interrupt enable
851 \arg CAN_INT_WU: wakeup interrupt enable
852 \arg CAN_INT_SLPW: sleep working interrupt enable
853 \param[out] none
854 \retval none
855 */
can_interrupt_disable(uint32_t can_periph,uint32_t interrupt)856 void can_interrupt_disable(uint32_t can_periph, uint32_t interrupt)
857 {
858 CAN_INTEN(can_periph) &= ~interrupt;
859 }
860
861 /*!
862 \brief get CAN flag state
863 \param[in] can_periph
864 \arg CANx(x=0,1)
865 \param[in] flag: CAN flags, refer to can_flag_enum
866 only one parameter can be selected which is shown as below:
867 \arg CAN_FLAG_RXL: RX level
868 \arg CAN_FLAG_LASTRX: last sample value of RX pin
869 \arg CAN_FLAG_RS: receiving state
870 \arg CAN_FLAG_TS: transmitting state
871 \arg CAN_FLAG_SLPIF: status change flag of entering sleep working mode
872 \arg CAN_FLAG_WUIF: status change flag of wakeup from sleep working mode
873 \arg CAN_FLAG_ERRIF: error flag
874 \arg CAN_FLAG_SLPWS: sleep working state
875 \arg CAN_FLAG_IWS: initial working state
876 \arg CAN_FLAG_TMLS2: transmit mailbox 2 last sending in Tx FIFO
877 \arg CAN_FLAG_TMLS1: transmit mailbox 1 last sending in Tx FIFO
878 \arg CAN_FLAG_TMLS0: transmit mailbox 0 last sending in Tx FIFO
879 \arg CAN_FLAG_TME2: transmit mailbox 2 empty
880 \arg CAN_FLAG_TME1: transmit mailbox 1 empty
881 \arg CAN_FLAG_TME0: transmit mailbox 0 empty
882 \arg CAN_FLAG_MTE2: mailbox 2 transmit error
883 \arg CAN_FLAG_MTE1: mailbox 1 transmit error
884 \arg CAN_FLAG_MTE0: mailbox 0 transmit error
885 \arg CAN_FLAG_MAL2: mailbox 2 arbitration lost
886 \arg CAN_FLAG_MAL1: mailbox 1 arbitration lost
887 \arg CAN_FLAG_MAL0: mailbox 0 arbitration lost
888 \arg CAN_FLAG_MTFNERR2: mailbox 2 transmit finished with no error
889 \arg CAN_FLAG_MTFNERR1: mailbox 1 transmit finished with no error
890 \arg CAN_FLAG_MTFNERR0: mailbox 0 transmit finished with no error
891 \arg CAN_FLAG_MTF2: mailbox 2 transmit finished
892 \arg CAN_FLAG_MTF1: mailbox 1 transmit finished
893 \arg CAN_FLAG_MTF0: mailbox 0 transmit finished
894 \arg CAN_FLAG_RFO0: receive FIFO0 overfull
895 \arg CAN_FLAG_RFF0: receive FIFO0 full
896 \arg CAN_FLAG_RFO1: receive FIFO1 overfull
897 \arg CAN_FLAG_RFF1: receive FIFO1 full
898 \arg CAN_FLAG_BOERR: bus-off error
899 \arg CAN_FLAG_PERR: passive error
900 \arg CAN_FLAG_WERR: warning error
901 \param[out] none
902 \retval FlagStatus: SET or RESET
903 */
can_flag_get(uint32_t can_periph,can_flag_enum flag)904 FlagStatus can_flag_get(uint32_t can_periph, can_flag_enum flag)
905 {
906 /* get flag and interrupt enable state */
907 if(RESET != (CAN_REG_VAL(can_periph, flag) & BIT(CAN_BIT_POS(flag)))){
908 return SET;
909 }else{
910 return RESET;
911 }
912 }
913
914 /*!
915 \brief clear CAN flag state
916 \param[in] can_periph
917 \arg CANx(x=0,1)
918 \param[in] flag: CAN flags, refer to can_flag_enum
919 only one parameter can be selected which is shown as below:
920 \arg CAN_FLAG_SLPIF: status change flag of entering sleep working mode
921 \arg CAN_FLAG_WUIF: status change flag of wakeup from sleep working mode
922 \arg CAN_FLAG_ERRIF: error flag
923 \arg CAN_FLAG_MTE2: mailbox 2 transmit error
924 \arg CAN_FLAG_MTE1: mailbox 1 transmit error
925 \arg CAN_FLAG_MTE0: mailbox 0 transmit error
926 \arg CAN_FLAG_MAL2: mailbox 2 arbitration lost
927 \arg CAN_FLAG_MAL1: mailbox 1 arbitration lost
928 \arg CAN_FLAG_MAL0: mailbox 0 arbitration lost
929 \arg CAN_FLAG_MTFNERR2: mailbox 2 transmit finished with no error
930 \arg CAN_FLAG_MTFNERR1: mailbox 1 transmit finished with no error
931 \arg CAN_FLAG_MTFNERR0: mailbox 0 transmit finished with no error
932 \arg CAN_FLAG_MTF2: mailbox 2 transmit finished
933 \arg CAN_FLAG_MTF1: mailbox 1 transmit finished
934 \arg CAN_FLAG_MTF0: mailbox 0 transmit finished
935 \arg CAN_FLAG_RFO0: receive FIFO0 overfull
936 \arg CAN_FLAG_RFF0: receive FIFO0 full
937 \arg CAN_FLAG_RFO1: receive FIFO1 overfull
938 \arg CAN_FLAG_RFF1: receive FIFO1 full
939 \param[out] none
940 \retval none
941 */
can_flag_clear(uint32_t can_periph,can_flag_enum flag)942 void can_flag_clear(uint32_t can_periph, can_flag_enum flag)
943 {
944 CAN_REG_VAL(can_periph, flag) = BIT(CAN_BIT_POS(flag));
945 }
946
947 /*!
948 \brief get CAN interrupt flag state
949 \param[in] can_periph
950 \arg CANx(x=0,1)
951 \param[in] flag: CAN interrupt flags, refer to can_interrupt_flag_enum
952 only one parameter can be selected which is shown as below:
953 \arg CAN_INT_FLAG_SLPIF: status change interrupt flag of sleep working mode entering
954 \arg CAN_INT_FLAG_WUIF: status change interrupt flag of wakeup from sleep working mode
955 \arg CAN_INT_FLAG_ERRIF: error interrupt flag
956 \arg CAN_INT_FLAG_MTF2: mailbox 2 transmit finished interrupt flag
957 \arg CAN_INT_FLAG_MTF1: mailbox 1 transmit finished interrupt flag
958 \arg CAN_INT_FLAG_MTF0: mailbox 0 transmit finished interrupt flag
959 \arg CAN_INT_FLAG_RFO0: receive FIFO0 overfull interrupt flag
960 \arg CAN_INT_FLAG_RFF0: receive FIFO0 full interrupt flag
961 \arg CAN_INT_FLAG_RFL0: receive FIFO0 not empty interrupt flag
962 \arg CAN_INT_FLAG_RFO1: receive FIFO1 overfull interrupt flag
963 \arg CAN_INT_FLAG_RFF1: receive FIFO1 full interrupt flag
964 \arg CAN_INT_FLAG_RFL1: receive FIFO1 not empty interrupt flag
965 \arg CAN_INT_FLAG_ERRN: error number interrupt flag
966 \arg CAN_INT_FLAG_BOERR: bus-off error interrupt flag
967 \arg CAN_INT_FLAG_PERR: passive error interrupt flag
968 \arg CAN_INT_FLAG_WERR: warning error interrupt flag
969 \param[out] none
970 \retval FlagStatus: SET or RESET
971 */
can_interrupt_flag_get(uint32_t can_periph,can_interrupt_flag_enum flag)972 FlagStatus can_interrupt_flag_get(uint32_t can_periph, can_interrupt_flag_enum flag)
973 {
974 uint32_t ret1 = RESET;
975 uint32_t ret2 = RESET;
976
977 /* get the staus of interrupt flag */
978 if (flag == CAN_INT_FLAG_RFL0) {
979 ret1 = can_receive_message_length_get(can_periph, CAN_FIFO0);
980 } else if (flag == CAN_INT_FLAG_RFL1) {
981 ret1 = can_receive_message_length_get(can_periph, CAN_FIFO1);
982 } else if (flag == CAN_INT_FLAG_ERRN) {
983 ret1 = can_error_get(can_periph);
984 } else {
985 ret1 = CAN_REG_VALS(can_periph, flag) & BIT(CAN_BIT_POS0(flag));
986 }
987 /* get the staus of interrupt enale bit */
988 ret2 = CAN_INTEN(can_periph) & BIT(CAN_BIT_POS1(flag));
989 if(ret1 && ret2){
990 return SET;
991 }else{
992 return RESET;
993 }
994 }
995
996 /*!
997 \brief clear CAN interrupt flag state
998 \param[in] can_periph
999 \arg CANx(x=0,1)
1000 \param[in] flag: CAN interrupt flags, refer to can_interrupt_flag_enum
1001 only one parameter can be selected which is shown as below:
1002 \arg CAN_INT_FLAG_SLPIF: status change interrupt flag of sleep working mode entering
1003 \arg CAN_INT_FLAG_WUIF: status change interrupt flag of wakeup from sleep working mode
1004 \arg CAN_INT_FLAG_ERRIF: error interrupt flag
1005 \arg CAN_INT_FLAG_MTF2: mailbox 2 transmit finished interrupt flag
1006 \arg CAN_INT_FLAG_MTF1: mailbox 1 transmit finished interrupt flag
1007 \arg CAN_INT_FLAG_MTF0: mailbox 0 transmit finished interrupt flag
1008 \arg CAN_INT_FLAG_RFO0: receive FIFO0 overfull interrupt flag
1009 \arg CAN_INT_FLAG_RFF0: receive FIFO0 full interrupt flag
1010 \arg CAN_INT_FLAG_RFO1: receive FIFO1 overfull interrupt flag
1011 \arg CAN_INT_FLAG_RFF1: receive FIFO1 full interrupt flag
1012 \param[out] none
1013 \retval none
1014 */
can_interrupt_flag_clear(uint32_t can_periph,can_interrupt_flag_enum flag)1015 void can_interrupt_flag_clear(uint32_t can_periph, can_interrupt_flag_enum flag)
1016 {
1017 CAN_REG_VALS(can_periph, flag) = BIT(CAN_BIT_POS0(flag));
1018 }
1019