aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authors-ol <s+removethis@s-ol.nu>2026-03-30 16:26:33 +0000
committers-ol <s+removethis@s-ol.nu>2026-03-30 16:26:33 +0000
commit9aa80ab752c0999ba1df9e98328f09c720f8ea66 (patch)
tree12fa888425c055d0993f68282a377f4ba7f64d98
downloadt144-meshcore-example-9aa80ab752c0999ba1df9e98328f09c720f8ea66.tar.gz
t144-meshcore-example-9aa80ab752c0999ba1df9e98328f09c720f8ea66.zip
initial commit
-rw-r--r--.cargo/config.toml9
-rw-r--r--.gitignore1
-rw-r--r--Cargo.lock1269
-rw-r--r--Cargo.toml52
-rw-r--r--build.rs35
-rw-r--r--memory.x11
-rw-r--r--src/display.rs89
-rw-r--r--src/lib.rs220
-rw-r--r--src/main.rs89
-rw-r--r--src/radio.rs70
10 files changed, 1845 insertions, 0 deletions
diff --git a/.cargo/config.toml b/.cargo/config.toml
new file mode 100644
index 0000000..e887e57
--- /dev/null
+++ b/.cargo/config.toml
@@ -0,0 +1,9 @@
+[target.'cfg(all(target_arch = "arm", target_os = "none"))']
+# replace nRF82810_xxAA with your chip as listed in `probe-rs chip list`
+runner = "probe-rs run --chip nRF52840_xxAA"
+
+[build]
+target = "thumbv7em-none-eabi"
+
+[env]
+DEFMT_LOG = "trace"
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..eb5a316
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1 @@
+target
diff --git a/Cargo.lock b/Cargo.lock
new file mode 100644
index 0000000..5de31a6
--- /dev/null
+++ b/Cargo.lock
@@ -0,0 +1,1269 @@
+# This file is automatically @generated by Cargo.
+# It is not intended for manual editing.
+version = 4
+
+[[package]]
+name = "MeshCore"
+version = "0.0.1"
+source = "git+https://git.housedillon.com/wdillon/Meshcore-rs.git?branch=s-ol%2Fnon-owned#405358ac7ffd4600f1baaf0147a38d62be4faf41"
+dependencies = [
+ "aes",
+ "cayenne_lpp",
+ "chrono",
+ "curve25519-dalek",
+ "ed25519-dalek",
+ "hex",
+ "hmac",
+ "rand",
+ "sha2",
+ "tinyvec",
+ "x25519-dalek",
+]
+
+[[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 = "arrayvec"
+version = "0.7.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "7c02d123df017efcdfbd739ef81735b36c5ba83ec3c59c80a9d7ecc718f92e50"
+
+[[package]]
+name = "autocfg"
+version = "1.5.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "c08606f8c3cbf4ce6ec8e28fb0014a2c086708fe954eaa885384a6165172e7e8"
+
+[[package]]
+name = "az"
+version = "1.2.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "7b7e4c2464d97fe331d41de9d5db0def0a96f4d823b8b32a2efd503578988973"
+
+[[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 = "base64"
+version = "0.13.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "9e1b586273c5702936fe7b7d6896644d8be71e6314cfe09d3167c95f712589e8"
+
+[[package]]
+name = "bitfield"
+version = "0.13.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "46afbd2983a5d5a7bd740ccb198caf5b82f45c40c09c0eed36052d91cb92e719"
+
+[[package]]
+name = "bitflags"
+version = "1.3.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a"
+
+[[package]]
+name = "bitflags"
+version = "2.11.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "843867be96c8daad0d758b57df9392b6d8d271134fce549de6ce169ff98a92af"
+
+[[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 = "byte-slice-cast"
+version = "1.2.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "7575182f7272186991736b70173b0ea045398f984bf5ebbb3804736ce1330c9d"
+
+[[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 = "cayenne_lpp"
+version = "0.4.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "f91070d9eb421c050d41849d3ba4bd4eb9b9bd31c8001435b8e5e0c503f439aa"
+
+[[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.44"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "c673075a2e0e5f4a1dde27ce9dee1ea4558c7ffe648f576438a20ca1d2acc4b0"
+dependencies = [
+ "num-traits",
+]
+
+[[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 = "const-default"
+version = "1.0.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "0b396d1f76d455557e1218ec8066ae14bba60b4b36ecd55577ba979f5db7ecaa"
+
+[[package]]
+name = "cortex-m"
+version = "0.7.7"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "8ec610d8f49840a5b376c69663b6369e71f4b34484b9b2eb29fb918d92516cb9"
+dependencies = [
+ "bare-metal",
+ "bitfield",
+ "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.117",
+]
+
+[[package]]
+name = "cpufeatures"
+version = "0.2.17"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "59ed5838eebb26a2bb2e58f6d5b5316989ae9d08bab10e0e6d103e656d1b0280"
+dependencies = [
+ "libc",
+]
+
+[[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-common"
+version = "0.1.7"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "78c8292055d1c1df0cce5d180393dc8cce0abec0a7102adb6c7b1eef6016d60a"
+dependencies = [
+ "generic-array",
+ "typenum",
+]
+
+[[package]]
+name = "curve25519-dalek"
+version = "4.1.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "97fb8b7c4503de7d6ae7b42ab72a5a59857b4c937ec27a3d4539dba95b5ab2be"
+dependencies = [
+ "cfg-if",
+ "cpufeatures",
+ "curve25519-dalek-derive",
+ "digest",
+ "fiat-crypto",
+ "rustc_version 0.4.1",
+ "subtle",
+ "zeroize",
+]
+
+[[package]]
+name = "curve25519-dalek-derive"
+version = "0.1.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "f46882e17999c6cc590af592290432be3bce0428cb0d5f8b6715e4dc7b383eb3"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "syn 2.0.117",
+]
+
+[[package]]
+name = "darling"
+version = "0.20.11"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "fc7f46116c46ff9ab3eb1597a45688b6715c6e628b5c133e288e709a29bcb4ee"
+dependencies = [
+ "darling_core",
+ "darling_macro",
+]
+
+[[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_macro"
+version = "0.20.11"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "fc34b93ccb385b40dc71c6fceac4b2ad23662c7eeb248cf10d529b7e055b6ead"
+dependencies = [
+ "darling_core",
+ "quote",
+ "syn 2.0.117",
+]
+
+[[package]]
+name = "defmt"
+version = "0.3.100"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "f0963443817029b2024136fc4dd07a5107eb8f977eaf18fcd1fdeb11306b64ad"
+dependencies = [
+ "defmt 1.0.1",
+]
+
+[[package]]
+name = "defmt"
+version = "1.0.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "548d977b6da32fa1d1fda2876453da1e7df63ad0304c8b3dae4dbe7b96f39b78"
+dependencies = [
+ "bitflags 1.3.2",
+ "defmt-macros",
+]
+
+[[package]]
+name = "defmt-macros"
+version = "1.0.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "3d4fc12a85bcf441cfe44344c4b72d58493178ce635338a3f3b78943aceb258e"
+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.1.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "93d5a25c99d89c40f5676bec8cefe0614f17f0f40e916f98e345dae941807f9e"
+dependencies = [
+ "critical-section",
+ "defmt 1.0.1",
+]
+
+[[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 = "display-interface"
+version = "0.5.0"
+source = "git+https://github.com/therealprof/display-interface.git#9b915f93e8665f56b47f11d4fe28c92c1db514bb"
+
+[[package]]
+name = "display-interface-spi"
+version = "0.5.0"
+source = "git+https://github.com/therealprof/display-interface.git#9b915f93e8665f56b47f11d4fe28c92c1db514bb"
+dependencies = [
+ "byte-slice-cast",
+ "display-interface",
+ "embedded-hal 1.0.0",
+ "embedded-hal-async",
+]
+
+[[package]]
+name = "document-features"
+version = "0.2.12"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d4b8a88685455ed29a21542a33abd9cb6510b6b129abadabdcef0f4c55bc8f61"
+dependencies = [
+ "litrs",
+]
+
+[[package]]
+name = "ed25519"
+version = "2.2.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "115531babc129696a58c64a4fef0a8bf9e9698629fb97e9e40767d235cfbcd53"
+dependencies = [
+ "signature",
+]
+
+[[package]]
+name = "ed25519-dalek"
+version = "2.2.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "70e796c081cee67dc755e1a36a0a172b897fab85fc3f6bc48307991f64e4eca9"
+dependencies = [
+ "curve25519-dalek",
+ "ed25519",
+ "rand_core 0.6.4",
+ "sha2",
+ "subtle",
+]
+
+[[package]]
+name = "either"
+version = "1.15.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "48c757948c5ede0e46177b7add2e67155f70e33c07fea8284df6576da70b3719"
+
+[[package]]
+name = "embassy-embedded-hal"
+version = "0.5.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "554e3e840696f54b4c9afcf28a0f24da431c927f4151040020416e7393d6d0d8"
+dependencies = [
+ "defmt 1.0.1",
+ "embassy-futures",
+ "embassy-hal-internal",
+ "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.9.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "06070468370195e0e86f241c8e5004356d696590a678d47d6676795b2e439c6b"
+dependencies = [
+ "cortex-m",
+ "critical-section",
+ "document-features",
+ "embassy-executor-macros",
+ "embassy-executor-timer-queue",
+]
+
+[[package]]
+name = "embassy-executor-macros"
+version = "0.7.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "dfdddc3a04226828316bf31393b6903ee162238576b1584ee2669af215d55472"
+dependencies = [
+ "darling",
+ "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"
+
+[[package]]
+name = "embassy-hal-internal"
+version = "0.3.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "95285007a91b619dc9f26ea8f55452aa6c60f7115a4edc05085cd2bd3127cd7a"
+dependencies = [
+ "cortex-m",
+ "critical-section",
+ "defmt 1.0.1",
+ "num-traits",
+]
+
+[[package]]
+name = "embassy-nrf"
+version = "0.8.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "a8d63429d74ab5786cde7c9dc9a0338ea162a4da95e204ac5345c5ae36831fdb"
+dependencies = [
+ "bitflags 2.11.0",
+ "cfg-if",
+ "cortex-m",
+ "cortex-m-rt",
+ "critical-section",
+ "defmt 1.0.1",
+ "document-features",
+ "embassy-embedded-hal",
+ "embassy-hal-internal",
+ "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",
+ "embedded-io-async",
+ "embedded-storage",
+ "embedded-storage-async",
+ "fixed",
+ "nrf-pac",
+ "rand_core 0.6.4",
+ "rand_core 0.9.5",
+]
+
+[[package]]
+name = "embassy-sync"
+version = "0.7.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "73974a3edbd0bd286759b3d483540f0ebef705919a5f56f4fc7709066f71689b"
+dependencies = [
+ "cfg-if",
+ "critical-section",
+ "defmt 1.0.1",
+ "embedded-io-async",
+ "futures-core",
+ "futures-sink",
+ "heapless",
+]
+
+[[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",
+ "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.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "80e2ee86063bd028a420a5fb5898c18c87a8898026da1d4c852af2c443d0a454"
+dependencies = [
+ "embassy-executor-timer-queue",
+ "heapless",
+]
+
+[[package]]
+name = "embassy-usb-driver"
+version = "0.2.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "17119855ccc2d1f7470a39756b12068454ae27a3eabb037d940b5c03d9c77b7a"
+dependencies = [
+ "defmt 1.0.1",
+ "embedded-io-async",
+]
+
+[[package]]
+name = "embedded-alloc"
+version = "0.6.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "8f2de9133f68db0d4627ad69db767726c99ff8585272716708227008d3f1bddd"
+dependencies = [
+ "const-default",
+ "critical-section",
+ "linked_list_allocator",
+ "rlsf",
+]
+
+[[package]]
+name = "embedded-graphics"
+version = "0.8.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "4e8da660bb0c829b34a56a965490597f82a55e767b91f9543be80ce8ccb416fe"
+dependencies = [
+ "az",
+ "byteorder",
+ "embedded-graphics-core",
+ "float-cmp",
+ "micromath",
+]
+
+[[package]]
+name = "embedded-graphics-core"
+version = "0.4.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "95743bef3ff70fcba3930246c4e6872882bbea0dcc6da2ca860112e0cd4bd09f"
+dependencies = [
+ "az",
+ "byteorder",
+]
+
+[[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"
+
+[[package]]
+name = "embedded-hal-async"
+version = "1.0.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "0c4c685bbef7fe13c3c6dd4da26841ed3980ef33e841cddfa15ce8a8fb3f1884"
+dependencies = [
+ "embedded-hal 1.0.0",
+]
+
+[[package]]
+name = "embedded-hal-bus"
+version = "0.3.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "513e0b3a8fb7d3013a8ae17a834283f170deaf7d0eeab0a7c1a36ad4dd356d22"
+dependencies = [
+ "critical-section",
+ "embedded-hal 1.0.0",
+ "embedded-hal-async",
+]
+
+[[package]]
+name = "embedded-io"
+version = "0.6.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "edd0f118536f44f5ccd48bcb8b111bdc3de888b58c74639dfb034a357d0f206d"
+
+[[package]]
+name = "embedded-io-async"
+version = "0.6.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "3ff09972d4073aa8c299395be75161d582e7629cd663171d62af73c8d50dba3f"
+dependencies = [
+ "embedded-io",
+]
+
+[[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 = "fiat-crypto"
+version = "0.2.9"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "28dea519a9695b9977216879a3ebfddf92f1c08c05d984f8996aecd6ecdc811d"
+
+[[package]]
+name = "fixed"
+version = "1.29.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "707070ccf8c4173548210893a0186e29c266901b71ed20cd9e2ca0193dfe95c3"
+dependencies = [
+ "az",
+ "bytemuck",
+ "half",
+ "typenum",
+]
+
+[[package]]
+name = "float-cmp"
+version = "0.9.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "98de4bbd547a563b716d8dfa9aad1cb19bfab00f4fa09a6a4ed21dbcf44ce9c4"
+dependencies = [
+ "num-traits",
+]
+
+[[package]]
+name = "fnv"
+version = "1.0.7"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1"
+
+[[package]]
+name = "futures-core"
+version = "0.3.32"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "7e3450815272ef58cec6d564423f6e755e25379b217b0bc688e295ba24df6b1d"
+
+[[package]]
+name = "futures-sink"
+version = "0.3.32"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "c39754e157331b013978ec91992bde1ac089843443c49cbc7f46150b0fad0893"
+
+[[package]]
+name = "generic-array"
+version = "0.14.7"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "85649ca51fd72272d7821adaf274ad91c288277713d9c18820d8499a7ff69e9a"
+dependencies = [
+ "typenum",
+ "version_check",
+]
+
+[[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.3.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "47d60b12902ba28e2730cd37e95b8c9223af2808df9e902d4df49588d1470606"
+dependencies = [
+ "byteorder",
+]
+
+[[package]]
+name = "heapless"
+version = "0.8.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "0bfb9eb618601c89945a70e254898da93b13be0388091d42117462b265bb3fad"
+dependencies = [
+ "hash32",
+ "stable_deref_trait",
+]
+
+[[package]]
+name = "hex"
+version = "0.4.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70"
+
+[[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 = "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.7.11"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "0d47946d458e94a1b7bcabbf6521ea7c037062c81f534615abcad76e84d4970d"
+dependencies = [
+ "either",
+]
+
+[[package]]
+name = "libc"
+version = "0.2.183"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "b5b646652bf6661599e1da8901b3b9522896f01e736bad5f723fe7a3a27f899d"
+
+[[package]]
+name = "linked_list_allocator"
+version = "0.10.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "9afa463f5405ee81cdb9cc2baf37e08ec7e4c8209442b5d72c04cfb2cd6e6286"
+
+[[package]]
+name = "litrs"
+version = "1.0.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "11d3d7f243d5c5a8b9bb5d6dd2b1602c0cb0b9db1621bafc7ed66e35ff9fe092"
+
+[[package]]
+name = "lora-modulation"
+version = "0.1.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "2c96c4a41a1f1ad04de765306e1829c7007a37898fe4033204fa82cf2e055624"
+
+[[package]]
+name = "lora-phy"
+version = "3.0.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "61471c3b2909789e3332083577f6cf6c41a4fcf37674ef15156bcbb20504ac65"
+dependencies = [
+ "defmt 0.3.100",
+ "embedded-hal 1.0.0",
+ "embedded-hal-async",
+ "lora-modulation",
+ "num-traits",
+]
+
+[[package]]
+name = "manyhow"
+version = "0.11.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "b33efb3ca6d3b07393750d4030418d594ab1139cee518f0dc88db70fec873587"
+dependencies = [
+ "manyhow-macros",
+ "proc-macro2",
+ "quote",
+ "syn 1.0.109",
+ "syn 2.0.117",
+]
+
+[[package]]
+name = "manyhow-macros"
+version = "0.11.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "46fce34d199b78b6e6073abf984c9cf5fd3e9330145a93ee0738a7443e371495"
+dependencies = [
+ "proc-macro-utils",
+ "proc-macro2",
+ "quote",
+]
+
+[[package]]
+name = "maybe-async-cfg"
+version = "0.2.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "8dbfaa67a76e2623580df07d6bb5e7956c0a4bae4b418314083a9c619bd66627"
+dependencies = [
+ "manyhow",
+ "proc-macro2",
+ "pulldown-cmark",
+ "quote",
+ "syn 1.0.109",
+]
+
+[[package]]
+name = "memchr"
+version = "2.8.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "f8ca58f447f06ed17d5fc4043ce1b10dd205e060fb3ce5b979b8ed8e59ff3f79"
+
+[[package]]
+name = "micromath"
+version = "2.1.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "c3c8dda44ff03a2f238717214da50f65d5a53b45cd213a7370424ffdb6fae815"
+
+[[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.1.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d334027d6703534f2a80de0794ae435c0e029358d28278533d3935e69b221b01"
+dependencies = [
+ "cortex-m",
+ "cortex-m-rt",
+]
+
+[[package]]
+name = "num-traits"
+version = "0.2.19"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841"
+dependencies = [
+ "autocfg",
+]
+
+[[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.0.1",
+]
+
+[[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-macro-utils"
+version = "0.10.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "eeaf08a13de400bc215877b5bdc088f241b12eb42f0a548d3390dc1c56bb7071"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "smallvec",
+]
+
+[[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 = "pulldown-cmark"
+version = "0.11.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "679341d22c78c6c649893cbd6c3278dcbe9fc4faa62fea3a9296ae2b50c14625"
+dependencies = [
+ "bitflags 2.11.0",
+ "memchr",
+ "unicase",
+]
+
+[[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.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404"
+dependencies = [
+ "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 = "rlsf"
+version = "0.2.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "1646a59a9734b8b7a0ac51689388a60fe1625d4b956348e9de07591a1478457a"
+dependencies = [
+ "cfg-if",
+ "const-default",
+ "libc",
+ "rustversion",
+ "svgbobdoc",
+]
+
+[[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.27",
+]
+
+[[package]]
+name = "rustversion"
+version = "1.0.22"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "b39cdef0fa800fc44525c84ccb54a029961a8215f9619753635a9c0d2538d46d"
+
+[[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.27"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d767eb0aabc880b29956c35734170f26ed551a859dbd361d140cdbeca61ab1e2"
+
+[[package]]
+name = "semver-parser"
+version = "0.7.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "388a1df253eca08550bef6c72392cfe7c30914bf41df5269b68cbd6ff8f570a3"
+
+[[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 = "signature"
+version = "2.2.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "77549399552de45a898a580c1b41d445bf730df867cc44e6c0233bbc4b8329de"
+
+[[package]]
+name = "smallvec"
+version = "1.15.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "67b1b7a3b5fe4f1376887184045fcf45c69e92af734b7aaddc05fb777b6fbd03"
+
+[[package]]
+name = "ssd1322"
+version = "0.3.0"
+source = "git+https://github.com/s-ol/ssd1322-rs.git?branch=display-interface#1e9561fa484348c16d1d0bf66f26bd8c5ae49412"
+dependencies = [
+ "display-interface",
+ "itertools",
+ "maybe-async-cfg",
+]
+
+[[package]]
+name = "stable_deref_trait"
+version = "1.2.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "6ce2be8dc25455e1f91df71bfa12ad37d7af1092ae736f3a6cd0e37bc7810596"
+
+[[package]]
+name = "strsim"
+version = "0.11.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f"
+
+[[package]]
+name = "subtle"
+version = "2.6.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "13c2bddecc57b384dee18652358fb23172facb8a2c51ccc10d74c157bdea3292"
+
+[[package]]
+name = "svgbobdoc"
+version = "0.3.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "f2c04b93fc15d79b39c63218f15e3fdffaa4c227830686e3b7c5f41244eb3e50"
+dependencies = [
+ "base64",
+ "proc-macro2",
+ "quote",
+ "syn 1.0.109",
+ "unicode-width",
+]
+
+[[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 = "t114-meshcore-example"
+version = "0.1.0"
+dependencies = [
+ "MeshCore",
+ "arrayvec",
+ "cortex-m",
+ "cortex-m-rt",
+ "defmt 1.0.1",
+ "defmt-rtt",
+ "display-interface-spi",
+ "embassy-executor",
+ "embassy-nrf",
+ "embassy-sync",
+ "embassy-time",
+ "embedded-alloc",
+ "embedded-graphics",
+ "embedded-hal 1.0.0",
+ "embedded-hal-bus",
+ "hex",
+ "lora-phy",
+ "panic-probe",
+ "ssd1322",
+]
+
+[[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 = "tinyvec"
+version = "1.11.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "3e61e67053d25a4e82c844e8424039d9745781b3fc4f32b8d55ed50f5f667ef3"
+
+[[package]]
+name = "typenum"
+version = "1.19.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "562d481066bde0658276a35467c4af00bdc6ee726305698a55b86e61d7ad82bb"
+
+[[package]]
+name = "unicase"
+version = "2.9.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "dbc4bc3a9f746d862c45cb89d705aa10f187bb96c76001afab07a0d35ce60142"
+
+[[package]]
+name = "unicode-ident"
+version = "1.0.24"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "e6e4313cd5fcd3dad5cafa179702e2b244f760991f45397d14d4ebf38247da75"
+
+[[package]]
+name = "unicode-width"
+version = "0.1.14"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "7dd6e30e90baa6f72411720665d41d89b9a3d039dc45b8faea1ddd07f617f6af"
+
+[[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 = "x25519-dalek"
+version = "2.0.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "c7e468321c81fb07fa7f4c636c3972b9100f0346e5b6a9f2bd0603a52f7ed277"
+dependencies = [
+ "curve25519-dalek",
+ "rand_core 0.6.4",
+]
+
+[[package]]
+name = "zerocopy"
+version = "0.8.48"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "eed437bf9d6692032087e337407a86f04cd8d6a16a37199ed57949d415bd68e9"
+dependencies = [
+ "zerocopy-derive",
+]
+
+[[package]]
+name = "zerocopy-derive"
+version = "0.8.48"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "70e3cd084b1788766f53af483dd21f93881ff30d7320490ec3ef7526d203bad4"
+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"
diff --git a/Cargo.toml b/Cargo.toml
new file mode 100644
index 0000000..05de164
--- /dev/null
+++ b/Cargo.toml
@@ -0,0 +1,52 @@
+[package]
+edition = "2021"
+name = "t114-meshcore-example"
+version = "0.1.0"
+license = "MIT OR Apache-2.0"
+publish = false
+
+[features]
+default = ["display"]
+display = ["dep:ssd1322", "dep:display-interface-spi"]
+
+[dependencies]
+
+# LoRa
+lora-phy = "3.0"
+MeshCore = { git = "https://git.housedillon.com/wdillon/Meshcore-rs.git", branch = "s-ol/non-owned", default-features = false }
+# lora-phy = { workspace = true, features = ["lorawan-radio"] }
+
+# utilities
+hex = { version = "*", features = ["alloc"], default-features = false }
+arrayvec = { version = "*", default-features = false }
+
+# logging
+defmt = "1.0"
+defmt-rtt = "1.0"
+
+# display
+display-interface-spi = { version = "0.5.0", optional = true }
+ssd1322 = { version = "0.3", optional = true }
+embedded-hal-bus = { version = "0.3", features = ["async"] }
+embedded-graphics = "0.8"
+
+# platform deps
+embassy-nrf = { version = "0.8.0", features = ["defmt", "nrf52840", "time-driver-rtc1", "time", "nfc-pins-as-gpio", "gpiote"] }
+embassy-sync = "0.7.2"
+embassy-time = "0.5.0"
+embassy-executor = { version = "0.9.0", features = ["arch-cortex-m", "executor-thread", "executor-interrupt"] }
+embedded-alloc = "0.6.0"
+embedded-hal = "1.0"
+cortex-m = { version = "0.7.6", features = ["inline-asm", "critical-section-single-core"] }
+cortex-m-rt = "0.7.0"
+panic-probe = { version = "1.0.0", features = ["print-defmt"] }
+
+[profile.release]
+debug = 2
+
+[package.metadata.embassy]
+build = [{ target = "thumbv7em-none-eabi", artifact-dir = "out/t114" }]
+
+[patch.crates-io]
+ssd1322 = { git = "https://github.com/s-ol/ssd1322-rs.git", branch = "display-interface" }
+display-interface-spi = { git = "https://github.com/therealprof/display-interface.git", commit = "9b915f93" }
diff --git a/build.rs b/build.rs
new file mode 100644
index 0000000..30691aa
--- /dev/null
+++ b/build.rs
@@ -0,0 +1,35 @@
+//! This build script copies the `memory.x` file from the crate root into
+//! a directory where the linker can always find it at build time.
+//! For many projects this is optional, as the linker always searches the
+//! project root directory -- wherever `Cargo.toml` is. However, if you
+//! are using a workspace or have a more complicated build setup, this
+//! build script becomes required. Additionally, by requesting that
+//! Cargo re-run the build script whenever `memory.x` is changed,
+//! updating `memory.x` ensures a rebuild of the application with the
+//! new memory settings.
+
+use std::env;
+use std::fs::File;
+use std::io::Write;
+use std::path::PathBuf;
+
+fn main() {
+ // Put `memory.x` in our output directory and ensure it's
+ // on the linker search path.
+ 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());
+
+ // By default, Cargo will re-run a build script whenever
+ // any file in the project changes. By specifying `memory.x`
+ // here, we ensure the build script is only re-run when
+ // `memory.x` is changed.
+ println!("cargo:rerun-if-changed=memory.x");
+
+ println!("cargo:rustc-link-arg-bins=--nmagic");
+ println!("cargo:rustc-link-arg-bins=-Tlink.x");
+ println!("cargo:rustc-link-arg-bins=-Tdefmt.x");
+}
diff --git a/memory.x b/memory.x
new file mode 100644
index 0000000..51bc398
--- /dev/null
+++ b/memory.x
@@ -0,0 +1,11 @@
+MEMORY
+{
+
+ FLASH (rx) : ORIGIN = 0x26000 , LENGTH = 0xED000 - 0x26000
+ RAM (rwx) : ORIGIN = 0x20006000, LENGTH = 0x20040000 - 0x20006000
+
+ /*
+ FLASH : ORIGIN = 0x00000000, LENGTH = 256K
+ RAM : ORIGIN = 0x20000000, LENGTH = 24K
+ */
+}
diff --git a/src/display.rs b/src/display.rs
new file mode 100644
index 0000000..5830254
--- /dev/null
+++ b/src/display.rs
@@ -0,0 +1,89 @@
+use defmt::info;
+use display_interface_spi::SpiInterface;
+use embassy_nrf::gpio::{AnyPin, Level, Output, OutputDrive};
+use embassy_nrf::{interrupt::typelevel::Binding, spim, Peri};
+use embassy_time::Timer;
+use embedded_graphics::{
+ framebuffer::{buffer_size, Framebuffer},
+ pixelcolor::{raw::LittleEndian, Gray4},
+};
+use embedded_hal_bus::spi::ExclusiveDevice;
+use ssd1322::{DisplayAsync, PixelCoord};
+
+type SPIDevice<'t> = ExclusiveDevice<spim::Spim<'t>, Output<'t>, embassy_time::Delay>;
+
+type Display<'t> = DisplayAsync<SpiInterface<SPIDevice<'t>, Output<'t>>>;
+
+pub struct Pins<'t> {
+ pub ven: Peri<'t, AnyPin>,
+ pub rst: Peri<'t, AnyPin>,
+ pub sck: Peri<'t, AnyPin>,
+ pub sdo: Peri<'t, AnyPin>,
+ pub cs: Peri<'t, AnyPin>,
+ pub dc: Peri<'t, AnyPin>,
+}
+
+pub async fn init<T: spim::Instance>(
+ spi_instance: Peri<'static, T>,
+ irq_binding: impl Binding<T::Interrupt, spim::InterruptHandler<T>> + 'static,
+ pins: Pins<'static>,
+) -> Display<'static> {
+ Output::new(pins.ven, Level::High, OutputDrive::Standard).persist();
+
+ let mut out_rst = Output::new(pins.rst, Level::Low, OutputDrive::Standard);
+ Timer::after_millis(2).await;
+ out_rst.set_high();
+ Timer::after_millis(2).await;
+
+ let out_cs = Output::new(pins.cs, Level::High, OutputDrive::Standard);
+ let out_dc = Output::new(pins.dc, Level::High, OutputDrive::Standard);
+
+ let mut spi_config = spim::Config::default();
+ spi_config.frequency = spim::Frequency::M8;
+ let spi_bus = spim::Spim::new_txonly(spi_instance, irq_binding, pins.sck, pins.sdo, spi_config);
+ let spi_dev = ExclusiveDevice::new(spi_bus, out_cs, embassy_time::Delay).unwrap();
+ let spi_iface = SpiInterface::new(spi_dev, out_dc);
+
+ let mut display = DisplayAsync::new(spi_iface, PixelCoord(256, 64), PixelCoord(0x1C * 4, 0));
+
+ info!("initializing display");
+ display
+ .init(
+ ssd1322::ConfigAsync::new(
+ ssd1322::ComScanDirection::RowZeroLast,
+ ssd1322::ComLayout::Progressive,
+ )
+ .column_remap(ssd1322::command::ColumnRemap::Reverse)
+ .clock_fosc_divset(9, 1)
+ .display_enhancements(true, true)
+ .contrast_current(0x7f)
+ .phase_lengths(5, 15)
+ .precharge_voltage(0x1f)
+ .com_deselect_voltage(0x04),
+ )
+ .await
+ .unwrap();
+
+ display
+}
+
+#[embassy_executor::task]
+pub async fn task(mut display: Display<'static>) {
+ let mut fb =
+ Framebuffer::<Gray4, _, LittleEndian, 128, 64, { buffer_size::<Gray4>(128, 64) }>::new();
+
+ info!("display task starting");
+ t114_meshcore_example::display_task(&mut fb, async |fb| {
+ display
+ .region(PixelCoord(0, 0), PixelCoord(256, 64))
+ .unwrap()
+ .draw_packed(fb.data().iter().flat_map(|n| {
+ let upper = n & 0xf0;
+ let lower = n & 0x0f;
+ [upper | (upper >> 4), lower | (lower << 4)]
+ }))
+ .await
+ .unwrap();
+ })
+ .await;
+}
diff --git a/src/lib.rs b/src/lib.rs
new file mode 100644
index 0000000..5bcd1ac
--- /dev/null
+++ b/src/lib.rs
@@ -0,0 +1,220 @@
+#![no_std]
+#![no_main]
+#![allow(async_fn_in_trait)]
+
+extern crate alloc;
+
+use arrayvec::{ArrayString, ArrayVec};
+use defmt::{info, Debug2Format};
+
+use core::{convert::Infallible, fmt::Write, str::FromStr};
+use embassy_sync::{
+ blocking_mutex::raw::CriticalSectionRawMutex, mutex::Mutex, pubsub::PubSubChannel,
+};
+use embassy_time::Timer;
+use embedded_graphics::{
+ draw_target::DrawTarget,
+ geometry::OriginDimensions,
+ mono_font::{ascii::FONT_4X6, MonoTextStyle},
+ pixelcolor::Gray4,
+ prelude::*,
+ primitives::{Circle, PrimitiveStyle, Rectangle},
+ text::{Alignment, Text},
+};
+use embedded_hal::digital::StatefulOutputPin;
+use lora_phy::{mod_traits::RadioKind, DelayNs, LoRa};
+use meshcore::{
+ crypto::{PrivateKey, PublicKey, SharedSecret},
+ packet::Packet,
+ packet_content::PacketContent,
+ text::ClearText,
+};
+
+pub static MESSAGE_CH: PubSubChannel<CriticalSectionRawMutex, ClearText, 3, 2, 1> =
+ PubSubChannel::new();
+
+pub async fn led_task(
+ led_pin: &Mutex<CriticalSectionRawMutex, impl StatefulOutputPin<Error = Infallible>>,
+) {
+ let mut subscriber = MESSAGE_CH.subscriber().unwrap();
+
+ loop {
+ let _ = subscriber.next_message().await;
+ info!("led: got message");
+
+ let mut led = led_pin.lock().await;
+ for _ in 0..3 {
+ led.set_low().unwrap();
+ Timer::after_millis(50).await;
+ led.set_high().unwrap();
+ Timer::after_millis(50).await;
+ }
+ }
+}
+
+fn cstr(bytes: &[u8]) -> &str {
+ let end = bytes.iter().position(|&b| b == 0).unwrap_or(bytes.len());
+ core::str::from_utf8(&bytes[..end]).unwrap_or("")
+}
+
+pub async fn display_task<D>(display: &mut D, mut finish: impl AsyncFnMut(&mut D))
+where
+ D: DrawTarget<Color = Gray4> + OriginDimensions,
+ <D as DrawTarget>::Error: core::fmt::Debug,
+{
+ let radius: u16 = 10;
+ let mut pos = Point::new(30, 30);
+ let mut vel = Point::new(-2, 1);
+
+ let pp = Point::new(radius.into(), radius.into());
+ let bounds = Rectangle::with_corners(Point::new(0, 0), -(pp - display.size()));
+
+ let mut lines = ArrayVec::<ArrayString<128>, 8>::new();
+ let mut subscriber = MESSAGE_CH.subscriber().unwrap();
+
+ loop {
+ // update ball
+ pos += vel;
+
+ let bottom_right = bounds.bottom_right().unwrap();
+
+ if pos.x < bounds.top_left.x || pos.x > bottom_right.x {
+ vel.x = -vel.x;
+ }
+ if pos.y < bounds.top_left.y || pos.y > bottom_right.y {
+ vel.y = -vel.y;
+ }
+
+ pos.x = pos.x.clamp(bounds.top_left.x, bottom_right.x);
+ pos.y = pos.y.clamp(bounds.top_left.y, bottom_right.y);
+
+ // update chat
+ if let Some(msg) = subscriber.try_next_message_pure() {
+ info!("display: got message");
+ if lines.is_full() {
+ lines.remove(0);
+ }
+
+ let mut str: ArrayString<128> = ArrayString::new();
+ write!(&mut str, "{}: {}", cstr(&msg.sender), cstr(&msg.message)).unwrap();
+ lines.push(str);
+ }
+
+ display.clear(Gray4::BLACK).unwrap();
+ Circle::new(pos, radius.into())
+ .into_styled(PrimitiveStyle::with_stroke(Gray4::new(4), 3))
+ .draw(display)
+ .unwrap();
+
+ for (i, line) in lines.iter().enumerate() {
+ Text::with_alignment(
+ line,
+ Point::new(4, 4 + 8 * (i as i32)),
+ MonoTextStyle::new(&FONT_4X6, Gray4::WHITE),
+ Alignment::Left,
+ )
+ .draw(display)
+ .unwrap();
+ }
+
+ finish(display).await;
+
+ Timer::after_millis(10).await;
+ }
+}
+
+fn hex16(hexstr: &'static str) -> [u8; 16] {
+ let mut buf = [0u8; 16];
+ hex::decode_to_slice(hexstr, &mut buf).expect("invalid hex secret");
+ buf
+}
+
+pub async fn radio_task(lora: &mut LoRa<impl RadioKind, impl DelayNs>) {
+ use lora_phy::mod_params::*;
+
+ let keystore = meshcore::no_std_identity::StaticKeystoreInput {
+ identities:
+ [PrivateKey::from_str( "5884BEECFA94A15B596C8FE51832B857EB018B37F3E85671971977F5A6139374B9C3ECD2415258A9C233D4CA9332C7BF06EB269B786EA71813DE17DFFF480177", ) .unwrap()]
+ .into_iter()
+ .collect(),
+ contacts: [].into_iter().collect(),
+ groups: [
+ SharedSecret::new_from_group_secret(&hex16("8b3387e9c5cdea6ac9e5edbaa115cd72")),
+ SharedSecret::new_from_group_secret(&hex16("4c97bfe431abe20672259d9b6969dcec")),
+ ]
+ .into_iter()
+ .collect(),
+ }
+ .compile();
+
+ let pk: PublicKey = (&keystore.identities[0].private_key).into();
+ info!("public key: {:?}", Debug2Format(&pk));
+
+ let publisher = MESSAGE_CH.publisher().unwrap();
+ let mut buffer: [u8; 256] = [0; 256];
+
+ let mdltn_params = lora
+ .create_modulation_params(
+ SpreadingFactor::_8,
+ Bandwidth::_62KHz,
+ CodingRate::_4_8,
+ 869_618_000,
+ )
+ .unwrap();
+
+ let rx_params = lora
+ .create_rx_packet_params(16, false, buffer.len() as u8, true, false, &mdltn_params)
+ .unwrap();
+
+ lora.prepare_for_rx(RxMode::Continuous, &mdltn_params, &rx_params)
+ .await
+ .unwrap();
+
+ loop {
+ info!("waiting for message");
+ let res = lora.rx(&rx_params, &mut buffer).await.unwrap();
+ let message = &buffer[0..res.0.into()];
+
+ let packet = Packet::try_from(message).unwrap();
+ info!("packet {:?}", Debug2Format(&packet));
+
+ match packet.content {
+ PacketContent::Advert(msg) => {
+ info!("got advert from {}", &msg.name);
+ }
+ PacketContent::GroupText(mut msg) => {
+ msg.decrypt(&keystore).unwrap();
+ if let Some(text) = msg.cleartext {
+ unsafe {
+ info!(
+ "decrypted group message from {}: {}",
+ alloc::str::from_utf8_unchecked(&text.sender),
+ alloc::str::from_utf8_unchecked(&text.message),
+ );
+ }
+ publisher.publish(text).await;
+ } else {
+ info!("failed to decrypt group message");
+ }
+ }
+ PacketContent::Text(mut msg) => {
+ msg.decrypt(&keystore).unwrap();
+ if let Some(text) = msg.cleartext {
+ unsafe {
+ info!(
+ "decrypted p2p message from {}: {}",
+ alloc::str::from_utf8_unchecked(&text.sender),
+ alloc::str::from_utf8_unchecked(&text.message),
+ );
+ }
+ publisher.publish(text).await;
+ } else {
+ info!("failed to decrypt p2p message");
+ }
+ }
+ content => {
+ info!("content: {:?}", Debug2Format(&content));
+ }
+ }
+ }
+}
diff --git a/src/main.rs b/src/main.rs
new file mode 100644
index 0000000..94a8c9e
--- /dev/null
+++ b/src/main.rs
@@ -0,0 +1,89 @@
+#![no_std]
+#![no_main]
+
+use alloc::boxed::Box;
+use embassy_executor::Spawner;
+use embassy_nrf::gpio::{Level, Output, OutputDrive};
+use embassy_nrf::{bind_interrupts, peripherals, spim};
+use embassy_sync::{blocking_mutex::raw::CriticalSectionRawMutex, mutex::Mutex};
+use embedded_alloc::LlffHeap as Heap;
+
+use {defmt_rtt as _, panic_probe as _};
+
+extern crate alloc;
+
+#[cfg(feature = "display")]
+mod display;
+
+mod radio;
+
+#[global_allocator]
+static HEAP: Heap = Heap::empty();
+
+bind_interrupts!(struct Irqs {
+ SPIM3 => spim::InterruptHandler<peripherals::SPI3>;
+ SPI2 => spim::InterruptHandler<peripherals::SPI2>;
+});
+
+type PinMutex<'a> = Mutex<CriticalSectionRawMutex, Output<'a>>;
+
+#[embassy_executor::task]
+async fn led_task(led_pin: &'static PinMutex<'static>) {
+ t114_meshcore_example::led_task(led_pin).await;
+}
+
+#[embassy_executor::main]
+async fn main(spawner: Spawner) {
+ {
+ use core::mem::MaybeUninit;
+ const HEAP_SIZE: usize = 64 * 1024;
+ static mut HEAP_MEM: [MaybeUninit<u8>; HEAP_SIZE] = [MaybeUninit::uninit(); HEAP_SIZE];
+ unsafe { HEAP.init(&raw mut HEAP_MEM as usize, HEAP_SIZE) }
+ }
+
+ let p = embassy_nrf::init(Default::default());
+
+ {
+ // led blink task
+ let led = Output::new(p.P1_03, Level::High, OutputDrive::Standard);
+ let pin: PinMutex = Mutex::new(led);
+ let pin_ref = Box::leak(Box::new(pin));
+ spawner.spawn(led_task(pin_ref)).unwrap();
+ }
+
+ #[cfg(feature = "display")]
+ {
+ let display = display::init(
+ p.SPI3,
+ Irqs,
+ display::Pins {
+ ven: p.P0_21.into(),
+ rst: p.P0_05.into(),
+ sck: p.P1_12.into(),
+ sdo: p.P1_14.into(),
+ cs: p.P1_15.into(),
+ dc: p.P1_13.into(),
+ },
+ )
+ .await;
+ spawner.spawn(display::task(display)).unwrap();
+ }
+
+ {
+ let radio = radio::init(
+ p.SPI2,
+ Irqs,
+ radio::Pins {
+ sck: p.P0_19.into(),
+ miso: p.P0_23.into(),
+ mosi: p.P0_22.into(),
+ cs: p.P0_24.into(),
+ rst: p.P0_25.into(),
+ dio1: p.P0_20.into(),
+ busy: p.P0_17.into(),
+ },
+ )
+ .await;
+ spawner.spawn(radio::task(radio)).unwrap();
+ }
+}
diff --git a/src/radio.rs b/src/radio.rs
new file mode 100644
index 0000000..db677ee
--- /dev/null
+++ b/src/radio.rs
@@ -0,0 +1,70 @@
+use embassy_nrf::gpio::{AnyPin, Input, Level, Output, OutputDrive, Pull};
+use embassy_nrf::{interrupt::typelevel::Binding, spim, Peri};
+use embassy_time::Delay;
+use embedded_hal_bus::spi::ExclusiveDevice;
+
+use lora_phy::iv::GenericSx126xInterfaceVariant;
+use lora_phy::sx126x::{Config, Sx1262, Sx126x, TcxoCtrlVoltage};
+use lora_phy::LoRa;
+
+type SPIDevice<'t> = ExclusiveDevice<spim::Spim<'t>, Output<'t>, Delay>;
+
+type RadioImpl<'t> = LoRa<
+ Sx126x<SPIDevice<'t>, GenericSx126xInterfaceVariant<Output<'t>, Input<'t>>, Sx1262>,
+ Delay,
+>;
+
+pub struct Radio(RadioImpl<'static>);
+
+pub struct Pins<'t> {
+ pub sck: Peri<'t, AnyPin>,
+ pub miso: Peri<'t, AnyPin>,
+ pub mosi: Peri<'t, AnyPin>,
+ pub cs: Peri<'t, AnyPin>,
+ pub rst: Peri<'t, AnyPin>,
+ pub dio1: Peri<'t, AnyPin>,
+ pub busy: Peri<'t, AnyPin>,
+}
+
+pub async fn init<T: spim::Instance>(
+ spi_instance: Peri<'static, T>,
+ irq_binding: impl Binding<T::Interrupt, spim::InterruptHandler<T>> + 'static,
+ pins: Pins<'static>,
+) -> Radio {
+ let out_rst = Output::new(pins.rst, Level::High, OutputDrive::Standard);
+ let out_cs = Output::new(pins.cs, Level::High, OutputDrive::Standard);
+
+ let in_dio1 = Input::new(pins.dio1, Pull::None);
+ let in_busy = Input::new(pins.busy, Pull::None);
+
+ let mut spi_config = spim::Config::default();
+ spi_config.frequency = spim::Frequency::M8;
+ let spi_bus = spim::Spim::new(
+ spi_instance,
+ irq_binding,
+ pins.sck,
+ pins.miso,
+ pins.mosi,
+ spi_config,
+ );
+ let spi_dev = ExclusiveDevice::new(spi_bus, out_cs, Delay).unwrap();
+
+ let iv = GenericSx126xInterfaceVariant::new(out_rst, in_dio1, in_busy, None, None).unwrap();
+ let config = Config {
+ chip: Sx1262,
+ tcxo_ctrl: Some(TcxoCtrlVoltage::Ctrl1V8),
+ use_dcdc: true,
+ rx_boost: true,
+ };
+
+ let lora: RadioImpl = LoRa::new(Sx126x::new(spi_dev, iv, config), false, Delay)
+ .await
+ .unwrap();
+
+ Radio(lora)
+}
+
+#[embassy_executor::task]
+pub async fn task(mut radio: Radio) {
+ t114_meshcore_example::radio_task(&mut radio.0).await;
+}