Open urbanze opened 2 years ago
adc_digi_isr_register()
has been removed in IDF 4.4.
It can be found only with IDF 4.2 and 4.3.
My guess is that it was removed beause it doesn't work.
Reading the S2 TRM, on chapter 32.2 (SAR ADC) there are some hints about how this should work:
Page 808: Threshold monitoring. An interrupt will be triggered when the value is greater or less than the threshold.
On page 814, chapter 32.2.5.4 (Threshold Monitoring) it talks about how to trigger an ADC interrupt.
On page 836 there is a reference to APB_SARADC_ADC2_THRES_MODE 1: ADC_DATA > = threshold, generate interrupt. 0: ADC_DATA < threshold, generate interrupt. (R/W) APB_SARADC_ADC1_THRES_MODE 1: ADC_DATA > = threshold, generate interrupt. 0: ADC_DATA < threshold, generate interrupt. (R/W)
Although your code sets up the Thresholds with adc_digi_monitor_set_config()
, it seems that it doesn't work.
I think that this line is causing the issue: adc1_config_width(ADC_WIDTH_BIT_13);
Upon TRM, on page 806, DIG ADC: 12-bit sampling resolution at most.
You may try to set it to 12-bit instead and verify if it works after that.
I think that this line is causing the issue:
adc1_config_width(ADC_WIDTH_BIT_13);
Upon TRM, on page 806, DIG ADC: 12-bit sampling resolution at most.You may try to set it to 12-bit instead and verify if it works after that.
but s2 is 13-bit adc! Monitor mode change this feature???
but s2 is 13-bit adc! Monitor mode change this feature???
Yes, but 13-bit is only for the RTC ADC controller. In TRM, page 811, in chapter 32.2.5 (DIG ADC Controllers), it is clear: "Up to 12-bit sampling resolution". Try changing this parameter and verify if this new setting makes it work.
but s2 is 13-bit adc! Monitor mode change this feature???
Yes, but 13-bit is only for the RTC ADC controller. In TRM, page 811, in chapter 32.2.5 (DIG ADC Controllers), it is clear: "Up to 12-bit sampling resolution". Try changing this parameter and verify if this new setting makes it work.
./main/main.c:38:23: error: 'ADC_WIDTH_BIT_12' undeclared (first use in this function); did you mean 'ADC_WIDTH_BIT_13'? adc1_config_width(ADC_WIDTH_BIT_12); ^~~~~~~~~~~~~~~~ ADC_WIDTH_BIT_13 ../main/main.c:38:23: note: each undeclared identifier is reported only once for each function it appears in ninja: build stopped: subcommand failed. ninja failed with exit code 1
Not defined, only works in esp32?!
https://github.com/espressif/esp-idf/blob/release/v4.3/components/hal/include/hal/adc_types.h#L86-L98 it sounds like for ESP32S2 there is only one option for this type 13 bits. but for IDF 4.2, it shall be there. https://github.com/espressif/esp-idf/blob/release/v4.2/components/soc/include/hal/adc_types.h#L73-L82
But, looking into
https://github.com/espressif/esp-idf/blob/release/v4.2/components/driver/adc_common.c#L307-L320
it also seems that adc1_config_width()
works for the RTC ADC controller.
I'd remove this line from the code and test it.
I think there is a step missing, which is using adc_digi_controller_config(...)
to configure the controller.
Also adc_digi_init()
I think there is a step missing, which is using
adc_digi_controller_config(...)
to configure the controller. Alsoadc_digi_init()
After configure digital domain to ADC, works but not 100%. With code bellow, configured to "ADC_DIGI_MONITOR_LOW", ISR is called only when I put 3v3 in GPIO, inverse of expected, is correct?
#include <stdio.h>
#include "sdkconfig.h"
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "esp_system.h"
#include "esp_log.h"
#include "driver/temp_sensor.h"
#include "driver/adc.h"
void isr_adc(void *z)
{
uint32_t st1 = adc_digi_intr_get_status(ADC_UNIT_1);
uint32_t st2 = REG_READ(0x3F440000+0x50);
adc_digi_intr_clear(ADC_UNIT_1, ADC_DIGI_INTR_MASK_MONITOR);
ESP_EARLY_LOGI(__func__, "ISR_ADC [%u], [%u]", st1, st2);
}
void app_main(void)
{
adc_digi_pattern_table_t a1p;
a1p.atten = 3;
a1p.channel = ADC_CHANNEL_0;
adc_digi_clk_t adc_clk;
adc_clk.use_apll = 0;
adc_clk.div_num = 100;
adc_clk.div_b = 1;
adc_clk.div_a = 0;
adc_digi_config_t dcfg;
dcfg.conv_limit_en = 0;
dcfg.conv_limit_num = 255;
dcfg.adc1_pattern_len = 1;
dcfg.adc2_pattern_len = 0;
dcfg.adc1_pattern = &a1p;
dcfg.adc2_pattern = 0;
dcfg.conv_mode = ADC_CONV_SINGLE_UNIT_1;
dcfg.format = ADC_DIGI_FORMAT_12BIT;
dcfg.interval = 400;
dcfg.dig_clk = adc_clk;
dcfg.dma_eof_num = 1000;
ESP_ERROR_CHECK(adc_digi_init());
ESP_ERROR_CHECK(adc_digi_controller_config(&dcfg));
adc_digi_monitor_t mcfg;
mcfg.adc_unit = ADC_UNIT_1;
mcfg.channel = ADC_CHANNEL_MAX;
mcfg.mode = ADC_DIGI_MONITOR_LOW;
mcfg.threshold = 4096;
ESP_ERROR_CHECK(adc_digi_monitor_set_config(ADC_DIGI_MONITOR_IDX0, &mcfg));
ESP_ERROR_CHECK(adc_digi_monitor_enable(ADC_DIGI_MONITOR_IDX0, true));
ESP_ERROR_CHECK(adc_digi_isr_register(isr_adc, NULL, 0));
ESP_ERROR_CHECK(adc_digi_intr_enable(ADC_UNIT_1, ADC_DIGI_INTR_MASK_MONITOR));
ESP_ERROR_CHECK(adc_digi_start());
while (1)
{
int val = 0;
//val = adc1_get_raw(ADC1_CHANNEL_0);
ESP_LOGI(__func__, "%d", val);
vTaskDelay(pdMS_TO_TICKS(500));
}
}
Yes. Correct.
ADC has actually an interrupt for detecting PWR 3.3Vdd. It works with RTC ADC mode.
There are 2 modes:
I think that maybe the code is configuring both at the same time and maybe some bit turns on the RTC mode and disable the DIGI mode.
Anyway, it seems that this Interrupt functionality has been disabled for IDF 4.4+, thus be careful, because it may not be compatible with newer IDF versions.
Yes. Correct.
ADC has actually an interrupt for detecting PWR 3.3Vdd. It works with RTC ADC mode.
There are 2 modes:
- RTC that can't generate Interrupt on Thresholds and
- DMA/DIGI mode that can do it.
I think that maybe the code is configuring both at the same time and maybe some bit turns on the RTC mode and disable the DIGI mode.
Anyway, it seems that this Interrupt functionality has been disabled for IDF 4.4+, thus be careful, because it may not be compatible with newer IDF versions.
Sorry, I expressed myself wrong.
I commented that it only works when I put 3v3, because Im only testing with GND and 3v3. What I mean is that the interrupt is called (apparently correct) but the configuration is inverted.
When configured to low_trigger, only occurs when put 3v3. When configure to high_trigger, only occurs when put GND.
Any one can help me? Im writing an article and I need clarification on this inverted trigger
Hello, I trying to use ADC Threshold with ESP32-S2 (monitor mode) but without examples, this is a little boring. Monitor mode is not working correctly.
ISR_ADC() is only trigged when "adc1_get_raw()" is executed, if I comment "adc1_get_raw()", ISR_ADC() is never called. Monitor mode should generate interrupt by itself, without having to polling with get_raw().
I tested with IDF 4.3 and 4.4.