Skip to content

feat: keep Ethernet settings independent of the framework - #70

Merged
cjkas merged 10 commits into
mainfrom
feat/eth-framework-independent
Oct 21, 2026
Merged

cjkas merged 10 commits into
mainfrom
feat/eth-framework-independent

Conversation

@cjkas

@cjkas cjkas commented Oct 19, 2026

Copy link
Copy Markdown
Owner

Summary

This is the first of two PRs moving to pioarduino / Arduino 3.x / ESP-IDF 5.5. It still builds on espressif32 @ 6.13.0 and changes nothing at runtime for current Ethernet boards.

Arduino 3.x adds ETH_PHY_GENERIC = 0 at the start of eth_phy_type_t, which shifts every chip up by one. The firmware casts the stored number straight to that enum, so after the switch a LAN8720 board would start as GENERIC and lose its network. The stored id now keeps today's numbering and is translated by name:

 connectWired
-  ETH.begin(..., (eth_phy_type_t)stored, ...)
+  ethPhyType(stored, phy)      // eth_phy_id_t -> ETH_PHY_<name>, false for DM9051/unknown
+  ETH.begin(..., phy, ...)

NVS, backups and the web UI keep the same numbers (eth_phy_id_t in src/EthPhy.h).

Ethernet is now built only on chips with the RMII MAC:

-#ifndef CONFIG_IDF_TARGET_ESP32C6   // C3/S3 compiled Ethernet they can't use
+#if HAS_ETHERNET                    // CONFIG_ETH_USE_ESP32_EMAC: original ESP32 only
  • On C3, S3 and C6, a stored ethernet/ethernetpref connection type falls back to Wi‑Fi, or to the AP when no SSID is set.
  • /networksettings returns hasEthernet, and the UI hides "Use Ethernet" when it's false. Older firmware without the field is treated as having Ethernet.
  • Fixed the UI PHY list. Value 5 was labelled "KZ8081" but is the KSZ8041. KSZ8081 (6) is added. DM9051 (4) is removed because it's an SPI chip the MAC can't drive.
  • SSDP gets its address from WiFi.localIP() / ETH.localIP() instead of tcpip_adapter_*, which IDF 5 removed. In AP mode it used to return an uninitialised address.

Evidence

The new native test uses a stub ETH.h with the Arduino 3.x numbering. With that numbering, a cast picks the wrong chip:

stored id 0 (LAN8720)
  cast         -> ETH_PHY_GENERIC   (test_lan8720_is_not_the_framework_zero fails)
  ethPhyType() -> ETH_PHY_LAN8720   (passes)
  • pio test -e native: 412/412 passed, including the new test_ethphy.
  • Firmware builds:
Env Platform Result Flash
esp32dev espressif32 6.13.0 ✅ 1,395,889
esp32c3 espressif32 6.13.0 ✅ 1,345,422
esp32s3 espressif32 6.13.0 ✅ 1,304,373
esp32c6 pioarduino 55.03.37 ✅ 1,637,534

Not yet tested on hardware: Ethernet start-up on an ESP32 Ethernet board.

Merge Danger

Door: two-way

Stored settings and the backup format don't change, so a revert puts everything back as it was.

Blast Radius: Ethernet

  • ESP32 Ethernet boards: same ids, now translated instead of cast. On 2.x the result is identical.
  • A board with DM9051 (4) stored now logs Ethernet PHY type 4 is not supported and fails to start Ethernet. It could never work through the RMII MAC anyway.
  • C3/S3 with an Ethernet connection type stored now uses Wi‑Fi instead of retrying Ethernet that can't start.

🤖 Generated with Claude Code

cjkas and others added 2 commits October 19, 2026 21:13
Prepares the move to Arduino 3.x / ESP-IDF 5.5, which renumbers
eth_phy_type_t (ETH_PHY_GENERIC is now 0) and only has the RMII MAC
API on the original ESP32.

- Store the PHY chip as our own id (eth_phy_id_t, the 2.x values) and
  translate it by name at ETH.begin(), so NVS, backups and the web UI
  keep their numbers on either framework.
- Build Ethernet only where CONFIG_ETH_USE_ESP32_EMAC is set instead of
  everywhere but the C6.  C3 and S3 could never use it.  A stored
  Ethernet connection falls back to Wi-Fi on those chips.
