SimpleFOClibrary 2.4.0
Loading...
Searching...
No Matches
esp32_adc_driver.cpp
Go to the documentation of this file.
1
2#include "esp32_mcu.h"
3#include "esp32_adc_driver.h"
4
5#if defined(ESP_H) && defined(ARDUINO_ARCH_ESP32)
6#define SIMPLEFOC_ADC_ATTEN ADC_11db
7#define SIMPLEFOC_ADC_RES 12
8
9static portMUX_TYPE spinlock = portMUX_INITIALIZER_UNLOCKED;
10
11#if CONFIG_IDF_TARGET_ESP32 // if esp32 variant
12
13#include "soc/sens_reg.h"
14
15// configure the ADCs in RTC mode
16// saves about 3us per call
17// going from 12us to 9us
18//
19// TODO: See if we need to configure both ADCs or we can just configure the one we'll use
20// For the moment we will configure both
21void IRAM_ATTR __configFastADCs(){
22
23 SIMPLEFOC_ESP32_CS_DEBUG("Configuring fast ADCs");
24
25 // configure both ADCs in RTC mode
26 SET_PERI_REG_MASK(SENS_SAR_READ_CTRL_REG, SENS_SAR1_DATA_INV);
27 SET_PERI_REG_MASK(SENS_SAR_READ_CTRL2_REG, SENS_SAR2_DATA_INV);
28
29 SET_PERI_REG_MASK(SENS_SAR_MEAS_START1_REG, SENS_MEAS1_START_FORCE_M); //SAR ADC1 controller (in RTC) is started by SW
30 SET_PERI_REG_MASK(SENS_SAR_MEAS_START1_REG, SENS_SAR1_EN_PAD_FORCE_M); //SAR ADC1 pad enable bitmap is controlled by SW
31 SET_PERI_REG_MASK(SENS_SAR_MEAS_START2_REG, SENS_MEAS2_START_FORCE_M); //SAR ADC2 controller (in RTC) is started by SW
32 SET_PERI_REG_MASK(SENS_SAR_MEAS_START2_REG, SENS_SAR2_EN_PAD_FORCE_M); //SAR ADC2 pad enable bitmap is controlled by SW
33
34 CLEAR_PERI_REG_MASK(SENS_SAR_MEAS_WAIT2_REG, SENS_FORCE_XPD_SAR_M); //force XPD_SAR=0, use XPD_FSM
35 SET_PERI_REG_BITS(SENS_SAR_MEAS_WAIT2_REG, SENS_FORCE_XPD_AMP, 0x2, SENS_FORCE_XPD_AMP_S); //force XPD_AMP=0
36
37 CLEAR_PERI_REG_MASK(SENS_SAR_MEAS_CTRL_REG, 0xfff << SENS_AMP_RST_FB_FSM_S); //clear FSM
38 SET_PERI_REG_BITS(SENS_SAR_MEAS_WAIT1_REG, SENS_SAR_AMP_WAIT1, 0x1, SENS_SAR_AMP_WAIT1_S);
39 SET_PERI_REG_BITS(SENS_SAR_MEAS_WAIT1_REG, SENS_SAR_AMP_WAIT2, 0x1, SENS_SAR_AMP_WAIT2_S);
40 SET_PERI_REG_BITS(SENS_SAR_MEAS_WAIT2_REG, SENS_SAR_AMP_WAIT3, 0x1, SENS_SAR_AMP_WAIT3_S);
41 while (GET_PERI_REG_BITS2(SENS_SAR_SLAVE_ADDR1_REG, 0x7, SENS_MEAS_STATUS_S) != 0); //wait det_fsm==
42
43}
44
45
46uint16_t IRAM_ATTR adcRead(uint8_t pin)
47{
48 int8_t channel = digitalPinToAnalogChannel(pin);
49 if(channel < 0){
50 SIMPLEFOC_ESP32_CS_DEBUG("ERROR: Not ADC pin: "+String(pin));
51 return false; //not adc pin
52 }
53
54 // channels <= MAX_CHANNEL_NUM belong to ADC1
55 // channels > MAX_CHANNEL_NUM belong to ADC2 (where the channel number is number-SOC_ADC_MAX_CHANNEL_NUM)
56 uint8_t adc_num = (channel >= SOC_ADC_MAX_CHANNEL_NUM) ? 2 : 1;
57 uint8_t adc_channel = (adc_num == 2) ? (channel - SOC_ADC_MAX_CHANNEL_NUM) : channel;
58
59 // variable to hold the ADC value
60 uint16_t value = 0;
61
62 //Protects against core migration, on single core chips this is noop.
63 portENTER_CRITICAL(&spinlock);
64
65 // do the ADC conversion
66 switch(adc_num){
67 case 1:
68 // start the ADC1 conversion
69 CLEAR_PERI_REG_MASK(SENS_SAR_MEAS_START1_REG, SENS_MEAS1_START_SAR_M);
70 SET_PERI_REG_BITS(SENS_SAR_MEAS_START1_REG, SENS_SAR1_EN_PAD, (1 << channel), SENS_SAR1_EN_PAD_S);
71 SET_PERI_REG_MASK(SENS_SAR_MEAS_START1_REG, SENS_MEAS1_START_SAR_M);
72
73 // wait for conversion
74 while (GET_PERI_REG_MASK(SENS_SAR_MEAS_START1_REG, SENS_MEAS1_DONE_SAR) == 0);
75 // read the value
76 value = GET_PERI_REG_BITS2(SENS_SAR_MEAS_START1_REG, SENS_MEAS1_DATA_SAR, SENS_MEAS1_DATA_SAR_S);
77 break;
78 case 2:
79 // start the ADC2 conversion
80 CLEAR_PERI_REG_MASK(SENS_SAR_MEAS_START2_REG, SENS_MEAS2_START_SAR_M);
81 SET_PERI_REG_BITS(SENS_SAR_MEAS_START2_REG, SENS_SAR2_EN_PAD, (1 << (adc_channel)), SENS_SAR2_EN_PAD_S);
82 SET_PERI_REG_MASK(SENS_SAR_MEAS_START2_REG, SENS_MEAS2_START_SAR_M);
83
84 // wait for conversion
85 while (GET_PERI_REG_MASK(SENS_SAR_MEAS_START2_REG, SENS_MEAS2_DONE_SAR) == 0);
86 // read the value
87 value = GET_PERI_REG_BITS2(SENS_SAR_MEAS_START2_REG, SENS_MEAS2_DATA_SAR, SENS_MEAS2_DATA_SAR_S);
88 break;
89 }
90
91 portEXIT_CRITICAL(&spinlock);
92
93 // return value
94 return value;
95}
96
97#elif CONFIG_IDF_TARGET_ESP32S2 || CONFIG_IDF_TARGET_ESP32S3 // if esp32 s2 or s3 variants
98
99#include "soc/sens_reg.h"
100
101
102// configure the ADCs in RTC mode
103// no real gain - see if we do something with it later
104// void __configFastADCs(){
105
106// SET_PERI_REG_MASK(SENS_SAR_READER1_CTRL_REG, SENS_SAR1_DATA_INV);
107// SET_PERI_REG_MASK(SENS_SAR_READER2_CTRL_REG, SENS_SAR2_DATA_INV);
108
109// SET_PERI_REG_MASK(SENS_SAR_MEAS1_CTRL2_REG, SENS_MEAS1_START_FORCE_M); //SAR ADC1 controller (in RTC) is started by SW
110// SET_PERI_REG_MASK(SENS_SAR_MEAS1_CTRL2_REG, SENS_SAR1_EN_PAD_FORCE_M); //SAR ADC1 pad enable bitmap is controlled by SW
111// SET_PERI_REG_MASK(SENS_SAR_MEAS2_CTRL2_REG, SENS_MEAS2_START_FORCE_M); //SAR ADC2 controller (in RTC) is started by SW
112// SET_PERI_REG_MASK(SENS_SAR_MEAS2_CTRL2_REG, SENS_SAR2_EN_PAD_FORCE_M); //SAR ADC2 pad enable bitmap is controlled by SW
113
114// CLEAR_PERI_REG_MASK(SENS_SAR_POWER_XPD_SAR_REG, SENS_FORCE_XPD_SAR_M); //force XPD_SAR=0, use XPD_FSM
115// SET_PERI_REG_BITS(SENS_SAR_POWER_XPD_SAR_REG, SENS_FORCE_XPD_AMP, 0x2, SENS_FORCE_XPD_AMP_S); //force XPD_AMP=0
116
117// CLEAR_PERI_REG_MASK(SENS_SAR_AMP_CTRL3_REG, 0xfff << SENS_AMP_RST_FB_FSM_S); //clear FSM
118// SET_PERI_REG_BITS(SENS_SAR_AMP_CTRL1_REG, SENS_SAR_AMP_WAIT1, 0x1, SENS_SAR_AMP_WAIT1_S);
119// SET_PERI_REG_BITS(SENS_SAR_AMP_CTRL1_REG, SENS_SAR_AMP_WAIT2, 0x1, SENS_SAR_AMP_WAIT2_S);
120// SET_PERI_REG_BITS(SENS_SAR_POWER_XPD_SAR_REG, SENS_SAR_AMP_WAIT3, 0x1, SENS_SAR_AMP_WAIT3_S);
121// while (GET_PERI_REG_BITS2(SENS_SAR_SLAVE_ADDR1_REG, 0x7, SENS_SARADC_MEAS_STATUS_S) != 0); //wait det_fsm==
122// }
123
124uint16_t IRAM_ATTR adcRead(uint8_t pin)
125{
126 int8_t channel = digitalPinToAnalogChannel(pin);
127 if(channel < 0){
128 SIMPLEFOC_ESP32_CS_DEBUG("ERROR: Not ADC pin: "+String(pin));
129 return false; //not adc pin
130 }
131
132 // channels <= MAX_CHANNEL_NUM belong to ADC1
133 // channels > MAX_CHANNEL_NUM belong to ADC2 (where the channel number is number-SOC_ADC_MAX_CHANNEL_NUM)
134 uint8_t adc_num = (channel >= SOC_ADC_MAX_CHANNEL_NUM) ? 2 : 1;
135 uint8_t adc_channel = (adc_num == 2) ? (channel - SOC_ADC_MAX_CHANNEL_NUM) : channel;
136
137 // variable to hold the ADC value
138 uint16_t value = 0;
139
140 //Protects against core migration, on single core chips this is noop.
141 portENTER_CRITICAL(&spinlock);
142
143 // do the ADC conversion
144 switch(adc_num){
145 case 1:
146 // start the ADC1 conversion
147 CLEAR_PERI_REG_MASK(SENS_SAR_MEAS1_CTRL2_REG, SENS_MEAS1_START_SAR_M);
148 SET_PERI_REG_BITS(SENS_SAR_MEAS1_CTRL2_REG, SENS_SAR1_EN_PAD, (1 << (adc_channel)), SENS_SAR1_EN_PAD_S);
149 SET_PERI_REG_MASK(SENS_SAR_MEAS1_CTRL2_REG, SENS_MEAS1_START_SAR_M);
150
151 // wait for conversion
152 while (GET_PERI_REG_MASK(SENS_SAR_MEAS1_CTRL2_REG, SENS_MEAS1_DONE_SAR) == 0);
153 // read the value
154 value = GET_PERI_REG_BITS2(SENS_SAR_MEAS1_CTRL2_REG, SENS_MEAS1_DATA_SAR, SENS_MEAS1_DATA_SAR_S);
155 break;
156 case 2:
157 // start the ADC2 conversion
158 CLEAR_PERI_REG_MASK(SENS_SAR_MEAS2_CTRL2_REG, SENS_MEAS2_START_SAR_M);
159 SET_PERI_REG_BITS(SENS_SAR_MEAS2_CTRL2_REG, SENS_SAR2_EN_PAD, (1 << (adc_channel)), SENS_SAR2_EN_PAD_S);
160 SET_PERI_REG_MASK(SENS_SAR_MEAS2_CTRL2_REG, SENS_MEAS2_START_SAR_M);
161
162 // wait for conversion
163 while (GET_PERI_REG_MASK(SENS_SAR_MEAS2_CTRL2_REG, SENS_MEAS2_DONE_SAR) == 0);
164 // read the value
165 value = GET_PERI_REG_BITS2(SENS_SAR_MEAS2_CTRL2_REG, SENS_MEAS2_DATA_SAR, SENS_MEAS2_DATA_SAR_S);
166 break;
167 }
168
169 portEXIT_CRITICAL(&spinlock);
170
171 return value;
172}
173
174#else // if others just use analogRead
175
176#pragma message("SimpleFOC: Using analogRead for ADC reading, no fast ADC configuration available!")
177
178uint16_t IRAM_ATTR adcRead(uint8_t pin){
179 return analogRead(pin);
180}
181
182#endif
183
184
185// configure the ADC for the pin
186bool IRAM_ATTR adcInit(uint8_t pin){
187 static bool initialized = false;
188
189 int8_t channel = digitalPinToAnalogChannel(pin);
190 if(channel < 0){
191 SIMPLEFOC_ESP32_CS_DEBUG("ERROR: Not ADC pin: "+String(pin));
192 return false;//not adc pin
193 }
194
195 uint8_t adc_num = (channel >= SOC_ADC_MAX_CHANNEL_NUM) ? 2 : 1;
196 uint8_t adc_channel = (adc_num == 2) ? (channel - SOC_ADC_MAX_CHANNEL_NUM) : channel;
197
198 SIMPLEFOC_ESP32_CS_DEBUG("Configuring ADC"+String(adc_num)+" channel "+String(adc_channel));
199
200 if(! initialized){
201 analogSetAttenuation(SIMPLEFOC_ADC_ATTEN);
202 analogReadResolution(SIMPLEFOC_ADC_RES);
203 }
204 pinMode(pin, ANALOG);
205 analogRead(pin);
206 analogSetPinAttenuation(pin, SIMPLEFOC_ADC_ATTEN);
207
208#if CONFIG_IDF_TARGET_ESP32 // if esp32 variant
209 __configFastADCs();
210#endif
211
212 initialized = true;
213 return true;
214}
215
216#endif