diff --git a/components/ulp/ulp_riscv.c b/components/ulp/ulp_riscv.c index 1cd3c0b3b7..ccf2f8fcb9 100644 --- a/components/ulp/ulp_riscv.c +++ b/components/ulp/ulp_riscv.c @@ -32,12 +32,14 @@ esp_err_t ulp_riscv_run(void) { /* Reset COCPU when power on. */ - SET_PERI_REG_MASK(RTC_CNTL_COCPU_CTRL_REG, RTC_CNTL_COCPU_CLK_FO); SET_PERI_REG_MASK(RTC_CNTL_COCPU_CTRL_REG, RTC_CNTL_COCPU_SHUT_RESET_EN); esp_rom_delay_us(20); - CLEAR_PERI_REG_MASK(RTC_CNTL_COCPU_CTRL_REG, RTC_CNTL_COCPU_CLK_FO); CLEAR_PERI_REG_MASK(RTC_CNTL_COCPU_CTRL_REG, RTC_CNTL_COCPU_SHUT_RESET_EN); + /* The coprocessor cpu trap signal doesnt have a stable reset value, + force ULP-RISC-V clock on to stop RTC_COCPU_TRAP_TRIG_EN from waking the CPU*/ + SET_PERI_REG_MASK(RTC_CNTL_COCPU_CTRL_REG, RTC_CNTL_COCPU_CLK_FO); + /* Disable ULP timer */ CLEAR_PERI_REG_MASK(RTC_CNTL_ULP_CP_TIMER_REG, RTC_CNTL_ULP_CP_SLP_TIMER_EN); /* wait for at least 1 RTC_SLOW_CLK cycle */ diff --git a/examples/system/ulp_riscv/main/ulp/example_ulp_gpio.h b/components/ulp/ulp_riscv/include/ulp_riscv/ulp_riscv_gpio.h similarity index 77% rename from examples/system/ulp_riscv/main/ulp/example_ulp_gpio.h rename to components/ulp/ulp_riscv/include/ulp_riscv/ulp_riscv_gpio.h index 23af14a255..a129930326 100644 --- a/examples/system/ulp_riscv/main/ulp/example_ulp_gpio.h +++ b/components/ulp/ulp_riscv/include/ulp_riscv/ulp_riscv_gpio.h @@ -20,6 +20,8 @@ extern "C" { #include "ulp_riscv/ulp_riscv.h" #include "soc/rtc_io_reg.h" +#include "soc/sens_reg.h" + typedef enum { GPIO_NUM_0 = 0, /*!< GPIO0, input and output */ @@ -51,38 +53,39 @@ typedef enum { RTCIO_MODE_OUTPUT_OD = 1, } rtc_io_out_mode_t; -static inline void example_ulp_gpio_init(gpio_num_t gpio_num) +static inline void ulp_riscv_gpio_init(gpio_num_t gpio_num) { + SET_PERI_REG_MASK(SENS_SAR_IO_MUX_CONF_REG, SENS_IOMUX_CLK_GATE_EN_M); SET_PERI_REG_MASK(RTC_IO_TOUCH_PAD0_REG + gpio_num*4, RTC_IO_TOUCH_PAD0_MUX_SEL); REG_SET_FIELD(RTC_IO_TOUCH_PAD0_REG + gpio_num*4, RTC_IO_TOUCH_PAD0_FUN_SEL, 0); } -static inline void example_ulp_gpio_deinit(gpio_num_t gpio_num) +static inline void ulp_riscv_gpio_deinit(gpio_num_t gpio_num) { CLEAR_PERI_REG_MASK(RTC_IO_TOUCH_PAD0_REG + gpio_num*4, RTC_IO_TOUCH_PAD0_MUX_SEL); } -static inline void example_ulp_gpio_output_enable(gpio_num_t gpio_num) +static inline void ulp_riscv_gpio_output_enable(gpio_num_t gpio_num) { REG_SET_FIELD(RTC_GPIO_ENABLE_W1TS_REG, RTC_GPIO_ENABLE_W1TS, BIT(gpio_num)); } -static inline void example_ulp_gpio_output_disable(gpio_num_t gpio_num) +static inline void ulp_riscv_gpio_output_disable(gpio_num_t gpio_num) { REG_SET_FIELD(RTC_GPIO_ENABLE_W1TC_REG, RTC_GPIO_ENABLE_W1TC, BIT(gpio_num)); } -static inline void example_ulp_gpio_input_enable(gpio_num_t gpio_num) +static inline void ulp_riscv_gpio_input_enable(gpio_num_t gpio_num) { SET_PERI_REG_MASK(RTC_IO_TOUCH_PAD0_REG + gpio_num*4, RTC_IO_TOUCH_PAD0_FUN_IE); } -static inline void example_ulp_gpio_input_disable(gpio_num_t gpio_num) +static inline void ulp_riscv_gpio_input_disable(gpio_num_t gpio_num) { CLEAR_PERI_REG_MASK(RTC_IO_TOUCH_PAD0_REG + gpio_num*4, RTC_IO_TOUCH_PAD0_FUN_IE); } -static inline void example_ulp_gpio_output_level(gpio_num_t gpio_num, uint8_t level) +static inline void ulp_riscv_gpio_output_level(gpio_num_t gpio_num, uint8_t level) { if (level) { REG_SET_FIELD(RTC_GPIO_OUT_W1TS_REG, RTC_GPIO_OUT_DATA_W1TS, BIT(gpio_num)); @@ -91,32 +94,32 @@ static inline void example_ulp_gpio_output_level(gpio_num_t gpio_num, uint8_t le } } -static inline uint8_t example_ulp_gpio_get_level(gpio_num_t gpio_num) +static inline uint8_t ulp_riscv_gpio_get_level(gpio_num_t gpio_num) { return (uint8_t)((REG_GET_FIELD(RTC_GPIO_IN_REG, RTC_GPIO_IN_NEXT) & BIT(gpio_num)) ? 1 : 0); } -static inline void example_ulp_gpio_set_output_mode(gpio_num_t gpio_num, rtc_io_out_mode_t mode) +static inline void ulp_riscv_gpio_set_output_mode(gpio_num_t gpio_num, rtc_io_out_mode_t mode) { REG_SET_FIELD(RTC_IO_TOUCH_PAD0_REG + gpio_num*4, RTC_IO_TOUCH_PAD0_DRV, mode); } -static inline void example_ulp_gpio_pullup(gpio_num_t gpio_num) +static inline void ulp_riscv_gpio_pullup(gpio_num_t gpio_num) { SET_PERI_REG_MASK(RTC_IO_TOUCH_PAD0_REG + gpio_num*4, RTC_IO_TOUCH_PAD0_RUE); } -static inline void example_ulp_gpio_pullup_disable(gpio_num_t gpio_num) +static inline void ulp_riscv_gpio_pullup_disable(gpio_num_t gpio_num) { CLEAR_PERI_REG_MASK(RTC_IO_TOUCH_PAD0_REG + gpio_num*4, RTC_IO_TOUCH_PAD0_RUE); } -static inline void example_ulp_gpio_pulldown(gpio_num_t gpio_num) +static inline void ulp_riscv_gpio_pulldown(gpio_num_t gpio_num) { SET_PERI_REG_MASK(RTC_IO_TOUCH_PAD0_REG + gpio_num*4, RTC_IO_TOUCH_PAD0_RDE); } -static inline void example_ulp_gpio_pulldown_disable(gpio_num_t gpio_num) +static inline void ulp_riscv_gpio_pulldown_disable(gpio_num_t gpio_num) { CLEAR_PERI_REG_MASK(RTC_IO_TOUCH_PAD0_REG + gpio_num*4, RTC_IO_TOUCH_PAD0_RDE); } diff --git a/components/ulp/ulp_riscv/include/ulp_riscv/ulp_riscv_utils.h b/components/ulp/ulp_riscv/include/ulp_riscv/ulp_riscv_utils.h index b92bfba1b4..58d1fff6b3 100644 --- a/components/ulp/ulp_riscv/include/ulp_riscv/ulp_riscv_utils.h +++ b/components/ulp/ulp_riscv/include/ulp_riscv/ulp_riscv_utils.h @@ -58,6 +58,24 @@ void ulp_riscv_rescue_from_monitor(void); */ void __attribute__((noreturn)) ulp_riscv_shutdown(void); +#define ULP_RISCV_GET_CCOUNT() ({ int __ccount; \ + asm volatile("rdcycle %0;" : "=r"(__ccount)); \ + __ccount; }) + + +/* These are only approximate default numbers, the default frequency + of the 8M oscillator is 8.5MHz +/- 5%, at the default DCAP setting +*/ +#define ULP_RISCV_CYCLES_PER_US 8.5 +#define ULP_RISCV_CYCLES_PER_MS ULP_RISCV_CYCLES_PER_US*1000 + +/** + * @brief Makes the co-processor busy wait for a certain number of cycles + * + * @param cycles Number of cycles to busy wait + */ +void ulp_riscv_delay_cycles(uint32_t cycles); + #ifdef __cplusplus } #endif diff --git a/components/ulp/ulp_riscv/ulp_riscv_utils.c b/components/ulp/ulp_riscv/ulp_riscv_utils.c index c586197706..d6cbc60a46 100644 --- a/components/ulp/ulp_riscv/ulp_riscv_utils.c +++ b/components/ulp/ulp_riscv/ulp_riscv_utils.c @@ -39,3 +39,12 @@ void ulp_riscv_shutdown(void) while(1); } + +void ulp_riscv_delay_cycles(uint32_t cycles) +{ + uint32_t start = ULP_RISCV_GET_CCOUNT(); + + while ((ULP_RISCV_GET_CCOUNT() - start) < cycles) { + /* Wait */ + } +} diff --git a/examples/system/ulp/CMakeLists.txt b/examples/system/ulp_fsm/ulp/CMakeLists.txt similarity index 100% rename from examples/system/ulp/CMakeLists.txt rename to examples/system/ulp_fsm/ulp/CMakeLists.txt diff --git a/examples/system/ulp/Makefile b/examples/system/ulp_fsm/ulp/Makefile similarity index 100% rename from examples/system/ulp/Makefile rename to examples/system/ulp_fsm/ulp/Makefile diff --git a/examples/system/ulp/README.md b/examples/system/ulp_fsm/ulp/README.md similarity index 100% rename from examples/system/ulp/README.md rename to examples/system/ulp_fsm/ulp/README.md diff --git a/examples/system/ulp/example_test.py b/examples/system/ulp_fsm/ulp/example_test.py similarity index 96% rename from examples/system/ulp/example_test.py rename to examples/system/ulp_fsm/ulp/example_test.py index 1e3afe0b46..4c7840e716 100644 --- a/examples/system/ulp/example_test.py +++ b/examples/system/ulp_fsm/ulp/example_test.py @@ -10,7 +10,7 @@ from tiny_test_fw import Utility @ttfw_idf.idf_example_test(env_tag='Example_GENERIC', target=['esp32']) def test_examples_ulp(env, extra_data): - dut = env.get_dut('ulp', 'examples/system/ulp') + dut = env.get_dut('ulp', 'examples/system/ulp_fsm/ulp') dut.start_app() dut.expect_all('Not ULP wakeup, initializing ULP', diff --git a/examples/system/ulp/image/ulp_power_graph.png b/examples/system/ulp_fsm/ulp/image/ulp_power_graph.png similarity index 100% rename from examples/system/ulp/image/ulp_power_graph.png rename to examples/system/ulp_fsm/ulp/image/ulp_power_graph.png diff --git a/examples/system/ulp/main/CMakeLists.txt b/examples/system/ulp_fsm/ulp/main/CMakeLists.txt similarity index 100% rename from examples/system/ulp/main/CMakeLists.txt rename to examples/system/ulp_fsm/ulp/main/CMakeLists.txt diff --git a/examples/system/ulp/main/component.mk b/examples/system/ulp_fsm/ulp/main/component.mk similarity index 100% rename from examples/system/ulp/main/component.mk rename to examples/system/ulp_fsm/ulp/main/component.mk diff --git a/examples/system/ulp/main/ulp/pulse_cnt.S b/examples/system/ulp_fsm/ulp/main/ulp/pulse_cnt.S similarity index 100% rename from examples/system/ulp/main/ulp/pulse_cnt.S rename to examples/system/ulp_fsm/ulp/main/ulp/pulse_cnt.S diff --git a/examples/system/ulp/main/ulp/wake_up.S b/examples/system/ulp_fsm/ulp/main/ulp/wake_up.S similarity index 100% rename from examples/system/ulp/main/ulp/wake_up.S rename to examples/system/ulp_fsm/ulp/main/ulp/wake_up.S diff --git a/examples/system/ulp/main/ulp_example_main.c b/examples/system/ulp_fsm/ulp/main/ulp_example_main.c similarity index 100% rename from examples/system/ulp/main/ulp_example_main.c rename to examples/system/ulp_fsm/ulp/main/ulp_example_main.c diff --git a/examples/system/ulp/sdkconfig.defaults b/examples/system/ulp_fsm/ulp/sdkconfig.defaults similarity index 100% rename from examples/system/ulp/sdkconfig.defaults rename to examples/system/ulp_fsm/ulp/sdkconfig.defaults diff --git a/examples/system/ulp_adc/CMakeLists.txt b/examples/system/ulp_fsm/ulp_adc/CMakeLists.txt similarity index 100% rename from examples/system/ulp_adc/CMakeLists.txt rename to examples/system/ulp_fsm/ulp_adc/CMakeLists.txt diff --git a/examples/system/ulp_adc/Makefile b/examples/system/ulp_fsm/ulp_adc/Makefile similarity index 100% rename from examples/system/ulp_adc/Makefile rename to examples/system/ulp_fsm/ulp_adc/Makefile diff --git a/examples/system/ulp_adc/README.md b/examples/system/ulp_fsm/ulp_adc/README.md similarity index 100% rename from examples/system/ulp_adc/README.md rename to examples/system/ulp_fsm/ulp_adc/README.md diff --git a/examples/system/ulp_adc/example_test.py b/examples/system/ulp_fsm/ulp_adc/example_test.py similarity index 94% rename from examples/system/ulp_adc/example_test.py rename to examples/system/ulp_fsm/ulp_adc/example_test.py index d0b07d51ba..300e0ed49c 100644 --- a/examples/system/ulp_adc/example_test.py +++ b/examples/system/ulp_fsm/ulp_adc/example_test.py @@ -9,7 +9,7 @@ from tiny_test_fw import Utility @ttfw_idf.idf_example_test(env_tag='Example_GENERIC', target=['esp32']) def test_examples_ulp_adc(env, extra_data): - dut = env.get_dut('ulp_adc', 'examples/system/ulp_adc') + dut = env.get_dut('ulp_adc', 'examples/system/ulp_fsm/ulp_adc') dut.start_app() dut.expect_all('Not ULP wakeup', diff --git a/examples/system/ulp_adc/main/CMakeLists.txt b/examples/system/ulp_fsm/ulp_adc/main/CMakeLists.txt similarity index 100% rename from examples/system/ulp_adc/main/CMakeLists.txt rename to examples/system/ulp_fsm/ulp_adc/main/CMakeLists.txt diff --git a/examples/system/ulp_adc/main/component.mk b/examples/system/ulp_fsm/ulp_adc/main/component.mk similarity index 100% rename from examples/system/ulp_adc/main/component.mk rename to examples/system/ulp_fsm/ulp_adc/main/component.mk diff --git a/examples/system/ulp_adc/main/ulp/adc.S b/examples/system/ulp_fsm/ulp_adc/main/ulp/adc.S similarity index 100% rename from examples/system/ulp_adc/main/ulp/adc.S rename to examples/system/ulp_fsm/ulp_adc/main/ulp/adc.S diff --git a/examples/system/ulp_adc/main/ulp_adc_example_main.c b/examples/system/ulp_fsm/ulp_adc/main/ulp_adc_example_main.c similarity index 100% rename from examples/system/ulp_adc/main/ulp_adc_example_main.c rename to examples/system/ulp_fsm/ulp_adc/main/ulp_adc_example_main.c diff --git a/examples/system/ulp_adc/sdkconfig.defaults b/examples/system/ulp_fsm/ulp_adc/sdkconfig.defaults similarity index 100% rename from examples/system/ulp_adc/sdkconfig.defaults rename to examples/system/ulp_fsm/ulp_adc/sdkconfig.defaults diff --git a/examples/system/ulp_riscv/ds18b20_onewire/CMakeLists.txt b/examples/system/ulp_riscv/ds18b20_onewire/CMakeLists.txt new file mode 100644 index 0000000000..799dcfb117 --- /dev/null +++ b/examples/system/ulp_riscv/ds18b20_onewire/CMakeLists.txt @@ -0,0 +1,6 @@ +# The following lines of boilerplate have to be in your project's CMakeLists +# in this exact order for cmake to work correctly +cmake_minimum_required(VERSION 3.5) + +include($ENV{IDF_PATH}/tools/cmake/project.cmake) +project(ulp-riscv-ds18b20-example) diff --git a/examples/system/ulp_riscv/ds18b20_onewire/README.md b/examples/system/ulp_riscv/ds18b20_onewire/README.md new file mode 100644 index 0000000000..63ae1409ff --- /dev/null +++ b/examples/system/ulp_riscv/ds18b20_onewire/README.md @@ -0,0 +1,42 @@ +| Supported Targets | ESP32-S2 | +| ----------------- | -------- | + +# ULP-RISC-V DS18B20 Temperature Sensor OneWire Communication + +This example demonstrates how to program the ULP-RISC-V co-processor to read temperature from a [DS18B20](https://datasheets.maximintegrated.com/en/ds/DS18B20.pdf) temperature sensor over 1-Wire. +When the measurement exceeds the limit set(32.5 degrees) the co-processor will wake up the main CPU from deep-sleep and the main CPU will print the temperature measurement. + +### Hardware Required + +* A development board with a SOC which has a RISC-V ULP coprocessor (e.g., ESP32-S2 Saola) +* A USB cable for power supply and programming +* A DS18B20 temperature sensor + +Example connection : + +| ESP Dev-kit | DS18B20 | +| ------------ | ------- | +| GPIO4 | DQ | +| VCC 3.3V | VDD | +| GND | GND | + + +## Example output + +``` +Not a ULP wakeup, initializing it! +Entering in deep sleep + +... + +ULP-RISC-V woke up the main CPU, temperature is above set limit! +ULP-RISC-V read temperature is 32.562500 +Entering in deep sleep + +... + +ULP-RISC-V woke up the main CPU, temperature is above set limit! +ULP-RISC-V read temperature is 33.000000 +Entering in deep sleep + +``` diff --git a/examples/system/ulp_riscv/ds18b20_onewire/main/CMakeLists.txt b/examples/system/ulp_riscv/ds18b20_onewire/main/CMakeLists.txt new file mode 100644 index 0000000000..1e806d7596 --- /dev/null +++ b/examples/system/ulp_riscv/ds18b20_onewire/main/CMakeLists.txt @@ -0,0 +1,27 @@ +# Set usual component variables +set(COMPONENT_SRCS "ulp_riscv_ds18b20_example_main.c") +set(COMPONENT_ADD_INCLUDEDIRS "") +set(COMPONENT_REQUIRES soc nvs_flash ulp driver) + +register_component() + +# +# ULP support additions to component CMakeLists.txt. +# +# 1. The ULP app name must be unique (if multiple components use ULP). +set(ulp_app_name ulp_${COMPONENT_NAME}) +# +# 2. Specify all C and Assembly source files. +# Files should be placed into a separate directory (in this case, ulp/), +# which should not be added to COMPONENT_SRCS. +set(ulp_riscv_sources "ulp/main.c") + +# +# 3. List all the component source files which include automatically +# generated ULP export file, ${ulp_app_name}.h: +set(ulp_exp_dep_srcs "ulp_riscv_ds18b20_example_main.c") + +# +# 4. Call function to build ULP binary and embed in project using the argument +# values above. +ulp_embed_binary(${ulp_app_name} "${ulp_riscv_sources}" "${ulp_exp_dep_srcs}") diff --git a/examples/system/ulp_riscv/ds18b20_onewire/main/ulp/main.c b/examples/system/ulp_riscv/ds18b20_onewire/main/ulp/main.c new file mode 100644 index 0000000000..323e6030bc --- /dev/null +++ b/examples/system/ulp_riscv/ds18b20_onewire/main/ulp/main.c @@ -0,0 +1,156 @@ +/* ULP-RISC-V example + + This example code is in the Public Domain (or CC0 licensed, at your option.) + + Unless required by applicable law or agreed to in writing, this + software is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR + CONDITIONS OF ANY KIND, either express or implied. + + This code runs on ULP-RISC-V coprocessor +*/ + +#include +#include +#include +#include "ulp_riscv/ulp_riscv.h" +#include "ulp_riscv/ulp_riscv_utils.h" +#include "ulp_riscv/ulp_riscv_gpio.h" + +#define EXAMPLE_1WIRE_GPIO GPIO_NUM_4 + +#define WAKEUP_TEMP_C 32.5 +#define TEMP_ALARM_LIMIT ( (int)(WAKEUP_TEMP_C*16) ) + +typedef enum { + SENSOR_CONVERSION_INIT, + SENSOR_CONVERSION_READ, +} sensor_state_t; + +sensor_state_t state = SENSOR_CONVERSION_INIT; +int32_t temp_reg_val = INT32_MIN; + +static void ds18b20_write_bit(bool bit) +{ + ulp_riscv_gpio_output_level(EXAMPLE_1WIRE_GPIO, 0); + if (bit) { + /* Must pull high within 15 us, without delay this takes 5 us */ + ulp_riscv_gpio_output_level(EXAMPLE_1WIRE_GPIO, 1); + } + + /* Write slot duration at least 60 us */ + ulp_riscv_delay_cycles(60 * ULP_RISCV_CYCLES_PER_US); + ulp_riscv_gpio_output_level(EXAMPLE_1WIRE_GPIO, 1); +} + +static bool ds18b20_read_bit(void) +{ + bool bit; + + /* Pull low minimum 1 us */ + ulp_riscv_gpio_output_level(EXAMPLE_1WIRE_GPIO, 0); + ulp_riscv_gpio_output_level(EXAMPLE_1WIRE_GPIO, 1); + + /* Must sample within 15 us of the failing edge */ + ulp_riscv_delay_cycles(5 * ULP_RISCV_CYCLES_PER_US); + bit = ulp_riscv_gpio_get_level(EXAMPLE_1WIRE_GPIO); + + /* Read slot duration at least 60 us */ + ulp_riscv_delay_cycles(55 * ULP_RISCV_CYCLES_PER_US); + + return bit; +} + +static void ds18b20_write_byte(uint8_t data) +{ + for (int i = 0; i < 8; i++) { + ds18b20_write_bit((data >> i) & 0x1); + } +} + +static uint8_t ds18b20_read_byte(void) +{ + uint8_t data = 0; + for (int i = 0; i < 8; i++) { + data |= ds18b20_read_bit() << i; + } + return data; +} + +bool ds18b20_reset_pulse(void) +{ + bool presence_pulse; + /* min 480 us reset pulse + 480 us reply time is specified by datasheet */ + ulp_riscv_gpio_output_level(EXAMPLE_1WIRE_GPIO, 0); + ulp_riscv_delay_cycles(480 * ULP_RISCV_CYCLES_PER_US); + + ulp_riscv_gpio_output_level(EXAMPLE_1WIRE_GPIO, 1); + + /* Wait for ds18b20 to pull low before sampling */ + ulp_riscv_delay_cycles(60 * ULP_RISCV_CYCLES_PER_US); + presence_pulse = ulp_riscv_gpio_get_level(EXAMPLE_1WIRE_GPIO) == 0; + + ulp_riscv_delay_cycles(420 * ULP_RISCV_CYCLES_PER_US); + + return presence_pulse; +} + +int main (void) +{ + uint8_t temp_high_byte; + uint8_t temp_low_byte; + + /* Setup GPIO used for 1wire */ + ulp_riscv_gpio_init(EXAMPLE_1WIRE_GPIO); + ulp_riscv_gpio_input_enable(EXAMPLE_1WIRE_GPIO); + ulp_riscv_gpio_output_enable(EXAMPLE_1WIRE_GPIO); + ulp_riscv_gpio_set_output_mode(EXAMPLE_1WIRE_GPIO, RTCIO_MODE_OUTPUT_OD); + ulp_riscv_gpio_pullup(EXAMPLE_1WIRE_GPIO); + ulp_riscv_gpio_pulldown_disable(EXAMPLE_1WIRE_GPIO); + + + switch (state) { + case SENSOR_CONVERSION_INIT: + if (!ds18b20_reset_pulse()) { + temp_reg_val = INT32_MIN; + break; + } + /* Start conversion */ + ds18b20_write_byte(0xCC); + ds18b20_write_byte(0x44); + + /* shutdown and wait for next period (750ms) where the data is ready for reading */ + state = SENSOR_CONVERSION_READ; + break; + + case SENSOR_CONVERSION_READ: + if (!ds18b20_reset_pulse()) { + temp_reg_val = INT32_MIN; + state = SENSOR_CONVERSION_INIT; + break; + } + + /* Read scratchpad */ + ds18b20_write_byte(0xCC); + ds18b20_write_byte(0xBE); + + temp_low_byte = ds18b20_read_byte(); + temp_high_byte = ds18b20_read_byte(); + + temp_reg_val = temp_high_byte << 8; + temp_reg_val |= temp_low_byte; + state = SENSOR_CONVERSION_INIT; + + /* Wakes up the main CPU if the temperature exceeds the limit */ + if (temp_reg_val > TEMP_ALARM_LIMIT) { + ulp_riscv_wakeup_main_processor(); + } + + break; + } + + /* ulp_riscv_shutdown() is called automatically when main exits, + main will be executed again at the next timeout period, + according to ulp_set_wakeup_period() + */ + return 0; +} diff --git a/examples/system/ulp_riscv/ds18b20_onewire/main/ulp_riscv_ds18b20_example_main.c b/examples/system/ulp_riscv/ds18b20_onewire/main/ulp_riscv_ds18b20_example_main.c new file mode 100644 index 0000000000..8244430447 --- /dev/null +++ b/examples/system/ulp_riscv/ds18b20_onewire/main/ulp_riscv_ds18b20_example_main.c @@ -0,0 +1,72 @@ +/* ULP riscv example + + This example code is in the Public Domain (or CC0 licensed, at your option.) + + Unless required by applicable law or agreed to in writing, this + software is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR + CONDITIONS OF ANY KIND, either express or implied. +*/ + +#include +#include "esp_sleep.h" +#include "soc/rtc_cntl_reg.h" +#include "soc/sens_reg.h" +#include "soc/rtc_periph.h" +#include "hal/rtc_io_ll.h" +#include "driver/gpio.h" +#include "driver/rtc_io.h" +#include "esp32s2/ulp.h" +#include "esp32s2/ulp_riscv.h" +#include "ulp_main.h" +#include "freertos/FreeRTOS.h" +#include "freertos/task.h" + +/* We alternate between start conversion and read result every other ULP wakeup, + Conversion time is 750 ms for 12 bit resolution +*/ +#define WAKEUP_PERIOD_US (750000) + +extern const uint8_t ulp_main_bin_start[] asm("_binary_ulp_main_bin_start"); +extern const uint8_t ulp_main_bin_end[] asm("_binary_ulp_main_bin_end"); + +static void init_ulp_program(void); + +void app_main(void) +{ + esp_sleep_wakeup_cause_t cause = esp_sleep_get_wakeup_cause(); + /* not a wakeup from ULP, load the firmware */ + if (cause != ESP_SLEEP_WAKEUP_ULP) { + printf("Not a ULP-RISC-V wakeup (cause = %d), initializing it! \n", cause); + init_ulp_program(); + } + + /* ULP Risc-V read and detected a temperature above the limit */ + if (cause == ESP_SLEEP_WAKEUP_ULP) { + printf("ULP-RISC-V woke up the main CPU, temperature is above set limit! \n"); + printf("ULP-RISC-V read temperature is %f\n", ulp_temp_reg_val / 16.0); + } + /* Go back to sleep, only the ULP Risc-V will run */ + printf("Entering in deep sleep\n\n"); + + /* Small delay to ensure the messages are printed */ + vTaskDelay(100); + + ESP_ERROR_CHECK( esp_sleep_enable_ulp_wakeup()); + + esp_deep_sleep_start(); +} + +static void init_ulp_program(void) +{ + esp_err_t err = ulp_riscv_load_binary(ulp_main_bin_start, (ulp_main_bin_end - ulp_main_bin_start)); + ESP_ERROR_CHECK(err); + + /* The first argument is the period index, which is not used by the ULP-RISC-V timer + * The second argument is the period in microseconds, which gives a wakeup time period of: 750ms + */ + ulp_set_wakeup_period(0, WAKEUP_PERIOD_US); + + /* Start the program */ + err = ulp_riscv_run(); + ESP_ERROR_CHECK(err); +} diff --git a/examples/system/ulp_riscv/sdkconfig.defaults b/examples/system/ulp_riscv/ds18b20_onewire/sdkconfig.defaults similarity index 100% rename from examples/system/ulp_riscv/sdkconfig.defaults rename to examples/system/ulp_riscv/ds18b20_onewire/sdkconfig.defaults diff --git a/examples/system/ulp_riscv/CMakeLists.txt b/examples/system/ulp_riscv/gpio/CMakeLists.txt similarity index 100% rename from examples/system/ulp_riscv/CMakeLists.txt rename to examples/system/ulp_riscv/gpio/CMakeLists.txt diff --git a/examples/system/ulp_riscv/README.md b/examples/system/ulp_riscv/gpio/README.md similarity index 100% rename from examples/system/ulp_riscv/README.md rename to examples/system/ulp_riscv/gpio/README.md diff --git a/examples/system/ulp_riscv/example_test.py b/examples/system/ulp_riscv/gpio/example_test.py similarity index 95% rename from examples/system/ulp_riscv/example_test.py rename to examples/system/ulp_riscv/gpio/example_test.py index 735fdb7aaa..b2bac053fb 100644 --- a/examples/system/ulp_riscv/example_test.py +++ b/examples/system/ulp_riscv/gpio/example_test.py @@ -9,7 +9,7 @@ from tiny_test_fw import DUT @ttfw_idf.idf_example_test(env_tag='Example_GENERIC', target=['esp32s2']) def test_examples_ulp_riscv(env, extra_data): # type: (tiny_test_fw.Env.Env, None) -> None # pylint: disable=unused-argument - dut = env.get_dut('ulp_riscv', 'examples/system/ulp_riscv') + dut = env.get_dut('ulp_riscv', 'examples/system/ulp_riscv/gpio') dut.start_app() dut.expect_all('Not a ULP-RISC-V wakeup, initializing it!', diff --git a/examples/system/ulp_riscv/main/CMakeLists.txt b/examples/system/ulp_riscv/gpio/main/CMakeLists.txt similarity index 100% rename from examples/system/ulp_riscv/main/CMakeLists.txt rename to examples/system/ulp_riscv/gpio/main/CMakeLists.txt diff --git a/examples/system/ulp_riscv/main/ulp/main.c b/examples/system/ulp_riscv/gpio/main/ulp/main.c similarity index 86% rename from examples/system/ulp_riscv/main/ulp/main.c rename to examples/system/ulp_riscv/gpio/main/ulp/main.c index 2d5e75addf..2f24ba377a 100644 --- a/examples/system/ulp_riscv/main/ulp/main.c +++ b/examples/system/ulp_riscv/gpio/main/ulp/main.c @@ -14,7 +14,7 @@ #include #include "ulp_riscv/ulp_riscv.h" #include "ulp_riscv/ulp_riscv_utils.h" -#include "example_ulp_gpio.h" +#include "ulp_riscv/ulp_riscv_gpio.h" static bool gpio_level = false; @@ -23,11 +23,11 @@ bool gpio_level_previous = false; int main (void) { - gpio_level = (bool)example_ulp_gpio_get_level(GPIO_NUM_0); + gpio_level = (bool)ulp_riscv_gpio_get_level(GPIO_NUM_0); gpio_level_previous = gpio_level; while(1) { - gpio_level = (bool)example_ulp_gpio_get_level(GPIO_NUM_0); + gpio_level = (bool)ulp_riscv_gpio_get_level(GPIO_NUM_0); /* Wakes up the main CPU if pin changed its state */ if(gpio_level != gpio_level_previous) { @@ -35,7 +35,6 @@ int main (void) ulp_riscv_wakeup_main_processor(); break; } - } /* ulp_riscv_shutdown() is called automatically when main exits */ return 0; diff --git a/examples/system/ulp_riscv/main/ulp_riscv_example_main.c b/examples/system/ulp_riscv/gpio/main/ulp_riscv_example_main.c similarity index 97% rename from examples/system/ulp_riscv/main/ulp_riscv_example_main.c rename to examples/system/ulp_riscv/gpio/main/ulp_riscv_example_main.c index 7bed64e64b..de9c20e3bb 100644 --- a/examples/system/ulp_riscv/main/ulp_riscv_example_main.c +++ b/examples/system/ulp_riscv/gpio/main/ulp_riscv_example_main.c @@ -1,4 +1,4 @@ -/* ULP riscv example +/* ULP riscv DS18B20 1wire temperature sensor example This example code is in the Public Domain (or CC0 licensed, at your option.) diff --git a/examples/system/ulp_riscv/gpio/sdkconfig.defaults b/examples/system/ulp_riscv/gpio/sdkconfig.defaults new file mode 100644 index 0000000000..1a3d12b265 --- /dev/null +++ b/examples/system/ulp_riscv/gpio/sdkconfig.defaults @@ -0,0 +1,10 @@ +CONFIG_IDF_TARGET="esp32s2" +# Enable ULP +CONFIG_ESP32S2_ULP_COPROC_ENABLED=y +CONFIG_ESP32S2_ULP_COPROC_RISCV=y +CONFIG_ESP32S2_ULP_COPROC_RESERVE_MEM=4096 +# Set log level to Warning to produce clean output +CONFIG_BOOTLOADER_LOG_LEVEL_WARN=y +CONFIG_BOOTLOADER_LOG_LEVEL=2 +CONFIG_LOG_DEFAULT_LEVEL_WARN=y +CONFIG_LOG_DEFAULT_LEVEL=2 diff --git a/tools/ci/mypy_ignore_list.txt b/tools/ci/mypy_ignore_list.txt index 766c57e3dc..75ec56e8c0 100644 --- a/tools/ci/mypy_ignore_list.txt +++ b/tools/ci/mypy_ignore_list.txt @@ -144,8 +144,8 @@ examples/system/startup_time/example_test.py examples/system/sysview_tracing/example_test.py examples/system/sysview_tracing_heap_log/example_test.py examples/system/task_watchdog/example_test.py -examples/system/ulp/example_test.py -examples/system/ulp_adc/example_test.py +examples/system/ulp_fsm/ulp/example_test.py +examples/system/ulp_fsm/ulp_adc/example_test.py examples/system/unit_test/example_test.py examples/wifi/iperf/iperf_test.py tools/ble/lib_ble_client.py