Просмотр исходного кода

Merge branch 'bugfix/fix_adc_dac_conflict' into 'master'

Driver(adc): Disable the synchronization operation function of ADC1 and DAC

Closes IDF-1585

See merge request espressif/esp-idf!8364
Michael (XIAO Xufeng) 5 лет назад
Родитель
Сommit
099f2706aa

+ 32 - 26
components/driver/adc_common.c

@@ -31,6 +31,7 @@
 
 #include "hal/adc_types.h"
 #include "hal/adc_hal.h"
+#include "hal/dac_hal.h"
 
 #define ADC_CHECK_RET(fun_ret) ({                  \
     if (fun_ret != ESP_OK) {                                \
@@ -148,21 +149,45 @@ esp_err_t adc_set_clk_div(uint8_t clk_div)
     return ESP_OK;
 }
 
+static void adc_rtc_chan_init(adc_unit_t adc_unit)
+{
+    if (adc_unit & ADC_UNIT_1) {
+        /* Workaround: Disable the synchronization operation function of ADC1 and DAC.
+           If enabled(default), ADC RTC controller sampling will cause the DAC channel output voltage. */
+        dac_hal_rtc_sync_by_adc(false);
+        adc_hal_rtc_output_invert(ADC_NUM_1, SOC_ADC1_DATA_INVERT_DEFAULT);
+        adc_hal_set_sar_clk_div(ADC_NUM_1, SOC_ADC_SAR_CLK_DIV_DEFAULT(ADC_NUM_1));
+#ifdef CONFIG_IDF_TARGET_ESP32
+        adc_hal_hall_disable(); //Disable other peripherals.
+        adc_hal_amp_disable();  //Currently the LNA is not open, close it by default.
+#endif
+    }
+    if (adc_unit & ADC_UNIT_2) {
+        adc_hal_pwdet_set_cct(SOC_ADC_PWDET_CCT_DEFAULT);
+        adc_hal_rtc_output_invert(ADC_NUM_2, SOC_ADC2_DATA_INVERT_DEFAULT);
+        adc_hal_set_sar_clk_div(ADC_NUM_2, SOC_ADC_SAR_CLK_DIV_DEFAULT(ADC_NUM_2));
+    }
+}
+
 esp_err_t adc_gpio_init(adc_unit_t adc_unit, adc_channel_t channel)
 {
     gpio_num_t gpio_num = 0;
     if (adc_unit & ADC_UNIT_1) {
         ADC_CHANNEL_CHECK(ADC_NUM_1, channel);
         gpio_num = ADC_GET_IO_NUM(ADC_NUM_1, channel);
+        ADC_CHECK_RET(rtc_gpio_init(gpio_num));
+        ADC_CHECK_RET(rtc_gpio_set_direction(gpio_num, RTC_GPIO_MODE_DISABLED));
+        ADC_CHECK_RET(rtc_gpio_pulldown_dis(gpio_num));
+        ADC_CHECK_RET(rtc_gpio_pullup_dis(gpio_num));
     }
     if (adc_unit & ADC_UNIT_2) {
         ADC_CHANNEL_CHECK(ADC_NUM_2, channel);
         gpio_num = ADC_GET_IO_NUM(ADC_NUM_2, channel);
+        ADC_CHECK_RET(rtc_gpio_init(gpio_num));
+        ADC_CHECK_RET(rtc_gpio_set_direction(gpio_num, RTC_GPIO_MODE_DISABLED));
+        ADC_CHECK_RET(rtc_gpio_pulldown_dis(gpio_num));
+        ADC_CHECK_RET(rtc_gpio_pullup_dis(gpio_num));
     }
-    ADC_CHECK_RET(rtc_gpio_init(gpio_num));
-    ADC_CHECK_RET(rtc_gpio_set_direction(gpio_num, RTC_GPIO_MODE_DISABLED));
-    ADC_CHECK_RET(rtc_gpio_pulldown_dis(gpio_num));
-    ADC_CHECK_RET(rtc_gpio_pullup_dis(gpio_num));
     return ESP_OK;
 }
 
@@ -194,7 +219,6 @@ esp_err_t adc_set_data_width(adc_unit_t adc_unit, adc_bits_width_t bits)
     }
     if (adc_unit & ADC_UNIT_2) {
         adc_hal_rtc_set_output_format(ADC_NUM_2, bits);
-        adc_hal_pwdet_set_cct(SOC_ADC_PWDET_CCT_DEFAULT);
     }
     ADC_EXIT_CRITICAL();
 
