1 /*
2  * Copyright (c) 2016, Freescale Semiconductor, Inc.
3  * Copyright 2016-2022 NXP
4  * All rights reserved.
5  *
6  * SPDX-License-Identifier: BSD-3-Clause
7  */
8 #ifndef FSL_MCAN_H_
9 #define FSL_MCAN_H_
10 
11 #include "fsl_common.h"
12 
13 /*!
14  * @addtogroup mcan
15  * @{
16  */
17 
18 /******************************************************************************
19  * Definitions
20  *****************************************************************************/
21 
22 /*! @name Driver version */
23 /*! @{ */
24 /*! @brief MCAN driver version. */
25 #define FSL_MCAN_DRIVER_VERSION (MAKE_VERSION(2, 4, 2))
26 /*! @} */
27 
28 #ifndef MCAN_RETRY_TIMES
29 /* Define to 0 by default means to retry infinitely until the flag is assert/de-assert.
30  * User can change the macro with their requirement by defined the MACRO.
31  */
32 #define MCAN_RETRY_TIMES (0U)
33 #endif
34 
35 /*! @brief MCAN transfer status. */
36 enum
37 {
38     kStatus_MCAN_TxBusy           = MAKE_STATUS(kStatusGroup_MCAN, 0),  /*!< Tx Buffer is Busy. */
39     kStatus_MCAN_TxIdle           = MAKE_STATUS(kStatusGroup_MCAN, 1),  /*!< Tx Buffer is Idle. */
40     kStatus_MCAN_RxBusy           = MAKE_STATUS(kStatusGroup_MCAN, 2),  /*!< Rx Buffer is Busy. */
41     kStatus_MCAN_RxIdle           = MAKE_STATUS(kStatusGroup_MCAN, 3),  /*!< Rx Buffer is Idle. */
42     kStatus_MCAN_RxFifo0New       = MAKE_STATUS(kStatusGroup_MCAN, 4),  /*!< New message written to Rx FIFO 0. */
43     kStatus_MCAN_RxFifo0Idle      = MAKE_STATUS(kStatusGroup_MCAN, 5),  /*!< Rx FIFO 0 is Idle. */
44     kStatus_MCAN_RxFifo0Watermark = MAKE_STATUS(kStatusGroup_MCAN, 6),  /*!< Rx FIFO 0 fill level reached watermark. */
45     kStatus_MCAN_RxFifo0Full      = MAKE_STATUS(kStatusGroup_MCAN, 7),  /*!< Rx FIFO 0 full. */
46     kStatus_MCAN_RxFifo0Lost      = MAKE_STATUS(kStatusGroup_MCAN, 8),  /*!< Rx FIFO 0 message lost. */
47     kStatus_MCAN_RxFifo1New       = MAKE_STATUS(kStatusGroup_MCAN, 9),  /*!< New message written to Rx FIFO 1. */
48     kStatus_MCAN_RxFifo1Idle      = MAKE_STATUS(kStatusGroup_MCAN, 10), /*!< Rx FIFO 1 is Idle. */
49     kStatus_MCAN_RxFifo1Watermark = MAKE_STATUS(kStatusGroup_MCAN, 11), /*!< Rx FIFO 1 fill level reached watermark. */
50     kStatus_MCAN_RxFifo1Full      = MAKE_STATUS(kStatusGroup_MCAN, 12), /*!< Rx FIFO 1 full. */
51     kStatus_MCAN_RxFifo1Lost      = MAKE_STATUS(kStatusGroup_MCAN, 13), /*!< Rx FIFO 1 message lost. */
52     kStatus_MCAN_RxFifo0Busy      = MAKE_STATUS(kStatusGroup_MCAN, 14), /*!< Rx FIFO 0 is busy. */
53     kStatus_MCAN_RxFifo1Busy      = MAKE_STATUS(kStatusGroup_MCAN, 15), /*!< Rx FIFO 1 is busy. */
54     kStatus_MCAN_ErrorStatus      = MAKE_STATUS(kStatusGroup_MCAN, 16), /*!< MCAN Module Error and Status. */
55     kStatus_MCAN_UnHandled        = MAKE_STATUS(kStatusGroup_MCAN, 17), /*!< UnHadled Interrupt asserted. */
56 };
57 
58 /*!
59  * @brief MCAN status flags.
60  *
61  * This provides constants for the MCAN status flags for use in the MCAN functions.
62  * Note: The CPU read action clears MCAN_ErrorFlag, therefore user need to
63  * read MCAN_ErrorFlag and distinguish which error is occur using
64  * _mcan_error_flags enumerations.
65  */
66 enum _mcan_flags
67 {
68     kMCAN_AccesstoRsvdFlag    = CAN_IR_ARA_MASK, /*!< CAN Synchronization Status. */
69     kMCAN_ProtocolErrDIntFlag = CAN_IR_PED_MASK, /*!< Tx Warning Interrupt Flag. */
70     kMCAN_ProtocolErrAIntFlag = CAN_IR_PEA_MASK, /*!< Rx Warning Interrupt Flag. */
71     kMCAN_BusOffIntFlag       = CAN_IR_BO_MASK,  /*!< Tx Error Warning Status. */
72     kMCAN_ErrorWarningIntFlag = CAN_IR_EW_MASK,  /*!< Rx Error Warning Status. */
73     kMCAN_ErrorPassiveIntFlag = CAN_IR_EP_MASK,  /*!< Rx Error Warning Status. */
74 };
75 
76 /*!
77  * @brief MCAN Rx FIFO status flags.
78  *
79  * The MCAN Rx FIFO Status enumerations are used to determine the status of the
80  * Rx FIFO.
81  */
82 enum _mcan_rx_fifo_flags
83 {
84     kMCAN_RxFifo0NewFlag       = CAN_IR_RF0N_MASK, /*!< Rx FIFO 0 new message flag. */
85     kMCAN_RxFifo0WatermarkFlag = CAN_IR_RF0W_MASK, /*!< Rx FIFO 0 watermark reached flag. */
86     kMCAN_RxFifo0FullFlag      = CAN_IR_RF0F_MASK, /*!< Rx FIFO 0 full flag. */
87     kMCAN_RxFifo0LostFlag      = CAN_IR_RF0L_MASK, /*!< Rx FIFO 0 message lost flag. */
88     kMCAN_RxFifo1NewFlag       = CAN_IR_RF1N_MASK, /*!< Rx FIFO 0 new message flag. */
89     kMCAN_RxFifo1WatermarkFlag = CAN_IR_RF1W_MASK, /*!< Rx FIFO 0 watermark reached flag. */
90     kMCAN_RxFifo1FullFlag      = CAN_IR_RF1F_MASK, /*!< Rx FIFO 0 full flag. */
91     kMCAN_RxFifo1LostFlag      = CAN_IR_RF1L_MASK, /*!< Rx FIFO 0 message lost flag. */
92 };
93 
94 /*!
95  * @brief MCAN Tx status flags.
96  *
97  * The MCAN Tx Status enumerations are used to determine the status of the
98  * Tx Buffer/Event FIFO.
99  */
100 enum _mcan_tx_flags
101 {
102     kMCAN_TxTransmitCompleteFlag     = CAN_IR_TC_MASK,   /*!< Transmission completed flag. */
103     kMCAN_TxTransmitCancelFinishFlag = CAN_IR_TCF_MASK,  /*!< Transmission cancellation finished flag. */
104     kMCAN_TxEventFifoLostFlag        = CAN_IR_TEFL_MASK, /*!< Tx Event FIFO element lost. */
105     kMCAN_TxEventFifoFullFlag        = CAN_IR_TEFF_MASK, /*!< Tx Event FIFO full. */
106     kMCAN_TxEventFifoWatermarkFlag   = CAN_IR_TEFW_MASK, /*!< Tx Event FIFO fill level reached watermark. */
107     kMCAN_TxEventFifoNewFlag         = CAN_IR_TEFN_MASK, /*!< Tx Handler wrote Tx Event FIFO element flag. */
108     kMCAN_TxEventFifoEmptyFlag       = CAN_IR_TFE_MASK,  /*!< Tx FIFO empty flag. */
109 };
110 
111 /*!
112  * @brief MCAN interrupt configuration structure, default settings all disabled.
113  *
114  * This structure contains the settings for all of the MCAN Module interrupt configurations.
115  */
116 enum _mcan_interrupt_enable
117 {
118     kMCAN_BusOffInterruptEnable  = CAN_IE_BOE_MASK, /*!< Bus Off interrupt. */
119     kMCAN_ErrorInterruptEnable   = CAN_IE_EPE_MASK, /*!< Error interrupt. */
120     kMCAN_WarningInterruptEnable = CAN_IE_EWE_MASK, /*!< Rx Warning interrupt. */
121 };
122 
123 /*! @brief MCAN frame format. */
124 typedef enum _mcan_frame_idformat
125 {
126     kMCAN_FrameIDStandard = 0x0U, /*!< Standard frame format attribute. */
127     kMCAN_FrameIDExtend   = 0x1U, /*!< Extend frame format attribute. */
128 } mcan_frame_idformat_t;
129 
130 /*! @brief MCAN frame type. */
131 typedef enum _mcan_frame_type
132 {
133     kMCAN_FrameTypeData   = 0x0U, /*!< Data frame type attribute. */
134     kMCAN_FrameTypeRemote = 0x1U, /*!< Remote frame type attribute. */
135 } mcan_frame_type_t;
136 
137 /*! @brief MCAN frame datafield size. */
138 typedef enum _mcan_bytes_in_datafield
139 {
140     kMCAN_8ByteDatafield  = 0x0U, /*!< 8 byte data field. */
141     kMCAN_12ByteDatafield = 0x1U, /*!< 12 byte data field. */
142     kMCAN_16ByteDatafield = 0x2U, /*!< 16 byte data field. */
143     kMCAN_20ByteDatafield = 0x3U, /*!< 20 byte data field. */
144     kMCAN_24ByteDatafield = 0x4U, /*!< 24 byte data field. */
145     kMCAN_32ByteDatafield = 0x5U, /*!< 32 byte data field. */
146     kMCAN_48ByteDatafield = 0x6U, /*!< 48 byte data field. */
147     kMCAN_64ByteDatafield = 0x7U, /*!< 64 byte data field. */
148 } mcan_bytes_in_datafield_t;
149 
150 #if defined(__CC_ARM)
151 #pragma anon_unions
152 #endif
153 /*! @brief MCAN Tx Buffer structure. */
154 typedef struct _mcan_tx_buffer_frame
155 {
156     struct
157     {
158         uint32_t id : 29; /*!< CAN Frame Identifier. */
159         uint32_t rtr : 1; /*!< CAN Frame Type(DATA or REMOTE). */
160         uint32_t xtd : 1; /*!< CAN Frame Type(STD or EXT). */
161         uint32_t esi : 1; /*!< CAN Frame Error State Indicator. */
162     };
163     struct
164     {
165         uint32_t : 16;
166         uint32_t dlc : 4; /*!< Data Length Code      9 10 11 12 13 14 15
167                                Number of data bytes 12 16 20 24 32 48 64 */
168         uint32_t brs : 1; /*!< Bit Rate Switch. */
169         uint32_t fdf : 1; /*!< CAN FD format. */
170         uint32_t : 1;     /*!< Reserved. */
171         uint32_t efc : 1; /*!< Event FIFO control. */
172         uint32_t mm : 8;  /*!< Message Marker. */
173     };
174     uint8_t *data;
175     uint8_t size; /*!< classical CAN is 8(bytes), FD is 12/64 such. */
176 } mcan_tx_buffer_frame_t;
177 
178 /*! @brief MCAN Rx FIFO/Buffer structure. */
179 typedef struct _mcan_rx_buffer_frame
180 {
181     struct
182     {
183         uint32_t id : 29; /*!< CAN Frame Identifier. */
184         uint32_t rtr : 1; /*!< CAN Frame Type(DATA or REMOTE). */
185         uint32_t xtd : 1; /*!< CAN Frame Type(STD or EXT). */
186         uint32_t esi : 1; /*!< CAN Frame Error State Indicator. */
187     };
188     struct
189     {
190         uint32_t rxts : 16; /*!< Rx Timestamp. */
191         uint32_t dlc : 4;   /*!< Data Length Code      9 10 11 12 13 14 15
192                                  Number of data bytes 12 16 20 24 32 48 64 */
193         uint32_t brs : 1;   /*!< Bit Rate Switch. */
194         uint32_t fdf : 1;   /*!< CAN FD format. */
195         uint32_t : 2;       /*!< Reserved. */
196         uint32_t fidx : 7;  /*!< Filter Index. */
197         uint32_t anmf : 1;  /*!< Accepted Non-matching Frame. */
198     };
199     uint8_t *data;
200     uint8_t size; /*!< classical CAN is 8(bytes), FD is 12/64 such. */
201 } mcan_rx_buffer_frame_t;
202 
203 /*! @brief MCAN Rx FIFO block number. */
204 typedef enum _mcan_fifo_type
205 {
206     kMCAN_Fifo0 = 0x0U, /*!< CAN Rx FIFO 0. */
207     kMCAN_Fifo1 = 0x1U, /*!< CAN Rx FIFO 1. */
208 } mcan_fifo_type_t;
209 
210 /*! @brief MCAN FIFO Operation Mode. */
211 typedef enum _mcan_fifo_opmode_config
212 {
213     kMCAN_FifoBlocking  = 0x0U, /*!< FIFO blocking mode. */
214     kMCAN_FifoOverwrite = 0x1U, /*!< FIFO overwrite mode. */
215 } mcan_fifo_opmode_config_t;
216 
217 /*! @brief MCAN Tx FIFO/Queue Mode. */
218 typedef enum _mcan_txmode_config
219 {
220     kMCAN_txFifo  = 0x0U, /*!< Tx FIFO operation. */
221     kMCAN_txQueue = 0x1U, /*!< Tx Queue operation. */
222 } mcan_txmode_config_t;
223 
224 /*! @brief MCAN remote frames treatment. */
225 typedef enum _mcan_remote_frame_config
226 {
227     kMCAN_filterFrame = 0x0U, /*!< Filter remote frames. */
228     kMCAN_rejectFrame = 0x1U, /*!< Reject all remote frames. */
229 } mcan_remote_frame_config_t;
230 
231 /*! @brief MCAN non-masking frames treatment. */
232 typedef enum _mcan_nonmasking_frame_config
233 {
234     kMCAN_acceptinFifo0 = 0x0U, /*!< Accept non-masking frames in Rx FIFO 0. */
235     kMCAN_acceptinFifo1 = 0x1U, /*!< Accept non-masking frames in Rx FIFO 1. */
236     kMCAN_reject0       = 0x2U, /*!< Reject non-masking frames. */
237     kMCAN_reject1       = 0x3U, /*!< Reject non-masking frames. */
238 } mcan_nonmasking_frame_config_t;
239 
240 /*! @brief MCAN Filter Element Configuration. */
241 typedef enum _mcan_fec_config
242 {
243     kMCAN_disable       = 0x0U, /*!< Disable filter element. */
244     kMCAN_storeinFifo0  = 0x1U, /*!< Store in Rx FIFO 0 if filter matches. */
245     kMCAN_storeinFifo1  = 0x2U, /*!< Store in Rx FIFO 1 if filter matches. */
246     kMCAN_reject        = 0x3U, /*!< Reject ID if filter matches. */
247     kMCAN_setprio       = 0x4U, /*!< Set priority if filter matches. */
248     kMCAN_setpriofifo0  = 0x5U, /*!< Set priority and store in FIFO 0 if filter matches. */
249     kMCAN_setpriofifo1  = 0x6U, /*!< Set priority and store in FIFO 1 if filter matches. */
250     kMCAN_storeinbuffer = 0x7U, /*!< Store into Rx Buffer or as debug message. */
251 } mcan_fec_config_t;
252 
253 /*! @brief MCAN Rx FIFO configuration. */
254 typedef struct _mcan_rx_fifo_config
255 {
256     uint32_t address;                        /*!< FIFOn start address. */
257     uint32_t elementSize;                    /*!< FIFOn element number. */
258     uint32_t watermark;                      /*!< FIFOn watermark level. */
259     mcan_fifo_opmode_config_t opmode;        /*!< FIFOn blocking/overwrite mode. */
260     mcan_bytes_in_datafield_t datafieldSize; /*!< Data field size per frame, size>8 is for CANFD. */
261 } mcan_rx_fifo_config_t;
262 
263 /*! @brief MCAN Rx Buffer configuration. */
264 typedef struct _mcan_rx_buffer_config
265 {
266     uint32_t address;                        /*!< Rx Buffer start address. */
267     mcan_bytes_in_datafield_t datafieldSize; /*!< Data field size per frame, size>8 is for CANFD. */
268 } mcan_rx_buffer_config_t;
269 
270 /*! @brief MCAN Tx Event FIFO configuration. */
271 typedef struct _mcan_tx_fifo_config
272 {
273     uint32_t address;     /*!< Event fifo start address. */
274     uint32_t elementSize; /*!< FIFOn element number. */
275     uint32_t watermark;   /*!< FIFOn watermark level. */
276 } mcan_tx_fifo_config_t;
277 
278 /*! @brief MCAN Tx Buffer configuration. */
279 typedef struct _mcan_tx_buffer_config
280 {
281     uint32_t address;                        /*!< Tx Buffers Start Address. */
282     uint32_t dedicatedSize;                  /*!< Number of Dedicated Transmit Buffers. */
283     uint32_t fqSize;                         /*!< Transmit FIFO/Queue Size. */
284     mcan_txmode_config_t mode;               /*!< Tx FIFO/Queue Mode.*/
285     mcan_bytes_in_datafield_t datafieldSize; /*!< Data field size per frame, size>8 is for CANFD. */
286 } mcan_tx_buffer_config_t;
287 
288 /*! @brief MCAN Filter Type. */
289 typedef enum _mcan_std_filter_type
290 {
291     kMCAN_range           = 0x0U, /*!< Range filter from SFID1 to SFID2. */
292     kMCAN_dual            = 0x1U, /*!< Dual ID filter for SFID1 or SFID2. */
293     kMCAN_classic         = 0x2U, /*!< Classic filter: SFID1 = filter, SFID2 = mask. */
294     kMCAN_disableORrange2 = 0x3U, /*!< Filter element disabled for standard filter
295                                     or Range filter, XIDAM mask not applied for extended filter. */
296 } mcan_filter_type_t;
297 
298 /*! @brief MCAN Standard Message ID Filter Element. */
299 typedef struct _mcan_std_filter_element_config
300 {
301     uint32_t sfid2 : 11; /*!< Standard Filter ID 2. */
302     uint32_t : 5;        /*!< Reserved. */
303     uint32_t sfid1 : 11; /*!< Standard Filter ID 1. */
304     uint32_t sfec : 3;   /*!< Standard Filter Element Configuration. */
305     uint32_t sft : 2;    /*!< Standard Filter Type. */
306 } mcan_std_filter_element_config_t;
307 
308 /*! @brief MCAN Extended Message ID Filter Element. */
309 typedef struct _mcan_ext_filter_element_config
310 {
311     uint32_t efid1 : 29; /*!< Extended Filter ID 1. */
312     uint32_t efec : 3;   /*!< Extended Filter Element Configuration. */
313     uint32_t efid2 : 29; /*!< Extended Filter ID 2. */
314     uint32_t : 1;        /*!< Reserved. */
315     uint32_t eft : 2;    /*!< Extended Filter Type. */
316 } mcan_ext_filter_element_config_t;
317 
318 /*! @brief MCAN Rx filter configuration. */
319 typedef struct _mcan_frame_filter_config
320 {
321     uint32_t address;                       /*!< Filter start address. */
322     uint32_t listSize;                      /*!< Filter list size. */
323     mcan_frame_idformat_t idFormat;         /*!< Frame format. */
324     mcan_remote_frame_config_t remFrame;    /*!< Remote frame treatment. */
325     mcan_nonmasking_frame_config_t nmFrame; /*!< Non-masking frame treatment. */
326 } mcan_frame_filter_config_t;
327 
328 /*! @brief MCAN protocol timing characteristic configuration structure. */
329 typedef struct _mcan_timing_config
330 {
331     uint16_t preDivider; /*!< Nominal Clock Pre-scaler Division Factor. */
332     uint8_t rJumpwidth;  /*!< Nominal Re-sync Jump Width. */
333     uint8_t seg1;        /*!< Nominal Time Segment 1. */
334     uint8_t seg2;        /*!< Nominal Time Segment 2. */
335 #if (defined(FSL_FEATURE_CAN_SUPPORT_CANFD) && FSL_FEATURE_CAN_SUPPORT_CANFD)
336     uint16_t datapreDivider; /*!< Data Clock Pre-scaler Division Factor. */
337     uint8_t datarJumpwidth;  /*!< Data Re-sync Jump Width. */
338     uint8_t dataseg1;        /*!< Data Time Segment 1. */
339     uint8_t dataseg2;        /*!< Data Time Segment 2. */
340 #endif
341 } mcan_timing_config_t;
342 
343 /*! @brief MCAN bit timing parameter configuration structure. */
344 typedef struct _mcan_timing_param
345 {
346     uint32_t busLength;         /*!< Maximum Bus length in meter. */
347     uint32_t propTxRx;          /*!< Transceiver propagation delay in nanosecond. */
348     uint32_t nominalbaudRate;   /*!< Baud rate of Arbitration phase in bps. */
349     uint32_t nominalSP;         /*!< Sample point of Arbitration phase, range in 10 ~ 990, 800 means 80%. */
350 #if (defined(FSL_FEATURE_CAN_SUPPORT_CANFD) && FSL_FEATURE_CAN_SUPPORT_CANFD)
351     uint32_t databaudRate;      /*!< Baud rate of Data phase in bps. */
352     uint32_t dataSP;            /*!< Sample point of Data phase, range in 0 ~ 1000, 800 means 80%. */
353 #endif
354 } mcan_timing_param_t;
355 
356 /*! @brief MCAN Message RAM related configuration structure. */
357 typedef struct _mcan_memory_config
358 {
359     uint32_t baseAddr;                        /*!< Message RAM base address, should be 4k alignment. */
360     mcan_frame_filter_config_t *stdFilterCfg; /* Standard message ID filter configure */
361     mcan_frame_filter_config_t *extFilterCfg; /* Extended message ID filter configure */
362     mcan_rx_fifo_config_t *rxFifo0Cfg;        /* Rx FIFO 0 configuration */
363     mcan_rx_fifo_config_t *rxFifo1Cfg;        /* Rx FIFO 1 configuration */
364     mcan_rx_buffer_config_t *rxBufferCfg;     /* Rx buffer configuration */
365     mcan_tx_fifo_config_t *txFifoCfg;         /* Tx event FIFO configuration */
366     mcan_tx_buffer_config_t *txBufferCfg;     /* Tx buffer configuration */
367 } mcan_memory_config_t;
368 
369 /*! @brief MCAN module configuration structure. */
370 typedef struct _mcan_config
371 {
372     uint32_t baudRateA;                /*!< Baud rate of Arbitration phase in bps. */
373     uint32_t baudRateD;                /*!< Baud rate of Data phase in bps. */
374     bool enableCanfdNormal;            /*!< Enable or Disable CANFD normal. */
375     bool enableCanfdSwitch;            /*!< Enable or Disable CANFD with baudrate switch. */
376     bool enableLoopBackInt;            /*!< Enable or Disable Internal Back. */
377     bool enableLoopBackExt;            /*!< Enable or Disable External Loop Back. */
378     bool enableBusMon;                 /*!< Enable or Disable Bus Monitoring Mode. */
379     mcan_timing_config_t timingConfig; /*!< Protocol timing . */
380 } mcan_config_t;
381 
382 /*! @brief MCAN Buffer transfer. */
383 typedef struct _mcan_buffer_transfer
384 {
385     mcan_tx_buffer_frame_t *frame; /*!< The buffer of CAN Message to be transfer. */
386     uint8_t bufferIdx;             /*!< The index of Message buffer used to transfer Message. */
387 } mcan_buffer_transfer_t;
388 
389 /*! @brief MCAN Rx FIFO transfer. */
390 typedef struct _mcan_fifo_transfer
391 {
392     mcan_rx_buffer_frame_t *frame; /*!< The buffer of CAN Message to be received from Rx FIFO. */
393 } mcan_fifo_transfer_t;
394 
395 /*! @brief MCAN handle structure definition. */
396 typedef struct _mcan_handle mcan_handle_t;
397 
398 /*! @brief MCAN transfer callback function.
399  *
400  *  The MCAN transfer callback returns a value from the underlying layer.
401  *  If the status equals to kStatus_MCAN_ErrorStatus, the result parameter is the Content of
402  *  MCAN status register which can be used to get the working status(or error status) of MCAN module.
403  *  If the status equals to other MCAN Message Buffer transfer status, the result is the index of
404  *  Message Buffer that generate transfer event.
405  *  If the status equals to other MCAN Message Buffer transfer status, the result is meaningless and should be
406  *  Ignored.
407  */
408 typedef void (*mcan_transfer_callback_t)(
409     CAN_Type *base, mcan_handle_t *handle, status_t status, uint32_t result, void *userData);
410 
411 /*! @brief MCAN handle structure. */
412 struct _mcan_handle
413 {
414     mcan_transfer_callback_t callback;                   /*!< Callback function. */
415     void *userData;                                      /*!< MCAN callback function parameter.*/
416     mcan_tx_buffer_frame_t *volatile bufferFrameBuf[64]; /*!< The buffer for received data from Buffers. */
417     mcan_rx_buffer_frame_t *volatile rxFifoFrameBuf;     /*!< The buffer for received data from Rx FIFO. */
418     volatile uint8_t bufferState[64];                    /*!< Message Buffer transfer state. */
419     volatile uint8_t rxFifoState;                        /*!< Rx FIFO transfer state. */
420 };
421 
422 /******************************************************************************
423  * API
424  *****************************************************************************/
425 
426 #if defined(__cplusplus)
427 extern "C" {
428 #endif
429 
430 /*!
431  * @name Initialization and deinitialization
432  * @{
433  */
434 
435 /*!
436  * @brief Initializes an MCAN instance.
437  *
438  * This function initializes the MCAN module with user-defined settings.
439  * This example shows how to set up the mcan_config_t parameters and how
440  * to call the MCAN_Init function by passing in these parameters.
441  *  @code
442  *   mcan_config_t config;
443  *   config->baudRateA = 500000U;
444  *   config->baudRateD = 1000000U;
445  *   config->enableCanfdNormal = false;
446  *   config->enableCanfdSwitch = false;
447  *   config->enableLoopBackInt = false;
448  *   config->enableLoopBackExt = false;
449  *   config->enableBusMon = false;
450  *   MCAN_Init(CANFD0, &config, 8000000UL);
451  *   @endcode
452  *
453  * @param base MCAN peripheral base address.
454  * @param config Pointer to the user-defined configuration structure.
455  * @param sourceClock_Hz MCAN Protocol Engine clock source frequency in Hz.
456  */
457 void MCAN_Init(CAN_Type *base, const mcan_config_t *config, uint32_t sourceClock_Hz);
458 
459 /*!
460  * @brief Deinitializes an MCAN instance.
461  *
462  * This function deinitializes the MCAN module.
463  *
464  * @param base MCAN peripheral base address.
465  */
466 void MCAN_Deinit(CAN_Type *base);
467 
468 /*!
469  * @brief Gets the default configuration structure.
470  *
471  * This function initializes the MCAN configuration structure to default values. The default
472  * values are as follows.
473  *   config->baudRateA = 500000U;
474  *   config->baudRateD = 1000000U;
475  *   config->enableCanfdNormal = false;
476  *   config->enableCanfdSwitch = false;
477  *   config->enableLoopBackInt = false;
478  *   config->enableLoopBackExt = false;
479  *   config->enableBusMon = false;
480  *
481  * @param config Pointer to the MCAN configuration structure.
482  */
483 void MCAN_GetDefaultConfig(mcan_config_t *config);
484 
485 /*!
486  * @brief MCAN enters initialization mode.
487  *
488  * After enter initialization mode, users can write access to the protected configuration registers.
489  *
490  * @param base MCAN peripheral base address.
491  */
MCAN_EnterInitialMode(CAN_Type * base)492 static inline void MCAN_EnterInitialMode(CAN_Type *base)
493 {
494     /* Enable write access to the protected configuration registers */
495     base->CCCR |= CAN_CCCR_INIT_MASK;
496     while (0U == (base->CCCR & CAN_CCCR_INIT_MASK))
497     {
498     }
499     base->CCCR |= CAN_CCCR_CCE_MASK;
500 }
501 
502 /*!
503  * @brief MCAN enters normal mode.
504  *
505  * After initialization, INIT bit in CCCR register must be cleared to enter
506  * normal mode thus synchronizes to the CAN bus and ready for communication.
507  *
508  * @param base MCAN peripheral base address.
509  */
MCAN_EnterNormalMode(CAN_Type * base)510 static inline void MCAN_EnterNormalMode(CAN_Type *base)
511 {
512     /* Reset INIT bit to enter normal mode. */
513     base->CCCR &= ~CAN_CCCR_INIT_MASK;
514     while (0U != (base->CCCR & CAN_CCCR_INIT_MASK))
515     {
516     }
517 }
518 
519 /*!
520  * @name Configuration.
521  * @{
522  */
523 
524 /*!
525  * @brief Sets the MCAN Message RAM base address.
526  *
527  * This function sets the Message RAM base address.
528  *
529  * @param base MCAN peripheral base address.
530  * @param value Desired Message RAM base.
531  */
MCAN_SetMsgRAMBase(CAN_Type * base,uint32_t value)532 static inline void MCAN_SetMsgRAMBase(CAN_Type *base, uint32_t value)
533 {
534     assert(((value >= 0x20000000U) && (value <= 0x20027FFFU)) || ((value >= 0x04000000U) && (value <= 0x04007FFFU)));
535 
536     base->MRBA = CAN_MRBA_BA(value >> 16U);
537 }
538 
539 /*!
540  * @brief Gets the MCAN Message RAM base address.
541  *
542  * This function gets the Message RAM base address.
543  *
544  * @param base MCAN peripheral base address.
545  * @return Message RAM base address.
546  */
MCAN_GetMsgRAMBase(CAN_Type * base)547 static inline uint32_t MCAN_GetMsgRAMBase(CAN_Type *base)
548 {
549     return base->MRBA;
550 }
551 
552 /*!
553  * @brief Calculates the improved timing values by specific baudrates for classical CAN
554  *
555  * @param baudRate  The classical CAN speed in bps defined by user
556  * @param sourceClock_Hz The Source clock data speed in bps. Zero to disable baudrate switching
557  * @param pconfig Pointer to the MCAN timing configuration structure.
558  *
559  * @return TRUE if timing configuration found, FALSE if failed to find configuration
560  */
561 bool MCAN_CalculateImprovedTimingValues(uint32_t baudRate, uint32_t sourceClock_Hz, mcan_timing_config_t *pconfig);
562 
563 /*!
564  * @brief Calculates the specified timing values for classical CAN with user-defined settings.
565  *
566  *  User can specify baudrates, sample point position, bus length, and transceiver propagation
567  *  delay. This example shows how to set up the mcan_timing_param_t parameters and how to call
568  *  the this function by passing in these parameters.
569  *  @code
570  *   mcan_timing_config_t timing_config;
571  *   mcan_timing_param_t timing_param;
572  *   timing_param.busLength = 1U;
573  *   timing_param.propTxRx = 230U;
574  *   timing_param.nominalbaudRate = 500000U;
575  *   timing_param.nominalSP = 800U;
576  *   MCAN_CalculateSpecifiedTimingValues(MCAN_CLK_FREQ, &timing_config, &timing_param);
577  *  @endcode
578  *
579  *  Note that due to integer division will sacrifice the precision, actual sample point may not
580  *  equal to expected. If actual sample point is not in allowed 2% range, this function will
581  *  return false. So it is better to select higher source clock when baudrate is relatively high.
582  *  This will ensure more time quanta and higher precision of sample point.
583  *  Parameter busLength and propTxRx are optional and intended to verify whether propagation
584  *  delay is too long to corrupt sample point. User can set these parameter zero if you do not
585  *  want to consider this factor.
586  *
587  * @param sourceClock_Hz The Source clock data speed in bps.
588  * @param pconfig Pointer to the MCAN timing configuration structure.
589  * @param config Pointer to the MCAN timing parameters structure.
590  *
591  * @return TRUE if timing configuration found, FALSE if failed to find configuration
592  */
593 bool MCAN_CalculateSpecifiedTimingValues(uint32_t sourceClock_Hz,
594                                          mcan_timing_config_t *pconfig,
595                                          const mcan_timing_param_t *pParamConfig);
596 
597 /*!
598  * @brief Sets the MCAN protocol arbitration phase timing characteristic.
599  *
600  * This function gives user settings to CAN bus timing characteristic.
601  * The function is for an experienced user. For less experienced users, call
602  * the MCAN_Init() and fill the baud rate field with a desired value.
603  * This provides the default arbitration phase timing characteristics.
604  *
605  * Note that calling MCAN_SetArbitrationTimingConfig() overrides the baud rate
606  * set in MCAN_Init().
607  *
608  * @param base MCAN peripheral base address.
609  * @param config Pointer to the timing configuration structure.
610  */
611 void MCAN_SetArbitrationTimingConfig(CAN_Type *base, const mcan_timing_config_t *config);
612 
613 /*!
614  * @brief Set Baud Rate of MCAN classic mode.
615  *
616  * This function set the baud rate of MCAN base on MCAN_CalculateImprovedTimingValues() API calculated timing values.
617  *
618  * @param base MCAN peripheral base address.
619  * @param sourceClock_Hz Source Clock in Hz.
620  * @param baudRate_Bps Baud Rate in Bps.
621  * @return kStatus_Success - Set CAN baud rate (only has Nominal phase) successfully.
622  */
623 status_t MCAN_SetBaudRate(CAN_Type *base, uint32_t sourceClock_Hz, uint32_t baudRate_Bps);
624 
625 #if (defined(FSL_FEATURE_CAN_SUPPORT_CANFD) && FSL_FEATURE_CAN_SUPPORT_CANFD)
626 /*!
627  * @brief Calculates the improved timing values by specific baudrates for CANFD
628  *
629  * @param baudRate  The CANFD bus control speed in bps defined by user
630  * @param baudRateFD  The CANFD bus data speed in bps defined by user
631  * @param sourceClock_Hz The Source clock data speed in bps.
632  * @param pconfig Pointer to the MCAN timing configuration structure.
633  *
634  * @return TRUE if timing configuration found, FALSE if failed to find configuration
635  */
636 bool MCAN_FDCalculateImprovedTimingValues(uint32_t baudRate,
637                                           uint32_t baudRateFD,
638                                           uint32_t sourceClock_Hz,
639                                           mcan_timing_config_t *pconfig);
640 
641 /*!
642  * @brief Calculates the specified timing values for CANFD with user-defined settings.
643  *
644  *  User can specify baudrates, sample point position, bus length, and transceiver propagation
645  *  delay. This example shows how to set up the mcan_timing_param_t parameters and how to call
646  *  the this function by passing in these parameters.
647  *  @code
648  *   mcan_timing_config_t timing_config;
649  *   mcan_timing_param_t timing_param;
650  *   timing_param.busLength = 1U;
651  *   timing_param.propTxRx = 230U;
652  *   timing_param.nominalbaudRate = 500000U;
653  *   timing_param.nominalSP = 800U;
654  *   timing_param.databaudRate = 4000000U;
655  *   timing_param.dataSP = 700U;
656  *   MCAN_FDCalculateSpecifiedTimingValues(MCAN_CLK_FREQ, &timing_config, &timing_param);
657  *  @endcode
658  *
659  *  Note that due to integer division will sacrifice the precision, actual sample point may not
660  *  equal to expected. So it is better to select higher source clock when baudrate is relatively
661  *  high. Select higher nominal baudrate when source clock is relatively high because large clock
662  *  predivider will lead to less time quanta in data phase. This function will set predivider in
663  *  arbitration phase equal to data phase. These methods will ensure more time quanta and higher
664  *  precision of sample point.
665  *  Parameter busLength and propTxRx are optional and intended to verify whether propagation
666  *  delay is too long to corrupt sample point. User can set these parameter zero if you do not
667  *  want to consider this factor.
668  *
669  * @param sourceClock_Hz The Source clock data speed in bps.
670  * @param pconfig Pointer to the MCAN timing configuration structure.
671  * @param config Pointer to the MCAN timing parameters structure.
672  *
673  * @return TRUE if timing configuration found, FALSE if failed to find configuration
674  */
675 bool MCAN_FDCalculateSpecifiedTimingValues(uint32_t sourceClock_Hz,
676                                            mcan_timing_config_t *pconfig,
677                                            const mcan_timing_param_t *pParamConfig);
678 
679 /*!
680  * @brief Set Baud Rate of MCAN FD mode.
681  *
682  * This function set the baud rate of MCAN FD base on MCAN_FDCalculateImprovedTimingValues API calculated timing values.
683  *
684  * @param base MCAN peripheral base address.
685  * @param sourceClock_Hz Source Clock in Hz.
686  * @param baudRateN_Bps Nominal Baud Rate in Bps.
687  * @param baudRateD_Bps Data Baud Rate in Bps.
688  * @return kStatus_Success - Set CAN FD baud rate (include Nominal and Data phase) successfully.
689  */
690 status_t MCAN_SetBaudRateFD(CAN_Type *base, uint32_t sourceClock_Hz, uint32_t baudRateN_Bps, uint32_t baudRateD_Bps);
691 /*!
692  * @brief Sets the MCAN protocol data phase timing characteristic.
693  *
694  * This function gives user settings to CAN bus timing characteristic.
695  * The function is for an experienced user. For less experienced users, call
696  * the MCAN_Init() and fill the baud rate field with a desired value.
697  * This provides the default data phase timing characteristics.
698  *
699  * Note that calling MCAN_SetArbitrationTimingConfig() overrides the baud rate
700  * set in MCAN_Init().
701  *
702  * @param base MCAN peripheral base address.
703  * @param config Pointer to the timing configuration structure.
704  */
705 void MCAN_SetDataTimingConfig(CAN_Type *base, const mcan_timing_config_t *config);
706 #endif /* FSL_FEATURE_CAN_SUPPORT_CANFD */
707 
708 /*!
709  * @brief Configures an MCAN receive fifo 0 buffer.
710  *
711  * This function sets start address, element size, watermark, operation mode
712  * and datafield size of the recieve fifo 0.
713  *
714  * @param base MCAN peripheral base address.
715  * @param config The receive fifo 0 configuration structure.
716  */
717 void MCAN_SetRxFifo0Config(CAN_Type *base, const mcan_rx_fifo_config_t *config);
718 
719 /*!
720  * @brief Configures an MCAN receive fifo 1 buffer.
721  *
722  * This function sets start address, element size, watermark, operation mode
723  * and datafield size of the recieve fifo 1.
724  *
725  * @param base MCAN peripheral base address.
726  * @param config The receive fifo 1 configuration structure.
727  */
728 void MCAN_SetRxFifo1Config(CAN_Type *base, const mcan_rx_fifo_config_t *config);
729 
730 /*!
731  * @brief Configures an MCAN receive buffer.
732  *
733  * This function sets start address and datafield size of the recieve buffer.
734  *
735  * @param base MCAN peripheral base address.
736  * @param config The receive buffer configuration structure.
737  */
738 void MCAN_SetRxBufferConfig(CAN_Type *base, const mcan_rx_buffer_config_t *config);
739 
740 /*!
741  * @brief Configures an MCAN transmit event fifo.
742  *
743  * This function sets start address, element size, watermark of the transmit event fifo.
744  *
745  * @param base MCAN peripheral base address.
746  * @param config The transmit event fifo configuration structure.
747  */
748 void MCAN_SetTxEventFifoConfig(CAN_Type *base, const mcan_tx_fifo_config_t *config);
749 
750 /*!
751  * @brief Configures an MCAN transmit buffer.
752  *
753  * This function sets start address, element size, fifo/queue mode and datafield
754  * size of the transmit buffer.
755  *
756  * @param base MCAN peripheral base address.
757  * @param config The transmit buffer configuration structure.
758  */
759 void MCAN_SetTxBufferConfig(CAN_Type *base, const mcan_tx_buffer_config_t *config);
760 
761 /*!
762  * @brief Set filter configuration.
763  *
764  * This function sets remote and non masking frames in global filter configuration,
765  * also the start address, list size in standard/extended ID filter configuration.
766  *
767  * @param base MCAN peripheral base address.
768  * @param config The MCAN filter configuration.
769  */
770 void MCAN_SetFilterConfig(CAN_Type *base, const mcan_frame_filter_config_t *config);
771 
772 /*!
773  * @brief Set Message RAM related configuration.
774  *
775  * @note This function include Standard/extended ID filter, Rx FIFO 0/1, Rx buffer, Tx event FIFO and Tx buffer
776  *      configurations
777  * @param base MCAN peripheral base address.
778  * @param config The MCAN filter configuration.
779  * @retval kStatus_Success - Message RAM related configuration Successfully.
780  * @retval kStatus_Fail    - Message RAM related configure fail due to wrong address parameter.
781  */
782 status_t MCAN_SetMessageRamConfig(CAN_Type *base, const mcan_memory_config_t *config);
783 
784 /*!
785  * @brief Set standard message ID filter element configuration.
786  *
787  * @param base MCAN peripheral base address.
788  * @param config The MCAN filter configuration.
789  * @param filter The MCAN standard message ID filter element configuration.
790  * @param idx The standard message ID filter element index.
791  */
792 void MCAN_SetSTDFilterElement(CAN_Type *base,
793                               const mcan_frame_filter_config_t *config,
794                               const mcan_std_filter_element_config_t *filter,
795                               uint8_t idx);
796 
797 /*!
798  * @brief Set extended message ID filter element configuration.
799  *
800  * @param base MCAN peripheral base address.
801  * @param config The MCAN filter configuration.
802  * @param filter The MCAN extended message ID filter element configuration.
803  * @param idx The extended message ID filter element index.
804  */
805 void MCAN_SetEXTFilterElement(CAN_Type *base,
806                               const mcan_frame_filter_config_t *config,
807                               const mcan_ext_filter_element_config_t *filter,
808                               uint8_t idx);
809 
810 /*!
811  * @name Status
812  * @{
813  */
814 
815 /*!
816  * @brief Gets the MCAN module interrupt flags.
817  *
818  * This function gets all MCAN interrupt status flags.
819  *
820  * @param base MCAN peripheral base address.
821  * @param mask The ORed MCAN interrupt mask.
822  * @return MCAN status flags which are ORed.
823  */
MCAN_GetStatusFlag(CAN_Type * base,uint32_t mask)824 static inline uint32_t MCAN_GetStatusFlag(CAN_Type *base, uint32_t mask)
825 {
826     return (base->IR & mask);
827 }
828 
829 /*!
830  * @brief Clears the MCAN module interrupt flags.
831  *
832  * This function clears MCAN interrupt status flags.
833  *
834  * @param base MCAN peripheral base address.
835  * @param mask The ORed MCAN interrupt mask.
836  */
MCAN_ClearStatusFlag(CAN_Type * base,uint32_t mask)837 static inline void MCAN_ClearStatusFlag(CAN_Type *base, uint32_t mask)
838 {
839     /* Write 1 to clear status flag, write 0 has no effect. */
840     base->IR = mask;
841 }
842 
843 /*!
844  * @brief Gets the new data flag of specific Rx Buffer.
845  *
846  * This function gets new data flag of specific Rx Buffer.
847  *
848  * @param base MCAN peripheral base address.
849  * @param idx Rx Buffer index.
850  * @return Rx Buffer new data status flag.
851  */
MCAN_GetRxBufferStatusFlag(CAN_Type * base,uint8_t idx)852 static inline bool MCAN_GetRxBufferStatusFlag(CAN_Type *base, uint8_t idx)
853 {
854     assert(idx <= 63U);
855 
856     bool fgRet;
857 
858     if (idx <= 31U)
859     {
860         fgRet = (0U != (base->NDAT1 & ((uint32_t)1U << idx)));
861     }
862     else
863     {
864         fgRet = (0U != (base->NDAT2 & ((uint32_t)1U << (idx - 32U))));
865     }
866 
867     return fgRet;
868 }
869 
870 /*!
871  * @brief Clears the new data flag of specific Rx Buffer.
872  *
873  * This function clears new data flag of specific Rx Buffer.
874  *
875  * @param base MCAN peripheral base address.
876  * @param idx Rx Buffer index.
877  */
MCAN_ClearRxBufferStatusFlag(CAN_Type * base,uint8_t idx)878 static inline void MCAN_ClearRxBufferStatusFlag(CAN_Type *base, uint8_t idx)
879 {
880     assert(idx <= 63U);
881 
882     if (idx <= 31U)
883     {
884         base->NDAT1 = ((uint32_t)1U << idx);
885     }
886     else
887     {
888         base->NDAT2 = ((uint32_t)1U << (idx - 32U));
889     }
890 }
891 
892 /*! @} */
893 
894 /*!
895  * @name Interrupts
896  * @{
897  */
898 
899 /*!
900  * @brief Enables MCAN interrupts according to the provided interrupt line and mask.
901  *
902  * This function enables the MCAN interrupts according to the provided interrupt line and mask.
903  * The mask is a logical OR of enumeration members.
904  *
905  * @param base MCAN peripheral base address.
906  * @param line Interrupt line number, 0 or 1.
907  * @param mask The interrupts to enable.
908  */
MCAN_EnableInterrupts(CAN_Type * base,uint32_t line,uint32_t mask)909 static inline void MCAN_EnableInterrupts(CAN_Type *base, uint32_t line, uint32_t mask)
910 {
911     base->ILE |= ((uint32_t)1U << line);
912     if (0U == line)
913     {
914         base->ILS &= ~mask;
915     }
916     else
917     {
918         base->ILS |= mask;
919     }
920     base->IE |= mask;
921 }
922 
923 /*!
924  * @brief Enables MCAN Tx Buffer interrupts according to the provided index.
925  *
926  * This function enables the MCAN Tx Buffer interrupts.
927  *
928  * @param base MCAN peripheral base address.
929  * @param idx Tx Buffer index.
930  */
MCAN_EnableTransmitBufferInterrupts(CAN_Type * base,uint8_t idx)931 static inline void MCAN_EnableTransmitBufferInterrupts(CAN_Type *base, uint8_t idx)
932 {
933     base->TXBTIE |= ((uint32_t)1U << idx);
934 }
935 
936 /*!
937  * @brief Disables MCAN Tx Buffer interrupts according to the provided index.
938  *
939  * This function disables the MCAN Tx Buffer interrupts.
940  *
941  * @param base MCAN peripheral base address.
942  * @param idx Tx Buffer index.
943  */
MCAN_DisableTransmitBufferInterrupts(CAN_Type * base,uint8_t idx)944 static inline void MCAN_DisableTransmitBufferInterrupts(CAN_Type *base, uint8_t idx)
945 {
946     base->TXBTIE &= (~((uint32_t)1U << idx));
947 }
948 
949 /*!
950  * @brief Disables MCAN interrupts according to the provided mask.
951  *
952  * This function disables the MCAN interrupts according to the provided mask.
953  * The mask is a logical OR of enumeration members.
954  *
955  * @param base MCAN peripheral base address.
956  * @param mask The interrupts to disable.
957  */
MCAN_DisableInterrupts(CAN_Type * base,uint32_t mask)958 static inline void MCAN_DisableInterrupts(CAN_Type *base, uint32_t mask)
959 {
960     base->IE &= ~mask;
961 }
962 
963 /*! @} */
964 
965 /*!
966  * @name Bus Operations
967  * @{
968  */
969 
970 /*!
971  * @brief Gets the Tx buffer request pending status.
972  *
973  * This function returns Tx Message Buffer transmission request pending status.
974  *
975  * @param base MCAN peripheral base address.
976  * @param idx The MCAN Tx Buffer index.
977  */
978 uint32_t MCAN_IsTransmitRequestPending(CAN_Type *base, uint8_t idx);
979 
980 /*!
981  * @brief Gets the Tx buffer transmission occurred status.
982  *
983  * This function returns Tx Message Buffer transmission occurred status.
984  *
985  * @param base MCAN peripheral base address.
986  * @param idx The MCAN Tx Buffer index.
987  */
988 uint32_t MCAN_IsTransmitOccurred(CAN_Type *base, uint8_t idx);
989 
990 /*!
991  * @brief Writes an MCAN Message to the Transmit Buffer.
992  *
993  * This function writes a CAN Message to the specified Transmit Message Buffer
994  * and changes the Message Buffer state to start CAN Message transmit. After
995  * that the function returns immediately.
996  *
997  * @param base MCAN peripheral base address.
998  * @param idx The MCAN Tx Buffer index.
999  * @param pTxFrame Pointer to CAN message frame to be sent.
1000  */
1001 status_t MCAN_WriteTxBuffer(CAN_Type *base, uint8_t idx, const mcan_tx_buffer_frame_t *pTxFrame);
1002 
1003 /*!
1004  * @brief Reads an MCAN Message from Rx Buffer.
1005  *
1006  * This function reads a CAN message from the Rx Buffer in the Message RAM.
1007  *
1008  * @param base MCAN peripheral base address.
1009  * @param idx The MCAN Rx Buffer index.
1010  * @param pRxFrame Pointer to CAN message frame structure for reception.
1011  * @retval kStatus_Success - Read Message from Rx Buffer successfully.
1012  */
1013 status_t MCAN_ReadRxBuffer(CAN_Type *base, uint8_t idx, mcan_rx_buffer_frame_t *pRxFrame);
1014 
1015 /*!
1016  * @brief Reads an MCAN Message from Rx FIFO.
1017  *
1018  * This function reads a CAN message from the Rx FIFO in the Message RAM.
1019  *
1020  * @param base MCAN peripheral base address.
1021  * @param fifoBlock Rx FIFO block 0 or 1.
1022  * @param pRxFrame Pointer to CAN message frame structure for reception.
1023  * @retval kStatus_Success - Read Message from Rx FIFO successfully.
1024  */
1025 status_t MCAN_ReadRxFifo(CAN_Type *base, uint8_t fifoBlock, mcan_rx_buffer_frame_t *pRxFrame);
1026 
1027 /*! @} */
1028 
1029 /*!
1030  * @name Transactional
1031  * @{
1032  */
1033 
1034 /*!
1035  * @brief Tx Buffer add request to send message out.
1036  *
1037  * This function add sending request to corresponding Tx Buffer.
1038  *
1039  * @param base MCAN peripheral base address.
1040  * @param idx Tx Buffer index.
1041  */
MCAN_TransmitAddRequest(CAN_Type * base,uint8_t idx)1042 static inline void MCAN_TransmitAddRequest(CAN_Type *base, uint8_t idx)
1043 {
1044     base->TXBAR = ((uint32_t)1U << idx);
1045 }
1046 
1047 /*!
1048  * @brief Tx Buffer cancel sending request.
1049  *
1050  * This function clears Tx buffer request pending bit.
1051  *
1052  * @param base MCAN peripheral base address.
1053  * @param idx Tx Buffer index.
1054  */
MCAN_TransmitCancelRequest(CAN_Type * base,uint8_t idx)1055 static inline void MCAN_TransmitCancelRequest(CAN_Type *base, uint8_t idx)
1056 {
1057     base->TXBCR = ((uint32_t)1U << idx);
1058 }
1059 
1060 /*!
1061  * @brief Performs a polling send transaction on the CAN bus.
1062  *
1063  * Note that a transfer handle does not need to be created  before calling this API.
1064  *
1065  * @param base MCAN peripheral base pointer.
1066  * @param idx The MCAN buffer index.
1067  * @param pTxFrame Pointer to CAN message frame to be sent.
1068  * @retval kStatus_Success - Write Tx Message Buffer Successfully.
1069  * @retval kStatus_Fail    - Tx Message Buffer is currently in use.
1070  */
1071 status_t MCAN_TransferSendBlocking(CAN_Type *base, uint8_t idx, mcan_tx_buffer_frame_t *pTxFrame);
1072 
1073 /*!
1074  * @brief Performs a polling receive transaction on the CAN bus.
1075  *
1076  * Note that a transfer handle does not need to be created  before calling this API.
1077  *
1078  * @param base MCAN peripheral base pointer.
1079  * @param idx The MCAN buffer index.
1080  * @param pRxFrame Pointer to CAN message frame structure for reception.
1081  * @retval kStatus_Success - Read Rx Message Buffer Successfully.
1082  * @retval kStatus_Fail    - No new message.
1083  */
1084 status_t MCAN_TransferReceiveBlocking(CAN_Type *base, uint8_t idx, mcan_rx_buffer_frame_t *pRxFrame);
1085 
1086 /*!
1087  * @brief Performs a polling receive transaction from Rx FIFO on the CAN bus.
1088  *
1089  * Note that a transfer handle does not need to be created before calling this API.
1090  *
1091  * @param base MCAN peripheral base pointer.
1092  * @param fifoBlock Rx FIFO block, 0 or 1.
1093  * @param pRxFrame Pointer to CAN message frame structure for reception.
1094  * @retval kStatus_Success - Read Message from Rx FIFO successfully.
1095  * @retval kStatus_Fail    - No new message in Rx FIFO.
1096  */
1097 status_t MCAN_TransferReceiveFifoBlocking(CAN_Type *base, uint8_t fifoBlock, mcan_rx_buffer_frame_t *pRxFrame);
1098 
1099 /*!
1100  * @brief Initializes the MCAN handle.
1101  *
1102  * This function initializes the MCAN handle, which can be used for other MCAN
1103  * transactional APIs. Usually, for a specified MCAN instance,
1104  * call this API once to get the initialized handle.
1105  *
1106  * @param base MCAN peripheral base address.
1107  * @param handle MCAN handle pointer.
1108  * @param callback The callback function.
1109  * @param userData The parameter of the callback function.
1110  */
1111 void MCAN_TransferCreateHandle(CAN_Type *base,
1112                                mcan_handle_t *handle,
1113                                mcan_transfer_callback_t callback,
1114                                void *userData);
1115 
1116 /*!
1117  * @brief Sends a message using IRQ.
1118  *
1119  * This function sends a message using IRQ. This is a non-blocking function, which returns
1120  * right away. When messages have been sent out, the send callback function is called.
1121  *
1122  * @param base MCAN peripheral base address.
1123  * @param handle MCAN handle pointer.
1124  * @param xfer MCAN Buffer transfer structure. See the #mcan_buffer_transfer_t.
1125  * @retval kStatus_Success        Start Tx Buffer sending process successfully.
1126  * @retval kStatus_Fail           Write Tx Buffer failed.
1127  * @retval kStatus_MCAN_TxBusy Tx Buffer is in use.
1128  */
1129 status_t MCAN_TransferSendNonBlocking(CAN_Type *base, mcan_handle_t *handle, mcan_buffer_transfer_t *xfer);
1130 
1131 /*!
1132  * @brief Receives a message from Rx FIFO using IRQ.
1133  *
1134  * This function receives a message using IRQ. This is a non-blocking function, which returns
1135  * right away. When all messages have been received, the receive callback function is called.
1136  *
1137  * @param base MCAN peripheral base address.
1138  * @param handle MCAN handle pointer.
1139  * @param fifoBlock Rx FIFO block, 0 or 1.
1140  * @param xfer MCAN Rx FIFO transfer structure. See the @ref mcan_fifo_transfer_t.
1141  * @retval kStatus_Success            - Start Rx FIFO receiving process successfully.
1142  * @retval kStatus_MCAN_RxFifo0Busy - Rx FIFO 0 is currently in use.
1143  * @retval kStatus_MCAN_RxFifo1Busy - Rx FIFO 1 is currently in use.
1144  */
1145 status_t MCAN_TransferReceiveFifoNonBlocking(CAN_Type *base,
1146                                              uint8_t fifoBlock,
1147                                              mcan_handle_t *handle,
1148                                              mcan_fifo_transfer_t *xfer);
1149 
1150 /*!
1151  * @brief Aborts the interrupt driven message send process.
1152  *
1153  * This function aborts the interrupt driven message send process.
1154  *
1155  * @param base MCAN peripheral base address.
1156  * @param handle MCAN handle pointer.
1157  * @param bufferIdx The MCAN Buffer index.
1158  */
1159 void MCAN_TransferAbortSend(CAN_Type *base, mcan_handle_t *handle, uint8_t bufferIdx);
1160 
1161 /*!
1162  * @brief Aborts the interrupt driven message receive from Rx FIFO process.
1163  *
1164  * This function aborts the interrupt driven message receive from Rx FIFO process.
1165  *
1166  * @param base MCAN peripheral base address.
1167  * @param fifoBlock MCAN Fifo block, 0 or 1.
1168  * @param handle MCAN handle pointer.
1169  */
1170 void MCAN_TransferAbortReceiveFifo(CAN_Type *base, uint8_t fifoBlock, mcan_handle_t *handle);
1171 
1172 /*!
1173  * @brief MCAN IRQ handle function.
1174  *
1175  * This function handles the MCAN Error, the Buffer, and the Rx FIFO IRQ request.
1176  *
1177  * @param base MCAN peripheral base address.
1178  * @param handle MCAN handle pointer.
1179  */
1180 void MCAN_TransferHandleIRQ(CAN_Type *base, mcan_handle_t *handle);
1181 
1182 /*! @} */
1183 
1184 #if defined(__cplusplus)
1185 }
1186 #endif
1187 
1188 /*! @}*/
1189 
1190 #endif /* FSL_MCAN_H_ */
1191