From bc74cf808d24f8a6ee5de0461754e9db29670757 Mon Sep 17 00:00:00 2001 From: Sudeep Mohanty Date: Mon, 12 Feb 2024 13:40:57 +0100 Subject: [PATCH 1/4] feat(ulp-riscv): Added Kconfig option to enable ULP RISC-V interrupts This commit adds a Kconfig option, CONFIG_ULP_RISCV_INTERRUPT_ENABLE, to enable interrupts on the ULP RISC-V core on the esp32s2 and esp32s3. --- components/ulp/Kconfig | 7 +++++++ components/ulp/ulp_riscv/ulp_core/include/ulp_riscv_gpio.h | 5 +++++ .../ulp/ulp_riscv/ulp_core/include/ulp_riscv_interrupt.h | 4 ++++ .../ulp/ulp_riscv/ulp_core/include/ulp_riscv_utils.h | 3 +++ components/ulp/ulp_riscv/ulp_core/start.S | 5 ++++- components/ulp/ulp_riscv/ulp_core/ulp_riscv_gpio.c | 3 +++ components/ulp/ulp_riscv/ulp_core/ulp_riscv_interrupt.c | 7 ++++++- components/ulp/ulp_riscv/ulp_core/ulp_riscv_utils.c | 7 ++++++- components/ulp/ulp_riscv/ulp_core/ulp_riscv_vectors.S | 6 +++++- .../system/ulp/ulp_riscv/interrupts/sdkconfig.defaults | 1 + 10 files changed, 44 insertions(+), 4 deletions(-) diff --git a/components/ulp/Kconfig b/components/ulp/Kconfig index fd144a4087..5b8a7c5ce1 100644 --- a/components/ulp/Kconfig +++ b/components/ulp/Kconfig @@ -43,6 +43,13 @@ menu "Ultra Low Power (ULP) Co-processor" menu "ULP RISC-V Settings" depends on ULP_COPROC_TYPE_RISCV + config ULP_RISCV_INTERRUPT_ENABLE + bool + prompt "Enable ULP RISC-V interrupts" + default "n" + help + Turn on this setting to enabled interrupts on the ULP RISC-V core. + config ULP_RISCV_UART_BAUDRATE int prompt "Baudrate used by the bitbanged ULP RISC-V UART driver" diff --git a/components/ulp/ulp_riscv/ulp_core/include/ulp_riscv_gpio.h b/components/ulp/ulp_riscv/ulp_core/include/ulp_riscv_gpio.h index 7deffbaab7..11e486c2f6 100644 --- a/components/ulp/ulp_riscv/ulp_core/include/ulp_riscv_gpio.h +++ b/components/ulp/ulp_riscv/ulp_core/include/ulp_riscv_gpio.h @@ -10,6 +10,7 @@ extern "C" { #endif +#include "sdkconfig.h" #include "soc/rtc_io_reg.h" #include "soc/sens_reg.h" #include "ulp_riscv_register_ops.h" @@ -131,6 +132,8 @@ 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); } +#if CONFIG_ULP_RISCV_INTERRUPT_ENABLE + /** * @brief Set RTC IO interrupt type and handler * @@ -152,6 +155,8 @@ esp_err_t ulp_riscv_gpio_isr_register(gpio_num_t gpio_num, ulp_riscv_gpio_int_ty */ esp_err_t ulp_riscv_gpio_isr_deregister(gpio_num_t gpio_num); +#endif /* CONFIG_ULP_RISCV_INTERRUPT_ENABLE */ + #ifdef __cplusplus } #endif diff --git a/components/ulp/ulp_riscv/ulp_core/include/ulp_riscv_interrupt.h b/components/ulp/ulp_riscv/ulp_core/include/ulp_riscv_interrupt.h index 746acf095e..0bdba291d5 100644 --- a/components/ulp/ulp_riscv/ulp_core/include/ulp_riscv_interrupt.h +++ b/components/ulp/ulp_riscv/ulp_core/include/ulp_riscv_interrupt.h @@ -14,6 +14,8 @@ extern "C" { #endif +#if CONFIG_ULP_RISCV_INTERRUPT_ENABLE + /* ULP RISC-V Interrupt sources */ typedef enum { ULP_RISCV_SW_INTR_SOURCE = 0, /**< Interrupt triggered by SW */ @@ -62,6 +64,8 @@ esp_err_t ulp_riscv_intr_alloc(ulp_riscv_interrupt_source_t source, intr_handler */ esp_err_t ulp_riscv_intr_free(ulp_riscv_interrupt_source_t source); +#endif /* CONFIG_ULP_RISCV_INTERRUPT_ENABLE */ + #ifdef __cplusplus } #endif diff --git a/components/ulp/ulp_riscv/ulp_core/include/ulp_riscv_utils.h b/components/ulp/ulp_riscv/ulp_core/include/ulp_riscv_utils.h index e8a07d3c4d..463da9d37c 100644 --- a/components/ulp/ulp_riscv/ulp_core/include/ulp_riscv_utils.h +++ b/components/ulp/ulp_riscv/ulp_core/include/ulp_riscv_utils.h @@ -111,6 +111,7 @@ void static inline ulp_riscv_delay_cycles(uint32_t cycles) */ void ulp_riscv_gpio_wakeup_clear(void); +#if CONFIG_ULP_RISCV_INTERRUPT_ENABLE /** * @brief Enable ULP RISC-V SW Interrupt * @@ -131,6 +132,8 @@ void ulp_riscv_disable_sw_intr(void); */ void ulp_riscv_trigger_sw_intr(void); +#endif /* CONFIG_ULP_RISCV_INTERRUPT_ENABLE */ + #ifdef __cplusplus } #endif diff --git a/components/ulp/ulp_riscv/ulp_core/start.S b/components/ulp/ulp_riscv/ulp_core/start.S index cad6db5f5a..e1f0b123e1 100644 --- a/components/ulp/ulp_riscv/ulp_core/start.S +++ b/components/ulp/ulp_riscv/ulp_core/start.S @@ -1,9 +1,10 @@ /* - * SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2022-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ +#include "sdkconfig.h" #include "ulp_riscv_interrupt_ops.h" .section .text @@ -14,8 +15,10 @@ __start: /* setup the stack pointer */ la sp, __stack_top +#if CONFIG_ULP_RISCV_INTERRUPT_ENABLE /* Enable interrupts globally */ maskirq_insn(zero, zero) +#endif /* CONFIG_ULP_RISCV_INTERRUPT_ENABLE */ /* Start ULP user code */ call ulp_riscv_rescue_from_monitor diff --git a/components/ulp/ulp_riscv/ulp_core/ulp_riscv_gpio.c b/components/ulp/ulp_riscv/ulp_core/ulp_riscv_gpio.c index 43d370644a..ae0792c0d5 100644 --- a/components/ulp/ulp_riscv/ulp_core/ulp_riscv_gpio.c +++ b/components/ulp/ulp_riscv/ulp_core/ulp_riscv_gpio.c @@ -3,9 +3,11 @@ * * SPDX-License-Identifier: Apache-2.0 */ +#include "sdkconfig.h" #include "ulp_riscv_gpio.h" #include "include/ulp_riscv_gpio.h" +#if CONFIG_ULP_RISCV_INTERRUPT_ENABLE esp_err_t ulp_riscv_gpio_isr_register(gpio_num_t gpio_num, ulp_riscv_gpio_int_type_t intr_type, intr_handler_t handler, void *arg) { if (gpio_num < 0 || gpio_num >= GPIO_NUM_MAX) { @@ -31,3 +33,4 @@ esp_err_t ulp_riscv_gpio_isr_deregister(gpio_num_t gpio_num) { return ulp_riscv_intr_free(ULP_RISCV_RTCIO0_INTR_SOURCE + gpio_num); } +#endif /* CONFIG_ULP_RISCV_INTERRUPT_ENABLE */ diff --git a/components/ulp/ulp_riscv/ulp_core/ulp_riscv_interrupt.c b/components/ulp/ulp_riscv/ulp_core/ulp_riscv_interrupt.c index e236acd989..18b5a418d3 100644 --- a/components/ulp/ulp_riscv/ulp_core/ulp_riscv_interrupt.c +++ b/components/ulp/ulp_riscv/ulp_core/ulp_riscv_interrupt.c @@ -1,15 +1,18 @@ /* - * SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2023-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ #include +#include "sdkconfig.h" #include "include/ulp_riscv_interrupt.h" #include "ulp_riscv_register_ops.h" #include "ulp_riscv_interrupt.h" #include "ulp_riscv_gpio.h" #include "soc/sens_reg.h" +#if CONFIG_ULP_RISCV_INTERRUPT_ENABLE + #define ULP_RISCV_TIMER_INT (1 << 0U) /* Internal Timer Interrupt */ #define ULP_RISCV_EBREAK_ECALL_ILLEGAL_INSN_INT (1 << 1U) /* EBREAK, ECALL or Illegal instruction */ #define ULP_RISCV_BUS_ERROR_INT (1 << 2U) /* Bus Error (Unaligned Memory Access) */ @@ -130,3 +133,5 @@ void __attribute__((weak)) _ulp_riscv_interrupt_handler(uint32_t q1) /* TODO: RTC I2C interrupt */ } } + +#endif /* CONFIG_ULP_RISCV_INTERRUPT_ENABLE */ diff --git a/components/ulp/ulp_riscv/ulp_core/ulp_riscv_utils.c b/components/ulp/ulp_riscv/ulp_core/ulp_riscv_utils.c index c4b8027fe7..8fce93363a 100644 --- a/components/ulp/ulp_riscv/ulp_core/ulp_riscv_utils.c +++ b/components/ulp/ulp_riscv/ulp_core/ulp_riscv_utils.c @@ -1,9 +1,10 @@ /* - * SPDX-FileCopyrightText: 2015-2023 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2015-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ +#include "sdkconfig.h" #include "ulp_riscv_utils.h" #include "ulp_riscv_register_ops.h" #include "soc/soc.h" @@ -48,6 +49,8 @@ void ulp_riscv_gpio_wakeup_clear(void) SET_PERI_REG_MASK(RTC_CNTL_ULP_CP_TIMER_REG, RTC_CNTL_ULP_CP_GPIO_WAKEUP_CLR); } +#if CONFIG_ULP_RISCV_INTERRUPT_ENABLE + void ulp_riscv_enable_sw_intr(intr_handler_t handler, void *arg) { /* Enable ULP RISC-V SW interrupt */ @@ -72,3 +75,5 @@ void ulp_riscv_trigger_sw_intr(void) { SET_PERI_REG_MASK(RTC_CNTL_COCPU_CTRL_REG, RTC_CNTL_COCPU_SW_INT_TRIGGER); } + +#endif /* CONFIG_ULP_RISCV_INTERRUPT_ENABLE */ diff --git a/components/ulp/ulp_riscv/ulp_core/ulp_riscv_vectors.S b/components/ulp/ulp_riscv/ulp_core/ulp_riscv_vectors.S index b302db429a..855894ce45 100644 --- a/components/ulp/ulp_riscv/ulp_core/ulp_riscv_vectors.S +++ b/components/ulp/ulp_riscv/ulp_core/ulp_riscv_vectors.S @@ -1,9 +1,10 @@ /* - * SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2023-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ +#include "sdkconfig.h" #include "ulp_riscv_interrupt_ops.h" #include "riscv/rvruntime-frames.h" .equ SAVE_REGS, 17 @@ -69,6 +70,7 @@ reset_vector: j __start +#if CONFIG_ULP_RISCV_INTERRUPT_ENABLE /* Interrupt handler */ .balign 0x10 irq_vector: @@ -89,3 +91,5 @@ irq_vector: /* Exit interrupt handler by executing the custom retirq instruction which will retore pc and re-enable interrupts */ retirq_insn() + +#endif /* CONFIG_ULP_RISCV_INTERRUPT_ENABLE */ diff --git a/examples/system/ulp/ulp_riscv/interrupts/sdkconfig.defaults b/examples/system/ulp/ulp_riscv/interrupts/sdkconfig.defaults index e3745e5057..16f5110d63 100644 --- a/examples/system/ulp/ulp_riscv/interrupts/sdkconfig.defaults +++ b/examples/system/ulp/ulp_riscv/interrupts/sdkconfig.defaults @@ -2,6 +2,7 @@ CONFIG_ULP_COPROC_ENABLED=y CONFIG_ULP_COPROC_TYPE_RISCV=y CONFIG_ULP_COPROC_RESERVE_MEM=4096 +CONFIG_ULP_RISCV_INTERRUPT_ENABLE=y # Set log level to Warning to produce clean output CONFIG_BOOTLOADER_LOG_LEVEL_WARN=y CONFIG_BOOTLOADER_LOG_LEVEL=2 From d352ec615a6568e65f4d440a242e299b2acbbc26 Mon Sep 17 00:00:00 2001 From: Sudeep Mohanty Date: Mon, 12 Feb 2024 13:53:11 +0100 Subject: [PATCH 2/4] feat(ulp-riscv): Added utility functions for atomicity This commit adds utility functions to enter and exit critical sections in the code flow by disabling and enabling interrupts. --- .../ulp_core/include/ulp_riscv_utils.h | 26 +++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/components/ulp/ulp_riscv/ulp_core/include/ulp_riscv_utils.h b/components/ulp/ulp_riscv/ulp_core/include/ulp_riscv_utils.h index 463da9d37c..acc47a28bf 100644 --- a/components/ulp/ulp_riscv/ulp_core/include/ulp_riscv_utils.h +++ b/components/ulp/ulp_riscv/ulp_core/include/ulp_riscv_utils.h @@ -132,6 +132,32 @@ void ulp_riscv_disable_sw_intr(void); */ void ulp_riscv_trigger_sw_intr(void); +/** + * @brief Enter a critical section by disabling all interrupts + * This inline assembly construct uses the t0 register and is equivalent to: + * + * li t0, 0x80000007 + * maskirq_insn(zero, t0) // Mask all interrupt bits + */ +#define ULP_RISCV_ENTER_CRITICAL() \ + asm volatile ( \ + "li t0, 0x80000007\n" \ + ".word 0x0602e00b" \ + ); \ + +/** + * @brief Exit a critical section by enabling all interrupts + * This inline assembly construct is equivalent to: + * + * maskirq_insn(zero, zero) // Unmask all interrupt bits + */ +#define ULP_RISCV_EXIT_CRITICAL() asm volatile (".word 0x0600600b"); + +#else /* CONFIG_ULP_RISCV_INTERRUPT_ENABLE */ + +#define ULP_RISCV_ENTER_CRITICAL() +#define ULP_RISCV_EXIT_CRITICAL() + #endif /* CONFIG_ULP_RISCV_INTERRUPT_ENABLE */ #ifdef __cplusplus From 993c8d4f0e102cef649c122aa8ee7b3fe1d91e7a Mon Sep 17 00:00:00 2001 From: Sudeep Mohanty Date: Thu, 1 Feb 2024 10:10:48 +0100 Subject: [PATCH 3/4] fix(ulp-riscv): Wrapped all RTC I2C and UART operations in critical sections This commit adds a workaround for a bug where the RTC I2C operations result in a Bus Error when interrupts are enabled. The commit also adds a critical section protection for UART print operations. --- components/ulp/ulp_riscv/ulp_core/ulp_riscv_i2c.c | 12 ++++++++++++ components/ulp/ulp_riscv/ulp_core/ulp_riscv_print.c | 11 +++++++++++ 2 files changed, 23 insertions(+) diff --git a/components/ulp/ulp_riscv/ulp_core/ulp_riscv_i2c.c b/components/ulp/ulp_riscv/ulp_core/ulp_riscv_i2c.c index 1da395304e..75c39faf46 100644 --- a/components/ulp/ulp_riscv/ulp_core/ulp_riscv_i2c.c +++ b/components/ulp/ulp_riscv/ulp_core/ulp_riscv_i2c.c @@ -141,6 +141,9 @@ void ulp_riscv_i2c_master_read_from_device(uint8_t *data_rd, size_t size) return; } + // Workaround for IDF-9145 + ULP_RISCV_ENTER_CRITICAL(); + /* By default, RTC I2C controller is hard wired to use CMD2 register onwards for read operations */ cmd_idx = 2; @@ -201,6 +204,9 @@ void ulp_riscv_i2c_master_read_from_device(uint8_t *data_rd, size_t size) /* Clear the RTC I2C transmission bits */ CLEAR_PERI_REG_MASK(SENS_SAR_I2C_CTRL_REG, SENS_SAR_I2C_START_FORCE); CLEAR_PERI_REG_MASK(SENS_SAR_I2C_CTRL_REG, SENS_SAR_I2C_START); + + // Workaround for IDF-9145 + ULP_RISCV_EXIT_CRITICAL(); } /* @@ -230,6 +236,9 @@ void ulp_riscv_i2c_master_write_to_device(uint8_t *data_wr, size_t size) return; } + // Workaround for IDF-9145 + ULP_RISCV_ENTER_CRITICAL(); + /* By default, RTC I2C controller is hard wired to use CMD0 and CMD1 registers for write operations */ cmd_idx = 0; @@ -269,4 +278,7 @@ void ulp_riscv_i2c_master_write_to_device(uint8_t *data_wr, size_t size) /* Clear the RTC I2C transmission bits */ CLEAR_PERI_REG_MASK(SENS_SAR_I2C_CTRL_REG, SENS_SAR_I2C_START_FORCE); CLEAR_PERI_REG_MASK(SENS_SAR_I2C_CTRL_REG, SENS_SAR_I2C_START); + + // Workaround for IDF-9145 + ULP_RISCV_EXIT_CRITICAL(); } diff --git a/components/ulp/ulp_riscv/ulp_core/ulp_riscv_print.c b/components/ulp/ulp_riscv/ulp_core/ulp_riscv_print.c index ae6ce8c1ee..6c3ed2c88a 100644 --- a/components/ulp/ulp_riscv/ulp_core/ulp_riscv_print.c +++ b/components/ulp/ulp_riscv/ulp_core/ulp_riscv_print.c @@ -4,6 +4,7 @@ * SPDX-License-Identifier: Apache-2.0 */ #include "ulp_riscv_print.h" +#include "ulp_riscv_utils.h" typedef struct { putc_fn_t putc; // Putc function of the underlying driver, e.g. UART @@ -24,9 +25,14 @@ void ulp_riscv_print_str(const char *str) return; } + /* Perform the bit-banged UART operation in a critical section */ + ULP_RISCV_ENTER_CRITICAL(); + for (int i = 0; str[i] != 0; i++) { s_print_ctx.putc(s_print_ctx.putc_ctx, str[i]); } + + ULP_RISCV_EXIT_CRITICAL(); } void ulp_riscv_print_hex(int h) @@ -38,6 +44,9 @@ void ulp_riscv_print_hex(int h) return; } + /* Perform the bit-banged UART operation in a critical section */ + ULP_RISCV_ENTER_CRITICAL(); + // Does not print '0x', only the digits (8 digits to print) for (x = 0; x < 8; x++) { c = (h >> 28) & 0xf; // extract the leftmost byte @@ -48,4 +57,6 @@ void ulp_riscv_print_hex(int h) } h <<= 4; // move the 2nd leftmost byte to the left, to be extracted next } + + ULP_RISCV_EXIT_CRITICAL(); } From 1c015a3f0d812278cf5e94aa11766d5e7849e205 Mon Sep 17 00:00:00 2001 From: Sudeep Mohanty Date: Thu, 15 Feb 2024 14:03:27 +0100 Subject: [PATCH 4/4] feat(ulp-riscv): Added unit test for RTC I2C This commit adds a unit-test for RTC I2C operation on the ULP RISC-V. --- .../ulp/test_apps/ulp_riscv/CMakeLists.txt | 4 + .../test_apps/ulp_riscv/main/CMakeLists.txt | 7 +- .../ulp_riscv/main/test_ulp_riscv_i2c.c | 166 ++++++++++++++++++ .../ulp_riscv/main/ulp/test_main_i2c.c | 42 +++++ .../ulp_riscv/main/ulp/ulp_test_shared.h | 8 +- .../test_apps/ulp_riscv/pytest_ulp_riscv.py | 20 ++- 6 files changed, 240 insertions(+), 7 deletions(-) create mode 100644 components/ulp/test_apps/ulp_riscv/main/test_ulp_riscv_i2c.c create mode 100644 components/ulp/test_apps/ulp_riscv/main/ulp/test_main_i2c.c diff --git a/components/ulp/test_apps/ulp_riscv/CMakeLists.txt b/components/ulp/test_apps/ulp_riscv/CMakeLists.txt index a01a170120..7c6144aee8 100644 --- a/components/ulp/test_apps/ulp_riscv/CMakeLists.txt +++ b/components/ulp/test_apps/ulp_riscv/CMakeLists.txt @@ -3,6 +3,10 @@ cmake_minimum_required(VERSION 3.16) list(PREPEND SDKCONFIG_DEFAULTS "$ENV{IDF_PATH}/tools/test_apps/configs/sdkconfig.debug_helpers" "sdkconfig.defaults") +set(EXTRA_COMPONENT_DIRS + "$ENV{IDF_PATH}/tools/unit-test-app/components" +) + # "Trim" the build. Include the minimal set of components, main, and anything it depends on. set(COMPONENTS main) diff --git a/components/ulp/test_apps/ulp_riscv/main/CMakeLists.txt b/components/ulp/test_apps/ulp_riscv/main/CMakeLists.txt index 3ba838bd9b..ff7fe44941 100644 --- a/components/ulp/test_apps/ulp_riscv/main/CMakeLists.txt +++ b/components/ulp/test_apps/ulp_riscv/main/CMakeLists.txt @@ -1,17 +1,20 @@ -set(app_sources "test_app_main.c" "test_ulp_riscv.c") +set(app_sources "test_app_main.c" "test_ulp_riscv.c" "test_ulp_riscv_i2c.c") set(ulp_sources "ulp/test_main.c") set(ulp_sources2 "ulp/test_main_second_cocpu_firmware.c") set(ulp_sources3 "ulp/test_main_cocpu_crash.c") +set(ulp_sources4 "ulp/test_main_i2c.c") idf_component_register(SRCS ${app_sources} INCLUDE_DIRS "ulp" - REQUIRES ulp unity + REQUIRES ulp unity test_utils WHOLE_ARCHIVE) set(ulp_app_name ulp_test_app) set(ulp_app_name2 ulp_test_app2) set(ulp_app_name3 ulp_test_app3) +set(ulp_app_name4 ulp_test_app_i2c) set(ulp_exp_dep_srcs ${app_sources}) ulp_embed_binary(${ulp_app_name} "${ulp_sources}" "${ulp_exp_dep_srcs}") ulp_embed_binary(${ulp_app_name2} "${ulp_sources2}" "${ulp_exp_dep_srcs}") ulp_embed_binary(${ulp_app_name3} "${ulp_sources3}" "${ulp_exp_dep_srcs}") +ulp_embed_binary(${ulp_app_name4} "${ulp_sources4}" "${ulp_exp_dep_srcs}") diff --git a/components/ulp/test_apps/ulp_riscv/main/test_ulp_riscv_i2c.c b/components/ulp/test_apps/ulp_riscv/main/test_ulp_riscv_i2c.c new file mode 100644 index 0000000000..2be2e701c2 --- /dev/null +++ b/components/ulp/test_apps/ulp_riscv/main/test_ulp_riscv_i2c.c @@ -0,0 +1,166 @@ +/* + * SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include "ulp_riscv.h" +#include "ulp_riscv_i2c.h" +#include "ulp_test_app_i2c.h" +#include "ulp_test_shared.h" +#include "unity.h" +#include "test_utils.h" +#include "esp_log.h" +#include "driver/i2c.h" + +#define ULP_WAKEUP_PERIOD 1000000 // 1 second +static const char* TAG = "ulp_riscv_i2c_test"; + +// ULP RISC-V RTC I2C firmware +extern const uint8_t ulp_test_app_i2c_bin_start[] asm("_binary_ulp_test_app_i2c_bin_start"); +extern const size_t ulp_test_app_i2c_bin_length asm("ulp_test_app_i2c_bin_length"); + +static void load_and_start_ulp_riscv_firmware(const uint8_t* ulp_bin, size_t ulp_bin_len) +{ + TEST_ASSERT(ulp_riscv_load_binary(ulp_bin, ulp_bin_len) == ESP_OK); + TEST_ASSERT(ulp_set_wakeup_period(0, ULP_WAKEUP_PERIOD) == ESP_OK); + TEST_ASSERT(ulp_riscv_run() == ESP_OK); +} + +#define I2C_SLAVE_SCL_IO 7 /*! +#include "ulp_test_shared.h" +// #include "ulp_riscv.h" +#include "ulp_riscv_utils.h" +#include "ulp_riscv_i2c_ulp_core.h" + +volatile riscv_test_command_reply_t read_test_reply = RISCV_COMMAND_INVALID; +volatile riscv_test_command_reply_t write_test_cmd = RISCV_COMMAND_INVALID; + +uint8_t data_rd[DATA_LENGTH] = {}; +uint8_t data_wr[DATA_LENGTH] = {}; + +int main(void) +{ + /* Set I2C slave device address */ + ulp_riscv_i2c_master_set_slave_addr(I2C_SLAVE_ADDRESS); + + /* Read from the I2C slave device */ + ulp_riscv_i2c_master_read_from_device(data_rd, RW_TEST_LENGTH); + + /* Signal the main CPU once read is done */ + read_test_reply = RISCV_COMMAND_OK; + + /* Wait for write command from main CPU */ + while (write_test_cmd != RISCV_COMMAND_OK) { + } + + /* Write to the I2C slave device */ + ulp_riscv_i2c_master_write_to_device(data_wr, RW_TEST_LENGTH); + + /* Signal the main CPU once write is done */ + write_test_cmd = RISCV_COMMAND_NOK; + + while (1) { + } +} diff --git a/components/ulp/test_apps/ulp_riscv/main/ulp/ulp_test_shared.h b/components/ulp/test_apps/ulp_riscv/main/ulp/ulp_test_shared.h index babcdeb10f..33ef18e67a 100644 --- a/components/ulp/test_apps/ulp_riscv/main/ulp/ulp_test_shared.h +++ b/components/ulp/test_apps/ulp_riscv/main/ulp/ulp_test_shared.h @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2022-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Unlicense OR CC0-1.0 */ @@ -8,6 +8,12 @@ #define MUTEX_TEST_ITERATIONS 100000 #define XOR_MASK 0xDEADBEEF +/* I2C test params */ +#define I2C_SLAVE_ADDRESS 0x28 +#define DATA_LENGTH 200 +// TODO: Updated the test to perform multi-byte read/write (IDFGH-11056) +#define RW_TEST_LENGTH 1 /*! None: # type: ignore - case_tester.run_all_cases() +def test_ulp_riscv(dut: Dut) -> None: # type: ignore + dut.run_all_single_board_cases() + + +@pytest.mark.esp32s2 +@pytest.mark.esp32s3 +@pytest.mark.generic_multi_device +@pytest.mark.parametrize( + 'count', [2], indirect=True +) +def test_ulp_riscv_multi_device(case_tester) -> None: # type: ignore + for case in case_tester.test_menu: + if case.attributes.get('test_env', 'generic_multi_device') == 'generic_multi_device': + case_tester.run_multi_dev_case(case=case, reset=True)