Files
test/drivers/include/sdrv_pdm.h
2025-11-07 20:19:23 +08:00

343 lines
9.0 KiB
C

/**
* @file sdrv_pdm.h
* @brief SemiDrive pdm driver header file.
*
* @copyright Copyright (c) 2021 Semidrive Semiconductor.
* All rights reserved.
*/
#ifndef SDRV_PDM_H_
#define SDRV_PDM_H_
#include <types.h>
#include "sdrv_ckgen.h"
#include "sdrv_common.h"
#include "sdrv_dma.h"
/* sdrv pdm max transfres */
#define SDRV_PDM_XFER_NUM_TRANSFERS (4U)
/* sdrv pdm dma buff size default value */
#define SDRV_PDM_CHANNELS_COUNT 1
#define SDRV_PDM_CHANNELS_BYTES (SDRV_PDM_SAMPLE_WIDTH_16BITS / 8)
#define SDRV_PDM_DMA_PERIOD_FRAME_SIZE 1024 * 4
#define SDRV_PDM_DMA_PERIOD_SIZE \
SDRV_PDM_DMA_PERIOD_FRAME_SIZE *SDRV_PDM_CHANNELS_COUNT \
*SDRV_PDM_CHANNELS_BYTES
#define SDRV_PDM_DMA_PERIOD_COUNT 2
#define SDRV_PDM_DMA_BUF_TOTAL_SIZE \
SDRV_PDM_DMA_PERIOD_SIZE *SDRV_PDM_DMA_PERIOD_COUNT
/**
* @brief pdm channel
*
*/
typedef enum sdrv_pdm_channel {
SDRV_PDM_CHANNEL_LEFT = 0x00,
SDRV_PDM_CHANNEL_RIGHT = 0x01,
SDRV_PDM_CHANNEL_STEREO = 0x02,
} sdrv_pdm_channel_t;
/**
* @brief pdm gain
*
*/
typedef enum sdrv_pdm_gain {
SDRV_PDM_GAIN_N6DB = 0x01,
SDRV_PDM_GAIN_N12DB = 0x02,
SDRV_PDM_GAIN_N18DB = 0x03,
SDRV_PDM_GAIN_N24DB = 0x04,
SDRV_PDM_GAIN_P0DB = 0x05,
SDRV_PDM_GAIN_P6DB = 0x06,
SDRV_PDM_GAIN_P12DB = 0x07,
SDRV_PDM_GAIN_P18DB = 0x08,
SDRV_PDM_GAIN_P24DB = 0x09,
} sdrv_pdm_gain_t;
/**
* @brief pdm sample rate
*
*/
typedef enum sdrv_pdm_sample_rate {
SDRV_PDM_SR_5512 = 5512,
SDRV_PDM_SR_8000 = 8000,
SDRV_PDM_SR_11025 = 11025,
SDRV_PDM_SR_16000 = 16000,
SDRV_PDM_SR_22050 = 22050,
SDRV_PDM_SR_32000 = 32000,
SDRV_PDM_SR_44100 = 44100,
SDRV_PDM_SR_48000 = 48000,
SDRV_PDM_SR_64000 = 64000,
SDRV_PDM_SR_88200 = 88200,
SDRV_PDM_SR_96000 = 96000,
SDRV_PDM_SR_176400 = 176400,
SDRV_PDM_SR_192000 = 192000,
} sdrv_pdm_sample_rate_t;
/**
* @brief pdm sample width
*
*/
typedef enum sdrv_pdm_sample_width {
SDRV_PDM_SAMPLE_WIDTH_8BITS = 8,
SDRV_PDM_SAMPLE_WIDTH_16BITS = 16,
SDRV_PDM_SAMPLE_WIDTH_24BITS = 24,
SDRV_PDM_SAMPLE_WIDTH_32BITS = 32,
} sdrv_pdm_sample_width_t;
/**
* @brief pdm status
*
*/
typedef enum sdrv_pdm_status {
/* status for Success */
SDRV_PDM_STATUS_SUCCESS = SDRV_ERROR_STATUS(SDRV_STATUS_GROUP_COMMON, 0),
/* status for Fail */
SDRV_PDM_STATUS_FAIL = SDRV_ERROR_STATUS(SDRV_STATUS_GROUP_PDM, 1),
/* status for invalid argument check */
SDRV_PDM_STATUS_INVALID_PARAMS =
SDRV_ERROR_STATUS(SDRV_STATUS_GROUP_PDM, 2),
/* status for Overrun */
SDRV_PDM_STATUS_OVERRUN = SDRV_ERROR_STATUS(SDRV_STATUS_GROUP_PDM, 3),
/* status for underrun */
SDRV_PDM_STATUS_UNDERRUN = SDRV_ERROR_STATUS(SDRV_STATUS_GROUP_PDM, 4),
} sdrv_pdm_status_t;
/**
* @brief pdm dma fifo descriptions
*
*/
typedef struct sdrv_pdm_dma_data {
/**< pdm fifo base addr */
paddr_t addr;
/**< pdm fifo width */
sdrv_dma_bus_width_e addr_width;
/**< pdm fifo max transfer size */
unsigned int max_burst;
/**< pdm fifo fifo size */
unsigned int fifo_size;
} sdrv_pdm_dma_data_t;
/**
* @brief pdm dma buff descriptions
*
*
*/
typedef struct sdrv_pdm_dma_buf {
/**< dma mode ,buffer address */
uint8_t *addr;
/**< buffer size */
int32_t buffer_bytes;
/**< buffer period_size */
int32_t period_bytes;
/**< buffer period count */
int32_t periods;
/**< app write pointer during playback, dma read pointer
during capture */
uint32_t appl_ptr;
/**< dma read pointer during playback, dma write pointer
during capture */
uint32_t hw_ptr;
/**< dma buff boundary */
uint32_t boundary;
} sdrv_pdm_dma_buf_t;
/**
* @brief pdm transfer
*
*/
typedef struct sdrv_pdm_transfer {
/**< audio data addr */
uint8_t *data;
/**< audio data length */
uint32_t length;
/**< transfer tag */
uint8_t id;
} sdrv_pdm_transfer_t;
/* @brief sdrv pdm transfer callback function. */
typedef void (*sdrv_pdm_callback)(sdrv_pdm_transfer_t *transfer, void *context,
sdrv_pdm_status_t state);
/**
* @brief pdm config params
*
*/
typedef struct sdrv_pdm_params {
/**< data channels */
sdrv_pdm_channel_t channels;
/**< data width */
sdrv_pdm_sample_width_t sample_width;
/**< data sample rate */
sdrv_pdm_sample_rate_t sample_rate;
/**< data gain */
sdrv_pdm_gain_t gain;
/**< dma mode must set, dma generates an interrupt
transmission data size */
unsigned int period_bytes;
/**< dma mode must set, dma generates an interrupt
transmission data size */
unsigned int periods;
/**< dma mode need set dma_buf addr, size=period_count*period_size */
uint8_t *dma_buff;
/**< true :dma mode; false:irq mode */
bool usedma;
} sdrv_pdm_params_t;
/**
* @brief pdm capture stream descriptions
*
*/
typedef struct sdrv_pdm_stream {
/**< pdm config params */
sdrv_pdm_params_t params;
/**< app submit transfer ,max is SDRV_PDM_XFER_NUM_TRANSFERS */
sdrv_pdm_transfer_t queue[SDRV_PDM_XFER_NUM_TRANSFERS];
/**< stream status; true : running false:idle */
bool active;
/**< app submit enqueue transfer index */
uint8_t queue_appl;
/**< hw dequeue transfer index */
uint8_t queue_hw;
/**< user callback */
sdrv_pdm_callback callback;
/**< user callback context */
void *context;
/**< data pack or loose mode in fifo */
bool pack_mode;
/**< data format in fifo */
bool data_lsb;
/**< pdm request dma transfer when fifo data is <= threshold for capture */
unsigned threshold;
/**< dma module instance handle */
sdrv_dma_t dma_instance;
/**< dma module channel handle */
sdrv_dma_channel_t dma_channel;
/**< dma fifo descriptions */
sdrv_pdm_dma_data_t dma_data;
/**< dma mode must set dma_buf addr, size=period_count*period_size */
sdrv_pdm_dma_buf_t dma_buf;
bool dma_abort;
} sdrv_pdm_stream_t;
/**
* @brief pdm board config
*
*/
typedef struct sdrv_pdm_config {
/**< pdm module base addr */
paddr_t base;
/**< pdm index in saci */
int id;
/**< pdm module irq num */
uint32_t irq;
/**< pdm module clk */
sdrv_ckgen_node_t *clk;
/**< dma used by pdm, which is dma base addr */
paddr_t dma_base;
/**< dma used by pdm, which is dma channel */
sdrv_dma_channel_id_e dma_channel;
} sdrv_pdm_config_t;
/**
* @brief pdm module descriptions
*
*/
typedef struct sdrv_pdm {
/**< pdm board config */
sdrv_pdm_config_t *config;
/**< pdm_ctrl work clk rate */
uint32_t clk_rate;
/**< pdm capture descriptions */
sdrv_pdm_stream_t stream;
} sdrv_pdm_t;
/**
* @brief sdrv pdm controller initialization.
*
* This function is used to initialize pdm module
* function.
*
* @param [in] pdm sdrv pdm controller
* @param [in] cfg sdrv pdm controller configurations
* @return sdrv_pdm_status_t
*
*/
sdrv_pdm_status_t sdrv_pdm_init(sdrv_pdm_t *pdm, sdrv_pdm_config_t *cfg);
/**
* @brief sdrv_pdm_get_default_params
*
* This function is used to get pdm default params
*
* @param [in] pdm sdrv pdm controller
* @param [out] params sdrv pdm params
* @return sdrv_pdm_status_t
*
*/
sdrv_pdm_status_t sdrv_pdm_get_default_params(sdrv_pdm_t *pdm,
sdrv_pdm_params_t *params);
/**
* @brief sdrv_pdm_set_params
*
* This function is used to set pdm params
*
* @param [in] pdm sdrv pdm controller
* @param [in] params sdrv pdm params
* @return sdrv_pdm_status_t
*
*
*/
sdrv_pdm_status_t sdrv_pdm_set_params(sdrv_pdm_t *pdm,
sdrv_pdm_params_t *params);
/**
* @brief sdrv_pdm_create_transfer
*
* This function is used to create transfer and attach transfer callback
*
* @param [in] pdm sdrv pdm controller
* @param [in] callback sdrv pdm transfer callback function.
* @param [in] context sdrv pdm transfer callback param.
* @return sdrv_pdm_status_t
*/
sdrv_pdm_status_t sdrv_pdm_create_transfer(sdrv_pdm_t *pdm,
sdrv_pdm_callback callback,
void *context);
/**
* @brief sdrv_pdm_submit_transfer
*
* This function is used to submit transfer, which's max num is
* SDRV_PDM_XFER_NUM_BUFFERS
*
* @param [in] pdm sdrv pdm controller
* @param [in] transfer sdrv pdm transfer
* @return sdrv_pdm_status_t
*/
sdrv_pdm_status_t sdrv_pdm_submit_transfer(sdrv_pdm_t *pdm,
sdrv_pdm_transfer_t *transfer);
/**
* @brief sdrv_pdm_start
*
* This function is used to start pdm transfer
*
* @param [in] pdm sdrv pdm controller
* @return sdrv_pdm_status_t
*/
sdrv_pdm_status_t sdrv_pdm_start(sdrv_pdm_t *pdm);
/**
* @brief sdrv_pdm_stop
*
* This function is used to stop pdm transfer
*
* @param [in] pdm sdrv pdm controller
* @return sdrv_pdm_status_t
*/
sdrv_pdm_status_t sdrv_pdm_stop(sdrv_pdm_t *pdm);
#endif /* SDRV_PDM_H_ */