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