From d0d2c4cb49a3bedba4ed0655d13949feea70eb23 Mon Sep 17 00:00:00 2001 From: Ivan Grokhotkov Date: Mon, 20 Feb 2017 15:44:49 +0800 Subject: [PATCH] esp32,ulp: add tests for TSENS --- components/esp32/test/test_tsens.c | 20 ++++++++++++ components/ulp/include/esp32/ulp.h | 14 +++++++- components/ulp/test/test_ulp.c | 52 ++++++++++++++++++++++++++++++ components/ulp/ulp.c | 3 ++ 4 files changed, 88 insertions(+), 1 deletion(-) create mode 100644 components/esp32/test/test_tsens.c diff --git a/components/esp32/test/test_tsens.c b/components/esp32/test/test_tsens.c new file mode 100644 index 000000000..ff2660d1b --- /dev/null +++ b/components/esp32/test/test_tsens.c @@ -0,0 +1,20 @@ +#include +#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); +} diff --git a/components/ulp/include/esp32/ulp.h b/components/ulp/include/esp32/ulp.h index 9620a5ac9..6d4bb18b1 100644 --- a/components/ulp/include/esp32/ulp.h +++ b/components/ulp/include/esp32/ulp.h @@ -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. * diff --git a/components/ulp/test/test_ulp.c b/components/ulp/test/test_ulp.c index 7ee0dbf9f..6a9d40253 100644 --- a/components/ulp/test/test_ulp.c +++ b/components/ulp/test/test_ulp.c @@ -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(); +} + diff --git a/components/ulp/ulp.c b/components/ulp/ulp.c index 60fa292f7..424a468c3 100644 --- a/components/ulp/ulp.c +++ b/components/ulp/ulp.c @@ -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;