diff --git a/.gitignore b/.gitignore index eeb477e..9ff3dc5 100644 --- a/.gitignore +++ b/.gitignore @@ -47,3 +47,4 @@ coverage_report/ .vscode mycode +/examples/player/pipeline_http_opus/sdkconfig.defaults diff --git a/components/audio_board/CMakeLists.txt b/components/audio_board/CMakeLists.txt index 5b9ea45..851331f 100644 --- a/components/audio_board/CMakeLists.txt +++ b/components/audio_board/CMakeLists.txt @@ -2,7 +2,7 @@ set(COMPONENT_ADD_INCLUDEDIRS ./include) # Edit following two lines to set component requirements (see docs) set(COMPONENT_REQUIRES ) -set(COMPONENT_PRIV_REQUIRES audio_sal audio_hal esp_dispatcher esp_peripherals display_service) +set(COMPONENT_PRIV_REQUIRES esp_peripherals audio_sal audio_hal esp_dispatcher display_service) if (CONFIG_ESP_LYRAT_V4_2_BOARD) @@ -79,4 +79,13 @@ set(COMPONENT_SRCS ) endif() +if (CONFIG_HAMWIFI_BOARD) +message(STATUS "Current board name is " CONFIG_HANWIFI_BOARD) +list(APPEND COMPONENT_ADD_INCLUDEDIRS ./hamwifi) +set(COMPONENT_SRCS +./hamwifi/board.c +./hamwifi/board_pins_config.c +) +endif() + register_component() diff --git a/components/audio_board/Kconfig.projbuild b/components/audio_board/Kconfig.projbuild index 9376fd0..d689eae 100644 --- a/components/audio_board/Kconfig.projbuild +++ b/components/audio_board/Kconfig.projbuild @@ -23,13 +23,15 @@ config ESP32_S2_KALUGA_1_V1_2_BOARD bool "ESP32-S2-Kaluga-1 v1.2" config ESP_AI_THINKER_V2_2_BOARD bool "ESP32-AiThinker-audio V2.2" +config HAMWIFI_BOARD + bool "HAMWIFI" endchoice choice ESP32_KORVO_DU1906_DAC prompt "ESP32 KORVO DU1906 Board DAC chip" depends on ESP32_KORVO_DU1906_BOARD - default ESP32_KORVO_DU1906_CODEC_TAS5805M + default ESP32_KORVO_DU1906_DAC_TAS5805M help Select DAC chip to use on ESP32_KORVO_DU1906 board diff --git a/components/audio_board/ai_thinker_audio_kit_v2_2/board.c b/components/audio_board/ai_thinker_audio_kit_v2_2/board.c old mode 100644 new mode 100755 index 07b7587..b560c5e --- a/components/audio_board/ai_thinker_audio_kit_v2_2/board.c +++ b/components/audio_board/ai_thinker_audio_kit_v2_2/board.c @@ -25,6 +25,7 @@ #include "esp_log.h" #include "board.h" #include "audio_mem.h" + #include "periph_sdcard.h" #include "led_indicator.h" #include "periph_touch.h" @@ -78,30 +79,71 @@ display_service_handle_t audio_board_led_init(void) return display_service_create(&display); } +display_service_handle_t audio_board_blue_led_init(void) +{ + led_indicator_handle_t led = led_indicator_init((gpio_num_t)get_blue_led_gpio()); + display_service_config_t display = { + .based_cfg = { + .task_stack = 0, + .task_prio = 0, + .task_core = 0, + .task_func = NULL, + .service_start = NULL, + .service_stop = NULL, + .service_destroy = NULL, + .service_ioctl = led_indicator_pattern, + .service_name = "DISPLAY_serv", + .user_data = NULL, + }, + .instance = led, + }; + + return display_service_create(&display); +} + esp_err_t audio_board_key_init(esp_periph_set_handle_t set) { esp_err_t ret = ESP_OK; periph_button_cfg_t btn_cfg = { - .gpio_mask = TOUCH_SEL_SET | TOUCH_SEL_PLAY | TOUCH_SEL_VOLUP | TOUCH_SEL_VOLDWN, //REC BTN & MODE BTN + .gpio_mask = TOUCH_SEL_SET | TOUCH_SEL_PLAY | TOUCH_SEL_VOLUP | TOUCH_SEL_VOLDWN | TOUCH_SEL_REC | TOUCH_SEL_REC, //REC BTN & MODE BTN }; esp_periph_handle_t button_handle = periph_button_init(&btn_cfg); AUDIO_NULL_CHECK(TAG, button_handle, return ESP_ERR_ADF_MEMORY_LACK); - ret = esp_periph_start(set, button_handle); return ret; } -esp_err_t audio_board_sdcard_init(esp_periph_set_handle_t set) +esp_err_t audio_board_sdcard_init(esp_periph_set_handle_t set, periph_sdcard_mode_t mode) { + if (mode != SD_MODE_1_LINE) { + ESP_LOGE(TAG, "current board only support 1-line SD mode!"); + return ESP_FAIL; + } + // if (mode >= SD_MODE_MAX) { + // ESP_LOGE(TAG, "PLease select the correct sd mode!, current mode is %d", mode); + // return ESP_FAIL; + // } periph_sdcard_cfg_t sdcard_cfg = { .root = "/sdcard", .card_detect_pin = get_sdcard_intr_gpio(), // GPIO_NUM_34 + .mode = mode, }; esp_periph_handle_t sdcard_handle = periph_sdcard_init(&sdcard_cfg); esp_err_t ret = esp_periph_start(set, sdcard_handle); - while (!periph_sdcard_is_mounted(sdcard_handle)) { - vTaskDelay(500 / portTICK_PERIOD_MS); + int retry_time = 5; + bool mount_flag = false; + while (retry_time --) { + if (periph_sdcard_is_mounted(sdcard_handle)) { + mount_flag = true; + break; + } else { + vTaskDelay(500 / portTICK_PERIOD_MS); + } + } + if (mount_flag == false) { + ESP_LOGE(TAG, "Sdcard mount failed"); + return ESP_FAIL; } return ret; } diff --git a/components/audio_board/ai_thinker_audio_kit_v2_2/board.h b/components/audio_board/ai_thinker_audio_kit_v2_2/board.h old mode 100644 new mode 100755 index e7fe565..ed21b7b --- a/components/audio_board/ai_thinker_audio_kit_v2_2/board.h +++ b/components/audio_board/ai_thinker_audio_kit_v2_2/board.h @@ -30,6 +30,7 @@ #include "board_pins_config.h" #include "esp_peripherals.h" #include "display_service.h" +#include "periph_sdcard.h" #ifdef __cplusplus extern "C" { @@ -73,6 +74,13 @@ audio_hal_handle_t audio_board_adc_init(void); */ display_service_handle_t audio_board_led_init(void); +/** + * @brief Initialize led peripheral and display service + * + * @return The audio display service handle + */ +display_service_handle_t audio_board_blue_led_init(void); + /** * @brief Initialize key peripheral * @@ -94,7 +102,7 @@ esp_err_t audio_board_key_init(esp_periph_set_handle_t set); * - ESP_OK, success * - Others, fail */ -esp_err_t audio_board_sdcard_init(esp_periph_set_handle_t set); +esp_err_t audio_board_sdcard_init(esp_periph_set_handle_t set, periph_sdcard_mode_t mode); /** diff --git a/components/audio_board/ai_thinker_audio_kit_v2_2/board_def.h b/components/audio_board/ai_thinker_audio_kit_v2_2/board_def.h old mode 100644 new mode 100755 index fe30eca..b303edb --- a/components/audio_board/ai_thinker_audio_kit_v2_2/board_def.h +++ b/components/audio_board/ai_thinker_audio_kit_v2_2/board_def.h @@ -52,6 +52,8 @@ #define TOUCH_SEL_PLAY GPIO_SEL_23 #define TOUCH_SEL_VOLUP GPIO_SEL_18 #define TOUCH_SEL_VOLDWN GPIO_SEL_5 +#define TOUCH_SEL_REC GPIO_SEL_36 +#define TOUCH_SEL_MODE GPIO_SEL_13 #define TOUCH_SET GPIO_NUM_19 #define TOUCH_PLAY GPIO_NUM_23 diff --git a/components/audio_board/ai_thinker_audio_kit_v2_2/board_pins_config.c b/components/audio_board/ai_thinker_audio_kit_v2_2/board_pins_config.c old mode 100644 new mode 100755 diff --git a/components/audio_board/component.mk b/components/audio_board/component.mk index bdc30e9..59921ad 100644 --- a/components/audio_board/component.mk +++ b/components/audio_board/component.mk @@ -47,3 +47,7 @@ COMPONENT_ADD_INCLUDEDIRS += ./ai_thinker_audio_kit_v2_2 COMPONENT_SRCDIRS += ./ai_thinker_audio_kit_v2_2 endif +ifdef CONFIG_HAMWIFI_BOARD +COMPONENT_ADD_INCLUDEDIRS += ./hamwifi +COMPONENT_SRCDIRS += ./hamwifi +endif diff --git a/components/audio_board/esp32_korvo_du1906/board.c b/components/audio_board/esp32_korvo_du1906/board.c index 26995b4..cc6f46b 100644 --- a/components/audio_board/esp32_korvo_du1906/board.c +++ b/components/audio_board/esp32_korvo_du1906/board.c @@ -121,11 +121,16 @@ esp_err_t audio_board_key_init(esp_periph_set_handle_t set) return ret; } -esp_err_t audio_board_sdcard_init(esp_periph_set_handle_t set) +esp_err_t audio_board_sdcard_init(esp_periph_set_handle_t set, periph_sdcard_mode_t mode) { + if (mode != SD_MODE_1_LINE) { + ESP_LOGE(TAG, "current board only support 1-line SD mode!"); + return ESP_FAIL; + } periph_sdcard_cfg_t sdcard_cfg = { .root = "/sdcard", .card_detect_pin = get_sdcard_intr_gpio(), // GPIO_NUM_34 + .mode = mode }; esp_periph_handle_t sdcard_handle = periph_sdcard_init(&sdcard_cfg); esp_err_t ret = esp_periph_start(set, sdcard_handle); diff --git a/components/audio_board/esp32_korvo_du1906/board.h b/components/audio_board/esp32_korvo_du1906/board.h index fc9d98a..4ec40e8 100644 --- a/components/audio_board/esp32_korvo_du1906/board.h +++ b/components/audio_board/esp32_korvo_du1906/board.h @@ -30,6 +30,7 @@ #include "board_pins_config.h" #include "esp_peripherals.h" #include "display_service.h" +#include "periph_sdcard.h" #ifdef __cplusplus extern "C" { @@ -98,7 +99,7 @@ esp_err_t audio_board_key_init(esp_periph_set_handle_t set); * - ESP_OK, success * - Others, fail */ -esp_err_t audio_board_sdcard_init(esp_periph_set_handle_t set); +esp_err_t audio_board_sdcard_init(esp_periph_set_handle_t set, periph_sdcard_mode_t mode); /** * @brief Query audio_board_handle diff --git a/components/audio_board/esp32_korvo_du1906/board_def.h b/components/audio_board/esp32_korvo_du1906/board_def.h index b253f43..c52d57f 100644 --- a/components/audio_board/esp32_korvo_du1906/board_def.h +++ b/components/audio_board/esp32_korvo_du1906/board_def.h @@ -36,7 +36,7 @@ #define SDCARD_OPEN_FILE_NUM_MAX 5 #define SDCARD_INTR_GPIO GPIO_NUM_39 - +#define ES7243_MCLK_GPIO GPIO_NUM_0 #define WS2812_LED_GPIO_PIN 3 #define WS2812_LED_BAR_NUMBERS 2 diff --git a/components/audio_board/esp32_korvo_du1906/board_pins_config.c b/components/audio_board/esp32_korvo_du1906/board_pins_config.c index 2c5c17d..68378eb 100644 --- a/components/audio_board/esp32_korvo_du1906/board_pins_config.c +++ b/components/audio_board/esp32_korvo_du1906/board_pins_config.c @@ -148,3 +148,8 @@ int8_t get_pa_enable_gpio(void) { return PA_ENABLE_GPIO; } + +int8_t get_es7243_mclk_gpio(void) +{ + return ES7243_MCLK_GPIO; +} diff --git a/components/audio_board/esp32_korvo_du1906/du1906_bar_pattern.c b/components/audio_board/esp32_korvo_du1906/du1906_bar_pattern.c index 65b96e8..85de880 100644 --- a/components/audio_board/esp32_korvo_du1906/du1906_bar_pattern.c +++ b/components/audio_board/esp32_korvo_du1906/du1906_bar_pattern.c @@ -48,15 +48,15 @@ const struct periph_ws2812_ctrl_cfg ws2812_display_pattern[DISPLAY_PATTERN_MAX][ { { .mode = PERIPH_WS2812_FADE, - .color = LED2812_COLOR_WHITE, - .loop = 20, + .color = LED2812_COLOR_PURPLE, + .loop = 0xFFFFFFFF, .time_off_ms = 1500, .time_on_ms = 1500, }, { .mode = PERIPH_WS2812_FADE, - .color = LED2812_COLOR_WHITE, - .loop = 20, + .color = LED2812_COLOR_PURPLE, + .loop = 0xFFFFFFFF, .time_off_ms = 1500, .time_on_ms = 1500, } // 1 @@ -65,14 +65,14 @@ const struct periph_ws2812_ctrl_cfg ws2812_display_pattern[DISPLAY_PATTERN_MAX][ { .mode = PERIPH_WS2812_BLINK, .color = LED2812_COLOR_WHITE, - .loop = 100, + .loop = 0xFFFFFFFF, .time_off_ms = 200, .time_on_ms = 800, }, { .mode = PERIPH_WS2812_BLINK, .color = LED2812_COLOR_WHITE, - .loop = 100, + .loop = 0xFFFFFFFF, .time_off_ms = 200, .time_on_ms = 800, } // 2 @@ -80,14 +80,14 @@ const struct periph_ws2812_ctrl_cfg ws2812_display_pattern[DISPLAY_PATTERN_MAX][ { { .mode = PERIPH_WS2812_ONE, - .color = LED2812_COLOR_WHITE , + .color = LED2812_COLOR_BLACK , .loop = 0, .time_off_ms = 0, .time_on_ms = 0, }, { .mode = PERIPH_WS2812_ONE, - .color = LED2812_COLOR_WHITE, + .color = LED2812_COLOR_BLACK, .loop = 0, .time_off_ms = 0, .time_on_ms = 0, @@ -95,18 +95,18 @@ const struct periph_ws2812_ctrl_cfg ws2812_display_pattern[DISPLAY_PATTERN_MAX][ }, { { - .mode = PERIPH_WS2812_BLINK, - .color = LED2812_COLOR_WHITE, - .loop = 100, - .time_off_ms = 200, - .time_on_ms = 400, + .mode = PERIPH_WS2812_ONE, + .color = LED2812_COLOR_RED, + .loop = 1, + .time_off_ms = 1000, + .time_on_ms = 4000, }, { - .mode = PERIPH_WS2812_BLINK, - .color = LED2812_COLOR_WHITE, - .loop = 100, - .time_off_ms = 200, - .time_on_ms = 400, + .mode = PERIPH_WS2812_ONE, + .color = LED2812_COLOR_RED, + .loop = 1, + .time_off_ms = 1000, + .time_on_ms = 4000, } // 4 }, { @@ -143,34 +143,34 @@ const struct periph_ws2812_ctrl_cfg ws2812_display_pattern[DISPLAY_PATTERN_MAX][ }, { { - .mode = PERIPH_WS2812_ONE, - .color = LED2812_COLOR_BLUE, - .loop = 0, - .time_off_ms = 0, - .time_on_ms = 0, + .mode = PERIPH_WS2812_BLINK, + .color = LED2812_COLOR_PURPLE, + .loop = 4, + .time_off_ms = 100, + .time_on_ms = 100, }, { - .mode = PERIPH_WS2812_ONE, - .color = LED2812_COLOR_BLUE, - .loop = 0, - .time_off_ms = 0, - .time_on_ms = 0, + .mode = PERIPH_WS2812_BLINK, + .color = LED2812_COLOR_PURPLE, + .loop = 4, + .time_off_ms = 100, + .time_on_ms = 100, } // 7 }, { { .mode = PERIPH_WS2812_BLINK, - .color = LED2812_COLOR_BLUE, - .loop = 100, - .time_off_ms = 200, - .time_on_ms = 400, + .color = LED2812_COLOR_PURPLE, + .loop = 4, + .time_off_ms = 100, + .time_on_ms = 100, }, { .mode = PERIPH_WS2812_BLINK, - .color = LED2812_COLOR_BLUE, - .loop = 100, - .time_off_ms = 200, - .time_on_ms = 400, + .color = LED2812_COLOR_PURPLE, + .loop = 4, + .time_off_ms = 100, + .time_on_ms = 100, } // 8 }, { @@ -240,14 +240,14 @@ const struct periph_ws2812_ctrl_cfg ws2812_display_pattern[DISPLAY_PATTERN_MAX][ { { .mode = PERIPH_WS2812_ONE, - .color = LED2812_COLOR_GREEN, + .color = LED2812_COLOR_BLUE, .loop = 0, .time_off_ms = 0, .time_on_ms = 0, }, { .mode = PERIPH_WS2812_ONE, - .color = LED2812_COLOR_GREEN, + .color = LED2812_COLOR_BLUE, .loop = 0, .time_off_ms = 0, .time_on_ms = 0, @@ -303,31 +303,31 @@ const struct periph_ws2812_ctrl_cfg ws2812_display_pattern[DISPLAY_PATTERN_MAX][ }, { { - .mode = PERIPH_WS2812_ONE, - .color = LED2812_COLOR_BLACK, - .loop = 0, + .mode = PERIPH_WS2812_FADE, + .color = LED2812_COLOR_GREEN, + .loop = 1, .time_off_ms = 0, - .time_on_ms = 0, + .time_on_ms = 1000, }, { - .mode = PERIPH_WS2812_ONE, - .color = LED2812_COLOR_BLACK, - .loop = 0, + .mode = PERIPH_WS2812_FADE, + .color = LED2812_COLOR_GREEN, + .loop = 1, .time_off_ms = 0, - .time_on_ms = 0, + .time_on_ms = 1000, } // 17 }, { { .mode = PERIPH_WS2812_ONE, - .color = LED2812_COLOR_YELLOW, + .color = LED2812_COLOR_ORANGE, .loop = 0, .time_off_ms = 0, .time_on_ms = 0, }, { .mode = PERIPH_WS2812_ONE, - .color = LED2812_COLOR_YELLOW, + .color = LED2812_COLOR_ORANGE, .loop = 0, .time_off_ms = 0, .time_on_ms = 0, @@ -428,6 +428,71 @@ const struct periph_ws2812_ctrl_cfg ws2812_display_pattern[DISPLAY_PATTERN_MAX][ .time_off_ms = 1000, .time_on_ms = 2000, } // 24 + }, + { + { + .mode = PERIPH_WS2812_ONE, + .color = LED2812_COLOR_PURPLE, + .loop = 0, + .time_off_ms = 0, + .time_on_ms = 0, + }, + { + .mode = PERIPH_WS2812_ONE, + .color = LED2812_COLOR_PURPLE, + .loop = 0, + .time_off_ms = 0, + .time_on_ms = 0, + } // 25 + } + , + { + { + .mode = PERIPH_WS2812_BLINK, + .color = LED2812_COLOR_RED, + .loop = 0xFFFFFFFF, + .time_off_ms = 2000, + .time_on_ms = 2000, + }, + { + .mode = PERIPH_WS2812_BLINK, + .color = LED2812_COLOR_RED, + .loop = 0xFFFFFFFF, + .time_off_ms = 2000, + .time_on_ms = 2000, + } // 26 + }, + { + { + .mode = PERIPH_WS2812_BLINK, + .color = LED2812_COLOR_BLUE, + .loop = 0xFFFFFFFF, + .time_off_ms = 500, + .time_on_ms = 500, + }, + { + .mode = PERIPH_WS2812_BLINK, + .color = LED2812_COLOR_BLUE, + .loop = 0xFFFFFFFF, + .time_off_ms = 500, + .time_on_ms = 500, + } // 27, + }, + { + { + .mode = PERIPH_WS2812_ONE, + .color = LED2812_COLOR_BLACK, + .loop = 0, + .time_off_ms = 0, + .time_on_ms = 0, + }, + { + .mode = PERIPH_WS2812_ONE, + .color = LED2812_COLOR_BLACK, + .loop = 0, + .time_off_ms = 0, + .time_on_ms = 0, + } // 28, } }; diff --git a/components/audio_board/esp32_s2_kaluga_1_v1_2/board.c b/components/audio_board/esp32_s2_kaluga_1_v1_2/board.c index 4305363..283f998 100644 --- a/components/audio_board/esp32_s2_kaluga_1_v1_2/board.c +++ b/components/audio_board/esp32_s2_kaluga_1_v1_2/board.c @@ -51,7 +51,7 @@ audio_hal_handle_t audio_board_codec_init(void) AUDIO_NULL_CHECK(TAG, codec_hal, return NULL); return codec_hal; } -esp_err_t audio_board_sdcard_init(esp_periph_set_handle_t set) +esp_err_t audio_board_sdcard_init(esp_periph_set_handle_t set, periph_sdcard_mode_t mode) { esp_err_t ret = ESP_OK; return ret; diff --git a/components/audio_board/esp32_s2_kaluga_1_v1_2/board.h b/components/audio_board/esp32_s2_kaluga_1_v1_2/board.h index 77c41a7..b178533 100644 --- a/components/audio_board/esp32_s2_kaluga_1_v1_2/board.h +++ b/components/audio_board/esp32_s2_kaluga_1_v1_2/board.h @@ -30,6 +30,7 @@ #include "board_pins_config.h" #include "esp_peripherals.h" #include "display_service.h" +#include "periph_sdcard.h" #ifdef __cplusplus extern "C" { @@ -74,7 +75,7 @@ display_service_handle_t audio_board_led_init(void); * - ESP_OK, success * - Others, fail */ -esp_err_t audio_board_sdcard_init(esp_periph_set_handle_t set); +esp_err_t audio_board_sdcard_init(esp_periph_set_handle_t set, periph_sdcard_mode_t mode); /** * @brief Initialize key peripheral diff --git a/components/audio_board/hamwifi/board.c b/components/audio_board/hamwifi/board.c new file mode 100755 index 0000000..046ac2b --- /dev/null +++ b/components/audio_board/hamwifi/board.c @@ -0,0 +1,73 @@ +/* + * ESPRESSIF MIT License + * + * Copyright (c) 2019 + * + * Permission is hereby granted for use on all ESPRESSIF SYSTEMS products, in which case, + * it is free of charge, to any person obtaining a copy of this software and associated + * documentation files (the "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the Software is furnished + * to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all copies or + * substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + */ + +#include "esp_log.h" +#include "board.h" +#include "audio_mem.h" + +#include "periph_sdcard.h" +#include "led_indicator.h" +#include "periph_touch.h" +#include "periph_button.h" +#include "led_indicator.h" + +static const char *TAG = "AUDIO_BOARD"; + +static audio_board_handle_t board_handle = 0; + +audio_board_handle_t audio_board_init(void) +{ + if (board_handle) + { + ESP_LOGW(TAG, "The board has already been initialized!"); + return board_handle; + } + board_handle = (audio_board_handle_t)audio_calloc(1, sizeof(struct audio_board_handle)); + AUDIO_MEM_CHECK(TAG, board_handle, return NULL); + board_handle->audio_hal = audio_board_codec_init(); + return board_handle; +} + +audio_hal_handle_t audio_board_codec_init(void) +{ + audio_hal_codec_config_t audio_codec_cfg = AUDIO_CODEC_DEFAULT_CONFIG(); + audio_hal_handle_t codec_hal = audio_hal_init(&audio_codec_cfg, &AUDIO_CODEC_AC101_CODEC_HANDLE); + AUDIO_NULL_CHECK(TAG, codec_hal, return NULL); + return codec_hal; +} + +audio_board_handle_t audio_board_get_handle(void) +{ + return board_handle; +} + +esp_err_t audio_board_deinit(audio_board_handle_t audio_board) +{ + esp_err_t ret = ESP_OK; + ret |= audio_hal_deinit(audio_board->audio_hal); + ret |= audio_hal_deinit(audio_board->adc_hal); + free(audio_board); + board_handle = NULL; + return ret; +} diff --git a/components/audio_board/hamwifi/board.h b/components/audio_board/hamwifi/board.h new file mode 100755 index 0000000..ba697ae --- /dev/null +++ b/components/audio_board/hamwifi/board.h @@ -0,0 +1,92 @@ +/* + * ESPRESSIF MIT License + * + * Copyright (c) 2019 + * + * Permission is hereby granted for use on all ESPRESSIF SYSTEMS products, in which case, + * it is free of charge, to any person obtaining a copy of this software and associated + * documentation files (the "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the Software is furnished + * to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all copies or + * substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + */ + +#ifndef _AUDIO_BOARD_H_ +#define _AUDIO_BOARD_H_ + +#include "audio_hal.h" +#include "board_def.h" +#include "board_pins_config.h" +#include "esp_peripherals.h" +#include "display_service.h" +#include "periph_sdcard.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @brief Audio board handle + */ +struct audio_board_handle { + audio_hal_handle_t audio_hal; /*!< audio hardware abstract layer handle */ + audio_hal_handle_t adc_hal; /*!< adc hardware abstract layer handle */ +}; + +typedef struct audio_board_handle *audio_board_handle_t; + +/** + * @brief Initialize audio board + * + * @return The audio board handle + */ +audio_board_handle_t audio_board_init(void); + +/** + * @brief Initialize codec chip + * + * @return The audio hal handle + */ +audio_hal_handle_t audio_board_codec_init(void); + +/** + * @brief Initialize adc + * + * @return The adc hal handle + */ +audio_hal_handle_t audio_board_adc_init(void); + + +/** + * @brief Query audio_board_handle + * + * @return The audio board handle + */ +audio_board_handle_t audio_board_get_handle(void); + +/** + * @brief Uninitialize the audio board + * + * @param audio_board The handle of audio board + * + * @return 0 success, + * others fail + */ +esp_err_t audio_board_deinit(audio_board_handle_t audio_board); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/components/audio_board/hamwifi/board_def.h b/components/audio_board/hamwifi/board_def.h new file mode 100755 index 0000000..3bbe10a --- /dev/null +++ b/components/audio_board/hamwifi/board_def.h @@ -0,0 +1,52 @@ +/* + * @Author: your name + * @Date: 2020-01-26 10:13:06 + * @LastEditTime : 2020-01-28 19:24:42 + * @LastEditors : Please set LastEditors + * @Description: In User Settings Edit + * @FilePath: \esp-adf\components\audio_board\aithinker\board_def.h + */ +/* + * ESPRESSIF MIT License + * + * Copyright (c) 2019 + * + * Permission is hereby granted for use on all ESPRESSIF SYSTEMS products, in which case, + * it is free of charge, to any person obtaining a copy of this software and associated + * documentation files (the "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the Software is furnished + * to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all copies or + * substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + */ + +#ifndef _AUDIO_BOARD_DEFINITION_H_ +#define _AUDIO_BOARD_DEFINITION_H_ + +#define PA_ENABLE_GPIO GPIO_NUM_21 + +extern audio_hal_func_t AUDIO_CODEC_AC101_CODEC_HANDLE; + +#define AUDIO_CODEC_DEFAULT_CONFIG() { \ + .adc_input = AUDIO_HAL_ADC_INPUT_LINE1, \ + .dac_output = AUDIO_HAL_DAC_OUTPUT_ALL, \ + .codec_mode = AUDIO_HAL_CODEC_MODE_BOTH, \ + .i2s_iface = { \ + .mode = AUDIO_HAL_MODE_SLAVE, \ + .fmt = AUDIO_HAL_I2S_NORMAL, \ + .samples = AUDIO_HAL_48K_SAMPLES, \ + .bits = AUDIO_HAL_BIT_LENGTH_16BITS, \ + }, \ +}; + +#endif diff --git a/components/audio_board/hamwifi/board_pins_config.c b/components/audio_board/hamwifi/board_pins_config.c new file mode 100755 index 0000000..19e7bc9 --- /dev/null +++ b/components/audio_board/hamwifi/board_pins_config.c @@ -0,0 +1,135 @@ +/* + * ESPRESSIF MIT License + * + * Copyright (c) 2019 + * + * Permission is hereby granted for use on all ESPRESSIF SYSTEMS products, in which case, + * it is free of charge, to any person obtaining a copy of this software and associated + * documentation files (the "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the Software is furnished + * to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all copies or + * substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + */ + +#include "esp_log.h" +#include "driver/gpio.h" +#include +#include "board.h" +#include "audio_error.h" +#include "audio_mem.h" + +static const char *TAG = "A1S"; + +esp_err_t get_i2c_pins(i2c_port_t port, i2c_config_t *i2c_config) +{ + AUDIO_NULL_CHECK(TAG, i2c_config, return ESP_FAIL); + if (port == I2C_NUM_0) + { + i2c_config->sda_io_num = GPIO_NUM_33; + i2c_config->scl_io_num = GPIO_NUM_32; + ESP_LOGI(TAG, "i2c port configured!!!!"); + } + else + { + i2c_config->sda_io_num = -1; + i2c_config->scl_io_num = -1; + ESP_LOGE(TAG, "i2c port %d is not supported", port); + return ESP_FAIL; + } + return ESP_OK; +} + +esp_err_t get_i2s_pins(i2s_port_t port, i2s_pin_config_t *i2s_config) +{ + AUDIO_NULL_CHECK(TAG, i2s_config, return ESP_FAIL); + if (port == I2S_NUM_0) + { + i2s_config->bck_io_num = GPIO_NUM_27; + i2s_config->ws_io_num = GPIO_NUM_26; + i2s_config->data_out_num = GPIO_NUM_25; + i2s_config->data_in_num = GPIO_NUM_35; + ESP_LOGI(TAG, "i2s port configured!!!!"); + } + else + { + memset(i2s_config, -1, sizeof(i2s_pin_config_t)); + ESP_LOGE(TAG, "i2s port %d is not supported", port); + return ESP_FAIL; + } + + return ESP_OK; +} + +esp_err_t get_spi_pins(spi_bus_config_t *spi_config, spi_device_interface_config_t *spi_device_interface_config) +{ + AUDIO_NULL_CHECK(TAG, spi_config, return ESP_FAIL); + AUDIO_NULL_CHECK(TAG, spi_device_interface_config, return ESP_FAIL); + + spi_config->mosi_io_num = GPIO_NUM_23; + spi_config->miso_io_num = -1; + spi_config->sclk_io_num = GPIO_NUM_18; + spi_config->quadwp_io_num = -1; + spi_config->quadhd_io_num = -1; + + spi_device_interface_config->spics_io_num = -1; + + ESP_LOGW(TAG, "SPI interface is not supported"); + return ESP_OK; +} + +esp_err_t i2s_mclk_gpio_select(i2s_port_t i2s_num, gpio_num_t gpio_num) +{ + if (i2s_num >= I2S_NUM_MAX) + { + ESP_LOGE(TAG, "Does not support i2s number(%d)", i2s_num); + return ESP_ERR_INVALID_ARG; + } + if (gpio_num != GPIO_NUM_0 && gpio_num != GPIO_NUM_1 && gpio_num != GPIO_NUM_3) + { + ESP_LOGE(TAG, "Only support GPIO0/GPIO1/GPIO3, gpio_num:%d", gpio_num); + return ESP_ERR_INVALID_ARG; + } + if (i2s_num == I2S_NUM_0) + { + if (gpio_num == GPIO_NUM_0) + { + PIN_FUNC_SELECT(PERIPHS_IO_MUX_GPIO0_U, FUNC_GPIO0_CLK_OUT1); + WRITE_PERI_REG(PIN_CTRL, 0xFFF0); + } + else if (gpio_num == GPIO_NUM_1) + { + PIN_FUNC_SELECT(PERIPHS_IO_MUX_U0TXD_U, FUNC_U0TXD_CLK_OUT3); + WRITE_PERI_REG(PIN_CTRL, 0xF0F0); + } + else + { + PIN_FUNC_SELECT(PERIPHS_IO_MUX_U0RXD_U, FUNC_U0RXD_CLK_OUT2); + WRITE_PERI_REG(PIN_CTRL, 0xFF00); + } + } + return ESP_OK; +} + +// input-output pins + +// int8_t get_headphone_detect_gpio(void) +// { +// return HEADPHONE_DETECT; +// } + +int8_t get_pa_enable_gpio(void) +{ + return PA_ENABLE_GPIO; +} + diff --git a/components/audio_board/include/board_pins_config.h b/components/audio_board/include/board_pins_config.h index 2c2ac1c..e25c8a0 100644 --- a/components/audio_board/include/board_pins_config.h +++ b/components/audio_board/include/board_pins_config.h @@ -135,6 +135,14 @@ int8_t get_pa_enable_gpio(void); */ int8_t get_adc_detect_gpio(void); +/** + * @brief Get the mclk gpio number of es7243 + * + * @return -1 non-existent + * Others gpio number + */ +int8_t get_es7243_mclk_gpio(void); + /** * @brief Get the record-button id for adc-button * diff --git a/components/audio_board/lyrat_mini_v1_1/board.c b/components/audio_board/lyrat_mini_v1_1/board.c index 0d06644..4821cc3 100644 --- a/components/audio_board/lyrat_mini_v1_1/board.c +++ b/components/audio_board/lyrat_mini_v1_1/board.c @@ -123,8 +123,12 @@ esp_err_t audio_board_key_init(esp_periph_set_handle_t set) return ret; } -esp_err_t audio_board_sdcard_init(esp_periph_set_handle_t set) +esp_err_t audio_board_sdcard_init(esp_periph_set_handle_t set, periph_sdcard_mode_t mode) { + if (mode != SD_MODE_1_LINE) { + ESP_LOGE(TAG, "current board only support 1-line SD mode!"); + return ESP_FAIL; + } gpio_config_t sdcard_pwr_pin_cfg = { .pin_bit_mask = 1UL << SDCARD_PWR_CTRL, .mode = GPIO_MODE_OUTPUT, @@ -139,6 +143,7 @@ esp_err_t audio_board_sdcard_init(esp_periph_set_handle_t set) periph_sdcard_cfg_t sdcard_cfg = { .root = "/sdcard", .card_detect_pin = get_sdcard_intr_gpio(), // GPIO_NUM_34 + .mode = mode }; esp_periph_handle_t sdcard_handle = periph_sdcard_init(&sdcard_cfg); esp_err_t ret = esp_periph_start(set, sdcard_handle); diff --git a/components/audio_board/lyrat_mini_v1_1/board.h b/components/audio_board/lyrat_mini_v1_1/board.h index c5c4bb2..a7317f3 100644 --- a/components/audio_board/lyrat_mini_v1_1/board.h +++ b/components/audio_board/lyrat_mini_v1_1/board.h @@ -30,6 +30,7 @@ #include "board_pins_config.h" #include "esp_peripherals.h" #include "display_service.h" +#include "periph_sdcard.h" #ifdef __cplusplus extern "C" { @@ -100,7 +101,7 @@ esp_err_t audio_board_key_init(esp_periph_set_handle_t set); * - ESP_OK, success * - Others, fail */ -esp_err_t audio_board_sdcard_init(esp_periph_set_handle_t set); +esp_err_t audio_board_sdcard_init(esp_periph_set_handle_t set, periph_sdcard_mode_t mode); /** * @brief Query audio_board_handle diff --git a/components/audio_board/lyrat_mini_v1_1/board_def.h b/components/audio_board/lyrat_mini_v1_1/board_def.h index 641ad4f..7d132f5 100644 --- a/components/audio_board/lyrat_mini_v1_1/board_def.h +++ b/components/audio_board/lyrat_mini_v1_1/board_def.h @@ -28,6 +28,7 @@ #define SDCARD_OPEN_FILE_NUM_MAX 5 #define SDCARD_INTR_GPIO GPIO_NUM_34 #define SDCARD_PWR_CTRL GPIO_NUM_13 +#define ES7243_MCLK_GPIO GPIO_NUM_0 #define BUTTON_VOLUP_ID 0 #define BUTTON_VOLDOWN_ID 1 diff --git a/components/audio_board/lyrat_mini_v1_1/board_pins_config.c b/components/audio_board/lyrat_mini_v1_1/board_pins_config.c index 7bc5e02..f786781 100644 --- a/components/audio_board/lyrat_mini_v1_1/board_pins_config.c +++ b/components/audio_board/lyrat_mini_v1_1/board_pins_config.c @@ -57,7 +57,7 @@ esp_err_t get_i2s_pins(i2s_port_t port, i2s_pin_config_t *i2s_config) } else if (port == I2S_NUM_1) { i2s_config->bck_io_num = GPIO_NUM_32; i2s_config->ws_io_num = GPIO_NUM_33; - i2s_config->data_out_num = GPIO_NUM_26; + i2s_config->data_out_num = -1; i2s_config->data_in_num = GPIO_NUM_36; } else { memset(i2s_config, -1, sizeof(i2s_pin_config_t)); @@ -199,3 +199,8 @@ int8_t get_es8311_mclk_src(void) { return ES8311_MCLK_SOURCE; } + +int8_t get_es7243_mclk_gpio(void) +{ + return ES7243_MCLK_GPIO; +} diff --git a/components/audio_board/lyrat_v4_2/board.h b/components/audio_board/lyrat_v4_2/board.h index d1a6b3e..935addf 100644 --- a/components/audio_board/lyrat_v4_2/board.h +++ b/components/audio_board/lyrat_v4_2/board.h @@ -30,6 +30,7 @@ #include "board_pins_config.h" #include "esp_peripherals.h" #include "display_service.h" +#include "periph_sdcard.h" #ifdef __cplusplus extern "C" { @@ -85,7 +86,7 @@ esp_err_t audio_board_key_init(esp_periph_set_handle_t set); * - ESP_OK, success * - Others, fail */ -esp_err_t audio_board_sdcard_init(esp_periph_set_handle_t set); +esp_err_t audio_board_sdcard_init(esp_periph_set_handle_t set, periph_sdcard_mode_t mode); /** * @brief Query audio_board_handle diff --git a/components/audio_board/lyrat_v4_3/board.c b/components/audio_board/lyrat_v4_3/board.c index 68f5107..8feadb0 100644 --- a/components/audio_board/lyrat_v4_3/board.c +++ b/components/audio_board/lyrat_v4_3/board.c @@ -100,11 +100,16 @@ esp_err_t audio_board_key_init(esp_periph_set_handle_t set) return ret; } -esp_err_t audio_board_sdcard_init(esp_periph_set_handle_t set) +esp_err_t audio_board_sdcard_init(esp_periph_set_handle_t set, periph_sdcard_mode_t mode) { + if (mode >= SD_MODE_MAX) { + ESP_LOGE(TAG, "PLease select the correct sd mode!, current mode is %d", mode); + return ESP_FAIL; + } periph_sdcard_cfg_t sdcard_cfg = { .root = "/sdcard", .card_detect_pin = get_sdcard_intr_gpio(), // GPIO_NUM_34 + .mode = mode, }; esp_periph_handle_t sdcard_handle = periph_sdcard_init(&sdcard_cfg); esp_err_t ret = esp_periph_start(set, sdcard_handle); diff --git a/components/audio_board/lyrat_v4_3/board.h b/components/audio_board/lyrat_v4_3/board.h index d1a6b3e..935addf 100644 --- a/components/audio_board/lyrat_v4_3/board.h +++ b/components/audio_board/lyrat_v4_3/board.h @@ -30,6 +30,7 @@ #include "board_pins_config.h" #include "esp_peripherals.h" #include "display_service.h" +#include "periph_sdcard.h" #ifdef __cplusplus extern "C" { @@ -85,7 +86,7 @@ esp_err_t audio_board_key_init(esp_periph_set_handle_t set); * - ESP_OK, success * - Others, fail */ -esp_err_t audio_board_sdcard_init(esp_periph_set_handle_t set); +esp_err_t audio_board_sdcard_init(esp_periph_set_handle_t set, periph_sdcard_mode_t mode); /** * @brief Query audio_board_handle diff --git a/components/audio_board/lyratd_msc_v2_1/board.c b/components/audio_board/lyratd_msc_v2_1/board.c index 070205d..25597d2 100644 --- a/components/audio_board/lyratd_msc_v2_1/board.c +++ b/components/audio_board/lyratd_msc_v2_1/board.c @@ -89,11 +89,16 @@ esp_err_t audio_board_key_init(esp_periph_set_handle_t set) return esp_periph_start(set, adc_btn_handle); } -esp_err_t audio_board_sdcard_init(esp_periph_set_handle_t set) +esp_err_t audio_board_sdcard_init(esp_periph_set_handle_t set, periph_sdcard_mode_t mode) { + if (mode != SD_MODE_1_LINE) { + ESP_LOGE(TAG, "current board only support 1-line SD mode!"); + return ESP_FAIL; + } periph_sdcard_cfg_t sdcard_cfg = { .root = "/sdcard", .card_detect_pin = get_sdcard_intr_gpio(), // GPIO_NUM_34 + .mode = mode }; esp_periph_handle_t sdcard_handle = periph_sdcard_init(&sdcard_cfg); esp_err_t ret = esp_periph_start(set, sdcard_handle); diff --git a/components/audio_board/lyratd_msc_v2_1/board.h b/components/audio_board/lyratd_msc_v2_1/board.h index d1a6b3e..935addf 100644 --- a/components/audio_board/lyratd_msc_v2_1/board.h +++ b/components/audio_board/lyratd_msc_v2_1/board.h @@ -30,6 +30,7 @@ #include "board_pins_config.h" #include "esp_peripherals.h" #include "display_service.h" +#include "periph_sdcard.h" #ifdef __cplusplus extern "C" { @@ -85,7 +86,7 @@ esp_err_t audio_board_key_init(esp_periph_set_handle_t set); * - ESP_OK, success * - Others, fail */ -esp_err_t audio_board_sdcard_init(esp_periph_set_handle_t set); +esp_err_t audio_board_sdcard_init(esp_periph_set_handle_t set, periph_sdcard_mode_t mode); /** * @brief Query audio_board_handle diff --git a/components/audio_board/lyratd_msc_v2_2/board.c b/components/audio_board/lyratd_msc_v2_2/board.c index 070205d..25597d2 100644 --- a/components/audio_board/lyratd_msc_v2_2/board.c +++ b/components/audio_board/lyratd_msc_v2_2/board.c @@ -89,11 +89,16 @@ esp_err_t audio_board_key_init(esp_periph_set_handle_t set) return esp_periph_start(set, adc_btn_handle); } -esp_err_t audio_board_sdcard_init(esp_periph_set_handle_t set) +esp_err_t audio_board_sdcard_init(esp_periph_set_handle_t set, periph_sdcard_mode_t mode) { + if (mode != SD_MODE_1_LINE) { + ESP_LOGE(TAG, "current board only support 1-line SD mode!"); + return ESP_FAIL; + } periph_sdcard_cfg_t sdcard_cfg = { .root = "/sdcard", .card_detect_pin = get_sdcard_intr_gpio(), // GPIO_NUM_34 + .mode = mode }; esp_periph_handle_t sdcard_handle = periph_sdcard_init(&sdcard_cfg); esp_err_t ret = esp_periph_start(set, sdcard_handle); diff --git a/components/audio_board/lyratd_msc_v2_2/board.h b/components/audio_board/lyratd_msc_v2_2/board.h index d1a6b3e..935addf 100644 --- a/components/audio_board/lyratd_msc_v2_2/board.h +++ b/components/audio_board/lyratd_msc_v2_2/board.h @@ -30,6 +30,7 @@ #include "board_pins_config.h" #include "esp_peripherals.h" #include "display_service.h" +#include "periph_sdcard.h" #ifdef __cplusplus extern "C" { @@ -85,7 +86,7 @@ esp_err_t audio_board_key_init(esp_periph_set_handle_t set); * - ESP_OK, success * - Others, fail */ -esp_err_t audio_board_sdcard_init(esp_periph_set_handle_t set); +esp_err_t audio_board_sdcard_init(esp_periph_set_handle_t set, periph_sdcard_mode_t mode); /** * @brief Query audio_board_handle diff --git a/components/audio_hal/driver/ac101/ac101.c b/components/audio_hal/driver/ac101/ac101.c old mode 100644 new mode 100755 diff --git a/components/audio_hal/driver/ac101/ac101.h b/components/audio_hal/driver/ac101/ac101.h old mode 100644 new mode 100755 diff --git a/components/audio_hal/driver/es7243/es7243.c b/components/audio_hal/driver/es7243/es7243.c index f555bb7..1eede86 100644 --- a/components/audio_hal/driver/es7243/es7243.c +++ b/components/audio_hal/driver/es7243/es7243.c @@ -28,6 +28,7 @@ #include "board.h" #include "esp_log.h" +#define MCLK_PULSES_NUMBER (20) #define ES_ASSERT(a, format, b, ...) \ if ((a) != 0) { \ ESP_LOGE(TAG, format, ##__VA_ARGS__); \ @@ -76,9 +77,28 @@ esp_err_t es7243_adc_set_addr(int addr) return ESP_OK; } +static esp_err_t es7243_mclk_active(uint8_t mclk_gpio) +{ + gpio_pad_select_gpio(mclk_gpio); + gpio_set_direction(mclk_gpio, GPIO_MODE_OUTPUT); + /* + Before initializing es7243, it is necessary to output + mclk to es7243 to activate the I2C configuration. + So give some clocks to active es7243. + */ + for (int i = 0; i < MCLK_PULSES_NUMBER; ++i) { + gpio_set_level(mclk_gpio, 0); + vTaskDelay(1 / portTICK_PERIOD_MS); + gpio_set_level(mclk_gpio, 1); + vTaskDelay(1 / portTICK_PERIOD_MS); + } + return ESP_OK; +} + esp_err_t es7243_adc_init(audio_hal_codec_config_t *codec_cfg) { esp_err_t ret = ESP_OK; + es7243_mclk_active(get_es7243_mclk_gpio()); i2c_init(); ret |= es7243_write_reg(0x00, 0x01); ret |= es7243_write_reg(0x06, 0x00); diff --git a/components/audio_hal/driver/es8311/es8311.c b/components/audio_hal/driver/es8311/es8311.c index d5090f9..4ccdda3 100644 --- a/components/audio_hal/driver/es8311/es8311.c +++ b/components/audio_hal/driver/es8311/es8311.c @@ -480,7 +480,6 @@ esp_err_t es8311_codec_init(audio_hal_codec_config_t *codec_cfg) ret |= es8311_write_reg(ES8311_SYSTEM_REG13, 0x10); ret |= es8311_write_reg(ES8311_ADC_REG1B, 0x0A); ret |= es8311_write_reg(ES8311_ADC_REG1C, 0x6A); - ret |= es8311_write_reg(ES8311_GPIO_REG44, 0x08); es8311_pa_power(true); return ESP_OK; diff --git a/components/audio_hal/driver/es8388/es8388.c b/components/audio_hal/driver/es8388/es8388.c index 4d58c55..94ba243 100755 --- a/components/audio_hal/driver/es8388/es8388.c +++ b/components/audio_hal/driver/es8388/es8388.c @@ -479,6 +479,7 @@ esp_err_t es8388_set_mic_gain(es_mic_gain_t gain) { esp_err_t res, gain_n; gain_n = (int)gain / 3; + gain_n = (gain_n << 4) + gain_n; res = es_write_reg(ES8388_ADDR, ES8388_ADCCONTROL1, gain_n); //MIC PGA return res; } diff --git a/components/audio_pipeline/audio_element.c b/components/audio_pipeline/audio_element.c index 2086b27..bec5112 100644 --- a/components/audio_pipeline/audio_element.c +++ b/components/audio_pipeline/audio_element.c @@ -133,6 +133,9 @@ const static int TASK_DESTROYED_BIT = BIT4; const static int PAUSED_BIT = BIT5; const static int RESUMED_BIT = BIT6; +static esp_err_t audio_element_on_cmd_error(audio_element_handle_t el); +static esp_err_t audio_element_on_cmd_stop(audio_element_handle_t el); + static esp_err_t audio_element_force_set_state(audio_element_handle_t el, audio_element_state_t new_state) { el->state = new_state; @@ -168,6 +171,7 @@ esp_err_t audio_element_process_init(audio_element_handle_t el) return ESP_OK; } el->is_open = true; + audio_element_force_set_state(el, AEL_STATE_INITIALIZING); esp_err_t ret = el->open(el); if (ret == ESP_OK) { ESP_LOGD(TAG, "[%s] el opened", el->tag); @@ -176,14 +180,18 @@ esp_err_t audio_element_process_init(audio_element_handle_t el) xEventGroupSetBits(el->state_event, STARTED_BIT); return ESP_OK; } else if (ret == AEL_IO_DONE) { - ESP_LOGW(TAG, "[%s] AEL_STATUS_ERROR_OPEN IO_DONE,%d", el->tag, ret); - audio_element_force_set_state(el, AEL_STATE_ERROR); - audio_element_cmd_send(el, AEL_MSG_CMD_ERROR); + ESP_LOGW(TAG, "[%s] OPEN AEL_IO_DONE", el->tag); + audio_element_force_set_state(el, AEL_STATE_RUNNING); + audio_element_report_status(el, AEL_STATUS_STATE_RUNNING); + return ESP_OK; + } else if (ret == AEL_IO_ABORT) { + ESP_LOGW(TAG, "[%s] AEL_IO_ABORT, %d", el->tag, ret); + audio_element_on_cmd_stop(el); } else { ESP_LOGE(TAG, "[%s] AEL_STATUS_ERROR_OPEN,%d", el->tag, ret); audio_element_force_set_state(el, AEL_STATE_ERROR); audio_element_report_status(el, AEL_STATUS_ERROR_OPEN); - audio_element_cmd_send(el, AEL_MSG_CMD_ERROR); + audio_element_on_cmd_error(el); } return ESP_FAIL; } @@ -193,12 +201,92 @@ esp_err_t audio_element_process_deinit(audio_element_handle_t el) if (el->is_open && el->close) { ESP_LOGV(TAG, "[%s] will be closed, line %d", el->tag, __LINE__); el->close(el); - } el->is_open = false; return ESP_OK; } +static esp_err_t audio_element_on_cmd_error(audio_element_handle_t el) +{ + if (el->state != AEL_STATE_STOPPED) { + ESP_LOGW(TAG, "[%s] audio_element_on_cmd_error,%d", el->tag, el->state); + audio_element_process_deinit(el); + el->state = AEL_STATE_ERROR; + audio_event_iface_set_cmd_waiting_timeout(el->iface_event, portMAX_DELAY); + el->is_running = false; + xEventGroupSetBits(el->state_event, STOPPED_BIT); + } + return ESP_OK; +} + +static esp_err_t audio_element_on_cmd_stop(audio_element_handle_t el) +{ + if ((el->state != AEL_STATE_FINISHED) && (el->state != AEL_STATE_STOPPED)) { + audio_element_process_deinit(el); + el->state = AEL_STATE_STOPPED; + audio_event_iface_set_cmd_waiting_timeout(el->iface_event, portMAX_DELAY); + audio_element_report_status(el, AEL_STATUS_STATE_STOPPED); + el->is_running = false; + el->stopping = false; + ESP_LOGD(TAG, "[%s] audio_element_on_cmd_stop", el->tag); + xEventGroupSetBits(el->state_event, STOPPED_BIT); + } else { + // Change element state to AEL_STATE_STOPPED, even if AEL_STATE_ERROR or AEL_STATE_FINISHED + // Except AEL_STATE_STOPPED and is not running + ESP_LOGD(TAG, "[%s] audio_element_on_cmd_stop, state:%d", el->tag, el->state); + if ((el->is_running == false) && (el->state == AEL_STATE_STOPPED)) { + el->stopping = false; + return ESP_OK; + } + el->state = AEL_STATE_STOPPED; + el->is_running = false; + el->stopping = false; + audio_element_report_status(el, AEL_STATUS_STATE_STOPPED); + xEventGroupSetBits(el->state_event, STOPPED_BIT); + } + return ESP_OK; +} + +static esp_err_t audio_element_on_cmd_finish(audio_element_handle_t el) +{ + if ((el->state == AEL_STATE_ERROR) + || (el->state == AEL_STATE_STOPPED)) { + ESP_LOGD(TAG, "[%s] audio_element_on_cmd_finish, state:%d", el->tag, el->state); + return ESP_OK; + } + audio_element_process_deinit(el); + el->state = AEL_STATE_FINISHED; + audio_event_iface_set_cmd_waiting_timeout(el->iface_event, portMAX_DELAY); + audio_element_report_status(el, AEL_STATUS_STATE_FINISHED); + el->is_running = false; + xEventGroupSetBits(el->state_event, STOPPED_BIT); + ESP_LOGD(TAG, "[%s] audio_element_on_cmd_finish", el->tag); + return ESP_OK; +} + +static esp_err_t audio_element_on_cmd_resume(audio_element_handle_t el) +{ + if (el->state == AEL_STATE_RUNNING) { + el->is_running = true; + xEventGroupSetBits(el->state_event, RESUMED_BIT); + return ESP_OK; + } + if (el->state != AEL_STATE_INIT && el->state != AEL_STATE_RUNNING && el->state != AEL_STATE_PAUSED) { + audio_element_reset_output_ringbuf(el); + } + el->is_running = true; + xEventGroupSetBits(el->state_event, RESUMED_BIT); + if (audio_element_process_init(el) != ESP_OK) { + audio_element_abort_output_ringbuf(el); + audio_element_abort_input_ringbuf(el); + el->is_running = false; + return ESP_FAIL; + } + audio_event_iface_set_cmd_waiting_timeout(el->iface_event, 0); + xEventGroupClearBits(el->state_event, STOPPED_BIT); + return ESP_OK; +} + static esp_err_t audio_element_on_cmd(audio_event_iface_msg_t *msg, void *context) { audio_element_handle_t el = (audio_element_handle_t)context; @@ -207,51 +295,16 @@ static esp_err_t audio_element_on_cmd(audio_event_iface_msg_t *msg, void *contex ESP_LOGE(TAG, "[%s] Invalid event type, this event should be ELEMENT type", el->tag); return ESP_FAIL; } + esp_err_t ret = ESP_OK; //process an event switch (msg->cmd) { - case AEL_MSG_CMD_ERROR: - if (el->state != AEL_STATE_STOPPED) { - ESP_LOGW(TAG, "[%s] AEL_MSG_CMD_ERROR,%d", el->tag, el->state); - audio_element_process_deinit(el); - el->state = AEL_STATE_ERROR; - audio_event_iface_set_cmd_waiting_timeout(el->iface_event, portMAX_DELAY); - el->is_running = false; - xEventGroupSetBits(el->state_event, STOPPED_BIT); - } - break; case AEL_MSG_CMD_FINISH: - if ((el->state == AEL_STATE_ERROR) - || (el->state == AEL_STATE_STOPPED)) { - ESP_LOGD(TAG, "[%s] AEL_MSG_CMD_FINISH, state:%d", el->tag, el->state); - break; - } - audio_element_process_deinit(el); - el->state = AEL_STATE_FINISHED; - audio_event_iface_set_cmd_waiting_timeout(el->iface_event, portMAX_DELAY); - audio_element_report_status(el, AEL_STATUS_STATE_FINISHED); - el->is_running = false; - xEventGroupSetBits(el->state_event, STOPPED_BIT); - ESP_LOGD(TAG, "[%s] AEL_MSG_CMD_FINISH", el->tag); + ESP_LOGD(TAG, "[%s] AEL_MSG_CMD_FINISH, state:%d", el->tag, el->state); + ret = audio_element_on_cmd_finish(el); break; case AEL_MSG_CMD_STOP: - if ((el->state != AEL_STATE_FINISHED) && (el->state != AEL_STATE_STOPPED)) { - audio_element_process_deinit(el); - el->state = AEL_STATE_STOPPED; - audio_event_iface_set_cmd_waiting_timeout(el->iface_event, portMAX_DELAY); - audio_element_report_status(el, AEL_STATUS_STATE_STOPPED); - el->is_running = false; - el->stopping = false; - ESP_LOGD(TAG, "[%s] AEL_MSG_CMD_STOP", el->tag); - xEventGroupSetBits(el->state_event, STOPPED_BIT); - } else { - // Change element state to AEL_STATE_STOPPED, even if AEL_STATE_ERROR or AEL_STATE_FINISHED. - ESP_LOGD(TAG, "[%s] AEL_MSG_CMD_STOP, state:%d", el->tag, el->state); - el->state = AEL_STATE_STOPPED; - el->is_running = false; - el->stopping = false; - audio_element_report_status(el, AEL_STATUS_STATE_STOPPED); - xEventGroupSetBits(el->state_event, STOPPED_BIT); - } + ESP_LOGD(TAG, "[%s] AEL_MSG_CMD_STOP, state:%d", el->tag, el->state); + ret = audio_element_on_cmd_stop(el); break; case AEL_MSG_CMD_PAUSE: el->state = AEL_STATE_PAUSED; @@ -264,32 +317,14 @@ static esp_err_t audio_element_on_cmd(audio_event_iface_msg_t *msg, void *contex break; case AEL_MSG_CMD_RESUME: ESP_LOGI(TAG, "[%s] AEL_MSG_CMD_RESUME,state:%d", el->tag, el->state); - if (el->state == AEL_STATE_RUNNING) { - el->is_running = true; - xEventGroupSetBits(el->state_event, RESUMED_BIT); - break; - } - if (el->state != AEL_STATE_INIT && el->state != AEL_STATE_RUNNING && el->state != AEL_STATE_PAUSED) { - audio_element_reset_output_ringbuf(el); - } - el->is_running = true; - xEventGroupSetBits(el->state_event, RESUMED_BIT); - if (audio_element_process_init(el) != ESP_OK) { - audio_element_abort_output_ringbuf(el); - audio_element_abort_input_ringbuf(el); - el->is_running = false; - return ESP_FAIL; - } - audio_event_iface_set_cmd_waiting_timeout(el->iface_event, 0); - xEventGroupClearBits(el->state_event, STOPPED_BIT); + ret = audio_element_on_cmd_resume(el); break; case AEL_MSG_CMD_DESTROY: - el->task_run = false; el->is_running = false; ESP_LOGD(TAG, "[%s] AEL_MSG_CMD_DESTROY", el->tag); - return ESP_FAIL; + ret = AEL_IO_ABORT; } - return ESP_OK; + return ret; } static esp_err_t audio_element_process_running(audio_element_handle_t el) @@ -303,23 +338,21 @@ static esp_err_t audio_element_process_running(audio_element_handle_t el) switch (process_len) { case AEL_IO_ABORT: ESP_LOGD(TAG, "[%s] ERROR_PROCESS, AEL_IO_ABORT", el->tag); - audio_element_cmd_send(el, AEL_MSG_CMD_STOP); + audio_element_on_cmd_stop(el); break; case AEL_IO_DONE: case AEL_IO_OK: // Re-open if reset_state function called if (audio_element_get_state(el) == AEL_STATE_INIT) { - el->is_running = false; - audio_element_cmd_send(el, AEL_MSG_CMD_RESUME); - return ESP_OK; + return audio_element_on_cmd_resume(el); } audio_element_set_ringbuf_done(el); - audio_element_cmd_send(el, AEL_MSG_CMD_FINISH); + audio_element_on_cmd_finish(el); break; case AEL_IO_FAIL: ESP_LOGE(TAG, "[%s] ERROR_PROCESS, AEL_IO_FAIL", el->tag); audio_element_report_status(el, AEL_STATUS_ERROR_PROCESS); - audio_element_cmd_send(el, AEL_MSG_CMD_ERROR); + audio_element_on_cmd_error(el); break; case AEL_IO_TIMEOUT: ESP_LOGD(TAG, "[%s] ERROR_PROCESS, AEL_IO_TIMEOUT", el->tag); @@ -327,7 +360,7 @@ static esp_err_t audio_element_process_running(audio_element_handle_t el) case AEL_PROCESS_FAIL: ESP_LOGE(TAG, "[%s] ERROR_PROCESS, AEL_PROCESS_FAIL", el->tag); audio_element_report_status(el, AEL_STATUS_ERROR_PROCESS); - audio_element_cmd_send(el, AEL_MSG_CMD_ERROR); + audio_element_on_cmd_error(el); break; default: ESP_LOGW(TAG, "[%s] Process return error,ret:%d", el->tag, process_len); @@ -361,8 +394,6 @@ audio_element_err_t audio_element_input(audio_element_handle_t el, char *buffer, switch (in_len) { case AEL_IO_ABORT: ESP_LOGW(TAG, "IN-[%s] AEL_IO_ABORT", el->tag); - audio_element_abort_output_ringbuf(el); - audio_element_cmd_send(el, AEL_MSG_CMD_STOP); break; case AEL_IO_DONE: case AEL_IO_OK: @@ -371,14 +402,12 @@ audio_element_err_t audio_element_input(audio_element_handle_t el, char *buffer, case AEL_IO_FAIL: ESP_LOGE(TAG, "IN-[%s] AEL_STATUS_ERROR_INPUT", el->tag); audio_element_report_status(el, AEL_STATUS_ERROR_INPUT); - audio_element_cmd_send(el, AEL_MSG_CMD_ERROR); break; case AEL_IO_TIMEOUT: // ESP_LOGD(TAG, "IN-[%s] AEL_IO_TIMEOUT", el->tag); break; default: ESP_LOGE(TAG, "IN-[%s] Input return not support,ret:%d", el->tag, in_len); - audio_element_cmd_send(el, AEL_MSG_CMD_PAUSE); break; } } @@ -405,8 +434,6 @@ audio_element_err_t audio_element_output(audio_element_handle_t el, char *buffer switch (output_len) { case AEL_IO_ABORT: ESP_LOGW(TAG, "OUT-[%s] AEL_IO_ABORT", el->tag); - audio_element_abort_input_ringbuf(el); - audio_element_cmd_send(el, AEL_MSG_CMD_STOP); break; case AEL_IO_DONE: case AEL_IO_OK: @@ -415,15 +442,12 @@ audio_element_err_t audio_element_output(audio_element_handle_t el, char *buffer case AEL_IO_FAIL: ESP_LOGE(TAG, "OUT-[%s] AEL_STATUS_ERROR_OUTPUT", el->tag); audio_element_report_status(el, AEL_STATUS_ERROR_OUTPUT); - audio_element_cmd_send(el, AEL_MSG_CMD_ERROR); break; case AEL_IO_TIMEOUT: ESP_LOGW(TAG, "OUT-[%s] AEL_IO_TIMEOUT", el->tag); - audio_element_cmd_send(el, AEL_MSG_CMD_PAUSE); break; default: ESP_LOGE(TAG, "OUT-[%s] Output return not support,ret:%d", el->tag, output_len); - audio_element_cmd_send(el, AEL_MSG_CMD_PAUSE); break; } } @@ -444,14 +468,15 @@ void audio_element_task(void *pv) }); } xEventGroupClearBits(el->state_event, STOPPED_BIT); + esp_err_t ret = ESP_OK; while (el->task_run) { - if (audio_event_iface_waiting_cmd_msg(el->iface_event) != ESP_OK) { + if ((ret = audio_event_iface_waiting_cmd_msg(el->iface_event)) != ESP_OK) { xEventGroupSetBits(el->state_event, STOPPED_BIT); /* * Do not exit task when audio_element_process_init failure to * make call audio_element_deinit safety. */ - if (el->task_run == 0) { + if (ret == AEL_IO_ABORT) { break; } } @@ -461,11 +486,13 @@ void audio_element_task(void *pv) } if (el->is_open && el->close) { - ESP_LOGD(TAG, "[%s] el closed", el->tag); + ESP_LOGD(TAG, "[%s-%p] el closed", el->tag, el); el->close(el); + audio_element_force_set_state(el, AEL_STATE_STOPPED); } el->is_open = false; audio_free(el->buf); + el->buf = NULL; el->stopping = false; el->task_run = false; ESP_LOGD(TAG, "[%s-%p] el task deleted,%d", el->tag, el, uxTaskGetStackHighWaterMark(NULL)); @@ -482,7 +509,10 @@ esp_err_t audio_element_reset_state(audio_element_handle_t el) audio_element_state_t audio_element_get_state(audio_element_handle_t el) { - return el->state; + if (el) { + return el->state; + } + return ESP_FAIL; } QueueHandle_t audio_element_get_event_queue(audio_element_handle_t el) @@ -912,6 +942,8 @@ audio_element_handle_t audio_element_init(audio_element_cfg_t *config) evt_cfg.on_cmd = audio_element_on_cmd; evt_cfg.context = el; evt_cfg.queue_set_size = 0; // Element have no queue_set by default. + evt_cfg.external_queue_size = 5; + evt_cfg.internal_queue_size = 5; bool _success = ( ((config->tag ? audio_element_set_tag(el, config->tag) : audio_element_set_tag(el, "unknown")) == ESP_OK) && @@ -1083,16 +1115,16 @@ static inline esp_err_t __audio_element_term(audio_element_handle_t el, TickType { xEventGroupClearBits(el->state_event, TASK_DESTROYED_BIT); if (audio_element_cmd_send(el, AEL_MSG_CMD_DESTROY) != ESP_OK) { - ESP_LOGE(TAG, "[%s] Element destroy CMD failed", el->tag); + ESP_LOGE(TAG, "[%s] Send destroy command failed", el->tag); return ESP_FAIL; } EventBits_t uxBits = xEventGroupWaitBits(el->state_event, TASK_DESTROYED_BIT, false, true, ticks_to_wait); esp_err_t ret = ESP_FAIL; if (uxBits & TASK_DESTROYED_BIT ) { - ESP_LOGD(TAG, "[%s] Element task destroyed", el->tag); + ESP_LOGD(TAG, "[%s-%p] Element task destroyed", el->tag, el); ret = ESP_OK; } else { - ESP_LOGW(TAG, "[%s] Element task destroy timeout[%d]", el->tag, ticks_to_wait); + ESP_LOGW(TAG, "[%s-%p] Element task destroy timeout[%d]", el->tag, el, ticks_to_wait); } return ret; } @@ -1186,10 +1218,13 @@ esp_err_t audio_element_resume(audio_element_handle_t el, float wait_for_rb_thre } int ret = ESP_OK; xEventGroupClearBits(el->state_event, RESUMED_BIT); - audio_element_cmd_send(el, AEL_MSG_CMD_RESUME); + if (audio_element_cmd_send(el, AEL_MSG_CMD_RESUME) == ESP_FAIL) { + ESP_LOGW(TAG, "[%s] Send resume command failed", el->tag); + return ESP_FAIL; + } EventBits_t uxBits = xEventGroupWaitBits(el->state_event, RESUMED_BIT, false, true, timeout); if ((uxBits & RESUMED_BIT) != RESUMED_BIT) { - ESP_LOGW(TAG, "[%s] RESUME timeout", el->tag); + ESP_LOGW(TAG, "[%s-%p] RESUME timeout", el->tag, el); ret = ESP_FAIL; } else { if (wait_for_rb_threshold != 0 && el->read_type == IO_TYPE_RB) { @@ -1205,6 +1240,14 @@ esp_err_t audio_element_stop(audio_element_handle_t el) ESP_LOGD(TAG, "[%s] Element has not create when AUDIO_ELEMENT_STOP", el->tag); return ESP_FAIL; } + if (el->is_running == false) { + xEventGroupSetBits(el->state_event, STOPPED_BIT); + audio_element_report_status(el, AEL_STATUS_STATE_STOPPED); + ESP_LOGE(TAG, "[%s] Element already stopped", el->tag); + return ESP_OK; + } + audio_element_abort_output_ringbuf(el); + audio_element_abort_input_ringbuf(el); if (el->state == AEL_STATE_RUNNING) { xEventGroupClearBits(el->state_event, STOPPED_BIT); } @@ -1216,17 +1259,8 @@ esp_err_t audio_element_stop(audio_element_handle_t el) return ESP_OK; } if (el->state == AEL_STATE_PAUSED) { - el->is_running = true; audio_event_iface_set_cmd_waiting_timeout(el->iface_event, 0); } - if (el->is_running == false) { - xEventGroupSetBits(el->state_event, STOPPED_BIT); - audio_element_report_status(el, AEL_STATUS_STATE_STOPPED); - ESP_LOGW(TAG, "[%s] Element already stopped", el->tag); - return ESP_OK; - } - audio_element_abort_output_ringbuf(el); - audio_element_abort_input_ringbuf(el); if (el->stopping) { ESP_LOGD(TAG, "[%s] Stop command has already sent, %d", el->tag, el->stopping); return ESP_OK; @@ -1234,10 +1268,10 @@ esp_err_t audio_element_stop(audio_element_handle_t el) el->stopping = true; if (audio_element_cmd_send(el, AEL_MSG_CMD_STOP) != ESP_OK) { el->stopping = false; - ESP_LOGW(TAG, "[%s] Send stop command failed", el->tag); + ESP_LOGW(TAG, "[%s-%p] Send stop command failed", el->tag, el); return ESP_FAIL; } - ESP_LOGD(TAG, "[%s] Send stop command", el->tag); + ESP_LOGD(TAG, "[%s-%p] Send stop command", el->tag, el); return ESP_OK; } diff --git a/components/audio_pipeline/audio_event_iface.c b/components/audio_pipeline/audio_event_iface.c index a5f40f0..5ab776c 100644 --- a/components/audio_pipeline/audio_event_iface.c +++ b/components/audio_pipeline/audio_event_iface.c @@ -104,9 +104,10 @@ static esp_err_t audio_event_iface_cleanup_listener(audio_event_iface_handle_t l audio_event_iface_item_t *item, *tmp; audio_event_iface_discard(listen); STAILQ_FOREACH_SAFE(item, &listen->listening_queues, next, tmp) { + audio_event_iface_msg_t dummy; + while (audio_event_iface_read(listen, &dummy, 0) == ESP_OK); if (listen->queue_set && xQueueRemoveFromSet(item->queue, listen->queue_set) != pdPASS) { - ESP_LOGE(TAG, "Error remove listener"); - return ESP_FAIL; + ESP_LOGW(TAG, "Error remove listener,%p", item->queue); } } if (listen->queue_set) { @@ -241,8 +242,8 @@ esp_err_t audio_event_iface_waiting_cmd_msg(audio_event_iface_handle_t evt) { audio_event_iface_msg_t msg; if (evt->internal_queue && (xQueueReceive(evt->internal_queue, (void *)&msg, evt->wait_time) == pdTRUE)) { - if (evt->on_cmd && evt->on_cmd((void *)&msg, evt->context) != ESP_OK) { - return ESP_FAIL; + if (evt->on_cmd) { + return evt->on_cmd((void *)&msg, evt->context); } } return ESP_OK; @@ -251,7 +252,7 @@ esp_err_t audio_event_iface_waiting_cmd_msg(audio_event_iface_handle_t evt) esp_err_t audio_event_iface_cmd(audio_event_iface_handle_t evt, audio_event_iface_msg_t *msg) { if (evt->internal_queue && (xQueueSend(evt->internal_queue, (void *)msg, 0) != pdPASS)) { - ESP_LOGD(TAG, "There are no space to dispatch queue"); + ESP_LOGW(TAG, "There are no space to dispatch queue"); return ESP_FAIL; } return ESP_OK; @@ -269,7 +270,7 @@ esp_err_t audio_event_iface_sendout(audio_event_iface_handle_t evt, audio_event_ { if (evt->external_queue) { if (xQueueSend(evt->external_queue, (void *)msg, 0) != pdPASS) { - ESP_LOGD(TAG, "There is no space in external queue"); + ESP_LOGW(TAG, "There is no space in external queue"); return ESP_FAIL; } } diff --git a/components/audio_pipeline/audio_pipeline.c b/components/audio_pipeline/audio_pipeline.c index 16f4224..b41e5e6 100644 --- a/components/audio_pipeline/audio_pipeline.c +++ b/components/audio_pipeline/audio_pipeline.c @@ -309,7 +309,8 @@ esp_err_t audio_pipeline_resume(audio_pipeline_handle_t pipeline) bool wait_first_el = true; esp_err_t ret = ESP_OK; STAILQ_FOREACH(el_item, &pipeline->el_list, next) { - ESP_LOGD(TAG, "resume,linked:%d, state:%d,[%p]", el_item->linked, audio_element_get_state(el_item->el), el_item->el); + ESP_LOGD(TAG, "resume,linked:%d, state:%d,[%s-%p]", el_item->linked, + audio_element_get_state(el_item->el), audio_element_get_tag(el_item->el), el_item->el); if (false == el_item->linked) { continue; } @@ -421,17 +422,12 @@ static inline esp_err_t __audio_pipeline_wait_stop(audio_pipeline_handle_t pipel if (res == ESP_ERR_TIMEOUT) { ESP_LOGW(TAG, "Wait stop timeout, el:%p, tag:%s", el_item->el, audio_element_get_tag(el_item->el) == NULL ? "NULL" : audio_element_get_tag(el_item->el)); + } else { + audio_element_reset_state(el_item->el); } ret |= res; } } - STAILQ_FOREACH(el_item, &pipeline->el_list, next) { - if (el_item->linked) { - audio_element_reset_input_ringbuf(el_item->el); - audio_element_reset_output_ringbuf(el_item->el); - audio_element_reset_state(el_item->el); - } - } audio_pipeline_change_state(pipeline, AEL_STATE_INIT); return ret; } @@ -539,8 +535,12 @@ esp_err_t audio_pipeline_unlink(audio_pipeline_handle_t pipeline) } } STAILQ_FOREACH_SAFE(rb_item, &pipeline->rb_list, next, tmp) { - ESP_LOGD(TAG, "audio_pipeline_unlink, RB, %p,", rb_item->rb); + ESP_LOGD(TAG, "audio_pipeline_unlink, RB:%p,host_el:%p", rb_item->rb, rb_item->host_el); STAILQ_REMOVE(&pipeline->rb_list, rb_item, ringbuf_item, next); + if (rb_item->host_el) { + audio_element_set_output_ringbuf(rb_item->host_el, NULL); + audio_element_set_input_ringbuf(rb_item->host_el, NULL); + } rb_destroy(rb_item->rb); rb_item->linked = false; rb_item->kept_ctx = false; @@ -671,7 +671,7 @@ esp_err_t audio_pipeline_check_items_state(audio_pipeline_handle_t pipeline, aud if (st == AEL_STATE_ERROR) { item->el_state = AEL_STATUS_ERROR_PROCESS; } else { - item->el_state = st + AEL_STATUS_OUTPUT_DONE; + item->el_state = st + AEL_STATUS_INPUT_BUFFERING; } } if (item->el_state == AEL_STATUS_NONE) { @@ -834,7 +834,8 @@ esp_err_t audio_pipeline_breakup_elements(audio_pipeline_handle_t pipeline, audi rb_item->kept_ctx = true; ESP_LOGD(TAG, "found kept_ctx_el:%p and ringbuf:%p", el_item->el, rb_item->rb); } else { - ESP_LOGW(TAG, "found kept_ctx_el and ringbuf, but not set kept"); + ESP_LOGW(TAG, "found kept_ctx_el and ringbuf, but not set kept, el:%p, rb:%p", el_item->el, rb_item->rb); + audio_element_set_output_ringbuf(el_item->el, NULL); } kept = false; audio_element_set_input_ringbuf(el_item->el, NULL); diff --git a/components/audio_pipeline/include/audio_element.h b/components/audio_pipeline/include/audio_element.h index 2ace3ff..aedd0c2 100755 --- a/components/audio_pipeline/include/audio_element.h +++ b/components/audio_pipeline/include/audio_element.h @@ -47,13 +47,14 @@ typedef enum { * @brief Audio element state */ typedef enum { - AEL_STATE_NONE = 0, - AEL_STATE_INIT, - AEL_STATE_RUNNING, - AEL_STATE_PAUSED, - AEL_STATE_STOPPED, - AEL_STATE_FINISHED, - AEL_STATE_ERROR + AEL_STATE_NONE = 0, + AEL_STATE_INIT = 1, + AEL_STATE_INITIALIZING = 2, + AEL_STATE_RUNNING = 3, + AEL_STATE_PAUSED = 4, + AEL_STATE_STOPPED = 5, + AEL_STATE_FINISHED = 6, + AEL_STATE_ERROR = 7 } audio_element_state_t; /** @@ -61,7 +62,7 @@ typedef enum { */ typedef enum { AEL_MSG_CMD_NONE = 0, - AEL_MSG_CMD_ERROR = 1, + // AEL_MSG_CMD_ERROR = 1, AEL_MSG_CMD_FINISH = 2, AEL_MSG_CMD_STOP = 3, AEL_MSG_CMD_PAUSE = 4, @@ -652,7 +653,7 @@ esp_err_t audio_element_change_cmd(audio_element_handle_t el, audio_element_msg_ esp_err_t audio_element_reset_output_ringbuf(audio_element_handle_t el); /** - * @brief Call this function to provice Element input data. + * @brief Call this function to provide Element input data. * Depending on setup using ringbuffer or function callback, Element invokes read ringbuffer, or calls read callback funtion. * * @param[in] el The audio element handle diff --git a/components/audio_pipeline/ringbuf.c b/components/audio_pipeline/ringbuf.c index eaafa85..1a48fd1 100644 --- a/components/audio_pipeline/ringbuf.c +++ b/components/audio_pipeline/ringbuf.c @@ -134,7 +134,10 @@ int rb_bytes_available(ringbuf_handle_t rb) int rb_bytes_filled(ringbuf_handle_t rb) { - return rb->fill_cnt; + if (rb) { + return rb->fill_cnt; + } + return ESP_FAIL; } static void rb_release(SemaphoreHandle_t handle) @@ -338,7 +341,6 @@ esp_err_t rb_abort(ringbuf_handle_t rb) } esp_err_t err = rb_abort_read(rb); err |= rb_abort_write(rb); - xSemaphoreGive(rb->lock); return err; } diff --git a/components/audio_sal/audio_mem.c b/components/audio_sal/audio_mem.c index 8314eed..4ee1c61 100644 --- a/components/audio_sal/audio_mem.c +++ b/components/audio_sal/audio_mem.c @@ -29,6 +29,7 @@ #include "esp_log.h" #include "audio_mem.h" #include "esp_heap_caps.h" +#include "esp_efuse.h" // #define ENABLE_AUDIO_MEM_TRACE @@ -104,10 +105,12 @@ char *audio_strdup(const char *str) void *audio_calloc_inner(size_t n, size_t size) { void *data = NULL; - data = heap_caps_malloc(n * size, MALLOC_CAP_INTERNAL | MALLOC_CAP_8BIT); - if (data) { - memset(data, 0, n * size); - } +#if CONFIG_SPIRAM_BOOT_INIT + data = heap_caps_calloc_prefer(n, size, 2, MALLOC_CAP_DEFAULT | MALLOC_CAP_INTERNAL | MALLOC_CAP_8BIT, MALLOC_CAP_DEFAULT | MALLOC_CAP_SPIRAM); +#else + data = heap_caps_calloc(n, size, MALLOC_CAP_INTERNAL | MALLOC_CAP_8BIT); +#endif + #ifdef ENABLE_AUDIO_MEM_TRACE ESP_LOGI("AUIDO_MEM", "calloc_inner:%p, size:%d, called:0x%08x", data, size, (intptr_t)__builtin_return_address(0) - 2); #endif @@ -135,3 +138,23 @@ bool audio_mem_spiram_is_enabled(void) return false; } #endif + +#if defined(CONFIG_SPIRAM_BOOT_INIT) && (CONFIG_SPIRAM_ALLOW_STACK_EXTERNAL_MEMORY) +bool audio_mem_spiram_stack_is_enabled(void) +{ + bool ret = true; +#if CONFIG_IDF_TARGET_ESP32 + uint8_t chip_ver = esp_efuse_get_chip_ver(); + if (chip_ver < 3) { + ESP_LOGW("AUIDO_MEM", "Can't support stack on external memory due to ESP32 chip is %d", chip_ver); + ret = false; + } +#endif + return ret; +} +#else +bool audio_mem_spiram_stack_is_enabled(void) +{ + return false; +} +#endif diff --git a/components/audio_sal/audio_sys.c b/components/audio_sal/audio_sys.c index 2a39fda..ce2c6f2 100644 --- a/components/audio_sal/audio_sys.c +++ b/components/audio_sal/audio_sys.c @@ -26,6 +26,28 @@ #include "freertos/FreeRTOS.h" #include "freertos/task.h" #include "esp_log.h" +#include "audio_mem.h" +#include "audio_error.h" +#include "audio_sys.h" +#include "soc/soc_memory_layout.h" + +static const char *TAG = "AUDIO_SYS"; + +#define ARRAY_SIZE_OFFSET 8 // Increase this if audio_sys_get_real_time_stats returns ESP_ERR_INVALID_SIZE +#define AUDIO_SYS_TASKS_ELAPSED_TIME_MS 1000 // Period of stats measurement + +const char *task_state[] = { + "Running", + "Ready", + "Blocked", + "Suspended", + "Deleted" +}; + +/** @brief + * "Extr": Allocated task stack from psram, "Intr": Allocated task stack from internel + */ +const char *task_stack[] = {"Extr", "Intr"}; int audio_sys_get_tick_by_time_ms(int ms) { @@ -39,3 +61,105 @@ int64_t audio_sys_get_time_ms(void) int64_t milliseconds = te.tv_sec * 1000LL + te.tv_usec / 1000; return milliseconds; } + +esp_err_t audio_sys_get_real_time_stats(void) +{ +#if (CONFIG_FREERTOS_VTASKLIST_INCLUDE_COREID && CONFIG_FREERTOS_GENERATE_RUN_TIME_STATS) + TaskStatus_t *start_array = NULL, *end_array = NULL; + UBaseType_t start_array_size, end_array_size; + uint32_t start_run_time, end_run_time; + uint32_t task_elapsed_time, percentage_time; + esp_err_t ret; + + // Allocate array to store current task states + start_array_size = uxTaskGetNumberOfTasks() + ARRAY_SIZE_OFFSET; + start_array = audio_malloc(sizeof(TaskStatus_t) * start_array_size); + AUDIO_MEM_CHECK(TAG, start_array, { + ret = ESP_FAIL; + goto exit; + }); + // Get current task states + start_array_size = uxTaskGetSystemState(start_array, start_array_size, &start_run_time); + if (start_array_size == 0) { + ESP_LOGE(TAG, "Insufficient array size for uxTaskGetSystemState. Trying increasing ARRAY_SIZE_OFFSET"); + ret = ESP_FAIL; + goto exit; + } + + vTaskDelay(pdMS_TO_TICKS(AUDIO_SYS_TASKS_ELAPSED_TIME_MS)); + + // Allocate array to store tasks states post delay + end_array_size = uxTaskGetNumberOfTasks() + ARRAY_SIZE_OFFSET; + end_array = audio_malloc(sizeof(TaskStatus_t) * end_array_size); + AUDIO_MEM_CHECK(TAG, start_array, { + ret = ESP_FAIL; + goto exit; + }); + + // Get post delay task states + end_array_size = uxTaskGetSystemState(end_array, end_array_size, &end_run_time); + if (end_array_size == 0) { + ESP_LOGE(TAG, "Insufficient array size for uxTaskGetSystemState. Trying increasing ARRAY_SIZE_OFFSET"); + ret = ESP_FAIL; + goto exit; + } + + // Calculate total_elapsed_time in units of run time stats clock period. + uint32_t total_elapsed_time = (end_run_time - start_run_time); + if (total_elapsed_time == 0) { + ESP_LOGE(TAG, "Delay duration too short. Trying increasing AUDIO_SYS_TASKS_ELAPSED_TIME_MS"); + ret = ESP_FAIL; + goto exit; + } + + ESP_LOGI(TAG, "| Task | Run Time | Per | Prio | HWM | State | CoreId | Stack "); + + // Match each task in start_array to those in the end_array + for (int i = 0; i < start_array_size; i++) { + for (int j = 0; j < end_array_size; j++) { + if (start_array[i].xHandle == end_array[j].xHandle) { + + task_elapsed_time = end_array[j].ulRunTimeCounter - start_array[i].ulRunTimeCounter; + percentage_time = (task_elapsed_time * 100UL) / (total_elapsed_time * portNUM_PROCESSORS); + ESP_LOGI(TAG, "| %-17s | %-11d |%2d%% | %-4u | %-9u | %-7s | %-8x | %s", + start_array[i].pcTaskName, task_elapsed_time, percentage_time, start_array[i].uxCurrentPriority, + start_array[i].usStackHighWaterMark, task_state[(start_array[i].eCurrentState)], + start_array[i].xCoreID, task_stack[esp_ptr_internal(pxTaskGetStackStart(start_array[i].xHandle))]); + + // Mark that task have been matched by overwriting their handles + start_array[i].xHandle = NULL; + end_array[j].xHandle = NULL; + break; + } + } + } + + // Print unmatched tasks + for (int i = 0; i < start_array_size; i++) { + if (start_array[i].xHandle != NULL) { + ESP_LOGI(TAG, "| %s | Deleted", start_array[i].pcTaskName); + } + } + for (int i = 0; i < end_array_size; i++) { + if (end_array[i].xHandle != NULL) { + ESP_LOGI(TAG, "| %s | Created", end_array[i].pcTaskName); + } + } + printf("\n"); + ret = ESP_OK; + +exit: // Common return path + if (start_array) { + audio_free(start_array); + start_array = NULL; + } + if (end_array) { + audio_free(end_array); + end_array = NULL; + } + return ret; +#else + ESP_LOGW(TAG, "Please enbale `CONFIG_FREERTOS_VTASKLIST_INCLUDE_COREID` and `CONFIG_FREERTOS_GENERATE_RUN_TIME_STATS` in menuconfig"); + return ESP_FAIL; +#endif +} \ No newline at end of file diff --git a/components/audio_sal/audio_thread.c b/components/audio_sal/audio_thread.c index d2308b8..4aaae9b 100644 --- a/components/audio_sal/audio_thread.c +++ b/components/audio_sal/audio_thread.c @@ -43,10 +43,11 @@ esp_err_t audio_thread_create(audio_thread_t *p_handle, const char *name, void(* uint32_t stack, int prio, bool stack_in_ext, int core_id) { StackType_t *task_stack = NULL; - if (stack_in_ext && audio_mem_spiram_is_enabled()) { + if (stack_in_ext && audio_mem_spiram_stack_is_enabled()) { /* - * Note: 1. Make sure selected the `CONFIG_SPIRAM_BOOT_INIT` and `CONFIG_SPIRAM_ALLOW_STACK_EXTERNAL_MEMORY` by `make menuconfig` - * 2. Please apply the $ADF_PATH/idf_patches/idf_v3.3_freertos.patch + * Note: 1. ESP32-ECO3 chip support stack on external memory only. + * 2. Make sure selected the `CONFIG_SPIRAM_BOOT_INIT` and `CONFIG_SPIRAM_ALLOW_STACK_EXTERNAL_MEMORY` by `make menuconfig` + * 3. Please apply the $ADF_PATH/idf_patches/idf_v3.3_freertos.patch * */ ESP_LOGI(TAG, "The %s task allocate stack on external memory", name); @@ -67,12 +68,12 @@ esp_err_t audio_thread_create(audio_thread_t *p_handle, const char *name, void(* } } }; - if (xTaskCreateRestrictedPinnedToCore(&xRegParameters, (xTaskHandle)&p_handle, core_id) != pdPASS) { + if (xTaskCreateRestrictedPinnedToCore(&xRegParameters, (xTaskHandle)p_handle, core_id) != pdPASS) { ESP_LOGE(TAG, "Error creating RestrictedPinnedToCore %s", name); goto audio_thread_create_error; } } else { - if (xTaskCreatePinnedToCore(main_func, name, stack, arg, prio, (xTaskHandle)&p_handle, core_id) != pdPASS) { + if (xTaskCreatePinnedToCore(main_func, name, stack, arg, prio, (xTaskHandle)p_handle, core_id) != pdPASS) { ESP_LOGE(TAG, "Error creating task %s", name); goto audio_thread_create_error; } diff --git a/components/audio_sal/include/audio_mem.h b/components/audio_sal/include/audio_mem.h index f58936c..98a3d45 100644 --- a/components/audio_sal/include/audio_mem.h +++ b/components/audio_sal/include/audio_mem.h @@ -122,6 +122,15 @@ char *audio_strdup(const char *str); */ bool audio_mem_spiram_is_enabled(void); +/** + * @brief Stack on external SPI ram is enabled or not + * + * @return + * - true, stack on spi ram is enabled + * - false, stack on spi ram is not enabled + */ +bool audio_mem_spiram_stack_is_enabled(void); + #define AUDIO_MEM_SHOW(x) audio_mem_print(x, __LINE__, __func__) #ifdef __cplusplus diff --git a/components/audio_sal/include/audio_sys.h b/components/audio_sal/include/audio_sys.h index 4e64e69..fc64350 100644 --- a/components/audio_sal/include/audio_sys.h +++ b/components/audio_sal/include/audio_sys.h @@ -25,6 +25,8 @@ #ifndef _AUDIO_SYS_H_ #define _AUDIO_SYS_H_ +#include "esp_err.h" + #ifdef __cplusplus extern "C" { #endif @@ -50,6 +52,27 @@ int audio_sys_get_tick_by_time_ms(int ms); */ int64_t audio_sys_get_time_ms(void); +/** + * @brief Function to print the CPU usage of tasks over a given AUDIO_SYS_TASKS_ELAPSED_TIME_MS. + * + * This function will measure and print the CPU usage of tasks over a specified + * number of ticks (i.e. real time stats). This is implemented by simply calling + * uxTaskGetSystemState() twice separated by a delay, then calculating the + * differences of task run times before and after the delay. + * + * @note If any tasks are added or removed during the delay, the stats of + * those tasks will not be printed. + * @note This function should be called from a high priority task to minimize + * inaccuracies with delays. + * @note When running in dual core mode, each core will correspond to 50% of + * the run time. + * + * @return + * - ESP_OK + * - ESP_FIAL + */ +esp_err_t audio_sys_get_real_time_stats(void); + #ifdef __cplusplus } #endif diff --git a/components/audio_stream/CMakeLists.txt b/components/audio_stream/CMakeLists.txt index b91a920..c886820 100644 --- a/components/audio_stream/CMakeLists.txt +++ b/components/audio_stream/CMakeLists.txt @@ -7,7 +7,8 @@ set(COMPONENT_SRCS "fatfs_stream.c" "tone_stream.c" "algorithm_stream.c" "tcp_client_stream.c" - "pwm_stream.c") + "pwm_stream.c" + "tts_stream.c") set(COMPONENT_ADD_INCLUDEDIRS "include") diff --git a/components/audio_stream/algorithm_stream.c b/components/audio_stream/algorithm_stream.c index fc49135..72756e5 100644 --- a/components/audio_stream/algorithm_stream.c +++ b/components/audio_stream/algorithm_stream.c @@ -38,10 +38,7 @@ #define AGC_FRAME_BYTES 320 // 10ms data frame (10 * 16 * 2) #define AEC_FRAME_BYTES 512 // 16ms data frame (16 * 16 * 2) -#define ALGORITHM_STREAM_DEFAULT_SAMPLE_RATE_HZ 16000 //Hz -#define ALGORITHM_STREAM_DEFAULT_SAMPLE_BIT 16 -#define ALGORITHM_STREAM_DEFAULT_CHANNEL 1 - +#define ALGORITHM_STREAM_DEFAULT_AEC_MODE 3 #define ALGORITHM_STREAM_DEFAULT_AGC_MODE 3 #define ALGORITHM_STREAM_DEFAULT_AGC_FRAME_LENGTH 10 //ms @@ -63,6 +60,7 @@ typedef struct { ringbuf_handle_t input_rb; bool data_need_be_resampled; bool data_need_be_divided_after_rsp; //The encode mode of resample function doesn't support change channels + bool is_after_reset_res_info; } algorithm_data_info_t; typedef struct { @@ -79,6 +77,30 @@ typedef struct { algorithm_stream_input_type_t input_type; } algo_stream_t; +static esp_err_t create_record_rsp_handle(algo_stream_t *algo); +static esp_err_t create_reference_rsp_handle(algo_stream_t *algo); +static esp_err_t destroy_record_rsp_handle(algo_stream_t *algo); +static esp_err_t destroy_reference_rsp_handle(algo_stream_t *algo); + +static esp_err_t is_valid_algorithm_rsp_samplerate(int samplerate) +{ + if (samplerate < 8000 + || samplerate > 96000) { + ESP_LOGE(TAG, "The sample rate should be within range [8000,96000], here is %d Hz", samplerate); + return ESP_FAIL; + } + return ESP_OK; +} + +static esp_err_t is_valid_algorithm_rsp_channel(int channel) +{ + if (channel != 1 && channel != 2) { + ESP_LOGE(TAG, "The number of channels should be either 1 or 2, here is %d", channel); + return ESP_FAIL; + } + return ESP_OK; +} + static esp_err_t algorithm_data_info_destroy(algorithm_data_info_t *data_info) { static void *rsp_handle; @@ -144,7 +166,7 @@ static esp_err_t _algo_open(audio_element_handle_t self) bool _success = true; if (algo->algo_mask & ALGORITHM_STREAM_USE_AEC) { - _success &= ((algo->aec_handle = aec_create(ALGORITHM_STREAM_DEFAULT_SAMPLE_RATE_HZ, AEC_FRAME_LENGTH_MS, AEC_FILTER_LENGTH)) != NULL); + _success &= ((algo->aec_handle = aec_pro_create(AEC_FRAME_LENGTH_MS, ALGORITHM_STREAM_DEFAULT_CHANNEL, ALGORITHM_STREAM_DEFAULT_AEC_MODE)) != NULL); } if (algo->algo_mask & ALGORITHM_STREAM_USE_AGC) { _success &= ((algo->agc_handle = esp_agc_open(ALGORITHM_STREAM_DEFAULT_AGC_MODE, ALGORITHM_STREAM_DEFAULT_SAMPLE_RATE_HZ)) != NULL); @@ -371,6 +393,29 @@ static audio_element_err_t _algo_process(audio_element_handle_t self, char *in_b { int ret = ESP_OK; algo_stream_t *algo = (algo_stream_t *)audio_element_getdata(self); + + if (algo->record.is_after_reset_res_info) { + ret = destroy_record_rsp_handle(algo); + if (ret != ESP_OK) { + return AEL_PROCESS_FAIL; + } + ret = create_record_rsp_handle(algo); + if (ret != ESP_OK) { + return AEL_PROCESS_FAIL; + } + } + + if (algo->reference.is_after_reset_res_info) { + ret = destroy_reference_rsp_handle(algo); + if (ret != ESP_OK) { + return AEL_PROCESS_FAIL; + } + ret = create_reference_rsp_handle(algo); + if (ret != ESP_OK) { + return AEL_PROCESS_FAIL; + } + } + if (algo->input_type == ALGORITHM_STREAM_INPUT_TYPE1) { ret = algorithm_data_process_for_type1(self); } else if (algo->input_type == ALGORITHM_STREAM_INPUT_TYPE2) { @@ -382,11 +427,22 @@ static audio_element_err_t _algo_process(audio_element_handle_t self, char *in_b return ret; } -static esp_err_t algorithm_resample_config(algorithm_data_info_t *data_info, algorithm_stream_input_type_t type, int src_fre, int src_ch) +static esp_err_t algorithm_resample_config(resample_info_t *rsp_cfg, algorithm_data_info_t *data_info, algorithm_stream_input_type_t type) { + AUDIO_NULL_CHECK(TAG, rsp_cfg, return ESP_FAIL); + AUDIO_NULL_CHECK(TAG, data_info, return ESP_FAIL); + + rsp_cfg->dest_rate = ALGORITHM_STREAM_DEFAULT_SAMPLE_RATE_HZ; + rsp_cfg->dest_ch = ALGORITHM_STREAM_DEFAULT_CHANNEL; // The encode resample cannot process diffrent channel + rsp_cfg->mode = RESAMPLE_ENCODE_MODE; + rsp_cfg->sample_bits = ALGORITHM_STREAM_DEFAULT_SAMPLE_BIT; + rsp_cfg->max_indata_bytes = ALGORITHM_STREAM_RESAMPE_DEFAULT_MAX_INPUT_SIZE; // The max input data maybe 48K 2ch --> 16k 1ch; so max_data = AEC_FRAME_BYTES * 6 + rsp_cfg->complexity = ALGORITHM_STREAM_RESAMPE_DEFAULT_COMPLEXITY; + rsp_cfg->type = ESP_RESAMPLE_TYPE_AUTO; + if (type == ALGORITHM_STREAM_INPUT_TYPE1) { data_info->data_need_be_divided_after_rsp = false; - if (src_fre != ALGORITHM_STREAM_DEFAULT_SAMPLE_RATE_HZ) { + if (data_info->rsp_info.src_rate != ALGORITHM_STREAM_DEFAULT_SAMPLE_RATE_HZ) { data_info->data_need_be_resampled = true; } else { data_info->data_need_be_resampled = false; @@ -394,17 +450,17 @@ static esp_err_t algorithm_resample_config(algorithm_data_info_t *data_info, alg return ESP_OK; } - if ((src_fre == ALGORITHM_STREAM_DEFAULT_SAMPLE_RATE_HZ) && (src_ch == ALGORITHM_STREAM_DEFAULT_CHANNEL)) { + if ((data_info->rsp_info.src_rate == ALGORITHM_STREAM_DEFAULT_SAMPLE_RATE_HZ) && (data_info->rsp_info.src_ch == ALGORITHM_STREAM_DEFAULT_CHANNEL)) { data_info->data_need_be_resampled = false; data_info->data_need_be_divided_after_rsp = false; - } else if (src_fre == ALGORITHM_STREAM_DEFAULT_SAMPLE_RATE_HZ) { + } else if (data_info->rsp_info.src_rate == ALGORITHM_STREAM_DEFAULT_SAMPLE_RATE_HZ) { data_info->data_need_be_resampled = false; data_info->data_need_be_divided_after_rsp = true; } else { data_info->data_need_be_resampled = true; - if (src_ch == 2) { + if (data_info->rsp_info.src_ch == 2) { data_info->data_need_be_divided_after_rsp = true; - } else if (src_ch == 1) { + } else if (data_info->rsp_info.src_ch == 1) { data_info->data_need_be_divided_after_rsp = false; } else { ESP_LOGE(TAG, "The channel number should be 0 or 1"); @@ -414,114 +470,107 @@ static esp_err_t algorithm_resample_config(algorithm_data_info_t *data_info, alg return ESP_OK; } -static esp_err_t create_rsp_handle(algo_stream_t *algo, algorithm_stream_cfg_t *cfg) +static esp_err_t _esp_algorithm_resample_create(algorithm_data_info_t *info, resample_info_t *rsp_cfg, int src_rate, int src_ch, bool is_divided_after_rsp, int8_t mask) { - AUDIO_NULL_CHECK(TAG, algo, return ESP_FAIL); - AUDIO_NULL_CHECK(TAG, cfg, return ESP_FAIL); + AUDIO_NULL_CHECK(TAG, info, return ESP_FAIL); + AUDIO_NULL_CHECK(TAG, rsp_cfg, return ESP_FAIL); + + rsp_cfg->src_rate = src_rate; + rsp_cfg->dest_ch = src_ch; + rsp_cfg->src_ch = src_ch; + if (is_divided_after_rsp) { + if (mask & ALGORITHM_STREAM_USE_AEC) { + rsp_cfg->out_len_bytes = AEC_FRAME_BYTES * 2; + } else { + rsp_cfg->out_len_bytes = AGC_FRAME_BYTES * 2; + } + } else { + if (mask & ALGORITHM_STREAM_USE_AEC) { + rsp_cfg->out_len_bytes = AEC_FRAME_BYTES; + } else { + rsp_cfg->out_len_bytes = AGC_FRAME_BYTES; + } + } - algorithm_data_info_t *record = &algo->record; - algorithm_data_info_t *reference = &algo->reference; + memcpy(&info->rsp_info, rsp_cfg, sizeof(resample_info_t)); + info->rsp_handle = esp_resample_create(rsp_cfg, &info->rsp_in, &info->rsp_out); + AUDIO_NULL_CHECK(TAG, info->rsp_handle, { + ESP_LOGE(TAG, "Fail to create recorder resample handle"); + return ESP_FAIL; + }); + return ESP_OK; +} - resample_info_t rsp_cfg = { - .dest_rate = ALGORITHM_STREAM_DEFAULT_SAMPLE_RATE_HZ, - .dest_ch = ALGORITHM_STREAM_DEFAULT_CHANNEL, // The encode resample cannot process diffrent channel - .mode = RESAMPLE_ENCODE_MODE, - .sample_bits = ALGORITHM_STREAM_DEFAULT_SAMPLE_BIT, - .max_indata_bytes = ALGORITHM_STREAM_RESAMPE_DEFAULT_MAX_INPUT_SIZE, // The max input data maybe 48K 2ch --> 16k 1ch, so max_data = AEC_FRAME_BYTES * 6 - .complexity = ALGORITHM_STREAM_RESAMPE_DEFAULT_COMPLEXITY, - .type = ESP_RESAMPLE_TYPE_AUTO - }; +static esp_err_t create_record_rsp_handle(algo_stream_t *algo) +{ + AUDIO_NULL_CHECK(TAG, algo, return ESP_FAIL); + algorithm_data_info_t *record = &algo->record; - algorithm_resample_config(record, cfg->input_type, cfg->rec_sample_rate, cfg->rec_ch); - algorithm_resample_config(reference, cfg->input_type, cfg->ref_sample_rate, cfg->ref_ch); + resample_info_t rsp_cfg; + algorithm_resample_config(&rsp_cfg, record, algo->input_type); + algo->record.is_after_reset_res_info = false; if (algo->input_type == ALGORITHM_STREAM_INPUT_TYPE1) { if (record->data_need_be_resampled) { - rsp_cfg.src_rate = cfg->rec_sample_rate; - rsp_cfg.src_ch = 2; - rsp_cfg.dest_ch = 2; - rsp_cfg.out_len_bytes = AEC_FRAME_BYTES * 2; - memcpy(&record->rsp_info, &rsp_cfg, sizeof(resample_info_t)); - record->rsp_handle = esp_resample_create(&rsp_cfg, &record->rsp_in, &record->rsp_out); - AUDIO_NULL_CHECK(TAG, record->rsp_handle, { - ESP_LOGE(TAG, "Fail to create resample handle"); - return ESP_FAIL; - }); - return ESP_OK; + return _esp_algorithm_resample_create(record, &rsp_cfg, record->rsp_info.src_rate, 2, 1, ALGORITHM_STREAM_USE_AEC); } else { return ESP_OK; } } if (record->data_need_be_resampled) { - rsp_cfg.src_rate = cfg->rec_sample_rate; - rsp_cfg.dest_ch = cfg->rec_ch; - rsp_cfg.src_ch = cfg->rec_ch; - if (record->data_need_be_divided_after_rsp) { - if (cfg->algo_mask & ALGORITHM_STREAM_USE_AEC) { - rsp_cfg.out_len_bytes = AEC_FRAME_BYTES * 2; - } else { - rsp_cfg.out_len_bytes = AGC_FRAME_BYTES * 2; - } - } else { - if (cfg->algo_mask & ALGORITHM_STREAM_USE_AEC) { - rsp_cfg.out_len_bytes = AEC_FRAME_BYTES; - } else { - rsp_cfg.out_len_bytes = AGC_FRAME_BYTES; - } - } - - memcpy(&record->rsp_info, &rsp_cfg, sizeof(resample_info_t)); - record->rsp_handle = esp_resample_create(&rsp_cfg, &record->rsp_in, &record->rsp_out); - AUDIO_NULL_CHECK(TAG, record->rsp_handle, { - ESP_LOGE(TAG, "Fail to create recorder resample handle"); - return ESP_FAIL; - }); - } else { - return ESP_OK; + return _esp_algorithm_resample_create(record, &rsp_cfg, record->rsp_info.src_rate, record->rsp_info.src_ch, record->data_need_be_divided_after_rsp, algo->algo_mask); } + return ESP_OK; +} + +static esp_err_t create_reference_rsp_handle(algo_stream_t *algo) +{ + AUDIO_NULL_CHECK(TAG, algo, return ESP_FAIL); + algorithm_data_info_t *reference = &algo->reference; + + resample_info_t rsp_cfg; + algorithm_resample_config(&rsp_cfg, reference, algo->input_type); + + algo->reference.is_after_reset_res_info = false; if (reference->data_need_be_resampled) { - rsp_cfg.src_rate = cfg->ref_sample_rate; - rsp_cfg.dest_ch = cfg->ref_ch; - rsp_cfg.src_ch = cfg->ref_ch; - if (reference->data_need_be_divided_after_rsp) { - if (cfg->algo_mask & ALGORITHM_STREAM_USE_AEC) { - rsp_cfg.out_len_bytes = AEC_FRAME_BYTES * 2; - } else { - rsp_cfg.out_len_bytes = AGC_FRAME_BYTES * 2; - } - } else { - if (cfg->algo_mask & ALGORITHM_STREAM_USE_AEC) { - rsp_cfg.out_len_bytes = AEC_FRAME_BYTES; - } else { - rsp_cfg.out_len_bytes = AGC_FRAME_BYTES; - } - } - memcpy(&reference->rsp_info, &rsp_cfg, sizeof(resample_info_t)); - reference->rsp_handle = esp_resample_create(&rsp_cfg, &reference->rsp_in, &reference->rsp_out); - AUDIO_NULL_CHECK(TAG, reference->rsp_handle, { - esp_resample_destroy(record->rsp_handle); - record->rsp_handle = NULL; - ESP_LOGE(TAG, "Fail to create reference resample handle"); - return ESP_FAIL; - }); - } else { - return ESP_OK; + return _esp_algorithm_resample_create(reference, &rsp_cfg, reference->rsp_info.src_rate, reference->rsp_info.src_ch, reference->data_need_be_divided_after_rsp, algo->algo_mask); } return ESP_OK; } -esp_err_t algo_stream_set_multi_input_rb(audio_element_handle_t algo_handle, ringbuf_handle_t input_rb) +static esp_err_t destroy_record_rsp_handle(algo_stream_t *algo) { - AUDIO_NULL_CHECK(TAG, algo_handle, return ESP_FAIL); - AUDIO_NULL_CHECK(TAG, input_rb, return ESP_FAIL); + AUDIO_NULL_CHECK(TAG, algo, return ESP_FAIL); + algorithm_data_info_t *record = &algo->record; - if (rb_get_size(input_rb) < ALGORITHM_STREAM_RESAMPE_DEFAULT_MAX_INPUT_SIZE) { - ESP_LOGE(TAG, "The ringbuffer size should be better than %d", ALGORITHM_STREAM_RESAMPE_DEFAULT_MAX_INPUT_SIZE); - return ESP_FAIL; + AUDIO_NULL_CHECK(TAG, record, return ESP_FAIL); + if (record->rsp_handle != NULL) { + esp_resample_destroy(record->rsp_handle); + record->rsp_handle = NULL; + } + + return ESP_OK; +} + +static esp_err_t destroy_reference_rsp_handle(algo_stream_t *algo) +{ + AUDIO_NULL_CHECK(TAG, algo, return ESP_FAIL); + algorithm_data_info_t *reference = &algo->reference; + + AUDIO_NULL_CHECK(TAG, reference, return ESP_FAIL); + if (reference->rsp_handle != NULL) { + esp_resample_destroy(reference->rsp_handle); + reference->rsp_handle = NULL; } - return audio_element_set_multi_input_ringbuf(algo_handle, input_rb, 0); + return ESP_OK; +} + +ringbuf_handle_t algo_stream_get_multi_input_rb(audio_element_handle_t algo_handle) +{ + AUDIO_NULL_CHECK(TAG, algo_handle, return NULL); + return audio_element_get_multi_input_ringbuf(algo_handle, 0); } audio_element_handle_t algo_stream_init(algorithm_stream_cfg_t *config) @@ -568,13 +617,18 @@ audio_element_handle_t algo_stream_init(algorithm_stream_cfg_t *config) cfg.buffer_len = AEC_FRAME_BYTES; algo->input_type = config->input_type; algo->algo_mask = config->algo_mask; + algo->record.rsp_info.src_ch = config->rec_ch; + algo->record.rsp_info.src_rate = config->rec_sample_rate; + algo->reference.rsp_info.src_ch = config->ref_ch; + algo->reference.rsp_info.src_rate = config->ref_sample_rate; audio_element_handle_t el = audio_element_init(&cfg); AUDIO_NULL_CHECK(TAG, el, { audio_free(algo); return NULL; }); bool _success = true; - _success &= (create_rsp_handle(algo, config) == ESP_OK); + _success &= (create_record_rsp_handle(algo) == ESP_OK); + _success &= (create_reference_rsp_handle(algo) == ESP_OK); _success &= ((algo->scale_buff = audio_calloc(1, AEC_FRAME_BYTES + AGC_FRAME_BYTES)) != NULL); if (algo->algo_mask & ALGORITHM_STREAM_USE_AEC) { _success &= ( @@ -600,3 +654,63 @@ audio_element_handle_t algo_stream_init(algorithm_stream_cfg_t *config) audio_element_setdata(el, algo); return el; } + +esp_err_t algo_stream_set_record_rate(audio_element_handle_t algo_handle, int rec_ch, int rec_sample_rate) +{ + AUDIO_NULL_CHECK(TAG, algo_handle, return ESP_FAIL); + algo_stream_t *algo = (algo_stream_t *)audio_element_getdata(algo_handle); + + if (algo->record.rsp_info.src_ch == rec_ch + && algo->record.rsp_info.src_rate == rec_sample_rate) { + return ESP_OK; + } + + if (is_valid_algorithm_rsp_channel(rec_ch) != ESP_OK + || is_valid_algorithm_rsp_samplerate(rec_sample_rate) != ESP_OK + ) { + return ESP_ERR_INVALID_ARG; + } else { + if (algo->input_type == ALGORITHM_STREAM_INPUT_TYPE1) { + algo->reference.is_after_reset_res_info = true; + algo->reference.rsp_info.src_ch = rec_ch; + algo->reference.rsp_info.src_rate = rec_sample_rate; + } + + algo->record.is_after_reset_res_info = true; + algo->record.rsp_info.src_ch = rec_ch; + algo->record.rsp_info.src_rate = rec_sample_rate; + ESP_LOGI(TAG, "reset channel number of record signal : %d, sample rate of record signal: %d", + rec_ch, rec_sample_rate); + } + return ESP_OK; +} + +esp_err_t algo_stream_set_reference_rate(audio_element_handle_t algo_handle, int ref_ch, int ref_sample_rate) +{ + AUDIO_NULL_CHECK(TAG, algo_handle, return ESP_FAIL); + algo_stream_t *algo = (algo_stream_t *)audio_element_getdata(algo_handle); + + if (algo->reference.rsp_info.src_ch == ref_ch + && algo->reference.rsp_info.src_rate == ref_sample_rate) { + return ESP_OK; + } + + if (is_valid_algorithm_rsp_channel(ref_ch) != ESP_OK + || is_valid_algorithm_rsp_samplerate(ref_sample_rate) != ESP_OK + ) { + return ESP_ERR_INVALID_ARG; + } else { + if (algo->input_type == ALGORITHM_STREAM_INPUT_TYPE1) { + algo->record.is_after_reset_res_info = true; + algo->record.rsp_info.src_ch = ref_ch; + algo->record.rsp_info.src_rate = ref_sample_rate; + } + + algo->reference.is_after_reset_res_info = true; + algo->reference.rsp_info.src_ch = ref_ch; + algo->reference.rsp_info.src_rate = ref_sample_rate; + ESP_LOGI(TAG, "reset channel number of reference signal: %d, sample rate of reference signal %d", + ref_ch, ref_sample_rate); + } + return ESP_OK; +} diff --git a/components/audio_stream/fatfs_stream.c b/components/audio_stream/fatfs_stream.c index ee35630..752f576 100644 --- a/components/audio_stream/fatfs_stream.c +++ b/components/audio_stream/fatfs_stream.c @@ -38,6 +38,8 @@ #include "audio_element.h" #include "wav_head.h" #include "esp_log.h" +#include "unistd.h" +#include "fcntl.h" #define FILE_WAV_SUFFIX_TYPE "wav" #define FILE_OPUS_SUFFIX_TYPE "opus" @@ -58,7 +60,7 @@ typedef struct fatfs_stream { audio_stream_type_t type; int block_size; bool is_open; - FILE *file; + int file; wr_stream_type_t w_type; bool write_header; } fatfs_stream_t; @@ -109,44 +111,44 @@ static esp_err_t _fatfs_open(audio_element_handle_t self) return ESP_FAIL; } if (fatfs->type == AUDIO_STREAM_READER) { - fatfs->file = fopen(path, "r"); + fatfs->file = open(path, O_RDONLY); + if (fatfs->file == -1) { + ESP_LOGE(TAG, "Failed to open. File name: %s, error message: %s, line: %d", path, strerror(errno), __LINE__); + return ESP_FAIL; + } struct stat siz = { 0 }; stat(path, &siz); info.total_bytes = siz.st_size; - ESP_LOGI(TAG, "File size is %d byte,pos:%d", (int)siz.st_size, (int)info.byte_pos); - if (fatfs->file && (info.byte_pos > 0)) { - if (fseek(fatfs->file, info.byte_pos, SEEK_SET) != 0) { - ESP_LOGE(TAG, "Error seek file"); + ESP_LOGI(TAG, "File size: %d byte, file position: %d", (int)siz.st_size, (int)info.byte_pos); + if (info.byte_pos > 0) { + if (lseek(fatfs->file, info.byte_pos, SEEK_SET) < 0) { + ESP_LOGE(TAG, "Error seek file. Error message: %s, line: %d", strerror(errno), __LINE__); return ESP_FAIL; } } } else if (fatfs->type == AUDIO_STREAM_WRITER) { - fatfs->file = fopen(path, "w+"); + fatfs->file = open(path, O_WRONLY | O_CREAT | O_TRUNC, S_IRWXU); + if (fatfs->file == -1) { + ESP_LOGE(TAG, "Failed to open. File name: %s, error message: %s, line: %d", path, strerror(errno), __LINE__); + return ESP_FAIL; + } fatfs->w_type = get_type(path); - if (fatfs->file && STREAM_TYPE_WAV == fatfs->w_type) { + if (STREAM_TYPE_WAV == fatfs->w_type) { wav_header_t info = {0}; - fwrite(&info, 1, sizeof(wav_header_t), fatfs->file); - fsync(fileno(fatfs->file)); - } else if (fatfs->file && (STREAM_TYPE_AMR == fatfs->w_type) && (fatfs->write_header == true)) { - fwrite("#!AMR\n", 1, 6, fatfs->file); - fsync(fileno(fatfs->file)); - } else if (fatfs->file && (STREAM_TYPE_AMRWB == fatfs->w_type) && (fatfs->write_header == true)) { - fwrite("#!AMR-WB\n", 1, 9, fatfs->file); - fsync(fileno(fatfs->file)); + write(fatfs->file, &info, sizeof(wav_header_t)); + fsync(fatfs->file); + } else if ((STREAM_TYPE_AMR == fatfs->w_type) && (fatfs->write_header == true)) { + write(fatfs->file, "#!AMR\n", 6); + fsync(fatfs->file); + } else if ((STREAM_TYPE_AMRWB == fatfs->w_type) && (fatfs->write_header == true)) { + write(fatfs->file, "#!AMR-WB\n", 9); + fsync(fatfs->file); } } else { ESP_LOGE(TAG, "FATFS must be Reader or Writer"); return ESP_FAIL; } - if (fatfs->file == NULL) { - ESP_LOGE(TAG, "Failed to open file %s", path); - return ESP_FAIL; - } fatfs->is_open = true; - if (info.byte_pos && fseek(fatfs->file, info.byte_pos, SEEK_SET) != 0) { - ESP_LOGE(TAG, "Failed to seek to %d/%d", (int)info.byte_pos, (int)info.total_bytes); - return ESP_FAIL; - } int ret = audio_element_set_total_bytes(self, info.total_bytes); return ret; } @@ -158,9 +160,12 @@ static int _fatfs_read(audio_element_handle_t self, char *buffer, int len, TickT audio_element_getinfo(self, &info); ESP_LOGD(TAG, "read len=%d, pos=%d/%d", len, (int)info.byte_pos, (int)info.total_bytes); - int rlen = fread(buffer, 1, len, fatfs->file); - if (rlen <= 0) { - ESP_LOGW(TAG, "No more data,ret:%d", rlen); + /* use file descriptors to access files */ + int rlen = read(fatfs->file, buffer, len); + if (rlen == 0) { + ESP_LOGW(TAG, "No more data, ret:%d", rlen); + } else if (rlen == -1) { + ESP_LOGE(TAG, "The error is happened in reading data. Error message: %s", strerror(errno)); } else { audio_element_update_byte_pos(self, rlen); } @@ -172,12 +177,14 @@ static int _fatfs_write(audio_element_handle_t self, char *buffer, int len, Tick fatfs_stream_t *fatfs = (fatfs_stream_t *)audio_element_getdata(self); audio_element_info_t info; audio_element_getinfo(self, &info); - int wlen = fwrite(buffer, 1, len, fatfs->file); - fsync(fileno(fatfs->file)); - ESP_LOGD(TAG, "write,%d, errno:%d,pos:%d", wlen, errno, (int)info.byte_pos); + int wlen = write(fatfs->file, buffer, len); + fsync(fatfs->file); if (wlen > 0) { audio_element_update_byte_pos(self, wlen); + } if (wlen == -1) { + ESP_LOGE(TAG, "The error is happened in writing data. Error message: %s", strerror(errno)); } + return wlen; } @@ -198,26 +205,26 @@ static esp_err_t _fatfs_close(audio_element_handle_t self) fatfs_stream_t *fatfs = (fatfs_stream_t *)audio_element_getdata(self); if (AUDIO_STREAM_WRITER == fatfs->type - && fatfs->file + && (fatfs->file != -1) && STREAM_TYPE_WAV == fatfs->w_type) { wav_header_t *wav_info = (wav_header_t *) audio_malloc(sizeof(wav_header_t)); AUDIO_MEM_CHECK(TAG, wav_info, return ESP_ERR_NO_MEM); - if (fseek(fatfs->file, 0, SEEK_SET) != 0) { - ESP_LOGE(TAG, "Error seek file ,line=%d", __LINE__); + if (lseek(fatfs->file, 0, SEEK_SET) < 0) { + ESP_LOGE(TAG, "Error seek file. Error message: %s, line: %d", strerror(errno), __LINE__); } audio_element_info_t info; audio_element_getinfo(self, &info); wav_head_init(wav_info, info.sample_rates, info.bits, info.channels); wav_head_size(wav_info, (uint32_t)info.byte_pos); - fwrite(wav_info, 1, sizeof(wav_header_t), fatfs->file); - fsync(fileno(fatfs->file)); + write(fatfs->file, wav_info, sizeof(wav_header_t)); + fsync(fatfs->file); audio_free(wav_info); } if (fatfs->is_open) { - fclose(fatfs->file); + close(fatfs->file); fatfs->is_open = false; } if (AEL_STATE_PAUSED != audio_element_get_state(self)) { diff --git a/components/audio_stream/http_stream.c b/components/audio_stream/http_stream.c index 8265aac..ea62c4c 100644 --- a/components/audio_stream/http_stream.c +++ b/components/audio_stream/http_stream.c @@ -194,9 +194,11 @@ static char *_client_read_line(http_stream_t *http) if (_get_line_in_buffer(http, &line)) { return line; } + } else { + ESP_LOGD(TAG, "Finish reading data, rlen:%d", rlen); + line = NULL; } } - return line; } @@ -488,15 +490,15 @@ static esp_err_t _http_close(audio_element_handle_t self) http->is_variant_playlist = false; http->is_playlist_resolved = false; } + if (AEL_STATE_PAUSED != audio_element_get_state(self) && (errno == 0)) { + audio_element_report_pos(self); + audio_element_set_byte_pos(self, 0); + } if (http->client) { esp_http_client_close(http->client); esp_http_client_cleanup(http->client); http->client = NULL; } - if (AEL_STATE_PAUSED != audio_element_get_state(self) && (errno == 0)) { - audio_element_report_pos(self); - audio_element_set_byte_pos(self, 0); - } return ESP_OK; } @@ -568,6 +570,10 @@ static int _http_write(audio_element_handle_t self, char *buffer, int len, TickT static int _http_process(audio_element_handle_t self, char *in_buffer, int in_len) { int r_size = audio_element_input(self, in_buffer, in_len); + if (audio_element_is_stopping(self) == true) { + ESP_LOGW(TAG, "No output due to stopping"); + return AEL_IO_ABORT; + } int w_size = 0; if (r_size > 0) { if (errno != 0) { diff --git a/components/audio_stream/include/algorithm_stream.h b/components/audio_stream/include/algorithm_stream.h index 36a670f..ba47f2b 100644 --- a/components/audio_stream/include/algorithm_stream.h +++ b/components/audio_stream/include/algorithm_stream.h @@ -35,6 +35,9 @@ extern "C" { #define ALGORITHM_STREAM_TASK_PERIOD 5 #define ALGORITHM_STREAM_TASK_STACK_SIZE (5 * 1024) +#define ALGORITHM_STREAM_DEFAULT_SAMPLE_RATE_HZ 16000 //Hz +#define ALGORITHM_STREAM_DEFAULT_SAMPLE_BIT 16 +#define ALGORITHM_STREAM_DEFAULT_CHANNEL 1 /* @@ -42,42 +45,44 @@ extern "C" { // AGC: Automatic Gain Control // WWE: Wake Word Engine // NS: Noise Suppression - +-----------+ - | | - | TYPE 1 | - | | -+-----------------------------------------------+-----------+---------------------------------------------------+ -| | -| reference signal | -| +-----------+ +-----------+ +-----------\ +-----------+ +-----------+ +-----------+ | -| | | | | | \ | | | | | | | -| | I2S read |--->| Resample |--->| Data split |--->| AEC |--->| NS |--->| AGC | | -| | | | | | / | | | | | | | -| +-----------+ +-----------+ +-----------/ +------------ +-----------+ +-----------+ | -| record signal | -| | -+---------------------------------------------------------------------------------------------------------------+ - - +-----------+ - | | - | TYPE 2 | - | | -+-----------------------------------------------+-----------+---------------------------------------------------+ -| | -| | -| +-----------+ +-----------+ +-----------+ +-----------+ +-----------+ +-----------+ | -| | | | | | | | | | | | | | -| | I2S read |--->| Resample |--->| rec signal|--->| AEC |--->| NS |--->| AGC | | -| | | | | | | | | | | | | | -| +-----------+ +-----------+ +-----------+ +-----^-----+ +-----------+ +-----------+ | -| | | -| +-----------+ +-----------+ +-----------+ | | -| | | | | | | | | -| | input_rb |--->| Resample |--->| ref signal|----------+ | -| | | | | | | | -| +-----------+ +-----------+ +-----------+ | -| | -+---------------------------------------------------------------------------------------------------------------+ + + + +-----------+ + | | + | TYPE 1 | + | | + +--------------------------------------+-----------+----------------------------------------+ + | | + | reference signal | ++-----------+ | +-----------+ +-----------\ +-----------+ +-----------+ +-----------+ | +| | | | | | \ | | | | | | | +| I2S read |-------|->| Resample |--->| Data split |--->| AEC |--->| NS |--->| AGC | | +| | | | | | / | | | | | | | ++-----------+ | +-----------+ +-----------/ +------------ +-----------+ +-----------+ | + | record signal | + | | + +-------------------------------------------------------------------------------------------+ + + +-----------+ + | | + | TYPE 2 | + | | + +--------------------------------------+-----------+----------------------------------------+ + | | + | | ++-----------+ | +-----------+ +-----------+ +-----------+ +-----------+ +-----------+ | +| | | | | | | | | | | | | | +| I2S read |-------|->| Resample |--->| rec signal|--->| AEC |--->| NS |--->| AGC | | +| | | | | | | | | | | | | | ++-----------+ | +-----------+ +-----------+ +-----^-----+ +-----------+ +-----------+ | + | | | ++-----------+ | +-----------+ +-----------+ | | +| | | | | | | | | +| input_rb |-------|->| Resample |--->| ref signal|----------+ | +| | | | | | | | ++-----------+ | +-----------+ +-----------+ | + | | + +-------------------------------------------------------------------------------------------+ */ @@ -85,9 +90,10 @@ extern "C" { * @brief Two types of algorithm stream input method */ typedef enum { - ALGORITHM_STREAM_INPUT_TYPE1 = 1, /*!< Type 1 is default used by mini-board, the reference signal and the recording signal are respectively read in from the left channel and the right channel of the same I2S */ - ALGORITHM_STREAM_INPUT_TYPE2 = 2, /*!< Type 2 read in record signal from I2S and when data be written, the data should be copy as a reference signal and input to the algorithm element by using multiple input buffer. */ -} algorithm_stream_input_type_t; /*!< When use type2, you can combine arbitrarily the algorithm modules you want to use, use algo_mask parameters below to configure that. */ + ALGORITHM_STREAM_INPUT_TYPE1 = 0, /*!< Type 1 is default used by mini-board, the reference signal and the recording signal are respectively read in from the left channel and the right channel of the same I2S */ + ALGORITHM_STREAM_INPUT_TYPE2 = 1, /*!< As the simple diagram above shows, when type2 is choosen, the recording signal and reference signal should be input by users. */ +} algorithm_stream_input_type_t; /*!< The recording signal is inputted by I2S element by default, and the reference signal should be inputted to the algorithm element by using multiple input buffer. */ + /*!< When use type2, you can combine arbitrarily the algorithm modules you want to use, use algo_mask parameters below to configure that. */ /** * @brief Choose the algorithm to be used @@ -115,17 +121,17 @@ typedef struct { int8_t algo_mask; /*!< Choose algorithm to use */ } algorithm_stream_cfg_t; -#define ALGORITHM_STREAM_CFG_DEFAULT() { \ - .input_type = ALGORITHM_STREAM_INPUT_TYPE1, \ - .task_stack = ALGORITHM_STREAM_TASK_STACK_SIZE, \ - .task_prio = ALGORITHM_STREAM_TASK_PERIOD, \ - .task_core = ALGORITHM_STREAM_PINNED_TO_CORE, \ - .rec_ch = 1, \ - .ref_ch = 1, \ - .ref_sample_rate = 16000, \ - .rec_sample_rate = 16000, \ - .rec_linear_factor = 1, \ - .ref_linear_factor = 3, \ +#define ALGORITHM_STREAM_CFG_DEFAULT() { \ + .input_type = ALGORITHM_STREAM_INPUT_TYPE1, \ + .task_stack = ALGORITHM_STREAM_TASK_STACK_SIZE, \ + .task_prio = ALGORITHM_STREAM_TASK_PERIOD, \ + .task_core = ALGORITHM_STREAM_PINNED_TO_CORE, \ + .rec_ch = 1, \ + .ref_ch = 1, \ + .ref_sample_rate = 16000, \ + .rec_sample_rate = 16000, \ + .rec_linear_factor = 1, \ + .ref_linear_factor = 3, \ .algo_mask = (ALGORITHM_STREAM_USE_AEC | ALGORITHM_STREAM_USE_AGC | ALGORITHM_STREAM_USE_NS), \ } @@ -139,17 +145,42 @@ typedef struct { audio_element_handle_t algo_stream_init(algorithm_stream_cfg_t *config); /** - * @brief Set reference signal input ringbuff + * @brief Get reference signal input ringbuff * - * @note If input type2 is choosen, call this function to set ringbuffer to input reference data. + * @note If input type2 is choosen, call this function to get ringbuffer to input reference data. * * @param algo_handle Handle of algorithm stream - * @param input_rb Ringbuffer handle to be set * - * @return ESP_OK success - * ESP_FAIL fail + * @return Ringbuffer handle to get + * + */ +ringbuf_handle_t algo_stream_get_multi_input_rb(audio_element_handle_t algo_handle); + +/** + * @brief Setup record signal clock for algorithm stream, this function is only used with handle created by `algo_stream_init` + * + * @param[in] algo_handle The algorithm stream element handle + * @param[in] rec_ch Channel number of record signal + * @param[in] rec_sample_rate Sample rate of record signal + * + * @return + * - ESP_OK + * - ESP_FAIL + */ +esp_err_t algo_stream_set_record_rate(audio_element_handle_t algo_handle, int rec_ch, int rec_sample_rate); + +/** + * @brief Setup reference signal clock for algorithm stream, this function is only used with handle created by `algo_stream_init` + * + * @param[in] algo_handle The algorithm stream element handle + * @param[in] ref_ch Channel number of reference signal + * @param[in] ref_sample_rate Sample rate of reference signal + * + * @return + * - ESP_OK + * - ESP_FAIL */ -esp_err_t algo_stream_set_multi_input_rb(audio_element_handle_t algo_handle, ringbuf_handle_t input_rb); +esp_err_t algo_stream_set_reference_rate(audio_element_handle_t algo_handle, int ref_ch, int ref_sample_rate); #ifdef __cplusplus } diff --git a/components/audio_stream/include/i2s_stream.h b/components/audio_stream/include/i2s_stream.h index 1ebcb27..1559930 100644 --- a/components/audio_stream/include/i2s_stream.h +++ b/components/audio_stream/include/i2s_stream.h @@ -112,6 +112,32 @@ typedef struct { .uninstall_drv = false, \ } +#define I2S_STREAM_TX_PDM_CFG_DEFAULT() { \ + .type = AUDIO_STREAM_WRITER, \ + .i2s_config = { \ + .mode = I2S_MODE_MASTER | I2S_MODE_PDM | I2S_MODE_TX, \ + .sample_rate = 44100, \ + .bits_per_sample = I2S_BITS_PER_SAMPLE_16BIT, \ + .channel_format = I2S_CHANNEL_FMT_RIGHT_LEFT, \ + .communication_format = I2S_COMM_FORMAT_I2S_MSB, \ + .dma_buf_count = 3, \ + .dma_buf_len = 300, \ + .use_apll = true, \ + .tx_desc_auto_clear = true, \ + .fixed_mclk = 0 \ + }, \ + .i2s_port = I2S_NUM_0, \ + .use_alc = false, \ + .volume = 0, \ + .out_rb_size = I2S_STREAM_RINGBUFFER_SIZE, \ + .task_stack = I2S_STREAM_TASK_STACK, \ + .task_core = I2S_STREAM_TASK_CORE, \ + .task_prio = I2S_STREAM_TASK_PRIO, \ + .stack_in_ext = false, \ + .multi_out_num = 0, \ + .uninstall_drv = false, \ +} + /** * @brief Create a handle to an Audio Element to stream data from I2S to another Element * or get data from other elements sent to I2S, depending on the configuration of stream type diff --git a/components/audio_stream/include/tone_stream.h b/components/audio_stream/include/tone_stream.h index d09ac3e..62149f0 100644 --- a/components/audio_stream/include/tone_stream.h +++ b/components/audio_stream/include/tone_stream.h @@ -43,6 +43,7 @@ typedef struct int task_stack; /*!< Task stack size */ int task_core; /*!< Task running in core (0 or 1) */ int task_prio; /*!< Task priority (based on freeRTOS priority) */ + const char *label; /*!< Label of tone stored in flash. The default value is `flash_tone`*/ bool extern_stack; /*!< Task stack allocate on the extern ram */ bool use_delegate; /*!< Read tone partition with esp_delegate. If task stack is on extern ram, this MUST be TRUE */ } tone_stream_cfg_t; @@ -57,12 +58,13 @@ typedef struct #define TONE_STREAM_CFG_DEFAULT() \ { \ - .type = AUDIO_STREAM_NONE, \ - .buf_sz = TONE_STREAM_BUF_SIZE, \ - .out_rb_size = TONE_STREAM_RINGBUFFER_SIZE, \ - .task_stack = TONE_STREAM_TASK_STACK, \ - .task_core = TONE_STREAM_TASK_CORE, \ - .task_prio = TONE_STREAM_TASK_PRIO, \ + .type = AUDIO_STREAM_NONE, \ + .buf_sz = TONE_STREAM_BUF_SIZE, \ + .out_rb_size = TONE_STREAM_RINGBUFFER_SIZE,\ + .task_stack = TONE_STREAM_TASK_STACK, \ + .task_core = TONE_STREAM_TASK_CORE, \ + .task_prio = TONE_STREAM_TASK_PRIO, \ + .label = "flash_tone", \ .extern_stack = TONE_STREAM_EXT_STACK, \ .use_delegate = TONE_STREAM_USE_DELEGATE, \ } diff --git a/components/audio_stream/include/tts_stream.h b/components/audio_stream/include/tts_stream.h new file mode 100644 index 0000000..28525bf --- /dev/null +++ b/components/audio_stream/include/tts_stream.h @@ -0,0 +1,125 @@ +/* + * ESPRESSIF MIT License + * + * Copyright (c) 2020 + * + * Permission is hereby granted for use on all ESPRESSIF SYSTEMS products, in which case, + * it is free of charge, to any person obtaining a copy of this software and associated + * documentation files (the "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the Software is furnished + * to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all copies or + * substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + */ + +#ifndef _TTS_STREAM_H_ +#define _TTS_STREAM_H_ + +#include "audio_error.h" +#include "audio_element.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/* The speech speed speed of synthesized speech */ +typedef enum { + TTS_VOICE_SPEED_0, /* the slowest speed */ + TTS_VOICE_SPEED_1, + TTS_VOICE_SPEED_2, + TTS_VOICE_SPEED_3, + TTS_VOICE_SPEED_4, + TTS_VOICE_SPEED_5, /* the fastest speech */ + TTS_VOICE_SPEED_MAX, +} tts_voice_speed_t; + +/** + * @brief TTS Stream configurations, if any entry is zero then the configuration will be set to default values + */ +typedef struct { + audio_stream_type_t type; /*!< Stream type */ + int buf_sz; /*!< Audio Element Buffer size */ + int out_rb_size; /*!< Size of output ringbuffer */ + int task_stack; /*!< Task stack size */ + int task_core; /*!< Task running in core (0 or 1) */ + int task_prio; /*!< Task priority (based on freeRTOS priority) */ + bool ext_stack; /*!< Allocate stack on extern ram */ +} tts_stream_cfg_t; + +#define TTS_STREAM_BUF_SIZE (2048) +#define TTS_STREAM_TASK_STACK (3072) +#define TTS_STREAM_TASK_CORE (0) +#define TTS_STREAM_TASK_PRIO (4) +#define TTS_STREAM_RINGBUFFER_SIZE (8 * 1024) + +#define TTS_STREAM_CFG_DEFAULT() { \ + .type = AUDIO_STREAM_READER, \ + .buf_sz = TTS_STREAM_BUF_SIZE, \ + .out_rb_size = TTS_STREAM_RINGBUFFER_SIZE, \ + .task_stack = TTS_STREAM_TASK_STACK, \ + .task_core = TTS_STREAM_TASK_CORE, \ + .task_prio = TTS_STREAM_TASK_PRIO, \ + .ext_stack = false, \ +} + +/** + * @brief Create a handle to an Audio Element to stream data from TTS to another Element, + * the stream type only support AUDIO_STREAM_READER for now. + * + * @param config The configuration + * + * @return The Audio Element handle + */ +audio_element_handle_t tts_stream_init(tts_stream_cfg_t *config); + +/** + * @brief Set tts stream strings. + * + * @param[in] el The audio element handle + * @param[in] string The string pointer + * + * @return + * - ESP_OK + * - ESP_FAIL + */ +esp_err_t tts_stream_set_strings(audio_element_handle_t el, const char *strings); + +/** + * @brief Setting tts stream voice speed. + * + * @param[in] handle The esp_audio instance + * @param[in] speed Speed will be set. 0-5 is legal. 0 is the slowest speed. + * + * @return + * - ESP_OK + * - ESP_FAIL + */ +esp_err_t tts_stream_set_speed(audio_element_handle_t el, tts_voice_speed_t speed); + +/** + * @brief Get tts stream voice speed. + * + * @param[in] handle The esp_audio instance + * @param[in] speed Return tts stream Speed will be [0,5] + * + * @return + * - ESP_OK + * - ESP_FAIL + */ +esp_err_t tts_stream_get_speed(audio_element_handle_t el, tts_voice_speed_t *speed); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/components/audio_stream/pwm_stream.c b/components/audio_stream/pwm_stream.c index 1bd1dc7..c0f63a5 100644 --- a/components/audio_stream/pwm_stream.c +++ b/components/audio_stream/pwm_stream.c @@ -299,7 +299,7 @@ static void IRAM_ATTR timer_group_isr(void *para) static esp_err_t audio_pwm_init(const audio_pwm_config_t *cfg) { esp_err_t res = ESP_OK; - AUDIO_NULL_CHECK(TAG, cfg, return NULL); + AUDIO_NULL_CHECK(TAG, cfg, return ESP_ERR_INVALID_ARG); if (!(cfg->tg_num < TIMER_GROUP_MAX)) { ESP_LOGE(TAG, "%s:%d (%s): AUDIO PWM TIMER GROUP NUMBER IS %d AND SHOULD BE 0 OR 1", __FILENAME__, __LINE__, __FUNCTION__, cfg->tg_num); } diff --git a/components/audio_stream/tcp_client_stream.c b/components/audio_stream/tcp_client_stream.c index 250ee23..b2646b4 100644 --- a/components/audio_stream/tcp_client_stream.c +++ b/components/audio_stream/tcp_client_stream.c @@ -26,12 +26,10 @@ #include #include "lwip/sockets.h" -#include "tcpip_adapter.h" #include "esp_transport_tcp.h" #include "esp_log.h" #include "esp_err.h" #include "audio_mem.h" - #include "tcp_client_stream.h" static const char *TAG = "TCP_STREAM"; @@ -108,10 +106,8 @@ static esp_err_t _tcp_open(audio_element_handle_t self) static esp_err_t _tcp_read(audio_element_handle_t self, char *buffer, int len, TickType_t ticks_to_wait, void *context) { tcp_stream_t *tcp = (tcp_stream_t *)audio_element_getdata(self); - audio_element_info_t info = { 0 }; - int rlen = esp_transport_read(tcp->t, buffer, len, tcp->timeout_ms); - ESP_LOGD(TAG, "read len=%d, rlen=%d, pos=%d", len, rlen, (int)info.byte_pos); + ESP_LOGD(TAG, "read len=%d, rlen=%d", len, rlen); if (rlen < 0) { _get_socket_error_code_reason("TCP read", tcp->sock); return ESP_FAIL; @@ -126,13 +122,12 @@ static esp_err_t _tcp_read(audio_element_handle_t self, char *buffer, int len, T static esp_err_t _tcp_write(audio_element_handle_t self, char *buffer, int len, TickType_t ticks_to_wait, void *context) { tcp_stream_t *tcp = (tcp_stream_t *)audio_element_getdata(self); - audio_element_info_t info; int wlen = esp_transport_write(tcp->t, buffer, len, tcp->timeout_ms); if (wlen < 0) { _get_socket_error_code_reason("TCP write", tcp->sock); return ESP_FAIL; } - ESP_LOGD(TAG, "read len=%d, wlen=%d pos=%d", len, wlen, (int)info.byte_pos); + ESP_LOGD(TAG, "read len=%d, wlen=%d", len, wlen); return wlen; } diff --git a/components/audio_stream/test/fatfs_stream_test.c b/components/audio_stream/test/fatfs_stream_test.c index 6c31787..6f53dba 100644 --- a/components/audio_stream/test/fatfs_stream_test.c +++ b/components/audio_stream/test/fatfs_stream_test.c @@ -95,7 +95,7 @@ TEST_CASE("fatfs stream read write loop", "[esp-adf-stream]") esp_periph_set_handle_t set = esp_periph_set_init(&periph_cfg); TEST_ASSERT_NOT_NULL(set); - TEST_ASSERT_EQUAL(ESP_OK, audio_board_sdcard_init(set)); + TEST_ASSERT_EQUAL(ESP_OK, audio_board_sdcard_init(set, SD_MODE_1_LINE)); audio_pipeline_cfg_t pipeline_cfg = DEFAULT_AUDIO_PIPELINE_CONFIG(); pipeline = audio_pipeline_init(&pipeline_cfg); diff --git a/components/audio_stream/test/http_stream_test.c b/components/audio_stream/test/http_stream_test.c index db6a17b..d62d204 100644 --- a/components/audio_stream/test/http_stream_test.c +++ b/components/audio_stream/test/http_stream_test.c @@ -187,7 +187,7 @@ TEST_CASE("http stream read", "[esp-adf-stream]") esp_periph_set_handle_t set = esp_periph_set_init(&periph_cfg); TEST_ASSERT_NOT_NULL(set); - TEST_ASSERT_EQUAL(ESP_OK, audio_board_sdcard_init(set)); + TEST_ASSERT_EQUAL(ESP_OK, audio_board_sdcard_init(set, SD_MODE_1_LINE)); periph_wifi_cfg_t wifi_cfg = { .ssid = UNITETS_HTTP_STREAM_WIFI_SSID, @@ -280,7 +280,7 @@ TEST_CASE("http stream write", "[esp-adf-stream]") esp_periph_set_handle_t set = esp_periph_set_init(&periph_cfg); TEST_ASSERT_NOT_NULL(set); - TEST_ASSERT_EQUAL(ESP_OK, audio_board_sdcard_init(set)); + TEST_ASSERT_EQUAL(ESP_OK, audio_board_sdcard_init(set, SD_MODE_1_LINE)); periph_wifi_cfg_t wifi_cfg = { .ssid = UNITETS_HTTP_STREAM_WIFI_SSID, diff --git a/components/audio_stream/test/i2s_stream_test.c b/components/audio_stream/test/i2s_stream_test.c index 4e4c017..cebea5f 100644 --- a/components/audio_stream/test/i2s_stream_test.c +++ b/components/audio_stream/test/i2s_stream_test.c @@ -112,7 +112,7 @@ TEST_CASE("i2s_stream alc test", "[esp-adf-stream]") esp_periph_set_handle_t set = esp_periph_set_init(&periph_cfg); TEST_ASSERT_NOT_NULL(set); - TEST_ASSERT_EQUAL(ESP_OK, audio_board_sdcard_init(set)); + TEST_ASSERT_EQUAL(ESP_OK, audio_board_sdcard_init(set, SD_MODE_1_LINE)); audio_board_handle_t board_handle = audio_board_init(); TEST_ASSERT_EQUAL(ESP_OK, audio_hal_ctrl_codec(board_handle->audio_hal, AUDIO_HAL_CODEC_MODE_DECODE, AUDIO_HAL_CTRL_START)); diff --git a/components/audio_stream/test/partitions_test_tts_stream.csv b/components/audio_stream/test/partitions_test_tts_stream.csv new file mode 100644 index 0000000..199e557 --- /dev/null +++ b/components/audio_stream/test/partitions_test_tts_stream.csv @@ -0,0 +1,18 @@ + +# Special partition table for unit test app +# +# Name, Type, SubType, Offset, Size, Flags +# Note: if you change the phy_init or app partition offset, make sure to change the offset in Kconfig.projbuild +nvs, data, nvs, 0x9000, 0x6000 +phy_init, data, phy, 0xf000, 0x1000 + +# these OTA partitions are used for tests, but can't fit real OTA apps in them +# (done this way to reduce total flash usage.) +ota_0, 0, ota_0, 0x10000, 0x80000 + +# flash_test partition used for SPI flash tests, WL FAT tests, and SPIFFS tests +flash_test, data, fat, , 0x90000 + +# Note: still 1MB of a 4MB flash left free for some other purpose +voice_data, data, fat, 0x500000, 3M + diff --git a/components/audio_stream/test/tcp_client_stream_test.c b/components/audio_stream/test/tcp_client_stream_test.c index 90c91d2..c585424 100644 --- a/components/audio_stream/test/tcp_client_stream_test.c +++ b/components/audio_stream/test/tcp_client_stream_test.c @@ -84,7 +84,7 @@ TEST_CASE("tcp client stream write", "[esp-adf-stream]") esp_periph_set_handle_t set = esp_periph_set_init(&periph_cfg); TEST_ASSERT_NOT_NULL(set); - TEST_ASSERT_EQUAL(ESP_OK, audio_board_sdcard_init(set)); + TEST_ASSERT_EQUAL(ESP_OK, audio_board_sdcard_init(set, SD_MODE_1_LINE)); audio_pipeline_cfg_t pipeline_cfg = DEFAULT_AUDIO_PIPELINE_CONFIG(); pipeline = audio_pipeline_init(&pipeline_cfg); @@ -172,7 +172,7 @@ TEST_CASE("tcp client stream read", "[esp-adf-stream]") esp_periph_set_handle_t set = esp_periph_set_init(&periph_cfg); TEST_ASSERT_NOT_NULL(set); - TEST_ASSERT_EQUAL(ESP_OK, audio_board_sdcard_init(set)); + TEST_ASSERT_EQUAL(ESP_OK, audio_board_sdcard_init(set, SD_MODE_1_LINE)); audio_pipeline_cfg_t pipeline_cfg = DEFAULT_AUDIO_PIPELINE_CONFIG(); pipeline = audio_pipeline_init(&pipeline_cfg); diff --git a/components/audio_stream/test/tone_stream_test.c b/components/audio_stream/test/tone_stream_test.c index 2865ac3..0a51e5e 100644 --- a/components/audio_stream/test/tone_stream_test.c +++ b/components/audio_stream/test/tone_stream_test.c @@ -91,7 +91,7 @@ TEST_CASE("tone stream read test", "esp-adf-stream") esp_periph_set_handle_t set = esp_periph_set_init(&periph_cfg); TEST_ASSERT_NOT_NULL(set); - TEST_ASSERT_EQUAL(ESP_OK, audio_board_sdcard_init(set)); + TEST_ASSERT_EQUAL(ESP_OK, audio_board_sdcard_init(set, SD_MODE_1_LINE)); audio_pipeline_cfg_t pipeline_cfg = DEFAULT_AUDIO_PIPELINE_CONFIG(); pipeline = audio_pipeline_init(&pipeline_cfg); diff --git a/components/audio_stream/test/tts_stream_test.c b/components/audio_stream/test/tts_stream_test.c new file mode 100644 index 0000000..e7da20d --- /dev/null +++ b/components/audio_stream/test/tts_stream_test.c @@ -0,0 +1,282 @@ +/* + * ESPRESSIF MIT License + * + * Copyright (c) 2020 + * + * Permission is hereby granted for use on all ESPRESSIF SYSTEMS products, in which case, + * it is free of charge, to any person obtaining a copy of this software and associated + * documentation files (the "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the Software is furnished + * to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all copies or + * substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + */ + +#include "unity.h" +#include "esp_err.h" +#include "esp_log.h" + +#include "audio_pipeline.h" +#include "audio_mem.h" +#include "tts_stream.h" +#include "i2s_stream.h" + +#include "esp_peripherals.h" +#include "board.h" + +static void init_tts_stream_test(audio_pipeline_handle_t *pipeline, + audio_element_handle_t *tts_stream_reader, + audio_element_handle_t *i2s_stream_writer, + esp_periph_set_handle_t *set) +{ + esp_periph_config_t periph_cfg = DEFAULT_ESP_PERIPH_SET_CONFIG(); + *set = esp_periph_set_init(&periph_cfg); + TEST_ASSERT_NOT_NULL(*set); + + audio_board_handle_t board_handle = audio_board_init(); + audio_hal_ctrl_codec(board_handle->audio_hal, AUDIO_HAL_CODEC_MODE_DECODE, AUDIO_HAL_CTRL_START); + + audio_pipeline_cfg_t pipeline_cfg = DEFAULT_AUDIO_PIPELINE_CONFIG(); + *pipeline = audio_pipeline_init(&pipeline_cfg); + TEST_ASSERT_NOT_NULL(*pipeline); + + tts_stream_cfg_t tts_cfg = TTS_STREAM_CFG_DEFAULT(); + tts_cfg.type = AUDIO_STREAM_READER; + *tts_stream_reader = tts_stream_init(&tts_cfg); + TEST_ASSERT_NOT_NULL(*tts_stream_reader); + + i2s_stream_cfg_t i2s_cfg = I2S_STREAM_CFG_DEFAULT(); + i2s_cfg.type = AUDIO_STREAM_WRITER; + i2s_cfg.i2s_config.sample_rate = 16000; + i2s_cfg.i2s_config.channel_format = I2S_CHANNEL_FMT_ONLY_LEFT; + *i2s_stream_writer = i2s_stream_init(&i2s_cfg); + TEST_ASSERT_NOT_NULL(*i2s_stream_writer); + + audio_pipeline_register(*pipeline, *tts_stream_reader, "tts"); + audio_pipeline_register(*pipeline, *i2s_stream_writer, "i2s"); + const char *link_tag[2] = {"tts", "i2s"}; + audio_pipeline_link(*pipeline, &link_tag[0], 2); +} + +static void init_audio_event_test(audio_pipeline_handle_t *pipeline, + esp_periph_set_handle_t *set, + audio_event_iface_handle_t *evt) +{ + audio_event_iface_cfg_t evt_cfg = AUDIO_EVENT_IFACE_DEFAULT_CFG(); + *evt = audio_event_iface_init(&evt_cfg); + TEST_ASSERT_EQUAL(ESP_OK,audio_pipeline_set_listener(*pipeline, *evt)); + TEST_ASSERT_EQUAL(ESP_OK,audio_event_iface_set_listener(esp_periph_set_get_event_iface(*set), *evt)); + TEST_ASSERT_EQUAL(ESP_OK,audio_pipeline_run(*pipeline)); +} + +static void deinit_tts_stream_test(audio_pipeline_handle_t *pipeline, + audio_element_handle_t *tts_stream_reader, + audio_element_handle_t *i2s_stream_writer, + esp_periph_set_handle_t *set, + audio_event_iface_handle_t *evt) +{ + TEST_ASSERT_EQUAL(ESP_OK, audio_pipeline_wait_for_stop(*pipeline)); + TEST_ASSERT_EQUAL(ESP_OK,audio_pipeline_terminate(*pipeline)); + TEST_ASSERT_EQUAL(ESP_OK,audio_pipeline_unregister(*pipeline, *tts_stream_reader)); + TEST_ASSERT_EQUAL(ESP_OK,audio_pipeline_unregister(*pipeline, *i2s_stream_writer)); + TEST_ASSERT_EQUAL(ESP_OK,audio_pipeline_remove_listener(*pipeline)); + TEST_ASSERT_EQUAL(ESP_OK,esp_periph_set_stop_all(*set)); + TEST_ASSERT_EQUAL(ESP_OK,audio_event_iface_remove_listener(esp_periph_set_get_event_iface(*set), *evt)); + TEST_ASSERT_EQUAL(ESP_OK,audio_event_iface_destroy(*evt)); + TEST_ASSERT_EQUAL(ESP_OK,audio_pipeline_deinit(*pipeline)); + TEST_ASSERT_EQUAL(ESP_OK,audio_element_deinit(*tts_stream_reader)); + TEST_ASSERT_EQUAL(ESP_OK,audio_element_deinit(*i2s_stream_writer)); + TEST_ASSERT_EQUAL(ESP_OK,esp_periph_set_destroy(*set)); +} + +TEST_CASE("tts stream init and deinit memory", "[esp-adf-stream]") +{ + AUDIO_MEM_SHOW("TTS STREAM INIT AND DEINIT MEMORY"); + esp_log_level_set("AUDIO_ELEMENT", ESP_LOG_DEBUG); + audio_element_handle_t tts_stream_reader; + tts_stream_cfg_t tts_cfg = TTS_STREAM_CFG_DEFAULT(); + tts_cfg.type = AUDIO_STREAM_READER; + int cnt = 20; + AUDIO_MEM_SHOW("BEFORE TTS_STREAM_INIT MEMORY TEST"); + while (cnt--) { + tts_stream_reader = tts_stream_init(&tts_cfg); + + audio_element_deinit(tts_stream_reader); + } + AUDIO_MEM_SHOW("AFTER TTS_STREAM_INIT MEMORY TEST"); +} + +TEST_CASE("tts stream set and read strings", "[esp-adf-stream]") +{ + AUDIO_MEM_SHOW("TTS STREAM SET AND READ STRINGS"); + static const char *STRINGS = "乐鑫语音开源框架简称ADF"; + esp_log_level_set("AUDIO_ELEMENT", ESP_LOG_DEBUG); + audio_element_handle_t tts_stream_reader; + tts_stream_cfg_t tts_cfg = TTS_STREAM_CFG_DEFAULT(); + tts_cfg.type = AUDIO_STREAM_READER; + tts_stream_reader = tts_stream_init(&tts_cfg); + tts_stream_set_strings(tts_stream_reader, STRINGS); + char *uri = audio_element_get_uri(tts_stream_reader); + TEST_ASSERT_EQUAL_STRING(STRINGS, uri); + audio_element_deinit(tts_stream_reader); +} + +TEST_CASE("tts stream speed write and read test", "[esp-adf-stream]") +{ + AUDIO_MEM_SHOW("TTS STREAM SPEED WRITE AND READ TEST"); + audio_element_handle_t tts_stream_reader; + tts_voice_speed_t speed; + esp_log_level_set("AUDIO_ELEMENT", ESP_LOG_DEBUG); + tts_stream_cfg_t tts_cfg = TTS_STREAM_CFG_DEFAULT(); + tts_cfg.type = AUDIO_STREAM_READER; + tts_stream_reader = tts_stream_init(&tts_cfg); + TEST_ASSERT_NOT_NULL(tts_stream_reader); + TEST_ASSERT_EQUAL(ESP_OK, tts_stream_set_speed(tts_stream_reader, TTS_VOICE_SPEED_0)); + TEST_ASSERT_EQUAL(ESP_OK, tts_stream_get_speed(tts_stream_reader, &speed)); + TEST_ASSERT_EQUAL(TTS_VOICE_SPEED_0, speed); + TEST_ASSERT_EQUAL(ESP_OK, tts_stream_set_speed(tts_stream_reader, TTS_VOICE_SPEED_1)); + TEST_ASSERT_EQUAL(ESP_OK, tts_stream_get_speed(tts_stream_reader, &speed)); + TEST_ASSERT_EQUAL(TTS_VOICE_SPEED_1, speed); + TEST_ASSERT_EQUAL(ESP_OK, tts_stream_set_speed(tts_stream_reader, TTS_VOICE_SPEED_2)); + TEST_ASSERT_EQUAL(ESP_OK, tts_stream_get_speed(tts_stream_reader, &speed)); + TEST_ASSERT_EQUAL(TTS_VOICE_SPEED_2, speed); + TEST_ASSERT_EQUAL(ESP_OK, tts_stream_set_speed(tts_stream_reader, TTS_VOICE_SPEED_3)); + TEST_ASSERT_EQUAL(ESP_OK, tts_stream_get_speed(tts_stream_reader, &speed)); + TEST_ASSERT_EQUAL(TTS_VOICE_SPEED_3, speed); + TEST_ASSERT_EQUAL(ESP_OK, tts_stream_set_speed(tts_stream_reader, TTS_VOICE_SPEED_4)); + TEST_ASSERT_EQUAL(ESP_OK, tts_stream_get_speed(tts_stream_reader, &speed)); + TEST_ASSERT_EQUAL(TTS_VOICE_SPEED_4, speed); + TEST_ASSERT_EQUAL(ESP_OK, tts_stream_set_speed(tts_stream_reader, TTS_VOICE_SPEED_5)); + TEST_ASSERT_EQUAL(ESP_OK, tts_stream_get_speed(tts_stream_reader, &speed)); + TEST_ASSERT_EQUAL(TTS_VOICE_SPEED_5, speed); + audio_element_deinit(tts_stream_reader); +} + +TEST_CASE("tts stream play a chinese string", "[esp-adf-stream]") +{ + AUDIO_MEM_SHOW("START PLAY A CHINESE STRING TEST"); + audio_pipeline_handle_t pipeline = NULL; + audio_element_handle_t tts_stream_reader = NULL, i2s_stream_writer = NULL; + esp_periph_set_handle_t set = NULL; + audio_event_iface_handle_t evt = NULL; + + init_tts_stream_test(&pipeline, &tts_stream_reader, &i2s_stream_writer, &set); + TEST_ASSERT_EQUAL(ESP_OK, tts_stream_set_strings(tts_stream_reader, "乐鑫提供安全、稳定、节能的 AIoT 解决方案")); + init_audio_event_test(&pipeline, &set, &evt); + + while (1) { + audio_event_iface_msg_t msg; + esp_err_t ret = audio_event_iface_listen(evt, &msg, portMAX_DELAY); + if (ret != ESP_OK) { + continue; + } + /* Stop when the last pipeline element (i2s_stream_writer in this case) receives stop event */ + if (msg.source_type == AUDIO_ELEMENT_TYPE_ELEMENT && msg.source == (void *) i2s_stream_writer + && msg.cmd == AEL_MSG_CMD_REPORT_STATUS + && (((int)msg.data == AEL_STATUS_STATE_STOPPED) || ((int)msg.data == AEL_STATUS_STATE_FINISHED))) { + break; + } + } + deinit_tts_stream_test(&pipeline, &tts_stream_reader, &i2s_stream_writer, &set, &evt); +} + +TEST_CASE("tts stream play multiple strings", "[esp-adf-stream]") +{ + AUDIO_MEM_SHOW("TTS STREAM PLAY MULTIPLE STRINGS"); + static const char STRINGS[][80] = { + {"乐鑫科技是一家全球化的无晶圆厂半导体公司"}, + {"在中国、捷克、印度、新加坡和巴西均设有办公地"}, + {"团队成员来自全世界的 20 多个国家和地区"}, + } ; + + audio_pipeline_handle_t pipeline = NULL; + audio_element_handle_t tts_stream_reader = NULL, i2s_stream_writer = NULL; + esp_periph_set_handle_t set = NULL; + audio_event_iface_handle_t evt = NULL; + + init_tts_stream_test(&pipeline, &tts_stream_reader, &i2s_stream_writer, &set); + TEST_ASSERT_EQUAL(ESP_OK, tts_stream_set_strings(tts_stream_reader, STRINGS)); + init_audio_event_test(&pipeline, &set, &evt); + + int cnt = 0; + while (1){ + audio_event_iface_msg_t msg; + esp_err_t ret = audio_event_iface_listen(evt, &msg, portMAX_DELAY); + if (ret != ESP_OK) { + continue; + } + /* Stop when the last pipeline element (i2s_stream_writer in this case) receives stop event */ + if (msg.source_type == AUDIO_ELEMENT_TYPE_ELEMENT && msg.source == (void *) i2s_stream_writer + && msg.cmd == AEL_MSG_CMD_REPORT_STATUS + && (((int)msg.data == AEL_STATUS_STATE_STOPPED) || ((int)msg.data == AEL_STATUS_STATE_FINISHED))){ + cnt ++; + if(cnt < (sizeof(STRINGS)/sizeof(STRINGS[0]))){ + TEST_ASSERT_EQUAL(ESP_OK, audio_pipeline_reset_ringbuffer(pipeline)); + TEST_ASSERT_EQUAL(ESP_OK, audio_pipeline_reset_elements(pipeline)); + TEST_ASSERT_EQUAL(ESP_OK, tts_stream_set_strings(tts_stream_reader, (STRINGS + cnt))); + TEST_ASSERT_EQUAL(ESP_OK, audio_pipeline_change_state(pipeline, AEL_STATE_INIT)); + TEST_ASSERT_EQUAL(ESP_OK, audio_pipeline_run(pipeline)); + }else{ + AUDIO_MEM_SHOW("ALL PLAY FINISHED"); + break; + } + } + } + deinit_tts_stream_test(&pipeline, &tts_stream_reader, &i2s_stream_writer, &set, &evt); +} + +TEST_CASE("tts stream play-stop and start new chainese string", "[esp-adf-stream]") +{ + AUDIO_MEM_SHOW("TTS STREAM PLAY-STOP AND START NEW CHAINESE STRING"); + audio_pipeline_handle_t pipeline = NULL; + audio_element_handle_t tts_stream_reader = NULL, i2s_stream_writer = NULL; + esp_periph_set_handle_t set = NULL; + audio_event_iface_handle_t evt = NULL; + + init_tts_stream_test(&pipeline, &tts_stream_reader, &i2s_stream_writer, &set); + TEST_ASSERT_EQUAL(ESP_OK, tts_stream_set_strings(tts_stream_reader, "第一个测试的 tts 音频流")); + init_audio_event_test(&pipeline, &set, &evt); + + bool play_once_flag = true; + while (1) { + audio_event_iface_msg_t msg; + esp_err_t ret = audio_event_iface_listen(evt, &msg, portMAX_DELAY); + if (ret != ESP_OK) { + continue; + } + + if (msg.source_type == AUDIO_ELEMENT_TYPE_ELEMENT && msg.source == (void *) tts_stream_reader){ + if(((int)msg.data == AEL_STATUS_STATE_RUNNING) && (play_once_flag)){ + play_once_flag = false; + vTaskDelay(1000); + TEST_ASSERT_EQUAL(ESP_OK, audio_pipeline_stop(pipeline)); + TEST_ASSERT_EQUAL(ESP_OK, audio_pipeline_wait_for_stop(pipeline)); + TEST_ASSERT_EQUAL(ESP_OK, audio_element_reset_state(tts_stream_reader)); + TEST_ASSERT_EQUAL(ESP_OK, audio_element_reset_state(i2s_stream_writer)); + TEST_ASSERT_EQUAL(ESP_OK, audio_pipeline_reset_ringbuffer(pipeline)); + TEST_ASSERT_EQUAL(ESP_OK, audio_pipeline_reset_items_state(pipeline)); + TEST_ASSERT_EQUAL(ESP_OK, tts_stream_set_strings(tts_stream_reader, "停止第一个播放,开始第二个测试的 tts 音频播放")); + TEST_ASSERT_EQUAL(ESP_OK, audio_pipeline_run(pipeline)); + } + } + /* Stop when the last pipeline element (i2s_stream_writer in this case) receives stop event */ + if (msg.source_type == AUDIO_ELEMENT_TYPE_ELEMENT && msg.source == (void *) i2s_stream_writer + && msg.cmd == AEL_MSG_CMD_REPORT_STATUS){ + if(((int)msg.data == AEL_STATUS_STATE_STOPPED) || ((int)msg.data == AEL_STATUS_STATE_FINISHED)){ + AUDIO_MEM_SHOW("AEL_STATUS_STATE_FINISHED"); + break; + } + } + } + deinit_tts_stream_test(&pipeline, &tts_stream_reader, &i2s_stream_writer, &set, &evt); +} diff --git a/components/audio_stream/tone_stream.c b/components/audio_stream/tone_stream.c index 441b30a..109e0b4 100644 --- a/components/audio_stream/tone_stream.c +++ b/components/audio_stream/tone_stream.c @@ -44,10 +44,9 @@ typedef struct tone_stream { bool use_delegate; /*!< Tone read with delegate*/ tone_partition_handle_t tone_handle; /*!< Tone partition's operation handle*/ tone_file_info_t cur_file; /*!< Address to read tone file */ + const char *partition_label; /*!< Label of tone stored in flash */ } tone_stream_t; -static const char *partition_label = "flash_tone"; - static esp_err_t _tone_open(audio_element_handle_t self) { tone_stream_t *stream = (tone_stream_t *)audio_element_getdata(self); @@ -55,7 +54,7 @@ static esp_err_t _tone_open(audio_element_handle_t self) ESP_LOGE(TAG, "already opened"); return ESP_FAIL; } - stream->tone_handle = tone_partition_init(partition_label, stream->use_delegate); + stream->tone_handle = tone_partition_init(stream->partition_label, stream->use_delegate); if (stream->tone_handle == NULL) { return ESP_FAIL; } @@ -177,6 +176,12 @@ audio_element_handle_t tone_stream_init(tone_stream_cfg_t *config) stream->type = config->type; stream->use_delegate = config->use_delegate; + if (config->label == NULL) { + ESP_LOGE(TAG, "Please set your tone label"); + return NULL; + } else { + stream->partition_label = config->label; + } if (config->type == AUDIO_STREAM_READER) { cfg.read = _tone_read; } else if (config->type == AUDIO_STREAM_WRITER) { diff --git a/components/audio_stream/tts_stream.c b/components/audio_stream/tts_stream.c new file mode 100644 index 0000000..e5ede80 --- /dev/null +++ b/components/audio_stream/tts_stream.c @@ -0,0 +1,213 @@ +/* + * ESPRESSIF MIT License + * + * Copyright (c) 2020 + * + * Permission is hereby granted for use on all ESPRESSIF SYSTEMS products, in which case, + * it is free of charge, to any person obtaining a copy of this software and associated + * documentation files (the "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the Software is furnished + * to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all copies or + * substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + */ + +#include +#include "tts_stream.h" +#include "audio_mem.h" +#include "esp_log.h" +#include "esp_partition.h" +#include "esp_tts_voice_template.h" + +static const char *TAG = "TTS_STREAM"; + +typedef struct tts_stream { + audio_stream_type_t type; + esp_tts_voice_t *voice; + esp_tts_handle_t *tts_handle; + char *prompt; + unsigned int speed; + bool is_open; +} tts_stream_t; + +static esp_err_t _tts_stream_open(audio_element_handle_t self) +{ + tts_stream_t *tts_stream = (tts_stream_t *)audio_element_getdata(self); + + tts_stream->is_open = false; + char *uri = audio_element_get_uri(self); + if (uri == NULL) { + ESP_LOGE(TAG, "The TTS string is not set"); + return ESP_FAIL; + } + + if (esp_tts_parse_chinese(tts_stream->tts_handle, uri)) { + tts_stream->is_open = true; + ESP_LOGW(TAG, "%s", uri); + return ESP_OK; + } else { + ESP_LOGE(TAG, "The Chinese string parse failed"); + } + + return ESP_FAIL; +} + +static int _tts_stream_read(audio_element_handle_t self, char *buffer, int len, TickType_t ticks_to_wait, void *context) +{ + tts_stream_t *tts_stream = (tts_stream_t *)audio_element_getdata(self); + int rlen = 0; + uint8_t *pcm_data = (uint8_t *)esp_tts_stream_play(tts_stream->tts_handle, &rlen, tts_stream->speed); + if (rlen <= 0) { + ESP_LOGW(TAG, "No more data,ret:%d", rlen); + } else { + memcpy(buffer, pcm_data, rlen * 2); + audio_element_update_byte_pos(self, rlen * 2); + } + + return rlen * 2 ; +} + +static int _tts_stream_process(audio_element_handle_t self, char *in_buffer, int in_len) +{ + int r_size = audio_element_input(self, in_buffer, in_len); + int w_size = 0; + if (r_size > 0) { + w_size = audio_element_output(self, in_buffer, r_size); + } else { + w_size = r_size; + } + return w_size; +} + +static esp_err_t _tts_stream_close(audio_element_handle_t self) +{ + tts_stream_t *tts_stream = (tts_stream_t *)audio_element_getdata(self); + if (tts_stream->is_open) { + esp_tts_stream_reset(tts_stream->tts_handle); + tts_stream->is_open = false; + } + + return ESP_OK; +} + +static esp_err_t _tts_stream_destroy(audio_element_handle_t self) +{ + tts_stream_t *tts_stream = (tts_stream_t *)audio_element_getdata(self); + esp_tts_stream_reset(tts_stream->tts_handle); + esp_tts_voice_set_free(tts_stream->voice); + esp_tts_destroy(tts_stream->tts_handle); + audio_free(tts_stream); + + return ESP_OK; +} + +esp_err_t tts_stream_set_strings(audio_element_handle_t el, const char *strings) +{ + return audio_element_set_uri(el, strings); +} + +esp_err_t tts_stream_set_speed(audio_element_handle_t el, tts_voice_speed_t speed) +{ + if (speed > TTS_VOICE_SPEED_MAX) { + ESP_LOGE(TAG, "Invalid parameter, voice speed range is [0 - 5]"); + return ESP_FAIL; + } + tts_stream_t *tts_stream = (tts_stream_t *)audio_element_getdata(el); + tts_stream->speed = speed; + + return ESP_OK; +} + +esp_err_t tts_stream_get_speed(audio_element_handle_t el, tts_voice_speed_t *speed) +{ + if(speed == NULL){ + ESP_LOGE(TAG, "The speed parameter is NULL"); + return ESP_FAIL; + } + + tts_stream_t *tts_stream = (tts_stream_t *)audio_element_getdata(el); + *speed = tts_stream->speed; + + return ESP_OK; +} + +audio_element_handle_t tts_stream_init(tts_stream_cfg_t *config) +{ + audio_element_handle_t el; + tts_stream_t *tts_stream = audio_calloc(1, sizeof(tts_stream_t)); + + AUDIO_MEM_CHECK(TAG, tts_stream, return NULL); + + audio_element_cfg_t cfg = DEFAULT_AUDIO_ELEMENT_CONFIG(); + cfg.open = _tts_stream_open; + cfg.close = _tts_stream_close; + cfg.process = _tts_stream_process; + cfg.destroy = _tts_stream_destroy; + cfg.task_stack = config->task_stack; + cfg.task_prio = config->task_prio; + cfg.task_core = config->task_core; + cfg.out_rb_size = config->out_rb_size; + cfg.buffer_len = config->buf_sz; + cfg.stack_in_ext = config->ext_stack; + if (cfg.buffer_len == 0) { + cfg.buffer_len = TTS_STREAM_BUF_SIZE; + } + + cfg.tag = "tts"; + tts_stream->type = config->type; + + const esp_partition_t* part = esp_partition_find_first(ESP_PARTITION_TYPE_DATA, ESP_PARTITION_SUBTYPE_DATA_FAT, "voice_data"); + AUDIO_MEM_CHECK(TAG, part, { + ESP_LOGE(TAG, "Couldn't find voice data partition!"); + audio_free(tts_stream); + return NULL; + }); + + spi_flash_mmap_handle_t mmap; + uint16_t* voicedata; + esp_err_t err = esp_partition_mmap(part, 0, 3 * 1024 * 1024, SPI_FLASH_MMAP_DATA, (const void**)&voicedata, &mmap); + if (err != ESP_OK) { + ESP_LOGE(TAG, "Couldn't map voice data partition!"); + audio_free(tts_stream); + return NULL; + } + + tts_stream->voice = esp_tts_voice_set_init(&esp_tts_voice_template, voicedata); + AUDIO_MEM_CHECK(TAG, tts_stream->voice, { + ESP_LOGE(TAG, "Couldn't init tts voice set!"); + audio_free(tts_stream); + return NULL; + }); + + tts_stream->tts_handle = esp_tts_create(tts_stream->voice); + AUDIO_MEM_CHECK(TAG, tts_stream->tts_handle, { + ESP_LOGE(TAG, "Couldn't create tts voice handle!"); + esp_tts_voice_set_free(tts_stream->voice); + audio_free(tts_stream); + return NULL; + }); + + tts_stream->speed = TTS_VOICE_SPEED_3; + cfg.read = _tts_stream_read; + el = audio_element_init(&cfg); + + AUDIO_MEM_CHECK(TAG, el, goto _tts_stream_init_exit); + audio_element_setdata(el, tts_stream); + return el; + +_tts_stream_init_exit: + esp_tts_voice_set_free(tts_stream->voice); + esp_tts_destroy(tts_stream->tts_handle); + audio_free(tts_stream); + return NULL; +} diff --git a/components/battery_service/monitors/voltage_monitor.c b/components/battery_service/monitors/voltage_monitor.c index 4840790..4069bf2 100644 --- a/components/battery_service/monitors/voltage_monitor.c +++ b/components/battery_service/monitors/voltage_monitor.c @@ -168,7 +168,7 @@ vol_monitor_handle_t vol_monitor_create(vol_monitor_param_t *config) esp_err_t vol_monitor_destroy(vol_monitor_handle_t handle) { - AUDIO_NULL_CHECK(TAG, handle, return NULL); + AUDIO_NULL_CHECK(TAG, handle, return ESP_ERR_INVALID_ARG); vol_monitor_ctx_t *vol_monitor = (vol_monitor_ctx_t *)handle; if (vol_monitor->check_timer != NULL) { esp_timer_stop(vol_monitor->check_timer); @@ -200,7 +200,7 @@ esp_err_t vol_monitor_set_event_cb(vol_monitor_handle_t handle, vol_monitor_even esp_err_t vol_monitor_start_freq_report(vol_monitor_handle_t handle) { - AUDIO_NULL_CHECK(TAG, handle, return NULL); + AUDIO_NULL_CHECK(TAG, handle, return ESP_ERR_INVALID_ARG); vol_monitor_ctx_t *vol_monitor = (vol_monitor_ctx_t *)handle; esp_err_t ret = ESP_OK; mutex_lock(vol_monitor->mutex); @@ -217,7 +217,7 @@ esp_err_t vol_monitor_start_freq_report(vol_monitor_handle_t handle) esp_err_t vol_monitor_stop_freq_report(vol_monitor_handle_t handle) { - AUDIO_NULL_CHECK(TAG, handle, return NULL); + AUDIO_NULL_CHECK(TAG, handle, return ESP_ERR_INVALID_ARG); vol_monitor_ctx_t *vol_monitor = (vol_monitor_ctx_t *)handle; mutex_lock(vol_monitor->mutex); vol_monitor->report_start = 0; @@ -227,7 +227,7 @@ esp_err_t vol_monitor_stop_freq_report(vol_monitor_handle_t handle) esp_err_t vol_monitor_set_report_freq(vol_monitor_handle_t handle, int freq) { - AUDIO_NULL_CHECK(TAG, handle, return NULL); + AUDIO_NULL_CHECK(TAG, handle, return ESP_ERR_INVALID_ARG); vol_monitor_ctx_t *vol_monitor = (vol_monitor_ctx_t *)handle; mutex_lock(vol_monitor->mutex); vol_monitor->config->report_freq = freq; diff --git a/components/bluetooth_service/CMakeLists.txt b/components/bluetooth_service/CMakeLists.txt index 2d7ea9f..04ddb1c 100644 --- a/components/bluetooth_service/CMakeLists.txt +++ b/components/bluetooth_service/CMakeLists.txt @@ -1,7 +1,7 @@ set(COMPONENT_ADD_INCLUDEDIRS include) # Edit following two lines to set component requirements (see docs) -set(COMPONENT_REQUIRES bt audio_sal audio_pipeline esp_peripherals audio_stream) +set(COMPONENT_REQUIRES bt audio_sal audio_pipeline esp_peripherals audio_stream audio_hal) set(COMPONENT_PRIV_REQUIRES nvs_flash) set(COMPONENT_SRCS ./bluetooth_service.c ./bt_keycontrol.c ./a2dp_stream.c ./hfp_stream.c) diff --git a/components/bluetooth_service/a2dp_stream.c b/components/bluetooth_service/a2dp_stream.c index 7686895..06dc1b4 100644 --- a/components/bluetooth_service/a2dp_stream.c +++ b/components/bluetooth_service/a2dp_stream.c @@ -45,7 +45,17 @@ static bool avrcp_conn_state = false; static audio_stream_type_t a2d_stream_type = 0; static uint8_t trans_label = 0; +#if (ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(4, 0, 0)) +static audio_hal_handle_t audio_hal = NULL; +static bool avrcp_conn_tg_state = false; +static _lock_t g_volume_lock; +static int16_t g_volume = 0; +static bool g_volume_notify; +static void bt_avrc_tg_cb(esp_avrc_tg_cb_event_t event, esp_avrc_tg_cb_param_t *param); +#endif + static const char *audio_state_str[] = { "Suspended", "Stopped", "Started" }; +static void bt_avrc_ct_cb(esp_avrc_ct_cb_event_t event, esp_avrc_ct_cb_param_t *param); static void bt_a2d_sink_cb(esp_a2d_cb_event_t event, esp_a2d_cb_param_t *param) { @@ -209,6 +219,20 @@ audio_element_handle_t a2dp_stream_init(a2dp_stream_config_t *config) cfg.task_stack = -1; // No need task cfg.tag = "aadp"; + + esp_avrc_ct_init(); + esp_avrc_ct_register_callback(bt_avrc_ct_cb); + +#if (ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(4, 0, 0)) + if (audio_hal == NULL) { + audio_hal = config->audio_hal; + } + esp_avrc_tg_init(); + esp_avrc_tg_register_callback(bt_avrc_tg_cb); + esp_avrc_rn_evt_cap_mask_t evt_set = {0}; + esp_avrc_rn_evt_bit_mask_operation(ESP_AVRC_BIT_MASK_OP_SET, &evt_set, ESP_AVRC_RN_VOLUME_CHANGE); + esp_avrc_tg_set_rn_evt_cap(&evt_set); +#endif if (config->type == AUDIO_STREAM_READER) { // A2DP sink @@ -247,6 +271,37 @@ esp_err_t a2dp_destroy() return ESP_OK; } +#if (ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(4, 0, 0)) +static void bt_avrc_volume_set_by_controller(int16_t volume) +{ + ESP_LOGI(TAG, "Volume is set by remote controller %d%%\n", (uint32_t)volume * 100 / 0x7f); + _lock_acquire(&g_volume_lock); + g_volume = volume; + if (audio_hal) { + audio_hal_set_volume(audio_hal, g_volume); + } + _lock_release(&g_volume_lock); +} + +static void bt_avrc_volume_set_by_local(int16_t volume) +{ + ESP_LOGI(TAG, "Volume is set locally to: %d%%", (uint32_t)volume * 100 / 0x7f); + _lock_acquire(&g_volume_lock); + g_volume = volume; + _lock_release(&g_volume_lock); + + if (g_volume_notify) { + esp_avrc_rn_param_t rn_param; + rn_param.volume = g_volume; + esp_avrc_tg_send_rn_rsp(ESP_AVRC_RN_VOLUME_CHANGE, ESP_AVRC_RN_RSP_CHANGED, &rn_param); + if (audio_hal) { + audio_hal_set_volume(audio_hal, g_volume); + } + g_volume_notify = false; + } +} +#endif + static void bt_avrc_ct_cb(esp_avrc_ct_cb_event_t event, esp_avrc_ct_cb_param_t *p_param) { esp_avrc_ct_cb_param_t *rc = p_param; @@ -297,10 +352,51 @@ static void bt_avrc_ct_cb(esp_avrc_ct_cb_event_t event, esp_avrc_ct_cb_param_t * } } -static esp_err_t _bt_avrc_periph_init(esp_periph_handle_t periph) +#if (ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(4, 0, 0)) +static void bt_avrc_tg_cb(esp_avrc_tg_cb_event_t event, esp_avrc_tg_cb_param_t *param) { - esp_avrc_ct_init(); - esp_avrc_ct_register_callback(bt_avrc_ct_cb); + ESP_LOGD(TAG, "%s evt %d", __func__, event); + esp_avrc_tg_cb_param_t *rc = (esp_avrc_tg_cb_param_t *)(param); + switch (event) { + case ESP_AVRC_TG_CONNECTION_STATE_EVT: { + uint8_t *bda = rc->conn_stat.remote_bda; + ESP_LOGI(TAG, "AVRC conn_state evt: state %d, [%02x:%02x:%02x:%02x:%02x:%02x]", + rc->conn_stat.connected, bda[0], bda[1], bda[2], bda[3], bda[4], bda[5]); + avrcp_conn_tg_state = rc->conn_stat.connected; + break; + } + case ESP_AVRC_TG_PASSTHROUGH_CMD_EVT: { + ESP_LOGI(TAG, "AVRC passthrough cmd: key_code 0x%x, key_state %d", rc->psth_cmd.key_code, rc->psth_cmd.key_state); + break; + } + case ESP_AVRC_TG_SET_ABSOLUTE_VOLUME_CMD_EVT: { + ESP_LOGI(TAG, "AVRC set absolute volume: %d%%", (int)rc->set_abs_vol.volume * 100/ 0x7f); + bt_avrc_volume_set_by_controller(rc->set_abs_vol.volume); + break; + } + case ESP_AVRC_TG_REGISTER_NOTIFICATION_EVT: { + ESP_LOGI(TAG, "AVRC register event notification: %d, param: 0x%x", rc->reg_ntf.event_id, rc->reg_ntf.event_parameter); + if (rc->reg_ntf.event_id == ESP_AVRC_RN_VOLUME_CHANGE) { + g_volume_notify = true; + esp_avrc_rn_param_t rn_param; + rn_param.volume = g_volume; + esp_avrc_tg_send_rn_rsp(ESP_AVRC_RN_VOLUME_CHANGE, ESP_AVRC_RN_RSP_INTERIM, &rn_param); + } + break; + } + case ESP_AVRC_TG_REMOTE_FEATURES_EVT: { + ESP_LOGI(TAG, "AVRC remote features %x, CT features %x", rc->rmt_feats.feat_mask, rc->rmt_feats.ct_feat_flag); + break; + } + default: + ESP_LOGE(TAG, "%s unhandled evt %d", __func__, event); + break; + } +} +#endif + +static esp_err_t _bt_avrc_periph_init(esp_periph_handle_t periph) +{ return ESP_OK; } @@ -331,6 +427,20 @@ static esp_err_t periph_bt_avrc_passthrough_cmd(esp_periph_handle_t periph, uint { esp_err_t err = ESP_OK; +#if (ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(4, 0, 0)) + if(avrcp_conn_tg_state) { + if (cmd == ESP_AVRC_PT_CMD_VOL_DOWN) { + int16_t volume = (g_volume - 5) < 0 ? 0 : (g_volume - 5); + bt_avrc_volume_set_by_local(volume); + return err; + } else if (cmd == ESP_AVRC_PT_CMD_VOL_UP) { + int16_t volume = (g_volume + 5) > 0x7f ? 0x7f : (g_volume + 5); + bt_avrc_volume_set_by_local(volume); + return err; + } + } +#endif + if (avrcp_conn_state) { bt_key_act_param_t param; memset(¶m, 0, sizeof(bt_key_act_param_t)); @@ -405,4 +515,16 @@ esp_err_t periph_bt_discover(esp_periph_handle_t periph) return ESP_OK; } +#if (ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(4, 0, 0)) +esp_err_t periph_bt_volume_up(esp_periph_handle_t periph) +{ + return periph_bt_avrc_passthrough_cmd(periph, ESP_AVRC_PT_CMD_VOL_UP); +} + +esp_err_t periph_bt_volume_down(esp_periph_handle_t periph) +{ + return periph_bt_avrc_passthrough_cmd(periph, ESP_AVRC_PT_CMD_VOL_DOWN); +} +#endif + #endif diff --git a/components/bluetooth_service/bluetooth_service.c b/components/bluetooth_service/bluetooth_service.c index 6c0decf..d3c7bfa 100644 --- a/components/bluetooth_service/bluetooth_service.c +++ b/components/bluetooth_service/bluetooth_service.c @@ -35,7 +35,7 @@ #if __has_include("esp_idf_version.h") #include "esp_idf_version.h" #else -#define ESP_IDF_VERSION_VAL(major, minor, patch) 0 +#define ESP_IDF_VERSION_VAL(major, minor, patch) 1 #endif #if CONFIG_BT_ENABLED @@ -84,10 +84,10 @@ typedef struct bluetooth_service { uint64_t pos; uint8_t tl; bool avrc_connected; + int a2dp_sample_rate; } bluetooth_service_t; bluetooth_service_t *g_bt_service = NULL; -int a2dp_sample_rate = 44100; static const char *conn_state_str[] = { "Disconnected", "Connecting", "Connected", "Disconnecting" }; static const char *audio_state_str[] = { "Suspended", "Stopped", "Started" }; @@ -159,7 +159,7 @@ static void bt_a2d_sink_cb(esp_a2d_cb_event_t event, esp_a2d_cb_param_t *p_param } else if (oct0 & (0x01 << 4)) { sample_rate = 48000; } - a2dp_sample_rate = sample_rate; + g_bt_service->a2dp_sample_rate = sample_rate; ESP_LOGD(TAG, "Bluetooth configured, sample rate=%d", sample_rate); if (g_bt_service->stream == NULL) { break; @@ -373,7 +373,7 @@ static void bt_a2d_source_cb(esp_a2d_cb_event_t event, esp_a2d_cb_param_t *param if (param->conn_stat.state == ESP_A2D_CONNECTION_STATE_CONNECTED) { ESP_LOGI(TAG, "a2dp connected"); g_bt_service->source_a2d_state = BT_SOURCE_STATE_CONNECTED; -#if (ESP_IDF_VERSION > ESP_IDF_VERSION_VAL(3, 3, 2)) +#if (ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(4, 0, 0)) esp_bt_gap_set_scan_mode(ESP_BT_NON_CONNECTABLE, ESP_BT_NON_DISCOVERABLE); #else esp_bt_gap_set_scan_mode(ESP_BT_SCAN_MODE_NONE); @@ -433,7 +433,7 @@ esp_err_t bluetooth_service_start(bluetooth_service_cfg_t *config) return ESP_FAIL; } - if (esp_bt_controller_enable(ESP_BT_MODE_CLASSIC_BT) != ESP_OK) { + if (esp_bt_controller_enable(ESP_BT_MODE_BTDM) != ESP_OK) { AUDIO_ERROR(TAG, "enable controller failed"); return ESP_FAIL; } @@ -492,12 +492,13 @@ esp_err_t bluetooth_service_start(bluetooth_service_cfg_t *config) } /* set discoverable and connectable mode */ -#if (ESP_IDF_VERSION > ESP_IDF_VERSION_VAL(3, 3, 2)) +#if (ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(4, 0, 0)) esp_bt_gap_set_scan_mode(ESP_BT_CONNECTABLE, ESP_BT_GENERAL_DISCOVERABLE); #else esp_bt_gap_set_scan_mode(ESP_BT_SCAN_MODE_CONNECTABLE_DISCOVERABLE); #endif + g_bt_service->a2dp_sample_rate = 44100; return ESP_OK; } @@ -596,7 +597,7 @@ static void bt_avrc_ct_cb(esp_avrc_ct_cb_event_t event, esp_avrc_ct_cb_param_t * break; } -#if (ESP_IDF_VERSION > ESP_IDF_VERSION_VAL(3, 3, 2)) +#if (ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(4, 0, 0)) case ESP_AVRC_CT_GET_RN_CAPABILITIES_RSP_EVT: { ESP_LOGD(TAG, "remote rn_cap: count %d, bitmask 0x%x", rc->get_rn_caps_rsp.cap_count, rc->get_rn_caps_rsp.evt_set.bits); @@ -631,6 +632,7 @@ static esp_err_t _bt_periph_destroy(esp_periph_handle_t periph) esp_periph_handle_t bluetooth_service_create_periph() { + AUDIO_NULL_CHECK(TAG, g_bt_service, return NULL); if (g_bt_service && g_bt_service->periph) { ESP_LOGE(TAG, "Bluetooth periph have been created"); return NULL; @@ -665,6 +667,7 @@ static esp_err_t periph_bluetooth_passthrough_cmd(esp_periph_handle_t periph, ui esp_err_t periph_bluetooth_play(esp_periph_handle_t periph) { + AUDIO_NULL_CHECK(TAG, g_bt_service, return ESP_FAIL); esp_err_t err = ESP_OK; if (g_bt_service->stream_type == AUDIO_STREAM_READER) { err = periph_bluetooth_passthrough_cmd(periph, ESP_AVRC_PT_CMD_PLAY); @@ -676,6 +679,7 @@ esp_err_t periph_bluetooth_play(esp_periph_handle_t periph) esp_err_t periph_bluetooth_pause(esp_periph_handle_t periph) { + AUDIO_NULL_CHECK(TAG, g_bt_service, return ESP_FAIL); esp_err_t err = ESP_OK; if (g_bt_service->stream_type == AUDIO_STREAM_READER) { err = periph_bluetooth_passthrough_cmd(periph, ESP_AVRC_PT_CMD_PAUSE); @@ -687,6 +691,7 @@ esp_err_t periph_bluetooth_pause(esp_periph_handle_t periph) esp_err_t periph_bluetooth_stop(esp_periph_handle_t periph) { + AUDIO_NULL_CHECK(TAG, g_bt_service, return ESP_FAIL); esp_err_t err = ESP_OK; if (g_bt_service->stream_type == AUDIO_STREAM_READER) { err = periph_bluetooth_passthrough_cmd(periph, ESP_AVRC_PT_CMD_STOP); @@ -719,6 +724,7 @@ esp_err_t periph_bluetooth_fast_forward(esp_periph_handle_t periph) esp_err_t periph_bluetooth_discover(esp_periph_handle_t periph) { + AUDIO_NULL_CHECK(TAG, g_bt_service, return ESP_FAIL); if (g_bt_service->stream_type == AUDIO_STREAM_READER) { return esp_bt_gap_start_discovery(ESP_BT_INQ_MODE_GENERAL_INQUIRY, 10, 0); } @@ -727,6 +733,7 @@ esp_err_t periph_bluetooth_discover(esp_periph_handle_t periph) esp_err_t periph_bluetooth_cancel_discover(esp_periph_handle_t periph) { + AUDIO_NULL_CHECK(TAG, g_bt_service, return ESP_FAIL); if (g_bt_service->stream_type == AUDIO_STREAM_READER) { g_bt_service->source_a2d_state = BT_SOURCE_STATE_IDLE; return esp_bt_gap_cancel_discovery(); @@ -736,6 +743,7 @@ esp_err_t periph_bluetooth_cancel_discover(esp_periph_handle_t periph) esp_err_t periph_bluetooth_connect(esp_periph_handle_t periph, bluetooth_addr_t remote_bda) { + AUDIO_NULL_CHECK(TAG, g_bt_service, return ESP_FAIL); if (g_bt_service->stream_type == AUDIO_STREAM_READER) { g_bt_service->source_a2d_state = BT_SOURCE_STATE_DISCOVERED; memcpy(&g_bt_service->remote_bda, remote_bda, BLUETOOTH_ADDR_LEN); @@ -745,4 +753,10 @@ esp_err_t periph_bluetooth_connect(esp_periph_handle_t periph, bluetooth_addr_t return ESP_OK; } +int periph_bluetooth_get_a2dp_sample_rate() +{ + AUDIO_NULL_CHECK(TAG, g_bt_service, return -1); + return g_bt_service->a2dp_sample_rate; +} + #endif diff --git a/components/bluetooth_service/hfp_stream.c b/components/bluetooth_service/hfp_stream.c index 3a57019..331e16a 100644 --- a/components/bluetooth_service/hfp_stream.c +++ b/components/bluetooth_service/hfp_stream.c @@ -34,10 +34,10 @@ #if CONFIG_BT_ENABLED static const char *TAG = "HFP_STREAM"; -#define ESP_HFP_RINGBUF_SIZE 3600 +#define ESP_HFP_RINGBUF_SIZE 3600 #define ESP_HFP_TASK_SIZE 2048 #define ESP_HFP_TASK_PRIORITY 23 -static uint32_t control_num = 0; +static bool is_get_data = true; static hfp_stream_user_callback_t hfp_stream_user_callback; static audio_element_handle_t hfp_incoming_stream = NULL; static audio_element_handle_t hfp_outgoing_stream = NULL; @@ -196,12 +196,17 @@ esp_err_t hfp_open_and_close_evt_cb_register(esp_hf_audio_open_t open_cb, esp_hf static uint32_t bt_app_hf_client_outgoing_cb(uint8_t *p_buf, uint32_t sz) { int out_len_bytes = 0; - out_len_bytes = audio_element_input(hfp_outgoing_stream, (char *)p_buf, sz); - if (out_len_bytes == sz) { - return sz; - } else { - return 0; - } + if (is_get_data) { + out_len_bytes = audio_element_input(hfp_outgoing_stream, (char *)p_buf, sz); + } + + if (out_len_bytes == sz) { + is_get_data = false; + return sz; + } else { + is_get_data = true; + return 0; + } } static void bt_app_hf_client_incoming_cb(const uint8_t *buf, uint32_t sz) @@ -209,15 +214,9 @@ static void bt_app_hf_client_incoming_cb(const uint8_t *buf, uint32_t sz) if (hfp_incoming_stream) { if (audio_element_get_state(hfp_incoming_stream) == AEL_STATE_RUNNING) { audio_element_output(hfp_incoming_stream, (char *)buf, sz); + esp_hf_client_outgoing_data_ready(); } } - - if (control_num < 5) { - control_num ++; - }else { - control_num = 0; - esp_hf_client_outgoing_data_ready(); - } } /* callback for HF_CLIENT */ void bt_hf_client_cb(esp_hf_client_cb_event_t event, esp_hf_client_cb_param_t *param) diff --git a/components/bluetooth_service/include/a2dp_stream.h b/components/bluetooth_service/include/a2dp_stream.h index f8fe6ba..6023465 100755 --- a/components/bluetooth_service/include/a2dp_stream.h +++ b/components/bluetooth_service/include/a2dp_stream.h @@ -27,7 +27,7 @@ #include "audio_error.h" #include "audio_element.h" - +#include "audio_hal.h" #ifdef __cplusplus extern "C" { @@ -42,6 +42,12 @@ extern "C" { #include "esp_avrc_api.h" #include "bt_keycontrol.h" +#if __has_include("esp_idf_version.h") +#include "esp_idf_version.h" +#else +#define ESP_IDF_VERSION_VAL(major, minor, patch) 1 +#endif + typedef struct { esp_a2d_cb_t user_a2d_cb; esp_a2d_sink_data_cb_t user_a2d_sink_data_cb; @@ -51,6 +57,9 @@ typedef struct { typedef struct { audio_stream_type_t type; a2dp_stream_user_callback_t user_callback; +#if (ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(4, 0, 0)) + audio_hal_handle_t audio_hal; +#endif } a2dp_stream_config_t; /** @@ -170,6 +179,29 @@ esp_err_t periph_bt_avrc_fast_forward(esp_periph_handle_t periph); * - ESP_FAIL: others */ esp_err_t periph_bt_discover(esp_periph_handle_t periph); +#if (ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(4, 0, 0)) +/** + * @brief Send the AVRC passthrough command (VOL_UP) to the Bluetooth device + * + * @param[in] periph The periph + * + * @return + * - ESP_OK + * - ESP_FAIL + */ +esp_err_t periph_bt_volume_up(esp_periph_handle_t periph); + +/** + * @brief Send the AVRC passthrough command (VOL_DOWN) to the Bluetooth device + * + * @param[in] periph The periph + * + * @return + * - ESP_OK + * - ESP_FAIL + */ +esp_err_t periph_bt_volume_down(esp_periph_handle_t periph); +#endif #endif diff --git a/components/bluetooth_service/include/bluetooth_service.h b/components/bluetooth_service/include/bluetooth_service.h index 72d9af3..d80ea19 100644 --- a/components/bluetooth_service/include/bluetooth_service.h +++ b/components/bluetooth_service/include/bluetooth_service.h @@ -35,6 +35,8 @@ extern "C" { #endif +#define ESP_A2DP_SAMPLE_RATE 44100 + /** * brief Bluetooth service working mode */ @@ -214,6 +216,14 @@ esp_err_t periph_bluetooth_connect(esp_periph_handle_t periph, bluetooth_addr_t */ esp_err_t bluetooth_service_destroy(); +/** + * @brief Get a2dp sample rate. + * + * @return + * - sample rate + */ +int periph_bluetooth_get_a2dp_sample_rate(); + #ifdef __cplusplus } #endif diff --git a/components/clouds/dueros/lightduer/include/baidu_json.h b/components/clouds/dueros/lightduer/include/baidu_json.h index a2d536b..3993085 100755 --- a/components/clouds/dueros/lightduer/include/baidu_json.h +++ b/components/clouds/dueros/lightduer/include/baidu_json.h @@ -73,7 +73,7 @@ typedef struct baidu_json_Hooks /* Supply malloc, realloc and free functions to baidu_json */ extern void baidu_json_InitHooks(baidu_json_Hooks* hooks); - +extern int baidu_json_Uninit(void); /* Supply a block of JSON, and this returns a baidu_json object you can interrogate. Call baidu_json_Delete when finished. */ extern baidu_json *baidu_json_Parse(const char *value); @@ -102,7 +102,8 @@ extern baidu_json *baidu_json_CreateTrue(void); extern baidu_json *baidu_json_CreateFalse(void); extern baidu_json *baidu_json_CreateBool(int b); extern baidu_json *baidu_json_CreateNumber(double num); -extern baidu_json *baidu_json_CreateString(const char *string); +// len indicate the length of string, if len <=0, the length will be got throuth strlen(string) +extern baidu_json *baidu_json_CreateString(const char *string, size_t len); extern baidu_json *baidu_json_CreateArray(void); extern baidu_json *baidu_json_CreateObject(void); @@ -151,7 +152,17 @@ extern void baidu_json_release(void *ptr); #define baidu_json_AddFalseToObject(object,name) baidu_json_AddItemToObject(object, name, baidu_json_CreateFalse()) #define baidu_json_AddBoolToObject(object,name,b) baidu_json_AddItemToObject(object, name, baidu_json_CreateBool(b)) #define baidu_json_AddNumberToObject(object,name,n) baidu_json_AddItemToObject(object, name, baidu_json_CreateNumber(n)) -#define baidu_json_AddStringToObject(object,name,s) baidu_json_AddItemToObject(object, name, baidu_json_CreateString(s)) +#define baidu_json_AddStringToObject(object,name,s) baidu_json_AddItemToObject(object, name, baidu_json_CreateString(s, 0)) +#define baidu_json_AddStringToObjectWithLength(object,name,s,len) baidu_json_AddItemToObject(object, name, baidu_json_CreateString(s, len)) + +/* Use this when string is definitely const (i.e. a literal, or as good as), and will definitely survive the baidu_json object */ +#define baidu_json_AddNullToObjectCS(object,name) baidu_json_AddItemToObjectCS(object, name, baidu_json_CreateNull()) +#define baidu_json_AddTrueToObjectCS(object,name) baidu_json_AddItemToObjectCS(object, name, baidu_json_CreateTrue()) +#define baidu_json_AddFalseToObjectCS(object,name) baidu_json_AddItemToObjectCS(object, name, baidu_json_CreateFalse()) +#define baidu_json_AddBoolToObjectCS(object,name,b) baidu_json_AddItemToObjectCS(object, name, baidu_json_CreateBool(b)) +#define baidu_json_AddNumberToObjectCS(object,name,n) baidu_json_AddItemToObjectCS(object, name, baidu_json_CreateNumber(n)) +#define baidu_json_AddStringToObjectCS(object,name,s) baidu_json_AddItemToObjectCS(object, name, baidu_json_CreateString(s, 0)) +#define baidu_json_AddStringToObjectCSWithLength(object,name,s,len) baidu_json_AddItemToObjectCS(object, name, baidu_json_CreateString(s, len)) /* When assigning an integer value, it needs to be propagated to valuedouble too. */ #define baidu_json_SetIntValue(object,val) ((object) ? (object)->valueint = (object)->valuedouble = (val) : (val)) diff --git a/components/clouds/dueros/lightduer/include/device_vad.h b/components/clouds/dueros/lightduer/include/device_vad.h new file mode 100755 index 0000000..39bdb8b --- /dev/null +++ b/components/clouds/dueros/lightduer/include/device_vad.h @@ -0,0 +1,52 @@ +#ifndef DUER_DEVICE_VAD_H +#define DUER_DEVICE_VAD_H + +#ifdef __cplusplus +extern "C" { +#endif + +// Copyright 2017 Baidu Inc. All Rights Reserved. +// Author: liuzhiyu (liuzhiyu04@baidu.com) +// +// device vad + +// default , do not modify +#define SAMPLE_RATE (16000) +#define VAD_10MS_SIZE (SAMPLE_RATE/100*2) +#define VAD_20MS_SIZE (SAMPLE_RATE/100*4) +#define VAD_FRAME_MS (80) // 80ms +#define VAD_INPUT_MS (20) // 20ms +#define VAD_CACHE_SIZE (VAD_FRAME_MS/VAD_INPUT_MS) +#define VAD_VOICE_NUM_IN_FRAME (2) // if a frame which is 80ms len, have >= 20ms voice, detect speaking +// can change +#define VAD_IGNORE_HOTWORD_TIME (2 * VAD_FRAME_MS) // 2*80 ms +#define VAD_SPEAKING_SILENCE_VALID_TIME (6 * VAD_FRAME_MS) // 6*80 ms +#define VAD_VOICE_VALID_TIME (5 * VAD_FRAME_MS) // 5*80 ms + +// human stop speak +int vad_stop_speak(void); + +void vad_stop_speak_done(void); + +// human start speak +int vad_start_speak(void); + +void vad_start_speak_done(void); + +// run vad state machine +int device_vad(char *buff, size_t length); + +// when wakeup use this function +void vad_set_wakeup(void); + +// when cloud vad work, use this function +void vad_set_playing(void); + +// ms recommendation is a multiple of VAD_FRAME_MS +void vad_set_silence_valid_time(unsigned int ms); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/components/clouds/dueros/lightduer/include/lightduer_2nd_wakeup.h b/components/clouds/dueros/lightduer/include/lightduer_2nd_wakeup.h new file mode 100755 index 0000000..d887a76 --- /dev/null +++ b/components/clouds/dueros/lightduer/include/lightduer_2nd_wakeup.h @@ -0,0 +1,61 @@ +/** + * Copyright (2017) Baidu Inc. All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/** + * File: lightduer_2nd_wakeup.h + * Auth: Sijun Li (lisijun@baidu.com) + * Desc: apply APIs to support cloud second wakeup. + */ +#ifndef BAIDU_DUER_LIGHTDUER_2ND_WAKEUP_H +#define BAIDU_DUER_LIGHTDUER_2ND_WAKEUP_H + +#ifdef __cplusplus +extern "C" { +#endif + +#ifdef DUER_SECOND_WAKEUP_ENABLE +/* + * Define type of callback of second wakeup directive. + * + * @param is_wakeup: Success: > 0 + * Failed: <= 0 + * + * @return void + */ +typedef void (*duer_on_2nd_wakeup_handler)(int is_wakeup); + +/* + * Initialize second wakeup feature. + * + * @param handler: callback of second wakeup directive. + * + * @return: DUER_OK if successful, else failed. + */ +duer_status_t duer_2nd_wakeup_init(void); + +/* + * Set callback to get second wakeup result. + * + * @param handler, the point of handler defined by user. + */ +void duer_2nd_wakeup_set_handler(duer_on_2nd_wakeup_handler handler); +#endif//DUER_SECOND_WAKEUP_ENABLE + +#ifdef __cplusplus +} +#endif + +#endif/*BAIDU_DUER_LIGHTDUER_2ND_WAKEUP_H*/ + diff --git a/components/clouds/dueros/lightduer/include/lightduer_aes.h b/components/clouds/dueros/lightduer/include/lightduer_aes.h new file mode 100755 index 0000000..4ce0989 --- /dev/null +++ b/components/clouds/dueros/lightduer/include/lightduer_aes.h @@ -0,0 +1,93 @@ +/** + * Copyright (2017) Baidu Inc. All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/** + * File: lightduer_aes.h + * Auth: Leliang Zhang(zhangleliang@baidu.com) + * Desc: Provide the aes encryption(only CBC mode support now). + */ + +#ifndef BAIDU_DUER_LIGHTDUER_AES_H +#define BAIDU_DUER_LIGHTDUER_AES_H + +#include "lightduer_types.h" + +#ifdef __cplusplus +extern "C" { +#endif + +// aes context, real type depend on the implementation +typedef void *duer_aes_context; + +// get the initialized aes context +duer_aes_context duer_aes_context_init(void); + +/* + *set the key used in the encryption and decryption + *@param ctx, got from duer_aes_context_init + *@param key, the key will be used, + *@param keybits, the length of @key in bits, should be one of 128, 192, 256 + *@return, DUER_OK on success, or other error code + */ +int duer_aes_setkey(duer_aes_context ctx, + const unsigned char *key, + unsigned int keybits); + +/* + *set the iv used in the encryption and decryption + *@param ctx, got from duer_aes_context_init + *@param iv, the iv will be used, it's 16 bytes length. + *@return, DUER_OK on success, or other error code + */ +int duer_aes_setiv(duer_aes_context ctx, unsigned char iv[16]); + +/* + *encrypt the input info, use the key/iv from @duer_aes_setkey and @duer_aes_setiv + *@param ctx, got from duer_aes_context_init + *@param length, the length of the input, should be multiple of 16 + *@param input, the content will be encrypted + *#param output, the encrypted content + *@return, DUER_OK on success, or other error code + */ +int duer_aes_cbc_encrypt(duer_aes_context ctx, + size_t length, + const unsigned char* input, + unsigned char* output); + +/* + *decrypt the input info, use the key/iv from @duer_aes_setkey and @duer_aes_setiv + *@param ctx, got from duer_aes_context_init + *@param length, the length of the input, should be multiple of 16 + *@param input, the content will be decrypted + *#param output, the decrypted content + *@return, DUER_OK on success, or other error code + */ +int duer_aes_cbc_decrypt(duer_aes_context ctx, + size_t length, + const unsigned char* input, + unsigned char* output); + +/* + *destroy the context + *@param ctx, got from duer_aes_context_init + *@return, DUER_OK on success, or other error code + */ +int duer_aes_context_destroy(duer_aes_context ctx); + +#ifdef __cplusplus +} +#endif + +#endif/*BAIDU_DUER_LIGHTDUER_AES_H*/ diff --git a/components/clouds/dueros/lightduer/include/lightduer_ap_info.h b/components/clouds/dueros/lightduer/include/lightduer_ap_info.h new file mode 100755 index 0000000..b8e1768 --- /dev/null +++ b/components/clouds/dueros/lightduer/include/lightduer_ap_info.h @@ -0,0 +1,54 @@ +/** + * Copyright (2017) Baidu Inc. All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +// Author: Gang Chen (chengang12@baidu.com) +// +// Description: The AP information APIs. + +#ifndef BAIDU_IOT_TINYDU_IOT_OS_SRC_IOT_BAIDU_CA_SOURCE_BAIDU_CA_AP_INFO_H +#define BAIDU_IOT_TINYDU_IOT_OS_SRC_IOT_BAIDU_CA_SOURCE_BAIDU_CA_AP_INFO_H + +#include "lightduer_types.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/* + * Obtain the wifi signal status + * + * @Return duer_status_t: + * DUER_OK, DUER_ERR_FAILED, DUER_ERR_WIFI_SIGNAL_WEAK OR DUER_ERR_WIFI_DISCONNECTED + */ +DUER_INT duer_status_t duer_wifi_status_get(void); + +/* + * The wifi signal status callbacks + * Return the wifi signal status + */ +typedef duer_status_t (*duer_get_wifi_status_f)(); + +/* + * Initial the AP information callbacks for Baidu CA + * + * @Param f_wifi_status, in, the function obtain the wifi signal status + */ +DUER_EXT void baidu_ca_ap_info_init(duer_get_wifi_status_f f_wifi_status); + +#ifdef __cplusplus +} +#endif + +#endif // BAIDU_IOT_TINYDU_IOT_OS_SRC_IOT_BAIDU_CA_SOURCE_BAIDU_CA_AP_INFO_H \ No newline at end of file diff --git a/components/clouds/dueros/lightduer/include/lightduer_bind_device.h b/components/clouds/dueros/lightduer/include/lightduer_bind_device.h old mode 100644 new mode 100755 index 97070d0..9dc8c3c --- a/components/clouds/dueros/lightduer/include/lightduer_bind_device.h +++ b/components/clouds/dueros/lightduer/include/lightduer_bind_device.h @@ -23,6 +23,7 @@ #define BAIDU_DUER_LIGHTDUER_INCLUDE_LIGHTDUER_BIND_DEVICE_H #include "lightduer_types.h" +#include "lightduer_dcs_router.h" #ifdef __cplusplus extern "C" { @@ -33,11 +34,14 @@ extern "C" { * Start the task to bind device. * * PARAM: + * @param[in] uuid: the uuid of device + * @param[in] bind_token: the bind token of device * @param[in] lifecycle: the lifecycle of task in seconds, at least 60s * * @RETURN: success return DUER_OK, failed return DUER_ERR_FAILED. */ -duer_status_t duer_start_bind_device_task(size_t lifecycle); +duer_status_t duer_start_bind_device_task(const char *uuid, + const char *bind_token, size_t lifecycle); /** * DESC: @@ -49,9 +53,20 @@ duer_status_t duer_start_bind_device_task(size_t lifecycle); */ duer_status_t duer_stop_bind_device_task(void); +/** + * DESC: + * Send utoken to cloud to bind device. + * + * PARAM: + * @param[in] utoken: the token passed from App + * @param[in] callback: the callback function to receive the bind result + * + * @RETURN: success return DUER_OK, failed return other. + */ +duer_status_t duer_bind_device_use_utoken(const char *utoken, dcs_directive_handler callback); + #ifdef __cplusplus } #endif #endif /* BAIDU_DUER_LIGHTDUER_INCLUDE_LIGHTDUER_BIND_DEVICE_H */ - diff --git a/components/clouds/dueros/lightduer/include/lightduer_ca.h b/components/clouds/dueros/lightduer/include/lightduer_ca.h old mode 100644 new mode 100755 index 926986a..c1da30c --- a/components/clouds/dueros/lightduer/include/lightduer_ca.h +++ b/components/clouds/dueros/lightduer/include/lightduer_ca.h @@ -56,6 +56,8 @@ DUER_EXT duer_status_t baidu_ca_add_resources(duer_handler hdlr, */ DUER_EXT duer_status_t baidu_ca_load_configuration(duer_handler hdlr, const void *data, duer_size_t size); +DUER_EXT duer_status_t baidu_ca_unload_configuration(duer_handler hdlr); + /* * Start run the Baidu CA, prepare the environment. * @@ -221,6 +223,14 @@ DUER_EXT duer_status_t baidu_ca_release(duer_handler hdlr); */ DUER_EXT const char *baidu_ca_get_uuid(duer_handler hdlr); +/* + * Obtain the rsa cacrt + * + * @Param hdlr, in, the handler will be operated + * @Return const char *, The RSA CACRT string + */ +DUER_EXT const char *baidu_ca_get_rsa_cacrt(duer_handler hdlr); + /* * Obtain the bindToken * diff --git a/components/clouds/dueros/lightduer/include/lightduer_ca_conf.h b/components/clouds/dueros/lightduer/include/lightduer_ca_conf.h index f4acca0..a154a1e 100755 --- a/components/clouds/dueros/lightduer/include/lightduer_ca_conf.h +++ b/components/clouds/dueros/lightduer/include/lightduer_ca_conf.h @@ -22,6 +22,10 @@ #include "lightduer_types.h" +#ifdef __cplusplus +extern "C" { +#endif + typedef void* duer_conf_handler; /* @@ -67,4 +71,8 @@ DUER_INT duer_u32_t duer_conf_get_uint(duer_conf_handler hdlr, const char* key); */ DUER_INT void duer_conf_destroy(duer_conf_handler hdlr); +#ifdef __cplusplus +} +#endif + #endif // BAIDU_IOT_TINYDU_IOT_OS_SRC_IOT_BAIDU_CA_SOURCE_BAIDU_CA_CONF_H diff --git a/components/clouds/dueros/lightduer/include/lightduer_coap_defs.h b/components/clouds/dueros/lightduer/include/lightduer_coap_defs.h old mode 100644 new mode 100755 diff --git a/components/clouds/dueros/lightduer/include/lightduer_connagent.h b/components/clouds/dueros/lightduer/include/lightduer_connagent.h old mode 100644 new mode 100755 diff --git a/components/clouds/dueros/lightduer/include/lightduer_data_cache.h b/components/clouds/dueros/lightduer/include/lightduer_data_cache.h old mode 100644 new mode 100755 index 596ac50..e9236cb --- a/components/clouds/dueros/lightduer/include/lightduer_data_cache.h +++ b/components/clouds/dueros/lightduer/include/lightduer_data_cache.h @@ -33,7 +33,15 @@ typedef struct _duer_transmit_data_s { void duer_dcache_initialize(void); -duer_status_t duer_dcache_push(const void *data, size_t size); +/** + * @param data, the memory address + * @param size, the size of memory + * @param need_copy, indicate whether the memroy @data need another copy + * DUER_FALSE means the invoker transfer the memory ownership, + * DUER_TRUE is default value, which means invoker still own the memory, + * so invoker have the responsibility to release it when no long used. + */ +duer_status_t duer_dcache_push(const void *data, size_t size, duer_bool need_copy); duer_dcache_item *duer_dcache_top(void); diff --git a/components/clouds/dueros/lightduer/include/lightduer_dcs.h b/components/clouds/dueros/lightduer/include/lightduer_dcs.h old mode 100644 new mode 100755 index de2d069..2dbcb13 --- a/components/clouds/dueros/lightduer/include/lightduer_dcs.h +++ b/components/clouds/dueros/lightduer/include/lightduer_dcs.h @@ -14,7 +14,7 @@ * limitations under the License. */ /** - * File: lightduer_dcs_router.h + * File: lightduer_dcs.h * Auth: Gang Chen (chengang12@baidu.com) * Desc: Light duer DCS APIS. */ @@ -45,6 +45,12 @@ typedef enum { DCS_MEDIA_ERROR_INTERNAL_DEVICE_ERROR, // device internal error } duer_dcs_audio_error_t; +typedef enum { + DCS_RECOMMEND_POWER_ON, + DCS_RECOMMEND_OUT_OF_BOX, + DCS_RECOMMEND_TIME_NUMBER, +} duer_dcs_recommend_time_t; + typedef struct { const char *url; int offset; @@ -56,6 +62,11 @@ enum duer_dcs_device_capability { DCS_WECHAT_SUPPORTED = 0x02, // the device support wechat }; +/** + * Internal used private namespace. + */ +extern const char *DCS_PRIVATE_NAMESPACE; + /** * Initialize the dcs framework. * @@ -390,7 +401,7 @@ int duer_dcs_sync_state(void); * DESC: * Sending an "Exited" event to close the multi dialogue. * - * @RETURN: None. + * @RETURN: 0 if succuss, negative if failed. */ int duer_dcs_close_multi_dialog(void); @@ -471,6 +482,97 @@ void duer_dcs_device_control_init(void); */ duer_status_t duer_dcs_capability_declare(duer_u32_t capability); +/** + * DESC: + * Sending RecommendationRequested event, and DCS server will recommend a resource to device. + * Currently, only the scene of "POWER_ON" is supported, that means this function should be called + * only one time(when device power_on). + * + * @PARAM[in] type: type of the scene. + * @RETURN: 0 if succuss, negative if failed. + */ +int duer_dcs_recommend_request(duer_dcs_recommend_time_t time); + +/** + * DESC: + * Similar to duer_dcs_on_listen_started, except not create new dialog id, but get current one. + * + * PARAM: none + * + * @RETURN: 0 when success, negative when fail. + */ +int duer_dcs_on_listen_started_with_current_dialogid(void); + +/** + * DESC: + * Developer needs to implement this interface to pause local player. + * + * PARAM: none + * + * @RETURN: None + */ +void duer_dcs_local_player_pause_handler(void); + +/** + * DESC: + * Developer needs to implement this interface to resume local player. + * + * PARAM: none + * + * @RETURN: None + */ +void duer_dcs_local_player_resume_handler(void); + +/** + * DESC: + * Developer needs to implement this interface to stop local player. + * + * PARAM: none + * + * @RETURN: None + */ +void duer_dcs_local_player_stop_handler(void); + +/** + * DESC: + * Notify DCS module when local player paused. + * + * PARAM: none + * + * @RETURN: None + */ +void duer_dcs_local_player_on_paused(void); + +/** + * DESC: + * Notify DCS module when local player playing. + * + * PARAM: none + * + * @RETURN: None + */ +void duer_dcs_local_player_on_played(void); + +/** + * DESC: + * Notify DCS module when local player stopped. + * + * PARAM: none + * + * @RETURN: None + */ +void duer_dcs_local_player_on_stopped(void); + +/** + * DESC: + * Get the client context. + * + * PARAM: none + * + * @RETURN: NULL if failed, pointer point to the client context if success. + */ +baidu_json *duer_dcs_get_client_context(void); + #ifdef __cplusplus } #endif diff --git a/components/clouds/dueros/lightduer/include/lightduer_dcs_infrared_control.h b/components/clouds/dueros/lightduer/include/lightduer_dcs_infrared_control.h new file mode 100755 index 0000000..57d6a2d --- /dev/null +++ b/components/clouds/dueros/lightduer/include/lightduer_dcs_infrared_control.h @@ -0,0 +1,102 @@ +/** + * Copyright (2017) Baidu Inc. All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/** + * File: lightduer_dcs_infrared_control.h + * Auth: Chang Li (changli@baidu.com) + * Desc: Light duer DCS APIS for infrared control. + */ + +#ifndef BAIDU_DUER_LIGHTDUER_DCS_INFRARED_CONTROL_H +#define BAIDU_DUER_LIGHTDUER_DCS_INFRARED_CONTROL_H + +#include "lightduer_types.h" +#include + +typedef enum { + DCS_INFRARED_SEND_COMPLETED, + DCS_INFRARED_SEND_FAILED, + DCS_INFRARED_RECEIVED, + DCS_INFRARED_RECEIVE_TIMEOUT +} duer_infrared_event_t; + +typedef struct _ray_item_t { + struct _ray_item_t *next; + uint32_t carrier_freq; + uint32_t interval_ms; + uint16_t pattern_cnt; + uint16_t pattern[]; +} duer_ray_item_t; + +typedef struct { + duer_ray_item_t *head; +} duer_ray_item_list_t; + +/** + * DESC: + * Destroy the ray item list and reclaim memory. + * + * PARAM[in] list: Infrared ray data. + * + * @RETURN: None + */ +void duer_destroy_ray_items(duer_ray_item_list_t *list); + +/** + * DESC: + * Developer needs to implement this interface to send infrared data. + * Note, it's asynchronized. + * + * PARAM[in] list: Infrared ray data. Note: need to be reclaimed after use. + * + * @RETURN: None + */ +void duer_dcs_infrared_send_handler(duer_ray_item_list_t *list); + +/** + * DESC: + * Developer needs to implement this interface to receive infrared data. + * + * PARAM[in] timeout_ms: the time device wait for the infrared data. + * + * @RETURN: None + */ +void duer_dcs_infrared_receive_handler(long timeout_ms); + +/** + * DESC: + * report infrared event to cloud. + * + * PARAM[in] event: infrared event. + * + * PARAM[in] array: pattern array for DCS_INFRARED_RECEIVED event. + * + * PARAM[in] cnt: pattern count for DCS_INFRARED_RECEIVED event. + * + * @RETURN: DUER_OK for sucess, others for failure. + */ +int duer_dcs_infrared_control_report(duer_infrared_event_t event, uint16_t *array, int cnt); + +/** + * DESC: + * Initialize infrared control interface. + * + * PARAM: none + * + * @RETURN: none + */ +void duer_dcs_infrared_control_init(void); + +#endif // BAIDU_DUER_LIGHTDUER_DCS_INFRARED_CONTROL_H diff --git a/components/clouds/dueros/lightduer/include/lightduer_dcs_local.h b/components/clouds/dueros/lightduer/include/lightduer_dcs_local.h old mode 100644 new mode 100755 index b55f55c..3061fb4 --- a/components/clouds/dueros/lightduer/include/lightduer_dcs_local.h +++ b/components/clouds/dueros/lightduer/include/lightduer_dcs_local.h @@ -41,6 +41,8 @@ typedef enum { DCS_AUDIO_FINISHED, DCS_AUDIO_STOPPED, DCS_NEED_OPEN_MIC, + DCS_ALERT_STARTED, + DCS_ALERT_FINISHED, } duer_dcs_channel_switch_event_t; #ifdef DCS_CRITICAL_LOCK_DEBUG @@ -75,6 +77,8 @@ extern const char *DCS_VOICE_INPUT_NAMESPACE; extern const char *DCS_SCREEN_NAMESPACE; extern const char *DCS_SCREEN_EXTENDED_CARD_NAMESPACE; extern const char *DCS_IOT_CLOUD_SYSTEM_NAMESPACE; +extern const char *DCS_PLAYBACK_CONTROL_NAMESPACE; +extern const char *DCS_RECOMMEND_NAMESPACE; // message keys extern const char *DCS_DIRECTIVE_KEY; @@ -119,6 +123,10 @@ extern const char *DCS_UNPARSED_DIRECTIVE_KEY; extern const char *DCS_FORMAT_KEY; extern const char *DCS_MESSAGE_KEY; extern const char *DCS_QUERY_KEY; +extern const char *DCS_TIME_OF_RECOMMEND; +extern const char *DCS_STUTTER_DURATION; +extern const char *DCS_PREVIOUS_DIALOG_ID_KEY; +extern const char *DCS_ACTIVE_DIALOG_ID_KEY; // directive name extern const char *DCS_SPEAK_NAME; @@ -143,6 +151,7 @@ extern const char *DCS_RENDER_WEATHER; extern const char *DCS_RENDER_PLAYER_INFO; extern const char *DCS_RENDER_AUDIO_LIST; extern const char *DCS_RENDER_ALBUM_LIST; +extern const char *DCS_SET_ACTIVE_DIALOG; // internal directive. extern const char *DCS_DIALOGUE_FINISHED_NAME; @@ -166,6 +175,7 @@ extern const char *DCS_VOLUME_CHANGED_NAME; extern const char *DCS_MUTE_CHANGED_NAME; extern const char *DCS_SPEECH_STATE_NAME; extern const char *DCS_LINK_CLICKED_NAME; +extern const char *DCS_RECOMMEND_NAME; // internal exception type extern const char *DCS_UNEXPECTED_INFORMATION_RECEIVED_TYPE; @@ -242,17 +252,43 @@ void duer_resume_audio_internal(void); */ void duer_speech_on_stop_internal(void); +/** + * DESC: + * Notify that audio is stopped. + * + * PARAM: none + * + * @RETURN: none. + */ +void duer_dcs_audio_on_stopped_internal(void); + /** * DESC: * Report exception. * * @PARAM[in] directive: which directive cause to the exception + * @PARAM[in] directive_len: the length of directive, if directive_len <=0, the value got from strlen * @PARAM[in] type: exception type * @PARAM[in] msg: excetpion content * * @RETURN: 0 if success, negative if failed. */ -int duer_report_exception_internal(const char* directive, const char* type, const char* msg); +int duer_report_exception_internal(const char* directive, size_t directive_len, + const char* type, const char* msg); + +/** + * DESC: + * get Report exception in baidu_json format. + * + * @PARAM[in] directive: which directive cause to the exception + * @PARAM[in] directive_len: the length of directive, if directive_len <=0, the value got from strlen + * @PARAM[in] type: exception type + * @PARAM[in] msg: excetpion content + * + * @RETURN: NULL if failed. + */ +baidu_json *duer_get_exception_internal(const char *directive, size_t directive_len, + const char *type, const char *msg); /** * DESC: @@ -512,6 +548,16 @@ void duer_dcs_play_control_uninitialize_internal(void); */ void duer_dcs_device_control_uninitialize_internal(void); +/** + * DESC: + * Uninitialize the DCS infrared control interface. + * + * @PARAM: none. + * + * @RETURN: none. + */ +void duer_dcs_infrared_control_uninitialize_internal(void); + /** * DESC: * Uninitialize the DCS audio player interface. @@ -583,6 +629,54 @@ duer_status_t duer_add_dcs_directive_internal(const duer_directive_list *directi */ duer_status_t duer_reg_client_context_cb_internal(dcs_client_context_handler cb); +/** + * DESC: + * Checking whether local player is paused by higher play channel. + * + * @RETURN: Reture DUER_TRUE if local player is paused, else returen DUER_FALSE. + */ +duer_bool duer_local_player_is_paused_internal(void); + +/** + * DESC: + * Checking whether local player is playing. + * + * @RETURN: Reture DUER_TRUE if local player is playing, else returen DUER_FALSE. + */ +duer_bool duer_local_player_is_playing_internal(void); + +/** + * DESC: + * Pause the loacl player. + * + * @RETURN: none. + */ +void duer_pause_local_player_internal(void); + +/** + * DESC: + * Resume the loacl player. + * + * @RETURN: none. + */ +void duer_resume_local_player_internal(void); + +/** + * DESC: + * Stop the loacl player. + * + * @RETURN: none. + */ +void duer_stop_local_player_internal(void); + +/** + * Set dialog id. + * + * @param dialog_id: the new dialog id. + * @return 0 if success, negative if failed. + */ +duer_status_t duer_set_dialog_id_internal(const char *dialog_id); + #ifdef __cplusplus } #endif diff --git a/components/clouds/dueros/lightduer/include/lightduer_dcs_router.h b/components/clouds/dueros/lightduer/include/lightduer_dcs_router.h old mode 100644 new mode 100755 diff --git a/components/clouds/dueros/lightduer/include/lightduer_debug.h b/components/clouds/dueros/lightduer/include/lightduer_debug.h index 2179731..2fa05d1 100755 --- a/components/clouds/dueros/lightduer/include/lightduer_debug.h +++ b/components/clouds/dueros/lightduer/include/lightduer_debug.h @@ -57,6 +57,9 @@ DUER_INT void duer_debug_print(duer_u32_t level, const char* file, DUER_INT void duer_debug(duer_u32_t level, const char* file, duer_u32_t line, const char* fmt, ...); +DUER_INT void duer_dump(duer_u32_t level, const char* file, duer_u32_t line, + const char *tag, const void *data, duer_size_t size); + #ifdef __cplusplus } #endif diff --git a/components/clouds/dueros/lightduer/include/lightduer_dev_info.h b/components/clouds/dueros/lightduer/include/lightduer_dev_info.h index 7b2e93e..d96d60d 100755 --- a/components/clouds/dueros/lightduer/include/lightduer_dev_info.h +++ b/components/clouds/dueros/lightduer/include/lightduer_dev_info.h @@ -37,8 +37,22 @@ struct DevInfoOps { * Provide firmware information about the current system */ int (*get_firmware_version)(char *firmware_version); +/* + * Set firmware information about the current system + */ + int (*set_firmware_version)(char const *firmware_version); }; +/* + * Set the firmware version of the current system + * + * @param firmware_version: + * + * @return int: Success: DUER_OK + * Failed: Other + */ +extern int duer_set_firmware_version(char const *firmware_version); + /* * Get the firmware version of the current system * diff --git a/components/clouds/dueros/lightduer/include/lightduer_ds_log.h b/components/clouds/dueros/lightduer/include/lightduer_ds_log.h index b0df1bd..682fab3 100755 --- a/components/clouds/dueros/lightduer/include/lightduer_ds_log.h +++ b/components/clouds/dueros/lightduer/include/lightduer_ds_log.h @@ -31,6 +31,7 @@ extern "C" { typedef enum _duer_ds_log_version_enum { DUER_DS_LOG_VERSION_UNKNOWN = 0x00, DUER_DS_LOG_VERSION_1_0 = 0x01, + DUER_DS_LOG_VERSION_2_0 = 0x02, DUER_DS_LOG_VERSION_MAX = 0x08 } duer_ds_log_version_enum_t; @@ -43,6 +44,11 @@ typedef enum _duer_ds_log_level_enum { DUER_DS_LOG_LEVEL_MAX = 0x08 } duer_ds_log_level_enum_t; +typedef enum { + DUER_DS_LOG_IMPORTANCE_NORMAL = 0x00, + DUER_DS_LOG_IMPORTANCE_MUST_REPORT = 0x01, +} duer_ds_log_importance_enum_t; + #ifndef DUER_DS_LOG_DEFAULT_REPORT_LEVEL #define DUER_DS_LOG_DEFAULT_REPORT_LEVEL DUER_DS_LOG_LEVEL_INFO #endif @@ -73,10 +79,15 @@ typedef enum _duer_ds_log_module_enum { DUER_DS_LOG_MODULE_MEDIA = 0x03, DUER_DS_LOG_MODULE_HTTP = 0x04, DUER_DS_LOG_MODULE_DCS = 0x05, - DUER_DS_LOG_MODULE_SPEEX = 0x06, - DUER_DS_LOG_MODULE_OTA = 0x07, + DUER_DS_LOG_MODULE_APP = 0x06, + DUER_DS_LOG_MODULE_WIFICFG = 0x07, DUER_DS_LOG_MODULE_SYSTEM = 0x08, DUER_DS_LOG_MODULE_ANALYSIS = 0x09, + DUER_DS_LOG_MODULE_BIND = 0x0A, + DUER_DS_LOG_MODULE_SONIC = 0x0B, + DUER_DS_LOG_MODULE_SMARTCFG = 0x0C, + DUER_DS_LOG_MODULE_AIRKISS = 0x0D, + DUER_DS_LOG_MODULE_PM = 0x0E, DUER_DS_LOG_MODULE_MAX = 0x20 } duer_ds_log_module_enum_t; @@ -192,19 +203,26 @@ duer_status_t duer_ds_log_v_f(duer_ds_log_version_enum_t log_version, duer_ds_log_module_enum_t log_module, duer_ds_log_family_enum_t log_family, int log_code, - const baidu_json *log_message); + const baidu_json *log_message, + duer_ds_log_importance_enum_t importance); duer_status_t duer_ds_log_f(duer_ds_log_level_enum_t log_level, duer_ds_log_module_enum_t log_module, duer_ds_log_family_enum_t log_family, int log_code, - const baidu_json *log_message); + const baidu_json *log_message, + duer_ds_log_importance_enum_t importance); duer_status_t duer_ds_log(duer_ds_log_level_enum_t log_level, duer_ds_log_module_enum_t log_module, int log_code, const baidu_json *log_message); +duer_status_t duer_ds_log_important(duer_ds_log_level_enum_t log_level, + duer_ds_log_module_enum_t log_module, + int log_code, + const baidu_json *log_message); + #ifdef __cplusplus } #endif diff --git a/components/clouds/dueros/lightduer/include/lightduer_ds_log_airkiss.h b/components/clouds/dueros/lightduer/include/lightduer_ds_log_airkiss.h new file mode 100755 index 0000000..7716963 --- /dev/null +++ b/components/clouds/dueros/lightduer/include/lightduer_ds_log_airkiss.h @@ -0,0 +1,48 @@ +/** + * Copyright (2018) Baidu Inc. All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/* + * Auth: Chen Xihao(chenxihao@baidu.com) + * Desc: airkiss related report log + */ + +#ifndef BAIDU_DUER_LIGHTDUER_DS_LOG_AIRKISS_H +#define BAIDU_DUER_LIGHTDUER_DS_LOG_AIRKISS_H + +#include "baidu_json.h" +#include "lightduer_types.h" + +#ifdef __cplusplus +extern "C" { +#endif + +typedef enum _duer_ds_log_airkiss_code { + DUER_DS_LOG_AIRKISS_START = 0x201, + DUER_DS_LOG_AIRKISS_FINISHED = 0x202, + + DUER_DS_LOG_AIRKISS_FAILED = 0x401, +} duer_ds_log_airkiss_code_t; + +/** + * common function to report the log of airkiss + */ +duer_status_t duer_ds_log_airkiss(duer_ds_log_airkiss_code_t log_code, + const baidu_json *message); + +#ifdef __cplusplus +} +#endif + +#endif // BAIDU_DUER_LIGHTDUER_DS_LOG_AIRKISS_H diff --git a/components/clouds/dueros/lightduer/include/lightduer_ds_log_bind.h b/components/clouds/dueros/lightduer/include/lightduer_ds_log_bind.h new file mode 100755 index 0000000..a51dcd4 --- /dev/null +++ b/components/clouds/dueros/lightduer/include/lightduer_ds_log_bind.h @@ -0,0 +1,63 @@ +/** + * Copyright (2018) Baidu Inc. All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/* + * Auth: Chen Xihao(chenxihao@baidu.com) + * Desc: bind device module related report log + */ + +#ifndef BAIDU_DUER_LIGHTDUER_DS_LOG_BIND_H +#define BAIDU_DUER_LIGHTDUER_DS_LOG_BIND_H + +#include "baidu_json.h" +#include "lightduer_types.h" + +#ifdef __cplusplus +extern "C" { +#endif + +typedef enum _duer_ds_log_bind_code { + DUER_DS_LOG_BIND_CONFIG_WIFI_AIRKISS = 0x001, + DUER_DS_LOG_BIND_CONFIG_WIFI_SMARTCONFIG = 0x002, + DUER_DS_LOG_BIND_CONFIG_WIFI_SONIC = 0x003, + DUER_DS_LOG_BIND_CONFIG_WIFI_BT = 0x004, + DUER_DS_LOG_BIND_TASK_START = 0x005, + DUER_DS_LOG_BIND_SEND_RESP = 0x006, + DUER_DS_LOG_BIND_TASK_END = 0x007, + + DUER_DS_LOG_BIND_NO_MEMORY = 0x301, + DUER_DS_LOG_BIND_INVALID_PARAMS = 0x302, + DUER_DS_LOG_BIND_START_TASK_FAILED = 0x303, + DUER_DS_LOG_BIND_INIT_AES_FAILED = 0x304, + DUER_DS_LOG_BIND_INIT_SOCKET_FAILED = 0x305, + DUER_DS_LOG_BIND_BIND_SOCKET_FAILED = 0x306, + DUER_DS_LOG_BIND_ENCRYPT_FAILED = 0x307, + DUER_DS_LOG_BIND_SOCKET_ERROR = 0x308, +} duer_ds_log_bind_code_t; + +/** + * common function to report the log of bind device moudle + */ +duer_status_t duer_ds_log_bind(duer_ds_log_bind_code_t log_code); + + +int duer_ds_log_report_bind_result(duer_u32_t req_port, + duer_u32_t resp_success_count, duer_u32_t resp_fail_count); + +#ifdef __cplusplus +} +#endif + +#endif // BAIDU_DUER_LIGHTDUER_DS_LOG_BIND_H diff --git a/components/clouds/dueros/lightduer/include/lightduer_ds_log_ca.h b/components/clouds/dueros/lightduer/include/lightduer_ds_log_ca.h old mode 100644 new mode 100755 diff --git a/components/clouds/dueros/lightduer/include/lightduer_ds_log_cache.h b/components/clouds/dueros/lightduer/include/lightduer_ds_log_cache.h index 854f3b1..fcabc34 100755 --- a/components/clouds/dueros/lightduer/include/lightduer_ds_log_cache.h +++ b/components/clouds/dueros/lightduer/include/lightduer_ds_log_cache.h @@ -41,6 +41,16 @@ duer_status_t duer_ds_log_cache_push(duer_u32_t code, const baidu_json *message, */ duer_status_t duer_ds_log_cache_report(void); +/** + * initialize the resource + */ +duer_status_t duer_ds_log_cache_initialize(void); + +/** + * release the resources + */ +duer_status_t duer_ds_log_cache_finalize(void); + #ifdef __cplusplus } #endif diff --git a/components/clouds/dueros/lightduer/include/lightduer_ds_log_e2e.h b/components/clouds/dueros/lightduer/include/lightduer_ds_log_e2e.h old mode 100644 new mode 100755 index 60e8e18..fba59f8 --- a/components/clouds/dueros/lightduer/include/lightduer_ds_log_e2e.h +++ b/components/clouds/dueros/lightduer/include/lightduer_ds_log_e2e.h @@ -29,16 +29,21 @@ extern "C" { #endif typedef enum { - DUER_E2E_REQUEST, + DUER_E2E_1ST_WAKEUP, DUER_E2E_RECORD_FINISH, DUER_E2E_SEND, DUER_E2E_RESPONSE, DUER_E2E_PLAY, DUER_E2E_CODEC, - DUER_E2E_EVENT_TOTAL +#ifdef DUER_SECOND_WAKEUP_ENABLE + DUER_E2E_WAKEUP_SEND_ENQUEUE, + DUER_E2E_WAKEUP_SEND, + DUER_E2E_2ND_WAKEUP, +#endif//DUER_SECOND_WAKEUP_ENABLE + DUER_E2E_EVENT_TOTAL, } duer_ds_e2e_event_t; -typedef char* (*duer_ds_e2e_get_dialog_id_cb)(void); +typedef const char* (*duer_ds_e2e_get_dialog_id_cb)(void); #ifdef DUER_STATISTICS_E2E diff --git a/components/clouds/dueros/lightduer/include/lightduer_ds_log_http.h b/components/clouds/dueros/lightduer/include/lightduer_ds_log_http.h index c52935f..cd5e329 100755 --- a/components/clouds/dueros/lightduer/include/lightduer_ds_log_http.h +++ b/components/clouds/dueros/lightduer/include/lightduer_ds_log_http.h @@ -35,11 +35,11 @@ typedef enum { DUER_DS_LOG_HTTP_COMMON_ERROR = 0x103, DUER_DS_LOG_HTTP_PERSISTENT_CONN_TIMEOUT = 0x104, DUER_DS_LOG_HTTP_DOWNLOAD_STARTED = 0x105, - DUER_DS_LOG_HTTP_DOWNLOAD_STOPPED = 0x106, - DUER_DS_LOG_HTTP_DOWNLOAD_FINISHED = 0x107, + // Attention: 0x106, 0x107, 0x201 must be reserved, as they had been used in old version SDK - DUER_DS_LOG_HTTP_DOWNLOAD_URL = 0x201, DUER_DS_LOG_HTTP_ZERO_BYTE_DOWNLOAD = 0x202, + DUER_DS_LOG_HTTP_DOWNLOAD_STOPPED = 0x203, + DUER_DS_LOG_HTTP_DOWNLOAD_FINISHED = 0x204, DUER_DS_LOG_HTTP_SOCKET_CONN_FAILED = 0x301, DUER_DS_LOG_HTTP_URL_PARSE_FAILED = 0x302, @@ -58,6 +58,8 @@ typedef enum { DUER_DS_LOG_HTTP_PARAM_ERROR = 0x310, DUER_DS_LOG_HTTP_RECEIVE_FAILED = 0x311, DUER_DS_LOG_HTTP_REDIRECT_FAILED = 0x312, + DUER_DS_LOG_HTTP_DNS_GET_IP = 0x313, + DUER_DS_LOG_HTTP_TOO_MANY_REDIRECT = 0x314, DUER_DS_LOG_HTTP_SOCKET_INIT_FAILED = 0x401, DUER_DS_LOG_HTTP_SOCKET_OPEN_FAILED = 0x402, @@ -98,6 +100,7 @@ duer_status_t duer_ds_log_http_download_exit(duer_ds_log_http_code_t log_code, * Report ds log when http persistent is timeout and be closed. */ duer_status_t duer_ds_log_http_persisten_conn_timeout(const char *host); + /** * Report ds log with url: * { @@ -105,6 +108,7 @@ duer_status_t duer_ds_log_http_persisten_conn_timeout(const char *host); * } */ duer_status_t duer_ds_log_http_report_with_url(duer_ds_log_http_code_t log_code, const char *url); + /** * Report ds log with error code: * { @@ -112,6 +116,7 @@ duer_status_t duer_ds_log_http_report_with_url(duer_ds_log_http_code_t log_code, * } */ duer_status_t duer_ds_log_http_report_err_code(duer_ds_log_http_code_t log_code, int err_code); + /** * Report ds log when redirect failed, it include the redirect location: * { @@ -120,6 +125,14 @@ duer_status_t duer_ds_log_http_report_err_code(duer_ds_log_http_code_t log_code, */ duer_status_t duer_ds_log_http_redirect_fail(const char *location); +/** + * Report ds log when redirect too many times, it include the redirect count: + * { + * "redirect_count" : 31 + * } + */ +duer_status_t duer_ds_log_http_too_many_redirect(int count); + #define DUER_DS_LOG_REPORT_HTTP_MEMORY_ERROR() \ duer_ds_log_http_report_with_dir(DUER_DS_LOG_HTTP_MEMORY_ERROR, __FILE__, __LINE__) #define DUER_DS_LOG_REPORT_HTTP_PARAM_ERROR() \ diff --git a/components/clouds/dueros/lightduer/include/lightduer_ds_log_pm.h b/components/clouds/dueros/lightduer/include/lightduer_ds_log_pm.h new file mode 100755 index 0000000..5c5b995 --- /dev/null +++ b/components/clouds/dueros/lightduer/include/lightduer_ds_log_pm.h @@ -0,0 +1,45 @@ +/** + * Copyright (2018) Baidu Inc. All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/* + * Auth: Chen Xihao(chenxihao@baidu.com) + * Desc: power manager module related report log + */ + +#ifndef BAIDU_DUER_LIGHTDUER_DS_LOG_PM_H +#define BAIDU_DUER_LIGHTDUER_DS_LOG_PM_H + +#include "baidu_json.h" +#include "lightduer_types.h" + +#ifdef __cplusplus +extern "C" { +#endif + +typedef enum _duer_ds_log_pm_code { + DUER_DS_LOG_PM_SLEEP = 0x201, + DUER_DS_LOG_PM_WAKEUP = 0x202, +} duer_ds_log_pm_code_t; + +/** + * common function to report the log of pm + */ +duer_status_t duer_ds_log_pm(duer_ds_log_pm_code_t log_code, const baidu_json *message); + +#ifdef __cplusplus +} +#endif + +#endif // BAIDU_DUER_LIGHTDUER_DS_LOG_PM_H diff --git a/components/clouds/dueros/lightduer/include/lightduer_ds_log_smart_config.h b/components/clouds/dueros/lightduer/include/lightduer_ds_log_smart_config.h new file mode 100755 index 0000000..cc20a35 --- /dev/null +++ b/components/clouds/dueros/lightduer/include/lightduer_ds_log_smart_config.h @@ -0,0 +1,67 @@ +/** + * Copyright (2018) Baidu Inc. All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/* + * Auth: Chen Xihao(chenxihao@baidu.com) + * Desc: SmartConfig related report log + */ + +#ifndef BAIDU_DUER_LIGHTDUER_DS_LOG_SMART_CONFIG_H +#define BAIDU_DUER_LIGHTDUER_DS_LOG_SMART_CONFIG_H + +#include "baidu_json.h" +#include "lightduer_types.h" + +#ifdef __cplusplus +extern "C" { +#endif + +typedef enum _duer_ds_log_smart_cfg_code { + DUER_DS_LOG_SMART_CFG_START = 0x201, + DUER_DS_LOG_SMART_CFG_LOCK_CHANNEL = 0x202, + DUER_DS_LOG_SMART_CFG_LEAD_COMPLETED = 0x203, + DUER_DS_LOG_SMART_CFG_FINISHED = 0x204, + + DUER_DS_LOG_SMART_CFG_FAILED = 0x401, +} duer_ds_log_smart_cfg_code_t; + +typedef struct duer_ds_log_smart_cfg_info_s { + duer_size_t packet_counts; + duer_size_t data_counts; + duer_size_t data_invalids; + duer_size_t decode_counts; +} duer_ds_log_smart_cfg_info_t; + +/** + * common function to report the log of smart config + */ +duer_status_t duer_ds_log_smart_cfg(duer_ds_log_smart_cfg_code_t log_code, + const baidu_json *message); + +/** + * report the log that smart config receive all lead code + */ +duer_status_t duer_ds_log_smart_cfg_lead_completed(duer_size_t data_len); + +/** + * report the log that smart config finished + */ +duer_status_t duer_ds_log_smart_cfg_finished(duer_ds_log_smart_cfg_info_t *info); + +#ifdef __cplusplus +} +#endif + +#endif // BAIDU_DUER_LIGHTDUER_DS_LOG_SMART_CONFIG_H diff --git a/components/clouds/dueros/lightduer/include/lightduer_ds_log_sonic_decode.h b/components/clouds/dueros/lightduer/include/lightduer_ds_log_sonic_decode.h new file mode 100755 index 0000000..9ef0102 --- /dev/null +++ b/components/clouds/dueros/lightduer/include/lightduer_ds_log_sonic_decode.h @@ -0,0 +1,65 @@ +/** + * Copyright (2018) Baidu Inc. All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/* + * Auth: Su Hao(suhao@baidu.com) + * Desc: Sonic decode related report log + */ + +#ifndef BAIDU_DUER_LIBDUER_DEVICE_MODULES_DEVICE_STATUS_LIGHTDUER_DS_LOG_SONIC_DECODE_H +#define BAIDU_DUER_LIBDUER_DEVICE_MODULES_DEVICE_STATUS_LIGHTDUER_DS_LOG_SONIC_DECODE_H + +#include "baidu_json.h" +#include "lightduer_types.h" +#include "lightduer_math.h" + +#ifdef __cplusplus +extern "C" { +#endif + +typedef enum _duer_ds_log_sonic_decode_code { + DUER_DS_LOG_SONICCODEC_DECODE_START = 0x101, // 开始解码 Info 否 + DUER_DS_LOG_SONICCODEC_DECODE_FETCHED_START = 0x102, // 接收第一人同步信息 Info 否 + DUER_DS_LOG_SONICCODEC_DECODE_BLOCK_ERROR = 0x301, // 收到错误的block Debug 否 + DUER_DS_LOG_SONICCODEC_DECODE_FRAGMENT_FETCHED = 0x103,// 收到正确的fragment Debug 否 + DUER_DS_LOG_SONICCODEC_DECODE_FRAGMENT_ERROR = 0x302, // 收到错误的fragment Debug 否 + DUER_DS_LOG_SONICCODEC_DECODE_FRAME_COMPLETE = 0x104, // 收到完整的Frame Debug 否 + DUER_DS_LOG_SONICCODEC_DECODE_FINISH = 0x105, // 解码结束 Info 否 + DUER_DS_LOG_SONICCODEC_DECODE_FAILED = 0x303, // 解码失败 Error 否 +} duer_ds_log_sonic_decode_code_t; + +DUER_INT duer_status_t duer_ds_log_sonicdec_start(void); + +DUER_INT duer_status_t duer_ds_log_sonicdec_audio_analysis(const duer_coef_t *data, duer_size_t size); + +DUER_INT duer_status_t duer_ds_log_sonicdec_fetched_start(void); + +DUER_INT duer_status_t duer_ds_log_sonicdec_block_error(void); + +DUER_INT duer_status_t duer_ds_log_sonicdec_fragment_fetched(void); + +DUER_INT duer_status_t duer_ds_log_sonicdec_fragment_error(void); + +DUER_INT duer_status_t duer_ds_log_sonicdec_frame_complete(int length); + +DUER_INT duer_status_t duer_ds_log_sonicdec_finish(void); + +DUER_INT duer_status_t duer_ds_log_sonicdec_failed(void); + +#ifdef __cplusplus +} +#endif + +#endif // BAIDU_DUER_LIBDUER_DEVICE_MODULES_DEVICE_STATUS_LIGHTDUER_DS_LOG_SONIC_DECODE_H diff --git a/components/clouds/dueros/lightduer/include/lightduer_ds_log_storage.h b/components/clouds/dueros/lightduer/include/lightduer_ds_log_storage.h new file mode 100755 index 0000000..8a5b282 --- /dev/null +++ b/components/clouds/dueros/lightduer/include/lightduer_ds_log_storage.h @@ -0,0 +1,46 @@ +/** + * Copyright (2017) Baidu Inc. All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/* + * Auth: Gang Chen(chengang12@baidu.com) + * Desc: Save the ds log to ROM. + */ + +#ifndef BAIDU_DUER_LIGHTDUER_DS_LOG_STORAGE_H +#define BAIDU_DUER_LIGHTDUER_DS_LOG_STORAGE_H + +#ifdef DUER_DS_LOG_STORAGE_ENABLED + +#ifdef __cplusplus +extern "C" { +#endif + +#include "lightduer_types.h" +#include "lightduer_flash_ring_buf.h" + +duer_status_t duer_ds_log_storage_push(const char *log); + +duer_status_t duer_ds_log_storage_send(void); + +duer_status_t duer_ds_log_storage_init(duer_flash_context_t *ctx, + duer_flash_config_t *config); + +#ifdef __cplusplus +} +#endif + +#endif // DUER_DS_LOG_STORAGE_ENABLED + +#endif // BAIDU_DUER_LIGHTDUER_DS_LOG_STORAGE_H \ No newline at end of file diff --git a/components/clouds/dueros/lightduer/include/lightduer_ds_log_wifi_config.h b/components/clouds/dueros/lightduer/include/lightduer_ds_log_wifi_config.h new file mode 100755 index 0000000..e3cd699 --- /dev/null +++ b/components/clouds/dueros/lightduer/include/lightduer_ds_log_wifi_config.h @@ -0,0 +1,107 @@ +/** + * Copyright (2018) Baidu Inc. All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/* + * Auth: Chen Xihao(chenxihao@baidu.com) + * Desc: wifi config related report log + */ + +#ifndef BAIDU_DUER_LIGHTDUER_DS_LOG_WIFI_CONFIG_H +#define BAIDU_DUER_LIGHTDUER_DS_LOG_WIFI_CONFIG_H + +#include "baidu_json.h" +#include "lightduer_types.h" + +#ifdef __cplusplus +extern "C" { +#endif + +typedef enum _duer_ds_log_wifi_cfg_code { + DUER_DS_LOG_WIFI_CFG_START = 0x101, + DUER_DS_LOG_WIFI_CFG_SCAN_RESLUTS = 0x102, + DUER_DS_LOG_WIFI_CFG_LOCKED = 0x103, + DUER_DS_LOG_WIFI_CFG_CONNECTING = 0x104, + DUER_DS_LOG_WIFI_CFG_CONNECTED = 0x105, + DUER_DS_LOG_WIFI_CFG_FINISHED = 0x106, + + DUER_DS_LOG_WIFI_CFG_TIMEOUT = 0x401, + DUER_DS_LOG_WIFI_CFG_FAILED = 0x402, +} duer_ds_log_wifi_cfg_code_t; + +typedef enum _duer_wifi_cfg_err_code { + DUER_WIFI_CFG_SUCCESS = 0, + DUER_WIFI_CFG_STOP = 1, + DUER_WIFI_CFG_ERR_NORMAL = 2, + DUER_WIFI_CFG_ERR_NO_MEMORY = 3, + DUER_WIFI_CFG_ERR_SSID_INVALID = 4, + DUER_WIFI_CFG_ERR_HANDSHARK = 5, +} duer_wifi_cfg_err_code_t; + +typedef enum _duer_wifi_cfg_method { + DUER_WIFI_CFG_UNKOWN = 0, + DUER_WIFI_CFG_AIRKISS = 1, + DUER_WIFI_CFG_SMART_CONFIG = 2, + DUER_WIFI_CFG_SONIC = 3, + DUER_WIFI_CFG_BLUE_TOOTH = 4, +} duer_wifi_cfg_method_t; + +#define CHECK_WIFI_CFG_ID() \ + if (duer_ds_log_wifi_cfg_get_id() == 0) { \ + DUER_LOGE("should call duer_ds_log_wifi_cfg_start first"); \ + return DUER_ERR_FAILED; \ + } + +/** + * common function to report the log of wifi config + */ +duer_status_t duer_ds_log_wifi_cfg(duer_ds_log_wifi_cfg_code_t log_code, + const baidu_json *message); + +/** + * report the log that wifi config start + */ +duer_status_t duer_ds_log_wifi_cfg_start(void); + +/** + * report the message for log code DUER_DS_LOG_WIFI_CFG_SCAN_RESLUTS + * { + * "list": [ + * "SSID名称1", "SSID名称2", ... + * ], + * } + */ +duer_status_t duer_ds_log_wifi_cfg_scan_resluts(const char **ssids, duer_size_t num); + +/** + * report the log that wifi config finished + */ +duer_status_t duer_ds_log_wifi_cfg_finished(duer_wifi_cfg_err_code_t code, + duer_wifi_cfg_method_t method); + +/** + * report the log that wifi config failed + */ +duer_status_t duer_ds_log_wifi_cfg_failed(duer_wifi_cfg_err_code_t err_code, int rssi); + +/** + * get the id of wifi config + */ +int duer_ds_log_wifi_cfg_get_id(void); + +#ifdef __cplusplus +} +#endif + +#endif // BAIDU_DUER_LIGHTDUER_DS_LOG_WIFI_CONFIG_H diff --git a/components/clouds/dueros/lightduer/include/lightduer_engine.h b/components/clouds/dueros/lightduer/include/lightduer_engine.h old mode 100644 new mode 100755 index f408eba..9aba197 --- a/components/clouds/dueros/lightduer/include/lightduer_engine.h +++ b/components/clouds/dueros/lightduer/include/lightduer_engine.h @@ -73,6 +73,8 @@ const char *duer_engine_get_uuid(void); const char *duer_engine_get_bind_token(void); +const char *duer_engine_get_rsa_cacrt(void); + #ifdef __cplusplus } #endif diff --git a/components/clouds/dueros/lightduer/include/lightduer_file.h b/components/clouds/dueros/lightduer/include/lightduer_file.h new file mode 100755 index 0000000..f641002 --- /dev/null +++ b/components/clouds/dueros/lightduer/include/lightduer_file.h @@ -0,0 +1,150 @@ +/** + * Copyright (2018) Baidu Inc. All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +// Author: Chen Yun (chenyun08@baidu.com) +// +// Description: Wrapper for file operation. + +#ifndef BAIDU_DUER_LIBDUER_DEVICE_FRAMEWORK_CORE_LIGHTDUER_FILE_H +#define BAIDU_DUER_LIBDUER_DEVICE_FRAMEWORK_CORE_LIGHTDUER_FILE_H + +#include "lightduer_types.h" + +#ifdef __cplusplus +extern "C" { +#endif + +typedef void *duer_file_t; + +/* + * The file system operation callbacks + */ +typedef duer_file_t (*duer_fs_open)(const char *filename, const char *mode); +typedef size_t (*duer_fs_read)(void *buffer, size_t size, size_t count, duer_file_t stream); +typedef size_t (*duer_fs_write)(const void *buffer, size_t size, size_t count, duer_file_t stream); +typedef long(*duer_fs_size)(duer_file_t stream); +typedef int (*duer_fs_seek)(duer_file_t stream, long offset, int origin); +typedef long(*duer_fs_tell)(duer_file_t stream); +typedef int (*duer_fs_close)(duer_file_t stream); + +/* + * Initial the file system callbacks for file opeation + * + * @Param f_open, open file + * @Param f_read, read block of data from stream + * @Param f_write, write block of data to stream + * @Param f_seek, reposition stream position indicator + * @Param f_tell, get current position in stream + * @Param f_close, close file + */ +DUER_EXT void duer_file_init(duer_fs_open f_open, + duer_fs_read f_read, + duer_fs_write f_write, + duer_fs_size f_size, + duer_fs_seek f_seek, + duer_fs_tell f_tell, + duer_fs_close f_close); + +/* + * @describe Opens the file whose name is specified in the parameter filename and associates + * it with a stream that can be identified in future operations by the FILE pointer returned. + * @Param filename, C string containing the name of the file to be opened.Its value shall + * follow the file name specifications of the running environment and can include a path + * (if supported by the system). + * @Param mode,C string containing a file access mode. It can be:"r" read: Open file for + * input operations. The file must exist."w" write: Create an empty file for output operations. + * If a file with the same name already exists, its contents are discarded and the file is + * treated as a new empty file."a" append: Open file for output at the end of a file. Output + * operations always write data at the end of the file, expanding it. Repositioning operations + * (fseek, fsetpos, rewind) are ignored. The file is created if it does not exist."r+" read/update: + * Open a file for update (both for input and output). The file must exist. + * "w+" write/update: Create an empty file and open it for update (both for input and output). If a file with the same + * name already exists its contents are discarded and the file is treated as a new empty file. + * "a+" append/update: Open a file for update (both for input and output) with all output operations writing data at the + * end of the file. Repositioning operations (fseek, fsetpos, rewind) affects the next input operations, but output operations + * move the position back to the end of file. The file is created if it does not exist. + * @Return If the file is successfully opened, the function returns a pointer to a FILE object that can be used to identify + * the stream on future operations.Otherwise, a null pointer is returned. + */ +DUER_EXT duer_file_t duer_file_open(const char *filename, const char *mode); + +/* + * @describe Read block of data from stream + * @Param buffer, Pointer to a block of memory with a size of at least (size*count) bytes, converted to a void*. + * @Param size, in bytes, of each element to be read.size_t is an unsigned integral type. + * @Param count,Number of elements, each one with a size of size bytes.size_t is an unsigned integral type. + * @Param, Pointer to a FILE object that specifies an input stream. + * @Return The total number of elements successfully read is returned. + */ +DUER_EXT size_t duer_file_read(void *buffer, + size_t size, + size_t count, + duer_file_t stream); + +/* + * @describe Write block of data to stream + * @Param buffer, Pointer to the array of elements to be written, converted to a const void*. + * @Param size, Size in bytes of each element to be written.size_t is an unsigned integral type. + * @Param count,Number of elements, each one with a size of size bytes.size_t is an unsigned integral type. + * @Param, Pointer to a FILE object that specifies an output stream. + * @Return The total number of elements successfully written is returned. + */ +DUER_EXT size_t duer_file_write(const void *buffer, + size_t size, + size_t count, + duer_file_t stream); + +/* + * @describe gets the size of a file. + * @Param stream, Pointer to the open file object structure. + * @Return Returns the size of the file in unit of byte. + */ +DUER_EXT long duer_file_size(duer_file_t stream); + +/* + * @describe Sets the position indicator associated with the stream to a new position. + * @Param stream,pointer to a FILE object that identifies the stream. + * @Param offset,Binary files: Number of bytes to offset from origin.Text files: Either zero, or a value returned by ftell. + * @Param origin,Position used as reference for the offset. It is specified by one of the following constants defined + * in exclusively to be used as arguments for this function: + * Constant Reference position + * SEEK_SET Beginning of file + * SEEK_CUR Current position of the file pointer + * SEEK_END End of file * + * @Return if successful, the function returns zero.Otherwise, it returns non-zero value. + */ +DUER_EXT int duer_file_seek(duer_file_t stream, long offset, int origin); + +/* + * @describe returns the current value of the position indicator of the stream. + * @Param stream, pointer to a FILE object that identifies the stream. + * @Return On success, the current value of the position indicator is returned. + * On failure, -1L is returned, and errno is set to a system-specific positive value. + */ +DUER_EXT long duer_file_tell(duer_file_t stream); + +/* + * @describe closes the file associated with the stream and disassociates it. + * @Param stream, pointer to a FILE object that specifies the stream to be closed. + * @Return if the stream is successfully closed, a zero value is returned. + * On failure, EOF is returned. + */ +DUER_EXT int duer_file_close(duer_file_t stream); + +#ifdef __cplusplus +} +#endif + +#endif // BAIDU_DUER_LIBDUER_DEVICE_FRAMEWORK_CORE_LIGHTDUER_FILE_H diff --git a/components/clouds/dueros/lightduer/include/lightduer_flash.h b/components/clouds/dueros/lightduer/include/lightduer_flash.h new file mode 100755 index 0000000..c5f41cc --- /dev/null +++ b/components/clouds/dueros/lightduer/include/lightduer_flash.h @@ -0,0 +1,139 @@ +// Copyright (2018) Baidu Inc. All rights reserved. +/** + * File: lightduer_flash.h + * Auth: Sijun Li(lisijun@baidu.com) + * Desc: Common defines for flash strings module. + */ +#ifndef BAIDU_DUER_LIGHTDUER_FLASH_H +#define BAIDU_DUER_LIGHTDUER_FLASH_H + +#ifdef __cplusplus +extern "C" { +#endif + +#include "lightduer_types.h" + +#define FLASH_MAGIC 0x56BD50C4 +#define FLASH_MAGIC_BITMASK 0xffffffff +#define FLASH_LEN_BITMASK 0xffffffff +#define FLASH_INVALID_ADDR 0xffffffff + +typedef enum { + DUER_ERR_FLASH_CORRUPT = -2, + DUER_ERR_FLASH_FULL = -3, +}duer_flash_errcode; + +/* + * Configuration of flash operations. + * xxx_align_bits: Number of last bits of address to be aligned. + * For example, Bits=5 indicates header's last 5 bits are '0'. + */ +typedef struct { + // For erase. + int sector_align_bits; + // For write. + int page_align_bits; + // For read. + int word_align_bits; +} duer_flash_config_t; + +typedef struct { + void *handle; + unsigned int len; + void *object; +} duer_flash_context_t; + +typedef struct { + unsigned int magic; // Magic number to check data valid; + unsigned int len; // Length of payload string; + // Used to know the sequence of the data in the flash, it's used in flash ring buf + unsigned int sequence_num; +} duer_flash_data_header; + +inline unsigned int flash_addr_align_floor(unsigned int addr, int bits) { + addr >>= bits; + addr <<= bits; + return addr; +} + +inline unsigned int flash_addr_align_ceil(unsigned int addr, int bits) { + unsigned int bitmask = (1 << bits) - 1; + if (addr & bitmask) { + addr >>= bits; + addr += 1; + addr <<= bits; + } + return addr; +} + +inline unsigned int flash_addr_cycle(unsigned int addr, int size) { + if (addr >= size) { + return (addr - size); + } else { + return addr; + } +} + +/** + * DESC: + * Developer needs to implement this interface to read flash. + * + * @PARAM[in] ctx: pointer of context. + * @PARAM[in] addr: the address offset of flash to read. + * @PARAM[out] buf: the buffer to store read data. + * @PARAM[in] len: length of byte to read. + * + * @RETURN: 0 when success, else when fail. + */ +extern int duer_flash_read( + duer_flash_context_t *ctx, + unsigned int addr, + void *buf, + unsigned int len); + +/** + * DESC: + * Developer needs to implement this interface to write flash. + * + * @PARAM[in] ctx: pointer of context. + * @PARAM[in] addr: the address offset of flash to write. + * @PARAM[in] buf: the buffer stored writing data. + * @PARAM[in] len: length of byte to write. + * + * @RETURN: 0 when success, else when fail. + */ +extern int duer_flash_write( + duer_flash_context_t *ctx, + unsigned int addr, + void *buf, + unsigned int len); + +/** + * DESC: + * Developer needs to implement this interface to erase flash. + * + * @PARAM[in] ctx: pointer of context. + * @PARAM[in] addr: the address offset start of flash to erase. + * @PARAM[in] len: length of byte to erase. + * + * @RETURN: 0 when success, else when fail. + */ +extern int duer_flash_erase( + duer_flash_context_t *ctx, + unsigned int addr, + unsigned int len); + +int duer_payload_write_flash( + duer_flash_context_t *ctx, + unsigned int addr_start, + duer_flash_data_header *p_flash_header, + const char *payload_string, + int payload_len, + int page_size); + +#ifdef __cplusplus +} +#endif + +#endif//BAIDU_DUER_LIGHTDUER_FLASH_H + diff --git a/components/clouds/dueros/lightduer/include/lightduer_flash_ring_buf.h b/components/clouds/dueros/lightduer/include/lightduer_flash_ring_buf.h new file mode 100755 index 0000000..0adae65 --- /dev/null +++ b/components/clouds/dueros/lightduer/include/lightduer_flash_ring_buf.h @@ -0,0 +1,49 @@ +// Copyright (2018) Baidu Inc. All rights reserved. +/** + * File: lightduer_flash_ring_buf.h + * Auth: Gang Chen(chengang12@baidu.com) + * Desc: APIs of store string list to flash. + */ +#ifndef BAIDU_DUER_LIGHTDUER_FLASH_RING_BUF_H +#define BAIDU_DUER_LIGHTDUER_FLASH_RING_BUF_H + +#ifdef __cplusplus +extern "C" { +#endif + +#include "lightduer_types.h" +#include "lightduer_flash.h" + +typedef struct { + duer_flash_context_t ctx; + int ele_count; + unsigned int sequence_num; + unsigned int ele_header; + unsigned int ele_tail; +} duer_flash_ring_buf_context_t; + +/** + * DESC: + * Should be called in duer_flash_init, + * This function will only take effect when first time called. + * + * PARAM config: configuration of hardware flash. + * + * @RETURN: none + */ +extern void duer_flash_ring_buf_set_config(const duer_flash_config_t *config); + +void duer_flash_ring_buf_load(duer_flash_ring_buf_context_t *ctx); + +char *duer_flash_ring_buf_top(duer_flash_ring_buf_context_t *ctx); + +duer_status_t duer_flash_ring_buf_header_remove(duer_flash_ring_buf_context_t *ctx); + +duer_status_t duer_flash_ring_buf_append(duer_flash_ring_buf_context_t *ctx, const char *msg); + +#ifdef __cplusplus +} +#endif + +#endif//BAIDU_DUER_LIGHTDUER_FLASH_RING_BUF_H + diff --git a/components/clouds/dueros/lightduer/include/lightduer_flash_strings.h b/components/clouds/dueros/lightduer/include/lightduer_flash_strings.h old mode 100644 new mode 100755 index b26ab2f..977f37c --- a/components/clouds/dueros/lightduer/include/lightduer_flash_strings.h +++ b/components/clouds/dueros/lightduer/include/lightduer_flash_strings.h @@ -11,48 +11,18 @@ extern "C" { #endif -#include "lightduer_types.h" - -#define FLASH_MAGIC 0x56BD50C4 -#define FLASH_MAGIC_BITMASK 0xffffffff -#define FLASH_LEN_BITMASK 0xffffffff -#define FLASH_INVALID_ADDR 0xffffffff +#include "lightduer_flash.h" typedef enum { ALARM_FLASH = 0, MAX_FLASH_MODULE = 1, }duer_flash_module; -typedef enum { - DUER_ERR_FLASH_CORRUPT = -2, - DUER_ERR_FLASH_FULL = -3, -}duer_flash_errcode; - -/* - * Configuration of flash operations. - * xxx_align_bits: Number of last bits of address to be aligned. - * For example, Bits=5 indicates header's last 5 bits are '0'. - */ -typedef struct { - // For erase. - int sector_align_bits; - // For write. - int page_align_bits; - // For read. - int word_align_bits; -} duer_flash_config_t; - typedef struct { - void *handle; - unsigned int len; + duer_flash_context_t ctx; int max_ele_count; unsigned int *ele_list; -} duer_flash_context_t; - -typedef struct { - unsigned int magic; // Magic number to check data valid; - unsigned int len; // Length of payload string; -} duer_flash_data_header; +} duer_flash_string_context_t; typedef char *(*duer_raw2string_func)(void *); typedef void (*duer_free_string_func)(char *); @@ -67,56 +37,7 @@ typedef void (*duer_free_string_func)(char *); * * @RETURN: pointer of created context. */ -extern duer_flash_context_t *duer_flash_init(duer_flash_module module); - -/** - * DESC: - * Developer needs to implement this interface to read flash. - * - * @PARAM[in] ctx: pointer of context. - * @PARAM[in] addr: the address offset of flash to read. - * @PARAM[out] buf: the buffer to store read data. - * @PARAM[in] len: length of byte to read. - * - * @RETURN: 0 when success, else when fail. - */ -extern int duer_flash_read( - duer_flash_context_t *ctx, - unsigned int addr, - void *buf, - unsigned int len); - -/** - * DESC: - * Developer needs to implement this interface to write flash. - * - * @PARAM[in] ctx: pointer of context. - * @PARAM[in] addr: the address offset of flash to write. - * @PARAM[in] buf: the buffer stored writing data. - * @PARAM[in] len: length of byte to write. - * - * @RETURN: 0 when success, else when fail. - */ -extern int duer_flash_write( - duer_flash_context_t *ctx, - unsigned int addr, - void *buf, - unsigned int len); - -/** - * DESC: - * Developer needs to implement this interface to erase flash. - * - * @PARAM[in] ctx: pointer of context. - * @PARAM[in] addr: the address offset start of flash to erase. - * @PARAM[in] len: length of byte to erase. - * - * @RETURN: 0 when success, else when fail. - */ -extern int duer_flash_erase( - duer_flash_context_t *ctx, - unsigned int addr, - unsigned int len); +extern duer_flash_string_context_t *duer_flash_init(duer_flash_module module); /** * DESC: @@ -145,7 +66,7 @@ extern void duer_set_flash_config(const duer_flash_config_t *config); * @RETURN: 0 when success, else when fail. */ extern int duer_append_to_flash( - duer_flash_context_t *ctx, + duer_flash_string_context_t *ctx, void *raw_data, duer_raw2string_func raw2string_func, duer_free_string_func free_string_func); @@ -162,7 +83,7 @@ extern int duer_append_to_flash( * @RETURN: none */ extern void duer_update_to_flash_prepare( - duer_flash_context_t *ctx, + duer_flash_string_context_t *ctx, unsigned int *p_first_ele_addr, unsigned int *p_last_ele_addr); @@ -183,7 +104,7 @@ extern void duer_update_to_flash_prepare( * @RETURN: 0 when success, else when fail. */ extern int duer_update_to_flash( - duer_flash_context_t *ctx, + duer_flash_string_context_t *ctx, void *raw_data, duer_raw2string_func raw2string_func, duer_free_string_func free_string_func, @@ -211,7 +132,7 @@ extern int duer_update_to_flash( * @RETURN: 0 when success, else when fail. */ extern void duer_update_flash_header( - duer_flash_context_t *ctx, + duer_flash_string_context_t *ctx, unsigned int first_ele_addr); /** @@ -223,7 +144,7 @@ extern void duer_update_flash_header( * @RETURN: none */ extern void duer_get_all_ele_from_flash( - duer_flash_context_t *ctx); + duer_flash_string_context_t *ctx); /** * DESC: @@ -237,7 +158,7 @@ extern void duer_get_all_ele_from_flash( * @RETURN: 0 when success, else when fail. */ extern int duer_get_flash_header( - duer_flash_context_t *ctx, + duer_flash_string_context_t *ctx, unsigned int flash_index, duer_flash_data_header *p_header); @@ -254,7 +175,7 @@ extern int duer_get_flash_header( * @RETURN: 0 when success, else when fail. */ extern void duer_parse_flash_ele_to_string( - duer_flash_context_t *ctx, + duer_flash_string_context_t *ctx, unsigned int flash_index, duer_flash_data_header data, char *payload_string); diff --git a/components/clouds/dueros/lightduer/include/lightduer_http_client.h b/components/clouds/dueros/lightduer/include/lightduer_http_client.h old mode 100644 new mode 100755 index 4a2349c..134b0ec --- a/components/clouds/dueros/lightduer/include/lightduer_http_client.h +++ b/components/clouds/dueros/lightduer/include/lightduer_http_client.h @@ -46,7 +46,8 @@ typedef enum { DUER_HTTP_ERR_CONNECT, // Connection error DUER_HTTP_CLOSED, // Connection was closed by remote host DUER_HTTP_ERR_NOT_SUPPORT, // not supported feature - DUER_HTTP_REDIRECTTION, //take a redirection when http header contains 'Location' + DUER_HTTP_REDIRECTTION, // take a redirection when http header contains 'Location' + DUER_HTTP_TOO_MANY_REDIRECT, // redirect too many times } duer_http_result_t; typedef enum { @@ -58,16 +59,16 @@ typedef enum { } duer_http_method_t; typedef struct { - int n_handle; - int (*init)(void *socket_args); - int (*open)(int socket_handle); - int (*connect)(int socket_handle, const char *host, const int port); - void (*set_blocking)(int socket_handle, int blocking); - void (*set_timeout)(int socket_handle, int timeout); - int (*recv)(int socket_handle, void *data, unsigned size); - int (*send)(int socket_handle, const void *data, unsigned size); - int (*close)(int socket_handle); - void (*destroy)(int socket_handle); + duer_handler n_handle; + duer_handler (*init)(void *socket_args); + int (*open)(duer_handler socket_handle); + int (*connect)(duer_handler socket_handle, const char *host, const int port); + void (*set_blocking)(duer_handler socket_handle, int blocking); + void (*set_timeout)(duer_handler socket_handle, int timeout); + int (*recv)(duer_handler socket_handle, void *data, unsigned size); + int (*send)(duer_handler socket_handle, const void *data, unsigned size); + int (*close)(duer_handler socket_handle); + void (*destroy)(duer_handler socket_handle); } duer_http_socket_ops_t; //to tell data output callback user that if the current data block is first block or last block @@ -93,15 +94,6 @@ typedef enum { */ typedef int (*duer_http_data_handler)(void *p_user_ctx, duer_http_data_pos_t pos, const char *buf, size_t len, const char *type); -/** - * DESC: - * callback to check whether need to stop getting data - * - * PARAM: none - * - * @RETURN 1: to stop; 0: no stop - */ -typedef int (*duer_http_stop_notify_cb_t)(); /** * DESC: @@ -109,25 +101,26 @@ typedef int (*duer_http_stop_notify_cb_t)(); * this callback is used to get the url * * PARAM: + * @param[in] p_user_ctx: usr ctx registed by user * @param[in] url: the url used by http to download data * * RETURN: none */ -typedef void (*duer_http_get_url_cb_t)(const char *url); +typedef void (*duer_http_get_url_cb_t)(void *p_user_ctx, const char *url); typedef struct { const char **pps_custom_headers; size_t sz_headers_count; int n_http_response_code; // http response code duer_http_socket_ops_t ops; // socket operations + int scheme; // http or https type,1 is https, 0 is http duer_http_data_handler data_hdlr_cb; // callback for output data void *p_data_hdlr_ctx; // users args for data_hdlr_cb int n_http_content_len; // http content length // http content type char p_http_content_type[DUER_HTTP_CONTENT_TYPE_LEN_MAX]; char *p_location; // http header "Location" - // a callback to check that stopping http client getting data or not - duer_http_stop_notify_cb_t check_stop_notify_cb; + int stop_flag; // to get the url used to download, the last url will be returned if 302 location happen duer_http_get_url_cb_t get_url_cb; int n_is_chunked; @@ -264,15 +257,13 @@ int duer_http_get_rsp_code(duer_http_client_t *p_client); /** * DESC: - * register callback to check stop flag + * Notify the http module to stop download. * * @param[in] p_client: pointer of the http client - * @param[in] chk_stp_cb: to notify httpclient to stop * * @RETURN none */ -void duer_http_reg_stop_notify_cb(duer_http_client_t *p_client, - duer_http_stop_notify_cb_t chk_stp_cb); +void duer_http_stop_notify(duer_http_client_t *p_client); /** * DESC: diff --git a/components/clouds/dueros/lightduer/include/lightduer_http_client_ops.h b/components/clouds/dueros/lightduer/include/lightduer_http_client_ops.h index 89e7b55..8e2aef2 100755 --- a/components/clouds/dueros/lightduer/include/lightduer_http_client_ops.h +++ b/components/clouds/dueros/lightduer/include/lightduer_http_client_ops.h @@ -21,9 +21,16 @@ #ifndef BAIDU_DUER_LIGHTDUER_INCLUDE_LIGHTDUER_HTTP_CLIENT_OPS_H #define BAIDU_DUER_LIGHTDUER_INCLUDE_LIGHTDUER_HTTP_CLIENT_OPS_H - +#ifdef __cplusplus +extern "C" { +#endif #include "lightduer_http_client.h" extern duer_http_client_t *duer_create_http_client(void); +extern void duer_destory_http_client(duer_http_client_t *client); + +#ifdef __cplusplus +} +#endif #endif // BAIDU_DUER_LIGHTDUER_INCLUDE_LIGHTDUER_HTTP_CLIENT_OPS_H diff --git a/components/clouds/dueros/lightduer/include/lightduer_http_dns_client_ops.h b/components/clouds/dueros/lightduer/include/lightduer_http_dns_client_ops.h old mode 100644 new mode 100755 diff --git a/components/clouds/dueros/lightduer/include/lightduer_log.h b/components/clouds/dueros/lightduer/include/lightduer_log.h index f346dbb..2961f3f 100755 --- a/components/clouds/dueros/lightduer/include/lightduer_log.h +++ b/components/clouds/dueros/lightduer/include/lightduer_log.h @@ -32,44 +32,58 @@ #ifdef DUER_DEBUG_LEVEL #define DUER_DEBUG_EXT(_l, _f, _li, ...) duer_debug(_l, _f, _li, __VA_ARGS__) +#define DUER_DUMP_EXT(_l, _f, _li, _tag, _data, _size) duer_dump(_l, _f, _li, _tag, _data, _size) #else #define DUER_DEBUG_EXT(...) +#define DUER_DUMP_EXT(...) #endif #if defined(DUER_DEBUG_LEVEL) && (DUER_DEBUG_LEVEL >= 5) #define DUER_LOGV_EXT(_f, _l, ...) DUER_DEBUG_EXT(5, _f, _l, __VA_ARGS__) +#define DUER_DUMPV_EXT(_f, _l, ...) DUER_DUMP_EXT(5, _f, _l, __VA_ARGS__) #else #define DUER_LOGV_EXT(...) +#define DUER_DUMPV_EXT(...) #endif #if defined(DUER_DEBUG_LEVEL) && (DUER_DEBUG_LEVEL >= 4) #define DUER_LOGD_EXT(_f, _l, ...) DUER_DEBUG_EXT(4, _f, _l, __VA_ARGS__) +#define DUER_DUMPD_EXT(_f, _l, ...) DUER_DUMP_EXT(4, _f, _l, __VA_ARGS__) #else #define DUER_LOGD_EXT(...) +#define DUER_DUMPD_EXT(...) #endif #if defined(DUER_DEBUG_LEVEL) && (DUER_DEBUG_LEVEL >= 3) #define DUER_LOGI_EXT(_f, _l, ...) DUER_DEBUG_EXT(3, _f, _l, __VA_ARGS__) +#define DUER_DUMPI_EXT(_f, _l, ...) DUER_DUMP_EXT(3, _f, _l, __VA_ARGS__) #else #define DUER_LOGI_EXT(...) +#define DUER_DUMPI_EXT(...) #endif #if defined(DUER_DEBUG_LEVEL) && (DUER_DEBUG_LEVEL >= 2) #define DUER_LOGW_EXT(_f, _l, ...) DUER_DEBUG_EXT(2, _f, _l, __VA_ARGS__) +#define DUER_DUMPW_EXT(_f, _l, ...) DUER_DUMP_EXT(2, _f, _l, __VA_ARGS__) #else #define DUER_LOGW_EXT(...) +#define DUER_DUMPW_EXT(...) #endif #if defined(DUER_DEBUG_LEVEL) && (DUER_DEBUG_LEVEL >= 1) #define DUER_LOGE_EXT(_f, _l, ...) DUER_DEBUG_EXT(1, _f, _l, __VA_ARGS__) +#define DUER_DUMPE_EXT(_f, _l, ...) DUER_DUMP_EXT(1, _f, _l, __VA_ARGS__) #else #define DUER_LOGE_EXT(...) +#define DUER_DUMPE_EXT(...) #endif #if defined(DUER_DEBUG_LEVEL) && (DUER_DEBUG_LEVEL >= 0) #define DUER_LOGWTF_EXT(_f, _l, ...) DUER_DEBUG_EXT(0, _f, _l, __VA_ARGS__) +#define DUER_DUMPWTF_EXT(_f, _l, ...) DUER_DUMP_EXT(0, _f, _l, __VA_ARGS__) #else #define DUER_LOGWTF_EXT(...) +#define DUER_DUMPWTF_EXT(...) #endif #define DUER_DEBUG(_l, ...) DUER_DEBUG_EXT(_l, __FILE__, __LINE__, __VA_ARGS__) @@ -80,4 +94,12 @@ #define DUER_LOGE(...) DUER_LOGE_EXT(__FILE__, __LINE__, __VA_ARGS__) #define DUER_LOGWTF(...) DUER_LOGWTF_EXT(__FILE__, __LINE__, __VA_ARGS__) +#define DUER_DUMP(_l, ...) DUER_DUMP_EXT(_l, __FILE__, __LINE__, __VA_ARGS__) +#define DUER_DUMPV(...) DUER_DUMPV_EXT(__FILE__, __LINE__, __VA_ARGS__) +#define DUER_DUMPD(...) DUER_DUMPD_EXT(__FILE__, __LINE__, __VA_ARGS__) +#define DUER_DUMPI(...) DUER_DUMPI_EXT(__FILE__, __LINE__, __VA_ARGS__) +#define DUER_DUMPW(...) DUER_DUMPW_EXT(__FILE__, __LINE__, __VA_ARGS__) +#define DUER_DUMPE(...) DUER_DUMPE_EXT(__FILE__, __LINE__, __VA_ARGS__) +#define DUER_DUMPWTF(...) DUER_DUMPWTF_EXT(__FILE__, __LINE__, __VA_ARGS__) + #endif/*LIBDUER_DEVICE_FRAMEWORK_CORE_LIGHTDUER_LOG_H*/ diff --git a/components/clouds/dueros/lightduer/include/lightduer_memory.h b/components/clouds/dueros/lightduer/include/lightduer_memory.h index 7934fec..438170c 100755 --- a/components/clouds/dueros/lightduer/include/lightduer_memory.h +++ b/components/clouds/dueros/lightduer/include/lightduer_memory.h @@ -23,14 +23,52 @@ #include "lightduer_types.h" #include "lightduer_lib.h" +#ifdef DUER_HEAP_MONITOR +#ifndef DUER_MEMORY_USAGE +#define DUER_MEMORY_USAGE // DUER_HEAP_MONITOR rely on this +#endif +#ifndef DUER_HM_MODULE_NAME +#error "DUER_HM_MODULE_NAME should be defined if the heapmonitor function needed" +// #else +// #define STR_HELPER(x) #x +// #define STR(x) STR_HELPER(x) +// #error #DUER_HM_MODULE_NAME +// #warning "error:"##DUER_HM_MODULE_NAME +#endif + +#undef HM_KEYWORD +#define HM_KEYWORD(symbol) symbol, + +typedef enum _duer_memory_hm_module_e { + DUER_MEMORY_HM_MIN = 0, +#include "lightduer_memory_hm_keywords.h" + DUER_MEMORY_HM_MAX, +} duer_memory_hm_module_e; + +#endif // DUER_HEAP_MONITOR + #ifdef DUER_MEMORY_USAGE +#ifndef DUER_HEAP_MONITOR DUER_INT void duer_memdbg_usage(); #define DUER_MEMDBG_USAGE(...) duer_memdbg_usage() #else +#ifdef DUER_HEAP_MONITOR_DEBUG +DUER_INT void duer_memdbg_usage(); +#define DUER_MEMDBG_USAGE(...) duer_memdbg_usage() +#else // DUER_HEAP_MONITOR_DEBUG +#define DUER_MEMDBG_USAGE(...) +#endif // DUER_HEAP_MONITOR_DEBUG +#endif +#else #define DUER_MEMDBG_USAGE(...) #endif -#ifdef DUER_MEMORY_DEBUG +#if defined(DUER_HEAP_MONITOR) +#define DUER_MALLOC(_s) duer_malloc_hm(_s, DUER_HM_MODULE_NAME) +#define DUER_CALLOC(_s, _n) duer_calloc_hm((_s) * (_n), DUER_HM_MODULE_NAME) +#define DUER_REALLOC(_p, _s) duer_realloc_hm(_p, _s, DUER_HM_MODULE_NAME) +#define DUER_FREE(_p) duer_free_hm(_p) +#elif DUER_MEMORY_DEBUG #define DUER_MALLOC(_s) duer_malloc_ext(_s, __FILE__, __LINE__) #define DUER_CALLOC(_s, _n) duer_calloc_ext((_s) * (_n), __FILE__, __LINE__) #define DUER_REALLOC(_p, _s) duer_realloc_ext(_p, _s, __FILE__, __LINE__) @@ -40,7 +78,7 @@ DUER_INT void duer_memdbg_usage(); #define DUER_CALLOC(_s, _n) duer_calloc((_s) * (_n)) #define DUER_REALLOC(_p, _s) duer_realloc(_p, _s) #define DUER_FREE(_p) duer_free(_p) -#endif/*DUER_MEMORY_DEBUG*/ +#endif/*DUER_HEAP_MONITOR*/ @@ -72,37 +110,67 @@ DUER_EXT void baidu_ca_memory_init(duer_context context, duer_free_f f_free); /* - * malloc function + * uninit the memory operations in baidu_ca_memory_init. + */ +DUER_EXT void baidu_ca_memory_uninit(void); + +/* + * malloc function for bjson * * @Param size, duer_size_t, the expected size of the memory * @Return the alloced memory pointer */ -DUER_INT void* duer_malloc(duer_size_t size); +DUER_INT void* duer_malloc_bjson(duer_size_t size); + +/* + * free function bjson + * + * @Param ptr, void *, the alloced memory + */ +DUER_INT void duer_free_bjson(void* ptr); + +#if defined(DUER_HEAP_MONITOR) + +DUER_INT void baidu_ca_memory_hm_init(void); + +DUER_INT void baidu_ca_memory_hm_destroy(void); + +/* + * malloc function for heap monitor + * + * @Param size, duer_size_t, the expected size of the memory + * @Param module, duer_memory_hm_module_e, the tag for where the memroy used + * @Return the alloced memory pointer + */ +DUER_INT void* duer_malloc_hm(duer_size_t size, duer_memory_hm_module_e module); /* * cmalloc function zero-initialize the memory before return * * @Param size, duer_size_t, the expected size of the memory + * @Param module, duer_memory_hm_module_e, the tag for where the memroy used * @Return the alloced memory pointer */ -DUER_INT void* duer_calloc(duer_size_t size); +DUER_INT void* duer_calloc_hm(duer_size_t size, duer_memory_hm_module_e module); /* * realloc function * * @Param ptr, void *, the old alloced memory * @Param size, duer_size_t, the expected size of the memory + * @Param module, duer_memory_hm_module_e, the tag for where the memroy used * @Return the new alloced memory pointer */ -DUER_INT void* duer_realloc(void* ptr, duer_size_t size); +DUER_INT void* duer_realloc_hm(void* ptr, duer_size_t size, duer_memory_hm_module_e module); /* * free function * * @Param ptr, void *, the alloced memory */ -DUER_INT void duer_free(void* ptr); +DUER_INT void duer_free_hm(void* ptr); +#else /* * malloc function * @@ -144,6 +212,40 @@ DUER_INT void* duer_realloc_ext(void* ptr, duer_size_t size, const char* file, */ DUER_INT void duer_free_ext(void* ptr, const char* file, duer_u32_t line); +/* + * malloc function + * + * @Param size, duer_size_t, the expected size of the memory + * @Return the alloced memory pointer + */ +DUER_INT void* duer_malloc(duer_size_t size); + +/* + * cmalloc function zero-initialize the memory before return + * + * @Param size, duer_size_t, the expected size of the memory + * @Return the alloced memory pointer + */ +DUER_INT void* duer_calloc(duer_size_t size); + +/* + * realloc function + * + * @Param ptr, void *, the old alloced memory + * @Param size, duer_size_t, the expected size of the memory + * @Return the new alloced memory pointer + */ +DUER_INT void* duer_realloc(void* ptr, duer_size_t size); + +/* + * free function + * + * @Param ptr, void *, the alloced memory + */ +DUER_INT void duer_free(void* ptr); + +#endif + #ifdef __cplusplus } #endif diff --git a/components/clouds/dueros/lightduer/include/lightduer_memory_hm_keywords.h b/components/clouds/dueros/lightduer/include/lightduer_memory_hm_keywords.h new file mode 100755 index 0000000..7d0162b --- /dev/null +++ b/components/clouds/dueros/lightduer/include/lightduer_memory_hm_keywords.h @@ -0,0 +1,59 @@ +/** + * Copyright (2017) Baidu Inc. All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +// Author: zhangleliang(zhangleliang@baidu.com) +// +// Description: definition about the heap monitor module +#ifdef DUER_HEAP_MONITOR +#ifdef HM_KEYWORD + HM_KEYWORD(DUER_HM_DUER_DEVICE) + HM_KEYWORD(DUER_HM_PLATFORM) + HM_KEYWORD(DUER_HM_PORT_LPT230) + HM_KEYWORD(DUER_HM_PORT_LPB100) + HM_KEYWORD(DUER_HM_PORT_LINUX) + HM_KEYWORD(DUER_HM_PORT_FREERTOS) + HM_KEYWORD(DUER_HM_FLASH_STRINGS) + HM_KEYWORD(DUER_HM_CONNAGENT) + HM_KEYWORD(DUER_HM_DCS) + HM_KEYWORD(DUER_HM_DEVICE_STATUS) + HM_KEYWORD(DUER_HM_DEVICE_INFO) + HM_KEYWORD(DUER_HM_HTTP) + HM_KEYWORD(DUER_HM_NTP) + HM_KEYWORD(DUER_HM_BIND_DEVICE) + HM_KEYWORD(DUER_HM_VOICE_ENGINE) + HM_KEYWORD(DUER_HM_COAP) + HM_KEYWORD(DUER_HM_SYSTEM_INFO) + HM_KEYWORD(DUER_HM_INTERACTIVE_CLASS) + HM_KEYWORD(DUER_HM_OTA) + HM_KEYWORD(DUER_HM_DCS3_LINUX_DEMO) + HM_KEYWORD(DUER_HM_TRACKER) + HM_KEYWORD(DUER_HM_LINUX_DEMO) + HM_KEYWORD(DUER_HM_SPEEX_ENCODER) + HM_KEYWORD(DUER_HM_FRAMEWORK) + HM_KEYWORD(DUER_HM_MBEDTLS) + HM_KEYWORD(DUER_HM_NSDL) + HM_KEYWORD(DUER_HM_CJSON) + HM_KEYWORD(DUER_HM_DEVICE_VAD) + HM_KEYWORD(DUER_HM_SPEEX) + HM_KEYWORD(DUER_HM_ZLIBLITE) + HM_KEYWORD(DUER_HM_MBED) + HM_KEYWORD(DUER_HM_SONIC_CODEC) + HM_KEYWORD(DUER_HM_SMARTCONFIG) + HM_KEYWORD(DUER_HM_DATA_PARSER) +#else +#error "define HM_KEYWORD is needed if use heap monitor function" +#endif +#endif + diff --git a/components/clouds/dueros/lightduer/include/lightduer_net_trans_aes_cbc_encrypted.h b/components/clouds/dueros/lightduer/include/lightduer_net_trans_aes_cbc_encrypted.h index f3ee8ac..7cfa170 100755 --- a/components/clouds/dueros/lightduer/include/lightduer_net_trans_aes_cbc_encrypted.h +++ b/components/clouds/dueros/lightduer/include/lightduer_net_trans_aes_cbc_encrypted.h @@ -76,6 +76,12 @@ DUER_INT duer_status_t duer_trans_aes_cbc_encrypted_recv(duer_trans_ptr trans, duer_size_t size, duer_addr_t* addr); +DUER_INT duer_status_t duer_trans_aes_cbc_encrypted_recv_timeout(duer_trans_ptr trans, + void* data, + duer_size_t size, + duer_u32_t timeout, + duer_addr_t* addr); + /* * Disconnect from the remote host. * diff --git a/components/clouds/dueros/lightduer/include/lightduer_net_trans_encrypted.h b/components/clouds/dueros/lightduer/include/lightduer_net_trans_encrypted.h index 8393cab..40f1c62 100755 --- a/components/clouds/dueros/lightduer/include/lightduer_net_trans_encrypted.h +++ b/components/clouds/dueros/lightduer/include/lightduer_net_trans_encrypted.h @@ -74,6 +74,12 @@ DUER_INT duer_status_t duer_trans_encrypted_recv(duer_trans_ptr trans, duer_size_t size, duer_addr_t* addr); + +DUER_INT duer_status_t duer_trans_encrypted_recv_timeout(duer_trans_ptr trans, + void* data, + duer_size_t size, + duer_u32_t timeout, + duer_addr_t* addr); /* * Disconnect from the remote host. * diff --git a/components/clouds/dueros/lightduer/include/lightduer_net_transport.h b/components/clouds/dueros/lightduer/include/lightduer_net_transport.h index a3abcf9..0aea0ab 100755 --- a/components/clouds/dueros/lightduer/include/lightduer_net_transport.h +++ b/components/clouds/dueros/lightduer/include/lightduer_net_transport.h @@ -52,6 +52,7 @@ typedef struct _duer_trans_s { duer_u32_t read_timeout; duer_addr_t addr; const void *key_info; + duer_bool is_encrypted; #ifdef NET_TRANS_ENCRYPTED_BY_AES_CBC unsigned char received_header[DUER_SIZEOF_TCPHEADER]; // header info duer_size_t received_header_bytes; // received header bytes[0-DUER_SIZEOF_TCPHEADER] diff --git a/components/clouds/dueros/lightduer/include/lightduer_net_transport_wrapper.h b/components/clouds/dueros/lightduer/include/lightduer_net_transport_wrapper.h index 0cc4b42..43ab019 100755 --- a/components/clouds/dueros/lightduer/include/lightduer_net_transport_wrapper.h +++ b/components/clouds/dueros/lightduer/include/lightduer_net_transport_wrapper.h @@ -47,6 +47,13 @@ DUER_INT duer_status_t duer_trans_set_pk(duer_trans_handler hdlr, const void* data, duer_size_t size); +/* + * clear the public key or certificate, release the buffer + * + * @Param hdlr, in, the context for the transport + */ +DUER_INT duer_status_t duer_trans_unset_pk(duer_trans_handler hdlr); + /* * Set the timeout for receiving data. * @@ -95,6 +102,11 @@ DUER_INT duer_status_t duer_trans_recv(duer_trans_handler hdlr, duer_size_t size, duer_addr_t* addr); + +DUER_INT duer_status_t duer_trans_recv_timeout(duer_trans_handler hdlr, + void* data, + duer_size_t size, + duer_addr_t* addr); /* * Disconnect from the remote host. * diff --git a/components/clouds/dueros/lightduer/include/lightduer_notifier.h b/components/clouds/dueros/lightduer/include/lightduer_notifier.h new file mode 100755 index 0000000..b3d2573 --- /dev/null +++ b/components/clouds/dueros/lightduer/include/lightduer_notifier.h @@ -0,0 +1,149 @@ +/** + * Copyright (2017) Baidu Inc. All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/* + * File: lightduer_notifier.h + * Auth: Zhong Shuai (zhongshuai@baidu.com) + * Desc: Notifier Head file + */ + +#ifndef BAIDU_DUER_LIGHTDUER_INCLUDE_LIGHTDUER_NOTIFIER_H +#define BAIDU_DUER_LIGHTDUER_INCLUDE_LIGHTDUER_NOTIFIER_H + +#include +#include "lightduer_mutex.h" + +#define DUER_NOTIFY_STOP_MASK 0x80 /* Don't call further */ + +#define DUER_NOTIFY_DONE 0x00 /* Don't care */ +#define DUER_NOTIFY_OK 0x01 /* Suits me */ +#define DUER_NOTIFY_BAD (DUER_NOTIFY_STOP_MASK | 0x02) /* Bad/Veto action */ + +#ifdef __cplusplus +extern "C" { +#endif + +struct duer_notifier_block; + +typedef int (*notifier_func)(struct duer_notifier_block *nb, + uint32_t val, void *data); + +typedef struct duer_notifier_block { + notifier_func notifier_call; + int priority; + struct duer_notifier_block *next; +} duer_notifier_block_t; + +typedef struct duer_notifier_block_head { + duer_mutex_t lock; + struct duer_notifier_block *head; +} duer_notifier_block_head_t; + +/* + * Create a notifier to receive the message + * + * @param void: + * + * @return pointer: Success: Pointer to duer_notifier_block_t + * Failed: NULL + */ +extern duer_notifier_block_t *duer_notifier_create_notifier(void); + +/* + * Destroy a notifier + * + * @param pointer to a notifier + * + * @return void: + */ +extern void duer_notifier_destroy_notifier(duer_notifier_block_t *notifier); + +/* + * Create a notifier chain to send the message + * + * @param void: + * + * @return pointer: Success: Pointer to duer_notifier_block_head_t + * Failed: NULL + */ +extern duer_notifier_block_head_t *duer_notifier_create_notifier_chain(void); + +/* + * Destroy a notifier chain + * + * @param pointer to duer_notifier_block_head_t + * + * @return int: Success: DUER_OK + * Failed: DUER_ERR_FAILED + */ +extern int duer_notifier_destroy_notifier_chain(duer_notifier_block_head_t *head); + +/* + * Register a notifier to a notifier chain + * + * @param pointer to duer_notifier_block_head_t + * @param pointer to duer_notifier_block_t + * + * @return int: Success: DUER_OK + * Failed: DUER_ERR_FAILED + */ +extern int duer_notifier_register( + duer_notifier_block_head_t *head, + duer_notifier_block_t *notifier); + +/* + * Unregister a notifier from a notifier chain + * + * @param pointer to duer_notifier_block_head_t + * pointer to duer_notifier_block_t + * + * @return int: Success: DUER_OK + * Failed: DUER_ERR_FAILED + */ +extern int duer_notifier_unregister( + duer_notifier_block_head_t *head, + duer_notifier_block_t *notifier); + +/** + * Send message to single notifier + * + * @param notifier: single notifier + * val: the input data + * data: the output data + * + * @return int: DUER_NOTIFY_ value + * + */ +int duer_notifier_call(duer_notifier_block_t *notifier, uint32_t val, void *data); + +/* + * Send message to the notifier + * + * @param pointer to duer_notifier_block_head_t + * val: the message + * data: which you can receive the message from the notifier + * + * @return int: Success: DUER_NOTIFY_OK || DUER_NOTIFY_DONE + * Failed: DUER_NOTIFY_BAD + */ +extern int duer_notifier_call_chain( + duer_notifier_block_head_t *head, + uint32_t val, void *data); + +#ifdef __cplusplus +} +#endif + +#endif // BAIDU_DUER_LIGHTDUER_INCLUDE_LIGHTDUER_NOTIFIER_H diff --git a/components/clouds/dueros/lightduer/include/lightduer_ota_decompress.h b/components/clouds/dueros/lightduer/include/lightduer_ota_decompress.h deleted file mode 100755 index 0e3126d..0000000 --- a/components/clouds/dueros/lightduer/include/lightduer_ota_decompress.h +++ /dev/null @@ -1,92 +0,0 @@ -/* - * Copyright (2017) Baidu Inc. All rights reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - * File: lightduer_ota_decompress.h - * Auth: Zhong Shuai (zhongshuai@baidu.com) - * Desc: OTA decompress head file - */ - -#ifndef BAIDU_DUER_LIGHTDUER_INCLUDE_LIGHTDUER_OTA_DECOMPRESS_H -#define BAIDU_DUER_LIGHTDUER_INCLUDE_LIGHTDUER_OTA_DECOMPRESS_H - -#include -#include "zlib.h" -#include "lightduer_ota_pack_info.h" -#include "lightduer_ota_installer.h" - -#ifdef __cplusplus -extern "C" { -#endif - -typedef struct _duer_decompress_context_s { - uint32_t stream_recieved_sz; // current size of recieved stream - uint32_t stream_processed_sz; // current size of processed stream - - // cache meta data - uint32_t meta_size; - uint32_t meta_stored_size; - char *meta_data; - - //module data write offset - uint32_t write_offset; - - // zlib stream object - z_streamp strmp; -} duer_ota_decompress_context_t; - -/* - * Init zlibstream - * - * @param void - * - * @return decompress context - */ -void *duer_ota_unpack_zlibstream_decompress_init(void); - -/* - * Decompress data - * - * @param verify_cxt: verify context - * @param ctx: decompress context - * @param buffer: data to decompress - * @param buffer_size: buffer size - * @param updater: OTA installer object - * @param update_cxt: private data - * - * @return: Success: 0 - * Failed: Other - */ -int duer_ota_unpack_zlibstream_decompress_process( - void *verify_cxt, - duer_ota_decompress_context_t *ctx, - unsigned char *buffer, - uint32_t buffer_size, - duer_ota_installer_t *installer, - void *update_cxt); - -/* - * Uninit zlibstream - * - * @param ctx: decompress context - * - * @return void - */ -void duer_ota_unpack_zlibstream_decompress_uninit(duer_ota_decompress_context_t *ctx); - -#ifdef __cplusplus -} -#endif - -#endif // BAIDU_DUER_LIGHTDUER_INCLUDE_LIGHTDUER_OTA_DECOMPRESS_H diff --git a/components/clouds/dueros/lightduer/include/lightduer_ota_decompression.h b/components/clouds/dueros/lightduer/include/lightduer_ota_decompression.h new file mode 100755 index 0000000..c153235 --- /dev/null +++ b/components/clouds/dueros/lightduer/include/lightduer_ota_decompression.h @@ -0,0 +1,232 @@ +/** + * Copyright (2017) Baidu Inc. All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/* + * File: lightduer_ota_decompression.h + * Auth: Zhong Shuai (zhongshuai@baidu.com) + * Desc: OTA decompression abstraction layer header file + */ + +#ifndef BAIDU_DUER_LIGHTDUER_INCLUDE_LIGHTDUER_OTA_DECOMPRESSION_H +#define BAIDU_DUER_LIGHTDUER_INCLUDE_LIGHTDUER_OTA_DECOMPRESSION_H + +#include +#include "lightduer_mutex.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#define NAME_LENGTH (20) +#define ERR_MSG_LEN (60) + +typedef enum _duer_ota_decompression_type_s { + ZLIB = 0, + DECOMPRESSION_MAX = 1, +} duer_ota_decompress_type_t; + +typedef int (*DECOMPRESS_DATA_HANDLER_FUN)(void *custom_data, char const *buf, size_t len); + +typedef struct _duer_ota_unpacker_decom_s { + char name[NAME_LENGTH + 1]; + duer_mutex_t lock; + void *pdata; + char err_msg[ERR_MSG_LEN + 1]; + int (*init)(struct _duer_ota_unpacker_decom_s *decompression, void **pdata); + int (*unzip)( + struct _duer_ota_unpacker_decom_s *decompression, + void *pdata, + char const *compressed_data, + size_t data_size, + void *custom_data, + DECOMPRESS_DATA_HANDLER_FUN data_handler); + int (*recovery)(struct _duer_ota_unpacker_decom_s *decompression, void *pdata); + int (*sync)(struct _duer_ota_unpacker_decom_s *decompression, void *pdata); + int (*unint)(struct _duer_ota_unpacker_decom_s *decompression, void *pdata); +} duer_ota_decompression_t; + +/* + * Initialize decompression module + * + * @param void: + * + * @return: Success: DUER_OK + * Failed: Other + */ +extern int duer_ota_init_decompression(void); + +/* + * Create a decompression object + * + * @param name: the name of decompression + * + * @return: Success: duer_ota_decompression_t * + * Failed: NULL + */ +extern duer_ota_decompression_t *duer_ota_unpacker_create_decompression(char const *name); + +/* + * Get decompression object + * + * @param name: the name of decompression + * + * @return: Success: duer_ota_decompression_t * + * Failed: NULL + */ +extern duer_ota_decompression_t *duer_ota_unpacker_get_decompression( + duer_ota_decompress_type_t type); + +/* + * Destroy decompression object + * + * @param void: + * + * @return: Success: duer_ota_decompression_t * + * Failed: NULL + */ +extern int duer_ota_unpacker_destroy_decompression(duer_ota_decompression_t *decompression); + +/* + * Get decompression name + * + * @param decompression: decompression object + * + * @return: Success: char const * + * Failed: NULL + */ +extern const char *duer_ota_unpacker_get_decompression_name( + duer_ota_decompression_t const *decompression); + +/* + * Register a decompression library + * + * @param decompression: decompression object + * type: decompression library type + * + * @return: Success: DUER_OK + * Failed: Other + */ +extern int duer_ota_unpacker_register_decompression( + duer_ota_decompression_t *decompression, + duer_ota_decompress_type_t type); + +/* + * Unregister a decompression library + * + * @param type: decompression library type + * + * @return: Success: DUER_OK + * Failed: Other + */ +extern int duer_ota_unpacker_unregister_decompression(duer_ota_decompress_type_t type); + +/* + * Initialize decompression + * + * @param decompression: decompression object + * + * @return: Success: DUER_OK + * Failed: Other + */ +extern int duer_ota_unpacker_init_decompression(duer_ota_decompression_t *decompression); + +/* + * Unzip data + * + * @param decompression: decompression object + * compressed_data: compressed data + * compressed_data_size: size of corpressed data + * unpacker: Unpacker object + * data_handler: A function which receive the decompressed data + * + * @return: Success: DUER_OK + * Failed: Other + */ +extern int duer_ota_unpacker_unzip( + duer_ota_decompression_t *decompression, + char const *compressed_data, + size_t compressed_data_size, + void *custom_data, + DECOMPRESS_DATA_HANDLER_FUN data_handler); + +/* + * Uninitialize decompression + * + * @param decompression: decompression object + * + * @return: Success: DUER_OK + * Failed: Other + */ +extern int duer_ota_unpacker_uninit_decompression(duer_ota_decompression_t *decompression); + +/* + * Try to repair data + * + * @param decompression: decompression object + * + * @return: Success: DUER_OK + * Failed: Other + */ +extern int duer_ota_unpacker_recovery_decompression(duer_ota_decompression_t *decompression); + +/* + * Synchronous data + * + * @param decompression: decompression object + * + * @return: Success: DUER_OK + * Failed: Other + */ +extern int duer_ota_unpacker_sync_decompression(duer_ota_decompression_t *decompression); + +/* + * Report error message + * + * @param decompression: OTA Decompression + * err_msg: error message + * err_code: error code + * + * @return void: + */ +extern void duer_ota_decompression_report_err( + duer_ota_decompression_t *decompression, + char const *err_msg, + int err_code); +/* + * Get decompression error message + * + * @param decompression: decompression object + * + * @return: Success: error message + * Failed: NULL + */ +extern char const *duer_ota_decompression_get_err_msg( + duer_ota_decompression_t const *decompression); + +/* + * Check wheater the error message exists + * + * @param decompression: decompression object + * + * @return: Success: 1 + * Failed: -1 + */ +extern int duer_ota_decompression_check_err_msg(duer_ota_decompression_t *decompression); + +#ifdef __cplusplus +} +#endif + +#endif // BAIDU_DUER_LIGHTDUER_INCLUDE_LIGHTDUER_OTA_DECOMPRESSION_H diff --git a/components/clouds/dueros/lightduer/include/lightduer_ota_downloader.h b/components/clouds/dueros/lightduer/include/lightduer_ota_downloader.h old mode 100644 new mode 100755 index 68491e5..8bf8118 --- a/components/clouds/dueros/lightduer/include/lightduer_ota_downloader.h +++ b/components/clouds/dueros/lightduer/include/lightduer_ota_downloader.h @@ -29,6 +29,8 @@ #define URL_LEN 301 #endif +#define ERR_MSG_LEN (60) + typedef enum _duer_downloader_Protocol { HTTP = 0, COAP = 1, @@ -42,6 +44,7 @@ typedef struct _duer_ota_downloader_s { duer_mutex_t lock; char url[URL_LEN + 1]; struct _duer_ota_downloader_ops_s *ops; + char err_msg[ERR_MSG_LEN]; } duer_ota_downloader_t ; typedef int (*data_handler)( @@ -226,4 +229,37 @@ extern int duer_ota_downloader_set_private_data( */ extern void *duer_ota_downloader_get_private_data(duer_ota_downloader_t *downloader); +/* + * Report error message + * + * @param downloader: OTA Downloader + * err_msg: error message + * err_code: error code + * + * @return void: + */ +extern void duer_ota_downloader_report_err( + duer_ota_downloader_t *downloader, + char const *err_msg, + int err_code); +/* + * Get error message + * + * @param downloader: downloader object + * + * @return: Success: error message + * Failed: NULL + */ +extern char const *duer_ota_downloader_get_err_msg(duer_ota_downloader_t const *downloader); + +/* + * Check wheater the error message exists + * + * @param downloader: downloader object + * + * @return: Success: 1 + * Failed: -1 + */ +extern int duer_ota_downloader_check_err_msg(duer_ota_downloader_t *downloader); + #endif // BAIDU_DUER_LIGHTDUER_INCLUDE_LIGHTDUER_OTA_DOWNLOADER_H diff --git a/components/clouds/dueros/lightduer/include/lightduer_ota_installer.h b/components/clouds/dueros/lightduer/include/lightduer_ota_installer.h index 2192da4..3adcf6d 100755 --- a/components/clouds/dueros/lightduer/include/lightduer_ota_installer.h +++ b/components/clouds/dueros/lightduer/include/lightduer_ota_installer.h @@ -1,4 +1,4 @@ -/* +/** * Copyright (2017) Baidu Inc. All rights reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -12,113 +12,292 @@ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. - * + */ +/* * File: lightduer_ota_installer.h * Auth: Zhong Shuai (zhongshuai@baidu.com) - * Desc: OTA installer head file + * Desc: OTA installer Head File */ #ifndef BAIDU_DUER_LIGHTDUER_INCLUDE_LIGHTDUER_OTA_INSTALLER_H #define BAIDU_DUER_LIGHTDUER_INCLUDE_LIGHTDUER_OTA_INSTALLER_H -#define PACKAGE_NAME_LENGTH_MAX (15) -#define PACKAGE_TYPE_OS (1) -#define PACKAGE_TYPE_APP (2) -#define PACKAGE_NO_UPDATE (0) -#define PACKAGE_UPDATE (1) - -typedef struct _duer_meta_data_basic_info_s { - char package_name[PACKAGE_NAME_LENGTH_MAX + 1]; - unsigned char package_type; - unsigned char package_update; -} duer_ota_meta_data_basic_info_t; - -#define MODULE_NAME_LENGTH_MAX (PACKAGE_NAME_LENGTH_MAX) -#define MODULE_VERSION_LENGTH_MAX (15) -#define HARDWARE_VERSION_LENGTH_MAX (15) -#define MODULE_SIGNATURE_LENGTH (33) -#define MODULE_TYPE_BIN (1) -#define MODULE_NO_UPDATE (0) -#define MODULE_UPDATE (1) - -typedef struct _duer_module_info_s { - char module_name[MODULE_NAME_LENGTH_MAX + 1]; - char module_version[MODULE_VERSION_LENGTH_MAX + 1]; - char module_support_hw_version[HARDWARE_VERSION_LENGTH_MAX + 1]; - unsigned char module_signature[MODULE_SIGNATURE_LENGTH]; - unsigned int module_size; - unsigned char module_type; - unsigned char module_update; -} duer_ota_module_info_t; - -#define PACKAGE_INSTALL_PATH_MAX (255) -typedef struct _duer_meta_data_install_info_s { - char package_install_path[PACKAGE_INSTALL_PATH_MAX + 1]; - unsigned int module_count; - duer_ota_module_info_t *module_list; -} duer_ota_meta_data_install_info_t; - -#define PACKAGE_VERSION_LENGTH MODULE_VERSION_LENGTH_MAX -typedef struct _duer_meta_data_update_info_s { - char package_version[PACKAGE_VERSION_LENGTH]; -} duer_ota_meta_data_update_info_t; - -typedef struct _duer_meta_data_extension_s { - unsigned int pair_count; - char **keys; - char **values; -} duer_ota_meta_data_extension_t; - -typedef struct _duer_package_meta_data_s { - duer_ota_meta_data_basic_info_t basic_info; - duer_ota_meta_data_install_info_t install_info; - duer_ota_meta_data_update_info_t update_info; - duer_ota_meta_data_extension_t extension_info; -} duer_ota_package_meta_data_t; +#include "lightduer_mutex.h" +#include "lightduer_ota_package_info.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#define ERR_MSG_LEN (60) +#define INSTALLER_NAME_LEN 20 typedef struct _duer_ota_installer_s { + // The name of OTA installer + char name[INSTALLER_NAME_LEN + 1]; + // The customer data + void *custom_data; + // Lock the installer + duer_mutex_t lock; + // Last Error message + char err_msg[ERR_MSG_LEN + 1]; + /* - * You can open do someting before receive data - * Such as open file, Initialise Flash, Initialise DMA ... + * You can get module information */ - int (*notify_data_begin)(void *cxt); + int (*get_module_info)( + struct _duer_ota_installer_s *installer, + void **custom_data, + duer_ota_module_info_t const *module_info); /* - * You can get install information from meta param - * If you want to use this, Call me + * Now we notify you, we are ready to start OTA + * You can do someting before receive data + * Such as open file, Initialise Flash, Initialise DMA, check chip ... */ - int (*notify_meta_data)(void *cxt, duer_ota_package_meta_data_t *meta); + int (*notify_ota_begin)(struct _duer_ota_installer_s *installer, void *custom_data); + + /* + * You can free the resource which you use in notify_ota_begin + * Set the boot partition ... + */ + int (*notify_ota_end)(struct _duer_ota_installer_s *installer, void *custom_data); /* * You can get the file which you upload to Duer Cloud */ - int (*notify_module_data)( - void *cxt, + int (*get_module_data)( + struct _duer_ota_installer_s *installer, + void *custom_data, unsigned int offset, - unsigned char *data, - unsigned int size); + unsigned char const *data, + size_t size); /* - * You can do some thing after you get the file - * Such as close file, free resource + * You can verify the data you received */ - int (*notify_data_end)(void *cxt); + int (*verify_module_data)(struct _duer_ota_installer_s *installer, void *custom_data); /* * You can do someting before update the firmware * Such as Erase Flash ... */ - int (*update_img_begin)(void *cxt); + int (*update_image_begin)(struct _duer_ota_installer_s *installer, void *custom_data); /* - * Burn the new firmware to the Flash + * Update the new firmware */ - int (*update_img)(void *cxt); + int (*update_image)(struct _duer_ota_installer_s *installer, void *custom_data); /* * You can check the new firmware, and select the boot partition */ - int (*update_img_end)(void *cxt); + int (*verify_image)(struct _duer_ota_installer_s *installer, void *custom_data); + + /* + * Cancel the OTA update, free the resources and revert + */ + int (*cancel_ota_update)(struct _duer_ota_installer_s *installer, void *custom_data); + + struct _duer_ota_installer_s *next; } duer_ota_installer_t; +/* + * Initialise OTA installer module + * + * @param void + * + * @return int: Success: DUER_OK + * Failed: Other + */ +extern int duer_ota_init_installer(void); + +/* + * Get the customr data + * + * @param installer: OTA installer + * + * @return void *: Success: void * + * Failed: NULL + */ +extern void *duer_ota_installer_get_custom_data(duer_ota_installer_t const *installer); + +/* + * Create a OTA installer + * + * @param name: The name of installer + * + * @return int: Success: duer_ota_installer_t * + * Failed: NULL + */ +extern duer_ota_installer_t *duer_ota_installer_create_installer(char const *name); + +/* + * Destory a OTA installer + * + * @param installer: OTA installer + * + * @return int: Success: DUER_OK + * Failed: Other + */ +extern int duer_ota_installer_destroy_installer(duer_ota_installer_t *installer); + +/* + * Register a OTA installer + * + * @param installer: OTA installer + * + * @return int: Success: DUER_OK + * Failed: Other + */ +extern int duer_ota_installer_register_installer(duer_ota_installer_t *installer); + +/* + * Unregister a OTA installer + * + * @param name : The name of the OTA installer + * + * @return int: Success: DUER_OK + * Failed: Other + */ +extern int duer_ota_installer_unregister_installer(char const *name); + +/* + * Get the OTA installer by name + * + * @param name : The name of the OTA installer + * + * @return int: Success: duer_ota_installer_t * + * Failed: NULL + */ +extern duer_ota_installer_t *duer_ota_installer_get_installer(char const *name); + +/* + * Notify OTA installer data begin + * + * @param installer: OTA installer + * + * @return int: Success: DUER_OK + * Failed: Other + */ +extern int duer_ota_installer_notify_ota_begin(duer_ota_installer_t *installer); + +/* + * Notify OTA installer the module information + * + * @param installer: OTA installer + * @param module_info: module information + * + * @return int: Success: DUER_OK + * Failed: Other + */ +extern int duer_ota_installer_send_module_info( + duer_ota_installer_t *installer, + duer_ota_module_info_t const *module_info); + +/* + * Send OTA installer the module data + * + * @param installer: OTA installer + * @param offset: The offset of the image + * @param data: OTA image data + * @param size The size of OTA image data + * + * @return int: Success: DUER_OK + * Failed: Other + */ +extern int duer_ota_installer_send_module_data( + duer_ota_installer_t *installer, + unsigned int offset, + unsigned char const *data, + size_t size); + +/* + * Verify the module data + * + * @param installer: OTA installer + * + * @return int: Success: DUER_OK + * Failed: Other + */ +extern int duer_ota_installer_verify_module_data(duer_ota_installer_t *installer); + +/* + * Notify OTA installer bigin to update OTA image + * + * @param installer: OTA installer + * + * @return int: Success: DUER_OK + * Failed: Other + */ +extern int duer_ota_installer_update_image_begin(duer_ota_installer_t *installer); + +/* + * Notify OTA installer to update OTA image + * + * @param installer: OTA installer + * + * @return int: Success: DUER_OK + * Failed: Other + */ +extern int duer_ota_installer_update_image(duer_ota_installer_t *installer); + +/* + * Notify OTA installer to verify OTA image + * + * @param installer: OTA installer + * + * @return int: Success: DUER_OK + * Failed: Other + */ +extern int duer_ota_installer_verify_image(duer_ota_installer_t *installer); + +/* + * Notify OTA installer to end the OTA update + * + * @param installer: OTA installer + * + * @return int: Success: DUER_OK + * Failed: Other + */ +extern int duer_ota_installer_notify_ota_end(duer_ota_installer_t *installer); + +/* + * Cancel the OTA update + * + * @param installer: OTA installer + * + * @return int: Success: DUER_OK + * Failed: Other + */ +extern int duer_ota_installer_cancel_ota_update(duer_ota_installer_t *installer); + +/* + * Report error message + * + * @param installer: OTA installer + * err_msg: error message + * err_code: error code + * + * @return void: + */ +extern void duer_ota_installer_report_err( + duer_ota_installer_t *installer, + char const *err_msg, + int err_code); + +/* + * Get error message + * + * @param installer: OTA installer + * + * @return : Success: error message + * Failed: NULL + */ +extern const char *duer_ota_installer_get_err_msg(duer_ota_installer_t const *installer); + +#ifdef __cplusplus +} +#endif + #endif // BAIDU_DUER_LIGHTDUER_INCLUDE_LIGHTDUER_OTA_INSTALLER_H diff --git a/components/clouds/dueros/lightduer/include/lightduer_ota_local_downloader.h b/components/clouds/dueros/lightduer/include/lightduer_ota_local_downloader.h old mode 100644 new mode 100755 diff --git a/components/clouds/dueros/lightduer/include/lightduer_ota_notifier.h b/components/clouds/dueros/lightduer/include/lightduer_ota_notifier.h old mode 100644 new mode 100755 index c849b60..0d63a49 --- a/components/clouds/dueros/lightduer/include/lightduer_ota_notifier.h +++ b/components/clouds/dueros/lightduer/include/lightduer_ota_notifier.h @@ -32,7 +32,7 @@ extern "C" { #define NAME_LEN 24 #define BATCH_LEN 4 -#define OTA_PROTOCOL_VERSION "0.9" +#define OTA_PROTOCOL_VERSION "1.0" typedef enum _duer_ota_state { OTA_IDLE = 0, @@ -79,6 +79,8 @@ typedef struct _duer_package_info_s { char product[NAME_LEN + 1]; char batch[BATCH_LEN + 1]; duer_os_info_t os_info; + char duer_os_sdk_version[FIRMWARE_VERSION_LEN + 1]; + char ota_package_version[FIRMWARE_VERSION_LEN + 1]; } duer_package_info_t; typedef struct _duer_package_info_ops_s { @@ -113,7 +115,7 @@ extern int duer_ota_get_package_info(duer_package_info_t *info); * @return int: Success: DUER_OK * Failed: Other */ -extern int duer_ota_register_package_info_ops(duer_package_info_ops_t *ops); +extern int duer_ota_register_package_info_ops(duer_package_info_ops_t const *ops); /* * Notifier the OTA state to Duer Cloud @@ -125,7 +127,7 @@ extern int duer_ota_register_package_info_ops(duer_package_info_ops_t *ops); * @return int: Success: DUER_OK * Failed: Other */ -extern int duer_ota_notifier_state(duer_ota_updater_t *updater, duer_ota_state state); +extern int duer_ota_notifier_state(duer_ota_updater_t const *updater, duer_ota_state state); /* * Notifier OTA event to Duer Cloud @@ -141,10 +143,10 @@ extern int duer_ota_notifier_state(duer_ota_updater_t *updater, duer_ota_state s * Failed: Other */ extern int duer_ota_notifier_event( - duer_ota_updater_t *updater, + duer_ota_updater_t const *updater, duer_ota_event event, double progress, - const char *desc); + char const *desc); #ifdef __cplusplus } diff --git a/components/clouds/dueros/lightduer/include/lightduer_ota_pack_info.h b/components/clouds/dueros/lightduer/include/lightduer_ota_pack_info.h deleted file mode 100755 index d0726a0..0000000 --- a/components/clouds/dueros/lightduer/include/lightduer_ota_pack_info.h +++ /dev/null @@ -1,100 +0,0 @@ -/* - * Copyright (2017) Baidu Inc. All rights reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - * File: lightduer_ota_pack_info.h - * Auth: Zhong Shuai (zhongshuai@baidu.com) - * Desc: OTA pack include head file - */ - -#ifndef BAIDU_DUER_LIGHTDUER_INCLUDE_LIGHTDUER_OTA_PACK_INFO_H -#define BAIDU_DUER_LIGHTDUER_INCLUDE_LIGHTDUER_OTA_PACK_INFO_H - -#include -#include "lightduer_log.h" - -#define KEY_LEN 128 - -#define _DEBUG_ - -// package header -typedef struct _duer_package_header_s { - // 'mbed' verify tag - unsigned char tag[4]; - // package header size - uint32_t header_size; - // package signature size : 1024 bits - uint32_t package_sig_size; - // package signature : include meta.json and all modules - unsigned char package_sig[KEY_LEN]; - // meta.json signature size : 1024 bits - uint32_t meta_sig_size; - // meta.json signature - unsigned char meta_sig[KEY_LEN]; - // meta.json size : used for decompress meta.json from package body - uint32_t meta_size; - // package size before decompress - uint32_t ori_package_size; -} duer_ota_package_header_t; - -// all modules included in mbed package is 'js' and mbed executable '.bin' file -typedef enum _duer_module_type { - ModuleTypeALL, - ModuleTypeJS, - ModuleTypeSO, - ModuleTypeBIN, - ModuleTypeJSON, - ModuleTypeIMG -} duer_ota_module_type_t; - -typedef struct _duer_file_type_pair_s { - char *string; - duer_ota_module_type_t type; -} duer_ota_file_type_t; - - -typedef enum _duer_package_type { - PackageTypeApp, - PackageTypeOS, - PackageTypeProfile, - PackageTypeUnknown -} duer_ota_package_type_t; - -typedef struct _duer_pack_module_info_s { - - // module name : xx.js / xx.bin - unsigned char *name; - // module type : js / bin - duer_ota_module_type_t type; - uint32_t module_size; - uint8_t update; - unsigned char *version; - unsigned char *hw_version; - // offset from file begin - uint32_t offset; -} duer_ota_unpack_module_info_t; - -// meta info : used for extract meta data and modules array data -typedef struct _duer_meta_info_s { - // decompressed meta data size - uint32_t meta_data_size; - // decompressed module data offset - uint32_t module_data_offset; - // decompressed meta data - unsigned char *meta_data; - // json object - void *meta_object; -} duer_ota_meta_info_t; - -#endif // BAIDU_DUER_LIGHTDUER_INCLUDE_LIGHTDUER_OTA_PACK_INFO_H diff --git a/components/clouds/dueros/lightduer/include/lightduer_ota_package_api.h b/components/clouds/dueros/lightduer/include/lightduer_ota_package_api.h deleted file mode 100755 index 48bfe36..0000000 --- a/components/clouds/dueros/lightduer/include/lightduer_ota_package_api.h +++ /dev/null @@ -1,105 +0,0 @@ -/* - * Copyright (2017) Baidu Inc. All rights reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - * File: lightduer_ota_package_api.h - * Auth: Zhong Shuai (zhongshuai@baidu.com) - * Desc: OTA package api head file - */ - -#ifndef BAIDU_DUER_LIGHTDUER_INCLUDE_LIGHTDUER_OTA_PACKAGE_API_H -#define BAIDU_DUER_LIGHTDUER_INCLUDE_LIGHTDUER_OTA_PACKAGE_API_H - -#include -#include "lightduer_ota_pack_info.h" - -#ifdef __cplusplus -extern "C" { -#endif - -/* - * Init verification - * - * @param void - * - * @return verification context if success, or NULL - */ -void *duer_ota_unpack_verification_init(void); - -/* - * verification update context - * - * @param ctx: verification context - * @param buffer: data to update context - * @param buffer:_size data size - * - * @return void - */ -void duer_ota_unpack_verification_update_ctx( - void *ctx, - unsigned char *buffer, - uint32_t buffer_size); - -/* - * Verify - * - * @param ctx: verification context - * - * @return 0 if success, or fail - */ -int duer_ota_unpack_verification(void *ctx); - -/* - * Init decompress - * - * @param void - * - * @return void *:decompress context - */ -void *duer_ota_unpack_decompress_init(void); - -/* - * Process compressed data - * - * @param verify_cxt: verification context - * @param ctx: decompress context - * @param buffer: data to decompress - * @param buffer_size: buffer size - * @param installer: OTA installer - * @param update_cxt: private data - * - * @return 0 success ,other failed - */ -int duer_ota_unpack_decompress_process( - void *verify_cxt, - void *ctx, - unsigned char *buffer, - uint32_t buffer_size, - duer_ota_installer_t *installer, - void *update_cxt); - -/* - * Uninit decompress - * - * @param ctx: decompress context - * - * @return void - */ -void duer_ota_unpack_decompress_uninit(void *ctx); - -#ifdef __cplusplus -} -#endif - -#endif // BAIDU_DUER_LIGHTDUER_INCLUDE_LIGHTDUER_OTA_PACKAGE_API_H diff --git a/components/clouds/dueros/lightduer/include/lightduer_ota_package_info.h b/components/clouds/dueros/lightduer/include/lightduer_ota_package_info.h new file mode 100755 index 0000000..a33a5a6 --- /dev/null +++ b/components/clouds/dueros/lightduer/include/lightduer_ota_package_info.h @@ -0,0 +1,110 @@ +/** + * Copyright (2017) Baidu Inc. All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/* + * File: lightduer_ota_package_info.h + * Auth: Zhong Shuai (zhongshuai@baidu.com) + * Desc: OTA Package Information Head File + */ + +#include +#include +#include + +#ifndef BAIDU_DUER_LIGHTDUER_INCLUDE_LIGHTDUER_OTA_PACKAGE_INFO_H +#define BAIDU_DUER_LIGHTDUER_INCLUDE_LIGHTDUER_OTA_PACKAGE_INFO_H + +#define KEY_LEN (128) +#define PACKAGE_NAME_LENGTH (15) +#define META_VERSION_LENGTH (3) +#define PACKAGE_VERSION_LENGTH (15) +#define INSTALL_PATH_LENGTH (255) +#define MODULE_NAME_LENGTH (15) +#define MODULE_VERSION_LENGTH (15) +#define MODULE_SIGNATURE_LENGTH (33) + +#ifdef __cplusplus +extern "C" { +#endif + +typedef enum _duer_ota_package_type_s { + PACKAGE_TYPE_OS, // Operation system + PACKAGE_TYPE_APP, // Application + PACKAGE_TYPE_FIRMWARE, // Chip firmware + PACKAGE_TYPE_MIXED, // MIXED +} duer_ota_package_type_t; + +typedef enum _duer_ota_module_type_s { + MODULE_TYPE_BIN, + MODULE_TYPE_IMG, + MODULE_TYPE_JSON, + MODULE_TYPE_SO, +} duer_ota_module_type_t; + +// package header +typedef struct _duer_ota_package_header_s { + // 'mbed' verify tag + uint8_t tag[4]; + // package header size + uint32_t package_header_size; + // package signature size: 1024 bits + uint32_t package_signature_size; + // package signature: include meta.json and all modules + unsigned char package_signature[KEY_LEN]; + // meta.json signature size: 1024 bits + uint32_t meta_signature_size; + // meta.json signature + unsigned char meta_signature[KEY_LEN]; + // meta.json size: used for decompress meta.json from package body + uint32_t meta_size; + // size of meta.json + all modules (before compress) + uint32_t ori_package_size; +} duer_ota_package_header_t; + +typedef struct _duer_ota_package_basic_info_s { + uint8_t package_name[PACKAGE_NAME_LENGTH + 1]; + uint8_t meta_version[META_VERSION_LENGTH + 1]; + duer_ota_package_type_t package_type; + // Enforce the update + bool update; +} duer_ota_package_basic_info_t; + +typedef struct _duer_ota_module_info_s { + uint8_t module_name[MODULE_NAME_LENGTH + 1]; + uint32_t module_size; + duer_ota_module_type_t module_type; + // Enforce the update + bool update; + uint8_t module_signature[MODULE_SIGNATURE_LENGTH + 1]; + uint8_t module_version[MODULE_VERSION_LENGTH + 1]; + uint8_t module_support_hardware_version[MODULE_VERSION_LENGTH + 1]; + uint8_t module_install_path[INSTALL_PATH_LENGTH + 1]; +} duer_ota_module_info_t; + +typedef struct _duer_ota_package_install_info_s { + uint8_t package_install_path[INSTALL_PATH_LENGTH + 1]; + uint8_t module_count; + duer_ota_module_info_t *module_list; +} duer_ota_package_install_info_t; + +typedef struct _duer_ota_update_info_s { + uint8_t package_version[PACKAGE_VERSION_LENGTH + 1]; +} duer_ota_update_info_t; + +#ifdef __cplusplus +} +#endif + +#endif // BAIDU_DUER_LIGHTDUER_INCLUDE_LIGHTDUER_OTA_PACKAGE_INFO_H diff --git a/components/clouds/dueros/lightduer/include/lightduer_ota_unpack.h b/components/clouds/dueros/lightduer/include/lightduer_ota_unpack.h deleted file mode 100755 index 81cfe3c..0000000 --- a/components/clouds/dueros/lightduer/include/lightduer_ota_unpack.h +++ /dev/null @@ -1,165 +0,0 @@ -/* - * Copyright (2017) Baidu Inc. All rights reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - * File: lightduer_ota_unpack.h - * Auth: Zhong Shuai (zhongshuai@baidu.com) - * Desc: OTA Unpack Head File - */ - -#ifndef BAIDU_DUER_LIGHTDUER_INCLUDE_LIGHTDUER_OTA_UNPACK_H -#define BAIDU_DUER_LIGHTDUER_INCLUDE_LIGHTDUER_OTA_UNPACK_H - -#include -#include -#include "lightduer_mutex.h" -#include "lightduer_ota_installer.h" - -#ifdef __cplusplus -extern "C" { -#endif - -typedef struct _duer_ota_unpacker_s { - void *private_data; // Which you want to pass to callback functions - void *verification; - void *decompress; - duer_ota_installer_t *installer; - duer_mutex_t lock; -} duer_ota_unpacker_t; - -/* - * Create a unpacker - * Now it can supports zliblite to adaptive to Duer Cloud - * We can refactor it to support multi-decompressor - * - * @param void: - * - * @return duer_ota_unpacker_t *: Success: Other - * Failed: NULL - */ -extern duer_ota_unpacker_t *duer_ota_unpack_create_unpacker(void); - -/* - * Destroy a unpacker - * - * @param unpacker: duer_ota_unpacker_t object - * - * @return void: - */ -extern void duer_ota_unpack_destroy_unpacker(duer_ota_unpacker_t *unpacker); - -/* - * Register installer to a unpacker, to receive uncompressed data ..... - * - * @param unpacker: duer_ota_unpacker_t object - * - * @param installer: update operations - * - * @return int: Success: DUER_OK - * Failed: Other - */ -extern int duer_ota_unpack_register_installer(duer_ota_unpacker_t *unpacker, duer_ota_installer_t *installer); - -/* - * Get private data - * - * @param unpacker: duer_ota_unpacker_t object - * - * @return void *: Success: Other - * Failed: NULL - */ -extern void *duer_ota_unpack_get_private_data(duer_ota_unpacker_t *unpacker); - -/* - * Set private data - * - * @param unpacker: duer_ota_unpacker_t object - * - * @param private: Data which you wang to pass - * - * @return int: Success: DUER_OK - * Failed: Other - */ -extern int duer_ota_unpack_set_private_data(duer_ota_unpacker_t *unpacker, void *private_data); - -/* - * Call it before you decompress data - * - * @param unpacker: duer_ota_unpacker_t object - * - * @return int: Success: DUER_OK - * Failed: Other - */ -extern int duer_ota_unpack_decompress_data_begin(duer_ota_unpacker_t *unpacker); - -/* - * Pass the compressed data to it, it will decompress the data. - * and send the decompressed data to you - * - * @param unpacker: duer_ota_unpacker_t object - * - * @param data: compressed data - * - * @param size: the size of data - * - * @return int: Success: DUER_OK - * Failed: Other - */ -extern int duer_ota_unpack_decompress_data(duer_ota_unpacker_t *unpacker, unsigned char *data, size_t size); - -/* - * Call it when you finish decompressing the data - * - * @param unpacker: duer_ota_unpacker_t object - * - * @return int: Success: DUER_OK - * Failed: Other - */ -extern int duer_ota_unpack_decompress_data_end(duer_ota_unpacker_t *unpacker); - -/* - * Call it before you update firmware - * - * @param unpacker: duer_ota_unpacker_t object - * - * @return int: Success: DUER_OK - * Failed: Other - */ -extern int duer_ota_unpack_update_image_begin(duer_ota_unpacker_t *unpacker); - -/* - * Call it when you want to update firmware - * - * @param unpacker: duer_ota_unpacker_t object - * - * @return int: Success: DUER_OK - * Failed: Other - */ -extern int duer_ota_unpack_update_image(duer_ota_unpacker_t *unpacker); - -/* - * Call it after you finished updating firmware - * - * @param unpacker: duer_ota_unpacker_t object - * - * @return int: Success: DUER_OK - * Failed: Other - */ -extern int duer_ota_unpack_update_image_end(duer_ota_unpacker_t *unpacker); - -#ifdef __cplusplus -} -#endif - -#endif // BAIDU_DUER_LIGHTDUER_INCLUDE_LIGHTDUER_OTA_UNPACK_H diff --git a/components/clouds/dueros/lightduer/include/lightduer_ota_unpacker.h b/components/clouds/dueros/lightduer/include/lightduer_ota_unpacker.h new file mode 100755 index 0000000..202abf3 --- /dev/null +++ b/components/clouds/dueros/lightduer/include/lightduer_ota_unpacker.h @@ -0,0 +1,204 @@ +/** + * Copyright (2017) Baidu Inc. All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/* + * File: lightduer_ota_unpacker.h + * Auth: Zhong Shuai (zhongshuai@baidu.com) + * Desc: OTA unpacker Head File + */ + +#include +#include +#include +#include "lightduer_ota_verifier.h" +#include "lightduer_ota_installer.h" +#include "lightduer_ota_package_info.h" +#include "lightduer_ota_decompression.h" + +#ifndef BAIDU_DUER_LIGHTDUER_INCLUDE_LIGHTDUER_OTA_UNPACKER_H +#define BAIDU_DUER_LIGHTDUER_INCLUDE_LIGHTDUER_OTA_UNPACKER_H + +#define ERR_MSG_LEN (60) + +#ifdef __cplusplus +extern "C" { +#endif + +typedef enum _duer_ota_unpack_mode_s { + SAVE_PACKAGE_HEADER = 1, + PARSE_PACKAGE_HEADER = 2, + SAVE_META_DATA = 3, + UNZIP_DATA = 4, + UNZIP_DATA_DONE = 5, + PARSE_META_DATA = 6, + GET_OTA_INSTALLER = 7, + UNZIP_MODLE_INFO = 8, + UNZIP_MODLE_DATA = 9, + NOTIFY_OTA_BEGIN = 10, + NOTIFY_OTA_END = 11, + DISTRIBUTE_MODULE_INFO = 12, + DISTRIBUTE_MODULE_DATA = 13, + VERIFY_MODULE_DATA = 14, + PUBLIC_KEY_VERIFICATION = 15, + UPDATE_IMAGE_BEGIN = 16, + UPDATE_IMAGE = 17, + VERIFY_IMAGE = 18, + OTA_UPDATE_DONE = 19, + CANCEL_OTA_UPDATE = 20, + UNPACKER_MODE_MAX = 21, +} duer_ota_unpacker_mode_t; + +typedef struct _duer_ota_unpack_state_s { + duer_ota_unpacker_mode_t mode; + size_t received_data_size; + size_t processed_data_size; + size_t decompress_data_size; + size_t used_decompress_data_offset; + size_t used_data_offset; + size_t meta_data_offset; + size_t module_data_offset; + size_t package_header_data_offset; +} duer_ota_unpack_state_t; + +typedef struct _duer_ota_unpacker_s { + // Lock the unpacker + duer_mutex_t lock; + duer_ota_verifier_t *verifier; + duer_ota_unpack_state_t state; + duer_ota_package_header_t package_header; + duer_ota_package_basic_info_t basic_info; + duer_ota_package_install_info_t install_info; + void *meta_data; + duer_ota_decompression_t *decompression; + duer_ota_installer_t *installer; + char err_msg[ERR_MSG_LEN]; +} duer_ota_unpacker_t; + +/* + * Create a OTA unpacker + * + * @param void: + * + * @return: Success: duer_ota_unpacker_t * + * Failed: NULL + */ +extern duer_ota_unpacker_t *duer_ota_unpacker_create_unpacker(void); + +/* + * Destroy a OTA unpacker + * + * @param unpacker: OTA unpacker + * + * @return int: Success: DUER_OK + * Failed: Other + */ +extern int duer_ota_unpacker_destroy_unpacker(duer_ota_unpacker_t *unpacker); + + +/* + * Initialize a OTA unpacker + * + * @param unpacker: OTA unpacker + * + * @return int: Success: DUER_OK + * Failed: Other + */ +extern int duer_ota_unpacker_init_unpacker(duer_ota_unpacker_t *unpacker); + +/* + * Get the basic information of the package + * + * @param unpacker: OTA unpacker + * + * @return : Success:duer_ota_package_basic_info_t * + * Failed: NULL + */ +extern duer_ota_package_basic_info_t const *duer_ota_unpacker_get_package_basic_info( + duer_ota_unpacker_t const *unpacker); + +/* + * Get the header information of the package + * + * @param unpacker: OTA unpacker + * + * @return : Success: duer_ota_package_header_t * + * Failed: NULL + */ +extern duer_ota_package_header_t const *duer_ota_unpacker_get_package_header_info( + duer_ota_unpacker_t const *unpacker); + +/* + * Unpacke a OTA upadate package + * + * @param unpacker: OTA unpacker + * data: data of the package + * size: data size + * + * @return int: Success: DUER_OK + * Failed: Other + */ +extern int duer_ota_unpacker_unpack_package( + duer_ota_unpacker_t *unpacker, + uint8_t const *data, + size_t size); + +/* + * Set the unpacker mode + * + * @param unpacker: OTA unpacker + * mode: Unpacker mode + * + * @return int: Success: DUER_OK + * Failed: Other + */ +extern int duer_ota_unpacker_set_unpacker_mode( + duer_ota_unpacker_t *unpacker, + duer_ota_unpacker_mode_t mode); + +/* + * Get the unpacker mode + * + * @param unpacker: OTA unpacker + * + * @return mode: Unpacker mode + */ +extern duer_ota_unpacker_mode_t duer_ota_unpacker_get_unpacker_mode( + duer_ota_unpacker_t const *unpacker); + +/* + * Get the unpacker error message + * + * @param unpacker: OTA unpacker + * + * @return char const *: Success: error message + * Failed: NULL + */ +extern char const *duer_ota_unpacker_get_err_msg(duer_ota_unpacker_t const *unpacker); + +/* + * Check wheater the error message exists + * + * @param unpacker: unpacker object + * + * @return: Success: 1 + * Failed: -1 + */ +extern int duer_ota_unpacker_check_err_msg(duer_ota_unpacker_t *unpacker); + +#ifdef __cplusplus +} +#endif + +#endif // BAIDU_DUER_LIGHTDUER_INCLUDE_LIGHTDUER_OTA_UNPACKER_H diff --git a/components/clouds/dueros/lightduer/include/lightduer_ota_updater.h b/components/clouds/dueros/lightduer/include/lightduer_ota_updater.h old mode 100644 new mode 100755 index d9920f6..a10faf1 --- a/components/clouds/dueros/lightduer/include/lightduer_ota_updater.h +++ b/components/clouds/dueros/lightduer/include/lightduer_ota_updater.h @@ -22,7 +22,7 @@ #ifndef BAIDU_DUER_LIGHTDUER_INCLUDE_LIGHTDUER_OTA_UPDATER_H #define BAIDU_DUER_LIGHTDUER_INCLUDE_LIGHTDUER_OTA_UPDATER_H -#include "lightduer_ota_unpack.h" +#include "lightduer_ota_unpacker.h" #include "lightduer_ota_downloader.h" #include "mbedtls/md5.h" @@ -59,22 +59,21 @@ typedef struct _duer_ota_updater_s { duer_ota_unpacker_t *unpacker; duer_ota_downloader_t *downloader; duer_ota_update_command_t *update_cmd; - size_t received_data_size; + int received_data_size; + int progress; mbedtls_md5_context md5_ctx; } duer_ota_updater_t; typedef struct _duer_ota_init_ops_s { /* - * You need to call duer_ota_unpack_register_updater() - * to implement duer_ota_installer_t in init_updater callback function - * Call duer_ota_unpack_set_private_data() to set your privater data + * Call duer_ota_installer_register_installer() to register the + * OTA installer */ - int (*init_updater)(duer_ota_updater_t *updater); + int (*register_installer)(void); /* - * You can free the resource which you create in init_updater callback function - * + * Unregister OTA installer */ - int (*uninit_updater)(duer_ota_updater_t *updater); + int (*unregister_installer)(void); /* * Implement reboot system function */ @@ -91,7 +90,7 @@ typedef void (*OTA_Updater)(int arg, void *update_cmd); * @return int: Success: DUER_OK * Failed: Other */ -extern int duer_init_ota(duer_ota_init_ops_t *ops); +extern int duer_init_ota(duer_ota_init_ops_t const *ops); /* * User Call it to enable/disable OTA @@ -136,12 +135,12 @@ extern int duer_ota_get_reboot(void); /* * get the OTA update command * - * @param void: duer_ota_updater_t * + * @param void: * - * @return Success: duer_ota_update_command_t* + * @return Success: duer_ota_update_command_t const * * Failed: NULL */ -extern duer_ota_update_command_t *duer_ota_get_update_cmd(const duer_ota_updater_t *updater); +extern duer_ota_update_command_t const *duer_ota_get_update_cmd(void); /* * Create a OTA updater to update the firmware @@ -151,7 +150,7 @@ extern duer_ota_update_command_t *duer_ota_get_update_cmd(const duer_ota_updater * @return int: Success: DUER_OK * Failed: Other */ -extern int duer_ota_update_firmware(duer_ota_update_command_t *update_cmd); +extern int duer_ota_update_firmware(duer_ota_update_command_t const *update_cmd); #ifdef __cplusplus } diff --git a/components/clouds/dueros/lightduer/include/lightduer_ota_verification.h b/components/clouds/dueros/lightduer/include/lightduer_ota_verification.h deleted file mode 100755 index 52deb9b..0000000 --- a/components/clouds/dueros/lightduer/include/lightduer_ota_verification.h +++ /dev/null @@ -1,107 +0,0 @@ -/* - * Copyright (2017) Baidu Inc. All rights reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - * File: lightduer_ota_verification.h - * Auth: Zhong Shuai (zhongshuai@baidu.com) - * Desc: OTA verification head file - */ - -#ifndef BAIDU_DUER_LIGHTDUER_INCLUDE_LIGHTDUER_OTA_VERIFICATION_H -#define BAIDU_DUER_LIGHTDUER_INCLUDE_LIGHTDUER_OTA_VERIFICATION_H - -#include "mbedtls/rsa.h" -#include "mbedtls/sha1.h" -#include "lightduer_ota_pack_info.h" - -#ifdef __cplusplus -extern "C" { -#endif - -typedef struct _verification_context_ { - // internal footprint - uint32_t stream_recieved_sz; // current size of recieved stream - uint32_t stream_processed_sz; // current size of processed stream - uint32_t stream_sig_stored_sz; // size of pck_header_sig_part - unsigned char *pck_header_sig_part; // package header buffer to pck signature(include), - // for verify use - // sha1 context - mbedtls_sha1_context *ctx; -} verification_context_t; - -/* - * Init rsa context - * - * @param rsa_ctx: point to an instance of mbedtls_rsa_context struct - * - * @return 0 if success, or failed - */ -int duer_ota_unpack_rsa_ca_pkcs1_init(mbedtls_rsa_context *rsa_ctx); - -/* - * Uinit rsa context - * - * @param rsa_ctx: point to an instance of mbedtls_rsa_context struct - * - * @return void - */ -void duer_ota_unpack_rsa_ca_pkcs1_uninit(mbedtls_rsa_context *rsa_ctx); - -/* - * Init verification - * - * @param void - * - * @return verification_context_t *: verification context if success, or NULL - */ -verification_context_t *duer_ota_unpack_hash_init(void); - -/* - * Update verification key - * - * @param ctx: verification context - * @param buffer: data source to gen hash - * @param buffer_size: the size of buffer - * - * @return void - */ -void duer_ota_unpack_hash_update_key( - verification_context_t *ctx, - unsigned char *buffer, - uint32_t buffer_size); - -/* - * Verify key - * - * @param rsa: RSA context - * @param ctx: verification context - * - * @return 0 if success, or failed - */ -int duer_ota_rsa_ca_pkcs1_verify(mbedtls_rsa_context *rsa, verification_context_t *ctx); - -/* - * Uninit verification - * - * @param ctx: verification context - * - * @return void - */ -void duer_ota_unpack_hash_uninit(verification_context_t *ctx); - -#ifdef __cplusplus -} -#endif - -#endif // BAIDU_DUER_LIGHTDUER_INCLUDE_LIGHTDUER_OTA_VERIFICATION_H diff --git a/components/clouds/dueros/lightduer/include/lightduer_ota_verifier.h b/components/clouds/dueros/lightduer/include/lightduer_ota_verifier.h new file mode 100755 index 0000000..a9590e0 --- /dev/null +++ b/components/clouds/dueros/lightduer/include/lightduer_ota_verifier.h @@ -0,0 +1,120 @@ +/** + * Copyright (2017) Baidu Inc. All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/* + * File: lightduer_ota_verification.h + * Auth: Zhong Shuai (zhongshuai@baidu.com) + * Desc: OTA Verification Head File + */ + +#ifndef BAIDU_DUER_LIGHTDUER_INCLUDE_LIGHTDUER_OTA_VERIFICATION_H +#define BAIDU_DUER_LIGHTDUER_INCLUDE_LIGHTDUER_OTA_VERIFICATION_H + +#include "mbedtls/md5.h" +#include "mbedtls/rsa.h" +#include "mbedtls/sha1.h" +#include "lightduer_ota_package_info.h" + +#define ERR_MSG_LEN (60) + +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct _duer_ota_verifier_s { + mbedtls_rsa_context rsa; + mbedtls_sha1_context sha1; + char err_msg[ERR_MSG_LEN + 1]; +} duer_ota_verifier_t; + +/* + * Create a OTA verifier + * + * @param void: + * + * @return: Success: duer_ota_verifier_t * + * Failed: NULL + */ +extern duer_ota_verifier_t *duer_ota_verification_create_verifier(void); + +/* + * Initialize a OTA verifier + * + * @param void: + * + * @return: Success: DUER_OK + * Failed: Other + */ +extern int duer_ota_verification_init_verifier(duer_ota_verifier_t *verifier); + +/* + * Destroy a OTA verifier + * + * @param verifier: duer_ota_verifier_t * + * + * @return void: + */ +extern void duer_ota_verification_destroy_verifier(duer_ota_verifier_t *verifier); + +/* + * Verify data + * + * @param verifier: duer_ota_verifier_t * + * data: uint8_t * + * size: size_t + * + * @return void: + */ +extern void duer_ota_verification_update( + duer_ota_verifier_t *verifier, + uint8_t const *data, + size_t size); + +/* + * Verify the OTA package + * + * @param verify: duer_ota_verifier_t * + * header: Heare information + * + * @return: Success: DUER_OK + * Failed: Other + */ +extern int duer_ota_verification_verify(duer_ota_verifier_t *verifier, duer_ota_package_header_t const *header); + +/* + * Get verofoer error message + * + * @param verify: duer_ota_verifier_t * + * + * @return: Success: error message + * Failed: NULL + */ +extern char const *duer_ota_verification_get_err_msg(duer_ota_verifier_t const *verifier); + +/* + * Check wheater the error message exists + * + * @param verifier: verifier object + * + * @return: Success: 1 + * Failed: -1 + */ +extern int duer_ota_verification_check_err_msg(duer_ota_verifier_t *verifier); + +#ifdef __cplusplus +} +#endif + +#endif // BAIDU_DUER_LIGHTDUER_INCLUDE_LIGHTDUER_OTA_VERIFICATION_H diff --git a/components/clouds/dueros/lightduer/include/lightduer_ota_zlib.h b/components/clouds/dueros/lightduer/include/lightduer_ota_zlib.h new file mode 100755 index 0000000..677b428 --- /dev/null +++ b/components/clouds/dueros/lightduer/include/lightduer_ota_zlib.h @@ -0,0 +1,43 @@ +/** + * Copyright (2017) Baidu Inc. All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/* + * File: lightduer_ota_zlib.h + * Auth: Zhong Shuai (zhongshuai@baidu.com) + * Desc: OTA Zlib header file + */ + +#ifndef BAIDU_DUER_LIGHTDUER_INCLUDE_LIGHTDUER_OTA_ZLIB_H +#define BAIDU_DUER_LIGHTDUER_INCLUDE_LIGHTDUER_OTA_ZLIB_H + +#ifdef __cplusplus +extern "C" { +#endif + +/* + * Initialize Zliblite + * + * @param void: + * + * @return: Success: DUER_OK + * Failed: Other + */ +extern int duer_ota_init_zlib(void); + +#ifdef __cplusplus +} +#endif + +#endif // BAIDU_DUER_LIGHTDUER_INCLUDE_LIGHTDUER_OTA_ZLIB_H diff --git a/components/clouds/dueros/lightduer/include/lightduer_pm_dev.h b/components/clouds/dueros/lightduer/include/lightduer_pm_dev.h new file mode 100755 index 0000000..4ee5a3a --- /dev/null +++ b/components/clouds/dueros/lightduer/include/lightduer_pm_dev.h @@ -0,0 +1,249 @@ +/** + * Copyright (2017) Baidu Inc. All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/* + * File: lightduer_pm_dev.h + * Auth: Chang Li (changli@baidu.com) + * Desc: PM Device Head file + */ + +#ifndef BAIDU_DUER_LIGHTDUER_INCLUDE_LIGHTDUER_PM_DEV_H +#define BAIDU_DUER_LIGHTDUER_INCLUDE_LIGHTDUER_PM_DEV_H + +#include +#include "lightduer_mutex.h" + +#define DEV_NAME_LEN 32 + +#ifdef __cplusplus +extern "C" { +#endif + +typedef enum duer_pm_dev_state { + PM_ST_NORMAL, + PM_ST_IDLE, + PM_ST_SUSPEND, + PM_ST_SUSPENDING, + PM_ST_RESUME, + PM_ST_RESUMEING, + PM_ST_POWER_OFF, + MAX_PM_STATE, +} duer_pm_dev_state_t; + +typedef enum duer_pm_dev_type { + PM_DEV_CODEC, + PM_DEV_LED, + PM_DEV_PA, + PM_DEV_WIFI, + PM_DEV_DSP, + MAX_PM_DEV_TYPE, +} duer_pm_dev_type_t; + +typedef struct duer_pm_device { + char name[DEV_NAME_LEN + 1]; + duer_mutex_t lock; + duer_pm_dev_type_t dev_type; + duer_pm_dev_state_t pm_state; + uint16_t user_cnt; + uint32_t suspend_target_time; + uint32_t power_off_target_time; + uint32_t normal_timestamp; + uint32_t prepare_suspend_timestamp; + uint32_t suspend_timestamp; + uint32_t prepare_poweroff_timestamp; + uint32_t poweroff_timestamp; + uint32_t pm_state_duration; + int (*enter_pm_state)(duer_pm_dev_state_t state); + struct duer_pm_device *next; +} duer_pm_device_t; + +typedef struct duer_pm_device_list { + duer_mutex_t list_lock; + duer_pm_device_t *list_head; +} duer_pm_device_list_t; + +typedef struct duer_init_pm_ops { + int (*register_pm_dev_func)(void); + int (*start_policy)(void); +} duer_init_pm_ops_t; + +typedef int (*treatment_dev_func)(duer_pm_device_t *dev); + +/* + * Initialize Power Managerment module + * + * @param pointer to duer_init_pm_ops_t + * + * @return int: Success: DUER_OK + * Failed: DUER_ERR_FAILED + */ +extern int duer_init_pm(const duer_init_pm_ops_t *init_ops); + +/* + * Initialize devices for power managerment + * + * @param none + * + * @return int: Success: DUER_OK + * Failed: DUER_ERR_FAILED + */ +int duer_pm_init_devices(void); + +/** + * Get device list + * + * @param none + * + * @return duer_pm_device_list_t* + * + */ +const duer_pm_device_list_t *duer_pm_get_device_list(void); + +/* + * Alloc a device + * + * @param void + * + * @return pointer: Success: duer_pm_device_t * + * Failed: NULL + */ +extern duer_pm_device_t *duer_pm_alloc_dev(void); + +/* + * Destroy a device object + * + * @param pointer to device + * + * @return int: Success: DUER_OK + * Failed: DUER_ERR_FAILED + */ +extern int duer_pm_destroy_dev(duer_pm_device_t *dev); + +/* + * Register a device to PM + * + * @param dev: duer_pm_device_t * + * + * @return int: Success: DUER_OK + * Failed: DUER_ERR_FAILED + */ +extern int duer_pm_register_dev(duer_pm_device_t *dev); + +/* + * Get device Object by the name of device + * + * @param name: const char * + * + * @return pointer: Success: duer_pm_device_t * + * Failed: NULL + */ +extern duer_pm_device_t *duer_pm_get_dev_obj_by_name(const char *name); + +/* + * Get device Object by the device type + * + * @param name: const char * + * + * @return pointer: Success: duer_pm_device_t * + * Failed: NULL + */ +extern duer_pm_device_t *duer_pm_get_dev_obj_by_type(duer_pm_dev_type_t type); +/* + * Unregister a device from PM and destroy it + * + * @param dev: duer_pm_device_t * + * + * @return int: Success: DUER_OK + * Failed: DUER_ERR_FAILED + */ +extern int duer_pm_unregister_dev(duer_pm_device_t *dev); + +/* + * Increase the reference count of the device + * + * @param dev: duer_pm_device_t * + * + * @return int: Success: DUER_OK + * Failed: DUER_ERR_FAILED + */ +extern int duer_pm_acquire_dev(duer_pm_device_t *dev); + +/* + * Reduce the reference count of the device + * + * @param dev: duer_pm_device_t * + * + * @return int: Success: DUER_OK + * Failed: DUER_ERR_FAILED + */ +extern int duer_pm_release_dev(duer_pm_device_t *dev); + +/* + * Update the power state of the device + * + * @param dev: duer_pm_device_t * + * state: duer_pm_dev_state + * + * @return int: Success: DUER_OK + * Failed: DUER_ERR_FAILED + */ +extern int duer_pm_update_pm_state(duer_pm_device_t *dev, duer_pm_dev_state_t state); + +/* + * Get the power state of the device + * + * @param dev: duer_pm_device_t * + * + * @return duer_pm_dev_state_t + */ +extern duer_pm_dev_state_t duer_pm_get_pm_state(duer_pm_device_t *dev); + +/* + * Update the suspend target time of the device + * + * @param dev: duer_pm_device_t * + * time: uint32_t + * + * @return int: Success: DUER_OK + * Failed: DUER_ERR_FAILED + */ +extern int duer_pm_update_suspend_target_time(duer_pm_device_t *dev, uint32_t time_s); + +/* + * Update the poweroff target time of the device + * + * @param dev: duer_pm_device_t * + * time: uint32_t + * + * @return int: Success: DUER_OK + * Failed: DUER_ERR_FAILED + */ +extern int duer_pm_update_poweroff_target_time(duer_pm_device_t *dev, uint32_t time_s); + +/* + * Traverse the device list + * + * @param traverse : Processing the device function + * + * @return int: Success: DUER_OK + * Failed: DUER_ERR_FAILED + */ +extern int duer_pm_traverses_dev_list(treatment_dev_func handler); + +#ifdef __cplusplus +} +#endif + +#endif // BAIDU_DUER_LIGHTDUER_INCLUDE_LIGHTDUER_PM_DEV_H diff --git a/components/clouds/dueros/lightduer/include/lightduer_pm_manager.h b/components/clouds/dueros/lightduer/include/lightduer_pm_manager.h new file mode 100755 index 0000000..8828e6f --- /dev/null +++ b/components/clouds/dueros/lightduer/include/lightduer_pm_manager.h @@ -0,0 +1,73 @@ +/** + * Copyright (2017) Baidu Inc. All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/* + * File: lightduer_pm_manager.c + * Auth: Chang Li (changli@baidu.com) + * Desc: PM manager implementation. + */ + +#ifndef BAIDU_DUER_LIGHTDUER_PM_MANAGER_H +#define BAIDU_DUER_LIGHTDUER_PM_MANAGER_H + +#include "lightduer_notifier.h" +#include "lightduer_pm_policy.h" + +#ifdef __cplusplus +extern "C" { +#endif + +typedef enum { + PM_SYSTEM_ENTER, + PM_SYSTEM_EXIT +} pm_system_handle_action_t; + +typedef int (*pm_system_handler_func)(pm_system_handle_action_t action, pm_policy_t policy, + uint32_t timer_sec, int *data); + +/** + * Register notifier for observer use + * + * @param notifier: duer_notifier_block_t object + * + * @return int : 0 for Success, others for failure + * + */ +int duer_pm_register_notifier(duer_notifier_block_t *notifier); + +/** + * Power Manager initialization + * + * @return int : 0 for Success, others for failure + * + */ +int duer_pm_init(pm_system_handler_func hdlr); + +/** + * Power Manager main logic + * + * @return int : 0 for Success, others for failure + * + */ +int duer_pm_manager(); + +#ifdef __cplusplus +} +#endif + +#endif // BAIDU_DUER_LIGHTDUER_PM_MANAGER_H + + + diff --git a/components/clouds/dueros/lightduer/include/lightduer_pm_policy.h b/components/clouds/dueros/lightduer/include/lightduer_pm_policy.h new file mode 100755 index 0000000..7e12a39 --- /dev/null +++ b/components/clouds/dueros/lightduer/include/lightduer_pm_policy.h @@ -0,0 +1,76 @@ +/** + * Copyright (2017) Baidu Inc. All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/* + * File: lightduer_pm_policy.h + * Auth: Chang Li (changli@baidu.com) + * Desc: PM Policy Head file + */ + +#ifndef BAIDU_DUER_LIGHTDUER_INCLUDE_LIGHTDUER_PM_POLICY_H +#define BAIDU_DUER_LIGHTDUER_INCLUDE_LIGHTDUER_PM_POLICY_H + +#include "lightduer_pm_dev.h" +#include "lightduer_types.h" + +#ifdef __cplusplus +extern "C" { +#endif + +typedef enum pm_policy { + PM_POLICY_NONE, + PM_POLICY_CPU_FREQ, + PM_POLICY_SLEEP, + PM_POLICY_POWER_OFF, + PM_POLICY_MAX +} pm_policy_t; + +typedef struct user_policy { + enum _baidu_ca_bool_e is_valid; + duer_pm_dev_type_t type; + duer_pm_dev_state_t state; + uint32_t duration; +} user_policy_t; + +typedef int (*pm_policy_func)(const duer_pm_device_list_t *dev_list, pm_policy_t *out_policy); + +/** + * Make decision according to current situation + * + * @param *dev_list : list of registered device + * @param *out_policy : output Policy + * + * @return int : 0 for Success, others for failure. + * + */ +int duer_pm_policy(const duer_pm_device_list_t *dev_list, pm_policy_t *out_policy); + +/** + * Check pm policy + * + * @param *dev_list : list of registered device + * @param *out_policy : output Policy + * @param handler: pm policy function + * + * @return int : 0 for Success, others for failure. + * + */ +int duer_pm_check_policy(const duer_pm_device_list_t *dev_list, pm_policy_t *out_policy, pm_policy_func handler); + +#ifdef __cplusplus +} +#endif + +#endif // BAIDU_DUER_LIGHTDUER_INCLUDE_LIGHTDUER_PM_POLICY_H diff --git a/components/clouds/dueros/lightduer/include/lightduer_security_bind_device.h b/components/clouds/dueros/lightduer/include/lightduer_security_bind_device.h new file mode 100755 index 0000000..7b42954 --- /dev/null +++ b/components/clouds/dueros/lightduer/include/lightduer_security_bind_device.h @@ -0,0 +1,60 @@ +/** + * Copyright (2018) Baidu Inc. All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/** + * File: lightduer_security_bind_device.h + * Auth: Chen Xihao (chenxihao@baidu.com) + * Desc: Support App to bind device securely + */ + +#ifndef BAIDU_DUER_LIGHTDUER_INCLUDE_LIGHTDUER_SECURITY_BIND_DEVICE_H +#define BAIDU_DUER_LIGHTDUER_INCLUDE_LIGHTDUER_SECURITY_BIND_DEVICE_H + +#include "lightduer_types.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * DESC: + * Start the task to bind device securely. + * + * PARAM: + * @param[in] uuid: the uuid of device + * @param[in] bind_token: the bind token of device + * @param[in] lifecycle: the lifecycle of task in seconds, at least 60s + * + * @RETURN: success return DUER_OK, failed return DUER_ERR_FAILED. + */ +duer_status_t duer_start_security_bind_device_task(const char *uuid, + const char *bind_token, size_t lifecycle); + +/** + * DESC: + * Stop the task that bind device. + * + * PARAM: none + * + * @RETURN: success return DUER_OK, failed return DUER_ERR_FAILED. + */ +duer_status_t duer_stop_security_bind_device_task(void); + +#ifdef __cplusplus +} +#endif + +#endif /* BAIDU_DUER_LIGHTDUER_INCLUDE_LIGHTDUER_SECURITY_BIND_DEVICE_H */ + diff --git a/components/clouds/dueros/lightduer/include/lightduer_session.h b/components/clouds/dueros/lightduer/include/lightduer_session.h old mode 100644 new mode 100755 diff --git a/components/clouds/dueros/lightduer/include/lightduer_speex.h b/components/clouds/dueros/lightduer/include/lightduer_speex.h old mode 100644 new mode 100755 index 4e4d5ce..ce71998 --- a/components/clouds/dueros/lightduer/include/lightduer_speex.h +++ b/components/clouds/dueros/lightduer/include/lightduer_speex.h @@ -32,7 +32,7 @@ typedef void *duer_speex_handler; typedef void (*duer_encoded_func)(const void *, size_t); -duer_speex_handler duer_speex_create(int rate); +duer_speex_handler duer_speex_create(int rate, int quality); void duer_speex_encode(duer_speex_handler handler, const void *data, size_t size, duer_encoded_func func); diff --git a/components/clouds/dueros/lightduer/include/lightduer_system_info.h b/components/clouds/dueros/lightduer/include/lightduer_system_info.h old mode 100644 new mode 100755 index bc7857a..1054476 --- a/components/clouds/dueros/lightduer/include/lightduer_system_info.h +++ b/components/clouds/dueros/lightduer/include/lightduer_system_info.h @@ -23,7 +23,7 @@ #include #include -#define DUER_OS_VERSION "release-v3.0.7" +#define DUER_OS_VERSION "release-v3.1.1" #define OS_VERSION_LEN 20 #define SW_VERSION_LEN 20 diff --git a/components/clouds/dueros/lightduer/include/lightduer_timestamp.h b/components/clouds/dueros/lightduer/include/lightduer_timestamp.h index 537ed58..2eb4228 100755 --- a/components/clouds/dueros/lightduer/include/lightduer_timestamp.h +++ b/components/clouds/dueros/lightduer/include/lightduer_timestamp.h @@ -26,6 +26,22 @@ extern "C" { #endif +/** + * @brief Macros used to compare time values + * + * These inlines deal with timer wrapping correctly. You are + * strongly encouraged to use them + * 1. Because people otherwise forget + * 2. Because if the timer wrap changes in future you won't have to + * alter your code. + * + * DUER_TIME_AFTER(a,b) returns true if the time a is after time b. + */ +#define DUER_TIME_AFTER(a, b) ((duer_s32_t)(b) - (duer_s32_t)(a) < 0) +#define DUER_TIME_BEFORE(a, b) DUER_TIME_AFTER(b, a) +#define DUER_TIME_AFTER_EQUAL(a, b) ((duer_s32_t)(a) - (duer_s32_t)(b) >= 0) +#define DUER_TIME_BEFORE_EQUAL(a, b) DUER_TIME_AFTER_EQUAL(b, a) + /* * Obtain the system timestamp by milliseconds * diff --git a/components/clouds/dueros/lightduer/include/lightduer_types.h b/components/clouds/dueros/lightduer/include/lightduer_types.h old mode 100644 new mode 100755 index f66968b..7f24128 --- a/components/clouds/dueros/lightduer/include/lightduer_types.h +++ b/components/clouds/dueros/lightduer/include/lightduer_types.h @@ -52,11 +52,15 @@ typedef size_t duer_size_t; typedef unsigned int duer_size_t; #endif typedef unsigned int duer_u32_t; +typedef signed int duer_s32_t; typedef unsigned short duer_u16_t; +typedef signed int duer_s16_t; typedef unsigned char duer_u8_t; -typedef signed int duer_s32_t; +typedef signed char duer_s8_t; typedef char duer_bool; +typedef duer_status_t (*duer_data_callback)(duer_context, const void *, duer_size_t); + enum _baidu_ca_bool_e { DUER_FALSE, DUER_TRUE @@ -86,6 +90,8 @@ typedef enum _duer_errcode_enum { DUER_ERR_TRANS_TIMEOUT = -0x0032, // send timeout DUER_ERR_REG_FAIL = -0x0033, DUER_ERR_TRANS_DNS_FAIL = -0x0034, + DUER_ERR_WIFI_SIGNAL_WEAK = -0x0035, + DUER_ERR_WIFI_DISCONNECTED = -0x0036, DUER_ERR_MBEDTLS_NET_MAX = -0x0040, // -0x0040 - -0x0060 reserved for mbed net error code , see mbedtls/net.h for more info diff --git a/components/clouds/dueros/lightduer/include/lightduer_voice.h b/components/clouds/dueros/lightduer/include/lightduer_voice.h index a79a942..a912ba8 100755 --- a/components/clouds/dueros/lightduer/include/lightduer_voice.h +++ b/components/clouds/dueros/lightduer/include/lightduer_voice.h @@ -38,7 +38,30 @@ typedef enum _duer_voice_mode_enum { } duer_voice_mode; +typedef struct _duer_voice_cache_t { + int head; + int tail; + int size; + char *items[0]; +} duer_voice_cache_t; + +#ifdef DUER_SECOND_WAKEUP_ENABLE +typedef enum _duer_voice_send_state_enum { + DUER_VOICE_SEND_STATE_DEFAULT = 1, + DUER_VOICE_SEND_STATE_CACHE, + DUER_VOICE_SEND_STATE_WAKEUP, + DUER_VOICE_SEND_STATE_QUERY, +} duer_voice_send_state; + +typedef enum _duer_wakeup_bit_enum { + DUER_WAKEUP_BIT = 0x01, + DUER_WAKEUP_EOF_BIT = 0x02, + DUER_WAKEUP_2ND_WAKEUP_BIT = 0x04, +} duer_wakeup_bit; +#endif//DUER_SECOND_WAKEUP_ENABLE + typedef void (*duer_voice_delay_func)(duer_u32_t); +typedef const char* (*duer_get_dialog_id_func)(void); void duer_voice_set_delay_threshold(duer_u32_t delay, duer_voice_delay_func); @@ -58,6 +81,49 @@ int duer_voice_terminate(void); void duer_add_translate_flag(baidu_json *data); +void duer_reg_dialog_id_cb(duer_get_dialog_id_func cb); + +#ifdef DUER_SECOND_WAKEUP_ENABLE +void duer_voice_set_send_state(duer_voice_send_state send_state); + +/* + * Restart voice session, but won't clear cached voice. + * Used for second wakeup, when got new keyword recognition before previous session end. + */ +int duer_voice_restart(void); + +/* + * Send voice with wakeup bit set, to trigger cloud second wakeup. + * + * @PARAM wakeup: the wakeup bit needs to be sent. + */ +int duer_voice_send_wakeup(int wakeup); + +/* + * Check if voice started, according to topic id value. + */ +duer_bool duer_voice_is_started(); + +/* + * Init second wakeup functionality. + * + * @PARAM cache_size: the size of cache of wakeup voice. + */ +void duer_voice_second_wakeup_init(int cache_size); + +/* + * Uninit second wakeup functionality. + */ +void duer_voice_second_wakeup_uninit(); + +/* + * Truncate wakeup voice cache. + * + * @PARAM count: the cache length after truncated. + */ +void duer_voice_truncate_wakeup_cache(int count); +#endif//DUER_SECOND_WAKEUP_ENABLE + /* * topic_id + 1 * @@ -66,6 +132,8 @@ void duer_add_translate_flag(baidu_json *data); */ size_t duer_increase_topic_id(void); +int duer_voice_set_speex_quality(int quality); + #ifdef __cplusplus } #endif diff --git a/components/clouds/dueros/lightduer/libduer-device.a b/components/clouds/dueros/lightduer/libduer-device.a index 47289e1..88cb07f 100644 Binary files a/components/clouds/dueros/lightduer/libduer-device.a and b/components/clouds/dueros/lightduer/libduer-device.a differ diff --git a/components/display_service/include/display_service.h b/components/display_service/include/display_service.h index 3290d38..c178d89 100644 --- a/components/display_service/include/display_service.h +++ b/components/display_service/include/display_service.h @@ -61,6 +61,12 @@ typedef enum { DISPLAY_PATTERN_BATTERY_LOW = 22, DISPLAY_PATTERN_BATTERY_CHARGING = 23, DISPLAY_PATTERN_BATTERY_FULL = 24, + + DISPLAY_PATTERN_POWERON_INIT = 25, + DISPLAY_PATTERN_WIFI_NO_CFG = 26, + DISPLAY_PATTERN_SPEECH_BEGIN = 27, + DISPLAY_PATTERN_SPEECH_OVER = 28, + DISPLAY_PATTERN_MAX, } display_pattern_t; diff --git a/components/display_service/led_bar/led_bar_aw2013.c b/components/display_service/led_bar/led_bar_aw2013.c index b47e578..ec664cd 100644 --- a/components/display_service/led_bar/led_bar_aw2013.c +++ b/components/display_service/led_bar/led_bar_aw2013.c @@ -235,7 +235,7 @@ esp_err_t led_bar_aw2013_pattern(void *handle, int pat, int value) esp_err_t led_bar_aw2013_set_blink_time(void *handle, uint8_t time, int period) { - AUDIO_NULL_CHECK(TAG, handle, return NULL); + AUDIO_NULL_CHECK(TAG, handle, return ESP_ERR_INVALID_ARG); led_bar_aw2013_cmd_t cmd = { .instance = handle, diff --git a/components/display_service/led_indicator/led_indicator.c b/components/display_service/led_indicator/led_indicator.c index d460998..076233c 100644 --- a/components/display_service/led_indicator/led_indicator.c +++ b/components/display_service/led_indicator/led_indicator.c @@ -67,11 +67,17 @@ esp_err_t led_indicator_pattern(void *handle, int pat, int value) periph_led_blink(h->periph_handle, h->gpio_num, 200, 500, false, -1, value); break; case DISPLAY_PATTERN_TURN_ON: + case DISPLAY_PATTERN_WAKEUP_ON: periph_led_blink(h->periph_handle, h->gpio_num, 100, 0, false, -1, value); break; case DISPLAY_PATTERN_TURN_OFF: + case DISPLAY_PATTERN_WAKEUP_FINISHED: + case DISPLAY_PATTERN_SPEECH_OVER: periph_led_blink(h->periph_handle, h->gpio_num, 0, 100, false, -1, value); break; + case DISPLAY_PATTERN_SPEECH_BEGIN: + periph_led_blink(h->periph_handle, h->gpio_num, 500, 500, false, -1, value); + break; default: ESP_LOGW(TAG, "The led mode is invalid"); break; diff --git a/components/display_service/test/test_display_service.c b/components/display_service/test/test_display_service.c index 38860ec..8a7ecea 100644 --- a/components/display_service/test/test_display_service.c +++ b/components/display_service/test/test_display_service.c @@ -63,6 +63,22 @@ TEST_CASE("Create a display service and set different pattern", "[display_servic TEST_ASSERT_FALSE(display_service_set_pattern(display_handle, DISPLAY_PATTERN_WIFI_SETTING_FINISHED, 0)); vTaskDelay(2000 / portTICK_PERIOD_MS); + ESP_LOGI(TAG, "wakeup on"); + TEST_ASSERT_FALSE(display_service_set_pattern(display_handle, DISPLAY_PATTERN_WAKEUP_ON, 0)); + vTaskDelay(2000 / portTICK_PERIOD_MS); + + ESP_LOGI(TAG, "wakeup finish"); + TEST_ASSERT_FALSE(display_service_set_pattern(display_handle, DISPLAY_PATTERN_WAKEUP_FINISHED, 0)); + vTaskDelay(2000 / portTICK_PERIOD_MS); + + ESP_LOGI(TAG, "speech begin"); + TEST_ASSERT_FALSE(display_service_set_pattern(display_handle, DISPLAY_PATTERN_SPEECH_BEGIN, 0)); + vTaskDelay(2000 / portTICK_PERIOD_MS); + + ESP_LOGI(TAG, "speech finish"); + TEST_ASSERT_FALSE(display_service_set_pattern(display_handle, DISPLAY_PATTERN_WAKEUP_FINISHED, 0)); + vTaskDelay(2000 / portTICK_PERIOD_MS); + ESP_LOGW(TAG, "Display service will be destroyed"); TEST_ASSERT_FALSE(display_destroy(display_handle)); } @@ -319,6 +335,22 @@ TEST_CASE("Create a display service on board with an ws2812 chip", "[display_ser TEST_ASSERT_FALSE(led_bar_ws2812_pattern(ws2812_handle, DISPLAY_PATTERN_BATTERY_FULL, 0)); vTaskDelay(2000 / portTICK_PERIOD_MS); + ESP_LOGI(TAG, "poweron init"); + TEST_ASSERT_FALSE(led_bar_ws2812_pattern(ws2812_handle, DISPLAY_PATTERN_POWERON_INIT, 0)); + vTaskDelay(2000 / portTICK_PERIOD_MS); + + ESP_LOGI(TAG, "wifi no cfg"); + TEST_ASSERT_FALSE(led_bar_ws2812_pattern(ws2812_handle, DISPLAY_PATTERN_WIFI_NO_CFG, 0)); + vTaskDelay(2000 / portTICK_PERIOD_MS); + + ESP_LOGI(TAG, "speech begin"); + TEST_ASSERT_FALSE(led_bar_ws2812_pattern(ws2812_handle, DISPLAY_PATTERN_SPEECH_BEGIN, 0)); + vTaskDelay(2000 / portTICK_PERIOD_MS); + + ESP_LOGI(TAG, "speech over"); + TEST_ASSERT_FALSE(led_bar_ws2812_pattern(ws2812_handle, DISPLAY_PATTERN_SPEECH_OVER, 0)); + vTaskDelay(2000 / portTICK_PERIOD_MS); + ESP_LOGW(TAG, "Display service will be destroyed"); led_bar_ws2812_deinit(ws2812_handle); } @@ -332,7 +364,7 @@ TEST_CASE("Create a display service on board with an aw2013 chip", "[display_ser esp_periph_handle_t aw2013_handle = led_bar_aw2013_init(); TEST_ASSERT_NOT_NULL(aw2013_handle); TEST_ASSERT_FALSE(led_bar_aw2013_set_blink_time(aw2013_handle, 5, 300)); - + display_service_config_t display = { .based_cfg = { .task_stack = 3 * 1024, diff --git a/components/dueros_service/duer_profile b/components/dueros_service/duer_profile old mode 100755 new mode 100644 diff --git a/components/dueros_service/dueros_esp_flash.c b/components/dueros_service/dueros_esp_flash.c new file mode 100644 index 0000000..650ddd3 --- /dev/null +++ b/components/dueros_service/dueros_esp_flash.c @@ -0,0 +1,136 @@ +/* + * ESPRESSIF MIT License + * + * Copyright (c) 2020 + * + * Permission is hereby granted for use on all ESPRESSIF SYSTEMS products, in which case, + * it is free of charge, to any person obtaining a copy of this software and associated + * documentation files (the "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the Software is furnished + * to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all copies or + * substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + */ + +#include "dueros_esp_flash.h" +#include "esp_partition.h" +#include "audio_mem.h" +#include "esp_log.h" + +#define MAX_FLASH_ALERT_COUNT 30 + +// 4k Byte erase size (12 bits), for erase. +#define FLASH_SECTOR_ALIGN_BITS 12 +// 4 Byte page size (2 bits), for write. +#define FLASH_PAGE_ALIGN_BITS 8 +// 4 byte (2 bits), for read flash data. +#define FLASH_WORD_ALIGN_BITS 2 + +static const char *TAG = "DUER_FLASH"; + +static const duer_flash_config_t s_flash_config = { + FLASH_SECTOR_ALIGN_BITS, + FLASH_PAGE_ALIGN_BITS, + FLASH_WORD_ALIGN_BITS, +}; + +static const char *s_parti_label_list[] = { + "alert", +}; + +static duer_flash_string_context_t s_ctx_list[] = { + {{NULL, 0, NULL}, MAX_FLASH_ALERT_COUNT, NULL}, +}; + +duer_flash_string_context_t *duer_flash_string_init(duer_flash_module module) +{ + int i = 0; + const char *label = s_parti_label_list[module]; + duer_flash_string_context_t *rt = &s_ctx_list[module]; + + duer_set_flash_config(&s_flash_config); + + if (module >= MAX_FLASH_MODULE) { + ESP_LOGE(TAG, "Invalid flash module"); + return NULL; + } + + if (!label) { + ESP_LOGE(TAG, "Invalid partition label."); + return NULL; + } + + rt->ctx.handle = (void *)esp_partition_find_first(ESP_PARTITION_TYPE_DATA, ESP_PARTITION_SUBTYPE_ANY, + label); + if (!rt->ctx.handle) { + ESP_LOGE(TAG, "cannot find partition label %s.", label); + return NULL; + } + + rt->ctx.len = ((esp_partition_t *)(rt->ctx.handle))->size; + + if (!rt->ele_list) { + rt->ele_list = (uint32_t *)audio_malloc(sizeof(uint32_t) * rt->max_ele_count); + for (i = 0; i < rt->max_ele_count; ++i) { + rt->ele_list[i] = FLASH_INVALID_ADDR; + } + } + return rt; +} + +duer_status_t duer_esp_flash_init(const char *label, + duer_flash_context_t *ctx, + duer_flash_config_t *config) +{ + if (!label || !ctx || !config) { + return DUER_ERR_INVALID_PARAMETER; + } + + ctx->handle = (void *)esp_partition_find_first(ESP_PARTITION_TYPE_DATA, ESP_PARTITION_SUBTYPE_ANY, + label); + if (!ctx->handle) { + ESP_LOGE(TAG, "cannot find partition label %s.", label); + return DUER_ERR_FAILED; + } + + ctx->len = ((esp_partition_t *)(ctx->handle))->size; + memcpy(config, &s_flash_config, sizeof(*config)); + + return DUER_OK; +} + +int duer_flash_read( + duer_flash_context_t *ctx, + unsigned int offset, + void *buf, + unsigned int len) +{ + return esp_partition_read((esp_partition_t *)(ctx->handle), offset, buf, len); +} + +int duer_flash_write( + duer_flash_context_t *ctx, + unsigned int offset, + void *buf, + unsigned int len) +{ + return esp_partition_write((esp_partition_t *)(ctx->handle), offset, buf, len); +} + +int duer_flash_erase( + duer_flash_context_t *ctx, + unsigned int offset, + unsigned int len) +{ + return esp_partition_erase_range((esp_partition_t *)(ctx->handle), offset, len); +} diff --git a/components/dueros_service/include/dueros_esp_flash.h b/components/dueros_service/include/dueros_esp_flash.h new file mode 100644 index 0000000..5ff8c1a --- /dev/null +++ b/components/dueros_service/include/dueros_esp_flash.h @@ -0,0 +1,63 @@ +/* + * ESPRESSIF MIT License + * + * Copyright (c) 2020 + * + * Permission is hereby granted for use on all ESPRESSIF SYSTEMS products, in which case, + * it is free of charge, to any person obtaining a copy of this software and associated + * documentation files (the "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the Software is furnished + * to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all copies or + * substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + */ + +#ifndef _DUEROS_SERVICE_ESP_FLASH_H +#define _DUEROS_SERVICE_ESP_FLASH_H + +#include "lightduer_types.h" +#include "lightduer_flash_strings.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/* + * @brief Initialize flash partition for alert service + * + * @param[in] module The audio service instance + * + * @return + * - NULL, Fail + * - Others, Success + */ +duer_flash_string_context_t *duer_flash_string_init(duer_flash_module module); + +/* + * @brief Initialize flash partition for dueros service + * + * @param[in] label A pointer to partition label + * @param[in] ctx A pointer to `duer_flash_context_t` + * @param[in] config A pointer to `duer_flash_config_t` + * + * @return + * - ESP_OK, Success + * - Others, Fail + */ +duer_status_t duer_esp_flash_init(const char *label, duer_flash_context_t *ctx, duer_flash_config_t *config); + +#ifdef __cplusplus +} +#endif + +#endif /* _DUEROS_SERVICE_ESP_FLASH_H */ diff --git a/components/esp_dispatcher/esp_dispatcher.c b/components/esp_dispatcher/esp_dispatcher.c index d0e1b1e..76dcb16 100644 --- a/components/esp_dispatcher/esp_dispatcher.c +++ b/components/esp_dispatcher/esp_dispatcher.c @@ -256,7 +256,7 @@ esp_err_t esp_dispatcher_execute_with_func(esp_dispatcher_handle_t dh, if (xQueueSend(impl->exe_que, &delegate, pdMS_TO_TICKS(5000)) != pdPASS) { ret->err = ESP_FAIL; ESP_LOGE(TAG, "Message send timeout"); - mutex_lock(impl->mutex); + mutex_unlock(impl->mutex); return ESP_ERR_ADF_TIMEOUT; } xQueueReceive(impl->result_que, ret, portMAX_DELAY); diff --git a/components/esp_peripherals/include/periph_sdcard.h b/components/esp_peripherals/include/periph_sdcard.h index d394b50..630d22c 100644 --- a/components/esp_peripherals/include/periph_sdcard.h +++ b/components/esp_peripherals/include/periph_sdcard.h @@ -46,12 +46,24 @@ typedef enum { SDCARD_STATUS_UNMOUNT_ERROR, /*!< SDCARD unmount error */ } periph_sdcard_event_id_t; +/** + * @brief SD card mode, SPI, 1-line SD mode, 4-line SD mode + * + */ +typedef enum { + SD_MODE_SPI = 0x0, /*!< sd_card SPI*/ + SD_MODE_1_LINE = 0x1, /*!< sd_card 1-line SD mode*/ + SD_MODE_4_LINE = 0x2, /*!< sd_card 4-line SD mode*/ + SD_MODE_MAX, +} periph_sdcard_mode_t; + /** * @brief The SD Card Peripheral configuration */ typedef struct { - int card_detect_pin; /*!< Card detect gpio number */ - const char* root; /*!< Base path for vfs */ + int card_detect_pin; /*!< Card detect gpio number */ + const char* root; /*!< Base path for vfs */ + periph_sdcard_mode_t mode; /*!< card mode*/ } periph_sdcard_cfg_t; diff --git a/components/esp_peripherals/include/periph_ws2812.h b/components/esp_peripherals/include/periph_ws2812.h index 7d8eab4..2ede64d 100755 --- a/components/esp_peripherals/include/periph_ws2812.h +++ b/components/esp_peripherals/include/periph_ws2812.h @@ -45,6 +45,7 @@ typedef uint32_t periph_rgb_value; #define LED2812_COLOR_PURPLE make_rgb_value(255, 0, 255) #define LED2812_COLOR_YELLOW make_rgb_value(255, 255, 0) #define LED2812_COLOR_WHITE make_rgb_value(255, 255, 255) +#define LED2812_COLOR_ORANGE make_rgb_value(255, 165, 0) /** * @brief The ws2812 peripheral configuration diff --git a/components/esp_peripherals/lib/blufi/blufi_security.c b/components/esp_peripherals/lib/blufi/blufi_security.c index a512d47..e5e6d54 100644 --- a/components/esp_peripherals/lib/blufi/blufi_security.c +++ b/components/esp_peripherals/lib/blufi/blufi_security.c @@ -34,7 +34,24 @@ #include "mbedtls/aes.h" #include "mbedtls/dhm.h" #include "mbedtls/md5.h" + +#if __has_include("esp_idf_version.h") +#include "esp_idf_version.h" +#else +#define ESP_IDF_VERSION_VAL(major, minor, patch) 1 +#endif + +#if (ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(4, 0, 0)) + +#ifdef CONFIG_IDF_TARGET_ESP32 +#include "esp32/rom/crc.h" +#else +#include "esp32s2beta/rom/crc.h" +#endif // CONFIG_IDF_TARGET_ESP32 + +#else #include "rom/crc.h" +#endif //(ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(4, 0, 0)) #define BLUFI_SECURITY_TAG "BLUFI_SECURITY" /* diff --git a/components/esp_peripherals/lib/sdcard/sdcard.c b/components/esp_peripherals/lib/sdcard/sdcard.c index 8e74abd..1315795 100644 --- a/components/esp_peripherals/lib/sdcard/sdcard.c +++ b/components/esp_peripherals/lib/sdcard/sdcard.c @@ -41,6 +41,11 @@ static const char *TAG = "SDCARD"; int g_gpio = -1; +#define PIN_NUM_MISO 2 +#define PIN_NUM_MOSI 15 +#define PIN_NUM_CLK 14 +#define PIN_NUM_CS 13 + static void sdmmc_card_print_info(const sdmmc_card_t *card) { ESP_LOGD(TAG, "Name: %s\n", card->cid.name); @@ -53,23 +58,50 @@ static void sdmmc_card_print_info(const sdmmc_card_t *card) ESP_LOGD(TAG, "SCR: sd_spec=%d, bus_width=%d\n", card->scr.sd_spec, card->scr.bus_width); } -esp_err_t sdcard_mount(const char *base_path) +esp_err_t sdcard_mount(const char *base_path, periph_sdcard_mode_t mode) { - sdmmc_host_t host = SDMMC_HOST_DEFAULT(); - // To use 1-line SD mode, uncomment the following line: - host.flags = SDMMC_HOST_FLAG_1BIT; - host.max_freq_khz = SDMMC_FREQ_HIGHSPEED; - sdmmc_slot_config_t slot_config = SDMMC_SLOT_CONFIG_DEFAULT(); - slot_config.gpio_cd = g_gpio; - slot_config.width = 1; + if (mode >= SD_MODE_MAX) { + ESP_LOGE(TAG, "PLease select the correct sd mode: 1-line SD mode, 4-line SD mode or SPI mode!, current mode is %d", mode); + return ESP_FAIL; + } + + sdmmc_card_t *card = NULL; + esp_err_t ret; esp_vfs_fat_sdmmc_mount_config_t mount_config = { .format_if_mount_failed = false, .max_files = get_sdcard_open_file_num_max() }; - sdmmc_card_t *card; - ESP_LOGI(TAG, "Trying to mount with base path=%s", base_path); - esp_err_t ret = esp_vfs_fat_sdmmc_mount(base_path, &host, &slot_config, &mount_config, &card); + if (mode != SD_MODE_SPI) { + ESP_LOGI(TAG, "Using 1-line SD mode, 4-line SD mode, base path=%s", base_path); + sdmmc_host_t host = SDMMC_HOST_DEFAULT(); + host.max_freq_khz = SDMMC_FREQ_HIGHSPEED; + + sdmmc_slot_config_t slot_config = SDMMC_SLOT_CONFIG_DEFAULT(); + slot_config.gpio_cd = g_gpio; + slot_config.width = mode & 0X01; + + gpio_set_pull_mode(GPIO_NUM_15, GPIO_PULLUP_ONLY); + gpio_set_pull_mode(GPIO_NUM_2, GPIO_PULLUP_ONLY); + gpio_set_pull_mode(GPIO_NUM_13, GPIO_PULLUP_ONLY); + + if (mode == SD_MODE_4_LINE) { + gpio_set_pull_mode(GPIO_NUM_4, GPIO_PULLUP_ONLY); + gpio_set_pull_mode(GPIO_NUM_12, GPIO_PULLUP_ONLY); + } + + ret = esp_vfs_fat_sdmmc_mount(base_path, &host, &slot_config, &mount_config, &card); + } else { + ESP_LOGI(TAG, "Using SPI mode, base path=%s", base_path); + sdmmc_host_t host = SDSPI_HOST_DEFAULT(); + sdspi_slot_config_t slot_config = SDSPI_SLOT_CONFIG_DEFAULT(); + slot_config.gpio_miso = PIN_NUM_MISO; + slot_config.gpio_mosi = PIN_NUM_MOSI; + slot_config.gpio_sck = PIN_NUM_CLK; + slot_config.gpio_cs = PIN_NUM_CS; + + ret = esp_vfs_fat_sdmmc_mount(base_path, &host, &slot_config, &mount_config, &card); + } switch (ret) { case ESP_OK: diff --git a/components/esp_peripherals/lib/sdcard/sdcard.h b/components/esp_peripherals/lib/sdcard/sdcard.h index 48845e4..42bdc98 100644 --- a/components/esp_peripherals/lib/sdcard/sdcard.h +++ b/components/esp_peripherals/lib/sdcard/sdcard.h @@ -26,6 +26,7 @@ #define _ESP_SDCARD_H_ #include "audio_error.h" +#include "periph_sdcard.h" #ifdef __cplusplus extern "C" { @@ -54,7 +55,7 @@ esp_err_t sdcard_init(int gpio, void (*detect_intr_handler)(void *), void *isr_c * - ESP_FAIL if partition can not be mounted * - other error codes from SDMMC or SPI drivers, SDMMC protocol, or FATFS drivers */ -esp_err_t sdcard_mount(const char* base_path); +esp_err_t sdcard_mount(const char* base_path, periph_sdcard_mode_t mode); /** * @brief Unmount FAT filesystem and release resources acquired using esp_vfs_fat_sdmmc_mount diff --git a/components/esp_peripherals/lib/touch/touch.c b/components/esp_peripherals/lib/touch/touch.c index d31424e..1b3846c 100644 --- a/components/esp_peripherals/lib/touch/touch.c +++ b/components/esp_peripherals/lib/touch/touch.c @@ -173,11 +173,11 @@ static touch_status_t touch_get_state(esp_touch_handle_t touch, esp_touch_item_t } touch_item->last_read_tick = tick; - + esp_err_t err = ESP_OK; #if CONFIG_IDF_TARGET_ESP32 - esp_err_t err = touch_pad_read_filtered(touch_item->touch_num, &touch_item->last_read_value); + err = touch_pad_read_filtered(touch_item->touch_num, &touch_item->last_read_value); #elif CONFIG_IDF_TARGET_ESP32S2 - esp_err_t err = ESP_OK; + err = ESP_OK; #endif diff --git a/components/esp_peripherals/periph_console.c b/components/esp_peripherals/periph_console.c index 18151a1..eff6829 100644 --- a/components/esp_peripherals/periph_console.c +++ b/components/esp_peripherals/periph_console.c @@ -23,12 +23,7 @@ */ #include -// #include "freertos/FreeRTOS.h" -// #include "freertos/semphr.h" -// #include "freertos/task.h" -// #include "freertos/event_groups.h" #include "driver/uart.h" - #include "esp_log.h" #include "esp_console.h" #include "esp_vfs_dev.h" @@ -40,13 +35,11 @@ #if __has_include("esp_idf_version.h") #include "esp_idf_version.h" #else -#define ESP_IDF_VERSION_VAL(major, minor, patch) 0 +#define ESP_IDF_VERSION_VAL(major, minor, patch) 1 #endif -static const char *TAG = "PERIPH_CONSOLE"; - #define CONSOLE_MAX_ARGUMENTS (5) - +static const char *TAG = "PERIPH_CONSOLE"; static const int STOPPED_BIT = BIT1; typedef struct periph_console *periph_console_handle_t; @@ -101,11 +94,11 @@ bool console_get_line(periph_console_handle_t console, unsigned max_size, TickTy { char c; char tx[3]; - -#if (ESP_IDF_VERSION > ESP_IDF_VERSION_VAL(3, 3, 2)) - int nread = uart_read_bytes(CONFIG_ESP_CONSOLE_UART_NUM, (uint8_t *)&c, 1, time_to_wait); + int nread = 0; +#if (ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(4, 0, 0)) + nread = uart_read_bytes(CONFIG_ESP_CONSOLE_UART_NUM, (uint8_t *)&c, 1, time_to_wait); #else - int nread = uart_read_bytes(CONFIG_CONSOLE_UART_NUM, (uint8_t *)&c, 1, time_to_wait); + nread = uart_read_bytes(CONFIG_CONSOLE_UART_NUM, (uint8_t *)&c, 1, time_to_wait); #endif if (nread <= 0) { @@ -118,7 +111,7 @@ bool console_get_line(periph_console_handle_t console, unsigned max_size, TickTy tx[1] = 0x20; tx[2] = c; -#if (ESP_IDF_VERSION > ESP_IDF_VERSION_VAL(3, 3, 2)) +#if (ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(4, 0, 0)) uart_write_bytes(CONFIG_ESP_CONSOLE_UART_NUM, (const char *)tx, 3); #else uart_write_bytes(CONFIG_CONSOLE_UART_NUM, (const char *)tx, 3); @@ -131,7 +124,7 @@ bool console_get_line(periph_console_handle_t console, unsigned max_size, TickTy tx[0] = '\r'; tx[1] = '\n'; -#if (ESP_IDF_VERSION > ESP_IDF_VERSION_VAL(3, 3, 2)) +#if (ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(4, 0, 0)) uart_write_bytes(CONFIG_ESP_CONSOLE_UART_NUM, (const char *)tx, 2); #else uart_write_bytes(CONFIG_CONSOLE_UART_NUM, (const char *)tx, 2); @@ -145,7 +138,7 @@ bool console_get_line(periph_console_handle_t console, unsigned max_size, TickTy return false; } -#if (ESP_IDF_VERSION > ESP_IDF_VERSION_VAL(3, 3, 2)) +#if (ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(4, 0, 0)) uart_write_bytes(CONFIG_ESP_CONSOLE_UART_NUM, (const char *)&c, 1); #else uart_write_bytes(CONFIG_CONSOLE_UART_NUM, (const char *)&c, 1); @@ -262,14 +255,14 @@ static esp_err_t _console_init(esp_periph_handle_t self) /* Move the caret to the beginning of the next line on '\n' */ esp_vfs_dev_uart_set_tx_line_endings(ESP_LINE_ENDINGS_CRLF); -#if (ESP_IDF_VERSION > ESP_IDF_VERSION_VAL(3, 3, 2)) +#if (ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(4, 0, 0)) uart_driver_install(CONFIG_ESP_CONSOLE_UART_NUM, console->buffer_size * 2, 0, 0, NULL, 0); #else uart_driver_install(CONFIG_CONSOLE_UART_NUM, console->buffer_size * 2, 0, 0, NULL, 0); #endif /* Tell VFS to use UART driver */ -#if (ESP_IDF_VERSION > ESP_IDF_VERSION_VAL(3, 3, 2)) +#if (ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(4, 0, 0)) esp_vfs_dev_uart_use_driver(CONFIG_ESP_CONSOLE_UART_NUM); #else esp_vfs_dev_uart_use_driver(CONFIG_CONSOLE_UART_NUM); @@ -293,7 +286,10 @@ esp_periph_handle_t periph_console_init(periph_console_cfg_t *config) esp_periph_handle_t periph = esp_periph_create(PERIPH_ID_CONSOLE, "periph_console"); AUDIO_MEM_CHECK(TAG, periph, return NULL); periph_console_t *console = audio_calloc(1, sizeof(periph_console_t)); - AUDIO_MEM_CHECK(TAG, console, return NULL); + AUDIO_MEM_CHECK(TAG, console, { + audio_free(periph); + return NULL; + }); console->commands = config->commands; console->command_num = config->command_num; console->task_stack = CONSOLE_DEFAULT_TASK_STACK; @@ -311,6 +307,7 @@ esp_periph_handle_t periph_console_init(periph_console_cfg_t *config) if (config->prompt_string) { console->prompt_string = audio_strdup(config->prompt_string); AUDIO_MEM_CHECK(TAG, console->prompt_string, { + audio_free(periph); audio_free(console); return NULL; }); diff --git a/components/esp_peripherals/periph_led.c b/components/esp_peripherals/periph_led.c index d4b77de..1cde6b1 100644 --- a/components/esp_peripherals/periph_led.c +++ b/components/esp_peripherals/periph_led.c @@ -29,6 +29,7 @@ #include "audio_sys.h" #include "periph_led.h" #include "esp_peripherals.h" +#include "audio_mutex.h" #define MAX_LED_CHANNEL (8) @@ -57,6 +58,7 @@ typedef struct periph_led { ledc_timer_bit_t led_duty_resolution; ledc_timer_t led_timer_num; uint32_t led_freq_hz; + QueueHandle_t led_mutex; periph_led_channel_t channels[MAX_LED_CHANNEL]; } periph_led_t; @@ -93,6 +95,7 @@ static esp_err_t _led_destroy(esp_periph_handle_t self) } esp_periph_stop_timer(self); ledc_fade_func_uninstall(); + mutex_destroy(periph_led->led_mutex); audio_free(periph_led); return ESP_OK; } @@ -107,6 +110,7 @@ esp_periph_handle_t periph_led_init(periph_led_cfg_t *config) periph_led->led_duty_resolution = config->led_duty_resolution; periph_led->led_timer_num = config->led_timer_num; periph_led->led_freq_hz = config->led_freq_hz; + periph_led->led_mutex = mutex_create(); if (periph_led->led_freq_hz == 0) { periph_led->led_freq_hz = 5000; } @@ -137,6 +141,7 @@ static void led_timer_handler(xTimerHandle tmr) esp_periph_handle_t periph = (esp_periph_handle_t) pvTimerGetTimerID(tmr); periph_led_t *periph_led = esp_periph_get_data(periph); + mutex_lock(periph_led->led_mutex); for (int i = 0; i < MAX_LED_CHANNEL; i++) { periph_led_channel_t *ch = &periph_led->channels[i]; if (ch->pin < 0 || ch->stop == true) { @@ -184,6 +189,7 @@ static void led_timer_handler(xTimerHandle tmr) ch->tick = audio_sys_get_time_ms(); } } + mutex_unlock(periph_led->led_mutex); } esp_err_t periph_led_blink(esp_periph_handle_t periph, int gpio_num, int time_on_ms, int time_off_ms, bool fade, int loop, periph_led_idle_level_t level) @@ -228,7 +234,10 @@ esp_err_t periph_led_stop(esp_periph_handle_t periph, int gpio_num) return ESP_OK; } - ledc_stop(periph_led->led_speed_mode, ch->index, ch->level); + mutex_lock(periph_led->led_mutex); ch->stop = true; + ledc_stop(periph_led->led_speed_mode, ch->index, ch->level); + mutex_unlock(periph_led->led_mutex); + return ESP_OK; } diff --git a/components/esp_peripherals/periph_sdcard.c b/components/esp_peripherals/periph_sdcard.c index 947ad42..d6dcdfb 100644 --- a/components/esp_peripherals/periph_sdcard.c +++ b/components/esp_peripherals/periph_sdcard.c @@ -51,6 +51,7 @@ typedef struct { int card_detect_pin; bool is_mounted; long long last_detect_time; + periph_sdcard_mode_t sd_mode; } periph_sdcard_t; @@ -121,7 +122,7 @@ esp_err_t periph_sdcard_mount(esp_periph_handle_t periph) periph_sdcard_t *sdcard = esp_periph_get_data(periph); - int ret = sdcard_mount(sdcard->root); + int ret = sdcard_mount(sdcard->root, sdcard->sd_mode); if (ret == ESP_OK) { ESP_LOGD(TAG, "Mount SDCARD success"); sdcard->is_mounted = true; @@ -161,7 +162,11 @@ esp_periph_handle_t periph_sdcard_init(periph_sdcard_cfg_t *sdcard_cfg) AUDIO_MEM_CHECK(TAG, periph, return NULL); periph_sdcard_t *sdcard = audio_calloc(1, sizeof(periph_sdcard_t)); - AUDIO_MEM_CHECK(TAG, sdcard, return NULL); + AUDIO_MEM_CHECK(TAG, sdcard, { + audio_free(periph); + return NULL; + }); + if (sdcard_cfg->root) { sdcard->root = audio_strdup(sdcard_cfg->root); } else { @@ -169,10 +174,12 @@ esp_periph_handle_t periph_sdcard_init(periph_sdcard_cfg_t *sdcard_cfg) } AUDIO_MEM_CHECK(TAG, sdcard->root, { audio_free(sdcard); + audio_free(periph); return NULL; }); sdcard->card_detect_pin = sdcard_cfg->card_detect_pin; + sdcard->sd_mode = sdcard_cfg->mode; esp_periph_set_data(periph, sdcard); esp_periph_set_function(periph, _sdcard_init, _sdcard_run, _sdcard_destroy); return periph; diff --git a/components/esp_peripherals/periph_spiffs.c b/components/esp_peripherals/periph_spiffs.c index e19a1cc..b8e1695 100644 --- a/components/esp_peripherals/periph_spiffs.c +++ b/components/esp_peripherals/periph_spiffs.c @@ -151,7 +151,10 @@ esp_periph_handle_t periph_spiffs_init(periph_spiffs_cfg_t *spiffs_cfg) AUDIO_MEM_CHECK(TAG, periph, return NULL); periph_spiffs_t *spiffs = audio_calloc(1, sizeof(periph_spiffs_t)); - AUDIO_MEM_CHECK(TAG, spiffs, return NULL); + AUDIO_MEM_CHECK(TAG, spiffs, { + audio_free(periph); + return NULL; + }); if (spiffs_cfg->root) { spiffs->root = audio_strdup(spiffs_cfg->root); } else { @@ -174,6 +177,7 @@ esp_periph_handle_t periph_spiffs_init(periph_spiffs_cfg_t *spiffs_cfg) AUDIO_MEM_CHECK(TAG, spiffs->root, { audio_free(spiffs); + audio_free(periph); return NULL; }); diff --git a/components/esp_peripherals/periph_touch.c b/components/esp_peripherals/periph_touch.c index ee757c7..ee90ec6 100644 --- a/components/esp_peripherals/periph_touch.c +++ b/components/esp_peripherals/periph_touch.c @@ -108,8 +108,10 @@ esp_periph_handle_t periph_touch_init(periph_touch_cfg_t *config) esp_periph_handle_t periph = esp_periph_create(PERIPH_ID_TOUCH, "periph_touch"); AUDIO_MEM_CHECK(TAG, periph, return NULL); periph_touch_t *periph_touch = audio_calloc(1, sizeof(periph_touch_t)); - - AUDIO_MEM_CHECK(TAG, periph_touch, return NULL); + AUDIO_MEM_CHECK(TAG, periph_touch, { + audio_free(periph); + return NULL; + }); periph_touch->touch_mask = config->touch_mask; periph_touch->long_tap_time_ms = config->long_tap_time_ms; periph_touch->tap_threshold_percent = config->tap_threshold_percent; diff --git a/components/esp_peripherals/periph_wifi.c b/components/esp_peripherals/periph_wifi.c index ad0dd67..fad29dd 100644 --- a/components/esp_peripherals/periph_wifi.c +++ b/components/esp_peripherals/periph_wifi.c @@ -37,7 +37,7 @@ #if __has_include("esp_idf_version.h") #include "esp_idf_version.h" #else -#define ESP_IDF_VERSION_VAL(major, minor, patch) 0 +#define ESP_IDF_VERSION_VAL(major, minor, patch) 1 #endif static const char *TAG = "PERIPH_WIFI"; @@ -99,7 +99,7 @@ periph_wifi_state_t periph_wifi_is_connected(esp_periph_handle_t periph) return wifi->wifi_state; } -#if (ESP_IDF_VERSION > ESP_IDF_VERSION_VAL(3, 3, 2)) +#if (ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(4, 0, 0)) static void _wifi_smartconfig_event_callback(void *arg, esp_event_base_t event_base, int32_t event_id, void *event_data) { @@ -239,7 +239,7 @@ esp_err_t periph_wifi_config_start(esp_periph_handle_t periph, periph_wifi_confi // esp_wifi_start(); err |= esp_smartconfig_set_type(mode); err |= esp_smartconfig_fast_mode(true); -#if (ESP_IDF_VERSION > ESP_IDF_VERSION_VAL(3, 3, 2)) +#if (ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(4, 0, 0)) smartconfig_start_config_t cfg = SMARTCONFIG_START_CONFIG_DEFAULT(); err |= esp_smartconfig_start(&cfg); esp_event_handler_register(SC_EVENT, ESP_EVENT_ANY_ID, &_wifi_smartconfig_event_callback, NULL); @@ -289,7 +289,7 @@ static void wifi_reconnect_timer(xTimerHandle tmr) } } -#if (ESP_IDF_VERSION > ESP_IDF_VERSION_VAL(3, 3, 2)) +#if (ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(4, 0, 0)) static void _wifi_event_callback(void *arg, esp_event_base_t event_base, int32_t event_id, void *event_data) { @@ -387,9 +387,11 @@ static esp_err_t _wifi_init(esp_periph_handle_t self) ESP_LOGE(TAG, "Wifi has initialized"); return ESP_FAIL; } - -#if (ESP_IDF_VERSION > ESP_IDF_VERSION_VAL(3, 3, 2)) +#if (ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(4, 0, 0)) ESP_ERROR_CHECK(esp_event_loop_create_default()); +#if (ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(4, 1, 0)) + esp_netif_create_default_wifi_sta(); +#endif ESP_ERROR_CHECK(esp_event_handler_register(WIFI_EVENT, ESP_EVENT_ANY_ID, &_wifi_event_callback, self)); ESP_ERROR_CHECK(esp_event_handler_register(IP_EVENT, IP_EVENT_STA_GOT_IP, &_wifi_event_callback, self)); #else @@ -422,21 +424,21 @@ static esp_err_t _wifi_init(esp_periph_handle_t self) unsigned int client_key_bytes = periph_wifi->wpa2_e_cfg->wpa2_e_key_end - periph_wifi->wpa2_e_cfg->wpa2_e_key_start; ESP_ERROR_CHECK(esp_wifi_sta_wpa2_ent_set_ca_cert((const unsigned char *)periph_wifi->wpa2_e_cfg->ca_pem_start, ca_pem_bytes)); - ESP_ERROR_CHECK(esp_wifi_sta_wpa2_ent_set_cert_key((const unsigned char *)periph_wifi->wpa2_e_cfg->wpa2_e_cert_start, client_crt_bytes,\ - (const unsigned char *)periph_wifi->wpa2_e_cfg->wpa2_e_key_start, client_key_bytes, NULL, 0)); + ESP_ERROR_CHECK(esp_wifi_sta_wpa2_ent_set_cert_key((const unsigned char *)periph_wifi->wpa2_e_cfg->wpa2_e_cert_start, client_crt_bytes, \ + (const unsigned char *)periph_wifi->wpa2_e_cfg->wpa2_e_key_start, client_key_bytes, NULL, 0)); ESP_ERROR_CHECK(esp_wifi_sta_wpa2_ent_set_identity((uint8_t *)periph_wifi->wpa2_e_cfg->eap_id, strlen(periph_wifi->wpa2_e_cfg->eap_id))); if (periph_wifi->wpa2_e_cfg->eap_method == EAP_PEAP || periph_wifi->wpa2_e_cfg->eap_method == EAP_TTLS) { ESP_ERROR_CHECK(esp_wifi_sta_wpa2_ent_set_username((uint8_t *)periph_wifi->wpa2_e_cfg->eap_username, strlen(periph_wifi->wpa2_e_cfg->eap_username))); ESP_ERROR_CHECK(esp_wifi_sta_wpa2_ent_set_password((uint8_t *)periph_wifi->wpa2_e_cfg->eap_password, strlen(periph_wifi->wpa2_e_cfg->eap_password))); } -#if (ESP_IDF_VERSION > ESP_IDF_VERSION_VAL(3, 3, 2)) +#if (ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(4, 0, 0)) ESP_ERROR_CHECK(esp_wifi_sta_wpa2_ent_enable()); #else esp_wpa2_config_t wpa2_config = WPA2_CONFIG_INIT_DEFAULT(); ESP_ERROR_CHECK(esp_wifi_sta_wpa2_ent_enable(&wpa2_config)); #endif - + } ESP_ERROR_CHECK(esp_wifi_start()); @@ -458,7 +460,7 @@ static esp_err_t _wifi_destroy(esp_periph_handle_t self) esp_wifi_deinit(); audio_free(periph_wifi->ssid); audio_free(periph_wifi->password); - + vEventGroupDelete(periph_wifi->state_event); if (periph_wifi->wpa2_e_cfg != NULL) { audio_free(periph_wifi->wpa2_e_cfg); @@ -487,9 +489,11 @@ esp_periph_handle_t periph_wifi_init(periph_wifi_cfg_t *config) } periph_wifi->disable_auto_reconnect = config->disable_auto_reconnect; - periph_wifi->wpa2_e_cfg = audio_malloc(sizeof(periph_wpa2_enterprise_cfg_t)); - AUDIO_NULL_CHECK(TAG, periph_wifi->wpa2_e_cfg, return NULL); + AUDIO_NULL_CHECK(TAG, periph_wifi->wpa2_e_cfg, { + audio_free(periph); + goto _periph_wifi_init_failed; + }); memcpy(periph_wifi->wpa2_e_cfg, &config->wpa2_e_cfg, sizeof(periph_wpa2_enterprise_cfg_t)); esp_periph_set_data(periph, periph_wifi); diff --git a/components/playlist/test/test_playlist.c b/components/playlist/test/test_playlist.c index 2761e92..ab921e0 100644 --- a/components/playlist/test/test_playlist.c +++ b/components/playlist/test/test_playlist.c @@ -47,7 +47,7 @@ static esp_err_t initialize_sdcard(esp_periph_set_handle_t *set_in) esp_periph_set_handle_t set = esp_periph_set_init(&periph_cfg); TEST_ASSERT_NOT_NULL(set); *set_in = set; - ret = audio_board_sdcard_init(set); + ret = audio_board_sdcard_init(set, SD_MODE_1_LINE); return ret; } diff --git a/components/wifi_service/airkiss_config/airkiss_config.c b/components/wifi_service/airkiss_config/airkiss_config.c index 3f6a891..a99ba11 100644 --- a/components/wifi_service/airkiss_config/airkiss_config.c +++ b/components/wifi_service/airkiss_config/airkiss_config.c @@ -27,7 +27,6 @@ #include "freertos/task.h" #include "esp_system.h" #include "esp_wifi.h" -#include "esp_event_loop.h" #include "esp_log.h" #include "esp_timer.h" #include "audio_mem.h" diff --git a/components/wifi_service/blufi_config/blufi_security.c b/components/wifi_service/blufi_config/blufi_security.c index b44bbc1..1bf91e3 100644 --- a/components/wifi_service/blufi_config/blufi_security.c +++ b/components/wifi_service/blufi_config/blufi_security.c @@ -34,7 +34,24 @@ #include "mbedtls/aes.h" #include "mbedtls/dhm.h" #include "mbedtls/md5.h" + +#if __has_include("esp_idf_version.h") +#include "esp_idf_version.h" +#else +#define ESP_IDF_VERSION_VAL(major, minor, patch) 1 +#endif + +#if (ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(4, 0, 0)) + +#ifdef CONFIG_IDF_TARGET_ESP32 +#include "esp32/rom/crc.h" +#else +#include "esp32s2beta/rom/crc.h" +#endif // CONFIG_IDF_TARGET_ESP32 + +#else #include "rom/crc.h" +#endif //(ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(4, 0, 0)) #define BLUFI_SECURITY_TAG "BLUFI_SECURITY" /* diff --git a/components/wifi_service/include/wifi_service.h b/components/wifi_service/include/wifi_service.h index 6f2e867..61c39d8 100644 --- a/components/wifi_service/include/wifi_service.h +++ b/components/wifi_service/include/wifi_service.h @@ -42,6 +42,7 @@ typedef enum { WIFI_SERV_EVENT_CONNECTED, WIFI_SERV_EVENT_DISCONNECTED, WIFI_SERV_EVENT_SETTING_TIMEOUT, + WIFI_SERV_EVENT_SETTING_FAILED, WIFI_SERV_EVENT_SETTING_FINISHED, } wifi_service_event_t; @@ -54,6 +55,7 @@ typedef enum { WIFI_SERV_STA_AUTH_ERROR, WIFI_SERV_STA_AP_NOT_FOUND, WIFI_SERV_STA_BY_USER, + WIFI_SERV_STA_SET_INFO, } wifi_service_disconnect_reason_t; /** @@ -69,6 +71,7 @@ typedef struct { char *user_data; /*!< User data */ int setting_timeout_s; /*!< Timeout of setting WiFi */ int max_retry_time; /*!< Maximum times of reconnection */ + int max_prov_retry_time; /*!< Maximum times of reconnection after wifi provision*/ uint8_t max_ssid_num; /*!< Maximum ssid that can be stored */ } wifi_service_config_t; @@ -82,6 +85,7 @@ typedef struct { .user_data = NULL, \ .setting_timeout_s = 60, \ .max_retry_time = 5,\ + .max_prov_retry_time = 3, \ .max_ssid_num = 5, \ } @@ -227,6 +231,19 @@ wifi_service_disconnect_reason_t wifi_service_disconnect_reason_get(periph_servi */ esp_err_t wifi_service_erase_ssid_manager_info(periph_service_handle_t handle); + +/* + * @brief Get the last wifi configure + * + * @param handle The periph_service_handle_t instance + * @param wifi_cfg A pointer to wifi_config_t + * + * @return + * - ESP_OK, Success + * - Others, Fail + */ +esp_err_t wifi_service_get_last_ssid_cfg(periph_service_handle_t handle, wifi_config_t* wifi_cfg); + #ifdef __cplusplus } #endif diff --git a/components/wifi_service/smart_config/smart_config.c b/components/wifi_service/smart_config/smart_config.c index f135bb6..ba4016c 100755 --- a/components/wifi_service/smart_config/smart_config.c +++ b/components/wifi_service/smart_config/smart_config.c @@ -34,7 +34,7 @@ #if __has_include("esp_idf_version.h") #include "esp_idf_version.h" #else -#define ESP_IDF_VERSION_VAL(major, minor, patch) 0 +#define ESP_IDF_VERSION_VAL(major, minor, patch) 1 #endif static char *TAG = "SMART_CONFIG"; @@ -44,7 +44,7 @@ typedef struct { smartconfig_type_t type; } smart_config_info; -#if (ESP_IDF_VERSION > ESP_IDF_VERSION_VAL(3, 3, 2)) +#if (ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(4, 0, 0)) static void smartconfg_cb(void *arg, esp_event_base_t event_base, int32_t event_id, void *event_data) { @@ -139,7 +139,7 @@ static esp_err_t _smart_config_start(esp_wifi_setting_handle_t self) return ESP_FAIL; } -#if (ESP_IDF_VERSION > ESP_IDF_VERSION_VAL(3, 3, 2)) +#if (ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(4, 0, 0)) smartconfig_start_config_t cfg = SMARTCONFIG_START_CONFIG_DEFAULT(); ret = esp_smartconfig_start(&cfg); esp_event_handler_register(SC_EVENT, ESP_EVENT_ANY_ID, &smartconfg_cb, NULL); diff --git a/components/wifi_service/src/wifi_service.c b/components/wifi_service/src/wifi_service.c index 20767f7..6a7215d 100644 --- a/components/wifi_service/src/wifi_service.c +++ b/components/wifi_service/src/wifi_service.c @@ -44,7 +44,7 @@ #if __has_include("esp_idf_version.h") #include "esp_idf_version.h" #else -#define ESP_IDF_VERSION_VAL(major, minor, patch) 0 +#define ESP_IDF_VERSION_VAL(major, minor, patch) 1 #endif static const char *TAG = "WIFI_SERV"; @@ -84,6 +84,8 @@ typedef struct { EventGroupHandle_t sync_evt; int retry_times; int max_retry_time; + int prov_retry_times; + int max_prov_retry_time; bool retrying; } wifi_service_t; @@ -127,7 +129,7 @@ static void wifi_serv_state_send(void *que, int type, void *data, int len, int d } } -#if (ESP_IDF_VERSION > ESP_IDF_VERSION_VAL(3, 3, 2)) +#if (ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(4, 0, 0)) static void wifi_event_cb(void *arg, esp_event_base_t event_base, int32_t event_id, void *event_data) { @@ -143,6 +145,7 @@ static void wifi_event_cb(void *arg, esp_event_base_t event_base, wifi_event_sta_disconnected_t *event = (wifi_event_sta_disconnected_t *) event_data; if (serv->reason == WIFI_SERV_STA_BY_USER) { ESP_LOGI(TAG, "SYSTEM_EVENT_STA_DISCONNECTED, reason is WIFI_SERV_STA_BY_USER"); + wifi_serv_state_send(serv->wifi_serv_que, WIFI_SERV_EVENT_DISCONNECTED, 0, 0, 0); return; } wifi_serv_state_send(serv->wifi_serv_que, WIFI_SERV_EVENT_DISCONNECTED, 0, 0, 0); @@ -190,11 +193,12 @@ static esp_err_t wifi_event_cb(void *ctx, system_event_t *event) wifi_serv_state_send(serv->wifi_serv_que, WIFI_SERV_EVENT_CONNECTED, 0, 0, 0); break; case SYSTEM_EVENT_STA_DISCONNECTED: - if (serv->reason == WIFI_SERV_STA_BY_USER) { - ESP_LOGI(TAG, "SYSTEM_EVENT_STA_DISCONNECTED, reason is WIFI_SERV_STA_BY_USER"); + if (serv->reason == WIFI_SERV_STA_BY_USER || serv->reason == WIFI_SERV_STA_SET_INFO) { + ESP_LOGI(TAG, "SYSTEM_EVENT_STA_DISCONNECTED, reason is %d", serv->reason); + wifi_serv_state_send(serv->wifi_serv_que, WIFI_SERV_EVENT_DISCONNECTED, 0, 0, 0); break; } - wifi_serv_state_send(serv->wifi_serv_que, WIFI_SERV_EVENT_DISCONNECTED, 0, 0, 0); + switch (event->event_info.disconnected.reason) { case WIFI_REASON_AUTH_EXPIRE: case WIFI_REASON_4WAY_HANDSHAKE_TIMEOUT: @@ -214,6 +218,7 @@ static esp_err_t wifi_event_cb(void *ctx, system_event_t *event) serv->reason = WIFI_SERV_STA_COM_ERROR; break; } + wifi_serv_state_send(serv->wifi_serv_que, WIFI_SERV_EVENT_DISCONNECTED, 0, 0, 0); break; case SYSTEM_EVENT_AP_STACONNECTED: ESP_LOGI(TAG, "Station:"MACSTR" join, AID=%d", @@ -241,7 +246,7 @@ esp_err_t configure_wifi_sta_mode(wifi_config_t *wifi_cfg) static void wifi_sta_setup(void *para) { -#if (ESP_IDF_VERSION > ESP_IDF_VERSION_VAL(3, 3, 2)) +#if (ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(4, 0, 0)) ESP_ERROR_CHECK(esp_event_loop_create_default()); ESP_ERROR_CHECK(esp_event_handler_register(WIFI_EVENT, ESP_EVENT_ANY_ID, &wifi_event_cb, para)); ESP_ERROR_CHECK(esp_event_handler_register(IP_EVENT, IP_EVENT_STA_GOT_IP, &wifi_event_cb, para)); @@ -255,7 +260,7 @@ static void wifi_sta_setup(void *para) #endif wifi_init_config_t cfg = WIFI_INIT_CONFIG_DEFAULT(); ESP_ERROR_CHECK(esp_wifi_init(&cfg)); - ESP_ERROR_CHECK(esp_wifi_set_storage(WIFI_STORAGE_FLASH)); + ESP_ERROR_CHECK(esp_wifi_set_storage(WIFI_STORAGE_RAM)); } static esp_err_t wifi_init(void *instance, action_arg_t *arg, action_result_t *result) @@ -333,6 +338,7 @@ static void wifi_task(void *pvParameters) if (wifi_msg.type == WIFI_SERV_EVENT_CONNECTED) { serv->reason = WIFI_SERV_STA_UNKNOWN; serv->retry_times = 0; + serv->prov_retry_times = 0; serv->retrying = false; if (serv->is_setting) { esp_timer_stop(serv->setting_timer); @@ -343,12 +349,12 @@ static void wifi_task(void *pvParameters) item->running = false; esp_wifi_setting_teardown(item->on_handle, NULL); } + serv->is_setting = false; } wifi_ssid_manager_save(serv->ssid_manager, (const char *)wifi_cfg.sta.ssid, (const char *)wifi_cfg.sta.password); } if (wifi_msg.type == WIFI_SERV_EVENT_DISCONNECTED) { - if ((serv->reason != WIFI_SERV_STA_BY_USER) - ) { + if ((serv->reason != WIFI_SERV_STA_BY_USER) && (serv->reason != WIFI_SERV_STA_SET_INFO)) { retry_interval = serv->retry_times * 1000 * 1000 * 2; if (retry_interval > 60 * 1000 * 1000) { // Longest interval is 60s retry_interval = 60 * 1000 * 1000; @@ -381,24 +387,39 @@ static void wifi_task(void *pvParameters) ESP_LOGW(TAG, "Got max_retry_time = %d, the station will try to reconnect until connected", serv->max_retry_time); } ESP_LOGW(TAG, "Disconnect reason %d", serv->reason); - continue; + } else if (serv->reason == WIFI_SERV_STA_SET_INFO) { + if (serv->prov_retry_times < serv->max_prov_retry_time) { + vTaskDelay(2000 / portTICK_PERIOD_MS); + configure_wifi_sta_mode(&wifi_cfg); + wifi_service_connect(serv_handle); + serv->prov_retry_times ++; + ESP_LOGW(TAG, "Fail to connect to provision wifi, reason: %d, start to reconnect ...", serv->reason); + } else { + serv->prov_retry_times = 0; + serv->reason = WIFI_SERV_STA_UNKNOWN; + ESP_LOGE(TAG, "Please configure wifi again"); + cb_evt.type = WIFI_SERV_EVENT_SETTING_FAILED; + } + } else if (serv->reason == WIFI_SERV_STA_BY_USER) { + serv->reason = WIFI_SERV_STA_UNKNOWN; } } periph_service_callback(serv_handle, &cb_evt); } else if (wifi_msg.msg_type == WIFI_SERV_EVENT_TYPE_CMD) { if (wifi_msg.type == WIFI_SERV_CMD_CONNECT) { - if (wifi_ssid_manager_get_latest_config(serv->ssid_manager, &wifi_cfg) != ESP_OK) { - ESP_LOGW(TAG, "No ssid stored in flash, try to connect to wifi set by wifi_service_set_sta_info()"); - if (serv->info.sta.ssid[0] == 0) { - ESP_LOGW(TAG, "There is no preset ssid, please set the wifi first"); - continue; + if (serv->reason != WIFI_SERV_STA_SET_INFO) { + if (wifi_ssid_manager_get_latest_config(serv->ssid_manager, &wifi_cfg) != ESP_OK) { + ESP_LOGW(TAG, "No ssid stored in flash, try to connect to wifi set by wifi_service_set_sta_info()"); + if (serv->info.sta.ssid[0] == 0) { + ESP_LOGW(TAG, "There is no preset ssid, please set the wifi first"); + continue; + } + memcpy(&wifi_cfg, &serv->info, sizeof(wifi_config_t)); } - memcpy(&wifi_cfg, &serv->info, sizeof(wifi_config_t)); } ESP_LOGI(TAG, "Connect to wifi ssid: %s, pwd: %s", wifi_cfg.sta.ssid, wifi_cfg.sta.password); configure_wifi_sta_mode(&wifi_cfg); ESP_ERROR_CHECK(esp_wifi_connect()); - } else if (wifi_msg.type == WIFI_SERV_CMD_DISCONNECT) { serv->reason = WIFI_SERV_STA_BY_USER; ESP_LOGI(TAG, "WIFI_SERV_CMD_DISCONNECT"); @@ -438,14 +459,25 @@ static void wifi_task(void *pvParameters) serv->is_setting = false; } else if (wifi_msg.type == WIFI_SERV_CMD_DESTROY) { task_run = false; - ESP_LOGI(TAG, "DUER_CMD_DESTROY"); + ESP_LOGI(TAG, "WIFI_SERV_CMD_DESTROY"); } else if (wifi_msg.type == WIFI_SERV_CMD_UPDATE) { wifi_config_t *info = (wifi_config_t *)wifi_msg.pdata; - ESP_LOGI(TAG, "WIFI_SERV_CMD_UPDATE got ssid: %s, pwd: %s", info->sta.ssid, info->sta.password); - memcpy(&wifi_cfg, info, sizeof(wifi_config_t)); - configure_wifi_sta_mode(&wifi_cfg); - esp_wifi_connect(); - audio_free(info); + if (serv->is_setting) { + ESP_LOGI(TAG, "WIFI_SERV_CMD_UPDATE got ssid: %s, pwd: %s", info->sta.ssid, info->sta.password); + serv->reason = WIFI_SERV_STA_SET_INFO; + memcpy(&wifi_cfg, info, sizeof(wifi_config_t)); + configure_wifi_sta_mode(&wifi_cfg); + esp_wifi_connect(); + audio_free(info); + + cb_evt.type = WIFI_SERV_EVENT_SETTING_FINISHED; + cb_evt.source = serv_handle; + cb_evt.data = NULL; + cb_evt.len = 0; + periph_service_callback(serv_handle, &cb_evt); + } else { + ESP_LOGW(TAG, "Not setting state, ignore the wifi information, ssid: %s, pwd: %s", info->sta.ssid, info->sta.password); + } } } else { ESP_LOGI(TAG, "Not supported event type"); @@ -590,6 +622,12 @@ esp_err_t wifi_service_erase_ssid_manager_info(periph_service_handle_t handle) return ret; } +esp_err_t wifi_service_get_last_ssid_cfg(periph_service_handle_t handle, wifi_config_t* wifi_cfg) +{ + wifi_service_t *serv = periph_service_get_data(handle); + return wifi_ssid_manager_get_latest_config(serv->ssid_manager, wifi_cfg); +} + periph_service_handle_t wifi_service_create(wifi_service_config_t *config) { wifi_service_t *serv = audio_calloc(1, sizeof(wifi_service_t)); @@ -601,6 +639,7 @@ periph_service_handle_t wifi_service_create(wifi_service_config_t *config) return NULL; }); serv->max_retry_time = config->max_retry_time; + serv->max_prov_retry_time = config->max_prov_retry_time; STAILQ_INIT(&serv->setting_list); serv->wifi_serv_que = xQueueCreate(3, sizeof(wifi_task_msg_t)); diff --git a/docs/en/api-reference/framework/audio_element.rst b/docs/en/api-reference/framework/audio_element.rst index 30f62a8..1d301e0 100644 --- a/docs/en/api-reference/framework/audio_element.rst +++ b/docs/en/api-reference/framework/audio_element.rst @@ -5,7 +5,7 @@ The basic building block for the application programmer developing with ADF is t This API has been designed and then used to implement Audio Elements provided by ADF. -The general functionality of an Element is to take some data on input, processes it, and output to a the next. Each Element is run as a separate task. To enable control on particular stages of the data lifecycle from the input, during processing and up to the output, the ``audio_element`` object provides possibility to trigger callbacks per stage. There are seven types of available callback functions: open, seek, process, close, destroy, read and write, and they are defined in :cpp:type:`audio_element_cfg_t`. Particular Elements typically use a subset of all avialable callbacks. For instance the :doc:`../codecs/mp3_decoder` is using open, process, close and destroy callback functions. +The general functionality of an Element is to take some data on input, processes it, and output to a the next. Each Element is run as a separate task. To enable control on particular stages of the data lifecycle from the input, during processing and up to the output, the ``audio_element`` object provides possibility to trigger callbacks per stage. There are seven types of available callback functions: open, seek, process, close, destroy, read and write, and they are defined in :cpp:type:`audio_element_cfg_t`. Particular Elements typically use a subset of all available callbacks. For instance the :doc:`../codecs/mp3_decoder` is using open, process, close and destroy callback functions. The available Audio Element types intended for development with this API are listed in description of :doc:`audio_common.h ` header file under :cpp:type:`audio_element_type_t` enumerator. diff --git a/examples/advanced_examples/algorithm/CMakeLists.txt b/examples/advanced_examples/algorithm/CMakeLists.txt new file mode 100644 index 0000000..c188961 --- /dev/null +++ b/examples/advanced_examples/algorithm/CMakeLists.txt @@ -0,0 +1,8 @@ +# 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{ADF_PATH}/CMakeLists.txt) +include($ENV{IDF_PATH}/tools/cmake/project.cmake) + +project(algorithm_examples) diff --git a/examples/advanced_examples/algorithm/Makefile b/examples/advanced_examples/algorithm/Makefile new file mode 100644 index 0000000..41e11fc --- /dev/null +++ b/examples/advanced_examples/algorithm/Makefile @@ -0,0 +1,2 @@ +PROJECT_NAME := algorithm_examples +include $(ADF_PATH)/project.mk diff --git a/examples/advanced_examples/algorithm/README.md b/examples/advanced_examples/algorithm/README.md new file mode 100644 index 0000000..c7de417 --- /dev/null +++ b/examples/advanced_examples/algorithm/README.md @@ -0,0 +1,150 @@ +# Algorithm examples + +The example shows how to use algorithm API, and algorithm API contains AEC, AGC and NS. + +## 1. How to use example + +#### Hardware Required + +This example is will run on boards marked with green checkbox. Please remember to select the board in menuconfig as discussed is section *Usage* below. + +| Board Name | Getting Started | Chip | Compatible | +|-------------------|:--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------:|:--------------------------------------------------------------------:|:-----------------------------------------------------------------:| +| ESP32-LyraT | [![alt text](../../../docs/_static/esp32-lyrat-v4.3-side-small.jpg "ESP32-LyraT")](https://docs.espressif.com/projects/esp-adf/en/latest/get-started/get-started-esp32-lyrat.html) | ESP32 | ![alt text](../../../docs/_static/yes-button.png "Compatible") | +| ESP32-LyraTD-MSC | [![alt text](../../../docs/_static/esp32-lyratd-msc-v2.2-small.jpg "ESP32-LyraTD-MSC")](https://docs.espressif.com/projects/esp-adf/en/latest/get-started/get-started-esp32-lyratd-msc.html) | ESP32 | ![alt text](../../../docs/_static/no-button.png "Compatible") | +| ESP32-LyraT-Mini | [![alt text](../../../docs/_static/esp32-lyrat-mini-v1.2-small.jpg "ESP32-LyraT-Mini")](https://docs.espressif.com/projects/esp-adf/en/latest/get-started/get-started-esp32-lyrat-mini.html) | ESP32 | ![alt text](../../../docs/_static/yes-button.png "Compatible") | +| ESP32-Korvo-DU1906 | [![alt text](../../../docs/_static/esp32-korvo-du1906-v1.1-small.jpg "ESP32-Korvo-DU1906")](https://docs.espressif.com/projects/esp-adf/en/latest/get-started/get-started-esp32-korvo-du1906.html) | ESP32 | ![alt text](../../../docs/_static/no-button.png "Compatible") | +| ESP32-S2-Kaluga-1 Kit | [![alt text](../../../docs/_static/esp32-s2-kaluga-1-kit-small.png "ESP32-S2-Kaluga-1 Kit")](https://docs.espressif.com/projects/esp-idf/en/latest/esp32s2/hw-reference/esp32s2/user-guide-esp32-s2-kaluga-1-kit.html) | ESP32-S2 | ![alt text](../../../docs/_static/no-button.png "Compatible") | + +Prepare the audio board: + +- Insert a microSD card required memory of 1 MB into board's SD card slot. +- Insert a microSD card loaded with a MP3 file 'test.mp3' into board's slot. + +## 2. Setup software environment + +Please refer to [Get Started](https://docs.espressif.com/projects/esp-adf/en/latest/get-started/index.html#get-started). + +#### Configure the project +cmake menuconfig: +``` +idf.py menuconfig +``` +Or use legacy GNU make: +``` +make menuconfig +``` +Select compatible audio board in ``menuconfig > Audio HAL``, then compile the example. + +#### Build and Flash +You can use `GNU make` or `cmake` to build the project. +If you are using make: +```bash +cd $ADF_PATH/examples/advanced_examples/algorithm +make clean +make menuconfig +make -j4 all +``` + +Or if you are using cmake: +```bash +cd $ADF_PATH/examples/advanced_examples/algorithm +idf.py fullclean +idf.py menuconfig +idf.py build +``` +The firmware downloading flash address refer to follow table. + +|Flash address | Bin Path| +|---|---| +|0x1000 | build/bootloader/bootloader.bin| +|0x8000 | build/partitiontable/partition-table.bin| +|0x10000 | build/algorithm_examples.bin| + +To exit the serial monitor, type ``Ctrl-]``. + +## 3. Example Output + +After download the follow logs should be output, here: + +``` +I (10) boot: ESP-IDF v3.3.2-107-g722043f 2nd stage bootloader +I (10) boot: compile time 17:34:10 +I (10) boot: Enabling RNG early entropy source... +I (14) boot: SPI Speed : 80MHz +I (19) boot: SPI Mode : DIO +I (23) boot: SPI Flash Size : 2MB +I (27) boot: Partition Table: +I (30) boot: ## Label Usage Type ST Offset Length +I (37) boot: 0 nvs WiFi data 01 02 00009000 00006000 +I (45) boot: 1 phy_init RF data 01 01 0000f000 00001000 +I (52) boot: 2 factory factory app 00 00 00010000 00100000 +I (60) boot: End of partition table +I (64) boot_comm: chip revision: 1, min. application chip revision: 0 +I (71) esp_image: segment 0: paddr=0x00010020 vaddr=0x3f400020 size=0x44d80 (281984) map +I (162) esp_image: segment 1: paddr=0x00054da8 vaddr=0x3ffb0000 size=0x01f7c ( 8060) load +I (165) esp_image: segment 2: paddr=0x00056d2c vaddr=0x40080000 size=0x00400 ( 1024) load +0x40080000: _WindowOverflow4 at /home/zhanghu/esp/esp-adf-internal/esp-idf/components/freertos/xtensa_vectors.S:1779 + +I (169) esp_image: segment 3: paddr=0x00057134 vaddr=0x40080400 size=0x08edc ( 36572) load +I (191) esp_image: segment 4: paddr=0x00060018 vaddr=0x400d0018 size=0x3be68 (245352) map +0x400d0018: _flash_cache_start at ??:? + +I (263) esp_image: segment 5: paddr=0x0009be88 vaddr=0x400892dc size=0x02bbc ( 11196) load +0x400892dc: xTaskResumeAll at /home/zhanghu/esp/esp-adf-internal/esp-idf/components/freertos/tasks.c:3507 + +I (274) boot: Loaded app from partition at offset 0x10000 +I (274) boot: Disabling RNG early entropy source... +I (275) cpu_start: Pro cpu up. +I (278) cpu_start: Application information: +I (283) cpu_start: Project name: esp-idf +I (288) cpu_start: App version: v1.0-667-g3cc7193 +I (294) cpu_start: Compile time: Nov 18 2020 17:34:09 +I (300) cpu_start: ELF file SHA256: 919997b2271ad260... +I (306) cpu_start: ESP-IDF: v3.3.2-107-g722043f +I (312) cpu_start: Starting app cpu, entry point is 0x400811fc +0x400811fc: call_start_cpu1 at /home/zhanghu/esp/esp-adf-internal/esp-idf/components/esp32/cpu_start.c:268 + +I (0) cpu_start: App cpu up. +I (322) heap_init: Initializing. RAM available for dynamic allocation: +I (329) heap_init: At 3FFAE6E0 len 00001920 (6 KiB): DRAM +I (335) heap_init: At 3FFB3140 len 0002CEC0 (179 KiB): DRAM +I (341) heap_init: At 3FFE0440 len 00003AE0 (14 KiB): D/IRAM +I (348) heap_init: At 3FFE4350 len 0001BCB0 (111 KiB): D/IRAM +I (354) heap_init: At 4008BE98 len 00014168 (80 KiB): IRAM +I (360) cpu_start: Pro cpu start user code +I (154) cpu_start: Starting scheduler on PRO CPU. +I (0) cpu_start: Starting scheduler on APP CPU. +I (155) ALGORITHM_EXAMPLES: [1.0] Mount sdcard +I (661) ALGORITHM_EXAMPLES: [2.0] Start codec chip +W (682) I2C_BUS: i2c_bus_create:57: I2C bus has been already created, [port:0] +I (692) ALGORITHM_EXAMPLES: [3.0] Create audio pipeline_rec for recording +I (692) ALGORITHM_EXAMPLES: [3.1] Create i2s stream to read audio data from codec chip +I (699) ALGORITHM_EXAMPLES: [3.2] Create mp3 encoder to encode mp3 format +I (705) ALGORITHM_EXAMPLES: [3.3] Create fatfs stream to write data to sdcard +I (713) ALGORITHM_EXAMPLES: [3.4] Register all elements to audio pipeline +I (720) ALGORITHM_EXAMPLES: [3.5] Link it together [codec_chip]-->i2s_stream-->mp3_encoder-->fatfs_stream-->[sdcard] +I (732) ALGORITHM_EXAMPLES: [3.6] Set up uri (file as fatfs_stream, mp3 as mp3 encoder) +I (740) ALGORITHM_EXAMPLES: [4.0] Create audio pipeline_rec for recording +I (748) ALGORITHM_EXAMPLES: [4.1] Create fatfs stream to read data from sdcard +I (756) ALGORITHM_EXAMPLES: [4.2] Create mp3 decoder to decode mp3 file +I (763) ALGORITHM_EXAMPLES: [4.3] Create i2s stream to write data to codec chip +I (773) ALGORITHM_EXAMPLES: [4.4] Register all elements to audio pipeline +I (778) ALGORITHM_EXAMPLES: [4.5] Link it together [sdcard]-->fatfs_stream-->mp3_decoder-->i2s_stream-->[codec_chip] +I (790) ALGORITHM_EXAMPLES: [4.6] Set up uri (file as fatfs_stream, mp3 as mp3 decoder, and default output is i2s) +I (801) ALGORITHM_EXAMPLES: [5.0] Set up event listener +I (807) ALGORITHM_EXAMPLES: [5.1] Listening event from all elements of pipeline +I (815) ALGORITHM_EXAMPLES: [5.2] Listening event from peripherals +I (821) ALGORITHM_EXAMPLES: [6.0] Start audio_pipeline +I (869) ALGORITHM_EXAMPLES: [7.0] Listen for all pipeline events + +``` + +Load and run the example: + +- The board will start playing automatically. +- After finish, you can open `/sdcard/rec_out.wav` to hear the recorded file. + +## 4. Troubleshooting + +- - If the AEC effect is not very good, you can set all the sampling rates to 16000. diff --git a/examples/advanced_examples/algorithm/main/CMakeLists.txt b/examples/advanced_examples/algorithm/main/CMakeLists.txt new file mode 100644 index 0000000..9fb9235 --- /dev/null +++ b/examples/advanced_examples/algorithm/main/CMakeLists.txt @@ -0,0 +1,4 @@ +set(COMPONENT_SRCS "algorithm_examples.c") +set(COMPONENT_ADD_INCLUDEDIRS .) + +register_component() diff --git a/examples/advanced_examples/algorithm/main/algorithm_examples.c b/examples/advanced_examples/algorithm/main/algorithm_examples.c new file mode 100644 index 0000000..f22342c --- /dev/null +++ b/examples/advanced_examples/algorithm/main/algorithm_examples.c @@ -0,0 +1,237 @@ +/* Record wav and amr to SD card + + 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 "freertos/FreeRTOS.h" +#include "freertos/task.h" +#include "esp_log.h" +#include "sdkconfig.h" +#include "esp_log.h" +#include "audio_element.h" +#include "audio_pipeline.h" +#include "board.h" +#include "fatfs_stream.h" +#include "i2s_stream.h" +#include "wav_encoder.h" +#include "mp3_decoder.h" +#include "filter_resample.h" +#include "algorithm_stream.h" + +static const char *TAG = "ALGORITHM_EXAMPLES"; + +#if defined CONFIG_ESP_LYRAT_MINI_V1_1_BOARD +#define MINI_I2S_READER_SAMPLES 16000 +#define MINI_I2S_READER_BITS 16 +#define MINI_I2S_READER_CHANNEL 1 +#endif + +void app_main() +{ + audio_pipeline_handle_t pipeline_rec, pipeline_play; + audio_element_handle_t i2s_stream_writer, i2s_stream_reader, wav_encoder, mp3_decoder, fatfs_stream_writer, fatfs_stream_reader; + audio_element_handle_t element_algo; + + esp_log_level_set("*", ESP_LOG_WARN); + esp_log_level_set(TAG, ESP_LOG_INFO); + + ESP_LOGI(TAG, "[1.0] Mount sdcard"); + // Initialize peripherals management + esp_periph_config_t periph_cfg = DEFAULT_ESP_PERIPH_SET_CONFIG(); + esp_periph_set_handle_t set = esp_periph_set_init(&periph_cfg); + // Initialize SD Card peripheral + audio_board_sdcard_init(set, SD_MODE_1_LINE); + + ESP_LOGI(TAG, "[2.0] Start codec chip"); + audio_board_handle_t board_handle = audio_board_init(); + audio_hal_ctrl_codec(board_handle->audio_hal, AUDIO_HAL_CODEC_MODE_BOTH, AUDIO_HAL_CTRL_START); + audio_hal_set_volume(board_handle->audio_hal, 50); + + ESP_LOGI(TAG, "[3.0] Create audio pipeline_rec for recording"); + audio_pipeline_cfg_t pipeline_cfg = DEFAULT_AUDIO_PIPELINE_CONFIG(); + pipeline_rec = audio_pipeline_init(&pipeline_cfg); + mem_assert(pipeline_rec); + + ESP_LOGI(TAG, "[3.1] Create i2s stream to read audio data from codec chip"); + i2s_stream_cfg_t i2s_rd_cfg = I2S_STREAM_CFG_DEFAULT(); + i2s_rd_cfg.type = AUDIO_STREAM_READER; +#if defined CONFIG_ESP_LYRAT_MINI_V1_1_BOARD + i2s_rd_cfg.i2s_config.use_apll = false; + i2s_rd_cfg.i2s_port = 1; +#endif + i2s_stream_reader = i2s_stream_init(&i2s_rd_cfg); + + algorithm_stream_cfg_t algo_config = ALGORITHM_STREAM_CFG_DEFAULT(); +#if defined CONFIG_ESP_LYRAT_MINI_V1_1_BOARD + algo_config.input_type = ALGORITHM_STREAM_INPUT_TYPE1; +#elif defined CONFIG_ESP_LYRAT_V4_3_BOARD + algo_config.input_type = ALGORITHM_STREAM_INPUT_TYPE2; +#else + ESP_LOGE(TAG, "[ * ] Do not support current board"); + return; +#endif + algo_config.input_type = ALGORITHM_STREAM_INPUT_TYPE2; + element_algo = algo_stream_init(&algo_config); + + ESP_LOGI(TAG, "[3.2] Create mp3 encoder to encode mp3 format"); + wav_encoder_cfg_t wav_cfg = DEFAULT_WAV_ENCODER_CONFIG(); + wav_encoder = wav_encoder_init(&wav_cfg); + + ESP_LOGI(TAG, "[3.3] Create fatfs stream to write data to sdcard"); + fatfs_stream_cfg_t fatfs_wd_cfg = FATFS_STREAM_CFG_DEFAULT(); + fatfs_wd_cfg.type = AUDIO_STREAM_WRITER; + fatfs_stream_writer = fatfs_stream_init(&fatfs_wd_cfg); + + ESP_LOGI(TAG, "[3.4] Register all elements to audio pipeline"); + audio_pipeline_register(pipeline_rec, i2s_stream_reader, "i2s_rd"); + audio_pipeline_register(pipeline_rec, element_algo, "algo"); + audio_pipeline_register(pipeline_rec, wav_encoder, "wav_encoder"); + audio_pipeline_register(pipeline_rec, fatfs_stream_writer, "mp3_wd_file"); + + ESP_LOGI(TAG, "[3.5] Link it together [codec_chip]-->i2s_stream-->mp3_encoder-->fatfs_stream-->[sdcard]"); + const char *link_rec[4] = {"i2s_rd", "algo", "wav_encoder", "mp3_wd_file"}; + audio_pipeline_link(pipeline_rec, &link_rec[0], 4); + + ESP_LOGI(TAG, "[3.6] Set up uri (file as fatfs_stream, mp3 as mp3 encoder)"); + audio_element_set_uri(fatfs_stream_writer, "/sdcard/rec_out.wav"); + + ESP_LOGI(TAG, "[4.0] Create audio pipeline_rec for recording"); + audio_pipeline_cfg_t pipeline_play_cfg = DEFAULT_AUDIO_PIPELINE_CONFIG(); + pipeline_play = audio_pipeline_init(&pipeline_play_cfg); + + ESP_LOGI(TAG, "[4.1] Create fatfs stream to read data from sdcard"); + fatfs_stream_cfg_t fatfs_rd_cfg = FATFS_STREAM_CFG_DEFAULT(); + fatfs_rd_cfg.type = AUDIO_STREAM_READER; + fatfs_stream_reader = fatfs_stream_init(&fatfs_rd_cfg); + + ESP_LOGI(TAG, "[4.2] Create mp3 decoder to decode mp3 file"); + mp3_decoder_cfg_t mp3_decoder_cfg = DEFAULT_MP3_DECODER_CONFIG(); + mp3_decoder = mp3_decoder_init(&mp3_decoder_cfg); + + ESP_LOGI(TAG, "[4.3] Create i2s stream to write data to codec chip"); + i2s_stream_cfg_t i2s_wd_cfg = I2S_STREAM_CFG_DEFAULT(); + i2s_wd_cfg.type = AUDIO_STREAM_WRITER; + i2s_stream_writer = i2s_stream_init(&i2s_wd_cfg); + + ESP_LOGI(TAG, "[4.4] Register all elements to audio pipeline"); + audio_pipeline_register(pipeline_play, fatfs_stream_reader, "file_rd"); + audio_pipeline_register(pipeline_play, mp3_decoder, "mp3_decoder"); + audio_pipeline_register(pipeline_play, i2s_stream_writer, "i2s_wd"); + + ESP_LOGI(TAG, "[4.5] Link it together [sdcard]-->fatfs_stream-->mp3_decoder-->i2s_stream-->[codec_chip]"); + const char *link_tag[3] = {"file_rd", "mp3_decoder", "i2s_wd"}; + audio_pipeline_link(pipeline_play, &link_tag[0], 3); + + ESP_LOGI(TAG, "[4.6] Set up uri (file as fatfs_stream, mp3 as mp3 decoder, and default output is i2s)"); + audio_element_set_uri(fatfs_stream_reader, "/sdcard/test.mp3"); + +#if defined CONFIG_ESP_LYRAT_V4_3_BOARD + //Please reference the way of ALGORITHM_STREAM_INPUT_TYPE2 in "algorithm_stream.h" + ringbuf_handle_t input_rb = algo_stream_get_multi_input_rb(element_algo); + audio_element_set_multi_output_ringbuf(mp3_decoder, input_rb, 0); +#endif + + ESP_LOGI(TAG, "[5.0] Set up event listener"); + audio_event_iface_cfg_t evt_cfg = AUDIO_EVENT_IFACE_DEFAULT_CFG(); + audio_event_iface_handle_t evt = audio_event_iface_init(&evt_cfg); + + ESP_LOGI(TAG, "[5.1] Listening event from all elements of pipeline"); + audio_pipeline_set_listener(pipeline_play, evt); + + ESP_LOGI(TAG, "[5.2] Listening event from peripherals"); + audio_event_iface_set_listener(esp_periph_set_get_event_iface(set), evt); + + ESP_LOGI(TAG, "[6.0] Start audio_pipeline"); + + audio_element_info_t fat_info = {0}; + audio_element_getinfo(fatfs_stream_writer, &fat_info); + fat_info.sample_rates = ALGORITHM_STREAM_DEFAULT_SAMPLE_RATE_HZ; + fat_info.channels = ALGORITHM_STREAM_DEFAULT_CHANNEL; + fat_info.bits = ALGORITHM_STREAM_DEFAULT_SAMPLE_BIT; + audio_element_setinfo(fatfs_stream_writer, &fat_info); + +#if defined CONFIG_ESP_LYRAT_MINI_V1_1_BOARD + //The purpose is to set a fixed frequency, when current board is "lyrat mini v1.1". + i2s_stream_set_clk(i2s_stream_reader, MINI_I2S_READER_SAMPLES, MINI_I2S_READER_BITS, MINI_I2S_READER_CHANNEL); + algo_stream_set_record_rate(element_algo, MINI_I2S_READER_CHANNEL, MINI_I2S_READER_SAMPLES); +#endif + + audio_pipeline_run(pipeline_play); + audio_pipeline_run(pipeline_rec); + + ESP_LOGI(TAG, "[7.0] Listen for all pipeline events"); + + while (1) { + audio_event_iface_msg_t msg; + esp_err_t ret = audio_event_iface_listen(evt, &msg, portMAX_DELAY); + if (ret != ESP_OK) { + ESP_LOGE(TAG, "[ * ] Event interface error : %d", ret); + continue; + } + + if (msg.source_type == AUDIO_ELEMENT_TYPE_ELEMENT && msg.source == (void *) mp3_decoder + && msg.cmd == AEL_MSG_CMD_REPORT_MUSIC_INFO) { + audio_element_info_t music_info = {0}; + audio_element_getinfo(mp3_decoder, &music_info); + + ESP_LOGI(TAG, "[ * ] Receive music info from mp3 decoder, sample_rates=%d, bits=%d, ch=%d", + music_info.sample_rates, music_info.bits, music_info.channels); + + i2s_stream_set_clk(i2s_stream_writer, music_info.sample_rates, music_info.bits, music_info.channels); + +#if defined CONFIG_ESP_LYRAT_V4_3_BOARD + algo_stream_set_record_rate(element_algo, music_info.channels, music_info.sample_rates); + algo_stream_set_reference_rate(element_algo, music_info.channels, music_info.sample_rates); +#endif + continue; + } + + /* Stop when the last pipeline element (i2s_stream_writer in this case) receives stop event */ + if (msg.source_type == AUDIO_ELEMENT_TYPE_ELEMENT && msg.source == (void *) i2s_stream_writer + && msg.cmd == AEL_MSG_CMD_REPORT_STATUS + && (((int)msg.data == AEL_STATUS_STATE_STOPPED) || ((int)msg.data == AEL_STATUS_STATE_FINISHED))) { + ESP_LOGW(TAG, "[ * ] Stop event received"); + break; + } + } + + audio_pipeline_stop(pipeline_rec); + audio_pipeline_wait_for_stop(pipeline_rec); + audio_pipeline_terminate(pipeline_rec); + audio_pipeline_unregister_more(pipeline_rec, i2s_stream_reader, + wav_encoder, fatfs_stream_writer); + + audio_pipeline_stop(pipeline_play); + audio_pipeline_wait_for_stop(pipeline_play); + audio_pipeline_terminate(pipeline_play); + audio_pipeline_unregister_more(pipeline_play, fatfs_stream_reader, + mp3_decoder, i2s_stream_writer); + + ESP_LOGI(TAG, "[8.0] Stop audio_pipeline"); + + /* Terminate the pipeline before removing the listener */ + audio_pipeline_remove_listener(pipeline_play); + + /* Stop all periph before removing the listener */ + esp_periph_set_stop_all(set); + audio_event_iface_remove_listener(esp_periph_set_get_event_iface(set), evt); + + /* Make sure audio_pipeline_remove_listener & audio_event_iface_remove_listener are called before destroying event_iface */ + audio_event_iface_destroy(evt); + + /* Release all resources */ + audio_pipeline_deinit(pipeline_rec); + audio_element_deinit(i2s_stream_reader); + audio_element_deinit(wav_encoder); + audio_element_deinit(fatfs_stream_writer); + + audio_pipeline_deinit(pipeline_play); + audio_element_deinit(fatfs_stream_reader); + audio_element_deinit(mp3_decoder); + audio_element_deinit(i2s_stream_writer); + + esp_periph_set_destroy(set); +} diff --git a/examples/advanced_examples/algorithm/main/component.mk b/examples/advanced_examples/algorithm/main/component.mk new file mode 100644 index 0000000..44bd2b5 --- /dev/null +++ b/examples/advanced_examples/algorithm/main/component.mk @@ -0,0 +1,3 @@ +# +# Main Makefile. This is basically the same as a component makefile. +# diff --git a/examples/advanced_examples/algorithm/sdkconfig.defaults b/examples/advanced_examples/algorithm/sdkconfig.defaults new file mode 100644 index 0000000..bf828ad --- /dev/null +++ b/examples/advanced_examples/algorithm/sdkconfig.defaults @@ -0,0 +1,30 @@ +# Override some defaults + +# +# Serial flasher config +# +CONFIG_FLASHMODE_QIO=y +CONFIG_ESPTOOLPY_FLASHMODE="qio" +CONFIG_ESPTOOLPY_FLASHFREQ_80M=y +CONFIG_ESPTOOLPY_FLASHFREQ="80m" +CONFIG_ESPTOOLPY_FLASHSIZE_4MB=y +CONFIG_ESPTOOLPY_FLASHSIZE="4MB" +CONFIG_ESPTOOLPY_FLASHSIZE_DETECT=y + +# +# FreeRTOS +# +CONFIG_FREERTOS_HZ=1000 + +# +# ESP32-specific +# +CONFIG_ESP32_DEFAULT_CPU_FREQ_240=y + +# +# FAT Filesystem support +# +CONFIG_FATFS_CODEPAGE_936=y +CONFIG_FATFS_LFN_HEAP=y +CONFIG_FATFS_MAX_LFN=255 +CONFIG_FATFS_FS_LOCK=5 diff --git a/examples/advanced_examples/dlna/CMakeLists.txt b/examples/advanced_examples/dlna/CMakeLists.txt index 1da8c1e..8c38d45 100644 --- a/examples/advanced_examples/dlna/CMakeLists.txt +++ b/examples/advanced_examples/dlna/CMakeLists.txt @@ -13,4 +13,5 @@ target_add_binary_data(dlna_example.elf "./components/esp_dlna/xml/rootDesc.xml" target_add_binary_data(dlna_example.elf "./components/esp_dlna/xml/rootDescLogo.xml" TEXT) target_add_binary_data(dlna_example.elf "./components/esp_dlna/xml/rootDescService.xml" TEXT) target_add_binary_data(dlna_example.elf "./components/esp_dlna/xml/SoapResponseErr.xml" TEXT) -target_add_binary_data(dlna_example.elf "./components/esp_dlna/xml/SoapResponseOk.xml" TEXT) \ No newline at end of file +target_add_binary_data(dlna_example.elf "./components/esp_dlna/xml/SoapResponseOk.xml" TEXT) +target_add_binary_data(dlna_example.elf "./components/esp_dlna/xml/devicelist.xml" TEXT) \ No newline at end of file diff --git a/examples/advanced_examples/dlna/main/dlna_example.c b/examples/advanced_examples/dlna/main/dlna_example.c index 7504d1a..cf57c97 100644 --- a/examples/advanced_examples/dlna/main/dlna_example.c +++ b/examples/advanced_examples/dlna/main/dlna_example.c @@ -23,6 +23,18 @@ #include "http_stream.h" #include "i2s_stream.h" +#if __has_include("esp_idf_version.h") +#include "esp_idf_version.h" +#else +#define ESP_IDF_VERSION_VAL(major, minor, patch) 1 +#endif + +#if (ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(4, 1, 0)) +#include "esp_netif.h" +#else +#include "tcpip_adapter.h" +#endif + static const char *TAG = "DLNA_EXAMPLE"; #define DLNA_UNIQUE_DEVICE_NAME "ESP32_DMR_8db0797a" @@ -309,7 +321,11 @@ void app_main() ret = nvs_flash_init(); } ESP_ERROR_CHECK(ret); +#if (ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(4, 1, 0)) + ESP_ERROR_CHECK(esp_netif_init()); +#else tcpip_adapter_init(); +#endif esp_periph_config_t periph_cfg = DEFAULT_ESP_PERIPH_SET_CONFIG(); esp_periph_set_handle_t set = esp_periph_set_init(&periph_cfg); diff --git a/examples/advanced_examples/downmix_pipeline/main/downmix_pipeline_main.c b/examples/advanced_examples/downmix_pipeline/main/downmix_pipeline_main.c index 5c5abc6..094af5e 100644 --- a/examples/advanced_examples/downmix_pipeline/main/downmix_pipeline_main.c +++ b/examples/advanced_examples/downmix_pipeline/main/downmix_pipeline_main.c @@ -47,7 +47,7 @@ void app_main(void) ESP_LOGI(TAG, "[2.0] Start and wait for SDCARD to mount"); esp_periph_config_t periph_cfg = DEFAULT_ESP_PERIPH_SET_CONFIG(); esp_periph_set_handle_t set = esp_periph_set_init(&periph_cfg); - audio_board_sdcard_init(set); + audio_board_sdcard_init(set, SD_MODE_1_LINE); audio_board_key_init(set); ESP_LOGI(TAG, "[3.0] Create pipeline_mix to mix"); @@ -116,7 +116,7 @@ void app_main(void) audio_pipeline_register(pipeline[i], fats_rd_el[i], "file"); audio_pipeline_register(pipeline[i], wav_decoder[i], "wav"); audio_pipeline_register(pipeline[i], el_raw_write[i], "raw"); - + const char *link_tag[3] = {"file", "wav", "raw"}; audio_pipeline_link(pipeline[i], &link_tag[0], 3); ringbuf_handle_t rb = audio_element_get_input_ringbuf(el_raw_write[i]); @@ -125,6 +125,7 @@ void app_main(void) } ESP_LOGI(TAG, "[5.1] Listening event from peripherals"); + audio_pipeline_set_listener(pipeline_mix, evt); audio_event_iface_set_listener(esp_periph_set_get_event_iface(set), evt); downmix_set_output_type(downmixer, PLAY_STATUS); i2s_stream_set_clk(i2s_writer, SAMPLERATE, 16, PLAY_STATUS); diff --git a/examples/advanced_examples/esp_dispatcher_dueros/README.md b/examples/advanced_examples/esp_dispatcher_dueros/README.md index 4849b0c..d7c2637 100644 --- a/examples/advanced_examples/esp_dispatcher_dueros/README.md +++ b/examples/advanced_examples/esp_dispatcher_dueros/README.md @@ -11,7 +11,7 @@ This example is will run on boards marked with green checkbox. Please remember t | ESP32-LyraT | [![alt text](../../../docs/_static/esp32-lyrat-v4.3-side-small.jpg "ESP32-LyraT")](https://docs.espressif.com/projects/esp-adf/en/latest/get-started/get-started-esp32-lyrat.html) | ESP32 | ![alt text](../../../docs/_static/yes-button.png "Compatible") | | ESP32-LyraTD-MSC | [![alt text](../../../docs/_static/esp32-lyratd-msc-v2.2-small.jpg "ESP32-LyraTD-MSC")](https://docs.espressif.com/projects/esp-adf/en/latest/get-started/get-started-esp32-lyratd-msc.html) | ESP32 | ![alt text](../../../docs/_static/yes-button.png "Compatible") | | ESP32-LyraT-Mini | [![alt text](../../../docs/_static/esp32-lyrat-mini-v1.2-small.jpg "ESP32-LyraT-Mini")](https://docs.espressif.com/projects/esp-adf/en/latest/get-started/get-started-esp32-lyrat-mini.html) | ESP32 | ![alt text](../../../docs/_static/yes-button.png "Compatible") | -| ESP32-Korvo-DU1906 | [![alt text](../../../docs/_static/esp32-korvo-du1906-v1.1-small.jpg "ESP32-Korvo-DU1906")](https://docs.espressif.com/projects/esp-adf/en/latest/get-started/get-started-esp32-korvo-du1906.html) | ESP32 | ![alt text](../../../docs/_static/yes-button.png "Compatible") | +| ESP32-Korvo-DU1906 | [![alt text](../../../docs/_static/esp32-korvo-du1906-v1.1-small.jpg "ESP32-Korvo-DU1906")](https://docs.espressif.com/projects/esp-adf/en/latest/get-started/get-started-esp32-korvo-du1906.html) | ESP32 | ![alt text](../../../docs/_static/no-button.png "Compatible") | | ESP32-S2-Kaluga-1 Kit | [![alt text](../../../docs/_static/esp32-s2-kaluga-1-kit-small.png "ESP32-S2-Kaluga-1 Kit")](https://docs.espressif.com/projects/esp-idf/en/latest/esp32s2/hw-reference/esp32s2/user-guide-esp32-s2-kaluga-1-kit.html) | ESP32-S2 | ![alt text](../../../docs/_static/no-button.png "Compatible") | ## Usage diff --git a/examples/advanced_examples/esp_dispatcher_dueros/main/app_main.c b/examples/advanced_examples/esp_dispatcher_dueros/main/app_main.c index 9c4b931..0f194a4 100644 --- a/examples/advanced_examples/esp_dispatcher_dueros/main/app_main.c +++ b/examples/advanced_examples/esp_dispatcher_dueros/main/app_main.c @@ -27,9 +27,20 @@ #include "freertos/task.h" #include "freertos/event_groups.h" #include "nvs_flash.h" -#include "tcpip_adapter.h" #include "esp_dispatcher_dueros_app.h" +#if __has_include("esp_idf_version.h") +#include "esp_idf_version.h" +#else +#define ESP_IDF_VERSION_VAL(major, minor, patch) 1 +#endif + +#if (ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(4, 1, 0)) +#include "esp_netif.h" +#else +#include "tcpip_adapter.h" +#endif + void app_main(void) { esp_err_t err = nvs_flash_init(); @@ -39,6 +50,10 @@ void app_main(void) ESP_ERROR_CHECK(nvs_flash_erase()); ESP_ERROR_CHECK(nvs_flash_init()); } +#if (ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(4, 1, 0)) + ESP_ERROR_CHECK(esp_netif_init()); +#else tcpip_adapter_init(); +#endif duer_app_init(); } diff --git a/examples/advanced_examples/esp_dispatcher_dueros/main/audio_setup.c b/examples/advanced_examples/esp_dispatcher_dueros/main/audio_setup.c index dacdebc..ebec21e 100644 --- a/examples/advanced_examples/esp_dispatcher_dueros/main/audio_setup.c +++ b/examples/advanced_examples/esp_dispatcher_dueros/main/audio_setup.c @@ -140,7 +140,7 @@ static esp_err_t recorder_pipeline_open(void **handle) i2s_cfg.i2s_port = 1; i2s_cfg.i2s_config.use_apll = 0; i2s_cfg.i2s_config.sample_rate = 16000; - i2s_cfg.i2s_config.channel_format = I2S_CHANNEL_FMT_ONLY_LEFT; + i2s_cfg.i2s_config.channel_format = I2S_CHANNEL_FMT_ONLY_RIGHT; i2s_cfg.type = AUDIO_STREAM_READER; i2s_stream_reader = i2s_stream_init(&i2s_cfg); #else diff --git a/examples/advanced_examples/esp_dispatcher_dueros/main/esp_dispatcher_dueros_app.c b/examples/advanced_examples/esp_dispatcher_dueros/main/esp_dispatcher_dueros_app.c index 31622cd..6b49e4c 100644 --- a/examples/advanced_examples/esp_dispatcher_dueros/main/esp_dispatcher_dueros_app.c +++ b/examples/advanced_examples/esp_dispatcher_dueros/main/esp_dispatcher_dueros_app.c @@ -230,7 +230,7 @@ void duer_app_init(void) esp_periph_config_t periph_cfg = DEFAULT_ESP_PERIPH_SET_CONFIG(); esp_periph_set_handle_t set = esp_periph_set_init(&periph_cfg); audio_board_key_init(set); - audio_board_sdcard_init(set); + audio_board_sdcard_init(set, SD_MODE_1_LINE); ESP_LOGI(TAG, "[Step 2.1] Initialize input key service"); input_key_service_info_t input_key_info[] = INPUT_KEY_DEFAULT_INFO(); diff --git a/examples/advanced_examples/esp_dispatcher_dueros/sdkconfig.defaults b/examples/advanced_examples/esp_dispatcher_dueros/sdkconfig.defaults index d7c8061..bb3135d 100644 --- a/examples/advanced_examples/esp_dispatcher_dueros/sdkconfig.defaults +++ b/examples/advanced_examples/esp_dispatcher_dueros/sdkconfig.defaults @@ -6,6 +6,7 @@ CONFIG_ESPTOOLPY_FLASHSIZE_4MB=y CONFIG_ESPTOOLPY_BAUD_921600B=y CONFIG_ESPTOOLPY_BAUD=921600 CONFIG_OPTIMIZATION_LEVEL_RELEASE=y +CONFIG_COMPILER_OPTIMIZATION_SIZE=y CONFIG_ESP32_DEFAULT_CPU_FREQ_240=y CONFIG_ESP32_DEFAULT_CPU_FREQ_MHZ=240 @@ -13,12 +14,13 @@ CONFIG_SPIRAM_SUPPORT=y CONFIG_SPIRAM_BOOT_INIT=y CONFIG_SPIRAM_USE_MALLOC=y CONFIG_SPIRAM_TYPE_AUTO=y -CONFIG_SPIRAM_SIZE=4194304 CONFIG_SPIRAM_SPEED_80M=y CONFIG_SPIRAM_MEMTEST=y CONFIG_SPIRAM_CACHE_WORKAROUND=y CONFIG_SPIRAM_MALLOC_ALWAYSINTERNAL=16384 CONFIG_WIFI_LWIP_ALLOCATION_FROM_SPIRAM_FIRST=y +CONFIG_SPIRAM_ALLOW_STACK_EXTERNAL_MEMORY=y +CONFIG_SPIRAM_ALLOW_BSS_SEG_EXTERNAL_MEMORY=y CONFIG_SPIRAM_MALLOC_RESERVE_INTERNAL=32768 CONFIG_FREERTOS_HZ=1000 CONFIG_TIMER_TASK_PRIORITY=5 diff --git a/examples/advanced_examples/flexible_pipeline/main/flexible_example_main.c b/examples/advanced_examples/flexible_pipeline/main/flexible_example_main.c index e0b4875..ff085ec 100644 --- a/examples/advanced_examples/flexible_pipeline/main/flexible_example_main.c +++ b/examples/advanced_examples/flexible_pipeline/main/flexible_example_main.c @@ -35,6 +35,18 @@ #include "periph_adc_button.h" #include "periph_touch.h" +#if __has_include("esp_idf_version.h") +#include "esp_idf_version.h" +#else +#define ESP_IDF_VERSION_VAL(major, minor, patch) 1 +#endif + +#if (ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(4, 1, 0)) +#include "esp_netif.h" +#else +#include "tcpip_adapter.h" +#endif + static const char *TAG = "FLEXIBLE_PIPELINE"; static esp_periph_set_handle_t set; @@ -200,14 +212,18 @@ void app_main(void) ESP_ERROR_CHECK(nvs_flash_erase()); err = nvs_flash_init(); } +#if (ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(4, 1, 0)) + ESP_ERROR_CHECK(esp_netif_init()); +#else tcpip_adapter_init(); +#endif // Initialize peripherals management esp_periph_config_t periph_cfg = DEFAULT_ESP_PERIPH_SET_CONFIG(); set = esp_periph_set_init(&periph_cfg); // Initialize SD Card peripheral - audio_board_sdcard_init(set); + audio_board_sdcard_init(set, SD_MODE_1_LINE); // Initialize Button peripheral audio_board_key_init(set); diff --git a/examples/advanced_examples/http_play_and_save_to_file/main/http_play_and_save_to_file.c b/examples/advanced_examples/http_play_and_save_to_file/main/http_play_and_save_to_file.c index 6cb0af4..f8ff6d1 100644 --- a/examples/advanced_examples/http_play_and_save_to_file/main/http_play_and_save_to_file.c +++ b/examples/advanced_examples/http_play_and_save_to_file/main/http_play_and_save_to_file.c @@ -29,6 +29,18 @@ #include "periph_sdcard.h" #include "board.h" +#if __has_include("esp_idf_version.h") +#include "esp_idf_version.h" +#else +#define ESP_IDF_VERSION_VAL(major, minor, patch) 1 +#endif + +#if (ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(4, 1, 0)) +#include "esp_netif.h" +#else +#include "tcpip_adapter.h" +#endif + static const char *TAG = "PLAY_AND_SAVE_FILE"; void app_main(void) @@ -40,7 +52,11 @@ void app_main(void) ESP_ERROR_CHECK(nvs_flash_erase()); err = nvs_flash_init(); } +#if (ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(4, 1, 0)) + ESP_ERROR_CHECK(esp_netif_init()); +#else tcpip_adapter_init(); +#endif audio_pipeline_handle_t pipeline; audio_element_handle_t http_stream_reader, i2s_stream_writer, mp3_decoder; @@ -123,7 +139,7 @@ void app_main(void) periph_wifi_wait_for_connected(wifi_handle, portMAX_DELAY); ESP_LOGI(TAG, "[4.1] Start and wait for SDCARD to mount"); - audio_board_sdcard_init(set); + audio_board_sdcard_init(set, SD_MODE_1_LINE); ESP_LOGI(TAG, "[ 5 ] Set up event listener"); audio_event_iface_cfg_t evt_cfg = AUDIO_EVENT_IFACE_DEFAULT_CFG(); diff --git a/examples/advanced_examples/nvs_dispatcher/main/nvs_dispatcher_example.c b/examples/advanced_examples/nvs_dispatcher/main/nvs_dispatcher_example.c index 3822b59..4529d38 100644 --- a/examples/advanced_examples/nvs_dispatcher/main/nvs_dispatcher_example.c +++ b/examples/advanced_examples/nvs_dispatcher/main/nvs_dispatcher_example.c @@ -103,7 +103,7 @@ static void task(void *param) ESP_LOGI(TAG, "Write and Read NVS with dispatcher and actions."); ESP_LOGI(TAG, "Open"); - nvs_handle nvs_sync_handle = NULL; + nvs_handle nvs_sync_handle = 0; nvs_action_open_args_t open = { .name = "action_sync", .open_mode = NVS_READWRITE, diff --git a/examples/advanced_examples/record_while_play/README.md b/examples/advanced_examples/record_while_play/README.md index 03f4868..f65ca08 100644 --- a/examples/advanced_examples/record_while_play/README.md +++ b/examples/advanced_examples/record_while_play/README.md @@ -14,7 +14,7 @@ This example is will run on boards marked with green checkbox. Please remember t | ESP32-LyraT | [![alt text](../../../docs/_static/esp32-lyrat-v4.3-side-small.jpg "ESP32-LyraT")](https://docs.espressif.com/projects/esp-adf/en/latest/get-started/get-started-esp32-lyrat.html) | ESP32 | ![alt text](../../../docs/_static/yes-button.png "Compatible") | | ESP32-LyraTD-MSC | [![alt text](../../../docs/_static/esp32-lyratd-msc-v2.2-small.jpg "ESP32-LyraTD-MSC")](https://docs.espressif.com/projects/esp-adf/en/latest/get-started/get-started-esp32-lyratd-msc.html) | ESP32 | ![alt text](../../../docs/_static/yes-button.png "Compatible") | | ESP32-LyraT-Mini | [![alt text](../../../docs/_static/esp32-lyrat-mini-v1.2-small.jpg "ESP32-LyraT-Mini")](https://docs.espressif.com/projects/esp-adf/en/latest/get-started/get-started-esp32-lyrat-mini.html) | ESP32 | ![alt text](../../../docs/_static/yes-button.png "Compatible") | -| ESP32-Korvo-DU1906 | [![alt text](../../../docs/_static/esp32-korvo-du1906-v1.1-small.jpg "ESP32-Korvo-DU1906")](https://docs.espressif.com/projects/esp-adf/en/latest/get-started/get-started-esp32-korvo-du1906.html) | ESP32 | ![alt text](../../../docs/_static/yes-button.png "Compatible") | +| ESP32-Korvo-DU1906 | [![alt text](../../../docs/_static/esp32-korvo-du1906-v1.1-small.jpg "ESP32-Korvo-DU1906")](https://docs.espressif.com/projects/esp-adf/en/latest/get-started/get-started-esp32-korvo-du1906.html) | ESP32 | ![alt text](../../../docs/_static/no-button.png "Compatible") | | ESP32-S2-Kaluga-1 Kit | [![alt text](../../../docs/_static/esp32-s2-kaluga-1-kit-small.png "ESP32-S2-Kaluga-1 Kit")](https://docs.espressif.com/projects/esp-idf/en/latest/esp32s2/hw-reference/esp32s2/user-guide-esp32-s2-kaluga-1-kit.html) | ESP32-S2 | ![alt text](../../../docs/_static/yes-button.png "Compatible") | ## Usage diff --git a/examples/advanced_examples/record_while_play/main/example_record_and_play.c b/examples/advanced_examples/record_while_play/main/example_record_and_play.c index a36b85f..ff8ce90 100644 --- a/examples/advanced_examples/record_while_play/main/example_record_and_play.c +++ b/examples/advanced_examples/record_while_play/main/example_record_and_play.c @@ -11,7 +11,6 @@ #include "freertos/FreeRTOS.h" #include "freertos/task.h" #include "freertos/event_groups.h" -#include "tcpip_adapter.h" #include "esp_log.h" #include "nvs_flash.h" #include "sdkconfig.h" @@ -35,6 +34,18 @@ #include "periph_wifi.h" #include "board.h" +#if __has_include("esp_idf_version.h") +#include "esp_idf_version.h" +#else +#define ESP_IDF_VERSION_VAL(major, minor, patch) 1 +#endif + +#if (ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(4, 1, 0)) +#include "esp_netif.h" +#else +#include "tcpip_adapter.h" +#endif + static const char *TAG = "REC_AND_PLAY_EXAMPLE"; static audio_pipeline_handle_t pipeline_for_record, pipeline_for_play; @@ -88,7 +99,7 @@ static audio_pipeline_handle_t example_create_play_pipeline(const char *url, out audio_pipeline_register(pipeline, mp3_decoder, "mp3"); audio_pipeline_register(pipeline, resample_for_play, "filter"); audio_pipeline_register(pipeline, i2s_stream_writer, "i2s"); - + const char *link_tag[4] = {"file", "mp3", "filter", "i2s"}; audio_pipeline_link(pipeline, &link_tag[0], 4); audio_element_set_uri(fatfs_stream_reader, url); @@ -114,7 +125,7 @@ static audio_pipeline_handle_t example_create_play_pipeline(const char *url, out audio_pipeline_register(pipeline, mp3_decoder, "mp3"); audio_pipeline_register(pipeline, resample_for_play, "filter"); audio_pipeline_register(pipeline, i2s_stream_writer, "i2s"); - + const char *link_tag[4] = {"http", "mp3", "filter", "i2s"}; audio_pipeline_link(pipeline, &link_tag[0], 4); audio_element_set_uri(http_stream_reader, url); @@ -162,7 +173,7 @@ static audio_pipeline_handle_t example_create_rec_pipeline(const char *url, int audio_pipeline_register(pipeline, wav_encoder, "wav"); audio_pipeline_register(pipeline, resample_for_rec, "filter"); audio_pipeline_register(pipeline, fatfs_stream_writer, "file"); - + const char *link_tag[4] = {"i2s", "filter", "wav", "file"}; audio_pipeline_link(pipeline, &link_tag[0], 4); audio_element_set_uri(fatfs_stream_writer, url); @@ -195,7 +206,7 @@ static audio_pipeline_handle_t example_create_rec_pipeline(const char *url, int audio_pipeline_register(pipeline, i2s_stream_reader, "i2s"); audio_pipeline_register(pipeline, resample_for_rec, "filter"); audio_pipeline_register(pipeline, raw_reader, "raw_read"); - + const char *link_tag[3] = {"i2s", "filter", "raw_read"}; audio_pipeline_link(pipeline, &link_tag[0], 3); break; @@ -289,7 +300,11 @@ void app_main(void) ESP_ERROR_CHECK(nvs_flash_erase()); err = nvs_flash_init(); } +#if (ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(4, 1, 0)) + ESP_ERROR_CHECK(esp_netif_init()); +#else tcpip_adapter_init(); +#endif esp_log_level_set("*", ESP_LOG_WARN); esp_log_level_set(TAG, ESP_LOG_INFO); @@ -299,7 +314,7 @@ void app_main(void) esp_periph_set_handle_t set = esp_periph_set_init(&periph_cfg); ESP_LOGI(TAG, "[ 1.1 ] Initialize sd card"); - audio_board_sdcard_init(set); + audio_board_sdcard_init(set, SD_MODE_1_LINE); ESP_LOGI(TAG, "[ 1.2 ] Initialize keys"); audio_board_key_init(set); diff --git a/examples/advanced_examples/record_while_play/sdkconfig.defaults b/examples/advanced_examples/record_while_play/sdkconfig.defaults index 6c5ee2f..4df4651 100644 --- a/examples/advanced_examples/record_while_play/sdkconfig.defaults +++ b/examples/advanced_examples/record_while_play/sdkconfig.defaults @@ -29,4 +29,14 @@ CONFIG_ESP32_DEFAULT_CPU_FREQ_240=y # CONFIG_SPIRAM_SUPPORT=y CONFIG_SPIRAM_BOOT_INIT=y -CONFIG_SPIRAM_SPEED_80M=y \ No newline at end of file +CONFIG_SPIRAM_SPEED_80M=y + + +# +# ESP Speech Recognition +# +CONFIG_SR_MODEL_WN5_QUANT=y +CONFIG_SR_WN5_HILEXIN=y +CONFIG_SINGLE_RECOGNITION=y +CONFIG_SR_CHINESE=y +CONFIG_SPEECH_COMMANDS_NUM=20 \ No newline at end of file diff --git a/examples/advanced_examples/voip/README.md b/examples/advanced_examples/voip/README.md index e48f8a9..322a9e2 100644 --- a/examples/advanced_examples/voip/README.md +++ b/examples/advanced_examples/voip/README.md @@ -15,7 +15,7 @@ This example is will run on boards marked with green checkbox. Please remember t | ESP32-LyraT | [![alt text](../../../docs/_static/esp32-lyrat-v4.3-side-small.jpg "ESP32-LyraT")](https://docs.espressif.com/projects/esp-adf/en/latest/get-started/get-started-esp32-lyrat.html) | ESP32 | ![alt text](../../../docs/_static/yes-button.png "Compatible") | | ESP32-LyraTD-MSC | [![alt text](../../../docs/_static/esp32-lyratd-msc-v2.2-small.jpg "ESP32-LyraTD-MSC")](https://docs.espressif.com/projects/esp-adf/en/latest/get-started/get-started-esp32-lyratd-msc.html) | ESP32 | ![alt text](../../../docs/_static/yes-button.png "Compatible") | | ESP32-LyraT-Mini | [![alt text](../../../docs/_static/esp32-lyrat-mini-v1.2-small.jpg "ESP32-LyraT-Mini")](https://docs.espressif.com/projects/esp-adf/en/latest/get-started/get-started-esp32-lyrat-mini.html) | ESP32 | ![alt text](../../../docs/_static/yes-button.png "Compatible") | -| ESP32-Korvo-DU1906 | [![alt text](../../../docs/_static/esp32-korvo-du1906-v1.1-small.jpg "ESP32-Korvo-DU1906")](https://docs.espressif.com/projects/esp-adf/en/latest/get-started/get-started-esp32-korvo-du1906.html) | ESP32 | ![alt text](../../../docs/_static/yes-button.png "Compatible") | +| ESP32-Korvo-DU1906 | [![alt text](../../../docs/_static/esp32-korvo-du1906-v1.1-small.jpg "ESP32-Korvo-DU1906")](https://docs.espressif.com/projects/esp-adf/en/latest/get-started/get-started-esp32-korvo-du1906.html) | ESP32 | ![alt text](../../../docs/_static/no-button.png "Compatible") | | ESP32-S2-Kaluga-1 Kit | [![alt text](../../../docs/_static/esp32-s2-kaluga-1-kit-small.png "ESP32-S2-Kaluga-1 Kit")](https://docs.espressif.com/projects/esp-idf/en/latest/esp32s2/hw-reference/esp32s2/user-guide-esp32-s2-kaluga-1-kit.html) | ESP32-S2 | ![alt text](../../../docs/_static/no-button.png "Compatible") | ## How to use example @@ -73,6 +73,11 @@ See the Getting Started Guide for full steps to configure and use ESP-IDF to bui - Freeswitch v1.8.5 - Yate v6.0 - Kamailio v5.3 +- Acoustic Echo Cancellation (AEC) : + - Software AEC + - only support MINI board with our algorithm stream + - Hardware AEC + - You can use MSC board or other board that support AEC features ## Example Output diff --git a/examples/advanced_examples/voip/main/Kconfig.projbuild b/examples/advanced_examples/voip/main/Kconfig.projbuild index 57e39ef..d9975dc 100644 --- a/examples/advanced_examples/voip/main/Kconfig.projbuild +++ b/examples/advanced_examples/voip/main/Kconfig.projbuild @@ -2,7 +2,7 @@ menu "VoIP App Configuration" choice VOIP_CODEC prompt "SIP Codec" - default G711A + default SIP_CODEC_G711A help sip codec @@ -16,13 +16,13 @@ config WIFI_SSID string "WiFi SSID" default "myssid" help - SSID (network name) for the example to connect to. + SSID (network name) for the example to connect to. config WIFI_PASSWORD string "WiFi Password" default "mypassword" help - WiFi password (WPA or WPA2) for the example to use. + WiFi password (WPA or WPA2) for the example to use. config SIP_URI string "SIP URI" diff --git a/examples/advanced_examples/voip/main/voip_app.c b/examples/advanced_examples/voip/main/voip_app.c index 69d79ad..b0e6c29 100644 --- a/examples/advanced_examples/voip/main/voip_app.c +++ b/examples/advanced_examples/voip/main/voip_app.c @@ -13,7 +13,6 @@ #include "freertos/event_groups.h" #include "esp_system.h" #include "esp_wifi.h" -#include "esp_event_loop.h" #include "esp_log.h" #include "nvs_flash.h" #include "audio_element.h" @@ -32,10 +31,23 @@ #include "esp_sip.h" #include "g711_decoder.h" #include "g711_encoder.h" +#include "algorithm_stream.h" + +#if __has_include("esp_idf_version.h") +#include "esp_idf_version.h" +#else +#define ESP_IDF_VERSION_VAL(major, minor, patch) 1 +#endif + +#if (ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(4, 1, 0)) +#include "esp_netif.h" +#else +#include "tcpip_adapter.h" +#endif static const char *TAG = "VOIP_EXAMPLE"; -#define I2S_SAMPLE_RATE 48000 +#define I2S_SAMPLE_RATE 16000 #define I2S_CHANNELS 2 #define I2S_BITS 16 @@ -58,24 +70,33 @@ static esp_err_t recorder_pipeline_open() i2s_cfg.uninstall_drv = false; #if defined CONFIG_ESP_LYRAT_MINI_V1_1_BOARD i2s_cfg.i2s_port = 1; + i2s_cfg.task_core = 1; #endif + i2s_cfg.i2s_config.sample_rate = I2S_SAMPLE_RATE; i2s_stream_reader = i2s_stream_init(&i2s_cfg); - audio_element_info_t i2s_info = {0}; - audio_element_getinfo(i2s_stream_reader, &i2s_info); - i2s_info.bits = I2S_BITS; - i2s_info.channels = I2S_CHANNELS; - i2s_info.sample_rates = I2S_SAMPLE_RATE; - audio_element_setinfo(i2s_stream_reader, &i2s_info); + +#if defined CONFIG_ESP_LYRAT_MINI_V1_1_BOARD + algorithm_stream_cfg_t algo_config = ALGORITHM_STREAM_CFG_DEFAULT(); + algo_config.input_type = ALGORITHM_STREAM_INPUT_TYPE1; + algo_config.task_core = 1; + audio_element_handle_t element_algo = algo_stream_init(&algo_config); +#endif rsp_filter_cfg_t rsp_cfg = DEFAULT_RESAMPLE_FILTER_CONFIG(); rsp_cfg.src_rate = I2S_SAMPLE_RATE; +#if defined CONFIG_ESP_LYRAT_MINI_V1_1_BOARD + rsp_cfg.src_ch = 1; +#else rsp_cfg.src_ch = I2S_CHANNELS; +#endif rsp_cfg.dest_rate = CODEC_SAMPLE_RATE; rsp_cfg.dest_ch = CODEC_CHANNELS; rsp_cfg.complexity = 5; + rsp_cfg.task_core = 1; audio_element_handle_t filter = rsp_filter_init(&rsp_cfg); g711_encoder_cfg_t g711_cfg = DEFAULT_G711_ENCODER_CONFIG(); + g711_cfg.task_core = 1; audio_element_handle_t sip_encoder = g711_encoder_init(&g711_cfg); raw_stream_cfg_t raw_cfg = RAW_STREAM_CFG_DEFAULT(); @@ -87,8 +108,17 @@ static esp_err_t recorder_pipeline_open() audio_pipeline_register(recorder, filter, "filter"); audio_pipeline_register(recorder, sip_encoder, "sip_enc"); audio_pipeline_register(recorder, raw_read, "raw"); + +#if defined CONFIG_ESP_LYRAT_MINI_V1_1_BOARD + audio_pipeline_register(recorder, element_algo, "algo"); + algo_stream_set_record_rate(element_algo, I2S_CHANNELS, I2S_SAMPLE_RATE); + const char *link_tag[5] = {"i2s", "algo", "filter", "sip_enc", "raw"}; + audio_pipeline_link(recorder, &link_tag[0], 5); +#else const char *link_tag[4] = {"i2s", "filter", "sip_enc", "raw"}; audio_pipeline_link(recorder, &link_tag[0], 4); +#endif + audio_pipeline_run(recorder); ESP_LOGI(TAG, " SIP recorder has been created"); return ESP_OK; @@ -119,13 +149,8 @@ static esp_err_t player_pipeline_open() i2s_stream_cfg_t i2s_cfg = I2S_STREAM_CFG_DEFAULT(); i2s_cfg.type = AUDIO_STREAM_WRITER; i2s_cfg.uninstall_drv = false; + i2s_cfg.i2s_config.sample_rate = I2S_SAMPLE_RATE; i2s_stream_writer = i2s_stream_init(&i2s_cfg); - audio_element_info_t i2s_info = {0}; - audio_element_getinfo(i2s_stream_writer, &i2s_info); - i2s_info.bits = I2S_BITS; - i2s_info.channels = I2S_CHANNELS; - i2s_info.sample_rates = I2S_SAMPLE_RATE; - audio_element_setinfo(i2s_stream_writer, &i2s_info); audio_pipeline_register(player, raw_write, "raw"); audio_pipeline_register(player, sip_decoder, "sip_dec"); @@ -134,7 +159,7 @@ static esp_err_t player_pipeline_open() const char *link_tag[4] = {"raw", "sip_dec", "filter", "i2s"}; audio_pipeline_link(player, &link_tag[0], 4); audio_pipeline_run(player); - ESP_LOGI(TAG, "Speaker has been created"); + ESP_LOGI(TAG, "SIP player has been created"); return ESP_OK; } @@ -178,8 +203,8 @@ static int _sip_event_handler(sip_event_msg_t *event) break; case SIP_EVENT_AUDIO_SESSION_BEGIN: ESP_LOGI(TAG, "SIP_EVENT_AUDIO_SESSION_BEGIN"); - recorder_pipeline_open(); player_pipeline_open(); + recorder_pipeline_open(); break; case SIP_EVENT_AUDIO_SESSION_END: ESP_LOGI(TAG, "SIP_EVENT_AUDIO_SESSION_END"); @@ -272,7 +297,11 @@ void app_main() err = nvs_flash_init(); } ESP_ERROR_CHECK(err); +#if (ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(4, 1, 0)) + ESP_ERROR_CHECK(esp_netif_init()); +#else tcpip_adapter_init(); +#endif ESP_LOGI(TAG, "[1.0] Initialize peripherals management"); esp_periph_config_t periph_cfg = DEFAULT_ESP_PERIPH_SET_CONFIG(); diff --git a/examples/advanced_examples/wifi_bt_ble_coex/main/wifi_bt_ble_coex_example.c b/examples/advanced_examples/wifi_bt_ble_coex/main/wifi_bt_ble_coex_example.c index 7d0655f..0e06d35 100644 --- a/examples/advanced_examples/wifi_bt_ble_coex/main/wifi_bt_ble_coex_example.c +++ b/examples/advanced_examples/wifi_bt_ble_coex/main/wifi_bt_ble_coex_example.c @@ -36,6 +36,18 @@ #include "sdkconfig.h" #include "ble_gatts_module.h" +#if __has_include("esp_idf_version.h") +#include "esp_idf_version.h" +#else +#define ESP_IDF_VERSION_VAL(major, minor, patch) 1 +#endif + +#if (ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(4, 1, 0)) +#include "esp_netif.h" +#else +#include "tcpip_adapter.h" +#endif + #define SAMPLE_DEVICE_NAME "ESP_COEX_EXAMPLE" static const char *TAG = "COEX_EXAMPLE"; @@ -78,8 +90,8 @@ static esp_err_t input_key_service_cb(periph_service_handle_t handle, periph_ser ESP_LOGI(TAG, "[ * ] Enter WIFI mode"); cx_handle->work_mode = WIFI_MODE; if (g_a2dp_connect_state == true) { - periph_bt_pause(cx_handle->bt_periph); - vTaskDelay(300/portTICK_RATE_MS); + periph_bt_pause(cx_handle->bt_periph); + vTaskDelay(300 / portTICK_RATE_MS); } esp_audio_stop(cx_handle->player, TERMINATION_TYPE_NOW); if (g_wifi_connect_state == true) { @@ -135,8 +147,8 @@ static void wifi_server_init(void) { ESP_LOGI(TAG, "Blufi module init"); wifi_config_t sta_cfg = {0}; - strncpy((char *)&sta_cfg.sta.ssid, CONFIG_WIFI_SSID, strlen(CONFIG_WIFI_SSID)); - strncpy((char *)&sta_cfg.sta.password, CONFIG_WIFI_PASSWORD, strlen(CONFIG_WIFI_PASSWORD)); + strncpy((char *)&sta_cfg.sta.ssid, CONFIG_WIFI_SSID, sizeof(sta_cfg.sta.ssid)); + strncpy((char *)&sta_cfg.sta.password, CONFIG_WIFI_PASSWORD, sizeof(sta_cfg.sta.password)); wifi_service_config_t cfg = WIFI_SERVICE_DEFAULT_CONFIG(); cfg.extern_stack = true; @@ -236,7 +248,7 @@ static void a2dp_sink_blufi_start(coex_handle_t *handle) wifi_server_init(); esp_err_t set_dev_name_ret = esp_bt_dev_set_device_name(SAMPLE_DEVICE_NAME); - if (set_dev_name_ret){ + if (set_dev_name_ret) { ESP_LOGE(TAG, "set device name failed, error code = %x", set_dev_name_ret); } ESP_LOGI(TAG, "Create Bluetooth peripheral"); @@ -244,7 +256,12 @@ static void a2dp_sink_blufi_start(coex_handle_t *handle) ESP_LOGI(TAG, "Start peripherals"); esp_periph_start(handle->set, handle->bt_periph); +#if (ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(4, 0, 0)) + esp_bt_gap_set_scan_mode(ESP_BT_CONNECTABLE, ESP_BT_GENERAL_DISCOVERABLE); +#else esp_bt_gap_set_scan_mode(ESP_BT_SCAN_MODE_CONNECTABLE_DISCOVERABLE); +#endif + handle->player = setup_player(); } @@ -257,7 +274,11 @@ void app_main(void) ESP_ERROR_CHECK(nvs_flash_erase()); err = nvs_flash_init(); } +#if (ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(4, 1, 0)) + ESP_ERROR_CHECK(esp_netif_init()); +#else tcpip_adapter_init(); +#endif esp_log_level_set("*", ESP_LOG_WARN); esp_log_level_set(TAG, ESP_LOG_DEBUG); diff --git a/examples/advanced_examples/wifi_bt_ble_coex/sdkconfig.defaults b/examples/advanced_examples/wifi_bt_ble_coex/sdkconfig.defaults index bcaab97..7a3f0f1 100644 --- a/examples/advanced_examples/wifi_bt_ble_coex/sdkconfig.defaults +++ b/examples/advanced_examples/wifi_bt_ble_coex/sdkconfig.defaults @@ -2,8 +2,6 @@ CONFIG_PARTITION_TABLE_CUSTOM=y CONFIG_PARTITION_TABLE_CUSTOM_FILENAME="partitions.csv" CONFIG_ESPTOOLPY_FLASHSIZE_4MB=y CONFIG_BT_ENABLED=y -CONFIG_BTDM_CONTROLLER_MODE_BLE_ONLY= -CONFIG_BTDM_CONTROLLER_MODE_BR_EDR_ONLY= CONFIG_BTDM_CONTROLLER_MODE_BTDM=y CONFIG_BTDM_CONTROLLER_PINNED_TO_CORE_0=n CONFIG_BTDM_CONTROLLER_PINNED_TO_CORE_1=y @@ -30,6 +28,7 @@ CONFIG_A2DP_SINK_TASK_STACK_SIZE=2048 CONFIG_A2DP_SOURCE_TASK_STACK_SIZE=0 CONFIG_BT_SPP_ENABLED=n CONFIG_GATTS_ENABLE=y +CONFIG_BT_BLE_BLUFI_ENABLE=y CONFIG_GATTC_ENABLE=y CONFIG_BLE_SMP_ENABLE=y CONFIG_BLE_ENABLE_SRVCHG_REG=y diff --git a/examples/audio_processing/pipeline_alc/README.md b/examples/audio_processing/pipeline_alc/README.md index 93ea110..f50804d 100644 --- a/examples/audio_processing/pipeline_alc/README.md +++ b/examples/audio_processing/pipeline_alc/README.md @@ -18,14 +18,14 @@ This example is will run on boards marked with green checkbox. Please remember t Prepare the audio board: -- Connect speakers or headphones to the board. +- Connect speakers or headphones to the board. - Insert a microSD card loaded with a WAV file 'test.wav' into board's card slot. Load and run the example. ## Additional Information -Two methods can implement volume setting with ALC. +Two methods can implement volume setting with ALC. 1. The one is through the function `i2s_alc_volume_set` in `i2s_stream.h`. 2. The other is ALC as a independent element to be used. If `USE_ALONE_ALC` is defined, the second method will be selected. If not, the first will be selected. diff --git a/examples/audio_processing/pipeline_alc/main/use_alc_set_volume.c b/examples/audio_processing/pipeline_alc/main/use_alc_set_volume.c index 0bfd8ed..e445190 100644 --- a/examples/audio_processing/pipeline_alc/main/use_alc_set_volume.c +++ b/examples/audio_processing/pipeline_alc/main/use_alc_set_volume.c @@ -45,7 +45,7 @@ void app_main(void) esp_periph_set_handle_t set = esp_periph_set_init(&periph_cfg); // Initialize SD Card peripheral - audio_board_sdcard_init(set); + audio_board_sdcard_init(set, SD_MODE_1_LINE); ESP_LOGI(TAG, "[ 2 ] Start codec chip"); audio_board_handle_t board_handle = audio_board_init(); diff --git a/examples/audio_processing/pipeline_audio_forge/main/audio_forge_pipeline_main.c b/examples/audio_processing/pipeline_audio_forge/main/audio_forge_pipeline_main.c index 811360f..4b33fe0 100644 --- a/examples/audio_processing/pipeline_audio_forge/main/audio_forge_pipeline_main.c +++ b/examples/audio_processing/pipeline_audio_forge/main/audio_forge_pipeline_main.c @@ -57,7 +57,7 @@ void app_main(void) ESP_LOGI(TAG, "[2.0] Start and wait for SDCARD to mount"); esp_periph_config_t periph_cfg = DEFAULT_ESP_PERIPH_SET_CONFIG(); esp_periph_set_handle_t set = esp_periph_set_init(&periph_cfg); - audio_board_sdcard_init(set); + audio_board_sdcard_init(set, SD_MODE_1_LINE); audio_board_key_init(set); ESP_LOGI(TAG, "[3.0] Create pipeline_mix to mix"); diff --git a/examples/audio_processing/pipeline_equalizer/main/equalizer_example.c b/examples/audio_processing/pipeline_equalizer/main/equalizer_example.c index 2f8109c..a200957 100644 --- a/examples/audio_processing/pipeline_equalizer/main/equalizer_example.c +++ b/examples/audio_processing/pipeline_equalizer/main/equalizer_example.c @@ -42,7 +42,7 @@ void app_main(void) esp_periph_set_handle_t set = esp_periph_set_init(&periph_cfg); // Initialize SD Card peripheral - audio_board_sdcard_init(set); + audio_board_sdcard_init(set, SD_MODE_1_LINE); ESP_LOGI(TAG, "[2.0] Start codec chip"); audio_board_handle_t board_handle = audio_board_init(); diff --git a/examples/audio_processing/pipeline_passthru/README.md b/examples/audio_processing/pipeline_passthru/README.md index 950c14c..cc5e8ba 100644 --- a/examples/audio_processing/pipeline_passthru/README.md +++ b/examples/audio_processing/pipeline_passthru/README.md @@ -17,14 +17,14 @@ This example is will run on boards marked with green checkbox. Please remember t | ESP32-LyraT | [![alt text](../../../docs/_static/esp32-lyrat-v4.3-side-small.jpg "ESP32-LyraT")](https://docs.espressif.com/projects/esp-adf/en/latest/get-started/get-started-esp32-lyrat.html) | ESP32 | ![alt text](../../../docs/_static/yes-button.png "Compatible") | | ESP32-LyraTD-MSC | [![alt text](../../../docs/_static/esp32-lyratd-msc-v2.2-small.jpg "ESP32-LyraTD-MSC")](https://docs.espressif.com/projects/esp-adf/en/latest/get-started/get-started-esp32-lyratd-msc.html) | ESP32 | ![alt text](../../../docs/_static/yes-button.png "Compatible") | | ESP32-LyraT-Mini | [![alt text](../../../docs/_static/esp32-lyrat-mini-v1.2-small.jpg "ESP32-LyraT-Mini")](https://docs.espressif.com/projects/esp-adf/en/latest/get-started/get-started-esp32-lyrat-mini.html) | ESP32 | ![alt text](../../../docs/_static/no-button.png "Compatible") | -| ESP32-Korvo-DU1906 | [![alt text](../../../docs/_static/esp32-korvo-du1906-v1.1-small.jpg "ESP32-Korvo-DU1906")](https://docs.espressif.com/projects/esp-adf/en/latest/get-started/get-started-esp32-korvo-du1906.html) | ESP32 | ![alt text](../../../docs/_static/yes-button.png "Compatible") | +| ESP32-Korvo-DU1906 | [![alt text](../../../docs/_static/esp32-korvo-du1906-v1.1-small.jpg "ESP32-Korvo-DU1906")](https://docs.espressif.com/projects/esp-adf/en/latest/get-started/get-started-esp32-korvo-du1906.html) | ESP32 | ![alt text](../../../docs/_static/no-button.png "Compatible") | | ESP32-S2-Kaluga-1 Kit | [![alt text](../../../docs/_static/esp32-s2-kaluga-1-kit-small.png "ESP32-S2-Kaluga-1 Kit")](https://docs.espressif.com/projects/esp-idf/en/latest/esp32s2/hw-reference/esp32s2/user-guide-esp32-s2-kaluga-1-kit.html) | ESP32-S2 | ![alt text](../../../docs/_static/yes-button.png "Compatible") | ## Usage Prepare the audio board: -- Connect speakers or headphones to the board. +- Connect speakers or headphones to the board. - Connect audio source to "aux_in". Configure the example: diff --git a/examples/audio_processing/pipeline_passthru/main/passthru.c b/examples/audio_processing/pipeline_passthru/main/passthru.c index 70a60ff..c4d6922 100755 --- a/examples/audio_processing/pipeline_passthru/main/passthru.c +++ b/examples/audio_processing/pipeline_passthru/main/passthru.c @@ -76,11 +76,6 @@ void app_main(void) continue; } - if (msg.cmd == AEL_MSG_CMD_ERROR) { - ESP_LOGE(TAG, "[ * ] Action command error: src_type:%d, source:%p cmd:%d, data:%p, data_len:%d", - msg.source_type, msg.source, msg.cmd, msg.data, msg.data_len); - } - /* Stop when the last pipeline element (i2s_stream_writer in this case) receives stop event */ if (msg.source_type == AUDIO_ELEMENT_TYPE_ELEMENT && msg.source == (void *) i2s_stream_writer && msg.cmd == AEL_MSG_CMD_REPORT_STATUS diff --git a/examples/audio_processing/pipeline_resample/README.md b/examples/audio_processing/pipeline_resample/README.md index be3f60d..8ccc67d 100644 --- a/examples/audio_processing/pipeline_resample/README.md +++ b/examples/audio_processing/pipeline_resample/README.md @@ -5,7 +5,7 @@ When [Rec] button on an audio board is pressed, this example will record, and wh For the Recorder: - We will set up I2S and get audio at sample rate 48000 Hz, 16-bits, stereo. -- Using resample-filter to convert to 16000 Hz, 16-bits, 1 channel. +- Using resample-filter to convert to 16000 Hz, 16-bits, 1 channel. - Encode with Wav encoder - Write to microSD @@ -25,14 +25,14 @@ This example is will run on boards marked with green checkbox. Please remember t | ESP32-LyraT | [![alt text](../../../docs/_static/esp32-lyrat-v4.3-side-small.jpg "ESP32-LyraT")](https://docs.espressif.com/projects/esp-adf/en/latest/get-started/get-started-esp32-lyrat.html) | ESP32 | ![alt text](../../../docs/_static/yes-button.png "Compatible") | | ESP32-LyraTD-MSC | [![alt text](../../../docs/_static/esp32-lyratd-msc-v2.2-small.jpg "ESP32-LyraTD-MSC")](https://docs.espressif.com/projects/esp-adf/en/latest/get-started/get-started-esp32-lyratd-msc.html) | ESP32 | ![alt text](../../../docs/_static/yes-button.png "Compatible") | | ESP32-LyraT-Mini | [![alt text](../../../docs/_static/esp32-lyrat-mini-v1.2-small.jpg "ESP32-LyraT-Mini")](https://docs.espressif.com/projects/esp-adf/en/latest/get-started/get-started-esp32-lyrat-mini.html) | ESP32 | ![alt text](../../../docs/_static/yes-button.png "Compatible") | -| ESP32-Korvo-DU1906 | [![alt text](../../../docs/_static/esp32-korvo-du1906-v1.1-small.jpg "ESP32-Korvo-DU1906")](https://docs.espressif.com/projects/esp-adf/en/latest/get-started/get-started-esp32-korvo-du1906.html) | ESP32 | ![alt text](../../../docs/_static/yes-button.png "Compatible") | +| ESP32-Korvo-DU1906 | [![alt text](../../../docs/_static/esp32-korvo-du1906-v1.1-small.jpg "ESP32-Korvo-DU1906")](https://docs.espressif.com/projects/esp-adf/en/latest/get-started/get-started-esp32-korvo-du1906.html) | ESP32 | ![alt text](../../../docs/_static/no-button.png "Compatible") | | ESP32-S2-Kaluga-1 Kit | [![alt text](../../../docs/_static/esp32-s2-kaluga-1-kit-small.png "ESP32-S2-Kaluga-1 Kit")](https://docs.espressif.com/projects/esp-idf/en/latest/esp32s2/hw-reference/esp32s2/user-guide-esp32-s2-kaluga-1-kit.html) | ESP32-S2 | ![alt text](../../../docs/_static/no-button.png "Compatible") | ## Usage Prepare the audio board: -- Connect speakers or headphones to the board. +- Connect speakers or headphones to the board. - Insert a microSD card. Configure the example: diff --git a/examples/audio_processing/pipeline_resample/main/resample_example.c b/examples/audio_processing/pipeline_resample/main/resample_example.c index 7d37c63..1064255 100644 --- a/examples/audio_processing/pipeline_resample/main/resample_example.c +++ b/examples/audio_processing/pipeline_resample/main/resample_example.c @@ -256,7 +256,7 @@ void app_main(void) set = esp_periph_set_init(&periph_cfg); // Initialize SD Card peripheral - audio_board_sdcard_init(set); + audio_board_sdcard_init(set, SD_MODE_1_LINE); // Initialize Button peripheral audio_board_key_init(set); diff --git a/examples/audio_processing/pipeline_sonic/main/sonic_example.c b/examples/audio_processing/pipeline_sonic/main/sonic_example.c index 13c8cfa..d462ce3 100644 --- a/examples/audio_processing/pipeline_sonic/main/sonic_example.c +++ b/examples/audio_processing/pipeline_sonic/main/sonic_example.c @@ -261,7 +261,7 @@ void app_main(void) set = esp_periph_set_init(&periph_cfg); // Initialize SD Card peripheral - audio_board_sdcard_init(set); + audio_board_sdcard_init(set, SD_MODE_1_LINE); // Initialize Button peripheral audio_board_key_init(set); diff --git a/examples/audio_processing/pipeline_spiffs_amr_resample/README.md b/examples/audio_processing/pipeline_spiffs_amr_resample/README.md index 9d80907..52cbde3 100644 --- a/examples/audio_processing/pipeline_spiffs_amr_resample/README.md +++ b/examples/audio_processing/pipeline_spiffs_amr_resample/README.md @@ -9,7 +9,7 @@ For Spiffs Partition: For the Recorder: - We will set up I2S and get audio at sample rate 48000 Hz, 16-bits, 2 channels. -- Using resample-filter to convert to 8000 Hz, 16-bits, 1 channel. +- Using resample-filter to convert to 8000 Hz, 16-bits, 1 channel. - Encode with AMRNB encoder. - Write to Spiffs. @@ -29,14 +29,14 @@ This example is will run on boards marked with green checkbox. Please remember t | ESP32-LyraT | [![alt text](../../../docs/_static/esp32-lyrat-v4.3-side-small.jpg "ESP32-LyraT")](https://docs.espressif.com/projects/esp-adf/en/latest/get-started/get-started-esp32-lyrat.html) | ESP32 | ![alt text](../../../docs/_static/yes-button.png "Compatible") | | ESP32-LyraTD-MSC | [![alt text](../../../docs/_static/esp32-lyratd-msc-v2.2-small.jpg "ESP32-LyraTD-MSC")](https://docs.espressif.com/projects/esp-adf/en/latest/get-started/get-started-esp32-lyratd-msc.html) | ESP32 | ![alt text](../../../docs/_static/yes-button.png "Compatible") | | ESP32-LyraT-Mini | [![alt text](../../../docs/_static/esp32-lyrat-mini-v1.2-small.jpg "ESP32-LyraT-Mini")](https://docs.espressif.com/projects/esp-adf/en/latest/get-started/get-started-esp32-lyrat-mini.html) | ESP32 | ![alt text](../../../docs/_static/yes-button.png "Compatible") | -| ESP32-Korvo-DU1906 | [![alt text](../../../docs/_static/esp32-korvo-du1906-v1.1-small.jpg "ESP32-Korvo-DU1906")](https://docs.espressif.com/projects/esp-adf/en/latest/get-started/get-started-esp32-korvo-du1906.html) | ESP32 | ![alt text](../../../docs/_static/yes-button.png "Compatible") | +| ESP32-Korvo-DU1906 | [![alt text](../../../docs/_static/esp32-korvo-du1906-v1.1-small.jpg "ESP32-Korvo-DU1906")](https://docs.espressif.com/projects/esp-adf/en/latest/get-started/get-started-esp32-korvo-du1906.html) | ESP32 | ![alt text](../../../docs/_static/no-button.png "Compatible") | | ESP32-S2-Kaluga-1 Kit | [![alt text](../../../docs/_static/esp32-s2-kaluga-1-kit-small.png "ESP32-S2-Kaluga-1 Kit")](https://docs.espressif.com/projects/esp-idf/en/latest/esp32s2/hw-reference/esp32s2/user-guide-esp32-s2-kaluga-1-kit.html) | ESP32-S2 | ![alt text](../../../docs/_static/yes-button.png "Compatible") | ## Usage Prepare the audio board: -- Connect speakers or headphones to the board. +- Connect speakers or headphones to the board. Configure the example: diff --git a/examples/cli/main/console_example.c b/examples/cli/main/console_example.c index d344c59..33d92ae 100644 --- a/examples/cli/main/console_example.c +++ b/examples/cli/main/console_example.c @@ -43,6 +43,19 @@ #include "sdcard_list.h" #include "sdcard_scan.h" +#include "audio_sys.h" + +#if __has_include("esp_idf_version.h") +#include "esp_idf_version.h" +#else +#define ESP_IDF_VERSION_VAL(major, minor, patch) 1 +#endif + +#if (ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(4, 1, 0)) +#include "esp_netif.h" +#else +#include "tcpip_adapter.h" +#endif // #define ESP_AUDIO_AUTO_PLAY @@ -409,6 +422,12 @@ static esp_err_t task_list(esp_periph_handle_t periph, int argc, char *argv[]) } #endif +static esp_err_t task_real_time_states(esp_periph_handle_t periph, int argc, char *argv[]) +{ + audio_sys_get_real_time_stats(); + return ESP_OK; +} + const periph_console_cmd_t cli_cmd[] = { /* ======================== Esp_audio ======================== */ { @@ -451,6 +470,7 @@ const periph_console_cmd_t cli_cmd[] = { #ifdef CONFIG_FREERTOS_USE_TRACE_FACILITY { .cmd = "tasks", .id = 33, .help = "Get information about running tasks", .func = task_list }, #endif + { .cmd = "system", .id = 34, .help = "Get freertos all task states information", .func = task_real_time_states }, }; static void esp_audio_state_task (void *para) @@ -611,11 +631,15 @@ void app_main(void) esp_log_level_set("*", ESP_LOG_INFO); ESP_ERROR_CHECK(nvs_flash_init()); +#if (ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(4, 1, 0)) + ESP_ERROR_CHECK(esp_netif_init()); +#else tcpip_adapter_init(); +#endif esp_periph_config_t periph_cfg = DEFAULT_ESP_PERIPH_SET_CONFIG(); set = esp_periph_set_init(&periph_cfg); - audio_board_sdcard_init(set); + audio_board_sdcard_init(set, SD_MODE_1_LINE); cli_setup_wifi(); cli_setup_player(); diff --git a/examples/cli/sdkconfig.defaults b/examples/cli/sdkconfig.defaults index 47a4409..79755a8 100644 --- a/examples/cli/sdkconfig.defaults +++ b/examples/cli/sdkconfig.defaults @@ -4,7 +4,7 @@ CONFIG_FREERTOS_USE_TRACE_FACILITY=y CONFIG_FREERTOS_USE_STATS_FORMATTING_FUNCTIONS=y CONFIG_FREERTOS_GENERATE_RUN_TIME_STATS=y CONFIG_FREERTOS_RUN_TIME_STATS_USING_ESP_TIMER=y -CONFIG_FREERTOS_RUN_TIME_STATS_USING_CPU_CLK= +CONFIG_FREERTOS_RUN_TIME_STATS_USING_CPU_CLK=y # # Serial flasher config diff --git a/examples/cloud_services/google_translate_device/main/google_tts.c b/examples/cloud_services/google_translate_device/main/google_tts.c index ece6596..36be5cd 100644 --- a/examples/cloud_services/google_translate_device/main/google_tts.c +++ b/examples/cloud_services/google_translate_device/main/google_tts.c @@ -192,7 +192,7 @@ google_tts_handle_t google_tts_init(google_tts_config_t *config) audio_pipeline_register(tts->pipeline, tts->mp3_decoder, "tts_mp3"); audio_pipeline_register(tts->pipeline, tts->i2s_writer, "tts_i2s"); const char *link_tag[3] = {"tts_http", "tts_mp3", "tts_i2s"}; - audio_pipeline_link(tts->pipeline, &link_tag[3], 3); + audio_pipeline_link(tts->pipeline, &link_tag[0], 3); i2s_stream_set_clk(tts->i2s_writer, config->playback_sample_rate, 16, 1); return tts; exit_tts_init: diff --git a/examples/cloud_services/google_translate_device/main/translate_device_example.c b/examples/cloud_services/google_translate_device/main/translate_device_example.c index 0622915..1aeb2c2 100644 --- a/examples/cloud_services/google_translate_device/main/translate_device_example.c +++ b/examples/cloud_services/google_translate_device/main/translate_device_example.c @@ -28,6 +28,18 @@ #include "google_translate.h" #include "board.h" +#if __has_include("esp_idf_version.h") +#include "esp_idf_version.h" +#else +#define ESP_IDF_VERSION_VAL(major, minor, patch) 1 +#endif + +#if (ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(4, 1, 0)) +#include "esp_netif.h" +#else +#include "tcpip_adapter.h" +#endif + static const char *TAG = "GOOGLE_TRANSLATION_EXAMPLE"; #define GOOGLE_SR_LANG "cmn-Hans-CN" // https://cloud.google.com/speech-to-text/docs/languages @@ -55,7 +67,11 @@ void translate_task(void *pv) ESP_ERROR_CHECK(nvs_flash_erase()); err = nvs_flash_init(); } +#if (ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(4, 1, 0)) + ESP_ERROR_CHECK(esp_netif_init()); +#else tcpip_adapter_init(); +#endif ESP_LOGI(TAG, "[ 1 ] Initialize Buttons & Connect to Wi-Fi network, ssid=%s", CONFIG_WIFI_SSID); // Initialize peripherals management diff --git a/examples/cloud_services/pipeline_aws_polly_mp3/main/play_aws_polly_mp3_example.c b/examples/cloud_services/pipeline_aws_polly_mp3/main/play_aws_polly_mp3_example.c index 0fc2580..4e303e2 100644 --- a/examples/cloud_services/pipeline_aws_polly_mp3/main/play_aws_polly_mp3_example.c +++ b/examples/cloud_services/pipeline_aws_polly_mp3/main/play_aws_polly_mp3_example.c @@ -31,6 +31,18 @@ #include "esp_http_client.h" #include "aws_sig_v4_signing.h" +#if __has_include("esp_idf_version.h") +#include "esp_idf_version.h" +#else +#define ESP_IDF_VERSION_VAL(major, minor, patch) 1 +#endif + +#if (ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(4, 1, 0)) +#include "esp_netif.h" +#else +#include "tcpip_adapter.h" +#endif + #define AWS_POLLY_ENDPOINT "https://polly."CONFIG_AWS_POLLY_REGION".amazonaws.com/v1/speech" #define TTS_TEXT "Espressif Systems is a multinational, fabless semiconductor company, with headquarters in Shanghai, China. We specialize in producing highly-integrated, low-power, WiFi-and-Bluetooth IoT solutions. Among our most popular chips are ESP8266 and ESP32. We are committed to creating IoT solutions that are power-efficient, robust and secure." static const char *polly_payload = "{\"OutputFormat\":\"mp3\",\"SampleRate\":\"22050\",\"Text\":\""TTS_TEXT"\",\"TextType\":\"text\",\"VoiceId\":\"Joanna\"}"; @@ -128,7 +140,11 @@ void app_main(void) ESP_ERROR_CHECK(nvs_flash_erase()); err = nvs_flash_init(); } +#if (ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(4, 1, 0)) + ESP_ERROR_CHECK(esp_netif_init()); +#else tcpip_adapter_init(); +#endif ESP_LOGI(TAG, "[ 0 ] Start and wait for Wi-Fi network"); esp_periph_config_t periph_cfg = DEFAULT_ESP_PERIPH_SET_CONFIG(); diff --git a/examples/cloud_services/pipeline_baidu_speech_mp3/main/play_baidu_speech_mp3_example.c b/examples/cloud_services/pipeline_baidu_speech_mp3/main/play_baidu_speech_mp3_example.c index 2cf400e..050099c 100644 --- a/examples/cloud_services/pipeline_baidu_speech_mp3/main/play_baidu_speech_mp3_example.c +++ b/examples/cloud_services/pipeline_baidu_speech_mp3/main/play_baidu_speech_mp3_example.c @@ -29,6 +29,17 @@ #include "esp_http_client.h" #include "baidu_access_token.h" +#if __has_include("esp_idf_version.h") +#include "esp_idf_version.h" +#else +#define ESP_IDF_VERSION_VAL(major, minor, patch) 1 +#endif + +#if (ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(4, 1, 0)) +#include "esp_netif.h" +#else +#include "tcpip_adapter.h" +#endif static const char *TAG = "BAIDU_SPEECH_EXAMPLE"; @@ -76,7 +87,11 @@ void app_main(void) ESP_ERROR_CHECK(nvs_flash_erase()); err = nvs_flash_init(); } +#if (ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(4, 1, 0)) + ESP_ERROR_CHECK(esp_netif_init()); +#else tcpip_adapter_init(); +#endif ESP_LOGI(TAG, "[ 0 ] Start and wait for Wi-Fi network"); esp_periph_config_t periph_cfg = DEFAULT_ESP_PERIPH_SET_CONFIG(); diff --git a/examples/dueros/README.md b/examples/dueros/README.md index c0c4dfd..a05f138 100644 --- a/examples/dueros/README.md +++ b/examples/dueros/README.md @@ -11,7 +11,7 @@ This example is will run on boards marked with green checkbox. Please remember t | ESP32-LyraT | [![alt text](../../docs/_static/esp32-lyrat-v4.3-side-small.jpg "ESP32-LyraT")](https://docs.espressif.com/projects/esp-adf/en/latest/get-started/get-started-esp32-lyrat.html) | ESP32 | ![alt text](../../docs/_static/yes-button.png "Compatible") | | ESP32-LyraTD-MSC | [![alt text](../../docs/_static/esp32-lyratd-msc-v2.2-small.jpg "ESP32-LyraTD-MSC")](https://docs.espressif.com/projects/esp-adf/en/latest/get-started/get-started-esp32-lyratd-msc.html) | ESP32 | ![alt text](../../docs/_static/no-button.png "Compatible") | | ESP32-LyraT-Mini | [![alt text](../../docs/_static/esp32-lyrat-mini-v1.2-small.jpg "ESP32-LyraT-Mini")](https://docs.espressif.com/projects/esp-adf/en/latest/get-started/get-started-esp32-lyrat-mini.html) | ESP32 | ![alt text](../../docs/_static/yes-button.png "Compatible") | -| ESP32-Korvo-DU1906 | [![alt text](../../docs/_static/esp32-korvo-du1906-v1.1-small.jpg "ESP32-Korvo-DU1906")](https://docs.espressif.com/projects/esp-adf/en/latest/get-started/get-started-esp32-korvo-du1906.html) | ESP32 | ![alt text](../../docs/_static/yes-button.png "Compatible") | +| ESP32-Korvo-DU1906 | [![alt text](../../docs/_static/esp32-korvo-du1906-v1.1-small.jpg "ESP32-Korvo-DU1906")](https://docs.espressif.com/projects/esp-adf/en/latest/get-started/get-started-esp32-korvo-du1906.html) | ESP32 | ![alt text](../../docs/_static/no-button.png "Compatible") | | ESP32-S2-Kaluga-1 Kit | [![alt text](../../docs/_static/esp32-s2-kaluga-1-kit-small.png "ESP32-S2-Kaluga-1 Kit")](https://docs.espressif.com/projects/esp-idf/en/latest/esp32s2/hw-reference/esp32s2/user-guide-esp32-s2-kaluga-1-kit.html) | ESP32-S2 | ![alt text](../../docs/_static/no-button.png "Compatible") | diff --git a/examples/dueros/main/app_main.c b/examples/dueros/main/app_main.c index 3432c8e..d013284 100644 --- a/examples/dueros/main/app_main.c +++ b/examples/dueros/main/app_main.c @@ -27,9 +27,20 @@ #include "freertos/task.h" #include "freertos/event_groups.h" #include "nvs_flash.h" -#include "tcpip_adapter.h" #include "dueros_app.h" +#if __has_include("esp_idf_version.h") +#include "esp_idf_version.h" +#else +#define ESP_IDF_VERSION_VAL(major, minor, patch) 1 +#endif + +#if (ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(4, 1, 0)) +#include "esp_netif.h" +#else +#include "tcpip_adapter.h" +#endif + void app_main(void) { esp_err_t err = nvs_flash_init(); @@ -39,6 +50,10 @@ void app_main(void) ESP_ERROR_CHECK(nvs_flash_erase()); err = nvs_flash_init(); } +#if (ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(4, 1, 0)) + ESP_ERROR_CHECK(esp_netif_init()); +#else tcpip_adapter_init(); +#endif duer_app_init(); } diff --git a/examples/dueros/main/dueros_app.c b/examples/dueros/main/dueros_app.c index 4a19780..2de1109 100644 --- a/examples/dueros/main/dueros_app.c +++ b/examples/dueros/main/dueros_app.c @@ -51,6 +51,7 @@ #include "i2s_stream.h" #include "raw_stream.h" #include "filter_resample.h" +#include "audio_sys.h" #include "display_service.h" #include "wifi_service.h" @@ -62,10 +63,10 @@ #if __has_include("esp_idf_version.h") #include "esp_idf_version.h" #else -#define ESP_IDF_VERSION_VAL(major, minor, patch) 0 +#define ESP_IDF_VERSION_VAL(major, minor, patch) 1 #endif -#if (ESP_IDF_VERSION > ESP_IDF_VERSION_VAL(3, 3, 2)) +#if (ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(4, 0, 0)) #include "driver/touch_pad.h" #endif @@ -145,7 +146,7 @@ static esp_err_t recorder_pipeline_open_for_mini(void **handle) audio_pipeline_register(recorder, algo_handle, "algo"); audio_element_set_read_cb(algo_handle, duer_i2s_read_cb, (void *)i2s_reader); audio_pipeline_register(recorder, raw_read, "raw"); - + const char *link_tag[2] = {"algo", "raw"}; audio_pipeline_link(recorder, &link_tag[0], 2); @@ -371,6 +372,23 @@ esp_err_t periph_callback(audio_event_iface_msg_t *event, void *context) return ESP_OK; } +void sys_monitor_task(void *para) +{ + while (1) { + vTaskDelay(5000 / portTICK_PERIOD_MS); + AUDIO_MEM_SHOW(TAG); +#ifdef CONFIG_FREERTOS_USE_TRACE_FACILITY + audio_sys_get_real_time_stats(); +#endif + } + vTaskDelete(NULL); +} + +void start_sys_monitor(void) +{ + xTaskCreatePinnedToCore(sys_monitor_task, "sys_monitor_task", (2 * 1024), NULL, 1, NULL, 1); +} + void duer_app_init(void) { esp_log_level_set("*", ESP_LOG_INFO); @@ -384,10 +402,25 @@ void duer_app_init(void) } audio_board_key_init(set); - audio_board_sdcard_init(set); + audio_board_sdcard_init(set, SD_MODE_1_LINE); disp_serv = audio_board_led_init(); - duer_audio_wrapper_init(); + rec_config_t eng = DEFAULT_REC_ENGINE_CONFIG(); + eng.vad_off_delay_ms = 800; + eng.wakeup_time_ms = 10 * 1000; + eng.evt_cb = rec_engine_cb; +#ifdef CONFIG_ESP_LYRAT_MINI_V1_1_BOARD + eng.open = recorder_pipeline_open_for_mini; +#else + eng.open = recorder_pipeline_open; +#endif + eng.close = recorder_pipeline_close; + eng.fetch = recorder_pipeline_read; + eng.extension = NULL; + eng.support_encoding = false; + eng.user_data = NULL; + rec_engine_create(&eng); + xTimerHandle retry_login_timer = xTimerCreate("tm_duer_login", 1000 / portTICK_PERIOD_MS, pdFALSE, NULL, retry_login_timer_cb); duer_serv_handle = dueros_service_create(); @@ -419,19 +452,6 @@ void duer_app_init(void) wifi_service_set_sta_info(wifi_serv, &sta_cfg); wifi_service_connect(wifi_serv); - rec_config_t eng = DEFAULT_REC_ENGINE_CONFIG(); - eng.vad_off_delay_ms = 800; - eng.wakeup_time_ms = 10 * 1000; - eng.evt_cb = rec_engine_cb; -#ifdef CONFIG_ESP_LYRAT_MINI_V1_1_BOARD - eng.open = recorder_pipeline_open_for_mini; -#else - eng.open = recorder_pipeline_open; -#endif - eng.close = recorder_pipeline_close; - eng.fetch = recorder_pipeline_read; - eng.extension = NULL; - eng.support_encoding = false; - eng.user_data = NULL; - rec_engine_create(&eng); + duer_audio_wrapper_init(); + start_sys_monitor(); } diff --git a/examples/dueros/sdkconfig.defaults b/examples/dueros/sdkconfig.defaults index c230525..bb3135d 100644 --- a/examples/dueros/sdkconfig.defaults +++ b/examples/dueros/sdkconfig.defaults @@ -6,6 +6,7 @@ CONFIG_ESPTOOLPY_FLASHSIZE_4MB=y CONFIG_ESPTOOLPY_BAUD_921600B=y CONFIG_ESPTOOLPY_BAUD=921600 CONFIG_OPTIMIZATION_LEVEL_RELEASE=y +CONFIG_COMPILER_OPTIMIZATION_SIZE=y CONFIG_ESP32_DEFAULT_CPU_FREQ_240=y CONFIG_ESP32_DEFAULT_CPU_FREQ_MHZ=240 @@ -18,6 +19,8 @@ CONFIG_SPIRAM_MEMTEST=y CONFIG_SPIRAM_CACHE_WORKAROUND=y CONFIG_SPIRAM_MALLOC_ALWAYSINTERNAL=16384 CONFIG_WIFI_LWIP_ALLOCATION_FROM_SPIRAM_FIRST=y +CONFIG_SPIRAM_ALLOW_STACK_EXTERNAL_MEMORY=y +CONFIG_SPIRAM_ALLOW_BSS_SEG_EXTERNAL_MEMORY=y CONFIG_SPIRAM_MALLOC_RESERVE_INTERNAL=32768 CONFIG_FREERTOS_HZ=1000 CONFIG_TIMER_TASK_PRIORITY=5 diff --git a/examples/get-started/pipeline_a2dp_sink_and_hfp/main/a2dp_sink_and_hfp_example.c b/examples/get-started/pipeline_a2dp_sink_and_hfp/main/a2dp_sink_and_hfp_example.c index b45d6bd..6628a3f 100755 --- a/examples/get-started/pipeline_a2dp_sink_and_hfp/main/a2dp_sink_and_hfp_example.c +++ b/examples/get-started/pipeline_a2dp_sink_and_hfp/main/a2dp_sink_and_hfp_example.c @@ -10,14 +10,12 @@ #include "nvs_flash.h" #include "freertos/FreeRTOS.h" #include "freertos/task.h" -#include "freertos/queue.h" -#include "freertos/semphr.h" -#include "freertos/ringbuf.h" - - #include "esp_log.h" #include "esp_peripherals.h" +#include "periph_touch.h" +#include "periph_adc_button.h" +#include "periph_button.h" #include "esp_bt_defs.h" #include "esp_gap_bt_api.h" #include "esp_hf_client_api.h" @@ -25,30 +23,36 @@ #include "audio_element.h" #include "audio_pipeline.h" #include "audio_event_iface.h" -#include "audio_common.h" #include "audio_mem.h" #include "i2s_stream.h" -#include "periph_touch.h" #include "board.h" #include "bluetooth_service.h" #include "filter_resample.h" -#include "driver/i2s.h" -#include "recorder_engine.h" #include "raw_stream.h" +#if (CONFIG_ESP_LYRATD_MSC_V2_1_BOARD || CONFIG_ESP_LYRATD_MSC_V2_2_BOARD) +#include "filter_resample.h" +#endif + +#if __has_include("esp_idf_version.h") +#include "esp_idf_version.h" +#else +#define ESP_IDF_VERSION_VAL(major, minor, patch) 1 +#endif + +#if (ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(4, 0, 0)) +#define HFP_RESAMPLE_RATE 16000 +#else +#define HFP_RESAMPLE_RATE 8000 +#endif static const char *TAG = "BLUETOOTH_EXAMPLE"; static const char *BT_HF_TAG = "BT_HF"; -static audio_element_handle_t raw_read, bt_stream_reader, i2s_stream_writer, i2s_stream_reader; +static audio_element_handle_t raw_read, bt_stream_reader, i2s_stream_writer, i2s_stream_reader; static audio_pipeline_handle_t pipeline_d, pipeline_e; -extern int a2dp_sample_rate; - -#define ESP_HFP_RINGBUF_SIZE 3600 -#define ESP_HFP_TASK_SIZE 2048 -#define ESP_HFP_TASK_PRIORITY 23 -static uint32_t control_num = 0; +static bool is_get_hfp = true; const char *c_hf_evt_str[] = { "CONNECTION_STATE_EVT", /*!< connection state changed event */ @@ -194,7 +198,7 @@ const char *c_inband_ring_state_str[] = { static void bt_app_hf_client_audio_open(void) { ESP_LOGE(BT_HF_TAG, "bt_app_hf_client_audio_open"); - int sample_rate = 8000; + int sample_rate = HFP_RESAMPLE_RATE; audio_element_info_t bt_info = {0}; audio_element_getinfo(bt_stream_reader, &bt_info); bt_info.sample_rates = sample_rate; @@ -206,9 +210,8 @@ static void bt_app_hf_client_audio_open(void) static void bt_app_hf_client_audio_close(void) { - ESP_LOGE(BT_HF_TAG, "bt_app_hf_client_audio_close"); - int sample_rate = a2dp_sample_rate; + int sample_rate = periph_bluetooth_get_a2dp_sample_rate(); audio_element_info_t bt_info = {0}; audio_element_getinfo(bt_stream_reader, &bt_info); bt_info.sample_rates = sample_rate; @@ -216,21 +219,24 @@ static void bt_app_hf_client_audio_close(void) bt_info.bits = 16; audio_element_setinfo(bt_stream_reader, &bt_info); audio_element_report_info(bt_stream_reader); - - } static uint32_t bt_app_hf_client_outgoing_cb(uint8_t *p_buf, uint32_t sz) { int out_len_bytes = 0; char *enc_buffer = (char *)audio_malloc(sz); - AUDIO_MEM_CHECK(BT_HF_TAG, enc_buffer, return NULL); - out_len_bytes = raw_stream_read(raw_read, enc_buffer, sz); + AUDIO_MEM_CHECK(BT_HF_TAG, enc_buffer, return 0); + if (is_get_hfp) { + out_len_bytes = raw_stream_read(raw_read, enc_buffer, sz); + } + if (out_len_bytes == sz) { + is_get_hfp = false; memcpy(p_buf, enc_buffer, out_len_bytes); free(enc_buffer); return sz; } else { + is_get_hfp = true; free(enc_buffer); return 0; } @@ -241,15 +247,9 @@ static void bt_app_hf_client_incoming_cb(const uint8_t *buf, uint32_t sz) if (bt_stream_reader) { if (audio_element_get_state(bt_stream_reader) == AEL_STATE_RUNNING) { audio_element_output(bt_stream_reader, (char *)buf, sz); + esp_hf_client_outgoing_data_ready(); } } - - if (control_num < 5) { - control_num ++; - }else { - control_num = 0; - esp_hf_client_outgoing_data_ready(); - } } /* callback for HF_CLIENT */ void bt_hf_client_cb(esp_hf_client_cb_event_t event, esp_hf_client_cb_param_t *param) @@ -389,8 +389,7 @@ void app_main(void) ESP_LOGI(TAG, "[ 2 ] Start codec chip"); audio_board_handle_t board_handle = audio_board_init(); - audio_hal_ctrl_codec(board_handle->audio_hal, AUDIO_HAL_CODEC_MODE_BOTH, AUDIO_HAL_CTRL_START); - + audio_hal_ctrl_codec(board_handle->audio_hal, AUDIO_HAL_CODEC_MODE_DECODE, AUDIO_HAL_CTRL_START); ESP_LOGI(TAG, "[ 3 ] Create audio pipeline for playback"); audio_pipeline_cfg_t pipeline_cfg = DEFAULT_AUDIO_PIPELINE_CONFIG(); @@ -404,45 +403,66 @@ void app_main(void) i2s_stream_cfg_t i2s_cfg2 = I2S_STREAM_CFG_DEFAULT(); i2s_cfg2.type = AUDIO_STREAM_READER; +#if defined CONFIG_ESP_LYRAT_MINI_V1_1_BOARD + i2s_cfg2.i2s_port = 1; + i2s_cfg2.i2s_config.use_apll = false; +#endif i2s_stream_reader = i2s_stream_init(&i2s_cfg2); raw_stream_cfg_t raw_cfg = RAW_STREAM_CFG_DEFAULT(); raw_cfg.type = AUDIO_STREAM_READER; raw_read = raw_stream_init(&raw_cfg); - ESP_LOGI(TAG, "[3.2] Get Bluetooth stream"); + ESP_LOGI(TAG, "[3.2] Create Bluetooth stream"); bt_stream_reader = bluetooth_service_create_stream(); - ESP_LOGI(TAG, "[3.2] Register all elements to audio pipeline"); +#if (CONFIG_ESP_LYRATD_MSC_V2_1_BOARD || CONFIG_ESP_LYRATD_MSC_V2_2_BOARD) + rsp_filter_cfg_t rsp_d_cfg = DEFAULT_RESAMPLE_FILTER_CONFIG(); + audio_element_handle_t filter_d = rsp_filter_init(&rsp_d_cfg); + audio_pipeline_register(pipeline_d, filter_d, "filter_d"); + + rsp_filter_cfg_t rsp_e_cfg = DEFAULT_RESAMPLE_FILTER_CONFIG(); + rsp_e_cfg.src_rate = 48000; + rsp_e_cfg.src_ch = 2; + rsp_e_cfg.dest_rate = HFP_RESAMPLE_RATE; + rsp_e_cfg.dest_ch = 1; + audio_element_handle_t filter_e = rsp_filter_init(&rsp_e_cfg); + audio_pipeline_register(pipeline_e, filter_e, "filter_e"); +#endif + + ESP_LOGI(TAG, "[3.3] Register all elements to audio pipeline"); audio_pipeline_register(pipeline_d, bt_stream_reader, "bt"); - audio_pipeline_register(pipeline_d, i2s_stream_writer, "i2s"); + audio_pipeline_register(pipeline_d, i2s_stream_writer, "i2s_w"); - audio_pipeline_register(pipeline_e, i2s_stream_reader, "i2s"); + audio_pipeline_register(pipeline_e, i2s_stream_reader, "i2s_r"); audio_pipeline_register(pipeline_e, raw_read, "raw"); - ESP_LOGI(TAG, "[3.3] Link it together [Bluetooth]-->bt_stream_reader-->i2s_stream_writer-->[codec_chip]"); - const char *link_d[2] = {"bt", "i2s"}; + ESP_LOGI(TAG, "[3.4] Link it together [Bluetooth]-->bt_stream_reader-->i2s_stream_writer-->[codec_chip]"); +#if (CONFIG_ESP_LYRATD_MSC_V2_1_BOARD || CONFIG_ESP_LYRATD_MSC_V2_2_BOARD) + const char *link_d[3] = {"bt", "filter_d", "i2s_w"}; + audio_pipeline_link(pipeline_d, &link_d[0], 3); + + const char *link_e[3] = {"i2s_r", "filter_e", "raw"}; + audio_pipeline_link(pipeline_e, &link_e[0], 3); +#else + const char *link_d[2] = {"bt", "i2s_w"}; audio_pipeline_link(pipeline_d, &link_d[0], 2); - - const char *link_e[2] = {"i2s", "raw"}; + + const char *link_e[2] = {"i2s_r", "raw"}; audio_pipeline_link(pipeline_e, &link_e[0], 2); +#endif ESP_LOGI(TAG, "[ 4 ] Initialize peripherals"); esp_periph_config_t periph_cfg = DEFAULT_ESP_PERIPH_SET_CONFIG(); esp_periph_set_handle_t set = esp_periph_set_init(&periph_cfg); ESP_LOGI(TAG, "[4.1] Initialize Touch peripheral"); - periph_touch_cfg_t touch_cfg = { - .touch_mask = BIT(get_input_set_id()) | BIT(get_input_play_id()) | BIT(get_input_volup_id()) | BIT(get_input_voldown_id()), - .tap_threshold_percent = 70, - }; - esp_periph_handle_t touch_periph = periph_touch_init(&touch_cfg); + audio_board_key_init(set); ESP_LOGI(TAG, "[4.2] Create Bluetooth peripheral"); esp_periph_handle_t bt_periph = bluetooth_service_create_periph(); ESP_LOGI(TAG, "[4.2] Start all peripherals"); - esp_periph_start(set, touch_periph); esp_periph_start(set, bt_periph); ESP_LOGI(TAG, "[ 5 ] Set up event listener"); @@ -468,11 +488,6 @@ void app_main(void) continue; } - if (msg.cmd == AEL_MSG_CMD_ERROR) { - ESP_LOGE(TAG, "[ * ] Action command error: src_type:%d, source:%p cmd:%d, data:%p, data_len:%d", - msg.source_type, msg.source, msg.cmd, msg.data, msg.data_len); - } - if (msg.source_type == AUDIO_ELEMENT_TYPE_ELEMENT && msg.source == (void *) bt_stream_reader && msg.cmd == AEL_MSG_CMD_REPORT_MUSIC_INFO) { audio_element_info_t music_info = {0}; @@ -480,16 +495,22 @@ void app_main(void) ESP_LOGI(TAG, "[ * ] Receive music info from Bluetooth, sample_rates=%d, bits=%d, ch=%d", music_info.sample_rates, music_info.bits, music_info.channels); - +#if (CONFIG_ESP_LYRATD_MSC_V2_1_BOARD || CONFIG_ESP_LYRATD_MSC_V2_2_BOARD) + rsp_filter_set_src_info(filter_d, music_info.sample_rates, music_info.channels); + i2s_stream_set_clk(i2s_stream_writer, 48000, 16, 2); +#else audio_element_setinfo(i2s_stream_writer, &music_info); i2s_stream_set_clk(i2s_stream_writer, music_info.sample_rates, music_info.bits, music_info.channels); +#endif + +#if defined CONFIG_ESP_LYRAT_MINI_V1_1_BOARD + i2s_stream_set_clk(i2s_stream_reader, music_info.sample_rates, music_info.bits, music_info.channels); +#endif continue; } - - if (msg.source_type == PERIPH_ID_TOUCH - && msg.cmd == PERIPH_TOUCH_TAP - && msg.source == (void *)touch_periph) { + if ((msg.source_type == PERIPH_ID_TOUCH || msg.source_type == PERIPH_ID_BUTTON || msg.source_type == PERIPH_ID_ADC_BTN) + && (msg.cmd == PERIPH_TOUCH_TAP || msg.cmd == PERIPH_BUTTON_PRESSED || msg.cmd == PERIPH_ADC_BUTTON_PRESSED)) { if ((int) msg.data == get_input_play_id()) { ESP_LOGI(TAG, "[ * ] [Play] touch tap event"); @@ -536,6 +557,10 @@ void app_main(void) audio_pipeline_unregister(pipeline_e, i2s_stream_reader); audio_pipeline_unregister(pipeline_e, raw_read); +#if (CONFIG_ESP_LYRATD_MSC_V2_1_BOARD || CONFIG_ESP_LYRATD_MSC_V2_2_BOARD) + audio_pipeline_unregister(pipeline_d, filter_d); + audio_pipeline_unregister(pipeline_e, filter_e); +#endif /* Terminate the pipeline before removing the listener */ audio_pipeline_remove_listener(pipeline_d); @@ -552,8 +577,10 @@ void app_main(void) audio_element_deinit(i2s_stream_writer); audio_element_deinit(i2s_stream_reader); audio_element_deinit(raw_read); +#if (CONFIG_ESP_LYRATD_MSC_V2_1_BOARD || CONFIG_ESP_LYRATD_MSC_V2_2_BOARD) + audio_element_deinit(filter_d); + audio_element_deinit(filter_e); +#endif esp_periph_set_destroy(set); bluetooth_service_destroy(); } - - diff --git a/examples/get-started/pipeline_a2dp_sink_and_hfp/sdkconfig.defaults b/examples/get-started/pipeline_a2dp_sink_and_hfp/sdkconfig.defaults index e50fe15..103fd80 100644 --- a/examples/get-started/pipeline_a2dp_sink_and_hfp/sdkconfig.defaults +++ b/examples/get-started/pipeline_a2dp_sink_and_hfp/sdkconfig.defaults @@ -5,13 +5,9 @@ CONFIG_BLUEDROID_ENABLED=y CONFIG_CLASSIC_BT_ENABLED=y CONFIG_A2DP_ENABLE=y CONFIG_A2DP_SINK_ENABLE=y -CONFIG_A2DP_SRC_ENABLE= -CONFIG_BT_SPP_ENABLED= -CONFIG_GATTS_ENABLE= -CONFIG_GATTC_ENABLE= -CONFIG_BLE_SMP_ENABLE= -CONFIG_BTDM_CONTROLLER_MODE_BR_EDR_ONLY=y + +CONFIG_BTDM_CONTROLLER_MODE_BTDM=y CONFIG_BTDM_CONTROLLER_BR_EDR_MAX_SYNC_CONN=2 CONFIG_BTDM_CONTROLLER_BR_EDR_MAX_SYNC_CONN_EFF=2 CONFIG_HFP_ENABLE=y diff --git a/examples/get-started/pipeline_tcp_client/main/tcp_client_example.c b/examples/get-started/pipeline_tcp_client/main/tcp_client_example.c index c06c8fa..ff63e4e 100644 --- a/examples/get-started/pipeline_tcp_client/main/tcp_client_example.c +++ b/examples/get-started/pipeline_tcp_client/main/tcp_client_example.c @@ -24,6 +24,18 @@ #include "periph_sdcard.h" #include "board.h" +#if __has_include("esp_idf_version.h") +#include "esp_idf_version.h" +#else +#define ESP_IDF_VERSION_VAL(major, minor, patch) 1 +#endif + +#if (ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(4, 1, 0)) +#include "esp_netif.h" +#else +#include "tcpip_adapter.h" +#endif + static const char *TAG = "TCP_CLIENT_EXAMPLE"; void app_main(void) @@ -35,7 +47,11 @@ void app_main(void) ESP_ERROR_CHECK(nvs_flash_erase()); err = nvs_flash_init(); } +#if (ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(4, 1, 0)) + ESP_ERROR_CHECK(esp_netif_init()); +#else tcpip_adapter_init(); +#endif audio_pipeline_handle_t pipeline; audio_element_handle_t tcp_stream_reader, mp3_decoder, i2s_stream_writer; diff --git a/examples/get-started/pipeline_tcp_client/tools/esp32.mp3 b/examples/get-started/pipeline_tcp_client/tools/esp32.mp3 new file mode 100644 index 0000000..a9a07f2 Binary files /dev/null and b/examples/get-started/pipeline_tcp_client/tools/esp32.mp3 differ diff --git a/examples/get-started/pipeline_tcp_client_opus/CMakeLists.txt b/examples/get-started/pipeline_tcp_client_opus/CMakeLists.txt new file mode 100644 index 0000000..dd3e77d --- /dev/null +++ b/examples/get-started/pipeline_tcp_client_opus/CMakeLists.txt @@ -0,0 +1,8 @@ +# 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{ADF_PATH}/CMakeLists.txt) +include($ENV{IDF_PATH}/tools/cmake/project.cmake) + +project(tcp_client_example) \ No newline at end of file diff --git a/examples/get-started/pipeline_tcp_client_opus/Makefile b/examples/get-started/pipeline_tcp_client_opus/Makefile new file mode 100644 index 0000000..a433a4c --- /dev/null +++ b/examples/get-started/pipeline_tcp_client_opus/Makefile @@ -0,0 +1,3 @@ +PROJECT_NAME := tcp_client_example +include $(ADF_PATH)/project.mk + diff --git a/examples/get-started/pipeline_tcp_client_opus/README.md b/examples/get-started/pipeline_tcp_client_opus/README.md new file mode 100644 index 0000000..809a4ad --- /dev/null +++ b/examples/get-started/pipeline_tcp_client_opus/README.md @@ -0,0 +1,32 @@ +# # Play mp3 file from Tcp stream + +The demo request data from local server via tcp client. + +## Compatibility + +This example is will run on boards marked with green checkbox. Please remember to select the board in menuconfig as discussed is section *Usage* below. + +| Board Name | Getting Started | Chip | Compatible | +|-------------------|:--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------:|:--------------------------------------------------------------------:|:-----------------------------------------------------------------:| +| ESP32-LyraT | [![alt text](../../../docs/_static/esp32-lyrat-v4.3-side-small.jpg "ESP32-LyraT")](https://docs.espressif.com/projects/esp-adf/en/latest/get-started/get-started-esp32-lyrat.html) | ESP32 | ![alt text](../../../docs/_static/yes-button.png "Compatible") | +| ESP32-LyraTD-MSC | [![alt text](../../../docs/_static/esp32-lyratd-msc-v2.2-small.jpg "ESP32-LyraTD-MSC")](https://docs.espressif.com/projects/esp-adf/en/latest/get-started/get-started-esp32-lyratd-msc.html) | ESP32 | ![alt text](../../../docs/_static/yes-button.png "Compatible") | +| ESP32-LyraT-Mini | [![alt text](../../../docs/_static/esp32-lyrat-mini-v1.2-small.jpg "ESP32-LyraT-Mini")](https://docs.espressif.com/projects/esp-adf/en/latest/get-started/get-started-esp32-lyrat-mini.html) | ESP32 | ![alt text](../../../docs/_static/yes-button.png "Compatible") | +| ESP32-Korvo-DU1906 | [![alt text](../../../docs/_static/esp32-korvo-du1906-v1.1-small.jpg "ESP32-Korvo-DU1906")](https://docs.espressif.com/projects/esp-adf/en/latest/get-started/get-started-esp32-korvo-du1906.html) | ESP32 | ![alt text](../../../docs/_static/yes-button.png "Compatible") | +| ESP32-S2-Kaluga-1 Kit | [![alt text](../../../docs/_static/esp32-s2-kaluga-1-kit-small.png "ESP32-S2-Kaluga-1 Kit")](https://docs.espressif.com/projects/esp-idf/en/latest/esp32s2/hw-reference/esp32s2/user-guide-esp32-s2-kaluga-1-kit.html) | ESP32-S2 | ![alt text](../../../docs/_static/yes-button.png "Compatible") | +## Usage + +Prepare the audio board: + +- Connect speakers or headphones to the board. + +Configure the example: + +- Select compatible audio board in `menuconfig` > `Audio HAL`. +- Set up the Wi-Fi connection by running `menuconfig` > `Example Configuration` and filling in `WiFi SSID` , `WiFi Password` `CONFIG_TCP_URL` and `CONFIG_TCP_PORT`. + +Load and run the example: + +- Copy a mp3 music to tools folder, and named `esp32.mp3` +- Run the `tcp_server_write.py` script from *`tools`* folder +- The audio board will first connect to the Wi-Fi. +- Then the board will get data from local server and play \ No newline at end of file diff --git a/examples/get-started/pipeline_tcp_client_opus/debug.log b/examples/get-started/pipeline_tcp_client_opus/debug.log new file mode 100644 index 0000000..9988edf --- /dev/null +++ b/examples/get-started/pipeline_tcp_client_opus/debug.log @@ -0,0 +1,3 @@ +2020-11-24 17:08:28,513 - Debug Adapter (main) - CRITICAL - Debug adapter -> Extension: DEBUG_ADAPTER_STARTED +2020-11-24 17:08:28,515 - Debug Adapter (main) - CRITICAL - Debug adapter -> Extension: DEBUG_ADAPTER_READY2CONNECT +2020-11-24 17:08:38,718 - Debug Adapter (main) - CRITICAL - Debug adapter -> Extension: DEBUG_ADAPTER_STOPPED diff --git a/examples/get-started/pipeline_tcp_client_opus/gdbinit b/examples/get-started/pipeline_tcp_client_opus/gdbinit new file mode 100644 index 0000000..0d68027 --- /dev/null +++ b/examples/get-started/pipeline_tcp_client_opus/gdbinit @@ -0,0 +1,6 @@ +target remote :3333 +set remote hardware-watchpoint-limit 2 +mon reset halt +flushregs +thb app_main +c \ No newline at end of file diff --git a/examples/get-started/pipeline_tcp_client_opus/main/CMakeLists.txt b/examples/get-started/pipeline_tcp_client_opus/main/CMakeLists.txt new file mode 100644 index 0000000..14432f1 --- /dev/null +++ b/examples/get-started/pipeline_tcp_client_opus/main/CMakeLists.txt @@ -0,0 +1,4 @@ +set(COMPONENT_SRCS "tcp_client_example.c") +set(COMPONENT_ADD_INCLUDEDIRS .) + +register_component() \ No newline at end of file diff --git a/examples/get-started/pipeline_tcp_client_opus/main/Kconfig.projbuild b/examples/get-started/pipeline_tcp_client_opus/main/Kconfig.projbuild new file mode 100644 index 0000000..651a70b --- /dev/null +++ b/examples/get-started/pipeline_tcp_client_opus/main/Kconfig.projbuild @@ -0,0 +1,37 @@ +menu "Example Configuration" + +config WIFI_SSID + string "WiFi SSID" + default "myssid" + help + SSID (network name) for the example to connect to. + +config WIFI_PASSWORD + string "WiFi Password" + default "mypassword" + help + WiFi password (WPA or WPA2) for the example to use. + + Can be left blank if the network has no security set. + +config TCP_URL + string "TCP URL" + default "192.168.4.1" + help + WiFi password (WPA or WPA2) for the example to use. + + Can be left blank if the network has no security set. + +config TCP_PORT + int "TCP PORT" + default "8080" + help + WiFi password (WPA or WPA2) for the example to use. + + Can be left blank if the network has no security set. + +config TCP_PORT_OUT + int "TCP PORT_OUT" + default "8081" + +endmenu \ No newline at end of file diff --git a/examples/get-started/pipeline_tcp_client_opus/main/component.mk b/examples/get-started/pipeline_tcp_client_opus/main/component.mk new file mode 100644 index 0000000..44bd2b5 --- /dev/null +++ b/examples/get-started/pipeline_tcp_client_opus/main/component.mk @@ -0,0 +1,3 @@ +# +# Main Makefile. This is basically the same as a component makefile. +# diff --git a/examples/get-started/pipeline_tcp_client_opus/main/tcp_client_example.c b/examples/get-started/pipeline_tcp_client_opus/main/tcp_client_example.c new file mode 100644 index 0000000..ffe09b2 --- /dev/null +++ b/examples/get-started/pipeline_tcp_client_opus/main/tcp_client_example.c @@ -0,0 +1,201 @@ +/* Play music to from local server + + 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 +#include "esp_log.h" +#include "esp_wifi.h" +#include "nvs_flash.h" +#include "sdkconfig.h" + +#include "audio_pipeline.h" +#include "audio_event_iface.h" +#include "tcp_client_stream.h" +#include "opus_decoder.h" +#include "opus_encoder.h" +#include "wav_encoder.h" +#include "i2s_stream.h" + +#include "esp_peripherals.h" +#include "periph_wifi.h" +#include "periph_sdcard.h" +#include "board.h" + +static const char *TAG = "TCP_CLIENT_EXAMPLE"; + +void app_main(void) +{ + esp_err_t err = nvs_flash_init(); + if (err == ESP_ERR_NVS_NO_FREE_PAGES) { + // NVS partition was truncated and needs to be erased + // Retry nvs_flash_init + ESP_ERROR_CHECK(nvs_flash_erase()); + err = nvs_flash_init(); + } + tcpip_adapter_init(); + + audio_pipeline_handle_t pipeline, pipeline_out; + audio_element_handle_t tcp_stream_reader,tcp_stream_writter,wav_encoder, opus_decoder,opus_encoder, i2s_stream_writer,i2s_stream_reader; + + esp_log_level_set("*", ESP_LOG_WARN); + esp_log_level_set(TAG, ESP_LOG_DEBUG); + + ESP_LOGI(TAG, "[ 1 ] Start codec chip"); + audio_board_handle_t board_handle = audio_board_init(); + audio_hal_ctrl_codec(board_handle->audio_hal, AUDIO_HAL_CODEC_MODE_DECODE, AUDIO_HAL_CTRL_START); + + ESP_LOGI(TAG, "[2.0] Create audio pipeline for playback"); + audio_pipeline_cfg_t pipeline_cfg = DEFAULT_AUDIO_PIPELINE_CONFIG(); + pipeline = audio_pipeline_init(&pipeline_cfg); + pipeline_out = audio_pipeline_init(&pipeline_cfg); + AUDIO_NULL_CHECK(TAG, pipeline, return); + + ESP_LOGI(TAG, "[2.1] Create i2s stream to write data to codec chip"); + i2s_stream_cfg_t i2s_cfg = I2S_STREAM_CFG_DEFAULT(); + i2s_cfg.type = AUDIO_STREAM_WRITER; + i2s_cfg.i2s_config.sample_rate = 16000; + i2s_cfg.i2s_config.channel_format = I2S_CHANNEL_FMT_ONLY_LEFT; + i2s_stream_writer = i2s_stream_init(&i2s_cfg); + AUDIO_NULL_CHECK(TAG, i2s_stream_writer, return); + + i2s_cfg.type = AUDIO_STREAM_READER; + i2s_stream_reader = i2s_stream_init(&i2s_cfg); + + ESP_LOGI(TAG, "[2.2] Create wav decoder to decode wav file"); + opus_decoder_cfg_t opus_cfg = DEFAULT_OPUS_DECODER_CONFIG(); + opus_cfg.task_core = 1; // if use core 0 music will be disfluency + opus_cfg.task_prio = 30; + opus_decoder = decoder_opus_init(&opus_cfg); + AUDIO_NULL_CHECK(TAG, opus_decoder, return); + + opus_encoder_cfg_t opus_cfg_e = DEFAULT_OPUS_ENCODER_CONFIG(); + opus_cfg_e.sample_rate = 16000; + opus_cfg_e.channel = 1; + opus_cfg_e.bitrate = 64000; + opus_cfg_e.complexity = 0; + opus_cfg_e.task_core = 0; // if use core 0 music will be disfluency + opus_cfg_e.task_prio = 30; + opus_encoder = encoder_opus_init(&opus_cfg_e); + AUDIO_NULL_CHECK(TAG, opus_encoder, return); + + wav_encoder_cfg_t wav_cfg_e = DEFAULT_WAV_ENCODER_CONFIG(); + wav_encoder = wav_encoder_init(&wav_cfg_e); + + ESP_LOGI(TAG, "[2.2] Create tcp client stream to read data"); + tcp_stream_cfg_t tcp_cfg = TCP_STREAM_CFG_DEFAULT(); + // tcp_cfg.type = AUDIO_STREAM_READER; + // tcp_cfg.port = CONFIG_TCP_PORT; + // tcp_cfg.host = CONFIG_TCP_URL; + // tcp_stream_reader = tcp_stream_init(&tcp_cfg); + // AUDIO_NULL_CHECK(TAG, tcp_stream_reader, return); + + tcp_cfg.type = AUDIO_STREAM_WRITER; + tcp_cfg.port = CONFIG_TCP_PORT_OUT; + tcp_cfg.host = CONFIG_TCP_URL; + tcp_stream_writter = tcp_stream_init(&tcp_cfg); + AUDIO_NULL_CHECK(TAG, tcp_stream_writter, return); + + + ESP_LOGI(TAG, "[2.3] Register all elements to audio pipeline"); + // audio_pipeline_register(pipeline, tcp_stream_reader, "tcp"); + // audio_pipeline_register(pipeline, opus_decoder, "opus"); + // audio_pipeline_register(pipeline, i2s_stream_writer, "i2s"); + + audio_pipeline_register(pipeline_out, tcp_stream_writter, "tcp_w"); + // audio_pipeline_register(pipeline_out, opus_decoder, "opus_d"); + // audio_pipeline_register(pipeline_out, opus_encoder, "opus_e"); + audio_pipeline_register(pipeline_out,wav_encoder,"wav_e"); + // audio_pipeline_register(pipeline_out, i2s_stream_writer, "i2s_w"); + audio_pipeline_register(pipeline_out, i2s_stream_reader, "i2s_r"); + + ESP_LOGI(TAG, "[2.4] Link it together tcp-->wav-->i2s"); + // audio_pipeline_link(pipeline, (const char *[]) {"tcp", "opus", "i2s"}, 3); + audio_pipeline_link(pipeline_out, (const char *[]) {"i2s_r","wav_e", "tcp_w"}, 3); + + ESP_LOGI(TAG, "[ 3 ] Start and wait for Wi-Fi network"); + esp_periph_config_t periph_cfg = DEFAULT_ESP_PERIPH_SET_CONFIG(); + esp_periph_set_handle_t set = esp_periph_set_init(&periph_cfg); + periph_wifi_cfg_t wifi_cfg = { + .ssid = CONFIG_WIFI_SSID, + .password = CONFIG_WIFI_PASSWORD, + }; + esp_periph_handle_t wifi_handle = periph_wifi_init(&wifi_cfg); + esp_periph_start(set, wifi_handle); + periph_wifi_wait_for_connected(wifi_handle, portMAX_DELAY); + + ESP_LOGI(TAG, "[ 4 ] Set up event listener"); + audio_event_iface_cfg_t evt_cfg = AUDIO_EVENT_IFACE_DEFAULT_CFG(); + audio_event_iface_handle_t evt = audio_event_iface_init(&evt_cfg); + + ESP_LOGI(TAG, "[4.1] Listening event from all elements of pipeline"); + // audio_pipeline_set_listener(pipeline, evt); + audio_pipeline_set_listener(pipeline_out, evt); + + ESP_LOGI(TAG, "[4.2] Listening event from peripherals"); + audio_event_iface_set_listener(esp_periph_set_get_event_iface(set), evt); + + ESP_LOGI(TAG, "[ 5 ] Start audio_pipeline"); + // audio_pipeline_run(pipeline); + audio_pipeline_run(pipeline_out); + + while (1) { + audio_event_iface_msg_t msg; + esp_err_t ret = audio_event_iface_listen(evt, &msg, portMAX_DELAY); + if (ret != ESP_OK) { + ESP_LOGE(TAG, "[ * ] Event interface error : %d", ret); + continue; + } + + if (msg.source_type == AUDIO_ELEMENT_TYPE_ELEMENT && msg.source == (void *) opus_decoder + && msg.cmd == AEL_MSG_CMD_REPORT_MUSIC_INFO) { + audio_element_info_t music_info = {0}; + audio_element_getinfo(opus_decoder, &music_info); + + ESP_LOGI(TAG, "[ * ] Receive music info from mp3 decoder, sample_rates=%d, bits=%d, ch=%d", + music_info.sample_rates, music_info.bits, music_info.channels); + + audio_element_setinfo(i2s_stream_writer, &music_info); + i2s_stream_set_clk(i2s_stream_writer, music_info.sample_rates, music_info.bits, music_info.channels); + continue; + } + + /* Stop when the last pipeline element (i2s_stream_writer in this case) receives stop event */ + if (msg.source_type == AUDIO_ELEMENT_TYPE_ELEMENT && msg.source == (void *) i2s_stream_writer + && msg.cmd == AEL_MSG_CMD_REPORT_STATUS + && (((int)msg.data == AEL_STATUS_STATE_STOPPED) || ((int)msg.data == AEL_STATUS_STATE_FINISHED))) { + ESP_LOGW(TAG, "[ * ] Stop event received"); + break; + } + } + + ESP_LOGI(TAG, "[ 6 ] Stop audio_pipeline"); + audio_pipeline_stop(pipeline); + audio_pipeline_wait_for_stop(pipeline); + audio_pipeline_terminate(pipeline); + + /* Terminate the pipeline before removing the listener */ + // audio_pipeline_unregister(pipeline, tcp_stream_reader); + audio_pipeline_unregister(pipeline, i2s_stream_writer); + audio_pipeline_unregister(pipeline, opus_decoder); + + audio_pipeline_remove_listener(pipeline); + + /* Stop all peripherals before removing the listener */ + esp_periph_set_stop_all(set); + audio_event_iface_remove_listener(esp_periph_set_get_event_iface(set), evt); + + /* Make sure audio_pipeline_remove_listener & audio_event_iface_remove_listener are called before destroying event_iface */ + audio_event_iface_destroy(evt); + + /* Release all resources */ + audio_pipeline_deinit(pipeline); + // audio_element_deinit(tcp_stream_reader); + audio_element_deinit(i2s_stream_writer); + audio_element_deinit(opus_decoder); + esp_periph_set_destroy(set); +} diff --git a/examples/get-started/pipeline_tcp_client_opus/partitions.csv b/examples/get-started/pipeline_tcp_client_opus/partitions.csv new file mode 100644 index 0000000..e43e81a --- /dev/null +++ b/examples/get-started/pipeline_tcp_client_opus/partitions.csv @@ -0,0 +1,4 @@ +# Name, Type, SubType, Offset, Size +nvs, data, nvs, 0x9000, 0x4000 +phy_init, data, phy, 0xd000, 0x1000 +factory, app, factory, 0x10000, 3M, diff --git a/examples/get-started/pipeline_tcp_client_opus/sdkconfig.defaults b/examples/get-started/pipeline_tcp_client_opus/sdkconfig.defaults new file mode 100644 index 0000000..fc3cd2e --- /dev/null +++ b/examples/get-started/pipeline_tcp_client_opus/sdkconfig.defaults @@ -0,0 +1,3 @@ +CONFIG_PARTITION_TABLE_CUSTOM=y +CONFIG_PARTITION_TABLE_CUSTOM_FILENAME="partitions.csv" +CONFIG_ESPTOOLPY_FLASHSIZE_4MB=y diff --git a/examples/get-started/pipeline_tcp_client_opus/tools/esp32.mp3 b/examples/get-started/pipeline_tcp_client_opus/tools/esp32.mp3 new file mode 100644 index 0000000..a9a07f2 Binary files /dev/null and b/examples/get-started/pipeline_tcp_client_opus/tools/esp32.mp3 differ diff --git a/examples/get-started/pipeline_tcp_client_opus/tools/tcp_server.py b/examples/get-started/pipeline_tcp_client_opus/tools/tcp_server.py new file mode 100755 index 0000000..6539fb0 --- /dev/null +++ b/examples/get-started/pipeline_tcp_client_opus/tools/tcp_server.py @@ -0,0 +1,81 @@ +#!/user/bin/env python + +# ESPRESSIF MIT License +# +# Copyright (c) 2020 +# +# Permission is hereby granted for use on all ESPRESSIF SYSTEMS products, in which case, +# it is free of charge, to any person obtaining a copy of this software and associated +# documentation files (the "Software"), to deal in the Software without restriction, including +# without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, +# and/or sell copies of the Software, and to permit persons to whom the Software is furnished +# to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in all copies or +# substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS +# FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR +# COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +# IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +import socket +import os + +RCV_BUF_SIZE = 8194 +SND_BUF_SIZE = 8194 +SERVER_PORT = 8080 +read_size = 0 + +FILE_PATH = "./" +FILE_NAME = "esp32.mp3" + +def log_info(value): + print("\033[35m[%s][user]%s\033[0m"%(get_time_stamp(),value)) + +def start_tcp_server(ip, port): + + fo = open("esp32.mp3", "rb+") + fsize = os.path.getsize(FILE_PATH+FILE_NAME) + print ("Get the %s size is %d" % (FILE_NAME, fsize)) + + sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) + server_address = (ip, port) + + print("starting listen on ip %s, port %s" % server_address) + sock.bind(server_address) + + sock.setsockopt(socket.SOL_SOCKET, socket.SO_RCVBUF, RCV_BUF_SIZE) + sock.setsockopt(socket.SOL_SOCKET, socket.SO_RCVBUF, SND_BUF_SIZE) + + try: + sock.listen(1) + except socket.error: + print("fail to listen on port %s" % e) + sys.exit(1) + + print("waiting for client to connect") + client, addr = sock.accept() + send_msg = "get msg, will download" + client.send(send_msg.encode()) + global read_size + while True: + file_msg = fo.read(1024) + read_size += len(file_msg) + print('total size \033[1;35m [%d/%d] \033[0m' % (read_size, fsize)) + if (len(file_msg) <= 0): + print("get all data for %s" % FILE_NAME) + fo.seek(0,0) + read_size = 0 + else: + client.send(file_msg) + + fo.close() + client.close() + sock.close() + print(" close client connect ") + +if __name__=='__main__': + start_tcp_server(socket.gethostbyname(socket.getfqdn(socket.gethostname())),SERVER_PORT) diff --git a/examples/get-started/play_mp3/components/my_board/my_board_v1_0/board.c b/examples/get-started/play_mp3/components/my_board/my_board_v1_0/board.c index d46f791..f2a51cd 100644 --- a/examples/get-started/play_mp3/components/my_board/my_board_v1_0/board.c +++ b/examples/get-started/play_mp3/components/my_board/my_board_v1_0/board.c @@ -71,7 +71,7 @@ esp_err_t audio_board_key_init(esp_periph_set_handle_t set) return ret; } -esp_err_t audio_board_sdcard_init(esp_periph_set_handle_t set) +esp_err_t audio_board_sdcard_init(esp_periph_set_handle_t set, periph_sdcard_mode_t mode) { periph_sdcard_cfg_t sdcard_cfg = { .root = "/sdcard", diff --git a/examples/get-started/play_mp3/components/my_board/my_board_v1_0/board.h b/examples/get-started/play_mp3/components/my_board/my_board_v1_0/board.h index ac71798..c6dd377 100644 --- a/examples/get-started/play_mp3/components/my_board/my_board_v1_0/board.h +++ b/examples/get-started/play_mp3/components/my_board/my_board_v1_0/board.h @@ -29,6 +29,7 @@ #include "board_def.h" #include "board_pins_config.h" #include "esp_peripherals.h" +#include "periph_sdcard.h" #ifdef __cplusplus extern "C" { @@ -85,7 +86,7 @@ esp_err_t audio_board_key_init(esp_periph_set_handle_t set); * - ESP_OK, success * - Others, fail */ -esp_err_t audio_board_sdcard_init(esp_periph_set_handle_t set); +esp_err_t audio_board_sdcard_init(esp_periph_set_handle_t set, periph_sdcard_mode_t mode); /** * @brief Query audio_board_handle diff --git a/examples/get-started/play_mp3_control/main/play_mp3_control_example.c b/examples/get-started/play_mp3_control/main/play_mp3_control_example.c index b9a030a..482c541 100644 --- a/examples/get-started/play_mp3_control/main/play_mp3_control_example.c +++ b/examples/get-started/play_mp3_control/main/play_mp3_control_example.c @@ -151,10 +151,11 @@ void app_main(void) break; case AEL_STATE_FINISHED : ESP_LOGI(TAG, "[ * ] Rewinding audio pipeline"); - audio_pipeline_stop(pipeline); - audio_pipeline_wait_for_stop(pipeline); + audio_pipeline_reset_ringbuffer(pipeline); + audio_pipeline_reset_elements(pipeline); + audio_pipeline_change_state(pipeline, AEL_STATE_INIT); adf_music_mp3_pos = 0; - audio_pipeline_resume(pipeline); + audio_pipeline_run(pipeline); break; default : ESP_LOGI(TAG, "[ * ] Not supported state %d", el_state); diff --git a/examples/korvo_du1906/README.md b/examples/korvo_du1906/README.md index a9213f7..159a0b0 100755 --- a/examples/korvo_du1906/README.md +++ b/examples/korvo_du1906/README.md @@ -42,9 +42,9 @@ Flash address | Bin Path 0x8000 | partitions.bin 0xf000 | phy_init_data.bin 0x10000 | app.bin -0x510000 | DU1906_slave_v1.4.8.E.bin -0x790000 | profile.bin -0x791000 | audio_tone.bin +0x570000 | DU1906_slave_v1.5.5.D.bin +0x7d9000 | audio_tone.bin +0x7FF000 | profile.bin ### Download firmware @@ -60,13 +60,13 @@ python $ADF_PATH/esp-idf/components/esptool_py/esptool/esptool.py --chip esp32 \ 0x8000 ./firmware/partitions.bin \ 0xf000 ./firmware/phy_init_data.bin \ 0x10000 ./firmware/app.bin \ -0x510000 ./firmware/DU1906_slave_v1.4.8.E.bin \ -0x790000 ./profiles/profile.bin \ -0x791000 ./tone/audio_tone.bin +0x570000 ./firmware/DU1906_slave_v1.5.5.D.bin \ +0x7d9000 ./tone/audio_tone.bin \ +0x7FF000 ./profiles/profile.bin ``` #### Windows operating system -- **step 1:** [Download the firmware download tool](https://www.espressif.com/sites/default/files/tools/flash_download_tool_v3.8.5_0.zip) and unzip the compressed package, then run the executable file with ".exe" suffix. +- **step 1:** [Download the Flash Download Tool](https://www.espressif.com/en/support/download/other-tools) and unzip the compressed package, then run the executable file with ".exe" suffix. - **step 2:** Choose download mode (Developer Mode) Tool choose mode @@ -136,25 +136,19 @@ After the experience, it's time to build the example now! you can also add some For now, we need to select audio IDF branch as follow. ```bash cd $IDF_PATH +git checkout master git pull -git checkout -b audio/stack_on_psram_v3.3 origin/audio/stack_on_psram_v3.3 +git checkout audio/stack_on_psram_v3.3 git submodule update --init --recursive ``` -The latest commit ID is `0c1859a5a5a5eded5af1b9423c290781e3973915` +The latest commit ID is `606dd2b629f264aa37a0d76fe23805d61bc6c712` ### ADF Patches For now, we need an ADF patch as follow. ```bash cd $ADF_PATH git apply ./idf_patches/adf_http_stream.patch -``` - -### Menuconfig - -Select the default sdkconfig for build - -```bash -cp sdkconfig.defaults sdkconfig +git apply ./examples/korvo_du1906/patches/a2dp_stream_du1906.patch ``` ### Build @@ -189,22 +183,22 @@ idf.py flash -p PORT **Note:** Replace `PORT` with USB port name where ESP32-Korvo-DU1906 board is connected to. -In addition, ESP32-Korvo-DU1906 have three more bins, `./firmware/DU1906_slave_v1.4.8.E.bin`, `./profiles/profile.bin` and `./tone/audio-esp.bin`. +In addition, ESP32-Korvo-DU1906 have three more bins, `./firmware/DU1906_slave_v1.5.5.D.bin`, `./profiles/profile.bin` and `./tone/audio-esp.bin`. ```bash python $ADF_PATH/esp-idf/components/esptool_py/esptool/esptool.py --chip esp32 \ --port PORT --baud 921600 \ --before default_reset \ --after hard_reset write_flash -z --flash_mode dio --flash_freq 80m --flash_size detect \ -0x510000 ./firmware/DU1906_slave_v1.4.8.E.bin \ -0x790000 ./profiles/profile.bin \ -0x791000 ./tone/audio_tone.bin +0x570000 ./firmware/DU1906_slave_v1.5.5.D.bin \ +0x7d9000 ./tone/audio_tone.bin \ +0x7FF000 ./profiles/profile.bin ``` The firmware downloading flash address refer to above table in jumpstart part. ### Usage -Please refer to jumpstart part. +Please refer to jumpstart part. The device should connect to an AP around first. ### Upgrade function @@ -686,7 +680,7 @@ abort() was called at PC 0x400d2117 on core 0 0x400d2117: esp_modem_sleep_deregister at /home/donglianghao/esp/esp-adf-dlh/esp-idf/components/esp32/phy_init.c:570 -ELF file SHA256: +ELF file SHA256: Backtrace: 0x40092d4b:0x3ffd1840 0x40092fe1:0x3ffd1860 0x400d2117:0x3ffd1880 0x400dfc1c:0x3ffd18b0 0x400dfd0d:0x3ffd18e0 0x400e000a:0x3ffd1910 0x400dbdd2:0x3ffd1940 0x400f77e5:0x3ffd1960 0x40092d4b: rtc_clk_cpu_freq_to_pll_mhz at /home/donglianghao/esp/esp-adf-dlh/esp-idf/components/soc/esp32/rtc_clk.c:517 diff --git a/examples/korvo_du1906/components/audio_player/CMakeLists.txt b/examples/korvo_du1906/components/audio_player/CMakeLists.txt index 3ce75e8..c2e0f3d 100644 --- a/examples/korvo_du1906/components/audio_player/CMakeLists.txt +++ b/examples/korvo_du1906/components/audio_player/CMakeLists.txt @@ -1,5 +1,4 @@ -set(COMPONENT_SRCS "audio_player.c" "audio_player_helper_bt.c" "audio_player_helper_default.c" "audio_player_helper_raw.c" "audio_player_helper_sd.c" "ble_gatts_module.c" "esp_audio_helper.c" "audio_player_manager.c") - +set(COMPONENT_SRCDIRS .) set(COMPONENT_ADD_INCLUDEDIRS . include) diff --git a/examples/korvo_du1906/components/audio_player/audio_player.c b/examples/korvo_du1906/components/audio_player/audio_player.c index f992303..67e2d85 100644 --- a/examples/korvo_du1906/components/audio_player/audio_player.c +++ b/examples/korvo_du1906/components/audio_player/audio_player.c @@ -266,3 +266,8 @@ audio_err_t audio_player_mode_get(audio_player_mode_t *mode) ret = ap_manager_get_mode(mode); return ret; } + +audio_err_t audio_player_clear_audio_info(void) +{ + return ap_manager_clear_audio_info(); +} diff --git a/examples/korvo_du1906/components/audio_player/audio_player_helper_bt.c b/examples/korvo_du1906/components/audio_player/audio_player_helper_bt.c index afc512d..f74cfe3 100644 --- a/examples/korvo_du1906/components/audio_player/audio_player_helper_bt.c +++ b/examples/korvo_du1906/components/audio_player/audio_player_helper_bt.c @@ -69,7 +69,7 @@ audio_err_t ap_helper_a2dp_stop(ap_ops_attr_t *at, ap_ops_para_t *para) audio_element_finish_state(a2dp_stream_hd); audio_element_stop(a2dp_stream_hd); #if CONFIG_BT_ENABLED - ret = periph_bt_stop((esp_periph_handle_t)para->ctx); + ret = periph_bt_pause((esp_periph_handle_t)para->ctx); #endif ret = esp_audio_helper_stop(TERMINATION_TYPE_NOW); return ret; diff --git a/examples/korvo_du1906/components/audio_player/audio_player_helper_raw.c b/examples/korvo_du1906/components/audio_player/audio_player_helper_raw.c index b082ec8..6cfaf36 100644 --- a/examples/korvo_du1906/components/audio_player/audio_player_helper_raw.c +++ b/examples/korvo_du1906/components/audio_player/audio_player_helper_raw.c @@ -33,7 +33,7 @@ static const char *TAG = "RAW_HELPER"; static audio_element_handle_t raw_write_hd; static bool is_feed_done; - +static xQueueHandle g_queue; audio_err_t ap_helper_raw_handle_set(void *handle) { @@ -93,8 +93,9 @@ audio_err_t audio_player_helper_raw_waiting_finished(ap_ops_attr_t *at, ap_ops_p if ((st.media_src == MEDIA_SRC_TYPE_MUSIC_RAW) && ((st.status == AUDIO_PLAYER_STATUS_STOPPED) || (st.status == AUDIO_PLAYER_STATUS_FINISHED) - || (st.status == AUDIO_PLAYER_STATUS_ERROR))) { - if (st.status == AUDIO_PLAYER_STATUS_STOPPED) { + || (st.status == AUDIO_PLAYER_STATUS_ERROR) + || (st.status == AUDIO_PLAYER_STATUS_PAUSED))) { + if (st.status == AUDIO_PLAYER_STATUS_STOPPED || AUDIO_PLAYER_STATUS_PAUSED == st.status) { // Use this status to break mix play ret = ESP_ERR_AUDIO_STOP_BY_USER; } @@ -118,6 +119,19 @@ audio_err_t ap_helper_raw_play_stop(ap_ops_attr_t *at, ap_ops_para_t *para) return ret; } +audio_err_t ap_helper_raw_play_abort_outbf() +{ + audio_element_abort_output_ringbuf(raw_write_hd); + audio_element_finish_state(raw_write_hd); + audio_player_state_t st = {0}; + st.media_src = MEDIA_SRC_TYPE_MUSIC_RAW; + st.status = AUDIO_PLAYER_STATUS_PAUSED; + if (g_queue) { + xQueueSend(g_queue, &st, 0); + } + return ESP_OK; +} + audio_err_t default_raw_player_init(void) { ap_ops_t ops = { @@ -134,6 +148,7 @@ audio_err_t default_raw_player_init(void) // TODO where to free the queue xQueueHandle que = xQueueCreate(3, sizeof(audio_player_state_t)); AUDIO_MEM_CHECK(TAG, que, return ESP_ERR_AUDIO_MEMORY_LACK); + g_queue = que; ap_manager_event_register(que); ops.para.media_src = MEDIA_SRC_TYPE_MUSIC_RAW; ops.para.ctx = que; diff --git a/examples/korvo_du1906/components/audio_player/audio_player_manager.c b/examples/korvo_du1906/components/audio_player/audio_player_manager.c index d8a0f45..29d4e29 100644 --- a/examples/korvo_du1906/components/audio_player/audio_player_manager.c +++ b/examples/korvo_du1906/components/audio_player/audio_player_manager.c @@ -49,7 +49,6 @@ const static int EP_TSK_PLAY_SYNC_STOPPED_BIT = BIT5; const static int EP_TSK_PLAY_SYNC_FINISHED_BIT = BIT6; const static int EP_TSK_PLAY_SYNC_ERROR_BIT = BIT7; - #define AM_ACTION_TIMEOUT (4000) @@ -80,6 +79,7 @@ typedef struct audio_player_impl { audio_player_mode_t mode; audio_player_state_t st; bool prepare_playing; + bool is_abort_playing; } audio_player_impl_t; static const char *TAG = "AUDIO_MANAGER"; @@ -435,21 +435,23 @@ audio_err_t ap_manager_backup_audio_info(void) if (type == ESP_AUDIO_PREFER_MEM) { if ((st.status == AUDIO_STATUS_RUNNING) || (st.status == AUDIO_STATUS_PAUSED)) { - esp_audio_info_get(s_player->audio_handle, &s_player->backup_info); - s_player->is_backup = true; + ret = esp_audio_info_get(s_player->audio_handle, &s_player->backup_info); + if (ret == ESP_OK) { + s_player->is_backup = true; + } ESP_LOGI(TAG, "BACKUP, ret:%x, i:%p, c:%p, f:%p, o:%p,status:%d", ret, s_player->backup_info.in_el, s_player->backup_info.codec_el, s_player->backup_info.filter_el, s_player->backup_info.out_el, s_player->backup_info.st.status); - } + // Call the stop at anytimes ap_ops_t *cur_ops = ap_manager_get_cur_ops(); if (cur_ops == NULL) { ESP_LOGW(TAG, "%s, not found the current operations", __func__); } if (cur_ops && cur_ops->stop) { - ESP_LOGI(TAG, "Call stop in backup, cur media type:%x", cur_ops->para.media_src); + ESP_LOGI(TAG, "Call stop in backup, cur media type:%x, is_abort_playing:%d", cur_ops->para.media_src, s_player->is_abort_playing); xEventGroupClearBits(s_player->sync_state, EP_TSK_PLAY_SYNC_STOPPED_BIT | EP_TSK_PLAY_SYNC_ERROR_BIT | EP_TSK_PLAY_SYNC_FINISHED_BIT); ret = cur_ops->stop(&cur_ops->attr, &cur_ops->para); if (ret == ESP_ERR_AUDIO_NO_ERROR) { @@ -474,7 +476,7 @@ audio_err_t ap_manager_backup_audio_info(void) } } - ESP_LOGI(TAG, "BACKUP Exit"); + ESP_LOGI(TAG, "BACKUP Exit, is_abort_playing:%d", s_player->is_abort_playing); return ret; } @@ -662,7 +664,7 @@ audio_err_t ap_manager_play(const char *url, uint32_t pos, bool blocked, bool au if (tmp == NULL) { mutex_unlock(s_player->lock_handle); s_player->prepare_playing = false; - ESP_LOGW(TAG, "AP_MANAGER_PLAY, The media_src type %x not found", type); + ESP_LOGW(TAG, "AP_MANAGER_PLAY exit, The media_src type %x not found", type); return ESP_ERR_AUDIO_NOT_SUPPORT; } tmp->attr.blocked = blocked; @@ -681,6 +683,13 @@ audio_err_t ap_manager_play(const char *url, uint32_t pos, bool blocked, bool au }); s_player->cur_ops = tmp; ret = esp_audio_media_type_set(s_player->audio_handle, type); + if (s_player->is_abort_playing) { + s_player->prepare_playing = false; + s_player->is_abort_playing = false; + mutex_unlock(s_player->lock_handle); + ESP_LOGE(TAG, "AP_MANAGER_PLAY exit:%d", __LINE__); + return ESP_ERR_AUDIO_FAIL; + } if (blocked == true) { ESP_LOGW(TAG, "AP_MANAGER_PLAY, Blocked playing, %s, type:%x", s_player->cur_ops->para.url, type); xEventGroupClearBits(s_player->sync_state, EP_TSK_PLAY_SYNC_TONE_BIT | EP_TSK_PLAY_SYNC_ERROR_BIT); @@ -711,7 +720,10 @@ audio_err_t ap_manager_play(const char *url, uint32_t pos, bool blocked, bool au } } s_player->prepare_playing = false; - ESP_LOGI(TAG, "AP_MANAGER_PLAY, Exit %s", __func__); + if (s_player->is_abort_playing) { + s_player->is_abort_playing = false; + } + ESP_LOGI(TAG, "AP_MANAGER_PLAY done exit"); return ret; } @@ -724,12 +736,13 @@ audio_err_t ap_manager_stop(void) return ESP_ERR_AUDIO_NOT_FOUND_MEDIA_SRC; } ESP_LOGI(TAG, "Enter:%s", __func__); - mutex_lock(s_player->lock_handle); if (cur_ops->stop) { - ESP_LOGI(TAG, "stop, cur media type:%x", cur_ops->para.media_src); + if (s_player->prepare_playing) { + s_player->is_abort_playing = true; + } + ESP_LOGI(TAG, "stop, cur media type:%x, is_abort_playing:%d", cur_ops->para.media_src, s_player->is_abort_playing); ret = cur_ops->stop(&cur_ops->attr, &cur_ops->para); } - mutex_unlock(s_player->lock_handle); ESP_LOGI(TAG, "Exit:%s", __func__); return ret; } @@ -742,12 +755,13 @@ audio_err_t ap_manager_pause(void) ESP_LOGW(TAG, "%s, not found the current operations", __func__); return ESP_ERR_AUDIO_NOT_FOUND_MEDIA_SRC; } - mutex_lock(s_player->lock_handle); if (cur_ops->pause) { - ESP_LOGI(TAG, "pause, cur media type:%x", cur_ops->para.media_src); + if (s_player->prepare_playing) { + s_player->is_abort_playing = true; + } + ESP_LOGI(TAG, "pause, cur media type:%x, is_abort_playing:%d", cur_ops->para.media_src, s_player->is_abort_playing); ret = cur_ops->pause(&cur_ops->attr, &cur_ops->para); } - mutex_unlock(s_player->lock_handle); return ret; } diff --git a/examples/korvo_du1906/components/audio_player/audio_player_manager.h b/examples/korvo_du1906/components/audio_player/audio_player_manager.h index b15fbc1..12b7e9a 100644 --- a/examples/korvo_du1906/components/audio_player/audio_player_manager.h +++ b/examples/korvo_du1906/components/audio_player/audio_player_manager.h @@ -205,7 +205,7 @@ audio_err_t ap_manager_get_mode(audio_player_mode_t *mode); * - ESP_ERR_AUDIO_NO_ERROR: on success * - ESP_ERR_AUDIO_NOT_READY: no audio player instance */ -audio_err_t ap_manager_event_register(void *que); +audio_err_t ap_manager_event_register(xQueueHandle que); /** * @brief Remove registered queue instance from audio player manager @@ -323,6 +323,15 @@ audio_err_t ap_manager_prev(void); */ audio_err_t ap_manager_seek(int seek_time_sec); +/* + * @brief Clear backup audio info. + * + * @return + * - ESP_ERR_AUDIO_NO_ERROR: on success + * - ESP_ERR_AUDIO_INVALID_PARAMETER: invalid arguments + */ +audio_err_t ap_manager_clear_audio_info(void); + #ifdef __cplusplus } #endif diff --git a/examples/korvo_du1906/components/audio_player/audio_player_pipeline_int_tone.c b/examples/korvo_du1906/components/audio_player/audio_player_pipeline_int_tone.c new file mode 100644 index 0000000..dfb6612 --- /dev/null +++ b/examples/korvo_du1906/components/audio_player/audio_player_pipeline_int_tone.c @@ -0,0 +1,234 @@ +/* + * ESPRESSIF MIT License + * + * Copyright (c) 2020 + * + * Permission is hereby granted for use on all ESPRESSIF SYSTEMS products, in which case, + * it is free of charge, to any person obtaining a copy of this software and associated + * documentation files (the "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the Software is furnished + * to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all copies or + * substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + */ + +#include +#include "esp_log.h" +#include "audio_error.h" +#include "audio_player.h" +#include "audio_mem.h" +#include "audio_player_helper.h" +#include "esp_audio_helper.h" +#include "audio_player_manager.h" +#include "audio_pipeline.h" +#include "tone_stream.h" +#include "mp3_decoder.h" +#include "i2s_stream.h" +#include "filter_resample.h" + +static const char *TAG = "PLAYER_INT_TONE"; + +#define DEFAULT_MAX_ELEMENT_NUM (4) +#define DEFAULT_RINGBUF_SIZE (4 * 1024) + +typedef struct { + SemaphoreHandle_t sem_mutex; + audio_event_iface_handle_t evt; + audio_element_handle_t element[DEFAULT_MAX_ELEMENT_NUM]; + ringbuf_handle_t ringbuffer[DEFAULT_MAX_ELEMENT_NUM - 1]; +} audio_player_int_tone_t; + +audio_element_handle_t app_player_get_i2s_handle(void); + +audio_player_int_tone_t *g_int_tone_handle; +audio_err_t audio_player_int_tone_init(void) +{ + g_int_tone_handle = audio_calloc(1, sizeof(audio_player_int_tone_t)); + + AUDIO_NULL_CHECK(TAG, g_int_tone_handle, return ESP_FAIL); + g_int_tone_handle->sem_mutex = xSemaphoreCreateMutex(); + + tone_stream_cfg_t tone_cfg = TONE_STREAM_CFG_DEFAULT(); + tone_cfg.type = AUDIO_STREAM_READER; + tone_cfg.task_prio = 17; + g_int_tone_handle->element[0] = tone_stream_init(&tone_cfg); + + mp3_decoder_cfg_t mp3_cfg = DEFAULT_MP3_DECODER_CONFIG(); + mp3_cfg.task_prio = 16; + g_int_tone_handle->element[1] = mp3_decoder_init(&mp3_cfg); + + rsp_filter_cfg_t rsp_cfg = DEFAULT_RESAMPLE_FILTER_CONFIG(); + rsp_cfg.dest_rate = 48000; + rsp_cfg.dest_ch = 2; + rsp_cfg.task_prio = 15; + g_int_tone_handle->element[2] = rsp_filter_init(&rsp_cfg); + + i2s_stream_cfg_t i2s_cfg = I2S_STREAM_CFG_DEFAULT(); + i2s_cfg.type = AUDIO_STREAM_WRITER; + i2s_cfg.i2s_config.sample_rate = 48000; + i2s_cfg.uninstall_drv = false; + g_int_tone_handle->element[3] = i2s_stream_init(&i2s_cfg); + + audio_event_iface_cfg_t evt_cfg = AUDIO_EVENT_IFACE_DEFAULT_CFG(); + g_int_tone_handle->evt = audio_event_iface_init(&evt_cfg); + for (int i = 0; i < DEFAULT_MAX_ELEMENT_NUM; i++) { + audio_element_msg_set_listener(g_int_tone_handle->element[i], g_int_tone_handle->evt); + } + for (int i = 0; i < (DEFAULT_MAX_ELEMENT_NUM - 1); i++) { + g_int_tone_handle->ringbuffer[i] = rb_create(DEFAULT_RINGBUF_SIZE, 1); + } + return ESP_OK; +} + +audio_element_err_t i2s_write_idle_cb(audio_element_handle_t self, char *buffer, int len, TickType_t ticks_to_wait, void *context) +{ + vTaskDelay(1 / portTICK_PERIOD_MS); + return ESP_OK; +} + + +audio_err_t audio_player_int_tone_play(char *url) +{ + AUDIO_NULL_CHECK(TAG, g_int_tone_handle, return ESP_FAIL); + AUDIO_NULL_CHECK(TAG, url, return ESP_FAIL); + if (!strstr(url, "mp3") && !strstr(url, "MP3")) { + ESP_LOGE(TAG, "For now, this API only support for MP3 type of tone"); + return ESP_FAIL; + } + + audio_element_handle_t g_player_i2s_write_handle = app_player_get_i2s_handle(); + if (g_player_i2s_write_handle == NULL) { + ESP_LOGE(TAG, "Fail to get i2s handle, maybe the player hasn't been initialized"); + return ESP_FAIL; + } + + ESP_LOGI(TAG, "Start play int tone (add reset state), get handle: %p", g_int_tone_handle); + xSemaphoreTake(g_int_tone_handle->sem_mutex, portMAX_DELAY); + ESP_LOGI(TAG, "Play intterupt tone URL: %s", url); + audio_element_set_uri(g_int_tone_handle->element[0], url); + + audio_element_set_output_ringbuf(g_int_tone_handle->element[0], g_int_tone_handle->ringbuffer[0]); + audio_element_set_input_ringbuf(g_int_tone_handle->element[1], g_int_tone_handle->ringbuffer[0]); + + audio_element_set_output_ringbuf(g_int_tone_handle->element[1], g_int_tone_handle->ringbuffer[1]); + audio_element_set_input_ringbuf(g_int_tone_handle->element[2], g_int_tone_handle->ringbuffer[1]); + + audio_element_set_output_ringbuf(g_int_tone_handle->element[2], g_int_tone_handle->ringbuffer[2]); + audio_element_set_input_ringbuf(g_int_tone_handle->element[3], g_int_tone_handle->ringbuffer[2]); + + audio_element_run(g_int_tone_handle->element[0]); + audio_element_run(g_int_tone_handle->element[1]); + + ESP_LOGI(TAG, "Get state before resume: flash: %d, mp3: %d", audio_element_get_state(g_int_tone_handle->element[0]), audio_element_get_state(g_int_tone_handle->element[1])); + audio_element_reset_state(g_int_tone_handle->element[0]); + audio_element_reset_state(g_int_tone_handle->element[1]); + + audio_element_resume(g_int_tone_handle->element[0], 0, 10 / portTICK_PERIOD_MS); + audio_element_resume(g_int_tone_handle->element[1], 0, 10 / portTICK_PERIOD_MS); + + stream_func backup_func = NULL; + if (g_player_i2s_write_handle) { + ESP_LOGI(TAG, "Set null cb"); + backup_func = audio_element_get_write_cb(g_player_i2s_write_handle); + audio_element_set_write_cb(g_player_i2s_write_handle, i2s_write_idle_cb, NULL); + ESP_LOGI(TAG, "Set done"); + } + + while (1) { + audio_event_iface_msg_t msg = { 0 }; + esp_err_t ret = audio_event_iface_listen(g_int_tone_handle->evt, &msg, portMAX_DELAY); + if (ret != ESP_OK) { + ESP_LOGE(TAG, "[ * ] Event interface error : %d", ret); + continue; + } + + if (msg.source_type == AUDIO_ELEMENT_TYPE_ELEMENT && msg.source == (void *) g_int_tone_handle->element[1] + && msg.cmd == AEL_MSG_CMD_REPORT_MUSIC_INFO) { + audio_element_info_t music_info = {0}; + audio_element_getinfo(g_int_tone_handle->element[1], &music_info); + + ESP_LOGI(TAG, "[ * ] Receive music info from mp3 decoder, sample_rates=%d, bits=%d, ch=%d", + music_info.sample_rates, music_info.bits, music_info.channels); + + rsp_filter_set_src_info(g_int_tone_handle->element[2], music_info.sample_rates, music_info.channels); + + audio_element_run(g_int_tone_handle->element[2]); + audio_element_run(g_int_tone_handle->element[3]); + + ESP_LOGI(TAG, "Get state before resume: rsp: %d, i2s: %d", audio_element_get_state(g_int_tone_handle->element[2]), audio_element_get_state(g_int_tone_handle->element[3])); + + audio_element_reset_state(g_int_tone_handle->element[2]); + audio_element_reset_state(g_int_tone_handle->element[3]); + + audio_element_resume(g_int_tone_handle->element[2], 0, 10 / portTICK_PERIOD_MS); + audio_element_resume(g_int_tone_handle->element[3], 0, 10 / portTICK_PERIOD_MS); + + continue; + } + + if (msg.source_type == AUDIO_ELEMENT_TYPE_ELEMENT && msg.source == (void *) g_int_tone_handle->element[3] + && msg.cmd == AEL_MSG_CMD_REPORT_STATUS + && (((int)msg.data == AEL_STATUS_STATE_STOPPED) || ((int)msg.data == AEL_STATUS_STATE_FINISHED))) { + ESP_LOGW(TAG, "[ * ] Stop event received"); + break; + } + + if (msg.source_type == AUDIO_ELEMENT_TYPE_ELEMENT && msg.cmd == AEL_MSG_CMD_REPORT_STATUS && ((int)msg.data == AEL_STATUS_ERROR_OPEN || + (int)msg.data == AEL_STATUS_ERROR_INPUT || (int)msg.data == AEL_STATUS_ERROR_PROCESS || (int)msg.data == AEL_STATUS_ERROR_OUTPUT || + (int)msg.data == AEL_STATUS_ERROR_CLOSE || (int)msg.data == AEL_STATUS_ERROR_TIMEOUT || (int)msg.data == AEL_STATUS_ERROR_UNKNOWN)) { + ESP_LOGE(TAG, "Error occured when play int tone"); + break; + } + } + + for (int i = 0; i < DEFAULT_MAX_ELEMENT_NUM; i++) { + audio_element_reset_state(g_int_tone_handle->element[i]); + audio_element_reset_input_ringbuf(g_int_tone_handle->element[i]); + audio_element_reset_output_ringbuf(g_int_tone_handle->element[i]); + } + if (backup_func) { + ESP_LOGI(TAG, "Back up cb"); + audio_element_set_write_cb(g_player_i2s_write_handle, backup_func, NULL); + } + xSemaphoreGive(g_int_tone_handle->sem_mutex); + ESP_LOGI(TAG, "Interrupt tone play done"); + return ESP_OK; +} + +audio_err_t audio_player_int_tone_deinit(void) +{ + esp_err_t ret = ESP_OK; + if (g_int_tone_handle) { + for (int i = 0; i < DEFAULT_MAX_ELEMENT_NUM; i++) { + ret |= audio_element_stop(g_int_tone_handle->element[i]); + ret |= audio_element_wait_for_stop(g_int_tone_handle->element[i]); + ret |= audio_element_terminate(g_int_tone_handle->element[i]); + ret |= audio_element_msg_remove_listener(g_int_tone_handle->element[i], g_int_tone_handle->evt); + ret |= audio_element_deinit(g_int_tone_handle->element[i]); + } + + ret |= audio_event_iface_destroy(g_int_tone_handle->evt); + vSemaphoreDelete(g_int_tone_handle->sem_mutex); + + for (int i = 0; i < (DEFAULT_MAX_ELEMENT_NUM - 1); i++) { + ret |= rb_destroy(g_int_tone_handle->ringbuffer[i]); + } + free(g_int_tone_handle); + g_int_tone_handle = NULL; + } + if (ret != ESP_OK) { + ESP_LOGE(TAG, "INT tone player init fail"); + return ESP_FAIL; + } + return ESP_OK; +} diff --git a/examples/korvo_du1906/components/audio_player/audio_player_pipeline_int_tone.h b/examples/korvo_du1906/components/audio_player/audio_player_pipeline_int_tone.h new file mode 100644 index 0000000..858778a --- /dev/null +++ b/examples/korvo_du1906/components/audio_player/audio_player_pipeline_int_tone.h @@ -0,0 +1,67 @@ +/* + * ESPRESSIF MIT License + * + * Copyright (c) 2020 + * + * Permission is hereby granted for use on all ESPRESSIF SYSTEMS products, in which case, + * it is free of charge, to any person obtaining a copy of this software and associated + * documentation files (the "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the Software is furnished + * to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all copies or + * substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + */ + +#ifndef _AUDIO_PLAYER_PIPELINE_INT_TONE_H_ +#define _AUDIO_PLAYER_PIPELINE_INT_TONE_H_ + +#include "audio_def.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/* + * @brief Initialize interrupt tone player + * + * @return + * - ESP_ERR_AUDIO_NO_ERROR : on success + * - ESP_FAIL : other errors + */ +audio_err_t audio_player_int_tone_init(void); + +/* + * @brief Play interrupt tone + * + * @param url Always be url in audio_tone_uri.h + * + * @return + * - ESP_ERR_AUDIO_NO_ERROR : on success + * - ESP_FAIL : other errors + */ +audio_err_t audio_player_int_tone_play(const char *url); + +/* + * @brief Deinitialize interrupt tone player + * + * @return + * - ESP_ERR_AUDIO_NO_ERROR : on success + * - ESP_FAIL : other errors + */ +audio_err_t audio_player_int_tone_deinit(void); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/examples/korvo_du1906/components/audio_player/ble_gatts_module.c b/examples/korvo_du1906/components/audio_player/ble_gatts_module.c index aaef6db..90cdb2b 100644 --- a/examples/korvo_du1906/components/audio_player/ble_gatts_module.c +++ b/examples/korvo_du1906/components/audio_player/ble_gatts_module.c @@ -299,7 +299,7 @@ static void gap_event_handler(esp_gap_ble_cb_event_t event, esp_ble_gap_cb_param break; #endif case ESP_GAP_BLE_ADV_START_COMPLETE_EVT: - /* advertising start complete event to indicate advertising start successful or failed */ + /* advertising start complete event to indicate advertising start successfully or failed */ if (param->adv_start_cmpl.status != ESP_BT_STATUS_SUCCESS) { ESP_LOGE(TAG, "Advertising start failed"); } else { diff --git a/examples/korvo_du1906/components/audio_player/include/audio_player.h b/examples/korvo_du1906/components/audio_player/include/audio_player.h index 1ab33e6..dcbfb4b 100644 --- a/examples/korvo_du1906/components/audio_player/include/audio_player.h +++ b/examples/korvo_du1906/components/audio_player/include/audio_player.h @@ -376,6 +376,14 @@ audio_err_t audio_player_mode_set(audio_player_mode_t mode); */ audio_err_t audio_player_mode_get(audio_player_mode_t *mode); +/* + * @brief Clear backup audio info. + * + * @return + * - ESP_ERR_AUDIO_NO_ERROR: on success + * - ESP_ERR_AUDIO_INVALID_PARAMETER: invalid arguments + */ +audio_err_t audio_player_clear_audio_info(void); #ifdef __cplusplus } diff --git a/examples/korvo_du1906/components/audio_player/test/audio_player_setup_common.c b/examples/korvo_du1906/components/audio_player/test/audio_player_setup_common.c index 451d62b..cee3113 100644 --- a/examples/korvo_du1906/components/audio_player/test/audio_player_setup_common.c +++ b/examples/korvo_du1906/components/audio_player/test/audio_player_setup_common.c @@ -78,6 +78,12 @@ static audio_element_handle_t raw_read_h; static audio_element_handle_t raw_write_h; static bool raw_task_run_flag = 0; +#if __has_include("esp_idf_version.h") +#include "esp_idf_version.h" +#else +#define ESP_IDF_VERSION_VAL(major, minor, patch) 1 +#endif + void setup_wifi() { if (wifi_handle == NULL) { @@ -124,7 +130,7 @@ void setup_sdcard() esp_periph_config_t periph_cfg = DEFAULT_ESP_PERIPH_SET_CONFIG(); set = esp_periph_set_init(&periph_cfg); } - audio_board_sdcard_init(set); + audio_board_sdcard_init(set, SD_MODE_1_LINE); sdcard_handle = esp_periph_set_get_by_id(set, PERIPH_ID_SDCARD); } } @@ -662,7 +668,12 @@ esp_periph_handle_t a2dp_init() esp_periph_start(set, bt_periph); ESP_LOGI(TAG, "Start Bluetooth peripherals"); +#if (ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(4, 0, 0)) + esp_bt_gap_set_scan_mode(ESP_BT_CONNECTABLE, ESP_BT_GENERAL_DISCOVERABLE); +#else esp_bt_gap_set_scan_mode(ESP_BT_SCAN_MODE_CONNECTABLE_DISCOVERABLE); +#endif + return bt_periph; } diff --git a/examples/korvo_du1906/components/bds_light/include/bds_client_command.h b/examples/korvo_du1906/components/bds_light/include/bds_client_command.h index 914642e..c07e39b 100755 --- a/examples/korvo_du1906/components/bds_light/include/bds_client_command.h +++ b/examples/korvo_du1906/components/bds_light/include/bds_client_command.h @@ -1,7 +1,7 @@ /* * Copyright (c) 2020 Baidu.com, Inc. All Rights Reserved * - * Licensed under the Apache License, Version 2.0 (the "License"); + * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with * the License. You may obtain a copy of the License at * @@ -39,12 +39,14 @@ typedef enum { CMD_EVENTUPLOAD_START = 300, CMD_EVENTUPLOAD_CANCEL, CMD_EVENTUPLOAD_DATA, - CMD_EVENTUPLOAD_CONFIG, CMD_LINK_START = 500, CMD_LINK_STOP, CMD_RECORDER_START = 600, CMD_RECORDER_STOP, - CMD_DYNAMIC_CONFIG = 700 + CMD_DYNAMIC_CONFIG = 700, + CMD_TTS_HEADER = 701, + CMD_TTS_START = 800, + CMD_TTS_CANCEL } bdsc_cmd_key_t; /** @@ -71,14 +73,14 @@ typedef struct { * * @param[in] flag Bdsc cmd flag * @param[in] buffer_length Bdsc cmd buffer length - * @param[in] buffer Bdsc cmd buffer + * @param[in] buffer Bdsc cmd buffer * @param[in] sn Bdsc cmd sn * * @return * - bdsc_cmd_data_t handle * - NULL if any errors */ -bdsc_cmd_data_t* bdsc_cmd_data_create(int32_t flag, uint16_t buffer_length, uint8_t *buffer, char* sn); +bdsc_cmd_data_t *bdsc_cmd_data_create(int32_t flag, uint16_t buffer_length, uint8_t *buffer, char *sn); /** * @brief Destory bdsc cmd data diff --git a/examples/korvo_du1906/components/bds_light/include/bds_client_context.h b/examples/korvo_du1906/components/bds_light/include/bds_client_context.h index bfa5df6..e86f080 100755 --- a/examples/korvo_du1906/components/bds_light/include/bds_client_context.h +++ b/examples/korvo_du1906/components/bds_light/include/bds_client_context.h @@ -1,7 +1,7 @@ /* * Copyright (c) 2020 Baidu.com, Inc. All Rights Reserved * - * Licensed under the Apache License, Version 2.0 (the "License"); + * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with * the License. You may obtain a copy of the License at * @@ -22,6 +22,7 @@ extern "C" { #include #include #include +#define BYTE1 __attribute__((packed, aligned(1))) /** * @brief Bdsc Engine error codes @@ -29,11 +30,20 @@ extern "C" { #define ERROR_BDSC_INVALID_RESOURCE -1000 #define ERROR_BDSC_ASR_START_FAILED -2000 #define ERROR_BDSC_ASR_CANCEL_FAILED -2001 +#define ERROR_BDSC_ASR_NET_ERROR -2002 +#define ERROR_BDSC_ASR_HD_SERVER_ERROR -2003 +#define ERROR_BDSC_ASR_TYPE_NOT_RSP -2004 + #define ERROR_BDSC_RECORDER_START_FAILED -3000 #define ERROR_BDSC_RECORDER_READ_FAILED -3001 #define ERROR_BDSC_EVENTUPLOAD_START_FAILED -4000 #define ERROR_BDSC_EVENTUPLOAD_CANCEL_FAILED -4001 #define ERROR_BDSC_EVENTUPLOAD_ENGINE_BUSY -4002 +#define ERROR_BDSC_EVENTUPLOAD_NET_ERROR -4003 +#define ERROR_BDSC_EVENTUPLOAD_HD_SERVER_ERROR -4004 +#define ERROR_BDSC_EVENTUPLOAD_TYPE_NOT_RSP -4005 +#define ERROR_BDSC_PUSH_NET_ERROR -4006 + #define ERROR_BDSC_WAKEUP_START_FAILED -5000 #define ERROR_BDSC_WAKEUP_STOP_FAILED -5001 #define ERROR_BDSC_LINK_START_INVALID -6000 @@ -45,20 +55,42 @@ extern "C" { #define ERROR_BDSC_MIC_SIGNAL_INCONSISTENCY -7003 #define ERROR_BDSC_DSP_RUNTIME_ERROR -7004 +#define ERROR_BDSC_TTS_START_FAILED -8000 +#define ERROR_BDSC_TTS_CANCEL_FAILED -8001 +#define ERROR_BDSC_TTS_NET_ERROR -8002 +#define ERROR_BDSC_TTS_RESPONSE_TIMEOUT -8003 + + #define SN_LENGTH 37 #define KEY_LENGTH 32 #define CUID_LENGTH 37 -#define HOST_LENGTH 64 #define APP_LENGTH 64 +#define WAKEUP_WORDS_LENGTH 32 +#define URI_LENGTH 128 +#define SCHEME_LENGTH 5 +#define HOST_LENGTH 64 +#define PORT_LENGTH 5 +#define PATH_LENGTH 64 +#define PARAM_LENGTH 64 + #define FLAG_DEFAULT 0 #define FLAG_TAIL 1 -#define KEY_NQE_MODE "nqe_mode" -#define KEY_LC_HOST "lc_host" #define KEY_ASR_MODE_STATE "asr_mode_state" #define KEY_WS_HEAD_HOST "head_host" #define KEY_SELF_WAKEUP_RESTRAIN "self_wakeup_restrain" +#define KEY_IDX "idx" +#define KEY_TTS_HOLD_WAKE "tts_hold_wake" +#define KEY_TTS_KEY_SP "tts_key_sp" +#define KEY_SN "sn" +#define KEY_PER "per" +#define KEY_TTS_TOTAL_TIME "tts_total_time" +#define KEY_SPK "spk" +#define KEY_SADDR "saddr" +#define KEY_LENGTH_STR "length" +#define KEY_NIGHT_MODE "night_mode" +#define KEY_DBG_FIRST_WP "dbg_first_wp" #define KEY_HOST "host" #define KEY_PORT "port" @@ -67,18 +99,30 @@ extern "C" { #define KEY_KEY "key" #define KEY_ENGINE_URI "engine_uri" #define KEY_NET_LOG_LEVEL "qnet_log_level" +#define KEY_WAKEUP_WORDS "wakeup_words" +#define KEY_PDT "pdt" +#define KEY_APPID "appid" +#define KEY_APPKEY "appkey" +#define KEY_SN "sn" +#define KEY_TEX "tex" +#define KEY_SPD "spd" +#define KEY_PIT "pit" +#define KEY_VOL "vol" +#define KEY_PER "per" +#define KEY_AUE "aue" +#define KEY_RATE "rate" +#define KEY_XML "xml" +#define KEY_PATH "path" +#define KEY_LAN "lan" +#define KEY_MODE "mode" +#define KEY_PAM "pam" -#define LENGTH_SN (SN_LENGTH) -#define LENGTH_HOST 64 -#define LENGTH_CUID 64 -#define LENGTH_KEY 128 -#define LENGTH_URI 128 /** * @brief Bdsc Audio data type */ typedef struct { - char sn[LENGTH_SN]; + char sn[SN_LENGTH]; int32_t flag; uint16_t buffer_length; uint16_t real_length; @@ -101,6 +145,10 @@ typedef struct { } bds_client_context_t; +typedef struct bds_sn { + char sn[SN_LENGTH]; +} BYTE1 bds_sn_t; + /** * @brief Create bdsc audio data type * @@ -112,7 +160,7 @@ typedef struct { * - `bdsc_audio_t` * - NULL if any errors */ -bdsc_audio_t* bdsc_audio_create(int32_t flag, uint16_t buffer_length, const uint8_t *buffer); +bdsc_audio_t *bdsc_audio_create(char *sn, int32_t flag, uint16_t buffer_length, const uint8_t *buffer); /** * @brief Destroy bdsc audio data type @@ -134,7 +182,7 @@ void bdsc_audio_destroy(bdsc_audio_t *audio); * - `bdsc_error_t` * - NULL if any errors */ -bdsc_error_t* bdsc_error_create(int32_t code, uint16_t info_length, char *info); +bdsc_error_t *bdsc_error_create(int32_t code, uint16_t info_length, char *info); /** * @brief Destroy bdsc error data type diff --git a/examples/korvo_du1906/components/bds_light/include/bds_client_event.h b/examples/korvo_du1906/components/bds_light/include/bds_client_event.h index acf05d7..f79f941 100755 --- a/examples/korvo_du1906/components/bds_light/include/bds_client_event.h +++ b/examples/korvo_du1906/components/bds_light/include/bds_client_event.h @@ -1,7 +1,7 @@ /* * Copyright (c) 2020 Baidu.com, Inc. All Rights Reserved * - * Licensed under the Apache License, Version 2.0 (the "License"); + * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with * the License. You may obtain a copy of the License at * @@ -34,7 +34,6 @@ typedef enum { EVENT_ASR_END, EVENT_ASR_CANCEL, EVENT_ASR_ERROR, - EVENT_ASR_GENERAL_INFO, EVENT_WAKEUP_TRIGGER = 2000, EVENT_WAKEUP_ERROR, EVENT_EVENTUPLOAD_BEGIN = 3000, @@ -53,7 +52,14 @@ typedef enum { EVENT_SDK_START_COMPLETED = 7000, EVENT_RECV_MQTT_PUSH_URL, EVENT_RECV_A2DP_START_PLAY, - EVENT_DSP_FATAL_ERROR = 8000 + EVENT_DSP_FATAL_ERROR = 8000, + EVENT_DSP_LOAD_FAILED = 8001, + EVENT_TTS_BEGIN = 9000, + EVENT_TTS_END, + EVENT_TTS_RESULT, + EVENT_TTS_CANCEL, + EVENT_TTS_ERROR, + } bdsc_event_key_t; /** @@ -100,6 +106,8 @@ typedef struct { */ typedef struct { int status; + uint16_t dci_length; + uint8_t dci_buffer[]; } bdsc_event_wakeup_t; /** @@ -114,7 +122,7 @@ typedef struct { * - `bdsc_event_error_t` * - NULL if any errors */ -bdsc_event_error_t* bdsc_event_error_create(char *sn, +bdsc_event_error_t *bdsc_event_error_create(char *sn, int32_t code, uint16_t info_length, char *info); /** @@ -138,7 +146,7 @@ void bdsc_event_error_destroy(bdsc_event_error_t *error); * - `bdsc_event_data_t` * - NULL if any errors */ -bdsc_event_data_t* bdsc_event_data_create(char *sn, +bdsc_event_data_t *bdsc_event_data_create(char *sn, int16_t idx, uint16_t buffer_length, uint8_t *buffer); /** @@ -150,6 +158,10 @@ bdsc_event_data_t* bdsc_event_data_create(char *sn, */ void bdsc_event_data_destroy(bdsc_event_data_t *data); +bdsc_event_wakeup_t *bdsc_wakeup_data_create(int status, uint16_t buffer_length, uint8_t *buffer); +void bdsc_wakeup_data_destroy(bdsc_event_wakeup_t *data); + + /** * @brief Deep copy bdsc event handle * diff --git a/examples/korvo_du1906/components/bds_light/include/bds_client_params.h b/examples/korvo_du1906/components/bds_light/include/bds_client_params.h index c863368..b6b1819 100755 --- a/examples/korvo_du1906/components/bds_light/include/bds_client_params.h +++ b/examples/korvo_du1906/components/bds_light/include/bds_client_params.h @@ -1,7 +1,7 @@ /* * Copyright (c) 2020 Baidu.com, Inc. All Rights Reserved * - * Licensed under the Apache License, Version 2.0 (the "License"); + * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with * the License. You may obtain a copy of the License at * @@ -59,6 +59,12 @@ typedef enum LAUNCH_MODE { LAUNCH_CHECK_DSP = 0x01 } LAUNCH_MODE_T; +typedef enum WAKEUP_NUM { + WP_NUM_DEFAULT = 0x00, + WP_NUM_ONE = 0x01, + WP_NUM_TWO = 0x02 +} WAKEUP_NUM; + /** * @brief bdsc engine params type */ @@ -76,14 +82,14 @@ typedef struct { } bdsc_engine_params_t; /** - * @brief bds client params type + * @brief bds client params type */ typedef struct { bdsc_engine_params_t *engine_params; } bds_client_params_t; /** - * @brief bdsc asr params type + * @brief bdsc asr params type */ typedef struct { char sn[SN_LENGTH]; @@ -93,12 +99,13 @@ typedef struct { uint16_t audio_rate; char cuid[CUID_LENGTH]; int wakeup_status; + int voice_print; uint16_t pam_len; char pam[]; } bdsc_asr_params_t; /** - * @brief bdsc eventupload params type + * @brief bdsc eventupload params type */ typedef struct { char sn[SN_LENGTH]; @@ -109,6 +116,10 @@ typedef struct { char pam[]; } bdsc_eventupload_params_t; +typedef struct { + int wakeup_num; +} bdsc_wp_params_t; + /** * @brief create bdsc asr params * @@ -128,9 +139,14 @@ typedef struct { */ bdsc_asr_params_t *bdsc_asr_params_create(char *sn, uint32_t primary_pid, uint32_t assist_pid, char *key, - uint16_t audio_rate, char *cuid, int backtrack_time, + uint16_t audio_rate, char *cuid, int wakeup_status, uint16_t pam_len, char *pam); +bdsc_asr_params_t *bdsc_asr_params_create_ext(char *sn, + uint32_t primary_pid, uint32_t assist_pid, char *key, + uint16_t audio_rate, char *cuid, int wakeup_status, + uint16_t pam_len, char *pam, int voice_print); + /** * @brief destroy bdsc asr params * @@ -155,7 +171,7 @@ void bdsc_asr_params_destroy(bdsc_asr_params_t *params); * - NULL if any errors */ bdsc_eventupload_params_t *bdsc_event_params_create(char *sn, - uint32_t pid, char *key, char *cuid, uint16_t pam_len, char *pam); + uint32_t pid, char *key, char *cuid, uint16_t pam_len, char *pam); /** * @brief destroy bdsc event params * @@ -184,9 +200,9 @@ void bdsc_event_params_destroy(bdsc_eventupload_params_t *params); * - `bdsc_engine_params_t` * - NULL if any errors */ -bdsc_engine_params_t* bdsc_engine_params_create(char *sn, uint32_t pid, char *host, int port, uint8_t protocol, +bdsc_engine_params_t *bdsc_engine_params_create(char *sn, uint32_t pid, char *host, int port, uint8_t protocol, char *cuid, char *app, LAUNCH_MODE_T launch_mode, uint16_t pam_len, char *pam); - + /** * @brief destory bdsc engine params * diff --git a/examples/korvo_du1906/components/bds_light/include/bds_common_utility.h b/examples/korvo_du1906/components/bds_light/include/bds_common_utility.h index 4d21298..026fdc9 100755 --- a/examples/korvo_du1906/components/bds_light/include/bds_common_utility.h +++ b/examples/korvo_du1906/components/bds_light/include/bds_common_utility.h @@ -14,7 +14,7 @@ #ifndef LIGHT_BDSPEECH_COMMON_UTILITY_H #define LIGHT_BDSPEECH_COMMON_UTILITY_H - + #ifdef __cplusplus extern "C" { #endif @@ -35,7 +35,7 @@ unsigned long long bds_get_current_time(); * @return * time stamp (ms) */ -long bds_get_current_time_ms(); +uint64_t bds_get_current_time_ms(); /** * @brief Generate uuid @@ -73,6 +73,8 @@ int bds_get_sdk_version(char* out_version, int len); */ int bds_create_sign(char* psrc, int slen, uint32_t *sign); +uint32_t bds_rand32(); + /** * @brief Set sdk log level * diff --git a/examples/korvo_du1906/components/bds_light/lib/libbds_light_sdk.a b/examples/korvo_du1906/components/bds_light/lib/libbds_light_sdk.a index c19e9fb..93d6804 100644 Binary files a/examples/korvo_du1906/components/bds_light/lib/libbds_light_sdk.a and b/examples/korvo_du1906/components/bds_light/lib/libbds_light_sdk.a differ diff --git a/examples/korvo_du1906/components/bds_private/lib/libbds_private_info.a b/examples/korvo_du1906/components/bds_private/lib/libbds_private_info.a index f20d689..8d30af0 100644 Binary files a/examples/korvo_du1906/components/bds_private/lib/libbds_private_info.a and b/examples/korvo_du1906/components/bds_private/lib/libbds_private_info.a differ diff --git a/examples/korvo_du1906/components/bdsc_engine/CMakeLists.txt b/examples/korvo_du1906/components/bdsc_engine/CMakeLists.txt index 3ec6159..a63cbf6 100644 --- a/examples/korvo_du1906/components/bdsc_engine/CMakeLists.txt +++ b/examples/korvo_du1906/components/bdsc_engine/CMakeLists.txt @@ -1,7 +1,11 @@ set(COMPONENT_ADD_INCLUDEDIRS include) +set(COMPONENT_REQUIRES mqtt json) + register_component() target_link_libraries(${COMPONENT_TARGET} INTERFACE "-L ${CMAKE_CURRENT_SOURCE_DIR}/lib") -target_link_libraries(${COMPONENT_TARGET} INTERFACE bdsc_engine) +add_prebuilt_library(bdsc_engine "${CMAKE_CURRENT_SOURCE_DIR}/lib/libbdsc_engine.a" PRIV_REQUIRES json mqtt audio_flash_tone) + +target_link_libraries(${COMPONENT_TARGET} INTERFACE bdsc_engine) diff --git a/examples/korvo_du1906/components/bdsc_engine/include/bdsc_cmd.h b/examples/korvo_du1906/components/bdsc_engine/include/bdsc_cmd.h index fdb46c0..bf5326c 100644 --- a/examples/korvo_du1906/components/bdsc_engine/include/bdsc_cmd.h +++ b/examples/korvo_du1906/components/bdsc_engine/include/bdsc_cmd.h @@ -77,7 +77,7 @@ void bdsc_link_stop(); */ void bdsc_dynamic_config(char *config); -void qnet_connect_config(); +void ws_connect_config(); #ifdef __cplusplus } diff --git a/examples/korvo_du1906/components/bdsc_engine/include/bdsc_engine.h b/examples/korvo_du1906/components/bdsc_engine/include/bdsc_engine.h index ce7c9da..46ca8bc 100644 --- a/examples/korvo_du1906/components/bdsc_engine/include/bdsc_engine.h +++ b/examples/korvo_du1906/components/bdsc_engine/include/bdsc_engine.h @@ -1,7 +1,7 @@ /* * Copyright (c) 2020 Baidu.com, Inc. All Rights Reserved * - * Licensed under the Apache License, Version 2.0 (the "License"); + * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with * the License. You may obtain a copy of the License at * @@ -24,7 +24,6 @@ #include "bdsc_profile.h" #include "auth_task.h" #include "bdsc_event_dispatcher.h" -#include "mixed_play_task.h" #include "mqtt_client.h" #include "cJSON.h" @@ -84,16 +83,6 @@ typedef enum { BDSC_TRANSPORT_OVER_WSS, /*!< Transport over wss */ } bdsc_engine_transport_t; -/** - * @brief Bdsc Engine event data type - */ -typedef struct { - char sn[SN_LENGTH]; - int16_t idx; - uint16_t buffer_length; - uint8_t *buffer; -} bdsc_engine_event_data_t; - typedef esp_err_t (*bdsc_engine_event_handle_cb)(bdsc_engine_event_t *evt); /** @@ -107,7 +96,7 @@ typedef struct { int auth_port; /*!< BDSC auth port */ bdsc_engine_event_handle_cb event_handler; /*!< BDSC Event Handle */ bdsc_engine_transport_t transport_type; /*!< BDSC transport type, see `bdsc_engine_transport_t` */ - int bdsc_methods; /*!< BDSC configuable methods*/ + int bdsc_methods; /*!< BDSC configuable methods*/ } bdsc_engine_config_t; typedef enum { @@ -133,26 +122,8 @@ struct bdsc_engine { bdsc_auth_cb g_auth_cb; QueueHandle_t g_engine_queue; SemaphoreHandle_t enqueue_mutex; - TimerHandle_t asr_timer; bdsc_engine_internal_st g_asr_tts_state; - - bool asr_timeout_once; - bool has_connected; - char *g_movie_url; - - QueueHandle_t g_mixed_wait_queue; - QueueHandle_t g_mixed_url_queue; - - char *g_mixed_play_url; - esp_http_client_handle_t g_mixed_client; - enum { - MIXED_PLAYER_ST_IDLE, - MIXED_PLAYER_ST_TTS_PLAYING, - MIXED_PLAYER_ST_TTS_PLAYED, - MIXED_PLAYER_ST_URL_PLAYING, - MIXED_PLAYER_ST_URL_PLAYED, - } mixed_st; int g_one_request_over; esp_mqtt_client_handle_t g_mqtt_client; @@ -166,7 +137,7 @@ struct bdsc_engine { cJSON *user_app_dataJ; char *asrnlp_ttsurl; - + bool g_has_greeted; char *current_asr_words; char *asr_block_words; @@ -174,8 +145,8 @@ struct bdsc_engine { int ota_trans_num; bool skip_tts_playing_once; bool in_ota_process_flag; - - void *userData; + bool dsp_detect_error; + void *userData; }; /** @@ -244,16 +215,6 @@ esp_err_t bdsc_engine_http_play(); */ void bdsc_engine_net_connected_cb(); -/** - * @brief Set Bdsc Engine net connected flag - * - * @param[in] connected flag to set - * - * @note This func MUST be called manually to notify Bdsc Engine connection status - * - * @return - */ -void bdsc_engine_set_connect_flag(bool connected); int bdsc_engine_get_internal_state(bdsc_engine_handle_t client); @@ -283,6 +244,9 @@ int bdsc_engine_channel_data_upload(uint8_t *upload_data, size_t upload_data_len */ esp_err_t bdsc_engine_deinit(bdsc_engine_handle_t client); +void start_sdk(); +void stop_sdk(); + #ifdef __cplusplus } #endif diff --git a/examples/korvo_du1906/components/bdsc_engine/include/bdsc_event_dispatcher.h b/examples/korvo_du1906/components/bdsc_engine/include/bdsc_event_dispatcher.h index 297daff..c53c5c0 100644 --- a/examples/korvo_du1906/components/bdsc_engine/include/bdsc_event_dispatcher.h +++ b/examples/korvo_du1906/components/bdsc_engine/include/bdsc_event_dispatcher.h @@ -67,6 +67,20 @@ void event_engine_elem_EnQueque(int event, uint8_t *buffer, size_t len); */ void event_engine_elem_FlushQueque(); +/** + * @brief Get flag judge whether the player need be resume + * @return + * - true: need to be resumed + * - false: no need to be resumed + */ +bool bdsc_get_pre_player_flag(); + +/** + * @brief Set flag judge whether the player need be resume + * @param[in] state Set flag + */ +void bdsc_set_pre_player_flag(bool flag); + #ifdef __cplusplus } #endif diff --git a/examples/korvo_du1906/components/bdsc_engine/include/bdsc_json.h b/examples/korvo_du1906/components/bdsc_engine/include/bdsc_json.h index 1562b05..d198f90 100755 --- a/examples/korvo_du1906/components/bdsc_engine/include/bdsc_json.h +++ b/examples/korvo_du1906/components/bdsc_engine/include/bdsc_json.h @@ -21,11 +21,11 @@ BdsJson* BdsJsonParse(const char* jStr); int BdsJsonPut( BdsJson* jObj); BdsJson* BdsJsonNext( BdsJson* jObj); BdsJson* BdsJsonObjectGet( BdsJson* jObj, const char* key); -const char* BdsJsonStringGet( BdsJson* jObj); +char* BdsJsonStringGet( BdsJson* jObj); int BdsJsonIntGet( BdsJson* jObj, int* value); int BdsJsonDoubleGet( BdsJson* jObj, double* value); int BdsJsonBoolGet( BdsJson* jObj, bool* bl); -const char* BdsJsonObjectGetString( BdsJson* jObj, const char* key); +char* BdsJsonObjectGetString( BdsJson* jObj, const char* key); int BdsJsonObjectGetInt( BdsJson* jObj, const char* key, int* value); int BdsJsonObjectGetDouble( BdsJson* jObj, const char* key, double* value); int BdsJsonObjectGetBool( BdsJson* jObj, const char* key, bool* value); diff --git a/examples/korvo_du1906/components/bdsc_engine/include/bdsc_profile.h b/examples/korvo_du1906/components/bdsc_engine/include/bdsc_profile.h index 5d1c8d8..e19ebc5 100644 --- a/examples/korvo_du1906/components/bdsc_engine/include/bdsc_profile.h +++ b/examples/korvo_du1906/components/bdsc_engine/include/bdsc_profile.h @@ -1,7 +1,7 @@ /* * Copyright (c) 2020 Baidu.com, Inc. All Rights Reserved * - * Licensed under the Apache License, Version 2.0 (the "License"); + * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with * the License. You may obtain a copy of the License at * @@ -25,7 +25,7 @@ extern "C" { #include "esp_system.h" #include "esp_spi_flash.h" #include "freertos/event_groups.h" -#include "esp_event_loop.h" +// #include "esp_event_loop.h" #include "esp_wifi.h" #include "nvs_flash.h" #include diff --git a/examples/korvo_du1906/components/bdsc_engine/include/bdsc_tools.h b/examples/korvo_du1906/components/bdsc_engine/include/bdsc_tools.h index 5a879bb..5b713b8 100644 --- a/examples/korvo_du1906/components/bdsc_engine/include/bdsc_tools.h +++ b/examples/korvo_du1906/components/bdsc_engine/include/bdsc_tools.h @@ -81,6 +81,11 @@ char* bdsc_strnstr(const char *buffer, const char *token, size_t n); */ esp_err_t bdsc_get_sn(char* outSn, size_t* length); +/** + * @brief Generate md5 checksum for buffer + */ +const char* generate_md5_checksum_needfree(uint8_t *buf, size_t buf_len); + #ifdef __cplusplus } #endif diff --git a/examples/korvo_du1906/components/bdsc_engine/include/generate_pam.h b/examples/korvo_du1906/components/bdsc_engine/include/generate_pam.h index 45a71f0..d95055e 100644 --- a/examples/korvo_du1906/components/bdsc_engine/include/generate_pam.h +++ b/examples/korvo_du1906/components/bdsc_engine/include/generate_pam.h @@ -42,7 +42,7 @@ char* generate_dcs_pam_needfree(); * - 0 : on success * - -1: fail */ -int generate_asr_thirdparty_pam(char* pam_prama, size_t max_len); +int generate_asr_thirdparty_pam(char* pam_prama, size_t max_len, int option); /** * @brief Generate auth parameters diff --git a/examples/korvo_du1906/components/bdsc_engine/lib/libbdsc_engine.a b/examples/korvo_du1906/components/bdsc_engine/lib/libbdsc_engine.a index 1b91970..00fb1f6 100644 Binary files a/examples/korvo_du1906/components/bdsc_engine/lib/libbdsc_engine.a and b/examples/korvo_du1906/components/bdsc_engine/lib/libbdsc_engine.a differ diff --git a/examples/korvo_du1906/docs/Du1906_cloud_access_guide.md b/examples/korvo_du1906/docs/Du1906_cloud_access_guide.md new file mode 100644 index 0000000..442d2f5 --- /dev/null +++ b/examples/korvo_du1906/docs/Du1906_cloud_access_guide.md @@ -0,0 +1,300 @@ +# ESP32-Korvo-DU1906 使用指南 + +使用 ESP32-KORVO-DU1906 开发版前,需要先在百度“度家 AIOT 语音平台”进行云端配置——购买相应服务获得权限,并获取调用语音服务必须的参数,具体操作详见第一章节。第一章配置指南完成后,参考第二章进行烧录和使用。 + +## 一、云端配置指南 + +> 度家 AIOT 语音平台提供端云一体的产品方案,通过阅读本章节,您可完成语音交互前必须的准备工作,进而通过设备直连的方式调用线上语音服务,本章包含以下三个部分:使用准备、购买服务、配置设备管理功能。 + +1. 使用准备:注册百度智能云账号,并完成实名认证。 +2. 购买服务:若您已购买 ESP32-Korvo-DU1906 开发版,需前往[度家AIOT语音平台](https://cloud.baidu.com/product/shc.html)点击“立即使用", 进入控制台的“购买服务"页面购买线上服务。 +3. 配置设备管理功能:完成创建厂商、创建产品及添加设备等基本操作,获取后续服务所需的参数。 + + +### 1. 使用准备 + +1. 在购买服务、使用百度智能云度家 AIOT 语音平台前,您需要拥有一个百度智能云账号并完成实名认证,具体操作如下: + - 注册并登录百度智能云平台,请参考[注册](https://cloud.baidu.com/doc/UserGuide/s/ejwvy3fo2#%E6%B3%A8%E5%86%8C%E7%99%BE%E5%BA%A6%E8%B4%A6%E5%8F%B7)和[登录](https://cloud.baidu.com/doc/UserGuide/s/jjwvy3dk5)教程。 + - 实名认证操作细节请参考[实名认证](https://cloud.baidu.com/doc/UserGuide/s/8jwvy3c96),实名认证后才可申请开通权限、购买度家 AIOT 语音平台提供的服务。 + +### 2. 购买服务 + +1. 前往[度家AIOT语音平台](https://cloud.baidu.com/product/shc.html)点击**“立即使用"**, 进入控制台。 + +2. 点击菜单栏的“购买服务"进入下方页面,您可在该页面查看已购买的**“AI语音服务次数包”**及**“设备管理额度”**,尚未购买时显示暂无数据。 + + playment + +3. 点击“+购买服务”,进入下图的购买信息配置页面。您可根据需求选择不同规格的设备管理服务,语音识别、语义解析及语音合成次数包。设备管理额度及三种次数包的定价计费信息请参考[计费策略](https://cloud.baidu.com/doc/SHC/s/Ok74ghlfz)。 + + ![PURCHASEINFO.png](https://bce.bdstatic.com/doc/bce-doc/SHC/PURCHASEINFO_2be2650.png) + + > 注意:
+ > 设备管理额度一经购买,永久有效;若您的目的为试用开发板,在设备管理服务栏输入最小购买额度“1”即可。
+ > 如何购买语音识别、语义解析、语音合成取决于您调用服务的需求,目前支持三种组合购买方式:
+ > 1)全链路:ASR+UNIT+TTS
+ > 2) 语音识别+语义解析:ASR+UNIT
+ > 3)仅语音识别:ASR
+ > 您需记住此时购买的服务,在后续文档**“修改main.c文件中的methods”**部分中您需要修改相应代码。 + +4. 配置购买信息后,控制台展示相应配置费用。确认购买信息配置无误后,点击下图**“去结算”**进入订单确认页。 + + ![PURCHASEPRICE.png](https://bce.bdstatic.com/doc/bce-doc/SHC/PURCHASEPRICE_87b3a05.png) + +5. 若您有百度智能云代金券,可在订单确认页使用代金券结算抵扣相应费用。若无代金券,确认订单信息无误后,直接点击“去支付”进入支付页面。 + + ![ORDERINFO.png](https://bce.bdstatic.com/doc/bce-doc/SHC/ORDERINFO_60cd75f.png) + +6. 您可以使用银行卡、支付宝、百度账户余额等方式完成支付操作。 + + ![PAYMENT.png](https://bce.bdstatic.com/doc/bce-doc/SHC/PAYMENT_cbba48c.png) + + > 注意:购买服务时需确认您的百度智能云账户余额(不包括代金券)大于或等于 0 元,若百度智能云账户欠费,将无法购买服务。关于百度智能云账户充值,请参见[如何充值](https://console.bce.baidu.com/billing/?_=1567132907317#/renew/list)。 + +7. 支付成功后,您可回到度家AIOT语音平台控制台的“购买服务"页面可查看到已购买的资源及使用情况。 + + ![PURCHASEREVIEW1.png](https://bce.bdstatic.com/doc/bce-doc/SHC/PURCHASEREVIEW1_bdbae4c.png) + +### 3. 配置设备管理功能 + +设备管理页面为厂商提供了设备身份注册、修改等一系列管理功能,帮助厂商为不同产品下的每一个设备创建身份 ID,并将该身份 ID 用于设备鉴权及语音服务调用。您需通过创建厂商、创建产品、导入设备三步操作分别创建设备的对应的 fc、pk 以及 ak、sk 码,参数含义介绍及设置 ak 码时的规则请参考[核心概念](https://cloud.baidu.com/doc/SHC/s/Gk7bh9rxo)。 + +> 注意:
+> 请保护好创建后生成的 fc,pk,ak,sk,泄露该信息给第三方可能导致设备异常调用等问题。 + +1. 登陆设备管理页面 + - 在[度家AIOT语音平台](https://cloud.baidu.com/product/shc.html)点击“设备管理"侧边栏, 进入设备管理页面的。 + + ![DEVMAG01.png](https://bce.bdstatic.com/doc/bce-doc/SHC/DEVMAG01_0994615.png) + +2. 创建厂商 + - 进入**“设备管理"**页面后,点击菜单下的**“厂商"**栏进入厂商列表页。点击**“创建厂商"**,输入厂商名称和描述,完成厂商创建,获得系统生成的 fc 码。 + + ![CREATE FAC01.png](https://bce.bdstatic.com/doc/bce-doc/SHC/CREATE%20FAC01_74b98ca.png) + + - 厂商列表页支持编辑和删除厂商。 + + ![CREATE FAC02.png](https://bce.bdstatic.com/doc/bce-doc/SHC/CREATE%20FAC02_68cfb76.png) + +3. 创建产品 + - 在厂商列表页点击**“管理产品”**。点击**“创建产品"**,选择厂商、和产品类型,同时输入产品型号及产品描述即可创建产品,获得系统生成的pk码。 + + ![CREATE PRODUCT 01.png](https://bce.bdstatic.com/doc/bce-doc/SHC/CREATE%20PRODUCT%2001_53938da.png) + + - 产品列表页支持编辑和删除产品。 + + ![CREATE PRODUCT 02.png](https://bce.bdstatic.com/doc/bce-doc/SHC/CREATE%20PRODUCT%2002_8c23742.png) + +4. 添加设备 + - 在产品列表页点击**“管理设备”**。可通过单个添加或导入 CSV 文件批量添加的方式导入设备。 + + ![CREATE DEVICE 01.png](https://bce.bdstatic.com/doc/bce-doc/SHC/CREATE%20DEVICE%2001_bea415a.png) + + >注意:测试开发版时建议通过添加单个设备的方式,添加所需数量的设备即可,同一个产品下的设备 ak 不可重复。 + + - 设备列表页支持删除设备,以及禁用、启用设备,同时可通过状态栏筛选设备状态。 + + ![CREATE DEVICE 02.png](https://bce.bdstatic.com/doc/bce-doc/SHC/CREATE%20DEVICE%2002_7beab8f.png) + + >注意:
+ >若厂商、产品下创建有设备则无法删除,需先删除设备后才可删除产品,进而删除厂商。
+ >后续完成第二章节操作,且调用设备成功后,度家控制台上的设备会显示“已激活”,若激活会有延时,可等待几分钟后刷新。
+ +
+ +## 二、烧录和使用 +### 1. 软件准备 + +1. 修改 main.c 文件中的 methods + - 在烧录固件前,您需要修改定义服务权限的相关代码,结合您在“一、云端配置指南” 中“2.购买服务”所选购的具体服务,您需按照如下逻辑修改 main.c 文件中的代码(下图红圈部分): + + playment + + - 若您购买了全链路的服务,该部分无需修改,保留为:BDSC\_METHODS\_DEFAULT + + - 若您仅购买了语音识别+语义解析,该部分修改为:BDSC\_METHODS\_ASR | BDSC\_METHODS\_NLP + + - 若您仅购买了语音识别,该部分修改为:BDSC\_METHODS\_ASR + + >注意: 购买的服务和此处代码需匹配一致才能正常调用,否则服务将鉴权失败。 + +2. 接入许可(Profile)准备 + - 编辑工程目录下的 profile 文件,将度家 AIOT 平台配置生成的 fc、pk、ak 和 sk 的字段,以字符串的形式填入文本文件 profile.bin 中(文件名称可以更改)。 +示例: +{"fc":"xxxxxx","pk":"xxxxxxxx","ak":"xxxxxxxxxxxx","sk":"xxxxxxxxxxxx","cuid":"xxxxxxxx"} + + > 注意: 工程软件务必烧录 Profile,否则会无法连接百度云进行语音交互。 + +3. 工程软件准备 + - 根据[ADF-Getting](https://docs.espressif.com/projects/esp-adf/en/latest/get-started/index.html)搭建软件开发环境,并按步骤编译 Korvo-DU1906 方案工程。 + +### 2. 工具准备 + +- ESP32-Korvo-DU1906 开发板一块 +- PC(建议使用 Windows 环境,并且安装有串口打印工具) +- 2 条 Micro-USB 线,其中一条作为供电线 + - 供电建议使用不小于 5V/2A +- 1 个 2.0mm 端子扬声器 + - 规格建议使用 4 欧 3W 或 4欧 5W + +### 3. 软件烧录 + +以 DU1906-Korvo-DU1906 开发板为例,烧录时需要让 ESP32 进入下载模式,长按 Boot 键(4S),再按 RST 键,一起松开即可进入下载模式,如果此时接入串口查看工具会打印 “ Waiting for download "。 + +**指令烧录** + +利用 ADF/IDF 中的 python 脚本,进行软件烧录,指令见如下(仅做示例,具体烧录地址依据 Make 的结果),烧录成功后按键 RST 重启运行。 + +```` +sudo python \ +/home/Admin/Baidu/baidu_dul1906/dul1906/esp-adf/esp-idf/components/esptool_py/esptool/esptool.py \ +--chip esp32 --port /dev/ttyUSB0 --baud 921600 \ +--before default_reset --after hard_reset write_flash \ +-z --flash_mode dio --flash_freq 80m --flash_size detect \ +0xd000 /home/donglianghao/Baidu/baidu_dul1906/dul1906/build/ota_data_initial.bin \ +0x1000 /home/donglianghao/Baidu/baidu_dul1906/dul1906/build/bootloader/bootloader.bin \ +0x10000 /home/donglianghao/Baidu/baidu_dul1906/dul1906/build/app.bin \ +0x8000 /home/donglianghao/Baidu/baidu_dul1906/dul1906/build/partitions.bin \ +0x7FF000 ./profiles/profile.bin \ +0x7d9000 ./tone/audio_tone.bin \ +0x570000 ./firmware/DU1906_slave_v1.5.5.D.bin +```` + +> 注意:串口的设备 /dev/ttyUSB0 根据电脑具体识别修改。 + +**工具烧录** + +下载乐鑫官方 [Flash 烧写工具](https://www.espressif.com/sites/default/files/tools/flash_download_tools_v3.6.8.zip),烧录地址如表格显示,烧录成功后,短按板子 RST 按键重启运行状态。 + +> 注意:烧录地址和固件名称会随着工程更替而变动,烦请以实际 Example 功能分区为准。 + +| 序号 | 固件名称 | 烧录地址 | 功能 | +| :---: | :------------------------------------: | :------: | :------: | +| 1 | bootloader.bin | 0x1000 | Boot | +| 2 | partitions.bin | 0x8000 | 分区表 | +| 3 | ota\_data\_initial.bin | 0xd000 | OTA分区 | +| 4 | app.bin | 0x10000 | APP工程 | +| 5 | profile.bin | 0x7FF000 | 证书许可 | +| 6 | audio\_tone.bin | 0x7d9000 | 提示音 | +| 7 | DU1906\_slave\_v1.5.5.D.bin | 0x570000 | DSP固件 | +| 配置 | SPI Mode DIO、SPI SPEED 80MHz、FLASH SIZE 64Mbit ||| + +
+### 4. 软件配网 + +ESP32-Korvo-DU1906 工程默认使用 Ble 配网,烦请前往乐鑫官方 Github 下载 [Blufi APP](https://github.com/EspressifApp/EspBlufiForAndroid/releases) 进行配网,IOS 版本见[地址](https://github.com/EspressifApp/EspBlufiForiOS/releases),配网步骤如下: + +- 开启手机蓝牙,打开 APP 扫描设备 +- 长按开发板 FUNC 键 4s,开发板进入配网模式,并播放提示音“请点击确定,开始配网” +- 下来 APP 扫描 Ble 设备,选择需要配对的设备,并点击链接 +- 链接成功后显示如下图,然后点击配网,按照输入需要配对的 Wi-Fi 账号密码 + + Blufi connect + + > 注意: 配网方式默认选择 "Station",配对的网络必须是 2.4GHz Wi-Fi + +- 输入后点击确认发送,此时设备会收到配网信息并开始连接网络,连接成功后会提示“网络链接成功” + + Blufi configuration + + > 注意:如果配对失败,烦请 Check 上述流程,并重新尝试 + +
+ +### 5. 使用体验 + +**语音交互体验** + +配网成功并连接上服务器后,设备即准备就绪,您可以使用“小度小度”语音唤醒开始对话,如下部分支持的语言命令,更多指令需要在百度后台申请定义。 + +``` +“小度小度” “在呢”“讲个笑话” +“小度小度” “在呢”“上海天气如何?” +“小度小度” “在呢”“中国有多少人口?” +“小度小度” “在呢”“百度百科乐鑫信息科技” +``` + +**返回示例** + +根据您在第二章 “1.1 修改 main.c 文件中的 methods”中修改的服务权限代码,您在设备端上收到的返回示例可能有如下四种: + +1. 购买全链路服务(BDSC_METHODS_DEFAULT) +2. 购买语音识别+语义解析(BDSC_METHODS_ASR | BDSC_METHODS_NLP ) +3. 仅购买语音识别(BDSC_METHODS_ASR) +4. 越权访问:定义的服务权限代码与控制台购买行为不一致 + +- 购买全链路服务(BDSC\_METHODS\_DEFAULT)时,收到 EVENT\_ASR\_RESULT 、EVENT\_ASR\_EXTERN\_DATA、EVENT\_ASR\_TTS\_DATA三个事件,示例如下: + +``` +I (30226) EVENT_IN: Handle sdk event start. +I (30227) ==========: 366 got asr result +W (30227) ==========: ---> EVENT_ASR_RESULT sn=8cba3508-2b80-?????becf0, idx=0, +buffer_length=243, buffer={"asr_align_begin":7,"asr_align_end":132, +"corpus_no":6844872432671848469,"err_no":0,"raf":400," +result":{"word":["今天天气","今天天泣","今天今天","今天天汽","今天天器"]}, +"sn":"8cba3508-2b80-4d17-adc4-08668c2becf0_ws_0"} + +I (30231) MAIN: ==> Got BDSC_EVENT_ON_ASR_RESULT +I (30231) MAIN: ========= asr result {"asr_align_begin":7,"asr_align_end":132, +"corpus_no":6844872432671848469,"err_no":0,"raf":400, +"result":{"word":["今天天气","今天天泣","今天今天","今天天汽","今天天器"]}, +"sn":"8cba3508-2b80-4d17-adc4-08668c2becf0_ws_0"} + +I (30236) EVENT_OUT: Handle sdk event end. +W (30236) ==========: Stack: 1756 +I (30316) EVENT_IN: Handle sdk event start. +I (30316) ==========: got 1st extern data +W (30316) ==========: ---> EVENT_ASR_EXTERN_DATA sn=8cba3508-2b80-4d17-adc4-08668c2becf0, +idx=0, buffer_length=265,buffer={"error_code":0,"err_msg":"", +"sessionId":"session-1593696055545-3360021168-8013-2136","origin":"92138", +"action_type":"asrnlp_tts","query":["今天天气"],"intent":"USER_WEATHER","slots": +[{"name":"user_time","value":"2020-07-02"}],"custom_reply":[]} +I (30320) MAIN: ==> Got BDSC_EVENT_ON_NLP_RESULT +I (30321) MAIN: early EXIT duplex mode! +I (30322) ==========: found tts type +``` + +- 购买语音识别和语义解析(BDSC\_METHODS\_ASR | BDSC\_METHODS\_NLP )时,收到 EVENT\_ASR\_RESULT EVENT\_ASR\_EXTERN\_DATA两个事件,示例如下。 + +``` +W (27391) ==========: ---> EVENT_ASR_RESULT sn=703f86e0-748e-40cc-a838-f6cdf0afa26a, +idx=0, buffer_length=227,buffer={"asr_align_begin":7,"asr_align_end":144, +"corpus_no":6844866601673826187,"err_no":0,"raf":28, +"result":{"word":["你好吗","祢好吗","拟好吗","旎好吗","你好啊"]}, +"sn":"703f86e0-748e-40cc-a838-f6cdf0afa26a_ws_0"} + +I (27395) MAIN: ==> Got BDSC_EVENT_ON_ASR_RESULT +I (27396) MAIN: ========= asr result {"asr_align_begin":7,"asr_align_end":144, +"corpus_no":6844866601673826187, +"err_no":0,"raf":28,"result":{"word":["你好吗","祢好吗","拟好吗","旎好吗","你好啊"]}, +"sn":"703f86e0-748e-40cc-a838-f6cdf0afa26a_ws_0"} + +I (27400) EVENT_OUT: Handle sdk event end. +W (27400) ==========: Stack: 1756 +I (27790) EVENT_IN: Handle sdk event start. +I (27790) ==========: got 1st extern data +W (27790) ==========: ---> EVENT_ASR_EXTERN_DATA sn=703f86e0-748e-40cc-a838-f6cdf0afa26a, +idx=0, buffer_length=504,buffer={"error_code":0,"err_msg":"","sessionId":"", +"origin":"92140","action_type":"asrnlp_none","query":["你好吗"], +"intent":"BUILT_SUBSTANTIVE","custom_reply":[{"type":"tts","value":" +《你好吗》是周杰伦演唱的一首歌曲,由周杰伦作曲,李汪哲、罗宇轩填词,黄雨勋编曲, +收录在周杰伦2011年11月11日发行的专辑《惊叹号》中,2011年11月4日这首歌曲在移动首发。2012年2月, +这首歌曲获得了中国歌曲排行榜周冠军。"}]} +``` + +- 仅购买语音识别(BDSC\_METHODS\_ASR)时,仅收到一个EVENT\_ASR\_RESULT事件,示例如下: + +``` +EVENT_ASR_RESULT sn=f51cb898-a0b8-4b49-a5d2-745782913936, idx=0, +buffer_length=242,buffer={"asr_align_begin":7, +"asr_align_end":136,"corpus_no":6844835706816949982, +"err_no":0,"raf":27,"result":{"word":["今天天气","今天天泣","今天天汽","今天天器", +"今天天弃"]},"sn":"54cbbbcf-393f-42a9-834f-e61d94a842fb_ws_1"} +``` + +- 越权访问:当您定义的服务权限与实际购买不符时,将收到如下信息: + +``` + {"corpus_no":0,"err_msg":"third party authentication failed[info:-3015]", + "err_no":-3015,"sn":"11199e39-cedc-4da4-a5ca-cd56d7624dda_ws_0"} +``` \ No newline at end of file diff --git a/examples/korvo_du1906/docs/Du1906_cloud_access_guide.pdf b/examples/korvo_du1906/docs/Du1906_cloud_access_guide.pdf deleted file mode 100644 index 989064c..0000000 Binary files a/examples/korvo_du1906/docs/Du1906_cloud_access_guide.pdf and /dev/null differ diff --git a/examples/korvo_du1906/docs/pictures/du_home_config.png b/examples/korvo_du1906/docs/pictures/du_home_config.png new file mode 100644 index 0000000..de2ffd3 Binary files /dev/null and b/examples/korvo_du1906/docs/pictures/du_home_config.png differ diff --git a/examples/korvo_du1906/docs/pictures/du_home_payment.jpeg b/examples/korvo_du1906/docs/pictures/du_home_payment.jpeg new file mode 100644 index 0000000..e777ede Binary files /dev/null and b/examples/korvo_du1906/docs/pictures/du_home_payment.jpeg differ diff --git a/examples/korvo_du1906/docs/pictures/tool_download.png b/examples/korvo_du1906/docs/pictures/tool_download.png index e4dae04..516abd9 100644 Binary files a/examples/korvo_du1906/docs/pictures/tool_download.png and b/examples/korvo_du1906/docs/pictures/tool_download.png differ diff --git a/examples/korvo_du1906/firmware/DU1906_slave_v1.4.8.E.bin b/examples/korvo_du1906/firmware/DU1906_slave_v1.4.8.E.bin deleted file mode 100644 index 012d3eb..0000000 Binary files a/examples/korvo_du1906/firmware/DU1906_slave_v1.4.8.E.bin and /dev/null differ diff --git a/examples/korvo_du1906/firmware/DU1906_slave_v1.5.5.D.bin b/examples/korvo_du1906/firmware/DU1906_slave_v1.5.5.D.bin new file mode 100644 index 0000000..1a956c2 Binary files /dev/null and b/examples/korvo_du1906/firmware/DU1906_slave_v1.5.5.D.bin differ diff --git a/examples/korvo_du1906/firmware/app.bin b/examples/korvo_du1906/firmware/app.bin index 9ebf6ef..4f5efc3 100644 Binary files a/examples/korvo_du1906/firmware/app.bin and b/examples/korvo_du1906/firmware/app.bin differ diff --git a/examples/korvo_du1906/firmware/bootloader.bin b/examples/korvo_du1906/firmware/bootloader.bin index 544cc48..e98d557 100644 Binary files a/examples/korvo_du1906/firmware/bootloader.bin and b/examples/korvo_du1906/firmware/bootloader.bin differ diff --git a/examples/korvo_du1906/firmware/combine_ota_default.bin b/examples/korvo_du1906/firmware/combine_ota_default.bin index 802c10c..85829af 100644 Binary files a/examples/korvo_du1906/firmware/combine_ota_default.bin and b/examples/korvo_du1906/firmware/combine_ota_default.bin differ diff --git a/examples/korvo_du1906/firmware/partitions.bin b/examples/korvo_du1906/firmware/partitions.bin index e856ff3..dc398ba 100644 Binary files a/examples/korvo_du1906/firmware/partitions.bin and b/examples/korvo_du1906/firmware/partitions.bin differ diff --git a/examples/korvo_du1906/main/CMakeLists.txt b/examples/korvo_du1906/main/CMakeLists.txt index 4040979..9184717 100644 --- a/examples/korvo_du1906/main/CMakeLists.txt +++ b/examples/korvo_du1906/main/CMakeLists.txt @@ -1,15 +1,9 @@ -set(COMPONENT_SRCS main.c - app_sys_tools.c - app_player_init.c - app_control.c - app_bt_init.c - app_ota_upgrade.c - ) +set(COMPONENT_SRCDIRS .) set(COMPONENT_ADD_INCLUDEDIRS . ) -set(COMPONENT_REQUIRES audio_sal audio_hal esp_dispatcher esp_peripherals display_service input_key_service bluetooth_service wifi_service audio_player audio_flash_tone bdsc_engine bds_light ota_service mqtt json) +set(COMPONENT_REQUIRES audio_sal audio_hal esp_dispatcher esp_peripherals display_service input_key_service bluetooth_service wifi_service audio_player audio_flash_tone bdsc_engine bds_light ota_service) register_component() diff --git a/examples/korvo_du1906/main/app_bt_init.c b/examples/korvo_du1906/main/app_bt_init.c index 20b6d61..cda9e13 100644 --- a/examples/korvo_du1906/main/app_bt_init.c +++ b/examples/korvo_du1906/main/app_bt_init.c @@ -27,11 +27,22 @@ #include "app_bt_init.h" #include "a2dp_stream.h" #include "ble_gatts_module.h" +#include "bdsc_tools.h" static const char *TAG = "APP_BT_INIT"; #define BT_DEVICE_NAME "ESP_BT_COEX_DEV" +#if __has_include("esp_idf_version.h") +#include "esp_idf_version.h" +#else +#define ESP_IDF_VERSION_VAL(major, minor, patch) 1 +#endif + +char sn[16] = {0}; +static bool bt_connected_flag; +static esp_bd_addr_t g_bda; + esp_periph_handle_t app_bluetooth_init(esp_periph_set_handle_t set) { #if CONFIG_BT_ENABLED @@ -44,21 +55,74 @@ esp_periph_handle_t app_bluetooth_init(esp_periph_set_handle_t set) ble_gatts_module_init(); - esp_err_t set_dev_name_ret = esp_bt_dev_set_device_name(BT_DEVICE_NAME); + size_t length = 16; // _get_sn function need length no less than sn length + esp_err_t set_dev_name_ret; + set_dev_name_ret = bdsc_get_sn(sn, &length); + ESP_LOGI(TAG, "sn = %s, length = %d, return %d\n", sn, length, set_dev_name_ret); + if (set_dev_name_ret == ESP_OK) { + set_dev_name_ret = esp_bt_dev_set_device_name(sn); + } else { + set_dev_name_ret = esp_bt_dev_set_device_name(BT_DEVICE_NAME); + } + if (set_dev_name_ret) { ESP_LOGE(TAG, "set device name failed, error code = %x", set_dev_name_ret); } esp_periph_handle_t bt_periph = bt_create_periph(); esp_periph_start(set, bt_periph); ESP_LOGI(TAG, "Start Bluetooth peripherals"); - - esp_bt_gap_set_scan_mode(ESP_BT_SCAN_MODE_CONNECTABLE_DISCOVERABLE); +#if (ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(4, 0, 0)) + esp_bt_gap_set_scan_mode(ESP_BT_NON_CONNECTABLE, ESP_BT_NON_DISCOVERABLE); +#else + esp_bt_gap_set_scan_mode(ESP_BT_SCAN_MODE_NONE); +#endif return bt_periph; #else + ESP_LOGE(TAG, "Please enable bt first"); return NULL; #endif } +esp_err_t app_bt_stop(void) +{ + esp_err_t ret = ESP_OK; +#if CONFIG_BT_ENABLED + ESP_LOGI(TAG, "bt stop"); + if (bt_connected_flag == true) { +#if (ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(4, 0, 0)) + ret |= esp_bt_gap_set_scan_mode(ESP_BT_NON_CONNECTABLE, ESP_BT_NON_DISCOVERABLE); +#else + ret |= esp_bt_gap_set_scan_mode(ESP_BT_SCAN_MODE_NONE); +#endif + ret |= esp_a2d_sink_disconnect(g_bda); + ret |= esp_a2d_sink_deinit(); + ret |= esp_avrc_ct_deinit();// + bt_connected_flag = false; + } +#endif + return ret; +} + +esp_err_t app_bt_start(void) +{ + esp_err_t ret = ESP_OK; +#if CONFIG_BT_ENABLED + ESP_LOGI(TAG, "bt start"); + if (bt_connected_flag == false) { + ret |= esp_a2d_sink_init(); + ret |= esp_avrc_ct_init();// + // ret |= esp_avrc_ct_register_callback(bt_app_rc_ct_cb);// +#if (ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(4, 0, 0)) + ret |= esp_bt_gap_set_scan_mode(ESP_BT_CONNECTABLE, ESP_BT_GENERAL_DISCOVERABLE); +#else + ret |= esp_bt_gap_set_scan_mode(ESP_BT_SCAN_MODE_CONNECTABLE_DISCOVERABLE); +#endif + bt_connected_flag = true; + } +#endif + return ret; +} + void app_bluetooth_deinit(void) { #if CONFIG_BT_ENABLED @@ -70,4 +134,11 @@ void app_bluetooth_deinit(void) ble_gatts_module_deinit(); #endif -} \ No newline at end of file +} + +void app_bt_set_addr(esp_bd_addr_t *addr) +{ + if (addr) { + memcpy(&g_bda, addr, sizeof(esp_bd_addr_t)); + } +} diff --git a/examples/korvo_du1906/main/app_bt_init.h b/examples/korvo_du1906/main/app_bt_init.h index e99101a..56baa97 100644 --- a/examples/korvo_du1906/main/app_bt_init.h +++ b/examples/korvo_du1906/main/app_bt_init.h @@ -30,6 +30,7 @@ extern "C" { #endif #include "esp_peripherals.h" +#include "esp_gap_bt_api.h" /** * @brief Initializes the bluetooth @@ -47,6 +48,31 @@ esp_periph_handle_t app_bluetooth_init(esp_periph_set_handle_t set); */ void app_bluetooth_deinit(void); +/** + * @brief Enable a2dp function + * + * @return ESP_OK success + * ESP_FAIL failed + */ +esp_err_t app_bt_start(void); + +/** + * @brief Disable a2dp function + * + * @param[in] bda remote bt adress (mac address) + * + * @return ESP_OK success + * ESP_FAIL failed + */ +esp_err_t app_bt_stop(void); + +/** + * @brief Set bt bda + * + * @param[in] addr remote bt adress (mac address) + */ +void app_bt_set_addr(esp_bd_addr_t *addr); + #ifdef __cplusplus } #endif diff --git a/examples/korvo_du1906/main/app_control.c b/examples/korvo_du1906/main/app_control.c index c0e2081..032be9f 100755 --- a/examples/korvo_du1906/main/app_control.c +++ b/examples/korvo_du1906/main/app_control.c @@ -37,6 +37,7 @@ #include "bdsc_event_dispatcher.h" #include "app_player_init.h" #include "app_ota_upgrade.h" +#include "app_bt_init.h" #include "audio_player_helper.h" #include "audio_player_type.h" #include "audio_player.h" @@ -44,6 +45,7 @@ #include "ble_gatts_module.h" #include "bds_client_event.h" #include "bdsc_engine.h" +#include "app_control.h" #define WIFI_CONNECTED_BIT (BIT0) #define WIFI_WAIT_CONNECT_TIME_MS (15000 / portTICK_PERIOD_MS) @@ -75,7 +77,6 @@ static esp_err_t wifi_service_cb(periph_service_handle_t handle, periph_service_ #endif } // BDSC Engine need net connected notifier to restart link - bdsc_engine_net_connected_cb(); } else if (evt->type == WIFI_SERV_EVENT_DISCONNECTED) { ESP_LOGW(TAG, "PERIPH_WIFI_DISCONNECTED [%d]", __LINE__); #ifdef CONFIG_ESP_BLUFI @@ -88,6 +89,8 @@ static esp_err_t wifi_service_cb(periph_service_handle_t handle, periph_service_ return ESP_OK; } +int bdsc_ota_start(char *url, int version); + static esp_err_t input_key_service_cb(periph_service_handle_t handle, periph_service_event_t *evt, void *ctx) { @@ -124,7 +127,6 @@ static esp_err_t input_key_service_cb(periph_service_handle_t handle, periph_ser blufi_set_sta_connected_flag(h, false); #endif if (evt->type == INPUT_KEY_SERVICE_ACTION_PRESS) { - bdsc_engine_set_connect_flag(false); if (wifi_setting_flag == false) { audio_player_state_get(&st); if (((int)st.status == AUDIO_STATUS_RUNNING)) { @@ -181,27 +183,40 @@ void audio_player_callback(audio_player_state_t *audio, void *ctx) ESP_LOGW(TAG, "AUDIO_PLAYER_CALLBACK send OK, status:%d, err_msg:%x, media_src:%x, ctx:%p", audio->status, audio->err_msg, audio->media_src, ctx); } -#if CONFIG_BT_ENABLED + +static const char *conn_state_str[] = { "Disconnected", "Connecting", "Connected", "Disconnecting" }; + static void user_a2dp_sink_cb(esp_a2d_cb_event_t event, esp_a2d_cb_param_t *param) { ESP_LOGI(TAG, "A2DP sink user cb"); switch (event) { - case ESP_A2D_CONNECTION_STATE_EVT: - if (param->conn_stat.state == ESP_A2D_CONNECTION_STATE_DISCONNECTED) { - ESP_LOGI(TAG, "A2DP disconnected"); - bdsc_play_hint(BDSC_HINT_BT_DISCONNECTED); - } else if (param->conn_stat.state == ESP_A2D_CONNECTION_STATE_CONNECTED) { - ESP_LOGI(TAG, "A2DP connected"); - // Do not play hint to avoid interrupt BT player - //bdsc_play_hint(BDSC_HINT_BT_CONNECTED); + case ESP_A2D_CONNECTION_STATE_EVT: { + esp_a2d_cb_param_t *a2d = param; + uint8_t *bda = a2d->conn_stat.remote_bda; + app_bt_set_addr(&a2d->conn_stat.remote_bda); + ESP_LOGI(TAG, "A2DP connection state: %s, [%02x:%02x:%02x:%02x:%02x:%02x]", + conn_state_str[a2d->conn_stat.state], bda[0], bda[1], bda[2], bda[3], bda[4], bda[5]); + if (a2d->conn_stat.state == ESP_A2D_CONNECTION_STATE_DISCONNECTED) { + + ESP_LOGI(TAG, "A2DP disconnected"); + } else if (a2d->conn_stat.state == ESP_A2D_CONNECTION_STATE_CONNECTED) { + ESP_LOGI(TAG, "A2DP connected"); + display_service_set_pattern(disp_serv, DISPLAY_PATTERN_BT_CONNECTED, 0); + } else if (a2d->conn_stat.state == ESP_A2D_CONNECTION_STATE_DISCONNECTING) { + } + break; + } + case ESP_A2D_AUDIO_STATE_EVT: { + + // Some wrong actions occur if use this event to control + // playing in bluetooth source. So we use avrc control. + break; } - break; default: ESP_LOGI(TAG, "User cb A2DP event: %d", event); break; } } -#endif void app_init(void) { @@ -223,19 +238,20 @@ void app_init(void) esp_periph_set_handle_t set = esp_periph_set_init(&periph_cfg); // step 2. initialize sdcard - audio_board_sdcard_init(set); + audio_board_sdcard_init(set, SD_MODE_1_LINE); // step 3. setup display service disp_serv = audio_board_led_init(); // step 4. setup Wi-Fi service wifi_config_t sta_cfg = {0}; - strncpy((char *)&sta_cfg.sta.ssid, CONFIG_WIFI_SSID, strlen(CONFIG_WIFI_SSID)); - strncpy((char *)&sta_cfg.sta.password, CONFIG_WIFI_PASSWORD, strlen(CONFIG_WIFI_PASSWORD)); + strncpy((char *)&sta_cfg.sta.ssid, CONFIG_WIFI_SSID, sizeof(sta_cfg.sta.ssid)); + strncpy((char *)&sta_cfg.sta.password, CONFIG_WIFI_PASSWORD, sizeof(sta_cfg.sta.password)); wifi_service_config_t cfg = WIFI_SERVICE_DEFAULT_CONFIG(); cfg.extern_stack = true; cfg.evt_cb = wifi_service_cb; cfg.cb_ctx = NULL; + cfg.task_prio = 11; cfg.setting_timeout_s = 3600; cfg.max_retry_time = -1; wifi_serv = wifi_service_create(&cfg); @@ -266,7 +282,7 @@ void app_init(void) // step 5. wait for wifi connected, and start ota service EventBits_t bits = xEventGroupWaitBits(WIFI_CONNECTED_FLAG, WIFI_CONNECTED_BIT, true, false, WIFI_WAIT_CONNECT_TIME_MS); if (bits & WIFI_CONNECTED_BIT) { - app_ota_start(); + // app_ota_start(); } else { ESP_LOGW(TAG, "WIFI connection timeout(%dms), skipped OTA service", WIFI_WAIT_CONNECT_TIME_MS); } diff --git a/examples/korvo_du1906/main/app_player_init.c b/examples/korvo_du1906/main/app_player_init.c index fb47ce4..9324c5e 100644 --- a/examples/korvo_du1906/main/app_player_init.c +++ b/examples/korvo_du1906/main/app_player_init.c @@ -46,9 +46,12 @@ #include "audio_player_type.h" #include "audio_player.h" #include "app_player_init.h" +#include "audio_player_pipeline_int_tone.h" static const char *TAG = "APP_PLAYER_INIT"; +static audio_element_handle_t g_player_i2s_write_handle; + static int _http_stream_event_handle(http_stream_event_msg_t *msg) { if (msg->event_id == HTTP_STREAM_RESOLVE_ALL_TRACKS) { @@ -112,19 +115,15 @@ static esp_audio_handle_t setup_app_esp_audio_instance(esp_audio_cfg_t *cfg, voi http_cfg.stack_in_ext = true; audio_element_handle_t http_stream_reader = http_stream_init(&http_cfg); esp_audio_input_stream_add(handle, http_stream_reader); + ESP_LOGI(TAG, "http_stream_reader0:%p", http_stream_reader); + http_stream_reader = http_stream_init(&http_cfg); + esp_audio_input_stream_add(handle, http_stream_reader); + ESP_LOGI(TAG, "http_stream_reader1:%p", http_stream_reader); + http_stream_reader = http_stream_init(&http_cfg); + esp_audio_input_stream_add(handle, http_stream_reader); + ESP_LOGI(TAG, "http_stream_reader2:%p", http_stream_reader); - // Add decoders and encoders to esp_audio - mp3_decoder_cfg_t mp3_dec_cfg = DEFAULT_MP3_DECODER_CONFIG(); - mp3_dec_cfg.task_core = 1; - mp3_dec_cfg.task_prio = 12; - aac_decoder_cfg_t aac_cfg = DEFAULT_AAC_DECODER_CONFIG(); - aac_cfg.task_core = 1; - aac_cfg.task_prio = 12; - esp_audio_codec_lib_add(handle, AUDIO_CODEC_TYPE_DECODER, aac_decoder_init(&aac_cfg)); - esp_audio_codec_lib_add(handle, AUDIO_CODEC_TYPE_DECODER, mp3_decoder_init(&mp3_dec_cfg)); - pcm_decoder_cfg_t pcm_dec_cfg = DEFAULT_PCM_DECODER_CONFIG(); - esp_audio_codec_lib_add(handle, AUDIO_CODEC_TYPE_DECODER, pcm_decoder_init(&pcm_dec_cfg)); - + // Add esp_decoder audio_decoder_t auto_decode[] = { DEFAULT_ESP_AMRNB_DECODER_CONFIG(), DEFAULT_ESP_AMRWB_DECODER_CONFIG(), @@ -139,14 +138,6 @@ static esp_audio_handle_t setup_app_esp_audio_instance(esp_audio_cfg_t *cfg, voi auto_dec_cfg.task_prio = 12; esp_audio_codec_lib_add(handle, AUDIO_CODEC_TYPE_DECODER, esp_decoder_init(&auto_dec_cfg, auto_decode, sizeof(auto_decode) / sizeof(audio_decoder_t))); - audio_element_handle_t m4a_dec_cfg = aac_decoder_init(&aac_cfg); - audio_element_set_tag(m4a_dec_cfg, "m4a"); - esp_audio_codec_lib_add(handle, AUDIO_CODEC_TYPE_DECODER, m4a_dec_cfg); - - audio_element_handle_t ts_dec_cfg = aac_decoder_init(&aac_cfg); - audio_element_set_tag(ts_dec_cfg, "ts"); - esp_audio_codec_lib_add(handle, AUDIO_CODEC_TYPE_DECODER, ts_dec_cfg); - // Set default volume esp_audio_vol_set(handle, 60); AUDIO_MEM_SHOW(TAG); @@ -178,17 +169,19 @@ esp_err_t app_player_init(QueueHandle_t que, audio_player_evt_callback cb, esp_p default_cfg.evt_que = NULL; default_cfg.resample_rate = 48000; default_cfg.in_stream_buf_size = 500 * 1024; + default_cfg.task_prio = 13; audio_player_cfg_t cfg = DEFAULT_AUDIO_PLAYER_CONFIG(); cfg.external_ram_stack = true; - cfg.task_prio = 6; + cfg.task_prio = 13; cfg.task_stack = 3 * 1024; cfg.evt_cb = cb; cfg.evt_ctx = que; cfg.music_list = NULL; cfg.handle = setup_app_esp_audio_instance(&default_cfg, a2dp_cb); - esp_audio_output_stream_add(cfg.handle, i2s_stream_init(&i2s_writer)); + g_player_i2s_write_handle = i2s_stream_init(&i2s_writer); + esp_audio_output_stream_add(cfg.handle, g_player_i2s_write_handle); audio_err_t ret = audio_player_init(&cfg); ret |= default_http_player_init(); @@ -197,5 +190,11 @@ esp_err_t app_player_init(QueueHandle_t que, audio_player_evt_callback cb, esp_p ret |= default_flash_tone_player_init(); ret |= default_a2dp_player_init(bt_periph); ret |= default_raw_player_init(); + ret |= audio_player_int_tone_init(); return ESP_OK; } + +audio_element_handle_t app_player_get_i2s_handle(void) +{ + return g_player_i2s_write_handle; +} diff --git a/examples/korvo_du1906/main/app_voice_control.c b/examples/korvo_du1906/main/app_voice_control.c new file mode 100644 index 0000000..6a481d8 --- /dev/null +++ b/examples/korvo_du1906/main/app_voice_control.c @@ -0,0 +1,143 @@ +/* + * Copyright (c) 2020 Baidu.com, Inc. All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on + * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the + * specific language governing permissions and limitations under the License. + */ + +#include "app_voice_control.h" +#include "app_bt_init.h" +#include "audio_player.h" +#include "bdsc_event_dispatcher.h" + +#define TAG "APP_VC" + +static app_voice_ctr_cmd_t app_voice_control_cmd_filter(BdsJson *data_j, void *userdata) +{ + char *intent, *name, *value; + char *user_action_key = NULL, *user_action_value = NULL; + char *user_func_key = NULL, *user_func_value = NULL; + char *user_att_key = NULL, *user_att_value = NULL; + BdsJson *slots_j; + int arr_len; + int on_off = -1; + + if (!data_j) { + return APP_VOICE_CTL_CMD_NONE; + } + if (!(intent = BdsJsonObjectGetString(data_j, "intent"))) { + return APP_VOICE_CTL_CMD_NONE; + } + if (strcmp(intent, DEVICE_ACTION_KEY)) { + return APP_VOICE_CTL_CMD_NONE; + } + if (!(slots_j = BdsJsonObjectGet(data_j, "slots"))) { + return APP_VOICE_CTL_CMD_NONE; + } + arr_len = BdsJsonArrayLen(slots_j); + if (arr_len <= 0) { + return APP_VOICE_CTL_CMD_NONE; + } + BdsJsonArrayForeach(slots_j, elem_j) { + if (!(name = BdsJsonObjectGetString(elem_j, "name")) || + !(value = BdsJsonObjectGetString(elem_j, "value"))) { + ESP_LOGE(TAG, "format error"); + return APP_VOICE_CTL_CMD_NONE; + } + if (!strcmp(name, "user_action")) { + user_action_key = name; + user_action_value = value; + } + if (!strcmp(name, "user_func_bluetooth")) { + user_func_key = name; + user_func_value = value; + } + if (!strcmp(name, "user_attr_mode")) { + user_func_key = name; + user_func_value = value; + } + if (!strcmp(name, "user_attr")) { + user_att_key = name; + user_att_value = value; + } + } + + if (user_att_value && user_att_key) { + ESP_LOGI(TAG, "get user att value and key"); + } + + if (!user_action_key || !user_action_value || strcmp(user_action_key, "user_action")) { + ESP_LOGE(TAG, "format error"); + return APP_VOICE_CTL_CMD_NONE; + } + if (!strcmp(user_action_value, "CONTINUE")) { + return APP_VOICE_CTL_CMD_MUSIC_CONTINUE; + } else if (!strcmp(user_action_value, "PAUSE")) { + return APP_VOICE_CTL_CMD_MUSIC_PAUSE; + } else if (!strcmp(user_action_value, "STOP")) { + return APP_VOICE_CTL_CMD_MUSIC_STOP; + } else if (!strcmp(user_action_value, "ON")) { + on_off = 1; + } else if (!strcmp(user_action_value, "OFF")) { + on_off = 0; + } else { + ESP_LOGE(TAG, "format error"); + return APP_VOICE_CTL_CMD_NONE; + } + + if (!user_func_key || !user_func_value) { + ESP_LOGE(TAG, "format error"); + return APP_VOICE_CTL_CMD_NONE; + } + if (!strcmp(user_func_key, "user_func_bluetooth")) { + if (on_off == 1) { + return APP_VOICE_CTL_CMD_OPEN_BT; + } else { + return APP_VOICE_CTL_CMD_CLOSE_BT; + } + } else { + ESP_LOGE(TAG, "format error"); + return APP_VOICE_CTL_CMD_NONE; + } +} + + +void app_voice_control_feed_data(BdsJson *data_j, void *userdata) +{ + switch (app_voice_control_cmd_filter(data_j, userdata)) { + case APP_VOICE_CTL_CMD_NONE: + ESP_LOGI(TAG, "APP_VOICE_CTL_CMD_NONE"); + break; + case APP_VOICE_CTL_CMD_OPEN_BT: + ESP_LOGI(TAG, "APP_VOICE_CTL_CMD_OPEN_BT"); + app_bt_start(); + break; + case APP_VOICE_CTL_CMD_CLOSE_BT: + ESP_LOGI(TAG, "APP_VOICE_CTL_CMD_CLOSE_BT"); + bdsc_engine_close_bt(); + app_bt_stop(); + break; + case APP_VOICE_CTL_CMD_MUSIC_CONTINUE: + bdsc_set_pre_player_flag(true); + ESP_LOGI(TAG, "APP_VOICE_CTL_CMD_MUSIC_CONTINUE"); + break; + case APP_VOICE_CTL_CMD_MUSIC_PAUSE: + bdsc_set_pre_player_flag(false); + ESP_LOGI(TAG, "APP_VOICE_CTL_CMD_MUSIC_PAUSE"); + break; + case APP_VOICE_CTL_CMD_MUSIC_STOP: + bdsc_set_pre_player_flag(false); + audio_player_clear_audio_info(); + ESP_LOGI(TAG, "APP_VOICE_CTL_CMD_MUSIC_STOP"); + break; + default: + break; + } +} diff --git a/examples/korvo_du1906/main/app_voice_control.h b/examples/korvo_du1906/main/app_voice_control.h new file mode 100644 index 0000000..52e3798 --- /dev/null +++ b/examples/korvo_du1906/main/app_voice_control.h @@ -0,0 +1,52 @@ +/* + * Copyright (c) 2020 Baidu.com, Inc. All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on + * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the + * specific language governing permissions and limitations under the License. + */ + +#ifndef __APP_VOICE_CONTROL_H__ +#define __APP_VOICE_CONTROL_H__ + +#include +#include "esp_log.h" +#include "freertos/FreeRTOS.h" +#include "freertos/task.h" +#include "esp_system.h" +#include "esp_spi_flash.h" +#include "freertos/event_groups.h" +#include "esp_wifi.h" +#include "nvs_flash.h" +#include +#include "bdsc_json.h" +#include "bdsc_engine.h" + +#define DEVICE_ACTION_KEY "DEV_ACTION" + +#ifdef __cplusplus +extern "C" { +#endif + +typedef enum { + APP_VOICE_CTL_CMD_NONE, + APP_VOICE_CTL_CMD_OPEN_BT, + APP_VOICE_CTL_CMD_CLOSE_BT, + APP_VOICE_CTL_CMD_MUSIC_CONTINUE, + APP_VOICE_CTL_CMD_MUSIC_PAUSE, + APP_VOICE_CTL_CMD_MUSIC_STOP, +} app_voice_ctr_cmd_t; + +void app_voice_control_feed_data(BdsJson *data_j, void *userdata); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/examples/korvo_du1906/main/component.mk b/examples/korvo_du1906/main/component.mk index 202734e..a3feea2 100644 --- a/examples/korvo_du1906/main/component.mk +++ b/examples/korvo_du1906/main/component.mk @@ -1,4 +1,4 @@ -COMPONENT_ADD_INCLUDEDIRS := ./include/ +COMPONENT_ADD_INCLUDEDIRS := ./include/ COMPONENT_SRCDIRS := . CFLAGS += -Wno-enum-compare diff --git a/examples/korvo_du1906/main/main.c b/examples/korvo_du1906/main/main.c index fdef7ac..9e24ffc 100755 --- a/examples/korvo_du1906/main/main.c +++ b/examples/korvo_du1906/main/main.c @@ -23,6 +23,20 @@ #include "display_service.h" #include "bdsc_json.h" #include "audio_mem.h" +#include "app_voice_control.h" +#include "app_bt_init.h" + +#if __has_include("esp_idf_version.h") +#include "esp_idf_version.h" +#else +#define ESP_IDF_VERSION_VAL(major, minor, patch) 1 +#endif + +#if (ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(4, 1, 0)) +#include "esp_netif.h" +#else +#include "tcpip_adapter.h" +#endif #define TAG "MAIN" @@ -32,7 +46,6 @@ bool need_skip_current_playing() return false; } - esp_err_t my_bdsc_engine_event_handler(bdsc_engine_event_t *evt) { cJSON *json; @@ -68,8 +81,8 @@ esp_err_t my_bdsc_engine_event_handler(bdsc_engine_event_t *evt) /* * 用户通过 “唤醒词 + 命令” 进行交互时,云端返回的ASR结果。 * 返回的 evt 类型如下: - * evt->data 为 bdsc_engine_event_data_t 结构体指针 - * evt->data_len 为 bdsc_engine_event_data_t 结构体大小 + * evt->data 为 bdsc_event_data_t 结构体指针 + * evt->data_len 为 bdsc_event_data_t 结构体大小 * evt->client 为 全局 bdsc_engine_handle_t 实例对象 * 结构体定义如下: * @@ -77,8 +90,8 @@ esp_err_t my_bdsc_engine_event_handler(bdsc_engine_event_t *evt) char sn[SN_LENGTH]; // 在语音链路中,每个request都对应一个sn码,方便追溯问题。 int16_t idx; // 序号 uint16_t buffer_length; // 数据包长度 - uint8_t *buffer; // 数据 - } bdsc_engine_event_data_t; + uint8_t buffer[]; // 数据 + } bdsc_event_data_t; * * 返回的 buffer 数据为 JSON 格式。格式如下: * 以“问:今天天气”为例,返回: @@ -96,18 +109,21 @@ esp_err_t my_bdsc_engine_event_handler(bdsc_engine_event_t *evt) */ /* 通过语音控制蓝牙打开 */ - bdsc_engine_event_data_t *asr_result = (bdsc_engine_event_data_t *)evt->data; + bdsc_event_data_t *asr_result = (bdsc_event_data_t *)evt->data; if (!asr_result->buffer) { ESP_LOGE(TAG, "BUG!!!\n"); return BDSC_CUSTOM_DESIRE_DEFAULT; } + if (strstr((char *)asr_result->buffer, "打开") && strstr((char *)asr_result->buffer, "蓝牙")) { + app_bt_start(); bdsc_engine_open_bt(); return BDSC_CUSTOM_DESIRE_DEFAULT; } /* 通过语音控制蓝牙关闭 */ if (strstr((char *)asr_result->buffer, "关闭") && strstr((char *)asr_result->buffer, "蓝牙")) { bdsc_engine_close_bt(); + app_bt_stop(); return BDSC_CUSTOM_DESIRE_DEFAULT; } @@ -123,7 +139,6 @@ esp_err_t my_bdsc_engine_event_handler(bdsc_engine_event_t *evt) } if (err_value == -3005) { - // bdsc_play_hint(BDSC_HINT_NOT_FIND); BdsJsonPut(json); return BDSC_CUSTOM_DESIRE_RESUME; } @@ -165,6 +180,22 @@ esp_err_t my_bdsc_engine_event_handler(bdsc_engine_event_t *evt) * * TIPS: 随 NLP 一起下发的TTS语音流,由SDK自动播放,暂时不对用户开放。 */ + + cJSON *j_content; + /* 某些情况下,需要跳过当前会话 */ + if (need_skip_current_playing()) { + ESP_LOGI(TAG, "skip playing"); + return BDSC_CUSTOM_DESIRE_SKIP_DEFAULT; + } + if (!(j_content = BdsJsonParse((const char *)evt->data))) { + ESP_LOGE(TAG, "json format error"); + return BDSC_CUSTOM_DESIRE_SKIP_DEFAULT; + } + + app_voice_control_feed_data(j_content, NULL); + + BdsJsonPut(j_content); + return BDSC_CUSTOM_DESIRE_DEFAULT; case BDSC_EVENT_ON_CHANNEL_DATA: @@ -195,7 +226,11 @@ void app_main(void) ret = nvs_flash_init(); } ESP_ERROR_CHECK(ret); +#if (ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(4, 1, 0)) + ESP_ERROR_CHECK(esp_netif_init()); +#else tcpip_adapter_init(); +#endif bdsc_engine_config_t cfg = { .log_level = 0, @@ -211,5 +246,5 @@ void app_main(void) bdsc_engine_init(&cfg); - // start_sys_monitor(); + start_sys_monitor(); } diff --git a/examples/korvo_du1906/partitions.csv b/examples/korvo_du1906/partitions.csv index 55debd5..65c665c 100644 --- a/examples/korvo_du1906/partitions.csv +++ b/examples/korvo_du1906/partitions.csv @@ -3,8 +3,8 @@ nvs, data, nvs, 0x9000, 0x4000, otadata, data, ota, 0xd000, 0x2000, phy_init, data, phy, 0xf000, 0x1000, -ota_0, app, ota_0, 0x10000, 2560K, -ota_1, app, ota_1, 0x290000, 2560K, -dsp_bin, data, 0x24, 0x510000, 2560K, -profile, data, 0x29, 0x790000, 0x1000, -flash_tone, data, 0x27, 0x791000, 384K, +ota_0, app, ota_0, 0x10000, 0x2b0000, +ota_1, app, ota_1, 0x2c0000, 0x2b0000, +dsp_bin, data, 0x24, 0x570000, 0x269000, +flash_tone, data, 0x27, 0x7d9000, 0x26000, +profile, data, 0x29, 0x7FF000, 0x1000, diff --git a/examples/korvo_du1906/patches/a2dp_stream_du1906.patch b/examples/korvo_du1906/patches/a2dp_stream_du1906.patch new file mode 100644 index 0000000..81d6a6f --- /dev/null +++ b/examples/korvo_du1906/patches/a2dp_stream_du1906.patch @@ -0,0 +1,247 @@ +diff --git a/components/bluetooth_service/a2dp_stream.c b/components/bluetooth_service/a2dp_stream.c +index 06dc1b4b..c1cacea7 100644 +--- a/components/bluetooth_service/a2dp_stream.c ++++ b/components/bluetooth_service/a2dp_stream.c +@@ -32,9 +32,16 @@ + #include "sdkconfig.h" + + #include "a2dp_stream.h" ++#include "esp_avrc_api.h" + + #if CONFIG_BT_ENABLED + ++#define APP_RC_CT_TL_GET_CAPS (0) ++#define APP_RC_CT_TL_GET_META_DATA (1) ++#define APP_RC_CT_TL_RN_TRACK_CHANGE (2) ++#define APP_RC_CT_TL_RN_PLAYBACK_CHANGE (3) ++#define APP_RC_CT_TL_RN_PLAY_POS_CHANGE (4) ++ + static const char *TAG = "A2DP_STREAM"; + + static audio_element_handle_t a2dp_sink_stream_handle = NULL; +@@ -44,6 +51,7 @@ static esp_periph_handle_t bt_avrc_periph = NULL; + static bool avrcp_conn_state = false; + static audio_stream_type_t a2d_stream_type = 0; + static uint8_t trans_label = 0; ++static esp_avrc_rn_evt_cap_mask_t s_avrc_peer_rn_cap; + + #if (ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(4, 0, 0)) + static audio_hal_handle_t audio_hal = NULL; +@@ -219,7 +227,7 @@ audio_element_handle_t a2dp_stream_init(a2dp_stream_config_t *config) + + cfg.task_stack = -1; // No need task + cfg.tag = "aadp"; +- ++ + esp_avrc_ct_init(); + esp_avrc_ct_register_callback(bt_avrc_ct_cb); + +@@ -295,13 +303,63 @@ static void bt_avrc_volume_set_by_local(int16_t volume) + rn_param.volume = g_volume; + esp_avrc_tg_send_rn_rsp(ESP_AVRC_RN_VOLUME_CHANGE, ESP_AVRC_RN_RSP_CHANGED, &rn_param); + if (audio_hal) { +- audio_hal_set_volume(audio_hal, g_volume); +- } ++ audio_hal_set_volume(audio_hal, g_volume); ++ } + g_volume_notify = false; + } + } + #endif + ++static void bt_av_new_track(void) ++{ ++ // request metadata ++ uint8_t attr_mask = ESP_AVRC_MD_ATTR_TITLE | ESP_AVRC_MD_ATTR_ARTIST | ESP_AVRC_MD_ATTR_ALBUM | ESP_AVRC_MD_ATTR_GENRE; ++ esp_avrc_ct_send_metadata_cmd(APP_RC_CT_TL_GET_META_DATA, attr_mask); ++ ++ // register notification if peer support the event_id ++ if (esp_avrc_rn_evt_bit_mask_operation(ESP_AVRC_BIT_MASK_OP_TEST, &s_avrc_peer_rn_cap, ++ ESP_AVRC_RN_TRACK_CHANGE)) { ++ esp_avrc_ct_send_register_notification_cmd(APP_RC_CT_TL_RN_TRACK_CHANGE, ESP_AVRC_RN_TRACK_CHANGE, 0); ++ } ++} ++ ++static void bt_av_playback_changed(void) ++{ ++ if (esp_avrc_rn_evt_bit_mask_operation(ESP_AVRC_BIT_MASK_OP_TEST, &s_avrc_peer_rn_cap, ++ ESP_AVRC_RN_PLAY_STATUS_CHANGE)) { ++ esp_avrc_ct_send_register_notification_cmd(APP_RC_CT_TL_RN_PLAYBACK_CHANGE, ESP_AVRC_RN_PLAY_STATUS_CHANGE, 0); ++ } ++} ++ ++static void bt_av_play_pos_changed(void) ++{ ++ if (esp_avrc_rn_evt_bit_mask_operation(ESP_AVRC_BIT_MASK_OP_TEST, &s_avrc_peer_rn_cap, ++ ESP_AVRC_RN_PLAY_POS_CHANGED)) { ++ esp_avrc_ct_send_register_notification_cmd(APP_RC_CT_TL_RN_PLAY_POS_CHANGE, ESP_AVRC_RN_PLAY_POS_CHANGED, 10); ++ } ++} ++ ++extern esp_err_t bdsc_engine_open_bt(); ++void bt_av_notify_evt_handler(uint8_t event_id, esp_avrc_rn_param_t *event_parameter) ++{ ++ switch (event_id) { ++ case ESP_AVRC_RN_TRACK_CHANGE: ++ bt_av_new_track(); ++ break; ++ case ESP_AVRC_RN_PLAY_STATUS_CHANGE: ++ ESP_LOGI(TAG, "Playback status changed: 0x%x", event_parameter->playback); ++ if (event_parameter->playback == ESP_AVRC_PLAYBACK_PLAYING) { ++ bdsc_engine_open_bt(); ++ } ++ bt_av_playback_changed(); ++ break; ++ case ESP_AVRC_RN_PLAY_POS_CHANGED: ++ ESP_LOGI(TAG, "Play position changed: %d-ms", event_parameter->play_pos); ++ bt_av_play_pos_changed(); ++ break; ++ } ++} ++ + static void bt_avrc_ct_cb(esp_avrc_ct_cb_event_t event, esp_avrc_ct_cb_param_t *p_param) + { + esp_avrc_ct_cb_param_t *rc = p_param; +@@ -312,17 +370,21 @@ static void bt_avrc_ct_cb(esp_avrc_ct_cb_event_t event, esp_avrc_ct_cb_param_t * + if (rc->conn_stat.connected) { + ESP_LOGD(TAG, "ESP_AVRC_CT_CONNECTION_STATE_EVT"); + bt_key_act_sm_init(); ++ // get remote supported event_ids of peer AVRCP Target ++ esp_avrc_ct_send_get_rn_capabilities_cmd(APP_RC_CT_TL_GET_CAPS); + } else if (0 == rc->conn_stat.connected) { + bt_key_act_sm_deinit(); ++ // clear peer notification capability record ++ s_avrc_peer_rn_cap.bits = 0; + } + +- ESP_LOGD(TAG, "AVRC conn_state evt: state %d, [%02x:%02x:%02x:%02x:%02x:%02x]", ++ ESP_LOGI(TAG, "AVRC conn_state evt: state %d, [%02x:%02x:%02x:%02x:%02x:%02x]", + rc->conn_stat.connected, bda[0], bda[1], bda[2], bda[3], bda[4], bda[5]); + break; + } + case ESP_AVRC_CT_PASSTHROUGH_RSP_EVT: { + if (avrcp_conn_state) { +- ESP_LOGD(TAG, "AVRC passthrough rsp: key_code 0x%x, key_state %d", rc->psth_rsp.key_code, rc->psth_rsp.key_state); ++ ESP_LOGI(TAG, "AVRC passthrough rsp: key_code 0x%x, key_state %d", rc->psth_rsp.key_code, rc->psth_rsp.key_state); + bt_key_act_param_t param; + memset(¶m, 0, sizeof(bt_key_act_param_t)); + param.evt = event; +@@ -334,16 +396,26 @@ static void bt_avrc_ct_cb(esp_avrc_ct_cb_event_t event, esp_avrc_ct_cb_param_t * + break; + } + case ESP_AVRC_CT_METADATA_RSP_EVT: { +- ESP_LOGD(TAG, "AVRC metadata rsp: attribute id 0x%x, %s", rc->meta_rsp.attr_id, rc->meta_rsp.attr_text); ++ ESP_LOGI(TAG, "AVRC metadata rsp: attribute id 0x%x, %s", rc->meta_rsp.attr_id, rc->meta_rsp.attr_text); + // free(rc->meta_rsp.attr_text); + break; + } + case ESP_AVRC_CT_CHANGE_NOTIFY_EVT: { +- // ESP_LOGD(TAG, "AVRC event notification: %u, param: %u", rc->change_ntf.event_id, rc->change_ntf.event_parameter); ++ // ESP_LOGI(TAG, "AVRC event notification: %u, param: %u", rc->change_ntf.event_id, rc->change_ntf.event_parameter); ++ bt_av_notify_evt_handler(rc->change_ntf.event_id, &rc->change_ntf.event_parameter); + break; + } + case ESP_AVRC_CT_REMOTE_FEATURES_EVT: { +- ESP_LOGD(TAG, "AVRC remote features %x", rc->rmt_feats.feat_mask); ++ ESP_LOGI(TAG, "AVRC remote features %x", rc->rmt_feats.feat_mask); ++ break; ++ } ++ case ESP_AVRC_CT_GET_RN_CAPABILITIES_RSP_EVT: { ++ ESP_LOGI(TAG, "remote rn_cap: count %d, bitmask 0x%x", rc->get_rn_caps_rsp.cap_count, ++ rc->get_rn_caps_rsp.evt_set.bits); ++ s_avrc_peer_rn_cap.bits = rc->get_rn_caps_rsp.evt_set.bits; ++ bt_av_new_track(); ++ bt_av_playback_changed(); ++ bt_av_play_pos_changed(); + break; + } + default: +@@ -358,45 +430,45 @@ static void bt_avrc_tg_cb(esp_avrc_tg_cb_event_t event, esp_avrc_tg_cb_param_t * + ESP_LOGD(TAG, "%s evt %d", __func__, event); + esp_avrc_tg_cb_param_t *rc = (esp_avrc_tg_cb_param_t *)(param); + switch (event) { +- case ESP_AVRC_TG_CONNECTION_STATE_EVT: { +- uint8_t *bda = rc->conn_stat.remote_bda; +- ESP_LOGI(TAG, "AVRC conn_state evt: state %d, [%02x:%02x:%02x:%02x:%02x:%02x]", +- rc->conn_stat.connected, bda[0], bda[1], bda[2], bda[3], bda[4], bda[5]); +- avrcp_conn_tg_state = rc->conn_stat.connected; +- break; +- } +- case ESP_AVRC_TG_PASSTHROUGH_CMD_EVT: { +- ESP_LOGI(TAG, "AVRC passthrough cmd: key_code 0x%x, key_state %d", rc->psth_cmd.key_code, rc->psth_cmd.key_state); +- break; +- } +- case ESP_AVRC_TG_SET_ABSOLUTE_VOLUME_CMD_EVT: { +- ESP_LOGI(TAG, "AVRC set absolute volume: %d%%", (int)rc->set_abs_vol.volume * 100/ 0x7f); +- bt_avrc_volume_set_by_controller(rc->set_abs_vol.volume); +- break; +- } +- case ESP_AVRC_TG_REGISTER_NOTIFICATION_EVT: { +- ESP_LOGI(TAG, "AVRC register event notification: %d, param: 0x%x", rc->reg_ntf.event_id, rc->reg_ntf.event_parameter); +- if (rc->reg_ntf.event_id == ESP_AVRC_RN_VOLUME_CHANGE) { +- g_volume_notify = true; +- esp_avrc_rn_param_t rn_param; +- rn_param.volume = g_volume; +- esp_avrc_tg_send_rn_rsp(ESP_AVRC_RN_VOLUME_CHANGE, ESP_AVRC_RN_RSP_INTERIM, &rn_param); +- } +- break; +- } +- case ESP_AVRC_TG_REMOTE_FEATURES_EVT: { +- ESP_LOGI(TAG, "AVRC remote features %x, CT features %x", rc->rmt_feats.feat_mask, rc->rmt_feats.ct_feat_flag); +- break; +- } +- default: +- ESP_LOGE(TAG, "%s unhandled evt %d", __func__, event); +- break; ++ case ESP_AVRC_TG_CONNECTION_STATE_EVT: { ++ uint8_t *bda = rc->conn_stat.remote_bda; ++ ESP_LOGI(TAG, "AVRC conn_state evt: state %d, [%02x:%02x:%02x:%02x:%02x:%02x]", ++ rc->conn_stat.connected, bda[0], bda[1], bda[2], bda[3], bda[4], bda[5]); ++ avrcp_conn_tg_state = rc->conn_stat.connected; ++ break; ++ } ++ case ESP_AVRC_TG_PASSTHROUGH_CMD_EVT: { ++ ESP_LOGI(TAG, "AVRC passthrough cmd: key_code 0x%x, key_state %d", rc->psth_cmd.key_code, rc->psth_cmd.key_state); ++ break; ++ } ++ case ESP_AVRC_TG_SET_ABSOLUTE_VOLUME_CMD_EVT: { ++ ESP_LOGI(TAG, "AVRC set absolute volume: %d%%", (int)rc->set_abs_vol.volume * 100 / 0x7f); ++ bt_avrc_volume_set_by_controller(rc->set_abs_vol.volume); ++ break; ++ } ++ case ESP_AVRC_TG_REGISTER_NOTIFICATION_EVT: { ++ ESP_LOGI(TAG, "AVRC register event notification: %d, param: 0x%x", rc->reg_ntf.event_id, rc->reg_ntf.event_parameter); ++ if (rc->reg_ntf.event_id == ESP_AVRC_RN_VOLUME_CHANGE) { ++ g_volume_notify = true; ++ esp_avrc_rn_param_t rn_param; ++ rn_param.volume = g_volume; ++ esp_avrc_tg_send_rn_rsp(ESP_AVRC_RN_VOLUME_CHANGE, ESP_AVRC_RN_RSP_INTERIM, &rn_param); ++ } ++ break; ++ } ++ case ESP_AVRC_TG_REMOTE_FEATURES_EVT: { ++ ESP_LOGI(TAG, "AVRC remote features %x, CT features %x", rc->rmt_feats.feat_mask, rc->rmt_feats.ct_feat_flag); ++ break; ++ } ++ default: ++ ESP_LOGE(TAG, "%s unhandled evt %d", __func__, event); ++ break; + } + } + #endif + + static esp_err_t _bt_avrc_periph_init(esp_periph_handle_t periph) +-{ ++{ + return ESP_OK; + } + +@@ -428,7 +500,7 @@ static esp_err_t periph_bt_avrc_passthrough_cmd(esp_periph_handle_t periph, uint + esp_err_t err = ESP_OK; + + #if (ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(4, 0, 0)) +- if(avrcp_conn_tg_state) { ++ if (avrcp_conn_tg_state) { + if (cmd == ESP_AVRC_PT_CMD_VOL_DOWN) { + int16_t volume = (g_volume - 5) < 0 ? 0 : (g_volume - 5); + bt_avrc_volume_set_by_local(volume); diff --git a/examples/korvo_du1906/sdkconfig.defaults b/examples/korvo_du1906/sdkconfig.defaults index 25cf5e5..308a42d 100644 --- a/examples/korvo_du1906/sdkconfig.defaults +++ b/examples/korvo_du1906/sdkconfig.defaults @@ -15,78 +15,37 @@ CONFIG_MAKE_WARN_UNDEFINED_VARIABLES=y # # Application manager # -CONFIG_APP_COMPILE_TIME_DATE=y -CONFIG_APP_EXCLUDE_PROJECT_VER_VAR=y -CONFIG_APP_EXCLUDE_PROJECT_NAME_VAR=y -CONFIG_APP_RETRIEVE_LEN_ELF_SHA=16 # # Audio HAL # -CONFIG_AUDIO_BOARD_CUSTOM= -CONFIG_ESP_LYRAT_V4_3_BOARD= -CONFIG_ESP_LYRAT_V4_2_BOARD= -CONFIG_ESP_LYRATD_MSC_V2_1_BOARD= -CONFIG_ESP_LYRATD_MSC_V2_2_BOARD= -CONFIG_ESP_LYRAT_MINI_V1_1_BOARD= CONFIG_ESP32_KORVO_DU1906_BOARD=y -CONFIG_ESP32_S2_KALUGA_1_V1_2_BOARD= CONFIG_ESP32_KORVO_DU1906_DAC_TAS5805M=y -CONFIG_ESP32_KORVO_DU1906_DAC_ES7148= CONFIG_ESP32_KORVO_DU1906_ADC_ES7243=y # # Bootloader config # -CONFIG_LOG_BOOTLOADER_LEVEL_NONE= -CONFIG_LOG_BOOTLOADER_LEVEL_ERROR= -CONFIG_LOG_BOOTLOADER_LEVEL_WARN= CONFIG_LOG_BOOTLOADER_LEVEL_INFO=y -CONFIG_LOG_BOOTLOADER_LEVEL_DEBUG= -CONFIG_LOG_BOOTLOADER_LEVEL_VERBOSE= CONFIG_LOG_BOOTLOADER_LEVEL=3 CONFIG_BOOTLOADER_SPI_WP_PIN=7 CONFIG_BOOTLOADER_VDDSDIO_BOOST_1_9V=y -CONFIG_BOOTLOADER_FACTORY_RESET= -CONFIG_BOOTLOADER_APP_TEST= CONFIG_BOOTLOADER_WDT_ENABLE=y -CONFIG_BOOTLOADER_WDT_DISABLE_IN_USER_CODE= CONFIG_BOOTLOADER_WDT_TIME_MS=9000 -CONFIG_APP_ROLLBACK_ENABLE= -# -# Security features -# -CONFIG_SECURE_SIGNED_APPS_NO_SECURE_BOOT= -CONFIG_SECURE_BOOT_ENABLED= -CONFIG_FLASH_ENCRYPTION_ENABLED= # # Recorder Engine Configuration # -CONFIG_REC_ENG_ENABLE_VAD_ONLY= -CONFIG_REC_ENG_ENABLE_VAD_WWE= CONFIG_REC_ENG_ENABLE_VAD_WWE_AMR=y # # ESP Speech Recognition # -CONFIG_SR_MODEL_WN3_QUANT= -CONFIG_SR_MODEL_WN4_QUANT= CONFIG_SR_MODEL_WN5_QUANT=y -CONFIG_SR_MODEL_WN6_QUANT= CONFIG_SR_WN5_HILEXIN=y -CONFIG_SR_WN5X2_HILEXIN= -CONFIG_SR_WN5X3_HILEXIN= -CONFIG_SR_WN5_NIHAOXIAOZHI= -CONFIG_SR_WN5X2_NIHAOXIAOZHI= -CONFIG_SR_WN5X3_NIHAOXIAOZHI= -CONFIG_SR_WN5X3_HIJESON= -CONFIG_SR_WN5X3_NIHAOXIAOXIN= -CONFIG_SR_WN5_CUSTOMIZED_WORD= CONFIG_SR_MN1_MODEL_QUANT=y CONFIG_SR_MN1_CHINESE=y -CONFIG_SR_MN1_ENGLISH= CONFIG_SPEECH_COMMANDS_NUM=20 # @@ -193,48 +152,33 @@ CONFIG_CN_SPEECH_COMMAND_ID97="" CONFIG_CN_SPEECH_COMMAND_ID98="" CONFIG_CN_SPEECH_COMMAND_ID99="" +# +# ADF Features +# +CONFIG_ESP_DISPATCHER_DELEGATE_TASK_CORE=0 +CONFIG_ESP_DISPATCHER_DELEGATE_TASK_PRIO=10 +CONFIG_ESP_DISPATCHER_DELEGATE_STACK_SIZE=4096 + # # Serial flasher config # CONFIG_ESPTOOLPY_PORT="/dev/ttyUSB0" -CONFIG_ESPTOOLPY_BAUD_115200B= -CONFIG_ESPTOOLPY_BAUD_230400B= -CONFIG_ESPTOOLPY_BAUD_921600B= CONFIG_ESPTOOLPY_BAUD_2MB=y -CONFIG_ESPTOOLPY_BAUD_OTHER= CONFIG_ESPTOOLPY_BAUD_OTHER_VAL=115200 CONFIG_ESPTOOLPY_BAUD=2000000 CONFIG_ESPTOOLPY_COMPRESSED=y CONFIG_FLASHMODE_QIO=y -CONFIG_FLASHMODE_QOUT= -CONFIG_FLASHMODE_DIO= -CONFIG_FLASHMODE_DOUT= CONFIG_ESPTOOLPY_FLASHMODE="dio" CONFIG_ESPTOOLPY_FLASHFREQ_80M=y -CONFIG_ESPTOOLPY_FLASHFREQ_40M= -CONFIG_ESPTOOLPY_FLASHFREQ_26M= -CONFIG_ESPTOOLPY_FLASHFREQ_20M= CONFIG_ESPTOOLPY_FLASHFREQ="80m" -CONFIG_ESPTOOLPY_FLASHSIZE_1MB= -CONFIG_ESPTOOLPY_FLASHSIZE_2MB= -CONFIG_ESPTOOLPY_FLASHSIZE_4MB= CONFIG_ESPTOOLPY_FLASHSIZE_8MB=y -CONFIG_ESPTOOLPY_FLASHSIZE_16MB= CONFIG_ESPTOOLPY_FLASHSIZE="8MB" CONFIG_ESPTOOLPY_FLASHSIZE_DETECT=y CONFIG_ESPTOOLPY_BEFORE_RESET=y -CONFIG_ESPTOOLPY_BEFORE_NORESET= CONFIG_ESPTOOLPY_BEFORE="default_reset" CONFIG_ESPTOOLPY_AFTER_RESET=y -CONFIG_ESPTOOLPY_AFTER_NORESET= CONFIG_ESPTOOLPY_AFTER="hard_reset" -CONFIG_MONITOR_BAUD_9600B= -CONFIG_MONITOR_BAUD_57600B= -CONFIG_MONITOR_BAUD_115200B= -CONFIG_MONITOR_BAUD_230400B= CONFIG_MONITOR_BAUD_921600B=y -CONFIG_MONITOR_BAUD_2MB= -CONFIG_MONITOR_BAUD_OTHER= CONFIG_MONITOR_BAUD_OTHER_VAL=115200 CONFIG_MONITOR_BAUD=921600 @@ -243,54 +187,28 @@ CONFIG_MONITOR_BAUD=921600 # CONFIG_WIFI_SSID="iot" CONFIG_WIFI_PASSWORD="123456789" -CONFIG_ESP_SMARTCONFIG= -CONFIG_ESP_BLUFI=y -CONFIG_AIRKISS_ENCRYPT= # # Partition Table # -CONFIG_PARTITION_TABLE_SINGLE_APP= -CONFIG_PARTITION_TABLE_TWO_OTA= CONFIG_PARTITION_TABLE_CUSTOM=y CONFIG_PARTITION_TABLE_CUSTOM_FILENAME="partitions.csv" CONFIG_PARTITION_TABLE_FILENAME="partitions.csv" CONFIG_PARTITION_TABLE_OFFSET=0x8000 CONFIG_PARTITION_TABLE_MD5=y -# -# Recorder Engine Configuration -# - # # Compiler options # -CONFIG_OPTIMIZATION_LEVEL_DEBUG= CONFIG_OPTIMIZATION_LEVEL_RELEASE=y CONFIG_OPTIMIZATION_ASSERTIONS_ENABLED=y -CONFIG_OPTIMIZATION_ASSERTIONS_SILENT= -CONFIG_OPTIMIZATION_ASSERTIONS_DISABLED= -CONFIG_CXX_EXCEPTIONS= CONFIG_STACK_CHECK_NONE=y -CONFIG_STACK_CHECK_NORM= -CONFIG_STACK_CHECK_STRONG= -CONFIG_STACK_CHECK_ALL= -CONFIG_STACK_CHECK= -CONFIG_WARN_WRITE_STRINGS= -CONFIG_DISABLE_GCC8_WARNINGS= - -# -# Component config -# # # Application Level Tracing # -CONFIG_ESP32_APPTRACE_DEST_TRAX= CONFIG_ESP32_APPTRACE_DEST_NONE=y -CONFIG_ESP32_APPTRACE_ENABLE= CONFIG_ESP32_APPTRACE_LOCK_ENABLE=y -CONFIG_AWS_IOT_SDK= # # Bluetooth @@ -300,31 +218,22 @@ CONFIG_BT_ENABLED=y # # Bluetooth controller # -CONFIG_BTDM_CONTROLLER_MODE_BLE_ONLY= -CONFIG_BTDM_CONTROLLER_MODE_BR_EDR_ONLY= CONFIG_BTDM_CONTROLLER_MODE_BTDM=y -CONFIG_BTDM_CONTROLLER_BLE_MAX_CONN=2 +CONFIG_BTDM_CONTROLLER_BLE_MAX_CONN=1 CONFIG_BTDM_CONTROLLER_BR_EDR_MAX_ACL_CONN=2 CONFIG_BTDM_CONTROLLER_BR_EDR_MAX_SYNC_CONN=0 CONFIG_BTDM_CTRL_BR_EDR_SCO_DATA_PATH_EFF=0 -CONFIG_BTDM_CTRL_AUTO_LATENCY= -CONFIG_BTDM_CTRL_AUTO_LATENCY_EFF= -CONFIG_BTDM_CONTROLLER_BLE_MAX_CONN_EFF=2 +CONFIG_BTDM_CONTROLLER_BLE_MAX_CONN_EFF=1 CONFIG_BTDM_CONTROLLER_BR_EDR_MAX_ACL_CONN_EFF=2 CONFIG_BTDM_CONTROLLER_BR_EDR_MAX_SYNC_CONN_EFF=0 -CONFIG_BTDM_CONTROLLER_PINNED_TO_CORE_0= CONFIG_BTDM_CONTROLLER_PINNED_TO_CORE_1=y CONFIG_BTDM_CONTROLLER_PINNED_TO_CORE=1 CONFIG_BTDM_CONTROLLER_HCI_MODE_VHCI=y -CONFIG_BTDM_CONTROLLER_HCI_MODE_UART_H4= # # MODEM SLEEP Options # -CONFIG_BTDM_CONTROLLER_MODEM_SLEEP= CONFIG_BLE_SCAN_DUPLICATE=y -CONFIG_SCAN_DUPLICATE_BY_DEVICE_ADDR= -CONFIG_SCAN_DUPLICATE_BY_ADV_DATA= CONFIG_SCAN_DUPLICATE_BY_ADV_DATA_AND_DEVICE_ADDR=y CONFIG_SCAN_DUPLICATE_TYPE=2 CONFIG_DUPLICATE_SCAN_CACHE_SIZE=20 @@ -337,130 +246,27 @@ CONFIG_BLE_ADV_REPORT_DISCARD_THRSHOLD=20 CONFIG_BTDM_COEX_BT_OPTIONS=y CONFIG_BTDM_COEX_BLE_ADV_HIGH_PRIORITY=y CONFIG_BLUEDROID_ENABLED=y -CONFIG_BLUEDROID_PINNED_TO_CORE_0= CONFIG_BLUEDROID_PINNED_TO_CORE_1=y CONFIG_BLUEDROID_PINNED_TO_CORE=1 CONFIG_BTC_TASK_STACK_SIZE=3072 -CONFIG_BTU_TASK_STACK_SIZE=5120 -CONFIG_BLUEDROID_MEM_DEBUG= +CONFIG_BTU_TASK_STACK_SIZE=4096 CONFIG_CLASSIC_BT_ENABLED=y CONFIG_A2DP_ENABLE=y CONFIG_A2DP_SINK_TASK_STACK_SIZE=3072 CONFIG_A2DP_SOURCE_TASK_STACK_SIZE=128 -CONFIG_BT_SPP_ENABLED= -CONFIG_HFP_ENABLE= CONFIG_BT_SSP_ENABLED=y CONFIG_GATTS_ENABLE=y -CONFIG_GATTS_SEND_SERVICE_CHANGE_MANUAL= CONFIG_GATTS_SEND_SERVICE_CHANGE_AUTO=y CONFIG_GATTS_SEND_SERVICE_CHANGE_MODE=0 CONFIG_GATTC_ENABLE=y -CONFIG_GATTC_CACHE_NVS_FLASH= CONFIG_BLE_SMP_ENABLE=y -CONFIG_SMP_SLAVE_CON_PARAMS_UPD_ENABLE= CONFIG_BT_STACK_NO_LOG=y -CONFIG_BT_ACL_CONNECTIONS=2 +CONFIG_BT_ACL_CONNECTIONS=1 CONFIG_BT_ALLOCATION_FROM_SPIRAM_FIRST=y CONFIG_BT_BLE_DYNAMIC_ENV_MEMORY=y -CONFIG_BLE_HOST_QUEUE_CONGESTION_CHECK= CONFIG_SMP_ENABLE=y -CONFIG_BLE_ACTIVE_SCAN_REPORT_ADV_SCAN_RSP_INDIVIDUALLY= CONFIG_BLE_ESTABLISH_LINK_CONNECTION_TIMEOUT=30 CONFIG_BT_RESERVE_DRAM=0xdb5c -CONFIG_BLE_MESH=y -CONFIG_BLE_MESH_HCI_5_0=y -CONFIG_BLE_MESH_USE_DUPLICATE_SCAN=y -CONFIG_BLE_MESH_ALLOC_FROM_PSRAM_FIRST=y -CONFIG_BLE_MESH_FAST_PROV= -CONFIG_BLE_MESH_NODE= -CONFIG_BLE_MESH_PROVISIONER=y -CONFIG_BLE_MESH_WAIT_FOR_PROV_MAX_DEV_NUM=20 -CONFIG_BLE_MESH_MAX_PROV_NODES=20 -CONFIG_BLE_MESH_PBA_SAME_TIME=2 -CONFIG_BLE_MESH_PBG_SAME_TIME=1 -CONFIG_BLE_MESH_PROVISIONER_SUBNET_COUNT=3 -CONFIG_BLE_MESH_PROVISIONER_APP_KEY_COUNT=9 -CONFIG_BLE_MESH_PROV=y -CONFIG_BLE_MESH_PB_ADV=y -CONFIG_BLE_MESH_PB_GATT=y -CONFIG_BLE_MESH_PROXY=y -CONFIG_BLE_MESH_GATT_PROXY_CLIENT= -CONFIG_BLE_MESH_NET_BUF_POOL_USAGE=y -CONFIG_BLE_MESH_SETTINGS=y -CONFIG_BLE_MESH_SPECIFIC_PARTITION= -CONFIG_BLE_MESH_STORE_TIMEOUT=0 -CONFIG_BLE_MESH_SEQ_STORE_RATE=6 -CONFIG_BLE_MESH_RPL_STORE_TIMEOUT=5 -CONFIG_BLE_MESH_SUBNET_COUNT=3 -CONFIG_BLE_MESH_APP_KEY_COUNT=3 -CONFIG_BLE_MESH_MODEL_KEY_COUNT=3 -CONFIG_BLE_MESH_MODEL_GROUP_COUNT=3 -CONFIG_BLE_MESH_LABEL_COUNT=3 -CONFIG_BLE_MESH_CRPL=10 -CONFIG_BLE_MESH_MSG_CACHE_SIZE=10 -CONFIG_BLE_MESH_ADV_BUF_COUNT=60 -CONFIG_BLE_MESH_SUPPORT_BLE_ADV= -CONFIG_BLE_MESH_IVU_DIVIDER=4 -CONFIG_BLE_MESH_TX_SEG_MSG_COUNT=10 -CONFIG_BLE_MESH_RX_SEG_MSG_COUNT=10 -CONFIG_BLE_MESH_RX_SDU_MAX=384 -CONFIG_BLE_MESH_TX_SEG_MAX=20 -CONFIG_BLE_MESH_FRIEND= -CONFIG_BLE_MESH_NO_LOG= - -# -# BLE Mesh STACK DEBUG LOG LEVEL -# -CONFIG_BLE_MESH_TRACE_LEVEL_NONE= -CONFIG_BLE_MESH_TRACE_LEVEL_ERROR= -CONFIG_BLE_MESH_TRACE_LEVEL_WARNING=y -CONFIG_BLE_MESH_TRACE_LEVEL_INFO= -CONFIG_BLE_MESH_TRACE_LEVEL_DEBUG= -CONFIG_BLE_MESH_TRACE_LEVEL_VERBOSE= -CONFIG_BLE_MESH_STACK_TRACE_LEVEL=2 - -# -# BLE Mesh NET BUF DEBUG LOG LEVEL -# -CONFIG_BLE_MESH_NET_BUF_TRACE_LEVEL_NONE= -CONFIG_BLE_MESH_NET_BUF_TRACE_LEVEL_ERROR= -CONFIG_BLE_MESH_NET_BUF_TRACE_LEVEL_WARNING=y -CONFIG_BLE_MESH_NET_BUF_TRACE_LEVEL_INFO= -CONFIG_BLE_MESH_NET_BUF_TRACE_LEVEL_DEBUG= -CONFIG_BLE_MESH_NET_BUF_TRACE_LEVEL_VERBOSE= -CONFIG_BLE_MESH_NET_BUF_TRACE_LEVEL=2 -CONFIG_BLE_MESH_CLIENT_MSG_TIMEOUT=4000 - -# -# Support for BLE Mesh Client Models -# -CONFIG_BLE_MESH_CFG_CLI=y -CONFIG_BLE_MESH_HEALTH_CLI= -CONFIG_BLE_MESH_GENERIC_ONOFF_CLI=y -CONFIG_BLE_MESH_GENERIC_LEVEL_CLI= -CONFIG_BLE_MESH_GENERIC_DEF_TRANS_TIME_CLI= -CONFIG_BLE_MESH_GENERIC_POWER_ONOFF_CLI= -CONFIG_BLE_MESH_GENERIC_POWER_LEVEL_CLI= -CONFIG_BLE_MESH_GENERIC_BATTERY_CLI= -CONFIG_BLE_MESH_GENERIC_LOCATION_CLI= -CONFIG_BLE_MESH_GENERIC_PROPERTY_CLI= -CONFIG_BLE_MESH_SENSOR_CLI= -CONFIG_BLE_MESH_TIME_CLI= -CONFIG_BLE_MESH_SCENE_CLI= -CONFIG_BLE_MESH_SCHEDULER_CLI= -CONFIG_BLE_MESH_LIGHT_LIGHTNESS_CLI= -CONFIG_BLE_MESH_LIGHT_CTL_CLI= -CONFIG_BLE_MESH_LIGHT_HSL_CLI= -CONFIG_BLE_MESH_LIGHT_XYL_CLI= -CONFIG_BLE_MESH_LIGHT_LC_CLI= -CONFIG_BLE_MESH_IV_UPDATE_TEST= - -# -# BLE Mesh specific test option -# -CONFIG_BLE_MESH_SELF_TEST= -CONFIG_BLE_MESH_SHELL= -CONFIG_BLE_MESH_DEBUG= # # Driver configurations @@ -469,38 +275,27 @@ CONFIG_BLE_MESH_DEBUG= # # ADC configuration # -CONFIG_ADC_FORCE_XPD_FSM= CONFIG_ADC2_DISABLE_DAC=y # # SPI configuration # -CONFIG_SPI_MASTER_IN_IRAM= CONFIG_SPI_MASTER_ISR_IN_IRAM=y -CONFIG_SPI_SLAVE_IN_IRAM= CONFIG_SPI_SLAVE_ISR_IN_IRAM=y # # eFuse Bit Manager # -CONFIG_EFUSE_CUSTOM_TABLE= -CONFIG_EFUSE_VIRTUAL= -CONFIG_EFUSE_CODE_SCHEME_COMPAT_NONE= CONFIG_EFUSE_CODE_SCHEME_COMPAT_3_4=y -CONFIG_EFUSE_CODE_SCHEME_COMPAT_REPEAT= CONFIG_EFUSE_MAX_BLK_LEN=192 # # ESP32-specific # CONFIG_IDF_TARGET_ESP32=y -CONFIG_ESP32_REV_MIN_0= -CONFIG_ESP32_REV_MIN_1= -CONFIG_ESP32_REV_MIN_2= +CONFIG_ESP32_ECO3_CACHE_LOCK_FIX=y CONFIG_ESP32_REV_MIN_3=y CONFIG_ESP32_REV_MIN=3 -CONFIG_ESP32_DEFAULT_CPU_FREQ_80= -CONFIG_ESP32_DEFAULT_CPU_FREQ_160= CONFIG_ESP32_DEFAULT_CPU_FREQ_240=y CONFIG_ESP32_DEFAULT_CPU_FREQ_MHZ=240 CONFIG_SPIRAM_SUPPORT=y @@ -509,14 +304,9 @@ CONFIG_SPIRAM_SUPPORT=y # SPI RAM config # CONFIG_SPIRAM_BOOT_INIT=y -CONFIG_SPIRAM_USE_MEMMAP= -CONFIG_SPIRAM_USE_CAPS_ALLOC= CONFIG_SPIRAM_USE_MALLOC=y CONFIG_SPIRAM_TYPE_AUTO=y -CONFIG_SPIRAM_TYPE_ESPPSRAM32= -CONFIG_SPIRAM_TYPE_ESPPSRAM64= CONFIG_SPIRAM_SIZE=-1 -CONFIG_SPIRAM_SPEED_40M= CONFIG_SPIRAM_SPEED_80M=y CONFIG_SPIRAM_MEMTEST=y CONFIG_SPIRAM_BANKSWITCH_ENABLE=y @@ -526,9 +316,7 @@ CONFIG_WIFI_LWIP_ALLOCATION_FROM_SPIRAM_FIRST=y CONFIG_SPIRAM_MALLOC_RESERVE_INTERNAL=18432 CONFIG_SPIRAM_ALLOW_STACK_EXTERNAL_MEMORY=y CONFIG_SPIRAM_ALLOW_BSS_SEG_EXTERNAL_MEMORY=y -CONFIG_SPIRAM_OCCUPY_HSPI_HOST= CONFIG_SPIRAM_OCCUPY_VSPI_HOST=y -CONFIG_SPIRAM_OCCUPY_NO_HOST= # # PSRAM clock and cs IO for ESP32-DOWD @@ -546,12 +334,7 @@ CONFIG_D2WD_PSRAM_CS_IO=10 # PSRAM clock and cs IO for ESP32-PICO # CONFIG_PICO_PSRAM_CS_IO=10 -CONFIG_SPIRAM_2T_MODE= -CONFIG_MEMMAP_TRACEMEM= -CONFIG_MEMMAP_TRACEMEM_TWOBANKS= -CONFIG_ESP32_TRAX= CONFIG_TRACEMEM_RESERVE_DRAM=0x0 -CONFIG_TWO_UNIVERSAL_MAC_ADDRESS= CONFIG_FOUR_UNIVERSAL_MAC_ADDRESS=y CONFIG_NUMBER_OF_UNIVERSAL_MAC_ADDRESS=4 CONFIG_SYSTEM_EVENT_QUEUE_SIZE=32 @@ -560,61 +343,31 @@ CONFIG_MAIN_TASK_STACK_SIZE=4096 CONFIG_IPC_TASK_STACK_SIZE=1024 CONFIG_TIMER_TASK_STACK_SIZE=3584 CONFIG_NEWLIB_STDOUT_LINE_ENDING_CRLF=y -CONFIG_NEWLIB_STDOUT_LINE_ENDING_LF= -CONFIG_NEWLIB_STDOUT_LINE_ENDING_CR= -CONFIG_NEWLIB_STDIN_LINE_ENDING_CRLF= -CONFIG_NEWLIB_STDIN_LINE_ENDING_LF= CONFIG_NEWLIB_STDIN_LINE_ENDING_CR=y -CONFIG_NEWLIB_NANO_FORMAT= CONFIG_CONSOLE_UART_DEFAULT=y -CONFIG_CONSOLE_UART_CUSTOM= -CONFIG_CONSOLE_UART_NONE= CONFIG_CONSOLE_UART_NUM=0 CONFIG_CONSOLE_UART_BAUDRATE=921600 -CONFIG_ULP_COPROC_ENABLED= CONFIG_ULP_COPROC_RESERVE_MEM=0 -CONFIG_ESP32_PANIC_PRINT_HALT= CONFIG_ESP32_PANIC_PRINT_REBOOT=y -CONFIG_ESP32_PANIC_SILENT_REBOOT= -CONFIG_ESP32_PANIC_GDBSTUB= CONFIG_ESP32_DEBUG_OCDAWARE=y -CONFIG_ESP32_DEBUG_STUBS_ENABLE= CONFIG_INT_WDT=y CONFIG_INT_WDT_TIMEOUT_MS=1000 CONFIG_INT_WDT_CHECK_CPU1=y CONFIG_TASK_WDT=y CONFIG_TASK_WDT_PANIC=y -CONFIG_TASK_WDT_TIMEOUT_S=8 +CONFIG_TASK_WDT_TIMEOUT_S=12 CONFIG_TASK_WDT_CHECK_IDLE_TASK_CPU0=y CONFIG_TASK_WDT_CHECK_IDLE_TASK_CPU1=y CONFIG_BROWNOUT_DET=y CONFIG_BROWNOUT_DET_LVL_SEL_0=y -CONFIG_BROWNOUT_DET_LVL_SEL_1= -CONFIG_BROWNOUT_DET_LVL_SEL_2= -CONFIG_BROWNOUT_DET_LVL_SEL_3= -CONFIG_BROWNOUT_DET_LVL_SEL_4= -CONFIG_BROWNOUT_DET_LVL_SEL_5= -CONFIG_BROWNOUT_DET_LVL_SEL_6= -CONFIG_BROWNOUT_DET_LVL_SEL_7= CONFIG_BROWNOUT_DET_LVL=0 CONFIG_REDUCE_PHY_TX_POWER=y CONFIG_ESP32_TIME_SYSCALL_USE_RTC_FRC1=y -CONFIG_ESP32_TIME_SYSCALL_USE_RTC= -CONFIG_ESP32_TIME_SYSCALL_USE_FRC1= -CONFIG_ESP32_TIME_SYSCALL_USE_NONE= CONFIG_ESP32_RTC_CLOCK_SOURCE_INTERNAL_RC=y -CONFIG_ESP32_RTC_CLOCK_SOURCE_EXTERNAL_CRYSTAL= -CONFIG_ESP32_RTC_CLOCK_SOURCE_EXTERNAL_OSC= -CONFIG_ESP32_RTC_CLOCK_SOURCE_INTERNAL_8MD256= CONFIG_ESP32_RTC_CLK_CAL_CYCLES=1024 CONFIG_ESP32_DEEP_SLEEP_WAKEUP_DELAY=2000 -CONFIG_ESP32_XTAL_FREQ_40=y -CONFIG_ESP32_XTAL_FREQ_26= -CONFIG_ESP32_XTAL_FREQ_AUTO= -CONFIG_ESP32_XTAL_FREQ=40 -CONFIG_DISABLE_BASIC_ROM_CONSOLE= -CONFIG_ESP_TIMER_PROFILING= -CONFIG_COMPATIBLE_PRE_V2_1_BOOTLOADERS= +CONFIG_ESP32_XTAL_FREQ_AUTO=y +CONFIG_ESP32_XTAL_FREQ=0 CONFIG_ESP_ERR_TO_NAME_LOOKUP=y CONFIG_ESP32_DPORT_DIS_INTERRUPT_LVL=5 @@ -627,32 +380,28 @@ CONFIG_ESP32_WIFI_DYNAMIC_RX_BUFFER_NUM=512 CONFIG_ESP32_WIFI_STATIC_TX_BUFFER=y CONFIG_ESP32_WIFI_TX_BUFFER_TYPE=0 CONFIG_ESP32_WIFI_STATIC_TX_BUFFER_NUM=16 -CONFIG_ESP32_WIFI_CSI_ENABLED= +CONFIG_ESP32_WIFI_CACHE_TX_BUFFER_NUM=32 CONFIG_ESP32_WIFI_AMPDU_TX_ENABLED=y CONFIG_ESP32_WIFI_TX_BA_WIN=16 CONFIG_ESP32_WIFI_AMPDU_RX_ENABLED=y CONFIG_ESP32_WIFI_RX_BA_WIN=32 CONFIG_ESP32_WIFI_NVS_ENABLED=y CONFIG_ESP32_WIFI_TASK_PINNED_TO_CORE_0=y -CONFIG_ESP32_WIFI_TASK_PINNED_TO_CORE_1= CONFIG_ESP32_WIFI_SOFTAP_BEACON_MAX_LEN=752 CONFIG_ESP32_WIFI_MGMT_SBUF_NUM=32 -CONFIG_ESP32_WIFI_DEBUG_LOG_ENABLE= CONFIG_ESP32_WIFI_IRAM_OPT=y -CONFIG_ESP32_WIFI_RX_IRAM_OPT= # # PHY # CONFIG_ESP32_PHY_CALIBRATION_AND_DATA_STORAGE=y -CONFIG_ESP32_PHY_INIT_DATA_IN_PARTITION= +CONFIG_ESP32_PHY_INIT_DATA_IN_PARTITION=y CONFIG_ESP32_PHY_MAX_WIFI_TX_POWER=20 CONFIG_ESP32_PHY_MAX_TX_POWER=20 # # Power Management # -CONFIG_PM_ENABLE= # # ADC-Calibration @@ -661,16 +410,18 @@ CONFIG_ADC_CAL_EFUSE_TP_ENABLE=y CONFIG_ADC_CAL_EFUSE_VREF_ENABLE=y CONFIG_ADC_CAL_LUT_ENABLE=y +# +# ESP DEBUG +# + # # Event Loop Library # -CONFIG_EVENT_LOOP_PROFILING= # # ESP HTTP client # CONFIG_ESP_HTTP_CLIENT_ENABLE_HTTPS=y -CONFIG_ESP_HTTP_CLIENT_ENABLE_BASIC_AUTH= # # HTTP Server @@ -679,29 +430,25 @@ CONFIG_HTTPD_MAX_REQ_HDR_LEN=512 CONFIG_HTTPD_MAX_URI_LEN=512 CONFIG_HTTPD_ERR_RESP_NO_DELAY=y CONFIG_HTTPD_PURGE_BUF_LEN=32 -CONFIG_HTTPD_LOG_PURGE_DATA= # # ESP HTTPS OTA # -CONFIG_OTA_ALLOW_HTTP= +CONFIG_OTA_ALLOW_HTTP=y # # Core dump # -CONFIG_ESP32_ENABLE_COREDUMP_TO_FLASH= CONFIG_ESP32_ENABLE_COREDUMP_TO_UART=y -CONFIG_ESP32_ENABLE_COREDUMP_TO_NONE= CONFIG_ESP32_ENABLE_COREDUMP=y CONFIG_ESP32_CORE_DUMP_MAX_TASKS_NUM=64 -CONFIG_ESP32_CORE_DUMP_UART_DELAY=100 +CONFIG_ESP32_CORE_DUMP_UART_DELAY=0 # # Ethernet # CONFIG_DMA_RX_BUF_NUM=10 CONFIG_DMA_TX_BUF_NUM=10 -CONFIG_EMAC_L2_TO_L3_RX_BUF_MODE= CONFIG_EMAC_CHECK_LINK_PERIOD_MS=2000 CONFIG_EMAC_TASK_PRIORITY=20 CONFIG_EMAC_TASK_STACK_SIZE=3072 @@ -709,35 +456,10 @@ CONFIG_EMAC_TASK_STACK_SIZE=3072 # # FAT Filesystem support # -CONFIG_FATFS_CODEPAGE_DYNAMIC= -CONFIG_FATFS_CODEPAGE_437= -CONFIG_FATFS_CODEPAGE_720= -CONFIG_FATFS_CODEPAGE_737= -CONFIG_FATFS_CODEPAGE_771= -CONFIG_FATFS_CODEPAGE_775= -CONFIG_FATFS_CODEPAGE_850= -CONFIG_FATFS_CODEPAGE_852= -CONFIG_FATFS_CODEPAGE_855= -CONFIG_FATFS_CODEPAGE_857= -CONFIG_FATFS_CODEPAGE_860= -CONFIG_FATFS_CODEPAGE_861= -CONFIG_FATFS_CODEPAGE_862= -CONFIG_FATFS_CODEPAGE_863= -CONFIG_FATFS_CODEPAGE_864= -CONFIG_FATFS_CODEPAGE_865= -CONFIG_FATFS_CODEPAGE_866= -CONFIG_FATFS_CODEPAGE_869= -CONFIG_FATFS_CODEPAGE_932= CONFIG_FATFS_CODEPAGE_936=y -CONFIG_FATFS_CODEPAGE_949= -CONFIG_FATFS_CODEPAGE_950= CONFIG_FATFS_CODEPAGE=936 -CONFIG_FATFS_LFN_NONE= CONFIG_FATFS_LFN_HEAP=y -CONFIG_FATFS_LFN_STACK= CONFIG_FATFS_MAX_LFN=255 -CONFIG_FATFS_API_ENCODING_ANSI_OEM= -CONFIG_FATFS_API_ENCODING_UTF_16= CONFIG_FATFS_API_ENCODING_UTF_8=y CONFIG_FATFS_FS_LOCK=2 CONFIG_FATFS_TIMEOUT_MS=10000 @@ -751,7 +473,6 @@ CONFIG_MB_QUEUE_LENGTH=20 CONFIG_MB_SERIAL_TASK_STACK_SIZE=2048 CONFIG_MB_SERIAL_BUF_SIZE=256 CONFIG_MB_SERIAL_TASK_PRIO=10 -CONFIG_MB_CONTROLLER_SLAVE_ID_SUPPORT= CONFIG_MB_CONTROLLER_NOTIFY_TIMEOUT=20 CONFIG_MB_CONTROLLER_NOTIFY_QUEUE_SIZE=20 CONFIG_MB_CONTROLLER_STACK_SIZE=4096 @@ -763,93 +484,60 @@ CONFIG_MB_TIMER_INDEX=0 # # FreeRTOS # -CONFIG_FREERTOS_UNICORE= CONFIG_FREERTOS_NO_AFFINITY=0x7FFFFFFF CONFIG_FREERTOS_CORETIMER_0=y -CONFIG_FREERTOS_CORETIMER_1= CONFIG_FREERTOS_HZ=1000 -CONFIG_FREERTOS_ASSERT_ON_UNTESTED_FUNCTION=y -CONFIG_FREERTOS_CHECK_STACKOVERFLOW_NONE= -CONFIG_FREERTOS_CHECK_STACKOVERFLOW_PTRVAL= CONFIG_FREERTOS_CHECK_STACKOVERFLOW_CANARY=y -CONFIG_FREERTOS_WATCHPOINT_END_OF_STACK= CONFIG_FREERTOS_INTERRUPT_BACKTRACE=y CONFIG_FREERTOS_THREAD_LOCAL_STORAGE_POINTERS=1 CONFIG_FREERTOS_ASSERT_FAIL_ABORT=y -CONFIG_FREERTOS_ASSERT_FAIL_PRINT_CONTINUE= -CONFIG_FREERTOS_ASSERT_DISABLE= -CONFIG_FREERTOS_IDLE_TASK_STACKSIZE=1536 +CONFIG_FREERTOS_IDLE_TASK_STACKSIZE=1024 CONFIG_FREERTOS_ISR_STACKSIZE=1536 -CONFIG_FREERTOS_LEGACY_HOOKS= CONFIG_FREERTOS_MAX_TASK_NAME_LEN=16 CONFIG_SUPPORT_STATIC_ALLOCATION=y -CONFIG_ENABLE_STATIC_TASK_CLEAN_UP_HOOK= CONFIG_TIMER_TASK_PRIORITY=22 -CONFIG_TIMER_TASK_STACK_DEPTH=2048 +CONFIG_TIMER_TASK_STACK_DEPTH=4096 CONFIG_TIMER_QUEUE_LENGTH=10 CONFIG_FREERTOS_QUEUE_REGISTRY_SIZE=0 CONFIG_FREERTOS_USE_TRACE_FACILITY=y CONFIG_FREERTOS_USE_STATS_FORMATTING_FUNCTIONS=y CONFIG_FREERTOS_VTASKLIST_INCLUDE_COREID=y -CONFIG_FREERTOS_GENERATE_RUN_TIME_STATS= -CONFIG_FREERTOS_DEBUG_INTERNALS= +CONFIG_FREERTOS_GENERATE_RUN_TIME_STATS=y +CONFIG_FREERTOS_RUN_TIME_STATS_USING_ESP_TIMER=y CONFIG_FREERTOS_CHECK_MUTEX_GIVEN_BY_OWNER=y -CONFIG_FREERTOS_CHECK_PORT_CRITICAL_COMPLIANCE= # # Heap memory debugging # CONFIG_HEAP_POISONING_DISABLED=y -CONFIG_HEAP_POISONING_LIGHT= -CONFIG_HEAP_POISONING_COMPREHENSIVE= -CONFIG_HEAP_TRACING= # # libsodium # -CONFIG_LIBSODIUM_USE_MBEDTLS_SHA=y # # Log output # -CONFIG_LOG_DEFAULT_LEVEL_NONE= -CONFIG_LOG_DEFAULT_LEVEL_ERROR= -CONFIG_LOG_DEFAULT_LEVEL_WARN= -CONFIG_LOG_DEFAULT_LEVEL_INFO= -CONFIG_LOG_DEFAULT_LEVEL_DEBUG=y -CONFIG_LOG_DEFAULT_LEVEL_VERBOSE= -CONFIG_LOG_DEFAULT_LEVEL=4 +CONFIG_LOG_DEFAULT_LEVEL_INFO=y +CONFIG_LOG_DEFAULT_LEVEL=3 CONFIG_LOG_COLORS=y # # LWIP # -CONFIG_L2_TO_L3_COPY= -CONFIG_ETHARP_SUPPORT_VLAN= -CONFIG_LWIP_IRAM_OPTIMIZATION= CONFIG_LWIP_MAX_SOCKETS=15 -CONFIG_LWIP_RANDOMIZE_INITIAL_LOCAL_PORTS=y -CONFIG_USE_ONLY_LWIP_SELECT= CONFIG_LWIP_SO_REUSE=y CONFIG_LWIP_SO_REUSE_RXTOALL=y -CONFIG_LWIP_SO_RCVBUF= -CONFIG_LWIP_IP_FRAG= -CONFIG_LWIP_IP_REASSEMBLY= -CONFIG_LWIP_STATS= -CONFIG_LWIP_ETHARP_TRUST_IP_MAC= CONFIG_ESP_GRATUITOUS_ARP=y CONFIG_GARP_TMR_INTERVAL=60 CONFIG_TCPIP_RECVMBOX_SIZE=512 CONFIG_LWIP_DHCP_DOES_ARP_CHECK=y -CONFIG_LWIP_DHCP_RESTORE_LAST_IP= # # DHCP server # CONFIG_LWIP_DHCPS_LEASE_UNIT=60 CONFIG_LWIP_DHCPS_MAX_STATION_NUM=8 -CONFIG_LWIP_AUTOIP= -CONFIG_LWIP_IPV6_AUTOCONFIG= CONFIG_LWIP_NETIF_LOOPBACK=y CONFIG_LWIP_LOOPBACK_MAX_PBUFS=8 @@ -864,12 +552,9 @@ CONFIG_TCP_MSS=1436 CONFIG_TCP_MSL=60000 CONFIG_TCP_SND_BUF_DEFAULT=65535 CONFIG_TCP_WND_DEFAULT=65535 -CONFIG_TCP_RECVMBOX_SIZE=512 +CONFIG_TCP_RECVMBOX_SIZE=128 CONFIG_TCP_QUEUE_OOSEQ=y -CONFIG_ESP_TCP_KEEP_CONNECTION_WHEN_IP_CHANGES= CONFIG_TCP_OVERSIZE_MSS=y -CONFIG_TCP_OVERSIZE_QUARTER_MSS= -CONFIG_TCP_OVERSIZE_DISABLE= CONFIG_LWIP_WND_SCALE=y CONFIG_TCP_RCV_SCALE=3 @@ -880,16 +565,11 @@ CONFIG_LWIP_MAX_UDP_PCBS=16 CONFIG_UDP_RECVMBOX_SIZE=6 CONFIG_TCPIP_TASK_STACK_SIZE=2560 CONFIG_TCPIP_TASK_AFFINITY_NO_AFFINITY=y -CONFIG_TCPIP_TASK_AFFINITY_CPU0= -CONFIG_TCPIP_TASK_AFFINITY_CPU1= CONFIG_TCPIP_TASK_AFFINITY=0x7FFFFFFF -CONFIG_PPP_SUPPORT= # # ICMP # -CONFIG_LWIP_MULTICAST_PING= -CONFIG_LWIP_BROADCAST_PING= # # LWIP RAW API @@ -901,29 +581,19 @@ CONFIG_LWIP_MAX_RAW_PCBS=16 # CONFIG_LWIP_DHCP_MAX_NTP_SERVERS=1 CONFIG_LWIP_SNTP_UPDATE_DELAY=3600000 -CONFIG_LWIP_ESP_LWIP_ASSERT=y # # mbedTLS # -CONFIG_MBEDTLS_INTERNAL_MEM_ALLOC= CONFIG_MBEDTLS_EXTERNAL_MEM_ALLOC=y -CONFIG_MBEDTLS_DEFAULT_MEM_ALLOC= -CONFIG_MBEDTLS_CUSTOM_MEM_ALLOC= CONFIG_MBEDTLS_SSL_MAX_CONTENT_LEN=16384 -CONFIG_MBEDTLS_ASYMMETRIC_CONTENT_LEN= -CONFIG_MBEDTLS_DEBUG= -CONFIG_MBEDTLS_ECP_RESTARTABLE= -CONFIG_MBEDTLS_CMAC_C= -CONFIG_MBEDTLS_HARDWARE_AES= -CONFIG_MBEDTLS_HARDWARE_MPI= -CONFIG_MBEDTLS_HARDWARE_SHA= +CONFIG_MBEDTLS_HARDWARE_AES=y +CONFIG_MBEDTLS_HARDWARE_MPI=y +CONFIG_MBEDTLS_MPI_USE_INTERRUPT=y +CONFIG_MBEDTLS_HARDWARE_SHA=y CONFIG_MBEDTLS_HAVE_TIME=y -CONFIG_MBEDTLS_HAVE_TIME_DATE= +CONFIG_MBEDTLS_HAVE_TIME_DATE=y CONFIG_MBEDTLS_TLS_SERVER_AND_CLIENT=y -CONFIG_MBEDTLS_TLS_SERVER_ONLY= -CONFIG_MBEDTLS_TLS_CLIENT_ONLY= -CONFIG_MBEDTLS_TLS_DISABLED= CONFIG_MBEDTLS_TLS_SERVER=y CONFIG_MBEDTLS_TLS_CLIENT=y CONFIG_MBEDTLS_TLS_ENABLED=y @@ -931,20 +601,15 @@ CONFIG_MBEDTLS_TLS_ENABLED=y # # TLS Key Exchange Methods # -CONFIG_MBEDTLS_PSK_MODES= CONFIG_MBEDTLS_KEY_EXCHANGE_RSA=y CONFIG_MBEDTLS_KEY_EXCHANGE_DHE_RSA=y CONFIG_MBEDTLS_KEY_EXCHANGE_ELLIPTIC_CURVE=y CONFIG_MBEDTLS_KEY_EXCHANGE_ECDHE_RSA=y -CONFIG_MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA=y -CONFIG_MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA=y CONFIG_MBEDTLS_KEY_EXCHANGE_ECDH_RSA=y CONFIG_MBEDTLS_SSL_RENEGOTIATION=y -CONFIG_MBEDTLS_SSL_PROTO_SSL3= CONFIG_MBEDTLS_SSL_PROTO_TLS1=y CONFIG_MBEDTLS_SSL_PROTO_TLS1_1=y CONFIG_MBEDTLS_SSL_PROTO_TLS1_2=y -CONFIG_MBEDTLS_SSL_PROTO_DTLS= CONFIG_MBEDTLS_SSL_ALPN=y CONFIG_MBEDTLS_SSL_SESSION_TICKETS=y @@ -952,16 +617,9 @@ CONFIG_MBEDTLS_SSL_SESSION_TICKETS=y # Symmetric Ciphers # CONFIG_MBEDTLS_AES_C=y -CONFIG_MBEDTLS_CAMELLIA_C= -CONFIG_MBEDTLS_DES_C= CONFIG_MBEDTLS_RC4_DISABLED=y -CONFIG_MBEDTLS_RC4_ENABLED_NO_DEFAULT= -CONFIG_MBEDTLS_RC4_ENABLED= -CONFIG_MBEDTLS_BLOWFISH_C= -CONFIG_MBEDTLS_XTEA_C= CONFIG_MBEDTLS_CCM_C=y CONFIG_MBEDTLS_GCM_C=y -CONFIG_MBEDTLS_RIPEMD160_C= # # Certificates @@ -972,9 +630,6 @@ CONFIG_MBEDTLS_X509_CRL_PARSE_C=y CONFIG_MBEDTLS_X509_CSR_PARSE_C=y CONFIG_MBEDTLS_ECP_C=y CONFIG_MBEDTLS_ECDH_C=y -CONFIG_MBEDTLS_ECDSA_C=y -CONFIG_MBEDTLS_ECP_DP_SECP192R1_ENABLED=y -CONFIG_MBEDTLS_ECP_DP_SECP224R1_ENABLED=y CONFIG_MBEDTLS_ECP_DP_SECP256R1_ENABLED=y CONFIG_MBEDTLS_ECP_DP_SECP384R1_ENABLED=y CONFIG_MBEDTLS_ECP_DP_SECP521R1_ENABLED=y @@ -999,20 +654,11 @@ CONFIG_MQTT_PROTOCOL_311=y CONFIG_MQTT_TRANSPORT_SSL=y CONFIG_MQTT_TRANSPORT_WEBSOCKET=y CONFIG_MQTT_TRANSPORT_WEBSOCKET_SECURE=y -CONFIG_MQTT_USE_CUSTOM_CONFIG= -CONFIG_MQTT_TASK_CORE_SELECTION_ENABLED= -CONFIG_MQTT_CUSTOM_OUTBOX= - -# -# NVS -# # # OpenSSL # -CONFIG_OPENSSL_DEBUG= CONFIG_OPENSSL_ASSERT_DO_NOTHING=y -CONFIG_OPENSSL_ASSERT_EXIT= # # PThreads @@ -1021,20 +667,14 @@ CONFIG_ESP32_PTHREAD_TASK_PRIO_DEFAULT=5 CONFIG_ESP32_PTHREAD_TASK_STACK_SIZE_DEFAULT=3072 CONFIG_PTHREAD_STACK_MIN=768 CONFIG_ESP32_DEFAULT_PTHREAD_CORE_NO_AFFINITY=y -CONFIG_ESP32_DEFAULT_PTHREAD_CORE_0= -CONFIG_ESP32_DEFAULT_PTHREAD_CORE_1= CONFIG_ESP32_PTHREAD_TASK_CORE_DEFAULT=-1 CONFIG_ESP32_PTHREAD_TASK_NAME_DEFAULT="pthread" # # SPI Flash driver # -CONFIG_SPI_FLASH_VERIFY_WRITE= -CONFIG_SPI_FLASH_ENABLE_COUNTERS= CONFIG_SPI_FLASH_ROM_DRIVER_PATCH=y CONFIG_SPI_FLASH_WRITING_DANGEROUS_REGIONS_ABORTS=y -CONFIG_SPI_FLASH_WRITING_DANGEROUS_REGIONS_FAILS= -CONFIG_SPI_FLASH_WRITING_DANGEROUS_REGIONS_ALLOWED= CONFIG_SPI_FLASH_YIELD_DURING_ERASE=y CONFIG_SPI_FLASH_ERASE_YIELD_DURATION_MS=20 CONFIG_SPI_FLASH_ERASE_YIELD_TICKS=1 @@ -1049,10 +689,8 @@ CONFIG_SPIFFS_MAX_PARTITIONS=3 # CONFIG_SPIFFS_CACHE=y CONFIG_SPIFFS_CACHE_WR=y -CONFIG_SPIFFS_CACHE_STATS= CONFIG_SPIFFS_PAGE_CHECK=y CONFIG_SPIFFS_GC_MAX_RUNS=10 -CONFIG_SPIFFS_GC_STATS= CONFIG_SPIFFS_PAGE_SIZE=256 CONFIG_SPIFFS_OBJ_NAME_LEN=32 CONFIG_SPIFFS_USE_MAGIC=y @@ -1060,15 +698,6 @@ CONFIG_SPIFFS_USE_MAGIC_LENGTH=y CONFIG_SPIFFS_META_LENGTH=4 CONFIG_SPIFFS_USE_MTIME=y -# -# Debug Configuration -# -CONFIG_SPIFFS_DBG= -CONFIG_SPIFFS_API_DBG= -CONFIG_SPIFFS_GC_DBG= -CONFIG_SPIFFS_CACHE_DBG= -CONFIG_SPIFFS_CHECK_DBG= -CONFIG_SPIFFS_TEST_VISUALISATION= # # TCP/IP Adapter @@ -1076,14 +705,6 @@ CONFIG_SPIFFS_TEST_VISUALISATION= CONFIG_IP_LOST_TIMER_INTERVAL=120 CONFIG_TCPIP_LWIP=y -# -# Unity unit testing library -# -CONFIG_UNITY_ENABLE_FLOAT=y -CONFIG_UNITY_ENABLE_DOUBLE=y -CONFIG_UNITY_ENABLE_COLOR= -CONFIG_UNITY_ENABLE_IDF_TEST_RUNNER=y -CONFIG_UNITY_ENABLE_FIXTURE= # # Virtual file system @@ -1094,7 +715,6 @@ CONFIG_SUPPORT_TERMIOS=y # # Wear Levelling # -CONFIG_WL_SECTOR_SIZE_512= CONFIG_WL_SECTOR_SIZE_4096=y CONFIG_WL_SECTOR_SIZE=4096 diff --git a/examples/korvo_du1906/tools/iot_ota_pkg_generator/mk_ota_bin.py b/examples/korvo_du1906/tools/iot_ota_pkg_generator/mk_ota_bin.py index d2ba7e9..cf2e425 100644 --- a/examples/korvo_du1906/tools/iot_ota_pkg_generator/mk_ota_bin.py +++ b/examples/korvo_du1906/tools/iot_ota_pkg_generator/mk_ota_bin.py @@ -18,7 +18,7 @@ parser.add_argument("-sa", "--sub_app", help = "Sub version of app bin. example: 1.0.0") parser.add_argument("-v", "--version", required = True, help = "OTA package version. example: 105") parser.add_argument("-p", "--path", default = ".", help = "Project abs or relative path.") -parser.add_argument("-fd", "--file_dsp", default = "DU1906_slave_v1.4.8.E.bin", help = "Dsp firmware file.") +parser.add_argument("-fd", "--file_dsp", default = "DU1906_slave_v1.5.5.D.bin", help = "Dsp firmware file.") args = parser.parse_args() #print(args.input) diff --git a/examples/korvo_du1906/version.txt b/examples/korvo_du1906/version.txt index 79127d8..18fa8e7 100644 --- a/examples/korvo_du1906/version.txt +++ b/examples/korvo_du1906/version.txt @@ -1 +1 @@ -v1.2.0 +v1.3.0 diff --git a/examples/ota/main/ota_example.c b/examples/ota/main/ota_example.c index febf37f..f913299 100644 --- a/examples/ota/main/ota_example.c +++ b/examples/ota/main/ota_example.c @@ -21,13 +21,24 @@ #include "nvs_flash.h" #include "periph_sdcard.h" #include "periph_wifi.h" -#include "tcpip_adapter.h" #include "audio_mem.h" #include "ota_service.h" #include "ota_proc_default.h" #include "tone_partition.h" +#if __has_include("esp_idf_version.h") +#include "esp_idf_version.h" +#else +#define ESP_IDF_VERSION_VAL(major, minor, patch) 1 +#endif + +#if (ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(4, 1, 0)) +#include "esp_netif.h" +#else +#include "tcpip_adapter.h" +#endif + static const char *TAG = "HTTPS_OTA_EXAMPLE"; static EventGroupHandle_t events = NULL; @@ -141,7 +152,11 @@ void app_main() err = nvs_flash_init(); } ESP_ERROR_CHECK(err); +#if (ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(4, 1, 0)) + ESP_ERROR_CHECK(esp_netif_init()); +#else tcpip_adapter_init(); +#endif ESP_LOGI(TAG, "[1.0] Initialize peripherals management"); esp_periph_config_t periph_cfg = DEFAULT_ESP_PERIPH_SET_CONFIG(); @@ -157,7 +172,7 @@ void app_main() periph_wifi_wait_for_connected(wifi_handle, portMAX_DELAY); ESP_LOGI(TAG, "[1.2] Mount SDCard"); - audio_board_sdcard_init(set); + audio_board_sdcard_init(set, SD_MODE_1_LINE); ESP_LOGI(TAG, "[2.0] Create OTA service"); ota_service_config_t ota_service_cfg = OTA_SERVICE_DEFAULT_CONFIG(); diff --git a/examples/ota/sdkconfig.defaults b/examples/ota/sdkconfig.defaults index 2a9fd4f..b3e2924 100644 --- a/examples/ota/sdkconfig.defaults +++ b/examples/ota/sdkconfig.defaults @@ -6,8 +6,6 @@ CONFIG_ESPTOOLPY_FLASHSIZE_4MB=y # # Partition Table # -CONFIG_PARTITION_TABLE_SINGLE_APP= -CONFIG_PARTITION_TABLE_TWO_OTA= CONFIG_PARTITION_TABLE_CUSTOM=y CONFIG_PARTITION_TABLE_CUSTOM_FILENAME="partitions.csv" CONFIG_PARTITION_TABLE_FILENAME="partitions.csv" diff --git a/examples/player/element_sdcard_amr/main/element_sdcard_amr_example.c b/examples/player/element_sdcard_amr/main/element_sdcard_amr_example.c index 5aaa9a2..fccf365 100644 --- a/examples/player/element_sdcard_amr/main/element_sdcard_amr_example.c +++ b/examples/player/element_sdcard_amr/main/element_sdcard_amr_example.c @@ -57,7 +57,7 @@ void app_main(void) esp_periph_set_handle_t set = esp_periph_set_init(&periph_cfg); // Initialize SD Card peripheral - audio_board_sdcard_init(set); + audio_board_sdcard_init(set, SD_MODE_1_LINE); ESP_LOGI(TAG, "[ 2 ] Start codec chip"); audio_board_handle_t board_handle = audio_board_init(); diff --git a/examples/player/element_sdcard_mp3/main/element_sdcard_mp3_example.c b/examples/player/element_sdcard_mp3/main/element_sdcard_mp3_example.c index 5c515f0..aa86d1c 100644 --- a/examples/player/element_sdcard_mp3/main/element_sdcard_mp3_example.c +++ b/examples/player/element_sdcard_mp3/main/element_sdcard_mp3_example.c @@ -57,7 +57,7 @@ void app_main(void) esp_periph_set_handle_t set = esp_periph_set_init(&periph_cfg); // Initialize SD Card peripheral - audio_board_sdcard_init(set); + audio_board_sdcard_init(set, SD_MODE_1_LINE); ESP_LOGI(TAG, "[ 2 ] Start codec chip"); audio_board_handle_t board_handle = audio_board_init(); diff --git a/examples/player/pipeline_a2dp_sink_stream/README.md b/examples/player/pipeline_a2dp_sink_stream/README.md index 10de6de..c03ae88 100644 --- a/examples/player/pipeline_a2dp_sink_stream/README.md +++ b/examples/player/pipeline_a2dp_sink_stream/README.md @@ -1,17 +1,13 @@ -ESP-ADF A2DP-SINK-Stream demo -============================= - -Demo of A2DP audio sink role +# ESP-ADF A2DP-SINK-Stream example +Example of A2DP audio sink. This is the demo of API implementing Advanced Audio Distribution Profile to receive an audio stream. - This example involves the use of Bluetooth legacy profile A2DP for audio stream reception, AVRCP for media information notifications. - Applications such as bluetooth speakers can take advantage of this example as a reference of basic functionalities. -## How to use this example +## 1. How to use example -### Compatibility +#### Hardware Required This example is will run on boards marked with green checkbox. Please remember to select the board in menuconfig as discussed is section *Usage* below. @@ -24,28 +20,170 @@ This example is will run on boards marked with green checkbox. Please remember t | ESP32-S2-Kaluga-1 Kit | [![alt text](../../../docs/_static/esp32-s2-kaluga-1-kit-small.png "ESP32-S2-Kaluga-1 Kit")](https://docs.espressif.com/projects/esp-idf/en/latest/esp32s2/hw-reference/esp32s2/user-guide-esp32-s2-kaluga-1-kit.html) | ESP32-S2 | ![alt text](../../../docs/_static/no-button.png "Compatible") | -### Configure the project +## 2. Setup software environment +Please refer to [Get Started](https://docs.espressif.com/projects/esp-adf/en/latest/get-started/index.html#get-started). + +#### Configure the project +cmake menuconfig: +``` +idf.py menuconfig ``` +Or use legacy GNU make: +``` +make menuconfig +``` +Select compatible audio board in ``menuconfig > Audio HAL``, then compile the example. +Enable Classic Bluetooth and A2DP under Component config --> Bluetooth --> Bluedroid Enable. + +#### Build and Flash +You can use `GNU make` or `cmake` to build the project. +If you are using make: +```bash +cd $ADF_PATH/examples/player/pipeline_a2dp_sink_stream +make clean make menuconfig +make -j4 all ``` -* Enable Classic Bluetooth and A2DP under Component config --> Bluetooth --> Bluedroid Enable +Or if you are using cmake: +```bash +cd $ADF_PATH/examples/player/pipeline_a2dp_sink_stream +idf.py fullclean +idf.py menuconfig +idf.py build +``` +The firmware downloading flash address refer to follow table. -* Select compatible audio board in `menuconfig` > `Audio HAL`. +|Flash address | Bin Path| +|---|---| +|0x1000 | build/bootloader/bootloader.bin| +|0x8000 | build/partitiontable/partition-table.bin| +|0x10000 | build/bt_sink_demo.bin| +To exit the serial monitor, type ``Ctrl-]``. -### Build and Flash +## 3. Example Output -Build the project and flash it to the board, then run monitor tool to view serial output. +After download the follow logs should be output, here: ``` -make -j4 flash monitor -``` +I (29) boot: ESP-IDF v4.2-47-g2532ddd-dirty 2nd stage bootloader +I (29) boot: compile time 11:56:15 +I (29) boot: chip revision: 1 +I (33) boot_comm: chip revision: 1, min. bootloader chip revision: 0 +I (40) boot.esp32: SPI Speed : 40MHz +I (45) boot.esp32: SPI Mode : DIO +I (49) boot.esp32: SPI Flash Size : 2MB +I (54) boot: Enabling RNG early entropy source... +I (59) boot: Partition Table: +I (63) boot: ## Label Usage Type ST Offset Length +I (70) boot: 0 nvs WiFi data 01 02 00009000 00006000 +I (78) boot: 1 phy_init RF data 01 01 0000f000 00001000 +I (85) boot: 2 factory factory app 00 00 00010000 00124f80 +I (93) boot: End of partition table +I (97) boot_comm: chip revision: 1, min. application chip revision: 0 +I (104) esp_image: segment 0: paddr=0x00010020 vaddr=0x3f400020 size=0x2cc78 (183416) map +I (183) esp_image: segment 1: paddr=0x0003cca0 vaddr=0x3ffbdb60 size=0x03378 ( 13176) load +I (188) esp_image: segment 2: paddr=0x00040020 vaddr=0x400d0020 size=0xae1d4 (713172) map +0x400d0020: _stext at ??:? + +I (461) esp_image: segment 3: paddr=0x000ee1fc vaddr=0x3ffc0ed8 size=0x001a8 ( 424) load +I (461) esp_image: segment 4: paddr=0x000ee3ac vaddr=0x40080000 size=0x00404 ( 1028) load +0x40080000: _WindowOverflow4 at /home/zhanghu/esp/esp-adf-internal/esp-idf/components/freertos/xtensa/xtensa_vectors.S:1730 + +I (468) esp_image: segment 5: paddr=0x000ee7b8 vaddr=0x40080404 size=0x16e4c ( 93772) load +I (530) boot: Loaded app from partition at offset 0x10000 +I (530) boot: Disabling RNG early entropy source... +I (531) cpu_start: Pro cpu up. +I (534) cpu_start: Application information: +I (539) cpu_start: Project name: bt_sink_demo +I (544) cpu_start: App version: v2.2-36-gdcbdc7b-dirty +I (551) cpu_start: Compile time: Dec 23 2020 11:56:29 +I (557) cpu_start: ELF file SHA256: ca5e58274e21d640... +I (563) cpu_start: ESP-IDF: v4.2-47-g2532ddd-dirty +I (569) cpu_start: Starting app cpu, entry point is 0x400815e4 +0x400815e4: call_start_cpu1 at /home/zhanghu/esp/esp-adf-internal/esp-idf/components/esp32/cpu_start.c:287 + +I (0) cpu_start: App cpu up. +I (579) heap_init: Initializing. RAM available for dynamic allocation: +I (586) heap_init: At 3FFAFF10 len 000000F0 (0 KiB): DRAM +I (592) heap_init: At 3FFB6388 len 00001C78 (7 KiB): DRAM +I (598) heap_init: At 3FFB9A20 len 00004108 (16 KiB): DRAM +I (605) heap_init: At 3FFCF100 len 00010F00 (67 KiB): DRAM +I (611) heap_init: At 3FFE0440 len 00003AE0 (14 KiB): D/IRAM +I (617) heap_init: At 3FFE4350 len 0001BCB0 (111 KiB): D/IRAM +I (623) heap_init: At 40097250 len 00008DB0 (35 KiB): IRAM +I (630) cpu_start: Pro cpu start user code +I (648) spi_flash: detected chip: gd +I (649) spi_flash: flash io: dio +W (649) spi_flash: Detected size(8192k) larger than the size in the binary image header(2048k). Using the size in the binary image header. +I (659) cpu_start: Starting scheduler on PRO CPU. +I (0) cpu_start: Starting scheduler on APP CPU. +I (731) BLUETOOTH_EXAMPLE: [ 1 ] Init Bluetooth +I (731) BTDM_INIT: BT controller compile version [3723d5b] +I (731) system_api: Base MAC address is not set +I (741) system_api: read default base MAC address from EFUSE +I (841) phy: phy_version: 4500, 0cd6843, Sep 17 2020, 15:37:07, 0, 0 +I (1431) BLUETOOTH_EXAMPLE: [ 2 ] Start codec chip +I (1431) gpio: GPIO[19]| InputEn: 1| OutputEn: 0| OpenDrain: 0| Pullup: 1| Pulldown: 0| Intr:3 +I (1461) gpio: GPIO[21]| InputEn: 0| OutputEn: 1| OpenDrain: 0| Pullup: 0| Pulldown: 0| Intr:0 +I (1461) ES8388_DRIVER: init,out:02, in:00 +I (1471) AUDIO_HAL: Codec mode is 2, Ctrl:1 +I (1471) BLUETOOTH_EXAMPLE: [ 3 ] Create audio pipeline for playback +I (1471) BLUETOOTH_EXAMPLE: [4] Create i2s stream to write data to codec chip +I (1481) I2S: DMA Malloc info, datalen=blocksize=1200, dma_buf_count=3 +I (1491) I2S: DMA Malloc info, datalen=blocksize=1200, dma_buf_count=3 +I (1521) I2S: APLL: Req RATE: 44100, real rate: 44099.988, BITS: 16, CLKM: 1, BCK_M: 8, MCLK: 11289597.000, SCLK: 1411199.625000, diva: 1, divb: 0 +I (1521) LYRAT_V4_3: I2S0, MCLK output by GPIO0 +I (1521) BLUETOOTH_EXAMPLE: [4.1] Get Bluetooth stream +W (1531) BT_BTC: A2DP Enable with AVRC +I (1551) BLUETOOTH_EXAMPLE: [4.2] Register all elements to audio pipeline +I (1551) BLUETOOTH_EXAMPLE: [4.3] Link it together [Bluetooth]-->bt_stream_reader-->i2s_stream_writer-->[codec_chip] +I (1561) AUDIO_PIPELINE: link el->rb, el:0x3ffd830c, tag:bt, rb:0x3ffd87c0 +I (1561) BLUETOOTH_EXAMPLE: [ 5 ] Initialize peripherals +E (1571) gpio: gpio_install_isr_service(438): GPIO isr service already installed +I (1581) gpio: GPIO[36]| InputEn: 1| OutputEn: 0| OpenDrain: 0| Pullup: 1| Pulldown: 0| Intr:3 +I (1591) gpio: GPIO[39]| InputEn: 1| OutputEn: 0| OpenDrain: 0| Pullup: 1| Pulldown: 0| Intr:3 +I (1601) BLUETOOTH_EXAMPLE: [ 5.1 ] Create and start input key service +I (1601) BLUETOOTH_EXAMPLE: [5.2] Create Bluetooth peripheral +W (1621) PERIPH_TOUCH: _touch_init +I (1621) BLUETOOTH_EXAMPLE: [5.3] Start all peripherals +I (1631) BLUETOOTH_EXAMPLE: [ 6 ] Set up event listener +I (1631) BLUETOOTH_EXAMPLE: [6.1] Listening event from all elements of pipeline +I (1641) BLUETOOTH_EXAMPLE: [ 7 ] Start audio_pipeline +I (1651) AUDIO_ELEMENT: [bt-0x3ffd830c] Element task created +I (1661) AUDIO_ELEMENT: [i2s-0x3ffd7fec] Element task created +I (1661) AUDIO_PIPELINE: Func:audio_pipeline_run, Line:359, MEM Total:134064 Bytes + +I (1681) AUDIO_ELEMENT: [i2s] AEL_MSG_CMD_RESUME,state:1 +I (1681) I2S_STREAM: AUDIO_STREAM_WRITER +I (1681) AUDIO_PIPELINE: Pipeline started +I (1681) BLUETOOTH_EXAMPLE: [ 8 ] Listen for all pipeline events +E (23161) BT_APPL: bta_av_rc_create ACP handle exist for shdl:0 +I (23171) A2DP_STREAM: A2DP bd address:, [e4:9a:dc:62:2d:d0] +I (23171) A2DP_STREAM: AVRC conn_state evt: state 1, [e4:9a:dc:62:2d:d0] +I (23381) A2DP_STREAM: AVRC register event notification: 13, param: 0x0 +I (23381) A2DP_STREAM: A2DP audio stream configuration, codec type 0 +I (23381) A2DP_STREAM: Bluetooth configured, sample rate=44100 +I (23391) BLUETOOTH_EXAMPLE: [ * ] Receive music info from Bluetooth, sample_rates=44100, bits=16, ch=2 +I (23421) AUDIO_ELEMENT: [i2s] AEL_MSG_CMD_PAUSE +I (23461) I2S: APLL: Req RATE: 44100, real rate: 44099.988, BITS: 16, CLKM: 1, BCK_M: 8, MCLK: 11289597.000, SCLK: 1411199.625000, diva: 1, divb: 0 +I (23461) AUDIO_ELEMENT: [i2s] AEL_MSG_CMD_RESUME,state:3 +I (23471) I2S_STREAM: AUDIO_STREAM_WRITER +I (23761) A2DP_STREAM: AVRC remote features 25b, CT features 2 +W (23821) BT_APPL: new conn_srvc id:19, app_id:0 +I (23831) A2DP_STREAM: A2DP bd address:, [e4:9a:dc:62:2d:d0] +I (23831) A2DP_STREAM: A2DP connection state = CONNECTED +I (23961) A2DP_STREAM: AVRC set absolute volume: 54% +I (23961) A2DP_STREAM: Volume is set by remote controller 54% + +I (24361) A2DP_STREAM: AVRC remote features 25b, CT features 2 +I (36401) BT_LOG: bta_av_link_role_ok hndl:x41 role:1 conn_audio:x1 bits:1 features:x824b -(To exit the serial monitor, type ``Ctrl-]``.) +``` -## Example Output +Load and run the example: - Connect with Bluetooth on your smartphone to the audio board identified as "ESP_SINK_STREAM_DEMO" - Play some audio from the smartphone and it will be transmitted over Bluetooth to the audio bard. @@ -57,23 +195,13 @@ make -j4 flash monitor | Stop Music | [Set] | | Next Song | [long Vol+] | | Previous Song | [long Vol-] | - | Volume Up | [n/a] | - | Volume Down | [n/a] | - -Once A2DP connection is set up, there will be a notification message with the remote device's bluetooth MAC address like the following: - -``` -I (106427) A2DP_STREAM: A2DP bd address:, [64:a2:f9:69:57:a4] -I (106427) A2DP_STREAM: A2DP connection state = CONNECTED -``` + | Volume Up | [Vol+] | + | Volume Down | [Vol-] | -If connection is terminated, there will be such message: +- `Volume Up` and `Volume Down` is not been supported in IDF 3.3. -``` -I (5100) A2DP_STREAM: A2DP connection state = DISCONNECTED -``` +## 4. Troubleshooting +- For current stage, the supported audio codec in ESP32 A2DP is SBC. SBC data stream is transmitted to A2DP sink and then decoded into PCM samples as output. The PCM data format is normally of 44.1kHz sampling rate, two-channel 16-bit sample stream. Other decoder configurations in ESP32 A2DP sink is supported but need additional modifications of protocol stack settings. -## Troubleshooting -* For current stage, the supported audio codec in ESP32 A2DP is SBC. SBC data stream is transmitted to A2DP sink and then decoded into PCM samples as output. The PCM data format is normally of 44.1kHz sampling rate, two-channel 16-bit sample stream. Other decoder configurations in ESP32 A2DP sink is supported but need additional modifications of protocol stack settings. -* As a usage limitation, ESP32 A2DP sink can support at most one connection with remote A2DP source devices. Also, A2DP sink cannot be used together with A2DP source at the same time, but can be used with other profiles such as SPP and HFP. \ No newline at end of file +- As a usage limitation, ESP32 A2DP sink can support at most one connection with remote A2DP source devices. Also, A2DP sink cannot be used together with A2DP source at the same time, but can be used with other profiles such as SPP and HFP. diff --git a/examples/player/pipeline_a2dp_sink_stream/main/play_bt_music_example.c b/examples/player/pipeline_a2dp_sink_stream/main/play_bt_music_example.c index da4a89c..ef4f9f0 100644 --- a/examples/player/pipeline_a2dp_sink_stream/main/play_bt_music_example.c +++ b/examples/player/pipeline_a2dp_sink_stream/main/play_bt_music_example.c @@ -42,8 +42,18 @@ static esp_err_t input_key_service_cb(periph_service_handle_t handle, periph_ser ESP_LOGI(TAG, "[ * ] [Set] pause"); periph_bt_pause(bt_periph); break; +#if (ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(4, 0, 0)) + case INPUT_KEY_USER_ID_VOLUP: + ESP_LOGI(TAG, "[ * ] [long Vol+] Vol+"); + periph_bt_volume_up(bt_periph); + break; + case INPUT_KEY_USER_ID_VOLDOWN: + ESP_LOGI(TAG, "[ * ] [long Vol-] Vol-"); + periph_bt_volume_down(bt_periph); + break; +#endif } - } else if (evt->type == INPUT_KEY_SERVICE_ACTION_PRESS_RELEASE) { + } else if (evt->type == INPUT_KEY_SERVICE_ACTION_PRESS) { ESP_LOGI(TAG, "[ * ] input key id is %d", (int)evt->data); switch ((int)evt->data) { case INPUT_KEY_USER_ID_VOLUP: @@ -86,7 +96,11 @@ void app_main(void) esp_bt_dev_set_device_name("ESP_SINK_STREAM_DEMO"); +#if (ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(4, 0, 0)) + esp_bt_gap_set_scan_mode(ESP_BT_CONNECTABLE, ESP_BT_GENERAL_DISCOVERABLE); +#else esp_bt_gap_set_scan_mode(ESP_BT_SCAN_MODE_CONNECTABLE_DISCOVERABLE); +#endif ESP_LOGI(TAG, "[ 2 ] Start codec chip"); audio_board_handle_t board_handle = audio_board_init(); @@ -105,6 +119,9 @@ void app_main(void) a2dp_stream_config_t a2dp_config = { .type = AUDIO_STREAM_READER, .user_callback = {0}, +#if (ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(4, 0, 0)) + .audio_hal = board_handle->audio_hal, +#endif }; bt_stream_reader = a2dp_stream_init(&a2dp_config); @@ -167,11 +184,6 @@ void app_main(void) continue; } - if (msg.cmd == AEL_MSG_CMD_ERROR) { - ESP_LOGI(TAG, "[ * ] Action command: src_type:%d, source:%p cmd:%d, data:%p, data_len:%d", - msg.source_type, msg.source, msg.cmd, msg.data, msg.data_len); - } - if (msg.source_type == AUDIO_ELEMENT_TYPE_ELEMENT && msg.source == (void *) bt_stream_reader && msg.cmd == AEL_MSG_CMD_REPORT_MUSIC_INFO) { audio_element_info_t music_info = {0}; @@ -224,7 +236,6 @@ void app_main(void) audio_element_deinit(i2s_stream_writer); esp_periph_set_destroy(set); periph_service_destroy(input_ser); - a2dp_destroy(); esp_bluedroid_disable(); esp_bluedroid_deinit(); esp_bt_controller_disable(); diff --git a/examples/player/pipeline_a2dp_sink_stream/sdkconfig.defaults b/examples/player/pipeline_a2dp_sink_stream/sdkconfig.defaults index 1c7562c..96d1fd8 100644 --- a/examples/player/pipeline_a2dp_sink_stream/sdkconfig.defaults +++ b/examples/player/pipeline_a2dp_sink_stream/sdkconfig.defaults @@ -5,11 +5,6 @@ CONFIG_BLUEDROID_ENABLED=y CONFIG_CLASSIC_BT_ENABLED=y CONFIG_A2DP_ENABLE=y CONFIG_A2DP_SINK_ENABLE=y -CONFIG_A2DP_SRC_ENABLE= -CONFIG_BT_SPP_ENABLED= -CONFIG_GATTS_ENABLE= -CONFIG_GATTC_ENABLE= -CONFIG_BLE_SMP_ENABLE= CONFIG_BTDM_CONTROLLER_MODE_BR_EDR_ONLY=y # Increase default app partition size to accommodate BT diff --git a/examples/player/pipeline_a2dp_source_stream/main/play_bt_source_example.c b/examples/player/pipeline_a2dp_source_stream/main/play_bt_source_example.c index cdbd5e2..f7dd925 100644 --- a/examples/player/pipeline_a2dp_source_stream/main/play_bt_source_example.c +++ b/examples/player/pipeline_a2dp_source_stream/main/play_bt_source_example.c @@ -88,22 +88,22 @@ static void filter_inquiry_scan_result(esp_bt_gap_cb_param_t *param) for (int i = 0; i < param->disc_res.num_prop; i++) { p = param->disc_res.prop + i; switch (p->type) { - case ESP_BT_GAP_DEV_PROP_COD: - cod = *(uint32_t *)(p->val); - ESP_LOGI(TAG, "--Class of Device: 0x%x", cod); - break; - case ESP_BT_GAP_DEV_PROP_RSSI: - rssi = *(int8_t *)(p->val); - ESP_LOGI(TAG, "--RSSI: %d", rssi); - break; - case ESP_BT_GAP_DEV_PROP_EIR: - eir = (uint8_t *)(p->val); - get_name_from_eir(eir, (uint8_t *)&peer_bdname, NULL); - ESP_LOGI(TAG, "--Name: %s", peer_bdname); - break; - case ESP_BT_GAP_DEV_PROP_BDNAME: - default: - break; + case ESP_BT_GAP_DEV_PROP_COD: + cod = *(uint32_t *)(p->val); + ESP_LOGI(TAG, "--Class of Device: 0x%x", cod); + break; + case ESP_BT_GAP_DEV_PROP_RSSI: + rssi = *(int8_t *)(p->val); + ESP_LOGI(TAG, "--RSSI: %d", rssi); + break; + case ESP_BT_GAP_DEV_PROP_EIR: + eir = (uint8_t *)(p->val); + get_name_from_eir(eir, (uint8_t *)&peer_bdname, NULL); + ESP_LOGI(TAG, "--Name: %s", peer_bdname); + break; + case ESP_BT_GAP_DEV_PROP_BDNAME: + default: + break; } } @@ -127,38 +127,38 @@ static void bt_app_gap_cb(esp_bt_gap_cb_event_t event, esp_bt_gap_cb_param_t *pa { switch (event) { case ESP_BT_GAP_DISC_RES_EVT: { - filter_inquiry_scan_result(param); - break; - } + filter_inquiry_scan_result(param); + break; + } case ESP_BT_GAP_DISC_STATE_CHANGED_EVT: { - if (param->disc_st_chg.state == ESP_BT_GAP_DISCOVERY_STOPPED) { - if (device_found) { - ESP_LOGI(TAG, "Device discovery stopped."); - ESP_LOGI(TAG, "a2dp connecting to peer: %s", remote_bt_device_name); - device_found = false; - esp_a2d_source_connect(remote_bd_addr); - } else { - // not discovered, continue to discover - ESP_LOGI(TAG, "Device discovery failed, continue to discover..."); - esp_bt_gap_start_discovery(ESP_BT_INQ_MODE_GENERAL_INQUIRY, 10, 0); + if (param->disc_st_chg.state == ESP_BT_GAP_DISCOVERY_STOPPED) { + if (device_found) { + ESP_LOGI(TAG, "Device discovery stopped."); + ESP_LOGI(TAG, "a2dp connecting to peer: %s", remote_bt_device_name); + device_found = false; + esp_a2d_source_connect(remote_bd_addr); + } else { + // not discovered, continue to discover + ESP_LOGI(TAG, "Device discovery failed, continue to discover..."); + esp_bt_gap_start_discovery(ESP_BT_INQ_MODE_GENERAL_INQUIRY, 10, 0); + } + } else if (param->disc_st_chg.state == ESP_BT_GAP_DISCOVERY_STARTED) { + ESP_LOGI(TAG, "Discovery started."); } - } else if (param->disc_st_chg.state == ESP_BT_GAP_DISCOVERY_STARTED) { - ESP_LOGI(TAG, "Discovery started."); + break; } - break; - } case ESP_BT_GAP_PIN_REQ_EVT: { - ESP_LOGI(TAG, "ESP_BT_GAP_PIN_REQ_EVT min_16_digit:%d", param->pin_req.min_16_digit); - if (param->pin_req.min_16_digit) { - ESP_LOGI(TAG, "Input pin code: 0000 0000 0000 0000"); - esp_bt_pin_code_t pin_code = {0}; - esp_bt_gap_pin_reply(param->pin_req.bda, true, 16, pin_code); - } else { - esp_bt_pin_code_t pin_code = {'1', '2', '3', '4'}; - esp_bt_gap_pin_reply(param->pin_req.bda, true, 4, pin_code); + ESP_LOGI(TAG, "ESP_BT_GAP_PIN_REQ_EVT min_16_digit:%d", param->pin_req.min_16_digit); + if (param->pin_req.min_16_digit) { + ESP_LOGI(TAG, "Input pin code: 0000 0000 0000 0000"); + esp_bt_pin_code_t pin_code = {0}; + esp_bt_gap_pin_reply(param->pin_req.bda, true, 16, pin_code); + } else { + esp_bt_pin_code_t pin_code = {'1', '2', '3', '4'}; + esp_bt_gap_pin_reply(param->pin_req.bda, true, 4, pin_code); + } + break; } - break; - } default: break; } @@ -187,7 +187,7 @@ void app_main(void) esp_periph_set_handle_t set = esp_periph_set_init(&periph_cfg); // Initialize SD Card peripheral - audio_board_sdcard_init(set); + audio_board_sdcard_init(set, SD_MODE_1_LINE); ESP_LOGI(TAG, "[ 2 ] Start codec chip"); audio_board_handle_t board_handle = audio_board_init(); @@ -227,7 +227,7 @@ void app_main(void) if (remote_name) { memcpy(&remote_bt_device_name, remote_name, strlen(remote_name) + 1); } else { - memcpy(&remote_bt_device_name, "ESP_SINK_STREAM_DEMO", ESP_BT_GAP_MAX_BDNAME_LEN + 1); + memcpy(&remote_bt_device_name, "ESP_SINK_STREAM_DEMO", ESP_BT_GAP_MAX_BDNAME_LEN); } a2dp_stream_config_t a2dp_config = { @@ -237,7 +237,12 @@ void app_main(void) bt_stream_writer = a2dp_stream_init(&a2dp_config); esp_bt_gap_start_discovery(ESP_BT_INQ_MODE_GENERAL_INQUIRY, 10, 0); +#if (ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(4, 0, 0)) + esp_bt_gap_set_scan_mode(ESP_BT_CONNECTABLE, ESP_BT_GENERAL_DISCOVERABLE); +#else esp_bt_gap_set_scan_mode(ESP_BT_SCAN_MODE_CONNECTABLE_DISCOVERABLE); +#endif + ESP_LOGI(TAG, "[3.4] Register all elements to audio pipeline"); audio_pipeline_register(pipeline, fatfs_stream_reader, "file"); @@ -290,7 +295,7 @@ void app_main(void) continue; } if (msg.source_type == PERIPH_ID_BLUETOOTH - && msg.source == (void *)bt_periph) { + && msg.source == (void *)bt_periph) { if ((msg.cmd == PERIPH_BLUETOOTH_DISCONNECTED) || (msg.cmd == PERIPH_BLUETOOTH_AUDIO_SUSPENDED)) { ESP_LOGW(TAG, "[ * ] Bluetooth disconnected or suspended"); periph_bt_stop(bt_periph); @@ -323,7 +328,6 @@ void app_main(void) audio_element_deinit(fatfs_stream_reader); audio_element_deinit(mp3_decoder); esp_periph_set_destroy(set); - a2dp_destroy(); esp_bluedroid_disable(); esp_bluedroid_deinit(); esp_bt_controller_disable(); diff --git a/examples/player/pipeline_a2dp_source_stream/sdkconfig.defaults b/examples/player/pipeline_a2dp_source_stream/sdkconfig.defaults index 17cda0e..180087e 100644 --- a/examples/player/pipeline_a2dp_source_stream/sdkconfig.defaults +++ b/examples/player/pipeline_a2dp_source_stream/sdkconfig.defaults @@ -10,11 +10,6 @@ CONFIG_CLASSIC_BT_ENABLED=y CONFIG_A2DP_ENABLE=y CONFIG_A2DP_SRC_ENABLE=y CONFIG_A2DP_SOURCE_TASK_STACK_SIZE=2048 -CONFIG_BT_SPP_ENABLED= -CONFIG_GATTS_ENABLE= -CONFIG_GATTC_ENABLE= -CONFIG_BLE_SMP_ENABLE= -CONFIG_BT_STACK_NO_LOG= CONFIG_BT_ALLOCATION_FROM_SPIRAM_FIRST=y CONFIG_BT_BLE_DYNAMIC_ENV_MEMORY=y CONFIG_ESP32_DEFAULT_CPU_FREQ_240=y diff --git a/examples/player/pipeline_bt_sink/main/play_bt_music_example.c b/examples/player/pipeline_bt_sink/main/play_bt_music_example.c index 15c1abd..d6dac24 100644 --- a/examples/player/pipeline_bt_sink/main/play_bt_music_example.c +++ b/examples/player/pipeline_bt_sink/main/play_bt_music_example.c @@ -122,11 +122,6 @@ void app_main(void) continue; } - if (msg.cmd == AEL_MSG_CMD_ERROR) { - ESP_LOGE(TAG, "[ * ] Action command error: src_type:%d, source:%p cmd:%d, data:%p, data_len:%d", - msg.source_type, msg.source, msg.cmd, msg.data, msg.data_len); - } - if (msg.source_type == AUDIO_ELEMENT_TYPE_ELEMENT && msg.source == (void *) bt_stream_reader && msg.cmd == AEL_MSG_CMD_REPORT_MUSIC_INFO) { audio_element_info_t music_info = {0}; diff --git a/examples/player/pipeline_bt_sink/sdkconfig.defaults b/examples/player/pipeline_bt_sink/sdkconfig.defaults index 5d2334d..db33b50 100644 --- a/examples/player/pipeline_bt_sink/sdkconfig.defaults +++ b/examples/player/pipeline_bt_sink/sdkconfig.defaults @@ -1,15 +1,11 @@ # Override some defaults so BT stack is enabled and # Classic BT is enabled and BT_DRAM_RELEASE is disabled CONFIG_BT_ENABLED=y -CONFIG_BTDM_CONTROLLER_MODE_BR_EDR_ONLY=y +CONFIG_BTDM_CONTROLLER_MODE_BTDM=y CONFIG_BLUEDROID_ENABLED=y CONFIG_CLASSIC_BT_ENABLED=y CONFIG_A2DP_ENABLE=y CONFIG_A2DP_SINK_TASK_STACK_SIZE=2048 -CONFIG_BT_SPP_ENABLED= -CONFIG_GATTS_ENABLE= -CONFIG_GATTC_ENABLE= -CONFIG_BLE_SMP_ENABLE= # Increase default app partition size to accommodate BT # by providing new partition table in "partitions_bt_sink_example.csv" diff --git a/examples/player/pipeline_bt_source/main/play_bt_source_example.c b/examples/player/pipeline_bt_source/main/play_bt_source_example.c index c7f5bba..e4852a3 100644 --- a/examples/player/pipeline_bt_source/main/play_bt_source_example.c +++ b/examples/player/pipeline_bt_source/main/play_bt_source_example.c @@ -24,6 +24,18 @@ #include "mp3_decoder.h" #include "http_stream.h" +#if __has_include("esp_idf_version.h") +#include "esp_idf_version.h" +#else +#define ESP_IDF_VERSION_VAL(major, minor, patch) 1 +#endif + +#if (ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(4, 1, 0)) +#include "esp_netif.h" +#else +#include "tcpip_adapter.h" +#endif + static const char *TAG = "BLUETOOTH_SOURCE_EXAMPLE"; void app_main(void) @@ -38,7 +50,11 @@ void app_main(void) ESP_ERROR_CHECK(nvs_flash_erase()); err = nvs_flash_init(); } +#if (ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(4, 1, 0)) + ESP_ERROR_CHECK(esp_netif_init()); +#else tcpip_adapter_init(); +#endif esp_log_level_set("*", ESP_LOG_INFO); esp_log_level_set(TAG, ESP_LOG_DEBUG); diff --git a/examples/player/pipeline_bt_source/sdkconfig.defaults b/examples/player/pipeline_bt_source/sdkconfig.defaults index 48706a6..03b549f 100644 --- a/examples/player/pipeline_bt_source/sdkconfig.defaults +++ b/examples/player/pipeline_bt_source/sdkconfig.defaults @@ -1,7 +1,7 @@ # Override some defaults so BT stack is enabled and # Classic BT is enabled CONFIG_BT_ENABLED=y -CONFIG_BTDM_CONTROLLER_MODE_BR_EDR_ONLY=y +CONFIG_BTDM_CONTROLLER_MODE_BTDM=y CONFIG_BTDM_CONTROLLER_PINNED_TO_CORE_1=y CONFIG_BTDM_CONTROLLER_MODEM_SLEEP=y CONFIG_BTDM_COEX_BT_OPTIONS=y @@ -12,16 +12,12 @@ CONFIG_CLASSIC_BT_ENABLED=y CONFIG_A2DP_ENABLE=y CONFIG_A2DP_SRC_ENABLE=y CONFIG_A2DP_SOURCE_TASK_STACK_SIZE=2048 -CONFIG_BT_SPP_ENABLED= -CONFIG_GATTS_ENABLE= -CONFIG_GATTC_ENABLE= -CONFIG_BLE_SMP_ENABLE= -CONFIG_BT_STACK_NO_LOG= CONFIG_BT_ALLOCATION_FROM_SPIRAM_FIRST=y CONFIG_BT_BLE_DYNAMIC_ENV_MEMORY=y CONFIG_ESP32_DEFAULT_CPU_FREQ_240=y CONFIG_ESP32_DEFAULT_CPU_FREQ_MHZ=240 CONFIG_SPIRAM_SUPPORT=y +CONFIG_BT_BLE_BLUFI_ENABLE=y # Increase default app partition size to accommodate BT # by providing new partition table in "partitions_bt_source_example.csv" diff --git a/examples/player/pipeline_flash_tone/main/play_tone_mp3_example.c b/examples/player/pipeline_flash_tone/main/play_tone_mp3_example.c index 069b9bc..ab2a019 100644 --- a/examples/player/pipeline_flash_tone/main/play_tone_mp3_example.c +++ b/examples/player/pipeline_flash_tone/main/play_tone_mp3_example.c @@ -49,15 +49,18 @@ void app_main(void) tone_stream_cfg_t tone_cfg = TONE_STREAM_CFG_DEFAULT(); tone_cfg.type = AUDIO_STREAM_READER; tone_stream_reader = tone_stream_init(&tone_cfg); + AUDIO_NULL_CHECK(TAG, tone_stream_reader, return); ESP_LOGI(TAG, "[2.2] Create i2s stream to write data to codec chip"); i2s_stream_cfg_t i2s_cfg = I2S_STREAM_CFG_DEFAULT(); i2s_cfg.type = AUDIO_STREAM_WRITER; i2s_stream_writer = i2s_stream_init(&i2s_cfg); + AUDIO_NULL_CHECK(TAG, i2s_stream_writer, return); ESP_LOGI(TAG, "[2.3] Create mp3 decoder to decode mp3 file"); mp3_decoder_cfg_t mp3_cfg = DEFAULT_MP3_DECODER_CONFIG(); mp3_decoder = mp3_decoder_init(&mp3_cfg); + AUDIO_NULL_CHECK(TAG, mp3_decoder, return); ESP_LOGI(TAG, "[2.4] Register all elements to audio pipeline"); audio_pipeline_register(pipeline, tone_stream_reader, "tone"); diff --git a/examples/player/pipeline_hfp_stream/README.md b/examples/player/pipeline_hfp_stream/README.md index 99699b5..f3a32fc 100644 --- a/examples/player/pipeline_hfp_stream/README.md +++ b/examples/player/pipeline_hfp_stream/README.md @@ -13,10 +13,10 @@ This example is will run on boards marked with green checkbox. Please remember t | Board Name | Getting Started | Chip | Compatible | |-------------------|:--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------:|:--------------------------------------------------------------------:|:-----------------------------------------------------------------:| | ESP32-LyraT | [![alt text](../../../docs/_static/esp32-lyrat-v4.3-side-small.jpg "ESP32-LyraT")](https://docs.espressif.com/projects/esp-adf/en/latest/get-started/get-started-esp32-lyrat.html) | ESP32 | ![alt text](../../../docs/_static/yes-button.png "Compatible") | -| ESP32-LyraTD-MSC | [![alt text](../../../docs/_static/esp32-lyratd-msc-v2.2-small.jpg "ESP32-LyraTD-MSC")](https://docs.espressif.com/projects/esp-adf/en/latest/get-started/get-started-esp32-lyratd-msc.html) | ESP32 | ![alt text](../../../docs/_static/yes-button.png "Compatible") | +| ESP32-LyraTD-MSC | [![alt text](../../../docs/_static/esp32-lyratd-msc-v2.2-small.jpg "ESP32-LyraTD-MSC")](https://docs.espressif.com/projects/esp-adf/en/latest/get-started/get-started-esp32-lyratd-msc.html) | ESP32 | ![alt text](../../../docs/_static/no-button.png "Compatible") | | ESP32-LyraT-Mini | [![alt text](../../../docs/_static/esp32-lyrat-mini-v1.2-small.jpg "ESP32-LyraT-Mini")](https://docs.espressif.com/projects/esp-adf/en/latest/get-started/get-started-esp32-lyrat-mini.html) | ESP32 | ![alt text](../../../docs/_static/yes-button.png "Compatible") | | ESP32-Korvo-DU1906 | [![alt text](../../../docs/_static/esp32-korvo-du1906-v1.1-small.jpg "ESP32-Korvo-DU1906")](https://docs.espressif.com/projects/esp-adf/en/latest/get-started/get-started-esp32-korvo-du1906.html) | ESP32 | ![alt text](../../../docs/_static/yes-button.png "Compatible") | -| ESP32-S2-Kaluga-1 Kit | [![alt text](../../../docs/_static/esp32-s2-kaluga-1-kit-small.png "ESP32-S2-Kaluga-1 Kit")](https://docs.espressif.com/projects/esp-idf/en/latest/esp32s2/hw-reference/esp32s2/user-guide-esp32-s2-kaluga-1-kit.html) | ESP32-S2 | ![alt text](../../../docs/_static/yes-button.png "Compatible") | +| ESP32-S2-Kaluga-1 Kit | [![alt text](../../../docs/_static/esp32-s2-kaluga-1-kit-small.png "ESP32-S2-Kaluga-1 Kit")](https://docs.espressif.com/projects/esp-idf/en/latest/esp32s2/hw-reference/esp32s2/user-guide-esp32-s2-kaluga-1-kit.html) | ESP32-S2 | ![alt text](../../../docs/_static/no-button.png "Compatible") | ### Configure the project diff --git a/examples/player/pipeline_hfp_stream/main/pipeline_hfp_stream_example.c b/examples/player/pipeline_hfp_stream/main/pipeline_hfp_stream_example.c index 0de7b72..6282397 100755 --- a/examples/player/pipeline_hfp_stream/main/pipeline_hfp_stream_example.c +++ b/examples/player/pipeline_hfp_stream/main/pipeline_hfp_stream_example.c @@ -19,7 +19,7 @@ #include "board.h" #include "hfp_stream.h" -static const char *TAG = "BLUETOOTH_EXAMPLE"; +static const char *TAG = "HFP_EXAMPLE"; static audio_element_handle_t hfp_in_stream, hfp_out_stream, i2s_stream_writer, i2s_stream_reader; static audio_pipeline_handle_t pipeline_in, pipeline_out; @@ -34,13 +34,9 @@ static void bt_app_hf_client_audio_open(hfp_data_enc_type_t type) sample_rate = 16000; } else { ESP_LOGE(TAG, "error hfp enc type = %d", type); - } - -#if defined CONFIG_ESP_LYRAT_MINI_V1_1_BOARD + } i2s_stream_set_clk(i2s_stream_reader, sample_rate, 16, 1); -#endif i2s_stream_set_clk(i2s_stream_writer, sample_rate, 16, 1); - audio_pipeline_run(pipeline_out); audio_pipeline_resume(pipeline_out); } @@ -87,7 +83,11 @@ void app_main(void) esp_bt_dev_set_device_name("ESP-ADF-HFP"); hfp_open_and_close_evt_cb_register(bt_app_hf_client_audio_open, bt_app_hf_client_audio_close); hfp_service_init(); +#if (ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(4, 0, 0)) + esp_bt_gap_set_scan_mode(ESP_BT_CONNECTABLE, ESP_BT_GENERAL_DISCOVERABLE); +#else esp_bt_gap_set_scan_mode(ESP_BT_SCAN_MODE_CONNECTABLE_DISCOVERABLE); +#endif ESP_LOGI(TAG, "[ 2 ] Start codec chip"); audio_board_handle_t board_handle = audio_board_init(); @@ -102,21 +102,14 @@ void app_main(void) i2s_stream_cfg_t i2s_cfg1 = I2S_STREAM_CFG_DEFAULT(); i2s_cfg1.type = AUDIO_STREAM_READER; #if defined CONFIG_ESP_LYRAT_MINI_V1_1_BOARD + i2s_cfg1.i2s_config.use_apll = false; i2s_cfg1.i2s_port = 1; #endif i2s_stream_reader = i2s_stream_init(&i2s_cfg1); - i2s_stream_cfg_t i2s_cfg2 = I2S_STREAM_CFG_DEFAULT(); i2s_cfg2.type = AUDIO_STREAM_WRITER; i2s_stream_writer = i2s_stream_init(&i2s_cfg2); - -#if defined CONFIG_ESP_LYRAT_MINI_V1_1_BOARD - i2s_stream_set_clk(i2s_stream_reader, 8000, 16, 1); -#endif - i2s_stream_set_clk(i2s_stream_writer, 8000, 16, 1); - - ESP_LOGI(TAG, "[3.2] Get hfp stream"); hfp_stream_config_t hfp_config; hfp_config.type = OUTGOING_STREAM; @@ -164,11 +157,6 @@ void app_main(void) continue; } - if (msg.cmd == AEL_MSG_CMD_ERROR) { - ESP_LOGE(TAG, "[ * ] Action command error: src_type:%d, source:%p cmd:%d, data:%p, data_len:%d", - msg.source_type, msg.source, msg.cmd, msg.data, msg.data_len); - } - /* Stop when the last pipeline element (i2s_stream_writer in this case) receives stop event */ if (msg.source_type == AUDIO_ELEMENT_TYPE_ELEMENT && msg.source == (void *) i2s_stream_writer && msg.cmd == AEL_MSG_CMD_REPORT_STATUS && (int) msg.data == AEL_STATUS_STATE_STOPPED) { @@ -211,5 +199,3 @@ void app_main(void) audio_element_deinit(hfp_out_stream); esp_periph_set_destroy(set); } - - diff --git a/examples/player/pipeline_hfp_stream/sdkconfig.defaults b/examples/player/pipeline_hfp_stream/sdkconfig.defaults index 07c47fa..c57e1bd 100644 --- a/examples/player/pipeline_hfp_stream/sdkconfig.defaults +++ b/examples/player/pipeline_hfp_stream/sdkconfig.defaults @@ -3,13 +3,6 @@ CONFIG_BT_ENABLED=y CONFIG_BLUEDROID_ENABLED=y CONFIG_CLASSIC_BT_ENABLED=y -CONFIG_A2DP_ENABLE= -CONFIG_A2DP_SINK_ENABLE= -CONFIG_A2DP_SRC_ENABLE= -CONFIG_BT_SPP_ENABLED= -CONFIG_GATTS_ENABLE= -CONFIG_GATTC_ENABLE= -CONFIG_BLE_SMP_ENABLE= CONFIG_BTDM_CONTROLLER_MODE_BR_EDR_ONLY=y CONFIG_BTDM_CONTROLLER_BR_EDR_MAX_SYNC_CONN=2 diff --git a/examples/player/pipeline_http_mp3/main/play_http_mp3_example.c b/examples/player/pipeline_http_mp3/main/play_http_mp3_example.c index 2f165ef..1910600 100644 --- a/examples/player/pipeline_http_mp3/main/play_http_mp3_example.c +++ b/examples/player/pipeline_http_mp3/main/play_http_mp3_example.c @@ -27,6 +27,18 @@ #include "periph_wifi.h" #include "board.h" +#if __has_include("esp_idf_version.h") +#include "esp_idf_version.h" +#else +#define ESP_IDF_VERSION_VAL(major, minor, patch) 1 +#endif + +#if (ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(4, 1, 0)) +#include "esp_netif.h" +#else +#include "tcpip_adapter.h" +#endif + static const char *TAG = "HTTP_MP3_EXAMPLE"; void app_main(void) @@ -38,7 +50,11 @@ void app_main(void) ESP_ERROR_CHECK(nvs_flash_erase()); err = nvs_flash_init(); } +#if (ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(4, 1, 0)) + ESP_ERROR_CHECK(esp_netif_init()); +#else tcpip_adapter_init(); +#endif audio_pipeline_handle_t pipeline; audio_element_handle_t http_stream_reader, i2s_stream_writer, mp3_decoder; diff --git a/examples/player/pipeline_http_opus/CMakeLists.txt b/examples/player/pipeline_http_opus/CMakeLists.txt new file mode 100644 index 0000000..fd7c4db --- /dev/null +++ b/examples/player/pipeline_http_opus/CMakeLists.txt @@ -0,0 +1,8 @@ +# 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{ADF_PATH}/CMakeLists.txt) +include($ENV{IDF_PATH}/tools/cmake/project.cmake) + +project(play_http_mp3) \ No newline at end of file diff --git a/examples/player/pipeline_http_opus/Makefile b/examples/player/pipeline_http_opus/Makefile new file mode 100644 index 0000000..6579a88 --- /dev/null +++ b/examples/player/pipeline_http_opus/Makefile @@ -0,0 +1,3 @@ +PROJECT_NAME := play_http_mp3 +include $(ADF_PATH)/project.mk + diff --git a/examples/player/pipeline_http_opus/README.md b/examples/player/pipeline_http_opus/README.md new file mode 100644 index 0000000..ca8571d --- /dev/null +++ b/examples/player/pipeline_http_opus/README.md @@ -0,0 +1,31 @@ +# Play mp3 file from HTTP + +The example plays a MP3 downloaded from HTTP. + +## Compatibility + +This example is will run on boards marked with green checkbox. Please remember to select the board in menuconfig as discussed is section *Usage* below. + +| Board Name | Getting Started | Chip | Compatible | +|-------------------|:--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------:|:--------------------------------------------------------------------:|:-----------------------------------------------------------------:| +| ESP32-LyraT | [![alt text](../../../docs/_static/esp32-lyrat-v4.3-side-small.jpg "ESP32-LyraT")](https://docs.espressif.com/projects/esp-adf/en/latest/get-started/get-started-esp32-lyrat.html) | ESP32 | ![alt text](../../../docs/_static/yes-button.png "Compatible") | +| ESP32-LyraTD-MSC | [![alt text](../../../docs/_static/esp32-lyratd-msc-v2.2-small.jpg "ESP32-LyraTD-MSC")](https://docs.espressif.com/projects/esp-adf/en/latest/get-started/get-started-esp32-lyratd-msc.html) | ESP32 | ![alt text](../../../docs/_static/yes-button.png "Compatible") | +| ESP32-LyraT-Mini | [![alt text](../../../docs/_static/esp32-lyrat-mini-v1.2-small.jpg "ESP32-LyraT-Mini")](https://docs.espressif.com/projects/esp-adf/en/latest/get-started/get-started-esp32-lyrat-mini.html) | ESP32 | ![alt text](../../../docs/_static/yes-button.png "Compatible") | +| ESP32-Korvo-DU1906 | [![alt text](../../../docs/_static/esp32-korvo-du1906-v1.1-small.jpg "ESP32-Korvo-DU1906")](https://docs.espressif.com/projects/esp-adf/en/latest/get-started/get-started-esp32-korvo-du1906.html) | ESP32 | ![alt text](../../../docs/_static/yes-button.png "Compatible") | +| ESP32-S2-Kaluga-1 Kit | [![alt text](../../../docs/_static/esp32-s2-kaluga-1-kit-small.png "ESP32-S2-Kaluga-1 Kit")](https://docs.espressif.com/projects/esp-idf/en/latest/esp32s2/hw-reference/esp32s2/user-guide-esp32-s2-kaluga-1-kit.html) | ESP32-S2 | ![alt text](../../../docs/_static/yes-button.png "Compatible") | + +## Usage + +Prepare the audio board: + +- Connect speakers or headphones to the board. + +Configure the example: + +- Select compatible audio board in `menuconfig` > `Audio HAL`. +- Set up the Wi-Fi connection by running `menuconfig` > `Example Configuration` and filling in `WiFi SSID` and `WiFi Password`. + +Load and run the example: + +- The audio board will first connect to the Wi-Fi. +- Then the board will start playing automatically. \ No newline at end of file diff --git a/examples/player/pipeline_http_opus/main/CMakeLists.txt b/examples/player/pipeline_http_opus/main/CMakeLists.txt new file mode 100644 index 0000000..86cd861 --- /dev/null +++ b/examples/player/pipeline_http_opus/main/CMakeLists.txt @@ -0,0 +1,4 @@ +set(COMPONENT_SRCS "play_http_opus_example.c") +set(COMPONENT_ADD_INCLUDEDIRS .) + +register_component() \ No newline at end of file diff --git a/examples/player/pipeline_http_opus/main/Kconfig.projbuild b/examples/player/pipeline_http_opus/main/Kconfig.projbuild new file mode 100644 index 0000000..98c2080 --- /dev/null +++ b/examples/player/pipeline_http_opus/main/Kconfig.projbuild @@ -0,0 +1,17 @@ +menu "Example Configuration" + +config WIFI_SSID + string "WiFi SSID" + default "myssid" + help + SSID (network name) for the example to connect to. + +config WIFI_PASSWORD + string "WiFi Password" + default "mypassword" + help + WiFi password (WPA or WPA2) for the example to use. + + Can be left blank if the network has no security set. + +endmenu \ No newline at end of file diff --git a/examples/player/pipeline_http_opus/main/component.mk b/examples/player/pipeline_http_opus/main/component.mk new file mode 100644 index 0000000..44bd2b5 --- /dev/null +++ b/examples/player/pipeline_http_opus/main/component.mk @@ -0,0 +1,3 @@ +# +# Main Makefile. This is basically the same as a component makefile. +# diff --git a/examples/player/pipeline_http_opus/main/play_http_opus_example.c b/examples/player/pipeline_http_opus/main/play_http_opus_example.c new file mode 100644 index 0000000..8285bb1 --- /dev/null +++ b/examples/player/pipeline_http_opus/main/play_http_opus_example.c @@ -0,0 +1,171 @@ +/* Play an MP3 file from HTTP + + 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 +#include "freertos/FreeRTOS.h" +#include "freertos/task.h" +#include "freertos/event_groups.h" +#include "esp_log.h" +#include "esp_wifi.h" +#include "nvs_flash.h" +#include "sdkconfig.h" +#include "audio_element.h" +#include "audio_pipeline.h" +#include "audio_event_iface.h" +#include "audio_common.h" +#include "http_stream.h" +#include "i2s_stream.h" +#include "opus_decoder.h" + +#include "esp_peripherals.h" +#include "periph_wifi.h" +#include "board.h" + +static const char *TAG = "HTTP_MP3_EXAMPLE"; + +void app_main(void) +{ + esp_err_t err = nvs_flash_init(); + if (err == ESP_ERR_NVS_NO_FREE_PAGES) { + // NVS partition was truncated and needs to be erased + // Retry nvs_flash_init + ESP_ERROR_CHECK(nvs_flash_erase()); + err = nvs_flash_init(); + } + tcpip_adapter_init(); + + audio_pipeline_handle_t pipeline; + audio_element_handle_t http_stream_reader, i2s_stream_writer,opus_decoder; + + esp_log_level_set("*", ESP_LOG_WARN); + esp_log_level_set(TAG, ESP_LOG_DEBUG); + + ESP_LOGI(TAG, "[ 1 ] Start audio codec chip"); + audio_board_handle_t board_handle = audio_board_init(); + audio_hal_ctrl_codec(board_handle->audio_hal, AUDIO_HAL_CODEC_MODE_DECODE, AUDIO_HAL_CTRL_START); + + ESP_LOGI(TAG, "[2.0] Create audio pipeline for playback"); + audio_pipeline_cfg_t pipeline_cfg = DEFAULT_AUDIO_PIPELINE_CONFIG(); + pipeline = audio_pipeline_init(&pipeline_cfg); + mem_assert(pipeline); + + ESP_LOGI(TAG, "[2.1] Create http stream to read data"); + http_stream_cfg_t http_cfg = HTTP_STREAM_CFG_DEFAULT(); + // http_cfg.task_core = 1; + // http_cfg.task_prio = 1; + http_stream_reader = http_stream_init(&http_cfg); + + ESP_LOGI(TAG, "[2.2] Create i2s stream to write data to codec chip"); + i2s_stream_cfg_t i2s_cfg = I2S_STREAM_CFG_DEFAULT(); + i2s_cfg.type = AUDIO_STREAM_WRITER; + // i2s_cfg.task_core = 0; + // i2s_cfg.task_prio = 50; + i2s_stream_writer = i2s_stream_init(&i2s_cfg); + + ESP_LOGI(TAG, "[2.3] Create opus decoder to decode opus file"); + opus_decoder_cfg_t opus_cfg = DEFAULT_OPUS_DECODER_CONFIG(); + opus_cfg.task_core = 1; + opus_cfg.task_prio = 10; + opus_decoder = decoder_opus_init(&opus_cfg); + + ESP_LOGI(TAG, "[2.4] Register all elements to audio pipeline"); + audio_pipeline_register(pipeline, http_stream_reader, "http"); + audio_pipeline_register(pipeline, opus_decoder, "opus"); + audio_pipeline_register(pipeline, i2s_stream_writer, "i2s"); + + ESP_LOGI(TAG, "[2.5] Link it together http_stream-->opus_decoder-->i2s_stream-->[codec_chip]"); + const char *link_tag[3] = {"http", "opus", "i2s"}; + audio_pipeline_link(pipeline, &link_tag[0], 3); + + // important !! esp32 can only decode single side opus with 44100hz. + // two side opus will be disfluency + ESP_LOGI(TAG, "[2.6] Set up uri (http as http_stream, opus as opus decoder, and default output is i2s)"); + audio_element_set_uri(http_stream_reader, "https://dl.espressif.com/dl/audio/ff-16b-1c-44100hz.opus"); + + ESP_LOGI(TAG, "[ 3 ] Start and wait for Wi-Fi network"); + esp_periph_config_t periph_cfg = DEFAULT_ESP_PERIPH_SET_CONFIG(); + esp_periph_set_handle_t set = esp_periph_set_init(&periph_cfg); + periph_wifi_cfg_t wifi_cfg = { + .ssid = CONFIG_WIFI_SSID, + .password = CONFIG_WIFI_PASSWORD, + }; + esp_periph_handle_t wifi_handle = periph_wifi_init(&wifi_cfg); + esp_periph_start(set, wifi_handle); + periph_wifi_wait_for_connected(wifi_handle, portMAX_DELAY); + + ESP_LOGI(TAG, "[ 4 ] Set up event listener"); + audio_event_iface_cfg_t evt_cfg = AUDIO_EVENT_IFACE_DEFAULT_CFG(); + audio_event_iface_handle_t evt = audio_event_iface_init(&evt_cfg); + + ESP_LOGI(TAG, "[4.1] Listening event from all elements of pipeline"); + audio_pipeline_set_listener(pipeline, evt); + + ESP_LOGI(TAG, "[4.2] Listening event from peripherals"); + audio_event_iface_set_listener(esp_periph_set_get_event_iface(set), evt); + + ESP_LOGI(TAG, "[ 5 ] Start audio_pipeline"); + audio_pipeline_run(pipeline); + + while (1) { + audio_event_iface_msg_t msg; + esp_err_t ret = audio_event_iface_listen(evt, &msg, portMAX_DELAY); + if (ret != ESP_OK) { + ESP_LOGE(TAG, "[ * ] Event interface error : %d", ret); + continue; + } + + if (msg.source_type == AUDIO_ELEMENT_TYPE_ELEMENT + && msg.source == (void *) opus_decoder + && msg.cmd == AEL_MSG_CMD_REPORT_MUSIC_INFO) { + audio_element_info_t music_info = {0}; + audio_element_getinfo(opus_decoder, &music_info); + + ESP_LOGI(TAG, "[ * ] Receive music info from opus decoder, sample_rates=%d, bits=%d, ch=%d", + music_info.sample_rates, music_info.bits, music_info.channels); + + audio_element_setinfo(i2s_stream_writer, &music_info); + i2s_stream_set_clk(i2s_stream_writer, music_info.sample_rates, music_info.bits, music_info.channels); + continue; + } + + /* Stop when the last pipeline element (i2s_stream_writer in this case) receives stop event */ + if (msg.source_type == AUDIO_ELEMENT_TYPE_ELEMENT && msg.source == (void *) i2s_stream_writer + && msg.cmd == AEL_MSG_CMD_REPORT_STATUS + && (((int)msg.data == AEL_STATUS_STATE_STOPPED) || ((int)msg.data == AEL_STATUS_STATE_FINISHED))) { + ESP_LOGW(TAG, "[ * ] Stop event received"); + break; + } + } + + ESP_LOGI(TAG, "[ 6 ] Stop audio_pipeline"); + audio_pipeline_stop(pipeline); + audio_pipeline_wait_for_stop(pipeline); + audio_pipeline_terminate(pipeline); + + /* Terminate the pipeline before removing the listener */ + audio_pipeline_unregister(pipeline, http_stream_reader); + audio_pipeline_unregister(pipeline, i2s_stream_writer); + audio_pipeline_unregister(pipeline, opus_decoder); + + audio_pipeline_remove_listener(pipeline); + + /* Stop all peripherals before removing the listener */ + esp_periph_set_stop_all(set); + audio_event_iface_remove_listener(esp_periph_set_get_event_iface(set), evt); + + /* Make sure audio_pipeline_remove_listener & audio_event_iface_remove_listener are called before destroying event_iface */ + audio_event_iface_destroy(evt); + + /* Release all resources */ + audio_pipeline_deinit(pipeline); + audio_element_deinit(http_stream_reader); + audio_element_deinit(i2s_stream_writer); + audio_element_deinit(opus_decoder); + esp_periph_set_destroy(set); +} diff --git a/examples/player/pipeline_http_opus/partitions.csv b/examples/player/pipeline_http_opus/partitions.csv new file mode 100644 index 0000000..e43e81a --- /dev/null +++ b/examples/player/pipeline_http_opus/partitions.csv @@ -0,0 +1,4 @@ +# Name, Type, SubType, Offset, Size +nvs, data, nvs, 0x9000, 0x4000 +phy_init, data, phy, 0xd000, 0x1000 +factory, app, factory, 0x10000, 3M, diff --git a/examples/player/pipeline_http_select_decoder/main/play_http_select_decoder_example.c b/examples/player/pipeline_http_select_decoder/main/play_http_select_decoder_example.c index c213a3f..ab40135 100644 --- a/examples/player/pipeline_http_select_decoder/main/play_http_select_decoder_example.c +++ b/examples/player/pipeline_http_select_decoder/main/play_http_select_decoder_example.c @@ -25,6 +25,18 @@ #include "periph_wifi.h" #include "board.h" +#if __has_include("esp_idf_version.h") +#include "esp_idf_version.h" +#else +#define ESP_IDF_VERSION_VAL(major, minor, patch) 1 +#endif + +#if (ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(4, 1, 0)) +#include "esp_netif.h" +#else +#include "tcpip_adapter.h" +#endif + #define SELECT_AAC_DECODER 1 #if defined SELECT_AAC_DECODER @@ -74,7 +86,11 @@ void app_main(void) ESP_ERROR_CHECK(nvs_flash_erase()); err = nvs_flash_init(); } +#if (ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(4, 1, 0)) + ESP_ERROR_CHECK(esp_netif_init()); +#else tcpip_adapter_init(); +#endif audio_pipeline_handle_t pipeline; audio_element_handle_t http_stream_reader, i2s_stream_writer, selected_decoder; diff --git a/examples/player/pipeline_living_stream/main/play_living_stream_example.c b/examples/player/pipeline_living_stream/main/play_living_stream_example.c index 262bf59..1aadc1d 100644 --- a/examples/player/pipeline_living_stream/main/play_living_stream_example.c +++ b/examples/player/pipeline_living_stream/main/play_living_stream_example.c @@ -27,6 +27,18 @@ #include "periph_wifi.h" #include "board.h" +#if __has_include("esp_idf_version.h") +#include "esp_idf_version.h" +#else +#define ESP_IDF_VERSION_VAL(major, minor, patch) 1 +#endif + +#if (ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(4, 1, 0)) +#include "esp_netif.h" +#else +#include "tcpip_adapter.h" +#endif + static const char *TAG = "HTTP_LIVINGSTREAM_EXAMPLE"; #define AAC_STREAM_URI "http://open.ls.qingting.fm/live/274/64k.m3u8?format=aac" @@ -53,7 +65,11 @@ void app_main(void) ESP_ERROR_CHECK(nvs_flash_erase()); err = nvs_flash_init(); } +#if (ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(4, 1, 0)) + ESP_ERROR_CHECK(esp_netif_init()); +#else tcpip_adapter_init(); +#endif audio_pipeline_handle_t pipeline; audio_element_handle_t http_stream_reader, i2s_stream_writer, aac_decoder; diff --git a/examples/player/pipeline_sdcard_mp3/main/play_sdcard_mp3_example.c b/examples/player/pipeline_sdcard_mp3/main/play_sdcard_mp3_example.c index 2c55490..05da0e2 100644 --- a/examples/player/pipeline_sdcard_mp3/main/play_sdcard_mp3_example.c +++ b/examples/player/pipeline_sdcard_mp3/main/play_sdcard_mp3_example.c @@ -40,7 +40,7 @@ void app_main(void) esp_periph_set_handle_t set = esp_periph_set_init(&periph_cfg); // Initialize SD Card peripheral - audio_board_sdcard_init(set); + audio_board_sdcard_init(set, SD_MODE_1_LINE); ESP_LOGI(TAG, "[ 2 ] Start codec chip"); audio_board_handle_t board_handle = audio_board_init(); diff --git a/examples/player/pipeline_sdcard_mp3_control/main/play_sdcard_mp3_control_example.c b/examples/player/pipeline_sdcard_mp3_control/main/play_sdcard_mp3_control_example.c index dbd86c2..d9415f9 100644 --- a/examples/player/pipeline_sdcard_mp3_control/main/play_sdcard_mp3_control_example.c +++ b/examples/player/pipeline_sdcard_mp3_control/main/play_sdcard_mp3_control_example.c @@ -129,7 +129,7 @@ void app_main(void) ESP_LOGI(TAG, "[1.1] Initialize and start peripherals"); audio_board_key_init(set); - audio_board_sdcard_init(set); + audio_board_sdcard_init(set, SD_MODE_1_LINE); ESP_LOGI(TAG, "[1.2] Set up a sdcard playlist and scan sdcard music save to it"); sdcard_list_create(&sdcard_list_handle); diff --git a/examples/player/pipeline_sdcard_wav/main/play_sdcard_wav_example.c b/examples/player/pipeline_sdcard_wav/main/play_sdcard_wav_example.c index d8a73ea..f55059c 100644 --- a/examples/player/pipeline_sdcard_wav/main/play_sdcard_wav_example.c +++ b/examples/player/pipeline_sdcard_wav/main/play_sdcard_wav_example.c @@ -39,7 +39,7 @@ void app_main(void) esp_periph_set_handle_t set = esp_periph_set_init(&periph_cfg); // Initialize SD Card peripheral - audio_board_sdcard_init(set); + audio_board_sdcard_init(set, SD_MODE_1_LINE); ESP_LOGI(TAG, "[ 2 ] Start codec chip"); audio_board_handle_t board_handle = audio_board_init(); diff --git a/examples/player/pipeline_tts_stream/CMakeLists.txt b/examples/player/pipeline_tts_stream/CMakeLists.txt new file mode 100644 index 0000000..c4d3c04 --- /dev/null +++ b/examples/player/pipeline_tts_stream/CMakeLists.txt @@ -0,0 +1,8 @@ +# 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{ADF_PATH}/CMakeLists.txt) +include($ENV{IDF_PATH}/tools/cmake/project.cmake) + +project(play_tts_example) diff --git a/examples/player/pipeline_tts_stream/Makefile b/examples/player/pipeline_tts_stream/Makefile new file mode 100644 index 0000000..c20fb1b --- /dev/null +++ b/examples/player/pipeline_tts_stream/Makefile @@ -0,0 +1,2 @@ +PROJECT_NAME := play_tts_example +include $(ADF_PATH)/project.mk diff --git a/examples/player/pipeline_tts_stream/README.md b/examples/player/pipeline_tts_stream/README.md new file mode 100644 index 0000000..da43055 --- /dev/null +++ b/examples/player/pipeline_tts_stream/README.md @@ -0,0 +1,154 @@ + +# _Chinese TTS Stream Example_ + +This example is to convert Chinese text into Chinese pronunciation. If the input text is a mixture of Chinese and English, the English words will be read letter by letter. If the customer needs English TTS(Text To Speech) customization, you can send an email to the business for individual customization. + + +## 1. How to use example + +#### Hardware Required + +This example is will run on boards marked with green checkbox. Please remember to select the board in menuconfig as discussed is section *Usage* below. + +| Board Name | Getting Started | Chip | Compatible | +|-------------------|:--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------:|:--------------------------------------------------------------------:|:-----------------------------------------------------------------:| +| ESP32-LyraT | [![alt text](../../../docs/_static/esp32-lyrat-v4.3-side-small.jpg "ESP32-LyraT")](https://docs.espressif.com/projects/esp-adf/en/latest/get-started/get-started-esp32-lyrat.html) | ESP32 | ![alt text](../../../docs/_static/yes-button.png "Compatible") | +| ESP32-LyraTD-MSC | [![alt text](../../../docs/_static/esp32-lyratd-msc-v2.2-small.jpg "ESP32-LyraTD-MSC")](https://docs.espressif.com/projects/esp-adf/en/latest/get-started/get-started-esp32-lyratd-msc.html) | ESP32 | ![alt text](../../../docs/_static/yes-button.png "Compatible") | +| ESP32-LyraT-Mini | [![alt text](../../../docs/_static/esp32-lyrat-mini-v1.2-small.jpg "ESP32-LyraT-Mini")](https://docs.espressif.com/projects/esp-adf/en/latest/get-started/get-started-esp32-lyrat-mini.html) | ESP32 | ![alt text](../../../docs/_static/yes-button.png "Compatible") | +| ESP32-Korvo-DU1906 | [![alt text](../../../docs/_static/esp32-korvo-du1906-v1.1-small.jpg "ESP32-Korvo-DU1906")](https://docs.espressif.com/projects/esp-adf/en/latest/get-started/get-started-esp32-korvo-du1906.html) | ESP32 | ![alt text](../../../docs/_static/yes-button.png "Compatible") | +| ESP32-S2-Kaluga-1 Kit | [![alt text](../../../docs/_static/esp32-s2-kaluga-1-kit-small.png "ESP32-S2-Kaluga-1 Kit")](https://docs.espressif.com/projects/esp-idf/en/latest/esp32s2/hw-reference/esp32s2/user-guide-esp32-s2-kaluga-1-kit.html) | ESP32-S2 | ![alt text](../../../docs/_static/no-button.png "Compatible") | + +## 2. Setup software environment + +Please refer to [Get Started](https://docs.espressif.com/projects/esp-adf/en/latest/get-started/index.html#get-started). + +#### Configure the project +cmake menuconfig: +``` +idf.py menuconfig +``` +Or use legacy GNU make: +``` +make menuconfig +``` +Select compatible audio board in ``menuconfig > Audio HAL``, then compile the example. + +#### Build and Flash +You can use `GNU make` or `cmake` to build the project. +If you are using make: +```bash +cd $ADF_PATH/examples/player/pipeline_tts_stream +make clean +make menuconfig +make -j4 all +``` + +Or if you are using cmake: +```bash +cd $ADF_PATH/examples/player/pipeline_tts_stream +idf.py fullclean +idf.py menuconfig +idf.py build +``` +The firmware downloading flash address refer to follow table. + +|Flash address | Bin Path| +|---|---| +|0x1000 | build/bootloader/bootloader.bin| +|0x8000 | build/partitions.bin| +|0x10000 | build/play_tts_example.bin| +|0x100000 | components/esp-sr/esp-tts/esp_tts_chinese/esp_tts_voice_data_xiaole.dat| + + +Build the project and flash it to the board, then run monitor tool to view serial output + +- Flash `components/esp-tts/esp_tts_chinese/esp_tts_voice_data_xiaole.dat` to partition table address +- Then flash the app bin, the board will start playing automatically. + +To exit the serial monitor, type ``Ctrl-]``. + + +## 3. Example Output + +After download the follow logs should be output, here: + +``` +I (10) boot: ESP-IDF v3.3.2-107-g722043f73-dirty 2nd stage bootloader +I (10) boot: compile time 15:04:38 +I (11) boot: Enabling RNG early entropy source... +I (16) qio_mode: Enabling default flash chip QIO +I (21) boot: SPI Speed : 80MHz +I (25) boot: SPI Mode : QIO +I (29) boot: SPI Flash Size : 8MB +I (33) boot: Partition Table: +I (37) boot: ## Label Usage Type ST Offset Length +I (44) boot: 0 factory factory app 00 00 00010000 000e0000 +I (52) boot: 1 voice_data Unknown data 01 81 00100000 00300000 +I (59) boot: End of partition table +I (63) boot_comm: chip revision: 1, min. application chip revision: 0 +I (70) esp_image: segment 0: paddr=0x00010020 vaddr=0x3f400020 size=0x16a74 ( 92788) map +I (104) esp_image: segment 1: paddr=0x00026a9c vaddr=0x3ffb0000 size=0x03aac ( 15020) load +I (109) esp_image: segment 2: paddr=0x0002a550 vaddr=0x40080000 size=0x00400 ( 1024) load +0x40080000: _WindowOverflow4 at /repo/workspace/experiments/esp-adf-internal/esp-idf/components/freertos/xtensa_vectors.S:1779 + +I (111) esp_image: segment 3: paddr=0x0002a958 vaddr=0x40080400 size=0x056b8 ( 22200) load +I (127) esp_image: segment 4: paddr=0x00030018 vaddr=0x400d0018 size=0x27238 (160312) map +0x400d0018: _flash_cache_start at ??:? + +I (171) esp_image: segment 5: paddr=0x00057258 vaddr=0x40085ab8 size=0x049b8 ( 18872) load +0x40085ab8: rtc_init at /repo/workspace/experiments/esp-adf-internal/esp-idf/components/soc/esp32/rtc_init.c:40 + +I (184) boot: Loaded app from partition at offset 0x10000 +I (184) boot: Disabling RNG early entropy source... +I (185) cpu_start: Pro cpu up. +I (188) cpu_start: Application information: +I (193) cpu_start: Project name: play_tts_example +I (199) cpu_start: App version: v2.1-93-g9fab9a49-dirty +I (205) cpu_start: Compile time: Nov 6 2020 15:04:37 +I (211) cpu_start: ELF file SHA256: 29860e7987740ea4... +I (217) cpu_start: ESP-IDF: v3.3.2-107-g722043f73-dirty +I (224) cpu_start: Starting app cpu, entry point is 0x40081044 +0x40081044: call_start_cpu1 at /repo/workspace/experiments/esp-adf-internal/esp-idf/components/esp32/cpu_start.c:268 + +I (0) cpu_start: App cpu up. +I (234) heap_init: Initializing. RAM available for dynamic allocation: +I (241) heap_init: At 3FFAE6E0 len 00001920 (6 KiB): DRAM +I (247) heap_init: At 3FFB50C0 len 0002AF40 (171 KiB): DRAM +I (253) heap_init: At 3FFE0440 len 00003AE0 (14 KiB): D/IRAM +I (260) heap_init: At 3FFE4350 len 0001BCB0 (111 KiB): D/IRAM +I (266) heap_init: At 4008A470 len 00015B90 (86 KiB): IRAM +I (272) cpu_start: Pro cpu start user code +I (66) cpu_start: Starting scheduler on PRO CPU. +I (0) cpu_start: Starting scheduler on APP CPU. +I (66) PLAY_TTS_EXAMPLE: [1.0] Init Peripheral Set +I (66) PLAY_TTS_EXAMPLE: [2.0] Start codec chip +W (96) I2C_BUS: i2c_bus_create:57: I2C bus has been already created, [port:0] +I (106) PLAY_TTS_EXAMPLE: [3.0] Create audio pipeline for playback +I (106) PLAY_TTS_EXAMPLE: [3.1] Create tts stream to read data from chinese strings +inti voice set:template +ESP Chinese TTS v1.0 (Jul 1 2020 16:09:41) +I (116) PLAY_TTS_EXAMPLE: [3.2] Create i2s stream to write data to codec chip +I (126) PLAY_TTS_EXAMPLE: [3.4] Register all elements to audio pipeline +I (126) PLAY_TTS_EXAMPLE: [3.5] Link it together [strings]-->tts_stream-->i2s_stream-->[codec_chip] +I (136) PLAY_TTS_EXAMPLE: [3.6] Set up uri (tts as tts_stream, and directly output is i2s) +I (146) PLAY_TTS_EXAMPLE: [3.7] 欢迎使用乐鑫语音开源框架 +I (156) PLAY_TTS_EXAMPLE: [4.0] Set up event listener +I (156) PLAY_TTS_EXAMPLE: [4.1] Listening event from all elements of pipeline +I (166) PLAY_TTS_EXAMPLE: [4.2] Listening event from peripherals +I (176) PLAY_TTS_EXAMPLE: [5.0] Start audio_pipeline +I (286) PLAY_TTS_EXAMPLE: [6.0] Listen for all pipeline events +W (2986) TTS_STREAM: No more data,ret:0 +W (3496) PLAY_TTS_EXAMPLE: [ * ] Stop event received +I (3496) PLAY_TTS_EXAMPLE: [7.0] Stop audio_pipeline +W (3496) AUDIO_PIPELINE: There are no listener registered +W (3506) AUDIO_ELEMENT: [tts] Element has not create when AUDIO_ELEMENT_TERMINATE +W (3516) AUDIO_ELEMENT: [i2s] Element has not create when AUDIO_ELEMENT_TERMINATE + +``` + + +## 4. Troubleshooting + +- If you encounter a situation where TTS doesn't play sound, try checking to see if the ``esp_tts_voice_data_xiaole.dat`` file has been flashed to the specified address. + + diff --git a/examples/player/pipeline_tts_stream/main/CMakeLists.txt b/examples/player/pipeline_tts_stream/main/CMakeLists.txt new file mode 100644 index 0000000..ab55a35 --- /dev/null +++ b/examples/player/pipeline_tts_stream/main/CMakeLists.txt @@ -0,0 +1,4 @@ +set(COMPONENT_SRCS "play_tts_example.c") +set(COMPONENT_ADD_INCLUDEDIRS .) + +register_component() diff --git a/examples/player/pipeline_tts_stream/main/component.mk b/examples/player/pipeline_tts_stream/main/component.mk new file mode 100644 index 0000000..44bd2b5 --- /dev/null +++ b/examples/player/pipeline_tts_stream/main/component.mk @@ -0,0 +1,3 @@ +# +# Main Makefile. This is basically the same as a component makefile. +# diff --git a/examples/player/pipeline_tts_stream/main/play_tts_example.c b/examples/player/pipeline_tts_stream/main/play_tts_example.c new file mode 100644 index 0000000..4e0b43b --- /dev/null +++ b/examples/player/pipeline_tts_stream/main/play_tts_example.c @@ -0,0 +1,135 @@ +/* Play pcm stream from tts stream, which can input chinese string + + 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 +#include "freertos/FreeRTOS.h" +#include "freertos/task.h" +#include "esp_log.h" +#include "sdkconfig.h" +#include "audio_element.h" +#include "audio_pipeline.h" +#include "audio_event_iface.h" +#include "audio_common.h" +#include "tts_stream.h" +#include "i2s_stream.h" +#include "esp_peripherals.h" +#include "board.h" + +bool play_once_flag = true; +static const char *TAG = "PLAY_TTS_EXAMPLE"; +static const char *CHINESE_STRINGS = "欢迎使用乐鑫语音开源框架"; + +void app_main(void) +{ + audio_pipeline_handle_t pipeline; + audio_element_handle_t tts_stream_reader, i2s_stream_writer; + + esp_log_level_set("*", ESP_LOG_WARN); + esp_log_level_set(TAG, ESP_LOG_INFO); + + ESP_LOGI(TAG, "[1.0] Init Peripheral Set"); + esp_periph_config_t periph_cfg = DEFAULT_ESP_PERIPH_SET_CONFIG(); + esp_periph_set_handle_t set = esp_periph_set_init(&periph_cfg); + + ESP_LOGI(TAG, "[2.0] Start codec chip"); + audio_board_handle_t board_handle = audio_board_init(); + audio_hal_ctrl_codec(board_handle->audio_hal, AUDIO_HAL_CODEC_MODE_DECODE, AUDIO_HAL_CTRL_START); + + ESP_LOGI(TAG, "[3.0] Create audio pipeline for playback"); + audio_pipeline_cfg_t pipeline_cfg = DEFAULT_AUDIO_PIPELINE_CONFIG(); + pipeline = audio_pipeline_init(&pipeline_cfg); + mem_assert(pipeline); + + ESP_LOGI(TAG, "[3.1] Create tts stream to read data from chinese strings"); + tts_stream_cfg_t tts_cfg = TTS_STREAM_CFG_DEFAULT(); + tts_cfg.type = AUDIO_STREAM_READER; + tts_stream_reader = tts_stream_init(&tts_cfg); + + ESP_LOGI(TAG, "[3.2] Create i2s stream to write data to codec chip"); + i2s_stream_cfg_t i2s_cfg = I2S_STREAM_CFG_DEFAULT(); + i2s_cfg.type = AUDIO_STREAM_WRITER; + i2s_cfg.i2s_config.sample_rate = 16000; + i2s_cfg.i2s_config.channel_format = I2S_CHANNEL_FMT_ONLY_LEFT; + i2s_stream_writer = i2s_stream_init(&i2s_cfg); + + ESP_LOGI(TAG, "[3.4] Register all elements to audio pipeline"); + audio_pipeline_register(pipeline, tts_stream_reader, "tts"); + audio_pipeline_register(pipeline, i2s_stream_writer, "i2s"); + + ESP_LOGI(TAG, "[3.5] Link it together [strings]-->tts_stream-->i2s_stream-->[codec_chip]"); + const char *link_tag[2] = {"tts", "i2s"}; + audio_pipeline_link(pipeline, &link_tag[0], 2); + + ESP_LOGI(TAG, "[3.6] Set up uri (tts as tts_stream, and directly output is i2s)"); + tts_stream_set_strings(tts_stream_reader, CHINESE_STRINGS); + + ESP_LOGI(TAG, "[4.0] Set up event listener"); + audio_event_iface_cfg_t evt_cfg = AUDIO_EVENT_IFACE_DEFAULT_CFG(); + audio_event_iface_handle_t evt = audio_event_iface_init(&evt_cfg); + + ESP_LOGI(TAG, "[4.1] Listening event from all elements of pipeline"); + audio_pipeline_set_listener(pipeline, evt); + + ESP_LOGI(TAG, "[4.2] Listening event from peripherals"); + audio_event_iface_set_listener(esp_periph_set_get_event_iface(set), evt); + + ESP_LOGI(TAG, "[5.0] Start audio_pipeline"); + audio_pipeline_run(pipeline); + + ESP_LOGI(TAG, "[6.0] Listen for all pipeline events"); + + while (1) { + audio_event_iface_msg_t msg; + esp_err_t ret = audio_event_iface_listen(evt, &msg, portMAX_DELAY); + if (ret != ESP_OK) { + ESP_LOGE(TAG, "[ * ] Event interface error : %d", ret); + continue; + } + + /* Stop when the last pipeline element (i2s_stream_writer in this case) receives stop event */ + if (msg.source_type == AUDIO_ELEMENT_TYPE_ELEMENT && msg.source == (void *) i2s_stream_writer + && msg.cmd == AEL_MSG_CMD_REPORT_STATUS + && (((int)msg.data == AEL_STATUS_STATE_STOPPED) || ((int)msg.data == AEL_STATUS_STATE_FINISHED))) { + if(play_once_flag){ + play_once_flag = false; + ESP_LOGI(TAG, " [ * ] Start a new tts stream play"); + audio_pipeline_reset_ringbuffer(pipeline); + audio_pipeline_reset_elements(pipeline); + tts_stream_set_strings(tts_stream_reader, "乐鑫语音开源框架简称ADF"); + audio_pipeline_change_state(pipeline, AEL_STATE_INIT); + audio_pipeline_run(pipeline); + }else{ + ESP_LOGI(TAG, "[ * ] Stop event received"); + break; + } + } + } + + ESP_LOGI(TAG, "[7.0] Stop audio_pipeline"); + audio_pipeline_wait_for_stop(pipeline); + audio_pipeline_terminate(pipeline); + audio_pipeline_unregister(pipeline, tts_stream_reader); + audio_pipeline_unregister(pipeline, i2s_stream_writer); + + /* Terminal the pipeline before removing the listener */ + audio_pipeline_remove_listener(pipeline); + + /* Stop all periph before removing the listener */ + esp_periph_set_stop_all(set); + audio_event_iface_remove_listener(esp_periph_set_get_event_iface(set), evt); + + /* Make sure audio_pipeline_remove_listener & audio_event_iface_remove_listener are called before destroying event_iface */ + audio_event_iface_destroy(evt); + + /* Release all resources */ + audio_pipeline_deinit(pipeline); + audio_element_deinit(tts_stream_reader); + audio_element_deinit(i2s_stream_writer); + esp_periph_set_destroy(set); +} diff --git a/examples/player/pipeline_tts_stream/partitions.csv b/examples/player/pipeline_tts_stream/partitions.csv new file mode 100644 index 0000000..e9e91d4 --- /dev/null +++ b/examples/player/pipeline_tts_stream/partitions.csv @@ -0,0 +1,4 @@ +# Espressif ESP32 Partition Table +# Name, Type, SubType, Offset, Size + factory, app, factory, 0x010000, 0xE0000 + voice_data, data, fat, 0x100000, 3M diff --git a/examples/player/pipeline_tts_stream/sdkconfig.defaults b/examples/player/pipeline_tts_stream/sdkconfig.defaults new file mode 100644 index 0000000..be190c0 --- /dev/null +++ b/examples/player/pipeline_tts_stream/sdkconfig.defaults @@ -0,0 +1,44 @@ +# +# Automatically generated file; DO NOT EDIT. +# Espressif IoT Development Framework Configuration +# + +# +# Audio HAL +# +CONFIG_ESP_LYRAT_MINI_V1_1_BOARD=y + +# +# Serial flasher config +# +CONFIG_FLASHMODE_QIO=y +CONFIG_ESPTOOLPY_FLASHMODE="qio" +CONFIG_ESPTOOLPY_FLASHFREQ_80M=y +CONFIG_ESPTOOLPY_FLASHFREQ="80m" +CONFIG_ESPTOOLPY_FLASHSIZE_4MB=y +CONFIG_ESPTOOLPY_FLASHSIZE="4MB" +CONFIG_ESPTOOLPY_FLASHSIZE_DETECT=y + +# +# Partition Table +# +# CONFIG_PARTITION_TABLE_SINGLE_APP is not set +# CONFIG_PARTITION_TABLE_TWO_OTA is not set +CONFIG_PARTITION_TABLE_CUSTOM=y +CONFIG_PARTITION_TABLE_CUSTOM_FILENAME="partitions.csv" +CONFIG_PARTITION_TABLE_FILENAME="partitions.csv" +CONFIG_PARTITION_TABLE_OFFSET=0x8000 +CONFIG_PARTITION_TABLE_MD5=y +# end of Partition Table + +# +# FreeRTOS +# +CONFIG_FREERTOS_HZ=1000 + +# +# ESP32-specific +# +CONFIG_ESP32_DEFAULT_CPU_FREQ_240=y + + diff --git a/examples/recorder/element_cb_sdcard_amr/README.md b/examples/recorder/element_cb_sdcard_amr/README.md index 8cd57d5..da748c2 100644 --- a/examples/recorder/element_cb_sdcard_amr/README.md +++ b/examples/recorder/element_cb_sdcard_amr/README.md @@ -1,4 +1,4 @@ -# Recoding AMR file to microSD +# Recoding AMR file to microSD The example records 10 seconds AMR-NB or AMR-WB audio file to microSD Card. The AMR audio compression format is optimized for speech coding and produces much smaller output files comparing to other popular codecs. @@ -14,7 +14,7 @@ This example is will run on boards marked with green checkbox. Please remember t | ESP32-LyraT | [![alt text](../../../docs/_static/esp32-lyrat-v4.3-side-small.jpg "ESP32-LyraT")](https://docs.espressif.com/projects/esp-adf/en/latest/get-started/get-started-esp32-lyrat.html) | ESP32 | ![alt text](../../../docs/_static/yes-button.png "Compatible") | | ESP32-LyraTD-MSC | [![alt text](../../../docs/_static/esp32-lyratd-msc-v2.2-small.jpg "ESP32-LyraTD-MSC")](https://docs.espressif.com/projects/esp-adf/en/latest/get-started/get-started-esp32-lyratd-msc.html) | ESP32 | ![alt text](../../../docs/_static/yes-button.png "Compatible") | | ESP32-LyraT-Mini | [![alt text](../../../docs/_static/esp32-lyrat-mini-v1.2-small.jpg "ESP32-LyraT-Mini")](https://docs.espressif.com/projects/esp-adf/en/latest/get-started/get-started-esp32-lyrat-mini.html) | ESP32 | ![alt text](../../../docs/_static/yes-button.png "Compatible") | -| ESP32-Korvo-DU1906 | [![alt text](../../../docs/_static/esp32-korvo-du1906-v1.1-small.jpg "ESP32-Korvo-DU1906")](https://docs.espressif.com/projects/esp-adf/en/latest/get-started/get-started-esp32-korvo-du1906.html) | ESP32 | ![alt text](../../../docs/_static/yes-button.png "Compatible") | +| ESP32-Korvo-DU1906 | [![alt text](../../../docs/_static/esp32-korvo-du1906-v1.1-small.jpg "ESP32-Korvo-DU1906")](https://docs.espressif.com/projects/esp-adf/en/latest/get-started/get-started-esp32-korvo-du1906.html) | ESP32 | ![alt text](../../../docs/_static/no-button.png "Compatible") | | ESP32-S2-Kaluga-1 Kit | [![alt text](../../../docs/_static/esp32-s2-kaluga-1-kit-small.png "ESP32-S2-Kaluga-1 Kit")](https://docs.espressif.com/projects/esp-idf/en/latest/esp32s2/hw-reference/esp32s2/user-guide-esp32-s2-kaluga-1-kit.html) | ESP32-S2 | ![alt text](../../../docs/_static/no-button.png "Compatible") | ## Usage @@ -26,7 +26,7 @@ Prepare the audio board: Configure the example: - Select compatible audio board in `menuconfig` > `Audio HAL`. -- You may change between AMR-NB and AMR-WB encoder in `menuconfig` > `Example configuration` > `Audio encoder file type`. +- You may change between AMR-NB and AMR-WB encoder in `menuconfig` > `Example configuration` > `Audio encoder file type`. Load and run the example: diff --git a/examples/recorder/element_cb_sdcard_amr/main/element_cb_sdcard_amr.c b/examples/recorder/element_cb_sdcard_amr/main/element_cb_sdcard_amr.c index c47e282..3d12560 100644 --- a/examples/recorder/element_cb_sdcard_amr/main/element_cb_sdcard_amr.c +++ b/examples/recorder/element_cb_sdcard_amr/main/element_cb_sdcard_amr.c @@ -63,7 +63,7 @@ void app_main(void) esp_periph_set_handle_t set = esp_periph_set_init(&periph_cfg); // Initialize SD Card peripheral - audio_board_sdcard_init(set); + audio_board_sdcard_init(set, SD_MODE_1_LINE); ESP_LOGI(TAG, "[2.0] Start codec chip"); audio_board_handle_t board_handle = audio_board_init(); diff --git a/examples/recorder/element_wav_amr_sdcard/README.md b/examples/recorder/element_wav_amr_sdcard/README.md index 7d1b0d6..457637d 100644 --- a/examples/recorder/element_wav_amr_sdcard/README.md +++ b/examples/recorder/element_wav_amr_sdcard/README.md @@ -1,6 +1,6 @@ -# Recoding WAV and AMR file to microSD +# Recoding WAV and AMR file to microSD -The example records 10 seconds WAV and AMR(AMR-NB or AMR-WB) audio file to microSD card via audio element API. +The example records 10 seconds WAV and AMR(AMR-NB or AMR-WB) audio file to microSD card via audio element API. ## Compatibility @@ -11,7 +11,7 @@ This example is will run on boards marked with green checkbox. Please remember t | ESP32-LyraT | [![alt text](../../../docs/_static/esp32-lyrat-v4.3-side-small.jpg "ESP32-LyraT")](https://docs.espressif.com/projects/esp-adf/en/latest/get-started/get-started-esp32-lyrat.html) | ESP32 | ![alt text](../../../docs/_static/yes-button.png "Compatible") | | ESP32-LyraTD-MSC | [![alt text](../../../docs/_static/esp32-lyratd-msc-v2.2-small.jpg "ESP32-LyraTD-MSC")](https://docs.espressif.com/projects/esp-adf/en/latest/get-started/get-started-esp32-lyratd-msc.html) | ESP32 | ![alt text](../../../docs/_static/yes-button.png "Compatible") | | ESP32-LyraT-Mini | [![alt text](../../../docs/_static/esp32-lyrat-mini-v1.2-small.jpg "ESP32-LyraT-Mini")](https://docs.espressif.com/projects/esp-adf/en/latest/get-started/get-started-esp32-lyrat-mini.html) | ESP32 | ![alt text](../../../docs/_static/yes-button.png "Compatible") | -| ESP32-Korvo-DU1906 | [![alt text](../../../docs/_static/esp32-korvo-du1906-v1.1-small.jpg "ESP32-Korvo-DU1906")](https://docs.espressif.com/projects/esp-adf/en/latest/get-started/get-started-esp32-korvo-du1906.html) | ESP32 | ![alt text](../../../docs/_static/yes-button.png "Compatible") | +| ESP32-Korvo-DU1906 | [![alt text](../../../docs/_static/esp32-korvo-du1906-v1.1-small.jpg "ESP32-Korvo-DU1906")](https://docs.espressif.com/projects/esp-adf/en/latest/get-started/get-started-esp32-korvo-du1906.html) | ESP32 | ![alt text](../../../docs/_static/no-button.png "Compatible") | | ESP32-S2-Kaluga-1 Kit | [![alt text](../../../docs/_static/esp32-s2-kaluga-1-kit-small.png "ESP32-S2-Kaluga-1 Kit")](https://docs.espressif.com/projects/esp-idf/en/latest/esp32s2/hw-reference/esp32s2/user-guide-esp32-s2-kaluga-1-kit.html) | ESP32-S2 | ![alt text](../../../docs/_static/no-button.png "Compatible") | ## Usage diff --git a/examples/recorder/element_wav_amr_sdcard/main/element_wav_amr_sdcard.c b/examples/recorder/element_wav_amr_sdcard/main/element_wav_amr_sdcard.c index 1cc359c..7f3d6d9 100644 --- a/examples/recorder/element_wav_amr_sdcard/main/element_wav_amr_sdcard.c +++ b/examples/recorder/element_wav_amr_sdcard/main/element_wav_amr_sdcard.c @@ -61,7 +61,7 @@ void app_main() esp_periph_config_t periph_cfg = DEFAULT_ESP_PERIPH_SET_CONFIG(); esp_periph_set_handle_t set = esp_periph_set_init(&periph_cfg); // Initialize SD Card peripheral - audio_board_sdcard_init(set); + audio_board_sdcard_init(set, SD_MODE_1_LINE); ESP_LOGI(TAG, "[2.0] Start codec chip"); audio_board_handle_t board_handle = audio_board_init(); diff --git a/examples/recorder/pipeline_amr_sdcard/README.md b/examples/recorder/pipeline_amr_sdcard/README.md index 89360a1..411ae05 100644 --- a/examples/recorder/pipeline_amr_sdcard/README.md +++ b/examples/recorder/pipeline_amr_sdcard/README.md @@ -1,4 +1,4 @@ -# Recoding AMR file to microSD +# Recoding AMR file to microSD The example records 10 seconds AMR-NB or AMR-WB audio file to microSD Card. The AMR audio compression format is optimized for speech coding and produces much smaller output files comparing to other popular codecs. @@ -11,7 +11,7 @@ This example is will run on boards marked with green checkbox. Please remember t | ESP32-LyraT | [![alt text](../../../docs/_static/esp32-lyrat-v4.3-side-small.jpg "ESP32-LyraT")](https://docs.espressif.com/projects/esp-adf/en/latest/get-started/get-started-esp32-lyrat.html) | ESP32 | ![alt text](../../../docs/_static/yes-button.png "Compatible") | | ESP32-LyraTD-MSC | [![alt text](../../../docs/_static/esp32-lyratd-msc-v2.2-small.jpg "ESP32-LyraTD-MSC")](https://docs.espressif.com/projects/esp-adf/en/latest/get-started/get-started-esp32-lyratd-msc.html) | ESP32 | ![alt text](../../../docs/_static/yes-button.png "Compatible") | | ESP32-LyraT-Mini | [![alt text](../../../docs/_static/esp32-lyrat-mini-v1.2-small.jpg "ESP32-LyraT-Mini")](https://docs.espressif.com/projects/esp-adf/en/latest/get-started/get-started-esp32-lyrat-mini.html) | ESP32 | ![alt text](../../../docs/_static/yes-button.png "Compatible") | -| ESP32-Korvo-DU1906 | [![alt text](../../../docs/_static/esp32-korvo-du1906-v1.1-small.jpg "ESP32-Korvo-DU1906")](https://docs.espressif.com/projects/esp-adf/en/latest/get-started/get-started-esp32-korvo-du1906.html) | ESP32 | ![alt text](../../../docs/_static/yes-button.png "Compatible") | +| ESP32-Korvo-DU1906 | [![alt text](../../../docs/_static/esp32-korvo-du1906-v1.1-small.jpg "ESP32-Korvo-DU1906")](https://docs.espressif.com/projects/esp-adf/en/latest/get-started/get-started-esp32-korvo-du1906.html) | ESP32 | ![alt text](../../../docs/_static/no-button.png "Compatible") | | ESP32-S2-Kaluga-1 Kit | [![alt text](../../../docs/_static/esp32-s2-kaluga-1-kit-small.png "ESP32-S2-Kaluga-1 Kit")](https://docs.espressif.com/projects/esp-idf/en/latest/esp32s2/hw-reference/esp32s2/user-guide-esp32-s2-kaluga-1-kit.html) | ESP32-S2 | ![alt text](../../../docs/_static/no-button.png "Compatible") | ## Usage @@ -23,7 +23,7 @@ Prepare the audio board: Configure the example: - Select compatible audio board in `menuconfig` > `Audio HAL`. -- You may change between AMR-NB and AMR-WB encoder in `menuconfig` > `Example configuration` > `Audio encoder file type`. +- You may change between AMR-NB and AMR-WB encoder in `menuconfig` > `Example configuration` > `Audio encoder file type`. Load and run the example: diff --git a/examples/recorder/pipeline_amr_sdcard/main/pipeline_amr_sdcard.c b/examples/recorder/pipeline_amr_sdcard/main/pipeline_amr_sdcard.c index 45c35c9..0e07be7 100644 --- a/examples/recorder/pipeline_amr_sdcard/main/pipeline_amr_sdcard.c +++ b/examples/recorder/pipeline_amr_sdcard/main/pipeline_amr_sdcard.c @@ -41,7 +41,7 @@ void app_main(void) esp_periph_set_handle_t set = esp_periph_set_init(&periph_cfg); // Initialize SD Card peripheral - audio_board_sdcard_init(set); + audio_board_sdcard_init(set, SD_MODE_1_LINE); ESP_LOGI(TAG, "[2.0] Start codec chip"); audio_board_handle_t board_handle = audio_board_init(); diff --git a/examples/recorder/pipeline_amr_sdcard/sdkconfig.defaults b/examples/recorder/pipeline_amr_sdcard/sdkconfig.defaults index feaf721..93c3d7b 100644 --- a/examples/recorder/pipeline_amr_sdcard/sdkconfig.defaults +++ b/examples/recorder/pipeline_amr_sdcard/sdkconfig.defaults @@ -1,6 +1,35 @@ # Override some defaults + + +# +# Serial flasher config +# +CONFIG_ESPTOOLPY_FLASHMODE_QIO=y +CONFIG_ESPTOOLPY_FLASHMODE="qio" +CONFIG_ESPTOOLPY_FLASHFREQ_80M=y +CONFIG_ESPTOOLPY_FLASHSIZE_4MB=y + +# +# ESP32-specific +# CONFIG_ESP32_DEFAULT_CPU_FREQ_240=y +CONFIG_ESP32_DEFAULT_CPU_FREQ_MHZ=240 CONFIG_FREERTOS_HZ=1000 + +# +# SPI RAM config +# +CONFIG_SPIRAM=y +CONFIG_SPIRAM_SUPPORT=y +CONFIG_SPIRAM_BOOT_INIT=y +CONFIG_SPIRAM_USE_MALLOC=y +CONFIG_SPIRAM_SPEED_80M=y +CONFIG_SPIRAM_ALLOW_STACK_EXTERNAL_MEMORY=y +CONFIG_WIFI_LWIP_ALLOCATION_FROM_SPIRAM_FIRST=y + +# +# FAT Filesystem support +# CONFIG_FATFS_CODEPAGE_936=y CONFIG_FATFS_LFN_HEAP=y CONFIG_FATFS_MAX_LFN=255 diff --git a/examples/recorder/pipeline_opus_sdcard/README.md b/examples/recorder/pipeline_opus_sdcard/README.md index 679432e..de5cbaf 100644 --- a/examples/recorder/pipeline_opus_sdcard/README.md +++ b/examples/recorder/pipeline_opus_sdcard/README.md @@ -1,4 +1,4 @@ -# Recoding OPUS file to microSD +# Recoding OPUS file to microSD The example encodes 10 seconds of audio using OPUS encoder and saves it to SD Card. @@ -11,7 +11,7 @@ This example is will run on boards marked with green checkbox. Please remember t | ESP32-LyraT | [![alt text](../../../docs/_static/esp32-lyrat-v4.3-side-small.jpg "ESP32-LyraT")](https://docs.espressif.com/projects/esp-adf/en/latest/get-started/get-started-esp32-lyrat.html) | ESP32 | ![alt text](../../../docs/_static/yes-button.png "Compatible") | | ESP32-LyraTD-MSC | [![alt text](../../../docs/_static/esp32-lyratd-msc-v2.2-small.jpg "ESP32-LyraTD-MSC")](https://docs.espressif.com/projects/esp-adf/en/latest/get-started/get-started-esp32-lyratd-msc.html) | ESP32 | ![alt text](../../../docs/_static/yes-button.png "Compatible") | | ESP32-LyraT-Mini | [![alt text](../../../docs/_static/esp32-lyrat-mini-v1.2-small.jpg "ESP32-LyraT-Mini")](https://docs.espressif.com/projects/esp-adf/en/latest/get-started/get-started-esp32-lyrat-mini.html) | ESP32 | ![alt text](../../../docs/_static/yes-button.png "Compatible") | -| ESP32-Korvo-DU1906 | [![alt text](../../../docs/_static/esp32-korvo-du1906-v1.1-small.jpg "ESP32-Korvo-DU1906")](https://docs.espressif.com/projects/esp-adf/en/latest/get-started/get-started-esp32-korvo-du1906.html) | ESP32 | ![alt text](../../../docs/_static/yes-button.png "Compatible") | +| ESP32-Korvo-DU1906 | [![alt text](../../../docs/_static/esp32-korvo-du1906-v1.1-small.jpg "ESP32-Korvo-DU1906")](https://docs.espressif.com/projects/esp-adf/en/latest/get-started/get-started-esp32-korvo-du1906.html) | ESP32 | ![alt text](../../../docs/_static/no-button.png "Compatible") | | ESP32-S2-Kaluga-1 Kit | [![alt text](../../../docs/_static/esp32-s2-kaluga-1-kit-small.png "ESP32-S2-Kaluga-1 Kit")](https://docs.espressif.com/projects/esp-idf/en/latest/esp32s2/hw-reference/esp32s2/user-guide-esp32-s2-kaluga-1-kit.html) | ESP32-S2 | ![alt text](../../../docs/_static/no-button.png "Compatible") | ## Hardware Preparation diff --git a/examples/recorder/pipeline_opus_sdcard/main/record_opus_sdcard.c b/examples/recorder/pipeline_opus_sdcard/main/record_opus_sdcard.c index 2cd4e64..b5e243a 100644 --- a/examples/recorder/pipeline_opus_sdcard/main/record_opus_sdcard.c +++ b/examples/recorder/pipeline_opus_sdcard/main/record_opus_sdcard.c @@ -56,7 +56,7 @@ void app_main(void) esp_periph_set_handle_t set = esp_periph_set_init(&periph_cfg); // Initialize SD Card peripheral - audio_board_sdcard_init(set); + audio_board_sdcard_init(set, SD_MODE_1_LINE); ESP_LOGI(TAG, "[ 2 ] Start codec chip"); audio_board_handle_t board_handle = audio_board_init(); diff --git a/examples/recorder/pipeline_opus_sdcard/sdkconfig.defaults b/examples/recorder/pipeline_opus_sdcard/sdkconfig.defaults index e7213ad..8399739 100644 --- a/examples/recorder/pipeline_opus_sdcard/sdkconfig.defaults +++ b/examples/recorder/pipeline_opus_sdcard/sdkconfig.defaults @@ -3,6 +3,7 @@ # CONFIG_FLASHMODE_QIO=y CONFIG_ESPTOOLPY_FLASHFREQ_80M=y + # # ESP32-specific # diff --git a/examples/recorder/pipeline_raw_http/README.md b/examples/recorder/pipeline_raw_http/README.md index 5c171d0..71ffd8d 100644 --- a/examples/recorder/pipeline_raw_http/README.md +++ b/examples/recorder/pipeline_raw_http/README.md @@ -11,7 +11,7 @@ This example is will run on boards marked with green checkbox. Please remember t | ESP32-LyraT | [![alt text](../../../docs/_static/esp32-lyrat-v4.3-side-small.jpg "ESP32-LyraT")](https://docs.espressif.com/projects/esp-adf/en/latest/get-started/get-started-esp32-lyrat.html) | ESP32 | ![alt text](../../../docs/_static/yes-button.png "Compatible") | | ESP32-LyraTD-MSC | [![alt text](../../../docs/_static/esp32-lyratd-msc-v2.2-small.jpg "ESP32-LyraTD-MSC")](https://docs.espressif.com/projects/esp-adf/en/latest/get-started/get-started-esp32-lyratd-msc.html) | ESP32 | ![alt text](../../../docs/_static/yes-button.png "Compatible") | | ESP32-LyraT-Mini | [![alt text](../../../docs/_static/esp32-lyrat-mini-v1.2-small.jpg "ESP32-LyraT-Mini")](https://docs.espressif.com/projects/esp-adf/en/latest/get-started/get-started-esp32-lyrat-mini.html) | ESP32 | ![alt text](../../../docs/_static/yes-button.png "Compatible") | -| ESP32-Korvo-DU1906 | [![alt text](../../../docs/_static/esp32-korvo-du1906-v1.1-small.jpg "ESP32-Korvo-DU1906")](https://docs.espressif.com/projects/esp-adf/en/latest/get-started/get-started-esp32-korvo-du1906.html) | ESP32 | ![alt text](../../../docs/_static/yes-button.png "Compatible") | +| ESP32-Korvo-DU1906 | [![alt text](../../../docs/_static/esp32-korvo-du1906-v1.1-small.jpg "ESP32-Korvo-DU1906")](https://docs.espressif.com/projects/esp-adf/en/latest/get-started/get-started-esp32-korvo-du1906.html) | ESP32 | ![alt text](../../../docs/_static/no-button.png "Compatible") | | ESP32-S2-Kaluga-1 Kit | [![alt text](../../../docs/_static/esp32-s2-kaluga-1-kit-small.png "ESP32-S2-Kaluga-1 Kit")](https://docs.espressif.com/projects/esp-idf/en/latest/esp32s2/hw-reference/esp32s2/user-guide-esp32-s2-kaluga-1-kit.html) | ESP32-S2 | ![alt text](../../../docs/_static/yes-button.png "Compatible") | ## Usage diff --git a/examples/recorder/pipeline_raw_http/main/record_raw_http.c b/examples/recorder/pipeline_raw_http/main/record_raw_http.c index 25968f7..fe58590 100644 --- a/examples/recorder/pipeline_raw_http/main/record_raw_http.c +++ b/examples/recorder/pipeline_raw_http/main/record_raw_http.c @@ -30,6 +30,18 @@ #include "filter_resample.h" #include "input_key_service.h" +#if __has_include("esp_idf_version.h") +#include "esp_idf_version.h" +#else +#define ESP_IDF_VERSION_VAL(major, minor, patch) 1 +#endif + +#if (ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(4, 1, 0)) +#include "esp_netif.h" +#else +#include "tcpip_adapter.h" +#endif + static const char *TAG = "REC_RAW_HTTP"; #define DEMO_EXIT_BIT (BIT0) @@ -142,7 +154,11 @@ void app_main(void) ESP_ERROR_CHECK(nvs_flash_erase()); err = nvs_flash_init(); } +#if (ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(4, 1, 0)) + ESP_ERROR_CHECK(esp_netif_init()); +#else tcpip_adapter_init(); +#endif ESP_LOGI(TAG, "[ 1 ] Initialize Button Peripheral & Connect to wifi network"); // Initialize peripherals management diff --git a/examples/recorder/pipeline_wav_amr_sdcard/README.md b/examples/recorder/pipeline_wav_amr_sdcard/README.md index 71908e7..cd86ae4 100644 --- a/examples/recorder/pipeline_wav_amr_sdcard/README.md +++ b/examples/recorder/pipeline_wav_amr_sdcard/README.md @@ -1,6 +1,6 @@ -# Recoding WAV and AMR file to microSD +# Recoding WAV and AMR file to microSD -The example records 10 seconds WAV and AMR(AMR-NB or AMR-WB) audio file to microSD card via audio pipeline API. +The example records 10 seconds WAV and AMR(AMR-NB or AMR-WB) audio file to microSD card via audio pipeline API. ## Compatibility @@ -11,7 +11,7 @@ This example is will run on boards marked with green checkbox. Please remember t | ESP32-LyraT | [![alt text](../../../docs/_static/esp32-lyrat-v4.3-side-small.jpg "ESP32-LyraT")](https://docs.espressif.com/projects/esp-adf/en/latest/get-started/get-started-esp32-lyrat.html) | ESP32 | ![alt text](../../../docs/_static/yes-button.png "Compatible") | | ESP32-LyraTD-MSC | [![alt text](../../../docs/_static/esp32-lyratd-msc-v2.2-small.jpg "ESP32-LyraTD-MSC")](https://docs.espressif.com/projects/esp-adf/en/latest/get-started/get-started-esp32-lyratd-msc.html) | ESP32 | ![alt text](../../../docs/_static/yes-button.png "Compatible") | | ESP32-LyraT-Mini | [![alt text](../../../docs/_static/esp32-lyrat-mini-v1.2-small.jpg "ESP32-LyraT-Mini")](https://docs.espressif.com/projects/esp-adf/en/latest/get-started/get-started-esp32-lyrat-mini.html) | ESP32 | ![alt text](../../../docs/_static/yes-button.png "Compatible") | -| ESP32-Korvo-DU1906 | [![alt text](../../../docs/_static/esp32-korvo-du1906-v1.1-small.jpg "ESP32-Korvo-DU1906")](https://docs.espressif.com/projects/esp-adf/en/latest/get-started/get-started-esp32-korvo-du1906.html) | ESP32 | ![alt text](../../../docs/_static/yes-button.png "Compatible") | +| ESP32-Korvo-DU1906 | [![alt text](../../../docs/_static/esp32-korvo-du1906-v1.1-small.jpg "ESP32-Korvo-DU1906")](https://docs.espressif.com/projects/esp-adf/en/latest/get-started/get-started-esp32-korvo-du1906.html) | ESP32 | ![alt text](../../../docs/_static/no-button.png "Compatible") | | ESP32-S2-Kaluga-1 Kit | [![alt text](../../../docs/_static/esp32-s2-kaluga-1-kit-small.png "ESP32-S2-Kaluga-1 Kit")](https://docs.espressif.com/projects/esp-idf/en/latest/esp32s2/hw-reference/esp32s2/user-guide-esp32-s2-kaluga-1-kit.html) | ESP32-S2 | ![alt text](../../../docs/_static/no-button.png "Compatible") | ## Usage @@ -23,7 +23,7 @@ Prepare the audio board: Configure the example: - Select compatible audio board in `menuconfig` > `Audio HAL`. -- You may select encoders between AMR-NB and AMR-WB in `menuconfig` > `Example configuration` > `Audio encoder file type`. +- You may select encoders between AMR-NB and AMR-WB in `menuconfig` > `Example configuration` > `Audio encoder file type`. Load and run the example: diff --git a/examples/recorder/pipeline_wav_amr_sdcard/main/pipeline_wav_amr_sdcard.c b/examples/recorder/pipeline_wav_amr_sdcard/main/pipeline_wav_amr_sdcard.c index f452de3..faec389 100644 --- a/examples/recorder/pipeline_wav_amr_sdcard/main/pipeline_wav_amr_sdcard.c +++ b/examples/recorder/pipeline_wav_amr_sdcard/main/pipeline_wav_amr_sdcard.c @@ -33,7 +33,7 @@ void app_main() esp_periph_config_t periph_cfg = DEFAULT_ESP_PERIPH_SET_CONFIG(); esp_periph_set_handle_t set = esp_periph_set_init(&periph_cfg); // Initialize SD Card peripheral - audio_board_sdcard_init(set); + audio_board_sdcard_init(set, SD_MODE_1_LINE); ESP_LOGI(TAG, "[2.0] Start codec chip"); audio_board_handle_t board_handle = audio_board_init(); diff --git a/examples/recorder/pipeline_wav_sdcard/README.md b/examples/recorder/pipeline_wav_sdcard/README.md index 486fc9c..8ce0bd7 100644 --- a/examples/recorder/pipeline_wav_sdcard/README.md +++ b/examples/recorder/pipeline_wav_sdcard/README.md @@ -1,6 +1,6 @@ -# Recoding WAV file to microSD +# Recoding WAV file to microSD -The example records 20 seconds WAV file audio to microSD Card. +The example records 20 seconds WAV file audio to microSD Card. ## Compatibility @@ -11,7 +11,7 @@ This example is will run on boards marked with green checkbox. Please remember t | ESP32-LyraT | [![alt text](../../../docs/_static/esp32-lyrat-v4.3-side-small.jpg "ESP32-LyraT")](https://docs.espressif.com/projects/esp-adf/en/latest/get-started/get-started-esp32-lyrat.html) | ESP32 | ![alt text](../../../docs/_static/yes-button.png "Compatible") | | ESP32-LyraTD-MSC | [![alt text](../../../docs/_static/esp32-lyratd-msc-v2.2-small.jpg "ESP32-LyraTD-MSC")](https://docs.espressif.com/projects/esp-adf/en/latest/get-started/get-started-esp32-lyratd-msc.html) | ESP32 | ![alt text](../../../docs/_static/yes-button.png "Compatible") | | ESP32-LyraT-Mini | [![alt text](../../../docs/_static/esp32-lyrat-mini-v1.2-small.jpg "ESP32-LyraT-Mini")](https://docs.espressif.com/projects/esp-adf/en/latest/get-started/get-started-esp32-lyrat-mini.html) | ESP32 | ![alt text](../../../docs/_static/yes-button.png "Compatible") | -| ESP32-Korvo-DU1906 | [![alt text](../../../docs/_static/esp32-korvo-du1906-v1.1-small.jpg "ESP32-Korvo-DU1906")](https://docs.espressif.com/projects/esp-adf/en/latest/get-started/get-started-esp32-korvo-du1906.html) | ESP32 | ![alt text](../../../docs/_static/yes-button.png "Compatible") | +| ESP32-Korvo-DU1906 | [![alt text](../../../docs/_static/esp32-korvo-du1906-v1.1-small.jpg "ESP32-Korvo-DU1906")](https://docs.espressif.com/projects/esp-adf/en/latest/get-started/get-started-esp32-korvo-du1906.html) | ESP32 | ![alt text](../../../docs/_static/no-button.png "Compatible") | | ESP32-S2-Kaluga-1 Kit | [![alt text](../../../docs/_static/esp32-s2-kaluga-1-kit-small.png "ESP32-S2-Kaluga-1 Kit")](https://docs.espressif.com/projects/esp-idf/en/latest/esp32s2/hw-reference/esp32s2/user-guide-esp32-s2-kaluga-1-kit.html) | ESP32-S2 | ![alt text](../../../docs/_static/no-button.png "Compatible") | ## Usage diff --git a/examples/recorder/pipeline_wav_sdcard/main/record_wav_sdcard_example.c b/examples/recorder/pipeline_wav_sdcard/main/record_wav_sdcard_example.c index 893981c..4937043 100644 --- a/examples/recorder/pipeline_wav_sdcard/main/record_wav_sdcard_example.c +++ b/examples/recorder/pipeline_wav_sdcard/main/record_wav_sdcard_example.c @@ -41,7 +41,7 @@ void app_main(void) esp_periph_set_handle_t set = esp_periph_set_init(&periph_cfg); // Initialize SD Card peripheral - audio_board_sdcard_init(set); + audio_board_sdcard_init(set, SD_MODE_1_LINE); ESP_LOGI(TAG, "[ 2 ] Start codec chip"); audio_board_handle_t board_handle = audio_board_init(); diff --git a/examples/speech_recognition/asr/README.md b/examples/speech_recognition/asr/README.md index 00058fe..7f12828 100644 --- a/examples/speech_recognition/asr/README.md +++ b/examples/speech_recognition/asr/README.md @@ -1,6 +1,6 @@ # Speech recognition example -The example demonstrates the speech recognition function on ESP32-LyraT and ESP32-LyraTD-MSC board. It contains nine keywords. +The example demonstrates the speech recognition function on ESP32-LyraT and ESP32-LyraTD-MSC board. It contains nine keywords. ## WakeUp words @@ -46,7 +46,7 @@ This example is will run on boards marked with green checkbox. Please remember t | ESP32-LyraT | [![alt text](../../../docs/_static/esp32-lyrat-v4.3-side-small.jpg "ESP32-LyraT")](https://docs.espressif.com/projects/esp-adf/en/latest/get-started/get-started-esp32-lyrat.html) | ESP32 | ![alt text](../../../docs/_static/yes-button.png "Compatible") | | ESP32-LyraTD-MSC | [![alt text](../../../docs/_static/esp32-lyratd-msc-v2.2-small.jpg "ESP32-LyraTD-MSC")](https://docs.espressif.com/projects/esp-adf/en/latest/get-started/get-started-esp32-lyratd-msc.html) | ESP32 | ![alt text](../../../docs/_static/yes-button.png "Compatible") | | ESP32-LyraT-Mini | [![alt text](../../../docs/_static/esp32-lyrat-mini-v1.2-small.jpg "ESP32-LyraT-Mini")](https://docs.espressif.com/projects/esp-adf/en/latest/get-started/get-started-esp32-lyrat-mini.html) | ESP32 | ![alt text](../../../docs/_static/yes-button.png "Compatible") | -| ESP32-Korvo-DU1906 | [![alt text](../../../docs/_static/esp32-korvo-du1906-v1.1-small.jpg "ESP32-Korvo-DU1906")](https://docs.espressif.com/projects/esp-adf/en/latest/get-started/get-started-esp32-korvo-du1906.html) | ESP32 | ![alt text](../../../docs/_static/yes-button.png "Compatible") | +| ESP32-Korvo-DU1906 | [![alt text](../../../docs/_static/esp32-korvo-du1906-v1.1-small.jpg "ESP32-Korvo-DU1906")](https://docs.espressif.com/projects/esp-adf/en/latest/get-started/get-started-esp32-korvo-du1906.html) | ESP32 | ![alt text](../../../docs/_static/no-button.png "Compatible") | | ESP32-S2-Kaluga-1 Kit | [![alt text](../../../docs/_static/esp32-s2-kaluga-1-kit-small.png "ESP32-S2-Kaluga-1 Kit")](https://docs.espressif.com/projects/esp-idf/en/latest/esp32s2/hw-reference/esp32s2/user-guide-esp32-s2-kaluga-1-kit.html) | ESP32-S2 | ![alt text](../../../docs/_static/no-button.png "Compatible") | ## Usage @@ -62,7 +62,7 @@ Configure the example: - `Wake word engine` > `WakeNet 5 (quantized)` or > `WakeNet 6 (quantized)` - `Wake word name` > `nihaoxiaozhi` - If you want to use "nihaoxiaozhi" as a wakeup word, open menuconfig, go to `Speech Recognition Configuration` and select: - - `Wake word engine` > `WakeNet 5 (quantized)` + - `Wake word engine` > `WakeNet 5 (quantized)` - `Wake word name` > `hi jeson` Load and run the example: diff --git a/examples/speech_recognition/asr/main/example_asr_main.c b/examples/speech_recognition/asr/main/example_asr_main.c index a4ccf34..62cde05 100644 --- a/examples/speech_recognition/asr/main/example_asr_main.c +++ b/examples/speech_recognition/asr/main/example_asr_main.c @@ -151,7 +151,7 @@ void app_main() ESP_LOGI(TAG, "[ 1 ] Start codec chip"); esp_periph_config_t periph_cfg = DEFAULT_ESP_PERIPH_SET_CONFIG(); - audio_board_sdcard_init(esp_periph_set_init(&periph_cfg)); + audio_board_sdcard_init(esp_periph_set_init(&periph_cfg), SD_MODE_1_LINE); ESP_LOGI(TAG, "[ 2.0 ] Create audio pipeline for recording"); audio_pipeline_cfg_t pipeline_cfg = DEFAULT_AUDIO_PIPELINE_CONFIG(); diff --git a/examples/speech_recognition/asr/partitions.csv b/examples/speech_recognition/asr/partitions.csv index f4dcd1d..d39813a 100644 --- a/examples/speech_recognition/asr/partitions.csv +++ b/examples/speech_recognition/asr/partitions.csv @@ -1,4 +1,5 @@ -# Espressif ESP32 Partition Table -# Name, Type, SubType, Offset, Size -factory, app, factory, 0x010000, 3840k -nvs, data, nvs, 0x3D0000, 16K +# Name, Type, SubType, Offset, Size, Flags +# Note: if you change the phy_init or app partition offset, make sure to change the offset in Kconfig.projbuild +nvs, data, nvs, 0x9000, 0x6000, +phy_init, data, phy, 0xf000, 0x1000, +factory, app, factory, 0x10000, 0x300000, \ No newline at end of file diff --git a/examples/speech_recognition/asr/sdkconfig.defaults b/examples/speech_recognition/asr/sdkconfig.defaults index f1114ed..adf65d2 100644 --- a/examples/speech_recognition/asr/sdkconfig.defaults +++ b/examples/speech_recognition/asr/sdkconfig.defaults @@ -7,6 +7,21 @@ CONFIG_FLASHMODE_QIO=y CONFIG_ESPTOOLPY_FLASHMODE="qio" CONFIG_ESPTOOLPY_FLASHFREQ_80M=y CONFIG_ESPTOOLPY_FLASHFREQ="80m" +CONFIG_ESPTOOLPY_FLASHSIZE_4MB=y +CONFIG_ESPTOOLPY_FLASHSIZE="4MB" +CONFIG_ESPTOOLPY_FLASHSIZE_DETECT=y + +# +# Partition Table +# +# CONFIG_PARTITION_TABLE_SINGLE_APP is not set +# CONFIG_PARTITION_TABLE_TWO_OTA is not set +CONFIG_PARTITION_TABLE_CUSTOM=y +CONFIG_PARTITION_TABLE_CUSTOM_FILENAME="partitions.csv" +CONFIG_PARTITION_TABLE_FILENAME="partitions.csv" +CONFIG_PARTITION_TABLE_OFFSET=0x8000 +CONFIG_PARTITION_TABLE_MD5=y +# end of Partition Table # # FreeRTOS @@ -19,12 +34,7 @@ CONFIG_FREERTOS_HZ=1000 CONFIG_ESP32_DEFAULT_CPU_FREQ_240=y # -# Speech Recognition Configuration +# ESP Speech Recognition # -CONFIG_SR_MODEL_WN3_QUANT= -CONFIG_SR_MODEL_WN4_QUANT=y -CONFIG_WAKEUP_WORD_LIGHT_CONTROL_CH= -CONFIG_WAKEUP_WORD_SPEECH_CMD_CH=y - - - +CONFIG_SR_MODEL_WN5_QUANT=y +CONFIG_SR_WN5_HILEXIN=y diff --git a/examples/speech_recognition/vad/README.md b/examples/speech_recognition/vad/README.md index 91620d4..a043b3e 100644 --- a/examples/speech_recognition/vad/README.md +++ b/examples/speech_recognition/vad/README.md @@ -11,7 +11,7 @@ This example is will run on boards marked with green checkbox. Please remember t | ESP32-LyraT | [![alt text](../../../docs/_static/esp32-lyrat-v4.3-side-small.jpg "ESP32-LyraT")](https://docs.espressif.com/projects/esp-adf/en/latest/get-started/get-started-esp32-lyrat.html) | ESP32 | ![alt text](../../../docs/_static/yes-button.png "Compatible") | | ESP32-LyraTD-MSC | [![alt text](../../../docs/_static/esp32-lyratd-msc-v2.2-small.jpg "ESP32-LyraTD-MSC")](https://docs.espressif.com/projects/esp-adf/en/latest/get-started/get-started-esp32-lyratd-msc.html) | ESP32 | ![alt text](../../../docs/_static/yes-button.png "Compatible") | | ESP32-LyraT-Mini | [![alt text](../../../docs/_static/esp32-lyrat-mini-v1.2-small.jpg "ESP32-LyraT-Mini")](https://docs.espressif.com/projects/esp-adf/en/latest/get-started/get-started-esp32-lyrat-mini.html) | ESP32 | ![alt text](../../../docs/_static/yes-button.png "Compatible") | -| ESP32-Korvo-DU1906 | [![alt text](../../../docs/_static/esp32-korvo-du1906-v1.1-small.jpg "ESP32-Korvo-DU1906")](https://docs.espressif.com/projects/esp-adf/en/latest/get-started/get-started-esp32-korvo-du1906.html) | ESP32 | ![alt text](../../../docs/_static/yes-button.png "Compatible") | +| ESP32-Korvo-DU1906 | [![alt text](../../../docs/_static/esp32-korvo-du1906-v1.1-small.jpg "ESP32-Korvo-DU1906")](https://docs.espressif.com/projects/esp-adf/en/latest/get-started/get-started-esp32-korvo-du1906.html) | ESP32 | ![alt text](../../../docs/_static/no-button.png "Compatible") | | ESP32-S2-Kaluga-1 Kit | [![alt text](../../../docs/_static/esp32-s2-kaluga-1-kit-small.png "ESP32-S2-Kaluga-1 Kit")](https://docs.espressif.com/projects/esp-idf/en/latest/esp32s2/hw-reference/esp32s2/user-guide-esp32-s2-kaluga-1-kit.html) | ESP32-S2 | ![alt text](../../../docs/_static/no-button.png "Compatible") | ## Usage diff --git a/examples/system/coredump/main/coredump_example.c b/examples/system/coredump/main/coredump_example.c index f8d6efb..1511e62 100644 --- a/examples/system/coredump/main/coredump_example.c +++ b/examples/system/coredump/main/coredump_example.c @@ -31,13 +31,22 @@ #include "esp_peripherals.h" #include "nvs_flash.h" #include "periph_wifi.h" -#include "tcpip_adapter.h" - #include "audio_mem.h" #include "audio_url.h" - #include "coredump_upload_service.h" +#if __has_include("esp_idf_version.h") +#include "esp_idf_version.h" +#else +#define ESP_IDF_VERSION_VAL(major, minor, patch) 1 +#endif + +#if (ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(4, 1, 0)) +#include "esp_netif.h" +#else +#include "tcpip_adapter.h" +#endif + static const char *TAG = "coredump_example"; #define CUSTOMIZE_POST (1) @@ -82,7 +91,11 @@ void app_main() err = nvs_flash_init(); } ESP_ERROR_CHECK(err); +#if (ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(4, 1, 0)) + ESP_ERROR_CHECK(esp_netif_init()); +#else tcpip_adapter_init(); +#endif ESP_LOGI(TAG, "[1.0] Initialize peripherals management"); esp_periph_config_t periph_cfg = DEFAULT_ESP_PERIPH_SET_CONFIG(); diff --git a/examples/system/coredump/sdkconfig.defaults b/examples/system/coredump/sdkconfig.defaults index 9ec5e24..9dc9997 100644 --- a/examples/system/coredump/sdkconfig.defaults +++ b/examples/system/coredump/sdkconfig.defaults @@ -6,8 +6,6 @@ CONFIG_ESPTOOLPY_FLASHSIZE_4MB=y # # Partition Table # -CONFIG_PARTITION_TABLE_SINGLE_APP= -CONFIG_PARTITION_TABLE_TWO_OTA= CONFIG_PARTITION_TABLE_CUSTOM=y CONFIG_PARTITION_TABLE_CUSTOM_FILENAME="partitions.csv" CONFIG_PARTITION_TABLE_FILENAME="partitions.csv" @@ -18,7 +16,5 @@ CONFIG_PARTITION_TABLE_MD5=y # Core dump # CONFIG_ESP32_ENABLE_COREDUMP_TO_FLASH=y -CONFIG_ESP32_ENABLE_COREDUMP_TO_UART= -CONFIG_ESP32_ENABLE_COREDUMP_TO_NONE= CONFIG_ESP32_ENABLE_COREDUMP=y CONFIG_ESP32_CORE_DUMP_MAX_TASKS_NUM=64 \ No newline at end of file diff --git a/examples/system/wpa2_enterprise/main/wpa2_enterprise_example.c b/examples/system/wpa2_enterprise/main/wpa2_enterprise_example.c index b81d619..98b30ea 100644 --- a/examples/system/wpa2_enterprise/main/wpa2_enterprise_example.c +++ b/examples/system/wpa2_enterprise/main/wpa2_enterprise_example.c @@ -13,7 +13,18 @@ #include "periph_wifi.h" #include "esp_log.h" #include "nvs_flash.h" + +#if __has_include("esp_idf_version.h") +#include "esp_idf_version.h" +#else +#define ESP_IDF_VERSION_VAL(major, minor, patch) 1 +#endif + +#if (ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(4, 1, 0)) +#include "esp_netif.h" +#else #include "tcpip_adapter.h" +#endif static const char *TAG = "wpa2_enterprise"; @@ -33,15 +44,19 @@ void app_main() ESP_ERROR_CHECK(nvs_flash_erase()); err = nvs_flash_init(); } +#if (ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(4, 1, 0)) + ESP_ERROR_CHECK(esp_netif_init()); +#else tcpip_adapter_init(); - +#endif + esp_log_level_set("*", ESP_LOG_WARN); esp_log_level_set(TAG, ESP_LOG_DEBUG); - + ESP_LOGI(TAG, "[ 0 ] Initialize peripherals"); esp_periph_config_t periph_cfg = DEFAULT_ESP_PERIPH_SET_CONFIG(); esp_periph_set_handle_t set = esp_periph_set_init(&periph_cfg); - + ESP_LOGI(TAG, "[ 1 ] Set Wi-Fi config"); periph_wifi_cfg_t wifi_cfg = {0}; wifi_cfg.ssid = CONFIG_WIFI_SSID; @@ -53,14 +68,14 @@ void app_main() wifi_cfg.wpa2_e_cfg.wpa2_e_cert_end = (char *)client_crt_end; wifi_cfg.wpa2_e_cfg.wpa2_e_key_start = (char *)client_key_start; wifi_cfg.wpa2_e_cfg.wpa2_e_key_end = (char *)client_key_end; - wifi_cfg.wpa2_e_cfg.eap_id = CONFIG_EAP_ID; - wifi_cfg.wpa2_e_cfg.eap_username = CONFIG_EAP_USERNAME; + wifi_cfg.wpa2_e_cfg.eap_id = CONFIG_EAP_ID; + wifi_cfg.wpa2_e_cfg.eap_username = CONFIG_EAP_USERNAME; wifi_cfg.wpa2_e_cfg.eap_password = CONFIG_EAP_PASSWORD; - - ESP_LOGI(TAG, "[ 2 ] Start bt peripheral"); + + ESP_LOGI(TAG, "[ 2 ] Start bt peripheral"); esp_periph_handle_t wifi_handle = periph_wifi_init(&wifi_cfg); esp_periph_start(set, wifi_handle); - + ESP_LOGI(TAG, "[ 3 ] Get ip info"); tcpip_adapter_ip_info_t ip_info; memset(&ip_info, 0, sizeof(tcpip_adapter_ip_info_t)); diff --git a/idf_patches/adf_http_stream.patch b/idf_patches/adf_http_stream.patch index ce958a3..0ab390f 100644 --- a/idf_patches/adf_http_stream.patch +++ b/idf_patches/adf_http_stream.patch @@ -1,5 +1,14 @@ +From ee6fd0d1c4f49a44af1ee2d5eb069568265df730 Mon Sep 17 00:00:00 2001 +From: donglianghao +Date: Fri, 18 Sep 2020 15:26:04 +0800 +Subject: [PATCH] Modify http stream reconnect patch + +--- + components/audio_stream/http_stream.c | 59 +++++++++++++++++++-------- + 1 file changed, 41 insertions(+), 18 deletions(-) + diff --git a/components/audio_stream/http_stream.c b/components/audio_stream/http_stream.c -index 8265aaca..37b1c00f 100644 +index ea62c4cf..f43c4830 100644 --- a/components/audio_stream/http_stream.c +++ b/components/audio_stream/http_stream.c @@ -32,7 +32,6 @@ @@ -27,7 +36,7 @@ index 8265aaca..37b1c00f 100644 } http_stream_t; static esp_err_t http_stream_auto_connect_next_track(audio_element_handle_t el); -@@ -329,7 +331,7 @@ static esp_err_t _http_open(audio_element_handle_t self) +@@ -331,7 +333,7 @@ static esp_err_t _http_open(audio_element_handle_t self) ESP_LOGE(TAG, "already opened"); return ESP_FAIL; } @@ -36,16 +45,36 @@ index 8265aaca..37b1c00f 100644 _stream_open_begin: uri = _playlist_get_next_track(self); -@@ -493,7 +495,7 @@ static esp_err_t _http_close(audio_element_handle_t self) - esp_http_client_cleanup(http->client); - http->client = NULL; +@@ -490,7 +492,7 @@ static esp_err_t _http_close(audio_element_handle_t self) + http->is_variant_playlist = false; + http->is_playlist_resolved = false; } - if (AEL_STATE_PAUSED != audio_element_get_state(self) && (errno == 0)) { -+ if (AEL_STATE_PAUSED != audio_element_get_state(self) && http->_errno == 0) { ++ if (AEL_STATE_PAUSED != audio_element_get_state(self)) { audio_element_report_pos(self); audio_element_set_byte_pos(self, 0); } -@@ -516,17 +518,11 @@ static int _http_read(audio_element_handle_t self, char *buffer, int len, TickTy +@@ -502,6 +504,19 @@ static esp_err_t _http_close(audio_element_handle_t self) + return ESP_OK; + } + ++static esp_err_t _http_reconnect(audio_element_handle_t self) ++{ ++ esp_err_t err = ESP_OK; ++ audio_element_info_t info = {0}; ++ AUDIO_NULL_CHECK(TAG, self, return ESP_FAIL); ++ err |= audio_element_getinfo(self, &info); ++ err |= _http_close(self); ++ err |= audio_element_set_byte_pos(self, info.byte_pos); ++ err |= _http_open(self); ++ return err; ++} ++ ++ + static int _http_read(audio_element_handle_t self, char *buffer, int len, TickType_t ticks_to_wait, void *context) + { + http_stream_t *http = (http_stream_t *)audio_element_getdata(self); +@@ -518,17 +533,11 @@ static int _http_read(audio_element_handle_t self, char *buffer, int len, TickTy } } if (rlen <= 0) { @@ -68,7 +97,7 @@ index 8265aaca..37b1c00f 100644 } if (http->auto_connect_next_track) { if (dispatch_hook(self, HTTP_STREAM_FINISH_PLAYLIST, NULL, 0) != ESP_OK) { -@@ -560,7 +556,8 @@ static int _http_write(audio_element_handle_t self, char *buffer, int len, TickT +@@ -562,7 +571,8 @@ static int _http_write(audio_element_handle_t self, char *buffer, int len, TickT } if ((wrlen = esp_http_client_write(http->client, buffer, len)) <= 0) { @@ -78,8 +107,8 @@ index 8265aaca..37b1c00f 100644 } return wrlen; } -@@ -570,10 +567,23 @@ static int _http_process(audio_element_handle_t self, char *in_buffer, int in_le - int r_size = audio_element_input(self, in_buffer, in_len); +@@ -576,10 +586,23 @@ static int _http_process(audio_element_handle_t self, char *in_buffer, int in_le + } int w_size = 0; if (r_size > 0) { - if (errno != 0) { @@ -93,23 +122,18 @@ index 8265aaca..37b1c00f 100644 + return ESP_FAIL; + }; + http->connect_times++; -+ ret |= _http_close(self); -+ ret |= _http_open(self); ++ ret = _http_reconnect(self); + if (ret != ESP_OK) { + ESP_LOGE(TAG, "Failed to reset connection"); + return ret; + } + ESP_LOGW(TAG, "reconnect to peer successful"); ++ return ESP_ERR_INVALID_STATE; } else { + http->connect_times = 0; w_size = audio_element_output(self, in_buffer, r_size); audio_element_multi_output(self, in_buffer, r_size, 0); } -@@ -685,6 +695,7 @@ esp_err_t http_stream_next_track(audio_element_handle_t el) - return ESP_OK; - } - audio_element_reset_state(el); -+ - audio_element_set_byte_pos(el, 0); - audio_element_set_total_bytes(el, 0); - http->is_open = false; +-- +2.17.1 + diff --git a/micropython_adf/mod/audio_recorder.c b/micropython_adf/mod/audio_recorder.c index d0bd26c..3c54f8f 100644 --- a/micropython_adf/mod/audio_recorder.c +++ b/micropython_adf/mod/audio_recorder.c @@ -255,6 +255,8 @@ STATIC mp_obj_t audio_recorder_stop(mp_obj_t self_in) self->timer = NULL; } if (self->pipeline != NULL) { + audio_pipeline_stop(self->pipeline); + audio_pipeline_wait_for_stop(self->pipeline); audio_pipeline_deinit(self->pipeline); } else { return mp_obj_new_bool(false); diff --git a/tools/audio_tone/mk_audio_tone.py b/tools/audio_tone/mk_audio_tone.py old mode 100644 new mode 100755 diff --git a/tools/ci/build_examples.sh b/tools/ci/build_examples.sh index a233a6f..fae7f1c 100755 --- a/tools/ci/build_examples.sh +++ b/tools/ci/build_examples.sh @@ -1,4 +1,4 @@ -#!/bin/bash +#!/usr/bin/env bash # # Build all examples from the examples directory, out of tree to # ensure they can run when copied to a new directory. @@ -23,7 +23,7 @@ # ----------------------------------------------------------------------------- # Safety settings (see https://gist.github.com/ilg-ul/383869cbb01f61a51c4d). -if [[ ! -z ${DEBUG} ]] +if [[ ! -z ${DEBUG_SHELL} ]] then set -x # Activate the expand mode if DEBUG is anything but empty. fi @@ -49,9 +49,6 @@ die() { echo "build_examples running in ${PWD}" -# only 0 or 1 arguments -[ $# -le 1 ] || die "Have to run as $(basename $0) []" - export BATCH_BUILD=1 export V=0 # only build verbose if there's an error @@ -62,41 +59,37 @@ FAILED_EXAMPLES="" RESULT_ISSUES=22 # magic number result code for issues found LOG_SUSPECTED=${LOG_PATH}/common_log.txt touch ${LOG_SUSPECTED} +SDKCONFIG_DEFAULTS_CI=sdkconfig.ci + +EXAMPLE_PATHS=$( find ${ADF_PATH}/examples/ -type f -name Makefile | grep -v "/build_system/cmake/" | sort ) -if [ $# -eq 0 ] +if [ -z "${CI_NODE_TOTAL:-}" ] then START_NUM=0 + if [ "${1:-}" ]; then + START_NUM=$1 + fi END_NUM=999 else - JOB_NAME=$1 - - # parse text prefix at the beginning of string 'some_your_text_NUM' - # (will be 'some_your_text' without last '_') - JOB_PATTERN=$( echo ${JOB_NAME} | sed -n -r 's/^(.*)_[0-9]+$/\1/p' ) - [ -z ${JOB_PATTERN} ] && die "JOB_PATTERN is bad" - - # parse number 'NUM' at the end of string 'some_your_text_NUM' - JOB_NUM=$( echo ${JOB_NAME} | sed -n -r 's/^.*_([0-9]+)$/\1/p' ) - [ -z ${JOB_NUM} ] && die "JOB_NUM is bad" - + JOB_NUM=${CI_NODE_INDEX} # count number of the jobs - NUM_OF_JOBS=$( grep -c -E "^${JOB_PATTERN}_[0-9]+:$" "${ADF_PATH}/.gitlab-ci.yml" ) - [ -z ${NUM_OF_JOBS} ] && die "NUM_OF_JOBS is bad" + NUM_OF_JOBS=${CI_NODE_TOTAL} # count number of examples - NUM_OF_EXAMPLES=$( find ${ADF_PATH}/examples/ -type f -name Makefile | wc -l ) + NUM_OF_EXAMPLES=$( echo "${EXAMPLE_PATHS}" | wc -l ) [ -z ${NUM_OF_EXAMPLES} ] && die "NUM_OF_EXAMPLES is bad" + # separate intervals #57 / 5 == 12 NUM_OF_EX_PER_JOB=$(( (${NUM_OF_EXAMPLES} + ${NUM_OF_JOBS} - 1) / ${NUM_OF_JOBS} )) [ -z ${NUM_OF_EX_PER_JOB} ] && die "NUM_OF_EX_PER_JOB is bad" # ex.: [0; 12); [12; 24); [24; 36); [36; 48); [48; 60) - START_NUM=$(( ${JOB_NUM} * ${NUM_OF_EX_PER_JOB} )) + START_NUM=$(( (${JOB_NUM} - 1) * ${NUM_OF_EX_PER_JOB} )) [ -z ${START_NUM} ] && die "START_NUM is bad" - END_NUM=$(( (${JOB_NUM} + 1) * ${NUM_OF_EX_PER_JOB} )) + END_NUM=$(( ${JOB_NUM} * ${NUM_OF_EX_PER_JOB} )) [ -z ${END_NUM} ] && die "END_NUM is bad" fi @@ -109,45 +102,75 @@ build_example () { local EXAMPLE_DIR=$(dirname "${MAKE_FILE}") local EXAMPLE_NAME=$(basename "${EXAMPLE_DIR}") + # Check if the example needs a different base directory. + # Path of the Makefile relative to $IDF_PATH + local MAKE_FILE_REL=${MAKE_FILE#"${IDF_PATH}/"} + # Look for it in build_example_dirs.txt: + local COPY_ROOT_REL=$(sed -n -E "s|${MAKE_FILE_REL}[[:space:]]+(.*)|\1|p" < ${IDF_PATH}/tools/ci/build_example_dirs.txt) + if [[ -n "${COPY_ROOT_REL}" && -d "${IDF_PATH}/${COPY_ROOT_REL}/" ]]; then + local COPY_ROOT=${IDF_PATH}/${COPY_ROOT_REL} + else + local COPY_ROOT=${EXAMPLE_DIR} + fi + echo "Building ${EXAMPLE_NAME} as ${ID}..." mkdir -p "example_builds/${ID}" - cp -r "${EXAMPLE_DIR}" "example_builds/${ID}" - pushd "example_builds/${ID}/${EXAMPLE_NAME}" + cp -r "${COPY_ROOT}" "example_builds/${ID}" + local COPY_ROOT_PARENT=$(dirname ${COPY_ROOT}) + local EXAMPLE_DIR_REL=${EXAMPLE_DIR#"${COPY_ROOT_PARENT}"} + pushd "example_builds/${ID}/${EXAMPLE_DIR_REL}" # be stricter in the CI build than the default IDF settings - export EXTRA_CFLAGS="-Werror -Werror=deprecated-declarations" - export EXTRA_CXXFLAGS=${EXTRA_CFLAGS} + # export in CI script + # export EXTRA_CFLAGS=${PEDANTIC_CFLAGS} + # export EXTRA_CXXFLAGS=${PEDANTIC_CXXFLAGS} + + # sdkconfig files are normally not checked into git, but may be present when + # a developer runs this script locally + rm -f sdkconfig + + # If sdkconfig.ci file is present, append it to sdkconfig.defaults, + # replacing environment variables + if [[ -f "$SDKCONFIG_DEFAULTS_CI" ]]; then + cat $SDKCONFIG_DEFAULTS_CI | $IDF_PATH/tools/ci/envsubst.py >> sdkconfig.defaults + fi # build non-verbose first local BUILDLOG=${LOG_PATH}/ex_${ID}_log.txt touch ${BUILDLOG} + local FLASH_ARGS=build/download.config + make clean >>${BUILDLOG} 2>&1 && make defconfig >>${BUILDLOG} 2>&1 && make all >>${BUILDLOG} 2>&1 && - ( make print_flash_cmd | tail -n 1 >build/download.config ) >>${BUILDLOG} 2>&1 || + make print_flash_cmd >${FLASH_ARGS}.full 2>>${BUILDLOG} || { RESULT=$?; FAILED_EXAMPLES+=" ${EXAMPLE_NAME}" ; } + tail -n 1 ${FLASH_ARGS}.full > ${FLASH_ARGS} || : + test -s ${FLASH_ARGS} || die "Error: ${FLASH_ARGS} file is empty" + cat ${BUILDLOG} popd - grep -i "error\|warning" "${BUILDLOG}" 2>&1 >> "${LOG_SUSPECTED}" || : + grep -i "error\|warning\|command not found" "${BUILDLOG}" 2>&1 >> "${LOG_SUSPECTED}" || : } EXAMPLE_NUM=0 -find ${ADF_PATH}/examples/ -type f -name Makefile | sort | \ -while read FN +echo "Current job will build example ${START_NUM} - ${END_NUM}" +echo "Current job will build example ${EXAMPLE_PATHS}" + +for EXAMPLE_PATH in ${EXAMPLE_PATHS} do if [[ $EXAMPLE_NUM -lt $START_NUM || $EXAMPLE_NUM -ge $END_NUM ]] then EXAMPLE_NUM=$(( $EXAMPLE_NUM + 1 )) continue fi - echo ">>> example [ ${EXAMPLE_NUM} ] - $FN" - build_example "${EXAMPLE_NUM}" "${FN}" + build_example "${EXAMPLE_NUM}" "${EXAMPLE_PATH}" EXAMPLE_NUM=$(( $EXAMPLE_NUM + 1 )) done @@ -156,11 +179,21 @@ done echo -e "\nFound issues:" # Ignore the next messages: -# files end with error: "error.o" or "error.c" or "error.h" or "error.d" -# "-Werror" in compiler's command line +# "error.o" or "-Werror" in compiler's command line # "reassigning to symbol" or "changes choice state" in sdkconfig -sort -u "${LOG_SUSPECTED}" | \ -grep -v "error.[ochd]\|\ -Werror\|reassigning to symbol\|changes choice state" \ +# 'Compiler and toochain versions is not supported' from make/project.mk +IGNORE_WARNS="\ +library/error\.o\ +\|\ -Werror\ +\|.*error.*\.o\ +\|.*error.*\.d\ +\|reassigning to symbol\ +\|changes choice state\ +\|Compiler version is not supported\ +\|Toolchain version is not supported\ +" + +sort -u "${LOG_SUSPECTED}" | grep -v "${IGNORE_WARNS}" \ && RESULT=$RESULT_ISSUES \ || echo -e "\tNone" @@ -169,4 +202,4 @@ grep -v "error.[ochd]\|\ -Werror\|reassigning to symbol\|changes choice state" \ echo -e "\nReturn code = $RESULT" -exit $RESULT +exit $RESULT \ No newline at end of file diff --git a/tools/ci/build_examples_cmake.sh b/tools/ci/build_examples_cmake.sh new file mode 100755 index 0000000..8b76423 --- /dev/null +++ b/tools/ci/build_examples_cmake.sh @@ -0,0 +1,106 @@ +#!/usr/bin/env bash +# +# Build all examples from the examples directory, in BUILD_PATH to +# ensure they can run when copied to a new directory. +# +# Runs as part of CI process. +# + +# ----------------------------------------------------------------------------- +# Safety settings (see https://gist.github.com/ilg-ul/383869cbb01f61a51c4d). + +if [[ ! -z ${DEBUG_SHELL} ]] +then + set -x # Activate the expand mode if DEBUG is anything but empty. +fi + +set -o errexit # Exit if command failed. +set -o pipefail # Exit if pipe failed. + +export PATH="$IDF_PATH/tools/ci:$IDF_PATH/tools:$PATH" + +# ----------------------------------------------------------------------------- + +die() { + echo "${1:-"Unknown Error"}" 1>&2 + exit 1 +} + +[ -z ${IDF_PATH} ] && die "IDF_PATH is not set" +[ -z ${LOG_PATH} ] && die "LOG_PATH is not set" +[ -z ${BUILD_PATH} ] && die "BUILD_PATH is not set" +[ -z ${IDF_TARGET} ] && die "IDF_TARGET is not set" +[ -d ${LOG_PATH} ] || mkdir -p ${LOG_PATH} +[ -d ${BUILD_PATH} ] || mkdir -p ${BUILD_PATH} + +if [ -z ${CI_NODE_TOTAL} ]; then + CI_NODE_TOTAL=1 + echo "Assuming CI_NODE_TOTAL=${CI_NODE_TOTAL}" +fi +if [ -z ${CI_NODE_INDEX} ]; then + # Gitlab uses a 1-based index + CI_NODE_INDEX=1 + echo "Assuming CI_NODE_INDEX=${CI_NODE_INDEX}" +fi + + +export EXTRA_CFLAGS="${PEDANTIC_CFLAGS:-}" +export EXTRA_CXXFLAGS="${PEDANTIC_CXXFLAGS:-}" + +set -o nounset # Exit if variable not set. + +export REALPATH=realpath +if [ "$(uname -s)" = "Darwin" ]; then + export REALPATH=grealpath +fi + +# Convert LOG_PATH and BUILD_PATH to relative, to make the json file less verbose. +LOG_PATH=$(${REALPATH} --relative-to ${IDF_PATH} ${LOG_PATH}) +BUILD_PATH=$(${REALPATH} --relative-to ${IDF_PATH} ${BUILD_PATH}) + +ALL_BUILD_LIST_JSON="${BUILD_PATH}/list.json" +JOB_BUILD_LIST_JSON="${BUILD_PATH}/list_job_${CI_NODE_INDEX}.json" + +echo "build_examples running for target $IDF_TARGET" + +cd ${IDF_PATH} + +# This part of the script produces the same result for all the example build jobs. It may be moved to a separate stage +# (pre-build) later, then the build jobs will receive ${BUILD_LIST_JSON} file as an artifact. + +# If changing the work-dir or build-dir format, remember to update the "artifacts" in gitlab-ci configs, and IDFApp.py. + +${IDF_PATH}/tools/find_apps.py ${ADF_PATH}/examples \ + -vv \ + --format json \ + --build-system cmake \ + --target ${IDF_TARGET} \ + --recursive \ + --exclude examples/build_system/idf_as_lib \ + --work-dir "${BUILD_PATH}/@f/@w/@t" \ + --build-dir build \ + --build-log "${LOG_PATH}/@f_@w.txt" \ + --output ${ALL_BUILD_LIST_JSON} \ + --config 'sdkconfig.ci=default' \ + --config 'sdkconfig.ci.*=' \ + --config '=default' \ + +# --config rules above explained: +# 1. If sdkconfig.ci exists, use it build the example with configuration name "default" +# 2. If sdkconfig.ci.* exists, use it to build the "*" configuration +# 3. If none of the above exist, build the default configuration under the name "default" + +# The part below is where the actual builds happen + +${IDF_PATH}/tools/build_apps.py \ + -vv \ + --format json \ + --keep-going \ + --parallel-count ${CI_NODE_TOTAL} \ + --parallel-index ${CI_NODE_INDEX} \ + --output-build-list ${JOB_BUILD_LIST_JSON} \ + ${ALL_BUILD_LIST_JSON}\ + + +# Check for build warnings +${IDF_PATH}/tools/ci/check_build_warnings.py -vv ${JOB_BUILD_LIST_JSON} diff --git a/tools/ci/set_idf.sh b/tools/ci/set_idf.sh new file mode 100755 index 0000000..93fc25e --- /dev/null +++ b/tools/ci/set_idf.sh @@ -0,0 +1,19 @@ +#!/usr/bin/env bash + +# sets up the IDF repo incl submodules with specified version as $1 +set -o errexit # Exit if command failed. + +if [ -z $IDF_PATH ] || [ -z $1 ] ; then + echo "Mandatory variables undefined" + exit 1; +fi; + +echo "Checking out IDF version $1" +cd $IDF_PATH +# Cleans out the untracked files in the repo, so the next "git checkout" doesn't fail +git clean -f +git checkout $1 +# Removes the mqtt submodule, so the next submodule update doesn't fail +rm -rf $IDF_PATH/components/mqtt/esp-mqtt +git submodule update --init --recursive +