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