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_ */