feat: adapt to esp_codec_dev>=1.5.5 (#1878)

* feat: adapt to esp_codec_dev>=1.5.5

* fix: fix board config resolution in release script
This commit is contained in:
laride
2026-03-26 23:56:45 +08:00
committed by GitHub
parent 6d51b9dbde
commit 0f3199a812
7 changed files with 142 additions and 44 deletions

View File

@ -20,7 +20,7 @@ jobs:
variants: ${{ steps.select.outputs.variants }} variants: ${{ steps.select.outputs.variants }}
steps: steps:
- name: Checkout - name: Checkout
uses: actions/checkout@v4 uses: actions/checkout@v6
with: with:
fetch-depth: 0 fetch-depth: 0

View File

@ -5,7 +5,6 @@
#include <driver/i2c.h> #include <driver/i2c.h>
#include <driver/i2c_master.h> #include <driver/i2c_master.h>
#include <driver/i2s_tdm.h> #include <driver/i2s_tdm.h>
#include "adc_mic.h"
#include "driver/i2s_pdm.h" #include "driver/i2s_pdm.h"
#include "soc/gpio_sig_map.h" #include "soc/gpio_sig_map.h"
#include "soc/io_mux_reg.h" #include "soc/io_mux_reg.h"
@ -44,18 +43,19 @@ AdcPdmAudioCodec::AdcPdmAudioCodec(int input_sample_rate, int output_sample_rate
input_sample_rate_ = input_sample_rate; input_sample_rate_ = input_sample_rate;
output_sample_rate_ = output_sample_rate; output_sample_rate_ = output_sample_rate;
uint8_t adc_channel[1] = {0}; audio_codec_adc_cfg_t cfg = {};
adc_channel[0] = adc_mic_channel; cfg.handle = NULL;
cfg.continuous_cfg.max_store_buf_size = 1024 * 2;
audio_codec_adc_cfg_t cfg = { cfg.continuous_cfg.conv_frame_size = 1024;
.handle = NULL, cfg.continuous_cfg.sample_freq_hz = (uint32_t)input_sample_rate;
.max_store_buf_size = 1024 * 2, cfg.continuous_cfg.conv_mode = ADC_CONV_SINGLE_UNIT_1;
.conv_frame_size = 1024, cfg.continuous_cfg.format = ADC_DIGI_OUTPUT_FORMAT_TYPE2;
.unit_id = ADC_UNIT_1, cfg.continuous_cfg.pattern_num = 1;
.adc_channel_list = adc_channel, cfg.continuous_cfg.cfg_mode = AUDIO_CODEC_ADC_CFG_MODE_SINGLE_UNIT;
.adc_channel_num = sizeof(adc_channel) / sizeof(adc_channel[0]), cfg.continuous_cfg.cfg.single_unit.unit_id = ADC_UNIT_1;
.sample_rate_hz = (uint32_t)input_sample_rate, cfg.continuous_cfg.cfg.single_unit.atten = ADC_ATTEN_DB_12;
}; cfg.continuous_cfg.cfg.single_unit.bit_width = ADC_BITWIDTH_12;
cfg.continuous_cfg.cfg.single_unit.channel_id[0] = (uint8_t)adc_mic_channel;
const audio_codec_data_if_t *adc_if = audio_codec_new_adc_data(&cfg); const audio_codec_data_if_t *adc_if = audio_codec_new_adc_data(&cfg);
esp_codec_dev_cfg_t codec_dev_cfg = { esp_codec_dev_cfg_t codec_dev_cfg = {

View File

@ -26,7 +26,8 @@
"CONFIG_NEWLIB_NANO_FORMAT=y", "CONFIG_NEWLIB_NANO_FORMAT=y",
"CONFIG_ESP_CONSOLE_NONE=y", "CONFIG_ESP_CONSOLE_NONE=y",
"CONFIG_USE_ESP_WAKE_WORD=y", "CONFIG_USE_ESP_WAKE_WORD=y",
"CONFIG_COMPILER_OPTIMIZATION_SIZE=y" "CONFIG_COMPILER_OPTIMIZATION_SIZE=y",
"CONFIG_CODEC_DATA_ADC_SUPPORT=y"
] ]
} }
] ]

