feature(I2S-ADC): add ADC mode for I2S.

1. Support built-in ADC for I2S.
2. Modify code of ADC, made no change to the original APIs.
3. Add APIs in I2S:
esp_err_t i2s_set_adc_mode(adc_unit_t adc_unit, adc1_channel_t adc_channel);
4. Add I2S ADC/DAC example code.
5. add old-fashion definition to make it more compatible
6. replase spi_flash_ APIs with esp_partition_ APIs
7. add example of generating audio table from wav
8. change example sound
This commit is contained in:
Wangjialin 2017-08-23 23:12:56 +08:00
parent b2adaf2a4c
commit 2fceec4d85
24 changed files with 6242 additions and 162 deletions

View file

@ -278,7 +278,7 @@ esp_err_t i2s_set_clk(i2s_port_t i2s_num, uint32_t rate, i2s_bits_per_sample_t b
}
double mclk;
if (p_i2s_obj[i2s_num]->mode & I2S_MODE_DAC_BUILT_IN) {
if (p_i2s_obj[i2s_num]->mode & (I2S_MODE_DAC_BUILT_IN | I2S_MODE_ADC_BUILT_IN)) {
//DAC uses bclk as sample clock, not WS. WS can be something arbitrary.
//Rate as given to this function is the intended sample rate;
//According to the TRM, WS clk equals to the sample rate, and bclk is double the speed of WS
@ -554,6 +554,13 @@ esp_err_t i2s_set_dac_mode(i2s_dac_mode_t dac_mode)
return ESP_OK;
}
esp_err_t i2s_set_adc_mode(adc_unit_t adc_unit, adc1_channel_t adc_channel)
{
I2S_CHECK((adc_unit < ADC_UNIT_2), "i2s ADC unit error, only support ADC1 for now", ESP_ERR_INVALID_ARG);
// For now, we only support SAR ADC1.
return adc_i2s_mode_init(adc_unit, adc_channel);
}
esp_err_t i2s_set_pin(i2s_port_t i2s_num, const i2s_pin_config_t *pin)
{
I2S_CHECK((i2s_num < I2S_NUM_MAX), "i2s_num error", ESP_ERR_INVALID_ARG);
@ -669,10 +676,14 @@ esp_err_t i2s_set_sample_rates(i2s_port_t i2s_num, uint32_t rate)
I2S_CHECK((p_i2s_obj[i2s_num]->bytes_per_sample > 0), "bits_per_sample not set", ESP_ERR_INVALID_ARG);
return i2s_set_clk(i2s_num, rate, p_i2s_obj[i2s_num]->bits_per_sample, p_i2s_obj[i2s_num]->channel_num);
}
static esp_err_t i2s_param_config(i2s_port_t i2s_num, const i2s_config_t *i2s_config)
{
I2S_CHECK((i2s_num < I2S_NUM_MAX), "i2s_num error", ESP_ERR_INVALID_ARG);
I2S_CHECK((i2s_config), "param null", ESP_ERR_INVALID_ARG);
I2S_CHECK(!((i2s_config->mode & I2S_MODE_ADC_BUILT_IN) && (i2s_num != I2S_NUM_0)), "I2S ADC built-in only support on I2S0", ESP_ERR_INVALID_ARG);
I2S_CHECK(!((i2s_config->mode & I2S_MODE_DAC_BUILT_IN) && (i2s_num != I2S_NUM_0)), "I2S DAC built-in only support on I2S0", ESP_ERR_INVALID_ARG);
I2S_CHECK(!((i2s_config->mode & I2S_MODE_PDM) && (i2s_num != I2S_NUM_0)), "I2S DAC PDM only support on I2S0", ESP_ERR_INVALID_ARG);
if (i2s_num == I2S_NUM_1) {
periph_module_enable(PERIPH_I2S1_MODULE);
@ -680,23 +691,27 @@ static esp_err_t i2s_param_config(i2s_port_t i2s_num, const i2s_config_t *i2s_co
periph_module_enable(PERIPH_I2S0_MODULE);
}
if(i2s_config->mode & I2S_MODE_ADC_BUILT_IN) {
//in ADC built-in mode, we need to call i2s_set_adc_mode to
//initialize the specific ADC channel.
//in the current stage, we only support ADC1 and single channel mode.
//In default data mode, the ADC data is in 12-bit resolution mode.
adc_power_on();
}
// configure I2S data port interface.
i2s_reset_fifo(i2s_num);
//reset i2s
I2S[i2s_num]->conf.tx_reset = 1;
I2S[i2s_num]->conf.tx_reset = 0;
I2S[i2s_num]->conf.rx_reset = 1;
I2S[i2s_num]->conf.rx_reset = 0;
//reset dma
I2S[i2s_num]->lc_conf.in_rst = 1;
I2S[i2s_num]->lc_conf.in_rst = 0;
I2S[i2s_num]->lc_conf.out_rst = 1;
I2S[i2s_num]->lc_conf.out_rst = 0;
//Enable and configure DMA
I2S[i2s_num]->lc_conf.check_owner = 0;
I2S[i2s_num]->lc_conf.out_loop_test = 0;
@ -707,7 +722,6 @@ static esp_err_t i2s_param_config(i2s_port_t i2s_num, const i2s_config_t *i2s_co
I2S[i2s_num]->lc_conf.indscr_burst_en = 0;
I2S[i2s_num]->lc_conf.out_eof_mode = 1;
I2S[i2s_num]->conf2.lcd_en = 0;
I2S[i2s_num]->conf2.camera_en = 0;
I2S[i2s_num]->pdm_conf.pcm2pdm_conv_en = 0;
@ -751,9 +765,10 @@ static esp_err_t i2s_param_config(i2s_port_t i2s_num, const i2s_config_t *i2s_co
}
}
if (i2s_config->mode & I2S_MODE_DAC_BUILT_IN) {
if (i2s_config->mode & (I2S_MODE_DAC_BUILT_IN | I2S_MODE_ADC_BUILT_IN)) {
I2S[i2s_num]->conf2.lcd_en = 1;
I2S[i2s_num]->conf.tx_right_first = 1;
I2S[i2s_num]->conf2.camera_en = 0;
}
if (i2s_config->mode & I2S_MODE_PDM) {
@ -873,7 +888,12 @@ esp_err_t i2s_driver_install(i2s_port_t i2s_num, const i2s_config_t *i2s_config,
return err;
}
i2s_stop(i2s_num);
i2s_param_config(i2s_num, i2s_config);
err = i2s_param_config(i2s_num, i2s_config);
if (err != ESP_OK) {
i2s_driver_uninstall(i2s_num);
ESP_LOGE(I2S_TAG, "I2S param configure error");
return err;
}
if (i2s_queue) {
p_i2s_obj[i2s_num]->i2s_queue = xQueueCreate(queue_size, sizeof(i2s_event_t));

View file

@ -20,24 +20,38 @@ extern "C" {
#endif
#include <stdint.h>
#include <stdbool.h>
#include "esp_err.h"
#include "driver/gpio.h"
#include "soc/adc_channel.h"
typedef enum {
ADC_ATTEN_0db = 0, /*!<The input voltage of ADC will be reduced to about 1/1 */
ADC_ATTEN_2_5db = 1, /*!<The input voltage of ADC will be reduced to about 1/1.34 */
ADC_ATTEN_6db = 2, /*!<The input voltage of ADC will be reduced to about 1/2 */
ADC_ATTEN_11db = 3, /*!<The input voltage of ADC will be reduced to about 1/3.6*/
ADC_ATTEN_DB_0 = 0, /*!<The input voltage of ADC will be reduced to about 1/1 */
ADC_ATTEN_DB_2_5 = 1, /*!<The input voltage of ADC will be reduced to about 1/1.34 */
ADC_ATTEN_DB_6 = 2, /*!<The input voltage of ADC will be reduced to about 1/2 */
ADC_ATTEN_DB_11 = 3, /*!<The input voltage of ADC will be reduced to about 1/3.6*/
ADC_ATTEN_MAX,
} adc_atten_t;
typedef enum {
ADC_WIDTH_9Bit = 0, /*!< ADC capture width is 9Bit*/
ADC_WIDTH_10Bit = 1, /*!< ADC capture width is 10Bit*/
ADC_WIDTH_11Bit = 2, /*!< ADC capture width is 11Bit*/
ADC_WIDTH_12Bit = 3, /*!< ADC capture width is 12Bit*/
ADC_WIDTH_BIT_9 = 0, /*!< ADC capture width is 9Bit*/
ADC_WIDTH_BIT_10 = 1, /*!< ADC capture width is 10Bit*/
ADC_WIDTH_BIT_11 = 2, /*!< ADC capture width is 11Bit*/
ADC_WIDTH_BIT_12 = 3, /*!< ADC capture width is 12Bit*/
ADC_WIDTH_MAX,
} adc_bits_width_t;
//this definitions are only for being back-compatible
#define ADC_ATTEN_0db ADC_ATTEN_DB_0
#define ADC_ATTEN_2_5db ADC_ATTEN_DB_2_5
#define ADC_ATTEN_6db ADC_ATTEN_DB_6
#define ADC_ATTEN_11db ADC_ATTEN_DB_11
//this definitions are only for being back-compatible
#define ADC_WIDTH_9Bit ADC_WIDTH_BIT_9
#define ADC_WIDTH_10Bit ADC_WIDTH_BIT_10
#define ADC_WIDTH_11Bit ADC_WIDTH_BIT_11
#define ADC_WIDTH_12Bit ADC_WIDTH_BIT_12
typedef enum {
ADC1_CHANNEL_0 = 0, /*!< ADC1 channel 0 is GPIO36 */
ADC1_CHANNEL_1, /*!< ADC1 channel 1 is GPIO37 */
@ -64,11 +78,43 @@ typedef enum {
ADC2_CHANNEL_MAX,
} adc2_channel_t;
typedef enum {
ADC_CHANNEL_0 = 0, /*!< ADC channel */
ADC_CHANNEL_1, /*!< ADC channel */
ADC_CHANNEL_2, /*!< ADC channel */
ADC_CHANNEL_3, /*!< ADC channel */
ADC_CHANNEL_4, /*!< ADC channel */
ADC_CHANNEL_5, /*!< ADC channel */
ADC_CHANNEL_6, /*!< ADC channel */
ADC_CHANNEL_7, /*!< ADC channel */
ADC_CHANNEL_8, /*!< ADC channel */
ADC_CHANNEL_9, /*!< ADC channel */
ADC_CHANNEL_MAX,
} adc_channel_t;
typedef enum {
ADC_UNIT_1 = 1, /*!< SAR ADC 1*/
ADC_UNIT_2 = 2, /*!< SAR ADC 2, not supported yet*/
ADC_UNIT_BOTH = 3, /*!< SAR ADC 1 and 2, not supported yet */
ADC_UNIT_ALTER = 7, /*!< SAR ADC 1 and 2 alternative mode, not supported yet */
ADC_UNIT_MAX,
} adc_unit_t;
typedef enum {
ADC_ENCODE_12BIT, /*!< ADC to I2S data format, [15:12]-channel [11:0]-12 bits ADC data */
ADC_ENCODE_11BIT, /*!< ADC to I2S data format, [15]-1 [14:11]-channel [10:0]-11 bits ADC data */
ADC_ENCODE_MAX,
} adc_i2s_encode_t;
typedef enum {
ADC_I2S_DATA_SRC_IO_SIG = 0, /*!< I2S data from GPIO matrix signal */
ADC_I2S_DATA_SRC_ADC = 1, /*!< I2S data from ADC */
ADC_I2S_DATA_SRC_MAX,
} adc_i2s_source_t;
/**
* @brief Configure ADC1 capture width.
*
* @brief Configure ADC1 capture width, meanwhile enable output invert for ADC1.
* The configuration is for all channels of ADC1
*
* @param width_bit Bit capture width for ADC1
*
* @return
@ -77,6 +123,16 @@ typedef enum {
*/
esp_err_t adc1_config_width(adc_bits_width_t width_bit);
/**
* @brief Configure ADC capture width.
* @param adc_unit ADC unit index
* @param width_bit Bit capture width for ADC unit.
* @return
* - ESP_OK success
* - ESP_ERR_INVALID_ARG Parameter error
*/
esp_err_t adc_set_data_width(adc_unit_t adc_unit, adc_bits_width_t width_bit);
/**
* @brief Configure the ADC1 channel, including setting attenuation.
*
@ -89,10 +145,10 @@ esp_err_t adc1_config_width(adc_bits_width_t width_bit);
*
* When VDD_A is 3.3V:
*
* - 0dB attenuaton (ADC_ATTEN_0db) gives full-scale voltage 1.1V
* - 2.5dB attenuation (ADC_ATTEN_2_5db) gives full-scale voltage 1.5V
* - 6dB attenuation (ADC_ATTEN_6db) gives full-scale voltage 2.2V
* - 11dB attenuation (ADC_ATTEN_11db) gives full-scale voltage 3.9V (see note below)
* - 0dB attenuaton (ADC_ATTEN_DB_0) gives full-scale voltage 1.1V
* - 2.5dB attenuation (ADC_ATTEN_DB_2_5) gives full-scale voltage 1.5V
* - 6dB attenuation (ADC_ATTEN_DB_6) gives full-scale voltage 2.2V
* - 11dB attenuation (ADC_ATTEN_DB_11) gives full-scale voltage 3.9V (see note below)
*
* @note The full-scale voltage is the voltage corresponding to a maximum reading (depending on ADC1 configured
* bit width, this value is: 4095 for 12-bits, 2047 for 11-bits, 1023 for 10-bits, 511 for 9 bits.)
@ -134,6 +190,62 @@ int adc1_get_raw(adc1_channel_t channel);
int adc1_get_voltage(adc1_channel_t channel) __attribute__((deprecated));
/** @endcond */
/**
* @brief Power on SAR ADC
*/
void adc_power_on();
/**
* @brief Power off SAR ADC
*/
void adc_power_off();
/**
* @brief Initialize ADC pad
* @param adc_unit ADC unit index
* @param channel ADC channel index
* @return
* - ESP_OK success
* - ESP_ERR_INVALID_ARG Parameter error
*/
esp_err_t adc_gpio_init(adc_unit_t adc_unit, adc_channel_t channel);
/**
* @brief Set ADC data invert
* @param adc_unit ADC unit index
* @param inv_en whether enable data invert
* @return
* - ESP_OK success
* - ESP_ERR_INVALID_ARG Parameter error
*/
esp_err_t adc_set_data_inv(adc_unit_t adc_unit, bool inv_en);
/**
* @brief Set ADC source clock
* @param clk_div ADC clock divider, ADC clock is divided from APB clock
* @return
* - ESP_OK success
*/
esp_err_t adc_set_clk_div(uint8_t clk_div);
/**
* @brief Set I2S data source
* @param src I2S DMA data source, I2S DMA can get data from digital signals or from ADC.
* @return
* - ESP_OK success
*/
esp_err_t adc_set_i2s_data_source(adc_i2s_source_t src);
/**
* @brief Initialize I2S ADC mode
* @param adc_unit ADC unit index
* @param channel ADC channel index
* @return
* - ESP_OK success
* - ESP_ERR_INVALID_ARG Parameter error
*/
esp_err_t adc_i2s_mode_init(adc_unit_t adc_unit, adc_channel_t channel);
/**
* @brief Configure ADC1 to be usable by the ULP
*

View file

@ -26,6 +26,7 @@
#include "esp_attr.h"
#include "esp_intr_alloc.h"
#include "driver/periph_ctrl.h"
#include "driver/adc.h"
#include "freertos/semphr.h"
#ifdef __cplusplus
@ -118,7 +119,7 @@ typedef enum {
I2S_MODE_TX = 4,
I2S_MODE_RX = 8,
I2S_MODE_DAC_BUILT_IN = 16, /*!< Output I2S data to built-in DAC, no matter the data format is 16bit or 32 bit, the DAC module will only take the 8bits from MSB*/
//I2S_MODE_ADC_BUILT_IN = 32, /*!< Currently not supported yet, will be added for the next version*/
I2S_MODE_ADC_BUILT_IN = 32, /*!< Input I2S data from built-in ADC, each data can be 12-bit width at most*/
I2S_MODE_PDM = 64,
} i2s_mode_t;
@ -402,6 +403,17 @@ esp_err_t i2s_zero_dma_buffer(i2s_port_t i2s_num);
*/
esp_err_t i2s_set_clk(i2s_port_t i2s_num, uint32_t rate, i2s_bits_per_sample_t bits, i2s_channel_t ch);
/**
* @brief Set built-in ADC mode for I2S DMA, this function will initialize ADC pad,
* and set ADC parameters.
* @param adc_unit SAR ADC unit index
* @param adc_channel ADC channel index
* @return
* - ESP_OK Success
* - ESP_FAIL Parameter error
*/
esp_err_t i2s_set_adc_mode(adc_unit_t adc_unit, adc1_channel_t adc_channel);
#ifdef __cplusplus
}
#endif

View file

@ -20,6 +20,8 @@
#include "soc/sens_struct.h"
#include "soc/rtc_cntl_reg.h"
#include "soc/rtc_cntl_struct.h"
#include "soc/syscon_reg.h"
#include "soc/syscon_struct.h"
#include "rtc_io.h"
#include "touch_pad.h"
#include "adc.h"
@ -40,6 +42,18 @@
#include "rom/queue.h"
#define ADC_FSM_RSTB_WAIT_DEFAULT (8)
#define ADC_FSM_START_WAIT_DEFAULT (5)
#define ADC_FSM_STANDBY_WAIT_DEFAULT (100)
#define ADC_FSM_TIME_KEEP (-1)
#define ADC_MAX_MEAS_NUM_DEFAULT (255)
#define ADC_MEAS_NUM_LIM_DEFAULT (1)
#define SAR_ADC_CLK_DIV_DEFUALT (2)
#define ADC_PATT_LEN_MAX (16)
#define TOUCH_PAD_FILTER_FACTOR_DEFAULT (16)
#define TOUCH_PAD_SHIFT_DEFAULT (4)
#define DAC_ERR_STR_CHANNEL_ERROR "DAC channel error"
static const char *RTC_MODULE_TAG = "RTC_MODULE";
#define RTC_MODULE_CHECK(a, str, ret_val) if (!(a)) { \
@ -52,17 +66,16 @@ static const char *RTC_MODULE_TAG = "RTC_MODULE";
return (ret_val); \
}
#define ADC_CHECK_UNIT(unit) RTC_MODULE_CHECK(adc_unit < ADC_UNIT_2, "ADC unit error, only support ADC1 for now", ESP_ERR_INVALID_ARG)
#define ADC1_CHECK_FUNCTION_RET(fun_ret) if(fun_ret!=ESP_OK){\
ESP_LOGE(RTC_MODULE_TAG,"%s:%d\n",__FUNCTION__,__LINE__);\
return ESP_FAIL;\
}
#define DAC_ERR_STR_CHANNEL_ERROR "DAC channel error"
portMUX_TYPE rtc_spinlock = portMUX_INITIALIZER_UNLOCKED;
static SemaphoreHandle_t rtc_touch_mux = NULL;
typedef struct {
TimerHandle_t timer;
uint32_t filtered_val[TOUCH_PAD_MAX];
@ -72,6 +85,12 @@ typedef struct {
} touch_pad_filter_t;
static touch_pad_filter_t *s_touch_pad_filter = NULL;
typedef enum {
ADC_FORCE_FSM = 0x0,
ADC_FORCE_DISABLE = 0x2,
ADC_FORCE_ENABLE = 0x3,
} adc_force_mode_t;
//Reg,Mux,Fun,IE,Up,Down,Rtc_number
const rtc_gpio_desc_t rtc_gpio_desc[GPIO_PIN_COUNT] = {
{RTC_IO_TOUCH_PAD1_REG, RTC_IO_TOUCH_PAD1_MUX_SEL_M, RTC_IO_TOUCH_PAD1_FUN_SEL_S, RTC_IO_TOUCH_PAD1_FUN_IE_M, RTC_IO_TOUCH_PAD1_RUE_M, RTC_IO_TOUCH_PAD1_RDE_M, RTC_IO_TOUCH_PAD1_SLP_SEL_M, RTC_IO_TOUCH_PAD1_SLP_IE_M, RTC_IO_TOUCH_PAD1_HOLD_M, RTC_CNTL_TOUCH_PAD1_HOLD_FORCE_M, RTC_IO_TOUCH_PAD1_DRV_V, RTC_IO_TOUCH_PAD1_DRV_S, RTCIO_GPIO0_CHANNEL}, //0
@ -412,8 +431,6 @@ static esp_err_t touch_pad_get_io_num(touch_pad_t touch_num, gpio_num_t *gpio_nu
return ESP_OK;
}
#define TOUCH_PAD_FILTER_FACTOR_DEFAULT (16)
#define TOUCH_PAD_SHIFT_DEFAULT (4)
static uint32_t _touch_filter_iir(uint32_t in_now, uint32_t out_last, uint32_t k)
{
if (k == 0) {
@ -909,69 +926,304 @@ static esp_err_t adc1_pad_get_io_num(adc1_channel_t channel, gpio_num_t *gpio_nu
return ESP_OK;
}
static esp_err_t adc1_pad_init(adc1_channel_t channel)
static esp_err_t adc_set_fsm_time(int rst_wait, int start_wait, int standby_wait, int sample_cycle)
{
gpio_num_t gpio_num = 0;
ADC1_CHECK_FUNCTION_RET(adc1_pad_get_io_num(channel, &gpio_num));
ADC1_CHECK_FUNCTION_RET(rtc_gpio_init(gpio_num));
ADC1_CHECK_FUNCTION_RET(rtc_gpio_output_disable(gpio_num));
ADC1_CHECK_FUNCTION_RET(rtc_gpio_input_disable(gpio_num));
ADC1_CHECK_FUNCTION_RET(gpio_set_pull_mode(gpio_num, GPIO_FLOATING));
portENTER_CRITICAL(&rtc_spinlock);
// Internal FSM reset wait time
if (rst_wait >= 0) {
SYSCON.saradc_fsm.rstb_wait = rst_wait;
}
// Internal FSM start wait time
if (start_wait >= 0) {
SYSCON.saradc_fsm.start_wait = start_wait;
}
// Internal FSM standby wait time
if (standby_wait >= 0) {
SYSCON.saradc_fsm.standby_wait = standby_wait;
}
// Internal FSM standby sample cycle
if (sample_cycle >= 0) {
SYSCON.saradc_fsm.sample_cycle = sample_cycle;
}
portEXIT_CRITICAL(&rtc_spinlock);
return ESP_OK;
}
static esp_err_t adc_set_data_format(adc_i2s_encode_t mode)
{
portENTER_CRITICAL(&rtc_spinlock);
//data format:
//0: ADC_ENCODE_12BIT [15:12]-channel [11:0]-12 bits ADC data
//1: ADC_ENCODE_11BIT [15]-1 [14:11]-channel [10:0]-11 bits ADC data, the resolution should not be larger than 11 bits in this case.
SYSCON.saradc_ctrl.data_sar_sel = mode;
portEXIT_CRITICAL(&rtc_spinlock);
return ESP_OK;
}
static esp_err_t adc_set_measure_limit(uint8_t meas_num, bool lim_en)
{
portENTER_CRITICAL(&rtc_spinlock);
// Set max measure number
SYSCON.saradc_ctrl2.max_meas_num = meas_num;
// Enable max measure number limit
SYSCON.saradc_ctrl2.meas_num_limit = lim_en;
portEXIT_CRITICAL(&rtc_spinlock);
return ESP_OK;
}
static esp_err_t adc_set_work_mode(adc_unit_t adc_unit)
{
portENTER_CRITICAL(&rtc_spinlock);
if (adc_unit == ADC_UNIT_1) {
// saradc mode sel : 0--single saradc; 1--double saradc; 2--alternative saradc
SYSCON.saradc_ctrl.work_mode = 0;
//ENABLE ADC 0: ADC1 1: ADC2, only work for single SAR mode
SYSCON.saradc_ctrl.sar_sel = 0;
} else if (adc_unit == ADC_UNIT_2) {
// saradc mode sel : 0--single saradc; 1--double saradc; 2--alternative saradc
SYSCON.saradc_ctrl.work_mode = 0;
//ENABLE ADC1 0: SAR1 1: SAR2 only work for single SAR mode
SYSCON.saradc_ctrl.sar_sel = 1;
} else if (adc_unit == ADC_UNIT_BOTH) {
// saradc mode sel : 0--single saradc; 1--double saradc; 2--alternative saradc
SYSCON.saradc_ctrl.work_mode = 1;
} else if (adc_unit == ADC_UNIT_ALTER) {
// saradc mode sel : 0--single saradc; 1--double saradc; 2--alternative saradc
SYSCON.saradc_ctrl.work_mode = 2;
}
portEXIT_CRITICAL(&rtc_spinlock);
return ESP_OK;
}
static esp_err_t adc_set_atten(adc_unit_t adc_unit, adc_channel_t channel, adc_atten_t atten)
{
ADC_CHECK_UNIT(adc_unit);
if (adc_unit & ADC_UNIT_1) {
RTC_MODULE_CHECK((adc1_channel_t)channel < ADC1_CHANNEL_MAX, "ADC Channel Err", ESP_ERR_INVALID_ARG);
}
RTC_MODULE_CHECK(atten < ADC_ATTEN_MAX, "ADC Atten Err", ESP_ERR_INVALID_ARG);
portENTER_CRITICAL(&rtc_spinlock);
if (adc_unit & ADC_UNIT_1) {
//SAR1_atten
SET_PERI_REG_BITS(SENS_SAR_ATTEN1_REG, SENS_SAR1_ATTEN_VAL_MASK, atten, (channel * 2));
}
if (adc_unit & ADC_UNIT_2) {
//SAR2_atten
SET_PERI_REG_BITS(SENS_SAR_ATTEN2_REG, SENS_SAR2_ATTEN_VAL_MASK, atten, (channel * 2));
}
portEXIT_CRITICAL(&rtc_spinlock);
return ESP_OK;
}
void adc_power_on()
{
portENTER_CRITICAL(&rtc_spinlock);
//Bit1 0:Fsm 1: SW mode
//Bit0 0:SW mode power down 1: SW mode power on
SENS.sar_meas_wait2.force_xpd_sar = ADC_FORCE_ENABLE;
portEXIT_CRITICAL(&rtc_spinlock);
}
void adc_power_off()
{
portENTER_CRITICAL(&rtc_spinlock);
//Bit1 0:Fsm 1: SW mode
//Bit0 0:SW mode power down 1: SW mode power on
SENS.sar_meas_wait2.force_xpd_sar = ADC_FORCE_DISABLE;
portEXIT_CRITICAL(&rtc_spinlock);
}
esp_err_t adc_set_clk_div(uint8_t clk_div)
{
portENTER_CRITICAL(&rtc_spinlock);
// ADC clock devided from APB clk, 80 / 2 = 40Mhz,
SYSCON.saradc_ctrl.sar_clk_div = clk_div;
portEXIT_CRITICAL(&rtc_spinlock);
return ESP_OK;
}
esp_err_t adc_set_i2s_data_source(adc_i2s_source_t src)
{
RTC_MODULE_CHECK(src < ADC_I2S_DATA_SRC_MAX, "ADC i2s data source error", ESP_ERR_INVALID_ARG);
portENTER_CRITICAL(&rtc_spinlock);
// 1: I2S input data is from SAR ADC (for DMA) 0: I2S input data is from GPIO matrix
SYSCON.saradc_ctrl.data_to_i2s = src;
portEXIT_CRITICAL(&rtc_spinlock);
return ESP_OK;
}
esp_err_t adc_gpio_init(adc_unit_t adc_unit, adc_channel_t channel)
{
ADC_CHECK_UNIT(adc_unit);
gpio_num_t gpio_num = 0;
if (adc_unit & ADC_UNIT_1) {
RTC_MODULE_CHECK((adc1_channel_t) channel < ADC1_CHANNEL_MAX, "ADC1 channel error", ESP_ERR_INVALID_ARG);
ADC1_CHECK_FUNCTION_RET(adc1_pad_get_io_num((adc1_channel_t) channel, &gpio_num));
ADC1_CHECK_FUNCTION_RET(rtc_gpio_init(gpio_num));
ADC1_CHECK_FUNCTION_RET(rtc_gpio_output_disable(gpio_num));
ADC1_CHECK_FUNCTION_RET(rtc_gpio_input_disable(gpio_num));
ADC1_CHECK_FUNCTION_RET(gpio_set_pull_mode(gpio_num, GPIO_FLOATING));
}
return ESP_OK;
}
esp_err_t adc_set_data_inv(adc_unit_t adc_unit, bool inv_en)
{
portENTER_CRITICAL(&rtc_spinlock);
if (adc_unit & ADC_UNIT_1) {
// Enable ADC data invert
SENS.sar_read_ctrl.sar1_data_inv = inv_en;
}
if (adc_unit & ADC_UNIT_2) {
// Enable ADC data invert
SENS.sar_read_ctrl2.sar2_data_inv = inv_en;
}
portEXIT_CRITICAL(&rtc_spinlock);
return ESP_OK;
}
esp_err_t adc_set_data_width(adc_unit_t adc_unit, adc_bits_width_t bits)
{
ADC_CHECK_UNIT(adc_unit);
RTC_MODULE_CHECK(bits < ADC_WIDTH_MAX, "ADC bit width error", ESP_ERR_INVALID_ARG);
portENTER_CRITICAL(&rtc_spinlock);
if (adc_unit & ADC_UNIT_1) {
SENS.sar_start_force.sar1_bit_width = bits;
SENS.sar_read_ctrl.sar1_sample_bit = bits;
}
if (adc_unit & ADC_UNIT_2) {
SENS.sar_start_force.sar2_bit_width = bits;
SENS.sar_read_ctrl2.sar2_sample_bit = bits;
}
portEXIT_CRITICAL(&rtc_spinlock);
return ESP_OK;
}
static esp_err_t adc_set_i2s_data_len(adc_unit_t adc_unit, int patt_len)
{
ADC_CHECK_UNIT(adc_unit);
RTC_MODULE_CHECK((patt_len < ADC_PATT_LEN_MAX) && (patt_len > 0), "ADC pattern length error", ESP_ERR_INVALID_ARG);
portENTER_CRITICAL(&rtc_spinlock);
if(adc_unit & ADC_UNIT_1) {
SYSCON.saradc_ctrl.sar1_patt_len = patt_len - 1;
}
if(adc_unit & ADC_UNIT_2) {
SYSCON.saradc_ctrl.sar2_patt_len = patt_len - 1;
}
portEXIT_CRITICAL(&rtc_spinlock);
return ESP_OK;
}
static esp_err_t adc_set_i2s_data_pattern(adc_unit_t adc_unit, int seq_num, adc_channel_t channel, adc_bits_width_t bits, adc_atten_t atten)
{
ADC_CHECK_UNIT(adc_unit);
if (adc_unit & ADC_UNIT_1) {
RTC_MODULE_CHECK((adc1_channel_t) channel < ADC1_CHANNEL_MAX, "ADC1 channel error", ESP_ERR_INVALID_ARG);
}
RTC_MODULE_CHECK(bits < ADC_WIDTH_MAX, "ADC bit width error", ESP_ERR_INVALID_ARG);
RTC_MODULE_CHECK(atten < ADC_ATTEN_MAX, "ADC Atten Err", ESP_ERR_INVALID_ARG);
portENTER_CRITICAL(&rtc_spinlock);
//Configure pattern table, each 8 bit defines one channel
//[7:4]-channel [3:2]-bit width [1:0]- attenuation
//BIT WIDTH: 3: 12BIT 2: 11BIT 1: 10BIT 0: 9BIT
//ATTEN: 3: ATTEN = 11dB 2: 6dB 1: 2.5dB 0: 0dB
uint8_t val = (channel << 4) | (bits << 2) | (atten << 0);
if (adc_unit & ADC_UNIT_1) {
SYSCON.saradc_sar1_patt_tab[seq_num / 4] &= (~(0xff << ((3 - (seq_num % 4)) * 8)));
SYSCON.saradc_sar1_patt_tab[seq_num / 4] |= (val << ((3 - (seq_num % 4)) * 8));
}
if (adc_unit & ADC_UNIT_2) {
SYSCON.saradc_sar2_patt_tab[seq_num / 4] &= (~(0xff << ((3 - (seq_num % 4)) * 8)));
SYSCON.saradc_sar2_patt_tab[seq_num / 4] |= (val << ((3 - (seq_num % 4)) * 8));
}
portEXIT_CRITICAL(&rtc_spinlock);
return ESP_OK;
}
esp_err_t adc_i2s_mode_init(adc_unit_t adc_unit, adc_channel_t channel)
{
ADC_CHECK_UNIT(adc_unit);
if (adc_unit & ADC_UNIT_1) {
RTC_MODULE_CHECK((adc1_channel_t) channel < ADC1_CHANNEL_MAX, "ADC1 channel error", ESP_ERR_INVALID_ARG);
}
uint8_t table_len = 1;
//POWER ON SAR
adc_power_on();
adc_gpio_init(adc_unit, channel);
adc_set_i2s_data_len(adc_unit, table_len);
adc_set_i2s_data_pattern(adc_unit, 0, channel, ADC_WIDTH_BIT_12, ADC_ATTEN_DB_11);
portENTER_CRITICAL(&rtc_spinlock);
if (adc_unit & ADC_UNIT_1) {
//switch SARADC into DIG channel
SENS.sar_read_ctrl.sar1_dig_force = 1;
}
if (adc_unit & ADC_UNIT_2) {
//switch SARADC into DIG channel
SENS.sar_read_ctrl2.sar2_dig_force = 1;
//1: SAR ADC2 is controlled by DIG ADC2 CTRL 0: SAR ADC2 is controlled by PWDET CTRL
SYSCON.saradc_ctrl.sar2_mux = 1;
}
portEXIT_CRITICAL(&rtc_spinlock);
adc_set_i2s_data_source(ADC_I2S_DATA_SRC_ADC);
adc_set_clk_div(SAR_ADC_CLK_DIV_DEFUALT);
// Set internal FSM wait time.
adc_set_fsm_time(ADC_FSM_RSTB_WAIT_DEFAULT, ADC_FSM_START_WAIT_DEFAULT, ADC_FSM_STANDBY_WAIT_DEFAULT,
ADC_FSM_TIME_KEEP);
adc_set_work_mode(adc_unit);
adc_set_data_format(ADC_ENCODE_12BIT);
adc_set_measure_limit(ADC_MAX_MEAS_NUM_DEFAULT, ADC_MEAS_NUM_LIM_DEFAULT);
//Invert The Level, Invert SAR ADC1 data
adc_set_data_inv(adc_unit, true);
return ESP_OK;
}
esp_err_t adc1_config_channel_atten(adc1_channel_t channel, adc_atten_t atten)
{
RTC_MODULE_CHECK(channel < ADC1_CHANNEL_MAX, "ADC Channel Err", ESP_ERR_INVALID_ARG);
RTC_MODULE_CHECK(atten <= ADC_ATTEN_11db, "ADC Atten Err", ESP_ERR_INVALID_ARG);
adc1_pad_init(channel);
portENTER_CRITICAL(&rtc_spinlock);
SET_PERI_REG_BITS(SENS_SAR_ATTEN1_REG, 3, atten, (channel * 2)); //SAR1_atten
portEXIT_CRITICAL(&rtc_spinlock);
RTC_MODULE_CHECK(atten < ADC_ATTEN_MAX, "ADC Atten Err", ESP_ERR_INVALID_ARG);
adc_gpio_init(ADC_UNIT_1, channel);
adc_set_atten(ADC_UNIT_1, channel, atten);
return ESP_OK;
}
esp_err_t adc1_config_width(adc_bits_width_t width_bit)
{
portENTER_CRITICAL(&rtc_spinlock);
SET_PERI_REG_BITS(SENS_SAR_START_FORCE_REG, SENS_SAR1_BIT_WIDTH_V, width_bit, SENS_SAR1_BIT_WIDTH_S); //SAR2_BIT_WIDTH[1:0]=0x3, SAR1_BIT_WIDTH[1:0]=0x3
//Invert the adc value,the Output value is invert
SET_PERI_REG_MASK(SENS_SAR_READ_CTRL_REG, SENS_SAR1_DATA_INV);
//Set The adc sample width,invert adc value,must
SET_PERI_REG_BITS(SENS_SAR_READ_CTRL_REG, SENS_SAR1_SAMPLE_BIT_V, width_bit, SENS_SAR1_SAMPLE_BIT_S); //digital sar1_bit_width[1:0]=3
portEXIT_CRITICAL(&rtc_spinlock);
RTC_MODULE_CHECK(width_bit < ADC_WIDTH_MAX, "ADC bit width error", ESP_ERR_INVALID_ARG);
adc_set_data_width(ADC_UNIT_1, width_bit);
adc_set_data_inv(ADC_UNIT_1, true);
return ESP_OK;
}
int adc1_get_raw(adc1_channel_t channel)
{
uint16_t adc_value;
RTC_MODULE_CHECK(channel < ADC1_CHANNEL_MAX, "ADC Channel Err", ESP_ERR_INVALID_ARG);
portENTER_CRITICAL(&rtc_spinlock);
//Adc Controler is Rtc module,not ulp coprocessor
SET_PERI_REG_BITS(SENS_SAR_MEAS_START1_REG, 1, 1, SENS_MEAS1_START_FORCE_S); //force pad mux and force start
SENS.sar_meas_start1.meas1_start_force = 1;
//Bit1=0:Fsm Bit1=1(Bit0=0:PownDown Bit10=1:Powerup)
SET_PERI_REG_BITS(SENS_SAR_MEAS_WAIT2_REG, SENS_FORCE_XPD_SAR, 0, SENS_FORCE_XPD_SAR_S); //force XPD_SAR=0, use XPD_FSM
SENS.sar_meas_wait2.force_xpd_sar = 0;
//Disable Amp Bit1=0:Fsm Bit1=1(Bit0=0:PownDown Bit10=1:Powerup)
SET_PERI_REG_BITS(SENS_SAR_MEAS_WAIT2_REG, SENS_FORCE_XPD_AMP, 0x2, SENS_FORCE_XPD_AMP_S); //force XPD_AMP=0
SENS.sar_meas_wait2.force_xpd_amp = 0x2;
//Open the ADC1 Data port Not ulp coprocessor
SET_PERI_REG_BITS(SENS_SAR_MEAS_START1_REG, 1, 1, SENS_SAR1_EN_PAD_FORCE_S); //open the ADC1 data port
SENS.sar_meas_start1.sar1_en_pad_force = 1;
//Select channel
SET_PERI_REG_BITS(SENS_SAR_MEAS_START1_REG, SENS_SAR1_EN_PAD, (1 << channel), SENS_SAR1_EN_PAD_S); //pad enable
SET_PERI_REG_BITS(SENS_SAR_MEAS_CTRL_REG, 0xfff, 0x0, SENS_AMP_RST_FB_FSM_S); //[11:8]:short ref ground, [7:4]:short ref, [3:0]:rst fb
SET_PERI_REG_BITS(SENS_SAR_MEAS_WAIT1_REG, SENS_SAR_AMP_WAIT1, 0x1, SENS_SAR_AMP_WAIT1_S);
SET_PERI_REG_BITS(SENS_SAR_MEAS_WAIT1_REG, SENS_SAR_AMP_WAIT2, 0x1, SENS_SAR_AMP_WAIT2_S);
SET_PERI_REG_BITS(SENS_SAR_MEAS_WAIT2_REG, SENS_SAR_AMP_WAIT3, 0x1, SENS_SAR_AMP_WAIT3_S);
while (GET_PERI_REG_BITS2(SENS_SAR_SLAVE_ADDR1_REG, 0x7, SENS_MEAS_STATUS_S) != 0); //wait det_fsm==0
SET_PERI_REG_BITS(SENS_SAR_MEAS_START1_REG, 1, 0, SENS_MEAS1_START_SAR_S); //start force 0
SET_PERI_REG_BITS(SENS_SAR_MEAS_START1_REG, 1, 1, SENS_MEAS1_START_SAR_S); //start force 1
while (GET_PERI_REG_MASK(SENS_SAR_MEAS_START1_REG, SENS_MEAS1_DONE_SAR) == 0) {}; //read done
adc_value = GET_PERI_REG_BITS2(SENS_SAR_MEAS_START1_REG, SENS_MEAS1_DATA_SAR, SENS_MEAS1_DATA_SAR_S);
SENS.sar_meas_start1.sar1_en_pad = (1 << channel);
SENS.sar_meas_ctrl.amp_rst_fb_fsm = 0;
SENS.sar_meas_ctrl.amp_short_ref_fsm = 0;
SENS.sar_meas_ctrl.amp_short_ref_gnd_fsm = 0;
SENS.sar_meas_wait1.sar_amp_wait1 = 1;
SENS.sar_meas_wait1.sar_amp_wait2 = 1;
SENS.sar_meas_wait2.sar_amp_wait3 = 1;
while (SENS.sar_slave_addr1.meas_status != 0);
SENS.sar_meas_start1.meas1_start_sar = 0;
SENS.sar_meas_start1.meas1_start_sar = 1;
while (SENS.sar_meas_start1.meas1_done_sar == 0);
adc_value = SENS.sar_meas_start1.meas1_data_sar;
portEXIT_CRITICAL(&rtc_spinlock);
return adc_value;
}
@ -983,14 +1235,16 @@ int adc1_get_voltage(adc1_channel_t channel) //Deprecated. Use adc1_get_raw()
void adc1_ulp_enable(void)
{
portENTER_CRITICAL(&rtc_spinlock);
CLEAR_PERI_REG_MASK(SENS_SAR_MEAS_START1_REG, SENS_MEAS1_START_FORCE);
CLEAR_PERI_REG_MASK(SENS_SAR_MEAS_START1_REG, SENS_SAR1_EN_PAD_FORCE_M);
SET_PERI_REG_BITS(SENS_SAR_MEAS_WAIT2_REG, SENS_FORCE_XPD_AMP, 0x2, SENS_FORCE_XPD_AMP_S);
SET_PERI_REG_BITS(SENS_SAR_MEAS_WAIT2_REG, SENS_FORCE_XPD_SAR, 0, SENS_FORCE_XPD_SAR_S);
SET_PERI_REG_BITS(SENS_SAR_MEAS_CTRL_REG, 0xfff, 0x0, SENS_AMP_RST_FB_FSM_S); //[11:8]:short ref ground, [7:4]:short ref, [3:0]:rst fb
SET_PERI_REG_BITS(SENS_SAR_MEAS_WAIT1_REG, SENS_SAR_AMP_WAIT1, 0x1, SENS_SAR_AMP_WAIT1_S);
SET_PERI_REG_BITS(SENS_SAR_MEAS_WAIT1_REG, SENS_SAR_AMP_WAIT2, 0x1, SENS_SAR_AMP_WAIT2_S);
SET_PERI_REG_BITS(SENS_SAR_MEAS_WAIT2_REG, SENS_SAR_AMP_WAIT3, 0x1, SENS_SAR_AMP_WAIT3_S);
SENS.sar_meas_start1.meas1_start_force = 0;
SENS.sar_meas_start1.sar1_en_pad_force = 0;
SENS.sar_meas_wait2.force_xpd_amp = 0x2;
SENS.sar_meas_wait2.force_xpd_sar = 0;
SENS.sar_meas_ctrl.amp_rst_fb_fsm = 0;
SENS.sar_meas_ctrl.amp_short_ref_fsm = 0;
SENS.sar_meas_ctrl.amp_short_ref_gnd_fsm = 0;
SENS.sar_meas_wait1.sar_amp_wait1 = 0x1;
SENS.sar_meas_wait1.sar_amp_wait2 = 1;
SENS.sar_meas_wait2.sar_amp_wait3 = 0x1;
portEXIT_CRITICAL(&rtc_spinlock);
}
@ -1199,10 +1453,10 @@ static int hall_sensor_get_value() //hall sensor without LNA
int hall_sensor_read()
{
adc1_pad_init(ADC1_CHANNEL_0);
adc1_pad_init(ADC1_CHANNEL_3);
adc1_config_channel_atten(ADC1_CHANNEL_0, ADC_ATTEN_0db);
adc1_config_channel_atten(ADC1_CHANNEL_3, ADC_ATTEN_0db);
adc_gpio_init(ADC_UNIT_1, ADC1_CHANNEL_0);
adc_gpio_init(ADC_UNIT_1, ADC1_CHANNEL_3);
adc1_config_channel_atten(ADC1_CHANNEL_0, ADC_ATTEN_DB_0);
adc1_config_channel_atten(ADC1_CHANNEL_3, ADC_ATTEN_DB_0);
return hall_sensor_get_value();
}

View file

@ -20,8 +20,9 @@ PROVIDE ( TIMERG0 = 0x3ff5F000 );
PROVIDE ( TIMERG1 = 0x3ff60000 );
PROVIDE ( SPI2 = 0x3ff64000 );
PROVIDE ( SPI3 = 0x3ff65000 );
PROVIDE ( SYSCON = 0x3ff66000 );
PROVIDE ( I2C1 = 0x3ff67000 );
PROVIDE ( SDMMC = 0x3ff68000 );
PROVIDE ( MCPWM1 = 0x3ff6C000 );
PROVIDE ( I2S1 = 0x3ff6D000 );
PROVIDE ( UART2 = 0x3ff6E000 );
PROVIDE ( SDMMC = 0x3ff68000 );

View file

@ -78,7 +78,7 @@ uint32_t esp_adc_cal_raw_to_voltage(uint32_t adc,
const esp_adc_cal_characteristics_t *chars)
{
//Scale ADC to 12 bit width (0 to 4095)
adc <<= (ADC_WIDTH_12Bit - chars->bit_width);
adc <<= (ADC_WIDTH_BIT_12 - chars->bit_width);
uint32_t i = (adc >> chars->table->bit_shift); //find index for lut voltages
//Refernce LUT to obtain voltage using index
uint32_t voltage = esp_adc_cal_interpolate_round(chars->table->voltage[i],

View file

@ -71,7 +71,7 @@ typedef struct {
for uint32 arithmetic */
uint32_t offset; /**<Offset in mV used to correct LUT Voltages to current v_ref */
uint32_t ideal_offset; /**<Offset in mV at the ideal reference voltage */
adc_bits_width_t bit_width; /**<Bit width of ADC e.g. ADC_WIDTH_12Bit */
adc_bits_width_t bit_width; /**<Bit width of ADC e.g. ADC_WIDTH_BIT_12 */
const esp_adc_cal_lookup_table_t *table; /**<Pointer to LUT */
} esp_adc_cal_characteristics_t;

View file

@ -297,6 +297,8 @@
#define SENS_SAR1_ATTEN_M ((SENS_SAR1_ATTEN_V)<<(SENS_SAR1_ATTEN_S))
#define SENS_SAR1_ATTEN_V 0xFFFFFFFF
#define SENS_SAR1_ATTEN_S 0
#define SENS_SAR1_ATTEN_VAL_MASK 0x3
#define SENS_SAR2_ATTEN_VAL_MASK 0x3
#define SENS_SAR_ATTEN2_REG (DR_REG_SENS_BASE + 0x0038)
/* SENS_SAR2_ATTEN : R/W ;bitpos:[31:0] ;default: 32'hffffffff ; */

View file

@ -18,112 +18,106 @@
extern "C" {
#endif
typedef struct {
typedef volatile struct {
union {
struct {
volatile uint32_t pre_div: 10;
volatile uint32_t clk_320m_en: 1;
volatile uint32_t clk_en: 1;
volatile uint32_t rst_tick: 1;
volatile uint32_t quick_clk_chng: 1;
volatile uint32_t reserved14: 18;
uint32_t pre_div: 10;
uint32_t clk_320m_en: 1;
uint32_t clk_en: 1;
uint32_t rst_tick: 1;
uint32_t quick_clk_chng: 1;
uint32_t reserved14: 18;
};
volatile uint32_t val;
uint32_t val;
}clk_conf;
union {
struct {
volatile uint32_t xtal_tick: 8;
volatile uint32_t reserved8: 24;
uint32_t xtal_tick: 8;
uint32_t reserved8: 24;
};
volatile uint32_t val;
uint32_t val;
}xtal_tick_conf;
union {
struct {
volatile uint32_t pll_tick: 8;
volatile uint32_t reserved8: 24;
uint32_t pll_tick: 8;
uint32_t reserved8: 24;
};
volatile uint32_t val;
uint32_t val;
}pll_tick_conf;
union {
struct {
volatile uint32_t ck8m_tick: 8;
volatile uint32_t reserved8: 24;
uint32_t ck8m_tick: 8;
uint32_t reserved8: 24;
};
volatile uint32_t val;
uint32_t val;
}ck8m_tick_conf;
union {
struct {
volatile uint32_t start_force: 1;
volatile uint32_t start: 1;
volatile uint32_t sar2_mux: 1; /*1: SAR ADC2 is controlled by DIG ADC2 CTRL 0: SAR ADC2 is controlled by PWDET CTRL*/
volatile uint32_t work_mode: 2; /*0: single mode 1: double mode 2: alternate mode*/
volatile uint32_t sar_sel: 1; /*0: SAR1 1: SAR2 only work for single SAR mode*/
volatile uint32_t sar_clk_gated: 1;
volatile uint32_t sar_clk_div: 8; /*SAR clock divider*/
volatile uint32_t sar1_patt_len: 4; /*0 ~ 15 means length 1 ~ 16*/
volatile uint32_t sar2_patt_len: 4; /*0 ~ 15 means length 1 ~ 16*/
volatile uint32_t sar1_patt_p_clear: 1; /*clear the pointer of pattern table for DIG ADC1 CTRL*/
volatile uint32_t sar2_patt_p_clear: 1; /*clear the pointer of pattern table for DIG ADC2 CTRL*/
volatile uint32_t data_sar_sel: 1; /*1: sar_sel will be coded by the MSB of the 16-bit output data in this case the resolution should not be larger than 11 bits.*/
volatile uint32_t data_to_i2s: 1; /*1: I2S input data is from SAR ADC (for DMA) 0: I2S input data is from GPIO matrix*/
volatile uint32_t reserved27: 5;
uint32_t start_force: 1;
uint32_t start: 1;
uint32_t sar2_mux: 1; /*1: SAR ADC2 is controlled by DIG ADC2 CTRL 0: SAR ADC2 is controlled by PWDET CTRL*/
uint32_t work_mode: 2; /*0: single mode 1: double mode 2: alternate mode*/
uint32_t sar_sel: 1; /*0: SAR1 1: SAR2 only work for single SAR mode*/
uint32_t sar_clk_gated: 1;
uint32_t sar_clk_div: 8; /*SAR clock divider*/
uint32_t sar1_patt_len: 4; /*0 ~ 15 means length 1 ~ 16*/
uint32_t sar2_patt_len: 4; /*0 ~ 15 means length 1 ~ 16*/
uint32_t sar1_patt_p_clear: 1; /*clear the pointer of pattern table for DIG ADC1 CTRL*/
uint32_t sar2_patt_p_clear: 1; /*clear the pointer of pattern table for DIG ADC2 CTRL*/
uint32_t data_sar_sel: 1; /*1: sar_sel will be coded by the MSB of the 16-bit output data in this case the resolution should not be larger than 11 bits.*/
uint32_t data_to_i2s: 1; /*1: I2S input data is from SAR ADC (for DMA) 0: I2S input data is from GPIO matrix*/
uint32_t reserved27: 5;
};
volatile uint32_t val;
uint32_t val;
}saradc_ctrl;
union {
struct {
volatile uint32_t meas_num_limit: 1;
volatile uint32_t max_meas_num: 8; /*max conversion number*/
volatile uint32_t sar1_inv: 1; /*1: data to DIG ADC1 CTRL is inverted otherwise not*/
volatile uint32_t sar2_inv: 1; /*1: data to DIG ADC2 CTRL is inverted otherwise not*/
volatile uint32_t reserved11: 21;
uint32_t meas_num_limit: 1;
uint32_t max_meas_num: 8; /*max conversion number*/
uint32_t sar1_inv: 1; /*1: data to DIG ADC1 CTRL is inverted otherwise not*/
uint32_t sar2_inv: 1; /*1: data to DIG ADC2 CTRL is inverted otherwise not*/
uint32_t reserved11: 21;
};
volatile uint32_t val;
uint32_t val;
}saradc_ctrl2;
union {
struct {
volatile uint32_t rstb_wait: 8;
volatile uint32_t standby_wait: 8;
volatile uint32_t start_wait: 8;
volatile uint32_t sample_cycle: 8; /*sample cycles*/
uint32_t rstb_wait: 8;
uint32_t standby_wait: 8;
uint32_t start_wait: 8;
uint32_t sample_cycle: 8; /*sample cycles*/
};
volatile uint32_t val;
uint32_t val;
}saradc_fsm;
volatile uint32_t saradc_sar1_patt_tab1; /*item 0 ~ 3 for pattern table 1 (each item one byte)*/
volatile uint32_t saradc_sar1_patt_tab2; /*Item 4 ~ 7 for pattern table 1 (each item one byte)*/
volatile uint32_t saradc_sar1_patt_tab3; /*Item 8 ~ 11 for pattern table 1 (each item one byte)*/
volatile uint32_t saradc_sar1_patt_tab4; /*Item 12 ~ 15 for pattern table 1 (each item one byte)*/
volatile uint32_t saradc_sar2_patt_tab1; /*item 0 ~ 3 for pattern table 2 (each item one byte)*/
volatile uint32_t saradc_sar2_patt_tab2; /*Item 4 ~ 7 for pattern table 2 (each item one byte)*/
volatile uint32_t saradc_sar2_patt_tab3; /*Item 8 ~ 11 for pattern table 2 (each item one byte)*/
volatile uint32_t saradc_sar2_patt_tab4; /*Item 12 ~ 15 for pattern table 2 (each item one byte)*/
uint32_t saradc_sar1_patt_tab[4]; /*item 0 ~ 3 for ADC1 pattern table*/
uint32_t saradc_sar2_patt_tab[4]; /*item 0 ~ 3 for ADC2 pattern table*/
union {
struct {
volatile uint32_t apll_tick: 8;
volatile uint32_t reserved8: 24;
uint32_t apll_tick: 8;
uint32_t reserved8: 24;
};
volatile uint32_t val;
uint32_t val;
}apll_tick_conf;
volatile uint32_t reserved_40;
volatile uint32_t reserved_44;
volatile uint32_t reserved_48;
volatile uint32_t reserved_4c;
volatile uint32_t reserved_50;
volatile uint32_t reserved_54;
volatile uint32_t reserved_58;
volatile uint32_t reserved_5c;
volatile uint32_t reserved_60;
volatile uint32_t reserved_64;
volatile uint32_t reserved_68;
volatile uint32_t reserved_6c;
volatile uint32_t reserved_70;
volatile uint32_t reserved_74;
volatile uint32_t reserved_78;
volatile uint32_t date; /**/
uint32_t reserved_40;
uint32_t reserved_44;
uint32_t reserved_48;
uint32_t reserved_4c;
uint32_t reserved_50;
uint32_t reserved_54;
uint32_t reserved_58;
uint32_t reserved_5c;
uint32_t reserved_60;
uint32_t reserved_64;
uint32_t reserved_68;
uint32_t reserved_6c;
uint32_t reserved_70;
uint32_t reserved_74;
uint32_t reserved_78;
uint32_t date; /**/
} syscon_dev_t;
#ifdef __cplusplus
}
#endif
extern syscon_dev_t SYSCON;
#endif /* _SOC_SYSCON_STRUCT_H_ */

View file

@ -32,8 +32,8 @@ Reading voltage on ADC1 channel 0 (GPIO 36)::
...
adc1_config_width(ADC_WIDTH_12Bit);
adc1_config_channel_atten(ADC1_CHANNEL_0,ADC_ATTEN_0db);
adc1_config_width(ADC_WIDTH_BIT_12);
adc1_config_channel_atten(ADC1_CHANNEL_0,ADC_ATTEN_DB_0);
int val = adc1_get_raw(ADC1_CHANNEL_0);
The input voltage in above example is from 0 to 1.1V (0 dB attenuation). The input range can be extended by setting higher attenuation, see :cpp:type:`adc_atten_t`.
@ -44,7 +44,7 @@ Reading the internal hall effect sensor::
...
adc1_config_width(ADC_WIDTH_12Bit);
adc1_config_width(ADC_WIDTH_BIT_12);
int val = hall_sensor_read();
@ -81,7 +81,7 @@ Reading the ADC and obtaining a result in mV::
// Calculate ADC characteristics i.e. gain and offset factors
esp_adc_cal_characteristics_t characteristics;
esp_adc_cal_get_characteristics(V_REF, ADC_ATTEN_11db, ADC_WIDTH_12Bit, &characteristics);
esp_adc_cal_get_characteristics(V_REF, ADC_ATTEN_DB_11, ADC_WIDTH_BIT_12, &characteristics);
// Read ADC and obtain result in mV
uint32_t voltage = adc1_to_voltage(ADC1_CHANNEL_6, &characteristics);

View file

@ -28,9 +28,9 @@ void app_main(void)
#ifndef V_REF_TO_GPIO
//Init ADC and Characteristics
esp_adc_cal_characteristics_t characteristics;
adc1_config_width(ADC_WIDTH_12Bit);
adc1_config_channel_atten(ADC1_TEST_CHANNEL, ADC_ATTEN_0db);
esp_adc_cal_get_characteristics(V_REF, ADC_ATTEN_0db, ADC_WIDTH_12Bit, &characteristics);
adc1_config_width(ADC_WIDTH_BIT_12);
adc1_config_channel_atten(ADC1_TEST_CHANNEL, ADC_ATTEN_DB_0);
esp_adc_cal_get_characteristics(V_REF, ADC_ATTEN_DB_0, ADC_WIDTH_BIT_12, &characteristics);
uint32_t voltage;
while(1){
voltage = adc1_to_voltage(ADC1_TEST_CHANNEL, &characteristics);

View file

@ -0,0 +1,9 @@
#
# This is a project Makefile. It is assumed the directory this Makefile resides in is a
# project subdirectory.
#
PROJECT_NAME := i2s-adc-dac
include $(IDF_PATH)/make/project.mk

View file

@ -0,0 +1,53 @@
# I2S built-in ADC/DAC Example
---
* This is an example of:
* Recording sound from ADC
* Replay the recorded sound via DAC
* Play an audio file in flash
---
* Run this example
* Set partition table to "partitions_adc_dac_example.csv" in menuconfig, or rename sdkconfig.default to sdkconfig directly.
* Set IDF_PATH and run "make flash"
---
* This example will execute the following steps:
1. Erase flash
2. Record audio from ADC and save in flash
3. Read flash and replay the sound via DAC
4. Play an example audio file(file format: 8bit/8khz/single channel)
5. Loop back to step 3
---
* Hardware connection:
| ESP32 | Microphone + amplifier | amplifier + speaker |
|--|--|--|
| GPIO36(ADC1CH0 input) | data output pin | |
| GPIO25(DAC1 output) | | right channel speaker input|
| GPIO26(DAC2 output) | | left channel speaker input|
---
* How to generate audio files:
* tools/generate_audio_file.py is an example of generate audio table from .wav files.
* In this example, the wav file must be in 16k/16bit mono format.
* generate_audio_file.py will bundle the wav files into a single table named audio_example_file.h
* Since the ADC can only play 8-bit data, the script will scale each 16-bit value to a 8-bit value.
* Since the ADC can only output positive value, the script will turn a signed value into an unsigned value.
---
* Note:
* DAC can only play 8-bit data, so the wav file data are scaled to 8-bit data.
* I2S DMA can only output 16-bit/32-bit data to DAC, DAC will only take the highest 8-bit data and output accordingly.
* Before I2S DMA can output data stream to DAC, the data format should be converted to 16-bit or 32-bit by padding zeros.

View file

@ -0,0 +1,266 @@
#include <stdio.h>
#include <string.h>
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "esp_spi_flash.h"
#include "esp_err.h"
#include "esp_log.h"
#include "esp_partition.h"
#include "driver/i2s.h"
#include "driver/adc.h"
#include "audio_example_file.h"
static const char* TAG = "ad/da";
#define PARTITION_NAME "storage"
/*---------------------------------------------------------------
EXAMPLE CONFIG
---------------------------------------------------------------*/
//enable record sound and save in flash
#define RECORD_IN_FLASH_EN (1)
//enable replay recorded sound in flash
#define REPLAY_FROM_FLASH_EN (1)
//i2s number
#define EXAMPLE_I2S_NUM (0)
//i2s sample rate
#define EXAMPLE_I2S_SAMPLE_RATE (16000)
//i2s data bits
#define EXAMPLE_I2S_SAMPLE_BITS (16)
//enable display buffer for debug
#define EXAMPLE_I2S_BUF_DEBUG (0)
//I2S read buffer length
#define EXAMPLE_I2S_READ_LEN (16 * 1024)
//I2S data format
#define EXAMPLE_I2S_FORMAT (I2S_CHANNEL_FMT_RIGHT_LEFT)
//I2S channel number
#define EXAMPLE_I2S_CHANNEL_NUM ((EXAMPLE_I2S_FORMAT < I2S_CHANNEL_FMT_ONLY_RIGHT) ? (2) : (1))
//flash record size, for recording 5 seconds' data
#define FLASH_RECORD_SIZE (EXAMPLE_I2S_CHANNEL_NUM * EXAMPLE_I2S_SAMPLE_RATE * EXAMPLE_I2S_SAMPLE_BITS / 8 * 5)
#define FLASH_ERASE_SIZE (FLASH_RECORD_SIZE % FLASH_SECTOR_SIZE == 0) ? FLASH_RECORD_SIZE : FLASH_RECORD_SIZE + (FLASH_SECTOR_SIZE - FLASH_RECORD_SIZE % FLASH_SECTOR_SIZE)
//sector size of flash
#define FLASH_SECTOR_SIZE (0x1000)
//flash read / write address
#define FLASH_ADDR (0x200000)
/**
* @brief I2S ADC/DAC mode init.
*/
void example_i2s_init()
{
int i2s_num = EXAMPLE_I2S_NUM;
i2s_config_t i2s_config = {
.mode = I2S_MODE_MASTER | I2S_MODE_RX | I2S_MODE_TX | I2S_MODE_DAC_BUILT_IN | I2S_MODE_ADC_BUILT_IN,
.sample_rate = EXAMPLE_I2S_SAMPLE_RATE,
.bits_per_sample = EXAMPLE_I2S_SAMPLE_BITS,
.communication_format = I2S_COMM_FORMAT_I2S_MSB,
.channel_format = EXAMPLE_I2S_FORMAT,
.intr_alloc_flags = 0,
.dma_buf_count = 2,
.dma_buf_len = 1024
};
//install and start i2s driver
i2s_driver_install(i2s_num, &i2s_config, 0, NULL);
//init DAC pad
i2s_set_dac_mode(I2S_DAC_CHANNEL_BOTH_EN);
//init ADC pad
i2s_set_adc_mode(ADC_UNIT_1, ADC1_CHANNEL_0);
}
/*
* @brief erase flash for recording
*/
void example_erase_flash()
{
#if RECORD_IN_FLASH_EN
printf("Erasing flash \n");
const esp_partition_t *data_partition = NULL;
data_partition = esp_partition_find_first(ESP_PARTITION_TYPE_DATA,
ESP_PARTITION_SUBTYPE_DATA_FAT, PARTITION_NAME);
if (data_partition != NULL) {
printf("partiton addr: 0x%08x; size: %d; label: %s\n", data_partition->address, data_partition->size, data_partition->label);
}
printf("Erase size: %d Bytes\n", FLASH_ERASE_SIZE);
ESP_ERROR_CHECK(esp_partition_erase_range(data_partition, 0, FLASH_ERASE_SIZE));
#else
printf("Skip flash erasing...\n");
#endif
}
/**
* @brief debug buffer data
*/
void example_disp_buf(uint8_t* buf, int length)
{
#if EXAMPLE_I2S_BUF_DEBUG
printf("======\n");
for (int i = 0; i < length; i++) {
printf("%02x ", buf[i]);
if ((i + 1) % 8 == 0) {
printf("\n");
}
}
printf("======\n");
#endif
}
/**
* @brief Reset i2s clock and mode
*/
void example_reset_play_mode()
{
i2s_set_clk(EXAMPLE_I2S_NUM, EXAMPLE_I2S_SAMPLE_RATE, EXAMPLE_I2S_SAMPLE_BITS, EXAMPLE_I2S_CHANNEL_NUM);
}
/**
* @brief Set i2s clock for example audio file
*/
void example_set_file_play_mode()
{
i2s_set_clk(EXAMPLE_I2S_NUM, 16000, EXAMPLE_I2S_SAMPLE_BITS, 1);
}
/**
* @brief Scale data to 16bit/32bit for I2S DMA output.
* DAC can only output 8bit data value.
* I2S DMA will still send 16 bit or 32bit data, the highest 8bit contains DAC data.
*/
int example_i2s_dac_data_scale(uint8_t* d_buff, uint8_t* s_buff, uint32_t len)
{
uint32_t j = 0;
#if (EXAMPLE_I2S_SAMPLE_BITS == 16)
for (int i = 0; i < len; i++) {
d_buff[j++] = 0;
d_buff[j++] = s_buff[i];
}
return (len * 2);
#else
for (int i = 0; i < len; i++) {
d_buff[j++] = 0;
d_buff[j++] = 0;
d_buff[j++] = 0;
d_buff[j++] = s_buff[i];
}
return (len * 4);
#endif
}
/**
* @brief Scale data to 8bit for data from ADC.
* Data from ADC are 12bit width by default.
* DAC can only output 8 bit data.
* Scale each 12bit ADC data to 8bit DAC data.
*/
void example_i2s_adc_data_scale(uint8_t * d_buff, uint8_t* s_buff, uint32_t len)
{
uint32_t j = 0;
uint32_t dac_value = 0;
#if (EXAMPLE_I2S_SAMPLE_BITS == 16)
for (int i = 0; i < len; i += 2) {
dac_value = ((((uint16_t) (s_buff[i + 1] & 0xf) << 8) | ((s_buff[i + 0]))));
d_buff[j++] = 0;
d_buff[j++] = dac_value * 256 / 4096;
}
#else
for (int i = 0; i < len; i += 4) {
dac_value = ((((uint16_t)(s_buff[i + 3] & 0xf) << 8) | ((s_buff[i + 2]))));
d_buff[j++] = 0;
d_buff[j++] = 0;
d_buff[j++] = 0;
d_buff[j++] = dac_value * 256 / 4096;
}
#endif
}
/**
* @brief I2S ADC/DAC example
* 1. Erase flash
* 2. Record audio from ADC and save in flash
* 3. Read flash and replay the sound via DAC
* 4. Play an example audio file(file format: 8bit/8khz/single channel)
* 5. Loop back to step 3
*/
void example_i2s_adc_dac(void*arg)
{
const esp_partition_t *data_partition = NULL;
data_partition = esp_partition_find_first(ESP_PARTITION_TYPE_DATA,
ESP_PARTITION_SUBTYPE_DATA_FAT, PARTITION_NAME);
if (data_partition != NULL) {
printf("partiton addr: 0x%08x; size: %d; label: %s\n", data_partition->address, data_partition->size, data_partition->label);
} else {
ESP_LOGE(TAG, "Partition error: can't find partition name: %s\n", PARTITION_NAME);
vTaskDelete(NULL);
}
//1. Erase flash
example_erase_flash();
example_i2s_init();
int i2s_read_len = EXAMPLE_I2S_READ_LEN;
int flash_wr_size = 0;
//2. Record audio from ADC and save in flash
#if RECORD_IN_FLASH_EN
char* i2s_read_buff = (char*) calloc(i2s_read_len, sizeof(char));
uint8_t* flash_write_buff = (uint8_t*) calloc(i2s_read_len, sizeof(char));
while (flash_wr_size < FLASH_RECORD_SIZE) {
//read data from I2S bus, in this case, from ADC.
i2s_read_bytes(EXAMPLE_I2S_NUM, (char*) i2s_read_buff, i2s_read_len, portMAX_DELAY);
example_disp_buf((uint8_t*) i2s_read_buff, 64);
//save original data from I2S(ADC) into flash.
esp_partition_write(data_partition, flash_wr_size, i2s_read_buff, i2s_read_len);
flash_wr_size += i2s_read_len;
ets_printf("Sound recording %u%%\n", flash_wr_size * 100 / FLASH_RECORD_SIZE);
}
free(i2s_read_buff);
i2s_read_buff = NULL;
free(flash_write_buff);
flash_write_buff = NULL;
#endif
uint8_t* flash_read_buff = (uint8_t*) calloc(i2s_read_len, sizeof(char));
uint8_t* i2s_write_buff = (uint8_t*) calloc(i2s_read_len, sizeof(char));
while (1) {
//3. Read flash and replay the sound via DAC
#if REPLAY_FROM_FLASH_EN
for (int rd_offset = 0; rd_offset < flash_wr_size; rd_offset += FLASH_SECTOR_SIZE) {
//read I2S(ADC) original data from flash
esp_partition_read(data_partition, rd_offset, flash_read_buff, FLASH_SECTOR_SIZE);
//process data and scale to 8bit for I2S DAC.
example_i2s_adc_data_scale(i2s_write_buff, flash_read_buff, FLASH_SECTOR_SIZE);
//send data
i2s_write_bytes(EXAMPLE_I2S_NUM, (char*) i2s_write_buff, FLASH_SECTOR_SIZE, portMAX_DELAY);
printf("playing: %d %%\n", rd_offset * 100 / flash_wr_size);
}
#endif
//4. Play an example audio file(file format: 8bit/16khz/single channel)
printf("Playing file example: \n");
int offset = 0;
int tot_size = sizeof(audio_table);
example_set_file_play_mode();
while (offset < tot_size) {
int play_len = ((tot_size - offset) > (4 * 1024)) ? (4 * 1024) : (tot_size - offset);
int i2s_wr_len = example_i2s_dac_data_scale(i2s_write_buff, (uint8_t*)(audio_table + offset), play_len);
i2s_write_bytes(EXAMPLE_I2S_NUM, (const char*) i2s_write_buff, i2s_wr_len, portMAX_DELAY);
offset += play_len;
example_disp_buf((uint8_t*) i2s_write_buff, 32);
}
vTaskDelay(100 / portTICK_PERIOD_MS);
example_reset_play_mode();
}
free(flash_read_buff);
free(i2s_write_buff);
vTaskDelete(NULL);
}
esp_err_t app_main()
{
esp_log_level_set("I2S", ESP_LOG_INFO);
xTaskCreate(example_i2s_adc_dac, "example_i2s_adc_dac", 1024 * 2, NULL, 5, NULL);
return ESP_OK;
}

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,5 @@
#
# "main" pseudo-component makefile.
#
# (Uses default behaviour of compiling all source files in directory, adding 'include' to include path.)

View file

@ -0,0 +1,6 @@
# Name, Type, SubType, Offset, Size, Flags
# Note: if you change the phy_init or app partition offset, make sure to change the offset in Kconfig.projbuild
nvs, data, nvs, 0x9000, 0x6000,
phy_init, data, phy, 0xf000, 0x1000,
factory, app, factory, 0x10000, 1M,
storage, data, fat, , 2M,
1 # Name, Type, SubType, Offset, Size, Flags
2 # Note: if you change the phy_init or app partition offset, make sure to change the offset in Kconfig.projbuild
3 nvs, data, nvs, 0x9000, 0x6000,
4 phy_init, data, phy, 0xf000, 0x1000,
5 factory, app, factory, 0x10000, 1M,
6 storage, data, fat, , 2M,

View file

@ -0,0 +1,333 @@
#
# Automatically generated file; DO NOT EDIT.
# Espressif IoT Development Framework Configuration
#
#
# SDK tool configuration
#
CONFIG_TOOLPREFIX="xtensa-esp32-elf-"
CONFIG_PYTHON="python"
#
# Bootloader config
#
# CONFIG_LOG_BOOTLOADER_LEVEL_NONE is not set
# CONFIG_LOG_BOOTLOADER_LEVEL_ERROR is not set
# CONFIG_LOG_BOOTLOADER_LEVEL_WARN is not set
# CONFIG_LOG_BOOTLOADER_LEVEL_INFO is not set
CONFIG_LOG_BOOTLOADER_LEVEL_DEBUG=y
# CONFIG_LOG_BOOTLOADER_LEVEL_VERBOSE is not set
CONFIG_LOG_BOOTLOADER_LEVEL=4
# CONFIG_BOOTLOADER_LTO is not set
#
# Security features
#
# CONFIG_SECURE_BOOT_ENABLED is not set
# CONFIG_FLASH_ENCRYPTION_ENABLED is not set
#
# Serial flasher config
#
CONFIG_ESPTOOLPY_PORT="/dev/ttyUSB1"
# CONFIG_ESPTOOLPY_BAUD_115200B is not set
# CONFIG_ESPTOOLPY_BAUD_230400B is not set
CONFIG_ESPTOOLPY_BAUD_921600B=y
# CONFIG_ESPTOOLPY_BAUD_2MB is not set
# CONFIG_ESPTOOLPY_BAUD_OTHER is not set
CONFIG_ESPTOOLPY_BAUD_OTHER_VAL=115200
CONFIG_ESPTOOLPY_BAUD=921600
CONFIG_ESPTOOLPY_COMPRESSED=y
# CONFIG_FLASHMODE_QIO is not set
# CONFIG_FLASHMODE_QOUT is not set
CONFIG_FLASHMODE_DIO=y
# CONFIG_FLASHMODE_DOUT is not set
CONFIG_ESPTOOLPY_FLASHMODE="dio"
# CONFIG_ESPTOOLPY_FLASHFREQ_80M is not set
CONFIG_ESPTOOLPY_FLASHFREQ_40M=y
# CONFIG_ESPTOOLPY_FLASHFREQ_26M is not set
# CONFIG_ESPTOOLPY_FLASHFREQ_20M is not set
CONFIG_ESPTOOLPY_FLASHFREQ="40m"
# CONFIG_ESPTOOLPY_FLASHSIZE_1MB is not set
# CONFIG_ESPTOOLPY_FLASHSIZE_2MB is not set
CONFIG_ESPTOOLPY_FLASHSIZE_4MB=y
# CONFIG_ESPTOOLPY_FLASHSIZE_8MB is not set
# CONFIG_ESPTOOLPY_FLASHSIZE_16MB is not set
CONFIG_ESPTOOLPY_FLASHSIZE="4MB"
CONFIG_ESPTOOLPY_FLASHSIZE_DETECT=y
CONFIG_ESPTOOLPY_BEFORE_RESET=y
# CONFIG_ESPTOOLPY_BEFORE_NORESET is not set
CONFIG_ESPTOOLPY_BEFORE="default_reset"
CONFIG_ESPTOOLPY_AFTER_RESET=y
# CONFIG_ESPTOOLPY_AFTER_NORESET is not set
CONFIG_ESPTOOLPY_AFTER="hard_reset"
# CONFIG_MONITOR_BAUD_9600B is not set
# CONFIG_MONITOR_BAUD_57600B is not set
CONFIG_MONITOR_BAUD_115200B=y
# CONFIG_MONITOR_BAUD_230400B is not set
# CONFIG_MONITOR_BAUD_921600B is not set
# CONFIG_MONITOR_BAUD_2MB is not set
# CONFIG_MONITOR_BAUD_OTHER is not set
CONFIG_MONITOR_BAUD_OTHER_VAL=115200
CONFIG_MONITOR_BAUD=115200
#
# Partition Table
#
# CONFIG_PARTITION_TABLE_SINGLE_APP is not set
# CONFIG_PARTITION_TABLE_TWO_OTA is not set
CONFIG_PARTITION_TABLE_CUSTOM=y
CONFIG_PARTITION_TABLE_CUSTOM_FILENAME="partitions_adc_dac_example.csv"
CONFIG_PARTITION_TABLE_CUSTOM_APP_BIN_OFFSET=0x10000
CONFIG_PARTITION_TABLE_FILENAME="partitions_adc_dac_example.csv"
CONFIG_APP_OFFSET=0x10000
#
# Compiler options
#
CONFIG_OPTIMIZATION_LEVEL_DEBUG=y
# CONFIG_OPTIMIZATION_LEVEL_RELEASE is not set
CONFIG_OPTIMIZATION_ASSERTIONS_ENABLED=y
# CONFIG_OPTIMIZATION_ASSERTIONS_SILENT is not set
# CONFIG_OPTIMIZATION_ASSERTIONS_DISABLED is not set
#
# Component config
#
#
# Application Level Tracing
#
# CONFIG_ESP32_APPTRACE_DEST_TRAX is not set
CONFIG_ESP32_APPTRACE_DEST_NONE=y
# CONFIG_ESP32_APPTRACE_ENABLE is not set
CONFIG_ESP32_APPTRACE_LOCK_ENABLE=y
#
# FreeRTOS SystemView Tracing
#
# CONFIG_AWS_IOT_SDK is not set
# CONFIG_BT_ENABLED is not set
CONFIG_BT_RESERVE_DRAM=0
#
# Touch pad driver
#
# CONFIG_TOUCH_PAD_FILTER_EN is not set
#
# ESP32-specific
#
CONFIG_ESP32_DEFAULT_CPU_FREQ_80=y
# CONFIG_ESP32_DEFAULT_CPU_FREQ_160 is not set
# CONFIG_ESP32_DEFAULT_CPU_FREQ_240 is not set
CONFIG_ESP32_DEFAULT_CPU_FREQ_MHZ=80
CONFIG_MEMMAP_SMP=y
# CONFIG_MEMMAP_TRACEMEM is not set
# CONFIG_MEMMAP_TRACEMEM_TWOBANKS is not set
# CONFIG_ESP32_TRAX is not set
CONFIG_TRACEMEM_RESERVE_DRAM=0x0
# CONFIG_ESP32_ENABLE_COREDUMP_TO_FLASH is not set
# CONFIG_ESP32_ENABLE_COREDUMP_TO_UART is not set
CONFIG_ESP32_ENABLE_COREDUMP_TO_NONE=y
# CONFIG_ESP32_ENABLE_COREDUMP is not set
# CONFIG_TWO_UNIVERSAL_MAC_ADDRESS is not set
CONFIG_FOUR_UNIVERSAL_MAC_ADDRESS=y
CONFIG_NUMBER_OF_UNIVERSAL_MAC_ADDRESS=4
CONFIG_SYSTEM_EVENT_QUEUE_SIZE=32
CONFIG_SYSTEM_EVENT_TASK_STACK_SIZE=2048
CONFIG_MAIN_TASK_STACK_SIZE=4096
CONFIG_IPC_TASK_STACK_SIZE=1024
CONFIG_NEWLIB_STDOUT_ADDCR=y
# CONFIG_NEWLIB_NANO_FORMAT is not set
CONFIG_CONSOLE_UART_DEFAULT=y
# CONFIG_CONSOLE_UART_CUSTOM is not set
# CONFIG_CONSOLE_UART_NONE is not set
CONFIG_CONSOLE_UART_NUM=0
CONFIG_CONSOLE_UART_BAUDRATE=115200
# CONFIG_ULP_COPROC_ENABLED is not set
CONFIG_ULP_COPROC_RESERVE_MEM=0
# CONFIG_ESP32_PANIC_PRINT_HALT is not set
CONFIG_ESP32_PANIC_PRINT_REBOOT=y
# CONFIG_ESP32_PANIC_SILENT_REBOOT is not set
# CONFIG_ESP32_PANIC_GDBSTUB is not set
CONFIG_ESP32_DEBUG_OCDAWARE=y
# CONFIG_INT_WDT is not set
# CONFIG_TASK_WDT is not set
CONFIG_BROWNOUT_DET=y
CONFIG_BROWNOUT_DET_LVL_SEL_0=y
# CONFIG_BROWNOUT_DET_LVL_SEL_1 is not set
# CONFIG_BROWNOUT_DET_LVL_SEL_2 is not set
# CONFIG_BROWNOUT_DET_LVL_SEL_3 is not set
# CONFIG_BROWNOUT_DET_LVL_SEL_4 is not set
# CONFIG_BROWNOUT_DET_LVL_SEL_5 is not set
# CONFIG_BROWNOUT_DET_LVL_SEL_6 is not set
# CONFIG_BROWNOUT_DET_LVL_SEL_7 is not set
CONFIG_BROWNOUT_DET_LVL=0
# CONFIG_ESP32_TIME_SYSCALL_USE_RTC is not set
CONFIG_ESP32_TIME_SYSCALL_USE_RTC_FRC1=y
# CONFIG_ESP32_TIME_SYSCALL_USE_FRC1 is not set
# CONFIG_ESP32_TIME_SYSCALL_USE_NONE is not set
CONFIG_ESP32_RTC_CLOCK_SOURCE_INTERNAL_RC=y
# CONFIG_ESP32_RTC_CLOCK_SOURCE_EXTERNAL_CRYSTAL is not set
CONFIG_ESP32_RTC_CLK_CAL_CYCLES=1024
CONFIG_ESP32_DEEP_SLEEP_WAKEUP_DELAY=0
# CONFIG_ESP32_XTAL_FREQ_40 is not set
# CONFIG_ESP32_XTAL_FREQ_26 is not set
CONFIG_ESP32_XTAL_FREQ_AUTO=y
CONFIG_ESP32_XTAL_FREQ=0
CONFIG_WIFI_ENABLED=y
CONFIG_ESP32_WIFI_STATIC_RX_BUFFER_NUM=10
CONFIG_ESP32_WIFI_DYNAMIC_RX_BUFFER_NUM=32
# CONFIG_ESP32_WIFI_STATIC_TX_BUFFER is not set
CONFIG_ESP32_WIFI_DYNAMIC_TX_BUFFER=y
CONFIG_ESP32_WIFI_TX_BUFFER_TYPE=1
CONFIG_ESP32_WIFI_DYNAMIC_TX_BUFFER_NUM=32
CONFIG_ESP32_WIFI_AMPDU_ENABLED=y
CONFIG_ESP32_WIFI_TX_BA_WIN=6
CONFIG_ESP32_WIFI_RX_BA_WIN=6
CONFIG_ESP32_WIFI_NVS_ENABLED=y
CONFIG_PHY_ENABLED=y
#
# PHY
#
CONFIG_ESP32_PHY_CALIBRATION_AND_DATA_STORAGE=y
# CONFIG_ESP32_PHY_INIT_DATA_IN_PARTITION is not set
CONFIG_ESP32_PHY_MAX_WIFI_TX_POWER=20
CONFIG_ESP32_PHY_MAX_TX_POWER=20
# CONFIG_ETHERNET is not set
#
# FAT Filesystem support
#
CONFIG_FATFS_CODEPAGE_ASCII=y
# CONFIG_FATFS_CODEPAGE_437 is not set
# CONFIG_FATFS_CODEPAGE_720 is not set
# CONFIG_FATFS_CODEPAGE_737 is not set
# CONFIG_FATFS_CODEPAGE_771 is not set
# CONFIG_FATFS_CODEPAGE_775 is not set
# CONFIG_FATFS_CODEPAGE_850 is not set
# CONFIG_FATFS_CODEPAGE_852 is not set
# CONFIG_FATFS_CODEPAGE_855 is not set
# CONFIG_FATFS_CODEPAGE_857 is not set
# CONFIG_FATFS_CODEPAGE_860 is not set
# CONFIG_FATFS_CODEPAGE_861 is not set
# CONFIG_FATFS_CODEPAGE_862 is not set
# CONFIG_FATFS_CODEPAGE_863 is not set
# CONFIG_FATFS_CODEPAGE_864 is not set
# CONFIG_FATFS_CODEPAGE_865 is not set
# CONFIG_FATFS_CODEPAGE_866 is not set
# CONFIG_FATFS_CODEPAGE_869 is not set
# CONFIG_FATFS_CODEPAGE_932 is not set
# CONFIG_FATFS_CODEPAGE_936 is not set
# CONFIG_FATFS_CODEPAGE_949 is not set
# CONFIG_FATFS_CODEPAGE_950 is not set
CONFIG_FATFS_CODEPAGE=1
CONFIG_FATFS_MAX_LFN=255
#
# FreeRTOS
#
CONFIG_FREERTOS_UNICORE=y
CONFIG_FREERTOS_CORETIMER_0=y
# CONFIG_FREERTOS_CORETIMER_1 is not set
CONFIG_FREERTOS_HZ=100
CONFIG_FREERTOS_ASSERT_ON_UNTESTED_FUNCTION=y
CONFIG_FREERTOS_CHECK_STACKOVERFLOW_NONE=y
# CONFIG_FREERTOS_CHECK_STACKOVERFLOW_PTRVAL is not set
# CONFIG_FREERTOS_CHECK_STACKOVERFLOW_CANARY is not set
# CONFIG_FREERTOS_WATCHPOINT_END_OF_STACK is not set
CONFIG_FREERTOS_THREAD_LOCAL_STORAGE_POINTERS=1
CONFIG_FREERTOS_ASSERT_FAIL_ABORT=y
# CONFIG_FREERTOS_ASSERT_FAIL_PRINT_CONTINUE is not set
# CONFIG_FREERTOS_ASSERT_DISABLE is not set
CONFIG_FREERTOS_BREAK_ON_SCHEDULER_START_JTAG=y
# CONFIG_ENABLE_MEMORY_DEBUG is not set
CONFIG_FREERTOS_IDLE_TASK_STACKSIZE=1024
CONFIG_FREERTOS_ISR_STACKSIZE=1536
# CONFIG_FREERTOS_LEGACY_HOOKS is not set
CONFIG_FREERTOS_MAX_TASK_NAME_LEN=16
# CONFIG_SUPPORT_STATIC_ALLOCATION is not set
CONFIG_TIMER_TASK_PRIORITY=1
CONFIG_TIMER_TASK_STACK_DEPTH=2048
CONFIG_TIMER_QUEUE_LENGTH=10
# CONFIG_FREERTOS_DEBUG_INTERNALS is not set
#
# Log output
#
# CONFIG_LOG_DEFAULT_LEVEL_NONE is not set
# CONFIG_LOG_DEFAULT_LEVEL_ERROR is not set
# CONFIG_LOG_DEFAULT_LEVEL_WARN is not set
# CONFIG_LOG_DEFAULT_LEVEL_INFO is not set
CONFIG_LOG_DEFAULT_LEVEL_DEBUG=y
# CONFIG_LOG_DEFAULT_LEVEL_VERBOSE is not set
CONFIG_LOG_DEFAULT_LEVEL=4
CONFIG_LOG_COLORS=y
#
# LWIP
#
# CONFIG_L2_TO_L3_COPY is not set
CONFIG_LWIP_MAX_SOCKETS=10
CONFIG_LWIP_THREAD_LOCAL_STORAGE_INDEX=0
# CONFIG_LWIP_SO_REUSE is not set
# CONFIG_LWIP_SO_RCVBUF is not set
CONFIG_LWIP_DHCP_MAX_NTP_SERVERS=1
# CONFIG_LWIP_IP_FRAG is not set
# CONFIG_LWIP_IP_REASSEMBLY is not set
#
# TCP
#
CONFIG_TCP_MAXRTX=12
CONFIG_TCP_SYNMAXRTX=6
CONFIG_TCP_MSS=1436
CONFIG_TCP_SND_BUF_DEFAULT=5744
CONFIG_TCP_WND_DEFAULT=5744
CONFIG_TCP_RECVMBOX_SIZE=6
CONFIG_TCP_QUEUE_OOSEQ=y
CONFIG_TCP_OVERSIZE_MSS=y
# CONFIG_TCP_OVERSIZE_QUARTER_MSS is not set
# CONFIG_TCP_OVERSIZE_DISABLE is not set
#
# UDP
#
CONFIG_UDP_RECVMBOX_SIZE=6
CONFIG_LWIP_DHCP_DOES_ARP_CHECK=y
CONFIG_TCPIP_TASK_STACK_SIZE=2560
# CONFIG_PPP_SUPPORT is not set
#
# ICMP
#
# CONFIG_LWIP_MULTICAST_PING is not set
# CONFIG_LWIP_BROADCAST_PING is not set
#
# mbedTLS
#
CONFIG_MBEDTLS_SSL_MAX_CONTENT_LEN=16384
# CONFIG_MBEDTLS_DEBUG is not set
CONFIG_MBEDTLS_HARDWARE_AES=y
CONFIG_MBEDTLS_HARDWARE_MPI=y
CONFIG_MBEDTLS_MPI_USE_INTERRUPT=y
CONFIG_MBEDTLS_HARDWARE_SHA=y
CONFIG_MBEDTLS_HAVE_TIME=y
# CONFIG_MBEDTLS_HAVE_TIME_DATE is not set
#
# OpenSSL
#
# CONFIG_OPENSSL_DEBUG is not set
CONFIG_OPENSSL_ASSERT_DO_NOTHING=y
# CONFIG_OPENSSL_ASSERT_EXIT is not set
#
# SPI Flash driver
#
# CONFIG_SPI_FLASH_ENABLE_COUNTERS is not set
CONFIG_SPI_FLASH_ROM_DRIVER_PATCH=y

View file

@ -0,0 +1,38 @@
import os
import wave
import struct
def get_wave_array_str(filename, target_bits):
wave_read = wave.open(filename, "r")
array_str = ""
nchannels, sampwidth, framerate, nframes, comptype, compname = wave_read.getparams()
sampwidth *= 8
for i in range(wave_read.getnframes()):
val, = struct.unpack("<H", wave_read.readframes(1))
scale_val = (1 << target_bits) - 1
cur_lim = (1 << sampwidth) - 1
#scale current data to 8-bit data
val = val * scale_val / cur_lim
val = (val + ((scale_val + 1) / 2)) & scale_val
array_str += "0x%x, "%(val)
if (i + 1) % 16 == 0:
array_str += "\n"
return array_str
def gen_wave_table(wav_file_list, target_file_name, scale_bits = 8):
with open(target_file_name, "w") as audio_table:
print >> audio_table, '#include <stdio.h>'
print >> audio_table, 'const unsigned char audio_table[] = {'
for wav in wav_file_list:
print("processing: {}".format(wav))
print >> audio_table, get_wave_array_str(filename = wav, target_bits = scale_bits)
print >>audio_table,'};\n'
print("Done...")
if __name__=='__main__':
print("Generating audio array...")
wav_list = []
for filename in os.listdir("./"):
if filename.endswith(".wav"):
wav_list.append(filename)
gen_wave_table(wav_file_list = wav_list, target_file_name = "audio_example_file.h")

Binary file not shown.

Binary file not shown.

Binary file not shown.

View file

@ -101,8 +101,8 @@ int adc1_sample_and_show(int sampling_period)
void test_task(void *arg)
{
ESP_LOGI(TAG, "Enabling ADC1 on channel 6 / GPIO34.");
adc1_config_width(ADC_WIDTH_12Bit);
adc1_config_channel_atten(ADC1_TEST_CHANNEL, ADC_ATTEN_11db);
adc1_config_width(ADC_WIDTH_BIT_12);
adc1_config_channel_atten(ADC1_TEST_CHANNEL, ADC_ATTEN_DB_11);
ESP_LOGI(TAG, "Enabling CW generator on DAC channel 1 / GPIO25.");
enable_cosine_generator();

View file

@ -63,8 +63,8 @@ static void init_ulp_program()
/* Configure ADC channel */
/* Note: when changing channel here, also change 'adc_channel' constant
in adc.S */
adc1_config_channel_atten(ADC1_CHANNEL_6, ADC_ATTEN_11db);
adc1_config_width(ADC_WIDTH_12Bit);
adc1_config_channel_atten(ADC1_CHANNEL_6, ADC_ATTEN_DB_11);
adc1_config_width(ADC_WIDTH_BIT_12);
adc1_ulp_enable();
/* Set low and high thresholds, approx. 1.35V - 1.75V*/