Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Commit d8b2098

Browse filesBrowse files
authored
Use IDF's ADC Driver and Add analogReadMilliVolts (espressif#3377)
1 parent 3fc974f commit d8b2098
Copy full SHA for d8b2098

File tree

Expand file treeCollapse file tree

2 files changed

+101
-167
lines changed
Filter options
Expand file treeCollapse file tree

2 files changed

+101
-167
lines changed

‎cores/esp32/esp32-hal-adc.c

Copy file name to clipboardExpand all lines: cores/esp32/esp32-hal-adc.c
+97-131Lines changed: 97 additions & 131 deletions
Original file line numberDiff line numberDiff line change
@@ -22,96 +22,48 @@
2222
#include "soc/rtc_cntl_reg.h"
2323
#include "soc/sens_reg.h"
2424

25+
#include "driver/adc.h"
26+
#include "esp_adc_cal.h"
27+
28+
#define DEFAULT_VREF 1100
29+
static esp_adc_cal_characteristics_t *__analogCharacteristics[2] = {NULL, NULL};
2530
static uint8_t __analogAttenuation = 3;//11db
2631
static uint8_t __analogWidth = 3;//12 bits
27-
static uint8_t __analogCycles = 8;
28-
static uint8_t __analogSamples = 0;//1 sample
2932
static uint8_t __analogClockDiv = 1;
30-
31-
// Width of returned answer ()
32-
static uint8_t __analogReturnedWidth = 12;
33+
static uint16_t __analogVRef = 0;
34+
static uint8_t __analogVRefPin = 0;
3335

3436
void __analogSetWidth(uint8_t bits){
3537
if(bits < 9){
3638
bits = 9;
3739
} else if(bits > 12){
3840
bits = 12;
3941
}
40-
__analogReturnedWidth = bits;
4142
__analogWidth = bits - 9;
42-
SET_PERI_REG_BITS(SENS_SAR_START_FORCE_REG, SENS_SAR1_BIT_WIDTH, __analogWidth, SENS_SAR1_BIT_WIDTH_S);
43-
SET_PERI_REG_BITS(SENS_SAR_READ_CTRL_REG, SENS_SAR1_SAMPLE_BIT, __analogWidth, SENS_SAR1_SAMPLE_BIT_S);
44-
45-
SET_PERI_REG_BITS(SENS_SAR_START_FORCE_REG, SENS_SAR2_BIT_WIDTH, __analogWidth, SENS_SAR2_BIT_WIDTH_S);
46-
SET_PERI_REG_BITS(SENS_SAR_READ_CTRL2_REG, SENS_SAR2_SAMPLE_BIT, __analogWidth, SENS_SAR2_SAMPLE_BIT_S);
47-
}
48-
49-
void __analogSetCycles(uint8_t cycles){
50-
__analogCycles = cycles;
51-
SET_PERI_REG_BITS(SENS_SAR_READ_CTRL_REG, SENS_SAR1_SAMPLE_CYCLE, __analogCycles, SENS_SAR1_SAMPLE_CYCLE_S);
52-
SET_PERI_REG_BITS(SENS_SAR_READ_CTRL2_REG, SENS_SAR2_SAMPLE_CYCLE, __analogCycles, SENS_SAR2_SAMPLE_CYCLE_S);
53-
}
54-
55-
void __analogSetSamples(uint8_t samples){
56-
if(!samples){
57-
return;
58-
}
59-
__analogSamples = samples - 1;
60-
SET_PERI_REG_BITS(SENS_SAR_READ_CTRL_REG, SENS_SAR1_SAMPLE_NUM, __analogSamples, SENS_SAR1_SAMPLE_NUM_S);
61-
SET_PERI_REG_BITS(SENS_SAR_READ_CTRL2_REG, SENS_SAR2_SAMPLE_NUM, __analogSamples, SENS_SAR2_SAMPLE_NUM_S);
43+
adc1_config_width(__analogWidth);
6244
}
6345

6446
void __analogSetClockDiv(uint8_t clockDiv){
6547
if(!clockDiv){
66-
return;
48+
clockDiv = 1;
6749
}
6850
__analogClockDiv = clockDiv;
69-
SET_PERI_REG_BITS(SENS_SAR_READ_CTRL_REG, SENS_SAR1_CLK_DIV, __analogClockDiv, SENS_SAR1_CLK_DIV_S);
70-
SET_PERI_REG_BITS(SENS_SAR_READ_CTRL2_REG, SENS_SAR2_CLK_DIV, __analogClockDiv, SENS_SAR2_CLK_DIV_S);
51+
adc_set_clk_div(__analogClockDiv);
7152
}
7253

