Skip to content

Commit

Permalink
Merge pull request #282 from pborcin/feature/s3korvo1_audio
Browse files Browse the repository at this point in the history
add esp32-s3-korvo-1 audio and sd card (BSP-446)
  • Loading branch information
tore-espressif authored Feb 29, 2024
2 parents 6606077 + 7606674 commit 5cd8d43
Show file tree
Hide file tree
Showing 9 changed files with 649 additions and 11 deletions.
4 changes: 2 additions & 2 deletions bsp/esp32_s3_korvo_1/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
#IDF version is less than IDF5.0
if("${IDF_VERSION_MAJOR}.${IDF_VERSION_MINOR}" VERSION_LESS "5.0")
set(SRC_VER "esp32_s3_korvo_1_idf4.c")
set(REQ spiffs)
set(REQ driver spiffs fatfs)
else()
set(SRC_VER "esp32_s3_korvo_1_idf5.c")
set(REQ spiffs esp_adc)
set(REQ driver spiffs fatfs esp_adc)
endif()

idf_component_register(
Expand Down
40 changes: 40 additions & 0 deletions bsp/esp32_s3_korvo_1/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,46 @@ menu "Board Support Package"
help
Error check assert the application before returning the error code.

menu "I2C"
config BSP_I2C_NUM
int "I2C peripheral index"
default 0
range 0 1
help
ESP32S3 has two I2C peripherals, pick the one you want to use.

config BSP_I2C_FAST_MODE
bool "Enable I2C fast mode"
default y
help
I2C has two speed modes: normal (100kHz) and fast (400kHz).

config BSP_I2C_CLK_SPEED_HZ
int
default 400000 if BSP_I2C_FAST_MODE
default 100000
endmenu

menu "uSD card - Virtual File System"
config BSP_SD_FORMAT_ON_MOUNT_FAIL
bool "Format uSD card if mounting fails"
default n
help
The SDMMC host will format (FAT) the uSD card if it fails to mount the filesystem.

config BSP_SD_MOUNT_POINT
string "uSD card mount point"
default "/sdcard"
help
Mount point of the uSD card in the Virtual File System

config BSP_SD_MAX_FILES
int "Max files supported for SD VFS"
default 2
help
Supported max files for SD in the Virtual File System.
endmenu

menu "SPIFFS - Virtual File System"
config BSP_SPIFFS_FORMAT_ON_MOUNT_FAIL
bool "Format SPIFFS if mounting fails"
Expand Down
1 change: 1 addition & 0 deletions bsp/esp32_s3_korvo_1/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ The ESP32-S3-Korvo-1 board consists of two parts: the main board (ESP32-S3-Korvo
| component | version |
|----------------------------------------------------------------------------------------------|-----------|
| [espressif/button](https://components.espressif.com/components/espressif/button) | >=2.5,<4.0|
|[espressif/esp_codec_dev](https://components.espressif.com/components/espressif/esp_codec_dev)| ~1.1.0 |
|[espressif/led_indicator](https://components.espressif.com/components/espressif/led_indicator)|>=0.7,<=0.8|
| idf | >=4.4 |
<!-- Autogenerated end: Dependencies -->
163 changes: 162 additions & 1 deletion bsp/esp32_s3_korvo_1/esp32_s3_korvo_1.c
Original file line number Diff line number Diff line change
@@ -1,20 +1,143 @@
/*
* SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD
* SPDX-FileCopyrightText: 2023-2024 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/

#include "driver/gpio.h"
#include "driver/spi_master.h"
#include "driver/i2c.h"
#include "esp_err.h"
#include "esp_log.h"

#include "iot_button.h"
#include "bsp/esp-bsp.h"
#include "bsp_err_check.h"
#include "esp_spiffs.h"
#include "esp_codec_dev.h"
#include "esp_codec_dev_defaults.h"
#include "led_indicator.h"
#include "esp_vfs_fat.h"

static const char *TAG = "S3-Korvo-1";

static bool i2c_initialized = false;
sdmmc_card_t *bsp_sdcard = NULL; // Global uSD card handler

esp_err_t bsp_i2c_init(void)
{
/* I2C was initialized before */
if (i2c_initialized) {
return ESP_OK;
}

const i2c_config_t i2c_conf = {
.mode = I2C_MODE_MASTER,
.sda_io_num = BSP_I2C_SDA,
.sda_pullup_en = GPIO_PULLUP_ENABLE,
.scl_io_num = BSP_I2C_SCL,
.scl_pullup_en = GPIO_PULLUP_ENABLE,
.master.clk_speed = CONFIG_BSP_I2C_CLK_SPEED_HZ
};
BSP_ERROR_CHECK_RETURN_ERR(i2c_param_config(BSP_I2C_NUM, &i2c_conf));
BSP_ERROR_CHECK_RETURN_ERR(i2c_driver_install(BSP_I2C_NUM, i2c_conf.mode, 0, 0, 0));

i2c_initialized = true;

return ESP_OK;
}

esp_err_t bsp_i2c_deinit(void)
{
BSP_ERROR_CHECK_RETURN_ERR(i2c_driver_delete(BSP_I2C_NUM));
i2c_initialized = false;
return ESP_OK;
}

esp_codec_dev_handle_t bsp_audio_codec_speaker_init(void)
{
const audio_codec_data_if_t *i2s_data_if = bsp_audio_get_codec_itf_spk();
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_spk();
}
assert(i2s_data_if);

const audio_codec_gpio_if_t *gpio_if = audio_codec_new_gpio();

audio_codec_i2c_cfg_t i2c_cfg = {
.port = BSP_I2C_NUM,
.addr = ES8311_CODEC_DEFAULT_ADDR,
};
const audio_codec_ctrl_if_t *i2c_ctrl_if = audio_codec_new_i2c_ctrl(&i2c_cfg);
BSP_NULL_CHECK(i2c_ctrl_if, NULL);

esp_codec_dev_hw_gain_t gain = {
.pa_voltage = 5.0,
.codec_dac_voltage = 3.3,
};

es8311_codec_cfg_t es8311_cfg = {
.ctrl_if = i2c_ctrl_if,
.gpio_if = gpio_if,
.codec_mode = ESP_CODEC_DEV_WORK_MODE_DAC,
.pa_pin = BSP_POWER_AMP_IO,
.pa_reverted = false,
.master_mode = false,
.use_mclk = false,
.digital_mic = false,
.invert_mclk = false,
.invert_sclk = false,
.hw_gain = gain,
};
const audio_codec_if_t *es8311_dev = es8311_codec_new(&es8311_cfg);
BSP_NULL_CHECK(es8311_dev, NULL);

esp_codec_dev_cfg_t codec_dev_cfg = {
.dev_type = ESP_CODEC_DEV_TYPE_OUT,
.codec_if = es8311_dev,
.data_if = i2s_data_if,
};
return esp_codec_dev_new(&codec_dev_cfg);
}

esp_codec_dev_handle_t bsp_audio_codec_microphone_init(void)
{
const audio_codec_data_if_t *i2s_data_if = bsp_audio_get_codec_itf_mic();
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_mic();
}
assert(i2s_data_if);

audio_codec_i2c_cfg_t i2c_cfg = {
.port = BSP_I2C_NUM,
.addr = ES7210_CODEC_DEFAULT_ADDR,
};
const audio_codec_ctrl_if_t *i2c_ctrl_if = audio_codec_new_i2c_ctrl(&i2c_cfg);
BSP_NULL_CHECK(i2c_ctrl_if, NULL);

es7210_codec_cfg_t es7210_cfg = {
.ctrl_if = i2c_ctrl_if,
.mic_selected = ES7120_SEL_MIC1 | ES7120_SEL_MIC2,
};
const audio_codec_if_t *es7210_dev = es7210_codec_new(&es7210_cfg);
BSP_NULL_CHECK(es7210_dev, NULL);

esp_codec_dev_cfg_t codec_es7210_dev_cfg = {
.dev_type = ESP_CODEC_DEV_TYPE_IN,
.codec_if = es7210_dev,
.data_if = i2s_data_if,
};
return esp_codec_dev_new(&codec_es7210_dev_cfg);
}

/**
* @brief led configuration structure
*
Expand Down Expand Up @@ -196,3 +319,41 @@ esp_err_t bsp_spiffs_unmount(void)
{
return esp_vfs_spiffs_unregister(CONFIG_BSP_SPIFFS_PARTITION_LABEL);
}

esp_err_t bsp_sdcard_mount(void)
{
const esp_vfs_fat_sdmmc_mount_config_t mount_config = {
#ifdef CONFIG_BSP_SD_FORMAT_ON_MOUNT_FAIL
.format_if_mount_failed = true,
#else
.format_if_mount_failed = false,
#endif
.max_files = CONFIG_BSP_SD_MAX_FILES,
.allocation_unit_size = 16 * 1024
};

const sdmmc_host_t host = SDMMC_HOST_DEFAULT();
const sdmmc_slot_config_t slot_config = {
.clk = BSP_SD_CLK,
.cmd = BSP_SD_CMD,
.d0 = BSP_SD_D0,
.d1 = GPIO_NUM_NC,
.d2 = GPIO_NUM_NC,
.d3 = GPIO_NUM_NC,
.d4 = GPIO_NUM_NC,
.d5 = GPIO_NUM_NC,
.d6 = GPIO_NUM_NC,
.d7 = GPIO_NUM_NC,
.cd = SDMMC_SLOT_NO_CD,
.wp = SDMMC_SLOT_NO_WP,
.width = 1,
.flags = 0,
};

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_SD_MOUNT_POINT, bsp_sdcard);
}
109 changes: 108 additions & 1 deletion bsp/esp32_s3_korvo_1/esp32_s3_korvo_1_idf4.c
Original file line number Diff line number Diff line change
@@ -1,16 +1,123 @@
/*
* SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD
* SPDX-FileCopyrightText: 2023-2024 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/

#include "esp_err.h"
#include "bsp/esp32_s3_korvo_1.h"
#include "bsp_err_check.h"
#include "driver/adc.h"
#include "hal/i2s_types.h"
#include "esp_adc_cal.h"
#include "esp_codec_dev_defaults.h"

static const char *TAG = "S3-Korvo-1";

#define BSP_I2S0_SIMPLEX_MONO_CFG(_sample_rate) \
{ \
.mode = I2S_MODE_MASTER | I2S_MODE_TX, \
.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, \
.tx_desc_auto_clear = true, \
.intr_alloc_flags = ESP_INTR_FLAG_LEVEL2 | ESP_INTR_FLAG_IRAM \
}

/* This board has 3 microphones, therefore using I2S TDM mode, it allows using more than 2 channels */
#define BSP_I2S1_CFG(_sample_rate) \
{ \
.mode = I2S_MODE_MASTER | I2S_MODE_RX, \
.sample_rate = _sample_rate, \
.bits_per_sample = I2S_BITS_PER_SAMPLE_16BIT, \
.channel_format = I2S_CHANNEL_FMT_MULTIPLE, \
.communication_format = I2S_COMM_FORMAT_STAND_I2S, \
.dma_buf_count = 6, \
.dma_buf_len = 1024, \
.chan_mask = I2S_TDM_ACTIVE_CH0 | I2S_TDM_ACTIVE_CH1, \
.intr_alloc_flags = ESP_INTR_FLAG_LEVEL2 | ESP_INTR_FLAG_IRAM \
}

static const audio_codec_data_if_t *i2s_data_if_spk = NULL; /* Codec data interface */
static const audio_codec_data_if_t *i2s_data_if_mic = 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_spk != NULL) {
/* Audio was initialized before */
return ESP_OK;
}

/* Setup I2S peripheral */
const i2s_pin_config_t i2s_pin_config_spk = {
.mck_io_num = BSP_I2S0_MCLK,
.bck_io_num = BSP_I2S0_SCLK,
.ws_io_num = BSP_I2S0_LCLK,
.data_out_num = BSP_I2S0_DOUT,
.data_in_num = BSP_I2S0_DSIN
};

const i2s_pin_config_t i2s_pin_config_mic = {
.mck_io_num = BSP_I2S1_MCLK,
.bck_io_num = BSP_I2S1_SCLK,
.ws_io_num = BSP_I2S1_LCLK,
.data_out_num = BSP_I2S1_DOUT,
.data_in_num = BSP_I2S1_DSIN
};

/* Setup I2S channels */

/* I2S_NUM_0 */
const i2s_config_t std_cfg_default = BSP_I2S0_SIMPLEX_MONO_CFG(16000);
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(I2S_NUM_0, p_i2s_cfg, 0, NULL));
ESP_GOTO_ON_ERROR(i2s_set_pin(I2S_NUM_0, &i2s_pin_config_spk), err, TAG, "I2S set pin failed");