@@ -249,6 +273,7 @@ esp_err_t adc1_config_channel_atten(adc1_channel_t channel, adc_atten_t atten)
 
     adc_gpio_init(ADC_UNIT_1, channel);
     ADC_ENTER_CRITICAL();
+    adc_rtc_chan_init(ADC_UNIT_1);
     adc_hal_set_atten(ADC_NUM_1, channel, atten);
     ADC_EXIT_CRITICAL();
 
@@ -265,8 +290,6 @@ esp_err_t adc1_config_width(adc_bits_width_t width_bit)
 
     ADC_ENTER_CRITICAL();
     adc_hal_rtc_set_output_format(ADC_NUM_1, width_bit);
-    adc_hal_rtc_output_invert(ADC_NUM_1, SOC_ADC1_DATA_INVERT_DEFAULT);
-    adc_hal_set_sar_clk_div(ADC_NUM_1, SOC_ADC_SAR_CLK_DIV_DEFAULT(ADC_NUM_1));
     ADC_EXIT_CRITICAL();
 
     return ESP_OK;
@@ -318,10 +341,6 @@ int adc1_get_raw(adc1_channel_t channel)
     adc_power_on();
 
     ADC_ENTER_CRITICAL();
-#ifdef CONFIG_IDF_TARGET_ESP32
-    adc_hal_hall_disable(); //Disable other peripherals.
-    adc_hal_amp_disable();  //Currently the LNA is not open, close it by default.
-#endif
 #ifdef CONFIG_IDF_TARGET_ESP32S2
     adc_set_init_code(ADC_NUM_1, channel);             // calibration for adc
 #endif
@@ -392,23 +411,12 @@ esp_err_t adc2_wifi_release(void)
     return ESP_OK;
 }
 
-static esp_err_t adc2_pad_init(adc2_channel_t channel)
-{
-    gpio_num_t gpio_num = 0;
-    ADC_CHECK_RET(adc2_pad_get_io_num(channel, &gpio_num));
-    ADC_CHECK_RET(rtc_gpio_init(gpio_num));
-    ADC_CHECK_RET(rtc_gpio_set_direction(gpio_num, RTC_GPIO_MODE_DISABLED));
-    ADC_CHECK_RET(rtc_gpio_pulldown_dis(gpio_num));
-    ADC_CHECK_RET(rtc_gpio_pullup_dis(gpio_num));
-    return ESP_OK;
-}
-
 esp_err_t adc2_config_channel_atten(adc2_channel_t channel, adc_atten_t atten)
 {
     ADC_CHANNEL_CHECK(ADC_NUM_2, channel);
     ADC_CHECK(atten <= ADC_ATTEN_11db, "ADC2 Atten Err", ESP_ERR_INVALID_ARG);
 
-    adc2_pad_init(channel);
+    adc_gpio_init(ADC_UNIT_2, channel);
     ADC2_ENTER_CRITICAL();
     //avoid collision with other tasks
     if ( ADC2_WIFI_LOCK_TRY_ACQUIRE() == -1 ) {
@@ -416,6 +424,7 @@ esp_err_t adc2_config_channel_atten(adc2_channel_t channel, adc_atten_t atten)
         ADC2_EXIT_CRITICAL();
         return ESP_ERR_TIMEOUT;
     }
+    adc_rtc_chan_init(ADC_UNIT_2);
     adc_hal_set_atten(ADC_NUM_2, channel, atten);
     ADC2_WIFI_LOCK_RELEASE();
     ADC2_EXIT_CRITICAL();
@@ -435,9 +444,6 @@ static inline void adc2_config_width(adc_bits_width_t width_bit)
 #endif  //CONFIG_IDF_TARGET_ESP32S2
     ADC_ENTER_CRITICAL();
     adc_hal_rtc_set_output_format(ADC_NUM_2, width_bit);
-    adc_hal_pwdet_set_cct(SOC_ADC_PWDET_CCT_DEFAULT);
-    adc_hal_rtc_output_invert(ADC_NUM_2, SOC_ADC2_DATA_INVERT_DEFAULT);
-    adc_hal_set_sar_clk_div(ADC_NUM_2, SOC_ADC_SAR_CLK_DIV_DEFAULT(ADC_NUM_2));
     ADC_EXIT_CRITICAL();
 }
 

