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