Skip to content

Commit b6f37bd

Browse files
committed
Merge branch 'feature/i2s_built_in_adc' into 'master'
feature(I2S-ADC): add ADC mode for I2S. See merge request !1077
2 parents 477ed8c + 2fceec4 commit b6f37bd

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
@@ -418,7 +418,7 @@ esp_err_t i2s_set_clk(i2s_port_t i2s_num, uint32_t rate, i2s_bits_per_sample_t b
418418
}
419419

420420
double mclk;
421-
if (p_i2s_obj[i2s_num]->mode & I2S_MODE_DAC_BUILT_IN) {
421+
if (p_i2s_obj[i2s_num]->mode & (I2S_MODE_DAC_BUILT_IN | I2S_MODE_ADC_BUILT_IN)) {
422422
//DAC uses bclk as sample clock, not WS. WS can be something arbitrary.
423423
//Rate as given to this function is the intended sample rate;
424424
//According to the TRM, WS clk equals to the sample rate, and bclk is double the speed of WS
@@ -708,6 +708,13 @@ esp_err_t i2s_set_dac_mode(i2s_dac_mode_t dac_mode)
708708
return ESP_OK;
709709
}
710710

711+
esp_err_t i2s_set_adc_mode(adc_unit_t adc_unit, adc1_channel_t adc_channel)
712+
{
713+
I2S_CHECK((adc_unit < ADC_UNIT_2), "i2s ADC unit error, only support ADC1 for now", ESP_ERR_INVALID_ARG);
714+
// For now, we only support SAR ADC1.
715+
return adc_i2s_mode_init(adc_unit, adc_channel);
716+
}
717+
711718
esp_err_t i2s_set_pin(i2s_port_t i2s_num, const i2s_pin_config_t *pin)
712719
{
713720
I2S_CHECK((i2s_num < I2S_NUM_MAX), "i2s_num error", ESP_ERR_INVALID_ARG);
@@ -823,34 +830,42 @@ esp_err_t i2s_set_sample_rates(i2s_port_t i2s_num, uint32_t rate)
823830
I2S_CHECK((p_i2s_obj[i2s_num]->bytes_per_sample > 0), "bits_per_sample not set", ESP_ERR_INVALID_ARG);
824831
return i2s_set_clk(i2s_num, rate, p_i2s_obj[i2s_num]->bits_per_sample, p_i2s_obj[i2s_num]->channel_num);
825832
}
833+
826834
static esp_err_t i2s_param_config(i2s_port_t i2s_num, const i2s_config_t *i2s_config)
827835
{
828836
I2S_CHECK((i2s_num < I2S_NUM_MAX), "i2s_num error", ESP_ERR_INVALID_ARG);
829837
I2S_CHECK((i2s_config), "param null", ESP_ERR_INVALID_ARG);
838+
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);
839+
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);
840+
I2S_CHECK(!((i2s_config->mode & I2S_MODE_PDM) && (i2s_num != I2S_NUM_0)), "I2S DAC PDM only support on I2S0", ESP_ERR_INVALID_ARG);
830841

831842
if (i2s_num == I2S_NUM_1) {
832843
periph_module_enable(PERIPH_I2S1_MODULE);
833844
} else {
834845
periph_module_enable(PERIPH_I2S0_MODULE);
835846
}
836847

848+
if(i2s_config->mode & I2S_MODE_ADC_BUILT_IN) {
849+
//in ADC built-in mode, we need to call i2s_set_adc_mode to
850+
//initialize the specific ADC channel.
851+
//in the current stage, we only support ADC1 and single channel mode.
852+
//In default data mode, the ADC data is in 12-bit resolution mode.
853+
adc_power_on();
854+
}
837855
// configure I2S data port interface.
838856
i2s_reset_fifo(i2s_num);
839-
840857
//reset i2s
841858
I2S[i2s_num]->conf.tx_reset = 1;
842859
I2S[i2s_num]->conf.tx_reset = 0;
843860
I2S[i2s_num]->conf.rx_reset = 1;
844861
I2S[i2s_num]->conf.rx_reset = 0;
845862

846-
847863
//reset dma
848864
I2S[i2s_num]->lc_conf.in_rst = 1;
849865
I2S[i2s_num]->lc_conf.in_rst = 0;
850866
I2S[i2s_num]->lc_conf.out_rst = 1;
851867
I2S[i2s_num]->lc_conf.out_rst = 0;
852868

853-
854869
//Enable and configure DMA
855870
I2S[i2s_num]->lc_conf.check_owner = 0;
856871
I2S[i2s_num]->lc_conf.out_loop_test = 0;
@@ -861,7 +876,6 @@ static esp_err_t i2s_param_config(i2s_port_t i2s_num, const i2s_config_t *i2s_co
861876
I2S[i2s_num]->lc_conf.indscr_burst_en = 0;
862877
I2S[i2s_num]->lc_conf.out_eof_mode = 1;
863878

864-
865879
I2S[i2s_num]->conf2.lcd_en = 0;
866880
I2S[i2s_num]->conf2.camera_en = 0;
867881
I2S[i2s_num]->pdm_conf.pcm2pdm_conv_en = 0;
@@ -905,9 +919,10 @@ static esp_err_t i2s_param_config(i2s_port_t i2s_num, const i2s_config_t *i2s_co
905919
}
906920
}
907921

908-
if (i2s_config->mode & I2S_MODE_DAC_BUILT_IN) {
922+
if (i2s_config->mode & (I2S_MODE_DAC_BUILT_IN | I2S_MODE_ADC_BUILT_IN)) {
909923
I2S[i2s_num]->conf2.lcd_en = 1;
910924
I2S[i2s_num]->conf.tx_right_first = 1;
925+
I2S[i2s_num]->conf2.camera_en = 0;
911926
}
912927

913928
if (i2s_config->mode & I2S_MODE_PDM) {
@@ -1029,7 +1044,12 @@ esp_err_t i2s_driver_install(i2s_port_t i2s_num, const i2s_config_t *i2s_config,
10291044
return err;
10301045
}
10311046
i2s_stop(i2s_num);
1032-
i2s_param_config(i2s_num, i2s_config);
1047+
err = i2s_param_config(i2s_num, i2s_config);
1048+
if (err != ESP_OK) {
1049+
i2s_driver_uninstall(i2s_num);
1050+
ESP_LOGE(I2S_TAG, "I2S param configure error");
1051+
return err;
1052+
}
10331053

10341054
if (i2s_queue) {
10351055
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

@@ -405,6 +406,17 @@ esp_err_t i2s_zero_dma_buffer(i2s_port_t i2s_num);
405406
*/
406407
esp_err_t i2s_set_clk(i2s_port_t i2s_num, uint32_t rate, i2s_bits_per_sample_t bits, i2s_channel_t ch);
407408

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

0 commit comments

Comments
 (0)