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