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