Skip to content

Add EC618 platform support - #3199

Merged
floitsch merged 37 commits into
masterfrom
floitsch/ec618-clean-stack
Sep 13, 2026
Merged

floitsch merged 37 commits into
masterfrom
floitsch/ec618-clean-stack

Conversation

@floitsch

@floitsch floitsch commented Sep 1, 2026 •

Copy link
Copy Markdown
Member

Add EC618 platform support with a cross-build toolchain, runtime integration, GPIO, asynchronous UART/I2C/SPI, PWM, ADC, cellular networking, TLS, persistent storage, and frozen-base slot OTA. Hardware fixtures, firmware tools, and CI accompany the port.

The branch is rebased onto master aa831d6851 and uses the shared async bus API and merged ESP-IDF fixes. Programmable ESP32/S3 targets replace the removed RC522/BME280 fixtures.

Base v4 fixes fixed-precision formatting by retaining newlib-nano's optional _printf_float and aligning initial RTOS task stacks to eight bytes. The prebuilt kernel supplied only four-byte alignment, so variadic doubles were read from the wrong address. The same formatting regression also exposed and now covers negative hexadecimal/octal truncation and unsupported unsigned 64-bit decimal formatting. ADC diagnostics use fixed precision again. Devices on older bases require a full reflash; slot OTA cannot change the base.

Documentation is consolidated into open work, rig operations/wiring, and short design notes. Completed review trackers, bring-up plans, and duplicated historical descriptions are removed.

The host bus coordinator is written in Toit using native serial/TCP support and the shared CRC framing code. It resets the target over RTS before the boot handshake and retains bounded waits. The Python coordinator and its pyserial dependency are removed.

Validation:

  • Host SDK and EC618 base/slot builds, relocation/byte-identity guards, Toit analysis, and whitespace/link checks pass.
  • Base v4 is flashed on the module. All 16 standalone regression cases pass, including the complete formatting suite plus signed zero, rounding, precision 64, subnormals, largest finite doubles, and repeated heap-buffer formatting. OTA to the other slot validates and the formatting regression passes again.
  • All eight module memory/storage/network cases pass, including DNS, TCP, HTTPS, and UDP/NTP.
  • The dev board is also flashed with base v4. All 16 standalone and 31 peripheral cases pass, including ADC fixed-precision diagnostics. Slot-B OTA validates and formatting passes again afterward.
  • Both bus fixtures pass with the Toit coordinator: full I2C1/SPI coverage on the S3 (including speed/stretch/cancellation and all four SPI modes through 32768 bytes), and I2C0 at 50/100/400 kHz on the classic ESP32. Host coordinator/framing regressions cover fragmented replies, boot retries/noise, bad CRCs, EOF, timeouts, and QUIT.
  • Before the base-v4 change, both EC618 boards passed the full target-based bus/peripheral/lifecycle regression; 1,295 host tests passed across the full run and isolated reruns. The independent ESP32/S3 matrix passed 120/122 applicable cases; classic Wi-Fi TCP and ESP-NOW failures also reproduced on unchanged master. The rig owner excluded S3 ultrasound because it lacked an obstacle. No ESP32 implementation changed in this follow-up.

Remaining limitations and release/test follow-ups are in docs/ec618-todo.md.

@floitsch
floitsch force-pushed the floitsch/ec618-clean-stack branch from f3f3bbc to e6fb582 Compare September 1, 2026 21:32
@floitsch
floitsch changed the base branch from ec618 to master September 1, 2026 21:32
@floitsch
floitsch force-pushed the floitsch/ec618-clean-stack branch from e6fb582 to 7faeac0 Compare September 1, 2026 22:38
@floitsch
floitsch force-pushed the floitsch/ec618-clean-stack branch from 2a584bd to 54332ad Compare September 13, 2026 16:44
floitsch added a commit that referenced this pull request Sep 13, 2026
Consolidate asynchronous I2C controller read, write, and write-read
operations into one native transfer start/finish pair. Preserve
address-only probing and explicit abort; reject empty public transfers
consistently. An omitted clock-stretch timeout uses the platform default
(100 ms on ESP32). EC618 can reject unsupported custom hardware timeouts
while still supporting task deadlines.

Serialize SPI transfers and reservations in the common library so each
backend has one active controller operation. Reservations belong to the
calling task and device; conflicting operations from that task fail
instead of deadlocking. Cancellation either aborts natively or drains
under protection before releasing ownership, preserving ESP32's
drain-before-release behavior.

Add regression coverage for cancellation, scheduler progress,
reservation contention, immediate reuse, repeated I2C NACK recovery, and
SPI target setup in clock-high modes. Based on master `71d24d83`,
including the ESP-IDF fixes merged through #3224; this PR does not
change the dependency pin.

