From 0483548a39bd5b9523d56b0bca37d07fbafd8f6b Mon Sep 17 00:00:00 2001 From: Ivan Grokhotkov Date: Thu, 26 Jan 2017 11:50:04 +0800 Subject: [PATCH] ulp: fix I_{RD,WR}_REG definitions - I_RD_REG used the wrong union member (.rd_reg) due to a copy-paste mistake - Peripheral register address in bits[7:0] should be given in words, not in bytes Fixes https://github.com/espressif/esp-idf/issues/297 --- components/ulp/include/esp32/ulp.h | 6 ++--- components/ulp/test/test_ulp.c | 39 ++++++++++++++++++++++++++++++ 2 files changed, 42 insertions(+), 3 deletions(-) diff --git a/components/ulp/include/esp32/ulp.h b/components/ulp/include/esp32/ulp.h index f4e37e924a..66865c5b99 100644 --- a/components/ulp/include/esp32/ulp.h +++ b/components/ulp/include/esp32/ulp.h @@ -307,7 +307,7 @@ static inline uint32_t SOC_REG_TO_ULP_PERIPH_SEL(uint32_t reg) { * This instruction can access RTC_CNTL_, RTC_IO_, and SENS_ peripheral registers. */ #define I_WR_REG(reg, low_bit, high_bit, val) {.wr_reg = {\ - .addr = reg & 0xff, \ + .addr = (reg & 0xff) / sizeof(uint32_t), \ .periph_sel = SOC_REG_TO_ULP_PERIPH_SEL(reg), \ .data = val, \ .low = low_bit, \ @@ -320,8 +320,8 @@ static inline uint32_t SOC_REG_TO_ULP_PERIPH_SEL(uint32_t reg) { * R0 = reg[high_bit : low_bit] * This instruction can access RTC_CNTL_, RTC_IO_, and SENS_ peripheral registers. */ -#define I_RD_REG(reg, low_bit, high_bit, val) {.wr_reg = {\ - .addr = reg & 0xff, \ +#define I_RD_REG(reg, low_bit, high_bit) {.rd_reg = {\ + .addr = (reg & 0xff) / sizeof(uint32_t), \ .periph_sel = SOC_REG_TO_ULP_PERIPH_SEL(reg), \ .unused = 0, \ .low = low_bit, \ diff --git a/components/ulp/test/test_ulp.c b/components/ulp/test/test_ulp.c index f04178623c..7ee0dbf9f4 100644 --- a/components/ulp/test/test_ulp.c +++ b/components/ulp/test/test_ulp.c @@ -121,6 +121,45 @@ TEST_CASE("ulp wakeup test", "[ulp][ignore]") esp_deep_sleep_start(); } +TEST_CASE("ulp can write and read peripheral registers", "[ulp]") +{ + assert(CONFIG_ULP_COPROC_RESERVE_MEM >= 260 && "this test needs ULP_COPROC_RESERVE_MEM option set in menuconfig"); + CLEAR_PERI_REG_MASK(RTC_CNTL_STATE0_REG, RTC_CNTL_ULP_CP_SLP_TIMER_EN); + memset(RTC_SLOW_MEM, 0, CONFIG_ULP_COPROC_RESERVE_MEM); + REG_WRITE(RTC_CNTL_STORE1_REG, 0x89abcdef); + + const ulp_insn_t program[] = { + I_MOVI(R1, 64), + I_RD_REG(RTC_CNTL_STORE1_REG, 0, 15), + I_ST(R0, R1, 0), + I_RD_REG(RTC_CNTL_STORE1_REG, 4, 11), + I_ST(R0, R1, 1), + I_RD_REG(RTC_CNTL_STORE1_REG, 16, 31), + I_ST(R0, R1, 2), + I_RD_REG(RTC_CNTL_STORE1_REG, 20, 27), + I_ST(R0, R1, 3), + I_WR_REG(RTC_CNTL_STORE0_REG, 0, 7, 0x89), + I_WR_REG(RTC_CNTL_STORE0_REG, 8, 15, 0xab), + I_WR_REG(RTC_CNTL_STORE0_REG, 16, 23, 0xcd), + I_WR_REG(RTC_CNTL_STORE0_REG, 24, 31, 0xef), + I_LD(R0, R1, 4), + I_ADDI(R0, R0, 1), + I_ST(R0, R1, 4), + I_END(0) + }; + size_t size = sizeof(program)/sizeof(ulp_insn_t); + TEST_ESP_OK(ulp_process_macros_and_load(0, program, &size)); + TEST_ESP_OK(ulp_run(0)); + vTaskDelay(100/portTICK_PERIOD_MS); + + TEST_ASSERT_EQUAL_HEX32(0xefcdab89, REG_READ(RTC_CNTL_STORE0_REG)); + TEST_ASSERT_EQUAL_HEX16(0xcdef, RTC_SLOW_MEM[64] & 0xffff); + TEST_ASSERT_EQUAL_HEX16(0xde, RTC_SLOW_MEM[65] & 0xffff); + TEST_ASSERT_EQUAL_HEX16(0x89ab, RTC_SLOW_MEM[66] & 0xffff); + TEST_ASSERT_EQUAL_HEX16(0x9a, RTC_SLOW_MEM[67] & 0xffff); + TEST_ASSERT_EQUAL_HEX32(1 | (15 << 21) | (1 << 16), RTC_SLOW_MEM[68]); +} + TEST_CASE("ulp controls RTC_IO", "[ulp][ignore]") { assert(CONFIG_ULP_COPROC_RESERVE_MEM >= 260 && "this test needs ULP_COPROC_RESERVE_MEM option set in menuconfig");