View File

@ -5,7 +5,6 @@
#include <driver/i2c.h> #include <driver/i2c.h>
#include <driver/i2c_master.h> #include <driver/i2c_master.h>
#include <driver/i2s_tdm.h> #include <driver/i2s_tdm.h>
#include "adc_mic.h"
#include "driver/i2s_pdm.h" #include "driver/i2s_pdm.h"
#include "soc/gpio_sig_map.h" #include "soc/gpio_sig_map.h"
#include "soc/io_mux_reg.h" #include "soc/io_mux_reg.h"
@ -44,18 +43,19 @@ AdcPdmAudioCodec::AdcPdmAudioCodec(int input_sample_rate, int output_sample_rate
input_sample_rate_ = input_sample_rate; input_sample_rate_ = input_sample_rate;
output_sample_rate_ = output_sample_rate; output_sample_rate_ = output_sample_rate;
uint8_t adc_channel[1] = {0}; audio_codec_adc_cfg_t cfg = {};
adc_channel[0] = adc_mic_channel; cfg.handle = NULL;
cfg.continuous_cfg.max_store_buf_size = 1024 * 2;
audio_codec_adc_cfg_t cfg = { cfg.continuous_cfg.conv_frame_size = 1024;
.handle = NULL, cfg.continuous_cfg.sample_freq_hz = (uint32_t)input_sample_rate;
.max_store_buf_size = 1024 * 2, cfg.continuous_cfg.conv_mode = ADC_CONV_SINGLE_UNIT_1;
.conv_frame_size = 1024, cfg.continuous_cfg.format = ADC_DIGI_OUTPUT_FORMAT_TYPE2;
.unit_id = ADC_UNIT_1, cfg.continuous_cfg.pattern_num = 1;
.adc_channel_list = adc_channel, cfg.continuous_cfg.cfg_mode = AUDIO_CODEC_ADC_CFG_MODE_SINGLE_UNIT;
.adc_channel_num = sizeof(adc_channel) / sizeof(adc_channel[0]), cfg.continuous_cfg.cfg.single_unit.unit_id = ADC_UNIT_1;
.sample_rate_hz = (uint32_t)input_sample_rate, cfg.continuous_cfg.cfg.single_unit.atten = ADC_ATTEN_DB_12;
}; cfg.continuous_cfg.cfg.single_unit.bit_width = ADC_BITWIDTH_12;
cfg.continuous_cfg.cfg.single_unit.channel_id[0] = (uint8_t)adc_mic_channel;
const audio_codec_data_if_t *adc_if = audio_codec_new_adc_data(&cfg); const audio_codec_data_if_t *adc_if = audio_codec_new_adc_data(&cfg);
esp_codec_dev_cfg_t codec_dev_cfg = { esp_codec_dev_cfg_t codec_dev_cfg = {

View File

@ -21,7 +21,8 @@
"CONFIG_SR_WN_WN9S_HIESP=y", "CONFIG_SR_WN_WN9S_HIESP=y",
"CONFIG_USE_EMOTE_MESSAGE_STYLE=y", "CONFIG_USE_EMOTE_MESSAGE_STYLE=y",
"CONFIG_FLASH_CUSTOM_ASSETS=y", "CONFIG_FLASH_CUSTOM_ASSETS=y",
"CONFIG_CUSTOM_ASSETS_FILE=\"https://dl.espressif.com/AE/wn9_nihaoxiaozhi_tts-font_puhui_common_20_4-echoear.bin\"" "CONFIG_CUSTOM_ASSETS_FILE=\"https://dl.espressif.com/AE/wn9_nihaoxiaozhi_tts-font_puhui_common_20_4-echoear.bin\"",
"CONFIG_CODEC_DATA_ADC_SUPPORT=y"
] ]
} }
] ]

