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