mirror of
https://github.com/MarekZegare4/MeshCore-Solo.git
synced 2026-09-14 15:16:40 +00:00
merge: 1.26 into main
Scope/repeater-scope filtering, magnetic Hall-sensor screen lock, solo build configs restructured into their own solo/<board>/ folder (one _solo_dual build per board), ProMicro + CardKB support (PR #31, tchellow), new Build Flags reference doc, book-order fullscreen message paging, and a confirmed "Start OTA" admin action -- plus a full pre-merge documentation audit. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
@@ -26,7 +26,7 @@ jobs:
|
||||
- name: List solo_dual envs
|
||||
id: list-envs
|
||||
run: |
|
||||
envs=$(grep -rh '^\[env:' platformio.ini variants/ \
|
||||
envs=$(grep -rh '^\[env:' solo/ \
|
||||
| sed 's/\[env://;s/\]//' \
|
||||
| grep '_solo_dual$' \
|
||||
| jq -R -s -c 'split("\n") | map(select(length > 0))')
|
||||
|
||||
@@ -7,6 +7,7 @@ on:
|
||||
- 'src/**'
|
||||
- 'examples/**'
|
||||
- 'variants/**'
|
||||
- 'solo/**'
|
||||
- 'platformio.ini'
|
||||
- '.github/workflows/pr-build-check.yml'
|
||||
push:
|
||||
@@ -15,6 +16,7 @@ on:
|
||||
- 'src/**'
|
||||
- 'examples/**'
|
||||
- 'variants/**'
|
||||
- 'solo/**'
|
||||
- 'platformio.ini'
|
||||
- '.github/workflows/pr-build-check.yml'
|
||||
|
||||
|
||||
@@ -15,16 +15,18 @@ Solo firmware thread: https://discord.com/channels/1495203904898728149/150529433
|
||||
| Seeed Wio Tracker L1 (OLED) | nRF52840 | SSD1306 / SH1106 128 × 64 | `solo-<version>-WioTrackerL1.uf2` |
|
||||
| Seeed Wio Tracker L1 (E-ink) | nRF52840 | GxEPD2 250 × 122 | `solo-<version>-WioTrackerL1Eink.uf2` |
|
||||
| GAT562 30S Mesh Kit | nRF52840 | SSD1306 128 × 64 | `solo-<version>-GAT562-30S-Mesh-Kit.uf2` |
|
||||
| GAT562 Mesh Watch13 *(experimental)* | nRF52840 | SSD1306 128 × 64 | `solo-<version>-GAT562-Mesh-Watch13.uf2` |
|
||||
| Heltec LoRa32 V3 *(experimental)* | ESP32-S3 | SSD1306 128 × 64 | `solo-<version>-Heltec-v3-merged.bin` |
|
||||
| Heltec LoRa32 V4 *(experimental)* | ESP32-S3 | SSD1306 128 × 64 | `solo-<version>-heltec-v4-merged.bin` |
|
||||
| M5Stack Cardputer ADV *(experimental)* | ESP32-S3 | ST7789 TFT 240 × 135 | `solo-<version>-M5Stack-Cardputer-ADV-merged.bin` |
|
||||
| LilyGO T-Echo Lite + KeyShield *(experimental)* | nRF52840 | GxEPD2 250 × 122 | `solo-<version>-LilyGo-T-Echo-Lite-keyshield.uf2` |
|
||||
| ProMicro *(experimental)* | nRF52840 | SSD1306 128 × 64 | `solo-<version>-ProMicro.uf2` |
|
||||
|
||||
All firmware files are published on the [releases page](https://github.com/MarekZegare4/MeshCore-Solo/releases). Each binary supports both BLE and USB serial — there are no separate BLE/USB builds.
|
||||
|
||||
The MCU column decides how you flash: nRF52840 boards take a drag-and-drop `.uf2`, ESP32-S3 boards take a `.bin` written with a flasher — see [Flashing](#flashing).
|
||||
|
||||
The Wio Tracker L1s, GAT562 and Cardputer ADV work out of the box (the Cardputer has a built-in QWERTY keyboard). Heltec V3/V4 need [a keyboard or joystick wired up](#hardware-setup--heltec-v3--v4) first. The T-Echo Lite needs the KeyShield add-on (its own T9 keypad) to be usable standalone — see [External Keyboard & Joystick](./docs/solo_features/external_keyboard.md).
|
||||
The Wio Tracker L1s, both GAT562 boards and Cardputer ADV work out of the box (the Cardputer has a built-in QWERTY keyboard). Heltec V3/V4 need [a keyboard or joystick wired up](#hardware-setup--heltec-v3--v4) first. The T-Echo Lite needs the KeyShield add-on (its own T9 keypad) to be usable standalone. ProMicro has no onboard buttons at all — a CardKB is required, sharing the board's primary I2C bus — see [External Keyboard & Joystick](./docs/solo_features/external_keyboard.md).
|
||||
|
||||
<!-- **Enclosures (Wio Tracker L1)**
|
||||
- [E-ink case](https://www.printables.com/model/1420534-seeed-wio-tracker-l1-e-ink-enclosure)
|
||||
@@ -136,7 +138,7 @@ Each joystick contact simply shorts its pin to GND — the firmware enables the
|
||||
|
||||
Either device is enough on its own — unwired pins read as not-pressed, and a missing CardKB just isn't detected at boot. For **CardKB-only**, wire just SDA/SCL and set Settings › Keyboard › **Ext. KB = Compact**, which needs no joystick at all.
|
||||
|
||||
These are only defaults, set in the `[env:Heltec_v3_companion_solo_dual]` / `[env:heltec_v4_companion_solo_dual]` blocks in [`variants/heltec_v3/platformio.ini`](./variants/heltec_v3/platformio.ini) and [`variants/heltec_v4/platformio.ini`](./variants/heltec_v4/platformio.ini) — comments there list which GPIOs are already claimed. Full details in [External Keyboard & Joystick](./docs/solo_features/external_keyboard.md).
|
||||
These are only defaults, set in the `[env:Heltec_v3_companion_solo_dual]` / `[env:heltec_v4_companion_solo_dual]` blocks in [`solo/heltec_v3/platformio.ini`](./solo/heltec_v3/platformio.ini) and [`solo/heltec_v4/platformio.ini`](./solo/heltec_v4/platformio.ini) — comments there list which GPIOs are already claimed. Full details in [External Keyboard & Joystick](./docs/solo_features/external_keyboard.md).
|
||||
|
||||
---
|
||||
|
||||
@@ -153,6 +155,7 @@ These are only defaults, set in the `[env:Heltec_v3_companion_solo_dual]` / `[en
|
||||
| [Screen Lock](./docs/solo_features/screen_lock/screen_lock.md) | Lock/unlock sequence, lock screen, auto-lock |
|
||||
| [Tools Screen](./docs/solo_features/tools_screen/tools_screen.md) | GPS trail & waypoints, compass, navigation, nearby nodes, ringtone editor, remote bot, auto-advert, live location sharing, locator, diagnostics, repeater, remote admin |
|
||||
| [External Keyboard & Joystick](./docs/solo_features/external_keyboard.md) | CardKB shortcuts, Full vs Compact mode, wired joystick, Heltec V3/V4 wiring |
|
||||
| [Build Flags](./docs/solo_features/build_flags.md) | Every optional `-D` build flag a solo build understands — GPIO, Hall sensor, buzzer/vibration, GPS switch, display/battery tuning |
|
||||
| [Solo UI framework](./docs/design/solo_ui_framework.md) | **Developer guide** — the reusable building blocks (screens, lists, popups, mini-icons, geo/persistence helpers) and how to add a new feature |
|
||||
| [Feature roadmap](./docs/development/roadmap.md) | **Developer notes** — planned / done / rejected features and the code-audit backlog |
|
||||
|
||||
@@ -204,10 +207,12 @@ git config merge.ours.driver true
|
||||
| `WioTrackerL1_companion_solo_dual` | Wio Tracker L1 (OLED) |
|
||||
| `WioTrackerL1Eink_companion_solo_dual` | Wio Tracker L1 (E-ink) |
|
||||
| `GAT562_30S_Mesh_Kit_solo_dual` | GAT562 30S Mesh Kit |
|
||||
| `GAT562_Mesh_Watch13_solo_dual` | GAT562 Mesh Watch13 *(experimental)* |
|
||||
| `Heltec_v3_companion_solo_dual` | Heltec LoRa32 V3 *(experimental)* |
|
||||
| `heltec_v4_companion_solo_dual` | Heltec LoRa32 V4 *(experimental)* |
|
||||
| `M5Stack_Cardputer_ADV_companion_solo_dual` | M5Stack Cardputer ADV *(experimental)* |
|
||||
| `LilyGo_T-Echo-Lite_keyshield_companion_solo_dual` | LilyGO T-Echo Lite + KeyShield *(experimental)* |
|
||||
| `ProMicro_companion_solo_dual` | ProMicro (nRF52840) + CardKB *(experimental)* |
|
||||
|
||||
```sh
|
||||
pio run -e <env> # build only
|
||||
@@ -217,6 +222,11 @@ FIRMWARE_VERSION=v1.0.0 bash build.sh build-firmware <env> # release artifacts i
|
||||
|
||||
The last command runs the same path CI does: a `.uf2` + DFU `.zip` on nRF52, or an app-only `.bin` plus a `-merged.bin` on ESP32. Releases carry the `.uf2`, the `.zip` and the `-merged.bin` only.
|
||||
|
||||
Every environment above builds as-is with no extra hardware required. If you've
|
||||
wired up something extra — CardKB, a joystick, GPIO, a magnetic cover sensor,
|
||||
a buzzer — see [Build Flags](./docs/solo_features/build_flags.md) for the full
|
||||
list of optional `-D` flags to add to your own `solo/<board>/platformio.ini`.
|
||||
|
||||
### Releasing
|
||||
|
||||
Pushing a `v*` tag runs [Build Solo Firmwares](./.github/workflows/build-solo-firmwares.yml), which discovers every `*_solo_dual` environment automatically, builds them all and opens a **draft** release with the artifacts attached. Write the notes from `release-notes.md` and publish it. See [RELEASE.md](./RELEASE.md) for the upstream companion/repeater/room-server tags.
|
||||
@@ -228,6 +238,7 @@ Pushing a `v*` tag runs [Build Solo Firmwares](./.github/workflows/build-solo-fi
|
||||
| `examples/companion_radio/ui-new/` | the solo UI — screens, widgets, `UITask` |
|
||||
| `src/helpers/ui/` | display drivers, fonts, buttons, buzzer |
|
||||
| `variants/<board>/` | per-board `platformio.ini`, `target.h`, `target.cpp` |
|
||||
| `solo/<board>/` | that board's solo (`*_solo_dual`) environment — kept separate from `variants/` so this fork's Solo-specific additions don't mix into configs upstream/other forks also carry |
|
||||
| `docs/solo_features/` | user documentation for this fork |
|
||||
| `docs/design/`, `docs/development/` | developer notes and the feature roadmap |
|
||||
| `tools/` | host-side helpers (screenshot, GPX export, font conversion) |
|
||||
@@ -244,5 +255,6 @@ Big thanks to the people who contributed to this fork:
|
||||
|
||||
- [vanous](https://github.com/vanous)
|
||||
- [marczykm](https://github.com/marczykm)
|
||||
- [tchellow](https://github.com/tchellow)
|
||||
|
||||
Built on upstream [MeshCore](https://github.com/meshcore-dev/MeshCore) and its [community](https://github.com/meshcore-dev/MeshCore/graphs/contributors).
|
||||
|
||||
@@ -40,12 +40,19 @@ Shutdown reason codes (stored in GPREGRET2):
|
||||
| Seeed Studio XIAO nRF52840 (`xiao_nrf52`) | Yes | Yes | Yes |
|
||||
| RAK4631 (`rak4631`) | Yes | Yes | Yes |
|
||||
| Heltec T114 (`heltec_t114`) | Yes | Yes | Yes |
|
||||
| Heltec T1 (`heltec_t1`) | Yes | Yes | Yes |
|
||||
| Heltec T096 (`heltec_t096`) | Yes | Yes | Yes |
|
||||
| Heltec Tower V2 (`heltec_tower_v2`) | Yes | Yes | Yes |
|
||||
| GAT562 30S Mesh Kit (`gat562_30s_mesh_kit`) | Yes | Yes | Yes |
|
||||
| GAT562 Mesh Watch13 | Yes | Yes | Yes |
|
||||
| GAT562 Mesh Tracker Pro (`gat562_mesh_tracker_pro`) | Yes | Yes | Yes |
|
||||
| GAT562 EVB Pro (`gat562_mesh_evb_pro`) | Yes | Yes | Yes |
|
||||
| muzi works R1 Neo (`muziworks_r1_neo`) | Yes | Yes | Yes |
|
||||
| SenseCAP Solar | Yes | Yes | Yes |
|
||||
| RAK 3401 (`rak3401`) | Yes | Yes | Yes |
|
||||
| Promicro nRF52840 | No | No | No |
|
||||
| RAK WisMesh Tag | No | No | No |
|
||||
| Heltec Mesh Solar | No | No | No |
|
||||
| LilyGo T-Echo / T-Echo Lite | No | No | No |
|
||||
| SenseCAP Solar | Yes | Yes | Yes |
|
||||
| WIO Tracker L1 / L1 E-Ink | No | No | No |
|
||||
| WIO WM1110 | No | No | No |
|
||||
| Mesh Pocket | No | No | No |
|
||||
|
||||
@@ -0,0 +1,99 @@
|
||||
## Build Flags
|
||||
|
||||
[Go back](../../README.md)
|
||||
|
||||
Reference for the `-D` build flags a Solo build understands beyond the
|
||||
per-board defaults already set in `solo/<board>/platformio.ini`. Add any of
|
||||
these to your own board's `build_flags` (in `solo/<board>/platformio.ini`) to
|
||||
enable optional hardware you've wired up yourself, or to tune a default.
|
||||
Everything below is a no-op when left unset — adding a flag for hardware that
|
||||
isn't there costs nothing and can't brick a build; the exceptions (pin
|
||||
conflicts, wrong polarity) are called out per flag.
|
||||
|
||||
None of this needs touching to get a board running — see the
|
||||
[environment table](../../README.md#building-from-source) for the flag-free
|
||||
default build for each supported board.
|
||||
|
||||
---
|
||||
|
||||
### Already part of every solo build
|
||||
|
||||
Set once per board in `solo/<board>/platformio.ini`, not usually touched
|
||||
per-user. Listed here so the rest of this page can assume them.
|
||||
|
||||
| Flag | Meaning |
|
||||
| --- | --- |
|
||||
| `FIRMWARE_SOLO_BUILD=1` | Marks the build as Solo (full on-device UI) rather than a companion-only firmware. |
|
||||
| `DUAL_SERIAL=1` | The companion app can attach over BLE *or* USB serial, whichever it finds; BLE wins if both are live. Every solo build sets this — Solo standardises on one build per board rather than splitting BLE-only / USB-only variants. |
|
||||
| `MAX_CONTACTS=<n>` | Size of the contact table. Default is 32 if unset; solo builds set 350. |
|
||||
| `MAX_GROUP_CHANNELS=<n>` | Size of the channel list. Required for channel support to compile in at all — not optional the way the rest of this page is. |
|
||||
| `OFFLINE_QUEUE_SIZE=<n>` | How many messages queue for later delivery while the phone app is disconnected. Default 16; solo builds set 256. |
|
||||
| `UI_SENSORS_PAGE=1` | Enables the on-device sensors dashboard page. |
|
||||
| `BLE_PIN_CODE=<n>` | See below — not a plain fixed value in practice. |
|
||||
| `DISPLAY_CLASS=<Class>` | Selects the display driver (e.g. `SSD1306Display`, `GxEPDDisplay`, `ST7789Display` — see `src/helpers/ui/` for the full set). Fixed by whatever panel the board actually has; only relevant if you're wiring on a *different* display than stock, in which case the matching driver's `.cpp` also needs adding to `build_src_filter`. |
|
||||
|
||||
**`BLE_PIN_CODE`** has a special case baked in: if it's left at the literal
|
||||
value `123456` *and* the board has a display, pairing uses a random 6-digit
|
||||
PIN generated fresh each session and shown on-device, rather than a fixed one.
|
||||
Any other numeric value is used as a static PIN instead. Leaving the flag out
|
||||
entirely disables the PIN prompt (BLE pairing is unauthenticated).
|
||||
|
||||
---
|
||||
|
||||
### Input hardware add-ons
|
||||
|
||||
Each of these assumes you're wiring something up yourself — check pins are
|
||||
actually free on your board first (see the board's `variant.h` and its
|
||||
existing `solo/<board>/platformio.ini` for what's already claimed).
|
||||
|
||||
| Flag | Adds |
|
||||
| --- | --- |
|
||||
| `ENV_PIN_SDA` / `ENV_PIN_SCL` | CardKB (M5Stack I2C keyboard, addr `0x5F`) on a second I2C bus (resolves to `Wire1`). Probed at boot — harmless with nothing plugged in. See [External Keyboard & Joystick](./external_keyboard.md). |
|
||||
| `CARDKB_I2C=<Wire\|Wire1>` | Same CardKB support, naming the bus directly — for a board with no free pins for a second bus, set `CARDKB_I2C=Wire` to share the primary bus (already used by the display/RTC) instead of defining `ENV_PIN_SDA`/`ENV_PIN_SCL`. Takes precedence if both are somehow set. |
|
||||
| `UI_HAS_JOYSTICK=1` + `UI_HAS_JOYSTICK_UPDOWN=1` (optional) + `JOYSTICK_UP` / `JOYSTICK_DOWN` / `JOYSTICK_LEFT` / `JOYSTICK_RIGHT` + `PIN_USER_BTN` + `PIN_BACK_BTN` | A wired joystick (four direction contacts + a press contact for Enter). Replaces single-button navigation entirely once enabled. See [External Keyboard & Joystick](./external_keyboard.md). |
|
||||
| `PIN_GPIO1` .. `PIN_GPIO4` | Up to four general-purpose pins, each independently switchable between Off / Input / Output (GPIO1/GPIO2 also get an Analog step, if wired to an ADC-capable pin) from Tools › GPIO, and via the `!gpio1`..`!gpio4` bot commands. Not restricted to any particular board — works anywhere the pins are actually free. See [Tools Screen › GPIO](./tools_screen/tools_screen.md#gpio). |
|
||||
| `PIN_HALL_SENSOR` + `HALL_ACTIVE_HIGH=1` (optional) | A Hall-effect or reed sensor for a magnetic flip cover: closing locks and blanks the screen instantly, opening unlocks and wakes it, no combo either way. `HALL_ACTIVE_HIGH` is only for a module wired to pull the pin high (rather than low) when the magnet is near. See [Screen Lock › Magnetic cover](./screen_lock/screen_lock.md#magnetic-cover-hall-sensor). |
|
||||
| `PIN_GPS_SWITCH` | A physical on/off switch for GPS power, read alongside the software GPS toggle — the Tools screen shows `gps off(hw)` / `gps off(sw)` when the two disagree, instead of silently trusting one over the other. |
|
||||
|
||||
---
|
||||
|
||||
### Output / feedback hardware
|
||||
|
||||
| Flag | Adds |
|
||||
| --- | --- |
|
||||
| `PIN_BUZZER` (+ `PIN_BUZZER_EN`, optional) | A passive piezo buzzer, driven by direct PWM (nRF52) or the `NonBlockingRtttl` library (everything else) for RTTTL ringtones and UI beeps. `PIN_BUZZER_EN` is an optional enable line some boards wire separately from the signal pin. |
|
||||
| `PIN_VIBRATION` | A vibration motor for haptic notification, via `GenericVibration`. |
|
||||
|
||||
---
|
||||
|
||||
### GPS
|
||||
|
||||
| Flag | Meaning |
|
||||
| --- | --- |
|
||||
| `ENV_INCLUDE_GPS=1` | Compiles in GPS support (NMEA parsing, location provider) at all. |
|
||||
| `GPS_BAUD_RATE=<n>` | Baud rate for the GPS module's serial link (`Serial1`). Match your module's default. |
|
||||
|
||||
`PIN_GPS_SWITCH` (above) is independent of both — it's a hardware kill switch
|
||||
layered on top of GPS support, not a requirement for it.
|
||||
|
||||
---
|
||||
|
||||
### Display & battery tuning
|
||||
|
||||
| Flag | Meaning |
|
||||
| --- | --- |
|
||||
| `OLED_MISC_FIXED_FONT=1` | Pulls in a full Latin/Greek/Cyrillic 6×9 fixed font (~14 KB flash) so typed text in those alphabets renders as itself instead of block placeholders. Worth it on any board with a keyboard; skip it on space-constrained builds without one. |
|
||||
| `DISPLAY_ROTATION=<0-3>` | Rotates the panel in 90° steps, for a board mounted sideways or upside down. |
|
||||
| `ENABLE_SCREENSHOT` | Lets Solo Tools read the framebuffer over USB to capture a screenshot. |
|
||||
| `KEEP_DISPLAY_ON_USB` | Refreshes the auto-off deadline continuously while externally (USB) powered, so the auto-off timer only starts counting once power is actually removed. Off by default because OLED panels burn in quickly with a permanently-lit screen — only worth enabling for an LCD/e-ink target, or a display you don't mind replacing. |
|
||||
| `AUTO_OFF_MILLIS=<ms>` | How long the display stays on before auto-off. Default 15000 (15s); `0` disables auto-off entirely. |
|
||||
| `UI_RECENT_LIST_SIZE=<n>` | How many entries the recent-activity lists show before scrolling. Default 4. |
|
||||
|
||||
---
|
||||
|
||||
### Misc
|
||||
|
||||
| Flag | Meaning |
|
||||
| --- | --- |
|
||||
| `ADVERT_NAME='"name"'` | Sets the default node name baked into a fresh device, instead of the hex of the first 4 bytes of its public key. Note the doubled quoting — it's a C string literal passed through a build flag. |
|
||||
| `MESHCORE_VERSION='"x.y"'` | Overrides the upstream MeshCore base-version string shown in diagnostics, for boards whose port hasn't been rebased onto the latest yet. Cosmetic only — doesn't change protocol behaviour. |
|
||||
@@ -23,6 +23,7 @@ see [Built-in keyboards](#built-in-keyboards-cardputer-adv-t-echo-lite--keyshiel
|
||||
| Heltec V4 *(experimental)* | ✅ solder to free GPIOs | ✅ solder to free GPIOs |
|
||||
| M5Stack Cardputer ADV *(experimental)* | — | built-in keyboard instead, see below |
|
||||
| LilyGO T-Echo Lite + KeyShield *(experimental)* | — | built-in keypad instead, see below |
|
||||
| ProMicro (nRF52840) *(experimental)* | ✅ shares the primary I2C bus (D8/D7) — no free pins for a second bus | — |
|
||||
|
||||
---
|
||||
|
||||
@@ -35,6 +36,11 @@ for it once at boot — nothing to enable in Settings.
|
||||
The same bus is scanned for environment sensors, so a CardKB and a sensor can
|
||||
share it.
|
||||
|
||||
On a board with no free pins for a second bus (ProMicro), CardKB instead
|
||||
shares the primary bus already used by the display/RTC — set `CARDKB_I2C=Wire`
|
||||
as a build flag rather than `ENV_PIN_SDA`/`ENV_PIN_SCL`. See
|
||||
[Build Flags](./build_flags.md) for both forms.
|
||||
|
||||
### Typing
|
||||
|
||||
Printable characters insert straight at the cursor, bypassing the on-screen grid
|
||||
@@ -115,8 +121,8 @@ hardware**; still worth checking against your own V3 module before soldering.
|
||||
|
||||
Everything above lives in the `[env:Heltec_v3_companion_solo_dual]` /
|
||||
`[env:heltec_v4_companion_solo_dual]` blocks in
|
||||
[`variants/heltec_v3/platformio.ini`](../../variants/heltec_v3/platformio.ini)
|
||||
and [`variants/heltec_v4/platformio.ini`](../../variants/heltec_v4/platformio.ini),
|
||||
[`solo/heltec_v3/platformio.ini`](../../solo/heltec_v3/platformio.ini)
|
||||
and [`solo/heltec_v4/platformio.ini`](../../solo/heltec_v4/platformio.ini),
|
||||
with comments explaining which pins are safe to reuse. To build a CardKB-only
|
||||
device, comment out the joystick block and set Ext. KB to Compact.
|
||||
|
||||
@@ -134,4 +140,5 @@ independent of the CardKB code — a board can have either, or neither.
|
||||
|
||||
Neither keypad follows CardKB's exact Fn-shortcut table (Fn+Enter,
|
||||
Fn+letter accent popups, Tab, Fn+Esc lock) — see each board's own
|
||||
`platformio.ini` / keyboard driver under `variants/` for its current keymap.
|
||||
keyboard driver under `variants/` and its solo `platformio.ini` under `solo/`
|
||||
for its current keymap.
|
||||
|
||||
@@ -74,7 +74,7 @@ Messages appear as chat bubbles sized to their content — **right**-anchored fo
|
||||
| :-----------------------: | :-----------------------: |
|
||||
|  |  |
|
||||
|
||||
Navigate between messages with **LEFT** (newer) and **RIGHT** (older). Long messages scroll with **UP/DOWN**.
|
||||
Navigate between messages like pages in a book — **LEFT** goes back to the older message, **RIGHT** forward to the newer one. The `<` / `>` markers along the bottom edge show which directions still have a message. Long messages scroll with **UP/DOWN**.
|
||||
|
||||
If the message is a reply addressed to someone (`@[nick]`), a **To: nick** bar is shown below the sender name and the body is displayed without the address prefix.
|
||||
|
||||
|
||||
@@ -51,3 +51,14 @@ The display turns off again automatically after 5 seconds of inactivity (or 2 se
|
||||
### Auto-lock
|
||||
|
||||
Enable **Auto-lock** in **Settings › Display** to lock the device automatically whenever the display turns off due to auto-off timeout.
|
||||
|
||||
---
|
||||
|
||||
### Magnetic cover (Hall sensor)
|
||||
|
||||
Optional, user-supplied hardware — no board in this repo has one built in. Wire a Hall-effect or reed sensor to any free GPIO, then set `PIN_HALL_SENSOR` (and `HALL_ACTIVE_HIGH=1`, if your module pulls the pin high rather than low when the magnet is present) as `build_flags` in your own env. No-op entirely unless `PIN_HALL_SENSOR` is defined.
|
||||
|
||||
Fully autonomous, independent of Auto-lock and of any key combo:
|
||||
|
||||
- **Magnet near (cover closed)** — locks and blanks the display immediately, no wake grace.
|
||||
- **Magnet away (cover opened)** — unlocks and wakes the display right away.
|
||||
|
||||
@@ -104,6 +104,7 @@ The **repeater** mode and its flood filters live on their own screen — see **T
|
||||
| Layout | ABC / T9 | On-screen keyboard style. **ABC**: a-b-c…z grid, one key per letter. **T9**: phone-keypad multi-tap — each key labelled digit+letters (e.g. `2abc`); repeated **Enter** cycles the letters then the digit. Applies to whichever script page is active, not just Latin. |
|
||||
| Main | Latin / Cyrillic / Greek | Which script the keyboard opens on by default. **Latin** is the default; picking **Cyrillic** or **Greek** makes that the one you land on, with Latin moving to the Additional cycle instead. |
|
||||
| Additional | Latin / Cyrillic / Greek | The second script in the **#@/abc** key's cycle (Main → Additional → Symbols → Main). Setting it to the same script as Main drops the cycle to just that script plus Symbols. **Greek** covers the 24-letter alphabet plus final sigma (`ς`), not the tonos stress accents. Every script renders natively via one shared Unicode font — no separate toggle needed. |
|
||||
| Ext. KB | Full / Compact | Only shown on a build with CardKB support (`CARDKB_I2C` or `ENV_PIN_SDA`/`ENV_PIN_SCL` set). Picks how the on-screen keyboard behaves while a CardKB is doing the typing — see [External Keyboard & Joystick](../external_keyboard.md#ext-kb--full-vs-compact). |
|
||||
|
||||
Applies to every on-screen text field (messages, waypoint labels, room passwords, preset names). Earlier releases labelled the grid *QWERTY*; the layout has always been alphabetical, so it is now named **ABC**.
|
||||
|
||||
|
||||
@@ -568,13 +568,13 @@ Send commands to a **repeater/room server you have admin permission on** — the
|
||||
| **System** | Name, Owner info, Admin password |
|
||||
| **Radio** | Frequency, Bandwidth, Spreading factor, Coding rate, TX power |
|
||||
| **Routing** | Repeat, Advert interval, Flood advert interval, Max hops |
|
||||
| **Actions** | Send advert, Send zero-hop advert, Sync clock, Reboot, **Custom command...** |
|
||||
| **Actions** | Send advert, Send zero-hop advert, Sync clock, Reboot, Start OTA, **Custom command...** |
|
||||
|
||||
**Enter** on a row does one of four things, depending on the field:
|
||||
- **Name / Owner info** first **fetch** the node's current value, then open the keyboard **pre-filled** with it to edit — submitting sends the change. If the fetch fails or times out, the keyboard still opens (blank), so the value can be set blind.
|
||||
- **Radio and Routing rows** are typed, not free text: **Repeat** is an ON/OFF toggle; **Advert interval / Flood advert interval / Max hops / TX power** are number steppers (**LEFT/RIGHT** to adjust, within that field's valid range); **Frequency** uses the same digit-by-digit cursor editor as Settings' own Radio screen (**LEFT/RIGHT** moves between digits, **UP/DOWN** changes the selected one); **Bandwidth / Spreading factor / Coding rate** step through their valid discrete LoRa values with **LEFT/RIGHT**. All four Radio-tuple fields (Frequency/Bandwidth/SF/Coding rate) fetch and re-send the same underlying `radio` value together — editing any one of them still only overwrites that one, the other three round-trip unchanged. **Enter** sends the change; **Cancel** discards it and returns to the row list without sending anything.
|
||||
- **Admin password** has no fetch (there's no way to read a password back) — it opens straight to a blank keyboard.
|
||||
- **Actions** (Reboot, Send advert, …) send immediately, no editing step.
|
||||
- **Actions** (Reboot, Send advert, …) send immediately, no editing step — except **Start OTA**, which asks **Start / Cancel** first (defaulting to Cancel): it puts the remote into BLE DFU mode for the duration of the update, far more disruptive than a quick reboot.
|
||||
- **Custom command...** (last row of Actions) opens the same free-text entry for anything not covered above — up to 160 characters, see the linked reference for the full grammar. The keyboard's **{}** key doubles as command completion here: it lists commands matching whatever's typed since the last space (narrowing as you type), and picking one completes that word instead of just inserting after it.
|
||||
4. **Read the reply** — the text reply opens in a scrollable view (**UP/DOWN** to scroll, **Cancel/Enter** to go back to the category tabs).
|
||||
|
||||
|
||||
@@ -25,6 +25,7 @@
|
||||
|
||||
#include "FullscreenMsgView.h"
|
||||
#include "TabBar.h"
|
||||
#include "PopupMenu.h" // "Start OTA" confirmation
|
||||
#include "RadioParamsEditor.h" // DigitEditor + stepSF/stepBW/stepCR -- same widgets Settings/Repeater use locally
|
||||
#include <helpers/ClientACL.h> // PERM_ACL_ADMIN / PERM_ACL_ROLE_MASK
|
||||
|
||||
@@ -137,6 +138,15 @@ class AdminScreen : public UIScreen {
|
||||
FullscreenMsgView _reply_view;
|
||||
char _reply_text[200] = "";
|
||||
|
||||
// "Start OTA" confirmation -- pulls the remote out of the mesh into BLE DFU
|
||||
// mode for the duration of the update, far more disruptive than the other
|
||||
// one-shot actions on this tab, so unlike Reboot it doesn't fire on a bare
|
||||
// Enter. Only this one action needs a confirm today, so it's special-cased
|
||||
// in activateField() by command string rather than adding a generic
|
||||
// needs_confirm flag to every AdminField literal below.
|
||||
PopupMenu _confirm;
|
||||
const AdminField* _pending_confirm_field = nullptr;
|
||||
|
||||
KeyboardWidget& kb() { return _task->keyboard(); }
|
||||
|
||||
bool isAdminOk(const uint8_t* pub_key) const {
|
||||
@@ -226,6 +236,14 @@ class AdminScreen : public UIScreen {
|
||||
if (f.get_cmd == nullptr && f.set_prefix == nullptr) { // Custom command...
|
||||
openValueKb(_cmd_text, true);
|
||||
} else if (f.set_prefix == nullptr) { // Action
|
||||
if (!strcmp(f.get_cmd, "start ota")) { // see _confirm's comment
|
||||
_pending_confirm_field = &f;
|
||||
_confirm.begin("Start OTA update?", 2);
|
||||
_confirm.addItem("Start");
|
||||
_confirm.addItem("Cancel");
|
||||
_confirm.setSelected(1); // default highlight = Cancel
|
||||
return;
|
||||
}
|
||||
strncpy(_cmd_text, f.get_cmd, sizeof(_cmd_text) - 1);
|
||||
_cmd_text[sizeof(_cmd_text) - 1] = '\0';
|
||||
sendCommand();
|
||||
@@ -333,6 +351,8 @@ public:
|
||||
_value_editing = false;
|
||||
_login_waiting = false;
|
||||
_admin_ok = false;
|
||||
_confirm.active = false;
|
||||
_pending_confirm_field = nullptr;
|
||||
}
|
||||
|
||||
// Canonical entry for a specific target -- called by UITask::openAdminFor(),
|
||||
@@ -519,6 +539,7 @@ public:
|
||||
}
|
||||
}
|
||||
});
|
||||
if (_confirm.active) { _confirm.render(display); return 50; }
|
||||
return _value_editing ? 50 : 2000;
|
||||
}
|
||||
|
||||
@@ -552,6 +573,20 @@ public:
|
||||
}
|
||||
|
||||
if (_phase == COMMAND) {
|
||||
if (_confirm.active) {
|
||||
auto res = _confirm.handleInput(c);
|
||||
if (res == PopupMenu::SELECTED) {
|
||||
if (_confirm.selectedIndex() == 0 && _pending_confirm_field) {
|
||||
strncpy(_cmd_text, _pending_confirm_field->get_cmd, sizeof(_cmd_text) - 1);
|
||||
_cmd_text[sizeof(_cmd_text) - 1] = '\0';
|
||||
sendCommand();
|
||||
}
|
||||
_pending_confirm_field = nullptr;
|
||||
} else if (res == PopupMenu::CANCELLED) {
|
||||
_pending_confirm_field = nullptr;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
if (_kb_active) {
|
||||
auto r = kb().handleInput(c);
|
||||
if (r == KeyboardWidget::DONE) {
|
||||
@@ -670,6 +705,7 @@ const AdminScreen::AdminField AdminScreen::ACTION_FIELDS[] = {
|
||||
{ "Send zero-hop advert", "advert.zerohop", nullptr },
|
||||
{ "Sync clock", "clock sync", nullptr },
|
||||
{ "Reboot", "reboot", nullptr }, // disruptive + no confirm: keep off the default row
|
||||
{ "Start OTA", "start ota", nullptr }, // confirmed first -- see _confirm's comment
|
||||
{ "Custom command...", nullptr, nullptr },
|
||||
};
|
||||
|
||||
|
||||
@@ -157,12 +157,14 @@ struct FullscreenMsgView {
|
||||
display.print(s_wrap_lines[scroll + i]);
|
||||
}
|
||||
drawScrollIndicator(display, startY, visible * lineH, lcount, visible, scroll);
|
||||
// Page markers read like a book: the older message is back to the left,
|
||||
// the newer one forward to the right (see handleInput).
|
||||
const int nav_y = display.height() - lineH;
|
||||
if (has_next) {
|
||||
if (has_prev) {
|
||||
display.setCursor(0, nav_y);
|
||||
display.print("<");
|
||||
}
|
||||
if (has_prev) {
|
||||
if (has_next) {
|
||||
display.setCursor(display.width() - cw, nav_y);
|
||||
display.print(">");
|
||||
}
|
||||
@@ -172,8 +174,12 @@ struct FullscreenMsgView {
|
||||
Result handleInput(char c) {
|
||||
if (c == KEY_UP) { if (scroll > 0) scroll--; return NONE; }
|
||||
if (c == KEY_DOWN) { if (scroll < _max_scroll) scroll++; return NONE; }
|
||||
if (keyIsPrev(c)) return NEXT; // page between messages (encoder too)
|
||||
if (keyIsNext(c)) return PREV;
|
||||
// Page between messages (encoder too), in reading order: left goes back to
|
||||
// the older message, right forward to the newer one. PREV/NEXT are named in
|
||||
// message order, and MessagesScreen's _hist_sel counts newest-first, so PREV
|
||||
// (older) is what a left press means.
|
||||
if (keyIsPrev(c)) return PREV;
|
||||
if (keyIsNext(c)) return NEXT;
|
||||
if (c == KEY_CONTEXT_MENU) return REPLY;
|
||||
if (c == KEY_ENTER || c == KEY_CANCEL) return CLOSE;
|
||||
return NONE;
|
||||
|
||||
@@ -77,7 +77,7 @@ class SettingsScreen : public UIScreen {
|
||||
KEYBOARD_TYPE,
|
||||
KEYBOARD_MAIN_ALPHABET,
|
||||
KEYBOARD_ALPHABET,
|
||||
#if defined(ENV_PIN_SDA) && defined(ENV_PIN_SCL)
|
||||
#if defined(CARDKB_I2C)
|
||||
KEYBOARD_CARDKB_COMPACT,
|
||||
#endif
|
||||
// Contacts section
|
||||
@@ -611,7 +611,7 @@ class SettingsScreen : public UIScreen {
|
||||
display.print("Additional");
|
||||
display.setCursor(valCol(display), y);
|
||||
display.print(NodePrefs::keyboardAlphabetLabel(p ? p->keyboard_alt_alphabet : 0));
|
||||
#if defined(ENV_PIN_SDA) && defined(ENV_PIN_SCL)
|
||||
#if defined(CARDKB_I2C)
|
||||
} else if (item == KEYBOARD_CARDKB_COMPACT) {
|
||||
display.print("Ext. KB");
|
||||
display.setCursor(valCol(display), y);
|
||||
@@ -1020,7 +1020,7 @@ public:
|
||||
_dirty = true;
|
||||
return true;
|
||||
}
|
||||
#if defined(ENV_PIN_SDA) && defined(ENV_PIN_SCL)
|
||||
#if defined(CARDKB_I2C)
|
||||
if (_selected == KEYBOARD_CARDKB_COMPACT && p && (left || right || enter)) {
|
||||
p->keyboard_cardkb_compact ^= 1;
|
||||
_dirty = true;
|
||||
|
||||
@@ -1397,11 +1397,25 @@ void UITask::begin(DisplayDriver* display, SensorManager* sensors, NodePrefs* no
|
||||
uint32_t aoff = autoOffMillis();
|
||||
_auto_off = millis() + (aoff > 0 ? aoff : AUTO_OFF_MILLIS);
|
||||
|
||||
#if defined(ENV_PIN_SDA) && defined(ENV_PIN_SCL)
|
||||
// Wire1 is already brought up by sensors.begin() (EnvironmentSensorManager),
|
||||
// which runs before this -- just probe for a CardKB sitting on it.
|
||||
Wire1.beginTransmission(0x5F);
|
||||
_has_cardkb = (Wire1.endTransmission() == 0);
|
||||
#if defined(CARDKB_I2C)
|
||||
// On the ENV_PIN_SDA/SCL path, CARDKB_I2C is Wire1, already brought up by
|
||||
// sensors.begin() (EnvironmentSensorManager), which runs before this. On
|
||||
// boards that set CARDKB_I2C=Wire directly in platformio.ini, that bus is
|
||||
// brought up by the board's own begin() instead -- also before this.
|
||||
// Either way, just probe for a CardKB sitting on it.
|
||||
CARDKB_I2C.beginTransmission(0x5F);
|
||||
_has_cardkb = (CARDKB_I2C.endTransmission() == 0);
|
||||
#endif
|
||||
|
||||
#if defined(PIN_HALL_SENSOR)
|
||||
// Internal pull matches the default polarity: pulled up so an active-low
|
||||
// sensor reads HIGH at rest, pulled down so an active-high one reads LOW at
|
||||
// rest. Most reed/Hall breakouts are open-drain, active-low -- HALL_ACTIVE_HIGH
|
||||
// is only for modules wired the other way.
|
||||
pinMode(PIN_HALL_SENSOR, HALL_ACTIVE_HIGH ? INPUT_PULLDOWN : INPUT_PULLUP);
|
||||
_hall_magnet_present = HALL_ACTIVE_HIGH ? (digitalRead(PIN_HALL_SENSOR) == HIGH)
|
||||
: (digitalRead(PIN_HALL_SENSOR) == LOW);
|
||||
if (_hall_magnet_present) _locked = true; // booting with the cover already closed
|
||||
#endif
|
||||
|
||||
#if defined(PIN_USER_BTN)
|
||||
@@ -2104,7 +2118,7 @@ bool UITask::dequeueKey(char& c) {
|
||||
return true;
|
||||
}
|
||||
|
||||
#if defined(ENV_PIN_SDA) && defined(ENV_PIN_SCL)
|
||||
#if defined(CARDKB_I2C)
|
||||
// CardKB's "fn" column (key_map in M5Stack's unit_CardKB.cpp): Fn+<physical
|
||||
// key> sends 0x80 + that key's row index, entirely disjoint from every other
|
||||
// code this UI recognises. Indexed by (raw - 0x80); non-letter slots (digits,
|
||||
@@ -2117,7 +2131,7 @@ static const char CARDKB_FN_BASE[48] = {
|
||||
};
|
||||
#endif
|
||||
|
||||
// Poll an optional CardKB (I2C keyboard, addr 0x5F) on Wire1/Grove, feeding
|
||||
// Poll an optional CardKB (I2C keyboard, addr 0x5F) on CARDKB_I2C, feeding
|
||||
// the same key queue as every physical button. Most of its output needs no
|
||||
// translation at all: CardKB's own arrow/Enter/Esc byte codes are already
|
||||
// identical to this UI's KEY_LEFT/UP/DOWN/RIGHT/ENTER/CANCEL (0xB4-0xB7, 13,
|
||||
@@ -2145,7 +2159,7 @@ static const char CARDKB_FN_BASE[48] = {
|
||||
// once), so _cardkb_last_raw debounces it into one press per physical
|
||||
// keypress, same as a MomentaryButton's CLICK event.
|
||||
void UITask::pollCardKB() {
|
||||
#if defined(ENV_PIN_SDA) && defined(ENV_PIN_SCL)
|
||||
#if defined(CARDKB_I2C)
|
||||
if (!_has_cardkb) return;
|
||||
// No artificial throttle: unlike a MomentaryButton (BUTTON_USE_INTERRUPTS
|
||||
// latches every edge in an ISR ring buffer, so it survives a blocking e-ink
|
||||
@@ -2156,9 +2170,9 @@ void UITask::pollCardKB() {
|
||||
// Polling every loop() iteration (same as a digital button's check(), which
|
||||
// has no throttle either) just shrinks that miss window down to exactly the
|
||||
// render() duration instead of render()+30ms.
|
||||
Wire1.requestFrom(0x5F, 1);
|
||||
if (!Wire1.available()) return;
|
||||
uint8_t raw = Wire1.read();
|
||||
CARDKB_I2C.requestFrom(0x5F, 1);
|
||||
if (!CARDKB_I2C.available()) return;
|
||||
uint8_t raw = CARDKB_I2C.read();
|
||||
if (raw == _cardkb_last_raw) return; // still held (or still released) -- no new edge
|
||||
_cardkb_last_raw = raw;
|
||||
if (raw == 0) return; // key just released, nothing to enqueue
|
||||
@@ -2237,6 +2251,50 @@ void UITask::pollCardKB() {
|
||||
#endif
|
||||
}
|
||||
|
||||
// Level-triggered, like pollCardKB() -- a magnet held near the sensor reads the
|
||||
// same way every tick, so this only acts on the two edges (closed/opened), not
|
||||
// on every poll. Fully autonomous: closing locks and blanks the display
|
||||
// immediately (no wake grace -- the cover is physically over the screen, so
|
||||
// there's nothing to show), opening unlocks and wakes it, with no combo or
|
||||
// keypress either way. Independent of Auto-lock (Settings > Display), which is
|
||||
// a timeout-driven setting -- this is a direct physical event.
|
||||
//
|
||||
// Debounced against a mechanical reed switch chattering for a few ms as the
|
||||
// magnet crosses the trigger distance -- a raw flip only becomes the new
|
||||
// _hall_magnet_present once it's been steady for HALL_DEBOUNCE_MS, so a bounce
|
||||
// can't fire the lock/unlock actions (each including a full display
|
||||
// off/on -- slow and disruptive on e-ink) more than once per real transition.
|
||||
void UITask::pollHallSensor() {
|
||||
#if defined(PIN_HALL_SENSOR)
|
||||
bool raw = HALL_ACTIVE_HIGH ? (digitalRead(PIN_HALL_SENSOR) == HIGH)
|
||||
: (digitalRead(PIN_HALL_SENSOR) == LOW);
|
||||
if (raw != _hall_candidate) {
|
||||
_hall_candidate = raw;
|
||||
_hall_candidate_since = millis();
|
||||
}
|
||||
if (_hall_candidate == _hall_magnet_present) return; // no debounced change yet
|
||||
if (millis() - _hall_candidate_since < HALL_DEBOUNCE_MS) return; // not steady long enough
|
||||
|
||||
bool present = _hall_candidate;
|
||||
_hall_magnet_present = present;
|
||||
|
||||
if (present) { // cover closed
|
||||
_locked = true;
|
||||
_lock_wake_until = 0;
|
||||
if (_display) _display->turnOff();
|
||||
#ifdef PIN_LED
|
||||
digitalWrite(PIN_LED, LOW); // same as the auto-off path -- one less thing lit under a closed cover
|
||||
#endif
|
||||
} else { // cover opened
|
||||
_locked = false;
|
||||
if (_display && !_display->isOn()) _display->turnOn();
|
||||
uint32_t aoff = autoOffMillis();
|
||||
if (aoff > 0) _auto_off = millis() + aoff;
|
||||
}
|
||||
_next_refresh = 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
void UITask::loop() {
|
||||
// Background delivery: resend pending on-device DMs whose ACK timed out, and
|
||||
// finalise the ✗ marker — runs regardless of which screen is active.
|
||||
@@ -2335,6 +2393,7 @@ void UITask::loop() {
|
||||
}
|
||||
#endif
|
||||
pollCardKB();
|
||||
pollHallSensor();
|
||||
#ifdef ENV_USE_TCA8418
|
||||
{
|
||||
extern char tca8418_keypad_read(); // provided by the active variant
|
||||
@@ -2480,7 +2539,7 @@ void UITask::loop() {
|
||||
}
|
||||
// Hint popup at bottom (like alert style)
|
||||
_display->setTextSize(1);
|
||||
#if defined(ENV_PIN_SDA) && defined(ENV_PIN_SCL)
|
||||
#if defined(CARDKB_I2C)
|
||||
const char* hint = _lock_seq_count == 0 ? (_has_cardkb ? "Back+3xEnter/Fn+Esc" : "Hold Back + 3xEnter") :
|
||||
_lock_seq_count == 1 ? "Enter x2 more..." : "Enter x1 more...";
|
||||
#else
|
||||
|
||||
@@ -23,6 +23,21 @@
|
||||
#include "../AbstractUITask.h"
|
||||
#include "../NodePrefs.h"
|
||||
#include "../Trail.h"
|
||||
|
||||
// Optional M5Stack CardKB (I2C keyboard, addr 0x5F). CARDKB_I2C names which
|
||||
// TwoWire it lives on -- set at file scope (not inside the class body, and
|
||||
// not resolved via an #elif ladder) so both this header and SettingsScreen.h
|
||||
// see a fully-resolved macro no matter which one gets included first.
|
||||
// - Boards with a free second I2C bus define ENV_PIN_SDA/ENV_PIN_SCL
|
||||
// (already brought up for EnvironmentSensorManager) and get Wire1 here,
|
||||
// same as before.
|
||||
// - Boards without a free second bus set -D CARDKB_I2C=Wire directly in
|
||||
// platformio.ini, sharing whatever bus the display/RTC already use.
|
||||
// Either way it's a no-op on boards that define neither, or when nothing
|
||||
// ACKs 0x5F at boot.
|
||||
#if !defined(CARDKB_I2C) && defined(ENV_PIN_SDA) && defined(ENV_PIN_SCL)
|
||||
#define CARDKB_I2C Wire1
|
||||
#endif
|
||||
#include "../Waypoint.h"
|
||||
#include "../LiveTrack.h"
|
||||
#include "KeyboardWidget.h"
|
||||
@@ -193,12 +208,9 @@ class UITask : public AbstractUITask {
|
||||
void enqueueKey(char c);
|
||||
bool dequeueKey(char& c);
|
||||
|
||||
// Optional M5Stack CardKB (I2C keyboard, addr 0x5F) on the Grove/Wire1 bus
|
||||
// -- reuses ENV_PIN_SDA/ENV_PIN_SCL (already brought up for
|
||||
// EnvironmentSensorManager) as the "this board has a second I2C bus" gate,
|
||||
// rather than a new board-specific pin define. No-op entirely on boards
|
||||
// without that bus, or when nothing ACKs 0x5F at boot.
|
||||
#if defined(ENV_PIN_SDA) && defined(ENV_PIN_SCL)
|
||||
// Optional M5Stack CardKB (I2C keyboard, addr 0x5F). See the CARDKB_I2C
|
||||
// definition near the top of this file for which bus it's on and why.
|
||||
#if defined(CARDKB_I2C)
|
||||
bool _has_cardkb = false;
|
||||
// CardKB is level-triggered, not edge-triggered -- it keeps returning the
|
||||
// same byte for as long as the physical key is held, not just once. Track
|
||||
@@ -208,6 +220,27 @@ class UITask : public AbstractUITask {
|
||||
#endif
|
||||
void pollCardKB();
|
||||
|
||||
// Optional magnetic "flip cover" lock: a Hall-effect or reed sensor wired to
|
||||
// any free GPIO, closing (pulling active) when a magnet is near. Entirely
|
||||
// user-supplied -- no board in this repo ships one, so PIN_HALL_SENSOR must
|
||||
// be added as a build_flag by whoever wires the sensor up; no-op everywhere
|
||||
// else. HALL_ACTIVE_HIGH overrides the default polarity for modules that
|
||||
// pull the pin HIGH (instead of LOW) when the magnet is present.
|
||||
#if defined(PIN_HALL_SENSOR)
|
||||
#ifndef HALL_ACTIVE_HIGH
|
||||
#define HALL_ACTIVE_HIGH 0
|
||||
#endif
|
||||
bool _hall_magnet_present = false;
|
||||
// Contact-bounce guard for a mechanical reed switch (a Hall-effect IC reads
|
||||
// clean, but the docs recommend either): a raw reading only replaces
|
||||
// _hall_magnet_present once it's held steady for HALL_DEBOUNCE_MS, same
|
||||
// threshold and reasoning as MomentaryButton's ISR_DEBOUNCE_MS.
|
||||
static const uint32_t HALL_DEBOUNCE_MS = 25;
|
||||
bool _hall_candidate = false;
|
||||
uint32_t _hall_candidate_since = 0;
|
||||
#endif
|
||||
void pollHallSensor();
|
||||
|
||||
void setCurrScreen(UIScreen* c);
|
||||
|
||||
// Centred alert overlay (the showAlert() box). Wraps long text to up to
|
||||
|
||||
@@ -11,6 +11,7 @@
|
||||
[platformio]
|
||||
extra_configs =
|
||||
variants/*/platformio.ini
|
||||
solo/*/platformio.ini
|
||||
platformio.local.ini
|
||||
|
||||
[arduino_base]
|
||||
|
||||
@@ -3,9 +3,14 @@
|
||||
### What's new
|
||||
|
||||
- **On-device community scope, and repeater-side scope filtering.** Settings › Radio gets a **Scope** field — type a region/community name (e.g. `pl`) and every device typing the same name derives the same shared tag, no key exchange needed; it's what your own DM/channel sends carry, previously only settable from a connected app. Tools › Repeater gains **Scope only** (only relay flood traffic matching your own scope, or one of the new **Extra scopes** below — a no-op until a scope is actually set, so it can't silently blackhole all forwarding) and **Extra scopes** (comma-separated additional regions to relay for, without changing what scope this device's own messages send under).
|
||||
- **Optional magnetic "flip cover" screen lock**, for anyone who wants to wire a Hall-effect or reed sensor to a free GPIO — no board ships one built in. Set `PIN_HALL_SENSOR` as a build flag on your own env and closing the cover locks and blanks the screen instantly, opening it unlocks and wakes it — no combo, independent of Auto-lock. See [Screen Lock](docs/solo_features/screen_lock/screen_lock.md#magnetic-cover-hall-sensor).
|
||||
- **Experimental: solo build for ProMicro (nRF52840)**, with CardKB support sharing the board's primary I2C bus (no free pins for a second one on this board). Contributed by @tchellow — thanks!
|
||||
- **New [Build Flags](docs/solo_features/build_flags.md) reference** — every optional `-D` flag a solo build understands (GPIO, CardKB/joystick, Hall-sensor cover lock, buzzer/vibration, GPS switch, display/battery tuning) in one place.
|
||||
- **Tools › Admin gains a "Start OTA" action** for a repeater/room server you're logged into — sends the same `start ota` CLI command the Custom-command row already reached, now with its own menu row and a confirm ("Start" defaulting to "Cancel" first) since it puts the remote into BLE DFU mode for the duration of the update.
|
||||
|
||||
### Fixes
|
||||
|
||||
- **Paging through the fullscreen message view now reads like a book** — **RIGHT** moves forward to the newer message, **LEFT** back to the older one, and the `<` / `>` markers along the bottom edge follow suit. It was the other way round before.
|
||||
- **Hardware CAD and RSSI interference-threshold detection were silently hardcoded off on companion_radio**, regardless of any setting. CAD now auto-enables whenever RX power-save (duty-cycle) is active — the noise floor isn't kept fresh during duty-cycle sleep, so a fresh hardware channel scan before TX is needed instead of the RSSI-threshold check.
|
||||
- **A long message could split a multi-byte UTF-8 character in half when truncated to fit the send frame** (e.g. a Polish/accented character landing right at the cut-off), delivering a mangled trailing byte to the app. Truncation now stops at the last complete character.
|
||||
- **Deleting the default "Public" channel didn't stick — it came back on every reboot.** A deleted channel is correctly left out of the saved channel file (to avoid rewriting it every save), but the Public channel was unconditionally re-added at every boot *before* the saved list was loaded, so its absence from the file never got a chance to matter. Now only seeded on a genuinely fresh device (no channel file yet) — once you've saved any channel state at all, your own list is authoritative.
|
||||
|
||||
@@ -0,0 +1,52 @@
|
||||
; Solo build for GAT562 30S Mesh Kit -- extends the board base defined in
|
||||
; variants/gat562_30s_mesh_kit/platformio.ini. Solo configs live in their own
|
||||
; top-level solo/ folder, separate from the shared upstream board variants in
|
||||
; variants/, so this repo's Solo-specific additions don't get mixed in with
|
||||
; configs other MeshCore forks/upstream also carry.
|
||||
;
|
||||
; Dual (BLE+USB) only -- the previous BLE-only solo_ble env was dropped since
|
||||
; dual is a strict superset (BLE still works, plus USB) and Solo standardises
|
||||
; on one build per board.
|
||||
[env:GAT562_30S_Mesh_Kit_solo_dual]
|
||||
extends = GAT562_30S_Mesh_Kit
|
||||
board_build.ldscript = boards/nrf52840_s140_v6_extrafs.ld
|
||||
board_upload.maximum_size = 712704
|
||||
; Optimise for size, not speed: the nRF52 Arduino core defaults to -Ofast
|
||||
; (≈ -O3 + -ffast-math), which bloats flash by ~200 KB on this feature-rich
|
||||
; solo build. -Os keeps every feature, fits comfortably, and is actually safer
|
||||
; for float (no fast-math reassociation). Speed is irrelevant for the UI/mesh.
|
||||
build_unflags = -Ofast
|
||||
build_flags =
|
||||
${GAT562_30S_Mesh_Kit.build_flags}
|
||||
-I examples/companion_radio/ui-new
|
||||
-D DISPLAY_CLASS=SSD1306Display
|
||||
-D MAX_CONTACTS=350
|
||||
-D MAX_GROUP_CHANNELS=40
|
||||
-D BLE_PIN_CODE=123456
|
||||
-D OFFLINE_QUEUE_SIZE=256
|
||||
-D FIRMWARE_SOLO_BUILD=1
|
||||
-D MESHCORE_VERSION='"1.17"'
|
||||
-D UI_SENSORS_PAGE=1
|
||||
-D UI_HAS_JOYSTICK_UPDOWN=1
|
||||
-D ADVERT_NAME='"@@MAC"'
|
||||
-D ENV_INCLUDE_GPS=1
|
||||
; misc-fixed 6x9 OLED font (full Latin/Greek/Cyrillic), same as the Wio L1
|
||||
; builds. Solo only: it costs ~14 KB of flash and the repeater/companion
|
||||
; builds have no keyboard to type those alphabets on.
|
||||
-D OLED_MISC_FIXED_FONT=1
|
||||
-D DUAL_SERIAL=1
|
||||
-D ENABLE_SCREENSHOT
|
||||
-Os
|
||||
; QSPIFLASH disabled: QSPI IO0/IO2 pins (P0.30/P0.28) conflict with joystick LEFT/UP
|
||||
; -D MESH_PACKET_LOGGING=1
|
||||
; -D MESH_DEBUG=1
|
||||
build_src_filter = ${GAT562_30S_Mesh_Kit.build_src_filter}
|
||||
+<helpers/nrf52/SerialBLEInterface.cpp>
|
||||
+<helpers/ui/buzzer.cpp>
|
||||
+<../examples/companion_radio/*.cpp>
|
||||
+<../examples/companion_radio/ui-new/*.cpp>
|
||||
lib_deps =
|
||||
${GAT562_30S_Mesh_Kit.lib_deps}
|
||||
adafruit/RTClib @ ^2.1.3
|
||||
densaugeo/base64 @ ~1.4.0
|
||||
end2endzone/NonBlockingRTTTL@^1.3.0
|
||||
@@ -0,0 +1,50 @@
|
||||
; Solo build for GAT562 Mesh Watch13 -- extends the board base defined in
|
||||
; variants/gat562_mesh_watch13/platformio.ini. Solo configs live in their own
|
||||
; top-level solo/ folder, separate from the shared upstream board variants in
|
||||
; variants/, so this repo's Solo-specific additions don't get mixed in with
|
||||
; configs other MeshCore forks/upstream also carry.
|
||||
;
|
||||
; Renamed from the previous BLE-only solo_ble to solo_dual (DUAL_SERIAL added
|
||||
; below) to match every other board's single solo build. This board has no
|
||||
; comment anywhere recording whether its USB data lines are actually broken
|
||||
; out to a connector (only charging pins might be) -- DUAL_SERIAL compiles
|
||||
; and works over BLE regardless, so worst case the USB half just goes unused.
|
||||
[env:GAT562_Mesh_Watch13_solo_dual]
|
||||
extends = GAT562_Mesh_Watch13
|
||||
board_build.ldscript = boards/nrf52840_s140_v6_extrafs.ld
|
||||
board_upload.maximum_size = 712704
|
||||
build_flags =
|
||||
${GAT562_Mesh_Watch13.build_flags}
|
||||
-I examples/companion_radio/ui-new
|
||||
-D DISPLAY_CLASS=SSD1306Display
|
||||
-D MAX_CONTACTS=350
|
||||
-D MAX_GROUP_CHANNELS=40
|
||||
-D BLE_PIN_CODE=123456
|
||||
-D OFFLINE_QUEUE_SIZE=256
|
||||
-D DUAL_SERIAL=1
|
||||
-D FIRMWARE_SOLO_BUILD=1
|
||||
-D MESHCORE_VERSION='"1.17"'
|
||||
-D UI_SENSORS_PAGE=1
|
||||
-D ADVERT_NAME='"@@MAC"'
|
||||
; GPS — re-enable (base undefines it); Serial1 pins 15/16 from variant
|
||||
-D ENV_INCLUDE_GPS=1
|
||||
-D GPS_BAUD_RATE=9600
|
||||
; Buzzer available on IO3 (pin 21) — uncomment to enable
|
||||
; -D PIN_BUZZER=21
|
||||
; -D PIN_VIBRATION=36
|
||||
; -D MESH_PACKET_LOGGING=1
|
||||
; -D MESH_DEBUG=1
|
||||
build_src_filter = ${GAT562_Mesh_Watch13.build_src_filter}
|
||||
+<helpers/nrf52/SerialBLEInterface.cpp>
|
||||
+<helpers/ui/MomentaryButton.cpp>
|
||||
+<helpers/ui/GenericVibration.cpp>
|
||||
+<../examples/companion_radio/*.cpp>
|
||||
+<../examples/companion_radio/ui-new/*.cpp>
|
||||
; If PIN_BUZZER is enabled above, also add:
|
||||
; +<helpers/ui/buzzer.cpp>
|
||||
lib_deps =
|
||||
${GAT562_Mesh_Watch13.lib_deps}
|
||||
adafruit/RTClib @ ^2.1.3
|
||||
densaugeo/base64 @ ~1.4.0
|
||||
; If PIN_BUZZER is enabled, also add:
|
||||
; end2endzone/NonBlockingRTTTL@^1.3.0
|
||||
@@ -0,0 +1,89 @@
|
||||
; Solo build for Heltec LoRa32 V3 -- extends the board base defined in
|
||||
; variants/heltec_v3/platformio.ini. Solo configs live in their own top-level
|
||||
; solo/ folder, separate from the shared upstream board variants in variants/,
|
||||
; so this repo's Solo-specific additions don't get mixed in with configs
|
||||
; other MeshCore forks/upstream also carry.
|
||||
;
|
||||
; Solo build: the full standalone on-device UI (message history, contacts, map,
|
||||
; tools) rather than a screen that only mirrors the phone app. Dual transport --
|
||||
; the companion app can attach over BLE or USB serial, whichever it finds, and
|
||||
; BLE wins while both are live.
|
||||
;
|
||||
; This firmware needs a real input device: the solo UI cannot be driven from the
|
||||
; PRG button alone. Both supported ones are wired up in target.cpp and enabled
|
||||
; below, so either is enough on its own and having both is fine. The pins are
|
||||
; defaults picked from what this board leaves free -- change them to match how
|
||||
; the device is actually built. Pins with nothing attached read as not-pressed,
|
||||
; so the unused half costs nothing.
|
||||
;
|
||||
; * CardKB (M5Stack I2C keyboard, addr 0x5F) on a second I2C bus. Any two free
|
||||
; GPIOs -- NOT 17/18, the OLED already owns those on Wire. It's probed at
|
||||
; boot, so a build with these set still runs fine with nothing plugged in.
|
||||
; Pair it with Settings > Keyboard > Ext. KB = Compact, which is designed to
|
||||
; need no joystick at all. The same bus is scanned for environment sensors.
|
||||
;
|
||||
; * Wired joystick: four direction pins plus a fifth "press" contact. The
|
||||
; press contact drives Enter (your thumb's already on the stick) via
|
||||
; PIN_USER_BTN -- overridden below (a later -D wins, no -U needed: this whole
|
||||
; project builds with -w) from the PRG-button default
|
||||
; the base env sets, since PRG's GPIO0 can't be moved to the stick. PRG
|
||||
; becomes Back instead (PIN_BACK_BTN), so it no longer needs its own
|
||||
; separately-wired button. Each contact just shorts its pin to GND;
|
||||
; target.cpp enables the internal pull-ups. Drop
|
||||
; UI_HAS_JOYSTICK_UPDOWN for a left/right-only stick. JOYSTICK_ROTATION (0-3)
|
||||
; rotates the mapping if the stick is mounted sideways -- it's also a runtime
|
||||
; setting, so leave it out unless you want a different default.
|
||||
; Comment the whole block out for a CardKB-only build. UI_HAS_JOYSTICK
|
||||
; replaces the single-button handling rather than adding to it (UITask.cpp
|
||||
; dispatches on '#if UI_HAS_JOYSTICK ... #elif defined(PIN_USER_BTN)'), which
|
||||
; costs nothing here -- that fallback only feeds KEY_NEXT/KEY_PREV, which the
|
||||
; solo screens don't act on.
|
||||
;
|
||||
; V3 and V4 are pin-compatible per Heltec's own docs, so the defaults below are
|
||||
; carried over from the heltec_v4_companion_solo_dual env, where this exact
|
||||
; CardKB + joystick combination is confirmed working on real hardware -- still
|
||||
; worth checking against your own V3 module before soldering, but not a blind
|
||||
; guess like the earlier SDA 41/SCL 42 default was. PIN_GPS_RX=47/TX=48/EN=26
|
||||
; above are dead defines on V3 (ENV_INCLUDE_GPS is never set to 1 in this file),
|
||||
; so they don't conflict with reusing 47/48 here despite the name.
|
||||
[env:Heltec_v3_companion_solo_dual]
|
||||
extends = Heltec_lora32_v3
|
||||
build_flags =
|
||||
${Heltec_lora32_v3.build_flags}
|
||||
-I examples/companion_radio/ui-new
|
||||
-D MAX_CONTACTS=350
|
||||
-D MAX_GROUP_CHANNELS=40
|
||||
-D DISPLAY_CLASS=SSD1306Display
|
||||
-D BLE_PIN_CODE=123456 ; dynamic, random PIN
|
||||
-D DUAL_SERIAL=1 ; companion app over BLE *or* USB serial
|
||||
-D OFFLINE_QUEUE_SIZE=256
|
||||
-D FIRMWARE_SOLO_BUILD=1
|
||||
-D UI_SENSORS_PAGE=1
|
||||
-D OLED_MISC_FIXED_FONT=1 ; full Latin/Greek/Cyrillic 6x9 font, ~14 KB flash
|
||||
-D ENABLE_SCREENSHOT ; same as the other solo builds — Solo Tools reads the framebuffer over USB
|
||||
; CardKB on the second I2C bus. Harmless with nothing plugged in.
|
||||
-D ENV_PIN_SDA=3
|
||||
-D ENV_PIN_SCL=4
|
||||
; Wired joystick — comment the block out for a CardKB-only build. The
|
||||
; press contact (Enter) overrides PIN_USER_BTN from its PRG default;
|
||||
; PRG becomes Back (PIN_BACK_BTN) instead.
|
||||
-D UI_HAS_JOYSTICK=1
|
||||
-D UI_HAS_JOYSTICK_UPDOWN=1
|
||||
-D JOYSTICK_UP=23
|
||||
-D JOYSTICK_DOWN=6
|
||||
-D JOYSTICK_LEFT=47
|
||||
-D JOYSTICK_RIGHT=48
|
||||
-D PIN_BACK_BTN=0 ; PRG button
|
||||
-D PIN_USER_BTN=33 ; joystick press contact -- Enter, overrides the PRG default above
|
||||
; -D PIN_BUZZER=<gpio>
|
||||
build_src_filter = ${Heltec_lora32_v3.build_src_filter}
|
||||
+<helpers/ui/SSD1306Display.cpp>
|
||||
+<helpers/ui/MomentaryButton.cpp>
|
||||
+<helpers/ui/buzzer.cpp>
|
||||
+<helpers/esp32/*.cpp>
|
||||
+<../examples/companion_radio/*.cpp>
|
||||
+<../examples/companion_radio/ui-new/*.cpp>
|
||||
lib_deps =
|
||||
${Heltec_lora32_v3.lib_deps}
|
||||
densaugeo/base64 @ ~1.4.0
|
||||
end2endzone/NonBlockingRTTTL@^1.3.0
|
||||
@@ -0,0 +1,96 @@
|
||||
; Solo build for Heltec LoRa32 V4 -- extends the board base defined in
|
||||
; variants/heltec_v4/platformio.ini. Solo configs live in their own top-level
|
||||
; solo/ folder, separate from the shared upstream board variants in variants/,
|
||||
; so this repo's Solo-specific additions don't get mixed in with configs
|
||||
; other MeshCore forks/upstream also carry.
|
||||
;
|
||||
; Solo build: the full standalone on-device UI (message history, contacts, map,
|
||||
; tools) rather than a screen that only mirrors the phone app. Dual transport --
|
||||
; the companion app can attach over BLE or USB serial, whichever it finds, and
|
||||
; BLE wins while both are live. OLED board only -- the TFT variant would need
|
||||
; its own DISPLAY_CLASS.
|
||||
;
|
||||
; This firmware needs a real input device: the solo UI cannot be driven from the
|
||||
; PRG button alone. Both supported ones are wired up in target.cpp and enabled
|
||||
; below, so either is enough on its own and having both is fine. The pins are
|
||||
; defaults picked from what this board leaves free -- change them to match how
|
||||
; the device is actually built. Pins with nothing attached read as not-pressed,
|
||||
; so the unused half costs nothing.
|
||||
;
|
||||
; * CardKB (M5Stack I2C keyboard, addr 0x5F) on a second I2C bus. Any two free
|
||||
; GPIOs -- NOT 17/18, the OLED already owns those on Wire. It's probed at
|
||||
; boot, so a build with these set still runs fine with nothing plugged in.
|
||||
; Pair it with Settings > Keyboard > Ext. KB = Compact, which is designed to
|
||||
; need no joystick at all. The same bus is scanned for environment sensors.
|
||||
; Defaults below: SDA 3, SCL 4 -- the pins heltec_v4_sensor and
|
||||
; heltec_v4_expansionkit_repeater already use for their second I2C bus, i.e.
|
||||
; the expansion kit's. (Those envs disagree on the order: two say SDA 3 /
|
||||
; SCL 4, one says the reverse. 3/4 is the pair either way; swap them if the
|
||||
; keyboard doesn't answer.)
|
||||
;
|
||||
; * Wired joystick: four direction pins plus a fifth "press" contact. The
|
||||
; press contact drives Enter (your thumb's already on the stick) via
|
||||
; PIN_USER_BTN -- overridden below (a later -D wins, no -U needed: this whole
|
||||
; project builds with -w) from the PRG-button default
|
||||
; the base env sets, since PRG's GPIO0 can't be moved to the stick. PRG
|
||||
; becomes Back instead (PIN_BACK_BTN), so it no longer needs its own
|
||||
; separately-wired button. Each contact just shorts its pin to GND;
|
||||
; target.cpp enables the internal pull-ups. Drop
|
||||
; UI_HAS_JOYSTICK_UPDOWN for a left/right-only stick. JOYSTICK_ROTATION (0-3)
|
||||
; rotates the mapping if the stick is mounted sideways -- it's also a runtime
|
||||
; setting, so leave it out unless you want a different default.
|
||||
; Comment the whole block out for a CardKB-only build. UI_HAS_JOYSTICK
|
||||
; replaces the single-button handling rather than adding to it (UITask.cpp
|
||||
; dispatches on '#if UI_HAS_JOYSTICK ... #elif defined(PIN_USER_BTN)'), which
|
||||
; costs nothing here -- that fallback only feeds KEY_NEXT/KEY_PREV, which the
|
||||
; solo screens don't act on.
|
||||
;
|
||||
; Free on this board, per its pinout: 3, 4, 6, 23, 33, 43, 44, 45, 46, 47, 48.
|
||||
; Two of those can't take an I2C pull-up: 45 selects VDD_SPI at boot, so held
|
||||
; high the chip comes up expecting 1.8V flash and won't boot at all, and 46 is
|
||||
; the boot-mode strap. 3 is a strapping pin too, but it only picks the JTAG
|
||||
; source -- and it's what this board's own expansion kit uses for I2C anyway.
|
||||
; 43/44 are UART0: unused by this build, since ARDUINO_USB_CDC_ON_BOOT (set in
|
||||
; boards/heltec_v4.json) makes Serial the native USB port, but a USB-UART bridge
|
||||
; may still be wired to them, so they're left alone.
|
||||
[env:heltec_v4_companion_solo_dual]
|
||||
extends = heltec_v4_oled
|
||||
build_flags =
|
||||
${heltec_v4_oled.build_flags}
|
||||
-I examples/companion_radio/ui-new
|
||||
-D MAX_CONTACTS=350
|
||||
-D MAX_GROUP_CHANNELS=40
|
||||
-D DISPLAY_CLASS=SSD1306Display
|
||||
-D BLE_PIN_CODE=123456 ; dynamic, random PIN
|
||||
-D DUAL_SERIAL=1 ; companion app over BLE *or* USB serial
|
||||
-D OFFLINE_QUEUE_SIZE=256
|
||||
-D FIRMWARE_SOLO_BUILD=1
|
||||
-D UI_SENSORS_PAGE=1
|
||||
-D OLED_MISC_FIXED_FONT=1 ; full Latin/Greek/Cyrillic 6x9 font, ~14 KB flash
|
||||
-D ENABLE_SCREENSHOT ; same as the other solo builds — Solo Tools reads the framebuffer over USB
|
||||
; CardKB on the second I2C bus. Harmless with nothing plugged in.
|
||||
-D ENV_PIN_SDA=3
|
||||
-D ENV_PIN_SCL=4
|
||||
; Wired joystick — comment the block out for a CardKB-only build. The
|
||||
; press contact (Enter) overrides PIN_USER_BTN from its PRG default;
|
||||
; PRG becomes Back (PIN_BACK_BTN) instead.
|
||||
-D UI_HAS_JOYSTICK=1
|
||||
-D UI_HAS_JOYSTICK_UPDOWN=1
|
||||
-D JOYSTICK_UP=23
|
||||
-D JOYSTICK_DOWN=6
|
||||
-D JOYSTICK_LEFT=47
|
||||
-D JOYSTICK_RIGHT=48
|
||||
-D PIN_BACK_BTN=0 ; PRG button
|
||||
-D PIN_USER_BTN=33 ; joystick press contact -- Enter, overrides the PRG default above
|
||||
; -D PIN_BUZZER=<gpio>
|
||||
build_src_filter = ${heltec_v4_oled.build_src_filter}
|
||||
+<helpers/ui/SSD1306Display.cpp>
|
||||
+<helpers/ui/MomentaryButton.cpp>
|
||||
+<helpers/ui/buzzer.cpp>
|
||||
+<helpers/esp32/*.cpp>
|
||||
+<../examples/companion_radio/*.cpp>
|
||||
+<../examples/companion_radio/ui-new/*.cpp>
|
||||
lib_deps =
|
||||
${heltec_v4_oled.lib_deps}
|
||||
densaugeo/base64 @ ~1.4.0
|
||||
end2endzone/NonBlockingRTTTL@^1.3.0
|
||||
@@ -0,0 +1,43 @@
|
||||
; Solo build for LilyGO T-Echo Lite + KeyShield -- extends the board base
|
||||
; defined in variants/lilygo_techo_lite/platformio.ini. Solo configs live in
|
||||
; their own top-level solo/ folder, separate from the shared upstream board
|
||||
; variants in variants/, so this repo's Solo-specific additions don't get
|
||||
; mixed in with configs other MeshCore forks/upstream also carry.
|
||||
;
|
||||
[env:LilyGo_T-Echo-Lite_keyshield_companion_solo_dual]
|
||||
extends = LilyGo_T-Echo-Lite
|
||||
board_build.ldscript = boards/nrf52840_s140_v6_extrafs.ld
|
||||
board_upload.maximum_size = 712704
|
||||
; Optimise for size, not speed: the nRF52 Arduino core defaults to -Ofast
|
||||
; (≈ -O3 + -ffast-math), which bloats flash by ~200 KB on this feature-rich
|
||||
; solo build. -Os keeps every feature, fits comfortably, and is actually safer
|
||||
; for float (no fast-math reassociation). Speed is irrelevant for the UI/mesh.
|
||||
build_unflags = -Ofast
|
||||
build_flags =
|
||||
${LilyGo_T-Echo-Lite.build_flags}
|
||||
-I src/helpers/ui
|
||||
-I examples/companion_radio/ui-new
|
||||
-D LILYGO_TECHO_LITE_KEYSHIELD
|
||||
-D MAX_CONTACTS=350
|
||||
-D MAX_GROUP_CHANNELS=40
|
||||
; -D QSPIFLASH=1
|
||||
-D BLE_PIN_CODE=123456
|
||||
; -D BLE_DEBUG_LOGGING=1
|
||||
-D OFFLINE_QUEUE_SIZE=256
|
||||
-D UI_RECENT_LIST_SIZE=9
|
||||
-D UI_SENSORS_PAGE=1
|
||||
; -D MESH_PACKET_LOGGING=1
|
||||
; -D MESH_DEBUG=1
|
||||
-D ENV_USE_TCA8418=1
|
||||
-D FIRMWARE_SOLO_BUILD=1
|
||||
-D MESHCORE_VERSION='"1.17"'
|
||||
-D ENABLE_SCREENSHOT
|
||||
-Os
|
||||
build_src_filter = ${LilyGo_T-Echo-Lite.build_src_filter}
|
||||
+<helpers/nrf52/SerialBLEInterface.cpp>
|
||||
+<../examples/companion_radio/*.cpp>
|
||||
+<../examples/companion_radio/ui-new/*.cpp>
|
||||
lib_deps =
|
||||
${LilyGo_T-Echo-Lite.lib_deps}
|
||||
densaugeo/base64 @ ~1.4.0
|
||||
;https://github.com/lewisxhe/SensorLib.git
|
||||
@@ -0,0 +1,34 @@
|
||||
; Solo build for M5Stack Cardputer ADV -- extends the board base defined in
|
||||
; variants/m5stack_cardputer_adv/platformio.ini. Solo configs live in their own
|
||||
; top-level solo/ folder, separate from the shared upstream board variants in
|
||||
; variants/, so this repo's Solo-specific additions don't get mixed in with
|
||||
; configs other MeshCore forks/upstream also carry.
|
||||
;
|
||||
[env:M5Stack_Cardputer_ADV_companion_solo_dual]
|
||||
extends = M5Stack_Cardputer_ADV
|
||||
build_flags =
|
||||
${M5Stack_Cardputer_ADV.build_flags}
|
||||
-I examples/companion_radio/ui-new
|
||||
-D MAX_CONTACTS=350
|
||||
-D MAX_GROUP_CHANNELS=40
|
||||
-D BLE_PIN_CODE=123456
|
||||
-D DUAL_SERIAL=1
|
||||
-D OFFLINE_QUEUE_SIZE=256
|
||||
-D FIRMWARE_SOLO_BUILD=1
|
||||
-D MESHCORE_VERSION='"1.17"'
|
||||
-D UI_SENSORS_PAGE=1
|
||||
; misc-fixed 6x9 font (full Latin/Greek/Cyrillic), same as the Wio L1/Heltec
|
||||
; solo builds. Solo only: it costs ~14 KB of flash, and this board's own
|
||||
; QWERTY keyboard is exactly the case that benefits from typing those
|
||||
; alphabets and having them render as themselves instead of blocks.
|
||||
-D OLED_MISC_FIXED_FONT=1
|
||||
; -D MESH_PACKET_LOGGING=1
|
||||
; -D MESH_DEBUG=1
|
||||
build_src_filter = ${M5Stack_Cardputer_ADV.build_src_filter}
|
||||
+<helpers/esp32/*.cpp>
|
||||
+<helpers/ui/MomentaryButton.cpp>
|
||||
+<../examples/companion_radio/*.cpp>
|
||||
+<../examples/companion_radio/ui-new/*.cpp>
|
||||
lib_deps =
|
||||
${M5Stack_Cardputer_ADV.lib_deps}
|
||||
densaugeo/base64 @ ~1.4.0
|
||||
@@ -0,0 +1,45 @@
|
||||
; Solo build for ProMicro (nRF52840) -- extends the board base defined in
|
||||
; variants/promicro/platformio.ini. Solo configs live in their own top-level
|
||||
; solo/ folder, separate from the shared upstream board variants in variants/,
|
||||
; so this repo's Solo-specific additions don't get mixed in with configs
|
||||
; other MeshCore forks/upstream also carry.
|
||||
;
|
||||
; Full on-device UI, with CardKB support: CardKB shares the board's primary
|
||||
; I2C bus (already used by the OLED display / RTC) instead of a dedicated
|
||||
; second bus -- the default Wire1 pins on this variant (D13/D14) physically
|
||||
; collide with the LoRa SPI bus (P_LORA_NSS=13, P_LORA_MOSI=14), and no other
|
||||
; free GPIO pair is broken out on this board for a second dedicated bus. Do
|
||||
; NOT define ENV_PIN_SDA/ENV_PIN_SCL here -- that would bring up a real Wire1
|
||||
; on the colliding pins instead.
|
||||
[env:ProMicro_companion_solo_dual]
|
||||
extends = Promicro
|
||||
board_build.ldscript = boards/nrf52840_s140_v6_extrafs.ld
|
||||
board_upload.maximum_size = 712704
|
||||
; -Ofast (the core's default) doesn't fit a feature-complete solo build;
|
||||
; -Os fits with headroom.
|
||||
build_unflags = -Ofast
|
||||
build_flags = ${Promicro.build_flags}
|
||||
-I examples/companion_radio/ui-new
|
||||
-D MAX_CONTACTS=350
|
||||
-D MAX_GROUP_CHANNELS=40
|
||||
-D BLE_PIN_CODE=123456
|
||||
-D DUAL_SERIAL=1
|
||||
-D OFFLINE_QUEUE_SIZE=256
|
||||
-D DISPLAY_CLASS=SSD1306Display
|
||||
-D FIRMWARE_SOLO_BUILD=1
|
||||
-D UI_SENSORS_PAGE=1
|
||||
-D ENABLE_SCREENSHOT
|
||||
-Os
|
||||
; CardKB on the shared primary bus (D8=SDA / D7=SCL on this board).
|
||||
-D CARDKB_I2C=Wire
|
||||
; -D MESH_PACKET_LOGGING=1
|
||||
; -D MESH_DEBUG=1
|
||||
build_src_filter = ${Promicro.build_src_filter}
|
||||
+<helpers/ui/SSD1306Display.cpp>
|
||||
+<helpers/ui/MomentaryButton.cpp>
|
||||
+<helpers/nrf52/SerialBLEInterface.cpp>
|
||||
+<../examples/companion_radio/*.cpp>
|
||||
+<../examples/companion_radio/ui-new/*.cpp>
|
||||
lib_deps = ${Promicro.lib_deps}
|
||||
adafruit/RTClib @ ^2.1.3
|
||||
densaugeo/base64 @ ~1.4.0
|
||||
@@ -0,0 +1,19 @@
|
||||
; Solo build for Seeed Wio Tracker L1 (E-ink) -- extends WioTrackerL1Eink,
|
||||
; defined in variants/wio-tracker-l1-eink/platformio.ini. Solo configs live in
|
||||
; their own top-level solo/ folder, separate from the shared upstream board
|
||||
; variants in variants/, so this repo's Solo-specific additions don't get
|
||||
; mixed in with configs other MeshCore forks/upstream also carry.
|
||||
;
|
||||
; Dual BLE+USB with added Solo
|
||||
[env:WioTrackerL1Eink_companion_solo_dual]
|
||||
extends = WioTrackerL1Eink
|
||||
; Optimise for size, not speed: the nRF52 Arduino core defaults to -Ofast
|
||||
; (≈ -O3 + -ffast-math), which bloats flash by ~200 KB on this feature-rich
|
||||
; solo build. -Os keeps every feature, fits comfortably, and is actually safer
|
||||
; for float (no fast-math reassociation). Speed is irrelevant for the UI/mesh.
|
||||
build_unflags = -Ofast
|
||||
build_flags = ${WioTrackerL1Eink.build_flags}
|
||||
-D DUAL_SERIAL=1
|
||||
-D ENABLE_SCREENSHOT
|
||||
-Os
|
||||
extra_scripts = post:create-uf2.py
|
||||
@@ -0,0 +1,19 @@
|
||||
; Solo build for Seeed Wio Tracker L1 (OLED) -- extends WioTrackerL1CompanionDual,
|
||||
; defined in variants/wio-tracker-l1/platformio.ini. Solo configs live in their
|
||||
; own top-level solo/ folder, separate from the shared upstream board variants
|
||||
; in variants/, so this repo's Solo-specific additions don't get mixed in with
|
||||
; configs other MeshCore forks/upstream also carry.
|
||||
;
|
||||
[env:WioTrackerL1_companion_solo_dual]
|
||||
extends = WioTrackerL1CompanionDual
|
||||
; Optimise for size, not speed: the nRF52 Arduino core defaults to -Ofast
|
||||
; (≈ -O3 + -ffast-math), which bloats flash by ~200 KB on this feature-rich
|
||||
; solo build. -Os keeps every feature, fits comfortably, and is actually safer
|
||||
; for float (no fast-math reassociation). Speed is irrelevant for the UI/mesh.
|
||||
build_unflags = -Ofast
|
||||
build_flags = ${WioTrackerL1CompanionDual.build_flags}
|
||||
-D UI_HAS_JOYSTICK_UPDOWN=1
|
||||
-D ENABLE_SCREENSHOT
|
||||
-D DUAL_SERIAL=1
|
||||
-Os
|
||||
extra_scripts = post:create-uf2.py
|
||||
@@ -113,91 +113,6 @@ lib_deps =
|
||||
densaugeo/base64 @ ~1.4.0
|
||||
end2endzone/NonBlockingRTTTL@^1.3.0
|
||||
|
||||
[env:GAT562_30S_Mesh_Kit_solo_ble]
|
||||
extends = GAT562_30S_Mesh_Kit
|
||||
board_build.ldscript = boards/nrf52840_s140_v6_extrafs.ld
|
||||
board_upload.maximum_size = 712704
|
||||
; Optimise for size, not speed: the nRF52 Arduino core defaults to -Ofast
|
||||
; (≈ -O3 + -ffast-math), which bloats flash by ~200 KB on this feature-rich
|
||||
; solo build. -Os keeps every feature, fits comfortably, and is actually safer
|
||||
; for float (no fast-math reassociation). Speed is irrelevant for the UI/mesh.
|
||||
build_unflags = -Ofast
|
||||
build_flags =
|
||||
${GAT562_30S_Mesh_Kit.build_flags}
|
||||
-I examples/companion_radio/ui-new
|
||||
-D DISPLAY_CLASS=SSD1306Display
|
||||
-D MAX_CONTACTS=350
|
||||
-D MAX_GROUP_CHANNELS=40
|
||||
-D BLE_PIN_CODE=123456
|
||||
-D OFFLINE_QUEUE_SIZE=256
|
||||
-D FIRMWARE_SOLO_BUILD=1
|
||||
-D MESHCORE_VERSION='"1.17"'
|
||||
-D UI_SENSORS_PAGE=1
|
||||
-D UI_HAS_JOYSTICK_UPDOWN=1
|
||||
-D ADVERT_NAME='"@@MAC"'
|
||||
-D ENV_INCLUDE_GPS=1
|
||||
; misc-fixed 6x9 OLED font (full Latin/Greek/Cyrillic), same as the Wio L1
|
||||
; builds. Solo only: it costs ~14 KB of flash and the repeater/companion
|
||||
; builds have no keyboard to type those alphabets on.
|
||||
-D OLED_MISC_FIXED_FONT=1
|
||||
-Os
|
||||
; QSPIFLASH disabled: QSPI IO0/IO2 pins (P0.30/P0.28) conflict with joystick LEFT/UP
|
||||
; -D MESH_PACKET_LOGGING=1
|
||||
; -D MESH_DEBUG=1
|
||||
build_src_filter = ${GAT562_30S_Mesh_Kit.build_src_filter}
|
||||
+<helpers/nrf52/SerialBLEInterface.cpp>
|
||||
+<helpers/ui/buzzer.cpp>
|
||||
+<../examples/companion_radio/*.cpp>
|
||||
+<../examples/companion_radio/ui-new/*.cpp>
|
||||
lib_deps =
|
||||
${GAT562_30S_Mesh_Kit.lib_deps}
|
||||
adafruit/RTClib @ ^2.1.3
|
||||
densaugeo/base64 @ ~1.4.0
|
||||
end2endzone/NonBlockingRTTTL@^1.3.0
|
||||
|
||||
[env:GAT562_30S_Mesh_Kit_solo_dual]
|
||||
extends = GAT562_30S_Mesh_Kit
|
||||
board_build.ldscript = boards/nrf52840_s140_v6_extrafs.ld
|
||||
board_upload.maximum_size = 712704
|
||||
; Optimise for size, not speed: the nRF52 Arduino core defaults to -Ofast
|
||||
; (≈ -O3 + -ffast-math), which bloats flash by ~200 KB on this feature-rich
|
||||
; solo build. -Os keeps every feature, fits comfortably, and is actually safer
|
||||
; for float (no fast-math reassociation). Speed is irrelevant for the UI/mesh.
|
||||
build_unflags = -Ofast
|
||||
build_flags =
|
||||
${GAT562_30S_Mesh_Kit.build_flags}
|
||||
-I examples/companion_radio/ui-new
|
||||
-D DISPLAY_CLASS=SSD1306Display
|
||||
-D MAX_CONTACTS=350
|
||||
-D MAX_GROUP_CHANNELS=40
|
||||
-D BLE_PIN_CODE=123456
|
||||
-D OFFLINE_QUEUE_SIZE=256
|
||||
-D FIRMWARE_SOLO_BUILD=1
|
||||
-D MESHCORE_VERSION='"1.17"'
|
||||
-D UI_SENSORS_PAGE=1
|
||||
-D UI_HAS_JOYSTICK_UPDOWN=1
|
||||
-D ADVERT_NAME='"@@MAC"'
|
||||
-D ENV_INCLUDE_GPS=1
|
||||
; misc-fixed 6x9 OLED font (full Latin/Greek/Cyrillic), same as the Wio L1
|
||||
; builds. Solo only: it costs ~14 KB of flash and the repeater/companion
|
||||
; builds have no keyboard to type those alphabets on.
|
||||
-D OLED_MISC_FIXED_FONT=1
|
||||
-D DUAL_SERIAL=1
|
||||
-D ENABLE_SCREENSHOT
|
||||
-Os
|
||||
; QSPIFLASH disabled: QSPI IO0/IO2 pins (P0.30/P0.28) conflict with joystick LEFT/UP
|
||||
; -D MESH_PACKET_LOGGING=1
|
||||
; -D MESH_DEBUG=1
|
||||
build_src_filter = ${GAT562_30S_Mesh_Kit.build_src_filter}
|
||||
+<helpers/nrf52/SerialBLEInterface.cpp>
|
||||
+<helpers/ui/buzzer.cpp>
|
||||
+<../examples/companion_radio/*.cpp>
|
||||
+<../examples/companion_radio/ui-new/*.cpp>
|
||||
lib_deps =
|
||||
${GAT562_30S_Mesh_Kit.lib_deps}
|
||||
adafruit/RTClib @ ^2.1.3
|
||||
densaugeo/base64 @ ~1.4.0
|
||||
end2endzone/NonBlockingRTTTL@^1.3.0
|
||||
|
||||
[env:GAT562_30S_Mesh_Kit_kiss_modem]
|
||||
extends = GAT562_30S_Mesh_Kit
|
||||
|
||||
@@ -87,45 +87,6 @@ lib_deps =
|
||||
${GAT562_Mesh_Watch13.lib_deps}
|
||||
densaugeo/base64 @ ~1.4.0
|
||||
|
||||
[env:GAT562_Mesh_Watch13_solo_ble]
|
||||
extends = GAT562_Mesh_Watch13
|
||||
board_build.ldscript = boards/nrf52840_s140_v6_extrafs.ld
|
||||
board_upload.maximum_size = 712704
|
||||
build_flags =
|
||||
${GAT562_Mesh_Watch13.build_flags}
|
||||
-I examples/companion_radio/ui-new
|
||||
-D DISPLAY_CLASS=SSD1306Display
|
||||
-D MAX_CONTACTS=350
|
||||
-D MAX_GROUP_CHANNELS=40
|
||||
-D BLE_PIN_CODE=123456
|
||||
-D OFFLINE_QUEUE_SIZE=256
|
||||
-D FIRMWARE_SOLO_BUILD=1
|
||||
-D MESHCORE_VERSION='"1.17"'
|
||||
-D UI_SENSORS_PAGE=1
|
||||
-D ADVERT_NAME='"@@MAC"'
|
||||
; GPS — re-enable (base undefines it); Serial1 pins 15/16 from variant
|
||||
-D ENV_INCLUDE_GPS=1
|
||||
-D GPS_BAUD_RATE=9600
|
||||
; Buzzer available on IO3 (pin 21) — uncomment to enable
|
||||
; -D PIN_BUZZER=21
|
||||
; -D PIN_VIBRATION=36
|
||||
; -D MESH_PACKET_LOGGING=1
|
||||
; -D MESH_DEBUG=1
|
||||
build_src_filter = ${GAT562_Mesh_Watch13.build_src_filter}
|
||||
+<helpers/nrf52/SerialBLEInterface.cpp>
|
||||
+<helpers/ui/MomentaryButton.cpp>
|
||||
+<helpers/ui/GenericVibration.cpp>
|
||||
+<../examples/companion_radio/*.cpp>
|
||||
+<../examples/companion_radio/ui-new/*.cpp>
|
||||
; If PIN_BUZZER is enabled above, also add:
|
||||
; +<helpers/ui/buzzer.cpp>
|
||||
lib_deps =
|
||||
${GAT562_Mesh_Watch13.lib_deps}
|
||||
adafruit/RTClib @ ^2.1.3
|
||||
densaugeo/base64 @ ~1.4.0
|
||||
; If PIN_BUZZER is enabled, also add:
|
||||
; end2endzone/NonBlockingRTTTL@^1.3.0
|
||||
|
||||
[env:GAT562_Mesh_Watch13_kiss_modem]
|
||||
extends = GAT562_Mesh_Watch13
|
||||
build_src_filter = ${GAT562_Mesh_Watch13.build_src_filter}
|
||||
|
||||
@@ -180,91 +180,6 @@ lib_deps =
|
||||
${Heltec_lora32_v3.lib_deps}
|
||||
densaugeo/base64 @ ~1.4.0
|
||||
|
||||
; Solo build: the full standalone on-device UI (message history, contacts, map,
|
||||
; tools) rather than a screen that only mirrors the phone app. Dual transport --
|
||||
; the companion app can attach over BLE or USB serial, whichever it finds, and
|
||||
; BLE wins while both are live.
|
||||
;
|
||||
; This firmware needs a real input device: the solo UI cannot be driven from the
|
||||
; PRG button alone. Both supported ones are wired up in target.cpp and enabled
|
||||
; below, so either is enough on its own and having both is fine. The pins are
|
||||
; defaults picked from what this board leaves free -- change them to match how
|
||||
; the device is actually built. Pins with nothing attached read as not-pressed,
|
||||
; so the unused half costs nothing.
|
||||
;
|
||||
; * CardKB (M5Stack I2C keyboard, addr 0x5F) on a second I2C bus. Any two free
|
||||
; GPIOs -- NOT 17/18, the OLED already owns those on Wire. It's probed at
|
||||
; boot, so a build with these set still runs fine with nothing plugged in.
|
||||
; Pair it with Settings > Keyboard > Ext. KB = Compact, which is designed to
|
||||
; need no joystick at all. The same bus is scanned for environment sensors.
|
||||
;
|
||||
; * Wired joystick: four direction pins plus a fifth "press" contact. The
|
||||
; press contact drives Enter (your thumb's already on the stick) via
|
||||
; PIN_USER_BTN -- overridden below (a later -D wins, no -U needed: this whole
|
||||
; project builds with -w) from the PRG-button default
|
||||
; the base env sets, since PRG's GPIO0 can't be moved to the stick. PRG
|
||||
; becomes Back instead (PIN_BACK_BTN), so it no longer needs its own
|
||||
; separately-wired button. Each contact just shorts its pin to GND;
|
||||
; target.cpp enables the internal pull-ups. Drop
|
||||
; UI_HAS_JOYSTICK_UPDOWN for a left/right-only stick. JOYSTICK_ROTATION (0-3)
|
||||
; rotates the mapping if the stick is mounted sideways -- it's also a runtime
|
||||
; setting, so leave it out unless you want a different default.
|
||||
; Comment the whole block out for a CardKB-only build. UI_HAS_JOYSTICK
|
||||
; replaces the single-button handling rather than adding to it (UITask.cpp
|
||||
; dispatches on '#if UI_HAS_JOYSTICK ... #elif defined(PIN_USER_BTN)'), which
|
||||
; costs nothing here -- that fallback only feeds KEY_NEXT/KEY_PREV, which the
|
||||
; solo screens don't act on.
|
||||
;
|
||||
; V3 and V4 are pin-compatible per Heltec's own docs, so the defaults below are
|
||||
; carried over from the heltec_v4_companion_solo_dual env, where this exact
|
||||
; CardKB + joystick combination is confirmed working on real hardware -- still
|
||||
; worth checking against your own V3 module before soldering, but not a blind
|
||||
; guess like the earlier SDA 41/SCL 42 default was. PIN_GPS_RX=47/TX=48/EN=26
|
||||
; above are dead defines on V3 (ENV_INCLUDE_GPS is never set to 1 in this file),
|
||||
; so they don't conflict with reusing 47/48 here despite the name.
|
||||
[env:Heltec_v3_companion_solo_dual]
|
||||
extends = Heltec_lora32_v3
|
||||
build_flags =
|
||||
${Heltec_lora32_v3.build_flags}
|
||||
-I examples/companion_radio/ui-new
|
||||
-D MAX_CONTACTS=350
|
||||
-D MAX_GROUP_CHANNELS=40
|
||||
-D DISPLAY_CLASS=SSD1306Display
|
||||
-D BLE_PIN_CODE=123456 ; dynamic, random PIN
|
||||
-D DUAL_SERIAL=1 ; companion app over BLE *or* USB serial
|
||||
-D AUTO_SHUTDOWN_MILLIVOLTS=3400
|
||||
-D OFFLINE_QUEUE_SIZE=256
|
||||
-D FIRMWARE_SOLO_BUILD=1
|
||||
-D UI_SENSORS_PAGE=1
|
||||
-D OLED_MISC_FIXED_FONT=1 ; full Latin/Greek/Cyrillic 6x9 font, ~14 KB flash
|
||||
-D ENABLE_SCREENSHOT ; same as the other solo builds — Solo Tools reads the framebuffer over USB
|
||||
; CardKB on the second I2C bus. Harmless with nothing plugged in.
|
||||
-D ENV_PIN_SDA=3
|
||||
-D ENV_PIN_SCL=4
|
||||
; Wired joystick — comment the block out for a CardKB-only build. The
|
||||
; press contact (Enter) overrides PIN_USER_BTN from its PRG default;
|
||||
; PRG becomes Back (PIN_BACK_BTN) instead.
|
||||
-D UI_HAS_JOYSTICK=1
|
||||
-D UI_HAS_JOYSTICK_UPDOWN=1
|
||||
-D JOYSTICK_UP=23
|
||||
-D JOYSTICK_DOWN=6
|
||||
-D JOYSTICK_LEFT=47
|
||||
-D JOYSTICK_RIGHT=48
|
||||
-D PIN_BACK_BTN=0 ; PRG button
|
||||
-D PIN_USER_BTN=33 ; joystick press contact -- Enter, overrides the PRG default above
|
||||
; -D PIN_BUZZER=<gpio>
|
||||
build_src_filter = ${Heltec_lora32_v3.build_src_filter}
|
||||
+<helpers/ui/SSD1306Display.cpp>
|
||||
+<helpers/ui/MomentaryButton.cpp>
|
||||
+<helpers/ui/buzzer.cpp>
|
||||
+<helpers/esp32/*.cpp>
|
||||
+<../examples/companion_radio/*.cpp>
|
||||
+<../examples/companion_radio/ui-new/*.cpp>
|
||||
lib_deps =
|
||||
${Heltec_lora32_v3.lib_deps}
|
||||
densaugeo/base64 @ ~1.4.0
|
||||
end2endzone/NonBlockingRTTTL@^1.3.0
|
||||
|
||||
[env:Heltec_v3_companion_radio_wifi]
|
||||
extends = Heltec_lora32_v3
|
||||
build_flags =
|
||||
|
||||
@@ -223,98 +223,6 @@ lib_deps =
|
||||
${heltec_v4_oled.lib_deps}
|
||||
densaugeo/base64 @ ~1.4.0
|
||||
|
||||
; Solo build: the full standalone on-device UI (message history, contacts, map,
|
||||
; tools) rather than a screen that only mirrors the phone app. Dual transport --
|
||||
; the companion app can attach over BLE or USB serial, whichever it finds, and
|
||||
; BLE wins while both are live. OLED board only -- the TFT variant would need
|
||||
; its own DISPLAY_CLASS.
|
||||
;
|
||||
; This firmware needs a real input device: the solo UI cannot be driven from the
|
||||
; PRG button alone. Both supported ones are wired up in target.cpp and enabled
|
||||
; below, so either is enough on its own and having both is fine. The pins are
|
||||
; defaults picked from what this board leaves free -- change them to match how
|
||||
; the device is actually built. Pins with nothing attached read as not-pressed,
|
||||
; so the unused half costs nothing.
|
||||
;
|
||||
; * CardKB (M5Stack I2C keyboard, addr 0x5F) on a second I2C bus. Any two free
|
||||
; GPIOs -- NOT 17/18, the OLED already owns those on Wire. It's probed at
|
||||
; boot, so a build with these set still runs fine with nothing plugged in.
|
||||
; Pair it with Settings > Keyboard > Ext. KB = Compact, which is designed to
|
||||
; need no joystick at all. The same bus is scanned for environment sensors.
|
||||
; Defaults below: SDA 3, SCL 4 -- the pins heltec_v4_sensor and
|
||||
; heltec_v4_expansionkit_repeater already use for their second I2C bus, i.e.
|
||||
; the expansion kit's. (Those envs disagree on the order: two say SDA 3 /
|
||||
; SCL 4, one says the reverse. 3/4 is the pair either way; swap them if the
|
||||
; keyboard doesn't answer.)
|
||||
;
|
||||
; * Wired joystick: four direction pins plus a fifth "press" contact. The
|
||||
; press contact drives Enter (your thumb's already on the stick) via
|
||||
; PIN_USER_BTN -- overridden below (a later -D wins, no -U needed: this whole
|
||||
; project builds with -w) from the PRG-button default
|
||||
; the base env sets, since PRG's GPIO0 can't be moved to the stick. PRG
|
||||
; becomes Back instead (PIN_BACK_BTN), so it no longer needs its own
|
||||
; separately-wired button. Each contact just shorts its pin to GND;
|
||||
; target.cpp enables the internal pull-ups. Drop
|
||||
; UI_HAS_JOYSTICK_UPDOWN for a left/right-only stick. JOYSTICK_ROTATION (0-3)
|
||||
; rotates the mapping if the stick is mounted sideways -- it's also a runtime
|
||||
; setting, so leave it out unless you want a different default.
|
||||
; Comment the whole block out for a CardKB-only build. UI_HAS_JOYSTICK
|
||||
; replaces the single-button handling rather than adding to it (UITask.cpp
|
||||
; dispatches on '#if UI_HAS_JOYSTICK ... #elif defined(PIN_USER_BTN)'), which
|
||||
; costs nothing here -- that fallback only feeds KEY_NEXT/KEY_PREV, which the
|
||||
; solo screens don't act on.
|
||||
;
|
||||
; Free on this board, per its pinout: 3, 4, 6, 23, 33, 43, 44, 45, 46, 47, 48.
|
||||
; Two of those can't take an I2C pull-up: 45 selects VDD_SPI at boot, so held
|
||||
; high the chip comes up expecting 1.8V flash and won't boot at all, and 46 is
|
||||
; the boot-mode strap. 3 is a strapping pin too, but it only picks the JTAG
|
||||
; source -- and it's what this board's own expansion kit uses for I2C anyway.
|
||||
; 43/44 are UART0: unused by this build, since ARDUINO_USB_CDC_ON_BOOT (set in
|
||||
; boards/heltec_v4.json) makes Serial the native USB port, but a USB-UART bridge
|
||||
; may still be wired to them, so they're left alone.
|
||||
[env:heltec_v4_companion_solo_dual]
|
||||
extends = heltec_v4_oled
|
||||
build_flags =
|
||||
${heltec_v4_oled.build_flags}
|
||||
-I examples/companion_radio/ui-new
|
||||
-D MAX_CONTACTS=350
|
||||
-D MAX_GROUP_CHANNELS=40
|
||||
-D DISPLAY_CLASS=SSD1306Display
|
||||
-D BLE_PIN_CODE=123456 ; dynamic, random PIN
|
||||
-D DUAL_SERIAL=1 ; companion app over BLE *or* USB serial
|
||||
-D AUTO_SHUTDOWN_MILLIVOLTS=3400
|
||||
-D OFFLINE_QUEUE_SIZE=256
|
||||
-D FIRMWARE_SOLO_BUILD=1
|
||||
-D UI_SENSORS_PAGE=1
|
||||
-D OLED_MISC_FIXED_FONT=1 ; full Latin/Greek/Cyrillic 6x9 font, ~14 KB flash
|
||||
-D ENABLE_SCREENSHOT ; same as the other solo builds — Solo Tools reads the framebuffer over USB
|
||||
; CardKB on the second I2C bus. Harmless with nothing plugged in.
|
||||
-D ENV_PIN_SDA=3
|
||||
-D ENV_PIN_SCL=4
|
||||
; Wired joystick — comment the block out for a CardKB-only build. The
|
||||
; press contact (Enter) overrides PIN_USER_BTN from its PRG default;
|
||||
; PRG becomes Back (PIN_BACK_BTN) instead.
|
||||
-D UI_HAS_JOYSTICK=1
|
||||
-D UI_HAS_JOYSTICK_UPDOWN=1
|
||||
-D JOYSTICK_UP=23
|
||||
-D JOYSTICK_DOWN=6
|
||||
-D JOYSTICK_LEFT=47
|
||||
-D JOYSTICK_RIGHT=48
|
||||
-D PIN_BACK_BTN=0 ; PRG button
|
||||
-D PIN_USER_BTN=33 ; joystick press contact -- Enter, overrides the PRG default above
|
||||
; -D PIN_BUZZER=<gpio>
|
||||
build_src_filter = ${heltec_v4_oled.build_src_filter}
|
||||
+<helpers/ui/SSD1306Display.cpp>
|
||||
+<helpers/ui/MomentaryButton.cpp>
|
||||
+<helpers/ui/buzzer.cpp>
|
||||
+<helpers/esp32/*.cpp>
|
||||
+<../examples/companion_radio/*.cpp>
|
||||
+<../examples/companion_radio/ui-new/*.cpp>
|
||||
lib_deps =
|
||||
${heltec_v4_oled.lib_deps}
|
||||
densaugeo/base64 @ ~1.4.0
|
||||
end2endzone/NonBlockingRTTTL@^1.3.0
|
||||
|
||||
[env:heltec_v4_companion_radio_wifi]
|
||||
extends = heltec_v4_oled
|
||||
build_flags =
|
||||
|
||||
@@ -45,45 +45,6 @@ lib_deps =
|
||||
debug_tool = jlink
|
||||
upload_protocol = nrfutil
|
||||
|
||||
[env:LilyGo_T-Echo-Lite_keyshield_companion_solo_dual]
|
||||
extends = LilyGo_T-Echo-Lite
|
||||
board_build.ldscript = boards/nrf52840_s140_v6_extrafs.ld
|
||||
board_upload.maximum_size = 712704
|
||||
; Optimise for size, not speed: the nRF52 Arduino core defaults to -Ofast
|
||||
; (≈ -O3 + -ffast-math), which bloats flash by ~200 KB on this feature-rich
|
||||
; solo build. -Os keeps every feature, fits comfortably, and is actually safer
|
||||
; for float (no fast-math reassociation). Speed is irrelevant for the UI/mesh.
|
||||
build_unflags = -Ofast
|
||||
build_flags =
|
||||
${LilyGo_T-Echo-Lite.build_flags}
|
||||
-I src/helpers/ui
|
||||
-I examples/companion_radio/ui-new
|
||||
-D LILYGO_TECHO_LITE_KEYSHIELD
|
||||
-D MAX_CONTACTS=350
|
||||
-D MAX_GROUP_CHANNELS=40
|
||||
; -D QSPIFLASH=1
|
||||
-D BLE_PIN_CODE=123456
|
||||
; -D BLE_DEBUG_LOGGING=1
|
||||
-D OFFLINE_QUEUE_SIZE=256
|
||||
-D UI_RECENT_LIST_SIZE=9
|
||||
-D UI_SENSORS_PAGE=1
|
||||
; -D MESH_PACKET_LOGGING=1
|
||||
; -D MESH_DEBUG=1
|
||||
-D AUTO_SHUTDOWN_MILLIVOLTS=3300
|
||||
-D ENV_USE_TCA8418=1
|
||||
-D FIRMWARE_SOLO_BUILD=1
|
||||
-D MESHCORE_VERSION='"1.17"'
|
||||
-D ENABLE_SCREENSHOT
|
||||
-Os
|
||||
build_src_filter = ${LilyGo_T-Echo-Lite.build_src_filter}
|
||||
+<helpers/nrf52/SerialBLEInterface.cpp>
|
||||
+<../examples/companion_radio/*.cpp>
|
||||
+<../examples/companion_radio/ui-new/*.cpp>
|
||||
lib_deps =
|
||||
${LilyGo_T-Echo-Lite.lib_deps}
|
||||
densaugeo/base64 @ ~1.4.0
|
||||
;https://github.com/lewisxhe/SensorLib.git
|
||||
|
||||
[env:LilyGo_T-Echo-Lite_repeater]
|
||||
extends = LilyGo_T-Echo-Lite
|
||||
build_src_filter = ${LilyGo_T-Echo-Lite.build_src_filter}
|
||||
|
||||
@@ -97,35 +97,6 @@ lib_deps =
|
||||
${M5Stack_Cardputer_ADV.lib_deps}
|
||||
densaugeo/base64 @ ~1.4.0
|
||||
|
||||
[env:M5Stack_Cardputer_ADV_companion_solo_dual]
|
||||
extends = M5Stack_Cardputer_ADV
|
||||
build_flags =
|
||||
${M5Stack_Cardputer_ADV.build_flags}
|
||||
-I examples/companion_radio/ui-new
|
||||
-D MAX_CONTACTS=350
|
||||
-D MAX_GROUP_CHANNELS=40
|
||||
-D BLE_PIN_CODE=123456
|
||||
-D DUAL_SERIAL=1
|
||||
-D OFFLINE_QUEUE_SIZE=256
|
||||
-D FIRMWARE_SOLO_BUILD=1
|
||||
-D MESHCORE_VERSION='"1.17"'
|
||||
-D UI_SENSORS_PAGE=1
|
||||
; misc-fixed 6x9 font (full Latin/Greek/Cyrillic), same as the Wio L1/Heltec
|
||||
; solo builds. Solo only: it costs ~14 KB of flash, and this board's own
|
||||
; QWERTY keyboard is exactly the case that benefits from typing those
|
||||
; alphabets and having them render as themselves instead of blocks.
|
||||
-D OLED_MISC_FIXED_FONT=1
|
||||
; -D MESH_PACKET_LOGGING=1
|
||||
; -D MESH_DEBUG=1
|
||||
build_src_filter = ${M5Stack_Cardputer_ADV.build_src_filter}
|
||||
+<helpers/esp32/*.cpp>
|
||||
+<helpers/ui/MomentaryButton.cpp>
|
||||
+<../examples/companion_radio/*.cpp>
|
||||
+<../examples/companion_radio/ui-new/*.cpp>
|
||||
lib_deps =
|
||||
${M5Stack_Cardputer_ADV.lib_deps}
|
||||
densaugeo/base64 @ ~1.4.0
|
||||
|
||||
[env:M5Stack_Cardputer_ADV_repeater]
|
||||
extends = M5Stack_Cardputer_ADV
|
||||
build_flags =
|
||||
|
||||
@@ -176,4 +176,4 @@ lib_deps =
|
||||
[env:ProMicro_kiss_modem]
|
||||
extends = Promicro
|
||||
build_src_filter = ${Promicro.build_src_filter}
|
||||
+<../examples/kiss_modem/>
|
||||
+<../examples/kiss_modem/>
|
||||
|
||||
@@ -70,20 +70,6 @@ build_flags = ${WioTrackerL1Eink.build_flags}
|
||||
-D DUAL_SERIAL=1
|
||||
extra_scripts = post:create-uf2.py
|
||||
|
||||
; Dual BLE+USB with added Solo
|
||||
[env:WioTrackerL1Eink_companion_solo_dual]
|
||||
extends = WioTrackerL1Eink
|
||||
; Optimise for size, not speed: the nRF52 Arduino core defaults to -Ofast
|
||||
; (≈ -O3 + -ffast-math), which bloats flash by ~200 KB on this feature-rich
|
||||
; solo build. -Os keeps every feature, fits comfortably, and is actually safer
|
||||
; for float (no fast-math reassociation). Speed is irrelevant for the UI/mesh.
|
||||
build_unflags = -Ofast
|
||||
build_flags = ${WioTrackerL1Eink.build_flags}
|
||||
-D DUAL_SERIAL=1
|
||||
-D ENABLE_SCREENSHOT
|
||||
-Os
|
||||
extra_scripts = post:create-uf2.py
|
||||
|
||||
; Dual BLE+USB with screenshot support (development/debug)
|
||||
[env:WioTrackerL1Eink_companion_dual_dev]
|
||||
extends = WioTrackerL1Eink
|
||||
|
||||
@@ -150,20 +150,6 @@ build_flags = ${WioTrackerL1CompanionDual.build_flags}
|
||||
-D UI_HAS_JOYSTICK_UPDOWN=1
|
||||
extra_scripts = post:create-uf2.py
|
||||
|
||||
[env:WioTrackerL1_companion_solo_dual]
|
||||
extends = WioTrackerL1CompanionDual
|
||||
; Optimise for size, not speed: the nRF52 Arduino core defaults to -Ofast
|
||||
; (≈ -O3 + -ffast-math), which bloats flash by ~200 KB on this feature-rich
|
||||
; solo build. -Os keeps every feature, fits comfortably, and is actually safer
|
||||
; for float (no fast-math reassociation). Speed is irrelevant for the UI/mesh.
|
||||
build_unflags = -Ofast
|
||||
build_flags = ${WioTrackerL1CompanionDual.build_flags}
|
||||
-D UI_HAS_JOYSTICK_UPDOWN=1
|
||||
-D ENABLE_SCREENSHOT
|
||||
-D DUAL_SERIAL=1
|
||||
-Os
|
||||
extra_scripts = post:create-uf2.py
|
||||
|
||||
[env:WioTrackerL1_companion_dual_dev]
|
||||
extends = WioTrackerL1CompanionDual
|
||||
build_flags = ${WioTrackerL1CompanionDual.build_flags}
|
||||
|
||||
Reference in New Issue
Block a user