diff --git a/docs/lora_ota_automation.md b/docs/lora_ota_automation.md index 647a27be3..9cd3abe4b 100644 --- a/docs/lora_ota_automation.md +++ b/docs/lora_ota_automation.md @@ -4,6 +4,9 @@ # Scripted LoRa OTA from start to finish +For a manual example using a Pi-connected repeater and the app's admin console, +see [Station G2 to Ikoka Stick](ota_station_g2_to_ikoka_stick.md). + For **[1.18.0.1 USA Cascade](releases/1.18.0.1.md)**, download the exact board, role and storage profile from the [firmware picker](firmware_picker.md). For a new nRF52 installation, use the matching diff --git a/docs/ota_easy.md b/docs/ota_easy.md index fe5e120b8..0251224ae 100644 --- a/docs/ota_easy.md +++ b/docs/ota_easy.md @@ -22,6 +22,10 @@ LoRa. Choose the package type for the **destination** node: For an end-to-end controller that accepts a release ZIP or ready mOTA, see [Scripted LoRa OTA from start to finish](lora_ota_automation.md). +For a complete manual example with one Pi-connected seeder, see +[Station G2 to Ikoka Stick](ota_station_g2_to_ikoka_stick.md), including both +bootloader and firmware installation. + | Destination | Update type | Files needed to build the `.mota` | Installer | | --- | --- | --- | --- | | ESP32 | Full firmware | New non-merged application `.bin` | ESP32 A/B firmware slots | diff --git a/docs/ota_station_g2_to_ikoka_stick.md b/docs/ota_station_g2_to_ikoka_stick.md new file mode 100644 index 000000000..d4e49e818 --- /dev/null +++ b/docs/ota_station_g2_to_ikoka_stick.md @@ -0,0 +1,375 @@ + +
View this page on MeshCore Docs.
+ + +# LoRa OTA example: Station G2 on a Pi to an Ikoka Stick + +Update the Ikoka Stick's bootloader to **OTAFIX 2.4.12**, then install +**1.18.0.1 Full Repeater** firmware. The Station G2 stays connected to the Pi +by USB and serves the files. Use the app's authenticated Repeater Admin console for the Ikoka +Stick, through your existing Companion. + +| Board | Job | +| --- | --- | +| Raspberry Pi | Runs the file server | +| Station G2 Repeater | USB-connected LoRa seeder | +| Ikoka Stick 33 dBm Repeater | Receives and installs both updates | +| Companion | Keeps the app connected to the Ikoka Stick's admin console | + +This example requires a **direct LoRa link** between the Station G2 and Ikoka +Stick. It keeps their existing main-channel settings during a four-hour +TempRadio window. The Companion stays on that same channel. Only the Station +G2 needs a USB connection to the Pi. For a route through intermediate +repeaters, every relay also needs an overlapping TempRadio window; see the +[scripted update guide](lora_ota_automation.md). + +## 1. Check the Ikoka Stick + +Run these in **Ikoka Stick — Repeater Admin** and save the replies: + +```text +ver +get bootloader.ver +ota self +ota qspi +ota bootloader status +ota config +ota key list +get radio +get radio.rxps.config +``` + +The example starts with these reported values: + +| Check | Required value for this example | +| --- | --- | +| Application hardware / target | `ikoka_stick_nrf_33dbm` / `E5331F02` | +| Installed bootloader | OTAFIX 2.4.11 | +| Bootloader identity | Board and target `28860044`, device `XIAO_DFU` | +| Bootloader support | `abi=3 caps=0E`, `QSPI apply OK`, `codecs=0x5` | +| Storage | `QSPI store:2048K`, working `ota qspi` probe | + +These values support a remote bootloader upgrade. A stock bootloader or +missing QSPI apply support needs the matching local installation first. +The Stick uses its onboard flash; no additional storage is needed. + +If `get radio.rxps.config` is unavailable, record `get radio.rxps` instead. +Keep each board's original RXPS and `ota config` replies for cleanup. + +## 2. Install the Pi tools + +On **Raspberry Pi — terminal**, install the host dependencies: + +```bash +sudo apt update +sudo apt install -y build-essential pkg-config libudev-dev libssl-dev curl unzip pipx python3-venv +pipx ensurepath +pipx install 'meshcore-cli>=1.6.0' +``` + +Install stable [Rust](https://rustup.rs/) if it is not already installed: + +```bash +curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs -o /tmp/meshcore-rustup.sh +sh /tmp/meshcore-rustup.sh -y --profile minimal +``` + +Open a new terminal so the Pi finds `meshcli` and Cargo. Check that both Rust +and Cargo are **1.86 or newer**, then install the supported motatool revision: + +```bash +rustc --version +cargo --version +cargo install --git https://github.com/mikecarper/motatool.git \ + --rev 8c38369e7d35ad50cf74261869676d52dd24adf7 --locked --bin motatool +meshcli -v +motatool --version +mkdir -p ~/ikoka-stick-ota/downloads ~/ikoka-stick-ota/inputs ~/ikoka-stick-ota/serve +cd ~/ikoka-stick-ota +``` + +## 3. Prepare the two update files + +On **Raspberry Pi — terminal**, download the signed bootloader bundle: + +```bash +BOOT_URL=https://github.com/mikecarper/Adafruit_nRF52_Bootloader_OTAFIX/releases/download/v0.11.0-OTAFIX2.4.12 +curl -fL "$BOOT_URL/OTAFIX-2.4.12-bootloader-mota.zip" -o downloads/bootloader-2.4.12.zip +unzip -q downloads/bootloader-2.4.12.zip -d inputs/bootloader-2.4.12 +cp inputs/bootloader-2.4.12/mota/update-xiao_nrf52840_ble_bootloader-v0.11.0-OTAFIX2.4.12.mota serve/ +BOOT_MOTA=serve/update-xiao_nrf52840_ble_bootloader-v0.11.0-OTAFIX2.4.12.mota +OTAFIX_PUBLIC_KEY=272564CC588D3D122285A15E6E2566D2ABE7177BB7EA1D1E41B23B29F0F85D2D +BOOT_KEY_FILE=inputs/bootloader-2.4.12/OTAFIX_MOTA_SIGNING_PUBLIC_KEY.txt +test "$(tr -d '[:space:]' < "$BOOT_KEY_FILE")" = "$OTAFIX_PUBLIC_KEY" +motatool verify "$BOOT_MOTA" --pub "$BOOT_KEY_FILE" +motatool inspect "$BOOT_MOTA" +``` + +The bootloader package must be signed, format 3, for **XIAO nRF52840 BLE** / +`XIAO_DFU`, target `28860044`, version 2.4.12. The key comparison and package +verification must both pass before continuing. + +Download the exact ordinary **Ikoka Stick 33 dBm Full Repeater** application +DFU ZIP on **Raspberry Pi — terminal**: + +```bash +APP_URL=https://github.com/mikecarper/MeshCore/releases/download/lora-ota-2-v1.18.0.1-halo-keymind-cascade-dev-03214a16 +curl -fL "$APP_URL/ikoka_stick_nrf_33dbm_repeater-full-ota-v1.18.0.1-halo-keymind-cascade-dev-03214a16.zip" \ + -o downloads/ikoka-stick-33dbm-repeater.zip +``` + +For a later release, use the [firmware picker](firmware_picker.md) to select +the same board, Repeater role, Full profile, and application DFU ZIP. + +On **Raspberry Pi — terminal**, extract the application binary named by the +DFU manifest and check its firmware identity trailer: + +```bash +python3 - <<'PY' +import hashlib, json, struct, zipfile +from pathlib import Path +with zipfile.ZipFile('downloads/ikoka-stick-33dbm-repeater.zip') as archive: + app = json.loads(archive.read('manifest.json'))['manifest']['application'] + image = archive.read(app['bin_file']) +trailer = image[-56:] +assert len(trailer) == 56 and trailer[:4] == b'EndF', 'Missing EndF' +assert struct.unpack_from(' flash +ota status +``` + +Check progress until it reports **ready to install**, then run: + +```text +ota bootloader status +``` + +Confirm `staged:ready`. Copy that reply's exact `mid` and 16-character `hash`: + +```text +ota bootloader install