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