diff --git a/.build-test-rules.yml b/.build-test-rules.yml index 35faf671..a3f9c8e5 100644 --- a/.build-test-rules.yml +++ b/.build-test-rules.yml @@ -1,4 +1,4 @@ examples: disable: - - if: IDF_VERSION_MAJOR < 5 and CONFIG_NAME not in ["esp-box", "esp-box-lite", "esp32_s3_eye", "esp_wrover_kit"] + - if: IDF_VERSION_MAJOR < 5 and CONFIG_NAME not in ["esp-box", "esp-box-lite", "esp32_s3_eye", "esp_wrover_kit", "esp32_s3_korvo_2"] reason: Example depends on BSP, which is supported only for IDF >= 5.0 diff --git a/esp32_s3_korvo_2/CMakeLists.txt b/esp32_s3_korvo_2/CMakeLists.txt index 0a514c10..0836705f 100644 --- a/esp32_s3_korvo_2/CMakeLists.txt +++ b/esp32_s3_korvo_2/CMakeLists.txt @@ -1,7 +1,16 @@ +#IDF version is less than IDF5.0 +if("${IDF_VERSION_MAJOR}.${IDF_VERSION_MINOR}" VERSION_LESS "5.0") + set(SRC_VER "esp32_s3_korvo_2_idf4.c") + set(REQ driver esp_lcd) +else() + set(SRC_VER "esp32_s3_korvo_2_idf5.c") + set(REQ driver esp_lcd esp_adc) +endif() + idf_component_register( - SRCS "esp32_s3_korvo_2.c" + SRCS "esp32_s3_korvo_2.c" ${SRC_VER} INCLUDE_DIRS "include" PRIV_INCLUDE_DIRS "priv_include" - REQUIRES driver - PRIV_REQUIRES fatfs esp_lcd esp_adc spiffs + REQUIRES ${REQ} + PRIV_REQUIRES spiffs fatfs ) diff --git a/esp32_s3_korvo_2/README.md b/esp32_s3_korvo_2/README.md index 9ba8ec97..392e0530 100644 --- a/esp32_s3_korvo_2/README.md +++ b/esp32_s3_korvo_2/README.md @@ -1,5 +1,7 @@ # BSP: ESP32-S3-Korvo-2 +[![Component Registry](https://components.espressif.com/components/espressif/esp32_s3_korvo_2/badge.svg)](https://components.espressif.com/components/espressif/esp32_s3_korvo_2) + * [Documentation](https://espressif-docs.readthedocs-hosted.com/projects/esp-adf/en/latest/design-guide/dev-boards/user-guide-esp32-s3-korvo-2.html) ![image](pic.png) diff --git a/esp32_s3_korvo_2/esp32_s3_korvo_2.c b/esp32_s3_korvo_2/esp32_s3_korvo_2.c index d2137d12..0bfb99f0 100644 --- a/esp32_s3_korvo_2/esp32_s3_korvo_2.c +++ b/esp32_s3_korvo_2/esp32_s3_korvo_2.c @@ -15,10 +15,6 @@ #include "esp_lcd_panel_ops.h" #include "esp_spiffs.h" -//#include "esp_adc/adc_oneshot.h" -//#include "esp_adc/adc_cali.h" -//#include "esp_adc/adc_cali_scheme.h" - #include "bsp/esp32_s3_korvo_2.h" #include "bsp/display.h" #include "bsp/touch.h" @@ -30,50 +26,16 @@ #include "esp_codec_dev_defaults.h" #include "bsp_err_check.h" -/* Battery voltage measurement is disabled, because it waits for update button component. */ -#define BSP_BATTERY_ENABLED 0 - -/** - * @brief I2S pinout - * - * Can be used for i2s_std_gpio_config_t and/or i2s_std_config_t initialization - */ -#define BSP_I2S_GPIO_CFG \ - { \ - .mclk = BSP_I2S_MCLK, \ - .bclk = BSP_I2S_SCLK, \ - .ws = BSP_I2S_LCLK, \ - .dout = BSP_I2S_DOUT, \ - .din = BSP_I2S_DSIN, \ - .invert_flags = { \ - .mclk_inv = false, \ - .bclk_inv = false, \ - .ws_inv = false, \ - }, \ - } - -/** - * @brief Mono Duplex I2S configuration structure - */ -#define BSP_I2S_DUPLEX_MONO_CFG(_sample_rate) \ - { \ - .clk_cfg = I2S_STD_CLK_DEFAULT_CONFIG(_sample_rate), \ - .slot_cfg = I2S_STD_PHILIP_SLOT_DEFAULT_CONFIG(I2S_DATA_BIT_WIDTH_16BIT, I2S_SLOT_MODE_MONO), \ - .gpio_cfg = BSP_I2S_GPIO_CFG, \ - } - static const char *TAG = "S3-KORVO-2"; static esp_io_expander_handle_t io_expander = NULL; // IO expander tca9554 handle -//static adc_oneshot_unit_handle_t adc1_handle; // ADC1 handle; for USB voltage measurement -//static adc_cali_handle_t adc1_cali_handle; // ADC1 calibration handle sdmmc_card_t *bsp_sdcard = NULL; // Global uSD card handler static esp_lcd_touch_handle_t tp; // LCD touch handle static lv_indev_t *disp_indev = NULL; -static const audio_codec_data_if_t *i2s_data_if = NULL; /* Codec data interface */ -static i2s_chan_handle_t i2s_tx_chan = NULL; -static i2s_chan_handle_t i2s_rx_chan = NULL; static bool i2c_initialized = false; +#if ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(5, 0, 0) +static adc_oneshot_unit_handle_t bsp_adc_handle = NULL; +#endif // This is just a wrapper to get function signature for espressif/button API callback static uint8_t bsp_get_main_button(void *param); @@ -82,6 +44,9 @@ static esp_err_t bsp_init_main_button(void *param); static const button_config_t bsp_button_config[BSP_BUTTON_NUM] = { { .type = BUTTON_TYPE_ADC, +#if ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(5, 0, 0) + .adc_button_config.adc_handle = &bsp_adc_handle, +#endif .adc_button_config.adc_channel = ADC_CHANNEL_4, // ADC1 channel 4 is GPIO5 .adc_button_config.button_index = BSP_BUTTON_REC, .adc_button_config.min = 2310, // middle is 2410mV @@ -89,6 +54,9 @@ static const button_config_t bsp_button_config[BSP_BUTTON_NUM] = { }, { .type = BUTTON_TYPE_ADC, +#if ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(5, 0, 0) + .adc_button_config.adc_handle = &bsp_adc_handle, +#endif .adc_button_config.adc_channel = ADC_CHANNEL_4, // ADC1 channel 4 is GPIO5 .adc_button_config.button_index = BSP_BUTTON_MUTE, .adc_button_config.min = 1880, // middle is 1980mV @@ -96,6 +64,9 @@ static const button_config_t bsp_button_config[BSP_BUTTON_NUM] = { }, { .type = BUTTON_TYPE_ADC, +#if ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(5, 0, 0) + .adc_button_config.adc_handle = &bsp_adc_handle, +#endif .adc_button_config.adc_channel = ADC_CHANNEL_4, // ADC1 channel 4 is GPIO5 .adc_button_config.button_index = BSP_BUTTON_PLAY, .adc_button_config.min = 1550, // middle is 1650mV @@ -103,6 +74,9 @@ static const button_config_t bsp_button_config[BSP_BUTTON_NUM] = { }, { .type = BUTTON_TYPE_ADC, +#if ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(5, 0, 0) + .adc_button_config.adc_handle = &bsp_adc_handle, +#endif .adc_button_config.adc_channel = ADC_CHANNEL_4, // ADC1 channel 4 is GPIO5 .adc_button_config.button_index = BSP_BUTTON_SET, .adc_button_config.min = 1010, // middle is 1110mV @@ -110,6 +84,9 @@ static const button_config_t bsp_button_config[BSP_BUTTON_NUM] = { }, { .type = BUTTON_TYPE_ADC, +#if ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(5, 0, 0) + .adc_button_config.adc_handle = &bsp_adc_handle, +#endif .adc_button_config.adc_channel = ADC_CHANNEL_4, // ADC1 channel 4 is GPIO5 .adc_button_config.button_index = BSP_BUTTON_VOLDOWN, .adc_button_config.min = 720, // middle is 820mV @@ -117,6 +94,9 @@ static const button_config_t bsp_button_config[BSP_BUTTON_NUM] = { }, { .type = BUTTON_TYPE_ADC, +#if ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(5, 0, 0) + .adc_button_config.adc_handle = &bsp_adc_handle, +#endif .adc_button_config.adc_channel = ADC_CHANNEL_4, // ADC1 channel 4 is GPIO5 .adc_button_config.button_index = BSP_BUTTON_VOLUP, .adc_button_config.min = 280, // middle is 380mV @@ -193,54 +173,23 @@ esp_err_t bsp_sdcard_mount(void) .flags = 0, }; - return esp_vfs_fat_sdmmc_mount(BSP_MOUNT_POINT, &host, &slot_config, &mount_config, &bsp_sdcard); + return esp_vfs_fat_sdmmc_mount(BSP_SD_MOUNT_POINT, &host, &slot_config, &mount_config, &bsp_sdcard); } esp_err_t bsp_sdcard_unmount(void) { - return esp_vfs_fat_sdcard_unmount(BSP_MOUNT_POINT, bsp_sdcard); -} - -esp_err_t bsp_audio_init(const i2s_std_config_t *i2s_config, i2s_chan_handle_t *tx_channel, i2s_chan_handle_t *rx_channel) -{ - /* Setup I2S peripheral */ - i2s_chan_config_t chan_cfg = I2S_CHANNEL_DEFAULT_CONFIG(CONFIG_BSP_I2S_NUM, I2S_ROLE_MASTER); - chan_cfg.auto_clear = true; // Auto clear the legacy data in the DMA buffer - BSP_ERROR_CHECK_RETURN_ERR(i2s_new_channel(&chan_cfg, tx_channel, rx_channel)); - - /* Setup I2S channels */ - const i2s_std_config_t std_cfg_default = BSP_I2S_DUPLEX_MONO_CFG(22050); - const i2s_std_config_t *p_i2s_cfg = &std_cfg_default; - if (i2s_config != NULL) { - p_i2s_cfg = i2s_config; - } - - if (tx_channel != NULL) { - BSP_ERROR_CHECK_RETURN_ERR(i2s_channel_init_std_mode(*tx_channel, p_i2s_cfg)); - BSP_ERROR_CHECK_RETURN_ERR(i2s_channel_enable(*tx_channel)); - } - if (rx_channel != NULL) { - BSP_ERROR_CHECK_RETURN_ERR(i2s_channel_init_std_mode(*rx_channel, p_i2s_cfg)); - BSP_ERROR_CHECK_RETURN_ERR(i2s_channel_enable(*rx_channel)); - } - - audio_codec_i2s_cfg_t i2s_cfg = { - .port = CONFIG_BSP_I2S_NUM, - .rx_handle = *rx_channel, - .tx_handle = *tx_channel, - }; - i2s_data_if = audio_codec_new_i2s_data(&i2s_cfg); - BSP_NULL_CHECK(i2s_data_if, ESP_FAIL); - - return ESP_OK; + return esp_vfs_fat_sdcard_unmount(BSP_SD_MOUNT_POINT, bsp_sdcard); } esp_codec_dev_handle_t bsp_audio_codec_speaker_init(void) { - if (i2s_tx_chan == NULL || i2s_rx_chan == NULL || i2s_data_if == NULL) { - /* Initialize I2C and I2S */ - BSP_ERROR_CHECK_RETURN_ERR(bsp_i2c_init()); - BSP_ERROR_CHECK_RETURN_ERR(bsp_audio_init(NULL, &i2s_tx_chan, &i2s_rx_chan)); + const audio_codec_data_if_t *i2s_data_if = bsp_audio_get_codec_itf(); + if (i2s_data_if == NULL) { + /* Initilize I2C */ + BSP_ERROR_CHECK_RETURN_NULL(bsp_i2c_init()); + /* Configure I2S peripheral and Power Amplifier */ + BSP_ERROR_CHECK_RETURN_NULL(bsp_audio_init(NULL)); + i2s_data_if = bsp_audio_get_codec_itf(); } assert(i2s_data_if); @@ -284,10 +233,13 @@ esp_codec_dev_handle_t bsp_audio_codec_speaker_init(void) esp_codec_dev_handle_t bsp_audio_codec_microphone_init(void) { - if (i2s_tx_chan == NULL || i2s_rx_chan == NULL || i2s_data_if == NULL) { - /* Initialize I2C and I2S */ - BSP_ERROR_CHECK_RETURN_ERR(bsp_i2c_init()); - BSP_ERROR_CHECK_RETURN_ERR(bsp_audio_init(NULL, &i2s_tx_chan, &i2s_rx_chan)); + const audio_codec_data_if_t *i2s_data_if = bsp_audio_get_codec_itf(); + if (i2s_data_if == NULL) { + /* Initilize I2C */ + BSP_ERROR_CHECK_RETURN_NULL(bsp_i2c_init()); + /* Configure I2S peripheral and Power Amplifier */ + BSP_ERROR_CHECK_RETURN_NULL(bsp_audio_init(NULL)); + i2s_data_if = bsp_audio_get_codec_itf(); } assert(i2s_data_if); @@ -495,10 +447,18 @@ esp_err_t bsp_display_backlight_on(void) } lv_disp_t *bsp_display_start(void) +{ + bsp_display_cfg_t cfg = { + .lvgl_port_cfg = ESP_LVGL_PORT_INIT_CONFIG() + }; + return bsp_display_start_with_config(&cfg); +} + +lv_disp_t *bsp_display_start_with_config(const bsp_display_cfg_t *cfg) { lv_disp_t *disp = NULL; - const lvgl_port_cfg_t lvgl_cfg = ESP_LVGL_PORT_INIT_CONFIG(); - BSP_ERROR_CHECK_RETURN_NULL(lvgl_port_init(&lvgl_cfg)); + assert(cfg != NULL); + BSP_ERROR_CHECK_RETURN_NULL(lvgl_port_init(&cfg->lvgl_port_cfg)); BSP_NULL_CHECK(disp = bsp_display_lcd_init(), NULL); @@ -527,51 +487,6 @@ void bsp_display_unlock(void) lvgl_port_unlock(); } -esp_err_t bsp_voltage_init(void) -{ -#if BSP_BATTERY_ENABLED - // Init ADC1 - const adc_oneshot_unit_init_cfg_t init_config1 = { - .unit_id = ADC_UNIT_1, - }; - BSP_ERROR_CHECK_RETURN_ERR(adc_oneshot_new_unit(&init_config1, &adc1_handle)); - - // Init ADC1 channels - const adc_oneshot_chan_cfg_t config = { - .bitwidth = ADC_BITWIDTH_DEFAULT, - .atten = ADC_ATTEN_DB_11, - }; - BSP_ERROR_CHECK_RETURN_ERR(adc_oneshot_config_channel(adc1_handle, ADC_CHANNEL_5, &config)); - - // ESP32-S3 supports Curve Fitting calibration scheme - const adc_cali_curve_fitting_config_t cali_config = { - .unit_id = ADC_UNIT_1, - .atten = ADC_ATTEN_DB_11, - .bitwidth = ADC_BITWIDTH_DEFAULT, - }; - BSP_ERROR_CHECK_RETURN_ERR(adc_cali_create_scheme_curve_fitting(&cali_config, &adc1_cali_handle)); - return ESP_OK; -#else - ESP_LOGW(TAG, "Battery voltage measurement is disabled, because it waits for update button component."); - return ESP_ERR_NOT_SUPPORTED; -#endif -} - -int bsp_voltage_battery_get(void) -{ -#if BSP_BATTERY_ENABLED - int voltage, adc_raw; - - assert(adc1_handle); - BSP_ERROR_CHECK(adc_oneshot_read(adc1_handle, ADC_CHANNEL_5, &adc_raw), -1); - BSP_ERROR_CHECK(adc_cali_raw_to_voltage(adc1_cali_handle, adc_raw, &voltage), -1); - return voltage * BSP_BATTERY_VOLTAGE_DIV; -#else - ESP_LOGW(TAG, "Battery voltage measurement is disabled, because it waits for update button component."); - return -1; -#endif -} - esp_err_t bsp_leds_init(void) { BSP_NULL_CHECK(bsp_io_expander_init(), ESP_ERR_INVALID_STATE); @@ -640,6 +555,11 @@ esp_err_t bsp_iot_button_create(button_handle_t btn_array[], int *btn_cnt, int b (btn_array == NULL)) { return ESP_ERR_INVALID_ARG; } +#if ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(5, 0, 0) + /* Initialize ADC and get ADC handle */ + BSP_ERROR_CHECK_RETURN_NULL(bsp_adc_initialize()); + bsp_adc_handle = bsp_adc_get_handle(); +#endif if (btn_cnt) { *btn_cnt = 0; diff --git a/esp32_s3_korvo_2/esp32_s3_korvo_2_idf4.c b/esp32_s3_korvo_2/esp32_s3_korvo_2_idf4.c new file mode 100644 index 00000000..60972e07 --- /dev/null +++ b/esp32_s3_korvo_2/esp32_s3_korvo_2_idf4.c @@ -0,0 +1,106 @@ +/* + * SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include "esp_err.h" +#include "bsp/esp32_s3_korvo_2.h" +#include "bsp_err_check.h" +#include "esp_codec_dev_defaults.h" +#include "driver/adc.h" +#include "esp_adc_cal.h" + +static const char *TAG = "S3-KORVO-2"; + +/* This configuration is used by default in bsp_audio_init() */ +#define BSP_I2S_DUPLEX_MONO_CFG(_sample_rate) \ + { \ + .mode = I2S_MODE_MASTER | I2S_MODE_TX | I2S_MODE_RX, \ + .sample_rate = _sample_rate, \ + .bits_per_sample = I2S_BITS_PER_SAMPLE_16BIT, \ + .channel_format = I2S_CHANNEL_FMT_ONLY_LEFT, \ + .communication_format = I2S_COMM_FORMAT_STAND_I2S, \ + .dma_buf_count = 3, \ + .dma_buf_len = 1024, \ + .use_apll = true, \ + .tx_desc_auto_clear = true, \ + .intr_alloc_flags = ESP_INTR_FLAG_LEVEL2 | ESP_INTR_FLAG_IRAM \ + } + +static const audio_codec_data_if_t *i2s_data_if = NULL; /* Codec data interface */ +static esp_adc_cal_characteristics_t bsp_adc_chars; + +esp_err_t bsp_audio_init(const i2s_config_t *i2s_config) +{ + esp_err_t ret = ESP_FAIL; + + if (i2s_data_if != NULL) { + /* Audio was initialized before */ + return ESP_OK; + } + + /* Setup I2S peripheral */ + const i2s_pin_config_t i2s_pin_config = { + .mck_io_num = BSP_I2S_MCLK, + .bck_io_num = BSP_I2S_SCLK, + .ws_io_num = BSP_I2S_LCLK, + .data_out_num = BSP_I2S_DOUT, + .data_in_num = BSP_I2S_DSIN + }; + + /* Setup I2S channels */ + const i2s_config_t std_cfg_default = BSP_I2S_DUPLEX_MONO_CFG(22050); + const i2s_config_t *p_i2s_cfg = &std_cfg_default; + if (i2s_config != NULL) { + p_i2s_cfg = i2s_config; + } + + ESP_ERROR_CHECK(i2s_driver_install(CONFIG_BSP_I2S_NUM, p_i2s_cfg, 0, NULL)); + ESP_GOTO_ON_ERROR(i2s_set_pin(CONFIG_BSP_I2S_NUM, &i2s_pin_config), err, TAG, "I2S set pin failed"); + + audio_codec_i2s_cfg_t i2s_cfg = { + .port = CONFIG_BSP_I2S_NUM, + }; + i2s_data_if = audio_codec_new_i2s_data(&i2s_cfg); + BSP_NULL_CHECK_GOTO(i2s_data_if, err); + + return ESP_OK; + +err: + i2s_driver_uninstall(CONFIG_BSP_I2S_NUM); + return ret; +} + +const audio_codec_data_if_t *bsp_audio_get_codec_itf(void) +{ + return i2s_data_if; +} + +esp_err_t bsp_adc_initialize(void) +{ + esp_err_t ret = ESP_OK; + BSP_ERROR_CHECK_RETURN_ERR(esp_adc_cal_check_efuse(ESP_ADC_CAL_VAL_EFUSE_TP_FIT)); + esp_adc_cal_characterize(ADC_UNIT_1, ADC_ATTEN_DB_11, ADC_WIDTH_BIT_DEFAULT, 0, &bsp_adc_chars); + + /* ADC1 config */ + BSP_ERROR_CHECK_RETURN_ERR(adc1_config_width(ADC_WIDTH_BIT_DEFAULT)); + return ret; +} + +esp_err_t bsp_voltage_init(void) +{ + BSP_ERROR_CHECK_RETURN_ERR(bsp_adc_initialize()); + BSP_ERROR_CHECK_RETURN_ERR(adc1_config_channel_atten(ADC1_CHANNEL_5, ADC_ATTEN_DB_11)); + + return ESP_OK; +} + +int bsp_voltage_battery_get(void) +{ + int voltage, adc_raw; + + adc_raw = adc1_get_raw(ADC1_CHANNEL_5); + voltage = esp_adc_cal_raw_to_voltage(adc_raw, &bsp_adc_chars); + return voltage * BSP_BATTERY_VOLTAGE_DIV; +} diff --git a/esp32_s3_korvo_2/esp32_s3_korvo_2_idf5.c b/esp32_s3_korvo_2/esp32_s3_korvo_2_idf5.c new file mode 100644 index 00000000..08fb1acf --- /dev/null +++ b/esp32_s3_korvo_2/esp32_s3_korvo_2_idf5.c @@ -0,0 +1,150 @@ +/* + * SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include "esp_err.h" +#include "esp_adc/adc_oneshot.h" +#include "bsp/esp32_s3_korvo_2.h" +#include "bsp_err_check.h" +#include "esp_codec_dev_defaults.h" + +static const char *TAG = "S3-KORVO-2"; + +static i2s_chan_handle_t i2s_tx_chan = NULL; +static i2s_chan_handle_t i2s_rx_chan = NULL; +static const audio_codec_data_if_t *i2s_data_if = NULL; /* Codec data interface */ +static adc_oneshot_unit_handle_t bsp_adc_handle = NULL; +static adc_cali_handle_t bsp_adc_cali_handle; /* ADC1 calibration handle */ + +/* Can be used for i2s_std_gpio_config_t and/or i2s_std_config_t initialization */ +#define BSP_I2S_GPIO_CFG \ + { \ + .mclk = BSP_I2S_MCLK, \ + .bclk = BSP_I2S_SCLK, \ + .ws = BSP_I2S_LCLK, \ + .dout = BSP_I2S_DOUT, \ + .din = BSP_I2S_DSIN, \ + .invert_flags = { \ + .mclk_inv = false, \ + .bclk_inv = false, \ + .ws_inv = false, \ + }, \ + } + +/* This configuration is used by default in bsp_audio_init() */ +#define BSP_I2S_DUPLEX_MONO_CFG(_sample_rate) \ + { \ + .clk_cfg = I2S_STD_CLK_DEFAULT_CONFIG(_sample_rate), \ + .slot_cfg = I2S_STD_PHILIP_SLOT_DEFAULT_CONFIG(I2S_DATA_BIT_WIDTH_16BIT, I2S_SLOT_MODE_MONO), \ + .gpio_cfg = BSP_I2S_GPIO_CFG, \ + } + +esp_err_t bsp_audio_init(const i2s_std_config_t *i2s_config) +{ + esp_err_t ret = ESP_FAIL; + if (i2s_tx_chan && i2s_rx_chan) { + /* Audio was initialized before */ + return ESP_OK; + } + + /* Setup I2S peripheral */ + i2s_chan_config_t chan_cfg = I2S_CHANNEL_DEFAULT_CONFIG(CONFIG_BSP_I2S_NUM, I2S_ROLE_MASTER); + chan_cfg.auto_clear = true; // Auto clear the legacy data in the DMA buffer + BSP_ERROR_CHECK_RETURN_ERR(i2s_new_channel(&chan_cfg, &i2s_tx_chan, &i2s_rx_chan)); + + /* Setup I2S channels */ + const i2s_std_config_t std_cfg_default = BSP_I2S_DUPLEX_MONO_CFG(22050); + const i2s_std_config_t *p_i2s_cfg = &std_cfg_default; + if (i2s_config != NULL) { + p_i2s_cfg = i2s_config; + } + + if (i2s_tx_chan != NULL) { + ESP_GOTO_ON_ERROR(i2s_channel_init_std_mode(i2s_tx_chan, p_i2s_cfg), err, TAG, "I2S channel initialization failed"); + ESP_GOTO_ON_ERROR(i2s_channel_enable(i2s_tx_chan), err, TAG, "I2S enabling failed"); + } + if (i2s_rx_chan != NULL) { + ESP_GOTO_ON_ERROR(i2s_channel_init_std_mode(i2s_rx_chan, p_i2s_cfg), err, TAG, "I2S channel initialization failed"); + ESP_GOTO_ON_ERROR(i2s_channel_enable(i2s_rx_chan), err, TAG, "I2S enabling failed"); + } + + audio_codec_i2s_cfg_t i2s_cfg = { + .port = CONFIG_BSP_I2S_NUM, + .rx_handle = i2s_rx_chan, + .tx_handle = i2s_tx_chan, + }; + i2s_data_if = audio_codec_new_i2s_data(&i2s_cfg); + BSP_NULL_CHECK_GOTO(i2s_data_if, err); + + return ESP_OK; + +err: + if (i2s_tx_chan) { + i2s_del_channel(i2s_tx_chan); + } + if (i2s_rx_chan) { + i2s_del_channel(i2s_rx_chan); + } + + return ret; +} + +const audio_codec_data_if_t *bsp_audio_get_codec_itf(void) +{ + return i2s_data_if; +} + +esp_err_t bsp_adc_initialize(void) +{ + /* ADC was initialized before */ + if (bsp_adc_handle != NULL) { + return ESP_OK; + } + + /* Initialize ADC */ + const adc_oneshot_unit_init_cfg_t init_config1 = { + .unit_id = BSP_ADC_UNIT, + }; + BSP_ERROR_CHECK_RETURN_ERR(adc_oneshot_new_unit(&init_config1, &bsp_adc_handle)); + + return ESP_OK; +} + +adc_oneshot_unit_handle_t bsp_adc_get_handle(void) +{ + return bsp_adc_handle; +} + +esp_err_t bsp_voltage_init(void) +{ + /* Initialize ADC and get ADC handle */ + BSP_ERROR_CHECK_RETURN_NULL(bsp_adc_initialize()); + + /* Init ADC1 channels */ + const adc_oneshot_chan_cfg_t config = { + .bitwidth = ADC_BITWIDTH_DEFAULT, + .atten = ADC_ATTEN_DB_11, + }; + BSP_ERROR_CHECK_RETURN_ERR(adc_oneshot_config_channel(bsp_adc_handle, ADC_CHANNEL_5, &config)); + + /* ESP32-S3 supports Curve Fitting calibration scheme */ + const adc_cali_curve_fitting_config_t cali_config = { + .unit_id = ADC_UNIT_1, + .atten = ADC_ATTEN_DB_11, + .bitwidth = ADC_BITWIDTH_DEFAULT, + }; + BSP_ERROR_CHECK_RETURN_ERR(adc_cali_create_scheme_curve_fitting(&cali_config, &bsp_adc_cali_handle)); + return ESP_OK; +} + +int bsp_voltage_battery_get(void) +{ + int voltage, adc_raw; + + assert(bsp_adc_handle); + BSP_ERROR_CHECK(adc_oneshot_read(bsp_adc_handle, ADC_CHANNEL_5, &adc_raw), -1); + BSP_ERROR_CHECK(adc_cali_raw_to_voltage(bsp_adc_cali_handle, adc_raw, &voltage), -1); + return voltage * BSP_BATTERY_VOLTAGE_DIV; +} diff --git a/esp32_s3_korvo_2/idf_component.yml b/esp32_s3_korvo_2/idf_component.yml index 6b7a1850..379cde62 100644 --- a/esp32_s3_korvo_2/idf_component.yml +++ b/esp32_s3_korvo_2/idf_component.yml @@ -1,4 +1,4 @@ -version: "2.0.1" +version: "2.1.0" description: Board Support Package for ESP32-S3-Korvo-2 url: https://github.com/espressif/esp-bsp/tree/master/esp32_s3_korvo_2 @@ -6,7 +6,7 @@ targets: - esp32s3 dependencies: - idf: ">=5.0" + idf: ">=4.4.5" esp_lcd_ili9341: "^1" esp_lcd_touch_tt21100: "^1" diff --git a/esp32_s3_korvo_2/include/bsp/esp32_s3_korvo_2.h b/esp32_s3_korvo_2/include/bsp/esp32_s3_korvo_2.h index 845bbc61..4d6336e5 100644 --- a/esp32_s3_korvo_2/include/bsp/esp32_s3_korvo_2.h +++ b/esp32_s3_korvo_2/include/bsp/esp32_s3_korvo_2.h @@ -9,13 +9,19 @@ #include "sdkconfig.h" #include "driver/gpio.h" #include "driver/i2c.h" -#include "driver/i2s_std.h" #include "driver/sdmmc_host.h" #include "soc/usb_pins.h" #include "iot_button.h" #include "esp_io_expander.h" #include "esp_codec_dev.h" #include "lvgl.h" +#include "esp_lvgl_port.h" + +#if ESP_IDF_VERSION < ESP_IDF_VERSION_VAL(5, 0, 0) +#include "driver/i2s.h" +#else +#include "driver/i2s_std.h" +#endif /************************************************************************************************** * Board pinout @@ -80,6 +86,14 @@ typedef enum bsp_led_t { extern "C" { #endif +/** + * @brief BSP display configuration structure + * + */ +typedef struct { + lvgl_port_cfg_t lvgl_port_cfg; +} bsp_display_cfg_t; + /************************************************************************************************** * * Buttons interface @@ -163,6 +177,36 @@ esp_err_t bsp_iot_button_create(button_handle_t btn_array[], int *btn_cnt, int b * \endcode **************************************************************************************************/ +/** + * @brief Init audio + * + * @note There is no deinit audio function. Users can free audio resources by calling i2s_del_channel() + * @warning The type of i2s_config param is depending on IDF version. + * @param[in] i2s_config I2S configuration. Pass NULL to use default values (Mono, duplex, 16bit, 22050 Hz) + * @param[out] tx_channel I2S TX channel + * @param[out] rx_channel I2S RX channel + * @return + * - ESP_OK On success + * - ESP_ERR_NOT_SUPPORTED The communication mode is not supported on the current chip + * - ESP_ERR_INVALID_ARG NULL pointer or invalid configuration + * - ESP_ERR_NOT_FOUND No available I2S channel found + * - ESP_ERR_NO_MEM No memory for storing the channel information + * - ESP_ERR_INVALID_STATE This channel has not initialized or already started + */ +#if ESP_IDF_VERSION < ESP_IDF_VERSION_VAL(5, 0, 0) +esp_err_t bsp_audio_init(const i2s_config_t *i2s_config); +#else +esp_err_t bsp_audio_init(const i2s_std_config_t *i2s_config); +#endif + +/** + * @brief Get codec I2S interface (initialized in bsp_audio_init) + * + * @return + * - Pointer to codec I2S interface handle or NULL when error occured + */ +const audio_codec_data_if_t *bsp_audio_get_codec_itf(void); + /** * @brief Initialize speaker codec device * @@ -290,7 +334,7 @@ esp_io_expander_handle_t bsp_io_expander_init(void); /** * @brief ESP32-S3-Korvo-2 camera default configuration * - * In this configuration we select RGB565 color format and 240x240 image size - matching the display. + * In this configuration we select RGB565 color format and 320x240 image size - matching the display. * We use double-buffering for the best performance. * Since we don't want to waste internal SRAM, we allocate the framebuffers in external PSRAM. * By setting XCLK to 16MHz, we configure the esp32-camera driver to use EDMA when accessing the PSRAM. @@ -319,7 +363,7 @@ esp_io_expander_handle_t bsp_io_expander_init(void); .ledc_timer = LEDC_TIMER_0, \ .ledc_channel = LEDC_CHANNEL_0, \ .pixel_format = PIXFORMAT_RGB565, \ - .frame_size = FRAMESIZE_240X240, \ + .frame_size = FRAMESIZE_QVGA, \ .jpeg_quality = 12, \ .fb_count = 2, \ .fb_location = CAMERA_FB_IN_PSRAM,\ @@ -337,7 +381,7 @@ esp_io_expander_handle_t bsp_io_expander_init(void); * fclose(f); * \endcode **************************************************************************************************/ -#define BSP_MOUNT_POINT CONFIG_BSP_SD_MOUNT_POINT +#define BSP_SD_MOUNT_POINT CONFIG_BSP_SD_MOUNT_POINT extern sdmmc_card_t *bsp_sdcard; /** @@ -396,6 +440,18 @@ esp_err_t bsp_sdcard_unmount(void); */ lv_disp_t *bsp_display_start(void); +/** + * @brief Initialize display + * + * This function initializes SPI, display controller and starts LVGL handling task. + * LCD backlight must be enabled separately by calling bsp_display_brightness_set() + * + * @param cfg display configuration + * + * @return Pointer to LVGL display or NULL when error occured + */ +lv_disp_t *bsp_display_start_with_config(const bsp_display_cfg_t *cfg); + /** * @brief Get pointer to input device (touch, buttons, ...) * @@ -492,6 +548,39 @@ esp_err_t bsp_leds_init(void); */ esp_err_t bsp_led_set(const bsp_led_t led_io, const bool on); +/************************************************************************************************** + * + * ADC interface + * + * There are multiple devices connected to ADC peripheral: + * - Buttons + * + * After initialization of ADC, use adc_handle when using ADC driver. + **************************************************************************************************/ + +#define BSP_ADC_UNIT ADC_UNIT_1 + +/** + * @brief Initialize ADC + * + * The ADC can be initialized inside BSP, when needed. + * + * @param[out] adc_handle Returned ADC handle + */ +esp_err_t bsp_adc_initialize(void); + + +#if ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(5, 0, 0) +/** + * @brief Get ADC handle + * + * @note This function is available only in IDF5 and higher + * + * @return ADC handle + */ +adc_oneshot_unit_handle_t bsp_adc_get_handle(void); +#endif + /************************************************************************************************** * * Voltage measurements diff --git a/esp32_s3_korvo_2/priv_include/bsp_err_check.h b/esp32_s3_korvo_2/priv_include/bsp_err_check.h index b2398acb..e0019994 100644 --- a/esp32_s3_korvo_2/priv_include/bsp_err_check.h +++ b/esp32_s3_korvo_2/priv_include/bsp_err_check.h @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -46,12 +46,6 @@ extern "C" { } \ } while(0) -#define BSP_NULL_CHECK(x, ret) do { \ - if ((x) == NULL) { \ - return ret; \ - } \ - } while(0) - #define BSP_NULL_CHECK_GOTO(x, goto_tag) do { \ if ((x) == NULL) { \ goto goto_tag; \ diff --git a/examples/audio/sdkconfig.bsp.esp32_lyrat b/examples/audio/sdkconfig.bsp.esp32_lyrat index 1ea0822d..d023f043 100644 --- a/examples/audio/sdkconfig.bsp.esp32_lyrat +++ b/examples/audio/sdkconfig.bsp.esp32_lyrat @@ -2,3 +2,15 @@ # Espressif IoT Development Framework (ESP-IDF) Project Minimal Configuration # CONFIG_IDF_TARGET="esp32" +CONFIG_ESPTOOLPY_FLASHSIZE_4MB=y +CONFIG_PARTITION_TABLE_CUSTOM=y +CONFIG_SPIRAM=y +CONFIG_SPIRAM_SPEED_80M=y +CONFIG_SPIRAM_USE_MEMMAP=y +CONFIG_SPIRAM_MODE_OCT=y +CONFIG_SPIFFS_PAGE_SIZE=1024 +CONFIG_LV_COLOR_16_SWAP=y +CONFIG_LV_MEM_CUSTOM=y +CONFIG_LV_MEMCPY_MEMSET_STD=y +CONFIG_LV_USE_PERF_MONITOR=y +CONFIG_LV_SPRINTF_CUSTOM=y diff --git a/examples/audio/sdkconfig.bsp.esp32_s3_korvo_2 b/examples/audio/sdkconfig.bsp.esp32_s3_korvo_2 index e9f1c7dc..d821bd83 100644 --- a/examples/audio/sdkconfig.bsp.esp32_s3_korvo_2 +++ b/examples/audio/sdkconfig.bsp.esp32_s3_korvo_2 @@ -2,3 +2,15 @@ # Espressif IoT Development Framework (ESP-IDF) Project Minimal Configuration # CONFIG_IDF_TARGET="esp32s3" +CONFIG_ESPTOOLPY_FLASHSIZE_4MB=y +CONFIG_PARTITION_TABLE_CUSTOM=y +CONFIG_SPIRAM=y +CONFIG_SPIRAM_SPEED_80M=y +CONFIG_SPIRAM_USE_MEMMAP=y +CONFIG_SPIRAM_MODE_OCT=y +CONFIG_SPIFFS_PAGE_SIZE=1024 +CONFIG_LV_COLOR_16_SWAP=y +CONFIG_LV_MEM_CUSTOM=y +CONFIG_LV_MEMCPY_MEMSET_STD=y +CONFIG_LV_USE_PERF_MONITOR=y +CONFIG_LV_SPRINTF_CUSTOM=y diff --git a/examples/display_audio_photo/sdkconfig.bsp.esp32_s3_korvo_2 b/examples/display_audio_photo/sdkconfig.bsp.esp32_s3_korvo_2 new file mode 100644 index 00000000..89fdc414 --- /dev/null +++ b/examples/display_audio_photo/sdkconfig.bsp.esp32_s3_korvo_2 @@ -0,0 +1,18 @@ +# This file was generated using idf.py save-defconfig. It can be edited manually. +# Espressif IoT Development Framework (ESP-IDF) Project Minimal Configuration +# +CONFIG_IDF_TARGET="esp32s3" +CONFIG_ESPTOOLPY_FLASHMODE_QIO=y +CONFIG_ESPTOOLPY_FLASHSIZE_16MB=y +CONFIG_PARTITION_TABLE_CUSTOM=y +CONFIG_SPIRAM=y +CONFIG_SPIRAM_MODE_OCT=y +CONFIG_SPIRAM_SPEED_80M=y +CONFIG_ESP_DEFAULT_CPU_FREQ_MHZ_240=y +CONFIG_SPIFFS_PAGE_SIZE=1024 +CONFIG_LV_COLOR_16_SWAP=y +CONFIG_LV_MEM_CUSTOM=y +CONFIG_LV_MEMCPY_MEMSET_STD=y +CONFIG_LV_USE_PERF_MONITOR=y +CONFIG_LV_SPRINTF_CUSTOM=y +# CONFIG_LV_BUILD_EXAMPLES is not set diff --git a/examples/display_camera/sdkconfig.bsp.esp32_s3_korvo_2 b/examples/display_camera/sdkconfig.bsp.esp32_s3_korvo_2 index 869e8ca2..ec2fa94c 100644 --- a/examples/display_camera/sdkconfig.bsp.esp32_s3_korvo_2 +++ b/examples/display_camera/sdkconfig.bsp.esp32_s3_korvo_2 @@ -2,15 +2,19 @@ # Espressif IoT Development Framework (ESP-IDF) Project Minimal Configuration # CONFIG_IDF_TARGET="esp32s3" +CONFIG_ESPTOOLPY_FLASHMODE_QIO=y CONFIG_ESPTOOLPY_FLASHSIZE_4MB=y CONFIG_ESP_DEFAULT_CPU_FREQ_240=y CONFIG_SPIRAM=y +CONFIG_ESP32S3_SPIRAM_SUPPORT=y CONFIG_SPIRAM_MODE_OCT=y -CONFIG_SPIRAM_FETCH_INSTRUCTIONS=y CONFIG_SPIRAM_SPEED_80M=y +CONFIG_SPIRAM_TRY_ALLOCATE_WIFI_LWIP=y +CONFIG_SPIRAM_MALLOC_RESERVE_INTERNAL=8192 +CONFIG_SPIRAM_ALLOW_BSS_SEG_EXTERNAL_MEMORY=y CONFIG_LV_COLOR_16_SWAP=y CONFIG_LV_MEM_CUSTOM=y CONFIG_LV_MEMCPY_MEMSET_STD=y CONFIG_LV_USE_PERF_MONITOR=y CONFIG_LV_SPRINTF_CUSTOM=y -# CONFIG_LV_BUILD_EXAMPLES is not set +# CONFIG_LV_BUILD_EXAMPLES is not set \ No newline at end of file