]> granicus.if.org Git - esp-idf/commitdiff
esp32,ulp: add tests for TSENS
authorIvan Grokhotkov <ivan@espressif.com>
Mon, 20 Feb 2017 07:44:49 +0000 (15:44 +0800)
committerIvan Grokhotkov <ivan@espressif.com>
Wed, 22 Feb 2017 06:40:36 +0000 (14:40 +0800)
components/esp32/test/test_tsens.c [new file with mode: 0644]
components/ulp/include/esp32/ulp.h
components/ulp/test/test_ulp.c
components/ulp/ulp.c

diff --git a/components/esp32/test/test_tsens.c b/components/esp32/test/test_tsens.c
new file mode 100644 (file)
index 0000000..ff2660d
--- /dev/null
@@ -0,0 +1,20 @@
+#include <stdio.h>
+#include "unity.h"
+#include "rom/ets_sys.h"
+#include "soc/rtc_cntl_reg.h"
+#include "soc/sens_reg.h"
+
+TEST_CASE("can control TSENS using registers", "[rtc][ignore]")
+{
+    SET_PERI_REG_BITS(SENS_SAR_MEAS_WAIT2_REG, SENS_FORCE_XPD_SAR, 3, SENS_FORCE_XPD_SAR_S);
+    SET_PERI_REG_BITS(SENS_SAR_TSENS_CTRL_REG, SENS_TSENS_CLK_DIV, 10, SENS_TSENS_CLK_DIV_S);
+    CLEAR_PERI_REG_MASK(SENS_SAR_TSENS_CTRL_REG, SENS_TSENS_POWER_UP);
+    CLEAR_PERI_REG_MASK(SENS_SAR_TSENS_CTRL_REG, SENS_TSENS_DUMP_OUT);
+    SET_PERI_REG_MASK(SENS_SAR_TSENS_CTRL_REG, SENS_TSENS_POWER_UP_FORCE);
+    SET_PERI_REG_MASK(SENS_SAR_TSENS_CTRL_REG, SENS_TSENS_POWER_UP);
+    ets_delay_us(100);
+    SET_PERI_REG_MASK(SENS_SAR_TSENS_CTRL_REG, SENS_TSENS_DUMP_OUT);
+    ets_delay_us(5);
+    int res = GET_PERI_REG_BITS2(SENS_SAR_SLAVE_ADDR3_REG, SENS_TSENS_OUT, SENS_TSENS_OUT_S);
+    printf("res=%d\n", res);
+}
index 9620a5ac9e31c0846b750e80dfd3f1ddc1db634a..6d4bb18b1377423e4bc324aa81ae84ec3ecfd02e 100644 (file)
@@ -222,7 +222,7 @@ typedef union {
     struct {
         uint32_t dreg : 2;          /*!< Register where to store temperature measurement result */
         uint32_t wait_delay: 14;    /*!< Cycles to wait after measurement is done */
-        uint32_t cycles: 12;        /*!< Cycles used to perform measurement */
+        uint32_t reserved: 12;      /*!< Reserved, set to 0 */
         uint32_t opcode: 4;         /*!< Opcode (OPCODE_TSENS) */
     } tsens;                        /*!< Format of TSENS instruction */
 
@@ -360,6 +360,18 @@ static inline uint32_t SOC_REG_TO_ULP_PERIPH_SEL(uint32_t reg) {
         .sub_opcode = SUB_OPCODE_SLEEP, \
         .opcode = OPCODE_END } }
 
