[workspace] members = ["."] [package] name = "donglora" version = "1.4.0" edition = "2021" build = "build.rs" authors = ["Stephen Waits "] license = "MIT" description = "Transparent LoRa radio over USB — plug in a board, talk LoRa from your host" repository = "https://github.com/donglora/firmware" homepage = "https://github.com/donglora/firmware" keywords = ["lora", "radio", "embedded", "usb", "firmware"] categories = ["embedded", "hardware-support", "no-std"] # NOTE: esp-rtos patched from GitHub main (see [patch.crates-io] below). # Remove patches once esp-rtos publishes with embassy-executor 0.10 support. [dependencies] cfg-if = "1.0" critical-section = "1.2" defmt = "0.3" embedded-hal = "1.0" embedded-hal-async = "1.0" embassy-embedded-hal = "0.6" embassy-executor = "0.10" embassy-sync = "0.8" embassy-time = "0.5" embassy-usb = { version = "0.6", features = ["defmt"] } embassy-usb-driver = "0.2" ucobs = { version = "0.3", features = ["legacy-msrv"] } heapless = "0.9" donglora-protocol = "1" hsmc = { version = "0.3", default-features = false, features = ["embassy", "trace-defmt"] } # Local path while iterating on CAD IRQ-clear / standby-after-CAD fixes. # Switch back to git fork (then crates.io) once changes are upstreamed. lora-phy = { path = "../../lora-rs/lora-phy", features = ["defmt-03"] } portable-atomic = { version = "1", default-features = false, features = ["critical-section"] } static_cell = "2.1" # Display rendering display-interface = "0.5" embedded-graphics = "0.8" ssd1306 = { version = "0.10", features = ["async"] } # Async IO traits and combinators embedded-io-async = "0.7" embassy-futures = "0.1" # Xtensa ESP crates — requires esp toolchain (espup). The chip feature # (esp32 / esp32s3) is selected per board via the board-level feature flag # below, so the same dep lines support both classic ESP32 and ESP32-S3. esp-backtrace = { version = "0.18", optional = true, features = [ "panic-handler", "defmt", ] } esp-hal = { version = "1.0", optional = true, features = [ "unstable", ] } esp-println = { version = "0.16", optional = true, features = [ "defmt-espflash", ] } esp-rtos = { version = "0.2", optional = true, features = [ "embassy", ] } # nRF52840 (RAK 4631) cortex-m = { version = "0.7", optional = true, features = [ "critical-section-single-core", ] } cortex-m-rt = { version = "0.7", optional = true } defmt-rtt = { version = "0.4", optional = true } embassy-nrf = { version = "0.10", optional = true, features = [ "nrf52840", "gpiote", "time-driver-rtc1", "defmt", # UICR pin-config flags — must match what the Adafruit nRF52 bootloader # actually programmed into UICR on this board. Verified empirically on # RAK4631 via `probe-rs read b32 0x10001200 4`: # PSELRESET[0/1] = 0x12 (P0.18 connected as RESET — NOT gpio) # NFCPINS = 0xFFFFFFFE (bit 0 = 0 → NFC pins as GPIO) # So `nfc-pins-as-gpio` matches; `reset-pin-as-gpio` would NOT match # (would request GPIO when UICR has RESET enabled). The bootloader # uses NRESET for its physical button-reset path, so leaving the pin # as RESET is the right state. "nfc-pins-as-gpio", ] } panic-probe = { version = "1.0", optional = true, features = ["print-defmt"] } # RP2040 (Waveshare RP2040-LoRa) embassy-rp = { version = "0.10", optional = true, features = [ "rp2040", "time-driver", "defmt", ] } [build-dependencies] minijinja = "2.18" owo-colors = "4.3" [features] # The `embassy` feature gates the async-actions codepath inside the `hsmc` # statechart macro. Its `#[cfg(feature = "embassy")]` attributes are # evaluated in *this* crate's context (a proc-macro cfg quirk), so every # board feature must enable it. `tokio` is declared only to silence the # macro's `#[cfg(feature = "tokio")]` checks. embassy = [] tokio = [] # When enabled, replaces the display task with a LED-based diagnostic # blinker driven by `crate::debug_blink::CHECKPOINT`. Used for diagnosing # the firmware on UART-only boards where defmt output would corrupt the # host protocol on the same UART. The LED flashes N times then pauses — # a human watches the pattern and reports N to determine where execution # reached / stopped. debug-checkpoint = [] # NOTE: chart auto-tracing is wired in unconditionally via the # `trace;` keyword in each `statechart!` and the `hsmc/trace-defmt` # feature on the dependency. Whether the trace lines actually emit at # runtime is controlled by defmt's standard compile-time level filter # (`DEFMT_LOG` env var). Release/shipping builds with `DEFMT_LOG` # unset (or `off`) compile every chart trace call out to nothing — # zero overhead, no separate cargo feature needed. # When enabled, the SH1106 OLED driver emits a defmt::info! line for # every I2C transaction it issues — bytes, lengths, addresses. Used to # debug the embassy_nrf::twim assertion panic at twim.rs:541 (cannot # happen via the documented call path; instrumenting the SH1106 path # captures the actual transaction sequence preceding the panic so we # can root-cause). Off by default; opt in via # `just flash-attach rak_wisblock_4631 debug-twim`. debug-twim = [] heltec_v3 = [ "embassy", "dep:esp-backtrace", "dep:esp-hal", "dep:esp-println", "dep:esp-rtos", "esp-backtrace/esp32s3", "esp-hal/esp32s3", "esp-println/esp32s3", "esp-rtos/esp32s3", ] heltec_v3_uart = [ "embassy", "dep:esp-backtrace", "dep:esp-hal", "dep:esp-println", "dep:esp-rtos", "esp-backtrace/esp32s3", "esp-hal/esp32s3", "esp-println/esp32s3", "esp-rtos/esp32s3", ] heltec_v4 = [ "embassy", "dep:esp-backtrace", "dep:esp-hal", "dep:esp-println", "dep:esp-rtos", "esp-backtrace/esp32s3", "esp-hal/esp32s3", "esp-println/esp32s3", "esp-rtos/esp32s3", ] elecrow_thinknode_m2 = [ "embassy", "dep:esp-backtrace", "dep:esp-hal", "dep:esp-println", "dep:esp-rtos", "esp-backtrace/esp32s3", "esp-hal/esp32s3", "esp-println/esp32s3", "esp-rtos/esp32s3", ] lilygo_tbeam_supreme = [ "embassy", "dep:esp-backtrace", "dep:esp-hal", "dep:esp-println", "dep:esp-rtos", "esp-backtrace/esp32s3", "esp-hal/esp32s3", "esp-println/esp32s3", "esp-rtos/esp32s3", ] lilygo_tbeam = [ "embassy", "dep:esp-backtrace", "dep:esp-hal", "dep:esp-println", "dep:esp-rtos", "esp-backtrace/esp32", "esp-hal/esp32", "esp-println/esp32", "esp-rtos/esp32", ] rak_wisblock_4631 = [ "embassy", "dep:cortex-m", "dep:cortex-m-rt", "cortex-m-rt/set-vtor", "dep:defmt-rtt", "dep:embassy-nrf", "dep:panic-probe", "embassy-executor/platform-cortex-m", "embassy-executor/executor-thread", ] wio_tracker_l1 = [ "embassy", "dep:cortex-m", "dep:cortex-m-rt", "cortex-m-rt/set-vtor", "dep:defmt-rtt", "dep:embassy-nrf", "dep:panic-probe", "embassy-executor/platform-cortex-m", "embassy-executor/executor-thread", ] waveshare_rp2040_lora = [ "embassy", "dep:cortex-m", "dep:cortex-m-rt", "dep:defmt-rtt", "dep:embassy-rp", "dep:panic-probe", "embassy-executor/platform-cortex-m", "embassy-executor/executor-thread", ] # REVISIT: esp-rtos 0.2.0 on crates.io pins embassy-executor ^0.9. The # esp-rs/esp-hal main branch already supports 0.10. Remove these patches once # esp-rtos publishes a release with embassy-executor 0.10 support. Track: # https://github.com/esp-rs/esp-hal/tree/main/esp-rtos [patch.crates-io] esp-hal = { git = "https://github.com/esp-rs/esp-hal.git", branch = "main" } esp-rtos = { git = "https://github.com/esp-rs/esp-hal.git", branch = "main" } esp-backtrace = { git = "https://github.com/esp-rs/esp-hal.git", branch = "main" } esp-println = { git = "https://github.com/esp-rs/esp-hal.git", branch = "main" } [lints.rust] # hsmc 0.3's `statechart!` macro emits `#[cfg(feature = "journal")]` # attributes (and others). check-cfg evaluates those in the CALLER's # crate context, so unless donglora declares the same feature names # (we don't — they're hsmc's, not ours), rustc lints them. Per hsmc's # README, the documented fix is to allow the lint with an explicit # check-cfg list so other unexpected cfgs still surface as warnings. unexpected_cfgs = { level = "allow", check-cfg = [ 'cfg(feature, values("tokio", "embassy", "journal", "trace-defmt", "trace-log", "trace-tracing"))', ] } [lints.clippy] undocumented_unsafe_blocks = "deny" [profile.release] codegen-units = 1 lto = "fat" opt-level = 3 # "s"/"z" break Xtensa (l32r literal range exceeded) panic = "abort" # `strip = true` was killing defmt's `_defmt_version_` / `_defmt_encoding_` # symbols, breaking RTT log decoding via probe-rs. Keep symbols + DWARF # so probe-rs can show source locations for log lines. strip = false debug = 2