Skip to content

Commit 0b367c3

Browse files
committed
refactured esp32 fast adc driver - simplified a lot
1 parent e92567e commit 0b367c3

File tree

4 files changed

+139
-533
lines changed

4 files changed

+139
-533
lines changed
Lines changed: 98 additions & 187 deletions
Original file line numberDiff line numberDiff line change
@@ -1,89 +1,20 @@
11
#include "esp32_adc_driver.h"
22

3-
#if defined(ESP_H) && defined(ARDUINO_ARCH_ESP32) && defined(SOC_MCPWM_SUPPORTED) && !defined(CONFIG_IDF_TARGET_ESP32S2) && !defined(CONFIG_IDF_TARGET_ESP32S3) && !defined(SIMPLEFOC_ESP32_USELEDC)
4-
5-
#include "freertos/FreeRTOS.h"
6-
#include "freertos/task.h"
7-
#include "rom/ets_sys.h"
8-
#include "esp_attr.h"
9-
//#include "esp_intr.h" deprecated
10-
#include "esp_intr_alloc.h"
11-
#include "soc/rtc_io_reg.h"
12-
#include "soc/rtc_cntl_reg.h"
13-
#include "soc/sens_reg.h"
14-
15-
static uint8_t __analogAttenuation = 3;//11db
16-
static uint8_t __analogWidth = 3;//12 bits
17-
static uint8_t __analogCycles = 8;
18-
static uint8_t __analogSamples = 0;//1 sample
19-
static uint8_t __analogClockDiv = 1;
20-
21-
// Width of returned answer ()
22-
static uint8_t __analogReturnedWidth = 12;
23-
24-
void __analogSetWidth(uint8_t bits){
25-
if(bits < 9){
26-
bits = 9;
27-
} else if(bits > 12){
28-
bits = 12;
29-
}
30-
__analogReturnedWidth = bits;
31-
__analogWidth = bits - 9;
32-
SET_PERI_REG_BITS(SENS_SAR_START_FORCE_REG, SENS_SAR1_BIT_WIDTH, __analogWidth, SENS_SAR1_BIT_WIDTH_S);
33-
SET_PERI_REG_BITS(SENS_SAR_READ_CTRL_REG, SENS_SAR1_SAMPLE_BIT, __analogWidth, SENS_SAR1_SAMPLE_BIT_S);
34-
35-
SET_PERI_REG_BITS(SENS_SAR_START_FORCE_REG, SENS_SAR2_BIT_WIDTH, __analogWidth, SENS_SAR2_BIT_WIDTH_S);
36-
SET_PERI_REG_BITS(SENS_SAR_READ_CTRL2_REG, SENS_SAR2_SAMPLE_BIT, __analogWidth, SENS_SAR2_SAMPLE_BIT_S);
37-
}
383

39-
void __analogSetCycles(uint8_t cycles){
40-
__analogCycles = cycles;
41-
SET_PERI_REG_BITS(SENS_SAR_READ_CTRL_REG, SENS_SAR1_SAMPLE_CYCLE, __analogCycles, SENS_SAR1_SAMPLE_CYCLE_S);
42-
SET_PERI_REG_BITS(SENS_SAR_READ_CTRL2_REG, SENS_SAR2_SAMPLE_CYCLE, __analogCycles, SENS_SAR2_SAMPLE_CYCLE_S);
43-
}
4+
// maybe go to the fast ADC in future even outside the MCPWM (we'd have to remove the SOC_MCPWM_SUPPORTED flag)
5+
#if defined(ESP_H) && defined(ARDUINO_ARCH_ESP32) && defined(SOC_MCPWM_SUPPORTED) && !defined(SIMPLEFOC_ESP32_USELEDC)
446

45-
void __analogSetSamples(uint8_t samples){
46-
if(!samples){
47-
return;
48-
}
49-
__analogSamples = samples - 1;
50-
SET_PERI_REG_BITS(SENS_SAR_READ_CTRL_REG, SENS_SAR1_SAMPLE_NUM, __analogSamples, SENS_SAR1_SAMPLE_NUM_S);
51-
SET_PERI_REG_BITS(SENS_SAR_READ_CTRL2_REG, SENS_SAR2_SAMPLE_NUM, __analogSamples, SENS_SAR2_SAMPLE_NUM_S);
52-
}
537