+/**
+ * Perform temperature sensor measurement and store it into reg_dest.
+ *
+ * Delay can be set between 1 and ((1 << 14) - 1). Higher values give
+ * higher measurement resolution.
+ */
+#define I_TSENS(reg_dest, delay) { .tsens = { \
+        .dreg = reg_dest, \
+        .wait_delay = delay, \
+        .reserved = 0, \
+        .opcode = OPCODE_TSENS } }
+
 /**
  * Store value from register reg_val into RTC memory.
  *
index 7ee0dbf9f48a7fe4997df744405321abd405a6c8..6a9d40253bf84c37b8b741e7c40f1b40b69fee6f 100644 (file)
@@ -207,3 +207,55 @@ TEST_CASE("ulp controls RTC_IO", "[ulp][ignore]")
     esp_deep_sleep_start();
 }
 
+
+TEST_CASE("ulp can use TSENS in deep sleep", "[ulp][ignore]")
+{
+    assert(CONFIG_ULP_COPROC_RESERVE_MEM >= 260 && "this test needs ULP_COPROC_RESERVE_MEM option set in menuconfig");
+
+    hexdump(RTC_SLOW_MEM, CONFIG_ULP_COPROC_RESERVE_MEM / 4);
+    printf("\n\n");
+    memset(RTC_SLOW_MEM, 0, CONFIG_ULP_COPROC_RESERVE_MEM);
+
+    // Allow TSENS to be controlled by the ULP
+    SET_PERI_REG_BITS(SENS_SAR_TSENS_CTRL_REG, SENS_TSENS_CLK_DIV, 10, SENS_TSENS_CLK_DIV_S);
+    SET_PERI_REG_BITS(SENS_SAR_MEAS_WAIT2_REG, SENS_FORCE_XPD_SAR, 3, SENS_FORCE_XPD_SAR_S);
+    CLEAR_PERI_REG_MASK(SENS_SAR_TSENS_CTRL_REG, SENS_TSENS_POWER_UP);
+    CLEAR_PERI_REG_MASK(SENS_SAR_TSENS_CTRL_REG, SENS_TSENS_DUMP_OUT);
+    CLEAR_PERI_REG_MASK(SENS_SAR_TSENS_CTRL_REG, SENS_TSENS_POWER_UP_FORCE);
+
+    // data start offset
+    size_t offset = 20;
+    // number of samples to collect
+    RTC_SLOW_MEM[offset] = (CONFIG_ULP_COPROC_RESERVE_MEM) / 4 - offset - 8;
+    // sample counter
+    RTC_SLOW_MEM[offset + 1] = 0;
+
+    const ulp_insn_t program[] = {
+        I_MOVI(R1, offset),     // r1 <- offset
+        I_LD(R2, R1, 1),    // r2 <- counter
+        I_LD(R3, R1, 0),    // r3 <- length
+        I_SUBI(R3, R3, 1),  // end = length - 1
+        I_SUBR(R3, R3, R2), // r3 = length - counter
+        M_BXF(1),           // if overflow goto 1:
+            I_WR_REG(SENS_SAR_MEAS_WAIT2_REG, SENS_FORCE_XPD_SAR_S, SENS_FORCE_XPD_SAR_S + 1, 3),
+            I_TSENS(R0, 16383), // r0 <- tsens
+            I_WR_REG(SENS_SAR_MEAS_WAIT2_REG, SENS_FORCE_XPD_SAR_S, SENS_FORCE_XPD_SAR_S + 1, 0),
+            I_ST(R0, R2, offset + 4),
+            I_ADDI(R2, R2, 1),  // counter += 1
+            I_ST(R2, R1, 1),    // save counter
+            I_SLEEP(0),         // enter sleep
+            I_HALT(),
+        M_LABEL(1),             // done with measurements
+            I_END(0),           // stop ULP timer
+            I_HALT()
+    };
+
+    size_t size = sizeof(program)/sizeof(ulp_insn_t);
+    TEST_ESP_OK(ulp_process_macros_and_load(0, program, &size));
+    assert(offset >= size);
+
+    TEST_ESP_OK(ulp_run(0));
+    esp_deep_sleep_enable_timer_wakeup(4000000);
+    esp_deep_sleep_start();
+}
+
index 60fa292f7c15e1789d3fda4247859da19c08e961..424a468c3c78eecf9ff8676923b02f316e933a62 100644 (file)
@@ -271,6 +271,9 @@ esp_err_t ulp_run(uint32_t entry_point)
     CLEAR_PERI_REG_MASK(SENS_SAR_START_FORCE_REG, SENS_ULP_CP_FORCE_START_TOP_M);
     // make sure voltage is raised when RTC 8MCLK is enabled
     SET_PERI_REG_MASK(RTC_CNTL_OPTIONS0_REG, RTC_CNTL_BIAS_I2C_FOLW_8M);
+    SET_PERI_REG_MASK(RTC_CNTL_OPTIONS0_REG, RTC_CNTL_BIAS_CORE_FOLW_8M);
+    SET_PERI_REG_MASK(RTC_CNTL_OPTIONS0_REG, RTC_CNTL_BIAS_SLEEP_FOLW_8M);
+    SET_PERI_REG_BITS(SENS_ULP_CP_SLEEP_CYC0_REG, SENS_SLEEP_CYCLES_S0, 1000, SENS_SLEEP_CYCLES_S0_S);
     // enable ULP timer
     SET_PERI_REG_MASK(RTC_CNTL_STATE0_REG, RTC_CNTL_ULP_CP_SLP_TIMER_EN);
     return ESP_OK;