]> git.donarmstrong.com Git - qmk_firmware.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
[qmk_firmware.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