Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
71 changes: 71 additions & 0 deletions .github/workflows/build_platformio.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
name: build_platformio

on: [push, pull_request]

jobs:
# ── Step 1: parse platformio.ini and produce the matrix list ──────────────
discover:
runs-on: ubuntu-latest
outputs:
envs: ${{ steps.get-envs.outputs.envs }}
steps:
- uses: actions/checkout@v4

- name: Discover buildable PlatformIO environments
id: get-envs
run: |
python3 - <<'EOF'
import re, json, os
with open("platformio.ini") as f:
content = f.read()
envs = re.findall(r"^\[env:([^\]]+)\]", content, re.MULTILINE)
# Skip abstract base templates and debug-only variants
envs = [e for e in envs if not e.startswith("base-") and not e.endswith("-debug")]
output = json.dumps(envs)
print(f"Discovered environments: {output}")
with open(os.environ["GITHUB_OUTPUT"], "a") as gh_out:
gh_out.write(f"envs={output}\n")
EOF

# ── Step 2: build each environment in parallel ────────────────────────────
build:
needs: discover
strategy:
fail-fast: false # let other envs finish even if one fails
matrix:
environment: ${{ fromJson(needs.discover.outputs.envs) }}

runs-on: ubuntu-latest
name: build / ${{ matrix.environment }}

steps:
- uses: actions/checkout@v4
with:
submodules: recursive

- uses: actions/setup-python@v5
with:
python-version: "3.x"

# Cache the PlatformIO home directory (toolchains, platform packages)
# and the per-env build output so incremental builds are faster.
- uses: actions/cache@v4
with:
path: |
~/.platformio
.pio/build/${{ matrix.environment }}
key: pio-${{ matrix.environment }}-${{ hashFiles('platformio.ini', 'sdkconfig.defaults', 'sdkconfig.defaults.*') }}
restore-keys: |
pio-${{ matrix.environment }}-

- name: Install PlatformIO Core
run: pip install --quiet platformio

- name: Build ${{ matrix.environment }}
run: |
# On the first completely clean build, cmake configure runs *after*
# extra_scripts are evaluated, so pre_build.py finds no build.ninja
# and skips ESP-IDF embed-file stub generation → ninja fails.
# The second attempt finds the freshly created build.ninja and succeeds.
platformio run --environment ${{ matrix.environment }} \
|| platformio run --environment ${{ matrix.environment }}
5 changes: 4 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,8 @@ build
libopus
managed_components
sdkconfig
sdkconfig.old
sdkconfig.*
!sdkconfig.defaults.*
dependencies.lock

# Created by https://www.toptal.com/developers/gitignore/api/c,c++,eclipse
Expand Down Expand Up @@ -149,3 +150,5 @@ local.properties