audio_codec_i2s_cfg_t i2s_cfg_spk = {
.port = I2S_NUM_0,
};
i2s_data_if_spk = audio_codec_new_i2s_data(&i2s_cfg_spk);
BSP_NULL_CHECK_GOTO(i2s_data_if_spk, err);

/* I2S_NUM_1 */
const i2s_config_t tdm_cfg_default = BSP_I2S1_CFG(16000);
ESP_ERROR_CHECK(i2s_driver_install(I2S_NUM_1, &tdm_cfg_default, 0, NULL));
ESP_GOTO_ON_ERROR(i2s_set_pin(I2S_NUM_1, &i2s_pin_config_mic), err, TAG, "I2S set pin failed");

audio_codec_i2s_cfg_t i2s_cfg_mic = {
.port = I2S_NUM_1,
};
i2s_data_if_mic = audio_codec_new_i2s_data(&i2s_cfg_mic);
BSP_NULL_CHECK_GOTO(i2s_data_if_mic, err);

return ESP_OK;

err:
i2s_driver_uninstall(I2S_NUM_0);
i2s_driver_uninstall(I2S_NUM_1);
return ret;
}

const audio_codec_data_if_t *bsp_audio_get_codec_itf_spk(void)
{
return i2s_data_if_spk;
}

const audio_codec_data_if_t *bsp_audio_get_codec_itf_mic(void)
{
return i2s_data_if_mic;
}

esp_err_t bsp_adc_initialize(void)
{
esp_err_t ret = ESP_OK;
Expand Down
Loading

0 comments on commit 5cd8d43

Please sign in to comment.