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