Просмотр исходного кода

RISCV-ULP: Add DS18B20 1wire RISCV-ULP example

Marius Vikhammer 4 лет назад
Родитель
Сommit
386739595f
38 измененных файлов с 369 добавлено и 25 удалено
  1. 4 2
      components/ulp/ulp_riscv.c
  2. 16 13
      components/ulp/ulp_riscv/include/ulp_riscv/ulp_riscv_gpio.h
  3. 18 0
      components/ulp/ulp_riscv/include/ulp_riscv/ulp_riscv_utils.h
  4. 9 0
      components/ulp/ulp_riscv/ulp_riscv_utils.c
  5. 0 0
      examples/system/ulp_fsm/ulp/CMakeLists.txt
  6. 0 0
      examples/system/ulp_fsm/ulp/Makefile
  7. 0 0
      examples/system/ulp_fsm/ulp/README.md
  8. 1 1
      examples/system/ulp_fsm/ulp/example_test.py
  9. 0 0
      examples/system/ulp_fsm/ulp/image/ulp_power_graph.png
  10. 0 0
      examples/system/ulp_fsm/ulp/main/CMakeLists.txt
  11. 0 0
      examples/system/ulp_fsm/ulp/main/component.mk
  12. 0 0
      examples/system/ulp_fsm/ulp/main/ulp/pulse_cnt.S
  13. 0 0
      examples/system/ulp_fsm/ulp/main/ulp/wake_up.S
  14. 0 0
      examples/system/ulp_fsm/ulp/main/ulp_example_main.c
  15. 0 0
      examples/system/ulp_fsm/ulp/sdkconfig.defaults
  16. 0 0
      examples/system/ulp_fsm/ulp_adc/CMakeLists.txt
  17. 0 0
      examples/system/ulp_fsm/ulp_adc/Makefile
  18. 0 0
      examples/system/ulp_fsm/ulp_adc/README.md
  19. 1 1
      examples/system/ulp_fsm/ulp_adc/example_test.py
  20. 0 0
      examples/system/ulp_fsm/ulp_adc/main/CMakeLists.txt
  21. 0 0
      examples/system/ulp_fsm/ulp_adc/main/component.mk
  22. 0 0
      examples/system/ulp_fsm/ulp_adc/main/ulp/adc.S
  23. 0 0
      examples/system/ulp_fsm/ulp_adc/main/ulp_adc_example_main.c
  24. 0 0
      examples/system/ulp_fsm/ulp_adc/sdkconfig.defaults
  25. 6 0
      examples/system/ulp_riscv/ds18b20_onewire/CMakeLists.txt
  26. 42 0
      examples/system/ulp_riscv/ds18b20_onewire/README.md
  27. 27 0
      examples/system/ulp_riscv/ds18b20_onewire/main/CMakeLists.txt
  28. 156 0
      examples/system/ulp_riscv/ds18b20_onewire/main/ulp/main.c
  29. 72 0
      examples/system/ulp_riscv/ds18b20_onewire/main/ulp_riscv_ds18b20_example_main.c
  30. 0 0
      examples/system/ulp_riscv/ds18b20_onewire/sdkconfig.defaults
  31. 0 0
      examples/system/ulp_riscv/gpio/CMakeLists.txt
  32. 0 0
      examples/system/ulp_riscv/gpio/README.md
  33. 1 1
      examples/system/ulp_riscv/gpio/example_test.py
  34. 0 0
      examples/system/ulp_riscv/gpio/main/CMakeLists.txt
  35. 3 4
      examples/system/ulp_riscv/gpio/main/ulp/main.c
  36. 1 1
      examples/system/ulp_riscv/gpio/main/ulp_riscv_example_main.c
  37. 10 0
      examples/system/ulp_riscv/gpio/sdkconfig.defaults
  38. 2 2
      tools/ci/mypy_ignore_list.txt

+ 4 - 2
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 */

+ 16 - 13
examples/system/ulp_riscv/main/ulp/example_ulp_gpio.h → 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);
 }

+ 18 - 0
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

+ 9 - 0
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 */
+    }
+}

