diff --git a/esp32/.cargo/config.toml b/esp32/.cargo/config.toml new file mode 100644 index 0000000..0b3ebe5 --- /dev/null +++ b/esp32/.cargo/config.toml @@ -0,0 +1,9 @@ + +[target.xtensa-esp32-none-elf] +runner = "espflash flash --monitor" + +[build] +target = "xtensa-esp32-none-elf" + +[env] +DEFMT_LOG = "debug" diff --git a/esp32/.gitignore b/esp32/.gitignore new file mode 100644 index 0000000..eb5a316 --- /dev/null +++ b/esp32/.gitignore @@ -0,0 +1 @@ +target diff --git a/esp32/Cargo.lock b/esp32/Cargo.lock new file mode 100644 index 0000000..3c9e56d --- /dev/null +++ b/esp32/Cargo.lock @@ -0,0 +1,2116 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 4 + +[[package]] +name = "ag-lcd" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2d33be4690212133536fac4ad4eea4b313bf4df60b5d2a27f78e8303e36b93a7" +dependencies = [ + "embedded-hal 1.0.0", + "shared-bus", + "ufmt 0.1.2", +] + +[[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 = "aligned" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ee4508988c62edf04abd8d92897fca0c2995d907ce1dfeaf369dac3716a40685" +dependencies = [ + "as-slice", +] + +[[package]] +name = "arrayvec" +version = "0.7.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7c02d123df017efcdfbd739ef81735b36c5ba83ec3c59c80a9d7ecc718f92e50" + +[[package]] +name = "as-slice" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "516b6b4f0e40d50dcda9365d53964ec74560ad4284da2e7fc97122cd83174516" +dependencies = [ + "stable_deref_trait", +] + +[[package]] +name = "as5600" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5fdbe60b23e3ae22f4618c03b63aa884c4ca641830880f9d64b770d6467b4b7f" +dependencies = [ + "embedded-hal 1.0.0", + "num-derive", + "num-traits", +] + +[[package]] +name = "ascii-canvas" +version = "4.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ef1e3e699d84ab1b0911a1010c5c106aa34ae89aeac103be5ce0c3859db1e891" +dependencies = [ + "term", +] + +[[package]] +name = "autocfg" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c08606f8c3cbf4ce6ec8e28fb0014a2c086708fe954eaa885384a6165172e7e8" + +[[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", +] + +[[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 = "bitflags" +version = "1.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" + +[[package]] +name = "bitflags" +version = "2.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c4512299f36f043ab09a583e57bceb5a5aab7a73db1805848e8fef3c9e8c78b3" + +[[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.0.1", + "embassy-sync 0.8.0", + "embedded-io 0.7.1", + "embedded-io-async 0.7.0", + "futures-intrusive", + "heapless 0.9.2", +] + +[[package]] +name = "btuuid" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f5f48f1e9b0aad0a4f05d17bdeae0fa20ff798e272a03a6940ca27ad9c5a6ae7" +dependencies = [ + "defmt 0.3.100", +] + +[[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 = "cc" +version = "1.2.61" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d16d90359e986641506914ba71350897565610e87ce0ad9e6f28569db3dd5c6d" +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.44" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c673075a2e0e5f4a1dde27ce9dee1ea4558c7ffe648f576438a20ca1d2acc4b0" +dependencies = [ + "defmt 1.0.1", + "num-traits", + "pure-rust-locales", +] + +[[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 = "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 = "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 = "cyw43" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "033e856bf6f38c96fee3e3f398cceff0ca2c2fae5db255bcd23495216c7047da" +dependencies = [ + "aligned", + "bt-hci", + "cortex-m", + "cortex-m-rt", + "defmt 1.0.1", + "embassy-futures", + "embassy-net-driver-channel 0.4.0", + "embassy-sync 0.8.0", + "embassy-time", + "embedded-hal 1.0.0", + "embedded-hal-async", + "embedded-io-async 0.7.0", + "futures", + "heapless 0.9.2", +] + +[[package]] +name = "cyw43-pio" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "768b74f36be804f7b1020938e711d91c0ab5a847cf620d3756245ae7e641e1e2" +dependencies = [ + "cyw43", + "defmt 1.0.1", + "embassy-rp", + "fixed", +] + +[[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 = "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.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", +] + +[[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.15.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "48c757948c5ede0e46177b7add2e67155f70e33c07fea8284df6576da70b3719" + +[[package]] +name = "embassy-embedded-hal" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b0641612053b2f34fc250bb63f6630ae75de46e02ade7f457268447081d709ce" +dependencies = [ + "embassy-futures", + "embassy-hal-internal 0.4.0", + "embassy-sync 0.8.0", + "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.0.1", + "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", + "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.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.0.1", + "num-traits", +] + +[[package]] +name = "embassy-net" +version = "0.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "347bc855bdbdf50ed9c5a1d80e8204badb0ba149b8732dde38e1e9708ed9d313" +dependencies = [ + "defmt 1.0.1", + "document-features", + "embassy-net-driver", + "embassy-sync 0.8.0", + "embassy-time", + "embedded-io-async 0.7.0", + "embedded-nal-async", + "heapless 0.9.2", + "managed", + "smoltcp", +] + +[[package]] +name = "embassy-net-driver" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "524eb3c489760508f71360112bca70f6e53173e6fe48fc5f0efd0f5ab217751d" +dependencies = [ + "defmt 0.3.100", +] + +[[package]] +name = "embassy-net-driver-channel" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b7b2739fbcf6cd206ae08779c7d709087b16577d255f2ea4a45bc4bbbf305b3f" +dependencies = [ + "embassy-futures", + "embassy-net-driver", + "embassy-sync 0.7.2", +] + +[[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 0.8.0", +] + +[[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.0.1", + "document-features", + "embassy-embedded-hal", + "embassy-futures", + "embassy-hal-internal 0.5.0", + "embassy-sync 0.8.0", + "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.7.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "73974a3edbd0bd286759b3d483540f0ebef705919a5f56f4fc7709066f71689b" +dependencies = [ + "cfg-if", + "critical-section", + "embedded-io-async 0.6.1", + "futures-core", + "futures-sink", + "heapless 0.8.0", +] + +[[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", + "embedded-io-async 0.7.0", + "futures-core", + "futures-sink", + "heapless 0.9.2", +] + +[[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.0.1", + "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.2", +] + +[[package]] +name = "embassy-usb" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dc4462e48b19a4f401a11901bdd981aab80c6a826608016a0bdc73cbbab31954" +dependencies = [ + "embassy-futures", + "embassy-net-driver-channel 0.3.2", + "embassy-sync 0.7.2", + "embassy-usb-driver", + "embedded-io-async 0.6.1", + "heapless 0.8.0", + "ssmarshal", + "usbd-hid", +] + +[[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 0.6.1", +] + +[[package]] +name = "embassy-usb-logger" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "deed6d36715838d6adbbff13b215b03a9deeaa66a64d5fccd6353708ccfb8b8f" +dependencies = [ + "embassy-futures", + "embassy-sync 0.7.2", + "embassy-usb", + "log", +] + +[[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-compat" +version = "0.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "08ecac72f6be75ad2d4809c9f07d45502e2e5c9a4e9579077f28d7135de81df3" +dependencies = [ + "embedded-hal 0.2.7", + "embedded-hal 1.0.0", + "nb 1.1.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.0.1", +] + +[[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.0.1", + "embedded-io 0.7.1", +] + +[[package]] +name = "embedded-nal" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c56a28be191a992f28f178ec338a0bf02f63d7803244add736d026a471e6ed77" +dependencies = [ + "nb 1.1.0", +] + +[[package]] +name = "embedded-nal-async" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eb5a1bd585135d302f8f6d7de329310938093da6271b37a6c94b8798795c0c6d" +dependencies = [ + "embedded-io-async 0.7.0", + "embedded-nal", +] + +[[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 = "equivalent" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "877a4ace8713b0bcf2a4e7eec82529c029f1d0619886d18145fea96c3ffe5c0f" + +[[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 = "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", +] + +[[package]] +name = "generator" +version = "0.8.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "52f04ae4152da20c76fe800fa48659201d5cf627c5149ca0b707b69d7eef6cf9" +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", +] + +[[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 = "hashbrown" +version = "0.13.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "43a3c133739dddd0d2990f9a4bdf8eb4b21ef50e4851ca85ab661199821d510e" +dependencies = [ + "ahash", +] + +[[package]] +name = "hashbrown" +version = "0.17.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4f467dd6dccf739c208452f8014c75c18bb8301b050ad1cfb27153803edb0f51" + +[[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 = "heapless" +version = "0.9.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2af2455f757db2b292a9b1768c4b70186d443bcb3b316252d6b540aec1cd89ed" +dependencies = [ + "defmt 1.0.1", + "hash32", + "stable_deref_trait", +] + +[[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.0", +] + +[[package]] +name = "itertools" +version = "0.14.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2b192c782037fadd9cfa75548310488aabdbf3d2da73885b31bd0abd03351285" +dependencies = [ + "either", +] + +[[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.29" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5e5032e24019045c762d3c0f28f5b6b8bbf38563a65908389bf7978758920897" + +[[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 = "managed" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0ca88d725a0a943b096803bd34e73a4437208b6077654cc4ecb2947a5f91618d" + +[[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.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f8ca58f447f06ed17d5fc4043ce1b10dd205e060fb3ce5b979b8ed8e59ff3f79" + +[[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 = "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-derive" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ed3955f1a9c7c0c15e092f9c887db08b1fc683305fdf6eb6684f22555355e202" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.117", +] + +[[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 = "owned_str" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "57b42c259c35d8ad3e87b6dbedd4818b7b54a112f6370fdf11cd45d2f355d0f4" + +[[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 = "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 = "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" +version = "0.1.0" +dependencies = [ + "ag-lcd", + "arrayvec", + "as5600", + "cortex-m", + "cortex-m-rt", + "critical-section", + "cyw43", + "cyw43-pio", + "defmt 1.0.1", + "defmt-rtt", + "embassy-executor", + "embassy-futures", + "embassy-net", + "embassy-rp", + "embassy-sync 0.8.0", + "embassy-time", + "embassy-usb-logger", + "embedded-hal-compat", + "embedded-io 0.7.1", + "embedded-io-async 0.7.0", + "log", + "owned_str", + "panic-probe", + "portable-atomic", + "static_cell", + "ufmt 0.2.0", +] + +[[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 = "portable-atomic" +version = "1.13.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c33a9471896f1c69cecef8d20cbe2f7accd12527ce60845ff44c153bb2a21b49" +dependencies = [ + "critical-section", +] + +[[package]] +name = "precomputed-hash" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "925383efa346730478fb4838dbe9137d2a47675ad789c546d150a6e1dd4ab31c" + +[[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-hack" +version = "0.5.20+deprecated" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dc375e1527247fe1a97d8b7156678dfe7c1af2fc075c9a4db3690ecd2a148068" + +[[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.0.1", +] + +[[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_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.11.1", +] + +[[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 = "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 = "rustc_version" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "138e3e0acb6c9fb258b19b67cb8abd63c00679d2851805ea151465464fe9030a" +dependencies = [ + "semver", +] + +[[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 = "semver" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1d7eb9ef2c18661902cc47e535f9bc51b78acd254da71d375c2f6720d9a40403" +dependencies = [ + "semver-parser", +] + +[[package]] +name = "semver-parser" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "388a1df253eca08550bef6c72392cfe7c30914bf41df5269b68cbd6ff8f570a3" + +[[package]] +name = "serde" +version = "1.0.228" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9a8e94ea7f378bd32cbbd37198a4a91436180c5bb472411e48b5ec2e2124ae9e" +dependencies = [ + "serde_core", +] + +[[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 = "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 = "shared-bus" +version = "0.2.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "05f8438a40b91c8b9531c664e9680c55b92bd78cd6809a8b45b4512b1e5765f2" +dependencies = [ + "embedded-hal 0.2.7", + "nb 0.1.3", +] + +[[package]] +name = "shlex" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64" + +[[package]] +name = "siphasher" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b2aa850e253778c88a04c3d7323b043aeda9d3e30d5971937c1855769763678e" + +[[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 = "smoltcp" +version = "0.13.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5f73d40463bba65efc9adc6370b56df76d563cc46e2482bba58351b4afb7535e" +dependencies = [ + "bitflags 1.3.2", + "byteorder", + "cfg-if", + "defmt 0.3.100", + "heapless 0.9.2", + "managed", +] + +[[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 = "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 = "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 = "typenum" +version = "1.20.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "40ce102ab67701b8526c123c1bab5cbe42d7040ccfd0f64af1a385808d2f43de" + +[[package]] +name = "ufmt" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "31d3c0c63312dfc9d8e5c71114d617018a19f6058674003c0da29ee8d8036cdd" +dependencies = [ + "proc-macro-hack", + "ufmt-macros 0.2.0", + "ufmt-write", +] + +[[package]] +name = "ufmt" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1a64846ec02b57e9108d6469d98d1648782ad6bb150a95a9baac26900bbeab9d" +dependencies = [ + "ufmt-macros 0.3.0", + "ufmt-write", +] + +[[package]] +name = "ufmt-macros" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e4ab6c92f30c996394a8bd525aef9f03ce01d0d7ac82d81902968057e37dd7d9" +dependencies = [ + "proc-macro-hack", + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "ufmt-macros" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d337d3be617449165cb4633c8dece429afd83f84051024079f97ad32a9663716" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "ufmt-write" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e87a2ed6b42ec5e28cc3b94c09982969e9227600b2e3dcbc1db927a84c06bd69" + +[[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 = "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 = [ + "heapless 0.8.0", + "portable-atomic", +] + +[[package]] +name = "usbd-hid" +version = "0.8.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e6f291ab53d428685cc780f08a2eb9d5d6ff58622db2b36e239a4f715f1e184c" +dependencies = [ + "serde", + "ssmarshal", + "usb-device", + "usbd-hid-macros", +] + +[[package]] +name = "usbd-hid-descriptors" +version = "0.8.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0eee54712c5d778d2fb2da43b1ce5a7b5060886ef7b09891baeb4bf36910a3ed" +dependencies = [ + "bitfield 0.14.0", +] + +[[package]] +name = "usbd-hid-macros" +version = "0.8.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bb573c76e7884035ac5e1ab4a81234c187a82b6100140af0ab45757650ccda38" +dependencies = [ + "byteorder", + "hashbrown 0.13.2", + "log", + "proc-macro2", + "quote", + "serde", + "syn 1.0.109", + "usbd-hid-descriptors", +] + +[[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 = "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 = "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", +] diff --git a/esp32/Cargo.toml b/esp32/Cargo.toml new file mode 100644 index 0000000..be339de --- /dev/null +++ b/esp32/Cargo.toml @@ -0,0 +1,52 @@ +[package] +name = "pico" +version = "0.1.0" +edition = "2024" + + +[dependencies] +embedded-hal-compat = "0.13.0" +embassy-usb-logger = "0.5.1" +ufmt = "0.2.0" +log = "0.4" +ag-lcd={ version = "0.3", features = ["ufmt"]} +as5600 = "0.8.0" +embassy-futures = "0.1.2" +embedded-io-async = "0.7.0" +embedded-io = "0.7.1" +owned_str = "0.1.2" +embassy-sync = "0.8.0" +arrayvec = { version = "0.7.6", default-features = false } +embassy-net = { version = "0.9.1",features = ["defmt", "icmp", "tcp", "udp", "raw", "dhcpv4", "medium-ethernet", "dns", "proto-ipv4", "proto-ipv6", "multicast"]} +embassy-executor = { version = "0.10.0", features = [ + "platform-cortex-m", + "executor-thread", + "executor-interrupt", + "defmt", +] } +embassy-rp = { version = "0.10.0", features = [ + "defmt", + "unstable-pac", + "time-driver", + "critical-section-impl", + "rp2040", +] } +embassy-time = { version = "0.5.1", features = [ + "defmt", + "defmt-timestamp-uptime", +] } + +cortex-m = { version = "0.7.7", features = ["inline-asm"] } +cortex-m-rt = "0.7.5" +critical-section = "1.2.0" +static_cell = "2.1.1" +portable-atomic = { version = "1.13.1", features = ["critical-section"] } + + +defmt = "1.0.1" +defmt-rtt = "1.1.0" + +panic-probe = { version = "1.0.0", features = ["print-defmt"] } + +cyw43 = { version = "0.7.0", features = ["defmt", "firmware-logs"] } +cyw43-pio = { version = "0.10.0", features = ["defmt"] } diff --git a/esp32/build.rs b/esp32/build.rs new file mode 100644 index 0000000..3f915f9 --- /dev/null +++ b/esp32/build.rs @@ -0,0 +1,36 @@ +//! 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=-Tlink-rp.x"); + println!("cargo:rustc-link-arg-bins=-Tdefmt.x"); +} diff --git a/esp32/elf2uf2.nix b/esp32/elf2uf2.nix new file mode 100644 index 0000000..a2185e7 --- /dev/null +++ b/esp32/elf2uf2.nix @@ -0,0 +1,26 @@ +{ lib, stdenv, rustPlatform, fetchFromGitHub, pkg-config, libudev-zero }: + +rustPlatform.buildRustPackage rec { + pname = "elf2uf2-rs"; + version = "2038e9a199101ee8a16d046a87136be2a607001d"; + + src = fetchFromGitHub { + owner = "JoNil"; + repo = pname; + rev = "${version}"; +# sha256 = "sha256-CHuTpnAnD4I5PY47sceSxfjGdPZznXWfARE4YBfYoIg="; +# sha256 = "sha256-tvjncEmVHFurhRtWN6m8JT0XIgrti4QTnZ2XioBtqxo="; + sha256 = "sha256-CHuTpnAnD4I5PY47sceSxfjGdPZznXWfARE4YBfYoIg="; + }; + + nativeBuildInputs = [ + pkg-config + ]; + + buildInputs = [ + libudev-zero + ]; + +# cargoHash = "sha256-OefAKK5rvh4HSHd26Pac4BSbcNO3ntqBReYepulV8Dk="; + cargoHash = "sha256-tvjncEmVHFurhRtWN6m8JT0XIgrti4QTnZ2XioBtqxo="; +} diff --git a/esp32/esp32_quiz/esp32_quiz.ino b/esp32/esp32_quiz/esp32_quiz.ino deleted file mode 100644 index 292cc8f..0000000 --- a/esp32/esp32_quiz/esp32_quiz.ino +++ /dev/null @@ -1,39 +0,0 @@ -#include -#include - -// LCD pins: RS, EN, D4, D5, D6, D7 -LiquidCrystal lcd(18, 19, 13, 14, 15, 26); - -const int LED_PIN = 2; // built-in LED on most ESP32 devkits - -void setup() { - Serial.begin(115200); - - // WiFi chip init (not connected yet) - WiFi.mode(WIFI_STA); - WiFi.disconnect(); - Serial.println("WiFi initialized"); - - // Let LCD power up before init (ESP32 boots faster than LCD expects) - delay(500); - lcd.begin(16, 2); - lcd.clear(); - - pinMode(LED_PIN, OUTPUT); -} - -void loop() { - Serial.println("led on!"); - digitalWrite(LED_PIN, HIGH); - delay(1000); - - lcd.clear(); - lcd.print("Test message!"); - - Serial.println("led off!"); - digitalWrite(LED_PIN, LOW); - delay(1000); - - lcd.clear(); - lcd.print("Test message2!"); -} diff --git a/esp32/firmware/43439A0.bin b/esp32/firmware/43439A0.bin new file mode 100644 index 0000000..a05482f Binary files /dev/null and b/esp32/firmware/43439A0.bin differ diff --git a/esp32/firmware/43439A0_clm.bin b/esp32/firmware/43439A0_clm.bin new file mode 100644 index 0000000..dc4ee02 Binary files /dev/null and b/esp32/firmware/43439A0_clm.bin differ diff --git a/esp32/firmware/nvram_rp2040.bin b/esp32/firmware/nvram_rp2040.bin new file mode 100644 index 0000000..7a24de5 Binary files /dev/null and b/esp32/firmware/nvram_rp2040.bin differ diff --git a/esp32/flake.lock b/esp32/flake.lock new file mode 100644 index 0000000..f5b3df2 --- /dev/null +++ b/esp32/flake.lock @@ -0,0 +1,130 @@ +{ + "nodes": { + "esp-rs": { + "inputs": { + "flake-parts": "flake-parts", + "nixpkgs": "nixpkgs" + }, + "locked": { + "lastModified": 1772358514, + "narHash": "sha256-EV0KKHtOmqFyAX4HakujCYwnX7ef+Hr8AKf73cd9n7s=", + "owner": "leighleighleigh", + "repo": "esp-rs-nix", + "rev": "8baa40f096e7f52a10e8438b0bd55ef5dc280164", + "type": "github" + }, + "original": { + "owner": "leighleighleigh", + "repo": "esp-rs-nix", + "type": "github" + } + }, + "flake-parts": { + "inputs": { + "nixpkgs-lib": "nixpkgs-lib" + }, + "locked": { + "lastModified": 1759362264, + "narHash": "sha256-wfG0S7pltlYyZTM+qqlhJ7GMw2fTF4mLKCIVhLii/4M=", + "owner": "hercules-ci", + "repo": "flake-parts", + "rev": "758cf7296bee11f1706a574c77d072b8a7baa881", + "type": "github" + }, + "original": { + "owner": "hercules-ci", + "repo": "flake-parts", + "type": "github" + } + }, + "nixpkgs": { + "locked": { + "lastModified": 1760038930, + "narHash": "sha256-Oncbh0UmHjSlxO7ErQDM3KM0A5/Znfofj2BSzlHLeVw=", + "owner": "NixOS", + "repo": "nixpkgs", + "rev": "0b4defa2584313f3b781240b29d61f6f9f7e0df3", + "type": "github" + }, + "original": { + "owner": "NixOS", + "ref": "nixos-unstable", + "repo": "nixpkgs", + "type": "github" + } + }, + "nixpkgs-lib": { + "locked": { + "lastModified": 1754788789, + "narHash": "sha256-x2rJ+Ovzq0sCMpgfgGaaqgBSwY+LST+WbZ6TytnT9Rk=", + "owner": "nix-community", + "repo": "nixpkgs.lib", + "rev": "a73b9c743612e4244d865a2fdee11865283c04e6", + "type": "github" + }, + "original": { + "owner": "nix-community", + "repo": "nixpkgs.lib", + "type": "github" + } + }, + "nixpkgs_2": { + "locked": { + "lastModified": 1777383249, + "narHash": "sha256-b6T90GXUr21iIu6Aw+KGy5uSiB/cVT/UecId1YSESys=", + "owner": "NixOS", + "repo": "nixpkgs", + "rev": "61a7520db583d9b41be602b4c1e1b1b1b1faa1f4", + "type": "github" + }, + "original": { + "owner": "NixOS", + "repo": "nixpkgs", + "type": "github" + } + }, + "nixpkgs_3": { + "locked": { + "lastModified": 1744536153, + "narHash": "sha256-awS2zRgF4uTwrOKwwiJcByDzDOdo3Q1rPZbiHQg/N38=", + "owner": "NixOS", + "repo": "nixpkgs", + "rev": "18dd725c29603f582cf1900e0d25f9f1063dbf11", + "type": "github" + }, + "original": { + "owner": "NixOS", + "ref": "nixpkgs-unstable", + "repo": "nixpkgs", + "type": "github" + } + }, + "root": { + "inputs": { + "esp-rs": "esp-rs", + "nixpkgs": "nixpkgs_2", + "rust-overlay": "rust-overlay" + } + }, + "rust-overlay": { + "inputs": { + "nixpkgs": "nixpkgs_3" + }, + "locked": { + "lastModified": 1777346187, + "narHash": "sha256-oVxyGjpiIsrXhWTJVUOs38fZQkLjd0nZGOY9K7Kfot8=", + "owner": "oxalica", + "repo": "rust-overlay", + "rev": "146e7bf7569b8288f24d41d806b9f584f7cfd5b5", + "type": "github" + }, + "original": { + "owner": "oxalica", + "repo": "rust-overlay", + "type": "github" + } + } + }, + "root": "root", + "version": 7 +} diff --git a/esp32/flake.nix b/esp32/flake.nix new file mode 100644 index 0000000..0d8d30c --- /dev/null +++ b/esp32/flake.nix @@ -0,0 +1,49 @@ +{ + inputs = { + nixpkgs.url = "github:NixOS/nixpkgs"; + rust-overlay.url = "github:oxalica/rust-overlay"; + esp-rs.url = "github:leighleighleigh/esp-rs-nix"; + }; + + outputs = + { + self, + rust-overlay, + nixpkgs, + esp-rs, + }: + let + overlays = [ (import rust-overlay) ]; + pkgs = import nixpkgs { + system = "x86_64-linux"; + inherit overlays; + }; + in + { + packages.x86_64-linux.elf2uf2-rs = pkgs.callPackage ./elf2uf2.nix { }; + devShell.x86_64-linux = pkgs.mkShell { + buildInputs = with pkgs; [ + espflash + esptool + esp-rs.packages.${system}.default + cargo-espmonitor + # (pkgs.rust-bin.selectLatestNightlyWith ( + # toolchain: + # toolchain.default.override { + # targets = [ + # "thumbv6m-none-eabi" + # "xtensa-esp32-none-eabi" + # ]; + # extensions = [ "rust-src" ]; + # } + # )) + pkgs.rust-analyzer + pkgs.flip-link + pkgs.probe-rs-tools + self.packages.x86_64-linux.elf2uf2-rs + pkgs.rustfmt + # pkgs.picotool + ]; + }; + }; +} diff --git a/esp32/memory.x b/esp32/memory.x new file mode 100644 index 0000000..ef19dff --- /dev/null +++ b/esp32/memory.x @@ -0,0 +1,17 @@ +MEMORY { + BOOT2 : ORIGIN = 0x10000000, LENGTH = 0x100 + FLASH : ORIGIN = 0x10000100, LENGTH = 2048K - 0x100 + + /* Pick one of the two options for RAM layout */ + + /* OPTION A: Use all RAM banks as one big block */ + /* Reasonable, unless you are doing something */ + /* really particular with DMA or other concurrent */ + /* access that would benefit from striping */ + RAM : ORIGIN = 0x20000000, LENGTH = 264K + + /* OPTION B: Keep the unstriped sections separate */ + /* RAM: ORIGIN = 0x20000000, LENGTH = 256K */ + /* SCRATCH_A: ORIGIN = 0x20040000, LENGTH = 4K */ + /* SCRATCH_B: ORIGIN = 0x20041000, LENGTH = 4K */ +} diff --git a/esp32/src/bin/logger.rs b/esp32/src/bin/logger.rs new file mode 100644 index 0000000..ed2333e --- /dev/null +++ b/esp32/src/bin/logger.rs @@ -0,0 +1,36 @@ +//! This example shows how to use USB (Universal Serial Bus) in the RP2040 chip. +//! +//! This creates the possibility to send log::info/warn/error/debug! to USB serial port. + +#![no_std] +#![no_main] + +use embassy_executor::Spawner; +use embassy_rp::bind_interrupts; +use embassy_rp::peripherals::USB; +use embassy_rp::usb::{Driver, InterruptHandler}; +use embassy_time::Timer; +use {defmt_rtt as _, panic_probe as _}; + +bind_interrupts!(struct Irqs { + USBCTRL_IRQ => InterruptHandler; +}); + +#[embassy_executor::task] +async fn logger_task(driver: Driver<'static, USB>) { + embassy_usb_logger::run!(1024, log::LevelFilter::Info, driver); +} + +#[embassy_executor::main] +async fn main(spawner: Spawner) { + let p = embassy_rp::init(Default::default()); + let driver = Driver::new(p.USB, Irqs); + spawner.spawn(logger_task(driver).unwrap()); + + let mut counter = 0; + loop { + counter += 1; + log::info!("Tick {}", counter); + Timer::after_secs(1).await; + } +} diff --git a/esp32/src/bin/scan.rs b/esp32/src/bin/scan.rs new file mode 100644 index 0000000..d9917a3 --- /dev/null +++ b/esp32/src/bin/scan.rs @@ -0,0 +1,101 @@ +//! This example uses the RP Pico W board Wifi chip (cyw43). +//! Scans Wifi for ssid names. + +#![no_std] +#![no_main] +#![allow(async_fn_in_trait)] + +use core::str; + +use cyw43::aligned_bytes; +use cyw43_pio::{DEFAULT_CLOCK_DIVIDER, PioSpi}; +use defmt::*; +use embassy_executor::Spawner; +use embassy_rp::gpio::{Level, Output}; +use embassy_rp::peripherals::{DMA_CH0, PIO0, USB}; +use embassy_rp::pio::{InterruptHandler, Pio}; +use embassy_rp::{bind_interrupts, dma, usb}; +use embassy_time::Timer; +use static_cell::StaticCell; +use {defmt_rtt as _, panic_probe as _}; + +bind_interrupts!(struct Irqs { + PIO0_IRQ_0 => InterruptHandler; + USBCTRL_IRQ => usb::InterruptHandler; + DMA_IRQ_0 => dma::InterruptHandler; +}); + +#[embassy_executor::task] +async fn cyw43_task( + runner: cyw43::Runner<'static, cyw43::SpiBus, PioSpi<'static, PIO0, 0>>>, +) -> ! { + runner.run().await +} +#[embassy_executor::task] +async fn logger_task(usb: embassy_rp::Peri<'static, embassy_rp::peripherals::USB>) { + let driver = embassy_rp::usb::Driver::new(usb, Irqs); + + embassy_usb_logger::run!(1024, log::LevelFilter::Info, driver); +} +#[embassy_executor::task] +async fn periodic_log() { + loop { + info!("periodic log"); + Timer::after_millis(1000).await; + } +} + +#[embassy_executor::main] +async fn main(spawner: Spawner) { + let p = embassy_rp::init(Default::default()); + spawner.spawn(unwrap!(logger_task(p.USB))); + spawner.spawn(unwrap!(periodic_log())); + + info!("Hello World!"); + + let fw = aligned_bytes!("../../firmware/43439A0.bin"); + let clm = aligned_bytes!("../../firmware/43439A0_clm.bin"); + let nvram = aligned_bytes!("../../firmware/nvram_rp2040.bin"); + + // To make flashing faster for development, you may want to flash the firmwares independently + // at hardcoded addresses, instead of baking them into the program with `include_bytes!`: + // probe-rs download 43439A0.bin --binary-format bin --chip RP2040 --base-address 0x10100000 + // probe-rs download 43439A0_clm.bin --binary-format bin --chip RP2040 --base-address 0x10140000 + //let fw = unsafe { core::slice::from_raw_parts(0x10100000 as *const u8, 230321) }; + //let clm = unsafe { core::slice::from_raw_parts(0x10140000 as *const u8, 4752) }; + + let pwr = Output::new(p.PIN_23, Level::Low); + let cs = Output::new(p.PIN_25, Level::High); + let mut pio = Pio::new(p.PIO0, Irqs); + let spi = PioSpi::new( + &mut pio.common, + pio.sm0, + DEFAULT_CLOCK_DIVIDER, + pio.irq0, + cs, + p.PIN_24, + p.PIN_29, + dma::Channel::new(p.DMA_CH0, Irqs), + ); + + static STATE: StaticCell = StaticCell::new(); + let state = STATE.init(cyw43::State::new()); + let (_net_device, mut control, runner) = cyw43::new(state, pwr, spi, fw, nvram).await; + spawner.spawn(unwrap!(cyw43_task(runner))); + + control.init(clm).await; + control + .set_power_management(cyw43::PowerManagementMode::PowerSave) + .await; + + loop { + info!("scan loop"); + let mut scanner = control.scan(Default::default()).await; + while let Some(bss) = scanner.next().await { + if let Ok(ssid_str) = str::from_utf8(&bss.ssid) { + info!("scanned {} == {:x}", ssid_str, bss.bssid); + } + } + Timer::after_millis(1000).await; + } +} diff --git a/esp32/src/buffer.rs b/esp32/src/buffer.rs new file mode 100644 index 0000000..df0ac3c --- /dev/null +++ b/esp32/src/buffer.rs @@ -0,0 +1,63 @@ +use core::{convert::Infallible, fmt::Display, ops::Deref}; + +use arrayvec::ArrayVec; +use embassy_futures::yield_now; +use embassy_net::Stack; + +pub struct WriteBuffer(ArrayVec); + +impl Display for WriteBuffer { + fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { + f.write_str(str::from_utf8(self).map_err(|_| core::fmt::Error)?) + } +} + +impl Deref for WriteBuffer { + type Target = [u8]; + + fn deref(&self) -> &Self::Target { + &self.0 + } +} + +impl WriteBuffer { + pub fn new() -> Self { + Self(ArrayVec::new()) + } + + pub fn clear(&mut self) { + self.0.clear(); + } +} + +impl embedded_io::ErrorType for WriteBuffer { + type Error = Infallible; +} + +impl embedded_io::Write for WriteBuffer { + #[inline] + fn write(&mut self, buf: &[u8]) -> Result { + let _ = self.0.try_extend_from_slice(buf); //silently fails! + Ok(buf.len()) + } + + #[inline] + fn write_all(&mut self, buf: &[u8]) -> Result<(), Self::Error> { + self.write(buf)?; + Ok(()) + } + + #[inline] + fn flush(&mut self) -> Result<(), Self::Error> { + Ok(()) + } +} + +pub async fn wait_for_config(stack: Stack<'static>) -> embassy_net::StaticConfigV4 { + loop { + if let Some(config) = stack.config_v4() { + return config.clone(); + } + yield_now().await; + } +} diff --git a/esp32/src/input.rs b/esp32/src/input.rs new file mode 100644 index 0000000..8bf35d9 --- /dev/null +++ b/esp32/src/input.rs @@ -0,0 +1,90 @@ +use as5600::As5600; +use embassy_executor::Spawner; +use embassy_rp::{ + Peri, + gpio::{AnyPin, Input}, + i2c::{Config, I2c}, + peripherals::{I2C0, PIN_4, PIN_5}, +}; +use embassy_sync::{blocking_mutex::raw::CriticalSectionRawMutex, channel::Channel, mutex::Mutex}; +use embassy_time::{Duration, Timer}; +use ufmt::uwrite; + +use crate::{Irqs, WHEEL_VALUE, screen::SCREEN_BUFFER, unwrap}; + +/// Button input notification channel +pub static INPUT: Channel = Channel::new(); + +#[embassy_executor::task(pool_size = 4)] +/// Polls a single pin for falling edge (assumes buttons are pulled up and shorted when pressed) +/// Sends [INPUT] with given id +pub async fn button_poll_task(mut button: Input<'static>, id: u8) { + loop { + button.wait_for_falling_edge().await; + INPUT.send(id).await; + // uwrite!(SCREEN_BUFFER.lock().await.line1(), "btn {}", id); + Timer::after(Duration::from_millis(50)).await; + } +} + +pub static ANGLE: Mutex = Mutex::new(0); + +#[embassy_executor::task] +pub async fn rotation_read_task( + i2c: Peri<'static, I2C0>, + scl: Peri<'static, PIN_5>, + sda: Peri<'static, PIN_4>, +) { + let i2c = I2c::new_async(i2c, scl, sda, Irqs, Config::default()); + let mut as5600 = As5600::new(i2c); + + loop { + Timer::after(Duration::from_millis(50)).await; + let angle = as5600.angle().unwrap_or(0); + let mut locked = ANGLE.lock().await; + let old = *locked as i32; + *locked = angle; + drop(locked); + let left_diff = old - angle as i32; + let right_diff = angle as i32 - old; + let diff = if left_diff.abs() < right_diff.abs() { + -left_diff + } else { + right_diff + }; + let mut wheel = WHEEL_VALUE.lock().await; + if wheel.max != wheel.min { + let wheel_range = wheel.max - wheel.min; + wheel.value += diff * wheel_range / 4096; + if wheel.value < wheel.min { + wheel.value = wheel.min; + } else if wheel.value > wheel.max { + wheel.value = wheel.max; + } + } + drop(wheel); + } +} + +pub struct InputConfig { + pub i2c0: Peri<'static, I2C0>, + pub scl: Peri<'static, PIN_5>, + pub sda: Peri<'static, PIN_4>, + + pub button_pins: [(Peri<'static, AnyPin>, u8); 4], +} + +pub fn setup(spawner: Spawner, config: InputConfig) { + spawner.spawn(unwrap!(rotation_read_task( + config.i2c0, + config.scl, + config.sda, + ))); + + for (pin, id) in config.button_pins { + spawner.spawn(unwrap!(button_poll_task( + Input::new(pin, embassy_rp::gpio::Pull::Up), + id, + ))); + } +} diff --git a/esp32/src/main.rs b/esp32/src/main.rs new file mode 100644 index 0000000..b856ebb --- /dev/null +++ b/esp32/src/main.rs @@ -0,0 +1,312 @@ +#![no_std] +#![no_main] + +use core::str::FromStr; + +use embassy_net::tcp::{TcpReader, TcpWriter}; +use embassy_rp::multicore::{Stack, spawn_core1}; +use embassy_sync::blocking_mutex::raw::CriticalSectionRawMutex; +use embassy_sync::mutex::Mutex; +use embassy_sync::signal::Signal; +use embedded_io::Write; +use log::info; +use owned_str::OwnedStr; +use ufmt::uwrite; + +use crate::buffer::WriteBuffer; +use crate::input::{ANGLE, INPUT, InputConfig}; +use crate::net::network_setup_task; +use crate::owned_str_writer::{OwnedStrWriter, center_str}; +use crate::screen::{lcd_display_task, overwrite_lcd}; +use ag_lcd::{Blink, Cursor, Display, LcdDisplay}; +use defmt::*; +use embassy_executor::{Executor, Spawner}; +use embassy_rp::gpio::{Level, Output}; +use embassy_rp::i2c::{self}; +use embassy_rp::peripherals::{DMA_CH0, I2C0, PIO0}; +use embassy_rp::pio::InterruptHandler; +use embassy_rp::{bind_interrupts, dma}; +use embassy_rp::{peripherals::USB, usb}; +use embassy_time::{Delay, Timer}; +use static_cell::StaticCell; + +use {defmt_rtt as _, panic_probe as _}; + +mod buffer; +mod input; +mod net; +mod owned_str_writer; +mod screen; + +const WIFI_NETWORK: &str = "flamme"; +const WIFI_PASSWORD: &str = "12345678"; +const TARGET_IP: &str = "84.238.32.253"; +const TARGET_PORT: u16 = 7070; + +bind_interrupts!(struct Irqs { + PIO0_IRQ_0 => InterruptHandler; + DMA_IRQ_0 => dma::InterruptHandler; + USBCTRL_IRQ => usb::InterruptHandler; + I2C0_IRQ => i2c::InterruptHandler; +}); + +#[embassy_executor::task] +async fn logger_task(usb: embassy_rp::Peri<'static, embassy_rp::peripherals::USB>) { + let driver = embassy_rp::usb::Driver::new(usb, Irqs); + + embassy_usb_logger::run!(1024, log::LevelFilter::Info, driver); +} + +enum QuestionType { + Choice, + Numeric { min: i32, max: i32 }, +} + +struct QuestionData { + text: OwnedStr<256>, + q_type: QuestionType, + points: i32, + generation: usize, +} + +#[derive(Clone, Copy)] +struct WheelData { + value: i32, + min: i32, + max: i32, +} + +static QUESTION: Mutex> = Mutex::new(None); +static QUESTION_UPDATE: Signal = Signal::new(); +static WHEEL_VALUE: Mutex = Mutex::new(WheelData { + value: 0, + min: 0, + max: 0, +}); + +pub async fn tcp_read_loop(mut read: TcpReader<'_>) { + let mut buf = [0u8; 1024]; + let mut generation = 1; + + while let Ok(len) = read.read(&mut buf).await { + if len == 0 { + break; + } + let Ok(str) = str::from_utf8(&buf[..len]) else { + continue; + }; + let mut counter = 0; + let mut question_data = None; + let mut future_wheel = WheelData { + value: 0, + min: 0, + max: 0, + }; + for line in str.lines() { + if line == "$$" { + counter = 1; + continue; + } + if counter == 1 { + let mut q_type = QuestionType::Choice; + let mut points = -1; + + for pairs in line.split(" ") { + let (key, value) = pairs.split_once("=").unwrap(); + if key == "type" { + q_type = if value == "choice" { + QuestionType::Choice + } else { + QuestionType::Numeric { min: -1, max: -1 } + }; + } + if key == "points" { + points = value.parse().unwrap(); + } + if key == "rangeMin" || key == "rangeMax" { + match q_type { + QuestionType::Choice => {} + QuestionType::Numeric { + ref mut min, + ref mut max, + } => { + if key == "rangeMin" { + *min = value.parse().unwrap(); + future_wheel.min = *min; + } else { + *max = value.parse().unwrap(); + future_wheel.max = *max; + } + } + } + } + } + + match q_type { + QuestionType::Numeric { min, max } => { + let diff = max - min; + future_wheel.value = min + diff / 2; + } + _ => {} + } + + question_data = Some(QuestionData { + text: OwnedStr::new(), + q_type, + points, + generation, + }); + counter = 2; + continue; + } + if counter == 2 { + question_data.as_mut().unwrap().text = OwnedStr::from_str(line).unwrap(); + generation += 1; + counter = 0; + } + } + + if let Some(question_data) = question_data { + *QUESTION.lock().await = Some(question_data); + *WHEEL_VALUE.lock().await = future_wheel; + QUESTION_UPDATE.signal(()); + } + } +} + +pub async fn tcp_write_loop(mut write: TcpWriter<'_>) { + let mut buffer = WriteBuffer::<256>::new(); + loop { + let data = INPUT.receive().await; + info!("button={}", data); + let angle = *ANGLE.lock().await; + core::writeln!(buffer, "button={} angle={}", data, angle).ok(); + info!("write: {}", &buffer); + write.write(&buffer).await.ok(); + buffer.clear(); + } +} + +const ARROW_RIGHT: char = char::from_u32(0b0111_1110).unwrap(); +const ARROW_LEFT: char = char::from_u32(0b0111_1111).unwrap(); +const DOT: char = char::from_u32(0b1010_0101).unwrap(); + +#[embassy_executor::task] +pub async fn main_loop() { + let mut last_gen = 0; + let mut title_offset = 0; + info!("Main loop started"); + loop { + Timer::after_millis(50).await; + let wheel = *WHEEL_VALUE.lock().await; + let question = QUESTION.lock().await; + let Some(question) = question.as_ref() else { + continue; + }; + title_offset += 1; + if question.generation != last_gen { + last_gen = question.generation; + title_offset = 0; + } + let title_line = if question.text.len() > 16 { + title_offset %= question.text.len() - 16; + &question.text[title_offset..title_offset + 16] + } else { + &question.text + }; + let number_str: OwnedStr<16> = match question.q_type { + QuestionType::Choice => { + let mut writer = OwnedStrWriter::new(); + writer.push(DOT).unwrap(); + writer.push(' ').unwrap(); + uwrite!(writer, "{}", question.points).unwrap(); + writer.into() + } + QuestionType::Numeric { min, max } => { + let mut writer = OwnedStrWriter::new(); + if wheel.value > min { + writer.push(ARROW_LEFT).unwrap(); + writer.push(' ').unwrap(); + } + uwrite!(writer, "{}", wheel.value).unwrap(); + if wheel.value < max { + writer.push(ARROW_RIGHT).unwrap(); + writer.push(' ').unwrap(); + } + + writer.into() + } + }; + let second_line = center_str::<16>(&number_str, 16).unwrap(); + info!("lcd: {} {}", title_line, second_line); + overwrite_lcd(title_line, &second_line).await; + } +} + +static mut CORE1_STACK: Stack<4096> = Stack::new(); +// static EXECUTOR0: StaticCell = StaticCell::new(); +static EXECUTOR1: StaticCell = StaticCell::new(); + +// #[cortex_m_rt::entry] + +#[embassy_executor::main] +async fn main(spawner: Spawner) -> () { + let p = embassy_rp::init(Default::default()); + + let lcd: LcdDisplay<_, _> = LcdDisplay::new( + Output::new(p.PIN_10, Level::Low), + Output::new(p.PIN_11, Level::Low), + Delay, + ) + .with_half_bus( + Output::new(p.PIN_12, Level::Low), + Output::new(p.PIN_13, Level::Low), + Output::new(p.PIN_14, Level::Low), + Output::new(p.PIN_15, Level::Low), + ) + .with_autoscroll(ag_lcd::AutoScroll::Off) + .with_display(Display::On) + .with_blink(Blink::On) + .with_cursor(Cursor::On) + .with_lines(ag_lcd::Lines::TwoLines); + + spawn_core1( + p.CORE1, + unsafe { &mut *core::ptr::addr_of_mut!(CORE1_STACK) }, + move || { + let executor1 = EXECUTOR1.init(Executor::new()); + executor1.run(|spawner| { + let mut lcd = lcd.build(); + lcd.set_blink(Blink::Off); + lcd.set_cursor(Cursor::Off); + spawner.spawn(unwrap!(lcd_display_task(lcd))); + }); + }, + ); + + // let executor0 = EXECUTOR0.init(Executor::new()); + // executor0.run(|spawner| { + spawner.spawn(unwrap!(logger_task(p.USB))); + spawner.spawn(unwrap!(network_setup_task( + p.PIN_23, p.PIN_25, p.PIO0, p.PIN_24, p.PIN_29, p.DMA_CH0, spawner + ))); + // let mut lcd = lcd.build(); + // lcd.set_blink(Blink::Off); + // lcd.set_cursor(Cursor::Off); + // spawner.spawn(unwrap!(lcd_display_task(lcd))); + crate::input::setup( + spawner, + InputConfig { + i2c0: p.I2C0, + scl: p.PIN_5, + sda: p.PIN_4, + button_pins: [ + (p.PIN_18.into(), 1), + (p.PIN_19.into(), 2), + (p.PIN_20.into(), 3), + (p.PIN_21.into(), 4), + ], + }, + ); + // }); +} diff --git a/esp32/src/net.rs b/esp32/src/net.rs new file mode 100644 index 0000000..d7dd4f9 --- /dev/null +++ b/esp32/src/net.rs @@ -0,0 +1,183 @@ +use core::net::SocketAddrV4; +use core::str::FromStr; +use embassy_futures::join::join; +use embassy_net::tcp::TcpSocket; + +use crate::buffer::wait_for_config; +use crate::screen::SCREEN_BUFFER; +use crate::{ + Irqs, TARGET_IP, TARGET_PORT, WIFI_NETWORK, WIFI_PASSWORD, main_loop, tcp_read_loop, + tcp_write_loop, +}; +use cyw43::{JoinOptions, ScanOptions, aligned_bytes}; +use cyw43_pio::{DEFAULT_CLOCK_DIVIDER, PioSpi}; +use defmt::*; +use embassy_executor::Spawner; +use embassy_net::StackResources; +use embassy_rp::clocks::RoscRng; +use embassy_rp::gpio::{Level, Output}; +use embassy_rp::peripherals::{DMA_CH0, PIN_23, PIN_24, PIN_25, PIN_29, PIO0}; +use embassy_rp::pio::Pio; +use embassy_rp::{Peri, dma}; +use embassy_time::{Duration, Timer}; +use static_cell::StaticCell; +use ufmt::uwrite; + +#[embassy_executor::task] +async fn cyw43_task( + runner: cyw43::Runner<'static, cyw43::SpiBus, PioSpi<'static, PIO0, 0>>>, +) -> ! { + runner.run().await +} + +#[embassy_executor::task] +async fn net_task(mut runner: embassy_net::Runner<'static, cyw43::NetDriver<'static>>) -> ! { + runner.run().await +} + +#[embassy_executor::task] +pub async fn network_setup_task( + pin23: Peri<'static, PIN_23>, + pin25: Peri<'static, PIN_25>, + pio: Peri<'static, PIO0>, + pin24: Peri<'static, PIN_24>, + pin29: Peri<'static, PIN_29>, + dma: Peri<'static, DMA_CH0>, + spawner: Spawner, +) { + let fw = aligned_bytes!("../firmware/43439A0.bin"); + let clm = aligned_bytes!("../firmware/43439A0_clm.bin"); + let nvram = aligned_bytes!("../firmware/nvram_rp2040.bin"); + let mut rng = RoscRng; + + // To make flashing faster for development, you may want to flash the firmwares independently + // at hardcoded addresses, instead of baking them into the program with `include_bytes!`: + // probe-rs download ../../cyw43-firmware/43439A0.bin --binary-format bin --chip RP2040 --base-address 0x10100000 + // probe-rs download ../../cyw43-firmware/43439A0_clm.bin --binary-format bin --chip RP2040 --base-address 0x10140000 + //let fw = unsafe { core::slice::from_raw_parts(0x10100000 as *const u8, 230321) }; + //let clm = unsafe { core::slice::from_raw_parts(0x10140000 as *const u8, 4752) }; + + let pwr = Output::new(pin23, Level::Low); + let cs = Output::new(pin25, Level::High); + let mut pio = Pio::new(pio, Irqs); + let spi = PioSpi::new( + &mut pio.common, + pio.sm0, + DEFAULT_CLOCK_DIVIDER, + pio.irq0, + cs, + pin24, + pin29, + dma::Channel::new(dma, Irqs), + ); + + static STATE: StaticCell = StaticCell::new(); + let state = STATE.init(cyw43::State::new()); + let (net_device, mut control, runner) = cyw43::new(state, pwr, spi, fw, nvram).await; + spawner.spawn(unwrap!(cyw43_task(runner))); + + control.init(clm).await; + control + .set_power_management(cyw43::PowerManagementMode::Performance) + .await; + + static RESOURCES: StaticCell> = StaticCell::new(); + let (stack, runner) = embassy_net::new( + net_device, + embassy_net::Config::dhcpv4(Default::default()), + RESOURCES.init(StackResources::new()), + rng.next_u64(), + ); + spawner.spawn(unwrap!(net_task(runner))); + Timer::after_millis(1000).await; + uwrite!(SCREEN_BUFFER.lock().await.line1(), "con - scan"); + + info!("scan started"); + + let mut opts = ScanOptions::default(); + opts.scan_type = cyw43::ScanType::Active; + let mut scanner = control.scan(opts).await; + + while let Some(bss) = scanner.next().await { + let mut buf = SCREEN_BUFFER.lock().await; + if let Ok(ssid_str) = str::from_utf8(&bss.ssid) { + info!("scanned {} == {:x}", ssid_str, bss.bssid); + uwrite!(buf.line1(), "{}", ssid_str); + // uwrite!(buf.line2(), "{:x}", bss.bssid); + } else { + info!("scanned {:x}", bss.bssid); + uwrite!(buf.line1(), "not-utf8"); + // uwrite!(buf.line2(), "{:x}", bss.bssid); + } + drop(buf); + Timer::after_millis(500).await; + } + + info!("scan completed"); + + uwrite!(SCREEN_BUFFER.lock().await.line1(), "scan end."); + Timer::after_millis(500).await; + drop(scanner); + + while let Err(err) = control + .join(WIFI_NETWORK, JoinOptions::new(WIFI_PASSWORD.as_bytes())) + .await + { + let mut buf = SCREEN_BUFFER.lock().await; + buf.clear(); + match err { + cyw43::JoinError::AuthenticationFailure => { + uwrite!(buf.line1(), "join failure"); + uwrite!(buf.line2(), "bad password"); + info!("authentication failure"); + } + cyw43::JoinError::JoinFailure(e) => { + uwrite!(buf.line1(), "join failure"); + uwrite!(buf.line2(), "code {}", e); + info!("join failure: {}", e); + } + cyw43::JoinError::NetworkNotFound => { + uwrite!(buf.line1(), "join failure"); + uwrite!(buf.line2(), "wifi not found"); + info!("network not found"); + } + }; + Timer::after_millis(200).await; + } + + let mut buf = SCREEN_BUFFER.lock().await; + buf.clear(); + uwrite!(buf.line1(), "link."); + drop(buf); + + stack.wait_link_up().await; + + uwrite!(SCREEN_BUFFER.lock().await.line1(), "dhcp."); + + stack.wait_config_up().await; + let cfg = wait_for_config(stack).await; + let local_addr = cfg.address.address(); + info!("IP address: {:?}", local_addr); + + let host_addr = embassy_net::Ipv4Address::from_str(TARGET_IP).unwrap(); + let mut rx_buffer = [0; 4096]; + let mut tx_buffer = [0; 4096]; + let mut socket = TcpSocket::new(stack, &mut rx_buffer, &mut tx_buffer); + socket.set_timeout(Some(Duration::from_secs(10))); + socket.set_keep_alive(Some(Duration::from_secs(1))); + if let Err(e) = socket + .connect(SocketAddrV4::new(host_addr, TARGET_PORT)) + .await + { + uwrite!(SCREEN_BUFFER.lock().await.line1(), "tcperr"); + error!("tcp connect error: {}", e); + } else { + uwrite!(SCREEN_BUFFER.lock().await.line1(), "tcpok"); + } + + let (read, write) = socket.split(); + + spawner.spawn(unwrap!(main_loop())); + + join(tcp_read_loop(read), tcp_write_loop(write)).await; +} diff --git a/esp32/src/owned_str_writer.rs b/esp32/src/owned_str_writer.rs new file mode 100644 index 0000000..c740050 --- /dev/null +++ b/esp32/src/owned_str_writer.rs @@ -0,0 +1,50 @@ +use owned_str::{Error, OwnedStr}; +use ufmt::uWrite; + +pub struct OwnedStrWriter(OwnedStr); + +impl OwnedStrWriter { + pub fn new() -> Self { + Self(OwnedStr::new()) + } + + pub fn push(&mut self, c: char) -> Result<(), Error> { + self.0.try_push(c).map(|_| ()) + } +} + +impl From> for OwnedStrWriter { + fn from(owned_str: OwnedStr) -> Self { + Self(owned_str) + } +} + +impl From> for OwnedStr { + fn from(writer: OwnedStrWriter) -> Self { + writer.0 + } +} + +impl uWrite for OwnedStrWriter { + type Error = owned_str::Error; + fn write_str(&mut self, s: &str) -> Result<(), Self::Error> { + self.0.try_push_str(s).map(|_| ()) + } + fn write_char(&mut self, c: char) -> Result<(), Self::Error> { + self.0.try_push(c).map(|_| ()) + } +} + +pub fn center_str( + str: &str, + width: usize, +) -> Result, owned_str::Error> { + let mut res = OwnedStr::new(); + let len = str.len(); + let padding = (width.saturating_sub(len) + 1) / 2; + for _ in 0..padding { + res.try_push(' ')?; + } + res.try_push_str(str)?; + Ok(res) +} diff --git a/esp32/src/screen.rs b/esp32/src/screen.rs new file mode 100644 index 0000000..6be00ba --- /dev/null +++ b/esp32/src/screen.rs @@ -0,0 +1,103 @@ +use core::convert::Infallible; + +use ag_lcd::LcdDisplay; +use embassy_rp::gpio::Output; +use embassy_sync::{blocking_mutex::raw::CriticalSectionRawMutex, mutex::Mutex, signal::Signal}; +use embassy_time::{Delay, Timer}; +use ufmt::uWrite; + +pub struct ScreenBuffer { + line1: [u8; 16], + line2: [u8; 16], + line1_ptr: u8, + line2_ptr: u8, +} + +impl ScreenBuffer { + pub fn clear(&mut self) { + self.line1.fill(0); + self.line2.fill(0); + self.line1_ptr = 0; + self.line2_ptr = 0; + } + + pub fn line1(&mut self) -> ScreenBufferWriter<'_> { + ScreenBufferWriter { buf: self, line: 0 } + } + + pub fn line2(&mut self) -> ScreenBufferWriter<'_> { + ScreenBufferWriter { buf: self, line: 1 } + } +} + +pub struct ScreenBufferWriter<'a> { + buf: &'a mut ScreenBuffer, + line: u8, +} + +impl<'a> uWrite for ScreenBufferWriter<'a> { + type Error = Infallible; + + fn write_char(&mut self, c: char) -> Result<(), Self::Error> { + if self.line == 0 { + let ptr = self.buf.line1_ptr as usize; + self.buf.line1[ptr] = c as u8; + self.buf.line1_ptr = (self.buf.line1_ptr + 1) % 16; + } else { + let ptr = self.buf.line2_ptr as usize; + self.buf.line2[ptr] = c as u8; + self.buf.line2_ptr = (self.buf.line2_ptr + 1) % 16; + } + Ok(()) + } + + fn write_str(&mut self, s: &str) -> Result<(), Self::Error> { + for c in s.chars() { + self.write_char(c)?; + } + Ok(()) + } +} + +impl Drop for ScreenBufferWriter<'_> { + fn drop(&mut self) { + LCD_UPDATE.signal(()); + } +} + +pub static SCREEN_BUFFER: Mutex = Mutex::new(ScreenBuffer { + line1: [0; 16], + line1_ptr: 0, + line2: [0; 16], + line2_ptr: 0, +}); + +static LCD_UPDATE: Signal = Signal::new(); + +#[embassy_executor::task] +pub async fn lcd_display_task(mut lcd: LcdDisplay, Delay>) { + loop { + LCD_UPDATE.wait().await; + let buffer = SCREEN_BUFFER.lock().await; + lcd.clear(); + for byte in &buffer.line1 { + lcd.write(*byte); + } + lcd.set_position(0, 1); + for byte in &buffer.line2 { + lcd.write(*byte); + } + Timer::after_millis(20).await; + } +} + +pub async fn overwrite_lcd(line1: &str, line2: &str) { + let mut buffer = SCREEN_BUFFER.lock().await; + buffer.line1_ptr = 0; + buffer.line2_ptr = 0; + buffer.line1.fill(0); + buffer.line2.fill(0); + buffer.line1[..line1.len()].copy_from_slice(line1.as_bytes()); + buffer.line2[..line2.len()].copy_from_slice(line2.as_bytes()); + LCD_UPDATE.signal(()); +} diff --git a/pico/.cargo/config.toml b/pico/.cargo/config.toml index 9740544..90a37aa 100644 --- a/pico/.cargo/config.toml +++ b/pico/.cargo/config.toml @@ -2,11 +2,8 @@ # runner = "probe-rs run --chip RP2040" runner = "sudo picotool load -u -v -x -t elf" -[target.xtensa-esp32-none-elf] -runner = "espflash flash --monitor" - [build] -target = "xtensa-esp32-none-elf" +target = "thumbv6m-none-eabi" # Cortex-M0 and Cortex-M0 [env] DEFMT_LOG = "debug" diff --git a/pico/flake.nix b/pico/flake.nix index ba232f7..ab261ea 100644 --- a/pico/flake.nix +++ b/pico/flake.nix @@ -2,7 +2,6 @@ inputs = { nixpkgs.url = "github:NixOS/nixpkgs"; rust-overlay.url = "github:oxalica/rust-overlay"; - esp-rs.url = "github:leighleighleigh/esp-rs-nix"; }; outputs = @@ -10,7 +9,6 @@ self, rust-overlay, nixpkgs, - esp-rs, }: let overlays = [ (import rust-overlay) ]; @@ -23,14 +21,11 @@ packages.x86_64-linux.elf2uf2-rs = pkgs.callPackage ./elf2uf2.nix { }; devShell.x86_64-linux = pkgs.mkShell { buildInputs = with pkgs; [ - espflash - esptool (pkgs.rust-bin.selectLatestNightlyWith ( toolchain: toolchain.default.override { targets = [ "thumbv6m-none-eabi" - "xtensa-esp32-none-eabi" ]; extensions = [ "rust-src" ]; }