1
+ // Copyright 2015-2016 Espressif Systems (Shanghai) PTE LTD
2
+ //
3
+ // Licensed under the Apache License, Version 2.0 (the "License");
4
+ // you may not use this file except in compliance with the License.
5
+ // You may obtain a copy of the License at
6
+
7
+ // http://www.apache.org/licenses/LICENSE-2.0
8
+ //
9
+ // Unless required by applicable law or agreed to in writing, software
10
+ // distributed under the License is distributed on an "AS IS" BASIS,
11
+ // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ // See the License for the specific language governing permissions and
13
+ // limitations under the License.
14
+
15
+ #if defined(ESP_H)
16
+
17
+ #include " esp32_adc_driver.h"
18
+ #include " Arduino.h"
19
+
20
+ #include " freertos/FreeRTOS.h"
21
+ #include " freertos/task.h"
22
+ #include " rom/ets_sys.h"
23
+ #include " esp_attr.h"
24
+ #include " esp_intr.h"
25
+ #include " soc/rtc_io_reg.h"
26
+ #include " soc/rtc_cntl_reg.h"
27
+ #include " soc/sens_reg.h"
28
+
29
+ static uint8_t __analogAttenuation = 3 ;// 11db
30
+ static uint8_t __analogWidth = 3 ;// 12 bits
31
+ static uint8_t __analogCycles = 8 ;
32
+ static uint8_t __analogSamples = 0 ;// 1 sample
33
+ static uint8_t __analogClockDiv = 1 ;
34
+
35
+ // Width of returned answer ()
36
+ static uint8_t __analogReturnedWidth = 12 ;
37
+
38
+ void __analogSetWidth (uint8_t bits){
39
+ if (bits < 9 ){
40
+ bits = 9 ;
41
+ } else if (bits > 12 ){
42
+ bits = 12 ;
43
+ }
44
+ __analogReturnedWidth = bits;
45
+ __analogWidth = bits - 9 ;
46
+ SET_PERI_REG_BITS (SENS_SAR_START_FORCE_REG, SENS_SAR1_BIT_WIDTH, __analogWidth, SENS_SAR1_BIT_WIDTH_S);
47
+ SET_PERI_REG_BITS (SENS_SAR_READ_CTRL_REG, SENS_SAR1_SAMPLE_BIT, __analogWidth, SENS_SAR1_SAMPLE_BIT_S);
48
+
49
+ SET_PERI_REG_BITS (SENS_SAR_START_FORCE_REG, SENS_SAR2_BIT_WIDTH, __analogWidth, SENS_SAR2_BIT_WIDTH_S);
50
+ SET_PERI_REG_BITS (SENS_SAR_READ_CTRL2_REG, SENS_SAR2_SAMPLE_BIT, __analogWidth, SENS_SAR2_SAMPLE_BIT_S);
51
+ }
52
+
53
+ void __analogSetCycles (uint8_t cycles){
54
+ __analogCycles = cycles;
55
+ SET_PERI_REG_BITS (SENS_SAR_READ_CTRL_REG, SENS_SAR1_SAMPLE_CYCLE, __analogCycles, SENS_SAR1_SAMPLE_CYCLE_S);
56
+ SET_PERI_REG_BITS (SENS_SAR_READ_CTRL2_REG, SENS_SAR2_SAMPLE_CYCLE, __analogCycles, SENS_SAR2_SAMPLE_CYCLE_S);
57
+ }
58
+
59
+ void __analogSetSamples (uint8_t samples){
60
+ if (!samples){
61
+ return ;
62
+ }
63
+ __analogSamples = samples - 1 ;
64
+ SET_PERI_REG_BITS (SENS_SAR_READ_CTRL_REG, SENS_SAR1_SAMPLE_NUM, __analogSamples, SENS_SAR1_SAMPLE_NUM_S);
65
+ SET_PERI_REG_BITS (SENS_SAR_READ_CTRL2_REG, SENS_SAR2_SAMPLE_NUM, __analogSamples, SENS_SAR2_SAMPLE_NUM_S);
66
+ }
67
+
68
+ void __analogSetClockDiv (uint8_t clockDiv){
69
+ if (!clockDiv){
70
+ return ;
71
+ }
72
+ __analogClockDiv = clockDiv;
73
+ SET_PERI_REG_BITS (SENS_SAR_READ_CTRL_REG, SENS_SAR1_CLK_DIV, __analogClockDiv, SENS_SAR1_CLK_DIV_S);
74
+ SET_PERI_REG_BITS (SENS_SAR_READ_CTRL2_REG, SENS_SAR2_CLK_DIV, __analogClockDiv, SENS_SAR2_CLK_DIV_S);
75
+ }
76
+
77
+ void __analogSetAttenuation (uint8_t attenuation)
78
+ {
79
+ __analogAttenuation = attenuation & 3 ;
80
+ uint32_t att_data = 0 ;
81
+ int i = 10 ;
82
+ while (i--){
83
+ att_data |= __analogAttenuation << (i * 2 );
84
+ }
85
+ WRITE_PERI_REG (SENS_SAR_ATTEN1_REG, att_data & 0xFFFF );// ADC1 has 8 channels
86
+ WRITE_PERI_REG (SENS_SAR_ATTEN2_REG, att_data);
87
+ }
88
+
89
+ void IRAM_ATTR __analogInit (){
90
+ static bool initialized = false ;
91
+ if (initialized){
92
+ return ;
93
+ }
94
+
95
+ __analogSetAttenuation (__analogAttenuation);
96
+ __analogSetCycles (__analogCycles);
97
+ __analogSetSamples (__analogSamples + 1 );// in samples
98
+ __analogSetClockDiv (__analogClockDiv);
99
+ __analogSetWidth (__analogWidth + 9 );// in bits
100
+
101
+ SET_PERI_REG_MASK (SENS_SAR_READ_CTRL_REG, SENS_SAR1_DATA_INV);
102
+ SET_PERI_REG_MASK (SENS_SAR_READ_CTRL2_REG, SENS_SAR2_DATA_INV);
103
+
104
+ SET_PERI_REG_MASK (SENS_SAR_MEAS_START1_REG, SENS_MEAS1_START_FORCE_M); // SAR ADC1 controller (in RTC) is started by SW
105
+ SET_PERI_REG_MASK (SENS_SAR_MEAS_START1_REG, SENS_SAR1_EN_PAD_FORCE_M); // SAR ADC1 pad enable bitmap is controlled by SW
106
+ SET_PERI_REG_MASK (SENS_SAR_MEAS_START2_REG, SENS_MEAS2_START_FORCE_M); // SAR ADC2 controller (in RTC) is started by SW
107
+ SET_PERI_REG_MASK (SENS_SAR_MEAS_START2_REG, SENS_SAR2_EN_PAD_FORCE_M); // SAR ADC2 pad enable bitmap is controlled by SW
108
+
109
+ CLEAR_PERI_REG_MASK (SENS_SAR_MEAS_WAIT2_REG, SENS_FORCE_XPD_SAR_M); // force XPD_SAR=0, use XPD_FSM
110
+ SET_PERI_REG_BITS (SENS_SAR_MEAS_WAIT2_REG, SENS_FORCE_XPD_AMP, 0x2 , SENS_FORCE_XPD_AMP_S); // force XPD_AMP=0
111
+
112
+ CLEAR_PERI_REG_MASK (SENS_SAR_MEAS_CTRL_REG, 0xfff << SENS_AMP_RST_FB_FSM_S); // clear FSM
113
+ SET_PERI_REG_BITS (SENS_SAR_MEAS_WAIT1_REG, SENS_SAR_AMP_WAIT1, 0x1 , SENS_SAR_AMP_WAIT1_S);
114
+ SET_PERI_REG_BITS (SENS_SAR_MEAS_WAIT1_REG, SENS_SAR_AMP_WAIT2, 0x1 , SENS_SAR_AMP_WAIT2_S);
115
+ SET_PERI_REG_BITS (SENS_SAR_MEAS_WAIT2_REG, SENS_SAR_AMP_WAIT3, 0x1 , SENS_SAR_AMP_WAIT3_S);
116
+ while (GET_PERI_REG_BITS2 (SENS_SAR_SLAVE_ADDR1_REG, 0x7 , SENS_MEAS_STATUS_S) != 0 ); // wait det_fsm==
117
+
118
+ initialized = true ;
119
+ }
120
+
121
+ void __analogSetPinAttenuation (uint8_t pin, uint8_t attenuation)
122
+ {
123
+ int8_t channel = digitalPinToAnalogChannel (pin);
124
+ if (channel < 0 || attenuation > 3 ){
125
+ return ;
126
+ }
127
+ __analogInit ();
128
+ if (channel > 7 ){
129
+ SET_PERI_REG_BITS (SENS_SAR_ATTEN2_REG, 3 , attenuation, ((channel - 10 ) * 2 ));
130
+ } else {
131
+ SET_PERI_REG_BITS (SENS_SAR_ATTEN1_REG, 3 , attenuation, (channel * 2 ));
132
+ }
133
+ }
134
+
135
+ bool IRAM_ATTR __adcAttachPin (uint8_t pin){
136
+
137
+ int8_t channel = digitalPinToAnalogChannel (pin);
138
+ if (channel < 0 ){
139
+ return false ;// not adc pin
140
+ }
141
+
142
+ int8_t pad = digitalPinToTouchChannel (pin);
143
+ if (pad >= 0 ){
144
+ uint32_t touch = READ_PERI_REG (SENS_SAR_TOUCH_ENABLE_REG);
145
+ if (touch & (1 << pad)){
146
+ touch &= ~((1 << (pad + SENS_TOUCH_PAD_OUTEN2_S))
147
+ | (1 << (pad + SENS_TOUCH_PAD_OUTEN1_S))
148
+ | (1 << (pad + SENS_TOUCH_PAD_WORKEN_S)));
149
+ WRITE_PERI_REG (SENS_SAR_TOUCH_ENABLE_REG, touch);
150
+ }
151
+ } else if (pin == 25 ){
152
+ CLEAR_PERI_REG_MASK (RTC_IO_PAD_DAC1_REG, RTC_IO_PDAC1_XPD_DAC | RTC_IO_PDAC1_DAC_XPD_FORCE); // stop dac1
153
+ } else if (pin == 26 ){
154
+ CLEAR_PERI_REG_MASK (RTC_IO_PAD_DAC2_REG, RTC_IO_PDAC2_XPD_DAC | RTC_IO_PDAC2_DAC_XPD_FORCE); // stop dac2
155
+ }
156
+
157
+ pinMode (pin, ANALOG);
158
+
159
+ __analogInit ();
160
+ return true ;
161
+ }
162
+
163
+ bool IRAM_ATTR __adcStart (uint8_t pin){
164
+
165
+ int8_t channel = digitalPinToAnalogChannel (pin);
166
+ if (channel < 0 ){
167
+ return false ;// not adc pin
168
+ }
169
+
170
+ if (channel > 9 ){
171
+ channel -= 10 ;
172
+ CLEAR_PERI_REG_MASK (SENS_SAR_MEAS_START2_REG, SENS_MEAS2_START_SAR_M);
173
+ SET_PERI_REG_BITS (SENS_SAR_MEAS_START2_REG, SENS_SAR2_EN_PAD, (1 << channel), SENS_SAR2_EN_PAD_S);
174
+ SET_PERI_REG_MASK (SENS_SAR_MEAS_START2_REG, SENS_MEAS2_START_SAR_M);
175
+ } else {
176
+ CLEAR_PERI_REG_MASK (SENS_SAR_MEAS_START1_REG, SENS_MEAS1_START_SAR_M);
177
+ SET_PERI_REG_BITS (SENS_SAR_MEAS_START1_REG, SENS_SAR1_EN_PAD, (1 << channel), SENS_SAR1_EN_PAD_S);
178
+ SET_PERI_REG_MASK (SENS_SAR_MEAS_START1_REG, SENS_MEAS1_START_SAR_M);
179
+ }
180
+ return true ;
181
+ }
182
+
183
+ bool IRAM_ATTR __adcBusy (uint8_t pin){
184
+
185
+ int8_t channel = digitalPinToAnalogChannel (pin);
186
+ if (channel < 0 ){
187
+ return false ;// not adc pin
188
+ }
189
+
190
+ if (channel > 7 ){
191
+ return (GET_PERI_REG_MASK (SENS_SAR_MEAS_START2_REG, SENS_MEAS2_DONE_SAR) == 0 );
192
+ }
193
+ return (GET_PERI_REG_MASK (SENS_SAR_MEAS_START1_REG, SENS_MEAS1_DONE_SAR) == 0 );
194
+ }
195
+
196
+ uint16_t IRAM_ATTR __adcEnd (uint8_t pin)
197
+ {
198
+
199
+ uint16_t value = 0 ;
200
+ int8_t channel = digitalPinToAnalogChannel (pin);
201
+ if (channel < 0 ){
202
+ return 0 ;// not adc pin
203
+ }
204
+ if (channel > 7 ){
205
+ while (GET_PERI_REG_MASK (SENS_SAR_MEAS_START2_REG, SENS_MEAS2_DONE_SAR) == 0 ); // wait for conversion
206
+ value = GET_PERI_REG_BITS2 (SENS_SAR_MEAS_START2_REG, SENS_MEAS2_DATA_SAR, SENS_MEAS2_DATA_SAR_S);
207
+ } else {
208
+ while (GET_PERI_REG_MASK (SENS_SAR_MEAS_START1_REG, SENS_MEAS1_DONE_SAR) == 0 ); // wait for conversion
209
+ value = GET_PERI_REG_BITS2 (SENS_SAR_MEAS_START1_REG, SENS_MEAS1_DATA_SAR, SENS_MEAS1_DATA_SAR_S);
210
+ }
211
+
212
+ // Shift result if necessary
213
+ uint8_t from = __analogWidth + 9 ;
214
+ if (from == __analogReturnedWidth) {
215
+ return value;
216
+ }
217
+ if (from > __analogReturnedWidth) {
218
+ return value >> (from - __analogReturnedWidth);
219
+ }
220
+ return value << (__analogReturnedWidth - from);
221
+ }
222
+
223
+ void __analogReadResolution (uint8_t bits)
224
+ {
225
+ if (!bits || bits > 16 ){
226
+ return ;
227
+ }
228
+ __analogSetWidth (bits); // hadware from 9 to 12
229
+ __analogReturnedWidth = bits; // software from 1 to 16
230
+ }
231
+
232
+ uint16_t IRAM_ATTR adcRead (uint8_t pin)
233
+ {
234
+ if (!__adcAttachPin (pin) || !__adcStart (pin)){
235
+ return 0 ;
236
+ }
237
+ return __adcEnd (pin);
238
+ }
239
+
240
+ #endif
0 commit comments