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