1 /****************************************************************************
2  * @file     canfd.c
3  * @version  V1.00
4  * @brief    CAN FD driver source file
5  *
6  * @copyright SPDX-License-Identifier: Apache-2.0
7  * @copyright Copyright (C) 2021 Nuvoton Technology Corp. All rights reserved.
8  *****************************************************************************/
9 
10 #include "NuMicro.h"
11 #include "string.h"
12 
13 /*******************************************************************************
14  * Definitions
15  ******************************************************************************/
16 
17 /* Minimum number of time quanta in a bit. */
18 #define MIN_TIME_QUANTA    9ul
19 /* Maximum number of time quanta in a bit. */
20 #define MAX_TIME_QUANTA    20ul
21 /* Number of receive FIFOs (1 - 2) */
22 #define CANFD_NUM_RX_FIFOS  2ul
23 
24 /*CANFD max nominal bit rate*/
25 #define MAX_NOMINAL_BAUDRATE (1000000UL)
26 
27 /* Tx Event FIFO Element ESI(Error State Indicator)  */
28 #define TX_FIFO_E0_EVENT_ESI_Pos   (31)
29 #define TX_FIFO_E0_EVENT_ESI_Msk   (0x1ul << TX_FIFO_E0_EVENT_ESI_Pos)
30 
31 /* Tx Event FIFO Element XTD(Extended Identifier)    */
32 #define TX_FIFO_E0_EVENT_XTD_Pos   (30)
33 #define TX_FIFO_E0_EVENT_XTD_Msk   (0x1ul << TX_FIFO_E0_EVENT_XTD_Pos)
34 
35 /* Tx Event FIFO Element RTR(Remote Transmission Request)    */
36 #define TX_FIFO_E0_EVENT_RTR_Pos   (29)
37 #define TX_FIFO_E0_EVENT_RTR_Msk   (0x1ul << TX_FIFO_E0_EVENT_RTR_Pos)
38 
39 /* Tx Event FIFO Element ID(Identifier)    */
40 #define TX_FIFO_E0_EVENT_ID_Pos    (0)
41 #define TX_FIFO_E0_EVENT_ID_Msk    (0x1FFFFFFFul << TX_FIFO_E0_EVENT_ID_Pos)
42 
43 /* Tx Event FIFO Element MM(Message Marker)    */
44 #define TX_FIFO_E1_EVENT_MM_Pos    (24)
45 #define TX_FIFO_E1_EVENT_MM_Msk    (0xFFul << TX_FIFO_E1_EVENT_MM_Pos)
46 
47 /* Tx Event FIFO Element ET(Event Type)    */
48 #define TX_FIFO_E1_EVENT_ET_Pos    (22)
49 #define TX_FIFO_E1_EVENT_ET_Msk    (0x3ul << TX_FIFO_E1_EVENT_ET_Pos)
50 
51 /* Tx Event FIFO Element FDF(FD Format)    */
52 #define TX_FIFO_E1_EVENT_FDF_Pos    (21)
53 #define TX_FIFO_E1_EVENT_FDF_Msk    (0x1ul << TX_FIFO_E1_EVENT_FDF_Pos)
54 
55 /* Tx Event FIFO Element BRS(Bit Rate Switch)    */
56 #define TX_FIFO_E1_EVENT_BRS_Pos    (20)
57 #define TX_FIFO_E1_EVENT_BRS_Msk    (0x1ul << TX_FIFO_E1_EVENT_BRS_Pos)
58 
59 /* Tx Event FIFO Element DLC(Data Length Code)    */
60 #define TX_FIFO_E1_EVENT_DLC_Pos    (16)
61 #define TX_FIFO_E1_EVENT_DLC_Msk    (0xFul << TX_FIFO_E1_EVENT_DLC_Pos)
62 
63 /* Tx Event FIFO Element TXTS(Tx Timestamp)    */
64 #define TX_FIFO_E1A_EVENT_TXTS_Pos  (0)
65 #define TX_FIFO_E1A_EVENT_TXTS_Msk  (0xFFFFul << TX_FIFO_E1A_EVENT_TXTS_Pos)
66 
67 /* Tx Event FIFO Element MM(Message Marker)    */
68 #define TX_FIFO_E1B_EVENT_MM_Pos    (8)
69 #define TX_FIFO_E1B_EVENT_MM_Msk    (0xFFul << TX_FIFO_E1B_EVENT_MM_Pos)
70 
71 /* Tx Event FIFO Element TSC(Timestamp Captured)    */
72 #define TX_FIFO_E1B_EVENT_TSC_Pos   (4)
73 #define TX_FIFO_E1B_EVENT_TSC_Msk   (0x1ul << TX_FIFO_E1B_EVENT_TSC_Pos)
74 
75 /* Tx Event FIFO Element TSC(Timestamp Captured)    */
76 #define TX_FIFO_E1B_EVENT_TXTS_Pos   (0)
77 #define TX_FIFO_E1B_EVENT_TXTS_Msk   (0xFul << TX_FIFO_E1B_EVENT_TSC_Pos)
78 
79 /* Rx Buffer and FIFO Element ESI2(Error State Indicator)    */
80 #define RX_BUFFER_AND_FIFO_R0_ELEM_ESI_Pos  (31)
81 #define RX_BUFFER_AND_FIFO_R0_ELEM_ESI_Msk  (0x1ul << RX_BUFFER_AND_FIFO_R0_ELEM_ESI_Pos)
82 
83 /* Rx Buffer and FIFO Element XTD(Extended Identifier)    */
84 #define RX_BUFFER_AND_FIFO_R0_ELEM_XTD_Pos  (30)
85 #define RX_BUFFER_AND_FIFO_R0_ELEM_XTD_Msk  (0x1ul << RX_BUFFER_AND_FIFO_R0_ELEM_XTD_Pos)
86 
87 /* Rx Buffer and FIFO Element RTR(Remote Transmission Request)    */
88 #define RX_BUFFER_AND_FIFO_R0_ELEM_RTR_Pos  (29)
89 #define RX_BUFFER_AND_FIFO_R0_ELEM_RTR_Msk  (0x1ul << RX_BUFFER_AND_FIFO_R0_ELEM_RTR_Pos)
90 
91 /* Rx Buffer and FIFO Element ID(Identifier)    */
92 #define RX_BUFFER_AND_FIFO_R0_ELEM_ID_Pos  (0)
93 #define RX_BUFFER_AND_FIFO_R0_ELEM_ID_Msk  (0x1FFFFFFFul << RX_BUFFER_AND_FIFO_R0_ELEM_ID_Pos)
94 
95 /* Rx Buffer and FIFO Element ANMF(Accepted Non-matching Frame)    */
96 #define RX_BUFFER_AND_FIFO_R1_ELEM_ANMF_Pos  (31)
97 #define RX_BUFFER_AND_FIFO_R1_ELEM_ANMF_Msk  (0x1ul << RX_BUFFER_AND_FIFO_R1_ELEM_ANMF_Pos)
98 
99 /* Rx Buffer and FIFO Element FIDX(Filter Index)    */
100 #define RX_BUFFER_AND_FIFO_R1_ELEM_FIDX_Pos  (24)
101 #define RX_BUFFER_AND_FIFO_R1_ELEM_FIDX_Msk  (0x7Ful << RX_BUFFER_AND_FIFO_R1_ELEM_FIDX_Pos)
102 
103 /* Rx Buffer and FIFO Element FDF(FD Format)    */
104 #define RX_BUFFER_AND_FIFO_R1_ELEM_FDF_Pos  (21)
105 #define RX_BUFFER_AND_FIFO_R1_ELEM_FDF_Msk  (0x1ul << RX_BUFFER_AND_FIFO_R1_ELEM_FDF_Pos)
106 
107 /* Rx Buffer and FIFO Element BRS(Bit Rate Swit)    */
108 #define RX_BUFFER_AND_FIFO_R1_ELEM_BSR_Pos  (20)
109 #define RX_BUFFER_AND_FIFO_R1_ELEM_BSR_Msk  (0x1ul << RX_BUFFER_AND_FIFO_R1_ELEM_BSR_Pos)
110 
111 /* Rx Buffer and FIFO Element DLC(Bit Rate Swit)    */
112 #define RX_BUFFER_AND_FIFO_R1_ELEM_DLC_Pos  (16)
113 #define RX_BUFFER_AND_FIFO_R1_ELEM_DLC_Msk  (0xFul << RX_BUFFER_AND_FIFO_R1_ELEM_DLC_Pos)
114 
115 /* Rx Buffer and FIFO Element RXTS(Rx Timestamp)    */
116 #define RX_BUFFER_AND_FIFO_R1_ELEM_RXTS_Pos  (0)
117 #define RX_BUFFER_AND_FIFO_R1_ELEM_RXTS_Msk  (0xFFFFul << RX_BUFFER_AND_FIFO_R1_ELEM_RXTS_Pos)
118 
119 /* Tx Buffer Element ESI(Error State Indicator)    */
120 #define TX_BUFFER_T0_ELEM_ESI_Pos  (31)
121 #define TX_BUFFER_T0_ELEM_ESI_Msk  (0x1ul << TX_BUFFER_T0_ELEM_ESI_Pos)
122 
123 /* Tx Buffer Element XTD(Extended Identifier)    */
124 #define TX_BUFFER_T0_ELEM_XTD_Pos  (30)
125 #define TX_BUFFER_T0_ELEM_XTD_Msk (0x1ul << TX_BUFFER_T0_ELEM_XTD_Pos)
126 
127 /* Tx Buffer RTR(Remote Transmission Request)    */
128 #define TX_BUFFER_T0_ELEM_RTR_Pos  (29)
129 #define TX_BUFFER_T0_ELEM_RTR_Msk  (0x1ul << TX_BUFFER_T0_ELEM_RTR_Pos)
130 
131 /* Tx Buffer Element ID(Identifier)    */
132 #define TX_BUFFER_T0_ELEM_ID_Pos  (0)
133 #define TX_BUFFER_T0_ELEM_ID_Msk  (0x1FFFFFFFul << TX_BUFFER_T0_ELEM_ID_Pos)
134 
135 /* Tx Buffer Element MM(Message Marker)    */
136 #define TX_BUFFER_T1_ELEM_MM1_Pos  (24)
137 #define TX_BUFFER_T1_ELEM_MM1_Msk  (0xFFul << TX_BUFFER_T1_ELEM_MM1_Pos)
138 
139 /* Tx Buffer Element EFC(Event FIFO Control)    */
140 #define TX_BUFFER_T1_ELEM_EFC_Pos  (23)
141 #define TX_BUFFER_T1_ELEM_EFC_Msk  (0xFFul << TX_BUFFER_T1_ELEM_EFC_Pos)
142 
143 /* Tx Buffer Element TSCE(Time Stamp Capture Enable for TSU)    */
144 #define TX_BUFFER_T1_ELEM_TSCE_Pos  (22)
145 #define TX_BUFFER_T1_ELEM_TSCE_Msk  (0x1ul << TX_BUFFER_T1_ELEM_TSCE_Pos)
146 
147 /* Tx Buffer Element FDF(FD Format)    */
148 #define TX_BUFFER_T1_ELEM_FDF_Pos  (21)
149 #define TX_BUFFER_T1_ELEM_FDF_Msk  (0x1ul << TX_BUFFER_T1_ELEM_FDF_Pos)
150 
151 /* Tx Buffer Element BRS(Bit Rate Swit)    */
152 #define TX_BUFFER_T1_ELEM_BSR_Pos  (20)
153 #define TX_BUFFER_T1_ELEM_BSR_Msk  (0x1ul << TX_BUFFER_T1_ELEM_BSR_Pos)
154 
155 /* Tx Buffer Element DLC(Bit Rate Swit)    */
156 #define TX_BUFFER_T1_ELEM_DLC_Pos  (16)
157 #define TX_BUFFER_T1_ELEM_DLC_Msk  (0xFul << TX_BUFFER_T1_ELEM_DLC_Pos)
158 
159 /* Tx Buffer Element MM(Message Marker)    */
160 #define TX_BUFFER_T1_ELEM_MM0_Pos  (8)
161 #define TX_BUFFER_T1_ELEM_MM0_Msk  (0xFFul << TX_BUFFER_T1_ELEM_MM0_Pos)
162 
163 #define CANFD_RXFS_RFL CANFD_RXF0S_RF0L_Msk
164 
165 /** @addtogroup Standard_Driver Standard Driver
166   @{
167 */
168 
169 /** @addtogroup CANFD_Driver CAN_FD Driver
170   @{
171 */
172 
173 /** @addtogroup CANFD_EXPORTED_FUNCTIONS CAN_FD Exported Functions
174   @{
175 */
176 
177 static void CANFD_InitRxFifo(CANFD_T *canfd, uint32_t u32RxFifoNum, CANFD_RAM_PART_T *psRamConfig, CANFD_ELEM_SIZE_T *psElemSize, uint32_t u32FifoWM, E_CANFD_DATA_FIELD_SIZE eFifoSize);
178 static void CANFD_InitRxDBuf(CANFD_T *canfd, CANFD_RAM_PART_T *psRamConfig, CANFD_ELEM_SIZE_T *psElemSize, E_CANFD_DATA_FIELD_SIZE eRxBufSize);
179 static void CANFD_InitTxDBuf(CANFD_T *canfd, CANFD_RAM_PART_T *psRamConfig, CANFD_ELEM_SIZE_T *psElemSize, E_CANFD_DATA_FIELD_SIZE eTxBufSize);
180 static void CANFD_InitTxEvntFifo(CANFD_T *canfd, CANFD_RAM_PART_T *psRamConfig, CANFD_ELEM_SIZE_T *psElemSize, uint32_t u32FifoWaterLvl);
181 static void CANFD_ConfigSIDFC(CANFD_T *canfd, CANFD_RAM_PART_T *psRamConfig, CANFD_ELEM_SIZE_T *psElemSize);
182 static void CANFD_ConfigXIDFC(CANFD_T *canfd, CANFD_RAM_PART_T *psRamConfig, CANFD_ELEM_SIZE_T *psElemSize);
183 
CANFD_ReadReg(__I uint32_t * pu32RegAddr)184 uint32_t CANFD_ReadReg(__I uint32_t* pu32RegAddr)
185 {
186     uint32_t u32ReadReg;
187     uint32_t u32TimeOutCnt = CANFD_READ_REG_TIMEOUT;
188     u32ReadReg = 0UL;
189 
190     do
191     {
192         u32ReadReg = inpw(pu32RegAddr);
193         if (--u32TimeOutCnt == 0UL)
194         {
195             break;
196         }
197     }
198     while (u32ReadReg == 0UL);
199 
200     return u32ReadReg;
201 }
202 
203 /**
204  * @brief       Calculates the CAN FD RAM buffer address.
205  *
206  * @param[in]   psConfigAddr  CAN FD element star address structure.
207  * @param[in]   psConfigSize  CAN FD element size structure.
208  *
209  * @return      None.
210  *
211  * @details     Calculates the CAN FD RAM buffer address.
212  */
CANFD_CalculateRamAddress(CANFD_RAM_PART_T * psConfigAddr,CANFD_ELEM_SIZE_T * psConfigSize)213 static void CANFD_CalculateRamAddress(CANFD_RAM_PART_T *psConfigAddr, CANFD_ELEM_SIZE_T *psConfigSize)
214 {
215     uint32_t u32RamAddrOffset = 0;
216 
217     /* Get the Standard Message ID Filter element address */
218     if (psConfigSize->u32SIDFC > 0)
219     {
220         psConfigAddr->u32SIDFC_FLSSA = 0;
221         u32RamAddrOffset += psConfigSize->u32SIDFC * sizeof(CANFD_STD_FILTER_T);
222     }
223 
224     /* Get the Extended Message ID Filter element address */
225     if (psConfigSize->u32XIDFC > 0)
226     {
227         psConfigAddr->u32XIDFC_FLESA = u32RamAddrOffset;
228         u32RamAddrOffset += psConfigSize->u32XIDFC * sizeof(CANFD_EXT_FILTER_T);
229     }
230 
231     /* Get the Rx FIFO0 element address */
232     if (psConfigSize->u32RxFifo0 > 0)
233     {
234         psConfigAddr->u32RXF0C_F0SA = u32RamAddrOffset;
235         u32RamAddrOffset += psConfigSize->u32RxFifo0 * sizeof(CANFD_BUF_T);
236     }
237 
238     /* Get the Rx FIFO1 element address */
239     if (psConfigSize->u32RxFifo1 > 0)
240     {
241         psConfigAddr->u32RXF1C_F1SA = u32RamAddrOffset;
242         u32RamAddrOffset += psConfigSize->u32RxFifo1 * sizeof(CANFD_BUF_T);
243     }
244 
245     /* Get the Rx Buffer element address */
246     if (psConfigSize->u32RxBuf > 0)
247     {
248         psConfigAddr->u32RXBC_RBSA = u32RamAddrOffset;
249         u32RamAddrOffset += psConfigSize->u32RxBuf * sizeof(CANFD_BUF_T);
250     }
251 
252     /* Get the TX Event FIFO element address */
253     if (psConfigSize->u32TxEventFifo > 0)
254     {
255         psConfigAddr->u32TXEFC_EFSA = u32RamAddrOffset;
256         u32RamAddrOffset += psConfigSize->u32TxEventFifo *  sizeof(CANFD_EXT_FILTER_T);
257     }
258 
259     /* Get the Tx Buffer element address */
260     if (psConfigSize->u32TxBuf > 0)
261     {
262         psConfigAddr->u32TXBC_TBSA = u32RamAddrOffset;
263         u32RamAddrOffset += psConfigSize->u32TxBuf * sizeof(CANFD_BUF_T);
264     }
265 }
266 
267 /**
268  * @brief       Get the default configuration structure.
269  *
270  * @param[in]   psConfig       Pointer to CAN FD configuration structure.
271  * @param[in]   u8OpMode       Setting the CAN FD Operating mode.
272  *
273  * @return      None.
274  *
275  * @details     This function initializes the CAN FD configure structure to default value.
276  *              The default value are:
277  *              sNormBitRate.u32BitRate   = 500000bps;
278  *              u32DataBaudRate     = 0(CAN mode) or 1000000(CAN FD mode) ;
279  *              u32MRamSize         = 0x20010000;
280  *              bEnableLoopBack     = FALSE;
281  *              bBitRateSwitch      = FALSE(CAN Mode) or TRUE(CAN FD Mode);
282  *              bFDEn               = FALSE(CAN Mode) or TRUE(CAN FD Mode);
283 */
CANFD_GetDefaultConfig(CANFD_FD_T * psConfig,uint8_t u8OpMode)284 void CANFD_GetDefaultConfig(CANFD_FD_T *psConfig, uint8_t u8OpMode)
285 {
286     memset(psConfig, 0, sizeof(CANFD_FD_T));
287 
288     psConfig->sBtConfig.sNormBitRate.u32BitRate = 500000;
289 
290     if (u8OpMode == CANFD_OP_CAN_MODE)
291     {
292         psConfig->sBtConfig.sDataBitRate.u32BitRate = 0;
293         psConfig->sBtConfig.bFDEn = FALSE;
294         psConfig->sBtConfig.bBitRateSwitch = FALSE;
295     }
296     else
297     {
298         psConfig->sBtConfig.sDataBitRate.u32BitRate = 10000000;
299         psConfig->sBtConfig.bFDEn = TRUE;
300         psConfig->sBtConfig.bBitRateSwitch = TRUE;
301     }
302 
303     /*Disable the Internal Loopback mode */
304     psConfig->sBtConfig.bEnableLoopBack = FALSE;
305     /*Get the CAN FD memory address*/
306     psConfig->u32MRamSize  = CANFD_SRAM_SIZE;
307 
308     /* CAN FD Standard message ID elements as 64 elements    */
309     psConfig->sElemSize.u32SIDFC = 64;
310     /* CAN FD Extended message ID elements as 64 elements    */
311     psConfig->sElemSize.u32XIDFC = 64;
312     /* CAN FD TX Buffer elements as 8 elements    */
313     psConfig->sElemSize.u32TxBuf = 8;
314     /* CAN FD RX Buffer elements as 8 elements    */
315     psConfig->sElemSize.u32RxBuf = 8;
316     /* CAN FD RX FIFO0 elements as 48 elements    */
317     psConfig->sElemSize.u32RxFifo0 = 48;
318     /* CAN FD RX FIFO1 elements as 8 elements    */
319     psConfig->sElemSize.u32RxFifo1 = 8;
320     /* CAN FD TX Event FOFI elements as 8 elements    */
321     psConfig->sElemSize.u32TxEventFifo = 8;
322     /*Calculates the CAN FD RAM buffer address*/
323     CANFD_CalculateRamAddress(&psConfig->sMRamStartAddr, &psConfig->sElemSize);
324 }
325 
326 
327 /**
328  * @brief       Encode the Data Length Code.
329  *
330  * @param[in]   u8NumberOfBytes  Number of bytes in a message.
331  *
332  * @return      Data Length Code.
333  *
334  * @details     Converts number of bytes in a message into a Data Length Code.
335  */
CANFD_EncodeDLC(uint8_t u8NumberOfBytes)336 static uint8_t CANFD_EncodeDLC(uint8_t u8NumberOfBytes)
337 {
338     if (u8NumberOfBytes <= 8) return u8NumberOfBytes;
339     else if (u8NumberOfBytes <= 12) return 9;
340     else if (u8NumberOfBytes <= 16) return 10;
341     else if (u8NumberOfBytes <= 20) return 11;
342     else if (u8NumberOfBytes <= 24) return 12;
343     else if (u8NumberOfBytes <= 32) return 13;
344     else if (u8NumberOfBytes <= 48) return 14;
345     else return 15;
346 }
347 
348 
349 /**
350  * @brief       Decode the Data Length Code.
351  *
352  * @param[in]   u8Dlc   Data Length Code.
353  *
354  * @return      Number of bytes in a message.
355  *
356  * @details     Converts a Data Length Code into a number of message bytes.
357  */
CANFD_DecodeDLC(uint8_t u8Dlc)358 static uint8_t CANFD_DecodeDLC(uint8_t u8Dlc)
359 {
360     if (u8Dlc <= 8) return u8Dlc;
361     else if (u8Dlc == 9) return 12;
362     else if (u8Dlc == 10) return 16;
363     else if (u8Dlc == 11) return 20;
364     else if (u8Dlc == 12) return 24;
365     else if (u8Dlc == 13) return 32;
366     else if (u8Dlc == 14) return 48;
367     else return 64;
368 }
369 
370 
371 /**
372  * @brief       Sets the CAN FD protocol timing characteristic.
373  *
374  * @param[in]   psCanfd     The pointer of the specified CANFD module.
375  * @param[in]   psConfig    Pointer to the timing configuration structure.
376  *
377  * @return      None.
378  *
379  * @details     This function gives user settings to CAN bus timing characteristic.
380  *              The function is for an experienced user. For less experienced users, call
381  *              the CANFD_Open() and fill the baud rate field with a desired value.
382  *              This provides the default timing characteristics to the module.
383  */
CANFD_SetTimingConfig(CANFD_T * psCanfd,const CANFD_TIMEING_CONFIG_T * psConfig)384 static void CANFD_SetTimingConfig(CANFD_T *psCanfd, const CANFD_TIMEING_CONFIG_T *psConfig)
385 {
386     if (psCanfd == (CANFD_T *)CANFD0)
387     {
388         /* Set CANFD0 clock divider number */
389         CLK->CLKDIV5 = (CLK->CLKDIV5 & ~CLK_CLKDIV5_CANFD0DIV_Msk) | CLK_CLKDIV5_CANFD0(psConfig->u8PreDivider) ;
390     }
391     else if (psCanfd == (CANFD_T *)CANFD1)
392     {
393         /* Set CANFD1 clock divider number */
394         CLK->CLKDIV5 = (CLK->CLKDIV5 & ~CLK_CLKDIV5_CANFD1DIV_Msk) | CLK_CLKDIV5_CANFD1(psConfig->u8PreDivider) ;
395     }
396     else if (psCanfd == (CANFD_T *)CANFD2)
397     {
398         /* Set CANFD2 clock divider number */
399         CLK->CLKDIV5 = (CLK->CLKDIV5 & ~CLK_CLKDIV5_CANFD2DIV_Msk) | CLK_CLKDIV5_CANFD2(psConfig->u8PreDivider) ;
400     }
401     else if (psCanfd == (CANFD_T *)CANFD3)
402     {
403         /* Set CANFD3 clock divider number */
404         CLK->CLKDIV5 = (CLK->CLKDIV5 & ~CLK_CLKDIV5_CANFD3DIV_Msk) | CLK_CLKDIV5_CANFD3(psConfig->u8PreDivider) ;
405     }
406     else
407     {
408         return;
409     }
410 
411     /* configuration change enable */
412     psCanfd->CCCR |= CANFD_CCCR_CCE_Msk;
413 
414     /* nominal bit rate */
415     psCanfd->NBTP = (((psConfig->u8NominalRJumpwidth & 0x7F) - 1) << 25) +
416                     (((psConfig->u16NominalPrescaler & 0x1FF) - 1) << 16) +
417                     ((((psConfig->u8NominalPhaseSeg1 + psConfig->u8NominalPropSeg) & 0xFF) - 1) << 8) +
418                     (((psConfig->u8NominalPhaseSeg2 & 0x7F) - 1) << 0);
419 
420 
421     /* canfd->DBTP */
422     if (psCanfd->CCCR & CANFD_CCCR_FDOE_Msk)
423     {
424         psCanfd->DBTP = (((psConfig->u8DataPrescaler & 0x1F) - 1) << 16) +
425                         ((((psConfig->u8DataPhaseSeg1 + psConfig->u8DataPropSeg) & 0x1F) - 1) << 8) +
426                         (((psConfig->u8DataPhaseSeg2 & 0xF) - 1) << 4) +
427                         (((psConfig->u8DataRJumpwidth & 0xF) - 1) << 0);
428     }
429 }
430 
431 
432 /**
433  * @brief       Get the segment values.
434  *
435  * @param[in]   u32NominalBaudRate  The nominal speed in bps.
436  * @param[in]   u32DataBaudRate     The data speed in bps.
437  * @param[in]   u32Ntq              Number of nominal time quanta per bit.
438  * @param[in]   u32Dtq              Number of data time quanta per bit.
439  * @param[in]   psConfig            Passed is a configuration structure, on return the configuration is stored in the structure
440  *
441  * @return      None.
442  *
443  * @details     Calculates the segment values for a single bit time for nominal and data baudrates.
444  */
CANFD_GetSegments(uint32_t u32NominalBaudRate,uint32_t u32DataBaudRate,uint32_t u32Ntq,uint32_t u32Dtq,CANFD_TIMEING_CONFIG_T * psConfig)445 static void CANFD_GetSegments(uint32_t u32NominalBaudRate, uint32_t u32DataBaudRate, uint32_t u32Ntq, uint32_t u32Dtq, CANFD_TIMEING_CONFIG_T *psConfig)
446 {
447     float ideal_sp;
448     int int32P1;
449 
450     /* get ideal sample point */
451     if (u32NominalBaudRate >= 1000000)     ideal_sp = 0.750;
452     else if (u32NominalBaudRate >= 800000) ideal_sp = 0.800;
453     else                                   ideal_sp = 0.875;
454 
455     /* distribute time quanta */
456     int32P1 = (int)(u32Ntq * ideal_sp);
457     /* can controller doesn't separate prop seg and phase seg 1 */
458     psConfig->u8NominalPropSeg = 0;
459     /* subtract one TQ for sync seg */
460     psConfig->u8NominalPhaseSeg1 = int32P1 - 1;
461     psConfig->u8NominalPhaseSeg2 = u32Ntq - int32P1;
462     /* sjw is 20% of total TQ, rounded to nearest int */
463     psConfig->u8NominalRJumpwidth = (u32Ntq + (5 - 1)) / 5;
464 
465 
466     /* if using baud rate switching then distribute time quanta for data rate */
467     if (u32Dtq > 0)
468     {
469         /* get ideal sample point */
470         if (u32DataBaudRate >= 1000000)     ideal_sp = 0.750;
471         else if (u32DataBaudRate >= 800000) ideal_sp = 0.800;
472         else                             ideal_sp = 0.875;
473 
474         /* distribute time quanta */
475         int32P1 = (int)(u32Dtq * ideal_sp);
476         /* can controller doesn't separate prop seg and phase seg 1 */
477         psConfig->u8DataPropSeg = 0;
478         /* subtract one TQ for sync seg */
479         psConfig->u8DataPhaseSeg1 = int32P1 - 1;
480         psConfig->u8DataPhaseSeg2 = u32Dtq - int32P1;
481         /* sjw is 20% of total TQ, rounded to nearest int */
482         psConfig->u8DataRJumpwidth = (u32Dtq + (5 - 1)) / 5;
483     }
484     else
485     {
486         psConfig->u8DataPropSeg = 0;
487         psConfig->u8DataPhaseSeg1 = 0;
488         psConfig->u8DataPhaseSeg2 = 0;
489         psConfig->u8DataRJumpwidth = 0;
490     }
491 }
492 
493 
494 /**
495  * @brief       Calculates the CAN controller timing values for specific baudrates.
496  *
497  * @param[in]   u32NominalBaudRate  The nominal speed in bps.
498  * @param[in]   u32DataBaudRate     The data speed in bps. Zero to disable baudrate switching.
499  * @param[in]   u32SourceClock_Hz   CAN FD Protocol Engine clock source frequency in Hz.
500  * @param[in]   psConfig            Passed is a configuration structure, on return the configuration is stored in the structure
501  *
502  * @return      true if timing configuration found, false if failed to find configuration.
503  *
504  * @details     Calculates the CAN controller timing values for specific baudrates.
505  */
CANFD_CalculateTimingValues(CANFD_T * psCanfd,uint32_t u32NominalBaudRate,uint32_t u32DataBaudRate,uint32_t u32SourceClock_Hz,CANFD_TIMEING_CONFIG_T * psConfig)506 static uint32_t CANFD_CalculateTimingValues(CANFD_T *psCanfd, uint32_t u32NominalBaudRate, uint32_t u32DataBaudRate, uint32_t u32SourceClock_Hz, CANFD_TIMEING_CONFIG_T *psConfig)
507 {
508     int i32Nclk;
509     int i32Nclk2;
510     int i32Ntq;
511     int i32Dclk;
512     int i32Dclk2;
513     int i32Dtq;
514 
515     /* observe baud rate maximums */
516     if (u32NominalBaudRate > MAX_NOMINAL_BAUDRATE) u32NominalBaudRate = MAX_NOMINAL_BAUDRATE;
517 
518     for (i32Ntq = MAX_TIME_QUANTA; i32Ntq >= MIN_TIME_QUANTA; i32Ntq--)
519     {
520         i32Nclk = u32NominalBaudRate * i32Ntq;
521 
522         for (psConfig->u16NominalPrescaler = 0x001; psConfig->u16NominalPrescaler <= 0x400; (psConfig->u16NominalPrescaler)++)
523         {
524             i32Nclk2 = i32Nclk * psConfig->u16NominalPrescaler;
525 
526             if (((u32SourceClock_Hz / i32Nclk2) <= 5) && ((u32SourceClock_Hz % i32Nclk2) == 0))
527             {
528                 psConfig->u8PreDivider = u32SourceClock_Hz / i32Nclk2;
529 
530                 /* FD Operation? */
531                 if ( psCanfd->CCCR & CANFD_CCCR_FDOE_Msk )
532                 {
533                     /* Exception case: Let u32DataBaudRate is same with u32NominalBaudRate. */
534                     if (u32DataBaudRate == 0)
535                         u32DataBaudRate = u32NominalBaudRate;
536 
537                     /* if baudrates are the same and the solution for nominal will work for
538                        data, then use the nominal settings for both */
539                     if ((u32DataBaudRate == u32NominalBaudRate) && (psConfig->u16NominalPrescaler <= 0x20))
540                     {
541                         i32Dtq = i32Ntq;
542                         psConfig->u8DataPrescaler = (uint8_t)psConfig->u16NominalPrescaler;
543                         CANFD_GetSegments(u32NominalBaudRate, u32DataBaudRate, i32Ntq, i32Dtq, psConfig);
544                         return TRUE;
545                     }
546 
547                     /* calculate data settings */
548                     for (i32Dtq = MAX_TIME_QUANTA; i32Dtq >= MIN_TIME_QUANTA; i32Dtq--)
549                     {
550                         i32Dclk = u32DataBaudRate * i32Dtq;
551 
552                         for (psConfig->u8DataPrescaler = 0x01; psConfig->u8DataPrescaler <= 0x20; (psConfig->u8DataPrescaler)++)
553                         {
554                             i32Dclk2 = i32Dclk * psConfig->u8DataPrescaler;
555                             if (u32SourceClock_Hz == ((uint32_t)i32Dclk2 * psConfig->u8PreDivider))
556                             {
557                                 CANFD_GetSegments(u32NominalBaudRate, u32DataBaudRate, i32Ntq, i32Dtq, psConfig);
558                                 return TRUE;
559                             }
560                         }
561                     }
562                 }
563                 else
564                 {
565                     psConfig->u8DataPrescaler = 0;
566                     CANFD_GetSegments(u32NominalBaudRate, 0, i32Ntq, 0, psConfig);
567                     return TRUE;
568                 }
569             }
570         }
571     }
572 
573     /* failed to find solution */
574     return FALSE;
575 }
576 
577 
578 /**
579  * @brief       Config message ram and Set bit-time.
580  *
581  * @param[in]   psCanfd     The pointer to CAN FD module base address.
582  * @param[in]   psCanfdStr  message ram setting and bit-time setting
583  *
584  * @return      None.
585  *
586  * @details     Converts a Data Length Code into a number of message bytes.
587  */
CANFD_Open(CANFD_T * psCanfd,CANFD_FD_T * psCanfdStr)588 void CANFD_Open(CANFD_T *psCanfd, CANFD_FD_T *psCanfdStr)
589 {
590     uint32_t u32RegLockLevel = SYS_IsRegLocked();
591 
592     if (u32RegLockLevel)
593         SYS_UnlockReg();
594 
595     if (psCanfd == (CANFD_T *)CANFD0)
596     {
597         CLK_EnableModuleClock(CANFD0_MODULE);
598         SYS_ResetModule(CANFD0_RST);
599     }
600     else if (psCanfd == (CANFD_T *)CANFD1)
601     {
602         CLK_EnableModuleClock(CANFD1_MODULE);
603         SYS_ResetModule(CANFD1_RST);
604     }
605     else if (psCanfd == (CANFD_T *)CANFD2)
606     {
607         CLK_EnableModuleClock(CANFD2_MODULE);
608         SYS_ResetModule(CANFD2_RST);
609     }
610     else if (psCanfd == (CANFD_T *)CANFD3)
611     {
612         CLK_EnableModuleClock(CANFD3_MODULE);
613         SYS_ResetModule(CANFD3_RST);
614     }
615     else
616     {
617         if (u32RegLockLevel)
618             SYS_LockReg();
619 
620         return;
621     }
622 
623     /* configuration change enable */
624     psCanfd->CCCR |= CANFD_CCCR_CCE_Msk;
625 
626     if (psCanfdStr->sBtConfig.bBitRateSwitch)
627     {
628         /* enable FD and baud-rate switching */
629         psCanfd->CCCR |= CANFD_CCCR_BRSE_Msk;
630     }
631 
632     if (psCanfdStr->sBtConfig.bFDEn)
633     {
634         /*FD Operation enabled*/
635         psCanfd->CCCR |= CANFD_CCCR_FDOE_Msk;
636     }
637 
638     /*Clear the Rx Fifo0 element setting */
639     psCanfd->RXF0C = 0;
640     /*Clear the Rx Fifo1 element setting */
641     psCanfd->RXF1C = 0;
642 
643     /* calculate and apply timing */
644     if (CANFD_CalculateTimingValues(psCanfd, psCanfdStr->sBtConfig.sNormBitRate.u32BitRate, psCanfdStr->sBtConfig.sDataBitRate.u32BitRate,
645                                     SystemCoreClock, &psCanfdStr->sBtConfig.sConfigBitTing))
646     {
647         CANFD_SetTimingConfig(psCanfd, &psCanfdStr->sBtConfig.sConfigBitTing);
648     }
649 
650     if (u32RegLockLevel)
651         SYS_LockReg();
652 
653     /* Configures the Standard ID Filter element */
654     if (psCanfdStr->sElemSize.u32SIDFC != 0)
655         CANFD_ConfigSIDFC(psCanfd, &psCanfdStr->sMRamStartAddr, &psCanfdStr->sElemSize);
656 
657     /*Configures the Extended ID Filter element */
658     if (psCanfdStr->sElemSize.u32XIDFC != 0)
659         CANFD_ConfigXIDFC(psCanfd, &psCanfdStr->sMRamStartAddr, &psCanfdStr->sElemSize);
660 
661     /*Configures the Tx Buffer element */
662     if (psCanfdStr->sElemSize.u32RxBuf != 0)
663         CANFD_InitTxDBuf(psCanfd, &psCanfdStr->sMRamStartAddr, &psCanfdStr->sElemSize, eCANFD_BYTE64);
664 
665     /*Configures the Rx Buffer element */
666     if (psCanfdStr->sElemSize.u32RxBuf != 0)
667         CANFD_InitRxDBuf(psCanfd, &psCanfdStr->sMRamStartAddr, &psCanfdStr->sElemSize, eCANFD_BYTE64);
668 
669     /*Configures the Rx Fifo0 element */
670     if (psCanfdStr->sElemSize.u32RxFifo0 != 0)
671         CANFD_InitRxFifo(psCanfd, 0, &psCanfdStr->sMRamStartAddr, &psCanfdStr->sElemSize, 0, eCANFD_BYTE64);
672 
673     /*Configures the Rx Fifo1 element */
674     if (psCanfdStr->sElemSize.u32RxFifo1 != 0)
675         CANFD_InitRxFifo(psCanfd, 1, &psCanfdStr->sMRamStartAddr, &psCanfdStr->sElemSize, 0, eCANFD_BYTE64);
676 
677     /*Configures the Tx Event FIFO element */
678     if (psCanfdStr->sElemSize.u32TxEventFifo != 0)
679         CANFD_InitTxEvntFifo(psCanfd, &psCanfdStr->sMRamStartAddr, &psCanfdStr->sElemSize, 0);
680 
681     /*Reject all Non-matching Frames Extended ID and Frames Standard ID,Reject all remote frames with 11-bit standard IDs and 29-bit extended IDs */
682     CANFD_SetGFC(psCanfd, eCANFD_REJ_NON_MATCH_FRM, eCANFD_REJ_NON_MATCH_FRM, 1, 1);
683 
684     if (psCanfdStr->sBtConfig.bEnableLoopBack)
685     {
686         psCanfd->CCCR |= CANFD_CCCR_TEST_Msk;
687         psCanfd->TEST |= CANFD_TEST_LBCK_Msk;
688     }
689 }
690 
691 
692 /**
693  * @brief       Close the CAN FD Bus.
694  *
695  * @param[in]   psCanfd   The pointer to CANFD module base address.
696  *
697  * @return      None.
698  *
699  * @details     Disable the CAN FD clock and Interrupt.
700  */
CANFD_Close(CANFD_T * psCanfd)701 void CANFD_Close(CANFD_T *psCanfd)
702 {
703     if (psCanfd == (CANFD_T *)CANFD0)
704     {
705         CLK_DisableModuleClock(CANFD0_MODULE);
706     }
707     else if (psCanfd == (CANFD_T *)CANFD1)
708     {
709         CLK_DisableModuleClock(CANFD1_MODULE);
710     }
711     else if (psCanfd == (CANFD_T *)CANFD2)
712     {
713         CLK_DisableModuleClock(CANFD2_MODULE);
714     }
715     else if (psCanfd == (CANFD_T *)CANFD3)
716     {
717         CLK_DisableModuleClock(CANFD3_MODULE);
718     }
719 }
720 
721 
722 /**
723  * @brief       Get the element's address when read transmit buffer.
724  *
725  * @param[in]   psCanfd      The pointer of the specified CAN FD module.
726  * @param[in]   u32Idx       The number of the transmit buffer element
727  *
728  * @return      Address of the element in transmit buffer.
729  *
730  * @details     The function is used to get the element's address when read transmit buffer.
731  */
CANFD_GetTxBufferElementAddress(CANFD_T * psCanfd,uint32_t u32Idx)732 static uint32_t CANFD_GetTxBufferElementAddress(CANFD_T *psCanfd, uint32_t u32Idx)
733 {
734     uint32_t u32Size = 0;
735     u32Size = (CANFD_ReadReg(&psCanfd->TXESC) & CANFD_TXESC_TBDS_Msk) >> CANFD_TXESC_TBDS_Pos;
736 
737     if (u32Size < 5U)
738     {
739         u32Size += 4U;
740     }
741     else
742     {
743         u32Size = u32Size * 4U - 10U;
744     }
745 
746     return (CANFD_ReadReg(&psCanfd->TXBC) & CANFD_TXBC_TBSA_Msk) + u32Idx * u32Size * 4U;
747 }
748 
749 
750 /**
751  * @brief       Enables CAN FD interrupts according to provided mask .
752  *
753  * @param[in]   psCanfd          The pointer of the specified CAN FD module.
754  * @param[in]   u32IntLine0      The Interrupt Line 0 type select.
755  * @param[in]   u32IntLine1      The Interrupt Line 1 type select.
756  *                              - \ref CANFD_IE_ARAE_Msk     : Access to Reserved Address Interrupt
757  *                              - \ref CANFD_IE_PEDE_Msk     : Protocol Error in Data Phase Interrupt
758  *                              - \ref CANFD_IE_PEAE_Msk     : Protocol Error in Arbitration Phase Interrupt
759  *                              - \ref CANFD_IE_WDIE_Msk     : Watchdog Interrupt
760  *                              - \ref CANFD_IE_BOE_Msk      : Bus_Off Status Interrupt
761  *                              - \ref CANFD_IE_EWE_Msk      : Warning Status Interrupt
762  *                              - \ref CANFD_IE_EPE_Msk      : Error Passive Interrupt
763  *                              - \ref CANFD_IE_ELOE_Msk     : Error Logging Overflow Interrupt
764  *                              - \ref CANFD_IE_BEUE_Msk     : Bit Error Uncorrected Interrupt
765  *                              - \ref CANFD_IE_BECE_Msk     : Bit Error Corrected Interrupt
766  *                              - \ref CANFD_IE_DRXE_Msk     : Message stored to Dedicated Rx Buffer Interrupt
767  *                              - \ref CANFD_IE_TOOE_Msk     : Timeout Occurred Interrupt
768  *                              - \ref CANFD_IE_MRAFE_Msk    : Message RAM Access Failure Interrupt
769  *                              - \ref CANFD_IE_TSWE_Msk     : Timestamp Wraparound Interrupt
770  *                              - \ref CANFD_IE_TEFLE_Msk    : Tx Event FIFO Event Lost Interrupt
771  *                              - \ref CANFD_IE_TEFFE_Msk    : Tx Event FIFO Full Interrupt
772  *                              - \ref CANFD_IE_TEFWE_Msk    : Tx Event FIFO Watermark Reached Interrupt
773  *                              - \ref CANFD_IE_TEFNE_Msk    : Tx Event FIFO New Entry Interrupt
774  *                              - \ref CANFD_IE_TFEE_Msk     : Tx FIFO Empty Interrupt
775  *                              - \ref CANFD_IE_TCFE_Msk     : Transmission Cancellation Finished Interrupt
776  *                              - \ref CANFD_IE_TCE_Msk      : Transmission Completed Interrupt
777  *                              - \ref CANFD_IE_HPME_Msk     : High Priority Message Interrupt
778  *                              - \ref CANFD_IE_RF1LE_Msk    : Rx FIFO 1 Message Lost Interrupt
779  *                              - \ref CANFD_IE_RF1FE_Msk    : Rx FIFO 1 Full Interrupt
780  *                              - \ref CANFD_IE_RF1WE_Msk    : Rx FIFO 1 Watermark Reached Interrupt
781  *                              - \ref CANFD_IE_RF1NE_Msk    : Rx FIFO 1 New Message Interrupt
782  *                              - \ref CANFD_IE_RF0LE_Msk    : Rx FIFO 0 Message Lost Interrupt
783  *                              - \ref CANFD_IE_RF0FE_Msk    : Rx FIFO 0 Full Interrupt
784  *                              - \ref CANFD_IE_RF0WE_Msk    : Rx FIFO 0 Watermark Reached Interrupt
785  *                              - \ref CANFD_IE_RF0NE_Msk    : Rx FIFO 0 New Message Interrupt
786  *
787  * @param[in]   u32TXBTIE        Enable Tx Buffer Transmission 0-31 Interrupt.
788  * @param[in]   u32TXBCIE        Enable Tx Buffer Cancellation Finished 0-31 Interrupt.
789  * @return      None.
790  *
791  * @details     This macro enable specified CAN FD interrupt.
792  */
CANFD_EnableInt(CANFD_T * psCanfd,uint32_t u32IntLine0,uint32_t u32IntLine1,uint32_t u32TXBTIE,uint32_t u32TXBCIE)793 void CANFD_EnableInt(CANFD_T *psCanfd, uint32_t u32IntLine0, uint32_t u32IntLine1, uint32_t u32TXBTIE, uint32_t u32TXBCIE)
794 {
795 
796     if (u32IntLine0 != 0)
797     {
798         /*Setting the CANFD0_IRQ0 Interrupt*/
799         psCanfd->IE = CANFD_ReadReg(&psCanfd->IE) | u32IntLine0;
800         /* Enable CAN FD specified interrupt */
801         psCanfd->ILE = CANFD_ReadReg(&psCanfd->ILE) | CANFD_ILE_ENT0_Msk;
802     }
803 
804     if (u32IntLine1 != 0)
805     {
806         /*Setting the CANFD0_IRQ1 Interrupt*/
807         psCanfd->ILS = CANFD_ReadReg(&psCanfd->ILS) | u32IntLine1;
808         /* Enable CAN FD specified interrupt */
809         psCanfd->ILE = CANFD_ReadReg(&psCanfd->ILE) | CANFD_ILE_ENT1_Msk;
810     }
811 
812     /*Setting the Tx Buffer Transmission Interrupt Enable*/
813     psCanfd->TXBTIE = CANFD_ReadReg(&psCanfd->TXBTIE) | u32TXBTIE;
814 
815     /*Tx Buffer Cancellation Finished Interrupt Enable*/
816     psCanfd->TXBCIE = CANFD_ReadReg(&psCanfd->TXBCIE) | u32TXBCIE;
817 }
818 
819 
820 /**
821  * @brief       Disables CAN FD interrupts according to provided mask .
822  *
823  * @param[in]   psCanfd          The pointer of the specified CAN FD module.
824  * @param[in]   u32IntLine0      The Interrupt Line 0 type select.
825  * @param[in]   u32IntLine1      The Interrupt Line 1 type select.
826  *                              - \ref CANFD_IE_ARAE_Msk     : Access to Reserved Address Interrupt
827  *                              - \ref CANFD_IE_PEDE_Msk     : Protocol Error in Data Phase Interrupt
828  *                              - \ref CANFD_IE_PEAE_Msk     : Protocol Error in Arbitration Phase Interrupt
829  *                              - \ref CANFD_IE_WDIE_Msk     : Watchdog Interrupt
830  *                              - \ref CANFD_IE_BOE_Msk      : Bus_Off Status Interrupt
831  *                              - \ref CANFD_IE_EWE_Msk      : Warning Status Interrupt
832  *                              - \ref CANFD_IE_EPE_Msk      : Error Passive Interrupt
833  *                              - \ref CANFD_IE_ELOE_Msk     : Error Logging Overflow Interrupt
834  *                              - \ref CANFD_IE_BEUE_Msk     : Bit Error Uncorrected Interrupt
835  *                              - \ref CANFD_IE_BECE_Msk     : Bit Error Corrected Interrupt
836  *                              - \ref CANFD_IE_DRXE_Msk     : Message stored to Dedicated Rx Buffer Interrupt
837  *                              - \ref CANFD_IE_TOOE_Msk     : Timeout Occurred Interrupt
838  *                              - \ref CANFD_IE_MRAFE_Msk    : Message RAM Access Failure Interrupt
839  *                              - \ref CANFD_IE_TSWE_Msk     : Timestamp Wraparound Interrupt
840  *                              - \ref CANFD_IE_TEFLE_Msk    : Tx Event FIFO Event Lost Interrupt
841  *                              - \ref CANFD_IE_TEFFE_Msk    : Tx Event FIFO Full Interrupt
842  *                              - \ref CANFD_IE_TEFWE_Msk    : Tx Event FIFO Watermark Reached Interrupt
843  *                              - \ref CANFD_IE_TEFNE_Msk    : Tx Event FIFO New Entry Interrupt
844  *                              - \ref CANFD_IE_TFEE_Msk     : Tx FIFO Empty Interrupt
845  *                              - \ref CANFD_IE_TCFE_Msk     : Transmission Cancellation Finished Interrupt
846  *                              - \ref CANFD_IE_TCE_Msk      : Transmission Completed Interrupt
847  *                              - \ref CANFD_IE_HPME_Msk     : High Priority Message Interrupt
848  *                              - \ref CANFD_IE_RF1LE_Msk    : Rx FIFO 1 Message Lost Interrupt
849  *                              - \ref CANFD_IE_RF1FE_Msk    : Rx FIFO 1 Full Interrupt
850  *                              - \ref CANFD_IE_RF1WE_Msk    : Rx FIFO 1 Watermark Reached Interrupt
851  *                              - \ref CANFD_IE_RF1NE_Msk    : Rx FIFO 1 New Message Interrupt
852  *                              - \ref CANFD_IE_RF0LE_Msk    : Rx FIFO 0 Message Lost Interrupt
853  *                              - \ref CANFD_IE_RF0FE_Msk    : Rx FIFO 0 Full Interrupt
854  *                              - \ref CANFD_IE_RF0WE_Msk    : Rx FIFO 0 Watermark Reached Interrupt
855  *                              - \ref CANFD_IE_RF0NE_Msk    : Rx FIFO 0 New Message Interrupt
856  *
857  * @param[in]   u32TXBTIE        Disable Tx Buffer Transmission 0-31 Interrupt.
858  * @param[in]   u32TXBCIE        Disable Tx Buffer Cancellation Finished 0-31 Interrupt.
859  * @return      None.
860  *
861  * @details     This macro disable specified CAN FD interrupt.
862  */
CANFD_DisableInt(CANFD_T * psCanfd,uint32_t u32IntLine0,uint32_t u32IntLine1,uint32_t u32TXBTIE,uint32_t u32TXBCIE)863 void CANFD_DisableInt(CANFD_T *psCanfd, uint32_t u32IntLine0, uint32_t u32IntLine1, uint32_t u32TXBTIE, uint32_t u32TXBCIE)
864 {
865     if (u32IntLine0 != 0)
866     {
867         /*Clear the CANFD0_IRQ0 Interrupt*/
868         psCanfd->IE = CANFD_ReadReg(&psCanfd->IE) & ~u32IntLine0;
869         /* Disable CAN FD specified interrupt */
870         psCanfd->ILE = CANFD_ReadReg(&psCanfd->ILE) & ~CANFD_ILE_ENT0_Msk;
871     }
872 
873     if (u32IntLine1 != 0)
874     {
875         /*Clear the CANFD0_IRQ1 Interrupt*/
876         psCanfd->ILS = CANFD_ReadReg(&psCanfd->ILS) & ~u32IntLine1;
877         /* Disable CAN FD specified interrupt */
878         psCanfd->ILE = CANFD_ReadReg(&psCanfd->ILE) & ~CANFD_ILE_ENT1_Msk;
879     }
880 
881     /*Setting the Tx Buffer Transmission Interrupt Disable*/
882     psCanfd->TXBTIE = CANFD_ReadReg(&psCanfd->TXBTIE) & ~u32TXBTIE;
883 
884     /*Tx Buffer Cancellation Finished Interrupt Disable*/
885     psCanfd->TXBCIE = CANFD_ReadReg(&psCanfd->TXBCIE) & ~u32TXBCIE;
886 }
887 
888 
889 /**
890  * @brief       Copy Tx Message to  TX buffer and Request transmission.
891  *
892  * @param[in]   psCanfd         The pointer to CAN FD module base address.
893  * @param[in]   u32TxBufIdx     The Message Buffer index.
894  * @param[in]   psTxMsg         Message to be copied.
895  *
896  * @return      number of tx requests set: 0= Tx Message Buffer is currently in use.
897  *                                         1= Write Tx Message Buffer Successfully.
898  *
899  * @details     Copy Tx Message to FIFO/Queue TX buffer and Request transmission.
900  */
CANFD_TransmitTxMsg(CANFD_T * psCanfd,uint32_t u32TxBufIdx,CANFD_FD_MSG_T * psTxMsg)901 uint32_t CANFD_TransmitTxMsg(CANFD_T *psCanfd, uint32_t u32TxBufIdx, CANFD_FD_MSG_T *psTxMsg)
902 {
903     uint32_t u32Success = 0;
904     uint32_t u32TimeOutCnt = CANFD_TIMEOUT;
905 
906     /* write the message to the message buffer */
907     u32Success = CANFD_TransmitDMsg(psCanfd, u32TxBufIdx, psTxMsg);
908 
909     if (u32Success == 1)
910     {
911         /* wait for completion */
912         while (!(psCanfd->TXBRP & (1UL << u32TxBufIdx)))
913         {
914             if (--u32TimeOutCnt == 0)
915             {
916                 u32Success = 0;
917                 break;
918             }
919 
920         }
921     }
922 
923     return u32Success;
924 }
925 
926 
927 /**
928  * @brief       Writes a Tx Message to Transmit Message Buffer.
929  *
930  * @param[in]   psCanfd        The pointer of the specified CAN FD module.
931  * @param[in]   u32TxBufIdx    The Message Buffer index.
932  * @param[in]   psTxMsg        Pointer to CAN FD message frame to be sent.
933  *
934  * @return      1  Write Tx Message Buffer Successfully.
935  *              0  Tx Message Buffer is currently in use.
936  *
937  * @details     This function writes a CANFD Message to the specified Transmit Message Buffer
938  *              and changes the Message Buffer state to start CANFD Message transmit. After
939  *              that the function returns immediately.
940  */
CANFD_TransmitDMsg(CANFD_T * psCanfd,uint32_t u32TxBufIdx,CANFD_FD_MSG_T * psTxMsg)941 uint32_t CANFD_TransmitDMsg(CANFD_T *psCanfd, uint32_t u32TxBufIdx, CANFD_FD_MSG_T *psTxMsg)
942 {
943     CANFD_BUF_T *psTxBuffer;
944     uint32_t u32Idx = 0, u32Success = 1;
945     uint32_t u32TimeOutCnt = CANFD_TIMEOUT;
946 
947     if (u32TxBufIdx >= CANFD_MAX_TX_BUF_ELEMS) return 0;
948 
949     /* transmission is pending in this message buffer */
950     if (CANFD_ReadReg(&(psCanfd->TXBRP)) & (1UL << u32TxBufIdx)) return 0;
951 
952     /*Get the TX Buffer Start Address in the RAM*/
953     psTxBuffer = (CANFD_BUF_T *)(CANFD_SRAM_BASE_ADDR(psCanfd) + (CANFD_ReadReg(&psCanfd->TXBC) & 0xFFFF) + (u32TxBufIdx * sizeof(CANFD_BUF_T)));
954 
955     if (psTxMsg->eIdType == eCANFD_XID)
956     {
957         psTxBuffer->u32Id = TX_BUFFER_T0_ELEM_XTD_Msk | (psTxMsg->u32Id & 0x1FFFFFFF);
958     }
959     else
960     {
961         psTxBuffer->u32Id = (psTxMsg->u32Id & 0x7FF) << 18;
962     }
963 
964     if (psTxMsg->eFrmType == eCANFD_REMOTE_FRM) psTxBuffer->u32Id |= TX_BUFFER_T0_ELEM_RTR_Msk;
965 
966     psTxBuffer->u32Config = (CANFD_EncodeDLC(psTxMsg->u32DLC) << 16);
967 
968     if (psTxMsg->bFDFormat) psTxBuffer->u32Config |= TX_BUFFER_T1_ELEM_FDF_Msk;
969 
970     if (psTxMsg->bBitRateSwitch) psTxBuffer->u32Config |= TX_BUFFER_T1_ELEM_BSR_Msk;
971 
972 
973     for (u32Idx = 0; u32Idx < (psTxMsg->u32DLC + (4 - 1)) / 4; u32Idx++)
974     {
975         psTxBuffer->au32Data[u32Idx] = psTxMsg->au32Data[u32Idx];
976     }
977 
978     while (CANFD_GET_COMMUNICATION_STATE(psCanfd) != eCANFD_IDLE)
979     {
980         if (--u32TimeOutCnt == 0) return 0;
981     }
982 
983     psCanfd->TXBAR = (1 << u32TxBufIdx);
984 
985     return u32Success;
986 }
987 
988 
989 /**
990  * @brief       Global Filter Configuration (GFC).
991  *
992  * @param[in]   psCanfd          The pointer to CAN FD module base address.
993  * @param[in]   eNMStdFrm        Accept/Reject Non-Matching Standard(11-bits) Frames.
994  * @param[in]   eEMExtFrm        Accept/Reject Non-Matching Extended(29-bits) Frames.
995  * @param[in]   u32RejRmtStdFrm  Reject/Filter Remote Standard Frames.
996  * @param[in]   u32RejRmtExtFrm  Reject/Filter Remote Extended Frames.
997  *
998  * @return      None.
999  *
1000  * @details     Global Filter Configuration.
1001  */
CANFD_SetGFC(CANFD_T * psCanfd,E_CANFD_ACC_NON_MATCH_FRM eNMStdFrm,E_CANFD_ACC_NON_MATCH_FRM eEMExtFrm,uint32_t u32RejRmtStdFrm,uint32_t u32RejRmtExtFrm)1002 void CANFD_SetGFC(CANFD_T *psCanfd, E_CANFD_ACC_NON_MATCH_FRM eNMStdFrm, E_CANFD_ACC_NON_MATCH_FRM eEMExtFrm, uint32_t u32RejRmtStdFrm, uint32_t u32RejRmtExtFrm)
1003 {
1004     psCanfd->GFC &= (CANFD_GFC_RRFS_Msk | CANFD_GFC_RRFE_Msk);
1005     psCanfd->GFC = (eNMStdFrm << CANFD_GFC_ANFS_Pos) | (eEMExtFrm << CANFD_GFC_ANFE_Pos)
1006                    | (u32RejRmtStdFrm << CANFD_GFC_RRFS_Pos) | (u32RejRmtExtFrm << CANFD_GFC_RRFE_Pos);
1007 }
1008 
1009 
1010 /**
1011  * @brief       Rx FIFO Configuration for RX_FIFO_0 and RX_FIFO_1.
1012  *
1013  * @param[in]   psCanfd          The pointer to CAN FD module base address.
1014  * @param[in]   u32RxFifoNum     0: RX FIFO_0, 1: RX_FIFO_1.
1015  * @param[in]   psRamConfig      Rx FIFO Size in number of configuration ram address.
1016  * @param[in]   psElemSize       Rx FIFO Size in number of Rx FIFO elements (element number (max. = 64)).
1017  * @param[in]   u32FifoWM        Watermark in number of Rx FIFO elements
1018  * @param[in]   eFifoSize        Maximum data field size that should be stored in this Rx FIFO
1019  *                               (configure BYTE64 if you are unsure, as this is the largest data field allowed in CAN FD)
1020  *
1021  * @return      None.
1022  *
1023  * @details     Rx FIFO Configuration for RX_FIFO_0 and RX_FIFO_1.
1024  */
CANFD_InitRxFifo(CANFD_T * psCanfd,uint32_t u32RxFifoNum,CANFD_RAM_PART_T * psRamConfig,CANFD_ELEM_SIZE_T * psElemSize,uint32_t u32FifoWM,E_CANFD_DATA_FIELD_SIZE eFifoSize)1025 static void CANFD_InitRxFifo(CANFD_T *psCanfd, uint32_t u32RxFifoNum, CANFD_RAM_PART_T *psRamConfig, CANFD_ELEM_SIZE_T *psElemSize, uint32_t u32FifoWM, E_CANFD_DATA_FIELD_SIZE eFifoSize)
1026 {
1027     uint32_t u32Address;
1028     uint32_t u32Size;
1029 
1030     /* ignore if index is too high */
1031     if (u32RxFifoNum > CANFD_NUM_RX_FIFOS)return;
1032 
1033     /* ignore if index is too high */
1034     if (psElemSize-> u32RxFifo0 > CANFD_MAX_RX_FIFO0_ELEMS) return;
1035 
1036     /* ignore if index is too high */
1037     if (psElemSize-> u32RxFifo1 > CANFD_MAX_RX_FIFO1_ELEMS) return;
1038 
1039     switch (u32RxFifoNum)
1040     {
1041     case 0:
1042         if (psElemSize-> u32RxFifo0)
1043         {
1044             /* set size of Rx FIFO 0, set offset, blocking mode */
1045             psCanfd->RXF0C = (psRamConfig->u32RXF0C_F0SA) | (psElemSize->u32RxFifo0 << CANFD_RXF0C_F0S_Pos)
1046                              | (u32FifoWM << CANFD_RXF0C_F0WM_Pos);
1047             psCanfd->RXESC = (psCanfd->RXESC & (~CANFD_RXESC_F0DS_Msk)) | (eFifoSize << CANFD_RXESC_F0DS_Pos);
1048 
1049             /*Get the RX FIFO 0 Start Address in the RAM*/
1050             u32Address = CANFD_SRAM_BASE_ADDR(psCanfd) + (psRamConfig->u32RXF0C_F0SA & CANFD_RXF0C_F0SA_Msk);
1051             u32Size = eFifoSize;
1052 
1053             if (u32Size < 5U)
1054             {
1055                 u32Size += 4U;
1056             }
1057             else
1058             {
1059                 u32Size = u32Size * 4U - 10U;
1060             }
1061 
1062             /*Clear the RX FIFO 0 Memory*/
1063             memset((uint32_t *)(u32Address), 0x00, (u32Size * 4 * psElemSize->u32RxFifo0));
1064         }
1065         else
1066         {
1067             psCanfd->RXF0C = 0;
1068         }
1069 
1070         break;
1071 
1072     case 1:
1073         if (psElemSize-> u32RxFifo1)
1074         {
1075             /* set size of Rx FIFO 1, set offset, blocking mode */
1076             psCanfd->RXF1C = (psRamConfig->u32RXF1C_F1SA) | (psElemSize->u32RxFifo1 << CANFD_RXF1C_F1S_Pos)
1077                              | (u32FifoWM << CANFD_RXF1C_F1WM_Pos);
1078             psCanfd->RXESC = (psCanfd->RXESC & (~CANFD_RXESC_F1DS_Msk)) | (eFifoSize << CANFD_RXESC_F1DS_Pos);
1079 
1080             /*Get the RX FIFO 1 Start Address in the RAM*/
1081             u32Address = CANFD_SRAM_BASE_ADDR(psCanfd) + (psRamConfig->u32RXF1C_F1SA & CANFD_RXF1C_F1SA_Msk);
1082 
1083             u32Size = eFifoSize;
1084 
1085             if (u32Size < 5U)
1086             {
1087                 u32Size += 4U;
1088             }
1089             else
1090             {
1091                 u32Size = u32Size * 4U - 10U;
1092             }
1093 
1094             /*Clear the RX FIFO 0 Memory*/
1095             memset((uint32_t *)(u32Address), 0x00, (u32Size * 4 * psElemSize->u32RxFifo1));
1096         }
1097         else
1098         {
1099             psCanfd->RXF1C = 0;
1100         }
1101 
1102         break;
1103     }
1104 }
1105 
1106 
1107 /**
1108  * @brief       Function configures the data structures used by a dedicated Rx Buffer.
1109  *
1110  * @param[in]   psCanfd          The pointer to CAN FD module base address.
1111  * @param[in]   psRamConfig      Tx buffer configuration ram address.
1112  * @param[in]   psElemSize       Tx buffer configuration element size.
1113  * @param[in]   eTxBufSize       Maximum data field size that should be stored in a dedicated Tx Buffer
1114  *                              (configure BYTE64 if you are unsure, as this is the largest data field allowed in CAN FD)largest data field allowed in CAN FD)
1115  *
1116  * @return      None.
1117  *
1118  * @details     Function configures the data structures used by a dedicated Rx Buffer.
1119  */
CANFD_InitTxDBuf(CANFD_T * psCanfd,CANFD_RAM_PART_T * psRamConfig,CANFD_ELEM_SIZE_T * psElemSize,E_CANFD_DATA_FIELD_SIZE eTxBufSize)1120 static void CANFD_InitTxDBuf(CANFD_T *psCanfd, CANFD_RAM_PART_T *psRamConfig, CANFD_ELEM_SIZE_T *psElemSize, E_CANFD_DATA_FIELD_SIZE eTxBufSize)
1121 {
1122     uint32_t u32Address;
1123     uint32_t u32Size;
1124 
1125     /*Setting the Tx Buffer Start Address*/
1126     psCanfd->TXBC = ((psElemSize->u32TxBuf & 0x3F) << CANFD_TXBC_NDTB_Pos) | (psRamConfig->u32TXBC_TBSA & CANFD_TXBC_TBSA_Msk);
1127 
1128     /*Get the TX Buffer Start Address in the RAM*/
1129     u32Address = CANFD_SRAM_BASE_ADDR(psCanfd) + (psRamConfig->u32TXBC_TBSA & CANFD_TXBC_TBSA_Msk);
1130 
1131     /*Setting the Tx Buffer Data Field Size*/
1132     psCanfd->TXESC = (psCanfd->TXESC & (~CANFD_TXESC_TBDS_Msk)) | (eTxBufSize <<  CANFD_TXESC_TBDS_Pos);
1133 
1134     /*Get the Buffer Data Field Size*/
1135     u32Size = eTxBufSize;
1136 
1137     if (u32Size < 5U)
1138     {
1139         u32Size += 4U;
1140     }
1141     else
1142     {
1143         u32Size = u32Size * 4U - 10U;
1144     }
1145 
1146     /*Clear the TX Buffer Memory*/
1147     memset((uint32_t *)(u32Address), 0x00, (u32Size * 4 * psElemSize->u32TxBuf));
1148 }
1149 
1150 
1151 /**
1152  * @brief       Function configures the data structures used by a dedicated Rx Buffer.
1153  *
1154  * @param[in]   psCanfd          The pointer to CAN FD module base address.
1155  * @param[in]   psRamConfig      Rx buffer configuration ram address.
1156  * @param[in]   psElemSize       Rx buffer configuration element size.
1157  * @param[in]   eRxBufSize       Maximum data field size that should be stored in a dedicated Rx Buffer
1158  *                              (configure BYTE64 if you are unsure, as this is the largest data field allowed in CAN FD)largest data field allowed in CAN FD)
1159  *
1160  * @return      None.
1161  *
1162  * @details     Function configures the data structures used by a dedicated Rx Buffer.
1163  */
CANFD_InitRxDBuf(CANFD_T * psCanfd,CANFD_RAM_PART_T * psRamConfig,CANFD_ELEM_SIZE_T * psElemSize,E_CANFD_DATA_FIELD_SIZE eRxBufSize)1164 static void CANFD_InitRxDBuf(CANFD_T *psCanfd, CANFD_RAM_PART_T *psRamConfig, CANFD_ELEM_SIZE_T *psElemSize, E_CANFD_DATA_FIELD_SIZE eRxBufSize)
1165 {
1166     uint32_t u32Address;
1167     uint32_t u32Size;
1168 
1169     /*Setting the Rx Buffer Start Address*/
1170     psCanfd->RXBC = (psRamConfig->u32RXBC_RBSA & CANFD_RXBC_RBSA_Msk);
1171 
1172     /*Get the RX Buffer Start Address in the RAM*/
1173     u32Address = CANFD_SRAM_BASE_ADDR(psCanfd) + (psRamConfig->u32RXBC_RBSA & CANFD_RXBC_RBSA_Msk);
1174 
1175     /*Setting the Rx Buffer Data Field Size*/
1176     psCanfd->RXESC = (psCanfd->RXESC & (~CANFD_RXESC_RBDS_Msk)) | (eRxBufSize <<  CANFD_RXESC_RBDS_Pos);
1177     /*Get the Buffer Data Field Size*/
1178     u32Size = eRxBufSize;
1179 
1180     if (u32Size < 5U)
1181     {
1182         u32Size += 4U;
1183     }
1184     else
1185     {
1186         u32Size = u32Size * 4U - 10U;
1187     }
1188 
1189     /*Clear the RX Buffer Memory*/
1190     memset((uint32_t *)(u32Address), 0x00, (u32Size * 4 * psElemSize->u32RxBuf));
1191 }
1192 
1193 
1194 /**
1195  * @brief       Configures the register SIDFC for the 11-bit Standard Message ID Filter elements.
1196  *
1197  * @param[in]   psCanfd           The pointer to CAN FD module base address.
1198  * @param[in]   psRamConfig       Standard ID filter configuration ram address
1199  * @param[in]   psElemSize        Standard ID filter configuration element size
1200  *
1201  * @return      None.
1202  *
1203  * @details     Function configures the data structures used by a dedicated Rx Buffer.
1204  */
CANFD_ConfigSIDFC(CANFD_T * psCanfd,CANFD_RAM_PART_T * psRamConfig,CANFD_ELEM_SIZE_T * psElemSize)1205 static void CANFD_ConfigSIDFC(CANFD_T *psCanfd, CANFD_RAM_PART_T *psRamConfig, CANFD_ELEM_SIZE_T *psElemSize)
1206 {
1207     uint32_t u32Address;
1208 
1209     /*Setting the Filter List Standard Start Address and List Size  */
1210     psCanfd->SIDFC = ((psElemSize->u32SIDFC & 0xFF) << CANFD_SIDFC_LSS_Pos) | (psRamConfig->u32SIDFC_FLSSA & CANFD_SIDFC_FLSSA_Msk);
1211 
1212     /*Get the Filter List Standard Start Address in the RAM*/
1213     u32Address = CANFD_SRAM_BASE_ADDR(psCanfd) + (psRamConfig->u32SIDFC_FLSSA & CANFD_SIDFC_FLSSA_Msk);
1214 
1215     /*Clear the Filter List Memory*/
1216     memset((uint32_t *)(u32Address), 0x00, (psElemSize->u32SIDFC * sizeof(CANFD_STD_FILTER_T)));
1217 }
1218 
1219 
1220 /**
1221  * @brief       Configures the register XIDFC for the 29-bit Extended Message ID Filter elements.
1222  *
1223  * @param[in]   psCanfd           The pointer to CAN FD module base address.
1224  * @param[in]   psRamConfig       Extended ID filter configuration ram address
1225  * @param[in]   psElemSize        Extended ID filter configuration element size
1226  *
1227  * @return      None.
1228  *
1229  * @details     Configures the register XIDFC for the 29-bit Extended Message ID Filter elements.
1230  */
CANFD_ConfigXIDFC(CANFD_T * psCanfd,CANFD_RAM_PART_T * psRamConfig,CANFD_ELEM_SIZE_T * psElemSize)1231 static void CANFD_ConfigXIDFC(CANFD_T *psCanfd, CANFD_RAM_PART_T *psRamConfig, CANFD_ELEM_SIZE_T *psElemSize)
1232 {
1233     uint32_t u32Address;
1234 
1235     /*Setting the Filter List Extended Start Address and List Size  */
1236     psCanfd->XIDFC = ((psElemSize->u32XIDFC & 0xFF) << CANFD_XIDFC_LSE_Pos) | (psRamConfig->u32XIDFC_FLESA & CANFD_XIDFC_FLESA_Msk);
1237 
1238     /*Get the Filter List Standard Start Address in the RAM*/
1239     u32Address = CANFD_SRAM_BASE_ADDR(psCanfd) + (psRamConfig->u32XIDFC_FLESA & CANFD_XIDFC_FLESA_Msk);
1240 
1241     /*Clear the Filter List Memory*/
1242     memset((uint32_t *)(u32Address), 0x00, (psElemSize->u32XIDFC * sizeof(CANFD_EXT_FILTER_T)));
1243 }
1244 
1245 
1246 /**
1247  * @brief       Writes a 11-bit Standard ID filter element in the Message RAM.
1248  *
1249  * @param[in]   psCanfd          The pointer to CAN FD module base address.
1250  * @param[in]   u32FltrIdx       Index at which the filter element should be written in the '11-bit Filter' section of Message RAM
1251  * @param[in]   u32Filter        Rx Individual filter value.
1252  *
1253  * @return      None.
1254  *
1255  * @details     Writes a 11-bit Standard ID filter element in the Message RAM.
1256  */
CANFD_SetSIDFltr(CANFD_T * psCanfd,uint32_t u32FltrIdx,uint32_t u32Filter)1257 void CANFD_SetSIDFltr(CANFD_T *psCanfd, uint32_t u32FltrIdx, uint32_t u32Filter)
1258 {
1259     CANFD_STD_FILTER_T *psFilter;
1260 
1261     /* ignore if index is too high */
1262     if (u32FltrIdx >= CANFD_MAX_11_BIT_FTR_ELEMS) return;
1263 
1264     /*Get the Filter List Configuration Address in the RAM*/
1265     psFilter = (CANFD_STD_FILTER_T *)(CANFD_SRAM_BASE_ADDR(psCanfd) + (psCanfd->SIDFC & CANFD_SIDFC_FLSSA_Msk) + (u32FltrIdx * sizeof(CANFD_STD_FILTER_T)));
1266 
1267     /*Wirted the Standard ID filter element to RAM */
1268     psFilter->VALUE = u32Filter;
1269 }
1270 
1271 
1272 /**
1273  * @brief       Writes a 29-bit extended id filter element in the Message RAM.
1274  *              Size of an Extended Id filter element is 2 words. So 2 words are written into the Message RAM for each filter element
1275  *
1276  * @param[in]   psCanfd         The pointer to CAN FD module base address.
1277  * @param[in]   u32FltrIdx      Index at which the filter element should be written in the '29-bit Filter' section of Message RAM.
1278  * @param[in]   u32FilterLow    Rx Individual filter low value.
1279  * @param[in]   u32FilterHigh   Rx Individual filter high value.
1280  *
1281  * @return      None.
1282  *
1283  * @details     Writes a 29-bit extended id filter element in the Message RAM.
1284  */
CANFD_SetXIDFltr(CANFD_T * psCanfd,uint32_t u32FltrIdx,uint32_t u32FilterLow,uint32_t u32FilterHigh)1285 void CANFD_SetXIDFltr(CANFD_T *psCanfd, uint32_t u32FltrIdx, uint32_t u32FilterLow, uint32_t u32FilterHigh)
1286 {
1287     CANFD_EXT_FILTER_T *psFilter;
1288 
1289     /* ignore if index is too high */
1290     if (u32FltrIdx >= CANFD_MAX_29_BIT_FTR_ELEMS) return;
1291 
1292     /*Get the Filter List Configuration Address on RAM*/
1293     psFilter = (CANFD_EXT_FILTER_T *)(CANFD_SRAM_BASE_ADDR(psCanfd) + (psCanfd->XIDFC & CANFD_XIDFC_FLESA_Msk) + (u32FltrIdx * sizeof(CANFD_EXT_FILTER_T)));
1294 
1295     /*Wirted the Extended ID filter element to RAM */
1296     psFilter->LOWVALUE = u32FilterLow;
1297     psFilter->HIGHVALUE = u32FilterHigh;
1298 }
1299 
1300 
1301 /**
1302  * @brief       Reads a CAN FD Message from Receive Message Buffer.
1303  *
1304  * @param[in]   psCanfd     The pointer of the specified CAN FD module.
1305  * @param[in]   u8MbIdx     The CANFD Message Buffer index.
1306  * @param[in]   psMsgBuf    Pointer to CAN FD message frame structure for reception.
1307  *
1308  * @return       1:Rx Message Buffer is full and has been read successfully.
1309  *               0:Rx Message Buffer is empty.
1310  *
1311  * @details     This function reads a CAN message from a specified Receive Message Buffer.
1312  *              The function fills a receive CAN message frame structure with just received data
1313  *              and activates the Message Buffer again.The function returns immediately.
1314 */
CANFD_ReadRxBufMsg(CANFD_T * psCanfd,uint8_t u8MbIdx,CANFD_FD_MSG_T * psMsgBuf)1315 uint32_t CANFD_ReadRxBufMsg(CANFD_T *psCanfd, uint8_t u8MbIdx, CANFD_FD_MSG_T *psMsgBuf)
1316 {
1317     CANFD_BUF_T *psRxBuffer;
1318     uint32_t u32Success = 0;
1319     uint32_t newData = 0;
1320 
1321     if (u8MbIdx < CANFD_MAX_RX_BUF_ELEMS)
1322     {
1323         if (u8MbIdx < 32)
1324             newData = (CANFD_ReadReg(&psCanfd->NDAT1) >> u8MbIdx) & 1;
1325         else
1326             newData = (CANFD_ReadReg(&psCanfd->NDAT2) >> (u8MbIdx - 32)) & 1;
1327 
1328         /* new message is waiting to be read */
1329         if (newData)
1330         {
1331             /* get memory location of rx buffer */
1332             psRxBuffer = (CANFD_BUF_T *)(CANFD_SRAM_BASE_ADDR(psCanfd) + (CANFD_ReadReg(&psCanfd->RXBC) & 0xFFFF) + (u8MbIdx * sizeof(CANFD_BUF_T)));
1333 
1334             /* read the message */
1335             CANFD_CopyDBufToMsgBuf(psRxBuffer, psMsgBuf);
1336 
1337             /* clear 'new data' flag */
1338             if (u8MbIdx < 32)
1339                 psCanfd->NDAT1 = CANFD_ReadReg(&psCanfd->NDAT1) | (1UL << u8MbIdx);
1340             else
1341                 psCanfd->NDAT2 = CANFD_ReadReg(&psCanfd->NDAT2) | (1UL << (u8MbIdx - 32));
1342 
1343             u32Success = 1;
1344         }
1345     }
1346 
1347     return u32Success;
1348 }
1349 
1350 
1351 /**
1352  * @brief       Reads a CAN FD Message from Rx FIFO.
1353  *
1354  * @param[in]   psCanfd     The pointer of the specified CANFD module.
1355  * @param[in]   u8FifoIdx   Number of the FIFO, 0 or 1.
1356  * @param[in]   psMsgBuf    Pointer to CANFD message frame structure for reception.
1357  *
1358  * @return      1           Read Message from Rx FIFO successfully.
1359  *              2           Rx FIFO is already overflowed and has been read successfully
1360  *              0           Rx FIFO is not enabled.
1361  *
1362  * @details     This function reads a CAN message from the CANFD build-in Rx FIFO.
1363  */
CANFD_ReadRxFifoMsg(CANFD_T * psCanfd,uint8_t u8FifoIdx,CANFD_FD_MSG_T * psMsgBuf)1364 uint32_t CANFD_ReadRxFifoMsg(CANFD_T *psCanfd, uint8_t u8FifoIdx, CANFD_FD_MSG_T *psMsgBuf)
1365 {
1366     CANFD_BUF_T *pRxBuffer;
1367     uint8_t GetIndex;
1368     uint32_t u32Success = 0;
1369     __I  uint32_t *pRXFS;
1370     __IO uint32_t *pRXFC, *pRXFA;
1371     uint8_t msgLostBit;
1372 
1373     /* check for valid FIFO number */
1374     if (u8FifoIdx < CANFD_NUM_RX_FIFOS)
1375     {
1376         if (u8FifoIdx == 0)
1377         {
1378             pRXFS = &(psCanfd->RXF0S);
1379             pRXFC = &(psCanfd->RXF0C);
1380             pRXFA = &(psCanfd->RXF0A);
1381             msgLostBit = 3;
1382         }
1383         else
1384         {
1385             pRXFS = &(psCanfd->RXF1S);
1386             pRXFC = &(psCanfd->RXF1C);
1387             pRXFA = &(psCanfd->RXF1A);
1388             msgLostBit = 7;
1389         }
1390 
1391         /* if FIFO is not empty */
1392         if ((CANFD_ReadReg(pRXFS) & 0x7F) > 0)
1393         {
1394             GetIndex = (uint8_t)((CANFD_ReadReg(pRXFS) >> 8) & 0x3F);
1395             pRxBuffer = (CANFD_BUF_T *)(CANFD_SRAM_BASE_ADDR(psCanfd) + (CANFD_ReadReg(pRXFC) & 0xFFFF) + (GetIndex * sizeof(CANFD_BUF_T)));
1396 
1397             CANFD_CopyRxFifoToMsgBuf(pRxBuffer, psMsgBuf);
1398 
1399             /* we got the message */
1400             *pRXFA = GetIndex;
1401 
1402             /* check for overflow */
1403             if (CANFD_ReadReg(pRXFS) & CANFD_RXFS_RFL)
1404             {
1405                 /* clear overflow flag */
1406                 psCanfd->IR = (1UL << msgLostBit);
1407                 u32Success = 2;
1408             }
1409             else
1410             {
1411                 u32Success = 1;
1412             }
1413         }
1414     }
1415 
1416     return u32Success;
1417 }
1418 
1419 
1420 /**
1421  * @brief       Copies a message from a dedicated Rx buffer into a message buffer.
1422  *
1423  * @param[in]   psRxBuf         Buffer to read from.
1424  * @param[in]   psMsgBuf        Location to store read message.
1425  *
1426  * @return      None.
1427  *
1428  * @details     Copies a message from a dedicated Rx buffer into a message buffer.
1429  */
CANFD_CopyDBufToMsgBuf(CANFD_BUF_T * psRxBuf,CANFD_FD_MSG_T * psMsgBuf)1430 void CANFD_CopyDBufToMsgBuf(CANFD_BUF_T *psRxBuf, CANFD_FD_MSG_T *psMsgBuf)
1431 {
1432     uint32_t u32Idx;
1433 
1434     if (psRxBuf->u32Id & RX_BUFFER_AND_FIFO_R0_ELEM_ESI_Msk)
1435         psMsgBuf->bErrStaInd = TRUE;
1436     else
1437         psMsgBuf->bErrStaInd = FALSE;
1438 
1439     /* if 29-bit ID */
1440     if (psRxBuf->u32Id & RX_BUFFER_AND_FIFO_R0_ELEM_XTD_Msk)
1441     {
1442         psMsgBuf->u32Id = (psRxBuf->u32Id & RX_BUFFER_AND_FIFO_R0_ELEM_ID_Msk);
1443         psMsgBuf->eIdType = eCANFD_XID;
1444     }
1445     /* if 11-bit ID */
1446     else
1447     {
1448         psMsgBuf->u32Id = (psRxBuf->u32Id  >> 18) & 0x7FF;
1449         psMsgBuf->eIdType = eCANFD_SID;
1450     }
1451 
1452     if (psRxBuf->u32Id  & RX_BUFFER_AND_FIFO_R0_ELEM_RTR_Msk)
1453         psMsgBuf->eFrmType = eCANFD_REMOTE_FRM;
1454     else
1455         psMsgBuf->eFrmType = eCANFD_DATA_FRM;
1456 
1457 
1458     if (psRxBuf->u32Config &  RX_BUFFER_AND_FIFO_R1_ELEM_FDF_Msk)
1459         psMsgBuf->bFDFormat = TRUE;
1460     else
1461         psMsgBuf->bFDFormat = FALSE;
1462 
1463     if (psRxBuf->u32Config &  RX_BUFFER_AND_FIFO_R1_ELEM_BSR_Msk)
1464         psMsgBuf->bBitRateSwitch = TRUE;
1465     else
1466         psMsgBuf->bBitRateSwitch = FALSE;
1467 
1468     psMsgBuf->u32DLC = CANFD_DecodeDLC((psRxBuf->u32Config & RX_BUFFER_AND_FIFO_R1_ELEM_DLC_Msk) >> RX_BUFFER_AND_FIFO_R1_ELEM_DLC_Pos);
1469 
1470     for (u32Idx = 0 ; u32Idx < psMsgBuf->u32DLC ; u32Idx++)
1471     {
1472         psMsgBuf->au8Data[u32Idx] = psRxBuf->au8Data[u32Idx];
1473     }
1474 }
1475 
1476 
1477 /**
1478  * @brief       Get Rx FIFO water level.
1479  *
1480  * @param[in]   psCanfd         The pointer to CANFD module base address.
1481  * @param[in]   u32RxFifoNum    0: RX FIFO_0, 1: RX_FIFO_1
1482  *
1483  * @return      Rx FIFO water level.
1484  *
1485  * @details     Get Rx FIFO water level.
1486  */
CANFD_GetRxFifoWaterLvl(CANFD_T * psCanfd,uint32_t u32RxFifoNum)1487 uint32_t CANFD_GetRxFifoWaterLvl(CANFD_T *psCanfd, uint32_t u32RxFifoNum)
1488 {
1489     uint32_t u32WaterLevel = 0;
1490 
1491     if (u32RxFifoNum == 0)
1492         u32WaterLevel = ((CANFD_ReadReg(&psCanfd->RXF0C) & CANFD_RXF0C_F0WM_Msk) >> CANFD_RXF0C_F0WM_Pos);
1493     else
1494         u32WaterLevel = ((CANFD_ReadReg(&psCanfd->RXF1C) & CANFD_RXF1C_F1WM_Msk) >> CANFD_RXF1C_F1WM_Pos);
1495 
1496     return u32WaterLevel;
1497 }
1498 
1499 
1500 /**
1501  * @brief       Copies messages from FIFO into a message buffert.
1502  *
1503  * @param[in]   psRxBuf         Buffer to read from.
1504  * @param[in]   psMsgBuf        Location to store read message.
1505  *
1506  * @return      None.
1507  *
1508  * @details      Copies messages from FIFO into a message buffert.
1509  */
CANFD_CopyRxFifoToMsgBuf(CANFD_BUF_T * psRxBuf,CANFD_FD_MSG_T * psMsgBuf)1510 void CANFD_CopyRxFifoToMsgBuf(CANFD_BUF_T *psRxBuf, CANFD_FD_MSG_T *psMsgBuf)
1511 {
1512     /*Copies a message from a dedicated Rx FIFO into a message buffer*/
1513     CANFD_CopyDBufToMsgBuf(psRxBuf, psMsgBuf);
1514 }
1515 
1516 
1517 /**
1518  * @brief       Cancel a Tx buffer transmission request.
1519  *
1520  * @param[in]   psCanfd         The pointer to CANFD module base address.
1521  * @param[in]   u32TxBufIdx     Tx buffer index number
1522  *
1523  * @return      None.
1524  *
1525  * @details     Cancel a Tx buffer transmission request.
1526  */
CANFD_TxBufCancelReq(CANFD_T * psCanfd,uint32_t u32TxBufIdx)1527 void CANFD_TxBufCancelReq(CANFD_T *psCanfd, uint32_t u32TxBufIdx)
1528 {
1529     psCanfd->TXBCR = CANFD_ReadReg(&psCanfd->TXBCR) | (0x1ul << u32TxBufIdx);
1530 }
1531 
1532 
1533 /**
1534  * @brief       Checks if a Tx buffer cancellation request has been finished or not.
1535  *
1536  * @param[in]   psCanfd         The pointer to CAN FD module base address.
1537  * @param[in]   u32TxBufIdx     Tx buffer index number
1538  *
1539  * @return      0: cancellation finished.
1540  *              1: cancellation fail
1541  *
1542  * @details     Checks if a Tx buffer cancellation request has been finished or not.
1543  */
CANFD_IsTxBufCancelFin(CANFD_T * psCanfd,uint32_t u32TxBufIdx)1544 uint32_t CANFD_IsTxBufCancelFin(CANFD_T *psCanfd, uint32_t u32TxBufIdx)
1545 {
1546     /* wait for completion */
1547     return ((CANFD_ReadReg(&psCanfd->TXBCR) & (0x1ul << u32TxBufIdx)) >> u32TxBufIdx);
1548 }
1549 
1550 
1551 /**
1552  * @brief       Checks if a Tx buffer transmission has occurred or not.
1553  *
1554  * @param[in]   psCanfd         The pointer to CAN FD module base address.
1555  * @param[in]   u32TxBufIdx     Tx buffer index number
1556  *
1557  * @return     0: No transmission occurred.
1558  *             1: Transmission occurred
1559  *
1560  * @details     Checks if a Tx buffer transmission has occurred or not.
1561  */
CANFD_IsTxBufTransmitOccur(CANFD_T * psCanfd,uint32_t u32TxBufIdx)1562 uint32_t CANFD_IsTxBufTransmitOccur(CANFD_T *psCanfd, uint32_t u32TxBufIdx)
1563 {
1564     return ((CANFD_ReadReg(&psCanfd->TXBTO) & (0x1ul << u32TxBufIdx)) >> u32TxBufIdx);
1565 }
1566 
1567 
1568 /**
1569  * @brief       Init Tx event fifo
1570  *
1571  * @param[in]   psCanfd          The pointer to CAN FD module base address.
1572  * @param[in]   psRamConfig      Tx Event Fifo configuration ram address.
1573  * @param[in]   psElemSize       Tx Event Fifo configuration element size
1574  * @param[in]   u32FifoWaterLvl  FIFO water level
1575  *
1576  * @return      None.
1577  *
1578  * @details     Init Tx event fifo.
1579  */
CANFD_InitTxEvntFifo(CANFD_T * psCanfd,CANFD_RAM_PART_T * psRamConfig,CANFD_ELEM_SIZE_T * psElemSize,uint32_t u32FifoWaterLvl)1580 static void CANFD_InitTxEvntFifo(CANFD_T *psCanfd, CANFD_RAM_PART_T *psRamConfig, CANFD_ELEM_SIZE_T *psElemSize, uint32_t u32FifoWaterLvl)
1581 {
1582     /* Set TX Event FIFO element size,watermark,start address. */
1583     psCanfd->TXEFC = (u32FifoWaterLvl << CANFD_TXEFC_EFWN_Pos) | (psElemSize->u32TxEventFifo << CANFD_TXEFC_EFS_Pos)
1584                      | (psRamConfig->u32TXEFC_EFSA & CANFD_TXEFC_EFSA_Msk);
1585 }
1586 
1587 
1588 /**
1589  * @brief       Get Tx event fifo water level
1590  *
1591  * @param[in]   psCanfd       The pointer to CANFD module base address.
1592  *
1593  * @return      Tx event fifo water level.
1594  *
1595  * @details     Get Tx event fifo water level.
1596  */
CANFD_GetTxEvntFifoWaterLvl(CANFD_T * psCanfd)1597 uint32_t CANFD_GetTxEvntFifoWaterLvl(CANFD_T *psCanfd)
1598 {
1599     return ((CANFD_ReadReg(&psCanfd->TXEFC) & CANFD_TXEFC_EFWN_Msk) >> CANFD_TXEFC_EFWN_Pos);
1600 }
1601 
1602 
1603 /**
1604  * @brief        Copy Event Elements from TX Event FIFO to user buffer
1605  *
1606  * @param[in]   psCanfd          The pointer to CAN FD module base address.
1607  * @param[in]   u32TxEvntNum     Tx Event FIFO number
1608  * @param[in]   psTxEvntElem     Tx Event Message struct
1609  *
1610  * @return      None.
1611  *
1612  * @details     Copy all Event Elements from TX Event FIFO to the Software Event List .
1613  */
CANFD_CopyTxEvntFifoToUsrBuf(CANFD_T * psCanfd,uint32_t u32TxEvntNum,CANFD_TX_EVNT_ELEM_T * psTxEvntElem)1614 void CANFD_CopyTxEvntFifoToUsrBuf(CANFD_T *psCanfd, uint32_t u32TxEvntNum, CANFD_TX_EVNT_ELEM_T *psTxEvntElem)
1615 {
1616     uint32_t *pu32TxEvnt;
1617     /*Get the Tx Event FIFO Address*/
1618     pu32TxEvnt = (uint32_t *)CANFD_GetTxBufferElementAddress(psCanfd, u32TxEvntNum);
1619 
1620     /*Get the Error State Indicator*/
1621     if ((pu32TxEvnt[0] & TX_FIFO_E0_EVENT_ESI_Msk) > 0)
1622         psTxEvntElem->bErrStaInd = TRUE; //Transmitting node is error passive
1623     else
1624         psTxEvntElem->bErrStaInd = FALSE;//Transmitting node is error active
1625 
1626     /*Get the Tx FIFO Identifier type and Identifier*/
1627 
1628     if ((pu32TxEvnt[0] & TX_FIFO_E0_EVENT_XTD_Msk) > 0)
1629     {
1630         psTxEvntElem-> eIdType = eCANFD_XID;
1631         psTxEvntElem->u32Id = (pu32TxEvnt[0] & TX_FIFO_E0_EVENT_ID_Msk);// Extended ID
1632     }
1633     else
1634     {
1635         psTxEvntElem-> eIdType = eCANFD_SID;
1636         psTxEvntElem->u32Id = (pu32TxEvnt[0] & TX_FIFO_E0_EVENT_ID_Msk) >> 18;// Standard ID
1637     }
1638 
1639     /*Get the Frame type*/
1640     if ((pu32TxEvnt[0] & TX_FIFO_E0_EVENT_RTR_Msk) > 0)
1641         psTxEvntElem->bRemote = TRUE; //Remote frame
1642     else
1643         psTxEvntElem->bRemote = FALSE; //Data frame
1644 
1645     /*Get the FD Format type*/
1646     if ((pu32TxEvnt[0] & TX_FIFO_E1_EVENT_FDF_Msk) > 0)
1647         psTxEvntElem->bFDFormat = TRUE; //CAN FD frame format
1648     else
1649         psTxEvntElem->bFDFormat = FALSE; //Classical CAN frame format
1650 
1651     /*Get the Bit Rate Switch type*/
1652     if ((pu32TxEvnt[0] & TX_FIFO_E1_EVENT_BRS_Msk) > 0)
1653         psTxEvntElem->bBitRateSwitch = TRUE; //Frame transmitted with bit rate switching
1654     else
1655         psTxEvntElem->bBitRateSwitch = FALSE; //Frame transmitted without bit rate switching
1656 
1657     /*Get the Tx FIFO Data Length  */
1658     psTxEvntElem->u32DLC = CANFD_DecodeDLC((uint8_t)((pu32TxEvnt[1] & TX_FIFO_E1_EVENT_DLC_Msk) >> TX_FIFO_E1_EVENT_DLC_Pos));
1659 
1660     /*Get the Tx FIFO Timestamp  */
1661     psTxEvntElem->u32TxTs = (((pu32TxEvnt[1] & TX_FIFO_E1A_EVENT_TXTS_Msk) >> TX_FIFO_E1A_EVENT_TXTS_Pos));
1662     /*Get the Tx FIFO Message marker  */
1663     psTxEvntElem->u32MsgMarker = (((pu32TxEvnt[1] & TX_FIFO_E1_EVENT_MM_Msk) >> TX_FIFO_E1_EVENT_MM_Pos));
1664 }
1665 
1666 
1667 /**
1668  * @brief       Get CAN FD interrupts status.
1669  *
1670  * @param[in]   psCanfd         The pointer of the specified CAN FD module.
1671  * @param[in]   u32IntTypeFlag  Interrupt Type Flag, should be
1672  *                              - \ref CANFD_IR_ARA_Msk     : Access to Reserved Address interrupt Indicator
1673  *                              - \ref CANFD_IR_PED_Msk     : Protocol Error in Data Phase interrupt Indicator
1674  *                              - \ref CANFD_IR_PEA_Msk     : Protocol Error in Arbitration Phase interrupt Indicator
1675  *                              - \ref CANFD_IR_WDI_Msk     : Watchdog interrupt Indicator
1676  *                              - \ref CANFD_IR_BO_Msk      : Bus_Off Status interrupt Indicator
1677  *                              - \ref CANFD_IR_EW_Msk      : Warning Status interrupt Indicator
1678  *                              - \ref CANFD_IR_EP_Msk      : Error Passive interrupt Indicator
1679  *                              - \ref CANFD_IR_ELO_Msk     : Error Logging Overflow interrupt Indicator
1680  *                              - \ref CANFD_IR_DRX_Msk     : Message stored to Dedicated Rx Buffer interrupt Indicator
1681  *                              - \ref CANFD_IR_TOO_Msk     : Timeout Occurred interrupt Indicator
1682  *                              - \ref CANFD_IR_MRAF_Msk    : Message RAM Access Failure interrupt Indicator
1683  *                              - \ref CANFD_IR_TSW_Msk     : Timestamp Wraparound interrupt Indicator
1684  *                              - \ref CANFD_IR_TEFL_Msk    : Tx Event FIFO Event Lost interrupt Indicator
1685  *                              - \ref CANFD_IR_TEFF_Msk    : Tx Event FIFO Full Indicator
1686  *                              - \ref CANFD_IR_TEFW_Msk    : Tx Event FIFO Watermark Reached Interrupt Indicator
1687  *                              - \ref CANFD_IR_TEFN_Msk    : Tx Event FIFO New Entry Interrupt Indicator
1688  *                              - \ref CANFD_IR_TFE_Msk     : Tx FIFO Empty Interrupt Indicator
1689  *                              - \ref CANFD_IR_TCF_Msk     : Transmission Cancellation Finished Interrupt Indicator
1690  *                              - \ref CANFD_IR_TC_Msk      : Transmission Completed interrupt Indicator
1691  *                              - \ref CANFD_IR_HPM_Msk     : High Priority Message Interrupt Indicator
1692  *                              - \ref CANFD_IR_RF1L_Msk    : Rx FIFO 1 Message Lost Interrupt Indicator
1693  *                              - \ref CANFD_IR_RF1F_Msk    : Rx FIFO 1 Full Interrupt Indicator
1694  *                              - \ref CANFD_IR_RF1W_Msk    : Rx FIFO 1 Watermark Reached Interrupt Indicator
1695  *                              - \ref CANFD_IR_RF1N_Msk    : Rx FIFO 1 New Message Interrupt Indicator
1696  *                              - \ref CANFD_IR_RF0L_Msk    : Rx FIFO 0 Message Lost Interrupt Indicator
1697  *                              - \ref CANFD_IR_RF0F_Msk    : Rx FIFO 0 Full Interrupt Indicator
1698  *                              - \ref CANFD_IR_RF0W_Msk    : Rx FIFO 0 Watermark Reached Interrupt Indicator
1699  *                              - \ref CANFD_IR_RF0N_Msk    : Rx FIFO 0 New Message Interrupt Indicator
1700  *
1701  * @return      None.
1702  *
1703  * @details     This function gets all CAN FD interrupt status flags.
1704  */
CANFD_GetStatusFlag(CANFD_T * psCanfd,uint32_t u32IntTypeFlag)1705 uint32_t CANFD_GetStatusFlag(CANFD_T *psCanfd, uint32_t u32IntTypeFlag)
1706 {
1707     return (CANFD_ReadReg(&psCanfd->IR) & u32IntTypeFlag);
1708 }
1709 
1710 
1711 /**
1712  * @brief       Clears the CAN FD module interrupt flags
1713  *
1714  * @param[in]   psCanfd           The pointer of the specified CANFD module.
1715  * @param[in]   u32InterruptFlag  The specified interrupt of CAN FD module
1716  *                               - \ref CANFD_IR_ARA_Msk     : Access to Reserved Address interrupt Indicator
1717  *                               - \ref CANFD_IR_PED_Msk     : Protocol Error in Data Phase interrupt Indicator
1718  *                               - \ref CANFD_IR_PEA_Msk     : Protocol Error in Arbitration Phase interrupt Indicator
1719  *                               - \ref CANFD_IR_WDI_Msk     : Watchdog interrupt Indicator
1720  *                               - \ref CANFD_IR_BO_Msk      : Bus_Off Status interrupt Indicator
1721  *                               - \ref CANFD_IR_EW_Msk      : Warning Status interrupt Indicator
1722  *                               - \ref CANFD_IR_EP_Msk      : Error Passive interrupt Indicator
1723  *                               - \ref CANFD_IR_ELO_Msk     : Error Logging Overflow interrupt Indicator
1724  *                               - \ref CANFD_IR_DRX_Msk     : Message stored to Dedicated Rx Buffer interrupt Indicator
1725  *                               - \ref CANFD_IR_TOO_Msk     : Timeout Occurred interrupt Indicator
1726  *                               - \ref CANFD_IR_MRAF_Msk    : Message RAM Access Failure interrupt Indicator
1727  *                               - \ref CANFD_IR_TSW_Msk     : Timestamp Wraparound interrupt Indicator
1728  *                               - \ref CANFD_IR_TEFL_Msk    : Tx Event FIFO Event Lost interrupt Indicator
1729  *                               - \ref CANFD_IR_TEFF_Msk    : Tx Event FIFO Full Indicator
1730  *                               - \ref CANFD_IR_TEFW_Msk    : Tx Event FIFO Watermark Reached Interrupt Indicator
1731  *                               - \ref CANFD_IR_TEFN_Msk    : Tx Event FIFO New Entry Interrupt Indicator
1732  *                               - \ref CANFD_IR_TFE_Msk     : Tx FIFO Empty Interrupt Indicator
1733  *                               - \ref CANFD_IR_TCF_Msk     : Transmission Cancellation Finished Interrupt Indicator
1734  *                               - \ref CANFD_IR_TC_Msk      : Transmission Completed interrupt Indicator
1735  *                               - \ref CANFD_IR_HPM_Msk     : High Priority Message Interrupt Indicator
1736  *                               - \ref CANFD_IR_RF1L_Msk    : Rx FIFO 1 Message Lost Interrupt Indicator
1737  *                               - \ref CANFD_IR_RF1F_Msk    : Rx FIFO 1 Full Interrupt Indicator
1738  *                               - \ref CANFD_IR_RF1W_Msk    : Rx FIFO 1 Watermark Reached Interrupt Indicator
1739  *                               - \ref CANFD_IR_RF1N_Msk    : Rx FIFO 1 New Message Interrupt Indicator
1740  *                               - \ref CANFD_IR_RF0L_Msk    : Rx FIFO 0 Message Lost Interrupt Indicator
1741  *                               - \ref CANFD_IR_RF0F_Msk    : Rx FIFO 0 Full Interrupt Indicator
1742  *                               - \ref CANFD_IR_RF0W_Msk    : Rx FIFO 0 Watermark Reached Interrupt Indicator
1743  *                               - \ref CANFD_IR_RF0N_Msk    : Rx FIFO 0 New Message Interrupt Indicator
1744  *
1745  * @return      None.
1746  *
1747  * @details     This function clears CAN FD interrupt status flags.
1748  */
CANFD_ClearStatusFlag(CANFD_T * psCanfd,uint32_t u32InterruptFlag)1749 void CANFD_ClearStatusFlag(CANFD_T *psCanfd, uint32_t u32InterruptFlag)
1750 {
1751     /* Write 1 to clear status flag. */
1752     psCanfd->IR = CANFD_ReadReg(&psCanfd->IR) | u32InterruptFlag;
1753 }
1754 
1755 
1756 /**
1757  * @brief       Gets the CAN FD Bus Error Counter value.
1758  *
1759  * @param[in]   psCanfd        The pointer of the specified CAN FD module.
1760  * @param[in]   pu8TxErrBuf    TxErrBuf Buffer to store Tx Error Counter value.
1761  * @param[in]   pu8RxErrBuf    RxErrBuf Buffer to store Rx Error Counter value.
1762  *
1763  * @return      None.
1764  *
1765  * @details     This function gets the CAN FD Bus Error Counter value for both Tx and Rx direction.
1766  *              These values may be needed in the upper layer error handling.
1767  */
CANFD_GetBusErrCount(CANFD_T * psCanfd,uint8_t * pu8TxErrBuf,uint8_t * pu8RxErrBuf)1768 void CANFD_GetBusErrCount(CANFD_T *psCanfd, uint8_t *pu8TxErrBuf, uint8_t *pu8RxErrBuf)
1769 {
1770     if (pu8TxErrBuf)
1771     {
1772         *pu8TxErrBuf = (uint8_t)((CANFD_ReadReg(&psCanfd->ECR) >> CANFD_ECR_TEC_Pos) & CANFD_ECR_TEC_Msk);
1773     }
1774 
1775     if (pu8RxErrBuf)
1776     {
1777         *pu8RxErrBuf = (uint8_t)((CANFD_ReadReg(&psCanfd->ECR) >> CANFD_ECR_REC_Pos) & CANFD_ECR_REC_Msk);
1778     }
1779 }
1780 
1781 
1782 /**
1783  * @brief       CAN FD Run to the Normal Operation.
1784  *
1785  * @param[in]   psCanfd        The pointer of the specified CAN FD module.
1786  * @param[in]   u8Enable       TxErrBuf Buffer to store Tx Error Counter value.
1787  *
1788  * @retval      CANFD_OK          CANFD operation OK.
1789  * @retval      CANFD_ERR_TIMEOUT CANFD operation abort due to timeout error.
1790  *
1791  * @details     This function gets the CAN FD Bus Error Counter value for both Tx and Rx direction.
1792  *              These values may be needed in the upper layer error handling.
1793  */
CANFD_RunToNormal(CANFD_T * psCanfd,uint8_t u8Enable)1794 int32_t CANFD_RunToNormal(CANFD_T *psCanfd, uint8_t u8Enable)
1795 {
1796     uint32_t u32TimeOutCnt = CANFD_TIMEOUT;
1797 
1798     if (u8Enable)
1799     {
1800         /* start operation */
1801         psCanfd->CCCR = CANFD_ReadReg(&psCanfd->CCCR) & ~(CANFD_CCCR_CCE_Msk | CANFD_CCCR_INIT_Msk);
1802 
1803         while (psCanfd->CCCR & CANFD_CCCR_INIT_Msk)
1804         {
1805             if (--u32TimeOutCnt == 0) return CANFD_ERR_TIMEOUT;
1806         }
1807     }
1808     else
1809     {
1810         /* init mode */
1811         psCanfd->CCCR = CANFD_ReadReg(&psCanfd->CCCR) | CANFD_CCCR_INIT_Msk;
1812 
1813         while (!(psCanfd->CCCR & CANFD_CCCR_INIT_Msk))
1814         {
1815             if (--u32TimeOutCnt == 0) return CANFD_ERR_TIMEOUT;
1816         }
1817     }
1818 
1819     return CANFD_OK;
1820 }
1821 
1822 
1823 
1824 /*@}*/ /* end of group CANFD_EXPORTED_FUNCTIONS */
1825 
1826 /*@}*/ /* end of group CANFD_Driver */
1827 
1828 /*@}*/ /* end of group Standard_Driver */
1829