Back to home page

LXR

 
 

    


File indexing completed on 2025-05-11 08:22:59

0001 /*
0002  * Copyright (c) 2015, Freescale Semiconductor, Inc.
0003  * Copyright 2016-2023 NXP
0004  * All rights reserved.
0005  *
0006  * SPDX-License-Identifier: BSD-3-Clause
0007  */
0008 
0009 #include "fsl_flexcan.h"
0010 
0011 /*******************************************************************************
0012  * Definitions
0013  ******************************************************************************/
0014 
0015 /* Component ID definition, used by tools. */
0016 #ifndef FSL_COMPONENT_ID
0017 #define FSL_COMPONENT_ID "platform.drivers.flexcan"
0018 #endif
0019 
0020 #if (defined(FSL_FEATURE_FLEXCAN_HAS_ERRATA_6032) && FSL_FEATURE_FLEXCAN_HAS_ERRATA_6032)
0021 #define RXINTERMISSION (CAN_DBG1_CFSM(0x2f))
0022 #define TXINTERMISSION (CAN_DBG1_CFSM(0x14))
0023 #define BUSIDLE        (CAN_DBG1_CFSM(0x02))
0024 #define CBN_VALUE3     (CAN_DBG1_CBN(0x03))
0025 #define DELAY_BUSIDLE  (200)
0026 #endif
0027 
0028 /* According to CiA doc 1301 v1.0.0, specified data/nominal phase sample point postion for CAN FD at 80 MHz. */
0029 #define IDEAL_DATA_SP_1  (800U)
0030 #define IDEAL_DATA_SP_2  (750U)
0031 #define IDEAL_DATA_SP_3  (700U)
0032 #define IDEAL_DATA_SP_4  (625U)
0033 #define IDEAL_NOMINAL_SP (800U)
0034 
0035 /* According to CiA doc 301 v4.2.0 and previous version. */
0036 #define IDEAL_SP_LOW  (750U)
0037 #define IDEAL_SP_MID  (800U)
0038 #define IDEAL_SP_HIGH (875U)
0039 
0040 #define IDEAL_SP_FACTOR (1000U)
0041 
0042 /* Define the max value of bit timing segments when use different timing register. */
0043 #define MAX_PROPSEG           (CAN_CTRL1_PROPSEG_MASK >> CAN_CTRL1_PROPSEG_SHIFT)
0044 #define MAX_PSEG1             (CAN_CTRL1_PSEG1_MASK >> CAN_CTRL1_PSEG1_SHIFT)
0045 #define MAX_PSEG2             (CAN_CTRL1_PSEG2_MASK >> CAN_CTRL1_PSEG2_SHIFT)
0046 #define MAX_RJW               (CAN_CTRL1_RJW_MASK >> CAN_CTRL1_RJW_SHIFT)
0047 #define MAX_PRESDIV           (CAN_CTRL1_PRESDIV_MASK >> CAN_CTRL1_PRESDIV_SHIFT)
0048 #define CTRL1_MAX_TIME_QUANTA (1U + MAX_PROPSEG + 1U + MAX_PSEG1 + 1U + MAX_PSEG2 + 1U)
0049 #define CTRL1_MIN_TIME_QUANTA (8U)
0050 
0051 #define MAX_EPROPSEG        (CAN_CBT_EPROPSEG_MASK >> CAN_CBT_EPROPSEG_SHIFT)
0052 #define MAX_EPSEG1          (CAN_CBT_EPSEG1_MASK >> CAN_CBT_EPSEG1_SHIFT)
0053 #define MAX_EPSEG2          (CAN_CBT_EPSEG2_MASK >> CAN_CBT_EPSEG2_SHIFT)
0054 #define MAX_ERJW            (CAN_CBT_ERJW_MASK >> CAN_CBT_ERJW_SHIFT)
0055 #define MAX_EPRESDIV        (CAN_CBT_EPRESDIV_MASK >> CAN_CBT_EPRESDIV_SHIFT)
0056 #define CBT_MAX_TIME_QUANTA (1U + MAX_EPROPSEG + 1U + MAX_EPSEG1 + 1U + MAX_EPSEG2 + 1U)
0057 #define CBT_MIN_TIME_QUANTA (8U)
0058 
0059 #define MAX_FPROPSEG          (CAN_FDCBT_FPROPSEG_MASK >> CAN_FDCBT_FPROPSEG_SHIFT)
0060 #define MAX_FPSEG1            (CAN_FDCBT_FPSEG1_MASK >> CAN_FDCBT_FPSEG1_SHIFT)
0061 #define MAX_FPSEG2            (CAN_FDCBT_FPSEG2_MASK >> CAN_FDCBT_FPSEG2_SHIFT)
0062 #define MAX_FRJW              (CAN_FDCBT_FRJW_MASK >> CAN_FDCBT_FRJW_SHIFT)
0063 #define MAX_FPRESDIV          (CAN_FDCBT_FPRESDIV_MASK >> CAN_FDCBT_FPRESDIV_SHIFT)
0064 #define FDCBT_MAX_TIME_QUANTA (1U + MAX_FPROPSEG + 0U + MAX_FPSEG1 + 1U + MAX_FPSEG2 + 1U)
0065 #define FDCBT_MIN_TIME_QUANTA (5U)
0066 
0067 #define MAX_TDCOFF ((uint32_t)CAN_FDCTRL_TDCOFF_MASK >> CAN_FDCTRL_TDCOFF_SHIFT)
0068 
0069 #define MAX_NTSEG1            (CAN_ENCBT_NTSEG1_MASK >> CAN_ENCBT_NTSEG1_SHIFT)
0070 #define MAX_NTSEG2            (CAN_ENCBT_NTSEG2_MASK >> CAN_ENCBT_NTSEG2_SHIFT)
0071 #define MAX_NRJW              (CAN_ENCBT_NRJW_MASK >> CAN_ENCBT_NRJW_SHIFT)
0072 #define MAX_ENPRESDIV         (CAN_EPRS_ENPRESDIV_MASK >> CAN_EPRS_ENPRESDIV_SHIFT)
0073 #define ENCBT_MAX_TIME_QUANTA (1U + MAX_NTSEG1 + 1U + MAX_NTSEG2 + 1U)
0074 #define ENCBT_MIN_TIME_QUANTA (8U)
0075 
0076 #define MAX_DTSEG1            (CAN_EDCBT_DTSEG1_MASK >> CAN_EDCBT_DTSEG1_SHIFT)
0077 #define MAX_DTSEG2            (CAN_EDCBT_DTSEG2_MASK >> CAN_EDCBT_DTSEG2_SHIFT)
0078 #define MAX_DRJW              (CAN_EDCBT_DRJW_MASK >> CAN_EDCBT_DRJW_SHIFT)
0079 #define MAX_EDPRESDIV         (CAN_EPRS_EDPRESDIV_MASK >> CAN_EPRS_EDPRESDIV_SHIFT)
0080 #define EDCBT_MAX_TIME_QUANTA (1U + MAX_DTSEG1 + 1U + MAX_DTSEG2 + 1U)
0081 #define EDCBT_MIN_TIME_QUANTA (5U)
0082 
0083 #define MAX_ETDCOFF ((uint32_t)CAN_ETDC_ETDCOFF_MASK >> CAN_ETDC_ETDCOFF_SHIFT)
0084 
0085 /* TSEG1 corresponds to the sum of xPROPSEG and xPSEG1, TSEG2 corresponds to the xPSEG2 value. */
0086 #define MIN_TIME_SEGMENT1 (2U)
0087 #define MIN_TIME_SEGMENT2 (2U)
0088 
0089 /* Define maximum CAN and CAN FD bit rate supported by FLEXCAN. */
0090 #define MAX_CANFD_BITRATE (8000000U)
0091 #define MAX_CAN_BITRATE   (1000000U)
0092 
0093 #if (defined(FSL_FEATURE_FLEXCAN_HAS_ERRATA_9595) && FSL_FEATURE_FLEXCAN_HAS_ERRATA_9595)
0094 #define CAN_ESR1_FLTCONF_BUSOFF CAN_ESR1_FLTCONF(2U)
0095 #endif
0096 
0097 /* Define the range of memory that needs to be initialized when the device has memory error detection feature. */
0098 #if (defined(FSL_FEATURE_FLEXCAN_HAS_MEMORY_ERROR_CONTROL) && FSL_FEATURE_FLEXCAN_HAS_MEMORY_ERROR_CONTROL)
0099 #define CAN_INIT_RXFIR         ((uintptr_t)base + 0x4Cu)
0100 #define CAN_INIT_MEMORY_BASE_1 (uint32_t *)((uintptr_t)base + (uintptr_t)FSL_FEATURE_FLEXCAN_INIT_MEMORY_BASE_1)
0101 #define CAN_INIT_MEMORY_SIZE_1 FSL_FEATURE_FLEXCAN_INIT_MEMORY_SIZE_1
0102 #define CAN_INIT_MEMORY_BASE_2 (uint32_t *)((uintptr_t)base + (uintptr_t)FSL_FEATURE_FLEXCAN_INIT_MEMORY_BASE_2)
0103 #define CAN_INIT_MEMORY_SIZE_2 FSL_FEATURE_FLEXCAN_INIT_MEMORY_SIZE_2
0104 #endif
0105 
0106 #if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
0107 #ifndef CAN_CLOCK_CHECK_NO_AFFECTS
0108 /* If no define such MACRO, it mean that the CAN in current device have no clock affect issue. */
0109 #define CAN_CLOCK_CHECK_NO_AFFECTS (true)
0110 #endif /* CAN_CLOCK_CHECK_NO_AFFECTS */
0111 #endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */
0112 
0113 /*! @brief FlexCAN Internal State. */
0114 enum _flexcan_state
0115 {
0116     kFLEXCAN_StateIdle     = 0x0, /*!< MB/RxFIFO idle.*/
0117     kFLEXCAN_StateRxData   = 0x1, /*!< MB receiving.*/
0118     kFLEXCAN_StateRxRemote = 0x2, /*!< MB receiving remote reply.*/
0119     kFLEXCAN_StateTxData   = 0x3, /*!< MB transmitting.*/
0120     kFLEXCAN_StateTxRemote = 0x4, /*!< MB transmitting remote request.*/
0121     kFLEXCAN_StateRxFifo   = 0x5, /*!< RxFIFO receiving.*/
0122 };
0123 
0124 /*! @brief FlexCAN message buffer CODE for Rx buffers. */
0125 enum _flexcan_mb_code_rx
0126 {
0127     kFLEXCAN_RxMbInactive = 0x0, /*!< MB is not active.*/
0128     kFLEXCAN_RxMbFull     = 0x2, /*!< MB is full.*/
0129     kFLEXCAN_RxMbEmpty    = 0x4, /*!< MB is active and empty.*/
0130     kFLEXCAN_RxMbOverrun  = 0x6, /*!< MB is overwritten into a full buffer.*/
0131     kFLEXCAN_RxMbBusy     = 0x8, /*!< FlexCAN is updating the contents of the MB, The CPU must not access the MB.*/
0132     kFLEXCAN_RxMbRanswer  = 0xA, /*!< A frame was configured to recognize a Remote Request Frame and transmit a
0133                                       Response Frame in return.*/
0134     kFLEXCAN_RxMbNotUsed = 0xF,  /*!< Not used.*/
0135 };
0136 
0137 /*! @brief FlexCAN message buffer CODE FOR Tx buffers. */
0138 enum _flexcan_mb_code_tx
0139 {
0140     kFLEXCAN_TxMbInactive     = 0x8, /*!< MB is not active.*/
0141     kFLEXCAN_TxMbAbort        = 0x9, /*!< MB is aborted.*/
0142     kFLEXCAN_TxMbDataOrRemote = 0xC, /*!< MB is a TX Data Frame(when MB RTR = 0) or MB is a TX Remote Request
0143                                           Frame (when MB RTR = 1).*/
0144     kFLEXCAN_TxMbTanswer = 0xE,      /*!< MB is a TX Response Request Frame from an incoming Remote Request Frame.*/
0145     kFLEXCAN_TxMbNotUsed = 0xF,      /*!< Not used.*/
0146 };
0147 
0148 /* Typedef for interrupt handler. */
0149 typedef void (*flexcan_isr_t)(CAN_Type *base, flexcan_handle_t *handle);
0150 
0151 /*******************************************************************************
0152  * Prototypes
0153  ******************************************************************************/
0154 
0155 #if !defined(NDEBUG)
0156 /*!
0157  * @brief Check if Message Buffer is occupied by Rx FIFO.
0158  *
0159  * This function check if Message Buffer is occupied by Rx FIFO.
0160  *
0161  * @param base FlexCAN peripheral base address.
0162  * @param mbIdx The FlexCAN Message Buffer index.
0163  * @return TRUE if the index MB is occupied by Rx FIFO, FALSE if the index MB not occupied by Rx FIFO.
0164  */
0165 static bool FLEXCAN_IsMbOccupied(CAN_Type *base, uint8_t mbIdx);
0166 #endif
0167 
0168 #if ((defined(FSL_FEATURE_FLEXCAN_HAS_ERRATA_5641) && FSL_FEATURE_FLEXCAN_HAS_ERRATA_5641) || \
0169      (defined(FSL_FEATURE_FLEXCAN_HAS_ERRATA_5829) && FSL_FEATURE_FLEXCAN_HAS_ERRATA_5829))
0170 /*!
0171  * @brief Get the first valid Message buffer ID of give FlexCAN instance.
0172  *
0173  * This function is a helper function for Errata 5641 workaround.
0174  *
0175  * @param base FlexCAN peripheral base address.
0176  * @return The first valid Message Buffer Number.
0177  */
0178 static uint8_t FLEXCAN_GetFirstValidMb(CAN_Type *base);
0179 #endif
0180 
0181 /*!
0182  * @brief Reset the FlexCAN Instance.
0183  *
0184  * Restores the FlexCAN module to reset state, notice that this function
0185  * will set all the registers to reset state so the FlexCAN module can not work
0186  * after calling this API.
0187  *
0188  * @param base FlexCAN peripheral base address.
0189  */
0190 static void FLEXCAN_Reset(CAN_Type *base);
0191 
0192 /*!
0193  * @brief Calculates the segment values for a single bit time for classical CAN.
0194  *
0195  * This function use to calculates the Classical CAN segment values which will be set in CTRL1/CBT/ENCBT register.
0196  *
0197  * @param base FlexCAN peripheral base address.
0198  * @param tqNum Number of time quantas per bit, range in 8 ~ 25 when use CTRL1, range in 8 ~ 129 when use CBT, range in
0199  *             8 ~ 385 when use ENCBT. param pTimingConfig Pointer to the FlexCAN timing configuration structure.
0200  */
0201 static void FLEXCAN_GetSegments(CAN_Type *base,
0202                                 uint32_t bitRate,
0203                                 uint32_t tqNum,
0204                                 flexcan_timing_config_t *pTimingConfig);
0205 
0206 #if (defined(FSL_FEATURE_FLEXCAN_HAS_FLEXIBLE_DATA_RATE) && FSL_FEATURE_FLEXCAN_HAS_FLEXIBLE_DATA_RATE)
0207 /*!
0208  * @brief Get Mailbox offset number by dword.
0209  *
0210  * This function gets the offset number of the specified mailbox.
0211  * Mailbox is not consecutive between memory regions when payload is not 8 bytes
0212  * so need to calculate the specified mailbox address.
0213  * For example, in the first memory region, MB[0].CS address is 0x4002_4080. For 32 bytes
0214  * payload frame, the second mailbox is ((1/12)*512 + 1%12*40)/4 = 10, meaning 10 dword
0215  * after the 0x4002_4080, which is actually the address of mailbox MB[1].CS.
0216  *
0217  * @param base FlexCAN peripheral base address.
0218  * @param mbIdx Mailbox index.
0219  */
0220 static uint32_t FLEXCAN_GetFDMailboxOffset(CAN_Type *base, uint8_t mbIdx);
0221 
0222 /*!
0223  * @brief Calculates the segment values for a single bit time for CAN FD data phase.
0224  *
0225  * This function use to calculates the CAN FD data phase segment values which will be set in CFDCBT/EDCBT
0226  * register.
0227  *
0228  * @param bitRateFD Data phase bit rate
0229  * @param tqNum Number of time quanta per bit
0230  * @param pTimingConfig Pointer to the FlexCAN timing configuration structure.
0231  */
0232 static void FLEXCAN_FDGetSegments(uint32_t bitRateFD, uint32_t tqNum, flexcan_timing_config_t *pTimingConfig);
0233 
0234 /*!
0235  * @brief Calculates the improved timing values by specific bit rate for CAN FD nominal phase.
0236  *
0237  * This function use to calculates the CAN FD nominal phase timing values according to the given nominal phase bit rate.
0238  * The Calculated timing values will be set in CBT/ENCBT registers. The calculation is based on the recommendation of
0239  * the CiA 1301 v1.0.0 document.
0240  *
0241  * @param bitRate  The CAN FD nominal phase speed in bps defined by user, should be less than or equal to 1Mbps.
0242  * @param sourceClock_Hz The Source clock frequency in Hz.
0243  * @param pTimingConfig Pointer to the FlexCAN timing configuration structure.
0244  *
0245  * @return TRUE if timing configuration found, FALSE if failed to find configuration.
0246  */
0247 static bool FLEXCAN_CalculateImprovedNominalTimingValues(uint32_t bitRate,
0248                                                          uint32_t sourceClock_Hz,
0249                                                          flexcan_timing_config_t *pTimingConfig);
0250 
0251 #endif
0252 
0253 /*!
0254  * @brief Check unhandle interrupt events
0255  *
0256  * @param base FlexCAN peripheral base address.
0257  * @return TRUE if unhandled interrupt action exist, FALSE if no unhandlered interrupt action exist.
0258  */
0259 static bool FLEXCAN_CheckUnhandleInterruptEvents(CAN_Type *base);
0260 
0261 /*!
0262  * @brief Sub Handler Data Trasfered Events
0263  *
0264  * @param base FlexCAN peripheral base address.
0265  * @param handle FlexCAN handle pointer.
0266  * @param pResult Pointer to the Handle result.
0267  *
0268  * @return the status after handle each data transfered event.
0269  */
0270 static status_t FLEXCAN_SubHandlerForDataTransfered(CAN_Type *base, flexcan_handle_t *handle, uint32_t *pResult);
0271 
0272 #if (defined(FSL_FEATURE_FLEXCAN_HAS_ENHANCED_RX_FIFO) && FSL_FEATURE_FLEXCAN_HAS_ENHANCED_RX_FIFO)
0273 /*!
0274  * @brief Sub Handler Ehanced Rx FIFO event
0275  *
0276  * @param base FlexCAN peripheral base address.
0277  * @param handle FlexCAN handle pointer.
0278  * @param flags FlexCAN interrupt flags.
0279  *
0280  * @return the status after handle Ehanced Rx FIFO event.
0281  */
0282 static status_t FLEXCAN_SubHandlerForEhancedRxFifo(CAN_Type *base, flexcan_handle_t *handle, uint64_t flags);
0283 #endif
0284 
0285 /*******************************************************************************
0286  * Variables
0287  ******************************************************************************/
0288 
0289 /* Array of FlexCAN peripheral base address. */
0290 static CAN_Type *const s_flexcanBases[] = CAN_BASE_PTRS;
0291 
0292 /* Array of FlexCAN IRQ number. */
0293 static const IRQn_Type s_flexcanRxWarningIRQ[] = CAN_Rx_Warning_IRQS;
0294 static const IRQn_Type s_flexcanTxWarningIRQ[] = CAN_Tx_Warning_IRQS;
0295 static const IRQn_Type s_flexcanWakeUpIRQ[]    = CAN_Wake_Up_IRQS;
0296 static const IRQn_Type s_flexcanErrorIRQ[]     = CAN_Error_IRQS;
0297 static const IRQn_Type s_flexcanBusOffIRQ[]    = CAN_Bus_Off_IRQS;
0298 static const IRQn_Type s_flexcanMbIRQ[]        = CAN_ORed_Message_buffer_IRQS;
0299 
0300 /* Array of FlexCAN handle. */
0301 static flexcan_handle_t *s_flexcanHandle[ARRAY_SIZE(s_flexcanBases)];
0302 
0303 #if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
0304 /* Array of FlexCAN clock name. */
0305 static const clock_ip_name_t s_flexcanClock[] = FLEXCAN_CLOCKS;
0306 #if defined(FLEXCAN_PERIPH_CLOCKS)
0307 /* Array of FlexCAN serial clock name. */
0308 static const clock_ip_name_t s_flexcanPeriphClock[] = FLEXCAN_PERIPH_CLOCKS;
0309 #endif /* FLEXCAN_PERIPH_CLOCKS */
0310 #endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */
0311 
0312 /* FlexCAN ISR for transactional APIs. */
0313 #if defined(__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050)
0314 static flexcan_isr_t s_flexcanIsr = (flexcan_isr_t)DefaultISR;
0315 #else
0316 static flexcan_isr_t s_flexcanIsr;
0317 #endif
0318 
0319 /*******************************************************************************
0320  * Implementation of 32-bit memset
0321  ******************************************************************************/
0322 
0323 static void flexcan_memset(void *s, uint32_t c, size_t n)
0324 {
0325     size_t m;
0326     uint32_t *ptr = s;
0327 
0328     m = n / sizeof(*ptr);
0329 
0330     while ((m--) != (size_t)0)
0331     {
0332         *ptr++ = c;
0333     }
0334 }
0335 
0336 /*******************************************************************************
0337  * Code
0338  ******************************************************************************/
0339 /*!
0340  * brief Get the FlexCAN instance from peripheral base address.
0341  *
0342  * param base FlexCAN peripheral base address.
0343  * return FlexCAN instance.
0344  */
0345 uint32_t FLEXCAN_GetInstance(CAN_Type *base)
0346 {
0347     uint32_t instance;
0348 
0349     /* Find the instance index from base address mappings. */
0350     for (instance = 0; instance < ARRAY_SIZE(s_flexcanBases); instance++)
0351     {
0352         if (s_flexcanBases[instance] == base)
0353         {
0354             break;
0355         }
0356     }
0357 
0358     assert(instance < ARRAY_SIZE(s_flexcanBases));
0359 
0360     return instance;
0361 }
0362 
0363 /*!
0364  * brief Enter FlexCAN Freeze Mode.
0365  *
0366  * This function makes the FlexCAN work under Freeze Mode.
0367  *
0368  * param base FlexCAN peripheral base address.
0369  */
0370 #if (defined(FSL_FEATURE_FLEXCAN_HAS_ERRATA_9595) && FSL_FEATURE_FLEXCAN_HAS_ERRATA_9595)
0371 void FLEXCAN_EnterFreezeMode(CAN_Type *base)
0372 {
0373     uint32_t u32TimeoutCount = 0U;
0374     uint32_t u32TempMCR      = 0U;
0375     uint32_t u32TempIMASK1   = 0U;
0376 #if (defined(FSL_FEATURE_FLEXCAN_HAS_EXTENDED_FLAG_REGISTER)) && (FSL_FEATURE_FLEXCAN_HAS_EXTENDED_FLAG_REGISTER > 0)
0377     uint32_t u32TempIMASK2 = 0U;
0378 #endif
0379 
0380     /* Step1: set FRZ enable in MCR. */
0381     base->MCR |= CAN_MCR_FRZ_MASK;
0382 
0383     /* Step2: to check if MDIS bit set in MCR. if yes, clear it. */
0384     if (0U != (base->MCR & CAN_MCR_MDIS_MASK))
0385     {
0386         base->MCR &= ~CAN_MCR_MDIS_MASK;
0387     }
0388 
0389     /* Step3: polling LPMACK. */
0390     u32TimeoutCount = (uint32_t)FLEXCAN_WAIT_TIMEOUT;
0391     while ((0U == (base->MCR & CAN_MCR_LPMACK_MASK)) && (u32TimeoutCount > 0U))
0392     {
0393         u32TimeoutCount--;
0394     }
0395 
0396     /* Step4: to check FLTCONF in ESR1 register */
0397     if (0U == (base->ESR1 & CAN_ESR1_FLTCONF_BUSOFF))
0398     {
0399         /* Step5B: Set Halt bits. */
0400         base->MCR |= CAN_MCR_HALT_MASK;
0401 
0402         /* Step6B: Poll the MCR register until the Freeze Acknowledge (FRZACK) bit is set, timeout need more than 178
0403          * CAN bit length, so 20 multiply timeout is enough. */
0404         u32TimeoutCount = (uint32_t)FLEXCAN_WAIT_TIMEOUT * 20U;
0405         while ((0U == (base->MCR & CAN_MCR_FRZACK_MASK)) && (u32TimeoutCount > 0U))
0406         {
0407             u32TimeoutCount--;
0408         }
0409     }
0410     else
0411     {
0412         /* backup MCR and IMASK register. Errata document not descript it, but we need backup for step 8A and 9A. */
0413         u32TempMCR    = base->MCR;
0414         u32TempIMASK1 = base->IMASK1;
0415 #if (defined(FSL_FEATURE_FLEXCAN_HAS_EXTENDED_FLAG_REGISTER)) && (FSL_FEATURE_FLEXCAN_HAS_EXTENDED_FLAG_REGISTER > 0)
0416         u32TempIMASK2 = base->IMASK2;
0417 #endif
0418 
0419         /* Step5A: Set the Soft Reset bit ((SOFTRST) in the MCR.*/
0420         base->MCR |= CAN_MCR_SOFTRST_MASK;
0421 
0422         /* Step6A: Poll the MCR register until the Soft Reset (SOFTRST) bit is cleared. */
0423         u32TimeoutCount = (uint32_t)FLEXCAN_WAIT_TIMEOUT;
0424         while ((CAN_MCR_SOFTRST_MASK == (base->MCR & CAN_MCR_SOFTRST_MASK)) && (u32TimeoutCount > 0U))
0425         {
0426             u32TimeoutCount--;
0427         }
0428 
0429         /* Step7A: Poll the MCR register until the Freeze Acknowledge (FRZACK) bit is set. */
0430         u32TimeoutCount = (uint32_t)FLEXCAN_WAIT_TIMEOUT;
0431         while ((0U == (base->MCR & CAN_MCR_FRZACK_MASK)) && (u32TimeoutCount > 0U))
0432         {
0433             u32TimeoutCount--;
0434         }
0435 
0436         /* Step8A: reconfig MCR. */
0437         base->MCR = u32TempMCR;
0438 
0439         /* Step9A: reconfig IMASK. */
0440         base->IMASK1 = u32TempIMASK1;
0441 #if (defined(FSL_FEATURE_FLEXCAN_HAS_EXTENDED_FLAG_REGISTER)) && (FSL_FEATURE_FLEXCAN_HAS_EXTENDED_FLAG_REGISTER > 0)
0442         base->IMASK2 = u32TempIMASK2;
0443 #endif
0444     }
0445 }
0446 #elif (defined(FSL_FEATURE_FLEXCAN_HAS_ERRATA_8341) && FSL_FEATURE_FLEXCAN_HAS_ERRATA_8341)
0447 void FLEXCAN_EnterFreezeMode(CAN_Type *base)
0448 {
0449     uint32_t u32TimeoutCount = 0U;
0450     uint32_t u32TempMCR      = 0U;
0451     uint32_t u32TempIMASK1   = 0U;
0452 #if (defined(FSL_FEATURE_FLEXCAN_HAS_EXTENDED_FLAG_REGISTER)) && (FSL_FEATURE_FLEXCAN_HAS_EXTENDED_FLAG_REGISTER > 0)
0453     uint32_t u32TempIMASK2   = 0U;
0454 #endif
0455 
0456     /* Step1: set FRZ and HALT bit enable in MCR. */
0457     base->MCR |= CAN_MCR_FRZ_MASK;
0458     base->MCR |= CAN_MCR_HALT_MASK;
0459 
0460     /* Step2: to check if MDIS bit set in MCR. if yes, clear it. */
0461     if (0U != (base->MCR & CAN_MCR_MDIS_MASK))
0462     {
0463         base->MCR &= ~CAN_MCR_MDIS_MASK;
0464     }
0465 
0466     /* Step3: Poll the MCR register until the Freeze Acknowledge (FRZACK) bit is set. */
0467     u32TimeoutCount = (uint32_t)FLEXCAN_WAIT_TIMEOUT * 100U;
0468     while ((0U == (base->MCR & CAN_MCR_FRZACK_MASK)) && (u32TimeoutCount > 0U))
0469     {
0470         u32TimeoutCount--;
0471     }
0472 
0473     /* Step4: check whether the timeout reached. if no skip step5 to step8. */
0474     if (0U == u32TimeoutCount)
0475     {
0476         /* backup MCR and IMASK register. Errata document not descript it, but we need backup for step 8A and 9A. */
0477         u32TempMCR    = base->MCR;
0478         u32TempIMASK1 = base->IMASK1;
0479 #if (defined(FSL_FEATURE_FLEXCAN_HAS_EXTENDED_FLAG_REGISTER)) && (FSL_FEATURE_FLEXCAN_HAS_EXTENDED_FLAG_REGISTER > 0)
0480         u32TempIMASK2 = base->IMASK2;
0481 #endif
0482         /* Step5: Set the Soft Reset bit ((SOFTRST) in the MCR.*/
0483         base->MCR |= CAN_MCR_SOFTRST_MASK;
0484 
0485         /* Step6: Poll the MCR register until the Soft Reset (SOFTRST) bit is cleared. */
0486         while (CAN_MCR_SOFTRST_MASK == (base->MCR & CAN_MCR_SOFTRST_MASK))
0487         {
0488         }
0489 
0490         /* Step7: reconfig MCR. */
0491         base->MCR = u32TempMCR;
0492 
0493         /* Step8: reconfig IMASK. */
0494         base->IMASK1 = u32TempIMASK1;
0495 #if (defined(FSL_FEATURE_FLEXCAN_HAS_EXTENDED_FLAG_REGISTER)) && (FSL_FEATURE_FLEXCAN_HAS_EXTENDED_FLAG_REGISTER > 0)
0496         base->IMASK2 = u32TempIMASK2;
0497 #endif
0498     }
0499 }
0500 #else
0501 void FLEXCAN_EnterFreezeMode(CAN_Type *base)
0502 {
0503     /* Set Freeze, Halt bits. */
0504     base->MCR |= CAN_MCR_FRZ_MASK;
0505     base->MCR |= CAN_MCR_HALT_MASK;
0506     while (0U == (base->MCR & CAN_MCR_FRZACK_MASK))
0507     {
0508     }
0509 }
0510 #endif
0511 
0512 /*!
0513  * brief Exit FlexCAN Freeze Mode.
0514  *
0515  * This function makes the FlexCAN leave Freeze Mode.
0516  *
0517  * param base FlexCAN peripheral base address.
0518  */
0519 void FLEXCAN_ExitFreezeMode(CAN_Type *base)
0520 {
0521 #if (defined(FSL_FEATURE_FLEXCAN_HAS_MEMORY_ERROR_CONTROL) && FSL_FEATURE_FLEXCAN_HAS_MEMORY_ERROR_CONTROL)
0522     /* Clean FlexCAN Access With Non-Correctable Error Interrupt Flag to avoid be put in freeze mode. */
0523     FLEXCAN_ClearStatusFlags(base, (uint64_t)kFLEXCAN_FlexCanAccessNonCorrectableErrorIntFlag |
0524                                        (uint64_t)kFLEXCAN_FlexCanAccessNonCorrectableErrorOverrunFlag);
0525 #endif
0526 
0527     /* Clear Freeze, Halt bits. */
0528     base->MCR &= ~CAN_MCR_HALT_MASK;
0529     base->MCR &= ~CAN_MCR_FRZ_MASK;
0530 
0531     /* Wait until the FlexCAN Module exit freeze mode. */
0532     while (0U != (base->MCR & CAN_MCR_FRZACK_MASK))
0533     {
0534     }
0535 }
0536 
0537 #if !defined(NDEBUG)
0538 /*!
0539  * brief Check if Message Buffer is occupied by Rx FIFO.
0540  *
0541  * This function check if Message Buffer is occupied by Rx FIFO.
0542  *
0543  * param base FlexCAN peripheral base address.
0544  * param mbIdx The FlexCAN Message Buffer index.
0545  * return TRUE if the index MB is occupied by Rx FIFO, FALSE if the index MB not occupied by Rx FIFO.
0546  */
0547 static bool FLEXCAN_IsMbOccupied(CAN_Type *base, uint8_t mbIdx)
0548 {
0549     uint8_t lastOccupiedMb;
0550     bool fgRet;
0551 
0552     /* Is Rx FIFO enabled? */
0553     if (0U != (base->MCR & CAN_MCR_RFEN_MASK))
0554     {
0555         /* Get RFFN value. */
0556         lastOccupiedMb = (uint8_t)((base->CTRL2 & CAN_CTRL2_RFFN_MASK) >> CAN_CTRL2_RFFN_SHIFT);
0557         /* Calculate the number of last Message Buffer occupied by Rx FIFO. */
0558         lastOccupiedMb = ((lastOccupiedMb + 1U) * 2U) + 5U;
0559 
0560 #if ((defined(FSL_FEATURE_FLEXCAN_HAS_ERRATA_5641) && FSL_FEATURE_FLEXCAN_HAS_ERRATA_5641) || \
0561      (defined(FSL_FEATURE_FLEXCAN_HAS_ERRATA_5829) && FSL_FEATURE_FLEXCAN_HAS_ERRATA_5829))
0562         /* the first valid MB should be occupied by ERRATA 5461 or 5829. */
0563         lastOccupiedMb += 1U;
0564 #endif
0565         fgRet = (mbIdx <= lastOccupiedMb);
0566     }
0567     else
0568     {
0569 #if ((defined(FSL_FEATURE_FLEXCAN_HAS_ERRATA_5641) && FSL_FEATURE_FLEXCAN_HAS_ERRATA_5641) || \
0570      (defined(FSL_FEATURE_FLEXCAN_HAS_ERRATA_5829) && FSL_FEATURE_FLEXCAN_HAS_ERRATA_5829))
0571         if (0U == mbIdx)
0572         {
0573             fgRet = true;
0574         }
0575         else
0576 #endif
0577         {
0578             fgRet = false;
0579         }
0580     }
0581 
0582     return fgRet;
0583 }
0584 #endif
0585 
0586 #if ((defined(FSL_FEATURE_FLEXCAN_HAS_ERRATA_5641) && FSL_FEATURE_FLEXCAN_HAS_ERRATA_5641) || \
0587      (defined(FSL_FEATURE_FLEXCAN_HAS_ERRATA_5829) && FSL_FEATURE_FLEXCAN_HAS_ERRATA_5829))
0588 /*!
0589  * brief Get the first valid Message buffer ID of give FlexCAN instance.
0590  *
0591  * This function is a helper function for Errata 5641 workaround.
0592  *
0593  * param base FlexCAN peripheral base address.
0594  * return The first valid Message Buffer Number.
0595  */
0596 static uint8_t FLEXCAN_GetFirstValidMb(CAN_Type *base)
0597 {
0598     uint8_t firstValidMbNum;
0599 
0600     if (0U != (base->MCR & CAN_MCR_RFEN_MASK))
0601     {
0602         firstValidMbNum = (uint8_t)((base->CTRL2 & CAN_CTRL2_RFFN_MASK) >> CAN_CTRL2_RFFN_SHIFT);
0603         firstValidMbNum = ((firstValidMbNum + 1U) * 2U) + 6U;
0604     }
0605     else
0606     {
0607         firstValidMbNum = 0U;
0608     }
0609 
0610     return firstValidMbNum;
0611 }
0612 #endif
0613 
0614 /*!
0615  * brief Reset the FlexCAN Instance.
0616  *
0617  * Restores the FlexCAN module to reset state, notice that this function
0618  * will set all the registers to reset state so the FlexCAN module can not work
0619  * after calling this API.
0620  *
0621  * param base FlexCAN peripheral base address.
0622  */
0623 static void FLEXCAN_Reset(CAN_Type *base)
0624 {
0625     /* The module must should be first exit from low power
0626      * mode, and then soft reset can be applied.
0627      */
0628     assert(0U == (base->MCR & CAN_MCR_MDIS_MASK));
0629 
0630     uint8_t i;
0631 
0632 #if (defined(FSL_FEATURE_FLEXCAN_HAS_DOZE_MODE_SUPPORT) && FSL_FEATURE_FLEXCAN_HAS_DOZE_MODE_SUPPORT)
0633     if (0 != (FSL_FEATURE_FLEXCAN_INSTANCE_HAS_DOZE_MODE_SUPPORTn(base)))
0634     {
0635         /* De-assert DOZE Enable Bit. */
0636         base->MCR &= ~CAN_MCR_DOZE_MASK;
0637     }
0638 #endif
0639 
0640     /* Wait until FlexCAN exit from any Low Power Mode. */
0641     while (0U != (base->MCR & CAN_MCR_LPMACK_MASK))
0642     {
0643     }
0644 
0645     /* Assert Soft Reset Signal. */
0646     base->MCR |= CAN_MCR_SOFTRST_MASK;
0647     /* Wait until FlexCAN reset completes. */
0648     while (0U != (base->MCR & CAN_MCR_SOFTRST_MASK))
0649     {
0650     }
0651 
0652 /* Reset MCR register. */
0653 #if (defined(FSL_FEATURE_FLEXCAN_HAS_GLITCH_FILTER) && FSL_FEATURE_FLEXCAN_HAS_GLITCH_FILTER)
0654     base->MCR |= CAN_MCR_WRNEN_MASK | CAN_MCR_WAKSRC_MASK |
0655                  CAN_MCR_MAXMB((uint32_t)FSL_FEATURE_FLEXCAN_HAS_MESSAGE_BUFFER_MAX_NUMBERn(base) - 1U);
0656 #else
0657     base->MCR |=
0658         CAN_MCR_WRNEN_MASK | CAN_MCR_MAXMB((uint32_t)FSL_FEATURE_FLEXCAN_HAS_MESSAGE_BUFFER_MAX_NUMBERn(base) - 1U);
0659 #endif
0660 
0661     /* Reset CTRL1 and CTRL2 register, default to eanble SMP feature which enable three sample point to determine the
0662      * received bit's value of the. */
0663     base->CTRL1 = CAN_CTRL1_SMP_MASK;
0664     base->CTRL2 = CAN_CTRL2_TASD(0x16) | CAN_CTRL2_RRS_MASK | CAN_CTRL2_EACEN_MASK;
0665 
0666 #if (defined(FSL_FEATURE_FLEXCAN_HAS_MEMORY_ERROR_CONTROL) && FSL_FEATURE_FLEXCAN_HAS_MEMORY_ERROR_CONTROL)
0667     /* Enable unrestricted write access to FlexCAN memory. */
0668     base->CTRL2 |= CAN_CTRL2_WRMFRZ_MASK;
0669     /* Do memory initialization for all FlexCAN RAM in order to have the parity bits in memory properly
0670        updated. */
0671     *(volatile uint32_t *)CAN_INIT_RXFIR = 0x0U;
0672     flexcan_memset(CAN_INIT_MEMORY_BASE_1, 0, CAN_INIT_MEMORY_SIZE_1);
0673     flexcan_memset(CAN_INIT_MEMORY_BASE_2, 0, CAN_INIT_MEMORY_SIZE_2);
0674     /* Disable unrestricted write access to FlexCAN memory. */
0675     base->CTRL2 &= ~CAN_CTRL2_WRMFRZ_MASK;
0676 
0677     /* Clean all memory error flags. */
0678     FLEXCAN_ClearStatusFlags(base, (uint64_t)kFLEXCAN_AllMemoryErrorFlag);
0679 #else
0680     /* Only need clean all Message Buffer memory. */
0681     flexcan_memset((void *)&base->MB[0], 0, sizeof(base->MB));
0682 #endif
0683 
0684     /* Clean all individual Rx Mask of Message Buffers. */
0685     for (i = 0; i < (uint32_t)FSL_FEATURE_FLEXCAN_HAS_MESSAGE_BUFFER_MAX_NUMBERn(base); i++)
0686     {
0687         base->RXIMR[i] = 0x3FFFFFFF;
0688     }
0689 
0690     /* Clean Global Mask of Message Buffers. */
0691     base->RXMGMASK = 0x3FFFFFFF;
0692     /* Clean Global Mask of Message Buffer 14. */
0693     base->RX14MASK = 0x3FFFFFFF;
0694     /* Clean Global Mask of Message Buffer 15. */
0695     base->RX15MASK = 0x3FFFFFFF;
0696     /* Clean Global Mask of Rx FIFO. */
0697     base->RXFGMASK = 0x3FFFFFFF;
0698 }
0699 
0700 /*!
0701  * brief Set bit rate of FlexCAN classical CAN frame or CAN FD frame nominal phase.
0702  *
0703  * This function set the bit rate of classical CAN frame or CAN FD frame nominal phase base on
0704  * FLEXCAN_CalculateImprovedTimingValues() API calculated timing values.
0705  *
0706  * note Calling FLEXCAN_SetBitRate() overrides the bit rate set in FLEXCAN_Init().
0707  *
0708  * param base FlexCAN peripheral base address.
0709  * param sourceClock_Hz Source Clock in Hz.
0710  * param bitRate_Bps Bit rate in Bps.
0711  * return kStatus_Success - Set CAN baud rate (only Nominal phase) successfully.
0712  */
0713 status_t FLEXCAN_SetBitRate(CAN_Type *base, uint32_t sourceClock_Hz, uint32_t bitRate_Bps)
0714 {
0715     flexcan_timing_config_t timingCfg;
0716     status_t result = kStatus_Fail;
0717 
0718     if (FLEXCAN_CalculateImprovedTimingValues(base, bitRate_Bps, sourceClock_Hz, &timingCfg))
0719     {
0720         FLEXCAN_SetTimingConfig(base, &timingCfg);
0721         result = kStatus_Success;
0722     }
0723 
0724     return result;
0725 }
0726 
0727 #if (defined(FSL_FEATURE_FLEXCAN_HAS_FLEXIBLE_DATA_RATE) && FSL_FEATURE_FLEXCAN_HAS_FLEXIBLE_DATA_RATE)
0728 /*!
0729  * @brief Set bit rate of FlexCAN FD frame.
0730  *
0731  * This function set the baud rate of FLEXCAN FD base on FLEXCAN_FDCalculateImprovedTimingValues() API calculated timing
0732  * values.
0733  *
0734  * @param base FlexCAN peripheral base address.
0735  * @param sourceClock_Hz Source Clock in Hz.
0736  * @param bitRateN_Bps Nominal bit Rate in Bps.
0737  * @param bitRateD_Bps Data bit Rate in Bps.
0738  * @return kStatus_Success - Set CAN FD bit rate (include Nominal and Data phase) successfully.
0739  */
0740 status_t FLEXCAN_SetFDBitRate(CAN_Type *base, uint32_t sourceClock_Hz, uint32_t bitRateN_Bps, uint32_t bitRateD_Bps)
0741 {
0742     flexcan_timing_config_t timingCfg;
0743     status_t result = kStatus_Fail;
0744 
0745     if (FLEXCAN_FDCalculateImprovedTimingValues(base, bitRateN_Bps, bitRateD_Bps, sourceClock_Hz, &timingCfg))
0746     {
0747         FLEXCAN_SetFDTimingConfig(base, &timingCfg);
0748         result = kStatus_Success;
0749     }
0750 
0751     return result;
0752 }
0753 #endif
0754 
0755 /*!
0756  * brief Initializes a FlexCAN instance.
0757  *
0758  * This function initializes the FlexCAN module with user-defined settings.
0759  * This example shows how to set up the flexcan_config_t parameters and how
0760  * to call the FLEXCAN_Init function by passing in these parameters.
0761  *  code
0762  *   flexcan_config_t flexcanConfig;
0763  *   flexcanConfig.clkSrc               = kFLEXCAN_ClkSrc0;
0764  *   flexcanConfig.bitRate              = 1000000U;
0765  *   flexcanConfig.maxMbNum             = 16;
0766  *   flexcanConfig.enableLoopBack       = false;
0767  *   flexcanConfig.enableSelfWakeup     = false;
0768  *   flexcanConfig.enableIndividMask    = false;
0769  *   flexcanConfig.disableSelfReception = false;
0770  *   flexcanConfig.enableListenOnlyMode = false;
0771  *   flexcanConfig.enableDoze           = false;
0772  *   flexcanConfig.timingConfig         = timingConfig;
0773  *   FLEXCAN_Init(CAN0, &flexcanConfig, 40000000UL);
0774  *   endcode
0775  *
0776  * param base FlexCAN peripheral base address.
0777  * param pConfig Pointer to the user-defined configuration structure.
0778  * param sourceClock_Hz FlexCAN Protocol Engine clock source frequency in Hz.
0779  */
0780 void FLEXCAN_Init(CAN_Type *base, const flexcan_config_t *pConfig, uint32_t sourceClock_Hz)
0781 {
0782     /* Assertion. */
0783     assert(NULL != pConfig);
0784     assert((pConfig->maxMbNum > 0U) &&
0785            (pConfig->maxMbNum <= (uint8_t)FSL_FEATURE_FLEXCAN_HAS_MESSAGE_BUFFER_MAX_NUMBERn(base)));
0786 
0787     uint32_t mcrTemp;
0788     uint32_t ctrl1Temp;
0789 #if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
0790     uint32_t instance;
0791 #endif
0792     flexcan_timing_config_t timingCfg = pConfig->timingConfig;
0793     /* FlexCAN classical CAN frame or CAN FD frame nominal phase timing setting formula:
0794      * quantum = 1 + (phaseSeg1 + 1) + (phaseSeg2 + 1) + (propSeg + 1);
0795      */
0796     uint32_t quantum = (1U + ((uint32_t)timingCfg.phaseSeg1 + 1U) + ((uint32_t)timingCfg.phaseSeg2 + 1U) +
0797                         ((uint32_t)timingCfg.propSeg + 1U));
0798     uint32_t tqFre   = pConfig->bitRate * quantum;
0799     uint16_t maxDivider;
0800 
0801     /* Assertion: Check bit rate value. */
0802     assert((pConfig->bitRate != 0U) && (pConfig->bitRate <= 1000000U) && (tqFre <= sourceClock_Hz));
0803 #if (defined(FSL_FEATURE_FLEXCAN_HAS_FLEXIBLE_DATA_RATE) && FSL_FEATURE_FLEXCAN_HAS_FLEXIBLE_DATA_RATE)
0804     if (0 != FSL_FEATURE_FLEXCAN_INSTANCE_HAS_FLEXIBLE_DATA_RATEn(base))
0805     {
0806 #if (defined(FSL_FEATURE_FLEXCAN_HAS_ENHANCED_BIT_TIMING_REG) && FSL_FEATURE_FLEXCAN_HAS_ENHANCED_BIT_TIMING_REG)
0807         assert((tqFre * MAX_ENPRESDIV) >= sourceClock_Hz);
0808         maxDivider = MAX_ENPRESDIV;
0809 #else
0810         assert((tqFre * MAX_EPRESDIV) >= sourceClock_Hz);
0811         maxDivider = MAX_EPRESDIV;
0812 #endif
0813     }
0814     else
0815     {
0816         assert((tqFre * MAX_PRESDIV) >= sourceClock_Hz);
0817         maxDivider = MAX_PRESDIV;
0818     }
0819 #else
0820     assert((tqFre * MAX_PRESDIV) >= sourceClock_Hz);
0821     maxDivider                       = MAX_PRESDIV;
0822 #endif
0823 
0824 #if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
0825     instance = FLEXCAN_GetInstance(base);
0826     /* Enable FlexCAN clock. */
0827     (void)CLOCK_EnableClock(s_flexcanClock[instance]);
0828     /*
0829      * Check the CAN clock in this device whether affected by Other clock gate
0830      * If it affected, we'd better to change other clock source,
0831      * If user insist on using that clock source, user need open these gate at same time,
0832      * In this scene, User need to care the power consumption.
0833      */
0834     assert(CAN_CLOCK_CHECK_NO_AFFECTS);
0835 #if defined(FLEXCAN_PERIPH_CLOCKS)
0836     /* Enable FlexCAN serial clock. */
0837     (void)CLOCK_EnableClock(s_flexcanPeriphClock[instance]);
0838 #endif /* FLEXCAN_PERIPH_CLOCKS */
0839 #endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */
0840 
0841 #if defined(CAN_CTRL1_CLKSRC_MASK)
0842 #if (defined(FSL_FEATURE_FLEXCAN_SUPPORT_ENGINE_CLK_SEL_REMOVE) && FSL_FEATURE_FLEXCAN_SUPPORT_ENGINE_CLK_SEL_REMOVE)
0843     if (0 == FSL_FEATURE_FLEXCAN_INSTANCE_SUPPORT_ENGINE_CLK_SEL_REMOVEn(base))
0844 #endif /* FSL_FEATURE_FLEXCAN_SUPPORT_ENGINE_CLK_SEL_REMOVE */
0845     {
0846         /* Disable FlexCAN Module. */
0847         FLEXCAN_Enable(base, false);
0848 
0849         /* Protocol-Engine clock source selection, This bit must be set
0850          * when FlexCAN Module in Disable Mode.
0851          */
0852         base->CTRL1 = (kFLEXCAN_ClkSrc0 == pConfig->clkSrc) ? (base->CTRL1 & ~CAN_CTRL1_CLKSRC_MASK) :
0853                                                               (base->CTRL1 | CAN_CTRL1_CLKSRC_MASK);
0854     }
0855 #endif /* CAN_CTRL1_CLKSRC_MASK */
0856 
0857     /* Enable FlexCAN Module for configuration. */
0858     FLEXCAN_Enable(base, true);
0859 
0860     /* Reset to known status. */
0861     FLEXCAN_Reset(base);
0862 
0863 #if (defined(FSL_FEATURE_FLEXCAN_HAS_MEMORY_ERROR_CONTROL) && FSL_FEATURE_FLEXCAN_HAS_MEMORY_ERROR_CONTROL)
0864     /* Enable to update in MCER. */
0865     base->CTRL2 |= CAN_CTRL2_ECRWRE_MASK;
0866     base->MECR &= ~CAN_MECR_ECRWRDIS_MASK;
0867 
0868     /* Enable/Disable Memory Error Detection and Correction.*/
0869     base->MECR = (pConfig->enableMemoryErrorControl) ? (base->MECR & ~CAN_MECR_ECCDIS_MASK) :
0870                                                        (base->MECR | CAN_MECR_ECCDIS_MASK);
0871 
0872     /* Enable/Disable Non-Correctable Errors In FlexCAN Access Put Device In Freeze Mode. */
0873     base->MECR = (pConfig->enableNonCorrectableErrorEnterFreeze) ? (base->MECR | CAN_MECR_NCEFAFRZ_MASK) :
0874                                                                    (base->MECR & ~CAN_MECR_NCEFAFRZ_MASK);
0875     /* Lock MCER register. */
0876     base->CTRL2 &= ~CAN_CTRL2_ECRWRE_MASK;
0877 #endif
0878 
0879     /* Save current CTRL1 value and enable to enter Freeze mode(enabled by default). */
0880     ctrl1Temp = base->CTRL1;
0881 
0882     /* Save current MCR value and enable to enter Freeze mode(enabled by default). */
0883     mcrTemp = base->MCR;
0884 
0885     /* Enable Loop Back Mode? */
0886     ctrl1Temp = (pConfig->enableLoopBack) ? (ctrl1Temp | CAN_CTRL1_LPB_MASK) : (ctrl1Temp & ~CAN_CTRL1_LPB_MASK);
0887 
0888     /* Enable Timer Sync? */
0889     ctrl1Temp = (pConfig->enableTimerSync) ? (ctrl1Temp | CAN_CTRL1_TSYN_MASK) : (ctrl1Temp & ~CAN_CTRL1_TSYN_MASK);
0890 
0891     /* Enable Listen Only Mode? */
0892     ctrl1Temp = (pConfig->enableListenOnlyMode) ? ctrl1Temp | CAN_CTRL1_LOM_MASK : ctrl1Temp & ~CAN_CTRL1_LOM_MASK;
0893 
0894 #if !(defined(FSL_FEATURE_FLEXCAN_HAS_NO_SUPV_SUPPORT) && FSL_FEATURE_FLEXCAN_HAS_NO_SUPV_SUPPORT)
0895     /* Enable Supervisor Mode? */
0896     mcrTemp = (pConfig->enableSupervisorMode) ? mcrTemp | CAN_MCR_SUPV_MASK : mcrTemp & ~CAN_MCR_SUPV_MASK;
0897 #endif
0898 
0899     /* Set the maximum number of Message Buffers */
0900     mcrTemp = (mcrTemp & ~CAN_MCR_MAXMB_MASK) | CAN_MCR_MAXMB((uint32_t)pConfig->maxMbNum - 1U);
0901 
0902     /* Enable Self Wake Up Mode and configure the wake up source. */
0903     mcrTemp = (pConfig->enableSelfWakeup) ? (mcrTemp | CAN_MCR_SLFWAK_MASK) : (mcrTemp & ~CAN_MCR_SLFWAK_MASK);
0904     mcrTemp = (kFLEXCAN_WakeupSrcFiltered == pConfig->wakeupSrc) ? (mcrTemp | CAN_MCR_WAKSRC_MASK) :
0905                                                                    (mcrTemp & ~CAN_MCR_WAKSRC_MASK);
0906 #if (defined(FSL_FEATURE_FLEXCAN_HAS_PN_MODE) && FSL_FEATURE_FLEXCAN_HAS_PN_MODE)
0907     /* Enable Pretended Networking Mode? When Pretended Networking mode is set, Self Wake Up feature must be disabled.*/
0908     mcrTemp = (pConfig->enablePretendedeNetworking) ? ((mcrTemp & ~CAN_MCR_SLFWAK_MASK) | CAN_MCR_PNET_EN_MASK) :
0909                                                       (mcrTemp & ~CAN_MCR_PNET_EN_MASK);
0910 #endif
0911 
0912     /* Enable Individual Rx Masking and Queue feature? */
0913     mcrTemp = (pConfig->enableIndividMask) ? (mcrTemp | CAN_MCR_IRMQ_MASK) : (mcrTemp & ~CAN_MCR_IRMQ_MASK);
0914 
0915     /* Disable Self Reception? */
0916     mcrTemp = (pConfig->disableSelfReception) ? mcrTemp | CAN_MCR_SRXDIS_MASK : mcrTemp & ~CAN_MCR_SRXDIS_MASK;
0917 
0918 #if (defined(FSL_FEATURE_FLEXCAN_HAS_DOZE_MODE_SUPPORT) && FSL_FEATURE_FLEXCAN_HAS_DOZE_MODE_SUPPORT)
0919     if (0 != FSL_FEATURE_FLEXCAN_INSTANCE_HAS_DOZE_MODE_SUPPORTn(base))
0920     {
0921         /* Enable Doze Mode? */
0922         mcrTemp = (pConfig->enableDoze) ? (mcrTemp | CAN_MCR_DOZE_MASK) : (mcrTemp & ~CAN_MCR_DOZE_MASK);
0923     }
0924 #endif
0925 
0926     /* Write back CTRL1 Configuration to register. */
0927     base->CTRL1 = ctrl1Temp;
0928 
0929     /* Write back MCR Configuration to register. */
0930     base->MCR = mcrTemp;
0931 
0932     /* Check whether Nominal Bit Rate Prescaler is overflow. */
0933     if ((sourceClock_Hz / tqFre - 1U) > maxDivider)
0934     {
0935         timingCfg.preDivider = maxDivider;
0936     }
0937     else
0938     {
0939         timingCfg.preDivider = (uint16_t)(sourceClock_Hz / tqFre) - 1U;
0940     }
0941 
0942     /* Update actual timing characteristic. */
0943     FLEXCAN_SetTimingConfig(base, &timingCfg);
0944 }
0945 
0946 #if (defined(FSL_FEATURE_FLEXCAN_HAS_FLEXIBLE_DATA_RATE) && FSL_FEATURE_FLEXCAN_HAS_FLEXIBLE_DATA_RATE)
0947 /*!
0948  * brief Initializes a FlexCAN instance.
0949  *
0950  * This function initializes the FlexCAN module with user-defined settings.
0951  * This example shows how to set up the flexcan_config_t parameters and how
0952  * to call the FLEXCAN_FDInit function by passing in these parameters.
0953  *  code
0954  *   flexcan_config_t flexcanConfig;
0955  *   flexcanConfig.clkSrc               = kFLEXCAN_ClkSrc0;
0956  *   flexcanConfig.bitRate              = 1000000U;
0957  *   flexcanConfig.bitRateFD            = 2000000U;
0958  *   flexcanConfig.maxMbNum             = 16;
0959  *   flexcanConfig.enableLoopBack       = false;
0960  *   flexcanConfig.enableSelfWakeup     = false;
0961  *   flexcanConfig.enableIndividMask    = false;
0962  *   flexcanConfig.disableSelfReception = false;
0963  *   flexcanConfig.enableListenOnlyMode = false;
0964  *   flexcanConfig.enableDoze           = false;
0965  *   flexcanConfig.timingConfig         = timingConfig;
0966  *   FLEXCAN_FDInit(CAN0, &flexcanConfig, 80000000UL, kFLEXCAN_16BperMB, true);
0967  *   endcode
0968  *
0969  * param base FlexCAN peripheral base address.
0970  * param pConfig Pointer to the user-defined configuration structure.
0971  * param sourceClock_Hz FlexCAN Protocol Engine clock source frequency in Hz.
0972  * param dataSize FlexCAN Message Buffer payload size. The actual transmitted or received CAN FD frame data size needs
0973  *                to be less than or equal to this value.
0974  * param brs True if bit rate switch is enabled in FD mode.
0975  */
0976 void FLEXCAN_FDInit(
0977     CAN_Type *base, const flexcan_config_t *pConfig, uint32_t sourceClock_Hz, flexcan_mb_size_t dataSize, bool brs)
0978 {
0979     assert((uint32_t)dataSize <= 3U);
0980     assert(((pConfig->bitRate < pConfig->bitRateFD) && brs) || ((pConfig->bitRate == pConfig->bitRateFD) && (!brs)));
0981 
0982     uint32_t fdctrl                   = 0U;
0983     flexcan_timing_config_t timingCfg = pConfig->timingConfig;
0984     /* FlexCAN FD frame data phase timing setting formula:
0985      * quantum = 1 + (fphaseSeg1 + 1) + (fphaseSeg2 + 1) + fpropSeg;
0986      */
0987     uint32_t quantum = (1U + ((uint32_t)timingCfg.fphaseSeg1 + 1U) + ((uint32_t)timingCfg.fphaseSeg2 + 1U) +
0988                         (uint32_t)timingCfg.fpropSeg);
0989     uint32_t tqFre   = pConfig->bitRateFD * quantum;
0990     uint16_t maxDivider;
0991 
0992     /* Check bit rate value. */
0993     assert((pConfig->bitRateFD <= 8000000U) && (tqFre <= sourceClock_Hz));
0994 #if (defined(FSL_FEATURE_FLEXCAN_HAS_ENHANCED_BIT_TIMING_REG) && FSL_FEATURE_FLEXCAN_HAS_ENHANCED_BIT_TIMING_REG)
0995     assert((tqFre * MAX_EDPRESDIV) >= sourceClock_Hz);
0996     maxDivider = MAX_EDPRESDIV;
0997 #else
0998     assert((tqFre * MAX_FPRESDIV) >= sourceClock_Hz);
0999     maxDivider = MAX_FPRESDIV;
1000 #endif
1001 
1002     /* Initialization of classical CAN. */
1003     FLEXCAN_Init(base, pConfig, sourceClock_Hz);
1004 
1005     /* Check whether Data Bit Rate Prescaler is overflow. */
1006     if ((sourceClock_Hz / tqFre - 1U) > maxDivider)
1007     {
1008         timingCfg.fpreDivider = maxDivider;
1009     }
1010     else
1011     {
1012         timingCfg.fpreDivider = (uint16_t)(sourceClock_Hz / tqFre) - 1U;
1013     }
1014 
1015     /* Update actual timing characteristic. */
1016     FLEXCAN_SetFDTimingConfig(base, &timingCfg);
1017 
1018     /* read FDCTRL register. */
1019     fdctrl = base->FDCTRL;
1020 
1021     /* Enable FD operation and set bit rate switch. */
1022     if (brs)
1023     {
1024         fdctrl |= CAN_FDCTRL_FDRATE_MASK;
1025     }
1026     else
1027     {
1028         fdctrl &= ~CAN_FDCTRL_FDRATE_MASK;
1029     }
1030 
1031     /* Before use "|=" operation for multi-bits field, CPU should clean previous Setting. */
1032     fdctrl = (fdctrl & ~CAN_FDCTRL_MBDSR0_MASK) | CAN_FDCTRL_MBDSR0(dataSize);
1033 #if defined(CAN_FDCTRL_MBDSR1_MASK)
1034     fdctrl = (fdctrl & ~CAN_FDCTRL_MBDSR1_MASK) | CAN_FDCTRL_MBDSR1(dataSize);
1035 #endif
1036 #if defined(CAN_FDCTRL_MBDSR2_MASK)
1037     fdctrl = (fdctrl & ~CAN_FDCTRL_MBDSR2_MASK) | CAN_FDCTRL_MBDSR2(dataSize);
1038 #endif
1039 #if defined(CAN_FDCTRL_MBDSR3_MASK)
1040     fdctrl = (fdctrl & ~CAN_FDCTRL_MBDSR3_MASK) | CAN_FDCTRL_MBDSR3(dataSize);
1041 #endif
1042 
1043     /* Enter Freeze Mode. */
1044     FLEXCAN_EnterFreezeMode(base);
1045     /* Enable CAN FD operation. */
1046     base->MCR |= CAN_MCR_FDEN_MASK;
1047     /* Clear SMP bit when CAN FD is enabled (CAN FD only can use one regular sample point plus one optional secondary
1048      * sampling point). */
1049     base->CTRL1 &= ~CAN_CTRL1_SMP_MASK;
1050 
1051     if (brs && !(pConfig->enableLoopBack))
1052     {
1053 #if (defined(FSL_FEATURE_FLEXCAN_HAS_ENHANCED_BIT_TIMING_REG) && FSL_FEATURE_FLEXCAN_HAS_ENHANCED_BIT_TIMING_REG)
1054         /* The TDC offset should be configured as shown in this equation : offset = DTSEG1 + 2 */
1055         if (((uint32_t)pConfig->timingConfig.fphaseSeg1 + pConfig->timingConfig.fpropSeg + 2U) *
1056                 (pConfig->timingConfig.fpreDivider + 1U) <
1057             MAX_ETDCOFF)
1058         {
1059             base->ETDC =
1060                 CAN_ETDC_ETDCEN_MASK | CAN_ETDC_TDMDIS(!pConfig->enableTransceiverDelayMeasure) |
1061                 CAN_ETDC_ETDCOFF(((uint32_t)pConfig->timingConfig.fphaseSeg1 + pConfig->timingConfig.fpropSeg + 2U) *
1062                                  (pConfig->timingConfig.fpreDivider + 1U));
1063         }
1064         else
1065         {
1066             /* Enable the Transceiver Delay Compensation */
1067             base->ETDC = CAN_ETDC_ETDCEN_MASK | CAN_ETDC_TDMDIS(!pConfig->enableTransceiverDelayMeasure) |
1068                          CAN_ETDC_ETDCOFF(MAX_ETDCOFF);
1069         }
1070 #else
1071         /* The TDC offset should be configured as shown in this equation : offset = PSEG1 + PROPSEG + 2 */
1072         if (((uint32_t)pConfig->timingConfig.fphaseSeg1 + pConfig->timingConfig.fpropSeg + 2U) *
1073                 (pConfig->timingConfig.fpreDivider + 1U) <
1074             MAX_TDCOFF)
1075         {
1076             fdctrl =
1077                 (fdctrl & ~CAN_FDCTRL_TDCOFF_MASK) |
1078                 CAN_FDCTRL_TDCOFF(((uint32_t)pConfig->timingConfig.fphaseSeg1 + pConfig->timingConfig.fpropSeg + 2U) *
1079                                   (pConfig->timingConfig.fpreDivider + 1U));
1080         }
1081         else
1082         {
1083             fdctrl = (fdctrl & ~CAN_FDCTRL_TDCOFF_MASK) | CAN_FDCTRL_TDCOFF(MAX_TDCOFF);
1084         }
1085         /* Enable the Transceiver Delay Compensation */
1086         fdctrl = (fdctrl & ~CAN_FDCTRL_TDCEN_MASK) | CAN_FDCTRL_TDCEN_MASK;
1087 #endif
1088     }
1089 
1090     /* update the FDCTL register. */
1091     base->FDCTRL = fdctrl;
1092 
1093     /* Enable CAN FD ISO mode by default. */
1094     base->CTRL2 |= CAN_CTRL2_ISOCANFDEN_MASK;
1095 
1096     /* Exit Freeze Mode. */
1097     FLEXCAN_ExitFreezeMode(base);
1098 }
1099 #endif
1100 
1101 /*!
1102  * brief De-initializes a FlexCAN instance.
1103  *
1104  * This function disables the FlexCAN module clock and sets all register values
1105  * to the reset value.
1106  *
1107  * param base FlexCAN peripheral base address.
1108  */
1109 void FLEXCAN_Deinit(CAN_Type *base)
1110 {
1111 #if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
1112     uint32_t instance;
1113 #endif
1114     /* Reset all Register Contents. */
1115     FLEXCAN_Reset(base);
1116 
1117     /* Disable FlexCAN module. */
1118     FLEXCAN_Enable(base, false);
1119 
1120 #if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
1121     instance = FLEXCAN_GetInstance(base);
1122 #if defined(FLEXCAN_PERIPH_CLOCKS)
1123     /* Disable FlexCAN serial clock. */
1124     (void)CLOCK_DisableClock(s_flexcanPeriphClock[instance]);
1125 #endif /* FLEXCAN_PERIPH_CLOCKS */
1126     /* Disable FlexCAN clock. */
1127     (void)CLOCK_DisableClock(s_flexcanClock[instance]);
1128 #endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */
1129 }
1130 
1131 /*!
1132  * brief Gets the default configuration structure.
1133  *
1134  * This function initializes the FlexCAN configuration structure to default values. The default
1135  * values are as follows.
1136  *   flexcanConfig->clkSrc                               = kFLEXCAN_ClkSrc0;
1137  *   flexcanConfig->bitRate                              = 1000000U;
1138  *   flexcanConfig->bitRateFD                            = 2000000U;
1139  *   flexcanConfig->maxMbNum                             = 16;
1140  *   flexcanConfig->enableLoopBack                       = false;
1141  *   flexcanConfig->enableSelfWakeup                     = false;
1142  *   flexcanConfig->enableIndividMask                    = false;
1143  *   flexcanConfig->disableSelfReception                 = false;
1144  *   flexcanConfig->enableListenOnlyMode                 = false;
1145  *   flexcanConfig->enableDoze                           = false;
1146  *   flexcanConfig->enablePretendedeNetworking           = false;
1147  *   flexcanConfig->enableMemoryErrorControl             = true;
1148  *   flexcanConfig->enableNonCorrectableErrorEnterFreeze = true;
1149  *   flexcanConfig->enableTransceiverDelayMeasure        = true;
1150  *   flexcanConfig.timingConfig                          = timingConfig;
1151  *
1152  * param pConfig Pointer to the FlexCAN configuration structure.
1153  */
1154 void FLEXCAN_GetDefaultConfig(flexcan_config_t *pConfig)
1155 {
1156     /* Assertion. */
1157     assert(NULL != pConfig);
1158 
1159     /* Initializes the configure structure to zero. */
1160     (void)memset(pConfig, 0, sizeof(*pConfig));
1161 
1162     /* Initialize FlexCAN Module config struct with default value. */
1163     pConfig->clkSrc  = kFLEXCAN_ClkSrc0;
1164     pConfig->bitRate = 1000000U;
1165 #if (defined(FSL_FEATURE_FLEXCAN_HAS_FLEXIBLE_DATA_RATE) && FSL_FEATURE_FLEXCAN_HAS_FLEXIBLE_DATA_RATE)
1166     pConfig->bitRateFD = 2000000U;
1167 #endif
1168     pConfig->maxMbNum             = 16;
1169     pConfig->enableLoopBack       = false;
1170     pConfig->enableTimerSync      = true;
1171     pConfig->enableSelfWakeup     = false;
1172     pConfig->wakeupSrc            = kFLEXCAN_WakeupSrcUnfiltered;
1173     pConfig->enableIndividMask    = false;
1174     pConfig->disableSelfReception = false;
1175     pConfig->enableListenOnlyMode = false;
1176 #if !(defined(FSL_FEATURE_FLEXCAN_HAS_NO_SUPV_SUPPORT) && FSL_FEATURE_FLEXCAN_HAS_NO_SUPV_SUPPORT)
1177     pConfig->enableSupervisorMode = true;
1178 #endif
1179 #if (defined(FSL_FEATURE_FLEXCAN_HAS_DOZE_MODE_SUPPORT) && FSL_FEATURE_FLEXCAN_HAS_DOZE_MODE_SUPPORT)
1180     pConfig->enableDoze = false;
1181 #endif
1182 #if (defined(FSL_FEATURE_FLEXCAN_HAS_PN_MODE) && FSL_FEATURE_FLEXCAN_HAS_PN_MODE)
1183     pConfig->enablePretendedeNetworking = false;
1184 #endif
1185 #if (defined(FSL_FEATURE_FLEXCAN_HAS_MEMORY_ERROR_CONTROL) && FSL_FEATURE_FLEXCAN_HAS_MEMORY_ERROR_CONTROL)
1186     pConfig->enableMemoryErrorControl             = true;
1187     pConfig->enableNonCorrectableErrorEnterFreeze = true;
1188 #endif
1189 #if (defined(FSL_FEATURE_FLEXCAN_HAS_ENHANCED_BIT_TIMING_REG) && FSL_FEATURE_FLEXCAN_HAS_ENHANCED_BIT_TIMING_REG)
1190     pConfig->enableTransceiverDelayMeasure = true;
1191 #endif
1192 
1193     /* Default protocol timing configuration, nominal bit time quantum is 10 (80% SP), data bit time quantum is 5
1194      * (60%). Suggest use FLEXCAN_CalculateImprovedTimingValues/FLEXCAN_FDCalculateImprovedTimingValues to get the
1195      * improved timing configuration.*/
1196 #if (defined(FSL_FEATURE_FLEXCAN_HAS_FLEXIBLE_DATA_RATE) && FSL_FEATURE_FLEXCAN_HAS_FLEXIBLE_DATA_RATE)
1197     pConfig->timingConfig.phaseSeg1   = 1;
1198     pConfig->timingConfig.phaseSeg2   = 1;
1199     pConfig->timingConfig.propSeg     = 4;
1200     pConfig->timingConfig.rJumpwidth  = 1;
1201     pConfig->timingConfig.fphaseSeg1  = 1;
1202     pConfig->timingConfig.fphaseSeg2  = 1;
1203     pConfig->timingConfig.fpropSeg    = 0;
1204     pConfig->timingConfig.frJumpwidth = 1;
1205 #else
1206     pConfig->timingConfig.phaseSeg1  = 1;
1207     pConfig->timingConfig.phaseSeg2  = 1;
1208     pConfig->timingConfig.propSeg    = 4;
1209     pConfig->timingConfig.rJumpwidth = 1;
1210 #endif
1211 }
1212 
1213 #if (defined(FSL_FEATURE_FLEXCAN_HAS_PN_MODE) && FSL_FEATURE_FLEXCAN_HAS_PN_MODE)
1214 /*!
1215  * brief Configures the FlexCAN Pretended Networking mode.
1216  *
1217  * This function configures the FlexCAN Pretended Networking mode with given configuration.
1218  *
1219  * param base FlexCAN peripheral base address.
1220  * param pConfig Pointer to the FlexCAN Rx FIFO configuration structure.
1221  */
1222 void FLEXCAN_SetPNConfig(CAN_Type *base, const flexcan_pn_config_t *pConfig)
1223 {
1224     /* Assertion. */
1225     assert(NULL != pConfig);
1226     assert(0U != pConfig->matchNum);
1227     uint32_t pnctrl;
1228     /* Enter Freeze Mode. */
1229     FLEXCAN_EnterFreezeMode(base);
1230     pnctrl = (pConfig->matchNum > 1U) ? CAN_CTRL1_PN_FCS(0x2U | (uint32_t)pConfig->matchSrc) :
1231                                         CAN_CTRL1_PN_FCS(pConfig->matchSrc);
1232     pnctrl |= (pConfig->enableMatch) ? (CAN_CTRL1_PN_WUMF_MSK_MASK) : 0U;
1233     pnctrl |= (pConfig->enableTimeout) ? (CAN_CTRL1_PN_WTOF_MSK_MASK) : 0U;
1234     pnctrl |= CAN_CTRL1_PN_NMATCH(pConfig->matchNum) | CAN_CTRL1_PN_IDFS(pConfig->idMatchMode) |
1235               CAN_CTRL1_PN_PLFS(pConfig->dataMatchMode);
1236     base->CTRL1_PN       = pnctrl;
1237     base->CTRL2_PN       = CAN_CTRL2_PN_MATCHTO(pConfig->timeoutValue);
1238     base->FLT_ID1        = pConfig->idLower;
1239     base->FLT_ID2_IDMASK = pConfig->idUpper;
1240     base->FLT_DLC        = CAN_FLT_DLC_FLT_DLC_LO(pConfig->lengthLower) | CAN_FLT_DLC_FLT_DLC_HI(pConfig->lengthUpper);
1241     base->PL1_LO         = pConfig->lowerWord0;
1242     base->PL1_HI         = pConfig->lowerWord1;
1243     base->PL2_PLMASK_LO  = pConfig->upperWord0;
1244     base->PL2_PLMASK_HI  = pConfig->upperWord1;
1245 
1246     FLEXCAN_ClearStatusFlags(base, (uint64_t)kFLEXCAN_PNMatchIntFlag | (uint64_t)kFLEXCAN_PNTimeoutIntFlag);
1247 
1248     /* Exit Freeze Mode. */
1249     FLEXCAN_ExitFreezeMode(base);
1250 }
1251 
1252 /*!
1253  * brief Reads a FlexCAN Message from Wake Up MB.
1254  *
1255  * This function reads a CAN message from the FlexCAN Wake up Message Buffers. There are four Wake up Message Buffers
1256  * (WMBs) used to store incoming messages in Pretended Networking mode. The WMB index indicates the arrival order. The
1257  * last message is stored in WMB3.
1258  *
1259  * param base FlexCAN peripheral base address.
1260  * param pRxFrame Pointer to CAN message frame structure for reception.
1261  * param mbIdx The FlexCAN Wake up Message Buffer index. Range in 0x0 ~ 0x3.
1262  * retval kStatus_Success - Read Message from Wake up Message Buffer successfully.
1263  * retval kStatus_Fail    - Wake up Message Buffer has no valid content.
1264  */
1265 status_t FLEXCAN_ReadPNWakeUpMB(CAN_Type *base, uint8_t mbIdx, flexcan_frame_t *pRxFrame)
1266 {
1267     /* Assertion. */
1268     assert(NULL != pRxFrame);
1269     assert(mbIdx <= 0x3U);
1270 
1271     uint32_t cs_temp;
1272     status_t status;
1273 
1274     /* Check if Wake Up MB has valid content. */
1275     if (CAN_WU_MTC_MCOUNTER(mbIdx) < (base->WU_MTC & CAN_WU_MTC_MCOUNTER_MASK))
1276     {
1277         /* Read CS field of wake up Message Buffer. */
1278         cs_temp = base->WMB[mbIdx].CS;
1279 
1280         /* Store Message ID. */
1281         pRxFrame->id = base->WMB[mbIdx].ID & (CAN_ID_EXT_MASK | CAN_ID_STD_MASK);
1282 
1283         /* Get the message ID and format. */
1284         pRxFrame->format = (cs_temp & CAN_CS_IDE_MASK) != 0U ? (uint8_t)kFLEXCAN_FrameFormatExtend :
1285                                                                (uint8_t)kFLEXCAN_FrameFormatStandard;
1286 
1287         /* Get the message type. */
1288         pRxFrame->type =
1289             (cs_temp & CAN_CS_RTR_MASK) != 0U ? (uint8_t)kFLEXCAN_FrameTypeRemote : (uint8_t)kFLEXCAN_FrameTypeData;
1290 
1291         /* Get the message length. */
1292         pRxFrame->length = (uint8_t)((cs_temp & CAN_CS_DLC_MASK) >> CAN_CS_DLC_SHIFT);
1293 
1294         /* Messages received during Pretended Networking mode don't have time stamps, and the respective field in the
1295            WMB structure must be ignored. */
1296         pRxFrame->timestamp = 0x0;
1297 
1298         /* Store Message Payload. */
1299         pRxFrame->dataWord0 = base->WMB[mbIdx].D03;
1300         pRxFrame->dataWord1 = base->WMB[mbIdx].D47;
1301 
1302         status = kStatus_Success;
1303     }
1304     else
1305     {
1306         status = kStatus_Fail;
1307     }
1308 
1309     return status;
1310 }
1311 #endif
1312 
1313 /*!
1314  * brief Sets the FlexCAN classical protocol timing characteristic.
1315  *
1316  * This function gives user settings to classical CAN or CAN FD nominal phase timing characteristic.
1317  * The function is for an experienced user. For less experienced users, call the FLEXCAN_GetDefaultConfig()
1318  * and get the default timing characteristicsthe, then call FLEXCAN_Init() and fill the
1319  * bit rate field.
1320  *
1321  * note Calling FLEXCAN_SetTimingConfig() overrides the bit rate set
1322  * in FLEXCAN_Init().
1323  *
1324  * param base FlexCAN peripheral base address.
1325  * param pConfig Pointer to the timing configuration structure.
1326  */
1327 void FLEXCAN_SetTimingConfig(CAN_Type *base, const flexcan_timing_config_t *pConfig)
1328 {
1329     /* Assertion. */
1330     assert(NULL != pConfig);
1331 
1332     /* Enter Freeze Mode. */
1333     FLEXCAN_EnterFreezeMode(base);
1334 
1335 #if (defined(FSL_FEATURE_FLEXCAN_HAS_FLEXIBLE_DATA_RATE) && FSL_FEATURE_FLEXCAN_HAS_FLEXIBLE_DATA_RATE)
1336     if (0 != FSL_FEATURE_FLEXCAN_INSTANCE_HAS_FLEXIBLE_DATA_RATEn(base))
1337     {
1338 #if (defined(FSL_FEATURE_FLEXCAN_HAS_ENHANCED_BIT_TIMING_REG) && FSL_FEATURE_FLEXCAN_HAS_ENHANCED_BIT_TIMING_REG)
1339         /* Enable extended Bit Timing register ENCBT. */
1340         base->CTRL2 |= CAN_CTRL2_BTE_MASK;
1341 
1342         /* Updating Timing Setting according to configuration structure. */
1343         base->EPRS  = (base->EPRS & (~CAN_EPRS_ENPRESDIV_MASK)) | CAN_EPRS_ENPRESDIV(pConfig->preDivider);
1344         base->ENCBT = CAN_ENCBT_NRJW(pConfig->rJumpwidth) |
1345                       CAN_ENCBT_NTSEG1((uint32_t)pConfig->phaseSeg1 + pConfig->propSeg + 1U) |
1346                       CAN_ENCBT_NTSEG2(pConfig->phaseSeg2);
1347 #else
1348         /* On RT106x devices, a single write may be ignored, so it is necessary to read back the register value to
1349          * determine whether the value is written successfully. */
1350 
1351         do
1352         {
1353             /* Enable Bit Timing register CBT, updating Timing Setting according to configuration structure. */
1354             base->CBT = CAN_CBT_BTF_MASK | CAN_CBT_EPRESDIV(pConfig->preDivider) | CAN_CBT_ERJW(pConfig->rJumpwidth) |
1355                         CAN_CBT_EPSEG1(pConfig->phaseSeg1) | CAN_CBT_EPSEG2(pConfig->phaseSeg2) |
1356                         CAN_CBT_EPROPSEG(pConfig->propSeg);
1357 
1358         } while ((CAN_CBT_EPRESDIV(pConfig->preDivider) | CAN_CBT_ERJW(pConfig->rJumpwidth) |
1359                   CAN_CBT_EPSEG1(pConfig->phaseSeg1) | CAN_CBT_EPSEG2(pConfig->phaseSeg2) |
1360                   CAN_CBT_EPROPSEG(pConfig->propSeg)) !=
1361                  (base->CBT & (CAN_CBT_EPRESDIV_MASK | CAN_CBT_ERJW_MASK | CAN_CBT_EPSEG1_MASK | CAN_CBT_EPSEG2_MASK |
1362                                CAN_CBT_EPROPSEG_MASK)));
1363 #endif
1364     }
1365     else
1366     {
1367         /* Cleaning previous Timing Setting. */
1368         base->CTRL1 &= ~(CAN_CTRL1_PRESDIV_MASK | CAN_CTRL1_RJW_MASK | CAN_CTRL1_PSEG1_MASK | CAN_CTRL1_PSEG2_MASK |
1369                          CAN_CTRL1_PROPSEG_MASK);
1370 
1371         /* Updating Timing Setting according to configuration structure. */
1372         base->CTRL1 |= (CAN_CTRL1_PRESDIV(pConfig->preDivider) | CAN_CTRL1_RJW(pConfig->rJumpwidth) |
1373                         CAN_CTRL1_PSEG1(pConfig->phaseSeg1) | CAN_CTRL1_PSEG2(pConfig->phaseSeg2) |
1374                         CAN_CTRL1_PROPSEG(pConfig->propSeg));
1375     }
1376 #else
1377     /* Cleaning previous Timing Setting. */
1378     base->CTRL1 &= ~(CAN_CTRL1_PRESDIV_MASK | CAN_CTRL1_RJW_MASK | CAN_CTRL1_PSEG1_MASK | CAN_CTRL1_PSEG2_MASK |
1379                      CAN_CTRL1_PROPSEG_MASK);
1380 
1381     /* Updating Timing Setting according to configuration structure. */
1382     base->CTRL1 |= (CAN_CTRL1_PRESDIV(pConfig->preDivider) | CAN_CTRL1_RJW(pConfig->rJumpwidth) |
1383                     CAN_CTRL1_PSEG1(pConfig->phaseSeg1) | CAN_CTRL1_PSEG2(pConfig->phaseSeg2) |
1384                     CAN_CTRL1_PROPSEG(pConfig->propSeg));
1385 #endif
1386 
1387     /* Exit Freeze Mode. */
1388     FLEXCAN_ExitFreezeMode(base);
1389 }
1390 
1391 #if (defined(FSL_FEATURE_FLEXCAN_HAS_FLEXIBLE_DATA_RATE) && FSL_FEATURE_FLEXCAN_HAS_FLEXIBLE_DATA_RATE)
1392 /*!
1393  * brief Sets the FlexCAN FD data phase timing characteristic.
1394  *
1395  * This function gives user settings to CAN FD data phase timing characteristic.
1396  * The function is for an experienced user. For less experienced users, call the FLEXCAN_GetDefaultConfig()
1397  * and get the default timing characteristicsthe, then call FLEXCAN_FDInit() and fill the
1398  * data phase bit rate field.
1399  *
1400  * note Calling FLEXCAN_SetFDTimingConfig() overrides the bit rate set
1401  * in FLEXCAN_FDInit().
1402  *
1403  * param base FlexCAN peripheral base address.
1404  * param pConfig Pointer to the timing configuration structure.
1405  */
1406 void FLEXCAN_SetFDTimingConfig(CAN_Type *base, const flexcan_timing_config_t *pConfig)
1407 {
1408     /* Assertion. */
1409     assert(NULL != pConfig);
1410 
1411     /* Enter Freeze Mode. */
1412     FLEXCAN_EnterFreezeMode(base);
1413 
1414 #if (defined(FSL_FEATURE_FLEXCAN_HAS_ENHANCED_BIT_TIMING_REG) && FSL_FEATURE_FLEXCAN_HAS_ENHANCED_BIT_TIMING_REG)
1415     /* Enable extended Bit Timing register EDCBT. */
1416     base->CTRL2 |= CAN_CTRL2_BTE_MASK;
1417 
1418     base->EPRS  = (base->EPRS & (~CAN_EPRS_EDPRESDIV_MASK)) | CAN_EPRS_EDPRESDIV(pConfig->fpreDivider);
1419     base->EDCBT = CAN_EDCBT_DRJW(pConfig->frJumpwidth) | CAN_EDCBT_DTSEG2(pConfig->fphaseSeg2) |
1420                   CAN_EDCBT_DTSEG1((uint32_t)pConfig->fphaseSeg1 + pConfig->fpropSeg);
1421 #else
1422     /* Enable Bit Timing register FDCBT,*/
1423     base->CBT |= CAN_CBT_BTF_MASK;
1424 
1425     /* On RT106x devices, a single write may be ignored, so it is necessary to read back the register value to determine
1426      * whether the value is written successfully. */
1427     do
1428     {
1429         /* Updating Timing Setting according to configuration structure. */
1430         base->FDCBT = (CAN_FDCBT_FPRESDIV(pConfig->fpreDivider) | CAN_FDCBT_FRJW(pConfig->frJumpwidth) |
1431                        CAN_FDCBT_FPSEG1(pConfig->fphaseSeg1) | CAN_FDCBT_FPSEG2(pConfig->fphaseSeg2) |
1432                        CAN_FDCBT_FPROPSEG(pConfig->fpropSeg));
1433     } while ((CAN_FDCBT_FPRESDIV(pConfig->fpreDivider) | CAN_FDCBT_FRJW(pConfig->frJumpwidth) |
1434               CAN_FDCBT_FPSEG1(pConfig->fphaseSeg1) | CAN_FDCBT_FPSEG2(pConfig->fphaseSeg2) |
1435               CAN_FDCBT_FPROPSEG(pConfig->fpropSeg)) !=
1436              (base->FDCBT & (CAN_FDCBT_FPRESDIV_MASK | CAN_FDCBT_FRJW_MASK | CAN_FDCBT_FPSEG1_MASK |
1437                              CAN_FDCBT_FPSEG2_MASK | CAN_FDCBT_FPROPSEG_MASK)));
1438 #endif
1439     /* Exit Freeze Mode. */
1440     FLEXCAN_ExitFreezeMode(base);
1441 }
1442 #endif
1443 
1444 /*!
1445  * brief Sets the FlexCAN receive message buffer global mask.
1446  *
1447  * This function sets the global mask for the FlexCAN message buffer in a matching process.
1448  * The configuration is only effective when the Rx individual mask is disabled in the FLEXCAN_Init().
1449  *
1450  * param base FlexCAN peripheral base address.
1451  * param mask Rx Message Buffer Global Mask value.
1452  */
1453 void FLEXCAN_SetRxMbGlobalMask(CAN_Type *base, uint32_t mask)
1454 {
1455     /* Enter Freeze Mode. */
1456     FLEXCAN_EnterFreezeMode(base);
1457 
1458     /* Setting Rx Message Buffer Global Mask value. */
1459     base->RXMGMASK = mask;
1460     base->RX14MASK = mask;
1461     base->RX15MASK = mask;
1462 
1463     /* Exit Freeze Mode. */
1464     FLEXCAN_ExitFreezeMode(base);
1465 }
1466 
1467 /*!
1468  * brief Sets the FlexCAN receive FIFO global mask.
1469  *
1470  * This function sets the global mask for FlexCAN FIFO in a matching process.
1471  *
1472  * param base FlexCAN peripheral base address.
1473  * param mask Rx Fifo Global Mask value.
1474  */
1475 void FLEXCAN_SetRxFifoGlobalMask(CAN_Type *base, uint32_t mask)
1476 {
1477     /* Enter Freeze Mode. */
1478     FLEXCAN_EnterFreezeMode(base);
1479 
1480     /* Setting Rx FIFO Global Mask value. */
1481     base->RXFGMASK = mask;
1482 
1483     /* Exit Freeze Mode. */
1484     FLEXCAN_ExitFreezeMode(base);
1485 }
1486 
1487 /*!
1488  * brief Sets the FlexCAN receive individual mask.
1489  *
1490  * This function sets the individual mask for the FlexCAN matching process.
1491  * The configuration is only effective when the Rx individual mask is enabled in the FLEXCAN_Init().
1492  * If the Rx FIFO is disabled, the individual mask is applied to the corresponding Message Buffer.
1493  * If the Rx FIFO is enabled, the individual mask for Rx FIFO occupied Message Buffer is applied to
1494  * the Rx Filter with the same index. Note that only the first 32
1495  * individual masks can be used as the Rx FIFO filter mask.
1496  *
1497  * param base FlexCAN peripheral base address.
1498  * param maskIdx The Index of individual Mask.
1499  * param mask Rx Individual Mask value.
1500  */
1501 void FLEXCAN_SetRxIndividualMask(CAN_Type *base, uint8_t maskIdx, uint32_t mask)
1502 {
1503     assert(maskIdx <= (base->MCR & CAN_MCR_MAXMB_MASK));
1504 
1505     /* Enter Freeze Mode. */
1506     FLEXCAN_EnterFreezeMode(base);
1507 
1508     /* Setting Rx Individual Mask value. */
1509     base->RXIMR[maskIdx] = mask;
1510 
1511     /* Exit Freeze Mode. */
1512     FLEXCAN_ExitFreezeMode(base);
1513 }
1514 
1515 /*!
1516  * brief Configures a FlexCAN transmit message buffer.
1517  *
1518  * This function aborts the previous transmission, cleans the Message Buffer, and
1519  * configures it as a Transmit Message Buffer.
1520  *
1521  * param base FlexCAN peripheral base address.
1522  * param mbIdx The Message Buffer index.
1523  * param enable Enable/disable Tx Message Buffer.
1524  *               - true: Enable Tx Message Buffer.
1525  *               - false: Disable Tx Message Buffer.
1526  */
1527 void FLEXCAN_SetTxMbConfig(CAN_Type *base, uint8_t mbIdx, bool enable)
1528 {
1529     /* Assertion. */
1530     assert(mbIdx <= (base->MCR & CAN_MCR_MAXMB_MASK));
1531 #if !defined(NDEBUG)
1532     assert(!FLEXCAN_IsMbOccupied(base, mbIdx));
1533 #endif
1534 
1535     /* Inactivate Message Buffer. */
1536     if (enable)
1537     {
1538         base->MB[mbIdx].CS = CAN_CS_CODE(kFLEXCAN_TxMbInactive);
1539     }
1540     else
1541     {
1542         base->MB[mbIdx].CS = 0;
1543     }
1544 
1545     /* Clean Message Buffer content. */
1546     base->MB[mbIdx].ID    = 0x0;
1547     base->MB[mbIdx].WORD0 = 0x0;
1548     base->MB[mbIdx].WORD1 = 0x0;
1549 }
1550 
1551 /*!
1552  * brief Calculates the segment values for a single bit time for classical CAN.
1553  *
1554  * This function use to calculates the Classical CAN segment values which will be set in CTRL1/CBT/ENCBT register.
1555  *
1556  * param bitRate The classical CAN bit rate in bps.
1557  * param base FlexCAN peripheral base address.
1558  * param tqNum Number of time quantas per bit, range in 8 ~ 25 when use CTRL1, range in 8 ~ 129 when use CBT, range in
1559  *             8 ~ 385 when use ENCBT. param pTimingConfig Pointer to the FlexCAN timing configuration structure.
1560  */
1561 static void FLEXCAN_GetSegments(CAN_Type *base,
1562                                 uint32_t bitRate,
1563                                 uint32_t tqNum,
1564                                 flexcan_timing_config_t *pTimingConfig)
1565 {
1566     uint32_t ideal_sp;
1567     uint32_t seg1Max, proSegMax;
1568     uint32_t seg1Temp;
1569 #if (defined(FSL_FEATURE_FLEXCAN_HAS_FLEXIBLE_DATA_RATE) && FSL_FEATURE_FLEXCAN_HAS_FLEXIBLE_DATA_RATE)
1570     if (0 != FSL_FEATURE_FLEXCAN_INSTANCE_HAS_FLEXIBLE_DATA_RATEn(base))
1571     {
1572 #if (defined(FSL_FEATURE_FLEXCAN_HAS_ENHANCED_BIT_TIMING_REG) && FSL_FEATURE_FLEXCAN_HAS_ENHANCED_BIT_TIMING_REG)
1573         /* Maximum value allowed in ENCBT register. */
1574         seg1Max   = MAX_NTSEG2 + 1U;
1575         proSegMax = MAX_NTSEG1 - MAX_NTSEG2;
1576 #else
1577         /* Maximum value allowed in CBT register. */
1578         seg1Max = MAX_EPSEG1 + 1U;
1579         proSegMax = MAX_EPROPSEG + 1U;
1580 #endif
1581     }
1582     else
1583     {
1584         /* Maximum value allowed in CTRL1 register. */
1585         seg1Max   = MAX_PSEG1 + 1U;
1586         proSegMax = MAX_PROPSEG + 1U;
1587     }
1588 #else
1589     /* Maximum value allowed in CTRL1 register. */
1590     seg1Max   = MAX_PSEG1 + 1U;
1591     proSegMax = MAX_PROPSEG + 1U;
1592 #endif
1593 
1594     /* Try to find the ideal sample point, according to CiA 301 doc.*/
1595     if (bitRate == 1000000U)
1596     {
1597         ideal_sp = IDEAL_SP_LOW;
1598     }
1599     else if (bitRate >= 800000U)
1600     {
1601         ideal_sp = IDEAL_SP_MID;
1602     }
1603     else
1604     {
1605         ideal_sp = IDEAL_SP_HIGH;
1606     }
1607     /* Calculates phaseSeg2. */
1608     pTimingConfig->phaseSeg2 = (uint8_t)(tqNum - (tqNum * ideal_sp) / (uint32_t)IDEAL_SP_FACTOR);
1609     if (pTimingConfig->phaseSeg2 < MIN_TIME_SEGMENT2)
1610     {
1611         pTimingConfig->phaseSeg2 = MIN_TIME_SEGMENT2;
1612     }
1613 
1614 #if (defined(FSL_FEATURE_FLEXCAN_HAS_FLEXIBLE_DATA_RATE) && FSL_FEATURE_FLEXCAN_HAS_FLEXIBLE_DATA_RATE)
1615     if (0 != FSL_FEATURE_FLEXCAN_INSTANCE_HAS_FLEXIBLE_DATA_RATEn(base))
1616     {
1617 #if !(defined(FSL_FEATURE_FLEXCAN_HAS_ENHANCED_BIT_TIMING_REG) && FSL_FEATURE_FLEXCAN_HAS_ENHANCED_BIT_TIMING_REG)
1618         if (pTimingConfig->phaseSeg2 > (uint8_t)(MAX_EPSEG2 + 1U))
1619         {
1620             pTimingConfig->phaseSeg2 = (uint8_t)(MAX_EPSEG2 + 1U);
1621         }
1622 #endif
1623     }
1624 #endif
1625 
1626     /* Calculates phaseSeg1 and propSeg and try to make phaseSeg1 equal to phaseSeg2. */
1627     if ((tqNum - pTimingConfig->phaseSeg2 - 1U) > (seg1Max + proSegMax))
1628     {
1629         seg1Temp                 = seg1Max + proSegMax;
1630         pTimingConfig->phaseSeg2 = (uint8_t)(tqNum - 1U - seg1Temp);
1631     }
1632     else
1633     {
1634         seg1Temp = tqNum - pTimingConfig->phaseSeg2 - 1U;
1635     }
1636     if (seg1Temp > (pTimingConfig->phaseSeg2 + proSegMax))
1637     {
1638         pTimingConfig->propSeg   = (uint8_t)proSegMax;
1639         pTimingConfig->phaseSeg1 = (uint8_t)(seg1Temp - proSegMax);
1640     }
1641     else
1642     {
1643         pTimingConfig->propSeg   = (uint8_t)(seg1Temp - pTimingConfig->phaseSeg2);
1644         pTimingConfig->phaseSeg1 = pTimingConfig->phaseSeg2;
1645     }
1646 
1647     /* rJumpwidth (sjw) is the minimum value of phaseSeg1 and phaseSeg2. */
1648     pTimingConfig->rJumpwidth =
1649         (pTimingConfig->phaseSeg1 > pTimingConfig->phaseSeg2) ? pTimingConfig->phaseSeg2 : pTimingConfig->phaseSeg1;
1650 #if !(defined(FSL_FEATURE_FLEXCAN_HAS_FLEXIBLE_DATA_RATE) && FSL_FEATURE_FLEXCAN_HAS_FLEXIBLE_DATA_RATE)
1651     if (pTimingConfig->rJumpwidth > (MAX_RJW + 1U))
1652     {
1653         pTimingConfig->rJumpwidth = (uint8_t)(MAX_RJW + 1U);
1654     }
1655 #else
1656     if (0 == FSL_FEATURE_FLEXCAN_INSTANCE_HAS_FLEXIBLE_DATA_RATEn(base))
1657     {
1658         if (pTimingConfig->rJumpwidth > (MAX_RJW + 1U))
1659         {
1660             pTimingConfig->rJumpwidth = (uint8_t)(MAX_RJW + 1U);
1661         }
1662     }
1663 #endif
1664 
1665     pTimingConfig->phaseSeg1 -= 1U;
1666     pTimingConfig->phaseSeg2 -= 1U;
1667     pTimingConfig->propSeg -= 1U;
1668     pTimingConfig->rJumpwidth -= 1U;
1669 }
1670 
1671 /*!
1672  * brief Calculates the improved timing values by specific bit Rates for classical CAN.
1673  *
1674  * This function use to calculates the Classical CAN timing values according to the given bit rate. The Calculated
1675  * timing values will be set in CTRL1/CBT/ENCBT register. The calculation is based on the recommendation of the CiA 301
1676  * v4.2.0 and previous version document.
1677  *
1678  * param base FlexCAN peripheral base address.
1679  * param bitRate  The classical CAN speed in bps defined by user, should be less than or equal to 1Mbps.
1680  * param sourceClock_Hz The Source clock frequency in Hz.
1681  * param pTimingConfig Pointer to the FlexCAN timing configuration structure.
1682  *
1683  * return TRUE if timing configuration found, FALSE if failed to find configuration.
1684  */
1685 bool FLEXCAN_CalculateImprovedTimingValues(CAN_Type *base,
1686                                            uint32_t bitRate,
1687                                            uint32_t sourceClock_Hz,
1688                                            flexcan_timing_config_t *pTimingConfig)
1689 {
1690     /* Observe bit rate maximums. */
1691     assert(bitRate <= MAX_CAN_BITRATE);
1692 
1693     uint32_t clk;
1694     uint32_t tqNum, tqMin, pdivMAX;
1695     uint32_t spTemp                    = 1000U;
1696     flexcan_timing_config_t configTemp = {0};
1697     bool fgRet                         = false;
1698 #if (defined(FSL_FEATURE_FLEXCAN_HAS_FLEXIBLE_DATA_RATE) && FSL_FEATURE_FLEXCAN_HAS_FLEXIBLE_DATA_RATE)
1699     if (0 != FSL_FEATURE_FLEXCAN_INSTANCE_HAS_FLEXIBLE_DATA_RATEn(base))
1700     {
1701 #if (defined(FSL_FEATURE_FLEXCAN_HAS_ENHANCED_BIT_TIMING_REG) && FSL_FEATURE_FLEXCAN_HAS_ENHANCED_BIT_TIMING_REG)
1702         /*  Auto Improved Protocal timing for ENCBT. */
1703         tqNum   = ENCBT_MAX_TIME_QUANTA;
1704         tqMin   = ENCBT_MIN_TIME_QUANTA;
1705         pdivMAX = MAX_ENPRESDIV;
1706 #else
1707         /*  Auto Improved Protocal timing for CBT. */
1708         tqNum = CBT_MAX_TIME_QUANTA;
1709         tqMin = CBT_MIN_TIME_QUANTA;
1710         pdivMAX = MAX_PRESDIV;
1711 #endif
1712     }
1713     else
1714     {
1715         /*  Auto Improved Protocal timing for CTRL1. */
1716         tqNum   = CTRL1_MAX_TIME_QUANTA;
1717         tqMin   = CTRL1_MIN_TIME_QUANTA;
1718         pdivMAX = MAX_PRESDIV;
1719     }
1720 #else
1721     /*  Auto Improved Protocal timing for CTRL1. */
1722     tqNum   = CTRL1_MAX_TIME_QUANTA;
1723     tqMin   = CTRL1_MIN_TIME_QUANTA;
1724     pdivMAX = MAX_PRESDIV;
1725 #endif
1726     do
1727     {
1728         clk = bitRate * tqNum;
1729         if (clk > sourceClock_Hz)
1730         {
1731             continue; /* tqNum too large, clk has been exceed sourceClock_Hz. */
1732         }
1733 
1734         if ((sourceClock_Hz / clk * clk) != sourceClock_Hz)
1735         {
1736             continue; /* Non-supporting: the frequency of clock source is not divisible by target bit rate, the user
1737                       should change a divisible bit rate. */
1738         }
1739 
1740         configTemp.preDivider = (uint16_t)(sourceClock_Hz / clk) - 1U;
1741         if (configTemp.preDivider > pdivMAX)
1742         {
1743             break; /* The frequency of source clock is too large or the bit rate is too small, the pre-divider could
1744                       not handle it. */
1745         }
1746 
1747         /* Calculates the best timing configuration under current tqNum. */
1748         FLEXCAN_GetSegments(base, bitRate, tqNum, &configTemp);
1749         /* Determine whether the calculated timing configuration can get the optimal sampling point. */
1750         if (((((uint32_t)configTemp.phaseSeg2 + 1U) * 1000U) / tqNum) < spTemp)
1751         {
1752             spTemp                    = (((uint32_t)configTemp.phaseSeg2 + 1U) * 1000U) / tqNum;
1753             pTimingConfig->preDivider = configTemp.preDivider;
1754             pTimingConfig->rJumpwidth = configTemp.rJumpwidth;
1755             pTimingConfig->phaseSeg1  = configTemp.phaseSeg1;
1756             pTimingConfig->phaseSeg2  = configTemp.phaseSeg2;
1757             pTimingConfig->propSeg    = configTemp.propSeg;
1758         }
1759         fgRet = true;
1760     } while (--tqNum >= tqMin);
1761 
1762     return fgRet;
1763 }
1764 
1765 #if (defined(FSL_FEATURE_FLEXCAN_HAS_FLEXIBLE_DATA_RATE) && FSL_FEATURE_FLEXCAN_HAS_FLEXIBLE_DATA_RATE)
1766 /*!
1767  * brief Get Mailbox offset number by dword.
1768  *
1769  * This function gets the offset number of the specified mailbox.
1770  * Mailbox is not consecutive between memory regions when payload is not 8 bytes
1771  * so need to calculate the specified mailbox address.
1772  * For example, in the first memory region, MB[0].CS address is 0x4002_4080. For 32 bytes
1773  * payload frame, the second mailbox is ((1/12)*512 + 1%12*40)/4 = 10, meaning 10 dword
1774  * after the 0x4002_4080, which is actually the address of mailbox MB[1].CS.
1775  *
1776  * param base FlexCAN peripheral base address.
1777  * param mbIdx Mailbox index.
1778  */
1779 static uint32_t FLEXCAN_GetFDMailboxOffset(CAN_Type *base, uint8_t mbIdx)
1780 {
1781     uint32_t offset   = 0;
1782     uint32_t dataSize = (base->FDCTRL & CAN_FDCTRL_MBDSR0_MASK) >> CAN_FDCTRL_MBDSR0_SHIFT;
1783     if (dataSize == (uint32_t)kFLEXCAN_8BperMB)
1784     {
1785         offset = (((uint32_t)mbIdx / 32U) * 512U + ((uint32_t)mbIdx % 32U) * 16U);
1786     }
1787     else if (dataSize == (uint32_t)kFLEXCAN_16BperMB)
1788     {
1789         offset = (((uint32_t)mbIdx / 21U) * 512U + ((uint32_t)mbIdx % 21U) * 24U);
1790     }
1791     else if (dataSize == (uint32_t)kFLEXCAN_32BperMB)
1792     {
1793         offset = (((uint32_t)mbIdx / 12U) * 512U + ((uint32_t)mbIdx % 12U) * 40U);
1794     }
1795     else
1796     {
1797         offset = (((uint32_t)mbIdx / 7U) * 512U + ((uint32_t)mbIdx % 7U) * 72U);
1798     }
1799 
1800     /* To get the dword aligned offset, need to divide by 4. */
1801     offset = offset / 4U;
1802     return offset;
1803 }
1804 
1805 /*!
1806  * brief Calculates the segment values for a single bit time for CAN FD data phase.
1807  *
1808  * This function use to calculates the CAN FD data phase segment values which will be set in CFDCBT/EDCBT
1809  * register.
1810  *
1811  * param bitRateFD CAN FD data phase bit rate.
1812  * param tqNum Number of time quanta per bit
1813  * param pTimingConfig Pointer to the FlexCAN timing configuration structure.
1814  */
1815 static void FLEXCAN_FDGetSegments(uint32_t bitRateFD, uint32_t tqNum, flexcan_timing_config_t *pTimingConfig)
1816 {
1817     uint32_t ideal_sp;
1818     uint32_t seg1Max, proSegMax, seg2Max;
1819     uint32_t seg1Temp;
1820 #if (defined(FSL_FEATURE_FLEXCAN_HAS_ENHANCED_BIT_TIMING_REG) && FSL_FEATURE_FLEXCAN_HAS_ENHANCED_BIT_TIMING_REG)
1821     /* Maximum value allowed in EDCBT register. */
1822     seg1Max   = MAX_DTSEG2 + 1U;
1823     proSegMax = MAX_DTSEG1 - MAX_DTSEG2;
1824     seg2Max   = MAX_DTSEG2 + 1U;
1825 #else
1826     /* Maximum value allowed in FDCBT register. */
1827     seg1Max = MAX_FPSEG1 + 1U;
1828     proSegMax = MAX_FPROPSEG;
1829     seg2Max = MAX_FPSEG2 + 1U;
1830 #endif
1831 
1832     /* According to CiA doc 1301 v1.0.0, which specified data phase sample point postion for CAN FD at 80 MHz. */
1833     if (bitRateFD <= 1000000U)
1834     {
1835         ideal_sp = IDEAL_DATA_SP_1;
1836     }
1837     else if (bitRateFD <= 2000000U)
1838     {
1839         ideal_sp = IDEAL_DATA_SP_2;
1840     }
1841     else if (bitRateFD <= 4000000U)
1842     {
1843         ideal_sp = IDEAL_DATA_SP_3;
1844     }
1845     else
1846     {
1847         ideal_sp = IDEAL_DATA_SP_4;
1848     }
1849 
1850     /* Calculates fphaseSeg2. */
1851     pTimingConfig->fphaseSeg2 = (uint8_t)(tqNum - (tqNum * ideal_sp) / (uint32_t)IDEAL_SP_FACTOR);
1852     if (pTimingConfig->fphaseSeg2 < MIN_TIME_SEGMENT2)
1853     {
1854         pTimingConfig->fphaseSeg2 = MIN_TIME_SEGMENT2;
1855     }
1856     else if (pTimingConfig->fphaseSeg2 > seg2Max)
1857     {
1858         pTimingConfig->fphaseSeg2 = (uint8_t)seg2Max;
1859     }
1860     else
1861     {
1862         ; /* Intentional empty */
1863     }
1864 
1865     /* Calculates fphaseSeg1 and fpropSeg and try to make phaseSeg1 equal to phaseSeg2 */
1866     if ((tqNum - pTimingConfig->fphaseSeg2 - 1U) > (seg1Max + proSegMax))
1867     {
1868         seg1Temp                  = seg1Max + proSegMax;
1869         pTimingConfig->fphaseSeg2 = (uint8_t)(tqNum - 1U - seg1Temp);
1870     }
1871     else
1872     {
1873         seg1Temp = tqNum - pTimingConfig->fphaseSeg2 - 1U;
1874     }
1875     if (seg1Temp > (pTimingConfig->fphaseSeg2 + proSegMax))
1876     {
1877         pTimingConfig->fpropSeg   = (uint8_t)proSegMax;
1878         pTimingConfig->fphaseSeg1 = (uint8_t)(seg1Temp - proSegMax);
1879     }
1880     else if (seg1Temp > pTimingConfig->fphaseSeg2)
1881     {
1882         pTimingConfig->fpropSeg   = (uint8_t)(seg1Temp - pTimingConfig->fphaseSeg2);
1883         pTimingConfig->fphaseSeg1 = pTimingConfig->fphaseSeg2;
1884     }
1885     else
1886     {
1887         pTimingConfig->fpropSeg   = 0U;
1888         pTimingConfig->fphaseSeg1 = (uint8_t)seg1Temp;
1889     }
1890 
1891     /* rJumpwidth (sjw) is the minimum value of phaseSeg1 and phaseSeg2. */
1892     pTimingConfig->frJumpwidth =
1893         (pTimingConfig->fphaseSeg1 > pTimingConfig->fphaseSeg2) ? pTimingConfig->fphaseSeg2 : pTimingConfig->fphaseSeg1;
1894 
1895     pTimingConfig->fphaseSeg1 -= 1U;
1896     pTimingConfig->fphaseSeg2 -= 1U;
1897     pTimingConfig->frJumpwidth -= 1U;
1898 }
1899 
1900 /*!
1901  * brief Calculates the improved timing values by specific bit rate for CAN FD nominal phase.
1902  *
1903  * This function use to calculates the CAN FD nominal phase timing values according to the given nominal phase bit rate.
1904  * The Calculated timing values will be set in CBT/ENCBT registers. The calculation is based on the recommendation of
1905  * the CiA 1301 v1.0.0 document.
1906  *
1907  * param bitRate  The CAN FD nominal phase speed in bps defined by user, should be less than or equal to 1Mbps.
1908  * param sourceClock_Hz The Source clock frequency in Hz.
1909  * param pTimingConfig Pointer to the FlexCAN timing configuration structure.
1910  *
1911  * return TRUE if timing configuration found, FALSE if failed to find configuration.
1912  */
1913 static bool FLEXCAN_CalculateImprovedNominalTimingValues(uint32_t bitRate,
1914                                                          uint32_t sourceClock_Hz,
1915                                                          flexcan_timing_config_t *pTimingConfig)
1916 {
1917     /* Observe bit rate maximums. */
1918     assert(bitRate <= MAX_CAN_BITRATE);
1919 
1920     uint32_t clk;
1921     uint32_t tqNum, tqMin, pdivMAX, seg1Max, proSegMax, seg1Temp;
1922     uint32_t spTemp                    = 1000U;
1923     flexcan_timing_config_t configTemp = {0};
1924     bool fgRet                         = false;
1925 
1926 #if (defined(FSL_FEATURE_FLEXCAN_HAS_ENHANCED_BIT_TIMING_REG) && FSL_FEATURE_FLEXCAN_HAS_ENHANCED_BIT_TIMING_REG)
1927     /*  Auto Improved Protocal timing for ENCBT. */
1928     tqNum     = ENCBT_MAX_TIME_QUANTA;
1929     tqMin     = ENCBT_MIN_TIME_QUANTA;
1930     pdivMAX   = MAX_ENPRESDIV;
1931     seg1Max   = MAX_NTSEG2 + 1U;
1932     proSegMax = MAX_NTSEG1 - MAX_NTSEG2;
1933 #else
1934     /*  Auto Improved Protocal timing for CBT. */
1935     tqNum = CBT_MAX_TIME_QUANTA;
1936     tqMin = CBT_MIN_TIME_QUANTA;
1937     pdivMAX = MAX_PRESDIV;
1938     seg1Max = MAX_EPSEG1 + 1U;
1939     proSegMax = MAX_EPROPSEG + 1U;
1940 #endif
1941 
1942     do
1943     {
1944         clk = bitRate * tqNum;
1945         if (clk > sourceClock_Hz)
1946         {
1947             continue; /* tqNum too large, clk has been exceed sourceClock_Hz. */
1948         }
1949 
1950         if ((sourceClock_Hz / clk * clk) != sourceClock_Hz)
1951         {
1952             continue; /* Non-supporting: the frequency of clock source is not divisible by target bit rate, the user
1953                       should change a divisible bit rate. */
1954         }
1955 
1956         configTemp.preDivider = (uint16_t)(sourceClock_Hz / clk) - 1U;
1957         if (configTemp.preDivider > pdivMAX)
1958         {
1959             break; /* The frequency of source clock is too large or the bit rate is too small, the pre-divider could
1960                       not handle it. */
1961         }
1962 
1963         /* Calculates the best timing configuration under current tqNum. */
1964         configTemp.phaseSeg2 = (uint8_t)(tqNum - (tqNum * IDEAL_NOMINAL_SP) / (uint32_t)IDEAL_SP_FACTOR);
1965 
1966         /* Calculates phaseSeg1 and propSeg and try to make phaseSeg1 equal to phaseSeg2. */
1967         if ((tqNum - configTemp.phaseSeg2 - 1U) > (seg1Max + proSegMax))
1968         {
1969             seg1Temp             = seg1Max + proSegMax;
1970             configTemp.phaseSeg2 = (uint8_t)(tqNum - 1U - seg1Temp);
1971         }
1972         else
1973         {
1974             seg1Temp = tqNum - configTemp.phaseSeg2 - 1U;
1975         }
1976         if (seg1Temp > (configTemp.phaseSeg2 + proSegMax))
1977         {
1978             configTemp.propSeg   = (uint8_t)proSegMax;
1979             configTemp.phaseSeg1 = (uint8_t)(seg1Temp - proSegMax);
1980         }
1981         else
1982         {
1983             configTemp.propSeg   = (uint8_t)(seg1Temp - configTemp.phaseSeg2);
1984             configTemp.phaseSeg1 = configTemp.phaseSeg2;
1985         }
1986 
1987         /* rJumpwidth (sjw) is the minimum value of phaseSeg1 and phaseSeg2. */
1988         configTemp.rJumpwidth =
1989             (configTemp.phaseSeg1 > configTemp.phaseSeg2) ? configTemp.phaseSeg2 : configTemp.phaseSeg1;
1990         configTemp.phaseSeg1 -= 1U;
1991         configTemp.phaseSeg2 -= 1U;
1992         configTemp.propSeg -= 1U;
1993         configTemp.rJumpwidth -= 1U;
1994 
1995         if (((((uint32_t)configTemp.phaseSeg2 + 1U) * 1000U) / tqNum) < spTemp)
1996         {
1997             spTemp                    = (((uint32_t)configTemp.phaseSeg2 + 1U) * 1000U) / tqNum;
1998             pTimingConfig->preDivider = configTemp.preDivider;
1999             pTimingConfig->rJumpwidth = configTemp.rJumpwidth;
2000             pTimingConfig->phaseSeg1  = configTemp.phaseSeg1;
2001             pTimingConfig->phaseSeg2  = configTemp.phaseSeg2;
2002             pTimingConfig->propSeg    = configTemp.propSeg;
2003         }
2004         fgRet = true;
2005     } while (--tqNum >= tqMin);
2006 
2007     return fgRet;
2008 }
2009 
2010 /*!
2011  * brief Calculates the improved timing values by specific bit rates for CAN FD.
2012  *
2013  * This function use to calculates the CAN FD timing values according to the given nominal phase bit rate and data phase
2014  * bit rate. The Calculated timing values will be set in CBT/ENCBT and FDCBT/EDCBT registers. The calculation is based
2015  * on the recommendation of the CiA 1301 v1.0.0 document.
2016  *
2017  * param bitRate  The CAN FD nominal phase speed in bps defined by user.
2018  * param bitRateFD  The CAN FD data phase speed in bps defined by user. Equal to bitRate means disable bit rate
2019  * switching. param sourceClock_Hz The Source clock frequency in Hz. param pTimingConfig Pointer to the FlexCAN timing
2020  * configuration structure.
2021  *
2022  * return TRUE if timing configuration found, FALSE if failed to find configuration
2023  */
2024 bool FLEXCAN_FDCalculateImprovedTimingValues(CAN_Type *base,
2025                                              uint32_t bitRate,
2026                                              uint32_t bitRateFD,
2027                                              uint32_t sourceClock_Hz,
2028                                              flexcan_timing_config_t *pTimingConfig)
2029 {
2030     /* Observe bit rate maximums */
2031     assert(bitRate <= MAX_CANFD_BITRATE);
2032     assert(bitRateFD <= MAX_CANFD_BITRATE);
2033     /* Data phase bit rate need greater or equal to nominal phase bit rate. */
2034     assert(bitRate <= bitRateFD);
2035 
2036     uint32_t clk;
2037     uint32_t tqMin, pdivMAX, tqTemp;
2038     bool fgRet = false;
2039 #if (defined(FSL_FEATURE_FLEXCAN_HAS_ENHANCED_BIT_TIMING_REG) && FSL_FEATURE_FLEXCAN_HAS_ENHANCED_BIT_TIMING_REG)
2040     /*  Auto Improved Protocal timing for EDCBT. */
2041     tqTemp  = EDCBT_MAX_TIME_QUANTA;
2042     tqMin   = EDCBT_MIN_TIME_QUANTA;
2043     pdivMAX = MAX_EDPRESDIV;
2044 #else
2045     /*  Auto Improved Protocal timing for FDCBT. */
2046     tqTemp = FDCBT_MAX_TIME_QUANTA;
2047     tqMin = FDCBT_MIN_TIME_QUANTA;
2048     pdivMAX = MAX_FPRESDIV;
2049 #endif
2050 
2051     if (bitRate != bitRateFD)
2052     {
2053         /* To minimize errors when processing FD frames, try to get the same bit rate prescaler value for nominal phase
2054            and data phase. */
2055         do
2056         {
2057             clk = bitRateFD * tqTemp;
2058             if (clk > sourceClock_Hz)
2059             {
2060                 continue; /* tqTemp too large, clk x tqTemp has been exceed sourceClock_Hz. */
2061             }
2062 
2063             if ((sourceClock_Hz / clk * clk) != sourceClock_Hz)
2064             {
2065                 continue; /*  the frequency of clock source is not divisible by target bit rate. */
2066             }
2067 
2068             pTimingConfig->fpreDivider = (uint16_t)(sourceClock_Hz / clk) - 1U;
2069 
2070             if (pTimingConfig->fpreDivider > pdivMAX)
2071             {
2072                 break; /* The frequency of source clock is too large or the bit rate is too small, the pre-divider
2073                           could not handle it. */
2074             }
2075 
2076             /* Calculates the best data phase timing configuration. */
2077             FLEXCAN_FDGetSegments(bitRateFD, tqTemp, pTimingConfig);
2078 
2079             if (FLEXCAN_CalculateImprovedNominalTimingValues(
2080                     bitRate, sourceClock_Hz / ((uint32_t)pTimingConfig->fpreDivider + 1U), pTimingConfig))
2081             {
2082                 fgRet = true;
2083                 if (pTimingConfig->preDivider == 0U)
2084                 {
2085                     pTimingConfig->preDivider = pTimingConfig->fpreDivider;
2086                     break;
2087                 }
2088                 else
2089                 {
2090                     pTimingConfig->preDivider =
2091                         (pTimingConfig->preDivider + 1U) * (pTimingConfig->fpreDivider + 1U) - 1U;
2092                     continue;
2093                 }
2094             }
2095         } while (--tqTemp >= tqMin);
2096     }
2097     else
2098     {
2099         if (FLEXCAN_CalculateImprovedNominalTimingValues(bitRate, sourceClock_Hz, pTimingConfig))
2100         {
2101             /* No need data phase timing configuration, data phase rate equal to nominal phase rate, user don't use Brs
2102                feature. */
2103             pTimingConfig->fpreDivider = 0U;
2104             pTimingConfig->frJumpwidth = 0U;
2105             pTimingConfig->fphaseSeg1  = 0U;
2106             pTimingConfig->fphaseSeg2  = 0U;
2107             pTimingConfig->fpropSeg    = 0U;
2108             fgRet                      = true;
2109         }
2110     }
2111     return fgRet;
2112 }
2113 
2114 /*!
2115  * brief Configures a FlexCAN transmit message buffer.
2116  *
2117  * This function aborts the previous transmission, cleans the Message Buffer, and
2118  * configures it as a Transmit Message Buffer.
2119  *
2120  * param base FlexCAN peripheral base address.
2121  * param mbIdx The Message Buffer index.
2122  * param enable Enable/disable Tx Message Buffer.
2123  *               - true: Enable Tx Message Buffer.
2124  *               - false: Disable Tx Message Buffer.
2125  */
2126 void FLEXCAN_SetFDTxMbConfig(CAN_Type *base, uint8_t mbIdx, bool enable)
2127 {
2128     /* Assertion. */
2129     assert(mbIdx <= (base->MCR & CAN_MCR_MAXMB_MASK));
2130 #if !defined(NDEBUG)
2131     assert(!FLEXCAN_IsMbOccupied(base, mbIdx));
2132 #endif
2133 
2134     uint8_t cnt           = 0;
2135     uint8_t payload_dword = 1;
2136     uint32_t dataSize;
2137     dataSize                  = (base->FDCTRL & CAN_FDCTRL_MBDSR0_MASK) >> CAN_FDCTRL_MBDSR0_SHIFT;
2138     volatile uint32_t *mbAddr = &(base->MB[0].CS);
2139     uint32_t offset           = FLEXCAN_GetFDMailboxOffset(base, mbIdx);
2140 #if ((defined(FSL_FEATURE_FLEXCAN_HAS_ERRATA_5641) && FSL_FEATURE_FLEXCAN_HAS_ERRATA_5641) || \
2141      (defined(FSL_FEATURE_FLEXCAN_HAS_ERRATA_5829) && FSL_FEATURE_FLEXCAN_HAS_ERRATA_5829))
2142     uint32_t availoffset = FLEXCAN_GetFDMailboxOffset(base, FLEXCAN_GetFirstValidMb(base));
2143 #endif
2144 
2145     /* Inactivate Message Buffer. */
2146     if (enable)
2147     {
2148         /* Inactivate by writing CS. */
2149         mbAddr[offset] = CAN_CS_CODE(kFLEXCAN_TxMbInactive);
2150     }
2151     else
2152     {
2153         mbAddr[offset] = 0x0;
2154     }
2155 
2156     /* Calculate the DWORD number, dataSize 0/1/2/3 corresponds to 8/16/32/64
2157        Bytes payload. */
2158     for (cnt = 0; cnt < (dataSize + 1U); cnt++)
2159     {
2160         payload_dword *= 2U;
2161     }
2162 
2163     /* Clean ID. */
2164     mbAddr[offset + 1U] = 0x0U;
2165     /* Clean Message Buffer content, DWORD by DWORD. */
2166     for (cnt = 0; cnt < payload_dword; cnt++)
2167     {
2168         mbAddr[offset + 2U + cnt] = 0x0U;
2169     }
2170 
2171 #if ((defined(FSL_FEATURE_FLEXCAN_HAS_ERRATA_5641) && FSL_FEATURE_FLEXCAN_HAS_ERRATA_5641) || \
2172      (defined(FSL_FEATURE_FLEXCAN_HAS_ERRATA_5829) && FSL_FEATURE_FLEXCAN_HAS_ERRATA_5829))
2173     mbAddr[availoffset] = CAN_CS_CODE(kFLEXCAN_TxMbInactive);
2174 #endif
2175 }
2176 #endif /* FSL_FEATURE_FLEXCAN_HAS_FLEXIBLE_DATA_RATE */
2177 
2178 /*!
2179  * brief Configures a FlexCAN Receive Message Buffer.
2180  *
2181  * This function cleans a FlexCAN build-in Message Buffer and configures it
2182  * as a Receive Message Buffer.
2183  *
2184  * param base FlexCAN peripheral base address.
2185  * param mbIdx The Message Buffer index.
2186  * param pRxMbConfig Pointer to the FlexCAN Message Buffer configuration structure.
2187  * param enable Enable/disable Rx Message Buffer.
2188  *               - true: Enable Rx Message Buffer.
2189  *               - false: Disable Rx Message Buffer.
2190  */
2191 void FLEXCAN_SetRxMbConfig(CAN_Type *base, uint8_t mbIdx, const flexcan_rx_mb_config_t *pRxMbConfig, bool enable)
2192 {
2193     /* Assertion. */
2194     assert(mbIdx <= (base->MCR & CAN_MCR_MAXMB_MASK));
2195     assert(((NULL != pRxMbConfig) || (false == enable)));
2196 #if !defined(NDEBUG)
2197     assert(!FLEXCAN_IsMbOccupied(base, mbIdx));
2198 #endif
2199 
2200     uint32_t cs_temp = 0;
2201 
2202     /* Inactivate Message Buffer. */
2203     base->MB[mbIdx].CS = 0;
2204 
2205     /* Clean Message Buffer content. */
2206     base->MB[mbIdx].ID    = 0x0;
2207     base->MB[mbIdx].WORD0 = 0x0;
2208     base->MB[mbIdx].WORD1 = 0x0;
2209 
2210     if (enable)
2211     {
2212         /* Setup Message Buffer ID. */
2213         base->MB[mbIdx].ID = pRxMbConfig->id;
2214 
2215         /* Setup Message Buffer format. */
2216         if (kFLEXCAN_FrameFormatExtend == pRxMbConfig->format)
2217         {
2218             cs_temp |= CAN_CS_IDE_MASK;
2219         }
2220 
2221         /* Setup Message Buffer type. */
2222         if (kFLEXCAN_FrameTypeRemote == pRxMbConfig->type)
2223         {
2224             cs_temp |= CAN_CS_RTR_MASK;
2225         }
2226 
2227         /* Activate Rx Message Buffer. */
2228         cs_temp |= CAN_CS_CODE(kFLEXCAN_RxMbEmpty);
2229         base->MB[mbIdx].CS = cs_temp;
2230     }
2231 }
2232 
2233 #if (defined(FSL_FEATURE_FLEXCAN_HAS_FLEXIBLE_DATA_RATE) && FSL_FEATURE_FLEXCAN_HAS_FLEXIBLE_DATA_RATE)
2234 /*!
2235  * brief Configures a FlexCAN Receive Message Buffer.
2236  *
2237  * This function cleans a FlexCAN build-in Message Buffer and configures it
2238  * as a Receive Message Buffer.
2239  *
2240  * param base FlexCAN peripheral base address.
2241  * param mbIdx The Message Buffer index.
2242  * param pRxMbConfig Pointer to the FlexCAN Message Buffer configuration structure.
2243  * param enable Enable/disable Rx Message Buffer.
2244  *               - true: Enable Rx Message Buffer.
2245  *               - false: Disable Rx Message Buffer.
2246  */
2247 void FLEXCAN_SetFDRxMbConfig(CAN_Type *base, uint8_t mbIdx, const flexcan_rx_mb_config_t *pRxMbConfig, bool enable)
2248 {
2249     /* Assertion. */
2250     assert(mbIdx <= (base->MCR & CAN_MCR_MAXMB_MASK));
2251     assert(((NULL != pRxMbConfig) || (false == enable)));
2252 #if !defined(NDEBUG)
2253     assert(!FLEXCAN_IsMbOccupied(base, mbIdx));
2254 #endif
2255 
2256     uint32_t cs_temp          = 0;
2257     uint8_t cnt               = 0;
2258     volatile uint32_t *mbAddr = &(base->MB[0].CS);
2259     uint32_t offset           = FLEXCAN_GetFDMailboxOffset(base, mbIdx);
2260     uint8_t payload_dword;
2261     uint32_t dataSize = (base->FDCTRL & CAN_FDCTRL_MBDSR0_MASK) >> CAN_FDCTRL_MBDSR0_SHIFT;
2262 
2263     /* Inactivate Message Buffer. */
2264     mbAddr[offset] = 0U;
2265 
2266     /* Clean Message Buffer content. */
2267     mbAddr[offset + 1U] = 0U;
2268     /* Calculate the DWORD number, dataSize 0/1/2/3 corresponds to 8/16/32/64
2269        Bytes payload. */
2270     payload_dword = (2U << dataSize);
2271     for (cnt = 0; cnt < payload_dword; cnt++)
2272     {
2273         mbAddr[offset + 2U + cnt] = 0x0;
2274     }
2275 
2276     if (enable)
2277     {
2278         /* Setup Message Buffer ID. */
2279         mbAddr[offset + 1U] = pRxMbConfig->id;
2280 
2281         /* Setup Message Buffer format. */
2282         if (kFLEXCAN_FrameFormatExtend == pRxMbConfig->format)
2283         {
2284             cs_temp |= CAN_CS_IDE_MASK;
2285         }
2286 
2287         /* Setup Message Buffer type. */
2288         if (kFLEXCAN_FrameTypeRemote == pRxMbConfig->type)
2289         {
2290             cs_temp |= CAN_CS_RTR_MASK;
2291         }
2292 
2293         /* Activate Rx Message Buffer. */
2294         cs_temp |= CAN_CS_CODE(kFLEXCAN_RxMbEmpty);
2295         mbAddr[offset] = cs_temp;
2296     }
2297 }
2298 #endif
2299 
2300 /*!
2301  * brief Configures the FlexCAN Legacy Rx FIFO.
2302  *
2303  * This function configures the FlexCAN Rx FIFO with given configuration.
2304  * note Legacy Rx FIFO only can receive classic CAN message.
2305  *
2306  * param base FlexCAN peripheral base address.
2307  * param pRxFifoConfig Pointer to the FlexCAN Legacy Rx FIFO configuration structure. Can be NULL when enable parameter
2308  *                      is false.
2309  * param enable Enable/disable Legacy Rx FIFO.
2310  *              - true: Enable Legacy Rx FIFO.
2311  *              - false: Disable Legacy Rx FIFO.
2312  */
2313 void FLEXCAN_SetRxFifoConfig(CAN_Type *base, const flexcan_rx_fifo_config_t *pRxFifoConfig, bool enable)
2314 {
2315     /* Assertion. */
2316     assert((NULL != pRxFifoConfig) || (false == enable));
2317 
2318     volatile uint32_t *mbAddr;
2319     uint8_t i, j, k, rffn = 0, numMbOccupy;
2320     uint32_t setup_mb = 0;
2321 
2322     /* Enter Freeze Mode. */
2323     FLEXCAN_EnterFreezeMode(base);
2324 
2325     if (enable)
2326     {
2327         assert(pRxFifoConfig->idFilterNum <= 128U);
2328 #if (defined(FSL_FEATURE_FLEXCAN_HAS_ENHANCED_RX_FIFO) && FSL_FEATURE_FLEXCAN_HAS_ENHANCED_RX_FIFO)
2329         /* Legacy Rx FIFO and Enhanced Rx FIFO cannot be enabled at the same time. */
2330         assert((base->ERFCR & CAN_ERFCR_ERFEN_MASK) == 0U);
2331 #endif
2332 
2333         /* Get the setup_mb value. */
2334         setup_mb = (uint8_t)((base->MCR & CAN_MCR_MAXMB_MASK) >> CAN_MCR_MAXMB_SHIFT);
2335         setup_mb = (setup_mb < (uint32_t)FSL_FEATURE_FLEXCAN_HAS_MESSAGE_BUFFER_MAX_NUMBERn(base)) ?
2336                        setup_mb :
2337                        (uint32_t)FSL_FEATURE_FLEXCAN_HAS_MESSAGE_BUFFER_MAX_NUMBERn(base);
2338 
2339         /* Determine RFFN value. */
2340         for (i = 0; i <= 0xFU; i++)
2341         {
2342             if ((8U * (i + 1U)) >= pRxFifoConfig->idFilterNum)
2343             {
2344                 rffn = i;
2345                 assert(((setup_mb - 8U) - (2U * rffn)) > 0U);
2346 
2347                 base->CTRL2 = (base->CTRL2 & ~CAN_CTRL2_RFFN_MASK) | CAN_CTRL2_RFFN(rffn);
2348                 break;
2349             }
2350         }
2351 
2352         /* caculate the Number of Mailboxes occupied by RX Legacy FIFO and the filter. */
2353         numMbOccupy = 6U + (rffn + 1U) * 2U;
2354 
2355         /* Copy ID filter table to Message Buffer Region (Fix MISRA_C-2012 Rule 18.1). */
2356         j = 0U;
2357         for (i = 6U; i < numMbOccupy; i++)
2358         {
2359             /* Get address for current mail box.  */
2360             mbAddr = &(base->MB[i].CS);
2361 
2362             /* One Mail box contain 4U DWORD registers. */
2363             for (k = 0; k < 4U; k++)
2364             {
2365                 /* Fill all valid filter in the mail box occupied by filter.
2366                  * Disable unused Rx FIFO Filter, the other rest of register in the last Mail box occupied by fiter set
2367                  * as 0xffffffff.
2368                  */
2369                 mbAddr[k] = (j < pRxFifoConfig->idFilterNum) ? (pRxFifoConfig->idFilterTable[j]) : 0xFFFFFFFFU;
2370 
2371                 /* Try to fill next filter in current Mail Box.  */
2372                 j++;
2373             }
2374         }
2375 
2376         /* Setup ID Fitlter Type. */
2377         switch (pRxFifoConfig->idFilterType)
2378         {
2379             case kFLEXCAN_RxFifoFilterTypeA:
2380                 base->MCR = (base->MCR & ~CAN_MCR_IDAM_MASK) | CAN_MCR_IDAM(0x0);
2381                 break;
2382             case kFLEXCAN_RxFifoFilterTypeB:
2383                 base->MCR = (base->MCR & ~CAN_MCR_IDAM_MASK) | CAN_MCR_IDAM(0x1);
2384                 break;
2385             case kFLEXCAN_RxFifoFilterTypeC:
2386                 base->MCR = (base->MCR & ~CAN_MCR_IDAM_MASK) | CAN_MCR_IDAM(0x2);
2387                 break;
2388             case kFLEXCAN_RxFifoFilterTypeD:
2389                 /* All frames rejected. */
2390                 base->MCR = (base->MCR & ~CAN_MCR_IDAM_MASK) | CAN_MCR_IDAM(0x3);
2391                 break;
2392             default:
2393                 /* All the cases have been listed above, the default clause should not be reached. */
2394                 assert(false);
2395                 break;
2396         }
2397 
2398         /* Setting Message Reception Priority. */
2399         base->CTRL2 = (pRxFifoConfig->priority == kFLEXCAN_RxFifoPrioHigh) ? (base->CTRL2 & ~CAN_CTRL2_MRP_MASK) :
2400                                                                              (base->CTRL2 | CAN_CTRL2_MRP_MASK);
2401 
2402         /* Enable Rx Message FIFO. */
2403         base->MCR |= CAN_MCR_RFEN_MASK;
2404     }
2405     else
2406     {
2407         rffn = (uint8_t)((base->CTRL2 & CAN_CTRL2_RFFN_MASK) >> CAN_CTRL2_RFFN_SHIFT);
2408         /* caculate the Number of Mailboxes occupied by RX Legacy FIFO and the filter. */
2409         numMbOccupy = 6U + (rffn + 1U) * 2U;
2410 
2411         /* Disable Rx Message FIFO. */
2412         base->MCR &= ~CAN_MCR_RFEN_MASK;
2413 
2414         /* Clean MB0 ~ MB5 and all MB occupied by ID filters (Fix MISRA_C-2012 Rule 18.1). */
2415 
2416         for (i = 0; i < numMbOccupy; i++)
2417         {
2418             FLEXCAN_SetRxMbConfig(base, i, NULL, false);
2419         }
2420     }
2421 
2422     /* Exit Freeze Mode. */
2423     FLEXCAN_ExitFreezeMode(base);
2424 }
2425 
2426 #if (defined(FSL_FEATURE_FLEXCAN_HAS_ENHANCED_RX_FIFO) && FSL_FEATURE_FLEXCAN_HAS_ENHANCED_RX_FIFO)
2427 /*!
2428  * brief Configures the FlexCAN Enhanced Rx FIFO.
2429  *
2430  * This function configures the Enhanced Rx FIFO with given configuration.
2431  * note  Enhanced Rx FIFO support receive classic CAN or CAN FD messages, Legacy Rx FIFO and Enhanced Rx FIFO
2432  *       cannot be enabled at the same time.
2433  *
2434  * param base    FlexCAN peripheral base address.
2435  * param pConfig Pointer to the FlexCAN Enhanced Rx FIFO configuration structure. Can be NULL when enable parameter
2436  *               is false.
2437  * param enable  Enable/disable Enhanced Rx FIFO.
2438  *               - true: Enable Enhanced Rx FIFO.
2439  *               - false: Disable Enhanced Rx FIFO.
2440  */
2441 void FLEXCAN_SetEnhancedRxFifoConfig(CAN_Type *base, const flexcan_enhanced_rx_fifo_config_t *pConfig, bool enable)
2442 {
2443     /* Assertion. */
2444     assert((NULL != pConfig) || (false == enable));
2445     uint32_t i;
2446     /* Enter Freeze Mode. */
2447     FLEXCAN_EnterFreezeMode(base);
2448 
2449     if (enable)
2450     {
2451         /* Each pair of filter elements occupies 2 words and can consist of one extended ID filter element or two
2452          * standard ID filter elements. */
2453         assert((((uint32_t)pConfig->idFilterPairNum * 2UL) <
2454                 (uint32_t)FSL_FEATURE_FLEXCAN_HAS_ENHANCED_RX_FIFO_FILTER_MAX_NUMBER) &&
2455                (pConfig->extendIdFilterNum <= pConfig->idFilterPairNum) && (0UL != pConfig->idFilterPairNum));
2456 
2457         /* The Enhanced Rx FIFO Watermark cannot be greater than the enhanced Rx FIFO size. */
2458         assert(pConfig->fifoWatermark < (uint32_t)FSL_FEATURE_FLEXCAN_HAS_ENHANCED_RX_FIFO_SIZE);
2459 
2460         /* Legacy Rx FIFO and Enhanced Rx FIFO cannot be enabled at the same time. */
2461         assert((base->MCR & CAN_MCR_RFEN_MASK) == 0U);
2462 
2463         /* Reset Enhanced Rx FIFO engine and clear flags. */
2464         base->ERFSR |= CAN_ERFSR_ERFCLR_MASK | CAN_ERFSR_ERFUFW_MASK | CAN_ERFSR_ERFOVF_MASK | CAN_ERFSR_ERFWMI_MASK |
2465                        CAN_ERFSR_ERFDA_MASK;
2466         /* Setting Enhanced Rx FIFO. */
2467         base->ERFCR = CAN_ERFCR_DMALW(pConfig->dmaPerReadLength) | CAN_ERFCR_NEXIF(pConfig->extendIdFilterNum) |
2468                       CAN_ERFCR_NFE((uint32_t)pConfig->idFilterPairNum - 1UL) | CAN_ERFCR_ERFWM(pConfig->fifoWatermark);
2469         /* Copy ID filter table to Enhanced Rx FIFO Filter Element registers. */
2470         for (i = 0; i < (uint32_t)FSL_FEATURE_FLEXCAN_HAS_ENHANCED_RX_FIFO_FILTER_MAX_NUMBER; i++)
2471         {
2472             base->ERFFEL[i] = (i < ((uint32_t)pConfig->idFilterPairNum * 2U)) ? pConfig->idFilterTable[i] : 0xFFFFFFFFU;
2473         }
2474 
2475         /* Setting Message Reception Priority. */
2476         base->CTRL2 = (pConfig->priority == kFLEXCAN_RxFifoPrioHigh) ? (base->CTRL2 & ~CAN_CTRL2_MRP_MASK) :
2477                                                                        (base->CTRL2 | CAN_CTRL2_MRP_MASK);
2478         /* Enable Enhanced Rx FIFO. */
2479         base->ERFCR |= CAN_ERFCR_ERFEN_MASK;
2480     }
2481     else
2482     {
2483         /* Disable Enhanced Rx FIFO. */
2484         base->ERFCR = 0U;
2485         /* Reset Enhanced Rx FIFO engine and clear flags. */
2486         base->ERFSR |= CAN_ERFSR_ERFCLR_MASK | CAN_ERFSR_ERFUFW_MASK | CAN_ERFSR_ERFOVF_MASK | CAN_ERFSR_ERFWMI_MASK |
2487                        CAN_ERFSR_ERFDA_MASK;
2488         /* Clean all Enhanced Rx FIFO Filter Element registers. */
2489         for (i = 0; i < (uint32_t)FSL_FEATURE_FLEXCAN_HAS_ENHANCED_RX_FIFO_FILTER_MAX_NUMBER; i++)
2490         {
2491             base->ERFFEL[i] = 0xFFFFFFFFU;
2492         }
2493     }
2494 
2495     /* Exit Freeze Mode. */
2496     FLEXCAN_ExitFreezeMode(base);
2497 }
2498 #endif
2499 
2500 #if (defined(FSL_FEATURE_FLEXCAN_HAS_RX_FIFO_DMA) && FSL_FEATURE_FLEXCAN_HAS_RX_FIFO_DMA)
2501 /*!
2502  * brief Enables or disables the FlexCAN Legacy/Enhanced Rx FIFO DMA request.
2503  *
2504  * This function enables or disables the DMA feature of FlexCAN build-in Rx FIFO.
2505  *
2506  * param base FlexCAN peripheral base address.
2507  * param enable true to enable, false to disable.
2508  */
2509 void FLEXCAN_EnableRxFifoDMA(CAN_Type *base, bool enable)
2510 {
2511     if (enable)
2512     {
2513         /* Enter Freeze Mode. */
2514         FLEXCAN_EnterFreezeMode(base);
2515 
2516         /* Enable FlexCAN DMA. */
2517         base->MCR |= CAN_MCR_DMA_MASK;
2518 
2519         /* Exit Freeze Mode. */
2520         FLEXCAN_ExitFreezeMode(base);
2521     }
2522     else
2523     {
2524         /* Enter Freeze Mode. */
2525         FLEXCAN_EnterFreezeMode(base);
2526 
2527         /* Disable FlexCAN DMA. */
2528         base->MCR &= ~CAN_MCR_DMA_MASK;
2529 
2530         /* Exit Freeze Mode. */
2531         FLEXCAN_ExitFreezeMode(base);
2532     }
2533 }
2534 #endif /* FSL_FEATURE_FLEXCAN_HAS_RX_FIFO_DMA */
2535 
2536 #if (defined(FSL_FEATURE_FLEXCAN_HAS_MEMORY_ERROR_CONTROL) && FSL_FEATURE_FLEXCAN_HAS_MEMORY_ERROR_CONTROL)
2537 /*!
2538  * brief Gets the FlexCAN Memory Error Report registers status.
2539  *
2540  * This function gets the FlexCAN Memory Error Report registers status.
2541  *
2542  * param base FlexCAN peripheral base address.
2543  * param errorStatus Pointer to FlexCAN Memory Error Report registers status structure.
2544  */
2545 void FLEXCAN_GetMemoryErrorReportStatus(CAN_Type *base, flexcan_memory_error_report_status_t *errorStatus)
2546 {
2547     uint32_t temp;
2548     /*  Disable updates of the error report registers. */
2549     base->MECR |= CAN_MECR_RERRDIS_MASK;
2550 
2551     errorStatus->accessAddress = (uint16_t)(base->RERRAR & CAN_RERRAR_ERRADDR_MASK);
2552     errorStatus->errorData     = base->RERRDR;
2553     errorStatus->errorType =
2554         (base->RERRAR & CAN_RERRAR_NCE_MASK) == 0U ? kFLEXCAN_CorrectableError : kFLEXCAN_NonCorrectableError;
2555 
2556     temp = (base->RERRAR & CAN_RERRAR_SAID_MASK) >> CAN_RERRAR_SAID_SHIFT;
2557     switch (temp)
2558     {
2559         case (uint32_t)kFLEXCAN_MoveOutFlexCanAccess:
2560         case (uint32_t)kFLEXCAN_MoveInAccess:
2561         case (uint32_t)kFLEXCAN_TxArbitrationAccess:
2562         case (uint32_t)kFLEXCAN_RxMatchingAccess:
2563         case (uint32_t)kFLEXCAN_MoveOutHostAccess:
2564             errorStatus->accessType = (flexcan_memory_access_type_t)temp;
2565             break;
2566         default:
2567             assert(false);
2568             break;
2569     }
2570 
2571     for (uint32_t i = 0; i < 4U; i++)
2572     {
2573         temp = (base->RERRSYNR & ((uint32_t)CAN_RERRSYNR_SYND0_MASK << (i * 8U))) >> (i * 8U);
2574         errorStatus->byteStatus[i].byteIsRead = (base->RERRSYNR & ((uint32_t)CAN_RERRSYNR_BE0_MASK << (i * 8U))) != 0U;
2575         switch (temp)
2576         {
2577             case CAN_RERRSYNR_SYND0(kFLEXCAN_NoError):
2578             case CAN_RERRSYNR_SYND0(kFLEXCAN_ParityBits0Error):
2579             case CAN_RERRSYNR_SYND0(kFLEXCAN_ParityBits1Error):
2580             case CAN_RERRSYNR_SYND0(kFLEXCAN_ParityBits2Error):
2581             case CAN_RERRSYNR_SYND0(kFLEXCAN_ParityBits3Error):
2582             case CAN_RERRSYNR_SYND0(kFLEXCAN_ParityBits4Error):
2583             case CAN_RERRSYNR_SYND0(kFLEXCAN_DataBits0Error):
2584             case CAN_RERRSYNR_SYND0(kFLEXCAN_DataBits1Error):
2585             case CAN_RERRSYNR_SYND0(kFLEXCAN_DataBits2Error):
2586             case CAN_RERRSYNR_SYND0(kFLEXCAN_DataBits3Error):
2587             case CAN_RERRSYNR_SYND0(kFLEXCAN_DataBits4Error):
2588             case CAN_RERRSYNR_SYND0(kFLEXCAN_DataBits5Error):
2589             case CAN_RERRSYNR_SYND0(kFLEXCAN_DataBits6Error):
2590             case CAN_RERRSYNR_SYND0(kFLEXCAN_DataBits7Error):
2591             case CAN_RERRSYNR_SYND0(kFLEXCAN_AllZeroError):
2592             case CAN_RERRSYNR_SYND0(kFLEXCAN_AllOneError):
2593                 errorStatus->byteStatus[i].bitAffected = (flexcan_byte_error_syndrome_t)temp;
2594                 break;
2595             default:
2596                 errorStatus->byteStatus[i].bitAffected = kFLEXCAN_NonCorrectableErrors;
2597                 break;
2598         }
2599     }
2600 
2601     /*  Re-enable updates of the error report registers. */
2602     base->MECR &= CAN_MECR_RERRDIS_MASK;
2603 }
2604 #endif
2605 
2606 #if (defined(FSL_FEATURE_FLEXCAN_HAS_ERRATA_6032) && FSL_FEATURE_FLEXCAN_HAS_ERRATA_6032)
2607 /*!
2608  * FlexCAN: A frame with wrong ID or payload is transmitted into
2609  * the CAN bus when the Message Buffer under transmission is
2610  * either aborted or deactivated while the CAN bus is in the Bus Idle state
2611  *
2612  * This function to do workaround for ERR006032
2613  *
2614  * param base FlexCAN peripheral base address.
2615  * param mbIdx The FlexCAN Message Buffer index.
2616  */
2617 static void FLEXCAN_ERRATA_6032(CAN_Type *base, volatile uint32_t *mbCSAddr)
2618 {
2619     uint32_t dbg_temp   = 0U;
2620     uint32_t u32TempCS  = 0U;
2621     uint32_t u32Timeout = DELAY_BUSIDLE;
2622     /*disable ALL interrupts to prevent any context switching*/
2623     uint32_t irqMask = DisableGlobalIRQ();
2624     dbg_temp         = (uint32_t)(base->DBG1);
2625     switch (dbg_temp & CAN_DBG1_CFSM_MASK)
2626     {
2627         case RXINTERMISSION:
2628             if (CBN_VALUE3 == (dbg_temp & CAN_DBG1_CBN_MASK))
2629             {
2630                 /*wait until CFSM is different from RXINTERMISSION */
2631                 while (RXINTERMISSION == (base->DBG1 & CAN_DBG1_CFSM_MASK))
2632                 {
2633                     __NOP();
2634                 }
2635             }
2636             break;
2637         case TXINTERMISSION:
2638             if (CBN_VALUE3 == (dbg_temp & CAN_DBG1_CBN_MASK))
2639             {
2640                 /*wait until CFSM is different from TXINTERMISSION*/
2641                 while (TXINTERMISSION == (base->DBG1 & CAN_DBG1_CFSM_MASK))
2642                 {
2643                     __NOP();
2644                 }
2645             }
2646             break;
2647         default:
2648             /* To avoid MISRA-C 2012 rule 16.4 issue. */
2649             break;
2650     }
2651     /*Anyway, BUSIDLE need to delay*/
2652     if (BUSIDLE == (base->DBG1 & CAN_DBG1_CFSM_MASK))
2653     {
2654         while (u32Timeout-- > 0U)
2655         {
2656             __NOP();
2657         }
2658 
2659         /*Write 0x0 into Code field of CS word.*/
2660         u32TempCS = (uint32_t)(*mbCSAddr);
2661         u32TempCS &= ~CAN_CS_CODE_MASK;
2662         *mbCSAddr = u32TempCS;
2663     }
2664     /*restore interruption*/
2665     EnableGlobalIRQ(irqMask);
2666 }
2667 #endif
2668 
2669 /*!
2670  * brief Writes a FlexCAN Message to the Transmit Message Buffer.
2671  *
2672  * This function writes a CAN Message to the specified Transmit Message Buffer
2673  * and changes the Message Buffer state to start CAN Message transmit. After
2674  * that the function returns immediately.
2675  *
2676  * param base FlexCAN peripheral base address.
2677  * param mbIdx The FlexCAN Message Buffer index.
2678  * param pTxFrame Pointer to CAN message frame to be sent.
2679  * retval kStatus_Success - Write Tx Message Buffer Successfully.
2680  * retval kStatus_Fail    - Tx Message Buffer is currently in use.
2681  */
2682 status_t FLEXCAN_WriteTxMb(CAN_Type *base, uint8_t mbIdx, const flexcan_frame_t *pTxFrame)
2683 {
2684     /* Assertion. */
2685     assert(mbIdx <= (base->MCR & CAN_MCR_MAXMB_MASK));
2686     assert(NULL != pTxFrame);
2687     assert(pTxFrame->length <= 8U);
2688 #if !defined(NDEBUG)
2689     assert(!FLEXCAN_IsMbOccupied(base, mbIdx));
2690 #endif
2691 
2692     uint32_t cs_temp = 0;
2693     status_t status;
2694 
2695     /* Check if Message Buffer is available. */
2696     if (CAN_CS_CODE(kFLEXCAN_TxMbDataOrRemote) != (base->MB[mbIdx].CS & CAN_CS_CODE_MASK))
2697     {
2698 #if (defined(FSL_FEATURE_FLEXCAN_HAS_ERRATA_6032) && FSL_FEATURE_FLEXCAN_HAS_ERRATA_6032)
2699         FLEXCAN_ERRATA_6032(base, &(base->MB[mbIdx].CS));
2700 #endif
2701         /* Inactive Tx Message Buffer. */
2702         base->MB[mbIdx].CS = (base->MB[mbIdx].CS & ~CAN_CS_CODE_MASK) | CAN_CS_CODE(kFLEXCAN_TxMbInactive);
2703 
2704         /* Fill Message ID field. */
2705         base->MB[mbIdx].ID = pTxFrame->id;
2706 
2707         /* Fill Message Format field. */
2708         if ((uint32_t)kFLEXCAN_FrameFormatExtend == pTxFrame->format)
2709         {
2710             cs_temp |= CAN_CS_SRR_MASK | CAN_CS_IDE_MASK;
2711         }
2712 
2713         /* Fill Message Type field. */
2714         if ((uint32_t)kFLEXCAN_FrameTypeRemote == pTxFrame->type)
2715         {
2716             cs_temp |= CAN_CS_RTR_MASK;
2717         }
2718 
2719         cs_temp |= CAN_CS_CODE(kFLEXCAN_TxMbDataOrRemote) | CAN_CS_DLC(pTxFrame->length);
2720 
2721         /* Load Message Payload. */
2722         base->MB[mbIdx].WORD0 = pTxFrame->dataWord0;
2723         base->MB[mbIdx].WORD1 = pTxFrame->dataWord1;
2724 
2725         /* Activate Tx Message Buffer. */
2726         base->MB[mbIdx].CS = cs_temp;
2727 
2728 #if ((defined(FSL_FEATURE_FLEXCAN_HAS_ERRATA_5641) && FSL_FEATURE_FLEXCAN_HAS_ERRATA_5641) || \
2729      (defined(FSL_FEATURE_FLEXCAN_HAS_ERRATA_5829) && FSL_FEATURE_FLEXCAN_HAS_ERRATA_5829))
2730         base->MB[FLEXCAN_GetFirstValidMb(base)].CS = CAN_CS_CODE(kFLEXCAN_TxMbInactive);
2731         base->MB[FLEXCAN_GetFirstValidMb(base)].CS = CAN_CS_CODE(kFLEXCAN_TxMbInactive);
2732 #endif
2733 
2734         status = kStatus_Success;
2735     }
2736     else
2737     {
2738         /* Tx Message Buffer is activated, return immediately. */
2739         status = kStatus_Fail;
2740     }
2741 
2742     return status;
2743 }
2744 
2745 #if (defined(FSL_FEATURE_FLEXCAN_HAS_FLEXIBLE_DATA_RATE) && FSL_FEATURE_FLEXCAN_HAS_FLEXIBLE_DATA_RATE)
2746 /*!
2747  * brief Writes a FlexCAN FD Message to the Transmit Message Buffer.
2748  *
2749  * This function writes a CAN FD Message to the specified Transmit Message Buffer
2750  * and changes the Message Buffer state to start CAN FD Message transmit. After
2751  * that the function returns immediately.
2752  *
2753  * param base FlexCAN peripheral base address.
2754  * param mbIdx The FlexCAN FD Message Buffer index.
2755  * param pTxFrame Pointer to CAN FD message frame to be sent.
2756  * retval kStatus_Success - Write Tx Message Buffer Successfully.
2757  * retval kStatus_Fail    - Tx Message Buffer is currently in use.
2758  */
2759 status_t FLEXCAN_WriteFDTxMb(CAN_Type *base, uint8_t mbIdx, const flexcan_fd_frame_t *pTxFrame)
2760 {
2761     /* Assertion. */
2762     assert(mbIdx <= (base->MCR & CAN_MCR_MAXMB_MASK));
2763     assert(NULL != pTxFrame);
2764 #if !defined(NDEBUG)
2765     assert(!FLEXCAN_IsMbOccupied(base, mbIdx));
2766 #endif
2767 
2768     status_t status;
2769     uint32_t cs_temp      = 0;
2770     uint8_t cnt           = 0;
2771     uint32_t can_cs       = 0;
2772     uint8_t payload_dword = 1;
2773     uint32_t dataSize     = (base->FDCTRL & CAN_FDCTRL_MBDSR0_MASK) >> CAN_FDCTRL_MBDSR0_SHIFT;
2774 #if ((defined(FSL_FEATURE_FLEXCAN_HAS_ERRATA_5641) && FSL_FEATURE_FLEXCAN_HAS_ERRATA_5641) || \
2775      (defined(FSL_FEATURE_FLEXCAN_HAS_ERRATA_5829) && FSL_FEATURE_FLEXCAN_HAS_ERRATA_5829))
2776     uint32_t availoffset = FLEXCAN_GetFDMailboxOffset(base, FLEXCAN_GetFirstValidMb(base));
2777 #endif
2778     volatile uint32_t *mbAddr = &(base->MB[0].CS);
2779     uint32_t offset           = FLEXCAN_GetFDMailboxOffset(base, mbIdx);
2780 
2781     can_cs = mbAddr[offset];
2782     /* Check if Message Buffer is available. */
2783     if (CAN_CS_CODE(kFLEXCAN_TxMbDataOrRemote) != (can_cs & CAN_CS_CODE_MASK))
2784     {
2785 #if (defined(FSL_FEATURE_FLEXCAN_HAS_ERRATA_6032) && FSL_FEATURE_FLEXCAN_HAS_ERRATA_6032)
2786         FLEXCAN_ERRATA_6032(base, &(mbAddr[offset]));
2787 #endif
2788         /* Inactive Tx Message Buffer and Fill Message ID field. */
2789         mbAddr[offset]      = (can_cs & ~CAN_CS_CODE_MASK) | CAN_CS_CODE(kFLEXCAN_TxMbInactive);
2790         mbAddr[offset + 1U] = pTxFrame->id;
2791 
2792         /* Fill Message Format field. */
2793         if ((uint32_t)kFLEXCAN_FrameFormatExtend == pTxFrame->format)
2794         {
2795             cs_temp |= CAN_CS_SRR_MASK | CAN_CS_IDE_MASK;
2796         }
2797 
2798         /* Fill Message Type field. */
2799         if ((uint32_t)kFLEXCAN_FrameTypeRemote == pTxFrame->type)
2800         {
2801             cs_temp |= CAN_CS_RTR_MASK;
2802         }
2803 
2804         cs_temp |= CAN_CS_CODE(kFLEXCAN_TxMbDataOrRemote) | CAN_CS_DLC(pTxFrame->length) | CAN_CS_EDL(1) |
2805                    CAN_CS_BRS(pTxFrame->brs);
2806 
2807         /* Calculate the DWORD number, dataSize 0/1/2/3 corresponds to 8/16/32/64
2808            Bytes payload. */
2809         for (cnt = 0; cnt < (dataSize + 1U); cnt++)
2810         {
2811             payload_dword *= 2U;
2812         }
2813 
2814         /* Load Message Payload and Activate Tx Message Buffer. */
2815         for (cnt = 0; cnt < payload_dword; cnt++)
2816         {
2817             mbAddr[offset + 2U + cnt] = pTxFrame->dataWord[cnt];
2818         }
2819         mbAddr[offset] = cs_temp;
2820 
2821 #if ((defined(FSL_FEATURE_FLEXCAN_HAS_ERRATA_5641) && FSL_FEATURE_FLEXCAN_HAS_ERRATA_5641) || \
2822      (defined(FSL_FEATURE_FLEXCAN_HAS_ERRATA_5829) && FSL_FEATURE_FLEXCAN_HAS_ERRATA_5829))
2823         mbAddr[availoffset] = CAN_CS_CODE(kFLEXCAN_TxMbInactive);
2824         mbAddr[availoffset] = CAN_CS_CODE(kFLEXCAN_TxMbInactive);
2825 #endif
2826 
2827         status = kStatus_Success;
2828     }
2829     else
2830     {
2831         /* Tx Message Buffer is activated, return immediately. */
2832         status = kStatus_Fail;
2833     }
2834 
2835     return status;
2836 }
2837 #endif
2838 
2839 /*!
2840  * brief Reads a FlexCAN Message from Receive Message Buffer.
2841  *
2842  * This function reads a CAN message from a specified Receive Message Buffer.
2843  * The function fills a receive CAN message frame structure with
2844  * just received data and activates the Message Buffer again.
2845  * The function returns immediately.
2846  *
2847  * param base FlexCAN peripheral base address.
2848  * param mbIdx The FlexCAN Message Buffer index.
2849  * param pRxFrame Pointer to CAN message frame structure for reception.
2850  * retval kStatus_Success            - Rx Message Buffer is full and has been read successfully.
2851  * retval kStatus_FLEXCAN_RxOverflow - Rx Message Buffer is already overflowed and has been read successfully.
2852  * retval kStatus_Fail               - Rx Message Buffer is empty.
2853  */
2854 status_t FLEXCAN_ReadRxMb(CAN_Type *base, uint8_t mbIdx, flexcan_frame_t *pRxFrame)
2855 {
2856     /* Assertion. */
2857     assert(mbIdx <= (base->MCR & CAN_MCR_MAXMB_MASK));
2858     assert(NULL != pRxFrame);
2859 #if !defined(NDEBUG)
2860     assert(!FLEXCAN_IsMbOccupied(base, mbIdx));
2861 #endif
2862 
2863     uint32_t cs_temp;
2864     uint32_t rx_code;
2865     status_t status;
2866 
2867     /* Read CS field of Rx Message Buffer to lock Message Buffer. */
2868     cs_temp = base->MB[mbIdx].CS;
2869     /* Get Rx Message Buffer Code field. */
2870     rx_code = (cs_temp & CAN_CS_CODE_MASK) >> CAN_CS_CODE_SHIFT;
2871 
2872     /* Check to see if Rx Message Buffer is full. */
2873     if (((uint32_t)kFLEXCAN_RxMbFull == rx_code) || ((uint32_t)kFLEXCAN_RxMbOverrun == rx_code))
2874     {
2875         /* Store Message ID. */
2876         pRxFrame->id = base->MB[mbIdx].ID & (CAN_ID_EXT_MASK | CAN_ID_STD_MASK);
2877 
2878         /* Get the message ID and format. */
2879         pRxFrame->format = (cs_temp & CAN_CS_IDE_MASK) != 0U ? (uint8_t)kFLEXCAN_FrameFormatExtend :
2880                                                                (uint8_t)kFLEXCAN_FrameFormatStandard;
2881 
2882         /* Get the message type. */
2883         pRxFrame->type =
2884             (cs_temp & CAN_CS_RTR_MASK) != 0U ? (uint8_t)kFLEXCAN_FrameTypeRemote : (uint8_t)kFLEXCAN_FrameTypeData;
2885 
2886         /* Get the message length. */
2887         pRxFrame->length = (uint8_t)((cs_temp & CAN_CS_DLC_MASK) >> CAN_CS_DLC_SHIFT);
2888 
2889         /* Get the time stamp. */
2890         pRxFrame->timestamp = (uint16_t)((cs_temp & CAN_CS_TIME_STAMP_MASK) >> CAN_CS_TIME_STAMP_SHIFT);
2891 
2892         /* Store Message Payload. */
2893         pRxFrame->dataWord0 = base->MB[mbIdx].WORD0;
2894         pRxFrame->dataWord1 = base->MB[mbIdx].WORD1;
2895 
2896         /* Read free-running timer to unlock Rx Message Buffer. */
2897         (void)base->TIMER;
2898 
2899         if ((uint32_t)kFLEXCAN_RxMbFull == rx_code)
2900         {
2901             status = kStatus_Success;
2902         }
2903         else
2904         {
2905             status = kStatus_FLEXCAN_RxOverflow;
2906         }
2907     }
2908     else
2909     {
2910         /* Read free-running timer to unlock Rx Message Buffer. */
2911         (void)base->TIMER;
2912 
2913         status = kStatus_Fail;
2914     }
2915 
2916     return status;
2917 }
2918 
2919 #if (defined(FSL_FEATURE_FLEXCAN_HAS_FLEXIBLE_DATA_RATE) && FSL_FEATURE_FLEXCAN_HAS_FLEXIBLE_DATA_RATE)
2920 /*!
2921  * brief Reads a FlexCAN FD Message from Receive Message Buffer.
2922  *
2923  * This function reads a CAN FD message from a specified Receive Message Buffer.
2924  * The function fills a receive CAN FD message frame structure with
2925  * just received data and activates the Message Buffer again.
2926  * The function returns immediately.
2927  *
2928  * param base FlexCAN peripheral base address.
2929  * param mbIdx The FlexCAN FD Message Buffer index.
2930  * param pRxFrame Pointer to CAN FD message frame structure for reception.
2931  * retval kStatus_Success            - Rx Message Buffer is full and has been read successfully.
2932  * retval kStatus_FLEXCAN_RxOverflow - Rx Message Buffer is already overflowed and has been read successfully.
2933  * retval kStatus_Fail               - Rx Message Buffer is empty.
2934  */
2935 status_t FLEXCAN_ReadFDRxMb(CAN_Type *base, uint8_t mbIdx, flexcan_fd_frame_t *pRxFrame)
2936 {
2937     /* Assertion. */
2938     assert(mbIdx <= (base->MCR & CAN_MCR_MAXMB_MASK));
2939     assert(NULL != pRxFrame);
2940 #if !defined(NDEBUG)
2941     assert(!FLEXCAN_IsMbOccupied(base, mbIdx));
2942 #endif
2943 
2944     status_t status;
2945     uint32_t cs_temp;
2946     uint8_t rx_code;
2947     uint8_t cnt     = 0;
2948     uint32_t can_id = 0;
2949     uint32_t dataSize;
2950     dataSize                  = (base->FDCTRL & CAN_FDCTRL_MBDSR0_MASK) >> CAN_FDCTRL_MBDSR0_SHIFT;
2951     uint8_t payload_dword     = 1;
2952     volatile uint32_t *mbAddr = &(base->MB[0].CS);
2953     uint32_t offset           = FLEXCAN_GetFDMailboxOffset(base, mbIdx);
2954 
2955     /* Read CS field of Rx Message Buffer to lock Message Buffer. */
2956     cs_temp = mbAddr[offset];
2957     can_id  = mbAddr[offset + 1U];
2958 
2959     /* Get Rx Message Buffer Code field. */
2960     rx_code = (uint8_t)((cs_temp & CAN_CS_CODE_MASK) >> CAN_CS_CODE_SHIFT);
2961 
2962     /* Check to see if Rx Message Buffer is full. */
2963     if (((uint8_t)kFLEXCAN_RxMbFull == rx_code) || ((uint8_t)kFLEXCAN_RxMbOverrun == rx_code))
2964     {
2965         /* Store Message ID. */
2966         pRxFrame->id = can_id & (CAN_ID_EXT_MASK | CAN_ID_STD_MASK);
2967 
2968         /* Get the message ID and format. */
2969         pRxFrame->format = (cs_temp & CAN_CS_IDE_MASK) != 0U ? (uint8_t)kFLEXCAN_FrameFormatExtend :
2970                                                                (uint8_t)kFLEXCAN_FrameFormatStandard;
2971 
2972         /* Get the message type. */
2973         pRxFrame->type =
2974             (cs_temp & CAN_CS_RTR_MASK) != 0U ? (uint8_t)kFLEXCAN_FrameTypeRemote : (uint8_t)kFLEXCAN_FrameTypeData;
2975 
2976         /* Get the message length. */
2977         pRxFrame->length = (uint8_t)((cs_temp & CAN_CS_DLC_MASK) >> CAN_CS_DLC_SHIFT);
2978 
2979         /* Get the time stamp. */
2980         pRxFrame->timestamp = (uint16_t)((cs_temp & CAN_CS_TIME_STAMP_MASK) >> CAN_CS_TIME_STAMP_SHIFT);
2981 
2982         /* Calculate the DWORD number, dataSize 0/1/2/3 corresponds to 8/16/32/64
2983            Bytes payload. */
2984         for (cnt = 0; cnt < (dataSize + 1U); cnt++)
2985         {
2986             payload_dword *= 2U;
2987         }
2988 
2989         /* Store Message Payload. */
2990         for (cnt = 0; cnt < payload_dword; cnt++)
2991         {
2992             pRxFrame->dataWord[cnt] = mbAddr[offset + 2U + cnt];
2993         }
2994 
2995         /* Read free-running timer to unlock Rx Message Buffer. */
2996         (void)base->TIMER;
2997 
2998         if ((uint32_t)kFLEXCAN_RxMbFull == rx_code)
2999         {
3000             status = kStatus_Success;
3001         }
3002         else
3003         {
3004             status = kStatus_FLEXCAN_RxOverflow;
3005         }
3006     }
3007     else
3008     {
3009         /* Read free-running timer to unlock Rx Message Buffer. */
3010         (void)base->TIMER;
3011 
3012         status = kStatus_Fail;
3013     }
3014 
3015     return status;
3016 }
3017 #endif
3018 
3019 /*!
3020  * brief Reads a FlexCAN Message from Legacy Rx FIFO.
3021  *
3022  * This function reads a CAN message from the FlexCAN Legacy Rx FIFO.
3023  *
3024  * param base FlexCAN peripheral base address.
3025  * param pRxFrame Pointer to CAN message frame structure for reception.
3026  * retval kStatus_Success - Read Message from Rx FIFO successfully.
3027  * retval kStatus_Fail    - Rx FIFO is not enabled.
3028  */
3029 status_t FLEXCAN_ReadRxFifo(CAN_Type *base, flexcan_frame_t *pRxFrame)
3030 {
3031     /* Assertion. */
3032     assert(NULL != pRxFrame);
3033 
3034     uint32_t cs_temp;
3035     status_t status;
3036 
3037     /* Check if Legacy Rx FIFO is Enabled. */
3038     if (0U != (base->MCR & CAN_MCR_RFEN_MASK))
3039     {
3040         /* Read CS field of Rx Message Buffer to lock Message Buffer. */
3041         cs_temp = base->MB[0].CS;
3042 
3043         /* Read data from Rx FIFO output port. */
3044         /* Store Message ID. */
3045         pRxFrame->id = base->MB[0].ID & (CAN_ID_EXT_MASK | CAN_ID_STD_MASK);
3046 
3047         /* Get the message ID and format. */
3048         pRxFrame->format = (cs_temp & CAN_CS_IDE_MASK) != 0U ? (uint8_t)kFLEXCAN_FrameFormatExtend :
3049                                                                (uint8_t)kFLEXCAN_FrameFormatStandard;
3050 
3051         /* Get the message type. */
3052         pRxFrame->type =
3053             (cs_temp & CAN_CS_RTR_MASK) != 0U ? (uint8_t)kFLEXCAN_FrameTypeRemote : (uint8_t)kFLEXCAN_FrameTypeData;
3054 
3055         /* Get the message length. */
3056         pRxFrame->length = (uint8_t)((cs_temp & CAN_CS_DLC_MASK) >> CAN_CS_DLC_SHIFT);
3057 
3058         /* Get the time stamp. */
3059         pRxFrame->timestamp = (uint16_t)((cs_temp & CAN_CS_TIME_STAMP_MASK) >> CAN_CS_TIME_STAMP_SHIFT);
3060 
3061         /* Store Message Payload. */
3062         pRxFrame->dataWord0 = base->MB[0].WORD0;
3063         pRxFrame->dataWord1 = base->MB[0].WORD1;
3064 
3065         /* Store ID Filter Hit Index. */
3066         pRxFrame->idhit = (uint16_t)(base->RXFIR & CAN_RXFIR_IDHIT_MASK);
3067 
3068         /* Read free-running timer to unlock Rx Message Buffer. */
3069         (void)base->TIMER;
3070 
3071         status = kStatus_Success;
3072     }
3073     else
3074     {
3075         status = kStatus_Fail;
3076     }
3077 
3078     return status;
3079 }
3080 
3081 #if (defined(FSL_FEATURE_FLEXCAN_HAS_ENHANCED_RX_FIFO) && FSL_FEATURE_FLEXCAN_HAS_ENHANCED_RX_FIFO)
3082 /*!
3083  * brief Reads a FlexCAN Message from Enhanced Rx FIFO.
3084  *
3085  * This function reads a CAN or CAN FD message from the FlexCAN Enhanced Rx FIFO.
3086  *
3087  * param base FlexCAN peripheral base address.
3088  * param pRxFrame Pointer to CAN FD message frame structure for reception.
3089  * retval kStatus_Success - Read Message from Rx FIFO successfully.
3090  * retval kStatus_Fail    - Rx FIFO is not enabled.
3091  */
3092 status_t FLEXCAN_ReadEnhancedRxFifo(CAN_Type *base, flexcan_fd_frame_t *pRxFrame)
3093 {
3094     /* Assertion. */
3095     assert(NULL != pRxFrame);
3096 
3097     status_t status;
3098     uint32_t idHitOff;
3099 
3100     /* Check if Enhanced Rx FIFO is Enabled. */
3101     if (0U != (base->ERFCR & CAN_ERFCR_ERFEN_MASK))
3102     {
3103         /* Enhanced Rx FIFO ID HIT offset is changed dynamically according to data length code (DLC) . */
3104         idHitOff = (DLC_LENGTH_DECODE(((flexcan_fd_frame_t *)E_RX_FIFO(base))->length) + 3U) / 4U + 3U;
3105         /* Copy CAN FD Message from Enhanced Rx FIFO, should use the DLC value to identify the bytes that belong to the
3106          * message which is being read. */
3107         (void)memcpy((void *)pRxFrame, (void *)(uint32_t *)E_RX_FIFO(base), sizeof(uint32_t) * idHitOff);
3108         pRxFrame->idhit = pRxFrame->dataWord[idHitOff - 3U];
3109         /* Clear the unused frame data. */
3110         for (uint32_t i = (idHitOff - 3U); i < 16U; i++)
3111         {
3112             pRxFrame->dataWord[i] = 0x0;
3113         }
3114 
3115         /* Clear data available flag to let FlexCAN know one frame has been read from the Enhanced Rx FIFO. */
3116         base->ERFSR = CAN_ERFSR_ERFDA_MASK;
3117         status      = kStatus_Success;
3118     }
3119     else
3120     {
3121         status = kStatus_Fail;
3122     }
3123 
3124     return status;
3125 }
3126 #endif
3127 
3128 /*!
3129  * brief Performs a polling send transaction on the CAN bus.
3130  *
3131  * note  A transfer handle does not need to be created  before calling this API.
3132  *
3133  * param base FlexCAN peripheral base pointer.
3134  * param mbIdx The FlexCAN Message Buffer index.
3135  * param pTxFrame Pointer to CAN message frame to be sent.
3136  * retval kStatus_Success - Write Tx Message Buffer Successfully.
3137  * retval kStatus_Fail    - Tx Message Buffer is currently in use.
3138  */
3139 status_t FLEXCAN_TransferSendBlocking(CAN_Type *base, uint8_t mbIdx, flexcan_frame_t *pTxFrame)
3140 {
3141     status_t status;
3142 
3143     /* Write Tx Message Buffer to initiate a data sending. */
3144     if (kStatus_Success == FLEXCAN_WriteTxMb(base, mbIdx, (const flexcan_frame_t *)(uintptr_t)pTxFrame))
3145     {
3146 /* Wait until CAN Message send out. */
3147 #if (defined(FSL_FEATURE_FLEXCAN_HAS_EXTENDED_FLAG_REGISTER)) && (FSL_FEATURE_FLEXCAN_HAS_EXTENDED_FLAG_REGISTER > 0)
3148         uint64_t u64flag = 1;
3149         while (0U == FLEXCAN_GetMbStatusFlags(base, u64flag << mbIdx))
3150 #else
3151         uint32_t u32flag = 1;
3152         while (0U == FLEXCAN_GetMbStatusFlags(base, u32flag << mbIdx))
3153 #endif
3154         {
3155         }
3156 
3157 /* Clean Tx Message Buffer Flag. */
3158 #if (defined(FSL_FEATURE_FLEXCAN_HAS_EXTENDED_FLAG_REGISTER)) && (FSL_FEATURE_FLEXCAN_HAS_EXTENDED_FLAG_REGISTER > 0)
3159         FLEXCAN_ClearMbStatusFlags(base, u64flag << mbIdx);
3160 #else
3161         FLEXCAN_ClearMbStatusFlags(base, u32flag << mbIdx);
3162 #endif
3163         /*After TX MB tranfered success, update the Timestamp from MB[mbIdx].CS register*/
3164         pTxFrame->timestamp = (uint16_t)((base->MB[mbIdx].CS & CAN_CS_TIME_STAMP_MASK) >> CAN_CS_TIME_STAMP_SHIFT);
3165 
3166         status = kStatus_Success;
3167     }
3168     else
3169     {
3170         status = kStatus_Fail;
3171     }
3172 
3173     return status;
3174 }
3175 
3176 /*!
3177  * brief Performs a polling receive transaction on the CAN bus.
3178  *
3179  * note  A transfer handle does not need to be created  before calling this API.
3180  *
3181  * param base FlexCAN peripheral base pointer.
3182  * param mbIdx The FlexCAN Message Buffer index.
3183  * param pRxFrame Pointer to CAN message frame structure for reception.
3184  * retval kStatus_Success            - Rx Message Buffer is full and has been read successfully.
3185  * retval kStatus_FLEXCAN_RxOverflow - Rx Message Buffer is already overflowed and has been read successfully.
3186  * retval kStatus_Fail               - Rx Message Buffer is empty.
3187  */
3188 status_t FLEXCAN_TransferReceiveBlocking(CAN_Type *base, uint8_t mbIdx, flexcan_frame_t *pRxFrame)
3189 {
3190 /* Wait until Rx Message Buffer non-empty. */
3191 #if (defined(FSL_FEATURE_FLEXCAN_HAS_EXTENDED_FLAG_REGISTER)) && (FSL_FEATURE_FLEXCAN_HAS_EXTENDED_FLAG_REGISTER > 0)
3192     uint64_t u64flag = 1;
3193     while (0U == FLEXCAN_GetMbStatusFlags(base, u64flag << mbIdx))
3194 #else
3195     uint32_t u32flag = 1;
3196     while (0U == FLEXCAN_GetMbStatusFlags(base, u32flag << mbIdx))
3197 #endif
3198     {
3199     }
3200 
3201 /* Clean Rx Message Buffer Flag. */
3202 #if (defined(FSL_FEATURE_FLEXCAN_HAS_EXTENDED_FLAG_REGISTER)) && (FSL_FEATURE_FLEXCAN_HAS_EXTENDED_FLAG_REGISTER > 0)
3203     FLEXCAN_ClearMbStatusFlags(base, u64flag << mbIdx);
3204 #else
3205     FLEXCAN_ClearMbStatusFlags(base, u32flag << mbIdx);
3206 #endif
3207 
3208     /* Read Received CAN Message. */
3209     return FLEXCAN_ReadRxMb(base, mbIdx, pRxFrame);
3210 }
3211 
3212 #if (defined(FSL_FEATURE_FLEXCAN_HAS_FLEXIBLE_DATA_RATE) && FSL_FEATURE_FLEXCAN_HAS_FLEXIBLE_DATA_RATE)
3213 /*!
3214  * brief Performs a polling send transaction on the CAN bus.
3215  *
3216  * note  A transfer handle does not need to be created before calling this API.
3217  *
3218  * param base FlexCAN peripheral base pointer.
3219  * param mbIdx The FlexCAN FD Message Buffer index.
3220  * param pTxFrame Pointer to CAN FD message frame to be sent.
3221  * retval kStatus_Success - Write Tx Message Buffer Successfully.
3222  * retval kStatus_Fail    - Tx Message Buffer is currently in use.
3223  */
3224 status_t FLEXCAN_TransferFDSendBlocking(CAN_Type *base, uint8_t mbIdx, flexcan_fd_frame_t *pTxFrame)
3225 {
3226     status_t status;
3227 
3228     /* Write Tx Message Buffer to initiate a data sending. */
3229     if (kStatus_Success == FLEXCAN_WriteFDTxMb(base, mbIdx, (const flexcan_fd_frame_t *)(uintptr_t)pTxFrame))
3230     {
3231 /* Wait until CAN Message send out. */
3232 #if (defined(FSL_FEATURE_FLEXCAN_HAS_EXTENDED_FLAG_REGISTER)) && (FSL_FEATURE_FLEXCAN_HAS_EXTENDED_FLAG_REGISTER > 0)
3233         uint64_t u64flag = 1;
3234         while (0U == FLEXCAN_GetMbStatusFlags(base, u64flag << mbIdx))
3235 #else
3236         uint32_t u32flag = 1;
3237         while (0U == FLEXCAN_GetMbStatusFlags(base, u32flag << mbIdx))
3238 #endif
3239         {
3240         }
3241 
3242 /* Clean Tx Message Buffer Flag. */
3243 #if (defined(FSL_FEATURE_FLEXCAN_HAS_EXTENDED_FLAG_REGISTER)) && (FSL_FEATURE_FLEXCAN_HAS_EXTENDED_FLAG_REGISTER > 0)
3244         FLEXCAN_ClearMbStatusFlags(base, u64flag << mbIdx);
3245 #else
3246         FLEXCAN_ClearMbStatusFlags(base, u32flag << mbIdx);
3247 #endif
3248         /*After TX MB tranfered success, update the Timestamp from base->MB[offset for CAN FD].CS register*/
3249         volatile uint32_t *mbAddr = &(base->MB[0].CS);
3250         uint32_t offset           = FLEXCAN_GetFDMailboxOffset(base, mbIdx);
3251         pTxFrame->timestamp       = (uint16_t)((mbAddr[offset] & CAN_CS_TIME_STAMP_MASK) >> CAN_CS_TIME_STAMP_SHIFT);
3252 
3253         status = kStatus_Success;
3254     }
3255     else
3256     {
3257         status = kStatus_Fail;
3258     }
3259 
3260     return status;
3261 }
3262 
3263 /*!
3264  * brief Performs a polling receive transaction on the CAN bus.
3265  *
3266  * note  A transfer handle does not need to be created before calling this API.
3267  *
3268  * param base FlexCAN peripheral base pointer.
3269  * param mbIdx The FlexCAN FD Message Buffer index.
3270  * param pRxFrame Pointer to CAN FD message frame structure for reception.
3271  * retval kStatus_Success            - Rx Message Buffer is full and has been read successfully.
3272  * retval kStatus_FLEXCAN_RxOverflow - Rx Message Buffer is already overflowed and has been read successfully.
3273  * retval kStatus_Fail               - Rx Message Buffer is empty.
3274  */
3275 status_t FLEXCAN_TransferFDReceiveBlocking(CAN_Type *base, uint8_t mbIdx, flexcan_fd_frame_t *pRxFrame)
3276 {
3277 /* Wait until Rx Message Buffer non-empty. */
3278 #if (defined(FSL_FEATURE_FLEXCAN_HAS_EXTENDED_FLAG_REGISTER)) && (FSL_FEATURE_FLEXCAN_HAS_EXTENDED_FLAG_REGISTER > 0)
3279     uint64_t u64flag = 1;
3280     while (0U == FLEXCAN_GetMbStatusFlags(base, u64flag << mbIdx))
3281 #else
3282     uint32_t u32flag = 1;
3283     while (0U == FLEXCAN_GetMbStatusFlags(base, u32flag << mbIdx))
3284 #endif
3285     {
3286     }
3287 
3288 /* Clean Rx Message Buffer Flag. */
3289 #if (defined(FSL_FEATURE_FLEXCAN_HAS_EXTENDED_FLAG_REGISTER)) && (FSL_FEATURE_FLEXCAN_HAS_EXTENDED_FLAG_REGISTER > 0)
3290     FLEXCAN_ClearMbStatusFlags(base, u64flag << mbIdx);
3291 #else
3292     FLEXCAN_ClearMbStatusFlags(base, u32flag << mbIdx);
3293 #endif
3294 
3295     /* Read Received CAN Message. */
3296     return FLEXCAN_ReadFDRxMb(base, mbIdx, pRxFrame);
3297 }
3298 #endif
3299 
3300 /*!
3301  * brief Performs a polling receive transaction from Legacy Rx FIFO on the CAN bus.
3302  *
3303  * note  A transfer handle does not need to be created before calling this API.
3304  *
3305  * param base FlexCAN peripheral base pointer.
3306  * param pRxFrame Pointer to CAN message frame structure for reception.
3307  * retval kStatus_Success - Read Message from Rx FIFO successfully.
3308  * retval kStatus_Fail    - Rx FIFO is not enabled.
3309  */
3310 status_t FLEXCAN_TransferReceiveFifoBlocking(CAN_Type *base, flexcan_frame_t *pRxFrame)
3311 {
3312     status_t rxFifoStatus;
3313 
3314     /* Wait until Legacy Rx FIFO non-empty. */
3315     while (0U == FLEXCAN_GetMbStatusFlags(base, (uint32_t)kFLEXCAN_RxFifoFrameAvlFlag))
3316     {
3317     }
3318 
3319     /* Read data from Legacy Rx FIFO. */
3320     rxFifoStatus = FLEXCAN_ReadRxFifo(base, pRxFrame);
3321 
3322     /* Clean Rx Fifo available flag. */
3323     FLEXCAN_ClearMbStatusFlags(base, (uint32_t)kFLEXCAN_RxFifoFrameAvlFlag);
3324 
3325     return rxFifoStatus;
3326 }
3327 
3328 #if (defined(FSL_FEATURE_FLEXCAN_HAS_ENHANCED_RX_FIFO) && FSL_FEATURE_FLEXCAN_HAS_ENHANCED_RX_FIFO)
3329 /*!
3330  * brief Performs a polling receive transaction from Enhanced Rx FIFO on the CAN bus.
3331  *
3332  * note  A transfer handle does not need to be created before calling this API.
3333  *
3334  * param base FlexCAN peripheral base pointer.
3335  * param pRxFrame Pointer to CAN FD message frame structure for reception.
3336  * retval kStatus_Success - Read Message from Rx FIFO successfully.
3337  * retval kStatus_Fail    - Rx FIFO is not enabled.
3338  */
3339 status_t FLEXCAN_TransferReceiveEnhancedFifoBlocking(CAN_Type *base, flexcan_fd_frame_t *pRxFrame)
3340 {
3341     status_t rxFifoStatus;
3342 
3343     /* Wait until Enhanced Rx FIFO non-empty. */
3344     while (0U == (FLEXCAN_GetStatusFlags(base) & (uint64_t)kFLEXCAN_ERxFifoDataAvlIntFlag))
3345     {
3346     }
3347 
3348     /* Read data from Enhanced Rx FIFO */
3349     rxFifoStatus = FLEXCAN_ReadEnhancedRxFifo(base, pRxFrame);
3350 
3351     return rxFifoStatus;
3352 }
3353 #endif
3354 
3355 /*!
3356  * brief Initializes the FlexCAN handle.
3357  *
3358  * This function initializes the FlexCAN handle, which can be used for other FlexCAN
3359  * transactional APIs. Usually, for a specified FlexCAN instance,
3360  * call this API once to get the initialized handle.
3361  *
3362  * param base FlexCAN peripheral base address.
3363  * param handle FlexCAN handle pointer.
3364  * param callback The callback function.
3365  * param userData The parameter of the callback function.
3366  */
3367 void FLEXCAN_TransferCreateHandle(CAN_Type *base,
3368                                   flexcan_handle_t *handle,
3369                                   flexcan_transfer_callback_t callback,
3370                                   void *userData)
3371 {
3372     assert(NULL != handle);
3373 
3374     uint8_t instance;
3375 
3376     /* Clean FlexCAN transfer handle. */
3377     (void)memset(handle, 0, sizeof(*handle));
3378 
3379     /* Get instance from peripheral base address. */
3380     instance = (uint8_t)FLEXCAN_GetInstance(base);
3381 
3382     /* Save the context in global variables to support the double weak mechanism. */
3383     s_flexcanHandle[instance] = handle;
3384 
3385     /* Register Callback function. */
3386     handle->callback = callback;
3387     handle->userData = userData;
3388 
3389     s_flexcanIsr = FLEXCAN_TransferHandleIRQ;
3390 
3391     /* We Enable Error & Status interrupt here, because this interrupt just
3392      * report current status of FlexCAN module through Callback function.
3393      * It is insignificance without a available callback function.
3394      */
3395     if (handle->callback != NULL)
3396     {
3397         FLEXCAN_EnableInterrupts(
3398             base, (uint32_t)kFLEXCAN_BusOffInterruptEnable | (uint32_t)kFLEXCAN_ErrorInterruptEnable |
3399                       (uint32_t)kFLEXCAN_RxWarningInterruptEnable | (uint32_t)kFLEXCAN_TxWarningInterruptEnable |
3400                       (uint32_t)kFLEXCAN_WakeUpInterruptEnable
3401 #if (defined(FSL_FEATURE_FLEXCAN_HAS_PN_MODE) && FSL_FEATURE_FLEXCAN_HAS_PN_MODE)
3402                       | (uint64_t)kFLEXCAN_PNMatchWakeUpInterruptEnable |
3403                       (uint64_t)kFLEXCAN_PNTimeoutWakeUpInterruptEnable
3404 #endif
3405 #if (defined(FSL_FEATURE_FLEXCAN_HAS_MEMORY_ERROR_CONTROL) && FSL_FEATURE_FLEXCAN_HAS_MEMORY_ERROR_CONTROL)
3406                       | (uint64_t)kFLEXCAN_HostAccessNCErrorInterruptEnable |
3407                       (uint64_t)kFLEXCAN_FlexCanAccessNCErrorInterruptEnable |
3408                       (uint64_t)kFLEXCAN_HostOrFlexCanCErrorInterruptEnable
3409 #endif
3410         );
3411     }
3412     else
3413     {
3414         FLEXCAN_DisableInterrupts(
3415             base, (uint32_t)kFLEXCAN_BusOffInterruptEnable | (uint32_t)kFLEXCAN_ErrorInterruptEnable |
3416                       (uint32_t)kFLEXCAN_RxWarningInterruptEnable | (uint32_t)kFLEXCAN_TxWarningInterruptEnable |
3417                       (uint32_t)kFLEXCAN_WakeUpInterruptEnable
3418 #if (defined(FSL_FEATURE_FLEXCAN_HAS_PN_MODE) && FSL_FEATURE_FLEXCAN_HAS_PN_MODE)
3419                       | (uint64_t)kFLEXCAN_PNMatchWakeUpInterruptEnable |
3420                       (uint64_t)kFLEXCAN_PNTimeoutWakeUpInterruptEnable
3421 #endif
3422 #if (defined(FSL_FEATURE_FLEXCAN_HAS_MEMORY_ERROR_CONTROL) && FSL_FEATURE_FLEXCAN_HAS_MEMORY_ERROR_CONTROL)
3423                       | (uint64_t)kFLEXCAN_HostAccessNCErrorInterruptEnable |
3424                       (uint64_t)kFLEXCAN_FlexCanAccessNCErrorInterruptEnable |
3425                       (uint64_t)kFLEXCAN_HostOrFlexCanCErrorInterruptEnable
3426 #endif
3427         );
3428     }
3429 
3430     /* Enable interrupts in NVIC. */
3431     (void)EnableIRQ((IRQn_Type)(s_flexcanRxWarningIRQ[instance]));
3432     (void)EnableIRQ((IRQn_Type)(s_flexcanTxWarningIRQ[instance]));
3433     (void)EnableIRQ((IRQn_Type)(s_flexcanWakeUpIRQ[instance]));
3434     (void)EnableIRQ((IRQn_Type)(s_flexcanErrorIRQ[instance]));
3435     (void)EnableIRQ((IRQn_Type)(s_flexcanBusOffIRQ[instance]));
3436     (void)EnableIRQ((IRQn_Type)(s_flexcanMbIRQ[instance]));
3437 }
3438 
3439 /*!
3440  * brief Sends a message using IRQ.
3441  *
3442  * This function sends a message using IRQ. This is a non-blocking function, which returns
3443  * right away. When messages have been sent out, the send callback function is called.
3444  *
3445  * param base FlexCAN peripheral base address.
3446  * param handle FlexCAN handle pointer.
3447  * param pMbXfer FlexCAN Message Buffer transfer structure. See the #flexcan_mb_transfer_t.
3448  * retval kStatus_Success        Start Tx Message Buffer sending process successfully.
3449  * retval kStatus_Fail           Write Tx Message Buffer failed.
3450  * retval kStatus_FLEXCAN_TxBusy Tx Message Buffer is in use.
3451  */
3452 status_t FLEXCAN_TransferSendNonBlocking(CAN_Type *base, flexcan_handle_t *handle, flexcan_mb_transfer_t *pMbXfer)
3453 {
3454     /* Assertion. */
3455     assert(NULL != handle);
3456     assert(NULL != pMbXfer);
3457     assert(pMbXfer->mbIdx <= (base->MCR & CAN_MCR_MAXMB_MASK));
3458 #if !defined(NDEBUG)
3459     assert(!FLEXCAN_IsMbOccupied(base, pMbXfer->mbIdx));
3460 #endif
3461 
3462     status_t status;
3463 
3464     /* Check if Message Buffer is idle. */
3465     if ((uint8_t)kFLEXCAN_StateIdle == handle->mbState[pMbXfer->mbIdx])
3466     {
3467         /* Distinguish transmit type. */
3468         if ((uint32_t)kFLEXCAN_FrameTypeRemote == pMbXfer->frame->type)
3469         {
3470             handle->mbState[pMbXfer->mbIdx] = (uint8_t)kFLEXCAN_StateTxRemote;
3471         }
3472         else
3473         {
3474             handle->mbState[pMbXfer->mbIdx] = (uint8_t)kFLEXCAN_StateTxData;
3475         }
3476 
3477         if (kStatus_Success ==
3478             FLEXCAN_WriteTxMb(base, pMbXfer->mbIdx, (const flexcan_frame_t *)(uintptr_t)pMbXfer->frame))
3479         {
3480 /* Enable Message Buffer Interrupt. */
3481 #if (defined(FSL_FEATURE_FLEXCAN_HAS_EXTENDED_FLAG_REGISTER)) && (FSL_FEATURE_FLEXCAN_HAS_EXTENDED_FLAG_REGISTER > 0)
3482             uint64_t u64mask = 1;
3483             FLEXCAN_EnableMbInterrupts(base, u64mask << pMbXfer->mbIdx);
3484 #else
3485             uint32_t u32mask = 1;
3486             FLEXCAN_EnableMbInterrupts(base, u32mask << pMbXfer->mbIdx);
3487 #endif
3488             status = kStatus_Success;
3489         }
3490         else
3491         {
3492             handle->mbState[pMbXfer->mbIdx] = (uint8_t)kFLEXCAN_StateIdle;
3493             status                          = kStatus_Fail;
3494         }
3495     }
3496     else
3497     {
3498         status = kStatus_FLEXCAN_TxBusy;
3499     }
3500 
3501     return status;
3502 }
3503 
3504 /*!
3505  * brief Receives a message using IRQ.
3506  *
3507  * This function receives a message using IRQ. This is non-blocking function, which returns
3508  * right away. When the message has been received, the receive callback function is called.
3509  *
3510  * param base FlexCAN peripheral base address.
3511  * param handle FlexCAN handle pointer.
3512  * param pMbXfer FlexCAN Message Buffer transfer structure. See the #flexcan_mb_transfer_t.
3513  * retval kStatus_Success        - Start Rx Message Buffer receiving process successfully.
3514  * retval kStatus_FLEXCAN_RxBusy - Rx Message Buffer is in use.
3515  */
3516 status_t FLEXCAN_TransferReceiveNonBlocking(CAN_Type *base, flexcan_handle_t *handle, flexcan_mb_transfer_t *pMbXfer)
3517 {
3518     status_t status;
3519 
3520     /* Assertion. */
3521     assert(NULL != handle);
3522     assert(NULL != pMbXfer);
3523     assert(pMbXfer->mbIdx <= (base->MCR & CAN_MCR_MAXMB_MASK));
3524 #if !defined(NDEBUG)
3525     assert(!FLEXCAN_IsMbOccupied(base, pMbXfer->mbIdx));
3526 #endif
3527 
3528     /* Check if Message Buffer is idle. */
3529     if ((uint8_t)kFLEXCAN_StateIdle == handle->mbState[pMbXfer->mbIdx])
3530     {
3531         handle->mbState[pMbXfer->mbIdx] = (uint8_t)kFLEXCAN_StateRxData;
3532 
3533         /* Register Message Buffer. */
3534         handle->mbFrameBuf[pMbXfer->mbIdx] = pMbXfer->frame;
3535 
3536 /* Enable Message Buffer Interrupt. */
3537 #if (defined(FSL_FEATURE_FLEXCAN_HAS_EXTENDED_FLAG_REGISTER)) && (FSL_FEATURE_FLEXCAN_HAS_EXTENDED_FLAG_REGISTER > 0)
3538         uint64_t u64mask = 1;
3539         FLEXCAN_EnableMbInterrupts(base, u64mask << pMbXfer->mbIdx);
3540 #else
3541         uint32_t u32mask = 1;
3542         FLEXCAN_EnableMbInterrupts(base, u32mask << pMbXfer->mbIdx);
3543 #endif
3544 
3545         status = kStatus_Success;
3546     }
3547     else
3548     {
3549         status = kStatus_FLEXCAN_RxBusy;
3550     }
3551 
3552     return status;
3553 }
3554 
3555 #if (defined(FSL_FEATURE_FLEXCAN_HAS_FLEXIBLE_DATA_RATE) && FSL_FEATURE_FLEXCAN_HAS_FLEXIBLE_DATA_RATE)
3556 /*!
3557  * brief Sends a message using IRQ.
3558  *
3559  * This function sends a message using IRQ. This is a non-blocking function, which returns
3560  * right away. When messages have been sent out, the send callback function is called.
3561  *
3562  * param base FlexCAN peripheral base address.
3563  * param handle FlexCAN handle pointer.
3564  * param pMbXfer FlexCAN FD Message Buffer transfer structure. See the #flexcan_mb_transfer_t.
3565  * retval kStatus_Success        Start Tx Message Buffer sending process successfully.
3566  * retval kStatus_Fail           Write Tx Message Buffer failed.
3567  * retval kStatus_FLEXCAN_TxBusy Tx Message Buffer is in use.
3568  */
3569 status_t FLEXCAN_TransferFDSendNonBlocking(CAN_Type *base, flexcan_handle_t *handle, flexcan_mb_transfer_t *pMbXfer)
3570 {
3571     /* Assertion. */
3572     assert(NULL != handle);
3573     assert(NULL != pMbXfer);
3574     assert(pMbXfer->mbIdx <= (base->MCR & CAN_MCR_MAXMB_MASK));
3575 #if !defined(NDEBUG)
3576     assert(!FLEXCAN_IsMbOccupied(base, pMbXfer->mbIdx));
3577 #endif
3578 
3579     status_t status;
3580 
3581     /* Check if Message Buffer is idle. */
3582     if ((uint8_t)kFLEXCAN_StateIdle == handle->mbState[pMbXfer->mbIdx])
3583     {
3584         /* Distinguish transmit type. */
3585         if ((uint32_t)kFLEXCAN_FrameTypeRemote == pMbXfer->framefd->type)
3586         {
3587             handle->mbState[pMbXfer->mbIdx] = (uint8_t)kFLEXCAN_StateTxRemote;
3588         }
3589         else
3590         {
3591             handle->mbState[pMbXfer->mbIdx] = (uint8_t)kFLEXCAN_StateTxData;
3592         }
3593 
3594         if (kStatus_Success ==
3595             FLEXCAN_WriteFDTxMb(base, pMbXfer->mbIdx, (const flexcan_fd_frame_t *)(uintptr_t)pMbXfer->framefd))
3596         {
3597 /* Enable Message Buffer Interrupt. */
3598 #if (defined(FSL_FEATURE_FLEXCAN_HAS_EXTENDED_FLAG_REGISTER)) && (FSL_FEATURE_FLEXCAN_HAS_EXTENDED_FLAG_REGISTER > 0)
3599             uint64_t u64mask = 1;
3600             FLEXCAN_EnableMbInterrupts(base, u64mask << pMbXfer->mbIdx);
3601 #else
3602             uint32_t u32mask = 1;
3603             FLEXCAN_EnableMbInterrupts(base, u32mask << pMbXfer->mbIdx);
3604 #endif
3605 
3606             status = kStatus_Success;
3607         }
3608         else
3609         {
3610             handle->mbState[pMbXfer->mbIdx] = (uint8_t)kFLEXCAN_StateIdle;
3611             status                          = kStatus_Fail;
3612         }
3613     }
3614     else
3615     {
3616         status = kStatus_FLEXCAN_TxBusy;
3617     }
3618 
3619     return status;
3620 }
3621 
3622 /*!
3623  * brief Receives a message using IRQ.
3624  *
3625  * This function receives a message using IRQ. This is non-blocking function, which returns
3626  * right away. When the message has been received, the receive callback function is called.
3627  *
3628  * param base FlexCAN peripheral base address.
3629  * param handle FlexCAN handle pointer.
3630  * param pMbXfer FlexCAN FD Message Buffer transfer structure. See the #flexcan_mb_transfer_t.
3631  * retval kStatus_Success        - Start Rx Message Buffer receiving process successfully.
3632  * retval kStatus_FLEXCAN_RxBusy - Rx Message Buffer is in use.
3633  */
3634 status_t FLEXCAN_TransferFDReceiveNonBlocking(CAN_Type *base, flexcan_handle_t *handle, flexcan_mb_transfer_t *pMbXfer)
3635 {
3636     /* Assertion. */
3637     assert(NULL != handle);
3638     assert(NULL != pMbXfer);
3639     assert(pMbXfer->mbIdx <= (base->MCR & CAN_MCR_MAXMB_MASK));
3640 #if !defined(NDEBUG)
3641     assert(!FLEXCAN_IsMbOccupied(base, pMbXfer->mbIdx));
3642 #endif
3643 
3644     status_t status;
3645 
3646     /* Check if Message Buffer is idle. */
3647     if ((uint8_t)kFLEXCAN_StateIdle == handle->mbState[pMbXfer->mbIdx])
3648     {
3649         handle->mbState[pMbXfer->mbIdx] = (uint8_t)kFLEXCAN_StateRxData;
3650 
3651         /* Register Message Buffer. */
3652         handle->mbFDFrameBuf[pMbXfer->mbIdx] = pMbXfer->framefd;
3653 
3654 /* Enable Message Buffer Interrupt. */
3655 #if (defined(FSL_FEATURE_FLEXCAN_HAS_EXTENDED_FLAG_REGISTER)) && (FSL_FEATURE_FLEXCAN_HAS_EXTENDED_FLAG_REGISTER > 0)
3656         uint64_t u64mask = 1;
3657         FLEXCAN_EnableMbInterrupts(base, u64mask << pMbXfer->mbIdx);
3658 #else
3659         uint32_t u32mask = 1;
3660         FLEXCAN_EnableMbInterrupts(base, u32mask << pMbXfer->mbIdx);
3661 #endif
3662 
3663         status = kStatus_Success;
3664     }
3665     else
3666     {
3667         status = kStatus_FLEXCAN_RxBusy;
3668     }
3669 
3670     return status;
3671 }
3672 #endif
3673 
3674 /*!
3675  * brief Receives a message from Legacy Rx FIFO using IRQ.
3676  *
3677  * This function receives a message using IRQ. This is a non-blocking function, which returns
3678  * right away. When all messages have been received, the receive callback function is called.
3679  *
3680  * param base FlexCAN peripheral base address.
3681  * param handle FlexCAN handle pointer.
3682  * param pFifoXfer FlexCAN Rx FIFO transfer structure. See the ref flexcan_fifo_transfer_t.
3683  * retval kStatus_Success            - Start Rx FIFO receiving process successfully.
3684  * retval kStatus_FLEXCAN_RxFifoBusy - Rx FIFO is currently in use.
3685  */
3686 status_t FLEXCAN_TransferReceiveFifoNonBlocking(CAN_Type *base,
3687                                                 flexcan_handle_t *handle,
3688                                                 flexcan_fifo_transfer_t *pFifoXfer)
3689 {
3690     /* Assertion. */
3691     assert(NULL != handle);
3692     assert(NULL != pFifoXfer);
3693 
3694     status_t status;
3695     uint32_t irqMask = (uint32_t)kFLEXCAN_RxFifoOverflowFlag | (uint32_t)kFLEXCAN_RxFifoWarningFlag;
3696 
3697     /* Check if Message Buffer is idle. */
3698     if ((uint8_t)kFLEXCAN_StateIdle == handle->rxFifoState)
3699     {
3700         handle->rxFifoState = (uint8_t)kFLEXCAN_StateRxFifo;
3701 
3702         /* Register Message Buffer. */
3703         handle->rxFifoFrameBuf         = pFifoXfer->frame;
3704         handle->rxFifoFrameNum         = pFifoXfer->frameNum;
3705         handle->rxFifoTransferTotalNum = pFifoXfer->frameNum;
3706 
3707         if (handle->rxFifoTransferTotalNum < 5U)
3708         {
3709             /* Enable data available interrupt. */
3710             irqMask |= (uint32_t)kFLEXCAN_RxFifoFrameAvlFlag;
3711         }
3712 
3713         /* Enable Message Buffer Interrupt. */
3714         FLEXCAN_EnableMbInterrupts(base, irqMask);
3715 
3716         status = kStatus_Success;
3717     }
3718     else
3719     {
3720         status = kStatus_FLEXCAN_RxFifoBusy;
3721     }
3722 
3723     return status;
3724 }
3725 
3726 /*!
3727  * brief Gets the Legacy Rx Fifo transfer status during a interrupt non-blocking receive.
3728  *
3729  * param base FlexCAN peripheral base address.
3730  * param handle FlexCAN handle pointer.
3731  * param count Number of CAN messages receive so far by the non-blocking transaction.
3732  * retval kStatus_InvalidArgument count is Invalid.
3733  * retval kStatus_Success Successfully return the count.
3734  */
3735 
3736 status_t FLEXCAN_TransferGetReceiveFifoCount(CAN_Type *base, flexcan_handle_t *handle, size_t *count)
3737 {
3738     assert(NULL != handle);
3739 
3740     status_t result = kStatus_Success;
3741 
3742     if (handle->rxFifoState == (uint32_t)kFLEXCAN_StateIdle)
3743     {
3744         result = kStatus_NoTransferInProgress;
3745     }
3746     else
3747     {
3748         *count = handle->rxFifoTransferTotalNum - handle->rxFifoFrameNum;
3749     }
3750 
3751     return result;
3752 }
3753 
3754 #if (defined(FSL_FEATURE_FLEXCAN_HAS_ENHANCED_RX_FIFO) && FSL_FEATURE_FLEXCAN_HAS_ENHANCED_RX_FIFO)
3755 /*!
3756  * brief Receives a message from Enhanced Rx FIFO using IRQ.
3757  *
3758  * This function receives a message using IRQ. This is a non-blocking function, which returns
3759  * right away. When all messages have been received, the receive callback function is called.
3760  *
3761  * param base FlexCAN peripheral base address.
3762  * param handle FlexCAN handle pointer.
3763  * param pFifoXfer FlexCAN Rx FIFO transfer structure. See the ref flexcan_fifo_transfer_t.
3764  * retval kStatus_Success            - Start Rx FIFO receiving process successfully.
3765  * retval kStatus_FLEXCAN_RxFifoBusy - Rx FIFO is currently in use.
3766  */
3767 status_t FLEXCAN_TransferReceiveEnhancedFifoNonBlocking(CAN_Type *base,
3768                                                         flexcan_handle_t *handle,
3769                                                         flexcan_fifo_transfer_t *pFifoXfer)
3770 {
3771     /* Assertion. */
3772     assert(NULL != handle);
3773     assert(NULL != pFifoXfer);
3774 
3775     status_t status;
3776     uint32_t watermark = ((base->ERFCR & CAN_ERFCR_ERFWM_MASK) >> CAN_ERFCR_ERFWM_SHIFT) + 1U;
3777     uint64_t irqMask =
3778         (uint64_t)kFLEXCAN_ERxFifoUnderflowInterruptEnable | (uint64_t)kFLEXCAN_ERxFifoOverflowInterruptEnable;
3779 
3780     /* Check if Enhanced Rx FIFO is idle. */
3781     if ((uint8_t)kFLEXCAN_StateIdle == handle->rxFifoState)
3782     {
3783         handle->rxFifoState = (uint8_t)kFLEXCAN_StateRxFifo;
3784 
3785         /* Register Message Buffer. */
3786         handle->rxFifoFDFrameBuf       = pFifoXfer->framefd;
3787         handle->rxFifoFrameNum         = pFifoXfer->frameNum;
3788         handle->rxFifoTransferTotalNum = pFifoXfer->frameNum;
3789 
3790         if (handle->rxFifoTransferTotalNum >= watermark)
3791         {
3792             /* Enable watermark interrupt. */
3793             irqMask |= (uint64_t)kFLEXCAN_ERxFifoWatermarkInterruptEnable;
3794         }
3795         else
3796         {
3797             /* Enable data available interrupt. */
3798             irqMask |= (uint64_t)kFLEXCAN_ERxFifoDataAvlInterruptEnable;
3799         }
3800         /* Enable Enhanced Rx FIFO Interrupt. */
3801         FLEXCAN_EnableInterrupts(base, irqMask);
3802 
3803         status = kStatus_Success;
3804     }
3805     else
3806     {
3807         status = kStatus_FLEXCAN_RxFifoBusy;
3808     }
3809 
3810     return status;
3811 }
3812 #endif
3813 
3814 /*!
3815  * brief Aborts the interrupt driven message send process.
3816  *
3817  * This function aborts the interrupt driven message send process.
3818  *
3819  * param base FlexCAN peripheral base address.
3820  * param handle FlexCAN handle pointer.
3821  * param mbIdx The FlexCAN Message Buffer index.
3822  */
3823 void FLEXCAN_TransferAbortSend(CAN_Type *base, flexcan_handle_t *handle, uint8_t mbIdx)
3824 {
3825     uint16_t timestamp;
3826 
3827     /* Assertion. */
3828     assert(NULL != handle);
3829     assert(mbIdx <= (base->MCR & CAN_MCR_MAXMB_MASK));
3830 #if !defined(NDEBUG)
3831     assert(!FLEXCAN_IsMbOccupied(base, mbIdx));
3832 #endif
3833 
3834 /* Disable Message Buffer Interrupt. */
3835 #if (defined(FSL_FEATURE_FLEXCAN_HAS_EXTENDED_FLAG_REGISTER)) && (FSL_FEATURE_FLEXCAN_HAS_EXTENDED_FLAG_REGISTER > 0)
3836     uint64_t u64mask = 1;
3837     FLEXCAN_DisableMbInterrupts(base, u64mask << mbIdx);
3838 #else
3839     uint32_t u32mask = 1;
3840     FLEXCAN_DisableMbInterrupts(base, u32mask << mbIdx);
3841 #endif
3842 
3843     /* Update the TX frame 's time stamp by MB[mbIdx].cs. */
3844     timestamp                = (uint16_t)((base->MB[mbIdx].CS & CAN_CS_TIME_STAMP_MASK) >> CAN_CS_TIME_STAMP_SHIFT);
3845     handle->timestamp[mbIdx] = timestamp;
3846 
3847     /* Clean Message Buffer. */
3848     FLEXCAN_SetTxMbConfig(base, mbIdx, true);
3849 
3850     handle->mbState[mbIdx] = (uint8_t)kFLEXCAN_StateIdle;
3851 }
3852 
3853 #if (defined(FSL_FEATURE_FLEXCAN_HAS_FLEXIBLE_DATA_RATE) && FSL_FEATURE_FLEXCAN_HAS_FLEXIBLE_DATA_RATE)
3854 /*!
3855  * brief Aborts the interrupt driven message send process.
3856  *
3857  * This function aborts the interrupt driven message send process.
3858  *
3859  * param base FlexCAN peripheral base address.
3860  * param handle FlexCAN handle pointer.
3861  * param mbIdx The FlexCAN FD Message Buffer index.
3862  */
3863 void FLEXCAN_TransferFDAbortSend(CAN_Type *base, flexcan_handle_t *handle, uint8_t mbIdx)
3864 {
3865     volatile uint32_t *mbAddr;
3866     uint32_t offset;
3867     uint16_t timestamp;
3868 
3869     /* Assertion. */
3870     assert(NULL != handle);
3871     assert(mbIdx <= (base->MCR & CAN_MCR_MAXMB_MASK));
3872 #if !defined(NDEBUG)
3873     assert(!FLEXCAN_IsMbOccupied(base, mbIdx));
3874 #endif
3875 
3876 /* Disable Message Buffer Interrupt. */
3877 #if (defined(FSL_FEATURE_FLEXCAN_HAS_EXTENDED_FLAG_REGISTER)) && (FSL_FEATURE_FLEXCAN_HAS_EXTENDED_FLAG_REGISTER > 0)
3878     uint64_t u64mask = 1;
3879     FLEXCAN_DisableMbInterrupts(base, u64mask << mbIdx);
3880 #else
3881     uint32_t u32mask = 1;
3882     FLEXCAN_DisableMbInterrupts(base, u32mask << mbIdx);
3883 #endif
3884 
3885     /* Update the TX frame 's time stamp by base->MB[offset for CAN FD].CS. */
3886     mbAddr                   = &(base->MB[0].CS);
3887     offset                   = FLEXCAN_GetFDMailboxOffset(base, mbIdx);
3888     timestamp                = (uint16_t)((mbAddr[offset] & CAN_CS_TIME_STAMP_MASK) >> CAN_CS_TIME_STAMP_SHIFT);
3889     handle->timestamp[mbIdx] = timestamp;
3890 
3891     /* Clean Message Buffer. */
3892     FLEXCAN_SetFDTxMbConfig(base, mbIdx, true);
3893 
3894     handle->mbState[mbIdx] = (uint8_t)kFLEXCAN_StateIdle;
3895 }
3896 
3897 /*!
3898  * brief Aborts the interrupt driven message receive process.
3899  *
3900  * This function aborts the interrupt driven message receive process.
3901  *
3902  * param base FlexCAN peripheral base address.
3903  * param handle FlexCAN handle pointer.
3904  * param mbIdx The FlexCAN FD Message Buffer index.
3905  */
3906 void FLEXCAN_TransferFDAbortReceive(CAN_Type *base, flexcan_handle_t *handle, uint8_t mbIdx)
3907 {
3908     /* Assertion. */
3909     assert(NULL != handle);
3910     assert(mbIdx <= (base->MCR & CAN_MCR_MAXMB_MASK));
3911 #if !defined(NDEBUG)
3912     assert(!FLEXCAN_IsMbOccupied(base, mbIdx));
3913 #endif
3914 
3915 /* Disable Message Buffer Interrupt. */
3916 #if (defined(FSL_FEATURE_FLEXCAN_HAS_EXTENDED_FLAG_REGISTER)) && (FSL_FEATURE_FLEXCAN_HAS_EXTENDED_FLAG_REGISTER > 0)
3917     uint64_t u64mask = 1;
3918     FLEXCAN_DisableMbInterrupts(base, u64mask << mbIdx);
3919 #else
3920     uint32_t u32mask = 1;
3921     FLEXCAN_DisableMbInterrupts(base, u32mask << mbIdx);
3922 #endif
3923 
3924     /* Un-register handle. */
3925     handle->mbFDFrameBuf[mbIdx] = NULL;
3926     handle->mbState[mbIdx]      = (uint8_t)kFLEXCAN_StateIdle;
3927 }
3928 #endif
3929 
3930 /*!
3931  * brief Aborts the interrupt driven message receive process.
3932  *
3933  * This function aborts the interrupt driven message receive process.
3934  *
3935  * param base FlexCAN peripheral base address.
3936  * param handle FlexCAN handle pointer.
3937  * param mbIdx The FlexCAN Message Buffer index.
3938  */
3939 void FLEXCAN_TransferAbortReceive(CAN_Type *base, flexcan_handle_t *handle, uint8_t mbIdx)
3940 {
3941     /* Assertion. */
3942     assert(NULL != handle);
3943     assert(mbIdx <= (base->MCR & CAN_MCR_MAXMB_MASK));
3944 #if !defined(NDEBUG)
3945     assert(!FLEXCAN_IsMbOccupied(base, mbIdx));
3946 #endif
3947 
3948 /* Disable Message Buffer Interrupt. */
3949 #if (defined(FSL_FEATURE_FLEXCAN_HAS_EXTENDED_FLAG_REGISTER)) && (FSL_FEATURE_FLEXCAN_HAS_EXTENDED_FLAG_REGISTER > 0)
3950     uint64_t u64mask = 1;
3951     FLEXCAN_DisableMbInterrupts(base, (u64mask << mbIdx));
3952 #else
3953     uint32_t u32mask = 1;
3954     FLEXCAN_DisableMbInterrupts(base, (u32mask << mbIdx));
3955 #endif
3956 
3957     /* Un-register handle. */
3958     handle->mbFrameBuf[mbIdx] = NULL;
3959     handle->mbState[mbIdx]    = (uint8_t)kFLEXCAN_StateIdle;
3960 }
3961 
3962 /*!
3963  * brief Aborts the interrupt driven message receive from Legacy Rx FIFO process.
3964  *
3965  * This function aborts the interrupt driven message receive from Legacy Rx FIFO process.
3966  *
3967  * param base FlexCAN peripheral base address.
3968  * param handle FlexCAN handle pointer.
3969  */
3970 void FLEXCAN_TransferAbortReceiveFifo(CAN_Type *base, flexcan_handle_t *handle)
3971 {
3972     /* Assertion. */
3973     assert(NULL != handle);
3974 
3975     /* Check if Rx FIFO is enabled. */
3976     if (0U != (base->MCR & CAN_MCR_RFEN_MASK))
3977     {
3978         /* Disable Rx Message FIFO Interrupts. */
3979         FLEXCAN_DisableMbInterrupts(base, (uint32_t)kFLEXCAN_RxFifoOverflowFlag | (uint32_t)kFLEXCAN_RxFifoWarningFlag |
3980                                               (uint32_t)kFLEXCAN_RxFifoFrameAvlFlag);
3981 
3982         /* Un-register handle. */
3983         handle->rxFifoFrameBuf = NULL;
3984         /* Clear transfer count. */
3985         handle->rxFifoFrameNum         = 0U;
3986         handle->rxFifoTransferTotalNum = 0U;
3987     }
3988 
3989     handle->rxFifoState = (uint8_t)kFLEXCAN_StateIdle;
3990 }
3991 
3992 #if (defined(FSL_FEATURE_FLEXCAN_HAS_ENHANCED_RX_FIFO) && FSL_FEATURE_FLEXCAN_HAS_ENHANCED_RX_FIFO)
3993 /*!
3994  * brief Aborts the interrupt driven message receive from Enhanced Rx FIFO process.
3995  *
3996  * This function aborts the interrupt driven message receive from Rx FIFO process.
3997  *
3998  * param base FlexCAN peripheral base address.
3999  * param handle FlexCAN handle pointer.
4000  */
4001 void FLEXCAN_TransferAbortReceiveEnhancedFifo(CAN_Type *base, flexcan_handle_t *handle)
4002 {
4003     /* Assertion. */
4004     assert(NULL != handle);
4005 
4006     /* Check if Enhanced Rx FIFO is enabled. */
4007     if (0U != (base->ERFCR & CAN_ERFCR_ERFEN_MASK))
4008     {
4009         /* Disable all Rx Message FIFO interrupts. */
4010         FLEXCAN_DisableInterrupts(base, (uint64_t)kFLEXCAN_ERxFifoUnderflowInterruptEnable |
4011                                             (uint64_t)kFLEXCAN_ERxFifoOverflowInterruptEnable |
4012                                             (uint64_t)kFLEXCAN_ERxFifoWatermarkInterruptEnable |
4013                                             (uint64_t)kFLEXCAN_ERxFifoDataAvlInterruptEnable);
4014 
4015         /* Un-register handle. */
4016         handle->rxFifoFDFrameBuf = NULL;
4017         /* Clear transfer count. */
4018         handle->rxFifoFrameNum         = 0U;
4019         handle->rxFifoTransferTotalNum = 0U;
4020     }
4021 
4022     handle->rxFifoState = (uint8_t)kFLEXCAN_StateIdle;
4023 }
4024 #endif
4025 
4026 /*!
4027  * brief Gets the detail index of Mailbox's Timestamp by handle.
4028  *
4029  * Then function can only be used when calling non-blocking Data transfer (TX/RX) API,
4030  * After TX/RX data transfer done (User can get the status by handler's callback function),
4031  * we can get the detail index of Mailbox's timestamp by handle,
4032  * Detail non-blocking data transfer API (TX/RX) contain.
4033  *   -FLEXCAN_TransferSendNonBlocking
4034  *   -FLEXCAN_TransferFDSendNonBlocking
4035  *   -FLEXCAN_TransferReceiveNonBlocking
4036  *   -FLEXCAN_TransferFDReceiveNonBlocking
4037  *   -FLEXCAN_TransferReceiveFifoNonBlocking
4038  *
4039  * param handle FlexCAN handle pointer.
4040  * param mbIdx The FlexCAN FD Message Buffer index.
4041  * return the index of mailbox 's timestamp stored in the handle.
4042  *
4043  */
4044 uint32_t FLEXCAN_GetTimeStamp(flexcan_handle_t *handle, uint8_t mbIdx)
4045 {
4046     /* Assertion. */
4047     assert(NULL != handle);
4048 
4049     return (uint32_t)(handle->timestamp[mbIdx]);
4050 }
4051 
4052 /*!
4053  * brief Check unhandle interrupt events
4054  *
4055  * param base FlexCAN peripheral base address.
4056  * return TRUE if unhandled interrupt action exist, FALSE if no unhandlered interrupt action exist.
4057  */
4058 static bool FLEXCAN_CheckUnhandleInterruptEvents(CAN_Type *base)
4059 {
4060     uint64_t tempmask;
4061     uint64_t tempflag;
4062     bool fgRet = false;
4063 
4064     if (0U == (FLEXCAN_GetStatusFlags(base) &
4065                (FLEXCAN_ERROR_AND_STATUS_INIT_FLAG | FLEXCAN_WAKE_UP_FLAG | FLEXCAN_MEMORY_ENHANCED_RX_FIFO_INIT_FLAG)))
4066     {
4067         /* If no error, wake_up or enhanced RX FIFO status, Checking whether exist MB interrupt status and legacy RX
4068          * FIFO interrupt status */
4069         tempmask = (uint64_t)base->IMASK1;
4070         tempflag = (uint64_t)base->IFLAG1;
4071 #if (defined(FSL_FEATURE_FLEXCAN_HAS_EXTENDED_FLAG_REGISTER)) && (FSL_FEATURE_FLEXCAN_HAS_EXTENDED_FLAG_REGISTER > 0)
4072         tempmask |= ((uint64_t)base->IMASK2) << 32;
4073         tempflag |= ((uint64_t)base->IFLAG2) << 32;
4074 #endif
4075         fgRet = (0U != (tempmask & tempflag));
4076     }
4077 #if (defined(FSL_FEATURE_FLEXCAN_HAS_ENHANCED_RX_FIFO) && FSL_FEATURE_FLEXCAN_HAS_ENHANCED_RX_FIFO)
4078     else if (0U != (FLEXCAN_GetStatusFlags(base) & FLEXCAN_MEMORY_ENHANCED_RX_FIFO_INIT_FLAG))
4079     {
4080         /* Checking whether exist enhanced RX FIFO interrupt status. */
4081         tempmask = (uint64_t)base->ERFIER;
4082         tempflag = (uint64_t)base->ERFSR;
4083         fgRet    = (0U != (tempmask & tempflag));
4084     }
4085 #endif
4086     else
4087     {
4088         /* Exist error or wake up flag. */
4089         fgRet = true;
4090     }
4091 
4092     return fgRet;
4093 }
4094 
4095 /*!
4096  * brief Sub Handler Data Trasfered Events
4097  *
4098  * param base FlexCAN peripheral base address.
4099  * param handle FlexCAN handle pointer.
4100  * param pResult Pointer to the Handle result.
4101  *
4102  * return the status after handle each data transfered event.
4103  */
4104 static status_t FLEXCAN_SubHandlerForDataTransfered(CAN_Type *base, flexcan_handle_t *handle, uint32_t *pResult)
4105 {
4106     status_t status = kStatus_FLEXCAN_UnHandled;
4107     uint32_t result = 0xFFU;
4108 
4109 #if (defined(FSL_FEATURE_FLEXCAN_HAS_EXTENDED_FLAG_REGISTER)) && (FSL_FEATURE_FLEXCAN_HAS_EXTENDED_FLAG_REGISTER > 0)
4110     uint64_t intflag = (((uint64_t)base->IMASK2 & base->IFLAG2) << 32UL) | (base->IMASK1 & base->IFLAG1);
4111 #else
4112     uint32_t intflag = base->IMASK1 & base->IFLAG1;
4113 #endif
4114     /* For this implementation, we solve the Message with lowest MB index first. */
4115     for (result = 0U; result < (uint32_t)FSL_FEATURE_FLEXCAN_HAS_MESSAGE_BUFFER_MAX_NUMBERn(base); result++)
4116     {
4117         /* Find the lowest unhandled Message Buffer */
4118 #if (defined(FSL_FEATURE_FLEXCAN_HAS_EXTENDED_FLAG_REGISTER)) && (FSL_FEATURE_FLEXCAN_HAS_EXTENDED_FLAG_REGISTER > 0)
4119         if (0UL != (intflag & ((uint64_t)1UL << result)))
4120 #else
4121         if (0UL != (intflag & ((uint32_t)1UL << result)))
4122 #endif
4123         {
4124             break;
4125         }
4126     }
4127 
4128     /* find Message to deal with. */
4129     if (result < (uint32_t)FSL_FEATURE_FLEXCAN_HAS_MESSAGE_BUFFER_MAX_NUMBERn(base))
4130     {
4131         /* Solve Legacy Rx FIFO interrupt. */
4132         if (((uint8_t)kFLEXCAN_StateIdle != handle->rxFifoState) && (result <= (uint32_t)CAN_IFLAG1_BUF7I_SHIFT) &&
4133             ((base->MCR & CAN_MCR_RFEN_MASK) != 0U))
4134         {
4135             uint32_t u32mask = 1;
4136             switch (u32mask << result)
4137             {
4138                 case kFLEXCAN_RxFifoOverflowFlag:
4139                     status = kStatus_FLEXCAN_RxFifoOverflow;
4140                     break;
4141 
4142                 case kFLEXCAN_RxFifoWarningFlag:
4143                     if ((handle->rxFifoFrameNum > 5U) && (0U != (base->IFLAG1 & (uint32_t)kFLEXCAN_RxFifoFrameAvlFlag)))
4144                     {
4145                         for (uint32_t i = 0; i < 5UL; i++)
4146                         {
4147                             status = FLEXCAN_ReadRxFifo(base, handle->rxFifoFrameBuf);
4148 
4149                             if (kStatus_Success == status)
4150                             {
4151                                 /* Align the current rxfifo timestamp to the timestamp array by handle. */
4152                                 handle->timestamp[i] = handle->rxFifoFrameBuf->timestamp;
4153                                 handle->rxFifoFrameBuf++;
4154                                 handle->rxFifoFrameNum--;
4155                                 /* Clean Rx Fifo available flag to discard the frame that has been read. */
4156                                 FLEXCAN_ClearMbStatusFlags(base, (uint32_t)kFLEXCAN_RxFifoFrameAvlFlag);
4157                             }
4158                             else
4159                             {
4160                                 return kStatus_FLEXCAN_RxFifoDisabled;
4161                             }
4162                         }
4163                         if (handle->rxFifoFrameNum < 5UL)
4164                         {
4165                             /* Enable data avaliable interrupt. */
4166                             FLEXCAN_EnableMbInterrupts(base, (uint32_t)kFLEXCAN_RxFifoFrameAvlFlag);
4167                         }
4168                         status = kStatus_FLEXCAN_RxFifoBusy;
4169                     }
4170                     else
4171                     {
4172                         /* Should enter case kFLEXCAN_RxFifoFrameAvlFlag but not, means previous transfer may have
4173                          * overflow*/
4174                         status = kStatus_FLEXCAN_RxFifoWarning;
4175                     }
4176                     break;
4177 
4178                 case kFLEXCAN_RxFifoFrameAvlFlag:
4179                     /* Whether still has CAN messages remaining to be received. */
4180                     if (handle->rxFifoFrameNum > 0U)
4181                     {
4182                         status = FLEXCAN_ReadRxFifo(base, handle->rxFifoFrameBuf);
4183                         if (kStatus_Success == status)
4184                         {
4185                             /* Align the current (index 0) rxfifo timestamp to the timestamp array by handle. */
4186                             handle->timestamp[0] = handle->rxFifoFrameBuf->timestamp;
4187                             handle->rxFifoFrameBuf++;
4188                             handle->rxFifoFrameNum--;
4189                         }
4190                         else
4191                         {
4192                             return kStatus_FLEXCAN_RxFifoDisabled;
4193                         }
4194                     }
4195                     if (handle->rxFifoFrameNum == 0U)
4196                     {
4197                         /* Stop receiving Ehanced Rx FIFO when the transmission is over. */
4198                         FLEXCAN_TransferAbortReceiveFifo(base, handle);
4199                         status = kStatus_FLEXCAN_RxFifoIdle;
4200                     }
4201                     else
4202                     {
4203                         /* Continue use data avaliable interrupt. */
4204                         status = kStatus_FLEXCAN_RxFifoBusy;
4205                     }
4206                     break;
4207 
4208                 default:
4209                     status = kStatus_FLEXCAN_UnHandled;
4210                     break;
4211             }
4212         }
4213         else
4214         {
4215             /* Get current State of Message Buffer. */
4216             switch (handle->mbState[result])
4217             {
4218                 /* Solve Rx Data Frame. */
4219                 case (uint8_t)kFLEXCAN_StateRxData:
4220 #if (defined(FSL_FEATURE_FLEXCAN_HAS_FLEXIBLE_DATA_RATE) && FSL_FEATURE_FLEXCAN_HAS_FLEXIBLE_DATA_RATE)
4221                     if (0U != (base->MCR & CAN_MCR_FDEN_MASK))
4222                     {
4223                         status = FLEXCAN_ReadFDRxMb(base, (uint8_t)result, handle->mbFDFrameBuf[result]);
4224                         if (kStatus_Success == status)
4225                         {
4226                             /* Align the current index of RX MB timestamp to the timestamp array by handle. */
4227                             handle->timestamp[result] = handle->mbFDFrameBuf[result]->timestamp;
4228                             status                    = kStatus_FLEXCAN_RxIdle;
4229                         }
4230                     }
4231                     else
4232 #endif
4233                     {
4234                         status = FLEXCAN_ReadRxMb(base, (uint8_t)result, handle->mbFrameBuf[result]);
4235                         if (kStatus_Success == status)
4236                         {
4237                             /* Align the current index of RX MB timestamp to the timestamp array by handle. */
4238                             handle->timestamp[result] = handle->mbFrameBuf[result]->timestamp;
4239                             status                    = kStatus_FLEXCAN_RxIdle;
4240                         }
4241                     }
4242 #if (defined(FSL_FEATURE_FLEXCAN_HAS_FLEXIBLE_DATA_RATE) && FSL_FEATURE_FLEXCAN_HAS_FLEXIBLE_DATA_RATE)
4243                     if (0U != (base->MCR & CAN_MCR_FDEN_MASK))
4244                     {
4245                         FLEXCAN_TransferFDAbortReceive(base, handle, (uint8_t)result);
4246                     }
4247                     else
4248 #endif
4249                     {
4250                         FLEXCAN_TransferAbortReceive(base, handle, (uint8_t)result);
4251                     }
4252                     break;
4253 
4254                 /* Sove Rx Remote Frame.  User need to Read the frame in Mail box in time by Read from MB API. */
4255                 case (uint8_t)kFLEXCAN_StateRxRemote:
4256                     status = kStatus_FLEXCAN_RxRemote;
4257 #if (defined(FSL_FEATURE_FLEXCAN_HAS_FLEXIBLE_DATA_RATE) && FSL_FEATURE_FLEXCAN_HAS_FLEXIBLE_DATA_RATE)
4258                     if (0U != (base->MCR & CAN_MCR_FDEN_MASK))
4259                     {
4260                         FLEXCAN_TransferFDAbortReceive(base, handle, (uint8_t)result);
4261                     }
4262                     else
4263 #endif
4264                     {
4265                         FLEXCAN_TransferAbortReceive(base, handle, (uint8_t)result);
4266                     }
4267                     break;
4268 
4269                 /* Solve Tx Data Frame. */
4270                 case (uint8_t)kFLEXCAN_StateTxData:
4271                     status = kStatus_FLEXCAN_TxIdle;
4272 #if (defined(FSL_FEATURE_FLEXCAN_HAS_FLEXIBLE_DATA_RATE) && FSL_FEATURE_FLEXCAN_HAS_FLEXIBLE_DATA_RATE)
4273                     if (0U != (base->MCR & CAN_MCR_FDEN_MASK))
4274                     {
4275                         FLEXCAN_TransferFDAbortSend(base, handle, (uint8_t)result);
4276                     }
4277                     else
4278 #endif
4279                     {
4280                         FLEXCAN_TransferAbortSend(base, handle, (uint8_t)result);
4281                     }
4282                     break;
4283 
4284                 /* Solve Tx Remote Frame. */
4285                 case (uint8_t)kFLEXCAN_StateTxRemote:
4286                     handle->mbState[result] = (uint8_t)kFLEXCAN_StateRxRemote;
4287                     status                  = kStatus_FLEXCAN_TxSwitchToRx;
4288                     break;
4289 
4290                 default:
4291                     status = kStatus_FLEXCAN_UnHandled;
4292                     break;
4293             }
4294         }
4295 
4296         /* Clear resolved Message Buffer IRQ. */
4297 #if (defined(FSL_FEATURE_FLEXCAN_HAS_EXTENDED_FLAG_REGISTER)) && (FSL_FEATURE_FLEXCAN_HAS_EXTENDED_FLAG_REGISTER > 0)
4298         uint64_t u64flag = 1;
4299         FLEXCAN_ClearMbStatusFlags(base, u64flag << result);
4300 #else
4301         uint32_t u32flag = 1;
4302         FLEXCAN_ClearMbStatusFlags(base, u32flag << result);
4303 #endif
4304     }
4305 
4306     *pResult = result;
4307 
4308     return status;
4309 }
4310 
4311 #if (defined(FSL_FEATURE_FLEXCAN_HAS_ENHANCED_RX_FIFO) && FSL_FEATURE_FLEXCAN_HAS_ENHANCED_RX_FIFO)
4312 /*!
4313  * brief Sub Handler Ehanced Rx FIFO event
4314  *
4315  * param base FlexCAN peripheral base address.
4316  * param handle FlexCAN handle pointer.
4317  * param flags FlexCAN interrupt flags.
4318  *
4319  * return the status after handle Ehanced Rx FIFO event.
4320  */
4321 static status_t FLEXCAN_SubHandlerForEhancedRxFifo(CAN_Type *base, flexcan_handle_t *handle, uint64_t flags)
4322 {
4323     uint32_t watermark = ((base->ERFCR & CAN_ERFCR_ERFWM_MASK) >> CAN_ERFCR_ERFWM_SHIFT) + 1U;
4324     uint32_t transferFrames;
4325 
4326     status_t status;
4327     /* Solve Ehanced Rx FIFO interrupt. */
4328     if ((0u != (flags & (uint64_t)kFLEXCAN_ERxFifoUnderflowIntFlag)) &&
4329         (0u != (base->ERFIER & CAN_ERFIER_ERFUFWIE_MASK)))
4330     {
4331         status = kStatus_FLEXCAN_RxFifoUnderflow;
4332         FLEXCAN_ClearStatusFlags(base, (uint64_t)kFLEXCAN_ERxFifoUnderflowIntFlag);
4333     }
4334     else if ((0u != (flags & (uint64_t)kFLEXCAN_ERxFifoOverflowIntFlag)) &&
4335              (0u != (base->ERFIER & CAN_ERFIER_ERFOVFIE_MASK)))
4336     {
4337         status = kStatus_FLEXCAN_RxFifoOverflow;
4338         FLEXCAN_ClearStatusFlags(base, (uint64_t)kFLEXCAN_ERxFifoOverflowIntFlag);
4339     }
4340     else if ((0u != (flags & (uint64_t)kFLEXCAN_ERxFifoWatermarkIntFlag)) &&
4341              (0u != (base->ERFIER & CAN_ERFIER_ERFWMIIE_MASK)))
4342     {
4343         /* Whether the number of CAN messages remaining to be received is greater than the watermark. */
4344         transferFrames = (handle->rxFifoFrameNum > watermark) ? watermark : handle->rxFifoFrameNum;
4345 
4346         for (uint32_t i = 0; i < transferFrames; i++)
4347         {
4348             status = FLEXCAN_ReadEnhancedRxFifo(base, handle->rxFifoFDFrameBuf);
4349 
4350             if (kStatus_Success == status)
4351             {
4352                 handle->rxFifoFDFrameBuf++;
4353                 handle->rxFifoFrameNum--;
4354                 /* Clear data Watermark flag due to has read back one frame. */
4355                 base->ERFSR = CAN_ERFSR_ERFWMI_MASK;
4356             }
4357             else
4358             {
4359                 return kStatus_FLEXCAN_RxFifoDisabled;
4360             }
4361         }
4362         if (handle->rxFifoFrameNum == 0U)
4363         {
4364             /* Stop receiving Ehanced Rx FIFO when the transmission is over. */
4365             FLEXCAN_TransferAbortReceiveEnhancedFifo(base, handle);
4366             status = kStatus_FLEXCAN_RxFifoIdle;
4367         }
4368         else if (handle->rxFifoFrameNum < watermark)
4369         {
4370             /* Disable watermark interrupt and enable data avaliable interrupt. */
4371             FLEXCAN_DisableInterrupts(base, (uint64_t)kFLEXCAN_ERxFifoWatermarkInterruptEnable);
4372             FLEXCAN_EnableInterrupts(base, (uint64_t)kFLEXCAN_ERxFifoDataAvlInterruptEnable);
4373             status = kStatus_FLEXCAN_RxFifoBusy;
4374         }
4375         else
4376         {
4377             /* Continue use watermark interrupt. */
4378             status = kStatus_FLEXCAN_RxFifoBusy;
4379         }
4380     }
4381     else
4382     {
4383         /* Data available status, check Whether still has CAN messages remaining to be received. */
4384         if (handle->rxFifoFrameNum > 0U)
4385         {
4386             status = FLEXCAN_ReadEnhancedRxFifo(base, handle->rxFifoFDFrameBuf);
4387 
4388             if (kStatus_Success == status)
4389             {
4390                 handle->rxFifoFDFrameBuf++;
4391                 handle->rxFifoFrameNum--;
4392             }
4393             else
4394             {
4395                 return kStatus_FLEXCAN_RxFifoDisabled;
4396             }
4397         }
4398         if (handle->rxFifoFrameNum == 0U)
4399         {
4400             /* Stop receiving Ehanced Rx FIFO when the transmission is over. */
4401             FLEXCAN_TransferAbortReceiveEnhancedFifo(base, handle);
4402             status = kStatus_FLEXCAN_RxFifoIdle;
4403         }
4404         else
4405         {
4406             /* Continue use data avaliable interrupt. */
4407             status = kStatus_FLEXCAN_RxFifoBusy;
4408         }
4409     }
4410     return status;
4411 }
4412 #endif
4413 
4414 /*!
4415  * brief FlexCAN IRQ handle function.
4416  *
4417  * This function handles the FlexCAN Error, the Message Buffer, and the Rx FIFO IRQ request.
4418  *
4419  * param base FlexCAN peripheral base address.
4420  * param handle FlexCAN handle pointer.
4421  */
4422 void FLEXCAN_TransferHandleIRQ(CAN_Type *base, flexcan_handle_t *handle)
4423 {
4424     /* Assertion. */
4425     assert(NULL != handle);
4426 
4427     status_t status;
4428     uint32_t mbNum = 0xFFU;
4429 #if (defined(FSL_FEATURE_FLEXCAN_HAS_PN_MODE) && FSL_FEATURE_FLEXCAN_HAS_PN_MODE) ||                   \
4430     (defined(FSL_FEATURE_FLEXCAN_HAS_ENHANCED_RX_FIFO) && FSL_FEATURE_FLEXCAN_HAS_ENHANCED_RX_FIFO) || \
4431     (defined(FSL_FEATURE_FLEXCAN_HAS_MEMORY_ERROR_CONTROL) && FSL_FEATURE_FLEXCAN_HAS_MEMORY_ERROR_CONTROL)
4432     uint64_t result = 0U;
4433 #else
4434     uint32_t result = 0U;
4435 #endif
4436     do
4437     {
4438         /* Get Current FlexCAN Module Error and Status. */
4439         result = FLEXCAN_GetStatusFlags(base);
4440 
4441         /* To handle FlexCAN Error and Status Interrupt first. */
4442         if (0U != (result & FLEXCAN_ERROR_AND_STATUS_INIT_FLAG))
4443         {
4444             status = kStatus_FLEXCAN_ErrorStatus;
4445             /* Clear FlexCAN Error and Status Interrupt. */
4446             FLEXCAN_ClearStatusFlags(base, FLEXCAN_ERROR_AND_STATUS_INIT_FLAG);
4447         }
4448         else if (0U != (result & FLEXCAN_WAKE_UP_FLAG))
4449         {
4450             status = kStatus_FLEXCAN_WakeUp;
4451             FLEXCAN_ClearStatusFlags(base, FLEXCAN_WAKE_UP_FLAG);
4452         }
4453 #if (defined(FSL_FEATURE_FLEXCAN_HAS_ENHANCED_RX_FIFO) && FSL_FEATURE_FLEXCAN_HAS_ENHANCED_RX_FIFO)
4454         else if (0U != (FLEXCAN_EFIFO_STATUS_UNMASK(result & FLEXCAN_MEMORY_ENHANCED_RX_FIFO_INIT_FLAG) & base->ERFIER))
4455         {
4456             status = FLEXCAN_SubHandlerForEhancedRxFifo(base, handle, result);
4457         }
4458 #endif
4459         else
4460         {
4461             /* To handle Message Buffer or Legacy Rx FIFO transfer. */
4462             status = FLEXCAN_SubHandlerForDataTransfered(base, handle, &mbNum);
4463             result = mbNum;
4464         }
4465 
4466         /* Calling Callback Function if has one. */
4467         if (handle->callback != NULL)
4468         {
4469             handle->callback(base, handle, status, result, handle->userData);
4470         }
4471     } while (FLEXCAN_CheckUnhandleInterruptEvents(base));
4472 }
4473 
4474 #if defined(CAN0)
4475 void CAN0_DriverIRQHandler(void);
4476 void CAN0_DriverIRQHandler(void)
4477 {
4478     assert(NULL != s_flexcanHandle[0]);
4479 
4480     s_flexcanIsr(CAN0, s_flexcanHandle[0]);
4481     SDK_ISR_EXIT_BARRIER;
4482 }
4483 #endif
4484 
4485 #if defined(CAN1)
4486 void CAN1_DriverIRQHandler(void);
4487 void CAN1_DriverIRQHandler(void)
4488 {
4489     assert(NULL != s_flexcanHandle[1]);
4490 
4491     s_flexcanIsr(CAN1, s_flexcanHandle[1]);
4492     SDK_ISR_EXIT_BARRIER;
4493 }
4494 #endif
4495 
4496 #if defined(CAN2)
4497 void CAN2_DriverIRQHandler(void);
4498 void CAN2_DriverIRQHandler(void)
4499 {
4500     assert(NULL != s_flexcanHandle[2]);
4501 
4502     s_flexcanIsr(CAN2, s_flexcanHandle[2]);
4503     SDK_ISR_EXIT_BARRIER;
4504 }
4505 #endif
4506 
4507 #if defined(CAN3)
4508 void CAN3_DriverIRQHandler(void);
4509 void CAN3_DriverIRQHandler(void)
4510 {
4511     assert(NULL != s_flexcanHandle[3]);
4512 
4513     s_flexcanIsr(CAN3, s_flexcanHandle[3]);
4514     SDK_ISR_EXIT_BARRIER;
4515 }
4516 #endif
4517 
4518 #if defined(CAN4)
4519 void CAN4_DriverIRQHandler(void);
4520 void CAN4_DriverIRQHandler(void)
4521 {
4522     assert(NULL != s_flexcanHandle[4]);
4523 
4524     s_flexcanIsr(CAN4, s_flexcanHandle[4]);
4525     SDK_ISR_EXIT_BARRIER;
4526 }
4527 #endif
4528 
4529 #if defined(DMA__CAN0)
4530 void DMA_FLEXCAN0_INT_DriverIRQHandler(void);
4531 void DMA_FLEXCAN0_INT_DriverIRQHandler(void)
4532 {
4533     assert(NULL != s_flexcanHandle[FLEXCAN_GetInstance(DMA__CAN0)]);
4534 
4535     s_flexcanIsr(DMA__CAN0, s_flexcanHandle[FLEXCAN_GetInstance(DMA__CAN0)]);
4536     SDK_ISR_EXIT_BARRIER;
4537 }
4538 #endif
4539 
4540 #if defined(DMA__CAN1)
4541 void DMA_FLEXCAN1_INT_DriverIRQHandler(void);
4542 void DMA_FLEXCAN1_INT_DriverIRQHandler(void)
4543 {
4544     assert(NULL != s_flexcanHandle[FLEXCAN_GetInstance(DMA__CAN1)]);
4545 
4546     s_flexcanIsr(DMA__CAN1, s_flexcanHandle[FLEXCAN_GetInstance(DMA__CAN1)]);
4547     SDK_ISR_EXIT_BARRIER;
4548 }
4549 #endif
4550 
4551 #if defined(DMA__CAN2)
4552 void DMA_FLEXCAN2_INT_DriverIRQHandler(void);
4553 void DMA_FLEXCAN2_INT_DriverIRQHandler(void)
4554 {
4555     assert(NULL != s_flexcanHandle[FLEXCAN_GetInstance(DMA__CAN2)]);
4556 
4557     s_flexcanIsr(DMA__CAN2, s_flexcanHandle[FLEXCAN_GetInstance(DMA__CAN2)]);
4558     SDK_ISR_EXIT_BARRIER;
4559 }
4560 #endif
4561 
4562 #if defined(ADMA__CAN0)
4563 void ADMA_FLEXCAN0_INT_DriverIRQHandler(void);
4564 void ADMA_FLEXCAN0_INT_DriverIRQHandler(void)
4565 {
4566     assert(NULL != s_flexcanHandle[FLEXCAN_GetInstance(ADMA__CAN0)]);
4567 
4568     s_flexcanIsr(ADMA__CAN0, s_flexcanHandle[FLEXCAN_GetInstance(ADMA__CAN0)]);
4569     SDK_ISR_EXIT_BARRIER;
4570 }
4571 #endif
4572 
4573 #if defined(ADMA__CAN1)
4574 void ADMA_FLEXCAN1_INT_DriverIRQHandler(void);
4575 void ADMA_FLEXCAN1_INT_DriverIRQHandler(void)
4576 {
4577     assert(NULL != s_flexcanHandle[FLEXCAN_GetInstance(ADMA__CAN1)]);
4578 
4579     s_flexcanIsr(ADMA__CAN1, s_flexcanHandle[FLEXCAN_GetInstance(ADMA__CAN1)]);
4580     SDK_ISR_EXIT_BARRIER;
4581 }
4582 #endif
4583 
4584 #if defined(ADMA__CAN2)
4585 void ADMA_FLEXCAN2_INT_DriverIRQHandler(void);
4586 void ADMA_FLEXCAN2_INT_DriverIRQHandler(void)
4587 {
4588     assert(NULL != s_flexcanHandle[FLEXCAN_GetInstance(ADMA__CAN2)]);
4589 
4590     s_flexcanIsr(ADMA__CAN2, s_flexcanHandle[FLEXCAN_GetInstance(ADMA__CAN2)]);
4591     SDK_ISR_EXIT_BARRIER;
4592 }
4593 #endif
4594 
4595 #if defined(FLEXCAN1)
4596 void CAN_FD1_DriverIRQHandler(void)
4597 {
4598     assert(NULL != s_flexcanHandle[1]);
4599 
4600     s_flexcanIsr(FLEXCAN1, s_flexcanHandle[1]);
4601     SDK_ISR_EXIT_BARRIER;
4602 }
4603 #endif
4604 
4605 #if defined(FLEXCAN2)
4606 void CAN_FD2_DriverIRQHandler(void)
4607 {
4608     assert(NULL != s_flexcanHandle[2]);
4609 
4610     s_flexcanIsr(FLEXCAN2, s_flexcanHandle[2]);
4611     SDK_ISR_EXIT_BARRIER;
4612 }
4613 #endif