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