Add MarkWTech extra buttons and dual-slot HTTP firmware OTA - #3
Merged
Conversation
Wire left/Stop/right/Back/Menu on GPIO 11–14 and 16 with a debounced scanner, map them through MarkwtechSurface/NavProfile, and document the pinout so provisioning chord *+Stop works on hardware. Co-authored-by: Cursor <cursoragent@cursor.com>
Keep GPIO 16 free for the serial console; GPIO 15 is strapping but idle-high with pull-up is safe if Menu is not held at reset. Co-authored-by: Cursor <cursoragent@cursor.com>
Add per-component connection tables, a master GPIO map, and clarify GPIO 15 strapping behavior on stock DevKitC-1 boards. Co-authored-by: Cursor <cursoragent@cursor.com>
GPIO 14 is not broken out on the ESP32-C6-WROOM-1 module, so the Back button had no header to connect to. Move it to GPIO 5 and Menu-right from USB_D+ (13) to GPIO 4, keeping the native USB pair intact apart from Stop on USB_D-. Document the ESP32-C6-DevKitC-1 J1/J3 header positions for every wire, and add the battery hardware the DevKit lacks compared to the LOLIN32 the original WiTcontroller uses: charger, 3.3 V regulator and the 47k/47k divider feeding the ADC on GPIO 1. Co-authored-by: Cursor <cursoragent@cursor.com>
Serve POST /api/v1/firmware from the pairing AP (with DHCP) and from the Extras firmware-update screen on STA, writing the inactive OTA slot. Co-authored-by: Cursor <cursoragent@cursor.com>
Point the first dual-slot install at update-firmware --mode usb as well as a raw espflash invocation. Co-authored-by: Cursor <cursoragent@cursor.com>
Add an English step-by-step build plus a Polish translation, log a suggested ADC factor for first-power calibration, and enable 4-minute inactivity sleep with a 5% low-battery cutoff. Co-authored-by: Cursor <cursoragent@cursor.com>
…tor. Adds paged lists, splash, T9 keyboard, diagnostics, ICMP ping, and expanded NVS persist. Documents MarkWTech assembly and adds a dedicated flash target. Co-authored-by: Cursor <cursoragent@cursor.com>
…outer. Replace the firmware FSM menus with one screen type per file, Intent-based side effects, and borrowed drive/network snapshots so the UI no longer depends on DomainState. Co-authored-by: Cursor <cursoragent@cursor.com>
Keep the text caret on ASCII, parse prefix digits without wrapping, honor EStop during HTTP OTA, bound nav hops, and serve static i18n tables. Co-authored-by: Cursor <cursoragent@cursor.com>
NetField, menu/extras/direct/device rows, and language entries encode legal choices in the type system. Drop dead Intent/menu/boot APIs and route analog pot and loco-slot switches into domain actions. Co-authored-by: Cursor <cursoragent@cursor.com>
Numbered layout lives on the list widget so screens stop passing a redundant flag and rebuilding labels on digit-select; firmware builds context through UiWorld instead of copying screen_ctx at every event. Co-authored-by: Cursor <cursoragent@cursor.com>
Firmware reuses longfred-ui GridView instead of memcpy, invert is a bitmask, text insert no longer clones the buffer, and nav mapping takes InputMode rather than a pair of booleans. Co-authored-by: Cursor <cursoragent@cursor.com>
Screens stay stateless across navigation, compiled SSID lists have an explicit cap, and host tests cover stack overflow plus keyboard/list edges; make test also runs the release-assertions profile. Co-authored-by: Cursor <cursoragent@cursor.com>
…red-ui. Co-authored-by: Cursor <cursoragent@cursor.com>
…ocs allow. Co-authored-by: Cursor <cursoragent@cursor.com>
Co-authored-by: Cursor <cursoragent@cursor.com>
Co-authored-by: Cursor <cursoragent@cursor.com>
Introduce ProtocolCaps, a BigFred protocol variant, and LocoCatalog so the roster picker no longer guesses from an empty live list. Co-authored-by: Cursor <cursoragent@cursor.com>
Honour Auto/Static/AddressOnly at connect with a one-step fallback to address-only, without writing NVS, and expose the setting in Extras, Soft-AP, and diagnostics. Co-authored-by: Cursor <cursoragent@cursor.com>
Keep five numbered shortcuts: AddressOnly opens AddrEdit, roster sources still open the list, and acquire reuses the existing address path. Co-authored-by: Cursor <cursoragent@cursor.com>
Release the current slot and acquire the neighbour into the same throttle; AddressOnly leaves the keys unused. Co-authored-by: Cursor <cursoragent@cursor.com>
Compose WiThrottle in a BigFredAdapter that owns the timed function-digit FSM, and route sentinel, success, and timeout events through dedicated pairing screens. Co-authored-by: Cursor <cursoragent@cursor.com>
Extend TAG_BIGFRED compatibly to version 5, expose pairingCode in Soft-AP, and clear stale codes after success or timeout. Co-authored-by: Cursor <cursoragent@cursor.com>
Recognize the stable product marker in a bounded HTTP response and gracefully retain WiThrottle when the probe fails or does not match. Co-authored-by: Cursor <cursoragent@cursor.com>
POST the bounded login/PIN/deviceId DTO after protocol detection, persist a valid 201 response, and feed its code into the existing pairing FSM. Co-authored-by: Cursor <cursoragent@cursor.com>
Use the collection's contains helper so the full make lint gate remains warning-free. Co-authored-by: Cursor <cursoragent@cursor.com>
Keep the WiThrottle session responsive while fetching a code, bound retries to one per pairing cycle, and reject stale responses after reconnect. Co-authored-by: Cursor <cursoragent@cursor.com>
Keep public types one level deep via mod.rs re-exports so firmware and UI import withrottle, z21, bigfred, and network rather than scattered leaf files. Co-authored-by: Cursor <cursoragent@cursor.com>
ProtocolSpec lives next to the adapters; Protocol is only the NVS/wire identity with one info() match, so UI and firmware ask for caps, probe, glyph, and transport instead of matching variants. Co-authored-by: Cursor <cursoragent@cursor.com>
Archive the loco-source and pairing design as a completed plan and gate pairing HTTP on protocol capabilities instead of BigFred identity. Co-authored-by: Cursor <cursoragent@cursor.com>
Replace the cramped "manetka" labels with "kontroler jazdy" so extras and the direct menu match the longer OLED line budget. Co-authored-by: Cursor <cursoragent@cursor.com>
Reuse a live BigFred session instead of pairing again, overlay station messages, probe mDNS hosts as BigFred, and keep locomotive lists in DCC address order. Co-authored-by: Cursor <cursoragent@cursor.com>
Reserve the last visible content row for hints when lists use a footer, so the fifth main-menu item stays on screen on 128×64 and mini paginates correctly. Align grid Y positions with FONT_6X10 bounds on 64 and 32 px panels. Map extras digit keys to label numbers via select_label_digit, and rename heartbeat toggle state to dead-man switch in UI and proto. Co-authored-by: Cursor <cursoragent@cursor.com>
Show roster position, line-drawn direction, server link status, and battery percent on the drive screen. Release the current slot before every roster or address acquire so functions and speed never hit two locos at once; document the single-loco policy in ARCHITECTURE.md. Co-authored-by: Cursor <cursoragent@cursor.com>
Add star-prefix row selection on MarkWTech lists and Shift+F shortcuts on LongFred, gate background ICMP ping to the diagnostics screen, merge RF and ping on one diagnostics page, and add server menu flows with reconnect/disconnect plus session restart when the station changes. Co-authored-by: Cursor <cursoragent@cursor.com>
Remove the one-loco toggle and drop-before-acquire path, raise MAX_THROTTLES to 9, and add a numeric Slot count screen with SetMaxThrottles and a confirmation overlay. Co-authored-by: Cursor <cursoragent@cursor.com>
Replace edge-triggered A/B sampling with a polled quadrature state machine so mechanical bounce no longer flips rotation direction. Co-authored-by: Cursor <cursoragent@cursor.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Why this is one PR
MarkWTech hardware bring-up and dual-slot firmware OTA are the same initiative. Extra GPIO buttons, pin remaps, and the DevKit wiring guide exist so the throttle can be assembled and driven. HTTP OTA is how firmware is iterated while that hardware is being built (no USB cable on every change) and is also the intended production update path once the dual-slot table is on the chip.
Companion: wireless-programmer#2 (
update-firmware --mode ap|lan|usb).MarkWTech extra buttons and wiring
Five debounced GPIO tact switches: menu left, Stop, menu right, Back, Menu. Scanner in
extra_buttons, mapped throughMarkwtechSurface/MarkwtechNav(Back = Cancel; left/right page lists or move the cursor in text entry). Provisioning chord remains*+ Stop (8 s).Pins that actually exist on the ESP32-C6-WROOM-1 / DevKitC-1 headers (GPIO 14 is not broken out; GPIO 16 is UART0 TX):
USB_D−)Native USB is sacrificed only on
D−(Stop). Firmware is flashed on the UART Type-C. GPIO 4/5/15 are strapping pins but idle-high with pull-up does not change boot mode if those buttons are not held at reset.Hardware guide (
docs/hardware/markwtech.md): per-component tables, master GPIO map, J1/J3 positions, and the battery hardware the DevKit lacks vs the original LOLIN32 WiTcontroller (TP4056, S7V8F3 3.3 V, 47 kΩ/47 kΩ divider on GPIO 1).Dual-slot HTTP firmware OTA
First flash of the new table is USB (
espflash/wireless-programmer update-firmware --mode usbwith ELF +partitions.csv). After that, updates are HTTP:NVS stays at
0x9000. No factory partition. Slot size0x3C0000;NET_SOCKETS=6/PROG_NET_SOCKETS=4.Two HTTP paths, same
POST /api/v1/firmware(streamed, magic0xE9, chip id0x000D/ ESP32-C6). Body is.app.bin(espflash save-imagewithout--merge); merged dumps are rejected.192.168.0.50–200, HTTP at192.168.0.1. After OTA the throttle stays inprogramming_mode. heiko-wifred: AP chord only (no Extras menu)._longfred-ota._tcp. Leaving the screen disables it. STA HTTP is firmware + GET settings/page only (no PUT settings, noprogramming-mode/off). After OTA the throttle reboots onto layout Wi-Fi.Flash writes take a mutex. CI publishes
.app.binartifacts; size-check covers the new slot.Test plan
make build VARIANT=markwtechmake build VARIANT=longfred-standard*+ Stop for 8 s enters provisioningupdate-firmware --mode usbwith ELF +partitions.csvupdate-firmware --mode ap --file *.app.binscan --mode lan/update-firmware --mode lan --host <ipv4> --file *.app.bin