View File

@ -30,7 +30,7 @@ dependencies:
- if: target not in [esp32] - if: target not in [esp32]
78/xiaozhi-fonts: ~1.6.0 78/xiaozhi-fonts: ~1.6.0
espressif/led_strip: ~3.0.2 espressif/led_strip: ~3.0.2
espressif/esp_codec_dev: ~1.5.4 espressif/esp_codec_dev: ~1.5.6
espressif/esp-sr: ~2.3.0 espressif/esp-sr: ~2.3.0
espressif/button: ~4.1.5 espressif/button: ~4.1.5
espressif/knob: ^1.0.0 espressif/knob: ^1.0.0
@ -57,7 +57,6 @@ dependencies:
espressif/esp_io_expander_tca95xx_16bit: ^2.0.0 espressif/esp_io_expander_tca95xx_16bit: ^2.0.0
espressif2022/image_player: ^1.1.1 espressif2022/image_player: ^1.1.1
espressif2022/esp_emote_expression: ^0.1.0 espressif2022/esp_emote_expression: ^0.1.0
espressif/adc_mic: ^0.2.1
espressif/esp_mmap_assets: ^1.3.2 espressif/esp_mmap_assets: ^1.3.2
txp666/otto-emoji-gif-component: txp666/otto-emoji-gif-component:
version: ^1.1.1 version: ^1.1.1

View File