- /networksettings reports hasEthernet; the UI hides the Ethernet
  options without it.
- Fix the UI PHY list: 5 is the KSZ8041, add the KSZ8081 (6), drop the
  DM9051, an SPI chip the MAC can't drive.
- SSDP takes its address from WiFi/ETH.localIP() instead of the
  tcpip_adapter API IDF 5 removed.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
IDF 4.4 gets no more security fixes, and the planned RMT radio needs
IDF 5's RMT driver.  See docs/adr/0003-pioarduino-idf55.md.

- Every env on one pinned pioarduino release.  C6 drops its own
  library list and flags but stays a debug build on huge_app.
- Release envs build at CORE_DEBUG_LEVEL=2 so the ESP32 image fits its
  1.5 MB OTA slot (17 KB free); debug envs stay at 3.
- Drop the C3: its image is 76.5 KB over the OTA slot on IDF 5.5.
- CI installs pioarduino's Core and checks firmware.bin against the app
  partition, failing under 8 KB free.  PlatformIO's "Flash:" figure
  reads ~45 KB low and passed a C3 image that doesn't fit.
- esp_task_wdt_reconfigure(): on 3.x the core already starts the watchdog
  and esp_task_wdt_init() fails, so the C6 build kept the 5 s default.
- An updated firmware is kept only once it has run 60 s with the
  network up; a reset before then rolls back to the previous one.
- ETH.begin() takes the 3.x argument order; Arduino 2.x branches gone.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
cjkas and others added 8 commits October 20, 2026 20:43
Releases publish SomfyController.littlefs.<chip>.bin, but the updater asked
for SomfyController.littlefs.bin. The download 404'd and the device rebooted
into the new firmware with the old web UI.

Also: hasFS now matches per-chip images, C6 picks its own firmware file, and
recoverFilesystem() points at cjkas instead of rstrouse.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Review follow-up for #72.

- releaseAssetName() takes ConfigSettings::chipModel ("", "s3", "c3", "c6"),
  so GitOTA no longer keeps its own chip switch. C3 keeps its name for when
  the build comes back.
- hasFS is set only when this board's own LittleFS image is in the release.
  isFsAsset() is gone; it also matched the old unsuffixed littlefs.bin, which
  the updater no longer asks for.
- releaseAssetName() returns void: no caller checked the result and every
  name fits currentFile.
- Both manual-upload hints name this board's file.
- KNOWN_ISSUES: the "Main" install can't work, the repo holds no .bin files.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Copied from the registry package lsatan/SmartRC-CC1101-Driver-Lib@2.5.7
(upstream unmaintained since 2021) so it can be fixed for Arduino 3.x in
the next commit. This commit is the untouched copy, so that diff shows
every change. Licence: LICENSE.txt ("permission to modify and publish").

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Arduino 3.x tracks which peripheral owns each pin and logs when a pin the
SPI bus owns is used through digitalRead()/digitalWrite(). The vendored
SmartRC-CC1101 driver does both:

- Every register access waits for CHIP_RDYn with digitalRead(MISO): one
  "IO 19 is not set as GPIO" warning per access, about one every 4 s from
  the RSSI read in decodeFrame(). It now reads the pad with gpio_get_level(),
  which returns the same level without the ownership check.
- Init() set SCK and MOSI with digitalWrite() after SpiStart(), which the core
  refused with an error each boot. The writes are gone; the bus idles them.

The MISO wait also had no bound, so a missing or dead module hung the caller.
It now gives up after 10 ms.

No native test: the driver only builds for the ESP32. To check on hardware:
the serial log should have no "is not set as GPIO" lines, and frames should
still decode with an RSSI.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
fix: download the per-chip LittleFS image in online updates
fix: stop the CC1101 driver's "IO is not set as GPIO" log spam
build: move to pioarduino 55.03.312 (Arduino 3.3.12, ESP-IDF 5.5)
Brings in the coredump bounds fix (#74). Utils.h, Utils.cpp and
test_utils.cpp conflicted only because both sides added helpers in the
same spot; kept otaProven/releaseAssetName and formatBacktrace.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@cjkas
cjkas merged commit 57aa01e into main Oct 21, 2026
4 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant