41
41
#include "freertos/semphr.h"
42
42
#include "driver/adc.h"
43
43
44
- //#define DEBUG_ANALOGBUFIO
44
+ // #define DEBUG_ANALOGBUFIO
45
45
46
46
#define NUM_SAMPLES_PER_INTERRUPT 256
47
47
#define NUM_ADC_CHANNELS 1
48
- #define DMA_BUFFER_SIZE 1024
48
+ #define DMA_BUFFER_SIZE 1024
49
49
#define ATTENUATION ADC_ATTEN_DB_0
50
50
#define ADC_READ_TIMEOUT_MS 2000
51
51
52
52
#if defined(CONFIG_IDF_TARGET_ESP32 )
53
53
#define ADC_RESULT_BYTE 2
54
- #define ADC_CONV_LIMIT_EN 1 //For ESP32, this should always be set to 1
54
+ #define ADC_CONV_LIMIT_EN 1 // For ESP32, this should always be set to 1
55
55
#elif defined(CONFIG_IDF_TARGET_ESP32S2 )
56
56
#define ADC_RESULT_BYTE 2
57
57
#define ADC_CONV_LIMIT_EN 0
@@ -71,12 +71,8 @@ void common_hal_analogbufio_bufferedin_construct(analogbufio_bufferedin_obj_t *s
71
71
uint16_t adc1_chan_mask = 0 ;
72
72
uint16_t adc2_chan_mask = 0 ;
73
73
74
- if ( self -> pin != NULL ) {
75
- mp_raise_ValueError (translate ("ADC DMA already initialized" ));
76
- }
77
-
78
74
output_format = ADC_DIGI_OUTPUT_FORMAT_TYPE1 ;
79
- if (pin -> adc_index == ADC_UNIT_1 ) {
75
+ if (pin -> adc_index == ADC_UNIT_1 ) {
80
76
convert_mode = ADC_CONV_SINGLE_UNIT_1 ;
81
77
} else {
82
78
convert_mode = ADC_CONV_SINGLE_UNIT_2 ;
@@ -90,34 +86,37 @@ void common_hal_analogbufio_bufferedin_construct(analogbufio_bufferedin_obj_t *s
90
86
91
87
/*
92
88
* Chip version Conversion Mode Output Format Type
93
- * ESP32 1 TYPE1
94
- * ESP32S2 1,2,BOTH,ALTER TYPE1, TYPE2
95
- * ESP32C3 ALTER TYPE2
96
- * ESP32S3 1,2,BOTH,ALTER TYPE2
97
- * ESP32H3 1,2,BOTH,ALTER TYPE2
89
+ * ESP32 1 TYPE1
90
+ * ESP32S2 1,2,BOTH,ALTER TYPE1, TYPE2
91
+ * ESP32C3 ALTER TYPE2
92
+ * ESP32S3 1,2,BOTH,ALTER TYPE2
93
+ * ESP32H3 1,2,BOTH,ALTER TYPE2
98
94
*/
99
95
100
- #if defined(CONFIG_IDF_TARGET_ESP32 )
101
- if (pin -> adc_index != ADC_UNIT_1 ) {
102
- mp_raise_ValueError (translate ("ESP32 only supports ADC1 unit" ));
96
+ #if defined(CONFIG_IDF_TARGET_ESP32 )
97
+ if (pin -> adc_index != ADC_UNIT_1 ) {
98
+ /*
99
+ * ESP32 only supports ADC1 unit
100
+ * https://www.espressif.com/sites/default/files/documentation/esp32_technical_reference_manual_en.pdf
101
+ * Table 29-3
102
+ */
103
+ raise_ValueError_invalid_pin ();
103
104
}
104
- #endif
105
- #if defined(CONFIG_IDF_TARGET_ESP32S2 )
106
- #endif
107
- #if defined(CONFIG_IDF_TARGET_ESP32C3 )
108
- //ESP32C3 only supports alter mode
105
+ #endif
106
+
107
+ #if defined(CONFIG_IDF_TARGET_ESP32C3 )
108
+ /* ESP32C3 only supports alter mode */
109
109
convert_mode = ADC_CONV_ALTER_UNIT ;
110
+ #endif
111
+
112
+ #if defined(CONFIG_IDF_TARGET_ESP32C3 ) || defined(CONFIG_IDF_TARGET_ESP32S3 ) || defined(CONFIG_IDF_TARGET_ESP32H2 )
110
113
output_format = ADC_DIGI_OUTPUT_FORMAT_TYPE2 ;
111
- #endif
112
- #if defined(CONFIG_IDF_TARGET_ESP32S3 )
113
- #endif
114
- #if defined(CONFIG_IDF_TARGET_ESP32H2 )
115
- #endif
114
+ #endif
116
115
117
116
self -> pin = pin ;
118
117
common_hal_mcu_pin_claim (pin );
119
118
120
- if (pin -> adc_index == ADC_UNIT_1 ) {
119
+ if (pin -> adc_index == ADC_UNIT_1 ) {
121
120
adc1_chan_mask = 1 << pin -> adc_channel ;
122
121
} else {
123
122
adc2_chan_mask = 1 << pin -> adc_channel ;
@@ -130,11 +129,11 @@ void common_hal_analogbufio_bufferedin_construct(analogbufio_bufferedin_obj_t *s
130
129
.adc2_chan_mask = adc2_chan_mask ,
131
130
};
132
131
133
- #if defined(DEBUG_ANALOGBUFIO )
132
+ #if defined(DEBUG_ANALOGBUFIO )
134
133
mp_printf (& mp_plat_print ,"pin:%d, ADC channel:%d, ADC index:%d, adc1_chan_mask:0x%x, adc2_chan_mask:0x%x\n" ,pin -> number ,pin -> adc_channel ,pin -> adc_index ,adc1_chan_mask ,adc2_chan_mask );
135
- #endif //DEBUG_ANALOGBUFIO
134
+ #endif // DEBUG_ANALOGBUFIO
136
135
esp_err_t err = adc_digi_initialize (& adc_dma_config );
137
- if (ESP_OK != err ) {
136
+ if (ESP_OK != err ) {
138
137
common_hal_analogbufio_bufferedin_deinit (self );
139
138
mp_raise_ValueError_varg (translate ("Unable to initialize ADC DMA controller, ErrorCode:%d" ),err );
140
139
}
@@ -148,32 +147,32 @@ void common_hal_analogbufio_bufferedin_construct(analogbufio_bufferedin_obj_t *s
148
147
.format = output_format ,
149
148
};
150
149
151
- #if defined(DEBUG_ANALOGBUFIO )
150
+ #if defined(DEBUG_ANALOGBUFIO )
152
151
mp_printf (& mp_plat_print ,"conversion_mode:%d, format:%d, conv_limit_en:%d, sample_rate:%d\n" ,convert_mode ,output_format ,ADC_CONV_LIMIT_EN ,sample_rate );
153
- #endif //DEBUG_ANALOGBUFIO
152
+ #endif // DEBUG_ANALOGBUFIO
154
153
155
154
adc_digi_pattern_config_t adc_pattern [NUM_ADC_CHANNELS ] = {0 };
156
155
adc_pattern [0 ].atten = ATTENUATION ;
157
156
adc_pattern [0 ].channel = pin -> adc_channel ;
158
- if (pin -> adc_index == ADC_UNIT_1 ) {
157
+ if (pin -> adc_index == ADC_UNIT_1 ) {
159
158
adc_pattern [0 ].unit = 0 ;
160
159
} else {
161
160
adc_pattern [0 ].unit = 1 ;
162
161
}
163
162
adc_pattern [0 ].bit_width = SOC_ADC_DIGI_MAX_BITWIDTH ;
164
163
165
164
dig_cfg .adc_pattern = adc_pattern ;
166
- #if defined(DEBUG_ANALOGBUFIO )
165
+ #if defined(DEBUG_ANALOGBUFIO )
167
166
mp_printf (& mp_plat_print ,"adc_pattern[0].channel:%d, adc_pattern[0].unit:%d, adc_pattern[0].atten:%d\n" ,adc_pattern [0 ].channel ,adc_pattern [0 ].unit ,adc_pattern [0 ].atten );
168
- #endif //DEBUG_ANALOGBUFIO
167
+ #endif // DEBUG_ANALOGBUFIO
169
168
170
169
err = adc_digi_controller_configure (& dig_cfg );
171
- if (ESP_OK != err ) {
170
+ if (ESP_OK != err ) {
172
171
common_hal_analogbufio_bufferedin_deinit (self );
173
172
mp_raise_ValueError_varg (translate ("Unable to configure ADC DMA controller, ErrorCode:%d" ),err );
174
173
}
175
174
err = adc_digi_start ();
176
- if (ESP_OK != err ) {
175
+ if (ESP_OK != err ) {
177
176
common_hal_analogbufio_bufferedin_deinit (self );
178
177
mp_raise_ValueError_varg (translate ("Unable to start ADC DMA controller, ErrorCode:%d" ),err );
179
178
}
@@ -196,88 +195,94 @@ void common_hal_analogbufio_bufferedin_deinit(analogbufio_bufferedin_obj_t *self
196
195
self -> pin = NULL ;
197
196
}
198
197
199
- static bool check_valid_data (const adc_digi_output_data_t * data )
200
- {
198
+ static bool check_valid_data (const adc_digi_output_data_t * data ) {
201
199
unsigned int unit = data -> type2 .unit ;
202
- if (output_format == ADC_DIGI_OUTPUT_FORMAT_TYPE2 ) {
203
- if (data -> type2 .channel >= SOC_ADC_CHANNEL_NUM (unit )) return false;
204
- if (adc_channel != data -> type2 .channel ) return false;
200
+ if (output_format == ADC_DIGI_OUTPUT_FORMAT_TYPE2 ) {
201
+ if (data -> type2 .channel >= SOC_ADC_CHANNEL_NUM (unit )) {
202
+ return false;
203
+ }
204
+ if (adc_channel != data -> type2 .channel ) {
205
+ return false;
206
+ }
205
207
} else {
206
- if ( convert_mode == ADC_CONV_SINGLE_UNIT_1 ) {
208
+ if ( convert_mode == ADC_CONV_SINGLE_UNIT_1 ) {
207
209
unit = 0 ;
208
210
} else {
209
211
unit = 1 ;
210
212
}
211
- if (data -> type1 .channel >= SOC_ADC_CHANNEL_NUM (unit )) return false;
212
- if (adc_channel != data -> type1 .channel ) return false;
213
+ #if defined(CONFIG_IDF_TARGET_ESP32 ) || defined(CONFIG_IDF_TARGET_ESP32S2 )
214
+ if (data -> type1 .channel >= SOC_ADC_CHANNEL_NUM (unit )) {
215
+ return false;
216
+ }
217
+ if (adc_channel != data -> type1 .channel ) {
218
+ return false;
219
+ }
220
+ #endif
221
+ }
222
+ if (unit > 2 ) {
223
+ return false;
213
224
}
214
- if (unit > 2 ) return false;
215
225
return true;
216
226
}
217
227
218
-
219
228
uint32_t common_hal_analogbufio_bufferedin_readinto (analogbufio_bufferedin_obj_t * self , uint8_t * buffer , uint32_t len , uint8_t bytes_per_sample ) {
220
- uint8_t result [NUM_SAMPLES_PER_INTERRUPT ] __attribute__ ((aligned (4 ))) = {0 };
229
+ uint8_t result [NUM_SAMPLES_PER_INTERRUPT ] __attribute__ ((aligned (4 ))) = {0 };
221
230
uint32_t captured_samples = 0 ;
222
231
uint32_t captured_bytes = 0 ;
223
232
esp_err_t ret ;
224
233
uint32_t ret_num = 0 ;
225
234
226
- #if defined(DEBUG_ANALOGBUFIO )
235
+ #if defined(DEBUG_ANALOGBUFIO )
227
236
mp_printf (& mp_plat_print ,"Required bytes: %d\n" ,len );
228
- #endif //DEBUG_ANALOGBUFIO
237
+ #endif // DEBUG_ANALOGBUFIO
229
238
230
239
while (captured_bytes < len ) {
231
240
ret_num = 0 ;
232
241
ret = adc_digi_read_bytes (result , NUM_SAMPLES_PER_INTERRUPT , & ret_num , ADC_READ_TIMEOUT_MS );
233
242
234
243
if (ret == ESP_OK ) {
235
244
for (uint32_t i = 0 ; i < ret_num ; i += ADC_RESULT_BYTE ) {
236
- if ( check_valid_data (( adc_digi_output_data_t * ) (void * )& result [i ])) {
237
- if ( captured_bytes < len ) {
238
- if ( ADC_RESULT_BYTE == 2 ) {
239
- if ( output_format == ADC_DIGI_OUTPUT_FORMAT_TYPE1 ) {
240
- * ( uint16_t * )( void * ) & buffer [ captured_bytes ] = (( adc_digi_output_data_t * ) ( void * ) & result [ i ]) -> type1 . data ;
241
- } else {
242
- * ( uint16_t * )( void * ) & buffer [ captured_bytes ] = (( adc_digi_output_data_t * ) ( void * ) & result [ i ]) -> type2 .data ;
243
- }
245
+ adc_digi_output_data_t * pResult = ( adc_digi_output_data_t * ) (void * )& result [i ];
246
+ if ( check_valid_data ( pResult ) ) {
247
+ if ( captured_bytes < len ) {
248
+ uint16_t * pBuffer = ( uint16_t * )( void * ) & buffer [ captured_bytes ];
249
+ if ( output_format == ADC_DIGI_OUTPUT_FORMAT_TYPE1 ) {
250
+ #if defined( CONFIG_IDF_TARGET_ESP32 ) || defined( CONFIG_IDF_TARGET_ESP32S2 )
251
+ * pBuffer = pResult -> type1 .data ;
252
+ #endif
244
253
} else {
245
- if (output_format == ADC_DIGI_OUTPUT_FORMAT_TYPE1 ) {
246
- * (uint32_t * )(void * )& buffer [captured_bytes ] = ((adc_digi_output_data_t * ) (void * )& result [i ])-> type1 .data ;
247
- } else {
248
- * (uint32_t * )(void * )& buffer [captured_bytes ] = ((adc_digi_output_data_t * ) (void * )& result [i ])-> type2 .data ;
249
- }
254
+ * pBuffer = pResult -> type2 .data ;
250
255
}
251
- captured_bytes += ADC_RESULT_BYTE ;
256
+ captured_bytes += sizeof ( uint16_t ) ;
252
257
captured_samples ++ ;
253
258
} else {
254
259
return captured_samples ;
255
260
}
256
261
} else {
257
- #if defined(DEBUG_ANALOGBUFIO )
258
- if (ADC_RESULT_BYTE == 2 ) {
259
- mp_printf (& mp_plat_print ,"Invalid sample received: 0x%0x\n" ,* (uint16_t * )(void * )& result [i ]);
260
- } else {
261
- mp_printf (& mp_plat_print ,"Invalid sample received: 0x%0x\n" ,* (uint32_t * )(void * )& result [i ]);
262
- }
263
- #endif //DEBUG_ANALOGBUFIO
262
+ #if !defined(CONFIG_IDF_TARGET_ESP32C3 )
263
+ // For all chips except for ESP32C3 we would receive samples only from one unit
264
+ // For ESP32C3 we may receive sample from alternating units and need to ignore them
265
+ #if defined(DEBUG_ANALOGBUFIO )
266
+ mp_printf (& mp_plat_print ,"Invalid sample received: 0x%x\n" ,pResult -> val );
267
+ #endif // DEBUG_ANALOGBUFIO
264
268
return captured_samples ;
265
- }
269
+ #endif
270
+ }
266
271
}
267
272
} else if (ret == ESP_ERR_TIMEOUT ) {
268
- #if defined(DEBUG_ANALOGBUFIO )
273
+ #if defined(DEBUG_ANALOGBUFIO )
269
274
mp_printf (& mp_plat_print ,"ADC Timeout\n" );
270
- #endif //DEBUG_ANALOGBUFIO
275
+ #endif // DEBUG_ANALOGBUFIO
271
276
return captured_samples ;
272
277
} else {
273
- #if defined(DEBUG_ANALOGBUFIO )
278
+ #if defined(DEBUG_ANALOGBUFIO )
274
279
mp_printf (& mp_plat_print ,"adc_digi_read_bytes failed error code:%d\n" ,ret );
275
- #endif //DEBUG_ANALOGBUFIO
280
+ #endif // DEBUG_ANALOGBUFIO
276
281
return captured_samples ;
277
282
}
278
283
}
279
- #if defined(DEBUG_ANALOGBUFIO )
284
+ #if defined(DEBUG_ANALOGBUFIO )
280
285
mp_printf (& mp_plat_print ,"Captured bytes: %d\n" ,captured_bytes );
281
- #endif //DEBUG_ANALOGBUFIO
286
+ #endif // DEBUG_ANALOGBUFIO
282
287
return captured_samples ;
283
288
}
0 commit comments