744 lines
36 KiB
C
744 lines
36 KiB
C
/*
|
|
* Copyright 2021 NXP
|
|
* All rights reserved.
|
|
*
|
|
*
|
|
* SPDX-License-Identifier: BSD-3-Clause
|
|
*/
|
|
|
|
#ifndef __HAL_AUDIO_ADAPTER_H__
|
|
#define __HAL_AUDIO_ADAPTER_H__
|
|
|
|
#include "fsl_common.h"
|
|
|
|
/*!
|
|
* @addtogroup Audio_Adapter
|
|
* @{
|
|
*/
|
|
|
|
/*******************************************************************************
|
|
* Definitions
|
|
******************************************************************************/
|
|
|
|
#if defined(SAI_XFER_QUEUE_SIZE)
|
|
#define HAL_AUDIO_QUEUE_SIZE ((uint32_t)SAI_XFER_QUEUE_SIZE)
|
|
#elif defined(I2S_NUM_BUFFERS)
|
|
#define HAL_AUDIO_QUEUE_SIZE ((uint32_t)I2S_NUM_BUFFERS)
|
|
#else
|
|
#define HAL_AUDIO_QUEUE_SIZE (4U)
|
|
#endif
|
|
|
|
#ifndef HAL_AUDIO_DMA_INIT_ENABLE
|
|
#define HAL_AUDIO_DMA_INIT_ENABLE (1U)
|
|
#endif /* HAL_AUDIO_DMA_INIT_ENABLE */
|
|
|
|
#if defined(__GIC_PRIO_BITS)
|
|
#ifndef HAL_AUDIO_ISR_PRIORITY
|
|
#define HAL_AUDIO_ISR_PRIORITY (25U)
|
|
#endif /* HAL_AUDIO_ISR_PRIORITY */
|
|
#else /* __GIC_PRIO_BITS */
|
|
#if defined(configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY)
|
|
#ifndef HAL_AUDIO_ISR_PRIORITY
|
|
#define HAL_AUDIO_ISR_PRIORITY (configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY)
|
|
#endif /* HAL_AUDIO_ISR_PRIORITY */
|
|
#else
|
|
/* The default value 3 is used to support different ARM Core, such as CM0P, CM4, CM7, and CM33, etc.
|
|
* The minimum number of priority bits implemented in the NVIC is 2 on these SOCs. The value of mininum
|
|
* priority is 3 (2^2 - 1). So, the default value is 3.
|
|
*/
|
|
#ifndef HAL_AUDIO_ISR_PRIORITY
|
|
#define HAL_AUDIO_ISR_PRIORITY (3U)
|
|
#endif /* HAL_AUDIO_ISR_PRIORITY */
|
|
#endif /* configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY */
|
|
#endif /* __GIC_PRIO_BITS */
|
|
|
|
#if (defined(FSL_FEATURE_SOC_FLEXCOMM_COUNT) && (FSL_FEATURE_SOC_FLEXCOMM_COUNT > 0U)) && \
|
|
(defined(FSL_FEATURE_SOC_I2S_COUNT) && (FSL_FEATURE_SOC_I2S_COUNT > 0U))
|
|
#if (defined(FSL_FEATURE_SOC_DMA_COUNT) && (FSL_FEATURE_SOC_DMA_COUNT > 0U))
|
|
#define HAL_AUDIO_I2S_DMA_HANDLE_SIZE (HAL_AUDIO_QUEUE_SIZE * 8U + 48U)
|
|
#define HAL_AUDIO_HANDLE_SIZE_TEMP (HAL_AUDIO_I2S_DMA_HANDLE_SIZE + 12U)
|
|
#else
|
|
#error This SOC does not have DMA available!
|
|
#endif /* FSL_FEATURE_SOC_DMA_COUNT */
|
|
|
|
#elif (defined(FSL_FEATURE_SOC_I2S_COUNT) && (FSL_FEATURE_SOC_I2S_COUNT > 0U))
|
|
#if (defined(FSL_FEATURE_SOC_EDMA_COUNT) && (FSL_FEATURE_SOC_EDMA_COUNT > 0U)) || \
|
|
(defined(FSL_FEATURE_SOC_DMA4_COUNT) && (FSL_FEATURE_SOC_DMA4_COUNT > 0U))
|
|
#define HAL_AUDIO_SAI_EDMA_HANDLE_SIZE (HAL_AUDIO_QUEUE_SIZE * 44U + 92U)
|
|
#define HAL_AUDIO_HANDLE_SIZE_TEMP (HAL_AUDIO_SAI_EDMA_HANDLE_SIZE + 16U)
|
|
#elif (defined(FSL_FEATURE_SOC_DMA_COUNT) && (FSL_FEATURE_SOC_DMA_COUNT > 0U))
|
|
#define HAL_AUDIO_SAI_DMA_HANDLE_SIZE (HAL_AUDIO_QUEUE_SIZE * 12U + 12U)
|
|
#define HAL_AUDIO_HANDLE_SIZE_TEMP (HAL_AUDIO_SAI_DMA_HANDLE_SIZE + 16U)
|
|
#else
|
|
#error This SOC does not have DMA or EDMA available!
|
|
#endif /*FSL_FEATURE_SOC_EDMA_COUNT or FSL_FEATURE_SOC_DMA_COUNT */
|
|
|
|
#else /* FSL_FEATURE_SOC_FLEXCOMM_COUNT && FSL_FEATURE_SOC_I2S_COUNT */
|
|
#endif /* FSL_FEATURE_SOC_FLEXCOMM_COUNT && FSL_FEATURE_SOC_I2S_COUNT */
|
|
|
|
/*! @brief Definition of audio adapter handle size. */
|
|
#define HAL_AUDIO_HANDLE_SIZE (HAL_AUDIO_HANDLE_SIZE_TEMP)
|
|
|
|
/*! @brief HAL Audio status. */
|
|
typedef enum _hal_AUDIO_status
|
|
{
|
|
kStatus_HAL_AudioSuccess = kStatus_Success, /*!< Successfully */
|
|
kStatus_HAL_AudioError = MAKE_STATUS(kStatusGroup_HAL_I2S, 1), /*!< Error occurs on HAL Audio */
|
|
kStatus_HAL_AudioBusy = MAKE_STATUS(kStatusGroup_HAL_I2S, 2), /*!< HAL Audio is busy with current transfer */
|
|
kStatus_HAL_AudioIdle = MAKE_STATUS(kStatusGroup_HAL_I2S, 3), /*!< HAL Audio transmitter is idle */
|
|
kStatus_HAL_AudioQueueFull = MAKE_STATUS(kStatusGroup_HAL_I2S, 4), /*!< Transfer queue is full */
|
|
} hal_audio_status_t;
|
|
|
|
/*! @brief HAL Audio channel number */
|
|
typedef enum _hal_audio_channel
|
|
{
|
|
kHAL_AudioMono = 0x7FU, /*!< Only one channel on bus. */
|
|
kHAL_AudioMonoRight = 0x0U, /*!< Only Right channel have sound. */
|
|
kHAL_AudioMonoLeft, /*!< Only left channel have sound. */
|
|
kHAL_AudioStereo, /*!< Stereo sound. */
|
|
kHAL_AudioStereo3Channel, /*!< Stereo 3 channel sound. */
|
|
kHAL_AudioStereo4Channel, /*!< Stereo 4 channel sound. */
|
|
kHAL_AudioStereo5Channel, /*!< Stereo 5 channel sound. */
|
|
kHAL_AudioStereo6Channel, /*!< Stereo 6 channel sound. */
|
|
kHAL_AudioStereo7Channel, /*!< Stereo 7 channel sound. */
|
|
kHAL_AudioStereo8Channel, /*!< Stereo 8 channel sound. */
|
|
kHAL_AudioStereo9Channel, /*!< Stereo 9 channel sound. */
|
|
kHAL_AudioStereo10Channel, /*!< Stereo 10 channel sound. */
|
|
kHAL_AudioStereo11Channel, /*!< Stereo 11 channel sound. */
|
|
kHAL_AudioStereo12Channel, /*!< Stereo 12 channel sound. */
|
|
kHAL_AudioStereo13Channel, /*!< Stereo 13 channel sound. */
|
|
kHAL_AudioStereo14Channel, /*!< Stereo 14 channel sound. */
|
|
kHAL_AudioStereo15Channel, /*!< Stereo 15 channel sound. */
|
|
kHAL_AudioStereo16Channel, /*!< Stereo 16 channel sound. */
|
|
} hal_audio_channel_t;
|
|
|
|
/*! @brief HAL Audio sample rate */
|
|
typedef enum _hal_audio_sample_rate
|
|
{
|
|
kHAL_AudioSampleRate8KHz = 8000U, /*!< Sample rate 8000 Hz */
|
|
kHAL_AudioSampleRate11025Hz = 11025U, /*!< Sample rate 11025 Hz */
|
|
kHAL_AudioSampleRate12KHz = 12000U, /*!< Sample rate 12000 Hz */
|
|
kHAL_AudioSampleRate16KHz = 16000U, /*!< Sample rate 16000 Hz */
|
|
kHAL_AudioSampleRate22050Hz = 22050U, /*!< Sample rate 22050 Hz */
|
|
kHAL_AudioSampleRate24KHz = 24000U, /*!< Sample rate 24000 Hz */
|
|
kHAL_AudioSampleRate32KHz = 32000U, /*!< Sample rate 32000 Hz */
|
|
kHAL_AudioSampleRate44100Hz = 44100U, /*!< Sample rate 44100 Hz */
|
|
kHAL_AudioSampleRate48KHz = 48000U, /*!< Sample rate 48000 Hz */
|
|
kHAL_AudioSampleRate96KHz = 96000U, /*!< Sample rate 96000 Hz */
|
|
kHAL_AudioSampleRate192KHz = 192000U, /*!< Sample rate 192000 Hz */
|
|
kHAL_AudioSampleRate384KHz = 384000U, /*!< Sample rate 384000 Hz */
|
|
} hal_audio_sample_rate_t;
|
|
|
|
/*! @brief HAL Audio bit width */
|
|
typedef enum _hal_audio_bit_width
|
|
{
|
|
kHAL_AudioWordWidth8bits = 8U, /*!< Audio data width 8 bits */
|
|
kHAL_AudioWordWidth16bits = 16U, /*!< Audio data width 16 bits */
|
|
kHAL_AudioWordWidth24bits = 24U, /*!< Audio data width 24 bits */
|
|
kHAL_AudioWordWidth32bits = 32U, /*!< Audio data width 32 bits */
|
|
} hal_audio_bit_width_t;
|
|
|
|
/*! @brief HAL Audio bit clock polarity */
|
|
typedef enum _hal_audio_bclk_polarity
|
|
{
|
|
kHAL_AudioSampleOnFallingEdge = 0x00U, /*!< Data samples at the falling edge. */
|
|
kHAL_AudioSampleOnRisingEdge, /*!< Data samples at the rising edge. */
|
|
} hal_audio_bclk_polarity_t;
|
|
|
|
/*! @brief HAL Audio frame sync width */
|
|
typedef enum _hal_audio_frame_sync_width
|
|
{
|
|
kHAL_AudioFrameSyncWidthOneBitClk = 0x00U, /*!< 1 bit clock frame sync len for DSP mode */
|
|
kHAL_AudioFrameSyncWidthPerWordWidth, /*!< Frame sync length decided by word width */
|
|
kHAL_AudioFrameSyncWidthHalfFrame, /*!< Frame sync length is half of frame length */
|
|
} hal_audio_frame_sync_width_t;
|
|
|
|
/*! @brief HAL Audio frame sync polarity */
|
|
typedef enum _hal_audio_frame_sync_polarity
|
|
{
|
|
kHAL_AudioBeginAtRisingEdge = 0x00U, /*!< Frame sync begins at the rising edge. */
|
|
kHAL_AudioBeginAtFallingEdge, /*!< Frame sync begins at the falling edge. */
|
|
} hal_audio_frame_sync_polarity_t;
|
|
|
|
/*! @brief HAL Audio master or slave mode */
|
|
typedef enum _hal_audio_master_slave
|
|
{
|
|
kHAL_AudioMaster = 0x0U, /*!< Master mode include bclk and frame sync */
|
|
kHAL_AudioSlave, /*!< Slave mode include bclk and frame sync */
|
|
kHAL_AudioBclkMasterFrameSyncSlave, /*!< BCLK in master mode, frame sync in slave mode */
|
|
kHAL_AudioBclkSlaveFrameSyncMaster, /*!< BCLK in slave mode, frame sync in master mode */
|
|
} hal_audio_master_slave_t;
|
|
|
|
/*! @brief Synchronous or asynchronous mode, only for SAI configuration */
|
|
typedef enum _hal_audio_sai_sync_mode
|
|
{
|
|
kHAL_AudioSaiModeAsync = 0x0U, /*!< Asynchronous mode */
|
|
kHAL_AudioSaiModeSync, /*!< Synchronous mode (with receiver or transmit) */
|
|
} hal_audio_sai_sync_mode_t;
|
|
|
|
/*! @brief HAL Audio data format */
|
|
typedef enum _hal_audio_data_format
|
|
{
|
|
kHAL_AudioDataFormatI2sClassic = 0x0U, /*!< I2S classic mode */
|
|
kHAL_AudioDataFormatLeftJustified, /*!< Left-Justified mode */
|
|
kHAL_AudioDataFormatRightJustified, /*!< Right-Justified mode */
|
|
kHAL_AudioDataFormatDspModeA, /*!< DSP mode A, channel is available on 2nd rising edge of BCLK
|
|
following a rising edge of frame sync */
|
|
kHAL_AudioDataFormatDspModeB, /*!< DSP mode B, channel is available on 1st rising edge of BCLK
|
|
following a rising edge of frame sync */
|
|
} hal_audio_data_format_t;
|
|
|
|
/*! @brief HAL Audio DMA channel priority */
|
|
typedef enum _hal_audio_dma_channel_priority
|
|
{
|
|
kHAL_AudioDmaChannelPriority0 = 0x0U,
|
|
kHAL_AudioDmaChannelPriority1,
|
|
kHAL_AudioDmaChannelPriority2,
|
|
kHAL_AudioDmaChannelPriority3,
|
|
kHAL_AudioDmaChannelPriority4,
|
|
kHAL_AudioDmaChannelPriority5,
|
|
kHAL_AudioDmaChannelPriority6,
|
|
kHAL_AudioDmaChannelPriority7,
|
|
kHAL_AudioDmaChannelPriority8,
|
|
kHAL_AudioDmaChannelPriority9,
|
|
kHAL_AudioDmaChannelPriority10,
|
|
kHAL_AudioDmaChannelPriority11,
|
|
kHAL_AudioDmaChannelPriority12,
|
|
kHAL_AudioDmaChannelPriority13,
|
|
kHAL_AudioDmaChannelPriority14,
|
|
kHAL_AudioDmaChannelPriority15,
|
|
kHAL_AudioDmaChannelPriority16,
|
|
kHAL_AudioDmaChannelPriority17,
|
|
kHAL_AudioDmaChannelPriority18,
|
|
kHAL_AudioDmaChannelPriority19,
|
|
kHAL_AudioDmaChannelPriority20,
|
|
kHAL_AudioDmaChannelPriority21,
|
|
kHAL_AudioDmaChannelPriority22,
|
|
kHAL_AudioDmaChannelPriority23,
|
|
kHAL_AudioDmaChannelPriority24,
|
|
kHAL_AudioDmaChannelPriority25,
|
|
kHAL_AudioDmaChannelPriority26,
|
|
kHAL_AudioDmaChannelPriority27,
|
|
kHAL_AudioDmaChannelPriority28,
|
|
kHAL_AudioDmaChannelPriority29,
|
|
kHAL_AudioDmaChannelPriority30,
|
|
kHAL_AudioDmaChannelPriority31,
|
|
kHAL_AudioDmaChannelPriorityDefault = 0xFFU, /*!< Use default value, not to configure priority. */
|
|
} hal_audio_dma_channel_priority_t;
|
|
|
|
/*! @brief HAL Audio DMA mux user configuration */
|
|
typedef struct _hal_audio_dma_mux_config_t
|
|
{
|
|
union
|
|
{
|
|
struct
|
|
{
|
|
uint8_t dmaMuxInstance;
|
|
uint32_t dmaRequestSource;
|
|
} dmaMuxConfig;
|
|
};
|
|
} hal_audio_dma_mux_config_t;
|
|
|
|
/*! @brief HAL Audio DMA channel mux user configuration */
|
|
typedef struct _hal_audio_dma_channel_mux_config_t
|
|
{
|
|
union
|
|
{
|
|
struct
|
|
{
|
|
uint32_t dmaRequestSource;
|
|
} dmaChannelMuxConfig;
|
|
};
|
|
} hal_audio_dma_channel_mux_config_t;
|
|
|
|
/*! @brief HAL Audio DMA extra user configuration */
|
|
typedef struct _hal_audio_dma_extra_config_t
|
|
{
|
|
union
|
|
{
|
|
/* DMA4 use this structure */
|
|
struct
|
|
{
|
|
bool enableMasterIdReplication;
|
|
} edmaExtraConfig;
|
|
};
|
|
} hal_audio_dma_extra_config_t;
|
|
|
|
/*! @brief HAL Audio DMA user configuration */
|
|
typedef struct _hal_audio_dma_config
|
|
{
|
|
uint8_t instance; /*!< DMA instance */
|
|
uint8_t channel; /*!< DMA channel */
|
|
hal_audio_dma_channel_priority_t priority; /*!< DMA channel priority */
|
|
|
|
bool enablePreemption; /*!< If true, a channel can be suspended by other channel with higher priority.
|
|
Not all SOCs support this feature. For example, EDMA, DMA4 supports this feature.
|
|
For detailed information please refer to the SOC corresponding RM.
|
|
If not supported, the value should be set to false. */
|
|
bool enablePreemptAbility; /*!< If true, a channel can suspend other channel with low priority
|
|
Not all SOCs support this feature. For example, EDMA, DMA4 supports this feature.
|
|
For detailed information please refer to the SOC corresponding RM.
|
|
If not supported, the value should be set to false. */
|
|
void *dmaMuxConfig; /*!< The pointer points to an entity defined by hal_audio_dma_mux_config_t.
|
|
Not all SOCs support this feature. In general, when the macro
|
|
FSL_FEATURE_SOC_DMAMUX_COUNT is defined as non-zero, the SOC supports this
|
|
feature. For detailed information please refer to the SOC corresponding RM.
|
|
If not supported, the pointer should be set to NULL. */
|
|
void *dmaChannelMuxConfig; /*!< The pointer points to an entity defined by hal_audio_dma_channel_mux_config_t.
|
|
Not all SOCs support this feature. In general, when the macro
|
|
FSL_FEATURE_EDMA_HAS_CHANNEL_MUX is defined as non-zero, the SOC supports this
|
|
feature. For detailed information please refer to the SOC corresponding RM.
|
|
If not supported, the pointer should be set to NULL. */
|
|
void *dmaChannelConfig; /*!< The pointer points to an entity defined by channel configuration structure
|
|
that is defined in dma driver, such as edma_channel_config_t.
|
|
Not all SOCs support this feature. In general, when the macro
|
|
FSL_FEATURE_EDMA_HAS_CHANNEL_CONFIG is defined as non-zero, the SOC supports this
|
|
feature. For detailed information please refer to the SOC corresponding RM.
|
|
If not supported, the pointer should be set to NULL. */
|
|
void *dmaExtraConfig; /*!< The pointer points to an entity defined by hal_audio_dma_extra_config_t.
|
|
Some DMA IPs have extra configurations, such as EDMA, DMA4.
|
|
The structure is used for these extra configurations.
|
|
Not all SOCs support this feature. For detailed information please refer to the
|
|
SOC corresponding RM. If not supported, the pointer should be set to NULL. */
|
|
} hal_audio_dma_config_t;
|
|
|
|
/*! @brief HAL Audio IP specific feature configuration */
|
|
typedef struct _hal_audio_ip_config
|
|
{
|
|
union
|
|
{
|
|
/* SAI port use this structure */
|
|
struct
|
|
{
|
|
uint32_t lineMask; /*!< Writing one to the corresponding bit reprsents the corresponding data line is
|
|
enabled. lineMask = 0x1U, represents RX0/TX0 data line is enabled.
|
|
lineMask = 0xFU, represents RX0-3/TX0-3 data line are enabled. */
|
|
hal_audio_sai_sync_mode_t syncMode; /*!< SAI sync mode, control Tx/Rx clock sync */
|
|
} sai;
|
|
};
|
|
} hal_audio_ip_config_t;
|
|
|
|
/*! @brief HAL Audio configuration structure. */
|
|
typedef struct _hal_audio_config
|
|
{
|
|
hal_audio_dma_config_t *dmaConfig; /*!< DMA configuration */
|
|
void *ipConfig; /*!< IP specific feature configuration. The pointer
|
|
points to an entity defined by hal_audio_ip_config_t.
|
|
If there is no specific feature configuration, it should be set to NULL. */
|
|
|
|
uint32_t srcClock_Hz; /*!< Source clock */
|
|
uint32_t sampleRate_Hz; /*!< Sample rate */
|
|
uint16_t frameLength; /*!< Only flexcomm_i2s uses this field. In most cases, frameLength is equal to bitWidth
|
|
times lineChannels. In some cases, frameLength needs to be set to other value.
|
|
For example, when the number of bit clock on the bus between two neighboring WS
|
|
value is greater than bitWidth times lineChannels, frameLength needs to be set to
|
|
the value that is equal to the number of bit clock between two neighboring WS signal.
|
|
SAI does not use this field because frameLength can be determined internally
|
|
by bitWidth and lineChannels. */
|
|
|
|
uint16_t fifoWatermark; /*!< FIFO watermark value. Generally, the value is set to half the number of FIFO(F).
|
|
Note that the receive(R) or transmit length(T) is related to fifoWatermark(W) and
|
|
bitWidth(B). The relationship between them is: R = N * W * B, T = N * (F - W) * B
|
|
(N is integer). On some SOCs, the W and (F - W) is constant 1 and setting the W
|
|
does not take effect. In that case the fifoWatermark does not need to be set.
|
|
If the value set by application is greater than the number of FIFO,
|
|
a maximum value will be used. For example, if the number of FIFO is 32 on a SOC
|
|
but the watermark is set to 64 by application, the real value that is written to
|
|
register will be 31. */
|
|
|
|
hal_audio_master_slave_t msaterSlave; /*!< master or slave, configure where the bclk and frame sync come from. */
|
|
hal_audio_bclk_polarity_t bclkPolarity; /*!< bclk polarity, data sample on rising edge or falling edge. */
|
|
|
|
hal_audio_frame_sync_width_t frameSyncWidth; /*!< Only DSP mode uses this field. For other data format, this field
|
|
does not need to be set and the frameSyncWidth is determined
|
|
internally that depends on different mode. For example, for I2S
|
|
classic mode, frameSyncWidth is equal to bitWidth. */
|
|
hal_audio_frame_sync_polarity_t frameSyncPolarity; /*!< frame sync polarity, frame sync begin at rising or falling
|
|
edge. This field is not used now and reserved for future
|
|
use. The frameSyncPolarity is set internally that depends
|
|
on different mode. For example, for I2S classic mode,
|
|
frameSyncWidth is equal to kHAL_AudioBeginAtFallingEdge. */
|
|
|
|
hal_audio_channel_t lineChannels; /*!< Configure the number of channel on the data line. */
|
|
hal_audio_data_format_t dataFormat; /*!< data format on bus */
|
|
|
|
uint8_t bitWidth; /*!< Bit Width */
|
|
uint8_t instance; /*!< Instance (0 - I2S0/SAI0, 1 - I2S1/SAI1, ...), for detailed information please refer to the
|
|
SOC corresponding RM. Invalid instance value will cause initialization failure. */
|
|
} hal_audio_config_t;
|
|
|
|
/*! @brief HAL Audio transfer structure. */
|
|
typedef struct _hal_audio_transfer
|
|
{
|
|
uint8_t *data; /*!< A transfer buffer. */
|
|
size_t dataSize; /*!< A transfer size. */
|
|
} hal_audio_transfer_t;
|
|
|
|
/*! @brief HAL Audio transfer handle. */
|
|
typedef void *hal_audio_handle_t;
|
|
|
|
/*!
|
|
* @brief Defines the Audio handle
|
|
*
|
|
* This macro is used to define a 4 byte aligned Audio handle.
|
|
* Then use "(hal_audio_handle_t)name" to get the Audio handle.
|
|
*
|
|
* The macro should be global and could be optional. You could also define Audio handle by yourself.
|
|
*
|
|
* This is an example,
|
|
* @code
|
|
* HAL_AUDIO_HANDLE_DEFINE(audioTxHandle);
|
|
* @endcode
|
|
*
|
|
* @param name The name string of the Audio transfer handle.
|
|
*/
|
|
#define HAL_AUDIO_HANDLE_DEFINE(name) uint32_t name[(HAL_AUDIO_HANDLE_SIZE + sizeof(uint32_t) - 1U) / sizeof(uint32_t)]
|
|
|
|
/*!
|
|
* @brief HAL Audio completion callback function pointer type.
|
|
*
|
|
* This callback is used only for the non-blocking Audio transfer API. Specify the callback you wish to use
|
|
* in the call to HAL_AudioTxInstallCallback() or HAL_AudioRxInstallCallback().
|
|
*
|
|
* @param handle audio transfer handle pointer, this should be a static variable.
|
|
* @param completionStatus Either #kStatus_HAL_AudioIdle or an error code describing how the transfer completed.
|
|
* @param callbackParam Arbitrary pointer-sized value passed from the application.
|
|
*/
|
|
typedef void (*hal_audio_transfer_callback_t)(hal_audio_handle_t handle,
|
|
hal_audio_status_t completionStatus,
|
|
void *callbackParam);
|
|
|
|
/*******************************************************************************
|
|
* API
|
|
******************************************************************************/
|
|
|
|
#if defined(__cplusplus)
|
|
extern "C" {
|
|
#endif /*_cplusplus. */
|
|
|
|
/*!
|
|
* @name Initialization and de-initialization
|
|
* @{
|
|
*/
|
|
|
|
/*!
|
|
* @brief Initializes the HAL Audio peripheral.
|
|
*
|
|
* @note This API should be called at the beginning of the application.
|
|
* Otherwise, any operation to the HAL Audio module can cause a hard fault
|
|
* because the clock is not enabled. This function configures the audio
|
|
* with user-defined settings. The user can configure the configuration
|
|
* structure. The parameter handle is a pointer to point to a memory space
|
|
* of size #HAL_AUDIO_HANDLE_SIZE allocated by the caller.
|
|
*
|
|
* @note DMA will be initialized and enabled by default in this function and calling
|
|
* HAL_AudioTransferSendNonBlocking or HAL_AudioTransferReceiveNonBlocking will use
|
|
* DMA to transfer data. Thus application should avoid initializing DMA repeatedly
|
|
* and dmaConfig should be configured.
|
|
*
|
|
* Example below shows how to use this API to configure the audio peripheral.
|
|
* For SAI,
|
|
* @code
|
|
* HAL_AUDIO_HANDLE_DEFINE(audioTxHandle);
|
|
* hal_audio_config_t audioConfig;
|
|
* hal_audio_dma_config_t dmaConfig;
|
|
* hal_audio_ip_config_t ipConfig;
|
|
* hal_audio_dma_mux_config_t dmaMuxConfig;
|
|
* dmaMuxConfig.dmaMuxConfig.dmaMuxInstance = 0;
|
|
* dmaMuxConfig.dmaMuxConfig.dmaRequestSource = (uint32_t)kDmaRequestMuxSai1Tx;
|
|
* dmaConfig.instance = 0;
|
|
* dmaConfig.channel = 0;
|
|
* dmaConfig.priority = kHAL_AudioDmaChannelPriorityDefault;
|
|
* dmaConfig.enablePreemption = false;
|
|
* dmaConfig.enablePreemptAbility = false;
|
|
* dmaConfig.dmaMuxConfig = &dmaMuxConfig;
|
|
* dmaConfig.dmaChannelMuxConfig = NULL;
|
|
* ipConfig.sai.lineMask = 1U << 0U;
|
|
* ipConfig.sai.syncMode = kHAL_AudioSaiModeAsync;
|
|
* audioConfig.dmaConfig = &dmaConfig;
|
|
* audioConfig.ipConfig = &ipConfig;
|
|
* audioConfig.srcClock_Hz = 24576000;
|
|
* audioConfig.sampleRate_Hz = (uint32_t)kHAL_AudioSampleRate48KHz;
|
|
* audioConfig.fifoWatermark = 16;
|
|
* audioConfig.msaterSlave = kHAL_AudioMaster;
|
|
* audioConfig.bclkPolarity = kHAL_AudioSampleOnRisingEdge;
|
|
* audioConfig.frameSyncWidth = kHAL_AudioFrameSyncWidthHalfFrame;
|
|
* audioConfig.frameSyncPolarity = kHAL_AudioBeginAtFallingEdge;
|
|
* audioConfig.lineChannels = kHAL_AudioStereo;
|
|
* audioConfig.dataFormat = kHAL_AudioDataFormatI2sClassic;
|
|
* audioConfig.bitWidth = (uint8_t)kHAL_AudioWordWidth16bits;
|
|
* audioConfig.instance = 0U;
|
|
* HAL_AudioTxInit((hal_audio_handle_t)audioTxHandle, &audioConfig);
|
|
* @endcode
|
|
* For I2S,
|
|
* @code
|
|
* HAL_AUDIO_HANDLE_DEFINE(audioTxHandle);
|
|
* hal_audio_config_t audioConfig;
|
|
* hal_audio_dma_config_t dmaConfig;
|
|
* dmaConfig.instance = 0;
|
|
* dmaConfig.channel = 0;
|
|
* dmaConfig.priority = kHAL_AudioDmaChannelPriorityDefault;
|
|
* dmaConfig.enablePreemption = false;
|
|
* dmaConfig.enablePreemptAbility = false;
|
|
* dmaConfig.dmaMuxConfig = NULL;
|
|
* dmaConfig.dmaChannelMuxConfig = NULL;
|
|
* audioConfig.dmaConfig = &dmaConfig;
|
|
* audioConfig.ipConfig = NULL;
|
|
* audioConfig.srcClock_Hz = 24576000;
|
|
* audioConfig.sampleRate_Hz = (uint32_t)kHAL_AudioSampleRate48KHz;
|
|
* audioConfig.fifoWatermark = 0;
|
|
* audioConfig.msaterSlave = kHAL_AudioMaster;
|
|
* audioConfig.bclkPolarity = kHAL_AudioSampleOnRisingEdge;
|
|
* audioConfig.frameSyncWidth = kHAL_AudioFrameSyncWidthHalfFrame;
|
|
* audioConfig.frameSyncPolarity = kHAL_AudioBeginAtFallingEdge;
|
|
* audioConfig.lineChannels = kHAL_AudioStereo;
|
|
* audioConfig.dataFormat = kHAL_AudioDataFormatI2sClassic;
|
|
* audioConfig.bitWidth = (uint8_t)kHAL_AudioWordWidth16bits;
|
|
* audioConfig.instance = 0U;
|
|
* HAL_AudioTxInit((hal_audio_handle_t)audioTxHandle, &audioConfig);
|
|
* @endcode
|
|
*
|
|
* @param handle Pointer to point to a memory space of size #HAL_AUDIO_HANDLE_SIZE allocated by the caller.
|
|
* The handle should be 4 byte aligned, because unaligned access doesn't be supported on some devices.
|
|
* You can define the handle in the following two ways:
|
|
* #HAL_AUDIO_HANDLE_DEFINE(handle);
|
|
* or
|
|
* uint32_t handle[((HAL_AUDIO_HANDLE_SIZE + sizeof(uint32_t) - 1U) / sizeof(uint32_t))];
|
|
* @param config A pointer to the audio configuration structure
|
|
* @retval kStatus_HAL_AudioSuccess audio initialization succeed
|
|
*/
|
|
hal_audio_status_t HAL_AudioTxInit(hal_audio_handle_t handle, const hal_audio_config_t *config);
|
|
|
|
/*!
|
|
* @brief Initializes the HAL Audio peripheral.
|
|
*
|
|
* @note This API should be called at the beginning of the application.
|
|
* Otherwise, any operation to the HAL Audio module can cause a hard fault
|
|
* because the clock is not enabled. This function configures the audio
|
|
* with user-defined settings. The user can configure the configuration
|
|
* structure. The parameter handle is a pointer to point to a memory space
|
|
* of size #HAL_AUDIO_HANDLE_SIZE allocated by the caller.
|
|
*
|
|
* @note DMA will be initialized and enabled by default in this function and calling
|
|
* HAL_AudioTransferSendNonBlocking or HAL_AudioTransferReceiveNonBlocking will use
|
|
* DMA to transfer data. Thus application should avoid initializing DMA repeatedly
|
|
* and dmaConfig should be configured.
|
|
*
|
|
* Example below shows how to use this API to configure the audio peripheral.
|
|
* For SAI,
|
|
* @code
|
|
* HAL_AUDIO_HANDLE_DEFINE(audioRxHandle);
|
|
* hal_audio_config_t audioConfig;
|
|
* hal_audio_dma_config_t dmaConfig;
|
|
* hal_audio_ip_config_t ipConfig;
|
|
* hal_audio_dma_mux_config_t dmaMuxConfig;
|
|
* dmaMuxConfig.dmaMuxConfig.dmaMuxInstance = 0;
|
|
* dmaMuxConfig.dmaMuxConfig.dmaRequestSource = (uint32_t)kDmaRequestMuxSai1Rx;
|
|
* dmaConfig.instance = 0;
|
|
* dmaConfig.channel = 0;
|
|
* dmaConfig.priority = kHAL_AudioDmaChannelPriorityDefault;
|
|
* dmaConfig.enablePreemption = false;
|
|
* dmaConfig.enablePreemptAbility = false;
|
|
* dmaConfig.dmaMuxConfig = &dmaMuxConfig;
|
|
* dmaConfig.dmaChannelMuxConfig = NULL;
|
|
* ipConfig.sai.lineMask = 1U << 0U;
|
|
* ipConfig.sai.syncMode = kHAL_AudioSaiModeAsync;
|
|
* audioConfig.dmaConfig = &dmaConfig;
|
|
* audioConfig.ipConfig = &ipConfig;
|
|
* audioConfig.srcClock_Hz = 24576000;
|
|
* audioConfig.sampleRate_Hz = (uint32_t)kHAL_AudioSampleRate48KHz;
|
|
* audioConfig.fifoWatermark = 16;
|
|
* audioConfig.msaterSlave = kHAL_AudioMaster;
|
|
* audioConfig.bclkPolarity = kHAL_AudioSampleOnRisingEdge;
|
|
* audioConfig.frameSyncWidth = kHAL_AudioFrameSyncWidthHalfFrame;
|
|
* audioConfig.frameSyncPolarity = kHAL_AudioBeginAtFallingEdge;
|
|
* audioConfig.lineChannels = kHAL_AudioStereo;
|
|
* audioConfig.dataFormat = kHAL_AudioDataFormatI2sClassic;
|
|
* audioConfig.bitWidth = (uint8_t)kHAL_AudioWordWidth16bits;
|
|
* audioConfig.instance = 0U;
|
|
* HAL_AudioRxInit((hal_audio_handle_t)audioRxHandle, &audioConfig);
|
|
* @endcode
|
|
* For I2S,
|
|
* @code
|
|
* HAL_AUDIO_HANDLE_DEFINE(audioRxHandle);
|
|
* hal_audio_config_t audioConfig;
|
|
* hal_audio_dma_config_t dmaConfig;
|
|
* dmaConfig.instance = 0;
|
|
* dmaConfig.channel = 0;
|
|
* dmaConfig.priority = kHAL_AudioDmaChannelPriorityDefault;
|
|
* dmaConfig.enablePreemption = false;
|
|
* dmaConfig.enablePreemptAbility = false;
|
|
* dmaConfig.dmaMuxConfig = NULL;
|
|
* dmaConfig.dmaChannelMuxConfig = NULL;
|
|
* audioConfig.dmaConfig = &dmaConfig;
|
|
* audioConfig.ipConfig = NULL;
|
|
* audioConfig.srcClock_Hz = 24576000;
|
|
* audioConfig.sampleRate_Hz = (uint32_t)kHAL_AudioSampleRate48KHz;
|
|
* audioConfig.fifoWatermark = 0;
|
|
* audioConfig.msaterSlave = kHAL_AudioMaster;
|
|
* audioConfig.bclkPolarity = kHAL_AudioSampleOnRisingEdge;
|
|
* audioConfig.frameSyncWidth = kHAL_AudioFrameSyncWidthHalfFrame;
|
|
* audioConfig.frameSyncPolarity = kHAL_AudioBeginAtFallingEdge;
|
|
* audioConfig.lineChannels = kHAL_AudioStereo;
|
|
* audioConfig.dataFormat = kHAL_AudioDataFormatI2sClassic;
|
|
* audioConfig.bitWidth = (uint8_t)kHAL_AudioWordWidth16bits;
|
|
* audioConfig.instance = 0U;
|
|
* HAL_AudioRxInit((hal_audio_handle_t)audioRxHandle, &audioConfig);
|
|
* @endcode
|
|
*
|
|
* @param handle Pointer to point to a memory space of size #HAL_AUDIO_HANDLE_SIZE allocated by the caller.
|
|
* The handle should be 4 byte aligned, because unaligned access doesn't be supported on some devices.
|
|
* You can define the handle in the following two ways:
|
|
* #HAL_AUDIO_HANDLE_DEFINE(handle);
|
|
* or
|
|
* uint32_t handle[((HAL_AUDIO_HANDLE_SIZE + sizeof(uint32_t) - 1U) / sizeof(uint32_t))];
|
|
* @param config A pointer to the audio configuration structure
|
|
* @retval kStatus_HAL_AudioSuccess audio initialization succeed
|
|
*/
|
|
hal_audio_status_t HAL_AudioRxInit(hal_audio_handle_t handle, const hal_audio_config_t *config);
|
|
|
|
/*!
|
|
* @brief De-initializes the HAL Audio peripheral. Call this API to gate the HAL Audio clock.
|
|
* The HAL Audio module can't work unless the HAL_AudioTxInit is called.
|
|
*
|
|
* @param handle audio handle pointer, this should be a static variable.
|
|
* @retval kStatus_HAL_AudioSuccess audio de-initialization succeed */
|
|
hal_audio_status_t HAL_AudioTxDeinit(hal_audio_handle_t handle);
|
|
/*!
|
|
* @brief De-initializes the HAL Audio peripheral. Call this API to gate the HAL Audio clock.
|
|
* The HAL Audio module can't work unless the HAL_AudioRxInit is called.
|
|
*
|
|
* @param handle audio handle pointer, this should be a static variable.
|
|
* @retval kStatus_HAL_AudioSuccess audio de-initialization succeed */
|
|
hal_audio_status_t HAL_AudioRxDeinit(hal_audio_handle_t handle);
|
|
|
|
/*! @} */
|
|
|
|
/*!
|
|
* @name Transactional
|
|
* @{
|
|
*/
|
|
|
|
/*!
|
|
* @brief Installs a callback and callback parameter.
|
|
*
|
|
* This function is used to install the callback and callback parameter for audio module.
|
|
* When any status of the audio changed, the driver will notify the upper layer by the installed callback
|
|
* function. And the status is also passed as status parameter when the callback is called.
|
|
*
|
|
* @param handle audio handle pointer, this should be a static variable.
|
|
* @param callback pointer to user callback function.
|
|
* @param callbackParam user parameter passed to the callback function.
|
|
* @retval kStatus_HAL_AudioSuccess audio tx transfer handle created
|
|
*/
|
|
hal_audio_status_t HAL_AudioTxInstallCallback(hal_audio_handle_t handle,
|
|
hal_audio_transfer_callback_t callback,
|
|
void *callbackParam);
|
|
/*!
|
|
* @brief Installs a callback and callback parameter.
|
|
*
|
|
* This function is used to install the callback and callback parameter for audio module.
|
|
* When any status of the audio changed, the driver will notify the upper layer by the installed callback
|
|
* function. And the status is also passed as status parameter when the callback is called.
|
|
*
|
|
* @param handle audio handle pointer, this should be a static variable.
|
|
* @param callback pointer to user callback function.
|
|
* @param callbackParam user parameter passed to the callback function.
|
|
* @retval kStatus_HAL_AudioSuccess audio rx transfer handle created
|
|
*/
|
|
hal_audio_status_t HAL_AudioRxInstallCallback(hal_audio_handle_t handle,
|
|
hal_audio_transfer_callback_t callback,
|
|
void *callbackParam);
|
|
|
|
/*!
|
|
* @brief Performs a DMA non-blocking send on the data bus.
|
|
*
|
|
* @note Calling the API returns immediately after transfer initiates. The user can
|
|
* call HAL_AudioTransferGetSendCount to poll the transfer status to check whether
|
|
* the transfer is finished. If the return status is kStatus_HAL_AudioIdle, the transfer
|
|
* is finished.
|
|
*
|
|
* @param handle audio handle pointer, this should be a static variable.
|
|
* @param xfer pointer to hal_audio_transfer_t structure.
|
|
*
|
|
* @note The transmit length(T) is related to fifoWatermark(W), bitWidth(B) and the number of FIFO(F).
|
|
* The relationship between them is: T = N * (F - W) * B (N is integer).
|
|
*
|
|
* @retval kStatus_HAL_AudioSuccess Successfully start the data transmission.
|
|
* @retval kStatus_HAL_AudioBusy Previous transmission still not finished.
|
|
* @retval kStatus_HAL_AudioError An error occurred.
|
|
*/
|
|
hal_audio_status_t HAL_AudioTransferSendNonBlocking(hal_audio_handle_t handle, hal_audio_transfer_t *xfer);
|
|
|
|
/*!
|
|
* @brief Performs a DMA non-blocking receive on the HAL Audio bus.
|
|
*
|
|
* @note Calling the API returns immediately after transfer initiates. The user can
|
|
* call HAL_AudioTransferGetReceiveCount to poll the transfer status to check whether
|
|
* the transfer is finished. If the return status is kStatus_HAL_AudioIdle, the transfer
|
|
* is finished.
|
|
*
|
|
* @param handle audio handle pointer, this should be a static variable.
|
|
* @param xfer pointer to hal_audio_transfer_t structure.
|
|
*
|
|
* @note The receive length(R) is related to fifoWatermark(W), bitWidth(B) and the number of FIFO(F).
|
|
* The relationship between them is: R = N * W * B (N is integer).
|
|
*
|
|
* @retval kStatus_HAL_AudioSuccess Successfully start the data transmission.
|
|
* @retval kStatus_HAL_AudioBusy Previous transmission still not finished.
|
|
* @retval kStatus_HAL_AudioError An error occurred.
|
|
*/
|
|
hal_audio_status_t HAL_AudioTransferReceiveNonBlocking(hal_audio_handle_t handle, hal_audio_transfer_t *xfer);
|
|
|
|
/*!
|
|
* @brief Aborts a DMA non-blocking transfer early.
|
|
*
|
|
* @note This API can be called at any time when a DMA non-blocking transfer initiates
|
|
* to abort the transfer early.
|
|
*
|
|
* @param handle audio handle pointer, this should be a static variable.
|
|
* @retval kStatus_HAL_AudioSuccess Successfully abort the transfer.
|
|
*/
|
|
hal_audio_status_t HAL_AudioTransferAbortSend(hal_audio_handle_t handle);
|
|
|
|
/*!
|
|
* @brief Aborts a DMA non-blocking transfer early.
|
|
*
|
|
* @note This API can be called at any time when a DMA non-blocking transfer initiates
|
|
* to abort the transfer early.
|
|
*
|
|
* @param handle audio handle pointer, this should be a static variable.
|
|
* @retval kStatus_HAL_AudioSuccess Successfully abort the transfer.
|
|
*/
|
|
hal_audio_status_t HAL_AudioTransferAbortReceive(hal_audio_handle_t handle);
|
|
|
|
/*!
|
|
* @brief Gets the tx transfer status during a DMA non-blocking transfer.
|
|
*
|
|
* @param handle audio handle pointer, this should be a static variable.
|
|
* @param count Number of bytes sent so far by the non-blocking transaction.
|
|
* @retval kStatus_HAL_AudioSuccess Successfully return the count.
|
|
* @retval kStatus_HAL_AudioIdle Previous transmission has been finished.
|
|
* @retval kStatus_HAL_AudioError An error occurred.
|
|
*/
|
|
hal_audio_status_t HAL_AudioTransferGetSendCount(hal_audio_handle_t handle, size_t *count);
|
|
/*!
|
|
* @brief Gets the rx transfer status during a DMA non-blocking transfer.
|
|
*
|
|
* @param handle audio handle pointer, this should be a static variable.
|
|
* @param count Number of bytes received so far by the non-blocking transaction.
|
|
* @retval kStatus_HAL_AudioSuccess Successfully return the count.
|
|
* @retval kStatus_HAL_AudioIdle Previous transmission has been finished.
|
|
* @retval kStatus_HAL_AudioError An error occurred.
|
|
*/
|
|
hal_audio_status_t HAL_AudioTransferGetReceiveCount(hal_audio_handle_t handle, size_t *count);
|
|
|
|
/*! @} */
|
|
|
|
#if defined(__cplusplus)
|
|
}
|
|
#endif /*_cplusplus. */
|
|
/*! @} */
|
|
|
|
#endif /* __HAL_AUDIO_ADAPTER_H__*/
|