This is the common prerequisite for the EC618 adaptation in #3225, which
targets the platform branch in #3199.
floitsch added a commit that referenced this pull request Sep 13, 2026
Adapt the EC618 controllers to the common asynchronous I2C/SPI lifecycle
merged through #3223, and replace the removed RC522/BME280 tests with
programmable ESP32 targets. This PR targets `floitsch/ec618-clean-stack`
(#3199), rebased onto master `71d24d83`, including the ESP-IDF fixes
merged through #3224.

I2C uses one start/finish pair for write, read, and combined transfers,
with explicit cancellation and platform-default hardware timeouts. The
EC618 backend correctly handles long FIFO transfers, repeated starts,
NACK recovery, clock stretching, and device frequency restoration after
probes. Custom hardware timeouts remain unsupported on EC618; task
deadlines abort the operation and leave the controller reusable.

SPI shares controller serialization and task-owned reservations with
ESP32. EC618 cancellation retires DMA before releasing ownership, and
the clock reaches its configured idle level before CS is asserted. The
target tests cover both directions, all four modes, non-byte-aligned
command/address prefixes, slice sentinels, and DMA payloads through 32
KiB. One large test buffer is reused to avoid native heap fragmentation.

The S3 supplies I2C1 and SPI targets. The classic ESP32 supplies a basic
I2C0 target for reads/write-reads through 32 bytes and writes through
1,025 bytes; larger read responses require the S3's stretching support.
Wiring, target setup, and sequential use of shared nets are documented
in `tests/hw/ec618/README.md`.

Broader validation also exposed and fixed short UART DMA completion,
late keepalive replies during tester baud restoration, ESP test-agent
reset behavior, GPIO fixture lifetime/completion errors, and an EC618
flash-registry allocation failure during large bucket rewrites. Flash
writes now use bounded RAM staging. Fixed-precision EC618 float
formatting remains documented as known issue 15.

Validation:
- EC618 build, canonical OTA, trial-container smoke test, and slot
validation passed on both boards.
- Final S3 target suite passed: I2C read/write/write-read through 1,025
bytes, ACK/NACK, frequency changes, stretching/deadline recovery, all
SPI modes/prefixes through 32 KiB, cancellation, and immediate reuse.
Classic I2C0 target suite also passed.
- GPIO, ADC, PWM, UART stress/configuration/overflow/recovery, and
lifetime tests passed. Both boards passed all nine standalone lifecycle
checks and multipage storage; the module passed cellular DNS, TCP,
HTTPS, and UDP/NTP.
- Independent ESP32 and ESP32-S3 rigs: 120/123 hardware-matrix cases
passed across the full run and final reruns; all I2C/SPI cases passed on
both variants. Classic ESP-NOW packet loss, classic short-sleep timing
failures, and intermittent Wi-Fi TCP hangs reproduce with unchanged
master firmware (`0ef62329`) and are documented separately.
- Integration host suite: all 1,002 tests passed across the run and
environment-corrected reruns. The multicast case needs its expected
loopback route; the isolated PTY test needs the mapped user name. The
common master refactor additionally passed its 353 fuzzer-library cases.
- CI follow-through restored master's ESP32-P4 guards/RTC includes and
removed seven stale external warning gold files in the prerequisite
branch. The full ESP32-P4 cross-build passed locally. A separate
header-order correction restores 64-bit directory offsets on 32-bit
POSIX hosts; the CI startup hang reproduced under local ARM emulation
and the corrected bundled application now starts and exits normally;
these guards do not change the tested classic ESP32, S3, or EC618 paths.
- CI host, ESP32/QEMU, and cross-platform execution checks passed. The
macOS external/flaky shard passed its targeted rerun after a TLS
session-resumption failure against adafruit.com.
- Common I2C/SPI runtime code and ESP32 backends match merged #3223. The
I2C write precondition documentation incorporates its pending review
nit; `toit analyze lib/i2c.toit` and `git diff --check` pass.
Add the LuatOS SDK submodule, EC618 toolchain definition, and the AP project used to build the Toit runtime.
Add the rig runner, framed-control protocol, shared ESP32 helpers, package setup, and baseline platform checks before feature-specific tests.
Add platform detection, OS and VM integration, primitive registration, resource ownership support, and the embedded boot service.
Add authoritative pad routing, shared controller-bit ownership, GPIO modes and interrupts, AON behavior, and the corresponding cross-board lifecycle tests.
Add CMSIS-backed UART resources, physical transmit completion, lifecycle and RS485 handling, and the complete UART hardware test matrix.
Add the task-backed I2C transfer engine, cancellation and recovery semantics, long-transfer support, and controller/slave hardware fixtures.
Add controller ownership, DMA completion and cancellation, command/address phases, and RC522 coverage.
Add channel ownership, exact endpoint handling, AON routing, and cross-board waveform tests.
Add calibrated asynchronous conversions, cross-container channel ownership, and lifecycle tests.
Integrate modem ownership with the shared network service, adapt lwIP TCP and UDP behavior, and add cellular, DNS, HTTP, Nagle, and lifecycle coverage.
Configure mbedTLS for EC618, provide threading integration and hardware-backed randomness, and retain the shared TLS and crypto contracts.
Add EC618 flash-registry persistence, shared storage-provider integration, and multi-page hardware coverage.
Add RTC persistence, physical wake-source handling, hardware and liveness watchdogs, explicit reset semantics, and cross-platform reset/deep-sleep tests.
Add the frozen-base image layout, anchor-described partitions, slot relocation and validation, trial boot and rollback, firmware services, release workflows, and host and hardware tests.
Teach the firmware tool to inspect and flash EC618 images while keeping platform dispatch explicit.
Wire the completed platform into CMake and Make, initialize the required SDK submodules, and add hosted EC618 build coverage.
Document building, testing, provisioning, frozen-base OTA, rig operation, known constraints, and the completed PR #3075 review.
floitsch and others added 11 commits September 13, 2026 23:28
Adapt the EC618 controllers to the common asynchronous I2C/SPI lifecycle
merged through #3223, and replace the removed RC522/BME280 tests with
programmable ESP32 targets. This PR targets `floitsch/ec618-clean-stack`
(#3199), rebased onto master `71d24d83`, including the ESP-IDF fixes
merged through #3224.

I2C uses one start/finish pair for write, read, and combined transfers,
with explicit cancellation and platform-default hardware timeouts. The
EC618 backend correctly handles long FIFO transfers, repeated starts,
NACK recovery, clock stretching, and device frequency restoration after
probes. Custom hardware timeouts remain unsupported on EC618; task
deadlines abort the operation and leave the controller reusable.

SPI shares controller serialization and task-owned reservations with
ESP32. EC618 cancellation retires DMA before releasing ownership, and
the clock reaches its configured idle level before CS is asserted. The
target tests cover both directions, all four modes, non-byte-aligned
command/address prefixes, slice sentinels, and DMA payloads through 32
KiB. One large test buffer is reused to avoid native heap fragmentation.

The S3 supplies I2C1 and SPI targets. The classic ESP32 supplies a basic
I2C0 target for reads/write-reads through 32 bytes and writes through
1,025 bytes; larger read responses require the S3's stretching support.
Wiring, target setup, and sequential use of shared nets are documented
in `tests/hw/ec618/README.md`.

Broader validation also exposed and fixed short UART DMA completion,
late keepalive replies during tester baud restoration, ESP test-agent
reset behavior, GPIO fixture lifetime/completion errors, and an EC618
flash-registry allocation failure during large bucket rewrites. Flash
writes now use bounded RAM staging. Fixed-precision EC618 float
formatting remains documented as known issue 15.

Validation:
- EC618 build, canonical OTA, trial-container smoke test, and slot
validation passed on both boards.
- Final S3 target suite passed: I2C read/write/write-read through 1,025
bytes, ACK/NACK, frequency changes, stretching/deadline recovery, all
SPI modes/prefixes through 32 KiB, cancellation, and immediate reuse.
Classic I2C0 target suite also passed.
- GPIO, ADC, PWM, UART stress/configuration/overflow/recovery, and
lifetime tests passed. Both boards passed all nine standalone lifecycle
checks and multipage storage; the module passed cellular DNS, TCP,
HTTPS, and UDP/NTP.
- Independent ESP32 and ESP32-S3 rigs: 120/123 hardware-matrix cases
passed across the full run and final reruns; all I2C/SPI cases passed on
both variants. Classic ESP-NOW packet loss, classic short-sleep timing
failures, and intermittent Wi-Fi TCP hangs reproduce with unchanged
master firmware (`0ef62329`) and are documented separately.
- Integration host suite: all 1,002 tests passed across the run and
environment-corrected reruns. The multicast case needs its expected
loopback route; the isolated PTY test needs the mapped user name. The
common master refactor additionally passed its 353 fuzzer-library cases.
- CI follow-through restored master's ESP32-P4 guards/RTC includes and
removed seven stale external warning gold files in the prerequisite
branch. The full ESP32-P4 cross-build passed locally. A separate
header-order correction restores 64-bit directory offsets on 32-bit
POSIX hosts; the CI startup hang reproduced under local ARM emulation
and the corrected bundled application now starts and exits normally;
these guards do not change the tested classic ESP32, S3, or EC618 paths.
- CI host, ESP32/QEMU, and cross-platform execution checks passed. The
macOS external/flaky shard passed its targeted rerun after a TLS
session-resumption failure against adafruit.com.
- Common I2C/SPI runtime code and ESP32 backends match merged #3223. The
I2C write precondition documentation incorporates its pending review
nit; `toit analyze lib/i2c.toit` and `git diff --check` pass.
@floitsch
floitsch force-pushed the floitsch/ec618-clean-stack branch from df88792 to 9bb5669 Compare September 13, 2026 21:38
@floitsch
floitsch merged commit 8f3a100 into master Sep 13, 2026
36 of 37 checks passed
@floitsch
floitsch deleted the floitsch/ec618-clean-stack branch September 13, 2026 23:53
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Development

Successfully merging this pull request may close these issues.

1 participant