Skip to content

Commit

Permalink
bsp: Added support for IDF v4.4 into ESP-BOX
Browse files Browse the repository at this point in the history
  • Loading branch information
espzav committed Jul 24, 2023
1 parent 1452b26 commit d4ab850
Show file tree
Hide file tree
Showing 13 changed files with 366 additions and 133 deletions.
4 changes: 4 additions & 0 deletions .build-test-rules.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
examples:
disable:
- if: IDF_VERSION_MAJOR < 5 and CONFIG_NAME not in ["esp-box"]
reason: Example depends on BSP, which is supported only for IDF >= 5.0
2 changes: 2 additions & 0 deletions .github/PULL_REQUEST_TEMPLATE/pr_template_bsp.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@
- [ ] Component was added to CI [upload job](https://github.com/espressif/esp-bsp/blob/master/.github/workflows/upload_component.yml#L17)
- [ ] New files were added to CI build job
- [ ] New BSP definitions added to [bsp_ext.py](../examples/bsp_ext.py)
- [ ] BSP was [added to SquareLine](https://github.com/espressif/esp-bsp/tree/master/SquareLine/common)
- [ ] New BSP supports IDF v4.4.x and later releases
- [ ] _Optional:_ Component contains unit tests
- [ ] CI passing

Expand Down
23 changes: 20 additions & 3 deletions .github/workflows/build_example.yml
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,25 @@ jobs:
build:
strategy:
matrix:
idf_ver: ["latest"]
parallel_index: [1,2,3,4,5] # This must be from 1 to 'parallel_count' defined in .idf_build_apps.toml
include:
- idf_ver: "latest"
parallel_count: 5
parallel_index: 1
- idf_ver: "latest"
parallel_count: 5
parallel_index: 2
- idf_ver: "latest"
parallel_count: 5
parallel_index: 3
- idf_ver: "latest"
parallel_count: 5
parallel_index: 4
- idf_ver: "latest"
parallel_count: 5
parallel_index: 5
- idf_ver: "release-v4.4"
parallel_count: 1
parallel_index: 1
runs-on: ubuntu-20.04
container: espressif/idf:${{ matrix.idf_ver }}
steps:
Expand All @@ -23,4 +40,4 @@ jobs:
. ${IDF_PATH}/export.sh
pip install idf-component-manager ruamel.yaml idf-build-apps --upgrade
idf-build-apps find
idf-build-apps build --parallel-index ${{ matrix.parallel_index }}
idf-build-apps build --parallel-count ${{ matrix.parallel_count }} --parallel-index ${{ matrix.parallel_index }}
2 changes: 1 addition & 1 deletion .idf_build_apps.toml
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
target = "all"
paths = "examples"
recursive = true
manifest_file = ".build-test-rules.yml"
check_warnings = true
ignore_warning_file = ".ignore_build_warnings.txt"
config = "sdkconfig.bsp.*"

# build related options
build_dir = "build_@w"
parallel_count = 5
9 changes: 8 additions & 1 deletion esp-box/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,5 +1,12 @@
#IDF version is less than IDF5.0
if("${IDF_VERSION_MAJOR}.${IDF_VERSION_MINOR}" VERSION_LESS "5.0")
set(SRC_VER "esp-box_idf4.c")
else()
set(SRC_VER "esp-box_idf5.c")
endif()

idf_component_register(
SRCS "esp-box.c"
SRCS "esp-box.c" ${SRC_VER}
INCLUDE_DIRS "include"
PRIV_INCLUDE_DIRS "priv_include"
REQUIRES driver spiffs
Expand Down
179 changes: 104 additions & 75 deletions esp-box/esp-box.c
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
#include "esp_lcd_panel_vendor.h"
#include "esp_lcd_panel_ops.h"

#include "iot_button.h"
#include "bsp/esp-box.h"
#include "bsp/display.h"
#include "bsp/touch.h"
Expand All @@ -32,9 +33,31 @@ _Static_assert(CONFIG_ESP_LCD_TOUCH_MAX_BUTTONS > 0, "Touch buttons must be supp
static lv_disp_t *disp;
static lv_indev_t *disp_indev = NULL;
static esp_lcd_touch_handle_t tp; // LCD touch handle
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;

// This is just a wrapper to get function signature for espressif/button API callback
static uint8_t bsp_get_main_button(void *param);
static esp_err_t bsp_init_main_button(void *param);

static const button_config_t bsp_button_config[BSP_BUTTON_NUM] = {
{
.type = BUTTON_TYPE_GPIO,
.gpio_button_config.gpio_num = BSP_BUTTON_CONFIG_IO,
.gpio_button_config.active_level = 0,
},
{
.type = BUTTON_TYPE_GPIO,
.gpio_button_config.gpio_num = BSP_BUTTON_MUTE_IO,
.gpio_button_config.active_level = 0,
},
{
.type = BUTTON_TYPE_CUSTOM,
.custom_button_config.button_custom_init = bsp_init_main_button,
.custom_button_config.button_custom_get_key_value = bsp_get_main_button,
.custom_button_config.button_custom_deinit = NULL,
.custom_button_config.active_level = 1,
.custom_button_config.priv = (void *) BSP_BUTTON_MAIN,
}
};

esp_err_t bsp_i2c_init(void)
{
Expand Down Expand Up @@ -100,78 +123,15 @@ esp_err_t bsp_spiffs_unmount(void)
return esp_vfs_spiffs_unregister(CONFIG_BSP_SPIFFS_PARTITION_LABEL);
}


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)
{
if (i2s_tx_chan && i2s_rx_chan && i2s_data_if) {
if (tx_channel) {
*tx_channel = i2s_tx_chan;
}
if (rx_channel) {
*rx_channel = 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, 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, NULL);

/* Setup power amplifier pin */
const gpio_config_t io_conf = {
.intr_type = GPIO_INTR_DISABLE,
.mode = GPIO_MODE_OUTPUT,
.pin_bit_mask = BIT64(BSP_POWER_AMP_IO),
.pull_down_en = GPIO_PULLDOWN_DISABLE,
.pull_up_en = GPIO_PULLDOWN_DISABLE,
};
BSP_ERROR_CHECK_RETURN_ERR(gpio_config(&io_conf));

return ESP_OK;
}

esp_err_t bsp_audio_poweramp_enable(bool enable)
{
BSP_ERROR_CHECK_RETURN_ERR(gpio_set_level(BSP_POWER_AMP_IO, enable ? 1 : 0));

return ESP_OK;
}

esp_codec_dev_handle_t bsp_audio_codec_speaker_init(void)
{
if (i2s_tx_chan == NULL || i2s_rx_chan == NULL || i2s_data_if == NULL) {
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_ERR(bsp_i2c_init());
/* Configure I2S peripheral and Power Amplifier */
BSP_ERROR_CHECK_RETURN_ERR(bsp_audio_init(NULL, &i2s_tx_chan, &i2s_rx_chan));
BSP_ERROR_CHECK_RETURN_ERR(bsp_audio_poweramp_enable(true));
BSP_ERROR_CHECK_RETURN_ERR(bsp_audio_init(NULL));
i2s_data_if = bsp_audio_get_codec_itf();
}
assert(i2s_data_if);

Expand Down Expand Up @@ -215,12 +175,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) {
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_ERR(bsp_i2c_init());
/* Configure I2S peripheral and Power Amplifier */
BSP_ERROR_CHECK_RETURN_ERR(bsp_audio_init(NULL, &i2s_tx_chan, &i2s_rx_chan));
BSP_ERROR_CHECK_RETURN_ERR(bsp_audio_poweramp_enable(true));
BSP_ERROR_CHECK_RETURN_ERR(bsp_audio_init(NULL));
i2s_data_if = bsp_audio_get_codec_itf();
}
assert(i2s_data_if);

Expand Down Expand Up @@ -471,8 +432,19 @@ void bsp_display_unlock(void)

esp_err_t bsp_button_init(const bsp_button_t btn)
{
gpio_num_t btn_io;
switch (btn) {
case BSP_BUTTON_CONFIG:
btn_io = BSP_BUTTON_CONFIG_IO;
break;
case BSP_BUTTON_MUTE:
btn_io = BSP_BUTTON_MUTE_IO;
break;
default:
return ESP_FAIL;
}
const gpio_config_t button_io_config = {
.pin_bit_mask = BIT64(btn),
.pin_bit_mask = BIT64(btn_io),
.mode = GPIO_MODE_INPUT,
.pull_up_en = GPIO_PULLUP_DISABLE,
.pull_down_en = GPIO_PULLDOWN_DISABLE,
Expand All @@ -495,6 +467,63 @@ bool bsp_button_get(const bsp_button_t btn)
return false;
#endif
} else {
return !(bool)gpio_get_level(btn);
gpio_num_t btn_io;
switch (btn) {
case BSP_BUTTON_CONFIG:
btn_io = BSP_BUTTON_CONFIG_IO;
break;
case BSP_BUTTON_MUTE:
btn_io = BSP_BUTTON_MUTE_IO;
break;
default:
return ESP_FAIL;
}
return !(bool)gpio_get_level(btn_io);
}
}

static uint8_t bsp_get_main_button(void *param)
{
assert(tp);
ESP_ERROR_CHECK(esp_lcd_touch_read_data(tp));
#if (CONFIG_ESP_LCD_TOUCH_MAX_BUTTONS > 0)
uint8_t home_btn_val = 0x00;
esp_lcd_touch_get_button_state(tp, 0, &home_btn_val);
return home_btn_val ? true : false;
#else
ESP_LOGE(TAG, "Button main is inaccessible");
return false;
#endif
}

static esp_err_t bsp_init_main_button(void *param)
{
if (tp == NULL) {
BSP_ERROR_CHECK_RETURN_ERR(bsp_touch_new(NULL, &tp));
}
return ESP_OK;
}

esp_err_t bsp_iot_button_create(button_handle_t btn_array[], int *btn_cnt, int btn_array_size)
{
esp_err_t ret = ESP_OK;
if ((btn_array_size < BSP_BUTTON_NUM) ||
(btn_array == NULL)) {
return ESP_ERR_INVALID_ARG;
}

if (btn_cnt) {
*btn_cnt = 0;
}
for (int i = 0; i < BSP_BUTTON_NUM; i++) {
btn_array[i] = iot_button_create(&bsp_button_config[i]);
if (btn_array[i] == NULL) {
ret = ESP_FAIL;
break;
}
if (btn_cnt) {
(*btn_cnt)++;
}
}
return ret;
}
75 changes: 75 additions & 0 deletions esp-box/esp-box_idf4.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
/*
* SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/

#include "esp_err.h"
#include "bsp/esp-box.h"
#include "bsp_err_check.h"
#include "esp_codec_dev_defaults.h"

static const char *TAG = "ESP-BOX";

/* 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 */

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;
}
Loading

0 comments on commit d4ab850

Please sign in to comment.