Back to home page

LXR

 
 

    


File indexing completed on 2025-05-11 08:23:01

0001 /*
0002  * Copyright (c) 2016, Freescale Semiconductor, Inc.
0003  * Copyright 2016-2022 NXP
0004  * All rights reserved.
0005  *
0006  * SPDX-License-Identifier: BSD-3-Clause
0007  */
0008 
0009 #include "fsl_sai.h"
0010 
0011 /* Component ID definition, used by tools. */
0012 #ifndef FSL_COMPONENT_ID
0013 #define FSL_COMPONENT_ID "platform.drivers.sai"
0014 #endif
0015 
0016 /*******************************************************************************
0017  * Definitations
0018  ******************************************************************************/
0019 /*! @brief _sai_transfer_state sai transfer state.*/
0020 enum
0021 {
0022     kSAI_Busy = 0x0U, /*!< SAI is busy */
0023     kSAI_Idle,        /*!< Transfer is done. */
0024     kSAI_Error        /*!< Transfer error occurred. */
0025 };
0026 
0027 /*! @brief Typedef for sai tx interrupt handler. */
0028 typedef void (*sai_tx_isr_t)(I2S_Type *base, sai_handle_t *saiHandle);
0029 
0030 /*! @brief Typedef for sai rx interrupt handler. */
0031 typedef void (*sai_rx_isr_t)(I2S_Type *base, sai_handle_t *saiHandle);
0032 
0033 /*! @brief check flag avalibility */
0034 #define IS_SAI_FLAG_SET(reg, flag) (((reg) & ((uint32_t)flag)) != 0UL)
0035 /*******************************************************************************
0036  * Prototypes
0037  ******************************************************************************/
0038 /*!
0039  * @brief sai get rx enabled interrupt status.
0040  *
0041  *
0042  * @param base SAI base pointer.
0043  * @param enableFlag enable flag to check.
0044  * @param statusFlag status flag to check.
0045  */
0046 static bool SAI_RxGetEnabledInterruptStatus(I2S_Type *base, uint32_t enableFlag, uint32_t statusFlag);
0047 
0048 /*!
0049  * @brief sai get tx enabled interrupt status.
0050  *
0051  *
0052  * @param base SAI base pointer.
0053  * @param enableFlag enable flag to check.
0054  * @param statusFlag status flag to check.
0055  */
0056 static bool SAI_TxGetEnabledInterruptStatus(I2S_Type *base, uint32_t enableFlag, uint32_t statusFlag);
0057 
0058 /*!
0059  * @brief Set the master clock divider.
0060  *
0061  * This API will compute the master clock divider according to master clock frequency and master
0062  * clock source clock source frequency.
0063  *
0064  * @param base SAI base pointer.
0065  * @param mclk_Hz Mater clock frequency in Hz.
0066  * @param mclkSrcClock_Hz Master clock source frequency in Hz.
0067  */
0068 static bool SAI_TxGetEnabledInterruptStatus(I2S_Type *base, uint32_t enableFlag, uint32_t statusFlag);
0069 
0070 #if ((defined(FSL_FEATURE_SAI_HAS_MCLKDIV_REGISTER) && (FSL_FEATURE_SAI_HAS_MCLKDIV_REGISTER)) || \
0071      (defined(FSL_FEATURE_SAI_HAS_MCR_MCLK_POST_DIV) && (FSL_FEATURE_SAI_HAS_MCR_MCLK_POST_DIV)))
0072 
0073 /*!
0074  * @brief Set the master clock divider.
0075  *
0076  * This API will compute the master clock divider according to master clock frequency and master
0077  * clock source clock source frequency.
0078  *
0079  * @param base SAI base pointer.
0080  * @param mclk_Hz Mater clock frequency in Hz.
0081  * @param mclkSrcClock_Hz Master clock source frequency in Hz.
0082  */
0083 static void SAI_SetMasterClockDivider(I2S_Type *base, uint32_t mclk_Hz, uint32_t mclkSrcClock_Hz);
0084 #endif /* FSL_FEATURE_SAI_HAS_MCLKDIV_REGISTER */
0085 
0086 /*!
0087  * @brief Get the instance number for SAI.
0088  *
0089  * @param base SAI base pointer.
0090  */
0091 static uint32_t SAI_GetInstance(I2S_Type *base);
0092 
0093 /*!
0094  * @brief sends a piece of data in non-blocking way.
0095  *
0096  * @param base SAI base pointer
0097  * @param channel start channel number.
0098  * @param channelMask enabled channels mask.
0099  * @param endChannel end channel numbers.
0100  * @param bitWidth How many bits in a audio word, usually 8/16/24/32 bits.
0101  * @param buffer Pointer to the data to be written.
0102  * @param size Bytes to be written.
0103  */
0104 static void SAI_WriteNonBlocking(I2S_Type *base,
0105                                  uint32_t channel,
0106                                  uint32_t channelMask,
0107                                  uint32_t endChannel,
0108                                  uint8_t bitWidth,
0109                                  uint8_t *buffer,
0110                                  uint32_t size);
0111 
0112 /*!
0113  * @brief Receive a piece of data in non-blocking way.
0114  *
0115  * @param base SAI base pointer
0116  * @param channel start channel number.
0117  * @param channelMask enabled channels mask.
0118  * @param endChannel end channel numbers.
0119  * @param bitWidth How many bits in a audio word, usually 8/16/24/32 bits.
0120  * @param buffer Pointer to the data to be read.
0121  * @param size Bytes to be read.
0122  */
0123 static void SAI_ReadNonBlocking(I2S_Type *base,
0124                                 uint32_t channel,
0125                                 uint32_t channelMask,
0126                                 uint32_t endChannel,
0127                                 uint8_t bitWidth,
0128                                 uint8_t *buffer,
0129                                 uint32_t size);
0130 
0131 /*!
0132  * @brief Get classic I2S mode configurations.
0133  *
0134  * @param config transceiver configurations
0135  * @param bitWidth audio data bitWidth.
0136  * @param mode audio data channel
0137  * @param saiChannelMask channel mask value to enable
0138  */
0139 static void SAI_GetCommonConfig(sai_transceiver_t *config,
0140                                 sai_word_width_t bitWidth,
0141                                 sai_mono_stereo_t mode,
0142                                 uint32_t saiChannelMask);
0143 /*******************************************************************************
0144  * Variables
0145  ******************************************************************************/
0146 /* Base pointer array */
0147 static I2S_Type *const s_saiBases[] = I2S_BASE_PTRS;
0148 /*!@brief SAI handle pointer */
0149 static sai_handle_t *s_saiHandle[ARRAY_SIZE(s_saiBases)][2];
0150 /* IRQ number array */
0151 static const IRQn_Type s_saiTxIRQ[] = I2S_TX_IRQS;
0152 static const IRQn_Type s_saiRxIRQ[] = I2S_RX_IRQS;
0153 #if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
0154 /* Clock name array */
0155 static const clock_ip_name_t s_saiClock[] = SAI_CLOCKS;
0156 #endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */
0157 /*! @brief Pointer to tx IRQ handler for each instance. */
0158 static sai_tx_isr_t s_saiTxIsr;
0159 /*! @brief Pointer to tx IRQ handler for each instance. */
0160 static sai_rx_isr_t s_saiRxIsr;
0161 
0162 /*******************************************************************************
0163  * Code
0164  ******************************************************************************/
0165 static bool SAI_RxGetEnabledInterruptStatus(I2S_Type *base, uint32_t enableFlag, uint32_t statusFlag)
0166 {
0167     uint32_t rcsr = base->RCSR;
0168 
0169     return IS_SAI_FLAG_SET(rcsr, enableFlag) && IS_SAI_FLAG_SET(rcsr, statusFlag);
0170 }
0171 
0172 static bool SAI_TxGetEnabledInterruptStatus(I2S_Type *base, uint32_t enableFlag, uint32_t statusFlag)
0173 {
0174     uint32_t tcsr = base->TCSR;
0175 
0176     return IS_SAI_FLAG_SET(tcsr, enableFlag) && IS_SAI_FLAG_SET(tcsr, statusFlag);
0177 }
0178 
0179 #if ((defined(FSL_FEATURE_SAI_HAS_MCLKDIV_REGISTER) && (FSL_FEATURE_SAI_HAS_MCLKDIV_REGISTER)) || \
0180      (defined(FSL_FEATURE_SAI_HAS_MCR_MCLK_POST_DIV) && (FSL_FEATURE_SAI_HAS_MCR_MCLK_POST_DIV)))
0181 static void SAI_SetMasterClockDivider(I2S_Type *base, uint32_t mclk_Hz, uint32_t mclkSrcClock_Hz)
0182 {
0183     assert(mclk_Hz <= mclkSrcClock_Hz);
0184 
0185     uint32_t sourceFreq = mclkSrcClock_Hz / 100U; /*In order to prevent overflow */
0186     uint32_t targetFreq = mclk_Hz / 100U;         /*In order to prevent overflow */
0187 
0188 #if FSL_FEATURE_SAI_HAS_MCR_MCLK_POST_DIV
0189     uint32_t postDivider = sourceFreq / targetFreq;
0190 
0191     /* if source equal to target, then disable divider */
0192     if (postDivider == 1U)
0193     {
0194         base->MCR &= ~I2S_MCR_DIVEN_MASK;
0195     }
0196     else
0197     {
0198         base->MCR = (base->MCR & (~I2S_MCR_DIV_MASK)) | I2S_MCR_DIV(postDivider / 2U - 1U) | I2S_MCR_DIVEN_MASK;
0199     }
0200 #endif
0201 #if FSL_FEATURE_SAI_HAS_MCLKDIV_REGISTER
0202     uint16_t fract, divide;
0203     uint32_t remaind           = 0;
0204     uint32_t current_remainder = 0xFFFFFFFFU;
0205     uint16_t current_fract     = 0;
0206     uint16_t current_divide    = 0;
0207     uint32_t mul_freq          = 0;
0208     uint32_t max_fract         = 256;
0209 
0210     /* Compute the max fract number */
0211     max_fract = targetFreq * 4096U / sourceFreq + 1U;
0212     if (max_fract > 256U)
0213     {
0214         max_fract = 256U;
0215     }
0216 
0217     /* Looking for the closet frequency */
0218     for (fract = 1; fract < max_fract; fract++)
0219     {
0220         mul_freq = sourceFreq * fract;
0221         remaind  = mul_freq % targetFreq;
0222         divide   = (uint16_t)(mul_freq / targetFreq);
0223 
0224         /* Find the exactly frequency */
0225         if (remaind == 0U)
0226         {
0227             current_fract  = fract;
0228             current_divide = (uint16_t)(mul_freq / targetFreq);
0229             break;
0230         }
0231 
0232         /* Closer to next one, set the closest to next data */
0233         if (remaind > mclk_Hz / 2U)
0234         {
0235             remaind = targetFreq - remaind;
0236             divide += 1U;
0237         }
0238 
0239         /* Update the closest div and fract */
0240         if (remaind < current_remainder)
0241         {
0242             current_fract     = fract;
0243             current_divide    = divide;
0244             current_remainder = remaind;
0245         }
0246     }
0247 
0248     /* Fill the computed fract and divider to registers */
0249     base->MDR = I2S_MDR_DIVIDE(current_divide - 1UL) | I2S_MDR_FRACT(current_fract - 1UL);
0250 
0251     /* Waiting for the divider updated */
0252     while ((base->MCR & I2S_MCR_DUF_MASK) != 0UL)
0253     {
0254     }
0255 #endif
0256 }
0257 #endif /* FSL_FEATURE_SAI_HAS_MCLKDIV_REGISTER */
0258 
0259 static uint32_t SAI_GetInstance(I2S_Type *base)
0260 {
0261     uint32_t instance;
0262 
0263     /* Find the instance index from base address mappings. */
0264     for (instance = 0; instance < ARRAY_SIZE(s_saiBases); instance++)
0265     {
0266         if (s_saiBases[instance] == base)
0267         {
0268             break;
0269         }
0270     }
0271 
0272     assert(instance < ARRAY_SIZE(s_saiBases));
0273 
0274     return instance;
0275 }
0276 
0277 static void SAI_WriteNonBlocking(I2S_Type *base,
0278                                  uint32_t channel,
0279                                  uint32_t channelMask,
0280                                  uint32_t endChannel,
0281                                  uint8_t bitWidth,
0282                                  uint8_t *buffer,
0283                                  uint32_t size)
0284 {
0285     uint32_t i = 0, j = 0U;
0286     uint8_t m            = 0;
0287     uint8_t bytesPerWord = bitWidth / 8U;
0288     uint32_t data        = 0;
0289     uint32_t temp        = 0;
0290 
0291     for (i = 0; i < size / bytesPerWord; i++)
0292     {
0293         for (j = channel; j <= endChannel; j++)
0294         {
0295             if (IS_SAI_FLAG_SET((1UL << j), channelMask))
0296             {
0297                 for (m = 0; m < bytesPerWord; m++)
0298                 {
0299                     temp = (uint32_t)(*buffer);
0300                     data |= (temp << (8U * m));
0301                     buffer++;
0302                 }
0303                 base->TDR[j] = data;
0304                 data         = 0;
0305             }
0306         }
0307     }
0308 }
0309 
0310 static void SAI_ReadNonBlocking(I2S_Type *base,
0311                                 uint32_t channel,
0312                                 uint32_t channelMask,
0313                                 uint32_t endChannel,
0314                                 uint8_t bitWidth,
0315                                 uint8_t *buffer,
0316                                 uint32_t size)
0317 {
0318     uint32_t i = 0, j = 0;
0319     uint8_t m            = 0;
0320     uint8_t bytesPerWord = bitWidth / 8U;
0321     uint32_t data        = 0;
0322 
0323     for (i = 0; i < size / bytesPerWord; i++)
0324     {
0325         for (j = channel; j <= endChannel; j++)
0326         {
0327             if (IS_SAI_FLAG_SET((1UL << j), channelMask))
0328             {
0329                 data = base->RDR[j];
0330                 for (m = 0; m < bytesPerWord; m++)
0331                 {
0332                     *buffer = (uint8_t)(data >> (8U * m)) & 0xFFU;
0333                     buffer++;
0334                 }
0335             }
0336         }
0337     }
0338 }
0339 
0340 static void SAI_GetCommonConfig(sai_transceiver_t *config,
0341                                 sai_word_width_t bitWidth,
0342                                 sai_mono_stereo_t mode,
0343                                 uint32_t saiChannelMask)
0344 {
0345     assert(NULL != config);
0346     assert(saiChannelMask != 0U);
0347 
0348     (void)memset(config, 0, sizeof(sai_transceiver_t));
0349 
0350     config->channelMask = (uint8_t)saiChannelMask;
0351     /* sync mode default configurations */
0352     config->syncMode = kSAI_ModeAsync;
0353 
0354     /* master mode default */
0355     config->masterSlave = kSAI_Master;
0356 
0357     /* bit default configurations */
0358     config->bitClock.bclkSrcSwap    = false;
0359     config->bitClock.bclkInputDelay = false;
0360     config->bitClock.bclkPolarity   = kSAI_SampleOnRisingEdge;
0361     config->bitClock.bclkSource     = kSAI_BclkSourceMclkDiv;
0362 
0363     /* frame sync default configurations */
0364     config->frameSync.frameSyncWidth = (uint8_t)bitWidth;
0365     config->frameSync.frameSyncEarly = true;
0366 #if defined(FSL_FEATURE_SAI_HAS_ON_DEMAND_MODE) && FSL_FEATURE_SAI_HAS_ON_DEMAND_MODE
0367     config->frameSync.frameSyncGenerateOnDemand = false;
0368 #endif
0369     config->frameSync.frameSyncPolarity = kSAI_PolarityActiveLow;
0370 
0371     /* serial data default configurations */
0372 #if defined(FSL_FEATURE_SAI_HAS_CHANNEL_MODE) && FSL_FEATURE_SAI_HAS_CHANNEL_MODE
0373     config->serialData.dataMode = kSAI_DataPinStateOutputZero;
0374 #endif
0375     config->serialData.dataOrder           = kSAI_DataMSB;
0376     config->serialData.dataWord0Length     = (uint8_t)bitWidth;
0377     config->serialData.dataWordLength      = (uint8_t)bitWidth;
0378     config->serialData.dataWordNLength     = (uint8_t)bitWidth;
0379     config->serialData.dataFirstBitShifted = (uint8_t)bitWidth;
0380     config->serialData.dataWordNum         = 2U;
0381     config->serialData.dataMaskedWord      = (uint32_t)mode;
0382 
0383 #if defined(FSL_FEATURE_SAI_HAS_FIFO_FUNCTION_AFTER_ERROR) && FSL_FEATURE_SAI_HAS_FIFO_FUNCTION_AFTER_ERROR
0384     config->fifo.fifoContinueOneError = true;
0385 #endif
0386 }
0387 
0388 /*!
0389  * brief Initializes the SAI Tx peripheral.
0390  *
0391  * deprecated Do not use this function.  It has been superceded by @ref SAI_Init
0392  *
0393  * Ungates the SAI clock, resets the module, and configures SAI Tx with a configuration structure.
0394  * The configuration structure can be custom filled or set with default values by
0395  * SAI_TxGetDefaultConfig().
0396  *
0397  * note  This API should be called at the beginning of the application to use
0398  * the SAI driver. Otherwise, accessing the SAIM module can cause a hard fault
0399  * because the clock is not enabled.
0400  *
0401  * param base SAI base pointer
0402  * param config SAI configuration structure.
0403  */
0404 void SAI_TxInit(I2S_Type *base, const sai_config_t *config)
0405 {
0406     uint32_t val = 0;
0407 
0408 #if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
0409     /* Enable the SAI clock */
0410     (void)CLOCK_EnableClock(s_saiClock[SAI_GetInstance(base)]);
0411 #endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */
0412 
0413 #if defined(FSL_FEATURE_SAI_HAS_MCR) && (FSL_FEATURE_SAI_HAS_MCR)
0414 #if !(defined(FSL_FEATURE_SAI_HAS_NO_MCR_MICS) && (FSL_FEATURE_SAI_HAS_NO_MCR_MICS))
0415     /* Master clock source setting */
0416     val       = (base->MCR & ~I2S_MCR_MICS_MASK);
0417     base->MCR = (val | I2S_MCR_MICS(config->mclkSource));
0418 #endif
0419 
0420     /* Configure Master clock output enable */
0421     val       = (base->MCR & ~I2S_MCR_MOE_MASK);
0422     base->MCR = (val | I2S_MCR_MOE(config->mclkOutputEnable));
0423 #endif /* FSL_FEATURE_SAI_HAS_MCR */
0424 
0425     SAI_TxReset(base);
0426 
0427     /* Configure audio protocol */
0428     if (config->protocol == kSAI_BusLeftJustified)
0429     {
0430         base->TCR2 |= I2S_TCR2_BCP_MASK;
0431         base->TCR3 &= ~I2S_TCR3_WDFL_MASK;
0432         base->TCR4 = I2S_TCR4_MF(1U) | I2S_TCR4_SYWD(31U) | I2S_TCR4_FSE(0U) | I2S_TCR4_FSP(0U) | I2S_TCR4_FRSZ(1U);
0433     }
0434     else if (config->protocol == kSAI_BusRightJustified)
0435     {
0436         base->TCR2 |= I2S_TCR2_BCP_MASK;
0437         base->TCR3 &= ~I2S_TCR3_WDFL_MASK;
0438         base->TCR4 = I2S_TCR4_MF(1U) | I2S_TCR4_SYWD(31U) | I2S_TCR4_FSE(0U) | I2S_TCR4_FSP(0U) | I2S_TCR4_FRSZ(1U);
0439     }
0440     else if (config->protocol == kSAI_BusI2S)
0441     {
0442         base->TCR2 |= I2S_TCR2_BCP_MASK;
0443         base->TCR3 &= ~I2S_TCR3_WDFL_MASK;
0444         base->TCR4 = I2S_TCR4_MF(1U) | I2S_TCR4_SYWD(31U) | I2S_TCR4_FSE(1U) | I2S_TCR4_FSP(1U) | I2S_TCR4_FRSZ(1U);
0445     }
0446     else if (config->protocol == kSAI_BusPCMA)
0447     {
0448         base->TCR2 &= ~I2S_TCR2_BCP_MASK;
0449         base->TCR3 &= ~I2S_TCR3_WDFL_MASK;
0450         base->TCR4 = I2S_TCR4_MF(1U) | I2S_TCR4_SYWD(0U) | I2S_TCR4_FSE(1U) | I2S_TCR4_FSP(0U) | I2S_TCR4_FRSZ(1U);
0451     }
0452     else
0453     {
0454         base->TCR2 &= ~I2S_TCR2_BCP_MASK;
0455         base->TCR3 &= ~I2S_TCR3_WDFL_MASK;
0456         base->TCR4 = I2S_TCR4_MF(1U) | I2S_TCR4_SYWD(0U) | I2S_TCR4_FSE(0U) | I2S_TCR4_FSP(0U) | I2S_TCR4_FRSZ(1U);
0457     }
0458 
0459     /* Set master or slave */
0460     if (config->masterSlave == kSAI_Master)
0461     {
0462         base->TCR2 |= I2S_TCR2_BCD_MASK;
0463         base->TCR4 |= I2S_TCR4_FSD_MASK;
0464 
0465         /* Bit clock source setting */
0466         val        = base->TCR2 & (~I2S_TCR2_MSEL_MASK);
0467         base->TCR2 = (val | I2S_TCR2_MSEL(config->bclkSource));
0468     }
0469     else
0470     {
0471         base->TCR2 &= ~I2S_TCR2_BCD_MASK;
0472         base->TCR4 &= ~I2S_TCR4_FSD_MASK;
0473     }
0474 
0475     /* Set Sync mode */
0476     if (config->syncMode == kSAI_ModeAsync)
0477     {
0478         val = base->TCR2;
0479         val &= ~I2S_TCR2_SYNC_MASK;
0480         base->TCR2 = (val | I2S_TCR2_SYNC(0U));
0481     }
0482     if (config->syncMode == kSAI_ModeSync)
0483     {
0484         val = base->TCR2;
0485         val &= ~I2S_TCR2_SYNC_MASK;
0486         base->TCR2 = (val | I2S_TCR2_SYNC(1U));
0487         /* If sync with Rx, should set Rx to async mode */
0488         val = base->RCR2;
0489         val &= ~I2S_RCR2_SYNC_MASK;
0490         base->RCR2 = (val | I2S_RCR2_SYNC(0U));
0491     }
0492 #if defined(FSL_FEATURE_SAI_HAS_SYNC_WITH_ANOTHER_SAI) && (FSL_FEATURE_SAI_HAS_SYNC_WITH_ANOTHER_SAI)
0493     if (config->syncMode == kSAI_ModeSyncWithOtherTx)
0494     {
0495         val = base->TCR2;
0496         val &= ~I2S_TCR2_SYNC_MASK;
0497         base->TCR2 = (val | I2S_TCR2_SYNC(2U));
0498     }
0499     if (config->syncMode == kSAI_ModeSyncWithOtherRx)
0500     {
0501         val = base->TCR2;
0502         val &= ~I2S_TCR2_SYNC_MASK;
0503         base->TCR2 = (val | I2S_TCR2_SYNC(3U));
0504     }
0505 #endif /* FSL_FEATURE_SAI_HAS_SYNC_WITH_ANOTHER_SAI */
0506 
0507 #if defined(FSL_FEATURE_SAI_HAS_FIFO_FUNCTION_AFTER_ERROR) && FSL_FEATURE_SAI_HAS_FIFO_FUNCTION_AFTER_ERROR
0508     SAI_TxSetFIFOErrorContinue(base, true);
0509 #endif /* FSL_FEATURE_SAI_HAS_FIFO_FUNCTION_AFTER_ERROR */
0510 }
0511 
0512 /*!
0513  * brief Initializes the SAI Rx peripheral.
0514  *
0515  * deprecated Do not use this function.  It has been superceded by @ref SAI_Init
0516  *
0517  * Ungates the SAI clock, resets the module, and configures the SAI Rx with a configuration structure.
0518  * The configuration structure can be custom filled or set with default values by
0519  * SAI_RxGetDefaultConfig().
0520  *
0521  * note  This API should be called at the beginning of the application to use
0522  * the SAI driver. Otherwise, accessing the SAI module can cause a hard fault
0523  * because the clock is not enabled.
0524  *
0525  * param base SAI base pointer
0526  * param config SAI configuration structure.
0527  */
0528 void SAI_RxInit(I2S_Type *base, const sai_config_t *config)
0529 {
0530     uint32_t val = 0;
0531 
0532 #if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
0533     /* Enable SAI clock first. */
0534     (void)CLOCK_EnableClock(s_saiClock[SAI_GetInstance(base)]);
0535 #endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */
0536 
0537 #if defined(FSL_FEATURE_SAI_HAS_MCR) && (FSL_FEATURE_SAI_HAS_MCR)
0538 #if !(defined(FSL_FEATURE_SAI_HAS_NO_MCR_MICS) && (FSL_FEATURE_SAI_HAS_NO_MCR_MICS))
0539     /* Master clock source setting */
0540     val       = (base->MCR & ~I2S_MCR_MICS_MASK);
0541     base->MCR = (val | I2S_MCR_MICS(config->mclkSource));
0542 #endif
0543 
0544     /* Configure Master clock output enable */
0545     val       = (base->MCR & ~I2S_MCR_MOE_MASK);
0546     base->MCR = (val | I2S_MCR_MOE(config->mclkOutputEnable));
0547 #endif /* FSL_FEATURE_SAI_HAS_MCR */
0548 
0549     SAI_RxReset(base);
0550 
0551     /* Configure audio protocol */
0552     if (config->protocol == kSAI_BusLeftJustified)
0553     {
0554         base->RCR2 |= I2S_RCR2_BCP_MASK;
0555         base->RCR3 &= ~I2S_RCR3_WDFL_MASK;
0556         base->RCR4 = I2S_RCR4_MF(1U) | I2S_RCR4_SYWD(31U) | I2S_RCR4_FSE(0U) | I2S_RCR4_FSP(0U) | I2S_RCR4_FRSZ(1U);
0557     }
0558     else if (config->protocol == kSAI_BusRightJustified)
0559     {
0560         base->RCR2 |= I2S_RCR2_BCP_MASK;
0561         base->RCR3 &= ~I2S_RCR3_WDFL_MASK;
0562         base->RCR4 = I2S_RCR4_MF(1U) | I2S_RCR4_SYWD(31U) | I2S_RCR4_FSE(0U) | I2S_RCR4_FSP(0U) | I2S_RCR4_FRSZ(1U);
0563     }
0564     else if (config->protocol == kSAI_BusI2S)
0565     {
0566         base->RCR2 |= I2S_RCR2_BCP_MASK;
0567         base->RCR3 &= ~I2S_RCR3_WDFL_MASK;
0568         base->RCR4 = I2S_RCR4_MF(1U) | I2S_RCR4_SYWD(31U) | I2S_RCR4_FSE(1U) | I2S_RCR4_FSP(1U) | I2S_RCR4_FRSZ(1U);
0569     }
0570     else if (config->protocol == kSAI_BusPCMA)
0571     {
0572         base->RCR2 &= ~I2S_RCR2_BCP_MASK;
0573         base->RCR3 &= ~I2S_RCR3_WDFL_MASK;
0574         base->RCR4 = I2S_RCR4_MF(1U) | I2S_RCR4_SYWD(0U) | I2S_RCR4_FSE(1U) | I2S_RCR4_FSP(0U) | I2S_RCR4_FRSZ(1U);
0575     }
0576     else
0577     {
0578         base->RCR2 &= ~I2S_RCR2_BCP_MASK;
0579         base->RCR3 &= ~I2S_RCR3_WDFL_MASK;
0580         base->RCR4 = I2S_RCR4_MF(1U) | I2S_RCR4_SYWD(0U) | I2S_RCR4_FSE(0U) | I2S_RCR4_FSP(0U) | I2S_RCR4_FRSZ(1U);
0581     }
0582 
0583     /* Set master or slave */
0584     if (config->masterSlave == kSAI_Master)
0585     {
0586         base->RCR2 |= I2S_RCR2_BCD_MASK;
0587         base->RCR4 |= I2S_RCR4_FSD_MASK;
0588 
0589         /* Bit clock source setting */
0590         val        = base->RCR2 & (~I2S_RCR2_MSEL_MASK);
0591         base->RCR2 = (val | I2S_RCR2_MSEL(config->bclkSource));
0592     }
0593     else
0594     {
0595         base->RCR2 &= ~I2S_RCR2_BCD_MASK;
0596         base->RCR4 &= ~I2S_RCR4_FSD_MASK;
0597     }
0598 
0599     /* Set Sync mode */
0600     if (config->syncMode == kSAI_ModeAsync)
0601     {
0602         val = base->RCR2;
0603         val &= ~I2S_RCR2_SYNC_MASK;
0604         base->RCR2 = (val | I2S_RCR2_SYNC(0U));
0605     }
0606     if (config->syncMode == kSAI_ModeSync)
0607     {
0608         val = base->RCR2;
0609         val &= ~I2S_RCR2_SYNC_MASK;
0610         base->RCR2 = (val | I2S_RCR2_SYNC(1U));
0611         /* If sync with Tx, should set Tx to async mode */
0612         val = base->TCR2;
0613         val &= ~I2S_TCR2_SYNC_MASK;
0614         base->TCR2 = (val | I2S_TCR2_SYNC(0U));
0615     }
0616 #if defined(FSL_FEATURE_SAI_HAS_SYNC_WITH_ANOTHER_SAI) && (FSL_FEATURE_SAI_HAS_SYNC_WITH_ANOTHER_SAI)
0617     if (config->syncMode == kSAI_ModeSyncWithOtherTx)
0618     {
0619         val = base->RCR2;
0620         val &= ~I2S_RCR2_SYNC_MASK;
0621         base->RCR2 = (val | I2S_RCR2_SYNC(2U));
0622     }
0623     if (config->syncMode == kSAI_ModeSyncWithOtherRx)
0624     {
0625         val = base->RCR2;
0626         val &= ~I2S_RCR2_SYNC_MASK;
0627         base->RCR2 = (val | I2S_RCR2_SYNC(3U));
0628     }
0629 #endif /* FSL_FEATURE_SAI_HAS_SYNC_WITH_ANOTHER_SAI */
0630 
0631 #if defined(FSL_FEATURE_SAI_HAS_FIFO_FUNCTION_AFTER_ERROR) && FSL_FEATURE_SAI_HAS_FIFO_FUNCTION_AFTER_ERROR
0632     SAI_RxSetFIFOErrorContinue(base, true);
0633 #endif /* FSL_FEATURE_SAI_HAS_FIFO_FUNCTION_AFTER_ERROR */
0634 }
0635 
0636 /*!
0637  * brief Initializes the SAI peripheral.
0638  *
0639  * This API gates the SAI clock. The SAI module can't operate unless SAI_Init is called to enable the clock.
0640  *
0641  * param base SAI base pointer
0642  */
0643 void SAI_Init(I2S_Type *base)
0644 {
0645 #if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
0646     /* Enable the SAI clock */
0647     (void)CLOCK_EnableClock(s_saiClock[SAI_GetInstance(base)]);
0648 #endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */
0649 
0650 #if defined(FSL_FEATURE_SAI_HAS_FIFO) && (FSL_FEATURE_SAI_HAS_FIFO)
0651     /* disable interrupt and DMA request*/
0652     base->TCSR &=
0653         ~(I2S_TCSR_FRIE_MASK | I2S_TCSR_FWIE_MASK | I2S_TCSR_FEIE_MASK | I2S_TCSR_FRDE_MASK | I2S_TCSR_FWDE_MASK);
0654     base->RCSR &=
0655         ~(I2S_RCSR_FRIE_MASK | I2S_RCSR_FWIE_MASK | I2S_RCSR_FEIE_MASK | I2S_RCSR_FRDE_MASK | I2S_RCSR_FWDE_MASK);
0656 #else
0657     /* disable interrupt and DMA request*/
0658     base->TCSR &= ~(I2S_TCSR_FWIE_MASK | I2S_TCSR_FEIE_MASK | I2S_TCSR_FWDE_MASK);
0659     base->RCSR &= ~(I2S_RCSR_FWIE_MASK | I2S_RCSR_FEIE_MASK | I2S_RCSR_FWDE_MASK);
0660 #endif
0661 }
0662 
0663 /*!
0664  * brief De-initializes the SAI peripheral.
0665  *
0666  * This API gates the SAI clock. The SAI module can't operate unless SAI_TxInit
0667  * or SAI_RxInit is called to enable the clock.
0668  *
0669  * param base SAI base pointer
0670  */
0671 void SAI_Deinit(I2S_Type *base)
0672 {
0673     SAI_TxEnable(base, false);
0674     SAI_RxEnable(base, false);
0675 #if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
0676     (void)CLOCK_DisableClock(s_saiClock[SAI_GetInstance(base)]);
0677 #endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */
0678 }
0679 
0680 /*!
0681  * brief  Sets the SAI Tx configuration structure to default values.
0682  *
0683  * deprecated Do not use this function.  It has been superceded by @ref
0684  * SAI_GetClassicI2SConfig, SAI_GetLeftJustifiedConfig,SAI_GetRightJustifiedConfig, SAI_GetDSPConfig,SAI_GetTDMConfig
0685  *
0686  * This API initializes the configuration structure for use in SAI_TxConfig().
0687  * The initialized structure can remain unchanged in SAI_TxConfig(), or it can be modified
0688  *  before calling SAI_TxConfig().
0689  * This is an example.
0690    code
0691    sai_config_t config;
0692    SAI_TxGetDefaultConfig(&config);
0693    endcode
0694  *
0695  * param config pointer to master configuration structure
0696  */
0697 void SAI_TxGetDefaultConfig(sai_config_t *config)
0698 {
0699     /* Initializes the configure structure to zero. */
0700     (void)memset(config, 0, sizeof(*config));
0701 
0702     config->bclkSource  = kSAI_BclkSourceMclkDiv;
0703     config->masterSlave = kSAI_Master;
0704 #if defined(FSL_FEATURE_SAI_HAS_MCR) && (FSL_FEATURE_SAI_HAS_MCR)
0705     config->mclkOutputEnable = true;
0706 #if !(defined(FSL_FEATURE_SAI_HAS_NO_MCR_MICS) && (FSL_FEATURE_SAI_HAS_NO_MCR_MICS))
0707     config->mclkSource = kSAI_MclkSourceSysclk;
0708 #endif
0709 #endif /* FSL_FEATURE_SAI_HAS_MCR */
0710     config->protocol = kSAI_BusI2S;
0711     config->syncMode = kSAI_ModeAsync;
0712 }
0713 
0714 /*!
0715  * brief  Sets the SAI Rx configuration structure to default values.
0716  *
0717  * deprecated Do not use this function.  It has been superceded by @ref
0718  * SAI_GetClassicI2SConfig,SAI_GetLeftJustifiedConfig,SAI_GetRightJustifiedConfig,SAI_GetDSPConfig,SAI_GetTDMConfig
0719  *
0720  * This API initializes the configuration structure for use in SAI_RxConfig().
0721  * The initialized structure can remain unchanged in SAI_RxConfig() or it can be modified
0722  *  before calling SAI_RxConfig().
0723  * This is an example.
0724    code
0725    sai_config_t config;
0726    SAI_RxGetDefaultConfig(&config);
0727    endcode
0728  *
0729  * param config pointer to master configuration structure
0730  */
0731 void SAI_RxGetDefaultConfig(sai_config_t *config)
0732 {
0733     /* Initializes the configure structure to zero. */
0734     (void)memset(config, 0, sizeof(*config));
0735 
0736     config->bclkSource  = kSAI_BclkSourceMclkDiv;
0737     config->masterSlave = kSAI_Master;
0738 #if defined(FSL_FEATURE_SAI_HAS_MCR) && (FSL_FEATURE_SAI_HAS_MCR)
0739     config->mclkOutputEnable = true;
0740 #if !(defined(FSL_FEATURE_SAI_HAS_NO_MCR_MICS) && (FSL_FEATURE_SAI_HAS_NO_MCR_MICS))
0741     config->mclkSource = kSAI_MclkSourceSysclk;
0742 #endif
0743 #endif /* FSL_FEATURE_SAI_HAS_MCR */
0744     config->protocol = kSAI_BusI2S;
0745     config->syncMode = kSAI_ModeSync;
0746 }
0747 
0748 /*!
0749  * brief Resets the SAI Tx.
0750  *
0751  * This function enables the software reset and FIFO reset of SAI Tx. After reset, clear the reset bit.
0752  *
0753  * param base SAI base pointer
0754  */
0755 void SAI_TxReset(I2S_Type *base)
0756 {
0757     /* Set the software reset and FIFO reset to clear internal state */
0758     base->TCSR = I2S_TCSR_SR_MASK | I2S_TCSR_FR_MASK;
0759 
0760     /* Clear software reset bit, this should be done by software */
0761     base->TCSR &= ~I2S_TCSR_SR_MASK;
0762 
0763     /* Reset all Tx register values */
0764     base->TCR2 = 0;
0765     base->TCR3 = 0;
0766     base->TCR4 = 0;
0767     base->TCR5 = 0;
0768     base->TMR  = 0;
0769 }
0770 
0771 /*!
0772  * brief Resets the SAI Rx.
0773  *
0774  * This function enables the software reset and FIFO reset of SAI Rx. After reset, clear the reset bit.
0775  *
0776  * param base SAI base pointer
0777  */
0778 void SAI_RxReset(I2S_Type *base)
0779 {
0780     /* Set the software reset and FIFO reset to clear internal state */
0781     base->RCSR = I2S_RCSR_SR_MASK | I2S_RCSR_FR_MASK;
0782 
0783     /* Clear software reset bit, this should be done by software */
0784     base->RCSR &= ~I2S_RCSR_SR_MASK;
0785 
0786     /* Reset all Rx register values */
0787     base->RCR2 = 0;
0788     base->RCR3 = 0;
0789     base->RCR4 = 0;
0790     base->RCR5 = 0;
0791     base->RMR  = 0;
0792 }
0793 
0794 /*!
0795  * brief Enables/disables the SAI Tx.
0796  *
0797  * param base SAI base pointer
0798  * param enable True means enable SAI Tx, false means disable.
0799  */
0800 void SAI_TxEnable(I2S_Type *base, bool enable)
0801 {
0802     if (enable)
0803     {
0804         /* If clock is sync with Rx, should enable RE bit. */
0805         if (((base->TCR2 & I2S_TCR2_SYNC_MASK) >> I2S_TCR2_SYNC_SHIFT) == 0x1U)
0806         {
0807             base->RCSR = ((base->RCSR & 0xFFE3FFFFU) | I2S_RCSR_RE_MASK);
0808         }
0809         base->TCSR = ((base->TCSR & 0xFFE3FFFFU) | I2S_TCSR_TE_MASK);
0810         /* Also need to clear the FIFO error flag before start */
0811         SAI_TxClearStatusFlags(base, kSAI_FIFOErrorFlag);
0812     }
0813     else
0814     {
0815         /* If Rx not in sync with Tx, then disable Tx, otherwise, shall not disable Tx */
0816         if (((base->RCR2 & I2S_RCR2_SYNC_MASK) >> I2S_RCR2_SYNC_SHIFT) != 0x1U)
0817         {
0818             /* Disable TE bit */
0819             base->TCSR = ((base->TCSR & 0xFFE3FFFFU) & (~I2S_TCSR_TE_MASK));
0820         }
0821     }
0822 }
0823 
0824 /*!
0825  * brief Enables/disables the SAI Rx.
0826  *
0827  * param base SAI base pointer
0828  * param enable True means enable SAI Rx, false means disable.
0829  */
0830 void SAI_RxEnable(I2S_Type *base, bool enable)
0831 {
0832     if (enable)
0833     {
0834         /* If clock is sync with Tx, should enable TE bit. */
0835         if (((base->RCR2 & I2S_RCR2_SYNC_MASK) >> I2S_RCR2_SYNC_SHIFT) == 0x1U)
0836         {
0837             base->TCSR = ((base->TCSR & 0xFFE3FFFFU) | I2S_TCSR_TE_MASK);
0838         }
0839         base->RCSR = ((base->RCSR & 0xFFE3FFFFU) | I2S_RCSR_RE_MASK);
0840         /* Also need to clear the FIFO error flag before start */
0841         SAI_RxClearStatusFlags(base, kSAI_FIFOErrorFlag);
0842     }
0843     else
0844     {
0845         /* If Tx not in sync with Rx, then disable Rx, otherwise, shall not disable Rx */
0846         if (((base->TCR2 & I2S_TCR2_SYNC_MASK) >> I2S_TCR2_SYNC_SHIFT) != 0x1U)
0847         {
0848             /* Disable RE bit */
0849             base->RCSR = ((base->RCSR & 0xFFE3FFFFU) & (~I2S_RCSR_RE_MASK));
0850         }
0851     }
0852 }
0853 
0854 /*!
0855  * brief Do software reset or FIFO reset .
0856  *
0857  * FIFO reset means clear all the data in the FIFO, and make the FIFO pointer both to 0.
0858  * Software reset means clear the Tx internal logic, including the bit clock, frame count etc. But software
0859  * reset will not clear any configuration registers like TCR1~TCR5.
0860  * This function will also clear all the error flags such as FIFO error, sync error etc.
0861  *
0862  * param base SAI base pointer
0863  * param resetType Reset type, FIFO reset or software reset
0864  */
0865 void SAI_TxSoftwareReset(I2S_Type *base, sai_reset_type_t resetType)
0866 {
0867     base->TCSR |= (uint32_t)resetType;
0868 
0869     /* Clear the software reset */
0870     base->TCSR &= ~I2S_TCSR_SR_MASK;
0871 }
0872 
0873 /*!
0874  * brief Do software reset or FIFO reset .
0875  *
0876  * FIFO reset means clear all the data in the FIFO, and make the FIFO pointer both to 0.
0877  * Software reset means clear the Rx internal logic, including the bit clock, frame count etc. But software
0878  * reset will not clear any configuration registers like RCR1~RCR5.
0879  * This function will also clear all the error flags such as FIFO error, sync error etc.
0880  *
0881  * param base SAI base pointer
0882  * param resetType Reset type, FIFO reset or software reset
0883  */
0884 void SAI_RxSoftwareReset(I2S_Type *base, sai_reset_type_t resetType)
0885 {
0886     base->RCSR |= (uint32_t)resetType;
0887 
0888     /* Clear the software reset */
0889     base->RCSR &= ~I2S_RCSR_SR_MASK;
0890 }
0891 
0892 /*!
0893  * brief Set the Tx channel FIFO enable mask.
0894  *
0895  * param base SAI base pointer
0896  * param mask Channel enable mask, 0 means all channel FIFO disabled, 1 means channel 0 enabled,
0897  * 3 means both channel 0 and channel 1 enabled.
0898  */
0899 void SAI_TxSetChannelFIFOMask(I2S_Type *base, uint8_t mask)
0900 {
0901     base->TCR3 &= ~I2S_TCR3_TCE_MASK;
0902     base->TCR3 |= I2S_TCR3_TCE(mask);
0903 }
0904 
0905 /*!
0906  * brief Set the Rx channel FIFO enable mask.
0907  *
0908  * param base SAI base pointer
0909  * param mask Channel enable mask, 0 means all channel FIFO disabled, 1 means channel 0 enabled,
0910  * 3 means both channel 0 and channel 1 enabled.
0911  */
0912 void SAI_RxSetChannelFIFOMask(I2S_Type *base, uint8_t mask)
0913 {
0914     base->RCR3 &= ~I2S_RCR3_RCE_MASK;
0915     base->RCR3 |= I2S_RCR3_RCE(mask);
0916 }
0917 
0918 /*!
0919  * brief Set the Tx data order.
0920  *
0921  * param base SAI base pointer
0922  * param order Data order MSB or LSB
0923  */
0924 void SAI_TxSetDataOrder(I2S_Type *base, sai_data_order_t order)
0925 {
0926     uint32_t val = (base->TCR4) & (~I2S_TCR4_MF_MASK);
0927 
0928     val |= I2S_TCR4_MF(order);
0929     base->TCR4 = val;
0930 }
0931 
0932 /*!
0933  * brief Set the Rx data order.
0934  *
0935  * param base SAI base pointer
0936  * param order Data order MSB or LSB
0937  */
0938 void SAI_RxSetDataOrder(I2S_Type *base, sai_data_order_t order)
0939 {
0940     uint32_t val = (base->RCR4) & (~I2S_RCR4_MF_MASK);
0941 
0942     val |= I2S_RCR4_MF(order);
0943     base->RCR4 = val;
0944 }
0945 
0946 /*!
0947  * brief Set the Tx data order.
0948  *
0949  * param base SAI base pointer
0950  * param order Data order MSB or LSB
0951  */
0952 void SAI_TxSetBitClockPolarity(I2S_Type *base, sai_clock_polarity_t polarity)
0953 {
0954     uint32_t val = (base->TCR2) & (~I2S_TCR2_BCP_MASK);
0955 
0956     val |= I2S_TCR2_BCP(polarity);
0957     base->TCR2 = val;
0958 }
0959 
0960 /*!
0961  * brief Set the Rx data order.
0962  *
0963  * param base SAI base pointer
0964  * param order Data order MSB or LSB
0965  */
0966 void SAI_RxSetBitClockPolarity(I2S_Type *base, sai_clock_polarity_t polarity)
0967 {
0968     uint32_t val = (base->RCR2) & (~I2S_RCR2_BCP_MASK);
0969 
0970     val |= I2S_RCR2_BCP(polarity);
0971     base->RCR2 = val;
0972 }
0973 
0974 /*!
0975  * brief Set the Tx data order.
0976  *
0977  * param base SAI base pointer
0978  * param order Data order MSB or LSB
0979  */
0980 void SAI_TxSetFrameSyncPolarity(I2S_Type *base, sai_clock_polarity_t polarity)
0981 {
0982     uint32_t val = (base->TCR4) & (~I2S_TCR4_FSP_MASK);
0983 
0984     val |= I2S_TCR4_FSP(polarity);
0985     base->TCR4 = val;
0986 }
0987 
0988 /*!
0989  * brief Set the Rx data order.
0990  *
0991  * param base SAI base pointer
0992  * param order Data order MSB or LSB
0993  */
0994 void SAI_RxSetFrameSyncPolarity(I2S_Type *base, sai_clock_polarity_t polarity)
0995 {
0996     uint32_t val = (base->RCR4) & (~I2S_RCR4_FSP_MASK);
0997 
0998     val |= I2S_RCR4_FSP(polarity);
0999     base->RCR4 = val;
1000 }
1001 
1002 #if defined(FSL_FEATURE_SAI_HAS_FIFO_PACKING) && FSL_FEATURE_SAI_HAS_FIFO_PACKING
1003 /*!
1004  * brief Set Tx FIFO packing feature.
1005  *
1006  * param base SAI base pointer.
1007  * param pack FIFO pack type. It is element of sai_fifo_packing_t.
1008  */
1009 void SAI_TxSetFIFOPacking(I2S_Type *base, sai_fifo_packing_t pack)
1010 {
1011     uint32_t val = base->TCR4;
1012 
1013     val &= ~I2S_TCR4_FPACK_MASK;
1014     val |= I2S_TCR4_FPACK(pack);
1015     base->TCR4 = val;
1016 }
1017 
1018 /*!
1019  * brief Set Rx FIFO packing feature.
1020  *
1021  * param base SAI base pointer.
1022  * param pack FIFO pack type. It is element of sai_fifo_packing_t.
1023  */
1024 void SAI_RxSetFIFOPacking(I2S_Type *base, sai_fifo_packing_t pack)
1025 {
1026     uint32_t val = base->RCR4;
1027 
1028     val &= ~I2S_RCR4_FPACK_MASK;
1029     val |= I2S_RCR4_FPACK(pack);
1030     base->RCR4 = val;
1031 }
1032 #endif /* FSL_FEATURE_SAI_HAS_FIFO_PACKING */
1033 
1034 /*!
1035  * brief Transmitter bit clock rate configurations.
1036  *
1037  * param base SAI base pointer.
1038  * param sourceClockHz, bit clock source frequency.
1039  * param sampleRate audio data sample rate.
1040  * param bitWidth, audio data bitWidth.
1041  * param channelNumbers, audio channel numbers.
1042  */
1043 void SAI_TxSetBitClockRate(
1044     I2S_Type *base, uint32_t sourceClockHz, uint32_t sampleRate, uint32_t bitWidth, uint32_t channelNumbers)
1045 {
1046     uint32_t tcr2         = base->TCR2;
1047     uint32_t bitClockDiv  = 0;
1048     uint32_t bitClockFreq = sampleRate * bitWidth * channelNumbers;
1049 
1050     assert(sourceClockHz >= bitClockFreq);
1051 
1052     tcr2 &= ~I2S_TCR2_DIV_MASK;
1053     /* need to check the divided bclk, if bigger than target, then divider need to re-calculate. */
1054     bitClockDiv = sourceClockHz / bitClockFreq;
1055     /* for the condition where the source clock is smaller than target bclk */
1056     if (bitClockDiv == 0U)
1057     {
1058         bitClockDiv++;
1059     }
1060     /* recheck the divider if properly or not, to make sure output blck not bigger than target*/
1061     if ((sourceClockHz / bitClockDiv) > bitClockFreq)
1062     {
1063         bitClockDiv++;
1064     }
1065 
1066 #if defined(FSL_FEATURE_SAI_HAS_BCLK_BYPASS) && (FSL_FEATURE_SAI_HAS_BCLK_BYPASS)
1067     /* if bclk same with MCLK, bypass the divider */
1068     if (bitClockDiv == 1U)
1069     {
1070         tcr2 |= I2S_TCR2_BYP_MASK;
1071     }
1072     else
1073 #endif
1074     {
1075         tcr2 |= I2S_TCR2_DIV(bitClockDiv / 2U - 1UL);
1076     }
1077 
1078     base->TCR2 = tcr2;
1079 }
1080 
1081 /*!
1082  * brief Receiver bit clock rate configurations.
1083  *
1084  * param base SAI base pointer.
1085  * param sourceClockHz, bit clock source frequency.
1086  * param sampleRate audio data sample rate.
1087  * param bitWidth, audio data bitWidth.
1088  * param channelNumbers, audio channel numbers.
1089  */
1090 void SAI_RxSetBitClockRate(
1091     I2S_Type *base, uint32_t sourceClockHz, uint32_t sampleRate, uint32_t bitWidth, uint32_t channelNumbers)
1092 {
1093     uint32_t rcr2         = base->RCR2;
1094     uint32_t bitClockDiv  = 0;
1095     uint32_t bitClockFreq = sampleRate * bitWidth * channelNumbers;
1096 
1097     assert(sourceClockHz >= bitClockFreq);
1098 
1099     rcr2 &= ~I2S_RCR2_DIV_MASK;
1100     /* need to check the divided bclk, if bigger than target, then divider need to re-calculate. */
1101     bitClockDiv = sourceClockHz / bitClockFreq;
1102     /* for the condition where the source clock is smaller than target bclk */
1103     if (bitClockDiv == 0U)
1104     {
1105         bitClockDiv++;
1106     }
1107     /* recheck the divider if properly or not, to make sure output blck not bigger than target*/
1108     if ((sourceClockHz / bitClockDiv) > bitClockFreq)
1109     {
1110         bitClockDiv++;
1111     }
1112 
1113 #if defined(FSL_FEATURE_SAI_HAS_BCLK_BYPASS) && (FSL_FEATURE_SAI_HAS_BCLK_BYPASS)
1114     /* if bclk same with MCLK, bypass the divider */
1115     if (bitClockDiv == 1U)
1116     {
1117         rcr2 |= I2S_RCR2_BYP_MASK;
1118     }
1119     else
1120 #endif
1121     {
1122         rcr2 |= I2S_RCR2_DIV(bitClockDiv / 2U - 1UL);
1123     }
1124 
1125     base->RCR2 = rcr2;
1126 }
1127 
1128 /*!
1129  * brief Transmitter Bit clock configurations.
1130  *
1131  * param base SAI base pointer.
1132  * param masterSlave master or slave.
1133  * param config bit clock other configurations, can be NULL in slave mode.
1134  */
1135 void SAI_TxSetBitclockConfig(I2S_Type *base, sai_master_slave_t masterSlave, sai_bit_clock_t *config)
1136 {
1137     uint32_t tcr2 = base->TCR2;
1138 
1139     if ((masterSlave == kSAI_Master) || (masterSlave == kSAI_Bclk_Master_FrameSync_Slave))
1140     {
1141         assert(config != NULL);
1142 
1143         tcr2 &= ~(I2S_TCR2_BCD_MASK | I2S_TCR2_BCP_MASK | I2S_TCR2_BCI_MASK | I2S_TCR2_BCS_MASK | I2S_TCR2_MSEL_MASK);
1144         tcr2 |= I2S_TCR2_BCD(1U) | I2S_TCR2_BCP(config->bclkPolarity) | I2S_TCR2_BCI(config->bclkInputDelay) |
1145                 I2S_TCR2_BCS(config->bclkSrcSwap) | I2S_TCR2_MSEL(config->bclkSource);
1146     }
1147     else
1148     {
1149         tcr2 &= ~(I2S_TCR2_BCD_MASK);
1150         tcr2 |= I2S_TCR2_BCP(config->bclkPolarity);
1151     }
1152 
1153     base->TCR2 = tcr2;
1154 }
1155 
1156 /*!
1157  * brief Receiver Bit clock configurations.
1158  *
1159  * param base SAI base pointer.
1160  * param masterSlave master or slave.
1161  * param config bit clock other configurations, can be NULL in slave mode.
1162  */
1163 void SAI_RxSetBitclockConfig(I2S_Type *base, sai_master_slave_t masterSlave, sai_bit_clock_t *config)
1164 {
1165     uint32_t rcr2 = base->RCR2;
1166 
1167     if ((masterSlave == kSAI_Master) || (masterSlave == kSAI_Bclk_Master_FrameSync_Slave))
1168     {
1169         assert(config != NULL);
1170 
1171         rcr2 &= ~(I2S_RCR2_BCD_MASK | I2S_RCR2_BCP_MASK | I2S_RCR2_BCI_MASK | I2S_RCR2_BCS_MASK | I2S_RCR2_MSEL_MASK);
1172         rcr2 |= I2S_RCR2_BCD(1U) | I2S_RCR2_BCP(config->bclkPolarity) | I2S_RCR2_BCI(config->bclkInputDelay) |
1173                 I2S_RCR2_BCS(config->bclkSrcSwap) | I2S_RCR2_MSEL(config->bclkSource);
1174     }
1175     else
1176     {
1177         rcr2 &= ~(I2S_RCR2_BCD_MASK);
1178         rcr2 |= I2S_RCR2_BCP(config->bclkPolarity);
1179     }
1180 
1181     base->RCR2 = rcr2;
1182 }
1183 
1184 #if (defined(FSL_FEATURE_SAI_HAS_MCR) && (FSL_FEATURE_SAI_HAS_MCR)) || \
1185     (defined(FSL_FEATURE_SAI_HAS_MCLKDIV_REGISTER) && (FSL_FEATURE_SAI_HAS_MCLKDIV_REGISTER))
1186 /*!
1187  * brief Master clock configurations.
1188  *
1189  * param base SAI base pointer.
1190  * param config master clock configurations.
1191  */
1192 void SAI_SetMasterClockConfig(I2S_Type *base, sai_master_clock_t *config)
1193 {
1194     assert(config != NULL);
1195 
1196 #if defined(FSL_FEATURE_SAI_HAS_MCR) && (FSL_FEATURE_SAI_HAS_MCR)
1197     uint32_t val = 0;
1198 #if !(defined(FSL_FEATURE_SAI_HAS_NO_MCR_MICS) && (FSL_FEATURE_SAI_HAS_NO_MCR_MICS))
1199     /* Master clock source setting */
1200     val       = (base->MCR & ~I2S_MCR_MICS_MASK);
1201     base->MCR = (val | I2S_MCR_MICS(config->mclkSource));
1202 #endif
1203 
1204     /* Configure Master clock output enable */
1205     val       = (base->MCR & ~I2S_MCR_MOE_MASK);
1206     base->MCR = (val | I2S_MCR_MOE(config->mclkOutputEnable));
1207 #endif /* FSL_FEATURE_SAI_HAS_MCR */
1208 
1209 #if ((defined(FSL_FEATURE_SAI_HAS_MCLKDIV_REGISTER) && (FSL_FEATURE_SAI_HAS_MCLKDIV_REGISTER)) || \
1210      (defined(FSL_FEATURE_SAI_HAS_MCR_MCLK_POST_DIV) && (FSL_FEATURE_SAI_HAS_MCR_MCLK_POST_DIV)))
1211     /* Check if master clock divider enabled, then set master clock divider */
1212     if (config->mclkOutputEnable)
1213     {
1214         SAI_SetMasterClockDivider(base, config->mclkHz, config->mclkSourceClkHz);
1215     }
1216 #endif /* FSL_FEATURE_SAI_HAS_MCLKDIV_REGISTER */
1217 }
1218 #endif
1219 
1220 #if FSL_SAI_HAS_FIFO_EXTEND_FEATURE
1221 /*!
1222  * brief SAI transmitter fifo configurations.
1223  *
1224  * param base SAI base pointer.
1225  * param config fifo configurations.
1226  */
1227 void SAI_TxSetFifoConfig(I2S_Type *base, sai_fifo_t *config)
1228 {
1229     assert(config != NULL);
1230 #if defined(FSL_FEATURE_SAI_HAS_FIFO) && (FSL_FEATURE_SAI_HAS_FIFO)
1231     if ((config->fifoWatermark == 0U) ||
1232         (config->fifoWatermark > (uint8_t)((uint32_t)FSL_FEATURE_SAI_FIFO_COUNTn(base))))
1233     {
1234         config->fifoWatermark = (uint8_t)((uint32_t)FSL_FEATURE_SAI_FIFO_COUNTn(base) / 2U);
1235     }
1236 #endif
1237 
1238     uint32_t tcr4 = base->TCR4;
1239 
1240 #if defined(FSL_FEATURE_SAI_HAS_FIFO_COMBINE_MODE) && FSL_FEATURE_SAI_HAS_FIFO_COMBINE_MODE
1241     tcr4 &= ~I2S_TCR4_FCOMB_MASK;
1242     tcr4 |= I2S_TCR4_FCOMB(config->fifoCombine);
1243 #endif
1244 
1245 #if defined(FSL_FEATURE_SAI_HAS_FIFO_FUNCTION_AFTER_ERROR) && FSL_FEATURE_SAI_HAS_FIFO_FUNCTION_AFTER_ERROR
1246     tcr4 &= ~I2S_TCR4_FCONT_MASK;
1247     /* ERR05144: not set FCONT = 1 when TMR > 0, the transmit shift register may not load correctly that will cause TX
1248      * not work */
1249     if (base->TMR == 0U)
1250     {
1251         tcr4 |= I2S_TCR4_FCONT(config->fifoContinueOneError);
1252     }
1253 #endif
1254 
1255 #if defined(FSL_FEATURE_SAI_HAS_FIFO_PACKING) && FSL_FEATURE_SAI_HAS_FIFO_PACKING
1256     tcr4 &= ~I2S_TCR4_FPACK_MASK;
1257     tcr4 |= I2S_TCR4_FPACK(config->fifoPacking);
1258 #endif
1259 
1260     base->TCR4 = tcr4;
1261 
1262 #if defined(FSL_FEATURE_SAI_HAS_FIFO) && (FSL_FEATURE_SAI_HAS_FIFO)
1263     base->TCR1 = (base->TCR1 & (~I2S_TCR1_TFW_MASK)) | I2S_TCR1_TFW(config->fifoWatermark);
1264 #endif
1265 }
1266 
1267 /*!
1268  * brief SAI receiver fifo configurations.
1269  *
1270  * param base SAI base pointer.
1271  * param config fifo configurations.
1272  */
1273 void SAI_RxSetFifoConfig(I2S_Type *base, sai_fifo_t *config)
1274 {
1275     assert(config != NULL);
1276 #if defined(FSL_FEATURE_SAI_HAS_FIFO) && (FSL_FEATURE_SAI_HAS_FIFO)
1277     if ((config->fifoWatermark == 0U) ||
1278         (config->fifoWatermark > (uint8_t)((uint32_t)FSL_FEATURE_SAI_FIFO_COUNTn(base))))
1279     {
1280         config->fifoWatermark = (uint8_t)((uint32_t)FSL_FEATURE_SAI_FIFO_COUNTn(base) / 2U);
1281     }
1282 #endif
1283     uint32_t rcr4 = base->RCR4;
1284 
1285 #if defined(FSL_FEATURE_SAI_HAS_FIFO_COMBINE_MODE) && FSL_FEATURE_SAI_HAS_FIFO_COMBINE_MODE
1286     rcr4 &= ~I2S_RCR4_FCOMB_MASK;
1287     rcr4 |= I2S_RCR4_FCOMB(config->fifoCombine);
1288 #endif
1289 
1290 #if defined(FSL_FEATURE_SAI_HAS_FIFO_FUNCTION_AFTER_ERROR) && FSL_FEATURE_SAI_HAS_FIFO_FUNCTION_AFTER_ERROR
1291     rcr4 &= ~I2S_RCR4_FCONT_MASK;
1292     rcr4 |= I2S_RCR4_FCONT(config->fifoContinueOneError);
1293 #endif
1294 
1295 #if defined(FSL_FEATURE_SAI_HAS_FIFO_PACKING) && FSL_FEATURE_SAI_HAS_FIFO_PACKING
1296     rcr4 &= ~I2S_RCR4_FPACK_MASK;
1297     rcr4 |= I2S_RCR4_FPACK(config->fifoPacking);
1298 #endif
1299 
1300     base->RCR4 = rcr4;
1301 
1302 #if defined(FSL_FEATURE_SAI_HAS_FIFO) && (FSL_FEATURE_SAI_HAS_FIFO)
1303     base->RCR1 = (base->RCR1 & (~I2S_RCR1_RFW_MASK)) | I2S_RCR1_RFW(config->fifoWatermark);
1304 #endif
1305 }
1306 #endif
1307 
1308 /*!
1309  * brief SAI transmitter Frame sync configurations.
1310  *
1311  * param base SAI base pointer.
1312  * param masterSlave master or slave.
1313  * param config frame sync configurations, can be NULL in slave mode.
1314  */
1315 void SAI_TxSetFrameSyncConfig(I2S_Type *base, sai_master_slave_t masterSlave, sai_frame_sync_t *config)
1316 {
1317     assert(config != NULL);
1318     assert((config->frameSyncWidth - 1UL) <= (I2S_TCR4_SYWD_MASK >> I2S_TCR4_SYWD_SHIFT));
1319 
1320     uint32_t tcr4 = base->TCR4;
1321 
1322     tcr4 &= ~(I2S_TCR4_FSE_MASK | I2S_TCR4_FSP_MASK | I2S_TCR4_FSD_MASK | I2S_TCR4_SYWD_MASK);
1323 
1324 #if defined(FSL_FEATURE_SAI_HAS_ON_DEMAND_MODE) && FSL_FEATURE_SAI_HAS_ON_DEMAND_MODE
1325     tcr4 &= ~I2S_TCR4_ONDEM_MASK;
1326     tcr4 |= I2S_TCR4_ONDEM(config->frameSyncGenerateOnDemand);
1327 #endif
1328 
1329     tcr4 |=
1330         I2S_TCR4_FSE(config->frameSyncEarly) | I2S_TCR4_FSP(config->frameSyncPolarity) |
1331         I2S_TCR4_FSD(((masterSlave == kSAI_Master) || (masterSlave == kSAI_Bclk_Slave_FrameSync_Master)) ? 1UL : 0U) |
1332         I2S_TCR4_SYWD(config->frameSyncWidth - 1UL);
1333 
1334     base->TCR4 = tcr4;
1335 }
1336 
1337 /*!
1338  * brief SAI receiver Frame sync configurations.
1339  *
1340  * param base SAI base pointer.
1341  * param masterSlave master or slave.
1342  * param config frame sync configurations, can be NULL in slave mode.
1343  */
1344 void SAI_RxSetFrameSyncConfig(I2S_Type *base, sai_master_slave_t masterSlave, sai_frame_sync_t *config)
1345 {
1346     assert(config != NULL);
1347     assert((config->frameSyncWidth - 1UL) <= (I2S_RCR4_SYWD_MASK >> I2S_RCR4_SYWD_SHIFT));
1348 
1349     uint32_t rcr4 = base->RCR4;
1350 
1351     rcr4 &= ~(I2S_RCR4_FSE_MASK | I2S_RCR4_FSP_MASK | I2S_RCR4_FSD_MASK | I2S_RCR4_SYWD_MASK);
1352 
1353 #if defined(FSL_FEATURE_SAI_HAS_ON_DEMAND_MODE) && FSL_FEATURE_SAI_HAS_ON_DEMAND_MODE
1354     rcr4 &= ~I2S_RCR4_ONDEM_MASK;
1355     rcr4 |= I2S_RCR4_ONDEM(config->frameSyncGenerateOnDemand);
1356 #endif
1357 
1358     rcr4 |=
1359         I2S_RCR4_FSE(config->frameSyncEarly) | I2S_RCR4_FSP(config->frameSyncPolarity) |
1360         I2S_RCR4_FSD(((masterSlave == kSAI_Master) || (masterSlave == kSAI_Bclk_Slave_FrameSync_Master)) ? 1UL : 0U) |
1361         I2S_RCR4_SYWD(config->frameSyncWidth - 1UL);
1362 
1363     base->RCR4 = rcr4;
1364 }
1365 
1366 /*!
1367  * brief SAI transmitter Serial data configurations.
1368  *
1369  * param base SAI base pointer.
1370  * param config serial data configurations.
1371  */
1372 void SAI_TxSetSerialDataConfig(I2S_Type *base, sai_serial_data_t *config)
1373 {
1374     assert(config != NULL);
1375 
1376     uint32_t tcr4 = base->TCR4;
1377 
1378     base->TCR5 = I2S_TCR5_WNW(config->dataWordNLength - 1UL) | I2S_TCR5_W0W(config->dataWord0Length - 1UL) |
1379                  I2S_TCR5_FBT(config->dataFirstBitShifted - 1UL);
1380     base->TMR = config->dataMaskedWord;
1381 #if defined(FSL_FEATURE_SAI_HAS_FIFO_FUNCTION_AFTER_ERROR) && FSL_FEATURE_SAI_HAS_FIFO_FUNCTION_AFTER_ERROR
1382     /* ERR05144: not set FCONT = 1 when TMR > 0, the transmit shift register may not load correctly that will cause TX
1383      * not work */
1384     if (config->dataMaskedWord > 0U)
1385     {
1386         tcr4 &= ~I2S_TCR4_FCONT_MASK;
1387     }
1388 #endif
1389     tcr4 &= ~(I2S_TCR4_FRSZ_MASK | I2S_TCR4_MF_MASK);
1390     tcr4 |= I2S_TCR4_FRSZ(config->dataWordNum - 1UL) | I2S_TCR4_MF(config->dataOrder);
1391 
1392 #if defined(FSL_FEATURE_SAI_HAS_CHANNEL_MODE) && FSL_FEATURE_SAI_HAS_CHANNEL_MODE
1393     tcr4 &= ~I2S_TCR4_CHMOD_MASK;
1394     tcr4 |= I2S_TCR4_CHMOD(config->dataMode);
1395 #endif
1396 
1397     base->TCR4 = tcr4;
1398 }
1399 
1400 /*!
1401  * @brief SAI receiver Serial data configurations.
1402  *
1403  * @param base SAI base pointer.
1404  * @param config serial data configurations.
1405  */
1406 void SAI_RxSetSerialDataConfig(I2S_Type *base, sai_serial_data_t *config)
1407 {
1408     assert(config != NULL);
1409 
1410     uint32_t rcr4 = base->RCR4;
1411 
1412     base->RCR5 = I2S_RCR5_WNW(config->dataWordNLength - 1UL) | I2S_RCR5_W0W(config->dataWord0Length - 1UL) |
1413                  I2S_RCR5_FBT(config->dataFirstBitShifted - 1UL);
1414     base->RMR = config->dataMaskedWord;
1415 
1416     rcr4 &= ~(I2S_RCR4_FRSZ_MASK | I2S_RCR4_MF_MASK);
1417     rcr4 |= I2S_RCR4_FRSZ(config->dataWordNum - 1uL) | I2S_RCR4_MF(config->dataOrder);
1418 
1419     base->RCR4 = rcr4;
1420 }
1421 
1422 /*!
1423  * brief SAI transmitter configurations.
1424  *
1425  * param base SAI base pointer.
1426  * param config transmitter configurations.
1427  */
1428 void SAI_TxSetConfig(I2S_Type *base, sai_transceiver_t *config)
1429 {
1430     assert(config != NULL);
1431     assert(FSL_FEATURE_SAI_CHANNEL_COUNTn(base) != -1);
1432 
1433     uint8_t i           = 0U;
1434     uint32_t val        = 0U;
1435     uint8_t channelNums = 0U;
1436 
1437     /* reset transmitter */
1438     SAI_TxReset(base);
1439 
1440     /* if channel mask is not set, then format->channel must be set,
1441      use it to get channel mask value */
1442     if (config->channelMask == 0U)
1443     {
1444         config->channelMask = 1U << config->startChannel;
1445     }
1446 
1447     for (i = 0U; i < (uint32_t)FSL_FEATURE_SAI_CHANNEL_COUNTn(base); i++)
1448     {
1449         if (IS_SAI_FLAG_SET(1UL << i, config->channelMask))
1450         {
1451             channelNums++;
1452             config->endChannel = i;
1453         }
1454     }
1455 
1456     for (i = 0U; i < (uint32_t)FSL_FEATURE_SAI_CHANNEL_COUNTn(base); i++)
1457     {
1458         if (IS_SAI_FLAG_SET((1UL << i), config->channelMask))
1459         {
1460             config->startChannel = i;
1461             break;
1462         }
1463     }
1464 
1465     config->channelNums = channelNums;
1466 #if defined(FSL_FEATURE_SAI_HAS_FIFO_COMBINE_MODE) && (FSL_FEATURE_SAI_HAS_FIFO_COMBINE_MODE)
1467     /* make sure combine mode disabled while multipe channel is used */
1468     if (config->channelNums > 1U)
1469     {
1470         base->TCR4 &= ~I2S_TCR4_FCOMB_MASK;
1471     }
1472 #endif
1473 
1474     /* Set data channel */
1475     base->TCR3 &= ~I2S_TCR3_TCE_MASK;
1476     base->TCR3 |= I2S_TCR3_TCE(config->channelMask);
1477 
1478     if (config->syncMode == kSAI_ModeAsync)
1479     {
1480         val = base->TCR2;
1481         val &= ~I2S_TCR2_SYNC_MASK;
1482         base->TCR2 = (val | I2S_TCR2_SYNC(0U));
1483     }
1484     if (config->syncMode == kSAI_ModeSync)
1485     {
1486         val = base->TCR2;
1487         val &= ~I2S_TCR2_SYNC_MASK;
1488         base->TCR2 = (val | I2S_TCR2_SYNC(1U));
1489         /* If sync with Rx, should set Rx to async mode */
1490         val = base->RCR2;
1491         val &= ~I2S_RCR2_SYNC_MASK;
1492         base->RCR2 = (val | I2S_RCR2_SYNC(0U));
1493     }
1494 #if defined(FSL_FEATURE_SAI_HAS_SYNC_WITH_ANOTHER_SAI) && (FSL_FEATURE_SAI_HAS_SYNC_WITH_ANOTHER_SAI)
1495     if (config->syncMode == kSAI_ModeSyncWithOtherTx)
1496     {
1497         val = base->TCR2;
1498         val &= ~I2S_TCR2_SYNC_MASK;
1499         base->TCR2 = (val | I2S_TCR2_SYNC(2U));
1500     }
1501     if (config->syncMode == kSAI_ModeSyncWithOtherRx)
1502     {
1503         val = base->TCR2;
1504         val &= ~I2S_TCR2_SYNC_MASK;
1505         base->TCR2 = (val | I2S_TCR2_SYNC(3U));
1506     }
1507 #endif /* FSL_FEATURE_SAI_HAS_SYNC_WITH_ANOTHER_SAI */
1508 
1509     /* bit clock configurations */
1510     SAI_TxSetBitclockConfig(base, config->masterSlave, &config->bitClock);
1511     /* serial data configurations */
1512     SAI_TxSetSerialDataConfig(base, &config->serialData);
1513     /* frame sync configurations */
1514     SAI_TxSetFrameSyncConfig(base, config->masterSlave, &config->frameSync);
1515 #if FSL_SAI_HAS_FIFO_EXTEND_FEATURE
1516     /* fifo configurations */
1517     SAI_TxSetFifoConfig(base, &config->fifo);
1518 #endif
1519 }
1520 
1521 /*!
1522  * brief SAI transmitter transfer configurations.
1523  *
1524  * This function initializes the TX, include bit clock, frame sync, master clock, serial data and fifo configurations.
1525  *
1526  * param base SAI base pointer.
1527  * param handle SAI handle pointer.
1528  * param config tranmitter configurations.
1529  */
1530 void SAI_TransferTxSetConfig(I2S_Type *base, sai_handle_t *handle, sai_transceiver_t *config)
1531 {
1532     assert(handle != NULL);
1533     assert(config != NULL);
1534     assert(config->channelNums <= (uint32_t)FSL_FEATURE_SAI_CHANNEL_COUNTn(base));
1535 
1536     handle->bitWidth = config->frameSync.frameSyncWidth;
1537 #if defined(FSL_FEATURE_SAI_HAS_FIFO) && (FSL_FEATURE_SAI_HAS_FIFO)
1538     if ((config->fifo.fifoWatermark == 0U) ||
1539         (config->fifo.fifoWatermark > (uint8_t)((uint32_t)FSL_FEATURE_SAI_FIFO_COUNTn(base))))
1540     {
1541         config->fifo.fifoWatermark = (uint8_t)((uint32_t)FSL_FEATURE_SAI_FIFO_COUNTn(base) / 2U);
1542     }
1543     handle->watermark = config->fifo.fifoWatermark;
1544 #endif
1545 
1546     /* transmitter configurations */
1547     SAI_TxSetConfig(base, config);
1548 
1549     handle->channel = config->startChannel;
1550     /* used for multi channel */
1551     handle->channelMask = config->channelMask;
1552     handle->channelNums = config->channelNums;
1553     handle->endChannel  = config->endChannel;
1554 }
1555 
1556 /*!
1557  * brief SAI receiver configurations.
1558  *
1559  * param base SAI base pointer.
1560  * param config transmitter configurations.
1561  */
1562 void SAI_RxSetConfig(I2S_Type *base, sai_transceiver_t *config)
1563 {
1564     assert(config != NULL);
1565     assert(FSL_FEATURE_SAI_CHANNEL_COUNTn(base) != -1);
1566 
1567     uint8_t i           = 0U;
1568     uint32_t val        = 0U;
1569     uint8_t channelNums = 0U;
1570 
1571     /* reset receiver */
1572     SAI_RxReset(base);
1573 
1574     /* if channel mask is not set, then format->channel must be set,
1575      use it to get channel mask value */
1576     if (config->channelMask == 0U)
1577     {
1578         config->channelMask = 1U << config->startChannel;
1579     }
1580 
1581     for (i = 0U; i < (uint32_t)FSL_FEATURE_SAI_CHANNEL_COUNTn(base); i++)
1582     {
1583         if (IS_SAI_FLAG_SET((1UL << i), config->channelMask))
1584         {
1585             channelNums++;
1586             config->endChannel = i;
1587         }
1588     }
1589 
1590     for (i = 0U; i < (uint32_t)FSL_FEATURE_SAI_CHANNEL_COUNTn(base); i++)
1591     {
1592         if (IS_SAI_FLAG_SET((1UL << i), config->channelMask))
1593         {
1594             config->startChannel = i;
1595             break;
1596         }
1597     }
1598 
1599     config->channelNums = channelNums;
1600 #if defined(FSL_FEATURE_SAI_HAS_FIFO_COMBINE_MODE) && (FSL_FEATURE_SAI_HAS_FIFO_COMBINE_MODE)
1601     /* make sure combine mode disabled while multipe channel is used */
1602     if (config->channelNums > 1U)
1603     {
1604         base->RCR4 &= ~I2S_RCR4_FCOMB_MASK;
1605     }
1606 #endif
1607 
1608     /* Set data channel */
1609     base->RCR3 &= ~I2S_RCR3_RCE_MASK;
1610     base->RCR3 |= I2S_RCR3_RCE(config->channelMask);
1611 
1612     /* Set Sync mode */
1613     if (config->syncMode == kSAI_ModeAsync)
1614     {
1615         val = base->RCR2;
1616         val &= ~I2S_RCR2_SYNC_MASK;
1617         base->RCR2 = (val | I2S_RCR2_SYNC(0U));
1618     }
1619     if (config->syncMode == kSAI_ModeSync)
1620     {
1621         val = base->RCR2;
1622         val &= ~I2S_RCR2_SYNC_MASK;
1623         base->RCR2 = (val | I2S_RCR2_SYNC(1U));
1624         /* If sync with Tx, should set Tx to async mode */
1625         val = base->TCR2;
1626         val &= ~I2S_TCR2_SYNC_MASK;
1627         base->TCR2 = (val | I2S_TCR2_SYNC(0U));
1628     }
1629 #if defined(FSL_FEATURE_SAI_HAS_SYNC_WITH_ANOTHER_SAI) && (FSL_FEATURE_SAI_HAS_SYNC_WITH_ANOTHER_SAI)
1630     if (config->syncMode == kSAI_ModeSyncWithOtherTx)
1631     {
1632         val = base->RCR2;
1633         val &= ~I2S_RCR2_SYNC_MASK;
1634         base->RCR2 = (val | I2S_RCR2_SYNC(2U));
1635     }
1636     if (config->syncMode == kSAI_ModeSyncWithOtherRx)
1637     {
1638         val = base->RCR2;
1639         val &= ~I2S_RCR2_SYNC_MASK;
1640         base->RCR2 = (val | I2S_RCR2_SYNC(3U));
1641     }
1642 #endif /* FSL_FEATURE_SAI_HAS_SYNC_WITH_ANOTHER_SAI */
1643 
1644     /* bit clock configurations */
1645     SAI_RxSetBitclockConfig(base, config->masterSlave, &config->bitClock);
1646     /* serial data configurations */
1647     SAI_RxSetSerialDataConfig(base, &config->serialData);
1648     /* frame sync configurations */
1649     SAI_RxSetFrameSyncConfig(base, config->masterSlave, &config->frameSync);
1650 #if FSL_SAI_HAS_FIFO_EXTEND_FEATURE
1651     /* fifo configurations */
1652     SAI_RxSetFifoConfig(base, &config->fifo);
1653 #endif
1654 }
1655 
1656 /*!
1657  * brief SAI receiver transfer configurations.
1658  *
1659  * This function initializes the TX, include bit clock, frame sync, master clock, serial data and fifo configurations.
1660  *
1661  * param base SAI base pointer.
1662  * param handle SAI handle pointer.
1663  * param config tranmitter configurations.
1664  */
1665 void SAI_TransferRxSetConfig(I2S_Type *base, sai_handle_t *handle, sai_transceiver_t *config)
1666 {
1667     assert(handle != NULL);
1668     assert(config != NULL);
1669 
1670     handle->bitWidth = config->frameSync.frameSyncWidth;
1671 #if defined(FSL_FEATURE_SAI_HAS_FIFO) && (FSL_FEATURE_SAI_HAS_FIFO)
1672     if ((config->fifo.fifoWatermark == 0U) ||
1673         (config->fifo.fifoWatermark > (uint8_t)((uint32_t)FSL_FEATURE_SAI_FIFO_COUNTn(base))))
1674     {
1675         config->fifo.fifoWatermark = (uint8_t)((uint32_t)FSL_FEATURE_SAI_FIFO_COUNTn(base) / 2U);
1676     }
1677     handle->watermark = config->fifo.fifoWatermark;
1678 #endif
1679 
1680     /* receiver configurations */
1681     SAI_RxSetConfig(base, config);
1682 
1683     handle->channel = config->startChannel;
1684     /* used for multi channel */
1685     handle->channelMask = config->channelMask;
1686     handle->channelNums = config->channelNums;
1687     handle->endChannel  = config->endChannel;
1688 }
1689 
1690 /*!
1691  * brief Get classic I2S mode configurations.
1692  *
1693  * param config transceiver configurations.
1694  * param bitWidth audio data bitWidth.
1695  * param mode audio data channel.
1696  * param saiChannelMask channel mask value to enable.
1697  */
1698 void SAI_GetClassicI2SConfig(sai_transceiver_t *config,
1699                              sai_word_width_t bitWidth,
1700                              sai_mono_stereo_t mode,
1701                              uint32_t saiChannelMask)
1702 {
1703     SAI_GetCommonConfig(config, bitWidth, mode, saiChannelMask);
1704 }
1705 
1706 /*!
1707  * brief Get left justified mode configurations.
1708  *
1709  * param config transceiver configurations.
1710  * param bitWidth audio data bitWidth.
1711  * param mode audio data channel.
1712  * param saiChannelMask channel mask value to enable.
1713  */
1714 void SAI_GetLeftJustifiedConfig(sai_transceiver_t *config,
1715                                 sai_word_width_t bitWidth,
1716                                 sai_mono_stereo_t mode,
1717                                 uint32_t saiChannelMask)
1718 {
1719     assert(NULL != config);
1720     assert(saiChannelMask != 0U);
1721 
1722     SAI_GetCommonConfig(config, bitWidth, mode, saiChannelMask);
1723 
1724     config->frameSync.frameSyncEarly    = false;
1725     config->frameSync.frameSyncPolarity = kSAI_PolarityActiveHigh;
1726 }
1727 
1728 /*!
1729  * brief Get right justified mode configurations.
1730  *
1731  * param config transceiver configurations.
1732  * param bitWidth audio data bitWidth.
1733  * param mode audio data channel.
1734  * param saiChannelMask channel mask value to enable.
1735  */
1736 void SAI_GetRightJustifiedConfig(sai_transceiver_t *config,
1737                                  sai_word_width_t bitWidth,
1738                                  sai_mono_stereo_t mode,
1739                                  uint32_t saiChannelMask)
1740 {
1741     assert(NULL != config);
1742     assert(saiChannelMask != 0U);
1743 
1744     SAI_GetCommonConfig(config, bitWidth, mode, saiChannelMask);
1745 
1746     config->frameSync.frameSyncEarly    = false;
1747     config->frameSync.frameSyncPolarity = kSAI_PolarityActiveHigh;
1748 }
1749 
1750 /*!
1751  * brief Get DSP mode configurations.
1752  *
1753  * note DSP mode is also called PCM mode which support MODE A and MODE B,
1754  * DSP/PCM MODE A configuration flow. RX is similiar but uses SAI_RxSetConfig instead of SAI_TxSetConfig:
1755  * code
1756  * SAI_GetDSPConfig(config, kSAI_FrameSyncLenOneBitClk, bitWidth, kSAI_Stereo, channelMask)
1757  * config->frameSync.frameSyncEarly    = true;
1758  * SAI_TxSetConfig(base, config)
1759  * endcode
1760  *
1761  * DSP/PCM MODE B configuration flow for TX. RX is similiar but uses SAI_RxSetConfig instead of SAI_TxSetConfig:
1762  * code
1763  * SAI_GetDSPConfig(config, kSAI_FrameSyncLenOneBitClk, bitWidth, kSAI_Stereo, channelMask)
1764  * SAI_TxSetConfig(base, config)
1765  * endcode
1766  *
1767  * param config transceiver configurations.
1768  * param frameSyncWidth length of frame sync.
1769  * param bitWidth audio data bitWidth.
1770  * param mode audio data channel.
1771  * param saiChannelMask mask value of the channel to enable.
1772  */
1773 void SAI_GetDSPConfig(sai_transceiver_t *config,
1774                       sai_frame_sync_len_t frameSyncWidth,
1775                       sai_word_width_t bitWidth,
1776                       sai_mono_stereo_t mode,
1777                       uint32_t saiChannelMask)
1778 {
1779     assert(NULL != config);
1780     assert(saiChannelMask != 0U);
1781 
1782     SAI_GetCommonConfig(config, bitWidth, mode, saiChannelMask);
1783 
1784     /* frame sync default configurations */
1785     switch (frameSyncWidth)
1786     {
1787         case kSAI_FrameSyncLenOneBitClk:
1788             config->frameSync.frameSyncWidth = 1U;
1789             break;
1790         default:
1791             assert(false);
1792             break;
1793     }
1794     config->frameSync.frameSyncEarly    = false;
1795     config->frameSync.frameSyncPolarity = kSAI_PolarityActiveHigh;
1796 }
1797 
1798 /*!
1799  * brief Get TDM mode configurations.
1800  *
1801  * param config transceiver configurations.
1802  * param bitWidth audio data bitWidth.
1803  * param mode audio data channel.
1804  * param saiChannelMask channel mask value to enable.
1805  */
1806 void SAI_GetTDMConfig(sai_transceiver_t *config,
1807                       sai_frame_sync_len_t frameSyncWidth,
1808                       sai_word_width_t bitWidth,
1809                       uint32_t dataWordNum,
1810                       uint32_t saiChannelMask)
1811 {
1812     assert(NULL != config);
1813     assert(saiChannelMask != 0U);
1814     assert(dataWordNum <= 32U);
1815 
1816     SAI_GetCommonConfig(config, bitWidth, kSAI_Stereo, saiChannelMask);
1817 
1818     /* frame sync default configurations */
1819     switch (frameSyncWidth)
1820     {
1821         case kSAI_FrameSyncLenOneBitClk:
1822             config->frameSync.frameSyncWidth = 1U;
1823             break;
1824         case kSAI_FrameSyncLenPerWordWidth:
1825             break;
1826         default:
1827             assert(false);
1828             break;
1829     }
1830     config->frameSync.frameSyncEarly    = false;
1831     config->frameSync.frameSyncPolarity = kSAI_PolarityActiveHigh;
1832     config->serialData.dataWordNum      = (uint8_t)dataWordNum;
1833 }
1834 
1835 /*!
1836  * brief Configures the SAI Tx audio format.
1837  *
1838  * deprecated Do not use this function.  It has been superceded by @ref SAI_TxSetConfig
1839  *
1840  * The audio format can be changed at run-time. This function configures the sample rate and audio data
1841  * format to be transferred.
1842  *
1843  * param base SAI base pointer.
1844  * param format Pointer to the SAI audio data format structure.
1845  * param mclkSourceClockHz SAI master clock source frequency in Hz.
1846  * param bclkSourceClockHz SAI bit clock source frequency in Hz. If the bit clock source is a master
1847  * clock, this value should equal the masterClockHz.
1848  */
1849 void SAI_TxSetFormat(I2S_Type *base,
1850                      sai_transfer_format_t *format,
1851                      uint32_t mclkSourceClockHz,
1852                      uint32_t bclkSourceClockHz)
1853 {
1854     assert(FSL_FEATURE_SAI_CHANNEL_COUNTn(base) != -1);
1855 
1856     uint32_t bclk = 0;
1857     uint32_t val  = 0;
1858     uint8_t i = 0U, channelNums = 0U;
1859     uint32_t divider = 0U;
1860 
1861     if (format->isFrameSyncCompact)
1862     {
1863         bclk = format->sampleRate_Hz * format->bitWidth * (format->stereo == kSAI_Stereo ? 2U : 1U);
1864         val  = (base->TCR4 & (~I2S_TCR4_SYWD_MASK));
1865         val |= I2S_TCR4_SYWD(format->bitWidth - 1U);
1866         base->TCR4 = val;
1867     }
1868     else
1869     {
1870         bclk = format->sampleRate_Hz * 32U * 2U;
1871     }
1872 
1873 /* Compute the mclk */
1874 #if defined(FSL_FEATURE_SAI_HAS_MCLKDIV_REGISTER) && (FSL_FEATURE_SAI_HAS_MCLKDIV_REGISTER)
1875     /* Check if master clock divider enabled, then set master clock divider */
1876     if (IS_SAI_FLAG_SET(base->MCR, I2S_MCR_MOE_MASK))
1877     {
1878         SAI_SetMasterClockDivider(base, format->masterClockHz, mclkSourceClockHz);
1879     }
1880 #endif /* FSL_FEATURE_SAI_HAS_MCLKDIV_REGISTER */
1881 
1882     /* Set bclk if needed */
1883     if (IS_SAI_FLAG_SET(base->TCR2, I2S_TCR2_BCD_MASK))
1884     {
1885         base->TCR2 &= ~I2S_TCR2_DIV_MASK;
1886         /* need to check the divided bclk, if bigger than target, then divider need to re-calculate. */
1887         divider = bclkSourceClockHz / bclk;
1888         /* for the condition where the source clock is smaller than target bclk */
1889         if (divider == 0U)
1890         {
1891             divider++;
1892         }
1893         /* recheck the divider if properly or not, to make sure output blck not bigger than target*/
1894         if ((bclkSourceClockHz / divider) > bclk)
1895         {
1896             divider++;
1897         }
1898 
1899 #if defined(FSL_FEATURE_SAI_HAS_BCLK_BYPASS) && (FSL_FEATURE_SAI_HAS_BCLK_BYPASS)
1900         /* if bclk same with MCLK, bypass the divider */
1901         if (divider == 1U)
1902         {
1903             base->TCR2 |= I2S_TCR2_BYP_MASK;
1904         }
1905         else
1906 #endif
1907         {
1908             base->TCR2 |= I2S_TCR2_DIV(divider / 2U - 1U);
1909         }
1910     }
1911 
1912     /* Set bitWidth */
1913     val = (format->isFrameSyncCompact) ? (format->bitWidth - 1U) : 31U;
1914     if (format->protocol == kSAI_BusRightJustified)
1915     {
1916         base->TCR5 = I2S_TCR5_WNW(val) | I2S_TCR5_W0W(val) | I2S_TCR5_FBT(val);
1917     }
1918     else
1919     {
1920         if (IS_SAI_FLAG_SET(base->TCR4, I2S_TCR4_MF_MASK))
1921         {
1922             base->TCR5 = I2S_TCR5_WNW(val) | I2S_TCR5_W0W(val) | I2S_TCR5_FBT(format->bitWidth - 1UL);
1923         }
1924         else
1925         {
1926             base->TCR5 = I2S_TCR5_WNW(val) | I2S_TCR5_W0W(val) | I2S_TCR5_FBT(0);
1927         }
1928     }
1929 
1930     /* Set mono or stereo */
1931     base->TMR = (uint32_t)format->stereo;
1932 
1933     /* if channel mask is not set, then format->channel must be set,
1934      use it to get channel mask value */
1935     if (format->channelMask == 0U)
1936     {
1937         format->channelMask = 1U << format->channel;
1938     }
1939 
1940     /* if channel nums is not set, calculate it here according to channelMask*/
1941     for (i = 0U; i < (uint32_t)FSL_FEATURE_SAI_CHANNEL_COUNTn(base); i++)
1942     {
1943         if (IS_SAI_FLAG_SET((1UL << i), format->channelMask))
1944         {
1945             channelNums++;
1946             format->endChannel = i;
1947         }
1948     }
1949 
1950     for (i = 0U; i < (uint32_t)FSL_FEATURE_SAI_CHANNEL_COUNTn(base); i++)
1951     {
1952         if (IS_SAI_FLAG_SET((1UL << i), format->channelMask))
1953         {
1954             format->channel = i;
1955             break;
1956         }
1957     }
1958 
1959     format->channelNums = channelNums;
1960 #if defined(FSL_FEATURE_SAI_HAS_FIFO_COMBINE_MODE) && (FSL_FEATURE_SAI_HAS_FIFO_COMBINE_MODE)
1961     /* make sure combine mode disabled while multipe channel is used */
1962     if (format->channelNums > 1U)
1963     {
1964         base->TCR4 &= ~I2S_TCR4_FCOMB_MASK;
1965     }
1966 #endif
1967 
1968     /* Set data channel */
1969     base->TCR3 &= ~I2S_TCR3_TCE_MASK;
1970     base->TCR3 |= I2S_TCR3_TCE(format->channelMask);
1971 
1972 #if defined(FSL_FEATURE_SAI_HAS_FIFO) && (FSL_FEATURE_SAI_HAS_FIFO)
1973     /* Set watermark */
1974     base->TCR1 = format->watermark;
1975 #endif /* FSL_FEATURE_SAI_HAS_FIFO */
1976 }
1977 
1978 /*!
1979  * brief Configures the SAI Rx audio format.
1980  *
1981  * deprecated Do not use this function.  It has been superceded by @ref SAI_RxSetConfig
1982  *
1983  * The audio format can be changed at run-time. This function configures the sample rate and audio data
1984  * format to be transferred.
1985  *
1986  * param base SAI base pointer.
1987  * param format Pointer to the SAI audio data format structure.
1988  * param mclkSourceClockHz SAI master clock source frequency in Hz.
1989  * param bclkSourceClockHz SAI bit clock source frequency in Hz. If the bit clock source is a master
1990  * clock, this value should equal the masterClockHz.
1991  */
1992 void SAI_RxSetFormat(I2S_Type *base,
1993                      sai_transfer_format_t *format,
1994                      uint32_t mclkSourceClockHz,
1995                      uint32_t bclkSourceClockHz)
1996 {
1997     assert(FSL_FEATURE_SAI_CHANNEL_COUNTn(base) != -1);
1998 
1999     uint32_t bclk = 0;
2000     uint32_t val  = 0;
2001     uint8_t i = 0U, channelNums = 0U;
2002     uint32_t divider = 0U;
2003 
2004     if (format->isFrameSyncCompact)
2005     {
2006         bclk = format->sampleRate_Hz * format->bitWidth * (format->stereo == kSAI_Stereo ? 2U : 1U);
2007         val  = (base->RCR4 & (~I2S_RCR4_SYWD_MASK));
2008         val |= I2S_RCR4_SYWD(format->bitWidth - 1U);
2009         base->RCR4 = val;
2010     }
2011     else
2012     {
2013         bclk = format->sampleRate_Hz * 32U * 2U;
2014     }
2015 
2016 /* Compute the mclk */
2017 #if defined(FSL_FEATURE_SAI_HAS_MCLKDIV_REGISTER) && (FSL_FEATURE_SAI_HAS_MCLKDIV_REGISTER)
2018     /* Check if master clock divider enabled */
2019     if (IS_SAI_FLAG_SET(base->MCR, I2S_MCR_MOE_MASK))
2020     {
2021         SAI_SetMasterClockDivider(base, format->masterClockHz, mclkSourceClockHz);
2022     }
2023 #endif /* FSL_FEATURE_SAI_HAS_MCLKDIV_REGISTER */
2024 
2025     /* Set bclk if needed */
2026     if (IS_SAI_FLAG_SET(base->RCR2, I2S_RCR2_BCD_MASK))
2027     {
2028         base->RCR2 &= ~I2S_RCR2_DIV_MASK;
2029         /* need to check the divided bclk, if bigger than target, then divider need to re-calculate. */
2030         divider = bclkSourceClockHz / bclk;
2031         /* for the condition where the source clock is smaller than target bclk */
2032         if (divider == 0U)
2033         {
2034             divider++;
2035         }
2036         /* recheck the divider if properly or not, to make sure output blck not bigger than target*/
2037         if ((bclkSourceClockHz / divider) > bclk)
2038         {
2039             divider++;
2040         }
2041 #if defined(FSL_FEATURE_SAI_HAS_BCLK_BYPASS) && (FSL_FEATURE_SAI_HAS_BCLK_BYPASS)
2042         /* if bclk same with MCLK, bypass the divider */
2043         if (divider == 1U)
2044         {
2045             base->RCR2 |= I2S_RCR2_BYP_MASK;
2046         }
2047         else
2048 #endif
2049         {
2050             base->RCR2 |= I2S_RCR2_DIV(divider / 2U - 1U);
2051         }
2052     }
2053 
2054     /* Set bitWidth */
2055     val = (format->isFrameSyncCompact) ? (format->bitWidth - 1U) : 31U;
2056     if (format->protocol == kSAI_BusRightJustified)
2057     {
2058         base->RCR5 = I2S_RCR5_WNW(val) | I2S_RCR5_W0W(val) | I2S_RCR5_FBT(val);
2059     }
2060     else
2061     {
2062         if (IS_SAI_FLAG_SET(base->RCR4, I2S_RCR4_MF_MASK))
2063         {
2064             base->RCR5 = I2S_RCR5_WNW(val) | I2S_RCR5_W0W(val) | I2S_RCR5_FBT(format->bitWidth - 1UL);
2065         }
2066         else
2067         {
2068             base->RCR5 = I2S_RCR5_WNW(val) | I2S_RCR5_W0W(val) | I2S_RCR5_FBT(0UL);
2069         }
2070     }
2071 
2072     /* Set mono or stereo */
2073     base->RMR = (uint32_t)format->stereo;
2074 
2075     /* if channel mask is not set, then format->channel must be set,
2076      use it to get channel mask value */
2077     if (format->channelMask == 0U)
2078     {
2079         format->channelMask = 1U << format->channel;
2080     }
2081 
2082     /* if channel nums is not set, calculate it here according to channelMask*/
2083     for (i = 0U; i < (uint32_t)FSL_FEATURE_SAI_CHANNEL_COUNTn(base); i++)
2084     {
2085         if (IS_SAI_FLAG_SET((1UL << i), format->channelMask))
2086         {
2087             channelNums++;
2088             format->endChannel = i;
2089         }
2090     }
2091 
2092     for (i = 0U; i < (uint32_t)FSL_FEATURE_SAI_CHANNEL_COUNTn(base); i++)
2093     {
2094         if (IS_SAI_FLAG_SET((1UL << i), format->channelMask))
2095         {
2096             format->channel = i;
2097             break;
2098         }
2099     }
2100 
2101     format->channelNums = channelNums;
2102 
2103 #if defined(FSL_FEATURE_SAI_HAS_FIFO_COMBINE_MODE) && (FSL_FEATURE_SAI_HAS_FIFO_COMBINE_MODE)
2104     /* make sure combine mode disabled while multipe channel is used */
2105     if (format->channelNums > 1U)
2106     {
2107         base->RCR4 &= ~I2S_RCR4_FCOMB_MASK;
2108     }
2109 #endif
2110 
2111     /* Set data channel */
2112     base->RCR3 &= ~I2S_RCR3_RCE_MASK;
2113     /* enable all the channel */
2114     base->RCR3 |= I2S_RCR3_RCE(format->channelMask);
2115 
2116 #if defined(FSL_FEATURE_SAI_HAS_FIFO) && (FSL_FEATURE_SAI_HAS_FIFO)
2117     /* Set watermark */
2118     base->RCR1 = format->watermark;
2119 #endif /* FSL_FEATURE_SAI_HAS_FIFO */
2120 }
2121 
2122 /*!
2123  * brief Sends data using a blocking method.
2124  *
2125  * note This function blocks by polling until data is ready to be sent.
2126  *
2127  * param base SAI base pointer.
2128  * param channel Data channel used.
2129  * param bitWidth How many bits in an audio word; usually 8/16/24/32 bits.
2130  * param buffer Pointer to the data to be written.
2131  * param size Bytes to be written.
2132  */
2133 void SAI_WriteBlocking(I2S_Type *base, uint32_t channel, uint32_t bitWidth, uint8_t *buffer, uint32_t size)
2134 {
2135     uint32_t i            = 0;
2136     uint32_t bytesPerWord = bitWidth / 8U;
2137 #if defined(FSL_FEATURE_SAI_HAS_FIFO) && (FSL_FEATURE_SAI_HAS_FIFO)
2138     bytesPerWord = (((uint32_t)FSL_FEATURE_SAI_FIFO_COUNTn(base) - base->TCR1) * bytesPerWord);
2139 #endif
2140 
2141     while (i < size)
2142     {
2143         /* Wait until it can write data */
2144         while (!(IS_SAI_FLAG_SET(base->TCSR, I2S_TCSR_FWF_MASK)))
2145         {
2146         }
2147 
2148         SAI_WriteNonBlocking(base, channel, 1UL << channel, channel, (uint8_t)bitWidth, buffer, bytesPerWord);
2149         buffer = (uint8_t *)((uintptr_t)buffer + bytesPerWord);
2150         i += bytesPerWord;
2151     }
2152 
2153     /* Wait until the last data is sent */
2154     while (!(IS_SAI_FLAG_SET(base->TCSR, I2S_TCSR_FWF_MASK)))
2155     {
2156     }
2157 }
2158 
2159 /*!
2160  * brief Sends data to multi channel using a blocking method.
2161  *
2162  * note This function blocks by polling until data is ready to be sent.
2163  *
2164  * param base SAI base pointer.
2165  * param channel Data channel used.
2166  * param channelMask channel mask.
2167  * param bitWidth How many bits in an audio word; usually 8/16/24/32 bits.
2168  * param buffer Pointer to the data to be written.
2169  * param size Bytes to be written.
2170  */
2171 void SAI_WriteMultiChannelBlocking(
2172     I2S_Type *base, uint32_t channel, uint32_t channelMask, uint32_t bitWidth, uint8_t *buffer, uint32_t size)
2173 {
2174     assert(FSL_FEATURE_SAI_CHANNEL_COUNTn(base) != -1);
2175 
2176     uint32_t i = 0, j = 0;
2177     uint32_t bytesPerWord = bitWidth / 8U;
2178     uint32_t channelNums = 0U, endChannel = 0U;
2179 
2180 #if defined(FSL_FEATURE_SAI_HAS_FIFO) && (FSL_FEATURE_SAI_HAS_FIFO)
2181     bytesPerWord = (((uint32_t)FSL_FEATURE_SAI_FIFO_COUNTn(base) - base->TCR1) * bytesPerWord);
2182 #endif
2183 
2184     for (i = 0U; (i < (uint32_t)FSL_FEATURE_SAI_CHANNEL_COUNTn(base)); i++)
2185     {
2186         if (IS_SAI_FLAG_SET((1UL << i), channelMask))
2187         {
2188             channelNums++;
2189             endChannel = i;
2190         }
2191     }
2192 
2193     bytesPerWord *= channelNums;
2194 
2195     while (j < size)
2196     {
2197         /* Wait until it can write data */
2198         while (!(IS_SAI_FLAG_SET(base->TCSR, I2S_TCSR_FWF_MASK)))
2199         {
2200         }
2201 
2202         SAI_WriteNonBlocking(base, channel, channelMask, endChannel, (uint8_t)bitWidth, buffer,
2203                              bytesPerWord * channelNums);
2204         buffer = (uint8_t *)((uintptr_t)buffer + bytesPerWord * channelNums);
2205         j += bytesPerWord * channelNums;
2206     }
2207 
2208     /* Wait until the last data is sent */
2209     while (!(IS_SAI_FLAG_SET(base->TCSR, I2S_TCSR_FWF_MASK)))
2210     {
2211     }
2212 }
2213 
2214 /*!
2215  * brief Receives multi channel data using a blocking method.
2216  *
2217  * note This function blocks by polling until data is ready to be sent.
2218  *
2219  * param base SAI base pointer.
2220  * param channel Data channel used.
2221  * param channelMask channel mask.
2222  * param bitWidth How many bits in an audio word; usually 8/16/24/32 bits.
2223  * param buffer Pointer to the data to be read.
2224  * param size Bytes to be read.
2225  */
2226 void SAI_ReadMultiChannelBlocking(
2227     I2S_Type *base, uint32_t channel, uint32_t channelMask, uint32_t bitWidth, uint8_t *buffer, uint32_t size)
2228 {
2229     assert(FSL_FEATURE_SAI_CHANNEL_COUNTn(base) != -1);
2230 
2231     uint32_t i = 0, j = 0;
2232     uint32_t bytesPerWord = bitWidth / 8U;
2233     uint32_t channelNums = 0U, endChannel = 0U;
2234 #if defined(FSL_FEATURE_SAI_HAS_FIFO) && (FSL_FEATURE_SAI_HAS_FIFO)
2235     bytesPerWord = base->RCR1 * bytesPerWord;
2236 #endif
2237     for (i = 0U; (i < (uint32_t)FSL_FEATURE_SAI_CHANNEL_COUNTn(base)); i++)
2238     {
2239         if (IS_SAI_FLAG_SET((1UL << i), channelMask))
2240         {
2241             channelNums++;
2242             endChannel = i;
2243         }
2244     }
2245 
2246     bytesPerWord *= channelNums;
2247 
2248     while (j < size)
2249     {
2250         /* Wait until data is received */
2251         while (!(IS_SAI_FLAG_SET(base->RCSR, I2S_RCSR_FWF_MASK)))
2252         {
2253         }
2254 
2255         SAI_ReadNonBlocking(base, channel, channelMask, endChannel, (uint8_t)bitWidth, buffer,
2256                             bytesPerWord * channelNums);
2257         buffer = (uint8_t *)((uintptr_t)buffer + bytesPerWord * channelNums);
2258         j += bytesPerWord * channelNums;
2259     }
2260 }
2261 
2262 /*!
2263  * brief Receives data using a blocking method.
2264  *
2265  * note This function blocks by polling until data is ready to be sent.
2266  *
2267  * param base SAI base pointer.
2268  * param channel Data channel used.
2269  * param bitWidth How many bits in an audio word; usually 8/16/24/32 bits.
2270  * param buffer Pointer to the data to be read.
2271  * param size Bytes to be read.
2272  */
2273 void SAI_ReadBlocking(I2S_Type *base, uint32_t channel, uint32_t bitWidth, uint8_t *buffer, uint32_t size)
2274 {
2275     uint32_t i            = 0;
2276     uint32_t bytesPerWord = bitWidth / 8U;
2277 #if defined(FSL_FEATURE_SAI_HAS_FIFO) && (FSL_FEATURE_SAI_HAS_FIFO)
2278     bytesPerWord = base->RCR1 * bytesPerWord;
2279 #endif
2280 
2281     while (i < size)
2282     {
2283         /* Wait until data is received */
2284         while (!(IS_SAI_FLAG_SET(base->RCSR, I2S_RCSR_FWF_MASK)))
2285         {
2286         }
2287 
2288         SAI_ReadNonBlocking(base, channel, 1UL << channel, channel, (uint8_t)bitWidth, buffer, bytesPerWord);
2289         buffer = (uint8_t *)((uintptr_t)buffer + bytesPerWord);
2290         i += bytesPerWord;
2291     }
2292 }
2293 
2294 /*!
2295  * brief Initializes the SAI Tx handle.
2296  *
2297  * This function initializes the Tx handle for the SAI Tx transactional APIs. Call
2298  * this function once to get the handle initialized.
2299  *
2300  * param base SAI base pointer
2301  * param handle SAI handle pointer.
2302  * param callback Pointer to the user callback function.
2303  * param userData User parameter passed to the callback function
2304  */
2305 void SAI_TransferTxCreateHandle(I2S_Type *base, sai_handle_t *handle, sai_transfer_callback_t callback, void *userData)
2306 {
2307     assert(handle != NULL);
2308 
2309     /* Zero the handle */
2310     (void)memset(handle, 0, sizeof(*handle));
2311 
2312     s_saiHandle[SAI_GetInstance(base)][0] = handle;
2313 
2314     handle->callback = callback;
2315     handle->userData = userData;
2316     handle->base     = base;
2317 
2318     /* Set the isr pointer */
2319     s_saiTxIsr = SAI_TransferTxHandleIRQ;
2320 
2321     /* Enable Tx irq */
2322     (void)EnableIRQ(s_saiTxIRQ[SAI_GetInstance(base)]);
2323 }
2324 
2325 /*!
2326  * brief Initializes the SAI Rx handle.
2327  *
2328  * This function initializes the Rx handle for the SAI Rx transactional APIs. Call
2329  * this function once to get the handle initialized.
2330  *
2331  * param base SAI base pointer.
2332  * param handle SAI handle pointer.
2333  * param callback Pointer to the user callback function.
2334  * param userData User parameter passed to the callback function.
2335  */
2336 void SAI_TransferRxCreateHandle(I2S_Type *base, sai_handle_t *handle, sai_transfer_callback_t callback, void *userData)
2337 {
2338     assert(handle != NULL);
2339 
2340     /* Zero the handle */
2341     (void)memset(handle, 0, sizeof(*handle));
2342 
2343     s_saiHandle[SAI_GetInstance(base)][1] = handle;
2344 
2345     handle->callback = callback;
2346     handle->userData = userData;
2347     handle->base     = base;
2348 
2349     /* Set the isr pointer */
2350     s_saiRxIsr = SAI_TransferRxHandleIRQ;
2351 
2352     /* Enable Rx irq */
2353     (void)EnableIRQ(s_saiRxIRQ[SAI_GetInstance(base)]);
2354 }
2355 
2356 /*!
2357  * brief Configures the SAI Tx audio format.
2358  *
2359  * deprecated Do not use this function.  It has been superceded by @ref SAI_TransferTxSetConfig
2360  *
2361  * The audio format can be changed at run-time. This function configures the sample rate and audio data
2362  * format to be transferred.
2363  *
2364  * param base SAI base pointer.
2365  * param handle SAI handle pointer.
2366  * param format Pointer to the SAI audio data format structure.
2367  * param mclkSourceClockHz SAI master clock source frequency in Hz.
2368  * param bclkSourceClockHz SAI bit clock source frequency in Hz. If a bit clock source is a master
2369  * clock, this value should equal the masterClockHz in format.
2370  * return Status of this function. Return value is the status_t.
2371  */
2372 status_t SAI_TransferTxSetFormat(I2S_Type *base,
2373                                  sai_handle_t *handle,
2374                                  sai_transfer_format_t *format,
2375                                  uint32_t mclkSourceClockHz,
2376                                  uint32_t bclkSourceClockHz)
2377 {
2378     assert(handle != NULL);
2379 
2380     if ((bclkSourceClockHz < format->sampleRate_Hz)
2381 #if defined(FSL_FEATURE_SAI_HAS_MCLKDIV_REGISTER) && (FSL_FEATURE_SAI_HAS_MCLKDIV_REGISTER)
2382         || (mclkSourceClockHz < format->sampleRate_Hz)
2383 #endif
2384     )
2385     {
2386         return kStatus_InvalidArgument;
2387     }
2388 
2389     /* Copy format to handle */
2390     handle->bitWidth = (uint8_t)format->bitWidth;
2391 #if defined(FSL_FEATURE_SAI_HAS_FIFO) && (FSL_FEATURE_SAI_HAS_FIFO)
2392     handle->watermark = format->watermark;
2393 #endif
2394 
2395     SAI_TxSetFormat(base, format, mclkSourceClockHz, bclkSourceClockHz);
2396 
2397     handle->channel = format->channel;
2398     /* used for multi channel */
2399     handle->channelMask = format->channelMask;
2400     handle->channelNums = format->channelNums;
2401     handle->endChannel  = format->endChannel;
2402 
2403     return kStatus_Success;
2404 }
2405 
2406 /*!
2407  * brief Configures the SAI Rx audio format.
2408  *
2409  * deprecated Do not use this function.  It has been superceded by @ref SAI_TransferRxSetConfig
2410  *
2411  * The audio format can be changed at run-time. This function configures the sample rate and audio data
2412  * format to be transferred.
2413  *
2414  * param base SAI base pointer.
2415  * param handle SAI handle pointer.
2416  * param format Pointer to the SAI audio data format structure.
2417  * param mclkSourceClockHz SAI master clock source frequency in Hz.
2418  * param bclkSourceClockHz SAI bit clock source frequency in Hz. If a bit clock source is a master
2419  * clock, this value should equal the masterClockHz in format.
2420  * return Status of this function. Return value is one of status_t.
2421  */
2422 status_t SAI_TransferRxSetFormat(I2S_Type *base,
2423                                  sai_handle_t *handle,
2424                                  sai_transfer_format_t *format,
2425                                  uint32_t mclkSourceClockHz,
2426                                  uint32_t bclkSourceClockHz)
2427 {
2428     assert(handle != NULL);
2429 
2430     if ((bclkSourceClockHz < format->sampleRate_Hz)
2431 #if defined(FSL_FEATURE_SAI_HAS_MCLKDIV_REGISTER) && (FSL_FEATURE_SAI_HAS_MCLKDIV_REGISTER)
2432         || (mclkSourceClockHz < format->sampleRate_Hz)
2433 #endif
2434     )
2435     {
2436         return kStatus_InvalidArgument;
2437     }
2438 
2439     /* Copy format to handle */
2440     handle->bitWidth = (uint8_t)format->bitWidth;
2441 #if defined(FSL_FEATURE_SAI_HAS_FIFO) && (FSL_FEATURE_SAI_HAS_FIFO)
2442     handle->watermark = format->watermark;
2443 #endif
2444 
2445     SAI_RxSetFormat(base, format, mclkSourceClockHz, bclkSourceClockHz);
2446 
2447     handle->channel = format->channel;
2448     /* used for multi channel */
2449     handle->channelMask = format->channelMask;
2450     handle->channelNums = format->channelNums;
2451     handle->endChannel  = format->endChannel;
2452 
2453     return kStatus_Success;
2454 }
2455 
2456 /*!
2457  * brief Performs an interrupt non-blocking send transfer on SAI.
2458  *
2459  * note This API returns immediately after the transfer initiates.
2460  * Call the SAI_TxGetTransferStatusIRQ to poll the transfer status and check whether
2461  * the transfer is finished. If the return status is not kStatus_SAI_Busy, the transfer
2462  * is finished.
2463  *
2464  * param base SAI base pointer.
2465  * param handle Pointer to the sai_handle_t structure which stores the transfer state.
2466  * param xfer Pointer to the sai_transfer_t structure.
2467  * retval kStatus_Success Successfully started the data receive.
2468  * retval kStatus_SAI_TxBusy Previous receive still not finished.
2469  * retval kStatus_InvalidArgument The input parameter is invalid.
2470  */
2471 status_t SAI_TransferSendNonBlocking(I2S_Type *base, sai_handle_t *handle, sai_transfer_t *xfer)
2472 {
2473     assert(handle != NULL);
2474     assert(handle->channelNums <= (uint32_t)FSL_FEATURE_SAI_CHANNEL_COUNTn(base));
2475 
2476     /* Check if the queue is full */
2477     if (handle->saiQueue[handle->queueUser].data != NULL)
2478     {
2479         return kStatus_SAI_QueueFull;
2480     }
2481 
2482     /* Add into queue */
2483     handle->transferSize[handle->queueUser]      = xfer->dataSize;
2484     handle->saiQueue[handle->queueUser].data     = xfer->data;
2485     handle->saiQueue[handle->queueUser].dataSize = xfer->dataSize;
2486     handle->queueUser                            = (handle->queueUser + 1U) % (uint8_t)SAI_XFER_QUEUE_SIZE;
2487 
2488     /* Set the state to busy */
2489     handle->state = (uint32_t)kSAI_Busy;
2490 
2491     /* Enable interrupt */
2492 #if defined(FSL_FEATURE_SAI_HAS_FIFO) && (FSL_FEATURE_SAI_HAS_FIFO)
2493     /* Use FIFO request interrupt and fifo error*/
2494     SAI_TxEnableInterrupts(base, I2S_TCSR_FEIE_MASK | I2S_TCSR_FRIE_MASK);
2495 #else
2496     SAI_TxEnableInterrupts(base, I2S_TCSR_FEIE_MASK | I2S_TCSR_FWIE_MASK);
2497 #endif /* FSL_FEATURE_SAI_HAS_FIFO */
2498 
2499     /* Enable Tx transfer */
2500     SAI_TxEnable(base, true);
2501 
2502     return kStatus_Success;
2503 }
2504 
2505 /*!
2506  * brief Performs an interrupt non-blocking receive transfer on SAI.
2507  *
2508  * note This API returns immediately after the transfer initiates.
2509  * Call the SAI_RxGetTransferStatusIRQ to poll the transfer status and check whether
2510  * the transfer is finished. If the return status is not kStatus_SAI_Busy, the transfer
2511  * is finished.
2512  *
2513  * param base SAI base pointer
2514  * param handle Pointer to the sai_handle_t structure which stores the transfer state.
2515  * param xfer Pointer to the sai_transfer_t structure.
2516  * retval kStatus_Success Successfully started the data receive.
2517  * retval kStatus_SAI_RxBusy Previous receive still not finished.
2518  * retval kStatus_InvalidArgument The input parameter is invalid.
2519  */
2520 status_t SAI_TransferReceiveNonBlocking(I2S_Type *base, sai_handle_t *handle, sai_transfer_t *xfer)
2521 {
2522     assert(handle != NULL);
2523     assert(handle->channelNums <= (uint32_t)FSL_FEATURE_SAI_CHANNEL_COUNTn(base));
2524 
2525     /* Check if the queue is full */
2526     if (handle->saiQueue[handle->queueUser].data != NULL)
2527     {
2528         return kStatus_SAI_QueueFull;
2529     }
2530 
2531     /* Add into queue */
2532     handle->transferSize[handle->queueUser]      = xfer->dataSize;
2533     handle->saiQueue[handle->queueUser].data     = xfer->data;
2534     handle->saiQueue[handle->queueUser].dataSize = xfer->dataSize;
2535     handle->queueUser                            = (handle->queueUser + 1U) % (uint8_t)SAI_XFER_QUEUE_SIZE;
2536 
2537     /* Set state to busy */
2538     handle->state = (uint32_t)kSAI_Busy;
2539 
2540 /* Enable interrupt */
2541 #if defined(FSL_FEATURE_SAI_HAS_FIFO) && (FSL_FEATURE_SAI_HAS_FIFO)
2542     /* Use FIFO request interrupt and fifo error*/
2543     SAI_RxEnableInterrupts(base, I2S_TCSR_FEIE_MASK | I2S_TCSR_FRIE_MASK);
2544 #else
2545     SAI_RxEnableInterrupts(base, I2S_TCSR_FEIE_MASK | I2S_TCSR_FWIE_MASK);
2546 #endif /* FSL_FEATURE_SAI_HAS_FIFO */
2547 
2548     /* Enable Rx transfer */
2549     SAI_RxEnable(base, true);
2550 
2551     return kStatus_Success;
2552 }
2553 
2554 /*!
2555  * brief Gets a set byte count.
2556  *
2557  * param base SAI base pointer.
2558  * param handle Pointer to the sai_handle_t structure which stores the transfer state.
2559  * param count Bytes count sent.
2560  * retval kStatus_Success Succeed get the transfer count.
2561  * retval kStatus_NoTransferInProgress There is not a non-blocking transaction currently in progress.
2562  */
2563 status_t SAI_TransferGetSendCount(I2S_Type *base, sai_handle_t *handle, size_t *count)
2564 {
2565     assert(handle != NULL);
2566 
2567     status_t status           = kStatus_Success;
2568     uint32_t queueDriverIndex = handle->queueDriver;
2569 
2570     if (handle->state != (uint32_t)kSAI_Busy)
2571     {
2572         status = kStatus_NoTransferInProgress;
2573     }
2574     else
2575     {
2576         *count = (handle->transferSize[queueDriverIndex] - handle->saiQueue[queueDriverIndex].dataSize);
2577     }
2578 
2579     return status;
2580 }
2581 
2582 /*!
2583  * brief Gets a received byte count.
2584  *
2585  * param base SAI base pointer.
2586  * param handle Pointer to the sai_handle_t structure which stores the transfer state.
2587  * param count Bytes count received.
2588  * retval kStatus_Success Succeed get the transfer count.
2589  * retval kStatus_NoTransferInProgress There is not a non-blocking transaction currently in progress.
2590  */
2591 status_t SAI_TransferGetReceiveCount(I2S_Type *base, sai_handle_t *handle, size_t *count)
2592 {
2593     assert(handle != NULL);
2594 
2595     status_t status           = kStatus_Success;
2596     uint32_t queueDriverIndex = handle->queueDriver;
2597 
2598     if (handle->state != (uint32_t)kSAI_Busy)
2599     {
2600         status = kStatus_NoTransferInProgress;
2601     }
2602     else
2603     {
2604         *count = (handle->transferSize[queueDriverIndex] - handle->saiQueue[queueDriverIndex].dataSize);
2605     }
2606 
2607     return status;
2608 }
2609 
2610 /*!
2611  * brief Aborts the current send.
2612  *
2613  * note This API can be called any time when an interrupt non-blocking transfer initiates
2614  * to abort the transfer early.
2615  *
2616  * param base SAI base pointer.
2617  * param handle Pointer to the sai_handle_t structure which stores the transfer state.
2618  */
2619 void SAI_TransferAbortSend(I2S_Type *base, sai_handle_t *handle)
2620 {
2621     assert(handle != NULL);
2622 
2623     /* Stop Tx transfer and disable interrupt */
2624     SAI_TxEnable(base, false);
2625 #if defined(FSL_FEATURE_SAI_HAS_FIFO) && (FSL_FEATURE_SAI_HAS_FIFO)
2626     /* Use FIFO request interrupt and fifo error */
2627     SAI_TxDisableInterrupts(base, I2S_TCSR_FEIE_MASK | I2S_TCSR_FRIE_MASK);
2628 #else
2629     SAI_TxDisableInterrupts(base, I2S_TCSR_FEIE_MASK | I2S_TCSR_FWIE_MASK);
2630 #endif /* FSL_FEATURE_SAI_HAS_FIFO */
2631 
2632     handle->state = (uint32_t)kSAI_Idle;
2633 
2634     /* Clear the queue */
2635     (void)memset(handle->saiQueue, 0, sizeof(sai_transfer_t) * (uint8_t)SAI_XFER_QUEUE_SIZE);
2636     handle->queueDriver = 0;
2637     handle->queueUser   = 0;
2638 }
2639 
2640 /*!
2641  * brief Aborts the current IRQ receive.
2642  *
2643  * note This API can be called when an interrupt non-blocking transfer initiates
2644  * to abort the transfer early.
2645  *
2646  * param base SAI base pointer
2647  * param handle Pointer to the sai_handle_t structure which stores the transfer state.
2648  */
2649 void SAI_TransferAbortReceive(I2S_Type *base, sai_handle_t *handle)
2650 {
2651     assert(handle != NULL);
2652 
2653     /* Stop Tx transfer and disable interrupt */
2654     SAI_RxEnable(base, false);
2655 #if defined(FSL_FEATURE_SAI_HAS_FIFO) && (FSL_FEATURE_SAI_HAS_FIFO)
2656     /* Use FIFO request interrupt and fifo error */
2657     SAI_RxDisableInterrupts(base, I2S_TCSR_FEIE_MASK | I2S_TCSR_FRIE_MASK);
2658 #else
2659     SAI_RxDisableInterrupts(base, I2S_TCSR_FEIE_MASK | I2S_TCSR_FWIE_MASK);
2660 #endif /* FSL_FEATURE_SAI_HAS_FIFO */
2661 
2662     handle->state = (uint32_t)kSAI_Idle;
2663 
2664     /* Clear the queue */
2665     (void)memset(handle->saiQueue, 0, sizeof(sai_transfer_t) * (uint8_t)SAI_XFER_QUEUE_SIZE);
2666     handle->queueDriver = 0;
2667     handle->queueUser   = 0;
2668 }
2669 
2670 /*!
2671  * brief Terminate all SAI send.
2672  *
2673  * This function will clear all transfer slots buffered in the sai queue. If users only want to abort the
2674  * current transfer slot, please call SAI_TransferAbortSend.
2675  *
2676  * param base SAI base pointer.
2677  * param handle SAI eDMA handle pointer.
2678  */
2679 void SAI_TransferTerminateSend(I2S_Type *base, sai_handle_t *handle)
2680 {
2681     assert(handle != NULL);
2682 
2683     /* Abort the current transfer */
2684     SAI_TransferAbortSend(base, handle);
2685 
2686     /* Clear all the internal information */
2687     (void)memset(handle->saiQueue, 0, sizeof(handle->saiQueue));
2688     (void)memset(handle->transferSize, 0, sizeof(handle->transferSize));
2689 
2690     handle->queueUser   = 0U;
2691     handle->queueDriver = 0U;
2692 }
2693 
2694 /*!
2695  * brief Terminate all SAI receive.
2696  *
2697  * This function will clear all transfer slots buffered in the sai queue. If users only want to abort the
2698  * current transfer slot, please call SAI_TransferAbortReceive.
2699  *
2700  * param base SAI base pointer.
2701  * param handle SAI eDMA handle pointer.
2702  */
2703 void SAI_TransferTerminateReceive(I2S_Type *base, sai_handle_t *handle)
2704 {
2705     assert(handle != NULL);
2706 
2707     /* Abort the current transfer */
2708     SAI_TransferAbortReceive(base, handle);
2709 
2710     /* Clear all the internal information */
2711     (void)memset(handle->saiQueue, 0, sizeof(handle->saiQueue));
2712     (void)memset(handle->transferSize, 0, sizeof(handle->transferSize));
2713 
2714     handle->queueUser   = 0U;
2715     handle->queueDriver = 0U;
2716 }
2717 
2718 /*!
2719  * brief Tx interrupt handler.
2720  *
2721  * param base SAI base pointer.
2722  * param handle Pointer to the sai_handle_t structure.
2723  */
2724 void SAI_TransferTxHandleIRQ(I2S_Type *base, sai_handle_t *handle)
2725 {
2726     assert(handle != NULL);
2727 
2728     uint8_t *buffer   = handle->saiQueue[handle->queueDriver].data;
2729     uint32_t dataSize = (handle->bitWidth / 8UL) * handle->channelNums;
2730 
2731     /* Handle Error */
2732     if (IS_SAI_FLAG_SET(base->TCSR, I2S_TCSR_FEF_MASK))
2733     {
2734         /* Clear FIFO error flag to continue transfer */
2735         SAI_TxClearStatusFlags(base, I2S_TCSR_FEF_MASK);
2736 
2737         /* Reset FIFO for safety */
2738         SAI_TxSoftwareReset(base, kSAI_ResetTypeFIFO);
2739 
2740         /* Call the callback */
2741         if (handle->callback != NULL)
2742         {
2743             (handle->callback)(base, handle, kStatus_SAI_TxError, handle->userData);
2744         }
2745     }
2746 
2747 /* Handle transfer */
2748 #if defined(FSL_FEATURE_SAI_HAS_FIFO) && (FSL_FEATURE_SAI_HAS_FIFO)
2749     if (IS_SAI_FLAG_SET(base->TCSR, I2S_TCSR_FRF_MASK))
2750     {
2751         /* Judge if the data need to transmit is less than space */
2752         size_t size = MIN((handle->saiQueue[handle->queueDriver].dataSize),
2753                           (size_t)(((uint32_t)FSL_FEATURE_SAI_FIFO_COUNTn(base) - handle->watermark) * dataSize));
2754 
2755         /* Copy the data from sai buffer to FIFO */
2756         SAI_WriteNonBlocking(base, handle->channel, handle->channelMask, handle->endChannel, handle->bitWidth, buffer,
2757                              size);
2758 
2759         /* Update the internal counter */
2760         handle->saiQueue[handle->queueDriver].dataSize -= size;
2761         handle->saiQueue[handle->queueDriver].data = (uint8_t *)((uintptr_t)buffer + size);
2762     }
2763 #else
2764     if (IS_SAI_FLAG_SET(base->TCSR, I2S_TCSR_FWF_MASK))
2765     {
2766         size_t size = MIN((handle->saiQueue[handle->queueDriver].dataSize), dataSize);
2767 
2768         SAI_WriteNonBlocking(base, handle->channel, handle->channelMask, handle->endChannel, handle->bitWidth, buffer,
2769                              size);
2770 
2771         /* Update internal counter */
2772         handle->saiQueue[handle->queueDriver].dataSize -= size;
2773         handle->saiQueue[handle->queueDriver].data = (uint8_t *)((uintptr_t)buffer + size);
2774     }
2775 #endif /* FSL_FEATURE_SAI_HAS_FIFO */
2776 
2777     /* If finished a block, call the callback function */
2778     if (handle->saiQueue[handle->queueDriver].dataSize == 0U)
2779     {
2780         (void)memset(&handle->saiQueue[handle->queueDriver], 0, sizeof(sai_transfer_t));
2781         handle->queueDriver = (handle->queueDriver + 1U) % (uint8_t)SAI_XFER_QUEUE_SIZE;
2782         if (handle->callback != NULL)
2783         {
2784             (handle->callback)(base, handle, kStatus_SAI_TxIdle, handle->userData);
2785         }
2786     }
2787 
2788     /* If all data finished, just stop the transfer */
2789     if (handle->saiQueue[handle->queueDriver].data == NULL)
2790     {
2791         SAI_TransferAbortSend(base, handle);
2792     }
2793 }
2794 
2795 /*!
2796  * brief Tx interrupt handler.
2797  *
2798  * param base SAI base pointer.
2799  * param handle Pointer to the sai_handle_t structure.
2800  */
2801 void SAI_TransferRxHandleIRQ(I2S_Type *base, sai_handle_t *handle)
2802 {
2803     assert(handle != NULL);
2804 
2805     uint8_t *buffer   = handle->saiQueue[handle->queueDriver].data;
2806     uint32_t dataSize = (handle->bitWidth / 8UL) * handle->channelNums;
2807 
2808     /* Handle Error */
2809     if (IS_SAI_FLAG_SET(base->RCSR, I2S_RCSR_FEF_MASK))
2810     {
2811         /* Clear FIFO error flag to continue transfer */
2812         SAI_RxClearStatusFlags(base, I2S_TCSR_FEF_MASK);
2813 
2814         /* Reset FIFO for safety */
2815         SAI_RxSoftwareReset(base, kSAI_ResetTypeFIFO);
2816 
2817         /* Call the callback */
2818         if (handle->callback != NULL)
2819         {
2820             (handle->callback)(base, handle, kStatus_SAI_RxError, handle->userData);
2821         }
2822     }
2823 
2824 /* Handle transfer */
2825 #if defined(FSL_FEATURE_SAI_HAS_FIFO) && (FSL_FEATURE_SAI_HAS_FIFO)
2826     if (IS_SAI_FLAG_SET(base->RCSR, I2S_RCSR_FRF_MASK))
2827     {
2828         /* Judge if the data need to transmit is less than space */
2829         size_t size = MIN((handle->saiQueue[handle->queueDriver].dataSize), handle->watermark * dataSize);
2830 
2831         /* Copy the data from sai buffer to FIFO */
2832         SAI_ReadNonBlocking(base, handle->channel, handle->channelMask, handle->endChannel, handle->bitWidth, buffer,
2833                             size);
2834 
2835         /* Update the internal counter */
2836         handle->saiQueue[handle->queueDriver].dataSize -= size;
2837         handle->saiQueue[handle->queueDriver].data = (uint8_t *)((uintptr_t)buffer + size);
2838     }
2839 #else
2840     if (IS_SAI_FLAG_SET(base->RCSR, I2S_RCSR_FWF_MASK))
2841     {
2842         size_t size = MIN((handle->saiQueue[handle->queueDriver].dataSize), dataSize);
2843 
2844         SAI_ReadNonBlocking(base, handle->channel, handle->channelMask, handle->endChannel, handle->bitWidth, buffer,
2845                             size);
2846 
2847         /* Update internal state */
2848         handle->saiQueue[handle->queueDriver].dataSize -= size;
2849         handle->saiQueue[handle->queueDriver].data = (uint8_t *)((uintptr_t)buffer + size);
2850     }
2851 #endif /* FSL_FEATURE_SAI_HAS_FIFO */
2852 
2853     /* If finished a block, call the callback function */
2854     if (handle->saiQueue[handle->queueDriver].dataSize == 0U)
2855     {
2856         (void)memset(&handle->saiQueue[handle->queueDriver], 0, sizeof(sai_transfer_t));
2857         handle->queueDriver = (handle->queueDriver + 1U) % (uint8_t)SAI_XFER_QUEUE_SIZE;
2858         if (handle->callback != NULL)
2859         {
2860             (handle->callback)(base, handle, kStatus_SAI_RxIdle, handle->userData);
2861         }
2862     }
2863 
2864     /* If all data finished, just stop the transfer */
2865     if (handle->saiQueue[handle->queueDriver].data == NULL)
2866     {
2867         SAI_TransferAbortReceive(base, handle);
2868     }
2869 }
2870 
2871 #if defined(I2S0)
2872 void I2S0_DriverIRQHandler(void);
2873 void I2S0_DriverIRQHandler(void)
2874 {
2875 #if defined(FSL_FEATURE_SAI_HAS_FIFO) && (FSL_FEATURE_SAI_HAS_FIFO)
2876     if ((s_saiHandle[0][1] != NULL) && SAI_RxGetEnabledInterruptStatus(I2S0, (I2S_TCSR_FRIE_MASK | I2S_TCSR_FEIE_MASK),
2877                                                                        (I2S_TCSR_FRF_MASK | I2S_TCSR_FEF_MASK)))
2878 #else
2879     if ((s_saiHandle[0][1] != NULL) && SAI_RxGetEnabledInterruptStatus(I2S0, (I2S_TCSR_FWIE_MASK | I2S_TCSR_FEIE_MASK),
2880                                                                        (I2S_TCSR_FWF_MASK | I2S_TCSR_FEF_MASK)))
2881 #endif
2882     {
2883         s_saiRxIsr(I2S0, s_saiHandle[0][1]);
2884     }
2885 #if defined(FSL_FEATURE_SAI_HAS_FIFO) && (FSL_FEATURE_SAI_HAS_FIFO)
2886     if ((s_saiHandle[0][0] != NULL) && SAI_TxGetEnabledInterruptStatus(I2S0, (I2S_TCSR_FRIE_MASK | I2S_TCSR_FEIE_MASK),
2887                                                                        (I2S_TCSR_FRF_MASK | I2S_TCSR_FEF_MASK)))
2888 #else
2889     if ((s_saiHandle[0][0] != NULL) && SAI_TxGetEnabledInterruptStatus(I2S0, (I2S_TCSR_FWIE_MASK | I2S_TCSR_FEIE_MASK),
2890                                                                        (I2S_TCSR_FWF_MASK | I2S_TCSR_FEF_MASK)))
2891 #endif
2892     {
2893         s_saiTxIsr(I2S0, s_saiHandle[0][0]);
2894     }
2895     SDK_ISR_EXIT_BARRIER;
2896 }
2897 
2898 void I2S0_Tx_DriverIRQHandler(void);
2899 void I2S0_Tx_DriverIRQHandler(void)
2900 {
2901     assert(s_saiHandle[0][0] != NULL);
2902     s_saiTxIsr(I2S0, s_saiHandle[0][0]);
2903     SDK_ISR_EXIT_BARRIER;
2904 }
2905 
2906 void I2S0_Rx_DriverIRQHandler(void);
2907 void I2S0_Rx_DriverIRQHandler(void)
2908 {
2909     assert(s_saiHandle[0][1] != NULL);
2910     s_saiRxIsr(I2S0, s_saiHandle[0][1]);
2911     SDK_ISR_EXIT_BARRIER;
2912 }
2913 #endif /* I2S0*/
2914 
2915 #if defined(I2S1)
2916 void I2S1_DriverIRQHandler(void);
2917 void I2S1_DriverIRQHandler(void)
2918 {
2919 #if defined(FSL_FEATURE_SAI_HAS_FIFO) && (FSL_FEATURE_SAI_HAS_FIFO)
2920     if ((s_saiHandle[1][1] != NULL) && SAI_RxGetEnabledInterruptStatus(I2S1, (I2S_TCSR_FRIE_MASK | I2S_TCSR_FEIE_MASK),
2921                                                                        (I2S_TCSR_FRF_MASK | I2S_TCSR_FEF_MASK)))
2922 #else
2923     if ((s_saiHandle[1][1] != NULL) && SAI_RxGetEnabledInterruptStatus(I2S1, (I2S_TCSR_FWIE_MASK | I2S_TCSR_FEIE_MASK),
2924                                                                        (I2S_TCSR_FWF_MASK | I2S_TCSR_FEF_MASK)))
2925 #endif
2926     {
2927         s_saiRxIsr(I2S1, s_saiHandle[1][1]);
2928     }
2929 
2930 #if defined(FSL_FEATURE_SAI_HAS_FIFO) && (FSL_FEATURE_SAI_HAS_FIFO)
2931     if ((s_saiHandle[1][0] != NULL) && SAI_TxGetEnabledInterruptStatus(I2S1, (I2S_TCSR_FRIE_MASK | I2S_TCSR_FEIE_MASK),
2932                                                                        (I2S_TCSR_FRF_MASK | I2S_TCSR_FEF_MASK)))
2933 #else
2934     if ((s_saiHandle[1][0] != NULL) && SAI_TxGetEnabledInterruptStatus(I2S1, (I2S_TCSR_FWIE_MASK | I2S_TCSR_FEIE_MASK),
2935                                                                        (I2S_TCSR_FWF_MASK | I2S_TCSR_FEF_MASK)))
2936 #endif
2937     {
2938         s_saiTxIsr(I2S1, s_saiHandle[1][0]);
2939     }
2940     SDK_ISR_EXIT_BARRIER;
2941 }
2942 
2943 void I2S1_Tx_DriverIRQHandler(void);
2944 void I2S1_Tx_DriverIRQHandler(void)
2945 {
2946     assert(s_saiHandle[1][0] != NULL);
2947     s_saiTxIsr(I2S1, s_saiHandle[1][0]);
2948     SDK_ISR_EXIT_BARRIER;
2949 }
2950 
2951 void I2S1_Rx_DriverIRQHandler(void);
2952 void I2S1_Rx_DriverIRQHandler(void)
2953 {
2954     assert(s_saiHandle[1][1] != NULL);
2955     s_saiRxIsr(I2S1, s_saiHandle[1][1]);
2956     SDK_ISR_EXIT_BARRIER;
2957 }
2958 #endif /* I2S1*/
2959 
2960 #if defined(I2S2)
2961 void I2S2_DriverIRQHandler(void);
2962 void I2S2_DriverIRQHandler(void)
2963 {
2964 #if defined(FSL_FEATURE_SAI_HAS_FIFO) && (FSL_FEATURE_SAI_HAS_FIFO)
2965     if ((s_saiHandle[2][1] != NULL) && SAI_RxGetEnabledInterruptStatus(I2S2, (I2S_TCSR_FRIE_MASK | I2S_TCSR_FEIE_MASK),
2966                                                                        (I2S_TCSR_FRF_MASK | I2S_TCSR_FEF_MASK)))
2967 #else
2968     if ((s_saiHandle[2][1] != NULL) && SAI_RxGetEnabledInterruptStatus(I2S2, (I2S_TCSR_FWIE_MASK | I2S_TCSR_FEIE_MASK),
2969                                                                        (I2S_TCSR_FWF_MASK | I2S_TCSR_FEF_MASK)))
2970 #endif
2971     {
2972         s_saiRxIsr(I2S2, s_saiHandle[2][1]);
2973     }
2974 
2975 #if defined(FSL_FEATURE_SAI_HAS_FIFO) && (FSL_FEATURE_SAI_HAS_FIFO)
2976     if ((s_saiHandle[2][0] != NULL) && SAI_TxGetEnabledInterruptStatus(I2S2, (I2S_TCSR_FRIE_MASK | I2S_TCSR_FEIE_MASK),
2977                                                                        (I2S_TCSR_FRF_MASK | I2S_TCSR_FEF_MASK)))
2978 #else
2979     if ((s_saiHandle[2][0] != NULL) && SAI_TxGetEnabledInterruptStatus(I2S2, (I2S_TCSR_FWIE_MASK | I2S_TCSR_FEIE_MASK),
2980                                                                        (I2S_TCSR_FWF_MASK | I2S_TCSR_FEF_MASK)))
2981 #endif
2982     {
2983         s_saiTxIsr(I2S2, s_saiHandle[2][0]);
2984     }
2985     SDK_ISR_EXIT_BARRIER;
2986 }
2987 
2988 void I2S2_Tx_DriverIRQHandler(void);
2989 void I2S2_Tx_DriverIRQHandler(void)
2990 {
2991     assert(s_saiHandle[2][0] != NULL);
2992     s_saiTxIsr(I2S2, s_saiHandle[2][0]);
2993     SDK_ISR_EXIT_BARRIER;
2994 }
2995 
2996 void I2S2_Rx_DriverIRQHandler(void);
2997 void I2S2_Rx_DriverIRQHandler(void)
2998 {
2999     assert(s_saiHandle[2][1] != NULL);
3000     s_saiRxIsr(I2S2, s_saiHandle[2][1]);
3001     SDK_ISR_EXIT_BARRIER;
3002 }
3003 #endif /* I2S2*/
3004 
3005 #if defined(I2S3)
3006 void I2S3_DriverIRQHandler(void);
3007 void I2S3_DriverIRQHandler(void)
3008 {
3009 #if defined(FSL_FEATURE_SAI_HAS_FIFO) && (FSL_FEATURE_SAI_HAS_FIFO)
3010     if ((s_saiHandle[3][1] != NULL) && SAI_RxGetEnabledInterruptStatus(I2S3, (I2S_TCSR_FRIE_MASK | I2S_TCSR_FEIE_MASK),
3011                                                                        (I2S_TCSR_FRF_MASK | I2S_TCSR_FEF_MASK)))
3012 #else
3013     if ((s_saiHandle[3][1] != NULL) && SAI_RxGetEnabledInterruptStatus(I2S3, (I2S_TCSR_FWIE_MASK | I2S_TCSR_FEIE_MASK),
3014                                                                        (I2S_TCSR_FWF_MASK | I2S_TCSR_FEF_MASK)))
3015 #endif
3016     {
3017         s_saiRxIsr(I2S3, s_saiHandle[3][1]);
3018     }
3019 #if defined(FSL_FEATURE_SAI_HAS_FIFO) && (FSL_FEATURE_SAI_HAS_FIFO)
3020     if ((s_saiHandle[3][0] != NULL) && SAI_TxGetEnabledInterruptStatus(I2S3, (I2S_TCSR_FRIE_MASK | I2S_TCSR_FEIE_MASK),
3021                                                                        (I2S_TCSR_FRF_MASK | I2S_TCSR_FEF_MASK)))
3022 #else
3023     if ((s_saiHandle[3][0] != NULL) && SAI_TxGetEnabledInterruptStatus(I2S3, (I2S_TCSR_FWIE_MASK | I2S_TCSR_FEIE_MASK),
3024                                                                        (I2S_TCSR_FWF_MASK | I2S_TCSR_FEF_MASK)))
3025 #endif
3026     {
3027         s_saiTxIsr(I2S3, s_saiHandle[3][0]);
3028     }
3029     SDK_ISR_EXIT_BARRIER;
3030 }
3031 
3032 void I2S3_Tx_DriverIRQHandler(void);
3033 void I2S3_Tx_DriverIRQHandler(void)
3034 {
3035     assert(s_saiHandle[3][0] != NULL);
3036     s_saiTxIsr(I2S3, s_saiHandle[3][0]);
3037     SDK_ISR_EXIT_BARRIER;
3038 }
3039 
3040 void I2S3_Rx_DriverIRQHandler(void);
3041 void I2S3_Rx_DriverIRQHandler(void)
3042 {
3043     assert(s_saiHandle[3][1] != NULL);
3044     s_saiRxIsr(I2S3, s_saiHandle[3][1]);
3045     SDK_ISR_EXIT_BARRIER;
3046 }
3047 #endif /* I2S3*/
3048 
3049 #if defined(I2S4)
3050 void I2S4_DriverIRQHandler(void);
3051 void I2S4_DriverIRQHandler(void)
3052 {
3053 #if defined(FSL_FEATURE_SAI_HAS_FIFO) && (FSL_FEATURE_SAI_HAS_FIFO)
3054     if ((s_saiHandle[4][1] != NULL) && SAI_RxGetEnabledInterruptStatus(I2S4, (I2S_TCSR_FRIE_MASK | I2S_TCSR_FEIE_MASK),
3055                                                                        (I2S_TCSR_FRF_MASK | I2S_TCSR_FEF_MASK)))
3056 #else
3057     if ((s_saiHandle[4][1] != NULL) && SAI_RxGetEnabledInterruptStatus(I2S4, (I2S_TCSR_FWIE_MASK | I2S_TCSR_FEIE_MASK),
3058                                                                        (I2S_TCSR_FWF_MASK | I2S_TCSR_FEF_MASK)))
3059 #endif
3060     {
3061         s_saiRxIsr(I2S4, s_saiHandle[4][1]);
3062     }
3063 
3064 #if defined(FSL_FEATURE_SAI_HAS_FIFO) && (FSL_FEATURE_SAI_HAS_FIFO)
3065     if ((s_saiHandle[4][0] != NULL) && SAI_TxGetEnabledInterruptStatus(I2S4, (I2S_TCSR_FRIE_MASK | I2S_TCSR_FEIE_MASK),
3066                                                                        (I2S_TCSR_FRF_MASK | I2S_TCSR_FEF_MASK)))
3067 #else
3068     if ((s_saiHandle[4][0] != NULL) && SAI_TxGetEnabledInterruptStatus(I2S4, (I2S_TCSR_FWIE_MASK | I2S_TCSR_FEIE_MASK),
3069                                                                        (I2S_TCSR_FWF_MASK | I2S_TCSR_FEF_MASK)))
3070 #endif
3071     {
3072         s_saiTxIsr(I2S4, s_saiHandle[4][0]);
3073     }
3074     SDK_ISR_EXIT_BARRIER;
3075 }
3076 
3077 void I2S4_Tx_DriverIRQHandler(void);
3078 void I2S4_Tx_DriverIRQHandler(void)
3079 {
3080     assert(s_saiHandle[4][0] != NULL);
3081     s_saiTxIsr(I2S4, s_saiHandle[4][0]);
3082     SDK_ISR_EXIT_BARRIER;
3083 }
3084 
3085 void I2S4_Rx_DriverIRQHandler(void);
3086 void I2S4_Rx_DriverIRQHandler(void)
3087 {
3088     assert(s_saiHandle[4][1] != NULL);
3089     s_saiRxIsr(I2S4, s_saiHandle[4][1]);
3090     SDK_ISR_EXIT_BARRIER;
3091 }
3092 #endif
3093 
3094 #if defined(FSL_FEATURE_SAI_SAI5_SAI6_SHARE_IRQ) && (FSL_FEATURE_SAI_SAI5_SAI6_SHARE_IRQ) && defined(I2S5) && \
3095     defined(I2S6)
3096 void I2S56_DriverIRQHandler(void);
3097 void I2S56_DriverIRQHandler(void)
3098 {
3099     /* use index 5 to get handle when I2S5 & I2S6 share IRQ NUMBER */
3100     I2S_Type *base = s_saiHandle[5][1]->base;
3101 #if defined(FSL_FEATURE_SAI_HAS_FIFO) && (FSL_FEATURE_SAI_HAS_FIFO)
3102     if ((s_saiHandle[5][1] != NULL) && SAI_RxGetEnabledInterruptStatus(base, (I2S_TCSR_FRIE_MASK | I2S_TCSR_FEIE_MASK),
3103                                                                        (I2S_TCSR_FRF_MASK | I2S_TCSR_FEF_MASK)))
3104 #else
3105     if ((s_saiHandle[5][1] != NULL) && SAI_RxGetEnabledInterruptStatus(base, (I2S_TCSR_FWIE_MASK | I2S_TCSR_FEIE_MASK),
3106                                                                        (I2S_TCSR_FWF_MASK | I2S_TCSR_FEF_MASK)))
3107 #endif
3108     {
3109         s_saiRxIsr(base, s_saiHandle[5][1]);
3110     }
3111 
3112     base = s_saiHandle[5][0]->base;
3113 #if defined(FSL_FEATURE_SAI_HAS_FIFO) && (FSL_FEATURE_SAI_HAS_FIFO)
3114     if ((s_saiHandle[5][0] != NULL) && SAI_TxGetEnabledInterruptStatus(base, (I2S_TCSR_FRIE_MASK | I2S_TCSR_FEIE_MASK),
3115                                                                        (I2S_TCSR_FRF_MASK | I2S_TCSR_FEF_MASK)))
3116 #else
3117     if ((s_saiHandle[5][0] != NULL) && SAI_TxGetEnabledInterruptStatus(base, (I2S_TCSR_FWIE_MASK | I2S_TCSR_FEIE_MASK),
3118                                                                        (I2S_TCSR_FWF_MASK | I2S_TCSR_FEF_MASK)))
3119 #endif
3120     {
3121         s_saiTxIsr(base, s_saiHandle[5][0]);
3122     }
3123     SDK_ISR_EXIT_BARRIER;
3124 }
3125 
3126 void I2S56_Tx_DriverIRQHandler(void);
3127 void I2S56_Tx_DriverIRQHandler(void)
3128 {
3129     /* use index 5 to get handle when I2S5 & I2S6 share IRQ NUMBER */
3130     assert(s_saiHandle[5][0] != NULL);
3131     s_saiTxIsr(s_saiHandle[5][0]->base, s_saiHandle[5][0]);
3132     SDK_ISR_EXIT_BARRIER;
3133 }
3134 
3135 void I2S56_Rx_DriverIRQHandler(void);
3136 void I2S56_Rx_DriverIRQHandler(void)
3137 {
3138     /* use index 5 to get handle when I2S5 & I2S6 share IRQ NUMBER */
3139     assert(s_saiHandle[5][1] != NULL);
3140     s_saiRxIsr(s_saiHandle[5][1]->base, s_saiHandle[5][1]);
3141     SDK_ISR_EXIT_BARRIER;
3142 }
3143 
3144 #else
3145 
3146 #if defined(I2S5)
3147 void I2S5_DriverIRQHandler(void);
3148 void I2S5_DriverIRQHandler(void)
3149 {
3150 #if defined(FSL_FEATURE_SAI_HAS_FIFO) && (FSL_FEATURE_SAI_HAS_FIFO)
3151     if ((s_saiHandle[5][1] != NULL) && SAI_RxGetEnabledInterruptStatus(I2S5, (I2S_TCSR_FRIE_MASK | I2S_TCSR_FEIE_MASK),
3152                                                                        (I2S_TCSR_FRF_MASK | I2S_TCSR_FEF_MASK)))
3153 #else
3154     if ((s_saiHandle[5][1] != NULL) && SAI_RxGetEnabledInterruptStatus(I2S5, (I2S_TCSR_FWIE_MASK | I2S_TCSR_FEIE_MASK),
3155                                                                        (I2S_TCSR_FWF_MASK | I2S_TCSR_FEF_MASK)))
3156 #endif
3157     {
3158         s_saiRxIsr(I2S5, s_saiHandle[5][1]);
3159     }
3160 #if defined(FSL_FEATURE_SAI_HAS_FIFO) && (FSL_FEATURE_SAI_HAS_FIFO)
3161     if ((s_saiHandle[5][0] != NULL) && SAI_TxGetEnabledInterruptStatus(I2S5, (I2S_TCSR_FRIE_MASK | I2S_TCSR_FEIE_MASK),
3162                                                                        (I2S_TCSR_FRF_MASK | I2S_TCSR_FEF_MASK)))
3163 #else
3164     if ((s_saiHandle[5][0] != NULL) && SAI_TxGetEnabledInterruptStatus(I2S5, (I2S_TCSR_FWIE_MASK | I2S_TCSR_FEIE_MASK),
3165                                                                        (I2S_TCSR_FWF_MASK | I2S_TCSR_FEF_MASK)))
3166 #endif
3167     {
3168         s_saiTxIsr(I2S5, s_saiHandle[5][0]);
3169     }
3170     SDK_ISR_EXIT_BARRIER;
3171 }
3172 
3173 void I2S5_Tx_DriverIRQHandler(void);
3174 void I2S5_Tx_DriverIRQHandler(void)
3175 {
3176     assert(s_saiHandle[5][0] != NULL);
3177     s_saiTxIsr(I2S5, s_saiHandle[5][0]);
3178     SDK_ISR_EXIT_BARRIER;
3179 }
3180 
3181 void I2S5_Rx_DriverIRQHandler(void);
3182 void I2S5_Rx_DriverIRQHandler(void)
3183 {
3184     assert(s_saiHandle[5][1] != NULL);
3185     s_saiRxIsr(I2S5, s_saiHandle[5][1]);
3186     SDK_ISR_EXIT_BARRIER;
3187 }
3188 #endif
3189 
3190 #if defined(I2S6)
3191 void I2S6_DriverIRQHandler(void);
3192 void I2S6_DriverIRQHandler(void)
3193 {
3194 #if defined(FSL_FEATURE_SAI_HAS_FIFO) && (FSL_FEATURE_SAI_HAS_FIFO)
3195     if ((s_saiHandle[6][1] != NULL) && SAI_RxGetEnabledInterruptStatus(I2S6, (I2S_TCSR_FRIE_MASK | I2S_TCSR_FEIE_MASK),
3196                                                                        (I2S_TCSR_FRF_MASK | I2S_TCSR_FEF_MASK)))
3197 #else
3198     if ((s_saiHandle[6][1] != NULL) && SAI_RxGetEnabledInterruptStatus(I2S6, (I2S_TCSR_FWIE_MASK | I2S_TCSR_FEIE_MASK),
3199                                                                        (I2S_TCSR_FWF_MASK | I2S_TCSR_FEF_MASK)))
3200 #endif
3201     {
3202         s_saiRxIsr(I2S6, s_saiHandle[6][1]);
3203     }
3204 #if defined(FSL_FEATURE_SAI_HAS_FIFO) && (FSL_FEATURE_SAI_HAS_FIFO)
3205     if ((s_saiHandle[6][0] != NULL) && SAI_TxGetEnabledInterruptStatus(I2S6, (I2S_TCSR_FRIE_MASK | I2S_TCSR_FEIE_MASK),
3206                                                                        (I2S_TCSR_FRF_MASK | I2S_TCSR_FEF_MASK)))
3207 #else
3208     if ((s_saiHandle[6][0] != NULL) && SAI_TxGetEnabledInterruptStatus(I2S6, (I2S_TCSR_FWIE_MASK | I2S_TCSR_FEIE_MASK),
3209                                                                        (I2S_TCSR_FWF_MASK | I2S_TCSR_FEF_MASK)))
3210 #endif
3211     {
3212         s_saiTxIsr(I2S6, s_saiHandle[6][0]);
3213     }
3214     SDK_ISR_EXIT_BARRIER;
3215 }
3216 
3217 void I2S6_Tx_DriverIRQHandler(void);
3218 void I2S6_Tx_DriverIRQHandler(void)
3219 {
3220     assert(s_saiHandle[6][0] != NULL);
3221     s_saiTxIsr(I2S6, s_saiHandle[6][0]);
3222     SDK_ISR_EXIT_BARRIER;
3223 }
3224 
3225 void I2S6_Rx_DriverIRQHandler(void);
3226 void I2S6_Rx_DriverIRQHandler(void)
3227 {
3228     assert(s_saiHandle[6][1] != NULL);
3229     s_saiRxIsr(I2S6, s_saiHandle[6][1]);
3230     SDK_ISR_EXIT_BARRIER;
3231 }
3232 #endif
3233 #endif
3234 
3235 #if defined(AUDIO__SAI0)
3236 void AUDIO_SAI0_INT_DriverIRQHandler(void);
3237 void AUDIO_SAI0_INT_DriverIRQHandler(void)
3238 {
3239 #if defined(FSL_FEATURE_SAI_HAS_FIFO) && (FSL_FEATURE_SAI_HAS_FIFO)
3240     if ((s_saiHandle[0][1] != NULL) &&
3241         SAI_RxGetEnabledInterruptStatus(AUDIO__SAI0, (I2S_TCSR_FRIE_MASK | I2S_TCSR_FEIE_MASK),
3242                                         (I2S_TCSR_FRF_MASK | I2S_TCSR_FEF_MASK)))
3243 #else
3244     if ((s_saiHandle[0][1] != NULL) &&
3245         SAI_RxGetEnabledInterruptStatus(AUDIO__SAI0, (I2S_TCSR_FWIE_MASK | I2S_TCSR_FEIE_MASK),
3246                                         (I2S_TCSR_FWF_MASK | I2S_TCSR_FEF_MASK)))
3247 #endif
3248     {
3249         s_saiRxIsr(AUDIO__SAI0, s_saiHandle[0][1]);
3250     }
3251 
3252 #if defined(FSL_FEATURE_SAI_HAS_FIFO) && (FSL_FEATURE_SAI_HAS_FIFO)
3253     if ((s_saiHandle[0][0] != NULL) &&
3254         SAI_TxGetEnabledInterruptStatus(AUDIO__SAI0, (I2S_TCSR_FRIE_MASK | I2S_TCSR_FEIE_MASK),
3255                                         (I2S_TCSR_FRF_MASK | I2S_TCSR_FEF_MASK)))
3256 #else
3257     if ((s_saiHandle[0][0] != NULL) &&
3258         SAI_TxGetEnabledInterruptStatus(AUDIO__SAI0, (I2S_TCSR_FWIE_MASK | I2S_TCSR_FEIE_MASK),
3259                                         (I2S_TCSR_FWF_MASK | I2S_TCSR_FEF_MASK)))
3260 #endif
3261     {
3262         s_saiTxIsr(AUDIO__SAI0, s_saiHandle[0][0]);
3263     }
3264     SDK_ISR_EXIT_BARRIER;
3265 }
3266 #endif /* AUDIO__SAI0 */
3267 
3268 #if defined(AUDIO__SAI1)
3269 void AUDIO_SAI1_INT_DriverIRQHandler(void);
3270 void AUDIO_SAI1_INT_DriverIRQHandler(void)
3271 {
3272 #if defined(FSL_FEATURE_SAI_HAS_FIFO) && (FSL_FEATURE_SAI_HAS_FIFO)
3273     if ((s_saiHandle[1][1] != NULL) &&
3274         SAI_RxGetEnabledInterruptStatus(AUDIO__SAI1, (I2S_TCSR_FRIE_MASK | I2S_TCSR_FEIE_MASK),
3275                                         (I2S_TCSR_FRF_MASK | I2S_TCSR_FEF_MASK)))
3276 #else
3277     if ((s_saiHandle[1][1] != NULL) &&
3278         SAI_RxGetEnabledInterruptStatus(AUDIO__SAI1, (I2S_TCSR_FWIE_MASK | I2S_TCSR_FEIE_MASK),
3279                                         (I2S_TCSR_FWF_MASK | I2S_TCSR_FEF_MASK)))
3280 #endif
3281     {
3282         s_saiRxIsr(AUDIO__SAI1, s_saiHandle[1][1]);
3283     }
3284 #if defined(FSL_FEATURE_SAI_HAS_FIFO) && (FSL_FEATURE_SAI_HAS_FIFO)
3285     if ((s_saiHandle[1][0] != NULL) &&
3286         SAI_TxGetEnabledInterruptStatus(AUDIO__SAI1, (I2S_TCSR_FRIE_MASK | I2S_TCSR_FEIE_MASK),
3287                                         (I2S_TCSR_FRF_MASK | I2S_TCSR_FEF_MASK)))
3288 #else
3289     if ((s_saiHandle[1][0] != NULL) &&
3290         SAI_TxGetEnabledInterruptStatus(AUDIO__SAI1, (I2S_TCSR_FWIE_MASK | I2S_TCSR_FEIE_MASK),
3291                                         (I2S_TCSR_FWF_MASK | I2S_TCSR_FEF_MASK)))
3292 #endif
3293     {
3294         s_saiTxIsr(AUDIO__SAI1, s_saiHandle[1][0]);
3295     }
3296     SDK_ISR_EXIT_BARRIER;
3297 }
3298 #endif /* AUDIO__SAI1 */
3299 
3300 #if defined(AUDIO__SAI2)
3301 void AUDIO_SAI2_INT_DriverIRQHandler(void);
3302 void AUDIO_SAI2_INT_DriverIRQHandler(void)
3303 {
3304 #if defined(FSL_FEATURE_SAI_HAS_FIFO) && (FSL_FEATURE_SAI_HAS_FIFO)
3305     if ((s_saiHandle[2][1] != NULL) &&
3306         SAI_RxGetEnabledInterruptStatus(AUDIO__SAI2, (I2S_TCSR_FRIE_MASK | I2S_TCSR_FEIE_MASK),
3307                                         (I2S_TCSR_FRF_MASK | I2S_TCSR_FEF_MASK)))
3308 #else
3309     if ((s_saiHandle[2][1] != NULL) &&
3310         SAI_RxGetEnabledInterruptStatus(AUDIO__SAI2, (I2S_TCSR_FWIE_MASK | I2S_TCSR_FEIE_MASK),
3311                                         (I2S_TCSR_FWF_MASK | I2S_TCSR_FEF_MASK)))
3312 #endif
3313     {
3314         s_saiRxIsr(AUDIO__SAI2, s_saiHandle[2][1]);
3315     }
3316 #if defined(FSL_FEATURE_SAI_HAS_FIFO) && (FSL_FEATURE_SAI_HAS_FIFO)
3317     if ((s_saiHandle[2][0] != NULL) &&
3318         SAI_TxGetEnabledInterruptStatus(AUDIO__SAI2, (I2S_TCSR_FRIE_MASK | I2S_TCSR_FEIE_MASK),
3319                                         (I2S_TCSR_FRF_MASK | I2S_TCSR_FEF_MASK)))
3320 #else
3321     if ((s_saiHandle[2][0] != NULL) &&
3322         SAI_TxGetEnabledInterruptStatus(AUDIO__SAI2, (I2S_TCSR_FWIE_MASK | I2S_TCSR_FEIE_MASK),
3323                                         (I2S_TCSR_FWF_MASK | I2S_TCSR_FEF_MASK)))
3324 #endif
3325     {
3326         s_saiTxIsr(AUDIO__SAI2, s_saiHandle[2][0]);
3327     }
3328     SDK_ISR_EXIT_BARRIER;
3329 }
3330 #endif /* AUDIO__SAI2 */
3331 
3332 #if defined(AUDIO__SAI3)
3333 void AUDIO_SAI3_INT_DriverIRQHandler(void);
3334 void AUDIO_SAI3_INT_DriverIRQHandler(void)
3335 {
3336 #if defined(FSL_FEATURE_SAI_HAS_FIFO) && (FSL_FEATURE_SAI_HAS_FIFO)
3337     if ((s_saiHandle[3][1] != NULL) &&
3338         SAI_RxGetEnabledInterruptStatus(AUDIO__SAI3, (I2S_TCSR_FRIE_MASK | I2S_TCSR_FEIE_MASK),
3339                                         (I2S_TCSR_FRF_MASK | I2S_TCSR_FEF_MASK)))
3340 #else
3341     if ((s_saiHandle[3][1] != NULL) &&
3342         SAI_RxGetEnabledInterruptStatus(AUDIO__SAI3, (I2S_TCSR_FWIE_MASK | I2S_TCSR_FEIE_MASK),
3343                                         (I2S_TCSR_FWF_MASK | I2S_TCSR_FEF_MASK)))
3344 #endif
3345     {
3346         s_saiRxIsr(AUDIO__SAI3, s_saiHandle[3][1]);
3347     }
3348 #if defined(FSL_FEATURE_SAI_HAS_FIFO) && (FSL_FEATURE_SAI_HAS_FIFO)
3349     if ((s_saiHandle[3][0] != NULL) &&
3350         SAI_TxGetEnabledInterruptStatus(AUDIO__SAI3, (I2S_TCSR_FRIE_MASK | I2S_TCSR_FEIE_MASK),
3351                                         (I2S_TCSR_FRF_MASK | I2S_TCSR_FEF_MASK)))
3352 #else
3353     if ((s_saiHandle[3][0] != NULL) &&
3354         SAI_TxGetEnabledInterruptStatus(AUDIO__SAI3, (I2S_TCSR_FWIE_MASK | I2S_TCSR_FEIE_MASK),
3355                                         (I2S_TCSR_FWF_MASK | I2S_TCSR_FEF_MASK)))
3356 #endif
3357     {
3358         s_saiTxIsr(AUDIO__SAI3, s_saiHandle[3][0]);
3359     }
3360     SDK_ISR_EXIT_BARRIER;
3361 }
3362 #endif
3363 
3364 #if defined(AUDIO__SAI6)
3365 void AUDIO_SAI6_INT_DriverIRQHandler(void);
3366 void AUDIO_SAI6_INT_DriverIRQHandler(void)
3367 {
3368 #if defined(FSL_FEATURE_SAI_HAS_FIFO) && (FSL_FEATURE_SAI_HAS_FIFO)
3369     if ((s_saiHandle[6][1] != NULL) &&
3370         SAI_RxGetEnabledInterruptStatus(AUDIO__SAI6, (I2S_TCSR_FRIE_MASK | I2S_TCSR_FEIE_MASK),
3371                                         (I2S_TCSR_FRF_MASK | I2S_TCSR_FEF_MASK)))
3372 #else
3373     if ((s_saiHandle[6][1] != NULL) &&
3374         SAI_RxGetEnabledInterruptStatus(AUDIO__SAI6, (I2S_TCSR_FWIE_MASK | I2S_TCSR_FEIE_MASK),
3375                                         (I2S_TCSR_FWF_MASK | I2S_TCSR_FEF_MASK)))
3376 #endif
3377     {
3378         s_saiRxIsr(AUDIO__SAI6, s_saiHandle[6][1]);
3379     }
3380 #if defined(FSL_FEATURE_SAI_HAS_FIFO) && (FSL_FEATURE_SAI_HAS_FIFO)
3381     if ((s_saiHandle[6][0] != NULL) &&
3382         SAI_TxGetEnabledInterruptStatus(AUDIO__SAI6, (I2S_TCSR_FRIE_MASK | I2S_TCSR_FEIE_MASK),
3383                                         (I2S_TCSR_FRF_MASK | I2S_TCSR_FEF_MASK)))
3384 #else
3385     if ((s_saiHandle[6][0] != NULL) &&
3386         SAI_TxGetEnabledInterruptStatus(AUDIO__SAI6, (I2S_TCSR_FWIE_MASK | I2S_TCSR_FEIE_MASK),
3387                                         (I2S_TCSR_FWF_MASK | I2S_TCSR_FEF_MASK)))
3388 #endif
3389     {
3390         s_saiTxIsr(AUDIO__SAI6, s_saiHandle[6][0]);
3391     }
3392     SDK_ISR_EXIT_BARRIER;
3393 }
3394 #endif /* AUDIO__SAI6 */
3395 
3396 #if defined(AUDIO__SAI7)
3397 void AUDIO_SAI7_INT_DriverIRQHandler(void);
3398 void AUDIO_SAI7_INT_DriverIRQHandler(void)
3399 {
3400 #if defined(FSL_FEATURE_SAI_HAS_FIFO) && (FSL_FEATURE_SAI_HAS_FIFO)
3401     if ((s_saiHandle[7][1] != NULL) &&
3402         SAI_RxGetEnabledInterruptStatus(AUDIO__SAI7, (I2S_TCSR_FRIE_MASK | I2S_TCSR_FEIE_MASK),
3403                                         (I2S_TCSR_FRF_MASK | I2S_TCSR_FEF_MASK)))
3404 #else
3405     if ((s_saiHandle[7][1] != NULL) &&
3406         SAI_RxGetEnabledInterruptStatus(AUDIO__SAI7, (I2S_TCSR_FWIE_MASK | I2S_TCSR_FEIE_MASK),
3407                                         (I2S_TCSR_FWF_MASK | I2S_TCSR_FEF_MASK)))
3408 #endif
3409     {
3410         s_saiRxIsr(AUDIO__SAI7, s_saiHandle[7][1]);
3411     }
3412 #if defined(FSL_FEATURE_SAI_HAS_FIFO) && (FSL_FEATURE_SAI_HAS_FIFO)
3413     if ((s_saiHandle[7][0] != NULL) &&
3414         SAI_TxGetEnabledInterruptStatus(AUDIO__SAI7, (I2S_TCSR_FRIE_MASK | I2S_TCSR_FEIE_MASK),
3415                                         (I2S_TCSR_FRF_MASK | I2S_TCSR_FEF_MASK)))
3416 #else
3417     if ((s_saiHandle[7][0] != NULL) &&
3418         SAI_TxGetEnabledInterruptStatus(AUDIO__SAI7, (I2S_TCSR_FWIE_MASK | I2S_TCSR_FEIE_MASK),
3419                                         (I2S_TCSR_FWF_MASK | I2S_TCSR_FEF_MASK)))
3420 #endif
3421     {
3422         s_saiTxIsr(AUDIO__SAI7, s_saiHandle[7][0]);
3423     }
3424     SDK_ISR_EXIT_BARRIER;
3425 }
3426 #endif /* AUDIO__SAI7 */
3427 
3428 #if defined(ADMA__SAI0)
3429 void ADMA_SAI0_INT_DriverIRQHandler(void);
3430 void ADMA_SAI0_INT_DriverIRQHandler(void)
3431 {
3432 #if defined(FSL_FEATURE_SAI_HAS_FIFO) && (FSL_FEATURE_SAI_HAS_FIFO)
3433     if ((s_saiHandle[1][1] != NULL) &&
3434         SAI_RxGetEnabledInterruptStatus(ADMA__SAI0, (I2S_TCSR_FRIE_MASK | I2S_TCSR_FEIE_MASK),
3435                                         (I2S_TCSR_FRF_MASK | I2S_TCSR_FEF_MASK)))
3436 #else
3437     if ((s_saiHandle[1][1] != NULL) &&
3438         SAI_RxGetEnabledInterruptStatus(ADMA__SAI0, (I2S_TCSR_FWIE_MASK | I2S_TCSR_FEIE_MASK),
3439                                         (I2S_TCSR_FWF_MASK | I2S_TCSR_FEF_MASK)))
3440 #endif
3441     {
3442         s_saiRxIsr(ADMA__SAI0, s_saiHandle[1][1]);
3443     }
3444 #if defined(FSL_FEATURE_SAI_HAS_FIFO) && (FSL_FEATURE_SAI_HAS_FIFO)
3445     if ((s_saiHandle[1][0] != NULL) &&
3446         SAI_TxGetEnabledInterruptStatus(ADMA__SAI0, (I2S_TCSR_FRIE_MASK | I2S_TCSR_FEIE_MASK),
3447                                         (I2S_TCSR_FRF_MASK | I2S_TCSR_FEF_MASK)))
3448 #else
3449     if ((s_saiHandle[1][0] != NULL) &&
3450         SAI_TxGetEnabledInterruptStatus(ADMA__SAI0, (I2S_TCSR_FWIE_MASK | I2S_TCSR_FEIE_MASK),
3451                                         (I2S_TCSR_FWF_MASK | I2S_TCSR_FEF_MASK)))
3452 #endif
3453     {
3454         s_saiTxIsr(ADMA__SAI0, s_saiHandle[1][0]);
3455     }
3456     SDK_ISR_EXIT_BARRIER;
3457 }
3458 #endif /* ADMA__SAI0 */
3459 
3460 #if defined(ADMA__SAI1)
3461 void ADMA_SAI1_INT_DriverIRQHandler(void);
3462 void ADMA_SAI1_INT_DriverIRQHandler(void)
3463 {
3464 #if defined(FSL_FEATURE_SAI_HAS_FIFO) && (FSL_FEATURE_SAI_HAS_FIFO)
3465     if ((s_saiHandle[1][1] != NULL) &&
3466         SAI_RxGetEnabledInterruptStatus(ADMA__SAI1, (I2S_TCSR_FRIE_MASK | I2S_TCSR_FEIE_MASK),
3467                                         (I2S_TCSR_FRF_MASK | I2S_TCSR_FEF_MASK)))
3468 #else
3469     if ((s_saiHandle[1][1] != NULL) &&
3470         SAI_RxGetEnabledInterruptStatus(ADMA__SAI1, (I2S_TCSR_FWIE_MASK | I2S_TCSR_FEIE_MASK),
3471                                         (I2S_TCSR_FWF_MASK | I2S_TCSR_FEF_MASK)))
3472 #endif
3473     {
3474         s_saiRxIsr(ADMA__SAI1, s_saiHandle[1][1]);
3475     }
3476 #if defined(FSL_FEATURE_SAI_HAS_FIFO) && (FSL_FEATURE_SAI_HAS_FIFO)
3477     if ((s_saiHandle[1][0] != NULL) &&
3478         SAI_TxGetEnabledInterruptStatus(ADMA__SAI1, (I2S_TCSR_FRIE_MASK | I2S_TCSR_FEIE_MASK),
3479                                         (I2S_TCSR_FRF_MASK | I2S_TCSR_FEF_MASK)))
3480 #else
3481     if ((s_saiHandle[1][0] != NULL) &&
3482         SAI_TxGetEnabledInterruptStatus(ADMA__SAI1, (I2S_TCSR_FWIE_MASK | I2S_TCSR_FEIE_MASK),
3483                                         (I2S_TCSR_FWF_MASK | I2S_TCSR_FEF_MASK)))
3484 #endif
3485     {
3486         s_saiTxIsr(ADMA__SAI1, s_saiHandle[1][0]);
3487     }
3488     SDK_ISR_EXIT_BARRIER;
3489 }
3490 #endif /* ADMA__SAI1 */
3491 
3492 #if defined(ADMA__SAI2)
3493 void ADMA_SAI2_INT_DriverIRQHandler(void);
3494 void ADMA_SAI2_INT_DriverIRQHandler(void)
3495 {
3496 #if defined(FSL_FEATURE_SAI_HAS_FIFO) && (FSL_FEATURE_SAI_HAS_FIFO)
3497     if ((s_saiHandle[1][1] != NULL) &&
3498         SAI_RxGetEnabledInterruptStatus(ADMA__SAI2, (I2S_TCSR_FRIE_MASK | I2S_TCSR_FEIE_MASK),
3499                                         (I2S_TCSR_FRF_MASK | I2S_TCSR_FEF_MASK)))
3500 #else
3501     if ((s_saiHandle[1][1] != NULL) &&
3502         SAI_RxGetEnabledInterruptStatus(ADMA__SAI2, (I2S_TCSR_FWIE_MASK | I2S_TCSR_FEIE_MASK),
3503                                         (I2S_TCSR_FWF_MASK | I2S_TCSR_FEF_MASK)))
3504 #endif
3505     {
3506         s_saiRxIsr(ADMA__SAI2, s_saiHandle[1][1]);
3507     }
3508 #if defined(FSL_FEATURE_SAI_HAS_FIFO) && (FSL_FEATURE_SAI_HAS_FIFO)
3509     if ((s_saiHandle[1][0] != NULL) &&
3510         SAI_TxGetEnabledInterruptStatus(ADMA__SAI2, (I2S_TCSR_FRIE_MASK | I2S_TCSR_FEIE_MASK),
3511                                         (I2S_TCSR_FRF_MASK | I2S_TCSR_FEF_MASK)))
3512 #else
3513     if ((s_saiHandle[1][0] != NULL) &&
3514         SAI_TxGetEnabledInterruptStatus(ADMA__SAI2, (I2S_TCSR_FWIE_MASK | I2S_TCSR_FEIE_MASK),
3515                                         (I2S_TCSR_FWF_MASK | I2S_TCSR_FEF_MASK)))
3516 #endif
3517     {
3518         s_saiTxIsr(ADMA__SAI2, s_saiHandle[1][0]);
3519     }
3520     SDK_ISR_EXIT_BARRIER;
3521 }
3522 #endif /* ADMA__SAI2 */
3523 
3524 #if defined(ADMA__SAI3)
3525 void ADMA_SAI3_INT_DriverIRQHandler(void);
3526 void ADMA_SAI3_INT_DriverIRQHandler(void)
3527 {
3528 #if defined(FSL_FEATURE_SAI_HAS_FIFO) && (FSL_FEATURE_SAI_HAS_FIFO)
3529     if ((s_saiHandle[1][1] != NULL) &&
3530         SAI_RxGetEnabledInterruptStatus(ADMA__SAI3, (I2S_TCSR_FRIE_MASK | I2S_TCSR_FEIE_MASK),
3531                                         (I2S_TCSR_FRF_MASK | I2S_TCSR_FEF_MASK)))
3532 #else
3533     if ((s_saiHandle[1][1] != NULL) &&
3534         SAI_RxGetEnabledInterruptStatus(ADMA__SAI3, (I2S_TCSR_FWIE_MASK | I2S_TCSR_FEIE_MASK),
3535                                         (I2S_TCSR_FWF_MASK | I2S_TCSR_FEF_MASK)))
3536 #endif
3537     {
3538         s_saiRxIsr(ADMA__SAI3, s_saiHandle[1][1]);
3539     }
3540 #if defined(FSL_FEATURE_SAI_HAS_FIFO) && (FSL_FEATURE_SAI_HAS_FIFO)
3541     if ((s_saiHandle[1][0] != NULL) &&
3542         SAI_TxGetEnabledInterruptStatus(ADMA__SAI3, (I2S_TCSR_FRIE_MASK | I2S_TCSR_FEIE_MASK),
3543                                         (I2S_TCSR_FRF_MASK | I2S_TCSR_FEF_MASK)))
3544 #else
3545     if ((s_saiHandle[1][0] != NULL) &&
3546         SAI_TxGetEnabledInterruptStatus(ADMA__SAI3, (I2S_TCSR_FWIE_MASK | I2S_TCSR_FEIE_MASK),
3547                                         (I2S_TCSR_FWF_MASK | I2S_TCSR_FEF_MASK)))
3548 #endif
3549     {
3550         s_saiTxIsr(ADMA__SAI3, s_saiHandle[1][0]);
3551     }
3552     SDK_ISR_EXIT_BARRIER;
3553 }
3554 #endif /* ADMA__SAI3 */
3555 
3556 #if defined(ADMA__SAI4)
3557 void ADMA_SAI4_INT_DriverIRQHandler(void);
3558 void ADMA_SAI4_INT_DriverIRQHandler(void)
3559 {
3560 #if defined(FSL_FEATURE_SAI_HAS_FIFO) && (FSL_FEATURE_SAI_HAS_FIFO)
3561     if ((s_saiHandle[1][1] != NULL) &&
3562         SAI_RxGetEnabledInterruptStatus(ADMA__SAI4, (I2S_TCSR_FRIE_MASK | I2S_TCSR_FEIE_MASK),
3563                                         (I2S_TCSR_FRF_MASK | I2S_TCSR_FEF_MASK)))
3564 #else
3565     if ((s_saiHandle[1][1] != NULL) &&
3566         SAI_RxGetEnabledInterruptStatus(ADMA__SAI4, (I2S_TCSR_FWIE_MASK | I2S_TCSR_FEIE_MASK),
3567                                         (I2S_TCSR_FWF_MASK | I2S_TCSR_FEF_MASK)))
3568 #endif
3569     {
3570         s_saiRxIsr(ADMA__SAI4, s_saiHandle[1][1]);
3571     }
3572 
3573 #if defined(FSL_FEATURE_SAI_HAS_FIFO) && (FSL_FEATURE_SAI_HAS_FIFO)
3574     if ((s_saiHandle[1][0] != NULL) &&
3575         SAI_TxGetEnabledInterruptStatus(ADMA__SAI4, (I2S_TCSR_FRIE_MASK | I2S_TCSR_FEIE_MASK),
3576                                         (I2S_TCSR_FRF_MASK | I2S_TCSR_FEF_MASK)))
3577 #else
3578     if ((s_saiHandle[1][0] != NULL) &&
3579         SAI_TxGetEnabledInterruptStatus(ADMA__SAI4, (I2S_TCSR_FWIE_MASK | I2S_TCSR_FEIE_MASK),
3580                                         (I2S_TCSR_FWF_MASK | I2S_TCSR_FEF_MASK)))
3581 #endif
3582     {
3583         s_saiTxIsr(ADMA__SAI4, s_saiHandle[1][0]);
3584     }
3585     SDK_ISR_EXIT_BARRIER;
3586 }
3587 #endif /* ADMA__SAI4 */
3588 
3589 #if defined(ADMA__SAI5)
3590 void ADMA_SAI5_INT_DriverIRQHandler(void);
3591 void ADMA_SAI5_INT_DriverIRQHandler(void)
3592 {
3593 #if defined(FSL_FEATURE_SAI_HAS_FIFO) && (FSL_FEATURE_SAI_HAS_FIFO)
3594     if ((s_saiHandle[1][1] != NULL) &&
3595         SAI_RxGetEnabledInterruptStatus(ADMA__SAI5, (I2S_TCSR_FRIE_MASK | I2S_TCSR_FEIE_MASK),
3596                                         (I2S_TCSR_FRF_MASK | I2S_TCSR_FEF_MASK)))
3597 #else
3598     if ((s_saiHandle[1][1] != NULL) &&
3599         SAI_RxGetEnabledInterruptStatus(ADMA__SAI5, (I2S_TCSR_FWIE_MASK | I2S_TCSR_FEIE_MASK),
3600                                         (I2S_TCSR_FWF_MASK | I2S_TCSR_FEF_MASK)))
3601 #endif
3602     {
3603         s_saiRxIsr(ADMA__SAI5, s_saiHandle[1][1]);
3604     }
3605 #if defined(FSL_FEATURE_SAI_HAS_FIFO) && (FSL_FEATURE_SAI_HAS_FIFO)
3606     if ((s_saiHandle[1][0] != NULL) &&
3607         SAI_TxGetEnabledInterruptStatus(ADMA__SAI5, (I2S_TCSR_FRIE_MASK | I2S_TCSR_FEIE_MASK),
3608                                         (I2S_TCSR_FRF_MASK | I2S_TCSR_FEF_MASK)))
3609 #else
3610     if ((s_saiHandle[1][0] != NULL) &&
3611         SAI_TxGetEnabledInterruptStatus(ADMA__SAI5, (I2S_TCSR_FWIE_MASK | I2S_TCSR_FEIE_MASK),
3612                                         (I2S_TCSR_FWF_MASK | I2S_TCSR_FEF_MASK)))
3613 #endif
3614     {
3615         s_saiTxIsr(ADMA__SAI5, s_saiHandle[1][0]);
3616     }
3617     SDK_ISR_EXIT_BARRIER;
3618 }
3619 #endif /* ADMA__SAI5 */
3620 
3621 #if defined(SAI0)
3622 void SAI0_DriverIRQHandler(void);
3623 void SAI0_DriverIRQHandler(void)
3624 {
3625 #if defined(FSL_FEATURE_SAI_HAS_FIFO) && (FSL_FEATURE_SAI_HAS_FIFO)
3626     if ((s_saiHandle[0][1] != NULL) && SAI_RxGetEnabledInterruptStatus(SAI0, (I2S_TCSR_FRIE_MASK | I2S_TCSR_FEIE_MASK),
3627                                                                        (I2S_TCSR_FRF_MASK | I2S_TCSR_FEF_MASK)))
3628 #else
3629     if ((s_saiHandle[0][1] != NULL) && SAI_RxGetEnabledInterruptStatus(SAI0, (I2S_TCSR_FWIE_MASK | I2S_TCSR_FEIE_MASK),
3630                                                                        (I2S_TCSR_FWF_MASK | I2S_TCSR_FEF_MASK)))
3631 #endif
3632     {
3633         s_saiRxIsr(SAI0, s_saiHandle[0][1]);
3634     }
3635 #if defined(FSL_FEATURE_SAI_HAS_FIFO) && (FSL_FEATURE_SAI_HAS_FIFO)
3636     if ((s_saiHandle[0][0] != NULL) && SAI_TxGetEnabledInterruptStatus(SAI0, (I2S_TCSR_FRIE_MASK | I2S_TCSR_FEIE_MASK),
3637                                                                        (I2S_TCSR_FRF_MASK | I2S_TCSR_FEF_MASK)))
3638 #else
3639     if ((s_saiHandle[0][0] != NULL) && SAI_TxGetEnabledInterruptStatus(SAI0, (I2S_TCSR_FWIE_MASK | I2S_TCSR_FEIE_MASK),
3640                                                                        (I2S_TCSR_FWF_MASK | I2S_TCSR_FEF_MASK)))
3641 #endif
3642     {
3643         s_saiTxIsr(SAI0, s_saiHandle[0][0]);
3644     }
3645     SDK_ISR_EXIT_BARRIER;
3646 }
3647 #endif /* SAI0 */
3648 
3649 #if defined(SAI1)
3650 void SAI1_DriverIRQHandler(void);
3651 void SAI1_DriverIRQHandler(void)
3652 {
3653 #if defined(FSL_FEATURE_SAI_HAS_FIFO) && (FSL_FEATURE_SAI_HAS_FIFO)
3654     if ((s_saiHandle[1][1] != NULL) && SAI_RxGetEnabledInterruptStatus(SAI1, (I2S_TCSR_FRIE_MASK | I2S_TCSR_FEIE_MASK),
3655                                                                        (I2S_TCSR_FRF_MASK | I2S_TCSR_FEF_MASK)))
3656 #else
3657     if ((s_saiHandle[1][1] != NULL) && SAI_RxGetEnabledInterruptStatus(SAI1, (I2S_TCSR_FWIE_MASK | I2S_TCSR_FEIE_MASK),
3658                                                                        (I2S_TCSR_FWF_MASK | I2S_TCSR_FEF_MASK)))
3659 #endif
3660     {
3661         s_saiRxIsr(SAI1, s_saiHandle[1][1]);
3662     }
3663 #if defined(FSL_FEATURE_SAI_HAS_FIFO) && (FSL_FEATURE_SAI_HAS_FIFO)
3664     if ((s_saiHandle[1][0] != NULL) && SAI_TxGetEnabledInterruptStatus(SAI1, (I2S_TCSR_FRIE_MASK | I2S_TCSR_FEIE_MASK),
3665                                                                        (I2S_TCSR_FRF_MASK | I2S_TCSR_FEF_MASK)))
3666 #else
3667     if ((s_saiHandle[1][0] != NULL) && SAI_TxGetEnabledInterruptStatus(SAI1, (I2S_TCSR_FWIE_MASK | I2S_TCSR_FEIE_MASK),
3668                                                                        (I2S_TCSR_FWF_MASK | I2S_TCSR_FEF_MASK)))
3669 #endif
3670     {
3671         s_saiTxIsr(SAI1, s_saiHandle[1][0]);
3672     }
3673     SDK_ISR_EXIT_BARRIER;
3674 }
3675 #endif /* SAI1 */
3676 
3677 #if defined(SAI2)
3678 void SAI2_DriverIRQHandler(void);
3679 void SAI2_DriverIRQHandler(void)
3680 {
3681 #if defined(FSL_FEATURE_SAI_HAS_FIFO) && (FSL_FEATURE_SAI_HAS_FIFO)
3682     if ((s_saiHandle[2][1] != NULL) && SAI_RxGetEnabledInterruptStatus(SAI2, (I2S_TCSR_FRIE_MASK | I2S_TCSR_FEIE_MASK),
3683                                                                        (I2S_TCSR_FRF_MASK | I2S_TCSR_FEF_MASK)))
3684 #else
3685     if ((s_saiHandle[2][1] != NULL) && SAI_RxGetEnabledInterruptStatus(SAI2, (I2S_TCSR_FWIE_MASK | I2S_TCSR_FEIE_MASK),
3686                                                                        (I2S_TCSR_FWF_MASK | I2S_TCSR_FEF_MASK)))
3687 #endif
3688     {
3689         s_saiRxIsr(SAI2, s_saiHandle[2][1]);
3690     }
3691 #if defined(FSL_FEATURE_SAI_HAS_FIFO) && (FSL_FEATURE_SAI_HAS_FIFO)
3692     if ((s_saiHandle[2][0] != NULL) && SAI_TxGetEnabledInterruptStatus(SAI2, (I2S_TCSR_FRIE_MASK | I2S_TCSR_FEIE_MASK),
3693                                                                        (I2S_TCSR_FRF_MASK | I2S_TCSR_FEF_MASK)))
3694 #else
3695     if ((s_saiHandle[2][0] != NULL) && SAI_TxGetEnabledInterruptStatus(SAI2, (I2S_TCSR_FWIE_MASK | I2S_TCSR_FEIE_MASK),
3696                                                                        (I2S_TCSR_FWF_MASK | I2S_TCSR_FEF_MASK)))
3697 #endif
3698     {
3699         s_saiTxIsr(SAI2, s_saiHandle[2][0]);
3700     }
3701     SDK_ISR_EXIT_BARRIER;
3702 }
3703 #endif /* SAI2 */
3704 
3705 #if defined(SAI3)
3706 void SAI3_DriverIRQHandler(void);
3707 void SAI3_DriverIRQHandler(void)
3708 {
3709 #if defined(FSL_FEATURE_SAI_HAS_FIFO) && (FSL_FEATURE_SAI_HAS_FIFO)
3710     if ((s_saiHandle[3][1] != NULL) && SAI_RxGetEnabledInterruptStatus(SAI3, (I2S_TCSR_FRIE_MASK | I2S_TCSR_FEIE_MASK),
3711                                                                        (I2S_TCSR_FRF_MASK | I2S_TCSR_FEF_MASK)))
3712 #else
3713     if ((s_saiHandle[3][1] != NULL) && SAI_RxGetEnabledInterruptStatus(SAI3, (I2S_TCSR_FWIE_MASK | I2S_TCSR_FEIE_MASK),
3714                                                                        (I2S_TCSR_FWF_MASK | I2S_TCSR_FEF_MASK)))
3715 #endif
3716     {
3717         s_saiRxIsr(SAI3, s_saiHandle[3][1]);
3718     }
3719 #if defined(FSL_FEATURE_SAI_HAS_FIFO) && (FSL_FEATURE_SAI_HAS_FIFO)
3720     if ((s_saiHandle[3][0] != NULL) && SAI_TxGetEnabledInterruptStatus(SAI3, (I2S_TCSR_FRIE_MASK | I2S_TCSR_FEIE_MASK),
3721                                                                        (I2S_TCSR_FRF_MASK | I2S_TCSR_FEF_MASK)))
3722 #else
3723     if ((s_saiHandle[3][0] != NULL) && SAI_TxGetEnabledInterruptStatus(SAI3, (I2S_TCSR_FWIE_MASK | I2S_TCSR_FEIE_MASK),
3724                                                                        (I2S_TCSR_FWF_MASK | I2S_TCSR_FEF_MASK)))
3725 #endif
3726     {
3727         s_saiTxIsr(SAI3, s_saiHandle[3][0]);
3728     }
3729     SDK_ISR_EXIT_BARRIER;
3730 }
3731 
3732 void SAI3_TX_DriverIRQHandler(void);
3733 void SAI3_TX_DriverIRQHandler(void)
3734 {
3735     assert(s_saiHandle[3][0] != NULL);
3736     s_saiTxIsr(SAI3, s_saiHandle[3][0]);
3737     SDK_ISR_EXIT_BARRIER;
3738 }
3739 
3740 void SAI3_RX_DriverIRQHandler(void);
3741 void SAI3_RX_DriverIRQHandler(void)
3742 {
3743     assert(s_saiHandle[3][1] != NULL);
3744     s_saiRxIsr(SAI3, s_saiHandle[3][1]);
3745     SDK_ISR_EXIT_BARRIER;
3746 }
3747 #endif /* SAI3 */
3748 
3749 #if defined(SAI4)
3750 void SAI4_DriverIRQHandler(void);
3751 void SAI4_DriverIRQHandler(void)
3752 {
3753 #if defined(FSL_FEATURE_SAI_HAS_FIFO) && (FSL_FEATURE_SAI_HAS_FIFO)
3754     if ((s_saiHandle[4][1] != NULL) && SAI_RxGetEnabledInterruptStatus(SAI4, (I2S_TCSR_FRIE_MASK | I2S_TCSR_FEIE_MASK),
3755                                                                        (I2S_TCSR_FRF_MASK | I2S_TCSR_FEF_MASK)))
3756 #else
3757     if ((s_saiHandle[4][1] != NULL) && SAI_RxGetEnabledInterruptStatus(SAI4, (I2S_TCSR_FWIE_MASK | I2S_TCSR_FEIE_MASK),
3758                                                                        (I2S_TCSR_FWF_MASK | I2S_TCSR_FEF_MASK)))
3759 #endif
3760     {
3761         s_saiRxIsr(SAI4, s_saiHandle[4][1]);
3762     }
3763 #if defined(FSL_FEATURE_SAI_HAS_FIFO) && (FSL_FEATURE_SAI_HAS_FIFO)
3764     if ((s_saiHandle[4][0] != NULL) && SAI_TxGetEnabledInterruptStatus(SAI4, (I2S_TCSR_FRIE_MASK | I2S_TCSR_FEIE_MASK),
3765                                                                        (I2S_TCSR_FRF_MASK | I2S_TCSR_FEF_MASK)))
3766 #else
3767     if ((s_saiHandle[4][0] != NULL) && SAI_TxGetEnabledInterruptStatus(SAI4, (I2S_TCSR_FWIE_MASK | I2S_TCSR_FEIE_MASK),
3768                                                                        (I2S_TCSR_FWF_MASK | I2S_TCSR_FEF_MASK)))
3769 #endif
3770     {
3771         s_saiTxIsr(SAI4, s_saiHandle[4][0]);
3772     }
3773     SDK_ISR_EXIT_BARRIER;
3774 }
3775 #endif /* SAI4 */
3776 
3777 #if defined(SAI5)
3778 void SAI5_DriverIRQHandler(void);
3779 void SAI5_DriverIRQHandler(void)
3780 {
3781 #if defined(FSL_FEATURE_SAI_HAS_FIFO) && (FSL_FEATURE_SAI_HAS_FIFO)
3782     if ((s_saiHandle[5][1] != NULL) && SAI_RxGetEnabledInterruptStatus(SAI5, (I2S_TCSR_FRIE_MASK | I2S_TCSR_FEIE_MASK),
3783                                                                        (I2S_TCSR_FRF_MASK | I2S_TCSR_FEF_MASK)))
3784 #else
3785     if ((s_saiHandle[5][1] != NULL) && SAI_RxGetEnabledInterruptStatus(SAI5, (I2S_TCSR_FWIE_MASK | I2S_TCSR_FEIE_MASK),
3786                                                                        (I2S_TCSR_FWF_MASK | I2S_TCSR_FEF_MASK)))
3787 #endif
3788     {
3789         s_saiRxIsr(SAI5, s_saiHandle[5][1]);
3790     }
3791 #if defined(FSL_FEATURE_SAI_HAS_FIFO) && (FSL_FEATURE_SAI_HAS_FIFO)
3792     if ((s_saiHandle[5][0] != NULL) && SAI_TxGetEnabledInterruptStatus(SAI5, (I2S_TCSR_FRIE_MASK | I2S_TCSR_FEIE_MASK),
3793                                                                        (I2S_TCSR_FRF_MASK | I2S_TCSR_FEF_MASK)))
3794 #else
3795     if ((s_saiHandle[5][0] != NULL) && SAI_TxGetEnabledInterruptStatus(SAI5, (I2S_TCSR_FWIE_MASK | I2S_TCSR_FEIE_MASK),
3796                                                                        (I2S_TCSR_FWF_MASK | I2S_TCSR_FEF_MASK)))
3797 #endif
3798     {
3799         s_saiTxIsr(SAI5, s_saiHandle[5][0]);
3800     }
3801     SDK_ISR_EXIT_BARRIER;
3802 }
3803 #endif /* SAI5 */
3804 
3805 #if defined(SAI6)
3806 void SAI6_DriverIRQHandler(void);
3807 void SAI6_DriverIRQHandler(void)
3808 {
3809 #if defined(FSL_FEATURE_SAI_HAS_FIFO) && (FSL_FEATURE_SAI_HAS_FIFO)
3810     if ((s_saiHandle[6][1] != NULL) && SAI_RxGetEnabledInterruptStatus(SAI6, (I2S_TCSR_FRIE_MASK | I2S_TCSR_FEIE_MASK),
3811                                                                        (I2S_TCSR_FRF_MASK | I2S_TCSR_FEF_MASK)))
3812 #else
3813     if ((s_saiHandle[6][1] != NULL) && SAI_RxGetEnabledInterruptStatus(SAI6, (I2S_TCSR_FWIE_MASK | I2S_TCSR_FEIE_MASK),
3814                                                                        (I2S_TCSR_FWF_MASK | I2S_TCSR_FEF_MASK)))
3815 #endif
3816     {
3817         s_saiRxIsr(SAI6, s_saiHandle[6][1]);
3818     }
3819 #if defined(FSL_FEATURE_SAI_HAS_FIFO) && (FSL_FEATURE_SAI_HAS_FIFO)
3820     if ((s_saiHandle[6][0] != NULL) && SAI_TxGetEnabledInterruptStatus(SAI6, (I2S_TCSR_FRIE_MASK | I2S_TCSR_FEIE_MASK),
3821                                                                        (I2S_TCSR_FRF_MASK | I2S_TCSR_FEF_MASK)))
3822 #else
3823     if ((s_saiHandle[6][0] != NULL) && SAI_TxGetEnabledInterruptStatus(SAI6, (I2S_TCSR_FWIE_MASK | I2S_TCSR_FEIE_MASK),
3824                                                                        (I2S_TCSR_FWF_MASK | I2S_TCSR_FEF_MASK)))
3825 #endif
3826     {
3827         s_saiTxIsr(SAI6, s_saiHandle[6][0]);
3828     }
3829     SDK_ISR_EXIT_BARRIER;
3830 }
3831 #endif /* SAI6 */