From b38ba665b19db9505af3719f937f6be3224eb9b7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pascal=20J=C3=A4ger?= Date: Mon, 8 Jun 2026 08:50:36 +0200 Subject: [PATCH 1/7] feat(dfu): add DFU support for RP2040, add dfu_lock MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Pascal Jäger --- docs/docs/main/docs/configuration/appendix.md | 2 + .../main/docs/configuration/chip_config.md | 47 - .../main/docs/configuration/chip_config.mdx | 187 + docs/docs/main/docs/user_guide/_meta.json | 8 +- .../index.mdx} | 0 .../flash_firmware/use_embassy_boot.mdx | 166 + .../rp2040_embassy_boot/.cargo/config.toml | 12 + .../use_config/rp2040_embassy_boot/Cargo.lock | 3045 ++++++++++++++++ .../use_config/rp2040_embassy_boot/Cargo.toml | 55 + .../use_config/rp2040_embassy_boot/build.rs | 54 + .../rp2040_embassy_boot/keyboard.toml | 65 + .../use_config/rp2040_embassy_boot/memory.x | 8 + .../rp2040_embassy_boot/src/main.rs | 7 + .../use_config/rp2040_embassy_boot/vial.json | 37 + .../rp2040_embassy_boot/.cargo/config.toml | 11 + .../use_rust/rp2040_embassy_boot/Cargo.lock | 3046 +++++++++++++++++ .../use_rust/rp2040_embassy_boot/Cargo.toml | 58 + .../use_rust/rp2040_embassy_boot/build.rs | 53 + .../use_rust/rp2040_embassy_boot/memory.x | 8 + .../rp2040_embassy_boot/src/keymap.rs | 23 + .../rp2040_embassy_boot/src/macros.rs | 12 + .../use_rust/rp2040_embassy_boot/src/main.rs | 166 + .../use_rust/rp2040_embassy_boot/src/vial.rs | 1 + .../use_rust/rp2040_embassy_boot/vial.json | 37 + rmk-config/src/default_config/pi_pico_w.toml | 5 +- rmk-config/src/default_config/rp2040.toml | 5 +- rmk-config/src/dfu.rs | 7 + rmk-config/src/lib.rs | 40 + rmk-config/src/resolved/hardware.rs | 55 + rmk-macro/Cargo.toml | 1 + rmk-macro/src/codegen/chip/flash.rs | 87 +- rmk-macro/src/codegen/orchestrator.rs | 26 + rmk/Cargo.toml | 12 + rmk/src/dfu.rs | 457 +++ rmk/src/lib.rs | 2 + rmk/src/usb/mod.rs | 24 +- 36 files changed, 7768 insertions(+), 61 deletions(-) delete mode 100644 docs/docs/main/docs/configuration/chip_config.md create mode 100644 docs/docs/main/docs/configuration/chip_config.mdx rename docs/docs/main/docs/user_guide/{flash_firmware.mdx => flash_firmware/index.mdx} (100%) create mode 100644 docs/docs/main/docs/user_guide/flash_firmware/use_embassy_boot.mdx create mode 100644 examples/use_config/rp2040_embassy_boot/.cargo/config.toml create mode 100644 examples/use_config/rp2040_embassy_boot/Cargo.lock create mode 100644 examples/use_config/rp2040_embassy_boot/Cargo.toml create mode 100644 examples/use_config/rp2040_embassy_boot/build.rs create mode 100644 examples/use_config/rp2040_embassy_boot/keyboard.toml create mode 100644 examples/use_config/rp2040_embassy_boot/memory.x create mode 100644 examples/use_config/rp2040_embassy_boot/src/main.rs create mode 100644 examples/use_config/rp2040_embassy_boot/vial.json create mode 100644 examples/use_rust/rp2040_embassy_boot/.cargo/config.toml create mode 100644 examples/use_rust/rp2040_embassy_boot/Cargo.lock create mode 100644 examples/use_rust/rp2040_embassy_boot/Cargo.toml create mode 100644 examples/use_rust/rp2040_embassy_boot/build.rs create mode 100644 examples/use_rust/rp2040_embassy_boot/memory.x create mode 100644 examples/use_rust/rp2040_embassy_boot/src/keymap.rs create mode 100644 examples/use_rust/rp2040_embassy_boot/src/macros.rs create mode 100644 examples/use_rust/rp2040_embassy_boot/src/main.rs create mode 100644 examples/use_rust/rp2040_embassy_boot/src/vial.rs create mode 100644 examples/use_rust/rp2040_embassy_boot/vial.json create mode 100644 rmk-config/src/dfu.rs create mode 100644 rmk/src/dfu.rs diff --git a/docs/docs/main/docs/configuration/appendix.md b/docs/docs/main/docs/configuration/appendix.md index 39dace57f..e3cee5513 100644 --- a/docs/docs/main/docs/configuration/appendix.md +++ b/docs/docs/main/docs/configuration/appendix.md @@ -233,6 +233,8 @@ low_active = false # Whether the storage is enabled enabled = true # The start address of storage +# Note: When the `dfu_rp` feature is enabled, this value is ignored. +# The storage partition is automatically placed after the DFU download slot. start_addr = 0xA0000 # Number of sectors used for storage, >= 2 num_sectors = 16 diff --git a/docs/docs/main/docs/configuration/chip_config.md b/docs/docs/main/docs/configuration/chip_config.md deleted file mode 100644 index 14ac9f71b..000000000 --- a/docs/docs/main/docs/configuration/chip_config.md +++ /dev/null @@ -1,47 +0,0 @@ -# Chip-Specific Configuration - -The `[chip.]` section allows you to configure chip-specific settings for different microcontrollers. These settings are optional and only needed when you want to override the default behavior. - -## nRF52840 - -### DCDC Configuration - -The nRF52840 has two DC/DC regulators that can improve power efficiency when enabled with proper hardware support. - -#### Configuration Example - -```toml -[chip.nrf52840] -# Enable DCDC regulator 0 -dcdc_reg0 = true -# Enable DCDC regulator 1 -dcdc_reg1 = true -# Set DCDC regulator 0 voltage -dcdc_reg0_voltage = "3V3" # Options: "3V3" or "1V8" -``` - -::: danger Hardware Requirement -Do not enable DC/DC regulators without an external LC filter being connected, as this will inhibit device operation, including debug access, until an LC filter is connected. -::: -::: danger Bootloader Version -If your hardware is using the [Adafruit nRF52 Bootloader](https://github.com/adafruit/Adafruit_nRF52_Bootloader) (e.g. nice!nano) ensure that your bootloader is updated to version ≥ [0.10.0](https://github.com/adafruit/Adafruit_nRF52_Bootloader/releases/tag/0.10.0) when setting a voltage other than 3V3. -There is a bug in older versions that can lead to a boot loop which can only be fixed by re-flashing the bootloader via the debug interface. -::: - -## nRF52833 - -### DCDC Configuration - -The nRF52833 has one DC/DC regulator available for configuration. - -#### Configuration Example - -```toml -[chip.nrf52833] -# Enable DCDC regulator 1 -dcdc_reg1 = true -``` - -::: danger Hardware Requirement -Do not enable DC/DC regulator without an external LC filter being connected, as this will inhibit device operation, including debug access, until an LC filter is connected. -::: diff --git a/docs/docs/main/docs/configuration/chip_config.mdx b/docs/docs/main/docs/configuration/chip_config.mdx new file mode 100644 index 000000000..987045583 --- /dev/null +++ b/docs/docs/main/docs/configuration/chip_config.mdx @@ -0,0 +1,187 @@ +# Chip-Specific Configuration + +The `[chip.]` section allows you to configure chip-specific settings for different microcontrollers. These settings are optional and only needed when you want to override the default behavior. + +## RP2040 (with embassy-boot bootloader) + +When using the embassy-boot bootloader on RP2040, add a `[dfu]` section to your `keyboard.toml` (or use the Rust API directly). + +import { Tab, Tabs, Rust, Toml } from '@theme' + + +}> + +```toml title="keyboard.toml" +[dfu] +# (Optional) Total flash size in bytes. Used to auto-calculate partition addresses. +# Defaults to 2 MB (2097152) when omitted. +flash_size = 2097152 + +# (Optional) Flash page size in bytes (4096 for RP2040). +page_size = 4096 + +# (Optional) DFU activity LED pin, default "PIN_25". +led = "PIN_25" +led = "none" to omit DFU LED + +# (Optional) Unlock keys for dfu_lock (physical matrix positions). Only works with dfu_lock feature enabled. +# Format: [[row, col], [row, col], ...] +unlock_keys = [[0, 0], [1, 1]] + +# ── (Optional) Manual overrides (only if auto-calculation is not suitable) ── +# state_offset = 0x6000 +# state_size = 0x1000 +# dfu_offset = 0x87000 +# dfu_size = 528384 +``` + + +}> + +```rust title="main.rs" +// Flash layout using the bootymcbootface formula: +// state at 0x6000 (4K), active from 0x7000 (size: (flash_size - 28K (= BOOT2 size + embassy-boot + embassy-boot state) - STORAGE_SIZE (= 128K) - page_size (= 4K)) / 2), +// dfu follows active (active_size + page_size (= 4K)) +// +// All offsets (DFU_OFFSET, DFU_SIZE, STORAGE_OFFSET, etc.) are derived +// automatically from FLASH_SIZE below — change only that constant when using bootymcbootface. +// +// ⚠ You can define your own FLASH_SIZE and addresses, but then you must build and +// flash a custom embassy-boot bootloader with a matching memory.x! +const FLASH_SIZE: u32 = 2 * 1024 * 1024; // 2 MB (default) +// const FLASH_SIZE: u32 = 4 * 1024 * 1024; // 4 MB +// const FLASH_SIZE: u32 = 8 * 1024 * 1024; // 8 MB +// const FLASH_SIZE: u32 = 16 * 1024 * 1024; // 16 MB +const PAGE_SIZE: u32 = 4 * 1024; +const STORAGE_SIZE: u32 = 128 * 1024; // 32 sectors × 4K after ACTIVE+DFU +const STATE_OFFSET: u32 = 0x6000; +const STATE_SIZE: u32 = 0x1000; +const ACTIVE_OFFSET: u32 = 0x7000; // after 28K bootloader + state +let remaining: u32 = FLASH_SIZE + - 28 * 1024 // size of boot 2 + embassy-boot + embassy-boot state + - STORAGE_SIZE; +let active_size: u32 = (remaining - PAGE_SIZE) / 2; // DFU = ACTIVE + 1 page (embassy-boot requirement) +let dfu_size: u32 = active_size + PAGE_SIZE; // embassy-boot needs that extra page for swap info +let dfu_offset: u32 = ACTIVE_OFFSET + active_size; // dfu after active +let storage_offset: u32 = dfu_offset + dfu_size; // storage after active + dfu +let storage_size: u32 = STORAGE_SIZE; +assert!(storage_offset + storage_size == FLASH_SIZE); // sanity check that we fit everything in flash + +info!( + "Flash layout: state @ 0x{:04X} ({}K), active @ 0x{:04X} ({}K), dfu @ 0x{:04X} ({}K), storage @ 0x{:04X} ({}K)", + STATE_OFFSET, + STATE_SIZE / 1024, + ACTIVE_OFFSET, + active_size / 1024, + dfu_offset, + dfu_size / 1024, + storage_offset, + storage_size / 1024 +); + +let flash = async_flash_wrapper(rmk::dfu::init_flash( + p.FLASH, + storage_offset, + storage_size, + STATE_OFFSET, + STATE_SIZE, + dfu_offset, + dfu_size, +)); + +// Optional: assign a DFU activity LED +rmk::dfu::set_led(Some(Output::new(p.PIN_25, Level::Low))); + +// Mark boot as successful (so bootloader doesn't revert on reset) +rmk::dfu::mark_booted(); + +// Optional: DFU lock with physical key unlock. Requires the `dfu_lock` Cargo feature. +let unlock_keys: &[(u8, u8)] = &[(0, 0), (1, 1)]; +let mut dfu_lock = ::rmk::dfu::DfuLock::new(unlock_keys, &keymap); +// Then add dfu_lock in run_all!() +// ... + run_all!( + // other processors ... + dfu_lock, + ) +``` + + + + +### Partition layout + +The bootloader divides flash into regions. The defaults follow the [bootymcbootface](https://codeberg.org/Schievel/bootymcbootface/) convention and are automatically calculated from `flash_size`: + +| Region | Offset | Size | +|-----------------|------------------|------------------------------------------------------------------------------------| +| Bootloader | `0x0000000` | 28 KB | +| Boot state | `0x6000` (24 KB) | 4 KB | +| Active firmware | `0x7000` (28 KB) | (flash_size - 28K (= BOOT2 size + embassy-boot + embassy-boot state) - STORAGE_SIZE - page_size) / 2| +| DFU download | follows active | `active_size + page_size` | +| Storage | follows DFU | rest of flash | + +The DFU partition size follows embassy-boot guidelines, the additional page is used for status information during flashing. + +All `[dfu]` fields are optional. The partition values are auto-calculated from `flash_size` and `page_size` using the bootymcbootface formula. If you supply any of `state_offset`, `state_size`, `dfu_offset`, or `dfu_size` directly, auto-calculation is disabled and your values are used as-is. + +Your `memory.x` must match this partition layout — see the [flashing guide](../user_guide/flash_firmware/use_embassy_boot.mdx) for details. + +#### `led` (optional) + +A GPIO pin for the DFU LED. On the Raspberry Pi Pico, the built-in LED is on pin 25. +See the [LED behavior table](../user_guide/flash_firmware/use_embassy_boot.mdx#led-behavior-during-dfu-transfer-optional) for the full state machine. + +#### `unlock_keys` (optional, dfu_lock) + +Physical key positions that unlock DFU firmware downloads. Requires the `dfu_lock` Cargo feature. Keys are identified by their matrix position `(row, column)`, not by keycode. + +Detailed unlock workflow in the [DFU lock section](../user_guide/flash_firmware/use_embassy_boot.mdx#unlocking-dfu-optional-dfu_lock). + +::: tip +Choose keys that are easy to press simultaneously but not commonly pressed together accidentally. +::: + +## nRF52840 + +### DCDC Configuration + +The nRF52840 has two DC/DC regulators that can improve power efficiency when enabled with proper hardware support. + +#### Configuration Example + +```toml +[chip.nrf52840] +# Enable DCDC regulator 0 +dcdc_reg0 = true +# Enable DCDC regulator 1 +dcdc_reg1 = true +# Set DCDC regulator 0 voltage +dcdc_reg0_voltage = "3V3" # Options: "3V3" or "1V8" +``` + +::: danger Hardware Requirement +Do not enable DC/DC regulators without an external LC filter being connected, as this will inhibit device operation, including debug access, until an LC filter is connected. +::: +::: danger Bootloader Version +If your hardware is using the [Adafruit nRF52 Bootloader](https://github.com/adafruit/Adafruit_nRF52_Bootloader) (e.g. nice!nano) ensure that your bootloader is updated to version ≥ [0.10.0](https://github.com/adafruit/Adafruit_nRF52_Bootloader/releases/tag/0.10.0) when setting a voltage other than 3V3. +There is a bug in older versions that can lead to a boot loop which can only be fixed by re-flashing the bootloader via the debug interface. +::: + +## nRF52833 + +### DCDC Configuration + +The nRF52833 has one DC/DC regulator available for configuration. + +#### Configuration Example + +```toml +[chip.nrf52833] +# Enable DCDC regulator 1 +dcdc_reg1 = true +``` + +::: danger Hardware Requirement +Do not enable DC/DC regulator without an external LC filter being connected, as this will inhibit device operation, including debug access, until an LC filter is connected. +::: diff --git a/docs/docs/main/docs/user_guide/_meta.json b/docs/docs/main/docs/user_guide/_meta.json index d264a89bb..0a1d7b27e 100644 --- a/docs/docs/main/docs/user_guide/_meta.json +++ b/docs/docs/main/docs/user_guide/_meta.json @@ -7,5 +7,11 @@ "collapsible": false, "collapsed": false }, - "flash_firmware" + { + "type": "dir", + "name": "flash_firmware", + "label": "Flashing Firmware", + "collapsible": false, + "collapsed": false + } ] diff --git a/docs/docs/main/docs/user_guide/flash_firmware.mdx b/docs/docs/main/docs/user_guide/flash_firmware/index.mdx similarity index 100% rename from docs/docs/main/docs/user_guide/flash_firmware.mdx rename to docs/docs/main/docs/user_guide/flash_firmware/index.mdx diff --git a/docs/docs/main/docs/user_guide/flash_firmware/use_embassy_boot.mdx b/docs/docs/main/docs/user_guide/flash_firmware/use_embassy_boot.mdx new file mode 100644 index 000000000..ee1ff0d52 --- /dev/null +++ b/docs/docs/main/docs/user_guide/flash_firmware/use_embassy_boot.mdx @@ -0,0 +1,166 @@ +# Use embassy-boot bootloader + +::: tip +This feature is only available for **RP2040** (Raspberry Pi Pico, Pi Pico W, and other RP2040 boards). +::: + +[embassy-boot](https://github.com/embassy-rs/embassy/tree/main/embassy-boot) is a bootloader framework from the Embassy project. It splits the flash into two firmware slots (active and DFU download), so updating is **safe even if power is lost or the transfer fails** — the old firmware remains intact and the bootloader can roll back automatically. You can build your own bootloader using the `embassy-boot-rp` crate, or use a pre-built one like **bootymcbootface**. + +[bootymcbootface](https://codeberg.org/Schievel/bootymcbootface/) is a pre-built embassy-boot bootloader for RP2040. It sits at the beginning of flash and handles the dual-slot firmware switching and rollback on boot. RMK itself provides the DFU USB interface (via `embassy-usb-dfu`) for subsequent updates, so once bootymcbootface and RMK are flashed, you never need to press BOOTSEL again. + +RMK and bootymcbootface use an **identical partition formula** so the layout always fits perfectly: + +```rust +// bootloader+state = 28K (fixed) +// storage = 128K (fixed — 32 sectors × 4K for persistent keymap storage) +// remaining = flash_size - 28K - 128K +// ACTIVE = (remaining - 4K) / 2 +// DFU = ACTIVE + 4K (1 page delta required by embassy-boot swap) +``` + +The 4K page delta is an **invariant of embassy-boot's swap algorithm**: the DFU slot must always be exactly one erase page larger than the ACTIVE slot. Storage is reserved at the end of flash and **cannot be reconfigured** when using bootymcbootface — it is always 128K (32 sectors × 4K). + +| Region | 2MB | 4MB | 8MB | 16MB | +|-------------|-------------------|-------------------|-------------------|-------------------| +| Boot+State | 28K (0x7000) | 28K (0x7000) | 28K (0x7000) | 28K (0x7000) | +| ACTIVE | **944K** (0xEC000)| **1968K** (0x1EC000) | **4016K** (0x3EC000) | **8112K** (0x7EC000) | +| DFU | **948K** (0xED000)| **1972K** (0x1ED000) | **4020K** (0x3ED000) | **8116K** (0x7ED000) | +| Storage | 128K (0x20000) | 128K (0x20000) | 128K (0x20000) | 128K (0x20000) | + +The size of the ACTIVE Region is what you need to plug in as the flash size in `memory.x`. + +If you override `flash_size` in your `keyboard.toml`'s `[dfu]` section, RMK's auto-calc recomputes the layout on the fly. You never need to manually set `dfu_offset` or `dfu_size` when using bootymcbootface. + +## Prerequisites + +### bootymcbootface + +You need the [bootymcbootface](https://codeberg.org/Schievel/bootymcbootface/) bootloader in the **correct flash size** for your board. The available versions are named by flash size, e.g.: + +- `bootymcbootface-rp2040-2mb.uf2` – for 2 MB flash +- `bootymcbootface-rp2040-4mb.uf2` – for 4 MB flash +- `bootymcbootface-rp2040-8mb.uf2` – for 8 MB flash +- `bootymcbootface-rp2040-16mb.uf2` – for 16 MB flash + +The **2 MB version works with larger flash chips too** (e.g. 4 MB or 8 MB), using only the first 2 MB. On 2 MB you get 944K of ACTIVE space, which is ample for most RMK firmwares. If you need more room (e.g. with large keymaps, Vial, or many features), pick the matching flash size variant — see the table above for exact slot sizes. + +### Compile RMK with DFU support + +RMK must be compiled with the `dfu` and `dfu_rp` features and the **matching flash size**. + +When using `rmkit init`, you will be asked whether you want to use embassy-boot and can enter the flash size. `rmkit` handles all necessary adjustments automatically. + +If configuring manually, ensure: + +- `Cargo.toml` uses the `dfu_rp` feature +- `keyboard.toml` has `[dfu]` section +- The flash partitioning in `memory.x` matches your bootloader and flash size (see `rmk/examples/use_rust/rp2040_embassy_boot/`) + +**Important:** The bootymcbootface version and the RMK compilation must use the **same flash size**. Example: bootymcbootface 2 MB → RMK with 2 MB flash configuration. + +::: tip +You can still flash firmware via UF2 or probe-rs — as long as it was built with the correct `memory.x` for the embassy-boot partition layout (i.e. with `dfu_rp` feature), it will land in the active firmware slot and leave bootymcbootface untouched. + +If you flash a RMK firmware built with a **normal** `memory.x` (without embassy-boot), it will start at flash address `0x0` and **overwrite bootymcbootface**. +::: + +::: tip +the embassy-boot bootloader and RMK will never overwrite the RP2040’s uf2 bootloader. It exists in ROM and can not be overwritten +::: + +## Step-by-step guide + +### First-time flashing + +The first time, you need to flash the bootloader first, then RMK. + +#### 1. Flash bootymcbootface + +**Method A – via UF2:** +1. Put your RP2040 into bootloader mode (hold BOOTSEL button, plug in USB, release) +2. A USB drive named `RPI-RP2` should appear +3. Copy the matching `bootymcbootface-rp2040-mb.uf2` to the drive +4. The RP2040 reboots – the bootloader is now active + +**Method B – via debug probe (probe-rs):** +```shell +probe-rs run --chip RP2040 bootymcbootface_ (elf) +# or +cargo run --release // in the bootymcbootface project directory +``` +(Make sure your project targets the bootloader binary) + +#### 2. Flash RMK firmware + +Now flash the actual RMK firmware. The bootloader stays in place. + +**Method A – via UF2:** +Put the board into bootloader mode (hold BOOTSEL button, plug in USB, release), then copy the RMK firmware `.uf2` file to the appearing `RPI-RP2` drive. + +**Method B – via debug probe (probe-rs):** +```shell +probe-rs run --chip RP2040 target/thumbv6m-none-eabi/release/your-firmware +``` + +### All subsequent updates via DFU + +Once bootymcbootface and the RMK firmware have been flashed once, all future updates can be done **easily over USB via DFU**. + +#### Generate the .bin file + +DFU flashing requires a `.bin` file (not `.elf` or `.uf2`). You have two options: + +**Option 1 – using `rust-objcopy` (or `arm-none-eabi-objcopy`):** +```shell +rust-objcopy -O binary target/thumbv6m-none-eabi/release/your-firmware your-firmware.bin +``` + +**Option 2 – using `cargo make bin`:** +```shell +cargo make bin --release +``` +(Requires a `Makefile.toml` with a `bin` task — the generated template from `rmkit` already includes one.) + +#### Flash via dfu-util + +```shell +dfu-util -a 0 -d ,, -D your-firmware.bin +``` + +Or with a device ID if multiple devices are connected: +```shell +dfu-util -a 0 -d 1209:1234 -D your-firmware.bin +``` + +Find your device's VID:PID via `lsusb` on Linux or Device Manager (under "Universal Serial Bus devices") on Windows. + +**Installing `dfu-util`:** +- Linux: `sudo apt install dfu-util` (Debian/Ubuntu) or `sudo pacman -S dfu-util` (Arch) +- macOS: `brew install dfu-util` +- Windows: Download from [dfu-util.sourceforge.net](https://dfu-util.sourceforge.net/) + +`dfu-util` will automatically detect the board — the RMK firmware exposes a DFU USB interface at runtime. No need to press BOOTSEL or trigger a special mode. (With the optional `dfu_lock` feature, DFU downloads require a physical key press to unlock — see below.) + +#### Unlocking DFU (optional, dfu_lock) + +If your RMK was compiled with the `dfu_lock` feature, DFU starts in a **locked** state. To unlock: + +1. Run `dfu-util -D your-firmware.bin` — the download will be rejected, but this signals the keyboard to open the unlock window +2. The DFU LED turns **solid on** — you have **10 seconds** to press the `unlock_keys` combination configured in `keyboard.toml` (e.g. `[[0, 0], [1, 1]]`) +3. Once the keys are pressed, the LED blinks **"D F U"** in Morse code (`-.. ..-. ..-`) — the DFU lock is released for another **10 seconds** +4. Re-run `dfu-util -D your-firmware.bin` — this time the download proceeds, the LED flickers, and the firmware is updated +5. After the update completes, the LED turns off and the board reboots + +If you don't press the unlock keys within the first 10 seconds, the window closes and the LED turns off. If no DFU download starts within the unlocked 10 seconds, the lock re-engages automatically. In both cases just repeat from step 1. + +#### LED behavior during DFU transfer (optional) + +If an LED pin is configured in `keyboard.toml` (default PIN_25, if not `[dfu] led = "none"`): + +| State | LED behavior | +|---|---|---| +| Unlock window open (waiting for keys) | Solid on | +| DFU unlocked (ready for dfu-util) | Blinks Morse "D F U" | +| DFU download started | On | +| Writing data blocks | Toggles on each block (flickers) | +| DFU finished / system reset | Off | diff --git a/examples/use_config/rp2040_embassy_boot/.cargo/config.toml b/examples/use_config/rp2040_embassy_boot/.cargo/config.toml new file mode 100644 index 000000000..f737cdf64 --- /dev/null +++ b/examples/use_config/rp2040_embassy_boot/.cargo/config.toml @@ -0,0 +1,12 @@ +[target.'cfg(all(target_arch = "arm", target_os = "none"))'] +runner = "probe-rs run --chip RP2040" +# runner = "elf2uf2-rs -d" + +linker = "flip-link" + +[build] +target = "thumbv6m-none-eabi" + +[env] +DEFMT_LOG = "debug" +KEYBOARD_TOML_PATH = { value = "keyboard.toml", relative = true } diff --git a/examples/use_config/rp2040_embassy_boot/Cargo.lock b/examples/use_config/rp2040_embassy_boot/Cargo.lock new file mode 100644 index 000000000..c05c607ed --- /dev/null +++ b/examples/use_config/rp2040_embassy_boot/Cargo.lock @@ -0,0 +1,3045 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 4 + +[[package]] +name = "aes" +version = "0.8.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b169f7a6d4742236a0a00c541b845991d0ac43e546831af1249753ab4c3aa3a0" +dependencies = [ + "cfg-if", + "cipher", + "cpufeatures", +] + +[[package]] +name = "ahash" +version = "0.8.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5a15f179cd60c4584b8a8c596927aadc462e27f2ca70c04e0071964a73ba7a75" +dependencies = [ + "cfg-if", + "once_cell", + "version_check", + "zerocopy", +] + +[[package]] +name = "aho-corasick" +version = "1.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ddd31a130427c27518df266943a5308ed92d4b226cc639f5a8f1002816174301" +dependencies = [ + "memchr", +] + +[[package]] +name = "arraydeque" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7d902e3d592a523def97af8f317b08ce16b7ab854c1985a0c671e6f15cebc236" + +[[package]] +name = "arrayvec" +version = "0.7.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7c02d123df017efcdfbd739ef81735b36c5ba83ec3c59c80a9d7ecc718f92e50" + +[[package]] +name = "ascii-canvas" +version = "4.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ef1e3e699d84ab1b0911a1010c5c106aa34ae89aeac103be5ce0c3859db1e891" +dependencies = [ + "term", +] + +[[package]] +name = "async-trait" +version = "0.1.89" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9035ad2d096bed7955a320ee7e2230574d28fd3c3a0f186cbea1ff3c7eed5dbb" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.117", +] + +[[package]] +name = "atomic-polyfill" +version = "1.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8cf2bce30dfe09ef0bfaef228b9d414faaf7e563035494d7fe092dba54b300f4" +dependencies = [ + "critical-section", +] + +[[package]] +name = "autocfg" +version = "1.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f2032f911046de80f0a198e0901378627c33f59ea0ac00e363d481118bd70a53" + +[[package]] +name = "az" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "be5eb007b7cacc6c660343e96f650fedf4b5a77512399eb952ca6642cf8d13f7" + +[[package]] +name = "bare-metal" +version = "0.2.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5deb64efa5bd81e31fcd1938615a6d98c82eafcbcd787162b6f63b91d6bac5b3" +dependencies = [ + "rustc_version 0.2.3", +] + +[[package]] +name = "base16ct" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4c7f02d4ea65f2c1853089ffd8d2787bdbc63de2f0d29dedbcf8ccdfa0ccd4cf" + +[[package]] +name = "bit-set" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "08807e080ed7f9d5433fa9b275196cfc35414f66a0c79d864dc51a0d825231a3" +dependencies = [ + "bit-vec", +] + +[[package]] +name = "bit-vec" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5e764a1d40d510daf35e07be9eb06e75770908c27d411ee6c92109c9840eaaf7" + +[[package]] +name = "bitfield" +version = "0.13.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "46afbd2983a5d5a7bd740ccb198caf5b82f45c40c09c0eed36052d91cb92e719" + +[[package]] +name = "bitfield" +version = "0.14.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2d7e60934ceec538daadb9d8432424ed043a904d8e0243f3c6446bce549a46ac" + +[[package]] +name = "bitfield-struct" +version = "0.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3ca6739863c590881f038d033a146c51ddae239186a4327014839fd864f44ed5" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.117", +] + +[[package]] +name = "bitflags" +version = "1.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" + +[[package]] +name = "bitflags" +version = "2.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b4388bee8683e3d04af747c73422af53102d2bd24d9eadb6cbc100baef4b43f8" +dependencies = [ + "serde_core", +] + +[[package]] +name = "block-buffer" +version = "0.10.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3078c7629b62d3f0439517fa394996acacc5cbc91c5a20d8c658e77abd503a71" +dependencies = [ + "generic-array", +] + +[[package]] +name = "bt-hci" +version = "0.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "211713d2e9fb4793ce4360a712c0764264aff6be48932ccf02ca2a331c0436a9" +dependencies = [ + "btuuid", + "defmt 1.1.0", + "embassy-sync", + "embedded-io 0.7.1", + "embedded-io-async 0.7.0", + "futures-intrusive", + "heapless 0.9.3", + "serde", +] + +[[package]] +name = "btuuid" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f5f48f1e9b0aad0a4f05d17bdeae0fa20ff798e272a03a6940ca27ad9c5a6ae7" +dependencies = [ + "defmt 0.3.100", + "serde", + "uuid", +] + +[[package]] +name = "bumpalo" +version = "3.20.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "72f5acc6cb2ba439de613abc23857ec3d78374d8ed5ac84e9d11336e87da8649" + +[[package]] +name = "bytemuck" +version = "1.25.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c8efb64bd706a16a1bdde310ae86b351e4d21550d98d056f22f8a7f7a2183fec" + +[[package]] +name = "byteorder" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" + +[[package]] +name = "cargo_toml" +version = "0.22.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "374b7c592d9c00c1f4972ea58390ac6b18cbb6ab79011f3bdc90a0b82ca06b77" +dependencies = [ + "serde", + "toml 0.9.12+spec-1.1.0", +] + +[[package]] +name = "cc" +version = "1.2.63" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "556e016178bb5662a08681bbe0f00f8e17631781a4dfc8c45e466e4b185ec27f" +dependencies = [ + "find-msvc-tools", + "shlex", +] + +[[package]] +name = "cfg-if" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9330f8b2ff13f34540b44e946ef35111825727b38d33286ef986142615121801" + +[[package]] +name = "chrono" +version = "0.4.45" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1aa79e62e7697b8e29b513a68abacf485adcd1fe8284a4316c5ae868e6633327" +dependencies = [ + "defmt 1.1.0", + "num-traits", + "pure-rust-locales", +] + +[[package]] +name = "cipher" +version = "0.4.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "773f3b9af64447d2ce9850330c473515014aa235e6a783b02db81ff39e4a3dad" +dependencies = [ + "crypto-common", + "inout", +] + +[[package]] +name = "cmac" +version = "0.7.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8543454e3c3f5126effff9cd44d562af4e31fb8ce1cc0d3dcd8f084515dbc1aa" +dependencies = [ + "cipher", + "dbl", + "digest", +] + +[[package]] +name = "cobs" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0fa961b519f0b462e3a3b4a34b64d119eeaca1d59af726fe450bbba07a9fc0a1" +dependencies = [ + "thiserror", +] + +[[package]] +name = "codespan-reporting" +version = "0.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3538270d33cc669650c4b093848450d380def10c331d38c768e34cac80576e6e" +dependencies = [ + "termcolor", + "unicode-width", +] + +[[package]] +name = "config" +version = "0.15.23" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f316c6237b2d38be61949ecd15268a4c6ca32570079394a2444d9ce2c72a72d8" +dependencies = [ + "async-trait", + "convert_case 0.6.0", + "json5", + "pathdiff", + "ron", + "rust-ini", + "serde-untagged", + "serde_core", + "serde_json", + "toml 1.1.2+spec-1.1.0", + "winnow 1.0.3", + "yaml-rust2", +] + +[[package]] +name = "const-gen" +version = "1.6.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a0bb51eeea292ceb9bf5312b4416c1b151b130502e6892a2ae174ae1e4b51e58" +dependencies = [ + "const-gen-derive", +] + +[[package]] +name = "const-gen-derive" +version = "1.1.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eabc01a5585d36649b6bee1f1198d112a7bb4982661d6c18406fba571ce3263e" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "const-oid" +version = "0.9.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c2459377285ad874054d797f3ccebf984978aa39129f6eafde5cdc8315b612f8" + +[[package]] +name = "const-random" +version = "0.1.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "87e00182fe74b066627d63b85fd550ac2998d4b0bd86bfed477a0ae4c7c71359" +dependencies = [ + "const-random-macro", +] + +[[package]] +name = "const-random-macro" +version = "0.1.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f9d839f2a20b0aee515dc581a6172f2321f96cab76c1a38a4c584a194955390e" +dependencies = [ + "getrandom", + "once_cell", + "tiny-keccak", +] + +[[package]] +name = "convert_case" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ec182b0ca2f35d8fc196cf3404988fd8b8c739a4d270ff118a398feb0cbec1ca" +dependencies = [ + "unicode-segmentation", +] + +[[package]] +name = "convert_case" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "baaaa0ecca5b51987b9423ccdc971514dd8b0bb7b4060b983d3664dad3f1f89f" +dependencies = [ + "unicode-segmentation", +] + +[[package]] +name = "cordyceps" +version = "0.3.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "688d7fbb8092b8de775ef2536f36c8c31f2bc4006ece2e8d8ad2d17d00ce0a2a" +dependencies = [ + "loom", + "tracing", +] + +[[package]] +name = "cortex-m" +version = "0.7.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8ec610d8f49840a5b376c69663b6369e71f4b34484b9b2eb29fb918d92516cb9" +dependencies = [ + "bare-metal", + "bitfield 0.13.2", + "embedded-hal 0.2.7", + "volatile-register", +] + +[[package]] +name = "cortex-m-rt" +version = "0.7.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "801d4dec46b34c299ccf6b036717ae0fce602faa4f4fe816d9013b9a7c9f5ba6" +dependencies = [ + "cortex-m-rt-macros", +] + +[[package]] +name = "cortex-m-rt-macros" +version = "0.7.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e37549a379a9e0e6e576fd208ee60394ccb8be963889eebba3ffe0980364f472" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.117", +] + +[[package]] +name = "cpufeatures" +version = "0.2.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "59ed5838eebb26a2bb2e58f6d5b5316989ae9d08bab10e0e6d103e656d1b0280" +dependencies = [ + "libc", +] + +[[package]] +name = "crc-any" +version = "2.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a62ec9ff5f7965e4d7280bd5482acd20aadb50d632cf6c1d74493856b011fa73" +dependencies = [ + "debug-helper", +] + +[[package]] +name = "crc32fast" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9481c1c90cbf2ac953f07c8d4a58aa3945c425b7185c9154d67a65e4230da511" +dependencies = [ + "cfg-if", +] + +[[package]] +name = "critical-section" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "790eea4361631c5e7d22598ecd5723ff611904e3344ce8720784c93e3d83d40b" + +[[package]] +name = "crunchy" +version = "0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "460fbee9c2c2f33933d720630a6a0bac33ba7053db5344fac858d4b8952d77d5" + +[[package]] +name = "crypto-bigint" +version = "0.5.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0dc92fb57ca44df6db8059111ab3af99a63d5d0f8375d9972e319a379c6bab76" +dependencies = [ + "generic-array", + "rand_core 0.6.4", + "subtle", + "zeroize", +] + +[[package]] +name = "crypto-common" +version = "0.1.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "78c8292055d1c1df0cce5d180393dc8cce0abec0a7102adb6c7b1eef6016d60a" +dependencies = [ + "generic-array", + "typenum", +] + +[[package]] +name = "darling" +version = "0.20.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fc7f46116c46ff9ab3eb1597a45688b6715c6e628b5c133e288e709a29bcb4ee" +dependencies = [ + "darling_core 0.20.11", + "darling_macro 0.20.11", +] + +[[package]] +name = "darling" +version = "0.23.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "25ae13da2f202d56bd7f91c25fba009e7717a1e4a1cc98a76d844b65ae912e9d" +dependencies = [ + "darling_core 0.23.0", + "darling_macro 0.23.0", +] + +[[package]] +name = "darling_core" +version = "0.20.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0d00b9596d185e565c2207a0b01f8bd1a135483d02d9b7b0a54b11da8d53412e" +dependencies = [ + "fnv", + "ident_case", + "proc-macro2", + "quote", + "strsim", + "syn 2.0.117", +] + +[[package]] +name = "darling_core" +version = "0.23.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9865a50f7c335f53564bb694ef660825eb8610e0a53d3e11bf1b0d3df31e03b0" +dependencies = [ + "ident_case", + "proc-macro2", + "quote", + "strsim", + "syn 2.0.117", +] + +[[package]] +name = "darling_macro" +version = "0.20.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fc34b93ccb385b40dc71c6fceac4b2ad23662c7eeb248cf10d529b7e055b6ead" +dependencies = [ + "darling_core 0.20.11", + "quote", + "syn 2.0.117", +] + +[[package]] +name = "darling_macro" +version = "0.23.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ac3984ec7bd6cfa798e62b4a642426a5be0e68f9401cfc2a01e3fa9ea2fcdb8d" +dependencies = [ + "darling_core 0.23.0", + "quote", + "syn 2.0.117", +] + +[[package]] +name = "dbl" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bd2735a791158376708f9347fe8faba9667589d82427ef3aed6794a8981de3d9" +dependencies = [ + "generic-array", +] + +[[package]] +name = "debug-helper" +version = "0.3.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f578e8e2c440e7297e008bb5486a3a8a194775224bbc23729b0dbdfaeebf162e" + +[[package]] +name = "defmt" +version = "0.3.100" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f0963443817029b2024136fc4dd07a5107eb8f977eaf18fcd1fdeb11306b64ad" +dependencies = [ + "defmt 1.1.0", +] + +[[package]] +name = "defmt" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a6e524506490a1953d237cb87b1cfc1e46f88c18f10a22dfe0f507dc6bfc7f7f" +dependencies = [ + "bitflags 1.3.2", + "defmt-macros", +] + +[[package]] +name = "defmt-macros" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f0a27770e9c8f719a79d8b638281f4d828f77d8fd61e0bd94451b9b85e576a0b" +dependencies = [ + "defmt-parser", + "proc-macro-error2", + "proc-macro2", + "quote", + "syn 2.0.117", +] + +[[package]] +name = "defmt-parser" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "10d60334b3b2e7c9d91ef8150abfb6fa4c1c39ebbcf4a81c2e346aad939fee3e" +dependencies = [ + "thiserror", +] + +[[package]] +name = "defmt-rtt" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c0f73a4a4a91609e977ae3b7bd831ffa292edfd42ad140a3244a61d805b0e05e" +dependencies = [ + "critical-section", + "defmt 1.1.0", +] + +[[package]] +name = "der" +version = "0.7.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e7c1832837b905bbfb5101e07cc24c8deddf52f93225eee6ead5f4d63d53ddcb" +dependencies = [ + "const-oid", + "zeroize", +] + +[[package]] +name = "digest" +version = "0.10.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292" +dependencies = [ + "block-buffer", + "crypto-common", + "subtle", +] + +[[package]] +name = "dlv-list" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "442039f5147480ba31067cb00ada1adae6892028e40e45fc5de7b7df6dcc1b5f" +dependencies = [ + "const-random", +] + +[[package]] +name = "document-features" +version = "0.2.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d4b8a88685455ed29a21542a33abd9cb6510b6b129abadabdcef0f4c55bc8f61" +dependencies = [ + "litrs", +] + +[[package]] +name = "either" +version = "1.16.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "91622ff5e7162018101f2fea40d6ebf4a78bbe5a49736a2020649edf9693679e" + +[[package]] +name = "elliptic-curve" +version = "0.13.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b5e6043086bf7973472e0c7dff2142ea0b680d30e18d9cc40f267efbf222bd47" +dependencies = [ + "base16ct", + "crypto-bigint", + "digest", + "ff", + "generic-array", + "group", + "hkdf", + "rand_core 0.6.4", + "sec1", + "subtle", + "zeroize", +] + +[[package]] +name = "embassy-boot" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "73bfc955c9238df2ce9fecc6f18a64b13ecaa41a3cd42d940a09f304765d10db" +dependencies = [ + "digest", + "document-features", + "embassy-embedded-hal", + "embassy-sync", + "embedded-storage", + "embedded-storage-async", + "signature", +] + +[[package]] +name = "embassy-boot-rp" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3fc17df4cf2a8ba86e8559a6515104e31ca7aa6b36221199310e244157935204" +dependencies = [ + "cfg-if", + "cortex-m", + "cortex-m-rt", + "embassy-boot", + "embassy-rp", + "embassy-sync", + "embassy-time", + "embedded-storage", + "embedded-storage-async", +] + +[[package]] +name = "embassy-embedded-hal" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b0641612053b2f34fc250bb63f6630ae75de46e02ade7f457268447081d709ce" +dependencies = [ + "defmt 1.1.0", + "embassy-futures", + "embassy-hal-internal 0.4.0", + "embassy-sync", + "embassy-time", + "embedded-hal 0.2.7", + "embedded-hal 1.0.0", + "embedded-hal-async", + "embedded-storage", + "embedded-storage-async", + "nb 1.1.0", +] + +[[package]] +name = "embassy-executor" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5d0d3b15c9d7dc4fec1d8cb77112472fb008b3b28c51ad23838d83587a6d2f1e" +dependencies = [ + "cordyceps", + "cortex-m", + "critical-section", + "defmt 1.1.0", + "document-features", + "embassy-executor-macros", + "embassy-executor-timer-queue", +] + +[[package]] +name = "embassy-executor-macros" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d11a246f53de5f97a387f40ac24726817cd0b6f833e7603baac784f29d6ff276" +dependencies = [ + "darling 0.20.11", + "proc-macro2", + "quote", + "syn 2.0.117", +] + +[[package]] +name = "embassy-executor-timer-queue" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2fc328bf943af66b80b98755db9106bf7e7471b0cf47dc8559cd9a6be504cc9c" + +[[package]] +name = "embassy-futures" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dc2d050bdc5c21e0862a89256ed8029ae6c290a93aecefc73084b3002cdebb01" +dependencies = [ + "defmt 1.1.0", +] + +[[package]] +name = "embassy-hal-internal" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7f10ce10a4dfdf6402d8e9bd63128986b96a736b1a0a6680547ed2ac55d55dba" +dependencies = [ + "num-traits", +] + +[[package]] +name = "embassy-hal-internal" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "568659fc53866d3d85c60fa33723fb751aa69e71507634fc2c19e7649432fb75" +dependencies = [ + "cortex-m", + "critical-section", + "defmt 1.1.0", + "num-traits", +] + +[[package]] +name = "embassy-net-driver" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "524eb3c489760508f71360112bca70f6e53173e6fe48fc5f0efd0f5ab217751d" + +[[package]] +name = "embassy-net-driver-channel" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a07d2eb9f05a6fc876500949856ea1be40773d866d8cb99384f72d0ae4568c16" +dependencies = [ + "embassy-futures", + "embassy-net-driver", + "embassy-sync", +] + +[[package]] +name = "embassy-nrf" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b715380574504335c40ec3016bc44598fac3c385f82959b26c41b25c30b7648d" +dependencies = [ + "bitflags 2.13.0", + "cfg-if", + "cortex-m", + "cortex-m-rt", + "critical-section", + "defmt 1.1.0", + "document-features", + "embassy-embedded-hal", + "embassy-futures", + "embassy-hal-internal 0.5.0", + "embassy-sync", + "embassy-time", + "embassy-usb-driver", + "embedded-hal 0.2.7", + "embedded-hal 1.0.0", + "embedded-hal-async", + "embedded-io 0.7.1", + "embedded-io-async 0.7.0", + "embedded-storage", + "embedded-storage-async", + "fixed", + "nrf-pac", + "rand_core 0.6.4", + "rand_core 0.9.5", +] + +[[package]] +name = "embassy-rp" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5d98f472894c1ecffac5596c657af5305c57282d29e8746d7fec033951931bc8" +dependencies = [ + "cfg-if", + "chrono", + "cortex-m", + "cortex-m-rt", + "critical-section", + "defmt 1.1.0", + "document-features", + "embassy-embedded-hal", + "embassy-futures", + "embassy-hal-internal 0.5.0", + "embassy-sync", + "embassy-time", + "embassy-time-driver", + "embassy-time-queue-utils", + "embassy-usb-driver", + "embedded-hal 0.2.7", + "embedded-hal 1.0.0", + "embedded-hal-async", + "embedded-hal-nb", + "embedded-io 0.7.1", + "embedded-io-async 0.7.0", + "embedded-storage", + "embedded-storage-async", + "fixed", + "nb 1.1.0", + "pio", + "rand_core 0.6.4", + "rand_core 0.9.5", + "rp-pac", + "rp2040-boot2", + "sha2-const-stable", + "smart-leds", +] + +[[package]] +name = "embassy-sync" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7bbd85cf5a5ae56bdf26f618364af642d1d0a4e245cdd75cd9aabda382f65a81" +dependencies = [ + "cfg-if", + "critical-section", + "defmt 1.1.0", + "embedded-io-async 0.7.0", + "futures-core", + "futures-sink", + "heapless 0.9.3", +] + +[[package]] +name = "embassy-time" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "592b0c143ec626e821d4d90da51a2bd91d559d6c442b7c74a47d368c9e23d97a" +dependencies = [ + "cfg-if", + "critical-section", + "defmt 1.1.0", + "document-features", + "embassy-time-driver", + "embedded-hal 0.2.7", + "embedded-hal 1.0.0", + "embedded-hal-async", + "futures-core", +] + +[[package]] +name = "embassy-time-driver" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6ee71af1b3a0deaa53eaf2d39252f83504c853646e472400b763060389b9fcc9" +dependencies = [ + "document-features", +] + +[[package]] +name = "embassy-time-queue-utils" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "168297bf80aaf114b3c9ad589bf38b01b3009b9af7f97cd18086c5bbf96f5693" +dependencies = [ + "embassy-executor-timer-queue", + "heapless 0.9.3", +] + +[[package]] +name = "embassy-usb" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a25746d8b152b72fbf2a217f489a083dbbe243f281f09184a1f2cfbe9bbb245f" +dependencies = [ + "bitflags 2.13.0", + "defmt 1.1.0", + "embassy-futures", + "embassy-net-driver-channel", + "embassy-sync", + "embassy-time", + "embassy-usb-driver", + "embedded-io-async 0.7.0", + "heapless 0.9.3", + "ssmarshal", + "usbd-hid", +] + +[[package]] +name = "embassy-usb-dfu" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e36d3678d16e1e71b052d00f7518620b5839a878f2bdab2019b81d984fb2a74f" +dependencies = [ + "bitflags 2.13.0", + "cortex-m", + "embassy-boot", + "embassy-futures", + "embassy-sync", + "embassy-time", + "embassy-usb", + "embedded-storage", +] + +[[package]] +name = "embassy-usb-driver" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fa675c5f4349b6aa0fcffc4bf9b241f18cd11b97c1f8323273fb9a5449937fbd" +dependencies = [ + "defmt 1.1.0", + "embedded-io-async 0.6.1", + "embedded-io-async 0.7.0", +] + +[[package]] +name = "embedded-hal" +version = "0.2.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "35949884794ad573cf46071e41c9b60efb0cb311e3ca01f7af807af1debc66ff" +dependencies = [ + "nb 0.1.3", + "void", +] + +[[package]] +name = "embedded-hal" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "361a90feb7004eca4019fb28352a9465666b24f840f5c3cddf0ff13920590b89" +dependencies = [ + "defmt 0.3.100", +] + +[[package]] +name = "embedded-hal-async" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0c4c685bbef7fe13c3c6dd4da26841ed3980ef33e841cddfa15ce8a8fb3f1884" +dependencies = [ + "defmt 0.3.100", + "embedded-hal 1.0.0", +] + +[[package]] +name = "embedded-hal-nb" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fba4268c14288c828995299e59b12babdbe170f6c6d73731af1b4648142e8605" +dependencies = [ + "embedded-hal 1.0.0", + "nb 1.1.0", +] + +[[package]] +name = "embedded-io" +version = "0.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "edd0f118536f44f5ccd48bcb8b111bdc3de888b58c74639dfb034a357d0f206d" + +[[package]] +name = "embedded-io" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9eb1aa714776b75c7e67e1da744b81a129b3ff919c8712b5e1b32252c1f07cc7" +dependencies = [ + "defmt 1.1.0", +] + +[[package]] +name = "embedded-io-async" +version = "0.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3ff09972d4073aa8c299395be75161d582e7629cd663171d62af73c8d50dba3f" +dependencies = [ + "embedded-io 0.6.1", +] + +[[package]] +name = "embedded-io-async" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2564b9f813c544241430e147d8bc454815ef9ac998878d30cc3055449f7fd4c0" +dependencies = [ + "defmt 1.1.0", + "embedded-io 0.7.1", +] + +[[package]] +name = "embedded-storage" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a21dea9854beb860f3062d10228ce9b976da520a73474aed3171ec276bc0c032" + +[[package]] +name = "embedded-storage-async" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1763775e2323b7d5f0aa6090657f5e21cfa02ede71f5dc40eead06d64dcd15cc" +dependencies = [ + "embedded-storage", +] + +[[package]] +name = "ena" +version = "0.14.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eabffdaee24bd1bf95c5ef7cec31260444317e72ea56c4c91750e8b7ee58d5f1" +dependencies = [ + "log", +] + +[[package]] +name = "encode_unicode" +version = "0.3.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a357d28ed41a50f9c765dbfe56cbc04a64e53e5fc58ba79fbc34c10ef3df831f" + +[[package]] +name = "encoding_rs" +version = "0.8.35" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "75030f3c4f45dafd7586dd6780965a8c7e8e285a5ecb86713e63a79c5b2766f3" +dependencies = [ + "cfg-if", +] + +[[package]] +name = "equivalent" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "877a4ace8713b0bcf2a4e7eec82529c029f1d0619886d18145fea96c3ffe5c0f" + +[[package]] +name = "erased-serde" +version = "0.4.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d2add8a07dd6a8d93ff627029c51de145e12686fbc36ecb298ac22e74cf02dec" +dependencies = [ + "serde", + "serde_core", + "typeid", +] + +[[package]] +name = "ff" +version = "0.13.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c0b50bfb653653f9ca9095b427bed08ab8d75a137839d9ad64eb11810d5b6393" +dependencies = [ + "rand_core 0.6.4", + "subtle", +] + +[[package]] +name = "find-msvc-tools" +version = "0.1.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5baebc0774151f905a1a2cc41989300b1e6fbb29aff0ceffa1064fdd3088d582" + +[[package]] +name = "fixed" +version = "1.31.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9af2cbf772fa6d1c11358f92ef554cb6b386201210bcf0e91fb7fba8a907fb40" +dependencies = [ + "az", + "bytemuck", + "half", + "typenum", +] + +[[package]] +name = "fixedbitset" +version = "0.5.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1d674e81391d1e1ab681a28d99df07927c6d4aa5b027d7da16ba32d1d21ecd99" + +[[package]] +name = "fnv" +version = "1.0.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" + +[[package]] +name = "foldhash" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "77ce24cb58228fbb8aa041425bb1050850ac19177686ea6e0f41a70416f56fdb" + +[[package]] +name = "futures" +version = "0.3.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8b147ee9d1f6d097cef9ce628cd2ee62288d963e16fb287bd9286455b241382d" +dependencies = [ + "futures-channel", + "futures-core", + "futures-io", + "futures-sink", + "futures-task", + "futures-util", +] + +[[package]] +name = "futures-channel" +version = "0.3.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "07bbe89c50d7a535e539b8c17bc0b49bdb77747034daa8087407d655f3f7cc1d" +dependencies = [ + "futures-core", + "futures-sink", +] + +[[package]] +name = "futures-core" +version = "0.3.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7e3450815272ef58cec6d564423f6e755e25379b217b0bc688e295ba24df6b1d" + +[[package]] +name = "futures-intrusive" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1d930c203dd0b6ff06e0201a4a2fe9149b43c684fd4420555b26d21b1a02956f" +dependencies = [ + "futures-core", + "lock_api", +] + +[[package]] +name = "futures-io" +version = "0.3.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cecba35d7ad927e23624b22ad55235f2239cfa44fd10428eecbeba6d6a717718" + +[[package]] +name = "futures-macro" +version = "0.3.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e835b70203e41293343137df5c0664546da5745f82ec9b84d40be8336958447b" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.117", +] + +[[package]] +name = "futures-sink" +version = "0.3.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c39754e157331b013978ec91992bde1ac089843443c49cbc7f46150b0fad0893" + +[[package]] +name = "futures-task" +version = "0.3.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "037711b3d59c33004d3856fbdc83b99d4ff37a24768fa1be9ce3538a1cde4393" + +[[package]] +name = "futures-util" +version = "0.3.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "389ca41296e6190b48053de0321d02a77f32f8a5d2461dd38762c0593805c6d6" +dependencies = [ + "futures-core", + "futures-macro", + "futures-sink", + "futures-task", + "pin-project-lite", + "slab", +] + +[[package]] +name = "generator" +version = "0.8.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b3b854b0e584ead1a33f18b2fcad7cf7be18b3875c78816b753639aa501513ae" +dependencies = [ + "cc", + "cfg-if", + "libc", + "log", + "rustversion", + "windows-link", + "windows-result", +] + +[[package]] +name = "generic-array" +version = "0.14.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "85649ca51fd72272d7821adaf274ad91c288277713d9c18820d8499a7ff69e9a" +dependencies = [ + "typenum", + "version_check", + "zeroize", +] + +[[package]] +name = "getrandom" +version = "0.2.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ff2abc00be7fca6ebc474524697ae276ad847ad0a6b3faa4bcb027e9a4614ad0" +dependencies = [ + "cfg-if", + "libc", + "wasi", +] + +[[package]] +name = "group" +version = "0.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f0f9ef7462f7c099f518d754361858f86d8a07af53ba9af0fe635bbccb151a63" +dependencies = [ + "ff", + "rand_core 0.6.4", + "subtle", +] + +[[package]] +name = "half" +version = "2.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6ea2d84b969582b4b1864a92dc5d27cd2b77b622a8d79306834f1be5ba20d84b" +dependencies = [ + "cfg-if", + "crunchy", + "zerocopy", +] + +[[package]] +name = "hash32" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b0c35f58762feb77d74ebe43bdbc3210f09be9fe6742234d573bacc26ed92b67" +dependencies = [ + "byteorder", +] + +[[package]] +name = "hash32" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "47d60b12902ba28e2730cd37e95b8c9223af2808df9e902d4df49588d1470606" +dependencies = [ + "byteorder", +] + +[[package]] +name = "hashbrown" +version = "0.13.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "43a3c133739dddd0d2990f9a4bdf8eb4b21ef50e4851ca85ab661199821d510e" +dependencies = [ + "ahash", +] + +[[package]] +name = "hashbrown" +version = "0.14.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e5274423e17b7c9fc20b6e7e208532f9b19825d82dfd615708b70edd83df41f1" + +[[package]] +name = "hashbrown" +version = "0.16.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "841d1cc9bed7f9236f321df977030373f4a4163ae1a7dbfe1a51a2c1a51d9100" +dependencies = [ + "foldhash", +] + +[[package]] +name = "hashbrown" +version = "0.17.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ed5909b6e89a2db4456e54cd5f673791d7eca6732202bbf2a9cc504fe2f9b84a" + +[[package]] +name = "hashlink" +version = "0.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "824e001ac4f3012dd16a264bec811403a67ca9deb6c102fc5049b32c4574b35f" +dependencies = [ + "hashbrown 0.16.1", +] + +[[package]] +name = "heapless" +version = "0.7.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cdc6457c0eb62c71aac4bc17216026d8410337c4126773b9c5daba343f17964f" +dependencies = [ + "atomic-polyfill", + "hash32 0.2.1", + "rustc_version 0.4.1", + "serde", + "spin", + "stable_deref_trait", +] + +[[package]] +name = "heapless" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0bfb9eb618601c89945a70e254898da93b13be0388091d42117462b265bb3fad" +dependencies = [ + "hash32 0.3.1", + "stable_deref_trait", +] + +[[package]] +name = "heapless" +version = "0.9.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "25ba4bd83f9415b58b4ed8dc5714c76e626a105be4646c02630ad730ad3b5aa4" +dependencies = [ + "defmt 1.1.0", + "hash32 0.3.1", + "serde_core", + "stable_deref_trait", +] + +[[package]] +name = "heck" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea" + +[[package]] +name = "hkdf" +version = "0.12.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7b5f8eb2ad728638ea2c7d47a21db23b7b58a72ed6a38256b8a1849f15fbbdf7" +dependencies = [ + "hmac", +] + +[[package]] +name = "hmac" +version = "0.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6c49c37c09c17a53d937dfbb742eb3a961d65a994e6bcdcf37e7399d0cc8ab5e" +dependencies = [ + "digest", +] + +[[package]] +name = "ident_case" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b9e0384b61958566e926dc50660321d12159025e767c18e043daf26b70104c39" + +[[package]] +name = "indexmap" +version = "2.14.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d466e9454f08e4a911e14806c24e16fba1b4c121d1ea474396f396069cf949d9" +dependencies = [ + "equivalent", + "hashbrown 0.17.1", +] + +[[package]] +name = "inout" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "879f10e63c20629ecabbb64a8010319738c66a5cd0c29b02d63d272b03751d01" +dependencies = [ + "generic-array", +] + +[[package]] +name = "itertools" +version = "0.14.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2b192c782037fadd9cfa75548310488aabdbf3d2da73885b31bd0abd03351285" +dependencies = [ + "either", +] + +[[package]] +name = "itoa" +version = "1.0.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f42a60cbdf9a97f5d2305f08a87dc4e09308d1276d28c869c684d7777685682" + +[[package]] +name = "js-sys" +version = "0.3.99" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "142bc4740e452c1e57ade0cbc129f139c9093e354346f0872ef985f4f5cf5f11" +dependencies = [ + "cfg-if", + "futures-util", + "once_cell", + "wasm-bindgen", +] + +[[package]] +name = "json" +version = "0.12.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "078e285eafdfb6c4b434e0d31e8cfcb5115b651496faca5749b88fafd4f23bfd" + +[[package]] +name = "json5" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "96b0db21af676c1ce64250b5f40f3ce2cf27e4e47cb91ed91eb6fe9350b430c1" +dependencies = [ + "pest", + "pest_derive", + "serde", +] + +[[package]] +name = "keccak" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cb26cec98cce3a3d96cbb7bced3c4b16e3d13f27ec56dbd62cbc8f39cfb9d653" +dependencies = [ + "cpufeatures", +] + +[[package]] +name = "lalrpop" +version = "0.22.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ba4ebbd48ce411c1d10fb35185f5a51a7bfa3d8b24b4e330d30c9e3a34129501" +dependencies = [ + "ascii-canvas", + "bit-set", + "ena", + "itertools", + "lalrpop-util", + "petgraph", + "pico-args", + "regex", + "regex-syntax", + "sha3", + "string_cache", + "term", + "unicode-xid", + "walkdir", +] + +[[package]] +name = "lalrpop-util" +version = "0.22.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b5baa5e9ff84f1aefd264e6869907646538a52147a755d494517a8007fb48733" +dependencies = [ + "regex-automata", + "rustversion", +] + +[[package]] +name = "lazy_static" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe" + +[[package]] +name = "libc" +version = "0.2.186" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "68ab91017fe16c622486840e4c83c9a37afeff978bd239b5293d61ece587de66" + +[[package]] +name = "litrs" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "11d3d7f243d5c5a8b9bb5d6dd2b1602c0cb0b9db1621bafc7ed66e35ff9fe092" + +[[package]] +name = "lock_api" +version = "0.4.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "224399e74b87b5f3557511d98dff8b14089b3dadafcab6bb93eab67d3aace965" +dependencies = [ + "scopeguard", +] + +[[package]] +name = "log" +version = "0.4.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "953f07c43838f8e6f9758cab68bf5bed85465e7587ebe0b823f1bcd81978ad3a" + +[[package]] +name = "loom" +version = "0.7.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "419e0dc8046cb947daa77eb95ae174acfbddb7673b4151f56d1eed8e93fbfaca" +dependencies = [ + "cfg-if", + "generator", + "scoped-tls", + "tracing", + "tracing-subscriber", +] + +[[package]] +name = "lzma-sys" +version = "0.1.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5fda04ab3764e6cde78b9974eec4f779acaba7c4e84b36eca3cf77c581b85d27" +dependencies = [ + "cc", + "libc", + "pkg-config", +] + +[[package]] +name = "matchers" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d1525a2a28c7f4fa0fc98bb91ae755d1e2d1505079e05539e35bc876b5d65ae9" +dependencies = [ + "regex-automata", +] + +[[package]] +name = "memchr" +version = "2.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6b947ae49db0d222b1dbc6b113ce7248a3fc3a6ca21b696717bfc000ba4484d8" + +[[package]] +name = "nb" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "801d31da0513b6ec5214e9bf433a77966320625a37860f910be265be6e18d06f" +dependencies = [ + "nb 1.1.0", +] + +[[package]] +name = "nb" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8d5439c4ad607c3c23abf66de8c8bf57ba8adcd1f129e699851a6e43935d339d" + +[[package]] +name = "new_debug_unreachable" +version = "1.0.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "650eef8c711430f1a879fdd01d4745a7deea475becfb90269c06775983bbf086" + +[[package]] +name = "nrf-pac" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bddd547fab92b0553ff37032034fd04ce8b8b60d3f9a83f89ea815dfd0400336" +dependencies = [ + "cortex-m", + "cortex-m-rt", +] + +[[package]] +name = "nu-ansi-term" +version = "0.50.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7957b9740744892f114936ab4a57b3f487491bbeafaf8083688b16841a4240e5" +dependencies = [ + "windows-sys", +] + +[[package]] +name = "num-traits" +version = "0.2.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841" +dependencies = [ + "autocfg", +] + +[[package]] +name = "num_enum" +version = "0.7.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5d0bca838442ec211fa11de3a8b0e0e8f3a4522575b5c4c06ed722e005036f26" +dependencies = [ + "num_enum_derive", + "rustversion", +] + +[[package]] +name = "num_enum_derive" +version = "0.7.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "680998035259dcfcafe653688bf2aa6d3e2dc05e98be6ab46afb089dc84f1df8" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.117", +] + +[[package]] +name = "once_cell" +version = "1.21.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9f7c3e4beb33f85d45ae3e3a1792185706c8e16d043238c593331cc7cd313b50" + +[[package]] +name = "ordered-multimap" +version = "0.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "49203cdcae0030493bad186b28da2fa25645fa276a51b6fec8010d281e02ef79" +dependencies = [ + "dlv-list", + "hashbrown 0.14.5", +] + +[[package]] +name = "p256" +version = "0.13.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c9863ad85fa8f4460f9c48cb909d38a0d689dba1f6f6988a5e3e0d31071bcd4b" +dependencies = [ + "elliptic-curve", + "primeorder", +] + +[[package]] +name = "panic-probe" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fd402d00b0fb94c5aee000029204a46884b1262e0c443f166d86d2c0747e1a1a" +dependencies = [ + "cortex-m", + "defmt 1.1.0", +] + +[[package]] +name = "parking_lot" +version = "0.12.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "93857453250e3077bd71ff98b6a65ea6621a19bb0f559a85248955ac12c45a1a" +dependencies = [ + "lock_api", + "parking_lot_core", +] + +[[package]] +name = "parking_lot_core" +version = "0.9.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2621685985a2ebf1c516881c026032ac7deafcda1a2c9b7850dc81e3dfcb64c1" +dependencies = [ + "cfg-if", + "libc", + "redox_syscall", + "smallvec", + "windows-link", +] + +[[package]] +name = "paste" +version = "1.0.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "57c0d7b74b563b49d38dae00a0c37d4d6de9b432382b2892f0574ddcae73fd0a" + +[[package]] +name = "pathdiff" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "df94ce210e5bc13cb6651479fa48d14f601d9858cfe0467f43ae157023b938d3" + +[[package]] +name = "pest" +version = "2.8.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e0848c601009d37dfa3430c4666e147e49cdcf1b92ecd3e63657d8a5f19da662" +dependencies = [ + "memchr", + "ucd-trie", +] + +[[package]] +name = "pest_derive" +version = "2.8.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "11f486f1ea21e6c10ed15d5a7c77165d0ee443402f0780849d1768e7d9d6fe77" +dependencies = [ + "pest", + "pest_generator", +] + +[[package]] +name = "pest_generator" +version = "2.8.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8040c4647b13b210a963c1ed407c1ff4fdfa01c31d6d2a098218702e6664f94f" +dependencies = [ + "pest", + "pest_meta", + "proc-macro2", + "quote", + "syn 2.0.117", +] + +[[package]] +name = "pest_meta" +version = "2.8.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "89815c69d36021a140146f26659a81d6c2afa33d216d736dd4be5381a7362220" +dependencies = [ + "pest", + "sha2", +] + +[[package]] +name = "petgraph" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3672b37090dbd86368a4145bc067582552b29c27377cad4e0a306c97f9bd7772" +dependencies = [ + "fixedbitset", + "indexmap", +] + +[[package]] +name = "phf_shared" +version = "0.11.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "67eabc2ef2a60eb7faa00097bd1ffdb5bd28e62bf39990626a582201b7a754e5" +dependencies = [ + "siphasher", +] + +[[package]] +name = "pico-args" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5be167a7af36ee22fe3115051bc51f6e6c7054c9348e28deb4f49bd6f705a315" + +[[package]] +name = "pin-project-lite" +version = "0.2.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a89322df9ebe1c1578d689c92318e070967d1042b512afbe49518723f4e6d5cd" + +[[package]] +name = "pio" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d0ba4153cee9585abc451271aa437d9e8defdea8b468d48ba6b8f098cbe03d7f" +dependencies = [ + "pio-core", + "pio-proc", +] + +[[package]] +name = "pio-core" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "61d90fddc3d67f21bbf93683bc461b05d6a29c708caf3ffb79947d7ff7095406" +dependencies = [ + "arrayvec", + "num_enum", + "paste", +] + +[[package]] +name = "pio-parser" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "825266c1eaddf54f636d06eefa4bf3c99d774c14ec46a4a6c6e5128a0f10d205" +dependencies = [ + "lalrpop", + "lalrpop-util", + "pio-core", +] + +[[package]] +name = "pio-proc" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ed4a76571f5fe51af43cc80ac870fe0c79cc0cdd686b9002a6c4c84bfdd0176b" +dependencies = [ + "codespan-reporting", + "lalrpop-util", + "pio-core", + "pio-parser", + "proc-macro-error2", + "proc-macro2", + "quote", + "syn 2.0.117", +] + +[[package]] +name = "pkg-config" +version = "0.3.33" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "19f132c84eca552bf34cab8ec81f1c1dcc229b811638f9d283dceabe58c5569e" + +[[package]] +name = "portable-atomic" +version = "1.13.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c33a9471896f1c69cecef8d20cbe2f7accd12527ce60845ff44c153bb2a21b49" +dependencies = [ + "critical-section", +] + +[[package]] +name = "postcard" +version = "1.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6764c3b5dd454e283a30e6dfe78e9b31096d9e32036b5d1eaac7a6119ccb9a24" +dependencies = [ + "cobs", + "defmt 1.1.0", + "heapless 0.7.17", + "postcard-derive", + "serde", +] + +[[package]] +name = "postcard-derive" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e0232bd009a197ceec9cc881ba46f727fcd8060a2d8d6a9dde7a69030a6fe2bb" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.117", +] + +[[package]] +name = "ppv-lite86" +version = "0.2.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "85eae3c4ed2f50dcfe72643da4befc30deadb458a9b590d720cde2f2b1e97da9" +dependencies = [ + "zerocopy", +] + +[[package]] +name = "precomputed-hash" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "925383efa346730478fb4838dbe9137d2a47675ad789c546d150a6e1dd4ab31c" + +[[package]] +name = "primeorder" +version = "0.13.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "353e1ca18966c16d9deb1c69278edbc5f194139612772bd9537af60ac231e1e6" +dependencies = [ + "elliptic-curve", +] + +[[package]] +name = "proc-macro-error-attr2" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "96de42df36bb9bba5542fe9f1a054b8cc87e172759a1868aa05c1f3acc89dfc5" +dependencies = [ + "proc-macro2", + "quote", +] + +[[package]] +name = "proc-macro-error2" +version = "2.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "11ec05c52be0a07b08061f7dd003e7d7092e0472bc731b4af7bb1ef876109802" +dependencies = [ + "proc-macro-error-attr2", + "proc-macro2", + "quote", + "syn 2.0.117", +] + +[[package]] +name = "proc-macro2" +version = "1.0.106" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8fd00f0bb2e90d81d1044c2b32617f68fcb9fa3bb7640c23e9c748e53fb30934" +dependencies = [ + "unicode-ident", +] + +[[package]] +name = "pure-rust-locales" +version = "0.8.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "869675ad2d7541aea90c6d88c81f46a7f4ea9af8cd0395d38f11a95126998a0d" +dependencies = [ + "defmt 1.1.0", +] + +[[package]] +name = "quote" +version = "1.0.45" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "41f2619966050689382d2b44f664f4bc593e129785a36d6ee376ddf37259b924" +dependencies = [ + "proc-macro2", +] + +[[package]] +name = "rand" +version = "0.8.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5ca0ecfa931c29007047d1bc58e623ab12e5590e8c7cc53200d5202b69266d8a" +dependencies = [ + "rand_core 0.6.4", +] + +[[package]] +name = "rand_chacha" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88" +dependencies = [ + "ppv-lite86", + "rand_core 0.6.4", +] + +[[package]] +name = "rand_core" +version = "0.6.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" + +[[package]] +name = "rand_core" +version = "0.9.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "76afc826de14238e6e8c374ddcc1fa19e374fd8dd986b0d2af0d02377261d83c" + +[[package]] +name = "redox_syscall" +version = "0.5.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ed2bf2547551a7053d6fdfafda3f938979645c44812fbfcda098faae3f1a362d" +dependencies = [ + "bitflags 2.13.0", +] + +[[package]] +name = "regex" +version = "1.12.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e10754a14b9137dd7b1e3e5b0493cc9171fdd105e0ab477f51b72e7f3ac0e276" +dependencies = [ + "aho-corasick", + "memchr", + "regex-automata", + "regex-syntax", +] + +[[package]] +name = "regex-automata" +version = "0.4.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6e1dd4122fc1595e8162618945476892eefca7b88c52820e74af6262213cae8f" +dependencies = [ + "aho-corasick", + "memchr", + "regex-syntax", +] + +[[package]] +name = "regex-syntax" +version = "0.8.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dc897dd8d9e8bd1ed8cdad82b5966c3e0ecae09fb1907d58efaa013543185d0a" + +[[package]] +name = "rgb" +version = "0.8.53" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "47b34b781b31e5d73e9fbc8689c70551fd1ade9a19e3e28cfec8580a79290cc4" + +[[package]] +name = "rmk" +version = "0.8.2" +dependencies = [ + "bt-hci", + "byteorder", + "cortex-m", + "crc32fast", + "defmt 1.1.0", + "document-features", + "embassy-boot-rp", + "embassy-embedded-hal", + "embassy-futures", + "embassy-hal-internal 0.5.0", + "embassy-nrf", + "embassy-rp", + "embassy-sync", + "embassy-time", + "embassy-usb", + "embassy-usb-dfu", + "embedded-hal 1.0.0", + "embedded-hal-async", + "embedded-io-async 0.7.0", + "embedded-storage", + "embedded-storage-async", + "fixed", + "futures", + "heapless 0.9.3", + "paste", + "pio", + "postcard", + "rmk-macro", + "rmk-types", + "rp-pac", + "sequential-storage", + "serde", + "static_cell", + "trouble-host", + "usbd-hid", +] + +[[package]] +name = "rmk-config" +version = "0.6.1" +dependencies = [ + "config", + "once_cell", + "paste", + "pest", + "pest_derive", + "serde", + "serde-inline-default", + "toml 1.1.2+spec-1.1.0", +] + +[[package]] +name = "rmk-macro" +version = "0.7.1" +dependencies = [ + "cargo_toml", + "darling 0.23.0", + "proc-macro2", + "quote", + "rmk-config", + "rmk-types", + "strum", + "syn 2.0.117", +] + +[[package]] +name = "rmk-rp2040-embassy-boot" +version = "0.2.0" +dependencies = [ + "const-gen", + "cortex-m-rt", + "defmt 1.1.0", + "defmt-rtt", + "embassy-executor", + "embassy-rp", + "embassy-time", + "json", + "panic-probe", + "portable-atomic", + "rmk", + "xz2", +] + +[[package]] +name = "rmk-types" +version = "0.2.2" +dependencies = [ + "bitfield-struct", + "defmt 1.1.0", + "heapless 0.9.3", + "postcard", + "rmk-config", + "serde", + "strum", + "toml 1.1.2+spec-1.1.0", +] + +[[package]] +name = "ron" +version = "0.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4147b952f3f819eca0e99527022f7d6a8d05f111aeb0a62960c74eb283bec8fc" +dependencies = [ + "bitflags 2.13.0", + "once_cell", + "serde", + "serde_derive", + "typeid", + "unicode-ident", +] + +[[package]] +name = "rp-pac" +version = "7.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8af65855c40b2c35079514c5489abffc0429347fef25d8467ff98ad84b4322d3" +dependencies = [ + "cortex-m", + "cortex-m-rt", +] + +[[package]] +name = "rp2040-boot2" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7c92f344f63f950ee36cf4080050e4dce850839b9175da38f9d2ffb69b4dbb21" +dependencies = [ + "crc-any", +] + +[[package]] +name = "rust-ini" +version = "0.21.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "796e8d2b6696392a43bea58116b667fb4c29727dc5abd27d6acf338bb4f688c7" +dependencies = [ + "cfg-if", + "ordered-multimap", +] + +[[package]] +name = "rustc_version" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "138e3e0acb6c9fb258b19b67cb8abd63c00679d2851805ea151465464fe9030a" +dependencies = [ + "semver 0.9.0", +] + +[[package]] +name = "rustc_version" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cfcb3a22ef46e85b45de6ee7e79d063319ebb6594faafcf1c225ea92ab6e9b92" +dependencies = [ + "semver 1.0.28", +] + +[[package]] +name = "rustversion" +version = "1.0.22" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b39cdef0fa800fc44525c84ccb54a029961a8215f9619753635a9c0d2538d46d" + +[[package]] +name = "same-file" +version = "1.0.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "93fc1dc3aaa9bfed95e02e6eadabb4baf7e3078b0bd1b4d7b6b0b68378900502" +dependencies = [ + "winapi-util", +] + +[[package]] +name = "scoped-tls" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e1cf6437eb19a8f4a6cc0f7dca544973b0b78843adbfeb3683d1a94a0024a294" + +[[package]] +name = "scopeguard" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" + +[[package]] +name = "sec1" +version = "0.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d3e97a565f76233a6003f9f5c54be1d9c5bdfa3eccfb189469f11ec4901c47dc" +dependencies = [ + "base16ct", + "der", + "generic-array", + "subtle", + "zeroize", +] + +[[package]] +name = "semver" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1d7eb9ef2c18661902cc47e535f9bc51b78acd254da71d375c2f6720d9a40403" +dependencies = [ + "semver-parser", +] + +[[package]] +name = "semver" +version = "1.0.28" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8a7852d02fc848982e0c167ef163aaff9cd91dc640ba85e263cb1ce46fae51cd" + +[[package]] +name = "semver-parser" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "388a1df253eca08550bef6c72392cfe7c30914bf41df5269b68cbd6ff8f570a3" + +[[package]] +name = "sequential-storage" +version = "7.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "574e5a379bf43653079b34cb4cf32958404b5f42e0ed5b5adcdff02c2de04d4d" +dependencies = [ + "defmt 1.1.0", + "embedded-storage-async", + "postcard", + "serde", +] + +[[package]] +name = "serde" +version = "1.0.228" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9a8e94ea7f378bd32cbbd37198a4a91436180c5bb472411e48b5ec2e2124ae9e" +dependencies = [ + "serde_core", + "serde_derive", +] + +[[package]] +name = "serde-inline-default" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2bf03b7a5281cfd4013bc788d057b0f09fc634397d83bc8973c955bd4f32727a" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.117", +] + +[[package]] +name = "serde-untagged" +version = "0.1.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f9faf48a4a2d2693be24c6289dbe26552776eb7737074e6722891fadbe6c5058" +dependencies = [ + "erased-serde", + "serde", + "serde_core", + "typeid", +] + +[[package]] +name = "serde_core" +version = "1.0.228" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "41d385c7d4ca58e59fc732af25c3983b67ac852c1a25000afe1175de458b67ad" +dependencies = [ + "serde_derive", +] + +[[package]] +name = "serde_derive" +version = "1.0.228" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d540f220d3187173da220f885ab66608367b6574e925011a9353e4badda91d79" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.117", +] + +[[package]] +name = "serde_json" +version = "1.0.150" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e8014e44b4736ed0538adeecded0fce2a272f22dc9578a7eb6b2d9993c74cfb9" +dependencies = [ + "itoa", + "memchr", + "serde", + "serde_core", + "zmij", +] + +[[package]] +name = "serde_spanned" +version = "1.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6662b5879511e06e8999a8a235d848113e942c9124f211511b16466ee2995f26" +dependencies = [ + "serde_core", +] + +[[package]] +name = "sha2" +version = "0.10.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a7507d819769d01a365ab707794a4084392c824f54a7a6a7862f8c3d0892b283" +dependencies = [ + "cfg-if", + "cpufeatures", + "digest", +] + +[[package]] +name = "sha2-const-stable" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5f179d4e11094a893b82fff208f74d448a7512f99f5a0acbd5c679b705f83ed9" + +[[package]] +name = "sha3" +version = "0.10.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "77fd7028345d415a4034cf8777cd4f8ab1851274233b45f84e3d955502d93874" +dependencies = [ + "digest", + "keccak", +] + +[[package]] +name = "sharded-slab" +version = "0.1.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f40ca3c46823713e0d4209592e8d6e826aa57e928f09752619fc696c499637f6" +dependencies = [ + "lazy_static", +] + +[[package]] +name = "shlex" +version = "2.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f8fadd59c855ef2080decdef8ff161eb6661b86933c9d82e5ba29dc602a55aba" + +[[package]] +name = "signature" +version = "2.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "77549399552de45a898a580c1b41d445bf730df867cc44e6c0233bbc4b8329de" + +[[package]] +name = "siphasher" +version = "1.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8ee5873ec9cce0195efcb7a4e9507a04cd49aec9c83d0389df45b1ef7ba2e649" + +[[package]] +name = "slab" +version = "0.4.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0c790de23124f9ab44544d7ac05d60440adc586479ce501c1d6d7da3cd8c9cf5" + +[[package]] +name = "smallvec" +version = "1.15.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "67b1b7a3b5fe4f1376887184045fcf45c69e92af734b7aaddc05fb777b6fbd03" + +[[package]] +name = "smart-leds" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "66df34e571fa9993fa6f99131a374d58ca3d694b75f9baac93458fe0d6057bf0" +dependencies = [ + "smart-leds-trait", +] + +[[package]] +name = "smart-leds-trait" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a7f4441a131924d58da6b83a7ad765c460e64630cce504376c3a87a2558c487f" +dependencies = [ + "rgb", +] + +[[package]] +name = "spin" +version = "0.9.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6980e8d7511241f8acf4aebddbb1ff938df5eebe98691418c4468d0b72a96a67" +dependencies = [ + "lock_api", +] + +[[package]] +name = "ssmarshal" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f3e6ad23b128192ed337dfa4f1b8099ced0c2bf30d61e551b65fda5916dbb850" +dependencies = [ + "encode_unicode", + "serde", +] + +[[package]] +name = "stable_deref_trait" +version = "1.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6ce2be8dc25455e1f91df71bfa12ad37d7af1092ae736f3a6cd0e37bc7810596" + +[[package]] +name = "static_cell" +version = "2.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0530892bb4fa575ee0da4b86f86c667132a94b74bb72160f58ee5a4afec74c23" +dependencies = [ + "portable-atomic", +] + +[[package]] +name = "string_cache" +version = "0.8.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bf776ba3fa74f83bf4b63c3dcbbf82173db2632ed8452cb2d891d33f459de70f" +dependencies = [ + "new_debug_unreachable", + "parking_lot", + "phf_shared", + "precomputed-hash", +] + +[[package]] +name = "strsim" +version = "0.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f" + +[[package]] +name = "strum" +version = "0.28.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9628de9b8791db39ceda2b119bbe13134770b56c138ec1d3af810d045c04f9bd" +dependencies = [ + "strum_macros", +] + +[[package]] +name = "strum_macros" +version = "0.28.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ab85eea0270ee17587ed4156089e10b9e6880ee688791d45a905f5b1ca36f664" +dependencies = [ + "heck", + "proc-macro2", + "quote", + "syn 2.0.117", +] + +[[package]] +name = "subtle" +version = "2.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "13c2bddecc57b384dee18652358fb23172facb8a2c51ccc10d74c157bdea3292" + +[[package]] +name = "syn" +version = "1.0.109" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[package]] +name = "syn" +version = "2.0.117" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e665b8803e7b1d2a727f4023456bbbbe74da67099c585258af0ad9c5013b9b99" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[package]] +name = "term" +version = "1.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d8c27177b12a6399ffc08b98f76f7c9a1f4fe9fc967c784c5a071fa8d93cf7e1" +dependencies = [ + "windows-sys", +] + +[[package]] +name = "termcolor" +version = "1.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "06794f8f6c5c898b3275aebefa6b8a1cb24cd2c6c79397ab15774837a0bc5755" +dependencies = [ + "winapi-util", +] + +[[package]] +name = "thiserror" +version = "2.0.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4288b5bcbc7920c07a1149a35cf9590a2aa808e0bc1eafaade0b80947865fbc4" +dependencies = [ + "thiserror-impl", +] + +[[package]] +name = "thiserror-impl" +version = "2.0.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ebc4ee7f67670e9b64d05fa4253e753e016c6c95ff35b89b7941d6b856dec1d5" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.117", +] + +[[package]] +name = "thread_local" +version = "1.1.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f60246a4944f24f6e018aa17cdeffb7818b76356965d03b07d6a9886e8962185" +dependencies = [ + "cfg-if", +] + +[[package]] +name = "tiny-keccak" +version = "2.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2c9d3793400a45f954c52e73d068316d76b6f4e36977e3fcebb13a2721e80237" +dependencies = [ + "crunchy", +] + +[[package]] +name = "toml" +version = "0.9.12+spec-1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cf92845e79fc2e2def6a5d828f0801e29a2f8acc037becc5ab08595c7d5e9863" +dependencies = [ + "indexmap", + "serde_core", + "serde_spanned", + "toml_datetime 0.7.5+spec-1.1.0", + "toml_parser", + "toml_writer", + "winnow 0.7.15", +] + +[[package]] +name = "toml" +version = "1.1.2+spec-1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "81f3d15e84cbcd896376e6730314d59fb5a87f31e4b038454184435cd57defee" +dependencies = [ + "indexmap", + "serde_core", + "serde_spanned", + "toml_datetime 1.1.1+spec-1.1.0", + "toml_parser", + "toml_writer", + "winnow 1.0.3", +] + +[[package]] +name = "toml_datetime" +version = "0.7.5+spec-1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "92e1cfed4a3038bc5a127e35a2d360f145e1f4b971b551a2ba5fd7aedf7e1347" +dependencies = [ + "serde_core", +] + +[[package]] +name = "toml_datetime" +version = "1.1.1+spec-1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3165f65f62e28e0115a00b2ebdd37eb6f3b641855f9d636d3cd4103767159ad7" +dependencies = [ + "serde_core", +] + +[[package]] +name = "toml_parser" +version = "1.1.2+spec-1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a2abe9b86193656635d2411dc43050282ca48aa31c2451210f4202550afb7526" +dependencies = [ + "winnow 1.0.3", +] + +[[package]] +name = "toml_writer" +version = "1.1.1+spec-1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "756daf9b1013ebe47a8776667b466417e2d4c5679d441c26230efd9ef78692db" + +[[package]] +name = "tracing" +version = "0.1.44" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "63e71662fa4b2a2c3a26f570f037eb95bb1f85397f3cd8076caed2f026a6d100" +dependencies = [ + "pin-project-lite", + "tracing-attributes", + "tracing-core", +] + +[[package]] +name = "tracing-attributes" +version = "0.1.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7490cfa5ec963746568740651ac6781f701c9c5ea257c58e057f3ba8cf69e8da" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.117", +] + +[[package]] +name = "tracing-core" +version = "0.1.36" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "db97caf9d906fbde555dd62fa95ddba9eecfd14cb388e4f491a66d74cd5fb79a" +dependencies = [ + "once_cell", + "valuable", +] + +[[package]] +name = "tracing-log" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ee855f1f400bd0e5c02d150ae5de3840039a3f54b025156404e34c23c03f47c3" +dependencies = [ + "log", + "once_cell", + "tracing-core", +] + +[[package]] +name = "tracing-subscriber" +version = "0.3.23" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cb7f578e5945fb242538965c2d0b04418d38ec25c79d160cd279bf0731c8d319" +dependencies = [ + "matchers", + "nu-ansi-term", + "once_cell", + "regex-automata", + "sharded-slab", + "smallvec", + "thread_local", + "tracing", + "tracing-core", + "tracing-log", +] + +[[package]] +name = "trouble-host" +version = "0.6.0" +source = "git+https://github.com/haobogu/trouble?rev=690373fd1166d16225b875435dd0600c92570e7d#690373fd1166d16225b875435dd0600c92570e7d" +dependencies = [ + "aes", + "bt-hci", + "cmac", + "defmt 1.1.0", + "embassy-futures", + "embassy-sync", + "embassy-time", + "embedded-io 0.7.1", + "futures", + "heapless 0.9.3", + "p256", + "rand", + "rand_chacha", + "rand_core 0.6.4", + "serde", + "static_cell", + "trouble-host-macros", + "zerocopy", +] + +[[package]] +name = "trouble-host-macros" +version = "0.4.0" +source = "git+https://github.com/haobogu/trouble?rev=690373fd1166d16225b875435dd0600c92570e7d#690373fd1166d16225b875435dd0600c92570e7d" +dependencies = [ + "convert_case 0.8.0", + "darling 0.20.11", + "proc-macro2", + "quote", + "syn 2.0.117", + "uuid", +] + +[[package]] +name = "typeid" +version = "1.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bc7d623258602320d5c55d1bc22793b57daff0ec7efc270ea7d55ce1d5f5471c" + +[[package]] +name = "typenum" +version = "1.20.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b6f5e870be6c3b371b77fe0ee0bafb859fa4964b4404c27de1d380043c4dda20" + +[[package]] +name = "ucd-trie" +version = "0.1.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2896d95c02a80c6d6a5d6e953d479f5ddf2dfdb6a244441010e373ac0fb88971" + +[[package]] +name = "unicode-ident" +version = "1.0.24" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e6e4313cd5fcd3dad5cafa179702e2b244f760991f45397d14d4ebf38247da75" + +[[package]] +name = "unicode-segmentation" +version = "1.13.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c6f5d3c3b1bf09027a88a6bc961fc00497d651009560b5463668dc81b0fa87a8" + +[[package]] +name = "unicode-width" +version = "0.1.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7dd6e30e90baa6f72411720665d41d89b9a3d039dc45b8faea1ddd07f617f6af" + +[[package]] +name = "unicode-xid" +version = "0.2.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ebc1c04c71510c7f702b52b7c350734c9ff1295c464a03335b00bb84fc54f853" + +[[package]] +name = "usb-device" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "98816b1accafbb09085168b90f27e93d790b4bfa19d883466b5e53315b5f06a6" +dependencies = [ + "defmt 0.3.100", + "heapless 0.8.0", + "portable-atomic", +] + +[[package]] +name = "usbd-hid" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "68beab087e4971a2fe76f631478b0e91d39593f58efd2775026ce6dc07a7bac6" +dependencies = [ + "defmt 0.3.100", + "usb-device", + "usbd-hid-macros", +] + +[[package]] +name = "usbd-hid-descriptors" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b297f021719c4308d5d0c61b6c1e7c6b3ba383deba774b49aa5484f996bdb8f1" +dependencies = [ + "bitfield 0.14.0", +] + +[[package]] +name = "usbd-hid-macros" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "011a3219e0933f5b3ad7dc90d9a66541a967d084c98c067deed1cd608e557ed7" +dependencies = [ + "byteorder", + "hashbrown 0.13.2", + "log", + "proc-macro2", + "quote", + "serde", + "syn 2.0.117", + "usbd-hid-descriptors", +] + +[[package]] +name = "uuid" +version = "1.23.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d258b83ceec21034727ecee8c382cfa6c3e133699b0742c64571814fb420c9f7" +dependencies = [ + "js-sys", + "wasm-bindgen", +] + +[[package]] +name = "valuable" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ba73ea9cf16a25df0c8caa16c51acb937d5712a8429db78a3ee29d5dcacd3a65" + +[[package]] +name = "vcell" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "77439c1b53d2303b20d9459b1ade71a83c716e3f9c34f3228c00e6f185d6c002" + +[[package]] +name = "version_check" +version = "0.9.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b928f33d975fc6ad9f86c8f283853ad26bdd5b10b7f1542aa2fa15e2289105a" + +[[package]] +name = "void" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6a02e4885ed3bc0f2de90ea6dd45ebcbb66dacffe03547fadbb0eeae2770887d" + +[[package]] +name = "volatile-register" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "de437e2a6208b014ab52972a27e59b33fa2920d3e00fe05026167a1c509d19cc" +dependencies = [ + "vcell", +] + +[[package]] +name = "walkdir" +version = "2.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "29790946404f91d9c5d06f9874efddea1dc06c5efe94541a7d6863108e3a5e4b" +dependencies = [ + "same-file", + "winapi-util", +] + +[[package]] +name = "wasi" +version = "0.11.1+wasi-snapshot-preview1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ccf3ec651a847eb01de73ccad15eb7d99f80485de043efb2f370cd654f4ea44b" + +[[package]] +name = "wasm-bindgen" +version = "0.2.122" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3ed04576f974d2b2fba0f38c51dbc5518011e38c36bf1143164be765528fd409" +dependencies = [ + "cfg-if", + "once_cell", + "rustversion", + "wasm-bindgen-macro", + "wasm-bindgen-shared", +] + +[[package]] +name = "wasm-bindgen-macro" +version = "0.2.122" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "916151b09da36bd82f6615cbf3a419e2f0ba23a03c6160e8e92eb6bd4aa1dec6" +dependencies = [ + "quote", + "wasm-bindgen-macro-support", +] + +[[package]] +name = "wasm-bindgen-macro-support" +version = "0.2.122" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "299047362ccbfce148b67ab7e73349f77748e00c8296f9542adfad2ad82c5c5e" +dependencies = [ + "bumpalo", + "proc-macro2", + "quote", + "syn 2.0.117", + "wasm-bindgen-shared", +] + +[[package]] +name = "wasm-bindgen-shared" +version = "0.2.122" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9a929b2c61f11ba3e9bc35b50c1f25cb38e0e892c0c231ae2b8cf78d5dad4437" +dependencies = [ + "unicode-ident", +] + +[[package]] +name = "winapi-util" +version = "0.1.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c2a7b1c03c876122aa43f3020e6c3c3ee5c05081c9a00739faf7503aeba10d22" +dependencies = [ + "windows-sys", +] + +[[package]] +name = "windows-link" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f0805222e57f7521d6a62e36fa9163bc891acd422f971defe97d64e70d0a4fe5" + +[[package]] +name = "windows-result" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7781fa89eaf60850ac3d2da7af8e5242a5ea78d1a11c49bf2910bb5a73853eb5" +dependencies = [ + "windows-link", +] + +[[package]] +name = "windows-sys" +version = "0.61.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ae137229bcbd6cdf0f7b80a31df61766145077ddf49416a728b02cb3921ff3fc" +dependencies = [ + "windows-link", +] + +[[package]] +name = "winnow" +version = "0.7.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "df79d97927682d2fd8adb29682d1140b343be4ac0f08fd68b7765d9c059d3945" + +[[package]] +name = "winnow" +version = "1.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0592e1c9d151f854e6fd382574c3a0855250e1d9b2f99d9281c6e6391af352f1" +dependencies = [ + "memchr", +] + +[[package]] +name = "xz2" +version = "0.1.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "388c44dc09d76f1536602ead6d325eb532f5c122f17782bd57fb47baeeb767e2" +dependencies = [ + "lzma-sys", +] + +[[package]] +name = "yaml-rust2" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "631a50d867fafb7093e709d75aaee9e0e0d5deb934021fcea25ac2fe09edc51e" +dependencies = [ + "arraydeque", + "encoding_rs", + "hashlink", +] + +[[package]] +name = "zerocopy" +version = "0.8.50" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3b065d4f0e55f82fae73202e189638116a87c55ab6b8e6c2721e13dd9d854ad1" +dependencies = [ + "zerocopy-derive", +] + +[[package]] +name = "zerocopy-derive" +version = "0.8.50" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b631b19d36a892ab55420c92dbc83ccd79274f25be714855d3074aa71cab639" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.117", +] + +[[package]] +name = "zeroize" +version = "1.8.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b97154e67e32c85465826e8bcc1c59429aaaf107c1e4a9e53c8d8ccd5eff88d0" + +[[package]] +name = "zmij" +version = "1.0.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b8848ee67ecc8aedbaf3e4122217aff892639231befc6a1b58d29fff4c2cabaa" diff --git a/examples/use_config/rp2040_embassy_boot/Cargo.toml b/examples/use_config/rp2040_embassy_boot/Cargo.toml new file mode 100644 index 000000000..a205862a3 --- /dev/null +++ b/examples/use_config/rp2040_embassy_boot/Cargo.toml @@ -0,0 +1,55 @@ +[package] +name = "rmk-rp2040-embassy-boot" +version = "0.2.0" +authors = ["Haobo Gu "] +description = "Keyboard firmware written in Rust" +homepage = "https://github.com/haobogu/rmk" +repository = "https://github.com/haobogu/rmk" +readme = "../../README.md" +edition = "2024" +license = "MIT OR Apache-2.0" + +[dependencies] +rmk = { path = "../../../rmk", features = ["dfu_rp", "dfu_lock"] } +embassy-time = { version = "0.5", features = ["defmt"] } +embassy-rp = { version = "0.10", features = [ + "rp2040", + "defmt", + "time-driver", + "critical-section-impl", +] } +embassy-executor = { version = "0.10", features = [ + "defmt", + "platform-cortex-m", + "executor-thread", +] } +cortex-m-rt = { version = "0.7.5", features = ["set-vtor"] } # <-- set-vtor necessary for embassy-boot +portable-atomic = { version = "1.11", features = ["critical-section"] } +defmt = "1.0" +defmt-rtt = "1.0" +panic-probe = { version = "1.0", features = ["print-defmt"] } + +[build-dependencies] +xz2 = "0.1.7" +json = "0.12" +const-gen = "1.6" + +[[bin]] +name = "rmk-rp2040-embassy-boot" +test = false +bench = false + +[profile.dev] +codegen-units = 1 +debug = true +opt-level = 1 +overflow-checks = true +lto = false +panic = 'unwind' + +[profile.release] +codegen-units = 1 +debug = true +opt-level = "z" +overflow-checks = false +lto = "fat" diff --git a/examples/use_config/rp2040_embassy_boot/build.rs b/examples/use_config/rp2040_embassy_boot/build.rs new file mode 100644 index 000000000..7adb35c2b --- /dev/null +++ b/examples/use_config/rp2040_embassy_boot/build.rs @@ -0,0 +1,54 @@ +use std::fs::File; +use std::io::{Read, Write}; +use std::path::{Path, PathBuf}; +use std::{env, fs}; + +use const_gen::*; +use xz2::read::XzEncoder; + +fn main() { + println!("cargo:rerun-if-changed=vial.json"); + generate_vial_config(); + + let out = &PathBuf::from(env::var_os("OUT_DIR").unwrap()); + File::create(out.join("memory.x")) + .unwrap() + .write_all(include_bytes!("memory.x")) + .unwrap(); + println!("cargo:rustc-link-search={}", out.display()); + + println!("cargo:rerun-if-changed=memory.x"); + println!("cargo:rerun-if-changed=keyboard.toml"); + + println!("cargo:rustc-link-arg=--nmagic"); + println!("cargo:rustc-link-arg=-Tlink.x"); + println!("cargo:rustc-link-arg=-Tdefmt.x"); +} + +fn generate_vial_config() { + let out_file = Path::new(&env::var_os("OUT_DIR").unwrap()).join("config_generated.rs"); + + let p = Path::new("vial.json"); + let mut content = String::new(); + match File::open(p) { + Ok(mut file) => { + file.read_to_string(&mut content).expect("Cannot read vial.json"); + } + Err(e) => println!("Cannot find vial.json {:?}: {}", p, e), + }; + + let vial_cfg = json::stringify(json::parse(&content).unwrap()); + let mut keyboard_def_compressed: Vec = Vec::new(); + XzEncoder::new(vial_cfg.as_bytes(), 6) + .read_to_end(&mut keyboard_def_compressed) + .unwrap(); + + let keyboard_id: Vec = vec![0xB9, 0xBC, 0x09, 0xB2, 0x9D, 0x37, 0x4C, 0xEA]; + let const_declarations = [ + const_declaration!(pub VIAL_KEYBOARD_DEF = keyboard_def_compressed), + const_declaration!(pub VIAL_KEYBOARD_ID = keyboard_id), + ] + .map(|s| "#[allow(clippy::redundant_static_lifetimes)]\n".to_owned() + s.as_str()) + .join("\n"); + fs::write(out_file, const_declarations).unwrap(); +} diff --git a/examples/use_config/rp2040_embassy_boot/keyboard.toml b/examples/use_config/rp2040_embassy_boot/keyboard.toml new file mode 100644 index 000000000..83c46b137 --- /dev/null +++ b/examples/use_config/rp2040_embassy_boot/keyboard.toml @@ -0,0 +1,65 @@ +[keyboard] +name = "RMK Keyboard" +product_name = "RMK Keyboard RP2040 embassy-boot use_config example" +vendor_id = 0x4c4b +product_id = 0x4643 +manufacturer = "haobo" +chip = "rp2040" + +[matrix] +row_pins = ["PIN_6", "PIN_7", "PIN_8", "PIN_9"] +col_pins = ["PIN_19", "PIN_20", "PIN_21"] + +[layout] +rows = 4 +cols = 3 +layers = 2 +keymap = [ + [ + ["A", "B", "C"], + ["Kc1", "Kc2", "Kc3"], + ["LCtrl", "MO(1)", "LShift"], + ["OSL(1)", "LT(2, Kc9)", "LM(1, LShift | LGui)"], + ], + [ + ["_", "TT(1)", "TG(2)"], + ["_", "_", "_"], + ["_", "_", "_"], + ["_", "_", "_"], + ], +] + +[storage] +enabled = true + +# DFU partition layout — must match your bootloader's memory.x +# +# By default RMK uses the bootymcbootface formula with flash_size from the +# chip default (2 MB for RP2040). +# Calculation: +# 2 * 1024 * 1024; // 2 MB (default) +# 4 * 1024 * 1024; // 4 MB +# and so on +# the addresses for the state, dfu, active and storage partitions are then automatically calculated. +# Uncomment and adjust to override: +# [dfu] +# flash_size = 2097152 # total flash (default: 2 MB) +# +# To set addresses manually, uncomment and edit the values below. +# Doing so disables the auto-calculation: +# state_offset = 0x6000 +# state_size = 0x1000 +# dfu_offset = 0x87000 +# dfu_size = 528384 +# Optional DFU activity LED (lit during firmware download) +# led = "PIN_25" + +[dfu] +led = "PIN_16" +# Optional DFU lock — physical keys to press simultaneously to unlock DFU firmware download. +# Requires the `dfu_lock` Cargo feature (not enabled by default). +unlock_keys = [[0, 0], [1, 1]] + +[rmk] +morse_max_num = 8 +max_patterns_per_key = 8 diff --git a/examples/use_config/rp2040_embassy_boot/memory.x b/examples/use_config/rp2040_embassy_boot/memory.x new file mode 100644 index 000000000..3e94ea4ba --- /dev/null +++ b/examples/use_config/rp2040_embassy_boot/memory.x @@ -0,0 +1,8 @@ +/* +This memory.x is for the RP2040 with 2MB flash. +For different flash sizes see docs. +*/ +MEMORY { + FLASH : ORIGIN = 0x10007000, LENGTH = 944K + RAM : ORIGIN = 0x20000000, LENGTH = 256K +} diff --git a/examples/use_config/rp2040_embassy_boot/src/main.rs b/examples/use_config/rp2040_embassy_boot/src/main.rs new file mode 100644 index 000000000..48b5541e8 --- /dev/null +++ b/examples/use_config/rp2040_embassy_boot/src/main.rs @@ -0,0 +1,7 @@ +#![no_main] +#![no_std] + +use rmk::macros::rmk_keyboard; + +#[rmk_keyboard] +mod keyboard {} diff --git a/examples/use_config/rp2040_embassy_boot/vial.json b/examples/use_config/rp2040_embassy_boot/vial.json new file mode 100644 index 000000000..eba77b1c5 --- /dev/null +++ b/examples/use_config/rp2040_embassy_boot/vial.json @@ -0,0 +1,37 @@ +{ + "name": "RMK Keyboard", + "vendorId": "0x4C4B", + "productId": "0x4643", + "lighting": "none", + "matrix": { + "rows": 4, + "cols": 3 + }, + "layouts": { + "keymap": [ + [ + "0,0", + "0,1", + "0,2" + ], + [ + "1,0", + "1,1", + "1,2" + ], + [ + "2,0", + "2,1", + "2,2" + ], + [ + { + "y": -2, + "x": 4 + }, + "3,0", + "3,2" + ] + ] + } +} \ No newline at end of file diff --git a/examples/use_rust/rp2040_embassy_boot/.cargo/config.toml b/examples/use_rust/rp2040_embassy_boot/.cargo/config.toml new file mode 100644 index 000000000..f1b4cbff9 --- /dev/null +++ b/examples/use_rust/rp2040_embassy_boot/.cargo/config.toml @@ -0,0 +1,11 @@ +[target.'cfg(all(target_arch = "arm", target_os = "none"))'] +runner = "probe-rs run --chip RP2040" +# runner = "elf2uf2-rs -d" + +linker = "flip-link" + +[build] +target = "thumbv6m-none-eabi" + +[env] +DEFMT_LOG = "debug" diff --git a/examples/use_rust/rp2040_embassy_boot/Cargo.lock b/examples/use_rust/rp2040_embassy_boot/Cargo.lock new file mode 100644 index 000000000..18c4043f9 --- /dev/null +++ b/examples/use_rust/rp2040_embassy_boot/Cargo.lock @@ -0,0 +1,3046 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 4 + +[[package]] +name = "aes" +version = "0.8.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b169f7a6d4742236a0a00c541b845991d0ac43e546831af1249753ab4c3aa3a0" +dependencies = [ + "cfg-if", + "cipher", + "cpufeatures", +] + +[[package]] +name = "ahash" +version = "0.8.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5a15f179cd60c4584b8a8c596927aadc462e27f2ca70c04e0071964a73ba7a75" +dependencies = [ + "cfg-if", + "once_cell", + "version_check", + "zerocopy", +] + +[[package]] +name = "aho-corasick" +version = "1.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ddd31a130427c27518df266943a5308ed92d4b226cc639f5a8f1002816174301" +dependencies = [ + "memchr", +] + +[[package]] +name = "arraydeque" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7d902e3d592a523def97af8f317b08ce16b7ab854c1985a0c671e6f15cebc236" + +[[package]] +name = "arrayvec" +version = "0.7.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7c02d123df017efcdfbd739ef81735b36c5ba83ec3c59c80a9d7ecc718f92e50" + +[[package]] +name = "ascii-canvas" +version = "4.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ef1e3e699d84ab1b0911a1010c5c106aa34ae89aeac103be5ce0c3859db1e891" +dependencies = [ + "term", +] + +[[package]] +name = "async-trait" +version = "0.1.89" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9035ad2d096bed7955a320ee7e2230574d28fd3c3a0f186cbea1ff3c7eed5dbb" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.117", +] + +[[package]] +name = "atomic-polyfill" +version = "1.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8cf2bce30dfe09ef0bfaef228b9d414faaf7e563035494d7fe092dba54b300f4" +dependencies = [ + "critical-section", +] + +[[package]] +name = "autocfg" +version = "1.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f2032f911046de80f0a198e0901378627c33f59ea0ac00e363d481118bd70a53" + +[[package]] +name = "az" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "be5eb007b7cacc6c660343e96f650fedf4b5a77512399eb952ca6642cf8d13f7" + +[[package]] +name = "bare-metal" +version = "0.2.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5deb64efa5bd81e31fcd1938615a6d98c82eafcbcd787162b6f63b91d6bac5b3" +dependencies = [ + "rustc_version 0.2.3", +] + +[[package]] +name = "base16ct" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4c7f02d4ea65f2c1853089ffd8d2787bdbc63de2f0d29dedbcf8ccdfa0ccd4cf" + +[[package]] +name = "bit-set" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "08807e080ed7f9d5433fa9b275196cfc35414f66a0c79d864dc51a0d825231a3" +dependencies = [ + "bit-vec", +] + +[[package]] +name = "bit-vec" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5e764a1d40d510daf35e07be9eb06e75770908c27d411ee6c92109c9840eaaf7" + +[[package]] +name = "bitfield" +version = "0.13.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "46afbd2983a5d5a7bd740ccb198caf5b82f45c40c09c0eed36052d91cb92e719" + +[[package]] +name = "bitfield" +version = "0.14.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2d7e60934ceec538daadb9d8432424ed043a904d8e0243f3c6446bce549a46ac" + +[[package]] +name = "bitfield-struct" +version = "0.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3ca6739863c590881f038d033a146c51ddae239186a4327014839fd864f44ed5" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.117", +] + +[[package]] +name = "bitflags" +version = "1.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" + +[[package]] +name = "bitflags" +version = "2.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b4388bee8683e3d04af747c73422af53102d2bd24d9eadb6cbc100baef4b43f8" +dependencies = [ + "serde_core", +] + +[[package]] +name = "block-buffer" +version = "0.10.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3078c7629b62d3f0439517fa394996acacc5cbc91c5a20d8c658e77abd503a71" +dependencies = [ + "generic-array", +] + +[[package]] +name = "bt-hci" +version = "0.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "211713d2e9fb4793ce4360a712c0764264aff6be48932ccf02ca2a331c0436a9" +dependencies = [ + "btuuid", + "defmt 1.1.0", + "embassy-sync", + "embedded-io 0.7.1", + "embedded-io-async 0.7.0", + "futures-intrusive", + "heapless 0.9.3", + "serde", +] + +[[package]] +name = "btuuid" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f5f48f1e9b0aad0a4f05d17bdeae0fa20ff798e272a03a6940ca27ad9c5a6ae7" +dependencies = [ + "defmt 0.3.100", + "serde", + "uuid", +] + +[[package]] +name = "bumpalo" +version = "3.20.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "72f5acc6cb2ba439de613abc23857ec3d78374d8ed5ac84e9d11336e87da8649" + +[[package]] +name = "bytemuck" +version = "1.25.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c8efb64bd706a16a1bdde310ae86b351e4d21550d98d056f22f8a7f7a2183fec" + +[[package]] +name = "byteorder" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" + +[[package]] +name = "cargo_toml" +version = "0.22.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "374b7c592d9c00c1f4972ea58390ac6b18cbb6ab79011f3bdc90a0b82ca06b77" +dependencies = [ + "serde", + "toml 0.9.12+spec-1.1.0", +] + +[[package]] +name = "cc" +version = "1.2.63" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "556e016178bb5662a08681bbe0f00f8e17631781a4dfc8c45e466e4b185ec27f" +dependencies = [ + "find-msvc-tools", + "shlex", +] + +[[package]] +name = "cfg-if" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9330f8b2ff13f34540b44e946ef35111825727b38d33286ef986142615121801" + +[[package]] +name = "chrono" +version = "0.4.45" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1aa79e62e7697b8e29b513a68abacf485adcd1fe8284a4316c5ae868e6633327" +dependencies = [ + "defmt 1.1.0", + "num-traits", + "pure-rust-locales", +] + +[[package]] +name = "cipher" +version = "0.4.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "773f3b9af64447d2ce9850330c473515014aa235e6a783b02db81ff39e4a3dad" +dependencies = [ + "crypto-common", + "inout", +] + +[[package]] +name = "cmac" +version = "0.7.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8543454e3c3f5126effff9cd44d562af4e31fb8ce1cc0d3dcd8f084515dbc1aa" +dependencies = [ + "cipher", + "dbl", + "digest", +] + +[[package]] +name = "cobs" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0fa961b519f0b462e3a3b4a34b64d119eeaca1d59af726fe450bbba07a9fc0a1" +dependencies = [ + "thiserror", +] + +[[package]] +name = "codespan-reporting" +version = "0.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3538270d33cc669650c4b093848450d380def10c331d38c768e34cac80576e6e" +dependencies = [ + "termcolor", + "unicode-width", +] + +[[package]] +name = "config" +version = "0.15.23" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f316c6237b2d38be61949ecd15268a4c6ca32570079394a2444d9ce2c72a72d8" +dependencies = [ + "async-trait", + "convert_case 0.6.0", + "json5", + "pathdiff", + "ron", + "rust-ini", + "serde-untagged", + "serde_core", + "serde_json", + "toml 1.1.2+spec-1.1.0", + "winnow 1.0.3", + "yaml-rust2", +] + +[[package]] +name = "const-gen" +version = "1.6.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a0bb51eeea292ceb9bf5312b4416c1b151b130502e6892a2ae174ae1e4b51e58" +dependencies = [ + "const-gen-derive", +] + +[[package]] +name = "const-gen-derive" +version = "1.1.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eabc01a5585d36649b6bee1f1198d112a7bb4982661d6c18406fba571ce3263e" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "const-oid" +version = "0.9.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c2459377285ad874054d797f3ccebf984978aa39129f6eafde5cdc8315b612f8" + +[[package]] +name = "const-random" +version = "0.1.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "87e00182fe74b066627d63b85fd550ac2998d4b0bd86bfed477a0ae4c7c71359" +dependencies = [ + "const-random-macro", +] + +[[package]] +name = "const-random-macro" +version = "0.1.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f9d839f2a20b0aee515dc581a6172f2321f96cab76c1a38a4c584a194955390e" +dependencies = [ + "getrandom", + "once_cell", + "tiny-keccak", +] + +[[package]] +name = "convert_case" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ec182b0ca2f35d8fc196cf3404988fd8b8c739a4d270ff118a398feb0cbec1ca" +dependencies = [ + "unicode-segmentation", +] + +[[package]] +name = "convert_case" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "baaaa0ecca5b51987b9423ccdc971514dd8b0bb7b4060b983d3664dad3f1f89f" +dependencies = [ + "unicode-segmentation", +] + +[[package]] +name = "cordyceps" +version = "0.3.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "688d7fbb8092b8de775ef2536f36c8c31f2bc4006ece2e8d8ad2d17d00ce0a2a" +dependencies = [ + "loom", + "tracing", +] + +[[package]] +name = "cortex-m" +version = "0.7.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8ec610d8f49840a5b376c69663b6369e71f4b34484b9b2eb29fb918d92516cb9" +dependencies = [ + "bare-metal", + "bitfield 0.13.2", + "embedded-hal 0.2.7", + "volatile-register", +] + +[[package]] +name = "cortex-m-rt" +version = "0.7.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "801d4dec46b34c299ccf6b036717ae0fce602faa4f4fe816d9013b9a7c9f5ba6" +dependencies = [ + "cortex-m-rt-macros", +] + +[[package]] +name = "cortex-m-rt-macros" +version = "0.7.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e37549a379a9e0e6e576fd208ee60394ccb8be963889eebba3ffe0980364f472" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.117", +] + +[[package]] +name = "cpufeatures" +version = "0.2.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "59ed5838eebb26a2bb2e58f6d5b5316989ae9d08bab10e0e6d103e656d1b0280" +dependencies = [ + "libc", +] + +[[package]] +name = "crc-any" +version = "2.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a62ec9ff5f7965e4d7280bd5482acd20aadb50d632cf6c1d74493856b011fa73" +dependencies = [ + "debug-helper", +] + +[[package]] +name = "crc32fast" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9481c1c90cbf2ac953f07c8d4a58aa3945c425b7185c9154d67a65e4230da511" +dependencies = [ + "cfg-if", +] + +[[package]] +name = "critical-section" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "790eea4361631c5e7d22598ecd5723ff611904e3344ce8720784c93e3d83d40b" + +[[package]] +name = "crunchy" +version = "0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "460fbee9c2c2f33933d720630a6a0bac33ba7053db5344fac858d4b8952d77d5" + +[[package]] +name = "crypto-bigint" +version = "0.5.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0dc92fb57ca44df6db8059111ab3af99a63d5d0f8375d9972e319a379c6bab76" +dependencies = [ + "generic-array", + "rand_core 0.6.4", + "subtle", + "zeroize", +] + +[[package]] +name = "crypto-common" +version = "0.1.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "78c8292055d1c1df0cce5d180393dc8cce0abec0a7102adb6c7b1eef6016d60a" +dependencies = [ + "generic-array", + "typenum", +] + +[[package]] +name = "darling" +version = "0.20.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fc7f46116c46ff9ab3eb1597a45688b6715c6e628b5c133e288e709a29bcb4ee" +dependencies = [ + "darling_core 0.20.11", + "darling_macro 0.20.11", +] + +[[package]] +name = "darling" +version = "0.23.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "25ae13da2f202d56bd7f91c25fba009e7717a1e4a1cc98a76d844b65ae912e9d" +dependencies = [ + "darling_core 0.23.0", + "darling_macro 0.23.0", +] + +[[package]] +name = "darling_core" +version = "0.20.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0d00b9596d185e565c2207a0b01f8bd1a135483d02d9b7b0a54b11da8d53412e" +dependencies = [ + "fnv", + "ident_case", + "proc-macro2", + "quote", + "strsim", + "syn 2.0.117", +] + +[[package]] +name = "darling_core" +version = "0.23.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9865a50f7c335f53564bb694ef660825eb8610e0a53d3e11bf1b0d3df31e03b0" +dependencies = [ + "ident_case", + "proc-macro2", + "quote", + "strsim", + "syn 2.0.117", +] + +[[package]] +name = "darling_macro" +version = "0.20.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fc34b93ccb385b40dc71c6fceac4b2ad23662c7eeb248cf10d529b7e055b6ead" +dependencies = [ + "darling_core 0.20.11", + "quote", + "syn 2.0.117", +] + +[[package]] +name = "darling_macro" +version = "0.23.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ac3984ec7bd6cfa798e62b4a642426a5be0e68f9401cfc2a01e3fa9ea2fcdb8d" +dependencies = [ + "darling_core 0.23.0", + "quote", + "syn 2.0.117", +] + +[[package]] +name = "dbl" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bd2735a791158376708f9347fe8faba9667589d82427ef3aed6794a8981de3d9" +dependencies = [ + "generic-array", +] + +[[package]] +name = "debug-helper" +version = "0.3.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f578e8e2c440e7297e008bb5486a3a8a194775224bbc23729b0dbdfaeebf162e" + +[[package]] +name = "defmt" +version = "0.3.100" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f0963443817029b2024136fc4dd07a5107eb8f977eaf18fcd1fdeb11306b64ad" +dependencies = [ + "defmt 1.1.0", +] + +[[package]] +name = "defmt" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a6e524506490a1953d237cb87b1cfc1e46f88c18f10a22dfe0f507dc6bfc7f7f" +dependencies = [ + "bitflags 1.3.2", + "defmt-macros", +] + +[[package]] +name = "defmt-macros" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f0a27770e9c8f719a79d8b638281f4d828f77d8fd61e0bd94451b9b85e576a0b" +dependencies = [ + "defmt-parser", + "proc-macro-error2", + "proc-macro2", + "quote", + "syn 2.0.117", +] + +[[package]] +name = "defmt-parser" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "10d60334b3b2e7c9d91ef8150abfb6fa4c1c39ebbcf4a81c2e346aad939fee3e" +dependencies = [ + "thiserror", +] + +[[package]] +name = "defmt-rtt" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c0f73a4a4a91609e977ae3b7bd831ffa292edfd42ad140a3244a61d805b0e05e" +dependencies = [ + "critical-section", + "defmt 1.1.0", +] + +[[package]] +name = "der" +version = "0.7.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e7c1832837b905bbfb5101e07cc24c8deddf52f93225eee6ead5f4d63d53ddcb" +dependencies = [ + "const-oid", + "zeroize", +] + +[[package]] +name = "digest" +version = "0.10.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292" +dependencies = [ + "block-buffer", + "crypto-common", + "subtle", +] + +[[package]] +name = "dlv-list" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "442039f5147480ba31067cb00ada1adae6892028e40e45fc5de7b7df6dcc1b5f" +dependencies = [ + "const-random", +] + +[[package]] +name = "document-features" +version = "0.2.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d4b8a88685455ed29a21542a33abd9cb6510b6b129abadabdcef0f4c55bc8f61" +dependencies = [ + "litrs", +] + +[[package]] +name = "either" +version = "1.16.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "91622ff5e7162018101f2fea40d6ebf4a78bbe5a49736a2020649edf9693679e" + +[[package]] +name = "elliptic-curve" +version = "0.13.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b5e6043086bf7973472e0c7dff2142ea0b680d30e18d9cc40f267efbf222bd47" +dependencies = [ + "base16ct", + "crypto-bigint", + "digest", + "ff", + "generic-array", + "group", + "hkdf", + "rand_core 0.6.4", + "sec1", + "subtle", + "zeroize", +] + +[[package]] +name = "embassy-boot" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "73bfc955c9238df2ce9fecc6f18a64b13ecaa41a3cd42d940a09f304765d10db" +dependencies = [ + "digest", + "document-features", + "embassy-embedded-hal", + "embassy-sync", + "embedded-storage", + "embedded-storage-async", + "signature", +] + +[[package]] +name = "embassy-boot-rp" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3fc17df4cf2a8ba86e8559a6515104e31ca7aa6b36221199310e244157935204" +dependencies = [ + "cfg-if", + "cortex-m", + "cortex-m-rt", + "embassy-boot", + "embassy-rp", + "embassy-sync", + "embassy-time", + "embedded-storage", + "embedded-storage-async", +] + +[[package]] +name = "embassy-embedded-hal" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b0641612053b2f34fc250bb63f6630ae75de46e02ade7f457268447081d709ce" +dependencies = [ + "defmt 1.1.0", + "embassy-futures", + "embassy-hal-internal 0.4.0", + "embassy-sync", + "embassy-time", + "embedded-hal 0.2.7", + "embedded-hal 1.0.0", + "embedded-hal-async", + "embedded-storage", + "embedded-storage-async", + "nb 1.1.0", +] + +[[package]] +name = "embassy-executor" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5d0d3b15c9d7dc4fec1d8cb77112472fb008b3b28c51ad23838d83587a6d2f1e" +dependencies = [ + "cordyceps", + "cortex-m", + "critical-section", + "defmt 1.1.0", + "document-features", + "embassy-executor-macros", + "embassy-executor-timer-queue", +] + +[[package]] +name = "embassy-executor-macros" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d11a246f53de5f97a387f40ac24726817cd0b6f833e7603baac784f29d6ff276" +dependencies = [ + "darling 0.20.11", + "proc-macro2", + "quote", + "syn 2.0.117", +] + +[[package]] +name = "embassy-executor-timer-queue" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2fc328bf943af66b80b98755db9106bf7e7471b0cf47dc8559cd9a6be504cc9c" + +[[package]] +name = "embassy-futures" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dc2d050bdc5c21e0862a89256ed8029ae6c290a93aecefc73084b3002cdebb01" +dependencies = [ + "defmt 1.1.0", +] + +[[package]] +name = "embassy-hal-internal" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7f10ce10a4dfdf6402d8e9bd63128986b96a736b1a0a6680547ed2ac55d55dba" +dependencies = [ + "num-traits", +] + +[[package]] +name = "embassy-hal-internal" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "568659fc53866d3d85c60fa33723fb751aa69e71507634fc2c19e7649432fb75" +dependencies = [ + "cortex-m", + "critical-section", + "defmt 1.1.0", + "num-traits", +] + +[[package]] +name = "embassy-net-driver" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "524eb3c489760508f71360112bca70f6e53173e6fe48fc5f0efd0f5ab217751d" + +[[package]] +name = "embassy-net-driver-channel" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a07d2eb9f05a6fc876500949856ea1be40773d866d8cb99384f72d0ae4568c16" +dependencies = [ + "embassy-futures", + "embassy-net-driver", + "embassy-sync", +] + +[[package]] +name = "embassy-nrf" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b715380574504335c40ec3016bc44598fac3c385f82959b26c41b25c30b7648d" +dependencies = [ + "bitflags 2.13.0", + "cfg-if", + "cortex-m", + "cortex-m-rt", + "critical-section", + "defmt 1.1.0", + "document-features", + "embassy-embedded-hal", + "embassy-futures", + "embassy-hal-internal 0.5.0", + "embassy-sync", + "embassy-time", + "embassy-usb-driver", + "embedded-hal 0.2.7", + "embedded-hal 1.0.0", + "embedded-hal-async", + "embedded-io 0.7.1", + "embedded-io-async 0.7.0", + "embedded-storage", + "embedded-storage-async", + "fixed", + "nrf-pac", + "rand_core 0.6.4", + "rand_core 0.9.5", +] + +[[package]] +name = "embassy-rp" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5d98f472894c1ecffac5596c657af5305c57282d29e8746d7fec033951931bc8" +dependencies = [ + "cfg-if", + "chrono", + "cortex-m", + "cortex-m-rt", + "critical-section", + "defmt 1.1.0", + "document-features", + "embassy-embedded-hal", + "embassy-futures", + "embassy-hal-internal 0.5.0", + "embassy-sync", + "embassy-time", + "embassy-time-driver", + "embassy-time-queue-utils", + "embassy-usb-driver", + "embedded-hal 0.2.7", + "embedded-hal 1.0.0", + "embedded-hal-async", + "embedded-hal-nb", + "embedded-io 0.7.1", + "embedded-io-async 0.7.0", + "embedded-storage", + "embedded-storage-async", + "fixed", + "nb 1.1.0", + "pio", + "rand_core 0.6.4", + "rand_core 0.9.5", + "rp-pac", + "rp2040-boot2", + "sha2-const-stable", + "smart-leds", +] + +[[package]] +name = "embassy-sync" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7bbd85cf5a5ae56bdf26f618364af642d1d0a4e245cdd75cd9aabda382f65a81" +dependencies = [ + "cfg-if", + "critical-section", + "defmt 1.1.0", + "embedded-io-async 0.7.0", + "futures-core", + "futures-sink", + "heapless 0.9.3", +] + +[[package]] +name = "embassy-time" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "592b0c143ec626e821d4d90da51a2bd91d559d6c442b7c74a47d368c9e23d97a" +dependencies = [ + "cfg-if", + "critical-section", + "defmt 1.1.0", + "document-features", + "embassy-time-driver", + "embedded-hal 0.2.7", + "embedded-hal 1.0.0", + "embedded-hal-async", + "futures-core", +] + +[[package]] +name = "embassy-time-driver" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6ee71af1b3a0deaa53eaf2d39252f83504c853646e472400b763060389b9fcc9" +dependencies = [ + "document-features", +] + +[[package]] +name = "embassy-time-queue-utils" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "168297bf80aaf114b3c9ad589bf38b01b3009b9af7f97cd18086c5bbf96f5693" +dependencies = [ + "embassy-executor-timer-queue", + "heapless 0.9.3", +] + +[[package]] +name = "embassy-usb" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a25746d8b152b72fbf2a217f489a083dbbe243f281f09184a1f2cfbe9bbb245f" +dependencies = [ + "bitflags 2.13.0", + "defmt 1.1.0", + "embassy-futures", + "embassy-net-driver-channel", + "embassy-sync", + "embassy-time", + "embassy-usb-driver", + "embedded-io-async 0.7.0", + "heapless 0.9.3", + "ssmarshal", + "usbd-hid", +] + +[[package]] +name = "embassy-usb-dfu" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e36d3678d16e1e71b052d00f7518620b5839a878f2bdab2019b81d984fb2a74f" +dependencies = [ + "bitflags 2.13.0", + "cortex-m", + "embassy-boot", + "embassy-futures", + "embassy-sync", + "embassy-time", + "embassy-usb", + "embedded-storage", +] + +[[package]] +name = "embassy-usb-driver" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fa675c5f4349b6aa0fcffc4bf9b241f18cd11b97c1f8323273fb9a5449937fbd" +dependencies = [ + "defmt 1.1.0", + "embedded-io-async 0.6.1", + "embedded-io-async 0.7.0", +] + +[[package]] +name = "embedded-hal" +version = "0.2.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "35949884794ad573cf46071e41c9b60efb0cb311e3ca01f7af807af1debc66ff" +dependencies = [ + "nb 0.1.3", + "void", +] + +[[package]] +name = "embedded-hal" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "361a90feb7004eca4019fb28352a9465666b24f840f5c3cddf0ff13920590b89" +dependencies = [ + "defmt 0.3.100", +] + +[[package]] +name = "embedded-hal-async" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0c4c685bbef7fe13c3c6dd4da26841ed3980ef33e841cddfa15ce8a8fb3f1884" +dependencies = [ + "defmt 0.3.100", + "embedded-hal 1.0.0", +] + +[[package]] +name = "embedded-hal-nb" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fba4268c14288c828995299e59b12babdbe170f6c6d73731af1b4648142e8605" +dependencies = [ + "embedded-hal 1.0.0", + "nb 1.1.0", +] + +[[package]] +name = "embedded-io" +version = "0.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "edd0f118536f44f5ccd48bcb8b111bdc3de888b58c74639dfb034a357d0f206d" + +[[package]] +name = "embedded-io" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9eb1aa714776b75c7e67e1da744b81a129b3ff919c8712b5e1b32252c1f07cc7" +dependencies = [ + "defmt 1.1.0", +] + +[[package]] +name = "embedded-io-async" +version = "0.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3ff09972d4073aa8c299395be75161d582e7629cd663171d62af73c8d50dba3f" +dependencies = [ + "embedded-io 0.6.1", +] + +[[package]] +name = "embedded-io-async" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2564b9f813c544241430e147d8bc454815ef9ac998878d30cc3055449f7fd4c0" +dependencies = [ + "defmt 1.1.0", + "embedded-io 0.7.1", +] + +[[package]] +name = "embedded-storage" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a21dea9854beb860f3062d10228ce9b976da520a73474aed3171ec276bc0c032" + +[[package]] +name = "embedded-storage-async" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1763775e2323b7d5f0aa6090657f5e21cfa02ede71f5dc40eead06d64dcd15cc" +dependencies = [ + "embedded-storage", +] + +[[package]] +name = "ena" +version = "0.14.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eabffdaee24bd1bf95c5ef7cec31260444317e72ea56c4c91750e8b7ee58d5f1" +dependencies = [ + "log", +] + +[[package]] +name = "encode_unicode" +version = "0.3.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a357d28ed41a50f9c765dbfe56cbc04a64e53e5fc58ba79fbc34c10ef3df831f" + +[[package]] +name = "encoding_rs" +version = "0.8.35" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "75030f3c4f45dafd7586dd6780965a8c7e8e285a5ecb86713e63a79c5b2766f3" +dependencies = [ + "cfg-if", +] + +[[package]] +name = "equivalent" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "877a4ace8713b0bcf2a4e7eec82529c029f1d0619886d18145fea96c3ffe5c0f" + +[[package]] +name = "erased-serde" +version = "0.4.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d2add8a07dd6a8d93ff627029c51de145e12686fbc36ecb298ac22e74cf02dec" +dependencies = [ + "serde", + "serde_core", + "typeid", +] + +[[package]] +name = "ff" +version = "0.13.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c0b50bfb653653f9ca9095b427bed08ab8d75a137839d9ad64eb11810d5b6393" +dependencies = [ + "rand_core 0.6.4", + "subtle", +] + +[[package]] +name = "find-msvc-tools" +version = "0.1.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5baebc0774151f905a1a2cc41989300b1e6fbb29aff0ceffa1064fdd3088d582" + +[[package]] +name = "fixed" +version = "1.31.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9af2cbf772fa6d1c11358f92ef554cb6b386201210bcf0e91fb7fba8a907fb40" +dependencies = [ + "az", + "bytemuck", + "half", + "typenum", +] + +[[package]] +name = "fixedbitset" +version = "0.5.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1d674e81391d1e1ab681a28d99df07927c6d4aa5b027d7da16ba32d1d21ecd99" + +[[package]] +name = "fnv" +version = "1.0.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" + +[[package]] +name = "foldhash" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "77ce24cb58228fbb8aa041425bb1050850ac19177686ea6e0f41a70416f56fdb" + +[[package]] +name = "futures" +version = "0.3.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8b147ee9d1f6d097cef9ce628cd2ee62288d963e16fb287bd9286455b241382d" +dependencies = [ + "futures-channel", + "futures-core", + "futures-io", + "futures-sink", + "futures-task", + "futures-util", +] + +[[package]] +name = "futures-channel" +version = "0.3.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "07bbe89c50d7a535e539b8c17bc0b49bdb77747034daa8087407d655f3f7cc1d" +dependencies = [ + "futures-core", + "futures-sink", +] + +[[package]] +name = "futures-core" +version = "0.3.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7e3450815272ef58cec6d564423f6e755e25379b217b0bc688e295ba24df6b1d" + +[[package]] +name = "futures-intrusive" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1d930c203dd0b6ff06e0201a4a2fe9149b43c684fd4420555b26d21b1a02956f" +dependencies = [ + "futures-core", + "lock_api", +] + +[[package]] +name = "futures-io" +version = "0.3.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cecba35d7ad927e23624b22ad55235f2239cfa44fd10428eecbeba6d6a717718" + +[[package]] +name = "futures-macro" +version = "0.3.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e835b70203e41293343137df5c0664546da5745f82ec9b84d40be8336958447b" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.117", +] + +[[package]] +name = "futures-sink" +version = "0.3.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c39754e157331b013978ec91992bde1ac089843443c49cbc7f46150b0fad0893" + +[[package]] +name = "futures-task" +version = "0.3.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "037711b3d59c33004d3856fbdc83b99d4ff37a24768fa1be9ce3538a1cde4393" + +[[package]] +name = "futures-util" +version = "0.3.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "389ca41296e6190b48053de0321d02a77f32f8a5d2461dd38762c0593805c6d6" +dependencies = [ + "futures-core", + "futures-macro", + "futures-sink", + "futures-task", + "pin-project-lite", + "slab", +] + +[[package]] +name = "generator" +version = "0.8.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b3b854b0e584ead1a33f18b2fcad7cf7be18b3875c78816b753639aa501513ae" +dependencies = [ + "cc", + "cfg-if", + "libc", + "log", + "rustversion", + "windows-link", + "windows-result", +] + +[[package]] +name = "generic-array" +version = "0.14.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "85649ca51fd72272d7821adaf274ad91c288277713d9c18820d8499a7ff69e9a" +dependencies = [ + "typenum", + "version_check", + "zeroize", +] + +[[package]] +name = "getrandom" +version = "0.2.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ff2abc00be7fca6ebc474524697ae276ad847ad0a6b3faa4bcb027e9a4614ad0" +dependencies = [ + "cfg-if", + "libc", + "wasi", +] + +[[package]] +name = "group" +version = "0.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f0f9ef7462f7c099f518d754361858f86d8a07af53ba9af0fe635bbccb151a63" +dependencies = [ + "ff", + "rand_core 0.6.4", + "subtle", +] + +[[package]] +name = "half" +version = "2.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6ea2d84b969582b4b1864a92dc5d27cd2b77b622a8d79306834f1be5ba20d84b" +dependencies = [ + "cfg-if", + "crunchy", + "zerocopy", +] + +[[package]] +name = "hash32" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b0c35f58762feb77d74ebe43bdbc3210f09be9fe6742234d573bacc26ed92b67" +dependencies = [ + "byteorder", +] + +[[package]] +name = "hash32" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "47d60b12902ba28e2730cd37e95b8c9223af2808df9e902d4df49588d1470606" +dependencies = [ + "byteorder", +] + +[[package]] +name = "hashbrown" +version = "0.13.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "43a3c133739dddd0d2990f9a4bdf8eb4b21ef50e4851ca85ab661199821d510e" +dependencies = [ + "ahash", +] + +[[package]] +name = "hashbrown" +version = "0.14.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e5274423e17b7c9fc20b6e7e208532f9b19825d82dfd615708b70edd83df41f1" + +[[package]] +name = "hashbrown" +version = "0.16.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "841d1cc9bed7f9236f321df977030373f4a4163ae1a7dbfe1a51a2c1a51d9100" +dependencies = [ + "foldhash", +] + +[[package]] +name = "hashbrown" +version = "0.17.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ed5909b6e89a2db4456e54cd5f673791d7eca6732202bbf2a9cc504fe2f9b84a" + +[[package]] +name = "hashlink" +version = "0.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "824e001ac4f3012dd16a264bec811403a67ca9deb6c102fc5049b32c4574b35f" +dependencies = [ + "hashbrown 0.16.1", +] + +[[package]] +name = "heapless" +version = "0.7.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cdc6457c0eb62c71aac4bc17216026d8410337c4126773b9c5daba343f17964f" +dependencies = [ + "atomic-polyfill", + "hash32 0.2.1", + "rustc_version 0.4.1", + "serde", + "spin", + "stable_deref_trait", +] + +[[package]] +name = "heapless" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0bfb9eb618601c89945a70e254898da93b13be0388091d42117462b265bb3fad" +dependencies = [ + "hash32 0.3.1", + "stable_deref_trait", +] + +[[package]] +name = "heapless" +version = "0.9.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "25ba4bd83f9415b58b4ed8dc5714c76e626a105be4646c02630ad730ad3b5aa4" +dependencies = [ + "defmt 1.1.0", + "hash32 0.3.1", + "serde_core", + "stable_deref_trait", +] + +[[package]] +name = "heck" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea" + +[[package]] +name = "hkdf" +version = "0.12.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7b5f8eb2ad728638ea2c7d47a21db23b7b58a72ed6a38256b8a1849f15fbbdf7" +dependencies = [ + "hmac", +] + +[[package]] +name = "hmac" +version = "0.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6c49c37c09c17a53d937dfbb742eb3a961d65a994e6bcdcf37e7399d0cc8ab5e" +dependencies = [ + "digest", +] + +[[package]] +name = "ident_case" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b9e0384b61958566e926dc50660321d12159025e767c18e043daf26b70104c39" + +[[package]] +name = "indexmap" +version = "2.14.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d466e9454f08e4a911e14806c24e16fba1b4c121d1ea474396f396069cf949d9" +dependencies = [ + "equivalent", + "hashbrown 0.17.1", +] + +[[package]] +name = "inout" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "879f10e63c20629ecabbb64a8010319738c66a5cd0c29b02d63d272b03751d01" +dependencies = [ + "generic-array", +] + +[[package]] +name = "itertools" +version = "0.14.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2b192c782037fadd9cfa75548310488aabdbf3d2da73885b31bd0abd03351285" +dependencies = [ + "either", +] + +[[package]] +name = "itoa" +version = "1.0.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f42a60cbdf9a97f5d2305f08a87dc4e09308d1276d28c869c684d7777685682" + +[[package]] +name = "js-sys" +version = "0.3.99" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "142bc4740e452c1e57ade0cbc129f139c9093e354346f0872ef985f4f5cf5f11" +dependencies = [ + "cfg-if", + "futures-util", + "once_cell", + "wasm-bindgen", +] + +[[package]] +name = "json" +version = "0.12.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "078e285eafdfb6c4b434e0d31e8cfcb5115b651496faca5749b88fafd4f23bfd" + +[[package]] +name = "json5" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "96b0db21af676c1ce64250b5f40f3ce2cf27e4e47cb91ed91eb6fe9350b430c1" +dependencies = [ + "pest", + "pest_derive", + "serde", +] + +[[package]] +name = "keccak" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cb26cec98cce3a3d96cbb7bced3c4b16e3d13f27ec56dbd62cbc8f39cfb9d653" +dependencies = [ + "cpufeatures", +] + +[[package]] +name = "lalrpop" +version = "0.22.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ba4ebbd48ce411c1d10fb35185f5a51a7bfa3d8b24b4e330d30c9e3a34129501" +dependencies = [ + "ascii-canvas", + "bit-set", + "ena", + "itertools", + "lalrpop-util", + "petgraph", + "pico-args", + "regex", + "regex-syntax", + "sha3", + "string_cache", + "term", + "unicode-xid", + "walkdir", +] + +[[package]] +name = "lalrpop-util" +version = "0.22.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b5baa5e9ff84f1aefd264e6869907646538a52147a755d494517a8007fb48733" +dependencies = [ + "regex-automata", + "rustversion", +] + +[[package]] +name = "lazy_static" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe" + +[[package]] +name = "libc" +version = "0.2.186" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "68ab91017fe16c622486840e4c83c9a37afeff978bd239b5293d61ece587de66" + +[[package]] +name = "litrs" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "11d3d7f243d5c5a8b9bb5d6dd2b1602c0cb0b9db1621bafc7ed66e35ff9fe092" + +[[package]] +name = "lock_api" +version = "0.4.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "224399e74b87b5f3557511d98dff8b14089b3dadafcab6bb93eab67d3aace965" +dependencies = [ + "scopeguard", +] + +[[package]] +name = "log" +version = "0.4.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "953f07c43838f8e6f9758cab68bf5bed85465e7587ebe0b823f1bcd81978ad3a" + +[[package]] +name = "loom" +version = "0.7.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "419e0dc8046cb947daa77eb95ae174acfbddb7673b4151f56d1eed8e93fbfaca" +dependencies = [ + "cfg-if", + "generator", + "scoped-tls", + "tracing", + "tracing-subscriber", +] + +[[package]] +name = "lzma-sys" +version = "0.1.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5fda04ab3764e6cde78b9974eec4f779acaba7c4e84b36eca3cf77c581b85d27" +dependencies = [ + "cc", + "libc", + "pkg-config", +] + +[[package]] +name = "matchers" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d1525a2a28c7f4fa0fc98bb91ae755d1e2d1505079e05539e35bc876b5d65ae9" +dependencies = [ + "regex-automata", +] + +[[package]] +name = "memchr" +version = "2.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6b947ae49db0d222b1dbc6b113ce7248a3fc3a6ca21b696717bfc000ba4484d8" + +[[package]] +name = "nb" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "801d31da0513b6ec5214e9bf433a77966320625a37860f910be265be6e18d06f" +dependencies = [ + "nb 1.1.0", +] + +[[package]] +name = "nb" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8d5439c4ad607c3c23abf66de8c8bf57ba8adcd1f129e699851a6e43935d339d" + +[[package]] +name = "new_debug_unreachable" +version = "1.0.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "650eef8c711430f1a879fdd01d4745a7deea475becfb90269c06775983bbf086" + +[[package]] +name = "nrf-pac" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bddd547fab92b0553ff37032034fd04ce8b8b60d3f9a83f89ea815dfd0400336" +dependencies = [ + "cortex-m", + "cortex-m-rt", +] + +[[package]] +name = "nu-ansi-term" +version = "0.50.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7957b9740744892f114936ab4a57b3f487491bbeafaf8083688b16841a4240e5" +dependencies = [ + "windows-sys", +] + +[[package]] +name = "num-traits" +version = "0.2.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841" +dependencies = [ + "autocfg", +] + +[[package]] +name = "num_enum" +version = "0.7.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5d0bca838442ec211fa11de3a8b0e0e8f3a4522575b5c4c06ed722e005036f26" +dependencies = [ + "num_enum_derive", + "rustversion", +] + +[[package]] +name = "num_enum_derive" +version = "0.7.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "680998035259dcfcafe653688bf2aa6d3e2dc05e98be6ab46afb089dc84f1df8" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.117", +] + +[[package]] +name = "once_cell" +version = "1.21.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9f7c3e4beb33f85d45ae3e3a1792185706c8e16d043238c593331cc7cd313b50" + +[[package]] +name = "ordered-multimap" +version = "0.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "49203cdcae0030493bad186b28da2fa25645fa276a51b6fec8010d281e02ef79" +dependencies = [ + "dlv-list", + "hashbrown 0.14.5", +] + +[[package]] +name = "p256" +version = "0.13.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c9863ad85fa8f4460f9c48cb909d38a0d689dba1f6f6988a5e3e0d31071bcd4b" +dependencies = [ + "elliptic-curve", + "primeorder", +] + +[[package]] +name = "panic-probe" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fd402d00b0fb94c5aee000029204a46884b1262e0c443f166d86d2c0747e1a1a" +dependencies = [ + "cortex-m", + "defmt 1.1.0", +] + +[[package]] +name = "parking_lot" +version = "0.12.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "93857453250e3077bd71ff98b6a65ea6621a19bb0f559a85248955ac12c45a1a" +dependencies = [ + "lock_api", + "parking_lot_core", +] + +[[package]] +name = "parking_lot_core" +version = "0.9.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2621685985a2ebf1c516881c026032ac7deafcda1a2c9b7850dc81e3dfcb64c1" +dependencies = [ + "cfg-if", + "libc", + "redox_syscall", + "smallvec", + "windows-link", +] + +[[package]] +name = "paste" +version = "1.0.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "57c0d7b74b563b49d38dae00a0c37d4d6de9b432382b2892f0574ddcae73fd0a" + +[[package]] +name = "pathdiff" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "df94ce210e5bc13cb6651479fa48d14f601d9858cfe0467f43ae157023b938d3" + +[[package]] +name = "pest" +version = "2.8.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e0848c601009d37dfa3430c4666e147e49cdcf1b92ecd3e63657d8a5f19da662" +dependencies = [ + "memchr", + "ucd-trie", +] + +[[package]] +name = "pest_derive" +version = "2.8.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "11f486f1ea21e6c10ed15d5a7c77165d0ee443402f0780849d1768e7d9d6fe77" +dependencies = [ + "pest", + "pest_generator", +] + +[[package]] +name = "pest_generator" +version = "2.8.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8040c4647b13b210a963c1ed407c1ff4fdfa01c31d6d2a098218702e6664f94f" +dependencies = [ + "pest", + "pest_meta", + "proc-macro2", + "quote", + "syn 2.0.117", +] + +[[package]] +name = "pest_meta" +version = "2.8.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "89815c69d36021a140146f26659a81d6c2afa33d216d736dd4be5381a7362220" +dependencies = [ + "pest", + "sha2", +] + +[[package]] +name = "petgraph" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3672b37090dbd86368a4145bc067582552b29c27377cad4e0a306c97f9bd7772" +dependencies = [ + "fixedbitset", + "indexmap", +] + +[[package]] +name = "phf_shared" +version = "0.11.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "67eabc2ef2a60eb7faa00097bd1ffdb5bd28e62bf39990626a582201b7a754e5" +dependencies = [ + "siphasher", +] + +[[package]] +name = "pico-args" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5be167a7af36ee22fe3115051bc51f6e6c7054c9348e28deb4f49bd6f705a315" + +[[package]] +name = "pin-project-lite" +version = "0.2.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a89322df9ebe1c1578d689c92318e070967d1042b512afbe49518723f4e6d5cd" + +[[package]] +name = "pio" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d0ba4153cee9585abc451271aa437d9e8defdea8b468d48ba6b8f098cbe03d7f" +dependencies = [ + "pio-core", + "pio-proc", +] + +[[package]] +name = "pio-core" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "61d90fddc3d67f21bbf93683bc461b05d6a29c708caf3ffb79947d7ff7095406" +dependencies = [ + "arrayvec", + "num_enum", + "paste", +] + +[[package]] +name = "pio-parser" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "825266c1eaddf54f636d06eefa4bf3c99d774c14ec46a4a6c6e5128a0f10d205" +dependencies = [ + "lalrpop", + "lalrpop-util", + "pio-core", +] + +[[package]] +name = "pio-proc" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ed4a76571f5fe51af43cc80ac870fe0c79cc0cdd686b9002a6c4c84bfdd0176b" +dependencies = [ + "codespan-reporting", + "lalrpop-util", + "pio-core", + "pio-parser", + "proc-macro-error2", + "proc-macro2", + "quote", + "syn 2.0.117", +] + +[[package]] +name = "pkg-config" +version = "0.3.33" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "19f132c84eca552bf34cab8ec81f1c1dcc229b811638f9d283dceabe58c5569e" + +[[package]] +name = "portable-atomic" +version = "1.13.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c33a9471896f1c69cecef8d20cbe2f7accd12527ce60845ff44c153bb2a21b49" +dependencies = [ + "critical-section", +] + +[[package]] +name = "postcard" +version = "1.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6764c3b5dd454e283a30e6dfe78e9b31096d9e32036b5d1eaac7a6119ccb9a24" +dependencies = [ + "cobs", + "defmt 1.1.0", + "heapless 0.7.17", + "postcard-derive", + "serde", +] + +[[package]] +name = "postcard-derive" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e0232bd009a197ceec9cc881ba46f727fcd8060a2d8d6a9dde7a69030a6fe2bb" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.117", +] + +[[package]] +name = "ppv-lite86" +version = "0.2.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "85eae3c4ed2f50dcfe72643da4befc30deadb458a9b590d720cde2f2b1e97da9" +dependencies = [ + "zerocopy", +] + +[[package]] +name = "precomputed-hash" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "925383efa346730478fb4838dbe9137d2a47675ad789c546d150a6e1dd4ab31c" + +[[package]] +name = "primeorder" +version = "0.13.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "353e1ca18966c16d9deb1c69278edbc5f194139612772bd9537af60ac231e1e6" +dependencies = [ + "elliptic-curve", +] + +[[package]] +name = "proc-macro-error-attr2" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "96de42df36bb9bba5542fe9f1a054b8cc87e172759a1868aa05c1f3acc89dfc5" +dependencies = [ + "proc-macro2", + "quote", +] + +[[package]] +name = "proc-macro-error2" +version = "2.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "11ec05c52be0a07b08061f7dd003e7d7092e0472bc731b4af7bb1ef876109802" +dependencies = [ + "proc-macro-error-attr2", + "proc-macro2", + "quote", + "syn 2.0.117", +] + +[[package]] +name = "proc-macro2" +version = "1.0.106" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8fd00f0bb2e90d81d1044c2b32617f68fcb9fa3bb7640c23e9c748e53fb30934" +dependencies = [ + "unicode-ident", +] + +[[package]] +name = "pure-rust-locales" +version = "0.8.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "869675ad2d7541aea90c6d88c81f46a7f4ea9af8cd0395d38f11a95126998a0d" +dependencies = [ + "defmt 1.1.0", +] + +[[package]] +name = "quote" +version = "1.0.45" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "41f2619966050689382d2b44f664f4bc593e129785a36d6ee376ddf37259b924" +dependencies = [ + "proc-macro2", +] + +[[package]] +name = "rand" +version = "0.8.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5ca0ecfa931c29007047d1bc58e623ab12e5590e8c7cc53200d5202b69266d8a" +dependencies = [ + "rand_core 0.6.4", +] + +[[package]] +name = "rand_chacha" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88" +dependencies = [ + "ppv-lite86", + "rand_core 0.6.4", +] + +[[package]] +name = "rand_core" +version = "0.6.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" + +[[package]] +name = "rand_core" +version = "0.9.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "76afc826de14238e6e8c374ddcc1fa19e374fd8dd986b0d2af0d02377261d83c" + +[[package]] +name = "redox_syscall" +version = "0.5.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ed2bf2547551a7053d6fdfafda3f938979645c44812fbfcda098faae3f1a362d" +dependencies = [ + "bitflags 2.13.0", +] + +[[package]] +name = "regex" +version = "1.12.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e10754a14b9137dd7b1e3e5b0493cc9171fdd105e0ab477f51b72e7f3ac0e276" +dependencies = [ + "aho-corasick", + "memchr", + "regex-automata", + "regex-syntax", +] + +[[package]] +name = "regex-automata" +version = "0.4.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6e1dd4122fc1595e8162618945476892eefca7b88c52820e74af6262213cae8f" +dependencies = [ + "aho-corasick", + "memchr", + "regex-syntax", +] + +[[package]] +name = "regex-syntax" +version = "0.8.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dc897dd8d9e8bd1ed8cdad82b5966c3e0ecae09fb1907d58efaa013543185d0a" + +[[package]] +name = "rgb" +version = "0.8.53" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "47b34b781b31e5d73e9fbc8689c70551fd1ade9a19e3e28cfec8580a79290cc4" + +[[package]] +name = "rmk" +version = "0.8.2" +dependencies = [ + "bt-hci", + "byteorder", + "cortex-m", + "crc32fast", + "defmt 1.1.0", + "document-features", + "embassy-boot", + "embassy-boot-rp", + "embassy-embedded-hal", + "embassy-futures", + "embassy-hal-internal 0.5.0", + "embassy-nrf", + "embassy-rp", + "embassy-sync", + "embassy-time", + "embassy-usb", + "embassy-usb-dfu", + "embedded-hal 1.0.0", + "embedded-hal-async", + "embedded-io-async 0.7.0", + "embedded-storage", + "embedded-storage-async", + "fixed", + "futures", + "heapless 0.9.3", + "paste", + "pio", + "postcard", + "rmk-macro", + "rmk-types", + "rp-pac", + "sequential-storage", + "serde", + "static_cell", + "trouble-host", + "usbd-hid", +] + +[[package]] +name = "rmk-config" +version = "0.6.1" +dependencies = [ + "config", + "once_cell", + "paste", + "pest", + "pest_derive", + "serde", + "serde-inline-default", + "toml 1.1.2+spec-1.1.0", +] + +[[package]] +name = "rmk-macro" +version = "0.7.1" +dependencies = [ + "cargo_toml", + "darling 0.23.0", + "proc-macro2", + "quote", + "rmk-config", + "rmk-types", + "strum", + "syn 2.0.117", +] + +[[package]] +name = "rmk-rp2040-embassy-boot" +version = "0.2.0" +dependencies = [ + "const-gen", + "cortex-m-rt", + "defmt 1.1.0", + "defmt-rtt", + "embassy-executor", + "embassy-rp", + "embassy-time", + "json", + "panic-probe", + "portable-atomic", + "rmk", + "xz2", +] + +[[package]] +name = "rmk-types" +version = "0.2.2" +dependencies = [ + "bitfield-struct", + "defmt 1.1.0", + "heapless 0.9.3", + "postcard", + "rmk-config", + "serde", + "strum", + "toml 1.1.2+spec-1.1.0", +] + +[[package]] +name = "ron" +version = "0.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4147b952f3f819eca0e99527022f7d6a8d05f111aeb0a62960c74eb283bec8fc" +dependencies = [ + "bitflags 2.13.0", + "once_cell", + "serde", + "serde_derive", + "typeid", + "unicode-ident", +] + +[[package]] +name = "rp-pac" +version = "7.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8af65855c40b2c35079514c5489abffc0429347fef25d8467ff98ad84b4322d3" +dependencies = [ + "cortex-m", + "cortex-m-rt", +] + +[[package]] +name = "rp2040-boot2" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7c92f344f63f950ee36cf4080050e4dce850839b9175da38f9d2ffb69b4dbb21" +dependencies = [ + "crc-any", +] + +[[package]] +name = "rust-ini" +version = "0.21.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "796e8d2b6696392a43bea58116b667fb4c29727dc5abd27d6acf338bb4f688c7" +dependencies = [ + "cfg-if", + "ordered-multimap", +] + +[[package]] +name = "rustc_version" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "138e3e0acb6c9fb258b19b67cb8abd63c00679d2851805ea151465464fe9030a" +dependencies = [ + "semver 0.9.0", +] + +[[package]] +name = "rustc_version" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cfcb3a22ef46e85b45de6ee7e79d063319ebb6594faafcf1c225ea92ab6e9b92" +dependencies = [ + "semver 1.0.28", +] + +[[package]] +name = "rustversion" +version = "1.0.22" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b39cdef0fa800fc44525c84ccb54a029961a8215f9619753635a9c0d2538d46d" + +[[package]] +name = "same-file" +version = "1.0.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "93fc1dc3aaa9bfed95e02e6eadabb4baf7e3078b0bd1b4d7b6b0b68378900502" +dependencies = [ + "winapi-util", +] + +[[package]] +name = "scoped-tls" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e1cf6437eb19a8f4a6cc0f7dca544973b0b78843adbfeb3683d1a94a0024a294" + +[[package]] +name = "scopeguard" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" + +[[package]] +name = "sec1" +version = "0.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d3e97a565f76233a6003f9f5c54be1d9c5bdfa3eccfb189469f11ec4901c47dc" +dependencies = [ + "base16ct", + "der", + "generic-array", + "subtle", + "zeroize", +] + +[[package]] +name = "semver" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1d7eb9ef2c18661902cc47e535f9bc51b78acd254da71d375c2f6720d9a40403" +dependencies = [ + "semver-parser", +] + +[[package]] +name = "semver" +version = "1.0.28" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8a7852d02fc848982e0c167ef163aaff9cd91dc640ba85e263cb1ce46fae51cd" + +[[package]] +name = "semver-parser" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "388a1df253eca08550bef6c72392cfe7c30914bf41df5269b68cbd6ff8f570a3" + +[[package]] +name = "sequential-storage" +version = "7.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "574e5a379bf43653079b34cb4cf32958404b5f42e0ed5b5adcdff02c2de04d4d" +dependencies = [ + "defmt 1.1.0", + "embedded-storage-async", + "postcard", + "serde", +] + +[[package]] +name = "serde" +version = "1.0.228" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9a8e94ea7f378bd32cbbd37198a4a91436180c5bb472411e48b5ec2e2124ae9e" +dependencies = [ + "serde_core", + "serde_derive", +] + +[[package]] +name = "serde-inline-default" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2bf03b7a5281cfd4013bc788d057b0f09fc634397d83bc8973c955bd4f32727a" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.117", +] + +[[package]] +name = "serde-untagged" +version = "0.1.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f9faf48a4a2d2693be24c6289dbe26552776eb7737074e6722891fadbe6c5058" +dependencies = [ + "erased-serde", + "serde", + "serde_core", + "typeid", +] + +[[package]] +name = "serde_core" +version = "1.0.228" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "41d385c7d4ca58e59fc732af25c3983b67ac852c1a25000afe1175de458b67ad" +dependencies = [ + "serde_derive", +] + +[[package]] +name = "serde_derive" +version = "1.0.228" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d540f220d3187173da220f885ab66608367b6574e925011a9353e4badda91d79" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.117", +] + +[[package]] +name = "serde_json" +version = "1.0.150" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e8014e44b4736ed0538adeecded0fce2a272f22dc9578a7eb6b2d9993c74cfb9" +dependencies = [ + "itoa", + "memchr", + "serde", + "serde_core", + "zmij", +] + +[[package]] +name = "serde_spanned" +version = "1.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6662b5879511e06e8999a8a235d848113e942c9124f211511b16466ee2995f26" +dependencies = [ + "serde_core", +] + +[[package]] +name = "sha2" +version = "0.10.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a7507d819769d01a365ab707794a4084392c824f54a7a6a7862f8c3d0892b283" +dependencies = [ + "cfg-if", + "cpufeatures", + "digest", +] + +[[package]] +name = "sha2-const-stable" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5f179d4e11094a893b82fff208f74d448a7512f99f5a0acbd5c679b705f83ed9" + +[[package]] +name = "sha3" +version = "0.10.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "77fd7028345d415a4034cf8777cd4f8ab1851274233b45f84e3d955502d93874" +dependencies = [ + "digest", + "keccak", +] + +[[package]] +name = "sharded-slab" +version = "0.1.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f40ca3c46823713e0d4209592e8d6e826aa57e928f09752619fc696c499637f6" +dependencies = [ + "lazy_static", +] + +[[package]] +name = "shlex" +version = "2.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f8fadd59c855ef2080decdef8ff161eb6661b86933c9d82e5ba29dc602a55aba" + +[[package]] +name = "signature" +version = "2.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "77549399552de45a898a580c1b41d445bf730df867cc44e6c0233bbc4b8329de" + +[[package]] +name = "siphasher" +version = "1.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8ee5873ec9cce0195efcb7a4e9507a04cd49aec9c83d0389df45b1ef7ba2e649" + +[[package]] +name = "slab" +version = "0.4.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0c790de23124f9ab44544d7ac05d60440adc586479ce501c1d6d7da3cd8c9cf5" + +[[package]] +name = "smallvec" +version = "1.15.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "67b1b7a3b5fe4f1376887184045fcf45c69e92af734b7aaddc05fb777b6fbd03" + +[[package]] +name = "smart-leds" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "66df34e571fa9993fa6f99131a374d58ca3d694b75f9baac93458fe0d6057bf0" +dependencies = [ + "smart-leds-trait", +] + +[[package]] +name = "smart-leds-trait" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a7f4441a131924d58da6b83a7ad765c460e64630cce504376c3a87a2558c487f" +dependencies = [ + "rgb", +] + +[[package]] +name = "spin" +version = "0.9.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6980e8d7511241f8acf4aebddbb1ff938df5eebe98691418c4468d0b72a96a67" +dependencies = [ + "lock_api", +] + +[[package]] +name = "ssmarshal" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f3e6ad23b128192ed337dfa4f1b8099ced0c2bf30d61e551b65fda5916dbb850" +dependencies = [ + "encode_unicode", + "serde", +] + +[[package]] +name = "stable_deref_trait" +version = "1.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6ce2be8dc25455e1f91df71bfa12ad37d7af1092ae736f3a6cd0e37bc7810596" + +[[package]] +name = "static_cell" +version = "2.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0530892bb4fa575ee0da4b86f86c667132a94b74bb72160f58ee5a4afec74c23" +dependencies = [ + "portable-atomic", +] + +[[package]] +name = "string_cache" +version = "0.8.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bf776ba3fa74f83bf4b63c3dcbbf82173db2632ed8452cb2d891d33f459de70f" +dependencies = [ + "new_debug_unreachable", + "parking_lot", + "phf_shared", + "precomputed-hash", +] + +[[package]] +name = "strsim" +version = "0.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f" + +[[package]] +name = "strum" +version = "0.28.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9628de9b8791db39ceda2b119bbe13134770b56c138ec1d3af810d045c04f9bd" +dependencies = [ + "strum_macros", +] + +[[package]] +name = "strum_macros" +version = "0.28.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ab85eea0270ee17587ed4156089e10b9e6880ee688791d45a905f5b1ca36f664" +dependencies = [ + "heck", + "proc-macro2", + "quote", + "syn 2.0.117", +] + +[[package]] +name = "subtle" +version = "2.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "13c2bddecc57b384dee18652358fb23172facb8a2c51ccc10d74c157bdea3292" + +[[package]] +name = "syn" +version = "1.0.109" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[package]] +name = "syn" +version = "2.0.117" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e665b8803e7b1d2a727f4023456bbbbe74da67099c585258af0ad9c5013b9b99" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[package]] +name = "term" +version = "1.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d8c27177b12a6399ffc08b98f76f7c9a1f4fe9fc967c784c5a071fa8d93cf7e1" +dependencies = [ + "windows-sys", +] + +[[package]] +name = "termcolor" +version = "1.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "06794f8f6c5c898b3275aebefa6b8a1cb24cd2c6c79397ab15774837a0bc5755" +dependencies = [ + "winapi-util", +] + +[[package]] +name = "thiserror" +version = "2.0.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4288b5bcbc7920c07a1149a35cf9590a2aa808e0bc1eafaade0b80947865fbc4" +dependencies = [ + "thiserror-impl", +] + +[[package]] +name = "thiserror-impl" +version = "2.0.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ebc4ee7f67670e9b64d05fa4253e753e016c6c95ff35b89b7941d6b856dec1d5" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.117", +] + +[[package]] +name = "thread_local" +version = "1.1.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f60246a4944f24f6e018aa17cdeffb7818b76356965d03b07d6a9886e8962185" +dependencies = [ + "cfg-if", +] + +[[package]] +name = "tiny-keccak" +version = "2.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2c9d3793400a45f954c52e73d068316d76b6f4e36977e3fcebb13a2721e80237" +dependencies = [ + "crunchy", +] + +[[package]] +name = "toml" +version = "0.9.12+spec-1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cf92845e79fc2e2def6a5d828f0801e29a2f8acc037becc5ab08595c7d5e9863" +dependencies = [ + "indexmap", + "serde_core", + "serde_spanned", + "toml_datetime 0.7.5+spec-1.1.0", + "toml_parser", + "toml_writer", + "winnow 0.7.15", +] + +[[package]] +name = "toml" +version = "1.1.2+spec-1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "81f3d15e84cbcd896376e6730314d59fb5a87f31e4b038454184435cd57defee" +dependencies = [ + "indexmap", + "serde_core", + "serde_spanned", + "toml_datetime 1.1.1+spec-1.1.0", + "toml_parser", + "toml_writer", + "winnow 1.0.3", +] + +[[package]] +name = "toml_datetime" +version = "0.7.5+spec-1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "92e1cfed4a3038bc5a127e35a2d360f145e1f4b971b551a2ba5fd7aedf7e1347" +dependencies = [ + "serde_core", +] + +[[package]] +name = "toml_datetime" +version = "1.1.1+spec-1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3165f65f62e28e0115a00b2ebdd37eb6f3b641855f9d636d3cd4103767159ad7" +dependencies = [ + "serde_core", +] + +[[package]] +name = "toml_parser" +version = "1.1.2+spec-1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a2abe9b86193656635d2411dc43050282ca48aa31c2451210f4202550afb7526" +dependencies = [ + "winnow 1.0.3", +] + +[[package]] +name = "toml_writer" +version = "1.1.1+spec-1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "756daf9b1013ebe47a8776667b466417e2d4c5679d441c26230efd9ef78692db" + +[[package]] +name = "tracing" +version = "0.1.44" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "63e71662fa4b2a2c3a26f570f037eb95bb1f85397f3cd8076caed2f026a6d100" +dependencies = [ + "pin-project-lite", + "tracing-attributes", + "tracing-core", +] + +[[package]] +name = "tracing-attributes" +version = "0.1.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7490cfa5ec963746568740651ac6781f701c9c5ea257c58e057f3ba8cf69e8da" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.117", +] + +[[package]] +name = "tracing-core" +version = "0.1.36" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "db97caf9d906fbde555dd62fa95ddba9eecfd14cb388e4f491a66d74cd5fb79a" +dependencies = [ + "once_cell", + "valuable", +] + +[[package]] +name = "tracing-log" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ee855f1f400bd0e5c02d150ae5de3840039a3f54b025156404e34c23c03f47c3" +dependencies = [ + "log", + "once_cell", + "tracing-core", +] + +[[package]] +name = "tracing-subscriber" +version = "0.3.23" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cb7f578e5945fb242538965c2d0b04418d38ec25c79d160cd279bf0731c8d319" +dependencies = [ + "matchers", + "nu-ansi-term", + "once_cell", + "regex-automata", + "sharded-slab", + "smallvec", + "thread_local", + "tracing", + "tracing-core", + "tracing-log", +] + +[[package]] +name = "trouble-host" +version = "0.6.0" +source = "git+https://github.com/haobogu/trouble?rev=690373fd1166d16225b875435dd0600c92570e7d#690373fd1166d16225b875435dd0600c92570e7d" +dependencies = [ + "aes", + "bt-hci", + "cmac", + "defmt 1.1.0", + "embassy-futures", + "embassy-sync", + "embassy-time", + "embedded-io 0.7.1", + "futures", + "heapless 0.9.3", + "p256", + "rand", + "rand_chacha", + "rand_core 0.6.4", + "serde", + "static_cell", + "trouble-host-macros", + "zerocopy", +] + +[[package]] +name = "trouble-host-macros" +version = "0.4.0" +source = "git+https://github.com/haobogu/trouble?rev=690373fd1166d16225b875435dd0600c92570e7d#690373fd1166d16225b875435dd0600c92570e7d" +dependencies = [ + "convert_case 0.8.0", + "darling 0.20.11", + "proc-macro2", + "quote", + "syn 2.0.117", + "uuid", +] + +[[package]] +name = "typeid" +version = "1.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bc7d623258602320d5c55d1bc22793b57daff0ec7efc270ea7d55ce1d5f5471c" + +[[package]] +name = "typenum" +version = "1.20.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b6f5e870be6c3b371b77fe0ee0bafb859fa4964b4404c27de1d380043c4dda20" + +[[package]] +name = "ucd-trie" +version = "0.1.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2896d95c02a80c6d6a5d6e953d479f5ddf2dfdb6a244441010e373ac0fb88971" + +[[package]] +name = "unicode-ident" +version = "1.0.24" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e6e4313cd5fcd3dad5cafa179702e2b244f760991f45397d14d4ebf38247da75" + +[[package]] +name = "unicode-segmentation" +version = "1.13.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c6f5d3c3b1bf09027a88a6bc961fc00497d651009560b5463668dc81b0fa87a8" + +[[package]] +name = "unicode-width" +version = "0.1.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7dd6e30e90baa6f72411720665d41d89b9a3d039dc45b8faea1ddd07f617f6af" + +[[package]] +name = "unicode-xid" +version = "0.2.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ebc1c04c71510c7f702b52b7c350734c9ff1295c464a03335b00bb84fc54f853" + +[[package]] +name = "usb-device" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "98816b1accafbb09085168b90f27e93d790b4bfa19d883466b5e53315b5f06a6" +dependencies = [ + "defmt 0.3.100", + "heapless 0.8.0", + "portable-atomic", +] + +[[package]] +name = "usbd-hid" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "68beab087e4971a2fe76f631478b0e91d39593f58efd2775026ce6dc07a7bac6" +dependencies = [ + "defmt 0.3.100", + "usb-device", + "usbd-hid-macros", +] + +[[package]] +name = "usbd-hid-descriptors" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b297f021719c4308d5d0c61b6c1e7c6b3ba383deba774b49aa5484f996bdb8f1" +dependencies = [ + "bitfield 0.14.0", +] + +[[package]] +name = "usbd-hid-macros" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "011a3219e0933f5b3ad7dc90d9a66541a967d084c98c067deed1cd608e557ed7" +dependencies = [ + "byteorder", + "hashbrown 0.13.2", + "log", + "proc-macro2", + "quote", + "serde", + "syn 2.0.117", + "usbd-hid-descriptors", +] + +[[package]] +name = "uuid" +version = "1.23.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d258b83ceec21034727ecee8c382cfa6c3e133699b0742c64571814fb420c9f7" +dependencies = [ + "js-sys", + "wasm-bindgen", +] + +[[package]] +name = "valuable" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ba73ea9cf16a25df0c8caa16c51acb937d5712a8429db78a3ee29d5dcacd3a65" + +[[package]] +name = "vcell" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "77439c1b53d2303b20d9459b1ade71a83c716e3f9c34f3228c00e6f185d6c002" + +[[package]] +name = "version_check" +version = "0.9.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b928f33d975fc6ad9f86c8f283853ad26bdd5b10b7f1542aa2fa15e2289105a" + +[[package]] +name = "void" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6a02e4885ed3bc0f2de90ea6dd45ebcbb66dacffe03547fadbb0eeae2770887d" + +[[package]] +name = "volatile-register" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "de437e2a6208b014ab52972a27e59b33fa2920d3e00fe05026167a1c509d19cc" +dependencies = [ + "vcell", +] + +[[package]] +name = "walkdir" +version = "2.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "29790946404f91d9c5d06f9874efddea1dc06c5efe94541a7d6863108e3a5e4b" +dependencies = [ + "same-file", + "winapi-util", +] + +[[package]] +name = "wasi" +version = "0.11.1+wasi-snapshot-preview1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ccf3ec651a847eb01de73ccad15eb7d99f80485de043efb2f370cd654f4ea44b" + +[[package]] +name = "wasm-bindgen" +version = "0.2.122" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3ed04576f974d2b2fba0f38c51dbc5518011e38c36bf1143164be765528fd409" +dependencies = [ + "cfg-if", + "once_cell", + "rustversion", + "wasm-bindgen-macro", + "wasm-bindgen-shared", +] + +[[package]] +name = "wasm-bindgen-macro" +version = "0.2.122" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "916151b09da36bd82f6615cbf3a419e2f0ba23a03c6160e8e92eb6bd4aa1dec6" +dependencies = [ + "quote", + "wasm-bindgen-macro-support", +] + +[[package]] +name = "wasm-bindgen-macro-support" +version = "0.2.122" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "299047362ccbfce148b67ab7e73349f77748e00c8296f9542adfad2ad82c5c5e" +dependencies = [ + "bumpalo", + "proc-macro2", + "quote", + "syn 2.0.117", + "wasm-bindgen-shared", +] + +[[package]] +name = "wasm-bindgen-shared" +version = "0.2.122" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9a929b2c61f11ba3e9bc35b50c1f25cb38e0e892c0c231ae2b8cf78d5dad4437" +dependencies = [ + "unicode-ident", +] + +[[package]] +name = "winapi-util" +version = "0.1.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c2a7b1c03c876122aa43f3020e6c3c3ee5c05081c9a00739faf7503aeba10d22" +dependencies = [ + "windows-sys", +] + +[[package]] +name = "windows-link" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f0805222e57f7521d6a62e36fa9163bc891acd422f971defe97d64e70d0a4fe5" + +[[package]] +name = "windows-result" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7781fa89eaf60850ac3d2da7af8e5242a5ea78d1a11c49bf2910bb5a73853eb5" +dependencies = [ + "windows-link", +] + +[[package]] +name = "windows-sys" +version = "0.61.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ae137229bcbd6cdf0f7b80a31df61766145077ddf49416a728b02cb3921ff3fc" +dependencies = [ + "windows-link", +] + +[[package]] +name = "winnow" +version = "0.7.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "df79d97927682d2fd8adb29682d1140b343be4ac0f08fd68b7765d9c059d3945" + +[[package]] +name = "winnow" +version = "1.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0592e1c9d151f854e6fd382574c3a0855250e1d9b2f99d9281c6e6391af352f1" +dependencies = [ + "memchr", +] + +[[package]] +name = "xz2" +version = "0.1.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "388c44dc09d76f1536602ead6d325eb532f5c122f17782bd57fb47baeeb767e2" +dependencies = [ + "lzma-sys", +] + +[[package]] +name = "yaml-rust2" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "631a50d867fafb7093e709d75aaee9e0e0d5deb934021fcea25ac2fe09edc51e" +dependencies = [ + "arraydeque", + "encoding_rs", + "hashlink", +] + +[[package]] +name = "zerocopy" +version = "0.8.50" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3b065d4f0e55f82fae73202e189638116a87c55ab6b8e6c2721e13dd9d854ad1" +dependencies = [ + "zerocopy-derive", +] + +[[package]] +name = "zerocopy-derive" +version = "0.8.50" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b631b19d36a892ab55420c92dbc83ccd79274f25be714855d3074aa71cab639" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.117", +] + +[[package]] +name = "zeroize" +version = "1.8.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b97154e67e32c85465826e8bcc1c59429aaaf107c1e4a9e53c8d8ccd5eff88d0" + +[[package]] +name = "zmij" +version = "1.0.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b8848ee67ecc8aedbaf3e4122217aff892639231befc6a1b58d29fff4c2cabaa" diff --git a/examples/use_rust/rp2040_embassy_boot/Cargo.toml b/examples/use_rust/rp2040_embassy_boot/Cargo.toml new file mode 100644 index 000000000..88132c6a7 --- /dev/null +++ b/examples/use_rust/rp2040_embassy_boot/Cargo.toml @@ -0,0 +1,58 @@ +[package] +name = "rmk-rp2040-embassy-boot" +version = "0.2.0" +authors = ["Haobo Gu "] +description = "Keyboard firmware written in Rust" +homepage = "https://github.com/haobogu/rmk" +repository = "https://github.com/haobogu/rmk" +readme = "../../README.md" +edition = "2024" +license = "MIT OR Apache-2.0" + +[dependencies] +rmk = { path = "../../../rmk", features = [ + "dfu_rp", + # "dfu_lock" +] } +embassy-time = { version = "0.5", features = ["defmt"] } +embassy-rp = { version = "0.10", features = [ + "rp2040", + "defmt", + "time-driver", + "critical-section-impl", +] } +embassy-executor = { version = "0.10", features = [ + "defmt", + "platform-cortex-m", + "executor-thread", +] } +cortex-m-rt = { version = "0.7.5", features = ["set-vtor"] } # <-- set-vtor necessary for embassy-boot +portable-atomic = { version = "1.11", features = ["critical-section"] } +defmt = "1.0" +defmt-rtt = "1.0" +panic-probe = { version = "1.0", features = ["print-defmt"] } + +[build-dependencies] +xz2 = "0.1.7" +json = "0.12" +const-gen = "1.6" + +[[bin]] +name = "rmk-rp2040-embassy-boot" +test = false +bench = false + +[profile.dev] +codegen-units = 1 +debug = true +opt-level = 1 +overflow-checks = true +lto = false +panic = 'unwind' + +[profile.release] +codegen-units = 1 +debug = true +opt-level = "z" +overflow-checks = false +lto = "fat" diff --git a/examples/use_rust/rp2040_embassy_boot/build.rs b/examples/use_rust/rp2040_embassy_boot/build.rs new file mode 100644 index 000000000..5268bfea6 --- /dev/null +++ b/examples/use_rust/rp2040_embassy_boot/build.rs @@ -0,0 +1,53 @@ +use std::fs::File; +use std::io::{Read, Write}; +use std::path::{Path, PathBuf}; +use std::{env, fs}; + +use const_gen::*; +use xz2::read::XzEncoder; + +fn main() { + println!("cargo:rerun-if-changed=vial.json"); + generate_vial_config(); + + let out = &PathBuf::from(env::var_os("OUT_DIR").unwrap()); + File::create(out.join("memory.x")) + .unwrap() + .write_all(include_bytes!("memory.x")) + .unwrap(); + println!("cargo:rustc-link-search={}", out.display()); + + println!("cargo:rerun-if-changed=memory.x"); + + println!("cargo:rustc-link-arg=--nmagic"); + println!("cargo:rustc-link-arg=-Tlink.x"); + println!("cargo:rustc-link-arg=-Tdefmt.x"); +} + +fn generate_vial_config() { + let out_file = Path::new(&env::var_os("OUT_DIR").unwrap()).join("config_generated.rs"); + + let p = Path::new("vial.json"); + let mut content = String::new(); + match File::open(p) { + Ok(mut file) => { + file.read_to_string(&mut content).expect("Cannot read vial.json"); + } + Err(e) => println!("Cannot find vial.json {:?}: {}", p, e), + }; + + let vial_cfg = json::stringify(json::parse(&content).unwrap()); + let mut keyboard_def_compressed: Vec = Vec::new(); + XzEncoder::new(vial_cfg.as_bytes(), 6) + .read_to_end(&mut keyboard_def_compressed) + .unwrap(); + + let keyboard_id: Vec = vec![0xB9, 0xBC, 0x09, 0xB2, 0x9D, 0x37, 0x4C, 0xEA]; + let const_declarations = [ + const_declaration!(pub VIAL_KEYBOARD_DEF = keyboard_def_compressed), + const_declaration!(pub VIAL_KEYBOARD_ID = keyboard_id), + ] + .map(|s| "#[allow(clippy::redundant_static_lifetimes)]\n".to_owned() + s.as_str()) + .join("\n"); + fs::write(out_file, const_declarations).unwrap(); +} diff --git a/examples/use_rust/rp2040_embassy_boot/memory.x b/examples/use_rust/rp2040_embassy_boot/memory.x new file mode 100644 index 000000000..3e94ea4ba --- /dev/null +++ b/examples/use_rust/rp2040_embassy_boot/memory.x @@ -0,0 +1,8 @@ +/* +This memory.x is for the RP2040 with 2MB flash. +For different flash sizes see docs. +*/ +MEMORY { + FLASH : ORIGIN = 0x10007000, LENGTH = 944K + RAM : ORIGIN = 0x20000000, LENGTH = 256K +} diff --git a/examples/use_rust/rp2040_embassy_boot/src/keymap.rs b/examples/use_rust/rp2040_embassy_boot/src/keymap.rs new file mode 100644 index 000000000..0ee3d0839 --- /dev/null +++ b/examples/use_rust/rp2040_embassy_boot/src/keymap.rs @@ -0,0 +1,23 @@ +use rmk::types::action::KeyAction; +use rmk::{a, k, layer, mo}; +pub(crate) const COL: usize = 3; +pub(crate) const ROW: usize = 4; +pub(crate) const NUM_LAYER: usize = 2; + +#[rustfmt::skip] +pub const fn get_default_keymap() -> [[[KeyAction; COL]; ROW]; NUM_LAYER] { + [ + layer!([ + [k!(AudioVolUp), k!(B), k!(AudioVolDown)], + [k!(Kp4), k!(LShift), k!(Kp6)], + [mo!(1), k!(Kp2), k!(Kp3)], + [mo!(1), a!(No), k!(Kp0)] + ]), + layer!([ + [k!(Kp7), k!(Kp8), k!(Kp9)], + [k!(Kp4), k!(LCtrl), k!(Kp6)], + [mo!(1), k!(Kp2), k!(Kp3)], + [mo!(1), a!(No), k!(Kp0)] + ]), + ] +} diff --git a/examples/use_rust/rp2040_embassy_boot/src/macros.rs b/examples/use_rust/rp2040_embassy_boot/src/macros.rs new file mode 100644 index 000000000..fb2652993 --- /dev/null +++ b/examples/use_rust/rp2040_embassy_boot/src/macros.rs @@ -0,0 +1,12 @@ +macro_rules! config_matrix_pins_rp { + (peripherals: $p:ident, input: [$($in_pin:ident), *], output: [$($out_pin:ident), +]) => { + { + let mut output_pins = [$(Output::new($p.$out_pin, embassy_rp::gpio::Level::Low)), +]; + let input_pins = [$(Input::new($p.$in_pin, embassy_rp::gpio::Pull::Down)), +]; + output_pins.iter_mut().for_each(|p| { + p.set_low(); + }); + (input_pins, output_pins) + } + }; +} diff --git a/examples/use_rust/rp2040_embassy_boot/src/main.rs b/examples/use_rust/rp2040_embassy_boot/src/main.rs new file mode 100644 index 000000000..43456ec5a --- /dev/null +++ b/examples/use_rust/rp2040_embassy_boot/src/main.rs @@ -0,0 +1,166 @@ +#![no_main] +#![no_std] + +#[macro_use] +mod keymap; +#[macro_use] +mod macros; +mod vial; + +use defmt::info; +use defmt_rtt as _; +use embassy_executor::Spawner; +use embassy_rp::gpio::{Input, Level, Output}; +use embassy_rp::peripherals::USB; +use embassy_rp::usb::{Driver, InterruptHandler}; +use embassy_rp::{bind_interrupts, dma}; +use keymap::{COL, ROW}; +use panic_probe as _; +use rmk::config::{BehaviorConfig, DeviceConfig, PositionalConfig, RmkConfig, StorageConfig, VialConfig}; +use rmk::debounce::default_debouncer::DefaultDebouncer; +use rmk::host::HostService; +use rmk::keyboard::Keyboard; +use rmk::matrix::Matrix; +use rmk::processor::builtin::wpm::WpmProcessor; +use rmk::storage::async_flash_wrapper; +use rmk::usb::UsbTransport; +use rmk::watchdog::Rp2040Watchdog; +use rmk::{KeymapData, initialize_keymap_and_storage, run_all}; +use vial::{VIAL_KEYBOARD_DEF, VIAL_KEYBOARD_ID}; + +bind_interrupts!(struct Irqs { + USBCTRL_IRQ => InterruptHandler; + DMA_IRQ_0 => dma::InterruptHandler; +}); + +#[embassy_executor::main] +async fn main(_spawner: Spawner) { + info!("RMK start!"); + let p = embassy_rp::init(Default::default()); + + let driver = Driver::new(p.USB, Irqs); + + let (row_pins, col_pins) = + config_matrix_pins_rp!(peripherals: p, input: [PIN_6, PIN_7, PIN_8, PIN_9], output: [PIN_19, PIN_20, PIN_21]); + + // Flash layout using the bootymcbootface formula: + // state at 0x6000 (4K), active from 0x7000 (size: (flash_size - 28K (= BOOT2 size + embassy-boot + embassy-boot state) - STORAGE_SIZE (= 128K) - page_size (= 4K)) / 2), + // dfu follows active (active_size + page_size (= 4K)) + // + // All offsets (DFU_OFFSET, DFU_SIZE, STORAGE_OFFSET, etc.) are derived + // automatically from FLASH_SIZE below — change only that constant when using + // bootymcbootface. + // + // ⚠ You can define your own FLASH_SIZE and addresses, but then you must build and + // flash a custom embassy-boot bootloader with a matching memory.x! + const FLASH_SIZE: u32 = 2 * 1024 * 1024; // 2 MB (default) + // const FLASH_SIZE: u32 = 4 * 1024 * 1024; // 4 MB + // const FLASH_SIZE: u32 = 8 * 1024 * 1024; // 8 MB + // const FLASH_SIZE: u32 = 16 * 1024 * 1024; // 16 MB + const PAGE_SIZE: u32 = 4 * 1024; + const STORAGE_SIZE: u32 = 128 * 1024; // 32 sectors × 4K after ACTIVE+DFU + const STATE_OFFSET: u32 = 0x6000; + const STATE_SIZE: u32 = 0x1000; + const ACTIVE_OFFSET: u32 = 0x7000; // after 28K bootloader + state + let remaining: u32 = FLASH_SIZE + - 28 * 1024 // size of boot 2 + embassy-boot + embassy-boot state + - STORAGE_SIZE; + let active_size: u32 = (remaining - PAGE_SIZE) / 2; // DFU = ACTIVE + 1 page (embassy-boot requirement) + let dfu_size: u32 = active_size + PAGE_SIZE; // embassy-boot needs that extra page for swap info + let dfu_offset: u32 = ACTIVE_OFFSET + active_size; // dfu after active + let storage_offset: u32 = dfu_offset + dfu_size; // storage after active + dfu + let storage_size: u32 = STORAGE_SIZE; + assert!(storage_offset + storage_size == FLASH_SIZE); // sanity check that we fit everything in flash + + info!( + "Flash layout: state @ 0x{:04X} ({}K), active @ 0x{:04X} ({}K), dfu @ 0x{:04X} ({}K), storage @ 0x{:04X} ({}K)", + STATE_OFFSET, + STATE_SIZE / 1024, + ACTIVE_OFFSET, + active_size / 1024, + dfu_offset, + dfu_size / 1024, + storage_offset, + storage_size / 1024 + ); + + let flash = async_flash_wrapper(rmk::dfu::init_flash( + p.FLASH, + storage_offset, + storage_size, + STATE_OFFSET, + STATE_SIZE, + dfu_offset, + dfu_size, + )); + + rmk::dfu::set_led(Some(Output::new(p.PIN_25, Level::Low))); + + let keyboard_device_config = DeviceConfig { + vid: 0x4c4b, + pid: 0x4643, + manufacturer: "Haobo", + product_name: "RMK Keyboard RP2040 embassy-boot use_rust example", + serial_number: "vial:f64c2b3c:000001", + }; + + let vial_config = VialConfig::new(VIAL_KEYBOARD_ID, VIAL_KEYBOARD_DEF, &[(0, 0), (1, 1)]); + + let rmk_config = RmkConfig { + device_config: keyboard_device_config, + vial_config, + ..Default::default() + }; + + let mut keymap_data = KeymapData::new(keymap::get_default_keymap()); + let storage_config = StorageConfig { + num_sectors: 32, + start_addr: 0, + clear_storage: false, + clear_layout: false, + }; + let mut behavior_config = BehaviorConfig::default(); + let per_key_config = PositionalConfig::default(); + let (keymap, mut storage) = initialize_keymap_and_storage( + &mut keymap_data, + flash, + &storage_config, + &mut behavior_config, + &per_key_config, + ) + .await; + + rmk::dfu::mark_booted(); + + // Optional DFU lock — requires the `dfu_lock` Cargo feature. + // Specify the physical keys to press simultaneously to unlock DFU firmware + // download. The keys are (row, col) pairs matching your matrix layout. + // The lock state is checked by the DFU USB handler on each download start. + // To use, create a `DfuLock` and poll it periodically: + // + // let unlock_keys: &[(u8, u8)] = &[(0, 0), (1, 1)]; + // let mut dfu_lock = ::rmk::dfu::DfuLock::new(unlock_keys, &keymap); + // add dfu_lock to run_all!() + + let debouncer = DefaultDebouncer::new(); + let mut matrix = Matrix::<_, _, _, ROW, COL, true>::new(row_pins, col_pins, debouncer); + let mut keyboard = Keyboard::new(&keymap); + let host_ctx = rmk::host::KeyboardContext::new(&keymap); + let mut host_service = HostService::new(&host_ctx, &rmk_config); + + let mut usb_transport = UsbTransport::new(driver, rmk_config.device_config); + let mut wpm_processor = WpmProcessor::new(); + + let mut watchdog_runner = Rp2040Watchdog::default_runner(embassy_rp::watchdog::Watchdog::new(p.WATCHDOG)); + + run_all!( + matrix, + storage, + usb_transport, + wpm_processor, + keyboard, + host_service, + watchdog_runner // , dfu_lock + ) + .await; +} diff --git a/examples/use_rust/rp2040_embassy_boot/src/vial.rs b/examples/use_rust/rp2040_embassy_boot/src/vial.rs new file mode 100644 index 000000000..33e0a4ad0 --- /dev/null +++ b/examples/use_rust/rp2040_embassy_boot/src/vial.rs @@ -0,0 +1 @@ +include!(concat!(env!("OUT_DIR"), "/config_generated.rs")); diff --git a/examples/use_rust/rp2040_embassy_boot/vial.json b/examples/use_rust/rp2040_embassy_boot/vial.json new file mode 100644 index 000000000..eba77b1c5 --- /dev/null +++ b/examples/use_rust/rp2040_embassy_boot/vial.json @@ -0,0 +1,37 @@ +{ + "name": "RMK Keyboard", + "vendorId": "0x4C4B", + "productId": "0x4643", + "lighting": "none", + "matrix": { + "rows": 4, + "cols": 3 + }, + "layouts": { + "keymap": [ + [ + "0,0", + "0,1", + "0,2" + ], + [ + "1,0", + "1,1", + "1,2" + ], + [ + "2,0", + "2,1", + "2,2" + ], + [ + { + "y": -2, + "x": 4 + }, + "3,0", + "3,2" + ] + ] + } +} \ No newline at end of file diff --git a/rmk-config/src/default_config/pi_pico_w.toml b/rmk-config/src/default_config/pi_pico_w.toml index 94299621d..300aa825e 100644 --- a/rmk-config/src/default_config/pi_pico_w.toml +++ b/rmk-config/src/default_config/pi_pico_w.toml @@ -7,4 +7,7 @@ enabled = true [storage] enabled = true start_addr = 0x100000 -num_sectors = 32 \ No newline at end of file +num_sectors = 32 + +[dfu] +flash_size = 2097152 \ No newline at end of file diff --git a/rmk-config/src/default_config/rp2040.toml b/rmk-config/src/default_config/rp2040.toml index 504264c10..e0b731315 100644 --- a/rmk-config/src/default_config/rp2040.toml +++ b/rmk-config/src/default_config/rp2040.toml @@ -4,4 +4,7 @@ usb_enable = true [storage] enabled = true start_addr = 0x100000 -num_sectors = 32 \ No newline at end of file +num_sectors = 32 + +[dfu] +flash_size = 2097152 \ No newline at end of file diff --git a/rmk-config/src/dfu.rs b/rmk-config/src/dfu.rs new file mode 100644 index 000000000..cd80ecd35 --- /dev/null +++ b/rmk-config/src/dfu.rs @@ -0,0 +1,7 @@ +use crate::DfuTomlConfig; + +impl crate::KeyboardTomlConfig { + pub(crate) fn get_dfu_config(&self) -> Option { + self.dfu.clone() + } +} diff --git a/rmk-config/src/lib.rs b/rmk-config/src/lib.rs index 61506ab61..1ee2e99bd 100644 --- a/rmk-config/src/lib.rs +++ b/rmk-config/src/lib.rs @@ -15,6 +15,7 @@ pub mod resolved; pub mod usb_interrupt_map; pub(crate) mod behavior; pub(crate) mod board; +pub(crate) mod dfu; pub(crate) mod display; pub(crate) mod host; pub(crate) mod keycode_alias; @@ -63,6 +64,8 @@ pub struct KeyboardTomlConfig { light: Option, /// Storage config storage: Option, + /// DFU partition config (embassy-boot) + dfu: Option, /// Ble config pub(crate) ble: Option, /// Chip-specific configs (e.g., [chip.nrf52840]) @@ -87,6 +90,10 @@ pub struct KeyboardTomlConfig { /// build.rs also loads event defaults via new_from_toml_path_with_event_defaults() #[serde(default)] pub(crate) event: EventConfig, + /// Whether the user explicitly set a [dfu] section in keyboard.toml. + /// Populated during two-pass parsing in new_from_toml_path(). + #[serde(skip)] + pub(crate) dfu_user_set: bool, } impl KeyboardTomlConfig { @@ -114,6 +121,7 @@ impl KeyboardTomlConfig { /// and should not require `[keyboard.board]`/`[keyboard.chip]`. pub fn new_from_toml_path_with_event_defaults>(config_toml_path: P) -> Self { let mut config = Self::parse_from_toml_path(config_toml_path, None); + config.dfu_user_set = config.dfu.is_some(); config.auto_calculate_parameters(); config } @@ -134,6 +142,10 @@ impl KeyboardTomlConfig { // 3. User config (highest priority) let mut config = Self::parse_from_toml_path(path, Some(default_config_str)); + // Track whether the user explicitly set [dfu] in their keyboard.toml + // (as opposed to the value coming only from chip defaults). + config.dfu_user_set = user_config.dfu.is_some(); + config.auto_calculate_parameters(); config @@ -481,6 +493,34 @@ pub(crate) struct StorageConfig { pub clear_layout: Option, } +/// Config for DFU partition layout (embassy-boot). +/// +/// These values must match the bootloader's `memory.x` / linker script. +#[derive(Clone, Debug, Default, Deserialize)] +#[serde(deny_unknown_fields)] +pub(crate) struct DfuTomlConfig { + /// Offset of the boot state partition + pub state_offset: Option, + /// Size of the boot state partition + pub state_size: Option, + /// Offset of the DFU download partition + pub dfu_offset: Option, + /// Size of the DFU download partition + pub dfu_size: Option, + /// Flash page size in bytes (e.g. 4096 for RP2040). + /// Used with `flash_size` to auto-calculate partition addresses. + pub page_size: Option, + /// Total flash size in bytes. When set, DFU partition addresses are + /// calculated automatically using the bootymcbootface formula. + /// Defaults to 2 MB (2097152) when omitted. + pub flash_size: Option, + /// Optional DFU activity LED pin, e.g. `"PIN_16"`. When set, the LED + /// is lit while a DFU download is in progress. + pub led: Option, + /// Unlock keys for DFU lock (optional) + pub unlock_keys: Option>, +} + #[derive(Clone, Default, Debug, Deserialize)] #[serde(deny_unknown_fields)] pub struct BleConfig { diff --git a/rmk-config/src/resolved/hardware.rs b/rmk-config/src/resolved/hardware.rs index 54573d132..e833ac86d 100644 --- a/rmk-config/src/resolved/hardware.rs +++ b/rmk-config/src/resolved/hardware.rs @@ -22,6 +22,17 @@ pub struct Storage { pub clear_layout: bool, } +/// Resolved DFU partition config +pub struct DfuConfig { + pub state_offset: u32, + pub state_size: u32, + pub dfu_offset: u32, + pub dfu_size: u32, + pub page_size: u32, + pub led: Option, + pub unlock_keys: Vec<[u8; 2]>, +} + /// Complete hardware configuration for init code generation. pub struct Hardware { pub chip: ChipModel, @@ -29,6 +40,7 @@ pub struct Hardware { pub communication: CommunicationConfig, pub board: BoardConfig, pub storage: Option, + pub dfu: Option, pub light: LightConfig, pub display: Option, pub output: Vec, @@ -53,6 +65,48 @@ impl crate::KeyboardTomlConfig { } else { None }; + let dfu = self.get_dfu_config().map(|d| { + let has_manual_overrides = self.dfu_user_set + && (d.state_offset.is_some() + || d.state_size.is_some() + || d.dfu_offset.is_some() + || d.dfu_size.is_some()); + + if has_manual_overrides { + // User manually set [dfu] values → use directly + DfuConfig { + state_offset: d.state_offset.unwrap_or(0x6000), + state_size: d.state_size.unwrap_or(0x1000), + dfu_offset: d.dfu_offset.unwrap_or(0x87000), + dfu_size: d.dfu_size.unwrap_or(516 * 1024), + page_size: d.page_size.unwrap_or(4096), + led: d.led.clone().map(|pin| PinConfig { pin, low_active: false }), + unlock_keys: d.unlock_keys.clone().unwrap_or_default(), + } + } else { + // Auto-calculate: use ALL remaining flash for ACTIVE+DFU+storage + // layout: [28K bootloader+state][ACTIVE][DFU(ACTIVE+1page)][storage] + let flash_size = d.flash_size.unwrap_or(2 * 1024 * 1024); + let page_size = d.page_size.unwrap_or(4096); + let bootloader_state_end = 0x7000u32; // 28K + let storage_size = if storage_toml.enabled { + storage_toml.num_sectors.unwrap_or(2) as u32 * page_size + } else { + 0 + }; + let remaining = flash_size - bootloader_state_end - storage_size; + let active_size = (remaining - page_size) / 2; + DfuConfig { + state_offset: 0x6000, + state_size: 0x1000, + dfu_offset: bootloader_state_end + active_size, + dfu_size: active_size + page_size, + page_size, + led: d.led.clone().map(|pin| PinConfig { pin, low_active: false }), + unlock_keys: d.unlock_keys.clone().unwrap_or_default(), + } + } + }); let light = self.get_light_config(); let display = self.get_display_config(); let output = self.get_output_config()?; @@ -63,6 +117,7 @@ impl crate::KeyboardTomlConfig { communication, board, storage, + dfu, light, display, output, diff --git a/rmk-macro/Cargo.toml b/rmk-macro/Cargo.toml index 4cbbbd405..c1c424993 100644 --- a/rmk-macro/Cargo.toml +++ b/rmk-macro/Cargo.toml @@ -22,6 +22,7 @@ strum = { version = "0.28", default-features = false, features = ["derive"] } [features] ## Enable hardware watchdog code generation watchdog = [] +dfu_rp = [] [lib] proc-macro = true diff --git a/rmk-macro/src/codegen/chip/flash.rs b/rmk-macro/src/codegen/chip/flash.rs index 9964d6afb..cb12c2980 100644 --- a/rmk-macro/src/codegen/chip/flash.rs +++ b/rmk-macro/src/codegen/chip/flash.rs @@ -6,6 +6,11 @@ use quote::quote; use rmk_config::resolved::Hardware; use rmk_config::resolved::hardware::ChipSeries; +#[cfg(feature = "dfu_rp")] +use super::gpio::convert_gpio_str_to_output_pin; +#[cfg(feature = "dfu_rp")] +use rmk_config::resolved::hardware::DfuConfig; + pub(crate) fn expand_flash_init(hardware: &Hardware) -> TokenStream2 { if hardware.storage.is_none() { // This config actually does nothing if storage is disabled @@ -16,13 +21,21 @@ pub(crate) fn expand_flash_init(hardware: &Hardware) -> TokenStream2 { } let storage = hardware.storage.as_ref().unwrap(); let num_sectors = storage.num_sectors; - let start_addr = storage.start_addr; + let _start_addr = storage.start_addr; let clear_storage = storage.clear_storage; let clear_layout = storage.clear_layout; + + // With dfu_rp, the flash is already a partition that starts at the + // storage offset, so the relative offset must be 0. + #[cfg(feature = "dfu_rp")] + let storage_start_addr = 0usize; + #[cfg(not(feature = "dfu_rp"))] + let storage_start_addr = _start_addr; + let mut flash_init = quote! { let storage_config = ::rmk::config::StorageConfig { num_sectors: #num_sectors, - start_addr: #start_addr, + start_addr: #storage_start_addr, clear_storage: #clear_storage, clear_layout: #clear_layout }; @@ -39,16 +52,58 @@ pub(crate) fn expand_flash_init(hardware: &Hardware) -> TokenStream2 { let flash = ::nrf_mpsl::Flash::take(mpsl, p.NVMC); } } - ChipSeries::Rp2040 => { + ChipSeries::Rp2040 => { + #[cfg(not(feature = "dfu_rp"))] + { quote! { const FLASH_SIZE: usize = 2 * 1024 * 1024; let flash = ::embassy_rp::flash::Flash::<_, ::embassy_rp::flash::Async, FLASH_SIZE>::new( - p.FLASH, - p.DMA_CH1, - Irqs, + p.FLASH, p.DMA_CH1, Irqs, + ); + } + } + #[cfg(feature = "dfu_rp")] + { + let dfu = hardware.dfu.as_ref().expect( + "[dfu] section is required in keyboard.toml (or chip default) when dfu_rp is enabled" + ); + let storage_num_sectors = hardware.storage.as_ref().map(|s| s.num_sectors).unwrap_or(32) as u32; + let erase_size = 4096u32; + let storage_offset = dfu.dfu_offset + dfu.dfu_size; + let storage_size = storage_num_sectors * erase_size; + let state_offset = dfu.state_offset; + let state_size = dfu.state_size; + let dfu_offset = dfu.dfu_offset; + let dfu_size = dfu.dfu_size; + let dfu_led = match &dfu.led { + Some(c) if c.pin == "none" => None, + Some(c) => Some(convert_gpio_str_to_output_pin(&hardware.chip, c.pin.clone(), false)), + None => Some(convert_gpio_str_to_output_pin(&hardware.chip, "PIN_25".to_string(), false)), + }; + let dfu_led_init = match dfu_led { + Some(pin) => quote! { + ::rmk::dfu::set_led(Some(#pin)); + }, + None => quote! {}, + }; + let dfu_unlock_keys = expand_dfu_unlock_keys(dfu); + quote! { + #dfu_unlock_keys + let flash = ::rmk::storage::async_flash_wrapper( + ::rmk::dfu::init_flash( + p.FLASH, + #storage_offset, + #storage_size, + #state_offset, + #state_size, + #dfu_offset, + #dfu_size, + ) ); + #dfu_led_init } } + } ChipSeries::Esp32 => quote! { let flash = ::rmk::storage::async_flash_wrapper(::esp_storage::FlashStorage::new(p.FLASH)); }, @@ -57,3 +112,23 @@ pub(crate) fn expand_flash_init(hardware: &Hardware) -> TokenStream2 { flash_init } + +/// Generate the `DFU_UNLOCK_KEYS` constant from the resolved DFU config. +#[cfg(feature = "dfu_rp")] +fn expand_dfu_unlock_keys(dfu: &DfuConfig) -> TokenStream2 { + if dfu.unlock_keys.is_empty() { + return quote! {}; + } + let keys_expr = dfu + .unlock_keys + .iter() + .map(|key| { + let row = key[0]; + let col = key[1]; + quote! { (#row, #col) } + }) + .collect::>(); + quote! { + const DFU_UNLOCK_KEYS: &[(u8, u8)] = &[#(#keys_expr), *]; + } +} diff --git a/rmk-macro/src/codegen/orchestrator.rs b/rmk-macro/src/codegen/orchestrator.rs index 82223e158..79469ff03 100644 --- a/rmk-macro/src/codegen/orchestrator.rs +++ b/rmk-macro/src/codegen/orchestrator.rs @@ -233,6 +233,23 @@ fn expand_main( let (registered_processor_initializers, mut registered_processors) = expand_registered_processor_init(hardware, &item_mod); + // Declare dfu_lock (if enabled) so it can be pushed as a Runnable task. + // Check the feature at macro-expansion time so we never emit `#[cfg]` + // into the user's crate (avoids "unexpected cfg condition" warnings). + let dfu_lock_enabled = is_feature_enabled(rmk_features, "dfu_lock"); + let dfu_lock_init = if let Some(ref dfu) = hardware.dfu { + if dfu_lock_enabled && !dfu.unlock_keys.is_empty() { + registered_processors.push(quote! { dfu_lock.run() }); + quote! { + let mut dfu_lock = ::rmk::dfu::DfuLock::new(&DFU_UNLOCK_KEYS, &keymap); + } + } else { + quote! {} + } + } else { + quote! {} + }; + // Display configuration — for unibody use top-level, for split use central's config let display_config = match &hardware.board { BoardConfig::UniBody(_) => hardware.display.as_ref(), @@ -367,6 +384,9 @@ fn expand_main( // Initialize watchdog #watchdog_init + // Initialize dfu lock + #dfu_lock_init + // Start #run_rmk } @@ -413,6 +433,11 @@ pub(crate) fn expand_keymap_and_storage(hardware: &Hardware, layout: &Layout) -> }; if hardware.storage.is_some() { + #[cfg(feature = "dfu_rp")] + let mark = quote! { ::rmk::dfu::mark_booted(); }; + #[cfg(not(feature = "dfu_rp"))] + let mark = quote! {}; + quote! { #initialize_positional_config #keymap_data_init @@ -423,6 +448,7 @@ pub(crate) fn expand_keymap_and_storage(hardware: &Hardware, layout: &Layout) -> &mut behavior_config, &per_key_config, ).await; + #mark } } else { quote! { diff --git a/rmk/Cargo.toml b/rmk/Cargo.toml index ad6718c39..00c7d25ec 100644 --- a/rmk/Cargo.toml +++ b/rmk/Cargo.toml @@ -78,6 +78,7 @@ embassy-rp = { version = "0.10", optional = true } embassy-hal-internal = { version = "0.5.0", optional = true } pio = { version = "0.3.0", optional = true } fixed = { version = "1.28.0", optional = true } +embassy-boot-rp = { version = "0.10.0", optional = true } # ESP32 dependencies esp-hal = { version = "1.1", optional = true } @@ -85,6 +86,9 @@ esp-hal = { version = "1.1", optional = true } # Document feature document-features = "0.2" +# for DFU firmware update +embassy-usb-dfu = { version = "0.3.0", optional = true, features = ["cortex-m", "dfu"] } + [dev-dependencies] # A hack for enabling 'std' feature in testing, ref: https://github.com/rust-lang/cargo/issues/2911 rmk = { path = ".", default-features = false, features = ["std", "log"] } @@ -118,6 +122,9 @@ vial = ["host"] ## Enable vial lock feature vial_lock = ["vial", "host_security"] +## Enable DFU lock feature — physical key unlock for DFU firmware download +dfu_lock = ["dfu_rp", "host_security"] + ## Enable physical key unlock and matrix state tracking (shared between vial_lock and rmk_protocol) host_security = [] @@ -217,6 +224,11 @@ adafruit_bl = ["_nrf_ble"] ## Enable feature if you're using the ZSA Voyager ignition DFU bootloader zsa_voyager_bl = [] +## Enable DFU firmware update support (USB DFU interface) +dfu = ["dep:embassy-usb-dfu", "dep:embassy-embedded-hal"] +## Enable RP2040-specific DFU with embassy-boot-rp (implies `dfu` and `rp2040`) +dfu_rp = ["dfu", "dep:embassy-boot-rp", "rp2040", "rmk-macro/dfu_rp"] + ## Enable Plover HID stenography support: adds the steno HID descriptor, ## the steno USB writer endpoint, and the `Action::Steno` variant. steno = ["rmk-types/steno"] diff --git a/rmk/src/dfu.rs b/rmk/src/dfu.rs new file mode 100644 index 000000000..e93a03de4 --- /dev/null +++ b/rmk/src/dfu.rs @@ -0,0 +1,457 @@ +use core::cell::RefCell; +#[cfg(feature = "dfu_lock")] +use core::sync::atomic::AtomicBool; +use core::sync::atomic::{AtomicPtr, Ordering}; + +use embassy_sync::blocking_mutex::Mutex; +#[cfg(feature = "dfu_lock")] +use embassy_sync::blocking_mutex::raw::CriticalSectionRawMutex; +use embassy_sync::blocking_mutex::raw::NoopRawMutex; +#[cfg(feature = "dfu_lock")] +use embassy_sync::signal::Signal; +use embassy_usb::control::{InResponse, OutResponse, Request}; +use embassy_usb::driver::Driver; +use embassy_usb::types::StringIndex; +use embassy_usb::{Builder, Handler}; +use static_cell::StaticCell; + +#[cfg(feature = "dfu_lock")] +use crate::core_traits::Runnable; + +struct DfuStringProvider { + string_idx: StringIndex, + string_val: &'static str, +} + +impl Handler for DfuStringProvider { + fn control_out(&mut self, _req: Request, _data: &[u8]) -> Option { + None + } + fn control_in<'a>(&'a mut self, _req: Request, _buf: &'a mut [u8]) -> Option> { + None + } + fn get_string(&mut self, index: StringIndex, _lang_id: u16) -> Option<&'static str> { + (index == self.string_idx).then_some(self.string_val) + } +} + +/// Total flash size passed to the embassy-rp Flash const generic. +/// +/// Set to 16 MB (the maximum common RP2040 flash size) so that the same +/// binary works on boards with 2, 4, 8 or 16 MB flash. `new_blocking()` +/// ignores this value at runtime — it is only used for software bounds +/// checking inside embassy-rp. Because all flash access goes through +/// `BlockingPartition` (which has its own partition-sized bounds checks), +/// overshooting the const generic is safe. +#[cfg(feature = "dfu_rp")] +pub const FLASH_SIZE: usize = 16 * 1024 * 1024; + +/// DFU transfer block size in bytes. Larger values speed up firmware +/// downloads. Must match the USB control buffer size used by the host. +pub const BLOCK_SIZE_DFU: usize = 512; + +#[cfg(feature = "dfu_rp")] +use embassy_embedded_hal::flash::partition::BlockingPartition; +#[cfg(feature = "dfu_rp")] +use embassy_rp::Peri; +#[cfg(feature = "dfu_rp")] +use embassy_rp::flash::{Blocking, Flash}; +#[cfg(feature = "dfu_rp")] +use embassy_rp::gpio::Output; +#[cfg(feature = "dfu_rp")] +use embassy_rp::peripherals::FLASH; +#[cfg(feature = "dfu")] +use embassy_usb::class::dfu::consts::Status; +#[cfg(feature = "dfu")] +use embassy_usb::class::dfu::dfu_mode::{self, DfuState}; + +#[cfg(feature = "dfu_rp")] +type FlashType = Flash<'static, FLASH, Blocking, FLASH_SIZE>; +#[cfg(feature = "dfu_rp")] +type MutexType = Mutex>; +#[cfg(feature = "dfu_rp")] +type PartitionType = BlockingPartition<'static, NoopRawMutex, FlashType>; + +#[cfg(feature = "dfu_rp")] +static FLASH_CELL: StaticCell = StaticCell::new(); +#[cfg(feature = "dfu_rp")] +static MANAGER_CELL: StaticCell = StaticCell::new(); +#[cfg(feature = "dfu_rp")] +static MANAGER_PTR: AtomicPtr = AtomicPtr::new(core::ptr::null_mut()); +#[cfg(feature = "dfu_rp")] +static LED_MUTEX: AtomicPtr>>>> = + AtomicPtr::new(core::ptr::null_mut()); + +#[cfg(feature = "dfu_rp")] +pub struct DfuFlashManager { + flash_mutex: &'static MutexType, + state_offset: u32, + state_size: u32, + dfu_offset: u32, + dfu_size: u32, + storage_offset: u32, + storage_size: u32, +} + +#[cfg(feature = "dfu_rp")] +impl DfuFlashManager { + fn new( + flash_mutex: &'static MutexType, + storage_offset: u32, + storage_size: u32, + state_offset: u32, + state_size: u32, + dfu_offset: u32, + dfu_size: u32, + ) -> Self { + Self { + flash_mutex, + state_offset, + state_size, + dfu_offset, + dfu_size, + storage_offset, + storage_size, + } + } + + pub fn state_partition(&self) -> PartitionType { + BlockingPartition::new(self.flash_mutex, self.state_offset, self.state_size) + } + + pub fn dfu_partition(&self) -> PartitionType { + BlockingPartition::new(self.flash_mutex, self.dfu_offset, self.dfu_size) + } + + pub fn storage_partition(&self) -> PartitionType { + BlockingPartition::new(self.flash_mutex, self.storage_offset, self.storage_size) + } +} + +/// Store an optional DFU LED pin globally. +#[cfg(feature = "dfu_rp")] +pub fn set_led(led: Option>) { + static LED_CELL: StaticCell>>>> = StaticCell::new(); + let m = LED_CELL.init(Mutex::new(RefCell::new(led))); + LED_MUTEX.store(m as *const _ as *mut _, Ordering::Release); +} + +/// Run a closure with the global DFU LED, if configured. +#[cfg(feature = "dfu_rp")] +fn with_led(f: F) -> Option +where + F: FnOnce(&mut Output<'static>) -> R, +{ + let ptr = LED_MUTEX.load(Ordering::Acquire); + if ptr.is_null() { + return None; + } + let m = unsafe { &*ptr }; + m.lock(|cell| cell.borrow_mut().as_mut().map(f)) +} + +/// DFU lock state (shared between keyboard loop and DFU handler). +#[cfg(feature = "dfu_lock")] +static DFU_LOCKED: AtomicBool = AtomicBool::new(true); + +/// Set to true once `RmkDfuHandler::start()` begins a DFU download. +#[cfg(feature = "dfu_lock")] +static DFU_STARTED: AtomicBool = AtomicBool::new(false); + +/// Signaled by `RmkDfuHandler::start()` when a blocked DFU download is rejected. +/// Triggers the unlock key polling window in `process_unlock`. +#[cfg(feature = "dfu_lock")] +static DFU_UNLOCK_SIGNAL: Signal = Signal::new(); + +#[cfg(feature = "dfu_lock")] +pub fn is_dfu_unlocked() -> bool { + !DFU_LOCKED.load(Ordering::Acquire) +} + +/// DFU handler wrapper that blinks an LED during transfer and checks the +/// DFU lock (if `dfu_lock` feature is enabled). +#[cfg(feature = "dfu")] +struct RmkDfuHandler { + inner: H, +} + +#[cfg(feature = "dfu")] +impl dfu_mode::Handler for RmkDfuHandler { + fn start(&mut self) -> Result<(), Status> { + #[cfg(feature = "dfu_lock")] + if !is_dfu_unlocked() { + DFU_UNLOCK_SIGNAL.signal(()); + info!("dfu_lock: DFU download rejected — keys not unlocked"); + return Err(Status::ErrVendor); + } + #[cfg(feature = "dfu_lock")] + DFU_STARTED.store(true, Ordering::Release); + info!("dfu_lock: DFU download started"); + #[cfg(feature = "dfu_rp")] + with_led(|led| led.set_high()); + self.inner.start() + } + + fn write(&mut self, data: &[u8]) -> Result<(), Status> { + #[cfg(feature = "dfu_rp")] + with_led(|led| led.toggle()); + self.inner.write(data) + } + + fn finish(&mut self) -> Result<(), Status> { + let res = self.inner.finish(); + #[cfg(feature = "dfu_rp")] + with_led(|led| led.set_low()); + res + } + + fn system_reset(&mut self) { + #[cfg(feature = "dfu_rp")] + with_led(|led| led.set_low()); + self.inner.system_reset() + } +} + +/// Initialize the blocking flash, create the DFU manager and store it globally. +#[cfg(feature = "dfu_rp")] +pub fn init_flash( + flash_peri: Peri<'static, FLASH>, + storage_offset: u32, + storage_size: u32, + state_offset: u32, + state_size: u32, + dfu_offset: u32, + dfu_size: u32, +) -> PartitionType { + let raw_flash = Flash::<_, Blocking, FLASH_SIZE>::new_blocking(flash_peri); + let flash_mutex: &'static MutexType = FLASH_CELL.init(Mutex::new(RefCell::new(raw_flash))); + let mgr = MANAGER_CELL.init(DfuFlashManager::new( + flash_mutex, + storage_offset, + storage_size, + state_offset, + state_size, + dfu_offset, + dfu_size, + )); + MANAGER_PTR.store(mgr as *const _ as *mut _, Ordering::Release); + mgr.storage_partition() +} + +/// Mark firmware boot as successful so the bootloader doesn't revert on next reset. +#[cfg(feature = "dfu_rp")] +pub fn mark_booted() { + if let Some(mgr) = get_manager() { + let state_part = mgr.state_partition(); + static ALIGNED: StaticCell<[u8; 1]> = StaticCell::new(); + let aligned: &'static mut [u8] = ALIGNED.init([0; 1]); + let mut state = embassy_boot_rp::BlockingFirmwareState::new(state_part, aligned); + state.mark_booted().ok(); + } +} + +/// Be a Karen and demand to see the manager. +/// Get a reference to the global DFU flash manager, if initialized. +#[cfg(feature = "dfu_rp")] +pub fn get_manager() -> Option<&'static DfuFlashManager> { + let ptr = MANAGER_PTR.load(Ordering::Acquire); + if ptr.is_null() { None } else { Some(unsafe { &*ptr }) } +} + +/// Register a DFU interface on the USB builder. +#[cfg(feature = "dfu_rp")] +pub fn register_dfu_interface>( + builder: &mut Builder<'static, D>, + mgr: &'static DfuFlashManager, + product_name: &'static str, +) { + use embassy_boot_rp::{BlockingFirmwareUpdater, FirmwareUpdaterConfig}; + use embassy_usb::class::dfu::consts::DfuAttributes; + use embassy_usb_dfu::ResetImmediate; + use embassy_usb_dfu::dfu::FirmwareHandler; + + let dfu_part = mgr.dfu_partition(); + let state_part = mgr.state_partition(); + let config = FirmwareUpdaterConfig { + dfu: dfu_part, + state: state_part, + }; + static ALIGNED: StaticCell<[u8; 1]> = StaticCell::new(); + let aligned: &'static mut [u8] = ALIGNED.init([0; 1]); + let updater = BlockingFirmwareUpdater::new(config, aligned); + + let attrs = DfuAttributes::CAN_DOWNLOAD | DfuAttributes::WILL_DETACH; + + let inner = FirmwareHandler::new(updater, ResetImmediate); + let handler = RmkDfuHandler { inner }; + let state = DfuState::new(handler, attrs); + + type DfuStateInner = + RmkDfuHandler>; + static DFU_STATE: StaticCell> = StaticCell::new(); + let state_ref = DFU_STATE.init(state); + + let string_idx = builder.string(); + + let mut func = builder.function(0x00, 0x00, 0x00); + let mut iface = func.interface(); + let mut alt = iface.alt_setting(0xFE, 0x01, 0x02, Some(string_idx)); + alt.descriptor( + 0x21, + &[ + attrs.bits(), + 0xc4, + 0x09, + (BLOCK_SIZE_DFU & 0xff) as u8, + ((BLOCK_SIZE_DFU >> 8) & 0xff) as u8, + 0x10, + 0x01, + ], + ); + drop(func); + builder.handler(state_ref); + + static STRING_PROVIDER: StaticCell = StaticCell::new(); + let string_provider = STRING_PROVIDER.init(DfuStringProvider { + string_idx, + string_val: product_name, + }); + builder.handler(string_provider); +} + +// --------------------------------------------------------------------------- +// dfu_lock — physical key unlock for DFU firmware download +// --------------------------------------------------------------------------- + +/// DfuLock state machine that checks a physical key combination to unlock DFU. +#[cfg(feature = "dfu_lock")] +pub struct DfuLock<'a> { + unlocked: AtomicBool, + unlock_keys: &'a [(u8, u8)], + keymap: &'a crate::keymap::KeyMap<'a>, +} + +#[cfg(feature = "dfu_lock")] +impl<'a> DfuLock<'a> { + pub fn new(unlock_keys: &'a [(u8, u8)], keymap: &'a crate::keymap::KeyMap<'a>) -> Self { + Self { + unlocked: AtomicBool::new(false), + unlock_keys, + keymap, + } + } + + /// One unlock cycle: block (yielded) on `DFU_UNLOCK_SIGNAL.wait()` until a + /// DFU download is rejected, then open a 10 s unlock window polling the + /// configured unlock keys at 50 ms. If the keys are pressed within that + /// window the lock is released and the LED blinks Morse "D F U". + pub(crate) async fn process_unlock(&self) { + // Phase 1: wait (yielded) until a DFU unlock request arrives + DFU_UNLOCK_SIGNAL.wait().await; + + // Phase 2: start the 10 s unlock window, wait for keypress or timeout. + // LED solid on to signal "press unlock keys now". + info!("dfu_lock: DFU activity detected, unlock window open for 10 s"); + info!("dfu_lock: waiting for unlock keys"); + with_led(|led| led.set_high()); + let deadline = embassy_time::Instant::now() + embassy_time::Duration::from_secs(10); + loop { + let all_pressed = self + .unlock_keys + .iter() + .all(|(row, col)| self.keymap.read_matrix_key(*row, *col)); + if all_pressed { + self.unlocked.store(true, Ordering::Release); + DFU_LOCKED.store(false, Ordering::Release); + info!("dfu_lock: unlock keys pressed, DFU unlocked for 10 s"); + break; + } + if embassy_time::Instant::now() >= deadline { + info!("dfu_lock: unlock window expired (10 s timeout)"); + DFU_LOCKED.store(true, Ordering::Release); + with_led(|led| led.set_low()); + return; + } + embassy_time::Timer::after_millis(50).await; + } + + // Phase 3: unlocked — wait until DFU download starts or 10 s pass. + // LED blinks Morse "D F U" to signal "ready to flash". + info!("dfu_lock: unlocked, signalling with Morse DFU"); + let deadline = embassy_time::Instant::now() + embassy_time::Duration::from_secs(10); + loop { + if DFU_STARTED.load(Ordering::Acquire) { + info!("dfu_lock: DFU download started, staying unlocked"); + with_led(|led| led.set_high()); + break; + } + if embassy_time::Instant::now() >= deadline { + info!("dfu_lock: unlock expired (10 s timeout)"); + DFU_LOCKED.store(true, Ordering::Release); + self.unlocked.store(false, Ordering::Release); + with_led(|led| led.set_low()); + break; + } + morse_blink_dfu().await; + } + } +} + +#[cfg(feature = "dfu_lock")] +impl<'a> Runnable for DfuLock<'a> { + async fn run(&mut self) -> ! { + loop { + self.process_unlock().await; + } + } +} + +/// Blink "D F U" in Morse code on the DFU LED. +#[cfg(feature = "dfu_lock")] +async fn morse_blink_dfu() { + use embassy_time::Timer; + + /// Element timing in milliseconds + const DOT: u64 = 100; + const DASH: u64 = 300; + const PAUSE_ELEMENT: u64 = 100; + const PAUSE_LETTER: u64 = 300; + + macro_rules! dot { + () => { + with_led(|led| led.set_high()); + Timer::after_millis(DOT).await; + with_led(|led| led.set_low()); + Timer::after_millis(PAUSE_ELEMENT).await; + }; + } + macro_rules! dash { + () => { + with_led(|led| led.set_high()); + Timer::after_millis(DASH).await; + with_led(|led| led.set_low()); + Timer::after_millis(PAUSE_ELEMENT).await; + }; + } + macro_rules! letter_gap { + () => { + Timer::after_millis(PAUSE_LETTER - PAUSE_ELEMENT).await; + }; + } + + // D = -.. + dash!(); + dot!(); + dot!(); + letter_gap!(); + // F = ..-. + dot!(); + dot!(); + dash!(); + dot!(); + letter_gap!(); + // U = ..- + dot!(); + dot!(); + dash!(); +} diff --git a/rmk/src/lib.rs b/rmk/src/lib.rs index 36a4fd5ef..ac361be81 100644 --- a/rmk/src/lib.rs +++ b/rmk/src/lib.rs @@ -60,6 +60,8 @@ pub mod channel; pub mod config; pub mod core_traits; pub mod debounce; +#[cfg(feature = "dfu")] +pub mod dfu; #[cfg(feature = "display")] pub mod display; pub mod driver; diff --git a/rmk/src/usb/mod.rs b/rmk/src/usb/mod.rs index 33f935584..2e2b20f3a 100644 --- a/rmk/src/usb/mod.rs +++ b/rmk/src/usb/mod.rs @@ -160,16 +160,22 @@ pub(crate) fn new_usb_builder<'d, D: Driver<'d>>(driver: D, keyboard_config: Dev usb_config.device_protocol = 0x01; usb_config.composite_with_iads = true; - // Extra HID interfaces (usb_log, steno) overflow the 128-byte config descriptor buffer. - #[cfg(any(feature = "usb_log", feature = "steno"))] + // Extra interfaces (usb_log, steno, dfu) overflow the 128-byte config descriptor buffer. + #[cfg(any(feature = "usb_log", feature = "steno", feature = "dfu"))] const USB_BUF_SIZE: usize = 256; - #[cfg(not(any(feature = "usb_log", feature = "steno")))] + #[cfg(not(any(feature = "usb_log", feature = "steno", feature = "dfu")))] const USB_BUF_SIZE: usize = 128; + // Control buffer must be large enough for the largest DFU transfer block. + #[cfg(feature = "dfu")] + const CONTROL_BUF_SIZE: usize = ::rmk::dfu::BLOCK_SIZE_DFU; + #[cfg(not(feature = "dfu"))] + const CONTROL_BUF_SIZE: usize = USB_BUF_SIZE; + static CONFIG_DESC: StaticCell<[u8; USB_BUF_SIZE]> = StaticCell::new(); static BOS_DESC: StaticCell<[u8; 16]> = StaticCell::new(); static MSOS_DESC: StaticCell<[u8; 16]> = StaticCell::new(); - static CONTROL_BUF: StaticCell<[u8; USB_BUF_SIZE]> = StaticCell::new(); + static CONTROL_BUF: StaticCell<[u8; CONTROL_BUF_SIZE]> = StaticCell::new(); let mut builder = Builder::new( driver, @@ -177,7 +183,7 @@ pub(crate) fn new_usb_builder<'d, D: Driver<'d>>(driver: D, keyboard_config: Dev &mut CONFIG_DESC.init([0; USB_BUF_SIZE])[..], &mut BOS_DESC.init([0; 16])[..], &mut MSOS_DESC.init([0; 16])[..], - &mut CONTROL_BUF.init([0; USB_BUF_SIZE])[..], + &mut CONTROL_BUF.init([0; CONTROL_BUF_SIZE])[..], ); static device_handler: StaticCell = StaticCell::new(); @@ -233,6 +239,14 @@ impl> UsbTransport { #[cfg(feature = "usb_log")] let logger = Some(add_usb_logger!(&mut builder)); + #[cfg(feature = "dfu")] + { + let product_name = device_config.product_name; + #[cfg(feature = "dfu_rp")] + if let Some(mgr) = ::rmk::dfu::get_manager() { + ::rmk::dfu::register_dfu_interface(&mut builder, mgr, product_name); + } + } let (keyboard_reader, keyboard_writer) = keyboard_rw.split(); let device = builder.build(); From f6c3ad77a980b2f5e1f5d766ab5e4cdb260e6b20 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pascal=20J=C3=A4ger?= Date: Tue, 16 Jun 2026 22:45:14 +0200 Subject: [PATCH 2/7] feat(dfu): add nrf52840 USB-DFU support MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Pascal Jäger --- docs/docs/main/docs/configuration/_meta.json | 1 + .../main/docs/configuration/bootloader.mdx | 264 ++ .../main/docs/configuration/chip_config.md | 47 + .../main/docs/configuration/chip_config.mdx | 187 -- .../flash_firmware/use_embassy_boot.mdx | 145 +- .../nrf52840_embassy_boot/.cargo/config.toml | 12 + .../nrf52840_embassy_boot/Cargo.lock | 2788 +++++++++++++++++ .../nrf52840_embassy_boot/Cargo.toml | 76 + .../nrf52840_embassy_boot/Makefile.toml | 41 + .../use_config/nrf52840_embassy_boot/build.rs | 54 + .../nrf52840_embassy_boot/keyboard.toml | 63 + .../use_config/nrf52840_embassy_boot/memory.x | 11 + .../nrf52840_embassy_boot/src/main.rs | 7 + .../nrf52840_embassy_boot/vial.json | 37 + .../use_config/rp2040_embassy_boot/Cargo.lock | 1 + .../rp2040_embassy_boot/keyboard.toml | 9 - .../use_config/rp2040_embassy_boot/memory.x | 7 +- .../nrf52840_embassy_boot/.cargo/config.toml | 11 + .../use_rust/nrf52840_embassy_boot/Cargo.lock | 2542 +++++++++++++++ .../use_rust/nrf52840_embassy_boot/Cargo.toml | 59 + .../nrf52840_embassy_boot/Makefile.toml | 41 + .../use_rust/nrf52840_embassy_boot/build.rs | 53 + .../use_rust/nrf52840_embassy_boot/memory.x | 11 + .../nrf52840_embassy_boot/src/keymap.rs | 23 + .../nrf52840_embassy_boot/src/macros.rs | 12 + .../nrf52840_embassy_boot/src/main.rs | 166 + .../nrf52840_embassy_boot/src/vial.rs | 1 + .../use_rust/nrf52840_embassy_boot/vial.json | 37 + .../use_rust/rp2040_embassy_boot/memory.x | 11 +- .../use_rust/rp2040_embassy_boot/src/main.rs | 7 +- rmk-config/src/default_config/nice_nano.toml | 3 + .../src/default_config/nice_nano_v2.toml | 3 + rmk-config/src/default_config/nrf52840.toml | 3 + rmk-config/src/lib.rs | 16 +- rmk-config/src/resolved/hardware.rs | 105 +- rmk-macro/Cargo.toml | 2 + rmk-macro/src/codegen/chip/flash.rs | 61 +- rmk-macro/src/codegen/orchestrator.rs | 4 +- rmk/Cargo.toml | 10 +- rmk/src/dfu.rs | 260 +- rmk/src/storage/mod.rs | 7 +- rmk/src/usb/mod.rs | 2 +- rmk/src/watchdog/mod.rs | 6 +- 43 files changed, 6766 insertions(+), 440 deletions(-) create mode 100644 docs/docs/main/docs/configuration/bootloader.mdx create mode 100644 docs/docs/main/docs/configuration/chip_config.md delete mode 100644 docs/docs/main/docs/configuration/chip_config.mdx create mode 100644 examples/use_config/nrf52840_embassy_boot/.cargo/config.toml create mode 100644 examples/use_config/nrf52840_embassy_boot/Cargo.lock create mode 100644 examples/use_config/nrf52840_embassy_boot/Cargo.toml create mode 100644 examples/use_config/nrf52840_embassy_boot/Makefile.toml create mode 100644 examples/use_config/nrf52840_embassy_boot/build.rs create mode 100644 examples/use_config/nrf52840_embassy_boot/keyboard.toml create mode 100644 examples/use_config/nrf52840_embassy_boot/memory.x create mode 100644 examples/use_config/nrf52840_embassy_boot/src/main.rs create mode 100644 examples/use_config/nrf52840_embassy_boot/vial.json create mode 100644 examples/use_rust/nrf52840_embassy_boot/.cargo/config.toml create mode 100644 examples/use_rust/nrf52840_embassy_boot/Cargo.lock create mode 100644 examples/use_rust/nrf52840_embassy_boot/Cargo.toml create mode 100644 examples/use_rust/nrf52840_embassy_boot/Makefile.toml create mode 100644 examples/use_rust/nrf52840_embassy_boot/build.rs create mode 100644 examples/use_rust/nrf52840_embassy_boot/memory.x create mode 100644 examples/use_rust/nrf52840_embassy_boot/src/keymap.rs create mode 100644 examples/use_rust/nrf52840_embassy_boot/src/macros.rs create mode 100644 examples/use_rust/nrf52840_embassy_boot/src/main.rs create mode 100644 examples/use_rust/nrf52840_embassy_boot/src/vial.rs create mode 100644 examples/use_rust/nrf52840_embassy_boot/vial.json diff --git a/docs/docs/main/docs/configuration/_meta.json b/docs/docs/main/docs/configuration/_meta.json index 882fa18e9..d3f2235c9 100644 --- a/docs/docs/main/docs/configuration/_meta.json +++ b/docs/docs/main/docs/configuration/_meta.json @@ -16,6 +16,7 @@ "host_config", "output", "chip_config", + "bootloader", { "type": "dir", "name": "input_device", diff --git a/docs/docs/main/docs/configuration/bootloader.mdx b/docs/docs/main/docs/configuration/bootloader.mdx new file mode 100644 index 000000000..06cbd2248 --- /dev/null +++ b/docs/docs/main/docs/configuration/bootloader.mdx @@ -0,0 +1,264 @@ +# Bootloader Configuration (embassy-boot) + +RMK supports DFU firmware updates via [embassy-boot](https://github.com/embassy-rs/embassy/tree/main/embassy-boot) for **RP2040** and **nRF52840**. The bootloader splits flash into ACTIVE and DFU slots, providing safe updates with automatic rollback on failure. + +A pre-built bootloader called **bootymcbootface** is available for both platforms. The partition formula is identical: + +```text +bootloader+state = 28K (fixed) +storage = 128K (fixed — 32 sectors × 4K for persistent keymap storage) +remaining = flash_size - 28K - 128K +ACTIVE = (remaining - 4K) / 2 +DFU = ACTIVE + 4K +``` + +See the [flashing guide](../user_guide/flash_firmware/use_embassy_boot.mdx) for step-by-step instructions. + +## RP2040 + +Add a `[dfu]` section to your `keyboard.toml` or use the Rust API directly. + +import { Tab, Tabs, Rust, Toml } from '@theme' + + +}> + +```toml title="keyboard.toml" +[dfu] +# (Optional) Total flash size in bytes. Used to auto-calculate partition addresses. +# Defaults to 2 MB (2097152) when omitted. +flash_size = 2097152 + +# (Optional) Flash page size in bytes (4096 for RP2040). +page_size = 4096 + +# (Optional) DFU activity LED pin, default "PIN_25". +led = "PIN_25" +# led = "none" to omit DFU LED + +# (Optional) Unlock keys for dfu_lock (physical matrix positions). Only works with dfu_lock feature enabled in Cargo.toml. +unlock_keys = [[0, 0], [1, 1]] + +# ── (Optional) Manual overrides (only if auto-calculation is not suitable) ── +state_offset = 0x6000 +state_size = 0x1000 +dfu_offset = 0x87000 +dfu_size = 528384 +``` + + +}> + +```rust title="main.rs" +// Flash layout using the bootymcbootface formula: +// state at 0x6000 (4K), active from 0x7000 (size: (flash_size - 28K (= BOOT2 size + embassy-boot + embassy-boot state) - STORAGE_SIZE (= 128K) - page_size (= 4K)) / 2), +// dfu follows active (active_size + page_size (= 4K)) +// +// All offsets (DFU_OFFSET, DFU_SIZE, STORAGE_OFFSET, etc.) are derived +// automatically from FLASH_SIZE below — change only that constant when using bootymcbootface. +// +// ⚠ You can define your own FLASH_SIZE and addresses, but then you must build and +// flash a custom embassy-boot bootloader with a matching memory.x! +const FLASH_SIZE: u32 = 2 * 1024 * 1024; // 2 MB (default) +// const FLASH_SIZE: u32 = 4 * 1024 * 1024; // 4 MB +// const FLASH_SIZE: u32 = 8 * 1024 * 1024; // 8 MB +// const FLASH_SIZE: u32 = 16 * 1024 * 1024; // 16 MB +const PAGE_SIZE: u32 = 4 * 1024; +const STORAGE_SIZE: u32 = 128 * 1024; // 32 sectors × 4K after ACTIVE+DFU +const STATE_OFFSET: u32 = 0x6000; +const STATE_SIZE: u32 = 0x1000; +const ACTIVE_OFFSET: u32 = 0x7000; // after 28K bootloader + state +let remaining: u32 = FLASH_SIZE + - 28 * 1024 // size of boot 2 + embassy-boot + embassy-boot state + - STORAGE_SIZE; +let active_size: u32 = (remaining - PAGE_SIZE) / 2; // DFU = ACTIVE + 1 page (embassy-boot requirement) +let dfu_size: u32 = active_size + PAGE_SIZE; // embassy-boot needs that extra page for swap info +let dfu_offset: u32 = ACTIVE_OFFSET + active_size; // dfu after active +let storage_offset: u32 = dfu_offset + dfu_size; // storage after active + dfu +assert!(storage_offset + STORAGE_SIZE == FLASH_SIZE); // sanity check that we fit everything in flash + +info!( + "Flash layout: state @ 0x{:04X} ({}K), active @ 0x{:04X} ({}K), dfu @ 0x{:04X} ({}K), storage @ 0x{:04X} ({}K)", + STATE_OFFSET, + STATE_SIZE / 1024, + ACTIVE_OFFSET, + active_size / 1024, + dfu_offset, + dfu_size / 1024, + storage_offset, + STORAGE_SIZE / 1024 +); + +let flash = async_flash_wrapper(rmk::dfu::init_flash( + p.FLASH, + storage_offset, + STORAGE_SIZE, + STATE_OFFSET, + STATE_SIZE, + dfu_offset, + dfu_size, +)); + +// Optional: assign a DFU activity LED +rmk::dfu::set_led(Some(Output::new(p.PIN_25, Level::Low))); + +// Mark boot as successful (so bootloader doesn't revert on reset) +rmk::dfu::mark_booted(); + +// Optional: DFU lock with physical key unlock. Requires the `dfu_lock` Cargo feature. +let unlock_keys: &[(u8, u8)] = &[(0, 0), (1, 1)]; +let mut dfu_lock = ::rmk::dfu::DfuLock::new(unlock_keys, &keymap); +// Then add dfu_lock in run_all!() +// ... + run_all!( + // other processors ... + dfu_lock, + ) +``` + + + + +## nRF52840 + +Add a `[dfu]` section to your `keyboard.toml` or use the Rust API directly. + + +}> + +```toml title="keyboard.toml" +[dfu] +# (Optional) Total flash size in bytes. Used to auto-calculate partition addresses. +# 1 MB flash — auto-calculates ACTIVE (432K) and DFU (436K) +flash_size = 1048576 + +# (Optional) Flash page size in bytes (4096 for RP2040). +page_size = 4096 + +# (Optional) DFU activity LED pin, default "P0_15". +led = "P0_15" +# led = "none" to omit DFU LED + +# (Optional) Unlock keys for dfu_lock (physical matrix positions). Only works with dfu_lock feature enabled in Cargo.toml. +unlock_keys = [[0, 0], [1, 1]] + +# ── (Optional) Manual overrides (only if auto-calculation is not suitable) ── +state_offset = 0x6000 +state_size = 0x1000 +dfu_offset = 0x87000 +dfu_size = 528384 +``` + + +}> + +```rust title="main.rs" +// Flash layout using the bootymcbootface formula: +// state at 0x6000 (4K), active from 0x7000 (size: (flash_size - 28K (= embassy-boot + embassy-boot state) - STORAGE_SIZE (= 64K) - page_size (= 4K)) / 2), +// dfu follows active (active_size + page_size (= 4K)) +// +// All offsets (DFU_OFFSET, DFU_SIZE, STORAGE_OFFSET, etc.) are derived +// automatically from FLASH_SIZE below — change only that constant when using +// bootymcbootface. +// +// ⚠ You can define your own FLASH_SIZE and addresses, but then you must build and +// flash a custom embassy-boot bootloader with a matching memory.x! +const FLASH_SIZE: u32 = 1024 * 1024; // 1 MB (nRF52840) +const PAGE_SIZE: u32 = 4 * 1024; +const STORAGE_SIZE: u32 = 128 * 1024; // 32 sectors × 4K after ACTIVE+DFU +const STATE_OFFSET: u32 = 0x6000; +const STATE_SIZE: u32 = 0x1000; +const ACTIVE_OFFSET: u32 = 0x7000; +let remaining: u32 = FLASH_SIZE + - 28 * 1024 // bootloader (24K) + state (4K) + - STORAGE_SIZE; +let active_size: u32 = (remaining - PAGE_SIZE) / 2; +let dfu_size: u32 = active_size + PAGE_SIZE; +let dfu_offset: u32 = ACTIVE_OFFSET + active_size; +let storage_offset: u32 = dfu_offset + dfu_size; +assert!(storage_offset + STORAGE_SIZE == FLASH_SIZE); + +info!( + "Flash layout: state @ 0x{:04X} ({}K), active @ 0x{:04X} ({}K), dfu @ 0x{:04X} ({}K), storage @ 0x{:04X} ({}K)", + STATE_OFFSET, + STATE_SIZE / 1024, + ACTIVE_OFFSET, + active_size / 1024, + dfu_offset, + dfu_size / 1024, + storage_offset, + STORAGE_SIZE / 1024 +); + +let flash = async_flash_wrapper(rmk::dfu::init_flash( + p.NVMC, + storage_offset, + STORAGE_SIZE, + STATE_OFFSET, + STATE_SIZE, + dfu_offset, + dfu_size, +)); + +rmk::dfu::set_led(Some(Output::new(p.P0_15, Level::Low, OutputDrive::Standard))); + +// Optional: assign a DFU activity LED +rmk::dfu::set_led(Some(Output::new(p.P0_15, Level::Low, OutputDrive::Standard))); + +// Mark boot as successful (so bootloader doesn't revert on reset) +rmk::dfu::mark_booted(); + +// Optional: DFU lock with physical key unlock. Requires the `dfu_lock` Cargo feature. +let unlock_keys: &[(u8, u8)] = &[(0, 0), (1, 1)]; +let mut dfu_lock = ::rmk::dfu::DfuLock::new(unlock_keys, &keymap); + +// Then add dfu_lock in run_all!() +// ... +run_all!( + // other processors ... + dfu_lock, +) +``` + + + + +## Partition layout + +The bootloader divides flash into regions. The defaults follow the [bootymcbootface](https://codeberg.org/Schievel/bootymcbootface/) convention and are automatically calculated from `flash_size`: + +| Region | Offset | Size | +|-----------------|----------------|--------------------------------------| +| Bootloader(s) | `0x0000000` | 28 KB | +| Boot state | `0x6000` | 4 KB | +| Active firmware | `0x7000` | `(flash_size - 28K - 128K - 4K) / 2` | +| DFU download | follows active | `active_size + 4K` | +| Storage | follows DFU | 128 KB | + +The DFU partition size follows embassy-boot guidelines, the additional page is used for status information during flashing. + +All `[dfu]` fields are optional. The partition values are auto-calculated from `flash_size` and `page_size` using the bootymcbootface formula. If you supply any of `state_offset`, `state_size`, `dfu_offset`, or `dfu_size` directly, auto-calculation is disabled and your values are used as-is. + +Your `memory.x` must match this partition layout — see the [flashing guide](../user_guide/flash_firmware/use_embassy_boot.mdx) for details. + +## DFU LED (optional) + +A GPIO pin for the DFU LED. + +| Platform | Default LED pin | Example configuration | +|----------|----------------|----------------------| +| RP2040 | `PIN_25` | `led = "PIN_25"` | +| nRF52840 | `P0_15` | `led = "P0_15"` | + +See the [LED behavior table](../user_guide/flash_firmware/use_embassy_boot.mdx#led-behavior-during-dfu-transfer-optional) for the full state machine. + +## DFU lock (optional, feature `dfu_lock`) + +Physical key positions that unlock DFU firmware downloads. Requires the `dfu_lock` Cargo feature. Keys are identified by matrix position `(row, col)`, not by keycode. + +See the [DFU lock section](../user_guide/flash_firmware/use_embassy_boot.mdx#unlocking-dfu-optional-dfu_lock) for the unlock workflow. + +::: tip +Choose keys that are easy to press simultaneously but not commonly pressed together accidentally. +::: + diff --git a/docs/docs/main/docs/configuration/chip_config.md b/docs/docs/main/docs/configuration/chip_config.md new file mode 100644 index 000000000..14ac9f71b --- /dev/null +++ b/docs/docs/main/docs/configuration/chip_config.md @@ -0,0 +1,47 @@ +# Chip-Specific Configuration + +The `[chip.]` section allows you to configure chip-specific settings for different microcontrollers. These settings are optional and only needed when you want to override the default behavior. + +## nRF52840 + +### DCDC Configuration + +The nRF52840 has two DC/DC regulators that can improve power efficiency when enabled with proper hardware support. + +#### Configuration Example + +```toml +[chip.nrf52840] +# Enable DCDC regulator 0 +dcdc_reg0 = true +# Enable DCDC regulator 1 +dcdc_reg1 = true +# Set DCDC regulator 0 voltage +dcdc_reg0_voltage = "3V3" # Options: "3V3" or "1V8" +``` + +::: danger Hardware Requirement +Do not enable DC/DC regulators without an external LC filter being connected, as this will inhibit device operation, including debug access, until an LC filter is connected. +::: +::: danger Bootloader Version +If your hardware is using the [Adafruit nRF52 Bootloader](https://github.com/adafruit/Adafruit_nRF52_Bootloader) (e.g. nice!nano) ensure that your bootloader is updated to version ≥ [0.10.0](https://github.com/adafruit/Adafruit_nRF52_Bootloader/releases/tag/0.10.0) when setting a voltage other than 3V3. +There is a bug in older versions that can lead to a boot loop which can only be fixed by re-flashing the bootloader via the debug interface. +::: + +## nRF52833 + +### DCDC Configuration + +The nRF52833 has one DC/DC regulator available for configuration. + +#### Configuration Example + +```toml +[chip.nrf52833] +# Enable DCDC regulator 1 +dcdc_reg1 = true +``` + +::: danger Hardware Requirement +Do not enable DC/DC regulator without an external LC filter being connected, as this will inhibit device operation, including debug access, until an LC filter is connected. +::: diff --git a/docs/docs/main/docs/configuration/chip_config.mdx b/docs/docs/main/docs/configuration/chip_config.mdx deleted file mode 100644 index 987045583..000000000 --- a/docs/docs/main/docs/configuration/chip_config.mdx +++ /dev/null @@ -1,187 +0,0 @@ -# Chip-Specific Configuration - -The `[chip.]` section allows you to configure chip-specific settings for different microcontrollers. These settings are optional and only needed when you want to override the default behavior. - -## RP2040 (with embassy-boot bootloader) - -When using the embassy-boot bootloader on RP2040, add a `[dfu]` section to your `keyboard.toml` (or use the Rust API directly). - -import { Tab, Tabs, Rust, Toml } from '@theme' - - -}> - -```toml title="keyboard.toml" -[dfu] -# (Optional) Total flash size in bytes. Used to auto-calculate partition addresses. -# Defaults to 2 MB (2097152) when omitted. -flash_size = 2097152 - -# (Optional) Flash page size in bytes (4096 for RP2040). -page_size = 4096 - -# (Optional) DFU activity LED pin, default "PIN_25". -led = "PIN_25" -led = "none" to omit DFU LED - -# (Optional) Unlock keys for dfu_lock (physical matrix positions). Only works with dfu_lock feature enabled. -# Format: [[row, col], [row, col], ...] -unlock_keys = [[0, 0], [1, 1]] - -# ── (Optional) Manual overrides (only if auto-calculation is not suitable) ── -# state_offset = 0x6000 -# state_size = 0x1000 -# dfu_offset = 0x87000 -# dfu_size = 528384 -``` - - -}> - -```rust title="main.rs" -// Flash layout using the bootymcbootface formula: -// state at 0x6000 (4K), active from 0x7000 (size: (flash_size - 28K (= BOOT2 size + embassy-boot + embassy-boot state) - STORAGE_SIZE (= 128K) - page_size (= 4K)) / 2), -// dfu follows active (active_size + page_size (= 4K)) -// -// All offsets (DFU_OFFSET, DFU_SIZE, STORAGE_OFFSET, etc.) are derived -// automatically from FLASH_SIZE below — change only that constant when using bootymcbootface. -// -// ⚠ You can define your own FLASH_SIZE and addresses, but then you must build and -// flash a custom embassy-boot bootloader with a matching memory.x! -const FLASH_SIZE: u32 = 2 * 1024 * 1024; // 2 MB (default) -// const FLASH_SIZE: u32 = 4 * 1024 * 1024; // 4 MB -// const FLASH_SIZE: u32 = 8 * 1024 * 1024; // 8 MB -// const FLASH_SIZE: u32 = 16 * 1024 * 1024; // 16 MB -const PAGE_SIZE: u32 = 4 * 1024; -const STORAGE_SIZE: u32 = 128 * 1024; // 32 sectors × 4K after ACTIVE+DFU -const STATE_OFFSET: u32 = 0x6000; -const STATE_SIZE: u32 = 0x1000; -const ACTIVE_OFFSET: u32 = 0x7000; // after 28K bootloader + state -let remaining: u32 = FLASH_SIZE - - 28 * 1024 // size of boot 2 + embassy-boot + embassy-boot state - - STORAGE_SIZE; -let active_size: u32 = (remaining - PAGE_SIZE) / 2; // DFU = ACTIVE + 1 page (embassy-boot requirement) -let dfu_size: u32 = active_size + PAGE_SIZE; // embassy-boot needs that extra page for swap info -let dfu_offset: u32 = ACTIVE_OFFSET + active_size; // dfu after active -let storage_offset: u32 = dfu_offset + dfu_size; // storage after active + dfu -let storage_size: u32 = STORAGE_SIZE; -assert!(storage_offset + storage_size == FLASH_SIZE); // sanity check that we fit everything in flash - -info!( - "Flash layout: state @ 0x{:04X} ({}K), active @ 0x{:04X} ({}K), dfu @ 0x{:04X} ({}K), storage @ 0x{:04X} ({}K)", - STATE_OFFSET, - STATE_SIZE / 1024, - ACTIVE_OFFSET, - active_size / 1024, - dfu_offset, - dfu_size / 1024, - storage_offset, - storage_size / 1024 -); - -let flash = async_flash_wrapper(rmk::dfu::init_flash( - p.FLASH, - storage_offset, - storage_size, - STATE_OFFSET, - STATE_SIZE, - dfu_offset, - dfu_size, -)); - -// Optional: assign a DFU activity LED -rmk::dfu::set_led(Some(Output::new(p.PIN_25, Level::Low))); - -// Mark boot as successful (so bootloader doesn't revert on reset) -rmk::dfu::mark_booted(); - -// Optional: DFU lock with physical key unlock. Requires the `dfu_lock` Cargo feature. -let unlock_keys: &[(u8, u8)] = &[(0, 0), (1, 1)]; -let mut dfu_lock = ::rmk::dfu::DfuLock::new(unlock_keys, &keymap); -// Then add dfu_lock in run_all!() -// ... - run_all!( - // other processors ... - dfu_lock, - ) -``` - - - - -### Partition layout - -The bootloader divides flash into regions. The defaults follow the [bootymcbootface](https://codeberg.org/Schievel/bootymcbootface/) convention and are automatically calculated from `flash_size`: - -| Region | Offset | Size | -|-----------------|------------------|------------------------------------------------------------------------------------| -| Bootloader | `0x0000000` | 28 KB | -| Boot state | `0x6000` (24 KB) | 4 KB | -| Active firmware | `0x7000` (28 KB) | (flash_size - 28K (= BOOT2 size + embassy-boot + embassy-boot state) - STORAGE_SIZE - page_size) / 2| -| DFU download | follows active | `active_size + page_size` | -| Storage | follows DFU | rest of flash | - -The DFU partition size follows embassy-boot guidelines, the additional page is used for status information during flashing. - -All `[dfu]` fields are optional. The partition values are auto-calculated from `flash_size` and `page_size` using the bootymcbootface formula. If you supply any of `state_offset`, `state_size`, `dfu_offset`, or `dfu_size` directly, auto-calculation is disabled and your values are used as-is. - -Your `memory.x` must match this partition layout — see the [flashing guide](../user_guide/flash_firmware/use_embassy_boot.mdx) for details. - -#### `led` (optional) - -A GPIO pin for the DFU LED. On the Raspberry Pi Pico, the built-in LED is on pin 25. -See the [LED behavior table](../user_guide/flash_firmware/use_embassy_boot.mdx#led-behavior-during-dfu-transfer-optional) for the full state machine. - -#### `unlock_keys` (optional, dfu_lock) - -Physical key positions that unlock DFU firmware downloads. Requires the `dfu_lock` Cargo feature. Keys are identified by their matrix position `(row, column)`, not by keycode. - -Detailed unlock workflow in the [DFU lock section](../user_guide/flash_firmware/use_embassy_boot.mdx#unlocking-dfu-optional-dfu_lock). - -::: tip -Choose keys that are easy to press simultaneously but not commonly pressed together accidentally. -::: - -## nRF52840 - -### DCDC Configuration - -The nRF52840 has two DC/DC regulators that can improve power efficiency when enabled with proper hardware support. - -#### Configuration Example - -```toml -[chip.nrf52840] -# Enable DCDC regulator 0 -dcdc_reg0 = true -# Enable DCDC regulator 1 -dcdc_reg1 = true -# Set DCDC regulator 0 voltage -dcdc_reg0_voltage = "3V3" # Options: "3V3" or "1V8" -``` - -::: danger Hardware Requirement -Do not enable DC/DC regulators without an external LC filter being connected, as this will inhibit device operation, including debug access, until an LC filter is connected. -::: -::: danger Bootloader Version -If your hardware is using the [Adafruit nRF52 Bootloader](https://github.com/adafruit/Adafruit_nRF52_Bootloader) (e.g. nice!nano) ensure that your bootloader is updated to version ≥ [0.10.0](https://github.com/adafruit/Adafruit_nRF52_Bootloader/releases/tag/0.10.0) when setting a voltage other than 3V3. -There is a bug in older versions that can lead to a boot loop which can only be fixed by re-flashing the bootloader via the debug interface. -::: - -## nRF52833 - -### DCDC Configuration - -The nRF52833 has one DC/DC regulator available for configuration. - -#### Configuration Example - -```toml -[chip.nrf52833] -# Enable DCDC regulator 1 -dcdc_reg1 = true -``` - -::: danger Hardware Requirement -Do not enable DC/DC regulator without an external LC filter being connected, as this will inhibit device operation, including debug access, until an LC filter is connected. -::: diff --git a/docs/docs/main/docs/user_guide/flash_firmware/use_embassy_boot.mdx b/docs/docs/main/docs/user_guide/flash_firmware/use_embassy_boot.mdx index ee1ff0d52..b2217c98d 100644 --- a/docs/docs/main/docs/user_guide/flash_firmware/use_embassy_boot.mdx +++ b/docs/docs/main/docs/user_guide/flash_firmware/use_embassy_boot.mdx @@ -1,35 +1,34 @@ # Use embassy-boot bootloader -::: tip -This feature is only available for **RP2040** (Raspberry Pi Pico, Pi Pico W, and other RP2040 boards). -::: +[embassy-boot](https://github.com/embassy-rs/embassy/tree/main/embassy-boot) is a bootloader framework from the Embassy project. It splits the flash into two firmware slots (active and DFU download), so updating is **safe even if power is lost or the transfer fails** — the old firmware remains intact and the bootloader can roll back automatically. You can build your own bootloader, or use a pre-built one like **bootymcbootface**. -[embassy-boot](https://github.com/embassy-rs/embassy/tree/main/embassy-boot) is a bootloader framework from the Embassy project. It splits the flash into two firmware slots (active and DFU download), so updating is **safe even if power is lost or the transfer fails** — the old firmware remains intact and the bootloader can roll back automatically. You can build your own bootloader using the `embassy-boot-rp` crate, or use a pre-built one like **bootymcbootface**. +RMK supports DFU for **RP2040** (via `dfu_rp`) and **nRF52840** (via `dfu_nrf`). -[bootymcbootface](https://codeberg.org/Schievel/bootymcbootface/) is a pre-built embassy-boot bootloader for RP2040. It sits at the beginning of flash and handles the dual-slot firmware switching and rollback on boot. RMK itself provides the DFU USB interface (via `embassy-usb-dfu`) for subsequent updates, so once bootymcbootface and RMK are flashed, you never need to press BOOTSEL again. +[bootymcbootface](https://codeberg.org/Schievel/bootymcbootface/) is a pre-built embassy-boot bootloader for both platforms. It sits at the beginning of flash and handles the dual-slot firmware switching and rollback on boot. RMK itself provides the DFU USB interface (via `embassy-usb-dfu`) for subsequent updates, so once bootymcbootface and RMK are flashed, you never need to press BOOTSEL again. RMK and bootymcbootface use an **identical partition formula** so the layout always fits perfectly: -```rust -// bootloader+state = 28K (fixed) -// storage = 128K (fixed — 32 sectors × 4K for persistent keymap storage) -// remaining = flash_size - 28K - 128K -// ACTIVE = (remaining - 4K) / 2 -// DFU = ACTIVE + 4K (1 page delta required by embassy-boot swap) +```text +bootloader+state = 28K (fixed) +storage = 128K (fixed — 32 sectors × 4K for persistent keymap storage) +remaining = flash_size - 28K - 128K +ACTIVE = (remaining - 4K) / 2 +DFU = ACTIVE + 4K (1 page delta required by embassy-boot swap) ``` The 4K page delta is an **invariant of embassy-boot's swap algorithm**: the DFU slot must always be exactly one erase page larger than the ACTIVE slot. Storage is reserved at the end of flash and **cannot be reconfigured** when using bootymcbootface — it is always 128K (32 sectors × 4K). -| Region | 2MB | 4MB | 8MB | 16MB | -|-------------|-------------------|-------------------|-------------------|-------------------| -| Boot+State | 28K (0x7000) | 28K (0x7000) | 28K (0x7000) | 28K (0x7000) | -| ACTIVE | **944K** (0xEC000)| **1968K** (0x1EC000) | **4016K** (0x3EC000) | **8112K** (0x7EC000) | -| DFU | **948K** (0xED000)| **1972K** (0x1ED000) | **4020K** (0x3ED000) | **8116K** (0x7ED000) | -| Storage | 128K (0x20000) | 128K (0x20000) | 128K (0x20000) | 128K (0x20000) | +| Region | 2MB (RP2040) | 4MB (RP2040) | 8MB (RP2040) | 16MB (RP2040) | 1MB (nRF52840) | +|-------------|-------------------|-------------------|-------------------|-------------------|------------------| +| Boot+State | 28K (0x7000) | 28K (0x7000) | 28K (0x7000) | 28K (0x7000) | 28K (0x7000) | +| ACTIVE | **944K** (0xEC000)| **1968K** (0x1EC000) | **4016K** (0x3EC000) | **8112K** (0x7EC000) | **432K** (0x73000) | +| DFU | **948K** (0xED000)| **1972K** (0x1ED000) | **4020K** (0x3ED000) | **8116K** (0x7ED000) | **436K** (0x7B000) | +| Storage | 128K (0x20000) | 128K (0x20000) | 128K (0x20000) | 128K (0x20000) | 128K (0x20000) | The size of the ACTIVE Region is what you need to plug in as the flash size in `memory.x`. +(see also the examples `memory.x` in `rmk/examples/use_rust/rp2040_embassy_boot/` for RP2040 or `rmk/examples/use_rust/nrf52840_embassy_boot/` for nRF) -If you override `flash_size` in your `keyboard.toml`'s `[dfu]` section, RMK's auto-calc recomputes the layout on the fly. You never need to manually set `dfu_offset` or `dfu_size` when using bootymcbootface. +If you override `flash_size` in your `keyboard.toml`'s `[dfu]` section, RMK's auto-calc recomputes the layout on the fly. You never need to manually set the addresses like `dfu_offset` or `dfu_size` when using bootymcbootface. ## Prerequisites @@ -37,35 +36,51 @@ If you override `flash_size` in your `keyboard.toml`'s `[dfu]` section, RMK's au You need the [bootymcbootface](https://codeberg.org/Schievel/bootymcbootface/) bootloader in the **correct flash size** for your board. The available versions are named by flash size, e.g.: +**RP2040:** - `bootymcbootface-rp2040-2mb.uf2` – for 2 MB flash -- `bootymcbootface-rp2040-4mb.uf2` – for 4 MB flash -- `bootymcbootface-rp2040-8mb.uf2` – for 8 MB flash -- `bootymcbootface-rp2040-16mb.uf2` – for 16 MB flash +- `bootymcbootface-rp204o-4mb.uf2` – for 4 MB flash +- `bootymcbootface-rp204o-8mb.uf2` – for 8 MB flash +- `bootymcbootface-rp204o-16mb.uf2` – for 16 MB flash + +::: tip +The **2 MB version works with larger flash chips too** (e.g. 4 MB or 8 MB), using only the first 2 MB. On 2 MB you get 944K of ACTIVE space, which is ample for most RMK firmwares. If you need more room (e.g. with large keymaps, displays, RGB, or many features), pick the matching flash size variant — see the table above for exact slot sizes. +::: + +**nRF52840:** +- `bootymcbootface-nrf52840.uf2` – for 1 MB flash +- `bootymcbootface-nrf52840.elf` – for 1 MB flash, for direct flashing via probe-rs -The **2 MB version works with larger flash chips too** (e.g. 4 MB or 8 MB), using only the first 2 MB. On 2 MB you get 944K of ACTIVE space, which is ample for most RMK firmwares. If you need more room (e.g. with large keymaps, Vial, or many features), pick the matching flash size variant — see the table above for exact slot sizes. +::: warning +When using the nRF52840 with the **Adafruit UF2 bootloader**, flashing bootymcbootface **overwrites** the Adafruit bootloader (even when flashing via UF2). Subsequent UF2 uploads won't work. +::: ### Compile RMK with DFU support -RMK must be compiled with the `dfu` and `dfu_rp` features and the **matching flash size**. +RMK must be compiled with the `dfu` feature and the platform-specific feature: -When using `rmkit init`, you will be asked whether you want to use embassy-boot and can enter the flash size. `rmkit` handles all necessary adjustments automatically. +- **RP2040**: `dfu_rp` +- **nRF52840**: `dfu_nrf` — optionally with `nrf52840_ble` for simultaneous BLE support If configuring manually, ensure: -- `Cargo.toml` uses the `dfu_rp` feature +- `Cargo.toml` uses the `dfu_rp` (RP2040) or `dfu_nrf` (nRF52840) feature - `keyboard.toml` has `[dfu]` section -- The flash partitioning in `memory.x` matches your bootloader and flash size (see `rmk/examples/use_rust/rp2040_embassy_boot/`) +- The flash partitioning in `memory.x` matches your bootloader and flash size (see `rmk/examples/use_rust/rp2040_embassy_boot/` for RP2040 or `rmk/examples/use_rust/nrf52840_embassy_boot/` for nRF) -**Important:** The bootymcbootface version and the RMK compilation must use the **same flash size**. Example: bootymcbootface 2 MB → RMK with 2 MB flash configuration. +**Important:** For RP2040 the bootymcbootface version (2MB, 4MB, ...) and the RMK settings must use the **same flash size**. Example: bootymcbootface 2 MB → RMK with 2 MB flash configuration. So that means, if you have a RP2040 with bigger flash, you can always use a bootymcbootface and a memory.x in your firmware for a smaller flash size, but the both must be for the same flash size. ::: tip -You can still flash firmware via UF2 or probe-rs — as long as it was built with the correct `memory.x` for the embassy-boot partition layout (i.e. with `dfu_rp` feature), it will land in the active firmware slot and leave bootymcbootface untouched. +You can still flash firmware via UF2 (when using RP2040, on nRF52840 the UF2 bootloader was overwritten by bootymcbootface) or probe-rs — as long as it was built with the correct `memory.x` for the embassy-boot partition layout (i.e. with `dfu_rp` or `dfu_nrf` feature), it will land in the active firmware slot and leave bootymcbootface untouched. If you flash a RMK firmware built with a **normal** `memory.x` (without embassy-boot), it will start at flash address `0x0` and **overwrite bootymcbootface**. ::: -::: tip -the embassy-boot bootloader and RMK will never overwrite the RP2040’s uf2 bootloader. It exists in ROM and can not be overwritten +::: tip +On RP2040 the UF2 bootloader lives in ROM and can't be overwritten. On nRF52840 with the Adafruit UF2 bootloader, flashing bootymcbootface via UF2 **overwrites** it — use DFU or probe-rs for subsequent uploads. +::: + +::: tip +On nRF52840, DFU and BLE can be used **simultaneously**. Enable both `dfu_nrf` and `nrf52840_ble` features in RMK, set `[ble] enabled = true` in `keyboard.toml`, and your keyboard works over USB + BLE with DFU updates (over USB). ::: ## Step-by-step guide @@ -76,35 +91,54 @@ The first time, you need to flash the bootloader first, then RMK. #### 1. Flash bootymcbootface -**Method A – via UF2:** +**RP2040 – via UF2:** 1. Put your RP2040 into bootloader mode (hold BOOTSEL button, plug in USB, release) 2. A USB drive named `RPI-RP2` should appear 3. Copy the matching `bootymcbootface-rp2040-mb.uf2` to the drive 4. The RP2040 reboots – the bootloader is now active -**Method B – via debug probe (probe-rs):** +**nRF52840 – via UF2:** +1. Double-tap the reset pin (connect to GND twice within 500 ms) — the LED pulses and a `NICENANO` drive appears +2. Copy `bootymcbootface-nrf52840.uf2` to the drive +3. The board reboots — the bootloader is now active +⚠️ This **overwrites** the Adafruit UF2 bootloader on the nRF52840. + +**Via debug probe (probe-rs):** ```shell -probe-rs run --chip RP2040 bootymcbootface_ (elf) -# or -cargo run --release // in the bootymcbootface project directory +# in the bootymcbootface directory +cargo build --relese +# RP2040 +probe-rs run --chip RP2040 target/thumbv6m-none-eabi/release/bootymcbootface +# nRF52840 +probe-rs run --chip nRF52840_xxAA target/thumbv7em-none-eabihf/release/bootymcbootface +# or build and run inside the bootymcbootface project: +cargo run --release --target thumbv6m-none-eabi --features rp2040-2mb # RP2040 +cargo run --release --target thumbv7em-none-eabihf --features nrf52840 # nRF52840 ``` -(Make sure your project targets the bootloader binary) #### 2. Flash RMK firmware Now flash the actual RMK firmware. The bootloader stays in place. **Method A – via UF2:** -Put the board into bootloader mode (hold BOOTSEL button, plug in USB, release), then copy the RMK firmware `.uf2` file to the appearing `RPI-RP2` drive. +- **RP2040**: Put the board into bootloader mode (hold BOOTSEL button, plug in USB, release), then copy the RMK firmware `.uf2` file to the appearing `RPI-RP2` drive. +- **nRF52840**: Since the Adafruit bootloader was overwritten when flashing the bootymcbootface bootloader, this method does not work for nRF52840 anymore. **Method B – via debug probe (probe-rs):** ```shell +# in your RMK firmware directory +# RP2040 probe-rs run --chip RP2040 target/thumbv6m-none-eabi/release/your-firmware +# nRF52840 +probe-rs run --chip nRF52840_xxAA target/thumbv7em-none-eabihf/release/your-firmware + +# or (for both RP2040 and nRF52840) +cargo run --release ``` ### All subsequent updates via DFU -Once bootymcbootface and the RMK firmware have been flashed once, all future updates can be done **easily over USB via DFU**. +Once bootymcbootface and the RMK firmware have been flashed once, all future updates can be done **easily over USB via DFU**. (but as stated above, as long as the `memory.x` of your firmware fits, you can still use probe-rs (RP2040 and nRF52840) or the UF2 bootloader (RP2040)) #### Generate the .bin file @@ -112,24 +146,27 @@ DFU flashing requires a `.bin` file (not `.elf` or `.uf2`). You have two options **Option 1 – using `rust-objcopy` (or `arm-none-eabi-objcopy`):** ```shell +# RP2040 (thumbv6m-none-eabi) rust-objcopy -O binary target/thumbv6m-none-eabi/release/your-firmware your-firmware.bin +# nRF52840 (thumbv7em-none-eabihf) +rust-objcopy -O binary target/thumbv7em-none-eabihf/release/your-firmware your-firmware.bin ``` **Option 2 – using `cargo make bin`:** ```shell cargo make bin --release ``` -(Requires a `Makefile.toml` with a `bin` task — the generated template from `rmkit` already includes one.) +(Requires a `Makefile.toml` with a `bin` task — the generated template from `rmkit` and the examples already include one or see embassy-boot examples.) #### Flash via dfu-util ```shell -dfu-util -a 0 -d ,, -D your-firmware.bin +dfu-util -D your-firmware.bin -R ``` -Or with a device ID if multiple devices are connected: +Or with a device ID if multiple DFU devices are connected: ```shell -dfu-util -a 0 -d 1209:1234 -D your-firmware.bin +dfu-util -d 4c4b:4643 -D your-firmware.bin ``` Find your device's VID:PID via `lsusb` on Linux or Device Manager (under "Universal Serial Bus devices") on Windows. @@ -157,10 +194,20 @@ If you don't press the unlock keys within the first 10 seconds, the window close If an LED pin is configured in `keyboard.toml` (default PIN_25, if not `[dfu] led = "none"`): -| State | LED behavior | -|---|---|---| -| Unlock window open (waiting for keys) | Solid on | -| DFU unlocked (ready for dfu-util) | Blinks Morse "D F U" | -| DFU download started | On | -| Writing data blocks | Toggles on each block (flickers) | -| DFU finished / system reset | Off | +| State | LED behavior | +|---------------------------------------|----------------------------------| +| Unlock window open (waiting for keys) | Solid on | +| DFU unlocked (ready for dfu-util) | Blinks Morse "D F U" | +| DFU download started | On | +| Writing data blocks | Toggles on each block (flickers) | +| DFU finished / system reset | Off | + +Additionally the bootymcbootface bootloader has blinking codes using PIN_25 (RP2040) / P0_15 (nRF52840) as well: +| State | LED behavior | +|------------------------------------------------------------------------------------------------------------|------------------------------------| +| Normal boot — bootloader ran and jumped to ACTIVE | 2 short blinks (≈2 Hz) | +| Bootloader detected a pending DFU→ACTIVE swap and is about to copy | 1 s solid on | +| Previous forward swap completed but the new app did not call =mark_booted()= — reverting to the old ACTIVE | 3 short blinks (50 ms) | +| Successful DFU→ACTIVE copy; about to jump | 5 short blinks (50 ms) | +| Bootloader itself panicked (e.g. flash read error, invalid state partition) | Morse SOS (... --- ...), repeating | + diff --git a/examples/use_config/nrf52840_embassy_boot/.cargo/config.toml b/examples/use_config/nrf52840_embassy_boot/.cargo/config.toml new file mode 100644 index 000000000..dd91ba412 --- /dev/null +++ b/examples/use_config/nrf52840_embassy_boot/.cargo/config.toml @@ -0,0 +1,12 @@ +[target.'cfg(all(target_arch = "arm", target_os = "none"))'] +runner = "probe-rs run --chip nRF52840_xxAA" + +# Use flip-link overflow check: https://github.com/knurling-rs/flip-link +linker = "flip-link" + +[build] +target = "thumbv7em-none-eabihf" + +[env] +DEFMT_LOG = "debug" +KEYBOARD_TOML_PATH = { value = "keyboard.toml", relative = true } diff --git a/examples/use_config/nrf52840_embassy_boot/Cargo.lock b/examples/use_config/nrf52840_embassy_boot/Cargo.lock new file mode 100644 index 000000000..ffb448dc5 --- /dev/null +++ b/examples/use_config/nrf52840_embassy_boot/Cargo.lock @@ -0,0 +1,2788 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 4 + +[[package]] +name = "aes" +version = "0.8.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b169f7a6d4742236a0a00c541b845991d0ac43e546831af1249753ab4c3aa3a0" +dependencies = [ + "cfg-if", + "cipher", + "cpufeatures", +] + +[[package]] +name = "ahash" +version = "0.8.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5a15f179cd60c4584b8a8c596927aadc462e27f2ca70c04e0071964a73ba7a75" +dependencies = [ + "cfg-if", + "once_cell", + "version_check", + "zerocopy", +] + +[[package]] +name = "aho-corasick" +version = "1.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ddd31a130427c27518df266943a5308ed92d4b226cc639f5a8f1002816174301" +dependencies = [ + "memchr", +] + +[[package]] +name = "arraydeque" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7d902e3d592a523def97af8f317b08ce16b7ab854c1985a0c671e6f15cebc236" + +[[package]] +name = "async-trait" +version = "0.1.89" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9035ad2d096bed7955a320ee7e2230574d28fd3c3a0f186cbea1ff3c7eed5dbb" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.118", +] + +[[package]] +name = "atomic-polyfill" +version = "1.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8cf2bce30dfe09ef0bfaef228b9d414faaf7e563035494d7fe092dba54b300f4" +dependencies = [ + "critical-section", +] + +[[package]] +name = "autocfg" +version = "1.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f2032f911046de80f0a198e0901378627c33f59ea0ac00e363d481118bd70a53" + +[[package]] +name = "az" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "be5eb007b7cacc6c660343e96f650fedf4b5a77512399eb952ca6642cf8d13f7" + +[[package]] +name = "bare-metal" +version = "0.2.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5deb64efa5bd81e31fcd1938615a6d98c82eafcbcd787162b6f63b91d6bac5b3" +dependencies = [ + "rustc_version 0.2.3", +] + +[[package]] +name = "base16ct" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4c7f02d4ea65f2c1853089ffd8d2787bdbc63de2f0d29dedbcf8ccdfa0ccd4cf" + +[[package]] +name = "bindgen" +version = "0.72.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "993776b509cfb49c750f11b8f07a46fa23e0a1386ffc01fb1e7d343efc387895" +dependencies = [ + "bitflags 2.13.0", + "cexpr", + "clang-sys", + "itertools", + "log", + "prettyplease", + "proc-macro2", + "quote", + "regex", + "rustc-hash", + "shlex 1.3.0", + "syn 2.0.118", +] + +[[package]] +name = "bitfield" +version = "0.13.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "46afbd2983a5d5a7bd740ccb198caf5b82f45c40c09c0eed36052d91cb92e719" + +[[package]] +name = "bitfield" +version = "0.14.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2d7e60934ceec538daadb9d8432424ed043a904d8e0243f3c6446bce549a46ac" + +[[package]] +name = "bitfield-struct" +version = "0.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3ca6739863c590881f038d033a146c51ddae239186a4327014839fd864f44ed5" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.118", +] + +[[package]] +name = "bitflags" +version = "1.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" + +[[package]] +name = "bitflags" +version = "2.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b4388bee8683e3d04af747c73422af53102d2bd24d9eadb6cbc100baef4b43f8" +dependencies = [ + "serde_core", +] + +[[package]] +name = "block-buffer" +version = "0.10.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3078c7629b62d3f0439517fa394996acacc5cbc91c5a20d8c658e77abd503a71" +dependencies = [ + "generic-array", +] + +[[package]] +name = "bt-hci" +version = "0.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "211713d2e9fb4793ce4360a712c0764264aff6be48932ccf02ca2a331c0436a9" +dependencies = [ + "btuuid", + "defmt 1.1.0", + "embassy-sync", + "embedded-io 0.7.1", + "embedded-io-async 0.7.0", + "futures-intrusive", + "heapless 0.9.3", + "serde", +] + +[[package]] +name = "btuuid" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f5f48f1e9b0aad0a4f05d17bdeae0fa20ff798e272a03a6940ca27ad9c5a6ae7" +dependencies = [ + "defmt 0.3.100", + "serde", + "uuid", +] + +[[package]] +name = "bumpalo" +version = "3.20.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "72f5acc6cb2ba439de613abc23857ec3d78374d8ed5ac84e9d11336e87da8649" + +[[package]] +name = "bytemuck" +version = "1.25.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c8efb64bd706a16a1bdde310ae86b351e4d21550d98d056f22f8a7f7a2183fec" + +[[package]] +name = "byteorder" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" + +[[package]] +name = "cargo_toml" +version = "0.22.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "374b7c592d9c00c1f4972ea58390ac6b18cbb6ab79011f3bdc90a0b82ca06b77" +dependencies = [ + "serde", + "toml 0.9.12+spec-1.1.0", +] + +[[package]] +name = "cc" +version = "1.2.64" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dad887fd958be91b5098c0248def011f4523ab786cd411be668777e55063501f" +dependencies = [ + "find-msvc-tools", + "shlex 2.0.1", +] + +[[package]] +name = "cexpr" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6fac387a98bb7c37292057cffc56d62ecb629900026402633ae9160df93a8766" +dependencies = [ + "nom", +] + +[[package]] +name = "cfg-if" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9330f8b2ff13f34540b44e946ef35111825727b38d33286ef986142615121801" + +[[package]] +name = "cipher" +version = "0.4.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "773f3b9af64447d2ce9850330c473515014aa235e6a783b02db81ff39e4a3dad" +dependencies = [ + "crypto-common", + "inout", +] + +[[package]] +name = "clang-sys" +version = "1.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b023947811758c97c59bf9d1c188fd619ad4718dcaa767947df1cadb14f39f4" +dependencies = [ + "glob", + "libc", + "libloading", +] + +[[package]] +name = "cmac" +version = "0.7.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8543454e3c3f5126effff9cd44d562af4e31fb8ce1cc0d3dcd8f084515dbc1aa" +dependencies = [ + "cipher", + "dbl", + "digest", +] + +[[package]] +name = "cobs" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0fa961b519f0b462e3a3b4a34b64d119eeaca1d59af726fe450bbba07a9fc0a1" +dependencies = [ + "thiserror", +] + +[[package]] +name = "config" +version = "0.15.24" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b34d0237145f33580b89724f75d16950efd3e2c91b2d823917ecb69ec7f84f0" +dependencies = [ + "async-trait", + "convert_case 0.6.0", + "json5", + "pathdiff", + "ron", + "rust-ini", + "serde-untagged", + "serde_core", + "serde_json", + "toml 1.1.2+spec-1.1.0", + "winnow 1.0.3", + "yaml-rust2", +] + +[[package]] +name = "const-gen" +version = "1.6.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a0bb51eeea292ceb9bf5312b4416c1b151b130502e6892a2ae174ae1e4b51e58" +dependencies = [ + "const-gen-derive", +] + +[[package]] +name = "const-gen-derive" +version = "1.1.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eabc01a5585d36649b6bee1f1198d112a7bb4982661d6c18406fba571ce3263e" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "const-oid" +version = "0.9.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c2459377285ad874054d797f3ccebf984978aa39129f6eafde5cdc8315b612f8" + +[[package]] +name = "const-random" +version = "0.1.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "87e00182fe74b066627d63b85fd550ac2998d4b0bd86bfed477a0ae4c7c71359" +dependencies = [ + "const-random-macro", +] + +[[package]] +name = "const-random-macro" +version = "0.1.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f9d839f2a20b0aee515dc581a6172f2321f96cab76c1a38a4c584a194955390e" +dependencies = [ + "getrandom", + "once_cell", + "tiny-keccak", +] + +[[package]] +name = "convert_case" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ec182b0ca2f35d8fc196cf3404988fd8b8c739a4d270ff118a398feb0cbec1ca" +dependencies = [ + "unicode-segmentation", +] + +[[package]] +name = "convert_case" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "baaaa0ecca5b51987b9423ccdc971514dd8b0bb7b4060b983d3664dad3f1f89f" +dependencies = [ + "unicode-segmentation", +] + +[[package]] +name = "cordyceps" +version = "0.3.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "688d7fbb8092b8de775ef2536f36c8c31f2bc4006ece2e8d8ad2d17d00ce0a2a" +dependencies = [ + "loom", + "tracing", +] + +[[package]] +name = "cortex-m" +version = "0.7.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8ec610d8f49840a5b376c69663b6369e71f4b34484b9b2eb29fb918d92516cb9" +dependencies = [ + "bare-metal", + "bitfield 0.13.2", + "critical-section", + "embedded-hal 0.2.7", + "volatile-register", +] + +[[package]] +name = "cortex-m-rt" +version = "0.7.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "801d4dec46b34c299ccf6b036717ae0fce602faa4f4fe816d9013b9a7c9f5ba6" +dependencies = [ + "cortex-m-rt-macros", +] + +[[package]] +name = "cortex-m-rt-macros" +version = "0.7.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e37549a379a9e0e6e576fd208ee60394ccb8be963889eebba3ffe0980364f472" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.118", +] + +[[package]] +name = "cpufeatures" +version = "0.2.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "59ed5838eebb26a2bb2e58f6d5b5316989ae9d08bab10e0e6d103e656d1b0280" +dependencies = [ + "libc", +] + +[[package]] +name = "crc32fast" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9481c1c90cbf2ac953f07c8d4a58aa3945c425b7185c9154d67a65e4230da511" +dependencies = [ + "cfg-if", +] + +[[package]] +name = "critical-section" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "790eea4361631c5e7d22598ecd5723ff611904e3344ce8720784c93e3d83d40b" + +[[package]] +name = "crunchy" +version = "0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "460fbee9c2c2f33933d720630a6a0bac33ba7053db5344fac858d4b8952d77d5" + +[[package]] +name = "crypto-bigint" +version = "0.5.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0dc92fb57ca44df6db8059111ab3af99a63d5d0f8375d9972e319a379c6bab76" +dependencies = [ + "generic-array", + "rand_core 0.6.4", + "subtle", + "zeroize", +] + +[[package]] +name = "crypto-common" +version = "0.1.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "78c8292055d1c1df0cce5d180393dc8cce0abec0a7102adb6c7b1eef6016d60a" +dependencies = [ + "generic-array", + "typenum", +] + +[[package]] +name = "darling" +version = "0.20.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fc7f46116c46ff9ab3eb1597a45688b6715c6e628b5c133e288e709a29bcb4ee" +dependencies = [ + "darling_core 0.20.11", + "darling_macro 0.20.11", +] + +[[package]] +name = "darling" +version = "0.23.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "25ae13da2f202d56bd7f91c25fba009e7717a1e4a1cc98a76d844b65ae912e9d" +dependencies = [ + "darling_core 0.23.0", + "darling_macro 0.23.0", +] + +[[package]] +name = "darling_core" +version = "0.20.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0d00b9596d185e565c2207a0b01f8bd1a135483d02d9b7b0a54b11da8d53412e" +dependencies = [ + "fnv", + "ident_case", + "proc-macro2", + "quote", + "strsim", + "syn 2.0.118", +] + +[[package]] +name = "darling_core" +version = "0.23.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9865a50f7c335f53564bb694ef660825eb8610e0a53d3e11bf1b0d3df31e03b0" +dependencies = [ + "ident_case", + "proc-macro2", + "quote", + "strsim", + "syn 2.0.118", +] + +[[package]] +name = "darling_macro" +version = "0.20.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fc34b93ccb385b40dc71c6fceac4b2ad23662c7eeb248cf10d529b7e055b6ead" +dependencies = [ + "darling_core 0.20.11", + "quote", + "syn 2.0.118", +] + +[[package]] +name = "darling_macro" +version = "0.23.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ac3984ec7bd6cfa798e62b4a642426a5be0e68f9401cfc2a01e3fa9ea2fcdb8d" +dependencies = [ + "darling_core 0.23.0", + "quote", + "syn 2.0.118", +] + +[[package]] +name = "dbl" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bd2735a791158376708f9347fe8faba9667589d82427ef3aed6794a8981de3d9" +dependencies = [ + "generic-array", +] + +[[package]] +name = "defmt" +version = "0.3.100" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f0963443817029b2024136fc4dd07a5107eb8f977eaf18fcd1fdeb11306b64ad" +dependencies = [ + "defmt 1.1.0", +] + +[[package]] +name = "defmt" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a6e524506490a1953d237cb87b1cfc1e46f88c18f10a22dfe0f507dc6bfc7f7f" +dependencies = [ + "bitflags 1.3.2", + "defmt-macros", +] + +[[package]] +name = "defmt-macros" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f0a27770e9c8f719a79d8b638281f4d828f77d8fd61e0bd94451b9b85e576a0b" +dependencies = [ + "defmt-parser", + "proc-macro-error2", + "proc-macro2", + "quote", + "syn 2.0.118", +] + +[[package]] +name = "defmt-parser" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "10d60334b3b2e7c9d91ef8150abfb6fa4c1c39ebbcf4a81c2e346aad939fee3e" +dependencies = [ + "thiserror", +] + +[[package]] +name = "defmt-rtt" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c0f73a4a4a91609e977ae3b7bd831ffa292edfd42ad140a3244a61d805b0e05e" +dependencies = [ + "critical-section", + "defmt 1.1.0", +] + +[[package]] +name = "der" +version = "0.7.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e7c1832837b905bbfb5101e07cc24c8deddf52f93225eee6ead5f4d63d53ddcb" +dependencies = [ + "const-oid", + "zeroize", +] + +[[package]] +name = "digest" +version = "0.10.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292" +dependencies = [ + "block-buffer", + "crypto-common", + "subtle", +] + +[[package]] +name = "dlv-list" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "442039f5147480ba31067cb00ada1adae6892028e40e45fc5de7b7df6dcc1b5f" +dependencies = [ + "const-random", +] + +[[package]] +name = "document-features" +version = "0.2.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d4b8a88685455ed29a21542a33abd9cb6510b6b129abadabdcef0f4c55bc8f61" +dependencies = [ + "litrs", +] + +[[package]] +name = "doxygen-rs" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "415b6ec780d34dcf624666747194393603d0373b7141eef01d12ee58881507d9" +dependencies = [ + "phf", +] + +[[package]] +name = "either" +version = "1.16.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "91622ff5e7162018101f2fea40d6ebf4a78bbe5a49736a2020649edf9693679e" + +[[package]] +name = "elliptic-curve" +version = "0.13.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b5e6043086bf7973472e0c7dff2142ea0b680d30e18d9cc40f267efbf222bd47" +dependencies = [ + "base16ct", + "crypto-bigint", + "digest", + "ff", + "generic-array", + "group", + "hkdf", + "rand_core 0.6.4", + "sec1", + "subtle", + "zeroize", +] + +[[package]] +name = "embassy-boot" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "73bfc955c9238df2ce9fecc6f18a64b13ecaa41a3cd42d940a09f304765d10db" +dependencies = [ + "digest", + "document-features", + "embassy-embedded-hal", + "embassy-sync", + "embedded-storage", + "embedded-storage-async", + "signature", +] + +[[package]] +name = "embassy-embedded-hal" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b0641612053b2f34fc250bb63f6630ae75de46e02ade7f457268447081d709ce" +dependencies = [ + "defmt 1.1.0", + "embassy-futures", + "embassy-hal-internal 0.4.0", + "embassy-sync", + "embassy-time", + "embedded-hal 0.2.7", + "embedded-hal 1.0.0", + "embedded-hal-async", + "embedded-storage", + "embedded-storage-async", + "nb 1.1.0", +] + +[[package]] +name = "embassy-executor" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5d0d3b15c9d7dc4fec1d8cb77112472fb008b3b28c51ad23838d83587a6d2f1e" +dependencies = [ + "cordyceps", + "cortex-m", + "critical-section", + "defmt 1.1.0", + "document-features", + "embassy-executor-macros", + "embassy-executor-timer-queue", +] + +[[package]] +name = "embassy-executor-macros" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d11a246f53de5f97a387f40ac24726817cd0b6f833e7603baac784f29d6ff276" +dependencies = [ + "darling 0.20.11", + "proc-macro2", + "quote", + "syn 2.0.118", +] + +[[package]] +name = "embassy-executor-timer-queue" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2fc328bf943af66b80b98755db9106bf7e7471b0cf47dc8559cd9a6be504cc9c" + +[[package]] +name = "embassy-futures" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dc2d050bdc5c21e0862a89256ed8029ae6c290a93aecefc73084b3002cdebb01" +dependencies = [ + "defmt 1.1.0", +] + +[[package]] +name = "embassy-hal-internal" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7f10ce10a4dfdf6402d8e9bd63128986b96a736b1a0a6680547ed2ac55d55dba" +dependencies = [ + "num-traits", +] + +[[package]] +name = "embassy-hal-internal" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "568659fc53866d3d85c60fa33723fb751aa69e71507634fc2c19e7649432fb75" +dependencies = [ + "cortex-m", + "critical-section", + "defmt 1.1.0", + "num-traits", +] + +[[package]] +name = "embassy-net-driver" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "524eb3c489760508f71360112bca70f6e53173e6fe48fc5f0efd0f5ab217751d" + +[[package]] +name = "embassy-net-driver-channel" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a07d2eb9f05a6fc876500949856ea1be40773d866d8cb99384f72d0ae4568c16" +dependencies = [ + "embassy-futures", + "embassy-net-driver", + "embassy-sync", +] + +[[package]] +name = "embassy-nrf" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b715380574504335c40ec3016bc44598fac3c385f82959b26c41b25c30b7648d" +dependencies = [ + "bitflags 2.13.0", + "cfg-if", + "cortex-m", + "cortex-m-rt", + "critical-section", + "defmt 1.1.0", + "document-features", + "embassy-embedded-hal", + "embassy-futures", + "embassy-hal-internal 0.5.0", + "embassy-sync", + "embassy-time", + "embassy-time-driver", + "embassy-time-queue-utils", + "embassy-usb-driver", + "embedded-hal 0.2.7", + "embedded-hal 1.0.0", + "embedded-hal-async", + "embedded-io 0.7.1", + "embedded-io-async 0.7.0", + "embedded-storage", + "embedded-storage-async", + "fixed", + "nrf-pac", + "rand_core 0.6.4", + "rand_core 0.9.5", +] + +[[package]] +name = "embassy-sync" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7bbd85cf5a5ae56bdf26f618364af642d1d0a4e245cdd75cd9aabda382f65a81" +dependencies = [ + "cfg-if", + "critical-section", + "defmt 1.1.0", + "embedded-io-async 0.7.0", + "futures-core", + "futures-sink", + "heapless 0.9.3", +] + +[[package]] +name = "embassy-time" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "592b0c143ec626e821d4d90da51a2bd91d559d6c442b7c74a47d368c9e23d97a" +dependencies = [ + "cfg-if", + "critical-section", + "defmt 1.1.0", + "document-features", + "embassy-time-driver", + "embedded-hal 0.2.7", + "embedded-hal 1.0.0", + "embedded-hal-async", + "futures-core", +] + +[[package]] +name = "embassy-time-driver" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6ee71af1b3a0deaa53eaf2d39252f83504c853646e472400b763060389b9fcc9" +dependencies = [ + "document-features", +] + +[[package]] +name = "embassy-time-queue-utils" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "168297bf80aaf114b3c9ad589bf38b01b3009b9af7f97cd18086c5bbf96f5693" +dependencies = [ + "embassy-executor-timer-queue", + "heapless 0.9.3", +] + +[[package]] +name = "embassy-usb" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a25746d8b152b72fbf2a217f489a083dbbe243f281f09184a1f2cfbe9bbb245f" +dependencies = [ + "bitflags 2.13.0", + "defmt 1.1.0", + "embassy-futures", + "embassy-net-driver-channel", + "embassy-sync", + "embassy-time", + "embassy-usb-driver", + "embedded-io-async 0.7.0", + "heapless 0.9.3", + "ssmarshal", + "usbd-hid", +] + +[[package]] +name = "embassy-usb-dfu" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e36d3678d16e1e71b052d00f7518620b5839a878f2bdab2019b81d984fb2a74f" +dependencies = [ + "bitflags 2.13.0", + "cortex-m", + "embassy-boot", + "embassy-futures", + "embassy-sync", + "embassy-time", + "embassy-usb", + "embedded-storage", +] + +[[package]] +name = "embassy-usb-driver" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fa675c5f4349b6aa0fcffc4bf9b241f18cd11b97c1f8323273fb9a5449937fbd" +dependencies = [ + "defmt 1.1.0", + "embedded-io-async 0.6.1", + "embedded-io-async 0.7.0", +] + +[[package]] +name = "embedded-hal" +version = "0.2.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "35949884794ad573cf46071e41c9b60efb0cb311e3ca01f7af807af1debc66ff" +dependencies = [ + "nb 0.1.3", + "void", +] + +[[package]] +name = "embedded-hal" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "361a90feb7004eca4019fb28352a9465666b24f840f5c3cddf0ff13920590b89" +dependencies = [ + "defmt 0.3.100", +] + +[[package]] +name = "embedded-hal-async" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0c4c685bbef7fe13c3c6dd4da26841ed3980ef33e841cddfa15ce8a8fb3f1884" +dependencies = [ + "defmt 0.3.100", + "embedded-hal 1.0.0", +] + +[[package]] +name = "embedded-io" +version = "0.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "edd0f118536f44f5ccd48bcb8b111bdc3de888b58c74639dfb034a357d0f206d" + +[[package]] +name = "embedded-io" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9eb1aa714776b75c7e67e1da744b81a129b3ff919c8712b5e1b32252c1f07cc7" +dependencies = [ + "defmt 1.1.0", +] + +[[package]] +name = "embedded-io-async" +version = "0.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3ff09972d4073aa8c299395be75161d582e7629cd663171d62af73c8d50dba3f" +dependencies = [ + "embedded-io 0.6.1", +] + +[[package]] +name = "embedded-io-async" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2564b9f813c544241430e147d8bc454815ef9ac998878d30cc3055449f7fd4c0" +dependencies = [ + "defmt 1.1.0", + "embedded-io 0.7.1", +] + +[[package]] +name = "embedded-storage" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a21dea9854beb860f3062d10228ce9b976da520a73474aed3171ec276bc0c032" + +[[package]] +name = "embedded-storage-async" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1763775e2323b7d5f0aa6090657f5e21cfa02ede71f5dc40eead06d64dcd15cc" +dependencies = [ + "embedded-storage", +] + +[[package]] +name = "encode_unicode" +version = "0.3.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a357d28ed41a50f9c765dbfe56cbc04a64e53e5fc58ba79fbc34c10ef3df831f" + +[[package]] +name = "encoding_rs" +version = "0.8.35" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "75030f3c4f45dafd7586dd6780965a8c7e8e285a5ecb86713e63a79c5b2766f3" +dependencies = [ + "cfg-if", +] + +[[package]] +name = "equivalent" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "877a4ace8713b0bcf2a4e7eec82529c029f1d0619886d18145fea96c3ffe5c0f" + +[[package]] +name = "erased-serde" +version = "0.4.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d2add8a07dd6a8d93ff627029c51de145e12686fbc36ecb298ac22e74cf02dec" +dependencies = [ + "serde", + "serde_core", + "typeid", +] + +[[package]] +name = "ff" +version = "0.13.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c0b50bfb653653f9ca9095b427bed08ab8d75a137839d9ad64eb11810d5b6393" +dependencies = [ + "rand_core 0.6.4", + "subtle", +] + +[[package]] +name = "find-msvc-tools" +version = "0.1.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5baebc0774151f905a1a2cc41989300b1e6fbb29aff0ceffa1064fdd3088d582" + +[[package]] +name = "fixed" +version = "1.31.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9af2cbf772fa6d1c11358f92ef554cb6b386201210bcf0e91fb7fba8a907fb40" +dependencies = [ + "az", + "bytemuck", + "half", + "typenum", +] + +[[package]] +name = "fnv" +version = "1.0.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" + +[[package]] +name = "foldhash" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "77ce24cb58228fbb8aa041425bb1050850ac19177686ea6e0f41a70416f56fdb" + +[[package]] +name = "futures" +version = "0.3.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8b147ee9d1f6d097cef9ce628cd2ee62288d963e16fb287bd9286455b241382d" +dependencies = [ + "futures-channel", + "futures-core", + "futures-io", + "futures-sink", + "futures-task", + "futures-util", +] + +[[package]] +name = "futures-channel" +version = "0.3.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "07bbe89c50d7a535e539b8c17bc0b49bdb77747034daa8087407d655f3f7cc1d" +dependencies = [ + "futures-core", + "futures-sink", +] + +[[package]] +name = "futures-core" +version = "0.3.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7e3450815272ef58cec6d564423f6e755e25379b217b0bc688e295ba24df6b1d" + +[[package]] +name = "futures-intrusive" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1d930c203dd0b6ff06e0201a4a2fe9149b43c684fd4420555b26d21b1a02956f" +dependencies = [ + "futures-core", + "lock_api", +] + +[[package]] +name = "futures-io" +version = "0.3.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cecba35d7ad927e23624b22ad55235f2239cfa44fd10428eecbeba6d6a717718" + +[[package]] +name = "futures-macro" +version = "0.3.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e835b70203e41293343137df5c0664546da5745f82ec9b84d40be8336958447b" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.118", +] + +[[package]] +name = "futures-sink" +version = "0.3.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c39754e157331b013978ec91992bde1ac089843443c49cbc7f46150b0fad0893" + +[[package]] +name = "futures-task" +version = "0.3.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "037711b3d59c33004d3856fbdc83b99d4ff37a24768fa1be9ce3538a1cde4393" + +[[package]] +name = "futures-util" +version = "0.3.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "389ca41296e6190b48053de0321d02a77f32f8a5d2461dd38762c0593805c6d6" +dependencies = [ + "futures-core", + "futures-macro", + "futures-sink", + "futures-task", + "pin-project-lite", + "slab", +] + +[[package]] +name = "generator" +version = "0.8.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b3b854b0e584ead1a33f18b2fcad7cf7be18b3875c78816b753639aa501513ae" +dependencies = [ + "cc", + "cfg-if", + "libc", + "log", + "rustversion", + "windows-link", + "windows-result", +] + +[[package]] +name = "generic-array" +version = "0.14.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "85649ca51fd72272d7821adaf274ad91c288277713d9c18820d8499a7ff69e9a" +dependencies = [ + "typenum", + "version_check", + "zeroize", +] + +[[package]] +name = "getrandom" +version = "0.2.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ff2abc00be7fca6ebc474524697ae276ad847ad0a6b3faa4bcb027e9a4614ad0" +dependencies = [ + "cfg-if", + "libc", + "wasi", +] + +[[package]] +name = "glob" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0cc23270f6e1808e30a928bdc84dea0b9b4136a8bc82338574f23baf47bbd280" + +[[package]] +name = "group" +version = "0.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f0f9ef7462f7c099f518d754361858f86d8a07af53ba9af0fe635bbccb151a63" +dependencies = [ + "ff", + "rand_core 0.6.4", + "subtle", +] + +[[package]] +name = "half" +version = "2.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6ea2d84b969582b4b1864a92dc5d27cd2b77b622a8d79306834f1be5ba20d84b" +dependencies = [ + "cfg-if", + "crunchy", + "zerocopy", +] + +[[package]] +name = "hash32" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b0c35f58762feb77d74ebe43bdbc3210f09be9fe6742234d573bacc26ed92b67" +dependencies = [ + "byteorder", +] + +[[package]] +name = "hash32" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "47d60b12902ba28e2730cd37e95b8c9223af2808df9e902d4df49588d1470606" +dependencies = [ + "byteorder", +] + +[[package]] +name = "hashbrown" +version = "0.13.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "43a3c133739dddd0d2990f9a4bdf8eb4b21ef50e4851ca85ab661199821d510e" +dependencies = [ + "ahash", +] + +[[package]] +name = "hashbrown" +version = "0.14.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e5274423e17b7c9fc20b6e7e208532f9b19825d82dfd615708b70edd83df41f1" + +[[package]] +name = "hashbrown" +version = "0.16.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "841d1cc9bed7f9236f321df977030373f4a4163ae1a7dbfe1a51a2c1a51d9100" +dependencies = [ + "foldhash", +] + +[[package]] +name = "hashbrown" +version = "0.17.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ed5909b6e89a2db4456e54cd5f673791d7eca6732202bbf2a9cc504fe2f9b84a" + +[[package]] +name = "hashlink" +version = "0.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "824e001ac4f3012dd16a264bec811403a67ca9deb6c102fc5049b32c4574b35f" +dependencies = [ + "hashbrown 0.16.1", +] + +[[package]] +name = "heapless" +version = "0.7.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cdc6457c0eb62c71aac4bc17216026d8410337c4126773b9c5daba343f17964f" +dependencies = [ + "atomic-polyfill", + "hash32 0.2.1", + "rustc_version 0.4.1", + "serde", + "spin", + "stable_deref_trait", +] + +[[package]] +name = "heapless" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0bfb9eb618601c89945a70e254898da93b13be0388091d42117462b265bb3fad" +dependencies = [ + "hash32 0.3.1", + "stable_deref_trait", +] + +[[package]] +name = "heapless" +version = "0.9.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "25ba4bd83f9415b58b4ed8dc5714c76e626a105be4646c02630ad730ad3b5aa4" +dependencies = [ + "defmt 1.1.0", + "hash32 0.3.1", + "serde_core", + "stable_deref_trait", +] + +[[package]] +name = "heck" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea" + +[[package]] +name = "hkdf" +version = "0.12.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7b5f8eb2ad728638ea2c7d47a21db23b7b58a72ed6a38256b8a1849f15fbbdf7" +dependencies = [ + "hmac", +] + +[[package]] +name = "hmac" +version = "0.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6c49c37c09c17a53d937dfbb742eb3a961d65a994e6bcdcf37e7399d0cc8ab5e" +dependencies = [ + "digest", +] + +[[package]] +name = "ident_case" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b9e0384b61958566e926dc50660321d12159025e767c18e043daf26b70104c39" + +[[package]] +name = "indexmap" +version = "2.14.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d466e9454f08e4a911e14806c24e16fba1b4c121d1ea474396f396069cf949d9" +dependencies = [ + "equivalent", + "hashbrown 0.17.1", +] + +[[package]] +name = "inout" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "879f10e63c20629ecabbb64a8010319738c66a5cd0c29b02d63d272b03751d01" +dependencies = [ + "generic-array", +] + +[[package]] +name = "itertools" +version = "0.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "413ee7dfc52ee1a4949ceeb7dbc8a33f2d6c088194d9f922fb8318faf1f01186" +dependencies = [ + "either", +] + +[[package]] +name = "itoa" +version = "1.0.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f42a60cbdf9a97f5d2305f08a87dc4e09308d1276d28c869c684d7777685682" + +[[package]] +name = "js-sys" +version = "0.3.102" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "03d04c30968dffe80775bd4d7fb676131cd04a1fb46d2686dbffbaec2d9dfd31" +dependencies = [ + "cfg-if", + "futures-util", + "wasm-bindgen", +] + +[[package]] +name = "json" +version = "0.12.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "078e285eafdfb6c4b434e0d31e8cfcb5115b651496faca5749b88fafd4f23bfd" + +[[package]] +name = "json5" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "96b0db21af676c1ce64250b5f40f3ce2cf27e4e47cb91ed91eb6fe9350b430c1" +dependencies = [ + "pest", + "pest_derive", + "serde", +] + +[[package]] +name = "lazy_static" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe" + +[[package]] +name = "libc" +version = "0.2.186" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "68ab91017fe16c622486840e4c83c9a37afeff978bd239b5293d61ece587de66" + +[[package]] +name = "libloading" +version = "0.8.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d7c4b02199fee7c5d21a5ae7d8cfa79a6ef5bb2fc834d6e9058e89c825efdc55" +dependencies = [ + "cfg-if", + "windows-link", +] + +[[package]] +name = "litrs" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "11d3d7f243d5c5a8b9bb5d6dd2b1602c0cb0b9db1621bafc7ed66e35ff9fe092" + +[[package]] +name = "lock_api" +version = "0.4.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "224399e74b87b5f3557511d98dff8b14089b3dadafcab6bb93eab67d3aace965" +dependencies = [ + "scopeguard", +] + +[[package]] +name = "log" +version = "0.4.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "953f07c43838f8e6f9758cab68bf5bed85465e7587ebe0b823f1bcd81978ad3a" + +[[package]] +name = "loom" +version = "0.7.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "419e0dc8046cb947daa77eb95ae174acfbddb7673b4151f56d1eed8e93fbfaca" +dependencies = [ + "cfg-if", + "generator", + "scoped-tls", + "tracing", + "tracing-subscriber", +] + +[[package]] +name = "lzma-sys" +version = "0.1.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5fda04ab3764e6cde78b9974eec4f779acaba7c4e84b36eca3cf77c581b85d27" +dependencies = [ + "cc", + "libc", + "pkg-config", +] + +[[package]] +name = "matchers" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d1525a2a28c7f4fa0fc98bb91ae755d1e2d1505079e05539e35bc876b5d65ae9" +dependencies = [ + "regex-automata", +] + +[[package]] +name = "memchr" +version = "2.8.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "88904434abc2901f197fe8cc55f0445e7ded921dba5911dad2e2b39b48e663c4" + +[[package]] +name = "minimal-lexical" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a" + +[[package]] +name = "nb" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "801d31da0513b6ec5214e9bf433a77966320625a37860f910be265be6e18d06f" +dependencies = [ + "nb 1.1.0", +] + +[[package]] +name = "nb" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8d5439c4ad607c3c23abf66de8c8bf57ba8adcd1f129e699851a6e43935d339d" + +[[package]] +name = "nom" +version = "7.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d273983c5a657a70a3e8f2a01329822f3b8c8172b73826411a55751e404a0a4a" +dependencies = [ + "memchr", + "minimal-lexical", +] + +[[package]] +name = "nrf-mpsl" +version = "0.3.0" +source = "git+https://github.com/haobogu/nrf-sdc?rev=ffe59a7aefaaa145a3d2474602f33387f80dcefa#ffe59a7aefaaa145a3d2474602f33387f80dcefa" +dependencies = [ + "cfg-if", + "cortex-m", + "defmt 1.1.0", + "embassy-nrf", + "embassy-sync", + "embedded-io 0.7.1", + "embedded-storage", + "embedded-storage-async", + "nrf-mpsl-sys", +] + +[[package]] +name = "nrf-mpsl-sys" +version = "0.2.1" +source = "git+https://github.com/haobogu/nrf-sdc?rev=ffe59a7aefaaa145a3d2474602f33387f80dcefa#ffe59a7aefaaa145a3d2474602f33387f80dcefa" +dependencies = [ + "bindgen", + "doxygen-rs", +] + +[[package]] +name = "nrf-pac" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bddd547fab92b0553ff37032034fd04ce8b8b60d3f9a83f89ea815dfd0400336" +dependencies = [ + "cortex-m", + "cortex-m-rt", +] + +[[package]] +name = "nrf-sdc" +version = "0.4.0" +source = "git+https://github.com/haobogu/nrf-sdc?rev=ffe59a7aefaaa145a3d2474602f33387f80dcefa#ffe59a7aefaaa145a3d2474602f33387f80dcefa" +dependencies = [ + "bt-hci", + "critical-section", + "defmt 1.1.0", + "embassy-hal-internal 0.5.0", + "embassy-nrf", + "embassy-sync", + "embedded-io 0.7.1", + "embedded-io-async 0.7.0", + "nrf-mpsl", + "nrf-sdc-sys", + "rand_core 0.9.5", +] + +[[package]] +name = "nrf-sdc-sys" +version = "0.2.1" +source = "git+https://github.com/haobogu/nrf-sdc?rev=ffe59a7aefaaa145a3d2474602f33387f80dcefa#ffe59a7aefaaa145a3d2474602f33387f80dcefa" +dependencies = [ + "bindgen", + "doxygen-rs", + "nrf-mpsl-sys", + "winnow 0.7.15", +] + +[[package]] +name = "nu-ansi-term" +version = "0.50.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7957b9740744892f114936ab4a57b3f487491bbeafaf8083688b16841a4240e5" +dependencies = [ + "windows-sys", +] + +[[package]] +name = "num-traits" +version = "0.2.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841" +dependencies = [ + "autocfg", +] + +[[package]] +name = "once_cell" +version = "1.21.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9f7c3e4beb33f85d45ae3e3a1792185706c8e16d043238c593331cc7cd313b50" + +[[package]] +name = "ordered-multimap" +version = "0.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "49203cdcae0030493bad186b28da2fa25645fa276a51b6fec8010d281e02ef79" +dependencies = [ + "dlv-list", + "hashbrown 0.14.5", +] + +[[package]] +name = "p256" +version = "0.13.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c9863ad85fa8f4460f9c48cb909d38a0d689dba1f6f6988a5e3e0d31071bcd4b" +dependencies = [ + "elliptic-curve", + "primeorder", +] + +[[package]] +name = "panic-probe" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fd402d00b0fb94c5aee000029204a46884b1262e0c443f166d86d2c0747e1a1a" +dependencies = [ + "cortex-m", + "defmt 1.1.0", +] + +[[package]] +name = "paste" +version = "1.0.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "57c0d7b74b563b49d38dae00a0c37d4d6de9b432382b2892f0574ddcae73fd0a" + +[[package]] +name = "pathdiff" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "df94ce210e5bc13cb6651479fa48d14f601d9858cfe0467f43ae157023b938d3" + +[[package]] +name = "pest" +version = "2.8.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e0848c601009d37dfa3430c4666e147e49cdcf1b92ecd3e63657d8a5f19da662" +dependencies = [ + "memchr", + "ucd-trie", +] + +[[package]] +name = "pest_derive" +version = "2.8.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "11f486f1ea21e6c10ed15d5a7c77165d0ee443402f0780849d1768e7d9d6fe77" +dependencies = [ + "pest", + "pest_generator", +] + +[[package]] +name = "pest_generator" +version = "2.8.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8040c4647b13b210a963c1ed407c1ff4fdfa01c31d6d2a098218702e6664f94f" +dependencies = [ + "pest", + "pest_meta", + "proc-macro2", + "quote", + "syn 2.0.118", +] + +[[package]] +name = "pest_meta" +version = "2.8.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "89815c69d36021a140146f26659a81d6c2afa33d216d736dd4be5381a7362220" +dependencies = [ + "pest", + "sha2", +] + +[[package]] +name = "phf" +version = "0.11.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1fd6780a80ae0c52cc120a26a1a42c1ae51b247a253e4e06113d23d2c2edd078" +dependencies = [ + "phf_macros", + "phf_shared", +] + +[[package]] +name = "phf_generator" +version = "0.11.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3c80231409c20246a13fddb31776fb942c38553c51e871f8cbd687a4cfb5843d" +dependencies = [ + "phf_shared", + "rand", +] + +[[package]] +name = "phf_macros" +version = "0.11.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f84ac04429c13a7ff43785d75ad27569f2951ce0ffd30a3321230db2fc727216" +dependencies = [ + "phf_generator", + "phf_shared", + "proc-macro2", + "quote", + "syn 2.0.118", +] + +[[package]] +name = "phf_shared" +version = "0.11.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "67eabc2ef2a60eb7faa00097bd1ffdb5bd28e62bf39990626a582201b7a754e5" +dependencies = [ + "siphasher", +] + +[[package]] +name = "pin-project-lite" +version = "0.2.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a89322df9ebe1c1578d689c92318e070967d1042b512afbe49518723f4e6d5cd" + +[[package]] +name = "pkg-config" +version = "0.3.33" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "19f132c84eca552bf34cab8ec81f1c1dcc229b811638f9d283dceabe58c5569e" + +[[package]] +name = "portable-atomic" +version = "1.13.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c33a9471896f1c69cecef8d20cbe2f7accd12527ce60845ff44c153bb2a21b49" +dependencies = [ + "critical-section", +] + +[[package]] +name = "postcard" +version = "1.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6764c3b5dd454e283a30e6dfe78e9b31096d9e32036b5d1eaac7a6119ccb9a24" +dependencies = [ + "cobs", + "defmt 1.1.0", + "heapless 0.7.17", + "postcard-derive", + "serde", +] + +[[package]] +name = "postcard-derive" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e0232bd009a197ceec9cc881ba46f727fcd8060a2d8d6a9dde7a69030a6fe2bb" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.118", +] + +[[package]] +name = "ppv-lite86" +version = "0.2.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "85eae3c4ed2f50dcfe72643da4befc30deadb458a9b590d720cde2f2b1e97da9" +dependencies = [ + "zerocopy", +] + +[[package]] +name = "prettyplease" +version = "0.2.37" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "479ca8adacdd7ce8f1fb39ce9ecccbfe93a3f1344b3d0d97f20bc0196208f62b" +dependencies = [ + "proc-macro2", + "syn 2.0.118", +] + +[[package]] +name = "primeorder" +version = "0.13.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "353e1ca18966c16d9deb1c69278edbc5f194139612772bd9537af60ac231e1e6" +dependencies = [ + "elliptic-curve", +] + +[[package]] +name = "proc-macro-error-attr2" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "96de42df36bb9bba5542fe9f1a054b8cc87e172759a1868aa05c1f3acc89dfc5" +dependencies = [ + "proc-macro2", + "quote", +] + +[[package]] +name = "proc-macro-error2" +version = "2.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "11ec05c52be0a07b08061f7dd003e7d7092e0472bc731b4af7bb1ef876109802" +dependencies = [ + "proc-macro-error-attr2", + "proc-macro2", + "quote", + "syn 2.0.118", +] + +[[package]] +name = "proc-macro2" +version = "1.0.106" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8fd00f0bb2e90d81d1044c2b32617f68fcb9fa3bb7640c23e9c748e53fb30934" +dependencies = [ + "unicode-ident", +] + +[[package]] +name = "quote" +version = "1.0.45" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "41f2619966050689382d2b44f664f4bc593e129785a36d6ee376ddf37259b924" +dependencies = [ + "proc-macro2", +] + +[[package]] +name = "rand" +version = "0.8.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5ca0ecfa931c29007047d1bc58e623ab12e5590e8c7cc53200d5202b69266d8a" +dependencies = [ + "rand_core 0.6.4", +] + +[[package]] +name = "rand_chacha" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88" +dependencies = [ + "ppv-lite86", + "rand_core 0.6.4", +] + +[[package]] +name = "rand_core" +version = "0.6.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" + +[[package]] +name = "rand_core" +version = "0.9.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "76afc826de14238e6e8c374ddcc1fa19e374fd8dd986b0d2af0d02377261d83c" + +[[package]] +name = "regex" +version = "1.12.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f1292b7759ae1cb9ec195452d1390a074f0cd8541ab7a5a8c31cd6db45d4a6ba" +dependencies = [ + "aho-corasick", + "memchr", + "regex-automata", + "regex-syntax", +] + +[[package]] +name = "regex-automata" +version = "0.4.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6e1dd4122fc1595e8162618945476892eefca7b88c52820e74af6262213cae8f" +dependencies = [ + "aho-corasick", + "memchr", + "regex-syntax", +] + +[[package]] +name = "regex-syntax" +version = "0.8.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d6f6ff9a378485b298a5286656da665ba74413d36db0979633275d2e708145d4" + +[[package]] +name = "rmk" +version = "0.8.2" +dependencies = [ + "bt-hci", + "byteorder", + "cortex-m", + "crc32fast", + "defmt 1.1.0", + "document-features", + "embassy-boot", + "embassy-embedded-hal", + "embassy-futures", + "embassy-nrf", + "embassy-sync", + "embassy-time", + "embassy-usb", + "embassy-usb-dfu", + "embedded-hal 1.0.0", + "embedded-hal-async", + "embedded-io-async 0.7.0", + "embedded-storage", + "embedded-storage-async", + "futures", + "heapless 0.9.3", + "paste", + "postcard", + "rand_core 0.6.4", + "rmk-macro", + "rmk-types", + "sequential-storage", + "serde", + "static_cell", + "trouble-host", + "usbd-hid", +] + +[[package]] +name = "rmk-config" +version = "0.6.1" +dependencies = [ + "config", + "once_cell", + "paste", + "pest", + "pest_derive", + "serde", + "serde-inline-default", + "toml 1.1.2+spec-1.1.0", +] + +[[package]] +name = "rmk-macro" +version = "0.7.1" +dependencies = [ + "cargo_toml", + "darling 0.23.0", + "proc-macro2", + "quote", + "rmk-config", + "rmk-types", + "strum", + "syn 2.0.118", +] + +[[package]] +name = "rmk-nrf52840-embassy-boot" +version = "0.2.0" +dependencies = [ + "bt-hci", + "const-gen", + "cortex-m", + "cortex-m-rt", + "defmt 1.1.0", + "defmt-rtt", + "embassy-boot", + "embassy-executor", + "embassy-nrf", + "embassy-time", + "json", + "nrf-mpsl", + "nrf-sdc", + "panic-probe", + "portable-atomic", + "rand_chacha", + "rand_core 0.6.4", + "rmk", + "static_cell", + "xz2", +] + +[[package]] +name = "rmk-types" +version = "0.2.2" +dependencies = [ + "bitfield-struct", + "defmt 1.1.0", + "heapless 0.9.3", + "postcard", + "rmk-config", + "serde", + "strum", + "toml 1.1.2+spec-1.1.0", +] + +[[package]] +name = "ron" +version = "0.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4147b952f3f819eca0e99527022f7d6a8d05f111aeb0a62960c74eb283bec8fc" +dependencies = [ + "bitflags 2.13.0", + "once_cell", + "serde", + "serde_derive", + "typeid", + "unicode-ident", +] + +[[package]] +name = "rust-ini" +version = "0.21.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "796e8d2b6696392a43bea58116b667fb4c29727dc5abd27d6acf338bb4f688c7" +dependencies = [ + "cfg-if", + "ordered-multimap", +] + +[[package]] +name = "rustc-hash" +version = "2.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "94300abf3f1ae2e2b8ffb7b58043de3d399c73fa6f4b73826402a5c457614dbe" + +[[package]] +name = "rustc_version" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "138e3e0acb6c9fb258b19b67cb8abd63c00679d2851805ea151465464fe9030a" +dependencies = [ + "semver 0.9.0", +] + +[[package]] +name = "rustc_version" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cfcb3a22ef46e85b45de6ee7e79d063319ebb6594faafcf1c225ea92ab6e9b92" +dependencies = [ + "semver 1.0.28", +] + +[[package]] +name = "rustversion" +version = "1.0.22" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b39cdef0fa800fc44525c84ccb54a029961a8215f9619753635a9c0d2538d46d" + +[[package]] +name = "scoped-tls" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e1cf6437eb19a8f4a6cc0f7dca544973b0b78843adbfeb3683d1a94a0024a294" + +[[package]] +name = "scopeguard" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" + +[[package]] +name = "sec1" +version = "0.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d3e97a565f76233a6003f9f5c54be1d9c5bdfa3eccfb189469f11ec4901c47dc" +dependencies = [ + "base16ct", + "der", + "generic-array", + "subtle", + "zeroize", +] + +[[package]] +name = "semver" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1d7eb9ef2c18661902cc47e535f9bc51b78acd254da71d375c2f6720d9a40403" +dependencies = [ + "semver-parser", +] + +[[package]] +name = "semver" +version = "1.0.28" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8a7852d02fc848982e0c167ef163aaff9cd91dc640ba85e263cb1ce46fae51cd" + +[[package]] +name = "semver-parser" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "388a1df253eca08550bef6c72392cfe7c30914bf41df5269b68cbd6ff8f570a3" + +[[package]] +name = "sequential-storage" +version = "7.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "574e5a379bf43653079b34cb4cf32958404b5f42e0ed5b5adcdff02c2de04d4d" +dependencies = [ + "defmt 1.1.0", + "embedded-storage-async", + "postcard", + "serde", +] + +[[package]] +name = "serde" +version = "1.0.228" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9a8e94ea7f378bd32cbbd37198a4a91436180c5bb472411e48b5ec2e2124ae9e" +dependencies = [ + "serde_core", + "serde_derive", +] + +[[package]] +name = "serde-inline-default" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2bf03b7a5281cfd4013bc788d057b0f09fc634397d83bc8973c955bd4f32727a" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.118", +] + +[[package]] +name = "serde-untagged" +version = "0.1.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f9faf48a4a2d2693be24c6289dbe26552776eb7737074e6722891fadbe6c5058" +dependencies = [ + "erased-serde", + "serde", + "serde_core", + "typeid", +] + +[[package]] +name = "serde_core" +version = "1.0.228" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "41d385c7d4ca58e59fc732af25c3983b67ac852c1a25000afe1175de458b67ad" +dependencies = [ + "serde_derive", +] + +[[package]] +name = "serde_derive" +version = "1.0.228" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d540f220d3187173da220f885ab66608367b6574e925011a9353e4badda91d79" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.118", +] + +[[package]] +name = "serde_json" +version = "1.0.150" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e8014e44b4736ed0538adeecded0fce2a272f22dc9578a7eb6b2d9993c74cfb9" +dependencies = [ + "itoa", + "memchr", + "serde", + "serde_core", + "zmij", +] + +[[package]] +name = "serde_spanned" +version = "1.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6662b5879511e06e8999a8a235d848113e942c9124f211511b16466ee2995f26" +dependencies = [ + "serde_core", +] + +[[package]] +name = "sha2" +version = "0.10.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a7507d819769d01a365ab707794a4084392c824f54a7a6a7862f8c3d0892b283" +dependencies = [ + "cfg-if", + "cpufeatures", + "digest", +] + +[[package]] +name = "sharded-slab" +version = "0.1.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f40ca3c46823713e0d4209592e8d6e826aa57e928f09752619fc696c499637f6" +dependencies = [ + "lazy_static", +] + +[[package]] +name = "shlex" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64" + +[[package]] +name = "shlex" +version = "2.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f8fadd59c855ef2080decdef8ff161eb6661b86933c9d82e5ba29dc602a55aba" + +[[package]] +name = "signature" +version = "2.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "77549399552de45a898a580c1b41d445bf730df867cc44e6c0233bbc4b8329de" + +[[package]] +name = "siphasher" +version = "1.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8ee5873ec9cce0195efcb7a4e9507a04cd49aec9c83d0389df45b1ef7ba2e649" + +[[package]] +name = "slab" +version = "0.4.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0c790de23124f9ab44544d7ac05d60440adc586479ce501c1d6d7da3cd8c9cf5" + +[[package]] +name = "smallvec" +version = "1.15.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8ed6a63f02c8539c91a8685a86f4099661ba3da017932f6ebbea6de3f0fa7c90" + +[[package]] +name = "spin" +version = "0.9.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6980e8d7511241f8acf4aebddbb1ff938df5eebe98691418c4468d0b72a96a67" +dependencies = [ + "lock_api", +] + +[[package]] +name = "ssmarshal" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f3e6ad23b128192ed337dfa4f1b8099ced0c2bf30d61e551b65fda5916dbb850" +dependencies = [ + "encode_unicode", + "serde", +] + +[[package]] +name = "stable_deref_trait" +version = "1.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6ce2be8dc25455e1f91df71bfa12ad37d7af1092ae736f3a6cd0e37bc7810596" + +[[package]] +name = "static_cell" +version = "2.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0530892bb4fa575ee0da4b86f86c667132a94b74bb72160f58ee5a4afec74c23" +dependencies = [ + "portable-atomic", +] + +[[package]] +name = "strsim" +version = "0.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f" + +[[package]] +name = "strum" +version = "0.28.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9628de9b8791db39ceda2b119bbe13134770b56c138ec1d3af810d045c04f9bd" +dependencies = [ + "strum_macros", +] + +[[package]] +name = "strum_macros" +version = "0.28.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ab85eea0270ee17587ed4156089e10b9e6880ee688791d45a905f5b1ca36f664" +dependencies = [ + "heck", + "proc-macro2", + "quote", + "syn 2.0.118", +] + +[[package]] +name = "subtle" +version = "2.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "13c2bddecc57b384dee18652358fb23172facb8a2c51ccc10d74c157bdea3292" + +[[package]] +name = "syn" +version = "1.0.109" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[package]] +name = "syn" +version = "2.0.118" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1b9ae57f904213ebb649ce6895b8a66c66f0203b9319718f69a5612a065b1422" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[package]] +name = "thiserror" +version = "2.0.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4288b5bcbc7920c07a1149a35cf9590a2aa808e0bc1eafaade0b80947865fbc4" +dependencies = [ + "thiserror-impl", +] + +[[package]] +name = "thiserror-impl" +version = "2.0.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ebc4ee7f67670e9b64d05fa4253e753e016c6c95ff35b89b7941d6b856dec1d5" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.118", +] + +[[package]] +name = "thread_local" +version = "1.1.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f60246a4944f24f6e018aa17cdeffb7818b76356965d03b07d6a9886e8962185" +dependencies = [ + "cfg-if", +] + +[[package]] +name = "tiny-keccak" +version = "2.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2c9d3793400a45f954c52e73d068316d76b6f4e36977e3fcebb13a2721e80237" +dependencies = [ + "crunchy", +] + +[[package]] +name = "toml" +version = "0.9.12+spec-1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cf92845e79fc2e2def6a5d828f0801e29a2f8acc037becc5ab08595c7d5e9863" +dependencies = [ + "indexmap", + "serde_core", + "serde_spanned", + "toml_datetime 0.7.5+spec-1.1.0", + "toml_parser", + "toml_writer", + "winnow 0.7.15", +] + +[[package]] +name = "toml" +version = "1.1.2+spec-1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "81f3d15e84cbcd896376e6730314d59fb5a87f31e4b038454184435cd57defee" +dependencies = [ + "indexmap", + "serde_core", + "serde_spanned", + "toml_datetime 1.1.1+spec-1.1.0", + "toml_parser", + "toml_writer", + "winnow 1.0.3", +] + +[[package]] +name = "toml_datetime" +version = "0.7.5+spec-1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "92e1cfed4a3038bc5a127e35a2d360f145e1f4b971b551a2ba5fd7aedf7e1347" +dependencies = [ + "serde_core", +] + +[[package]] +name = "toml_datetime" +version = "1.1.1+spec-1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3165f65f62e28e0115a00b2ebdd37eb6f3b641855f9d636d3cd4103767159ad7" +dependencies = [ + "serde_core", +] + +[[package]] +name = "toml_parser" +version = "1.1.2+spec-1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a2abe9b86193656635d2411dc43050282ca48aa31c2451210f4202550afb7526" +dependencies = [ + "winnow 1.0.3", +] + +[[package]] +name = "toml_writer" +version = "1.1.1+spec-1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "756daf9b1013ebe47a8776667b466417e2d4c5679d441c26230efd9ef78692db" + +[[package]] +name = "tracing" +version = "0.1.44" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "63e71662fa4b2a2c3a26f570f037eb95bb1f85397f3cd8076caed2f026a6d100" +dependencies = [ + "pin-project-lite", + "tracing-attributes", + "tracing-core", +] + +[[package]] +name = "tracing-attributes" +version = "0.1.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7490cfa5ec963746568740651ac6781f701c9c5ea257c58e057f3ba8cf69e8da" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.118", +] + +[[package]] +name = "tracing-core" +version = "0.1.36" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "db97caf9d906fbde555dd62fa95ddba9eecfd14cb388e4f491a66d74cd5fb79a" +dependencies = [ + "once_cell", + "valuable", +] + +[[package]] +name = "tracing-log" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ee855f1f400bd0e5c02d150ae5de3840039a3f54b025156404e34c23c03f47c3" +dependencies = [ + "log", + "once_cell", + "tracing-core", +] + +[[package]] +name = "tracing-subscriber" +version = "0.3.23" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cb7f578e5945fb242538965c2d0b04418d38ec25c79d160cd279bf0731c8d319" +dependencies = [ + "matchers", + "nu-ansi-term", + "once_cell", + "regex-automata", + "sharded-slab", + "smallvec", + "thread_local", + "tracing", + "tracing-core", + "tracing-log", +] + +[[package]] +name = "trouble-host" +version = "0.6.0" +source = "git+https://github.com/haobogu/trouble?rev=690373fd1166d16225b875435dd0600c92570e7d#690373fd1166d16225b875435dd0600c92570e7d" +dependencies = [ + "aes", + "bt-hci", + "cmac", + "defmt 1.1.0", + "embassy-futures", + "embassy-sync", + "embassy-time", + "embedded-io 0.7.1", + "futures", + "heapless 0.9.3", + "p256", + "rand", + "rand_chacha", + "rand_core 0.6.4", + "serde", + "static_cell", + "trouble-host-macros", + "zerocopy", +] + +[[package]] +name = "trouble-host-macros" +version = "0.4.0" +source = "git+https://github.com/haobogu/trouble?rev=690373fd1166d16225b875435dd0600c92570e7d#690373fd1166d16225b875435dd0600c92570e7d" +dependencies = [ + "convert_case 0.8.0", + "darling 0.20.11", + "proc-macro2", + "quote", + "syn 2.0.118", + "uuid", +] + +[[package]] +name = "typeid" +version = "1.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bc7d623258602320d5c55d1bc22793b57daff0ec7efc270ea7d55ce1d5f5471c" + +[[package]] +name = "typenum" +version = "1.20.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b6f5e870be6c3b371b77fe0ee0bafb859fa4964b4404c27de1d380043c4dda20" + +[[package]] +name = "ucd-trie" +version = "0.1.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2896d95c02a80c6d6a5d6e953d479f5ddf2dfdb6a244441010e373ac0fb88971" + +[[package]] +name = "unicode-ident" +version = "1.0.24" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e6e4313cd5fcd3dad5cafa179702e2b244f760991f45397d14d4ebf38247da75" + +[[package]] +name = "unicode-segmentation" +version = "1.13.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c6f5d3c3b1bf09027a88a6bc961fc00497d651009560b5463668dc81b0fa87a8" + +[[package]] +name = "usb-device" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "98816b1accafbb09085168b90f27e93d790b4bfa19d883466b5e53315b5f06a6" +dependencies = [ + "defmt 0.3.100", + "heapless 0.8.0", + "portable-atomic", +] + +[[package]] +name = "usbd-hid" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "68beab087e4971a2fe76f631478b0e91d39593f58efd2775026ce6dc07a7bac6" +dependencies = [ + "defmt 0.3.100", + "usb-device", + "usbd-hid-macros", +] + +[[package]] +name = "usbd-hid-descriptors" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b297f021719c4308d5d0c61b6c1e7c6b3ba383deba774b49aa5484f996bdb8f1" +dependencies = [ + "bitfield 0.14.0", +] + +[[package]] +name = "usbd-hid-macros" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "011a3219e0933f5b3ad7dc90d9a66541a967d084c98c067deed1cd608e557ed7" +dependencies = [ + "byteorder", + "hashbrown 0.13.2", + "log", + "proc-macro2", + "quote", + "serde", + "syn 2.0.118", + "usbd-hid-descriptors", +] + +[[package]] +name = "uuid" +version = "1.23.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "144d6b123cef80b301b8f72a9e2ca4370ddec21950d0a103dd22c437006d2db7" +dependencies = [ + "js-sys", + "wasm-bindgen", +] + +[[package]] +name = "valuable" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ba73ea9cf16a25df0c8caa16c51acb937d5712a8429db78a3ee29d5dcacd3a65" + +[[package]] +name = "vcell" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "77439c1b53d2303b20d9459b1ade71a83c716e3f9c34f3228c00e6f185d6c002" + +[[package]] +name = "version_check" +version = "0.9.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b928f33d975fc6ad9f86c8f283853ad26bdd5b10b7f1542aa2fa15e2289105a" + +[[package]] +name = "void" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6a02e4885ed3bc0f2de90ea6dd45ebcbb66dacffe03547fadbb0eeae2770887d" + +[[package]] +name = "volatile-register" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "de437e2a6208b014ab52972a27e59b33fa2920d3e00fe05026167a1c509d19cc" +dependencies = [ + "vcell", +] + +[[package]] +name = "wasi" +version = "0.11.1+wasi-snapshot-preview1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ccf3ec651a847eb01de73ccad15eb7d99f80485de043efb2f370cd654f4ea44b" + +[[package]] +name = "wasm-bindgen" +version = "0.2.125" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8ddb3f79143bced6de84270411622a2699cee572fc0875aeaf1e7867cf9fca1a" +dependencies = [ + "cfg-if", + "once_cell", + "rustversion", + "wasm-bindgen-macro", + "wasm-bindgen-shared", +] + +[[package]] +name = "wasm-bindgen-macro" +version = "0.2.125" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4e21a184b13fb19e157296e2c46056aec9092264fab83e4ba59e68c61b323c3d" +dependencies = [ + "quote", + "wasm-bindgen-macro-support", +] + +[[package]] +name = "wasm-bindgen-macro-support" +version = "0.2.125" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fecefd9c35bd935a20fc3fc344b5f29138961e4f47fb03297d88f2587afb5ebd" +dependencies = [ + "bumpalo", + "proc-macro2", + "quote", + "syn 2.0.118", + "wasm-bindgen-shared", +] + +[[package]] +name = "wasm-bindgen-shared" +version = "0.2.125" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "23939e44bb9a5d7576fa2b563dc2e136628f1224e88a8deed09e04858b77871f" +dependencies = [ + "unicode-ident", +] + +[[package]] +name = "windows-link" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f0805222e57f7521d6a62e36fa9163bc891acd422f971defe97d64e70d0a4fe5" + +[[package]] +name = "windows-result" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7781fa89eaf60850ac3d2da7af8e5242a5ea78d1a11c49bf2910bb5a73853eb5" +dependencies = [ + "windows-link", +] + +[[package]] +name = "windows-sys" +version = "0.61.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ae137229bcbd6cdf0f7b80a31df61766145077ddf49416a728b02cb3921ff3fc" +dependencies = [ + "windows-link", +] + +[[package]] +name = "winnow" +version = "0.7.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "df79d97927682d2fd8adb29682d1140b343be4ac0f08fd68b7765d9c059d3945" +dependencies = [ + "memchr", +] + +[[package]] +name = "winnow" +version = "1.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0592e1c9d151f854e6fd382574c3a0855250e1d9b2f99d9281c6e6391af352f1" +dependencies = [ + "memchr", +] + +[[package]] +name = "xz2" +version = "0.1.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "388c44dc09d76f1536602ead6d325eb532f5c122f17782bd57fb47baeeb767e2" +dependencies = [ + "lzma-sys", +] + +[[package]] +name = "yaml-rust2" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "631a50d867fafb7093e709d75aaee9e0e0d5deb934021fcea25ac2fe09edc51e" +dependencies = [ + "arraydeque", + "encoding_rs", + "hashlink", +] + +[[package]] +name = "zerocopy" +version = "0.8.52" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ce1022995ff5ff5d841ad7d994facc23098cd40152f2c1d11cd607c6f530653f" +dependencies = [ + "zerocopy-derive", +] + +[[package]] +name = "zerocopy-derive" +version = "0.8.52" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1ae7f38b72ec2a254e2b87ef277cf2cd4fb97cbebf944faa6f33354da0867930" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.118", +] + +[[package]] +name = "zeroize" +version = "1.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e13c156562582aa81c60cb29407084cdb54c4164760106ab78e6c5b0858cf64e" + +[[package]] +name = "zmij" +version = "1.0.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b8848ee67ecc8aedbaf3e4122217aff892639231befc6a1b58d29fff4c2cabaa" diff --git a/examples/use_config/nrf52840_embassy_boot/Cargo.toml b/examples/use_config/nrf52840_embassy_boot/Cargo.toml new file mode 100644 index 000000000..f423269dc --- /dev/null +++ b/examples/use_config/nrf52840_embassy_boot/Cargo.toml @@ -0,0 +1,76 @@ +[package] +name = "rmk-nrf52840-embassy-boot" +version = "0.2.0" +authors = ["Haobo Gu "] +description = "Keyboard firmware written in Rust" +homepage = "https://github.com/haobogu/rmk" +repository = "https://github.com/haobogu/rmk" +readme = "../../README.md" +edition = "2024" +license = "MIT OR Apache-2.0" + +[dependencies] +rmk = { path = "../../../rmk", features = [ + "dfu_nrf", + "nrf52840_ble", + # "dfu_lock" +] } +embassy-time = { version = "0.5", features = ["tick-hz-32_768", "defmt"] } +embassy-nrf = { version = "0.10", features = [ + "defmt", + "nrf52840", + "time-driver-rtc1", + "gpiote", + "unstable-pac", + "time", +] } +embassy-boot = { version = "0.7", default-features = false } +nrf-sdc = { git = "https://github.com/haobogu/nrf-sdc", rev = "ffe59a7aefaaa145a3d2474602f33387f80dcefa", features = [ + "defmt", + "peripheral", + "nrf52840", +] } +nrf-mpsl = { git = "https://github.com/haobogu/nrf-sdc", rev = "ffe59a7aefaaa145a3d2474602f33387f80dcefa", features = [ + "defmt", + "nrf52840", +] } +bt-hci = { version = "0.8", features = ["defmt"] } +embassy-executor = { version = "0.10", features = [ + "defmt", + "platform-cortex-m", + "executor-thread", +] } +portable-atomic = { version = "1.11", features = ["critical-section"] } +cortex-m = { version = "0.7.7", features = ["critical-section-single-core"] } +cortex-m-rt = { version = "0.7.5", features = ["set-vtor"] } +defmt = "1.0" +defmt-rtt = "1.0" +panic-probe = { version = "1.0", features = ["print-defmt"] } +static_cell = "2" +rand_core = { version = "0.6", default-features = false } +rand_chacha = { version = "0.3", default-features = false } + +[build-dependencies] +xz2 = "0.1.7" +json = "0.12" +const-gen = "1.6" + +[[bin]] +name = "rmk-nrf52840-embassy-boot" +test = false +bench = false + +[profile.dev] +codegen-units = 1 +debug = true +opt-level = 1 +overflow-checks = true +lto = false +panic = 'unwind' + +[profile.release] +codegen-units = 1 +debug = true +opt-level = "z" +overflow-checks = false +lto = "fat" diff --git a/examples/use_config/nrf52840_embassy_boot/Makefile.toml b/examples/use_config/nrf52840_embassy_boot/Makefile.toml new file mode 100644 index 000000000..a390948bb --- /dev/null +++ b/examples/use_config/nrf52840_embassy_boot/Makefile.toml @@ -0,0 +1,41 @@ +[tasks.install-llvm-tools] +install_crate = { rustup_component_name = "llvm-tools" } + +[tasks.flip-link] +install_crate = { crate_name = "flip-link", binary = "flip-link", test_arg = ["-h"] } + +[tasks.build] +command = "cargo" +args = ["build", "--release"] +dependencies = ["install-llvm-tools", "flip-link"] + +[tasks.bin] +command = "cargo" +args = ["objcopy", "--release", "--", "-O", "binary", "${CARGO_MAKE_PROJECT_NAME}.bin"] +dependencies = ["build"] + +[tasks.objcopy] +install_crate = { crate_name = "cargo-binutils", binary = "cargo", test_arg = [ + "objcopy", + "--help", +] } +command = "cargo" +args = ["objcopy", "--release", "--", "-O", "ihex", "rmk.hex"] +dependencies = ["build"] + +[tasks.uf2] +install_crate = { crate_name = "cargo-hex-to-uf2", binary = "cargo", test_arg = [ + "hex-to-uf2", + "--help", +] } +command = "cargo" +args = [ + "hex-to-uf2", + "--input-path", + "rmk.hex", + "--output-path", + "rmk.uf2", + "--family", + "nrf52840", +] +dependencies = ["objcopy"] diff --git a/examples/use_config/nrf52840_embassy_boot/build.rs b/examples/use_config/nrf52840_embassy_boot/build.rs new file mode 100644 index 000000000..7adb35c2b --- /dev/null +++ b/examples/use_config/nrf52840_embassy_boot/build.rs @@ -0,0 +1,54 @@ +use std::fs::File; +use std::io::{Read, Write}; +use std::path::{Path, PathBuf}; +use std::{env, fs}; + +use const_gen::*; +use xz2::read::XzEncoder; + +fn main() { + println!("cargo:rerun-if-changed=vial.json"); + generate_vial_config(); + + let out = &PathBuf::from(env::var_os("OUT_DIR").unwrap()); + File::create(out.join("memory.x")) + .unwrap() + .write_all(include_bytes!("memory.x")) + .unwrap(); + println!("cargo:rustc-link-search={}", out.display()); + + println!("cargo:rerun-if-changed=memory.x"); + println!("cargo:rerun-if-changed=keyboard.toml"); + + println!("cargo:rustc-link-arg=--nmagic"); + println!("cargo:rustc-link-arg=-Tlink.x"); + println!("cargo:rustc-link-arg=-Tdefmt.x"); +} + +fn generate_vial_config() { + let out_file = Path::new(&env::var_os("OUT_DIR").unwrap()).join("config_generated.rs"); + + let p = Path::new("vial.json"); + let mut content = String::new(); + match File::open(p) { + Ok(mut file) => { + file.read_to_string(&mut content).expect("Cannot read vial.json"); + } + Err(e) => println!("Cannot find vial.json {:?}: {}", p, e), + }; + + let vial_cfg = json::stringify(json::parse(&content).unwrap()); + let mut keyboard_def_compressed: Vec = Vec::new(); + XzEncoder::new(vial_cfg.as_bytes(), 6) + .read_to_end(&mut keyboard_def_compressed) + .unwrap(); + + let keyboard_id: Vec = vec![0xB9, 0xBC, 0x09, 0xB2, 0x9D, 0x37, 0x4C, 0xEA]; + let const_declarations = [ + const_declaration!(pub VIAL_KEYBOARD_DEF = keyboard_def_compressed), + const_declaration!(pub VIAL_KEYBOARD_ID = keyboard_id), + ] + .map(|s| "#[allow(clippy::redundant_static_lifetimes)]\n".to_owned() + s.as_str()) + .join("\n"); + fs::write(out_file, const_declarations).unwrap(); +} diff --git a/examples/use_config/nrf52840_embassy_boot/keyboard.toml b/examples/use_config/nrf52840_embassy_boot/keyboard.toml new file mode 100644 index 000000000..f169806d5 --- /dev/null +++ b/examples/use_config/nrf52840_embassy_boot/keyboard.toml @@ -0,0 +1,63 @@ +[keyboard] +name = "RMK nRF52840 Keyboard" +product_name = "My RMK Keyboard" +vendor_id = 0x4c4b +product_id = 0x4643 +manufacturer = "Haobo" +chip = "nrf52840" + +[matrix] +row_pins = ["P0_07", "P0_22", "P0_11", "P0_12"] +col_pins = ["P0_13", "P0_17", "P0_20"] + +[layout] +rows = 4 +cols = 3 +layers = 1 +matrix_map = """ +(0,0) (0,1) (0,2) +(1,0) (1,1) (1,2) +(2,0) (2,1) (2,2) +(3,0) (3,1) (3,2) +""" + +[[layer]] +name = "base_layer" +keys = """ +Kp7 Kp8 Kp9 +Kp4 Kp5 Kp6 +Kp1 Kp2 Kp3 + Kp0 +""" + +[usb] +enabled = true + +[ble] +enabled = true + +# DFU partition layout — must match your bootloader's memory.x +# +# By default RMK uses the bootymcbootface formula with flash_size from the +# chip default (1 MB for nRF52840). +# Calculation: +# 2 * 1024 * 1024; // 2 MB (default) +# 4 * 1024 * 1024; // 4 MB +# and so on +# the addresses for the state, dfu, active and storage partitions are then automatically calculated. +# Uncomment and adjust to override: +# [dfu] +# flash_size = 2097152 # total flash (default: 1 MB) +# +# To set addresses manually, uncomment and edit the values below. +# Doing so disables the auto-calculation: +# state_offset = 0x6000 +# state_size = 0x1000 +# dfu_offset = 0x87000 +# dfu_size = 528384 + +[dfu] +led = "P0_15" # default P0_15, to not use set to "none" +# Optional DFU lock — physical keys to press simultaneously to unlock DFU firmware download. +# Requires the `dfu_lock` Cargo feature (not enabled by default). +# unlock_keys = [[0, 0], [1, 1]] \ No newline at end of file diff --git a/examples/use_config/nrf52840_embassy_boot/memory.x b/examples/use_config/nrf52840_embassy_boot/memory.x new file mode 100644 index 000000000..0561d1894 --- /dev/null +++ b/examples/use_config/nrf52840_embassy_boot/memory.x @@ -0,0 +1,11 @@ +/* +Flash layout matching bootymcbootface nRF layout: + bootloader: 24K at 0x0, state: 4K at 0x6000 + ACTIVE (this firmware): 432K at 0x7000 + DFU: 436K at 0x73000 + storage: 128K at 0xE0000 +*/ +MEMORY { + FLASH : ORIGIN = 0x00007000, LENGTH = 432K + RAM : ORIGIN = 0x20000000, LENGTH = 256K +} diff --git a/examples/use_config/nrf52840_embassy_boot/src/main.rs b/examples/use_config/nrf52840_embassy_boot/src/main.rs new file mode 100644 index 000000000..48b5541e8 --- /dev/null +++ b/examples/use_config/nrf52840_embassy_boot/src/main.rs @@ -0,0 +1,7 @@ +#![no_main] +#![no_std] + +use rmk::macros::rmk_keyboard; + +#[rmk_keyboard] +mod keyboard {} diff --git a/examples/use_config/nrf52840_embassy_boot/vial.json b/examples/use_config/nrf52840_embassy_boot/vial.json new file mode 100644 index 000000000..eba77b1c5 --- /dev/null +++ b/examples/use_config/nrf52840_embassy_boot/vial.json @@ -0,0 +1,37 @@ +{ + "name": "RMK Keyboard", + "vendorId": "0x4C4B", + "productId": "0x4643", + "lighting": "none", + "matrix": { + "rows": 4, + "cols": 3 + }, + "layouts": { + "keymap": [ + [ + "0,0", + "0,1", + "0,2" + ], + [ + "1,0", + "1,1", + "1,2" + ], + [ + "2,0", + "2,1", + "2,2" + ], + [ + { + "y": -2, + "x": 4 + }, + "3,0", + "3,2" + ] + ] + } +} \ No newline at end of file diff --git a/examples/use_config/rp2040_embassy_boot/Cargo.lock b/examples/use_config/rp2040_embassy_boot/Cargo.lock index c05c607ed..18c4043f9 100644 --- a/examples/use_config/rp2040_embassy_boot/Cargo.lock +++ b/examples/use_config/rp2040_embassy_boot/Cargo.lock @@ -2048,6 +2048,7 @@ dependencies = [ "crc32fast", "defmt 1.1.0", "document-features", + "embassy-boot", "embassy-boot-rp", "embassy-embedded-hal", "embassy-futures", diff --git a/examples/use_config/rp2040_embassy_boot/keyboard.toml b/examples/use_config/rp2040_embassy_boot/keyboard.toml index 83c46b137..cf3a09087 100644 --- a/examples/use_config/rp2040_embassy_boot/keyboard.toml +++ b/examples/use_config/rp2040_embassy_boot/keyboard.toml @@ -29,9 +29,6 @@ keymap = [ ], ] -[storage] -enabled = true - # DFU partition layout — must match your bootloader's memory.x # # By default RMK uses the bootymcbootface formula with flash_size from the @@ -51,15 +48,9 @@ enabled = true # state_size = 0x1000 # dfu_offset = 0x87000 # dfu_size = 528384 -# Optional DFU activity LED (lit during firmware download) -# led = "PIN_25" [dfu] led = "PIN_16" # Optional DFU lock — physical keys to press simultaneously to unlock DFU firmware download. # Requires the `dfu_lock` Cargo feature (not enabled by default). unlock_keys = [[0, 0], [1, 1]] - -[rmk] -morse_max_num = 8 -max_patterns_per_key = 8 diff --git a/examples/use_config/rp2040_embassy_boot/memory.x b/examples/use_config/rp2040_embassy_boot/memory.x index 3e94ea4ba..c6f982df6 100644 --- a/examples/use_config/rp2040_embassy_boot/memory.x +++ b/examples/use_config/rp2040_embassy_boot/memory.x @@ -1,8 +1,13 @@ /* This memory.x is for the RP2040 with 2MB flash. -For different flash sizes see docs. +For different flash sizes uncomment below. +Be aware you need to change [dfu] flash_size in keyboard.toml accordingly +and flash the matching bootloader. */ MEMORY { FLASH : ORIGIN = 0x10007000, LENGTH = 944K + /* 4MB: FLASH : ORIGIN = 0x10007000, LENGTH = 1968K */ + /* 8MB: FLASH : ORIGIN = 0x10007000, LENGTH = 4016K */ + /* 16MB: FLASH : ORIGIN = 0x10007000, LENGTH = 8112K */ RAM : ORIGIN = 0x20000000, LENGTH = 256K } diff --git a/examples/use_rust/nrf52840_embassy_boot/.cargo/config.toml b/examples/use_rust/nrf52840_embassy_boot/.cargo/config.toml new file mode 100644 index 000000000..3d89ecaef --- /dev/null +++ b/examples/use_rust/nrf52840_embassy_boot/.cargo/config.toml @@ -0,0 +1,11 @@ +[target.'cfg(all(target_arch = "arm", target_os = "none"))'] +runner = "probe-rs run --chip nRF52840_xxAA" + +# Use flip-link overflow check: https://github.com/knurling-rs/flip-link +linker = "flip-link" + +[build] +target = "thumbv7em-none-eabihf" # Cortex-M4F and Cortex-M7F (with FPU) + +[env] +DEFMT_LOG = "trace" diff --git a/examples/use_rust/nrf52840_embassy_boot/Cargo.lock b/examples/use_rust/nrf52840_embassy_boot/Cargo.lock new file mode 100644 index 000000000..eab0b48a8 --- /dev/null +++ b/examples/use_rust/nrf52840_embassy_boot/Cargo.lock @@ -0,0 +1,2542 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 4 + +[[package]] +name = "aes" +version = "0.8.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b169f7a6d4742236a0a00c541b845991d0ac43e546831af1249753ab4c3aa3a0" +dependencies = [ + "cfg-if", + "cipher", + "cpufeatures", +] + +[[package]] +name = "ahash" +version = "0.8.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5a15f179cd60c4584b8a8c596927aadc462e27f2ca70c04e0071964a73ba7a75" +dependencies = [ + "cfg-if", + "once_cell", + "version_check", + "zerocopy", +] + +[[package]] +name = "aho-corasick" +version = "1.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ddd31a130427c27518df266943a5308ed92d4b226cc639f5a8f1002816174301" +dependencies = [ + "memchr", +] + +[[package]] +name = "arraydeque" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7d902e3d592a523def97af8f317b08ce16b7ab854c1985a0c671e6f15cebc236" + +[[package]] +name = "async-trait" +version = "0.1.89" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9035ad2d096bed7955a320ee7e2230574d28fd3c3a0f186cbea1ff3c7eed5dbb" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.118", +] + +[[package]] +name = "atomic-polyfill" +version = "1.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8cf2bce30dfe09ef0bfaef228b9d414faaf7e563035494d7fe092dba54b300f4" +dependencies = [ + "critical-section", +] + +[[package]] +name = "autocfg" +version = "1.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f2032f911046de80f0a198e0901378627c33f59ea0ac00e363d481118bd70a53" + +[[package]] +name = "az" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "be5eb007b7cacc6c660343e96f650fedf4b5a77512399eb952ca6642cf8d13f7" + +[[package]] +name = "bare-metal" +version = "0.2.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5deb64efa5bd81e31fcd1938615a6d98c82eafcbcd787162b6f63b91d6bac5b3" +dependencies = [ + "rustc_version 0.2.3", +] + +[[package]] +name = "base16ct" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4c7f02d4ea65f2c1853089ffd8d2787bdbc63de2f0d29dedbcf8ccdfa0ccd4cf" + +[[package]] +name = "bitfield" +version = "0.13.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "46afbd2983a5d5a7bd740ccb198caf5b82f45c40c09c0eed36052d91cb92e719" + +[[package]] +name = "bitfield" +version = "0.14.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2d7e60934ceec538daadb9d8432424ed043a904d8e0243f3c6446bce549a46ac" + +[[package]] +name = "bitfield-struct" +version = "0.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3ca6739863c590881f038d033a146c51ddae239186a4327014839fd864f44ed5" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.118", +] + +[[package]] +name = "bitflags" +version = "1.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" + +[[package]] +name = "bitflags" +version = "2.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b4388bee8683e3d04af747c73422af53102d2bd24d9eadb6cbc100baef4b43f8" +dependencies = [ + "serde_core", +] + +[[package]] +name = "block-buffer" +version = "0.10.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3078c7629b62d3f0439517fa394996acacc5cbc91c5a20d8c658e77abd503a71" +dependencies = [ + "generic-array", +] + +[[package]] +name = "bt-hci" +version = "0.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "211713d2e9fb4793ce4360a712c0764264aff6be48932ccf02ca2a331c0436a9" +dependencies = [ + "btuuid", + "defmt 1.1.0", + "embassy-sync", + "embedded-io 0.7.1", + "embedded-io-async 0.7.0", + "futures-intrusive", + "heapless 0.9.3", + "serde", +] + +[[package]] +name = "btuuid" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f5f48f1e9b0aad0a4f05d17bdeae0fa20ff798e272a03a6940ca27ad9c5a6ae7" +dependencies = [ + "defmt 0.3.100", + "serde", + "uuid", +] + +[[package]] +name = "bumpalo" +version = "3.20.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "72f5acc6cb2ba439de613abc23857ec3d78374d8ed5ac84e9d11336e87da8649" + +[[package]] +name = "bytemuck" +version = "1.25.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c8efb64bd706a16a1bdde310ae86b351e4d21550d98d056f22f8a7f7a2183fec" + +[[package]] +name = "byteorder" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" + +[[package]] +name = "cargo_toml" +version = "0.22.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "374b7c592d9c00c1f4972ea58390ac6b18cbb6ab79011f3bdc90a0b82ca06b77" +dependencies = [ + "serde", + "toml 0.9.12+spec-1.1.0", +] + +[[package]] +name = "cc" +version = "1.2.64" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dad887fd958be91b5098c0248def011f4523ab786cd411be668777e55063501f" +dependencies = [ + "find-msvc-tools", + "shlex", +] + +[[package]] +name = "cfg-if" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9330f8b2ff13f34540b44e946ef35111825727b38d33286ef986142615121801" + +[[package]] +name = "cipher" +version = "0.4.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "773f3b9af64447d2ce9850330c473515014aa235e6a783b02db81ff39e4a3dad" +dependencies = [ + "crypto-common", + "inout", +] + +[[package]] +name = "cmac" +version = "0.7.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8543454e3c3f5126effff9cd44d562af4e31fb8ce1cc0d3dcd8f084515dbc1aa" +dependencies = [ + "cipher", + "dbl", + "digest", +] + +[[package]] +name = "cobs" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0fa961b519f0b462e3a3b4a34b64d119eeaca1d59af726fe450bbba07a9fc0a1" +dependencies = [ + "thiserror", +] + +[[package]] +name = "config" +version = "0.15.24" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b34d0237145f33580b89724f75d16950efd3e2c91b2d823917ecb69ec7f84f0" +dependencies = [ + "async-trait", + "convert_case 0.6.0", + "json5", + "pathdiff", + "ron", + "rust-ini", + "serde-untagged", + "serde_core", + "serde_json", + "toml 1.1.2+spec-1.1.0", + "winnow 1.0.3", + "yaml-rust2", +] + +[[package]] +name = "const-gen" +version = "1.6.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a0bb51eeea292ceb9bf5312b4416c1b151b130502e6892a2ae174ae1e4b51e58" +dependencies = [ + "const-gen-derive", +] + +[[package]] +name = "const-gen-derive" +version = "1.1.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eabc01a5585d36649b6bee1f1198d112a7bb4982661d6c18406fba571ce3263e" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "const-oid" +version = "0.9.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c2459377285ad874054d797f3ccebf984978aa39129f6eafde5cdc8315b612f8" + +[[package]] +name = "const-random" +version = "0.1.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "87e00182fe74b066627d63b85fd550ac2998d4b0bd86bfed477a0ae4c7c71359" +dependencies = [ + "const-random-macro", +] + +[[package]] +name = "const-random-macro" +version = "0.1.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f9d839f2a20b0aee515dc581a6172f2321f96cab76c1a38a4c584a194955390e" +dependencies = [ + "getrandom", + "once_cell", + "tiny-keccak", +] + +[[package]] +name = "convert_case" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ec182b0ca2f35d8fc196cf3404988fd8b8c739a4d270ff118a398feb0cbec1ca" +dependencies = [ + "unicode-segmentation", +] + +[[package]] +name = "convert_case" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "baaaa0ecca5b51987b9423ccdc971514dd8b0bb7b4060b983d3664dad3f1f89f" +dependencies = [ + "unicode-segmentation", +] + +[[package]] +name = "cordyceps" +version = "0.3.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "688d7fbb8092b8de775ef2536f36c8c31f2bc4006ece2e8d8ad2d17d00ce0a2a" +dependencies = [ + "loom", + "tracing", +] + +[[package]] +name = "cortex-m" +version = "0.7.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8ec610d8f49840a5b376c69663b6369e71f4b34484b9b2eb29fb918d92516cb9" +dependencies = [ + "bare-metal", + "bitfield 0.13.2", + "critical-section", + "embedded-hal 0.2.7", + "volatile-register", +] + +[[package]] +name = "cortex-m-rt" +version = "0.7.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "801d4dec46b34c299ccf6b036717ae0fce602faa4f4fe816d9013b9a7c9f5ba6" +dependencies = [ + "cortex-m-rt-macros", +] + +[[package]] +name = "cortex-m-rt-macros" +version = "0.7.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e37549a379a9e0e6e576fd208ee60394ccb8be963889eebba3ffe0980364f472" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.118", +] + +[[package]] +name = "cpufeatures" +version = "0.2.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "59ed5838eebb26a2bb2e58f6d5b5316989ae9d08bab10e0e6d103e656d1b0280" +dependencies = [ + "libc", +] + +[[package]] +name = "crc32fast" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9481c1c90cbf2ac953f07c8d4a58aa3945c425b7185c9154d67a65e4230da511" +dependencies = [ + "cfg-if", +] + +[[package]] +name = "critical-section" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "790eea4361631c5e7d22598ecd5723ff611904e3344ce8720784c93e3d83d40b" + +[[package]] +name = "crunchy" +version = "0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "460fbee9c2c2f33933d720630a6a0bac33ba7053db5344fac858d4b8952d77d5" + +[[package]] +name = "crypto-bigint" +version = "0.5.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0dc92fb57ca44df6db8059111ab3af99a63d5d0f8375d9972e319a379c6bab76" +dependencies = [ + "generic-array", + "rand_core 0.6.4", + "subtle", + "zeroize", +] + +[[package]] +name = "crypto-common" +version = "0.1.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "78c8292055d1c1df0cce5d180393dc8cce0abec0a7102adb6c7b1eef6016d60a" +dependencies = [ + "generic-array", + "typenum", +] + +[[package]] +name = "darling" +version = "0.20.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fc7f46116c46ff9ab3eb1597a45688b6715c6e628b5c133e288e709a29bcb4ee" +dependencies = [ + "darling_core 0.20.11", + "darling_macro 0.20.11", +] + +[[package]] +name = "darling" +version = "0.23.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "25ae13da2f202d56bd7f91c25fba009e7717a1e4a1cc98a76d844b65ae912e9d" +dependencies = [ + "darling_core 0.23.0", + "darling_macro 0.23.0", +] + +[[package]] +name = "darling_core" +version = "0.20.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0d00b9596d185e565c2207a0b01f8bd1a135483d02d9b7b0a54b11da8d53412e" +dependencies = [ + "fnv", + "ident_case", + "proc-macro2", + "quote", + "strsim", + "syn 2.0.118", +] + +[[package]] +name = "darling_core" +version = "0.23.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9865a50f7c335f53564bb694ef660825eb8610e0a53d3e11bf1b0d3df31e03b0" +dependencies = [ + "ident_case", + "proc-macro2", + "quote", + "strsim", + "syn 2.0.118", +] + +[[package]] +name = "darling_macro" +version = "0.20.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fc34b93ccb385b40dc71c6fceac4b2ad23662c7eeb248cf10d529b7e055b6ead" +dependencies = [ + "darling_core 0.20.11", + "quote", + "syn 2.0.118", +] + +[[package]] +name = "darling_macro" +version = "0.23.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ac3984ec7bd6cfa798e62b4a642426a5be0e68f9401cfc2a01e3fa9ea2fcdb8d" +dependencies = [ + "darling_core 0.23.0", + "quote", + "syn 2.0.118", +] + +[[package]] +name = "dbl" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bd2735a791158376708f9347fe8faba9667589d82427ef3aed6794a8981de3d9" +dependencies = [ + "generic-array", +] + +[[package]] +name = "defmt" +version = "0.3.100" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f0963443817029b2024136fc4dd07a5107eb8f977eaf18fcd1fdeb11306b64ad" +dependencies = [ + "defmt 1.1.0", +] + +[[package]] +name = "defmt" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a6e524506490a1953d237cb87b1cfc1e46f88c18f10a22dfe0f507dc6bfc7f7f" +dependencies = [ + "bitflags 1.3.2", + "defmt-macros", +] + +[[package]] +name = "defmt-macros" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f0a27770e9c8f719a79d8b638281f4d828f77d8fd61e0bd94451b9b85e576a0b" +dependencies = [ + "defmt-parser", + "proc-macro-error2", + "proc-macro2", + "quote", + "syn 2.0.118", +] + +[[package]] +name = "defmt-parser" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "10d60334b3b2e7c9d91ef8150abfb6fa4c1c39ebbcf4a81c2e346aad939fee3e" +dependencies = [ + "thiserror", +] + +[[package]] +name = "defmt-rtt" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c0f73a4a4a91609e977ae3b7bd831ffa292edfd42ad140a3244a61d805b0e05e" +dependencies = [ + "critical-section", + "defmt 1.1.0", +] + +[[package]] +name = "der" +version = "0.7.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e7c1832837b905bbfb5101e07cc24c8deddf52f93225eee6ead5f4d63d53ddcb" +dependencies = [ + "const-oid", + "zeroize", +] + +[[package]] +name = "digest" +version = "0.10.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292" +dependencies = [ + "block-buffer", + "crypto-common", + "subtle", +] + +[[package]] +name = "dlv-list" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "442039f5147480ba31067cb00ada1adae6892028e40e45fc5de7b7df6dcc1b5f" +dependencies = [ + "const-random", +] + +[[package]] +name = "document-features" +version = "0.2.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d4b8a88685455ed29a21542a33abd9cb6510b6b129abadabdcef0f4c55bc8f61" +dependencies = [ + "litrs", +] + +[[package]] +name = "elliptic-curve" +version = "0.13.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b5e6043086bf7973472e0c7dff2142ea0b680d30e18d9cc40f267efbf222bd47" +dependencies = [ + "base16ct", + "crypto-bigint", + "digest", + "ff", + "generic-array", + "group", + "hkdf", + "rand_core 0.6.4", + "sec1", + "subtle", + "zeroize", +] + +[[package]] +name = "embassy-boot" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "73bfc955c9238df2ce9fecc6f18a64b13ecaa41a3cd42d940a09f304765d10db" +dependencies = [ + "digest", + "document-features", + "embassy-embedded-hal", + "embassy-sync", + "embedded-storage", + "embedded-storage-async", + "signature", +] + +[[package]] +name = "embassy-embedded-hal" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b0641612053b2f34fc250bb63f6630ae75de46e02ade7f457268447081d709ce" +dependencies = [ + "defmt 1.1.0", + "embassy-futures", + "embassy-hal-internal 0.4.0", + "embassy-sync", + "embassy-time", + "embedded-hal 0.2.7", + "embedded-hal 1.0.0", + "embedded-hal-async", + "embedded-storage", + "embedded-storage-async", + "nb 1.1.0", +] + +[[package]] +name = "embassy-executor" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5d0d3b15c9d7dc4fec1d8cb77112472fb008b3b28c51ad23838d83587a6d2f1e" +dependencies = [ + "cordyceps", + "cortex-m", + "critical-section", + "defmt 1.1.0", + "document-features", + "embassy-executor-macros", + "embassy-executor-timer-queue", +] + +[[package]] +name = "embassy-executor-macros" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d11a246f53de5f97a387f40ac24726817cd0b6f833e7603baac784f29d6ff276" +dependencies = [ + "darling 0.20.11", + "proc-macro2", + "quote", + "syn 2.0.118", +] + +[[package]] +name = "embassy-executor-timer-queue" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2fc328bf943af66b80b98755db9106bf7e7471b0cf47dc8559cd9a6be504cc9c" + +[[package]] +name = "embassy-futures" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dc2d050bdc5c21e0862a89256ed8029ae6c290a93aecefc73084b3002cdebb01" +dependencies = [ + "defmt 1.1.0", +] + +[[package]] +name = "embassy-hal-internal" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7f10ce10a4dfdf6402d8e9bd63128986b96a736b1a0a6680547ed2ac55d55dba" +dependencies = [ + "num-traits", +] + +[[package]] +name = "embassy-hal-internal" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "568659fc53866d3d85c60fa33723fb751aa69e71507634fc2c19e7649432fb75" +dependencies = [ + "cortex-m", + "critical-section", + "defmt 1.1.0", + "num-traits", +] + +[[package]] +name = "embassy-net-driver" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "524eb3c489760508f71360112bca70f6e53173e6fe48fc5f0efd0f5ab217751d" + +[[package]] +name = "embassy-net-driver-channel" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a07d2eb9f05a6fc876500949856ea1be40773d866d8cb99384f72d0ae4568c16" +dependencies = [ + "embassy-futures", + "embassy-net-driver", + "embassy-sync", +] + +[[package]] +name = "embassy-nrf" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b715380574504335c40ec3016bc44598fac3c385f82959b26c41b25c30b7648d" +dependencies = [ + "bitflags 2.13.0", + "cfg-if", + "cortex-m", + "cortex-m-rt", + "critical-section", + "defmt 1.1.0", + "document-features", + "embassy-embedded-hal", + "embassy-futures", + "embassy-hal-internal 0.5.0", + "embassy-sync", + "embassy-time", + "embassy-time-driver", + "embassy-time-queue-utils", + "embassy-usb-driver", + "embedded-hal 0.2.7", + "embedded-hal 1.0.0", + "embedded-hal-async", + "embedded-io 0.7.1", + "embedded-io-async 0.7.0", + "embedded-storage", + "embedded-storage-async", + "fixed", + "nrf-pac", + "rand_core 0.6.4", + "rand_core 0.9.5", +] + +[[package]] +name = "embassy-sync" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7bbd85cf5a5ae56bdf26f618364af642d1d0a4e245cdd75cd9aabda382f65a81" +dependencies = [ + "cfg-if", + "critical-section", + "defmt 1.1.0", + "embedded-io-async 0.7.0", + "futures-core", + "futures-sink", + "heapless 0.9.3", +] + +[[package]] +name = "embassy-time" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "592b0c143ec626e821d4d90da51a2bd91d559d6c442b7c74a47d368c9e23d97a" +dependencies = [ + "cfg-if", + "critical-section", + "defmt 1.1.0", + "document-features", + "embassy-time-driver", + "embedded-hal 0.2.7", + "embedded-hal 1.0.0", + "embedded-hal-async", + "futures-core", +] + +[[package]] +name = "embassy-time-driver" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6ee71af1b3a0deaa53eaf2d39252f83504c853646e472400b763060389b9fcc9" +dependencies = [ + "document-features", +] + +[[package]] +name = "embassy-time-queue-utils" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "168297bf80aaf114b3c9ad589bf38b01b3009b9af7f97cd18086c5bbf96f5693" +dependencies = [ + "embassy-executor-timer-queue", + "heapless 0.9.3", +] + +[[package]] +name = "embassy-usb" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a25746d8b152b72fbf2a217f489a083dbbe243f281f09184a1f2cfbe9bbb245f" +dependencies = [ + "bitflags 2.13.0", + "defmt 1.1.0", + "embassy-futures", + "embassy-net-driver-channel", + "embassy-sync", + "embassy-time", + "embassy-usb-driver", + "embedded-io-async 0.7.0", + "heapless 0.9.3", + "ssmarshal", + "usbd-hid", +] + +[[package]] +name = "embassy-usb-dfu" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e36d3678d16e1e71b052d00f7518620b5839a878f2bdab2019b81d984fb2a74f" +dependencies = [ + "bitflags 2.13.0", + "cortex-m", + "embassy-boot", + "embassy-futures", + "embassy-sync", + "embassy-time", + "embassy-usb", + "embedded-storage", +] + +[[package]] +name = "embassy-usb-driver" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fa675c5f4349b6aa0fcffc4bf9b241f18cd11b97c1f8323273fb9a5449937fbd" +dependencies = [ + "defmt 1.1.0", + "embedded-io-async 0.6.1", + "embedded-io-async 0.7.0", +] + +[[package]] +name = "embedded-hal" +version = "0.2.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "35949884794ad573cf46071e41c9b60efb0cb311e3ca01f7af807af1debc66ff" +dependencies = [ + "nb 0.1.3", + "void", +] + +[[package]] +name = "embedded-hal" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "361a90feb7004eca4019fb28352a9465666b24f840f5c3cddf0ff13920590b89" +dependencies = [ + "defmt 0.3.100", +] + +[[package]] +name = "embedded-hal-async" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0c4c685bbef7fe13c3c6dd4da26841ed3980ef33e841cddfa15ce8a8fb3f1884" +dependencies = [ + "defmt 0.3.100", + "embedded-hal 1.0.0", +] + +[[package]] +name = "embedded-io" +version = "0.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "edd0f118536f44f5ccd48bcb8b111bdc3de888b58c74639dfb034a357d0f206d" + +[[package]] +name = "embedded-io" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9eb1aa714776b75c7e67e1da744b81a129b3ff919c8712b5e1b32252c1f07cc7" +dependencies = [ + "defmt 1.1.0", +] + +[[package]] +name = "embedded-io-async" +version = "0.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3ff09972d4073aa8c299395be75161d582e7629cd663171d62af73c8d50dba3f" +dependencies = [ + "embedded-io 0.6.1", +] + +[[package]] +name = "embedded-io-async" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2564b9f813c544241430e147d8bc454815ef9ac998878d30cc3055449f7fd4c0" +dependencies = [ + "defmt 1.1.0", + "embedded-io 0.7.1", +] + +[[package]] +name = "embedded-storage" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a21dea9854beb860f3062d10228ce9b976da520a73474aed3171ec276bc0c032" + +[[package]] +name = "embedded-storage-async" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1763775e2323b7d5f0aa6090657f5e21cfa02ede71f5dc40eead06d64dcd15cc" +dependencies = [ + "embedded-storage", +] + +[[package]] +name = "encode_unicode" +version = "0.3.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a357d28ed41a50f9c765dbfe56cbc04a64e53e5fc58ba79fbc34c10ef3df831f" + +[[package]] +name = "encoding_rs" +version = "0.8.35" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "75030f3c4f45dafd7586dd6780965a8c7e8e285a5ecb86713e63a79c5b2766f3" +dependencies = [ + "cfg-if", +] + +[[package]] +name = "equivalent" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "877a4ace8713b0bcf2a4e7eec82529c029f1d0619886d18145fea96c3ffe5c0f" + +[[package]] +name = "erased-serde" +version = "0.4.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d2add8a07dd6a8d93ff627029c51de145e12686fbc36ecb298ac22e74cf02dec" +dependencies = [ + "serde", + "serde_core", + "typeid", +] + +[[package]] +name = "ff" +version = "0.13.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c0b50bfb653653f9ca9095b427bed08ab8d75a137839d9ad64eb11810d5b6393" +dependencies = [ + "rand_core 0.6.4", + "subtle", +] + +[[package]] +name = "find-msvc-tools" +version = "0.1.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5baebc0774151f905a1a2cc41989300b1e6fbb29aff0ceffa1064fdd3088d582" + +[[package]] +name = "fixed" +version = "1.31.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9af2cbf772fa6d1c11358f92ef554cb6b386201210bcf0e91fb7fba8a907fb40" +dependencies = [ + "az", + "bytemuck", + "half", + "typenum", +] + +[[package]] +name = "fnv" +version = "1.0.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" + +[[package]] +name = "foldhash" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "77ce24cb58228fbb8aa041425bb1050850ac19177686ea6e0f41a70416f56fdb" + +[[package]] +name = "futures" +version = "0.3.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8b147ee9d1f6d097cef9ce628cd2ee62288d963e16fb287bd9286455b241382d" +dependencies = [ + "futures-channel", + "futures-core", + "futures-io", + "futures-sink", + "futures-task", + "futures-util", +] + +[[package]] +name = "futures-channel" +version = "0.3.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "07bbe89c50d7a535e539b8c17bc0b49bdb77747034daa8087407d655f3f7cc1d" +dependencies = [ + "futures-core", + "futures-sink", +] + +[[package]] +name = "futures-core" +version = "0.3.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7e3450815272ef58cec6d564423f6e755e25379b217b0bc688e295ba24df6b1d" + +[[package]] +name = "futures-intrusive" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1d930c203dd0b6ff06e0201a4a2fe9149b43c684fd4420555b26d21b1a02956f" +dependencies = [ + "futures-core", + "lock_api", +] + +[[package]] +name = "futures-io" +version = "0.3.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cecba35d7ad927e23624b22ad55235f2239cfa44fd10428eecbeba6d6a717718" + +[[package]] +name = "futures-macro" +version = "0.3.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e835b70203e41293343137df5c0664546da5745f82ec9b84d40be8336958447b" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.118", +] + +[[package]] +name = "futures-sink" +version = "0.3.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c39754e157331b013978ec91992bde1ac089843443c49cbc7f46150b0fad0893" + +[[package]] +name = "futures-task" +version = "0.3.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "037711b3d59c33004d3856fbdc83b99d4ff37a24768fa1be9ce3538a1cde4393" + +[[package]] +name = "futures-util" +version = "0.3.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "389ca41296e6190b48053de0321d02a77f32f8a5d2461dd38762c0593805c6d6" +dependencies = [ + "futures-core", + "futures-macro", + "futures-sink", + "futures-task", + "pin-project-lite", + "slab", +] + +[[package]] +name = "generator" +version = "0.8.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b3b854b0e584ead1a33f18b2fcad7cf7be18b3875c78816b753639aa501513ae" +dependencies = [ + "cc", + "cfg-if", + "libc", + "log", + "rustversion", + "windows-link", + "windows-result", +] + +[[package]] +name = "generic-array" +version = "0.14.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "85649ca51fd72272d7821adaf274ad91c288277713d9c18820d8499a7ff69e9a" +dependencies = [ + "typenum", + "version_check", + "zeroize", +] + +[[package]] +name = "getrandom" +version = "0.2.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ff2abc00be7fca6ebc474524697ae276ad847ad0a6b3faa4bcb027e9a4614ad0" +dependencies = [ + "cfg-if", + "libc", + "wasi", +] + +[[package]] +name = "group" +version = "0.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f0f9ef7462f7c099f518d754361858f86d8a07af53ba9af0fe635bbccb151a63" +dependencies = [ + "ff", + "rand_core 0.6.4", + "subtle", +] + +[[package]] +name = "half" +version = "2.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6ea2d84b969582b4b1864a92dc5d27cd2b77b622a8d79306834f1be5ba20d84b" +dependencies = [ + "cfg-if", + "crunchy", + "zerocopy", +] + +[[package]] +name = "hash32" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b0c35f58762feb77d74ebe43bdbc3210f09be9fe6742234d573bacc26ed92b67" +dependencies = [ + "byteorder", +] + +[[package]] +name = "hash32" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "47d60b12902ba28e2730cd37e95b8c9223af2808df9e902d4df49588d1470606" +dependencies = [ + "byteorder", +] + +[[package]] +name = "hashbrown" +version = "0.13.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "43a3c133739dddd0d2990f9a4bdf8eb4b21ef50e4851ca85ab661199821d510e" +dependencies = [ + "ahash", +] + +[[package]] +name = "hashbrown" +version = "0.14.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e5274423e17b7c9fc20b6e7e208532f9b19825d82dfd615708b70edd83df41f1" + +[[package]] +name = "hashbrown" +version = "0.16.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "841d1cc9bed7f9236f321df977030373f4a4163ae1a7dbfe1a51a2c1a51d9100" +dependencies = [ + "foldhash", +] + +[[package]] +name = "hashbrown" +version = "0.17.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ed5909b6e89a2db4456e54cd5f673791d7eca6732202bbf2a9cc504fe2f9b84a" + +[[package]] +name = "hashlink" +version = "0.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "824e001ac4f3012dd16a264bec811403a67ca9deb6c102fc5049b32c4574b35f" +dependencies = [ + "hashbrown 0.16.1", +] + +[[package]] +name = "heapless" +version = "0.7.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cdc6457c0eb62c71aac4bc17216026d8410337c4126773b9c5daba343f17964f" +dependencies = [ + "atomic-polyfill", + "hash32 0.2.1", + "rustc_version 0.4.1", + "serde", + "spin", + "stable_deref_trait", +] + +[[package]] +name = "heapless" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0bfb9eb618601c89945a70e254898da93b13be0388091d42117462b265bb3fad" +dependencies = [ + "hash32 0.3.1", + "stable_deref_trait", +] + +[[package]] +name = "heapless" +version = "0.9.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "25ba4bd83f9415b58b4ed8dc5714c76e626a105be4646c02630ad730ad3b5aa4" +dependencies = [ + "defmt 1.1.0", + "hash32 0.3.1", + "serde_core", + "stable_deref_trait", +] + +[[package]] +name = "heck" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea" + +[[package]] +name = "hkdf" +version = "0.12.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7b5f8eb2ad728638ea2c7d47a21db23b7b58a72ed6a38256b8a1849f15fbbdf7" +dependencies = [ + "hmac", +] + +[[package]] +name = "hmac" +version = "0.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6c49c37c09c17a53d937dfbb742eb3a961d65a994e6bcdcf37e7399d0cc8ab5e" +dependencies = [ + "digest", +] + +[[package]] +name = "ident_case" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b9e0384b61958566e926dc50660321d12159025e767c18e043daf26b70104c39" + +[[package]] +name = "indexmap" +version = "2.14.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d466e9454f08e4a911e14806c24e16fba1b4c121d1ea474396f396069cf949d9" +dependencies = [ + "equivalent", + "hashbrown 0.17.1", +] + +[[package]] +name = "inout" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "879f10e63c20629ecabbb64a8010319738c66a5cd0c29b02d63d272b03751d01" +dependencies = [ + "generic-array", +] + +[[package]] +name = "itoa" +version = "1.0.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f42a60cbdf9a97f5d2305f08a87dc4e09308d1276d28c869c684d7777685682" + +[[package]] +name = "js-sys" +version = "0.3.102" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "03d04c30968dffe80775bd4d7fb676131cd04a1fb46d2686dbffbaec2d9dfd31" +dependencies = [ + "cfg-if", + "futures-util", + "wasm-bindgen", +] + +[[package]] +name = "json" +version = "0.12.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "078e285eafdfb6c4b434e0d31e8cfcb5115b651496faca5749b88fafd4f23bfd" + +[[package]] +name = "json5" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "96b0db21af676c1ce64250b5f40f3ce2cf27e4e47cb91ed91eb6fe9350b430c1" +dependencies = [ + "pest", + "pest_derive", + "serde", +] + +[[package]] +name = "lazy_static" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe" + +[[package]] +name = "libc" +version = "0.2.186" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "68ab91017fe16c622486840e4c83c9a37afeff978bd239b5293d61ece587de66" + +[[package]] +name = "litrs" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "11d3d7f243d5c5a8b9bb5d6dd2b1602c0cb0b9db1621bafc7ed66e35ff9fe092" + +[[package]] +name = "lock_api" +version = "0.4.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "224399e74b87b5f3557511d98dff8b14089b3dadafcab6bb93eab67d3aace965" +dependencies = [ + "scopeguard", +] + +[[package]] +name = "log" +version = "0.4.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "953f07c43838f8e6f9758cab68bf5bed85465e7587ebe0b823f1bcd81978ad3a" + +[[package]] +name = "loom" +version = "0.7.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "419e0dc8046cb947daa77eb95ae174acfbddb7673b4151f56d1eed8e93fbfaca" +dependencies = [ + "cfg-if", + "generator", + "scoped-tls", + "tracing", + "tracing-subscriber", +] + +[[package]] +name = "lzma-sys" +version = "0.1.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5fda04ab3764e6cde78b9974eec4f779acaba7c4e84b36eca3cf77c581b85d27" +dependencies = [ + "cc", + "libc", + "pkg-config", +] + +[[package]] +name = "matchers" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d1525a2a28c7f4fa0fc98bb91ae755d1e2d1505079e05539e35bc876b5d65ae9" +dependencies = [ + "regex-automata", +] + +[[package]] +name = "memchr" +version = "2.8.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "88904434abc2901f197fe8cc55f0445e7ded921dba5911dad2e2b39b48e663c4" + +[[package]] +name = "nb" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "801d31da0513b6ec5214e9bf433a77966320625a37860f910be265be6e18d06f" +dependencies = [ + "nb 1.1.0", +] + +[[package]] +name = "nb" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8d5439c4ad607c3c23abf66de8c8bf57ba8adcd1f129e699851a6e43935d339d" + +[[package]] +name = "nrf-pac" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bddd547fab92b0553ff37032034fd04ce8b8b60d3f9a83f89ea815dfd0400336" +dependencies = [ + "cortex-m", + "cortex-m-rt", +] + +[[package]] +name = "nu-ansi-term" +version = "0.50.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7957b9740744892f114936ab4a57b3f487491bbeafaf8083688b16841a4240e5" +dependencies = [ + "windows-sys", +] + +[[package]] +name = "num-traits" +version = "0.2.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841" +dependencies = [ + "autocfg", +] + +[[package]] +name = "once_cell" +version = "1.21.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9f7c3e4beb33f85d45ae3e3a1792185706c8e16d043238c593331cc7cd313b50" + +[[package]] +name = "ordered-multimap" +version = "0.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "49203cdcae0030493bad186b28da2fa25645fa276a51b6fec8010d281e02ef79" +dependencies = [ + "dlv-list", + "hashbrown 0.14.5", +] + +[[package]] +name = "p256" +version = "0.13.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c9863ad85fa8f4460f9c48cb909d38a0d689dba1f6f6988a5e3e0d31071bcd4b" +dependencies = [ + "elliptic-curve", + "primeorder", +] + +[[package]] +name = "panic-probe" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fd402d00b0fb94c5aee000029204a46884b1262e0c443f166d86d2c0747e1a1a" +dependencies = [ + "cortex-m", + "defmt 1.1.0", +] + +[[package]] +name = "paste" +version = "1.0.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "57c0d7b74b563b49d38dae00a0c37d4d6de9b432382b2892f0574ddcae73fd0a" + +[[package]] +name = "pathdiff" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "df94ce210e5bc13cb6651479fa48d14f601d9858cfe0467f43ae157023b938d3" + +[[package]] +name = "pest" +version = "2.8.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e0848c601009d37dfa3430c4666e147e49cdcf1b92ecd3e63657d8a5f19da662" +dependencies = [ + "memchr", + "ucd-trie", +] + +[[package]] +name = "pest_derive" +version = "2.8.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "11f486f1ea21e6c10ed15d5a7c77165d0ee443402f0780849d1768e7d9d6fe77" +dependencies = [ + "pest", + "pest_generator", +] + +[[package]] +name = "pest_generator" +version = "2.8.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8040c4647b13b210a963c1ed407c1ff4fdfa01c31d6d2a098218702e6664f94f" +dependencies = [ + "pest", + "pest_meta", + "proc-macro2", + "quote", + "syn 2.0.118", +] + +[[package]] +name = "pest_meta" +version = "2.8.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "89815c69d36021a140146f26659a81d6c2afa33d216d736dd4be5381a7362220" +dependencies = [ + "pest", + "sha2", +] + +[[package]] +name = "pin-project-lite" +version = "0.2.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a89322df9ebe1c1578d689c92318e070967d1042b512afbe49518723f4e6d5cd" + +[[package]] +name = "pkg-config" +version = "0.3.33" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "19f132c84eca552bf34cab8ec81f1c1dcc229b811638f9d283dceabe58c5569e" + +[[package]] +name = "portable-atomic" +version = "1.13.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c33a9471896f1c69cecef8d20cbe2f7accd12527ce60845ff44c153bb2a21b49" + +[[package]] +name = "postcard" +version = "1.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6764c3b5dd454e283a30e6dfe78e9b31096d9e32036b5d1eaac7a6119ccb9a24" +dependencies = [ + "cobs", + "defmt 1.1.0", + "heapless 0.7.17", + "postcard-derive", + "serde", +] + +[[package]] +name = "postcard-derive" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e0232bd009a197ceec9cc881ba46f727fcd8060a2d8d6a9dde7a69030a6fe2bb" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.118", +] + +[[package]] +name = "ppv-lite86" +version = "0.2.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "85eae3c4ed2f50dcfe72643da4befc30deadb458a9b590d720cde2f2b1e97da9" +dependencies = [ + "zerocopy", +] + +[[package]] +name = "primeorder" +version = "0.13.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "353e1ca18966c16d9deb1c69278edbc5f194139612772bd9537af60ac231e1e6" +dependencies = [ + "elliptic-curve", +] + +[[package]] +name = "proc-macro-error-attr2" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "96de42df36bb9bba5542fe9f1a054b8cc87e172759a1868aa05c1f3acc89dfc5" +dependencies = [ + "proc-macro2", + "quote", +] + +[[package]] +name = "proc-macro-error2" +version = "2.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "11ec05c52be0a07b08061f7dd003e7d7092e0472bc731b4af7bb1ef876109802" +dependencies = [ + "proc-macro-error-attr2", + "proc-macro2", + "quote", + "syn 2.0.118", +] + +[[package]] +name = "proc-macro2" +version = "1.0.106" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8fd00f0bb2e90d81d1044c2b32617f68fcb9fa3bb7640c23e9c748e53fb30934" +dependencies = [ + "unicode-ident", +] + +[[package]] +name = "quote" +version = "1.0.45" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "41f2619966050689382d2b44f664f4bc593e129785a36d6ee376ddf37259b924" +dependencies = [ + "proc-macro2", +] + +[[package]] +name = "rand" +version = "0.8.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5ca0ecfa931c29007047d1bc58e623ab12e5590e8c7cc53200d5202b69266d8a" +dependencies = [ + "rand_core 0.6.4", +] + +[[package]] +name = "rand_chacha" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88" +dependencies = [ + "ppv-lite86", + "rand_core 0.6.4", +] + +[[package]] +name = "rand_core" +version = "0.6.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" + +[[package]] +name = "rand_core" +version = "0.9.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "76afc826de14238e6e8c374ddcc1fa19e374fd8dd986b0d2af0d02377261d83c" + +[[package]] +name = "regex-automata" +version = "0.4.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6e1dd4122fc1595e8162618945476892eefca7b88c52820e74af6262213cae8f" +dependencies = [ + "aho-corasick", + "memchr", + "regex-syntax", +] + +[[package]] +name = "regex-syntax" +version = "0.8.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d6f6ff9a378485b298a5286656da665ba74413d36db0979633275d2e708145d4" + +[[package]] +name = "rmk" +version = "0.8.2" +dependencies = [ + "bt-hci", + "byteorder", + "cortex-m", + "crc32fast", + "defmt 1.1.0", + "document-features", + "embassy-boot", + "embassy-embedded-hal", + "embassy-futures", + "embassy-nrf", + "embassy-sync", + "embassy-time", + "embassy-usb", + "embassy-usb-dfu", + "embedded-hal 1.0.0", + "embedded-hal-async", + "embedded-io-async 0.7.0", + "embedded-storage", + "embedded-storage-async", + "futures", + "heapless 0.9.3", + "paste", + "postcard", + "rmk-macro", + "rmk-types", + "sequential-storage", + "serde", + "static_cell", + "trouble-host", + "usbd-hid", +] + +[[package]] +name = "rmk-config" +version = "0.6.1" +dependencies = [ + "config", + "once_cell", + "paste", + "pest", + "pest_derive", + "serde", + "serde-inline-default", + "toml 1.1.2+spec-1.1.0", +] + +[[package]] +name = "rmk-macro" +version = "0.7.1" +dependencies = [ + "cargo_toml", + "darling 0.23.0", + "proc-macro2", + "quote", + "rmk-config", + "rmk-types", + "strum", + "syn 2.0.118", +] + +[[package]] +name = "rmk-nrf52840-embassy-boot" +version = "0.2.0" +dependencies = [ + "const-gen", + "cortex-m", + "cortex-m-rt", + "defmt 1.1.0", + "defmt-rtt", + "embassy-boot", + "embassy-executor", + "embassy-nrf", + "embassy-time", + "json", + "panic-probe", + "rmk", + "xz2", +] + +[[package]] +name = "rmk-types" +version = "0.2.2" +dependencies = [ + "bitfield-struct", + "defmt 1.1.0", + "heapless 0.9.3", + "postcard", + "rmk-config", + "serde", + "strum", + "toml 1.1.2+spec-1.1.0", +] + +[[package]] +name = "ron" +version = "0.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4147b952f3f819eca0e99527022f7d6a8d05f111aeb0a62960c74eb283bec8fc" +dependencies = [ + "bitflags 2.13.0", + "once_cell", + "serde", + "serde_derive", + "typeid", + "unicode-ident", +] + +[[package]] +name = "rust-ini" +version = "0.21.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "796e8d2b6696392a43bea58116b667fb4c29727dc5abd27d6acf338bb4f688c7" +dependencies = [ + "cfg-if", + "ordered-multimap", +] + +[[package]] +name = "rustc_version" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "138e3e0acb6c9fb258b19b67cb8abd63c00679d2851805ea151465464fe9030a" +dependencies = [ + "semver 0.9.0", +] + +[[package]] +name = "rustc_version" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cfcb3a22ef46e85b45de6ee7e79d063319ebb6594faafcf1c225ea92ab6e9b92" +dependencies = [ + "semver 1.0.28", +] + +[[package]] +name = "rustversion" +version = "1.0.22" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b39cdef0fa800fc44525c84ccb54a029961a8215f9619753635a9c0d2538d46d" + +[[package]] +name = "scoped-tls" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e1cf6437eb19a8f4a6cc0f7dca544973b0b78843adbfeb3683d1a94a0024a294" + +[[package]] +name = "scopeguard" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" + +[[package]] +name = "sec1" +version = "0.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d3e97a565f76233a6003f9f5c54be1d9c5bdfa3eccfb189469f11ec4901c47dc" +dependencies = [ + "base16ct", + "der", + "generic-array", + "subtle", + "zeroize", +] + +[[package]] +name = "semver" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1d7eb9ef2c18661902cc47e535f9bc51b78acd254da71d375c2f6720d9a40403" +dependencies = [ + "semver-parser", +] + +[[package]] +name = "semver" +version = "1.0.28" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8a7852d02fc848982e0c167ef163aaff9cd91dc640ba85e263cb1ce46fae51cd" + +[[package]] +name = "semver-parser" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "388a1df253eca08550bef6c72392cfe7c30914bf41df5269b68cbd6ff8f570a3" + +[[package]] +name = "sequential-storage" +version = "7.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "574e5a379bf43653079b34cb4cf32958404b5f42e0ed5b5adcdff02c2de04d4d" +dependencies = [ + "defmt 1.1.0", + "embedded-storage-async", + "postcard", + "serde", +] + +[[package]] +name = "serde" +version = "1.0.228" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9a8e94ea7f378bd32cbbd37198a4a91436180c5bb472411e48b5ec2e2124ae9e" +dependencies = [ + "serde_core", + "serde_derive", +] + +[[package]] +name = "serde-inline-default" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2bf03b7a5281cfd4013bc788d057b0f09fc634397d83bc8973c955bd4f32727a" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.118", +] + +[[package]] +name = "serde-untagged" +version = "0.1.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f9faf48a4a2d2693be24c6289dbe26552776eb7737074e6722891fadbe6c5058" +dependencies = [ + "erased-serde", + "serde", + "serde_core", + "typeid", +] + +[[package]] +name = "serde_core" +version = "1.0.228" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "41d385c7d4ca58e59fc732af25c3983b67ac852c1a25000afe1175de458b67ad" +dependencies = [ + "serde_derive", +] + +[[package]] +name = "serde_derive" +version = "1.0.228" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d540f220d3187173da220f885ab66608367b6574e925011a9353e4badda91d79" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.118", +] + +[[package]] +name = "serde_json" +version = "1.0.150" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e8014e44b4736ed0538adeecded0fce2a272f22dc9578a7eb6b2d9993c74cfb9" +dependencies = [ + "itoa", + "memchr", + "serde", + "serde_core", + "zmij", +] + +[[package]] +name = "serde_spanned" +version = "1.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6662b5879511e06e8999a8a235d848113e942c9124f211511b16466ee2995f26" +dependencies = [ + "serde_core", +] + +[[package]] +name = "sha2" +version = "0.10.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a7507d819769d01a365ab707794a4084392c824f54a7a6a7862f8c3d0892b283" +dependencies = [ + "cfg-if", + "cpufeatures", + "digest", +] + +[[package]] +name = "sharded-slab" +version = "0.1.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f40ca3c46823713e0d4209592e8d6e826aa57e928f09752619fc696c499637f6" +dependencies = [ + "lazy_static", +] + +[[package]] +name = "shlex" +version = "2.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f8fadd59c855ef2080decdef8ff161eb6661b86933c9d82e5ba29dc602a55aba" + +[[package]] +name = "signature" +version = "2.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "77549399552de45a898a580c1b41d445bf730df867cc44e6c0233bbc4b8329de" + +[[package]] +name = "slab" +version = "0.4.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0c790de23124f9ab44544d7ac05d60440adc586479ce501c1d6d7da3cd8c9cf5" + +[[package]] +name = "smallvec" +version = "1.15.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8ed6a63f02c8539c91a8685a86f4099661ba3da017932f6ebbea6de3f0fa7c90" + +[[package]] +name = "spin" +version = "0.9.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6980e8d7511241f8acf4aebddbb1ff938df5eebe98691418c4468d0b72a96a67" +dependencies = [ + "lock_api", +] + +[[package]] +name = "ssmarshal" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f3e6ad23b128192ed337dfa4f1b8099ced0c2bf30d61e551b65fda5916dbb850" +dependencies = [ + "encode_unicode", + "serde", +] + +[[package]] +name = "stable_deref_trait" +version = "1.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6ce2be8dc25455e1f91df71bfa12ad37d7af1092ae736f3a6cd0e37bc7810596" + +[[package]] +name = "static_cell" +version = "2.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0530892bb4fa575ee0da4b86f86c667132a94b74bb72160f58ee5a4afec74c23" +dependencies = [ + "portable-atomic", +] + +[[package]] +name = "strsim" +version = "0.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f" + +[[package]] +name = "strum" +version = "0.28.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9628de9b8791db39ceda2b119bbe13134770b56c138ec1d3af810d045c04f9bd" +dependencies = [ + "strum_macros", +] + +[[package]] +name = "strum_macros" +version = "0.28.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ab85eea0270ee17587ed4156089e10b9e6880ee688791d45a905f5b1ca36f664" +dependencies = [ + "heck", + "proc-macro2", + "quote", + "syn 2.0.118", +] + +[[package]] +name = "subtle" +version = "2.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "13c2bddecc57b384dee18652358fb23172facb8a2c51ccc10d74c157bdea3292" + +[[package]] +name = "syn" +version = "1.0.109" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[package]] +name = "syn" +version = "2.0.118" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1b9ae57f904213ebb649ce6895b8a66c66f0203b9319718f69a5612a065b1422" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[package]] +name = "thiserror" +version = "2.0.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4288b5bcbc7920c07a1149a35cf9590a2aa808e0bc1eafaade0b80947865fbc4" +dependencies = [ + "thiserror-impl", +] + +[[package]] +name = "thiserror-impl" +version = "2.0.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ebc4ee7f67670e9b64d05fa4253e753e016c6c95ff35b89b7941d6b856dec1d5" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.118", +] + +[[package]] +name = "thread_local" +version = "1.1.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f60246a4944f24f6e018aa17cdeffb7818b76356965d03b07d6a9886e8962185" +dependencies = [ + "cfg-if", +] + +[[package]] +name = "tiny-keccak" +version = "2.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2c9d3793400a45f954c52e73d068316d76b6f4e36977e3fcebb13a2721e80237" +dependencies = [ + "crunchy", +] + +[[package]] +name = "toml" +version = "0.9.12+spec-1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cf92845e79fc2e2def6a5d828f0801e29a2f8acc037becc5ab08595c7d5e9863" +dependencies = [ + "indexmap", + "serde_core", + "serde_spanned", + "toml_datetime 0.7.5+spec-1.1.0", + "toml_parser", + "toml_writer", + "winnow 0.7.15", +] + +[[package]] +name = "toml" +version = "1.1.2+spec-1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "81f3d15e84cbcd896376e6730314d59fb5a87f31e4b038454184435cd57defee" +dependencies = [ + "indexmap", + "serde_core", + "serde_spanned", + "toml_datetime 1.1.1+spec-1.1.0", + "toml_parser", + "toml_writer", + "winnow 1.0.3", +] + +[[package]] +name = "toml_datetime" +version = "0.7.5+spec-1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "92e1cfed4a3038bc5a127e35a2d360f145e1f4b971b551a2ba5fd7aedf7e1347" +dependencies = [ + "serde_core", +] + +[[package]] +name = "toml_datetime" +version = "1.1.1+spec-1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3165f65f62e28e0115a00b2ebdd37eb6f3b641855f9d636d3cd4103767159ad7" +dependencies = [ + "serde_core", +] + +[[package]] +name = "toml_parser" +version = "1.1.2+spec-1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a2abe9b86193656635d2411dc43050282ca48aa31c2451210f4202550afb7526" +dependencies = [ + "winnow 1.0.3", +] + +[[package]] +name = "toml_writer" +version = "1.1.1+spec-1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "756daf9b1013ebe47a8776667b466417e2d4c5679d441c26230efd9ef78692db" + +[[package]] +name = "tracing" +version = "0.1.44" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "63e71662fa4b2a2c3a26f570f037eb95bb1f85397f3cd8076caed2f026a6d100" +dependencies = [ + "pin-project-lite", + "tracing-attributes", + "tracing-core", +] + +[[package]] +name = "tracing-attributes" +version = "0.1.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7490cfa5ec963746568740651ac6781f701c9c5ea257c58e057f3ba8cf69e8da" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.118", +] + +[[package]] +name = "tracing-core" +version = "0.1.36" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "db97caf9d906fbde555dd62fa95ddba9eecfd14cb388e4f491a66d74cd5fb79a" +dependencies = [ + "once_cell", + "valuable", +] + +[[package]] +name = "tracing-log" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ee855f1f400bd0e5c02d150ae5de3840039a3f54b025156404e34c23c03f47c3" +dependencies = [ + "log", + "once_cell", + "tracing-core", +] + +[[package]] +name = "tracing-subscriber" +version = "0.3.23" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cb7f578e5945fb242538965c2d0b04418d38ec25c79d160cd279bf0731c8d319" +dependencies = [ + "matchers", + "nu-ansi-term", + "once_cell", + "regex-automata", + "sharded-slab", + "smallvec", + "thread_local", + "tracing", + "tracing-core", + "tracing-log", +] + +[[package]] +name = "trouble-host" +version = "0.6.0" +source = "git+https://github.com/haobogu/trouble?rev=690373fd1166d16225b875435dd0600c92570e7d#690373fd1166d16225b875435dd0600c92570e7d" +dependencies = [ + "aes", + "bt-hci", + "cmac", + "defmt 1.1.0", + "embassy-futures", + "embassy-sync", + "embassy-time", + "embedded-io 0.7.1", + "futures", + "heapless 0.9.3", + "p256", + "rand", + "rand_chacha", + "rand_core 0.6.4", + "serde", + "static_cell", + "trouble-host-macros", + "zerocopy", +] + +[[package]] +name = "trouble-host-macros" +version = "0.4.0" +source = "git+https://github.com/haobogu/trouble?rev=690373fd1166d16225b875435dd0600c92570e7d#690373fd1166d16225b875435dd0600c92570e7d" +dependencies = [ + "convert_case 0.8.0", + "darling 0.20.11", + "proc-macro2", + "quote", + "syn 2.0.118", + "uuid", +] + +[[package]] +name = "typeid" +version = "1.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bc7d623258602320d5c55d1bc22793b57daff0ec7efc270ea7d55ce1d5f5471c" + +[[package]] +name = "typenum" +version = "1.20.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b6f5e870be6c3b371b77fe0ee0bafb859fa4964b4404c27de1d380043c4dda20" + +[[package]] +name = "ucd-trie" +version = "0.1.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2896d95c02a80c6d6a5d6e953d479f5ddf2dfdb6a244441010e373ac0fb88971" + +[[package]] +name = "unicode-ident" +version = "1.0.24" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e6e4313cd5fcd3dad5cafa179702e2b244f760991f45397d14d4ebf38247da75" + +[[package]] +name = "unicode-segmentation" +version = "1.13.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c6f5d3c3b1bf09027a88a6bc961fc00497d651009560b5463668dc81b0fa87a8" + +[[package]] +name = "usb-device" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "98816b1accafbb09085168b90f27e93d790b4bfa19d883466b5e53315b5f06a6" +dependencies = [ + "defmt 0.3.100", + "heapless 0.8.0", + "portable-atomic", +] + +[[package]] +name = "usbd-hid" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "68beab087e4971a2fe76f631478b0e91d39593f58efd2775026ce6dc07a7bac6" +dependencies = [ + "defmt 0.3.100", + "usb-device", + "usbd-hid-macros", +] + +[[package]] +name = "usbd-hid-descriptors" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b297f021719c4308d5d0c61b6c1e7c6b3ba383deba774b49aa5484f996bdb8f1" +dependencies = [ + "bitfield 0.14.0", +] + +[[package]] +name = "usbd-hid-macros" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "011a3219e0933f5b3ad7dc90d9a66541a967d084c98c067deed1cd608e557ed7" +dependencies = [ + "byteorder", + "hashbrown 0.13.2", + "log", + "proc-macro2", + "quote", + "serde", + "syn 2.0.118", + "usbd-hid-descriptors", +] + +[[package]] +name = "uuid" +version = "1.23.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "144d6b123cef80b301b8f72a9e2ca4370ddec21950d0a103dd22c437006d2db7" +dependencies = [ + "js-sys", + "wasm-bindgen", +] + +[[package]] +name = "valuable" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ba73ea9cf16a25df0c8caa16c51acb937d5712a8429db78a3ee29d5dcacd3a65" + +[[package]] +name = "vcell" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "77439c1b53d2303b20d9459b1ade71a83c716e3f9c34f3228c00e6f185d6c002" + +[[package]] +name = "version_check" +version = "0.9.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b928f33d975fc6ad9f86c8f283853ad26bdd5b10b7f1542aa2fa15e2289105a" + +[[package]] +name = "void" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6a02e4885ed3bc0f2de90ea6dd45ebcbb66dacffe03547fadbb0eeae2770887d" + +[[package]] +name = "volatile-register" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "de437e2a6208b014ab52972a27e59b33fa2920d3e00fe05026167a1c509d19cc" +dependencies = [ + "vcell", +] + +[[package]] +name = "wasi" +version = "0.11.1+wasi-snapshot-preview1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ccf3ec651a847eb01de73ccad15eb7d99f80485de043efb2f370cd654f4ea44b" + +[[package]] +name = "wasm-bindgen" +version = "0.2.125" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8ddb3f79143bced6de84270411622a2699cee572fc0875aeaf1e7867cf9fca1a" +dependencies = [ + "cfg-if", + "once_cell", + "rustversion", + "wasm-bindgen-macro", + "wasm-bindgen-shared", +] + +[[package]] +name = "wasm-bindgen-macro" +version = "0.2.125" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4e21a184b13fb19e157296e2c46056aec9092264fab83e4ba59e68c61b323c3d" +dependencies = [ + "quote", + "wasm-bindgen-macro-support", +] + +[[package]] +name = "wasm-bindgen-macro-support" +version = "0.2.125" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fecefd9c35bd935a20fc3fc344b5f29138961e4f47fb03297d88f2587afb5ebd" +dependencies = [ + "bumpalo", + "proc-macro2", + "quote", + "syn 2.0.118", + "wasm-bindgen-shared", +] + +[[package]] +name = "wasm-bindgen-shared" +version = "0.2.125" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "23939e44bb9a5d7576fa2b563dc2e136628f1224e88a8deed09e04858b77871f" +dependencies = [ + "unicode-ident", +] + +[[package]] +name = "windows-link" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f0805222e57f7521d6a62e36fa9163bc891acd422f971defe97d64e70d0a4fe5" + +[[package]] +name = "windows-result" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7781fa89eaf60850ac3d2da7af8e5242a5ea78d1a11c49bf2910bb5a73853eb5" +dependencies = [ + "windows-link", +] + +[[package]] +name = "windows-sys" +version = "0.61.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ae137229bcbd6cdf0f7b80a31df61766145077ddf49416a728b02cb3921ff3fc" +dependencies = [ + "windows-link", +] + +[[package]] +name = "winnow" +version = "0.7.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "df79d97927682d2fd8adb29682d1140b343be4ac0f08fd68b7765d9c059d3945" + +[[package]] +name = "winnow" +version = "1.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0592e1c9d151f854e6fd382574c3a0855250e1d9b2f99d9281c6e6391af352f1" +dependencies = [ + "memchr", +] + +[[package]] +name = "xz2" +version = "0.1.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "388c44dc09d76f1536602ead6d325eb532f5c122f17782bd57fb47baeeb767e2" +dependencies = [ + "lzma-sys", +] + +[[package]] +name = "yaml-rust2" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "631a50d867fafb7093e709d75aaee9e0e0d5deb934021fcea25ac2fe09edc51e" +dependencies = [ + "arraydeque", + "encoding_rs", + "hashlink", +] + +[[package]] +name = "zerocopy" +version = "0.8.52" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ce1022995ff5ff5d841ad7d994facc23098cd40152f2c1d11cd607c6f530653f" +dependencies = [ + "zerocopy-derive", +] + +[[package]] +name = "zerocopy-derive" +version = "0.8.52" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1ae7f38b72ec2a254e2b87ef277cf2cd4fb97cbebf944faa6f33354da0867930" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.118", +] + +[[package]] +name = "zeroize" +version = "1.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e13c156562582aa81c60cb29407084cdb54c4164760106ab78e6c5b0858cf64e" + +[[package]] +name = "zmij" +version = "1.0.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b8848ee67ecc8aedbaf3e4122217aff892639231befc6a1b58d29fff4c2cabaa" diff --git a/examples/use_rust/nrf52840_embassy_boot/Cargo.toml b/examples/use_rust/nrf52840_embassy_boot/Cargo.toml new file mode 100644 index 000000000..4ebc8eb0b --- /dev/null +++ b/examples/use_rust/nrf52840_embassy_boot/Cargo.toml @@ -0,0 +1,59 @@ +[package] +name = "rmk-nrf52840-embassy-boot" +version = "0.2.0" +authors = ["Haobo Gu "] +description = "Keyboard firmware written in Rust" +homepage = "https://github.com/haobogu/rmk" +repository = "https://github.com/haobogu/rmk" +readme = "../../README.md" +edition = "2024" +license = "MIT OR Apache-2.0" + +[dependencies] +rmk = { path = "../../../rmk", features = [ + "dfu_nrf", + # "dfu_lock" +] } +embassy-time = { version = "0.5", features = ["defmt"] } +embassy-nrf = { version = "0.10", features = [ + "defmt", + "nrf52840", + "time-driver-rtc1", + "gpiote", +] } +embassy-boot = { version = "0.7" } +embassy-executor = { version = "0.10", features = [ + "defmt", + "platform-cortex-m", + "executor-thread", +] } +cortex-m = { version = "0.7.7", features = ["critical-section-single-core"] } +cortex-m-rt = { version = "0.7.5", features = ["set-vtor"] } +defmt = "1.0" +defmt-rtt = "1.0" +panic-probe = { version = "1.0", features = ["print-defmt"] } + +[build-dependencies] +xz2 = "0.1.7" +json = "0.12" +const-gen = "1.6" + +[[bin]] +name = "rmk-nrf52840-embassy-boot" +test = false +bench = false + +[profile.dev] +codegen-units = 1 +debug = true +opt-level = 1 +overflow-checks = true +lto = false +panic = 'unwind' + +[profile.release] +codegen-units = 1 +debug = true +opt-level = "z" +overflow-checks = false +lto = "fat" diff --git a/examples/use_rust/nrf52840_embassy_boot/Makefile.toml b/examples/use_rust/nrf52840_embassy_boot/Makefile.toml new file mode 100644 index 000000000..a390948bb --- /dev/null +++ b/examples/use_rust/nrf52840_embassy_boot/Makefile.toml @@ -0,0 +1,41 @@ +[tasks.install-llvm-tools] +install_crate = { rustup_component_name = "llvm-tools" } + +[tasks.flip-link] +install_crate = { crate_name = "flip-link", binary = "flip-link", test_arg = ["-h"] } + +[tasks.build] +command = "cargo" +args = ["build", "--release"] +dependencies = ["install-llvm-tools", "flip-link"] + +[tasks.bin] +command = "cargo" +args = ["objcopy", "--release", "--", "-O", "binary", "${CARGO_MAKE_PROJECT_NAME}.bin"] +dependencies = ["build"] + +[tasks.objcopy] +install_crate = { crate_name = "cargo-binutils", binary = "cargo", test_arg = [ + "objcopy", + "--help", +] } +command = "cargo" +args = ["objcopy", "--release", "--", "-O", "ihex", "rmk.hex"] +dependencies = ["build"] + +[tasks.uf2] +install_crate = { crate_name = "cargo-hex-to-uf2", binary = "cargo", test_arg = [ + "hex-to-uf2", + "--help", +] } +command = "cargo" +args = [ + "hex-to-uf2", + "--input-path", + "rmk.hex", + "--output-path", + "rmk.uf2", + "--family", + "nrf52840", +] +dependencies = ["objcopy"] diff --git a/examples/use_rust/nrf52840_embassy_boot/build.rs b/examples/use_rust/nrf52840_embassy_boot/build.rs new file mode 100644 index 000000000..5268bfea6 --- /dev/null +++ b/examples/use_rust/nrf52840_embassy_boot/build.rs @@ -0,0 +1,53 @@ +use std::fs::File; +use std::io::{Read, Write}; +use std::path::{Path, PathBuf}; +use std::{env, fs}; + +use const_gen::*; +use xz2::read::XzEncoder; + +fn main() { + println!("cargo:rerun-if-changed=vial.json"); + generate_vial_config(); + + let out = &PathBuf::from(env::var_os("OUT_DIR").unwrap()); + File::create(out.join("memory.x")) + .unwrap() + .write_all(include_bytes!("memory.x")) + .unwrap(); + println!("cargo:rustc-link-search={}", out.display()); + + println!("cargo:rerun-if-changed=memory.x"); + + println!("cargo:rustc-link-arg=--nmagic"); + println!("cargo:rustc-link-arg=-Tlink.x"); + println!("cargo:rustc-link-arg=-Tdefmt.x"); +} + +fn generate_vial_config() { + let out_file = Path::new(&env::var_os("OUT_DIR").unwrap()).join("config_generated.rs"); + + let p = Path::new("vial.json"); + let mut content = String::new(); + match File::open(p) { + Ok(mut file) => { + file.read_to_string(&mut content).expect("Cannot read vial.json"); + } + Err(e) => println!("Cannot find vial.json {:?}: {}", p, e), + }; + + let vial_cfg = json::stringify(json::parse(&content).unwrap()); + let mut keyboard_def_compressed: Vec = Vec::new(); + XzEncoder::new(vial_cfg.as_bytes(), 6) + .read_to_end(&mut keyboard_def_compressed) + .unwrap(); + + let keyboard_id: Vec = vec![0xB9, 0xBC, 0x09, 0xB2, 0x9D, 0x37, 0x4C, 0xEA]; + let const_declarations = [ + const_declaration!(pub VIAL_KEYBOARD_DEF = keyboard_def_compressed), + const_declaration!(pub VIAL_KEYBOARD_ID = keyboard_id), + ] + .map(|s| "#[allow(clippy::redundant_static_lifetimes)]\n".to_owned() + s.as_str()) + .join("\n"); + fs::write(out_file, const_declarations).unwrap(); +} diff --git a/examples/use_rust/nrf52840_embassy_boot/memory.x b/examples/use_rust/nrf52840_embassy_boot/memory.x new file mode 100644 index 000000000..769874737 --- /dev/null +++ b/examples/use_rust/nrf52840_embassy_boot/memory.x @@ -0,0 +1,11 @@ +/* +Flash layout matching bootymcbootface nRF layout: + bootloader: 24K at 0x0, state: 4K at 0x6000 + ACTIVE (this firmware): 464K at 0x7000 + DFU: 468K at 0x7B000 + storage: 64K at 0xF0000 +*/ +MEMORY { + FLASH : ORIGIN = 0x00007000, LENGTH = 432K + RAM : ORIGIN = 0x20000000, LENGTH = 256K +} diff --git a/examples/use_rust/nrf52840_embassy_boot/src/keymap.rs b/examples/use_rust/nrf52840_embassy_boot/src/keymap.rs new file mode 100644 index 000000000..0ee3d0839 --- /dev/null +++ b/examples/use_rust/nrf52840_embassy_boot/src/keymap.rs @@ -0,0 +1,23 @@ +use rmk::types::action::KeyAction; +use rmk::{a, k, layer, mo}; +pub(crate) const COL: usize = 3; +pub(crate) const ROW: usize = 4; +pub(crate) const NUM_LAYER: usize = 2; + +#[rustfmt::skip] +pub const fn get_default_keymap() -> [[[KeyAction; COL]; ROW]; NUM_LAYER] { + [ + layer!([ + [k!(AudioVolUp), k!(B), k!(AudioVolDown)], + [k!(Kp4), k!(LShift), k!(Kp6)], + [mo!(1), k!(Kp2), k!(Kp3)], + [mo!(1), a!(No), k!(Kp0)] + ]), + layer!([ + [k!(Kp7), k!(Kp8), k!(Kp9)], + [k!(Kp4), k!(LCtrl), k!(Kp6)], + [mo!(1), k!(Kp2), k!(Kp3)], + [mo!(1), a!(No), k!(Kp0)] + ]), + ] +} diff --git a/examples/use_rust/nrf52840_embassy_boot/src/macros.rs b/examples/use_rust/nrf52840_embassy_boot/src/macros.rs new file mode 100644 index 000000000..441e3e2dc --- /dev/null +++ b/examples/use_rust/nrf52840_embassy_boot/src/macros.rs @@ -0,0 +1,12 @@ +macro_rules! config_matrix_pins_nrf { + (peripherals: $p:ident, input: [$($in_pin:ident), *], output: [$($out_pin:ident), +]) => { + { + let mut output_pins = [$(Output::new($p.$out_pin, embassy_nrf::gpio::Level::Low, embassy_nrf::gpio::OutputDrive::Standard)), +]; + let input_pins = [$(Input::new($p.$in_pin, embassy_nrf::gpio::Pull::Down)), +]; + output_pins.iter_mut().for_each(|p| { + p.set_low(); + }); + (input_pins, output_pins) + } + }; +} diff --git a/examples/use_rust/nrf52840_embassy_boot/src/main.rs b/examples/use_rust/nrf52840_embassy_boot/src/main.rs new file mode 100644 index 000000000..ec7d48cb2 --- /dev/null +++ b/examples/use_rust/nrf52840_embassy_boot/src/main.rs @@ -0,0 +1,166 @@ +#![no_main] +#![no_std] + +#[macro_use] +mod keymap; +#[macro_use] +mod macros; +mod vial; + +use defmt::info; +use defmt_rtt as _; +use embassy_executor::Spawner; +use embassy_nrf::gpio::{Input, Level, Output, OutputDrive}; +use embassy_nrf::interrupt::InterruptExt; +use embassy_nrf::usb::{self, Driver}; +use embassy_nrf::{bind_interrupts, peripherals}; +use keymap::{COL, ROW}; +use panic_probe as _; +use rmk::config::{BehaviorConfig, DeviceConfig, PositionalConfig, RmkConfig, StorageConfig, VialConfig}; +use rmk::debounce::default_debouncer::DefaultDebouncer; +use rmk::host::HostService; +use rmk::keyboard::Keyboard; +use rmk::matrix::Matrix; +use rmk::processor::builtin::wpm::WpmProcessor; +use rmk::storage::async_flash_wrapper; +use rmk::usb::UsbTransport; +use rmk::{KeymapData, initialize_keymap_and_storage, run_all}; +use vial::{VIAL_KEYBOARD_DEF, VIAL_KEYBOARD_ID}; + +bind_interrupts!(struct Irqs { + USBD => usb::InterruptHandler; + CLOCK_POWER => usb::vbus_detect::InterruptHandler; +}); + +#[embassy_executor::main] +async fn main(_spawner: Spawner) { + info!("RMK start!"); + let mut config = embassy_nrf::config::Config::default(); + config.gpiote_interrupt_priority = embassy_nrf::interrupt::Priority::P3; + config.time_interrupt_priority = embassy_nrf::interrupt::Priority::P3; + embassy_nrf::interrupt::USBD.set_priority(embassy_nrf::interrupt::Priority::P2); + embassy_nrf::interrupt::CLOCK_POWER.set_priority(embassy_nrf::interrupt::Priority::P2); + config.debug = embassy_nrf::config::Debug::NotConfigured; + let p = embassy_nrf::init(config); + embassy_nrf::pac::CLOCK.tasks_hfclkstart().write_value(1); + while embassy_nrf::pac::CLOCK.events_hfclkstarted().read() != 1 {} + + let driver = Driver::new(p.USBD, Irqs, usb::vbus_detect::HardwareVbusDetect::new(Irqs)); + + let (row_pins, col_pins) = + config_matrix_pins_nrf!(peripherals: p, input: [P0_07, P0_22, P0_11, P0_12], output: [P0_13, P0_17, P0_20]); + + // Flash layout using the bootymcbootface formula: + // state at 0x6000 (4K), active from 0x7000 (size: (flash_size - 28K (= embassy-boot + embassy-boot state) - STORAGE_SIZE (= 64K) - page_size (= 4K)) / 2), + // dfu follows active (active_size + page_size (= 4K)) + // + // All offsets (DFU_OFFSET, DFU_SIZE, STORAGE_OFFSET, etc.) are derived + // automatically from FLASH_SIZE below — change only that constant when using + // bootymcbootface. + // + // ⚠ You can define your own FLASH_SIZE and addresses, but then you must build and + // flash a custom embassy-boot bootloader with a matching memory.x! + const FLASH_SIZE: u32 = 1024 * 1024; // 1 MB (nRF52840) + const PAGE_SIZE: u32 = 4 * 1024; + const STORAGE_SIZE: u32 = 128 * 1024; // 32 sectors × 4K after ACTIVE+DFU + const STATE_OFFSET: u32 = 0x6000; + const STATE_SIZE: u32 = 0x1000; + const ACTIVE_OFFSET: u32 = 0x7000; + let remaining: u32 = FLASH_SIZE + - 28 * 1024 // bootloader (24K) + state (4K) + - STORAGE_SIZE; + let active_size: u32 = (remaining - PAGE_SIZE) / 2; + let dfu_size: u32 = active_size + PAGE_SIZE; + let dfu_offset: u32 = ACTIVE_OFFSET + active_size; + let storage_offset: u32 = dfu_offset + dfu_size; + assert!(storage_offset + STORAGE_SIZE == FLASH_SIZE); + + info!( + "Flash layout: state @ 0x{:04X} ({}K), active @ 0x{:04X} ({}K), dfu @ 0x{:04X} ({}K), storage @ 0x{:04X} ({}K)", + STATE_OFFSET, + STATE_SIZE / 1024, + ACTIVE_OFFSET, + active_size / 1024, + dfu_offset, + dfu_size / 1024, + storage_offset, + STORAGE_SIZE / 1024 + ); + + let flash = async_flash_wrapper(rmk::dfu::init_flash( + p.NVMC, + storage_offset, + STORAGE_SIZE, + STATE_OFFSET, + STATE_SIZE, + dfu_offset, + dfu_size, + )); + + rmk::dfu::set_led(Some(Output::new(p.P0_15, Level::Low, OutputDrive::Standard))); + + let keyboard_device_config = DeviceConfig { + vid: 0x4c4b, + pid: 0x4643, + manufacturer: "Haobo", + product_name: "RMK Keyboard nRF52840 embassy-boot use_rust example", + serial_number: "vial:f64c2b3c:000001", + }; + + let vial_config = VialConfig::new(VIAL_KEYBOARD_ID, VIAL_KEYBOARD_DEF, &[(0, 0), (1, 1)]); + + let rmk_config = RmkConfig { + device_config: keyboard_device_config, + vial_config, + ..Default::default() + }; + + let mut keymap_data = KeymapData::new(keymap::get_default_keymap()); + let storage_config = StorageConfig { + num_sectors: 16, + start_addr: 0, + clear_storage: false, + clear_layout: false, + }; + let mut behavior_config = BehaviorConfig::default(); + let per_key_config = PositionalConfig::default(); + let (keymap, mut storage) = initialize_keymap_and_storage( + &mut keymap_data, + flash, + &storage_config, + &mut behavior_config, + &per_key_config, + ) + .await; + + rmk::dfu::mark_booted(); + + // Optional DFU lock — requires the `dfu_lock` Cargo feature. + // Specify the physical keys to press simultaneously to unlock DFU firmware + // download. The keys are (row, col) pairs matching your matrix layout. + // The lock state is checked by the DFU USB handler on each download start. + // To use, create a `DfuLock` and poll it periodically: + // + // let unlock_keys: &[(u8, u8)] = &[(0, 0), (1, 1)]; + // let mut dfu_lock = ::rmk::dfu::DfuLock::new(unlock_keys, &keymap); + // add dfu_lock to run_all!() + + let debouncer = DefaultDebouncer::new(); + let mut matrix = Matrix::<_, _, _, ROW, COL, true>::new(row_pins, col_pins, debouncer); + let mut keyboard = Keyboard::new(&keymap); + let host_ctx = rmk::host::KeyboardContext::new(&keymap); + let mut host_service = HostService::new(&host_ctx, &rmk_config); + + let mut usb_transport = UsbTransport::new(driver, rmk_config.device_config); + let mut wpm_processor = WpmProcessor::new(); + + run_all!( + matrix, + storage, + usb_transport, + wpm_processor, + keyboard, + host_service // , dfu_lock + ) + .await; +} diff --git a/examples/use_rust/nrf52840_embassy_boot/src/vial.rs b/examples/use_rust/nrf52840_embassy_boot/src/vial.rs new file mode 100644 index 000000000..33e0a4ad0 --- /dev/null +++ b/examples/use_rust/nrf52840_embassy_boot/src/vial.rs @@ -0,0 +1 @@ +include!(concat!(env!("OUT_DIR"), "/config_generated.rs")); diff --git a/examples/use_rust/nrf52840_embassy_boot/vial.json b/examples/use_rust/nrf52840_embassy_boot/vial.json new file mode 100644 index 000000000..eba77b1c5 --- /dev/null +++ b/examples/use_rust/nrf52840_embassy_boot/vial.json @@ -0,0 +1,37 @@ +{ + "name": "RMK Keyboard", + "vendorId": "0x4C4B", + "productId": "0x4643", + "lighting": "none", + "matrix": { + "rows": 4, + "cols": 3 + }, + "layouts": { + "keymap": [ + [ + "0,0", + "0,1", + "0,2" + ], + [ + "1,0", + "1,1", + "1,2" + ], + [ + "2,0", + "2,1", + "2,2" + ], + [ + { + "y": -2, + "x": 4 + }, + "3,0", + "3,2" + ] + ] + } +} \ No newline at end of file diff --git a/examples/use_rust/rp2040_embassy_boot/memory.x b/examples/use_rust/rp2040_embassy_boot/memory.x index 3e94ea4ba..ed0413401 100644 --- a/examples/use_rust/rp2040_embassy_boot/memory.x +++ b/examples/use_rust/rp2040_embassy_boot/memory.x @@ -1,8 +1,13 @@ /* This memory.x is for the RP2040 with 2MB flash. -For different flash sizes see docs. +For different flash sizes uncomment below. +Be aware you need to change FLASH_SIZE in main.rs accordingly +and flash the matching bootloader. */ MEMORY { - FLASH : ORIGIN = 0x10007000, LENGTH = 944K - RAM : ORIGIN = 0x20000000, LENGTH = 256K +FLASH : ORIGIN = 0x10007000, LENGTH = 944K +/* 4MB: FLASH : ORIGIN = 0x10007000, LENGTH = 1968K */ +/* 8MB: FLASH : ORIGIN = 0x10007000, LENGTH = 4016K */ +/* 16MB: FLASH : ORIGIN = 0x10007000, LENGTH = 8112K */ +RAM : ORIGIN = 0x20000000, LENGTH = 256K } diff --git a/examples/use_rust/rp2040_embassy_boot/src/main.rs b/examples/use_rust/rp2040_embassy_boot/src/main.rs index 43456ec5a..b10bf91a8 100644 --- a/examples/use_rust/rp2040_embassy_boot/src/main.rs +++ b/examples/use_rust/rp2040_embassy_boot/src/main.rs @@ -69,8 +69,7 @@ async fn main(_spawner: Spawner) { let dfu_size: u32 = active_size + PAGE_SIZE; // embassy-boot needs that extra page for swap info let dfu_offset: u32 = ACTIVE_OFFSET + active_size; // dfu after active let storage_offset: u32 = dfu_offset + dfu_size; // storage after active + dfu - let storage_size: u32 = STORAGE_SIZE; - assert!(storage_offset + storage_size == FLASH_SIZE); // sanity check that we fit everything in flash + assert!(storage_offset + STORAGE_SIZE == FLASH_SIZE); // sanity check that we fit everything in flash info!( "Flash layout: state @ 0x{:04X} ({}K), active @ 0x{:04X} ({}K), dfu @ 0x{:04X} ({}K), storage @ 0x{:04X} ({}K)", @@ -81,13 +80,13 @@ async fn main(_spawner: Spawner) { dfu_offset, dfu_size / 1024, storage_offset, - storage_size / 1024 + STORAGE_SIZE / 1024 ); let flash = async_flash_wrapper(rmk::dfu::init_flash( p.FLASH, storage_offset, - storage_size, + STORAGE_SIZE, STATE_OFFSET, STATE_SIZE, dfu_offset, diff --git a/rmk-config/src/default_config/nice_nano.toml b/rmk-config/src/default_config/nice_nano.toml index 617f6be84..a4dc0f3df 100644 --- a/rmk-config/src/default_config/nice_nano.toml +++ b/rmk-config/src/default_config/nice_nano.toml @@ -7,6 +7,9 @@ battery_adc_pin = "P0_04" adc_divider_measured = 2000 adc_divider_total = 2806 +[dfu] +flash_size = 1048576 + [storage] enabled = true # Storage starts from 640K diff --git a/rmk-config/src/default_config/nice_nano_v2.toml b/rmk-config/src/default_config/nice_nano_v2.toml index 500a2fbbf..b2860b209 100644 --- a/rmk-config/src/default_config/nice_nano_v2.toml +++ b/rmk-config/src/default_config/nice_nano_v2.toml @@ -5,6 +5,9 @@ usb_enable = true enabled = true battery_adc_pin = "vddh" +[dfu] +flash_size = 1048576 + [storage] enabled = true # Storage starts from 640K diff --git a/rmk-config/src/default_config/nrf52840.toml b/rmk-config/src/default_config/nrf52840.toml index bdcf41cf5..1deae99c1 100644 --- a/rmk-config/src/default_config/nrf52840.toml +++ b/rmk-config/src/default_config/nrf52840.toml @@ -11,6 +11,9 @@ start_addr = 0xA0000 # Storage uses 128K = 640K ~ 768K num_sectors = 32 +[dfu] +flash_size = 1048576 + [chip.nrf52840] # DCDC regulator 0 enabled (default: true) dcdc_reg0 = false diff --git a/rmk-config/src/lib.rs b/rmk-config/src/lib.rs index 1ee2e99bd..e81a48283 100644 --- a/rmk-config/src/lib.rs +++ b/rmk-config/src/lib.rs @@ -90,10 +90,9 @@ pub struct KeyboardTomlConfig { /// build.rs also loads event defaults via new_from_toml_path_with_event_defaults() #[serde(default)] pub(crate) event: EventConfig, - /// Whether the user explicitly set a [dfu] section in keyboard.toml. - /// Populated during two-pass parsing in new_from_toml_path(). + /// Whether the user explicitly set a [storage] section in keyboard.toml. #[serde(skip)] - pub(crate) dfu_user_set: bool, + pub(crate) storage_user_set: bool, } impl KeyboardTomlConfig { @@ -121,7 +120,9 @@ impl KeyboardTomlConfig { /// and should not require `[keyboard.board]`/`[keyboard.chip]`. pub fn new_from_toml_path_with_event_defaults>(config_toml_path: P) -> Self { let mut config = Self::parse_from_toml_path(config_toml_path, None); - config.dfu_user_set = config.dfu.is_some(); + config.storage_user_set = config.storage.as_ref().map_or(false, |s| { + s.start_addr.is_some() || s.num_sectors.is_some() + }); config.auto_calculate_parameters(); config } @@ -141,10 +142,9 @@ impl KeyboardTomlConfig { // 2. Chip-specific default config // 3. User config (highest priority) let mut config = Self::parse_from_toml_path(path, Some(default_config_str)); - - // Track whether the user explicitly set [dfu] in their keyboard.toml - // (as opposed to the value coming only from chip defaults). - config.dfu_user_set = user_config.dfu.is_some(); + config.storage_user_set = user_config.storage.as_ref().map_or(false, |s| { + s.start_addr.is_some() || s.num_sectors.is_some() + }); config.auto_calculate_parameters(); diff --git a/rmk-config/src/resolved/hardware.rs b/rmk-config/src/resolved/hardware.rs index e833ac86d..1383692e7 100644 --- a/rmk-config/src/resolved/hardware.rs +++ b/rmk-config/src/resolved/hardware.rs @@ -65,48 +65,79 @@ impl crate::KeyboardTomlConfig { } else { None }; - let dfu = self.get_dfu_config().map(|d| { - let has_manual_overrides = self.dfu_user_set - && (d.state_offset.is_some() - || d.state_size.is_some() - || d.dfu_offset.is_some() - || d.dfu_size.is_some()); + let (dfu, dfu_auto_calc) = match self.get_dfu_config() { + Some(d) => { + let vals = [d.state_offset, d.state_size, d.dfu_offset, d.dfu_size]; + let any_set = vals.iter().any(|v| v.is_some()); + let all_set = vals.iter().all(|v| v.is_some()); - if has_manual_overrides { - // User manually set [dfu] values → use directly - DfuConfig { - state_offset: d.state_offset.unwrap_or(0x6000), - state_size: d.state_size.unwrap_or(0x1000), - dfu_offset: d.dfu_offset.unwrap_or(0x87000), - dfu_size: d.dfu_size.unwrap_or(516 * 1024), - page_size: d.page_size.unwrap_or(4096), - led: d.led.clone().map(|pin| PinConfig { pin, low_active: false }), - unlock_keys: d.unlock_keys.clone().unwrap_or_default(), + if any_set && !all_set { + return Err( + "If you set one of state_offset/state_size/dfu_offset/dfu_size, you must set all four" + .to_string(), + ); } - } else { - // Auto-calculate: use ALL remaining flash for ACTIVE+DFU+storage - // layout: [28K bootloader+state][ACTIVE][DFU(ACTIVE+1page)][storage] - let flash_size = d.flash_size.unwrap_or(2 * 1024 * 1024); - let page_size = d.page_size.unwrap_or(4096); - let bootloader_state_end = 0x7000u32; // 28K - let storage_size = if storage_toml.enabled { - storage_toml.num_sectors.unwrap_or(2) as u32 * page_size + + if all_set { + ( + Some(DfuConfig { + state_offset: d.state_offset.unwrap(), + state_size: d.state_size.unwrap(), + dfu_offset: d.dfu_offset.unwrap(), + dfu_size: d.dfu_size.unwrap(), + page_size: d.page_size.unwrap_or(4096), + led: d.led.clone().map(|pin| PinConfig { pin, low_active: false }), + unlock_keys: d.unlock_keys.clone().unwrap_or_default(), + }), + false, + ) } else { - 0 - }; - let remaining = flash_size - bootloader_state_end - storage_size; - let active_size = (remaining - page_size) / 2; - DfuConfig { - state_offset: 0x6000, - state_size: 0x1000, - dfu_offset: bootloader_state_end + active_size, - dfu_size: active_size + page_size, - page_size, - led: d.led.clone().map(|pin| PinConfig { pin, low_active: false }), - unlock_keys: d.unlock_keys.clone().unwrap_or_default(), + // Auto-calculate: use ALL remaining flash for ACTIVE+DFU+storage + // layout: [28K bootloader+state][ACTIVE][DFU(ACTIVE+1page)][storage] + let flash_size = d.flash_size.unwrap_or(2 * 1024 * 1024); + let page_size = d.page_size.unwrap_or(4096); + let bootloader_state_end = 0x7000u32; // 28K + // Reserve 128 KB for storage behind DFU, DFU auto-calc always assumes this + let storage_size = 32u32 * page_size; + let remaining = flash_size - bootloader_state_end - storage_size; + let active_size = (remaining - page_size) / 2; + ( + Some(DfuConfig { + state_offset: 0x6000, + state_size: 0x1000, + dfu_offset: bootloader_state_end + active_size, + dfu_size: active_size + page_size, + page_size, + led: d.led.clone().map(|pin| PinConfig { pin, low_active: false }), + unlock_keys: d.unlock_keys.clone().unwrap_or_default(), + }), + true, + ) } } - }); + None => (None, false), + }; + if self.storage_user_set + && dfu_auto_calc + && let Some(storage_cfg) = &self.storage + { + if let Some(num_sectors) = storage_cfg.num_sectors + && num_sectors != 32 + { + eprintln!( + "warning: `[storage].num_sectors = {}` is ignored with DFU auto-calculation. The DFU layout always reserves 128 KB (32 sectors) at the end of flash. Values < 32 waste reserved space, values > 32 risk flash overflow.", + num_sectors + ); + } + if let Some(start_addr) = storage_cfg.start_addr + && start_addr != 0 + { + eprintln!( + "warning: `[storage].start_addr = {:#x}` has no effect with DFU. The storage partition is automatically placed after the DFU partition.", + start_addr + ); + } + } let light = self.get_light_config(); let display = self.get_display_config(); let output = self.get_output_config()?; diff --git a/rmk-macro/Cargo.toml b/rmk-macro/Cargo.toml index c1c424993..691594af0 100644 --- a/rmk-macro/Cargo.toml +++ b/rmk-macro/Cargo.toml @@ -23,6 +23,8 @@ strum = { version = "0.28", default-features = false, features = ["derive"] } ## Enable hardware watchdog code generation watchdog = [] dfu_rp = [] +## Enable nRF DFU firmware update code generation +dfu_nrf = [] [lib] proc-macro = true diff --git a/rmk-macro/src/codegen/chip/flash.rs b/rmk-macro/src/codegen/chip/flash.rs index cb12c2980..8fa6d9aa9 100644 --- a/rmk-macro/src/codegen/chip/flash.rs +++ b/rmk-macro/src/codegen/chip/flash.rs @@ -6,9 +6,9 @@ use quote::quote; use rmk_config::resolved::Hardware; use rmk_config::resolved::hardware::ChipSeries; -#[cfg(feature = "dfu_rp")] +#[cfg(any(feature = "dfu_rp", feature = "dfu_nrf"))] use super::gpio::convert_gpio_str_to_output_pin; -#[cfg(feature = "dfu_rp")] +#[cfg(any(feature = "dfu_rp", feature = "dfu_nrf"))] use rmk_config::resolved::hardware::DfuConfig; pub(crate) fn expand_flash_init(hardware: &Hardware) -> TokenStream2 { @@ -25,11 +25,11 @@ pub(crate) fn expand_flash_init(hardware: &Hardware) -> TokenStream2 { let clear_storage = storage.clear_storage; let clear_layout = storage.clear_layout; - // With dfu_rp, the flash is already a partition that starts at the + // With dfu, the flash is already a partition that starts at the // storage offset, so the relative offset must be 0. - #[cfg(feature = "dfu_rp")] + #[cfg(any(feature = "dfu_rp", feature = "dfu_nrf"))] let storage_start_addr = 0usize; - #[cfg(not(feature = "dfu_rp"))] + #[cfg(not(any(feature = "dfu_rp", feature = "dfu_nrf")))] let storage_start_addr = _start_addr; let mut flash_init = quote! { @@ -48,9 +48,52 @@ pub(crate) fn expand_flash_init(hardware: &Hardware) -> TokenStream2 { } } ChipSeries::Nrf52 => { - quote! { + #[cfg(feature = "dfu_nrf")] + let flash_code = { + let dfu = hardware.dfu.as_ref().expect( + "[dfu] section is required in keyboard.toml (or chip default) when dfu_nrf is enabled" + ); + let storage_num_sectors = hardware.storage.as_ref().map(|s| s.num_sectors).unwrap_or(32) as u32; + let erase_size = dfu.page_size; + let storage_offset = dfu.dfu_offset + dfu.dfu_size; + let storage_size = storage_num_sectors * erase_size; + let state_offset = dfu.state_offset; + let state_size = dfu.state_size; + let dfu_offset = dfu.dfu_offset; + let dfu_size = dfu.dfu_size; + let dfu_led = match &dfu.led { + Some(c) if c.pin == "none" => None, + Some(c) => Some(convert_gpio_str_to_output_pin(&hardware.chip, c.pin.clone(), false)), + None => Some(convert_gpio_str_to_output_pin(&hardware.chip, "P0_15".to_string(), false)), + }; + let dfu_led_init = match dfu_led { + Some(pin) => quote! { + ::rmk::dfu::set_led(Some(#pin)); + }, + None => quote! {}, + }; + let dfu_unlock_keys = expand_dfu_unlock_keys(dfu); + quote! { + #dfu_unlock_keys + let flash = ::rmk::storage::async_flash_wrapper( + ::rmk::dfu::init_flash( + p.NVMC, + #storage_offset, + #storage_size, + #state_offset, + #state_size, + #dfu_offset, + #dfu_size, + ) + ); + #dfu_led_init + } + }; + #[cfg(not(feature = "dfu_nrf"))] + let flash_code = quote! { let flash = ::nrf_mpsl::Flash::take(mpsl, p.NVMC); - } + }; + flash_code } ChipSeries::Rp2040 => { #[cfg(not(feature = "dfu_rp"))] @@ -68,7 +111,7 @@ pub(crate) fn expand_flash_init(hardware: &Hardware) -> TokenStream2 { "[dfu] section is required in keyboard.toml (or chip default) when dfu_rp is enabled" ); let storage_num_sectors = hardware.storage.as_ref().map(|s| s.num_sectors).unwrap_or(32) as u32; - let erase_size = 4096u32; + let erase_size = dfu.page_size; let storage_offset = dfu.dfu_offset + dfu.dfu_size; let storage_size = storage_num_sectors * erase_size; let state_offset = dfu.state_offset; @@ -114,7 +157,7 @@ pub(crate) fn expand_flash_init(hardware: &Hardware) -> TokenStream2 { } /// Generate the `DFU_UNLOCK_KEYS` constant from the resolved DFU config. -#[cfg(feature = "dfu_rp")] +#[cfg(any(feature = "dfu_rp", feature = "dfu_nrf"))] fn expand_dfu_unlock_keys(dfu: &DfuConfig) -> TokenStream2 { if dfu.unlock_keys.is_empty() { return quote! {}; diff --git a/rmk-macro/src/codegen/orchestrator.rs b/rmk-macro/src/codegen/orchestrator.rs index 79469ff03..fb424115a 100644 --- a/rmk-macro/src/codegen/orchestrator.rs +++ b/rmk-macro/src/codegen/orchestrator.rs @@ -433,9 +433,9 @@ pub(crate) fn expand_keymap_and_storage(hardware: &Hardware, layout: &Layout) -> }; if hardware.storage.is_some() { - #[cfg(feature = "dfu_rp")] + #[cfg(any(feature = "dfu_rp", feature = "dfu_nrf"))] let mark = quote! { ::rmk::dfu::mark_booted(); }; - #[cfg(not(feature = "dfu_rp"))] + #[cfg(not(any(feature = "dfu_rp", feature = "dfu_nrf")))] let mark = quote! {}; quote! { diff --git a/rmk/Cargo.toml b/rmk/Cargo.toml index 00c7d25ec..2b5f9c82c 100644 --- a/rmk/Cargo.toml +++ b/rmk/Cargo.toml @@ -79,6 +79,7 @@ embassy-hal-internal = { version = "0.5.0", optional = true } pio = { version = "0.3.0", optional = true } fixed = { version = "1.28.0", optional = true } embassy-boot-rp = { version = "0.10.0", optional = true } +embassy-boot = { version = "0.7", optional = true, default-features = false } # ESP32 dependencies esp-hal = { version = "1.1", optional = true } @@ -123,7 +124,7 @@ vial = ["host"] vial_lock = ["vial", "host_security"] ## Enable DFU lock feature — physical key unlock for DFU firmware download -dfu_lock = ["dfu_rp", "host_security"] +dfu_lock = ["host_security"] ## Enable physical key unlock and matrix state tracking (shared between vial_lock and rmk_protocol) host_security = [] @@ -227,7 +228,9 @@ zsa_voyager_bl = [] ## Enable DFU firmware update support (USB DFU interface) dfu = ["dep:embassy-usb-dfu", "dep:embassy-embedded-hal"] ## Enable RP2040-specific DFU with embassy-boot-rp (implies `dfu` and `rp2040`) -dfu_rp = ["dfu", "dep:embassy-boot-rp", "rp2040", "rmk-macro/dfu_rp"] +dfu_rp = ["dfu", "dep:embassy-boot-rp", "dep:embassy-boot", "rp2040", "rmk-macro/dfu_rp"] +## Enable nRF DFU firmware update support (add a chip feature like `nrf52840` too) +dfu_nrf = ["dfu", "dep:embassy-boot", "dep:embassy-nrf", "rmk-macro/dfu_nrf"] ## Enable Plover HID stenography support: adds the steno HID descriptor, ## the steno USB writer endpoint, and the `Action::Steno` variant. @@ -278,3 +281,6 @@ _ble = ["dep:trouble-host", "dep:bt-hci", "storage", "rmk-types/_ble"] [lib] # Don't run doctest for lib doctest = false +[workspace.dependencies] +embassy-nrf = { version = "0.10", features = ["nrf52840"] } + diff --git a/rmk/src/dfu.rs b/rmk/src/dfu.rs index e93a03de4..9562226c0 100644 --- a/rmk/src/dfu.rs +++ b/rmk/src/dfu.rs @@ -1,12 +1,10 @@ use core::cell::RefCell; #[cfg(feature = "dfu_lock")] -use core::sync::atomic::AtomicBool; -use core::sync::atomic::{AtomicPtr, Ordering}; +use core::sync::atomic::{AtomicBool, Ordering}; use embassy_sync::blocking_mutex::Mutex; -#[cfg(feature = "dfu_lock")] use embassy_sync::blocking_mutex::raw::CriticalSectionRawMutex; -use embassy_sync::blocking_mutex::raw::NoopRawMutex; +use embassy_sync::once_lock::OnceLock; #[cfg(feature = "dfu_lock")] use embassy_sync::signal::Signal; use embassy_usb::control::{InResponse, OutResponse, Request}; @@ -18,6 +16,8 @@ use static_cell::StaticCell; #[cfg(feature = "dfu_lock")] use crate::core_traits::Runnable; +/// Simple USB string provider for the DFU interface, to show a product name in the host's device manager during DFU mode. The FirmwareHandler of embassy_usb_dfu doesn't use the string index from the interface descriptor, so we have to provide our own handler to return the string when requested by the host. +/// This is the name string that gets shown with `dfu-util -l` option. struct DfuStringProvider { string_idx: StringIndex, string_val: &'static str, @@ -50,39 +50,43 @@ pub const FLASH_SIZE: usize = 16 * 1024 * 1024; /// downloads. Must match the USB control buffer size used by the host. pub const BLOCK_SIZE_DFU: usize = 512; +/// Flash write granularity — 1 for RP2040, 4 for nRF NVMC. #[cfg(feature = "dfu_rp")] -use embassy_embedded_hal::flash::partition::BlockingPartition; -#[cfg(feature = "dfu_rp")] -use embassy_rp::Peri; -#[cfg(feature = "dfu_rp")] -use embassy_rp::flash::{Blocking, Flash}; -#[cfg(feature = "dfu_rp")] -use embassy_rp::gpio::Output; +const DFU_WRITE_SIZE: usize = 1; +#[cfg(feature = "dfu_nrf")] +const DFU_WRITE_SIZE: usize = 4; + +#[cfg(feature = "dfu_nrf")] +use embassy_nrf::{Peri, gpio::Output, nvmc::Nvmc, peripherals::NVMC}; #[cfg(feature = "dfu_rp")] -use embassy_rp::peripherals::FLASH; -#[cfg(feature = "dfu")] -use embassy_usb::class::dfu::consts::Status; +use embassy_rp::{ + Peri, + flash::{Blocking, Flash}, + gpio::Output, + peripherals::FLASH, +}; #[cfg(feature = "dfu")] -use embassy_usb::class::dfu::dfu_mode::{self, DfuState}; +use embassy_usb::class::dfu::{ + consts::Status, + dfu_mode::{self, DfuState}, +}; +#[cfg(any(feature = "dfu_rp", feature = "dfu_nrf"))] +use { + embassy_boot::{BlockingFirmwareState, BlockingFirmwareUpdater, FirmwareUpdaterConfig}, + embassy_embedded_hal::flash::partition::BlockingPartition, +}; #[cfg(feature = "dfu_rp")] type FlashType = Flash<'static, FLASH, Blocking, FLASH_SIZE>; -#[cfg(feature = "dfu_rp")] -type MutexType = Mutex>; -#[cfg(feature = "dfu_rp")] -type PartitionType = BlockingPartition<'static, NoopRawMutex, FlashType>; +#[cfg(feature = "dfu_nrf")] +type FlashType = Nvmc<'static>; -#[cfg(feature = "dfu_rp")] -static FLASH_CELL: StaticCell = StaticCell::new(); -#[cfg(feature = "dfu_rp")] -static MANAGER_CELL: StaticCell = StaticCell::new(); -#[cfg(feature = "dfu_rp")] -static MANAGER_PTR: AtomicPtr = AtomicPtr::new(core::ptr::null_mut()); -#[cfg(feature = "dfu_rp")] -static LED_MUTEX: AtomicPtr>>>> = - AtomicPtr::new(core::ptr::null_mut()); +#[cfg(any(feature = "dfu_rp", feature = "dfu_nrf"))] +type MutexType = Mutex>; +#[cfg(any(feature = "dfu_rp", feature = "dfu_nrf"))] +type PartitionType = BlockingPartition<'static, CriticalSectionRawMutex, FlashType>; -#[cfg(feature = "dfu_rp")] +#[cfg(any(feature = "dfu_rp", feature = "dfu_nrf"))] pub struct DfuFlashManager { flash_mutex: &'static MutexType, state_offset: u32, @@ -93,7 +97,7 @@ pub struct DfuFlashManager { storage_size: u32, } -#[cfg(feature = "dfu_rp")] +#[cfg(any(feature = "dfu_rp", feature = "dfu_nrf"))] impl DfuFlashManager { fn new( flash_mutex: &'static MutexType, @@ -128,26 +132,34 @@ impl DfuFlashManager { } } +// Per-chip statics +#[cfg(any(feature = "dfu_rp", feature = "dfu_nrf"))] +static FLASH_CELL: StaticCell = StaticCell::new(); +#[cfg(any(feature = "dfu_rp", feature = "dfu_nrf"))] +static MANAGER: OnceLock = OnceLock::new(); +#[cfg(any(feature = "dfu_rp", feature = "dfu_nrf"))] +static LED: OnceLock>>>> = OnceLock::new(); + /// Store an optional DFU LED pin globally. -#[cfg(feature = "dfu_rp")] +#[cfg(any(feature = "dfu_rp", feature = "dfu_nrf"))] pub fn set_led(led: Option>) { - static LED_CELL: StaticCell>>>> = StaticCell::new(); - let m = LED_CELL.init(Mutex::new(RefCell::new(led))); - LED_MUTEX.store(m as *const _ as *mut _, Ordering::Release); + let _ = LED.init(Mutex::new(RefCell::new(led))); } -/// Run a closure with the global DFU LED, if configured. -#[cfg(feature = "dfu_rp")] +/// Run a closure with the global DFU LED, if configured (platform-specific impl). +#[cfg(any(feature = "dfu_rp", feature = "dfu_nrf"))] fn with_led(f: F) -> Option where F: FnOnce(&mut Output<'static>) -> R, { - let ptr = LED_MUTEX.load(Ordering::Acquire); - if ptr.is_null() { - return None; - } - let m = unsafe { &*ptr }; - m.lock(|cell| cell.borrow_mut().as_mut().map(f)) + LED.try_get() + .and_then(|m| m.lock(|cell| cell.borrow_mut().as_mut().map(f))) +} + +/// No-op fallback when DFU is built without an LED-capable platform driver. +#[cfg(all(feature = "dfu", not(any(feature = "dfu_rp", feature = "dfu_nrf"))))] +fn with_led(_: F) -> Option { + None } /// DFU lock state (shared between keyboard loop and DFU handler). @@ -186,36 +198,37 @@ impl dfu_mode::Handler for RmkDfuHandler { } #[cfg(feature = "dfu_lock")] DFU_STARTED.store(true, Ordering::Release); - info!("dfu_lock: DFU download started"); - #[cfg(feature = "dfu_rp")] + info!("dfu: DFU download started"); with_led(|led| led.set_high()); self.inner.start() } fn write(&mut self, data: &[u8]) -> Result<(), Status> { - #[cfg(feature = "dfu_rp")] with_led(|led| led.toggle()); self.inner.write(data) } fn finish(&mut self) -> Result<(), Status> { let res = self.inner.finish(); - #[cfg(feature = "dfu_rp")] with_led(|led| led.set_low()); res } fn system_reset(&mut self) { - #[cfg(feature = "dfu_rp")] with_led(|led| led.set_low()); self.inner.system_reset() } } -/// Initialize the blocking flash, create the DFU manager and store it globally. #[cfg(feature = "dfu_rp")] +type FlashPeri = Peri<'static, FLASH>; +#[cfg(feature = "dfu_nrf")] +type FlashPeri = Peri<'static, NVMC>; + +/// Initialize the blocking flash, create the DFU manager and store it globally. +#[cfg(any(feature = "dfu_rp", feature = "dfu_nrf"))] pub fn init_flash( - flash_peri: Peri<'static, FLASH>, + flash_peri: FlashPeri, storage_offset: u32, storage_size: u32, state_offset: u32, @@ -223,9 +236,13 @@ pub fn init_flash( dfu_offset: u32, dfu_size: u32, ) -> PartitionType { + #[cfg(feature = "dfu_nrf")] + let raw_flash = Nvmc::new(flash_peri); + #[cfg(feature = "dfu_rp")] let raw_flash = Flash::<_, Blocking, FLASH_SIZE>::new_blocking(flash_peri); + let flash_mutex: &'static MutexType = FLASH_CELL.init(Mutex::new(RefCell::new(raw_flash))); - let mgr = MANAGER_CELL.init(DfuFlashManager::new( + let mgr = DfuFlashManager::new( flash_mutex, storage_offset, storage_size, @@ -233,39 +250,37 @@ pub fn init_flash( state_size, dfu_offset, dfu_size, - )); - MANAGER_PTR.store(mgr as *const _ as *mut _, Ordering::Release); - mgr.storage_partition() + ); + let partition = mgr.storage_partition(); + MANAGER.init(mgr).ok(); + partition } /// Mark firmware boot as successful so the bootloader doesn't revert on next reset. -#[cfg(feature = "dfu_rp")] +#[cfg(any(feature = "dfu_rp", feature = "dfu_nrf"))] pub fn mark_booted() { if let Some(mgr) = get_manager() { let state_part = mgr.state_partition(); - static ALIGNED: StaticCell<[u8; 1]> = StaticCell::new(); - let aligned: &'static mut [u8] = ALIGNED.init([0; 1]); - let mut state = embassy_boot_rp::BlockingFirmwareState::new(state_part, aligned); + static ALIGNED: StaticCell<[u8; DFU_WRITE_SIZE]> = StaticCell::new(); + let aligned: &'static mut [u8] = ALIGNED.init([0; DFU_WRITE_SIZE]); + let mut state = BlockingFirmwareState::new(state_part, aligned); state.mark_booted().ok(); } } -/// Be a Karen and demand to see the manager. -/// Get a reference to the global DFU flash manager, if initialized. -#[cfg(feature = "dfu_rp")] +/// Get a reference to the global DFU flash manager. +#[cfg(any(feature = "dfu_rp", feature = "dfu_nrf"))] pub fn get_manager() -> Option<&'static DfuFlashManager> { - let ptr = MANAGER_PTR.load(Ordering::Acquire); - if ptr.is_null() { None } else { Some(unsafe { &*ptr }) } + MANAGER.try_get() } /// Register a DFU interface on the USB builder. -#[cfg(feature = "dfu_rp")] +#[cfg(any(feature = "dfu_rp", feature = "dfu_nrf"))] pub fn register_dfu_interface>( builder: &mut Builder<'static, D>, mgr: &'static DfuFlashManager, product_name: &'static str, ) { - use embassy_boot_rp::{BlockingFirmwareUpdater, FirmwareUpdaterConfig}; use embassy_usb::class::dfu::consts::DfuAttributes; use embassy_usb_dfu::ResetImmediate; use embassy_usb_dfu::dfu::FirmwareHandler; @@ -276,8 +291,8 @@ pub fn register_dfu_interface>( dfu: dfu_part, state: state_part, }; - static ALIGNED: StaticCell<[u8; 1]> = StaticCell::new(); - let aligned: &'static mut [u8] = ALIGNED.init([0; 1]); + static ALIGNED: StaticCell<[u8; DFU_WRITE_SIZE]> = StaticCell::new(); + let aligned: &'static mut [u8] = ALIGNED.init([0; DFU_WRITE_SIZE]); let updater = BlockingFirmwareUpdater::new(config, aligned); let attrs = DfuAttributes::CAN_DOWNLOAD | DfuAttributes::WILL_DETACH; @@ -295,16 +310,16 @@ pub fn register_dfu_interface>( let mut func = builder.function(0x00, 0x00, 0x00); let mut iface = func.interface(); - let mut alt = iface.alt_setting(0xFE, 0x01, 0x02, Some(string_idx)); + let mut alt = iface.alt_setting(0xFE, 0x01, 0x02, Some(string_idx)); // class-specific DFU interface with string descriptor for product name alt.descriptor( - 0x21, + 0x21, // DFU functional descriptor &[ attrs.bits(), - 0xc4, + 0xc4, // detach timeout in ms (09c4 = 2500 ms) 0x09, - (BLOCK_SIZE_DFU & 0xff) as u8, - ((BLOCK_SIZE_DFU >> 8) & 0xff) as u8, - 0x10, + (BLOCK_SIZE_DFU & 0xff) as u8, // transfer size low byte + ((BLOCK_SIZE_DFU >> 8) & 0xff) as u8, // transfer size high byte + 0x10, // DFU version 1.1 (BCD 0x0110) 0x01, ], ); @@ -392,8 +407,57 @@ impl<'a> DfuLock<'a> { with_led(|led| led.set_low()); break; } - morse_blink_dfu().await; + Self::morse_blink_dfu().await; + } + } + + /// Blink "D F U" in Morse code on the DFU LED. + async fn morse_blink_dfu() { + use embassy_time::Timer; + + /// Element timing in milliseconds + const DOT: u64 = 100; + const DASH: u64 = 300; + const PAUSE_ELEMENT: u64 = 100; + const PAUSE_LETTER: u64 = 300; + + macro_rules! dot { + () => { + with_led(|led| led.set_high()); + Timer::after_millis(DOT).await; + with_led(|led| led.set_low()); + Timer::after_millis(PAUSE_ELEMENT).await; + }; } + macro_rules! dash { + () => { + with_led(|led| led.set_high()); + Timer::after_millis(DASH).await; + with_led(|led| led.set_low()); + Timer::after_millis(PAUSE_ELEMENT).await; + }; + } + macro_rules! letter_gap { + () => { + Timer::after_millis(PAUSE_LETTER - PAUSE_ELEMENT).await; + }; + } + + // D = -.. + dash!(); + dot!(); + dot!(); + letter_gap!(); + // F = ..-. + dot!(); + dot!(); + dash!(); + dot!(); + letter_gap!(); + // U = ..- + dot!(); + dot!(); + dash!(); } } @@ -405,53 +469,3 @@ impl<'a> Runnable for DfuLock<'a> { } } } - -/// Blink "D F U" in Morse code on the DFU LED. -#[cfg(feature = "dfu_lock")] -async fn morse_blink_dfu() { - use embassy_time::Timer; - - /// Element timing in milliseconds - const DOT: u64 = 100; - const DASH: u64 = 300; - const PAUSE_ELEMENT: u64 = 100; - const PAUSE_LETTER: u64 = 300; - - macro_rules! dot { - () => { - with_led(|led| led.set_high()); - Timer::after_millis(DOT).await; - with_led(|led| led.set_low()); - Timer::after_millis(PAUSE_ELEMENT).await; - }; - } - macro_rules! dash { - () => { - with_led(|led| led.set_high()); - Timer::after_millis(DASH).await; - with_led(|led| led.set_low()); - Timer::after_millis(PAUSE_ELEMENT).await; - }; - } - macro_rules! letter_gap { - () => { - Timer::after_millis(PAUSE_LETTER - PAUSE_ELEMENT).await; - }; - } - - // D = -.. - dash!(); - dot!(); - dot!(); - letter_gap!(); - // F = ..-. - dot!(); - dot!(); - dash!(); - dot!(); - letter_gap!(); - // U = ..- - dot!(); - dot!(); - dash!(); -} diff --git a/rmk/src/storage/mod.rs b/rmk/src/storage/mod.rs index 2beb18a81..fa2e669d3 100644 --- a/rmk/src/storage/mod.rs +++ b/rmk/src/storage/mod.rs @@ -421,16 +421,17 @@ impl> UsbTransport { #[cfg(feature = "dfu")] { let product_name = device_config.product_name; - #[cfg(feature = "dfu_rp")] + #[cfg(any(feature = "dfu_rp", feature = "dfu_nrf"))] if let Some(mgr) = ::rmk::dfu::get_manager() { ::rmk::dfu::register_dfu_interface(&mut builder, mgr, product_name); } diff --git a/rmk/src/watchdog/mod.rs b/rmk/src/watchdog/mod.rs index 2ba030540..2e407fdd7 100644 --- a/rmk/src/watchdog/mod.rs +++ b/rmk/src/watchdog/mod.rs @@ -4,14 +4,16 @@ use crate::core_traits::Runnable; #[cfg(feature = "_esp_ble")] mod esp32; -#[cfg(all(feature = "_nrf_ble", not(any(feature = "nrf54l15_ble", feature = "nrf54lm20_ble"))))] +#[cfg(any(feature = "_nrf_ble", feature = "dfu_nrf"))] +#[cfg(not(any(feature = "nrf54l15_ble", feature = "nrf54lm20_ble")))] mod nrf52; #[cfg(feature = "rp2040")] mod rp2040; #[cfg(feature = "_esp_ble")] pub use esp32::Esp32Watchdog; -#[cfg(all(feature = "_nrf_ble", not(any(feature = "nrf54l15_ble", feature = "nrf54lm20_ble"))))] +#[cfg(any(feature = "_nrf_ble", feature = "dfu_nrf"))] +#[cfg(not(any(feature = "nrf54l15_ble", feature = "nrf54lm20_ble")))] pub use nrf52::Nrf52Watchdog; #[cfg(feature = "rp2040")] pub use rp2040::Rp2040Watchdog; From 934391165248dfc0e6aca18cdd7ea5f311a48d3e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pascal=20J=C3=A4ger?= Date: Mon, 22 Jun 2026 18:27:01 +0200 Subject: [PATCH 3/7] feat(dfu): add USB-DFU support for peripheral MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Pascal Jäger --- rmk-macro/src/codegen/split/peripheral.rs | 117 ++++++++++++++++++++-- rmk/src/dfu.rs | 27 +++++ 2 files changed, 138 insertions(+), 6 deletions(-) diff --git a/rmk-macro/src/codegen/split/peripheral.rs b/rmk-macro/src/codegen/split/peripheral.rs index a960c2f09..3f2c6ad99 100644 --- a/rmk-macro/src/codegen/split/peripheral.rs +++ b/rmk-macro/src/codegen/split/peripheral.rs @@ -9,6 +9,7 @@ use syn::ItemMod; use super::central::expand_serial_init; use crate::codegen::chip::chip_init::expand_chip_init; +use rmk_config::resolved::Identity; use crate::codegen::chip::flash::expand_flash_init; use crate::codegen::chip::gpio::expand_output_initialization; use crate::codegen::display::{expand_display_config, expand_display_interrupt}; @@ -43,10 +44,34 @@ pub(crate) fn parse_split_peripheral_mod( let hardware = toml_config .hardware() .expect("failed to resolve hardware config"); + let identity = toml_config + .identity() + .expect("failed to resolve identity config"); + + let dfu_enabled = is_feature_enabled(&rmk_features, "dfu_rp") + || is_feature_enabled(&rmk_features, "dfu_nrf"); + let device_config = if dfu_enabled { + let vid = identity.vendor_id; + let pid = identity.product_id; + let manufacturer = &identity.manufacturer; + let product_name = &identity.product_name; + let serial_number = &identity.serial_number; + quote! { + const KEYBOARD_DEVICE_CONFIG: ::rmk::config::DeviceConfig = ::rmk::config::DeviceConfig { + vid: #vid, + pid: #pid, + manufacturer: #manufacturer, + product_name: #product_name, + serial_number: #serial_number, + }; + } + } else { + quote! {} + }; - let main_function = expand_split_peripheral(id, &hardware, item_mod, &rmk_features); + let main_function = expand_split_peripheral(id, &identity, &hardware, item_mod, &rmk_features); - let bind_interrupts = expand_bind_interrupt_for_split_peripheral(&hardware.chip, &hardware, id); + let bind_interrupts = expand_bind_interrupt_for_split_peripheral(&hardware.chip, &hardware, id, &rmk_features); let chip = &hardware.chip; let main_function_sig = if chip.series == ChipSeries::Esp32 { @@ -69,6 +94,7 @@ pub(crate) fn parse_split_peripheral_mod( }; quote! { + #device_config #main_function_sig { // ::defmt::info!("RMK start!"); #main_function @@ -80,6 +106,7 @@ fn expand_bind_interrupt_for_split_peripheral( chip: &ChipModel, hardware: &Hardware, peripheral_id: usize, + rmk_features: &Option>, ) -> TokenStream2 { let communication = &hardware.communication; @@ -107,6 +134,16 @@ fn expand_bind_interrupt_for_split_peripheral( match chip.series { ChipSeries::Nrf52 => { + let dfu_enabled = is_feature_enabled(rmk_features, "dfu_rp") + || is_feature_enabled(rmk_features, "dfu_nrf"); + let usb_interrupt = if dfu_enabled { + quote! { + USBD => ::embassy_nrf::usb::InterruptHandler<::embassy_nrf::peripherals::USBD>; + } + } else { + quote! {} + }; + let ble_config = communication.get_ble_config().unwrap(); let tx_power = if let Some(pwr) = ble_config.default_tx_power { quote! { .default_tx_power(#pwr)? } @@ -159,11 +196,22 @@ fn expand_bind_interrupt_for_split_peripheral( quote! {} }; + let clock_power_handler = if dfu_enabled { + quote! { + CLOCK_POWER => ::nrf_sdc::mpsl::ClockInterruptHandler, ::embassy_nrf::usb::vbus_detect::InterruptHandler; + } + } else { + quote! { + CLOCK_POWER => ::nrf_sdc::mpsl::ClockInterruptHandler; + } + }; + quote! { use ::embassy_nrf::bind_interrupts; #spim_import bind_interrupts!(struct Irqs { - CLOCK_POWER => ::nrf_sdc::mpsl::ClockInterruptHandler; + #clock_power_handler + #usb_interrupt RNG => ::embassy_nrf::rng::InterruptHandler<::embassy_nrf::peripherals::RNG>; EGU0_SWI0 => ::nrf_sdc::mpsl::LowPrioInterruptHandler; RADIO => ::nrf_sdc::mpsl::HighPrioInterruptHandler; @@ -208,10 +256,18 @@ fn expand_bind_interrupt_for_split_peripheral( } } ChipSeries::Rp2040 => { + let dfu_enabled = is_feature_enabled(rmk_features, "dfu_rp") + || is_feature_enabled(rmk_features, "dfu_nrf"); if communication.ble_enabled() { + let usb_int = if dfu_enabled { + quote! { USBCTRL_IRQ => ::embassy_rp::usb::InterruptHandler<::embassy_rp::peripherals::USB>; } + } else { + quote! {} + }; quote! { use ::embassy_rp::bind_interrupts; bind_interrupts!(struct Irqs { + #usb_int PIO0_IRQ_0 => ::embassy_rp::pio::InterruptHandler<::embassy_rp::peripherals::PIO0>; DMA_IRQ_0 => ::embassy_rp::dma::InterruptHandler<::embassy_rp::peripherals::DMA_CH0>, ::embassy_rp::dma::InterruptHandler<::embassy_rp::peripherals::DMA_CH1>, ::embassy_rp::dma::InterruptHandler<::embassy_rp::peripherals::DMA_CH2>; #iqs5xx_interrupt @@ -222,10 +278,16 @@ fn expand_bind_interrupt_for_split_peripheral( runner.run().await } } - } else if !display_interrupt.is_empty() || !iqs5xx_interrupt.is_empty() { + } else if !display_interrupt.is_empty() || !iqs5xx_interrupt.is_empty() || dfu_enabled { + let usb_int = if dfu_enabled { + quote! { USBCTRL_IRQ => ::embassy_rp::usb::InterruptHandler<::embassy_rp::peripherals::USB>; } + } else { + quote! {} + }; quote! { use ::embassy_rp::bind_interrupts; bind_interrupts!(struct Irqs { + #usb_int #iqs5xx_interrupt #display_interrupt }); @@ -240,6 +302,7 @@ fn expand_bind_interrupt_for_split_peripheral( fn expand_split_peripheral( id: usize, + _identity: &Identity, hardware: &Hardware, item_mod: ItemMod, rmk_features: &Option>, @@ -259,15 +322,49 @@ fn expand_split_peripheral( let imports = expand_custom_imports(&item_mod); let mut chip_init = expand_chip_init(hardware, Some(id), &item_mod); + if split_config.connection == "ble" { - // Add storage when using BLE split let flash_init = expand_flash_init(hardware); chip_init.extend(quote! { #flash_init let mut storage = ::rmk::storage::new_storage_for_split_peripheral(flash, storage_config).await; }); + } else if is_feature_enabled(rmk_features, "dfu_rp") + || is_feature_enabled(rmk_features, "dfu_nrf") + { + let flash_init = expand_flash_init(hardware); + chip_init.extend(quote! { #flash_init }); + } + + let dfu_enabled = is_feature_enabled(rmk_features, "dfu_rp") + || is_feature_enabled(rmk_features, "dfu_nrf"); + + // Mark booted when DFU is enabled so the bootloader doesn't + // revert the previous update. + if dfu_enabled { + chip_init.extend(quote! { ::rmk::dfu::mark_booted(); }); } + // Initialize USB driver for DFU on the peripheral side + // so it can be firmware-updated via USB. + let dfu_task_future = if dfu_enabled { + let usb_init = match hardware.chip.series { + ChipSeries::Nrf52 => quote! { + let driver = ::embassy_nrf::usb::Driver::new(p.USBD, Irqs, ::embassy_nrf::usb::vbus_detect::HardwareVbusDetect::new(Irqs)); + }, + ChipSeries::Rp2040 => quote! { + let driver = ::embassy_rp::usb::Driver::new(p.USB, Irqs); + }, + _ => quote! {}, + }; + chip_init.extend(usb_init); + Some(quote! { + async { ::rmk::dfu::run_peripheral_dfu(driver, KEYBOARD_DEVICE_CONFIG).await } + }) + } else { + None + }; + // Debouncer config let col = peripheral_config.cols; let row = peripheral_config.rows; @@ -395,6 +492,7 @@ fn expand_split_peripheral( processors, registered_processors, watchdog_task, + dfu_task_future, ); quote! { @@ -422,6 +520,7 @@ fn expand_split_peripheral_entry( processors: Vec, registered_processors: Vec, watchdog_task: Option, + dfu_task_future: Option, ) -> TokenStream2 { // Add matrix to devices, and run all devices let mut devs = devices.clone(); @@ -453,7 +552,7 @@ fn expand_split_peripheral_entry( &stack, ) }; - // Build task list: device, processor (if any), peripheral, registered_processors + // Build task list: device, processor (if any), peripheral, registered_processors, dfu let mut tasks = vec![device_task]; if !processors.is_empty() { tasks.push(processor_task); @@ -463,6 +562,9 @@ fn expand_split_peripheral_entry( if let Some(t) = &watchdog_task { tasks.push(t.clone()); } + if let Some(t) = &dfu_task_future { + tasks.push(t.clone()); + } let run_rmk_peripheral = join_all_tasks(tasks); quote! { #run_rmk_peripheral @@ -496,6 +598,9 @@ fn expand_split_peripheral_entry( if let Some(t) = &watchdog_task { tasks.push(t.clone()); } + if let Some(t) = &dfu_task_future { + tasks.push(t.clone()); + } let run_rmk_peripheral = join_all_tasks(tasks); quote! { #serial_init diff --git a/rmk/src/dfu.rs b/rmk/src/dfu.rs index 9562226c0..b4592d820 100644 --- a/rmk/src/dfu.rs +++ b/rmk/src/dfu.rs @@ -274,6 +274,33 @@ pub fn get_manager() -> Option<&'static DfuFlashManager> { MANAGER.try_get() } +/// Run a USB DFU-only device on the peripheral side of a split keyboard. +/// +/// Creates a USB device with only a DFU interface (no HID/keyboard) so the +/// peripheral can be firmware-updated via USB while the normal split +/// communication (BLE or serial) continues running. +#[cfg(any(feature = "dfu_rp", feature = "dfu_nrf"))] +pub async fn run_peripheral_dfu>( + driver: D, + device_config: crate::config::DeviceConfig<'static>, +) -> ! { + use crate::usb::new_usb_builder; + + let mut builder = new_usb_builder(driver, device_config); + + let product_name = device_config.product_name; + if let Some(mgr) = get_manager() { + register_dfu_interface(&mut builder, mgr, product_name); + } + + let mut device = builder.build(); + + loop { + device.run_until_suspend().await; + device.wait_resume().await; + } +} + /// Register a DFU interface on the USB builder. #[cfg(any(feature = "dfu_rp", feature = "dfu_nrf"))] pub fn register_dfu_interface>( From 90cce016e88fe0e412d22b991a7723481d1d0293 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pascal=20J=C3=A4ger?= Date: Fri, 19 Jun 2026 12:28:37 +0200 Subject: [PATCH 4/7] add --help for format_all.sh script MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Pascal Jäger --- scripts/format_all.sh | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/scripts/format_all.sh b/scripts/format_all.sh index bbc444264..95e29ffce 100644 --- a/scripts/format_all.sh +++ b/scripts/format_all.sh @@ -2,6 +2,22 @@ set -e +usage() { + echo "Usage: $0 [OPTION]" + echo "Format all Rust source files in the repository." + echo "" + echo "Options:" + echo " --help Show this help message and exit" + echo " --touched Format only .rs files changed in the working tree" + echo " --touched-branch Format only .rs files changed since branching off main" + echo " --touched-since REF Format only .rs files changed since REF" +} + +if [ "$1" = "--help" ]; then + usage + exit 0 +fi + format_changed() { if [ -z "$1" ]; then exit 0 From ce9820369fbddbf280b75f613cf9d1ca6a24caca Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pascal=20J=C3=A4ger?= Date: Wed, 1 Jul 2026 12:42:11 +0200 Subject: [PATCH 5/7] feat(dfu): refactor to modules MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Pascal Jäger --- rmk/src/{dfu.rs => dfu/mod.rs} | 274 ++++++++++++--------------------- rmk/src/dfu/nrf.rs | 74 +++++++++ rmk/src/dfu/rp.rs | 81 ++++++++++ 3 files changed, 253 insertions(+), 176 deletions(-) rename rmk/src/{dfu.rs => dfu/mod.rs} (65%) create mode 100644 rmk/src/dfu/nrf.rs create mode 100644 rmk/src/dfu/rp.rs diff --git a/rmk/src/dfu.rs b/rmk/src/dfu/mod.rs similarity index 65% rename from rmk/src/dfu.rs rename to rmk/src/dfu/mod.rs index b4592d820..f066f02fa 100644 --- a/rmk/src/dfu.rs +++ b/rmk/src/dfu/mod.rs @@ -4,7 +4,6 @@ use core::sync::atomic::{AtomicBool, Ordering}; use embassy_sync::blocking_mutex::Mutex; use embassy_sync::blocking_mutex::raw::CriticalSectionRawMutex; -use embassy_sync::once_lock::OnceLock; #[cfg(feature = "dfu_lock")] use embassy_sync::signal::Signal; use embassy_usb::control::{InResponse, OutResponse, Request}; @@ -16,65 +15,41 @@ use static_cell::StaticCell; #[cfg(feature = "dfu_lock")] use crate::core_traits::Runnable; -/// Simple USB string provider for the DFU interface, to show a product name in the host's device manager during DFU mode. The FirmwareHandler of embassy_usb_dfu doesn't use the string index from the interface descriptor, so we have to provide our own handler to return the string when requested by the host. -/// This is the name string that gets shown with `dfu-util -l` option. -struct DfuStringProvider { - string_idx: StringIndex, - string_val: &'static str, -} - -impl Handler for DfuStringProvider { - fn control_out(&mut self, _req: Request, _data: &[u8]) -> Option { - None - } - fn control_in<'a>(&'a mut self, _req: Request, _buf: &'a mut [u8]) -> Option> { - None - } - fn get_string(&mut self, index: StringIndex, _lang_id: u16) -> Option<&'static str> { - (index == self.string_idx).then_some(self.string_val) - } -} +// --------------------------------------------------------------------------- +// Chip modules +// --------------------------------------------------------------------------- -/// Total flash size passed to the embassy-rp Flash const generic. -/// -/// Set to 16 MB (the maximum common RP2040 flash size) so that the same -/// binary works on boards with 2, 4, 8 or 16 MB flash. `new_blocking()` -/// ignores this value at runtime — it is only used for software bounds -/// checking inside embassy-rp. Because all flash access goes through -/// `BlockingPartition` (which has its own partition-sized bounds checks), -/// overshooting the const generic is safe. #[cfg(feature = "dfu_rp")] -pub const FLASH_SIZE: usize = 16 * 1024 * 1024; - -/// DFU transfer block size in bytes. Larger values speed up firmware -/// downloads. Must match the USB control buffer size used by the host. -pub const BLOCK_SIZE_DFU: usize = 512; +mod rp; +#[cfg(feature = "dfu_nrf")] +mod nrf; -/// Flash write granularity — 1 for RP2040, 4 for nRF NVMC. #[cfg(feature = "dfu_rp")] -const DFU_WRITE_SIZE: usize = 1; +pub use self::rp::{init_flash, set_led, with_led, mark_booted, get_manager, DFU_WRITE_SIZE}; #[cfg(feature = "dfu_nrf")] -const DFU_WRITE_SIZE: usize = 4; +pub use self::nrf::{init_flash, set_led, with_led, mark_booted, get_manager, DFU_WRITE_SIZE}; + +// --------------------------------------------------------------------------- +// Chip-specific type aliases +// --------------------------------------------------------------------------- -#[cfg(feature = "dfu_nrf")] -use embassy_nrf::{Peri, gpio::Output, nvmc::Nvmc, peripherals::NVMC}; #[cfg(feature = "dfu_rp")] use embassy_rp::{ - Peri, flash::{Blocking, Flash}, - gpio::Output, peripherals::FLASH, }; -#[cfg(feature = "dfu")] -use embassy_usb::class::dfu::{ - consts::Status, - dfu_mode::{self, DfuState}, -}; +#[cfg(feature = "dfu_nrf")] +use embassy_nrf::nvmc::Nvmc; + #[cfg(any(feature = "dfu_rp", feature = "dfu_nrf"))] -use { - embassy_boot::{BlockingFirmwareState, BlockingFirmwareUpdater, FirmwareUpdaterConfig}, - embassy_embedded_hal::flash::partition::BlockingPartition, -}; +use embassy_embedded_hal::flash::partition::BlockingPartition; + +/// DFU transfer block size in bytes. Larger values speed up firmware +/// downloads. Must match the USB control buffer size used by the host. +pub const BLOCK_SIZE_DFU: usize = 512; + +#[cfg(feature = "dfu_rp")] +pub const FLASH_SIZE: usize = 16 * 1024 * 1024; #[cfg(feature = "dfu_rp")] type FlashType = Flash<'static, FLASH, Blocking, FLASH_SIZE>; @@ -84,7 +59,11 @@ type FlashType = Nvmc<'static>; #[cfg(any(feature = "dfu_rp", feature = "dfu_nrf"))] type MutexType = Mutex>; #[cfg(any(feature = "dfu_rp", feature = "dfu_nrf"))] -type PartitionType = BlockingPartition<'static, CriticalSectionRawMutex, FlashType>; +pub(super) type PartitionType = BlockingPartition<'static, CriticalSectionRawMutex, FlashType>; + +// --------------------------------------------------------------------------- +// DfuFlashManager — shared by RP2040 and nRF +// --------------------------------------------------------------------------- #[cfg(any(feature = "dfu_rp", feature = "dfu_nrf"))] pub struct DfuFlashManager { @@ -99,7 +78,7 @@ pub struct DfuFlashManager { #[cfg(any(feature = "dfu_rp", feature = "dfu_nrf"))] impl DfuFlashManager { - fn new( + pub(super) fn new( flash_mutex: &'static MutexType, storage_offset: u32, storage_size: u32, @@ -132,46 +111,45 @@ impl DfuFlashManager { } } -// Per-chip statics -#[cfg(any(feature = "dfu_rp", feature = "dfu_nrf"))] -static FLASH_CELL: StaticCell = StaticCell::new(); -#[cfg(any(feature = "dfu_rp", feature = "dfu_nrf"))] -static MANAGER: OnceLock = OnceLock::new(); -#[cfg(any(feature = "dfu_rp", feature = "dfu_nrf"))] -static LED: OnceLock>>>> = OnceLock::new(); +// --------------------------------------------------------------------------- +// DfuStringProvider +// --------------------------------------------------------------------------- -/// Store an optional DFU LED pin globally. -#[cfg(any(feature = "dfu_rp", feature = "dfu_nrf"))] -pub fn set_led(led: Option>) { - let _ = LED.init(Mutex::new(RefCell::new(led))); +struct DfuStringProvider { + string_idx: StringIndex, + string_val: &'static str, } -/// Run a closure with the global DFU LED, if configured (platform-specific impl). -#[cfg(any(feature = "dfu_rp", feature = "dfu_nrf"))] -fn with_led(f: F) -> Option -where - F: FnOnce(&mut Output<'static>) -> R, -{ - LED.try_get() - .and_then(|m| m.lock(|cell| cell.borrow_mut().as_mut().map(f))) +impl Handler for DfuStringProvider { + fn control_out(&mut self, _req: Request, _data: &[u8]) -> Option { + None + } + fn control_in<'a>(&'a mut self, _req: Request, _buf: &'a mut [u8]) -> Option> { + None + } + fn get_string(&mut self, index: StringIndex, _lang_id: u16) -> Option<&'static str> { + (index == self.string_idx).then_some(self.string_val) + } } +// --------------------------------------------------------------------------- +// with_led — platform LED helper or no-op +// --------------------------------------------------------------------------- + /// No-op fallback when DFU is built without an LED-capable platform driver. #[cfg(all(feature = "dfu", not(any(feature = "dfu_rp", feature = "dfu_nrf"))))] fn with_led(_: F) -> Option { None } -/// DFU lock state (shared between keyboard loop and DFU handler). +// --------------------------------------------------------------------------- +// DFU lock state +// --------------------------------------------------------------------------- + #[cfg(feature = "dfu_lock")] static DFU_LOCKED: AtomicBool = AtomicBool::new(true); - -/// Set to true once `RmkDfuHandler::start()` begins a DFU download. #[cfg(feature = "dfu_lock")] static DFU_STARTED: AtomicBool = AtomicBool::new(false); - -/// Signaled by `RmkDfuHandler::start()` when a blocked DFU download is rejected. -/// Triggers the unlock key polling window in `process_unlock`. #[cfg(feature = "dfu_lock")] static DFU_UNLOCK_SIGNAL: Signal = Signal::new(); @@ -180,6 +158,13 @@ pub fn is_dfu_unlocked() -> bool { !DFU_LOCKED.load(Ordering::Acquire) } +// --------------------------------------------------------------------------- +// RmkDfuHandler +// --------------------------------------------------------------------------- + +#[cfg(feature = "dfu")] +use embassy_usb::class::dfu::{consts::Status, dfu_mode::{self, DfuState}}; + /// DFU handler wrapper that blinks an LED during transfer and checks the /// DFU lock (if `dfu_lock` feature is enabled). #[cfg(feature = "dfu")] @@ -220,86 +205,12 @@ impl dfu_mode::Handler for RmkDfuHandler { } } -#[cfg(feature = "dfu_rp")] -type FlashPeri = Peri<'static, FLASH>; -#[cfg(feature = "dfu_nrf")] -type FlashPeri = Peri<'static, NVMC>; - -/// Initialize the blocking flash, create the DFU manager and store it globally. -#[cfg(any(feature = "dfu_rp", feature = "dfu_nrf"))] -pub fn init_flash( - flash_peri: FlashPeri, - storage_offset: u32, - storage_size: u32, - state_offset: u32, - state_size: u32, - dfu_offset: u32, - dfu_size: u32, -) -> PartitionType { - #[cfg(feature = "dfu_nrf")] - let raw_flash = Nvmc::new(flash_peri); - #[cfg(feature = "dfu_rp")] - let raw_flash = Flash::<_, Blocking, FLASH_SIZE>::new_blocking(flash_peri); - - let flash_mutex: &'static MutexType = FLASH_CELL.init(Mutex::new(RefCell::new(raw_flash))); - let mgr = DfuFlashManager::new( - flash_mutex, - storage_offset, - storage_size, - state_offset, - state_size, - dfu_offset, - dfu_size, - ); - let partition = mgr.storage_partition(); - MANAGER.init(mgr).ok(); - partition -} - -/// Mark firmware boot as successful so the bootloader doesn't revert on next reset. -#[cfg(any(feature = "dfu_rp", feature = "dfu_nrf"))] -pub fn mark_booted() { - if let Some(mgr) = get_manager() { - let state_part = mgr.state_partition(); - static ALIGNED: StaticCell<[u8; DFU_WRITE_SIZE]> = StaticCell::new(); - let aligned: &'static mut [u8] = ALIGNED.init([0; DFU_WRITE_SIZE]); - let mut state = BlockingFirmwareState::new(state_part, aligned); - state.mark_booted().ok(); - } -} - -/// Get a reference to the global DFU flash manager. -#[cfg(any(feature = "dfu_rp", feature = "dfu_nrf"))] -pub fn get_manager() -> Option<&'static DfuFlashManager> { - MANAGER.try_get() -} +// --------------------------------------------------------------------------- +// register_dfu_interface +// --------------------------------------------------------------------------- -/// Run a USB DFU-only device on the peripheral side of a split keyboard. -/// -/// Creates a USB device with only a DFU interface (no HID/keyboard) so the -/// peripheral can be firmware-updated via USB while the normal split -/// communication (BLE or serial) continues running. #[cfg(any(feature = "dfu_rp", feature = "dfu_nrf"))] -pub async fn run_peripheral_dfu>( - driver: D, - device_config: crate::config::DeviceConfig<'static>, -) -> ! { - use crate::usb::new_usb_builder; - - let mut builder = new_usb_builder(driver, device_config); - - let product_name = device_config.product_name; - if let Some(mgr) = get_manager() { - register_dfu_interface(&mut builder, mgr, product_name); - } - - let mut device = builder.build(); - - loop { - device.run_until_suspend().await; - device.wait_resume().await; - } -} +use {embassy_boot::{BlockingFirmwareUpdater, FirmwareUpdaterConfig}, embassy_usb_dfu::{ResetImmediate, dfu::FirmwareHandler}}; /// Register a DFU interface on the USB builder. #[cfg(any(feature = "dfu_rp", feature = "dfu_nrf"))] @@ -309,8 +220,6 @@ pub fn register_dfu_interface>( product_name: &'static str, ) { use embassy_usb::class::dfu::consts::DfuAttributes; - use embassy_usb_dfu::ResetImmediate; - use embassy_usb_dfu::dfu::FirmwareHandler; let dfu_part = mgr.dfu_partition(); let state_part = mgr.state_partition(); @@ -337,16 +246,16 @@ pub fn register_dfu_interface>( let mut func = builder.function(0x00, 0x00, 0x00); let mut iface = func.interface(); - let mut alt = iface.alt_setting(0xFE, 0x01, 0x02, Some(string_idx)); // class-specific DFU interface with string descriptor for product name + let mut alt = iface.alt_setting(0xFE, 0x01, 0x02, Some(string_idx)); alt.descriptor( - 0x21, // DFU functional descriptor + 0x21, &[ attrs.bits(), - 0xc4, // detach timeout in ms (09c4 = 2500 ms) + 0xc4, 0x09, - (BLOCK_SIZE_DFU & 0xff) as u8, // transfer size low byte - ((BLOCK_SIZE_DFU >> 8) & 0xff) as u8, // transfer size high byte - 0x10, // DFU version 1.1 (BCD 0x0110) + (BLOCK_SIZE_DFU & 0xff) as u8, + ((BLOCK_SIZE_DFU >> 8) & 0xff) as u8, + 0x10, 0x01, ], ); @@ -362,7 +271,34 @@ pub fn register_dfu_interface>( } // --------------------------------------------------------------------------- -// dfu_lock — physical key unlock for DFU firmware download +// run_peripheral_dfu +// --------------------------------------------------------------------------- + +/// Run a USB DFU-only device on the peripheral side of a split keyboard. +#[cfg(any(feature = "dfu_rp", feature = "dfu_nrf"))] +pub async fn run_peripheral_dfu>( + driver: D, + device_config: crate::config::DeviceConfig<'static>, +) -> ! { + use crate::usb::new_usb_builder; + + let mut builder = new_usb_builder(driver, device_config); + + let product_name = device_config.product_name; + if let Some(mgr) = get_manager() { + register_dfu_interface(&mut builder, mgr, product_name); + } + + let mut device = builder.build(); + + loop { + device.run_until_suspend().await; + device.wait_resume().await; + } +} + +// --------------------------------------------------------------------------- +// dfu_lock // --------------------------------------------------------------------------- /// DfuLock state machine that checks a physical key combination to unlock DFU. @@ -383,16 +319,9 @@ impl<'a> DfuLock<'a> { } } - /// One unlock cycle: block (yielded) on `DFU_UNLOCK_SIGNAL.wait()` until a - /// DFU download is rejected, then open a 10 s unlock window polling the - /// configured unlock keys at 50 ms. If the keys are pressed within that - /// window the lock is released and the LED blinks Morse "D F U". pub(crate) async fn process_unlock(&self) { - // Phase 1: wait (yielded) until a DFU unlock request arrives DFU_UNLOCK_SIGNAL.wait().await; - // Phase 2: start the 10 s unlock window, wait for keypress or timeout. - // LED solid on to signal "press unlock keys now". info!("dfu_lock: DFU activity detected, unlock window open for 10 s"); info!("dfu_lock: waiting for unlock keys"); with_led(|led| led.set_high()); @@ -417,8 +346,6 @@ impl<'a> DfuLock<'a> { embassy_time::Timer::after_millis(50).await; } - // Phase 3: unlocked — wait until DFU download starts or 10 s pass. - // LED blinks Morse "D F U" to signal "ready to flash". info!("dfu_lock: unlocked, signalling with Morse DFU"); let deadline = embassy_time::Instant::now() + embassy_time::Duration::from_secs(10); loop { @@ -438,11 +365,9 @@ impl<'a> DfuLock<'a> { } } - /// Blink "D F U" in Morse code on the DFU LED. async fn morse_blink_dfu() { use embassy_time::Timer; - /// Element timing in milliseconds const DOT: u64 = 100; const DASH: u64 = 300; const PAUSE_ELEMENT: u64 = 100; @@ -470,18 +395,15 @@ impl<'a> DfuLock<'a> { }; } - // D = -.. dash!(); dot!(); dot!(); letter_gap!(); - // F = ..-. dot!(); dot!(); dash!(); dot!(); letter_gap!(); - // U = ..- dot!(); dot!(); dash!(); diff --git a/rmk/src/dfu/nrf.rs b/rmk/src/dfu/nrf.rs new file mode 100644 index 000000000..3ee62a2b8 --- /dev/null +++ b/rmk/src/dfu/nrf.rs @@ -0,0 +1,74 @@ +use core::cell::RefCell; + +use embassy_boot::BlockingFirmwareState; +use embassy_nrf::{gpio::Output, nvmc::Nvmc, peripherals::NVMC}; +use embassy_nrf::Peri; +use embassy_sync::blocking_mutex::{Mutex, raw::CriticalSectionRawMutex}; +use embassy_sync::once_lock::OnceLock; +use static_cell::StaticCell; + +use super::{DfuFlashManager, MutexType, PartitionType}; + +/// Flash write granularity — 4 for nRF NVMC. +pub const DFU_WRITE_SIZE: usize = 4; + +static FLASH_CELL: StaticCell = StaticCell::new(); +static MANAGER: OnceLock = OnceLock::new(); +static LED: OnceLock>>>> = OnceLock::new(); + +/// Initialize the blocking flash, create the DFU manager and store it globally. +pub fn init_flash( + flash_peri: Peri<'static, NVMC>, + storage_offset: u32, + storage_size: u32, + state_offset: u32, + state_size: u32, + dfu_offset: u32, + dfu_size: u32, +) -> PartitionType { + let raw_flash = Nvmc::new(flash_peri); + + let flash_mutex: &'static MutexType = FLASH_CELL.init(Mutex::new(RefCell::new(raw_flash))); + let mgr = DfuFlashManager::new( + flash_mutex, + storage_offset, + storage_size, + state_offset, + state_size, + dfu_offset, + dfu_size, + ); + let partition = mgr.storage_partition(); + MANAGER.init(mgr).ok(); + partition +} + +/// Mark firmware boot as successful so the bootloader doesn't revert on next reset. +pub fn mark_booted() { + if let Some(mgr) = get_manager() { + let state_part = mgr.state_partition(); + static ALIGNED: StaticCell<[u8; DFU_WRITE_SIZE]> = StaticCell::new(); + let aligned: &'static mut [u8] = ALIGNED.init([0; DFU_WRITE_SIZE]); + let mut state = BlockingFirmwareState::new(state_part, aligned); + state.mark_booted().ok(); + } +} + +/// Get a reference to the global DFU flash manager. +pub fn get_manager() -> Option<&'static DfuFlashManager> { + MANAGER.try_get() +} + +/// Store an optional DFU LED pin globally. +pub fn set_led(led: Option>) { + let _ = LED.init(Mutex::new(RefCell::new(led))); +} + +/// Run a closure with the global DFU LED, if configured. +pub fn with_led(f: F) -> Option +where + F: FnOnce(&mut Output<'static>) -> R, +{ + LED.try_get() + .and_then(|m| m.lock(|cell| cell.borrow_mut().as_mut().map(f))) +} diff --git a/rmk/src/dfu/rp.rs b/rmk/src/dfu/rp.rs new file mode 100644 index 000000000..e58cbf4bc --- /dev/null +++ b/rmk/src/dfu/rp.rs @@ -0,0 +1,81 @@ +use core::cell::RefCell; + +use embassy_boot::BlockingFirmwareState; +use embassy_rp::{ + flash::{Blocking, Flash}, + gpio::Output, + peripherals::FLASH, +}; +use embassy_rp::Peri; +use embassy_sync::blocking_mutex::{Mutex, raw::CriticalSectionRawMutex}; +use embassy_sync::once_lock::OnceLock; +use static_cell::StaticCell; + +use super::{DfuFlashManager, MutexType, PartitionType}; + +/// Total flash size passed to the embassy-rp Flash const generic. +pub const FLASH_SIZE: usize = 16 * 1024 * 1024; + +/// Flash write granularity — 1 for RP2040. +pub const DFU_WRITE_SIZE: usize = 1; + +static FLASH_CELL: StaticCell = StaticCell::new(); +static MANAGER: OnceLock = OnceLock::new(); +static LED: OnceLock>>>> = OnceLock::new(); + +/// Initialize the blocking flash, create the DFU manager and store it globally. +pub fn init_flash( + flash_peri: Peri<'static, FLASH>, + storage_offset: u32, + storage_size: u32, + state_offset: u32, + state_size: u32, + dfu_offset: u32, + dfu_size: u32, +) -> PartitionType { + let raw_flash = Flash::<_, Blocking, FLASH_SIZE>::new_blocking(flash_peri); + + let flash_mutex: &'static MutexType = FLASH_CELL.init(Mutex::new(RefCell::new(raw_flash))); + let mgr = DfuFlashManager::new( + flash_mutex, + storage_offset, + storage_size, + state_offset, + state_size, + dfu_offset, + dfu_size, + ); + let partition = mgr.storage_partition(); + MANAGER.init(mgr).ok(); + partition +} + +/// Mark firmware boot as successful so the bootloader doesn't revert on next reset. +pub fn mark_booted() { + if let Some(mgr) = get_manager() { + let state_part = mgr.state_partition(); + static ALIGNED: StaticCell<[u8; DFU_WRITE_SIZE]> = StaticCell::new(); + let aligned: &'static mut [u8] = ALIGNED.init([0; DFU_WRITE_SIZE]); + let mut state = BlockingFirmwareState::new(state_part, aligned); + state.mark_booted().ok(); + } +} + +/// Get a reference to the global DFU flash manager. +pub fn get_manager() -> Option<&'static DfuFlashManager> { + MANAGER.try_get() +} + +/// Store an optional DFU LED pin globally. +pub fn set_led(led: Option>) { + let _ = LED.init(Mutex::new(RefCell::new(led))); +} + +/// Run a closure with the global DFU LED, if configured. +pub fn with_led(f: F) -> Option +where + F: FnOnce(&mut Output<'static>) -> R, +{ + LED.try_get() + .and_then(|m| m.lock(|cell| cell.borrow_mut().as_mut().map(f))) +} From 3340db3cfc55133778842f2ec34b7f821685b97b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pascal=20J=C3=A4ger?= Date: Wed, 1 Jul 2026 14:23:29 +0200 Subject: [PATCH 6/7] feat(dfu): refactor dfu led to processor MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Pascal Jäger --- .../main/docs/configuration/bootloader.mdx | 28 +++-- docs/docs/main/docs/development/roadmap.md | 5 +- .../rp2040_embassy_boot/keyboard.toml | 2 +- .../nrf52840_embassy_boot/src/main.rs | 8 +- .../use_rust/rp2040_embassy_boot/src/main.rs | 8 +- .../src/default_config/event_default.toml | 6 + rmk-config/src/lib.rs | 2 + rmk-config/src/resolved/build_constants.rs | 1 + rmk-macro/src/codegen/chip/flash.rs | 26 ---- rmk-macro/src/codegen/registered_processor.rs | 33 ++++++ rmk-types/Cargo.toml | 2 + rmk-types/src/dfu.rs | 27 +++++ rmk-types/src/lib.rs | 2 + rmk/Cargo.toml | 2 +- rmk/src/dfu/mod.rs | 111 ++++-------------- rmk/src/dfu/nrf.rs | 24 ++-- rmk/src/dfu/rp.rs | 35 +++--- rmk/src/event/dfu.rs | 22 ++++ rmk/src/event/mod.rs | 4 + rmk/src/processor/builtin/dfu_led.rs | 53 +++++++++ rmk/src/processor/builtin/mod.rs | 2 + 21 files changed, 235 insertions(+), 168 deletions(-) create mode 100644 rmk-types/src/dfu.rs create mode 100644 rmk/src/event/dfu.rs create mode 100644 rmk/src/processor/builtin/dfu_led.rs diff --git a/docs/docs/main/docs/configuration/bootloader.mdx b/docs/docs/main/docs/configuration/bootloader.mdx index 06cbd2248..f4aea566f 100644 --- a/docs/docs/main/docs/configuration/bootloader.mdx +++ b/docs/docs/main/docs/configuration/bootloader.mdx @@ -1,8 +1,10 @@ # Bootloader Configuration (embassy-boot) -RMK supports DFU firmware updates via [embassy-boot](https://github.com/embassy-rs/embassy/tree/main/embassy-boot) for **RP2040** and **nRF52840**. The bootloader splits flash into ACTIVE and DFU slots, providing safe updates with automatic rollback on failure. +[embassy-boot](https://github.com/embassy-rs/embassy/tree/main/embassy-boot) is a libary of the embassy framework that is used to build bootloaders. +RMK supports DFU firmware updates via embassy-boot for **RP2040** and **nRF52840**. An embassy-boot based bootloader splits flash into ACTIVE and DFU slots, providing safe updates with automatic rollback on failure. +This is an optional feature of RMK, the default bootloaders of the devices can still be used as usual without runtime updates via USB DFU. -A pre-built bootloader called **bootymcbootface** is available for both platforms. The partition formula is identical: +A pre-built embassy-boot based bootloader called **bootymcbootface** is available for both platforms. The partition formula is identical: ```text bootloader+state = 28K (fixed) @@ -12,7 +14,7 @@ ACTIVE = (remaining - 4K) / 2 DFU = ACTIVE + 4K ``` -See the [flashing guide](../user_guide/flash_firmware/use_embassy_boot.mdx) for step-by-step instructions. +See the [flashing guide](../user_guide/flash_firmware/use_embassy_boot.mdx) for step-by-step instructions on how to get the bootloader and RMK flashed. ## RP2040 @@ -27,6 +29,8 @@ import { Tab, Tabs, Rust, Toml } from '@theme' [dfu] # (Optional) Total flash size in bytes. Used to auto-calculate partition addresses. # Defaults to 2 MB (2097152) when omitted. +# ⚠ You can define your own FLASH_SIZE and offset addresses, but then you must build and +# flash a custom embassy-boot bootloader with a matching memory.x! flash_size = 2097152 # (Optional) Flash page size in bytes (4096 for RP2040). @@ -100,7 +104,8 @@ let flash = async_flash_wrapper(rmk::dfu::init_flash( )); // Optional: assign a DFU activity LED -rmk::dfu::set_led(Some(Output::new(p.PIN_25, Level::Low))); +let mut dfu_led_processor = + rmk::processor::builtin::dfu_led::DfuLedProcessor::new(Output::new(p.PIN_25, Level::Low), false); // Mark boot as successful (so bootloader doesn't revert on reset) rmk::dfu::mark_booted(); @@ -111,7 +116,8 @@ let mut dfu_lock = ::rmk::dfu::DfuLock::new(unlock_keys, &keymap); // Then add dfu_lock in run_all!() // ... run_all!( - // other processors ... + // other processors ... + dfu_led_processor, dfu_lock, ) ``` @@ -130,6 +136,8 @@ Add a `[dfu]` section to your `keyboard.toml` or use the Rust API directly. [dfu] # (Optional) Total flash size in bytes. Used to auto-calculate partition addresses. # 1 MB flash — auto-calculates ACTIVE (432K) and DFU (436K) +# ⚠ You can define your own FLASH_SIZE and offset addresses, but then you must build and +# flash a custom embassy-boot bootloader with a matching memory.x! flash_size = 1048576 # (Optional) Flash page size in bytes (4096 for RP2040). @@ -200,10 +208,11 @@ let flash = async_flash_wrapper(rmk::dfu::init_flash( dfu_size, )); -rmk::dfu::set_led(Some(Output::new(p.P0_15, Level::Low, OutputDrive::Standard))); - // Optional: assign a DFU activity LED -rmk::dfu::set_led(Some(Output::new(p.P0_15, Level::Low, OutputDrive::Standard))); +let mut dfu_led_processor = rmk::processor::builtin::dfu_led::DfuLedProcessor::new( + Output::new(p.P0_15, Level::Low, OutputDrive::Standard), + false, +); // Mark boot as successful (so bootloader doesn't revert on reset) rmk::dfu::mark_booted(); @@ -215,7 +224,8 @@ let mut dfu_lock = ::rmk::dfu::DfuLock::new(unlock_keys, &keymap); // Then add dfu_lock in run_all!() // ... run_all!( - // other processors ... + // other processors ... + dfu_led_processor dfu_lock, ) ``` diff --git a/docs/docs/main/docs/development/roadmap.md b/docs/docs/main/docs/development/roadmap.md index f85ae63df..d2b032e9f 100644 --- a/docs/docs/main/docs/development/roadmap.md +++ b/docs/docs/main/docs/development/roadmap.md @@ -63,6 +63,9 @@ There are a bunch of things to do with RMK in the near future. I plan to ship 1. - [ ] Making vial and default keymap consistent automatically - [ ] 🔴🔵 GUI keymap configurator which supports windows/macos/linux/web - [ ] Default bootloader -- [ ] USB DFU/OTA +- [x] USB DFU +- [ ] Flashing peripherals from the central via uart +- [ ] Flashing peripherals from the central via ble +- [ ] OTA updates If you want to contribute, please feel free to open an issue or PR, or just ping me! Any forms of contribution are welcome :D diff --git a/examples/use_config/rp2040_embassy_boot/keyboard.toml b/examples/use_config/rp2040_embassy_boot/keyboard.toml index cf3a09087..5fa8de76c 100644 --- a/examples/use_config/rp2040_embassy_boot/keyboard.toml +++ b/examples/use_config/rp2040_embassy_boot/keyboard.toml @@ -50,7 +50,7 @@ keymap = [ # dfu_size = 528384 [dfu] -led = "PIN_16" +led = "PIN_25" # Optional DFU lock — physical keys to press simultaneously to unlock DFU firmware download. # Requires the `dfu_lock` Cargo feature (not enabled by default). unlock_keys = [[0, 0], [1, 1]] diff --git a/examples/use_rust/nrf52840_embassy_boot/src/main.rs b/examples/use_rust/nrf52840_embassy_boot/src/main.rs index ec7d48cb2..8bd62de90 100644 --- a/examples/use_rust/nrf52840_embassy_boot/src/main.rs +++ b/examples/use_rust/nrf52840_embassy_boot/src/main.rs @@ -97,7 +97,10 @@ async fn main(_spawner: Spawner) { dfu_size, )); - rmk::dfu::set_led(Some(Output::new(p.P0_15, Level::Low, OutputDrive::Standard))); + let mut dfu_led_processor = rmk::processor::builtin::dfu_led::DfuLedProcessor::new( + Output::new(p.P0_15, Level::Low, OutputDrive::Standard), + false, + ); let keyboard_device_config = DeviceConfig { vid: 0x4c4b, @@ -160,7 +163,8 @@ async fn main(_spawner: Spawner) { usb_transport, wpm_processor, keyboard, - host_service // , dfu_lock + host_service, + dfu_led_processor, // , dfu_lock ) .await; } diff --git a/examples/use_rust/rp2040_embassy_boot/src/main.rs b/examples/use_rust/rp2040_embassy_boot/src/main.rs index b10bf91a8..c610a6bbb 100644 --- a/examples/use_rust/rp2040_embassy_boot/src/main.rs +++ b/examples/use_rust/rp2040_embassy_boot/src/main.rs @@ -93,7 +93,10 @@ async fn main(_spawner: Spawner) { dfu_size, )); - rmk::dfu::set_led(Some(Output::new(p.PIN_25, Level::Low))); + let mut dfu_led_processor = rmk::processor::builtin::dfu_led::DfuLedProcessor::new( + Output::new(p.PIN_25, Level::Low), + false, + ); let keyboard_device_config = DeviceConfig { vid: 0x4c4b, @@ -159,7 +162,8 @@ async fn main(_spawner: Spawner) { wpm_processor, keyboard, host_service, - watchdog_runner // , dfu_lock + watchdog_runner, + dfu_led_processor, // , dfu_lock ) .await; } diff --git a/rmk-config/src/default_config/event_default.toml b/rmk-config/src/default_config/event_default.toml index a404f8e4e..e6d054cfb 100644 --- a/rmk-config/src/default_config/event_default.toml +++ b/rmk-config/src/default_config/event_default.toml @@ -86,3 +86,9 @@ subs = 0 channel_size = 16 pubs = 1 subs = 0 + +# DFU events +[event.dfu_status] +channel_size = 2 +pubs = 1 +subs = 1 diff --git a/rmk-config/src/lib.rs b/rmk-config/src/lib.rs index e81a48283..acd9023fb 100644 --- a/rmk-config/src/lib.rs +++ b/rmk-config/src/lib.rs @@ -405,6 +405,8 @@ define_event_config!( central_connected, peripheral_battery, clear_peer, + // DFU events + dfu_status, // Action events action, ); diff --git a/rmk-config/src/resolved/build_constants.rs b/rmk-config/src/resolved/build_constants.rs index 74a99d050..e1cd0d271 100644 --- a/rmk-config/src/resolved/build_constants.rs +++ b/rmk-config/src/resolved/build_constants.rs @@ -110,6 +110,7 @@ impl crate::KeyboardTomlConfig { central_connected, peripheral_battery, clear_peer, + dfu_status, action, ); diff --git a/rmk-macro/src/codegen/chip/flash.rs b/rmk-macro/src/codegen/chip/flash.rs index 8fa6d9aa9..08a46f281 100644 --- a/rmk-macro/src/codegen/chip/flash.rs +++ b/rmk-macro/src/codegen/chip/flash.rs @@ -6,8 +6,6 @@ use quote::quote; use rmk_config::resolved::Hardware; use rmk_config::resolved::hardware::ChipSeries; -#[cfg(any(feature = "dfu_rp", feature = "dfu_nrf"))] -use super::gpio::convert_gpio_str_to_output_pin; #[cfg(any(feature = "dfu_rp", feature = "dfu_nrf"))] use rmk_config::resolved::hardware::DfuConfig; @@ -61,17 +59,6 @@ pub(crate) fn expand_flash_init(hardware: &Hardware) -> TokenStream2 { let state_size = dfu.state_size; let dfu_offset = dfu.dfu_offset; let dfu_size = dfu.dfu_size; - let dfu_led = match &dfu.led { - Some(c) if c.pin == "none" => None, - Some(c) => Some(convert_gpio_str_to_output_pin(&hardware.chip, c.pin.clone(), false)), - None => Some(convert_gpio_str_to_output_pin(&hardware.chip, "P0_15".to_string(), false)), - }; - let dfu_led_init = match dfu_led { - Some(pin) => quote! { - ::rmk::dfu::set_led(Some(#pin)); - }, - None => quote! {}, - }; let dfu_unlock_keys = expand_dfu_unlock_keys(dfu); quote! { #dfu_unlock_keys @@ -86,7 +73,6 @@ pub(crate) fn expand_flash_init(hardware: &Hardware) -> TokenStream2 { #dfu_size, ) ); - #dfu_led_init } }; #[cfg(not(feature = "dfu_nrf"))] @@ -118,17 +104,6 @@ pub(crate) fn expand_flash_init(hardware: &Hardware) -> TokenStream2 { let state_size = dfu.state_size; let dfu_offset = dfu.dfu_offset; let dfu_size = dfu.dfu_size; - let dfu_led = match &dfu.led { - Some(c) if c.pin == "none" => None, - Some(c) => Some(convert_gpio_str_to_output_pin(&hardware.chip, c.pin.clone(), false)), - None => Some(convert_gpio_str_to_output_pin(&hardware.chip, "PIN_25".to_string(), false)), - }; - let dfu_led_init = match dfu_led { - Some(pin) => quote! { - ::rmk::dfu::set_led(Some(#pin)); - }, - None => quote! {}, - }; let dfu_unlock_keys = expand_dfu_unlock_keys(dfu); quote! { #dfu_unlock_keys @@ -143,7 +118,6 @@ pub(crate) fn expand_flash_init(hardware: &Hardware) -> TokenStream2 { #dfu_size, ) ); - #dfu_led_init } } } diff --git a/rmk-macro/src/codegen/registered_processor.rs b/rmk-macro/src/codegen/registered_processor.rs index 72c96ae96..803232f3d 100644 --- a/rmk-macro/src/codegen/registered_processor.rs +++ b/rmk-macro/src/codegen/registered_processor.rs @@ -19,6 +19,10 @@ pub(crate) fn expand_registered_processor_init( initializers.extend(i); executors.extend(e); + if hardware.dfu.is_some() { + create_dfu_led_processor(hardware, &mut initializers, &mut executors); + } + // Custom processors declared in the module. if let Some((_, items)) = &item_mod.content { for item in items { @@ -129,6 +133,35 @@ fn create_keyboard_indicator_processor( } } +fn create_dfu_led_processor( + hardware: &Hardware, + initializers: &mut TokenStream, + executors: &mut Vec, +) { + use rmk_config::resolved::hardware::ChipSeries; + let chip = &hardware.chip; + if let Some(dfu) = &hardware.dfu { + let pin_str = match &dfu.led { + Some(c) if c.pin == "none" => return, + Some(c) => c.pin.clone(), + None => match chip.series { + ChipSeries::Nrf52 => "P0_15".to_string(), + ChipSeries::Rp2040 => "PIN_25".to_string(), + _ => return, + }, + }; + let p = convert_gpio_str_to_output_pin(chip, pin_str, false); + let processor_init = quote! { + let mut dfu_led_processor = ::rmk::processor::builtin::dfu_led::DfuLedProcessor::new( + #p, + false, + ); + }; + initializers.extend(processor_init); + executors.push(quote! { dfu_led_processor.run() }); + } +} + fn expand_custom_processor(fn_item: &syn::ItemFn) -> (TokenStream, &syn::Ident) { let task_name = &fn_item.sig.ident; diff --git a/rmk-types/Cargo.toml b/rmk-types/Cargo.toml index 948039d41..0bdc00362 100644 --- a/rmk-types/Cargo.toml +++ b/rmk-types/Cargo.toml @@ -48,5 +48,7 @@ _ble = [] split = [] display = [] passkey_entry = [] +# DFU firmware update support +dfu = [] # Stenography (Plover HID) support: `StenoKey` + `Action::Steno` variant. steno = [] diff --git a/rmk-types/src/dfu.rs b/rmk-types/src/dfu.rs new file mode 100644 index 000000000..6e53f66cd --- /dev/null +++ b/rmk-types/src/dfu.rs @@ -0,0 +1,27 @@ +//! DFU status types. + +use postcard::experimental::max_size::MaxSize; +#[cfg(feature = "rmk_protocol")] +use postcard_schema::Schema; +use serde::{Deserialize, Serialize}; + +/// DFU status. +#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize, MaxSize)] +#[cfg_attr(feature = "rmk_protocol", derive(Schema))] +#[cfg_attr(feature = "defmt", derive(defmt::Format))] +pub enum DfuStatus { + /// DFU idle / no download active + Idle, + /// DFU download started + Started, + /// Data block received and written + Downloading, + /// DFU download finished successfully + Finished, + /// A DFU error occurred + Error, + /// Unlock window open, waiting for unlock keys + LockWaiting, + /// Unlock successful, waiting for DFU download to start + LockUnlocked, +} diff --git a/rmk-types/src/lib.rs b/rmk-types/src/lib.rs index 69735bf7e..cc0769e9b 100644 --- a/rmk-types/src/lib.rs +++ b/rmk-types/src/lib.rs @@ -35,6 +35,8 @@ pub mod battery; pub mod ble; pub mod combo; pub mod connection; +#[cfg(feature = "dfu")] +pub mod dfu; pub mod constants; pub mod fmt; pub mod fork; diff --git a/rmk/Cargo.toml b/rmk/Cargo.toml index 2b5f9c82c..cef83ff7b 100644 --- a/rmk/Cargo.toml +++ b/rmk/Cargo.toml @@ -226,7 +226,7 @@ adafruit_bl = ["_nrf_ble"] zsa_voyager_bl = [] ## Enable DFU firmware update support (USB DFU interface) -dfu = ["dep:embassy-usb-dfu", "dep:embassy-embedded-hal"] +dfu = ["dep:embassy-usb-dfu", "dep:embassy-embedded-hal", "rmk-types/dfu"] ## Enable RP2040-specific DFU with embassy-boot-rp (implies `dfu` and `rp2040`) dfu_rp = ["dfu", "dep:embassy-boot-rp", "dep:embassy-boot", "rp2040", "rmk-macro/dfu_rp"] ## Enable nRF DFU firmware update support (add a chip feature like `nrf52840` too) diff --git a/rmk/src/dfu/mod.rs b/rmk/src/dfu/mod.rs index f066f02fa..a45da4ba3 100644 --- a/rmk/src/dfu/mod.rs +++ b/rmk/src/dfu/mod.rs @@ -1,8 +1,7 @@ -use core::cell::RefCell; #[cfg(feature = "dfu_lock")] use core::sync::atomic::{AtomicBool, Ordering}; -use embassy_sync::blocking_mutex::Mutex; +#[cfg(feature = "dfu_lock")] use embassy_sync::blocking_mutex::raw::CriticalSectionRawMutex; #[cfg(feature = "dfu_lock")] use embassy_sync::signal::Signal; @@ -25,41 +24,25 @@ mod rp; mod nrf; #[cfg(feature = "dfu_rp")] -pub use self::rp::{init_flash, set_led, with_led, mark_booted, get_manager, DFU_WRITE_SIZE}; +pub use self::rp::{init_flash, mark_booted, get_manager, DFU_WRITE_SIZE}; #[cfg(feature = "dfu_nrf")] -pub use self::nrf::{init_flash, set_led, with_led, mark_booted, get_manager, DFU_WRITE_SIZE}; +pub use self::nrf::{init_flash, mark_booted, get_manager, DFU_WRITE_SIZE}; // --------------------------------------------------------------------------- // Chip-specific type aliases // --------------------------------------------------------------------------- -#[cfg(feature = "dfu_rp")] -use embassy_rp::{ - flash::{Blocking, Flash}, - peripherals::FLASH, -}; -#[cfg(feature = "dfu_nrf")] -use embassy_nrf::nvmc::Nvmc; - -#[cfg(any(feature = "dfu_rp", feature = "dfu_nrf"))] -use embassy_embedded_hal::flash::partition::BlockingPartition; - /// DFU transfer block size in bytes. Larger values speed up firmware /// downloads. Must match the USB control buffer size used by the host. pub const BLOCK_SIZE_DFU: usize = 512; -#[cfg(feature = "dfu_rp")] -pub const FLASH_SIZE: usize = 16 * 1024 * 1024; +#[cfg(any(feature = "dfu_rp", feature = "dfu_nrf"))] +use embassy_embedded_hal::flash::partition::BlockingPartition; #[cfg(feature = "dfu_rp")] -type FlashType = Flash<'static, FLASH, Blocking, FLASH_SIZE>; +use self::rp::{MutexType, PartitionType}; #[cfg(feature = "dfu_nrf")] -type FlashType = Nvmc<'static>; - -#[cfg(any(feature = "dfu_rp", feature = "dfu_nrf"))] -type MutexType = Mutex>; -#[cfg(any(feature = "dfu_rp", feature = "dfu_nrf"))] -pub(super) type PartitionType = BlockingPartition<'static, CriticalSectionRawMutex, FlashType>; +use self::nrf::{MutexType, PartitionType}; // --------------------------------------------------------------------------- // DfuFlashManager — shared by RP2040 and nRF @@ -132,16 +115,6 @@ impl Handler for DfuStringProvider { } } -// --------------------------------------------------------------------------- -// with_led — platform LED helper or no-op -// --------------------------------------------------------------------------- - -/// No-op fallback when DFU is built without an LED-capable platform driver. -#[cfg(all(feature = "dfu", not(any(feature = "dfu_rp", feature = "dfu_nrf"))))] -fn with_led(_: F) -> Option { - None -} - // --------------------------------------------------------------------------- // DFU lock state // --------------------------------------------------------------------------- @@ -167,6 +140,11 @@ use embassy_usb::class::dfu::{consts::Status, dfu_mode::{self, DfuState}}; /// DFU handler wrapper that blinks an LED during transfer and checks the /// DFU lock (if `dfu_lock` feature is enabled). +#[cfg(any(feature = "dfu", feature = "dfu_lock"))] +use crate::event::publish_event; +#[cfg(any(feature = "dfu", feature = "dfu_lock"))] +use rmk_types::dfu::DfuStatus; + #[cfg(feature = "dfu")] struct RmkDfuHandler { inner: H, @@ -184,23 +162,24 @@ impl dfu_mode::Handler for RmkDfuHandler { #[cfg(feature = "dfu_lock")] DFU_STARTED.store(true, Ordering::Release); info!("dfu: DFU download started"); - with_led(|led| led.set_high()); + publish_event(crate::event::DfuStatusEvent::new(DfuStatus::Started)); self.inner.start() } fn write(&mut self, data: &[u8]) -> Result<(), Status> { - with_led(|led| led.toggle()); + publish_event(crate::event::DfuStatusEvent::new(DfuStatus::Downloading)); self.inner.write(data) } fn finish(&mut self) -> Result<(), Status> { let res = self.inner.finish(); - with_led(|led| led.set_low()); + publish_event(crate::event::DfuStatusEvent::new( + if res.is_ok() { DfuStatus::Finished } else { DfuStatus::Error }, + )); res } fn system_reset(&mut self) { - with_led(|led| led.set_low()); self.inner.system_reset() } } @@ -324,7 +303,7 @@ impl<'a> DfuLock<'a> { info!("dfu_lock: DFU activity detected, unlock window open for 10 s"); info!("dfu_lock: waiting for unlock keys"); - with_led(|led| led.set_high()); + publish_event(crate::event::DfuStatusEvent::new(DfuStatus::LockWaiting)); let deadline = embassy_time::Instant::now() + embassy_time::Duration::from_secs(10); loop { let all_pressed = self @@ -335,79 +314,35 @@ impl<'a> DfuLock<'a> { self.unlocked.store(true, Ordering::Release); DFU_LOCKED.store(false, Ordering::Release); info!("dfu_lock: unlock keys pressed, DFU unlocked for 10 s"); + publish_event(crate::event::DfuStatusEvent::new(DfuStatus::LockUnlocked)); break; } if embassy_time::Instant::now() >= deadline { info!("dfu_lock: unlock window expired (10 s timeout)"); DFU_LOCKED.store(true, Ordering::Release); - with_led(|led| led.set_low()); + publish_event(crate::event::DfuStatusEvent::new(DfuStatus::Idle)); return; } embassy_time::Timer::after_millis(50).await; } - info!("dfu_lock: unlocked, signalling with Morse DFU"); + info!("dfu_lock: unlocked, waiting for DFU download"); let deadline = embassy_time::Instant::now() + embassy_time::Duration::from_secs(10); loop { if DFU_STARTED.load(Ordering::Acquire) { info!("dfu_lock: DFU download started, staying unlocked"); - with_led(|led| led.set_high()); break; } if embassy_time::Instant::now() >= deadline { info!("dfu_lock: unlock expired (10 s timeout)"); DFU_LOCKED.store(true, Ordering::Release); self.unlocked.store(false, Ordering::Release); - with_led(|led| led.set_low()); + publish_event(crate::event::DfuStatusEvent::new(DfuStatus::Idle)); break; } - Self::morse_blink_dfu().await; + embassy_time::Timer::after_millis(200).await; } } - - async fn morse_blink_dfu() { - use embassy_time::Timer; - - const DOT: u64 = 100; - const DASH: u64 = 300; - const PAUSE_ELEMENT: u64 = 100; - const PAUSE_LETTER: u64 = 300; - - macro_rules! dot { - () => { - with_led(|led| led.set_high()); - Timer::after_millis(DOT).await; - with_led(|led| led.set_low()); - Timer::after_millis(PAUSE_ELEMENT).await; - }; - } - macro_rules! dash { - () => { - with_led(|led| led.set_high()); - Timer::after_millis(DASH).await; - with_led(|led| led.set_low()); - Timer::after_millis(PAUSE_ELEMENT).await; - }; - } - macro_rules! letter_gap { - () => { - Timer::after_millis(PAUSE_LETTER - PAUSE_ELEMENT).await; - }; - } - - dash!(); - dot!(); - dot!(); - letter_gap!(); - dot!(); - dot!(); - dash!(); - dot!(); - letter_gap!(); - dot!(); - dot!(); - dash!(); - } } #[cfg(feature = "dfu_lock")] diff --git a/rmk/src/dfu/nrf.rs b/rmk/src/dfu/nrf.rs index 3ee62a2b8..7bad725cd 100644 --- a/rmk/src/dfu/nrf.rs +++ b/rmk/src/dfu/nrf.rs @@ -1,20 +1,24 @@ use core::cell::RefCell; use embassy_boot::BlockingFirmwareState; -use embassy_nrf::{gpio::Output, nvmc::Nvmc, peripherals::NVMC}; +use embassy_embedded_hal::flash::partition::BlockingPartition; +use embassy_nrf::{nvmc::Nvmc, peripherals::NVMC}; use embassy_nrf::Peri; use embassy_sync::blocking_mutex::{Mutex, raw::CriticalSectionRawMutex}; use embassy_sync::once_lock::OnceLock; use static_cell::StaticCell; -use super::{DfuFlashManager, MutexType, PartitionType}; +use super::DfuFlashManager; /// Flash write granularity — 4 for nRF NVMC. pub const DFU_WRITE_SIZE: usize = 4; +pub(super) type FlashType = Nvmc<'static>; +pub(super) type MutexType = Mutex>; +pub(super) type PartitionType = BlockingPartition<'static, CriticalSectionRawMutex, FlashType>; + static FLASH_CELL: StaticCell = StaticCell::new(); static MANAGER: OnceLock = OnceLock::new(); -static LED: OnceLock>>>> = OnceLock::new(); /// Initialize the blocking flash, create the DFU manager and store it globally. pub fn init_flash( @@ -58,17 +62,3 @@ pub fn mark_booted() { pub fn get_manager() -> Option<&'static DfuFlashManager> { MANAGER.try_get() } - -/// Store an optional DFU LED pin globally. -pub fn set_led(led: Option>) { - let _ = LED.init(Mutex::new(RefCell::new(led))); -} - -/// Run a closure with the global DFU LED, if configured. -pub fn with_led(f: F) -> Option -where - F: FnOnce(&mut Output<'static>) -> R, -{ - LED.try_get() - .and_then(|m| m.lock(|cell| cell.borrow_mut().as_mut().map(f))) -} diff --git a/rmk/src/dfu/rp.rs b/rmk/src/dfu/rp.rs index e58cbf4bc..b555fb76d 100644 --- a/rmk/src/dfu/rp.rs +++ b/rmk/src/dfu/rp.rs @@ -1,27 +1,34 @@ use core::cell::RefCell; use embassy_boot::BlockingFirmwareState; -use embassy_rp::{ - flash::{Blocking, Flash}, - gpio::Output, - peripherals::FLASH, -}; +use embassy_embedded_hal::flash::partition::BlockingPartition; +use embassy_rp::{flash::{Blocking, Flash}, peripherals::FLASH}; use embassy_rp::Peri; use embassy_sync::blocking_mutex::{Mutex, raw::CriticalSectionRawMutex}; use embassy_sync::once_lock::OnceLock; use static_cell::StaticCell; -use super::{DfuFlashManager, MutexType, PartitionType}; +use super::DfuFlashManager; /// Total flash size passed to the embassy-rp Flash const generic. +/// +/// Set to 16 MB (the maximum common RP2040 flash size) so that the same +/// binary works on boards with 2, 4, 8 or 16 MB flash. `new_blocking()` +/// ignores this value at runtime — it is only used for software bounds +/// checking inside embassy-rp. Because all flash access goes through +/// `BlockingPartition` (which has its own partition-sized bounds checks), +/// overshooting the const generic is safe. pub const FLASH_SIZE: usize = 16 * 1024 * 1024; /// Flash write granularity — 1 for RP2040. pub const DFU_WRITE_SIZE: usize = 1; +pub(super) type FlashType = Flash<'static, FLASH, Blocking, FLASH_SIZE>; +pub(super) type MutexType = Mutex>; +pub(super) type PartitionType = BlockingPartition<'static, CriticalSectionRawMutex, FlashType>; + static FLASH_CELL: StaticCell = StaticCell::new(); static MANAGER: OnceLock = OnceLock::new(); -static LED: OnceLock>>>> = OnceLock::new(); /// Initialize the blocking flash, create the DFU manager and store it globally. pub fn init_flash( @@ -65,17 +72,3 @@ pub fn mark_booted() { pub fn get_manager() -> Option<&'static DfuFlashManager> { MANAGER.try_get() } - -/// Store an optional DFU LED pin globally. -pub fn set_led(led: Option>) { - let _ = LED.init(Mutex::new(RefCell::new(led))); -} - -/// Run a closure with the global DFU LED, if configured. -pub fn with_led(f: F) -> Option -where - F: FnOnce(&mut Output<'static>) -> R, -{ - LED.try_get() - .and_then(|m| m.lock(|cell| cell.borrow_mut().as_mut().map(f))) -} diff --git a/rmk/src/event/dfu.rs b/rmk/src/event/dfu.rs new file mode 100644 index 000000000..f117cc8f1 --- /dev/null +++ b/rmk/src/event/dfu.rs @@ -0,0 +1,22 @@ +//! DFU events + +use rmk_macro::event; +use rmk_types::dfu::DfuStatus; + +/// DFU status changed event +#[event( + channel_size = crate::DFU_STATUS_EVENT_CHANNEL_SIZE, + pubs = crate::DFU_STATUS_EVENT_PUB_SIZE, + subs = crate::DFU_STATUS_EVENT_SUB_SIZE +)] +#[derive(Clone, Copy, Debug, PartialEq, Eq)] +#[cfg_attr(feature = "defmt", derive(defmt::Format))] +pub struct DfuStatusEvent(pub DfuStatus); + +impl DfuStatusEvent { + pub fn new(status: DfuStatus) -> Self { + Self(status) + } +} + +impl_payload_wrapper!(DfuStatusEvent, DfuStatus); diff --git a/rmk/src/event/mod.rs b/rmk/src/event/mod.rs index d2d6cc2ad..1fc8aa528 100644 --- a/rmk/src/event/mod.rs +++ b/rmk/src/event/mod.rs @@ -47,6 +47,8 @@ macro_rules! impl_payload_wrapper { mod action; mod battery; mod connection; +#[cfg(feature = "dfu")] +mod dfu; mod input; #[cfg(feature = "split")] mod split; @@ -54,6 +56,8 @@ mod state; pub use action::ActionEvent; pub use battery::{BatteryAdcEvent, BatteryStatusEvent, ChargingStateEvent}; +#[cfg(feature = "dfu")] +pub use dfu::DfuStatusEvent; pub use connection::{ConnectionStatus, ConnectionStatusChangeEvent, ConnectionType}; pub use input::{ Axis, AxisEvent, AxisValType, KeyPos, KeyboardEvent, KeyboardEventPos, ModifierEvent, PointingEvent, diff --git a/rmk/src/processor/builtin/dfu_led.rs b/rmk/src/processor/builtin/dfu_led.rs new file mode 100644 index 000000000..f3e02b232 --- /dev/null +++ b/rmk/src/processor/builtin/dfu_led.rs @@ -0,0 +1,53 @@ +//! DFU LED processor for RMK +use embedded_hal::digital::StatefulOutputPin; +use rmk_macro::processor; +use rmk_types::dfu::DfuStatus; + +use crate::driver::gpio::OutputController; +use crate::event::DfuStatusEvent; + +#[processor(subscribe = [DfuStatusEvent], poll_interval = 200)] +pub struct DfuLedProcessor { + pin: OutputController

, + blink: bool, +} + +impl DfuLedProcessor

{ + pub fn new(pin: P, low_active: bool) -> Self { + Self { + pin: OutputController::new(pin, low_active), + blink: false, + } + } + + async fn on_dfu_status_event(&mut self, event: DfuStatusEvent) { + match *event { + DfuStatus::Idle | DfuStatus::Finished => { + self.blink = false; + self.pin.deactivate(); + } + DfuStatus::Started => { + self.blink = false; + self.pin.activate(); + } + DfuStatus::Downloading => self.pin.toggle(), + DfuStatus::Error => { + self.blink = false; + self.pin.activate(); + } + DfuStatus::LockWaiting => { + self.blink = false; + self.pin.activate(); + } + DfuStatus::LockUnlocked => { + self.blink = true; + } + } + } + + async fn poll(&mut self) { + if self.blink { + self.pin.toggle(); + } + } +} diff --git a/rmk/src/processor/builtin/mod.rs b/rmk/src/processor/builtin/mod.rs index ddd0d359c..00cf096ef 100644 --- a/rmk/src/processor/builtin/mod.rs +++ b/rmk/src/processor/builtin/mod.rs @@ -4,5 +4,7 @@ #[cfg(feature = "_ble")] pub mod battery_led; +#[cfg(feature = "dfu")] +pub mod dfu_led; pub mod led_indicator; pub mod wpm; From 5d58bcac7a008230fdafaf19efacb50b3787b5a2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pascal=20J=C3=A4ger?= Date: Wed, 1 Jul 2026 15:32:06 +0200 Subject: [PATCH 7/7] feat(dfu): add use_rust example for USB DFU with split MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit update example cargo.locks Signed-off-by: Pascal Jäger --- .../nrf52840_embassy_boot/Cargo.lock | 164 +- .../nrf52840_embassy_boot/Cargo.toml | 8 +- .../use_config/rp2040_embassy_boot/Cargo.lock | 100 +- .../use_rust/nrf52840_embassy_boot/Cargo.lock | 143 +- .../use_rust/nrf52840_embassy_boot/Cargo.toml | 4 +- .../use_rust/rp2040_embassy_boot/Cargo.lock | 100 +- .../use_rust/rp2040_embassy_boot/src/main.rs | 6 +- .../.cargo/config.toml | 11 + .../rp2040_embassy_boot_split/Cargo.lock | 3045 +++++++++++++++++ .../rp2040_embassy_boot_split/Cargo.toml | 64 + .../rp2040_embassy_boot_split/build.rs | 48 + .../rp2040_embassy_boot_split/memory.x | 4 + .../rp2040_embassy_boot_split/src/central.rs | 150 + .../rp2040_embassy_boot_split/src/keymap.rs | 23 + .../rp2040_embassy_boot_split/src/macros.rs | 12 + .../src/peripheral.rs | 104 + .../rp2040_embassy_boot_split/src/vial.rs | 1 + .../rp2040_embassy_boot_split/vial.json | 18 + rmk-config/src/lib.rs | 14 +- rmk-macro/src/codegen/orchestrator.rs | 2 +- rmk-macro/src/codegen/registered_processor.rs | 4 +- rmk-macro/src/codegen/split/peripheral.rs | 15 +- rmk-types/src/lib.rs | 2 +- rmk/src/dfu/mod.rs | 36 +- rmk/src/dfu/nrf.rs | 6 +- rmk/src/dfu/rp.rs | 6 +- rmk/src/event/mod.rs | 2 +- 27 files changed, 3802 insertions(+), 290 deletions(-) create mode 100644 examples/use_rust/rp2040_embassy_boot_split/.cargo/config.toml create mode 100644 examples/use_rust/rp2040_embassy_boot_split/Cargo.lock create mode 100644 examples/use_rust/rp2040_embassy_boot_split/Cargo.toml create mode 100644 examples/use_rust/rp2040_embassy_boot_split/build.rs create mode 100644 examples/use_rust/rp2040_embassy_boot_split/memory.x create mode 100644 examples/use_rust/rp2040_embassy_boot_split/src/central.rs create mode 100644 examples/use_rust/rp2040_embassy_boot_split/src/keymap.rs create mode 100644 examples/use_rust/rp2040_embassy_boot_split/src/macros.rs create mode 100644 examples/use_rust/rp2040_embassy_boot_split/src/peripheral.rs create mode 100644 examples/use_rust/rp2040_embassy_boot_split/src/vial.rs create mode 100644 examples/use_rust/rp2040_embassy_boot_split/vial.json diff --git a/examples/use_config/nrf52840_embassy_boot/Cargo.lock b/examples/use_config/nrf52840_embassy_boot/Cargo.lock index ffb448dc5..399ed008e 100644 --- a/examples/use_config/nrf52840_embassy_boot/Cargo.lock +++ b/examples/use_config/nrf52840_embassy_boot/Cargo.lock @@ -159,6 +159,21 @@ name = "bt-hci" version = "0.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "211713d2e9fb4793ce4360a712c0764264aff6be48932ccf02ca2a331c0436a9" +dependencies = [ + "btuuid", + "defmt 1.1.0", + "embassy-sync", + "embedded-io 0.7.1", + "embedded-io-async 0.7.0", + "futures-intrusive", + "heapless 0.9.3", +] + +[[package]] +name = "bt-hci" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f3c66fd0a41a3b3a5906847b1bf5516048ce083e24fa9341a0fa31d3b4cd73d" dependencies = [ "btuuid", "defmt 1.1.0", @@ -201,19 +216,20 @@ checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" [[package]] name = "cargo_toml" -version = "0.22.3" +version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "374b7c592d9c00c1f4972ea58390ac6b18cbb6ab79011f3bdc90a0b82ca06b77" +checksum = "aa61aec073ec94791433ddf3df2323ff9d1711557c2a0eefb0f99cb4f8dca520" dependencies = [ + "semver 1.0.28", "serde", - "toml 0.9.12+spec-1.1.0", + "toml", ] [[package]] name = "cc" -version = "1.2.64" +version = "1.2.65" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dad887fd958be91b5098c0248def011f4523ab786cd411be668777e55063501f" +checksum = "e228eec9be7c17ccb640b59b36a5cd805ea2a564a4c5e162c2f659fea30d3b96" dependencies = [ "find-msvc-tools", "shlex 2.0.1", @@ -277,9 +293,9 @@ dependencies = [ [[package]] name = "config" -version = "0.15.24" +version = "0.15.25" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0b34d0237145f33580b89724f75d16950efd3e2c91b2d823917ecb69ec7f84f0" +checksum = "b85f248a4de22d204ceabc6299d89d2c70fbd7f09fea53c06c852369652d8139" dependencies = [ "async-trait", "convert_case 0.6.0", @@ -290,7 +306,7 @@ dependencies = [ "serde-untagged", "serde_core", "serde_json", - "toml 1.1.2+spec-1.1.0", + "toml", "winnow 1.0.3", "yaml-rust2", ] @@ -772,9 +788,9 @@ dependencies = [ [[package]] name = "embassy-nrf" -version = "0.10.0" +version = "0.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b715380574504335c40ec3016bc44598fac3c385f82959b26c41b25c30b7648d" +checksum = "82051f67e8a06a8faebd183f62cfade184c96be68126c5f064abb8223a591ff1" dependencies = [ "bitflags 2.13.0", "cfg-if", @@ -791,6 +807,7 @@ dependencies = [ "embassy-time-driver", "embassy-time-queue-utils", "embassy-usb-driver", + "embassy-usb-synopsys-otg", "embedded-hal 0.2.7", "embedded-hal 1.0.0", "embedded-hal-async", @@ -800,6 +817,7 @@ dependencies = [ "embedded-storage-async", "fixed", "nrf-pac", + "rand_core 0.10.1", "rand_core 0.6.4", "rand_core 0.9.5", ] @@ -901,6 +919,20 @@ dependencies = [ "embedded-io-async 0.7.0", ] +[[package]] +name = "embassy-usb-synopsys-otg" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6efd0c0e0b21bcf91b475b8fa47347c1df32c9a99728ae1e1b0e6625862dfd1a" +dependencies = [ + "critical-section", + "defmt 1.1.0", + "embassy-sync", + "embassy-time", + "embassy-usb-driver", + "portable-atomic", +] + [[package]] name = "embedded-hal" version = "0.2.7" @@ -1358,9 +1390,9 @@ checksum = "8f42a60cbdf9a97f5d2305f08a87dc4e09308d1276d28c869c684d7777685682" [[package]] name = "js-sys" -version = "0.3.102" +version = "0.3.103" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "03d04c30968dffe80775bd4d7fb676131cd04a1fb46d2686dbffbaec2d9dfd31" +checksum = "53b44bfcdb3f8d5837a46dae1ca9660a837176eee74a28b229bc626816589102" dependencies = [ "cfg-if", "futures-util", @@ -1423,9 +1455,9 @@ dependencies = [ [[package]] name = "log" -version = "0.4.32" +version = "0.4.33" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "953f07c43838f8e6f9758cab68bf5bed85465e7587ebe0b823f1bcd81978ad3a" +checksum = "0ceec5bc11778974d1bcb055b18002eba7f4b3518b6a0081b3af5f21666da9ad" [[package]] name = "loom" @@ -1500,7 +1532,7 @@ dependencies = [ [[package]] name = "nrf-mpsl" version = "0.3.0" -source = "git+https://github.com/haobogu/nrf-sdc?rev=ffe59a7aefaaa145a3d2474602f33387f80dcefa#ffe59a7aefaaa145a3d2474602f33387f80dcefa" +source = "git+https://github.com/alexmoon/nrf-sdc?rev=abe49d22ebfc85fae134eb082fbfddf752016a55#abe49d22ebfc85fae134eb082fbfddf752016a55" dependencies = [ "cfg-if", "cortex-m", @@ -1516,7 +1548,7 @@ dependencies = [ [[package]] name = "nrf-mpsl-sys" version = "0.2.1" -source = "git+https://github.com/haobogu/nrf-sdc?rev=ffe59a7aefaaa145a3d2474602f33387f80dcefa#ffe59a7aefaaa145a3d2474602f33387f80dcefa" +source = "git+https://github.com/alexmoon/nrf-sdc?rev=abe49d22ebfc85fae134eb082fbfddf752016a55#abe49d22ebfc85fae134eb082fbfddf752016a55" dependencies = [ "bindgen", "doxygen-rs", @@ -1524,9 +1556,9 @@ dependencies = [ [[package]] name = "nrf-pac" -version = "0.3.0" +version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bddd547fab92b0553ff37032034fd04ce8b8b60d3f9a83f89ea815dfd0400336" +checksum = "83531b9f1e19f493018da9b8b20359e4cedd6d1357553b1ac50f3fa27a0104fa" dependencies = [ "cortex-m", "cortex-m-rt", @@ -1535,12 +1567,11 @@ dependencies = [ [[package]] name = "nrf-sdc" version = "0.4.0" -source = "git+https://github.com/haobogu/nrf-sdc?rev=ffe59a7aefaaa145a3d2474602f33387f80dcefa#ffe59a7aefaaa145a3d2474602f33387f80dcefa" +source = "git+https://github.com/alexmoon/nrf-sdc?rev=abe49d22ebfc85fae134eb082fbfddf752016a55#abe49d22ebfc85fae134eb082fbfddf752016a55" dependencies = [ - "bt-hci", + "bt-hci 0.9.0", "critical-section", "defmt 1.1.0", - "embassy-hal-internal 0.5.0", "embassy-nrf", "embassy-sync", "embedded-io 0.7.1", @@ -1553,7 +1584,7 @@ dependencies = [ [[package]] name = "nrf-sdc-sys" version = "0.2.1" -source = "git+https://github.com/haobogu/nrf-sdc?rev=ffe59a7aefaaa145a3d2474602f33387f80dcefa#ffe59a7aefaaa145a3d2474602f33387f80dcefa" +source = "git+https://github.com/alexmoon/nrf-sdc?rev=abe49d22ebfc85fae134eb082fbfddf752016a55#abe49d22ebfc85fae134eb082fbfddf752016a55" dependencies = [ "bindgen", "doxygen-rs", @@ -1818,9 +1849,9 @@ dependencies = [ [[package]] name = "quote" -version = "1.0.45" +version = "1.0.46" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "41f2619966050689382d2b44f664f4bc593e129785a36d6ee376ddf37259b924" +checksum = "dfbc457d0c7a0759a614551b11a6409e5951f6c7537be1f1b7682b9ae9230368" dependencies = [ "proc-macro2", ] @@ -1856,6 +1887,12 @@ version = "0.9.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "76afc826de14238e6e8c374ddcc1fa19e374fd8dd986b0d2af0d02377261d83c" +[[package]] +name = "rand_core" +version = "0.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "63b8176103e19a2643978565ca18b50549f6101881c443590420e4dc998a3c69" + [[package]] name = "regex" version = "1.12.4" @@ -1889,7 +1926,7 @@ checksum = "d6f6ff9a378485b298a5286656da665ba74413d36db0979633275d2e708145d4" name = "rmk" version = "0.8.2" dependencies = [ - "bt-hci", + "bt-hci 0.9.0", "byteorder", "cortex-m", "crc32fast", @@ -1912,7 +1949,6 @@ dependencies = [ "heapless 0.9.3", "paste", "postcard", - "rand_core 0.6.4", "rmk-macro", "rmk-types", "sequential-storage", @@ -1933,7 +1969,7 @@ dependencies = [ "pest_derive", "serde", "serde-inline-default", - "toml 1.1.2+spec-1.1.0", + "toml", ] [[package]] @@ -1954,7 +1990,7 @@ dependencies = [ name = "rmk-nrf52840-embassy-boot" version = "0.2.0" dependencies = [ - "bt-hci", + "bt-hci 0.8.1", "const-gen", "cortex-m", "cortex-m-rt", @@ -1987,14 +2023,14 @@ dependencies = [ "rmk-config", "serde", "strum", - "toml 1.1.2+spec-1.1.0", + "toml", ] [[package]] name = "ron" -version = "0.12.1" +version = "0.12.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4147b952f3f819eca0e99527022f7d6a8d05f111aeb0a62960c74eb283bec8fc" +checksum = "81116b9531d61eabc41aeb228e4b6b2435bcca3233b98cf3b3077d4e6e9debb3" dependencies = [ "bitflags 2.13.0", "once_cell", @@ -2016,9 +2052,9 @@ dependencies = [ [[package]] name = "rustc-hash" -version = "2.1.2" +version = "2.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "94300abf3f1ae2e2b8ffb7b58043de3d399c73fa6f4b73826402a5c457614dbe" +checksum = "6b1e7f9a428571be2dc5bc0505c13fb6bf936822b894ec87abf8a08a4e51742d" [[package]] name = "rustc_version" @@ -2083,6 +2119,10 @@ name = "semver" version = "1.0.28" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8a7852d02fc848982e0c167ef163aaff9cd91dc640ba85e263cb1ce46fae51cd" +dependencies = [ + "serde", + "serde_core", +] [[package]] name = "semver-parser" @@ -2360,21 +2400,6 @@ dependencies = [ "crunchy", ] -[[package]] -name = "toml" -version = "0.9.12+spec-1.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cf92845e79fc2e2def6a5d828f0801e29a2f8acc037becc5ab08595c7d5e9863" -dependencies = [ - "indexmap", - "serde_core", - "serde_spanned", - "toml_datetime 0.7.5+spec-1.1.0", - "toml_parser", - "toml_writer", - "winnow 0.7.15", -] - [[package]] name = "toml" version = "1.1.2+spec-1.1.0" @@ -2384,21 +2409,12 @@ dependencies = [ "indexmap", "serde_core", "serde_spanned", - "toml_datetime 1.1.1+spec-1.1.0", + "toml_datetime", "toml_parser", "toml_writer", "winnow 1.0.3", ] -[[package]] -name = "toml_datetime" -version = "0.7.5+spec-1.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "92e1cfed4a3038bc5a127e35a2d360f145e1f4b971b551a2ba5fd7aedf7e1347" -dependencies = [ - "serde_core", -] - [[package]] name = "toml_datetime" version = "1.1.1+spec-1.1.0" @@ -2486,11 +2502,12 @@ dependencies = [ [[package]] name = "trouble-host" -version = "0.6.0" -source = "git+https://github.com/haobogu/trouble?rev=690373fd1166d16225b875435dd0600c92570e7d#690373fd1166d16225b875435dd0600c92570e7d" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bb9fe2be24000037431b036ba244cdb1d26f40e1719548553fb43c3fc62d496b" dependencies = [ "aes", - "bt-hci", + "bt-hci 0.9.0", "cmac", "defmt 1.1.0", "embassy-futures", @@ -2511,8 +2528,9 @@ dependencies = [ [[package]] name = "trouble-host-macros" -version = "0.4.0" -source = "git+https://github.com/haobogu/trouble?rev=690373fd1166d16225b875435dd0600c92570e7d#690373fd1166d16225b875435dd0600c92570e7d" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2562dc74f79ad12f7bf088da55c936d5eb1d022f2caac9849175326307a5eec1" dependencies = [ "convert_case 0.8.0", "darling 0.20.11", @@ -2601,9 +2619,9 @@ dependencies = [ [[package]] name = "uuid" -version = "1.23.3" +version = "1.23.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "144d6b123cef80b301b8f72a9e2ca4370ddec21950d0a103dd22c437006d2db7" +checksum = "bf80a72845275afea99e7f2b434723d3bc7e38470fcd1c7ed39a599c73319a53" dependencies = [ "js-sys", "wasm-bindgen", @@ -2650,9 +2668,9 @@ checksum = "ccf3ec651a847eb01de73ccad15eb7d99f80485de043efb2f370cd654f4ea44b" [[package]] name = "wasm-bindgen" -version = "0.2.125" +version = "0.2.126" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8ddb3f79143bced6de84270411622a2699cee572fc0875aeaf1e7867cf9fca1a" +checksum = "4b067c0c11094aef6b7a801c1e34a26affafdf3d051dba08456b868789aaf9a4" dependencies = [ "cfg-if", "once_cell", @@ -2663,9 +2681,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro" -version = "0.2.125" +version = "0.2.126" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4e21a184b13fb19e157296e2c46056aec9092264fab83e4ba59e68c61b323c3d" +checksum = "167ce5e579f6bcf889c4f7175a8a5a585de84e8ff93976ce393efa5f2837aab1" dependencies = [ "quote", "wasm-bindgen-macro-support", @@ -2673,9 +2691,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro-support" -version = "0.2.125" +version = "0.2.126" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fecefd9c35bd935a20fc3fc344b5f29138961e4f47fb03297d88f2587afb5ebd" +checksum = "f3997c7839262f4ef12cf90b818d6340c18e80f263f1a94bf157d0ec4420380e" dependencies = [ "bumpalo", "proc-macro2", @@ -2686,9 +2704,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-shared" -version = "0.2.125" +version = "0.2.126" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "23939e44bb9a5d7576fa2b563dc2e136628f1224e88a8deed09e04858b77871f" +checksum = "dc1b4cb0cc549fcf58d7dfc081778139b3d283a081644e833e84682ad71cea24" dependencies = [ "unicode-ident", ] diff --git a/examples/use_config/nrf52840_embassy_boot/Cargo.toml b/examples/use_config/nrf52840_embassy_boot/Cargo.toml index f423269dc..f9af512b7 100644 --- a/examples/use_config/nrf52840_embassy_boot/Cargo.toml +++ b/examples/use_config/nrf52840_embassy_boot/Cargo.toml @@ -16,21 +16,23 @@ rmk = { path = "../../../rmk", features = [ # "dfu_lock" ] } embassy-time = { version = "0.5", features = ["tick-hz-32_768", "defmt"] } -embassy-nrf = { version = "0.10", features = [ +embassy-nrf = { version = "0.11", features = [ "defmt", "nrf52840", "time-driver-rtc1", "gpiote", "unstable-pac", + "nfc-pins-as-gpio", "time", ] } embassy-boot = { version = "0.7", default-features = false } -nrf-sdc = { git = "https://github.com/haobogu/nrf-sdc", rev = "ffe59a7aefaaa145a3d2474602f33387f80dcefa", features = [ +nrf-sdc = { git = "https://github.com/alexmoon/nrf-sdc", rev = "abe49d22ebfc85fae134eb082fbfddf752016a55", features = [ "defmt", "peripheral", + "central", "nrf52840", ] } -nrf-mpsl = { git = "https://github.com/haobogu/nrf-sdc", rev = "ffe59a7aefaaa145a3d2474602f33387f80dcefa", features = [ +nrf-mpsl = { git = "https://github.com/alexmoon/nrf-sdc", rev = "abe49d22ebfc85fae134eb082fbfddf752016a55", features = [ "defmt", "nrf52840", ] } diff --git a/examples/use_config/rp2040_embassy_boot/Cargo.lock b/examples/use_config/rp2040_embassy_boot/Cargo.lock index 18c4043f9..9b0be7d5d 100644 --- a/examples/use_config/rp2040_embassy_boot/Cargo.lock +++ b/examples/use_config/rp2040_embassy_boot/Cargo.lock @@ -166,9 +166,9 @@ dependencies = [ [[package]] name = "bt-hci" -version = "0.8.1" +version = "0.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "211713d2e9fb4793ce4360a712c0764264aff6be48932ccf02ca2a331c0436a9" +checksum = "8f3c66fd0a41a3b3a5906847b1bf5516048ce083e24fa9341a0fa31d3b4cd73d" dependencies = [ "btuuid", "defmt 1.1.0", @@ -211,12 +211,13 @@ checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" [[package]] name = "cargo_toml" -version = "0.22.3" +version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "374b7c592d9c00c1f4972ea58390ac6b18cbb6ab79011f3bdc90a0b82ca06b77" +checksum = "aa61aec073ec94791433ddf3df2323ff9d1711557c2a0eefb0f99cb4f8dca520" dependencies = [ + "semver 1.0.28", "serde", - "toml 0.9.12+spec-1.1.0", + "toml", ] [[package]] @@ -301,8 +302,8 @@ dependencies = [ "serde-untagged", "serde_core", "serde_json", - "toml 1.1.2+spec-1.1.0", - "winnow 1.0.3", + "toml", + "winnow", "yaml-rust2", ] @@ -805,9 +806,9 @@ dependencies = [ [[package]] name = "embassy-nrf" -version = "0.10.0" +version = "0.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b715380574504335c40ec3016bc44598fac3c385f82959b26c41b25c30b7648d" +checksum = "82051f67e8a06a8faebd183f62cfade184c96be68126c5f064abb8223a591ff1" dependencies = [ "bitflags 2.13.0", "cfg-if", @@ -822,6 +823,7 @@ dependencies = [ "embassy-sync", "embassy-time", "embassy-usb-driver", + "embassy-usb-synopsys-otg", "embedded-hal 0.2.7", "embedded-hal 1.0.0", "embedded-hal-async", @@ -831,6 +833,7 @@ dependencies = [ "embedded-storage-async", "fixed", "nrf-pac", + "rand_core 0.10.1", "rand_core 0.6.4", "rand_core 0.9.5", ] @@ -972,6 +975,20 @@ dependencies = [ "embedded-io-async 0.7.0", ] +[[package]] +name = "embassy-usb-synopsys-otg" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6efd0c0e0b21bcf91b475b8fa47347c1df32c9a99728ae1e1b0e6625862dfd1a" +dependencies = [ + "critical-section", + "defmt 1.1.0", + "embassy-sync", + "embassy-time", + "embassy-usb-driver", + "portable-atomic", +] + [[package]] name = "embedded-hal" version = "0.2.7" @@ -1611,9 +1628,9 @@ checksum = "650eef8c711430f1a879fdd01d4745a7deea475becfb90269c06775983bbf086" [[package]] name = "nrf-pac" -version = "0.3.0" +version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bddd547fab92b0553ff37032034fd04ce8b8b60d3f9a83f89ea815dfd0400336" +checksum = "83531b9f1e19f493018da9b8b20359e4cedd6d1357553b1ac50f3fa27a0104fa" dependencies = [ "cortex-m", "cortex-m-rt", @@ -1994,6 +2011,12 @@ version = "0.9.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "76afc826de14238e6e8c374ddcc1fa19e374fd8dd986b0d2af0d02377261d83c" +[[package]] +name = "rand_core" +version = "0.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "63b8176103e19a2643978565ca18b50549f6101881c443590420e4dc998a3c69" + [[package]] name = "redox_syscall" version = "0.5.18" @@ -2072,7 +2095,6 @@ dependencies = [ "postcard", "rmk-macro", "rmk-types", - "rp-pac", "sequential-storage", "serde", "static_cell", @@ -2091,7 +2113,7 @@ dependencies = [ "pest_derive", "serde", "serde-inline-default", - "toml 1.1.2+spec-1.1.0", + "toml", ] [[package]] @@ -2137,7 +2159,7 @@ dependencies = [ "rmk-config", "serde", "strum", - "toml 1.1.2+spec-1.1.0", + "toml", ] [[package]] @@ -2255,6 +2277,10 @@ name = "semver" version = "1.0.28" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8a7852d02fc848982e0c167ef163aaff9cd91dc640ba85e263cb1ce46fae51cd" +dependencies = [ + "serde", + "serde_core", +] [[package]] name = "semver-parser" @@ -2590,21 +2616,6 @@ dependencies = [ "crunchy", ] -[[package]] -name = "toml" -version = "0.9.12+spec-1.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cf92845e79fc2e2def6a5d828f0801e29a2f8acc037becc5ab08595c7d5e9863" -dependencies = [ - "indexmap", - "serde_core", - "serde_spanned", - "toml_datetime 0.7.5+spec-1.1.0", - "toml_parser", - "toml_writer", - "winnow 0.7.15", -] - [[package]] name = "toml" version = "1.1.2+spec-1.1.0" @@ -2614,19 +2625,10 @@ dependencies = [ "indexmap", "serde_core", "serde_spanned", - "toml_datetime 1.1.1+spec-1.1.0", + "toml_datetime", "toml_parser", "toml_writer", - "winnow 1.0.3", -] - -[[package]] -name = "toml_datetime" -version = "0.7.5+spec-1.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "92e1cfed4a3038bc5a127e35a2d360f145e1f4b971b551a2ba5fd7aedf7e1347" -dependencies = [ - "serde_core", + "winnow", ] [[package]] @@ -2644,7 +2646,7 @@ version = "1.1.2+spec-1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a2abe9b86193656635d2411dc43050282ca48aa31c2451210f4202550afb7526" dependencies = [ - "winnow 1.0.3", + "winnow", ] [[package]] @@ -2716,8 +2718,9 @@ dependencies = [ [[package]] name = "trouble-host" -version = "0.6.0" -source = "git+https://github.com/haobogu/trouble?rev=690373fd1166d16225b875435dd0600c92570e7d#690373fd1166d16225b875435dd0600c92570e7d" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bb9fe2be24000037431b036ba244cdb1d26f40e1719548553fb43c3fc62d496b" dependencies = [ "aes", "bt-hci", @@ -2741,8 +2744,9 @@ dependencies = [ [[package]] name = "trouble-host-macros" -version = "0.4.0" -source = "git+https://github.com/haobogu/trouble?rev=690373fd1166d16225b875435dd0600c92570e7d#690373fd1166d16225b875435dd0600c92570e7d" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2562dc74f79ad12f7bf088da55c936d5eb1d022f2caac9849175326307a5eec1" dependencies = [ "convert_case 0.8.0", "darling 0.20.11", @@ -2978,12 +2982,6 @@ dependencies = [ "windows-link", ] -[[package]] -name = "winnow" -version = "0.7.15" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "df79d97927682d2fd8adb29682d1140b343be4ac0f08fd68b7765d9c059d3945" - [[package]] name = "winnow" version = "1.0.3" diff --git a/examples/use_rust/nrf52840_embassy_boot/Cargo.lock b/examples/use_rust/nrf52840_embassy_boot/Cargo.lock index eab0b48a8..b5ccc5526 100644 --- a/examples/use_rust/nrf52840_embassy_boot/Cargo.lock +++ b/examples/use_rust/nrf52840_embassy_boot/Cargo.lock @@ -136,9 +136,9 @@ dependencies = [ [[package]] name = "bt-hci" -version = "0.8.1" +version = "0.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "211713d2e9fb4793ce4360a712c0764264aff6be48932ccf02ca2a331c0436a9" +checksum = "8f3c66fd0a41a3b3a5906847b1bf5516048ce083e24fa9341a0fa31d3b4cd73d" dependencies = [ "btuuid", "defmt 1.1.0", @@ -181,19 +181,20 @@ checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" [[package]] name = "cargo_toml" -version = "0.22.3" +version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "374b7c592d9c00c1f4972ea58390ac6b18cbb6ab79011f3bdc90a0b82ca06b77" +checksum = "aa61aec073ec94791433ddf3df2323ff9d1711557c2a0eefb0f99cb4f8dca520" dependencies = [ + "semver 1.0.28", "serde", - "toml 0.9.12+spec-1.1.0", + "toml", ] [[package]] name = "cc" -version = "1.2.64" +version = "1.2.65" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dad887fd958be91b5098c0248def011f4523ab786cd411be668777e55063501f" +checksum = "e228eec9be7c17ccb640b59b36a5cd805ea2a564a4c5e162c2f659fea30d3b96" dependencies = [ "find-msvc-tools", "shlex", @@ -237,9 +238,9 @@ dependencies = [ [[package]] name = "config" -version = "0.15.24" +version = "0.15.25" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0b34d0237145f33580b89724f75d16950efd3e2c91b2d823917ecb69ec7f84f0" +checksum = "b85f248a4de22d204ceabc6299d89d2c70fbd7f09fea53c06c852369652d8139" dependencies = [ "async-trait", "convert_case 0.6.0", @@ -250,8 +251,8 @@ dependencies = [ "serde-untagged", "serde_core", "serde_json", - "toml 1.1.2+spec-1.1.0", - "winnow 1.0.3", + "toml", + "winnow", "yaml-rust2", ] @@ -717,9 +718,9 @@ dependencies = [ [[package]] name = "embassy-nrf" -version = "0.10.0" +version = "0.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b715380574504335c40ec3016bc44598fac3c385f82959b26c41b25c30b7648d" +checksum = "82051f67e8a06a8faebd183f62cfade184c96be68126c5f064abb8223a591ff1" dependencies = [ "bitflags 2.13.0", "cfg-if", @@ -736,6 +737,7 @@ dependencies = [ "embassy-time-driver", "embassy-time-queue-utils", "embassy-usb-driver", + "embassy-usb-synopsys-otg", "embedded-hal 0.2.7", "embedded-hal 1.0.0", "embedded-hal-async", @@ -745,6 +747,7 @@ dependencies = [ "embedded-storage-async", "fixed", "nrf-pac", + "rand_core 0.10.1", "rand_core 0.6.4", "rand_core 0.9.5", ] @@ -846,6 +849,20 @@ dependencies = [ "embedded-io-async 0.7.0", ] +[[package]] +name = "embassy-usb-synopsys-otg" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6efd0c0e0b21bcf91b475b8fa47347c1df32c9a99728ae1e1b0e6625862dfd1a" +dependencies = [ + "critical-section", + "defmt 1.1.0", + "embassy-sync", + "embassy-time", + "embassy-usb-driver", + "portable-atomic", +] + [[package]] name = "embedded-hal" version = "0.2.7" @@ -1288,9 +1305,9 @@ checksum = "8f42a60cbdf9a97f5d2305f08a87dc4e09308d1276d28c869c684d7777685682" [[package]] name = "js-sys" -version = "0.3.102" +version = "0.3.103" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "03d04c30968dffe80775bd4d7fb676131cd04a1fb46d2686dbffbaec2d9dfd31" +checksum = "53b44bfcdb3f8d5837a46dae1ca9660a837176eee74a28b229bc626816589102" dependencies = [ "cfg-if", "futures-util", @@ -1343,9 +1360,9 @@ dependencies = [ [[package]] name = "log" -version = "0.4.32" +version = "0.4.33" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "953f07c43838f8e6f9758cab68bf5bed85465e7587ebe0b823f1bcd81978ad3a" +checksum = "0ceec5bc11778974d1bcb055b18002eba7f4b3518b6a0081b3af5f21666da9ad" [[package]] name = "loom" @@ -1403,9 +1420,9 @@ checksum = "8d5439c4ad607c3c23abf66de8c8bf57ba8adcd1f129e699851a6e43935d339d" [[package]] name = "nrf-pac" -version = "0.3.0" +version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bddd547fab92b0553ff37032034fd04ce8b8b60d3f9a83f89ea815dfd0400336" +checksum = "83531b9f1e19f493018da9b8b20359e4cedd6d1357553b1ac50f3fa27a0104fa" dependencies = [ "cortex-m", "cortex-m-rt", @@ -1613,9 +1630,9 @@ dependencies = [ [[package]] name = "quote" -version = "1.0.45" +version = "1.0.46" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "41f2619966050689382d2b44f664f4bc593e129785a36d6ee376ddf37259b924" +checksum = "dfbc457d0c7a0759a614551b11a6409e5951f6c7537be1f1b7682b9ae9230368" dependencies = [ "proc-macro2", ] @@ -1651,6 +1668,12 @@ version = "0.9.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "76afc826de14238e6e8c374ddcc1fa19e374fd8dd986b0d2af0d02377261d83c" +[[package]] +name = "rand_core" +version = "0.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "63b8176103e19a2643978565ca18b50549f6101881c443590420e4dc998a3c69" + [[package]] name = "regex-automata" version = "0.4.14" @@ -1715,7 +1738,7 @@ dependencies = [ "pest_derive", "serde", "serde-inline-default", - "toml 1.1.2+spec-1.1.0", + "toml", ] [[package]] @@ -1762,14 +1785,14 @@ dependencies = [ "rmk-config", "serde", "strum", - "toml 1.1.2+spec-1.1.0", + "toml", ] [[package]] name = "ron" -version = "0.12.1" +version = "0.12.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4147b952f3f819eca0e99527022f7d6a8d05f111aeb0a62960c74eb283bec8fc" +checksum = "81116b9531d61eabc41aeb228e4b6b2435bcca3233b98cf3b3077d4e6e9debb3" dependencies = [ "bitflags 2.13.0", "once_cell", @@ -1852,6 +1875,10 @@ name = "semver" version = "1.0.28" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8a7852d02fc848982e0c167ef163aaff9cd91dc640ba85e263cb1ce46fae51cd" +dependencies = [ + "serde", + "serde_core", +] [[package]] name = "semver-parser" @@ -2117,21 +2144,6 @@ dependencies = [ "crunchy", ] -[[package]] -name = "toml" -version = "0.9.12+spec-1.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cf92845e79fc2e2def6a5d828f0801e29a2f8acc037becc5ab08595c7d5e9863" -dependencies = [ - "indexmap", - "serde_core", - "serde_spanned", - "toml_datetime 0.7.5+spec-1.1.0", - "toml_parser", - "toml_writer", - "winnow 0.7.15", -] - [[package]] name = "toml" version = "1.1.2+spec-1.1.0" @@ -2141,19 +2153,10 @@ dependencies = [ "indexmap", "serde_core", "serde_spanned", - "toml_datetime 1.1.1+spec-1.1.0", + "toml_datetime", "toml_parser", "toml_writer", - "winnow 1.0.3", -] - -[[package]] -name = "toml_datetime" -version = "0.7.5+spec-1.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "92e1cfed4a3038bc5a127e35a2d360f145e1f4b971b551a2ba5fd7aedf7e1347" -dependencies = [ - "serde_core", + "winnow", ] [[package]] @@ -2171,7 +2174,7 @@ version = "1.1.2+spec-1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a2abe9b86193656635d2411dc43050282ca48aa31c2451210f4202550afb7526" dependencies = [ - "winnow 1.0.3", + "winnow", ] [[package]] @@ -2243,8 +2246,9 @@ dependencies = [ [[package]] name = "trouble-host" -version = "0.6.0" -source = "git+https://github.com/haobogu/trouble?rev=690373fd1166d16225b875435dd0600c92570e7d#690373fd1166d16225b875435dd0600c92570e7d" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bb9fe2be24000037431b036ba244cdb1d26f40e1719548553fb43c3fc62d496b" dependencies = [ "aes", "bt-hci", @@ -2268,8 +2272,9 @@ dependencies = [ [[package]] name = "trouble-host-macros" -version = "0.4.0" -source = "git+https://github.com/haobogu/trouble?rev=690373fd1166d16225b875435dd0600c92570e7d#690373fd1166d16225b875435dd0600c92570e7d" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2562dc74f79ad12f7bf088da55c936d5eb1d022f2caac9849175326307a5eec1" dependencies = [ "convert_case 0.8.0", "darling 0.20.11", @@ -2358,9 +2363,9 @@ dependencies = [ [[package]] name = "uuid" -version = "1.23.3" +version = "1.23.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "144d6b123cef80b301b8f72a9e2ca4370ddec21950d0a103dd22c437006d2db7" +checksum = "bf80a72845275afea99e7f2b434723d3bc7e38470fcd1c7ed39a599c73319a53" dependencies = [ "js-sys", "wasm-bindgen", @@ -2407,9 +2412,9 @@ checksum = "ccf3ec651a847eb01de73ccad15eb7d99f80485de043efb2f370cd654f4ea44b" [[package]] name = "wasm-bindgen" -version = "0.2.125" +version = "0.2.126" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8ddb3f79143bced6de84270411622a2699cee572fc0875aeaf1e7867cf9fca1a" +checksum = "4b067c0c11094aef6b7a801c1e34a26affafdf3d051dba08456b868789aaf9a4" dependencies = [ "cfg-if", "once_cell", @@ -2420,9 +2425,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro" -version = "0.2.125" +version = "0.2.126" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4e21a184b13fb19e157296e2c46056aec9092264fab83e4ba59e68c61b323c3d" +checksum = "167ce5e579f6bcf889c4f7175a8a5a585de84e8ff93976ce393efa5f2837aab1" dependencies = [ "quote", "wasm-bindgen-macro-support", @@ -2430,9 +2435,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro-support" -version = "0.2.125" +version = "0.2.126" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fecefd9c35bd935a20fc3fc344b5f29138961e4f47fb03297d88f2587afb5ebd" +checksum = "f3997c7839262f4ef12cf90b818d6340c18e80f263f1a94bf157d0ec4420380e" dependencies = [ "bumpalo", "proc-macro2", @@ -2443,9 +2448,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-shared" -version = "0.2.125" +version = "0.2.126" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "23939e44bb9a5d7576fa2b563dc2e136628f1224e88a8deed09e04858b77871f" +checksum = "dc1b4cb0cc549fcf58d7dfc081778139b3d283a081644e833e84682ad71cea24" dependencies = [ "unicode-ident", ] @@ -2474,12 +2479,6 @@ dependencies = [ "windows-link", ] -[[package]] -name = "winnow" -version = "0.7.15" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "df79d97927682d2fd8adb29682d1140b343be4ac0f08fd68b7765d9c059d3945" - [[package]] name = "winnow" version = "1.0.3" diff --git a/examples/use_rust/nrf52840_embassy_boot/Cargo.toml b/examples/use_rust/nrf52840_embassy_boot/Cargo.toml index 4ebc8eb0b..8339faa0f 100644 --- a/examples/use_rust/nrf52840_embassy_boot/Cargo.toml +++ b/examples/use_rust/nrf52840_embassy_boot/Cargo.toml @@ -15,11 +15,13 @@ rmk = { path = "../../../rmk", features = [ # "dfu_lock" ] } embassy-time = { version = "0.5", features = ["defmt"] } -embassy-nrf = { version = "0.10", features = [ +embassy-nrf = { version = "0.11", features = [ "defmt", "nrf52840", "time-driver-rtc1", "gpiote", + "unstable-pac", + "time", ] } embassy-boot = { version = "0.7" } embassy-executor = { version = "0.10", features = [ diff --git a/examples/use_rust/rp2040_embassy_boot/Cargo.lock b/examples/use_rust/rp2040_embassy_boot/Cargo.lock index 18c4043f9..9b0be7d5d 100644 --- a/examples/use_rust/rp2040_embassy_boot/Cargo.lock +++ b/examples/use_rust/rp2040_embassy_boot/Cargo.lock @@ -166,9 +166,9 @@ dependencies = [ [[package]] name = "bt-hci" -version = "0.8.1" +version = "0.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "211713d2e9fb4793ce4360a712c0764264aff6be48932ccf02ca2a331c0436a9" +checksum = "8f3c66fd0a41a3b3a5906847b1bf5516048ce083e24fa9341a0fa31d3b4cd73d" dependencies = [ "btuuid", "defmt 1.1.0", @@ -211,12 +211,13 @@ checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" [[package]] name = "cargo_toml" -version = "0.22.3" +version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "374b7c592d9c00c1f4972ea58390ac6b18cbb6ab79011f3bdc90a0b82ca06b77" +checksum = "aa61aec073ec94791433ddf3df2323ff9d1711557c2a0eefb0f99cb4f8dca520" dependencies = [ + "semver 1.0.28", "serde", - "toml 0.9.12+spec-1.1.0", + "toml", ] [[package]] @@ -301,8 +302,8 @@ dependencies = [ "serde-untagged", "serde_core", "serde_json", - "toml 1.1.2+spec-1.1.0", - "winnow 1.0.3", + "toml", + "winnow", "yaml-rust2", ] @@ -805,9 +806,9 @@ dependencies = [ [[package]] name = "embassy-nrf" -version = "0.10.0" +version = "0.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b715380574504335c40ec3016bc44598fac3c385f82959b26c41b25c30b7648d" +checksum = "82051f67e8a06a8faebd183f62cfade184c96be68126c5f064abb8223a591ff1" dependencies = [ "bitflags 2.13.0", "cfg-if", @@ -822,6 +823,7 @@ dependencies = [ "embassy-sync", "embassy-time", "embassy-usb-driver", + "embassy-usb-synopsys-otg", "embedded-hal 0.2.7", "embedded-hal 1.0.0", "embedded-hal-async", @@ -831,6 +833,7 @@ dependencies = [ "embedded-storage-async", "fixed", "nrf-pac", + "rand_core 0.10.1", "rand_core 0.6.4", "rand_core 0.9.5", ] @@ -972,6 +975,20 @@ dependencies = [ "embedded-io-async 0.7.0", ] +[[package]] +name = "embassy-usb-synopsys-otg" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6efd0c0e0b21bcf91b475b8fa47347c1df32c9a99728ae1e1b0e6625862dfd1a" +dependencies = [ + "critical-section", + "defmt 1.1.0", + "embassy-sync", + "embassy-time", + "embassy-usb-driver", + "portable-atomic", +] + [[package]] name = "embedded-hal" version = "0.2.7" @@ -1611,9 +1628,9 @@ checksum = "650eef8c711430f1a879fdd01d4745a7deea475becfb90269c06775983bbf086" [[package]] name = "nrf-pac" -version = "0.3.0" +version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bddd547fab92b0553ff37032034fd04ce8b8b60d3f9a83f89ea815dfd0400336" +checksum = "83531b9f1e19f493018da9b8b20359e4cedd6d1357553b1ac50f3fa27a0104fa" dependencies = [ "cortex-m", "cortex-m-rt", @@ -1994,6 +2011,12 @@ version = "0.9.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "76afc826de14238e6e8c374ddcc1fa19e374fd8dd986b0d2af0d02377261d83c" +[[package]] +name = "rand_core" +version = "0.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "63b8176103e19a2643978565ca18b50549f6101881c443590420e4dc998a3c69" + [[package]] name = "redox_syscall" version = "0.5.18" @@ -2072,7 +2095,6 @@ dependencies = [ "postcard", "rmk-macro", "rmk-types", - "rp-pac", "sequential-storage", "serde", "static_cell", @@ -2091,7 +2113,7 @@ dependencies = [ "pest_derive", "serde", "serde-inline-default", - "toml 1.1.2+spec-1.1.0", + "toml", ] [[package]] @@ -2137,7 +2159,7 @@ dependencies = [ "rmk-config", "serde", "strum", - "toml 1.1.2+spec-1.1.0", + "toml", ] [[package]] @@ -2255,6 +2277,10 @@ name = "semver" version = "1.0.28" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8a7852d02fc848982e0c167ef163aaff9cd91dc640ba85e263cb1ce46fae51cd" +dependencies = [ + "serde", + "serde_core", +] [[package]] name = "semver-parser" @@ -2590,21 +2616,6 @@ dependencies = [ "crunchy", ] -[[package]] -name = "toml" -version = "0.9.12+spec-1.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cf92845e79fc2e2def6a5d828f0801e29a2f8acc037becc5ab08595c7d5e9863" -dependencies = [ - "indexmap", - "serde_core", - "serde_spanned", - "toml_datetime 0.7.5+spec-1.1.0", - "toml_parser", - "toml_writer", - "winnow 0.7.15", -] - [[package]] name = "toml" version = "1.1.2+spec-1.1.0" @@ -2614,19 +2625,10 @@ dependencies = [ "indexmap", "serde_core", "serde_spanned", - "toml_datetime 1.1.1+spec-1.1.0", + "toml_datetime", "toml_parser", "toml_writer", - "winnow 1.0.3", -] - -[[package]] -name = "toml_datetime" -version = "0.7.5+spec-1.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "92e1cfed4a3038bc5a127e35a2d360f145e1f4b971b551a2ba5fd7aedf7e1347" -dependencies = [ - "serde_core", + "winnow", ] [[package]] @@ -2644,7 +2646,7 @@ version = "1.1.2+spec-1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a2abe9b86193656635d2411dc43050282ca48aa31c2451210f4202550afb7526" dependencies = [ - "winnow 1.0.3", + "winnow", ] [[package]] @@ -2716,8 +2718,9 @@ dependencies = [ [[package]] name = "trouble-host" -version = "0.6.0" -source = "git+https://github.com/haobogu/trouble?rev=690373fd1166d16225b875435dd0600c92570e7d#690373fd1166d16225b875435dd0600c92570e7d" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bb9fe2be24000037431b036ba244cdb1d26f40e1719548553fb43c3fc62d496b" dependencies = [ "aes", "bt-hci", @@ -2741,8 +2744,9 @@ dependencies = [ [[package]] name = "trouble-host-macros" -version = "0.4.0" -source = "git+https://github.com/haobogu/trouble?rev=690373fd1166d16225b875435dd0600c92570e7d#690373fd1166d16225b875435dd0600c92570e7d" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2562dc74f79ad12f7bf088da55c936d5eb1d022f2caac9849175326307a5eec1" dependencies = [ "convert_case 0.8.0", "darling 0.20.11", @@ -2978,12 +2982,6 @@ dependencies = [ "windows-link", ] -[[package]] -name = "winnow" -version = "0.7.15" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "df79d97927682d2fd8adb29682d1140b343be4ac0f08fd68b7765d9c059d3945" - [[package]] name = "winnow" version = "1.0.3" diff --git a/examples/use_rust/rp2040_embassy_boot/src/main.rs b/examples/use_rust/rp2040_embassy_boot/src/main.rs index c610a6bbb..df449e9cb 100644 --- a/examples/use_rust/rp2040_embassy_boot/src/main.rs +++ b/examples/use_rust/rp2040_embassy_boot/src/main.rs @@ -93,10 +93,8 @@ async fn main(_spawner: Spawner) { dfu_size, )); - let mut dfu_led_processor = rmk::processor::builtin::dfu_led::DfuLedProcessor::new( - Output::new(p.PIN_25, Level::Low), - false, - ); + let mut dfu_led_processor = + rmk::processor::builtin::dfu_led::DfuLedProcessor::new(Output::new(p.PIN_25, Level::Low), false); let keyboard_device_config = DeviceConfig { vid: 0x4c4b, diff --git a/examples/use_rust/rp2040_embassy_boot_split/.cargo/config.toml b/examples/use_rust/rp2040_embassy_boot_split/.cargo/config.toml new file mode 100644 index 000000000..f1b4cbff9 --- /dev/null +++ b/examples/use_rust/rp2040_embassy_boot_split/.cargo/config.toml @@ -0,0 +1,11 @@ +[target.'cfg(all(target_arch = "arm", target_os = "none"))'] +runner = "probe-rs run --chip RP2040" +# runner = "elf2uf2-rs -d" + +linker = "flip-link" + +[build] +target = "thumbv6m-none-eabi" + +[env] +DEFMT_LOG = "debug" diff --git a/examples/use_rust/rp2040_embassy_boot_split/Cargo.lock b/examples/use_rust/rp2040_embassy_boot_split/Cargo.lock new file mode 100644 index 000000000..bff55ffec --- /dev/null +++ b/examples/use_rust/rp2040_embassy_boot_split/Cargo.lock @@ -0,0 +1,3045 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 4 + +[[package]] +name = "aes" +version = "0.8.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b169f7a6d4742236a0a00c541b845991d0ac43e546831af1249753ab4c3aa3a0" +dependencies = [ + "cfg-if", + "cipher", + "cpufeatures", +] + +[[package]] +name = "ahash" +version = "0.8.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5a15f179cd60c4584b8a8c596927aadc462e27f2ca70c04e0071964a73ba7a75" +dependencies = [ + "cfg-if", + "once_cell", + "version_check", + "zerocopy", +] + +[[package]] +name = "aho-corasick" +version = "1.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ddd31a130427c27518df266943a5308ed92d4b226cc639f5a8f1002816174301" +dependencies = [ + "memchr", +] + +[[package]] +name = "arraydeque" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7d902e3d592a523def97af8f317b08ce16b7ab854c1985a0c671e6f15cebc236" + +[[package]] +name = "arrayvec" +version = "0.7.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f02882884d3e1bc524fb12c79f107f6ad0e1cfd498c536ffb494301740995dfe" + +[[package]] +name = "ascii-canvas" +version = "4.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ef1e3e699d84ab1b0911a1010c5c106aa34ae89aeac103be5ce0c3859db1e891" +dependencies = [ + "term", +] + +[[package]] +name = "async-trait" +version = "0.1.89" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9035ad2d096bed7955a320ee7e2230574d28fd3c3a0f186cbea1ff3c7eed5dbb" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.118", +] + +[[package]] +name = "atomic-polyfill" +version = "1.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8cf2bce30dfe09ef0bfaef228b9d414faaf7e563035494d7fe092dba54b300f4" +dependencies = [ + "critical-section", +] + +[[package]] +name = "autocfg" +version = "1.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f2032f911046de80f0a198e0901378627c33f59ea0ac00e363d481118bd70a53" + +[[package]] +name = "az" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "be5eb007b7cacc6c660343e96f650fedf4b5a77512399eb952ca6642cf8d13f7" + +[[package]] +name = "bare-metal" +version = "0.2.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5deb64efa5bd81e31fcd1938615a6d98c82eafcbcd787162b6f63b91d6bac5b3" +dependencies = [ + "rustc_version 0.2.3", +] + +[[package]] +name = "base16ct" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4c7f02d4ea65f2c1853089ffd8d2787bdbc63de2f0d29dedbcf8ccdfa0ccd4cf" + +[[package]] +name = "bit-set" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "08807e080ed7f9d5433fa9b275196cfc35414f66a0c79d864dc51a0d825231a3" +dependencies = [ + "bit-vec", +] + +[[package]] +name = "bit-vec" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5e764a1d40d510daf35e07be9eb06e75770908c27d411ee6c92109c9840eaaf7" + +[[package]] +name = "bitfield" +version = "0.13.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "46afbd2983a5d5a7bd740ccb198caf5b82f45c40c09c0eed36052d91cb92e719" + +[[package]] +name = "bitfield" +version = "0.14.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2d7e60934ceec538daadb9d8432424ed043a904d8e0243f3c6446bce549a46ac" + +[[package]] +name = "bitfield-struct" +version = "0.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3ca6739863c590881f038d033a146c51ddae239186a4327014839fd864f44ed5" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.118", +] + +[[package]] +name = "bitflags" +version = "1.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" + +[[package]] +name = "bitflags" +version = "2.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b4388bee8683e3d04af747c73422af53102d2bd24d9eadb6cbc100baef4b43f8" +dependencies = [ + "serde_core", +] + +[[package]] +name = "block-buffer" +version = "0.10.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3078c7629b62d3f0439517fa394996acacc5cbc91c5a20d8c658e77abd503a71" +dependencies = [ + "generic-array", +] + +[[package]] +name = "bt-hci" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f3c66fd0a41a3b3a5906847b1bf5516048ce083e24fa9341a0fa31d3b4cd73d" +dependencies = [ + "btuuid", + "defmt 1.1.0", + "embassy-sync", + "embedded-io 0.7.1", + "embedded-io-async 0.7.0", + "futures-intrusive", + "heapless 0.9.3", + "serde", +] + +[[package]] +name = "btuuid" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f5f48f1e9b0aad0a4f05d17bdeae0fa20ff798e272a03a6940ca27ad9c5a6ae7" +dependencies = [ + "defmt 0.3.100", + "serde", + "uuid", +] + +[[package]] +name = "bumpalo" +version = "3.20.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "72f5acc6cb2ba439de613abc23857ec3d78374d8ed5ac84e9d11336e87da8649" + +[[package]] +name = "bytemuck" +version = "1.25.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c8efb64bd706a16a1bdde310ae86b351e4d21550d98d056f22f8a7f7a2183fec" + +[[package]] +name = "byteorder" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" + +[[package]] +name = "cargo_toml" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "aa61aec073ec94791433ddf3df2323ff9d1711557c2a0eefb0f99cb4f8dca520" +dependencies = [ + "semver 1.0.28", + "serde", + "toml", +] + +[[package]] +name = "cc" +version = "1.2.65" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e228eec9be7c17ccb640b59b36a5cd805ea2a564a4c5e162c2f659fea30d3b96" +dependencies = [ + "find-msvc-tools", + "shlex", +] + +[[package]] +name = "cfg-if" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9330f8b2ff13f34540b44e946ef35111825727b38d33286ef986142615121801" + +[[package]] +name = "chrono" +version = "0.4.45" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1aa79e62e7697b8e29b513a68abacf485adcd1fe8284a4316c5ae868e6633327" +dependencies = [ + "defmt 1.1.0", + "num-traits", + "pure-rust-locales", +] + +[[package]] +name = "cipher" +version = "0.4.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "773f3b9af64447d2ce9850330c473515014aa235e6a783b02db81ff39e4a3dad" +dependencies = [ + "crypto-common", + "inout", +] + +[[package]] +name = "cmac" +version = "0.7.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8543454e3c3f5126effff9cd44d562af4e31fb8ce1cc0d3dcd8f084515dbc1aa" +dependencies = [ + "cipher", + "dbl", + "digest", +] + +[[package]] +name = "cobs" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0fa961b519f0b462e3a3b4a34b64d119eeaca1d59af726fe450bbba07a9fc0a1" +dependencies = [ + "thiserror", +] + +[[package]] +name = "codespan-reporting" +version = "0.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3538270d33cc669650c4b093848450d380def10c331d38c768e34cac80576e6e" +dependencies = [ + "termcolor", + "unicode-width", +] + +[[package]] +name = "config" +version = "0.15.25" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b85f248a4de22d204ceabc6299d89d2c70fbd7f09fea53c06c852369652d8139" +dependencies = [ + "async-trait", + "convert_case 0.6.0", + "json5", + "pathdiff", + "ron", + "rust-ini", + "serde-untagged", + "serde_core", + "serde_json", + "toml", + "winnow", + "yaml-rust2", +] + +[[package]] +name = "const-gen" +version = "1.6.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a0bb51eeea292ceb9bf5312b4416c1b151b130502e6892a2ae174ae1e4b51e58" +dependencies = [ + "const-gen-derive", +] + +[[package]] +name = "const-gen-derive" +version = "1.1.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eabc01a5585d36649b6bee1f1198d112a7bb4982661d6c18406fba571ce3263e" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "const-oid" +version = "0.9.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c2459377285ad874054d797f3ccebf984978aa39129f6eafde5cdc8315b612f8" + +[[package]] +name = "const-random" +version = "0.1.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "87e00182fe74b066627d63b85fd550ac2998d4b0bd86bfed477a0ae4c7c71359" +dependencies = [ + "const-random-macro", +] + +[[package]] +name = "const-random-macro" +version = "0.1.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f9d839f2a20b0aee515dc581a6172f2321f96cab76c1a38a4c584a194955390e" +dependencies = [ + "getrandom", + "once_cell", + "tiny-keccak", +] + +[[package]] +name = "convert_case" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ec182b0ca2f35d8fc196cf3404988fd8b8c739a4d270ff118a398feb0cbec1ca" +dependencies = [ + "unicode-segmentation", +] + +[[package]] +name = "convert_case" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "baaaa0ecca5b51987b9423ccdc971514dd8b0bb7b4060b983d3664dad3f1f89f" +dependencies = [ + "unicode-segmentation", +] + +[[package]] +name = "cordyceps" +version = "0.3.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "688d7fbb8092b8de775ef2536f36c8c31f2bc4006ece2e8d8ad2d17d00ce0a2a" +dependencies = [ + "loom", + "tracing", +] + +[[package]] +name = "cortex-m" +version = "0.7.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8ec610d8f49840a5b376c69663b6369e71f4b34484b9b2eb29fb918d92516cb9" +dependencies = [ + "bare-metal", + "bitfield 0.13.2", + "embedded-hal 0.2.7", + "volatile-register", +] + +[[package]] +name = "cortex-m-rt" +version = "0.7.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "801d4dec46b34c299ccf6b036717ae0fce602faa4f4fe816d9013b9a7c9f5ba6" +dependencies = [ + "cortex-m-rt-macros", +] + +[[package]] +name = "cortex-m-rt-macros" +version = "0.7.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e37549a379a9e0e6e576fd208ee60394ccb8be963889eebba3ffe0980364f472" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.118", +] + +[[package]] +name = "cpufeatures" +version = "0.2.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "59ed5838eebb26a2bb2e58f6d5b5316989ae9d08bab10e0e6d103e656d1b0280" +dependencies = [ + "libc", +] + +[[package]] +name = "crc-any" +version = "2.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "46db9f663dfb869b80fcf59e32d7a80fc6c464a4f6328f3f06a00f5e36d05f8c" +dependencies = [ + "debug-helper", +] + +[[package]] +name = "crc32fast" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9481c1c90cbf2ac953f07c8d4a58aa3945c425b7185c9154d67a65e4230da511" +dependencies = [ + "cfg-if", +] + +[[package]] +name = "critical-section" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "790eea4361631c5e7d22598ecd5723ff611904e3344ce8720784c93e3d83d40b" + +[[package]] +name = "crunchy" +version = "0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "460fbee9c2c2f33933d720630a6a0bac33ba7053db5344fac858d4b8952d77d5" + +[[package]] +name = "crypto-bigint" +version = "0.5.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0dc92fb57ca44df6db8059111ab3af99a63d5d0f8375d9972e319a379c6bab76" +dependencies = [ + "generic-array", + "rand_core 0.6.4", + "subtle", + "zeroize", +] + +[[package]] +name = "crypto-common" +version = "0.1.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "78c8292055d1c1df0cce5d180393dc8cce0abec0a7102adb6c7b1eef6016d60a" +dependencies = [ + "generic-array", + "typenum", +] + +[[package]] +name = "darling" +version = "0.20.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fc7f46116c46ff9ab3eb1597a45688b6715c6e628b5c133e288e709a29bcb4ee" +dependencies = [ + "darling_core 0.20.11", + "darling_macro 0.20.11", +] + +[[package]] +name = "darling" +version = "0.23.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "25ae13da2f202d56bd7f91c25fba009e7717a1e4a1cc98a76d844b65ae912e9d" +dependencies = [ + "darling_core 0.23.0", + "darling_macro 0.23.0", +] + +[[package]] +name = "darling_core" +version = "0.20.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0d00b9596d185e565c2207a0b01f8bd1a135483d02d9b7b0a54b11da8d53412e" +dependencies = [ + "fnv", + "ident_case", + "proc-macro2", + "quote", + "strsim", + "syn 2.0.118", +] + +[[package]] +name = "darling_core" +version = "0.23.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9865a50f7c335f53564bb694ef660825eb8610e0a53d3e11bf1b0d3df31e03b0" +dependencies = [ + "ident_case", + "proc-macro2", + "quote", + "strsim", + "syn 2.0.118", +] + +[[package]] +name = "darling_macro" +version = "0.20.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fc34b93ccb385b40dc71c6fceac4b2ad23662c7eeb248cf10d529b7e055b6ead" +dependencies = [ + "darling_core 0.20.11", + "quote", + "syn 2.0.118", +] + +[[package]] +name = "darling_macro" +version = "0.23.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ac3984ec7bd6cfa798e62b4a642426a5be0e68f9401cfc2a01e3fa9ea2fcdb8d" +dependencies = [ + "darling_core 0.23.0", + "quote", + "syn 2.0.118", +] + +[[package]] +name = "dbl" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bd2735a791158376708f9347fe8faba9667589d82427ef3aed6794a8981de3d9" +dependencies = [ + "generic-array", +] + +[[package]] +name = "debug-helper" +version = "0.3.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "80a4af69c60438a1a82af89d362f4729fd38db7b73f305a237636fad31ceb2bf" + +[[package]] +name = "defmt" +version = "0.3.100" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f0963443817029b2024136fc4dd07a5107eb8f977eaf18fcd1fdeb11306b64ad" +dependencies = [ + "defmt 1.1.0", +] + +[[package]] +name = "defmt" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a6e524506490a1953d237cb87b1cfc1e46f88c18f10a22dfe0f507dc6bfc7f7f" +dependencies = [ + "bitflags 1.3.2", + "defmt-macros", +] + +[[package]] +name = "defmt-macros" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f0a27770e9c8f719a79d8b638281f4d828f77d8fd61e0bd94451b9b85e576a0b" +dependencies = [ + "defmt-parser", + "proc-macro-error2", + "proc-macro2", + "quote", + "syn 2.0.118", +] + +[[package]] +name = "defmt-parser" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "10d60334b3b2e7c9d91ef8150abfb6fa4c1c39ebbcf4a81c2e346aad939fee3e" +dependencies = [ + "thiserror", +] + +[[package]] +name = "defmt-rtt" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c0f73a4a4a91609e977ae3b7bd831ffa292edfd42ad140a3244a61d805b0e05e" +dependencies = [ + "critical-section", + "defmt 1.1.0", +] + +[[package]] +name = "der" +version = "0.7.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e7c1832837b905bbfb5101e07cc24c8deddf52f93225eee6ead5f4d63d53ddcb" +dependencies = [ + "const-oid", + "zeroize", +] + +[[package]] +name = "digest" +version = "0.10.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292" +dependencies = [ + "block-buffer", + "crypto-common", + "subtle", +] + +[[package]] +name = "dlv-list" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "442039f5147480ba31067cb00ada1adae6892028e40e45fc5de7b7df6dcc1b5f" +dependencies = [ + "const-random", +] + +[[package]] +name = "document-features" +version = "0.2.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d4b8a88685455ed29a21542a33abd9cb6510b6b129abadabdcef0f4c55bc8f61" +dependencies = [ + "litrs", +] + +[[package]] +name = "either" +version = "1.16.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "91622ff5e7162018101f2fea40d6ebf4a78bbe5a49736a2020649edf9693679e" + +[[package]] +name = "elliptic-curve" +version = "0.13.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b5e6043086bf7973472e0c7dff2142ea0b680d30e18d9cc40f267efbf222bd47" +dependencies = [ + "base16ct", + "crypto-bigint", + "digest", + "ff", + "generic-array", + "group", + "hkdf", + "rand_core 0.6.4", + "sec1", + "subtle", + "zeroize", +] + +[[package]] +name = "embassy-boot" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "73bfc955c9238df2ce9fecc6f18a64b13ecaa41a3cd42d940a09f304765d10db" +dependencies = [ + "digest", + "document-features", + "embassy-embedded-hal", + "embassy-sync", + "embedded-storage", + "embedded-storage-async", + "signature", +] + +[[package]] +name = "embassy-boot-rp" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3fc17df4cf2a8ba86e8559a6515104e31ca7aa6b36221199310e244157935204" +dependencies = [ + "cfg-if", + "cortex-m", + "cortex-m-rt", + "embassy-boot", + "embassy-rp", + "embassy-sync", + "embassy-time", + "embedded-storage", + "embedded-storage-async", +] + +[[package]] +name = "embassy-embedded-hal" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b0641612053b2f34fc250bb63f6630ae75de46e02ade7f457268447081d709ce" +dependencies = [ + "defmt 1.1.0", + "embassy-futures", + "embassy-hal-internal 0.4.0", + "embassy-sync", + "embassy-time", + "embedded-hal 0.2.7", + "embedded-hal 1.0.0", + "embedded-hal-async", + "embedded-storage", + "embedded-storage-async", + "nb 1.1.0", +] + +[[package]] +name = "embassy-executor" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5d0d3b15c9d7dc4fec1d8cb77112472fb008b3b28c51ad23838d83587a6d2f1e" +dependencies = [ + "cordyceps", + "cortex-m", + "critical-section", + "defmt 1.1.0", + "document-features", + "embassy-executor-macros", + "embassy-executor-timer-queue", +] + +[[package]] +name = "embassy-executor-macros" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d11a246f53de5f97a387f40ac24726817cd0b6f833e7603baac784f29d6ff276" +dependencies = [ + "darling 0.20.11", + "proc-macro2", + "quote", + "syn 2.0.118", +] + +[[package]] +name = "embassy-executor-timer-queue" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2fc328bf943af66b80b98755db9106bf7e7471b0cf47dc8559cd9a6be504cc9c" + +[[package]] +name = "embassy-futures" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dc2d050bdc5c21e0862a89256ed8029ae6c290a93aecefc73084b3002cdebb01" +dependencies = [ + "defmt 1.1.0", +] + +[[package]] +name = "embassy-hal-internal" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7f10ce10a4dfdf6402d8e9bd63128986b96a736b1a0a6680547ed2ac55d55dba" +dependencies = [ + "num-traits", +] + +[[package]] +name = "embassy-hal-internal" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "568659fc53866d3d85c60fa33723fb751aa69e71507634fc2c19e7649432fb75" +dependencies = [ + "cortex-m", + "critical-section", + "defmt 1.1.0", + "num-traits", +] + +[[package]] +name = "embassy-net-driver" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "524eb3c489760508f71360112bca70f6e53173e6fe48fc5f0efd0f5ab217751d" + +[[package]] +name = "embassy-net-driver-channel" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a07d2eb9f05a6fc876500949856ea1be40773d866d8cb99384f72d0ae4568c16" +dependencies = [ + "embassy-futures", + "embassy-net-driver", + "embassy-sync", +] + +[[package]] +name = "embassy-nrf" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "82051f67e8a06a8faebd183f62cfade184c96be68126c5f064abb8223a591ff1" +dependencies = [ + "bitflags 2.13.0", + "cfg-if", + "cortex-m", + "cortex-m-rt", + "critical-section", + "defmt 1.1.0", + "document-features", + "embassy-embedded-hal", + "embassy-futures", + "embassy-hal-internal 0.5.0", + "embassy-sync", + "embassy-time", + "embassy-usb-driver", + "embassy-usb-synopsys-otg", + "embedded-hal 0.2.7", + "embedded-hal 1.0.0", + "embedded-hal-async", + "embedded-io 0.7.1", + "embedded-io-async 0.7.0", + "embedded-storage", + "embedded-storage-async", + "fixed", + "nrf-pac", + "rand_core 0.10.1", + "rand_core 0.6.4", + "rand_core 0.9.5", +] + +[[package]] +name = "embassy-rp" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5d98f472894c1ecffac5596c657af5305c57282d29e8746d7fec033951931bc8" +dependencies = [ + "cfg-if", + "chrono", + "cortex-m", + "cortex-m-rt", + "critical-section", + "defmt 1.1.0", + "document-features", + "embassy-embedded-hal", + "embassy-futures", + "embassy-hal-internal 0.5.0", + "embassy-sync", + "embassy-time", + "embassy-time-driver", + "embassy-time-queue-utils", + "embassy-usb-driver", + "embedded-hal 0.2.7", + "embedded-hal 1.0.0", + "embedded-hal-async", + "embedded-hal-nb", + "embedded-io 0.7.1", + "embedded-io-async 0.7.0", + "embedded-storage", + "embedded-storage-async", + "fixed", + "nb 1.1.0", + "pio", + "rand_core 0.6.4", + "rand_core 0.9.5", + "rp-pac", + "rp2040-boot2", + "sha2-const-stable", + "smart-leds", +] + +[[package]] +name = "embassy-sync" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7bbd85cf5a5ae56bdf26f618364af642d1d0a4e245cdd75cd9aabda382f65a81" +dependencies = [ + "cfg-if", + "critical-section", + "defmt 1.1.0", + "embedded-io-async 0.7.0", + "futures-core", + "futures-sink", + "heapless 0.9.3", +] + +[[package]] +name = "embassy-time" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "592b0c143ec626e821d4d90da51a2bd91d559d6c442b7c74a47d368c9e23d97a" +dependencies = [ + "cfg-if", + "critical-section", + "defmt 1.1.0", + "document-features", + "embassy-time-driver", + "embedded-hal 0.2.7", + "embedded-hal 1.0.0", + "embedded-hal-async", + "futures-core", +] + +[[package]] +name = "embassy-time-driver" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6ee71af1b3a0deaa53eaf2d39252f83504c853646e472400b763060389b9fcc9" +dependencies = [ + "document-features", +] + +[[package]] +name = "embassy-time-queue-utils" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "168297bf80aaf114b3c9ad589bf38b01b3009b9af7f97cd18086c5bbf96f5693" +dependencies = [ + "embassy-executor-timer-queue", + "heapless 0.9.3", +] + +[[package]] +name = "embassy-usb" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a25746d8b152b72fbf2a217f489a083dbbe243f281f09184a1f2cfbe9bbb245f" +dependencies = [ + "bitflags 2.13.0", + "defmt 1.1.0", + "embassy-futures", + "embassy-net-driver-channel", + "embassy-sync", + "embassy-time", + "embassy-usb-driver", + "embedded-io-async 0.7.0", + "heapless 0.9.3", + "ssmarshal", + "usbd-hid", +] + +[[package]] +name = "embassy-usb-dfu" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e36d3678d16e1e71b052d00f7518620b5839a878f2bdab2019b81d984fb2a74f" +dependencies = [ + "bitflags 2.13.0", + "cortex-m", + "embassy-boot", + "embassy-futures", + "embassy-sync", + "embassy-time", + "embassy-usb", + "embedded-storage", +] + +[[package]] +name = "embassy-usb-driver" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fa675c5f4349b6aa0fcffc4bf9b241f18cd11b97c1f8323273fb9a5449937fbd" +dependencies = [ + "defmt 1.1.0", + "embedded-io-async 0.6.1", + "embedded-io-async 0.7.0", +] + +[[package]] +name = "embassy-usb-synopsys-otg" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6efd0c0e0b21bcf91b475b8fa47347c1df32c9a99728ae1e1b0e6625862dfd1a" +dependencies = [ + "critical-section", + "defmt 1.1.0", + "embassy-sync", + "embassy-time", + "embassy-usb-driver", + "portable-atomic", +] + +[[package]] +name = "embedded-hal" +version = "0.2.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "35949884794ad573cf46071e41c9b60efb0cb311e3ca01f7af807af1debc66ff" +dependencies = [ + "nb 0.1.3", + "void", +] + +[[package]] +name = "embedded-hal" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "361a90feb7004eca4019fb28352a9465666b24f840f5c3cddf0ff13920590b89" +dependencies = [ + "defmt 0.3.100", +] + +[[package]] +name = "embedded-hal-async" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0c4c685bbef7fe13c3c6dd4da26841ed3980ef33e841cddfa15ce8a8fb3f1884" +dependencies = [ + "defmt 0.3.100", + "embedded-hal 1.0.0", +] + +[[package]] +name = "embedded-hal-nb" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fba4268c14288c828995299e59b12babdbe170f6c6d73731af1b4648142e8605" +dependencies = [ + "embedded-hal 1.0.0", + "nb 1.1.0", +] + +[[package]] +name = "embedded-io" +version = "0.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "edd0f118536f44f5ccd48bcb8b111bdc3de888b58c74639dfb034a357d0f206d" + +[[package]] +name = "embedded-io" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9eb1aa714776b75c7e67e1da744b81a129b3ff919c8712b5e1b32252c1f07cc7" +dependencies = [ + "defmt 1.1.0", +] + +[[package]] +name = "embedded-io-async" +version = "0.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3ff09972d4073aa8c299395be75161d582e7629cd663171d62af73c8d50dba3f" +dependencies = [ + "embedded-io 0.6.1", +] + +[[package]] +name = "embedded-io-async" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2564b9f813c544241430e147d8bc454815ef9ac998878d30cc3055449f7fd4c0" +dependencies = [ + "defmt 1.1.0", + "embedded-io 0.7.1", +] + +[[package]] +name = "embedded-storage" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a21dea9854beb860f3062d10228ce9b976da520a73474aed3171ec276bc0c032" + +[[package]] +name = "embedded-storage-async" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1763775e2323b7d5f0aa6090657f5e21cfa02ede71f5dc40eead06d64dcd15cc" +dependencies = [ + "embedded-storage", +] + +[[package]] +name = "ena" +version = "0.14.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eabffdaee24bd1bf95c5ef7cec31260444317e72ea56c4c91750e8b7ee58d5f1" +dependencies = [ + "log", +] + +[[package]] +name = "encode_unicode" +version = "0.3.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a357d28ed41a50f9c765dbfe56cbc04a64e53e5fc58ba79fbc34c10ef3df831f" + +[[package]] +name = "encoding_rs" +version = "0.8.35" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "75030f3c4f45dafd7586dd6780965a8c7e8e285a5ecb86713e63a79c5b2766f3" +dependencies = [ + "cfg-if", +] + +[[package]] +name = "equivalent" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "877a4ace8713b0bcf2a4e7eec82529c029f1d0619886d18145fea96c3ffe5c0f" + +[[package]] +name = "erased-serde" +version = "0.4.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d2add8a07dd6a8d93ff627029c51de145e12686fbc36ecb298ac22e74cf02dec" +dependencies = [ + "serde", + "serde_core", + "typeid", +] + +[[package]] +name = "ff" +version = "0.13.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c0b50bfb653653f9ca9095b427bed08ab8d75a137839d9ad64eb11810d5b6393" +dependencies = [ + "rand_core 0.6.4", + "subtle", +] + +[[package]] +name = "find-msvc-tools" +version = "0.1.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5baebc0774151f905a1a2cc41989300b1e6fbb29aff0ceffa1064fdd3088d582" + +[[package]] +name = "fixed" +version = "1.31.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9af2cbf772fa6d1c11358f92ef554cb6b386201210bcf0e91fb7fba8a907fb40" +dependencies = [ + "az", + "bytemuck", + "half", + "typenum", +] + +[[package]] +name = "fixedbitset" +version = "0.5.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1d674e81391d1e1ab681a28d99df07927c6d4aa5b027d7da16ba32d1d21ecd99" + +[[package]] +name = "fnv" +version = "1.0.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" + +[[package]] +name = "foldhash" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "77ce24cb58228fbb8aa041425bb1050850ac19177686ea6e0f41a70416f56fdb" + +[[package]] +name = "futures" +version = "0.3.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8b147ee9d1f6d097cef9ce628cd2ee62288d963e16fb287bd9286455b241382d" +dependencies = [ + "futures-channel", + "futures-core", + "futures-io", + "futures-sink", + "futures-task", + "futures-util", +] + +[[package]] +name = "futures-channel" +version = "0.3.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "07bbe89c50d7a535e539b8c17bc0b49bdb77747034daa8087407d655f3f7cc1d" +dependencies = [ + "futures-core", + "futures-sink", +] + +[[package]] +name = "futures-core" +version = "0.3.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7e3450815272ef58cec6d564423f6e755e25379b217b0bc688e295ba24df6b1d" + +[[package]] +name = "futures-intrusive" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1d930c203dd0b6ff06e0201a4a2fe9149b43c684fd4420555b26d21b1a02956f" +dependencies = [ + "futures-core", + "lock_api", +] + +[[package]] +name = "futures-io" +version = "0.3.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cecba35d7ad927e23624b22ad55235f2239cfa44fd10428eecbeba6d6a717718" + +[[package]] +name = "futures-macro" +version = "0.3.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e835b70203e41293343137df5c0664546da5745f82ec9b84d40be8336958447b" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.118", +] + +[[package]] +name = "futures-sink" +version = "0.3.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c39754e157331b013978ec91992bde1ac089843443c49cbc7f46150b0fad0893" + +[[package]] +name = "futures-task" +version = "0.3.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "037711b3d59c33004d3856fbdc83b99d4ff37a24768fa1be9ce3538a1cde4393" + +[[package]] +name = "futures-util" +version = "0.3.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "389ca41296e6190b48053de0321d02a77f32f8a5d2461dd38762c0593805c6d6" +dependencies = [ + "futures-core", + "futures-macro", + "futures-sink", + "futures-task", + "pin-project-lite", + "slab", +] + +[[package]] +name = "generator" +version = "0.8.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b3b854b0e584ead1a33f18b2fcad7cf7be18b3875c78816b753639aa501513ae" +dependencies = [ + "cc", + "cfg-if", + "libc", + "log", + "rustversion", + "windows-link", + "windows-result", +] + +[[package]] +name = "generic-array" +version = "0.14.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "85649ca51fd72272d7821adaf274ad91c288277713d9c18820d8499a7ff69e9a" +dependencies = [ + "typenum", + "version_check", + "zeroize", +] + +[[package]] +name = "getrandom" +version = "0.2.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ff2abc00be7fca6ebc474524697ae276ad847ad0a6b3faa4bcb027e9a4614ad0" +dependencies = [ + "cfg-if", + "libc", + "wasi", +] + +[[package]] +name = "group" +version = "0.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f0f9ef7462f7c099f518d754361858f86d8a07af53ba9af0fe635bbccb151a63" +dependencies = [ + "ff", + "rand_core 0.6.4", + "subtle", +] + +[[package]] +name = "half" +version = "2.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6ea2d84b969582b4b1864a92dc5d27cd2b77b622a8d79306834f1be5ba20d84b" +dependencies = [ + "cfg-if", + "crunchy", + "zerocopy", +] + +[[package]] +name = "hash32" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b0c35f58762feb77d74ebe43bdbc3210f09be9fe6742234d573bacc26ed92b67" +dependencies = [ + "byteorder", +] + +[[package]] +name = "hash32" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "47d60b12902ba28e2730cd37e95b8c9223af2808df9e902d4df49588d1470606" +dependencies = [ + "byteorder", +] + +[[package]] +name = "hashbrown" +version = "0.13.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "43a3c133739dddd0d2990f9a4bdf8eb4b21ef50e4851ca85ab661199821d510e" +dependencies = [ + "ahash", +] + +[[package]] +name = "hashbrown" +version = "0.14.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e5274423e17b7c9fc20b6e7e208532f9b19825d82dfd615708b70edd83df41f1" + +[[package]] +name = "hashbrown" +version = "0.16.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "841d1cc9bed7f9236f321df977030373f4a4163ae1a7dbfe1a51a2c1a51d9100" +dependencies = [ + "foldhash", +] + +[[package]] +name = "hashbrown" +version = "0.17.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ed5909b6e89a2db4456e54cd5f673791d7eca6732202bbf2a9cc504fe2f9b84a" + +[[package]] +name = "hashlink" +version = "0.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "824e001ac4f3012dd16a264bec811403a67ca9deb6c102fc5049b32c4574b35f" +dependencies = [ + "hashbrown 0.16.1", +] + +[[package]] +name = "heapless" +version = "0.7.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cdc6457c0eb62c71aac4bc17216026d8410337c4126773b9c5daba343f17964f" +dependencies = [ + "atomic-polyfill", + "hash32 0.2.1", + "rustc_version 0.4.1", + "serde", + "spin", + "stable_deref_trait", +] + +[[package]] +name = "heapless" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0bfb9eb618601c89945a70e254898da93b13be0388091d42117462b265bb3fad" +dependencies = [ + "hash32 0.3.1", + "stable_deref_trait", +] + +[[package]] +name = "heapless" +version = "0.9.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "25ba4bd83f9415b58b4ed8dc5714c76e626a105be4646c02630ad730ad3b5aa4" +dependencies = [ + "defmt 1.1.0", + "hash32 0.3.1", + "serde_core", + "stable_deref_trait", +] + +[[package]] +name = "heck" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea" + +[[package]] +name = "hkdf" +version = "0.12.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7b5f8eb2ad728638ea2c7d47a21db23b7b58a72ed6a38256b8a1849f15fbbdf7" +dependencies = [ + "hmac", +] + +[[package]] +name = "hmac" +version = "0.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6c49c37c09c17a53d937dfbb742eb3a961d65a994e6bcdcf37e7399d0cc8ab5e" +dependencies = [ + "digest", +] + +[[package]] +name = "ident_case" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b9e0384b61958566e926dc50660321d12159025e767c18e043daf26b70104c39" + +[[package]] +name = "indexmap" +version = "2.14.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d466e9454f08e4a911e14806c24e16fba1b4c121d1ea474396f396069cf949d9" +dependencies = [ + "equivalent", + "hashbrown 0.17.1", +] + +[[package]] +name = "inout" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "879f10e63c20629ecabbb64a8010319738c66a5cd0c29b02d63d272b03751d01" +dependencies = [ + "generic-array", +] + +[[package]] +name = "itertools" +version = "0.14.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2b192c782037fadd9cfa75548310488aabdbf3d2da73885b31bd0abd03351285" +dependencies = [ + "either", +] + +[[package]] +name = "itoa" +version = "1.0.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f42a60cbdf9a97f5d2305f08a87dc4e09308d1276d28c869c684d7777685682" + +[[package]] +name = "js-sys" +version = "0.3.103" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "53b44bfcdb3f8d5837a46dae1ca9660a837176eee74a28b229bc626816589102" +dependencies = [ + "cfg-if", + "futures-util", + "wasm-bindgen", +] + +[[package]] +name = "json" +version = "0.12.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "078e285eafdfb6c4b434e0d31e8cfcb5115b651496faca5749b88fafd4f23bfd" + +[[package]] +name = "json5" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "96b0db21af676c1ce64250b5f40f3ce2cf27e4e47cb91ed91eb6fe9350b430c1" +dependencies = [ + "pest", + "pest_derive", + "serde", +] + +[[package]] +name = "keccak" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cb26cec98cce3a3d96cbb7bced3c4b16e3d13f27ec56dbd62cbc8f39cfb9d653" +dependencies = [ + "cpufeatures", +] + +[[package]] +name = "lalrpop" +version = "0.22.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ba4ebbd48ce411c1d10fb35185f5a51a7bfa3d8b24b4e330d30c9e3a34129501" +dependencies = [ + "ascii-canvas", + "bit-set", + "ena", + "itertools", + "lalrpop-util", + "petgraph", + "pico-args", + "regex", + "regex-syntax", + "sha3", + "string_cache", + "term", + "unicode-xid", + "walkdir", +] + +[[package]] +name = "lalrpop-util" +version = "0.22.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b5baa5e9ff84f1aefd264e6869907646538a52147a755d494517a8007fb48733" +dependencies = [ + "regex-automata", + "rustversion", +] + +[[package]] +name = "lazy_static" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe" + +[[package]] +name = "libc" +version = "0.2.186" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "68ab91017fe16c622486840e4c83c9a37afeff978bd239b5293d61ece587de66" + +[[package]] +name = "litrs" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "11d3d7f243d5c5a8b9bb5d6dd2b1602c0cb0b9db1621bafc7ed66e35ff9fe092" + +[[package]] +name = "lock_api" +version = "0.4.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "224399e74b87b5f3557511d98dff8b14089b3dadafcab6bb93eab67d3aace965" +dependencies = [ + "scopeguard", +] + +[[package]] +name = "log" +version = "0.4.33" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0ceec5bc11778974d1bcb055b18002eba7f4b3518b6a0081b3af5f21666da9ad" + +[[package]] +name = "loom" +version = "0.7.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "419e0dc8046cb947daa77eb95ae174acfbddb7673b4151f56d1eed8e93fbfaca" +dependencies = [ + "cfg-if", + "generator", + "scoped-tls", + "tracing", + "tracing-subscriber", +] + +[[package]] +name = "lzma-sys" +version = "0.1.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5fda04ab3764e6cde78b9974eec4f779acaba7c4e84b36eca3cf77c581b85d27" +dependencies = [ + "cc", + "libc", + "pkg-config", +] + +[[package]] +name = "matchers" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d1525a2a28c7f4fa0fc98bb91ae755d1e2d1505079e05539e35bc876b5d65ae9" +dependencies = [ + "regex-automata", +] + +[[package]] +name = "memchr" +version = "2.8.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "88904434abc2901f197fe8cc55f0445e7ded921dba5911dad2e2b39b48e663c4" + +[[package]] +name = "nb" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "801d31da0513b6ec5214e9bf433a77966320625a37860f910be265be6e18d06f" +dependencies = [ + "nb 1.1.0", +] + +[[package]] +name = "nb" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8d5439c4ad607c3c23abf66de8c8bf57ba8adcd1f129e699851a6e43935d339d" + +[[package]] +name = "new_debug_unreachable" +version = "1.0.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "650eef8c711430f1a879fdd01d4745a7deea475becfb90269c06775983bbf086" + +[[package]] +name = "nrf-pac" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "83531b9f1e19f493018da9b8b20359e4cedd6d1357553b1ac50f3fa27a0104fa" +dependencies = [ + "cortex-m", + "cortex-m-rt", +] + +[[package]] +name = "nu-ansi-term" +version = "0.50.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7957b9740744892f114936ab4a57b3f487491bbeafaf8083688b16841a4240e5" +dependencies = [ + "windows-sys", +] + +[[package]] +name = "num-traits" +version = "0.2.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841" +dependencies = [ + "autocfg", +] + +[[package]] +name = "num_enum" +version = "0.7.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5d0bca838442ec211fa11de3a8b0e0e8f3a4522575b5c4c06ed722e005036f26" +dependencies = [ + "num_enum_derive", + "rustversion", +] + +[[package]] +name = "num_enum_derive" +version = "0.7.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "680998035259dcfcafe653688bf2aa6d3e2dc05e98be6ab46afb089dc84f1df8" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.118", +] + +[[package]] +name = "once_cell" +version = "1.21.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9f7c3e4beb33f85d45ae3e3a1792185706c8e16d043238c593331cc7cd313b50" + +[[package]] +name = "ordered-multimap" +version = "0.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "49203cdcae0030493bad186b28da2fa25645fa276a51b6fec8010d281e02ef79" +dependencies = [ + "dlv-list", + "hashbrown 0.14.5", +] + +[[package]] +name = "p256" +version = "0.13.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c9863ad85fa8f4460f9c48cb909d38a0d689dba1f6f6988a5e3e0d31071bcd4b" +dependencies = [ + "elliptic-curve", + "primeorder", +] + +[[package]] +name = "panic-probe" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fd402d00b0fb94c5aee000029204a46884b1262e0c443f166d86d2c0747e1a1a" +dependencies = [ + "cortex-m", + "defmt 1.1.0", +] + +[[package]] +name = "parking_lot" +version = "0.12.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "93857453250e3077bd71ff98b6a65ea6621a19bb0f559a85248955ac12c45a1a" +dependencies = [ + "lock_api", + "parking_lot_core", +] + +[[package]] +name = "parking_lot_core" +version = "0.9.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2621685985a2ebf1c516881c026032ac7deafcda1a2c9b7850dc81e3dfcb64c1" +dependencies = [ + "cfg-if", + "libc", + "redox_syscall", + "smallvec", + "windows-link", +] + +[[package]] +name = "paste" +version = "1.0.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "57c0d7b74b563b49d38dae00a0c37d4d6de9b432382b2892f0574ddcae73fd0a" + +[[package]] +name = "pathdiff" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "df94ce210e5bc13cb6651479fa48d14f601d9858cfe0467f43ae157023b938d3" + +[[package]] +name = "pest" +version = "2.8.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e0848c601009d37dfa3430c4666e147e49cdcf1b92ecd3e63657d8a5f19da662" +dependencies = [ + "memchr", + "ucd-trie", +] + +[[package]] +name = "pest_derive" +version = "2.8.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "11f486f1ea21e6c10ed15d5a7c77165d0ee443402f0780849d1768e7d9d6fe77" +dependencies = [ + "pest", + "pest_generator", +] + +[[package]] +name = "pest_generator" +version = "2.8.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8040c4647b13b210a963c1ed407c1ff4fdfa01c31d6d2a098218702e6664f94f" +dependencies = [ + "pest", + "pest_meta", + "proc-macro2", + "quote", + "syn 2.0.118", +] + +[[package]] +name = "pest_meta" +version = "2.8.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "89815c69d36021a140146f26659a81d6c2afa33d216d736dd4be5381a7362220" +dependencies = [ + "pest", + "sha2", +] + +[[package]] +name = "petgraph" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3672b37090dbd86368a4145bc067582552b29c27377cad4e0a306c97f9bd7772" +dependencies = [ + "fixedbitset", + "indexmap", +] + +[[package]] +name = "phf_shared" +version = "0.11.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "67eabc2ef2a60eb7faa00097bd1ffdb5bd28e62bf39990626a582201b7a754e5" +dependencies = [ + "siphasher", +] + +[[package]] +name = "pico-args" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5be167a7af36ee22fe3115051bc51f6e6c7054c9348e28deb4f49bd6f705a315" + +[[package]] +name = "pin-project-lite" +version = "0.2.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a89322df9ebe1c1578d689c92318e070967d1042b512afbe49518723f4e6d5cd" + +[[package]] +name = "pio" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d0ba4153cee9585abc451271aa437d9e8defdea8b468d48ba6b8f098cbe03d7f" +dependencies = [ + "pio-core", + "pio-proc", +] + +[[package]] +name = "pio-core" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "61d90fddc3d67f21bbf93683bc461b05d6a29c708caf3ffb79947d7ff7095406" +dependencies = [ + "arrayvec", + "num_enum", + "paste", +] + +[[package]] +name = "pio-parser" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "825266c1eaddf54f636d06eefa4bf3c99d774c14ec46a4a6c6e5128a0f10d205" +dependencies = [ + "lalrpop", + "lalrpop-util", + "pio-core", +] + +[[package]] +name = "pio-proc" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ed4a76571f5fe51af43cc80ac870fe0c79cc0cdd686b9002a6c4c84bfdd0176b" +dependencies = [ + "codespan-reporting", + "lalrpop-util", + "pio-core", + "pio-parser", + "proc-macro-error2", + "proc-macro2", + "quote", + "syn 2.0.118", +] + +[[package]] +name = "pkg-config" +version = "0.3.33" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "19f132c84eca552bf34cab8ec81f1c1dcc229b811638f9d283dceabe58c5569e" + +[[package]] +name = "portable-atomic" +version = "1.13.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c33a9471896f1c69cecef8d20cbe2f7accd12527ce60845ff44c153bb2a21b49" +dependencies = [ + "critical-section", +] + +[[package]] +name = "postcard" +version = "1.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6764c3b5dd454e283a30e6dfe78e9b31096d9e32036b5d1eaac7a6119ccb9a24" +dependencies = [ + "cobs", + "defmt 1.1.0", + "heapless 0.7.17", + "postcard-derive", + "serde", +] + +[[package]] +name = "postcard-derive" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e0232bd009a197ceec9cc881ba46f727fcd8060a2d8d6a9dde7a69030a6fe2bb" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.118", +] + +[[package]] +name = "ppv-lite86" +version = "0.2.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "85eae3c4ed2f50dcfe72643da4befc30deadb458a9b590d720cde2f2b1e97da9" +dependencies = [ + "zerocopy", +] + +[[package]] +name = "precomputed-hash" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "925383efa346730478fb4838dbe9137d2a47675ad789c546d150a6e1dd4ab31c" + +[[package]] +name = "primeorder" +version = "0.13.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "353e1ca18966c16d9deb1c69278edbc5f194139612772bd9537af60ac231e1e6" +dependencies = [ + "elliptic-curve", +] + +[[package]] +name = "proc-macro-error-attr2" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "96de42df36bb9bba5542fe9f1a054b8cc87e172759a1868aa05c1f3acc89dfc5" +dependencies = [ + "proc-macro2", + "quote", +] + +[[package]] +name = "proc-macro-error2" +version = "2.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "11ec05c52be0a07b08061f7dd003e7d7092e0472bc731b4af7bb1ef876109802" +dependencies = [ + "proc-macro-error-attr2", + "proc-macro2", + "quote", + "syn 2.0.118", +] + +[[package]] +name = "proc-macro2" +version = "1.0.106" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8fd00f0bb2e90d81d1044c2b32617f68fcb9fa3bb7640c23e9c748e53fb30934" +dependencies = [ + "unicode-ident", +] + +[[package]] +name = "pure-rust-locales" +version = "0.8.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "869675ad2d7541aea90c6d88c81f46a7f4ea9af8cd0395d38f11a95126998a0d" +dependencies = [ + "defmt 1.1.0", +] + +[[package]] +name = "quote" +version = "1.0.46" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dfbc457d0c7a0759a614551b11a6409e5951f6c7537be1f1b7682b9ae9230368" +dependencies = [ + "proc-macro2", +] + +[[package]] +name = "rand" +version = "0.8.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5ca0ecfa931c29007047d1bc58e623ab12e5590e8c7cc53200d5202b69266d8a" +dependencies = [ + "rand_core 0.6.4", +] + +[[package]] +name = "rand_chacha" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88" +dependencies = [ + "ppv-lite86", + "rand_core 0.6.4", +] + +[[package]] +name = "rand_core" +version = "0.6.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" + +[[package]] +name = "rand_core" +version = "0.9.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "76afc826de14238e6e8c374ddcc1fa19e374fd8dd986b0d2af0d02377261d83c" + +[[package]] +name = "rand_core" +version = "0.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "63b8176103e19a2643978565ca18b50549f6101881c443590420e4dc998a3c69" + +[[package]] +name = "redox_syscall" +version = "0.5.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ed2bf2547551a7053d6fdfafda3f938979645c44812fbfcda098faae3f1a362d" +dependencies = [ + "bitflags 2.13.0", +] + +[[package]] +name = "regex" +version = "1.12.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f1292b7759ae1cb9ec195452d1390a074f0cd8541ab7a5a8c31cd6db45d4a6ba" +dependencies = [ + "aho-corasick", + "memchr", + "regex-automata", + "regex-syntax", +] + +[[package]] +name = "regex-automata" +version = "0.4.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6e1dd4122fc1595e8162618945476892eefca7b88c52820e74af6262213cae8f" +dependencies = [ + "aho-corasick", + "memchr", + "regex-syntax", +] + +[[package]] +name = "regex-syntax" +version = "0.8.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d6f6ff9a378485b298a5286656da665ba74413d36db0979633275d2e708145d4" + +[[package]] +name = "rgb" +version = "0.8.53" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "47b34b781b31e5d73e9fbc8689c70551fd1ade9a19e3e28cfec8580a79290cc4" + +[[package]] +name = "rmk" +version = "0.8.2" +dependencies = [ + "bt-hci", + "byteorder", + "cortex-m", + "crc32fast", + "defmt 1.1.0", + "document-features", + "embassy-boot", + "embassy-boot-rp", + "embassy-embedded-hal", + "embassy-futures", + "embassy-hal-internal 0.5.0", + "embassy-nrf", + "embassy-rp", + "embassy-sync", + "embassy-time", + "embassy-usb", + "embassy-usb-dfu", + "embedded-hal 1.0.0", + "embedded-hal-async", + "embedded-io-async 0.7.0", + "embedded-storage", + "embedded-storage-async", + "fixed", + "futures", + "heapless 0.9.3", + "paste", + "pio", + "postcard", + "rmk-macro", + "rmk-types", + "sequential-storage", + "serde", + "static_cell", + "trouble-host", + "usbd-hid", +] + +[[package]] +name = "rmk-config" +version = "0.6.1" +dependencies = [ + "config", + "once_cell", + "paste", + "pest", + "pest_derive", + "serde", + "serde-inline-default", + "toml", +] + +[[package]] +name = "rmk-macro" +version = "0.7.1" +dependencies = [ + "cargo_toml", + "darling 0.23.0", + "proc-macro2", + "quote", + "rmk-config", + "rmk-types", + "strum", + "syn 2.0.118", +] + +[[package]] +name = "rmk-rp2040-embassy-boot-split" +version = "0.2.0" +dependencies = [ + "const-gen", + "cortex-m-rt", + "defmt 1.1.0", + "defmt-rtt", + "embassy-executor", + "embassy-futures", + "embassy-rp", + "embassy-time", + "json", + "panic-probe", + "portable-atomic", + "rmk", + "static_cell", + "xz2", +] + +[[package]] +name = "rmk-types" +version = "0.2.2" +dependencies = [ + "bitfield-struct", + "defmt 1.1.0", + "heapless 0.9.3", + "postcard", + "rmk-config", + "serde", + "strum", + "toml", +] + +[[package]] +name = "ron" +version = "0.12.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "81116b9531d61eabc41aeb228e4b6b2435bcca3233b98cf3b3077d4e6e9debb3" +dependencies = [ + "bitflags 2.13.0", + "once_cell", + "serde", + "serde_derive", + "typeid", + "unicode-ident", +] + +[[package]] +name = "rp-pac" +version = "7.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8af65855c40b2c35079514c5489abffc0429347fef25d8467ff98ad84b4322d3" +dependencies = [ + "cortex-m", + "cortex-m-rt", +] + +[[package]] +name = "rp2040-boot2" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7c92f344f63f950ee36cf4080050e4dce850839b9175da38f9d2ffb69b4dbb21" +dependencies = [ + "crc-any", +] + +[[package]] +name = "rust-ini" +version = "0.21.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "796e8d2b6696392a43bea58116b667fb4c29727dc5abd27d6acf338bb4f688c7" +dependencies = [ + "cfg-if", + "ordered-multimap", +] + +[[package]] +name = "rustc_version" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "138e3e0acb6c9fb258b19b67cb8abd63c00679d2851805ea151465464fe9030a" +dependencies = [ + "semver 0.9.0", +] + +[[package]] +name = "rustc_version" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cfcb3a22ef46e85b45de6ee7e79d063319ebb6594faafcf1c225ea92ab6e9b92" +dependencies = [ + "semver 1.0.28", +] + +[[package]] +name = "rustversion" +version = "1.0.22" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b39cdef0fa800fc44525c84ccb54a029961a8215f9619753635a9c0d2538d46d" + +[[package]] +name = "same-file" +version = "1.0.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "93fc1dc3aaa9bfed95e02e6eadabb4baf7e3078b0bd1b4d7b6b0b68378900502" +dependencies = [ + "winapi-util", +] + +[[package]] +name = "scoped-tls" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e1cf6437eb19a8f4a6cc0f7dca544973b0b78843adbfeb3683d1a94a0024a294" + +[[package]] +name = "scopeguard" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" + +[[package]] +name = "sec1" +version = "0.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d3e97a565f76233a6003f9f5c54be1d9c5bdfa3eccfb189469f11ec4901c47dc" +dependencies = [ + "base16ct", + "der", + "generic-array", + "subtle", + "zeroize", +] + +[[package]] +name = "semver" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1d7eb9ef2c18661902cc47e535f9bc51b78acd254da71d375c2f6720d9a40403" +dependencies = [ + "semver-parser", +] + +[[package]] +name = "semver" +version = "1.0.28" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8a7852d02fc848982e0c167ef163aaff9cd91dc640ba85e263cb1ce46fae51cd" +dependencies = [ + "serde", + "serde_core", +] + +[[package]] +name = "semver-parser" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "388a1df253eca08550bef6c72392cfe7c30914bf41df5269b68cbd6ff8f570a3" + +[[package]] +name = "sequential-storage" +version = "7.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "574e5a379bf43653079b34cb4cf32958404b5f42e0ed5b5adcdff02c2de04d4d" +dependencies = [ + "defmt 1.1.0", + "embedded-storage-async", + "postcard", + "serde", +] + +[[package]] +name = "serde" +version = "1.0.228" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9a8e94ea7f378bd32cbbd37198a4a91436180c5bb472411e48b5ec2e2124ae9e" +dependencies = [ + "serde_core", + "serde_derive", +] + +[[package]] +name = "serde-inline-default" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2bf03b7a5281cfd4013bc788d057b0f09fc634397d83bc8973c955bd4f32727a" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.118", +] + +[[package]] +name = "serde-untagged" +version = "0.1.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f9faf48a4a2d2693be24c6289dbe26552776eb7737074e6722891fadbe6c5058" +dependencies = [ + "erased-serde", + "serde", + "serde_core", + "typeid", +] + +[[package]] +name = "serde_core" +version = "1.0.228" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "41d385c7d4ca58e59fc732af25c3983b67ac852c1a25000afe1175de458b67ad" +dependencies = [ + "serde_derive", +] + +[[package]] +name = "serde_derive" +version = "1.0.228" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d540f220d3187173da220f885ab66608367b6574e925011a9353e4badda91d79" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.118", +] + +[[package]] +name = "serde_json" +version = "1.0.150" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e8014e44b4736ed0538adeecded0fce2a272f22dc9578a7eb6b2d9993c74cfb9" +dependencies = [ + "itoa", + "memchr", + "serde", + "serde_core", + "zmij", +] + +[[package]] +name = "serde_spanned" +version = "1.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6662b5879511e06e8999a8a235d848113e942c9124f211511b16466ee2995f26" +dependencies = [ + "serde_core", +] + +[[package]] +name = "sha2" +version = "0.10.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a7507d819769d01a365ab707794a4084392c824f54a7a6a7862f8c3d0892b283" +dependencies = [ + "cfg-if", + "cpufeatures", + "digest", +] + +[[package]] +name = "sha2-const-stable" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5f179d4e11094a893b82fff208f74d448a7512f99f5a0acbd5c679b705f83ed9" + +[[package]] +name = "sha3" +version = "0.10.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "77fd7028345d415a4034cf8777cd4f8ab1851274233b45f84e3d955502d93874" +dependencies = [ + "digest", + "keccak", +] + +[[package]] +name = "sharded-slab" +version = "0.1.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f40ca3c46823713e0d4209592e8d6e826aa57e928f09752619fc696c499637f6" +dependencies = [ + "lazy_static", +] + +[[package]] +name = "shlex" +version = "2.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f8fadd59c855ef2080decdef8ff161eb6661b86933c9d82e5ba29dc602a55aba" + +[[package]] +name = "signature" +version = "2.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "77549399552de45a898a580c1b41d445bf730df867cc44e6c0233bbc4b8329de" + +[[package]] +name = "siphasher" +version = "1.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8ee5873ec9cce0195efcb7a4e9507a04cd49aec9c83d0389df45b1ef7ba2e649" + +[[package]] +name = "slab" +version = "0.4.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0c790de23124f9ab44544d7ac05d60440adc586479ce501c1d6d7da3cd8c9cf5" + +[[package]] +name = "smallvec" +version = "1.15.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8ed6a63f02c8539c91a8685a86f4099661ba3da017932f6ebbea6de3f0fa7c90" + +[[package]] +name = "smart-leds" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "66df34e571fa9993fa6f99131a374d58ca3d694b75f9baac93458fe0d6057bf0" +dependencies = [ + "smart-leds-trait", +] + +[[package]] +name = "smart-leds-trait" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a7f4441a131924d58da6b83a7ad765c460e64630cce504376c3a87a2558c487f" +dependencies = [ + "rgb", +] + +[[package]] +name = "spin" +version = "0.9.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6980e8d7511241f8acf4aebddbb1ff938df5eebe98691418c4468d0b72a96a67" +dependencies = [ + "lock_api", +] + +[[package]] +name = "ssmarshal" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f3e6ad23b128192ed337dfa4f1b8099ced0c2bf30d61e551b65fda5916dbb850" +dependencies = [ + "encode_unicode", + "serde", +] + +[[package]] +name = "stable_deref_trait" +version = "1.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6ce2be8dc25455e1f91df71bfa12ad37d7af1092ae736f3a6cd0e37bc7810596" + +[[package]] +name = "static_cell" +version = "2.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0530892bb4fa575ee0da4b86f86c667132a94b74bb72160f58ee5a4afec74c23" +dependencies = [ + "portable-atomic", +] + +[[package]] +name = "string_cache" +version = "0.8.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bf776ba3fa74f83bf4b63c3dcbbf82173db2632ed8452cb2d891d33f459de70f" +dependencies = [ + "new_debug_unreachable", + "parking_lot", + "phf_shared", + "precomputed-hash", +] + +[[package]] +name = "strsim" +version = "0.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f" + +[[package]] +name = "strum" +version = "0.28.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9628de9b8791db39ceda2b119bbe13134770b56c138ec1d3af810d045c04f9bd" +dependencies = [ + "strum_macros", +] + +[[package]] +name = "strum_macros" +version = "0.28.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ab85eea0270ee17587ed4156089e10b9e6880ee688791d45a905f5b1ca36f664" +dependencies = [ + "heck", + "proc-macro2", + "quote", + "syn 2.0.118", +] + +[[package]] +name = "subtle" +version = "2.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "13c2bddecc57b384dee18652358fb23172facb8a2c51ccc10d74c157bdea3292" + +[[package]] +name = "syn" +version = "1.0.109" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[package]] +name = "syn" +version = "2.0.118" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1b9ae57f904213ebb649ce6895b8a66c66f0203b9319718f69a5612a065b1422" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[package]] +name = "term" +version = "1.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d8c27177b12a6399ffc08b98f76f7c9a1f4fe9fc967c784c5a071fa8d93cf7e1" +dependencies = [ + "windows-sys", +] + +[[package]] +name = "termcolor" +version = "1.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "06794f8f6c5c898b3275aebefa6b8a1cb24cd2c6c79397ab15774837a0bc5755" +dependencies = [ + "winapi-util", +] + +[[package]] +name = "thiserror" +version = "2.0.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4288b5bcbc7920c07a1149a35cf9590a2aa808e0bc1eafaade0b80947865fbc4" +dependencies = [ + "thiserror-impl", +] + +[[package]] +name = "thiserror-impl" +version = "2.0.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ebc4ee7f67670e9b64d05fa4253e753e016c6c95ff35b89b7941d6b856dec1d5" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.118", +] + +[[package]] +name = "thread_local" +version = "1.1.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f60246a4944f24f6e018aa17cdeffb7818b76356965d03b07d6a9886e8962185" +dependencies = [ + "cfg-if", +] + +[[package]] +name = "tiny-keccak" +version = "2.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2c9d3793400a45f954c52e73d068316d76b6f4e36977e3fcebb13a2721e80237" +dependencies = [ + "crunchy", +] + +[[package]] +name = "toml" +version = "1.1.2+spec-1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "81f3d15e84cbcd896376e6730314d59fb5a87f31e4b038454184435cd57defee" +dependencies = [ + "indexmap", + "serde_core", + "serde_spanned", + "toml_datetime", + "toml_parser", + "toml_writer", + "winnow", +] + +[[package]] +name = "toml_datetime" +version = "1.1.1+spec-1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3165f65f62e28e0115a00b2ebdd37eb6f3b641855f9d636d3cd4103767159ad7" +dependencies = [ + "serde_core", +] + +[[package]] +name = "toml_parser" +version = "1.1.2+spec-1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a2abe9b86193656635d2411dc43050282ca48aa31c2451210f4202550afb7526" +dependencies = [ + "winnow", +] + +[[package]] +name = "toml_writer" +version = "1.1.1+spec-1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "756daf9b1013ebe47a8776667b466417e2d4c5679d441c26230efd9ef78692db" + +[[package]] +name = "tracing" +version = "0.1.44" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "63e71662fa4b2a2c3a26f570f037eb95bb1f85397f3cd8076caed2f026a6d100" +dependencies = [ + "pin-project-lite", + "tracing-attributes", + "tracing-core", +] + +[[package]] +name = "tracing-attributes" +version = "0.1.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7490cfa5ec963746568740651ac6781f701c9c5ea257c58e057f3ba8cf69e8da" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.118", +] + +[[package]] +name = "tracing-core" +version = "0.1.36" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "db97caf9d906fbde555dd62fa95ddba9eecfd14cb388e4f491a66d74cd5fb79a" +dependencies = [ + "once_cell", + "valuable", +] + +[[package]] +name = "tracing-log" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ee855f1f400bd0e5c02d150ae5de3840039a3f54b025156404e34c23c03f47c3" +dependencies = [ + "log", + "once_cell", + "tracing-core", +] + +[[package]] +name = "tracing-subscriber" +version = "0.3.23" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cb7f578e5945fb242538965c2d0b04418d38ec25c79d160cd279bf0731c8d319" +dependencies = [ + "matchers", + "nu-ansi-term", + "once_cell", + "regex-automata", + "sharded-slab", + "smallvec", + "thread_local", + "tracing", + "tracing-core", + "tracing-log", +] + +[[package]] +name = "trouble-host" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bb9fe2be24000037431b036ba244cdb1d26f40e1719548553fb43c3fc62d496b" +dependencies = [ + "aes", + "bt-hci", + "cmac", + "defmt 1.1.0", + "embassy-futures", + "embassy-sync", + "embassy-time", + "embedded-io 0.7.1", + "futures", + "heapless 0.9.3", + "p256", + "rand", + "rand_chacha", + "rand_core 0.6.4", + "serde", + "static_cell", + "trouble-host-macros", + "zerocopy", +] + +[[package]] +name = "trouble-host-macros" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2562dc74f79ad12f7bf088da55c936d5eb1d022f2caac9849175326307a5eec1" +dependencies = [ + "convert_case 0.8.0", + "darling 0.20.11", + "proc-macro2", + "quote", + "syn 2.0.118", + "uuid", +] + +[[package]] +name = "typeid" +version = "1.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bc7d623258602320d5c55d1bc22793b57daff0ec7efc270ea7d55ce1d5f5471c" + +[[package]] +name = "typenum" +version = "1.20.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b6f5e870be6c3b371b77fe0ee0bafb859fa4964b4404c27de1d380043c4dda20" + +[[package]] +name = "ucd-trie" +version = "0.1.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2896d95c02a80c6d6a5d6e953d479f5ddf2dfdb6a244441010e373ac0fb88971" + +[[package]] +name = "unicode-ident" +version = "1.0.24" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e6e4313cd5fcd3dad5cafa179702e2b244f760991f45397d14d4ebf38247da75" + +[[package]] +name = "unicode-segmentation" +version = "1.13.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c6f5d3c3b1bf09027a88a6bc961fc00497d651009560b5463668dc81b0fa87a8" + +[[package]] +name = "unicode-width" +version = "0.1.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7dd6e30e90baa6f72411720665d41d89b9a3d039dc45b8faea1ddd07f617f6af" + +[[package]] +name = "unicode-xid" +version = "0.2.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ebc1c04c71510c7f702b52b7c350734c9ff1295c464a03335b00bb84fc54f853" + +[[package]] +name = "usb-device" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "98816b1accafbb09085168b90f27e93d790b4bfa19d883466b5e53315b5f06a6" +dependencies = [ + "defmt 0.3.100", + "heapless 0.8.0", + "portable-atomic", +] + +[[package]] +name = "usbd-hid" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "68beab087e4971a2fe76f631478b0e91d39593f58efd2775026ce6dc07a7bac6" +dependencies = [ + "defmt 0.3.100", + "usb-device", + "usbd-hid-macros", +] + +[[package]] +name = "usbd-hid-descriptors" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b297f021719c4308d5d0c61b6c1e7c6b3ba383deba774b49aa5484f996bdb8f1" +dependencies = [ + "bitfield 0.14.0", +] + +[[package]] +name = "usbd-hid-macros" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "011a3219e0933f5b3ad7dc90d9a66541a967d084c98c067deed1cd608e557ed7" +dependencies = [ + "byteorder", + "hashbrown 0.13.2", + "log", + "proc-macro2", + "quote", + "serde", + "syn 2.0.118", + "usbd-hid-descriptors", +] + +[[package]] +name = "uuid" +version = "1.23.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bf80a72845275afea99e7f2b434723d3bc7e38470fcd1c7ed39a599c73319a53" +dependencies = [ + "js-sys", + "wasm-bindgen", +] + +[[package]] +name = "valuable" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ba73ea9cf16a25df0c8caa16c51acb937d5712a8429db78a3ee29d5dcacd3a65" + +[[package]] +name = "vcell" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "77439c1b53d2303b20d9459b1ade71a83c716e3f9c34f3228c00e6f185d6c002" + +[[package]] +name = "version_check" +version = "0.9.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b928f33d975fc6ad9f86c8f283853ad26bdd5b10b7f1542aa2fa15e2289105a" + +[[package]] +name = "void" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6a02e4885ed3bc0f2de90ea6dd45ebcbb66dacffe03547fadbb0eeae2770887d" + +[[package]] +name = "volatile-register" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "de437e2a6208b014ab52972a27e59b33fa2920d3e00fe05026167a1c509d19cc" +dependencies = [ + "vcell", +] + +[[package]] +name = "walkdir" +version = "2.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "29790946404f91d9c5d06f9874efddea1dc06c5efe94541a7d6863108e3a5e4b" +dependencies = [ + "same-file", + "winapi-util", +] + +[[package]] +name = "wasi" +version = "0.11.1+wasi-snapshot-preview1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ccf3ec651a847eb01de73ccad15eb7d99f80485de043efb2f370cd654f4ea44b" + +[[package]] +name = "wasm-bindgen" +version = "0.2.126" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4b067c0c11094aef6b7a801c1e34a26affafdf3d051dba08456b868789aaf9a4" +dependencies = [ + "cfg-if", + "once_cell", + "rustversion", + "wasm-bindgen-macro", + "wasm-bindgen-shared", +] + +[[package]] +name = "wasm-bindgen-macro" +version = "0.2.126" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "167ce5e579f6bcf889c4f7175a8a5a585de84e8ff93976ce393efa5f2837aab1" +dependencies = [ + "quote", + "wasm-bindgen-macro-support", +] + +[[package]] +name = "wasm-bindgen-macro-support" +version = "0.2.126" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f3997c7839262f4ef12cf90b818d6340c18e80f263f1a94bf157d0ec4420380e" +dependencies = [ + "bumpalo", + "proc-macro2", + "quote", + "syn 2.0.118", + "wasm-bindgen-shared", +] + +[[package]] +name = "wasm-bindgen-shared" +version = "0.2.126" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dc1b4cb0cc549fcf58d7dfc081778139b3d283a081644e833e84682ad71cea24" +dependencies = [ + "unicode-ident", +] + +[[package]] +name = "winapi-util" +version = "0.1.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c2a7b1c03c876122aa43f3020e6c3c3ee5c05081c9a00739faf7503aeba10d22" +dependencies = [ + "windows-sys", +] + +[[package]] +name = "windows-link" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f0805222e57f7521d6a62e36fa9163bc891acd422f971defe97d64e70d0a4fe5" + +[[package]] +name = "windows-result" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7781fa89eaf60850ac3d2da7af8e5242a5ea78d1a11c49bf2910bb5a73853eb5" +dependencies = [ + "windows-link", +] + +[[package]] +name = "windows-sys" +version = "0.61.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ae137229bcbd6cdf0f7b80a31df61766145077ddf49416a728b02cb3921ff3fc" +dependencies = [ + "windows-link", +] + +[[package]] +name = "winnow" +version = "1.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0592e1c9d151f854e6fd382574c3a0855250e1d9b2f99d9281c6e6391af352f1" +dependencies = [ + "memchr", +] + +[[package]] +name = "xz2" +version = "0.1.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "388c44dc09d76f1536602ead6d325eb532f5c122f17782bd57fb47baeeb767e2" +dependencies = [ + "lzma-sys", +] + +[[package]] +name = "yaml-rust2" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "631a50d867fafb7093e709d75aaee9e0e0d5deb934021fcea25ac2fe09edc51e" +dependencies = [ + "arraydeque", + "encoding_rs", + "hashlink", +] + +[[package]] +name = "zerocopy" +version = "0.8.52" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ce1022995ff5ff5d841ad7d994facc23098cd40152f2c1d11cd607c6f530653f" +dependencies = [ + "zerocopy-derive", +] + +[[package]] +name = "zerocopy-derive" +version = "0.8.52" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1ae7f38b72ec2a254e2b87ef277cf2cd4fb97cbebf944faa6f33354da0867930" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.118", +] + +[[package]] +name = "zeroize" +version = "1.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e13c156562582aa81c60cb29407084cdb54c4164760106ab78e6c5b0858cf64e" + +[[package]] +name = "zmij" +version = "1.0.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b8848ee67ecc8aedbaf3e4122217aff892639231befc6a1b58d29fff4c2cabaa" diff --git a/examples/use_rust/rp2040_embassy_boot_split/Cargo.toml b/examples/use_rust/rp2040_embassy_boot_split/Cargo.toml new file mode 100644 index 000000000..2ffdf059f --- /dev/null +++ b/examples/use_rust/rp2040_embassy_boot_split/Cargo.toml @@ -0,0 +1,64 @@ +[package] +name = "rmk-rp2040-embassy-boot-split" +version = "0.2.0" +authors = ["Haobo Gu "] +description = "RMK split keyboard with embassy-boot DFU on both sides" +homepage = "https://github.com/haobogu/rmk" +repository = "https://github.com/haobogu/rmk" +readme = "../../README.md" +edition = "2024" +license = "MIT OR Apache-2.0" + +[dependencies] +rmk = { path = "../../../rmk", features = [ + "dfu_rp", + "split", + "storage", +] } +embassy-time = { version = "0.5", features = ["defmt"] } +embassy-rp = { version = "0.10", features = [ + "rp2040", + "defmt", + "time-driver", + "critical-section-impl", +] } +embassy-executor = { version = "0.10", features = [ + "defmt", + "platform-cortex-m", + "executor-thread", +] } +embassy-futures = { version = "0.1", features = ["defmt"] } +cortex-m-rt = { version = "0.7.5", features = ["set-vtor"] } # <-- set-vtor necessary for embassy-boot +portable-atomic = { version = "1.11", features = ["critical-section"] } +defmt = "1.0" +defmt-rtt = "1.0" +panic-probe = { version = "1.0", features = ["print-defmt"] } +static_cell = "2" + +[build-dependencies] +xz2 = "0.1.7" +json = "0.12" +const-gen = "1.6" + +[[bin]] +name = "central" +path = "src/central.rs" + +[[bin]] +name = "peripheral" +path = "src/peripheral.rs" + +[profile.dev] +codegen-units = 1 +debug = true +opt-level = 1 +overflow-checks = true +lto = false +panic = 'unwind' + +[profile.release] +codegen-units = 1 +debug = true +opt-level = "z" +overflow-checks = false +lto = "fat" diff --git a/examples/use_rust/rp2040_embassy_boot_split/build.rs b/examples/use_rust/rp2040_embassy_boot_split/build.rs new file mode 100644 index 000000000..3da977141 --- /dev/null +++ b/examples/use_rust/rp2040_embassy_boot_split/build.rs @@ -0,0 +1,48 @@ +use std::fs::File; +use std::io::{Read, Write}; +use std::path::{Path, PathBuf}; +use std::{env, fs}; + +use const_gen::*; +use xz2::read::XzEncoder; + +fn main() { + println!("cargo:rerun-if-changed=vial.json"); + generate_vial_config(); + + let out = &PathBuf::from(env::var_os("OUT_DIR").unwrap()); + File::create(out.join("memory.x")) + .unwrap() + .write_all(include_bytes!("memory.x")) + .unwrap(); + println!("cargo:rustc-link-search={}", out.display()); + println!("cargo:rerun-if-changed=memory.x"); + println!("cargo:rustc-link-arg=--nmagic"); + println!("cargo:rustc-link-arg=-Tlink.x"); + println!("cargo:rustc-link-arg=-Tdefmt.x"); +} + +fn generate_vial_config() { + let out_file = Path::new(&env::var_os("OUT_DIR").unwrap()).join("config_generated.rs"); + let p = Path::new("vial.json"); + let mut content = String::new(); + match File::open(p) { + Ok(mut file) => { + file.read_to_string(&mut content).expect("Cannot read vial.json"); + } + Err(e) => println!("Cannot find vial.json {:?}: {}", p, e), + }; + let vial_cfg = json::stringify(json::parse(&content).unwrap()); + let mut keyboard_def_compressed: Vec = Vec::new(); + XzEncoder::new(vial_cfg.as_bytes(), 6) + .read_to_end(&mut keyboard_def_compressed) + .unwrap(); + let keyboard_id: Vec = vec![0xB9, 0xBC, 0x09, 0xB2, 0x9D, 0x37, 0x4C, 0xEA]; + let const_declarations = [ + const_declaration!(pub VIAL_KEYBOARD_DEF = keyboard_def_compressed), + const_declaration!(pub VIAL_KEYBOARD_ID = keyboard_id), + ] + .map(|s| "#[allow(clippy::redundant_static_lifetimes)]\n".to_owned() + s.as_str()) + .join("\n"); + fs::write(out_file, const_declarations).unwrap(); +} diff --git a/examples/use_rust/rp2040_embassy_boot_split/memory.x b/examples/use_rust/rp2040_embassy_boot_split/memory.x new file mode 100644 index 000000000..1a1c12a71 --- /dev/null +++ b/examples/use_rust/rp2040_embassy_boot_split/memory.x @@ -0,0 +1,4 @@ +MEMORY { + FLASH : ORIGIN = 0x10007000, LENGTH = 944K + RAM : ORIGIN = 0x20000000, LENGTH = 256K +} diff --git a/examples/use_rust/rp2040_embassy_boot_split/src/central.rs b/examples/use_rust/rp2040_embassy_boot_split/src/central.rs new file mode 100644 index 000000000..18fd76818 --- /dev/null +++ b/examples/use_rust/rp2040_embassy_boot_split/src/central.rs @@ -0,0 +1,150 @@ +#![no_main] +#![no_std] + +#[macro_use] +mod keymap; +#[macro_use] +mod macros; +mod vial; + +use defmt::info; +use defmt_rtt as _; +use embassy_executor::Spawner; +use embassy_rp::gpio::{Input, Output}; +use embassy_rp::peripherals::{UART0, USB}; +use embassy_rp::uart::{self, BufferedUart}; +use embassy_rp::usb::{Driver, InterruptHandler}; +use embassy_rp::{bind_interrupts, dma}; +use panic_probe as _; +use rmk::config::{BehaviorConfig, DeviceConfig, PositionalConfig, RmkConfig, StorageConfig, VialConfig}; +use rmk::debounce::default_debouncer::DefaultDebouncer; +use rmk::futures::future::join; +use rmk::host::HostService; +use rmk::keyboard::Keyboard; +use rmk::matrix::Matrix; +use rmk::processor::builtin::wpm::WpmProcessor; +use rmk::split::SPLIT_MESSAGE_MAX_SIZE; +use rmk::split::central::run_peripheral_manager; +use rmk::storage::async_flash_wrapper; +use rmk::usb::UsbTransport; +use rmk::watchdog::Rp2040Watchdog; +use rmk::{KeymapData, initialize_keymap_and_storage, run_all}; +use static_cell::StaticCell; +use vial::{VIAL_KEYBOARD_DEF, VIAL_KEYBOARD_ID}; + +bind_interrupts!(struct Irqs { + USBCTRL_IRQ => InterruptHandler; + UART0_IRQ => uart::BufferedInterruptHandler; + DMA_IRQ_0 => dma::InterruptHandler; +}); + +const FLASH_SIZE: u32 = 2 * 1024 * 1024; +const PAGE_SIZE: u32 = 4 * 1024; +const STORAGE_SIZE: u32 = 128 * 1024; +const STATE_OFFSET: u32 = 0x6000; +const STATE_SIZE: u32 = 0x1000; +const ACTIVE_OFFSET: u32 = 0x7000; + +#[embassy_executor::main] +async fn main(_spawner: Spawner) { + info!("RMK central start!"); + let p = embassy_rp::init(Default::default()); + + let driver = Driver::new(p.USB, Irqs); + + let (row_pins, col_pins) = config_matrix_pins_rp!(peripherals: p, input: [PIN_9, PIN_11], output: [PIN_10, PIN_12]); + + let remaining = FLASH_SIZE - 28 * 1024 - STORAGE_SIZE; + let active_size = (remaining - PAGE_SIZE) / 2; + let dfu_size = active_size + PAGE_SIZE; + let dfu_offset = ACTIVE_OFFSET + active_size; + let storage_offset = dfu_offset + dfu_size; + assert!(storage_offset + STORAGE_SIZE == FLASH_SIZE); + + info!( + "Flash: state=0x{:04X} active=0x{:04X}({}K) dfu=0x{:04X}({}K) storage=0x{:04X}", + STATE_OFFSET, + ACTIVE_OFFSET, + active_size / 1024, + dfu_offset, + dfu_size / 1024, + storage_offset + ); + + let flash = async_flash_wrapper(rmk::dfu::init_flash( + p.FLASH, + storage_offset, + STORAGE_SIZE, + STATE_OFFSET, + STATE_SIZE, + dfu_offset, + dfu_size, + )); + + rmk::dfu::mark_booted(); + + let keyboard_device_config = DeviceConfig { + vid: 0x4c4b, + pid: 0x4643, + manufacturer: "Haobo", + product_name: "RMK Keyboard", + serial_number: "vial:f64c2b3c:000001", + }; + + let vial_config = VialConfig::new(VIAL_KEYBOARD_ID, VIAL_KEYBOARD_DEF, &[(0, 0), (1, 1)]); + + let rmk_config = RmkConfig { + device_config: keyboard_device_config, + vial_config, + ..Default::default() + }; + + static TX_BUF: StaticCell<[u8; SPLIT_MESSAGE_MAX_SIZE]> = StaticCell::new(); + let tx_buf = &mut TX_BUF.init([0; SPLIT_MESSAGE_MAX_SIZE])[..]; + static RX_BUF: StaticCell<[u8; SPLIT_MESSAGE_MAX_SIZE]> = StaticCell::new(); + let rx_buf = &mut RX_BUF.init([0; SPLIT_MESSAGE_MAX_SIZE])[..]; + let uart_receiver = BufferedUart::new(p.UART0, p.PIN_0, p.PIN_1, Irqs, tx_buf, rx_buf, uart::Config::default()); + + let mut keymap_data = KeymapData::new(keymap::get_default_keymap()); + let mut behavior_config = BehaviorConfig::default(); + let storage_config = StorageConfig { + num_sectors: 32, + start_addr: 0, + clear_storage: false, + clear_layout: false, + }; + let per_key_config = PositionalConfig::default(); + let (keymap, mut storage) = initialize_keymap_and_storage( + &mut keymap_data, + flash, + &storage_config, + &mut behavior_config, + &per_key_config, + ) + .await; + + let debouncer = DefaultDebouncer::new(); + let mut matrix = Matrix::<_, _, _, 2, 2, true>::new(row_pins, col_pins, debouncer); + let mut keyboard = Keyboard::new(&keymap); + let host_ctx = rmk::host::KeyboardContext::new(&keymap); + let mut host_service = HostService::new(&host_ctx, &rmk_config); + + let mut usb_transport = UsbTransport::new(driver, rmk_config.device_config); + let mut wpm_processor = WpmProcessor::new(); + + let mut watchdog_runner = Rp2040Watchdog::default_runner(embassy_rp::watchdog::Watchdog::new(p.WATCHDOG)); + + join( + run_all!( + matrix, + storage, + usb_transport, + wpm_processor, + keyboard, + host_service, + watchdog_runner + ), + run_peripheral_manager::<2, 1, 2, 2, _>(0, uart_receiver), + ) + .await; +} diff --git a/examples/use_rust/rp2040_embassy_boot_split/src/keymap.rs b/examples/use_rust/rp2040_embassy_boot_split/src/keymap.rs new file mode 100644 index 000000000..0ee3d0839 --- /dev/null +++ b/examples/use_rust/rp2040_embassy_boot_split/src/keymap.rs @@ -0,0 +1,23 @@ +use rmk::types::action::KeyAction; +use rmk::{a, k, layer, mo}; +pub(crate) const COL: usize = 3; +pub(crate) const ROW: usize = 4; +pub(crate) const NUM_LAYER: usize = 2; + +#[rustfmt::skip] +pub const fn get_default_keymap() -> [[[KeyAction; COL]; ROW]; NUM_LAYER] { + [ + layer!([ + [k!(AudioVolUp), k!(B), k!(AudioVolDown)], + [k!(Kp4), k!(LShift), k!(Kp6)], + [mo!(1), k!(Kp2), k!(Kp3)], + [mo!(1), a!(No), k!(Kp0)] + ]), + layer!([ + [k!(Kp7), k!(Kp8), k!(Kp9)], + [k!(Kp4), k!(LCtrl), k!(Kp6)], + [mo!(1), k!(Kp2), k!(Kp3)], + [mo!(1), a!(No), k!(Kp0)] + ]), + ] +} diff --git a/examples/use_rust/rp2040_embassy_boot_split/src/macros.rs b/examples/use_rust/rp2040_embassy_boot_split/src/macros.rs new file mode 100644 index 000000000..fb2652993 --- /dev/null +++ b/examples/use_rust/rp2040_embassy_boot_split/src/macros.rs @@ -0,0 +1,12 @@ +macro_rules! config_matrix_pins_rp { + (peripherals: $p:ident, input: [$($in_pin:ident), *], output: [$($out_pin:ident), +]) => { + { + let mut output_pins = [$(Output::new($p.$out_pin, embassy_rp::gpio::Level::Low)), +]; + let input_pins = [$(Input::new($p.$in_pin, embassy_rp::gpio::Pull::Down)), +]; + output_pins.iter_mut().for_each(|p| { + p.set_low(); + }); + (input_pins, output_pins) + } + }; +} diff --git a/examples/use_rust/rp2040_embassy_boot_split/src/peripheral.rs b/examples/use_rust/rp2040_embassy_boot_split/src/peripheral.rs new file mode 100644 index 000000000..1a2436878 --- /dev/null +++ b/examples/use_rust/rp2040_embassy_boot_split/src/peripheral.rs @@ -0,0 +1,104 @@ +#![no_main] +#![no_std] + +#[macro_use] +mod macros; + +use defmt::*; +use defmt_rtt as _; +use embassy_executor::Spawner; +use embassy_futures::join::join3; +use embassy_rp::gpio::{Input, Level, Output}; +use embassy_rp::peripherals::{UART0, USB}; +use embassy_rp::uart::{self, BufferedUart}; +use embassy_rp::usb::{Driver, InterruptHandler}; +use embassy_rp::{bind_interrupts, dma}; +use panic_probe as _; +use rmk::config::DeviceConfig; +use rmk::debounce::default_debouncer::DefaultDebouncer; +use rmk::matrix::Matrix; +use rmk::processor::builtin::dfu_led::DfuLedProcessor; +use rmk::run_all; +use rmk::split::SPLIT_MESSAGE_MAX_SIZE; +use rmk::split::peripheral::run_rmk_split_peripheral; +use rmk::storage::{async_flash_wrapper, new_storage_for_split_peripheral}; +use rmk::watchdog::Rp2040Watchdog; +use static_cell::StaticCell; + +bind_interrupts!(struct Irqs { + USBCTRL_IRQ => InterruptHandler; + UART0_IRQ => uart::BufferedInterruptHandler; + DMA_IRQ_0 => dma::InterruptHandler; +}); + +const FLASH_SIZE: u32 = 2 * 1024 * 1024; +const PAGE_SIZE: u32 = 4 * 1024; +const STORAGE_SIZE: u32 = 128 * 1024; +const STATE_OFFSET: u32 = 0x6000; +const STATE_SIZE: u32 = 0x1000; +const ACTIVE_OFFSET: u32 = 0x7000; + +#[embassy_executor::main] +async fn main(_spawner: Spawner) { + info!("RMK peripheral start!"); + let p = embassy_rp::init(Default::default()); + + let (row_pins, col_pins) = config_matrix_pins_rp!(peripherals: p, input: [PIN_9, PIN_11], output: [PIN_10, PIN_12]); + + let remaining = FLASH_SIZE - 28 * 1024 - STORAGE_SIZE; + let active_size = (remaining - PAGE_SIZE) / 2; + let dfu_size = active_size + PAGE_SIZE; + let dfu_offset = ACTIVE_OFFSET + active_size; + let storage_offset = dfu_offset + dfu_size; + + let flash = async_flash_wrapper(rmk::dfu::init_flash( + p.FLASH, + storage_offset, + STORAGE_SIZE, + STATE_OFFSET, + STATE_SIZE, + dfu_offset, + dfu_size, + )); + + rmk::dfu::mark_booted(); + + // DFU USB device so the peripheral can be firmware-updated via USB + let dfu_driver = Driver::new(p.USB, Irqs); + + let dfu_device_config = DeviceConfig { + vid: 0x4c4b, + pid: 0x4643, + manufacturer: "Haobo", + product_name: "RMK Keyboard Peripheral", + serial_number: "vial:f64c2b3c:000001", + }; + + let mut dfu_led = DfuLedProcessor::new(Output::new(p.PIN_25, Level::Low), false); + + static TX_BUF: StaticCell<[u8; SPLIT_MESSAGE_MAX_SIZE]> = StaticCell::new(); + let tx_buf = &mut TX_BUF.init([0; SPLIT_MESSAGE_MAX_SIZE])[..]; + static RX_BUF: StaticCell<[u8; SPLIT_MESSAGE_MAX_SIZE]> = StaticCell::new(); + let rx_buf = &mut RX_BUF.init([0; SPLIT_MESSAGE_MAX_SIZE])[..]; + let uart_instance = BufferedUart::new(p.UART0, p.PIN_0, p.PIN_1, Irqs, tx_buf, rx_buf, uart::Config::default()); + + let debouncer = DefaultDebouncer::new(); + let mut matrix = Matrix::<_, _, _, 2, 2, true>::new(row_pins, col_pins, debouncer); + + let storage_config = rmk::config::StorageConfig { + num_sectors: 32, + start_addr: 0, + clear_storage: false, + clear_layout: false, + }; + let mut storage = new_storage_for_split_peripheral(flash, storage_config).await; + + let mut watchdog_runner = Rp2040Watchdog::default_runner(embassy_rp::watchdog::Watchdog::new(p.WATCHDOG)); + + join3( + run_all!(matrix, storage, dfu_led, watchdog_runner), + run_rmk_split_peripheral(uart_instance), + rmk::dfu::run_peripheral_dfu(dfu_driver, dfu_device_config), + ) + .await; +} diff --git a/examples/use_rust/rp2040_embassy_boot_split/src/vial.rs b/examples/use_rust/rp2040_embassy_boot_split/src/vial.rs new file mode 100644 index 000000000..33e0a4ad0 --- /dev/null +++ b/examples/use_rust/rp2040_embassy_boot_split/src/vial.rs @@ -0,0 +1 @@ +include!(concat!(env!("OUT_DIR"), "/config_generated.rs")); diff --git a/examples/use_rust/rp2040_embassy_boot_split/vial.json b/examples/use_rust/rp2040_embassy_boot_split/vial.json new file mode 100644 index 000000000..bd673d08e --- /dev/null +++ b/examples/use_rust/rp2040_embassy_boot_split/vial.json @@ -0,0 +1,18 @@ +{ + "name": "RMK Keyboard", + "vendorId": "0x4C4B", + "productId": "0x4643", + "lighting": "none", + "matrix": { + "rows": 4, + "cols": 3 + }, + "layouts": { + "keymap": [ + ["0,0", "0,1", "0,2"], + ["1,0", "1,1", "1,2"], + ["2,0", "2,1", "2,2"], + [{"y": -2, "x": 4}, "3,0", "3,2"] + ] + } +} diff --git a/rmk-config/src/lib.rs b/rmk-config/src/lib.rs index acd9023fb..f083fe9ce 100644 --- a/rmk-config/src/lib.rs +++ b/rmk-config/src/lib.rs @@ -120,9 +120,10 @@ impl KeyboardTomlConfig { /// and should not require `[keyboard.board]`/`[keyboard.chip]`. pub fn new_from_toml_path_with_event_defaults>(config_toml_path: P) -> Self { let mut config = Self::parse_from_toml_path(config_toml_path, None); - config.storage_user_set = config.storage.as_ref().map_or(false, |s| { - s.start_addr.is_some() || s.num_sectors.is_some() - }); + config.storage_user_set = config + .storage + .as_ref() + .is_some_and(|s| s.start_addr.is_some() || s.num_sectors.is_some()); config.auto_calculate_parameters(); config } @@ -142,9 +143,10 @@ impl KeyboardTomlConfig { // 2. Chip-specific default config // 3. User config (highest priority) let mut config = Self::parse_from_toml_path(path, Some(default_config_str)); - config.storage_user_set = user_config.storage.as_ref().map_or(false, |s| { - s.start_addr.is_some() || s.num_sectors.is_some() - }); + config.storage_user_set = user_config + .storage + .as_ref() + .is_some_and(|s| s.start_addr.is_some() || s.num_sectors.is_some()); config.auto_calculate_parameters(); diff --git a/rmk-macro/src/codegen/orchestrator.rs b/rmk-macro/src/codegen/orchestrator.rs index fb424115a..85ae68c0d 100644 --- a/rmk-macro/src/codegen/orchestrator.rs +++ b/rmk-macro/src/codegen/orchestrator.rs @@ -231,7 +231,7 @@ fn expand_main( let (input_device_config, devices, processors) = expand_input_device_config(hardware); let matrix_and_keyboard = expand_matrix_and_keyboard_init(hardware); let (registered_processor_initializers, mut registered_processors) = - expand_registered_processor_init(hardware, &item_mod); + expand_registered_processor_init(hardware, &item_mod, rmk_features); // Declare dfu_lock (if enabled) so it can be pushed as a Runnable task. // Check the feature at macro-expansion time so we never emit `#[cfg]` diff --git a/rmk-macro/src/codegen/registered_processor.rs b/rmk-macro/src/codegen/registered_processor.rs index 803232f3d..9d84eb73c 100644 --- a/rmk-macro/src/codegen/registered_processor.rs +++ b/rmk-macro/src/codegen/registered_processor.rs @@ -5,12 +5,14 @@ use rmk_config::resolved::hardware::{ChipModel, PinConfig}; use syn::ItemMod; use super::chip::gpio::convert_gpio_str_to_output_pin; +use crate::codegen::feature::is_feature_enabled; /// Expand processor init/exec blocks from keyboard config. /// Returns (initializers, executors). pub(crate) fn expand_registered_processor_init( hardware: &Hardware, item_mod: &ItemMod, + rmk_features: &Option>, ) -> (TokenStream, Vec) { let mut initializers = TokenStream::new(); let mut executors = vec![]; @@ -19,7 +21,7 @@ pub(crate) fn expand_registered_processor_init( initializers.extend(i); executors.extend(e); - if hardware.dfu.is_some() { + if is_feature_enabled(rmk_features, "dfu_rp") || is_feature_enabled(rmk_features, "dfu_nrf") { create_dfu_led_processor(hardware, &mut initializers, &mut executors); } diff --git a/rmk-macro/src/codegen/split/peripheral.rs b/rmk-macro/src/codegen/split/peripheral.rs index 3f2c6ad99..8a0b76fd4 100644 --- a/rmk-macro/src/codegen/split/peripheral.rs +++ b/rmk-macro/src/codegen/split/peripheral.rs @@ -9,7 +9,6 @@ use syn::ItemMod; use super::central::expand_serial_init; use crate::codegen::chip::chip_init::expand_chip_init; -use rmk_config::resolved::Identity; use crate::codegen::chip::flash::expand_flash_init; use crate::codegen::chip::gpio::expand_output_initialization; use crate::codegen::display::{expand_display_config, expand_display_interrupt}; @@ -28,6 +27,7 @@ use crate::codegen::matrix::{ use crate::codegen::orchestrator::get_debouncer_type; use crate::codegen::registered_processor::expand_registered_processor_init; use crate::codegen::watchdog::expand_watchdog_init; +use rmk_config::resolved::Identity; /// Parse split peripheral mod and generate a valid RMK main function with all needed code pub(crate) fn parse_split_peripheral_mod( @@ -48,8 +48,8 @@ pub(crate) fn parse_split_peripheral_mod( .identity() .expect("failed to resolve identity config"); - let dfu_enabled = is_feature_enabled(&rmk_features, "dfu_rp") - || is_feature_enabled(&rmk_features, "dfu_nrf"); + let dfu_enabled = + is_feature_enabled(&rmk_features, "dfu_rp") || is_feature_enabled(&rmk_features, "dfu_nrf"); let device_config = if dfu_enabled { let vid = identity.vendor_id; let pid = identity.product_id; @@ -71,7 +71,8 @@ pub(crate) fn parse_split_peripheral_mod( let main_function = expand_split_peripheral(id, &identity, &hardware, item_mod, &rmk_features); - let bind_interrupts = expand_bind_interrupt_for_split_peripheral(&hardware.chip, &hardware, id, &rmk_features); + let bind_interrupts = + expand_bind_interrupt_for_split_peripheral(&hardware.chip, &hardware, id, &rmk_features); let chip = &hardware.chip; let main_function_sig = if chip.series == ChipSeries::Esp32 { @@ -336,8 +337,8 @@ fn expand_split_peripheral( chip_init.extend(quote! { #flash_init }); } - let dfu_enabled = is_feature_enabled(rmk_features, "dfu_rp") - || is_feature_enabled(rmk_features, "dfu_nrf"); + let dfu_enabled = + is_feature_enabled(rmk_features, "dfu_rp") || is_feature_enabled(rmk_features, "dfu_nrf"); // Mark booted when DFU is enabled so the bootloader doesn't // revert the previous update. @@ -459,7 +460,7 @@ fn expand_split_peripheral( // Add processor support for peripherals let (registered_processor_initializers, mut registered_processors) = - expand_registered_processor_init(hardware, &item_mod); + expand_registered_processor_init(hardware, &item_mod, rmk_features); // Display configuration for this peripheral let display_init = if let Some(display_config) = &peripheral_config.display { diff --git a/rmk-types/src/lib.rs b/rmk-types/src/lib.rs index cc0769e9b..cc80e4e8a 100644 --- a/rmk-types/src/lib.rs +++ b/rmk-types/src/lib.rs @@ -35,9 +35,9 @@ pub mod battery; pub mod ble; pub mod combo; pub mod connection; +pub mod constants; #[cfg(feature = "dfu")] pub mod dfu; -pub mod constants; pub mod fmt; pub mod fork; pub mod keycode; diff --git a/rmk/src/dfu/mod.rs b/rmk/src/dfu/mod.rs index a45da4ba3..f5ddc92f8 100644 --- a/rmk/src/dfu/mod.rs +++ b/rmk/src/dfu/mod.rs @@ -18,15 +18,15 @@ use crate::core_traits::Runnable; // Chip modules // --------------------------------------------------------------------------- -#[cfg(feature = "dfu_rp")] -mod rp; #[cfg(feature = "dfu_nrf")] mod nrf; - #[cfg(feature = "dfu_rp")] -pub use self::rp::{init_flash, mark_booted, get_manager, DFU_WRITE_SIZE}; +mod rp; + #[cfg(feature = "dfu_nrf")] -pub use self::nrf::{init_flash, mark_booted, get_manager, DFU_WRITE_SIZE}; +pub use self::nrf::{DFU_WRITE_SIZE, get_manager, init_flash, mark_booted}; +#[cfg(feature = "dfu_rp")] +pub use self::rp::{DFU_WRITE_SIZE, get_manager, init_flash, mark_booted}; // --------------------------------------------------------------------------- // Chip-specific type aliases @@ -39,10 +39,10 @@ pub const BLOCK_SIZE_DFU: usize = 512; #[cfg(any(feature = "dfu_rp", feature = "dfu_nrf"))] use embassy_embedded_hal::flash::partition::BlockingPartition; -#[cfg(feature = "dfu_rp")] -use self::rp::{MutexType, PartitionType}; #[cfg(feature = "dfu_nrf")] use self::nrf::{MutexType, PartitionType}; +#[cfg(feature = "dfu_rp")] +use self::rp::{MutexType, PartitionType}; // --------------------------------------------------------------------------- // DfuFlashManager — shared by RP2040 and nRF @@ -136,14 +136,17 @@ pub fn is_dfu_unlocked() -> bool { // --------------------------------------------------------------------------- #[cfg(feature = "dfu")] -use embassy_usb::class::dfu::{consts::Status, dfu_mode::{self, DfuState}}; +use embassy_usb::class::dfu::{ + consts::Status, + dfu_mode::{self, DfuState}, +}; +#[cfg(any(feature = "dfu", feature = "dfu_lock"))] +use rmk_types::dfu::DfuStatus; /// DFU handler wrapper that blinks an LED during transfer and checks the /// DFU lock (if `dfu_lock` feature is enabled). #[cfg(any(feature = "dfu", feature = "dfu_lock"))] use crate::event::publish_event; -#[cfg(any(feature = "dfu", feature = "dfu_lock"))] -use rmk_types::dfu::DfuStatus; #[cfg(feature = "dfu")] struct RmkDfuHandler { @@ -173,9 +176,11 @@ impl dfu_mode::Handler for RmkDfuHandler { fn finish(&mut self) -> Result<(), Status> { let res = self.inner.finish(); - publish_event(crate::event::DfuStatusEvent::new( - if res.is_ok() { DfuStatus::Finished } else { DfuStatus::Error }, - )); + publish_event(crate::event::DfuStatusEvent::new(if res.is_ok() { + DfuStatus::Finished + } else { + DfuStatus::Error + })); res } @@ -189,7 +194,10 @@ impl dfu_mode::Handler for RmkDfuHandler { // --------------------------------------------------------------------------- #[cfg(any(feature = "dfu_rp", feature = "dfu_nrf"))] -use {embassy_boot::{BlockingFirmwareUpdater, FirmwareUpdaterConfig}, embassy_usb_dfu::{ResetImmediate, dfu::FirmwareHandler}}; +use { + embassy_boot::{BlockingFirmwareUpdater, FirmwareUpdaterConfig}, + embassy_usb_dfu::{ResetImmediate, dfu::FirmwareHandler}, +}; /// Register a DFU interface on the USB builder. #[cfg(any(feature = "dfu_rp", feature = "dfu_nrf"))] diff --git a/rmk/src/dfu/nrf.rs b/rmk/src/dfu/nrf.rs index 7bad725cd..c47b9e9de 100644 --- a/rmk/src/dfu/nrf.rs +++ b/rmk/src/dfu/nrf.rs @@ -2,9 +2,11 @@ use core::cell::RefCell; use embassy_boot::BlockingFirmwareState; use embassy_embedded_hal::flash::partition::BlockingPartition; -use embassy_nrf::{nvmc::Nvmc, peripherals::NVMC}; use embassy_nrf::Peri; -use embassy_sync::blocking_mutex::{Mutex, raw::CriticalSectionRawMutex}; +use embassy_nrf::nvmc::Nvmc; +use embassy_nrf::peripherals::NVMC; +use embassy_sync::blocking_mutex::Mutex; +use embassy_sync::blocking_mutex::raw::CriticalSectionRawMutex; use embassy_sync::once_lock::OnceLock; use static_cell::StaticCell; diff --git a/rmk/src/dfu/rp.rs b/rmk/src/dfu/rp.rs index b555fb76d..d33685f7b 100644 --- a/rmk/src/dfu/rp.rs +++ b/rmk/src/dfu/rp.rs @@ -2,9 +2,11 @@ use core::cell::RefCell; use embassy_boot::BlockingFirmwareState; use embassy_embedded_hal::flash::partition::BlockingPartition; -use embassy_rp::{flash::{Blocking, Flash}, peripherals::FLASH}; use embassy_rp::Peri; -use embassy_sync::blocking_mutex::{Mutex, raw::CriticalSectionRawMutex}; +use embassy_rp::flash::{Blocking, Flash}; +use embassy_rp::peripherals::FLASH; +use embassy_sync::blocking_mutex::Mutex; +use embassy_sync::blocking_mutex::raw::CriticalSectionRawMutex; use embassy_sync::once_lock::OnceLock; use static_cell::StaticCell; diff --git a/rmk/src/event/mod.rs b/rmk/src/event/mod.rs index 1fc8aa528..e13297825 100644 --- a/rmk/src/event/mod.rs +++ b/rmk/src/event/mod.rs @@ -56,9 +56,9 @@ mod state; pub use action::ActionEvent; pub use battery::{BatteryAdcEvent, BatteryStatusEvent, ChargingStateEvent}; +pub use connection::{ConnectionStatus, ConnectionStatusChangeEvent, ConnectionType}; #[cfg(feature = "dfu")] pub use dfu::DfuStatusEvent; -pub use connection::{ConnectionStatus, ConnectionStatusChangeEvent, ConnectionType}; pub use input::{ Axis, AxisEvent, AxisValType, KeyPos, KeyboardEvent, KeyboardEventPos, ModifierEvent, PointingEvent, PointingProcessorEvent, PointingSetCpiEvent, RotaryEncoderPos,