Open
Description
Hello! I've been exploring the espulp module with a project to read some analog sensors using the ULP and I believe I've hit a wall. As far as I'm able to tell, the ADCs have to be initialized from the main processor before they can be used by the ULP.
RISC-V:
ulp_riscv_adc_cfg_t cfg = {
.channel = EXAMPLE_ADC_CHANNEL,
.width = EXAMPLE_ADC_WIDTH,
.atten = EXAMPLE_ADC_ATTEN,
};
ESP_ERROR_CHECK(ulp_riscv_adc_init(&cfg));
FSM:
/* Configure ADC channel */
/* Note: when changing channel here, also change 'adc_channel' constant
in adc.S */
adc1_config_channel_atten(ADC1_CHANNEL_6, ADC_ATTEN_DB_11);
#if CONFIG_IDF_TARGET_ESP32
adc1_config_width(ADC_WIDTH_BIT_12);
#elif CONFIG_IDF_TARGET_ESP32S2
adc1_config_width(ADC_WIDTH_BIT_13);
#endif
adc1_ulp_enable();
I'd be happy to work on a PR to add this functionality. The API I have in mind is:
ulp = espulp.ULP()
ulp.run(code, adc_pin=board.IO11)
I think it makes sense to limit the ULP to using a single pin on ADC1 because:
- Wi-Fi interferes with ADC2. Trying to manage this seems like complexity that is outside of the scope of CircuitPython, but I could be wrong.
- AFAICT, the ADC needs to be configured on a per-channel basis with each pin using a different channel, and the ULP is unable to re-calibrate the ADC. This means if multiple pins were used by the ULP, only the last one configured will be accurate (this is my understanding of the code, at least)