velxio/backend/app/services
David Montero cf4af79414 fix(esp32/ledc): translate ledcWrite(pin,duty) → ledcWrite(channel,duty)
arduino-esp32 3.x ledcWrite takes a PIN and looks up the attached channel
internally. arduino-esp32 2.x (the toolchain version we pin) takes a
CHANNEL. The velxio_compat.h shim already aliased the 3.x-only
ledcAttach onto ledcSetup+ledcAttachPin so 3.x sketches would compile,
but ledcWrite still mapped 1:1 — so a call like

    #define R_PIN 16
    ledcAttach(R_PIN, 5000, 8);   // shim → channel 0 attached to pin 16
    ledcWrite(R_PIN, 128);        // ★ writes to "channel 16" (invalid)

silently wrote to LEDC channel 16, which doesn't exist (valid range
0-15). The hardware duty register never changed, qemu-lcgamboa never
emitted a `ledc_duty` event, and the RGB LED stayed dark even though
the firmware ran cleanly and the wires looked right. Verified end-to-end
with examples/esp32-pwm-led-rgb: gpio_change events fired at boot, no
ledc_duty events fired, ledRed/ledGreen/ledBlue all stayed at 0.

Fix: maintain a 40-entry pin→channel table populated by both ledcAttach
variants. Replace ledcWrite with a macro that calls a helper checking
the table first; if the value isn't a known pin we pass it through as a
channel, preserving 2.x channel-style call sites.

Macro/function name collision is sidestepped with the standard
parenthesizing trick — `(ledcWrite)(channel, duty)` doesn't expand the
function-like macro because the token isn't followed by `(`.

Verified live on velxio.dev/example/esp32-pwm-led-rgb after hot-copying
the new header into the velxio-app container: ledRed/ledGreen/ledBlue
now cycle through the full HSV wheel as expected (samples: (255,41,0),
(41,255,0), (0,41,255), (232,255,0), …).

Single-file sketch only — the table is `static` (internal linkage) and
ledcAttach + ledcWrite live in the header. Multi-file sketches that
attach in file A and write in file B would each see their own table.
Acceptable for now since arduino-esp32 sketches are nearly always
single-file; revisit when we bump the toolchain to 3.x and can drop the
shim entirely.
2026-05-22 16:14:55 +02:00
..
boot_images feat(pi): Phase 3.3 — Pi Zero / Pi 1 / Pi 2 armhf simulators 2026-05-18 23:23:48 +02:00
esp-idf-template fix(esp32/ledc): translate ledcWrite(pin,duty) → ledcWrite(channel,duty) 2026-05-22 16:14:55 +02:00
picow_net
__init__.py
arduino_cli.py fix(arduino-cli): pin ATTinyCore to 1.4.1 (azduino.com micronucleus host unreachable) 2026-05-22 15:15:53 +02:00
asm8080.py feat(chips): programmable retro CPU chips with external ROM 2026-05-18 23:38:18 -03:00
asmz80.py feat(chips): programmable Z80 chip + Larson scanner example 2026-05-19 00:21:08 -03:00
c_compile.py feat(chips): C-to-Z80 compile via SDCC + LED chaser example 2026-05-19 00:31:10 -03:00
chip_compile.py
esp32_flash_image.py fix(esp32): trim flash image before serializing, pad on QEMU attach 2026-05-08 14:36:34 -03:00
esp32_i2c_slaves.py feat(i2c): cross-board bridging across all velxio boards (AVR/RP2040/ESP32 xtensa+riscv) 2026-05-12 17:51:39 -03:00
esp32_lib_bridge.py feat(compile): ESP-IDF compile options + request dedup 2026-05-18 21:50:45 -03:00
esp32_lib_manager.py refactor(esp32): retire ledc_update + broadcastPwm + channelGpioMemo 2026-05-19 04:05:34 +02:00
esp32_signals.py fix(esp32): LEDC signal IDs are 71-86 per ESP32 TRM, not 72-87 2026-05-17 05:42:52 +02:00
esp32_spi_slaves.py
esp32_worker.py fix(ci+esp32): unblock backend e2e + bump frontend node heap 2026-05-19 16:04:50 +02:00
esp_qemu_manager.py
espidf_compiler.py feat(compile): ESP-IDF compile options + request dedup 2026-05-18 21:50:45 -03:00
gpio_shim.py
picow_net_bridge.py
qemu_manager.py feat(pi): Phase 3.3 — Pi Zero / Pi 1 / Pi 2 armhf simulators 2026-05-18 23:23:48 +02:00
rom_compile.py feat(chips): C-to-Z80 compile via SDCC + LED chaser example 2026-05-19 00:31:10 -03:00
signal_router.py feat(esp32): SignalRouter — model the GPIO Matrix as first-class 2026-05-17 05:00:53 +02:00
wasm_chip_runtime.py
wasm_chip_slave.py
wifi_status_parser.py