54-
void __analogSetClockDiv(uint8_t clockDiv){
55-
if(!clockDiv){
56-
return;
57-
}
58-
__analogClockDiv = clockDiv;
59-
SET_PERI_REG_BITS(SENS_SAR_READ_CTRL_REG, SENS_SAR1_CLK_DIV, __analogClockDiv, SENS_SAR1_CLK_DIV_S);
60-
SET_PERI_REG_BITS(SENS_SAR_READ_CTRL2_REG, SENS_SAR2_CLK_DIV, __analogClockDiv, SENS_SAR2_CLK_DIV_S);
61-
}
8+
#ifdef CONFIG_IDF_TARGET_ESP32 // if esp32 variant
629

63-
void __analogSetAttenuation(uint8_t attenuation)
64-
{
65-
__analogAttenuation = attenuation & 3;
66-
uint32_t att_data = 0;
67-
int i = 10;
68-
while(i--){
69-
att_data |= __analogAttenuation << (i * 2);
70-
}
71-
WRITE_PERI_REG(SENS_SAR_ATTEN1_REG, att_data & 0xFFFF);//ADC1 has 8 channels
72-
WRITE_PERI_REG(SENS_SAR_ATTEN2_REG, att_data);
73-
}
74-
75-
void IRAM_ATTR __analogInit(){
76-
static bool initialized = false;
77-
if(initialized){
78-
return;
79-
}
80-
81-
__analogSetAttenuation(__analogAttenuation);
82-
__analogSetCycles(__analogCycles);
83-
__analogSetSamples(__analogSamples + 1);//in samples
84-
__analogSetClockDiv(__analogClockDiv);
85-
__analogSetWidth(__analogWidth + 9);//in bits
10+
#include "soc/sens_reg.h"
8611

12+
// configure the ADCs in RTC mode
13+
// saves about 3us per call
14+
// going from 12us to 9us
15+
void __configFastADCs(){
16+
17+
// configure both ADCs in RTC mode
8718
SET_PERI_REG_MASK(SENS_SAR_READ_CTRL_REG, SENS_SAR1_DATA_INV);
8819
SET_PERI_REG_MASK(SENS_SAR_READ_CTRL2_REG, SENS_SAR2_DATA_INV);
8920

@@ -100,59 +31,17 @@ void IRAM_ATTR __analogInit(){
10031
SET_PERI_REG_BITS(SENS_SAR_MEAS_WAIT1_REG, SENS_SAR_AMP_WAIT2, 0x1, SENS_SAR_AMP_WAIT2_S);
10132
SET_PERI_REG_BITS(SENS_SAR_MEAS_WAIT2_REG, SENS_SAR_AMP_WAIT3, 0x1, SENS_SAR_AMP_WAIT3_S);
10233
while (GET_PERI_REG_BITS2(SENS_SAR_SLAVE_ADDR1_REG, 0x7, SENS_MEAS_STATUS_S) != 0); //wait det_fsm==
103-
104-
initialized = true;
105-
}
106-
107-
void __analogSetPinAttenuation(uint8_t pin, uint8_t attenuation)
108-
{
109-
int8_t channel = digitalPinToAnalogChannel(pin);
110-
if(channel < 0 || attenuation > 3){
111-
return ;
112-
}
113-
__analogInit();
114-
if(channel > 7){
115-
SET_PERI_REG_BITS(SENS_SAR_ATTEN2_REG, 3, attenuation, ((channel - 10) * 2));
116-
} else {
117-
SET_PERI_REG_BITS(SENS_SAR_ATTEN1_REG, 3, attenuation, (channel * 2));
118-
}
11934
}
12035

121-
bool IRAM_ATTR __adcAttachPin(uint8_t pin){
122-
123-
int8_t channel = digitalPinToAnalogChannel(pin);
124-
if(channel < 0){
125-
return false;//not adc pin
126-
}
127-
128-
int8_t pad = digitalPinToTouchChannel(pin);
129-
if(pad >= 0){
130-
uint32_t touch = READ_PERI_REG(SENS_SAR_TOUCH_ENABLE_REG);
131-
if(touch & (1 << pad)){
132-
touch &= ~((1 << (pad + SENS_TOUCH_PAD_OUTEN2_S))
133-
| (1 << (pad + SENS_TOUCH_PAD_OUTEN1_S))
134-
| (1 << (pad + SENS_TOUCH_PAD_WORKEN_S)));
135-
WRITE_PERI_REG(SENS_SAR_TOUCH_ENABLE_REG, touch);
136-
}
137-
} else if(pin == 25){
138-
CLEAR_PERI_REG_MASK(RTC_IO_PAD_DAC1_REG, RTC_IO_PDAC1_XPD_DAC | RTC_IO_PDAC1_DAC_XPD_FORCE); //stop dac1
139-
} else if(pin == 26){
140-
CLEAR_PERI_REG_MASK(RTC_IO_PAD_DAC2_REG, RTC_IO_PDAC2_XPD_DAC | RTC_IO_PDAC2_DAC_XPD_FORCE); //stop dac2
141-
}
142-
143-
pinMode(pin, ANALOG);
144-
145-
__analogInit();
146-
return true;
147-
}
148-
149-
bool IRAM_ATTR __adcStart(uint8_t pin){
15036

37+
uint16_t IRAM_ATTR adcRead(uint8_t pin)
38+
{
15139
int8_t channel = digitalPinToAnalogChannel(pin);
15240
if(channel < 0){
15341
return false;//not adc pin
15442
}
15543

44+
// start teh ADC conversion
15645
if(channel > 9){
15746
CLEAR_PERI_REG_MASK(SENS_SAR_MEAS_START2_REG, SENS_MEAS2_START_SAR_M);
15847
SET_PERI_REG_BITS(SENS_SAR_MEAS_START2_REG, SENS_SAR2_EN_PAD, (1 << (channel - 10)), SENS_SAR2_EN_PAD_S);
@@ -162,57 +51,51 @@ bool IRAM_ATTR __adcStart(uint8_t pin){
16251
SET_PERI_REG_BITS(SENS_SAR_MEAS_START1_REG, SENS_SAR1_EN_PAD, (1 << channel), SENS_SAR1_EN_PAD_S);
16352
SET_PERI_REG_MASK(SENS_SAR_MEAS_START1_REG, SENS_MEAS1_START_SAR_M);
16453
}
165-
return true;
166-
}
167-
168-
bool IRAM_ATTR __adcBusy(uint8_t pin){
169-
170-
int8_t channel = digitalPinToAnalogChannel(pin);
171-
if(channel < 0){
172-
return false;//not adc pin
173-
}
174-
175-
if(channel > 7){
176-
return (GET_PERI_REG_MASK(SENS_SAR_MEAS_START2_REG, SENS_MEAS2_DONE_SAR) == 0);
177-
}
178-
return (GET_PERI_REG_MASK(SENS_SAR_MEAS_START1_REG, SENS_MEAS1_DONE_SAR) == 0);
179-
}
180-
181-
uint16_t IRAM_ATTR __adcEnd(uint8_t pin)
182-
{
18354

18455
uint16_t value = 0;
185-
int8_t channel = digitalPinToAnalogChannel(pin);
186-
if(channel < 0){
187-
return 0;//not adc pin
188-
}
56+
18957
if(channel > 7){
190-
while (GET_PERI_REG_MASK(SENS_SAR_MEAS_START2_REG, SENS_MEAS2_DONE_SAR) == 0); //wait for conversion
58+
//wait for conversion
59+
while (GET_PERI_REG_MASK(SENS_SAR_MEAS_START2_REG, SENS_MEAS2_DONE_SAR) == 0);
60+
// read the value
19161
value = GET_PERI_REG_BITS2(SENS_SAR_MEAS_START2_REG, SENS_MEAS2_DATA_SAR, SENS_MEAS2_DATA_SAR_S);
19262
} else {
193-
while (GET_PERI_REG_MASK(SENS_SAR_MEAS_START1_REG, SENS_MEAS1_DONE_SAR) == 0); //wait for conversion
63+
//wait for conversion
64+
while (GET_PERI_REG_MASK(SENS_SAR_MEAS_START1_REG, SENS_MEAS1_DONE_SAR) == 0);
65+
// read the value
19466
value = GET_PERI_REG_BITS2(SENS_SAR_MEAS_START1_REG, SENS_MEAS1_DATA_SAR, SENS_MEAS1_DATA_SAR_S);
19567
}
19668

197-
// Shift result if necessary
198-
uint8_t from = __analogWidth + 9;
199-
if (from == __analogReturnedWidth) {
200-
return value;
201-
}
202-
if (from > __analogReturnedWidth) {
203-
return value >> (from - __analogReturnedWidth);
204-
}
205-
return value << (__analogReturnedWidth - from);
69+
// return value
70+
return value;
20671
}
20772

208-
void __analogReadResolution(uint8_t bits)
209-
{
210-
if(!bits || bits > 16){
211-
return;
212-
}
213-
__analogSetWidth(bits); // hadware from 9 to 12
214-
__analogReturnedWidth = bits; // software from 1 to 16
215-
}
73+
#elif (defined(CONFIG_IDF_TARGET_ESP32S2) || defined(CONFIG_IDF_TARGET_ESP32S3)) // if esp32 s2 or s3 variants
74+
75+
#include "soc/sens_reg.h"
76+
77+
78+
// configure the ADCs in RTC mode
79+
// no real gain
80+
// void __configFastADCs(){
81+
82+
// SET_PERI_REG_MASK(SENS_SAR_READER1_CTRL_REG, SENS_SAR1_DATA_INV);
83+
// SET_PERI_REG_MASK(SENS_SAR_READER2_CTRL_REG, SENS_SAR2_DATA_INV);
84+
85+
// SET_PERI_REG_MASK(SENS_SAR_MEAS1_CTRL2_REG, SENS_MEAS1_START_FORCE_M); //SAR ADC1 controller (in RTC) is started by SW
86+
// SET_PERI_REG_MASK(SENS_SAR_MEAS1_CTRL2_REG, SENS_SAR1_EN_PAD_FORCE_M); //SAR ADC1 pad enable bitmap is controlled by SW
87+
// SET_PERI_REG_MASK(SENS_SAR_MEAS2_CTRL2_REG, SENS_MEAS2_START_FORCE_M); //SAR ADC2 controller (in RTC) is started by SW
88+
// SET_PERI_REG_MASK(SENS_SAR_MEAS2_CTRL2_REG, SENS_SAR2_EN_PAD_FORCE_M); //SAR ADC2 pad enable bitmap is controlled by SW
89+
90+
// CLEAR_PERI_REG_MASK(SENS_SAR_POWER_XPD_SAR_REG, SENS_FORCE_XPD_SAR_M); //force XPD_SAR=0, use XPD_FSM
91+
// SET_PERI_REG_BITS(SENS_SAR_POWER_XPD_SAR_REG, SENS_FORCE_XPD_AMP, 0x2, SENS_FORCE_XPD_AMP_S); //force XPD_AMP=0
92+
93+
// CLEAR_PERI_REG_MASK(SENS_SAR_AMP_CTRL3_REG, 0xfff << SENS_AMP_RST_FB_FSM_S); //clear FSM
94+
// SET_PERI_REG_BITS(SENS_SAR_AMP_CTRL1_REG, SENS_SAR_AMP_WAIT1, 0x1, SENS_SAR_AMP_WAIT1_S);
95+
// SET_PERI_REG_BITS(SENS_SAR_AMP_CTRL1_REG, SENS_SAR_AMP_WAIT2, 0x1, SENS_SAR_AMP_WAIT2_S);
96+
// SET_PERI_REG_BITS(SENS_SAR_POWER_XPD_SAR_REG, SENS_SAR_AMP_WAIT3, 0x1, SENS_SAR_AMP_WAIT3_S);
97+
// while (GET_PERI_REG_BITS2(SENS_SAR_SLAVE_ADDR1_REG, 0x7, SENS_SARADC_MEAS_STATUS_S) != 0); //wait det_fsm==
98+
// }
21699

217100
uint16_t IRAM_ATTR adcRead(uint8_t pin)
218101
{
@@ -221,38 +104,66 @@ uint16_t IRAM_ATTR adcRead(uint8_t pin)
221104
return false;//not adc pin
222105
}
223106

224-
__analogInit();
225-
107+
// start the ADC conversion
226108
if(channel > 9){
227-
CLEAR_PERI_REG_MASK(SENS_SAR_MEAS_START2_REG, SENS_MEAS2_START_SAR_M);
228-
SET_PERI_REG_BITS(SENS_SAR_MEAS_START2_REG, SENS_SAR2_EN_PAD, (1 << (channel - 10)), SENS_SAR2_EN_PAD_S);
229-
SET_PERI_REG_MASK(SENS_SAR_MEAS_START2_REG, SENS_MEAS2_START_SAR_M);
109+
CLEAR_PERI_REG_MASK(SENS_SAR_MEAS2_CTRL2_REG, SENS_MEAS2_START_SAR_M);
110+
SET_PERI_REG_BITS(SENS_SAR_MEAS2_CTRL2_REG, SENS_SAR2_EN_PAD, (1 << (channel - 10)), SENS_SAR2_EN_PAD_S);
111+
SET_PERI_REG_MASK(SENS_SAR_MEAS2_CTRL2_REG, SENS_MEAS2_START_SAR_M);
230112
} else {
231-
CLEAR_PERI_REG_MASK(SENS_SAR_MEAS_START1_REG, SENS_MEAS1_START_SAR_M);
232-
SET_PERI_REG_BITS(SENS_SAR_MEAS_START1_REG, SENS_SAR1_EN_PAD, (1 << channel), SENS_SAR1_EN_PAD_S);
233-
SET_PERI_REG_MASK(SENS_SAR_MEAS_START1_REG, SENS_MEAS1_START_SAR_M);
113+
CLEAR_PERI_REG_MASK(SENS_SAR_MEAS1_CTRL2_REG, SENS_MEAS1_START_SAR_M);
114+
SET_PERI_REG_BITS(SENS_SAR_MEAS1_CTRL2_REG, SENS_SAR1_EN_PAD, (1 << channel), SENS_SAR1_EN_PAD_S);
115+
SET_PERI_REG_MASK(SENS_SAR_MEAS1_CTRL2_REG, SENS_MEAS1_START_SAR_M);
234116
}
235117

236118
uint16_t value = 0;
237119

238-
if(channel > 7){
239-
while (GET_PERI_REG_MASK(SENS_SAR_MEAS_START2_REG, SENS_MEAS2_DONE_SAR) == 0); //wait for conversion
240-
value = GET_PERI_REG_BITS2(SENS_SAR_MEAS_START2_REG, SENS_MEAS2_DATA_SAR, SENS_MEAS2_DATA_SAR_S);
120+
if(channel > 9){
121+
//wait for conversion
122+
while (GET_PERI_REG_MASK(SENS_SAR_MEAS2_CTRL2_REG, SENS_MEAS2_DONE_SAR) == 0);
123+
// read the value
124+
value = GET_PERI_REG_BITS2(SENS_SAR_MEAS2_CTRL2_REG, SENS_MEAS2_DATA_SAR, SENS_MEAS2_DATA_SAR_S);
241125
} else {
242-
while (GET_PERI_REG_MASK(SENS_SAR_MEAS_START1_REG, SENS_MEAS1_DONE_SAR) == 0); //wait for conversion
243-
value = GET_PERI_REG_BITS2(SENS_SAR_MEAS_START1_REG, SENS_MEAS1_DATA_SAR, SENS_MEAS1_DATA_SAR_S);
126+
//wait for conversion
127+
while (GET_PERI_REG_MASK(SENS_SAR_MEAS1_CTRL2_REG, SENS_MEAS1_DONE_SAR) == 0);
128+
// read teh value
129+
value = GET_PERI_REG_BITS2(SENS_SAR_MEAS1_CTRL2_REG, SENS_MEAS1_DATA_SAR, SENS_MEAS1_DATA_SAR_S);
244130
}
245131

246-
// Shift result if necessary
247-
uint8_t from = __analogWidth + 9;
248-
if (from == __analogReturnedWidth) {
249-
return value;
250-
}
251-
if (from > __analogReturnedWidth) {
252-
return value >> (from - __analogReturnedWidth);
253-
}
254-
return value << (__analogReturnedWidth - from);
132+
return value;
255133
}
256134

135+
#else // if others just use analogRead
136+
137+
uint16_t IRAM_ATTR adcRead(uint8_t pin){
138+
return analogRead(pin);
139+
}
140+
141+
#endif
142+
143+
144+
// configure the ADC for the pin
145+
bool IRAM_ATTR adcInit(uint8_t pin){
146+
static bool initialized = false;
147+
148+
int8_t channel = digitalPinToAnalogChannel(pin);
149+
if(channel < 0){
150+
return false;//not adc pin
151+
}
152+
153+
if(! initialized){
154+
analogSetAttenuation(SIMPLEFOC_ADC_ATTEN);
155+
analogReadResolution(SIMPLEFOC_ADC_RES);
156+
}
157+
pinMode(pin, ANALOG);
158+
analogSetPinAttenuation(pin, SIMPLEFOC_ADC_ATTEN);
159+
analogRead(pin);
160+
161+
#ifdef CONFIG_IDF_TARGET_ESP32 // if esp32 variant
162+
__configFastADCs();
163+
#endif
164+
165+
initialized = true;
166+
return true;
167+
}
257168

258169
#endif

0 commit comments

Comments
 (0)