Pre-commit: Done the formatting changes
Pre-commit: Fixed compilation error for other ESP32C3/ESP32S3/ESP32H2 boards Review comment: Removed the self->pin NULL check Review comment: Using raise_ValueError_invalid_pin when adc_index is not ADC_UNIT1 for ESP32 Review comment: Optimized the code to set data in buffer from DMA results Fix: For ESP32C3 boards continuing collecting samples after channel mismatch as DMA runs in alternating UNIT mode Fix: For ESP32S3 and ESP32H2 setting conversion mode to type2
This commit is contained in:
parent
58532ece3f
commit
ead5751803
@ -41,7 +41,7 @@
|
|||||||
#include "freertos/semphr.h"
|
#include "freertos/semphr.h"
|
||||||
#include "driver/adc.h"
|
#include "driver/adc.h"
|
||||||
|
|
||||||
//#define DEBUG_ANALOGBUFIO
|
// #define DEBUG_ANALOGBUFIO
|
||||||
|
|
||||||
#define NUM_SAMPLES_PER_INTERRUPT 256
|
#define NUM_SAMPLES_PER_INTERRUPT 256
|
||||||
#define NUM_ADC_CHANNELS 1
|
#define NUM_ADC_CHANNELS 1
|
||||||
@ -51,7 +51,7 @@
|
|||||||
|
|
||||||
#if defined(CONFIG_IDF_TARGET_ESP32)
|
#if defined(CONFIG_IDF_TARGET_ESP32)
|
||||||
#define ADC_RESULT_BYTE 2
|
#define ADC_RESULT_BYTE 2
|
||||||
#define ADC_CONV_LIMIT_EN 1 //For ESP32, this should always be set to 1
|
#define ADC_CONV_LIMIT_EN 1 // For ESP32, this should always be set to 1
|
||||||
#elif defined(CONFIG_IDF_TARGET_ESP32S2)
|
#elif defined(CONFIG_IDF_TARGET_ESP32S2)
|
||||||
#define ADC_RESULT_BYTE 2
|
#define ADC_RESULT_BYTE 2
|
||||||
#define ADC_CONV_LIMIT_EN 0
|
#define ADC_CONV_LIMIT_EN 0
|
||||||
@ -71,12 +71,8 @@ void common_hal_analogbufio_bufferedin_construct(analogbufio_bufferedin_obj_t *s
|
|||||||
uint16_t adc1_chan_mask = 0;
|
uint16_t adc1_chan_mask = 0;
|
||||||
uint16_t adc2_chan_mask = 0;
|
uint16_t adc2_chan_mask = 0;
|
||||||
|
|
||||||
if( self->pin != NULL) {
|
|
||||||
mp_raise_ValueError(translate("ADC DMA already initialized"));
|
|
||||||
}
|
|
||||||
|
|
||||||
output_format = ADC_DIGI_OUTPUT_FORMAT_TYPE1;
|
output_format = ADC_DIGI_OUTPUT_FORMAT_TYPE1;
|
||||||
if(pin->adc_index == ADC_UNIT_1) {
|
if (pin->adc_index == ADC_UNIT_1) {
|
||||||
convert_mode = ADC_CONV_SINGLE_UNIT_1;
|
convert_mode = ADC_CONV_SINGLE_UNIT_1;
|
||||||
} else {
|
} else {
|
||||||
convert_mode = ADC_CONV_SINGLE_UNIT_2;
|
convert_mode = ADC_CONV_SINGLE_UNIT_2;
|
||||||
@ -97,27 +93,30 @@ void common_hal_analogbufio_bufferedin_construct(analogbufio_bufferedin_obj_t *s
|
|||||||
* ESP32H3 1,2,BOTH,ALTER TYPE2
|
* ESP32H3 1,2,BOTH,ALTER TYPE2
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#if defined(CONFIG_IDF_TARGET_ESP32)
|
#if defined(CONFIG_IDF_TARGET_ESP32)
|
||||||
if(pin->adc_index != ADC_UNIT_1) {
|
if (pin->adc_index != ADC_UNIT_1) {
|
||||||
mp_raise_ValueError(translate("ESP32 only supports ADC1 unit"));
|
/*
|
||||||
|
* ESP32 only supports ADC1 unit
|
||||||
|
* https://www.espressif.com/sites/default/files/documentation/esp32_technical_reference_manual_en.pdf
|
||||||
|
* Table 29-3
|
||||||
|
*/
|
||||||
|
raise_ValueError_invalid_pin();
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
#if defined(CONFIG_IDF_TARGET_ESP32S2)
|
|
||||||
#endif
|
#if defined(CONFIG_IDF_TARGET_ESP32C3)
|
||||||
#if defined(CONFIG_IDF_TARGET_ESP32C3)
|
/* ESP32C3 only supports alter mode */
|
||||||
//ESP32C3 only supports alter mode
|
|
||||||
convert_mode = ADC_CONV_ALTER_UNIT;
|
convert_mode = ADC_CONV_ALTER_UNIT;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(CONFIG_IDF_TARGET_ESP32C3) || defined(CONFIG_IDF_TARGET_ESP32S3) || defined(CONFIG_IDF_TARGET_ESP32H2)
|
||||||
output_format = ADC_DIGI_OUTPUT_FORMAT_TYPE2;
|
output_format = ADC_DIGI_OUTPUT_FORMAT_TYPE2;
|
||||||
#endif
|
#endif
|
||||||
#if defined(CONFIG_IDF_TARGET_ESP32S3)
|
|
||||||
#endif
|
|
||||||
#if defined(CONFIG_IDF_TARGET_ESP32H2)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
self->pin = pin;
|
self->pin = pin;
|
||||||
common_hal_mcu_pin_claim(pin);
|
common_hal_mcu_pin_claim(pin);
|
||||||
|
|
||||||
if(pin->adc_index == ADC_UNIT_1) {
|
if (pin->adc_index == ADC_UNIT_1) {
|
||||||
adc1_chan_mask = 1 << pin->adc_channel;
|
adc1_chan_mask = 1 << pin->adc_channel;
|
||||||
} else {
|
} else {
|
||||||
adc2_chan_mask = 1 << pin->adc_channel;
|
adc2_chan_mask = 1 << pin->adc_channel;
|
||||||
@ -130,11 +129,11 @@ void common_hal_analogbufio_bufferedin_construct(analogbufio_bufferedin_obj_t *s
|
|||||||
.adc2_chan_mask = adc2_chan_mask,
|
.adc2_chan_mask = adc2_chan_mask,
|
||||||
};
|
};
|
||||||
|
|
||||||
#if defined(DEBUG_ANALOGBUFIO)
|
#if defined(DEBUG_ANALOGBUFIO)
|
||||||
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);
|
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);
|
||||||
#endif //DEBUG_ANALOGBUFIO
|
#endif // DEBUG_ANALOGBUFIO
|
||||||
esp_err_t err = adc_digi_initialize(&adc_dma_config);
|
esp_err_t err = adc_digi_initialize(&adc_dma_config);
|
||||||
if(ESP_OK != err) {
|
if (ESP_OK != err) {
|
||||||
common_hal_analogbufio_bufferedin_deinit(self);
|
common_hal_analogbufio_bufferedin_deinit(self);
|
||||||
mp_raise_ValueError_varg(translate("Unable to initialize ADC DMA controller, ErrorCode:%d"),err);
|
mp_raise_ValueError_varg(translate("Unable to initialize ADC DMA controller, ErrorCode:%d"),err);
|
||||||
}
|
}
|
||||||
@ -148,14 +147,14 @@ void common_hal_analogbufio_bufferedin_construct(analogbufio_bufferedin_obj_t *s
|
|||||||
.format = output_format,
|
.format = output_format,
|
||||||
};
|
};
|
||||||
|
|
||||||
#if defined(DEBUG_ANALOGBUFIO)
|
#if defined(DEBUG_ANALOGBUFIO)
|
||||||
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);
|
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);
|
||||||
#endif //DEBUG_ANALOGBUFIO
|
#endif // DEBUG_ANALOGBUFIO
|
||||||
|
|
||||||
adc_digi_pattern_config_t adc_pattern[NUM_ADC_CHANNELS] = {0};
|
adc_digi_pattern_config_t adc_pattern[NUM_ADC_CHANNELS] = {0};
|
||||||
adc_pattern[0].atten = ATTENUATION;
|
adc_pattern[0].atten = ATTENUATION;
|
||||||
adc_pattern[0].channel = pin->adc_channel;
|
adc_pattern[0].channel = pin->adc_channel;
|
||||||
if(pin->adc_index == ADC_UNIT_1) {
|
if (pin->adc_index == ADC_UNIT_1) {
|
||||||
adc_pattern[0].unit = 0;
|
adc_pattern[0].unit = 0;
|
||||||
} else {
|
} else {
|
||||||
adc_pattern[0].unit = 1;
|
adc_pattern[0].unit = 1;
|
||||||
@ -163,17 +162,17 @@ void common_hal_analogbufio_bufferedin_construct(analogbufio_bufferedin_obj_t *s
|
|||||||
adc_pattern[0].bit_width = SOC_ADC_DIGI_MAX_BITWIDTH;
|
adc_pattern[0].bit_width = SOC_ADC_DIGI_MAX_BITWIDTH;
|
||||||
|
|
||||||
dig_cfg.adc_pattern = adc_pattern;
|
dig_cfg.adc_pattern = adc_pattern;
|
||||||
#if defined(DEBUG_ANALOGBUFIO)
|
#if defined(DEBUG_ANALOGBUFIO)
|
||||||
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);
|
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);
|
||||||
#endif //DEBUG_ANALOGBUFIO
|
#endif // DEBUG_ANALOGBUFIO
|
||||||
|
|
||||||
err = adc_digi_controller_configure(&dig_cfg);
|
err = adc_digi_controller_configure(&dig_cfg);
|
||||||
if(ESP_OK != err) {
|
if (ESP_OK != err) {
|
||||||
common_hal_analogbufio_bufferedin_deinit(self);
|
common_hal_analogbufio_bufferedin_deinit(self);
|
||||||
mp_raise_ValueError_varg(translate("Unable to configure ADC DMA controller, ErrorCode:%d"),err);
|
mp_raise_ValueError_varg(translate("Unable to configure ADC DMA controller, ErrorCode:%d"),err);
|
||||||
}
|
}
|
||||||
err = adc_digi_start();
|
err = adc_digi_start();
|
||||||
if(ESP_OK != err) {
|
if (ESP_OK != err) {
|
||||||
common_hal_analogbufio_bufferedin_deinit(self);
|
common_hal_analogbufio_bufferedin_deinit(self);
|
||||||
mp_raise_ValueError_varg(translate("Unable to start ADC DMA controller, ErrorCode:%d"),err);
|
mp_raise_ValueError_varg(translate("Unable to start ADC DMA controller, ErrorCode:%d"),err);
|
||||||
}
|
}
|
||||||
@ -196,36 +195,46 @@ void common_hal_analogbufio_bufferedin_deinit(analogbufio_bufferedin_obj_t *self
|
|||||||
self->pin = NULL;
|
self->pin = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool check_valid_data(const adc_digi_output_data_t *data)
|
static bool check_valid_data(const adc_digi_output_data_t *data) {
|
||||||
{
|
|
||||||
unsigned int unit = data->type2.unit;
|
unsigned int unit = data->type2.unit;
|
||||||
if(output_format == ADC_DIGI_OUTPUT_FORMAT_TYPE2) {
|
if (output_format == ADC_DIGI_OUTPUT_FORMAT_TYPE2) {
|
||||||
if (data->type2.channel >= SOC_ADC_CHANNEL_NUM(unit)) return false;
|
if (data->type2.channel >= SOC_ADC_CHANNEL_NUM(unit)) {
|
||||||
if (adc_channel != data->type2.channel) return false;
|
return false;
|
||||||
|
}
|
||||||
|
if (adc_channel != data->type2.channel) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
if( convert_mode == ADC_CONV_SINGLE_UNIT_1 ) {
|
if ( convert_mode == ADC_CONV_SINGLE_UNIT_1 ) {
|
||||||
unit = 0;
|
unit = 0;
|
||||||
} else {
|
} else {
|
||||||
unit = 1;
|
unit = 1;
|
||||||
}
|
}
|
||||||
if (data->type1.channel >= SOC_ADC_CHANNEL_NUM(unit)) return false;
|
#if defined(CONFIG_IDF_TARGET_ESP32) || defined(CONFIG_IDF_TARGET_ESP32S2)
|
||||||
if (adc_channel != data->type1.channel) return false;
|
if (data->type1.channel >= SOC_ADC_CHANNEL_NUM(unit)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (adc_channel != data->type1.channel) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
if (unit > 2) {
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
if (unit > 2) return false;
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
uint32_t common_hal_analogbufio_bufferedin_readinto(analogbufio_bufferedin_obj_t *self, uint8_t *buffer, uint32_t len, uint8_t bytes_per_sample) {
|
uint32_t common_hal_analogbufio_bufferedin_readinto(analogbufio_bufferedin_obj_t *self, uint8_t *buffer, uint32_t len, uint8_t bytes_per_sample) {
|
||||||
uint8_t result[NUM_SAMPLES_PER_INTERRUPT] __attribute__ ((aligned (4))) = {0};
|
uint8_t result[NUM_SAMPLES_PER_INTERRUPT] __attribute__ ((aligned(4))) = {0};
|
||||||
uint32_t captured_samples = 0;
|
uint32_t captured_samples = 0;
|
||||||
uint32_t captured_bytes = 0;
|
uint32_t captured_bytes = 0;
|
||||||
esp_err_t ret;
|
esp_err_t ret;
|
||||||
uint32_t ret_num = 0;
|
uint32_t ret_num = 0;
|
||||||
|
|
||||||
#if defined(DEBUG_ANALOGBUFIO)
|
#if defined(DEBUG_ANALOGBUFIO)
|
||||||
mp_printf(&mp_plat_print,"Required bytes: %d\n",len);
|
mp_printf(&mp_plat_print,"Required bytes: %d\n",len);
|
||||||
#endif //DEBUG_ANALOGBUFIO
|
#endif // DEBUG_ANALOGBUFIO
|
||||||
|
|
||||||
while(captured_bytes < len) {
|
while(captured_bytes < len) {
|
||||||
ret_num = 0;
|
ret_num = 0;
|
||||||
@ -233,51 +242,47 @@ uint32_t common_hal_analogbufio_bufferedin_readinto(analogbufio_bufferedin_obj_t
|
|||||||
|
|
||||||
if (ret == ESP_OK) {
|
if (ret == ESP_OK) {
|
||||||
for(uint32_t i=0; i<ret_num; i+=ADC_RESULT_BYTE) {
|
for(uint32_t i=0; i<ret_num; i+=ADC_RESULT_BYTE) {
|
||||||
if(check_valid_data((adc_digi_output_data_t *) (void *)&result[i])) {
|
adc_digi_output_data_t *pResult = (adc_digi_output_data_t *) (void *)&result[i];
|
||||||
if(captured_bytes < len) {
|
if (check_valid_data(pResult)) {
|
||||||
if(ADC_RESULT_BYTE == 2) {
|
if (captured_bytes < len) {
|
||||||
if(output_format == ADC_DIGI_OUTPUT_FORMAT_TYPE1) {
|
uint16_t *pBuffer = (uint16_t *)(void *)&buffer[captured_bytes];
|
||||||
*(uint16_t *)(void *)&buffer[captured_bytes] = ((adc_digi_output_data_t *) (void *)&result[i])->type1.data;
|
if (output_format == ADC_DIGI_OUTPUT_FORMAT_TYPE1) {
|
||||||
|
#if defined(CONFIG_IDF_TARGET_ESP32) || defined(CONFIG_IDF_TARGET_ESP32S2)
|
||||||
|
*pBuffer = pResult->type1.data;
|
||||||
|
#endif
|
||||||
} else {
|
} else {
|
||||||
*(uint16_t *)(void *)&buffer[captured_bytes] = ((adc_digi_output_data_t *) (void *)&result[i])->type2.data;
|
*pBuffer = pResult->type2.data;
|
||||||
}
|
}
|
||||||
} else {
|
captured_bytes += sizeof(uint16_t);
|
||||||
if(output_format == ADC_DIGI_OUTPUT_FORMAT_TYPE1) {
|
|
||||||
*(uint32_t *)(void *)&buffer[captured_bytes] = ((adc_digi_output_data_t *) (void *)&result[i])->type1.data;
|
|
||||||
} else {
|
|
||||||
*(uint32_t *)(void *)&buffer[captured_bytes] = ((adc_digi_output_data_t *) (void *)&result[i])->type2.data;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
captured_bytes += ADC_RESULT_BYTE;
|
|
||||||
captured_samples++;
|
captured_samples++;
|
||||||
} else {
|
} else {
|
||||||
return captured_samples;
|
return captured_samples;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
#if defined(DEBUG_ANALOGBUFIO)
|
#if !defined(CONFIG_IDF_TARGET_ESP32C3)
|
||||||
if(ADC_RESULT_BYTE == 2) {
|
// For all chips except for ESP32C3 we would receive samples only from one unit
|
||||||
mp_printf(&mp_plat_print,"Invalid sample received: 0x%0x\n",*(uint16_t *)(void *)&result[i]);
|
// For ESP32C3 we may receive sample from alternating units and need to ignore them
|
||||||
} else {
|
#if defined(DEBUG_ANALOGBUFIO)
|
||||||
mp_printf(&mp_plat_print,"Invalid sample received: 0x%0x\n",*(uint32_t *)(void *)&result[i]);
|
mp_printf(&mp_plat_print,"Invalid sample received: 0x%x\n",pResult->val);
|
||||||
}
|
#endif // DEBUG_ANALOGBUFIO
|
||||||
#endif //DEBUG_ANALOGBUFIO
|
|
||||||
return captured_samples;
|
return captured_samples;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if (ret == ESP_ERR_TIMEOUT) {
|
} else if (ret == ESP_ERR_TIMEOUT) {
|
||||||
#if defined(DEBUG_ANALOGBUFIO)
|
#if defined(DEBUG_ANALOGBUFIO)
|
||||||
mp_printf(&mp_plat_print,"ADC Timeout\n");
|
mp_printf(&mp_plat_print,"ADC Timeout\n");
|
||||||
#endif //DEBUG_ANALOGBUFIO
|
#endif // DEBUG_ANALOGBUFIO
|
||||||
return captured_samples;
|
return captured_samples;
|
||||||
} else {
|
} else {
|
||||||
#if defined(DEBUG_ANALOGBUFIO)
|
#if defined(DEBUG_ANALOGBUFIO)
|
||||||
mp_printf(&mp_plat_print,"adc_digi_read_bytes failed error code:%d\n",ret);
|
mp_printf(&mp_plat_print,"adc_digi_read_bytes failed error code:%d\n",ret);
|
||||||
#endif //DEBUG_ANALOGBUFIO
|
#endif // DEBUG_ANALOGBUFIO
|
||||||
return captured_samples;
|
return captured_samples;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#if defined(DEBUG_ANALOGBUFIO)
|
#if defined(DEBUG_ANALOGBUFIO)
|
||||||
mp_printf(&mp_plat_print,"Captured bytes: %d\n",captured_bytes);
|
mp_printf(&mp_plat_print,"Captured bytes: %d\n",captured_bytes);
|
||||||
#endif //DEBUG_ANALOGBUFIO
|
#endif // DEBUG_ANALOGBUFIO
|
||||||
return captured_samples;
|
return captured_samples;
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user