#ifndef _HAL_AUDIO_SRC_H_
#define _HAL_AUDIO_SRC_H_
#include "hal_dma.h"
#include "hal_def.h"
#include "hal_audio.h"

typedef enum
{
    HIGH_16BIT,
    LOW_16BIT,
    HIGH_24BIT,
    LOW_24BIT,
} src_inout_fmt_typedef;

typedef enum
{
    LVL_256,
    LVL_512,
    LVL_768,
    LVL_1024,
} src_wbuf_half_lvl_typedef;


typedef enum
{
    RX_MEM_FIFO,
    RX_ADC_FIFO,
    RX_ASI0_FIFO,
    RX_ASI1_FIFO,
} src_src_data_sel_typedef;

typedef enum
{
    TX_MEM_FIFO,
    TX_DAC_FIFO,
    TX_ASI0_FIFO,
    TX_ASI1_FIFO,
} src_dst_data_sel_typedef;

typedef enum
{
    RX_MEM_TX_MEM  = ((DEV_SRC_CHNn_CFG_RX_DEV_SEL_DEV0RXFIFO) + (DEV_SRC_CHNn_CFG_TX_DEV_SEL_DEV0TXFIFO)),
    RX_MEM_TX_DAC  = ((DEV_SRC_CHNn_CFG_RX_DEV_SEL_DEV0RXFIFO) + (DEV_SRC_CHNn_CFG_TX_DEV_SEL_DEV1TXFIFO)),
    RX_MEM_TX_ASI0  = ((DEV_SRC_CHNn_CFG_RX_DEV_SEL_DEV0RXFIFO) + (DEV_SRC_CHNn_CFG_TX_DEV_SEL_DEV2TXFIFO)),
    RX_MEM_TX_ASI1  = ((DEV_SRC_CHNn_CFG_RX_DEV_SEL_DEV0RXFIFO) + (DEV_SRC_CHNn_CFG_TX_DEV_SEL_DEV3TXFIFO)),

    RX_ADC_TX_MEM  = ((DEV_SRC_CHNn_CFG_RX_DEV_SEL_DEV1RXFIFO) + (DEV_SRC_CHNn_CFG_TX_DEV_SEL_DEV0TXFIFO)),
    RX_ADC_TX_DAC  = ((DEV_SRC_CHNn_CFG_RX_DEV_SEL_DEV1RXFIFO) + (DEV_SRC_CHNn_CFG_TX_DEV_SEL_DEV1TXFIFO)),
    RX_ADC_TX_ASI0 = ((DEV_SRC_CHNn_CFG_RX_DEV_SEL_DEV1RXFIFO) + (DEV_SRC_CHNn_CFG_TX_DEV_SEL_DEV2TXFIFO)),
    RX_ADC_TX_ASI1 = ((DEV_SRC_CHNn_CFG_RX_DEV_SEL_DEV1RXFIFO) + (DEV_SRC_CHNn_CFG_TX_DEV_SEL_DEV3TXFIFO)),

    RX_ASI0_TX_MEM  = ((DEV_SRC_CHNn_CFG_RX_DEV_SEL_DEV2RXFIFO) + (DEV_SRC_CHNn_CFG_TX_DEV_SEL_DEV0TXFIFO)),
    RX_ASI0_TX_DAC  = ((DEV_SRC_CHNn_CFG_RX_DEV_SEL_DEV2RXFIFO) + (DEV_SRC_CHNn_CFG_TX_DEV_SEL_DEV1TXFIFO)),
    RX_ASI0_TX_ASI0  = ((DEV_SRC_CHNn_CFG_RX_DEV_SEL_DEV2RXFIFO) + (DEV_SRC_CHNn_CFG_TX_DEV_SEL_DEV2TXFIFO)),
    RX_ASI0_TX_ASI1  = ((DEV_SRC_CHNn_CFG_RX_DEV_SEL_DEV2RXFIFO) + (DEV_SRC_CHNn_CFG_TX_DEV_SEL_DEV3TXFIFO)),

    RX_ASI1_TX_MEM  = ((DEV_SRC_CHNn_CFG_RX_DEV_SEL_DEV3RXFIFO) + (DEV_SRC_CHNn_CFG_TX_DEV_SEL_DEV0TXFIFO)),
    RX_ASI1_TX_DAC  = ((DEV_SRC_CHNn_CFG_RX_DEV_SEL_DEV3RXFIFO) + (DEV_SRC_CHNn_CFG_TX_DEV_SEL_DEV1TXFIFO)),
    RX_ASI1_TX_ASI0 = ((DEV_SRC_CHNn_CFG_RX_DEV_SEL_DEV3RXFIFO) + (DEV_SRC_CHNn_CFG_TX_DEV_SEL_DEV2TXFIFO)),
    RX_ASI1_TX_ASI1 = ((DEV_SRC_CHNn_CFG_RX_DEV_SEL_DEV3RXFIFO) + (DEV_SRC_CHNn_CFG_TX_DEV_SEL_DEV3TXFIFO)),
} src_dev_sel_typedef;


