fsl_sai.c
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2016, Freescale Semiconductor, Inc.
3  * Copyright 2016-2020 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  ******************************************************************************/
20 enum
21 {
22  kSAI_Busy = 0x0U,
23  kSAI_Idle,
25 };
26 
28 typedef void (*sai_tx_isr_t)(I2S_Type *base, sai_handle_t *saiHandle);
29 
31 typedef void (*sai_rx_isr_t)(I2S_Type *base, sai_handle_t *saiHandle);
32 
34 #define IS_SAI_FLAG_SET(reg, flag) (((reg) & ((uint32_t)flag)) != 0UL)
35 /*******************************************************************************
36  * Prototypes
37  ******************************************************************************/
46 static bool SAI_RxGetEnabledInterruptStatus(I2S_Type *base, uint32_t enableFlag, uint32_t statusFlag);
47 
56 static bool SAI_TxGetEnabledInterruptStatus(I2S_Type *base, uint32_t enableFlag, uint32_t statusFlag);
57 
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 
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 
91 static uint32_t SAI_GetInstance(I2S_Type *base);
92 
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 
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 
140  sai_word_width_t bitWidth,
141  sai_mono_stereo_t mode,
142  uint32_t saiChannelMask);
143 /*******************************************************************************
144  * Variables
145  ******************************************************************************/
146 /* Base pointer array */
150 /* IRQ number array */
153 #if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
154 /* Clock name array */
156 #endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */
157 
161 
162 /*******************************************************************************
163  * Code
164  ******************************************************************************/
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 
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)))
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 
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 
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 
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 
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 */
353 
354  /* master mode default */
356 
357  /* bit default configurations */
358  config->bitClock.bclkSrcSwap = false;
359  config->bitClock.bclkInputDelay = false;
362 
363  /* frame sync default configurations */
364  config->frameSync.frameSyncWidth = (uint8_t)bitWidth;
366 #if defined(FSL_FEATURE_SAI_HAS_FRAME_SYNC_ON_DEMAND) && FSL_FEATURE_SAI_HAS_FRAME_SYNC_ON_DEMAND
367  config->frameSync.frameSyncGenerateOnDemand = false;
368 #endif
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
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;
381  config->serialData.dataMaskedWord = (uint32_t)mode;
382 
383 #if defined(FSL_FEATURE_SAI_FIFO_COUNT) && (FSL_FEATURE_SAI_FIFO_COUNT > 1)
384  /* fifo configurations */
385  config->fifo.fifoWatermark = (uint8_t)((uint32_t)FSL_FEATURE_SAI_FIFO_COUNT / 2U);
386 #endif
387 
388 #if defined(FSL_FEATURE_SAI_HAS_FIFO_FUNCTION_AFTER_ERROR) && FSL_FEATURE_SAI_HAS_FIFO_FUNCTION_AFTER_ERROR
389  config->fifo.fifoContinueOneError = true;
390 #endif
391 }
392 
410 {
411  uint32_t val = 0;
412 
413 #if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
414  /* Enable the SAI clock */
416 #endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */
417 
418 #if defined(FSL_FEATURE_SAI_HAS_MCR) && (FSL_FEATURE_SAI_HAS_MCR)
419 #if !(defined(FSL_FEATURE_SAI_HAS_NO_MCR_MICS) && (FSL_FEATURE_SAI_HAS_NO_MCR_MICS))
420  /* Master clock source setting */
421  val = (base->MCR & ~I2S_MCR_MICS_MASK);
422  base->MCR = (val | I2S_MCR_MICS(config->mclkSource));
423 #endif
424 
425  /* Configure Master clock output enable */
426  val = (base->MCR & ~I2S_MCR_MOE_MASK);
427  base->MCR = (val | I2S_MCR_MOE(config->mclkOutputEnable));
428 #endif /* FSL_FEATURE_SAI_HAS_MCR */
429 
430  SAI_TxReset(base);
431 
432  /* Configure audio protocol */
433  if (config->protocol == kSAI_BusLeftJustified)
434  {
435  base->TCR2 |= I2S_TCR2_BCP_MASK;
436  base->TCR3 &= ~I2S_TCR3_WDFL_MASK;
437  base->TCR4 = I2S_TCR4_MF(1U) | I2S_TCR4_SYWD(31U) | I2S_TCR4_FSE(0U) | I2S_TCR4_FSP(0U) | I2S_TCR4_FRSZ(1U);
438  }
439  else if (config->protocol == kSAI_BusRightJustified)
440  {
441  base->TCR2 |= I2S_TCR2_BCP_MASK;
442  base->TCR3 &= ~I2S_TCR3_WDFL_MASK;
443  base->TCR4 = I2S_TCR4_MF(1U) | I2S_TCR4_SYWD(31U) | I2S_TCR4_FSE(0U) | I2S_TCR4_FSP(0U) | I2S_TCR4_FRSZ(1U);
444  }
445  else if (config->protocol == kSAI_BusI2S)
446  {
447  base->TCR2 |= I2S_TCR2_BCP_MASK;
448  base->TCR3 &= ~I2S_TCR3_WDFL_MASK;
449  base->TCR4 = I2S_TCR4_MF(1U) | I2S_TCR4_SYWD(31U) | I2S_TCR4_FSE(1U) | I2S_TCR4_FSP(1U) | I2S_TCR4_FRSZ(1U);
450  }
451  else if (config->protocol == kSAI_BusPCMA)
452  {
453  base->TCR2 &= ~I2S_TCR2_BCP_MASK;
454  base->TCR3 &= ~I2S_TCR3_WDFL_MASK;
455  base->TCR4 = I2S_TCR4_MF(1U) | I2S_TCR4_SYWD(0U) | I2S_TCR4_FSE(1U) | I2S_TCR4_FSP(0U) | I2S_TCR4_FRSZ(1U);
456  }
457  else
458  {
459  base->TCR2 &= ~I2S_TCR2_BCP_MASK;
460  base->TCR3 &= ~I2S_TCR3_WDFL_MASK;
461  base->TCR4 = I2S_TCR4_MF(1U) | I2S_TCR4_SYWD(0U) | I2S_TCR4_FSE(0U) | I2S_TCR4_FSP(0U) | I2S_TCR4_FRSZ(1U);
462  }
463 
464  /* Set master or slave */
466  {
467  base->TCR2 |= I2S_TCR2_BCD_MASK;
468  base->TCR4 |= I2S_TCR4_FSD_MASK;
469 
470  /* Bit clock source setting */
471  val = base->TCR2 & (~I2S_TCR2_MSEL_MASK);
472  base->TCR2 = (val | I2S_TCR2_MSEL(config->bclkSource));
473  }
474  else
475  {
476  base->TCR2 &= ~I2S_TCR2_BCD_MASK;
477  base->TCR4 &= ~I2S_TCR4_FSD_MASK;
478  }
479 
480  /* Set Sync mode */
482  {
483  val = base->TCR2;
484  val &= ~I2S_TCR2_SYNC_MASK;
485  base->TCR2 = (val | I2S_TCR2_SYNC(0U));
486  }
487  if (config->syncMode == kSAI_ModeSync)
488  {
489  val = base->TCR2;
490  val &= ~I2S_TCR2_SYNC_MASK;
491  base->TCR2 = (val | I2S_TCR2_SYNC(1U));
492  /* If sync with Rx, should set Rx to async mode */
493  val = base->RCR2;
494  val &= ~I2S_RCR2_SYNC_MASK;
495  base->RCR2 = (val | I2S_RCR2_SYNC(0U));
496  }
497 #if defined(FSL_FEATURE_SAI_HAS_SYNC_WITH_ANOTHER_SAI) && (FSL_FEATURE_SAI_HAS_SYNC_WITH_ANOTHER_SAI)
498  if (config->syncMode == kSAI_ModeSyncWithOtherTx)
499  {
500  val = base->TCR2;
501  val &= ~I2S_TCR2_SYNC_MASK;
502  base->TCR2 = (val | I2S_TCR2_SYNC(2U));
503  }
504  if (config->syncMode == kSAI_ModeSyncWithOtherRx)
505  {
506  val = base->TCR2;
507  val &= ~I2S_TCR2_SYNC_MASK;
508  base->TCR2 = (val | I2S_TCR2_SYNC(3U));
509  }
510 #endif /* FSL_FEATURE_SAI_HAS_SYNC_WITH_ANOTHER_SAI */
511 
512 #if defined(FSL_FEATURE_SAI_HAS_FIFO_FUNCTION_AFTER_ERROR) && FSL_FEATURE_SAI_HAS_FIFO_FUNCTION_AFTER_ERROR
513  SAI_TxSetFIFOErrorContinue(base, true);
514 #endif /* FSL_FEATURE_SAI_HAS_FIFO_FUNCTION_AFTER_ERROR */
515 }
516 
534 {
535  uint32_t val = 0;
536 
537 #if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
538  /* Enable SAI clock first. */
540 #endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */
541 
542 #if defined(FSL_FEATURE_SAI_HAS_MCR) && (FSL_FEATURE_SAI_HAS_MCR)
543 #if !(defined(FSL_FEATURE_SAI_HAS_NO_MCR_MICS) && (FSL_FEATURE_SAI_HAS_NO_MCR_MICS))
544  /* Master clock source setting */
545  val = (base->MCR & ~I2S_MCR_MICS_MASK);
546  base->MCR = (val | I2S_MCR_MICS(config->mclkSource));
547 #endif
548 
549  /* Configure Master clock output enable */
550  val = (base->MCR & ~I2S_MCR_MOE_MASK);
551  base->MCR = (val | I2S_MCR_MOE(config->mclkOutputEnable));
552 #endif /* FSL_FEATURE_SAI_HAS_MCR */
553 
554  SAI_RxReset(base);
555 
556  /* Configure audio protocol */
557  if (config->protocol == kSAI_BusLeftJustified)
558  {
559  base->RCR2 |= I2S_RCR2_BCP_MASK;
560  base->RCR3 &= ~I2S_RCR3_WDFL_MASK;
561  base->RCR4 = I2S_RCR4_MF(1U) | I2S_RCR4_SYWD(31U) | I2S_RCR4_FSE(0U) | I2S_RCR4_FSP(0U) | I2S_RCR4_FRSZ(1U);
562  }
563  else if (config->protocol == kSAI_BusRightJustified)
564  {
565  base->RCR2 |= I2S_RCR2_BCP_MASK;
566  base->RCR3 &= ~I2S_RCR3_WDFL_MASK;
567  base->RCR4 = I2S_RCR4_MF(1U) | I2S_RCR4_SYWD(31U) | I2S_RCR4_FSE(0U) | I2S_RCR4_FSP(0U) | I2S_RCR4_FRSZ(1U);
568  }
569  else if (config->protocol == kSAI_BusI2S)
570  {
571  base->RCR2 |= I2S_RCR2_BCP_MASK;
572  base->RCR3 &= ~I2S_RCR3_WDFL_MASK;
573  base->RCR4 = I2S_RCR4_MF(1U) | I2S_RCR4_SYWD(31U) | I2S_RCR4_FSE(1U) | I2S_RCR4_FSP(1U) | I2S_RCR4_FRSZ(1U);
574  }
575  else if (config->protocol == kSAI_BusPCMA)
576  {
577  base->RCR2 &= ~I2S_RCR2_BCP_MASK;
578  base->RCR3 &= ~I2S_RCR3_WDFL_MASK;
579  base->RCR4 = I2S_RCR4_MF(1U) | I2S_RCR4_SYWD(0U) | I2S_RCR4_FSE(1U) | I2S_RCR4_FSP(0U) | I2S_RCR4_FRSZ(1U);
580  }
581  else
582  {
583  base->RCR2 &= ~I2S_RCR2_BCP_MASK;
584  base->RCR3 &= ~I2S_RCR3_WDFL_MASK;
585  base->RCR4 = I2S_RCR4_MF(1U) | I2S_RCR4_SYWD(0U) | I2S_RCR4_FSE(0U) | I2S_RCR4_FSP(0U) | I2S_RCR4_FRSZ(1U);
586  }
587 
588  /* Set master or slave */
590  {
591  base->RCR2 |= I2S_RCR2_BCD_MASK;
592  base->RCR4 |= I2S_RCR4_FSD_MASK;
593 
594  /* Bit clock source setting */
595  val = base->RCR2 & (~I2S_RCR2_MSEL_MASK);
596  base->RCR2 = (val | I2S_RCR2_MSEL(config->bclkSource));
597  }
598  else
599  {
600  base->RCR2 &= ~I2S_RCR2_BCD_MASK;
601  base->RCR4 &= ~I2S_RCR4_FSD_MASK;
602  }
603 
604  /* Set Sync mode */
606  {
607  val = base->RCR2;
608  val &= ~I2S_RCR2_SYNC_MASK;
609  base->RCR2 = (val | I2S_RCR2_SYNC(0U));
610  }
611  if (config->syncMode == kSAI_ModeSync)
612  {
613  val = base->RCR2;
614  val &= ~I2S_RCR2_SYNC_MASK;
615  base->RCR2 = (val | I2S_RCR2_SYNC(1U));
616  /* If sync with Tx, should set Tx to async mode */
617  val = base->TCR2;
618  val &= ~I2S_TCR2_SYNC_MASK;
619  base->TCR2 = (val | I2S_TCR2_SYNC(0U));
620  }
621 #if defined(FSL_FEATURE_SAI_HAS_SYNC_WITH_ANOTHER_SAI) && (FSL_FEATURE_SAI_HAS_SYNC_WITH_ANOTHER_SAI)
622  if (config->syncMode == kSAI_ModeSyncWithOtherTx)
623  {
624  val = base->RCR2;
625  val &= ~I2S_RCR2_SYNC_MASK;
626  base->RCR2 = (val | I2S_RCR2_SYNC(2U));
627  }
628  if (config->syncMode == kSAI_ModeSyncWithOtherRx)
629  {
630  val = base->RCR2;
631  val &= ~I2S_RCR2_SYNC_MASK;
632  base->RCR2 = (val | I2S_RCR2_SYNC(3U));
633  }
634 #endif /* FSL_FEATURE_SAI_HAS_SYNC_WITH_ANOTHER_SAI */
635 
636 #if defined(FSL_FEATURE_SAI_HAS_FIFO_FUNCTION_AFTER_ERROR) && FSL_FEATURE_SAI_HAS_FIFO_FUNCTION_AFTER_ERROR
637  SAI_RxSetFIFOErrorContinue(base, true);
638 #endif /* FSL_FEATURE_SAI_HAS_FIFO_FUNCTION_AFTER_ERROR */
639 }
640 
648 void SAI_Init(I2S_Type *base)
649 {
650 #if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
651  /* Enable the SAI clock */
653 #endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */
654 
655 #if defined(FSL_FEATURE_SAI_FIFO_COUNT) && (FSL_FEATURE_SAI_FIFO_COUNT > 1)
656  /* disable interrupt and DMA request*/
657  base->TCSR &=
659  base->RCSR &=
661 #else
662  /* disable interrupt and DMA request*/
665 #endif
666 }
667 
676 void SAI_Deinit(I2S_Type *base)
677 {
678  SAI_TxEnable(base, false);
679  SAI_RxEnable(base, false);
680 #if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
682 #endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */
683 }
684 
703 {
704  /* Initializes the configure structure to zero. */
705  (void)memset(config, 0, sizeof(*config));
706 
707  config->bclkSource = kSAI_BclkSourceMclkDiv;
709 #if defined(FSL_FEATURE_SAI_HAS_MCR) && (FSL_FEATURE_SAI_HAS_MCR)
710  config->mclkOutputEnable = true;
711 #if !(defined(FSL_FEATURE_SAI_HAS_NO_MCR_MICS) && (FSL_FEATURE_SAI_HAS_NO_MCR_MICS))
712  config->mclkSource = kSAI_MclkSourceSysclk;
713 #endif
714 #endif /* FSL_FEATURE_SAI_HAS_MCR */
715  config->protocol = kSAI_BusI2S;
717 }
718 
737 {
738  /* Initializes the configure structure to zero. */
739  (void)memset(config, 0, sizeof(*config));
740 
741  config->bclkSource = kSAI_BclkSourceMclkDiv;
743 #if defined(FSL_FEATURE_SAI_HAS_MCR) && (FSL_FEATURE_SAI_HAS_MCR)
744  config->mclkOutputEnable = true;
745 #if !(defined(FSL_FEATURE_SAI_HAS_NO_MCR_MICS) && (FSL_FEATURE_SAI_HAS_NO_MCR_MICS))
746  config->mclkSource = kSAI_MclkSourceSysclk;
747 #endif
748 #endif /* FSL_FEATURE_SAI_HAS_MCR */
749  config->protocol = kSAI_BusI2S;
751 }
752 
761 {
762  /* Set the software reset and FIFO reset to clear internal state */
764 
765  /* Clear software reset bit, this should be done by software */
766  base->TCSR &= ~I2S_TCSR_SR_MASK;
767 
768  /* Reset all Tx register values */
769  base->TCR2 = 0;
770  base->TCR3 = 0;
771  base->TCR4 = 0;
772  base->TCR5 = 0;
773  base->TMR = 0;
774 }
775 
784 {
785  /* Set the software reset and FIFO reset to clear internal state */
787 
788  /* Clear software reset bit, this should be done by software */
789  base->RCSR &= ~I2S_RCSR_SR_MASK;
790 
791  /* Reset all Rx register values */
792  base->RCR2 = 0;
793  base->RCR3 = 0;
794  base->RCR4 = 0;
795  base->RCR5 = 0;
796  base->RMR = 0;
797 }
798 
805 void SAI_TxEnable(I2S_Type *base, bool enable)
806 {
807  if (enable)
808  {
809  /* If clock is sync with Rx, should enable RE bit. */
810  if (((base->TCR2 & I2S_TCR2_SYNC_MASK) >> I2S_TCR2_SYNC_SHIFT) == 0x1U)
811  {
812  base->RCSR = ((base->RCSR & 0xFFE3FFFFU) | I2S_RCSR_RE_MASK);
813  }
814  base->TCSR = ((base->TCSR & 0xFFE3FFFFU) | I2S_TCSR_TE_MASK);
815  /* Also need to clear the FIFO error flag before start */
817  }
818  else
819  {
820  /* If Rx not in sync with Tx, then disable Tx, otherwise, shall not disable Tx */
821  if (((base->RCR2 & I2S_RCR2_SYNC_MASK) >> I2S_RCR2_SYNC_SHIFT) != 0x1U)
822  {
823  /* Disable TE bit */
824  base->TCSR = ((base->TCSR & 0xFFE3FFFFU) & (~I2S_TCSR_TE_MASK));
825  }
826  }
827 }
828 
835 void SAI_RxEnable(I2S_Type *base, bool enable)
836 {
837  if (enable)
838  {
839  /* If clock is sync with Tx, should enable TE bit. */
840  if (((base->RCR2 & I2S_RCR2_SYNC_MASK) >> I2S_RCR2_SYNC_SHIFT) == 0x1U)
841  {
842  base->TCSR = ((base->TCSR & 0xFFE3FFFFU) | I2S_TCSR_TE_MASK);
843  }
844  base->RCSR = ((base->RCSR & 0xFFE3FFFFU) | I2S_RCSR_RE_MASK);
845  /* Also need to clear the FIFO error flag before start */
847  }
848  else
849  {
850  /* If Tx not in sync with Rx, then disable Rx, otherwise, shall not disable Rx */
851  if (((base->TCR2 & I2S_TCR2_SYNC_MASK) >> I2S_TCR2_SYNC_SHIFT) != 0x1U)
852  {
853  /* Disable RE bit */
854  base->RCSR = ((base->RCSR & 0xFFE3FFFFU) & (~I2S_RCSR_RE_MASK));
855  }
856  }
857 }
858 
871 {
872  base->TCSR |= (uint32_t)type;
873 
874  /* Clear the software reset */
875  base->TCSR &= ~I2S_TCSR_SR_MASK;
876 }
877 
890 {
891  base->RCSR |= (uint32_t)type;
892 
893  /* Clear the software reset */
894  base->RCSR &= ~I2S_RCSR_SR_MASK;
895 }
896 
904 void SAI_TxSetChannelFIFOMask(I2S_Type *base, uint8_t mask)
905 {
906  base->TCR3 &= ~I2S_TCR3_TCE_MASK;
907  base->TCR3 |= I2S_TCR3_TCE(mask);
908 }
909 
917 void SAI_RxSetChannelFIFOMask(I2S_Type *base, uint8_t mask)
918 {
919  base->RCR3 &= ~I2S_RCR3_RCE_MASK;
920  base->RCR3 |= I2S_RCR3_RCE(mask);
921 }
922 
930 {
931  uint32_t val = (base->TCR4) & (~I2S_TCR4_MF_MASK);
932 
933  val |= I2S_TCR4_MF(order);
934  base->TCR4 = val;
935 }
936 
944 {
945  uint32_t val = (base->RCR4) & (~I2S_RCR4_MF_MASK);
946 
947  val |= I2S_RCR4_MF(order);
948  base->RCR4 = val;
949 }
950 
958 {
959  uint32_t val = (base->TCR2) & (~I2S_TCR2_BCP_MASK);
960 
961  val |= I2S_TCR2_BCP(polarity);
962  base->TCR2 = val;
963 }
964 
972 {
973  uint32_t val = (base->RCR2) & (~I2S_RCR2_BCP_MASK);
974 
975  val |= I2S_RCR2_BCP(polarity);
976  base->RCR2 = val;
977 }
978 
986 {
987  uint32_t val = (base->TCR4) & (~I2S_TCR4_FSP_MASK);
988 
989  val |= I2S_TCR4_FSP(polarity);
990  base->TCR4 = val;
991 }
992 
1000 {
1001  uint32_t val = (base->RCR4) & (~I2S_RCR4_FSP_MASK);
1002 
1003  val |= I2S_RCR4_FSP(polarity);
1004  base->RCR4 = val;
1005 }
1006 
1007 #if defined(FSL_FEATURE_SAI_HAS_FIFO_PACKING) && FSL_FEATURE_SAI_HAS_FIFO_PACKING
1008 
1014 void SAI_TxSetFIFOPacking(I2S_Type *base, sai_fifo_packing_t pack)
1015 {
1016  uint32_t val = base->TCR4;
1017 
1018  val &= ~I2S_TCR4_FPACK_MASK;
1019  val |= I2S_TCR4_FPACK(pack);
1020  base->TCR4 = val;
1021 }
1022 
1029 void SAI_RxSetFIFOPacking(I2S_Type *base, sai_fifo_packing_t pack)
1030 {
1031  uint32_t val = base->RCR4;
1032 
1033  val &= ~I2S_RCR4_FPACK_MASK;
1034  val |= I2S_RCR4_FPACK(pack);
1035  base->RCR4 = val;
1036 }
1037 #endif /* FSL_FEATURE_SAI_HAS_FIFO_PACKING */
1038 
1049  I2S_Type *base, uint32_t sourceClockHz, uint32_t sampleRate, uint32_t bitWidth, uint32_t channelNumbers)
1050 {
1051  uint32_t tcr2 = base->TCR2;
1052  uint32_t bitClockDiv = 0;
1053  uint32_t bitClockFreq = sampleRate * bitWidth * channelNumbers;
1054 
1055  assert(sourceClockHz >= bitClockFreq);
1056 
1057  tcr2 &= ~I2S_TCR2_DIV_MASK;
1058  /* need to check the divided bclk, if bigger than target, then divider need to re-calculate. */
1059  bitClockDiv = sourceClockHz / bitClockFreq;
1060  /* for the condition where the source clock is smaller than target bclk */
1061  if (bitClockDiv == 0U)
1062  {
1063  bitClockDiv++;
1064  }
1065  /* recheck the divider if properly or not, to make sure output blck not bigger than target*/
1066  if ((sourceClockHz / bitClockDiv) > bitClockFreq)
1067  {
1068  bitClockDiv++;
1069  }
1070 
1071 #if defined(FSL_FEATURE_SAI_HAS_BCLK_BYPASS) && (FSL_FEATURE_SAI_HAS_BCLK_BYPASS)
1072  /* if bclk same with MCLK, bypass the divider */
1073  if (bitClockDiv == 1U)
1074  {
1075  tcr2 |= I2S_TCR2_BYP_MASK;
1076  }
1077  else
1078 #endif
1079  {
1080  tcr2 |= I2S_TCR2_DIV(bitClockDiv / 2U - 1UL);
1081  }
1082 
1083  base->TCR2 = tcr2;
1084 }
1085 
1096  I2S_Type *base, uint32_t sourceClockHz, uint32_t sampleRate, uint32_t bitWidth, uint32_t channelNumbers)
1097 {
1098  uint32_t rcr2 = base->RCR2;
1099  uint32_t bitClockDiv = 0;
1100  uint32_t bitClockFreq = sampleRate * bitWidth * channelNumbers;
1101 
1102  assert(sourceClockHz >= bitClockFreq);
1103 
1104  rcr2 &= ~I2S_RCR2_DIV_MASK;
1105  /* need to check the divided bclk, if bigger than target, then divider need to re-calculate. */
1106  bitClockDiv = sourceClockHz / bitClockFreq;
1107  /* for the condition where the source clock is smaller than target bclk */
1108  if (bitClockDiv == 0U)
1109  {
1110  bitClockDiv++;
1111  }
1112  /* recheck the divider if properly or not, to make sure output blck not bigger than target*/
1113  if ((sourceClockHz / bitClockDiv) > bitClockFreq)
1114  {
1115  bitClockDiv++;
1116  }
1117 
1118 #if defined(FSL_FEATURE_SAI_HAS_BCLK_BYPASS) && (FSL_FEATURE_SAI_HAS_BCLK_BYPASS)
1119  /* if bclk same with MCLK, bypass the divider */
1120  if (bitClockDiv == 1U)
1121  {
1122  rcr2 |= I2S_RCR2_BYP_MASK;
1123  }
1124  else
1125 #endif
1126  {
1127  rcr2 |= I2S_RCR2_DIV(bitClockDiv / 2U - 1UL);
1128  }
1129 
1130  base->RCR2 = rcr2;
1131 }
1132 
1141 {
1142  uint32_t tcr2 = base->TCR2;
1143 
1144  if ((masterSlave == kSAI_Master) || (masterSlave == kSAI_Bclk_Master_FrameSync_Slave))
1145  {
1146  assert(config != NULL);
1147 
1149  tcr2 |= I2S_TCR2_BCD(1U) | I2S_TCR2_BCP(config->bclkPolarity) | I2S_TCR2_BCI(config->bclkInputDelay) |
1150  I2S_TCR2_BCS(config->bclkSrcSwap) | I2S_TCR2_MSEL(config->bclkSource);
1151  }
1152  else
1153  {
1154  tcr2 &= ~(I2S_TCR2_BCD_MASK);
1155  }
1156 
1157  base->TCR2 = tcr2;
1158 }
1159 
1168 {
1169  uint32_t rcr2 = base->RCR2;
1170 
1171  if ((masterSlave == kSAI_Master) || (masterSlave == kSAI_Bclk_Master_FrameSync_Slave))
1172  {
1173  assert(config != NULL);
1174 
1176  rcr2 |= I2S_RCR2_BCD(1U) | I2S_RCR2_BCP(config->bclkPolarity) | I2S_RCR2_BCI(config->bclkInputDelay) |
1177  I2S_RCR2_BCS(config->bclkSrcSwap) | I2S_RCR2_MSEL(config->bclkSource);
1178  }
1179  else
1180  {
1181  rcr2 &= ~(I2S_RCR2_BCD_MASK);
1182  }
1183 
1184  base->RCR2 = rcr2;
1185 }
1186 
1187 #if (defined(FSL_FEATURE_SAI_HAS_MCR) && (FSL_FEATURE_SAI_HAS_MCR)) || \
1188  (defined(FSL_FEATURE_SAI_HAS_MCLKDIV_REGISTER) && (FSL_FEATURE_SAI_HAS_MCLKDIV_REGISTER))
1189 
1195 void SAI_SetMasterClockConfig(I2S_Type *base, sai_master_clock_t *config)
1196 {
1197  assert(config != NULL);
1198 
1199 #if defined(FSL_FEATURE_SAI_HAS_MCR) && (FSL_FEATURE_SAI_HAS_MCR)
1200  uint32_t val = 0;
1201 #if !(defined(FSL_FEATURE_SAI_HAS_NO_MCR_MICS) && (FSL_FEATURE_SAI_HAS_NO_MCR_MICS))
1202  /* Master clock source setting */
1203  val = (base->MCR & ~I2S_MCR_MICS_MASK);
1204  base->MCR = (val | I2S_MCR_MICS(config->mclkSource));
1205 #endif
1206 
1207  /* Configure Master clock output enable */
1208  val = (base->MCR & ~I2S_MCR_MOE_MASK);
1209  base->MCR = (val | I2S_MCR_MOE(config->mclkOutputEnable));
1210 #endif /* FSL_FEATURE_SAI_HAS_MCR */
1211 
1212 #if ((defined(FSL_FEATURE_SAI_HAS_MCLKDIV_REGISTER) && (FSL_FEATURE_SAI_HAS_MCLKDIV_REGISTER)) || \
1213  (defined(FSL_FEATURE_SAI_HAS_MCR_MCLK_POST_DIV) && (FSL_FEATURE_SAI_HAS_MCR_MCLK_POST_DIV)))
1214  /* Check if master clock divider enabled, then set master clock divider */
1215  if (config->mclkOutputEnable)
1216  {
1217  SAI_SetMasterClockDivider(base, config->mclkHz, config->mclkSourceClkHz);
1218  }
1219 #endif /* FSL_FEATURE_SAI_HAS_MCLKDIV_REGISTER */
1220 }
1221 #endif
1222 
1223 #if FSL_SAI_HAS_FIFO_EXTEND_FEATURE
1224 
1230 void SAI_TxSetFifoConfig(I2S_Type *base, sai_fifo_t *config)
1231 {
1232  assert(config != NULL);
1233 #if defined(FSL_FEATURE_SAI_FIFO_COUNT) && (FSL_FEATURE_SAI_FIFO_COUNT > 1)
1234  assert(config->fifoWatermark <= (I2S_TCR1_TFW_MASK >> I2S_TCR1_TFW_SHIFT));
1235 #endif
1236 
1237  uint32_t tcr4 = base->TCR4;
1238 
1239 #if defined(FSL_FEATURE_SAI_HAS_FIFO_FUNCTION_COMBINE) && FSL_FEATURE_SAI_HAS_FIFO_FUNCTION_COMBINE
1240  tcr4 &= ~I2S_TCR4_FCOMB_MASK;
1241  tcr4 |= I2S_TCR4_FCOMB(config->fifoCombine);
1242 #endif
1243 
1244 #if defined(FSL_FEATURE_SAI_HAS_FIFO_FUNCTION_AFTER_ERROR) && FSL_FEATURE_SAI_HAS_FIFO_FUNCTION_AFTER_ERROR
1245  tcr4 &= ~I2S_TCR4_FCONT_MASK;
1246  /* ERR05144: not set FCONT = 1 when TMR > 0, the transmit shift register may not load correctly that will cause TX
1247  * not work */
1248  if (base->TMR == 0U)
1249  {
1250  tcr4 |= I2S_TCR4_FCONT(config->fifoContinueOneError);
1251  }
1252 #endif
1253 
1254 #if defined(FSL_FEATURE_SAI_HAS_FIFO_PACKING) && FSL_FEATURE_SAI_HAS_FIFO_PACKING
1255  tcr4 &= ~I2S_TCR4_FPACK_MASK;
1256  tcr4 |= I2S_TCR4_FPACK(config->fifoPacking);
1257 #endif
1258 
1259  base->TCR4 = tcr4;
1260 
1261 #if defined(FSL_FEATURE_SAI_FIFO_COUNT) && (FSL_FEATURE_SAI_FIFO_COUNT > 1)
1262  base->TCR1 = (base->TCR1 & (~I2S_TCR1_TFW_MASK)) | I2S_TCR1_TFW(config->fifoWatermark);
1263 #endif
1264 }
1265 
1272 void SAI_RxSetFifoConfig(I2S_Type *base, sai_fifo_t *config)
1273 {
1274  assert(config != NULL);
1275 #if defined(FSL_FEATURE_SAI_FIFO_COUNT) && (FSL_FEATURE_SAI_FIFO_COUNT > 1)
1276  assert(config->fifoWatermark <= (I2S_TCR1_TFW_MASK >> I2S_TCR1_TFW_SHIFT));
1277 #endif
1278  uint32_t rcr4 = base->RCR4;
1279 
1280 #if defined(FSL_FEATURE_SAI_HAS_FIFO_FUNCTION_COMBINE) && FSL_FEATURE_SAI_HAS_FIFO_FUNCTION_COMBINE
1281  rcr4 &= ~I2S_RCR4_FCOMB_MASK;
1282  rcr4 |= I2S_RCR4_FCOMB(config->fifoCombine);
1283 #endif
1284 
1285 #if defined(FSL_FEATURE_SAI_HAS_FIFO_FUNCTION_AFTER_ERROR) && FSL_FEATURE_SAI_HAS_FIFO_FUNCTION_AFTER_ERROR
1286  rcr4 &= ~I2S_RCR4_FCONT_MASK;
1287  rcr4 |= I2S_RCR4_FCONT(config->fifoContinueOneError);
1288 #endif
1289 
1290 #if defined(FSL_FEATURE_SAI_HAS_FIFO_PACKING) && FSL_FEATURE_SAI_HAS_FIFO_PACKING
1291  rcr4 &= ~I2S_RCR4_FPACK_MASK;
1292  rcr4 |= I2S_RCR4_FPACK(config->fifoPacking);
1293 #endif
1294 
1295  base->RCR4 = rcr4;
1296 
1297 #if defined(FSL_FEATURE_SAI_FIFO_COUNT) && (FSL_FEATURE_SAI_FIFO_COUNT > 1)
1298  base->RCR1 = (base->RCR1 & (~I2S_RCR1_RFW_MASK)) | I2S_RCR1_RFW(config->fifoWatermark);
1299 #endif
1300 }
1301 #endif
1302 
1311 {
1312  uint32_t tcr4 = base->TCR4;
1313 
1314  if ((masterSlave == kSAI_Master) || (masterSlave == kSAI_Bclk_Slave_FrameSync_Master))
1315  {
1316  assert(config != NULL);
1317  assert((config->frameSyncWidth - 1UL) <= (I2S_TCR4_SYWD_MASK >> I2S_TCR4_SYWD_SHIFT));
1318 
1320 
1321 #if defined(FSL_FEATURE_SAI_HAS_FRAME_SYNC_ON_DEMAND) && FSL_FEATURE_SAI_HAS_FRAME_SYNC_ON_DEMAND
1322  tcr4 &= ~I2S_TCR4_ONDEM_MASK;
1323  tcr4 |= I2S_TCR4_ONDEM(config->frameSyncGenerateOnDemand);
1324 #endif
1325 
1326  tcr4 |= I2S_TCR4_FSE(config->frameSyncEarly) | I2S_TCR4_FSP(config->frameSyncPolarity) | I2S_TCR4_FSD(1UL) |
1327  I2S_TCR4_SYWD(config->frameSyncWidth - 1UL);
1328  }
1329  else
1330  {
1331  tcr4 &= ~I2S_TCR4_FSD_MASK;
1332  }
1333 
1334  base->TCR4 = tcr4;
1335 }
1336 
1345 {
1346  uint32_t rcr4 = base->RCR4;
1347 
1348  if ((masterSlave == kSAI_Master) || (masterSlave == kSAI_Bclk_Slave_FrameSync_Master))
1349  {
1350  assert(config != NULL);
1351  assert((config->frameSyncWidth - 1UL) <= (I2S_RCR4_SYWD_MASK >> I2S_RCR4_SYWD_SHIFT));
1352 
1354 
1355 #if defined(FSL_FEATURE_SAI_HAS_FRAME_SYNC_ON_DEMAND) && FSL_FEATURE_SAI_HAS_FRAME_SYNC_ON_DEMAND
1356  rcr4 &= ~I2S_RCR4_ONDEM_MASK;
1357  rcr4 |= I2S_RCR4_ONDEM(config->frameSyncGenerateOnDemand);
1358 #endif
1359 
1360  rcr4 |= I2S_RCR4_FSE(config->frameSyncEarly) | I2S_RCR4_FSP(config->frameSyncPolarity) | I2S_RCR4_FSD(1UL) |
1361  I2S_RCR4_SYWD(config->frameSyncWidth - 1UL);
1362  }
1363  else
1364  {
1365  rcr4 &= ~I2S_RCR4_FSD_MASK;
1366  }
1367 
1368  base->RCR4 = rcr4;
1369 }
1370 
1378 {
1379  assert(config != NULL);
1380 
1381  uint32_t tcr4 = base->TCR4;
1382 
1383  base->TCR5 = I2S_TCR5_WNW(config->dataWordNLength - 1UL) | I2S_TCR5_W0W(config->dataWord0Length - 1UL) |
1384  I2S_TCR5_FBT(config->dataFirstBitShifted - 1UL);
1385  base->TMR = config->dataMaskedWord;
1386 #if defined(FSL_FEATURE_SAI_HAS_FIFO_FUNCTION_AFTER_ERROR) && FSL_FEATURE_SAI_HAS_FIFO_FUNCTION_AFTER_ERROR
1387  /* ERR05144: not set FCONT = 1 when TMR > 0, the transmit shift register may not load correctly that will cause TX
1388  * not work */
1389  if (config->dataMaskedWord > 0U)
1390  {
1391  tcr4 &= ~I2S_TCR4_FCONT_MASK;
1392  }
1393 #endif
1394  tcr4 &= ~(I2S_TCR4_FRSZ_MASK | I2S_TCR4_MF_MASK);
1395  tcr4 |= I2S_TCR4_FRSZ(config->dataWordNum - 1UL) | I2S_TCR4_MF(config->dataOrder);
1396 
1397 #if defined(FSL_FEATURE_SAI_HAS_CHANNEL_MODE) && FSL_FEATURE_SAI_HAS_CHANNEL_MODE
1398  tcr4 &= ~I2S_TCR4_CHMOD_MASK;
1399  tcr4 |= I2S_TCR4_CHMOD(config->dataMode);
1400 #endif
1401 
1402  base->TCR4 = tcr4;
1403 }
1404 
1412 {
1413  assert(config != NULL);
1414 
1415  uint32_t rcr4 = base->RCR4;
1416 
1417  base->RCR5 = I2S_RCR5_WNW(config->dataWordNLength - 1UL) | I2S_RCR5_W0W(config->dataWord0Length - 1UL) |
1418  I2S_RCR5_FBT(config->dataFirstBitShifted - 1UL);
1419  base->RMR = config->dataMaskedWord;
1420 
1421  rcr4 &= ~(I2S_RCR4_FRSZ_MASK | I2S_RCR4_MF_MASK);
1422  rcr4 |= I2S_RCR4_FRSZ(config->dataWordNum - 1uL) | I2S_RCR4_MF(config->dataOrder);
1423 
1424  base->RCR4 = rcr4;
1425 }
1426 
1434 {
1435  assert(config != NULL);
1436  assert(FSL_FEATURE_SAI_CHANNEL_COUNTn(base) != -1);
1437 
1438  uint8_t i = 0U;
1439  uint32_t val = 0U;
1440  uint8_t channelNums = 0U;
1441 
1442  /* reset transmitter */
1443  SAI_TxReset(base);
1444 
1445  /* if channel mask is not set, then format->channel must be set,
1446  use it to get channel mask value */
1447  if (config->channelMask == 0U)
1448  {
1450  }
1451 
1452  for (i = 0U; i < (uint32_t)FSL_FEATURE_SAI_CHANNEL_COUNTn(base); i++)
1453  {
1454  if (IS_SAI_FLAG_SET(1UL << i, config->channelMask))
1455  {
1456  channelNums++;
1457  config->endChannel = i;
1458  }
1459  }
1460 
1461  for (i = 0U; i < (uint32_t)FSL_FEATURE_SAI_CHANNEL_COUNTn(base); i++)
1462  {
1463  if (IS_SAI_FLAG_SET((1UL << i), config->channelMask))
1464  {
1465  config->startChannel = i;
1466  break;
1467  }
1468  }
1469 
1470  config->channelNums = channelNums;
1471 #if defined(FSL_FEATURE_SAI_HAS_FIFO_COMBINE_MODE) && (FSL_FEATURE_SAI_HAS_FIFO_COMBINE_MODE)
1472  /* make sure combine mode disabled while multipe channel is used */
1473  if (config->channelNums > 1U)
1474  {
1475  base->TCR4 &= ~I2S_TCR4_FCOMB_MASK;
1476  }
1477 #endif
1478 
1479  /* Set data channel */
1480  base->TCR3 &= ~I2S_TCR3_TCE_MASK;
1481  base->TCR3 |= I2S_TCR3_TCE(config->channelMask);
1482 
1483  if (config->syncMode == kSAI_ModeAsync)
1484  {
1485  val = base->TCR2;
1486  val &= ~I2S_TCR2_SYNC_MASK;
1487  base->TCR2 = (val | I2S_TCR2_SYNC(0U));
1488  }
1489  if (config->syncMode == kSAI_ModeSync)
1490  {
1491  val = base->TCR2;
1492  val &= ~I2S_TCR2_SYNC_MASK;
1493  base->TCR2 = (val | I2S_TCR2_SYNC(1U));
1494  /* If sync with Rx, should set Rx to async mode */
1495  val = base->RCR2;
1496  val &= ~I2S_RCR2_SYNC_MASK;
1497  base->RCR2 = (val | I2S_RCR2_SYNC(0U));
1498  }
1499 #if defined(FSL_FEATURE_SAI_HAS_SYNC_WITH_ANOTHER_SAI) && (FSL_FEATURE_SAI_HAS_SYNC_WITH_ANOTHER_SAI)
1500  if (config->syncMode == kSAI_ModeSyncWithOtherTx)
1501  {
1502  val = base->TCR2;
1503  val &= ~I2S_TCR2_SYNC_MASK;
1504  base->TCR2 = (val | I2S_TCR2_SYNC(2U));
1505  }
1506  if (config->syncMode == kSAI_ModeSyncWithOtherRx)
1507  {
1508  val = base->TCR2;
1509  val &= ~I2S_TCR2_SYNC_MASK;
1510  base->TCR2 = (val | I2S_TCR2_SYNC(3U));
1511  }
1512 #endif /* FSL_FEATURE_SAI_HAS_SYNC_WITH_ANOTHER_SAI */
1513 
1514  /* bit clock configurations */
1516  /* serial data configurations */
1518  /* frame sync configurations */
1520 #if FSL_SAI_HAS_FIFO_EXTEND_FEATURE
1521  /* fifo configurations */
1522  SAI_TxSetFifoConfig(base, &config->fifo);
1523 #endif
1524 }
1525 
1536 {
1537  assert(handle != NULL);
1538  assert(config != NULL);
1539  assert(config->channelNums <= (uint32_t)FSL_FEATURE_SAI_CHANNEL_COUNTn(base));
1540 
1542 #if defined(FSL_FEATURE_SAI_FIFO_COUNT) && (FSL_FEATURE_SAI_FIFO_COUNT > 1)
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 
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  {
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 */
1646  /* serial data configurations */
1648  /* frame sync configurations */
1650 #if FSL_SAI_HAS_FIFO_EXTEND_FEATURE
1651  /* fifo configurations */
1652  SAI_RxSetFifoConfig(base, &config->fifo);
1653 #endif
1654 }
1655 
1666 {
1667  assert(handle != NULL);
1668  assert(config != NULL);
1669 
1671 #if defined(FSL_FEATURE_SAI_FIFO_COUNT) && (FSL_FEATURE_SAI_FIFO_COUNT > 1)
1672  handle->watermark = config->fifo.fifoWatermark;
1673 #endif
1674 
1675  /* receiver configurations */
1676  SAI_RxSetConfig(base, config);
1677 
1678  handle->channel = config->startChannel;
1679  /* used for multi channel */
1680  handle->channelMask = config->channelMask;
1681  handle->channelNums = config->channelNums;
1682  handle->endChannel = config->endChannel;
1683 }
1684 
1694  sai_word_width_t bitWidth,
1695  sai_mono_stereo_t mode,
1696  uint32_t saiChannelMask)
1697 {
1698  SAI_GetCommonConfig(config, bitWidth, mode, saiChannelMask);
1699 }
1700 
1710  sai_word_width_t bitWidth,
1711  sai_mono_stereo_t mode,
1712  uint32_t saiChannelMask)
1713 {
1714  assert(NULL != config);
1715  assert(saiChannelMask != 0U);
1716 
1717  SAI_GetCommonConfig(config, bitWidth, mode, saiChannelMask);
1718 
1719  config->frameSync.frameSyncEarly = false;
1721 }
1722 
1732  sai_word_width_t bitWidth,
1733  sai_mono_stereo_t mode,
1734  uint32_t saiChannelMask)
1735 {
1736  assert(NULL != config);
1737  assert(saiChannelMask != 0U);
1738 
1739  SAI_GetCommonConfig(config, bitWidth, mode, saiChannelMask);
1740 
1741  config->frameSync.frameSyncEarly = false;
1743 }
1744 
1754  sai_frame_sync_len_t frameSyncWidth,
1755  sai_word_width_t bitWidth,
1756  sai_mono_stereo_t mode,
1757  uint32_t saiChannelMask)
1758 {
1759  assert(NULL != config);
1760  assert(saiChannelMask != 0U);
1761 
1762  SAI_GetCommonConfig(config, bitWidth, mode, saiChannelMask);
1763 
1764  /* frame sync default configurations */
1765  switch (frameSyncWidth)
1766  {
1769  break;
1770  default:
1771  assert(false);
1772  break;
1773  }
1774  config->frameSync.frameSyncEarly = false;
1776 }
1777 
1787  sai_frame_sync_len_t frameSyncWidth,
1788  sai_word_width_t bitWidth,
1789  uint32_t dataWordNum,
1790  uint32_t saiChannelMask)
1791 {
1792  assert(NULL != config);
1793  assert(saiChannelMask != 0U);
1794  assert(dataWordNum <= 32U);
1795 
1796  SAI_GetCommonConfig(config, bitWidth, kSAI_Stereo, saiChannelMask);
1797 
1798  /* frame sync default configurations */
1799  switch (frameSyncWidth)
1800  {
1803  break;
1805  break;
1806  default:
1807  assert(false);
1808  break;
1809  }
1810  config->frameSync.frameSyncEarly = false;
1812  config->serialData.dataWordNum = (uint8_t)dataWordNum;
1813 }
1814 
1830  sai_transfer_format_t *format,
1831  uint32_t mclkSourceClockHz,
1832  uint32_t bclkSourceClockHz)
1833 {
1834  assert(FSL_FEATURE_SAI_CHANNEL_COUNTn(base) != -1);
1835 
1836  uint32_t bclk = 0;
1837  uint32_t val = 0;
1838  uint8_t i = 0U, channelNums = 0U;
1839  uint32_t divider = 0U;
1840 
1841  if (format->isFrameSyncCompact)
1842  {
1843  bclk = format->sampleRate_Hz * format->bitWidth * (format->stereo == kSAI_Stereo ? 2U : 1U);
1844  val = (base->TCR4 & (~I2S_TCR4_SYWD_MASK));
1845  val |= I2S_TCR4_SYWD(format->bitWidth - 1U);
1846  base->TCR4 = val;
1847  }
1848  else
1849  {
1850  bclk = format->sampleRate_Hz * 32U * 2U;
1851  }
1852 
1853 /* Compute the mclk */
1854 #if defined(FSL_FEATURE_SAI_HAS_MCLKDIV_REGISTER) && (FSL_FEATURE_SAI_HAS_MCLKDIV_REGISTER)
1855  /* Check if master clock divider enabled, then set master clock divider */
1856  if (IS_SAI_FLAG_SET(base->MCR, I2S_MCR_MOE_MASK))
1857  {
1858  SAI_SetMasterClockDivider(base, format->masterClockHz, mclkSourceClockHz);
1859  }
1860 #endif /* FSL_FEATURE_SAI_HAS_MCLKDIV_REGISTER */
1861 
1862  /* Set bclk if needed */
1864  {
1865  base->TCR2 &= ~I2S_TCR2_DIV_MASK;
1866  /* need to check the divided bclk, if bigger than target, then divider need to re-calculate. */
1867  divider = bclkSourceClockHz / bclk;
1868  /* for the condition where the source clock is smaller than target bclk */
1869  if (divider == 0U)
1870  {
1871  divider++;
1872  }
1873  /* recheck the divider if properly or not, to make sure output blck not bigger than target*/
1874  if ((bclkSourceClockHz / divider) > bclk)
1875  {
1876  divider++;
1877  }
1878 
1879 #if defined(FSL_FEATURE_SAI_HAS_BCLK_BYPASS) && (FSL_FEATURE_SAI_HAS_BCLK_BYPASS)
1880  /* if bclk same with MCLK, bypass the divider */
1881  if (divider == 1U)
1882  {
1883  base->TCR2 |= I2S_TCR2_BYP_MASK;
1884  }
1885  else
1886 #endif
1887  {
1888  base->TCR2 |= I2S_TCR2_DIV(divider / 2U - 1U);
1889  }
1890  }
1891 
1892  /* Set bitWidth */
1893  val = (format->isFrameSyncCompact) ? (format->bitWidth - 1U) : 31U;
1894  if (format->protocol == kSAI_BusRightJustified)
1895  {
1896  base->TCR5 = I2S_TCR5_WNW(val) | I2S_TCR5_W0W(val) | I2S_TCR5_FBT(val);
1897  }
1898  else
1899  {
1901  {
1902  base->TCR5 = I2S_TCR5_WNW(val) | I2S_TCR5_W0W(val) | I2S_TCR5_FBT(format->bitWidth - 1UL);
1903  }
1904  else
1905  {
1906  base->TCR5 = I2S_TCR5_WNW(val) | I2S_TCR5_W0W(val) | I2S_TCR5_FBT(0);
1907  }
1908  }
1909 
1910  /* Set mono or stereo */
1911  base->TMR = (uint32_t)format->stereo;
1912 
1913  /* if channel mask is not set, then format->channel must be set,
1914  use it to get channel mask value */
1915  if (format->channelMask == 0U)
1916  {
1917  format->channelMask = 1U << format->channel;
1918  }
1919 
1920  /* if channel nums is not set, calculate it here according to channelMask*/
1921  for (i = 0U; i < (uint32_t)FSL_FEATURE_SAI_CHANNEL_COUNTn(base); i++)
1922  {
1923  if (IS_SAI_FLAG_SET((1UL << i), format->channelMask))
1924  {
1925  channelNums++;
1926  format->endChannel = i;
1927  }
1928  }
1929 
1930  for (i = 0U; i < (uint32_t)FSL_FEATURE_SAI_CHANNEL_COUNTn(base); i++)
1931  {
1932  if (IS_SAI_FLAG_SET((1UL << i), format->channelMask))
1933  {
1934  format->channel = i;
1935  break;
1936  }
1937  }
1938 
1939  format->channelNums = channelNums;
1940 #if defined(FSL_FEATURE_SAI_HAS_FIFO_COMBINE_MODE) && (FSL_FEATURE_SAI_HAS_FIFO_COMBINE_MODE)
1941  /* make sure combine mode disabled while multipe channel is used */
1942  if (format->channelNums > 1U)
1943  {
1944  base->TCR4 &= ~I2S_TCR4_FCOMB_MASK;
1945  }
1946 #endif
1947 
1948  /* Set data channel */
1949  base->TCR3 &= ~I2S_TCR3_TCE_MASK;
1950  base->TCR3 |= I2S_TCR3_TCE(format->channelMask);
1951 
1952 #if defined(FSL_FEATURE_SAI_FIFO_COUNT) && (FSL_FEATURE_SAI_FIFO_COUNT > 1)
1953  /* Set watermark */
1954  base->TCR1 = format->watermark;
1955 #endif /* FSL_FEATURE_SAI_FIFO_COUNT */
1956 }
1957 
1973  sai_transfer_format_t *format,
1974  uint32_t mclkSourceClockHz,
1975  uint32_t bclkSourceClockHz)
1976 {
1977  assert(FSL_FEATURE_SAI_CHANNEL_COUNTn(base) != -1);
1978 
1979  uint32_t bclk = 0;
1980  uint32_t val = 0;
1981  uint8_t i = 0U, channelNums = 0U;
1982  uint32_t divider = 0U;
1983 
1984  if (format->isFrameSyncCompact)
1985  {
1986  bclk = format->sampleRate_Hz * format->bitWidth * (format->stereo == kSAI_Stereo ? 2U : 1U);
1987  val = (base->RCR4 & (~I2S_RCR4_SYWD_MASK));
1988  val |= I2S_RCR4_SYWD(format->bitWidth - 1U);
1989  base->RCR4 = val;
1990  }
1991  else
1992  {
1993  bclk = format->sampleRate_Hz * 32U * 2U;
1994  }
1995 
1996 /* Compute the mclk */
1997 #if defined(FSL_FEATURE_SAI_HAS_MCLKDIV_REGISTER) && (FSL_FEATURE_SAI_HAS_MCLKDIV_REGISTER)
1998  /* Check if master clock divider enabled */
1999  if (IS_SAI_FLAG_SET(base->MCR, I2S_MCR_MOE_MASK))
2000  {
2001  SAI_SetMasterClockDivider(base, format->masterClockHz, mclkSourceClockHz);
2002  }
2003 #endif /* FSL_FEATURE_SAI_HAS_MCLKDIV_REGISTER */
2004 
2005  /* Set bclk if needed */
2007  {
2008  base->RCR2 &= ~I2S_RCR2_DIV_MASK;
2009  /* need to check the divided bclk, if bigger than target, then divider need to re-calculate. */
2010  divider = bclkSourceClockHz / bclk;
2011  /* for the condition where the source clock is smaller than target bclk */
2012  if (divider == 0U)
2013  {
2014  divider++;
2015  }
2016  /* recheck the divider if properly or not, to make sure output blck not bigger than target*/
2017  if ((bclkSourceClockHz / divider) > bclk)
2018  {
2019  divider++;
2020  }
2021 #if defined(FSL_FEATURE_SAI_HAS_BCLK_BYPASS) && (FSL_FEATURE_SAI_HAS_BCLK_BYPASS)
2022  /* if bclk same with MCLK, bypass the divider */
2023  if (divider == 1U)
2024  {
2025  base->RCR2 |= I2S_RCR2_BYP_MASK;
2026  }
2027  else
2028 #endif
2029  {
2030  base->RCR2 |= I2S_RCR2_DIV(divider / 2U - 1U);
2031  }
2032  }
2033 
2034  /* Set bitWidth */
2035  val = (format->isFrameSyncCompact) ? (format->bitWidth - 1U) : 31U;
2036  if (format->protocol == kSAI_BusRightJustified)
2037  {
2038  base->RCR5 = I2S_RCR5_WNW(val) | I2S_RCR5_W0W(val) | I2S_RCR5_FBT(val);
2039  }
2040  else
2041  {
2043  {
2044  base->RCR5 = I2S_RCR5_WNW(val) | I2S_RCR5_W0W(val) | I2S_RCR5_FBT(format->bitWidth - 1UL);
2045  }
2046  else
2047  {
2048  base->RCR5 = I2S_RCR5_WNW(val) | I2S_RCR5_W0W(val) | I2S_RCR5_FBT(0UL);
2049  }
2050  }
2051 
2052  /* Set mono or stereo */
2053  base->RMR = (uint32_t)format->stereo;
2054 
2055  /* if channel mask is not set, then format->channel must be set,
2056  use it to get channel mask value */
2057  if (format->channelMask == 0U)
2058  {
2059  format->channelMask = 1U << format->channel;
2060  }
2061 
2062  /* if channel nums is not set, calculate it here according to channelMask*/
2063  for (i = 0U; i < (uint32_t)FSL_FEATURE_SAI_CHANNEL_COUNTn(base); i++)
2064  {
2065  if (IS_SAI_FLAG_SET((1UL << i), format->channelMask))
2066  {
2067  channelNums++;
2068  format->endChannel = i;
2069  }
2070  }
2071 
2072  for (i = 0U; i < (uint32_t)FSL_FEATURE_SAI_CHANNEL_COUNTn(base); i++)
2073  {
2074  if (IS_SAI_FLAG_SET((1UL << i), format->channelMask))
2075  {
2076  format->channel = i;
2077  break;
2078  }
2079  }
2080 
2081  format->channelNums = channelNums;
2082 
2083 #if defined(FSL_FEATURE_SAI_HAS_FIFO_COMBINE_MODE) && (FSL_FEATURE_SAI_HAS_FIFO_COMBINE_MODE)
2084  /* make sure combine mode disabled while multipe channel is used */
2085  if (format->channelNums > 1U)
2086  {
2087  base->RCR4 &= ~I2S_RCR4_FCOMB_MASK;
2088  }
2089 #endif
2090 
2091  /* Set data channel */
2092  base->RCR3 &= ~I2S_RCR3_RCE_MASK;
2093  /* enable all the channel */
2094  base->RCR3 |= I2S_RCR3_RCE(format->channelMask);
2095 
2096 #if defined(FSL_FEATURE_SAI_FIFO_COUNT) && (FSL_FEATURE_SAI_FIFO_COUNT > 1)
2097  /* Set watermark */
2098  base->RCR1 = format->watermark;
2099 #endif /* FSL_FEATURE_SAI_FIFO_COUNT */
2100 }
2101 
2113 void SAI_WriteBlocking(I2S_Type *base, uint32_t channel, uint32_t bitWidth, uint8_t *buffer, uint32_t size)
2114 {
2115  uint32_t i = 0;
2116  uint32_t bytesPerWord = bitWidth / 8U;
2117 #if defined(FSL_FEATURE_SAI_FIFO_COUNT) && (FSL_FEATURE_SAI_FIFO_COUNT > 1)
2118  bytesPerWord = (((uint32_t)FSL_FEATURE_SAI_FIFO_COUNT - base->TCR1) * bytesPerWord);
2119 #endif
2120 
2121  while (i < size)
2122  {
2123  /* Wait until it can write data */
2124  while (!(IS_SAI_FLAG_SET(base->TCSR, I2S_TCSR_FWF_MASK)))
2125  {
2126  }
2127 
2128  SAI_WriteNonBlocking(base, channel, 1UL << channel, channel, (uint8_t)bitWidth, buffer, bytesPerWord);
2129  buffer += bytesPerWord;
2130  i += bytesPerWord;
2131  }
2132 
2133  /* Wait until the last data is sent */
2134  while (!(IS_SAI_FLAG_SET(base->TCSR, I2S_TCSR_FWF_MASK)))
2135  {
2136  }
2137 }
2138 
2152  I2S_Type *base, uint32_t channel, uint32_t channelMask, uint32_t bitWidth, uint8_t *buffer, uint32_t size)
2153 {
2154  assert(FSL_FEATURE_SAI_CHANNEL_COUNTn(base) != -1);
2155 
2156  uint32_t i = 0, j = 0;
2157  uint32_t bytesPerWord = bitWidth / 8U;
2158  uint32_t channelNums = 0U, endChannel = 0U;
2159 
2160 #if defined(FSL_FEATURE_SAI_FIFO_COUNT) && (FSL_FEATURE_SAI_FIFO_COUNT > 1)
2161  bytesPerWord = (((uint32_t)FSL_FEATURE_SAI_FIFO_COUNT - base->TCR1) * bytesPerWord);
2162 #endif
2163 
2164  for (i = 0U; (i < (uint32_t)FSL_FEATURE_SAI_CHANNEL_COUNTn(base)); i++)
2165  {
2166  if (IS_SAI_FLAG_SET((1UL << i), channelMask))
2167  {
2168  channelNums++;
2169  endChannel = i;
2170  }
2171  }
2172 
2173  bytesPerWord *= channelNums;
2174 
2175  while (j < size)
2176  {
2177  /* Wait until it can write data */
2178  while (!(IS_SAI_FLAG_SET(base->TCSR, I2S_TCSR_FWF_MASK)))
2179  {
2180  }
2181 
2182  SAI_WriteNonBlocking(base, channel, channelMask, endChannel, (uint8_t)bitWidth, buffer, bytesPerWord);
2183  buffer += bytesPerWord;
2184  j += bytesPerWord;
2185  }
2186 
2187  /* Wait until the last data is sent */
2188  while (!(IS_SAI_FLAG_SET(base->TCSR, I2S_TCSR_FWF_MASK)))
2189  {
2190  }
2191 }
2192 
2206  I2S_Type *base, uint32_t channel, uint32_t channelMask, uint32_t bitWidth, uint8_t *buffer, uint32_t size)
2207 {
2208  assert(FSL_FEATURE_SAI_CHANNEL_COUNTn(base) != -1);
2209 
2210  uint32_t i = 0, j = 0;
2211  uint32_t bytesPerWord = bitWidth / 8U;
2212  uint32_t channelNums = 0U, endChannel = 0U;
2213 #if defined(FSL_FEATURE_SAI_FIFO_COUNT) && (FSL_FEATURE_SAI_FIFO_COUNT > 1)
2214  bytesPerWord = base->RCR1 * bytesPerWord;
2215 #endif
2216  for (i = 0U; (i < (uint32_t)FSL_FEATURE_SAI_CHANNEL_COUNTn(base)); i++)
2217  {
2218  if (IS_SAI_FLAG_SET((1UL << i), channelMask))
2219  {
2220  channelNums++;
2221  endChannel = i;
2222  }
2223  }
2224 
2225  bytesPerWord *= channelNums;
2226 
2227  while (j < size)
2228  {
2229  /* Wait until data is received */
2230  while (!(IS_SAI_FLAG_SET(base->RCSR, I2S_RCSR_FWF_MASK)))
2231  {
2232  }
2233 
2234  SAI_ReadNonBlocking(base, channel, channelMask, endChannel, (uint8_t)bitWidth, buffer, bytesPerWord);
2235  buffer += bytesPerWord;
2236  j += bytesPerWord;
2237  }
2238 }
2239 
2251 void SAI_ReadBlocking(I2S_Type *base, uint32_t channel, uint32_t bitWidth, uint8_t *buffer, uint32_t size)
2252 {
2253  uint32_t i = 0;
2254  uint32_t bytesPerWord = bitWidth / 8U;
2255 #if defined(FSL_FEATURE_SAI_FIFO_COUNT) && (FSL_FEATURE_SAI_FIFO_COUNT > 1)
2256  bytesPerWord = base->RCR1 * bytesPerWord;
2257 #endif
2258 
2259  while (i < size)
2260  {
2261  /* Wait until data is received */
2262  while (!(IS_SAI_FLAG_SET(base->RCSR, I2S_RCSR_FWF_MASK)))
2263  {
2264  }
2265 
2266  SAI_ReadNonBlocking(base, channel, 1UL << channel, channel, (uint8_t)bitWidth, buffer, bytesPerWord);
2267  buffer += bytesPerWord;
2268  i += bytesPerWord;
2269  }
2270 }
2271 
2283 void SAI_TransferTxCreateHandle(I2S_Type *base, sai_handle_t *handle, sai_transfer_callback_t callback, void *userData)
2284 {
2285  assert(handle != NULL);
2286 
2287  /* Zero the handle */
2288  (void)memset(handle, 0, sizeof(*handle));
2289 
2290  s_saiHandle[SAI_GetInstance(base)][0] = handle;
2291 
2292  handle->callback = callback;
2293  handle->userData = userData;
2294  handle->base = base;
2295 
2296  /* Set the isr pointer */
2298 
2299  /* Enable Tx irq */
2300  (void)EnableIRQ(s_saiTxIRQ[SAI_GetInstance(base)]);
2301 }
2302 
2314 void SAI_TransferRxCreateHandle(I2S_Type *base, sai_handle_t *handle, sai_transfer_callback_t callback, void *userData)
2315 {
2316  assert(handle != NULL);
2317 
2318  /* Zero the handle */
2319  (void)memset(handle, 0, sizeof(*handle));
2320 
2321  s_saiHandle[SAI_GetInstance(base)][1] = handle;
2322 
2323  handle->callback = callback;
2324  handle->userData = userData;
2325  handle->base = base;
2326 
2327  /* Set the isr pointer */
2329 
2330  /* Enable Rx irq */
2331  (void)EnableIRQ(s_saiRxIRQ[SAI_GetInstance(base)]);
2332 }
2333 
2351  sai_handle_t *handle,
2352  sai_transfer_format_t *format,
2353  uint32_t mclkSourceClockHz,
2354  uint32_t bclkSourceClockHz)
2355 {
2356  assert(handle != NULL);
2357 
2358  if ((bclkSourceClockHz < format->sampleRate_Hz)
2360  || (mclkSourceClockHz < format->sampleRate_Hz)
2361 #endif
2362  )
2363  {
2364  return kStatus_InvalidArgument;
2365  }
2366 
2367  /* Copy format to handle */
2368  handle->bitWidth = (uint8_t)format->bitWidth;
2370  handle->watermark = format->watermark;
2371 #endif
2372 
2373  SAI_TxSetFormat(base, format, mclkSourceClockHz, bclkSourceClockHz);
2374 
2375  handle->channel = format->channel;
2376  /* used for multi channel */
2377  handle->channelMask = format->channelMask;
2378  handle->channelNums = format->channelNums;
2379  handle->endChannel = format->endChannel;
2380 
2381  return kStatus_Success;
2382 }
2383 
2401  sai_handle_t *handle,
2402  sai_transfer_format_t *format,
2403  uint32_t mclkSourceClockHz,
2404  uint32_t bclkSourceClockHz)
2405 {
2406  assert(handle != NULL);
2407 
2408  if ((bclkSourceClockHz < format->sampleRate_Hz)
2410  || (mclkSourceClockHz < format->sampleRate_Hz)
2411 #endif
2412  )
2413  {
2414  return kStatus_InvalidArgument;
2415  }
2416 
2417  /* Copy format to handle */
2418  handle->bitWidth = (uint8_t)format->bitWidth;
2420  handle->watermark = format->watermark;
2421 #endif
2422 
2423  SAI_RxSetFormat(base, format, mclkSourceClockHz, bclkSourceClockHz);
2424 
2425  handle->channel = format->channel;
2426  /* used for multi channel */
2427  handle->channelMask = format->channelMask;
2428  handle->channelNums = format->channelNums;
2429  handle->endChannel = format->endChannel;
2430 
2431  return kStatus_Success;
2432 }
2433 
2450 {
2451  assert(handle != NULL);
2452  assert(handle->channelNums <= (uint32_t)FSL_FEATURE_SAI_CHANNEL_COUNTn(base));
2453 
2454  /* Check if the queue is full */
2455  if (handle->saiQueue[handle->queueUser].data != NULL)
2456  {
2457  return kStatus_SAI_QueueFull;
2458  }
2459 
2460  /* Add into queue */
2461  handle->transferSize[handle->queueUser] = xfer->dataSize;
2462  handle->saiQueue[handle->queueUser].data = xfer->data;
2463  handle->saiQueue[handle->queueUser].dataSize = xfer->dataSize;
2464  handle->queueUser = (handle->queueUser + 1U) % SAI_XFER_QUEUE_SIZE;
2465 
2466  /* Set the state to busy */
2467  handle->state = (uint32_t)kSAI_Busy;
2468 
2469  /* Enable interrupt */
2470 #if defined(FSL_FEATURE_SAI_FIFO_COUNT) && (FSL_FEATURE_SAI_FIFO_COUNT > 1)
2471  /* Use FIFO request interrupt and fifo error*/
2473 #else
2475 #endif /* FSL_FEATURE_SAI_FIFO_COUNT */
2476 
2477  /* Enable Tx transfer */
2478  SAI_TxEnable(base, true);
2479 
2480  return kStatus_Success;
2481 }
2482 
2499 {
2500  assert(handle != NULL);
2501  assert(handle->channelNums <= (uint32_t)FSL_FEATURE_SAI_CHANNEL_COUNTn(base));
2502 
2503  /* Check if the queue is full */
2504  if (handle->saiQueue[handle->queueUser].data != NULL)
2505  {
2506  return kStatus_SAI_QueueFull;
2507  }
2508 
2509  /* Add into queue */
2510  handle->transferSize[handle->queueUser] = xfer->dataSize;
2511  handle->saiQueue[handle->queueUser].data = xfer->data;
2512  handle->saiQueue[handle->queueUser].dataSize = xfer->dataSize;
2513  handle->queueUser = (handle->queueUser + 1U) % SAI_XFER_QUEUE_SIZE;
2514 
2515  /* Set state to busy */
2516  handle->state = (uint32_t)kSAI_Busy;
2517 
2518 /* Enable interrupt */
2519 #if defined(FSL_FEATURE_SAI_FIFO_COUNT) && (FSL_FEATURE_SAI_FIFO_COUNT > 1)
2520  /* Use FIFO request interrupt and fifo error*/
2522 #else
2524 #endif /* FSL_FEATURE_SAI_FIFO_COUNT */
2525 
2526  /* Enable Rx transfer */
2527  SAI_RxEnable(base, true);
2528 
2529  return kStatus_Success;
2530 }
2531 
2542 {
2543  assert(handle != NULL);
2544 
2545  status_t status = kStatus_Success;
2546  uint32_t queueDriverIndex = handle->queueDriver;
2547 
2548  if (handle->state != (uint32_t)kSAI_Busy)
2549  {
2551  }
2552  else
2553  {
2554  *count = (handle->transferSize[queueDriverIndex] - handle->saiQueue[queueDriverIndex].dataSize);
2555  }
2556 
2557  return status;
2558 }
2559 
2570 {
2571  assert(handle != NULL);
2572 
2573  status_t status = kStatus_Success;
2574  uint32_t queueDriverIndex = handle->queueDriver;
2575 
2576  if (handle->state != (uint32_t)kSAI_Busy)
2577  {
2579  }
2580  else
2581  {
2582  *count = (handle->transferSize[queueDriverIndex] - handle->saiQueue[queueDriverIndex].dataSize);
2583  }
2584 
2585  return status;
2586 }
2587 
2598 {
2599  assert(handle != NULL);
2600 
2601  /* Stop Tx transfer and disable interrupt */
2602  SAI_TxEnable(base, false);
2603 #if defined(FSL_FEATURE_SAI_FIFO_COUNT) && (FSL_FEATURE_SAI_FIFO_COUNT > 1)
2604  /* Use FIFO request interrupt and fifo error */
2606 #else
2608 #endif /* FSL_FEATURE_SAI_FIFO_COUNT */
2609 
2610  handle->state = (uint32_t)kSAI_Idle;
2611 
2612  /* Clear the queue */
2613  (void)memset(handle->saiQueue, 0, sizeof(sai_transfer_t) * SAI_XFER_QUEUE_SIZE);
2614  handle->queueDriver = 0;
2615  handle->queueUser = 0;
2616 }
2617 
2628 {
2629  assert(handle != NULL);
2630 
2631  /* Stop Tx transfer and disable interrupt */
2632  SAI_RxEnable(base, false);
2633 #if defined(FSL_FEATURE_SAI_FIFO_COUNT) && (FSL_FEATURE_SAI_FIFO_COUNT > 1)
2634  /* Use FIFO request interrupt and fifo error */
2636 #else
2638 #endif /* FSL_FEATURE_SAI_FIFO_COUNT */
2639 
2640  handle->state = (uint32_t)kSAI_Idle;
2641 
2642  /* Clear the queue */
2643  (void)memset(handle->saiQueue, 0, sizeof(sai_transfer_t) * SAI_XFER_QUEUE_SIZE);
2644  handle->queueDriver = 0;
2645  handle->queueUser = 0;
2646 }
2647 
2658 {
2659  assert(handle != NULL);
2660 
2661  /* Abort the current transfer */
2662  SAI_TransferAbortSend(base, handle);
2663 
2664  /* Clear all the internal information */
2665  (void)memset(handle->saiQueue, 0, sizeof(handle->saiQueue));
2666  (void)memset(handle->transferSize, 0, sizeof(handle->transferSize));
2667 
2668  handle->queueUser = 0U;
2669  handle->queueDriver = 0U;
2670 }
2671 
2682 {
2683  assert(handle != NULL);
2684 
2685  /* Abort the current transfer */
2686  SAI_TransferAbortReceive(base, handle);
2687 
2688  /* Clear all the internal information */
2689  (void)memset(handle->saiQueue, 0, sizeof(handle->saiQueue));
2690  (void)memset(handle->transferSize, 0, sizeof(handle->transferSize));
2691 
2692  handle->queueUser = 0U;
2693  handle->queueDriver = 0U;
2694 }
2695 
2703 {
2704  assert(handle != NULL);
2705 
2706  uint8_t *buffer = handle->saiQueue[handle->queueDriver].data;
2707  uint32_t dataSize = (handle->bitWidth / 8UL) * handle->channelNums;
2708 
2709  /* Handle Error */
2711  {
2712  /* Clear FIFO error flag to continue transfer */
2714 
2715  /* Reset FIFO for safety */
2717 
2718  /* Call the callback */
2719  if (handle->callback != NULL)
2720  {
2721  (handle->callback)(base, handle, kStatus_SAI_TxError, handle->userData);
2722  }
2723  }
2724 
2725 /* Handle transfer */
2726 #if defined(FSL_FEATURE_SAI_FIFO_COUNT) && (FSL_FEATURE_SAI_FIFO_COUNT > 1)
2728  {
2729  /* Judge if the data need to transmit is less than space */
2730  size_t size = MIN((handle->saiQueue[handle->queueDriver].dataSize),
2731  (size_t)(((uint32_t)FSL_FEATURE_SAI_FIFO_COUNT - handle->watermark) * dataSize));
2732 
2733  /* Copy the data from sai buffer to FIFO */
2734  SAI_WriteNonBlocking(base, handle->channel, handle->channelMask, handle->endChannel, handle->bitWidth, buffer,
2735  size);
2736 
2737  /* Update the internal counter */
2738  handle->saiQueue[handle->queueDriver].dataSize -= size;
2739  handle->saiQueue[handle->queueDriver].data = (uint8_t *)((uint32_t)buffer + size);
2740  }
2741 #else
2743  {
2744  size_t size = MIN((handle->saiQueue[handle->queueDriver].dataSize), dataSize);
2745 
2746  SAI_WriteNonBlocking(base, handle->channel, handle->channelMask, handle->endChannel, handle->bitWidth, buffer,
2747  size);
2748 
2749  /* Update internal counter */
2750  handle->saiQueue[handle->queueDriver].dataSize -= size;
2751  handle->saiQueue[handle->queueDriver].data = (uint8_t *)((uint32_t)buffer + size);
2752  }
2753 #endif /* FSL_FEATURE_SAI_FIFO_COUNT */
2754 
2755  /* If finished a block, call the callback function */
2756  if (handle->saiQueue[handle->queueDriver].dataSize == 0U)
2757  {
2758  (void)memset(&handle->saiQueue[handle->queueDriver], 0, sizeof(sai_transfer_t));
2759  handle->queueDriver = (handle->queueDriver + 1U) % SAI_XFER_QUEUE_SIZE;
2760  if (handle->callback != NULL)
2761  {
2762  (handle->callback)(base, handle, kStatus_SAI_TxIdle, handle->userData);
2763  }
2764  }
2765 
2766  /* If all data finished, just stop the transfer */
2767  if (handle->saiQueue[handle->queueDriver].data == NULL)
2768  {
2769  SAI_TransferAbortSend(base, handle);
2770  }
2771 }
2772 
2780 {
2781  assert(handle != NULL);
2782 
2783  uint8_t *buffer = handle->saiQueue[handle->queueDriver].data;
2784  uint32_t dataSize = (handle->bitWidth / 8UL) * handle->channelNums;
2785 
2786  /* Handle Error */
2788  {
2789  /* Clear FIFO error flag to continue transfer */
2791 
2792  /* Reset FIFO for safety */
2794 
2795  /* Call the callback */
2796  if (handle->callback != NULL)
2797  {
2798  (handle->callback)(base, handle, kStatus_SAI_RxError, handle->userData);
2799  }
2800  }
2801 
2802 /* Handle transfer */
2803 #if defined(FSL_FEATURE_SAI_FIFO_COUNT) && (FSL_FEATURE_SAI_FIFO_COUNT > 1)
2805  {
2806  /* Judge if the data need to transmit is less than space */
2807  size_t size = MIN((handle->saiQueue[handle->queueDriver].dataSize), handle->watermark * dataSize);
2808 
2809  /* Copy the data from sai buffer to FIFO */
2810  SAI_ReadNonBlocking(base, handle->channel, handle->channelMask, handle->endChannel, handle->bitWidth, buffer,
2811  size);
2812 
2813  /* Update the internal counter */
2814  handle->saiQueue[handle->queueDriver].dataSize -= size;
2815  handle->saiQueue[handle->queueDriver].data = (uint8_t *)((uint32_t)buffer + size);
2816  }
2817 #else
2819  {
2820  size_t size = MIN((handle->saiQueue[handle->queueDriver].dataSize), dataSize);
2821 
2822  SAI_ReadNonBlocking(base, handle->channel, handle->channelMask, handle->endChannel, handle->bitWidth, buffer,
2823  size);
2824 
2825  /* Update internal state */
2826  handle->saiQueue[handle->queueDriver].dataSize -= size;
2827  handle->saiQueue[handle->queueDriver].data = (uint8_t *)((uint32_t)buffer + size);
2828  }
2829 #endif /* FSL_FEATURE_SAI_FIFO_COUNT */
2830 
2831  /* If finished a block, call the callback function */
2832  if (handle->saiQueue[handle->queueDriver].dataSize == 0U)
2833  {
2834  (void)memset(&handle->saiQueue[handle->queueDriver], 0, sizeof(sai_transfer_t));
2835  handle->queueDriver = (handle->queueDriver + 1U) % SAI_XFER_QUEUE_SIZE;
2836  if (handle->callback != NULL)
2837  {
2838  (handle->callback)(base, handle, kStatus_SAI_RxIdle, handle->userData);
2839  }
2840  }
2841 
2842  /* If all data finished, just stop the transfer */
2843  if (handle->saiQueue[handle->queueDriver].data == NULL)
2844  {
2845  SAI_TransferAbortReceive(base, handle);
2846  }
2847 }
2848 
2849 #if defined(I2S0)
2850 void I2S0_DriverIRQHandler(void)
2851 {
2852 #if defined(FSL_FEATURE_SAI_FIFO_COUNT) && (FSL_FEATURE_SAI_FIFO_COUNT > 1)
2855 #else
2858 #endif
2859  {
2860  s_saiRxIsr(I2S0, s_saiHandle[0][1]);
2861  }
2862 #if defined(FSL_FEATURE_SAI_FIFO_COUNT) && (FSL_FEATURE_SAI_FIFO_COUNT > 1)
2865 #else
2868 #endif
2869  {
2870  s_saiTxIsr(I2S0, s_saiHandle[0][0]);
2871  }
2873 }
2874 
2875 void I2S0_Tx_DriverIRQHandler(void)
2876 {
2877  assert(s_saiHandle[0][0] != NULL);
2878  s_saiTxIsr(I2S0, s_saiHandle[0][0]);
2880 }
2881 
2882 void I2S0_Rx_DriverIRQHandler(void)
2883 {
2884  assert(s_saiHandle[0][1] != NULL);
2885  s_saiRxIsr(I2S0, s_saiHandle[0][1]);
2887 }
2888 #endif /* I2S0*/
2889 
2890 #if defined(I2S1)
2891 void I2S1_DriverIRQHandler(void)
2892 {
2893 #if defined(FSL_FEATURE_SAI_FIFO_COUNT) && (FSL_FEATURE_SAI_FIFO_COUNT > 1)
2896 #else
2899 #endif
2900  {
2901  s_saiRxIsr(I2S1, s_saiHandle[1][1]);
2902  }
2903 
2904 #if defined(FSL_FEATURE_SAI_FIFO_COUNT) && (FSL_FEATURE_SAI_FIFO_COUNT > 1)
2907 #else
2910 #endif
2911  {
2912  s_saiTxIsr(I2S1, s_saiHandle[1][0]);
2913  }
2915 }
2916 
2917 void I2S1_Tx_DriverIRQHandler(void)
2918 {
2919  assert(s_saiHandle[1][0] != NULL);
2920  s_saiTxIsr(I2S1, s_saiHandle[1][0]);
2922 }
2923 
2924 void I2S1_Rx_DriverIRQHandler(void)
2925 {
2926  assert(s_saiHandle[1][1] != NULL);
2927  s_saiRxIsr(I2S1, s_saiHandle[1][1]);
2929 }
2930 #endif /* I2S1*/
2931 
2932 #if defined(I2S2)
2933 void I2S2_DriverIRQHandler(void)
2934 {
2935 #if defined(FSL_FEATURE_SAI_FIFO_COUNT) && (FSL_FEATURE_SAI_FIFO_COUNT > 1)
2938 #else
2941 #endif
2942  {
2943  s_saiRxIsr(I2S2, s_saiHandle[2][1]);
2944  }
2945 
2946 #if defined(FSL_FEATURE_SAI_FIFO_COUNT) && (FSL_FEATURE_SAI_FIFO_COUNT > 1)
2949 #else
2952 #endif
2953  {
2954  s_saiTxIsr(I2S2, s_saiHandle[2][0]);
2955  }
2957 }
2958 
2959 void I2S2_Tx_DriverIRQHandler(void)
2960 {
2961  assert(s_saiHandle[2][0] != NULL);
2962  s_saiTxIsr(I2S2, s_saiHandle[2][0]);
2964 }
2965 
2966 void I2S2_Rx_DriverIRQHandler(void)
2967 {
2968  assert(s_saiHandle[2][1] != NULL);
2969  s_saiRxIsr(I2S2, s_saiHandle[2][1]);
2971 }
2972 #endif /* I2S2*/
2973 
2974 #if defined(I2S3)
2975 void I2S3_DriverIRQHandler(void)
2976 {
2977 #if defined(FSL_FEATURE_SAI_FIFO_COUNT) && (FSL_FEATURE_SAI_FIFO_COUNT > 1)
2980 #else
2983 #endif
2984  {
2985  s_saiRxIsr(I2S3, s_saiHandle[3][1]);
2986  }
2987 #if defined(FSL_FEATURE_SAI_FIFO_COUNT) && (FSL_FEATURE_SAI_FIFO_COUNT > 1)
2990 #else
2993 #endif
2994  {
2995  s_saiTxIsr(I2S3, s_saiHandle[3][0]);
2996  }
2998 }
2999 
3000 void I2S3_Tx_DriverIRQHandler(void)
3001 {
3002  assert(s_saiHandle[3][0] != NULL);
3003  s_saiTxIsr(I2S3, s_saiHandle[3][0]);
3005 }
3006 
3007 void I2S3_Rx_DriverIRQHandler(void)
3008 {
3009  assert(s_saiHandle[3][1] != NULL);
3010  s_saiRxIsr(I2S3, s_saiHandle[3][1]);
3012 }
3013 #endif /* I2S3*/
3014 
3015 #if defined(I2S4)
3016 void I2S4_DriverIRQHandler(void)
3017 {
3018 #if defined(FSL_FEATURE_SAI_FIFO_COUNT) && (FSL_FEATURE_SAI_FIFO_COUNT > 1)
3021 #else
3024 #endif
3025  {
3026  s_saiRxIsr(I2S4, s_saiHandle[4][1]);
3027  }
3028 
3029 #if defined(FSL_FEATURE_SAI_FIFO_COUNT) && (FSL_FEATURE_SAI_FIFO_COUNT > 1)
3032 #else
3035 #endif
3036  {
3037  s_saiTxIsr(I2S4, s_saiHandle[4][0]);
3038  }
3040 }
3041 
3042 void I2S4_Tx_DriverIRQHandler(void)
3043 {
3044  assert(s_saiHandle[4][0] != NULL);
3045  s_saiTxIsr(I2S4, s_saiHandle[4][0]);
3047 }
3048 
3049 void I2S4_Rx_DriverIRQHandler(void)
3050 {
3051  assert(s_saiHandle[4][1] != NULL);
3052  s_saiRxIsr(I2S4, s_saiHandle[4][1]);
3054 }
3055 #endif
3056 
3057 #if defined(FSL_FEATURE_SAI_SAI5_SAI6_SHARE_IRQ) && (FSL_FEATURE_SAI_SAI5_SAI6_SHARE_IRQ) && defined(I2S5) && \
3058  defined(I2S6)
3059 void I2S56_DriverIRQHandler(void)
3060 {
3061  /* use index 5 to get handle when I2S5 & I2S6 share IRQ NUMBER */
3062  I2S_Type *base = s_saiHandle[5][1]->base;
3063 #if defined(FSL_FEATURE_SAI_FIFO_COUNT) && (FSL_FEATURE_SAI_FIFO_COUNT > 1)
3066 #else
3069 #endif
3070  {
3071  s_saiRxIsr(base, s_saiHandle[5][1]);
3072  }
3073 
3074  base = s_saiHandle[5][0]->base;
3075 #if defined(FSL_FEATURE_SAI_FIFO_COUNT) && (FSL_FEATURE_SAI_FIFO_COUNT > 1)
3078 #else
3081 #endif
3082  {
3083  s_saiTxIsr(base, s_saiHandle[5][0]);
3084  }
3086 }
3087 
3088 void I2S56_Tx_DriverIRQHandler(void)
3089 {
3090  /* use index 5 to get handle when I2S5 & I2S6 share IRQ NUMBER */
3091  assert(s_saiHandle[5][0] != NULL);
3092  s_saiTxIsr(s_saiHandle[5][0]->base, s_saiHandle[5][0]);
3094 }
3095 
3096 void I2S56_Rx_DriverIRQHandler(void)
3097 {
3098  /* use index 5 to get handle when I2S5 & I2S6 share IRQ NUMBER */
3099  assert(s_saiHandle[5][1] != NULL);
3100  s_saiRxIsr(s_saiHandle[5][1]->base, s_saiHandle[5][1]);
3102 }
3103 
3104 #else
3105 
3106 #if defined(I2S5)
3107 void I2S5_DriverIRQHandler(void)
3108 {
3109 #if defined(FSL_FEATURE_SAI_FIFO_COUNT) && (FSL_FEATURE_SAI_FIFO_COUNT > 1)
3112 #else
3115 #endif
3116  {
3117  s_saiRxIsr(I2S5, s_saiHandle[5][1]);
3118  }
3119 #if defined(FSL_FEATURE_SAI_FIFO_COUNT) && (FSL_FEATURE_SAI_FIFO_COUNT > 1)
3122 #else
3125 #endif
3126  {
3127  s_saiTxIsr(I2S5, s_saiHandle[5][0]);
3128  }
3130 }
3131 
3132 void I2S5_Tx_DriverIRQHandler(void)
3133 {
3134  assert(s_saiHandle[5][0] != NULL);
3135  s_saiTxIsr(I2S5, s_saiHandle[5][0]);
3137 }
3138 
3139 void I2S5_Rx_DriverIRQHandler(void)
3140 {
3141  assert(s_saiHandle[5][1] != NULL);
3142  s_saiRxIsr(I2S5, s_saiHandle[5][1]);
3144 }
3145 #endif
3146 
3147 #if defined(I2S6)
3148 void I2S6_DriverIRQHandler(void)
3149 {
3150 #if defined(FSL_FEATURE_SAI_FIFO_COUNT) && (FSL_FEATURE_SAI_FIFO_COUNT > 1)
3153 #else
3156 #endif
3157  {
3158  s_saiRxIsr(I2S6, s_saiHandle[6][1]);
3159  }
3160 #if defined(FSL_FEATURE_SAI_FIFO_COUNT) && (FSL_FEATURE_SAI_FIFO_COUNT > 1)
3163 #else
3166 #endif
3167  {
3168  s_saiTxIsr(I2S6, s_saiHandle[6][0]);
3169  }
3171 }
3172 
3173 void I2S6_Tx_DriverIRQHandler(void)
3174 {
3175  assert(s_saiHandle[6][0] != NULL);
3176  s_saiTxIsr(I2S6, s_saiHandle[6][0]);
3178 }
3179 
3180 void I2S6_Rx_DriverIRQHandler(void)
3181 {
3182  assert(s_saiHandle[6][1] != NULL);
3183  s_saiRxIsr(I2S6, s_saiHandle[6][1]);
3185 }
3186 #endif
3187 #endif
3188 
3189 #if defined(AUDIO__SAI0)
3190 void AUDIO_SAI0_INT_DriverIRQHandler(void)
3191 {
3192 #if defined(FSL_FEATURE_SAI_FIFO_COUNT) && (FSL_FEATURE_SAI_FIFO_COUNT > 1)
3193  if ((s_saiHandle[0][1] != NULL) &&
3196 #else
3197  if ((s_saiHandle[0][1] != NULL) &&
3200 #endif
3201  {
3202  s_saiRxIsr(AUDIO__SAI0, s_saiHandle[0][1]);
3203  }
3204 
3205 #if defined(FSL_FEATURE_SAI_FIFO_COUNT) && (FSL_FEATURE_SAI_FIFO_COUNT > 1)
3206  if ((s_saiHandle[0][0] != NULL) &&
3209 #else
3210  if ((s_saiHandle[0][0] != NULL) &&
3213 #endif
3214  {
3215  s_saiTxIsr(AUDIO__SAI0, s_saiHandle[0][0]);
3216  }
3218 }
3219 #endif /* AUDIO__SAI0 */
3220 
3221 #if defined(AUDIO__SAI1)
3222 void AUDIO_SAI1_INT_DriverIRQHandler(void)
3223 {
3224 #if defined(FSL_FEATURE_SAI_FIFO_COUNT) && (FSL_FEATURE_SAI_FIFO_COUNT > 1)
3225  if ((s_saiHandle[1][1] != NULL) &&
3228 #else
3229  if ((s_saiHandle[1][1] != NULL) &&
3232 #endif
3233  {
3234  s_saiRxIsr(AUDIO__SAI1, s_saiHandle[1][1]);
3235  }
3236 #if defined(FSL_FEATURE_SAI_FIFO_COUNT) && (FSL_FEATURE_SAI_FIFO_COUNT > 1)
3237  if ((s_saiHandle[1][0] != NULL) &&
3240 #else
3241  if ((s_saiHandle[1][0] != NULL) &&
3244 #endif
3245  {
3246  s_saiTxIsr(AUDIO__SAI1, s_saiHandle[1][0]);
3247  }
3249 }
3250 #endif /* AUDIO__SAI1 */
3251 
3252 #if defined(AUDIO__SAI2)
3253 void AUDIO_SAI2_INT_DriverIRQHandler(void)
3254 {
3255 #if defined(FSL_FEATURE_SAI_FIFO_COUNT) && (FSL_FEATURE_SAI_FIFO_COUNT > 1)
3256  if ((s_saiHandle[2][1] != NULL) &&
3259 #else
3260  if ((s_saiHandle[2][1] != NULL) &&
3263 #endif
3264  {
3265  s_saiRxIsr(AUDIO__SAI2, s_saiHandle[2][1]);
3266  }
3267 #if defined(FSL_FEATURE_SAI_FIFO_COUNT) && (FSL_FEATURE_SAI_FIFO_COUNT > 1)
3268  if ((s_saiHandle[2][0] != NULL) &&
3271 #else
3272  if ((s_saiHandle[2][0] != NULL) &&
3275 #endif
3276  {
3277  s_saiTxIsr(AUDIO__SAI2, s_saiHandle[2][0]);
3278  }
3280 }
3281 #endif /* AUDIO__SAI2 */
3282 
3283 #if defined(AUDIO__SAI3)
3284 void AUDIO_SAI3_INT_DriverIRQHandler(void)
3285 {
3286 #if defined(FSL_FEATURE_SAI_FIFO_COUNT) && (FSL_FEATURE_SAI_FIFO_COUNT > 1)
3287  if ((s_saiHandle[3][1] != NULL) &&
3290 #else
3291  if ((s_saiHandle[3][1] != NULL) &&
3294 #endif
3295  {
3296  s_saiRxIsr(AUDIO__SAI3, s_saiHandle[3][1]);
3297  }
3298 #if defined(FSL_FEATURE_SAI_FIFO_COUNT) && (FSL_FEATURE_SAI_FIFO_COUNT > 1)
3299  if ((s_saiHandle[3][0] != NULL) &&
3302 #else
3303  if ((s_saiHandle[3][0] != NULL) &&
3306 #endif
3307  {
3308  s_saiTxIsr(AUDIO__SAI3, s_saiHandle[3][0]);
3309  }
3311 }
3312 #endif
3313 
3314 #if defined(AUDIO__SAI6)
3315 void AUDIO_SAI6_INT_DriverIRQHandler(void)
3316 {
3317 #if defined(FSL_FEATURE_SAI_FIFO_COUNT) && (FSL_FEATURE_SAI_FIFO_COUNT > 1)
3318  if ((s_saiHandle[6][1] != NULL) &&
3321 #else
3322  if ((s_saiHandle[6][1] != NULL) &&
3325 #endif
3326  {
3327  s_saiRxIsr(AUDIO__SAI6, s_saiHandle[6][1]);
3328  }
3329 #if defined(FSL_FEATURE_SAI_FIFO_COUNT) && (FSL_FEATURE_SAI_FIFO_COUNT > 1)
3330  if ((s_saiHandle[6][0] != NULL) &&
3333 #else
3334  if ((s_saiHandle[6][0] != NULL) &&
3337 #endif
3338  {
3339  s_saiTxIsr(AUDIO__SAI6, s_saiHandle[6][0]);
3340  }
3342 }
3343 #endif /* AUDIO__SAI6 */
3344 
3345 #if defined(AUDIO__SAI7)
3346 void AUDIO_SAI7_INT_DriverIRQHandler(void)
3347 {
3348 #if defined(FSL_FEATURE_SAI_FIFO_COUNT) && (FSL_FEATURE_SAI_FIFO_COUNT > 1)
3349  if ((s_saiHandle[7][1] != NULL) &&
3352 #else
3353  if ((s_saiHandle[7][1] != NULL) &&
3356 #endif
3357  {
3358  s_saiRxIsr(AUDIO__SAI7, s_saiHandle[7][1]);
3359  }
3360 #if defined(FSL_FEATURE_SAI_FIFO_COUNT) && (FSL_FEATURE_SAI_FIFO_COUNT > 1)
3361  if ((s_saiHandle[7][0] != NULL) &&
3364 #else
3365  if ((s_saiHandle[7][0] != NULL) &&
3368 #endif
3369  {
3370  s_saiTxIsr(AUDIO__SAI7, s_saiHandle[7][0]);
3371  }
3373 }
3374 #endif /* AUDIO__SAI7 */
3375 
3376 #if defined(ADMA__SAI0)
3377 void ADMA_SAI0_INT_DriverIRQHandler(void)
3378 {
3379 #if defined(FSL_FEATURE_SAI_FIFO_COUNT) && (FSL_FEATURE_SAI_FIFO_COUNT > 1)
3380  if ((s_saiHandle[1][1] != NULL) &&
3383 #else
3384  if ((s_saiHandle[1][1] != NULL) &&
3387 #endif
3388  {
3389  s_saiRxIsr(ADMA__SAI0, s_saiHandle[1][1]);
3390  }
3391 #if defined(FSL_FEATURE_SAI_FIFO_COUNT) && (FSL_FEATURE_SAI_FIFO_COUNT > 1)
3392  if ((s_saiHandle[1][0] != NULL) &&
3395 #else
3396  if ((s_saiHandle[1][0] != NULL) &&
3399 #endif
3400  {
3401  s_saiTxIsr(ADMA__SAI0, s_saiHandle[1][0]);
3402  }
3404 }
3405 #endif /* ADMA__SAI0 */
3406 
3407 #if defined(ADMA__SAI1)
3408 void ADMA_SAI1_INT_DriverIRQHandler(void)
3409 {
3410 #if defined(FSL_FEATURE_SAI_FIFO_COUNT) && (FSL_FEATURE_SAI_FIFO_COUNT > 1)
3411  if ((s_saiHandle[1][1] != NULL) &&
3414 #else
3415  if ((s_saiHandle[1][1] != NULL) &&
3418 #endif
3419  {
3420  s_saiRxIsr(ADMA__SAI1, s_saiHandle[1][1]);
3421  }
3422 #if defined(FSL_FEATURE_SAI_FIFO_COUNT) && (FSL_FEATURE_SAI_FIFO_COUNT > 1)
3423  if ((s_saiHandle[1][0] != NULL) &&
3426 #else
3427  if ((s_saiHandle[1][0] != NULL) &&
3430 #endif
3431  {
3432  s_saiTxIsr(ADMA__SAI1, s_saiHandle[1][0]);
3433  }
3435 }
3436 #endif /* ADMA__SAI1 */
3437 
3438 #if defined(ADMA__SAI2)
3439 void ADMA_SAI2_INT_DriverIRQHandler(void)
3440 {
3441 #if defined(FSL_FEATURE_SAI_FIFO_COUNT) && (FSL_FEATURE_SAI_FIFO_COUNT > 1)
3442  if ((s_saiHandle[1][1] != NULL) &&
3445 #else
3446  if ((s_saiHandle[1][1] != NULL) &&
3449 #endif
3450  {
3451  s_saiRxIsr(ADMA__SAI2, s_saiHandle[1][1]);
3452  }
3453 #if defined(FSL_FEATURE_SAI_FIFO_COUNT) && (FSL_FEATURE_SAI_FIFO_COUNT > 1)
3454  if ((s_saiHandle[1][0] != NULL) &&
3457 #else
3458  if ((s_saiHandle[1][0] != NULL) &&
3461 #endif
3462  {
3463  s_saiTxIsr(ADMA__SAI2, s_saiHandle[1][0]);
3464  }
3466 }
3467 #endif /* ADMA__SAI2 */
3468 
3469 #if defined(ADMA__SAI3)
3470 void ADMA_SAI3_INT_DriverIRQHandler(void)
3471 {
3472 #if defined(FSL_FEATURE_SAI_FIFO_COUNT) && (FSL_FEATURE_SAI_FIFO_COUNT > 1)
3473  if ((s_saiHandle[1][1] != NULL) &&
3476 #else
3477  if ((s_saiHandle[1][1] != NULL) &&
3480 #endif
3481  {
3482  s_saiRxIsr(ADMA__SAI3, s_saiHandle[1][1]);
3483  }
3484 #if defined(FSL_FEATURE_SAI_FIFO_COUNT) && (FSL_FEATURE_SAI_FIFO_COUNT > 1)
3485  if ((s_saiHandle[1][0] != NULL) &&
3488 #else
3489  if ((s_saiHandle[1][0] != NULL) &&
3492 #endif
3493  {
3494  s_saiTxIsr(ADMA__SAI3, s_saiHandle[1][0]);
3495  }
3497 }
3498 #endif /* ADMA__SAI3 */
3499 
3500 #if defined(ADMA__SAI4)
3501 void ADMA_SAI4_INT_DriverIRQHandler(void)
3502 {
3503 #if defined(FSL_FEATURE_SAI_FIFO_COUNT) && (FSL_FEATURE_SAI_FIFO_COUNT > 1)
3504  if ((s_saiHandle[1][1] != NULL) &&
3507 #else
3508  if ((s_saiHandle[1][1] != NULL) &&
3511 #endif
3512  {
3513  s_saiRxIsr(ADMA__SAI4, s_saiHandle[1][1]);
3514  }
3515 
3516 #if defined(FSL_FEATURE_SAI_FIFO_COUNT) && (FSL_FEATURE_SAI_FIFO_COUNT > 1)
3517  if ((s_saiHandle[1][0] != NULL) &&
3520 #else
3521  if ((s_saiHandle[1][0] != NULL) &&
3524 #endif
3525  {
3526  s_saiTxIsr(ADMA__SAI4, s_saiHandle[1][0]);
3527  }
3529 }
3530 #endif /* ADMA__SAI4 */
3531 
3532 #if defined(ADMA__SAI5)
3533 void ADMA_SAI5_INT_DriverIRQHandler(void)
3534 {
3535 #if defined(FSL_FEATURE_SAI_FIFO_COUNT) && (FSL_FEATURE_SAI_FIFO_COUNT > 1)
3536  if ((s_saiHandle[1][1] != NULL) &&
3539 #else
3540  if ((s_saiHandle[1][1] != NULL) &&
3543 #endif
3544  {
3545  s_saiRxIsr(ADMA__SAI5, s_saiHandle[1][1]);
3546  }
3547 #if defined(FSL_FEATURE_SAI_FIFO_COUNT) && (FSL_FEATURE_SAI_FIFO_COUNT > 1)
3548  if ((s_saiHandle[1][0] != NULL) &&
3551 #else
3552  if ((s_saiHandle[1][0] != NULL) &&
3555 #endif
3556  {
3557  s_saiTxIsr(ADMA__SAI5, s_saiHandle[1][0]);
3558  }
3560 }
3561 #endif /* ADMA__SAI5 */
3562 
3563 #if defined(SAI0)
3564 void SAI0_DriverIRQHandler(void)
3565 {
3566 #if defined(FSL_FEATURE_SAI_FIFO_COUNT) && (FSL_FEATURE_SAI_FIFO_COUNT > 1)
3569 #else
3572 #endif
3573  {
3574  s_saiRxIsr(SAI0, s_saiHandle[0][1]);
3575  }
3576 #if defined(FSL_FEATURE_SAI_FIFO_COUNT) && (FSL_FEATURE_SAI_FIFO_COUNT > 1)
3579 #else
3582 #endif
3583  {
3584  s_saiTxIsr(SAI0, s_saiHandle[0][0]);
3585  }
3587 }
3588 #endif /* SAI0 */
3589 
3590 #if defined(SAI1)
3591 void SAI1_DriverIRQHandler(void)
3592 {
3593 #if defined(FSL_FEATURE_SAI_FIFO_COUNT) && (FSL_FEATURE_SAI_FIFO_COUNT > 1)
3596 #else
3599 #endif
3600  {
3601  s_saiRxIsr(SAI1, s_saiHandle[1][1]);
3602  }
3603 #if defined(FSL_FEATURE_SAI_FIFO_COUNT) && (FSL_FEATURE_SAI_FIFO_COUNT > 1)
3606 #else
3609 #endif
3610  {
3611  s_saiTxIsr(SAI1, s_saiHandle[1][0]);
3612  }
3614 }
3615 #endif /* SAI1 */
3616 
3617 #if defined(SAI2)
3618 void SAI2_DriverIRQHandler(void)
3619 {
3620 #if defined(FSL_FEATURE_SAI_FIFO_COUNT) && (FSL_FEATURE_SAI_FIFO_COUNT > 1)
3623 #else
3626 #endif
3627  {
3628  s_saiRxIsr(SAI2, s_saiHandle[2][1]);
3629  }
3630 #if defined(FSL_FEATURE_SAI_FIFO_COUNT) && (FSL_FEATURE_SAI_FIFO_COUNT > 1)
3633 #else
3636 #endif
3637  {
3638  s_saiTxIsr(SAI2, s_saiHandle[2][0]);
3639  }
3641 }
3642 #endif /* SAI2 */
3643 
3644 #if defined(SAI3)
3645 void SAI3_DriverIRQHandler(void)
3646 {
3647 #if defined(FSL_FEATURE_SAI_FIFO_COUNT) && (FSL_FEATURE_SAI_FIFO_COUNT > 1)
3650 #else
3653 #endif
3654  {
3655  s_saiRxIsr(SAI3, s_saiHandle[3][1]);
3656  }
3657 #if defined(FSL_FEATURE_SAI_FIFO_COUNT) && (FSL_FEATURE_SAI_FIFO_COUNT > 1)
3660 #else
3663 #endif
3664  {
3665  s_saiTxIsr(SAI3, s_saiHandle[3][0]);
3666  }
3668 }
3669 
3670 void SAI3_TX_DriverIRQHandler(void)
3671 {
3672  assert(s_saiHandle[3][0] != NULL);
3673  s_saiTxIsr(SAI3, s_saiHandle[3][0]);
3675 }
3676 
3677 void SAI3_RX_DriverIRQHandler(void)
3678 {
3679  assert(s_saiHandle[3][1] != NULL);
3680  s_saiRxIsr(SAI3, s_saiHandle[3][1]);
3682 }
3683 #endif /* SAI3 */
3684 
3685 #if defined(SAI4)
3686 void SAI4_DriverIRQHandler(void)
3687 {
3688 #if defined(FSL_FEATURE_SAI_FIFO_COUNT) && (FSL_FEATURE_SAI_FIFO_COUNT > 1)
3691 #else
3694 #endif
3695  {
3696  s_saiRxIsr(SAI4, s_saiHandle[4][1]);
3697  }
3698 #if defined(FSL_FEATURE_SAI_FIFO_COUNT) && (FSL_FEATURE_SAI_FIFO_COUNT > 1)
3701 #else
3704 #endif
3705  {
3706  s_saiTxIsr(SAI4, s_saiHandle[4][0]);
3707  }
3709 }
3710 #endif /* SAI4 */
3711 
3712 #if defined(SAI5)
3713 void SAI5_DriverIRQHandler(void)
3714 {
3715 #if defined(FSL_FEATURE_SAI_FIFO_COUNT) && (FSL_FEATURE_SAI_FIFO_COUNT > 1)
3718 #else
3721 #endif
3722  {
3723  s_saiRxIsr(SAI5, s_saiHandle[5][1]);
3724  }
3725 #if defined(FSL_FEATURE_SAI_FIFO_COUNT) && (FSL_FEATURE_SAI_FIFO_COUNT > 1)
3728 #else
3731 #endif
3732  {
3733  s_saiTxIsr(SAI5, s_saiHandle[5][0]);
3734  }
3736 }
3737 #endif /* SAI5 */
3738 
3739 #if defined(SAI6)
3740 void SAI6_DriverIRQHandler(void)
3741 {
3742 #if defined(FSL_FEATURE_SAI_FIFO_COUNT) && (FSL_FEATURE_SAI_FIFO_COUNT > 1)
3745 #else
3748 #endif
3749  {
3750  s_saiRxIsr(SAI6, s_saiHandle[6][1]);
3751  }
3752 #if defined(FSL_FEATURE_SAI_FIFO_COUNT) && (FSL_FEATURE_SAI_FIFO_COUNT > 1)
3755 #else
3758 #endif
3759  {
3760  s_saiTxIsr(SAI6, s_saiHandle[6][0]);
3761  }
3763 }
3764 #endif /* SAI6 */
_sai_transfer::data
uint8_t * data
Definition: fsl_sai.h:416
SAI_RxGetDefaultConfig
void SAI_RxGetDefaultConfig(sai_config_t *config)
Sets the SAI Rx configuration structure to default values.
Definition: fsl_sai.c:736
sai_tx_isr_t
void(* sai_tx_isr_t)(I2S_Type *base, sai_handle_t *saiHandle)
Typedef for sai tx interrupt handler.
Definition: fsl_sai.c:28
_sai_transfer_format::channel
uint8_t channel
Definition: fsl_sai.h:289
I2S_RCR2_MSEL
#define I2S_RCR2_MSEL(x)
Definition: MIMXRT1052.h:20471
sai_master_slave_t
enum _sai_master_slave sai_master_slave_t
Master or slave mode.
SAI_TxSetBitclockConfig
void SAI_TxSetBitclockConfig(I2S_Type *base, sai_master_slave_t masterSlave, sai_bit_clock_t *config)
Transmitter Bit clock configurations.
Definition: fsl_sai.c:1140
I2S_TCR2_DIV
#define I2S_TCR2_DIV(x)
Definition: MIMXRT1052.h:20088
I2S_RCSR_SR_MASK
#define I2S_RCSR_SR_MASK
Definition: MIMXRT1052.h:20389
I2S_RCR4_FCONT_MASK
#define I2S_RCR4_FCONT_MASK
Definition: MIMXRT1052.h:20581
_sai_bit_clock::bclkInputDelay
bool bclkInputDelay
Definition: fsl_sai.h:354
SAI_TransferTerminateReceive
void SAI_TransferTerminateReceive(I2S_Type *base, sai_handle_t *handle)
Terminate all SAI receive.
Definition: fsl_sai.c:2681
I2S_RCR4_MF_MASK
#define I2S_RCR4_MF_MASK
Definition: MIMXRT1052.h:20546
s_saiHandle
static sai_handle_t * s_saiHandle[ARRAY_SIZE(s_saiBases)][2]
SAI handle pointer.
Definition: fsl_sai.c:149
kSAI_BusRightJustified
@ kSAI_BusRightJustified
Definition: fsl_sai.h:57
_sai_handle::transferSize
size_t transferSize[SAI_XFER_QUEUE_SIZE]
Definition: fsl_sai.h:448
_sai_transfer_format::protocol
sai_protocol_t protocol
Definition: fsl_sai.h:294
kStatus_InvalidArgument
@ kStatus_InvalidArgument
Definition: fsl_common.h:183
I2S_Type::TCR4
__IO uint32_t TCR4
Definition: MIMXRT1052.h:19874
SAI_TransferTxCreateHandle
void SAI_TransferTxCreateHandle(I2S_Type *base, sai_handle_t *handle, sai_transfer_callback_t callback, void *userData)
Initializes the SAI Tx handle.
Definition: fsl_sai.c:2283
SAI3
#define SAI3
Definition: MIMXRT1052.h:20674
I2S_RCSR_FWF_MASK
#define I2S_RCSR_FWF_MASK
Definition: MIMXRT1052.h:20361
I2S_RCR2_DIV_MASK
#define I2S_RCR2_DIV_MASK
Definition: MIMXRT1052.h:20444
SAI_RxGetEnabledInterruptStatus
static bool SAI_RxGetEnabledInterruptStatus(I2S_Type *base, uint32_t enableFlag, uint32_t statusFlag)
sai get rx enabled interrupt status.
Definition: fsl_sai.c:165
I2S_TCR2_BCI_MASK
#define I2S_TCR2_BCI_MASK
Definition: MIMXRT1052.h:20112
I2S_TCSR_FEIE_MASK
#define I2S_TCSR_FEIE_MASK
Definition: MIMXRT1052.h:19973
I2S_RCR2_BCD_MASK
#define I2S_RCR2_BCD_MASK
Definition: MIMXRT1052.h:20449
_sai_serial_data::dataFirstBitShifted
uint8_t dataFirstBitShifted
Definition: fsl_sai.h:388
I2S_RCR4_FSE_MASK
#define I2S_RCR4_FSE_MASK
Definition: MIMXRT1052.h:20539
_sai_transfer_format::channelNums
uint8_t channelNums
Definition: fsl_sai.h:292
SAI_TransferRxSetFormat
status_t SAI_TransferRxSetFormat(I2S_Type *base, sai_handle_t *handle, sai_transfer_format_t *format, uint32_t mclkSourceClockHz, uint32_t bclkSourceClockHz)
Configures the SAI Rx audio format.
Definition: fsl_sai.c:2400
I2S_TCR4_SYWD_SHIFT
#define I2S_TCR4_SYWD_SHIFT
Definition: MIMXRT1052.h:20201
_sai_transfer_format::stereo
sai_mono_stereo_t stereo
Definition: fsl_sai.h:274
SAI_GetCommonConfig
static void SAI_GetCommonConfig(sai_transceiver_t *config, sai_word_width_t bitWidth, sai_mono_stereo_t mode, uint32_t saiChannelMask)
Get classic I2S mode configurations.
Definition: fsl_sai.c:340
NULL
#define NULL
Definition: porcupine/demo/c/dr_libs/tests/external/miniaudio/extras/speex_resampler/thirdparty/resample.c:92
sai_mono_stereo_t
enum _sai_mono_stereo sai_mono_stereo_t
Mono or stereo audio format.
_sai_frame_sync
sai frame sync configurations
Definition: fsl_sai.h:362
kSAI_ResetTypeFIFO
@ kSAI_ResetTypeFIFO
Definition: fsl_sai.h:170
SAI_TxSoftwareReset
void SAI_TxSoftwareReset(I2S_Type *base, sai_reset_type_t type)
Do software reset or FIFO reset .
Definition: fsl_sai.c:870
I2S_Type::RCSR
__IO uint32_t RCSR
Definition: MIMXRT1052.h:19882
_sai_handle::channelMask
uint8_t channelMask
Definition: fsl_sai.h:443
I2S_Type
Definition: MIMXRT1052.h:19867
I2S_RCR4_FRSZ
#define I2S_RCR4_FRSZ(x)
Definition: MIMXRT1052.h:20562
I2S_TCSR_FWIE_MASK
#define I2S_TCSR_FWIE_MASK
Definition: MIMXRT1052.h:19966
I2S_TCR1_TFW_MASK
#define I2S_TCR1_TFW_MASK
Definition: MIMXRT1052.h:20075
kSAI_DataMSB
@ kSAI_DataMSB
Definition: fsl_sai.h:84
IS_SAI_FLAG_SET
#define IS_SAI_FLAG_SET(reg, flag)
check flag avalibility
Definition: fsl_sai.c:34
I2S_TCSR_FRF_MASK
#define I2S_TCSR_FRF_MASK
Definition: MIMXRT1052.h:19994
SAI_TransferTxSetFormat
status_t SAI_TransferTxSetFormat(I2S_Type *base, sai_handle_t *handle, sai_transfer_format_t *format, uint32_t mclkSourceClockHz, uint32_t bclkSourceClockHz)
Configures the SAI Tx audio format.
Definition: fsl_sai.c:2350
I2S_TCSR_FWF_MASK
#define I2S_TCSR_FWF_MASK
Definition: MIMXRT1052.h:20001
I2S_Type::RCR3
__IO uint32_t RCR3
Definition: MIMXRT1052.h:19885
SAI_TxSetChannelFIFOMask
void SAI_TxSetChannelFIFOMask(I2S_Type *base, uint8_t mask)
Set the Tx channel FIFO enable mask.
Definition: fsl_sai.c:904
_sai_handle::channel
uint8_t channel
Definition: fsl_sai.h:442
_sai_transfer::dataSize
size_t dataSize
Definition: fsl_sai.h:417
_sai_serial_data::dataWord0Length
uint8_t dataWord0Length
Definition: fsl_sai.h:384
_sai_handle::queueDriver
volatile uint8_t queueDriver
Definition: fsl_sai.h:450
kStatus_NoTransferInProgress
@ kStatus_NoTransferInProgress
Definition: fsl_common.h:185
I2S_RCR2_DIV
#define I2S_RCR2_DIV(x)
Definition: MIMXRT1052.h:20448
I2S_RCR4_SYWD
#define I2S_RCR4_SYWD(x)
Definition: MIMXRT1052.h:20557
sai_data_order_t
enum _sai_data_order sai_data_order_t
SAI data order, MSB or LSB.
_sai_serial_data::dataWordNLength
uint8_t dataWordNLength
Definition: fsl_sai.h:385
I2S_TCR4_CHMOD_MASK
#define I2S_TCR4_CHMOD_MASK
Definition: MIMXRT1052.h:20193
sai_word_width_t
enum _sai_word_width sai_word_width_t
Audio word width.
SAI_TransferGetReceiveCount
status_t SAI_TransferGetReceiveCount(I2S_Type *base, sai_handle_t *handle, size_t *count)
Gets a received byte count.
Definition: fsl_sai.c:2569
I2S_TCR4_SYWD
#define I2S_TCR4_SYWD(x)
Definition: MIMXRT1052.h:20204
I2S_RCSR_RE_MASK
#define I2S_RCSR_RE_MASK
Definition: MIMXRT1052.h:20424
_sai_transceiver::endChannel
uint8_t endChannel
Definition: fsl_sai.h:408
I2S_TCR4_FSE
#define I2S_TCR4_FSE(x)
Definition: MIMXRT1052.h:20185
SAI_RxSetBitclockConfig
void SAI_RxSetBitclockConfig(I2S_Type *base, sai_master_slave_t masterSlave, sai_bit_clock_t *config)
Receiver Bit clock configurations.
Definition: fsl_sai.c:1167
_sai_transfer_format::channelMask
uint8_t channelMask
Definition: fsl_sai.h:290
_sai_serial_data::dataMaskedWord
uint32_t dataMaskedWord
Definition: fsl_sai.h:390
s_saiTxIsr
static sai_tx_isr_t s_saiTxIsr
Pointer to tx IRQ handler for each instance.
Definition: fsl_sai.c:158
_sai_bit_clock::bclkSrcSwap
bool bclkSrcSwap
Definition: fsl_sai.h:353
I2S_RCR3_RCE_MASK
#define I2S_RCR3_RCE_MASK
Definition: MIMXRT1052.h:20504
FSL_FEATURE_SAI_HAS_MCLKDIV_REGISTER
#define FSL_FEATURE_SAI_HAS_MCLKDIV_REGISTER
Definition: MIMXRT1052_features.h:556
SAI_RxSetSerialDataConfig
void SAI_RxSetSerialDataConfig(I2S_Type *base, sai_serial_data_t *config)
SAI receiver Serial data configurations.
Definition: fsl_sai.c:1411
SAI_RxSetFrameSyncPolarity
void SAI_RxSetFrameSyncPolarity(I2S_Type *base, sai_clock_polarity_t polarity)
Set the Rx data order.
Definition: fsl_sai.c:999
I2S_TCR4_SYWD_MASK
#define I2S_TCR4_SYWD_MASK
Definition: MIMXRT1052.h:20200
I2S_RCSR_FEIE_MASK
#define I2S_RCSR_FEIE_MASK
Definition: MIMXRT1052.h:20333
SAI_GetTDMConfig
void SAI_GetTDMConfig(sai_transceiver_t *config, sai_frame_sync_len_t frameSyncWidth, sai_word_width_t bitWidth, uint32_t dataWordNum, uint32_t saiChannelMask)
Get TDM mode configurations.
Definition: fsl_sai.c:1786
SAI_RxEnable
void SAI_RxEnable(I2S_Type *base, bool enable)
Enables/disables the SAI Rx.
Definition: fsl_sai.c:835
SAI_WriteMultiChannelBlocking
void SAI_WriteMultiChannelBlocking(I2S_Type *base, uint32_t channel, uint32_t channelMask, uint32_t bitWidth, uint8_t *buffer, uint32_t size)
Sends data to multi channel using a blocking method.
Definition: fsl_sai.c:2151
SAI_TransferGetSendCount
status_t SAI_TransferGetSendCount(I2S_Type *base, sai_handle_t *handle, size_t *count)
Gets a set byte count.
Definition: fsl_sai.c:2541
_sai_transfer_format::isFrameSyncCompact
bool isFrameSyncCompact
Definition: fsl_sai.h:295
I2S_TCR2_BCD
#define I2S_TCR2_BCD(x)
Definition: MIMXRT1052.h:20095
_sai_frame_sync::frameSyncEarly
bool frameSyncEarly
Definition: fsl_sai.h:365
I2S_TCR2_BCD_MASK
#define I2S_TCR2_BCD_MASK
Definition: MIMXRT1052.h:20089
kStatus_SAI_QueueFull
@ kStatus_SAI_QueueFull
Definition: fsl_sai.h:35
I2S_RCR4_MF
#define I2S_RCR4_MF(x)
Definition: MIMXRT1052.h:20552
_sai_frame_sync::frameSyncPolarity
sai_clock_polarity_t frameSyncPolarity
Definition: fsl_sai.h:372
I2S_TCR3_TCE
#define I2S_TCR3_TCE(x)
Definition: MIMXRT1052.h:20148
sai_clock_polarity_t
enum _sai_clock_polarity sai_clock_polarity_t
SAI clock polarity, active high or low.
_sai_handle::callback
sai_transfer_callback_t callback
Definition: fsl_sai.h:431
I2S_RCR4_FCOMB
#define I2S_RCR4_FCOMB(x)
Definition: MIMXRT1052.h:20580
I2S_RCSR_FRIE_MASK
#define I2S_RCSR_FRIE_MASK
Definition: MIMXRT1052.h:20319
I2S_RCR2_MSEL_MASK
#define I2S_RCR2_MSEL_MASK
Definition: MIMXRT1052.h:20463
_sai_transceiver::masterSlave
sai_master_slave_t masterSlave
Definition: fsl_sai.h:402
SAI_TxSetBitClockRate
void SAI_TxSetBitClockRate(I2S_Type *base, uint32_t sourceClockHz, uint32_t sampleRate, uint32_t bitWidth, uint32_t channelNumbers)
Transmitter bit clock rate configurations.
Definition: fsl_sai.c:1048
kSAI_PolarityActiveLow
@ kSAI_PolarityActiveLow
Definition: fsl_sai.h:91
_sai_transceiver::channelMask
uint8_t channelMask
Definition: fsl_sai.h:407
I2S_TCR4_FCOMB_MASK
#define I2S_TCR4_FCOMB_MASK
Definition: MIMXRT1052.h:20219
SAI_TxSetFrameSyncPolarity
void SAI_TxSetFrameSyncPolarity(I2S_Type *base, sai_clock_polarity_t polarity)
Set the Tx data order.
Definition: fsl_sai.c:985
_sai_handle::userData
void * userData
Definition: fsl_sai.h:432
I2S_RCSR_FWIE_MASK
#define I2S_RCSR_FWIE_MASK
Definition: MIMXRT1052.h:20326
I2S_RCR3_WDFL_MASK
#define I2S_RCR3_WDFL_MASK
Definition: MIMXRT1052.h:20499
SAI1
#define SAI1
Definition: MIMXRT1052.h:20666
kStatus_SAI_RxError
@ kStatus_SAI_RxError
Definition: fsl_sai.h:34
SAI_RxSetFormat
void SAI_RxSetFormat(I2S_Type *base, sai_transfer_format_t *format, uint32_t mclkSourceClockHz, uint32_t bclkSourceClockHz)
Configures the SAI Rx audio format.
Definition: fsl_sai.c:1972
SAI_TxGetEnabledInterruptStatus
static bool SAI_TxGetEnabledInterruptStatus(I2S_Type *base, uint32_t enableFlag, uint32_t statusFlag)
sai get tx enabled interrupt status.
Definition: fsl_sai.c:172
_sai_serial_data
sai serial data configurations
Definition: fsl_sai.h:377
kSAI_PolarityActiveHigh
@ kSAI_PolarityActiveHigh
Definition: fsl_sai.h:90
_sai_transfer_format::endChannel
uint8_t endChannel
Definition: fsl_sai.h:291
I2S_RCR4_FCOMB_MASK
#define I2S_RCR4_FCOMB_MASK
Definition: MIMXRT1052.h:20572
I2S_TCR4_MF
#define I2S_TCR4_MF(x)
Definition: MIMXRT1052.h:20192
I2S_TCR5_WNW
#define I2S_TCR5_WNW(x)
Definition: MIMXRT1052.h:20253
I2S_RCR4_FSP
#define I2S_RCR4_FSP(x)
Definition: MIMXRT1052.h:20531
I2S_TCR4_FCOMB
#define I2S_TCR4_FCOMB(x)
Definition: MIMXRT1052.h:20227
_sai_transceiver::frameSync
sai_frame_sync_t frameSync
Definition: fsl_sai.h:397
I2S_Type::RCR1
__IO uint32_t RCR1
Definition: MIMXRT1052.h:19883
I2S_RCR4_FSE
#define I2S_RCR4_FSE(x)
Definition: MIMXRT1052.h:20545
SAI4
#define SAI4
Definition: stm32h735xx.h:2613
SAI_TransferReceiveNonBlocking
status_t SAI_TransferReceiveNonBlocking(I2S_Type *base, sai_handle_t *handle, sai_transfer_t *xfer)
Performs an interrupt non-blocking receive transfer on SAI.
Definition: fsl_sai.c:2498
_sai_transceiver::bitClock
sai_bit_clock_t bitClock
Definition: fsl_sai.h:398
I2S_TCR4_FRSZ
#define I2S_TCR4_FRSZ(x)
Definition: MIMXRT1052.h:20209
SAI_TransferAbortSend
void SAI_TransferAbortSend(I2S_Type *base, sai_handle_t *handle)
Aborts the current send.
Definition: fsl_sai.c:2597
SAI_XFER_QUEUE_SIZE
#define SAI_XFER_QUEUE_SIZE
SAI transfer queue size, user can refine it according to use case.
Definition: fsl_sai.h:204
SAI_TransferRxHandleIRQ
void SAI_TransferRxHandleIRQ(I2S_Type *base, sai_handle_t *handle)
Tx interrupt handler.
Definition: fsl_sai.c:2779
SAI_TxInit
void SAI_TxInit(I2S_Type *base, const sai_config_t *config)
Initializes the SAI Tx peripheral.
Definition: fsl_sai.c:409
SAI_TransferRxSetConfig
void SAI_TransferRxSetConfig(I2S_Type *base, sai_handle_t *handle, sai_transceiver_t *config)
SAI receiver transfer configurations.
Definition: fsl_sai.c:1665
_sai_handle::saiQueue
sai_transfer_t saiQueue[SAI_XFER_QUEUE_SIZE]
Definition: fsl_sai.h:447
I2S_TCSR_FRDE_MASK
#define I2S_TCSR_FRDE_MASK
Definition: MIMXRT1052.h:19945
I2S_TCR2_BCS_MASK
#define I2S_TCR2_BCS_MASK
Definition: MIMXRT1052.h:20119
SDK_ISR_EXIT_BARRIER
#define SDK_ISR_EXIT_BARRIER
Definition: fsl_common.h:250
sai_reset_type_t
enum _sai_reset_type sai_reset_type_t
The reset type.
I2S_RCR2_SYNC
#define I2S_RCR2_SYNC(x)
Definition: MIMXRT1052.h:20494
I2S_Type::RCR4
__IO uint32_t RCR4
Definition: MIMXRT1052.h:19886
SAI_RxSetFrameSyncConfig
void SAI_RxSetFrameSyncConfig(I2S_Type *base, sai_master_slave_t masterSlave, sai_frame_sync_t *config)
SAI receiver Frame sync configurations.
Definition: fsl_sai.c:1344
kSAI_FrameSyncLenOneBitClk
@ kSAI_FrameSyncLenOneBitClk
Definition: fsl_sai.h:265
SAI_RxDisableInterrupts
static void SAI_RxDisableInterrupts(I2S_Type *base, uint32_t mask)
Disables the SAI Rx interrupt requests.
Definition: fsl_sai.h:1144
SAI_TransferTerminateSend
void SAI_TransferTerminateSend(I2S_Type *base, sai_handle_t *handle)
Terminate all SAI send.
Definition: fsl_sai.c:2657
I2S_RCR2_BCD
#define I2S_RCR2_BCD(x)
Definition: MIMXRT1052.h:20455
I2S_RCR2_BCP
#define I2S_RCR2_BCP(x)
Definition: MIMXRT1052.h:20462
kSAI_Stereo
@ kSAI_Stereo
Definition: fsl_sai.h:75
I2S_RCSR_FEF_MASK
#define I2S_RCSR_FEF_MASK
Definition: MIMXRT1052.h:20368
kSAI_ModeSync
@ kSAI_ModeSync
Definition: fsl_sai.h:100
I2S_RCR4_SYWD_MASK
#define I2S_RCR4_SYWD_MASK
Definition: MIMXRT1052.h:20553
I2S_TCR5_FBT
#define I2S_TCR5_FBT(x)
Definition: MIMXRT1052.h:20243
SAI_GetInstance
static uint32_t SAI_GetInstance(I2S_Type *base)
Get the instance number for SAI.
Definition: fsl_sai.c:259
ARRAY_SIZE
#define ARRAY_SIZE(x)
Computes the number of elements in an array.
Definition: fsl_common.h:211
kSAI_Bclk_Master_FrameSync_Slave
@ kSAI_Bclk_Master_FrameSync_Slave
Definition: fsl_sai.h:68
I2S_Type::TCR5
__IO uint32_t TCR5
Definition: MIMXRT1052.h:19875
sai_frame_sync_len_t
enum _sai_frame_sync_len sai_frame_sync_len_t
sai frame sync len
I2S_Type::TDR
__O uint32_t TDR[4]
Definition: MIMXRT1052.h:19876
SAI_CLOCKS
#define SAI_CLOCKS
Clock ip name array for SAI.
Definition: fsl_clock.h:338
s_saiBases
static I2S_Type *const s_saiBases[]
Definition: fsl_sai.c:147
fsl_sai.h
I2S_TCSR_FEF_MASK
#define I2S_TCSR_FEF_MASK
Definition: MIMXRT1052.h:20008
IRQn_Type
IRQn_Type
STM32F4XX Interrupt Number Definition, according to the selected device in Library_configuration_sect...
Definition: stm32f407xx.h:66
I2S_TCR2_MSEL_MASK
#define I2S_TCR2_MSEL_MASK
Definition: MIMXRT1052.h:20103
_sai_handle::state
uint32_t state
Definition: fsl_sai.h:430
I2S_RCR2_BCS
#define I2S_RCR2_BCS(x)
Definition: MIMXRT1052.h:20485
I2S_RCR4_FPACK
#define I2S_RCR4_FPACK(x)
Definition: MIMXRT1052.h:20571
I2S_TCR4_FPACK
#define I2S_TCR4_FPACK(x)
Definition: MIMXRT1052.h:20218
count
size_t count
Definition: porcupine/demo/c/dr_libs/tests/external/miniaudio/tests/test_common/ma_test_common.c:31
kSAI_Bclk_Slave_FrameSync_Master
@ kSAI_Bclk_Slave_FrameSync_Master
Definition: fsl_sai.h:69
SAI_TxEnableInterrupts
static void SAI_TxEnableInterrupts(I2S_Type *base, uint32_t mask)
Enables the SAI Tx interrupt requests.
Definition: fsl_sai.h:1093
I2S_TCSR_TE_MASK
#define I2S_TCSR_TE_MASK
Definition: MIMXRT1052.h:20064
SAI_GetRightJustifiedConfig
void SAI_GetRightJustifiedConfig(sai_transceiver_t *config, sai_word_width_t bitWidth, sai_mono_stereo_t mode, uint32_t saiChannelMask)
Get right justified mode configurations.
Definition: fsl_sai.c:1731
I2S_RCR2_SYNC_MASK
#define I2S_RCR2_SYNC_MASK
Definition: MIMXRT1052.h:20486
I2S_RCR4_SYWD_SHIFT
#define I2S_RCR4_SYWD_SHIFT
Definition: MIMXRT1052.h:20554
SAI_RxClearStatusFlags
static void SAI_RxClearStatusFlags(I2S_Type *base, uint32_t mask)
Clears the SAI Rx status flag state.
Definition: fsl_sai.h:915
I2S3
#define I2S3
Definition: stm32f4_discovery_audio.h:81
SAI_Deinit
void SAI_Deinit(I2S_Type *base)
De-initializes the SAI peripheral.
Definition: fsl_sai.c:676
I2S_RCSR_FRF_MASK
#define I2S_RCSR_FRF_MASK
Definition: MIMXRT1052.h:20354
SAI_GetLeftJustifiedConfig
void SAI_GetLeftJustifiedConfig(sai_transceiver_t *config, sai_word_width_t bitWidth, sai_mono_stereo_t mode, uint32_t saiChannelMask)
Get left justified mode configurations.
Definition: fsl_sai.c:1709
SAI_WriteNonBlocking
static void SAI_WriteNonBlocking(I2S_Type *base, uint32_t channel, uint32_t channelMask, uint32_t endChannel, uint8_t bitWidth, uint8_t *buffer, uint32_t size)
sends a piece of data in non-blocking way.
Definition: fsl_sai.c:277
I2S_RCR4_FCONT
#define I2S_RCR4_FCONT(x)
Definition: MIMXRT1052.h:20587
_sai_transceiver
sai transceiver configurations
Definition: fsl_sai.h:394
I2S_RCR2_BCI_MASK
#define I2S_RCR2_BCI_MASK
Definition: MIMXRT1052.h:20472
SAI_TransferTxHandleIRQ
void SAI_TransferTxHandleIRQ(I2S_Type *base, sai_handle_t *handle)
Tx interrupt handler.
Definition: fsl_sai.c:2702
_sai_bit_clock::bclkSource
sai_bclk_source_t bclkSource
Definition: fsl_sai.h:358
I2S_RCR4_FSD
#define I2S_RCR4_FSD(x)
Definition: MIMXRT1052.h:20524
kSAI_BusLeftJustified
@ kSAI_BusLeftJustified
Definition: fsl_sai.h:56
CLOCK_EnableClock
static void CLOCK_EnableClock(clock_ip_name_t name)
Enable the clock for specific IP.
Definition: fsl_clock.h:1059
I2S_RCR4_FRSZ_MASK
#define I2S_RCR4_FRSZ_MASK
Definition: MIMXRT1052.h:20558
I2S_TX_IRQS
#define I2S_TX_IRQS
Definition: MIMXRT1052.h:20681
I2S_TCR4_CHMOD
#define I2S_TCR4_CHMOD(x)
Definition: MIMXRT1052.h:20199
FSL_FEATURE_SAI_FIFO_COUNT
#define FSL_FEATURE_SAI_FIFO_COUNT
Definition: MIMXRT1052_features.h:537
I2S_RCSR_FWDE_MASK
#define I2S_RCSR_FWDE_MASK
Definition: MIMXRT1052.h:20312
kSAI_BusI2S
@ kSAI_BusI2S
Definition: fsl_sai.h:58
I2S_RCSR_FR_MASK
#define I2S_RCSR_FR_MASK
Definition: MIMXRT1052.h:20396
kSAI_ModeAsync
@ kSAI_ModeAsync
Definition: fsl_sai.h:99
I2S_RCR4_ONDEM_MASK
#define I2S_RCR4_ONDEM_MASK
Definition: MIMXRT1052.h:20532
I2S_RCSR_FRDE_MASK
#define I2S_RCSR_FRDE_MASK
Definition: MIMXRT1052.h:20305
I2S_TCR2_DIV_MASK
#define I2S_TCR2_DIV_MASK
Definition: MIMXRT1052.h:20084
SAI_WriteBlocking
void SAI_WriteBlocking(I2S_Type *base, uint32_t channel, uint32_t bitWidth, uint8_t *buffer, uint32_t size)
Sends data using a blocking method.
Definition: fsl_sai.c:2113
s_saiTxIRQ
static const IRQn_Type s_saiTxIRQ[]
Definition: fsl_sai.c:151
_sai_transceiver::syncMode
sai_sync_mode_t syncMode
Definition: fsl_sai.h:404
I2S_TCR4_ONDEM_MASK
#define I2S_TCR4_ONDEM_MASK
Definition: MIMXRT1052.h:20172
I2S_RCR2_BCI
#define I2S_RCR2_BCI(x)
Definition: MIMXRT1052.h:20478
_sai_transfer_format::sampleRate_Hz
uint32_t sampleRate_Hz
Definition: fsl_sai.h:272
I2S_TCR2_MSEL
#define I2S_TCR2_MSEL(x)
Definition: MIMXRT1052.h:20111
FSL_FEATURE_SAI_CHANNEL_COUNTn
#define FSL_FEATURE_SAI_CHANNEL_COUNTn(x)
Definition: MIMXRT1052_features.h:539
SAI_TransferRxCreateHandle
void SAI_TransferRxCreateHandle(I2S_Type *base, sai_handle_t *handle, sai_transfer_callback_t callback, void *userData)
Initializes the SAI Rx handle.
Definition: fsl_sai.c:2314
SAI_TransferAbortReceive
void SAI_TransferAbortReceive(I2S_Type *base, sai_handle_t *handle)
Aborts the current IRQ receive.
Definition: fsl_sai.c:2627
I2S_TCR5_W0W
#define I2S_TCR5_W0W(x)
Definition: MIMXRT1052.h:20248
SAI_ReadBlocking
void SAI_ReadBlocking(I2S_Type *base, uint32_t channel, uint32_t bitWidth, uint8_t *buffer, uint32_t size)
Receives data using a blocking method.
Definition: fsl_sai.c:2251
SAI_RxReset
void SAI_RxReset(I2S_Type *base)
Resets the SAI Rx.
Definition: fsl_sai.c:783
I2S_Type::TCSR
__IO uint32_t TCSR
Definition: MIMXRT1052.h:19870
I2S_RCR3_RCE
#define I2S_RCR3_RCE(x)
Definition: MIMXRT1052.h:20508
kSAI_BclkSourceMclkDiv
@ kSAI_BclkSourceMclkDiv
Definition: fsl_sai.h:127
_sai_config
SAI user configuration structure.
Definition: fsl_sai.h:188
SAI_RxSetConfig
void SAI_RxSetConfig(I2S_Type *base, sai_transceiver_t *config)
SAI receiver configurations.
Definition: fsl_sai.c:1562
I2S_Type::RCR5
__IO uint32_t RCR5
Definition: MIMXRT1052.h:19887
_sai_transceiver::channelNums
uint8_t channelNums
Definition: fsl_sai.h:409
_sai_handle::channelNums
uint8_t channelNums
Definition: fsl_sai.h:445
sai_rx_isr_t
void(* sai_rx_isr_t)(I2S_Type *base, sai_handle_t *saiHandle)
Typedef for sai rx interrupt handler.
Definition: fsl_sai.c:31
SAI_TxSetSerialDataConfig
void SAI_TxSetSerialDataConfig(I2S_Type *base, sai_serial_data_t *config)
SAI transmitter Serial data configurations.
Definition: fsl_sai.c:1377
I2S_TCR4_FCONT
#define I2S_TCR4_FCONT(x)
Definition: MIMXRT1052.h:20234
kSAI_Master
@ kSAI_Master
Definition: fsl_sai.h:66
kSAI_BusPCMA
@ kSAI_BusPCMA
Definition: fsl_sai.h:59
I2S_RCR2_BCS_MASK
#define I2S_RCR2_BCS_MASK
Definition: MIMXRT1052.h:20479
I2S_RCR5_WNW
#define I2S_RCR5_WNW(x)
Definition: MIMXRT1052.h:20606
SAI_TransferTxSetConfig
void SAI_TransferTxSetConfig(I2S_Type *base, sai_handle_t *handle, sai_transceiver_t *config)
SAI transmitter transfer configurations.
Definition: fsl_sai.c:1535
s_saiClock
static const clock_ip_name_t s_saiClock[]
Definition: fsl_sai.c:155
I2S_TCR4_FSE_MASK
#define I2S_TCR4_FSE_MASK
Definition: MIMXRT1052.h:20179
_sai_transfer_format::bitWidth
uint32_t bitWidth
Definition: fsl_sai.h:273
kSAI_Idle
@ kSAI_Idle
Definition: fsl_sai.c:25
_sai_serial_data::dataWordNum
uint8_t dataWordNum
Definition: fsl_sai.h:389
SAI_TxDisableInterrupts
static void SAI_TxDisableInterrupts(I2S_Type *base, uint32_t mask)
Disables the SAI Tx interrupt requests.
Definition: fsl_sai.h:1127
I2S_RCR4_FSD_MASK
#define I2S_RCR4_FSD_MASK
Definition: MIMXRT1052.h:20518
I2S_RCR4_FSP_MASK
#define I2S_RCR4_FSP_MASK
Definition: MIMXRT1052.h:20525
I2S_TCSR_FRIE_MASK
#define I2S_TCSR_FRIE_MASK
Definition: MIMXRT1052.h:19959
_sai_serial_data::dataWordLength
uint8_t dataWordLength
Definition: fsl_sai.h:386
I2S_TCR4_FRSZ_MASK
#define I2S_TCR4_FRSZ_MASK
Definition: MIMXRT1052.h:20205
I2S_TCR2_BCI
#define I2S_TCR2_BCI(x)
Definition: MIMXRT1052.h:20118
SAI_TxSetBitClockPolarity
void SAI_TxSetBitClockPolarity(I2S_Type *base, sai_clock_polarity_t polarity)
Set the Tx data order.
Definition: fsl_sai.c:957
SAI_TxSetFrameSyncConfig
void SAI_TxSetFrameSyncConfig(I2S_Type *base, sai_master_slave_t masterSlave, sai_frame_sync_t *config)
SAI transmitter Frame sync configurations.
Definition: fsl_sai.c:1310
_sai_transceiver::serialData
sai_serial_data_t serialData
Definition: fsl_sai.h:396
I2S_TCR3_WDFL_MASK
#define I2S_TCR3_WDFL_MASK
Definition: MIMXRT1052.h:20139
SAI_RxEnableInterrupts
static void SAI_RxEnableInterrupts(I2S_Type *base, uint32_t mask)
Enables the SAI Rx interrupt requests.
Definition: fsl_sai.h:1110
EnableIRQ
static status_t EnableIRQ(IRQn_Type interrupt)
Enable specific interrupt.
Definition: fsl_common.h:484
I2S_TCSR_FWDE_MASK
#define I2S_TCSR_FWDE_MASK
Definition: MIMXRT1052.h:19952
I2S_TCR2_BCP
#define I2S_TCR2_BCP(x)
Definition: MIMXRT1052.h:20102
_sai_serial_data::dataOrder
sai_data_order_t dataOrder
Definition: fsl_sai.h:383
I2S_TCR1_TFW_SHIFT
#define I2S_TCR1_TFW_SHIFT
Definition: MIMXRT1052.h:20076
SAI_RxInit
void SAI_RxInit(I2S_Type *base, const sai_config_t *config)
Initializes the SAI Rx peripheral.
Definition: fsl_sai.c:533
kSAI_MclkSourceSysclk
@ kSAI_MclkSourceSysclk
Definition: fsl_sai.h:111
I2S_RCR1_RFW_MASK
#define I2S_RCR1_RFW_MASK
Definition: MIMXRT1052.h:20435
I2S_RCR1_RFW
#define I2S_RCR1_RFW(x)
Definition: MIMXRT1052.h:20439
I2S_TCR1_TFW
#define I2S_TCR1_TFW(x)
Definition: MIMXRT1052.h:20079
I2S_TCR4_FSP_MASK
#define I2S_TCR4_FSP_MASK
Definition: MIMXRT1052.h:20165
_sai_transfer_format
sai transfer format
Definition: fsl_sai.h:270
I2S_TCR4_FCONT_MASK
#define I2S_TCR4_FCONT_MASK
Definition: MIMXRT1052.h:20228
I2S_RCR4_FPACK_MASK
#define I2S_RCR4_FPACK_MASK
Definition: MIMXRT1052.h:20563
_sai_handle
SAI handle structure.
Definition: fsl_sai.h:426
I2S_RCR2_SYNC_SHIFT
#define I2S_RCR2_SYNC_SHIFT
Definition: MIMXRT1052.h:20487
SAI_GetDSPConfig
void 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)
Get DSP mode configurations.
Definition: fsl_sai.c:1753
CLOCK_DisableClock
static void CLOCK_DisableClock(clock_ip_name_t name)
Disable the clock for specific IP.
Definition: fsl_clock.h:1069
s_saiRxIRQ
static const IRQn_Type s_saiRxIRQ[]
Definition: fsl_sai.c:152
_sai_transfer
SAI transfer structure.
Definition: fsl_sai.h:414
I2S_BASE_PTRS
#define I2S_BASE_PTRS
Definition: MIMXRT1052.h:20678
SAI_RxSetDataOrder
void SAI_RxSetDataOrder(I2S_Type *base, sai_data_order_t order)
Set the Rx data order.
Definition: fsl_sai.c:943
_sai_handle::base
I2S_Type * base
Definition: fsl_sai.h:428
kStatus_SAI_RxIdle
@ kStatus_SAI_RxIdle
Definition: fsl_sai.h:37
kStatus_SAI_TxError
@ kStatus_SAI_TxError
Definition: fsl_sai.h:33
_sai_bit_clock
sai bit clock configurations
Definition: fsl_sai.h:351
I2S_RCR5_FBT
#define I2S_RCR5_FBT(x)
Definition: MIMXRT1052.h:20596
SAI_TxSetConfig
void SAI_TxSetConfig(I2S_Type *base, sai_transceiver_t *config)
SAI transmitter configurations.
Definition: fsl_sai.c:1433
SAI_RxSoftwareReset
void SAI_RxSoftwareReset(I2S_Type *base, sai_reset_type_t type)
Do software reset or FIFO reset .
Definition: fsl_sai.c:889
I2S_Type::TCR2
__IO uint32_t TCR2
Definition: MIMXRT1052.h:19872
I2S_TCSR_SR_MASK
#define I2S_TCSR_SR_MASK
Definition: MIMXRT1052.h:20029
SAI_RxSetBitClockRate
void SAI_RxSetBitClockRate(I2S_Type *base, uint32_t sourceClockHz, uint32_t sampleRate, uint32_t bitWidth, uint32_t channelNumbers)
Receiver bit clock rate configurations.
Definition: fsl_sai.c:1095
I2S_TCR4_ONDEM
#define I2S_TCR4_ONDEM(x)
Definition: MIMXRT1052.h:20178
SAI_TxClearStatusFlags
static void SAI_TxClearStatusFlags(I2S_Type *base, uint32_t mask)
Clears the SAI Tx status flag state.
Definition: fsl_sai.h:890
_sai_handle::queueUser
volatile uint8_t queueUser
Definition: fsl_sai.h:449
I2S_TCSR_FR_MASK
#define I2S_TCSR_FR_MASK
Definition: MIMXRT1052.h:20036
s_saiRxIsr
static sai_rx_isr_t s_saiRxIsr
Pointer to tx IRQ handler for each instance.
Definition: fsl_sai.c:160
config
static sai_transceiver_t config
Definition: imxrt1050/imxrt1050-evkb/source/pv_audio_rec.c:75
SAI_TxReset
void SAI_TxReset(I2S_Type *base)
Resets the SAI Tx.
Definition: fsl_sai.c:760
_sai_handle::endChannel
uint8_t endChannel
Definition: fsl_sai.h:444
clock_ip_name_t
enum _clock_ip_name clock_ip_name_t
CCM CCGR gate control for each module independently.
I2S_TCR4_FSP
#define I2S_TCR4_FSP(x)
Definition: MIMXRT1052.h:20171
I2S_TCR4_FSD
#define I2S_TCR4_FSD(x)
Definition: MIMXRT1052.h:20164
_sai_transceiver::startChannel
uint8_t startChannel
Definition: fsl_sai.h:406
I2S_Type::RMR
__IO uint32_t RMR
Definition: MIMXRT1052.h:19892
I2S_TCR2_SYNC_MASK
#define I2S_TCR2_SYNC_MASK
Definition: MIMXRT1052.h:20126
kSAI_FIFOErrorFlag
@ kSAI_FIFOErrorFlag
Definition: fsl_sai.h:159
I2S_TCR3_TCE_MASK
#define I2S_TCR3_TCE_MASK
Definition: MIMXRT1052.h:20144
kSAI_Busy
@ kSAI_Busy
Definition: fsl_sai.c:24
I2S_TCR2_BCP_MASK
#define I2S_TCR2_BCP_MASK
Definition: MIMXRT1052.h:20096
I2S_Type::RCR2
__IO uint32_t RCR2
Definition: MIMXRT1052.h:19884
SAI_RxSetChannelFIFOMask
void SAI_RxSetChannelFIFOMask(I2S_Type *base, uint8_t mask)
Set the Rx channel FIFO enable mask.
Definition: fsl_sai.c:917
I2S_Type::RDR
__I uint32_t RDR[4]
Definition: MIMXRT1052.h:19888
SAI2
#define SAI2
Definition: MIMXRT1052.h:20670
I2S_RX_IRQS
#define I2S_RX_IRQS
Definition: MIMXRT1052.h:20680
I2S_TCR2_BCS
#define I2S_TCR2_BCS(x)
Definition: MIMXRT1052.h:20125
SAI_TxSetDataOrder
void SAI_TxSetDataOrder(I2S_Type *base, sai_data_order_t order)
Set the Tx data order.
Definition: fsl_sai.c:929
kSAI_Error
@ kSAI_Error
Definition: fsl_sai.c:26
sai_transfer_callback_t
void(* sai_transfer_callback_t)(I2S_Type *base, sai_handle_t *handle, status_t status, void *userData)
SAI transfer callback prototype.
Definition: fsl_sai.h:423
kStatus_SAI_TxIdle
@ kStatus_SAI_TxIdle
Definition: fsl_sai.h:36
status_t
int32_t status_t
Type used for all status and error return values.
Definition: fsl_common.h:189
I2S_RCR2_BCP_MASK
#define I2S_RCR2_BCP_MASK
Definition: MIMXRT1052.h:20456
kSAI_FrameSyncLenPerWordWidth
@ kSAI_FrameSyncLenPerWordWidth
Definition: fsl_sai.h:266
I2S2
#define I2S2
Definition: stm32f4_discovery_audio.h:115
SAI_TxSetFormat
void SAI_TxSetFormat(I2S_Type *base, sai_transfer_format_t *format, uint32_t mclkSourceClockHz, uint32_t bclkSourceClockHz)
Configures the SAI Tx audio format.
Definition: fsl_sai.c:1829
I2S_TCR2_SYNC_SHIFT
#define I2S_TCR2_SYNC_SHIFT
Definition: MIMXRT1052.h:20127
_sai_frame_sync::frameSyncWidth
uint8_t frameSyncWidth
Definition: fsl_sai.h:364
_sai_bit_clock::bclkPolarity
sai_clock_polarity_t bclkPolarity
Definition: fsl_sai.h:357
I2S_Type::TMR
__IO uint32_t TMR
Definition: MIMXRT1052.h:19880
kStatus_Success
@ kStatus_Success
Definition: fsl_common.h:179
I2S_Type::TCR1
__IO uint32_t TCR1
Definition: MIMXRT1052.h:19871
I2S_TCR2_SYNC
#define I2S_TCR2_SYNC(x)
Definition: MIMXRT1052.h:20134
SAI_RxSetBitClockPolarity
void SAI_RxSetBitClockPolarity(I2S_Type *base, sai_clock_polarity_t polarity)
Set the Rx data order.
Definition: fsl_sai.c:971
I2S_TCR4_FSD_MASK
#define I2S_TCR4_FSD_MASK
Definition: MIMXRT1052.h:20158
I2S_RCR4_ONDEM
#define I2S_RCR4_ONDEM(x)
Definition: MIMXRT1052.h:20538
SAI_ReadNonBlocking
static void SAI_ReadNonBlocking(I2S_Type *base, uint32_t channel, uint32_t channelMask, uint32_t endChannel, uint8_t bitWidth, uint8_t *buffer, uint32_t size)
Receive a piece of data in non-blocking way.
Definition: fsl_sai.c:310
SAI_GetClassicI2SConfig
void SAI_GetClassicI2SConfig(sai_transceiver_t *config, sai_word_width_t bitWidth, sai_mono_stereo_t mode, uint32_t saiChannelMask)
Get classic I2S mode configurations.
Definition: fsl_sai.c:1693
I2S_TCR4_FPACK_MASK
#define I2S_TCR4_FPACK_MASK
Definition: MIMXRT1052.h:20210
SAI_Init
void SAI_Init(I2S_Type *base)
Initializes the SAI peripheral.
Definition: fsl_sai.c:648
SAI_TxEnable
void SAI_TxEnable(I2S_Type *base, bool enable)
Enables/disables the SAI Tx.
Definition: fsl_sai.c:805
kSAI_SampleOnRisingEdge
@ kSAI_SampleOnRisingEdge
Definition: fsl_sai.h:93
SAI_TransferSendNonBlocking
status_t SAI_TransferSendNonBlocking(I2S_Type *base, sai_handle_t *handle, sai_transfer_t *xfer)
Performs an interrupt non-blocking send transfer on SAI.
Definition: fsl_sai.c:2449
SAI_ReadMultiChannelBlocking
void SAI_ReadMultiChannelBlocking(I2S_Type *base, uint32_t channel, uint32_t channelMask, uint32_t bitWidth, uint8_t *buffer, uint32_t size)
Receives multi channel data using a blocking method.
Definition: fsl_sai.c:2205
SAI_TxGetDefaultConfig
void SAI_TxGetDefaultConfig(sai_config_t *config)
Sets the SAI Tx configuration structure to default values.
Definition: fsl_sai.c:702
I2S_TCR4_MF_MASK
#define I2S_TCR4_MF_MASK
Definition: MIMXRT1052.h:20186
_sai_handle::bitWidth
uint8_t bitWidth
Definition: fsl_sai.h:433
I2S_Type::TCR3
__IO uint32_t TCR3
Definition: MIMXRT1052.h:19873
I2S_RCR5_W0W
#define I2S_RCR5_W0W(x)
Definition: MIMXRT1052.h:20601
MIN
#define MIN(a, b)
Definition: fsl_common.h:201


picovoice_driver
Author(s):
autogenerated on Fri Apr 1 2022 02:13:56