Skip to content

Commit 2fceec4

Browse files
committed
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
1 parent b2adaf2 commit 2fceec4

File tree

24 files changed

+6238
-158
lines changed

24 files changed

+6238
-158
lines changed

components/driver/i2s.c

Lines changed: 27 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -278,7 +278,7 @@ esp_err_t i2s_set_clk(i2s_port_t i2s_num, uint32_t rate, i2s_bits_per_sample_t b
278278
}
279279

280280
double mclk;
281-
if (p_i2s_obj[i2s_num]->mode & I2S_MODE_DAC_BUILT_IN) {
281+
if (p_i2s_obj[i2s_num]->mode & (I2S_MODE_DAC_BUILT_IN | I2S_MODE_ADC_BUILT_IN)) {
282282
//DAC uses bclk as sample clock, not WS. WS can be something arbitrary.
283283
//Rate as given to this function is the intended sample rate;
284284
//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)
554554
return ESP_OK;
555555
}
556556

557+
esp_err_t i2s_set_adc_mode(adc_unit_t adc_unit, adc1_channel_t adc_channel)
558+
{
559+
I2S_CHECK((adc_unit < ADC_UNIT_2), "i2s ADC unit error, only support ADC1 for now", ESP_ERR_INVALID_ARG);
560+
// For now, we only support SAR ADC1.
561+
return adc_i2s_mode_init(adc_unit, adc_channel);
562+
}
563+
557564
esp_err_t i2s_set_pin(i2s_port_t i2s_num, const i2s_pin_config_t *pin)
558565
{
559566
I2S_CHECK((i2s_num < I2S_NUM_MAX), "i2s_num error", ESP_ERR_INVALID_ARG);
@@ -669,34 +676,42 @@ esp_err_t i2s_set_sample_rates(i2s_port_t i2s_num, uint32_t rate)
669676
I2S_CHECK((p_i2s_obj[i2s_num]->bytes_per_sample > 0), "bits_per_sample not set", ESP_ERR_INVALID_ARG);
670677
return i2s_set_clk(i2s_num, rate, p_i2s_obj[i2s_num]->bits_per_sample, p_i2s_obj[i2s_num]->channel_num);
671678
}
679+
672680
static esp_err_t i2s_param_config(i2s_port_t i2s_num, const i2s_config_t *i2s_config)
673681
{
674682
I2S_CHECK((i2s_num < I2S_NUM_MAX), "i2s_num error", ESP_ERR_INVALID_ARG);
675683
I2S_CHECK((i2s_config), "param null", ESP_ERR_INVALID_ARG);
684+
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);
685+
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);
686+
I2S_CHECK(!((i2s_config->mode & I2S_MODE_PDM) && (i2s_num != I2S_NUM_0)), "I2S DAC PDM only support on I2S0", ESP_ERR_INVALID_ARG);
676687

677688
if (i2s_num == I2S_NUM_1) {
678689
periph_module_enable(PERIPH_I2S1_MODULE);
679690
} else {
680691
periph_module_enable(PERIPH_I2S0_MODULE);
681692
}
682693

694+
if(i2s_config->mode & I2S_MODE_ADC_BUILT_IN) {
695+
//in ADC built-in mode, we need to call i2s_set_adc_mode to
696+
//initialize the specific ADC channel.
697+
//in the current stage, we only support ADC1 and single channel mode.
698+
//In default data mode, the ADC data is in 12-bit resolution mode.
699+
adc_power_on();
700+
}
683701
// configure I2S data port interface.
684702
i2s_reset_fifo(i2s_num);
685-
686703
//reset i2s
687704
I2S[i2s_num]->conf.tx_reset = 1;
688705
I2S[i2s_num]->conf.tx_reset = 0;
689706
I2S[i2s_num]->conf.rx_reset = 1;
690707
I2S[i2s_num]->conf.rx_reset = 0;
691708

692-
693709
//reset dma
694710
I2S[i2s_num]->lc_conf.in_rst = 1;
695711
I2S[i2s_num]->lc_conf.in_rst = 0;
696712
I2S[i2s_num]->lc_conf.out_rst = 1;
697713
I2S[i2s_num]->lc_conf.out_rst = 0;
698714

699-
700715
//Enable and configure DMA
701716
I2S[i2s_num]->lc_conf.check_owner = 0;
702717
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
707722
I2S[i2s_num]->lc_conf.indscr_burst_en = 0;
708723
I2S[i2s_num]->lc_conf.out_eof_mode = 1;
709724

