Kaynağa Gözat

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

Marius Vikhammer 4 yıl önce
ebeveyn
işleme
386739595f
38 değiştirilmiş dosya ile 369 ekleme ve 25 silme
  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)
 esp_err_t ulp_riscv_run(void)
 {
 {
     /* Reset COCPU when power on. */
     /* 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);
     SET_PERI_REG_MASK(RTC_CNTL_COCPU_CTRL_REG, RTC_CNTL_COCPU_SHUT_RESET_EN);
     esp_rom_delay_us(20);
     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);
     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 */
     /* Disable ULP timer */
     CLEAR_PERI_REG_MASK(RTC_CNTL_ULP_CP_TIMER_REG, RTC_CNTL_ULP_CP_SLP_TIMER_EN);
     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 */
     /* 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 "ulp_riscv/ulp_riscv.h"
 #include "soc/rtc_io_reg.h"
 #include "soc/rtc_io_reg.h"
+#include "soc/sens_reg.h"
+
 
 
 typedef enum {
 typedef enum {
     GPIO_NUM_0 = 0,     /*!< GPIO0, input and output */
     GPIO_NUM_0 = 0,     /*!< GPIO0, input and output */
@@ -51,38 +53,39 @@ typedef enum {
     RTCIO_MODE_OUTPUT_OD = 1,
     RTCIO_MODE_OUTPUT_OD = 1,
 } rtc_io_out_mode_t;
 } 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);
     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);
     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);
     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));
     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));
     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);
     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);
     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) {
     if (level) {
         REG_SET_FIELD(RTC_GPIO_OUT_W1TS_REG, RTC_GPIO_OUT_DATA_W1TS, BIT(gpio_num));
         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);
     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);
     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);
     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);
     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);
     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);
     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);
 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
 #ifdef __cplusplus
 }
 }
 #endif
 #endif

+ 9 - 0
components/ulp/ulp_riscv/ulp_riscv_utils.c

@@ -39,3 +39,12 @@ void ulp_riscv_shutdown(void)
 
 
     while(1);
     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'])
 @ttfw_idf.idf_example_test(env_tag='Example_GENERIC', target=['esp32'])
 def test_examples_ulp(env, extra_data):
 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.start_app()
 
 
     dut.expect_all('Not ULP wakeup, initializing ULP',
     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'])
 @ttfw_idf.idf_example_test(env_tag='Example_GENERIC', target=['esp32'])
 def test_examples_ulp_adc(env, extra_data):
 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.start_app()
 
 
     dut.expect_all('Not ULP wakeup',
     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'])
 @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
 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.start_app()
 
 
     dut.expect_all('Not a ULP-RISC-V wakeup, initializing it!',
     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 <stdbool.h>
 #include "ulp_riscv/ulp_riscv.h"
 #include "ulp_riscv/ulp_riscv.h"
 #include "ulp_riscv/ulp_riscv_utils.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;
 static bool gpio_level = false;
 
 
@@ -23,11 +23,11 @@ bool gpio_level_previous = false;
 
 
 int main (void)
 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;
     gpio_level_previous = gpio_level;
 
 
     while(1) {
     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 */
         /* Wakes up the main CPU if pin changed its state */
         if(gpio_level != gpio_level_previous) {
         if(gpio_level != gpio_level_previous) {
@@ -35,7 +35,6 @@ int main (void)
             ulp_riscv_wakeup_main_processor();
             ulp_riscv_wakeup_main_processor();
             break;
             break;
         }
         }
-
     }
     }
     /* ulp_riscv_shutdown() is called automatically when main exits */
     /* ulp_riscv_shutdown() is called automatically when main exits */
     return 0;
     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.)
    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/example_test.py
 examples/system/sysview_tracing_heap_log/example_test.py
 examples/system/sysview_tracing_heap_log/example_test.py
 examples/system/task_watchdog/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/system/unit_test/example_test.py
 examples/wifi/iperf/iperf_test.py
 examples/wifi/iperf/iperf_test.py
 tools/ble/lib_ble_client.py
 tools/ble/lib_ble_client.py