+ 1 - 0
components/driver/dac.c

@@ -68,6 +68,7 @@ esp_err_t dac_output_enable(dac_channel_t channel)
     dac_rtc_pad_init(channel);
     portENTER_CRITICAL(&rtc_spinlock);
     dac_hal_power_on(channel);
+    dac_hal_rtc_sync_by_adc(false);
     portEXIT_CRITICAL(&rtc_spinlock);
 
     return ESP_OK;

+ 1 - 0
components/driver/esp32/adc.c

@@ -166,6 +166,7 @@ static int hall_sensor_get_value(void)    //hall sensor without LNA
     // set controller
     adc_hal_set_controller( ADC_NUM_1, ADC_CTRL_RTC );
     hall_value = adc_hal_hall_convert();
+    adc_hal_hall_disable();
     ADC_EXIT_CRITICAL();
 
     return hall_value;

+ 3 - 3
components/driver/include/driver/adc_common.h

@@ -158,7 +158,7 @@ esp_err_t adc1_config_width(adc_bits_width_t width_bit);
  *       When enabling power for any of these peripherals, ignore input from GPIO36 and GPIO39.
  *       Please refer to section 3.11 of 'ECO_and_Workarounds_for_Bugs_in_ESP32' for the description of this issue.
  *
- * @note Call adc1_config_width() before the first time this
+ * @note Call ``adc1_config_width()`` before the first time this
  *       function is called.
  *
  * @note For any given channel, adc1_config_channel_atten(channel)
@@ -230,9 +230,9 @@ esp_err_t adc_set_data_width(adc_unit_t adc_unit, adc_bits_width_t width_bit);
  * @brief Configure ADC1 to be usable by the ULP
  *
  * This function reconfigures ADC1 to be controlled by the ULP.
- * Effect of this function can be reverted using adc1_get_raw function.
+ * Effect of this function can be reverted using ``adc1_get_raw()`` function.
  *
- * Note that adc1_config_channel_atten, adc1_config_width functions need
+ * Note that adc1_config_channel_atten, ``adc1_config_width()`` functions need
  * to be called to configure ADC1 channels, before ADC1 is used by the ULP.
  */
 void adc1_ulp_enable(void);

+ 9 - 0
components/soc/include/hal/dac_hal.h

@@ -39,6 +39,15 @@
  */
 #define dac_hal_power_down(channel) dac_ll_power_down(channel)
 
+/**
+ * Enable/disable the synchronization operation function of ADC1 and DAC.
+ *
+ * @note  If enabled(default), ADC RTC controller sampling will cause the DAC channel output voltage.
+ *
+ * @param enable Enable or disable adc and dac synchronization function.
+ */
+#define  dac_hal_rtc_sync_by_adc(enable) dac_ll_rtc_sync_by_adc(enable)
+
 /**
  * Output voltage with value (8 bit).
  *

+ 12 - 0
components/soc/src/esp32/include/hal/dac_ll.h

@@ -69,6 +69,18 @@ static inline void dac_ll_update_output_value(dac_channel_t channel, uint8_t val
     }
 }
 
+/**
+ * Enable/disable the synchronization operation function of ADC1 and DAC.
+ *
+ * @note  If enabled(default), ADC RTC controller sampling will cause the DAC channel output voltage.
+ *
+ * @param enable Enable or disable adc and dac synchronization function.
+ */
+static inline void dac_ll_rtc_sync_by_adc(bool enable)
+{
+    SENS.sar_meas_ctrl2.sar1_dac_xpd_fsm = enable;
+}
+
 /************************************/
 /*  DAC cosine wave generator API's */
 /************************************/

+ 12 - 0
components/soc/src/esp32s2/include/hal/dac_ll.h

@@ -86,6 +86,18 @@ static inline void dac_ll_rtc_reset(void)
     SENS.sar_dac_ctrl1.dac_reset = 0;
 }
 
+/**
+ * Enable/disable the synchronization operation function of ADC1 and DAC.
+ *
+ * @note  If enabled(default), ADC RTC controller sampling will cause the DAC channel output voltage.
+ *
+ * @param enable Enable or disable adc and dac synchronization function.
+ */
+static inline void dac_ll_rtc_sync_by_adc(bool enable)
+{
+    SENS.sar_amp_ctrl3.sar1_dac_xpd_fsm = enable;
+}
+
 /************************************/
 /*  DAC cosine wave generator API's */
 /************************************/