4141#include "freertos/semphr.h"
4242#include "driver/adc.h"
4343
44- //#define DEBUG_ANALOGBUFIO
44+ // #define DEBUG_ANALOGBUFIO
4545
4646#define NUM_SAMPLES_PER_INTERRUPT 256
4747#define NUM_ADC_CHANNELS 1
48- #define DMA_BUFFER_SIZE 1024
48+ #define DMA_BUFFER_SIZE 1024
4949#define ATTENUATION ADC_ATTEN_DB_0
5050#define ADC_READ_TIMEOUT_MS 2000
5151
5252#if defined(CONFIG_IDF_TARGET_ESP32 )
5353#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
5555#elif defined(CONFIG_IDF_TARGET_ESP32S2 )
5656#define ADC_RESULT_BYTE 2
5757#define ADC_CONV_LIMIT_EN 0
@@ -71,12 +71,8 @@ void common_hal_analogbufio_bufferedin_construct(analogbufio_bufferedin_obj_t *s
7171 uint16_t adc1_chan_mask = 0 ;
7272 uint16_t adc2_chan_mask = 0 ;
7373
74- if ( self -> pin != NULL ) {
75- mp_raise_ValueError (translate ("ADC DMA already initialized" ));
76- }
77-
7874 output_format = ADC_DIGI_OUTPUT_FORMAT_TYPE1 ;
79- if (pin -> adc_index == ADC_UNIT_1 ) {
75+ if (pin -> adc_index == ADC_UNIT_1 ) {
8076 convert_mode = ADC_CONV_SINGLE_UNIT_1 ;
8177 } else {
8278 convert_mode = ADC_CONV_SINGLE_UNIT_2 ;
@@ -90,34 +86,37 @@ void common_hal_analogbufio_bufferedin_construct(analogbufio_bufferedin_obj_t *s
9086
9187 /*
9288 * 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
9894 */
9995
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 ();
103104 }
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 */
109109 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 )
110113 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
116115
117116 self -> pin = pin ;
118117 common_hal_mcu_pin_claim (pin );
119118
120- if (pin -> adc_index == ADC_UNIT_1 ) {
119+ if (pin -> adc_index == ADC_UNIT_1 ) {
121120 adc1_chan_mask = 1 << pin -> adc_channel ;
122121 } else {
123122 adc2_chan_mask = 1 << pin -> adc_channel ;
@@ -130,11 +129,11 @@ void common_hal_analogbufio_bufferedin_construct(analogbufio_bufferedin_obj_t *s
130129 .adc2_chan_mask = adc2_chan_mask ,
131130 };
132131
133- #if defined(DEBUG_ANALOGBUFIO )
132+ #if defined(DEBUG_ANALOGBUFIO )
134133 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
136135 esp_err_t err = adc_digi_initialize (& adc_dma_config );
137- if (ESP_OK != err ) {
136+ if (ESP_OK != err ) {
138137 common_hal_analogbufio_bufferedin_deinit (self );
139138 mp_raise_ValueError_varg (translate ("Unable to initialize ADC DMA controller, ErrorCode:%d" ),err );
140139 }
@@ -148,32 +147,32 @@ void common_hal_analogbufio_bufferedin_construct(analogbufio_bufferedin_obj_t *s
148147 .format = output_format ,
149148 };
150149
151- #if defined(DEBUG_ANALOGBUFIO )
150+ #if defined(DEBUG_ANALOGBUFIO )
152151 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
154153
155154 adc_digi_pattern_config_t adc_pattern [NUM_ADC_CHANNELS ] = {0 };
156155 adc_pattern [0 ].atten = ATTENUATION ;
157156 adc_pattern [0 ].channel = pin -> adc_channel ;
158- if (pin -> adc_index == ADC_UNIT_1 ) {
157+ if (pin -> adc_index == ADC_UNIT_1 ) {
159158 adc_pattern [0 ].unit = 0 ;
160159 } else {
161160 adc_pattern [0 ].unit = 1 ;
162161 }
163162 adc_pattern [0 ].bit_width = SOC_ADC_DIGI_MAX_BITWIDTH ;
164163
165164 dig_cfg .adc_pattern = adc_pattern ;
166- #if defined(DEBUG_ANALOGBUFIO )
165+ #if defined(DEBUG_ANALOGBUFIO )
167166 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
169168
170169 err = adc_digi_controller_configure (& dig_cfg );
171- if (ESP_OK != err ) {
170+ if (ESP_OK != err ) {
172171 common_hal_analogbufio_bufferedin_deinit (self );
173172 mp_raise_ValueError_varg (translate ("Unable to configure ADC DMA controller, ErrorCode:%d" ),err );
174173 }
175174 err = adc_digi_start ();
176- if (ESP_OK != err ) {
175+ if (ESP_OK != err ) {
177176 common_hal_analogbufio_bufferedin_deinit (self );
178177 mp_raise_ValueError_varg (translate ("Unable to start ADC DMA controller, ErrorCode:%d" ),err );
179178 }
@@ -196,88 +195,94 @@ void common_hal_analogbufio_bufferedin_deinit(analogbufio_bufferedin_obj_t *self
196195 self -> pin = NULL ;
197196}
198197
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 ) {
201199 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+ }
205207 } else {
206- if ( convert_mode == ADC_CONV_SINGLE_UNIT_1 ) {
208+ if ( convert_mode == ADC_CONV_SINGLE_UNIT_1 ) {
207209 unit = 0 ;
208210 } else {
209211 unit = 1 ;
210212 }
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;
213224 }
214- if (unit > 2 ) return false;
215225 return true;
216226}
217227
218-
219228uint32_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 };
221230 uint32_t captured_samples = 0 ;
222231 uint32_t captured_bytes = 0 ;
223232 esp_err_t ret ;
224233 uint32_t ret_num = 0 ;
225234
226- #if defined(DEBUG_ANALOGBUFIO )
235+ #if defined(DEBUG_ANALOGBUFIO )
227236 mp_printf (& mp_plat_print ,"Required bytes: %d\n" ,len );
228- #endif //DEBUG_ANALOGBUFIO
237+ #endif // DEBUG_ANALOGBUFIO
229238
230239 while (captured_bytes < len ) {
231240 ret_num = 0 ;
232241 ret = adc_digi_read_bytes (result , NUM_SAMPLES_PER_INTERRUPT , & ret_num , ADC_READ_TIMEOUT_MS );
233242
234243 if (ret == ESP_OK ) {
235244 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
244253 } 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 ;
250255 }
251- captured_bytes += ADC_RESULT_BYTE ;
256+ captured_bytes += sizeof ( uint16_t ) ;
252257 captured_samples ++ ;
253258 } else {
254259 return captured_samples ;
255260 }
256261 } 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
264268 return captured_samples ;
265- }
269+ #endif
270+ }
266271 }
267272 } else if (ret == ESP_ERR_TIMEOUT ) {
268- #if defined(DEBUG_ANALOGBUFIO )
273+ #if defined(DEBUG_ANALOGBUFIO )
269274 mp_printf (& mp_plat_print ,"ADC Timeout\n" );
270- #endif //DEBUG_ANALOGBUFIO
275+ #endif // DEBUG_ANALOGBUFIO
271276 return captured_samples ;
272277 } else {
273- #if defined(DEBUG_ANALOGBUFIO )
278+ #if defined(DEBUG_ANALOGBUFIO )
274279 mp_printf (& mp_plat_print ,"adc_digi_read_bytes failed error code:%d\n" ,ret );
275- #endif //DEBUG_ANALOGBUFIO
280+ #endif // DEBUG_ANALOGBUFIO
276281 return captured_samples ;
277282 }
278283 }
279- #if defined(DEBUG_ANALOGBUFIO )
284+ #if defined(DEBUG_ANALOGBUFIO )
280285 mp_printf (& mp_plat_print ,"Captured bytes: %d\n" ,captured_bytes );
281- #endif //DEBUG_ANALOGBUFIO
286+ #endif // DEBUG_ANALOGBUFIO
282287 return captured_samples ;
283288}
0 commit comments