mirror of
https://github.com/espressif/esp-idf.git
synced 2026-10-01 18:50:34 +03:00
feat(asrc): Support asrc hal on esp32s31
Closes IDF-14564
This commit is contained in:
@@ -0,0 +1,70 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2026 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include "hal/asrc_ll.h"
|
||||
#include "hal/asrc_hal.h"
|
||||
|
||||
void asrc_hal_init(asrc_hal_context_t *hal)
|
||||
{
|
||||
hal->dev = ASRC_LL_GET_HW();
|
||||
}
|
||||
|
||||
void asrc_hal_enable_asrc_module(asrc_hal_context_t *hal, bool enable)
|
||||
{
|
||||
asrc_ll_enable_asrc_module(enable);
|
||||
}
|
||||
|
||||
void asrc_hal_init_stream(asrc_hal_context_t *hal, asrc_hal_config_t *asrc_cfg, uint8_t asrc_idx)
|
||||
{
|
||||
asrc_ll_stop_stream(hal->dev, asrc_idx);
|
||||
asrc_ll_reset_stream(hal->dev, asrc_idx);
|
||||
asrc_ll_reset_input_fifo(hal->dev, asrc_idx);
|
||||
asrc_ll_reset_output_fifo(hal->dev, asrc_idx);
|
||||
asrc_ll_set_channel_mode(hal->dev, asrc_idx, asrc_cfg->src_info.channel,
|
||||
asrc_cfg->dest_info.channel, asrc_cfg->weight, asrc_cfg->weight_len);
|
||||
asrc_ll_set_rate_reg(hal->dev, asrc_idx, asrc_cfg->src_info.sample_rate, asrc_cfg->dest_info.sample_rate);
|
||||
asrc_ll_clear_incnt_counter(hal->dev, asrc_idx);
|
||||
asrc_ll_clear_outcnt_counter(hal->dev, asrc_idx);
|
||||
asrc_ll_enable_outcnt_counter(hal->dev, asrc_idx);
|
||||
asrc_ll_set_eof_mode(hal->dev, asrc_idx, 0);
|
||||
asrc_ll_enable_outsample_comp(hal->dev, asrc_idx);
|
||||
}
|
||||
|
||||
void asrc_hal_deinit_stream(asrc_hal_context_t *hal, uint8_t asrc_idx)
|
||||
{
|
||||
asrc_ll_stop_stream(hal->dev, asrc_idx);
|
||||
asrc_ll_reset_stream(hal->dev, asrc_idx);
|
||||
asrc_ll_reset_input_fifo(hal->dev, asrc_idx);
|
||||
asrc_ll_reset_output_fifo(hal->dev, asrc_idx);
|
||||
asrc_ll_clear_incnt_counter(hal->dev, asrc_idx);
|
||||
asrc_ll_clear_outcnt_counter(hal->dev, asrc_idx);
|
||||
}
|
||||
|
||||
void asrc_hal_set_in_bytes_num(asrc_hal_context_t *hal, uint8_t asrc_idx, uint32_t in_bytes_num)
|
||||
{
|
||||
asrc_ll_set_in_bytes_num(hal->dev, asrc_idx, in_bytes_num);
|
||||
}
|
||||
|
||||
void asrc_hal_set_out_bytes_num(asrc_hal_context_t *hal, uint8_t asrc_idx, uint32_t out_bytes_num)
|
||||
{
|
||||
asrc_ll_set_out_bytes_num(hal->dev, asrc_idx, out_bytes_num);
|
||||
}
|
||||
|
||||
void asrc_hal_start(asrc_hal_context_t *hal, uint8_t asrc_idx)
|
||||
{
|
||||
asrc_ll_start_stream(hal->dev, asrc_idx);
|
||||
}
|
||||
|
||||
uint32_t asrc_hal_get_out_data_bytes(asrc_hal_context_t *hal, uint8_t asrc_idx)
|
||||
{
|
||||
return asrc_ll_get_outbytes_cnt(hal->dev, asrc_idx);
|
||||
}
|
||||
|
||||
void asrc_hal_deinit(asrc_hal_context_t *hal)
|
||||
{
|
||||
hal->dev = NULL;
|
||||
}
|
||||
@@ -0,0 +1,63 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2026 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#include "hal/asrc_periph.h"
|
||||
|
||||
/**
|
||||
* @brief ASRC rate conversion configuration lookup table
|
||||
* Table structure: asrc_periph_rate_table[src_rate_index][dest_rate_index]
|
||||
* Rate index mapping: 0=8kHz, 1=16kHz, 2=24kHz, 3=32kHz, 4=44.1kHz, 5=48kHz
|
||||
*/
|
||||
const asrc_periph_rate_config_t asrc_periph_rate_table[6][6] = {
|
||||
{
|
||||
{1, 1, 1, 0, 0, 0, 0, 0, 0}, // 8k->8k (bypass)
|
||||
{1, 0, 1, 0, 0, 0, 0, 0, 0}, // 8k->16k (up_2)
|
||||
{0, 0, 0, 0, 0, 0, 4, 3, (int)(((1 << 20) + 3) / (2 * 3))}, // 8k->32k->24k (up_4 + frac: 4/3)
|
||||
{0, 0, 1, 0, 0, 0, 0, 0, 0}, // 8k->32k (up_4)
|
||||
{0, 0, 0, 0, 0, 0, 320, 441, (int)(((1 << 20) + 441) / (2 * 441))}, // 8k->32k->44.1k (up_4 + frac: 320/441)
|
||||
{0, 0, 0, 0, 0, 0, 2, 3, (int)(((1 << 20) + 3) / (2 * 3))} // 8k->32k->48k (up_4 + frac: 2/3)
|
||||
},
|
||||
{
|
||||
{1, 0, 1, 0, 1, 0, 0, 0, 0}, // 16k->8k (down_2)
|
||||
{1, 1, 1, 0, 0, 0, 0, 0, 0}, // 16k->16k (bypass)
|
||||
{1, 0, 0, 0, 0, 0, 4, 3, (int)(((1 << 20) + 3) / (2 * 3))}, // 16k->32k->24k (up_2 + frac: 4/3)
|
||||
{1, 0, 1, 0, 0, 0, 0, 0, 0}, // 16k->32k (up_2)
|
||||
{1, 0, 0, 0, 0, 0, 320, 441, (int)(((1 << 20) + 441) / (2 * 441))}, // 16k->32k->44.1k (up_2 + frac: 320/441)
|
||||
{1, 0, 0, 0, 0, 0, 2, 3, (int)(((1 << 20) + 3) / (2 * 3))} // 16k->32k->48k (up_2 + frac: 2/3)
|
||||
},
|
||||
{
|
||||
{0, 0, 0, 1, 1, 1, 3, 4, (int)(((1 << 20) + 4) / (2 * 4))}, // 24k->32k->8k (frac: 3/4 + down_4)
|
||||
{1, 0, 0, 0, 1, 1, 3, 4, (int)(((1 << 20) + 4) / (2 * 4))}, // 24k->32k->16k (frac: 3/4 + down_2)
|
||||
{1, 1, 1, 0, 0, 0, 0, 0, 0}, // 24k->24k (bypass)
|
||||
{1, 1, 0, 0, 0, 1, 3, 4, (int)(((1 << 20) + 4) / (2 * 4))}, // 24k->32k (frac: 3/4)
|
||||
{0, 0, 0, 0, 0, 0, 320, 147, (int)(((1 << 20) + 147) / (2 * 147))}, // 24k->96k->44.1k (up_4 + frac: 320/147)
|
||||
{1, 0, 1, 0, 0, 0, 0, 0, 0} // 24k->48k (up_2)
|
||||
},
|
||||
{
|
||||
{0, 0, 1, 1, 1, 0, 0, 0, 0}, // 32k->8k (down_4)
|
||||
{1, 0, 1, 0, 1, 0, 0, 0, 0}, // 32k->16k (down_2)
|
||||
{1, 1, 0, 0, 0, 0, 4, 3, (int)(((1 << 20) + 3) / (2 * 3))}, // 32k->24k (frac: 4/3)
|
||||
{1, 1, 1, 0, 0, 0, 0, 0, 0}, // 32k->32k (bypass)
|
||||
{1, 0, 0, 0, 0, 0, 640, 441, (int)(((1 << 20) + 441) / (2 * 441))}, // 32k->64k->44.1k (up_2 + frac: 640/441)
|
||||
{1, 0, 0, 0, 0, 0, 4, 3, (int)(((1 << 20) + 3) / (2 * 3))} // 32k->64k->48k (up_2 + frac: 4/3)
|
||||
},
|
||||
{
|
||||
{0, 0, 0, 1, 1, 1, 441, 320, (int)(((1 << 20) + 320) / (2 * 320))}, // 44.1k->32k->8k (frac: 441/320 + down_4)
|
||||
{1, 0, 0, 0, 1, 1, 441, 320, (int)(((1 << 20) + 320) / (2 * 320))}, // 44.1k->32k->16k (frac: 441/320 + down_2)
|
||||
{0, 0, 0, 1, 1, 1, 147, 320, (int)(((1 << 20) + 320) / (2 * 320))}, // 44.1k->96k->24k (frac: 147/320 + down_4)
|
||||
{1, 0, 0, 0, 1, 1, 441, 640, (int)(((1 << 20) + 640) / (2 * 640))}, // 44.1k->64k->32k (frac: 441/640 + down_2)
|
||||
{1, 1, 1, 0, 0, 0, 0, 0, 0}, // 44.1k->44.1k (bypass)
|
||||
{1, 0, 0, 0, 0, 0, 147, 80, (int)(((1 << 20) + 80) / (2 * 80))} // 44.1k->88.2k->48k (up_2 + frac: 147/80)
|
||||
},
|
||||
{
|
||||
{0, 0, 0, 1, 1, 1, 3, 2, (int)(((1 << 20) + 2) / (2 * 2))}, // 48k->32k->8k (frac: 3/2 + down_4)
|
||||
{1, 0, 0, 0, 1, 1, 3, 2, (int)(((1 << 20) + 2) / (2 * 2))}, // 48k->32k->16k (frac: 3/2 + down_2)
|
||||
{1, 0, 1, 0, 1, 0, 0, 0, 0}, // 48k->24k (down_2)
|
||||
{1, 0, 0, 0, 1, 1, 3, 4, (int)(((1 << 20) + 4) / (2 * 4))}, // 48k->64k->32k (frac: 3/4 + down_2)
|
||||
{1, 0, 0, 0, 1, 1, 80, 147, (int)(((1 << 20) + 147) / (2 * 147))}, // 48k->88.2k->44.1k (frac: 80/147 + down_2)
|
||||
{1, 1, 1, 0, 0, 0, 0, 0, 0} // 48k->48k (bypass)
|
||||
},
|
||||
};
|
||||
@@ -0,0 +1,355 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2026 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <stdbool.h>
|
||||
#include "soc/asrc_struct.h"
|
||||
#include "soc/hp_sys_clkrst_struct.h"
|
||||
#include "hal/assert.h"
|
||||
#include "hal/asrc_periph.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif /* __cplusplus */
|
||||
|
||||
#define ASRC_LL_GET_HW() (&ASRC)
|
||||
#define ASRC_LL_STREAM_NUM (2)
|
||||
|
||||
/**
|
||||
* @brief ASRC interrupt types
|
||||
*/
|
||||
typedef enum {
|
||||
ASRC_LL_INTR_OUTCNT_EOF = (1 << 0), /**< Output counter EOF interrupt */
|
||||
} asrc_ll_intr_type_t;
|
||||
|
||||
/**
|
||||
* @brief Convert sample rate to table index
|
||||
*
|
||||
* @param[in] rate Sample rate in Hz (8000/16000/24000/32000/44100/48000)
|
||||
*
|
||||
* @return
|
||||
* - Table index
|
||||
* - -1 if rate not supported
|
||||
*/
|
||||
static inline int8_t asrc_ll_get_rate_index(uint32_t rate)
|
||||
{
|
||||
int32_t idx = rate / 8000;
|
||||
if (idx == 5) {
|
||||
return (rate == 44100) ? 4 : -1;
|
||||
}
|
||||
if (idx && rate == idx * 8000 && idx <= 6) {
|
||||
return idx - 1;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Reset ASRC module
|
||||
*
|
||||
* @param[in] hw Peripheral ASRC hardware instance address
|
||||
*/
|
||||
static inline void asrc_ll_reset_asrc_module(asrc_dev_t *hw)
|
||||
{
|
||||
HP_SYS_CLKRST.ahb_asrc_ctrl0.reg_ahb_asrc_rst_en = 1;
|
||||
HP_SYS_CLKRST.ahb_asrc_ctrl0.reg_ahb_asrc_rst_en = 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Enable the bus clock for the ASRC module
|
||||
*
|
||||
* @param[in] enable Enable the bus clock
|
||||
*/
|
||||
static inline void asrc_ll_enable_asrc_module(bool enable)
|
||||
{
|
||||
HP_SYS_CLKRST.ahb_asrc_ctrl0.reg_ahb_asrc_sys_clk_en = enable;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Force enable the register clock for the ASRC module
|
||||
*
|
||||
* @param[in] hw Peripheral ASRC hardware instance address
|
||||
* @param[in] enable Enable the register clock
|
||||
*/
|
||||
static inline void asrc_ll_force_enable_reg_clock(asrc_dev_t *hw, bool enable)
|
||||
{
|
||||
hw->sys.clk_en = enable;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Reset specific ASRC stream
|
||||
*
|
||||
* @param[in] hw Peripheral ASRC hardware instance address
|
||||
* @param[in] asrc_idx ASRC stream index
|
||||
*/
|
||||
static inline void asrc_ll_reset_stream(asrc_dev_t *hw, uint8_t asrc_idx)
|
||||
{
|
||||
hw->asrc_para[asrc_idx].cfg3.reset = 1;
|
||||
hw->asrc_para[asrc_idx].cfg3.reset = 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Start ASRC processing
|
||||
*
|
||||
* @param[in] hw Peripheral ASRC hardware instance address
|
||||
* @param[in] asrc_idx ASRC stream index
|
||||
*/
|
||||
static inline void asrc_ll_start_stream(asrc_dev_t *hw, uint8_t asrc_idx)
|
||||
{
|
||||
hw->asrc_para[asrc_idx].cfg4.start = 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Stop ASRC processing
|
||||
*
|
||||
* @param[in] hw Peripheral ASRC hardware instance address
|
||||
* @param[in] asrc_idx ASRC stream index
|
||||
*/
|
||||
static inline void asrc_ll_stop_stream(asrc_dev_t *hw, uint8_t asrc_idx)
|
||||
{
|
||||
hw->asrc_para[asrc_idx].cfg4.start = 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set ASRC rate register
|
||||
*
|
||||
* @param[in] hw Peripheral ASRC hardware instance address
|
||||
* @param[in] asrc_idx ASRC stream index
|
||||
* @param[in] src_rate Source sample rate
|
||||
* @param[in] dest_rate Destination sample rate
|
||||
*/
|
||||
static inline void asrc_ll_set_rate_reg(asrc_dev_t *hw, uint8_t asrc_idx, uint32_t src_rate, uint32_t dest_rate)
|
||||
{
|
||||
int8_t src_idx = asrc_ll_get_rate_index(src_rate);
|
||||
int8_t dest_idx = asrc_ll_get_rate_index(dest_rate);
|
||||
HAL_ASSERT(src_idx != -1 && dest_idx != -1);
|
||||
const asrc_periph_rate_config_t *config = &asrc_periph_rate_table[src_idx][dest_idx];
|
||||
hw->asrc_para[asrc_idx].cfg0.rs2_stg0_bypass = config->stg0_bypass;
|
||||
hw->asrc_para[asrc_idx].cfg0.rs2_stg1_bypass = config->stg1_bypass;
|
||||
hw->asrc_para[asrc_idx].cfg0.rs2_stg0_mode = config->stg0_mode;
|
||||
hw->asrc_para[asrc_idx].cfg0.rs2_stg1_mode = config->stg1_mode;
|
||||
hw->asrc_para[asrc_idx].cfg0.frac_bypass = config->frac_bypass;
|
||||
hw->asrc_para[asrc_idx].cfg0.frac_ahead = config->frac_ahead;
|
||||
hw->asrc_para[asrc_idx].cfg1.frac_m = config->frac_m;
|
||||
hw->asrc_para[asrc_idx].cfg1.frac_l = config->frac_l;
|
||||
hw->asrc_para[asrc_idx].cfg2.frac_recipl = config->frac_recipl;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set ASRC channel mode configuration
|
||||
*
|
||||
* @param[in] hw Peripheral ASRC hardware instance address
|
||||
* @param[in] asrc_idx ASRC stream index
|
||||
* @param[in] src_ch Source channel number
|
||||
* @param[in] dest_ch Destination channel number
|
||||
* @param[in] weight Weight array
|
||||
* @param[in] weight_len Weight array length
|
||||
*/
|
||||
static inline void asrc_ll_set_channel_mode(asrc_dev_t *hw, uint8_t asrc_idx, uint8_t src_ch,
|
||||
uint8_t dest_ch, float *weight, uint8_t weight_len)
|
||||
{
|
||||
if (src_ch == 1 && dest_ch == 1) {
|
||||
// Mode 0: Mono to Mono (1 channel -> 1 channel)
|
||||
hw->asrc_para[asrc_idx].cfg0.mode = 0;
|
||||
} else if (src_ch == 1 && dest_ch == 2) {
|
||||
// Mode 2: Mono to Dual (1 channel -> 2 channels, duplicate mono channel to both outputs)
|
||||
hw->asrc_para[asrc_idx].cfg0.mode = 2;
|
||||
} else if (src_ch == 2 && dest_ch == 1) {
|
||||
// Mode 3: Dual to Mono (2 channels -> 1 channel)
|
||||
// ch_sel determines channel selection: 0 = select channel 0 only, 1 = mix both channels
|
||||
HAL_ASSERT(weight_len == 2);
|
||||
uint32_t ch_sel = (weight[0] == 1.0f && weight[1] == 0.0f) ? 0 : 1;
|
||||
hw->asrc_para[asrc_idx].cfg0.mode = 3;
|
||||
hw->asrc_para[asrc_idx].cfg0.sel = ch_sel;
|
||||
} else {
|
||||
// Mode 1: Dual to Dual (2 channels -> 2 channels)
|
||||
hw->asrc_para[asrc_idx].cfg0.mode = 1;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Clear input samples counter register
|
||||
*
|
||||
* @param[in] hw Peripheral ASRC hardware instance address
|
||||
* @param[in] asrc_idx ASRC stream index
|
||||
*/
|
||||
static inline void asrc_ll_clear_incnt_counter(asrc_dev_t *hw, uint8_t asrc_idx)
|
||||
{
|
||||
hw->asrc_para[asrc_idx].cfg5.in_cnt_clr = 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Enable input samples counter register
|
||||
*
|
||||
* @param[in] hw Peripheral ASRC hardware instance address
|
||||
* @param[in] asrc_idx ASRC stream index
|
||||
*/
|
||||
static inline void asrc_ll_enable_incnt_counter(asrc_dev_t *hw, uint8_t asrc_idx)
|
||||
{
|
||||
hw->asrc_para[asrc_idx].cfg5.in_cnt_ena = 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set expected input samples count register
|
||||
*
|
||||
* @param[in] hw Peripheral ASRC hardware instance address
|
||||
* @param[in] asrc_idx ASRC stream index
|
||||
* @param[in] in_bytes_num Number of input samples expected
|
||||
*/
|
||||
static inline void asrc_ll_set_in_bytes_num(asrc_dev_t *hw, uint8_t asrc_idx, uint32_t in_bytes_num)
|
||||
{
|
||||
hw->asrc_para[asrc_idx].cfg5.in_samples = in_bytes_num;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Clear output samples counter register
|
||||
*
|
||||
* @param[in] hw Peripheral ASRC hardware instance address
|
||||
* @param[in] asrc_idx ASRC stream index
|
||||
*/
|
||||
static inline void asrc_ll_clear_outcnt_counter(asrc_dev_t *hw, uint8_t asrc_idx)
|
||||
{
|
||||
hw->asrc_para[asrc_idx].cfg6.out_cnt_clr = 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Enable output samples counter register
|
||||
*
|
||||
* @param[in] hw Peripheral ASRC hardware instance address
|
||||
* @param[in] asrc_idx ASRC stream index
|
||||
*/
|
||||
static inline void asrc_ll_enable_outcnt_counter(asrc_dev_t *hw, uint8_t asrc_idx)
|
||||
{
|
||||
hw->asrc_para[asrc_idx].cfg6.out_cnt_ena = 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Enable output samples counter compensation register
|
||||
*
|
||||
* @param[in] hw Peripheral ASRC hardware instance address
|
||||
* @param[in] asrc_idx ASRC stream index
|
||||
*/
|
||||
static inline void asrc_ll_enable_outsample_comp(asrc_dev_t *hw, uint8_t asrc_idx)
|
||||
{
|
||||
hw->asrc_para[asrc_idx].cfg6.out_samples_comp = 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set expected output sample count register
|
||||
*
|
||||
* @param[in] hw Peripheral ASRC hardware instance address
|
||||
* @param[in] asrc_idx ASRC stream index
|
||||
* @param[in] out_bytes_num Number of output samples expected
|
||||
*/
|
||||
static inline void asrc_ll_set_out_bytes_num(asrc_dev_t *hw, uint8_t asrc_idx, uint32_t out_bytes_num)
|
||||
{
|
||||
hw->asrc_para[asrc_idx].cfg6.out_samples = out_bytes_num;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set EOF (End of Frame) generation mode
|
||||
*
|
||||
* @param[in] hw Peripheral ASRC hardware instance address
|
||||
* @param[in] asrc_idx ASRC stream index
|
||||
* @param[in] eof_mode EOF generation mode
|
||||
*/
|
||||
static inline void asrc_ll_set_eof_mode(asrc_dev_t *hw, uint8_t asrc_idx, uint32_t eof_mode)
|
||||
{
|
||||
hw->asrc_para[asrc_idx].cfg6.out_eof_gen_mode = eof_mode;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Reset input fifo
|
||||
*
|
||||
* @param[in] hw Peripheral ASRC hardware instance address
|
||||
* @param[in] asrc_idx ASRC stream index
|
||||
*/
|
||||
static inline void asrc_ll_reset_input_fifo(asrc_dev_t *hw, uint8_t asrc_idx)
|
||||
{
|
||||
hw->asrc_para[asrc_idx].fifo_ctrl.infifo_reset = 1;
|
||||
hw->asrc_para[asrc_idx].fifo_ctrl.infifo_reset = 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Reset output fifo
|
||||
*
|
||||
* @param[in] hw Peripheral ASRC hardware instance address
|
||||
* @param[in] asrc_idx ASRC stream index
|
||||
*/
|
||||
static inline void asrc_ll_reset_output_fifo(asrc_dev_t *hw, uint8_t asrc_idx)
|
||||
{
|
||||
hw->asrc_para[asrc_idx].fifo_ctrl.outfifo_reset = 1;
|
||||
hw->asrc_para[asrc_idx].fifo_ctrl.outfifo_reset = 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Enable ASRC interrupt
|
||||
*
|
||||
* @param[in] hw Pointer to ASRC hardware.
|
||||
* @param[in] asrc_idx ASRC stream index
|
||||
* @param[in] mask Interrupt mask to enable
|
||||
*/
|
||||
static inline void asrc_ll_enable_intr_mask(asrc_dev_t *hw, uint8_t asrc_idx, uint32_t mask)
|
||||
{
|
||||
hw->asrc_para[asrc_idx].int_ena.val |= mask;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Clear ASRC interrupt
|
||||
*
|
||||
* @param[in] hw Pointer to ASRC hardware.
|
||||
* @param[in] asrc_idx ASRC stream index
|
||||
* @param[in] mask Interrupt mask to clear
|
||||
*/
|
||||
static inline void asrc_ll_clear_intr_mask(asrc_dev_t *hw, uint8_t asrc_idx, uint32_t mask)
|
||||
{
|
||||
hw->asrc_para[asrc_idx].int_clr.val = mask;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Disable ASRC interrupt
|
||||
*
|
||||
* @param[in] hw Pointer to ASRC hardware.
|
||||
* @param[in] asrc_idx ASRC stream index
|
||||
* @param[in] mask Interrupt mask to disable
|
||||
*/
|
||||
static inline void asrc_ll_disable_intr_mask(asrc_dev_t *hw, uint8_t asrc_idx, uint32_t mask)
|
||||
{
|
||||
hw->asrc_para[asrc_idx].int_ena.val &= (~mask);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get ASRC interrupt status
|
||||
*
|
||||
* @param[in] hw Pointer to ASRC hardware.
|
||||
* @param[in] asrc_idx ASRC stream index
|
||||
*
|
||||
* @return
|
||||
* - Interrupt status (masked)
|
||||
*/
|
||||
static inline uint32_t asrc_ll_get_intr_status(asrc_dev_t *hw, uint8_t asrc_idx)
|
||||
{
|
||||
return hw->asrc_para[asrc_idx].int_st.val;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get current output sample count
|
||||
*
|
||||
* @param[in] hw Peripheral ASRC hardware instance address
|
||||
* @param[in] asrc_idx ASRC stream index
|
||||
*
|
||||
* @return
|
||||
* - Current output samples count
|
||||
*/
|
||||
static inline uint32_t asrc_ll_get_outbytes_cnt(asrc_dev_t *hw, uint8_t asrc_idx)
|
||||
{
|
||||
uint32_t out_cnt = hw->asrc_para[asrc_idx].out_cnt.out_cnt;
|
||||
return out_cnt;
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif /* __cplusplus */
|
||||
@@ -0,0 +1,52 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2026 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif /* __cplusplus */
|
||||
|
||||
/**
|
||||
* @brief ASRC rate conversion register configuration structure
|
||||
*/
|
||||
typedef struct {
|
||||
uint32_t stg1_bypass; /*!< Stage 1 bypass control
|
||||
- 0: Enable stage 1 processing
|
||||
- 1: Bypass stage 1 (pass-through) */
|
||||
uint32_t stg0_bypass; /*!< Stage 0 bypass control
|
||||
- 0: Enable stage 0 processing
|
||||
- 1: Bypass stage 0 (pass-through) */
|
||||
uint32_t frac_bypass; /*!< Fractional resampler bypass control
|
||||
- 0: Enable fractional resampler
|
||||
- 1: Bypass fractional resampler */
|
||||
uint32_t stg1_mode; /*!< Stage 1 operation mode
|
||||
- 1: Down-sampling by 2 (decimation)
|
||||
- 0: Up-sampling by 2 (interpolation) */
|
||||
uint32_t stg0_mode; /*!< Stage 0 operation mode
|
||||
- 1: Down-sampling by 2 (decimation)
|
||||
- 0: Up-sampling by 2 (interpolation) */
|
||||
uint32_t frac_ahead; /*!< Fractional resampler advance flag
|
||||
- 0: Normal operation
|
||||
- 1: Advance mode (implementation specific) */
|
||||
uint32_t frac_m; /*!< Fractional resampler numerator
|
||||
Used in ratio calculation: frac_m/frac_l
|
||||
Range: Depends on sample rate conversion ratio */
|
||||
uint32_t frac_l; /*!< Fractional resampler denominator
|
||||
Used in ratio calculation: frac_m/frac_l
|
||||
Range: Depends on sample rate conversion ratio */
|
||||
uint32_t frac_recipl; /*!< Fractional resampler reciprocal value
|
||||
Pre-calculated reciprocal for hardware efficiency
|
||||
Formula: ((1 << 20) + frac_l) / (2 * frac_l) */
|
||||
} asrc_periph_rate_config_t;
|
||||
|
||||
extern const asrc_periph_rate_config_t asrc_periph_rate_table[6][6];
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif /* __cplusplus */
|
||||
Reference in New Issue
Block a user