1 /*
2  * Copyright 2021 NXP
3  * All rights reserved.
4  *
5  *
6  * SPDX-License-Identifier: BSD-3-Clause
7  */
8 
9 #ifndef __HAL_AUDIO_ADAPTER_H__
10 #define __HAL_AUDIO_ADAPTER_H__
11 
12 #include "fsl_common.h"
13 
14 /*!
15  * @addtogroup Audio_Adapter
16  * @{
17  */
18 
19 /*******************************************************************************
20  * Definitions
21  ******************************************************************************/
22 
23 #if defined(SAI_XFER_QUEUE_SIZE)
24 #define HAL_AUDIO_QUEUE_SIZE ((uint32_t)SAI_XFER_QUEUE_SIZE)
25 #elif defined(I2S_NUM_BUFFERS)
26 #define HAL_AUDIO_QUEUE_SIZE ((uint32_t)I2S_NUM_BUFFERS)
27 #else
28 #define HAL_AUDIO_QUEUE_SIZE (4U)
29 #endif
30 
31 #ifndef HAL_AUDIO_DMA_INIT_ENABLE
32 #define HAL_AUDIO_DMA_INIT_ENABLE (1U)
33 #endif /* HAL_AUDIO_DMA_INIT_ENABLE */
34 
35 #if defined(__GIC_PRIO_BITS)
36 #ifndef HAL_AUDIO_ISR_PRIORITY
37 #define HAL_AUDIO_ISR_PRIORITY (25U)
38 #endif /* HAL_AUDIO_ISR_PRIORITY */
39 #else  /* __GIC_PRIO_BITS */
40 #if defined(configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY)
41 #ifndef HAL_AUDIO_ISR_PRIORITY
42 #define HAL_AUDIO_ISR_PRIORITY (configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY)
43 #endif /* HAL_AUDIO_ISR_PRIORITY */
44 #else
45 /* The default value 3 is used to support different ARM Core, such as CM0P, CM4, CM7, and CM33, etc.
46  * The minimum number of priority bits implemented in the NVIC is 2 on these SOCs. The value of mininum
47  * priority is 3 (2^2 - 1). So, the default value is 3.
48  */
49 #ifndef HAL_AUDIO_ISR_PRIORITY
50 #define HAL_AUDIO_ISR_PRIORITY (3U)
51 #endif /* HAL_AUDIO_ISR_PRIORITY */
52 #endif /* configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY */
53 #endif /* __GIC_PRIO_BITS */
54 
55 #if (defined(FSL_FEATURE_SOC_FLEXCOMM_COUNT) && (FSL_FEATURE_SOC_FLEXCOMM_COUNT > 0U)) && \
56     (defined(FSL_FEATURE_SOC_I2S_COUNT) && (FSL_FEATURE_SOC_I2S_COUNT > 0U))
57 #if (defined(FSL_FEATURE_SOC_DMA_COUNT) && (FSL_FEATURE_SOC_DMA_COUNT > 0U))
58 #define HAL_AUDIO_I2S_DMA_HANDLE_SIZE (HAL_AUDIO_QUEUE_SIZE * 8U + 48U)
59 #define HAL_AUDIO_HANDLE_SIZE_TEMP    (HAL_AUDIO_I2S_DMA_HANDLE_SIZE + 12U)
60 #else
61 #error This SOC does not have DMA available!
62 #endif /* FSL_FEATURE_SOC_DMA_COUNT */
63 
64 #elif (defined(FSL_FEATURE_SOC_I2S_COUNT) && (FSL_FEATURE_SOC_I2S_COUNT > 0U))
65 #if (defined(FSL_FEATURE_SOC_EDMA_COUNT) && (FSL_FEATURE_SOC_EDMA_COUNT > 0U)) || \
66     (defined(FSL_FEATURE_SOC_DMA4_COUNT) && (FSL_FEATURE_SOC_DMA4_COUNT > 0U))
67 #define HAL_AUDIO_SAI_EDMA_HANDLE_SIZE (HAL_AUDIO_QUEUE_SIZE * 44U + 92U)
68 #define HAL_AUDIO_HANDLE_SIZE_TEMP     (HAL_AUDIO_SAI_EDMA_HANDLE_SIZE + 16U)
69 #elif (defined(FSL_FEATURE_SOC_DMA_COUNT) && (FSL_FEATURE_SOC_DMA_COUNT > 0U))
70 #define HAL_AUDIO_SAI_DMA_HANDLE_SIZE (HAL_AUDIO_QUEUE_SIZE * 12U + 12U)
71 #define HAL_AUDIO_HANDLE_SIZE_TEMP    (HAL_AUDIO_SAI_DMA_HANDLE_SIZE + 16U)
72 #else
73 #error This SOC does not have DMA or EDMA available!
74 #endif /*FSL_FEATURE_SOC_EDMA_COUNT or FSL_FEATURE_SOC_DMA_COUNT */
75 
76 #else  /* FSL_FEATURE_SOC_FLEXCOMM_COUNT && FSL_FEATURE_SOC_I2S_COUNT */
77 #endif /* FSL_FEATURE_SOC_FLEXCOMM_COUNT && FSL_FEATURE_SOC_I2S_COUNT */
78 
79 /*! @brief Definition of audio adapter handle size. */
80 #define HAL_AUDIO_HANDLE_SIZE (HAL_AUDIO_HANDLE_SIZE_TEMP)
81 
82 /*! @brief HAL Audio status. */
83 typedef enum _hal_AUDIO_status
84 {
85     kStatus_HAL_AudioSuccess   = kStatus_Success,                      /*!< Successfully */
86     kStatus_HAL_AudioError     = MAKE_STATUS(kStatusGroup_HAL_I2S, 1), /*!< Error occurs on HAL Audio */
87     kStatus_HAL_AudioBusy      = MAKE_STATUS(kStatusGroup_HAL_I2S, 2), /*!< HAL Audio is busy with current transfer */
88     kStatus_HAL_AudioIdle      = MAKE_STATUS(kStatusGroup_HAL_I2S, 3), /*!< HAL Audio transmitter is idle */
89     kStatus_HAL_AudioQueueFull = MAKE_STATUS(kStatusGroup_HAL_I2S, 4), /*!< Transfer queue is full */
90 } hal_audio_status_t;
91 
92 /*! @brief HAL Audio channel number */
93 typedef enum _hal_audio_channel
94 {
95     kHAL_AudioMono      = 0x7FU, /*!< Only one channel on bus. */
96     kHAL_AudioMonoRight = 0x0U,  /*!< Only Right channel have sound. */
97     kHAL_AudioMonoLeft,          /*!< Only left channel have sound. */
98     kHAL_AudioStereo,            /*!< Stereo sound. */
99     kHAL_AudioStereo3Channel,    /*!< Stereo 3 channel sound. */
100     kHAL_AudioStereo4Channel,    /*!< Stereo 4 channel sound. */
101     kHAL_AudioStereo5Channel,    /*!< Stereo 5 channel sound. */
102     kHAL_AudioStereo6Channel,    /*!< Stereo 6 channel sound. */
103     kHAL_AudioStereo7Channel,    /*!< Stereo 7 channel sound. */
104     kHAL_AudioStereo8Channel,    /*!< Stereo 8 channel sound. */
105     kHAL_AudioStereo9Channel,    /*!< Stereo 9 channel sound. */
106     kHAL_AudioStereo10Channel,   /*!< Stereo 10 channel sound. */
107     kHAL_AudioStereo11Channel,   /*!< Stereo 11 channel sound. */
108     kHAL_AudioStereo12Channel,   /*!< Stereo 12 channel sound. */
109     kHAL_AudioStereo13Channel,   /*!< Stereo 13 channel sound. */
110     kHAL_AudioStereo14Channel,   /*!< Stereo 14 channel sound. */
111     kHAL_AudioStereo15Channel,   /*!< Stereo 15 channel sound. */
112     kHAL_AudioStereo16Channel,   /*!< Stereo 16 channel sound. */
113 } hal_audio_channel_t;
114 
115 /*! @brief HAL Audio sample rate */
116 typedef enum _hal_audio_sample_rate
117 {
118     kHAL_AudioSampleRate8KHz    = 8000U,   /*!< Sample rate 8000 Hz */
119     kHAL_AudioSampleRate11025Hz = 11025U,  /*!< Sample rate 11025 Hz */
120     kHAL_AudioSampleRate12KHz   = 12000U,  /*!< Sample rate 12000 Hz */
121     kHAL_AudioSampleRate16KHz   = 16000U,  /*!< Sample rate 16000 Hz */
122     kHAL_AudioSampleRate22050Hz = 22050U,  /*!< Sample rate 22050 Hz */
123     kHAL_AudioSampleRate24KHz   = 24000U,  /*!< Sample rate 24000 Hz */
124     kHAL_AudioSampleRate32KHz   = 32000U,  /*!< Sample rate 32000 Hz */
125     kHAL_AudioSampleRate44100Hz = 44100U,  /*!< Sample rate 44100 Hz */
126     kHAL_AudioSampleRate48KHz   = 48000U,  /*!< Sample rate 48000 Hz */
127     kHAL_AudioSampleRate96KHz   = 96000U,  /*!< Sample rate 96000 Hz */
128     kHAL_AudioSampleRate192KHz  = 192000U, /*!< Sample rate 192000 Hz */
129     kHAL_AudioSampleRate384KHz  = 384000U, /*!< Sample rate 384000 Hz */
130 } hal_audio_sample_rate_t;
131 
132 /*! @brief HAL Audio bit width */
133 typedef enum _hal_audio_bit_width
134 {
135     kHAL_AudioWordWidth8bits  = 8U,  /*!< Audio data width 8 bits */
136     kHAL_AudioWordWidth16bits = 16U, /*!< Audio data width 16 bits */
137     kHAL_AudioWordWidth24bits = 24U, /*!< Audio data width 24 bits */
138     kHAL_AudioWordWidth32bits = 32U, /*!< Audio data width 32 bits */
139 } hal_audio_bit_width_t;
140 
141 /*! @brief HAL Audio bit clock polarity */
142 typedef enum _hal_audio_bclk_polarity
143 {
144     kHAL_AudioSampleOnFallingEdge = 0x00U, /*!< Data samples at the falling edge. */
145     kHAL_AudioSampleOnRisingEdge,          /*!< Data samples at the rising edge. */
146 } hal_audio_bclk_polarity_t;
147 
148 /*! @brief HAL Audio frame sync width */
149 typedef enum _hal_audio_frame_sync_width
150 {
151     kHAL_AudioFrameSyncWidthOneBitClk = 0x00U, /*!< 1 bit clock frame sync len for DSP mode */
152     kHAL_AudioFrameSyncWidthPerWordWidth,      /*!< Frame sync length decided by word width */
153     kHAL_AudioFrameSyncWidthHalfFrame,         /*!< Frame sync length is half of frame length */
154 } hal_audio_frame_sync_width_t;
155 
156 /*! @brief HAL Audio frame sync polarity */
157 typedef enum _hal_audio_frame_sync_polarity
158 {
159     kHAL_AudioBeginAtRisingEdge = 0x00U, /*!< Frame sync begins at the rising edge. */
160     kHAL_AudioBeginAtFallingEdge,        /*!< Frame sync begins at the falling edge. */
161 } hal_audio_frame_sync_polarity_t;
162 
163 /*! @brief HAL Audio master or slave mode */
164 typedef enum _hal_audio_master_slave
165 {
166     kHAL_AudioMaster = 0x0U,            /*!< Master mode include bclk and frame sync */
167     kHAL_AudioSlave,                    /*!< Slave mode  include bclk and frame sync */
168     kHAL_AudioBclkMasterFrameSyncSlave, /*!< BCLK in master mode, frame sync in slave mode */
169     kHAL_AudioBclkSlaveFrameSyncMaster, /*!< BCLK in slave mode, frame sync in master mode */
170 } hal_audio_master_slave_t;
171 
172 /*! @brief Synchronous or asynchronous mode, only for SAI configuration */
173 typedef enum _hal_audio_sai_sync_mode
174 {
175     kHAL_AudioSaiModeAsync = 0x0U, /*!< Asynchronous mode */
176     kHAL_AudioSaiModeSync,         /*!< Synchronous mode (with receiver or transmit) */
177 } hal_audio_sai_sync_mode_t;
178 
179 /*! @brief HAL Audio data format */
180 typedef enum _hal_audio_data_format
181 {
182     kHAL_AudioDataFormatI2sClassic = 0x0U, /*!< I2S classic mode */
183     kHAL_AudioDataFormatLeftJustified,     /*!< Left-Justified mode */
184     kHAL_AudioDataFormatRightJustified,    /*!< Right-Justified mode */
185     kHAL_AudioDataFormatDspModeA,          /*!< DSP mode A, channel is available on 2nd rising edge of BCLK
186                                                 following a rising edge of frame sync */
187     kHAL_AudioDataFormatDspModeB,          /*!< DSP mode B, channel is available on 1st rising edge of BCLK
188                                                 following a rising edge of frame sync */
189 } hal_audio_data_format_t;
190 
191 /*! @brief HAL Audio DMA channel priority */
192 typedef enum _hal_audio_dma_channel_priority
193 {
194     kHAL_AudioDmaChannelPriority0 = 0x0U,
195     kHAL_AudioDmaChannelPriority1,
196     kHAL_AudioDmaChannelPriority2,
197     kHAL_AudioDmaChannelPriority3,
198     kHAL_AudioDmaChannelPriority4,
199     kHAL_AudioDmaChannelPriority5,
200     kHAL_AudioDmaChannelPriority6,
201     kHAL_AudioDmaChannelPriority7,
202     kHAL_AudioDmaChannelPriority8,
203     kHAL_AudioDmaChannelPriority9,
204     kHAL_AudioDmaChannelPriority10,
205     kHAL_AudioDmaChannelPriority11,
206     kHAL_AudioDmaChannelPriority12,
207     kHAL_AudioDmaChannelPriority13,
208     kHAL_AudioDmaChannelPriority14,
209     kHAL_AudioDmaChannelPriority15,
210     kHAL_AudioDmaChannelPriority16,
211     kHAL_AudioDmaChannelPriority17,
212     kHAL_AudioDmaChannelPriority18,
213     kHAL_AudioDmaChannelPriority19,
214     kHAL_AudioDmaChannelPriority20,
215     kHAL_AudioDmaChannelPriority21,
216     kHAL_AudioDmaChannelPriority22,
217     kHAL_AudioDmaChannelPriority23,
218     kHAL_AudioDmaChannelPriority24,
219     kHAL_AudioDmaChannelPriority25,
220     kHAL_AudioDmaChannelPriority26,
221     kHAL_AudioDmaChannelPriority27,
222     kHAL_AudioDmaChannelPriority28,
223     kHAL_AudioDmaChannelPriority29,
224     kHAL_AudioDmaChannelPriority30,
225     kHAL_AudioDmaChannelPriority31,
226     kHAL_AudioDmaChannelPriorityDefault = 0xFFU, /*!< Use default value, not to configure priority. */
227 } hal_audio_dma_channel_priority_t;
228 
229 /*! @brief HAL Audio DMA mux user configuration */
230 typedef struct _hal_audio_dma_mux_config_t
231 {
232     union
233     {
234         struct
235         {
236             uint8_t dmaMuxInstance;
237             uint32_t dmaRequestSource;
238         } dmaMuxConfig;
239     };
240 } hal_audio_dma_mux_config_t;
241 
242 /*! @brief HAL Audio DMA channel mux user configuration */
243 typedef struct _hal_audio_dma_channel_mux_config_t
244 {
245     union
246     {
247         struct
248         {
249             uint32_t dmaRequestSource;
250         } dmaChannelMuxConfig;
251     };
252 } hal_audio_dma_channel_mux_config_t;
253 
254 /*! @brief HAL Audio DMA extra user configuration */
255 typedef struct _hal_audio_dma_extra_config_t
256 {
257     union
258     {
259         /* DMA4 use this structure */
260         struct
261         {
262             bool enableMasterIdReplication;
263         } edmaExtraConfig;
264     };
265 } hal_audio_dma_extra_config_t;
266 
267 /*! @brief HAL Audio DMA user configuration */
268 typedef struct _hal_audio_dma_config
269 {
270     uint8_t instance;                          /*!< DMA instance */
271     uint8_t channel;                           /*!< DMA channel */
272     hal_audio_dma_channel_priority_t priority; /*!< DMA channel priority */
273 
274     bool enablePreemption;     /*!< If true, a channel can be suspended by other channel with higher priority.
275                                     Not all SOCs support this feature. For example, EDMA, DMA4 supports this feature.
276                                     For detailed information please refer to the SOC corresponding RM.
277                                     If not supported, the value should be set to false. */
278     bool enablePreemptAbility; /*!< If true, a channel can suspend other channel with low priority
279                                     Not all SOCs support this feature. For example, EDMA, DMA4 supports this feature.
280                                     For detailed information please refer to the SOC corresponding RM.
281                                     If not supported, the value should be set to false. */
282     void *dmaMuxConfig;        /*!< The pointer points to an entity defined by hal_audio_dma_mux_config_t.
283                                     Not all SOCs support this feature. In general, when the macro
284                                     FSL_FEATURE_SOC_DMAMUX_COUNT is defined as non-zero, the SOC supports this
285                                     feature. For detailed information please refer to the SOC corresponding RM.
286                                     If not supported, the pointer should be set to NULL. */
287     void *dmaChannelMuxConfig; /*!< The pointer points to an entity defined by hal_audio_dma_channel_mux_config_t.
288                                     Not all SOCs support this feature. In general, when the macro
289                                     FSL_FEATURE_EDMA_HAS_CHANNEL_MUX is defined as non-zero, the SOC supports this
290                                     feature. For detailed information please refer to the SOC corresponding RM.
291                                     If not supported, the pointer should be set to NULL. */
292     void *dmaChannelConfig;    /*!< The pointer points to an entity defined by channel configuration structure
293                                     that is defined in dma driver, such as edma_channel_config_t.
294                                     Not all SOCs support this feature. In general, when the macro
295                                     FSL_FEATURE_EDMA_HAS_CHANNEL_CONFIG is defined as non-zero, the SOC supports this
296                                     feature. For detailed information please refer to the SOC corresponding RM.
297                                     If not supported, the pointer should be set to NULL. */
298     void *dmaExtraConfig;      /*!< The pointer points to an entity defined by hal_audio_dma_extra_config_t.
299                                     Some DMA IPs have extra configurations, such as EDMA, DMA4.
300                                     The structure is used for these extra configurations.
301                                     Not all SOCs support this feature. For detailed information please refer to the
302                                     SOC corresponding RM. If not supported, the pointer should be set to NULL. */
303 } hal_audio_dma_config_t;
304 
305 /*! @brief HAL Audio IP specific feature configuration */
306 typedef struct _hal_audio_ip_config
307 {
308     union
309     {
310         /* SAI port use this structure */
311         struct
312         {
313             uint32_t lineMask; /*!< Writing one to the corresponding bit reprsents the corresponding data line is
314                                   enabled. lineMask = 0x1U, represents RX0/TX0 data line is enabled.
315                                     lineMask = 0xFU, represents RX0-3/TX0-3 data line are enabled. */
316             hal_audio_sai_sync_mode_t syncMode; /*!< SAI sync mode, control Tx/Rx clock sync */
317         } sai;
318     };
319 } hal_audio_ip_config_t;
320 
321 /*! @brief HAL Audio configuration structure. */
322 typedef struct _hal_audio_config
323 {
324     hal_audio_dma_config_t *dmaConfig; /*!< DMA configuration */
325     void *ipConfig;                    /*!< IP specific feature configuration. The pointer
326                                             points to an entity defined by hal_audio_ip_config_t.
327                                             If there is no specific feature configuration, it should be set to NULL. */
328 
329     uint32_t srcClock_Hz;              /*!< Source clock  */
330     uint32_t sampleRate_Hz;            /*!< Sample rate */
331     uint16_t frameLength;   /*!< Only flexcomm_i2s uses this field. In most cases, frameLength is equal to bitWidth
332                                  times lineChannels. In some cases, frameLength needs to be set to other value.
333                                  For example, when the number of bit clock on the bus between two neighboring WS
334                                  value is greater than bitWidth times lineChannels, frameLength needs to be set to
335                                  the value that is equal to the number of bit clock between two neighboring WS signal.
336                                  SAI does not use this field because frameLength can be determined internally
337                                  by bitWidth and lineChannels. */
338 
339     uint16_t fifoWatermark; /*!< FIFO watermark value. Generally, the value is set to half the number of FIFO(F).
340                                  Note that the receive(R) or transmit length(T) is related to fifoWatermark(W) and
341                                  bitWidth(B). The relationship between them is: R = N * W * B, T = N * (F - W) * B
342                                  (N is integer). On some SOCs, the W and (F - W) is constant 1 and setting the W
343                                  does not take effect. In that case the fifoWatermark does not need to be set.
344                                  If the value set by application is greater than the number of FIFO,
345                                  a maximum value will be used. For example, if the number of FIFO is 32 on a SOC
346                                  but the watermark is set to 64 by application, the real value that is written to
347                                  register will be 31. */
348 
349     hal_audio_master_slave_t masterSlave;   /*!< master or slave, configure where the bclk and frame sync come from. */
350     hal_audio_bclk_polarity_t bclkPolarity; /*!< bclk polarity, data sample on rising edge or falling edge. */
351 
352     hal_audio_frame_sync_width_t frameSyncWidth; /*!< Only DSP mode uses this field. For other data format, this field
353                                                       does not need to be set and the frameSyncWidth is determined
354                                                       internally that depends on different mode. For example, for I2S
355                                                       classic mode, frameSyncWidth is equal to bitWidth. */
356     hal_audio_frame_sync_polarity_t frameSyncPolarity; /*!< frame sync polarity, frame sync begin at rising or falling
357                                                             edge. This field is not used now and reserved for future
358                                                             use. The frameSyncPolarity is set internally that depends
359                                                             on different mode. For example, for I2S classic mode,
360                                                             frameSyncWidth is equal to kHAL_AudioBeginAtFallingEdge. */
361 
362     hal_audio_channel_t lineChannels;                  /*!< Configure the number of channel on the data line. */
363     hal_audio_data_format_t dataFormat;                /*!< data format on bus */
364 
365     uint8_t bitWidth;                                  /*!< Bit Width */
366     uint8_t instance; /*!< Instance (0 - I2S0/SAI0, 1 - I2S1/SAI1, ...), for detailed information please refer to the
367                            SOC corresponding RM. Invalid instance value will cause initialization failure. */
368 } hal_audio_config_t;
369 
370 /*! @brief HAL Audio transfer structure. */
371 typedef struct _hal_audio_transfer
372 {
373     uint8_t *data;   /*!< A transfer buffer. */
374     size_t dataSize; /*!< A transfer size. */
375 } hal_audio_transfer_t;
376 
377 /*! @brief HAL Audio transfer handle. */
378 typedef void *hal_audio_handle_t;
379 
380 /*!
381  * @brief Defines the Audio handle
382  *
383  * This macro is used to define a 4 byte aligned Audio handle.
384  * Then use "(hal_audio_handle_t)name" to get the Audio handle.
385  *
386  * The macro should be global and could be optional. You could also define Audio handle by yourself.
387  *
388  * This is an example,
389  * @code
390  *   HAL_AUDIO_HANDLE_DEFINE(audioTxHandle);
391  * @endcode
392  *
393  * @param name The name string of the Audio transfer handle.
394  */
395 #define HAL_AUDIO_HANDLE_DEFINE(name) uint32_t name[(HAL_AUDIO_HANDLE_SIZE + sizeof(uint32_t) - 1U) / sizeof(uint32_t)]
396 
397 /*!
398  * @brief HAL Audio completion callback function pointer type.
399  *
400  * This callback is used only for the non-blocking Audio transfer API. Specify the callback you wish to use
401  * in the call to HAL_AudioTxInstallCallback() or HAL_AudioRxInstallCallback().
402  *
403  * @param handle audio transfer handle pointer, this should be a static variable.
404  * @param completionStatus Either #kStatus_HAL_AudioIdle or an error code describing how the transfer completed.
405  * @param callbackParam Arbitrary pointer-sized value passed from the application.
406  */
407 typedef void (*hal_audio_transfer_callback_t)(hal_audio_handle_t handle,
408                                               hal_audio_status_t completionStatus,
409                                               void *callbackParam);
410 
411 /*******************************************************************************
412  * API
413  ******************************************************************************/
414 
415 #if defined(__cplusplus)
416 extern "C" {
417 #endif /*_cplusplus. */
418 
419 /*!
420  * @name Initialization and de-initialization
421  * @{
422  */
423 
424 /*!
425  * @brief Initializes the HAL Audio peripheral.
426  *
427  * @note This API should be called at the beginning of the application.
428  * Otherwise, any operation to the HAL Audio module can cause a hard fault
429  * because the clock is not enabled. This function configures the audio
430  * with user-defined settings. The user can configure the configuration
431  * structure. The parameter handle is a pointer to point to a memory space
432  * of size #HAL_AUDIO_HANDLE_SIZE allocated by the caller.
433  *
434  * @note DMA will be initialized and enabled by default in this function and calling
435  * HAL_AudioTransferSendNonBlocking or HAL_AudioTransferReceiveNonBlocking will use
436  * DMA to transfer data. Thus application should avoid initializing DMA repeatedly
437  * and dmaConfig should be configured.
438  *
439  * Example below shows how to use this API to configure the audio peripheral.
440  * For SAI,
441  * @code
442  *   HAL_AUDIO_HANDLE_DEFINE(audioTxHandle);
443  *   hal_audio_config_t audioConfig;
444  *   hal_audio_dma_config_t dmaConfig;
445  *   hal_audio_ip_config_t ipConfig;
446  *   hal_audio_dma_mux_config_t dmaMuxConfig;
447  *   dmaMuxConfig.dmaMuxConfig.dmaMuxInstance   = 0;
448  *   dmaMuxConfig.dmaMuxConfig.dmaRequestSource = (uint32_t)kDmaRequestMuxSai1Tx;
449  *   dmaConfig.instance                         = 0;
450  *   dmaConfig.channel                          = 0;
451  *   dmaConfig.priority                         = kHAL_AudioDmaChannelPriorityDefault;
452  *   dmaConfig.enablePreemption                 = false;
453  *   dmaConfig.enablePreemptAbility             = false;
454  *   dmaConfig.dmaMuxConfig                     = &dmaMuxConfig;
455  *   dmaConfig.dmaChannelMuxConfig              = NULL;
456  *   ipConfig.sai.lineMask                      = 1U << 0U;
457  *   ipConfig.sai.syncMode                      = kHAL_AudioSaiModeAsync;
458  *   audioConfig.dmaConfig                      = &dmaConfig;
459  *   audioConfig.ipConfig                       = &ipConfig;
460  *   audioConfig.srcClock_Hz                    = 24576000;
461  *   audioConfig.sampleRate_Hz                  = (uint32_t)kHAL_AudioSampleRate48KHz;
462  *   audioConfig.fifoWatermark                  = 16;
463  *   audioConfig.masterSlave                    = kHAL_AudioMaster;
464  *   audioConfig.bclkPolarity                   = kHAL_AudioSampleOnRisingEdge;
465  *   audioConfig.frameSyncWidth                 = kHAL_AudioFrameSyncWidthHalfFrame;
466  *   audioConfig.frameSyncPolarity              = kHAL_AudioBeginAtFallingEdge;
467  *   audioConfig.lineChannels                   = kHAL_AudioStereo;
468  *   audioConfig.dataFormat                     = kHAL_AudioDataFormatI2sClassic;
469  *   audioConfig.bitWidth                       = (uint8_t)kHAL_AudioWordWidth16bits;
470  *   audioConfig.instance                       = 0U;
471  *   HAL_AudioTxInit((hal_audio_handle_t)audioTxHandle, &audioConfig);
472  * @endcode
473  * For I2S,
474  * @code
475  *   HAL_AUDIO_HANDLE_DEFINE(audioTxHandle);
476  *   hal_audio_config_t     audioConfig;
477  *   hal_audio_dma_config_t dmaConfig;
478  *   dmaConfig.instance             = 0;
479  *   dmaConfig.channel              = 0;
480  *   dmaConfig.priority             = kHAL_AudioDmaChannelPriorityDefault;
481  *   dmaConfig.enablePreemption     = false;
482  *   dmaConfig.enablePreemptAbility = false;
483  *   dmaConfig.dmaMuxConfig         = NULL;
484  *   dmaConfig.dmaChannelMuxConfig  = NULL;
485  *   audioConfig.dmaConfig          = &dmaConfig;
486  *   audioConfig.ipConfig           = NULL;
487  *   audioConfig.srcClock_Hz        = 24576000;
488  *   audioConfig.sampleRate_Hz      = (uint32_t)kHAL_AudioSampleRate48KHz;
489  *   audioConfig.fifoWatermark      = 0;
490  *   audioConfig.masterSlave        = kHAL_AudioMaster;
491  *   audioConfig.bclkPolarity       = kHAL_AudioSampleOnRisingEdge;
492  *   audioConfig.frameSyncWidth     = kHAL_AudioFrameSyncWidthHalfFrame;
493  *   audioConfig.frameSyncPolarity  = kHAL_AudioBeginAtFallingEdge;
494  *   audioConfig.lineChannels       = kHAL_AudioStereo;
495  *   audioConfig.dataFormat         = kHAL_AudioDataFormatI2sClassic;
496  *   audioConfig.bitWidth           = (uint8_t)kHAL_AudioWordWidth16bits;
497  *   audioConfig.instance           = 0U;
498  *   HAL_AudioTxInit((hal_audio_handle_t)audioTxHandle, &audioConfig);
499  * @endcode
500  *
501  * @param handle Pointer to point to a memory space of size #HAL_AUDIO_HANDLE_SIZE allocated by the caller.
502  * The handle should be 4 byte aligned, because unaligned access doesn't be supported on some devices.
503  * You can define the handle in the following two ways:
504  * #HAL_AUDIO_HANDLE_DEFINE(handle);
505  * or
506  * uint32_t handle[((HAL_AUDIO_HANDLE_SIZE + sizeof(uint32_t) - 1U) / sizeof(uint32_t))];
507  * @param config A pointer to the audio configuration structure
508  * @retval kStatus_HAL_AudioSuccess audio initialization succeed
509  */
510 hal_audio_status_t HAL_AudioTxInit(hal_audio_handle_t handle, const hal_audio_config_t *config);
511 
512 /*!
513  * @brief Initializes the HAL Audio peripheral.
514  *
515  * @note This API should be called at the beginning of the application.
516  * Otherwise, any operation to the HAL Audio module can cause a hard fault
517  * because the clock is not enabled. This function configures the audio
518  * with user-defined settings. The user can configure the configuration
519  * structure. The parameter handle is a pointer to point to a memory space
520  * of size #HAL_AUDIO_HANDLE_SIZE allocated by the caller.
521  *
522  * @note DMA will be initialized and enabled by default in this function and calling
523  * HAL_AudioTransferSendNonBlocking or HAL_AudioTransferReceiveNonBlocking will use
524  * DMA to transfer data. Thus application should avoid initializing DMA repeatedly
525  * and dmaConfig should be configured.
526  *
527  * Example below shows how to use this API to configure the audio peripheral.
528  * For SAI,
529  * @code
530  *   HAL_AUDIO_HANDLE_DEFINE(audioRxHandle);
531  *   hal_audio_config_t audioConfig;
532  *   hal_audio_dma_config_t dmaConfig;
533  *   hal_audio_ip_config_t ipConfig;
534  *   hal_audio_dma_mux_config_t dmaMuxConfig;
535  *   dmaMuxConfig.dmaMuxConfig.dmaMuxInstance   = 0;
536  *   dmaMuxConfig.dmaMuxConfig.dmaRequestSource = (uint32_t)kDmaRequestMuxSai1Rx;
537  *   dmaConfig.instance                         = 0;
538  *   dmaConfig.channel                          = 0;
539  *   dmaConfig.priority                         = kHAL_AudioDmaChannelPriorityDefault;
540  *   dmaConfig.enablePreemption                 = false;
541  *   dmaConfig.enablePreemptAbility             = false;
542  *   dmaConfig.dmaMuxConfig                     = &dmaMuxConfig;
543  *   dmaConfig.dmaChannelMuxConfig              = NULL;
544  *   ipConfig.sai.lineMask                      = 1U << 0U;
545  *   ipConfig.sai.syncMode                      = kHAL_AudioSaiModeAsync;
546  *   audioConfig.dmaConfig                      = &dmaConfig;
547  *   audioConfig.ipConfig                       = &ipConfig;
548  *   audioConfig.srcClock_Hz                    = 24576000;
549  *   audioConfig.sampleRate_Hz                  = (uint32_t)kHAL_AudioSampleRate48KHz;
550  *   audioConfig.fifoWatermark                  = 16;
551  *   audioConfig.masterSlave                    = kHAL_AudioMaster;
552  *   audioConfig.bclkPolarity                   = kHAL_AudioSampleOnRisingEdge;
553  *   audioConfig.frameSyncWidth                 = kHAL_AudioFrameSyncWidthHalfFrame;
554  *   audioConfig.frameSyncPolarity              = kHAL_AudioBeginAtFallingEdge;
555  *   audioConfig.lineChannels                   = kHAL_AudioStereo;
556  *   audioConfig.dataFormat                     = kHAL_AudioDataFormatI2sClassic;
557  *   audioConfig.bitWidth                       = (uint8_t)kHAL_AudioWordWidth16bits;
558  *   audioConfig.instance                       = 0U;
559  *   HAL_AudioRxInit((hal_audio_handle_t)audioRxHandle, &audioConfig);
560  * @endcode
561  * For I2S,
562  * @code
563  *   HAL_AUDIO_HANDLE_DEFINE(audioRxHandle);
564  *   hal_audio_config_t     audioConfig;
565  *   hal_audio_dma_config_t dmaConfig;
566  *   dmaConfig.instance             = 0;
567  *   dmaConfig.channel              = 0;
568  *   dmaConfig.priority             = kHAL_AudioDmaChannelPriorityDefault;
569  *   dmaConfig.enablePreemption     = false;
570  *   dmaConfig.enablePreemptAbility = false;
571  *   dmaConfig.dmaMuxConfig         = NULL;
572  *   dmaConfig.dmaChannelMuxConfig  = NULL;
573  *   audioConfig.dmaConfig          = &dmaConfig;
574  *   audioConfig.ipConfig           = NULL;
575  *   audioConfig.srcClock_Hz        = 24576000;
576  *   audioConfig.sampleRate_Hz      = (uint32_t)kHAL_AudioSampleRate48KHz;
577  *   audioConfig.fifoWatermark      = 0;
578  *   audioConfig.masterSlave        = kHAL_AudioMaster;
579  *   audioConfig.bclkPolarity       = kHAL_AudioSampleOnRisingEdge;
580  *   audioConfig.frameSyncWidth     = kHAL_AudioFrameSyncWidthHalfFrame;
581  *   audioConfig.frameSyncPolarity  = kHAL_AudioBeginAtFallingEdge;
582  *   audioConfig.lineChannels       = kHAL_AudioStereo;
583  *   audioConfig.dataFormat         = kHAL_AudioDataFormatI2sClassic;
584  *   audioConfig.bitWidth           = (uint8_t)kHAL_AudioWordWidth16bits;
585  *   audioConfig.instance           = 0U;
586  *   HAL_AudioRxInit((hal_audio_handle_t)audioRxHandle, &audioConfig);
587  * @endcode
588  *
589  * @param handle Pointer to point to a memory space of size #HAL_AUDIO_HANDLE_SIZE allocated by the caller.
590  * The handle should be 4 byte aligned, because unaligned access doesn't be supported on some devices.
591  * You can define the handle in the following two ways:
592  * #HAL_AUDIO_HANDLE_DEFINE(handle);
593  * or
594  * uint32_t handle[((HAL_AUDIO_HANDLE_SIZE + sizeof(uint32_t) - 1U) / sizeof(uint32_t))];
595  * @param config A pointer to the audio configuration structure
596  * @retval kStatus_HAL_AudioSuccess audio initialization succeed
597  */
598 hal_audio_status_t HAL_AudioRxInit(hal_audio_handle_t handle, const hal_audio_config_t *config);
599 
600 /*!
601  * @brief De-initializes the HAL Audio peripheral. Call this API to gate the HAL Audio clock.
602  * The HAL Audio module can't work unless the HAL_AudioTxInit is called.
603  *
604  * @param handle audio handle pointer, this should be a static variable.
605  * @retval kStatus_HAL_AudioSuccess audio de-initialization succeed */
606 hal_audio_status_t HAL_AudioTxDeinit(hal_audio_handle_t handle);
607 /*!
608  * @brief De-initializes the HAL Audio peripheral. Call this API to gate the HAL Audio clock.
609  * The HAL Audio module can't work unless the HAL_AudioRxInit is called.
610  *
611  * @param handle audio handle pointer, this should be a static variable.
612  * @retval kStatus_HAL_AudioSuccess audio de-initialization succeed */
613 hal_audio_status_t HAL_AudioRxDeinit(hal_audio_handle_t handle);
614 
615 /*! @} */
616 
617 /*!
618  * @name Transactional
619  * @{
620  */
621 
622 /*!
623  * @brief Installs a callback and callback parameter.
624  *
625  * This function is used to install the callback and callback parameter for audio module.
626  * When any status of the audio changed, the driver will notify the upper layer by the installed callback
627  * function. And the status is also passed as status parameter when the callback is called.
628  *
629  * @param handle audio handle pointer, this should be a static variable.
630  * @param callback pointer to user callback function.
631  * @param callbackParam user parameter passed to the callback function.
632  * @retval kStatus_HAL_AudioSuccess audio tx transfer handle created
633  */
634 hal_audio_status_t HAL_AudioTxInstallCallback(hal_audio_handle_t handle,
635                                               hal_audio_transfer_callback_t callback,
636                                               void *callbackParam);
637 /*!
638  * @brief Installs a callback and callback parameter.
639  *
640  * This function is used to install the callback and callback parameter for audio module.
641  * When any status of the audio changed, the driver will notify the upper layer by the installed callback
642  * function. And the status is also passed as status parameter when the callback is called.
643  *
644  * @param handle audio handle pointer, this should be a static variable.
645  * @param callback pointer to user callback function.
646  * @param callbackParam user parameter passed to the callback function.
647  * @retval kStatus_HAL_AudioSuccess audio rx transfer handle created
648  */
649 hal_audio_status_t HAL_AudioRxInstallCallback(hal_audio_handle_t handle,
650                                               hal_audio_transfer_callback_t callback,
651                                               void *callbackParam);
652 
653 /*!
654  * @brief Performs a DMA non-blocking send on the data bus.
655  *
656  * @note Calling the API returns immediately after transfer initiates. The user can
657  * call HAL_AudioTransferGetSendCount to poll the transfer status to check whether
658  * the transfer is finished. If the return status is kStatus_HAL_AudioIdle, the transfer
659  * is finished.
660  *
661  * @param handle audio handle pointer, this should be a static variable.
662  * @param xfer pointer to hal_audio_transfer_t structure.
663  *
664  * @note The transmit length(T) is related to fifoWatermark(W), bitWidth(B) and the number of FIFO(F).
665  * The relationship between them is: T = N * (F - W) * B (N is integer).
666  *
667  * @retval kStatus_HAL_AudioSuccess Successfully start the data transmission.
668  * @retval kStatus_HAL_AudioBusy Previous transmission still not finished.
669  * @retval kStatus_HAL_AudioError An error occurred.
670  */
671 hal_audio_status_t HAL_AudioTransferSendNonBlocking(hal_audio_handle_t handle, hal_audio_transfer_t *xfer);
672 
673 /*!
674  * @brief Performs a DMA non-blocking receive on the HAL Audio bus.
675  *
676  * @note Calling the API returns immediately after transfer initiates. The user can
677  * call HAL_AudioTransferGetReceiveCount to poll the transfer status to check whether
678  * the transfer is finished. If the return status is kStatus_HAL_AudioIdle, the transfer
679  * is finished.
680  *
681  * @param handle audio handle pointer, this should be a static variable.
682  * @param xfer pointer to hal_audio_transfer_t structure.
683  *
684  * @note The receive length(R) is related to fifoWatermark(W), bitWidth(B) and the number of FIFO(F).
685  * The relationship between them is: R = N * W * B (N is integer).
686  *
687  * @retval kStatus_HAL_AudioSuccess Successfully start the data transmission.
688  * @retval kStatus_HAL_AudioBusy Previous transmission still not finished.
689  * @retval kStatus_HAL_AudioError An error occurred.
690  */
691 hal_audio_status_t HAL_AudioTransferReceiveNonBlocking(hal_audio_handle_t handle, hal_audio_transfer_t *xfer);
692 
693 /*!
694  * @brief Aborts a DMA non-blocking transfer early.
695  *
696  * @note This API can be called at any time when a DMA non-blocking transfer initiates
697  * to abort the transfer early.
698  *
699  * @param handle audio handle pointer, this should be a static variable.
700  * @retval kStatus_HAL_AudioSuccess Successfully abort the transfer.
701  */
702 hal_audio_status_t HAL_AudioTransferAbortSend(hal_audio_handle_t handle);
703 
704 /*!
705  * @brief Aborts a DMA non-blocking transfer early.
706  *
707  * @note This API can be called at any time when a DMA non-blocking transfer initiates
708  * to abort the transfer early.
709  *
710  * @param handle audio handle pointer, this should be a static variable.
711  * @retval kStatus_HAL_AudioSuccess Successfully abort the transfer.
712  */
713 hal_audio_status_t HAL_AudioTransferAbortReceive(hal_audio_handle_t handle);
714 
715 /*!
716  * @brief Gets the tx transfer status during a DMA non-blocking transfer.
717  *
718  * @param handle audio handle pointer, this should be a static variable.
719  * @param count Number of bytes sent so far by the non-blocking transaction.
720  * @retval kStatus_HAL_AudioSuccess Successfully return the count.
721  * @retval kStatus_HAL_AudioIdle Previous transmission has been finished.
722  * @retval kStatus_HAL_AudioError An error occurred.
723  */
724 hal_audio_status_t HAL_AudioTransferGetSendCount(hal_audio_handle_t handle, size_t *count);
725 /*!
726  * @brief Gets the rx transfer status during a DMA non-blocking transfer.
727  *
728  * @param handle audio handle pointer, this should be a static variable.
729  * @param count Number of bytes received so far by the non-blocking transaction.
730  * @retval kStatus_HAL_AudioSuccess Successfully return the count.
731  * @retval kStatus_HAL_AudioIdle Previous transmission has been finished.
732  * @retval kStatus_HAL_AudioError An error occurred.
733  */
734 hal_audio_status_t HAL_AudioTransferGetReceiveCount(hal_audio_handle_t handle, size_t *count);
735 
736 /*! @} */
737 
738 #if defined(__cplusplus)
739 }
740 #endif /*_cplusplus. */
741 /*! @} */
742 
743 #endif /* __HAL_AUDIO_ADAPTER_H__*/
744