710-
711725
I2S[i2s_num]->conf2.lcd_en = 0;
712726
I2S[i2s_num]->conf2.camera_en = 0;
713727
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
751765
}
752766
}
753767

754-
if (i2s_config->mode & I2S_MODE_DAC_BUILT_IN) {
768+
if (i2s_config->mode & (I2S_MODE_DAC_BUILT_IN | I2S_MODE_ADC_BUILT_IN)) {
755769
I2S[i2s_num]->conf2.lcd_en = 1;
756770
I2S[i2s_num]->conf.tx_right_first = 1;
771+
I2S[i2s_num]->conf2.camera_en = 0;
757772
}
758773

759774
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,
873888
return err;
874889
}
875890
i2s_stop(i2s_num);
876-
i2s_param_config(i2s_num, i2s_config);
891+
err = i2s_param_config(i2s_num, i2s_config);
892+
if (err != ESP_OK) {
893+
i2s_driver_uninstall(i2s_num);
894+
ESP_LOGE(I2S_TAG, "I2S param configure error");
895+
return err;
896+
}
877897

878898
if (i2s_queue) {
879899
p_i2s_obj[i2s_num]->i2s_queue = xQueueCreate(queue_size, sizeof(i2s_event_t));

components/driver/include/driver/adc.h

Lines changed: 127 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -20,24 +20,38 @@ extern "C" {
2020
#endif
2121

2222
#include <stdint.h>
23+
#include <stdbool.h>
2324
#include "esp_err.h"
2425
#include "driver/gpio.h"
2526
#include "soc/adc_channel.h"
2627

2728
typedef enum {
28-
ADC_ATTEN_0db = 0, /*!<The input voltage of ADC will be reduced to about 1/1 */
29-
ADC_ATTEN_2_5db = 1, /*!<The input voltage of ADC will be reduced to about 1/1.34 */
30-
ADC_ATTEN_6db = 2, /*!<The input voltage of ADC will be reduced to about 1/2 */
31-
ADC_ATTEN_11db = 3, /*!<The input voltage of ADC will be reduced to about 1/3.6*/
29+
ADC_ATTEN_DB_0 = 0, /*!<The input voltage of ADC will be reduced to about 1/1 */
30+
ADC_ATTEN_DB_2_5 = 1, /*!<The input voltage of ADC will be reduced to about 1/1.34 */
31+
ADC_ATTEN_DB_6 = 2, /*!<The input voltage of ADC will be reduced to about 1/2 */
32+
ADC_ATTEN_DB_11 = 3, /*!<The input voltage of ADC will be reduced to about 1/3.6*/
33+
ADC_ATTEN_MAX,
3234
} adc_atten_t;
3335

3436
typedef enum {
35-
ADC_WIDTH_9Bit = 0, /*!< ADC capture width is 9Bit*/
36-
ADC_WIDTH_10Bit = 1, /*!< ADC capture width is 10Bit*/
37-
ADC_WIDTH_11Bit = 2, /*!< ADC capture width is 11Bit*/
38-
ADC_WIDTH_12Bit = 3, /*!< ADC capture width is 12Bit*/
37+
ADC_WIDTH_BIT_9 = 0, /*!< ADC capture width is 9Bit*/
38+
ADC_WIDTH_BIT_10 = 1, /*!< ADC capture width is 10Bit*/
39+
ADC_WIDTH_BIT_11 = 2, /*!< ADC capture width is 11Bit*/
40+
ADC_WIDTH_BIT_12 = 3, /*!< ADC capture width is 12Bit*/
41+
ADC_WIDTH_MAX,
3942
} adc_bits_width_t;
4043

44+
//this definitions are only for being back-compatible
45+
#define ADC_ATTEN_0db ADC_ATTEN_DB_0
46+
#define ADC_ATTEN_2_5db ADC_ATTEN_DB_2_5
47+
#define ADC_ATTEN_6db ADC_ATTEN_DB_6
48+
#define ADC_ATTEN_11db ADC_ATTEN_DB_11
49+
//this definitions are only for being back-compatible
50+
#define ADC_WIDTH_9Bit ADC_WIDTH_BIT_9
51+
#define ADC_WIDTH_10Bit ADC_WIDTH_BIT_10
52+
#define ADC_WIDTH_11Bit ADC_WIDTH_BIT_11
53+
#define ADC_WIDTH_12Bit ADC_WIDTH_BIT_12
54+
4155
typedef enum {
4256
ADC1_CHANNEL_0 = 0, /*!< ADC1 channel 0 is GPIO36 */
4357
ADC1_CHANNEL_1, /*!< ADC1 channel 1 is GPIO37 */
@@ -64,11 +78,43 @@ typedef enum {
6478
ADC2_CHANNEL_MAX,
6579
} adc2_channel_t;
6680

81+
typedef enum {
82+
ADC_CHANNEL_0 = 0, /*!< ADC channel */
83+
ADC_CHANNEL_1, /*!< ADC channel */
84+
ADC_CHANNEL_2, /*!< ADC channel */
85+
ADC_CHANNEL_3, /*!< ADC channel */
86+
ADC_CHANNEL_4, /*!< ADC channel */
87+
ADC_CHANNEL_5, /*!< ADC channel */
88+
ADC_CHANNEL_6, /*!< ADC channel */
89+
ADC_CHANNEL_7, /*!< ADC channel */
90+
ADC_CHANNEL_8, /*!< ADC channel */
91+
ADC_CHANNEL_9, /*!< ADC channel */
92+
ADC_CHANNEL_MAX,
93+
} adc_channel_t;
94+
95+
typedef enum {
96+
ADC_UNIT_1 = 1, /*!< SAR ADC 1*/
97+
ADC_UNIT_2 = 2, /*!< SAR ADC 2, not supported yet*/
98+
ADC_UNIT_BOTH = 3, /*!< SAR ADC 1 and 2, not supported yet */
99+
ADC_UNIT_ALTER = 7, /*!< SAR ADC 1 and 2 alternative mode, not supported yet */
100+
ADC_UNIT_MAX,
101+
} adc_unit_t;
102+
103+
typedef enum {
104+
ADC_ENCODE_12BIT, /*!< ADC to I2S data format, [15:12]-channel [11:0]-12 bits ADC data */
105+
ADC_ENCODE_11BIT, /*!< ADC to I2S data format, [15]-1 [14:11]-channel [10:0]-11 bits ADC data */
106+
ADC_ENCODE_MAX,
107+
} adc_i2s_encode_t;
108+
109+
typedef enum {
110+
ADC_I2S_DATA_SRC_IO_SIG = 0, /*!< I2S data from GPIO matrix signal */
111+
ADC_I2S_DATA_SRC_ADC = 1, /*!< I2S data from ADC */
112+
ADC_I2S_DATA_SRC_MAX,
113+
} adc_i2s_source_t;
114+
67115
/**
68-
* @brief Configure ADC1 capture width.
69-
*
116+
* @brief Configure ADC1 capture width, meanwhile enable output invert for ADC1.
70117
* The configuration is for all channels of ADC1
71-
*
72118
* @param width_bit Bit capture width for ADC1
73119
*
74120
* @return
@@ -77,6 +123,16 @@ typedef enum {
77123
*/
78124
esp_err_t adc1_config_width(adc_bits_width_t width_bit);
79125

126+
/**
127+
* @brief Configure ADC capture width.
128+
* @param adc_unit ADC unit index
129+
* @param width_bit Bit capture width for ADC unit.
130+
* @return
131+
* - ESP_OK success
132+
* - ESP_ERR_INVALID_ARG Parameter error
133+
*/
134+
esp_err_t adc_set_data_width(adc_unit_t adc_unit, adc_bits_width_t width_bit);
135+
80136
/**
81137
* @brief Configure the ADC1 channel, including setting attenuation.
82138
*
@@ -89,10 +145,10 @@ esp_err_t adc1_config_width(adc_bits_width_t width_bit);
89145
*
90146
* When VDD_A is 3.3V:
91147
*
92-
* - 0dB attenuaton (ADC_ATTEN_0db) gives full-scale voltage 1.1V
93-
* - 2.5dB attenuation (ADC_ATTEN_2_5db) gives full-scale voltage 1.5V
94-
* - 6dB attenuation (ADC_ATTEN_6db) gives full-scale voltage 2.2V
95-
* - 11dB attenuation (ADC_ATTEN_11db) gives full-scale voltage 3.9V (see note below)
148+
* - 0dB attenuaton (ADC_ATTEN_DB_0) gives full-scale voltage 1.1V
149+
* - 2.5dB attenuation (ADC_ATTEN_DB_2_5) gives full-scale voltage 1.5V
150+
* - 6dB attenuation (ADC_ATTEN_DB_6) gives full-scale voltage 2.2V
151+
* - 11dB attenuation (ADC_ATTEN_DB_11) gives full-scale voltage 3.9V (see note below)
96152
*
97153
* @note The full-scale voltage is the voltage corresponding to a maximum reading (depending on ADC1 configured
98154
* 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);
134190
int adc1_get_voltage(adc1_channel_t channel) __attribute__((deprecated));
135191
/** @endcond */
136192

193+
/**
194+
* @brief Power on SAR ADC
195+
*/
196+
void adc_power_on();
197+
198+
/**
199+
* @brief Power off SAR ADC
200+
*/
201+
void adc_power_off();
202+
203+
/**
204+
* @brief Initialize ADC pad
205+
* @param adc_unit ADC unit index
206+
* @param channel ADC channel index
207+
* @return
208+
* - ESP_OK success
209+
* - ESP_ERR_INVALID_ARG Parameter error
210+
*/
211+
esp_err_t adc_gpio_init(adc_unit_t adc_unit, adc_channel_t channel);
212+
213+
/**
214+
* @brief Set ADC data invert
215+
* @param adc_unit ADC unit index
216+
* @param inv_en whether enable data invert
217+
* @return
218+
* - ESP_OK success
219+
* - ESP_ERR_INVALID_ARG Parameter error
220+
*/
221+
esp_err_t adc_set_data_inv(adc_unit_t adc_unit, bool inv_en);
222+
223+
/**
224+
* @brief Set ADC source clock
225+
* @param clk_div ADC clock divider, ADC clock is divided from APB clock
226+
* @return
227+
* - ESP_OK success
228+
*/
229+
esp_err_t adc_set_clk_div(uint8_t clk_div);
230+
231+
/**
232+
* @brief Set I2S data source
233+
* @param src I2S DMA data source, I2S DMA can get data from digital signals or from ADC.
234+
* @return
235+
* - ESP_OK success
236+
*/
237+
esp_err_t adc_set_i2s_data_source(adc_i2s_source_t src);
238+
239+
/**
240+
* @brief Initialize I2S ADC mode
241+
* @param adc_unit ADC unit index
242+
* @param channel ADC channel index
243+
* @return
244+
* - ESP_OK success
245+
* - ESP_ERR_INVALID_ARG Parameter error
246+
*/
247+
esp_err_t adc_i2s_mode_init(adc_unit_t adc_unit, adc_channel_t channel);
248+
137249
/**
138250
* @brief Configure ADC1 to be usable by the ULP
139251
*

components/driver/include/driver/i2s.h

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626
#include "esp_attr.h"
2727
#include "esp_intr_alloc.h"
2828
#include "driver/periph_ctrl.h"
29+
#include "driver/adc.h"
2930
#include "freertos/semphr.h"
3031

3132
#ifdef __cplusplus
@@ -118,7 +119,7 @@ typedef enum {
118119
I2S_MODE_TX = 4,
119120
I2S_MODE_RX = 8,
120121
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*/
121-
//I2S_MODE_ADC_BUILT_IN = 32, /*!< Currently not supported yet, will be added for the next version*/
122+
I2S_MODE_ADC_BUILT_IN = 32, /*!< Input I2S data from built-in ADC, each data can be 12-bit width at most*/
122123
I2S_MODE_PDM = 64,
123124
} i2s_mode_t;
124125

@@ -402,6 +403,17 @@ esp_err_t i2s_zero_dma_buffer(i2s_port_t i2s_num);
402403
*/
403404
esp_err_t i2s_set_clk(i2s_port_t i2s_num, uint32_t rate, i2s_bits_per_sample_t bits, i2s_channel_t ch);
404405

406+
/**
407+
* @brief Set built-in ADC mode for I2S DMA, this function will initialize ADC pad,
408+
* and set ADC parameters.
409+
* @param adc_unit SAR ADC unit index
410+
* @param adc_channel ADC channel index
411+
* @return
412+
* - ESP_OK Success
413+
* - ESP_FAIL Parameter error
414+
*/
415+
esp_err_t i2s_set_adc_mode(adc_unit_t adc_unit, adc1_channel_t adc_channel);
416+
405417
#ifdef __cplusplus
406418
}
407419
#endif

0 commit comments

Comments
 (0)