7354
void __analogSetAttenuation(adc_attenuation_t attenuation)
7455
{
7556
__analogAttenuation = attenuation & 3;
76-
uint32_t att_data = 0;
77-
int i = 10;
78-
while(i--){
79-
att_data |= __analogAttenuation << (i * 2);
80-
}
81-
WRITE_PERI_REG(SENS_SAR_ATTEN1_REG, att_data & 0xFFFF);//ADC1 has 8 channels
82-
WRITE_PERI_REG(SENS_SAR_ATTEN2_REG, att_data);
8357
}
8458

85-
void IRAM_ATTR __analogInit(){
59+
void __analogInit(){
8660
static bool initialized = false;
8761
if(initialized){
8862
return;
8963
}
90-
91-
__analogSetAttenuation(__analogAttenuation);
92-
__analogSetCycles(__analogCycles);
93-
__analogSetSamples(__analogSamples + 1);//in samples
64+
initialized = true;
9465
__analogSetClockDiv(__analogClockDiv);
9566
__analogSetWidth(__analogWidth + 9);//in bits
96-
97-
SET_PERI_REG_MASK(SENS_SAR_READ_CTRL_REG, SENS_SAR1_DATA_INV);
98-
SET_PERI_REG_MASK(SENS_SAR_READ_CTRL2_REG, SENS_SAR2_DATA_INV);
99-
100-
SET_PERI_REG_MASK(SENS_SAR_MEAS_START1_REG, SENS_MEAS1_START_FORCE_M); //SAR ADC1 controller (in RTC) is started by SW
101-
SET_PERI_REG_MASK(SENS_SAR_MEAS_START1_REG, SENS_SAR1_EN_PAD_FORCE_M); //SAR ADC1 pad enable bitmap is controlled by SW
102-
SET_PERI_REG_MASK(SENS_SAR_MEAS_START2_REG, SENS_MEAS2_START_FORCE_M); //SAR ADC2 controller (in RTC) is started by SW
103-
SET_PERI_REG_MASK(SENS_SAR_MEAS_START2_REG, SENS_SAR2_EN_PAD_FORCE_M); //SAR ADC2 pad enable bitmap is controlled by SW
104-
105-
CLEAR_PERI_REG_MASK(SENS_SAR_MEAS_WAIT2_REG, SENS_FORCE_XPD_SAR_M); //force XPD_SAR=0, use XPD_FSM
106-
SET_PERI_REG_BITS(SENS_SAR_MEAS_WAIT2_REG, SENS_FORCE_XPD_AMP, 0x2, SENS_FORCE_XPD_AMP_S); //force XPD_AMP=0
107-
108-
CLEAR_PERI_REG_MASK(SENS_SAR_MEAS_CTRL_REG, 0xfff << SENS_AMP_RST_FB_FSM_S); //clear FSM
109-
SET_PERI_REG_BITS(SENS_SAR_MEAS_WAIT1_REG, SENS_SAR_AMP_WAIT1, 0x1, SENS_SAR_AMP_WAIT1_S);
110-
SET_PERI_REG_BITS(SENS_SAR_MEAS_WAIT1_REG, SENS_SAR_AMP_WAIT2, 0x1, SENS_SAR_AMP_WAIT2_S);
111-
SET_PERI_REG_BITS(SENS_SAR_MEAS_WAIT2_REG, SENS_SAR_AMP_WAIT3, 0x1, SENS_SAR_AMP_WAIT3_S);
112-
while (GET_PERI_REG_BITS2(SENS_SAR_SLAVE_ADDR1_REG, 0x7, SENS_MEAS_STATUS_S) != 0); //wait det_fsm==
113-
114-
initialized = true;
11567
}
11668

11769
void __analogSetPinAttenuation(uint8_t pin, adc_attenuation_t attenuation)
@@ -120,21 +72,20 @@ void __analogSetPinAttenuation(uint8_t pin, adc_attenuation_t attenuation)
12072
if(channel < 0 || attenuation > 3){
12173
return ;
12274
}
123-
__analogInit();
124-
if(channel > 7){
125-
SET_PERI_REG_BITS(SENS_SAR_ATTEN2_REG, 3, attenuation, ((channel - 10) * 2));
75+
if(channel > 9){
76+
adc2_config_channel_atten(channel - 10, attenuation);
12677
} else {
127-
SET_PERI_REG_BITS(SENS_SAR_ATTEN1_REG, 3, attenuation, (channel * 2));
78+
adc1_config_channel_atten(channel, attenuation);
12879
}
80+
__analogInit();
12981
}
13082

131-
bool IRAM_ATTR __adcAttachPin(uint8_t pin){
132-
83+
bool __adcAttachPin(uint8_t pin){
13384
int8_t channel = digitalPinToAnalogChannel(pin);
13485
if(channel < 0){
135-
return false;//not adc pin
86+
log_e("Pin %u is not ADC pin!", pin);
87+
return false;
13688
}
137-
13889
int8_t pad = digitalPinToTouchChannel(pin);
13990
if(pad >= 0){
14091
uint32_t touch = READ_PERI_REG(SENS_SAR_TOUCH_ENABLE_REG);
@@ -151,86 +102,103 @@ bool IRAM_ATTR __adcAttachPin(uint8_t pin){
151102
}
152103

153104
pinMode(pin, ANALOG);
154-
155-
__analogInit();
105+
__analogSetPinAttenuation(pin, __analogAttenuation);
156106
return true;
157107
}
158108

159-
bool IRAM_ATTR __adcStart(uint8_t pin){
109+
void __analogReadResolution(uint8_t bits)
110+
{
111+
if(!bits || bits > 16){
112+
return;
113+
}
114+
__analogSetWidth(bits); // hadware from 9 to 12
115+
}
160116

117+
uint16_t __analogRead(uint8_t pin)
118+
{
161119
int8_t channel = digitalPinToAnalogChannel(pin);
120+
int value = 0;
121+
esp_err_t r = ESP_OK;
162122
if(channel < 0){
163-
return false;//not adc pin
123+
log_e("Pin %u is not ADC pin!", pin);
124+
return value;
164125
}
165-
126+
__adcAttachPin(pin);
166127
if(channel > 9){
167128
channel -= 10;
168-
CLEAR_PERI_REG_MASK(SENS_SAR_MEAS_START2_REG, SENS_MEAS2_START_SAR_M);
169-
SET_PERI_REG_BITS(SENS_SAR_MEAS_START2_REG, SENS_SAR2_EN_PAD, (1 << channel), SENS_SAR2_EN_PAD_S);
170-
SET_PERI_REG_MASK(SENS_SAR_MEAS_START2_REG, SENS_MEAS2_START_SAR_M);
129+
r = adc2_get_raw( channel, __analogWidth, &value);
130+
if ( r == ESP_OK ) {
131+
return value;
132+
} else if ( r == ESP_ERR_INVALID_STATE ) {
133+
log_e("GPIO%u: %s: ADC2 not initialized yet.", pin, esp_err_to_name(r));
134+
} else if ( r == ESP_ERR_TIMEOUT ) {
135+
log_e("GPIO%u: %s: ADC2 is in use by Wi-Fi.", pin, esp_err_to_name(r));
136+
} else {
137+
log_e("GPIO%u: %s", pin, esp_err_to_name(r));
138+
}
171139
} else {
172-
CLEAR_PERI_REG_MASK(SENS_SAR_MEAS_START1_REG, SENS_MEAS1_START_SAR_M);
173-
SET_PERI_REG_BITS(SENS_SAR_MEAS_START1_REG, SENS_SAR1_EN_PAD, (1 << channel), SENS_SAR1_EN_PAD_S);
174-
SET_PERI_REG_MASK(SENS_SAR_MEAS_START1_REG, SENS_MEAS1_START_SAR_M);
140+
return adc1_get_raw(channel);
175141
}
176-
return true;
142+
return value;
177143
}
178144

179-
bool IRAM_ATTR __adcBusy(uint8_t pin){
180-
181-
int8_t channel = digitalPinToAnalogChannel(pin);
182-
if(channel < 0){
183-
return false;//not adc pin
184-
}
185-
186-
if(channel > 7){
187-
return (GET_PERI_REG_MASK(SENS_SAR_MEAS_START2_REG, SENS_MEAS2_DONE_SAR) == 0);
145+
void __analogSetVRefPin(uint8_t pin){
146+
if(pin <25 || pin > 27){
147+
pin = 0;
188148
}
189-
return (GET_PERI_REG_MASK(SENS_SAR_MEAS_START1_REG, SENS_MEAS1_DONE_SAR) == 0);
149+
__analogVRefPin = pin;
190150
}
191151

192-
uint16_t IRAM_ATTR __adcEnd(uint8_t pin)
193-
{
194-
195-
uint16_t value = 0;
152+
uint32_t __analogReadMilliVolts(uint8_t pin){
196153
int8_t channel = digitalPinToAnalogChannel(pin);
197154
if(channel < 0){
198-
return 0;//not adc pin
199-
}
200-
if(channel > 7){
201-
while (GET_PERI_REG_MASK(SENS_SAR_MEAS_START2_REG, SENS_MEAS2_DONE_SAR) == 0); //wait for conversion
202-
value = GET_PERI_REG_BITS2(SENS_SAR_MEAS_START2_REG, SENS_MEAS2_DATA_SAR, SENS_MEAS2_DATA_SAR_S);
203-
} else {
204-
while (GET_PERI_REG_MASK(SENS_SAR_MEAS_START1_REG, SENS_MEAS1_DONE_SAR) == 0); //wait for conversion
205-
value = GET_PERI_REG_BITS2(SENS_SAR_MEAS_START1_REG, SENS_MEAS1_DATA_SAR, SENS_MEAS1_DATA_SAR_S);
206-
}
207-
208-
// Shift result if necessary
209-
uint8_t from = __analogWidth + 9;
210-
if (from == __analogReturnedWidth) {
211-
return value;
155+
log_e("Pin %u is not ADC pin!", pin);
156+
return 0;
212157
}
213-
if (from > __analogReturnedWidth) {
214-
return value >> (from - __analogReturnedWidth);
158+
if(!__analogVRef){
159+
if (esp_adc_cal_check_efuse(ESP_ADC_CAL_VAL_EFUSE_TP) == ESP_OK) {
160+
log_d("eFuse Two Point: Supported");
161+
__analogVRef = DEFAULT_VREF;
162+
}
163+
if (esp_adc_cal_check_efuse(ESP_ADC_CAL_VAL_EFUSE_VREF) == ESP_OK) {
164+
log_d("eFuse Vref: Supported");
165+
__analogVRef = DEFAULT_VREF;
166+
}
167+
if(!__analogVRef){
168+
__analogVRef = DEFAULT_VREF;
169+
if(__analogVRefPin){
170+
esp_adc_cal_characteristics_t chars;
171+
if(adc2_vref_to_gpio(__analogVRefPin) == ESP_OK){
172+
__analogVRef = __analogRead(__analogVRefPin);
173+
esp_adc_cal_characterize(1, __analogAttenuation, __analogWidth, DEFAULT_VREF, &chars);
174+
__analogVRef = esp_adc_cal_raw_to_voltage(__analogVRef, &chars);
175+
log_d("Vref to GPIO%u: %u", __analogVRefPin, __analogVRef);
176+
}
177+
}
178+
}
215179
}
216-
return value << (__analogReturnedWidth - from);
217-
}
218-
219-
uint16_t IRAM_ATTR __analogRead(uint8_t pin)
220-
{
221-
if(!__adcAttachPin(pin) || !__adcStart(pin)){
222-
return 0;
180+
uint8_t unit = 1;
181+
if(channel > 9){
182+
unit = 2;
223183
}
224-
return __adcEnd(pin);
225-
}
226-
227-
void __analogReadResolution(uint8_t bits)
228-
{
229-
if(!bits || bits > 16){
230-
return;
184+
uint16_t adc_reading = __analogRead(pin);
185+
if(__analogCharacteristics[unit - 1] == NULL){
186+
__analogCharacteristics[unit - 1] = calloc(1, sizeof(esp_adc_cal_characteristics_t));
187+
if(__analogCharacteristics[unit - 1] == NULL){
188+
return 0;
189+
}
190+
esp_adc_cal_value_t val_type = esp_adc_cal_characterize(unit, __analogAttenuation, __analogWidth, __analogVRef, __analogCharacteristics[unit - 1]);
191+
if (val_type == ESP_ADC_CAL_VAL_EFUSE_TP) {
192+
log_i("ADC%u: Characterized using Two Point Value: %u\n", unit, __analogCharacteristics[unit - 1]->vref);
193+
} else if (val_type == ESP_ADC_CAL_VAL_EFUSE_VREF) {
194+
log_i("ADC%u: Characterized using eFuse Vref: %u\n", unit, __analogCharacteristics[unit - 1]->vref);
195+
} else if(__analogVRef != DEFAULT_VREF){
196+
log_i("ADC%u: Characterized using Vref to GPIO%u: %u\n", unit, __analogVRefPin, __analogCharacteristics[unit - 1]->vref);
197+
} else {
198+
log_i("ADC%u: Characterized using Default Vref: %u\n", unit, __analogCharacteristics[unit - 1]->vref);
199+
}
231200
}
232-
__analogSetWidth(bits); // hadware from 9 to 12
233-
__analogReturnedWidth = bits; // software from 1 to 16
201+
return esp_adc_cal_raw_to_voltage(adc_reading, __analogCharacteristics[unit - 1]);
234202
}
235203

236204
int __hallRead() //hall sensor without LNA
@@ -260,14 +228,12 @@ int __hallRead() //hall sensor without LNA
260228
extern uint16_t analogRead(uint8_t pin) __attribute__ ((weak, alias("__analogRead")));
261229
extern void analogReadResolution(uint8_t bits) __attribute__ ((weak, alias("__analogReadResolution")));
262230
extern void analogSetWidth(uint8_t bits) __attribute__ ((weak, alias("__analogSetWidth")));
263-
extern void analogSetCycles(uint8_t cycles) __attribute__ ((weak, alias("__analogSetCycles")));
264-
extern void analogSetSamples(uint8_t samples) __attribute__ ((weak, alias("__analogSetSamples")));
265231
extern void analogSetClockDiv(uint8_t clockDiv) __attribute__ ((weak, alias("__analogSetClockDiv")));
266232
extern void analogSetAttenuation(adc_attenuation_t attenuation) __attribute__ ((weak, alias("__analogSetAttenuation")));
267233
extern void analogSetPinAttenuation(uint8_t pin, adc_attenuation_t attenuation) __attribute__ ((weak, alias("__analogSetPinAttenuation")));
268234
extern int hallRead() __attribute__ ((weak, alias("__hallRead")));
269235

270236
extern bool adcAttachPin(uint8_t pin) __attribute__ ((weak, alias("__adcAttachPin")));
271-
extern bool adcStart(uint8_t pin) __attribute__ ((weak, alias("__adcStart")));
272-
extern bool adcBusy(uint8_t pin) __attribute__ ((weak, alias("__adcBusy")));
273-
extern uint16_t adcEnd(uint8_t pin) __attribute__ ((weak, alias("__adcEnd")));
237+
238+
extern void analogSetVRefPin(uint8_t pin) __attribute__ ((weak, alias("__analogSetVRefPin")));
239+
extern uint32_t analogReadMilliVolts(uint8_t pin) __attribute__ ((weak, alias("__analogReadMilliVolts")));

‎cores/esp32/esp32-hal-adc.h

Copy file name to clipboardExpand all lines: cores/esp32/esp32-hal-adc.h
+4-36Lines changed: 4 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -54,24 +54,6 @@ void analogReadResolution(uint8_t bits);
5454
* */
5555
void analogSetWidth(uint8_t bits);
5656

57-
/*
58-
* Set number of cycles per sample
59-
* Default is 8 and seems to do well
60-
* Range is 1 - 255
61-
* */
62-
void analogSetCycles(uint8_t cycles);
63-
64-
/*
65-
* Set number of samples in the range.
66-
* Default is 1
67-
* Range is 1 - 255
68-
* This setting splits the range into
69-
* "samples" pieces, which could look
70-
* like the sensitivity has been multiplied
71-
* that many times
72-
* */
73-
void analogSetSamples(uint8_t samples);
74-
7557
/*
7658
* Set the divider for the ADC clock.
7759
* Default is 1
@@ -97,34 +79,20 @@ void analogSetPinAttenuation(uint8_t pin, adc_attenuation_t attenuation);
9779
* */
9880
int hallRead();
9981

100-
/*
101-
* Non-Blocking API (almost)
102-
*
103-
* Note: ADC conversion can run only for single pin at a time.
104-
* That means that if you want to run ADC on two pins on the same bus,
105-
* you need to run them one after another. Probably the best use would be
106-
* to start conversion on both buses in parallel.
107-
* */
108-
10982
/*
11083
* Attach pin to ADC (will also clear any other analog mode that could be on)
11184
* */
11285
bool adcAttachPin(uint8_t pin);
11386

11487
/*
115-
* Start ADC conversion on attached pin's bus
116-
* */
117-
bool adcStart(uint8_t pin);
118-
119-
/*
120-
* Check if conversion on the pin's ADC bus is currently running
88+
* Set pin to use for ADC calibration if the esp is not already calibrated (25, 26 or 27)
12189
* */
122-
bool adcBusy(uint8_t pin);
90+
void analogSetVRefPin(uint8_t pin);
12391

12492
/*
125-
* Get the result of the conversion (will wait if it have not finished)
93+
* Get MilliVolts value for pin
12694
* */
127-
uint16_t adcEnd(uint8_t pin);
95+
uint32_t analogReadMilliVolts(uint8_t pin);
12896

12997
#ifdef __cplusplus
13098
}

0 commit comments

Comments
0 (0)
Morty Proxy This is a proxified and sanitized view of the page, visit original site.