1 /*
2  * Copyright 2017-2020, 2023 NXP
3  * All rights reserved.
4  *
5  * SPDX-License-Identifier: BSD-3-Clause
6  */
7 #ifndef _FSL_MSCAN_H_
8 #define _FSL_MSCAN_H_
9 
10 #include "fsl_common.h"
11 
12 /*!
13  * @addtogroup mscan_driver
14  * @{
15  */
16 
17 /******************************************************************************
18  * Definitions
19  *****************************************************************************/
20 
21 /*! @name Driver version */
22 /*@{*/
23 /*! @brief MsCAN driver version. */
24 #define FSL_MSCAN_DRIVER_VERSION (MAKE_VERSION(2, 1, 0))
25 /*@}*/
26 
27 /*! @brief MsCAN Rx Message Buffer Mask helper macro. */
28 #define MSCAN_RX_MB_STD_MASK(id)               \
29     ((uint32_t)((((uint32_t)(id)&0x7) << 21) | \
30                 ((((uint32_t)(id) >> 3) & 0xFF) << 24))) /*!< Standard Rx Message Buffer Mask helper macro. */
31 #define MSCAN_RX_MB_EXT_MASK(id)                                                                   \
32     ((uint32_t)(((((uint32_t)(id) >> 21) & 0xFF) << 24) | ((((uint32_t)(id) >> 18) & 0x7) << 21) | \
33                 ((((uint32_t)(id) >> 15) & 0x7) << 16) | (((((uint32_t)(id) >> 7) & 0xFF)) << 8) | \
34                 (((uint32_t)(id)&0x7F) << 1))) /*!< Extend Rx Message Buffer Mask helper macro. */
35 
36 /*! @brief FlexCAN transfer status. */
37 enum
38 {
39     kStatus_MSCAN_TxBusy       = MAKE_STATUS(kStatusGroup_MSCAN, 0), /*!< Tx Message Buffer is Busy. */
40     kStatus_MSCAN_TxIdle       = MAKE_STATUS(kStatusGroup_MSCAN, 1), /*!< Tx Message Buffer is Idle. */
41     kStatus_MSCAN_TxSwitchToRx = MAKE_STATUS(
42         kStatusGroup_MSCAN, 2), /*!< Remote Message is send out and Message buffer changed to Receive one. */
43     kStatus_MSCAN_RxBusy          = MAKE_STATUS(kStatusGroup_MSCAN, 3),  /*!< Rx Message Buffer is Busy. */
44     kStatus_MSCAN_RxIdle          = MAKE_STATUS(kStatusGroup_MSCAN, 4),  /*!< Rx Message Buffer is Idle. */
45     kStatus_MSCAN_RxOverflow      = MAKE_STATUS(kStatusGroup_MSCAN, 5),  /*!< Rx Message Buffer is Overflowed. */
46     kStatus_MSCAN_RxFifoBusy      = MAKE_STATUS(kStatusGroup_MSCAN, 6),  /*!< Rx Message FIFO is Busy. */
47     kStatus_MSCAN_RxFifoIdle      = MAKE_STATUS(kStatusGroup_MSCAN, 7),  /*!< Rx Message FIFO is Idle. */
48     kStatus_MSCAN_RxFifoOverflow  = MAKE_STATUS(kStatusGroup_MSCAN, 8),  /*!< Rx Message FIFO is overflowed. */
49     kStatus_MSCAN_RxFifoWarning   = MAKE_STATUS(kStatusGroup_MSCAN, 9),  /*!< Rx Message FIFO is almost overflowed. */
50     kStatus_MSCAN_ErrorStatus     = MAKE_STATUS(kStatusGroup_MSCAN, 10), /*!< FlexCAN Module Error and Status. */
51     kStatus_MSCAN_UnHandled       = MAKE_STATUS(kStatusGroup_MSCAN, 11), /*!< UnHadled Interrupt asserted. */
52     kStatus_MSCAN_DataLengthError = MAKE_STATUS(kStatusGroup_MSCAN, 12), /*!< Frame data length is wrong. */
53 };
54 
55 /*! @brief MsCAN frame format. */
56 typedef enum _mscan_frame_format
57 {
58     kMSCAN_FrameFormatStandard = 0x0U, /*!< Standard frame format attribute. */
59     kMSCAN_FrameFormatExtend   = 0x1U, /*!< Extend frame format attribute. */
60 } mscan_frame_format_t;
61 
62 /*! @brief MsCAN frame type. */
63 typedef enum _mscan_frame_type
64 {
65     kMSCAN_FrameTypeData   = 0x0U, /*!< Data frame type attribute. */
66     kMSCAN_FrameTypeRemote = 0x1U, /*!< Remote frame type attribute. */
67 } mscan_frame_type_t;
68 
69 /*! @brief MsCAN clock source. */
70 typedef enum _mscan_clock_source
71 {
72     kMSCAN_ClkSrcOsc = 0x0U, /*!< MsCAN Protocol Engine clock from Oscillator. */
73     kMSCAN_ClkSrcBus = 0x1U, /*!< MsCAN Protocol Engine clock from Bus Clock. */
74 } mscan_clock_source_t;
75 
76 /*! @brief MsCAN bus-off recovery mode. */
77 typedef enum _mscan_busoffrec_mode
78 {
79     kMSCAN_BusoffrecAuto = 0x0U, /*!< MsCAN automatic bus-off recovery. */
80     kMSCAN_BusoffrecUsr  = 0x1U, /*!< MsCAN bus-off recovery upon user request. */
81 } mscan_busoffrec_mode_t;
82 
83 /*! @brief MsCAN Tx buffer empty flag. */
84 enum _mscan_tx_buffer_empty_flag
85 {
86     kMSCAN_TxBuf0Empty = 0x1U, /*!< MsCAN Tx Buffer 0 empty. */
87     kMSCAN_TxBuf1Empty = 0x2U, /*!< MsCAN Tx Buffer 1 empty. */
88     kMSCAN_TxBuf2Empty = 0x4U, /*!< MsCAN Tx Buffer 2 empty. */
89     kMSCAN_TxBufFull   = 0x0U, /*!< MsCAN Tx Buffer all not empty. */
90 };
91 
92 /*! @brief MsCAN id filter mode. */
93 typedef enum _mscan_id_filter_mode
94 {
95     kMSCAN_Filter32Bit = 0x0U, /*!< Two 32-bit acceptance filters. */
96     kMSCAN_Filter16Bit = 0x1U, /*!< Four 16-bit acceptance filters. */
97     kMSCAN_Filter8Bit  = 0x2U, /*!< Eight 8-bit acceptance filters. */
98     kMSCAN_FilterClose = 0x3U, /*!< Filter closed. */
99 } mscan_id_filter_mode_t;
100 
101 /*!
102  * @brief MsCAN interrupt configuration structure, default settings all disabled.
103  *
104  * This structure contains the settings for all of the MsCAN Module interrupt configurations.
105  */
106 enum _mscan_interrupt_enable
107 {
108     kMSCAN_WakeUpInterruptEnable         = MSCAN_CANRIER_WUPIE_MASK,  /*!< Wake Up interrupt. */
109     kMSCAN_StatusChangeInterruptEnable   = MSCAN_CANRIER_CSCIE_MASK,  /*!< Status change interrupt. */
110     kMSCAN_RxStatusChangeInterruptEnable = MSCAN_CANRIER_RSTATE_MASK, /*!< Rx status change interrupt. */
111     kMSCAN_TxStatusChangeInterruptEnable = MSCAN_CANRIER_TSTATE_MASK, /*!< Tx status change interrupt. */
112     kMSCAN_OverrunInterruptEnable        = MSCAN_CANRIER_OVRIE_MASK,  /*!< Overrun interrupt. */
113     kMSCAN_RxFullInterruptEnable         = MSCAN_CANRIER_RXFIE_MASK,  /*!< Rx buffer full interrupt. */
114     kMSCAN_TxEmptyInterruptEnable        = MSCAN_CANTIER_TXEIE_MASK,  /*!< Tx buffer empty interrupt. */
115 };
116 
117 #if defined(__CC_ARM)
118 #pragma anon_unions
119 #endif
120 
121 /*! @brief MSCAN IDR1 struct. */
122 typedef struct
123 {
124     uint8_t EID17_15 : 3;           /*!< Extended Format Identifier 17-15*/
125     uint8_t R_TEIDE : 1;            /*!< ID Extended */
126     uint8_t R_TSRR : 1;             /*!< Substitute Remote Request */
127     uint8_t EID20_18_OR_SID2_0 : 3; /*!< Extended Format Identifier 18-20 or standard format bit 0-2*/
128 } MSCAN_IDR1Type;
129 
130 /*! @brief MSCAN IDR3 struct. */
131 typedef struct
132 {
133     uint8_t ERTR : 1;   /*!< Remote Transmission Request*/
134     uint8_t EID6_0 : 7; /*!< Extended Format Identifier 6-0*/
135 } MSCAN_IDR3Type;
136 
137 /*! @brief MSCAN idr1 and idr3 union. */
138 typedef union
139 {
140     MSCAN_IDR1Type IDR1; /*!< structure for identifier 1 */
141     MSCAN_IDR3Type IDR3; /*!< structure for identifier 3 */
142     uint8_t Bytes;       /*!< bytes */
143 } IDR1_3_UNION;
144 
145 /*! @brief MSCAN extend ID struct. */
146 typedef struct
147 {
148     uint32_t EID6_0 : 7;   /*!< ID[0:6] */
149     uint32_t EID14_7 : 8;  /*!< ID[14:7] */
150     uint32_t EID17_15 : 3; /*!< ID[17:15] */
151     uint32_t EID20_18 : 3; /*!< ID[20:18] */
152     uint32_t EID28_21 : 8; /*!< ID[28:21] */
153     uint32_t rsvd : 3;
154 } MSCAN_ExtendIDType;
155 
156 /*! @brief MSCAN standard ID struct. */
157 typedef struct
158 {
159     uint32_t EID2_0 : 3;  /*!< ID[0:2] */
160     uint32_t EID10_3 : 8; /*!< ID[10:3] */
161     uint32_t rsvd : 21;
162 } MSCAN_StandardIDType;
163 
164 /*! @brief MsCAN message buffer structure. */
165 typedef struct _mscan_mb
166 {
167     uint8_t EIDR0;   /*!< Extended Identifier Register 0 */
168     uint8_t EIDR1;   /*!< Extended Identifier Register 1 */
169     uint8_t EIDR2;   /*!< Extended Identifier Register 2 */
170     uint8_t EIDR3;   /*!< Extended Identifier Register 3 */
171     uint8_t EDSR[8]; /*!< Extended Data Segment Register */
172     uint8_t DLR;     /*!< data length field */
173     uint8_t BPR;     /*!< Buffer Priority Register */
174     uint8_t TSRH;    /*!< Time Stamp Register High */
175     uint8_t TSRL;    /*!< Time Stamp Register Low */
176 } mscan_mb_t;
177 
178 /*! @brief MsCAN frame structure. */
179 typedef struct _mscan_frame
180 {
181     union
182     {
183         MSCAN_StandardIDType StdID; /*!< standard format */
184         MSCAN_ExtendIDType ExtID;   /*!< extend format */
185         uint32_t ID;                /*!< Identifire with 32 bit format */
186     } ID_Type;                      /*!< identifier union */
187     union
188     {
189         uint8_t DSR[8]; /*!< data segment */
190         struct
191         {
192             uint32_t dataWord0; /*!< MSCAN Frame payload word0. */
193             uint32_t dataWord1; /*!< MSCAN Frame payload word1. */
194         };
195         struct
196         {
197             uint8_t dataByte0; /*!< MSCAN Frame payload byte0. */
198             uint8_t dataByte1; /*!< MSCAN Frame payload byte1. */
199             uint8_t dataByte2; /*!< MSCAN Frame payload byte2. */
200             uint8_t dataByte3; /*!< MSCAN Frame payload byte3. */
201             uint8_t dataByte4; /*!< MSCAN Frame payload byte4. */
202             uint8_t dataByte5; /*!< MSCAN Frame payload byte5. */
203             uint8_t dataByte6; /*!< MSCAN Frame payload byte6. */
204             uint8_t dataByte7; /*!< MSCAN Frame payload byte7. */
205         };
206     };
207     uint8_t DLR;                 /*!< data length */
208     uint8_t BPR;                 /*!< transmit buffer priority */
209     mscan_frame_type_t type;     /*!< remote frame or data frame */
210     mscan_frame_format_t format; /*!< extend frame or standard frame */
211     uint8_t TSRH;                /*!< time stamp high byte */
212     uint8_t TSRL;                /*!< time stamp low byte */
213 } mscan_frame_t;
214 
215 /*! @brief MsCAN module acceptance filter configuration structure. */
216 typedef struct _mscan_idfilter_config
217 {
218     mscan_id_filter_mode_t filterMode; /*!< MSCAN Identifier Acceptance Filter Mode */
219     uint32_t u32IDAR0;                 /*!< MSCAN Identifier Acceptance Register n of First Bank */
220     uint32_t u32IDAR1;                 /*!< MSCAN Identifier Acceptance Register n of Second Bank */
221     uint32_t u32IDMR0;                 /*!< MSCAN Identifier Mask Register n of First Bank */
222     uint32_t u32IDMR1;                 /*!< MSCAN Identifier Mask Register n of Second Bank */
223 } mscan_idfilter_config_t;
224 
225 /*! @brief MsCAN module configuration structure. */
226 typedef struct _mscan_config
227 {
228     uint32_t baudRate;                    /*!< MsCAN baud rate in bps. */
229     bool enableTimer;                     /*!< Enable or Disable free running timer. */
230     bool enableWakeup;                    /*!< Enable or Disable Wakeup Mode. */
231     mscan_clock_source_t clkSrc;          /*!< Clock source for MsCAN Protocol Engine. */
232     bool enableLoopBack;                  /*!< Enable or Disable Loop Back Self Test Mode. */
233     bool enableListen;                    /*!< Enable or Disable Listen Only Mode. */
234     mscan_busoffrec_mode_t busoffrecMode; /*!< Bus-Off Recovery Mode. */
235     mscan_idfilter_config_t filterConfig;
236 } mscan_config_t;
237 
238 /*! @brief MsCAN protocol timing characteristic configuration structure. */
239 typedef struct _mscan_timing_config
240 {
241     uint8_t priDiv;     /*!< Baud rate prescaler. */
242     uint8_t sJumpwidth; /*!< Sync Jump Width. */
243     uint8_t timeSeg1;   /*!< Time Segment 1. */
244     uint8_t timeSeg2;   /*!< Time Segment 2. */
245     uint8_t samp;       /*!< Number of samples per bit time. */
246 } mscan_timing_config_t;
247 
248 /*! @brief MSCAN Message Buffer transfer. */
249 typedef struct _mscan_mb_transfer
250 {
251     mscan_frame_t *frame; /*!< The buffer of CAN Message to be transfer. */
252     uint8_t mask;         /*!< The mask of Tx buffer. */
253 } mscan_mb_transfer_t;
254 
255 /*! @brief MsCAN handle structure definition. */
256 typedef struct _mscan_handle mscan_handle_t;
257 
258 /*! @brief MsCAN transfer callback function.
259  *
260  *  The MsCAN transfer callback returns a value from the underlying layer.
261  *  If the status equals to kStatus_MSCAN_ErrorStatus, the result parameter is the Content of
262  *  MsCAN status register which can be used to get the working status(or error status) of MsCAN module.
263  *  If the status equals to other MsCAN Message Buffer transfer status, the result is the index of
264  *  Message Buffer that generate transfer event.
265  *  If the status equals to other MsCAN Message Buffer transfer status, the result is meaningless and should be
266  *  Ignored.
267  *  If the status equals kStatus_MSCAN_DataLengthError, it means the received frame data length code (DLC) is wrong.
268  */
269 typedef void (*mscan_transfer_callback_t)(MSCAN_Type *base, mscan_handle_t *handle, status_t status, void *userData);
270 
271 /*! @brief MsCAN handle structure. */
272 struct _mscan_handle
273 {
274     mscan_transfer_callback_t callback; /*!< Callback function. */
275     void *userData;                     /*!< MsCAN callback function parameter.*/
276     mscan_frame_t *volatile mbFrameBuf;
277     /*!< The buffer for received data from Message Buffers. */
278     volatile uint8_t mbStateTx; /*!< Message Buffer transfer state. */
279     volatile uint8_t mbStateRx; /*!< Message Buffer transfer state. */
280 };
281 
282 /******************************************************************************
283  * API
284  *****************************************************************************/
285 
286 #if defined(__cplusplus)
287 extern "C" {
288 #endif
289 
290 /*!
291  * @name Initialization and deinitialization
292  * @{
293  */
294 
295 /*!
296  * @brief Initializes a MsCAN instance.
297  *
298  * This function initializes the MsCAN module with user-defined settings.
299  * This example shows how to set up the mscan_config_t parameters and how
300  * to call the MSCAN_Init function by passing in these parameters.
301  *  @code
302  *   mscan_config_t mscanConfig;
303  *   mscanConfig.clkSrc            = kMSCAN_ClkSrcOsc;
304  *   mscanConfig.baudRate          = 1250000U;
305  *   mscanConfig.enableTimer       = false;
306  *   mscanConfig.enableLoopBack    = false;
307  *   mscanConfig.enableWakeup      = false;
308  *   mscanConfig.enableListen      = false;
309  *   mscanConfig.busoffrecMode     = kMSCAN_BusoffrecAuto;
310  *   mscanConfig.filterConfig.filterMode = kMSCAN_Filter32Bit;
311  *   MSCAN_Init(MSCAN, &mscanConfig, 8000000UL);
312  *   @endcode
313  *
314  * @param base MsCAN peripheral base address.
315  * @param config Pointer to the user-defined configuration structure.
316  * @param sourceClock_Hz MsCAN Protocol Engine clock source frequency in Hz.
317  */
318 void MSCAN_Init(MSCAN_Type *base, const mscan_config_t *config, uint32_t sourceClock_Hz);
319 
320 /*!
321  * @brief De-initializes a MsCAN instance.
322  *
323  * This function disables the MsCAN module clock and sets all register values
324  * to the reset value.
325  *
326  * @param base MsCAN peripheral base address.
327  */
328 void MSCAN_Deinit(MSCAN_Type *base);
329 
330 /*!
331  * @brief Gets the default configuration structure.
332  *
333  * This function initializes the MsCAN configuration structure to default values.
334  *
335  * @param config Pointer to the MsCAN configuration structure.
336  */
337 void MSCAN_GetDefaultConfig(mscan_config_t *config);
338 
339 /* @} */
340 
341 /*!
342  * @name Configuration.
343  * @{
344  */
345 
346 /*!
347  * @brief Get the transmit buffer empty status.
348  *
349  * This flag indicates that the associated transmit message buffer is empty.
350  *
351  * @param base MsCAN peripheral base address.
352  */
MSCAN_GetTxBufferEmptyFlag(MSCAN_Type * base)353 static inline uint8_t MSCAN_GetTxBufferEmptyFlag(MSCAN_Type *base)
354 {
355     return base->CANTFLG & MSCAN_CANTFLG_TXE_MASK;
356 }
357 
358 /*!
359  * @brief The selection of the actual transmit message buffer.
360  *
361  * To get the next available transmit buffer, read the CANTFLG
362  * register and write its value back into the CANTBSEL register.
363  *
364  * @param base MsCAN peripheral base address.
365  * @param txBuf The value read from CANTFLG.
366  */
MSCAN_TxBufferSelect(MSCAN_Type * base,uint8_t txBuf)367 static inline void MSCAN_TxBufferSelect(MSCAN_Type *base, uint8_t txBuf)
368 {
369     base->CANTBSEL = MSCAN_CANTBSEL_TX(txBuf);
370 }
371 
372 /*!
373  * @brief Get the actual transmit message buffer.
374  *
375  * After write TFLG value back into the CANTBSEL register, read again CANBSEL
376  * to get the actual trasnsmit message buffer.
377  *
378  * @param base MsCAN peripheral base address.
379  */
MSCAN_GetTxBufferSelect(MSCAN_Type * base)380 static inline uint8_t MSCAN_GetTxBufferSelect(MSCAN_Type *base)
381 {
382     return base->CANTBSEL & MSCAN_CANTBSEL_TX_MASK;
383 }
384 
385 /*!
386  * @brief Clear TFLG to schedule for transmission.
387  *
388  * The CPU must clear the flag after a message is set up in the
389  * transmit buffer and is due for transmission.
390  *
391  * @param base MsCAN peripheral base address.
392  * @param txBuf Message buffer(s) to be cleared.
393  */
MSCAN_TxBufferLaunch(MSCAN_Type * base,uint8_t txBuf)394 static inline void MSCAN_TxBufferLaunch(MSCAN_Type *base, uint8_t txBuf)
395 {
396     base->CANTFLG = MSCAN_CANTFLG_TXE_MASK & txBuf;
397 }
398 
399 /*!
400  * @brief Get Tx buffer status flag.
401  *
402  * The bit is set after successful transmission.
403  *
404  * @param base MsCAN peripheral base address.
405  * @param mask Message buffer(s) mask.
406  */
MSCAN_GetTxBufferStatusFlags(MSCAN_Type * base,uint8_t mask)407 static inline uint8_t MSCAN_GetTxBufferStatusFlags(MSCAN_Type *base, uint8_t mask)
408 {
409     return base->CANTFLG & mask;
410 }
411 
412 /*!
413  * @brief Check Receive Buffer Full Flag.
414  *
415  * RXF is set by the MSCAN when a new message is shifted in the receiver FIFO.
416  * This flag indicates whether the shifted buffer is loaded with a correctly received message.
417  *
418  * @param base MsCAN peripheral base address.
419  */
MSCAN_GetRxBufferFullFlag(MSCAN_Type * base)420 static inline uint8_t MSCAN_GetRxBufferFullFlag(MSCAN_Type *base)
421 {
422     return base->CANRFLG & MSCAN_CANRFLG_RXF_MASK;
423 }
424 
425 /*!
426  * @brief Clear Receive buffer Full flag.
427  *
428  * After the CPU has read that message from the RxFG buffer in the receiver FIFO
429  * The RXF flag must be cleared to release the buffer.
430  *
431  * @param base MsCAN peripheral base address.
432  */
MSCAN_ClearRxBufferFullFlag(MSCAN_Type * base)433 static inline void MSCAN_ClearRxBufferFullFlag(MSCAN_Type *base)
434 {
435     base->CANRFLG |= MSCAN_CANRFLG_RXF_MASK;
436 }
437 
MSCAN_ReadRIDR0(MSCAN_Type * base)438 static inline uint8_t MSCAN_ReadRIDR0(MSCAN_Type *base)
439 {
440     return base->REIDR0;
441 }
442 
MSCAN_ReadRIDR1(MSCAN_Type * base)443 static inline uint8_t MSCAN_ReadRIDR1(MSCAN_Type *base)
444 {
445     return base->REIDR1;
446 }
447 
MSCAN_ReadRIDR2(MSCAN_Type * base)448 static inline uint8_t MSCAN_ReadRIDR2(MSCAN_Type *base)
449 {
450     return base->REIDR2;
451 }
452 
MSCAN_ReadRIDR3(MSCAN_Type * base)453 static inline uint8_t MSCAN_ReadRIDR3(MSCAN_Type *base)
454 {
455     return base->REIDR3;
456 }
457 
MSCAN_WriteTIDR0(MSCAN_Type * base,uint8_t id)458 static inline void MSCAN_WriteTIDR0(MSCAN_Type *base, uint8_t id)
459 {
460     base->TEIDR0 = id;
461 }
462 
MSCAN_WriteTIDR1(MSCAN_Type * base,uint8_t id)463 static inline void MSCAN_WriteTIDR1(MSCAN_Type *base, uint8_t id)
464 {
465     base->TEIDR1 = id;
466 }
467 
MSCAN_WriteTIDR2(MSCAN_Type * base,uint8_t id)468 static inline void MSCAN_WriteTIDR2(MSCAN_Type *base, uint8_t id)
469 {
470     base->TEIDR2 = id;
471 }
472 
MSCAN_WriteTIDR3(MSCAN_Type * base,uint8_t id)473 static inline void MSCAN_WriteTIDR3(MSCAN_Type *base, uint8_t id)
474 {
475     base->TEIDR3 = id;
476 }
477 
MSCAN_SetIDFilterMode(MSCAN_Type * base,mscan_id_filter_mode_t mode)478 static inline void MSCAN_SetIDFilterMode(MSCAN_Type *base, mscan_id_filter_mode_t mode)
479 {
480     base->CANIDAC |= MSCAN_CANIDAC_IDAM((uint8_t)mode);
481 }
482 
MSCAN_WriteIDAR0(MSCAN_Type * base,uint8_t * pID)483 static inline void MSCAN_WriteIDAR0(MSCAN_Type *base, uint8_t *pID)
484 {
485     base->CANIDAR_BANK_1[0] = pID[3];
486     base->CANIDAR_BANK_1[1] = pID[2];
487     base->CANIDAR_BANK_1[2] = pID[1];
488     base->CANIDAR_BANK_1[3] = pID[0];
489 }
490 
MSCAN_WriteIDAR1(MSCAN_Type * base,uint8_t * pID)491 static inline void MSCAN_WriteIDAR1(MSCAN_Type *base, uint8_t *pID)
492 {
493     base->CANIDAR_BANK_2[0] = pID[3];
494     base->CANIDAR_BANK_2[1] = pID[2];
495     base->CANIDAR_BANK_2[2] = pID[1];
496     base->CANIDAR_BANK_2[3] = pID[0];
497 }
498 
MSCAN_WriteIDMR0(MSCAN_Type * base,uint8_t * pID)499 static inline void MSCAN_WriteIDMR0(MSCAN_Type *base, uint8_t *pID)
500 {
501     base->CANIDMR_BANK_1[0] = pID[3];
502     base->CANIDMR_BANK_1[1] = pID[2];
503     base->CANIDMR_BANK_1[2] = pID[1];
504     base->CANIDMR_BANK_1[3] = pID[0];
505 }
506 
MSCAN_WriteIDMR1(MSCAN_Type * base,uint8_t * pID)507 static inline void MSCAN_WriteIDMR1(MSCAN_Type *base, uint8_t *pID)
508 {
509     base->CANIDMR_BANK_2[0] = pID[3];
510     base->CANIDMR_BANK_2[1] = pID[2];
511     base->CANIDMR_BANK_2[2] = pID[1];
512     base->CANIDMR_BANK_2[3] = pID[0];
513 }
514 
515 /*!
516  * @brief Sets the MsCAN protocol timing characteristic.
517  *
518  * This function gives user settings to CAN bus timing characteristic.
519  * The function is for an experienced user. For less experienced users, call
520  * the MSCAN_Init() and fill the baud rate field with a desired value.
521  * This provides the default timing characteristics to the module.
522  *
523  * Note that calling MSCAN_SetTimingConfig() overrides the baud rate set
524  * in MSCAN_Init().
525  *
526  * @param base MsCAN peripheral base address.
527  * @param config Pointer to the timing configuration structure.
528  */
529 void MSCAN_SetTimingConfig(MSCAN_Type *base, const mscan_timing_config_t *config);
530 
531 /* @} */
532 
533 /*!
534  * @name Status
535  * @{
536  */
537 
538 /*!
539  * @brief Gets the MsCAN Tx buffer empty flags.
540  *
541  * This function gets MsCAN Tx buffer empty flags. It's returned as the
542  * value of the enumerators @ref _mscan_tx_buffer_empty_flag.
543  *
544  * @param base MsCAN peripheral base address.
545  * @return Tx buffer empty flags in the _mscan_tx_buffer_empty_flag.
546  */
MSCAN_GetTxBufEmptyFlags(MSCAN_Type * base)547 static inline uint8_t MSCAN_GetTxBufEmptyFlags(MSCAN_Type *base)
548 {
549     return base->CANTFLG & MSCAN_CANTFLG_TXE_MASK;
550 }
551 
552 /* @} */
553 
554 /*!
555  * @name Interrupts
556  * @{
557  */
558 
559 /*!
560  * @brief Enables MsCAN Transmitter interrupts according to the provided mask.
561  *
562  * This function enables the MsCAN Tx empty interrupts according to the mask.
563  *
564  * @param base MsCAN peripheral base address.
565  * @param mask The Tx interrupts mask to enable.
566  */
MSCAN_EnableTxInterrupts(MSCAN_Type * base,uint8_t mask)567 static inline void MSCAN_EnableTxInterrupts(MSCAN_Type *base, uint8_t mask)
568 {
569     base->CANTIER |= mask;
570 }
571 
572 /*!
573  * @brief Disables MsCAN Transmitter interrupts according to the provided mask.
574  *
575  * This function disables the MsCAN Tx emtpy interrupts according to the mask.
576  *
577  * @param base MsCAN peripheral base address.
578  * @param mask The Tx interrupts mask to disable.
579  */
MSCAN_DisableTxInterrupts(MSCAN_Type * base,uint8_t mask)580 static inline void MSCAN_DisableTxInterrupts(MSCAN_Type *base, uint8_t mask)
581 {
582     base->CANTIER &= ~mask;
583 }
584 
585 /*!
586  * @brief Enables MsCAN Receiver interrupts according to the provided mask.
587  *
588  * This function enables the MsCAN Rx interrupts according to the provided mask
589  * which is a logical OR of enumeration members, see @ref _mscan_interrupt_enable.
590  *
591  * @param base MsCAN peripheral base address.
592  * @param mask The interrupts to enable. Logical OR of @ref _mscan_interrupt_enable.
593  */
MSCAN_EnableRxInterrupts(MSCAN_Type * base,uint8_t mask)594 static inline void MSCAN_EnableRxInterrupts(MSCAN_Type *base, uint8_t mask)
595 {
596     base->CANRIER |= mask;
597 }
598 
599 /*!
600  * @brief Disables MsCAN Receiver interrupts according to the provided mask.
601  *
602  * This function disables the MsCAN Rx interrupts according to the provided mask
603  * which is a logical OR of enumeration members, see @ref _mscan_interrupt_enable.
604  *
605  * @param base MsCAN peripheral base address.
606  * @param mask The interrupts to disable. Logical OR of @ref _mscan_interrupt_enable.
607  */
MSCAN_DisableRxInterrupts(MSCAN_Type * base,uint8_t mask)608 static inline void MSCAN_DisableRxInterrupts(MSCAN_Type *base, uint8_t mask)
609 {
610     base->CANRIER &= ~mask;
611 }
612 
613 /*!
614  * @brief Abort MsCAN Tx request.
615  *
616  * This function allows abort request of queued messages.
617  *
618  * @param base MsCAN peripheral base address.
619  * @param mask The Tx mask to abort.
620  */
MSCAN_AbortTxRequest(MSCAN_Type * base,uint8_t mask)621 static inline void MSCAN_AbortTxRequest(MSCAN_Type *base, uint8_t mask)
622 {
623     base->CANTARQ |= mask;
624 }
625 
626 /* @} */
627 
628 /*!
629  * @name Bus Operations
630  * @{
631  */
632 
633 /*!
634  * @brief Enables or disables the MsCAN module operation.
635  *
636  * This function enables or disables the MsCAN module.
637  *
638  * @param base MsCAN base pointer.
639  * @param enable true to enable, false to disable.
640  */
MSCAN_Enable(MSCAN_Type * base,bool enable)641 static inline void MSCAN_Enable(MSCAN_Type *base, bool enable)
642 {
643     if (enable)
644     {
645         base->CANCTL1 |= MSCAN_CANCTL1_CANE_MASK;
646     }
647     else
648     {
649         base->CANCTL1 &= ~((uint8_t)MSCAN_CANCTL1_CANE_MASK);
650     }
651 }
652 
653 /*!
654  * @brief Writes a MsCAN Message to the Transmit Message Buffer.
655  *
656  * This function writes a CAN Message to the specified Transmit Message Buffer
657  * and changes the Message Buffer state to start CAN Message transmit. After
658  * that the function returns immediately.
659  *
660  * @param base MsCAN peripheral base address.
661  * @param pTxFrame Pointer to CAN message frame to be sent.
662  * @retval kStatus_Success - Write Tx Message Buffer Successfully.
663  * @retval kStatus_Fail    - Tx Message Buffer is currently in use.
664  * @retval kStatus_MSCAN_DataLengthError - Tx Message Buffer data length is wrong.
665  */
666 status_t MSCAN_WriteTxMb(MSCAN_Type *base, mscan_frame_t *pTxFrame);
667 
668 /*!
669  * @brief Reads a MsCAN Message from Receive Message Buffer.
670  *
671  * This function reads a CAN message from a specified Receive Message Buffer.
672  * The function fills a receive CAN message frame structure with
673  * just received data and activates the Message Buffer again.
674  * The function returns immediately.
675  *
676  * @param base MsCAN peripheral base address.
677  * @param pRxFrame Pointer to CAN message frame structure for reception.
678  * @retval kStatus_Success            - Rx Message Buffer is full and has been read successfully.
679  * @retval kStatus_Fail               - Rx Message Buffer is empty.
680  * @retval kStatus_MSCAN_DataLengthError - Rx Message data length is wrong.
681  */
682 status_t MSCAN_ReadRxMb(MSCAN_Type *base, mscan_frame_t *pRxFrame);
683 
684 /* @} */
685 
686 /*!
687  * @name Transactional
688  * @{
689  */
690 
691 /*!
692  * @brief Initializes the MsCAN handle.
693  *
694  * This function initializes the MsCAN handle, which can be used for other MsCAN
695  * transactional APIs. Usually, for a specified MsCAN instance,
696  * call this API once to get the initialized handle.
697  *
698  * @param base MsCAN peripheral base address.
699  * @param handle MsCAN handle pointer.
700  * @param callback The callback function.
701  * @param userData The parameter of the callback function.
702  */
703 void MSCAN_TransferCreateHandle(MSCAN_Type *base,
704                                 mscan_handle_t *handle,
705                                 mscan_transfer_callback_t callback,
706                                 void *userData);
707 
708 /*!
709  * @brief Performs a polling send transaction on the CAN bus.
710  *
711  * Note that a transfer handle does not need to be created before calling this API.
712  *
713  * @param base MsCAN peripheral base pointer.
714  * @param pTxFrame Pointer to CAN message frame to be sent.
715  * @retval kStatus_Success - Write Tx Message Buffer Successfully.
716  * @retval kStatus_Fail    - Tx Message Buffer is currently in use.
717  * @retval kStatus_MSCAN_DataLengthError - Tx Message Buffer data length is wrong.
718  */
719 status_t MSCAN_TransferSendBlocking(MSCAN_Type *base, mscan_frame_t *pTxFrame);
720 
721 /*!
722  * @brief Performs a polling receive transaction on the CAN bus.
723  *
724  * Note that a transfer handle does not need to be created before calling this API.
725  *
726  * @param base MsCAN peripheral base pointer.
727  * @param pRxFrame Pointer to CAN message frame to be received.
728  * @retval kStatus_Success - Read Rx Message Buffer Successfully.
729  * @retval kStatus_Fail    - Tx Message Buffer is currently in use.
730  * @retval kStatus_MSCAN_DataLengthError - Rx Message data length is wrong.
731  */
732 status_t MSCAN_TransferReceiveBlocking(MSCAN_Type *base, mscan_frame_t *pRxFrame);
733 
734 /*!
735  * @brief Sends a message using IRQ.
736  *
737  * This function sends a message using IRQ. This is a non-blocking function, which returns
738  * right away. When messages have been sent out, the send callback function is called.
739  *
740  * @param base MsCAN peripheral base address.
741  * @param handle MsCAN handle pointer.
742  * @param xfer MsCAN Message Buffer transfer structure. See the #mscan_mb_transfer_t.
743  * @retval kStatus_Success        Start Tx Message Buffer sending process successfully.
744  * @retval kStatus_Fail           Write Tx Message Buffer failed.
745  * @retval kStatus_MSCAN_DataLengthError - Tx Message Buffer data length is wrong.
746  */
747 status_t MSCAN_TransferSendNonBlocking(MSCAN_Type *base, mscan_handle_t *handle, mscan_mb_transfer_t *xfer);
748 
749 /*!
750  * @brief Receives a message using IRQ.
751  *
752  * This function receives a message using IRQ. This is non-blocking function, which returns
753  * right away. When the message has been received, the receive callback function is called.
754  *
755  * @param base MsCAN peripheral base address.
756  * @param handle MsCAN handle pointer.
757  * @param xfer MsCAN Message Buffer transfer structure. See the #mscan_mb_transfer_t.
758  * @retval kStatus_Success        - Start Rx Message Buffer receiving process successfully.
759  * @retval kStatus_MSCAN_RxBusy - Rx Message Buffer is in use.
760  */
761 status_t MSCAN_TransferReceiveNonBlocking(MSCAN_Type *base, mscan_handle_t *handle, mscan_mb_transfer_t *xfer);
762 
763 /*!
764  * @brief Aborts the interrupt driven message send process.
765  *
766  * This function aborts the interrupt driven message send process.
767  *
768  * @param base MsCAN peripheral base address.
769  * @param handle MsCAN handle pointer.
770  * @param mask The MsCAN Tx Message Buffer mask.
771  */
772 void MSCAN_TransferAbortSend(MSCAN_Type *base, mscan_handle_t *handle, uint8_t mask);
773 
774 /*!
775  * @brief Aborts the interrupt driven message receive process.
776  *
777  * This function aborts the interrupt driven message receive process.
778  *
779  * @param base MsCAN peripheral base address.
780  * @param handle MsCAN handle pointer.
781  * @param mask The MsCAN Rx Message Buffer mask.
782  */
783 void MSCAN_TransferAbortReceive(MSCAN_Type *base, mscan_handle_t *handle, uint8_t mask);
784 
785 /*!
786  * @brief MSCAN IRQ handle function.
787  *
788  * This function handles the MSCAN Error, the Message Buffer, and the Rx FIFO IRQ request.
789  *
790  * @param base MSCAN peripheral base address.
791  * @param handle MSCAN handle pointer.
792  */
793 void MSCAN_TransferHandleIRQ(MSCAN_Type *base, mscan_handle_t *handle);
794 
795 /* @} */
796 
797 #if defined(__cplusplus)
798 }
799 #endif
800 
801 /*! @}*/
802 
803 #endif /* _FSL_MSCAN_H_ */