typedef enum
{
    SAMPLE_RATE_8K_16K,
    SAMPLE_RATE_8K_24K,
    SAMPLE_RATE_8K_48K,
    SAMPLE_RATE_48K_8K,
    SAMPLE_RATE_24K_8K,
    SAMPLE_RATE_16K_8K,
    SAMPLE_RATE_NUMBER,
} src_frq_sel_typedef;

typedef enum
{
    SRC_STEREO,
    SRC_MONO,
} src_track_sel_typedef;

typedef enum
{
    SOFT_SRC,
    HARD_SRC,
} src_mode_sel_typedef;

typedef struct _src_shift_sel_typedef
{
    uint32_t        sel3;
    uint32_t        sel2;
    uint32_t        sel1;
    uint32_t        sel0;
} src_shift_sel_typedef;

typedef struct _src_filter_cfg_typedef
{
    uint32_t   *cbuf_addr;
    src_shift_sel_typedef  shift;
} src_filter_cfg_typedef;




typedef struct  _src_init_typedef
{
    src_dev_sel_typedef        dev_sel;
    uint32_t                   input_sampe_rate;
    uint32_t                   output_sampe_rate;
    src_inout_fmt_typedef      input_fmt;
    src_inout_fmt_typedef      output_fmt;
    src_track_sel_typedef      track;
} src_init_typedef;


typedef struct  _audio_src_handle_typedef
{
    SRC_CHN_RegDef_f        *Instance;    /*!< Register base address */
    src_init_typedef        init;
    DMA_HandleTypeDef       *dma_rx_handle; /*!< Pointer DMA Handler */
    DMA_HandleTypeDef       *dma_tx_handle; /*!< Pointer DMA Handler */
    void (* src_rx_dma_full_pcall_back)(struct __DMA_HandleTypeDef *hdma, void *param);
    void (* src_rx_dma_half_pcall_back)(struct __DMA_HandleTypeDef *hdma, void *param);
    void (* src_tx_dma_full_pcall_back)(struct __DMA_HandleTypeDef *hdma, void *param);
    void (* src_tx_dma_half_pcall_back)(struct __DMA_HandleTypeDef *hdma, void *param);
    audio_state_type_def    state;
    __IO uint32_t           err_code;
    uint32_t                *cfg_buff;
} audio_src_handle_typedef;

HAL_StatusTypeDef hal_src_init(audio_src_handle_typedef *hsrc);
HAL_StatusTypeDef src_cmd(audio_src_handle_typedef *hsrc, Options_EnableEnum cmd);
HAL_StatusTypeDef src_deinit(audio_src_handle_typedef *hsrc);
void sample_src1_rate_updata(void);
void sample_src0_rate_updata(void);
void src1_set_rate(uint32_t input_sampe_rate,uint32_t output_sampe_rate);
void src0_set_rate(uint32_t input_sampe_rate,uint32_t output_sampe_rate);
uint32_t src_wbuff_printf(void);

#define SRC0                ((SRC_CHN_RegDef_f *)_IO_((uint32_t)0x20170000 + 0x100*0))
#define SRC1                ((SRC_CHN_RegDef_f *)_IO_((uint32_t)0x20170000 + 0x100*1))


#endif