@ -3,6 +3,7 @@ import os
import json import json
import zipfile import zipfile
import argparse import argparse
import re
from pathlib import Path from pathlib import Path
from typing import Optional from typing import Optional
@ -139,26 +140,113 @@ def _collect_variants(config_filename: str = "config.json") -> list[dict[str, st
def _find_board_config(board_type: str) -> Optional[str]: def _find_board_config_candidates(board_type: str) -> list[str]:
"""Find the corresponding CONFIG_BOARD_TYPE_xxx for the given board_type """Find all CONFIG_BOARD_TYPE_xxx candidates for the given board_type."""
Search backwards from 'set(BOARD_TYPE "xxx")' to find the nearest if(CONFIG_BOARD_TYPE_).
"""
board_leaf = board_type.split("/")[-1] board_leaf = board_type.split("/")[-1]
pattern = f'set(BOARD_TYPE "{board_leaf}")' pattern = f'set(BOARD_TYPE "{board_leaf}")'
cmake_file = Path("main/CMakeLists.txt") cmake_file = Path("main/CMakeLists.txt")
lines = cmake_file.read_text(encoding="utf-8").splitlines() lines = cmake_file.read_text(encoding="utf-8").splitlines()
candidates: list[str] = []
for idx, line in enumerate(lines): for idx, line in enumerate(lines):
if pattern in line: if pattern in line:
# Found the BOARD_TYPE line, search backwards for the config # Found the BOARD_TYPE line, search backwards for the nearest config guard
for back_idx in range(idx - 1, -1, -1): for back_idx in range(idx - 1, -1, -1):
back_line = lines[back_idx] back_line = lines[back_idx]
if "if(CONFIG_BOARD_TYPE_" in back_line: if "if(CONFIG_BOARD_TYPE_" in back_line:
return back_line.strip().split("if(")[1].split(")")[0] candidates.append(back_line.strip().split("if(")[1].split(")")[0])
break break
return candidates
def _extract_board_config_from_sdkconfig_append(sdkconfig_append: list[str]) -> Optional[str]:
"""Extract explicit CONFIG_BOARD_TYPE_xxx=y from sdkconfig_append, if present."""
pattern = re.compile(r"^(CONFIG_BOARD_TYPE_[A-Z0-9_]+)=y$")
matches = []
for item in sdkconfig_append:
m = pattern.match(item.strip())
if m:
matches.append(m.group(1))
if not matches:
return None return None
uniq = list(dict.fromkeys(matches))
if len(uniq) > 1:
raise ValueError(f"Multiple board type configs found in sdkconfig_append: {uniq}")
return uniq[0]
def _symbol_supports_target(symbol: str, target: str) -> bool:
"""Check whether Kconfig symbol depends on given target (e.g. esp32c5)."""
kconfig_file = Path("main/Kconfig.projbuild")
if not kconfig_file.exists():
return False
target_flag = f"IDF_TARGET_{target.upper()}"
lines = kconfig_file.read_text(encoding="utf-8").splitlines()
in_symbol = False
for line in lines:
stripped = line.strip()
if stripped.startswith("config "):
curr_symbol = stripped.split("config ", 1)[1].strip()
in_symbol = curr_symbol == symbol
continue
if in_symbol and stripped.startswith(("config ", "choice ", "endchoice", "menu ", "endmenu")):
break
if in_symbol and "depends on" in stripped and target_flag in stripped:
return True
return False
def _resolve_board_config(board_type: str, target: str, sdkconfig_append: list[str]) -> str:
"""Resolve CONFIG_BOARD_TYPE_xxx for current board build."""
explicit = _extract_board_config_from_sdkconfig_append(sdkconfig_append)
if explicit:
return explicit
candidates = _find_board_config_candidates(board_type)
if not candidates:
raise ValueError(f"Cannot find board config symbol for {board_type}")
if len(candidates) == 1:
return candidates[0]
by_target = [c for c in candidates if _symbol_supports_target(c, target)]
if len(by_target) == 1:
return by_target[0]
if len(by_target) > 1:
selected = by_target[0]
print(
f"[WARN] Ambiguous board config for {board_type} (target={target}), "
f"target-matched candidates={by_target}, selecting first: {selected}",
file=sys.stderr,
)
return selected
target_u = target.upper()
target_short = target_u.replace("ESP32", "")
by_name = [
c for c in candidates
if target_u in c or f"_{target_short}" in c
]
if len(by_name) == 1:
return by_name[0]
if len(by_name) > 1:
selected = by_name[0]
print(
f"[WARN] Ambiguous board config for {board_type} (target={target}), "
f"name-matched candidates={by_name}, selecting first: {selected}",
file=sys.stderr,
)
return selected
selected = candidates[0]
print(
f"[WARN] Ambiguous board config for {board_type} (target={target}), "
f"candidates={candidates}, selecting first: {selected}",
file=sys.stderr,
)
return selected
# Kconfig "select" entries are not automatically applied when we simply append # Kconfig "select" entries are not automatically applied when we simply append
@ -258,9 +346,18 @@ def release(board_type: str, config_filename: str = "config.json", *, filter_nam
continue continue
# Process sdkconfig_append # Process sdkconfig_append
board_type_config = _find_board_config(board_type) build_sdkconfig_append = build.get("sdkconfig_append", [])
explicit_board_cfg = _extract_board_config_from_sdkconfig_append(build_sdkconfig_append)
if explicit_board_cfg:
print(
f"[INFO] Board config explicitly set in config.json: {explicit_board_cfg}, "
"skip auto-select.",
)
sdkconfig_append = list(build_sdkconfig_append)
else:
board_type_config = _resolve_board_config(board_type, target, build_sdkconfig_append)
sdkconfig_append = [f"{board_type_config}=y"] sdkconfig_append = [f"{board_type_config}=y"]
sdkconfig_append.extend(build.get("sdkconfig_append", [])) sdkconfig_append.extend(build_sdkconfig_append)
sdkconfig_append = _apply_auto_selects(sdkconfig_append) sdkconfig_append = _apply_auto_selects(sdkconfig_append)
print("-" * 80) print("-" * 80)