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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 J0=Wm|2LKs`z?1+0 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