]> granicus.if.org Git - esp-idf/commitdiff
Corrected ULP wakeup period setup API to account for time the ULP FSM spends on inter...
authorkrzychb <krzychb@gazeta.pl>
Sun, 9 Sep 2018 14:13:26 +0000 (16:13 +0200)
committerkrzychb <krzychb@gazeta.pl>
Mon, 10 Sep 2018 05:08:12 +0000 (07:08 +0200)
components/ulp/include/esp32/ulp.h
components/ulp/ulp.c

index 8acbd7120b024bf09dea4e68d012a5fc5d3df670..e9668593d3ddadbe7c90ed7111e79463a1cdc53f 100644 (file)
@@ -23,6 +23,8 @@
 extern "C" {
 #endif
 
+#define ULP_FSM_PREPARE_SLEEP_CYCLES 2    /*!< Cycles spent by FSM preparing ULP for sleep */
+#define ULP_FSM_WAKEUP_SLEEP_CYCLES  2    /*!< Cycles spent by FSM waking up ULP from sleep */
 
 /**
  * @defgroup ulp_registers ULP coprocessor registers
@@ -898,6 +900,13 @@ esp_err_t ulp_run(uint32_t entry_point);
  *
  * @param period_index wakeup period setting number (0 - 4)
  * @param period_us wakeup period, us
+ * @note  The ULP FSM requires some time to wakeup before being able to run the program.
+ *        Then additional time is reserved after wakeup waiting until the 8M clock is stable.
+ *        The FSM also requires time to go to sleep after the program execution is halted.
+ *        The minimum wakeup period that may be set up for the ULP
+ *        is the total time spent on the above internal tasks.
+ *        For a default configuration of the ULP running at 150kHz
+ *        the minimum wakeup period is about 160us.
  * @return
  *      - ESP_OK on success
  *      - ESP_ERR_INVALID_ARG if period_index is out of range
index d325bccf3305429b236e08f91bb3b0e9e956ebf8..3424da21ec228f049d3d591d00dd49a4b85003b3 100644 (file)
@@ -112,6 +112,15 @@ esp_err_t ulp_set_wakeup_period(size_t period_index, uint32_t period_us)
     }
     uint64_t period_us_64 = period_us;
     uint64_t period_cycles = (period_us_64 << RTC_CLK_CAL_FRACT) / esp_clk_slowclk_cal_get();
+    uint64_t min_sleep_period_cycles = ULP_FSM_PREPARE_SLEEP_CYCLES 
+                                    + ULP_FSM_WAKEUP_SLEEP_CYCLES
+                                    + REG_GET_FIELD(RTC_CNTL_TIMER2_REG, RTC_CNTL_ULPCP_TOUCH_START_WAIT);
+    if (period_cycles < min_sleep_period_cycles) {
+        period_cycles = 0;
+        ESP_LOGW(TAG, "Sleep period clipped to minimum of %d cycles", (uint32_t) min_sleep_period_cycles);
+    } else {
+        period_cycles -= min_sleep_period_cycles;
+    }
     REG_SET_FIELD(SENS_ULP_CP_SLEEP_CYC0_REG + period_index * sizeof(uint32_t),
             SENS_SLEEP_CYCLES_S0, (uint32_t) period_cycles);
     return ESP_OK;