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 #if defined(SAI_RSTS)
37 #define SAI_RESETS_ARRAY SAI_RSTS
38 #endif
39 /*******************************************************************************
40  * Prototypes
41  ******************************************************************************/
42 /*!
43  * @brief sai get rx enabled interrupt status.
44  *
45  *
46  * @param base SAI base pointer.
47  * @param enableFlag enable flag to check.
48  * @param statusFlag status flag to check.
49  */
50 static bool SAI_RxGetEnabledInterruptStatus(I2S_Type *base, uint32_t enableFlag, uint32_t statusFlag);
51 
52 /*!
53  * @brief sai get tx enabled interrupt status.
54  *
55  *
56  * @param base SAI base pointer.
57  * @param enableFlag enable flag to check.
58  * @param statusFlag status flag to check.
59  */
60 static bool SAI_TxGetEnabledInterruptStatus(I2S_Type *base, uint32_t enableFlag, uint32_t statusFlag);
61 
62 /*!
63  * @brief Set the master clock divider.
64  *
65  * This API will compute the master clock divider according to master clock frequency and master
66  * clock source clock source frequency.
67  *
68  * @param base SAI base pointer.
69  * @param mclk_Hz Mater clock frequency in Hz.
70  * @param mclkSrcClock_Hz Master clock source frequency in Hz.
71  */
72 static bool SAI_TxGetEnabledInterruptStatus(I2S_Type *base, uint32_t enableFlag, uint32_t statusFlag);
73 
74 #if ((defined(FSL_FEATURE_SAI_HAS_MCLKDIV_REGISTER) && (FSL_FEATURE_SAI_HAS_MCLKDIV_REGISTER)) || \
75      (defined(FSL_FEATURE_SAI_HAS_MCR_MCLK_POST_DIV) && (FSL_FEATURE_SAI_HAS_MCR_MCLK_POST_DIV)))
76 
77 /*!
78  * @brief Set the master clock divider.
79  *
80  * This API will compute the master clock divider according to master clock frequency and master
81  * clock source clock source frequency.
82  *
83  * @param base SAI base pointer.
84  * @param mclk_Hz Mater clock frequency in Hz.
85  * @param mclkSrcClock_Hz Master clock source frequency in Hz.
86  */
87 static void SAI_SetMasterClockDivider(I2S_Type *base, uint32_t mclk_Hz, uint32_t mclkSrcClock_Hz);
88 #endif /* FSL_FEATURE_SAI_HAS_MCLKDIV_REGISTER */
89 
90 /*!
91  * @brief Get the instance number for SAI.
92  *
93  * @param base SAI base pointer.
94  */
95 static uint32_t SAI_GetInstance(I2S_Type *base);
96 
97 /*!
98  * @brief sends a piece of data in non-blocking way.
99  *
100  * @param base SAI base pointer
101  * @param channel start channel number.
102  * @param channelMask enabled channels mask.
103  * @param endChannel end channel numbers.
104  * @param bitWidth How many bits in a audio word, usually 8/16/24/32 bits.
105  * @param buffer Pointer to the data to be written.
106  * @param size Bytes to be written.
107  */
108 static void SAI_WriteNonBlocking(I2S_Type *base,
109                                  uint32_t channel,
110                                  uint32_t channelMask,
111                                  uint32_t endChannel,
112                                  uint8_t bitWidth,
113                                  uint8_t *buffer,
114                                  uint32_t size);
115 
116 /*!
117  * @brief Receive a piece of data in non-blocking way.
118  *
119  * @param base SAI base pointer
120  * @param channel start channel number.
121  * @param channelMask enabled channels mask.
122  * @param endChannel end channel numbers.
123  * @param bitWidth How many bits in a audio word, usually 8/16/24/32 bits.
124  * @param buffer Pointer to the data to be read.
125  * @param size Bytes to be read.
126  */
127 static void SAI_ReadNonBlocking(I2S_Type *base,
128                                 uint32_t channel,
129                                 uint32_t channelMask,
130                                 uint32_t endChannel,
131                                 uint8_t bitWidth,
132                                 uint8_t *buffer,
133                                 uint32_t size);
134 
135 /*!
136  * @brief Get classic I2S mode configurations.
137  *
138  * @param config transceiver configurations
139  * @param bitWidth audio data bitWidth.
140  * @param mode audio data channel
141  * @param saiChannelMask channel mask value to enable
142  */
143 static void SAI_GetCommonConfig(sai_transceiver_t *config,
144                                 sai_word_width_t bitWidth,
145                                 sai_mono_stereo_t mode,
146                                 uint32_t saiChannelMask);
147 /*******************************************************************************
148  * Variables
149  ******************************************************************************/
150 /* Base pointer array */
151 static I2S_Type *const s_saiBases[] = I2S_BASE_PTRS;
152 #if defined(SAI_RESETS_ARRAY)
153 /* Reset array */
154 static const reset_ip_name_t s_saiReset[] = SAI_RESETS_ARRAY;
155 #endif
156 /*!@brief SAI handle pointer */
157 static sai_handle_t *s_saiHandle[ARRAY_SIZE(s_saiBases)][2];
158 /* IRQ number array */
159 static const IRQn_Type s_saiTxIRQ[] = I2S_TX_IRQS;
160 static const IRQn_Type s_saiRxIRQ[] = I2S_RX_IRQS;
161 #if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
162 /* Clock name array */
163 static const clock_ip_name_t s_saiClock[] = SAI_CLOCKS;
164 #endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */
165 /*! @brief Pointer to tx IRQ handler for each instance. */
166 static sai_tx_isr_t s_saiTxIsr;
167 /*! @brief Pointer to tx IRQ handler for each instance. */
168 static sai_rx_isr_t s_saiRxIsr;
169 
170 /*******************************************************************************
171  * Code
172  ******************************************************************************/
SAI_RxGetEnabledInterruptStatus(I2S_Type * base,uint32_t enableFlag,uint32_t statusFlag)173 static bool SAI_RxGetEnabledInterruptStatus(I2S_Type *base, uint32_t enableFlag, uint32_t statusFlag)
174 {
175     uint32_t rcsr = base->RCSR;
176 
177     return IS_SAI_FLAG_SET(rcsr, enableFlag) && IS_SAI_FLAG_SET(rcsr, statusFlag);
178 }
179 
SAI_TxGetEnabledInterruptStatus(I2S_Type * base,uint32_t enableFlag,uint32_t statusFlag)180 static bool SAI_TxGetEnabledInterruptStatus(I2S_Type *base, uint32_t enableFlag, uint32_t statusFlag)
181 {
182     uint32_t tcsr = base->TCSR;
183 
184     return IS_SAI_FLAG_SET(tcsr, enableFlag) && IS_SAI_FLAG_SET(tcsr, statusFlag);
185 }
186 
187 #if ((defined(FSL_FEATURE_SAI_HAS_MCLKDIV_REGISTER) && (FSL_FEATURE_SAI_HAS_MCLKDIV_REGISTER)) || \
188      (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)189 static void SAI_SetMasterClockDivider(I2S_Type *base, uint32_t mclk_Hz, uint32_t mclkSrcClock_Hz)
190 {
191     assert(mclk_Hz <= mclkSrcClock_Hz);
192 
193     uint32_t sourceFreq = mclkSrcClock_Hz / 100U; /*In order to prevent overflow */
194     uint32_t targetFreq = mclk_Hz / 100U;         /*In order to prevent overflow */
195 
196 #if FSL_FEATURE_SAI_HAS_MCR_MCLK_POST_DIV
197     uint32_t postDivider = sourceFreq / targetFreq;
198 
199     /* if source equal to target, then disable divider */
200     if (postDivider == 1U)
201     {
202         base->MCR &= ~I2S_MCR_DIVEN_MASK;
203     }
204     else
205     {
206         base->MCR = (base->MCR & (~I2S_MCR_DIV_MASK)) | I2S_MCR_DIV(postDivider / 2U - 1U) | I2S_MCR_DIVEN_MASK;
207     }
208 #endif
209 #if FSL_FEATURE_SAI_HAS_MCLKDIV_REGISTER
210     uint16_t fract, divide;
211     uint32_t remaind           = 0;
212     uint32_t current_remainder = 0xFFFFFFFFU;
213     uint16_t current_fract     = 0;
214     uint16_t current_divide    = 0;
215     uint32_t mul_freq          = 0;
216     uint32_t max_fract         = 256;
217 
218     /* Compute the max fract number */
219     max_fract = targetFreq * 4096U / sourceFreq + 1U;
220     if (max_fract > 256U)
221     {
222         max_fract = 256U;
223     }
224 
225     /* Looking for the closet frequency */
226     for (fract = 1; fract < max_fract; fract++)
227     {
228         mul_freq = sourceFreq * fract;
229         remaind  = mul_freq % targetFreq;
230         divide   = (uint16_t)(mul_freq / targetFreq);
231 
232         /* Find the exactly frequency */
233         if (remaind == 0U)
234         {
235             current_fract  = fract;
236             current_divide = (uint16_t)(mul_freq / targetFreq);
237             break;
238         }
239 
240         /* Closer to next one, set the closest to next data */
241         if (remaind > mclk_Hz / 2U)
242         {
243             remaind = targetFreq - remaind;
244             divide += 1U;
245         }
246 
247         /* Update the closest div and fract */
248         if (remaind < current_remainder)
249         {
250             current_fract     = fract;
251             current_divide    = divide;
252             current_remainder = remaind;
253         }
254     }
255 
256     /* Fill the computed fract and divider to registers */
257     base->MDR = I2S_MDR_DIVIDE(current_divide - 1UL) | I2S_MDR_FRACT(current_fract - 1UL);
258 
259     /* Waiting for the divider updated */
260     while ((base->MCR & I2S_MCR_DUF_MASK) != 0UL)
261     {
262     }
263 #endif
264 }
265 #endif /* FSL_FEATURE_SAI_HAS_MCLKDIV_REGISTER */
266 
SAI_GetInstance(I2S_Type * base)267 static uint32_t SAI_GetInstance(I2S_Type *base)
268 {
269     uint32_t instance;
270 
271     /* Find the instance index from base address mappings. */
272     for (instance = 0; instance < ARRAY_SIZE(s_saiBases); instance++)
273     {
274         if (s_saiBases[instance] == base)
275         {
276             break;
277         }
278     }
279 
280     if (instance == ARRAY_SIZE(s_saiBases)) {
281         assert(false);
282 	/* asserts may not always be enabled. As such, return NULL here to
283 	 * avoid compilation warnings complaining about a possible out-of-bounds
284 	 * access. If the user decides to disable the asserts, it is up to them
285 	 * to debug in case of out-of-bounds access as SAI_GetInstance() will
286 	 * return a valid instance.
287 	 */
288 	return 0;
289     }
290 
291     return instance;
292 }
293 
SAI_WriteNonBlocking(I2S_Type * base,uint32_t channel,uint32_t channelMask,uint32_t endChannel,uint8_t bitWidth,uint8_t * buffer,uint32_t size)294 static void SAI_WriteNonBlocking(I2S_Type *base,
295                                  uint32_t channel,
296                                  uint32_t channelMask,
297                                  uint32_t endChannel,
298                                  uint8_t bitWidth,
299                                  uint8_t *buffer,
300                                  uint32_t size)
301 {
302     uint32_t i = 0, j = 0U;
303     uint8_t m            = 0;
304     uint8_t bytesPerWord = bitWidth / 8U;
305     uint32_t data        = 0;
306     uint32_t temp        = 0;
307 
308     for (i = 0; i < size / bytesPerWord; i++)
309     {
310         for (j = channel; j <= endChannel; j++)
311         {
312             if (IS_SAI_FLAG_SET((1UL << j), channelMask))
313             {
314                 for (m = 0; m < bytesPerWord; m++)
315                 {
316                     temp = (uint32_t)(*buffer);
317                     data |= (temp << (8U * m));
318                     buffer++;
319                 }
320                 base->TDR[j] = data;
321                 data         = 0;
322             }
323         }
324     }
325 }
326 
SAI_ReadNonBlocking(I2S_Type * base,uint32_t channel,uint32_t channelMask,uint32_t endChannel,uint8_t bitWidth,uint8_t * buffer,uint32_t size)327 static void SAI_ReadNonBlocking(I2S_Type *base,
328                                 uint32_t channel,
329                                 uint32_t channelMask,
330                                 uint32_t endChannel,
331                                 uint8_t bitWidth,
332                                 uint8_t *buffer,
333                                 uint32_t size)
334 {
335     uint32_t i = 0, j = 0;
336     uint8_t m            = 0;
337     uint8_t bytesPerWord = bitWidth / 8U;
338     uint32_t data        = 0;
339 
340     for (i = 0; i < size / bytesPerWord; i++)
341     {
342         for (j = channel; j <= endChannel; j++)
343         {
344             if (IS_SAI_FLAG_SET((1UL << j), channelMask))
345             {
346                 data = base->RDR[j];
347                 for (m = 0; m < bytesPerWord; m++)
348                 {
349                     *buffer = (uint8_t)(data >> (8U * m)) & 0xFFU;
350                     buffer++;
351                 }
352             }
353         }
354     }
355 }
356 
SAI_GetCommonConfig(sai_transceiver_t * config,sai_word_width_t bitWidth,sai_mono_stereo_t mode,uint32_t saiChannelMask)357 static void SAI_GetCommonConfig(sai_transceiver_t *config,
358                                 sai_word_width_t bitWidth,
359                                 sai_mono_stereo_t mode,
360                                 uint32_t saiChannelMask)
361 {
362     assert(NULL != config);
363     assert(saiChannelMask != 0U);
364 
365     (void)memset(config, 0, sizeof(sai_transceiver_t));
366 
367     config->channelMask = (uint8_t)saiChannelMask;
368     /* sync mode default configurations */
369     config->syncMode = kSAI_ModeAsync;
370 
371     /* master mode default */
372     config->masterSlave = kSAI_Master;
373 
374     /* bit default configurations */
375     config->bitClock.bclkSrcSwap    = false;
376     config->bitClock.bclkInputDelay = false;
377     config->bitClock.bclkPolarity   = kSAI_SampleOnRisingEdge;
378     config->bitClock.bclkSource     = kSAI_BclkSourceMclkDiv;
379 
380     /* frame sync default configurations */
381     config->frameSync.frameSyncWidth = (uint8_t)bitWidth;
382     config->frameSync.frameSyncEarly = true;
383 #if defined(FSL_FEATURE_SAI_HAS_ON_DEMAND_MODE) && FSL_FEATURE_SAI_HAS_ON_DEMAND_MODE
384     config->frameSync.frameSyncGenerateOnDemand = false;
385 #endif
386     config->frameSync.frameSyncPolarity = kSAI_PolarityActiveLow;
387 
388     /* serial data default configurations */
389 #if defined(FSL_FEATURE_SAI_HAS_CHANNEL_MODE) && FSL_FEATURE_SAI_HAS_CHANNEL_MODE
390     config->serialData.dataMode = kSAI_DataPinStateOutputZero;
391 #endif
392     config->serialData.dataOrder           = kSAI_DataMSB;
393     config->serialData.dataWord0Length     = (uint8_t)bitWidth;
394     config->serialData.dataWordLength      = (uint8_t)bitWidth;
395     config->serialData.dataWordNLength     = (uint8_t)bitWidth;
396     config->serialData.dataFirstBitShifted = (uint8_t)bitWidth;
397     config->serialData.dataWordNum         = 2U;
398     config->serialData.dataMaskedWord      = (uint32_t)mode;
399 
400 #if defined(FSL_FEATURE_SAI_HAS_FIFO_FUNCTION_AFTER_ERROR) && FSL_FEATURE_SAI_HAS_FIFO_FUNCTION_AFTER_ERROR
401     config->fifo.fifoContinueOneError = true;
402 #endif
403 }
404 
405 /*!
406  * brief Initializes the SAI peripheral.
407  *
408  * This API gates the SAI clock. The SAI module can't operate unless SAI_Init is called to enable the clock.
409  *
410  * param base SAI base pointer
411  */
SAI_Init(I2S_Type * base)412 void SAI_Init(I2S_Type *base)
413 {
414 #if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
415     /* Enable the SAI clock */
416     (void)CLOCK_EnableClock(s_saiClock[SAI_GetInstance(base)]);
417 #endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */
418 
419 #if defined(SAI_RESETS_ARRAY)
420     RESET_ReleasePeripheralReset(s_saiReset[SAI_GetInstance(base)]);
421 #endif
422 
423 #if defined(FSL_FEATURE_SAI_HAS_FIFO) && (FSL_FEATURE_SAI_HAS_FIFO)
424     /* disable interrupt and DMA request*/
425     base->TCSR &=
426         ~(I2S_TCSR_FRIE_MASK | I2S_TCSR_FWIE_MASK | I2S_TCSR_FEIE_MASK | I2S_TCSR_FRDE_MASK | I2S_TCSR_FWDE_MASK);
427     base->RCSR &=
428         ~(I2S_RCSR_FRIE_MASK | I2S_RCSR_FWIE_MASK | I2S_RCSR_FEIE_MASK | I2S_RCSR_FRDE_MASK | I2S_RCSR_FWDE_MASK);
429 #else
430     /* disable interrupt and DMA request*/
431     base->TCSR &= ~(I2S_TCSR_FWIE_MASK | I2S_TCSR_FEIE_MASK | I2S_TCSR_FWDE_MASK);
432     base->RCSR &= ~(I2S_RCSR_FWIE_MASK | I2S_RCSR_FEIE_MASK | I2S_RCSR_FWDE_MASK);
433 #endif
434 }
435 
436 /*!
437  * brief De-initializes the SAI peripheral.
438  *
439  * This API gates the SAI clock. The SAI module can't operate unless SAI_TxInit
440  * or SAI_RxInit is called to enable the clock.
441  *
442  * param base SAI base pointer
443  */
SAI_Deinit(I2S_Type * base)444 void SAI_Deinit(I2S_Type *base)
445 {
446     SAI_TxEnable(base, false);
447     SAI_RxEnable(base, false);
448 #if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
449     (void)CLOCK_DisableClock(s_saiClock[SAI_GetInstance(base)]);
450 #endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */
451 }
452 
453 /*!
454  * brief Resets the SAI Tx.
455  *
456  * This function enables the software reset and FIFO reset of SAI Tx. After reset, clear the reset bit.
457  *
458  * param base SAI base pointer
459  */
SAI_TxReset(I2S_Type * base)460 void SAI_TxReset(I2S_Type *base)
461 {
462     /* Set the software reset and FIFO reset to clear internal state */
463     base->TCSR = I2S_TCSR_SR_MASK | I2S_TCSR_FR_MASK;
464 
465     /* Clear software reset bit, this should be done by software */
466     base->TCSR &= ~I2S_TCSR_SR_MASK;
467 
468     /* Reset all Tx register values */
469     base->TCR2 = 0;
470     base->TCR3 = 0;
471     base->TCR4 = 0;
472     base->TCR5 = 0;
473     base->TMR  = 0;
474 }
475 
476 /*!
477  * brief Resets the SAI Rx.
478  *
479  * This function enables the software reset and FIFO reset of SAI Rx. After reset, clear the reset bit.
480  *
481  * param base SAI base pointer
482  */
SAI_RxReset(I2S_Type * base)483 void SAI_RxReset(I2S_Type *base)
484 {
485     /* Set the software reset and FIFO reset to clear internal state */
486     base->RCSR = I2S_RCSR_SR_MASK | I2S_RCSR_FR_MASK;
487 
488     /* Clear software reset bit, this should be done by software */
489     base->RCSR &= ~I2S_RCSR_SR_MASK;
490 
491     /* Reset all Rx register values */
492     base->RCR2 = 0;
493     base->RCR3 = 0;
494     base->RCR4 = 0;
495     base->RCR5 = 0;
496     base->RMR  = 0;
497 }
498 
499 /*!
500  * brief Enables/disables the SAI Tx.
501  *
502  * param base SAI base pointer
503  * param enable True means enable SAI Tx, false means disable.
504  */
SAI_TxEnable(I2S_Type * base,bool enable)505 void SAI_TxEnable(I2S_Type *base, bool enable)
506 {
507     if (enable)
508     {
509         /* If clock is sync with Rx, should enable RE bit. */
510         if (((base->TCR2 & I2S_TCR2_SYNC_MASK) >> I2S_TCR2_SYNC_SHIFT) == 0x1U)
511         {
512             base->RCSR = ((base->RCSR & 0xFFE3FFFFU) | I2S_RCSR_RE_MASK);
513         }
514         base->TCSR = ((base->TCSR & 0xFFE3FFFFU) | I2S_TCSR_TE_MASK);
515         /* Also need to clear the FIFO error flag before start */
516         SAI_TxClearStatusFlags(base, kSAI_FIFOErrorFlag);
517     }
518     else
519     {
520         /* If Rx not in sync with Tx, then disable Tx, otherwise, shall not disable Tx */
521         if (((base->RCR2 & I2S_RCR2_SYNC_MASK) >> I2S_RCR2_SYNC_SHIFT) != 0x1U)
522         {
523             /* Disable TE bit */
524             base->TCSR = ((base->TCSR & 0xFFE3FFFFU) & (~I2S_TCSR_TE_MASK));
525         }
526     }
527 }
528 
529 /*!
530  * brief Enables/disables the SAI Rx.
531  *
532  * param base SAI base pointer
533  * param enable True means enable SAI Rx, false means disable.
534  */
SAI_RxEnable(I2S_Type * base,bool enable)535 void SAI_RxEnable(I2S_Type *base, bool enable)
536 {
537     if (enable)
538     {
539         /* If clock is sync with Tx, should enable TE bit. */
540         if (((base->RCR2 & I2S_RCR2_SYNC_MASK) >> I2S_RCR2_SYNC_SHIFT) == 0x1U)
541         {
542             base->TCSR = ((base->TCSR & 0xFFE3FFFFU) | I2S_TCSR_TE_MASK);
543         }
544         base->RCSR = ((base->RCSR & 0xFFE3FFFFU) | I2S_RCSR_RE_MASK);
545         /* Also need to clear the FIFO error flag before start */
546         SAI_RxClearStatusFlags(base, kSAI_FIFOErrorFlag);
547     }
548     else
549     {
550         /* If Tx not in sync with Rx, then disable Rx, otherwise, shall not disable Rx */
551         if (((base->TCR2 & I2S_TCR2_SYNC_MASK) >> I2S_TCR2_SYNC_SHIFT) != 0x1U)
552         {
553             /* Disable RE bit */
554             base->RCSR = ((base->RCSR & 0xFFE3FFFFU) & (~I2S_RCSR_RE_MASK));
555         }
556     }
557 }
558 
559 /*!
560  * brief Do software reset or FIFO reset .
561  *
562  * FIFO reset means clear all the data in the FIFO, and make the FIFO pointer both to 0.
563  * Software reset means clear the Tx internal logic, including the bit clock, frame count etc. But software
564  * reset will not clear any configuration registers like TCR1~TCR5.
565  * This function will also clear all the error flags such as FIFO error, sync error etc.
566  *
567  * param base SAI base pointer
568  * param resetType Reset type, FIFO reset or software reset
569  */
SAI_TxSoftwareReset(I2S_Type * base,sai_reset_type_t resetType)570 void SAI_TxSoftwareReset(I2S_Type *base, sai_reset_type_t resetType)
571 {
572     base->TCSR |= (uint32_t)resetType;
573 
574     /* Clear the software reset */
575     base->TCSR &= ~I2S_TCSR_SR_MASK;
576 }
577 
578 /*!
579  * brief Do software reset or FIFO reset .
580  *
581  * FIFO reset means clear all the data in the FIFO, and make the FIFO pointer both to 0.
582  * Software reset means clear the Rx internal logic, including the bit clock, frame count etc. But software
583  * reset will not clear any configuration registers like RCR1~RCR5.
584  * This function will also clear all the error flags such as FIFO error, sync error etc.
585  *
586  * param base SAI base pointer
587  * param resetType Reset type, FIFO reset or software reset
588  */
SAI_RxSoftwareReset(I2S_Type * base,sai_reset_type_t resetType)589 void SAI_RxSoftwareReset(I2S_Type *base, sai_reset_type_t resetType)
590 {
591     base->RCSR |= (uint32_t)resetType;
592 
593     /* Clear the software reset */
594     base->RCSR &= ~I2S_RCSR_SR_MASK;
595 }
596 
597 /*!
598  * brief Set the Tx channel FIFO enable mask.
599  *
600  * param base SAI base pointer
601  * param mask Channel enable mask, 0 means all channel FIFO disabled, 1 means channel 0 enabled,
602  * 3 means both channel 0 and channel 1 enabled.
603  */
SAI_TxSetChannelFIFOMask(I2S_Type * base,uint8_t mask)604 void SAI_TxSetChannelFIFOMask(I2S_Type *base, uint8_t mask)
605 {
606     base->TCR3 &= ~I2S_TCR3_TCE_MASK;
607     base->TCR3 |= I2S_TCR3_TCE(mask);
608 }
609 
610 /*!
611  * brief Set the Rx channel FIFO enable mask.
612  *
613  * param base SAI base pointer
614  * param mask Channel enable mask, 0 means all channel FIFO disabled, 1 means channel 0 enabled,
615  * 3 means both channel 0 and channel 1 enabled.
616  */
SAI_RxSetChannelFIFOMask(I2S_Type * base,uint8_t mask)617 void SAI_RxSetChannelFIFOMask(I2S_Type *base, uint8_t mask)
618 {
619     base->RCR3 &= ~I2S_RCR3_RCE_MASK;
620     base->RCR3 |= I2S_RCR3_RCE(mask);
621 }
622 
623 /*!
624  * brief Set the Tx data order.
625  *
626  * param base SAI base pointer
627  * param order Data order MSB or LSB
628  */
SAI_TxSetDataOrder(I2S_Type * base,sai_data_order_t order)629 void SAI_TxSetDataOrder(I2S_Type *base, sai_data_order_t order)
630 {
631     uint32_t val = (base->TCR4) & (~I2S_TCR4_MF_MASK);
632 
633     val |= I2S_TCR4_MF(order);
634     base->TCR4 = val;
635 }
636 
637 /*!
638  * brief Set the Rx data order.
639  *
640  * param base SAI base pointer
641  * param order Data order MSB or LSB
642  */
SAI_RxSetDataOrder(I2S_Type * base,sai_data_order_t order)643 void SAI_RxSetDataOrder(I2S_Type *base, sai_data_order_t order)
644 {
645     uint32_t val = (base->RCR4) & (~I2S_RCR4_MF_MASK);
646 
647     val |= I2S_RCR4_MF(order);
648     base->RCR4 = val;
649 }
650 
651 /*!
652  * brief Set the Tx data order.
653  *
654  * param base SAI base pointer
655  * param order Data order MSB or LSB
656  */
SAI_TxSetBitClockPolarity(I2S_Type * base,sai_clock_polarity_t polarity)657 void SAI_TxSetBitClockPolarity(I2S_Type *base, sai_clock_polarity_t polarity)
658 {
659     uint32_t val = (base->TCR2) & (~I2S_TCR2_BCP_MASK);
660 
661     val |= I2S_TCR2_BCP(polarity);
662     base->TCR2 = val;
663 }
664 
665 /*!
666  * brief Set the Rx data order.
667  *
668  * param base SAI base pointer
669  * param order Data order MSB or LSB
670  */
SAI_RxSetBitClockPolarity(I2S_Type * base,sai_clock_polarity_t polarity)671 void SAI_RxSetBitClockPolarity(I2S_Type *base, sai_clock_polarity_t polarity)
672 {
673     uint32_t val = (base->RCR2) & (~I2S_RCR2_BCP_MASK);
674 
675     val |= I2S_RCR2_BCP(polarity);
676     base->RCR2 = val;
677 }
678 
679 /*!
680  * brief Set the Tx data order.
681  *
682  * param base SAI base pointer
683  * param order Data order MSB or LSB
684  */
SAI_TxSetFrameSyncPolarity(I2S_Type * base,sai_clock_polarity_t polarity)685 void SAI_TxSetFrameSyncPolarity(I2S_Type *base, sai_clock_polarity_t polarity)
686 {
687     uint32_t val = (base->TCR4) & (~I2S_TCR4_FSP_MASK);
688 
689     val |= I2S_TCR4_FSP(polarity);
690     base->TCR4 = val;
691 }
692 
693 /*!
694  * brief Set the Rx data order.
695  *
696  * param base SAI base pointer
697  * param order Data order MSB or LSB
698  */
SAI_RxSetFrameSyncPolarity(I2S_Type * base,sai_clock_polarity_t polarity)699 void SAI_RxSetFrameSyncPolarity(I2S_Type *base, sai_clock_polarity_t polarity)
700 {
701     uint32_t val = (base->RCR4) & (~I2S_RCR4_FSP_MASK);
702 
703     val |= I2S_RCR4_FSP(polarity);
704     base->RCR4 = val;
705 }
706 
707 #if defined(FSL_FEATURE_SAI_HAS_FIFO_PACKING) && FSL_FEATURE_SAI_HAS_FIFO_PACKING
708 /*!
709  * brief Set Tx FIFO packing feature.
710  *
711  * param base SAI base pointer.
712  * param pack FIFO pack type. It is element of sai_fifo_packing_t.
713  */
SAI_TxSetFIFOPacking(I2S_Type * base,sai_fifo_packing_t pack)714 void SAI_TxSetFIFOPacking(I2S_Type *base, sai_fifo_packing_t pack)
715 {
716     uint32_t val = base->TCR4;
717 
718     val &= ~I2S_TCR4_FPACK_MASK;
719     val |= I2S_TCR4_FPACK(pack);
720     base->TCR4 = val;
721 }
722 
723 /*!
724  * brief Set Rx FIFO packing feature.
725  *
726  * param base SAI base pointer.
727  * param pack FIFO pack type. It is element of sai_fifo_packing_t.
728  */
SAI_RxSetFIFOPacking(I2S_Type * base,sai_fifo_packing_t pack)729 void SAI_RxSetFIFOPacking(I2S_Type *base, sai_fifo_packing_t pack)
730 {
731     uint32_t val = base->RCR4;
732 
733     val &= ~I2S_RCR4_FPACK_MASK;
734     val |= I2S_RCR4_FPACK(pack);
735     base->RCR4 = val;
736 }
737 #endif /* FSL_FEATURE_SAI_HAS_FIFO_PACKING */
738 
739 /*!
740  * brief Transmitter bit clock rate configurations.
741  *
742  * param base SAI base pointer.
743  * param sourceClockHz, bit clock source frequency.
744  * param sampleRate audio data sample rate.
745  * param bitWidth, audio data bitWidth.
746  * param channelNumbers, audio channel numbers.
747  */
SAI_TxSetBitClockRate(I2S_Type * base,uint32_t sourceClockHz,uint32_t sampleRate,uint32_t bitWidth,uint32_t channelNumbers)748 void SAI_TxSetBitClockRate(
749     I2S_Type *base, uint32_t sourceClockHz, uint32_t sampleRate, uint32_t bitWidth, uint32_t channelNumbers)
750 {
751     uint32_t tcr2         = base->TCR2;
752     uint32_t bitClockDiv  = 0;
753     uint32_t bitClockFreq = sampleRate * bitWidth * channelNumbers;
754 
755     assert(sourceClockHz >= bitClockFreq);
756 
757     tcr2 &= ~I2S_TCR2_DIV_MASK;
758     /* need to check the divided bclk, if bigger than target, then divider need to re-calculate. */
759     bitClockDiv = sourceClockHz / bitClockFreq;
760     /* for the condition where the source clock is smaller than target bclk */
761     if (bitClockDiv == 0U)
762     {
763         bitClockDiv++;
764     }
765     /* recheck the divider if properly or not, to make sure output blck not bigger than target*/
766     if ((sourceClockHz / bitClockDiv) > bitClockFreq)
767     {
768         bitClockDiv++;
769     }
770 
771 #if defined(FSL_FEATURE_SAI_HAS_BCLK_BYPASS) && (FSL_FEATURE_SAI_HAS_BCLK_BYPASS)
772     /* if bclk same with MCLK, bypass the divider */
773     if (bitClockDiv == 1U)
774     {
775         tcr2 |= I2S_TCR2_BYP_MASK;
776     }
777     else
778 #endif
779     {
780         tcr2 |= I2S_TCR2_DIV(bitClockDiv / 2U - 1UL);
781     }
782 
783     base->TCR2 = tcr2;
784 }
785 
786 /*!
787  * brief Receiver bit clock rate configurations.
788  *
789  * param base SAI base pointer.
790  * param sourceClockHz, bit clock source frequency.
791  * param sampleRate audio data sample rate.
792  * param bitWidth, audio data bitWidth.
793  * param channelNumbers, audio channel numbers.
794  */
SAI_RxSetBitClockRate(I2S_Type * base,uint32_t sourceClockHz,uint32_t sampleRate,uint32_t bitWidth,uint32_t channelNumbers)795 void SAI_RxSetBitClockRate(
796     I2S_Type *base, uint32_t sourceClockHz, uint32_t sampleRate, uint32_t bitWidth, uint32_t channelNumbers)
797 {
798     uint32_t rcr2         = base->RCR2;
799     uint32_t bitClockDiv  = 0;
800     uint32_t bitClockFreq = sampleRate * bitWidth * channelNumbers;
801 
802     assert(sourceClockHz >= bitClockFreq);
803 
804     rcr2 &= ~I2S_RCR2_DIV_MASK;
805     /* need to check the divided bclk, if bigger than target, then divider need to re-calculate. */
806     bitClockDiv = sourceClockHz / bitClockFreq;
807     /* for the condition where the source clock is smaller than target bclk */
808     if (bitClockDiv == 0U)
809     {
810         bitClockDiv++;
811     }
812     /* recheck the divider if properly or not, to make sure output blck not bigger than target*/
813     if ((sourceClockHz / bitClockDiv) > bitClockFreq)
814     {
815         bitClockDiv++;
816     }
817 
818 #if defined(FSL_FEATURE_SAI_HAS_BCLK_BYPASS) && (FSL_FEATURE_SAI_HAS_BCLK_BYPASS)
819     /* if bclk same with MCLK, bypass the divider */
820     if (bitClockDiv == 1U)
821     {
822         rcr2 |= I2S_RCR2_BYP_MASK;
823     }
824     else
825 #endif
826     {
827         rcr2 |= I2S_RCR2_DIV(bitClockDiv / 2U - 1UL);
828     }
829 
830     base->RCR2 = rcr2;
831 }
832 
833 /*!
834  * brief Transmitter Bit clock configurations.
835  *
836  * param base SAI base pointer.
837  * param masterSlave master or slave.
838  * param config bit clock other configurations, can be NULL in slave mode.
839  */
SAI_TxSetBitclockConfig(I2S_Type * base,sai_master_slave_t masterSlave,sai_bit_clock_t * config)840 void SAI_TxSetBitclockConfig(I2S_Type *base, sai_master_slave_t masterSlave, sai_bit_clock_t *config)
841 {
842     uint32_t tcr2 = base->TCR2;
843 
844     if ((masterSlave == kSAI_Master) || (masterSlave == kSAI_Bclk_Master_FrameSync_Slave))
845     {
846         assert(config != NULL);
847 
848         tcr2 &= ~(I2S_TCR2_BCD_MASK | I2S_TCR2_BCP_MASK | I2S_TCR2_BCI_MASK | I2S_TCR2_BCS_MASK | I2S_TCR2_MSEL_MASK);
849         tcr2 |= I2S_TCR2_BCD(1U) | I2S_TCR2_BCP(config->bclkPolarity) | I2S_TCR2_BCI(config->bclkInputDelay) |
850                 I2S_TCR2_BCS(config->bclkSrcSwap) | I2S_TCR2_MSEL(config->bclkSource);
851     }
852     else
853     {
854         tcr2 &= ~(I2S_TCR2_BCD_MASK);
855         tcr2 |= I2S_TCR2_BCP(config->bclkPolarity);
856     }
857 
858     base->TCR2 = tcr2;
859 }
860 
861 /*!
862  * brief Receiver Bit clock configurations.
863  *
864  * param base SAI base pointer.
865  * param masterSlave master or slave.
866  * param config bit clock other configurations, can be NULL in slave mode.
867  */
SAI_RxSetBitclockConfig(I2S_Type * base,sai_master_slave_t masterSlave,sai_bit_clock_t * config)868 void SAI_RxSetBitclockConfig(I2S_Type *base, sai_master_slave_t masterSlave, sai_bit_clock_t *config)
869 {
870     uint32_t rcr2 = base->RCR2;
871 
872     if ((masterSlave == kSAI_Master) || (masterSlave == kSAI_Bclk_Master_FrameSync_Slave))
873     {
874         assert(config != NULL);
875 
876         rcr2 &= ~(I2S_RCR2_BCD_MASK | I2S_RCR2_BCP_MASK | I2S_RCR2_BCI_MASK | I2S_RCR2_BCS_MASK | I2S_RCR2_MSEL_MASK);
877         rcr2 |= I2S_RCR2_BCD(1U) | I2S_RCR2_BCP(config->bclkPolarity) | I2S_RCR2_BCI(config->bclkInputDelay) |
878                 I2S_RCR2_BCS(config->bclkSrcSwap) | I2S_RCR2_MSEL(config->bclkSource);
879     }
880     else
881     {
882         rcr2 &= ~(I2S_RCR2_BCD_MASK);
883         rcr2 |= I2S_RCR2_BCP(config->bclkPolarity);
884     }
885 
886     base->RCR2 = rcr2;
887 }
888 
889 #if (defined(FSL_FEATURE_SAI_HAS_MCR) && (FSL_FEATURE_SAI_HAS_MCR)) || \
890     (defined(FSL_FEATURE_SAI_HAS_MCLKDIV_REGISTER) && (FSL_FEATURE_SAI_HAS_MCLKDIV_REGISTER))
891 /*!
892  * brief Master clock configurations.
893  *
894  * param base SAI base pointer.
895  * param config master clock configurations.
896  */
SAI_SetMasterClockConfig(I2S_Type * base,sai_master_clock_t * config)897 void SAI_SetMasterClockConfig(I2S_Type *base, sai_master_clock_t *config)
898 {
899     assert(config != NULL);
900 
901 #if defined(FSL_FEATURE_SAI_HAS_MCR) && (FSL_FEATURE_SAI_HAS_MCR)
902     uint32_t val = 0;
903 #if !(defined(FSL_FEATURE_SAI_HAS_NO_MCR_MICS) && (FSL_FEATURE_SAI_HAS_NO_MCR_MICS))
904     /* Master clock source setting */
905     val       = (base->MCR & ~I2S_MCR_MICS_MASK);
906     base->MCR = (val | I2S_MCR_MICS(config->mclkSource));
907 #endif
908 
909     /* Configure Master clock output enable */
910     val       = (base->MCR & ~I2S_MCR_MOE_MASK);
911     base->MCR = (val | I2S_MCR_MOE(config->mclkOutputEnable));
912 #endif /* FSL_FEATURE_SAI_HAS_MCR */
913 
914 #if ((defined(FSL_FEATURE_SAI_HAS_MCLKDIV_REGISTER) && (FSL_FEATURE_SAI_HAS_MCLKDIV_REGISTER)) || \
915      (defined(FSL_FEATURE_SAI_HAS_MCR_MCLK_POST_DIV) && (FSL_FEATURE_SAI_HAS_MCR_MCLK_POST_DIV)))
916     /* Check if master clock divider enabled, then set master clock divider */
917     if (config->mclkOutputEnable)
918     {
919         SAI_SetMasterClockDivider(base, config->mclkHz, config->mclkSourceClkHz);
920     }
921 #endif /* FSL_FEATURE_SAI_HAS_MCLKDIV_REGISTER */
922 }
923 #endif
924 
925 #if FSL_SAI_HAS_FIFO_EXTEND_FEATURE
926 /*!
927  * brief SAI transmitter fifo configurations.
928  *
929  * param base SAI base pointer.
930  * param config fifo configurations.
931  */
SAI_TxSetFifoConfig(I2S_Type * base,sai_fifo_t * config)932 void SAI_TxSetFifoConfig(I2S_Type *base, sai_fifo_t *config)
933 {
934     assert(config != NULL);
935 #if defined(FSL_FEATURE_SAI_HAS_FIFO) && (FSL_FEATURE_SAI_HAS_FIFO)
936     if (config->fifoWatermark > (uint8_t)((uint32_t)FSL_FEATURE_SAI_FIFO_COUNTn(base)) ||
937 	(!MCUX_SDK_SAI_ALLOW_NULL_FIFO_WATERMARK && config->fifoWatermark == 0U))
938     {
939         config->fifoWatermark = (uint8_t)((uint32_t)FSL_FEATURE_SAI_FIFO_COUNTn(base) / 2U);
940     }
941 #endif
942 
943     uint32_t tcr4 = base->TCR4;
944 
945 #if defined(FSL_FEATURE_SAI_HAS_FIFO_COMBINE_MODE) && FSL_FEATURE_SAI_HAS_FIFO_COMBINE_MODE
946     tcr4 &= ~I2S_TCR4_FCOMB_MASK;
947     tcr4 |= I2S_TCR4_FCOMB(config->fifoCombine);
948 #endif
949 
950 #if defined(FSL_FEATURE_SAI_HAS_FIFO_FUNCTION_AFTER_ERROR) && FSL_FEATURE_SAI_HAS_FIFO_FUNCTION_AFTER_ERROR
951     tcr4 &= ~I2S_TCR4_FCONT_MASK;
952     /* ERR05144: not set FCONT = 1 when TMR > 0, the transmit shift register may not load correctly that will cause TX
953      * not work */
954     if (base->TMR == 0U)
955     {
956         tcr4 |= I2S_TCR4_FCONT(config->fifoContinueOneError);
957     }
958 #endif
959 
960 #if defined(FSL_FEATURE_SAI_HAS_FIFO_PACKING) && FSL_FEATURE_SAI_HAS_FIFO_PACKING
961     tcr4 &= ~I2S_TCR4_FPACK_MASK;
962     tcr4 |= I2S_TCR4_FPACK(config->fifoPacking);
963 #endif
964 
965     base->TCR4 = tcr4;
966 
967 #if defined(FSL_FEATURE_SAI_HAS_FIFO) && (FSL_FEATURE_SAI_HAS_FIFO)
968     base->TCR1 = (base->TCR1 & (~I2S_TCR1_TFW_MASK)) | I2S_TCR1_TFW(config->fifoWatermark);
969 #endif
970 }
971 
972 /*!
973  * brief SAI receiver fifo configurations.
974  *
975  * param base SAI base pointer.
976  * param config fifo configurations.
977  */
SAI_RxSetFifoConfig(I2S_Type * base,sai_fifo_t * config)978 void SAI_RxSetFifoConfig(I2S_Type *base, sai_fifo_t *config)
979 {
980     assert(config != NULL);
981 #if defined(FSL_FEATURE_SAI_HAS_FIFO) && (FSL_FEATURE_SAI_HAS_FIFO)
982     if (config->fifoWatermark > (uint8_t)((uint32_t)FSL_FEATURE_SAI_FIFO_COUNTn(base)) ||
983 	(!MCUX_SDK_SAI_ALLOW_NULL_FIFO_WATERMARK && config->fifoWatermark == 0U))
984     {
985         config->fifoWatermark = (uint8_t)((uint32_t)FSL_FEATURE_SAI_FIFO_COUNTn(base) / 2U);
986     }
987 #endif
988     uint32_t rcr4 = base->RCR4;
989 
990 #if defined(FSL_FEATURE_SAI_HAS_FIFO_COMBINE_MODE) && FSL_FEATURE_SAI_HAS_FIFO_COMBINE_MODE
991     rcr4 &= ~I2S_RCR4_FCOMB_MASK;
992     rcr4 |= I2S_RCR4_FCOMB(config->fifoCombine);
993 #endif
994 
995 #if defined(FSL_FEATURE_SAI_HAS_FIFO_FUNCTION_AFTER_ERROR) && FSL_FEATURE_SAI_HAS_FIFO_FUNCTION_AFTER_ERROR
996     rcr4 &= ~I2S_RCR4_FCONT_MASK;
997     rcr4 |= I2S_RCR4_FCONT(config->fifoContinueOneError);
998 #endif
999 
1000 #if defined(FSL_FEATURE_SAI_HAS_FIFO_PACKING) && FSL_FEATURE_SAI_HAS_FIFO_PACKING
1001     rcr4 &= ~I2S_RCR4_FPACK_MASK;
1002     rcr4 |= I2S_RCR4_FPACK(config->fifoPacking);
1003 #endif
1004 
1005     base->RCR4 = rcr4;
1006 
1007 #if defined(FSL_FEATURE_SAI_HAS_FIFO) && (FSL_FEATURE_SAI_HAS_FIFO)
1008     base->RCR1 = (base->RCR1 & (~I2S_RCR1_RFW_MASK)) | I2S_RCR1_RFW(config->fifoWatermark);
1009 #endif
1010 }
1011 #endif
1012 
1013 /*!
1014  * brief SAI transmitter Frame sync configurations.
1015  *
1016  * param base SAI base pointer.
1017  * param masterSlave master or slave.
1018  * param config frame sync configurations, can be NULL in slave mode.
1019  */
SAI_TxSetFrameSyncConfig(I2S_Type * base,sai_master_slave_t masterSlave,sai_frame_sync_t * config)1020 void SAI_TxSetFrameSyncConfig(I2S_Type *base, sai_master_slave_t masterSlave, sai_frame_sync_t *config)
1021 {
1022     assert(config != NULL);
1023     assert((config->frameSyncWidth - 1UL) <= (I2S_TCR4_SYWD_MASK >> I2S_TCR4_SYWD_SHIFT));
1024 
1025     uint32_t tcr4 = base->TCR4;
1026 
1027     tcr4 &= ~(I2S_TCR4_FSE_MASK | I2S_TCR4_FSP_MASK | I2S_TCR4_FSD_MASK | I2S_TCR4_SYWD_MASK);
1028 
1029 #if defined(FSL_FEATURE_SAI_HAS_ON_DEMAND_MODE) && FSL_FEATURE_SAI_HAS_ON_DEMAND_MODE
1030     tcr4 &= ~I2S_TCR4_ONDEM_MASK;
1031     tcr4 |= I2S_TCR4_ONDEM(config->frameSyncGenerateOnDemand);
1032 #endif
1033 
1034     tcr4 |=
1035         I2S_TCR4_FSE(config->frameSyncEarly) | I2S_TCR4_FSP(config->frameSyncPolarity) |
1036         I2S_TCR4_FSD(((masterSlave == kSAI_Master) || (masterSlave == kSAI_Bclk_Slave_FrameSync_Master)) ? 1UL : 0U) |
1037         I2S_TCR4_SYWD(config->frameSyncWidth - 1UL);
1038 
1039     base->TCR4 = tcr4;
1040 }
1041 
1042 /*!
1043  * brief SAI receiver Frame sync configurations.
1044  *
1045  * param base SAI base pointer.
1046  * param masterSlave master or slave.
1047  * param config frame sync configurations, can be NULL in slave mode.
1048  */
SAI_RxSetFrameSyncConfig(I2S_Type * base,sai_master_slave_t masterSlave,sai_frame_sync_t * config)1049 void SAI_RxSetFrameSyncConfig(I2S_Type *base, sai_master_slave_t masterSlave, sai_frame_sync_t *config)
1050 {
1051     assert(config != NULL);
1052     assert((config->frameSyncWidth - 1UL) <= (I2S_RCR4_SYWD_MASK >> I2S_RCR4_SYWD_SHIFT));
1053 
1054     uint32_t rcr4 = base->RCR4;
1055 
1056     rcr4 &= ~(I2S_RCR4_FSE_MASK | I2S_RCR4_FSP_MASK | I2S_RCR4_FSD_MASK | I2S_RCR4_SYWD_MASK);
1057 
1058 #if defined(FSL_FEATURE_SAI_HAS_ON_DEMAND_MODE) && FSL_FEATURE_SAI_HAS_ON_DEMAND_MODE
1059     rcr4 &= ~I2S_RCR4_ONDEM_MASK;
1060     rcr4 |= I2S_RCR4_ONDEM(config->frameSyncGenerateOnDemand);
1061 #endif
1062 
1063     rcr4 |=
1064         I2S_RCR4_FSE(config->frameSyncEarly) | I2S_RCR4_FSP(config->frameSyncPolarity) |
1065         I2S_RCR4_FSD(((masterSlave == kSAI_Master) || (masterSlave == kSAI_Bclk_Slave_FrameSync_Master)) ? 1UL : 0U) |
1066         I2S_RCR4_SYWD(config->frameSyncWidth - 1UL);
1067 
1068     base->RCR4 = rcr4;
1069 }
1070 
1071 /*!
1072  * brief SAI transmitter Serial data configurations.
1073  *
1074  * param base SAI base pointer.
1075  * param config serial data configurations.
1076  */
SAI_TxSetSerialDataConfig(I2S_Type * base,sai_serial_data_t * config)1077 void SAI_TxSetSerialDataConfig(I2S_Type *base, sai_serial_data_t *config)
1078 {
1079     assert(config != NULL);
1080 
1081     uint32_t tcr4 = base->TCR4;
1082 
1083     base->TCR5 = I2S_TCR5_WNW(config->dataWordNLength - 1UL) | I2S_TCR5_W0W(config->dataWord0Length - 1UL) |
1084                  I2S_TCR5_FBT(config->dataFirstBitShifted - 1UL);
1085     base->TMR = config->dataMaskedWord;
1086 #if defined(FSL_FEATURE_SAI_HAS_FIFO_FUNCTION_AFTER_ERROR) && FSL_FEATURE_SAI_HAS_FIFO_FUNCTION_AFTER_ERROR
1087     /* ERR05144: not set FCONT = 1 when TMR > 0, the transmit shift register may not load correctly that will cause TX
1088      * not work */
1089     if (config->dataMaskedWord > 0U)
1090     {
1091         tcr4 &= ~I2S_TCR4_FCONT_MASK;
1092     }
1093 #endif
1094     tcr4 &= ~(I2S_TCR4_FRSZ_MASK | I2S_TCR4_MF_MASK);
1095     tcr4 |= I2S_TCR4_FRSZ(config->dataWordNum - 1UL) | I2S_TCR4_MF(config->dataOrder);
1096 
1097 #if defined(FSL_FEATURE_SAI_HAS_CHANNEL_MODE) && FSL_FEATURE_SAI_HAS_CHANNEL_MODE
1098     tcr4 &= ~I2S_TCR4_CHMOD_MASK;
1099     tcr4 |= I2S_TCR4_CHMOD(config->dataMode);
1100 #endif
1101 
1102     base->TCR4 = tcr4;
1103 }
1104 
1105 /*!
1106  * @brief SAI receiver Serial data configurations.
1107  *
1108  * @param base SAI base pointer.
1109  * @param config serial data configurations.
1110  */
SAI_RxSetSerialDataConfig(I2S_Type * base,sai_serial_data_t * config)1111 void SAI_RxSetSerialDataConfig(I2S_Type *base, sai_serial_data_t *config)
1112 {
1113     assert(config != NULL);
1114 
1115     uint32_t rcr4 = base->RCR4;
1116 
1117     base->RCR5 = I2S_RCR5_WNW(config->dataWordNLength - 1UL) | I2S_RCR5_W0W(config->dataWord0Length - 1UL) |
1118                  I2S_RCR5_FBT(config->dataFirstBitShifted - 1UL);
1119     base->RMR = config->dataMaskedWord;
1120 
1121     rcr4 &= ~(I2S_RCR4_FRSZ_MASK | I2S_RCR4_MF_MASK);
1122     rcr4 |= I2S_RCR4_FRSZ(config->dataWordNum - 1uL) | I2S_RCR4_MF(config->dataOrder);
1123 
1124     base->RCR4 = rcr4;
1125 }
1126 
1127 #if !MCUX_SDK_SAI_DISABLE_IMPLICIT_CHAN_CONFIG
SAI_ComputeChannelConfig(I2S_Type * base,sai_transceiver_t * config)1128 static void SAI_ComputeChannelConfig(I2S_Type *base, sai_transceiver_t *config)
1129 {
1130     assert(config != NULL);
1131     assert(FSL_FEATURE_SAI_CHANNEL_COUNTn(base) != -1);
1132 
1133     uint8_t i           = 0U;
1134     uint8_t channelNums = 0U;
1135 
1136     /* if channel mask is not set, then format->channel must be set,
1137      use it to get channel mask value */
1138     if (config->channelMask == 0U)
1139     {
1140         config->channelMask = 1U << config->startChannel;
1141     }
1142 
1143     for (i = 0U; i < (uint32_t)FSL_FEATURE_SAI_CHANNEL_COUNTn(base); i++)
1144     {
1145         if (IS_SAI_FLAG_SET(1UL << i, config->channelMask))
1146         {
1147             channelNums++;
1148             config->endChannel = i;
1149         }
1150     }
1151 
1152     for (i = 0U; i < (uint32_t)FSL_FEATURE_SAI_CHANNEL_COUNTn(base); i++)
1153     {
1154         if (IS_SAI_FLAG_SET((1UL << i), config->channelMask))
1155         {
1156             config->startChannel = i;
1157             break;
1158         }
1159     }
1160 
1161     config->channelNums = channelNums;
1162 }
1163 #endif /* MCUX_SDK_SAI_DISABLE_IMPLICIT_CHAN_CONFIG */
1164 
1165 /*!
1166  * brief SAI transmitter configurations.
1167  *
1168  * param base SAI base pointer.
1169  * param config transmitter configurations.
1170  */
SAI_TxSetConfig(I2S_Type * base,sai_transceiver_t * config)1171 void SAI_TxSetConfig(I2S_Type *base, sai_transceiver_t *config)
1172 {
1173     uint32_t val = 0U;
1174 
1175     /* reset transmitter */
1176     SAI_TxReset(base);
1177 
1178 #if !MCUX_SDK_SAI_DISABLE_IMPLICIT_CHAN_CONFIG
1179     /* sometimes, the user of the SAI driver may want to
1180      * set the channel configuration (i.e: the startChannel,
1181      * channelMask, endChannel, and channelNums fields of
1182      * sai_transceiver_t) before calling SAI_TxSetConfig().
1183      * As such, if the user wants to do this, they can define
1184      * FSL_FEATURE_SAI_DISABLE_IMPLICIT_CHAN_CONFIG which will
1185      * stop SAI_TxSetConfig() from implicitly computing those
1186      * values.
1187      */
1188     SAI_ComputeChannelConfig(base, config);
1189 #endif /* MCUX_SDK_SAI_DISABLE_IMPLICIT_CHAN_CONFIG */
1190 
1191 #if defined(FSL_FEATURE_SAI_HAS_FIFO_COMBINE_MODE) && (FSL_FEATURE_SAI_HAS_FIFO_COMBINE_MODE)
1192     /* make sure combine mode disabled while multipe channel is used */
1193     if (config->channelNums > 1U)
1194     {
1195         base->TCR4 &= ~I2S_TCR4_FCOMB_MASK;
1196     }
1197 #endif
1198 
1199     /* Set data channel */
1200     base->TCR3 &= ~I2S_TCR3_TCE_MASK;
1201     base->TCR3 |= I2S_TCR3_TCE(config->channelMask);
1202 
1203     if (config->syncMode == kSAI_ModeAsync)
1204     {
1205         val = base->TCR2;
1206         val &= ~I2S_TCR2_SYNC_MASK;
1207         base->TCR2 = (val | I2S_TCR2_SYNC(0U));
1208     }
1209     if (config->syncMode == kSAI_ModeSync)
1210     {
1211         val = base->TCR2;
1212         val &= ~I2S_TCR2_SYNC_MASK;
1213         base->TCR2 = (val | I2S_TCR2_SYNC(1U));
1214         /* If sync with Rx, should set Rx to async mode */
1215         val = base->RCR2;
1216         val &= ~I2S_RCR2_SYNC_MASK;
1217         base->RCR2 = (val | I2S_RCR2_SYNC(0U));
1218     }
1219 #if defined(FSL_FEATURE_SAI_HAS_SYNC_WITH_ANOTHER_SAI) && (FSL_FEATURE_SAI_HAS_SYNC_WITH_ANOTHER_SAI)
1220     if (config->syncMode == kSAI_ModeSyncWithOtherTx)
1221     {
1222         val = base->TCR2;
1223         val &= ~I2S_TCR2_SYNC_MASK;
1224         base->TCR2 = (val | I2S_TCR2_SYNC(2U));
1225     }
1226     if (config->syncMode == kSAI_ModeSyncWithOtherRx)
1227     {
1228         val = base->TCR2;
1229         val &= ~I2S_TCR2_SYNC_MASK;
1230         base->TCR2 = (val | I2S_TCR2_SYNC(3U));
1231     }
1232 #endif /* FSL_FEATURE_SAI_HAS_SYNC_WITH_ANOTHER_SAI */
1233 
1234     /* bit clock configurations */
1235     SAI_TxSetBitclockConfig(base, config->masterSlave, &config->bitClock);
1236     /* serial data configurations */
1237     SAI_TxSetSerialDataConfig(base, &config->serialData);
1238     /* frame sync configurations */
1239     SAI_TxSetFrameSyncConfig(base, config->masterSlave, &config->frameSync);
1240 #if FSL_SAI_HAS_FIFO_EXTEND_FEATURE
1241     /* fifo configurations */
1242     SAI_TxSetFifoConfig(base, &config->fifo);
1243 #endif
1244 }
1245 
1246 /*!
1247  * brief SAI transmitter transfer configurations.
1248  *
1249  * This function initializes the TX, include bit clock, frame sync, master clock, serial data and fifo configurations.
1250  *
1251  * param base SAI base pointer.
1252  * param handle SAI handle pointer.
1253  * param config tranmitter configurations.
1254  */
SAI_TransferTxSetConfig(I2S_Type * base,sai_handle_t * handle,sai_transceiver_t * config)1255 void SAI_TransferTxSetConfig(I2S_Type *base, sai_handle_t *handle, sai_transceiver_t *config)
1256 {
1257     assert(handle != NULL);
1258     assert(config != NULL);
1259     assert(config->channelNums <= (uint32_t)FSL_FEATURE_SAI_CHANNEL_COUNTn(base));
1260 
1261     handle->bitWidth = config->serialData.dataWordNLength;
1262 #if defined(FSL_FEATURE_SAI_HAS_FIFO) && (FSL_FEATURE_SAI_HAS_FIFO)
1263     if ((config->fifo.fifoWatermark == 0U) ||
1264         (config->fifo.fifoWatermark > (uint8_t)((uint32_t)FSL_FEATURE_SAI_FIFO_COUNTn(base))))
1265     {
1266         config->fifo.fifoWatermark = (uint8_t)((uint32_t)FSL_FEATURE_SAI_FIFO_COUNTn(base) / 2U);
1267     }
1268     handle->watermark = config->fifo.fifoWatermark;
1269 #endif
1270 
1271     /* transmitter configurations */
1272     SAI_TxSetConfig(base, config);
1273 
1274     handle->channel = config->startChannel;
1275     /* used for multi channel */
1276     handle->channelMask = config->channelMask;
1277     handle->channelNums = config->channelNums;
1278     handle->endChannel  = config->endChannel;
1279 }
1280 
1281 /*!
1282  * brief SAI receiver configurations.
1283  *
1284  * param base SAI base pointer.
1285  * param config transmitter configurations.
1286  */
SAI_RxSetConfig(I2S_Type * base,sai_transceiver_t * config)1287 void SAI_RxSetConfig(I2S_Type *base, sai_transceiver_t *config)
1288 {
1289     uint32_t val = 0U;
1290 
1291     /* reset receiver */
1292     SAI_RxReset(base);
1293 
1294 #if !MCUX_SDK_SAI_DISABLE_IMPLICIT_CHAN_CONFIG
1295     /* sometimes, the user of the SAI driver may want to
1296      * set the channel configuration (i.e: the startChannel,
1297      * channelMask, endChannel, and channelNums fields of
1298      * sai_transceiver_t) before calling SAI_RxSetConfig().
1299      * As such, if the user wants to do this, they can define
1300      * FSL_FEATURE_SAI_DISABLE_IMPLICIT_CHAN_CONFIG which will
1301      * stop SAI_RxSetConfig() from implicitly computing those
1302      * values.
1303      */
1304     SAI_ComputeChannelConfig(base, config);
1305 #endif /* MCUX_SDK_SAI_DISABLE_IMPLICIT_CHAN_CONFIG */
1306 
1307 #if defined(FSL_FEATURE_SAI_HAS_FIFO_COMBINE_MODE) && (FSL_FEATURE_SAI_HAS_FIFO_COMBINE_MODE)
1308     /* make sure combine mode disabled while multipe channel is used */
1309     if (config->channelNums > 1U)
1310     {
1311         base->RCR4 &= ~I2S_RCR4_FCOMB_MASK;
1312     }
1313 #endif
1314 
1315     /* Set data channel */
1316     base->RCR3 &= ~I2S_RCR3_RCE_MASK;
1317     base->RCR3 |= I2S_RCR3_RCE(config->channelMask);
1318 
1319     /* Set Sync mode */
1320     if (config->syncMode == kSAI_ModeAsync)
1321     {
1322         val = base->RCR2;
1323         val &= ~I2S_RCR2_SYNC_MASK;
1324         base->RCR2 = (val | I2S_RCR2_SYNC(0U));
1325     }
1326     if (config->syncMode == kSAI_ModeSync)
1327     {
1328         val = base->RCR2;
1329         val &= ~I2S_RCR2_SYNC_MASK;
1330         base->RCR2 = (val | I2S_RCR2_SYNC(1U));
1331         /* If sync with Tx, should set Tx to async mode */
1332         val = base->TCR2;
1333         val &= ~I2S_TCR2_SYNC_MASK;
1334         base->TCR2 = (val | I2S_TCR2_SYNC(0U));
1335     }
1336 #if defined(FSL_FEATURE_SAI_HAS_SYNC_WITH_ANOTHER_SAI) && (FSL_FEATURE_SAI_HAS_SYNC_WITH_ANOTHER_SAI)
1337     if (config->syncMode == kSAI_ModeSyncWithOtherTx)
1338     {
1339         val = base->RCR2;
1340         val &= ~I2S_RCR2_SYNC_MASK;
1341         base->RCR2 = (val | I2S_RCR2_SYNC(2U));
1342     }
1343     if (config->syncMode == kSAI_ModeSyncWithOtherRx)
1344     {
1345         val = base->RCR2;
1346         val &= ~I2S_RCR2_SYNC_MASK;
1347         base->RCR2 = (val | I2S_RCR2_SYNC(3U));
1348     }
1349 #endif /* FSL_FEATURE_SAI_HAS_SYNC_WITH_ANOTHER_SAI */
1350 
1351     /* bit clock configurations */
1352     SAI_RxSetBitclockConfig(base, config->masterSlave, &config->bitClock);
1353     /* serial data configurations */
1354     SAI_RxSetSerialDataConfig(base, &config->serialData);
1355     /* frame sync configurations */
1356     SAI_RxSetFrameSyncConfig(base, config->masterSlave, &config->frameSync);
1357 #if FSL_SAI_HAS_FIFO_EXTEND_FEATURE
1358     /* fifo configurations */
1359     SAI_RxSetFifoConfig(base, &config->fifo);
1360 #endif
1361 }
1362 
1363 /*!
1364  * brief SAI receiver transfer configurations.
1365  *
1366  * This function initializes the TX, include bit clock, frame sync, master clock, serial data and fifo configurations.
1367  *
1368  * param base SAI base pointer.
1369  * param handle SAI handle pointer.
1370  * param config tranmitter configurations.
1371  */
SAI_TransferRxSetConfig(I2S_Type * base,sai_handle_t * handle,sai_transceiver_t * config)1372 void SAI_TransferRxSetConfig(I2S_Type *base, sai_handle_t *handle, sai_transceiver_t *config)
1373 {
1374     assert(handle != NULL);
1375     assert(config != NULL);
1376 
1377     handle->bitWidth = config->serialData.dataWordNLength;
1378 #if defined(FSL_FEATURE_SAI_HAS_FIFO) && (FSL_FEATURE_SAI_HAS_FIFO)
1379     if ((config->fifo.fifoWatermark == 0U) ||
1380         (config->fifo.fifoWatermark > (uint8_t)((uint32_t)FSL_FEATURE_SAI_FIFO_COUNTn(base))))
1381     {
1382         config->fifo.fifoWatermark = (uint8_t)((uint32_t)FSL_FEATURE_SAI_FIFO_COUNTn(base) / 2U);
1383     }
1384     handle->watermark = config->fifo.fifoWatermark;
1385 #endif
1386 
1387     /* receiver configurations */
1388     SAI_RxSetConfig(base, config);
1389 
1390     handle->channel = config->startChannel;
1391     /* used for multi channel */
1392     handle->channelMask = config->channelMask;
1393     handle->channelNums = config->channelNums;
1394     handle->endChannel  = config->endChannel;
1395 }
1396 
1397 /*!
1398  * brief Get classic I2S mode configurations.
1399  *
1400  * param config transceiver configurations.
1401  * param bitWidth audio data bitWidth.
1402  * param mode audio data channel.
1403  * param saiChannelMask channel mask value to enable.
1404  */
SAI_GetClassicI2SConfig(sai_transceiver_t * config,sai_word_width_t bitWidth,sai_mono_stereo_t mode,uint32_t saiChannelMask)1405 void SAI_GetClassicI2SConfig(sai_transceiver_t *config,
1406                              sai_word_width_t bitWidth,
1407                              sai_mono_stereo_t mode,
1408                              uint32_t saiChannelMask)
1409 {
1410     SAI_GetCommonConfig(config, bitWidth, mode, saiChannelMask);
1411 }
1412 
1413 /*!
1414  * brief Get left justified mode configurations.
1415  *
1416  * param config transceiver configurations.
1417  * param bitWidth audio data bitWidth.
1418  * param mode audio data channel.
1419  * param saiChannelMask channel mask value to enable.
1420  */
SAI_GetLeftJustifiedConfig(sai_transceiver_t * config,sai_word_width_t bitWidth,sai_mono_stereo_t mode,uint32_t saiChannelMask)1421 void SAI_GetLeftJustifiedConfig(sai_transceiver_t *config,
1422                                 sai_word_width_t bitWidth,
1423                                 sai_mono_stereo_t mode,
1424                                 uint32_t saiChannelMask)
1425 {
1426     assert(NULL != config);
1427     assert(saiChannelMask != 0U);
1428 
1429     SAI_GetCommonConfig(config, bitWidth, mode, saiChannelMask);
1430 
1431     config->frameSync.frameSyncEarly    = false;
1432     config->frameSync.frameSyncPolarity = kSAI_PolarityActiveHigh;
1433 }
1434 
1435 /*!
1436  * brief Get right justified mode configurations.
1437  *
1438  * param config transceiver configurations.
1439  * param bitWidth audio data bitWidth.
1440  * param mode audio data channel.
1441  * param saiChannelMask channel mask value to enable.
1442  */
SAI_GetRightJustifiedConfig(sai_transceiver_t * config,sai_word_width_t bitWidth,sai_mono_stereo_t mode,uint32_t saiChannelMask)1443 void SAI_GetRightJustifiedConfig(sai_transceiver_t *config,
1444                                  sai_word_width_t bitWidth,
1445                                  sai_mono_stereo_t mode,
1446                                  uint32_t saiChannelMask)
1447 {
1448     assert(NULL != config);
1449     assert(saiChannelMask != 0U);
1450 
1451     SAI_GetCommonConfig(config, bitWidth, mode, saiChannelMask);
1452 
1453     config->frameSync.frameSyncEarly    = false;
1454     config->frameSync.frameSyncPolarity = kSAI_PolarityActiveHigh;
1455 }
1456 
1457 /*!
1458  * brief Get DSP mode configurations.
1459  *
1460  * note DSP mode is also called PCM mode which support MODE A and MODE B,
1461  * DSP/PCM MODE A configuration flow. RX is similiar but uses SAI_RxSetConfig instead of SAI_TxSetConfig:
1462  * code
1463  * SAI_GetDSPConfig(config, kSAI_FrameSyncLenOneBitClk, bitWidth, kSAI_Stereo, channelMask)
1464  * config->frameSync.frameSyncEarly    = true;
1465  * SAI_TxSetConfig(base, config)
1466  * endcode
1467  *
1468  * DSP/PCM MODE B configuration flow for TX. RX is similiar but uses SAI_RxSetConfig instead of SAI_TxSetConfig:
1469  * code
1470  * SAI_GetDSPConfig(config, kSAI_FrameSyncLenOneBitClk, bitWidth, kSAI_Stereo, channelMask)
1471  * SAI_TxSetConfig(base, config)
1472  * endcode
1473  *
1474  * param config transceiver configurations.
1475  * param frameSyncWidth length of frame sync.
1476  * param bitWidth audio data bitWidth.
1477  * param mode audio data channel.
1478  * param saiChannelMask mask value of the channel to enable.
1479  */
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)1480 void SAI_GetDSPConfig(sai_transceiver_t *config,
1481                       sai_frame_sync_len_t frameSyncWidth,
1482                       sai_word_width_t bitWidth,
1483                       sai_mono_stereo_t mode,
1484                       uint32_t saiChannelMask)
1485 {
1486     assert(NULL != config);
1487     assert(saiChannelMask != 0U);
1488 
1489     SAI_GetCommonConfig(config, bitWidth, mode, saiChannelMask);
1490 
1491     /* frame sync default configurations */
1492     switch (frameSyncWidth)
1493     {
1494         case kSAI_FrameSyncLenOneBitClk:
1495             config->frameSync.frameSyncWidth = 1U;
1496             break;
1497         default:
1498             assert(false);
1499             break;
1500     }
1501     config->frameSync.frameSyncEarly    = false;
1502     config->frameSync.frameSyncPolarity = kSAI_PolarityActiveHigh;
1503 }
1504 
1505 /*!
1506  * brief Get TDM mode configurations.
1507  *
1508  * param config transceiver configurations.
1509  * param bitWidth audio data bitWidth.
1510  * param mode audio data channel.
1511  * param saiChannelMask channel mask value to enable.
1512  */
SAI_GetTDMConfig(sai_transceiver_t * config,sai_frame_sync_len_t frameSyncWidth,sai_word_width_t bitWidth,uint32_t dataWordNum,uint32_t saiChannelMask)1513 void SAI_GetTDMConfig(sai_transceiver_t *config,
1514                       sai_frame_sync_len_t frameSyncWidth,
1515                       sai_word_width_t bitWidth,
1516                       uint32_t dataWordNum,
1517                       uint32_t saiChannelMask)
1518 {
1519     assert(NULL != config);
1520     assert(saiChannelMask != 0U);
1521     assert(dataWordNum <= 32U);
1522 
1523     SAI_GetCommonConfig(config, bitWidth, kSAI_Stereo, saiChannelMask);
1524 
1525     /* frame sync default configurations */
1526     switch (frameSyncWidth)
1527     {
1528         case kSAI_FrameSyncLenOneBitClk:
1529             config->frameSync.frameSyncWidth = 1U;
1530             break;
1531         case kSAI_FrameSyncLenPerWordWidth:
1532             break;
1533         default:
1534             assert(false);
1535             break;
1536     }
1537     config->frameSync.frameSyncEarly    = false;
1538     config->frameSync.frameSyncPolarity = kSAI_PolarityActiveHigh;
1539     config->serialData.dataWordNum      = (uint8_t)dataWordNum;
1540 }
1541 
1542 /*!
1543  * brief Sends data using a blocking method.
1544  *
1545  * note This function blocks by polling until data is ready to be sent.
1546  *
1547  * param base SAI base pointer.
1548  * param channel Data channel used.
1549  * param bitWidth How many bits in an audio word; usually 8/16/24/32 bits.
1550  * param buffer Pointer to the data to be written.
1551  * param size Bytes to be written.
1552  */
SAI_WriteBlocking(I2S_Type * base,uint32_t channel,uint32_t bitWidth,uint8_t * buffer,uint32_t size)1553 void SAI_WriteBlocking(I2S_Type *base, uint32_t channel, uint32_t bitWidth, uint8_t *buffer, uint32_t size)
1554 {
1555     uint32_t i            = 0;
1556     uint32_t bytesPerWord = bitWidth / 8U;
1557 #if defined(FSL_FEATURE_SAI_HAS_FIFO) && (FSL_FEATURE_SAI_HAS_FIFO)
1558     bytesPerWord = (((uint32_t)FSL_FEATURE_SAI_FIFO_COUNTn(base) - base->TCR1) * bytesPerWord);
1559 #endif
1560 
1561     while (i < size)
1562     {
1563         /* Wait until it can write data */
1564         while (!(IS_SAI_FLAG_SET(base->TCSR, I2S_TCSR_FWF_MASK)))
1565         {
1566         }
1567 
1568         SAI_WriteNonBlocking(base, channel, 1UL << channel, channel, (uint8_t)bitWidth, buffer, bytesPerWord);
1569         buffer = (uint8_t *)((uintptr_t)buffer + bytesPerWord);
1570         i += bytesPerWord;
1571     }
1572 
1573     /* Wait until the last data is sent */
1574     while (!(IS_SAI_FLAG_SET(base->TCSR, I2S_TCSR_FWF_MASK)))
1575     {
1576     }
1577 }
1578 
1579 /*!
1580  * brief Sends data to multi channel using a blocking method.
1581  *
1582  * note This function blocks by polling until data is ready to be sent.
1583  *
1584  * param base SAI base pointer.
1585  * param channel Data channel used.
1586  * param channelMask channel mask.
1587  * param bitWidth How many bits in an audio word; usually 8/16/24/32 bits.
1588  * param buffer Pointer to the data to be written.
1589  * param size Bytes to be written.
1590  */
SAI_WriteMultiChannelBlocking(I2S_Type * base,uint32_t channel,uint32_t channelMask,uint32_t bitWidth,uint8_t * buffer,uint32_t size)1591 void SAI_WriteMultiChannelBlocking(
1592     I2S_Type *base, uint32_t channel, uint32_t channelMask, uint32_t bitWidth, uint8_t *buffer, uint32_t size)
1593 {
1594     assert(FSL_FEATURE_SAI_CHANNEL_COUNTn(base) != -1);
1595 
1596     uint32_t i = 0, j = 0;
1597     uint32_t bytesPerWord = bitWidth / 8U;
1598     uint32_t channelNums = 0U, endChannel = 0U;
1599 
1600 #if defined(FSL_FEATURE_SAI_HAS_FIFO) && (FSL_FEATURE_SAI_HAS_FIFO)
1601     bytesPerWord = (((uint32_t)FSL_FEATURE_SAI_FIFO_COUNTn(base) - base->TCR1) * bytesPerWord);
1602 #endif
1603 
1604     for (i = 0U; (i < (uint32_t)FSL_FEATURE_SAI_CHANNEL_COUNTn(base)); i++)
1605     {
1606         if (IS_SAI_FLAG_SET((1UL << i), channelMask))
1607         {
1608             channelNums++;
1609             endChannel = i;
1610         }
1611     }
1612 
1613     bytesPerWord *= channelNums;
1614 
1615     while (j < size)
1616     {
1617         /* Wait until it can write data */
1618         while (!(IS_SAI_FLAG_SET(base->TCSR, I2S_TCSR_FWF_MASK)))
1619         {
1620         }
1621 
1622         SAI_WriteNonBlocking(base, channel, channelMask, endChannel, (uint8_t)bitWidth, buffer,
1623                              bytesPerWord * channelNums);
1624         buffer = (uint8_t *)((uintptr_t)buffer + bytesPerWord * channelNums);
1625         j += bytesPerWord * channelNums;
1626     }
1627 
1628     /* Wait until the last data is sent */
1629     while (!(IS_SAI_FLAG_SET(base->TCSR, I2S_TCSR_FWF_MASK)))
1630     {
1631     }
1632 }
1633 
1634 /*!
1635  * brief Receives multi channel data using a blocking method.
1636  *
1637  * note This function blocks by polling until data is ready to be sent.
1638  *
1639  * param base SAI base pointer.
1640  * param channel Data channel used.
1641  * param channelMask channel mask.
1642  * param bitWidth How many bits in an audio word; usually 8/16/24/32 bits.
1643  * param buffer Pointer to the data to be read.
1644  * param size Bytes to be read.
1645  */
SAI_ReadMultiChannelBlocking(I2S_Type * base,uint32_t channel,uint32_t channelMask,uint32_t bitWidth,uint8_t * buffer,uint32_t size)1646 void SAI_ReadMultiChannelBlocking(
1647     I2S_Type *base, uint32_t channel, uint32_t channelMask, uint32_t bitWidth, uint8_t *buffer, uint32_t size)
1648 {
1649     assert(FSL_FEATURE_SAI_CHANNEL_COUNTn(base) != -1);
1650 
1651     uint32_t i = 0, j = 0;
1652     uint32_t bytesPerWord = bitWidth / 8U;
1653     uint32_t channelNums = 0U, endChannel = 0U;
1654 #if defined(FSL_FEATURE_SAI_HAS_FIFO) && (FSL_FEATURE_SAI_HAS_FIFO)
1655     bytesPerWord = base->RCR1 * bytesPerWord;
1656 #endif
1657     for (i = 0U; (i < (uint32_t)FSL_FEATURE_SAI_CHANNEL_COUNTn(base)); i++)
1658     {
1659         if (IS_SAI_FLAG_SET((1UL << i), channelMask))
1660         {
1661             channelNums++;
1662             endChannel = i;
1663         }
1664     }
1665 
1666     bytesPerWord *= channelNums;
1667 
1668     while (j < size)
1669     {
1670         /* Wait until data is received */
1671         while (!(IS_SAI_FLAG_SET(base->RCSR, I2S_RCSR_FWF_MASK)))
1672         {
1673         }
1674 
1675         SAI_ReadNonBlocking(base, channel, channelMask, endChannel, (uint8_t)bitWidth, buffer,
1676                             bytesPerWord * channelNums);
1677         buffer = (uint8_t *)((uintptr_t)buffer + bytesPerWord * channelNums);
1678         j += bytesPerWord * channelNums;
1679     }
1680 }
1681 
1682 /*!
1683  * brief Receives data using a blocking method.
1684  *
1685  * note This function blocks by polling until data is ready to be sent.
1686  *
1687  * param base SAI base pointer.
1688  * param channel Data channel used.
1689  * param bitWidth How many bits in an audio word; usually 8/16/24/32 bits.
1690  * param buffer Pointer to the data to be read.
1691  * param size Bytes to be read.
1692  */
SAI_ReadBlocking(I2S_Type * base,uint32_t channel,uint32_t bitWidth,uint8_t * buffer,uint32_t size)1693 void SAI_ReadBlocking(I2S_Type *base, uint32_t channel, uint32_t bitWidth, uint8_t *buffer, uint32_t size)
1694 {
1695     uint32_t i            = 0;
1696     uint32_t bytesPerWord = bitWidth / 8U;
1697 #if defined(FSL_FEATURE_SAI_HAS_FIFO) && (FSL_FEATURE_SAI_HAS_FIFO)
1698     bytesPerWord = base->RCR1 * bytesPerWord;
1699 #endif
1700 
1701     while (i < size)
1702     {
1703         /* Wait until data is received */
1704         while (!(IS_SAI_FLAG_SET(base->RCSR, I2S_RCSR_FWF_MASK)))
1705         {
1706         }
1707 
1708         SAI_ReadNonBlocking(base, channel, 1UL << channel, channel, (uint8_t)bitWidth, buffer, bytesPerWord);
1709         buffer = (uint8_t *)((uintptr_t)buffer + bytesPerWord);
1710         i += bytesPerWord;
1711     }
1712 }
1713 
1714 /*!
1715  * brief Initializes the SAI Tx handle.
1716  *
1717  * This function initializes the Tx handle for the SAI Tx transactional APIs. Call
1718  * this function once to get the handle initialized.
1719  *
1720  * param base SAI base pointer
1721  * param handle SAI handle pointer.
1722  * param callback Pointer to the user callback function.
1723  * param userData User parameter passed to the callback function
1724  */
SAI_TransferTxCreateHandle(I2S_Type * base,sai_handle_t * handle,sai_transfer_callback_t callback,void * userData)1725 void SAI_TransferTxCreateHandle(I2S_Type *base, sai_handle_t *handle, sai_transfer_callback_t callback, void *userData)
1726 {
1727     assert(handle != NULL);
1728 
1729     /* Zero the handle */
1730     (void)memset(handle, 0, sizeof(*handle));
1731 
1732     s_saiHandle[SAI_GetInstance(base)][0] = handle;
1733 
1734     handle->callback = callback;
1735     handle->userData = userData;
1736     handle->base     = base;
1737 
1738     /* Set the isr pointer */
1739     s_saiTxIsr = SAI_TransferTxHandleIRQ;
1740 
1741     /* Enable Tx irq */
1742     (void)EnableIRQ(s_saiTxIRQ[SAI_GetInstance(base)]);
1743 }
1744 
1745 /*!
1746  * brief Initializes the SAI Rx handle.
1747  *
1748  * This function initializes the Rx handle for the SAI Rx transactional APIs. Call
1749  * this function once to get the handle initialized.
1750  *
1751  * param base SAI base pointer.
1752  * param handle SAI handle pointer.
1753  * param callback Pointer to the user callback function.
1754  * param userData User parameter passed to the callback function.
1755  */
SAI_TransferRxCreateHandle(I2S_Type * base,sai_handle_t * handle,sai_transfer_callback_t callback,void * userData)1756 void SAI_TransferRxCreateHandle(I2S_Type *base, sai_handle_t *handle, sai_transfer_callback_t callback, void *userData)
1757 {
1758     assert(handle != NULL);
1759 
1760     /* Zero the handle */
1761     (void)memset(handle, 0, sizeof(*handle));
1762 
1763     s_saiHandle[SAI_GetInstance(base)][1] = handle;
1764 
1765     handle->callback = callback;
1766     handle->userData = userData;
1767     handle->base     = base;
1768 
1769     /* Set the isr pointer */
1770     s_saiRxIsr = SAI_TransferRxHandleIRQ;
1771 
1772     /* Enable Rx irq */
1773     (void)EnableIRQ(s_saiRxIRQ[SAI_GetInstance(base)]);
1774 }
1775 
1776 /*!
1777  * brief Performs an interrupt non-blocking send transfer on SAI.
1778  *
1779  * note This API returns immediately after the transfer initiates.
1780  * Call the SAI_TxGetTransferStatusIRQ to poll the transfer status and check whether
1781  * the transfer is finished. If the return status is not kStatus_SAI_Busy, the transfer
1782  * is finished.
1783  *
1784  * param base SAI base pointer.
1785  * param handle Pointer to the sai_handle_t structure which stores the transfer state.
1786  * param xfer Pointer to the sai_transfer_t structure.
1787  * retval kStatus_Success Successfully started the data receive.
1788  * retval kStatus_SAI_TxBusy Previous receive still not finished.
1789  * retval kStatus_InvalidArgument The input parameter is invalid.
1790  */
SAI_TransferSendNonBlocking(I2S_Type * base,sai_handle_t * handle,sai_transfer_t * xfer)1791 status_t SAI_TransferSendNonBlocking(I2S_Type *base, sai_handle_t *handle, sai_transfer_t *xfer)
1792 {
1793     assert(handle != NULL);
1794     assert(handle->channelNums <= (uint32_t)FSL_FEATURE_SAI_CHANNEL_COUNTn(base));
1795 
1796     /* Check if the queue is full */
1797     if (handle->saiQueue[handle->queueUser].data != NULL)
1798     {
1799         return kStatus_SAI_QueueFull;
1800     }
1801 
1802     /* Add into queue */
1803     handle->transferSize[handle->queueUser]      = xfer->dataSize;
1804     handle->saiQueue[handle->queueUser].data     = xfer->data;
1805     handle->saiQueue[handle->queueUser].dataSize = xfer->dataSize;
1806     handle->queueUser                            = (handle->queueUser + 1U) % (uint8_t)SAI_XFER_QUEUE_SIZE;
1807 
1808     /* Set the state to busy */
1809     handle->state = (uint32_t)kSAI_Busy;
1810 
1811     /* Enable interrupt */
1812 #if defined(FSL_FEATURE_SAI_HAS_FIFO) && (FSL_FEATURE_SAI_HAS_FIFO)
1813     /* Use FIFO request interrupt and fifo error*/
1814     SAI_TxEnableInterrupts(base, I2S_TCSR_FEIE_MASK | I2S_TCSR_FRIE_MASK);
1815 #else
1816     SAI_TxEnableInterrupts(base, I2S_TCSR_FEIE_MASK | I2S_TCSR_FWIE_MASK);
1817 #endif /* FSL_FEATURE_SAI_HAS_FIFO */
1818 
1819     /* Enable Tx transfer */
1820     SAI_TxEnable(base, true);
1821 
1822     return kStatus_Success;
1823 }
1824 
1825 /*!
1826  * brief Performs an interrupt non-blocking receive transfer on SAI.
1827  *
1828  * note This API returns immediately after the transfer initiates.
1829  * Call the SAI_RxGetTransferStatusIRQ to poll the transfer status and check whether
1830  * the transfer is finished. If the return status is not kStatus_SAI_Busy, the transfer
1831  * is finished.
1832  *
1833  * param base SAI base pointer
1834  * param handle Pointer to the sai_handle_t structure which stores the transfer state.
1835  * param xfer Pointer to the sai_transfer_t structure.
1836  * retval kStatus_Success Successfully started the data receive.
1837  * retval kStatus_SAI_RxBusy Previous receive still not finished.
1838  * retval kStatus_InvalidArgument The input parameter is invalid.
1839  */
SAI_TransferReceiveNonBlocking(I2S_Type * base,sai_handle_t * handle,sai_transfer_t * xfer)1840 status_t SAI_TransferReceiveNonBlocking(I2S_Type *base, sai_handle_t *handle, sai_transfer_t *xfer)
1841 {
1842     assert(handle != NULL);
1843     assert(handle->channelNums <= (uint32_t)FSL_FEATURE_SAI_CHANNEL_COUNTn(base));
1844 
1845     /* Check if the queue is full */
1846     if (handle->saiQueue[handle->queueUser].data != NULL)
1847     {
1848         return kStatus_SAI_QueueFull;
1849     }
1850 
1851     /* Add into queue */
1852     handle->transferSize[handle->queueUser]      = xfer->dataSize;
1853     handle->saiQueue[handle->queueUser].data     = xfer->data;
1854     handle->saiQueue[handle->queueUser].dataSize = xfer->dataSize;
1855     handle->queueUser                            = (handle->queueUser + 1U) % (uint8_t)SAI_XFER_QUEUE_SIZE;
1856 
1857     /* Set state to busy */
1858     handle->state = (uint32_t)kSAI_Busy;
1859 
1860 /* Enable interrupt */
1861 #if defined(FSL_FEATURE_SAI_HAS_FIFO) && (FSL_FEATURE_SAI_HAS_FIFO)
1862     /* Use FIFO request interrupt and fifo error*/
1863     SAI_RxEnableInterrupts(base, I2S_TCSR_FEIE_MASK | I2S_TCSR_FRIE_MASK);
1864 #else
1865     SAI_RxEnableInterrupts(base, I2S_TCSR_FEIE_MASK | I2S_TCSR_FWIE_MASK);
1866 #endif /* FSL_FEATURE_SAI_HAS_FIFO */
1867 
1868     /* Enable Rx transfer */
1869     SAI_RxEnable(base, true);
1870 
1871     return kStatus_Success;
1872 }
1873 
1874 /*!
1875  * brief Gets a set byte count.
1876  *
1877  * param base SAI base pointer.
1878  * param handle Pointer to the sai_handle_t structure which stores the transfer state.
1879  * param count Bytes count sent.
1880  * retval kStatus_Success Succeed get the transfer count.
1881  * retval kStatus_NoTransferInProgress There is not a non-blocking transaction currently in progress.
1882  */
SAI_TransferGetSendCount(I2S_Type * base,sai_handle_t * handle,size_t * count)1883 status_t SAI_TransferGetSendCount(I2S_Type *base, sai_handle_t *handle, size_t *count)
1884 {
1885     assert(handle != NULL);
1886 
1887     status_t status           = kStatus_Success;
1888     uint32_t queueDriverIndex = handle->queueDriver;
1889 
1890     if (handle->state != (uint32_t)kSAI_Busy)
1891     {
1892         status = kStatus_NoTransferInProgress;
1893     }
1894     else
1895     {
1896         *count = (handle->transferSize[queueDriverIndex] - handle->saiQueue[queueDriverIndex].dataSize);
1897     }
1898 
1899     return status;
1900 }
1901 
1902 /*!
1903  * brief Gets a received byte count.
1904  *
1905  * param base SAI base pointer.
1906  * param handle Pointer to the sai_handle_t structure which stores the transfer state.
1907  * param count Bytes count received.
1908  * retval kStatus_Success Succeed get the transfer count.
1909  * retval kStatus_NoTransferInProgress There is not a non-blocking transaction currently in progress.
1910  */
SAI_TransferGetReceiveCount(I2S_Type * base,sai_handle_t * handle,size_t * count)1911 status_t SAI_TransferGetReceiveCount(I2S_Type *base, sai_handle_t *handle, size_t *count)
1912 {
1913     assert(handle != NULL);
1914 
1915     status_t status           = kStatus_Success;
1916     uint32_t queueDriverIndex = handle->queueDriver;
1917 
1918     if (handle->state != (uint32_t)kSAI_Busy)
1919     {
1920         status = kStatus_NoTransferInProgress;
1921     }
1922     else
1923     {
1924         *count = (handle->transferSize[queueDriverIndex] - handle->saiQueue[queueDriverIndex].dataSize);
1925     }
1926 
1927     return status;
1928 }
1929 
1930 /*!
1931  * brief Aborts the current send.
1932  *
1933  * note This API can be called any time when an interrupt non-blocking transfer initiates
1934  * to abort the transfer early.
1935  *
1936  * param base SAI base pointer.
1937  * param handle Pointer to the sai_handle_t structure which stores the transfer state.
1938  */
SAI_TransferAbortSend(I2S_Type * base,sai_handle_t * handle)1939 void SAI_TransferAbortSend(I2S_Type *base, sai_handle_t *handle)
1940 {
1941     assert(handle != NULL);
1942 
1943     /* Stop Tx transfer and disable interrupt */
1944     SAI_TxEnable(base, false);
1945 #if defined(FSL_FEATURE_SAI_HAS_FIFO) && (FSL_FEATURE_SAI_HAS_FIFO)
1946     /* Use FIFO request interrupt and fifo error */
1947     SAI_TxDisableInterrupts(base, I2S_TCSR_FEIE_MASK | I2S_TCSR_FRIE_MASK);
1948 #else
1949     SAI_TxDisableInterrupts(base, I2S_TCSR_FEIE_MASK | I2S_TCSR_FWIE_MASK);
1950 #endif /* FSL_FEATURE_SAI_HAS_FIFO */
1951 
1952     handle->state = (uint32_t)kSAI_Idle;
1953 
1954     /* Clear the queue */
1955     (void)memset(handle->saiQueue, 0, sizeof(sai_transfer_t) * (uint8_t)SAI_XFER_QUEUE_SIZE);
1956     handle->queueDriver = 0;
1957     handle->queueUser   = 0;
1958 }
1959 
1960 /*!
1961  * brief Aborts the current IRQ receive.
1962  *
1963  * note This API can be called when an interrupt non-blocking transfer initiates
1964  * to abort the transfer early.
1965  *
1966  * param base SAI base pointer
1967  * param handle Pointer to the sai_handle_t structure which stores the transfer state.
1968  */
SAI_TransferAbortReceive(I2S_Type * base,sai_handle_t * handle)1969 void SAI_TransferAbortReceive(I2S_Type *base, sai_handle_t *handle)
1970 {
1971     assert(handle != NULL);
1972 
1973     /* Stop Tx transfer and disable interrupt */
1974     SAI_RxEnable(base, false);
1975 #if defined(FSL_FEATURE_SAI_HAS_FIFO) && (FSL_FEATURE_SAI_HAS_FIFO)
1976     /* Use FIFO request interrupt and fifo error */
1977     SAI_RxDisableInterrupts(base, I2S_TCSR_FEIE_MASK | I2S_TCSR_FRIE_MASK);
1978 #else
1979     SAI_RxDisableInterrupts(base, I2S_TCSR_FEIE_MASK | I2S_TCSR_FWIE_MASK);
1980 #endif /* FSL_FEATURE_SAI_HAS_FIFO */
1981 
1982     handle->state = (uint32_t)kSAI_Idle;
1983 
1984     /* Clear the queue */
1985     (void)memset(handle->saiQueue, 0, sizeof(sai_transfer_t) * (uint8_t)SAI_XFER_QUEUE_SIZE);
1986     handle->queueDriver = 0;
1987     handle->queueUser   = 0;
1988 }
1989 
1990 /*!
1991  * brief Terminate all SAI send.
1992  *
1993  * This function will clear all transfer slots buffered in the sai queue. If users only want to abort the
1994  * current transfer slot, please call SAI_TransferAbortSend.
1995  *
1996  * param base SAI base pointer.
1997  * param handle SAI eDMA handle pointer.
1998  */
SAI_TransferTerminateSend(I2S_Type * base,sai_handle_t * handle)1999 void SAI_TransferTerminateSend(I2S_Type *base, sai_handle_t *handle)
2000 {
2001     assert(handle != NULL);
2002 
2003     /* Abort the current transfer */
2004     SAI_TransferAbortSend(base, handle);
2005 
2006     /* Clear all the internal information */
2007     (void)memset(handle->saiQueue, 0, sizeof(handle->saiQueue));
2008     (void)memset(handle->transferSize, 0, sizeof(handle->transferSize));
2009 
2010     handle->queueUser   = 0U;
2011     handle->queueDriver = 0U;
2012 }
2013 
2014 /*!
2015  * brief Terminate all SAI receive.
2016  *
2017  * This function will clear all transfer slots buffered in the sai queue. If users only want to abort the
2018  * current transfer slot, please call SAI_TransferAbortReceive.
2019  *
2020  * param base SAI base pointer.
2021  * param handle SAI eDMA handle pointer.
2022  */
SAI_TransferTerminateReceive(I2S_Type * base,sai_handle_t * handle)2023 void SAI_TransferTerminateReceive(I2S_Type *base, sai_handle_t *handle)
2024 {
2025     assert(handle != NULL);
2026 
2027     /* Abort the current transfer */
2028     SAI_TransferAbortReceive(base, handle);
2029 
2030     /* Clear all the internal information */
2031     (void)memset(handle->saiQueue, 0, sizeof(handle->saiQueue));
2032     (void)memset(handle->transferSize, 0, sizeof(handle->transferSize));
2033 
2034     handle->queueUser   = 0U;
2035     handle->queueDriver = 0U;
2036 }
2037 
2038 /*!
2039  * brief Tx interrupt handler.
2040  *
2041  * param base SAI base pointer.
2042  * param handle Pointer to the sai_handle_t structure.
2043  */
SAI_TransferTxHandleIRQ(I2S_Type * base,sai_handle_t * handle)2044 void SAI_TransferTxHandleIRQ(I2S_Type *base, sai_handle_t *handle)
2045 {
2046     assert(handle != NULL);
2047 
2048     uint8_t *buffer   = handle->saiQueue[handle->queueDriver].data;
2049     uint32_t dataSize = (handle->bitWidth / 8UL) * handle->channelNums;
2050 
2051     /* Handle Error */
2052     if (IS_SAI_FLAG_SET(base->TCSR, I2S_TCSR_FEF_MASK))
2053     {
2054         /* Clear FIFO error flag to continue transfer */
2055         SAI_TxClearStatusFlags(base, I2S_TCSR_FEF_MASK);
2056 
2057         /* Reset FIFO for safety */
2058         SAI_TxSoftwareReset(base, kSAI_ResetTypeFIFO);
2059 
2060         /* Call the callback */
2061         if (handle->callback != NULL)
2062         {
2063             (handle->callback)(base, handle, kStatus_SAI_TxError, handle->userData);
2064         }
2065     }
2066 
2067 /* Handle transfer */
2068 #if defined(FSL_FEATURE_SAI_HAS_FIFO) && (FSL_FEATURE_SAI_HAS_FIFO)
2069     if (IS_SAI_FLAG_SET(base->TCSR, I2S_TCSR_FRF_MASK))
2070     {
2071         /* Judge if the data need to transmit is less than space */
2072         size_t size = MIN((handle->saiQueue[handle->queueDriver].dataSize),
2073                           (size_t)(((uint32_t)FSL_FEATURE_SAI_FIFO_COUNTn(base) - handle->watermark) * dataSize));
2074 
2075         /* Copy the data from sai buffer to FIFO */
2076         SAI_WriteNonBlocking(base, handle->channel, handle->channelMask, handle->endChannel, handle->bitWidth, buffer,
2077                              size);
2078 
2079         /* Update the internal counter */
2080         handle->saiQueue[handle->queueDriver].dataSize -= size;
2081         handle->saiQueue[handle->queueDriver].data = (uint8_t *)((uintptr_t)buffer + size);
2082     }
2083 #else
2084     if (IS_SAI_FLAG_SET(base->TCSR, I2S_TCSR_FWF_MASK))
2085     {
2086         size_t size = MIN((handle->saiQueue[handle->queueDriver].dataSize), dataSize);
2087 
2088         SAI_WriteNonBlocking(base, handle->channel, handle->channelMask, handle->endChannel, handle->bitWidth, buffer,
2089                              size);
2090 
2091         /* Update internal counter */
2092         handle->saiQueue[handle->queueDriver].dataSize -= size;
2093         handle->saiQueue[handle->queueDriver].data = (uint8_t *)((uintptr_t)buffer + size);
2094     }
2095 #endif /* FSL_FEATURE_SAI_HAS_FIFO */
2096 
2097     /* If finished a block, call the callback function */
2098     if (handle->saiQueue[handle->queueDriver].dataSize == 0U)
2099     {
2100         (void)memset(&handle->saiQueue[handle->queueDriver], 0, sizeof(sai_transfer_t));
2101         handle->queueDriver = (handle->queueDriver + 1U) % (uint8_t)SAI_XFER_QUEUE_SIZE;
2102         if (handle->callback != NULL)
2103         {
2104             (handle->callback)(base, handle, kStatus_SAI_TxIdle, handle->userData);
2105         }
2106     }
2107 
2108     /* If all data finished, just stop the transfer */
2109     if (handle->saiQueue[handle->queueDriver].data == NULL)
2110     {
2111         SAI_TransferAbortSend(base, handle);
2112     }
2113 }
2114 
2115 /*!
2116  * brief Tx interrupt handler.
2117  *
2118  * param base SAI base pointer.
2119  * param handle Pointer to the sai_handle_t structure.
2120  */
SAI_TransferRxHandleIRQ(I2S_Type * base,sai_handle_t * handle)2121 void SAI_TransferRxHandleIRQ(I2S_Type *base, sai_handle_t *handle)
2122 {
2123     assert(handle != NULL);
2124 
2125     uint8_t *buffer   = handle->saiQueue[handle->queueDriver].data;
2126     uint32_t dataSize = (handle->bitWidth / 8UL) * handle->channelNums;
2127 
2128     /* Handle Error */
2129     if (IS_SAI_FLAG_SET(base->RCSR, I2S_RCSR_FEF_MASK))
2130     {
2131         /* Clear FIFO error flag to continue transfer */
2132         SAI_RxClearStatusFlags(base, I2S_TCSR_FEF_MASK);
2133 
2134         /* Reset FIFO for safety */
2135         SAI_RxSoftwareReset(base, kSAI_ResetTypeFIFO);
2136 
2137         /* Call the callback */
2138         if (handle->callback != NULL)
2139         {
2140             (handle->callback)(base, handle, kStatus_SAI_RxError, handle->userData);
2141         }
2142     }
2143 
2144 /* Handle transfer */
2145 #if defined(FSL_FEATURE_SAI_HAS_FIFO) && (FSL_FEATURE_SAI_HAS_FIFO)
2146     if (IS_SAI_FLAG_SET(base->RCSR, I2S_RCSR_FRF_MASK))
2147     {
2148         /* Judge if the data need to transmit is less than space */
2149         size_t size = MIN((handle->saiQueue[handle->queueDriver].dataSize), handle->watermark * dataSize);
2150 
2151         /* Copy the data from sai buffer to FIFO */
2152         SAI_ReadNonBlocking(base, handle->channel, handle->channelMask, handle->endChannel, handle->bitWidth, buffer,
2153                             size);
2154 
2155         /* Update the internal counter */
2156         handle->saiQueue[handle->queueDriver].dataSize -= size;
2157         handle->saiQueue[handle->queueDriver].data = (uint8_t *)((uintptr_t)buffer + size);
2158     }
2159 #else
2160     if (IS_SAI_FLAG_SET(base->RCSR, I2S_RCSR_FWF_MASK))
2161     {
2162         size_t size = MIN((handle->saiQueue[handle->queueDriver].dataSize), dataSize);
2163 
2164         SAI_ReadNonBlocking(base, handle->channel, handle->channelMask, handle->endChannel, handle->bitWidth, buffer,
2165                             size);
2166 
2167         /* Update internal state */
2168         handle->saiQueue[handle->queueDriver].dataSize -= size;
2169         handle->saiQueue[handle->queueDriver].data = (uint8_t *)((uintptr_t)buffer + size);
2170     }
2171 #endif /* FSL_FEATURE_SAI_HAS_FIFO */
2172 
2173     /* If finished a block, call the callback function */
2174     if (handle->saiQueue[handle->queueDriver].dataSize == 0U)
2175     {
2176         (void)memset(&handle->saiQueue[handle->queueDriver], 0, sizeof(sai_transfer_t));
2177         handle->queueDriver = (handle->queueDriver + 1U) % (uint8_t)SAI_XFER_QUEUE_SIZE;
2178         if (handle->callback != NULL)
2179         {
2180             (handle->callback)(base, handle, kStatus_SAI_RxIdle, handle->userData);
2181         }
2182     }
2183 
2184     /* If all data finished, just stop the transfer */
2185     if (handle->saiQueue[handle->queueDriver].data == NULL)
2186     {
2187         SAI_TransferAbortReceive(base, handle);
2188     }
2189 }
2190 
2191 #if defined(I2S0)
2192 void I2S0_DriverIRQHandler(void);
I2S0_DriverIRQHandler(void)2193 void I2S0_DriverIRQHandler(void)
2194 {
2195 #if defined(FSL_FEATURE_SAI_HAS_FIFO) && (FSL_FEATURE_SAI_HAS_FIFO)
2196     if ((s_saiHandle[0][1] != NULL) && SAI_RxGetEnabledInterruptStatus(I2S0, (I2S_TCSR_FRIE_MASK | I2S_TCSR_FEIE_MASK),
2197                                                                        (I2S_TCSR_FRF_MASK | I2S_TCSR_FEF_MASK)))
2198 #else
2199     if ((s_saiHandle[0][1] != NULL) && SAI_RxGetEnabledInterruptStatus(I2S0, (I2S_TCSR_FWIE_MASK | I2S_TCSR_FEIE_MASK),
2200                                                                        (I2S_TCSR_FWF_MASK | I2S_TCSR_FEF_MASK)))
2201 #endif
2202     {
2203         s_saiRxIsr(I2S0, s_saiHandle[0][1]);
2204     }
2205 #if defined(FSL_FEATURE_SAI_HAS_FIFO) && (FSL_FEATURE_SAI_HAS_FIFO)
2206     if ((s_saiHandle[0][0] != NULL) && SAI_TxGetEnabledInterruptStatus(I2S0, (I2S_TCSR_FRIE_MASK | I2S_TCSR_FEIE_MASK),
2207                                                                        (I2S_TCSR_FRF_MASK | I2S_TCSR_FEF_MASK)))
2208 #else
2209     if ((s_saiHandle[0][0] != NULL) && SAI_TxGetEnabledInterruptStatus(I2S0, (I2S_TCSR_FWIE_MASK | I2S_TCSR_FEIE_MASK),
2210                                                                        (I2S_TCSR_FWF_MASK | I2S_TCSR_FEF_MASK)))
2211 #endif
2212     {
2213         s_saiTxIsr(I2S0, s_saiHandle[0][0]);
2214     }
2215     SDK_ISR_EXIT_BARRIER;
2216 }
2217 
2218 void I2S0_Tx_DriverIRQHandler(void);
I2S0_Tx_DriverIRQHandler(void)2219 void I2S0_Tx_DriverIRQHandler(void)
2220 {
2221     assert(s_saiHandle[0][0] != NULL);
2222     s_saiTxIsr(I2S0, s_saiHandle[0][0]);
2223     SDK_ISR_EXIT_BARRIER;
2224 }
2225 
2226 void I2S0_Rx_DriverIRQHandler(void);
I2S0_Rx_DriverIRQHandler(void)2227 void I2S0_Rx_DriverIRQHandler(void)
2228 {
2229     assert(s_saiHandle[0][1] != NULL);
2230     s_saiRxIsr(I2S0, s_saiHandle[0][1]);
2231     SDK_ISR_EXIT_BARRIER;
2232 }
2233 #endif /* I2S0*/
2234 
2235 #if defined(I2S1)
2236 void I2S1_DriverIRQHandler(void);
I2S1_DriverIRQHandler(void)2237 void I2S1_DriverIRQHandler(void)
2238 {
2239 #if defined(FSL_FEATURE_SAI_HAS_FIFO) && (FSL_FEATURE_SAI_HAS_FIFO)
2240     if ((s_saiHandle[1][1] != NULL) && SAI_RxGetEnabledInterruptStatus(I2S1, (I2S_TCSR_FRIE_MASK | I2S_TCSR_FEIE_MASK),
2241                                                                        (I2S_TCSR_FRF_MASK | I2S_TCSR_FEF_MASK)))
2242 #else
2243     if ((s_saiHandle[1][1] != NULL) && SAI_RxGetEnabledInterruptStatus(I2S1, (I2S_TCSR_FWIE_MASK | I2S_TCSR_FEIE_MASK),
2244                                                                        (I2S_TCSR_FWF_MASK | I2S_TCSR_FEF_MASK)))
2245 #endif
2246     {
2247         s_saiRxIsr(I2S1, s_saiHandle[1][1]);
2248     }
2249 
2250 #if defined(FSL_FEATURE_SAI_HAS_FIFO) && (FSL_FEATURE_SAI_HAS_FIFO)
2251     if ((s_saiHandle[1][0] != NULL) && SAI_TxGetEnabledInterruptStatus(I2S1, (I2S_TCSR_FRIE_MASK | I2S_TCSR_FEIE_MASK),
2252                                                                        (I2S_TCSR_FRF_MASK | I2S_TCSR_FEF_MASK)))
2253 #else
2254     if ((s_saiHandle[1][0] != NULL) && SAI_TxGetEnabledInterruptStatus(I2S1, (I2S_TCSR_FWIE_MASK | I2S_TCSR_FEIE_MASK),
2255                                                                        (I2S_TCSR_FWF_MASK | I2S_TCSR_FEF_MASK)))
2256 #endif
2257     {
2258         s_saiTxIsr(I2S1, s_saiHandle[1][0]);
2259     }
2260     SDK_ISR_EXIT_BARRIER;
2261 }
2262 
2263 void I2S1_Tx_DriverIRQHandler(void);
I2S1_Tx_DriverIRQHandler(void)2264 void I2S1_Tx_DriverIRQHandler(void)
2265 {
2266     assert(s_saiHandle[1][0] != NULL);
2267     s_saiTxIsr(I2S1, s_saiHandle[1][0]);
2268     SDK_ISR_EXIT_BARRIER;
2269 }
2270 
2271 void I2S1_Rx_DriverIRQHandler(void);
I2S1_Rx_DriverIRQHandler(void)2272 void I2S1_Rx_DriverIRQHandler(void)
2273 {
2274     assert(s_saiHandle[1][1] != NULL);
2275     s_saiRxIsr(I2S1, s_saiHandle[1][1]);
2276     SDK_ISR_EXIT_BARRIER;
2277 }
2278 #endif /* I2S1*/
2279 
2280 #if defined(I2S2)
2281 void I2S2_DriverIRQHandler(void);
I2S2_DriverIRQHandler(void)2282 void I2S2_DriverIRQHandler(void)
2283 {
2284 #if defined(FSL_FEATURE_SAI_HAS_FIFO) && (FSL_FEATURE_SAI_HAS_FIFO)
2285     if ((s_saiHandle[2][1] != NULL) && SAI_RxGetEnabledInterruptStatus(I2S2, (I2S_TCSR_FRIE_MASK | I2S_TCSR_FEIE_MASK),
2286                                                                        (I2S_TCSR_FRF_MASK | I2S_TCSR_FEF_MASK)))
2287 #else
2288     if ((s_saiHandle[2][1] != NULL) && SAI_RxGetEnabledInterruptStatus(I2S2, (I2S_TCSR_FWIE_MASK | I2S_TCSR_FEIE_MASK),
2289                                                                        (I2S_TCSR_FWF_MASK | I2S_TCSR_FEF_MASK)))
2290 #endif
2291     {
2292         s_saiRxIsr(I2S2, s_saiHandle[2][1]);
2293     }
2294 
2295 #if defined(FSL_FEATURE_SAI_HAS_FIFO) && (FSL_FEATURE_SAI_HAS_FIFO)
2296     if ((s_saiHandle[2][0] != NULL) && SAI_TxGetEnabledInterruptStatus(I2S2, (I2S_TCSR_FRIE_MASK | I2S_TCSR_FEIE_MASK),
2297                                                                        (I2S_TCSR_FRF_MASK | I2S_TCSR_FEF_MASK)))
2298 #else
2299     if ((s_saiHandle[2][0] != NULL) && SAI_TxGetEnabledInterruptStatus(I2S2, (I2S_TCSR_FWIE_MASK | I2S_TCSR_FEIE_MASK),
2300                                                                        (I2S_TCSR_FWF_MASK | I2S_TCSR_FEF_MASK)))
2301 #endif
2302     {
2303         s_saiTxIsr(I2S2, s_saiHandle[2][0]);
2304     }
2305     SDK_ISR_EXIT_BARRIER;
2306 }
2307 
2308 void I2S2_Tx_DriverIRQHandler(void);
I2S2_Tx_DriverIRQHandler(void)2309 void I2S2_Tx_DriverIRQHandler(void)
2310 {
2311     assert(s_saiHandle[2][0] != NULL);
2312     s_saiTxIsr(I2S2, s_saiHandle[2][0]);
2313     SDK_ISR_EXIT_BARRIER;
2314 }
2315 
2316 void I2S2_Rx_DriverIRQHandler(void);
I2S2_Rx_DriverIRQHandler(void)2317 void I2S2_Rx_DriverIRQHandler(void)
2318 {
2319     assert(s_saiHandle[2][1] != NULL);
2320     s_saiRxIsr(I2S2, s_saiHandle[2][1]);
2321     SDK_ISR_EXIT_BARRIER;
2322 }
2323 #endif /* I2S2*/
2324 
2325 #if defined(I2S3)
2326 void I2S3_DriverIRQHandler(void);
I2S3_DriverIRQHandler(void)2327 void I2S3_DriverIRQHandler(void)
2328 {
2329 #if defined(FSL_FEATURE_SAI_HAS_FIFO) && (FSL_FEATURE_SAI_HAS_FIFO)
2330     if ((s_saiHandle[3][1] != NULL) && SAI_RxGetEnabledInterruptStatus(I2S3, (I2S_TCSR_FRIE_MASK | I2S_TCSR_FEIE_MASK),
2331                                                                        (I2S_TCSR_FRF_MASK | I2S_TCSR_FEF_MASK)))
2332 #else
2333     if ((s_saiHandle[3][1] != NULL) && SAI_RxGetEnabledInterruptStatus(I2S3, (I2S_TCSR_FWIE_MASK | I2S_TCSR_FEIE_MASK),
2334                                                                        (I2S_TCSR_FWF_MASK | I2S_TCSR_FEF_MASK)))
2335 #endif
2336     {
2337         s_saiRxIsr(I2S3, s_saiHandle[3][1]);
2338     }
2339 #if defined(FSL_FEATURE_SAI_HAS_FIFO) && (FSL_FEATURE_SAI_HAS_FIFO)
2340     if ((s_saiHandle[3][0] != NULL) && SAI_TxGetEnabledInterruptStatus(I2S3, (I2S_TCSR_FRIE_MASK | I2S_TCSR_FEIE_MASK),
2341                                                                        (I2S_TCSR_FRF_MASK | I2S_TCSR_FEF_MASK)))
2342 #else
2343     if ((s_saiHandle[3][0] != NULL) && SAI_TxGetEnabledInterruptStatus(I2S3, (I2S_TCSR_FWIE_MASK | I2S_TCSR_FEIE_MASK),
2344                                                                        (I2S_TCSR_FWF_MASK | I2S_TCSR_FEF_MASK)))
2345 #endif
2346     {
2347         s_saiTxIsr(I2S3, s_saiHandle[3][0]);
2348     }
2349     SDK_ISR_EXIT_BARRIER;
2350 }
2351 
2352 void I2S3_Tx_DriverIRQHandler(void);
I2S3_Tx_DriverIRQHandler(void)2353 void I2S3_Tx_DriverIRQHandler(void)
2354 {
2355     assert(s_saiHandle[3][0] != NULL);
2356     s_saiTxIsr(I2S3, s_saiHandle[3][0]);
2357     SDK_ISR_EXIT_BARRIER;
2358 }
2359 
2360 void I2S3_Rx_DriverIRQHandler(void);
I2S3_Rx_DriverIRQHandler(void)2361 void I2S3_Rx_DriverIRQHandler(void)
2362 {
2363     assert(s_saiHandle[3][1] != NULL);
2364     s_saiRxIsr(I2S3, s_saiHandle[3][1]);
2365     SDK_ISR_EXIT_BARRIER;
2366 }
2367 #endif /* I2S3*/
2368 
2369 #if defined(I2S4)
2370 void I2S4_DriverIRQHandler(void);
I2S4_DriverIRQHandler(void)2371 void I2S4_DriverIRQHandler(void)
2372 {
2373 #if defined(FSL_FEATURE_SAI_HAS_FIFO) && (FSL_FEATURE_SAI_HAS_FIFO)
2374     if ((s_saiHandle[4][1] != NULL) && SAI_RxGetEnabledInterruptStatus(I2S4, (I2S_TCSR_FRIE_MASK | I2S_TCSR_FEIE_MASK),
2375                                                                        (I2S_TCSR_FRF_MASK | I2S_TCSR_FEF_MASK)))
2376 #else
2377     if ((s_saiHandle[4][1] != NULL) && SAI_RxGetEnabledInterruptStatus(I2S4, (I2S_TCSR_FWIE_MASK | I2S_TCSR_FEIE_MASK),
2378                                                                        (I2S_TCSR_FWF_MASK | I2S_TCSR_FEF_MASK)))
2379 #endif
2380     {
2381         s_saiRxIsr(I2S4, s_saiHandle[4][1]);
2382     }
2383 
2384 #if defined(FSL_FEATURE_SAI_HAS_FIFO) && (FSL_FEATURE_SAI_HAS_FIFO)
2385     if ((s_saiHandle[4][0] != NULL) && SAI_TxGetEnabledInterruptStatus(I2S4, (I2S_TCSR_FRIE_MASK | I2S_TCSR_FEIE_MASK),
2386                                                                        (I2S_TCSR_FRF_MASK | I2S_TCSR_FEF_MASK)))
2387 #else
2388     if ((s_saiHandle[4][0] != NULL) && SAI_TxGetEnabledInterruptStatus(I2S4, (I2S_TCSR_FWIE_MASK | I2S_TCSR_FEIE_MASK),
2389                                                                        (I2S_TCSR_FWF_MASK | I2S_TCSR_FEF_MASK)))
2390 #endif
2391     {
2392         s_saiTxIsr(I2S4, s_saiHandle[4][0]);
2393     }
2394     SDK_ISR_EXIT_BARRIER;
2395 }
2396 
2397 void I2S4_Tx_DriverIRQHandler(void);
I2S4_Tx_DriverIRQHandler(void)2398 void I2S4_Tx_DriverIRQHandler(void)
2399 {
2400     assert(s_saiHandle[4][0] != NULL);
2401     s_saiTxIsr(I2S4, s_saiHandle[4][0]);
2402     SDK_ISR_EXIT_BARRIER;
2403 }
2404 
2405 void I2S4_Rx_DriverIRQHandler(void);
I2S4_Rx_DriverIRQHandler(void)2406 void I2S4_Rx_DriverIRQHandler(void)
2407 {
2408     assert(s_saiHandle[4][1] != NULL);
2409     s_saiRxIsr(I2S4, s_saiHandle[4][1]);
2410     SDK_ISR_EXIT_BARRIER;
2411 }
2412 #endif
2413 
2414 #if defined(FSL_FEATURE_SAI_SAI5_SAI6_SHARE_IRQ) && (FSL_FEATURE_SAI_SAI5_SAI6_SHARE_IRQ) && defined(I2S5) && \
2415     defined(I2S6)
2416 void I2S56_DriverIRQHandler(void);
I2S56_DriverIRQHandler(void)2417 void I2S56_DriverIRQHandler(void)
2418 {
2419     /* use index 5 to get handle when I2S5 & I2S6 share IRQ NUMBER */
2420     I2S_Type *base = s_saiHandle[5][1]->base;
2421 #if defined(FSL_FEATURE_SAI_HAS_FIFO) && (FSL_FEATURE_SAI_HAS_FIFO)
2422     if ((s_saiHandle[5][1] != NULL) && SAI_RxGetEnabledInterruptStatus(base, (I2S_TCSR_FRIE_MASK | I2S_TCSR_FEIE_MASK),
2423                                                                        (I2S_TCSR_FRF_MASK | I2S_TCSR_FEF_MASK)))
2424 #else
2425     if ((s_saiHandle[5][1] != NULL) && SAI_RxGetEnabledInterruptStatus(base, (I2S_TCSR_FWIE_MASK | I2S_TCSR_FEIE_MASK),
2426                                                                        (I2S_TCSR_FWF_MASK | I2S_TCSR_FEF_MASK)))
2427 #endif
2428     {
2429         s_saiRxIsr(base, s_saiHandle[5][1]);
2430     }
2431 
2432     base = s_saiHandle[5][0]->base;
2433 #if defined(FSL_FEATURE_SAI_HAS_FIFO) && (FSL_FEATURE_SAI_HAS_FIFO)
2434     if ((s_saiHandle[5][0] != NULL) && SAI_TxGetEnabledInterruptStatus(base, (I2S_TCSR_FRIE_MASK | I2S_TCSR_FEIE_MASK),
2435                                                                        (I2S_TCSR_FRF_MASK | I2S_TCSR_FEF_MASK)))
2436 #else
2437     if ((s_saiHandle[5][0] != NULL) && SAI_TxGetEnabledInterruptStatus(base, (I2S_TCSR_FWIE_MASK | I2S_TCSR_FEIE_MASK),
2438                                                                        (I2S_TCSR_FWF_MASK | I2S_TCSR_FEF_MASK)))
2439 #endif
2440     {
2441         s_saiTxIsr(base, s_saiHandle[5][0]);
2442     }
2443     SDK_ISR_EXIT_BARRIER;
2444 }
2445 
2446 void I2S56_Tx_DriverIRQHandler(void);
I2S56_Tx_DriverIRQHandler(void)2447 void I2S56_Tx_DriverIRQHandler(void)
2448 {
2449     /* use index 5 to get handle when I2S5 & I2S6 share IRQ NUMBER */
2450     assert(s_saiHandle[5][0] != NULL);
2451     s_saiTxIsr(s_saiHandle[5][0]->base, s_saiHandle[5][0]);
2452     SDK_ISR_EXIT_BARRIER;
2453 }
2454 
2455 void I2S56_Rx_DriverIRQHandler(void);
I2S56_Rx_DriverIRQHandler(void)2456 void I2S56_Rx_DriverIRQHandler(void)
2457 {
2458     /* use index 5 to get handle when I2S5 & I2S6 share IRQ NUMBER */
2459     assert(s_saiHandle[5][1] != NULL);
2460     s_saiRxIsr(s_saiHandle[5][1]->base, s_saiHandle[5][1]);
2461     SDK_ISR_EXIT_BARRIER;
2462 }
2463 
2464 #else
2465 
2466 #if defined(I2S5)
2467 void I2S5_DriverIRQHandler(void);
I2S5_DriverIRQHandler(void)2468 void I2S5_DriverIRQHandler(void)
2469 {
2470 #if defined(FSL_FEATURE_SAI_HAS_FIFO) && (FSL_FEATURE_SAI_HAS_FIFO)
2471     if ((s_saiHandle[5][1] != NULL) && SAI_RxGetEnabledInterruptStatus(I2S5, (I2S_TCSR_FRIE_MASK | I2S_TCSR_FEIE_MASK),
2472                                                                        (I2S_TCSR_FRF_MASK | I2S_TCSR_FEF_MASK)))
2473 #else
2474     if ((s_saiHandle[5][1] != NULL) && SAI_RxGetEnabledInterruptStatus(I2S5, (I2S_TCSR_FWIE_MASK | I2S_TCSR_FEIE_MASK),
2475                                                                        (I2S_TCSR_FWF_MASK | I2S_TCSR_FEF_MASK)))
2476 #endif
2477     {
2478         s_saiRxIsr(I2S5, s_saiHandle[5][1]);
2479     }
2480 #if defined(FSL_FEATURE_SAI_HAS_FIFO) && (FSL_FEATURE_SAI_HAS_FIFO)
2481     if ((s_saiHandle[5][0] != NULL) && SAI_TxGetEnabledInterruptStatus(I2S5, (I2S_TCSR_FRIE_MASK | I2S_TCSR_FEIE_MASK),
2482                                                                        (I2S_TCSR_FRF_MASK | I2S_TCSR_FEF_MASK)))
2483 #else
2484     if ((s_saiHandle[5][0] != NULL) && SAI_TxGetEnabledInterruptStatus(I2S5, (I2S_TCSR_FWIE_MASK | I2S_TCSR_FEIE_MASK),
2485                                                                        (I2S_TCSR_FWF_MASK | I2S_TCSR_FEF_MASK)))
2486 #endif
2487     {
2488         s_saiTxIsr(I2S5, s_saiHandle[5][0]);
2489     }
2490     SDK_ISR_EXIT_BARRIER;
2491 }
2492 
2493 void I2S5_Tx_DriverIRQHandler(void);
I2S5_Tx_DriverIRQHandler(void)2494 void I2S5_Tx_DriverIRQHandler(void)
2495 {
2496     assert(s_saiHandle[5][0] != NULL);
2497     s_saiTxIsr(I2S5, s_saiHandle[5][0]);
2498     SDK_ISR_EXIT_BARRIER;
2499 }
2500 
2501 void I2S5_Rx_DriverIRQHandler(void);
I2S5_Rx_DriverIRQHandler(void)2502 void I2S5_Rx_DriverIRQHandler(void)
2503 {
2504     assert(s_saiHandle[5][1] != NULL);
2505     s_saiRxIsr(I2S5, s_saiHandle[5][1]);
2506     SDK_ISR_EXIT_BARRIER;
2507 }
2508 #endif
2509 
2510 #if defined(I2S6)
2511 void I2S6_DriverIRQHandler(void);
I2S6_DriverIRQHandler(void)2512 void I2S6_DriverIRQHandler(void)
2513 {
2514 #if defined(FSL_FEATURE_SAI_HAS_FIFO) && (FSL_FEATURE_SAI_HAS_FIFO)
2515     if ((s_saiHandle[6][1] != NULL) && SAI_RxGetEnabledInterruptStatus(I2S6, (I2S_TCSR_FRIE_MASK | I2S_TCSR_FEIE_MASK),
2516                                                                        (I2S_TCSR_FRF_MASK | I2S_TCSR_FEF_MASK)))
2517 #else
2518     if ((s_saiHandle[6][1] != NULL) && SAI_RxGetEnabledInterruptStatus(I2S6, (I2S_TCSR_FWIE_MASK | I2S_TCSR_FEIE_MASK),
2519                                                                        (I2S_TCSR_FWF_MASK | I2S_TCSR_FEF_MASK)))
2520 #endif
2521     {
2522         s_saiRxIsr(I2S6, s_saiHandle[6][1]);
2523     }
2524 #if defined(FSL_FEATURE_SAI_HAS_FIFO) && (FSL_FEATURE_SAI_HAS_FIFO)
2525     if ((s_saiHandle[6][0] != NULL) && SAI_TxGetEnabledInterruptStatus(I2S6, (I2S_TCSR_FRIE_MASK | I2S_TCSR_FEIE_MASK),
2526                                                                        (I2S_TCSR_FRF_MASK | I2S_TCSR_FEF_MASK)))
2527 #else
2528     if ((s_saiHandle[6][0] != NULL) && SAI_TxGetEnabledInterruptStatus(I2S6, (I2S_TCSR_FWIE_MASK | I2S_TCSR_FEIE_MASK),
2529                                                                        (I2S_TCSR_FWF_MASK | I2S_TCSR_FEF_MASK)))
2530 #endif
2531     {
2532         s_saiTxIsr(I2S6, s_saiHandle[6][0]);
2533     }
2534     SDK_ISR_EXIT_BARRIER;
2535 }
2536 
2537 void I2S6_Tx_DriverIRQHandler(void);
I2S6_Tx_DriverIRQHandler(void)2538 void I2S6_Tx_DriverIRQHandler(void)
2539 {
2540     assert(s_saiHandle[6][0] != NULL);
2541     s_saiTxIsr(I2S6, s_saiHandle[6][0]);
2542     SDK_ISR_EXIT_BARRIER;
2543 }
2544 
2545 void I2S6_Rx_DriverIRQHandler(void);
I2S6_Rx_DriverIRQHandler(void)2546 void I2S6_Rx_DriverIRQHandler(void)
2547 {
2548     assert(s_saiHandle[6][1] != NULL);
2549     s_saiRxIsr(I2S6, s_saiHandle[6][1]);
2550     SDK_ISR_EXIT_BARRIER;
2551 }
2552 #endif
2553 #endif
2554 
2555 #if defined(AUDIO__SAI0)
2556 void AUDIO_SAI0_INT_DriverIRQHandler(void);
AUDIO_SAI0_INT_DriverIRQHandler(void)2557 void AUDIO_SAI0_INT_DriverIRQHandler(void)
2558 {
2559 #if defined(FSL_FEATURE_SAI_HAS_FIFO) && (FSL_FEATURE_SAI_HAS_FIFO)
2560     if ((s_saiHandle[0][1] != NULL) &&
2561         SAI_RxGetEnabledInterruptStatus(AUDIO__SAI0, (I2S_TCSR_FRIE_MASK | I2S_TCSR_FEIE_MASK),
2562                                         (I2S_TCSR_FRF_MASK | I2S_TCSR_FEF_MASK)))
2563 #else
2564     if ((s_saiHandle[0][1] != NULL) &&
2565         SAI_RxGetEnabledInterruptStatus(AUDIO__SAI0, (I2S_TCSR_FWIE_MASK | I2S_TCSR_FEIE_MASK),
2566                                         (I2S_TCSR_FWF_MASK | I2S_TCSR_FEF_MASK)))
2567 #endif
2568     {
2569         s_saiRxIsr(AUDIO__SAI0, s_saiHandle[0][1]);
2570     }
2571 
2572 #if defined(FSL_FEATURE_SAI_HAS_FIFO) && (FSL_FEATURE_SAI_HAS_FIFO)
2573     if ((s_saiHandle[0][0] != NULL) &&
2574         SAI_TxGetEnabledInterruptStatus(AUDIO__SAI0, (I2S_TCSR_FRIE_MASK | I2S_TCSR_FEIE_MASK),
2575                                         (I2S_TCSR_FRF_MASK | I2S_TCSR_FEF_MASK)))
2576 #else
2577     if ((s_saiHandle[0][0] != NULL) &&
2578         SAI_TxGetEnabledInterruptStatus(AUDIO__SAI0, (I2S_TCSR_FWIE_MASK | I2S_TCSR_FEIE_MASK),
2579                                         (I2S_TCSR_FWF_MASK | I2S_TCSR_FEF_MASK)))
2580 #endif
2581     {
2582         s_saiTxIsr(AUDIO__SAI0, s_saiHandle[0][0]);
2583     }
2584     SDK_ISR_EXIT_BARRIER;
2585 }
2586 #endif /* AUDIO__SAI0 */
2587 
2588 #if defined(AUDIO__SAI1)
2589 void AUDIO_SAI1_INT_DriverIRQHandler(void);
AUDIO_SAI1_INT_DriverIRQHandler(void)2590 void AUDIO_SAI1_INT_DriverIRQHandler(void)
2591 {
2592 #if defined(FSL_FEATURE_SAI_HAS_FIFO) && (FSL_FEATURE_SAI_HAS_FIFO)
2593     if ((s_saiHandle[1][1] != NULL) &&
2594         SAI_RxGetEnabledInterruptStatus(AUDIO__SAI1, (I2S_TCSR_FRIE_MASK | I2S_TCSR_FEIE_MASK),
2595                                         (I2S_TCSR_FRF_MASK | I2S_TCSR_FEF_MASK)))
2596 #else
2597     if ((s_saiHandle[1][1] != NULL) &&
2598         SAI_RxGetEnabledInterruptStatus(AUDIO__SAI1, (I2S_TCSR_FWIE_MASK | I2S_TCSR_FEIE_MASK),
2599                                         (I2S_TCSR_FWF_MASK | I2S_TCSR_FEF_MASK)))
2600 #endif
2601     {
2602         s_saiRxIsr(AUDIO__SAI1, s_saiHandle[1][1]);
2603     }
2604 #if defined(FSL_FEATURE_SAI_HAS_FIFO) && (FSL_FEATURE_SAI_HAS_FIFO)
2605     if ((s_saiHandle[1][0] != NULL) &&
2606         SAI_TxGetEnabledInterruptStatus(AUDIO__SAI1, (I2S_TCSR_FRIE_MASK | I2S_TCSR_FEIE_MASK),
2607                                         (I2S_TCSR_FRF_MASK | I2S_TCSR_FEF_MASK)))
2608 #else
2609     if ((s_saiHandle[1][0] != NULL) &&
2610         SAI_TxGetEnabledInterruptStatus(AUDIO__SAI1, (I2S_TCSR_FWIE_MASK | I2S_TCSR_FEIE_MASK),
2611                                         (I2S_TCSR_FWF_MASK | I2S_TCSR_FEF_MASK)))
2612 #endif
2613     {
2614         s_saiTxIsr(AUDIO__SAI1, s_saiHandle[1][0]);
2615     }
2616     SDK_ISR_EXIT_BARRIER;
2617 }
2618 #endif /* AUDIO__SAI1 */
2619 
2620 #if defined(AUDIO__SAI2)
2621 void AUDIO_SAI2_INT_DriverIRQHandler(void);
AUDIO_SAI2_INT_DriverIRQHandler(void)2622 void AUDIO_SAI2_INT_DriverIRQHandler(void)
2623 {
2624 #if defined(FSL_FEATURE_SAI_HAS_FIFO) && (FSL_FEATURE_SAI_HAS_FIFO)
2625     if ((s_saiHandle[2][1] != NULL) &&
2626         SAI_RxGetEnabledInterruptStatus(AUDIO__SAI2, (I2S_TCSR_FRIE_MASK | I2S_TCSR_FEIE_MASK),
2627                                         (I2S_TCSR_FRF_MASK | I2S_TCSR_FEF_MASK)))
2628 #else
2629     if ((s_saiHandle[2][1] != NULL) &&
2630         SAI_RxGetEnabledInterruptStatus(AUDIO__SAI2, (I2S_TCSR_FWIE_MASK | I2S_TCSR_FEIE_MASK),
2631                                         (I2S_TCSR_FWF_MASK | I2S_TCSR_FEF_MASK)))
2632 #endif
2633     {
2634         s_saiRxIsr(AUDIO__SAI2, s_saiHandle[2][1]);
2635     }
2636 #if defined(FSL_FEATURE_SAI_HAS_FIFO) && (FSL_FEATURE_SAI_HAS_FIFO)
2637     if ((s_saiHandle[2][0] != NULL) &&
2638         SAI_TxGetEnabledInterruptStatus(AUDIO__SAI2, (I2S_TCSR_FRIE_MASK | I2S_TCSR_FEIE_MASK),
2639                                         (I2S_TCSR_FRF_MASK | I2S_TCSR_FEF_MASK)))
2640 #else
2641     if ((s_saiHandle[2][0] != NULL) &&
2642         SAI_TxGetEnabledInterruptStatus(AUDIO__SAI2, (I2S_TCSR_FWIE_MASK | I2S_TCSR_FEIE_MASK),
2643                                         (I2S_TCSR_FWF_MASK | I2S_TCSR_FEF_MASK)))
2644 #endif
2645     {
2646         s_saiTxIsr(AUDIO__SAI2, s_saiHandle[2][0]);
2647     }
2648     SDK_ISR_EXIT_BARRIER;
2649 }
2650 #endif /* AUDIO__SAI2 */
2651 
2652 #if defined(AUDIO__SAI3)
2653 void AUDIO_SAI3_INT_DriverIRQHandler(void);
AUDIO_SAI3_INT_DriverIRQHandler(void)2654 void AUDIO_SAI3_INT_DriverIRQHandler(void)
2655 {
2656 #if defined(FSL_FEATURE_SAI_HAS_FIFO) && (FSL_FEATURE_SAI_HAS_FIFO)
2657     if ((s_saiHandle[3][1] != NULL) &&
2658         SAI_RxGetEnabledInterruptStatus(AUDIO__SAI3, (I2S_TCSR_FRIE_MASK | I2S_TCSR_FEIE_MASK),
2659                                         (I2S_TCSR_FRF_MASK | I2S_TCSR_FEF_MASK)))
2660 #else
2661     if ((s_saiHandle[3][1] != NULL) &&
2662         SAI_RxGetEnabledInterruptStatus(AUDIO__SAI3, (I2S_TCSR_FWIE_MASK | I2S_TCSR_FEIE_MASK),
2663                                         (I2S_TCSR_FWF_MASK | I2S_TCSR_FEF_MASK)))
2664 #endif
2665     {
2666         s_saiRxIsr(AUDIO__SAI3, s_saiHandle[3][1]);
2667     }
2668 #if defined(FSL_FEATURE_SAI_HAS_FIFO) && (FSL_FEATURE_SAI_HAS_FIFO)
2669     if ((s_saiHandle[3][0] != NULL) &&
2670         SAI_TxGetEnabledInterruptStatus(AUDIO__SAI3, (I2S_TCSR_FRIE_MASK | I2S_TCSR_FEIE_MASK),
2671                                         (I2S_TCSR_FRF_MASK | I2S_TCSR_FEF_MASK)))
2672 #else
2673     if ((s_saiHandle[3][0] != NULL) &&
2674         SAI_TxGetEnabledInterruptStatus(AUDIO__SAI3, (I2S_TCSR_FWIE_MASK | I2S_TCSR_FEIE_MASK),
2675                                         (I2S_TCSR_FWF_MASK | I2S_TCSR_FEF_MASK)))
2676 #endif
2677     {
2678         s_saiTxIsr(AUDIO__SAI3, s_saiHandle[3][0]);
2679     }
2680     SDK_ISR_EXIT_BARRIER;
2681 }
2682 #endif
2683 
2684 #if defined(AUDIO__SAI6)
2685 void AUDIO_SAI6_INT_DriverIRQHandler(void);
AUDIO_SAI6_INT_DriverIRQHandler(void)2686 void AUDIO_SAI6_INT_DriverIRQHandler(void)
2687 {
2688 #if defined(FSL_FEATURE_SAI_HAS_FIFO) && (FSL_FEATURE_SAI_HAS_FIFO)
2689     if ((s_saiHandle[6][1] != NULL) &&
2690         SAI_RxGetEnabledInterruptStatus(AUDIO__SAI6, (I2S_TCSR_FRIE_MASK | I2S_TCSR_FEIE_MASK),
2691                                         (I2S_TCSR_FRF_MASK | I2S_TCSR_FEF_MASK)))
2692 #else
2693     if ((s_saiHandle[6][1] != NULL) &&
2694         SAI_RxGetEnabledInterruptStatus(AUDIO__SAI6, (I2S_TCSR_FWIE_MASK | I2S_TCSR_FEIE_MASK),
2695                                         (I2S_TCSR_FWF_MASK | I2S_TCSR_FEF_MASK)))
2696 #endif
2697     {
2698         s_saiRxIsr(AUDIO__SAI6, s_saiHandle[6][1]);
2699     }
2700 #if defined(FSL_FEATURE_SAI_HAS_FIFO) && (FSL_FEATURE_SAI_HAS_FIFO)
2701     if ((s_saiHandle[6][0] != NULL) &&
2702         SAI_TxGetEnabledInterruptStatus(AUDIO__SAI6, (I2S_TCSR_FRIE_MASK | I2S_TCSR_FEIE_MASK),
2703                                         (I2S_TCSR_FRF_MASK | I2S_TCSR_FEF_MASK)))
2704 #else
2705     if ((s_saiHandle[6][0] != NULL) &&
2706         SAI_TxGetEnabledInterruptStatus(AUDIO__SAI6, (I2S_TCSR_FWIE_MASK | I2S_TCSR_FEIE_MASK),
2707                                         (I2S_TCSR_FWF_MASK | I2S_TCSR_FEF_MASK)))
2708 #endif
2709     {
2710         s_saiTxIsr(AUDIO__SAI6, s_saiHandle[6][0]);
2711     }
2712     SDK_ISR_EXIT_BARRIER;
2713 }
2714 #endif /* AUDIO__SAI6 */
2715 
2716 #if defined(AUDIO__SAI7)
2717 void AUDIO_SAI7_INT_DriverIRQHandler(void);
AUDIO_SAI7_INT_DriverIRQHandler(void)2718 void AUDIO_SAI7_INT_DriverIRQHandler(void)
2719 {
2720 #if defined(FSL_FEATURE_SAI_HAS_FIFO) && (FSL_FEATURE_SAI_HAS_FIFO)
2721     if ((s_saiHandle[7][1] != NULL) &&
2722         SAI_RxGetEnabledInterruptStatus(AUDIO__SAI7, (I2S_TCSR_FRIE_MASK | I2S_TCSR_FEIE_MASK),
2723                                         (I2S_TCSR_FRF_MASK | I2S_TCSR_FEF_MASK)))
2724 #else
2725     if ((s_saiHandle[7][1] != NULL) &&
2726         SAI_RxGetEnabledInterruptStatus(AUDIO__SAI7, (I2S_TCSR_FWIE_MASK | I2S_TCSR_FEIE_MASK),
2727                                         (I2S_TCSR_FWF_MASK | I2S_TCSR_FEF_MASK)))
2728 #endif
2729     {
2730         s_saiRxIsr(AUDIO__SAI7, s_saiHandle[7][1]);
2731     }
2732 #if defined(FSL_FEATURE_SAI_HAS_FIFO) && (FSL_FEATURE_SAI_HAS_FIFO)
2733     if ((s_saiHandle[7][0] != NULL) &&
2734         SAI_TxGetEnabledInterruptStatus(AUDIO__SAI7, (I2S_TCSR_FRIE_MASK | I2S_TCSR_FEIE_MASK),
2735                                         (I2S_TCSR_FRF_MASK | I2S_TCSR_FEF_MASK)))
2736 #else
2737     if ((s_saiHandle[7][0] != NULL) &&
2738         SAI_TxGetEnabledInterruptStatus(AUDIO__SAI7, (I2S_TCSR_FWIE_MASK | I2S_TCSR_FEIE_MASK),
2739                                         (I2S_TCSR_FWF_MASK | I2S_TCSR_FEF_MASK)))
2740 #endif
2741     {
2742         s_saiTxIsr(AUDIO__SAI7, s_saiHandle[7][0]);
2743     }
2744     SDK_ISR_EXIT_BARRIER;
2745 }
2746 #endif /* AUDIO__SAI7 */
2747 
2748 #if defined(ADMA__SAI0)
2749 void ADMA_SAI0_INT_DriverIRQHandler(void);
ADMA_SAI0_INT_DriverIRQHandler(void)2750 void ADMA_SAI0_INT_DriverIRQHandler(void)
2751 {
2752 #if defined(FSL_FEATURE_SAI_HAS_FIFO) && (FSL_FEATURE_SAI_HAS_FIFO)
2753     if ((s_saiHandle[1][1] != NULL) &&
2754         SAI_RxGetEnabledInterruptStatus(ADMA__SAI0, (I2S_TCSR_FRIE_MASK | I2S_TCSR_FEIE_MASK),
2755                                         (I2S_TCSR_FRF_MASK | I2S_TCSR_FEF_MASK)))
2756 #else
2757     if ((s_saiHandle[1][1] != NULL) &&
2758         SAI_RxGetEnabledInterruptStatus(ADMA__SAI0, (I2S_TCSR_FWIE_MASK | I2S_TCSR_FEIE_MASK),
2759                                         (I2S_TCSR_FWF_MASK | I2S_TCSR_FEF_MASK)))
2760 #endif
2761     {
2762         s_saiRxIsr(ADMA__SAI0, s_saiHandle[1][1]);
2763     }
2764 #if defined(FSL_FEATURE_SAI_HAS_FIFO) && (FSL_FEATURE_SAI_HAS_FIFO)
2765     if ((s_saiHandle[1][0] != NULL) &&
2766         SAI_TxGetEnabledInterruptStatus(ADMA__SAI0, (I2S_TCSR_FRIE_MASK | I2S_TCSR_FEIE_MASK),
2767                                         (I2S_TCSR_FRF_MASK | I2S_TCSR_FEF_MASK)))
2768 #else
2769     if ((s_saiHandle[1][0] != NULL) &&
2770         SAI_TxGetEnabledInterruptStatus(ADMA__SAI0, (I2S_TCSR_FWIE_MASK | I2S_TCSR_FEIE_MASK),
2771                                         (I2S_TCSR_FWF_MASK | I2S_TCSR_FEF_MASK)))
2772 #endif
2773     {
2774         s_saiTxIsr(ADMA__SAI0, s_saiHandle[1][0]);
2775     }
2776     SDK_ISR_EXIT_BARRIER;
2777 }
2778 #endif /* ADMA__SAI0 */
2779 
2780 #if defined(ADMA__SAI1)
2781 void ADMA_SAI1_INT_DriverIRQHandler(void);
ADMA_SAI1_INT_DriverIRQHandler(void)2782 void ADMA_SAI1_INT_DriverIRQHandler(void)
2783 {
2784 #if defined(FSL_FEATURE_SAI_HAS_FIFO) && (FSL_FEATURE_SAI_HAS_FIFO)
2785     if ((s_saiHandle[1][1] != NULL) &&
2786         SAI_RxGetEnabledInterruptStatus(ADMA__SAI1, (I2S_TCSR_FRIE_MASK | I2S_TCSR_FEIE_MASK),
2787                                         (I2S_TCSR_FRF_MASK | I2S_TCSR_FEF_MASK)))
2788 #else
2789     if ((s_saiHandle[1][1] != NULL) &&
2790         SAI_RxGetEnabledInterruptStatus(ADMA__SAI1, (I2S_TCSR_FWIE_MASK | I2S_TCSR_FEIE_MASK),
2791                                         (I2S_TCSR_FWF_MASK | I2S_TCSR_FEF_MASK)))
2792 #endif
2793     {
2794         s_saiRxIsr(ADMA__SAI1, s_saiHandle[1][1]);
2795     }
2796 #if defined(FSL_FEATURE_SAI_HAS_FIFO) && (FSL_FEATURE_SAI_HAS_FIFO)
2797     if ((s_saiHandle[1][0] != NULL) &&
2798         SAI_TxGetEnabledInterruptStatus(ADMA__SAI1, (I2S_TCSR_FRIE_MASK | I2S_TCSR_FEIE_MASK),
2799                                         (I2S_TCSR_FRF_MASK | I2S_TCSR_FEF_MASK)))
2800 #else
2801     if ((s_saiHandle[1][0] != NULL) &&
2802         SAI_TxGetEnabledInterruptStatus(ADMA__SAI1, (I2S_TCSR_FWIE_MASK | I2S_TCSR_FEIE_MASK),
2803                                         (I2S_TCSR_FWF_MASK | I2S_TCSR_FEF_MASK)))
2804 #endif
2805     {
2806         s_saiTxIsr(ADMA__SAI1, s_saiHandle[1][0]);
2807     }
2808     SDK_ISR_EXIT_BARRIER;
2809 }
2810 #endif /* ADMA__SAI1 */
2811 
2812 #if defined(ADMA__SAI2)
2813 void ADMA_SAI2_INT_DriverIRQHandler(void);
ADMA_SAI2_INT_DriverIRQHandler(void)2814 void ADMA_SAI2_INT_DriverIRQHandler(void)
2815 {
2816 #if defined(FSL_FEATURE_SAI_HAS_FIFO) && (FSL_FEATURE_SAI_HAS_FIFO)
2817     if ((s_saiHandle[1][1] != NULL) &&
2818         SAI_RxGetEnabledInterruptStatus(ADMA__SAI2, (I2S_TCSR_FRIE_MASK | I2S_TCSR_FEIE_MASK),
2819                                         (I2S_TCSR_FRF_MASK | I2S_TCSR_FEF_MASK)))
2820 #else
2821     if ((s_saiHandle[1][1] != NULL) &&
2822         SAI_RxGetEnabledInterruptStatus(ADMA__SAI2, (I2S_TCSR_FWIE_MASK | I2S_TCSR_FEIE_MASK),
2823                                         (I2S_TCSR_FWF_MASK | I2S_TCSR_FEF_MASK)))
2824 #endif
2825     {
2826         s_saiRxIsr(ADMA__SAI2, s_saiHandle[1][1]);
2827     }
2828 #if defined(FSL_FEATURE_SAI_HAS_FIFO) && (FSL_FEATURE_SAI_HAS_FIFO)
2829     if ((s_saiHandle[1][0] != NULL) &&
2830         SAI_TxGetEnabledInterruptStatus(ADMA__SAI2, (I2S_TCSR_FRIE_MASK | I2S_TCSR_FEIE_MASK),
2831                                         (I2S_TCSR_FRF_MASK | I2S_TCSR_FEF_MASK)))
2832 #else
2833     if ((s_saiHandle[1][0] != NULL) &&
2834         SAI_TxGetEnabledInterruptStatus(ADMA__SAI2, (I2S_TCSR_FWIE_MASK | I2S_TCSR_FEIE_MASK),
2835                                         (I2S_TCSR_FWF_MASK | I2S_TCSR_FEF_MASK)))
2836 #endif
2837     {
2838         s_saiTxIsr(ADMA__SAI2, s_saiHandle[1][0]);
2839     }
2840     SDK_ISR_EXIT_BARRIER;
2841 }
2842 #endif /* ADMA__SAI2 */
2843 
2844 #if defined(ADMA__SAI3)
2845 void ADMA_SAI3_INT_DriverIRQHandler(void);
ADMA_SAI3_INT_DriverIRQHandler(void)2846 void ADMA_SAI3_INT_DriverIRQHandler(void)
2847 {
2848 #if defined(FSL_FEATURE_SAI_HAS_FIFO) && (FSL_FEATURE_SAI_HAS_FIFO)
2849     if ((s_saiHandle[1][1] != NULL) &&
2850         SAI_RxGetEnabledInterruptStatus(ADMA__SAI3, (I2S_TCSR_FRIE_MASK | I2S_TCSR_FEIE_MASK),
2851                                         (I2S_TCSR_FRF_MASK | I2S_TCSR_FEF_MASK)))
2852 #else
2853     if ((s_saiHandle[1][1] != NULL) &&
2854         SAI_RxGetEnabledInterruptStatus(ADMA__SAI3, (I2S_TCSR_FWIE_MASK | I2S_TCSR_FEIE_MASK),
2855                                         (I2S_TCSR_FWF_MASK | I2S_TCSR_FEF_MASK)))
2856 #endif
2857     {
2858         s_saiRxIsr(ADMA__SAI3, s_saiHandle[1][1]);
2859     }
2860 #if defined(FSL_FEATURE_SAI_HAS_FIFO) && (FSL_FEATURE_SAI_HAS_FIFO)
2861     if ((s_saiHandle[1][0] != NULL) &&
2862         SAI_TxGetEnabledInterruptStatus(ADMA__SAI3, (I2S_TCSR_FRIE_MASK | I2S_TCSR_FEIE_MASK),
2863                                         (I2S_TCSR_FRF_MASK | I2S_TCSR_FEF_MASK)))
2864 #else
2865     if ((s_saiHandle[1][0] != NULL) &&
2866         SAI_TxGetEnabledInterruptStatus(ADMA__SAI3, (I2S_TCSR_FWIE_MASK | I2S_TCSR_FEIE_MASK),
2867                                         (I2S_TCSR_FWF_MASK | I2S_TCSR_FEF_MASK)))
2868 #endif
2869     {
2870         s_saiTxIsr(ADMA__SAI3, s_saiHandle[1][0]);
2871     }
2872     SDK_ISR_EXIT_BARRIER;
2873 }
2874 #endif /* ADMA__SAI3 */
2875 
2876 #if defined(ADMA__SAI4)
2877 void ADMA_SAI4_INT_DriverIRQHandler(void);
ADMA_SAI4_INT_DriverIRQHandler(void)2878 void ADMA_SAI4_INT_DriverIRQHandler(void)
2879 {
2880 #if defined(FSL_FEATURE_SAI_HAS_FIFO) && (FSL_FEATURE_SAI_HAS_FIFO)
2881     if ((s_saiHandle[1][1] != NULL) &&
2882         SAI_RxGetEnabledInterruptStatus(ADMA__SAI4, (I2S_TCSR_FRIE_MASK | I2S_TCSR_FEIE_MASK),
2883                                         (I2S_TCSR_FRF_MASK | I2S_TCSR_FEF_MASK)))
2884 #else
2885     if ((s_saiHandle[1][1] != NULL) &&
2886         SAI_RxGetEnabledInterruptStatus(ADMA__SAI4, (I2S_TCSR_FWIE_MASK | I2S_TCSR_FEIE_MASK),
2887                                         (I2S_TCSR_FWF_MASK | I2S_TCSR_FEF_MASK)))
2888 #endif
2889     {
2890         s_saiRxIsr(ADMA__SAI4, s_saiHandle[1][1]);
2891     }
2892 
2893 #if defined(FSL_FEATURE_SAI_HAS_FIFO) && (FSL_FEATURE_SAI_HAS_FIFO)
2894     if ((s_saiHandle[1][0] != NULL) &&
2895         SAI_TxGetEnabledInterruptStatus(ADMA__SAI4, (I2S_TCSR_FRIE_MASK | I2S_TCSR_FEIE_MASK),
2896                                         (I2S_TCSR_FRF_MASK | I2S_TCSR_FEF_MASK)))
2897 #else
2898     if ((s_saiHandle[1][0] != NULL) &&
2899         SAI_TxGetEnabledInterruptStatus(ADMA__SAI4, (I2S_TCSR_FWIE_MASK | I2S_TCSR_FEIE_MASK),
2900                                         (I2S_TCSR_FWF_MASK | I2S_TCSR_FEF_MASK)))
2901 #endif
2902     {
2903         s_saiTxIsr(ADMA__SAI4, s_saiHandle[1][0]);
2904     }
2905     SDK_ISR_EXIT_BARRIER;
2906 }
2907 #endif /* ADMA__SAI4 */
2908 
2909 #if defined(ADMA__SAI5)
2910 void ADMA_SAI5_INT_DriverIRQHandler(void);
ADMA_SAI5_INT_DriverIRQHandler(void)2911 void ADMA_SAI5_INT_DriverIRQHandler(void)
2912 {
2913 #if defined(FSL_FEATURE_SAI_HAS_FIFO) && (FSL_FEATURE_SAI_HAS_FIFO)
2914     if ((s_saiHandle[1][1] != NULL) &&
2915         SAI_RxGetEnabledInterruptStatus(ADMA__SAI5, (I2S_TCSR_FRIE_MASK | I2S_TCSR_FEIE_MASK),
2916                                         (I2S_TCSR_FRF_MASK | I2S_TCSR_FEF_MASK)))
2917 #else
2918     if ((s_saiHandle[1][1] != NULL) &&
2919         SAI_RxGetEnabledInterruptStatus(ADMA__SAI5, (I2S_TCSR_FWIE_MASK | I2S_TCSR_FEIE_MASK),
2920                                         (I2S_TCSR_FWF_MASK | I2S_TCSR_FEF_MASK)))
2921 #endif
2922     {
2923         s_saiRxIsr(ADMA__SAI5, s_saiHandle[1][1]);
2924     }
2925 #if defined(FSL_FEATURE_SAI_HAS_FIFO) && (FSL_FEATURE_SAI_HAS_FIFO)
2926     if ((s_saiHandle[1][0] != NULL) &&
2927         SAI_TxGetEnabledInterruptStatus(ADMA__SAI5, (I2S_TCSR_FRIE_MASK | I2S_TCSR_FEIE_MASK),
2928                                         (I2S_TCSR_FRF_MASK | I2S_TCSR_FEF_MASK)))
2929 #else
2930     if ((s_saiHandle[1][0] != NULL) &&
2931         SAI_TxGetEnabledInterruptStatus(ADMA__SAI5, (I2S_TCSR_FWIE_MASK | I2S_TCSR_FEIE_MASK),
2932                                         (I2S_TCSR_FWF_MASK | I2S_TCSR_FEF_MASK)))
2933 #endif
2934     {
2935         s_saiTxIsr(ADMA__SAI5, s_saiHandle[1][0]);
2936     }
2937     SDK_ISR_EXIT_BARRIER;
2938 }
2939 #endif /* ADMA__SAI5 */
2940 
2941 #if defined(SAI0)
2942 void SAI0_DriverIRQHandler(void);
SAI0_DriverIRQHandler(void)2943 void SAI0_DriverIRQHandler(void)
2944 {
2945 #if defined(FSL_FEATURE_SAI_HAS_FIFO) && (FSL_FEATURE_SAI_HAS_FIFO)
2946     if ((s_saiHandle[0][1] != NULL) && SAI_RxGetEnabledInterruptStatus(SAI0, (I2S_TCSR_FRIE_MASK | I2S_TCSR_FEIE_MASK),
2947                                                                        (I2S_TCSR_FRF_MASK | I2S_TCSR_FEF_MASK)))
2948 #else
2949     if ((s_saiHandle[0][1] != NULL) && SAI_RxGetEnabledInterruptStatus(SAI0, (I2S_TCSR_FWIE_MASK | I2S_TCSR_FEIE_MASK),
2950                                                                        (I2S_TCSR_FWF_MASK | I2S_TCSR_FEF_MASK)))
2951 #endif
2952     {
2953         s_saiRxIsr(SAI0, s_saiHandle[0][1]);
2954     }
2955 #if defined(FSL_FEATURE_SAI_HAS_FIFO) && (FSL_FEATURE_SAI_HAS_FIFO)
2956     if ((s_saiHandle[0][0] != NULL) && SAI_TxGetEnabledInterruptStatus(SAI0, (I2S_TCSR_FRIE_MASK | I2S_TCSR_FEIE_MASK),
2957                                                                        (I2S_TCSR_FRF_MASK | I2S_TCSR_FEF_MASK)))
2958 #else
2959     if ((s_saiHandle[0][0] != NULL) && SAI_TxGetEnabledInterruptStatus(SAI0, (I2S_TCSR_FWIE_MASK | I2S_TCSR_FEIE_MASK),
2960                                                                        (I2S_TCSR_FWF_MASK | I2S_TCSR_FEF_MASK)))
2961 #endif
2962     {
2963         s_saiTxIsr(SAI0, s_saiHandle[0][0]);
2964     }
2965     SDK_ISR_EXIT_BARRIER;
2966 }
2967 #endif /* SAI0 */
2968 
2969 #if defined(SAI1)
2970 void SAI1_DriverIRQHandler(void);
SAI1_DriverIRQHandler(void)2971 void SAI1_DriverIRQHandler(void)
2972 {
2973 #if defined(FSL_FEATURE_SAI_HAS_FIFO) && (FSL_FEATURE_SAI_HAS_FIFO)
2974     if ((s_saiHandle[1][1] != NULL) && SAI_RxGetEnabledInterruptStatus(SAI1, (I2S_TCSR_FRIE_MASK | I2S_TCSR_FEIE_MASK),
2975                                                                        (I2S_TCSR_FRF_MASK | I2S_TCSR_FEF_MASK)))
2976 #else
2977     if ((s_saiHandle[1][1] != NULL) && SAI_RxGetEnabledInterruptStatus(SAI1, (I2S_TCSR_FWIE_MASK | I2S_TCSR_FEIE_MASK),
2978                                                                        (I2S_TCSR_FWF_MASK | I2S_TCSR_FEF_MASK)))
2979 #endif
2980     {
2981         s_saiRxIsr(SAI1, s_saiHandle[1][1]);
2982     }
2983 #if defined(FSL_FEATURE_SAI_HAS_FIFO) && (FSL_FEATURE_SAI_HAS_FIFO)
2984     if ((s_saiHandle[1][0] != NULL) && SAI_TxGetEnabledInterruptStatus(SAI1, (I2S_TCSR_FRIE_MASK | I2S_TCSR_FEIE_MASK),
2985                                                                        (I2S_TCSR_FRF_MASK | I2S_TCSR_FEF_MASK)))
2986 #else
2987     if ((s_saiHandle[1][0] != NULL) && SAI_TxGetEnabledInterruptStatus(SAI1, (I2S_TCSR_FWIE_MASK | I2S_TCSR_FEIE_MASK),
2988                                                                        (I2S_TCSR_FWF_MASK | I2S_TCSR_FEF_MASK)))
2989 #endif
2990     {
2991         s_saiTxIsr(SAI1, s_saiHandle[1][0]);
2992     }
2993     SDK_ISR_EXIT_BARRIER;
2994 }
2995 #endif /* SAI1 */
2996 
2997 #if defined(SAI2)
2998 void SAI2_DriverIRQHandler(void);
SAI2_DriverIRQHandler(void)2999 void SAI2_DriverIRQHandler(void)
3000 {
3001 #if defined(FSL_FEATURE_SAI_HAS_FIFO) && (FSL_FEATURE_SAI_HAS_FIFO)
3002     if ((s_saiHandle[2][1] != NULL) && SAI_RxGetEnabledInterruptStatus(SAI2, (I2S_TCSR_FRIE_MASK | I2S_TCSR_FEIE_MASK),
3003                                                                        (I2S_TCSR_FRF_MASK | I2S_TCSR_FEF_MASK)))
3004 #else
3005     if ((s_saiHandle[2][1] != NULL) && SAI_RxGetEnabledInterruptStatus(SAI2, (I2S_TCSR_FWIE_MASK | I2S_TCSR_FEIE_MASK),
3006                                                                        (I2S_TCSR_FWF_MASK | I2S_TCSR_FEF_MASK)))
3007 #endif
3008     {
3009         s_saiRxIsr(SAI2, s_saiHandle[2][1]);
3010     }
3011 #if defined(FSL_FEATURE_SAI_HAS_FIFO) && (FSL_FEATURE_SAI_HAS_FIFO)
3012     if ((s_saiHandle[2][0] != NULL) && SAI_TxGetEnabledInterruptStatus(SAI2, (I2S_TCSR_FRIE_MASK | I2S_TCSR_FEIE_MASK),
3013                                                                        (I2S_TCSR_FRF_MASK | I2S_TCSR_FEF_MASK)))
3014 #else
3015     if ((s_saiHandle[2][0] != NULL) && SAI_TxGetEnabledInterruptStatus(SAI2, (I2S_TCSR_FWIE_MASK | I2S_TCSR_FEIE_MASK),
3016                                                                        (I2S_TCSR_FWF_MASK | I2S_TCSR_FEF_MASK)))
3017 #endif
3018     {
3019         s_saiTxIsr(SAI2, s_saiHandle[2][0]);
3020     }
3021     SDK_ISR_EXIT_BARRIER;
3022 }
3023 #endif /* SAI2 */
3024 
3025 #if defined(SAI3)
3026 void SAI3_DriverIRQHandler(void);
SAI3_DriverIRQHandler(void)3027 void SAI3_DriverIRQHandler(void)
3028 {
3029 #if defined(FSL_FEATURE_SAI_HAS_FIFO) && (FSL_FEATURE_SAI_HAS_FIFO)
3030     if ((s_saiHandle[3][1] != NULL) && SAI_RxGetEnabledInterruptStatus(SAI3, (I2S_TCSR_FRIE_MASK | I2S_TCSR_FEIE_MASK),
3031                                                                        (I2S_TCSR_FRF_MASK | I2S_TCSR_FEF_MASK)))
3032 #else
3033     if ((s_saiHandle[3][1] != NULL) && SAI_RxGetEnabledInterruptStatus(SAI3, (I2S_TCSR_FWIE_MASK | I2S_TCSR_FEIE_MASK),
3034                                                                        (I2S_TCSR_FWF_MASK | I2S_TCSR_FEF_MASK)))
3035 #endif
3036     {
3037         s_saiRxIsr(SAI3, s_saiHandle[3][1]);
3038     }
3039 #if defined(FSL_FEATURE_SAI_HAS_FIFO) && (FSL_FEATURE_SAI_HAS_FIFO)
3040     if ((s_saiHandle[3][0] != NULL) && SAI_TxGetEnabledInterruptStatus(SAI3, (I2S_TCSR_FRIE_MASK | I2S_TCSR_FEIE_MASK),
3041                                                                        (I2S_TCSR_FRF_MASK | I2S_TCSR_FEF_MASK)))
3042 #else
3043     if ((s_saiHandle[3][0] != NULL) && SAI_TxGetEnabledInterruptStatus(SAI3, (I2S_TCSR_FWIE_MASK | I2S_TCSR_FEIE_MASK),
3044                                                                        (I2S_TCSR_FWF_MASK | I2S_TCSR_FEF_MASK)))
3045 #endif
3046     {
3047         s_saiTxIsr(SAI3, s_saiHandle[3][0]);
3048     }
3049     SDK_ISR_EXIT_BARRIER;
3050 }
3051 
3052 void SAI3_TX_DriverIRQHandler(void);
SAI3_TX_DriverIRQHandler(void)3053 void SAI3_TX_DriverIRQHandler(void)
3054 {
3055     assert(s_saiHandle[3][0] != NULL);
3056     s_saiTxIsr(SAI3, s_saiHandle[3][0]);
3057     SDK_ISR_EXIT_BARRIER;
3058 }
3059 
3060 void SAI3_RX_DriverIRQHandler(void);
SAI3_RX_DriverIRQHandler(void)3061 void SAI3_RX_DriverIRQHandler(void)
3062 {
3063     assert(s_saiHandle[3][1] != NULL);
3064     s_saiRxIsr(SAI3, s_saiHandle[3][1]);
3065     SDK_ISR_EXIT_BARRIER;
3066 }
3067 #endif /* SAI3 */
3068 
3069 #if defined(SAI4)
3070 void SAI4_DriverIRQHandler(void);
SAI4_DriverIRQHandler(void)3071 void SAI4_DriverIRQHandler(void)
3072 {
3073 #if defined(FSL_FEATURE_SAI_HAS_FIFO) && (FSL_FEATURE_SAI_HAS_FIFO)
3074     if ((s_saiHandle[4][1] != NULL) && SAI_RxGetEnabledInterruptStatus(SAI4, (I2S_TCSR_FRIE_MASK | I2S_TCSR_FEIE_MASK),
3075                                                                        (I2S_TCSR_FRF_MASK | I2S_TCSR_FEF_MASK)))
3076 #else
3077     if ((s_saiHandle[4][1] != NULL) && SAI_RxGetEnabledInterruptStatus(SAI4, (I2S_TCSR_FWIE_MASK | I2S_TCSR_FEIE_MASK),
3078                                                                        (I2S_TCSR_FWF_MASK | I2S_TCSR_FEF_MASK)))
3079 #endif
3080     {
3081         s_saiRxIsr(SAI4, s_saiHandle[4][1]);
3082     }
3083 #if defined(FSL_FEATURE_SAI_HAS_FIFO) && (FSL_FEATURE_SAI_HAS_FIFO)
3084     if ((s_saiHandle[4][0] != NULL) && SAI_TxGetEnabledInterruptStatus(SAI4, (I2S_TCSR_FRIE_MASK | I2S_TCSR_FEIE_MASK),
3085                                                                        (I2S_TCSR_FRF_MASK | I2S_TCSR_FEF_MASK)))
3086 #else
3087     if ((s_saiHandle[4][0] != NULL) && SAI_TxGetEnabledInterruptStatus(SAI4, (I2S_TCSR_FWIE_MASK | I2S_TCSR_FEIE_MASK),
3088                                                                        (I2S_TCSR_FWF_MASK | I2S_TCSR_FEF_MASK)))
3089 #endif
3090     {
3091         s_saiTxIsr(SAI4, s_saiHandle[4][0]);
3092     }
3093     SDK_ISR_EXIT_BARRIER;
3094 }
3095 #endif /* SAI4 */
3096 
3097 #if defined(SAI5)
3098 void SAI5_DriverIRQHandler(void);
SAI5_DriverIRQHandler(void)3099 void SAI5_DriverIRQHandler(void)
3100 {
3101 #if defined(FSL_FEATURE_SAI_HAS_FIFO) && (FSL_FEATURE_SAI_HAS_FIFO)
3102     if ((s_saiHandle[5][1] != NULL) && SAI_RxGetEnabledInterruptStatus(SAI5, (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(SAI5, (I2S_TCSR_FWIE_MASK | I2S_TCSR_FEIE_MASK),
3106                                                                        (I2S_TCSR_FWF_MASK | I2S_TCSR_FEF_MASK)))
3107 #endif
3108     {
3109         s_saiRxIsr(SAI5, s_saiHandle[5][1]);
3110     }
3111 #if defined(FSL_FEATURE_SAI_HAS_FIFO) && (FSL_FEATURE_SAI_HAS_FIFO)
3112     if ((s_saiHandle[5][0] != NULL) && SAI_TxGetEnabledInterruptStatus(SAI5, (I2S_TCSR_FRIE_MASK | I2S_TCSR_FEIE_MASK),
3113                                                                        (I2S_TCSR_FRF_MASK | I2S_TCSR_FEF_MASK)))
3114 #else
3115     if ((s_saiHandle[5][0] != NULL) && SAI_TxGetEnabledInterruptStatus(SAI5, (I2S_TCSR_FWIE_MASK | I2S_TCSR_FEIE_MASK),
3116                                                                        (I2S_TCSR_FWF_MASK | I2S_TCSR_FEF_MASK)))
3117 #endif
3118     {
3119         s_saiTxIsr(SAI5, s_saiHandle[5][0]);
3120     }
3121     SDK_ISR_EXIT_BARRIER;
3122 }
3123 #endif /* SAI5 */
3124 
3125 #if defined(SAI6)
3126 void SAI6_DriverIRQHandler(void);
SAI6_DriverIRQHandler(void)3127 void SAI6_DriverIRQHandler(void)
3128 {
3129 #if defined(FSL_FEATURE_SAI_HAS_FIFO) && (FSL_FEATURE_SAI_HAS_FIFO)
3130     if ((s_saiHandle[6][1] != NULL) && SAI_RxGetEnabledInterruptStatus(SAI6, (I2S_TCSR_FRIE_MASK | I2S_TCSR_FEIE_MASK),
3131                                                                        (I2S_TCSR_FRF_MASK | I2S_TCSR_FEF_MASK)))
3132 #else
3133     if ((s_saiHandle[6][1] != NULL) && SAI_RxGetEnabledInterruptStatus(SAI6, (I2S_TCSR_FWIE_MASK | I2S_TCSR_FEIE_MASK),
3134                                                                        (I2S_TCSR_FWF_MASK | I2S_TCSR_FEF_MASK)))
3135 #endif
3136     {
3137         s_saiRxIsr(SAI6, s_saiHandle[6][1]);
3138     }
3139 #if defined(FSL_FEATURE_SAI_HAS_FIFO) && (FSL_FEATURE_SAI_HAS_FIFO)
3140     if ((s_saiHandle[6][0] != NULL) && SAI_TxGetEnabledInterruptStatus(SAI6, (I2S_TCSR_FRIE_MASK | I2S_TCSR_FEIE_MASK),
3141                                                                        (I2S_TCSR_FRF_MASK | I2S_TCSR_FEF_MASK)))
3142 #else
3143     if ((s_saiHandle[6][0] != NULL) && SAI_TxGetEnabledInterruptStatus(SAI6, (I2S_TCSR_FWIE_MASK | I2S_TCSR_FEIE_MASK),
3144                                                                        (I2S_TCSR_FWF_MASK | I2S_TCSR_FEF_MASK)))
3145 #endif
3146     {
3147         s_saiTxIsr(SAI6, s_saiHandle[6][0]);
3148     }
3149     SDK_ISR_EXIT_BARRIER;
3150 }
3151 #endif /* SAI6 */
3152