# End of https://www.toptal.com/developers/gitignore/api/c,c++,eclipse
.vscode-ctags
.vscode/c_cpp_properties.json
.vscode/launch.json
10 changes: 10 additions & 0 deletions .vscode/extensions.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
{
// See http://go.microsoft.com/fwlink/?LinkId=827846
// for the documentation about the extensions.json format
"recommendations": [
"platformio.platformio-ide"
],
"unwantedRecommendations": [
"ms-vscode.cpptools-extension-pack"
]
}
4 changes: 2 additions & 2 deletions .vscode/tasks.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,13 @@
{
"label": "Start Docker Container for Build",
"type": "shell",
"command": "docker run --rm -it -v ${workspaceFolder}:${workspaceFolder} -w ${workspaceFolder} -v /dev:/dev --privileged espressif/idf:v5.1.1",
"command": "docker run --rm -it -v ${workspaceFolder}:${workspaceFolder} -w ${workspaceFolder} -v /dev:/dev --privileged espressif/idf:v5.5.1",
"problemMatcher": []
},
{
"label": "Build, Flash and Monitor (Docker)",
"type": "shell",
"command": "docker run --rm -it -v ${workspaceFolder}:${workspaceFolder} -w ${workspaceFolder} -v /dev:/dev --privileged espressif/idf:v5.1.1 /bin/bash -c '. $IDF_PATH/export.sh && idf.py build flash monitor'",
"command": "docker run --rm -it -v ${workspaceFolder}:${workspaceFolder} -w ${workspaceFolder} -v /dev:/dev --privileged espressif/idf:v5.5.1 /bin/bash -c '. $IDF_PATH/export.sh && idf.py build flash monitor'",
"group": {
"kind": "build",
"isDefault": true
Expand Down
41 changes: 38 additions & 3 deletions components/audio_board/Kconfig.projbuild
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,14 @@ menu "Audio Board"
choice and is not exposed to menuconfig.
See https://github.com/schreibfaul1/ESP32-audioI2S/blob/1d9b299d0197f99fc70335295adcd226dc220f88/src/Audio.cpp#L4929

config I2S_SLOT_32BIT
bool
default n
help
Forces the I2S slot width to 32 bits regardless of sample depth. Required for DACs that only
support 32-bit or 24-bit frames (e.g. MA120X0P whose OTP default frame size is 32 bits).
The IDF zero-pads 16-bit samples to fill the 32-bit slot automatically.

choice AUDIO_BOARD
prompt "Audio board"
default ESP32_S2_KALUGA_1_V1_2_BOARD if IDF_TARGET_ESP32S2
Expand Down Expand Up @@ -94,6 +102,7 @@ menu "Audio Board"

config DAC_MA120X0
bool "Infineon MA120X0 ClassD AMP"
select I2S_SLOT_32BIT

config DAC_ADAU1961
bool "Analog Devices ADAU1961 DAC"
Expand Down Expand Up @@ -195,7 +204,8 @@ menu "Audio Board"
When enabled, build includes optional TAS5805M equalizer support.
Equalizer configuration and runtime control remain available via
the device UI. Default: disabled.
endmenu

endmenu

menu "Merus MA120x0 interface Configuration"
depends on DAC_MA120X0
Expand All @@ -206,23 +216,48 @@ menu "Audio Board"
help
GPIO number to control enable/disable.

config MA120X0_NENABLE_INVERT
bool "Invert nEnable pin logic (active-low)"
default n
depends on MA120X0_NENABLE_PIN != -1
help
When enabled, the nEnable pin is driven LOW to enable the
amplifier and HIGH to disable it (active-low, as per the
MA120x0 datasheet). When disabled, HIGH = on, LOW = off.

config MA120X0_NMUTE_PIN
int "Master mute/unmute for ma120x0"
default 2
help
GPIO number to controm mute/unmute.

config MERUS_NERR_PIN
config MA120X0_NERR_PIN
int "NERR monitor pin"
default 21
help
GPIO number to monitor NERROR.

config MERUS_NCLIP_PIN
config MA120X0_NCLIP_PIN
int "Clip indication pin"
default 22
help
GPIO number low if clip observed

config MA120X0_VOL_MAX_DB
int "Maximum volume level (dB, ≤ 0)"
default 0
range -144 24
help
Register value at slider position 100. 0 dB is the
maximum undistorted output level of the MA120x0.

config MA120X0_VOL_MIN_DB
int "Minimum volume level (dB)"
default -60
range -144 24
help
Register value at slider position 0. Values below -60 dB
are practically inaudible on most systems.
endmenu

menu "Merus MA120 interface Configuration"
Expand Down
6 changes: 3 additions & 3 deletions components/audio_hal/driver/tas5805m/tas5805m.c
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,7 @@ static esp_err_t tas5805m_transmit_registers(const tas5805m_cfg_reg_t *conf_buf,
// Used in legacy applications. Ignored here.
break;
case CFG_META_DELAY:
vTaskDelay(conf_buf[i].value / portTICK_PERIOD_MS);
vTaskDelay(pdMS_TO_TICKS(conf_buf[i].value));
break;
case CFG_META_BURST:
ret = i2c_bus_write_bytes(i2c_handler, TAS5805M_ADDR,
Expand Down Expand Up @@ -135,9 +135,9 @@ esp_err_t tas5805m_init(audio_hal_codec_config_t *codec_cfg) {
io_conf.intr_type = GPIO_INTR_DISABLE;
gpio_config(&io_conf);
gpio_set_level(TAS5805M_RST_GPIO, 0);
vTaskDelay(20 / portTICK_PERIOD_MS);
vTaskDelay(pdMS_TO_TICKS(20));
gpio_set_level(TAS5805M_RST_GPIO, 1);
vTaskDelay(200 / portTICK_PERIOD_MS);
vTaskDelay(pdMS_TO_TICKS(200));

ret = get_i2c_pins(I2C_NUM_0, &i2c_cfg);
i2c_handler = i2c_bus_create(I2C_NUM_0, &i2c_cfg);
Expand Down
6 changes: 6 additions & 0 deletions components/bq_calc/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
set(COMPONENT_REQUIRES)
set(COMPONENT_PRIV_REQUIRES)

list(APPEND COMPONENT_ADD_INCLUDEDIRS ./include)
set(COMPONENT_SRCS ./bq_calc.c)
register_component()
Loading
Loading