From 56af6b5fc4fe1fcef4a44bfc6f2341bcc93b55da Mon Sep 17 00:00:00 2001 From: Armando Date: Wed, 9 Oct 2024 14:50:00 +0800 Subject: [PATCH] test(sleep): vad wakeup hp core test --- .../test_apps/lp_i2s/sdkconfig.ci.defaults | 1 - .../test_apps/.build-test-rules.yml | 4 + .../test_apps/vad_wakeup/CMakeLists.txt | 8 + .../test_apps/vad_wakeup/README.md | 3 + .../test_apps/vad_wakeup/main/CMakeLists.txt | 7 + .../test_apps/vad_wakeup/main/test_app_main.c | 27 +++ .../test_apps/vad_wakeup/main/test_vad_8k.pcm | Bin 0 -> 34272 bytes .../vad_wakeup/main/test_vad_wakeup.c | 162 ++++++++++++++++++ .../test_apps/vad_wakeup/pytest_wakeup_vad.py | 11 ++ .../test_apps/vad_wakeup/sdkconfig.defaults | 8 + .../lp_core_basic_tests/sdkconfig.ci.lp_vad | 1 - 11 files changed, 230 insertions(+), 2 deletions(-) create mode 100644 components/esp_hw_support/test_apps/vad_wakeup/CMakeLists.txt create mode 100644 components/esp_hw_support/test_apps/vad_wakeup/README.md create mode 100644 components/esp_hw_support/test_apps/vad_wakeup/main/CMakeLists.txt create mode 100644 components/esp_hw_support/test_apps/vad_wakeup/main/test_app_main.c create mode 100644 components/esp_hw_support/test_apps/vad_wakeup/main/test_vad_8k.pcm create mode 100644 components/esp_hw_support/test_apps/vad_wakeup/main/test_vad_wakeup.c create mode 100644 components/esp_hw_support/test_apps/vad_wakeup/pytest_wakeup_vad.py create mode 100644 components/esp_hw_support/test_apps/vad_wakeup/sdkconfig.defaults diff --git a/components/esp_driver_i2s/test_apps/lp_i2s/sdkconfig.ci.defaults b/components/esp_driver_i2s/test_apps/lp_i2s/sdkconfig.ci.defaults index 5e9f8e25bd..e69de29bb2 100644 --- a/components/esp_driver_i2s/test_apps/lp_i2s/sdkconfig.ci.defaults +++ b/components/esp_driver_i2s/test_apps/lp_i2s/sdkconfig.ci.defaults @@ -1 +0,0 @@ -CONFIG_ESP_CONSOLE_USB_SERIAL_JTAG=y diff --git a/components/esp_hw_support/test_apps/.build-test-rules.yml b/components/esp_hw_support/test_apps/.build-test-rules.yml index b61d8878c6..a13010cf3a 100644 --- a/components/esp_hw_support/test_apps/.build-test-rules.yml +++ b/components/esp_hw_support/test_apps/.build-test-rules.yml @@ -42,6 +42,10 @@ components/esp_hw_support/test_apps/rtc_power_modes: temporary: true reason: the other targets are not tested yet +components/esp_hw_support/test_apps/vad_wakeup: + disable: + - if: SOC_LP_VAD_SUPPORTED != 1 + components/esp_hw_support/test_apps/wakeup_tests: disable: - if: IDF_TARGET in ["esp32c5", "esp32p4", "linux", "esp32c61"] diff --git a/components/esp_hw_support/test_apps/vad_wakeup/CMakeLists.txt b/components/esp_hw_support/test_apps/vad_wakeup/CMakeLists.txt new file mode 100644 index 0000000000..5036560011 --- /dev/null +++ b/components/esp_hw_support/test_apps/vad_wakeup/CMakeLists.txt @@ -0,0 +1,8 @@ +# This is the project CMakeLists.txt file for the test subproject +cmake_minimum_required(VERSION 3.16) + +# "Trim" the build. Include the minimal set of components, main, and anything it depends on. +set(COMPONENTS main) + +include($ENV{IDF_PATH}/tools/cmake/project.cmake) +project(vad_wakeup) diff --git a/components/esp_hw_support/test_apps/vad_wakeup/README.md b/components/esp_hw_support/test_apps/vad_wakeup/README.md new file mode 100644 index 0000000000..f8ea707124 --- /dev/null +++ b/components/esp_hw_support/test_apps/vad_wakeup/README.md @@ -0,0 +1,3 @@ +| Supported Targets | ESP32-P4 | +| ----------------- | -------- | + diff --git a/components/esp_hw_support/test_apps/vad_wakeup/main/CMakeLists.txt b/components/esp_hw_support/test_apps/vad_wakeup/main/CMakeLists.txt new file mode 100644 index 0000000000..3a92a5d2bd --- /dev/null +++ b/components/esp_hw_support/test_apps/vad_wakeup/main/CMakeLists.txt @@ -0,0 +1,7 @@ +set(srcs "test_app_main.c" + "test_vad_wakeup.c") + +idf_component_register(SRCS ${srcs} + REQUIRES unity esp_driver_i2s esp_driver_uart ulp esp_timer + WHOLE_ARCHIVE + EMBED_FILES "test_vad_8k.pcm") diff --git a/components/esp_hw_support/test_apps/vad_wakeup/main/test_app_main.c b/components/esp_hw_support/test_apps/vad_wakeup/main/test_app_main.c new file mode 100644 index 0000000000..1d34b63e44 --- /dev/null +++ b/components/esp_hw_support/test_apps/vad_wakeup/main/test_app_main.c @@ -0,0 +1,27 @@ +/* + * SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include "unity.h" +#include "unity_test_runner.h" +#include "unity_test_utils.h" + +#define LEAKS (400) + + +void setUp(void) +{ + unity_utils_record_free_mem(); +} + +void tearDown(void) +{ + unity_utils_evaluate_leaks_direct(LEAKS); +} + +void app_main(void) +{ + unity_run_menu(); +} diff --git a/components/esp_hw_support/test_apps/vad_wakeup/main/test_vad_8k.pcm b/components/esp_hw_support/test_apps/vad_wakeup/main/test_vad_8k.pcm new file mode 100644 index 0000000000000000000000000000000000000000..5b6c32a03731f5cee7ba8bfa178b38477ac7f5f4 GIT binary patch literal 34272 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 literal 0 HcmV?d00001 diff --git a/components/esp_hw_support/test_apps/vad_wakeup/main/test_vad_wakeup.c b/components/esp_hw_support/test_apps/vad_wakeup/main/test_vad_wakeup.c new file mode 100644 index 0000000000..2a245bfc6f --- /dev/null +++ b/components/esp_hw_support/test_apps/vad_wakeup/main/test_vad_wakeup.c @@ -0,0 +1,162 @@ +/* + * SPDX-FileCopyrightText: 2021-2024 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Unlicense OR CC0-1.0 + */ + +#include +#include +#include +#include "freertos/FreeRTOS.h" +#include "freertos/task.h" +#include "esp_sleep.h" +#include "esp_log.h" +#include "driver/uart.h" +#include "driver/lp_i2s.h" +#include "driver/lp_i2s_std.h" +#include "driver/i2s_std.h" +#include "ulp_lp_core_lp_vad_shared.h" +#include "unity.h" +#include "esp_timer.h" + +#define TEST_I2S_FRAME_SIZE (128) // Frame numbers in every writing / reading +#define TEST_I2S_TRANS_SIZE (4096) // Trans size +#define TEST_LP_I2S_PIN_BCK 4 +#define TEST_LP_I2S_PIN_WS 5 +#define TEST_LP_I2S_PIN_DIN 6 + + +extern const uint8_t test_vad_pcm_start[] asm("_binary_test_vad_8k_pcm_start"); +extern const uint8_t test_vad_pcm_end[] asm("_binary_test_vad_8k_pcm_end"); +static const char *TAG = "TEST_VAD"; + +static void s_hp_i2s_config(void) +{ + esp_err_t ret = ESP_FAIL; + int pcm_size = test_vad_pcm_end - test_vad_pcm_start; + printf("pcm_size: %d\n", pcm_size); + + i2s_chan_handle_t tx_handle = NULL; + i2s_chan_config_t i2s_channel_config = { + .id = I2S_NUM_0, + .role = I2S_ROLE_MASTER, + .dma_desc_num = 16, + .dma_frame_num = TEST_I2S_FRAME_SIZE, + .auto_clear = false, + }; + TEST_ESP_OK(i2s_new_channel(&i2s_channel_config, &tx_handle, NULL)); + + + i2s_std_config_t i2s_std_config = { + .gpio_cfg = { + .mclk = I2S_GPIO_UNUSED, + .bclk = GPIO_NUM_7, + .ws = GPIO_NUM_8, + .dout = GPIO_NUM_21, + .din = -1, + .invert_flags = { + .mclk_inv = false, + .bclk_inv = false, + .ws_inv = false, + }, + }, + }; + i2s_std_config.clk_cfg = (i2s_std_clk_config_t)I2S_STD_CLK_DEFAULT_CONFIG(16000); + i2s_std_config.slot_cfg = (i2s_std_slot_config_t)I2S_STD_PCM_SLOT_DEFAULT_CONFIG(I2S_DATA_BIT_WIDTH_16BIT, I2S_SLOT_MODE_STEREO); + TEST_ESP_OK(i2s_channel_init_std_mode(tx_handle, &i2s_std_config)); + + + uint8_t *txbuf = (uint8_t *)heap_caps_calloc(1, TEST_I2S_TRANS_SIZE, MALLOC_CAP_8BIT | MALLOC_CAP_INTERNAL); + TEST_ASSERT(txbuf); + + uint8_t *prebuf = (uint8_t *)heap_caps_calloc(1, TEST_I2S_TRANS_SIZE, MALLOC_CAP_8BIT | MALLOC_CAP_INTERNAL); + TEST_ASSERT(prebuf); + + memcpy(prebuf, test_vad_pcm_start, TEST_I2S_TRANS_SIZE); + memcpy(txbuf, test_vad_pcm_start, TEST_I2S_TRANS_SIZE); + + for (int i = 0; i < TEST_I2S_TRANS_SIZE; i++) { + ESP_LOGD(TAG, "prebuf[%d]: %d", i, prebuf[i]); + ESP_LOGD(TAG, "txbuf[%d]: %d", i, txbuf[i]); + } + + size_t bytes_written = 0; + TEST_ESP_OK(i2s_channel_preload_data(tx_handle, prebuf, TEST_I2S_TRANS_SIZE, &bytes_written)); + + TEST_ESP_OK(i2s_channel_enable(tx_handle)); + + while (1) { + ret = i2s_channel_write(tx_handle, txbuf, TEST_I2S_TRANS_SIZE, &bytes_written, 0); + if (ret != ESP_OK && ret != ESP_ERR_TIMEOUT) { + TEST_ESP_OK(ret); + } + ESP_LOGD(TAG, "bytes_written: %d", bytes_written); + vTaskDelay(1); + } +} + +static void s_lp_vad_config(void) +{ + ESP_ERROR_CHECK(esp_sleep_enable_vad_wakeup()); + ESP_ERROR_CHECK(esp_sleep_pd_config(ESP_PD_DOMAIN_RTC_PERIPH, ESP_PD_OPTION_ON)); + ESP_ERROR_CHECK(esp_sleep_pd_config(ESP_PD_DOMAIN_XTAL, ESP_PD_OPTION_ON)); + + lp_i2s_chan_handle_t rx_handle = NULL; + lp_i2s_chan_config_t config = { + .id = 0, + .role = I2S_ROLE_SLAVE, + .threshold = 512, + }; + TEST_ESP_OK(lp_i2s_new_channel(&config, NULL, &rx_handle)); + + lp_i2s_std_config_t lp_std_cfg = { + .pin_cfg = { + .bck = TEST_LP_I2S_PIN_BCK, + .ws = TEST_LP_I2S_PIN_WS, + .din = TEST_LP_I2S_PIN_DIN, + }, + }; + lp_std_cfg.slot_cfg = (lp_i2s_std_slot_config_t)LP_I2S_STD_PCM_SHORT_SLOT_DEFAULT_CONFIG(I2S_DATA_BIT_WIDTH_16BIT, I2S_SLOT_MODE_STEREO); + TEST_ESP_OK(lp_i2s_channel_init_std_mode(rx_handle, &lp_std_cfg)); + + // LP VAD Init + lp_vad_init_config_t init_config = { + .lp_i2s_chan = rx_handle, + .vad_config = { + .init_frame_num = 100, + .min_energy_thresh = 100, + .speak_activity_thresh = 10, + .non_speak_activity_thresh = 30, + .min_speak_activity_thresh = 3, + .max_speak_activity_thresh = 100, + }, + }; + TEST_ESP_OK(lp_core_lp_vad_init(0, &init_config)); + TEST_ESP_OK(lp_i2s_channel_enable(rx_handle)); + TEST_ESP_OK(lp_core_lp_vad_enable(0)); + + printf("Entering light sleep\n"); + /* To make sure the complete line is printed before entering sleep mode, + * need to wait until UART TX FIFO is empty: + */ + uart_wait_tx_idle_polling(CONFIG_ESP_CONSOLE_UART_NUM); + + /* Enter sleep mode */ + esp_light_sleep_start(); + + /* Determine wake up reason */ + const char* wakeup_reason; + switch (esp_sleep_get_wakeup_cause()) { + case ESP_SLEEP_WAKEUP_VAD: + wakeup_reason = "vad"; + break; + default: + wakeup_reason = "other"; + TEST_ASSERT(false); + break; + } + + ESP_LOGI(TAG, "wakeup, reason: %s", wakeup_reason); +} + +TEST_CASE_MULTIPLE_DEVICES("test LP VAD wakeup", "[vad][ignore][manual]", s_hp_i2s_config, s_lp_vad_config); diff --git a/components/esp_hw_support/test_apps/vad_wakeup/pytest_wakeup_vad.py b/components/esp_hw_support/test_apps/vad_wakeup/pytest_wakeup_vad.py new file mode 100644 index 0000000000..b4d9f85aff --- /dev/null +++ b/components/esp_hw_support/test_apps/vad_wakeup/pytest_wakeup_vad.py @@ -0,0 +1,11 @@ +# SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD +# SPDX-License-Identifier: Unlicense OR CC0-1.0 +import pytest +from pytest_embedded import Dut + + +@pytest.mark.esp32p4 +@pytest.mark.temp_skip_ci(targets=['esp32p4'], reason='lack of runners for now') +@pytest.mark.lp_i2s +def test_efuse(dut: Dut) -> None: + dut.run_all_single_board_cases() diff --git a/components/esp_hw_support/test_apps/vad_wakeup/sdkconfig.defaults b/components/esp_hw_support/test_apps/vad_wakeup/sdkconfig.defaults new file mode 100644 index 0000000000..cac3f9a01f --- /dev/null +++ b/components/esp_hw_support/test_apps/vad_wakeup/sdkconfig.defaults @@ -0,0 +1,8 @@ +CONFIG_ESP_TASK_WDT_INIT=n + +CONFIG_ULP_COPROC_ENABLED=y +CONFIG_ULP_COPROC_TYPE_LP_CORE=y +CONFIG_ULP_COPROC_RESERVE_MEM=12000 +CONFIG_ULP_PANIC_OUTPUT_ENABLE=y + +CONFIG_ESP_CONSOLE_USB_SERIAL_JTAG=y diff --git a/components/ulp/test_apps/lp_core/lp_core_basic_tests/sdkconfig.ci.lp_vad b/components/ulp/test_apps/lp_core/lp_core_basic_tests/sdkconfig.ci.lp_vad index 8397edb939..766d6c83cd 100644 --- a/components/ulp/test_apps/lp_core/lp_core_basic_tests/sdkconfig.ci.lp_vad +++ b/components/ulp/test_apps/lp_core/lp_core_basic_tests/sdkconfig.ci.lp_vad @@ -1,2 +1 @@ CONFIG_TEST_LP_CORE_VAD_ENABLE=y -CONFIG_ESP_CONSOLE_USB_SERIAL_JTAG=y