+ 0 - 0
examples/system/ulp/CMakeLists.txt → examples/system/ulp_fsm/ulp/CMakeLists.txt


+ 0 - 0
examples/system/ulp/Makefile → examples/system/ulp_fsm/ulp/Makefile


+ 0 - 0
examples/system/ulp/README.md → examples/system/ulp_fsm/ulp/README.md


+ 1 - 1
examples/system/ulp/example_test.py → 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',

+ 0 - 0
examples/system/ulp/image/ulp_power_graph.png → examples/system/ulp_fsm/ulp/image/ulp_power_graph.png


+ 0 - 0
examples/system/ulp/main/CMakeLists.txt → examples/system/ulp_fsm/ulp/main/CMakeLists.txt


+ 0 - 0
examples/system/ulp/main/component.mk → examples/system/ulp_fsm/ulp/main/component.mk


+ 0 - 0
examples/system/ulp/main/ulp/pulse_cnt.S → examples/system/ulp_fsm/ulp/main/ulp/pulse_cnt.S


+ 0 - 0
examples/system/ulp/main/ulp/wake_up.S → examples/system/ulp_fsm/ulp/main/ulp/wake_up.S


+ 0 - 0
examples/system/ulp/main/ulp_example_main.c → examples/system/ulp_fsm/ulp/main/ulp_example_main.c


+ 0 - 0
examples/system/ulp/sdkconfig.defaults → examples/system/ulp_fsm/ulp/sdkconfig.defaults


+ 0 - 0
examples/system/ulp_adc/CMakeLists.txt → examples/system/ulp_fsm/ulp_adc/CMakeLists.txt


+ 0 - 0
examples/system/ulp_adc/Makefile → examples/system/ulp_fsm/ulp_adc/Makefile


+ 0 - 0
examples/system/ulp_adc/README.md → examples/system/ulp_fsm/ulp_adc/README.md


+ 1 - 1
examples/system/ulp_adc/example_test.py → 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',

+ 0 - 0
examples/system/ulp_adc/main/CMakeLists.txt → examples/system/ulp_fsm/ulp_adc/main/CMakeLists.txt


+ 0 - 0
examples/system/ulp_adc/main/component.mk → examples/system/ulp_fsm/ulp_adc/main/component.mk


+ 0 - 0
examples/system/ulp_adc/main/ulp/adc.S → examples/system/ulp_fsm/ulp_adc/main/ulp/adc.S


+ 0 - 0
examples/system/ulp_adc/main/ulp_adc_example_main.c → examples/system/ulp_fsm/ulp_adc/main/ulp_adc_example_main.c


+ 0 - 0
examples/system/ulp_adc/sdkconfig.defaults → examples/system/ulp_fsm/ulp_adc/sdkconfig.defaults


+ 6 - 0
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)

+ 42 - 0
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
+
+```

+ 27 - 0
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}")

+ 156 - 0
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 <stdio.h>
+#include <stdint.h>
+#include <stdbool.h>
+#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;
+}

+ 72 - 0
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 <stdio.h>
+#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);
+}

+ 0 - 0
examples/system/ulp_riscv/sdkconfig.defaults → examples/system/ulp_riscv/ds18b20_onewire/sdkconfig.defaults


+ 0 - 0
examples/system/ulp_riscv/CMakeLists.txt → examples/system/ulp_riscv/gpio/CMakeLists.txt


+ 0 - 0
examples/system/ulp_riscv/README.md → examples/system/ulp_riscv/gpio/README.md


+ 1 - 1
examples/system/ulp_riscv/example_test.py → 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!',

+ 0 - 0
examples/system/ulp_riscv/main/CMakeLists.txt → examples/system/ulp_riscv/gpio/main/CMakeLists.txt


+ 3 - 4
examples/system/ulp_riscv/main/ulp/main.c → examples/system/ulp_riscv/gpio/main/ulp/main.c

@@ -14,7 +14,7 @@
 #include <stdbool.h>
 #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;

+ 1 - 1
examples/system/ulp_riscv/main/ulp_riscv_example_main.c → 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.)
 

+ 10 - 0
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

+ 2 - 2
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