Skip to content

Commit b1a5e4e

Browse files
committed
esp32s adc driver -contribution by @Fu-Xiaotian issues #198 and #212
1 parent 2cb2c8a commit b1a5e4e

File tree

2 files changed

+258
-1
lines changed

2 files changed

+258
-1
lines changed

src/current_sense/hardware_specific/esp32/esp32_adc_driver.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
#include "esp32_adc_driver.h"
22

3-
#if defined(ESP_H) && defined(ARDUINO_ARCH_ESP32) && defined(SOC_MCPWM_SUPPORTED)
3+
#if defined(ESP_H) && defined(ARDUINO_ARCH_ESP32) && defined(SOC_MCPWM_SUPPORTED) && !defined(CONFIG_IDF_TARGET_ESP32S2) && !defined(CONFIG_IDF_TARGET_ESP32S3)
44

55
#include "freertos/FreeRTOS.h"
66
#include "freertos/task.h"
Lines changed: 257 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,257 @@
1+
#include "esp32_adc_driver.h"
2+
3+
#if defined(ESP_H) && defined(ARDUINO_ARCH_ESP32) && defined(SOC_MCPWM_SUPPORTED) && (defined(CONFIG_IDF_TARGET_ESP32S2) || defined(CONFIG_IDF_TARGET_ESP32S3))
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"
10+
#include "soc/rtc_io_reg.h"
11+
#include "soc/rtc_cntl_reg.h"
12+
#include "soc/sens_reg.h"
13+
14+
static uint8_t __analogAttenuation = 3;//11db
15+
static uint8_t __analogWidth = 3;//12 bits
16+
static uint8_t __analogCycles = 8;
17+
static uint8_t __analogSamples = 0;//1 sample
18+
static uint8_t __analogClockDiv = 1;
19+
20+
// Width of returned answer ()
21+
static uint8_t __analogReturnedWidth = 12;
22+
23+
void __analogSetWidth(uint8_t bits){
24+
if(bits < 9){
25+
bits = 9;
26+
} else if(bits > 12){
27+
bits = 12;
28+
}
29+
__analogReturnedWidth = bits;
30+
__analogWidth = bits - 9;
31+
// SET_PERI_REG_BITS(SENS_SAR_START_FORCE_REG, SENS_SAR1_BIT_WIDTH, __analogWidth, SENS_SAR1_BIT_WIDTH_S);
32+
// SET_PERI_REG_BITS(SENS_SAR_READER1_CTRL_REG, SENS_SAR1_SAMPLE_BIT, __analogWidth, SENS_SAR1_SAMPLE_BIT_S);
33+
34+
// SET_PERI_REG_BITS(SENS_SAR_START_FORCE_REG, SENS_SAR2_BIT_WIDTH, __analogWidth, SENS_SAR2_BIT_WIDTH_S);
35+
// SET_PERI_REG_BITS(SENS_SAR_READER2_CTRL_REG, SENS_SAR2_SAMPLE_BIT, __analogWidth, SENS_SAR2_SAMPLE_BIT_S);
36+
}
37+
38+
void __analogSetCycles(uint8_t cycles){
39+
__analogCycles = cycles;
40+
// SET_PERI_REG_BITS(SENS_SAR_READER1_CTRL_REG, SENS_SAR1_SAMPLE_CYCLE, __analogCycles, SENS_SAR1_SAMPLE_CYCLE_S);
41+
// SET_PERI_REG_BITS(SENS_SAR_READER2_CTRL_REG, SENS_SAR2_SAMPLE_CYCLE, __analogCycles, SENS_SAR2_SAMPLE_CYCLE_S);
42+
}
43+
44+
void __analogSetSamples(uint8_t samples){
45+
if(!samples){
46+
return;
47+
}
48+
__analogSamples = samples - 1;
49+
SET_PERI_REG_BITS(SENS_SAR_READER1_CTRL_REG, SENS_SAR1_SAMPLE_NUM, __analogSamples, SENS_SAR1_SAMPLE_NUM_S);
50+
SET_PERI_REG_BITS(SENS_SAR_READER2_CTRL_REG, SENS_SAR2_SAMPLE_NUM, __analogSamples, SENS_SAR2_SAMPLE_NUM_S);
51+
}
52+
53+
void __analogSetClockDiv(uint8_t clockDiv){
54+
if(!clockDiv){
55+
return;
56+
}
57+
__analogClockDiv = clockDiv;
58+
SET_PERI_REG_BITS(SENS_SAR_READER1_CTRL_REG, SENS_SAR1_CLK_DIV, __analogClockDiv, SENS_SAR1_CLK_DIV_S);
59+
SET_PERI_REG_BITS(SENS_SAR_READER2_CTRL_REG, SENS_SAR2_CLK_DIV, __analogClockDiv, SENS_SAR2_CLK_DIV_S);
60+
}
61+
62+
void __analogSetAttenuation(uint8_t attenuation)
63+
{
64+
__analogAttenuation = attenuation & 3;
65+
uint32_t att_data = 0;
66+
int i = 10;
67+
while(i--){
68+
att_data |= __analogAttenuation << (i * 2);
69+
}
70+
WRITE_PERI_REG(SENS_SAR_ATTEN1_REG, att_data & 0xFFFF);//ADC1 has 8 channels
71+
WRITE_PERI_REG(SENS_SAR_ATTEN2_REG, att_data);
72+
}
73+
74+
void IRAM_ATTR __analogInit(){
75+
static bool initialized = false;
76+
if(initialized){
77+
return;
78+
}
79+
80+
__analogSetAttenuation(__analogAttenuation);
81+
__analogSetCycles(__analogCycles);
82+
__analogSetSamples(__analogSamples + 1);//in samples
83+
__analogSetClockDiv(__analogClockDiv);
84+
__analogSetWidth(__analogWidth + 9);//in bits
85+
86+
SET_PERI_REG_MASK(SENS_SAR_READER1_CTRL_REG, SENS_SAR1_DATA_INV);
87+
SET_PERI_REG_MASK(SENS_SAR_READER2_CTRL_REG, SENS_SAR2_DATA_INV);
88+
89+
SET_PERI_REG_MASK(SENS_SAR_MEAS1_CTRL2_REG, SENS_MEAS1_START_FORCE_M); //SAR ADC1 controller (in RTC) is started by SW
90+
SET_PERI_REG_MASK(SENS_SAR_MEAS1_CTRL2_REG, SENS_SAR1_EN_PAD_FORCE_M); //SAR ADC1 pad enable bitmap is controlled by SW
91+
SET_PERI_REG_MASK(SENS_SAR_MEAS2_CTRL2_REG, SENS_MEAS2_START_FORCE_M); //SAR ADC2 controller (in RTC) is started by SW
92+
SET_PERI_REG_MASK(SENS_SAR_MEAS2_CTRL2_REG, SENS_SAR2_EN_PAD_FORCE_M); //SAR ADC2 pad enable bitmap is controlled by SW
93+
94+
CLEAR_PERI_REG_MASK(SENS_SAR_POWER_XPD_SAR_REG, SENS_FORCE_XPD_SAR_M); //force XPD_SAR=0, use XPD_FSM
95+
SET_PERI_REG_BITS(SENS_SAR_POWER_XPD_SAR_REG, SENS_FORCE_XPD_AMP, 0x2, SENS_FORCE_XPD_AMP_S); //force XPD_AMP=0
96+
97+
CLEAR_PERI_REG_MASK(SENS_SAR_AMP_CTRL3_REG, 0xfff << SENS_AMP_RST_FB_FSM_S); //clear FSM
98+
SET_PERI_REG_BITS(SENS_SAR_AMP_CTRL1_REG, SENS_SAR_AMP_WAIT1, 0x1, SENS_SAR_AMP_WAIT1_S);
99+
SET_PERI_REG_BITS(SENS_SAR_AMP_CTRL1_REG, SENS_SAR_AMP_WAIT2, 0x1, SENS_SAR_AMP_WAIT2_S);
100+
SET_PERI_REG_BITS(SENS_SAR_POWER_XPD_SAR_REG, SENS_SAR_AMP_WAIT3, 0x1, SENS_SAR_AMP_WAIT3_S);
101+
while (GET_PERI_REG_BITS2(SENS_SAR_SLAVE_ADDR1_REG, 0x7, SENS_SARADC_MEAS_STATUS_S) != 0); //wait det_fsm==
102+
103+
initialized = true;
104+
}
105+
106+
void __analogSetPinAttenuation(uint8_t pin, uint8_t attenuation)
107+
{
108+
int8_t channel = digitalPinToAnalogChannel(pin);
109+
if(channel < 0 || attenuation > 3){
110+
return ;
111+
}
112+
__analogInit();
113+
if(channel > 7){
114+
SET_PERI_REG_BITS(SENS_SAR_ATTEN2_REG, 3, attenuation, ((channel - 10) * 2));
115+
} else {
116+
SET_PERI_REG_BITS(SENS_SAR_ATTEN1_REG, 3, attenuation, (channel * 2));
117+
}
118+
}
119+
120+
bool IRAM_ATTR __adcAttachPin(uint8_t pin){
121+
122+
int8_t channel = digitalPinToAnalogChannel(pin);
123+
if(channel < 0){
124+
return false;//not adc pin
125+
}
126+
127+
int8_t pad = digitalPinToTouchChannel(pin);
128+
if(pad >= 0){
129+
uint32_t touch = READ_PERI_REG(SENS_SAR_TOUCH_CONF_REG);
130+
if(touch & (1 << pad)){
131+
touch &= ~((1 << (pad + SENS_TOUCH_OUTEN_S)));
132+
WRITE_PERI_REG(SENS_SAR_TOUCH_CONF_REG, touch);
133+
}
134+
} else if(pin == 25){
135+
CLEAR_PERI_REG_MASK(RTC_IO_PAD_DAC1_REG, RTC_IO_PDAC1_XPD_DAC | RTC_IO_PDAC1_DAC_XPD_FORCE); //stop dac1
136+
} else if(pin == 26){
137+
CLEAR_PERI_REG_MASK(RTC_IO_PAD_DAC2_REG, RTC_IO_PDAC2_XPD_DAC | RTC_IO_PDAC2_DAC_XPD_FORCE); //stop dac2
138+
}
139+
140+
pinMode(pin, ANALOG);
141+
142+
__analogInit();
143+
return true;
144+
}
145+
146+
bool IRAM_ATTR __adcStart(uint8_t pin){
147+
148+
int8_t channel = digitalPinToAnalogChannel(pin);
149+
if(channel < 0){
150+
return false;//not adc pin
151+
}
152+
153+
if(channel > 9){
154+
channel -= 10;
155+
CLEAR_PERI_REG_MASK(SENS_SAR_MEAS2_CTRL2_REG, SENS_MEAS2_START_SAR_M);
156+
SET_PERI_REG_BITS(SENS_SAR_MEAS2_CTRL2_REG, SENS_SAR2_EN_PAD, (1 << channel), SENS_SAR2_EN_PAD_S);
157+
SET_PERI_REG_MASK(SENS_SAR_MEAS2_CTRL2_REG, SENS_MEAS2_START_SAR_M);
158+
} else {
159+
CLEAR_PERI_REG_MASK(SENS_SAR_MEAS1_CTRL2_REG, SENS_MEAS1_START_SAR_M);
160+
SET_PERI_REG_BITS(SENS_SAR_MEAS1_CTRL2_REG, SENS_SAR1_EN_PAD, (1 << channel), SENS_SAR1_EN_PAD_S);
161+
SET_PERI_REG_MASK(SENS_SAR_MEAS1_CTRL2_REG, SENS_MEAS1_START_SAR_M);
162+
}
163+
return true;
164+
}
165+
166+
bool IRAM_ATTR __adcBusy(uint8_t pin){
167+
168+
int8_t channel = digitalPinToAnalogChannel(pin);
169+
if(channel < 0){
170+
return false;//not adc pin
171+
}
172+
173+
if(channel > 7){
174+
return (GET_PERI_REG_MASK(SENS_SAR_MEAS2_CTRL2_REG, SENS_MEAS2_DONE_SAR) == 0);
175+
}
176+
return (GET_PERI_REG_MASK(SENS_SAR_MEAS1_CTRL2_REG, SENS_MEAS1_DONE_SAR) == 0);
177+
}
178+
179+
uint16_t IRAM_ATTR __adcEnd(uint8_t pin)
180+
{
181+
182+
uint16_t value = 0;
183+
int8_t channel = digitalPinToAnalogChannel(pin);
184+
if(channel < 0){
185+
return 0;//not adc pin
186+
}
187+
if(channel > 7){
188+
while (GET_PERI_REG_MASK(SENS_SAR_MEAS2_CTRL2_REG, SENS_MEAS2_DONE_SAR) == 0); //wait for conversion
189+
value = GET_PERI_REG_BITS2(SENS_SAR_MEAS2_CTRL2_REG, SENS_MEAS2_DATA_SAR, SENS_MEAS2_DATA_SAR_S);
190+
} else {
191+
while (GET_PERI_REG_MASK(SENS_SAR_MEAS1_CTRL2_REG, SENS_MEAS1_DONE_SAR) == 0); //wait for conversion
192+
value = GET_PERI_REG_BITS2(SENS_SAR_MEAS1_CTRL2_REG, SENS_MEAS1_DATA_SAR, SENS_MEAS1_DATA_SAR_S);
193+
}
194+
195+
// Shift result if necessary
196+
uint8_t from = __analogWidth + 9;
197+
if (from == __analogReturnedWidth) {
198+
return value;
199+
}
200+
if (from > __analogReturnedWidth) {
201+
return value >> (from - __analogReturnedWidth);
202+
}
203+
return value << (__analogReturnedWidth - from);
204+
}
205+
206+
void __analogReadResolution(uint8_t bits)
207+
{
208+
if(!bits || bits > 16){
209+
return;
210+
}
211+
__analogSetWidth(bits); // hadware from 9 to 12
212+
__analogReturnedWidth = bits; // software from 1 to 16
213+
}
214+
215+
uint16_t IRAM_ATTR adcRead(uint8_t pin)
216+
{
217+
int8_t channel = digitalPinToAnalogChannel(pin);
218+
if(channel < 0){
219+
return false;//not adc pin
220+
}
221+
222+
__analogInit();
223+
224+
if(channel > 9){
225+
channel -= 10;
226+
CLEAR_PERI_REG_MASK(SENS_SAR_MEAS2_CTRL2_REG, SENS_MEAS2_START_SAR_M);
227+
SET_PERI_REG_BITS(SENS_SAR_MEAS2_CTRL2_REG, SENS_SAR2_EN_PAD, (1 << channel), SENS_SAR2_EN_PAD_S);
228+
SET_PERI_REG_MASK(SENS_SAR_MEAS2_CTRL2_REG, SENS_MEAS2_START_SAR_M);
229+
} else {
230+
CLEAR_PERI_REG_MASK(SENS_SAR_MEAS1_CTRL2_REG, SENS_MEAS1_START_SAR_M);
231+
SET_PERI_REG_BITS(SENS_SAR_MEAS1_CTRL2_REG, SENS_SAR1_EN_PAD, (1 << channel), SENS_SAR1_EN_PAD_S);
232+
SET_PERI_REG_MASK(SENS_SAR_MEAS1_CTRL2_REG, SENS_MEAS1_START_SAR_M);
233+
}
234+
235+
uint16_t value = 0;
236+
237+
if(channel > 7){
238+
while (GET_PERI_REG_MASK(SENS_SAR_MEAS2_CTRL2_REG, SENS_MEAS2_DONE_SAR) == 0); //wait for conversion
239+
value = GET_PERI_REG_BITS2(SENS_SAR_MEAS2_CTRL2_REG, SENS_MEAS2_DATA_SAR, SENS_MEAS2_DATA_SAR_S);
240+
} else {
241+
while (GET_PERI_REG_MASK(SENS_SAR_MEAS1_CTRL2_REG, SENS_MEAS1_DONE_SAR) == 0); //wait for conversion
242+
value = GET_PERI_REG_BITS2(SENS_SAR_MEAS1_CTRL2_REG, SENS_MEAS1_DATA_SAR, SENS_MEAS1_DATA_SAR_S);
243+
}
244+
245+
// Shift result if necessary
246+
uint8_t from = __analogWidth + 9;
247+
if (from == __analogReturnedWidth) {
248+
return value;
249+
}
250+
if (from > __analogReturnedWidth) {
251+
return value >> (from - __analogReturnedWidth);
252+
}
253+
return value << (__analogReturnedWidth - from);
254+
}
255+
256+
257+
#endif

0 commit comments

Comments
 (0)