1 /*
2 * Copyright 2021 NXP
3 * All rights reserved.
4 *
5 *
6 * SPDX-License-Identifier: BSD-3-Clause
7 */
8
9 #include "fsl_common.h"
10 #if (defined(FSL_FEATURE_SOC_EDMA_COUNT) && (FSL_FEATURE_SOC_EDMA_COUNT > 0U))
11 #if (defined(FSL_FEATURE_SOC_DMAMUX_COUNT) && (FSL_FEATURE_SOC_DMAMUX_COUNT > 0U))
12 #include "fsl_dmamux.h"
13 #endif /* FSL_FEATURE_SOC_DMAMUX_COUNT */
14 #include "fsl_edma.h"
15 #include "fsl_sai.h"
16 #include "fsl_sai_edma.h"
17 #elif (defined(FSL_FEATURE_SOC_DMA_COUNT) && (FSL_FEATURE_SOC_DMA_COUNT > 0U))
18 #include "fsl_dma.h"
19 #include "fsl_sai.h"
20 #include "fsl_sai_dma.h"
21 #else
22 #endif /* FSL_FEATURE_SOC_EDMA_COUNT or FSL_FEATURE_SOC_DMA_COUNT */
23 #include "fsl_adapter_audio.h"
24
25 /*******************************************************************************
26 * Definitions
27 ******************************************************************************/
28
29 /*! @brief hal audio state structure. */
30 typedef struct _hal_audio_state
31 {
32 hal_audio_transfer_callback_t callback;
33 void *callbackParam;
34 #if (defined(FSL_FEATURE_SOC_EDMA_COUNT) && (FSL_FEATURE_SOC_EDMA_COUNT > 0U))
35 sai_edma_handle_t xferDmaHandle;
36 edma_handle_t dmaHandle;
37 #elif (defined(FSL_FEATURE_SOC_DMA_COUNT) && (FSL_FEATURE_SOC_DMA_COUNT > 0U))
38 sai_dma_handle_t xferDmaHandle;
39 dma_handle_t dmaHandle;
40 #else
41 #endif
42 #if (defined(FSL_FEATURE_SOC_EDMA_COUNT) && (FSL_FEATURE_SOC_EDMA_COUNT > 0U))
43 #if (defined(FSL_FEATURE_SOC_DMAMUX_COUNT) && (FSL_FEATURE_SOC_DMAMUX_COUNT > 0U))
44 uint8_t dmaMuxInstance;
45 #endif /* FSL_FEATURE_SOC_DMAMUX_COUNT */
46 #endif /* FSL_FEATURE_SOC_EDMA_COUNT */
47 uint8_t dmaInstance;
48 uint8_t dmaChannel;
49 uint8_t instance;
50 uint8_t occupied;
51 } hal_audio_state_t;
52
53 /*******************************************************************************
54 * Prototypes
55 ******************************************************************************/
56
57 /*******************************************************************************
58 * Variables
59 ******************************************************************************/
60
61 /*! @brief Pointers to audio bases for each instance. */
62 static I2S_Type *const s_i2sBases[] = I2S_BASE_PTRS;
63 /*! @brief Resource for each i2s instance. */
64 static uint8_t s_i2sOccupied[ARRAY_SIZE(s_i2sBases)];
65 #if (defined(HAL_AUDIO_DMA_INIT_ENABLE) && (HAL_AUDIO_DMA_INIT_ENABLE > 0U))
66 /*! @brief Resource for each dma instance. */
67 static uint8_t s_dmaOccupied[ARRAY_SIZE((DMA_Type *[])DMA_BASE_PTRS)];
68 #if (defined(FSL_FEATURE_SOC_EDMA_COUNT) && (FSL_FEATURE_SOC_EDMA_COUNT > 0U))
69 #if (defined(FSL_FEATURE_SOC_DMAMUX_COUNT) && (FSL_FEATURE_SOC_DMAMUX_COUNT > 0U))
70 /*! @brief Resource for each dma mux instance. */
71 static uint8_t s_dmaMuxOccupied[ARRAY_SIZE((DMAMUX_Type *[])DMAMUX_BASE_PTRS)];
72 #endif /* FSL_FEATURE_SOC_DMAMUX_COUNT */
73 #endif /* FSL_FEATURE_SOC_EDMA_COUNT */
74 #endif /* HAL_AUDIO_DMA_INIT_ENABLE */
75
76 /*******************************************************************************
77 * Code
78 ******************************************************************************/
79
80 #if (defined(FSL_FEATURE_SOC_I2S_COUNT) && (FSL_FEATURE_SOC_I2S_COUNT > 0U))
HAL_AudioFifoErrorIsr(I2S_Type * base)81 static void HAL_AudioFifoErrorIsr(I2S_Type *base)
82 {
83 if (0U != (base->TCSR & (uint32_t)kSAI_FIFOErrorFlag))
84 {
85 /* Clear the FIFO error flag */
86 SAI_TxClearStatusFlags(base, kSAI_FIFOErrorFlag);
87 /* Reset FIFO */
88 SAI_TxSoftwareReset(base, kSAI_ResetTypeFIFO);
89 }
90
91 if (0U != (base->RCSR & (uint32_t)kSAI_FIFOErrorFlag))
92 {
93 /* Clear the FIFO error flag */
94 SAI_RxClearStatusFlags(base, kSAI_FIFOErrorFlag);
95 /* Reset FIFO */
96 SAI_RxSoftwareReset(base, kSAI_ResetTypeFIFO);
97 }
98
99 SDK_ISR_EXIT_BARRIER;
100 }
101 #endif
102
103 /* IRQHandler for I2S0 */
104 #if defined(I2S0) && (FSL_FEATURE_SOC_I2S_COUNT > 0U)
105 void I2S0_Tx_IRQHandler(void);
106 void I2S0_Rx_IRQHandler(void);
I2S0_Tx_IRQHandler(void)107 void I2S0_Tx_IRQHandler(void)
108 {
109 HAL_AudioFifoErrorIsr(I2S0);
110 }
I2S0_Rx_IRQHandler(void)111 void I2S0_Rx_IRQHandler(void)
112 {
113 HAL_AudioFifoErrorIsr(I2S0);
114 }
115 #endif
116
117 /* IRQHandler for SAI1 */
118 #if defined(SAI1) && (FSL_FEATURE_SOC_I2S_COUNT > 0U)
119 void SAI1_IRQHandler(void);
SAI1_IRQHandler(void)120 void SAI1_IRQHandler(void)
121 {
122 HAL_AudioFifoErrorIsr(SAI1);
123 }
124 #endif
125
126 /* IRQHandler for SAI2 */
127 #if defined(SAI2) && (FSL_FEATURE_SOC_I2S_COUNT > 0U)
128 void SAI2_IRQHandler(void);
SAI2_IRQHandler(void)129 void SAI2_IRQHandler(void)
130 {
131 HAL_AudioFifoErrorIsr(SAI2);
132 }
133 #endif
134
135 /* IRQHandler for SAI3 */
136 #if defined(SAI3) && (FSL_FEATURE_SOC_I2S_COUNT > 0U)
137 void SAI3_IRQHandler(void);
138 void SAI3_TX_IRQHandler(void);
139 void SAI3_RX_IRQHandler(void);
SAI3_IRQHandler(void)140 void SAI3_IRQHandler(void)
141 {
142 HAL_AudioFifoErrorIsr(SAI3);
143 }
SAI3_TX_IRQHandler(void)144 void SAI3_TX_IRQHandler(void)
145 {
146 HAL_AudioFifoErrorIsr(SAI3);
147 }
SAI3_RX_IRQHandler(void)148 void SAI3_RX_IRQHandler(void)
149 {
150 HAL_AudioFifoErrorIsr(SAI3);
151 }
152 #endif
153
154 /* IRQHandler for SAI4 */
155 #if defined(SAI4) && (FSL_FEATURE_SOC_I2S_COUNT > 0U)
156 void SAI4_IRQHandler(void);
157 void SAI4_TX_IRQHandler(void);
158 void SAI4_RX_IRQHandler(void);
SAI4_IRQHandler(void)159 void SAI4_IRQHandler(void)
160 {
161 HAL_AudioFifoErrorIsr(SAI4);
162 }
SAI4_TX_IRQHandler(void)163 void SAI4_TX_IRQHandler(void)
164 {
165 HAL_AudioFifoErrorIsr(SAI4);
166 }
SAI4_RX_IRQHandler(void)167 void SAI4_RX_IRQHandler(void)
168 {
169 HAL_AudioFifoErrorIsr(SAI4);
170 }
171 #endif
172
HAL_AudioGetStatus(status_t status)173 static hal_audio_status_t HAL_AudioGetStatus(status_t status)
174 {
175 hal_audio_status_t returnStatus;
176 switch (status)
177 {
178 case kStatus_Success:
179 returnStatus = kStatus_HAL_AudioSuccess;
180 break;
181
182 case kStatus_SAI_TxBusy:
183 case kStatus_SAI_RxBusy:
184 returnStatus = kStatus_HAL_AudioBusy;
185 break;
186
187 case kStatus_SAI_TxIdle:
188 case kStatus_SAI_RxIdle:
189 case kStatus_NoTransferInProgress:
190 returnStatus = kStatus_HAL_AudioIdle;
191 break;
192
193 case kStatus_SAI_QueueFull:
194 returnStatus = kStatus_HAL_AudioQueueFull;
195 break;
196
197 default:
198 returnStatus = kStatus_HAL_AudioError;
199 break;
200 }
201 return returnStatus;
202 }
203
204 #if (defined(FSL_FEATURE_SOC_EDMA_COUNT) && (FSL_FEATURE_SOC_EDMA_COUNT > 0U))
HAL_AudioCallbackEDMA(I2S_Type * base,sai_edma_handle_t * handle,status_t status,void * userData)205 static void HAL_AudioCallbackEDMA(I2S_Type *base, sai_edma_handle_t *handle, status_t status, void *userData)
206 {
207 hal_audio_state_t *audioHandle;
208
209 assert(userData);
210
211 audioHandle = (hal_audio_state_t *)userData;
212
213 if (NULL != audioHandle->callback)
214 {
215 audioHandle->callback(audioHandle, HAL_AudioGetStatus(status), audioHandle->callbackParam);
216 }
217 }
218 #elif (defined(FSL_FEATURE_SOC_DMA_COUNT) && (FSL_FEATURE_SOC_DMA_COUNT > 0U))
HAL_AudioCallbackDMA(I2S_Type * base,sai_dma_handle_t * handle,status_t status,void * userData)219 static void HAL_AudioCallbackDMA(I2S_Type *base, sai_dma_handle_t *handle, status_t status, void *userData)
220 {
221 hal_audio_state_t *audioHandle;
222
223 assert(userData);
224
225 audioHandle = (hal_audio_state_t *)userData;
226
227 if (NULL != audioHandle->callback)
228 {
229 audioHandle->callback(audioHandle, HAL_AudioGetStatus(status), audioHandle->callbackParam);
230 }
231 }
232 #else
233 #endif
234
HAL_AudioCommonInit(hal_audio_handle_t handle,const hal_audio_config_t * config,bool direction)235 static hal_audio_status_t HAL_AudioCommonInit(hal_audio_handle_t handle,
236 const hal_audio_config_t *config,
237 bool direction)
238 {
239 hal_audio_state_t *audioHandle;
240 sai_transceiver_t saiConfig;
241 hal_audio_dma_config_t *dmaConfig;
242 hal_audio_ip_config_t *featureConfig;
243 #if (defined(FSL_FEATURE_SOC_EDMA_COUNT) && (FSL_FEATURE_SOC_EDMA_COUNT > 0U) && \
244 (defined(FSL_EDMA_SOC_IP_DMA3) && (FSL_EDMA_SOC_IP_DMA3 > 0) || \
245 defined(FSL_EDMA_SOC_IP_DMA4) && (FSL_EDMA_SOC_IP_DMA4 > 0)))
246 EDMA_Type *dmaBases[] = EDMA_BASE_PTRS;
247 #else
248 DMA_Type *dmaBases[] = DMA_BASE_PTRS;
249 #endif /* FSL_FEATURE_SOC_EDMA_COUNT */
250 IRQn_Type txIrqNumber[] = I2S_TX_IRQS;
251 IRQn_Type rxIrqNumber[] = I2S_RX_IRQS;
252 #if (defined(FSL_FEATURE_SOC_EDMA_COUNT) && (FSL_FEATURE_SOC_EDMA_COUNT > 0U))
253 #if (defined(FSL_EDMA_SOC_IP_DMA3) && (FSL_EDMA_SOC_IP_DMA3 > 0) || \
254 defined(FSL_EDMA_SOC_IP_DMA4) && (FSL_EDMA_SOC_IP_DMA4 > 0))
255 IRQn_Type dmaIrqNumber[][FSL_FEATURE_EDMA_MODULE_CHANNEL] = EDMA_CHN_IRQS;
256 #else
257 IRQn_Type dmaIrqNumber[][FSL_FEATURE_EDMA_MODULE_CHANNEL] = DMA_CHN_IRQS;
258 #endif
259 #if (defined(HAL_AUDIO_DMA_INIT_ENABLE) && (HAL_AUDIO_DMA_INIT_ENABLE > 0U))
260 edma_config_t audioDmaConfig;
261 #endif /* HAL_AUDIO_DMA_INIT_ENABLE */
262 edma_channel_Preemption_config_t preemptionConfig;
263 #if (defined(FSL_FEATURE_SOC_DMAMUX_COUNT) && (FSL_FEATURE_SOC_DMAMUX_COUNT > 0U))
264 DMAMUX_Type *dmaMuxBases[] = DMAMUX_BASE_PTRS;
265 hal_audio_dma_mux_config_t *dmaMuxConfig;
266 #endif /* FSL_FEATURE_SOC_DMAMUX_COUNT */
267 #elif (defined(FSL_FEATURE_SOC_DMA_COUNT) && (FSL_FEATURE_SOC_DMA_COUNT > 0U))
268 IRQn_Type dmaIrqNumber[][FSL_FEATURE_DMA_MODULE_CHANNEL] = DMA_CHN_IRQS;
269 #else
270 #endif /* FSL_FEATURE_SOC_EDMA_COUNT or FSL_FEATURE_SOC_DMA_COUNT */
271
272 #if (defined(FSL_FEATURE_SAI_HAS_FIFO_COMBINE_MODE) && (FSL_FEATURE_SAI_HAS_FIFO_COMBINE_MODE > 0U))
273 uint32_t u32Temp;
274 uint8_t lineNum;
275 #endif /* FSL_FEATURE_SAI_HAS_FIFO_COMBINE_MODE */
276 uint8_t channelNum;
277
278 assert(handle);
279 assert(config);
280 assert(config->dmaConfig);
281 assert(config->ipConfig);
282 /* If asserted, please check if the value of SAI_XFER_QUEUE_SIZE defined in the fsl_sai.h is modified.
283 If modified, please modify the value of HAL_AUDIO_QUEUE_SIZE defined in the fsl_adapter_audio.h to be the same as
284 SAI_XFER_QUEUE_SIZE. */
285 assert(HAL_AUDIO_HANDLE_SIZE >= sizeof(hal_audio_state_t));
286 assert(config->instance < ARRAY_SIZE(s_i2sBases));
287 assert(config->dmaConfig->instance < ARRAY_SIZE(dmaBases));
288
289 dmaConfig = (hal_audio_dma_config_t *)config->dmaConfig;
290 featureConfig = (hal_audio_ip_config_t *)config->ipConfig;
291 audioHandle = (hal_audio_state_t *)handle;
292
293 assert(featureConfig->sai.lineMask != 0U);
294
295 if (audioHandle->occupied != 0U)
296 {
297 return kStatus_HAL_AudioSuccess;
298 }
299
300 audioHandle->instance = config->instance;
301 audioHandle->dmaInstance = dmaConfig->instance;
302 audioHandle->dmaChannel = dmaConfig->channel;
303 audioHandle->occupied = 1;
304
305 SAI_GetClassicI2SConfig(&saiConfig, (sai_word_width_t)config->bitWidth, kSAI_Stereo, featureConfig->sai.lineMask);
306
307 #if (defined(FSL_FEATURE_SAI_HAS_FIFO_COMBINE_MODE) && (FSL_FEATURE_SAI_HAS_FIFO_COMBINE_MODE > 0U))
308 lineNum = 0;
309 u32Temp = featureConfig->sai.lineMask;
310 while (u32Temp > 0U)
311 {
312 u32Temp &= u32Temp - 1U;
313 lineNum++;
314 }
315
316 if (lineNum > 1U)
317 {
318 saiConfig.fifo.fifoCombine = kSAI_FifoCombineModeEnabledOnWrite;
319 }
320 #endif /* FSL_FEATURE_SAI_HAS_FIFO_COMBINE_MODE */
321
322 #if (defined(FSL_FEATURE_SAI_HAS_FIFO) && (FSL_FEATURE_SAI_HAS_FIFO > 0U))
323 if (config->fifoWatermark < (uint16_t)FSL_FEATURE_SAI_FIFO_COUNTn(s_i2sBases[audioHandle->instance]))
324 {
325 saiConfig.fifo.fifoWatermark = (uint8_t)config->fifoWatermark;
326 }
327 else
328 {
329 saiConfig.fifo.fifoWatermark = (uint8_t)FSL_FEATURE_SAI_FIFO_COUNTn(s_i2sBases[audioHandle->instance]) - 1U;
330 }
331 #endif /* FSL_FEATURE_SAI_HAS_FIFO */
332
333 if ((uint8_t)config->bclkPolarity == (uint8_t)kHAL_AudioSampleOnFallingEdge)
334 {
335 saiConfig.bitClock.bclkPolarity = kSAI_SampleOnFallingEdge;
336 }
337 else
338 {
339 saiConfig.bitClock.bclkPolarity = kSAI_SampleOnRisingEdge;
340 }
341
342 channelNum = (uint8_t)config->lineChannels;
343
344 if (channelNum == (uint8_t)kHAL_AudioMono)
345 {
346 saiConfig.frameSync.frameSyncWidth = config->bitWidth >> 1U;
347 saiConfig.serialData.dataWordNum = 1U;
348 channelNum = 1;
349 }
350 else if (channelNum < (uint8_t)kHAL_AudioStereo)
351 {
352 saiConfig.frameSync.frameSyncWidth = config->bitWidth;
353 saiConfig.serialData.dataWordNum = 2U;
354 saiConfig.serialData.dataMaskedWord = 0x1UL << channelNum;
355 channelNum = 2;
356 }
357 else
358 {
359 saiConfig.frameSync.frameSyncWidth = config->bitWidth * channelNum >> 1U;
360 saiConfig.serialData.dataWordNum = channelNum;
361 }
362
363 if ((uint8_t)featureConfig->sai.syncMode == (uint8_t)kHAL_AudioSaiModeAsync)
364 {
365 saiConfig.syncMode = kSAI_ModeAsync;
366 }
367 else
368 {
369 saiConfig.syncMode = kSAI_ModeSync;
370 }
371
372 switch (config->masterSlave)
373 {
374 case kHAL_AudioMaster:
375 saiConfig.masterSlave = kSAI_Master;
376 break;
377
378 case kHAL_AudioSlave:
379 saiConfig.masterSlave = kSAI_Slave;
380 break;
381
382 case kHAL_AudioBclkMasterFrameSyncSlave:
383 saiConfig.masterSlave = kSAI_Bclk_Master_FrameSync_Slave;
384 break;
385
386 case kHAL_AudioBclkSlaveFrameSyncMaster:
387 saiConfig.masterSlave = kSAI_Bclk_Slave_FrameSync_Master;
388 break;
389
390 default:
391 assert(false);
392 break;
393 }
394
395 switch (config->dataFormat)
396 {
397 case kHAL_AudioDataFormatI2sClassic:
398 saiConfig.frameSync.frameSyncEarly = true;
399 saiConfig.frameSync.frameSyncPolarity = kSAI_PolarityActiveLow;
400 break;
401
402 case kHAL_AudioDataFormatLeftJustified:
403 saiConfig.frameSync.frameSyncEarly = false;
404 saiConfig.frameSync.frameSyncPolarity = kSAI_PolarityActiveHigh;
405 break;
406
407 case kHAL_AudioDataFormatRightJustified:
408 saiConfig.frameSync.frameSyncEarly = false;
409 saiConfig.frameSync.frameSyncPolarity = kSAI_PolarityActiveHigh;
410 break;
411
412 case kHAL_AudioDataFormatDspModeA:
413 saiConfig.frameSync.frameSyncEarly = true;
414 saiConfig.frameSync.frameSyncPolarity = kSAI_PolarityActiveHigh;
415 if ((uint8_t)config->frameSyncWidth == (uint8_t)kHAL_AudioFrameSyncWidthOneBitClk)
416 {
417 saiConfig.frameSync.frameSyncWidth = 1;
418 }
419 else if ((uint8_t)config->frameSyncWidth == (uint8_t)kHAL_AudioFrameSyncWidthPerWordWidth)
420 {
421 saiConfig.frameSync.frameSyncWidth = config->bitWidth;
422 }
423 else
424 {
425 /* no action */
426 }
427 break;
428
429 case kHAL_AudioDataFormatDspModeB:
430 saiConfig.frameSync.frameSyncEarly = false;
431 saiConfig.frameSync.frameSyncPolarity = kSAI_PolarityActiveHigh;
432 if ((uint8_t)config->frameSyncWidth == (uint8_t)kHAL_AudioFrameSyncWidthOneBitClk)
433 {
434 saiConfig.frameSync.frameSyncWidth = 1;
435 }
436 else if ((uint8_t)config->frameSyncWidth == (uint8_t)kHAL_AudioFrameSyncWidthPerWordWidth)
437 {
438 saiConfig.frameSync.frameSyncWidth = config->bitWidth;
439 }
440 else
441 {
442 /* no action */
443 }
444 break;
445
446 default:
447 assert(false);
448 break;
449 }
450
451 if (s_i2sOccupied[audioHandle->instance] == 0U)
452 {
453 SAI_Init(s_i2sBases[audioHandle->instance]);
454 }
455 s_i2sOccupied[audioHandle->instance]++;
456
457 #if (defined(FSL_FEATURE_SOC_EDMA_COUNT) && (FSL_FEATURE_SOC_EDMA_COUNT > 0U))
458 #if (defined(FSL_FEATURE_SOC_DMAMUX_COUNT) && (FSL_FEATURE_SOC_DMAMUX_COUNT > 0U))
459 assert(dmaConfig->dmaMuxConfig);
460
461 dmaMuxConfig = (hal_audio_dma_mux_config_t *)dmaConfig->dmaMuxConfig;
462
463 audioHandle->dmaMuxInstance = dmaMuxConfig->dmaMuxConfig.dmaMuxInstance;
464
465 #if (defined(HAL_AUDIO_DMA_INIT_ENABLE) && (HAL_AUDIO_DMA_INIT_ENABLE > 0U))
466 if (s_dmaMuxOccupied[audioHandle->dmaMuxInstance] == 0U)
467 {
468 DMAMUX_Init(dmaMuxBases[audioHandle->dmaMuxInstance]);
469 }
470 s_dmaMuxOccupied[audioHandle->dmaMuxInstance]++;
471 #endif /* HAL_AUDIO_DMA_INIT_ENABLE */
472
473 DMAMUX_SetSource(dmaMuxBases[audioHandle->dmaMuxInstance], dmaConfig->channel,
474 (int32_t)dmaMuxConfig->dmaMuxConfig.dmaRequestSource);
475
476 DMAMUX_EnableChannel(dmaMuxBases[audioHandle->dmaMuxInstance], dmaConfig->channel);
477 #endif /* FSL_FEATURE_SOC_DMAMUX_COUNT */
478
479 #if (defined(HAL_AUDIO_DMA_INIT_ENABLE) && (HAL_AUDIO_DMA_INIT_ENABLE > 0U))
480 EDMA_GetDefaultConfig(&audioDmaConfig);
481 #if (defined(FSL_FEATURE_EDMA_HAS_GLOBAL_MASTER_ID_REPLICATION) && \
482 (FSL_FEATURE_EDMA_HAS_GLOBAL_MASTER_ID_REPLICATION > 0U))
483 if (dmaConfig->dmaExtraConfig != NULL)
484 {
485 audioDmaConfig.enableMasterIdReplication =
486 ((hal_audio_dma_extra_config_t *)dmaConfig->dmaExtraConfig)->edmaExtraConfig.enableMasterIdReplication;
487 }
488 #endif /* FSL_FEATURE_EDMA_HAS_GLOBAL_MASTER_ID_REPLICATION */
489 if (s_dmaOccupied[dmaConfig->instance] == 0U)
490 {
491 EDMA_Init(dmaBases[dmaConfig->instance], &audioDmaConfig);
492 }
493 s_dmaOccupied[dmaConfig->instance]++;
494 #endif /* HAL_AUDIO_DMA_INIT_ENABLE */
495
496 #if (defined(FSL_FEATURE_EDMA_HAS_CHANNEL_CONFIG) && (FSL_FEATURE_EDMA_HAS_CHANNEL_CONFIG > 0U))
497 if (dmaConfig->dmaChannelConfig != NULL)
498 {
499 EDMA_InitChannel(dmaBases[dmaConfig->instance], dmaConfig->channel, dmaConfig->dmaChannelConfig);
500 }
501 #endif /* FSL_FEATURE_EDMA_HAS_CHANNEL_CONFIG */
502
503 NVIC_SetPriority((IRQn_Type)dmaIrqNumber[dmaConfig->instance][dmaConfig->channel], HAL_AUDIO_ISR_PRIORITY);
504 EDMA_CreateHandle(&audioHandle->dmaHandle, dmaBases[dmaConfig->instance], dmaConfig->channel);
505
506 #if (defined(FSL_FEATURE_EDMA_HAS_CHANNEL_MUX) && (FSL_FEATURE_EDMA_HAS_CHANNEL_MUX > 0U))
507 assert(dmaConfig->dmaChannelMuxConfig);
508 EDMA_SetChannelMux(dmaBases[dmaConfig->instance], dmaConfig->channel,
509 (int32_t)((hal_audio_dma_channel_mux_config_t *)dmaConfig->dmaChannelMuxConfig)
510 ->dmaChannelMuxConfig.dmaRequestSource);
511 #endif /* FSL_FEATURE_EDMA_HAS_CHANNEL_MUX */
512
513 if ((uint8_t)kHAL_AudioDmaChannelPriorityDefault != (uint8_t)dmaConfig->priority)
514 {
515 preemptionConfig.enableChannelPreemption = dmaConfig->enablePreemption;
516 preemptionConfig.enablePreemptAbility = dmaConfig->enablePreemptAbility;
517 preemptionConfig.channelPriority = (uint8_t)dmaConfig->priority;
518 EDMA_SetChannelPreemptionConfig(dmaBases[dmaConfig->instance], dmaConfig->channel, &preemptionConfig);
519 }
520
521 if (direction)
522 {
523 SAI_TransferTxCreateHandleEDMA(s_i2sBases[audioHandle->instance], &audioHandle->xferDmaHandle,
524 HAL_AudioCallbackEDMA, audioHandle, &audioHandle->dmaHandle);
525 SAI_TransferTxSetConfigEDMA(s_i2sBases[audioHandle->instance], &audioHandle->xferDmaHandle, &saiConfig);
526 }
527 else
528 {
529 SAI_TransferRxCreateHandleEDMA(s_i2sBases[audioHandle->instance], &audioHandle->xferDmaHandle,
530 HAL_AudioCallbackEDMA, audioHandle, &audioHandle->dmaHandle);
531 SAI_TransferRxSetConfigEDMA(s_i2sBases[audioHandle->instance], &audioHandle->xferDmaHandle, &saiConfig);
532 }
533
534 #elif (defined(FSL_FEATURE_SOC_DMA_COUNT) && (FSL_FEATURE_SOC_DMA_COUNT > 0U))
535 #if (defined(HAL_AUDIO_DMA_INIT_ENABLE) && (HAL_AUDIO_DMA_INIT_ENABLE > 0U))
536 if (s_dmaOccupied[dmaConfig->instance] == 0U)
537 {
538 DMA_Init(dmaBases[dmaConfig->instance]);
539 }
540 s_dmaOccupied[dmaConfig->instance]++;
541 #endif /* HAL_AUDIO_DMA_INIT_ENABLE */
542
543 NVIC_SetPriority((IRQn_Type)dmaIrqNumber[dmaConfig->instance][dmaConfig->channel], HAL_AUDIO_ISR_PRIORITY);
544 DMA_CreateHandle(&audioHandle->dmaHandle, dmaBases[dmaConfig->instance], dmaConfig->channel);
545
546 if (direction)
547 {
548 SAI_TransferTxCreateHandleDMA(s_i2sBases[audioHandle->instance], &audioHandle->xferDmaHandle,
549 HAL_AudioCallbackDMA, audioHandle, &audioHandle->dmaHandle);
550 SAI_TransferTxSetConfigDMA(s_i2sBases[audioHandle->instance], &audioHandle->xferDmaHandle, &saiConfig);
551 }
552 else
553 {
554 SAI_TransferRxCreateHandleDMA(s_i2sBases[audioHandle->instance], &audioHandle->xferDmaHandle,
555 HAL_AudioCallbackDMA, audioHandle, &audioHandle->dmaHandle);
556 SAI_TransferRxSetConfigDMA(s_i2sBases[audioHandle->instance], &audioHandle->xferDmaHandle, &saiConfig);
557 }
558 #else
559 #endif /* FSL_FEATURE_SOC_EDMA_COUNT or FSL_FEATURE_SOC_DMA_COUNT */
560
561 if (direction)
562 {
563 SAI_TxSetBitClockRate(s_i2sBases[audioHandle->instance], config->srcClock_Hz, config->sampleRate_Hz,
564 config->bitWidth, channelNum);
565
566 (void)EnableIRQ(txIrqNumber[audioHandle->instance]);
567
568 SAI_TxEnableInterrupts(s_i2sBases[audioHandle->instance], kSAI_FIFOErrorInterruptEnable);
569 }
570 else
571 {
572 SAI_RxSetBitClockRate(s_i2sBases[audioHandle->instance], config->srcClock_Hz, config->sampleRate_Hz,
573 config->bitWidth, channelNum);
574
575 (void)EnableIRQ(rxIrqNumber[audioHandle->instance]);
576
577 SAI_RxEnableInterrupts(s_i2sBases[audioHandle->instance], kSAI_FIFOErrorInterruptEnable);
578 }
579
580 return kStatus_HAL_AudioSuccess;
581 }
582
HAL_AudioCommonDeinit(hal_audio_handle_t handle,bool direction)583 static hal_audio_status_t HAL_AudioCommonDeinit(hal_audio_handle_t handle, bool direction)
584 {
585 hal_audio_state_t *audioHandle;
586
587 #if (defined(FSL_FEATURE_SOC_EDMA_COUNT) && (FSL_FEATURE_SOC_EDMA_COUNT > 0U) && \
588 (defined(FSL_EDMA_SOC_IP_DMA3) && (FSL_EDMA_SOC_IP_DMA3 > 0) || \
589 defined(FSL_EDMA_SOC_IP_DMA4) && (FSL_EDMA_SOC_IP_DMA4 > 0)))
590 #if (defined(HAL_AUDIO_DMA_INIT_ENABLE) && (HAL_AUDIO_DMA_INIT_ENABLE > 0U)) || \
591 (defined(FSL_FEATURE_EDMA_HAS_CHANNEL_MUX) && (FSL_FEATURE_EDMA_HAS_CHANNEL_MUX > 0U))
592 EDMA_Type *dmaBases[] = EDMA_BASE_PTRS;
593 #endif /* HAL_AUDIO_DMA_INIT_ENABLE or FSL_FEATURE_EDMA_HAS_CHANNEL_MUX */
594 #else
595 #if (defined(HAL_AUDIO_DMA_INIT_ENABLE) && (HAL_AUDIO_DMA_INIT_ENABLE > 0U)) || \
596 (defined(FSL_FEATURE_EDMA_HAS_CHANNEL_MUX) && (FSL_FEATURE_EDMA_HAS_CHANNEL_MUX > 0U))
597 DMA_Type *dmaBases[] = DMA_BASE_PTRS;
598 #endif /* HAL_AUDIO_DMA_INIT_ENABLE or FSL_FEATURE_EDMA_HAS_CHANNEL_MUX */
599 #endif /* FSL_FEATURE_SOC_EDMA_COUNT */
600 #if (defined(HAL_AUDIO_DMA_INIT_ENABLE) && (HAL_AUDIO_DMA_INIT_ENABLE > 0U))
601 #if (defined(FSL_FEATURE_SOC_EDMA_COUNT) && (FSL_FEATURE_SOC_EDMA_COUNT > 0U))
602 #if (defined(FSL_FEATURE_SOC_DMAMUX_COUNT) && (FSL_FEATURE_SOC_DMAMUX_COUNT > 0U))
603 DMAMUX_Type *dmaMuxBases[] = DMAMUX_BASE_PTRS;
604 #endif /* FSL_FEATURE_SOC_DMAMUX_COUNT */
605 #endif /* FSL_FEATURE_SOC_EDMA_COUNT */
606 #endif /* HAL_AUDIO_DMA_INIT_ENABLE */
607
608 assert(handle);
609
610 audioHandle = (hal_audio_state_t *)handle;
611
612 if (audioHandle->occupied == 0U)
613 {
614 return kStatus_HAL_AudioSuccess;
615 }
616 audioHandle->occupied = 0;
617
618 if (direction)
619 {
620 (void)HAL_AudioTransferAbortSend(handle);
621 }
622 else
623 {
624 (void)HAL_AudioTransferAbortReceive(handle);
625 }
626
627 if (s_i2sOccupied[audioHandle->instance] != 0U)
628 {
629 s_i2sOccupied[audioHandle->instance]--;
630
631 if (s_i2sOccupied[audioHandle->instance] == 0U)
632 {
633 SAI_Deinit(s_i2sBases[audioHandle->instance]);
634 }
635 }
636
637 #if (defined(FSL_FEATURE_SOC_EDMA_COUNT) && (FSL_FEATURE_SOC_EDMA_COUNT > 0U))
638 #if (defined(FSL_FEATURE_EDMA_HAS_CHANNEL_MUX) && (FSL_FEATURE_EDMA_HAS_CHANNEL_MUX > 0U))
639 EDMA_SetChannelMux(dmaBases[audioHandle->dmaInstance], audioHandle->dmaChannel, 0);
640 #endif /* FSL_FEATURE_EDMA_HAS_CHANNEL_MUX */
641 #endif /* FSL_FEATURE_SOC_EDMA_COUNT */
642
643 #if (defined(HAL_AUDIO_DMA_INIT_ENABLE) && (HAL_AUDIO_DMA_INIT_ENABLE > 0U))
644 if (s_dmaOccupied[audioHandle->dmaInstance] != 0U)
645 {
646 s_dmaOccupied[audioHandle->dmaInstance]--;
647
648 if (s_dmaOccupied[audioHandle->dmaInstance] == 0U)
649 {
650 #if (defined(FSL_FEATURE_SOC_EDMA_COUNT) && (FSL_FEATURE_SOC_EDMA_COUNT > 0U))
651 EDMA_Deinit(dmaBases[audioHandle->dmaInstance]);
652 #elif (defined(FSL_FEATURE_SOC_DMA_COUNT) && (FSL_FEATURE_SOC_DMA_COUNT > 0U))
653 DMA_Deinit(dmaBases[audioHandle->dmaInstance]);
654 #else
655 #endif
656 }
657 }
658
659 #if (defined(FSL_FEATURE_SOC_EDMA_COUNT) && (FSL_FEATURE_SOC_EDMA_COUNT > 0U))
660 #if (defined(FSL_FEATURE_SOC_DMAMUX_COUNT) && (FSL_FEATURE_SOC_DMAMUX_COUNT > 0U))
661 if (s_dmaMuxOccupied[audioHandle->dmaMuxInstance] != 0U)
662 {
663 s_dmaMuxOccupied[audioHandle->dmaMuxInstance]--;
664
665 if (s_dmaMuxOccupied[audioHandle->dmaMuxInstance] == 0U)
666 {
667 DMAMUX_Deinit(dmaMuxBases[audioHandle->dmaMuxInstance]);
668 }
669 }
670 #endif /* FSL_FEATURE_SOC_DMAMUX_COUNT */
671 #endif /* FSL_FEATURE_SOC_EDMA_COUNT */
672 #endif /* HAL_AUDIO_DMA_INIT_ENABLE */
673
674 return kStatus_HAL_AudioSuccess;
675 }
676
HAL_AudioTxInit(hal_audio_handle_t handle,const hal_audio_config_t * config)677 hal_audio_status_t HAL_AudioTxInit(hal_audio_handle_t handle, const hal_audio_config_t *config)
678 {
679 return HAL_AudioCommonInit(handle, config, true);
680 }
681
HAL_AudioRxInit(hal_audio_handle_t handle,const hal_audio_config_t * config)682 hal_audio_status_t HAL_AudioRxInit(hal_audio_handle_t handle, const hal_audio_config_t *config)
683 {
684 return HAL_AudioCommonInit(handle, config, false);
685 }
686
HAL_AudioTxDeinit(hal_audio_handle_t handle)687 hal_audio_status_t HAL_AudioTxDeinit(hal_audio_handle_t handle)
688 {
689 return HAL_AudioCommonDeinit(handle, true);
690 }
691
HAL_AudioRxDeinit(hal_audio_handle_t handle)692 hal_audio_status_t HAL_AudioRxDeinit(hal_audio_handle_t handle)
693 {
694 return HAL_AudioCommonDeinit(handle, false);
695 }
696
HAL_AudioTxInstallCallback(hal_audio_handle_t handle,hal_audio_transfer_callback_t callback,void * callbackParam)697 hal_audio_status_t HAL_AudioTxInstallCallback(hal_audio_handle_t handle,
698 hal_audio_transfer_callback_t callback,
699 void *callbackParam)
700 {
701 hal_audio_state_t *audioHandle;
702
703 assert(handle);
704
705 audioHandle = (hal_audio_state_t *)handle;
706
707 audioHandle->callback = callback;
708 audioHandle->callbackParam = callbackParam;
709
710 return kStatus_HAL_AudioSuccess;
711 }
712
HAL_AudioRxInstallCallback(hal_audio_handle_t handle,hal_audio_transfer_callback_t callback,void * callbackParam)713 hal_audio_status_t HAL_AudioRxInstallCallback(hal_audio_handle_t handle,
714 hal_audio_transfer_callback_t callback,
715 void *callbackParam)
716 {
717 hal_audio_state_t *audioHandle;
718
719 assert(handle);
720
721 audioHandle = (hal_audio_state_t *)handle;
722
723 audioHandle->callback = callback;
724 audioHandle->callbackParam = callbackParam;
725
726 return kStatus_HAL_AudioSuccess;
727 }
728
HAL_AudioTransferSendNonBlocking(hal_audio_handle_t handle,hal_audio_transfer_t * xfer)729 hal_audio_status_t HAL_AudioTransferSendNonBlocking(hal_audio_handle_t handle, hal_audio_transfer_t *xfer)
730 {
731 sai_transfer_t transfer;
732 hal_audio_state_t *audioHandle;
733
734 assert(handle);
735
736 audioHandle = (hal_audio_state_t *)handle;
737
738 transfer.data = (uint8_t *)xfer->data;
739 transfer.dataSize = xfer->dataSize;
740
741 #if (defined(FSL_FEATURE_SOC_EDMA_COUNT) && (FSL_FEATURE_SOC_EDMA_COUNT > 0U))
742 return HAL_AudioGetStatus(
743 SAI_TransferSendEDMA(s_i2sBases[audioHandle->instance], &audioHandle->xferDmaHandle, &transfer));
744 #elif (defined(FSL_FEATURE_SOC_DMA_COUNT) && (FSL_FEATURE_SOC_DMA_COUNT > 0U))
745 return HAL_AudioGetStatus(
746 SAI_TransferSendDMA(s_i2sBases[audioHandle->instance], &audioHandle->xferDmaHandle, &transfer));
747 #else
748 #endif
749 }
750
HAL_AudioTransferReceiveNonBlocking(hal_audio_handle_t handle,hal_audio_transfer_t * xfer)751 hal_audio_status_t HAL_AudioTransferReceiveNonBlocking(hal_audio_handle_t handle, hal_audio_transfer_t *xfer)
752 {
753 sai_transfer_t transfer;
754 hal_audio_state_t *audioHandle;
755
756 assert(handle);
757
758 audioHandle = (hal_audio_state_t *)handle;
759
760 transfer.data = (uint8_t *)xfer->data;
761 transfer.dataSize = xfer->dataSize;
762
763 #if (defined(FSL_FEATURE_SOC_EDMA_COUNT) && (FSL_FEATURE_SOC_EDMA_COUNT > 0U))
764 return HAL_AudioGetStatus(
765 SAI_TransferReceiveEDMA(s_i2sBases[audioHandle->instance], &audioHandle->xferDmaHandle, &transfer));
766 #elif (defined(FSL_FEATURE_SOC_DMA_COUNT) && (FSL_FEATURE_SOC_DMA_COUNT > 0U))
767 return HAL_AudioGetStatus(
768 SAI_TransferReceiveDMA(s_i2sBases[audioHandle->instance], &audioHandle->xferDmaHandle, &transfer));
769 #else
770 #endif
771 }
772
HAL_AudioTransferGetSendCount(hal_audio_handle_t handle,size_t * count)773 hal_audio_status_t HAL_AudioTransferGetSendCount(hal_audio_handle_t handle, size_t *count)
774 {
775 hal_audio_state_t *audioHandle;
776
777 assert(handle);
778
779 audioHandle = (hal_audio_state_t *)handle;
780
781 #if (defined(FSL_FEATURE_SOC_EDMA_COUNT) && (FSL_FEATURE_SOC_EDMA_COUNT > 0U))
782 return HAL_AudioGetStatus(
783 SAI_TransferGetSendCountEDMA(s_i2sBases[audioHandle->instance], &audioHandle->xferDmaHandle, count));
784 #elif (defined(FSL_FEATURE_SOC_DMA_COUNT) && (FSL_FEATURE_SOC_DMA_COUNT > 0U))
785 return HAL_AudioGetStatus(
786 SAI_TransferGetSendCountDMA(s_i2sBases[audioHandle->instance], &audioHandle->xferDmaHandle, count));
787 #else
788 #endif
789 }
790
HAL_AudioTransferGetReceiveCount(hal_audio_handle_t handle,size_t * count)791 hal_audio_status_t HAL_AudioTransferGetReceiveCount(hal_audio_handle_t handle, size_t *count)
792 {
793 hal_audio_state_t *audioHandle;
794
795 assert(handle);
796
797 audioHandle = (hal_audio_state_t *)handle;
798
799 #if (defined(FSL_FEATURE_SOC_EDMA_COUNT) && (FSL_FEATURE_SOC_EDMA_COUNT > 0U))
800 return HAL_AudioGetStatus(
801 SAI_TransferGetReceiveCountEDMA(s_i2sBases[audioHandle->instance], &audioHandle->xferDmaHandle, count));
802 #elif (defined(FSL_FEATURE_SOC_DMA_COUNT) && (FSL_FEATURE_SOC_DMA_COUNT > 0U))
803 return HAL_AudioGetStatus(
804 SAI_TransferGetReceiveCountDMA(s_i2sBases[audioHandle->instance], &audioHandle->xferDmaHandle, count));
805 #else
806 #endif
807 }
808
HAL_AudioTransferAbortSend(hal_audio_handle_t handle)809 hal_audio_status_t HAL_AudioTransferAbortSend(hal_audio_handle_t handle)
810 {
811 hal_audio_state_t *audioHandle;
812
813 assert(handle);
814
815 audioHandle = (hal_audio_state_t *)handle;
816
817 #if (defined(FSL_FEATURE_SOC_EDMA_COUNT) && (FSL_FEATURE_SOC_EDMA_COUNT > 0U))
818 SAI_TransferTerminateSendEDMA(s_i2sBases[audioHandle->instance], &audioHandle->xferDmaHandle);
819 #elif (defined(FSL_FEATURE_SOC_DMA_COUNT) && (FSL_FEATURE_SOC_DMA_COUNT > 0U))
820 SAI_TransferAbortSendDMA(s_i2sBases[audioHandle->instance], &audioHandle->xferDmaHandle);
821 #else
822 #endif
823
824 return kStatus_HAL_AudioSuccess;
825 }
826
HAL_AudioTransferAbortReceive(hal_audio_handle_t handle)827 hal_audio_status_t HAL_AudioTransferAbortReceive(hal_audio_handle_t handle)
828 {
829 hal_audio_state_t *audioHandle;
830
831 assert(handle);
832
833 audioHandle = (hal_audio_state_t *)handle;
834
835 #if (defined(FSL_FEATURE_SOC_EDMA_COUNT) && (FSL_FEATURE_SOC_EDMA_COUNT > 0U))
836 SAI_TransferTerminateReceiveEDMA(s_i2sBases[audioHandle->instance], &audioHandle->xferDmaHandle);
837 #elif (defined(FSL_FEATURE_SOC_DMA_COUNT) && (FSL_FEATURE_SOC_DMA_COUNT > 0U))
838 SAI_TransferAbortReceiveDMA(s_i2sBases[audioHandle->instance], &audioHandle->xferDmaHandle);
839 #else
840 #endif
841
842 return kStatus_HAL_AudioSuccess;
843 }
844