From 667d6433b0d546d454623497281308651815d65d Mon Sep 17 00:00:00 2001 From: Qiang Zhang Date: Fri, 11 Feb 2022 23:05:47 -0800 Subject: [PATCH 1/8] modify for esp32-a1s 2297 --- components/audio_board/lyrat_v4_3/board_pins_config.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/components/audio_board/lyrat_v4_3/board_pins_config.c b/components/audio_board/lyrat_v4_3/board_pins_config.c index 6c0735fbb..930129cfb 100644 --- a/components/audio_board/lyrat_v4_3/board_pins_config.c +++ b/components/audio_board/lyrat_v4_3/board_pins_config.c @@ -35,8 +35,8 @@ 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 || port == I2C_NUM_1) { - i2c_config->sda_io_num = GPIO_NUM_18; - i2c_config->scl_io_num = GPIO_NUM_23; + i2c_config->sda_io_num = GPIO_NUM_33; + i2c_config->scl_io_num = GPIO_NUM_32; } else { i2c_config->sda_io_num = -1; i2c_config->scl_io_num = -1; @@ -50,7 +50,7 @@ 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 || port == I2S_NUM_1) { - i2s_config->bck_io_num = GPIO_NUM_5; + i2s_config->bck_io_num = GPIO_NUM_27; i2s_config->ws_io_num = GPIO_NUM_25; i2s_config->data_out_num = GPIO_NUM_26; i2s_config->data_in_num = GPIO_NUM_35; From 1017b7fd0c0a70ff699389c403bf955cfe72a440 Mon Sep 17 00:00:00 2001 From: Qiang Zhang Date: Sat, 12 Feb 2022 00:18:52 -0800 Subject: [PATCH 2/8] block list build folder for git. --- .gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitignore b/.gitignore index 310068049..aa77f1bc2 100644 --- a/.gitignore +++ b/.gitignore @@ -46,3 +46,4 @@ coverage.info coverage_report/ .vscode +**/build \ No newline at end of file From bb27694934e282c63e7ba3eeebd76131759391e9 Mon Sep 17 00:00:00 2001 From: Qiang Zhang Date: Sun, 13 Feb 2022 21:30:51 -0800 Subject: [PATCH 3/8] Add ESP32-A1S board support. --- components/audio_board/CMakeLists.txt | 9 + components/audio_board/Kconfig.projbuild | 3 +- .../ai_thinker_audio_kit_v2_2/board.c | 122 +++++ .../ai_thinker_audio_kit_v2_2/board.h | 121 +++++ .../ai_thinker_audio_kit_v2_2/board_def.h | 75 +++ .../board_pins_config.c | 191 +++++++ components/audio_board/component.mk | 4 + components/audio_hal/CMakeLists.txt | 2 + components/audio_hal/component.mk | 3 + components/audio_hal/driver/ac101/ac101.c | 484 ++++++++++++++++++ components/audio_hal/driver/ac101/ac101.h | 170 ++++++ 11 files changed, 1183 insertions(+), 1 deletion(-) create mode 100644 components/audio_board/ai_thinker_audio_kit_v2_2/board.c create mode 100644 components/audio_board/ai_thinker_audio_kit_v2_2/board.h create mode 100644 components/audio_board/ai_thinker_audio_kit_v2_2/board_def.h create mode 100644 components/audio_board/ai_thinker_audio_kit_v2_2/board_pins_config.c create mode 100644 components/audio_hal/driver/ac101/ac101.c create mode 100644 components/audio_hal/driver/ac101/ac101.h diff --git a/components/audio_board/CMakeLists.txt b/components/audio_board/CMakeLists.txt index 1a6d0452d..011249469 100644 --- a/components/audio_board/CMakeLists.txt +++ b/components/audio_board/CMakeLists.txt @@ -79,4 +79,13 @@ set(COMPONENT_SRCS ) endif() +if (CONFIG_ESP_AI_THINKER_V2_2_BOARD) +message(STATUS "Current board name is " CONFIG_ESP_AI_THINKER_V2_2_BOARD) +list(APPEND COMPONENT_ADD_INCLUDEDIRS ./ai_thinker_audio_kit_v2_2) +set(COMPONENT_SRCS +./ai_thinker_audio_kit_v2_2/board.c +./ai_thinker_audio_kit_v2_2/board_pins_config.c +) +endif() + register_component() diff --git a/components/audio_board/Kconfig.projbuild b/components/audio_board/Kconfig.projbuild index dc7acbc02..f7edc2e12 100644 --- a/components/audio_board/Kconfig.projbuild +++ b/components/audio_board/Kconfig.projbuild @@ -23,7 +23,8 @@ config ESP32_S2_KALUGA_1_V1_2_BOARD bool "ESP32-S2-Kaluga-1 v1.2" config ESP32_S3_KORVO2_V3_BOARD bool "ESP32-S3-Korvo-2 v3.0" - +config ESP_AI_THINKER_V2_2_BOARD + bool "ESP32-AiThinker-audio V2.2" endchoice choice ESP32_KORVO_DU1906_DAC 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 new file mode 100644 index 000000000..07b758795 --- /dev/null +++ b/components/audio_board/ai_thinker_audio_kit_v2_2/board.c @@ -0,0 +1,122 @@ +/* + * 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; +} + +display_service_handle_t audio_board_led_init(void) +{ + led_indicator_handle_t led = led_indicator_init((gpio_num_t)get_green_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 + }; + 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) +{ + periph_sdcard_cfg_t sdcard_cfg = { + .root = "/sdcard", + .card_detect_pin = get_sdcard_intr_gpio(), // GPIO_NUM_34 + }; + 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); + } + return ret; +} + +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/ai_thinker_audio_kit_v2_2/board.h b/components/audio_board/ai_thinker_audio_kit_v2_2/board.h new file mode 100644 index 000000000..e7fe565ed --- /dev/null +++ b/components/audio_board/ai_thinker_audio_kit_v2_2/board.h @@ -0,0 +1,121 @@ +/* + * 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" + +#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 Initialize led peripheral and display service + * + * @return The audio display service handle + */ +display_service_handle_t audio_board_led_init(void); + +/** + * @brief Initialize key peripheral + * + * @param set The handle of esp_periph_set_handle_t + * + * @return + * - ESP_OK, success + * - Others, fail + */ +esp_err_t audio_board_key_init(esp_periph_set_handle_t set); + + +/** + * @brief Initialize sdcard peripheral + * + * @param set The handle of esp_periph_set_handle_t + * + * @return + * - ESP_OK, success + * - Others, fail + */ +esp_err_t audio_board_sdcard_init(esp_periph_set_handle_t set); + + +/** + * @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/ai_thinker_audio_kit_v2_2/board_def.h b/components/audio_board/ai_thinker_audio_kit_v2_2/board_def.h new file mode 100644 index 000000000..fe30ecac9 --- /dev/null +++ b/components/audio_board/ai_thinker_audio_kit_v2_2/board_def.h @@ -0,0 +1,75 @@ +/* + * @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_ + +/* SD card related */ +#define SD_CARD_INTR_GPIO GPIO_NUM_34 +#define SD_CARD_INTR_SEL GPIO_SEL_34 +#define SD_CARD_OPEN_FILE_NUM_MAX 5 + +#define HEADPHONE_DETECT GPIO_NUM_5 +#define PA_ENABLE_GPIO GPIO_NUM_21 + +#define GREEN_LED_GPIO GPIO_NUM_22 +#define BLUE_LED_GPIO GPIO_NUM_19 + +#define BUTTON_REC_ID GPIO_NUM_36 +#define BUTTON_MODE_ID GPIO_NUM_13 + +/* Touch pad related */ +#define TOUCH_SEL_SET GPIO_SEL_19 +#define TOUCH_SEL_PLAY GPIO_SEL_23 +#define TOUCH_SEL_VOLUP GPIO_SEL_18 +#define TOUCH_SEL_VOLDWN GPIO_SEL_5 + +#define TOUCH_SET GPIO_NUM_19 +#define TOUCH_PLAY GPIO_NUM_23 +#define TOUCH_VOLUP GPIO_NUM_18 +#define TOUCH_VOLDWN GPIO_NUM_5 + +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/ai_thinker_audio_kit_v2_2/board_pins_config.c b/components/audio_board/ai_thinker_audio_kit_v2_2/board_pins_config.c new file mode 100644 index 000000000..a5669ee5b --- /dev/null +++ b/components/audio_board/ai_thinker_audio_kit_v2_2/board_pins_config.c @@ -0,0 +1,191 @@ +/* + * 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; +} + +// led pins + +int8_t get_green_led_gpio(void) +{ + return GREEN_LED_GPIO; +} + +int8_t get_blue_led_gpio(void) +{ + return BLUE_LED_GPIO; +} + +// button pins + +int8_t get_input_rec_id(void) +{ + return BUTTON_REC_ID; +} + +int8_t get_input_mode_id(void) +{ + return BUTTON_MODE_ID; +} + +// touch pins + +int8_t get_input_set_id(void) +{ + return TOUCH_SET; +} + +int8_t get_input_play_id(void) +{ + return TOUCH_PLAY; +} + +int8_t get_input_volup_id(void) +{ + return TOUCH_VOLUP; +} + +int8_t get_input_voldown_id(void) +{ + return TOUCH_VOLDWN; +} + +// sdcard +int8_t get_sdcard_intr_gpio(void){ + return SD_CARD_INTR_GPIO; +} + +int8_t get_sdcard_open_file_num_max(void) +{ + return SD_CARD_OPEN_FILE_NUM_MAX; +} + diff --git a/components/audio_board/component.mk b/components/audio_board/component.mk index 0d8c945fa..56372362c 100644 --- a/components/audio_board/component.mk +++ b/components/audio_board/component.mk @@ -47,3 +47,7 @@ COMPONENT_ADD_INCLUDEDIRS += ./esp32_s3_korvo2_v3 COMPONENT_SRCDIRS += ./esp32_s3_korvo2_v3 endif +ifdef CONFIG_ESP_AI_THINKER_V2_2_BOARD +COMPONENT_ADD_INCLUDEDIRS += ./ai_thinker_audio_kit_v2_2 +COMPONENT_SRCDIRS += ./ai_thinker_audio_kit_v2_2 +endif \ No newline at end of file diff --git a/components/audio_hal/CMakeLists.txt b/components/audio_hal/CMakeLists.txt index b35cbbd0d..f97b23872 100644 --- a/components/audio_hal/CMakeLists.txt +++ b/components/audio_hal/CMakeLists.txt @@ -9,6 +9,7 @@ set(COMPONENT_ADD_INCLUDEDIRS ./include ./driver/es7243e ./driver/tas5805m ./driver/zl38063 + ./driver/es8388 ./driver/zl38063/api_lib ./driver/zl38063/example_apps ./driver/zl38063/firmware @@ -19,6 +20,7 @@ set(COMPONENT_REQUIRES ) set(COMPONENT_PRIV_REQUIRES audio_sal audio_board mbedtls esp_peripherals display_service esp_dispatcher) set(COMPONENT_SRCS ./audio_hal.c + ./driver/es8388/es8388.c ./driver/es8388/es8388.c ./driver/es8388/headphone_detect.c ./driver/es8374/es8374.c diff --git a/components/audio_hal/component.mk b/components/audio_hal/component.mk index d794d0e7f..93b232df6 100644 --- a/components/audio_hal/component.mk +++ b/components/audio_hal/component.mk @@ -22,3 +22,6 @@ COMPONENT_SRCDIRS += ./driver/tas5805m ./driver/es7148 COMPONENT_ADD_INCLUDEDIRS += ./driver/es7210 ./driver/es8156 ./driver/es7243e COMPONENT_SRCDIRS += ./driver/es7210 ./driver/es8156 ./driver/es7243e + +COMPONENT_ADD_INCLUDEDIRS += ./driver/ac101 +COMPONENT_SRCDIRS += ./driver/ac101 \ No newline at end of file diff --git a/components/audio_hal/driver/ac101/ac101.c b/components/audio_hal/driver/ac101/ac101.c new file mode 100644 index 000000000..2a362e25e --- /dev/null +++ b/components/audio_hal/driver/ac101/ac101.c @@ -0,0 +1,484 @@ +// code from https://github.com/donny681/esp-adf/blob/master/components/audio_hal/driver/AC101/AC101.c + +#include +#include "driver/i2c.h" +#include "board.h" +#include "esp_log.h" +#include "ac101.h" + +static char *TAG = "AC101"; + +static i2c_config_t ac_i2c_cfg = { + .mode = I2C_MODE_MASTER, + .sda_pullup_en = GPIO_PULLUP_ENABLE, + .scl_pullup_en = GPIO_PULLUP_ENABLE, + .master.clk_speed = 100000}; + +/* + * operate function of codec + */ +audio_hal_func_t AUDIO_CODEC_AC101_CODEC_HANDLE = { + .audio_codec_initialize = ac101_init, + .audio_codec_deinitialize = ac101_deinit, + .audio_codec_ctrl = ac101_ctrl_state, + .audio_codec_config_iface = ac101_config_i2s, + .audio_codec_set_mute = ac101_set_voice_mute, + .audio_codec_set_volume = ac101_set_voice_volume, + .audio_codec_get_volume = ac101_get_voice_volume, +}; + +#define AC_ASSERT(a, format, b, ...) \ + if ((a) != 0) \ + { \ + ESP_LOGE(TAG, format, ##__VA_ARGS__); \ + return b; \ + } + +static esp_err_t ac101_write_reg(uint8_t reg_addr, uint16_t val) +{ + i2c_cmd_handle_t cmd = i2c_cmd_link_create(); + esp_err_t ret = 0; + uint8_t send_buff[4]; + send_buff[0] = (AC101_ADDR << 1); + send_buff[1] = reg_addr; + send_buff[2] = (val >> 8) & 0xff; + send_buff[3] = val & 0xff; + ret |= i2c_master_start(cmd); + ret |= i2c_master_write(cmd, send_buff, 4, ACK_CHECK_EN); + ret |= i2c_master_stop(cmd); + ret |= i2c_master_cmd_begin(I2C_NUM_0, cmd, 1000 / portTICK_RATE_MS); + i2c_cmd_link_delete(cmd); + return ret; +} + +static esp_err_t i2c_example_master_read_slave(uint8_t DevAddr, uint8_t reg, uint8_t *data_rd, size_t size) +{ + if (size == 0) + { + return ESP_OK; + } + i2c_cmd_handle_t cmd = i2c_cmd_link_create(); + i2c_master_start(cmd); + i2c_master_write_byte(cmd, (DevAddr << 1) | WRITE_BIT, ACK_CHECK_EN); + i2c_master_write_byte(cmd, reg, ACK_CHECK_EN); + i2c_master_start(cmd); + i2c_master_write_byte(cmd, (DevAddr << 1) | READ_BIT, ACK_CHECK_EN); //check or not + i2c_master_read(cmd, data_rd, size, ACK_VAL); + i2c_master_stop(cmd); + esp_err_t ret = i2c_master_cmd_begin(I2C_NUM_0, cmd, 1000 / portTICK_RATE_MS); + i2c_cmd_link_delete(cmd); + return ret; +} + +static uint16_t ac101_read_reg(uint8_t reg_addr) +{ + uint16_t val = 0; + uint8_t data_rd[2]; + i2c_example_master_read_slave(AC101_ADDR, reg_addr, data_rd, 2); + val = (data_rd[0] << 8) + data_rd[1]; + return val; +} + +static int i2c_init() +{ + int res = 0; + get_i2c_pins(I2C_NUM_0, &ac_i2c_cfg); + res |= i2c_param_config(I2C_NUM_0, &ac_i2c_cfg); + res |= i2c_driver_install(I2C_NUM_0, ac_i2c_cfg.mode, 0, 0, 0); + AC_ASSERT(res, "i2c_init error", -1); + return res; +} + +void set_codec_clk(audio_hal_iface_samples_t sampledata) +{ + uint16_t sample_fre; + switch (sampledata) + { + case AUDIO_HAL_08K_SAMPLES: + sample_fre = 8000; + break; + case AUDIO_HAL_11K_SAMPLES: + sample_fre = 11025; + break; + case AUDIO_HAL_16K_SAMPLES: + sample_fre = 16000; + break; + case AUDIO_HAL_22K_SAMPLES: + sample_fre = 22050; + break; + case AUDIO_HAL_24K_SAMPLES: + sample_fre = 24000; + break; + case AUDIO_HAL_32K_SAMPLES: + sample_fre = 32000; + break; + case AUDIO_HAL_44K_SAMPLES: + sample_fre = 44100; + break; + case AUDIO_HAL_48K_SAMPLES: + sample_fre = 48000; + break; + default: + sample_fre = 44100; + } + ac101_write_reg(I2S_SR_CTRL, sample_fre); +} + +esp_err_t ac101_init(audio_hal_codec_config_t *codec_cfg) +{ + + // if(i2c_init() < 0) return -1; + + // esp_err_t res; + + esp_err_t res = ESP_OK; + + i2c_init(); // ESP32 in master mode + + res = ac101_write_reg(CHIP_AUDIO_RS, 0x123); + vTaskDelay(1000 / portTICK_PERIOD_MS); + + if (res != ESP_OK) + { + ESP_LOGE(TAG, "reset failed!"); + return res; + } + else + { + ESP_LOGW(TAG, "reset succeed"); + } + res |= ac101_write_reg(SPKOUT_CTRL, 0xe880); + + //Enable the PLL from 256*44.1KHz MCLK source + res |= ac101_write_reg(PLL_CTRL1, 0x014f); + //res |= ac101_write_reg(PLL_CTRL2, 0x83c0); + res |= ac101_write_reg(PLL_CTRL2, 0x8600); + + //Clocking system + res |= ac101_write_reg(SYSCLK_CTRL, 0x8b08); + res |= ac101_write_reg(MOD_CLK_ENA, 0x800c); + res |= ac101_write_reg(MOD_RST_CTRL, 0x800c); + res |= ac101_write_reg(I2S_SR_CTRL, 0x7000); //sample rate + //AIF config + res |= ac101_write_reg(I2S1LCK_CTRL, 0x8850); //BCLK/LRCK + res |= ac101_write_reg(I2S1_SDOUT_CTRL, 0xc000); // + res |= ac101_write_reg(I2S1_SDIN_CTRL, 0xc000); + res |= ac101_write_reg(I2S1_MXR_SRC, 0x2200); // + + res |= ac101_write_reg(ADC_SRCBST_CTRL, 0xccc4); + res |= ac101_write_reg(ADC_SRC, 0x2020); + res |= ac101_write_reg(ADC_DIG_CTRL, 0x8000); + res |= ac101_write_reg(ADC_APC_CTRL, 0xbbc3); + + //Path Configuration + res |= ac101_write_reg(DAC_MXR_SRC, 0xcc00); + res |= ac101_write_reg(DAC_DIG_CTRL, 0x8000); + res |= ac101_write_reg(OMIXER_SR, 0x0081); + res |= ac101_write_reg(OMIXER_DACA_CTRL, 0xf080); //} + + //* Enable Speaker output + res |= ac101_write_reg(0x58, 0xeabd); + + ESP_LOGI(TAG, "init done"); + ac101_pa_power(true); + return res; +} + +int ac101_get_spk_volume(void) +{ + int res; + res = ac101_read_reg(SPKOUT_CTRL); + res &= 0x1f; + return res * 2; +} + +esp_err_t ac101_set_spk_volume(uint8_t volume) +{ + if (volume > 0x3f) + volume = 0x3f; + volume = volume / 2; + + uint16_t res; + esp_err_t ret; + + res = ac101_read_reg(SPKOUT_CTRL); + res &= (~0x1f); + volume &= 0x1f; + res |= volume; + ret = ac101_write_reg(SPKOUT_CTRL, res); + return ret; +} + +int ac101_get_earph_volume(void) +{ + int res; + res = ac101_read_reg(HPOUT_CTRL); + return (res >> 4) & 0x3f; +} + +esp_err_t ac101_set_earph_volume(uint8_t volume) +{ + if (volume > 0x3f) + volume = 0x3f; + + uint16_t res, tmp; + esp_err_t ret; + res = ac101_read_reg(HPOUT_CTRL); + tmp = ~(0x3f << 4); + res &= tmp; + volume &= 0x3f; + res |= (volume << 4); + ret = ac101_write_reg(HPOUT_CTRL, res); + return ret; +} + +esp_err_t ac101_set_output_mixer_gain(ac_output_mixer_gain_t gain, ac_output_mixer_source_t source) +{ + uint16_t regval, temp, clrbit; + esp_err_t ret; + regval = ac101_read_reg(OMIXER_BST1_CTRL); + switch (source) + { + case SRC_MIC1: + temp = (gain & 0x7) << 6; + clrbit = ~(0x7 << 6); + break; + case SRC_MIC2: + temp = (gain & 0x7) << 3; + clrbit = ~(0x7 << 3); + break; + case SRC_LINEIN: + temp = (gain & 0x7); + clrbit = ~0x7; + break; + default: + return -1; + } + regval &= clrbit; + regval |= temp; + ret = ac101_write_reg(OMIXER_BST1_CTRL, regval); + return ret; +} + +esp_err_t AC101_start(ac_module_t mode) +{ + + esp_err_t res = 0; + if (mode == AC_MODULE_LINE) + { + res |= ac101_write_reg(0x51, 0x0408); + res |= ac101_write_reg(0x40, 0x8000); + res |= ac101_write_reg(0x50, 0x3bc0); + } + if (mode == AC_MODULE_ADC || mode == AC_MODULE_ADC_DAC || mode == AC_MODULE_LINE) + { + //I2S1_SDOUT_CTRL + //res |= ac101_write_reg(PLL_CTRL2, 0x8120); + res |= ac101_write_reg(0x04, 0x800c); + res |= ac101_write_reg(0x05, 0x800c); + //res |= ac101_write_reg(0x06, 0x3000); + } + if (mode == AC_MODULE_DAC || mode == AC_MODULE_ADC_DAC || mode == AC_MODULE_LINE) + { + //* Enable Headphoe output + res |= ac101_write_reg(OMIXER_DACA_CTRL, 0xff80); + res |= ac101_write_reg(HPOUT_CTRL, 0xc3c1); + res |= ac101_write_reg(HPOUT_CTRL, 0xcb00); + vTaskDelay(100 / portTICK_PERIOD_MS); + res |= ac101_write_reg(HPOUT_CTRL, 0xfbc0); + + //* Enable Speaker output + res |= ac101_write_reg(SPKOUT_CTRL, 0xeabd); + vTaskDelay(10 / portTICK_PERIOD_MS); + ac101_set_voice_volume(30); + } + + return res; +} + +esp_err_t AC101_stop(ac_module_t mode) +{ + esp_err_t res = 0; + res |= ac101_write_reg(HPOUT_CTRL, 0x01); //disable earphone + res |= ac101_write_reg(SPKOUT_CTRL, 0xe880); //disable speaker + return res; +} + +esp_err_t ac101_deinit(void) +{ + + return ac101_write_reg(CHIP_AUDIO_RS, 0x123); //soft reset +} + +esp_err_t ac101_ctrl_state(audio_hal_codec_mode_t mode, audio_hal_ctrl_t ctrl_state) +{ + int res = 0; + int es_mode_t = 0; + + switch (mode) + { + case AUDIO_HAL_CODEC_MODE_ENCODE: + es_mode_t = AC_MODULE_ADC; + break; + case AUDIO_HAL_CODEC_MODE_LINE_IN: + es_mode_t = AC_MODULE_LINE; + break; + case AUDIO_HAL_CODEC_MODE_DECODE: + es_mode_t = AC_MODULE_DAC; + break; + case AUDIO_HAL_CODEC_MODE_BOTH: + es_mode_t = AC_MODULE_ADC_DAC; + break; + default: + es_mode_t = AC_MODULE_DAC; + ESP_LOGW(TAG, "Codec mode not support, default is decode mode"); + break; + } + if (AUDIO_HAL_CTRL_STOP == ctrl_state) + { + res = AC101_stop(es_mode_t); + } + else + { + res = AC101_start(es_mode_t); + } + return res; +} + +esp_err_t ac101_config_i2s(audio_hal_codec_mode_t mode, audio_hal_codec_i2s_iface_t *iface) +{ + esp_err_t res = 0; + int bits = 0; + int fmat = 0; + int sample_fre = 0; + uint16_t regval; + switch (iface->bits) //0x10 + { + // case AUDIO_HAL_BIT_LENGTH_8BITS: + // bits = BIT_LENGTH_8_BITS; + // break; + case AUDIO_HAL_BIT_LENGTH_16BITS: + bits = BIT_LENGTH_16_BITS; + break; + case AUDIO_HAL_BIT_LENGTH_24BITS: + bits = BIT_LENGTH_24_BITS; + break; + default: + bits = BIT_LENGTH_16_BITS; + } + + switch (iface->fmt) //0x10 + { + case AUDIO_HAL_I2S_NORMAL: + fmat = 0x0; + break; + case AUDIO_HAL_I2S_LEFT: + fmat = 0x01; + break; + case AUDIO_HAL_I2S_RIGHT: + fmat = 0x02; + break; + case AUDIO_HAL_I2S_DSP: + fmat = 0x03; + break; + default: + fmat = 0x00; + break; + } + + switch (iface->samples) + { + case AUDIO_HAL_08K_SAMPLES: + sample_fre = 8000; + break; + case AUDIO_HAL_11K_SAMPLES: + sample_fre = 11025; + break; + case AUDIO_HAL_16K_SAMPLES: + sample_fre = 16000; + break; + case AUDIO_HAL_22K_SAMPLES: + sample_fre = 22050; + break; + case AUDIO_HAL_24K_SAMPLES: + sample_fre = 24000; + break; + case AUDIO_HAL_32K_SAMPLES: + sample_fre = 32000; + break; + case AUDIO_HAL_44K_SAMPLES: + sample_fre = 44100; + break; + case AUDIO_HAL_48K_SAMPLES: + sample_fre = 48000; + break; + default: + sample_fre = 44100; + } + regval = ac101_read_reg(I2S1LCK_CTRL); + regval &= 0xffc3; + regval |= (iface->mode << 15); + regval |= (bits << 4); + regval |= (fmat << 2); + res |= ac101_write_reg(I2S1LCK_CTRL, regval); + res |= ac101_write_reg(I2S_SR_CTRL, sample_fre); + return res; +} + +esp_err_t AC101_i2s_config_clock(ac_i2s_clock_t *cfg) +{ + esp_err_t res = 0; + uint16_t regval = 0; + regval = ac101_read_reg(I2S1LCK_CTRL); + regval &= 0xe03f; + regval |= (cfg->bclk_div << 9); + regval |= (cfg->lclk_div << 6); + res = ac101_write_reg(I2S1LCK_CTRL, regval); + return res; +} + +esp_err_t ac101_set_voice_mute(bool enable) +{ + esp_err_t res = 0; + + if (enable) + { + res = ac101_set_earph_volume(0); + res |= ac101_set_spk_volume(0); + } + return res; +} + +esp_err_t ac101_set_voice_volume(int volume) +{ + esp_err_t res; + res = ac101_set_earph_volume(volume); + res |= ac101_set_spk_volume(volume); + return res; +} + +esp_err_t ac101_get_voice_volume(int *volume) +{ + *volume = ac101_get_earph_volume(); + return 0; +} + +void ac101_pa_power(bool enable) +{ + gpio_config_t io_conf; + memset(&io_conf, 0, sizeof(io_conf)); + io_conf.intr_type = GPIO_PIN_INTR_DISABLE; + io_conf.mode = GPIO_MODE_OUTPUT; + io_conf.pin_bit_mask = BIT(PA_ENABLE_GPIO); + io_conf.pull_down_en = 0; + io_conf.pull_up_en = 0; + gpio_config(&io_conf); + if (enable) + { + gpio_set_level(PA_ENABLE_GPIO, 1); + } + else + { + gpio_set_level(PA_ENABLE_GPIO, 0); + } +} diff --git a/components/audio_hal/driver/ac101/ac101.h b/components/audio_hal/driver/ac101/ac101.h new file mode 100644 index 000000000..188bf7b02 --- /dev/null +++ b/components/audio_hal/driver/ac101/ac101.h @@ -0,0 +1,170 @@ +// code from https://github.com/donny681/esp-adf/blob/master/components/audio_hal/driver/AC101/AC101.h + +#ifndef __AC101_H__ +#define __AC101_H__ + +//#include "sdkconfig.h" +#include "esp_types.h" +#include "audio_hal.h" + +#define AC101_ADDR 0x1a /*!< Device address*/ + +#define WRITE_BIT I2C_MASTER_WRITE /*!< I2C master write */ +#define READ_BIT I2C_MASTER_READ /*!< I2C master read */ +#define ACK_CHECK_EN 0x1 /*!< I2C master will check ack from slave*/ +#define ACK_CHECK_DIS 0x0 /*!< I2C master will not check ack from slave */ +#define ACK_VAL 0x0 /*!< I2C ack value */ +#define NACK_VAL 0x1 /*!< I2C nack value */ + +#define CHIP_AUDIO_RS 0x00 +#define PLL_CTRL1 0x01 +#define PLL_CTRL2 0x02 +#define SYSCLK_CTRL 0x03 +#define MOD_CLK_ENA 0x04 +#define MOD_RST_CTRL 0x05 +#define I2S_SR_CTRL 0x06 +#define I2S1LCK_CTRL 0x10 +#define I2S1_SDOUT_CTRL 0x11 +#define I2S1_SDIN_CTRL 0x12 +#define I2S1_MXR_SRC 0x13 +#define I2S1_VOL_CTRL1 0x14 +#define I2S1_VOL_CTRL2 0x15 +#define I2S1_VOL_CTRL3 0x16 +#define I2S1_VOL_CTRL4 0x17 +#define I2S1_MXR_GAIN 0x18 +#define ADC_DIG_CTRL 0x40 +#define ADC_VOL_CTRL 0x41 +#define HMIC_CTRL1 0x44 +#define HMIC_CTRL2 0x45 +#define HMIC_STATUS 0x46 +#define DAC_DIG_CTRL 0x48 +#define DAC_VOL_CTRL 0x49 +#define DAC_MXR_SRC 0x4c +#define DAC_MXR_GAIN 0x4d +#define ADC_APC_CTRL 0x50 +#define ADC_SRC 0x51 +#define ADC_SRCBST_CTRL 0x52 +#define OMIXER_DACA_CTRL 0x53 +#define OMIXER_SR 0x54 +#define OMIXER_BST1_CTRL 0x55 +#define HPOUT_CTRL 0x56 +#define SPKOUT_CTRL 0x58 +#define AC_DAC_DAPCTRL 0xa0 +#define AC_DAC_DAPHHPFC 0xa1 +#define AC_DAC_DAPLHPFC 0xa2 +#define AC_DAC_DAPLHAVC 0xa3 +#define AC_DAC_DAPLLAVC 0xa4 +#define AC_DAC_DAPRHAVC 0xa5 +#define AC_DAC_DAPRLAVC 0xa6 +#define AC_DAC_DAPHGDEC 0xa7 +#define AC_DAC_DAPLGDEC 0xa8 +#define AC_DAC_DAPHGATC 0xa9 +#define AC_DAC_DAPLGATC 0xaa +#define AC_DAC_DAPHETHD 0xab +#define AC_DAC_DAPLETHD 0xac +#define AC_DAC_DAPHGKPA 0xad +#define AC_DAC_DAPLGKPA 0xae +#define AC_DAC_DAPHGOPA 0xaf +#define AC_DAC_DAPLGOPA 0xb0 +#define AC_DAC_DAPOPT 0xb1 +#define DAC_DAP_ENA 0xb5 + +typedef enum{ + SAMPLE_RATE_8000 = 0x0000, + SAMPLE_RATE_11052 = 0x1000, + SAMPLE_RATE_12000 = 0x2000, + SAMPLE_RATE_16000 = 0x3000, + SAMPLE_RATE_22050 = 0x4000, + SAMPLE_RATE_24000 = 0x5000, + SAMPLE_RATE_32000 = 0x6000, + SAMPLE_RATE_44100 = 0x7000, + SAMPLE_RATE_48000 = 0x8000, + SAMPLE_RATE_96000 = 0x9000, + SAMPLE_RATE_192000 = 0xa000, +}ac_adda_fs_i2s1_t; + +typedef enum{ + BCLK_DIV_1 = 0x0, + BCLK_DIV_2 = 0x1, + BCLK_DIV_4 = 0x2, + BCLK_DIV_6 = 0x3, + BCLK_DIV_8 = 0x4, + BCLK_DIV_12 = 0x5, + BCLK_DIV_16 = 0x6, + BCLK_DIV_24 = 0x7, + BCLK_DIV_32 = 0x8, + BCLK_DIV_48 = 0x9, + BCLK_DIV_64 = 0xa, + BCLK_DIV_96 = 0xb, + BCLK_DIV_128 = 0xc, + BCLK_DIV_192 = 0xd, + +}ac_i2s1_bclk_div_t; + +typedef enum{ + LRCK_DIV_16 =0x0, + LRCK_DIV_32 =0x1, + LRCK_DIV_64 =0x2, + LRCK_DIV_128 =0x3, + LRCK_DIV_256 =0x4, +}ac_i2s1_lrck_div_t; + +typedef enum { + BIT_LENGTH_8_BITS = 0x00, + BIT_LENGTH_16_BITS = 0x01, + BIT_LENGTH_20_BITS = 0x02, + BIT_LENGTH_24_BITS = 0x03, +} ac_bits_length_t; + +typedef enum { + AC_MODE_MIN = -1, + AC_MODE_SLAVE = 0x00, + AC_MODE_MASTER = 0x01, + AC_MODE_MAX, +} ac_mode_sm_t; + +typedef enum { + AC_MODULE_MIN = -1, + AC_MODULE_ADC = 0x01, + AC_MODULE_DAC = 0x02, + AC_MODULE_ADC_DAC = 0x03, + AC_MODULE_LINE = 0x04, + AC_MODULE_MAX +} ac_module_t; + +typedef enum{ + SRC_MIC1 = 1, + SRC_MIC2 = 2, + SRC_LINEIN = 3, +}ac_output_mixer_source_t; + +typedef enum { + GAIN_N45DB = 0, + GAIN_N30DB = 1, + GAIN_N15DB = 2, + GAIN_0DB = 3, + GAIN_15DB = 4, + GAIN_30DB = 5, + GAIN_45DB = 6, + GAIN_60DB = 7, +} ac_output_mixer_gain_t; + +/** + * @brief Configure AC101 clock + */ +typedef struct { + ac_i2s1_bclk_div_t bclk_div; /*!< bits clock divide */ + ac_i2s1_lrck_div_t lclk_div; /*!< WS clock divide */ +} ac_i2s_clock_t; + + +esp_err_t ac101_init(audio_hal_codec_config_t* codec_cfg); +esp_err_t ac101_deinit(void); +esp_err_t ac101_ctrl_state(audio_hal_codec_mode_t mode, audio_hal_ctrl_t ctrl_state); +esp_err_t ac101_config_i2s(audio_hal_codec_mode_t mode, audio_hal_codec_i2s_iface_t* iface); +esp_err_t ac101_set_voice_mute(bool enable); +esp_err_t ac101_set_voice_volume(int volume); +esp_err_t ac101_get_voice_volume(int* volume); +void ac101_pa_power(bool enable); + +#endif From 3a6e75eddc33fc19dfc0c357c67dd5fe5b99b651 Mon Sep 17 00:00:00 2001 From: Qiang Zhang Date: Sun, 13 Feb 2022 22:25:36 -0800 Subject: [PATCH 4/8] Create a board for ESP32-A1S-Kit ES8388 --- components/audio_board/CMakeLists.txt | 9 + components/audio_board/Kconfig.projbuild | 2 + .../ai_thinker_audio_kit_v2_2/README.MD | 4 + .../ai_thinker_audio_kit_v2_297/README.md | 4 + .../ai_thinker_audio_kit_v2_297/board.c | 134 +++++++++++++ .../ai_thinker_audio_kit_v2_297/board.h | 112 +++++++++++ .../ai_thinker_audio_kit_v2_297/board_def.h | 93 +++++++++ .../board_pins_config.c | 187 ++++++++++++++++++ components/audio_board/component.mk | 5 + 9 files changed, 550 insertions(+) create mode 100644 components/audio_board/ai_thinker_audio_kit_v2_2/README.MD create mode 100644 components/audio_board/ai_thinker_audio_kit_v2_297/README.md create mode 100644 components/audio_board/ai_thinker_audio_kit_v2_297/board.c create mode 100644 components/audio_board/ai_thinker_audio_kit_v2_297/board.h create mode 100644 components/audio_board/ai_thinker_audio_kit_v2_297/board_def.h create mode 100644 components/audio_board/ai_thinker_audio_kit_v2_297/board_pins_config.c diff --git a/components/audio_board/CMakeLists.txt b/components/audio_board/CMakeLists.txt index 011249469..3a6a3f898 100644 --- a/components/audio_board/CMakeLists.txt +++ b/components/audio_board/CMakeLists.txt @@ -88,4 +88,13 @@ set(COMPONENT_SRCS ) endif() +if (CONFIG_ESP_AI_THINKER_V2_297_BOARD) +message(STATUS "Current board name is " CONFIG_ESP_AI_THINKER_V2_297_BOARD) +list(APPEND COMPONENT_ADD_INCLUDEDIRS ./ai_thinker_audio_kit_v2_297) +set(COMPONENT_SRCS +./ai_thinker_audio_kit_v2_297/board.c +./ai_thinker_audio_kit_v2_297/board_pins_config.c +) +endif() + register_component() diff --git a/components/audio_board/Kconfig.projbuild b/components/audio_board/Kconfig.projbuild index f7edc2e12..b7d69154f 100644 --- a/components/audio_board/Kconfig.projbuild +++ b/components/audio_board/Kconfig.projbuild @@ -25,6 +25,8 @@ config ESP32_S3_KORVO2_V3_BOARD bool "ESP32-S3-Korvo-2 v3.0" config ESP_AI_THINKER_V2_2_BOARD bool "ESP32-AiThinker-audio V2.2" +config ESP_AI_THINKER_V2_297_BOARD + bool "ESP32-AiThinker-audio V2.297" endchoice choice ESP32_KORVO_DU1906_DAC diff --git a/components/audio_board/ai_thinker_audio_kit_v2_2/README.MD b/components/audio_board/ai_thinker_audio_kit_v2_2/README.MD new file mode 100644 index 000000000..d70b0e17a --- /dev/null +++ b/components/audio_board/ai_thinker_audio_kit_v2_2/README.MD @@ -0,0 +1,4 @@ +This is for ESP32-A1S-Kit AC101 Development Board(deprecated). Its back should be like +![](https://github.com/Ai-Thinker-Open/ESP32-A1S-AudioKit/raw/master/static/A1S_AC101.jpg) + +For more information, please check [Ai-Thinker-Open/ESP32-A1S-AudioKit](https://github.com/Ai-Thinker-Open/ESP32-A1S-AudioKit) \ No newline at end of file diff --git a/components/audio_board/ai_thinker_audio_kit_v2_297/README.md b/components/audio_board/ai_thinker_audio_kit_v2_297/README.md new file mode 100644 index 000000000..4507a290b --- /dev/null +++ b/components/audio_board/ai_thinker_audio_kit_v2_297/README.md @@ -0,0 +1,4 @@ +This is for ESP32-A1S-Kit ES8388 Development Board. The back should be like +![](https://github.com/Ai-Thinker-Open/ESP32-A1S-AudioKit/raw/master/static/A1S_ES8388.jpg) + +For more information, please check [Ai-Thinker-Open/ESP32-A1S-AudioKit](https://github.com/Ai-Thinker-Open/ESP32-A1S-AudioKit) \ No newline at end of file diff --git a/components/audio_board/ai_thinker_audio_kit_v2_297/board.c b/components/audio_board/ai_thinker_audio_kit_v2_297/board.c new file mode 100644 index 000000000..150e023ea --- /dev/null +++ b/components/audio_board/ai_thinker_audio_kit_v2_297/board.c @@ -0,0 +1,134 @@ +/* + * 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_button.h" + +static const char *TAG = "ESP32-A1S-Kit ES8388"; + +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_ES8388_DEFAULT_HANDLE); + AUDIO_NULL_CHECK(TAG, codec_hal, return NULL); + return codec_hal; +} + +display_service_handle_t audio_board_led_init(void) +{ + led_indicator_handle_t led = led_indicator_init((gpio_num_t)get_green_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) +{ + periph_button_cfg_t btn_cfg = { + .gpio_mask = (1ULL << get_input_rec_id()) | (1ULL << get_input_mode_id()), //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); + esp_err_t ret = ESP_OK; + ret = esp_periph_start(set, button_handle); + return ret; +} + +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); + 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; +} + +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); + audio_free(audio_board); + board_handle = NULL; + return ret; +} diff --git a/components/audio_board/ai_thinker_audio_kit_v2_297/board.h b/components/audio_board/ai_thinker_audio_kit_v2_297/board.h new file mode 100644 index 000000000..935addfeb --- /dev/null +++ b/components/audio_board/ai_thinker_audio_kit_v2_297/board.h @@ -0,0 +1,112 @@ +/* + * 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 */ +}; + +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 led peripheral and display service + * + * @return The audio display service handle + */ +display_service_handle_t audio_board_led_init(void); + +/** + * @brief Initialize key peripheral + * + * @param set The handle of esp_periph_set_handle_t + * + * @return + * - ESP_OK, success + * - Others, fail + */ +esp_err_t audio_board_key_init(esp_periph_set_handle_t set); + +/** + * @brief Initialize sdcard peripheral + * + * @param set The handle of esp_periph_set_handle_t + * + * @return + * - ESP_OK, success + * - Others, fail + */ +esp_err_t audio_board_sdcard_init(esp_periph_set_handle_t set, periph_sdcard_mode_t mode); + +/** + * @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/ai_thinker_audio_kit_v2_297/board_def.h b/components/audio_board/ai_thinker_audio_kit_v2_297/board_def.h new file mode 100644 index 000000000..4a906bf36 --- /dev/null +++ b/components/audio_board/ai_thinker_audio_kit_v2_297/board_def.h @@ -0,0 +1,93 @@ +/* + * 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 SDCARD_OPEN_FILE_NUM_MAX 5 +#define SDCARD_INTR_GPIO GPIO_NUM_34 + +#define BUTTON_VOLUP_ID 0 +#define BUTTON_VOLDOWN_ID 1 +#define BUTTON_SET_ID 2 +#define BUTTON_PLAY_ID 3 +#define BUTTON_MODE_ID 4 +#define BUTTON_REC_ID 5 + +#define AUXIN_DETECT_GPIO GPIO_NUM_12 +#define HEADPHONE_DETECT GPIO_NUM_19 +#define PA_ENABLE_GPIO GPIO_NUM_21 + +#define GREEN_LED_GPIO GPIO_NUM_22 + +extern audio_hal_func_t AUDIO_CODEC_ES8388_DEFAULT_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, \ + }, \ +}; + +#define INPUT_KEY_NUM 6 + +#define INPUT_KEY_DEFAULT_INFO() { \ + { \ + .type = PERIPH_ID_BUTTON, \ + .user_id = INPUT_KEY_USER_ID_REC, \ + .act_id = BUTTON_REC_ID, \ + }, \ + { \ + .type = PERIPH_ID_BUTTON, \ + .user_id = INPUT_KEY_USER_ID_MODE, \ + .act_id = BUTTON_MODE_ID, \ + }, \ + { \ + .type = PERIPH_ID_TOUCH, \ + .user_id = INPUT_KEY_USER_ID_SET, \ + .act_id = BUTTON_SET_ID, \ + }, \ + { \ + .type = PERIPH_ID_TOUCH, \ + .user_id = INPUT_KEY_USER_ID_PLAY, \ + .act_id = BUTTON_PLAY_ID, \ + }, \ + { \ + .type = PERIPH_ID_TOUCH, \ + .user_id = INPUT_KEY_USER_ID_VOLUP, \ + .act_id = BUTTON_VOLUP_ID, \ + }, \ + { \ + .type = PERIPH_ID_TOUCH, \ + .user_id = INPUT_KEY_USER_ID_VOLDOWN, \ + .act_id = BUTTON_VOLDOWN_ID, \ + } \ +} + +#endif diff --git a/components/audio_board/ai_thinker_audio_kit_v2_297/board_pins_config.c b/components/audio_board/ai_thinker_audio_kit_v2_297/board_pins_config.c new file mode 100644 index 000000000..459c1efba --- /dev/null +++ b/components/audio_board/ai_thinker_audio_kit_v2_297/board_pins_config.c @@ -0,0 +1,187 @@ +/* + * 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 = "ESP32-A1S-Kit ES8388"; + +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 || port == I2C_NUM_1) { + i2c_config->sda_io_num = GPIO_NUM_33; + i2c_config->scl_io_num = GPIO_NUM_32; + } 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 || port == I2S_NUM_1) { + i2s_config->bck_io_num = GPIO_NUM_27; + i2s_config->ws_io_num = GPIO_NUM_25; + i2s_config->data_out_num = GPIO_NUM_26; + i2s_config->data_in_num = GPIO_NUM_35; + } 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 = -1; + spi_config->miso_io_num = -1; + spi_config->sclk_io_num = -1; + 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; + } + ESP_LOGI(TAG, "I2S%d, MCLK output by GPIO%d", i2s_num, gpio_num); + 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); + } + } else if (i2s_num == I2S_NUM_1) { + if (gpio_num == GPIO_NUM_0) { + PIN_FUNC_SELECT(PERIPHS_IO_MUX_GPIO0_U, FUNC_GPIO0_CLK_OUT1); + WRITE_PERI_REG(PIN_CTRL, 0xFFFF); + } else if (gpio_num == GPIO_NUM_1) { + PIN_FUNC_SELECT(PERIPHS_IO_MUX_U0TXD_U, FUNC_U0TXD_CLK_OUT3); + WRITE_PERI_REG(PIN_CTRL, 0xF0FF); + } else { + PIN_FUNC_SELECT(PERIPHS_IO_MUX_U0RXD_U, FUNC_U0RXD_CLK_OUT2); + WRITE_PERI_REG(PIN_CTRL, 0xFF0F); + } + } + return ESP_OK; +} + +// sdcard + +int8_t get_sdcard_intr_gpio(void) +{ + return SDCARD_INTR_GPIO; +} + +int8_t get_sdcard_open_file_num_max(void) +{ + return SDCARD_OPEN_FILE_NUM_MAX; +} + +// input-output pins + +int8_t get_auxin_detect_gpio(void) +{ + return AUXIN_DETECT_GPIO; +} + +int8_t get_headphone_detect_gpio(void) +{ + return HEADPHONE_DETECT; +} + +int8_t get_pa_enable_gpio(void) +{ + return PA_ENABLE_GPIO; +} + +// button pins + +int8_t get_input_rec_id(void) +{ + return BUTTON_REC_ID; +} + +int8_t get_input_mode_id(void) +{ + return BUTTON_MODE_ID; +} + +// touch pins + +int8_t get_input_set_id(void) +{ + return BUTTON_SET_ID; +} + +int8_t get_input_play_id(void) +{ + return BUTTON_PLAY_ID; +} + +int8_t get_input_volup_id(void) +{ + return BUTTON_VOLUP_ID; +} + +int8_t get_input_voldown_id(void) +{ + return BUTTON_VOLDOWN_ID; +} + +// led pins + +int8_t get_green_led_gpio(void) +{ + return GREEN_LED_GPIO; +} diff --git a/components/audio_board/component.mk b/components/audio_board/component.mk index 56372362c..d139ad9e4 100644 --- a/components/audio_board/component.mk +++ b/components/audio_board/component.mk @@ -50,4 +50,9 @@ endif ifdef CONFIG_ESP_AI_THINKER_V2_2_BOARD COMPONENT_ADD_INCLUDEDIRS += ./ai_thinker_audio_kit_v2_2 COMPONENT_SRCDIRS += ./ai_thinker_audio_kit_v2_2 +endif + +ifdef CONFIG_ESP_AI_THINKER_V2_297_BOARD +COMPONENT_ADD_INCLUDEDIRS += ./ai_thinker_audio_kit_v2_297 +COMPONENT_SRCDIRS += ./ai_thinker_audio_kit_v2_297 endif \ No newline at end of file From f3b1186e495e772e6c11cacd4fd81fafdd7bde0d Mon Sep 17 00:00:00 2001 From: Qiang Zhang Date: Sun, 13 Feb 2022 22:26:02 -0800 Subject: [PATCH 5/8] Make the music start playing automatically. --- .../main/play_sdcard_mp3_control_example.c | 2 ++ 1 file changed, 2 insertions(+) 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 bd1347145..4f12d5cec 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 @@ -199,6 +199,8 @@ void app_main(void) ESP_LOGW(TAG, "[ 6 ] Press the keys to control music player:"); ESP_LOGW(TAG, " [Play] to start, pause and resume, [Set] next song."); ESP_LOGW(TAG, " [Vol-] or [Vol+] to adjust volume."); + ESP_LOGI(TAG, "[7] Start playing automatically."); + audio_pipeline_run(pipeline); while (1) { /* Handle event interface messages from pipeline From 8f3aad7ee1924d1dbf92369c747e022b58d8154b Mon Sep 17 00:00:00 2001 From: Qiang Zhang Date: Sun, 13 Feb 2022 23:09:50 -0800 Subject: [PATCH 6/8] Fix the key mapping for esp32-a1s According to https://docs.ai-thinker.com/en/esp32-audio-kit. But still only key 1 and key 2 are working. --- .../ai_thinker_audio_kit_v2_297/board_def.h | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) diff --git a/components/audio_board/ai_thinker_audio_kit_v2_297/board_def.h b/components/audio_board/ai_thinker_audio_kit_v2_297/board_def.h index 4a906bf36..12c4e678b 100644 --- a/components/audio_board/ai_thinker_audio_kit_v2_297/board_def.h +++ b/components/audio_board/ai_thinker_audio_kit_v2_297/board_def.h @@ -28,18 +28,22 @@ #define SDCARD_OPEN_FILE_NUM_MAX 5 #define SDCARD_INTR_GPIO GPIO_NUM_34 -#define BUTTON_VOLUP_ID 0 -#define BUTTON_VOLDOWN_ID 1 -#define BUTTON_SET_ID 2 -#define BUTTON_PLAY_ID 3 -#define BUTTON_MODE_ID 4 -#define BUTTON_REC_ID 5 +// According to https://docs.ai-thinker.com/en/esp32-audio-kit +// Only 36 and 13 are working +#define BUTTON_VOLUP_ID GPIO_NUM_5 +#define BUTTON_VOLDOWN_ID GPIO_NUM_18 +#define BUTTON_SET_ID GPIO_NUM_23 +#define BUTTON_PLAY_ID GPIO_NUM_19 +#define BUTTON_MODE_ID GPIO_NUM_13 +#define BUTTON_REC_ID GPIO_NUM_36 #define AUXIN_DETECT_GPIO GPIO_NUM_12 -#define HEADPHONE_DETECT GPIO_NUM_19 +#define HEADPHONE_DETECT GPIO_NUM_39 #define PA_ENABLE_GPIO GPIO_NUM_21 #define GREEN_LED_GPIO GPIO_NUM_22 +// This LED shares with KEY 3 +#define BLUE_LED_GPIO GPIO_NUM_19 extern audio_hal_func_t AUDIO_CODEC_ES8388_DEFAULT_HANDLE; From 4e859ac07b6a7648e660d107476b2ad86d8c6188 Mon Sep 17 00:00:00 2001 From: Qiang Zhang Date: Sun, 13 Feb 2022 23:16:52 -0800 Subject: [PATCH 7/8] Undo change to lyrat v4_3 --- components/audio_board/lyrat_v4_3/board_pins_config.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/components/audio_board/lyrat_v4_3/board_pins_config.c b/components/audio_board/lyrat_v4_3/board_pins_config.c index 930129cfb..6c0735fbb 100644 --- a/components/audio_board/lyrat_v4_3/board_pins_config.c +++ b/components/audio_board/lyrat_v4_3/board_pins_config.c @@ -35,8 +35,8 @@ 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 || port == I2C_NUM_1) { - i2c_config->sda_io_num = GPIO_NUM_33; - i2c_config->scl_io_num = GPIO_NUM_32; + i2c_config->sda_io_num = GPIO_NUM_18; + i2c_config->scl_io_num = GPIO_NUM_23; } else { i2c_config->sda_io_num = -1; i2c_config->scl_io_num = -1; @@ -50,7 +50,7 @@ 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 || port == I2S_NUM_1) { - i2s_config->bck_io_num = GPIO_NUM_27; + i2s_config->bck_io_num = GPIO_NUM_5; i2s_config->ws_io_num = GPIO_NUM_25; i2s_config->data_out_num = GPIO_NUM_26; i2s_config->data_in_num = GPIO_NUM_35; From dc4f652efe8a3b3638b08a798af6e13763fd95c8 Mon Sep 17 00:00:00 2001 From: Qiang Zhang Date: Wed, 16 Feb 2022 23:03:38 -0800 Subject: [PATCH 8/8] Add resampler to fix music sample rate doesn't match ad2p --- .../main/play_bt_source_example.c | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) 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 f7dd925e7..26e12ce7f 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 @@ -19,6 +19,7 @@ #include "audio_event_iface.h" #include "board.h" #include "mp3_decoder.h" +#include "filter_resample.h" #include "a2dp_stream.h" #include "fatfs_stream.h" @@ -168,7 +169,7 @@ static void bt_app_gap_cb(esp_bt_gap_cb_event_t event, esp_bt_gap_cb_param_t *pa void app_main(void) { audio_pipeline_handle_t pipeline; - audio_element_handle_t fatfs_stream_reader, bt_stream_writer, mp3_decoder; + audio_element_handle_t fatfs_stream_reader, bt_stream_writer, mp3_decoder, rsp_handle; esp_log_level_set("*", ESP_LOG_WARN); esp_log_level_set(TAG, ESP_LOG_INFO); @@ -207,6 +208,10 @@ void app_main(void) mp3_decoder_cfg_t mp3_cfg = DEFAULT_MP3_DECODER_CONFIG(); mp3_decoder = mp3_decoder_init(&mp3_cfg); + ESP_LOGI(TAG, "[3.2.5] Create resample filter"); + rsp_filter_cfg_t rsp_cfg = DEFAULT_RESAMPLE_FILTER_CONFIG(); + rsp_handle = rsp_filter_init(&rsp_cfg); + ESP_LOGI(TAG, "[3.3] Create Bluetooth stream"); esp_bt_controller_config_t bt_cfg = BT_CONTROLLER_INIT_CONFIG_DEFAULT(); @@ -247,11 +252,12 @@ void app_main(void) ESP_LOGI(TAG, "[3.4] Register all elements to audio pipeline"); audio_pipeline_register(pipeline, fatfs_stream_reader, "file"); audio_pipeline_register(pipeline, mp3_decoder, "mp3"); + audio_pipeline_register(pipeline, rsp_handle, "filter"); audio_pipeline_register(pipeline, bt_stream_writer, "bt"); ESP_LOGI(TAG, "[3.5] Link it together [sdcard]-->fatfs_stream-->mp3_decoder-->bt_stream-->[bt sink]"); - const char *link_tag[3] = {"file", "mp3", "bt"}; - audio_pipeline_link(pipeline, &link_tag[0], 3); + const char *link_tag[4] = {"file", "mp3", "filter", "bt"}; + audio_pipeline_link(pipeline, &link_tag[0], 4); ESP_LOGI(TAG, "[3.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"); @@ -292,6 +298,7 @@ void app_main(void) 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(rsp_handle, music_info.sample_rates, music_info.channels); continue; } if (msg.source_type == PERIPH_ID_BLUETOOTH @@ -323,10 +330,12 @@ void app_main(void) audio_pipeline_unregister(pipeline, bt_stream_writer); audio_pipeline_unregister(pipeline, fatfs_stream_reader); audio_pipeline_unregister(pipeline, mp3_decoder); + audio_pipeline_unregister(pipeline, rsp_handle); audio_pipeline_deinit(pipeline); audio_element_deinit(bt_stream_writer); audio_element_deinit(fatfs_stream_reader); audio_element_deinit(mp3_decoder); + audio_element_deinit(rsp_handle); esp_periph_set_destroy(set); esp_bluedroid_disable(); esp_bluedroid_deinit();