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