1 /*
2  * Copyright (c) 2016, Freescale Semiconductor, Inc.
3  * Copyright 2016-2022 NXP
4  * All rights reserved.
5  *
6  * SPDX-License-Identifier: BSD-3-Clause
7  */
8 
9 #include "fsl_sai.h"
10 
11 /* Component ID definition, used by tools. */
12 #ifndef FSL_COMPONENT_ID
13 #define FSL_COMPONENT_ID "platform.drivers.sai"
14 #endif
15 
16 /*******************************************************************************
17  * Definitations
18  ******************************************************************************/
19 /*! @brief _sai_transfer_state sai transfer state.*/
20 enum
21 {
22     kSAI_Busy = 0x0U, /*!< SAI is busy */
23     kSAI_Idle,        /*!< Transfer is done. */
24     kSAI_Error        /*!< Transfer error occurred. */
25 };
26 
27 /*! @brief Typedef for sai tx interrupt handler. */
28 typedef void (*sai_tx_isr_t)(I2S_Type *base, sai_handle_t *saiHandle);
29 
30 /*! @brief Typedef for sai rx interrupt handler. */
31 typedef void (*sai_rx_isr_t)(I2S_Type *base, sai_handle_t *saiHandle);
32 
33 /*! @brief check flag avalibility */
34 #define IS_SAI_FLAG_SET(reg, flag) (((reg) & ((uint32_t)flag)) != 0UL)
35 /*******************************************************************************
36  * Prototypes
37  ******************************************************************************/
38 /*!
39  * @brief sai get rx enabled interrupt status.
40  *
41  *
42  * @param base SAI base pointer.
43  * @param enableFlag enable flag to check.
44  * @param statusFlag status flag to check.
45  */
46 static bool SAI_RxGetEnabledInterruptStatus(I2S_Type *base, uint32_t enableFlag, uint32_t statusFlag);
47 
48 /*!
49  * @brief sai get tx enabled interrupt status.
50  *
51  *
52  * @param base SAI base pointer.
53  * @param enableFlag enable flag to check.
54  * @param statusFlag status flag to check.
55  */
56 static bool SAI_TxGetEnabledInterruptStatus(I2S_Type *base, uint32_t enableFlag, uint32_t statusFlag);
57 
58 /*!
59  * @brief Set the master clock divider.
60  *
61  * This API will compute the master clock divider according to master clock frequency and master
62  * clock source clock source frequency.
63  *
64  * @param base SAI base pointer.
65  * @param mclk_Hz Mater clock frequency in Hz.
66  * @param mclkSrcClock_Hz Master clock source frequency in Hz.
67  */
68 static bool SAI_TxGetEnabledInterruptStatus(I2S_Type *base, uint32_t enableFlag, uint32_t statusFlag);
69 
70 #if ((defined(FSL_FEATURE_SAI_HAS_MCLKDIV_REGISTER) && (FSL_FEATURE_SAI_HAS_MCLKDIV_REGISTER)) || \
71      (defined(FSL_FEATURE_SAI_HAS_MCR_MCLK_POST_DIV) && (FSL_FEATURE_SAI_HAS_MCR_MCLK_POST_DIV)))
72 
73 /*!
74  * @brief Set the master clock divider.
75  *
76  * This API will compute the master clock divider according to master clock frequency and master
77  * clock source clock source frequency.
78  *
79  * @param base SAI base pointer.
80  * @param mclk_Hz Mater clock frequency in Hz.
81  * @param mclkSrcClock_Hz Master clock source frequency in Hz.
82  */
83 static void SAI_SetMasterClockDivider(I2S_Type *base, uint32_t mclk_Hz, uint32_t mclkSrcClock_Hz);
84 #endif /* FSL_FEATURE_SAI_HAS_MCLKDIV_REGISTER */
85 
86 /*!
87  * @brief Get the instance number for SAI.
88  *
89  * @param base SAI base pointer.
90  */
91 static uint32_t SAI_GetInstance(I2S_Type *base);
92 
93 /*!
94  * @brief sends a piece of data in non-blocking way.
95  *
96  * @param base SAI base pointer
97  * @param channel start channel number.
98  * @param channelMask enabled channels mask.
99  * @param endChannel end channel numbers.
100  * @param bitWidth How many bits in a audio word, usually 8/16/24/32 bits.
101  * @param buffer Pointer to the data to be written.
102  * @param size Bytes to be written.
103  */
104 static void SAI_WriteNonBlocking(I2S_Type *base,
105                                  uint32_t channel,
106                                  uint32_t channelMask,
107                                  uint32_t endChannel,
108                                  uint8_t bitWidth,
109                                  uint8_t *buffer,
110                                  uint32_t size);
111 
112 /*!
113  * @brief Receive a piece of data in non-blocking way.
114  *
115  * @param base SAI base pointer
116  * @param channel start channel number.
117  * @param channelMask enabled channels mask.
118  * @param endChannel end channel numbers.
119  * @param bitWidth How many bits in a audio word, usually 8/16/24/32 bits.
120  * @param buffer Pointer to the data to be read.
121  * @param size Bytes to be read.
122  */
123 static void SAI_ReadNonBlocking(I2S_Type *base,
124                                 uint32_t channel,
125                                 uint32_t channelMask,
126                                 uint32_t endChannel,
127                                 uint8_t bitWidth,
128                                 uint8_t *buffer,
129                                 uint32_t size);
130 
131 /*!
132  * @brief Get classic I2S mode configurations.
133  *
134  * @param config transceiver configurations
135  * @param bitWidth audio data bitWidth.
136  * @param mode audio data channel
137  * @param saiChannelMask channel mask value to enable
138  */
139 static void SAI_GetCommonConfig(sai_transceiver_t *config,
140                                 sai_word_width_t bitWidth,
141                                 sai_mono_stereo_t mode,
142                                 uint32_t saiChannelMask);
143 /*******************************************************************************
144  * Variables
145  ******************************************************************************/
146 /* Base pointer array */
147 static I2S_Type *const s_saiBases[] = I2S_BASE_PTRS;
148 /*!@brief SAI handle pointer */
149 static sai_handle_t *s_saiHandle[ARRAY_SIZE(s_saiBases)][2];
150 /* IRQ number array */
151 static const IRQn_Type s_saiTxIRQ[] = I2S_TX_IRQS;
152 static const IRQn_Type s_saiRxIRQ[] = I2S_RX_IRQS;
153 #if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
154 /* Clock name array */
155 static const clock_ip_name_t s_saiClock[] = SAI_CLOCKS;
156 #endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */
157 /*! @brief Pointer to tx IRQ handler for each instance. */
158 static sai_tx_isr_t s_saiTxIsr;
159 /*! @brief Pointer to tx IRQ handler for each instance. */
160 static sai_rx_isr_t s_saiRxIsr;
161 
162 /*******************************************************************************
163  * Code
164  ******************************************************************************/
SAI_RxGetEnabledInterruptStatus(I2S_Type * base,uint32_t enableFlag,uint32_t statusFlag)165 static bool SAI_RxGetEnabledInterruptStatus(I2S_Type *base, uint32_t enableFlag, uint32_t statusFlag)
166 {
167     uint32_t rcsr = base->RCSR;
168 
169     return IS_SAI_FLAG_SET(rcsr, enableFlag) && IS_SAI_FLAG_SET(rcsr, statusFlag);
170 }
171 
SAI_TxGetEnabledInterruptStatus(I2S_Type * base,uint32_t enableFlag,uint32_t statusFlag)172 static bool SAI_TxGetEnabledInterruptStatus(I2S_Type *base, uint32_t enableFlag, uint32_t statusFlag)
173 {
174     uint32_t tcsr = base->TCSR;
175 
176     return IS_SAI_FLAG_SET(tcsr, enableFlag) && IS_SAI_FLAG_SET(tcsr, statusFlag);
177 }
178 
179 #if ((defined(FSL_FEATURE_SAI_HAS_MCLKDIV_REGISTER) && (FSL_FEATURE_SAI_HAS_MCLKDIV_REGISTER)) || \
180      (defined(FSL_FEATURE_SAI_HAS_MCR_MCLK_POST_DIV) && (FSL_FEATURE_SAI_HAS_MCR_MCLK_POST_DIV)))
SAI_SetMasterClockDivider(I2S_Type * base,uint32_t mclk_Hz,uint32_t mclkSrcClock_Hz)181 static void SAI_SetMasterClockDivider(I2S_Type *base, uint32_t mclk_Hz, uint32_t mclkSrcClock_Hz)
182 {
183     assert(mclk_Hz <= mclkSrcClock_Hz);
184 
185     uint32_t sourceFreq = mclkSrcClock_Hz / 100U; /*In order to prevent overflow */
186     uint32_t targetFreq = mclk_Hz / 100U;         /*In order to prevent overflow */
187 
188 #if FSL_FEATURE_SAI_HAS_MCR_MCLK_POST_DIV
189     uint32_t postDivider = sourceFreq / targetFreq;
190 
191     /* if source equal to target, then disable divider */
192     if (postDivider == 1U)
193     {
194         base->MCR &= ~I2S_MCR_DIVEN_MASK;
195     }
196     else
197     {
198         base->MCR = (base->MCR & (~I2S_MCR_DIV_MASK)) | I2S_MCR_DIV(postDivider / 2U - 1U) | I2S_MCR_DIVEN_MASK;
199     }
200 #endif
201 #if FSL_FEATURE_SAI_HAS_MCLKDIV_REGISTER
202     uint16_t fract, divide;
203     uint32_t remaind           = 0;
204     uint32_t current_remainder = 0xFFFFFFFFU;
205     uint16_t current_fract     = 0;
206     uint16_t current_divide    = 0;
207     uint32_t mul_freq          = 0;
208     uint32_t max_fract         = 256;
209 
210     /* Compute the max fract number */
211     max_fract = targetFreq * 4096U / sourceFreq + 1U;
212     if (max_fract > 256U)
213     {
214         max_fract = 256U;
215     }
216 
217     /* Looking for the closet frequency */
218     for (fract = 1; fract < max_fract; fract++)
219     {
220         mul_freq = sourceFreq * fract;
221         remaind  = mul_freq % targetFreq;
222         divide   = (uint16_t)(mul_freq / targetFreq);
223 
224         /* Find the exactly frequency */
225         if (remaind == 0U)
226         {
227             current_fract  = fract;
228             current_divide = (uint16_t)(mul_freq / targetFreq);
229             break;
230         }
231 
232         /* Closer to next one, set the closest to next data */
233         if (remaind > mclk_Hz / 2U)
234         {
235             remaind = targetFreq - remaind;
236             divide += 1U;
237         }
238 
239         /* Update the closest div and fract */
240         if (remaind < current_remainder)
241         {
242             current_fract     = fract;
243             current_divide    = divide;
244             current_remainder = remaind;
245         }
246     }
247 
248     /* Fill the computed fract and divider to registers */
249     base->MDR = I2S_MDR_DIVIDE(current_divide - 1UL) | I2S_MDR_FRACT(current_fract - 1UL);
250 
251     /* Waiting for the divider updated */
252     while ((base->MCR & I2S_MCR_DUF_MASK) != 0UL)
253     {
254     }
255 #endif
256 }
257 #endif /* FSL_FEATURE_SAI_HAS_MCLKDIV_REGISTER */
258 
SAI_GetInstance(I2S_Type * base)259 static uint32_t SAI_GetInstance(I2S_Type *base)
260 {
261     uint32_t instance;
262 
263     /* Find the instance index from base address mappings. */
264     for (instance = 0; instance < ARRAY_SIZE(s_saiBases); instance++)
265     {
266         if (s_saiBases[instance] == base)
267         {
268             break;
269         }
270     }
271 
272     assert(instance < ARRAY_SIZE(s_saiBases));
273 
274     return instance;
275 }
276 
SAI_WriteNonBlocking(I2S_Type * base,uint32_t channel,uint32_t channelMask,uint32_t endChannel,uint8_t bitWidth,uint8_t * buffer,uint32_t size)277 static void SAI_WriteNonBlocking(I2S_Type *base,
278                                  uint32_t channel,
279                                  uint32_t channelMask,
280                                  uint32_t endChannel,
281                                  uint8_t bitWidth,
282                                  uint8_t *buffer,
283                                  uint32_t size)
284 {
285     uint32_t i = 0, j = 0U;
286     uint8_t m            = 0;
287     uint8_t bytesPerWord = bitWidth / 8U;
288     uint32_t data        = 0;
289     uint32_t temp        = 0;
290 
291     for (i = 0; i < size / bytesPerWord; i++)
292     {
293         for (j = channel; j <= endChannel; j++)
294         {
295             if (IS_SAI_FLAG_SET((1UL << j), channelMask))
296             {
297                 for (m = 0; m < bytesPerWord; m++)
298                 {
299                     temp = (uint32_t)(*buffer);
300                     data |= (temp << (8U * m));
301                     buffer++;
302                 }
303                 base->TDR[j] = data;
304                 data         = 0;
305             }
306         }
307     }
308 }
309 
SAI_ReadNonBlocking(I2S_Type * base,uint32_t channel,uint32_t channelMask,uint32_t endChannel,uint8_t bitWidth,uint8_t * buffer,uint32_t size)310 static void SAI_ReadNonBlocking(I2S_Type *base,
311                                 uint32_t channel,
312                                 uint32_t channelMask,
313                                 uint32_t endChannel,
314                                 uint8_t bitWidth,
315                                 uint8_t *buffer,
316                                 uint32_t size)
317 {
318     uint32_t i = 0, j = 0;
319     uint8_t m            = 0;
320     uint8_t bytesPerWord = bitWidth / 8U;
321     uint32_t data        = 0;
322 
323     for (i = 0; i < size / bytesPerWord; i++)
324     {
325         for (j = channel; j <= endChannel; j++)
326         {
327             if (IS_SAI_FLAG_SET((1UL << j), channelMask))
328             {
329                 data = base->RDR[j];
330                 for (m = 0; m < bytesPerWord; m++)
331                 {
332                     *buffer = (uint8_t)(data >> (8U * m)) & 0xFFU;
333                     buffer++;
334                 }
335             }
336         }
337     }
338 }
339 
SAI_GetCommonConfig(sai_transceiver_t * config,sai_word_width_t bitWidth,sai_mono_stereo_t mode,uint32_t saiChannelMask)340 static void SAI_GetCommonConfig(sai_transceiver_t *config,
341                                 sai_word_width_t bitWidth,
342                                 sai_mono_stereo_t mode,
343                                 uint32_t saiChannelMask)
344 {
345     assert(NULL != config);
346     assert(saiChannelMask != 0U);
347 
348     (void)memset(config, 0, sizeof(sai_transceiver_t));
349 
350     config->channelMask = (uint8_t)saiChannelMask;
351     /* sync mode default configurations */
352     config->syncMode = kSAI_ModeAsync;
353 
354     /* master mode default */
355     config->masterSlave = kSAI_Master;
356 
357     /* bit default configurations */
358     config->bitClock.bclkSrcSwap    = false;
359     config->bitClock.bclkInputDelay = false;
360     config->bitClock.bclkPolarity   = kSAI_SampleOnRisingEdge;
361     config->bitClock.bclkSource     = kSAI_BclkSourceMclkDiv;
362 
363     /* frame sync default configurations */
364     config->frameSync.frameSyncWidth = (uint8_t)bitWidth;
365     config->frameSync.frameSyncEarly = true;
366 #if defined(FSL_FEATURE_SAI_HAS_ON_DEMAND_MODE) && FSL_FEATURE_SAI_HAS_ON_DEMAND_MODE
367     config->frameSync.frameSyncGenerateOnDemand = false;
368 #endif
369     config->frameSync.frameSyncPolarity = kSAI_PolarityActiveLow;
370 
371     /* serial data default configurations */
372 #if defined(FSL_FEATURE_SAI_HAS_CHANNEL_MODE) && FSL_FEATURE_SAI_HAS_CHANNEL_MODE
373     config->serialData.dataMode = kSAI_DataPinStateOutputZero;
374 #endif
375     config->serialData.dataOrder           = kSAI_DataMSB;
376     config->serialData.dataWord0Length     = (uint8_t)bitWidth;
377     config->serialData.dataWordLength      = (uint8_t)bitWidth;
378     config->serialData.dataWordNLength     = (uint8_t)bitWidth;
379     config->serialData.dataFirstBitShifted = (uint8_t)bitWidth;
380     config->serialData.dataWordNum         = 2U;
381     config->serialData.dataMaskedWord      = (uint32_t)mode;
382 
383 #if defined(FSL_FEATURE_SAI_HAS_FIFO_FUNCTION_AFTER_ERROR) && FSL_FEATURE_SAI_HAS_FIFO_FUNCTION_AFTER_ERROR
384     config->fifo.fifoContinueOneError = true;
385 #endif
386 }
387 
388 /*!
389  * brief Initializes the SAI Tx peripheral.
390  *
391  * deprecated Do not use this function.  It has been superceded by @ref SAI_Init
392  *
393  * Ungates the SAI clock, resets the module, and configures SAI Tx with a configuration structure.
394  * The configuration structure can be custom filled or set with default values by
395  * SAI_TxGetDefaultConfig().
396  *
397  * note  This API should be called at the beginning of the application to use
398  * the SAI driver. Otherwise, accessing the SAIM module can cause a hard fault
399  * because the clock is not enabled.
400  *
401  * param base SAI base pointer
402  * param config SAI configuration structure.
403  */
SAI_TxInit(I2S_Type * base,const sai_config_t * config)404 void SAI_TxInit(I2S_Type *base, const sai_config_t *config)
405 {
406     uint32_t val = 0;
407 
408 #if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
409     /* Enable the SAI clock */
410     (void)CLOCK_EnableClock(s_saiClock[SAI_GetInstance(base)]);
411 #endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */
412 
413 #if defined(FSL_FEATURE_SAI_HAS_MCR) && (FSL_FEATURE_SAI_HAS_MCR)
414 #if !(defined(FSL_FEATURE_SAI_HAS_NO_MCR_MICS) && (FSL_FEATURE_SAI_HAS_NO_MCR_MICS))
415     /* Master clock source setting */
416     val       = (base->MCR & ~I2S_MCR_MICS_MASK);
417     base->MCR = (val | I2S_MCR_MICS(config->mclkSource));
418 #endif
419 
420     /* Configure Master clock output enable */
421     val       = (base->MCR & ~I2S_MCR_MOE_MASK);
422     base->MCR = (val | I2S_MCR_MOE(config->mclkOutputEnable));
423 #endif /* FSL_FEATURE_SAI_HAS_MCR */
424 
425     SAI_TxReset(base);
426 
427     /* Configure audio protocol */
428     if (config->protocol == kSAI_BusLeftJustified)
429     {
430         base->TCR2 |= I2S_TCR2_BCP_MASK;
431         base->TCR3 &= ~I2S_TCR3_WDFL_MASK;
432         base->TCR4 = I2S_TCR4_MF(1U) | I2S_TCR4_SYWD(31U) | I2S_TCR4_FSE(0U) | I2S_TCR4_FSP(0U) | I2S_TCR4_FRSZ(1U);
433     }
434     else if (config->protocol == kSAI_BusRightJustified)
435     {
436         base->TCR2 |= I2S_TCR2_BCP_MASK;
437         base->TCR3 &= ~I2S_TCR3_WDFL_MASK;
438         base->TCR4 = I2S_TCR4_MF(1U) | I2S_TCR4_SYWD(31U) | I2S_TCR4_FSE(0U) | I2S_TCR4_FSP(0U) | I2S_TCR4_FRSZ(1U);
439     }
440     else if (config->protocol == kSAI_BusI2S)
441     {
442         base->TCR2 |= I2S_TCR2_BCP_MASK;
443         base->TCR3 &= ~I2S_TCR3_WDFL_MASK;
444         base->TCR4 = I2S_TCR4_MF(1U) | I2S_TCR4_SYWD(31U) | I2S_TCR4_FSE(1U) | I2S_TCR4_FSP(1U) | I2S_TCR4_FRSZ(1U);
445     }
446     else if (config->protocol == kSAI_BusPCMA)
447     {
448         base->TCR2 &= ~I2S_TCR2_BCP_MASK;
449         base->TCR3 &= ~I2S_TCR3_WDFL_MASK;
450         base->TCR4 = I2S_TCR4_MF(1U) | I2S_TCR4_SYWD(0U) | I2S_TCR4_FSE(1U) | I2S_TCR4_FSP(0U) | I2S_TCR4_FRSZ(1U);
451     }
452     else
453     {
454         base->TCR2 &= ~I2S_TCR2_BCP_MASK;
455         base->TCR3 &= ~I2S_TCR3_WDFL_MASK;
456         base->TCR4 = I2S_TCR4_MF(1U) | I2S_TCR4_SYWD(0U) | I2S_TCR4_FSE(0U) | I2S_TCR4_FSP(0U) | I2S_TCR4_FRSZ(1U);
457     }
458 
459     /* Set master or slave */
460     if (config->masterSlave == kSAI_Master)
461     {
462         base->TCR2 |= I2S_TCR2_BCD_MASK;
463         base->TCR4 |= I2S_TCR4_FSD_MASK;
464 
465         /* Bit clock source setting */
466         val        = base->TCR2 & (~I2S_TCR2_MSEL_MASK);
467         base->TCR2 = (val | I2S_TCR2_MSEL(config->bclkSource));
468     }
469     else
470     {
471         base->TCR2 &= ~I2S_TCR2_BCD_MASK;
472         base->TCR4 &= ~I2S_TCR4_FSD_MASK;
473     }
474 
475     /* Set Sync mode */
476     if (config->syncMode == kSAI_ModeAsync)
477     {
478         val = base->TCR2;
479         val &= ~I2S_TCR2_SYNC_MASK;
480         base->TCR2 = (val | I2S_TCR2_SYNC(0U));
481     }
482     if (config->syncMode == kSAI_ModeSync)
483     {
484         val = base->TCR2;
485         val &= ~I2S_TCR2_SYNC_MASK;
486         base->TCR2 = (val | I2S_TCR2_SYNC(1U));
487         /* If sync with Rx, should set Rx to async mode */
488         val = base->RCR2;
489         val &= ~I2S_RCR2_SYNC_MASK;
490         base->RCR2 = (val | I2S_RCR2_SYNC(0U));
491     }
492 #if defined(FSL_FEATURE_SAI_HAS_SYNC_WITH_ANOTHER_SAI) && (FSL_FEATURE_SAI_HAS_SYNC_WITH_ANOTHER_SAI)
493     if (config->syncMode == kSAI_ModeSyncWithOtherTx)
494     {
495         val = base->TCR2;
496         val &= ~I2S_TCR2_SYNC_MASK;
497         base->TCR2 = (val | I2S_TCR2_SYNC(2U));
498     }
499     if (config->syncMode == kSAI_ModeSyncWithOtherRx)
500     {
501         val = base->TCR2;
502         val &= ~I2S_TCR2_SYNC_MASK;
503         base->TCR2 = (val | I2S_TCR2_SYNC(3U));
504     }
505 #endif /* FSL_FEATURE_SAI_HAS_SYNC_WITH_ANOTHER_SAI */
506 
507 #if defined(FSL_FEATURE_SAI_HAS_FIFO_FUNCTION_AFTER_ERROR) && FSL_FEATURE_SAI_HAS_FIFO_FUNCTION_AFTER_ERROR
508     SAI_TxSetFIFOErrorContinue(base, true);
509 #endif /* FSL_FEATURE_SAI_HAS_FIFO_FUNCTION_AFTER_ERROR */
510 }
511 
512 /*!
513  * brief Initializes the SAI Rx peripheral.
514  *
515  * deprecated Do not use this function.  It has been superceded by @ref SAI_Init
516  *
517  * Ungates the SAI clock, resets the module, and configures the SAI Rx with a configuration structure.
518  * The configuration structure can be custom filled or set with default values by
519  * SAI_RxGetDefaultConfig().
520  *
521  * note  This API should be called at the beginning of the application to use
522  * the SAI driver. Otherwise, accessing the SAI module can cause a hard fault
523  * because the clock is not enabled.
524  *
525  * param base SAI base pointer
526  * param config SAI configuration structure.
527  */
SAI_RxInit(I2S_Type * base,const sai_config_t * config)528 void SAI_RxInit(I2S_Type *base, const sai_config_t *config)
529 {
530     uint32_t val = 0;
531 
532 #if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
533     /* Enable SAI clock first. */
534     (void)CLOCK_EnableClock(s_saiClock[SAI_GetInstance(base)]);
535 #endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */
536 
537 #if defined(FSL_FEATURE_SAI_HAS_MCR) && (FSL_FEATURE_SAI_HAS_MCR)
538 #if !(defined(FSL_FEATURE_SAI_HAS_NO_MCR_MICS) && (FSL_FEATURE_SAI_HAS_NO_MCR_MICS))
539     /* Master clock source setting */
540     val       = (base->MCR & ~I2S_MCR_MICS_MASK);
541     base->MCR = (val | I2S_MCR_MICS(config->mclkSource));
542 #endif
543 
544     /* Configure Master clock output enable */
545     val       = (base->MCR & ~I2S_MCR_MOE_MASK);
546     base->MCR = (val | I2S_MCR_MOE(config->mclkOutputEnable));
547 #endif /* FSL_FEATURE_SAI_HAS_MCR */
548 
549     SAI_RxReset(base);
550 
551     /* Configure audio protocol */
552     if (config->protocol == kSAI_BusLeftJustified)
553     {
554         base->RCR2 |= I2S_RCR2_BCP_MASK;
555         base->RCR3 &= ~I2S_RCR3_WDFL_MASK;
556         base->RCR4 = I2S_RCR4_MF(1U) | I2S_RCR4_SYWD(31U) | I2S_RCR4_FSE(0U) | I2S_RCR4_FSP(0U) | I2S_RCR4_FRSZ(1U);
557     }
558     else if (config->protocol == kSAI_BusRightJustified)
559     {
560         base->RCR2 |= I2S_RCR2_BCP_MASK;
561         base->RCR3 &= ~I2S_RCR3_WDFL_MASK;
562         base->RCR4 = I2S_RCR4_MF(1U) | I2S_RCR4_SYWD(31U) | I2S_RCR4_FSE(0U) | I2S_RCR4_FSP(0U) | I2S_RCR4_FRSZ(1U);
563     }
564     else if (config->protocol == kSAI_BusI2S)
565     {
566         base->RCR2 |= I2S_RCR2_BCP_MASK;
567         base->RCR3 &= ~I2S_RCR3_WDFL_MASK;
568         base->RCR4 = I2S_RCR4_MF(1U) | I2S_RCR4_SYWD(31U) | I2S_RCR4_FSE(1U) | I2S_RCR4_FSP(1U) | I2S_RCR4_FRSZ(1U);
569     }
570     else if (config->protocol == kSAI_BusPCMA)
571     {
572         base->RCR2 &= ~I2S_RCR2_BCP_MASK;
573         base->RCR3 &= ~I2S_RCR3_WDFL_MASK;
574         base->RCR4 = I2S_RCR4_MF(1U) | I2S_RCR4_SYWD(0U) | I2S_RCR4_FSE(1U) | I2S_RCR4_FSP(0U) | I2S_RCR4_FRSZ(1U);
575     }
576     else
577     {
578         base->RCR2 &= ~I2S_RCR2_BCP_MASK;
579         base->RCR3 &= ~I2S_RCR3_WDFL_MASK;
580         base->RCR4 = I2S_RCR4_MF(1U) | I2S_RCR4_SYWD(0U) | I2S_RCR4_FSE(0U) | I2S_RCR4_FSP(0U) | I2S_RCR4_FRSZ(1U);
581     }
582 
583     /* Set master or slave */
584     if (config->masterSlave == kSAI_Master)
585     {
586         base->RCR2 |= I2S_RCR2_BCD_MASK;
587         base->RCR4 |= I2S_RCR4_FSD_MASK;
588 
589         /* Bit clock source setting */
590         val        = base->RCR2 & (~I2S_RCR2_MSEL_MASK);
591         base->RCR2 = (val | I2S_RCR2_MSEL(config->bclkSource));
592     }
593     else
594     {
595         base->RCR2 &= ~I2S_RCR2_BCD_MASK;
596         base->RCR4 &= ~I2S_RCR4_FSD_MASK;
597     }
598 
599     /* Set Sync mode */
600     if (config->syncMode == kSAI_ModeAsync)
601     {
602         val = base->RCR2;
603         val &= ~I2S_RCR2_SYNC_MASK;
604         base->RCR2 = (val | I2S_RCR2_SYNC(0U));
605     }
606     if (config->syncMode == kSAI_ModeSync)
607     {
608         val = base->RCR2;
609         val &= ~I2S_RCR2_SYNC_MASK;
610         base->RCR2 = (val | I2S_RCR2_SYNC(1U));
611         /* If sync with Tx, should set Tx to async mode */
612         val = base->TCR2;
613         val &= ~I2S_TCR2_SYNC_MASK;
614         base->TCR2 = (val | I2S_TCR2_SYNC(0U));
615     }
616 #if defined(FSL_FEATURE_SAI_HAS_SYNC_WITH_ANOTHER_SAI) && (FSL_FEATURE_SAI_HAS_SYNC_WITH_ANOTHER_SAI)
617     if (config->syncMode == kSAI_ModeSyncWithOtherTx)
618     {
619         val = base->RCR2;
620         val &= ~I2S_RCR2_SYNC_MASK;
621         base->RCR2 = (val | I2S_RCR2_SYNC(2U));
622     }
623     if (config->syncMode == kSAI_ModeSyncWithOtherRx)
624     {
625         val = base->RCR2;
626         val &= ~I2S_RCR2_SYNC_MASK;
627         base->RCR2 = (val | I2S_RCR2_SYNC(3U));
628     }
629 #endif /* FSL_FEATURE_SAI_HAS_SYNC_WITH_ANOTHER_SAI */
630 
631 #if defined(FSL_FEATURE_SAI_HAS_FIFO_FUNCTION_AFTER_ERROR) && FSL_FEATURE_SAI_HAS_FIFO_FUNCTION_AFTER_ERROR
632     SAI_RxSetFIFOErrorContinue(base, true);
633 #endif /* FSL_FEATURE_SAI_HAS_FIFO_FUNCTION_AFTER_ERROR */
634 }
635 
636 /*!
637  * brief Initializes the SAI peripheral.
638  *
639  * This API gates the SAI clock. The SAI module can't operate unless SAI_Init is called to enable the clock.
640  *
641  * param base SAI base pointer
642  */
SAI_Init(I2S_Type * base)643 void SAI_Init(I2S_Type *base)
644 {
645 #if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
646     /* Enable the SAI clock */
647     (void)CLOCK_EnableClock(s_saiClock[SAI_GetInstance(base)]);
648 #endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */
649 
650 #if defined(FSL_FEATURE_SAI_HAS_FIFO) && (FSL_FEATURE_SAI_HAS_FIFO)
651     /* disable interrupt and DMA request*/
652     base->TCSR &=
653         ~(I2S_TCSR_FRIE_MASK | I2S_TCSR_FWIE_MASK | I2S_TCSR_FEIE_MASK | I2S_TCSR_FRDE_MASK | I2S_TCSR_FWDE_MASK);
654     base->RCSR &=
655         ~(I2S_RCSR_FRIE_MASK | I2S_RCSR_FWIE_MASK | I2S_RCSR_FEIE_MASK | I2S_RCSR_FRDE_MASK | I2S_RCSR_FWDE_MASK);
656 #else
657     /* disable interrupt and DMA request*/
658     base->TCSR &= ~(I2S_TCSR_FWIE_MASK | I2S_TCSR_FEIE_MASK | I2S_TCSR_FWDE_MASK);
659     base->RCSR &= ~(I2S_RCSR_FWIE_MASK | I2S_RCSR_FEIE_MASK | I2S_RCSR_FWDE_MASK);
660 #endif
661 }
662 
663 /*!
664  * brief De-initializes the SAI peripheral.
665  *
666  * This API gates the SAI clock. The SAI module can't operate unless SAI_TxInit
667  * or SAI_RxInit is called to enable the clock.
668  *
669  * param base SAI base pointer
670  */
SAI_Deinit(I2S_Type * base)671 void SAI_Deinit(I2S_Type *base)
672 {
673     SAI_TxEnable(base, false);
674     SAI_RxEnable(base, false);
675 #if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
676     (void)CLOCK_DisableClock(s_saiClock[SAI_GetInstance(base)]);
677 #endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */
678 }
679 
680 /*!
681  * brief  Sets the SAI Tx configuration structure to default values.
682  *
683  * deprecated Do not use this function.  It has been superceded by @ref
684  * SAI_GetClassicI2SConfig, SAI_GetLeftJustifiedConfig,SAI_GetRightJustifiedConfig, SAI_GetDSPConfig,SAI_GetTDMConfig
685  *
686  * This API initializes the configuration structure for use in SAI_TxConfig().
687  * The initialized structure can remain unchanged in SAI_TxConfig(), or it can be modified
688  *  before calling SAI_TxConfig().
689  * This is an example.
690    code
691    sai_config_t config;
692    SAI_TxGetDefaultConfig(&config);
693    endcode
694  *
695  * param config pointer to master configuration structure
696  */
SAI_TxGetDefaultConfig(sai_config_t * config)697 void SAI_TxGetDefaultConfig(sai_config_t *config)
698 {
699     /* Initializes the configure structure to zero. */
700     (void)memset(config, 0, sizeof(*config));
701 
702     config->bclkSource  = kSAI_BclkSourceMclkDiv;
703     config->masterSlave = kSAI_Master;
704 #if defined(FSL_FEATURE_SAI_HAS_MCR) && (FSL_FEATURE_SAI_HAS_MCR)
705     config->mclkOutputEnable = true;
706 #if !(defined(FSL_FEATURE_SAI_HAS_NO_MCR_MICS) && (FSL_FEATURE_SAI_HAS_NO_MCR_MICS))
707     config->mclkSource = kSAI_MclkSourceSysclk;
708 #endif
709 #endif /* FSL_FEATURE_SAI_HAS_MCR */
710     config->protocol = kSAI_BusI2S;
711     config->syncMode = kSAI_ModeAsync;
712 }
713 
714 /*!
715  * brief  Sets the SAI Rx configuration structure to default values.
716  *
717  * deprecated Do not use this function.  It has been superceded by @ref
718  * SAI_GetClassicI2SConfig,SAI_GetLeftJustifiedConfig,SAI_GetRightJustifiedConfig,SAI_GetDSPConfig,SAI_GetTDMConfig
719  *
720  * This API initializes the configuration structure for use in SAI_RxConfig().
721  * The initialized structure can remain unchanged in SAI_RxConfig() or it can be modified
722  *  before calling SAI_RxConfig().
723  * This is an example.
724    code
725    sai_config_t config;
726    SAI_RxGetDefaultConfig(&config);
727    endcode
728  *
729  * param config pointer to master configuration structure
730  */
SAI_RxGetDefaultConfig(sai_config_t * config)731 void SAI_RxGetDefaultConfig(sai_config_t *config)
732 {
733     /* Initializes the configure structure to zero. */
734     (void)memset(config, 0, sizeof(*config));
735 
736     config->bclkSource  = kSAI_BclkSourceMclkDiv;
737     config->masterSlave = kSAI_Master;
738 #if defined(FSL_FEATURE_SAI_HAS_MCR) && (FSL_FEATURE_SAI_HAS_MCR)
739     config->mclkOutputEnable = true;
740 #if !(defined(FSL_FEATURE_SAI_HAS_NO_MCR_MICS) && (FSL_FEATURE_SAI_HAS_NO_MCR_MICS))
741     config->mclkSource = kSAI_MclkSourceSysclk;
742 #endif
743 #endif /* FSL_FEATURE_SAI_HAS_MCR */
744     config->protocol = kSAI_BusI2S;
745     config->syncMode = kSAI_ModeSync;
746 }
747 
748 /*!
749  * brief Resets the SAI Tx.
750  *
751  * This function enables the software reset and FIFO reset of SAI Tx. After reset, clear the reset bit.
752  *
753  * param base SAI base pointer
754  */
SAI_TxReset(I2S_Type * base)755 void SAI_TxReset(I2S_Type *base)
756 {
757     /* Set the software reset and FIFO reset to clear internal state */
758     base->TCSR = I2S_TCSR_SR_MASK | I2S_TCSR_FR_MASK;
759 
760     /* Clear software reset bit, this should be done by software */
761     base->TCSR &= ~I2S_TCSR_SR_MASK;
762 
763     /* Reset all Tx register values */
764     base->TCR2 = 0;
765     base->TCR3 = 0;
766     base->TCR4 = 0;
767     base->TCR5 = 0;
768     base->TMR  = 0;
769 }
770 
771 /*!
772  * brief Resets the SAI Rx.
773  *
774  * This function enables the software reset and FIFO reset of SAI Rx. After reset, clear the reset bit.
775  *
776  * param base SAI base pointer
777  */
SAI_RxReset(I2S_Type * base)778 void SAI_RxReset(I2S_Type *base)
779 {
780     /* Set the software reset and FIFO reset to clear internal state */
781     base->RCSR = I2S_RCSR_SR_MASK | I2S_RCSR_FR_MASK;
782 
783     /* Clear software reset bit, this should be done by software */
784     base->RCSR &= ~I2S_RCSR_SR_MASK;
785 
786     /* Reset all Rx register values */
787     base->RCR2 = 0;
788     base->RCR3 = 0;
789     base->RCR4 = 0;
790     base->RCR5 = 0;
791     base->RMR  = 0;
792 }
793 
794 /*!
795  * brief Enables/disables the SAI Tx.
796  *
797  * param base SAI base pointer
798  * param enable True means enable SAI Tx, false means disable.
799  */
SAI_TxEnable(I2S_Type * base,bool enable)800 void SAI_TxEnable(I2S_Type *base, bool enable)
801 {
802     if (enable)
803     {
804         /* If clock is sync with Rx, should enable RE bit. */
805         if (((base->TCR2 & I2S_TCR2_SYNC_MASK) >> I2S_TCR2_SYNC_SHIFT) == 0x1U)
806         {
807             base->RCSR = ((base->RCSR & 0xFFE3FFFFU) | I2S_RCSR_RE_MASK);
808         }
809         base->TCSR = ((base->TCSR & 0xFFE3FFFFU) | I2S_TCSR_TE_MASK);
810         /* Also need to clear the FIFO error flag before start */
811         SAI_TxClearStatusFlags(base, kSAI_FIFOErrorFlag);
812     }
813     else
814     {
815         /* If Rx not in sync with Tx, then disable Tx, otherwise, shall not disable Tx */
816         if (((base->RCR2 & I2S_RCR2_SYNC_MASK) >> I2S_RCR2_SYNC_SHIFT) != 0x1U)
817         {
818             /* Disable TE bit */
819             base->TCSR = ((base->TCSR & 0xFFE3FFFFU) & (~I2S_TCSR_TE_MASK));
820         }
821     }
822 }
823 
824 /*!
825  * brief Enables/disables the SAI Rx.
826  *
827  * param base SAI base pointer
828  * param enable True means enable SAI Rx, false means disable.
829  */
SAI_RxEnable(I2S_Type * base,bool enable)830 void SAI_RxEnable(I2S_Type *base, bool enable)
831 {
832     if (enable)
833     {
834         /* If clock is sync with Tx, should enable TE bit. */
835         if (((base->RCR2 & I2S_RCR2_SYNC_MASK) >> I2S_RCR2_SYNC_SHIFT) == 0x1U)
836         {
837             base->TCSR = ((base->TCSR & 0xFFE3FFFFU) | I2S_TCSR_TE_MASK);
838         }
839         base->RCSR = ((base->RCSR & 0xFFE3FFFFU) | I2S_RCSR_RE_MASK);
840         /* Also need to clear the FIFO error flag before start */
841         SAI_RxClearStatusFlags(base, kSAI_FIFOErrorFlag);
842     }
843     else
844     {
845         /* If Tx not in sync with Rx, then disable Rx, otherwise, shall not disable Rx */
846         if (((base->TCR2 & I2S_TCR2_SYNC_MASK) >> I2S_TCR2_SYNC_SHIFT) != 0x1U)
847         {
848             /* Disable RE bit */
849             base->RCSR = ((base->RCSR & 0xFFE3FFFFU) & (~I2S_RCSR_RE_MASK));
850         }
851     }
852 }
853 
854 /*!
855  * brief Do software reset or FIFO reset .
856  *
857  * FIFO reset means clear all the data in the FIFO, and make the FIFO pointer both to 0.
858  * Software reset means clear the Tx internal logic, including the bit clock, frame count etc. But software
859  * reset will not clear any configuration registers like TCR1~TCR5.
860  * This function will also clear all the error flags such as FIFO error, sync error etc.
861  *
862  * param base SAI base pointer
863  * param resetType Reset type, FIFO reset or software reset
864  */
SAI_TxSoftwareReset(I2S_Type * base,sai_reset_type_t resetType)865 void SAI_TxSoftwareReset(I2S_Type *base, sai_reset_type_t resetType)
866 {
867     base->TCSR |= (uint32_t)resetType;
868 
869     /* Clear the software reset */
870     base->TCSR &= ~I2S_TCSR_SR_MASK;
871 }
872 
873 /*!
874  * brief Do software reset or FIFO reset .
875  *
876  * FIFO reset means clear all the data in the FIFO, and make the FIFO pointer both to 0.
877  * Software reset means clear the Rx internal logic, including the bit clock, frame count etc. But software
878  * reset will not clear any configuration registers like RCR1~RCR5.
879  * This function will also clear all the error flags such as FIFO error, sync error etc.
880  *
881  * param base SAI base pointer
882  * param resetType Reset type, FIFO reset or software reset
883  */
SAI_RxSoftwareReset(I2S_Type * base,sai_reset_type_t resetType)884 void SAI_RxSoftwareReset(I2S_Type *base, sai_reset_type_t resetType)
885 {
886     base->RCSR |= (uint32_t)resetType;
887 
888     /* Clear the software reset */
889     base->RCSR &= ~I2S_RCSR_SR_MASK;
890 }
891 
892 /*!
893  * brief Set the Tx channel FIFO enable mask.
894  *
895  * param base SAI base pointer
896  * param mask Channel enable mask, 0 means all channel FIFO disabled, 1 means channel 0 enabled,
897  * 3 means both channel 0 and channel 1 enabled.
898  */
SAI_TxSetChannelFIFOMask(I2S_Type * base,uint8_t mask)899 void SAI_TxSetChannelFIFOMask(I2S_Type *base, uint8_t mask)
900 {
901     base->TCR3 &= ~I2S_TCR3_TCE_MASK;
902     base->TCR3 |= I2S_TCR3_TCE(mask);
903 }
904 
905 /*!
906  * brief Set the Rx channel FIFO enable mask.
907  *
908  * param base SAI base pointer
909  * param mask Channel enable mask, 0 means all channel FIFO disabled, 1 means channel 0 enabled,
910  * 3 means both channel 0 and channel 1 enabled.
911  */
SAI_RxSetChannelFIFOMask(I2S_Type * base,uint8_t mask)912 void SAI_RxSetChannelFIFOMask(I2S_Type *base, uint8_t mask)
913 {
914     base->RCR3 &= ~I2S_RCR3_RCE_MASK;
915     base->RCR3 |= I2S_RCR3_RCE(mask);
916 }
917 
918 /*!
919  * brief Set the Tx data order.
920  *
921  * param base SAI base pointer
922  * param order Data order MSB or LSB
923  */
SAI_TxSetDataOrder(I2S_Type * base,sai_data_order_t order)924 void SAI_TxSetDataOrder(I2S_Type *base, sai_data_order_t order)
925 {
926     uint32_t val = (base->TCR4) & (~I2S_TCR4_MF_MASK);
927 
928     val |= I2S_TCR4_MF(order);
929     base->TCR4 = val;
930 }
931 
932 /*!
933  * brief Set the Rx data order.
934  *
935  * param base SAI base pointer
936  * param order Data order MSB or LSB
937  */
SAI_RxSetDataOrder(I2S_Type * base,sai_data_order_t order)938 void SAI_RxSetDataOrder(I2S_Type *base, sai_data_order_t order)
939 {
940     uint32_t val = (base->RCR4) & (~I2S_RCR4_MF_MASK);
941 
942     val |= I2S_RCR4_MF(order);
943     base->RCR4 = val;
944 }
945 
946 /*!
947  * brief Set the Tx data order.
948  *
949  * param base SAI base pointer
950  * param order Data order MSB or LSB
951  */
SAI_TxSetBitClockPolarity(I2S_Type * base,sai_clock_polarity_t polarity)952 void SAI_TxSetBitClockPolarity(I2S_Type *base, sai_clock_polarity_t polarity)
953 {
954     uint32_t val = (base->TCR2) & (~I2S_TCR2_BCP_MASK);
955 
956     val |= I2S_TCR2_BCP(polarity);
957     base->TCR2 = val;
958 }
959 
960 /*!
961  * brief Set the Rx data order.
962  *
963  * param base SAI base pointer
964  * param order Data order MSB or LSB
965  */
SAI_RxSetBitClockPolarity(I2S_Type * base,sai_clock_polarity_t polarity)966 void SAI_RxSetBitClockPolarity(I2S_Type *base, sai_clock_polarity_t polarity)
967 {
968     uint32_t val = (base->RCR2) & (~I2S_RCR2_BCP_MASK);
969 
970     val |= I2S_RCR2_BCP(polarity);
971     base->RCR2 = val;
972 }
973 
974 /*!
975  * brief Set the Tx data order.
976  *
977  * param base SAI base pointer
978  * param order Data order MSB or LSB
979  */
SAI_TxSetFrameSyncPolarity(I2S_Type * base,sai_clock_polarity_t polarity)980 void SAI_TxSetFrameSyncPolarity(I2S_Type *base, sai_clock_polarity_t polarity)
981 {
982     uint32_t val = (base->TCR4) & (~I2S_TCR4_FSP_MASK);
983 
984     val |= I2S_TCR4_FSP(polarity);
985     base->TCR4 = val;
986 }
987 
988 /*!
989  * brief Set the Rx data order.
990  *
991  * param base SAI base pointer
992  * param order Data order MSB or LSB
993  */
SAI_RxSetFrameSyncPolarity(I2S_Type * base,sai_clock_polarity_t polarity)994 void SAI_RxSetFrameSyncPolarity(I2S_Type *base, sai_clock_polarity_t polarity)
995 {
996     uint32_t val = (base->RCR4) & (~I2S_RCR4_FSP_MASK);
997 
998     val |= I2S_RCR4_FSP(polarity);
999     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  */
SAI_TxSetFIFOPacking(I2S_Type * base,sai_fifo_packing_t pack)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  */
SAI_RxSetFIFOPacking(I2S_Type * base,sai_fifo_packing_t pack)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  */
SAI_TxSetBitClockRate(I2S_Type * base,uint32_t sourceClockHz,uint32_t sampleRate,uint32_t bitWidth,uint32_t channelNumbers)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  */
SAI_RxSetBitClockRate(I2S_Type * base,uint32_t sourceClockHz,uint32_t sampleRate,uint32_t bitWidth,uint32_t channelNumbers)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  */
SAI_TxSetBitclockConfig(I2S_Type * base,sai_master_slave_t masterSlave,sai_bit_clock_t * config)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  */
SAI_RxSetBitclockConfig(I2S_Type * base,sai_master_slave_t masterSlave,sai_bit_clock_t * config)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  */
SAI_SetMasterClockConfig(I2S_Type * base,sai_master_clock_t * config)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  */
SAI_TxSetFifoConfig(I2S_Type * base,sai_fifo_t * config)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  */
SAI_RxSetFifoConfig(I2S_Type * base,sai_fifo_t * config)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  */
SAI_TxSetFrameSyncConfig(I2S_Type * base,sai_master_slave_t masterSlave,sai_frame_sync_t * config)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  */
SAI_RxSetFrameSyncConfig(I2S_Type * base,sai_master_slave_t masterSlave,sai_frame_sync_t * config)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  */
SAI_TxSetSerialDataConfig(I2S_Type * base,sai_serial_data_t * config)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  */
SAI_RxSetSerialDataConfig(I2S_Type * base,sai_serial_data_t * config)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  */
SAI_TxSetConfig(I2S_Type * base,sai_transceiver_t * config)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  */
SAI_TransferTxSetConfig(I2S_Type * base,sai_handle_t * handle,sai_transceiver_t * config)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  */
SAI_RxSetConfig(I2S_Type * base,sai_transceiver_t * config)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  */
SAI_TransferRxSetConfig(I2S_Type * base,sai_handle_t * handle,sai_transceiver_t * config)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  */
SAI_GetClassicI2SConfig(sai_transceiver_t * config,sai_word_width_t bitWidth,sai_mono_stereo_t mode,uint32_t saiChannelMask)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  */
SAI_GetLeftJustifiedConfig(sai_transceiver_t * config,sai_word_width_t bitWidth,sai_mono_stereo_t mode,uint32_t saiChannelMask)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  */
SAI_GetRightJustifiedConfig(sai_transceiver_t * config,sai_word_width_t bitWidth,sai_mono_stereo_t mode,uint32_t saiChannelMask)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  */
SAI_GetDSPConfig(sai_transceiver_t * config,sai_frame_sync_len_t frameSyncWidth,sai_word_width_t bitWidth,sai_mono_stereo_t mode,uint32_t saiChannelMask)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  */
SAI_GetTDMConfig(sai_transceiver_t * config,sai_frame_sync_len_t frameSyncWidth,sai_word_width_t bitWidth,uint32_t dataWordNum,uint32_t saiChannelMask)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  */
SAI_TxSetFormat(I2S_Type * base,sai_transfer_format_t * format,uint32_t mclkSourceClockHz,uint32_t bclkSourceClockHz)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  */
SAI_RxSetFormat(I2S_Type * base,sai_transfer_format_t * format,uint32_t mclkSourceClockHz,uint32_t bclkSourceClockHz)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  */
SAI_WriteBlocking(I2S_Type * base,uint32_t channel,uint32_t bitWidth,uint8_t * buffer,uint32_t size)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  */
SAI_WriteMultiChannelBlocking(I2S_Type * base,uint32_t channel,uint32_t channelMask,uint32_t bitWidth,uint8_t * buffer,uint32_t size)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  */
SAI_ReadMultiChannelBlocking(I2S_Type * base,uint32_t channel,uint32_t channelMask,uint32_t bitWidth,uint8_t * buffer,uint32_t size)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  */
SAI_ReadBlocking(I2S_Type * base,uint32_t channel,uint32_t bitWidth,uint8_t * buffer,uint32_t size)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  */
SAI_TransferTxCreateHandle(I2S_Type * base,sai_handle_t * handle,sai_transfer_callback_t callback,void * userData)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  */
SAI_TransferRxCreateHandle(I2S_Type * base,sai_handle_t * handle,sai_transfer_callback_t callback,void * userData)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  */
SAI_TransferTxSetFormat(I2S_Type * base,sai_handle_t * handle,sai_transfer_format_t * format,uint32_t mclkSourceClockHz,uint32_t bclkSourceClockHz)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  */
SAI_TransferRxSetFormat(I2S_Type * base,sai_handle_t * handle,sai_transfer_format_t * format,uint32_t mclkSourceClockHz,uint32_t bclkSourceClockHz)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  */
SAI_TransferSendNonBlocking(I2S_Type * base,sai_handle_t * handle,sai_transfer_t * xfer)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  */
SAI_TransferReceiveNonBlocking(I2S_Type * base,sai_handle_t * handle,sai_transfer_t * xfer)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  */
SAI_TransferGetSendCount(I2S_Type * base,sai_handle_t * handle,size_t * count)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  */
SAI_TransferGetReceiveCount(I2S_Type * base,sai_handle_t * handle,size_t * count)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  */
SAI_TransferAbortSend(I2S_Type * base,sai_handle_t * handle)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  */
SAI_TransferAbortReceive(I2S_Type * base,sai_handle_t * handle)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  */
SAI_TransferTerminateSend(I2S_Type * base,sai_handle_t * handle)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  */
SAI_TransferTerminateReceive(I2S_Type * base,sai_handle_t * handle)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  */
SAI_TransferTxHandleIRQ(I2S_Type * base,sai_handle_t * handle)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  */
SAI_TransferRxHandleIRQ(I2S_Type * base,sai_handle_t * handle)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);
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);
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);
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);
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);
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);
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);
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);
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);
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);
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);
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);
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);
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);
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);
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);
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);
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);
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);
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);
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);
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);
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);
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);
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);
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);
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);
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);
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);
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);
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);
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);
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);
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);
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);
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);
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);
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);
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);
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);
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);
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);
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);
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);
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);
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 */