]> git.gir.st - tmk_keyboard.git/blob - tool/mbed/mbed-sdk/libraries/mbed/targets/hal/TARGET_Freescale/TARGET_KPSDK_MCUS/TARGET_KPSDK_CODE/hal/can/fsl_flexcan_hal.c
Squashed 'tmk_core/' changes from 7967731..b9e0ea0
[tmk_keyboard.git] / tool / mbed / mbed-sdk / libraries / mbed / targets / hal / TARGET_Freescale / TARGET_KPSDK_MCUS / TARGET_KPSDK_CODE / hal / can / fsl_flexcan_hal.c
1 /*
2 * Copyright (c) 2013 - 2014, Freescale Semiconductor, Inc.
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without modification,
6 * are permitted provided that the following conditions are met:
7 *
8 * o Redistributions of source code must retain the above copyright notice, this list
9 * of conditions and the following disclaimer.
10 *
11 * o Redistributions in binary form must reproduce the above copyright notice, this
12 * list of conditions and the following disclaimer in the documentation and/or
13 * other materials provided with the distribution.
14 *
15 * o Neither the name of Freescale Semiconductor, Inc. nor the names of its
16 * contributors may be used to endorse or promote products derived from this
17 * software without specific prior written permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
21 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
22 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
23 * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
24 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
25 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
26 * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
28 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29 */
30 #include "fsl_flexcan_hal.h"
31
32 #ifndef MBED_NO_FLEXCAN
33
34 /*******************************************************************************
35 * Variables
36 ******************************************************************************/
37
38 /*******************************************************************************
39 * Definitions
40 ******************************************************************************/
41
42 #define FLEXCAN_RX_FIFO_ID_FILTER_FORMATA_EXT_MASK (0x3FFFFFFFU) /*!< FlexCAN RX FIFO ID filter*/
43 /*! format A extended mask.*/
44 #define FLEXCAN_RX_FIFO_ID_FILTER_FORMATA_EXT_SHIFT (1U) /*!< FlexCAN RX FIFO ID filter*/
45 /*! format A extended shift.*/
46 #define FLEXCAN_RX_FIFO_ID_FILTER_FORMATA_STD_MASK (0x3FF80000U) /*!< FlexCAN RX FIFO ID filter*/
47 /*! format A standard mask.*/
48 #define FLEXCAN_RX_FIFO_ID_FILTER_FORMATA_STD_SHIFT (19U) /*!< FlexCAN RX FIFO ID filter*/
49 /*! format A standard shift.*/
50 #define FLEXCAN_RX_FIFO_ID_FILTER_FORMATB_EXT_MASK (0x3FFFU) /*!< FlexCAN RX FIFO ID filter*/
51 /*! format B extended mask.*/
52 #define FLEXCAN_RX_FIFO_ID_FILTER_FORMATB_EXT_SHIFT1 (16U) /*!< FlexCAN RX FIFO ID filter*/
53 /*! format B extended mask.*/
54 #define FLEXCAN_RX_FIFO_ID_FILTER_FORMATB_EXT_SHIFT2 (0U) /*!< FlexCAN RX FIFO ID filter*/
55 /*! format B extended mask.*/
56 #define FLEXCAN_RX_FIFO_ID_FILTER_FORMATB_STD_MASK (0x3FF8U) /*!< FlexCAN RX FIFO ID filter*/
57 /*! format B standard mask.*/
58 #define FLEXCAN_RX_FIFO_ID_FILTER_FORMATB_STD_SHIFT1 (19U) /*!< FlexCAN RX FIFO ID filter*/
59 /*! format B standard shift1.*/
60 #define FLEXCAN_RX_FIFO_ID_FILTER_FORMATB_STD_SHIFT2 (3U) /*!< FlexCAN RX FIFO ID filter*/
61 /*! format B standard shift2.*/
62 #define FLEXCAN_RX_FIFO_ID_FILTER_FORMATC_MASK (0xFFU) /*!< FlexCAN RX FIFO ID filter*/
63 /*! format C mask.*/
64 #define FLEXCAN_RX_FIFO_ID_FILTER_FORMATC_SHIFT1 (24U) /*!< FlexCAN RX FIFO ID filter*/
65 /*! format C shift1.*/
66 #define FLEXCAN_RX_FIFO_ID_FILTER_FORMATC_SHIFT2 (16U) /*!< FlexCAN RX FIFO ID filter*/
67 /*! format C shift2.*/
68 #define FLEXCAN_RX_FIFO_ID_FILTER_FORMATC_SHIFT3 (8U) /*!< FlexCAN RX FIFO ID filter*/
69 /*! format C shift3.*/
70 #define FLEXCAN_RX_FIFO_ID_FILTER_FORMATC_SHIFT4 (0U) /*!< FlexCAN RX FIFO ID filter*/
71 /*! format C shift4.*/
72 #define FLEXCAN_ALL_INT (0x0007U) /*!< Masks for wakeup, error, bus off*/
73 /*! interrupts*/
74 #define FLEXCAN_BYTE_DATA_FIELD_MASK (0xFFU) /*!< Masks for byte data field.*/
75
76 /*******************************************************************************
77 * Code
78 ******************************************************************************/
79
80 /*FUNCTION**********************************************************************
81 *
82 * Function Name : FLEXCAN_HAL_Enable
83 * Description : Enable FlexCAN module.
84 * This function will enable FlexCAN module clock.
85 *
86 *END**************************************************************************/
87 flexcan_status_t FLEXCAN_HAL_Enable(uint32_t canBaseAddr)
88 {
89 /* Check for low power mode*/
90 if(BR_CAN_MCR_LPMACK(canBaseAddr))
91 {
92 /* Enable clock*/
93 HW_CAN_MCR_CLR(canBaseAddr, BM_CAN_MCR_MDIS);
94 /* Wait until enabled*/
95 while (BR_CAN_MCR_LPMACK(canBaseAddr)){}
96 }
97
98 return (kStatus_FLEXCAN_Success);
99 }
100
101 /*FUNCTION**********************************************************************
102 *
103 * Function Name : FLEXCAN_HAL_Disable
104 * Description : Disable FlexCAN module.
105 * This function will disable FlexCAN module clock.
106 *
107 *END**************************************************************************/
108 flexcan_status_t FLEXCAN_HAL_Disable(uint32_t canBaseAddr)
109 {
110 /* To access the memory mapped registers*/
111 /* Entre disable mode (hard reset).*/
112 if(BR_CAN_MCR_MDIS(canBaseAddr) == 0x0)
113 {
114 /* Clock disable (module)*/
115 BW_CAN_MCR_MDIS(canBaseAddr, 0x1);
116
117 /* Wait until disable mode acknowledged*/
118 while (!(BR_CAN_MCR_LPMACK(canBaseAddr))){}
119 }
120
121 return (kStatus_FLEXCAN_Success);
122 }
123
124 /*FUNCTION**********************************************************************
125 *
126 * Function Name : FLEXCAN_HAL_SelectClock
127 * Description : Select FlexCAN clock source.
128 * This function will select either internal bus clock or external clock as
129 * FlexCAN clock source.
130 *
131 *END**************************************************************************/
132 flexcan_status_t FLEXCAN_HAL_SelectClock(
133 uint32_t canBaseAddr,
134 flexcan_clk_source_t clk)
135 {
136 if (clk == kFlexCanClkSource_Ipbus)
137 {
138 /* Internal bus clock (fsys/2)*/
139 BW_CAN_CTRL1_CLKSRC(canBaseAddr, 0x1);
140 }
141 else if (clk == kFlexCanClkSource_Osc)
142 {
143 /* External clock*/
144 BW_CAN_CTRL1_CLKSRC(canBaseAddr, 0x0);
145 }
146 else
147 {
148 return (kStatus_FLEXCAN_InvalidArgument);
149 }
150
151 return (kStatus_FLEXCAN_Success);
152 }
153
154 /*FUNCTION**********************************************************************
155 *
156 * Function Name : FLEXCAN_HAL_Init
157 * Description : Initialize FlexCAN module.
158 * This function will reset FlexCAN module, set maximum number of message
159 * buffers, initialize all message buffers as inactive, enable RX FIFO
160 * if needed, mask all mask bits, and disable all MB interrupts.
161 *
162 *END**************************************************************************/
163 flexcan_status_t FLEXCAN_HAL_Init(uint32_t canBaseAddr, const flexcan_user_config_t *data)
164 {
165 uint32_t i;
166 volatile CAN_Type *flexcan_reg_ptr;
167
168 assert(data);
169
170 flexcan_reg_ptr = ((CAN_Type *)canBaseAddr);
171 if (NULL == flexcan_reg_ptr)
172 {
173 return (kStatus_FLEXCAN_InvalidArgument);
174 }
175
176 /* Reset the FLEXCAN*/
177 BW_CAN_MCR_SOFTRST(canBaseAddr, 0x1);
178
179 /* Wait for reset cycle to complete*/
180 while (BR_CAN_MCR_SOFTRST(canBaseAddr)){}
181
182 /* Set Freeze, Halt*/
183 BW_CAN_MCR_FRZ(canBaseAddr, 0x1);
184 BW_CAN_MCR_HALT(canBaseAddr, 0x1);
185
186 /* check for freeze Ack*/
187 while ((!BR_CAN_MCR_FRZACK(canBaseAddr)) ||
188 (!BR_CAN_MCR_NOTRDY(canBaseAddr))){}
189
190 /* Set maximum number of message buffers*/
191 BW_CAN_MCR_MAXMB(canBaseAddr, data->max_num_mb);
192
193 /* Initialize all message buffers as inactive*/
194 for (i = 0; i < data->max_num_mb; i++)
195 {
196 flexcan_reg_ptr->MB[i].CS = 0x0;
197 flexcan_reg_ptr->MB[i].ID = 0x0;
198 flexcan_reg_ptr->MB[i].WORD0 = 0x0;
199 flexcan_reg_ptr->MB[i].WORD1 = 0x0;
200 }
201
202 /* Enable RX FIFO if need*/
203 if (data->is_rx_fifo_needed)
204 {
205 /* Enable RX FIFO*/
206 BW_CAN_MCR_RFEN(canBaseAddr, 0x1);
207 /* Set the number of the RX FIFO filters needed*/
208 BW_CAN_CTRL2_RFFN(canBaseAddr, data->num_id_filters);
209 /* RX FIFO global mask*/
210 HW_CAN_RXFGMASK_WR(canBaseAddr, CAN_ID_EXT(CAN_RXFGMASK_FGM_MASK));
211 for (i = 0; i < data->max_num_mb; i++)
212 {
213 /* RX individual mask*/
214 HW_CAN_RXIMRn_WR(canBaseAddr, i, CAN_ID_EXT(CAN_RXIMR_MI_MASK));
215 }
216 }
217
218 /* Rx global mask*/
219 HW_CAN_RXMGMASK_WR(canBaseAddr, CAN_ID_EXT(CAN_RXMGMASK_MG_MASK));
220
221 /* Rx reg 14 mask*/
222 HW_CAN_RX14MASK_WR(canBaseAddr, CAN_ID_EXT(CAN_RX14MASK_RX14M_MASK));
223
224 /* Rx reg 15 mask*/
225 HW_CAN_RX15MASK_WR(canBaseAddr, CAN_ID_EXT(CAN_RX15MASK_RX15M_MASK));
226
227 /* De-assert Freeze Mode*/
228 BW_CAN_MCR_HALT(canBaseAddr, 0x0);
229 BW_CAN_MCR_FRZ(canBaseAddr, 0x0);
230
231 /* Wait till exit of freeze mode*/
232 while(BR_CAN_MCR_FRZACK(canBaseAddr)){}
233
234 /* Disable all MB interrupts*/
235 HW_CAN_IMASK1_WR(canBaseAddr, 0x0);
236
237 return (kStatus_FLEXCAN_Success);
238 }
239
240 /*FUNCTION**********************************************************************
241 *
242 * Function Name : FLEXCAN_HAL_SetTimeSegments
243 * Description : Set FlexCAN time segments.
244 * This function will set all FlexCAN time segments which define the length of
245 * Propagation Segment in the bit time, the length of Phase Buffer Segment 2 in
246 * the bit time, the length of Phase Buffer Segment 1 in the bit time, the ratio
247 * between the PE clock frequency and the Serial Clock (Sclock) frequency, and
248 * the maximum number of time quanta that a bit time can be changed by one
249 * resynchronization. (One time quantum is equal to the Sclock period.)
250 *
251 *END**************************************************************************/
252 void FLEXCAN_HAL_SetTimeSegments(
253 uint32_t canBaseAddr,
254 flexcan_time_segment_t *time_seg)
255 {
256 /* Set Freeze mode*/
257 BW_CAN_MCR_FRZ(canBaseAddr, 0x1);
258 BW_CAN_MCR_HALT(canBaseAddr, 0x1);
259
260 /* Wait for entering the freeze mode*/
261 while(!(BR_CAN_MCR_FRZACK(canBaseAddr))) {}
262
263 /* Set FlexCAN time segments*/
264 HW_CAN_CTRL1_CLR(canBaseAddr, (CAN_CTRL1_PROPSEG_MASK | CAN_CTRL1_PSEG2_MASK |
265 CAN_CTRL1_PSEG1_MASK | CAN_CTRL1_PRESDIV_MASK) |
266 CAN_CTRL1_RJW_MASK);
267 HW_CAN_CTRL1_SET(canBaseAddr, (CAN_CTRL1_PROPSEG(time_seg->propseg) |
268 CAN_CTRL1_PSEG2(time_seg->pseg2) |
269 CAN_CTRL1_PSEG1(time_seg->pseg1) |
270 CAN_CTRL1_PRESDIV(time_seg->pre_divider) |
271 CAN_CTRL1_RJW(time_seg->rjw)));
272
273 /* De-assert Freeze mode*/
274 BW_CAN_MCR_HALT(canBaseAddr, 0x0);
275 BW_CAN_MCR_FRZ(canBaseAddr, 0x0);
276
277 /* Wait till exit of freeze mode*/
278 while(BR_CAN_MCR_FRZACK(canBaseAddr)){}
279 }
280
281 /*FUNCTION**********************************************************************
282 *
283 * Function Name : FLEXCAN_HAL_GetTimeSegments
284 * Description : Get FlexCAN time segments.
285 * This function will get all FlexCAN time segments defined.
286 *
287 *END**************************************************************************/
288 void FLEXCAN_HAL_GetTimeSegments(
289 uint32_t canBaseAddr,
290 flexcan_time_segment_t *time_seg)
291 {
292 time_seg->pre_divider = BR_CAN_CTRL1_PRESDIV(canBaseAddr);
293 time_seg->propseg = BR_CAN_CTRL1_PROPSEG(canBaseAddr);
294 time_seg->pseg1 = BR_CAN_CTRL1_PSEG1(canBaseAddr);
295 time_seg->pseg2 = BR_CAN_CTRL1_PSEG2(canBaseAddr);
296 time_seg->rjw = BR_CAN_CTRL1_RJW(canBaseAddr);
297 }
298
299 /*FUNCTION**********************************************************************
300 *
301 * Function Name : FLEXCAN_HAL_SetMbTx
302 * Description : Configure a message buffer for transmission.
303 * This function will first check if RX FIFO is enabled. If RX FIFO is enabled,
304 * the function will make sure if the MB requested is not occupied by RX FIFO
305 * and ID filter table. Then this function will copy user's buffer into the
306 * message buffer data area and configure the message buffer as required for
307 * transmission.
308 *
309 *END**************************************************************************/
310 flexcan_status_t FLEXCAN_HAL_SetMbTx(
311 uint32_t canBaseAddr,
312 const flexcan_user_config_t *data,
313 uint32_t mb_idx,
314 flexcan_mb_code_status_t *cs,
315 uint32_t msg_id,
316 uint8_t *mb_data)
317 {
318 uint32_t i;
319 uint32_t val1, val2 = 1, temp, temp1;
320
321 assert(data);
322
323 volatile CAN_Type *flexcan_reg_ptr;
324
325 flexcan_reg_ptr = ((CAN_Type *)canBaseAddr);
326 if (NULL == flexcan_reg_ptr)
327 {
328 return (kStatus_FLEXCAN_InvalidArgument);
329 }
330
331 if (mb_idx >= data->max_num_mb)
332 {
333 return (kStatus_FLEXCAN_OutOfRange);
334 }
335
336 /* Check if RX FIFO is enabled*/
337 if (BR_CAN_MCR_RFEN(canBaseAddr))
338 {
339 /* Get the number of RX FIFO Filters*/
340 val1 = (BR_CAN_CTRL2_RFFN(canBaseAddr));
341 /* Get the number if MBs occupied by RX FIFO and ID filter table*/
342 /* the Rx FIFO occupies the memory space originally reserved for MB0-5*/
343 /* Every number of RFFN means 8 number of RX FIFO filters*/
344 /* and every 4 number of RX FIFO filters occupied one MB*/
345 val2 = 6 + (val1 + 1) * 8 / 4;
346
347 if (mb_idx <= (val2 - 1))
348 {
349 return (kStatus_FLEXCAN_InvalidArgument);
350 }
351 }
352
353 /* Copy user's buffer into the message buffer data area*/
354 if (mb_data != NULL)
355 {
356 flexcan_reg_ptr->MB[mb_idx].WORD0 = 0x0;
357 flexcan_reg_ptr->MB[mb_idx].WORD1 = 0x0;
358
359 for (i = 0; i < cs->data_length; i++ )
360 {
361 temp1 = (*(mb_data + i));
362 if (i < 4)
363 {
364 temp = temp1 << ((3 - i) * 8);
365 flexcan_reg_ptr->MB[mb_idx].WORD0 |= temp;
366 }
367 else
368 {
369 temp = temp1 << ((7 - i) * 8);
370 flexcan_reg_ptr->MB[mb_idx].WORD1 |= temp;
371 }
372 }
373 }
374
375 /* Set the ID according the format structure*/
376 if (cs->msg_id_type == kFlexCanMbId_Ext)
377 {
378 /* ID [28-0]*/
379 flexcan_reg_ptr->MB[mb_idx].ID &= ~(CAN_ID_STD_MASK | CAN_ID_EXT_MASK);
380 flexcan_reg_ptr->MB[mb_idx].ID |= (msg_id & (CAN_ID_STD_MASK | CAN_ID_EXT_MASK));
381
382 /* Set IDE*/
383 flexcan_reg_ptr->MB[mb_idx].CS |= CAN_CS_IDE_MASK;
384
385 /* Clear SRR bit*/
386 flexcan_reg_ptr->MB[mb_idx].CS &= ~CAN_CS_SRR_MASK;
387
388 /* Set the length of data in bytes*/
389 flexcan_reg_ptr->MB[mb_idx].CS &= ~CAN_CS_DLC_MASK;
390 flexcan_reg_ptr->MB[mb_idx].CS |= CAN_CS_DLC(cs->data_length);
391
392 /* Set MB CODE*/
393 /* Reset the code*/
394 if (cs->code != kFlexCanTX_NotUsed)
395 {
396 if (cs->code == kFlexCanTX_Remote)
397 {
398 /* Set RTR bit*/
399 flexcan_reg_ptr->MB[mb_idx].CS |= CAN_CS_RTR_MASK;
400 cs->code = kFlexCanTX_Data;
401 }
402
403 /* Reset the code*/
404 flexcan_reg_ptr->MB[mb_idx].CS &= ~(CAN_CS_CODE_MASK);
405
406 /* Activating message buffer*/
407 flexcan_reg_ptr->MB[mb_idx].CS |= CAN_CS_CODE(cs->code);
408 }
409 }
410 else if(cs->msg_id_type == kFlexCanMbId_Std)
411 {
412 /* ID[28-18]*/
413 flexcan_reg_ptr->MB[mb_idx].ID &= ~CAN_ID_STD_MASK;
414 flexcan_reg_ptr->MB[mb_idx].ID |= CAN_ID_STD(msg_id);
415
416 /* make sure IDE and SRR are not set*/
417 flexcan_reg_ptr->MB[mb_idx].CS &= ~(CAN_CS_IDE_MASK | CAN_CS_SRR_MASK);
418
419 /* Set the length of data in bytes*/
420 flexcan_reg_ptr->MB[mb_idx].CS &= ~CAN_CS_DLC_MASK;
421 flexcan_reg_ptr->MB[mb_idx].CS |= (cs->data_length) << CAN_CS_DLC_SHIFT;
422
423 /* Set MB CODE*/
424 if (cs->code != kFlexCanTX_NotUsed)
425 {
426 if (cs->code == kFlexCanTX_Remote)
427 {
428 /* Set RTR bit*/
429 flexcan_reg_ptr->MB[mb_idx].CS |= CAN_CS_RTR_MASK;
430 cs->code = kFlexCanTX_Data;
431 }
432
433 /* Reset the code*/
434 flexcan_reg_ptr->MB[mb_idx].CS &= ~CAN_CS_CODE_MASK;
435
436 /* Set the code*/
437 flexcan_reg_ptr->MB[mb_idx].CS |= CAN_CS_CODE(cs->code);
438 }
439 }
440 else
441 {
442 return (kStatus_FLEXCAN_InvalidArgument);
443 }
444
445 return (kStatus_FLEXCAN_Success);
446 }
447
448 /*FUNCTION**********************************************************************
449 *
450 * Function Name : FLEXCAN_HAL_SetMbRx
451 * Description : Configure a message buffer for receiving.
452 * This function will first check if RX FIFO is enabled. If RX FIFO is enabled,
453 * the function will make sure if the MB requested is not occupied by RX FIFO
454 * and ID filter table. Then this function will configure the message buffer as
455 * required for receiving.
456 *
457 *END**************************************************************************/
458 flexcan_status_t FLEXCAN_HAL_SetMbRx(
459 uint32_t canBaseAddr,
460 const flexcan_user_config_t *data,
461 uint32_t mb_idx,
462 flexcan_mb_code_status_t *cs,
463 uint32_t msg_id)
464 {
465 uint32_t val1, val2 = 1;
466
467 assert(data);
468
469 volatile CAN_Type *flexcan_reg_ptr;
470
471 flexcan_reg_ptr = ((CAN_Type *)canBaseAddr);
472 if (NULL == flexcan_reg_ptr)
473 {
474 return (kStatus_FLEXCAN_InvalidArgument);
475 }
476
477 if (mb_idx >= data->max_num_mb)
478 {
479 return (kStatus_FLEXCAN_OutOfRange);
480 }
481
482 /* Check if RX FIFO is enabled*/
483 if (BR_CAN_MCR_RFEN(canBaseAddr))
484 {
485 /* Get the number of RX FIFO Filters*/
486 val1 = BR_CAN_CTRL2_RFFN(canBaseAddr);
487 /* Get the number if MBs occupied by RX FIFO and ID filter table*/
488 /* the Rx FIFO occupies the memory space originally reserved for MB0-5*/
489 /* Every number of RFFN means 8 number of RX FIFO filters*/
490 /* and every 4 number of RX FIFO filters occupied one MB*/
491 val2 = 6 + (val1 + 1) * 8 / 4;
492
493 if (mb_idx <= (val2 - 1))
494 {
495 return (kStatus_FLEXCAN_InvalidArgument);
496 }
497 }
498
499 /* Set the ID according the format structure*/
500 if (cs->msg_id_type == kFlexCanMbId_Ext)
501 {
502 /* Set IDE*/
503 flexcan_reg_ptr->MB[mb_idx].CS |= CAN_CS_IDE_MASK;
504
505 /* Clear SRR bit*/
506 flexcan_reg_ptr->MB[mb_idx].CS &= ~CAN_CS_SRR_MASK;
507
508 /* Set the length of data in bytes*/
509 flexcan_reg_ptr->MB[mb_idx].CS &= ~CAN_CS_DLC_MASK;
510 flexcan_reg_ptr->MB[mb_idx].CS |= CAN_CS_DLC(cs->data_length);
511
512 /* ID [28-0]*/
513 flexcan_reg_ptr->MB[mb_idx].ID &= ~(CAN_ID_STD_MASK | CAN_ID_EXT_MASK);
514 flexcan_reg_ptr->MB[mb_idx].ID |= (msg_id & (CAN_ID_STD_MASK | CAN_ID_EXT_MASK));
515
516 /* Set MB CODE*/
517 if (cs->code != kFlexCanRX_NotUsed)
518 {
519 flexcan_reg_ptr->MB[mb_idx].CS &= ~CAN_CS_CODE_MASK;
520 flexcan_reg_ptr->MB[mb_idx].CS |= CAN_CS_CODE(cs->code);
521 }
522 }
523 else if(cs->msg_id_type == kFlexCanMbId_Std)
524 {
525 /* Make sure IDE and SRR are not set*/
526 flexcan_reg_ptr->MB[mb_idx].CS &= ~(CAN_CS_IDE_MASK | CAN_CS_SRR_MASK);
527
528 /* Set the length of data in bytes*/
529 flexcan_reg_ptr->MB[mb_idx].CS &= ~CAN_CS_DLC_MASK;
530 flexcan_reg_ptr->MB[mb_idx].CS |= (cs->data_length) << CAN_CS_DLC_SHIFT;
531
532 /* ID[28-18]*/
533 flexcan_reg_ptr->MB[mb_idx].ID &= ~CAN_ID_STD_MASK;
534 flexcan_reg_ptr->MB[mb_idx].ID |= CAN_ID_STD(msg_id);
535
536 /* Set MB CODE*/
537 if (cs->code != kFlexCanRX_NotUsed)
538 {
539 flexcan_reg_ptr->MB[mb_idx].CS &= ~CAN_CS_CODE_MASK;
540 flexcan_reg_ptr->MB[mb_idx].CS |= CAN_CS_CODE(cs->code);
541 }
542 }
543 else
544 {
545 return (kStatus_FLEXCAN_InvalidArgument);
546 }
547
548 return (kStatus_FLEXCAN_Success);
549 }
550
551 /*FUNCTION**********************************************************************
552 *
553 * Function Name : FLEXCAN_HAL_GetMb
554 * Description : Get a message buffer field values.
555 * This function will first check if RX FIFO is enabled. If RX FIFO is enabled,
556 * the function will make sure if the MB requested is not occupied by RX FIFO
557 * and ID filter table. Then this function will get the message buffer field
558 * values and copy the MB data field into user's buffer.
559 *
560 *END**************************************************************************/
561 flexcan_status_t FLEXCAN_HAL_GetMb(
562 uint32_t canBaseAddr,
563 const flexcan_user_config_t *data,
564 uint32_t mb_idx,
565 flexcan_mb_t *mb)
566 {
567 uint32_t i;
568 uint32_t val1, val2 = 1;
569 volatile CAN_Type *flexcan_reg_ptr;
570
571 assert(data);
572
573 flexcan_reg_ptr = ((CAN_Type *)canBaseAddr);
574 if (NULL == flexcan_reg_ptr)
575 {
576 return (kStatus_FLEXCAN_InvalidArgument);
577 }
578
579 if (mb_idx >= data->max_num_mb)
580 {
581 return (kStatus_FLEXCAN_OutOfRange);
582 }
583
584 /* Check if RX FIFO is enabled*/
585 if (BR_CAN_MCR_RFEN(canBaseAddr))
586 {
587 /* Get the number of RX FIFO Filters*/
588 val1 = BR_CAN_CTRL2_RFFN(canBaseAddr);
589 /* Get the number if MBs occupied by RX FIFO and ID filter table*/
590 /* the Rx FIFO occupies the memory space originally reserved for MB0-5*/
591 /* Every number of RFFN means 8 number of RX FIFO filters*/
592 /* and every 4 number of RX FIFO filters occupied one MB*/
593 val2 = 6 + (val1 + 1) * 8 / 4;
594
595 if (mb_idx <= (val2 - 1))
596 {
597 return (kStatus_FLEXCAN_InvalidArgument);
598 }
599 }
600
601 /* Get a MB field values*/
602 mb->cs = flexcan_reg_ptr->MB[mb_idx].CS;
603 if ((mb->cs) & CAN_CS_IDE_MASK)
604 {
605 mb->msg_id = flexcan_reg_ptr->MB[mb_idx].ID;
606 }
607 else
608 {
609 mb->msg_id = (flexcan_reg_ptr->MB[mb_idx].ID) >> CAN_ID_STD_SHIFT;
610 }
611
612 /* Copy MB data field into user's buffer*/
613 for (i = 0 ; i < kFlexCanMessageSize ; i++)
614 {
615 if (i < 4)
616 {
617 mb->data[3 - i] = ((flexcan_reg_ptr->MB[mb_idx].WORD0) >> (i * 8)) &
618 FLEXCAN_BYTE_DATA_FIELD_MASK;
619 }
620 else
621 {
622 mb->data[11 - i] = ((flexcan_reg_ptr->MB[mb_idx].WORD1) >> ((i - 4) * 8)) &
623 FLEXCAN_BYTE_DATA_FIELD_MASK;
624 }
625 }
626
627 return (kStatus_FLEXCAN_Success);
628 }
629
630 /*FUNCTION**********************************************************************
631 *
632 * Function Name : FLEXCAN_HAL_LockRxMb
633 * Description : Lock the RX message buffer.
634 * This function will the RX message buffer.
635 *
636 *END**************************************************************************/
637 flexcan_status_t FLEXCAN_HAL_LockRxMb(
638 uint32_t canBaseAddr,
639 const flexcan_user_config_t *data,
640 uint32_t mb_idx)
641 {
642 assert(data);
643
644 volatile CAN_Type *flexcan_reg_ptr;
645
646 flexcan_reg_ptr = ((CAN_Type *)canBaseAddr);
647 if (NULL == flexcan_reg_ptr)
648 {
649 return (kStatus_FLEXCAN_InvalidArgument);
650 }
651
652 if (mb_idx >= data->max_num_mb)
653 {
654 return (kStatus_FLEXCAN_OutOfRange);
655 }
656
657 /* Lock the mailbox*/
658 flexcan_reg_ptr->MB[mb_idx].CS;
659
660 return (kStatus_FLEXCAN_Success);
661 }
662
663 /*FUNCTION**********************************************************************
664 *
665 * Function Name : FLEXCAN_HAL_EnableRxFifo
666 * Description : Enable Rx FIFO feature.
667 * This function will enable the Rx FIFO feature.
668 *
669 *END**************************************************************************/
670 void FLEXCAN_HAL_EnableRxFifo(uint32_t canBaseAddr)
671 {
672 /* Set Freeze mode*/
673 BW_CAN_MCR_FRZ(canBaseAddr, 0x1);
674 BW_CAN_MCR_HALT(canBaseAddr, 0x1);
675
676 /* Wait for entering the freeze mode*/
677 while (!(BR_CAN_MCR_FRZACK(canBaseAddr))){}
678
679 /* Enable RX FIFO*/
680 BW_CAN_MCR_RFEN(canBaseAddr, 0x1);
681
682 /* De-assert Freeze Mode*/
683 BW_CAN_MCR_HALT(canBaseAddr, 0x0);
684 BW_CAN_MCR_FRZ(canBaseAddr, 0x0);
685
686 /* Wait till exit of freeze mode*/
687 while (BR_CAN_MCR_FRZACK(canBaseAddr)){}
688 }
689
690 /*FUNCTION**********************************************************************
691 *
692 * Function Name : FLEXCAN_HAL_DisableRxFifo
693 * Description : Disable Rx FIFO feature.
694 * This function will disable the Rx FIFO feature.
695 *
696 *END**************************************************************************/
697 void FLEXCAN_HAL_DisableRxFifo(uint32_t canBaseAddr)
698 {
699 /* Set Freeze mode*/
700 BW_CAN_MCR_FRZ(canBaseAddr, 0x1);
701 BW_CAN_MCR_HALT(canBaseAddr, 0x1);
702
703 /* Wait for entering the freeze mode*/
704 while(!(BR_CAN_MCR_FRZACK(canBaseAddr))){}
705
706 /* Disable RX FIFO*/
707 BW_CAN_MCR_RFEN(canBaseAddr, 0x0);
708
709 /* De-assert Freeze Mode*/
710 BW_CAN_MCR_HALT(canBaseAddr, 0x0);
711 BW_CAN_MCR_FRZ(canBaseAddr, 0x0);
712
713 /* Wait till exit of freeze mode*/
714 while (BR_CAN_MCR_FRZACK(canBaseAddr)){}
715 }
716
717 /*FUNCTION**********************************************************************
718 *
719 * Function Name : FLEXCAN_HAL_SetRxFifoFiltersNumber
720 * Description : Set the number of Rx FIFO filters.
721 * This function will define the number of Rx FIFO filters.
722 *
723 *END**************************************************************************/
724 void FLEXCAN_HAL_SetRxFifoFiltersNumber(
725 uint32_t canBaseAddr,
726 uint32_t number)
727 {
728 /* Set Freeze mode*/
729 BW_CAN_MCR_FRZ(canBaseAddr, 0x1);
730 BW_CAN_MCR_HALT(canBaseAddr, 0x1);
731
732 /* Wait for entering the freeze mode*/
733 while(!(BR_CAN_MCR_FRZACK(canBaseAddr))){}
734
735 /* Set the number of RX FIFO ID filters*/
736 BW_CAN_CTRL2_RFFN(canBaseAddr, number);
737
738 /* De-assert Freeze Mode*/
739 BW_CAN_MCR_HALT(canBaseAddr, 0x0);
740 BW_CAN_MCR_FRZ(canBaseAddr, 0x0);
741
742 /* Wait till exit of freeze mode*/
743 while (BR_CAN_MCR_FRZACK(canBaseAddr)){}
744 }
745
746 /*FUNCTION**********************************************************************
747 *
748 * Function Name : FLEXCAN_HAL_SetMaxMbNumber
749 * Description : Set the number of the last Message Buffers.
750 * This function will define the number of the last Message Buffers
751 *
752 *END**************************************************************************/
753 void FLEXCAN_HAL_SetMaxMbNumber(
754 uint32_t canBaseAddr,
755 const flexcan_user_config_t *data)
756 {
757 assert(data);
758
759 /* Set Freeze mode*/
760 BW_CAN_MCR_FRZ(canBaseAddr, 0x1);
761 BW_CAN_MCR_HALT(canBaseAddr, 0x1);
762
763 /* Wait for entering the freeze mode*/
764 while(!(BR_CAN_MCR_FRZACK(canBaseAddr))){}
765
766 /* Set the maximum number of MBs*/
767 BW_CAN_MCR_MAXMB(canBaseAddr, data->max_num_mb);
768
769 /* De-assert Freeze Mode*/
770 BW_CAN_MCR_HALT(canBaseAddr, 0x0);
771 BW_CAN_MCR_FRZ(canBaseAddr, 0x0);
772
773 /* Wait till exit of freeze mode*/
774 while (BR_CAN_MCR_FRZACK(canBaseAddr)){}
775 }
776
777 /*FUNCTION**********************************************************************
778 *
779 * Function Name : FLEXCAN_HAL_SetIdFilterTableElements
780 * Description : Set ID filter table elements.
781 * This function will set up ID filter table elements.
782 *
783 *END**************************************************************************/
784 flexcan_status_t FLEXCAN_HAL_SetIdFilterTableElements(
785 uint32_t canBaseAddr,
786 const flexcan_user_config_t *data,
787 flexcan_rx_fifo_id_element_format_t id_format,
788 flexcan_id_table_t *id_filter_table)
789 {
790 uint32_t i, j;
791 uint32_t val1, val2, val;
792 volatile CAN_Type *flexcan_reg_ptr;
793
794 assert(data);
795
796 flexcan_reg_ptr = ((CAN_Type *)canBaseAddr);
797 if (NULL == flexcan_reg_ptr)
798 {
799 return (kStatus_FLEXCAN_InvalidArgument);
800 }
801
802 switch(id_format)
803 {
804 case (kFlexCanRxFifoIdElementFormat_A):
805 /* One full ID (standard and extended) per ID Filter Table element.*/
806 BW_CAN_MCR_IDAM(canBaseAddr, kFlexCanRxFifoIdElementFormat_A);
807 if (id_filter_table->is_remote_mb)
808 {
809 val = 1U << 31U;
810 }
811 if (id_filter_table->is_extended_mb)
812 {
813 val |= 1 << 30;
814 j = 0;
815 for (i = 0; i < (data->num_id_filters + 1) * 8; i += 4)
816 {
817 flexcan_reg_ptr->MB[6 + i - j * 3].CS = val +
818 ((*(id_filter_table->id_filter + i)) <<
819 FLEXCAN_RX_FIFO_ID_FILTER_FORMATA_EXT_SHIFT &
820 FLEXCAN_RX_FIFO_ID_FILTER_FORMATA_EXT_MASK);
821 flexcan_reg_ptr->MB[6 + i - j * 3].ID = val +
822 ((*(id_filter_table->id_filter + i + 1)) <<
823 FLEXCAN_RX_FIFO_ID_FILTER_FORMATA_EXT_SHIFT &
824 FLEXCAN_RX_FIFO_ID_FILTER_FORMATA_EXT_MASK);
825 flexcan_reg_ptr->MB[6 + i - j * 3].WORD0 = val +
826 ((*(id_filter_table->id_filter + i + 2)) <<
827 FLEXCAN_RX_FIFO_ID_FILTER_FORMATA_EXT_SHIFT &
828 FLEXCAN_RX_FIFO_ID_FILTER_FORMATA_EXT_MASK);
829 flexcan_reg_ptr->MB[6 + i - j * 3].WORD1 = val +
830 ((*(id_filter_table->id_filter + i + 3)) <<
831 FLEXCAN_RX_FIFO_ID_FILTER_FORMATA_EXT_SHIFT &
832 FLEXCAN_RX_FIFO_ID_FILTER_FORMATA_EXT_MASK);
833 j++;
834 }
835 }
836 else
837 {
838 j = 0;
839 for (i = 0; i < (data->num_id_filters + 1) * 8; i += 4)
840 {
841 flexcan_reg_ptr->MB[6 + i - j * 3].CS = val +
842 ((*(id_filter_table->id_filter + i)) <<
843 FLEXCAN_RX_FIFO_ID_FILTER_FORMATA_STD_SHIFT &
844 FLEXCAN_RX_FIFO_ID_FILTER_FORMATA_STD_MASK);
845 flexcan_reg_ptr->MB[6 + i - j * 3].ID = val +
846 ((*(id_filter_table->id_filter + i + 1)) <<
847 FLEXCAN_RX_FIFO_ID_FILTER_FORMATA_STD_SHIFT &
848 FLEXCAN_RX_FIFO_ID_FILTER_FORMATA_STD_MASK);
849 flexcan_reg_ptr->MB[6 + i - j * 3].WORD0 = val +
850 ((*(id_filter_table->id_filter + i + 2)) <<
851 FLEXCAN_RX_FIFO_ID_FILTER_FORMATA_STD_SHIFT &
852 FLEXCAN_RX_FIFO_ID_FILTER_FORMATA_STD_MASK);
853 flexcan_reg_ptr->MB[6 + i - j * 3].WORD1 = val +
854 ((*(id_filter_table->id_filter + i + 3)) <<
855 FLEXCAN_RX_FIFO_ID_FILTER_FORMATA_STD_SHIFT &
856 FLEXCAN_RX_FIFO_ID_FILTER_FORMATA_STD_MASK);
857 j++;
858 }
859 }
860 break;
861 case (kFlexCanRxFifoIdElementFormat_B):
862 /* Two full standard IDs or two partial 14-bit (standard and extended) IDs*/
863 /* per ID Filter Table element.*/
864 BW_CAN_MCR_IDAM(canBaseAddr, kFlexCanRxFifoIdElementFormat_B);
865 if (id_filter_table->is_remote_mb)
866 {
867 val1 = 1U << 31U;
868 val2 = 1 << 15;
869 }
870 if (id_filter_table->is_extended_mb)
871 {
872 val1 |= 1 << 30;
873 val2 |= 1 << 14;
874 j = 0;
875 for (i = 0; i < (data->num_id_filters + 1) * 8; i += 8)
876 {
877 flexcan_reg_ptr->MB[6 + i - j * 3].CS = val1 +
878 ((*(id_filter_table->id_filter + i)) &
879 FLEXCAN_RX_FIFO_ID_FILTER_FORMATB_EXT_MASK <<
880 FLEXCAN_RX_FIFO_ID_FILTER_FORMATB_EXT_SHIFT1);
881 flexcan_reg_ptr->MB[6 + i - j * 3].CS |= val2 +
882 ((*(id_filter_table->id_filter + i + 1)) &
883 FLEXCAN_RX_FIFO_ID_FILTER_FORMATB_EXT_MASK <<
884 FLEXCAN_RX_FIFO_ID_FILTER_FORMATB_EXT_SHIFT2);
885
886 flexcan_reg_ptr->MB[6 + i - j * 3].ID = val1 +
887 ((*(id_filter_table->id_filter + i + 2)) &
888 FLEXCAN_RX_FIFO_ID_FILTER_FORMATB_EXT_MASK <<
889 FLEXCAN_RX_FIFO_ID_FILTER_FORMATB_EXT_SHIFT1);
890 flexcan_reg_ptr->MB[6 + i - j * 3].ID |= val2 +
891 ((*(id_filter_table->id_filter + i + 3)) &
892 FLEXCAN_RX_FIFO_ID_FILTER_FORMATB_EXT_MASK <<
893 FLEXCAN_RX_FIFO_ID_FILTER_FORMATB_EXT_SHIFT2);
894
895 flexcan_reg_ptr->MB[6 + i - j * 3].WORD0 = val1 +
896 ((*(id_filter_table->id_filter + i + 4)) &
897 FLEXCAN_RX_FIFO_ID_FILTER_FORMATB_EXT_MASK <<
898 FLEXCAN_RX_FIFO_ID_FILTER_FORMATB_EXT_SHIFT1);
899 flexcan_reg_ptr->MB[6 + i - j * 3].WORD0 |= val2 +
900 ((*(id_filter_table->id_filter + i + 5)) &
901 FLEXCAN_RX_FIFO_ID_FILTER_FORMATB_EXT_MASK <<
902 FLEXCAN_RX_FIFO_ID_FILTER_FORMATB_EXT_SHIFT2);
903
904 flexcan_reg_ptr->MB[6 + i - j * 3].WORD1 = val1 +
905 ((*(id_filter_table->id_filter + i + 6)) &
906 FLEXCAN_RX_FIFO_ID_FILTER_FORMATB_EXT_MASK <<
907 FLEXCAN_RX_FIFO_ID_FILTER_FORMATB_EXT_SHIFT1);
908 flexcan_reg_ptr->MB[6 + i - j * 3].WORD1 |= val2 +
909 ((*(id_filter_table->id_filter + i + 7)) &
910 FLEXCAN_RX_FIFO_ID_FILTER_FORMATB_EXT_MASK <<
911 FLEXCAN_RX_FIFO_ID_FILTER_FORMATB_EXT_SHIFT2);
912 j++;
913 }
914 }
915 else
916 {
917 j = 0;
918 for (i = 0; i < (data->num_id_filters + 1) * 8; i += 8)
919 {
920 flexcan_reg_ptr->MB[6 + i - j * 3].CS = val1 +
921 (((*(id_filter_table->id_filter + i)) &
922 FLEXCAN_RX_FIFO_ID_FILTER_FORMATB_STD_MASK) <<
923 FLEXCAN_RX_FIFO_ID_FILTER_FORMATB_STD_SHIFT1);
924 flexcan_reg_ptr->MB[6 + i - j * 3].CS |= val2 +
925 (((*(id_filter_table->id_filter + i + 1)) &
926 FLEXCAN_RX_FIFO_ID_FILTER_FORMATB_STD_MASK) <<
927 FLEXCAN_RX_FIFO_ID_FILTER_FORMATB_STD_SHIFT2);
928
929 flexcan_reg_ptr->MB[6 + i - j * 3].ID = val1 +
930 (((*(id_filter_table->id_filter + i + 2)) &
931 FLEXCAN_RX_FIFO_ID_FILTER_FORMATB_STD_MASK) <<
932 FLEXCAN_RX_FIFO_ID_FILTER_FORMATB_STD_SHIFT1);
933 flexcan_reg_ptr->MB[6 + i - j * 3].ID |= val2 +
934 (((*(id_filter_table->id_filter + i + 3)) &
935 FLEXCAN_RX_FIFO_ID_FILTER_FORMATB_STD_MASK) <<
936 FLEXCAN_RX_FIFO_ID_FILTER_FORMATB_STD_SHIFT2);
937
938 flexcan_reg_ptr->MB[6 + i - j * 3].WORD0 = val1 +
939 (((*(id_filter_table->id_filter + i + 4)) &
940 FLEXCAN_RX_FIFO_ID_FILTER_FORMATB_STD_MASK) <<
941 FLEXCAN_RX_FIFO_ID_FILTER_FORMATB_STD_SHIFT1);
942 flexcan_reg_ptr->MB[6 + i - j * 3].WORD0 |= val2 +
943 (((*(id_filter_table->id_filter + i + 5)) &
944 FLEXCAN_RX_FIFO_ID_FILTER_FORMATB_STD_MASK) <<
945 FLEXCAN_RX_FIFO_ID_FILTER_FORMATB_STD_SHIFT2);
946
947 flexcan_reg_ptr->MB[6 + i - j * 3].WORD1 = val1 +
948 (((*(id_filter_table->id_filter + i + 6)) &
949 FLEXCAN_RX_FIFO_ID_FILTER_FORMATB_STD_MASK) <<
950 FLEXCAN_RX_FIFO_ID_FILTER_FORMATB_STD_SHIFT1);
951 flexcan_reg_ptr->MB[6 + i - j * 3].WORD1 |= val2 +
952 (((*(id_filter_table->id_filter + i + 7)) &
953 FLEXCAN_RX_FIFO_ID_FILTER_FORMATB_STD_MASK) <<
954 FLEXCAN_RX_FIFO_ID_FILTER_FORMATB_STD_SHIFT2);
955 j++;
956 }
957 }
958 break;
959 case (kFlexCanRxFifoIdElementFormat_C):
960 /* Four partial 8-bit Standard IDs per ID Filter Table element.*/
961 BW_CAN_MCR_IDAM(canBaseAddr, kFlexCanRxFifoIdElementFormat_C);
962 j = 0;
963 for (i = 0; i < (data->num_id_filters + 1) * 8; i += 16)
964 {
965 flexcan_reg_ptr->MB[6 + i - j * 3].CS = ((*(id_filter_table->id_filter + i)) &
966 FLEXCAN_RX_FIFO_ID_FILTER_FORMATC_MASK <<
967 FLEXCAN_RX_FIFO_ID_FILTER_FORMATC_SHIFT1);
968 flexcan_reg_ptr->MB[6 + i - j * 3].CS |= ((*(id_filter_table->id_filter + i + 1)) &
969 FLEXCAN_RX_FIFO_ID_FILTER_FORMATC_MASK <<
970 FLEXCAN_RX_FIFO_ID_FILTER_FORMATC_SHIFT2);
971 flexcan_reg_ptr->MB[6 + i - j * 3].CS |= ((*(id_filter_table->id_filter + i + 2)) &
972 FLEXCAN_RX_FIFO_ID_FILTER_FORMATC_MASK <<
973 FLEXCAN_RX_FIFO_ID_FILTER_FORMATC_SHIFT3);
974 flexcan_reg_ptr->MB[6 + i - j * 3].CS |= ((*(id_filter_table->id_filter + i + 3)) &
975 FLEXCAN_RX_FIFO_ID_FILTER_FORMATC_MASK <<
976 FLEXCAN_RX_FIFO_ID_FILTER_FORMATC_SHIFT4);
977
978 flexcan_reg_ptr->MB[6 + i - j * 3].ID = ((*(id_filter_table->id_filter + i + 4)) &
979 FLEXCAN_RX_FIFO_ID_FILTER_FORMATC_MASK <<
980 FLEXCAN_RX_FIFO_ID_FILTER_FORMATC_SHIFT1);
981 flexcan_reg_ptr->MB[6 + i - j * 3].ID |= ((*(id_filter_table->id_filter + i + 5)) &
982 FLEXCAN_RX_FIFO_ID_FILTER_FORMATC_MASK <<
983 FLEXCAN_RX_FIFO_ID_FILTER_FORMATC_SHIFT2);
984 flexcan_reg_ptr->MB[6 + i - j * 3].ID |= ((*(id_filter_table->id_filter + i + 6)) &
985 FLEXCAN_RX_FIFO_ID_FILTER_FORMATC_MASK <<
986 FLEXCAN_RX_FIFO_ID_FILTER_FORMATC_SHIFT3);
987 flexcan_reg_ptr->MB[6 + i - j * 3].ID |= ((*(id_filter_table->id_filter + i + 7)) &
988 FLEXCAN_RX_FIFO_ID_FILTER_FORMATC_MASK <<
989 FLEXCAN_RX_FIFO_ID_FILTER_FORMATC_SHIFT4);
990
991 flexcan_reg_ptr->MB[6 + i - j * 3].WORD0 = ((*(id_filter_table->id_filter + i + 8)) &
992 FLEXCAN_RX_FIFO_ID_FILTER_FORMATC_MASK <<
993 FLEXCAN_RX_FIFO_ID_FILTER_FORMATC_SHIFT1);
994 flexcan_reg_ptr->MB[6 + i - j * 3].WORD0 |= ((*(id_filter_table->id_filter + i + 9)) &
995 FLEXCAN_RX_FIFO_ID_FILTER_FORMATC_MASK <<
996 FLEXCAN_RX_FIFO_ID_FILTER_FORMATC_SHIFT2);
997 flexcan_reg_ptr->MB[6 + i - j * 3].WORD0 |= ((*(id_filter_table->id_filter + i + 10)) &
998 FLEXCAN_RX_FIFO_ID_FILTER_FORMATC_MASK <<
999 FLEXCAN_RX_FIFO_ID_FILTER_FORMATC_SHIFT3);
1000 flexcan_reg_ptr->MB[6 + i - j * 3].WORD0 |= ((*(id_filter_table->id_filter + i + 11)) &
1001 FLEXCAN_RX_FIFO_ID_FILTER_FORMATC_MASK <<
1002 FLEXCAN_RX_FIFO_ID_FILTER_FORMATC_SHIFT4);
1003
1004 flexcan_reg_ptr->MB[6 + i - j * 3].WORD1 = ((*(id_filter_table->id_filter + i + 12)) &
1005 FLEXCAN_RX_FIFO_ID_FILTER_FORMATC_MASK <<
1006 FLEXCAN_RX_FIFO_ID_FILTER_FORMATC_SHIFT1);
1007 flexcan_reg_ptr->MB[6 + i - j * 3].WORD1 |= ((*(id_filter_table->id_filter + i + 13)) &
1008 FLEXCAN_RX_FIFO_ID_FILTER_FORMATC_MASK <<
1009 FLEXCAN_RX_FIFO_ID_FILTER_FORMATC_SHIFT2);
1010 flexcan_reg_ptr->MB[6 + i - j * 3].WORD1 |= ((*(id_filter_table->id_filter + i + 14)) &
1011 FLEXCAN_RX_FIFO_ID_FILTER_FORMATC_MASK <<
1012 FLEXCAN_RX_FIFO_ID_FILTER_FORMATC_SHIFT3);
1013 flexcan_reg_ptr->MB[6 + i - j * 3].WORD1 |= ((*(id_filter_table->id_filter + i + 15)) &
1014 FLEXCAN_RX_FIFO_ID_FILTER_FORMATC_MASK <<
1015 FLEXCAN_RX_FIFO_ID_FILTER_FORMATC_SHIFT4);
1016
1017 j++;
1018 }
1019 break;
1020 case (kFlexCanRxFifoIdElementFormat_D):
1021 /* All frames rejected.*/
1022 BW_CAN_MCR_IDAM(canBaseAddr, kFlexCanRxFifoIdElementFormat_D);
1023 break;
1024 default:
1025 return kStatus_FLEXCAN_InvalidArgument;
1026 }
1027
1028 return (kStatus_FLEXCAN_Success);
1029 }
1030
1031 /*FUNCTION**********************************************************************
1032 *
1033 * Function Name : FLEXCAN_HAL_SetRxFifo
1034 * Description : Confgure RX FIFO ID filter table elements.
1035 *
1036 *END**************************************************************************/
1037 flexcan_status_t FLEXCAN_HAL_SetRxFifo(
1038 uint32_t canBaseAddr,
1039 const flexcan_user_config_t *data,
1040 flexcan_rx_fifo_id_element_format_t id_format,
1041 flexcan_id_table_t *id_filter_table)
1042 {
1043 assert(data);
1044
1045 if (!data->is_rx_fifo_needed)
1046 {
1047 return (kStatus_FLEXCAN_InvalidArgument);
1048 }
1049
1050 /* Set RX FIFO ID filter table elements*/
1051 return FLEXCAN_HAL_SetIdFilterTableElements(canBaseAddr, data, id_format, id_filter_table);
1052 }
1053
1054 /*FUNCTION**********************************************************************
1055 *
1056 * Function Name : FLEXCAN_HAL_EnableMbInt
1057 * Description : Enable the corresponding Message Buffer interrupt.
1058 *
1059 *END**************************************************************************/
1060 flexcan_status_t FLEXCAN_HAL_EnableMbInt(
1061 uint32_t canBaseAddr,
1062 const flexcan_user_config_t *data,
1063 uint32_t mb_idx)
1064 {
1065 assert(data);
1066 uint32_t temp;
1067
1068 if ( mb_idx >= data->max_num_mb)
1069 {
1070 return (kStatus_FLEXCAN_OutOfRange);
1071 }
1072
1073 /* Enable the corresponding message buffer Interrupt*/
1074 temp = 0x1 << mb_idx;
1075 HW_CAN_IMASK1_SET(canBaseAddr, temp);
1076
1077 return (kStatus_FLEXCAN_Success);
1078 }
1079
1080 /*FUNCTION**********************************************************************
1081 *
1082 * Function Name : FLEXCAN_HAL_DisableMbInt
1083 * Description : Disable the corresponding Message Buffer interrupt.
1084 *
1085 *END**************************************************************************/
1086 flexcan_status_t FLEXCAN_HAL_DisableMbInt(
1087 uint32_t canBaseAddr,
1088 const flexcan_user_config_t *data,
1089 uint32_t mb_idx)
1090 {
1091 assert(data);
1092 uint32_t temp;
1093
1094 if (mb_idx >= data->max_num_mb)
1095 {
1096 return (kStatus_FLEXCAN_OutOfRange);
1097 }
1098
1099 /* Disable the corresponding message buffer Interrupt*/
1100 temp = 0x1 << mb_idx;
1101 HW_CAN_IMASK1_CLR(canBaseAddr, temp);
1102
1103 return (kStatus_FLEXCAN_Success);
1104 }
1105
1106 /*FUNCTION**********************************************************************
1107 *
1108 * Function Name : FLEXCAN_HAL_EnableErrInt
1109 * Description : Enable the error interrupts.
1110 * This function will enable Error interrupt.
1111 *
1112 *END**************************************************************************/
1113 void FLEXCAN_HAL_EnableErrInt(uint32_t canBaseAddr)
1114 {
1115 /* Enable Error interrupt*/
1116 BW_CAN_CTRL1_ERRMSK(canBaseAddr, 0x1);
1117 }
1118
1119 /*FUNCTION**********************************************************************
1120 *
1121 * Function Name : FLEXCAN_HAL_DisableErrorInt
1122 * Description : Disable the error interrupts.
1123 * This function will disable Error interrupt.
1124 *
1125 *END**************************************************************************/
1126 void FLEXCAN_HAL_DisableErrInt(uint32_t canBaseAddr)
1127 {
1128 /* Disable Error interrupt*/
1129 BW_CAN_CTRL1_ERRMSK(canBaseAddr, 0x0);
1130 }
1131
1132 /*FUNCTION**********************************************************************
1133 *
1134 * Function Name : FLEXCAN_HAL_EnableBusOffInt
1135 * Description : Enable the Bus off interrupts.
1136 * This function will enable Bus Off interrupt.
1137 *
1138 *END**************************************************************************/
1139 void FLEXCAN_HAL_EnableBusOffInt(uint32_t canBaseAddr)
1140 {
1141 /* Enable Bus Off interrupt*/
1142 BW_CAN_CTRL1_BOFFMSK(canBaseAddr, 0x1);
1143 }
1144
1145 /*FUNCTION**********************************************************************
1146 *
1147 * Function Name : FLEXCAN_HAL_DisableBusOffInt
1148 * Description : Disable the Bus off interrupts.
1149 * This function will disable Bus Off interrupt.
1150 *
1151 *END**************************************************************************/
1152 void FLEXCAN_HAL_DisableBusOffInt(uint32_t canBaseAddr)
1153 {
1154 /* Disable Bus Off interrupt*/
1155 BW_CAN_CTRL1_BOFFMSK(canBaseAddr, 0x0);
1156 }
1157
1158 /*FUNCTION**********************************************************************
1159 *
1160 * Function Name : FLEXCAN_HAL_EnableWakeupInt
1161 * Description : Enable the wakeup interrupts.
1162 * This function will enable Wake up interrupt.
1163 *
1164 *END**************************************************************************/
1165 void FLEXCAN_HAL_EnableWakeupInt(uint32_t canBaseAddr)
1166 {
1167 /* Enable Wake Up interrupt*/
1168 BW_CAN_MCR_WAKMSK(canBaseAddr, 1);
1169 }
1170
1171 /*FUNCTION**********************************************************************
1172 *
1173 * Function Name : FLEXCAN_HAL_DisableWakeupInt
1174 * Description : Disable the wakeup interrupts.
1175 * This function will disable Wake up interrupt.
1176 *
1177 *END**************************************************************************/
1178 void FLEXCAN_HAL_DisableWakeupInt(uint32_t canBaseAddr)
1179 {
1180 /* Disable Wake Up interrupt*/
1181 BW_CAN_MCR_WAKMSK(canBaseAddr, 0);
1182 }
1183
1184 /*FUNCTION**********************************************************************
1185 *
1186 * Function Name : FLEXCAN_HAL_EnableTxWarningInt
1187 * Description : Enable the TX warning interrupts.
1188 * This function will enable TX warning interrupt.
1189 *
1190 *END**************************************************************************/
1191 void FLEXCAN_HAL_EnableTxWarningInt(uint32_t canBaseAddr)
1192 {
1193 /* Enable TX warning interrupt*/
1194 BW_CAN_CTRL1_TWRNMSK(canBaseAddr, 0x1);
1195 }
1196
1197 /*FUNCTION**********************************************************************
1198 *
1199 * Function Name : FLEXCAN_HAL_DisableTxWarningInt
1200 * Description : Disable the TX warning interrupts.
1201 * This function will disable TX warning interrupt.
1202 *
1203 *END**************************************************************************/
1204 void FLEXCAN_HAL_DisableTxWarningInt(uint32_t canBaseAddr)
1205 {
1206 /* Disable TX warning interrupt*/
1207 BW_CAN_CTRL1_TWRNMSK(canBaseAddr, 0x0);
1208 }
1209
1210 /*FUNCTION**********************************************************************
1211 *
1212 * Function Name : FLEXCAN_HAL_EnableRxWarningInt
1213 * Description : Enable the RX warning interrupts.
1214 * This function will enable RX warning interrupt.
1215 *
1216 *END**************************************************************************/
1217 void FLEXCAN_HAL_EnableRxWarningInt(uint32_t canBaseAddr)
1218 {
1219 /* Enable RX warning interrupt*/
1220 BW_CAN_CTRL1_RWRNMSK(canBaseAddr, 0x1);
1221 }
1222
1223 /*FUNCTION**********************************************************************
1224 *
1225 * Function Name : FLEXCAN_HAL_DisableRxWarningInt
1226 * Description : Disable the RX warning interrupts.
1227 * This function will disable RX warning interrupt.
1228 *
1229 *END**************************************************************************/
1230 void FLEXCAN_HAL_DisableRxWarningInt(uint32_t canBaseAddr)
1231 {
1232 /* Disable RX warning interrupt*/
1233 BW_CAN_CTRL1_RWRNMSK(canBaseAddr, 0x0);
1234 }
1235
1236 /*FUNCTION**********************************************************************
1237 *
1238 * Function Name : FLEXCAN_HAL_ExitFreezeMode
1239 * Description : Exit of freeze mode.
1240 *
1241 *END**************************************************************************/
1242 void FLEXCAN_HAL_ExitFreezeMode(uint32_t canBaseAddr)
1243 {
1244 BW_CAN_MCR_HALT(canBaseAddr, 0x0);
1245 BW_CAN_MCR_FRZ(canBaseAddr, 0x0);
1246
1247 /* Wait till exit freeze mode*/
1248 while (BR_CAN_MCR_FRZACK(canBaseAddr)){}
1249 }
1250
1251 /*FUNCTION**********************************************************************
1252 *
1253 * Function Name : FLEXCAN_HAL_EnterFreezeMode
1254 * Description : Enter the freeze mode.
1255 *
1256 *END**************************************************************************/
1257 void FLEXCAN_HAL_EnterFreezeMode(uint32_t canBaseAddr)
1258 {
1259 BW_CAN_MCR_FRZ(canBaseAddr, 0x1);
1260 BW_CAN_MCR_HALT(canBaseAddr, 0x1);
1261
1262
1263 /* Wait for entering the freeze mode*/
1264 while (!(BR_CAN_MCR_FRZACK(canBaseAddr))){}
1265 }
1266
1267 /*FUNCTION**********************************************************************
1268 *
1269 * Function Name : FLEXCAN_HAL_GetMbIntFlag
1270 * Description : Get the corresponding message buffer interrupt flag.
1271 *
1272 *END**************************************************************************/
1273 uint8_t FLEXCAN_HAL_GetMbIntFlag(
1274 uint32_t canBaseAddr,
1275 const flexcan_user_config_t *data,
1276 uint32_t mb_idx)
1277 {
1278 assert(data);
1279 assert(mb_idx < data->max_num_mb);
1280 uint32_t temp;
1281
1282 /* Get the corresponding message buffer interrupt flag*/
1283 temp = 0x1 << mb_idx;
1284 if (HW_CAN_IFLAG1_RD(canBaseAddr) & temp)
1285 {
1286 return 1;
1287 }
1288 else
1289 {
1290 return 0;
1291 }
1292 }
1293
1294 /*FUNCTION**********************************************************************
1295 *
1296 * Function Name : FLEXCAN_HAL_GetErrCounter
1297 * Description : Get transmit error counter and receive error counter.
1298 *
1299 *END**************************************************************************/
1300 void FLEXCAN_HAL_GetErrCounter(
1301 uint32_t canBaseAddr,
1302 flexcan_berr_counter_t *err_cnt)
1303 {
1304 /* Get transmit error counter and receive error counter*/
1305 err_cnt->rxerr = HW_CAN_ECR(canBaseAddr).B.RXERRCNT;
1306 err_cnt->txerr = HW_CAN_ECR(canBaseAddr).B.TXERRCNT;
1307 }
1308
1309 /*FUNCTION**********************************************************************
1310 *
1311 * Function Name : FLEXCAN_HAL_ClearErrIntStatus
1312 * Description : Clear all error interrupt status.
1313 *
1314 *END**************************************************************************/
1315 void FLEXCAN_HAL_ClearErrIntStatus(uint32_t canBaseAddr)
1316 {
1317 if(HW_CAN_ESR1_RD(canBaseAddr) & FLEXCAN_ALL_INT)
1318 {
1319 HW_CAN_ESR1_SET(canBaseAddr, FLEXCAN_ALL_INT);
1320 }
1321 }
1322
1323 /*FUNCTION**********************************************************************
1324 *
1325 * Function Name : FLEXCAN_HAL_ReadFifo
1326 * Description : Read Rx FIFO data.
1327 * This function will copy MB[0] data field into user's buffer.
1328 *
1329 *END**************************************************************************/
1330 flexcan_status_t FLEXCAN_HAL_ReadFifo(
1331 uint32_t canBaseAddr,
1332 flexcan_mb_t *rx_fifo)
1333 {
1334 uint32_t i;
1335 volatile CAN_Type *flexcan_reg_ptr;
1336
1337 flexcan_reg_ptr = ((CAN_Type *)canBaseAddr);
1338 if (NULL == flexcan_reg_ptr)
1339 {
1340 return (kStatus_FLEXCAN_InvalidArgument);
1341 }
1342
1343 rx_fifo->cs = flexcan_reg_ptr->MB[0].CS;
1344
1345 if ((rx_fifo->cs) & CAN_CS_IDE_MASK)
1346 {
1347 rx_fifo->msg_id = flexcan_reg_ptr->MB[0].ID;
1348 }
1349 else
1350 {
1351 rx_fifo->msg_id = (flexcan_reg_ptr->MB[0].ID) >> CAN_ID_STD_SHIFT;
1352 }
1353
1354 /* Copy MB[0] data field into user's buffer*/
1355 for ( i=0 ; i < kFlexCanMessageSize ; i++ )
1356 {
1357 if (i < 4)
1358 {
1359 rx_fifo->data[3 - i] = ((flexcan_reg_ptr->MB[0].WORD0) >> (i * 8)) &
1360 FLEXCAN_BYTE_DATA_FIELD_MASK;
1361 }
1362 else
1363 {
1364 rx_fifo->data[11 - i] = ((flexcan_reg_ptr->MB[0].WORD1) >> ((i - 4) * 8)) &
1365 FLEXCAN_BYTE_DATA_FIELD_MASK;
1366 }
1367 }
1368
1369 return (kStatus_FLEXCAN_Success);
1370 }
1371
1372 /*FUNCTION**********************************************************************
1373 *
1374 * Function Name : FLEXCAN_HAL_SetMaskType
1375 * Description : Set RX masking type.
1376 * This function will set RX masking type as RX global mask or RX individual
1377 * mask.
1378 *
1379 *END**************************************************************************/
1380 void FLEXCAN_HAL_SetMaskType(
1381 uint32_t canBaseAddr,
1382 flexcan_rx_mask_type_t type)
1383 {
1384 /* Set Freeze mode*/
1385 BW_CAN_MCR_FRZ(canBaseAddr, 0x1);
1386 BW_CAN_MCR_HALT(canBaseAddr, 0x1);
1387
1388
1389 /* Wait for entering the freeze mode*/
1390 while (!(BR_CAN_MCR_FRZACK(canBaseAddr))){}
1391
1392 /* Set RX masking type (RX global mask or RX individual mask)*/
1393 if (type == kFlexCanRxMask_Global)
1394 {
1395 /* Enable Global RX masking*/
1396 BW_CAN_MCR_IRMQ(canBaseAddr, 0x0);
1397 }
1398 else
1399 {
1400 /* Enable Individual Rx Masking and Queue*/
1401 BW_CAN_MCR_IRMQ(canBaseAddr, 0x1);
1402 }
1403
1404 /* De-assert Freeze Mode*/
1405 BW_CAN_MCR_HALT(canBaseAddr, 0x0);
1406 BW_CAN_MCR_FRZ(canBaseAddr, 0x0);
1407
1408 /* Wait till exit of freeze mode*/
1409 while (BR_CAN_MCR_FRZACK(canBaseAddr)){}
1410 }
1411
1412 /*FUNCTION**********************************************************************
1413 *
1414 * Function Name : FLEXCAN_HAL_SetRxFifoGlobalStdMask
1415 * Description : Set Rx FIFO global mask as the 11-bit standard mask.
1416 *
1417 *END**************************************************************************/
1418 void FLEXCAN_HAL_SetRxFifoGlobalStdMask(
1419 uint32_t canBaseAddr,
1420 uint32_t std_mask)
1421 {
1422 /* Set Freeze mode*/
1423 BW_CAN_MCR_FRZ(canBaseAddr, 0x1);
1424 BW_CAN_MCR_HALT(canBaseAddr, 0x1);
1425
1426 /* Wait for entering the freeze mode*/
1427 while (!(BR_CAN_MCR_FRZACK(canBaseAddr))){}
1428
1429 /* 11 bit standard mask*/
1430 HW_CAN_RXFGMASK_WR(canBaseAddr, CAN_ID_STD(std_mask));
1431
1432 /* De-assert Freeze Mode*/
1433 BW_CAN_MCR_HALT(canBaseAddr, 0x0);
1434 BW_CAN_MCR_FRZ(canBaseAddr, 0x0);
1435
1436 /* Wait till exit of freeze mode*/
1437 while (BR_CAN_MCR_FRZACK(canBaseAddr)){}
1438 }
1439
1440 /*FUNCTION**********************************************************************
1441 *
1442 * Function Name : FLEXCAN_HAL_SetRxFifoGlobalExtMask
1443 * Description : Set Rx FIFO global mask as the 29-bit extended mask.
1444 *
1445 *END**************************************************************************/
1446 void FLEXCAN_HAL_SetRxFifoGlobalExtMask(
1447 uint32_t canBaseAddr,
1448 uint32_t ext_mask)
1449 {
1450 /* Set Freeze mode*/
1451 BW_CAN_MCR_FRZ(canBaseAddr, 0x1);
1452 BW_CAN_MCR_HALT(canBaseAddr, 0x1);
1453
1454 /* Wait for entering the freeze mode*/
1455 while (!(BR_CAN_MCR_FRZACK(canBaseAddr))){}
1456
1457 /* 29-bit extended mask*/
1458 HW_CAN_RXFGMASK_WR(canBaseAddr, CAN_ID_EXT(ext_mask));
1459
1460 /* De-assert Freeze Mode*/
1461 BW_CAN_MCR_HALT(canBaseAddr, 0x0);
1462 BW_CAN_MCR_FRZ(canBaseAddr, 0x0);
1463
1464 /* Wait till exit of freeze mode*/
1465 while (BR_CAN_MCR_FRZACK(canBaseAddr)){}
1466 }
1467
1468 /*FUNCTION**********************************************************************
1469 *
1470 * Function Name : FLEXCAN_HAL_SetRxIndividualStdMask
1471 * Description : Set Rx individual mask as the 11-bit standard mask.
1472 *
1473 *END**************************************************************************/
1474 flexcan_status_t FLEXCAN_HAL_SetRxIndividualStdMask(
1475 uint32_t canBaseAddr,
1476 const flexcan_user_config_t * data,
1477 uint32_t mb_idx,
1478 uint32_t std_mask)
1479 {
1480 assert(data);
1481
1482 if (mb_idx >= data->max_num_mb)
1483 {
1484 return (kStatus_FLEXCAN_OutOfRange);
1485 }
1486
1487 /* Set Freeze mode*/
1488 BW_CAN_MCR_FRZ(canBaseAddr, 0x1);
1489 BW_CAN_MCR_HALT(canBaseAddr, 0x1);
1490
1491 /* Wait for entering the freeze mode*/
1492 while (!(BR_CAN_MCR_FRZACK(canBaseAddr))){}
1493
1494 /* 11 bit standard mask*/
1495 HW_CAN_RXIMRn_WR(canBaseAddr, mb_idx, CAN_ID_STD(std_mask));
1496
1497 /* De-assert Freeze Mode*/
1498 BW_CAN_MCR_HALT(canBaseAddr, 0x0);
1499 BW_CAN_MCR_FRZ(canBaseAddr, 0x0);
1500
1501 /* Wait till exit of freeze mode*/
1502 while (BR_CAN_MCR_FRZACK(canBaseAddr)){}
1503
1504 return (kStatus_FLEXCAN_Success);
1505 }
1506
1507 /*FUNCTION**********************************************************************
1508 *
1509 * Function Name : FLEXCAN_HAL_SetRxIndividualExtMask
1510 * Description : Set Rx individual mask as the 29-bit extended mask.
1511 *
1512 *END**************************************************************************/
1513 flexcan_status_t FLEXCAN_HAL_SetRxIndividualExtMask(
1514 uint32_t canBaseAddr,
1515 const flexcan_user_config_t * data,
1516 uint32_t mb_idx,
1517 uint32_t ext_mask)
1518 {
1519 assert(data);
1520
1521 if (mb_idx >= data->max_num_mb)
1522 {
1523 return (kStatus_FLEXCAN_OutOfRange);
1524 }
1525
1526 /* Set Freeze mode*/
1527 BW_CAN_MCR_FRZ(canBaseAddr, 0x1);
1528 BW_CAN_MCR_HALT(canBaseAddr, 0x1);
1529
1530 /* Wait for entering the freeze mode*/
1531 while (!(BR_CAN_MCR_FRZACK(canBaseAddr))){}
1532
1533 /* 29-bit extended mask*/
1534 HW_CAN_RXIMRn_WR(canBaseAddr, mb_idx, CAN_ID_EXT(ext_mask));
1535
1536 /* De-assert Freeze Mode*/
1537 BW_CAN_MCR_HALT(canBaseAddr, 0x0);
1538 BW_CAN_MCR_FRZ(canBaseAddr, 0x0);
1539
1540 /* Wait till exit of freeze mode*/
1541 while (BR_CAN_MCR_FRZACK(canBaseAddr)){}
1542
1543 return (kStatus_FLEXCAN_Success);
1544 }
1545
1546 /*FUNCTION**********************************************************************
1547 *
1548 * Function Name : FLEXCAN_HAL_SetRxMbGlobalStdMask
1549 * Description : Set Rx Message Buffer global mask as the 11-bit standard mask.
1550 *
1551 *END**************************************************************************/
1552 void FLEXCAN_HAL_SetRxMbGlobalStdMask(
1553 uint32_t canBaseAddr,
1554 uint32_t std_mask)
1555 {
1556 /* Set Freeze mode*/
1557 BW_CAN_MCR_FRZ(canBaseAddr, 0x1);
1558 BW_CAN_MCR_HALT(canBaseAddr, 0x1);
1559
1560 /* Wait for entering the freeze mode*/
1561 while (!(BR_CAN_MCR_FRZACK(canBaseAddr))){}
1562
1563 /* 11 bit standard mask*/
1564 HW_CAN_RXMGMASK_WR(canBaseAddr, CAN_ID_STD(std_mask));
1565
1566 /* De-assert Freeze Mode*/
1567 BW_CAN_MCR_HALT(canBaseAddr, 0x0);
1568 BW_CAN_MCR_FRZ(canBaseAddr, 0x0);
1569
1570 /* Wait till exit of freeze mode*/
1571 while (BR_CAN_MCR_FRZACK(canBaseAddr)){}
1572 }
1573
1574 /*FUNCTION**********************************************************************
1575 *
1576 * Function Name : FLEXCAN_HAL_SetRxMbBuf14StdMask
1577 * Description : Set Rx Message Buffer 14 mask as the 11-bit standard mask.
1578 *
1579 *END**************************************************************************/
1580 void FLEXCAN_HAL_SetRxMbBuf14StdMask(
1581 uint32_t canBaseAddr,
1582 uint32_t std_mask)
1583 {
1584 /* Set Freeze mode*/
1585 BW_CAN_MCR_FRZ(canBaseAddr, 0x1);
1586 BW_CAN_MCR_HALT(canBaseAddr, 0x1);
1587
1588 /* Wait for entering the freeze mode*/
1589 while (!(BR_CAN_MCR_FRZACK(canBaseAddr))){}
1590
1591 /* 11 bit standard mask*/
1592 HW_CAN_RX14MASK_WR(canBaseAddr, CAN_ID_STD(std_mask));
1593
1594 /* De-assert Freeze Mode*/
1595 BW_CAN_MCR_HALT(canBaseAddr, 0x0);
1596 BW_CAN_MCR_FRZ(canBaseAddr, 0x0);
1597
1598 /* Wait till exit of freeze mode*/
1599 while (BR_CAN_MCR_FRZACK(canBaseAddr)){}
1600 }
1601
1602 /*FUNCTION**********************************************************************
1603 *
1604 * Function Name : FLEXCAN_HAL_SetRxMbBuf15StdMask
1605 * Description : Set Rx Message Buffer 15 mask as the 11-bit standard mask.
1606 *
1607 *END**************************************************************************/
1608 void FLEXCAN_HAL_SetRxMbBuf15StdMask(
1609 uint32_t canBaseAddr,
1610 uint32_t std_mask)
1611 {
1612 /* Set Freeze mode*/
1613 BW_CAN_MCR_FRZ(canBaseAddr, 0x1);
1614 BW_CAN_MCR_HALT(canBaseAddr, 0x1);
1615
1616 /* Wait for entering the freeze mode*/
1617 while (!(BR_CAN_MCR_FRZACK(canBaseAddr))){}
1618
1619 /* 11 bit standard mask*/
1620 HW_CAN_RX15MASK_WR(canBaseAddr, CAN_ID_STD(std_mask));
1621
1622 /* De-assert Freeze Mode*/
1623 BW_CAN_MCR_HALT(canBaseAddr, 0x0);
1624 BW_CAN_MCR_FRZ(canBaseAddr, 0x0);
1625
1626 /* Wait till exit of freeze mode*/
1627 while (BR_CAN_MCR_FRZACK(canBaseAddr)){}
1628 }
1629
1630 /*FUNCTION**********************************************************************
1631 *
1632 * Function Name : FLEXCAN_HAL_SetRxMbGlobalExtMask
1633 * Description : Set Rx Message Buffer global mask as the 29-bit extended mask.
1634 *
1635 *END**************************************************************************/
1636 void FLEXCAN_HAL_SetRxMbGlobalExtMask(
1637 uint32_t canBaseAddr,
1638 uint32_t ext_mask)
1639 {
1640 /* Set Freeze mode*/
1641 BW_CAN_MCR_FRZ(canBaseAddr, 0x1);
1642 BW_CAN_MCR_HALT(canBaseAddr, 0x1);
1643
1644 /* Wait for entering the freeze mode*/
1645 while (!(HW_CAN_MCR_RD(canBaseAddr))){}
1646
1647 /* 29-bit extended mask*/
1648 HW_CAN_RXMGMASK_WR(canBaseAddr, CAN_ID_EXT(ext_mask));
1649
1650 /* De-assert Freeze Mode*/
1651 BW_CAN_MCR_HALT(canBaseAddr, 0x0);
1652 BW_CAN_MCR_FRZ(canBaseAddr, 0x0);
1653
1654 /* Wait till exit of freeze mode*/
1655 while (BR_CAN_MCR_FRZACK(canBaseAddr)){}
1656 }
1657
1658 /*FUNCTION**********************************************************************
1659 *
1660 * Function Name : FLEXCAN_HAL_SetRxMbBuf14ExtMask
1661 * Description : Set Rx Message Buffer 14 mask as the 29-bit extended mask.
1662 *
1663 *END**************************************************************************/
1664 void FLEXCAN_HAL_SetRxMbBuf14ExtMask(
1665 uint32_t canBaseAddr,
1666 uint32_t ext_mask)
1667 {
1668 /* Set Freeze mode*/
1669 BW_CAN_MCR_FRZ(canBaseAddr, 0x1);
1670 BW_CAN_MCR_HALT(canBaseAddr, 0x1);
1671
1672 /* Wait for entering the freeze mode*/
1673 while (!(BR_CAN_MCR_FRZACK(canBaseAddr))){}
1674
1675 /* 29-bit extended mask*/
1676 HW_CAN_RX14MASK_WR(canBaseAddr, CAN_ID_EXT(ext_mask));
1677
1678 /* De-assert Freeze Mode*/
1679 BW_CAN_MCR_HALT(canBaseAddr, 0x0);
1680 BW_CAN_MCR_FRZ(canBaseAddr, 0x0);
1681
1682 /* Wait till exit of freeze mode*/
1683 while (BR_CAN_MCR_FRZACK(canBaseAddr)){}
1684 }
1685
1686 /*FUNCTION**********************************************************************
1687 *
1688 * Function Name : FLEXCAN_HAL_SetRxMbBuf15ExtMask
1689 * Description : Set Rx Message Buffer 15 mask as the 29-bit extended mask.
1690 *
1691 *END**************************************************************************/
1692 void FLEXCAN_HAL_SetRxMbBuf15ExtMask(
1693 uint32_t canBaseAddr,
1694 uint32_t ext_mask)
1695 {
1696 /* Set Freeze mode*/
1697 BW_CAN_MCR_FRZ(canBaseAddr, 0x1);
1698 BW_CAN_MCR_HALT(canBaseAddr, 0x1);
1699
1700 /* Wait for entering the freeze mode*/
1701 while (!(BR_CAN_MCR_FRZACK(canBaseAddr))){}
1702
1703 /* 29-bit extended mask*/
1704 HW_CAN_RX15MASK_WR(canBaseAddr, CAN_ID_EXT(ext_mask));
1705
1706 /* De-assert Freeze Mode*/
1707 BW_CAN_MCR_HALT(canBaseAddr, 0x0);
1708 BW_CAN_MCR_FRZ(canBaseAddr, 0x0);
1709
1710 /* Wait till exit of freeze mode*/
1711 while (BR_CAN_MCR_FRZACK(canBaseAddr)){}
1712 }
1713
1714 /*FUNCTION**********************************************************************
1715 *
1716 * Function Name : FLEXCAN_HAL_EnableOperationMode
1717 * Description : Enable a FlexCAN operation mode.
1718 * This function will enable one of the modes listed in flexcan_operation_modes_t.
1719 *
1720 *END**************************************************************************/
1721 flexcan_status_t FLEXCAN_HAL_EnableOperationMode(
1722 uint32_t canBaseAddr,
1723 flexcan_operation_modes_t mode)
1724 {
1725 if (mode == kFlexCanFreezeMode)
1726 {
1727 /* Debug mode, Halt and Freeze*/
1728 BW_CAN_MCR_FRZ(canBaseAddr, 0x1);
1729 BW_CAN_MCR_HALT(canBaseAddr, 0x1);
1730
1731 /* Wait for entering the freeze mode*/
1732 while (!(BR_CAN_MCR_FRZACK(canBaseAddr))){}
1733
1734 return (kStatus_FLEXCAN_Success);
1735 }
1736 else if (mode == kFlexCanDisableMode)
1737 {
1738 /* Debug mode, Halt and Freeze*/
1739 BW_CAN_MCR_MDIS(canBaseAddr, 0x1);
1740 return (kStatus_FLEXCAN_Success);
1741 }
1742
1743 /* Set Freeze mode*/
1744 BW_CAN_MCR_FRZ(canBaseAddr, 0x1);
1745 BW_CAN_MCR_HALT(canBaseAddr, 0x1);
1746
1747 /* Wait for entering the freeze mode*/
1748 while (!(BR_CAN_MCR_FRZACK(canBaseAddr))){}
1749
1750 if (mode == kFlexCanNormalMode)
1751 {
1752 BW_CAN_MCR_SUPV(canBaseAddr, 0x0);
1753 }
1754 else if (mode == kFlexCanListenOnlyMode)
1755 {
1756 BW_CAN_CTRL1_LOM(canBaseAddr, 0x1);
1757 }
1758 else if (mode == kFlexCanLoopBackMode)
1759 {
1760 BW_CAN_CTRL1_LPB(canBaseAddr, 0x1);
1761 }
1762 else
1763 {
1764 return kStatus_FLEXCAN_InvalidArgument;
1765 }
1766
1767 /* De-assert Freeze Mode*/
1768 BW_CAN_MCR_HALT(canBaseAddr, 0x0);
1769 BW_CAN_MCR_FRZ(canBaseAddr, 0x0);
1770
1771 /* Wait till exit of freeze mode*/
1772 while (BR_CAN_MCR_FRZACK(canBaseAddr)){}
1773
1774 return (kStatus_FLEXCAN_Success);
1775 }
1776
1777 /*FUNCTION**********************************************************************
1778 *
1779 * Function Name : FLEXCAN_HAL_DisableOperationMode
1780 * Description : Disable a FlexCAN operation mode.
1781 * This function will disable one of the modes listed in flexcan_operation_modes_t.
1782 *
1783 *END**************************************************************************/
1784 flexcan_status_t FLEXCAN_HAL_DisableOperationMode(
1785 uint32_t canBaseAddr,
1786 flexcan_operation_modes_t mode)
1787 {
1788 if (mode == kFlexCanFreezeMode)
1789 {
1790 /* De-assert Freeze Mode*/
1791 BW_CAN_MCR_HALT(canBaseAddr, 0x0);
1792 BW_CAN_MCR_FRZ(canBaseAddr, 0x0);
1793
1794 /* Wait till exit of freeze mode*/
1795 while (BR_CAN_MCR_FRZACK(canBaseAddr)){}
1796
1797 return (kStatus_FLEXCAN_Success);
1798 }
1799 else if (mode == kFlexCanDisableMode)
1800 {
1801 /* Disable module mode*/
1802 BW_CAN_MCR_MDIS(canBaseAddr, 0x0);
1803 return (kStatus_FLEXCAN_Success);
1804 }
1805
1806 /* Set Freeze mode*/
1807 BW_CAN_MCR_FRZ(canBaseAddr, 0x1);
1808 BW_CAN_MCR_HALT(canBaseAddr, 0x1);
1809
1810 /* Wait for entering the freeze mode*/
1811 while (!(BR_CAN_MCR_FRZACK(canBaseAddr))){}
1812
1813 if (mode == kFlexCanNormalMode)
1814 {
1815 BW_CAN_MCR_SUPV(canBaseAddr, 0x1);
1816 }
1817 else if (mode == kFlexCanListenOnlyMode)
1818 {
1819 BW_CAN_CTRL1_LOM(canBaseAddr, 0x0);
1820 }
1821 else if (mode == kFlexCanLoopBackMode)
1822 {
1823 BW_CAN_CTRL1_LPB(canBaseAddr, 0x0);
1824 }
1825 else
1826 {
1827 return kStatus_FLEXCAN_InvalidArgument;
1828 }
1829
1830 /* De-assert Freeze Mode*/
1831 BW_CAN_MCR_HALT(canBaseAddr, 0x0);
1832 BW_CAN_MCR_FRZ(canBaseAddr, 0x0);
1833
1834 /* Wait till exit of freeze mode*/
1835 while (BR_CAN_MCR_FRZACK(canBaseAddr)){}
1836
1837 return (kStatus_FLEXCAN_Success);
1838 }
1839
1840 #endif /* MBED_NO_FLEXCAN */
1841
1842 /*******************************************************************************
1843 * EOF
1844 ******************************************************************************/
1845
Imprint / Impressum