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