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