diff --git a/.gitignore b/.gitignore index 9c404369..6bb53369 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,5 @@ +nodes/esp32/airbox/cfg.toml + # Compiled source # ################### *.com @@ -64,7 +66,6 @@ __pycache__ debugToRemoteHost.sh hueBridgeLogin keys/ -data/ releaseToRemoteHost.sh specs/ userdb.hm @@ -72,3 +73,5 @@ userdb.hm # Rust # ##################### target/ +src/input/web_api/logins.rs +database/ diff --git a/Cargo.lock b/Cargo.lock index 5f4b5d6c..193761f8 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1,2939 +1,4275 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 3 + [[package]] -name = "HomeAutomation" -version = "0.1.0" +name = "addr2line" +version = "0.21.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8a30b2e23b9e17a9f90641c7ab1549cd9b44f296d3ccbf309d2863cfe398a0cb" dependencies = [ - "actix 0.7.9 (registry+https://github.com/rust-lang/crates.io-index)", - "actix-web 0.7.18 (registry+https://github.com/rust-lang/crates.io-index)", - "actix-web-httpauth 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", - "bme280 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", - "bytes 0.4.11 (registry+https://github.com/rust-lang/crates.io-index)", - "chrono 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", - "dataserver 0.1.0 (git+https://github.com/dskleingeld/dataserver?branch=as_lib)", - "futures 0.1.25 (registry+https://github.com/rust-lang/crates.io-index)", - "linux-embedded-hal 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", - "philipshue 0.3.2 (git+https://github.com/dskleingeld/philipshue)", - "serde 1.0.88 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_yaml 0.8.8 (registry+https://github.com/rust-lang/crates.io-index)", - "smallvec 0.6.9 (registry+https://github.com/rust-lang/crates.io-index)", - "sysfs_gpio 0.5.3 (git+https://github.com/rust-embedded/rust-sysfs-gpio)", - "tokio 0.1.15 (registry+https://github.com/rust-lang/crates.io-index)", + "gimli", ] [[package]] -name = "MacTypes-sys" -version = "2.1.0" +name = "adler" +version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "libc 0.2.49 (registry+https://github.com/rust-lang/crates.io-index)", -] +checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe" [[package]] -name = "acme-client" -version = "0.5.3" +name = "adler2" +version = "2.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "base64 0.9.3 (registry+https://github.com/rust-lang/crates.io-index)", - "clap 2.32.0 (registry+https://github.com/rust-lang/crates.io-index)", - "env_logger 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)", - "error-chain 0.12.0 (registry+https://github.com/rust-lang/crates.io-index)", - "foreign-types 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)", - "hyper 0.10.15 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)", - "openssl 0.10.18 (registry+https://github.com/rust-lang/crates.io-index)", - "openssl-sys 0.9.41 (registry+https://github.com/rust-lang/crates.io-index)", - "reqwest 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.88 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_derive 1.0.88 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_json 1.0.38 (registry+https://github.com/rust-lang/crates.io-index)", -] +checksum = "512761e0bb2578dd7380c6baaa0f4ce03e84f95e960231d1dec8bf4d7d6e2627" [[package]] -name = "actix" -version = "0.7.9" +name = "aho-corasick" +version = "1.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e60d3430d3a69478ad0993f19238d2df97c507009a52b3c10addcd7f6bcb916" dependencies = [ - "actix_derive 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)", - "bitflags 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)", - "bytes 0.4.11 (registry+https://github.com/rust-lang/crates.io-index)", - "crossbeam-channel 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", - "failure 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", - "fnv 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", - "futures 0.1.25 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.49 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", - "parking_lot 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)", - "smallvec 0.6.9 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio 0.1.15 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-codec 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-executor 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-io 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-reactor 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-signal 0.2.7 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-tcp 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-timer 0.2.10 (registry+https://github.com/rust-lang/crates.io-index)", - "trust-dns-proto 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)", - "trust-dns-resolver 0.10.3 (registry+https://github.com/rust-lang/crates.io-index)", - "uuid 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)", + "memchr", ] [[package]] -name = "actix-net" -version = "0.2.6" +name = "allocator-api2" +version = "0.2.21" source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "actix 0.7.9 (registry+https://github.com/rust-lang/crates.io-index)", - "bytes 0.4.11 (registry+https://github.com/rust-lang/crates.io-index)", - "futures 0.1.25 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", - "mio 0.6.16 (registry+https://github.com/rust-lang/crates.io-index)", - "net2 0.2.33 (registry+https://github.com/rust-lang/crates.io-index)", - "num_cpus 1.10.0 (registry+https://github.com/rust-lang/crates.io-index)", - "rustls 0.14.0 (registry+https://github.com/rust-lang/crates.io-index)", - "slab 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio 0.1.15 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-codec 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-current-thread 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-io 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-reactor 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-rustls 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-tcp 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-timer 0.2.10 (registry+https://github.com/rust-lang/crates.io-index)", - "tower-service 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", - "trust-dns-resolver 0.10.3 (registry+https://github.com/rust-lang/crates.io-index)", - "webpki 0.18.1 (registry+https://github.com/rust-lang/crates.io-index)", - "webpki-roots 0.15.0 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "actix-web" -version = "0.7.18" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "actix 0.7.9 (registry+https://github.com/rust-lang/crates.io-index)", - "actix-net 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)", - "base64 0.10.1 (registry+https://github.com/rust-lang/crates.io-index)", - "bitflags 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)", - "brotli2 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)", - "byteorder 1.3.1 (registry+https://github.com/rust-lang/crates.io-index)", - "bytes 0.4.11 (registry+https://github.com/rust-lang/crates.io-index)", - "cookie 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)", - "encoding 0.2.33 (registry+https://github.com/rust-lang/crates.io-index)", - "failure 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", - "flate2 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", - "futures 0.1.25 (registry+https://github.com/rust-lang/crates.io-index)", - "futures-cpupool 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)", - "h2 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)", - "http 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)", - "httparse 1.3.3 (registry+https://github.com/rust-lang/crates.io-index)", - "language-tags 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", - "lazy_static 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)", - "lazycell 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", - "mime 0.3.13 (registry+https://github.com/rust-lang/crates.io-index)", - "mime_guess 2.0.0-alpha.6 (registry+https://github.com/rust-lang/crates.io-index)", - "mio 0.6.16 (registry+https://github.com/rust-lang/crates.io-index)", - "net2 0.2.33 (registry+https://github.com/rust-lang/crates.io-index)", - "num_cpus 1.10.0 (registry+https://github.com/rust-lang/crates.io-index)", - "parking_lot 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)", - "percent-encoding 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)", - "rand 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)", - "regex 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", - "rustls 0.14.0 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.88 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_json 1.0.38 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_urlencoded 0.5.4 (registry+https://github.com/rust-lang/crates.io-index)", - "sha1 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)", - "slab 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", - "smallvec 0.6.9 (registry+https://github.com/rust-lang/crates.io-index)", - "time 0.1.42 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio 0.1.15 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-current-thread 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-io 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-reactor 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-rustls 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-tcp 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-timer 0.2.10 (registry+https://github.com/rust-lang/crates.io-index)", - "url 1.7.2 (registry+https://github.com/rust-lang/crates.io-index)", - "v_htmlescape 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)", - "version_check 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", - "webpki 0.18.1 (registry+https://github.com/rust-lang/crates.io-index)", - "webpki-roots 0.15.0 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "actix-web-httpauth" -version = "0.1.0" +checksum = "683d7910e743518b0e34f1186f92494becacb047c7b6bf616c96772180fef923" + +[[package]] +name = "anstream" +version = "0.6.18" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8acc5369981196006228e28809f761875c0327210a891e941f4c683b3a99529b" dependencies = [ - "actix-web 0.7.18 (registry+https://github.com/rust-lang/crates.io-index)", - "base64 0.9.3 (registry+https://github.com/rust-lang/crates.io-index)", - "bytes 0.4.11 (registry+https://github.com/rust-lang/crates.io-index)", + "anstyle", + "anstyle-parse", + "anstyle-query", + "anstyle-wincon", + "colorchoice", + "is_terminal_polyfill", + "utf8parse", ] [[package]] -name = "actix_derive" -version = "0.3.2" +name = "anstyle" +version = "1.0.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "55cc3b69f167a1ef2e161439aa98aed94e6028e5f9a59be9a6ffb47aef1651f9" + +[[package]] +name = "anstyle-parse" +version = "0.2.6" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3b2d16507662817a6a20a9ea92df6652ee4f94f914589377d69f3b21bc5798a9" dependencies = [ - "proc-macro2 0.4.27 (registry+https://github.com/rust-lang/crates.io-index)", - "quote 0.6.11 (registry+https://github.com/rust-lang/crates.io-index)", - "syn 0.15.26 (registry+https://github.com/rust-lang/crates.io-index)", + "utf8parse", ] [[package]] -name = "adler32" -version = "1.0.3" +name = "anstyle-query" +version = "1.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "79947af37f4177cfead1110013d678905c37501914fba0efea834c3fe9a8d60c" +dependencies = [ + "windows-sys 0.59.0", +] [[package]] -name = "aho-corasick" -version = "0.6.10" +name = "anstyle-wincon" +version = "3.0.7" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ca3534e77181a9cc07539ad51f2141fe32f6c3ffd4df76db8ad92346b003ae4e" dependencies = [ - "memchr 2.2.0 (registry+https://github.com/rust-lang/crates.io-index)", + "anstyle", + "once_cell", + "windows-sys 0.59.0", ] [[package]] -name = "ansi_term" -version = "0.11.0" +name = "approx" +version = "0.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cab112f0a86d568ea0e627cc1d6be74a1e9cd55214684db5561995f6dad897c6" dependencies = [ - "winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", + "num-traits", ] [[package]] -name = "antidote" -version = "1.0.0" +name = "arraydeque" +version = "0.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7d902e3d592a523def97af8f317b08ce16b7ab854c1985a0c671e6f15cebc236" [[package]] -name = "arc-swap" -version = "0.3.7" +name = "async-stdin" +version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b1ff8b5d9b5ec29e0f49583ba71847b8c8888b67a8510133048a380903aa6822" +dependencies = [ + "tokio", +] [[package]] -name = "arrayvec" -version = "0.4.10" +name = "async-throttle" +version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1c99532de164435a0b91279e715bff4fa0d164643b409a67761907ffc210ee8f" dependencies = [ - "nodrop 0.1.13 (registry+https://github.com/rust-lang/crates.io-index)", + "backoff", + "dashmap 5.5.3", + "tokio", ] [[package]] -name = "atty" -version = "0.2.11" +name = "atomic-polyfill" +version = "1.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8cf2bce30dfe09ef0bfaef228b9d414faaf7e563035494d7fe092dba54b300f4" dependencies = [ - "libc 0.2.49 (registry+https://github.com/rust-lang/crates.io-index)", - "termion 1.5.1 (registry+https://github.com/rust-lang/crates.io-index)", - "winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", + "critical-section", ] +[[package]] +name = "atomic-waker" +version = "1.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1505bd5d3d116872e7271a6d4e16d81d0c8570876c8de68093a09ac269d8aac0" + [[package]] name = "autocfg" -version = "0.1.2" +version = "1.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ace50bade8e6234aa140d9a2f552bbee1db4d353f69b8217bc503490fc1a9f26" [[package]] -name = "backtrace" -version = "0.3.14" +name = "backoff" +version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b62ddb9cb1ec0a098ad4bbf9344d0713fa193ae1a80af55febcff2627b6a00c1" dependencies = [ - "autocfg 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", - "backtrace-sys 0.1.28 (registry+https://github.com/rust-lang/crates.io-index)", - "cfg-if 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.49 (registry+https://github.com/rust-lang/crates.io-index)", - "rustc-demangle 0.1.13 (registry+https://github.com/rust-lang/crates.io-index)", - "winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", + "futures-core", + "getrandom 0.2.15", + "instant", + "pin-project-lite", + "rand 0.8.5", + "tokio", ] [[package]] -name = "backtrace-sys" -version = "0.1.28" +name = "backtrace" +version = "0.3.71" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "26b05800d2e817c8b3b4b54abd461726265fa9789ae34330622f2db9ee696f9d" dependencies = [ - "cc 1.0.29 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.49 (registry+https://github.com/rust-lang/crates.io-index)", + "addr2line", + "cc", + "cfg-if", + "libc", + "miniz_oxide 0.7.4", + "object", + "rustc-demangle", ] [[package]] name = "base64" -version = "0.9.3" +version = "0.21.7" source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "byteorder 1.3.1 (registry+https://github.com/rust-lang/crates.io-index)", - "safemem 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", -] +checksum = "9d297deb1925b89f2ccc13d7635fa0714f12c87adce1c75356b39ca9b7178567" [[package]] name = "base64" -version = "0.10.1" +version = "0.22.1" source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "byteorder 1.3.1 (registry+https://github.com/rust-lang/crates.io-index)", -] +checksum = "72b3254f16251a8381aa12e40e3c4d2f0199f8c6508fbecb9d91f575e0fbb8c6" [[package]] name = "bincode" -version = "1.1.2" +version = "1.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b1f45e9417d87227c7a56d22e471c6206462cba514c7590c09aff4cf6d1ddcad" dependencies = [ - "autocfg 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", - "byteorder 1.3.1 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.88 (registry+https://github.com/rust-lang/crates.io-index)", + "serde", ] [[package]] -name = "bitflags" -version = "0.3.3" +name = "bincode" +version = "2.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "36eaf5d7b090263e8150820482d5d93cd964a81e4019913c972f4edcc6edb740" +dependencies = [ + "serde", + "unty", +] [[package]] name = "bitflags" -version = "0.4.0" +version = "1.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" [[package]] name = "bitflags" -version = "0.9.1" +version = "2.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c8214115b7bf84099f1309324e63141d4c5d7cc26862f97a0a857dbefe165bd" +dependencies = [ + "serde", +] [[package]] -name = "bitflags" -version = "1.0.4" +name = "block-buffer" +version = "0.10.4" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3078c7629b62d3f0439517fa394996acacc5cbc91c5a20d8c658e77abd503a71" +dependencies = [ + "generic-array", +] [[package]] name = "bme280" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" +version = "0.5.1" +source = "git+https://github.com/dvdsk/bme280-rs#a147bfc93d73a827616121f194972d6cc9cb3d11" dependencies = [ - "embedded-hal 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", + "derive_more", + "embedded-hal", + "maybe-async-cfg", + "postcard", + "serde", ] [[package]] -name = "brotli-sys" -version = "0.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" +name = "brain" +version = "0.1.0" dependencies = [ - "cc 1.0.29 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.49 (registry+https://github.com/rust-lang/crates.io-index)", -] + "clap", + "color-eyre", + "data-server", + "dbstruct", + "futures", + "futures-concurrency", + "futures-util", + "jiff", + "logger", + "mpd", + "mpdrs", + "protocol", + "rand 0.9.0", + "serde", + "serde_yaml", + "sled", + "thiserror 2.0.12", + "tokio", + "tracing", + "zigbee-bridge", +] + +[[package]] +name = "bufstream" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "40e38929add23cdf8a366df9b0e088953150724bcbe5fc330b0d8eb3b328eec8" [[package]] -name = "brotli2" -version = "0.3.2" +name = "bumpalo" +version = "3.17.0" source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "brotli-sys 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.49 (registry+https://github.com/rust-lang/crates.io-index)", -] +checksum = "1628fb46dfa0b37568d12e5edd512553eccf6a22a78e8bde00bb4aed84d5bdbf" [[package]] -name = "build_const" -version = "0.2.1" +name = "bytemuck" +version = "1.22.0" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b6b1fc10dbac614ebc03540c9dbd60e83887fda27794998c6528f1782047d540" [[package]] name = "byteorder" -version = "1.3.1" +version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" [[package]] name = "bytes" -version = "0.4.11" +version = "1.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e748733b7cbc798e1434b6ac524f0c1ff2ab456fe201501e6497c8417a4fc33" + +[[package]] +name = "byteseries" +version = "0.7.1" +source = "git+https://github.com/dvdsk/byteseries?rev=a9da72e9585e5f5a8cc3cf543d6ca2561ad7007a#a9da72e9585e5f5a8cc3cf543d6ca2561ad7007a" dependencies = [ - "byteorder 1.3.1 (registry+https://github.com/rust-lang/crates.io-index)", - "iovec 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", + "arraydeque", + "itertools 0.13.0", + "num-traits", + "ron 0.8.1", + "serde", + "smallvec 2.0.0-alpha.11", + "thiserror 1.0.69", + "tracing", ] [[package]] -name = "cast" -version = "0.2.2" +name = "cassowary" +version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "df8670b8c7b9dae1793364eafadf7239c40d669904660c5960d74cfd80b46a53" [[package]] -name = "cc" -version = "1.0.29" +name = "cast" +version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "37b2a672a2cb129a2e41c10b1224bb368f9f37a2b16b612598138befd7b37eb5" [[package]] -name = "cfg-if" -version = "0.1.6" +name = "castaway" +version = "0.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0abae9be0aaf9ea96a3b1b8b1b55c602ca751eba1b1500220cea4ecbafe7c0d5" +dependencies = [ + "rustversion", +] [[package]] -name = "chrono" -version = "0.4.6" +name = "cc" +version = "1.2.17" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1fcb57c740ae1daf453ae85f16e37396f672b039e00d9d866e07ddb24e328e3a" dependencies = [ - "num-integer 0.1.39 (registry+https://github.com/rust-lang/crates.io-index)", - "num-traits 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.88 (registry+https://github.com/rust-lang/crates.io-index)", - "time 0.1.42 (registry+https://github.com/rust-lang/crates.io-index)", + "shlex", ] +[[package]] +name = "cfg-if" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" + [[package]] name = "clap" -version = "2.32.0" +version = "4.5.34" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e958897981290da2a852763fe9cdb89cd36977a5d729023127095fa94d95e2ff" dependencies = [ - "ansi_term 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)", - "atty 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)", - "bitflags 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)", - "strsim 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", - "textwrap 0.10.0 (registry+https://github.com/rust-lang/crates.io-index)", - "unicode-width 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", - "vec_map 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)", + "clap_builder", + "clap_derive", ] [[package]] -name = "cloudabi" -version = "0.0.3" +name = "clap_builder" +version = "4.5.34" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "83b0f35019843db2160b5bb19ae09b4e6411ac33fc6a712003c33e03090e2489" dependencies = [ - "bitflags 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)", + "anstream", + "anstyle", + "clap_lex", + "strsim", ] [[package]] -name = "colored" -version = "1.7.0" +name = "clap_derive" +version = "4.5.32" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "09176aae279615badda0765c0c0b3f6ed53f4709118af73cf4655d85d1530cd7" dependencies = [ - "lazy_static 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)", + "heck", + "proc-macro2", + "quote", + "syn 2.0.100", ] [[package]] -name = "cookie" -version = "0.11.0" +name = "clap_lex" +version = "0.7.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f46ad14479a25103f283c0f10005961cf086d8dc42205bb44c46ac563475dca6" + +[[package]] +name = "clipboard-win" +version = "4.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7191c27c2357d9b7ef96baac1773290d4ca63b24205b82a3fd8a0637afcf0362" dependencies = [ - "base64 0.9.3 (registry+https://github.com/rust-lang/crates.io-index)", - "ring 0.13.5 (registry+https://github.com/rust-lang/crates.io-index)", - "time 0.1.42 (registry+https://github.com/rust-lang/crates.io-index)", - "url 1.7.2 (registry+https://github.com/rust-lang/crates.io-index)", + "error-code", + "str-buf", + "winapi", ] [[package]] -name = "core-foundation" +name = "cobs" version = "0.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "core-foundation-sys 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.49 (registry+https://github.com/rust-lang/crates.io-index)", -] +checksum = "67ba02a97a2bd10f4b59b25c7973101c79642302776489e030cd13cdab09ed15" [[package]] -name = "core-foundation" -version = "0.5.1" +name = "color-eyre" +version = "0.6.3" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "55146f5e46f237f7423d74111267d4597b59b0dad0ffaf7303bce9945d843ad5" dependencies = [ - "core-foundation-sys 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.49 (registry+https://github.com/rust-lang/crates.io-index)", + "backtrace", + "color-spantrace", + "eyre", + "indenter", + "once_cell", + "owo-colors", + "tracing-error", ] [[package]] -name = "core-foundation-sys" -version = "0.2.3" +name = "color-spantrace" +version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cd6be1b2a7e382e2b98b43b2adcca6bb0e465af0bdd38123873ae61eb17a72c2" dependencies = [ - "libc 0.2.49 (registry+https://github.com/rust-lang/crates.io-index)", + "once_cell", + "owo-colors", + "tracing-core", + "tracing-error", ] [[package]] -name = "core-foundation-sys" -version = "0.5.1" +name = "colorchoice" +version = "1.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "libc 0.2.49 (registry+https://github.com/rust-lang/crates.io-index)", -] +checksum = "5b63caa9aa9397e2d9480a9b13673856c78d8ac123288526c37d7839f2a86990" [[package]] -name = "crc" -version = "1.8.1" +name = "colored" +version = "2.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "117725a109d387c937a1533ce01b450cbde6b88abceea8473c4d7a85853cda3c" dependencies = [ - "build_const 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", + "lazy_static", + "windows-sys 0.59.0", ] [[package]] -name = "crc32fast" -version = "1.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" +name = "colorimetry" +version = "0.0.2" +source = "git+https://github.com/harbik/colorimetry#f55b1953653a8a264c54648ef3b6a3d5cfce9f14" dependencies = [ - "cfg-if 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", + "approx", + "colored", + "js-sys", + "libm", + "nalgebra", + "num-traits", + "once_cell", + "paste", + "strum 0.26.3", + "strum_macros 0.26.4", + "thiserror 1.0.69", + "url", + "wasm-bindgen", + "wasm-bindgen-futures", ] [[package]] -name = "crossbeam" -version = "0.6.0" +name = "compact_str" +version = "0.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3b79c4069c6cad78e2e0cdfcbd26275770669fb39fd308a752dc110e83b9af32" dependencies = [ - "cfg-if 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", - "crossbeam-channel 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", - "crossbeam-deque 0.6.3 (registry+https://github.com/rust-lang/crates.io-index)", - "crossbeam-epoch 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)", - "crossbeam-utils 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)", - "lazy_static 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)", - "num_cpus 1.10.0 (registry+https://github.com/rust-lang/crates.io-index)", - "parking_lot 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)", + "castaway", + "cfg-if", + "itoa", + "rustversion", + "ryu", + "static_assertions", ] [[package]] -name = "crossbeam-channel" -version = "0.3.8" +name = "console" +version = "0.15.11" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "054ccb5b10f9f2cbf51eb355ca1d05c2d279ce1804688d0db74b4733a5aeafd8" dependencies = [ - "crossbeam-utils 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)", - "smallvec 0.6.9 (registry+https://github.com/rust-lang/crates.io-index)", + "encode_unicode", + "libc", + "once_cell", + "unicode-width 0.2.0", + "windows-sys 0.59.0", ] [[package]] -name = "crossbeam-deque" -version = "0.6.3" +name = "convert_case" +version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "crossbeam-epoch 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)", - "crossbeam-utils 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)", -] +checksum = "6245d59a3e82a7fc217c5828a6692dbc6dfb63a0c8c90495621f7b9d79704a0e" [[package]] -name = "crossbeam-epoch" -version = "0.7.1" +name = "cordyceps" +version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ec10f0a762d93c4498d2e97a333805cb6250d60bead623f71d8034f9a4152ba3" dependencies = [ - "arrayvec 0.4.10 (registry+https://github.com/rust-lang/crates.io-index)", - "cfg-if 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", - "crossbeam-utils 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)", - "lazy_static 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)", - "memoffset 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", - "scopeguard 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", + "loom", + "tracing", ] [[package]] -name = "crossbeam-utils" -version = "0.6.5" +name = "core-foundation" +version = "0.9.4" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "91e195e091a93c46f7102ec7818a2aa394e1e1771c3ab4825963fa03e45afb8f" dependencies = [ - "cfg-if 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", - "lazy_static 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)", + "core-foundation-sys", + "libc", ] [[package]] -name = "dataserver" -version = "0.1.0" -source = "git+https://github.com/dskleingeld/dataserver?branch=as_lib#1f73c853f9f0698fe1b7b90ac9ab91a7768d0588" -dependencies = [ - "acme-client 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)", - "actix 0.7.9 (registry+https://github.com/rust-lang/crates.io-index)", - "actix-net 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)", - "actix-web 0.7.18 (registry+https://github.com/rust-lang/crates.io-index)", - "bincode 1.1.2 (registry+https://github.com/rust-lang/crates.io-index)", - "byteorder 1.3.1 (registry+https://github.com/rust-lang/crates.io-index)", - "bytes 0.4.11 (registry+https://github.com/rust-lang/crates.io-index)", - "chrono 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", - "crossbeam-utils 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)", - "fern 0.5.7 (registry+https://github.com/rust-lang/crates.io-index)", - "futures 0.1.25 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", - "minimal_timeseries 0.1.1 (git+https://github.com/dskleingeld/minimal_timeseries?branch=multithraeded_file_read)", - "num 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", - "rand 0.5.6 (registry+https://github.com/rust-lang/crates.io-index)", - "reqwest 0.9.10 (registry+https://github.com/rust-lang/crates.io-index)", - "ring 0.13.5 (registry+https://github.com/rust-lang/crates.io-index)", - "rustls 0.14.0 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.88 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_derive 1.0.88 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_json 1.0.38 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_yaml 0.8.8 (registry+https://github.com/rust-lang/crates.io-index)", - "smallvec 0.6.9 (registry+https://github.com/rust-lang/crates.io-index)", - "text_io 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)", - "untrusted 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)", - "walkdir 2.2.7 (registry+https://github.com/rust-lang/crates.io-index)", - "webpki 0.18.1 (registry+https://github.com/rust-lang/crates.io-index)", - "webpki-roots 0.15.0 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "dtoa" -version = "0.4.3" +name = "core-foundation" +version = "0.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b55271e5c8c478ad3f38ad24ef34923091e0548492a266d19b3c0b4d82574c63" +dependencies = [ + "core-foundation-sys", + "libc", +] [[package]] -name = "either" -version = "1.5.1" +name = "core-foundation-sys" +version = "0.8.7" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "773648b94d0e5d620f64f280777445740e61fe701025087ec8b57f45c791888b" [[package]] -name = "embedded-hal" -version = "0.2.2" +name = "cpufeatures" +version = "0.2.17" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "59ed5838eebb26a2bb2e58f6d5b5316989ae9d08bab10e0e6d103e656d1b0280" dependencies = [ - "nb 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", - "void 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", + "libc", ] [[package]] -name = "encoding" -version = "0.2.33" +name = "crc32fast" +version = "1.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a97769d94ddab943e4510d138150169a2758b5ef3eb191a9ee688de3e23ef7b3" dependencies = [ - "encoding-index-japanese 1.20141219.5 (registry+https://github.com/rust-lang/crates.io-index)", - "encoding-index-korean 1.20141219.5 (registry+https://github.com/rust-lang/crates.io-index)", - "encoding-index-simpchinese 1.20141219.5 (registry+https://github.com/rust-lang/crates.io-index)", - "encoding-index-singlebyte 1.20141219.5 (registry+https://github.com/rust-lang/crates.io-index)", - "encoding-index-tradchinese 1.20141219.5 (registry+https://github.com/rust-lang/crates.io-index)", + "cfg-if", ] [[package]] -name = "encoding-index-japanese" -version = "1.20141219.5" +name = "critical-section" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "790eea4361631c5e7d22598ecd5723ff611904e3344ce8720784c93e3d83d40b" + +[[package]] +name = "crossbeam-channel" +version = "0.5.14" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "06ba6d68e24814cb8de6bb986db8222d3a027d15872cabc0d18817bc3c0e4471" dependencies = [ - "encoding_index_tests 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", + "crossbeam-utils", ] [[package]] -name = "encoding-index-korean" -version = "1.20141219.5" +name = "crossbeam-epoch" +version = "0.9.18" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5b82ac4a3c2ca9c3460964f020e1402edd5753411d7737aa39c3714ad1b5420e" dependencies = [ - "encoding_index_tests 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", + "crossbeam-utils", ] [[package]] -name = "encoding-index-simpchinese" -version = "1.20141219.5" +name = "crossbeam-queue" +version = "0.3.12" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0f58bbc28f91df819d0aa2a2c00cd19754769c2fad90579b3592b1c9ba7a3115" dependencies = [ - "encoding_index_tests 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", + "crossbeam-utils", ] [[package]] -name = "encoding-index-singlebyte" -version = "1.20141219.5" +name = "crossbeam-utils" +version = "0.8.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d0a5c400df2834b80a4c3327b3aad3a4c4cd4de0629063962b03235697506a28" + +[[package]] +name = "crossterm" +version = "0.28.1" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "829d955a0bb380ef178a640b91779e3987da38c9aea133b20614cfed8cdea9c6" dependencies = [ - "encoding_index_tests 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", + "bitflags 2.9.0", + "crossterm_winapi", + "mio", + "parking_lot 0.12.3", + "rustix", + "signal-hook", + "signal-hook-mio", + "winapi", ] [[package]] -name = "encoding-index-tradchinese" -version = "1.20141219.5" +name = "crossterm_winapi" +version = "0.9.1" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "acdd7c62a3665c7f6830a51635d9ac9b23ed385797f70a83bb8bafe9c572ab2b" dependencies = [ - "encoding_index_tests 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi", ] [[package]] -name = "encoding_index_tests" -version = "0.1.4" +name = "crypto-common" +version = "0.1.6" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1bfb12502f3fc46cca1bb51ac28df9d618d813cdc3d2f25b9fe775a34af26bb3" +dependencies = [ + "generic-array", + "typenum", +] [[package]] -name = "encoding_rs" -version = "0.8.17" +name = "darling" +version = "0.20.11" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fc7f46116c46ff9ab3eb1597a45688b6715c6e628b5c133e288e709a29bcb4ee" dependencies = [ - "cfg-if 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", + "darling_core", + "darling_macro", ] [[package]] -name = "env_logger" -version = "0.4.3" +name = "darling_core" +version = "0.20.11" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0d00b9596d185e565c2207a0b01f8bd1a135483d02d9b7b0a54b11da8d53412e" dependencies = [ - "log 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)", - "regex 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)", + "fnv", + "ident_case", + "proc-macro2", + "quote", + "strsim", + "syn 2.0.100", ] [[package]] -name = "error-chain" -version = "0.8.1" +name = "darling_macro" +version = "0.20.11" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fc34b93ccb385b40dc71c6fceac4b2ad23662c7eeb248cf10d529b7e055b6ead" dependencies = [ - "backtrace 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)", + "darling_core", + "quote", + "syn 2.0.100", ] [[package]] -name = "error-chain" -version = "0.11.0" +name = "dashmap" +version = "5.5.3" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "978747c1d849a7d2ee5e8adc0159961c48fb7e5db2f06af6723b80123bb53856" dependencies = [ - "backtrace 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)", + "cfg-if", + "hashbrown 0.14.5", + "lock_api", + "once_cell", + "parking_lot_core 0.9.10", ] [[package]] -name = "error-chain" -version = "0.12.0" +name = "dashmap" +version = "6.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5041cc499144891f3790297212f32a74fb938e5136a14943f338ef9e0ae276cf" dependencies = [ - "backtrace 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)", + "cfg-if", + "crossbeam-utils", + "hashbrown 0.14.5", + "lock_api", + "once_cell", + "parking_lot_core 0.9.10", ] [[package]] -name = "failure" -version = "0.1.5" -source = "registry+https://github.com/rust-lang/crates.io-index" +name = "data-server" +version = "0.0.0" dependencies = [ - "backtrace 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)", - "failure_derive 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", + "clap", + "color-eyre", + "futures", + "futures-concurrency", + "governor", + "logger", + "protocol", + "reserve-port", + "rpc", + "serde", + "slotmap", + "socket2 0.6.0", + "thiserror 2.0.12", + "tokio", + "tokio-serde", + "tokio-util", + "tokio-utils", + "tracing", + "tracing-error", + "tracing-futures", + "tracing-subscriber", ] [[package]] -name = "failure_derive" -version = "0.1.5" -source = "registry+https://github.com/rust-lang/crates.io-index" +name = "data-store" +version = "0.1.0" dependencies = [ - "proc-macro2 0.4.27 (registry+https://github.com/rust-lang/crates.io-index)", - "quote 0.6.11 (registry+https://github.com/rust-lang/crates.io-index)", - "syn 0.15.26 (registry+https://github.com/rust-lang/crates.io-index)", - "synstructure 0.10.1 (registry+https://github.com/rust-lang/crates.io-index)", + "byteseries", + "clap", + "color-eyre", + "data-server", + "futures", + "futures-concurrency", + "indicatif", + "itertools 0.14.0", + "jiff", + "logger", + "nucleo-matcher", + "num", + "protocol", + "reserve-port", + "ron 0.9.0", + "rpc", + "rstest", + "serde", + "smallvec 2.0.0-alpha.11", + "temp-dir", + "thiserror 2.0.12", + "tokio", + "tracing", + "tracing-error", + "tracing-subscriber", +] + +[[package]] +name = "dbstruct" +version = "0.6.0" +source = "git+https://github.com/dvdsk/dbstruct#5ecca3460f19f34e816ae50f7b199c15f1b21b02" +dependencies = [ + "bincode 2.0.1", + "dbstruct-derive", + "serde", + "sled", + "thiserror 2.0.12", + "tracing", ] [[package]] -name = "fern" -version = "0.5.7" -source = "registry+https://github.com/rust-lang/crates.io-index" +name = "dbstruct-derive" +version = "0.4.0" +source = "git+https://github.com/dvdsk/dbstruct#5ecca3460f19f34e816ae50f7b199c15f1b21b02" dependencies = [ - "colored 1.7.0 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", + "itertools 0.14.0", + "proc-macro-error", + "proc-macro2", + "quote", + "syn 2.0.100", + "thiserror 2.0.12", ] [[package]] -name = "flate2" -version = "1.0.6" +name = "defmt" +version = "0.3.10" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "86f6162c53f659f65d00619fe31f14556a6e9f8752ccc4a41bd177ffcf3d6130" dependencies = [ - "crc32fast 1.1.2 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.49 (registry+https://github.com/rust-lang/crates.io-index)", - "miniz-sys 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)", - "miniz_oxide_c_api 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", + "bitflags 1.3.2", + "defmt-macros", ] [[package]] -name = "fnv" -version = "1.0.6" +name = "defmt-macros" +version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9d135dd939bad62d7490b0002602d35b358dce5fd9233a709d3c1ef467d4bde6" +dependencies = [ + "defmt-parser", + "proc-macro-error2", + "proc-macro2", + "quote", + "syn 2.0.100", +] [[package]] -name = "foreign-types" -version = "0.3.2" +name = "defmt-parser" +version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3983b127f13995e68c1e29071e5d115cd96f215ccb5e6812e3728cd6f92653b3" dependencies = [ - "foreign-types-shared 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", + "thiserror 2.0.12", ] [[package]] -name = "foreign-types-shared" -version = "0.1.1" +name = "derivative" +version = "2.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fcc3dd5e9e9c0b295d6e1e4d811fb6f157d5ffd784b8d202fc62eac8035a770b" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.109", +] [[package]] -name = "fuchsia-cprng" -version = "0.1.1" +name = "derive_more" +version = "0.99.19" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3da29a38df43d6f156149c9b43ded5e018ddff2a855cf2cfd62e8cd7d079c69f" +dependencies = [ + "convert_case", + "proc-macro2", + "quote", + "rustc_version", + "syn 2.0.100", +] [[package]] -name = "fuchsia-zircon" -version = "0.3.3" -source = "registry+https://github.com/rust-lang/crates.io-index" +name = "desk-sensors" +version = "0.2.0" dependencies = [ - "bitflags 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)", - "fuchsia-zircon-sys 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", + "bme280", + "clap", + "color-eyre", + "data-server", + "governor", + "heapless 0.8.0", + "linux-embedded-hal", + "logger", + "protocol", + "tokio", + "tracing", + "tracing-error", + "tracing-subscriber", ] [[package]] -name = "fuchsia-zircon-sys" -version = "0.3.3" +name = "diatomic-waker" +version = "0.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ab03c107fafeb3ee9f5925686dbb7a73bc76e3932abb0d2b365cb64b169cf04c" [[package]] -name = "futures" -version = "0.1.25" +name = "digest" +version = "0.10.7" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292" +dependencies = [ + "block-buffer", + "crypto-common", + "subtle", +] [[package]] -name = "futures-cpupool" -version = "0.1.8" +name = "dirs" +version = "6.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c3e8aa94d75141228480295a7d0e7feb620b1a5ad9f12bc40be62411e38cce4e" dependencies = [ - "futures 0.1.25 (registry+https://github.com/rust-lang/crates.io-index)", - "num_cpus 1.10.0 (registry+https://github.com/rust-lang/crates.io-index)", + "dirs-sys", ] [[package]] -name = "fxhash" -version = "0.2.1" +name = "dirs-next" +version = "2.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b98cf8ebf19c3d1b223e151f99a4f9f0690dca41414773390fc824184ac833e1" dependencies = [ - "byteorder 1.3.1 (registry+https://github.com/rust-lang/crates.io-index)", + "cfg-if", + "dirs-sys-next", ] [[package]] -name = "gcc" -version = "0.3.55" +name = "dirs-sys" +version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e01a3366d27ee9890022452ee61b2b63a67e6f13f58900b651ff5665f0bb1fab" +dependencies = [ + "libc", + "option-ext", + "redox_users 0.5.0", + "windows-sys 0.59.0", +] [[package]] -name = "h2" -version = "0.1.16" +name = "dirs-sys-next" +version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4ebda144c4fe02d1f7ea1a7d9641b6fc6b580adcfa024ae48797ecdeb6825b4d" dependencies = [ - "byteorder 1.3.1 (registry+https://github.com/rust-lang/crates.io-index)", - "bytes 0.4.11 (registry+https://github.com/rust-lang/crates.io-index)", - "fnv 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", - "futures 0.1.25 (registry+https://github.com/rust-lang/crates.io-index)", - "http 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)", - "indexmap 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", - "slab 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", - "string 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-io 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)", + "libc", + "redox_users 0.4.6", + "winapi", ] [[package]] -name = "hostname" -version = "0.1.5" +name = "displaydoc" +version = "0.2.5" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "97369cbbc041bc366949bc74d34658d6cda5621039731c6310521892a3a20ae0" dependencies = [ - "libc 0.2.49 (registry+https://github.com/rust-lang/crates.io-index)", - "winutil 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", + "proc-macro2", + "quote", + "syn 2.0.100", ] [[package]] -name = "http" -version = "0.1.16" +name = "educe" +version = "0.5.11" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e4bd92664bf78c4d3dba9b7cdafce6fa15b13ed3ed16175218196942e99168a8" dependencies = [ - "bytes 0.4.11 (registry+https://github.com/rust-lang/crates.io-index)", - "fnv 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", - "itoa 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)", + "enum-ordinalize", + "proc-macro2", + "quote", + "syn 2.0.100", ] [[package]] -name = "httparse" -version = "1.3.3" +name = "either" +version = "1.15.0" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "48c757948c5ede0e46177b7add2e67155f70e33c07fea8284df6576da70b3719" [[package]] -name = "hyper" -version = "0.10.15" +name = "embedded-hal" +version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "base64 0.9.3 (registry+https://github.com/rust-lang/crates.io-index)", - "httparse 1.3.3 (registry+https://github.com/rust-lang/crates.io-index)", - "language-tags 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)", - "mime 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)", - "num_cpus 1.10.0 (registry+https://github.com/rust-lang/crates.io-index)", - "time 0.1.42 (registry+https://github.com/rust-lang/crates.io-index)", - "traitobject 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", - "typeable 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", - "unicase 1.4.2 (registry+https://github.com/rust-lang/crates.io-index)", - "url 1.7.2 (registry+https://github.com/rust-lang/crates.io-index)", -] +checksum = "361a90feb7004eca4019fb28352a9465666b24f840f5c3cddf0ff13920590b89" [[package]] -name = "hyper" -version = "0.12.24" +name = "embedded-hal-nb" +version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fba4268c14288c828995299e59b12babdbe170f6c6d73731af1b4648142e8605" dependencies = [ - "bytes 0.4.11 (registry+https://github.com/rust-lang/crates.io-index)", - "futures 0.1.25 (registry+https://github.com/rust-lang/crates.io-index)", - "futures-cpupool 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)", - "h2 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)", - "http 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)", - "httparse 1.3.3 (registry+https://github.com/rust-lang/crates.io-index)", - "iovec 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", - "itoa 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", - "net2 0.2.33 (registry+https://github.com/rust-lang/crates.io-index)", - "time 0.1.42 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio 0.1.15 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-executor 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-io 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-reactor 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-tcp 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-threadpool 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-timer 0.2.10 (registry+https://github.com/rust-lang/crates.io-index)", - "want 0.0.6 (registry+https://github.com/rust-lang/crates.io-index)", + "embedded-hal", + "nb", ] [[package]] -name = "hyper-native-tls" -version = "0.2.4" +name = "embedded-io" +version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "antidote 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", - "hyper 0.10.15 (registry+https://github.com/rust-lang/crates.io-index)", - "native-tls 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", -] +checksum = "ef1a6892d9eef45c8fa6b9e0086428a2cca8491aca8f787c534a3d6d0bcb3ced" [[package]] -name = "hyper-rustls" -version = "0.6.2" +name = "embedded-io" +version = "0.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "hyper 0.10.15 (registry+https://github.com/rust-lang/crates.io-index)", - "rustls 0.13.1 (registry+https://github.com/rust-lang/crates.io-index)", - "webpki 0.18.1 (registry+https://github.com/rust-lang/crates.io-index)", - "webpki-roots 0.15.0 (registry+https://github.com/rust-lang/crates.io-index)", -] +checksum = "edd0f118536f44f5ccd48bcb8b111bdc3de888b58c74639dfb034a357d0f206d" [[package]] -name = "hyper-tls" -version = "0.3.1" +name = "encode_unicode" +version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "bytes 0.4.11 (registry+https://github.com/rust-lang/crates.io-index)", - "futures 0.1.25 (registry+https://github.com/rust-lang/crates.io-index)", - "hyper 0.12.24 (registry+https://github.com/rust-lang/crates.io-index)", - "native-tls 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-io 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)", -] +checksum = "34aa73646ffb006b8f5147f3dc182bd4bcb190227ce861fc4a4844bf8e3cb2c0" [[package]] -name = "i2cdev" -version = "0.4.1" +name = "endian-type" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c34f04666d835ff5d62e058c3995147c06f42fe86ff053337632bca83e42702d" + +[[package]] +name = "enum-ordinalize" +version = "4.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fea0dcfa4e54eeb516fe454635a95753ddd39acda650ce703031c6973e315dd5" dependencies = [ - "bitflags 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)", - "byteorder 1.3.1 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.49 (registry+https://github.com/rust-lang/crates.io-index)", - "nix 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)", + "enum-ordinalize-derive", ] [[package]] -name = "idna" -version = "0.1.5" +name = "enum-ordinalize-derive" +version = "4.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0d28318a75d4aead5c4db25382e8ef717932d0346600cacae6357eb5941bc5ff" dependencies = [ - "matches 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)", - "unicode-bidi 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)", - "unicode-normalization 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)", + "proc-macro2", + "quote", + "syn 2.0.100", ] [[package]] -name = "indexmap" +name = "equivalent" version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "877a4ace8713b0bcf2a4e7eec82529c029f1d0619886d18145fea96c3ffe5c0f" [[package]] -name = "iovec" -version = "0.1.2" +name = "errno" +version = "0.3.10" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "33d852cb9b869c2a9b3df2f71a3074817f01e1844f839a144f5fcef059a4eb5d" dependencies = [ - "libc 0.2.49 (registry+https://github.com/rust-lang/crates.io-index)", - "winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", + "libc", + "windows-sys 0.59.0", ] [[package]] -name = "ipconfig" -version = "0.1.9" +name = "error-code" +version = "2.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "64f18991e7bf11e7ffee451b5318b5c1a73c52d0d0ada6e5a3017c8c1ced6a21" dependencies = [ - "error-chain 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)", - "socket2 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", - "widestring 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", - "winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", - "winreg 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)", + "libc", + "str-buf", ] [[package]] -name = "itertools" -version = "0.7.11" +name = "eyre" +version = "0.6.12" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7cd915d99f24784cdc19fd37ef22b97e3ff0ae756c7e492e9fbfe897d61e2aec" dependencies = [ - "either 1.5.1 (registry+https://github.com/rust-lang/crates.io-index)", + "indenter", + "once_cell", ] [[package]] -name = "itoa" -version = "0.4.3" +name = "fastrand" +version = "2.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "37909eebbb50d72f9059c3b6d82c0463f2ff062c9e95845c43a6c9c0355411be" [[package]] -name = "kernel32-sys" -version = "0.2.2" +name = "fd-lock" +version = "3.0.13" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ef033ed5e9bad94e55838ca0ca906db0e043f517adda0c8b79c7a8c66c93c1b5" dependencies = [ - "winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", - "winapi-build 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", + "cfg-if", + "rustix", + "windows-sys 0.48.0", ] [[package]] -name = "language-tags" -version = "0.2.2" +name = "fixedbitset" +version = "0.5.7" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1d674e81391d1e1ab681a28d99df07927c6d4aa5b027d7da16ba32d1d21ecd99" [[package]] -name = "lazy_static" -version = "0.2.11" +name = "flate2" +version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "11faaf5a5236997af9848be0bef4db95824b1d534ebc64d0f0c6cf3e67bd38dc" +dependencies = [ + "crc32fast", + "miniz_oxide 0.8.5", +] [[package]] -name = "lazy_static" -version = "1.3.0" +name = "flume" +version = "0.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "da0e4dd2a88388a1f4ccc7c9ce104604dab68d9f408dc34cd45823d5a9069095" +dependencies = [ + "futures-core", + "futures-sink", + "spin", +] [[package]] -name = "lazycell" -version = "1.2.1" +name = "fnv" +version = "1.0.7" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" [[package]] -name = "libc" -version = "0.2.49" +name = "foldhash" +version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d9c4f5dac5e15c24eb999c26181a6ca40b39fe946cbe4c263c7209467bc83af2" [[package]] -name = "libflate" -version = "0.1.20" +name = "form_urlencoded" +version = "1.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e13624c2627564efccf4934284bdd98cbaa14e79b0b5a141218e507b3a823456" dependencies = [ - "adler32 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)", - "byteorder 1.3.1 (registry+https://github.com/rust-lang/crates.io-index)", - "crc32fast 1.1.2 (registry+https://github.com/rust-lang/crates.io-index)", + "percent-encoding", ] [[package]] -name = "linked-hash-map" -version = "0.4.2" +name = "fs2" +version = "0.4.3" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9564fc758e15025b46aa6643b1b77d047d1a56a1aea6e01002ac0c7026876213" +dependencies = [ + "libc", + "winapi", +] [[package]] -name = "linked-hash-map" -version = "0.5.1" +name = "futures" +version = "0.3.31" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "65bc07b1a8bc7c85c5f2e110c476c7389b4554ba72af57d8445ea63a576b0876" +dependencies = [ + "futures-channel", + "futures-core", + "futures-executor", + "futures-io", + "futures-sink", + "futures-task", + "futures-util", +] [[package]] -name = "linux-embedded-hal" -version = "0.2.2" +name = "futures-buffered" +version = "0.2.11" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fe940397c8b744b9c2c974791c2c08bca2c3242ce0290393249e98f215a00472" dependencies = [ - "cast 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", - "embedded-hal 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", - "i2cdev 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)", - "spidev 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", - "sysfs_gpio 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)", + "cordyceps", + "diatomic-waker", + "futures-core", + "pin-project-lite", + "spin", ] [[package]] -name = "lock_api" -version = "0.1.5" +name = "futures-channel" +version = "0.3.31" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2dff15bf788c671c1934e366d07e30c1814a8ef514e1af724a602e8a2fbe1b10" dependencies = [ - "owning_ref 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", - "scopeguard 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", + "futures-core", + "futures-sink", ] [[package]] -name = "log" -version = "0.3.9" +name = "futures-concurrency" +version = "7.6.3" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0eb68017df91f2e477ed4bea586c59eaecaa47ed885a770d0444e21e62572cd2" dependencies = [ - "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", + "fixedbitset", + "futures-buffered", + "futures-core", + "futures-lite", + "pin-project", + "slab", + "smallvec 1.14.0", ] [[package]] -name = "log" -version = "0.4.6" +name = "futures-core" +version = "0.3.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "05f29059c0c2090612e8d742178b0580d2dc940c837851ad723096f87af6663e" + +[[package]] +name = "futures-executor" +version = "0.3.31" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e28d1d997f585e54aebc3f97d39e72338912123a67330d723fdbb564d646c9f" dependencies = [ - "cfg-if 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", + "futures-core", + "futures-task", + "futures-util", ] [[package]] -name = "lru-cache" -version = "0.1.1" +name = "futures-io" +version = "0.3.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9e5c1b78ca4aae1ac06c48a526a655760685149f0d465d21f37abfe57ce075c6" + +[[package]] +name = "futures-lite" +version = "2.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f5edaec856126859abb19ed65f39e90fea3a9574b9707f13539acf4abf7eb532" +dependencies = [ + "fastrand", + "futures-core", + "futures-io", + "parking", + "pin-project-lite", +] + +[[package]] +name = "futures-macro" +version = "0.3.31" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "162ee34ebcb7c64a8abebc059ce0fee27c2262618d7b60ed8faf72fef13c3650" dependencies = [ - "linked-hash-map 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", + "proc-macro2", + "quote", + "syn 2.0.100", ] [[package]] -name = "matches" -version = "0.1.8" +name = "futures-sink" +version = "0.3.31" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e575fab7d1e0dcb8d0c7bcf9a63ee213816ab51902e6d244a95819acacf1d4f7" [[package]] -name = "matrixmultiply" -version = "0.1.15" +name = "futures-task" +version = "0.3.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f90f7dce0722e95104fcb095585910c0977252f286e354b5e3bd38902cd99988" + +[[package]] +name = "futures-timer" +version = "3.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f288b0a4f20f9a56b5d1da57e2227c661b7b16168e2f72365f57b63326e29b24" + +[[package]] +name = "futures-util" +version = "0.3.31" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9fa08315bb612088cc391249efdc3bc77536f16c91f6cf495e6fbe85b20a4a81" dependencies = [ - "rawpointer 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", + "futures-channel", + "futures-core", + "futures-io", + "futures-macro", + "futures-sink", + "futures-task", + "memchr", + "pin-project-lite", + "pin-utils", + "slab", ] [[package]] -name = "memchr" -version = "2.2.0" +name = "fxhash" +version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c31b6d751ae2c7f11320402d34e41349dd1016f8d5d45e48c4312bc8625af50c" +dependencies = [ + "byteorder", +] [[package]] -name = "memoffset" -version = "0.2.1" +name = "generator" +version = "0.7.5" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5cc16584ff22b460a382b7feec54b23d2908d858152e5739a120b949293bd74e" +dependencies = [ + "cc", + "libc", + "log", + "rustversion", + "windows", +] [[package]] -name = "mime" -version = "0.2.6" +name = "generic-array" +version = "0.14.7" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "85649ca51fd72272d7821adaf274ad91c288277713d9c18820d8499a7ff69e9a" dependencies = [ - "log 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)", + "typenum", + "version_check", ] [[package]] -name = "mime" -version = "0.3.13" +name = "gethostname" +version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dc3655aa6818d65bc620d6911f05aa7b6aeb596291e1e9f79e52df85583d1e30" dependencies = [ - "unicase 2.2.0 (registry+https://github.com/rust-lang/crates.io-index)", + "rustix", + "windows-targets 0.52.6", ] [[package]] -name = "mime_guess" -version = "2.0.0-alpha.6" +name = "getrandom" +version = "0.2.15" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c4567c8db10ae91089c99af84c68c38da3ec2f087c3f82960bcdbf3656b6f4d7" dependencies = [ - "mime 0.3.13 (registry+https://github.com/rust-lang/crates.io-index)", - "phf 0.7.24 (registry+https://github.com/rust-lang/crates.io-index)", - "phf_codegen 0.7.24 (registry+https://github.com/rust-lang/crates.io-index)", - "unicase 1.4.2 (registry+https://github.com/rust-lang/crates.io-index)", + "cfg-if", + "libc", + "wasi 0.11.0+wasi-snapshot-preview1", ] [[package]] -name = "minimal_timeseries" -version = "0.1.1" -source = "git+https://github.com/dskleingeld/minimal_timeseries?branch=multithraeded_file_read#69a69ef9ed8c79beceecd1f2113fc98b035df2ac" +name = "getrandom" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "73fea8450eea4bac3940448fb7ae50d91f034f941199fcd9d909a5a07aa455f0" dependencies = [ - "byteorder 1.3.1 (registry+https://github.com/rust-lang/crates.io-index)", - "chrono 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", - "fern 0.5.7 (registry+https://github.com/rust-lang/crates.io-index)", - "fxhash 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", - "ndarray 0.12.1 (registry+https://github.com/rust-lang/crates.io-index)", - "num-traits 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)", + "cfg-if", + "js-sys", + "libc", + "r-efi", + "wasi 0.14.2+wasi-0.2.4", + "wasm-bindgen", ] [[package]] -name = "miniz-sys" -version = "0.1.11" +name = "gimli" +version = "0.28.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4271d37baee1b8c7e4b708028c57d816cf9d2434acb33a549475f78c181f6253" + +[[package]] +name = "glob" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a8d1add55171497b4705a648c6b583acafb01d58050a51727785f0b2c8e0a2b2" + +[[package]] +name = "governor" +version = "0.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "be93b4ec2e4710b04d9264c0c7350cdd62a8c20e5e4ac732552ebb8f0debe8eb" dependencies = [ - "cc 1.0.29 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.49 (registry+https://github.com/rust-lang/crates.io-index)", + "cfg-if", + "dashmap 6.1.0", + "futures-sink", + "futures-timer", + "futures-util", + "getrandom 0.3.2", + "no-std-compat", + "nonzero_ext", + "parking_lot 0.12.3", + "portable-atomic", + "quanta", + "rand 0.9.0", + "smallvec 1.14.0", + "spinning_top", + "web-time", ] [[package]] -name = "miniz_oxide" -version = "0.2.1" +name = "gpio-cdev" +version = "0.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "09831ec59b80be69e75d29cf36e16afbbe5fd1af9c1bf4689ad91c77db5aa6a6" dependencies = [ - "adler32 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)", + "bitflags 2.9.0", + "libc", + "nix 0.27.1", ] [[package]] -name = "miniz_oxide_c_api" +name = "ha-text-widget" +version = "0.1.0" +dependencies = [ + "clap", + "color-eyre", + "data-server", + "data-store", + "dirs", + "gethostname", + "itertools 0.14.0", + "logger", + "nucleo-matcher", + "promptly", + "protocol", + "ron 0.9.0", + "serde", + "tokio", + "tracing", + "tracing-error", + "tracing-subscriber", +] + +[[package]] +name = "hash32" version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b0c35f58762feb77d74ebe43bdbc3210f09be9fe6742234d573bacc26ed92b67" dependencies = [ - "cc 1.0.29 (registry+https://github.com/rust-lang/crates.io-index)", - "crc 1.8.1 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.49 (registry+https://github.com/rust-lang/crates.io-index)", - "miniz_oxide 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", + "byteorder", ] [[package]] -name = "mio" -version = "0.6.16" +name = "hash32" +version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "47d60b12902ba28e2730cd37e95b8c9223af2808df9e902d4df49588d1470606" dependencies = [ - "fuchsia-zircon 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", - "fuchsia-zircon-sys 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", - "iovec 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", - "kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", - "lazycell 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.49 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", - "miow 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", - "net2 0.2.33 (registry+https://github.com/rust-lang/crates.io-index)", - "slab 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", - "winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", + "byteorder", ] [[package]] -name = "mio-uds" -version = "0.6.7" +name = "hashbrown" +version = "0.14.5" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e5274423e17b7c9fc20b6e7e208532f9b19825d82dfd615708b70edd83df41f1" + +[[package]] +name = "hashbrown" +version = "0.15.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bf151400ff0baff5465007dd2f3e717f3fe502074ca563069ce3a6629d07b289" dependencies = [ - "iovec 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.49 (registry+https://github.com/rust-lang/crates.io-index)", - "mio 0.6.16 (registry+https://github.com/rust-lang/crates.io-index)", + "allocator-api2", + "equivalent", + "foldhash", ] [[package]] -name = "miow" -version = "0.2.1" +name = "hdrhistogram" +version = "7.5.4" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "765c9198f173dd59ce26ff9f95ef0aafd0a0fe01fb9d72841bc5066a4c06511d" dependencies = [ - "kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", - "net2 0.2.33 (registry+https://github.com/rust-lang/crates.io-index)", - "winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", - "ws2_32-sys 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", + "base64 0.21.7", + "byteorder", + "crossbeam-channel", + "flate2", + "nom", + "num-traits", ] [[package]] -name = "native-tls" -version = "0.1.5" +name = "heapless" +version = "0.7.17" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cdc6457c0eb62c71aac4bc17216026d8410337c4126773b9c5daba343f17964f" dependencies = [ - "lazy_static 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.49 (registry+https://github.com/rust-lang/crates.io-index)", - "openssl 0.9.24 (registry+https://github.com/rust-lang/crates.io-index)", - "schannel 0.1.15 (registry+https://github.com/rust-lang/crates.io-index)", - "security-framework 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)", - "security-framework-sys 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)", - "tempdir 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)", + "atomic-polyfill", + "hash32 0.2.1", + "rustc_version", + "serde", + "spin", + "stable_deref_trait", ] [[package]] -name = "native-tls" -version = "0.2.2" +name = "heapless" +version = "0.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0bfb9eb618601c89945a70e254898da93b13be0388091d42117462b265bb3fad" dependencies = [ - "lazy_static 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.49 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", - "openssl 0.10.18 (registry+https://github.com/rust-lang/crates.io-index)", - "openssl-probe 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", - "openssl-sys 0.9.41 (registry+https://github.com/rust-lang/crates.io-index)", - "schannel 0.1.15 (registry+https://github.com/rust-lang/crates.io-index)", - "security-framework 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", - "security-framework-sys 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", - "tempfile 3.0.7 (registry+https://github.com/rust-lang/crates.io-index)", + "defmt", + "hash32 0.3.1", + "serde", + "stable_deref_trait", ] [[package]] -name = "nb" -version = "0.1.1" +name = "heck" +version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea" [[package]] -name = "ndarray" +name = "hmac" version = "0.12.1" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6c49c37c09c17a53d937dfbb742eb3a961d65a994e6bcdcf37e7399d0cc8ab5e" dependencies = [ - "itertools 0.7.11 (registry+https://github.com/rust-lang/crates.io-index)", - "matrixmultiply 0.1.15 (registry+https://github.com/rust-lang/crates.io-index)", - "num-complex 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", - "num-traits 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)", + "digest", ] [[package]] -name = "net2" -version = "0.2.33" +name = "i2cdev" +version = "0.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a01f563561b53e2def844167c92984da13779a53ca409e948a03400633cb8228" dependencies = [ - "cfg-if 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.49 (registry+https://github.com/rust-lang/crates.io-index)", - "winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", + "bitflags 2.9.0", + "byteorder", + "libc", + "nix 0.26.4", ] [[package]] -name = "nix" -version = "0.6.0" +name = "icu_collections" +version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "db2fa452206ebee18c4b5c2274dbf1de17008e874b4dc4f0aea9d01ca79e4526" dependencies = [ - "bitflags 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", - "cfg-if 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.49 (registry+https://github.com/rust-lang/crates.io-index)", - "rustc_version 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)", - "semver 0.1.20 (registry+https://github.com/rust-lang/crates.io-index)", - "void 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", + "displaydoc", + "yoke", + "zerofrom", + "zerovec", ] [[package]] -name = "nix" -version = "0.10.0" +name = "icu_locid" +version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "13acbb8371917fc971be86fc8057c41a64b521c184808a698c02acc242dbf637" dependencies = [ - "bitflags 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)", - "bytes 0.4.11 (registry+https://github.com/rust-lang/crates.io-index)", - "cfg-if 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", - "gcc 0.3.55 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.49 (registry+https://github.com/rust-lang/crates.io-index)", - "void 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", + "displaydoc", + "litemap", + "tinystr", + "writeable", + "zerovec", ] [[package]] -name = "nix" -version = "0.11.0" +name = "icu_locid_transform" +version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "01d11ac35de8e40fdeda00d9e1e9d92525f3f9d887cdd7aa81d727596788b54e" dependencies = [ - "bitflags 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)", - "cc 1.0.29 (registry+https://github.com/rust-lang/crates.io-index)", - "cfg-if 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.49 (registry+https://github.com/rust-lang/crates.io-index)", - "void 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", + "displaydoc", + "icu_locid", + "icu_locid_transform_data", + "icu_provider", + "tinystr", + "zerovec", ] [[package]] -name = "nodrop" -version = "0.1.13" +name = "icu_locid_transform_data" +version = "1.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7515e6d781098bf9f7205ab3fc7e9709d34554ae0b21ddbcb5febfa4bc7df11d" [[package]] -name = "nom" -version = "4.2.0" +name = "icu_normalizer" +version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "19ce3e0da2ec68599d193c93d088142efd7f9c5d6fc9b803774855747dc6a84f" dependencies = [ - "memchr 2.2.0 (registry+https://github.com/rust-lang/crates.io-index)", - "version_check 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", + "displaydoc", + "icu_collections", + "icu_normalizer_data", + "icu_properties", + "icu_provider", + "smallvec 1.14.0", + "utf16_iter", + "utf8_iter", + "write16", + "zerovec", ] [[package]] -name = "num" -version = "0.2.0" +name = "icu_normalizer_data" +version = "1.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c5e8338228bdc8ab83303f16b797e177953730f601a96c25d10cb3ab0daa0cb7" + +[[package]] +name = "icu_properties" +version = "1.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "93d6020766cfc6302c15dbbc9c8778c37e62c14427cb7f6e601d849e092aeef5" dependencies = [ - "num-bigint 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", - "num-complex 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", - "num-integer 0.1.39 (registry+https://github.com/rust-lang/crates.io-index)", - "num-iter 0.1.37 (registry+https://github.com/rust-lang/crates.io-index)", - "num-rational 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", - "num-traits 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)", + "displaydoc", + "icu_collections", + "icu_locid_transform", + "icu_properties_data", + "icu_provider", + "tinystr", + "zerovec", ] [[package]] -name = "num-bigint" -version = "0.2.2" +name = "icu_properties_data" +version = "1.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "85fb8799753b75aee8d2a21d7c14d9f38921b54b3dbda10f5a3c7a7b82dba5e2" + +[[package]] +name = "icu_provider" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6ed421c8a8ef78d3e2dbc98a973be2f3770cb42b606e3ab18d6237c4dfde68d9" dependencies = [ - "num-integer 0.1.39 (registry+https://github.com/rust-lang/crates.io-index)", - "num-traits 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)", + "displaydoc", + "icu_locid", + "icu_provider_macros", + "stable_deref_trait", + "tinystr", + "writeable", + "yoke", + "zerofrom", + "zerovec", ] [[package]] -name = "num-complex" -version = "0.2.1" +name = "icu_provider_macros" +version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1ec89e9337638ecdc08744df490b221a7399bf8d164eb52a665454e60e075ad6" dependencies = [ - "num-traits 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)", + "proc-macro2", + "quote", + "syn 2.0.100", ] [[package]] -name = "num-integer" -version = "0.1.39" +name = "ident_case" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b9e0384b61958566e926dc50660321d12159025e767c18e043daf26b70104c39" + +[[package]] +name = "idna" +version = "1.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "686f825264d630750a544639377bae737628043f20d38bbc029e8f29ea968a7e" dependencies = [ - "num-traits 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)", + "idna_adapter", + "smallvec 1.14.0", + "utf8_iter", ] [[package]] -name = "num-iter" -version = "0.1.37" +name = "idna_adapter" +version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "daca1df1c957320b2cf139ac61e7bd64fed304c5040df000a745aa1de3b4ef71" dependencies = [ - "num-integer 0.1.39 (registry+https://github.com/rust-lang/crates.io-index)", - "num-traits 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)", + "icu_normalizer", + "icu_properties", ] [[package]] -name = "num-rational" -version = "0.2.1" +name = "indenter" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ce23b50ad8242c51a442f3ff322d56b02f08852c77e4c0b4d3fd684abc89c683" + +[[package]] +name = "indexmap" +version = "2.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3954d50fe15b02142bf25d3b8bdadb634ec3948f103d04ffe3031bc8fe9d7058" dependencies = [ - "num-bigint 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", - "num-integer 0.1.39 (registry+https://github.com/rust-lang/crates.io-index)", - "num-traits 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)", + "equivalent", + "hashbrown 0.15.2", ] [[package]] -name = "num-traits" -version = "0.2.6" +name = "indextree" +version = "4.7.3" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "91f3e68a01402c3404bfb739079f38858325bc7ad775b07922278a8a415b1a3f" +dependencies = [ + "indextree-macros", +] [[package]] -name = "num_cpus" -version = "1.10.0" +name = "indextree-macros" +version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "477e2e7ec7379407656293ff74902caea786a1dda427ca1f84b923c4fdeb7659" dependencies = [ - "libc 0.2.49 (registry+https://github.com/rust-lang/crates.io-index)", + "either", + "itertools 0.13.0", + "proc-macro2", + "quote", + "strum 0.26.3", + "syn 2.0.100", + "thiserror 1.0.69", ] [[package]] -name = "openssl" -version = "0.9.24" +name = "indicatif" +version = "0.17.11" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "183b3088984b400f4cfac3620d5e076c84da5364016b4f49473de574b2586235" dependencies = [ - "bitflags 0.9.1 (registry+https://github.com/rust-lang/crates.io-index)", - "foreign-types 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)", - "lazy_static 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.49 (registry+https://github.com/rust-lang/crates.io-index)", - "openssl-sys 0.9.41 (registry+https://github.com/rust-lang/crates.io-index)", + "console", + "number_prefix", + "portable-atomic", + "unicode-width 0.2.0", + "web-time", ] [[package]] -name = "openssl" -version = "0.10.18" +name = "indoc" +version = "2.0.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f4c7245a08504955605670dbf141fceab975f15ca21570696aebe9d2e71576bd" + +[[package]] +name = "instability" +version = "0.3.7" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0bf9fed6d91cfb734e7476a06bde8300a1b94e217e1b523b6f0cd1a01998c71d" dependencies = [ - "bitflags 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)", - "cfg-if 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", - "foreign-types 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)", - "lazy_static 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.49 (registry+https://github.com/rust-lang/crates.io-index)", - "openssl-sys 0.9.41 (registry+https://github.com/rust-lang/crates.io-index)", + "darling", + "indoc", + "proc-macro2", + "quote", + "syn 2.0.100", ] [[package]] -name = "openssl-probe" -version = "0.1.2" +name = "instant" +version = "0.1.13" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e0242819d153cba4b4b05a5a8f2a7e9bbf97b6055b2a002b395c96b5ff3c0222" +dependencies = [ + "cfg-if", +] [[package]] -name = "openssl-sys" -version = "0.9.41" +name = "io-kit-sys" +version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "617ee6cf8e3f66f3b4ea67a4058564628cde41901316e19f559e14c7c72c5e7b" dependencies = [ - "cc 1.0.29 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.49 (registry+https://github.com/rust-lang/crates.io-index)", - "pkg-config 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)", - "vcpkg 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)", + "core-foundation-sys", + "mach2", ] [[package]] -name = "owning_ref" -version = "0.4.0" +name = "is_terminal_polyfill" +version = "1.70.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7943c866cc5cd64cbc25b2e01621d07fa8eb2a1a23160ee81ce38704e97b8ecf" + +[[package]] +name = "itertools" +version = "0.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "413ee7dfc52ee1a4949ceeb7dbc8a33f2d6c088194d9f922fb8318faf1f01186" dependencies = [ - "stable_deref_trait 1.1.1 (registry+https://github.com/rust-lang/crates.io-index)", + "either", ] [[package]] -name = "parking_lot" -version = "0.7.1" +name = "itertools" +version = "0.14.0" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2b192c782037fadd9cfa75548310488aabdbf3d2da73885b31bd0abd03351285" dependencies = [ - "lock_api 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", - "parking_lot_core 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", + "either", ] [[package]] -name = "parking_lot_core" -version = "0.4.0" +name = "itoa" +version = "1.0.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4a5f13b858c8d314ee3e8f639011f7ccefe71f97f96e50151fb991f267928e2c" + +[[package]] +name = "jiff" +version = "0.1.29" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c04ef77ae73f3cf50510712722f0c4e8b46f5aaa1bf5ffad2ae213e6495e78e5" dependencies = [ - "libc 0.2.49 (registry+https://github.com/rust-lang/crates.io-index)", - "rand 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)", - "rustc_version 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", - "smallvec 0.6.9 (registry+https://github.com/rust-lang/crates.io-index)", - "winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", + "jiff-tzdb-platform", + "log", + "portable-atomic", + "portable-atomic-util", + "serde", + "windows-sys 0.59.0", ] [[package]] -name = "percent-encoding" -version = "1.0.1" +name = "jiff-tzdb" +version = "0.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c1283705eb0a21404d2bfd6eef2a7593d240bc42a0bdb39db0ad6fa2ec026524" [[package]] -name = "phf" -version = "0.7.24" +name = "jiff-tzdb-platform" +version = "0.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "875a5a69ac2bab1a891711cf5eccbec1ce0341ea805560dcd90b7a2e925132e8" dependencies = [ - "phf_shared 0.7.24 (registry+https://github.com/rust-lang/crates.io-index)", + "jiff-tzdb", ] [[package]] -name = "phf_codegen" -version = "0.7.24" +name = "js-sys" +version = "0.3.77" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1cfaf33c695fc6e08064efbc1f72ec937429614f25eef83af942d0e227c3a28f" dependencies = [ - "phf_generator 0.7.24 (registry+https://github.com/rust-lang/crates.io-index)", - "phf_shared 0.7.24 (registry+https://github.com/rust-lang/crates.io-index)", + "once_cell", + "wasm-bindgen", ] [[package]] -name = "phf_generator" -version = "0.7.24" +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.174" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1171693293099992e19cddea4e8b849964e9846f4acee11b3948bcc337be8776" + +[[package]] +name = "libm" +version = "0.2.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8355be11b20d696c8f18f6cc018c4e372165b1fa8126cef092399c9951984ffa" + +[[package]] +name = "libredox" +version = "0.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c0ff37bd590ca25063e35af745c343cb7a0271906fb7b37e4813e8f79f00268d" dependencies = [ - "phf_shared 0.7.24 (registry+https://github.com/rust-lang/crates.io-index)", - "rand 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)", + "bitflags 2.9.0", + "libc", ] [[package]] -name = "phf_shared" -version = "0.7.24" +name = "libsystemd" +version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c592dc396b464005f78a5853555b9f240bc5378bf5221acc4e129910b2678869" dependencies = [ - "siphasher 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", - "unicase 1.4.2 (registry+https://github.com/rust-lang/crates.io-index)", + "hmac", + "libc", + "log", + "nix 0.27.1", + "nom", + "once_cell", + "serde", + "sha2", + "thiserror 1.0.69", + "uuid", ] [[package]] -name = "philipshue" -version = "0.3.2" -source = "git+https://github.com/dskleingeld/philipshue#7005847cd8dca572d411634d20c02264d6262081" +name = "linux-embedded-hal" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a8d566b726e1b6810f66c6f1c769889248439c27f06a59df2881a735454cfa02" dependencies = [ - "error-chain 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)", - "hyper 0.10.15 (registry+https://github.com/rust-lang/crates.io-index)", - "hyper-rustls 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.88 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_derive 1.0.88 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_json 1.0.38 (registry+https://github.com/rust-lang/crates.io-index)", + "cast", + "embedded-hal", + "embedded-hal-nb", + "gpio-cdev", + "i2cdev", + "nb", + "nix 0.27.1", + "serialport", + "spidev", + "sysfs_gpio", ] [[package]] -name = "pkg-config" -version = "0.3.14" +name = "linux-raw-sys" +version = "0.4.15" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d26c52dbd32dccf2d10cac7725f8eae5296885fb5703b261f7d0a0739ec807ab" [[package]] -name = "proc-macro2" +name = "litemap" +version = "0.7.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "23fb14cb19457329c82206317a5663005a4d404783dc74f4252769b0d5f42856" + +[[package]] +name = "lock_api" +version = "0.4.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "07af8b9cdd281b7915f413fa73f29ebd5d55d0d3f0155584dade1ff18cea1b17" +dependencies = [ + "autocfg", + "scopeguard", +] + +[[package]] +name = "log" version = "0.4.27" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "13dc2df351e3202783a1fe0d44375f7295ffb4049267b0f3018346dc122a1d94" + +[[package]] +name = "log-store" +version = "0.1.0" +dependencies = [ + "bincode 2.0.1", + "byteseries", + "clap", + "color-eyre", + "data-server", + "derivative", + "futures", + "futures-concurrency", + "hdrhistogram", + "heapless 0.8.0", + "jiff", + "logger", + "nucleo-matcher", + "protocol", + "reserve-port", + "rpc", + "serde", + "smallvec 2.0.0-alpha.11", + "temp-dir", + "thiserror 2.0.12", + "tokio", + "tracing", + "tracing-error", + "tracing-subscriber", +] + +[[package]] +name = "logger" +version = "0.1.0" dependencies = [ - "unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", + "color-eyre", + "governor", + "libsystemd", + "tracing", + "tracing-core", + "tracing-error", + "tracing-journald", + "tracing-subscriber", ] [[package]] -name = "quick-error" -version = "1.2.2" +name = "loom" +version = "0.5.6" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ff50ecb28bb86013e935fb6683ab1f6d3a20016f123c76fd4c27470076ac30f5" +dependencies = [ + "cfg-if", + "generator", + "scoped-tls", + "tracing", + "tracing-subscriber", +] [[package]] -name = "quote" -version = "0.6.11" +name = "lru" +version = "0.12.5" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "234cf4f4a04dc1f57e24b96cc0cd600cf2af460d4161ac5ecdd0af8e1f3b2a38" dependencies = [ - "proc-macro2 0.4.27 (registry+https://github.com/rust-lang/crates.io-index)", + "hashbrown 0.15.2", ] [[package]] -name = "rand" -version = "0.4.6" +name = "mach2" +version = "0.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "19b955cdeb2a02b9117f121ce63aa52d08ade45de53e48fe6a38b39c10f6f709" dependencies = [ - "fuchsia-cprng 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.49 (registry+https://github.com/rust-lang/crates.io-index)", - "rand_core 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", - "rdrand 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", - "winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", + "libc", ] [[package]] -name = "rand" -version = "0.5.6" +name = "manyhow" +version = "0.11.4" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b33efb3ca6d3b07393750d4030418d594ab1139cee518f0dc88db70fec873587" dependencies = [ - "cloudabi 0.0.3 (registry+https://github.com/rust-lang/crates.io-index)", - "fuchsia-cprng 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.49 (registry+https://github.com/rust-lang/crates.io-index)", - "rand_core 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", - "winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", + "manyhow-macros", + "proc-macro2", + "quote", + "syn 1.0.109", + "syn 2.0.100", ] [[package]] -name = "rand" +name = "manyhow-macros" +version = "0.11.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "46fce34d199b78b6e6073abf984c9cf5fd3e9330145a93ee0738a7443e371495" +dependencies = [ + "proc-macro-utils", + "proc-macro2", + "quote", +] + +[[package]] +name = "matchers" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8263075bb86c5a1b1427b5ae862e8889656f126e9f77c484496e8b47cf5c5558" +dependencies = [ + "regex-automata 0.1.10", +] + +[[package]] +name = "matrixmultiply" +version = "0.3.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9380b911e3e96d10c1f415da0876389aaf1b56759054eeb0de7df940c456ba1a" +dependencies = [ + "autocfg", + "rawpointer", +] + +[[package]] +name = "maybe-async-cfg" +version = "0.2.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8dbfaa67a76e2623580df07d6bb5e7956c0a4bae4b418314083a9c619bd66627" +dependencies = [ + "manyhow", + "proc-macro2", + "pulldown-cmark", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "memchr" +version = "2.7.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "78ca9ab1a0babb1e7d5695e3530886289c18cf2f87ec19a575a0abdce112e3a3" + +[[package]] +name = "memoffset" version = "0.6.5" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5aa361d4faea93603064a027415f07bd8e1d5c88c9fbf68bf56a285428fd79ce" dependencies = [ - "autocfg 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.49 (registry+https://github.com/rust-lang/crates.io-index)", - "rand_chacha 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", - "rand_core 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", - "rand_hc 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", - "rand_isaac 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", - "rand_jitter 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", - "rand_os 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", - "rand_pcg 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", - "rand_xorshift 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", - "winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", + "autocfg", ] [[package]] -name = "rand_chacha" -version = "0.1.1" +name = "memoffset" +version = "0.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5de893c32cde5f383baa4c04c5d6dbdd735cfd4a794b0debdb2bb1b421da5ff4" dependencies = [ - "autocfg 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", - "rand_core 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", + "autocfg", ] [[package]] -name = "rand_core" -version = "0.3.1" +name = "memoffset" +version = "0.9.1" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "488016bfae457b036d996092f6cb448677611ce4449e970ceaf42695203f218a" dependencies = [ - "rand_core 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", + "autocfg", ] [[package]] -name = "rand_core" -version = "0.4.0" +name = "minimal-lexical" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a" + +[[package]] +name = "miniz_oxide" +version = "0.7.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b8a240ddb74feaf34a79a7add65a741f3167852fba007066dcac1ca548d89c08" +dependencies = [ + "adler", +] + +[[package]] +name = "miniz_oxide" +version = "0.8.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e3e04debbb59698c15bacbb6d93584a8c0ca9cc3213cb423d31f760d8843ce5" +dependencies = [ + "adler2", +] + +[[package]] +name = "mio" +version = "1.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2886843bf800fba2e3377cff24abf6379b4c4d5c6681eaf9ea5b0d15090450bd" +dependencies = [ + "libc", + "log", + "wasi 0.11.0+wasi-snapshot-preview1", + "windows-sys 0.52.0", +] + +[[package]] +name = "mpd" +version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2e12cace5746cb0aa78faa6cd2caec9f9c01882fc0e6b54d34685a2d3303ea34" +dependencies = [ + "bufstream", +] [[package]] -name = "rand_hc" +name = "mpdrs" version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dec81b7ee8968b02af77c52cbcee75a33e83924a4322090f3d83075bd2032686" dependencies = [ - "rand_core 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", + "bufstream", ] [[package]] -name = "rand_isaac" -version = "0.1.1" +name = "nalgebra" +version = "0.33.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "26aecdf64b707efd1310e3544d709c5c0ac61c13756046aaaba41be5c4f66a3b" +dependencies = [ + "approx", + "matrixmultiply", + "nalgebra-macros", + "num-complex", + "num-rational", + "num-traits", + "simba", + "typenum", +] + +[[package]] +name = "nalgebra-macros" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "254a5372af8fc138e36684761d3c0cdb758a4410e938babcff1c860ce14ddbfc" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.100", +] + +[[package]] +name = "nb" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8d5439c4ad607c3c23abf66de8c8bf57ba8adcd1f129e699851a6e43935d339d" + +[[package]] +name = "nibble_vec" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "77a5d83df9f36fe23f0c3648c6bbb8b0298bb5f1939c8f2704431371f4b84d43" +dependencies = [ + "smallvec 1.14.0", +] + +[[package]] +name = "nix" +version = "0.23.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f3790c00a0150112de0f4cd161e3d7fc4b2d8a5542ffc35f099a2562aecb35c" +dependencies = [ + "bitflags 1.3.2", + "cc", + "cfg-if", + "libc", + "memoffset 0.6.5", +] + +[[package]] +name = "nix" +version = "0.26.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "598beaf3cc6fdd9a5dfb1630c2800c7acd31df7aaf0f565796fba2b53ca1af1b" +dependencies = [ + "bitflags 1.3.2", + "cfg-if", + "libc", + "memoffset 0.7.1", + "pin-utils", +] + +[[package]] +name = "nix" +version = "0.27.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2eb04e9c688eff1c89d72b407f168cf79bb9e867a9d3323ed6c01519eb9cc053" +dependencies = [ + "bitflags 2.9.0", + "cfg-if", + "libc", + "memoffset 0.9.1", +] + +[[package]] +name = "no-std-compat" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b93853da6d84c2e3c7d730d6473e8817692dd89be387eb01b94d7f108ecb5b8c" + +[[package]] +name = "nom" +version = "7.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d273983c5a657a70a3e8f2a01329822f3b8c8172b73826411a55751e404a0a4a" +dependencies = [ + "memchr", + "minimal-lexical", +] + +[[package]] +name = "nonzero_ext" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "38bf9645c8b145698bb0b18a4637dcacbc421ea49bef2317e4fd8065a387cf21" + +[[package]] +name = "nu-ansi-term" +version = "0.46.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "77a8165726e8236064dbb45459242600304b42a5ea24ee2948e18e023bf7ba84" +dependencies = [ + "overload", + "winapi", +] + +[[package]] +name = "nucleo-matcher" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bf33f538733d1a5a3494b836ba913207f14d9d4a1d3cd67030c5061bdd2cac85" +dependencies = [ + "memchr", + "unicode-segmentation", +] + +[[package]] +name = "num" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "35bd024e8b2ff75562e5f34e7f4905839deb4b22955ef5e73d2fea1b9813cb23" +dependencies = [ + "num-bigint", + "num-complex", + "num-integer", + "num-iter", + "num-rational", + "num-traits", +] + +[[package]] +name = "num-bigint" +version = "0.4.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a5e44f723f1133c9deac646763579fdb3ac745e418f2a7af9cd0c431da1f20b9" +dependencies = [ + "num-integer", + "num-traits", +] + +[[package]] +name = "num-complex" +version = "0.4.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "73f88a1307638156682bada9d7604135552957b7818057dcef22705b4d509495" +dependencies = [ + "num-traits", +] + +[[package]] +name = "num-integer" +version = "0.1.46" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7969661fd2958a5cb096e56c8e1ad0444ac2bbcd0061bd28660485a44879858f" +dependencies = [ + "num-traits", +] + +[[package]] +name = "num-iter" +version = "0.1.45" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1429034a0490724d0075ebb2bc9e875d6503c3cf69e235a8941aa757d83ef5bf" +dependencies = [ + "autocfg", + "num-integer", + "num-traits", +] + +[[package]] +name = "num-rational" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f83d14da390562dca69fc84082e73e548e1ad308d24accdedd2720017cb37824" +dependencies = [ + "num-bigint", + "num-integer", + "num-traits", +] + +[[package]] +name = "num-traits" +version = "0.2.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841" +dependencies = [ + "autocfg", +] + +[[package]] +name = "number_prefix" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "830b246a0e5f20af87141b25c173cd1b609bd7779a4617d6ec582abaf90870f3" + +[[package]] +name = "nusb" +version = "0.1.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "99a726776e551f3ee9b467fe47202f26e64b9bbf715df5443b0904df6f2dcc41" +dependencies = [ + "atomic-waker", + "core-foundation 0.9.4", + "core-foundation-sys", + "futures-core", + "io-kit-sys", + "libc", + "log", + "once_cell", + "rustix", + "slab", + "windows-sys 0.48.0", +] + +[[package]] +name = "object" +version = "0.32.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a6a622008b6e321afc04970976f62ee297fdbaa6f95318ca343e3eebb9648441" +dependencies = [ + "memchr", +] + +[[package]] +name = "once_cell" +version = "1.21.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "42f5e15c9953c5e4ccceeb2e7382a716482c34515315f7b03532b8b4e8393d2d" + +[[package]] +name = "option-ext" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "04744f49eae99ab78e0d5c0b603ab218f515ea8cfe5a456d7629ad883a3b6e7d" + +[[package]] +name = "overload" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b15813163c1d831bf4a13c3610c05c0d03b39feb07f7e09fa234dac9b15aaf39" + +[[package]] +name = "owo-colors" +version = "3.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c1b04fb49957986fdce4d6ee7a65027d55d4b6d2265e5848bbb507b58ccfdb6f" + +[[package]] +name = "parking" +version = "2.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f38d5652c16fde515bb1ecef450ab0f6a219d619a7274976324d5e377f7dceba" + +[[package]] +name = "parking_lot" +version = "0.11.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7d17b78036a60663b797adeaee46f5c9dfebb86948d1255007a1d6be0271ff99" +dependencies = [ + "instant", + "lock_api", + "parking_lot_core 0.8.6", +] + +[[package]] +name = "parking_lot" +version = "0.12.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f1bf18183cf54e8d6059647fc3063646a1801cf30896933ec2311622cc4b9a27" +dependencies = [ + "lock_api", + "parking_lot_core 0.9.10", +] + +[[package]] +name = "parking_lot_core" +version = "0.8.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "60a2cfe6f0ad2bfc16aefa463b497d5c7a5ecd44a23efa72aa342d90177356dc" +dependencies = [ + "cfg-if", + "instant", + "libc", + "redox_syscall 0.2.16", + "smallvec 1.14.0", + "winapi", +] + +[[package]] +name = "parking_lot_core" +version = "0.9.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e401f977ab385c9e4e3ab30627d6f26d00e2c73eef317493c4ec6d468726cf8" +dependencies = [ + "cfg-if", + "libc", + "redox_syscall 0.5.10", + "smallvec 1.14.0", + "windows-targets 0.52.6", +] + +[[package]] +name = "paste" +version = "1.0.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "57c0d7b74b563b49d38dae00a0c37d4d6de9b432382b2892f0574ddcae73fd0a" + +[[package]] +name = "percent-encoding" +version = "2.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e3148f5046208a5d56bcfc03053e3ca6334e51da8dfb19b6cdc8b306fae3283e" + +[[package]] +name = "pin-project" +version = "1.1.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "677f1add503faace112b9f1373e43e9e054bfdd22ff1a63c1bc485eaec6a6a8a" +dependencies = [ + "pin-project-internal", +] + +[[package]] +name = "pin-project-internal" +version = "1.1.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6e918e4ff8c4549eb882f14b3a4bc8c8bc93de829416eacf579f1207a8fbf861" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.100", +] + +[[package]] +name = "pin-project-lite" +version = "0.2.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3b3cff922bd51709b605d9ead9aa71031d81447142d828eb4a6eba76fe619f9b" + +[[package]] +name = "pin-utils" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" + +[[package]] +name = "portable-atomic" +version = "1.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "350e9b48cbc6b0e028b0473b114454c6316e57336ee184ceab6e53f72c178b3e" + +[[package]] +name = "portable-atomic-util" +version = "0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d8a2f0d8d040d7848a709caf78912debcc3f33ee4b3cac47d73d1e1069e83507" +dependencies = [ + "portable-atomic", +] + +[[package]] +name = "postcard" +version = "1.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "170a2601f67cc9dba8edd8c4870b15f71a6a2dc196daec8c83f72b59dff628a8" +dependencies = [ + "cobs", + "defmt", + "embedded-io 0.4.0", + "embedded-io 0.6.1", + "heapless 0.7.17", + "postcard-derive", + "serde", +] + +[[package]] +name = "postcard-derive" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0239fa9c1d225d4b7eb69925c25c5e082307a141e470573fbbe3a817ce6a7a37" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "ppv-lite86" +version = "0.2.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "85eae3c4ed2f50dcfe72643da4befc30deadb458a9b590d720cde2f2b1e97da9" +dependencies = [ + "zerocopy", +] + +[[package]] +name = "proc-macro-crate" +version = "3.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "edce586971a4dfaa28950c6f18ed55e0406c1ab88bbce2c6f6293a7aaba73d35" +dependencies = [ + "toml_edit", +] + +[[package]] +name = "proc-macro-error" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "da25490ff9892aab3fcf7c36f08cfb902dd3e71ca0f9f9517bea02a73a5ce38c" +dependencies = [ + "proc-macro-error-attr", + "proc-macro2", + "quote", + "syn 1.0.109", + "version_check", +] + +[[package]] +name = "proc-macro-error-attr" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a1be40180e52ecc98ad80b184934baf3d0d29f979574e439af5a55274b35f869" +dependencies = [ + "proc-macro2", + "quote", + "version_check", +] + +[[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.100", +] + +[[package]] +name = "proc-macro-utils" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eeaf08a13de400bc215877b5bdc088f241b12eb42f0a548d3390dc1c56bb7071" +dependencies = [ + "proc-macro2", + "quote", + "smallvec 1.14.0", +] + +[[package]] +name = "proc-macro2" +version = "1.0.94" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a31971752e70b8b2686d7e46ec17fb38dad4051d94024c88df49b667caea9c84" +dependencies = [ + "unicode-ident", +] + +[[package]] +name = "promptly" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9acbc6c5a5b029fe58342f58445acb00ccfe24624e538894bc2f04ce112980ba" +dependencies = [ + "rustyline", +] + +[[package]] +name = "protocol" +version = "0.1.0" +dependencies = [ + "defmt", + "heapless 0.8.0", + "postcard", + "serde", + "strum 0.27.1", + "thiserror 2.0.12", +] + +[[package]] +name = "pulldown-cmark" +version = "0.11.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "679341d22c78c6c649893cbd6c3278dcbe9fc4faa62fea3a9296ae2b50c14625" +dependencies = [ + "bitflags 2.9.0", + "memchr", + "unicase", +] + +[[package]] +name = "quanta" +version = "0.12.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3bd1fe6824cea6538803de3ff1bc0cf3949024db3d43c9643024bfb33a807c0e" +dependencies = [ + "crossbeam-utils", + "libc", + "once_cell", + "raw-cpuid", + "wasi 0.11.0+wasi-snapshot-preview1", + "web-sys", + "winapi", +] + +[[package]] +name = "quote" +version = "1.0.40" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1885c039570dc00dcb4ff087a89e185fd56bae234ddc7f056a945bf36467248d" +dependencies = [ + "proc-macro2", +] + +[[package]] +name = "r-efi" +version = "5.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "74765f6d916ee2faa39bc8e68e4f3ed8949b48cccdac59983d287a7cb71ce9c5" + +[[package]] +name = "radiator-bridge" +version = "0.1.0" +dependencies = [ + "clap", + "color-eyre", + "data-server", + "futures", + "futures-concurrency", + "logger", + "protocol", + "tokio", + "tracing", + "zigbee-bridge", +] + +[[package]] +name = "radix_trie" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c069c179fcdc6a2fe24d8d18305cf085fdbd4f922c041943e203685d6a1c58fd" +dependencies = [ + "endian-type", + "nibble_vec", +] + +[[package]] +name = "rand" +version = "0.8.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404" +dependencies = [ + "libc", + "rand_chacha 0.3.1", + "rand_core 0.6.4", +] + +[[package]] +name = "rand" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3779b94aeb87e8bd4e834cee3650289ee9e0d5677f976ecdb6d219e5f4f6cd94" +dependencies = [ + "rand_chacha 0.9.0", + "rand_core 0.9.3", + "zerocopy", +] + +[[package]] +name = "rand_chacha" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88" +dependencies = [ + "ppv-lite86", + "rand_core 0.6.4", +] + +[[package]] +name = "rand_chacha" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d3022b5f1df60f26e1ffddd6c66e8aa15de382ae63b3a0c1bfc0e4d3e3f325cb" +dependencies = [ + "ppv-lite86", + "rand_core 0.9.3", +] + +[[package]] +name = "rand_core" +version = "0.6.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" +dependencies = [ + "getrandom 0.2.15", +] + +[[package]] +name = "rand_core" +version = "0.9.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "99d9a13982dcf210057a8a78572b2217b667c3beacbf3a0d8b454f6f82837d38" +dependencies = [ + "getrandom 0.3.2", +] + +[[package]] +name = "ratatui" +version = "0.29.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eabd94c2f37801c20583fc49dd5cd6b0ba68c716787c2dd6ed18571e1e63117b" +dependencies = [ + "bitflags 2.9.0", + "cassowary", + "compact_str", + "crossterm", + "indoc", + "instability", + "itertools 0.13.0", + "lru", + "paste", + "strum 0.26.3", + "unicode-segmentation", + "unicode-truncate", + "unicode-width 0.2.0", +] + +[[package]] +name = "raw-cpuid" +version = "11.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c6df7ab838ed27997ba19a4664507e6f82b41fe6e20be42929332156e5e85146" +dependencies = [ + "bitflags 2.9.0", +] + +[[package]] +name = "rawpointer" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "60a357793950651c4ed0f3f52338f53b2f809f32d83a07f72909fa13e4c6c1e3" + +[[package]] +name = "redox_syscall" +version = "0.2.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fb5a58c1855b4b6819d59012155603f0b22ad30cad752600aadfcb695265519a" +dependencies = [ + "bitflags 1.3.2", +] + +[[package]] +name = "redox_syscall" +version = "0.5.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b8c0c260b63a8219631167be35e6a988e9554dbd323f8bd08439c8ed1302bd1" +dependencies = [ + "bitflags 2.9.0", +] + +[[package]] +name = "redox_users" +version = "0.4.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ba009ff324d1fc1b900bd1fdb31564febe58a8ccc8a6fdbb93b543d33b13ca43" +dependencies = [ + "getrandom 0.2.15", + "libredox", + "thiserror 1.0.69", +] + +[[package]] +name = "redox_users" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dd6f9d3d47bdd2ad6945c5015a226ec6155d0bcdfd8f7cd29f86b71f8de99d2b" +dependencies = [ + "getrandom 0.2.15", + "libredox", + "thiserror 2.0.12", +] + +[[package]] +name = "regex" +version = "1.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b544ef1b4eac5dc2db33ea63606ae9ffcfac26c1416a2806ae0bf5f56b201191" +dependencies = [ + "aho-corasick", + "memchr", + "regex-automata 0.4.9", + "regex-syntax 0.8.5", +] + +[[package]] +name = "regex-automata" +version = "0.1.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6c230d73fb8d8c1b9c0b3135c5142a8acee3a0558fb8db5cf1cb65f8d7862132" +dependencies = [ + "regex-syntax 0.6.29", +] + +[[package]] +name = "regex-automata" +version = "0.4.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "809e8dc61f6de73b46c85f4c96486310fe304c434cfa43669d7b40f711150908" +dependencies = [ + "aho-corasick", + "memchr", + "regex-syntax 0.8.5", +] + +[[package]] +name = "regex-syntax" +version = "0.6.29" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f162c6dd7b008981e4d40210aca20b4bd0f9b60ca9271061b07f78537722f2e1" + +[[package]] +name = "regex-syntax" +version = "0.8.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2b15c43186be67a4fd63bee50d0303afffcef381492ebe2c5d87f324e1b8815c" + +[[package]] +name = "relative-path" +version = "1.9.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ba39f3699c378cd8970968dcbff9c43159ea4cfbd88d43c00b22f2ef10a435d2" + +[[package]] +name = "reserve-port" +version = "2.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ba3747658ee2585ecf5607fa9887c92eff61b362ff5253dbf797dfeb73d33d78" +dependencies = [ + "thiserror 2.0.12", +] + +[[package]] +name = "ron" +version = "0.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b91f7eff05f748767f183df4320a63d6936e9c6107d97c9e6bdd9784f4289c94" +dependencies = [ + "base64 0.21.7", + "bitflags 2.9.0", + "serde", + "serde_derive", +] + +[[package]] +name = "ron" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "63f3aa105dea217ef30d89581b65a4d527a19afc95ef5750be3890e8d3c5b837" +dependencies = [ + "base64 0.22.1", + "bitflags 2.9.0", + "serde", + "serde_derive", + "unicode-ident", +] + +[[package]] +name = "rpc" +version = "0.1.0" +dependencies = [ + "color-eyre", + "futures", + "governor", + "serde", + "thiserror 2.0.12", + "tokio", + "tokio-serde", + "tokio-util", + "tracing", +] + +[[package]] +name = "rstest" +version = "0.25.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6fc39292f8613e913f7df8fa892b8944ceb47c247b78e1b1ae2f09e019be789d" +dependencies = [ + "futures-timer", + "futures-util", + "rstest_macros", + "rustc_version", +] + +[[package]] +name = "rstest_macros" +version = "0.25.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1f168d99749d307be9de54d23fd226628d99768225ef08f6ffb52e0182a27746" +dependencies = [ + "cfg-if", + "glob", + "proc-macro-crate", + "proc-macro2", + "quote", + "regex", + "relative-path", + "rustc_version", + "syn 2.0.100", + "unicode-ident", +] + +[[package]] +name = "rumqttc" +version = "0.24.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e1568e15fab2d546f940ed3a21f48bbbd1c494c90c99c4481339364a497f94a9" +dependencies = [ + "bytes", + "flume", + "futures-util", + "log", + "thiserror 1.0.69", + "tokio", +] + +[[package]] +name = "rustc-demangle" +version = "0.1.24" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "719b953e2095829ee67db738b3bfa9fa368c94900df327b3f07fe6e794d2fe1f" + +[[package]] +name = "rustc_version" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cfcb3a22ef46e85b45de6ee7e79d063319ebb6594faafcf1c225ea92ab6e9b92" +dependencies = [ + "semver", +] + +[[package]] +name = "rustix" +version = "0.38.44" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fdb5bc1ae2baa591800df16c9ca78619bf65c0488b41b96ccec5d11220d8c154" +dependencies = [ + "bitflags 2.9.0", + "errno", + "libc", + "linux-raw-sys", + "windows-sys 0.59.0", +] + +[[package]] +name = "rustversion" +version = "1.0.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eded382c5f5f786b989652c49544c4877d9f015cc22e145a5ea8ea66c2921cd2" + +[[package]] +name = "rustyline" +version = "9.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "db7826789c0e25614b03e5a54a0717a86f9ff6e6e5247f92b369472869320039" +dependencies = [ + "bitflags 1.3.2", + "cfg-if", + "clipboard-win", + "dirs-next", + "fd-lock", + "libc", + "log", + "memchr", + "nix 0.23.2", + "radix_trie", + "scopeguard", + "smallvec 1.14.0", + "unicode-segmentation", + "unicode-width 0.1.14", + "utf8parse", + "winapi", +] + +[[package]] +name = "ryu" +version = "1.0.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "28d3b2b1366ec20994f1fd18c3c594f05c5dd4bc44d8bb0c1c632c8d6829481f" + +[[package]] +name = "safe_arch" +version = "0.7.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "96b02de82ddbe1b636e6170c21be622223aea188ef2e139be0a5b219ec215323" +dependencies = [ + "bytemuck", +] + +[[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 = "1.0.26" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "56e6fa9c48d24d85fb3de5ad847117517440f6beceb7798af16b4a87d616b8d0" + +[[package]] +name = "serde" +version = "1.0.219" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5f0e2c6ed6606019b4e29e69dbaba95b11854410e5347d525002456dbbb786b6" +dependencies = [ + "serde_derive", +] + +[[package]] +name = "serde_derive" +version = "1.0.219" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5b0276cf7f2c73365f7157c8123c21cd9a50fbbd844757af28ca1f5925fc2a00" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.100", +] + +[[package]] +name = "serde_json" +version = "1.0.140" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "20068b6e96dc6c9bd23e01df8827e6c7e1f2fddd43c21810382803c136b99373" +dependencies = [ + "itoa", + "memchr", + "ryu", + "serde", +] + +[[package]] +name = "serde_yaml" +version = "0.9.34+deprecated" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6a8b1a1a2ebf674015cc02edccce75287f1a0130d394307b36743c2f5d504b47" +dependencies = [ + "indexmap", + "itoa", + "ryu", + "serde", + "unsafe-libyaml", +] + +[[package]] +name = "serialport" +version = "4.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2daa7abb9b965493e3c8f4184c6f46435484ff2538a332b886788cf6768b927b" +dependencies = [ + "bitflags 2.9.0", + "cfg-if", + "core-foundation 0.10.0", + "core-foundation-sys", + "io-kit-sys", + "mach2", + "nix 0.26.4", + "scopeguard", + "unescaper", + "winapi", +] + +[[package]] +name = "sha2" +version = "0.10.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "793db75ad2bcafc3ffa7c68b215fee268f537982cd901d132f89c6343f3a3dc8" +dependencies = [ + "cfg-if", + "cpufeatures", + "digest", +] + +[[package]] +name = "sharded-slab" +version = "0.1.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f40ca3c46823713e0d4209592e8d6e826aa57e928f09752619fc696c499637f6" +dependencies = [ + "lazy_static", +] + +[[package]] +name = "shlex" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64" + +[[package]] +name = "shutdown-async" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e2799e69bde7e68bedd86c6d94bffa783219114f1f31435ddda61f4aeba348ff" +dependencies = [ + "tokio", +] + +[[package]] +name = "signal-hook" +version = "0.3.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8621587d4798caf8eb44879d42e56b9a93ea5dcd315a6487c357130095b62801" +dependencies = [ + "libc", + "signal-hook-registry", +] + +[[package]] +name = "signal-hook-mio" +version = "0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "34db1a06d485c9142248b7a054f034b349b212551f3dfd19c94d45a754a217cd" +dependencies = [ + "libc", + "mio", + "signal-hook", +] + +[[package]] +name = "signal-hook-registry" +version = "1.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a9e9e0b4211b72e7b8b6e85c807d36c212bdb33ea8587f7569562a84df5465b1" +dependencies = [ + "libc", +] + +[[package]] +name = "simba" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b3a386a501cd104797982c15ae17aafe8b9261315b5d07e3ec803f2ea26be0fa" +dependencies = [ + "approx", + "num-complex", + "num-traits", + "paste", + "wide", +] + +[[package]] +name = "slab" +version = "0.4.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f92a496fb766b417c996b9c5e57daf2f7ad3b0bebe1ccfca4856390e3d3bb67" +dependencies = [ + "autocfg", +] + +[[package]] +name = "sled" +version = "0.34.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7f96b4737c2ce5987354855aed3797279def4ebf734436c6aa4552cf8e169935" +dependencies = [ + "crc32fast", + "crossbeam-epoch", + "crossbeam-utils", + "fs2", + "fxhash", + "libc", + "log", + "parking_lot 0.11.2", +] + +[[package]] +name = "slotmap" +version = "1.0.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dbff4acf519f630b3a3ddcfaea6c06b42174d9a44bc70c620e9ed1649d58b82a" +dependencies = [ + "version_check", +] + +[[package]] +name = "smallvec" +version = "1.14.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7fcf8323ef1faaee30a44a340193b1ac6814fd9b7b4e88e9d4519a3e4abe1cfd" + +[[package]] +name = "smallvec" +version = "2.0.0-alpha.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "87b96efa4bd6bdd2ff0c6615cc36fc4970cbae63cfd46ddff5cee35a1b4df570" + +[[package]] +name = "socket2" +version = "0.5.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c970269d99b64e60ec3bd6ad27270092a5394c4e309314b18ae3fe575695fbe8" +dependencies = [ + "libc", + "windows-sys 0.52.0", +] + +[[package]] +name = "socket2" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "233504af464074f9d066d7b5416c5f9b894a5862a6506e306f7b816cdd6f1807" +dependencies = [ + "libc", + "windows-sys 0.59.0", +] + +[[package]] +name = "spidev" +version = "0.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c2800c129338c77998c1dcb6d4200447e018beb7d29959eb104cba2d45f83c1a" dependencies = [ - "rand_core 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", + "bitflags 2.9.0", + "libc", + "nix 0.26.4", ] [[package]] -name = "rand_jitter" -version = "0.1.3" +name = "spin" +version = "0.9.8" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6980e8d7511241f8acf4aebddbb1ff938df5eebe98691418c4468d0b72a96a67" dependencies = [ - "libc 0.2.49 (registry+https://github.com/rust-lang/crates.io-index)", - "rand_core 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", - "winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", + "lock_api", ] [[package]] -name = "rand_os" -version = "0.1.2" +name = "spinning_top" +version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d96d2d1d716fb500937168cc09353ffdc7a012be8475ac7308e1bdf0e3923300" dependencies = [ - "cloudabi 0.0.3 (registry+https://github.com/rust-lang/crates.io-index)", - "fuchsia-cprng 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.49 (registry+https://github.com/rust-lang/crates.io-index)", - "rand_core 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", - "rdrand 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", - "winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", + "lock_api", ] [[package]] -name = "rand_pcg" -version = "0.1.2" +name = "stable_deref_trait" +version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "autocfg 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", - "rand_core 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", -] +checksum = "a8f112729512f8e442d81f95a8a7ddf2b7c6b8a1a6f509a95864142b30cab2d3" [[package]] -name = "rand_xorshift" -version = "0.1.1" +name = "static_assertions" +version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "rand_core 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", -] +checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f" [[package]] -name = "rawpointer" -version = "0.1.0" +name = "str-buf" +version = "1.0.6" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9e08d8363704e6c71fc928674353e6b7c23dcea9d82d7012c8faf2a3a025f8d0" [[package]] -name = "rdrand" -version = "0.4.0" +name = "strip-ansi-escapes" +version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2a8f8038e7e7969abb3f1b7c2a811225e9296da208539e0f79c5251d6cac0025" dependencies = [ - "rand_core 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", + "vte", ] [[package]] -name = "redox_syscall" -version = "0.1.51" +name = "strsim" +version = "0.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f" [[package]] -name = "redox_termios" -version = "0.1.1" +name = "strum" +version = "0.26.3" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8fec0f0aef304996cf250b31b5a10dee7980c85da9d759361292b8bca5a18f06" dependencies = [ - "redox_syscall 0.1.51 (registry+https://github.com/rust-lang/crates.io-index)", + "strum_macros 0.26.4", ] [[package]] -name = "regex" -version = "0.2.11" +name = "strum" +version = "0.27.1" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f64def088c51c9510a8579e3c5d67c65349dcf755e5479ad3d010aa6454e2c32" dependencies = [ - "aho-corasick 0.6.10 (registry+https://github.com/rust-lang/crates.io-index)", - "memchr 2.2.0 (registry+https://github.com/rust-lang/crates.io-index)", - "regex-syntax 0.5.6 (registry+https://github.com/rust-lang/crates.io-index)", - "thread_local 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", - "utf8-ranges 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", + "strum_macros 0.27.1", ] [[package]] -name = "regex" -version = "1.1.0" +name = "strum_macros" +version = "0.26.4" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4c6bee85a5a24955dc440386795aa378cd9cf82acd5f764469152d2270e581be" dependencies = [ - "aho-corasick 0.6.10 (registry+https://github.com/rust-lang/crates.io-index)", - "memchr 2.2.0 (registry+https://github.com/rust-lang/crates.io-index)", - "regex-syntax 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)", - "thread_local 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", - "utf8-ranges 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", + "heck", + "proc-macro2", + "quote", + "rustversion", + "syn 2.0.100", ] [[package]] -name = "regex-syntax" -version = "0.5.6" +name = "strum_macros" +version = "0.27.1" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c77a8c5abcaf0f9ce05d62342b7d298c346515365c36b673df4ebe3ced01fde8" dependencies = [ - "ucd-util 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", + "heck", + "proc-macro2", + "quote", + "rustversion", + "syn 2.0.100", ] [[package]] -name = "regex-syntax" -version = "0.6.5" +name = "subtle" +version = "2.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "ucd-util 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", -] +checksum = "13c2bddecc57b384dee18652358fb23172facb8a2c51ccc10d74c157bdea3292" [[package]] -name = "remove_dir_all" -version = "0.5.1" +name = "syn" +version = "1.0.109" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237" dependencies = [ - "winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", + "proc-macro2", + "quote", + "unicode-ident", ] [[package]] -name = "reqwest" -version = "0.6.2" +name = "syn" +version = "2.0.100" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b09a44accad81e1ba1cd74a32461ba89dee89095ba17b32f5d03683b1b1fc2a0" dependencies = [ - "hyper 0.10.15 (registry+https://github.com/rust-lang/crates.io-index)", - "hyper-native-tls 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)", - "libflate 0.1.20 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.88 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_json 1.0.38 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_urlencoded 0.5.4 (registry+https://github.com/rust-lang/crates.io-index)", - "url 1.7.2 (registry+https://github.com/rust-lang/crates.io-index)", + "proc-macro2", + "quote", + "unicode-ident", ] [[package]] -name = "reqwest" -version = "0.9.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "base64 0.10.1 (registry+https://github.com/rust-lang/crates.io-index)", - "bytes 0.4.11 (registry+https://github.com/rust-lang/crates.io-index)", - "encoding_rs 0.8.17 (registry+https://github.com/rust-lang/crates.io-index)", - "futures 0.1.25 (registry+https://github.com/rust-lang/crates.io-index)", - "http 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)", - "hyper 0.12.24 (registry+https://github.com/rust-lang/crates.io-index)", - "hyper-tls 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", - "libflate 0.1.20 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", - "mime 0.3.13 (registry+https://github.com/rust-lang/crates.io-index)", - "mime_guess 2.0.0-alpha.6 (registry+https://github.com/rust-lang/crates.io-index)", - "native-tls 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.88 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_json 1.0.38 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_urlencoded 0.5.4 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio 0.1.15 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-executor 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-io 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-threadpool 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-timer 0.2.10 (registry+https://github.com/rust-lang/crates.io-index)", - "url 1.7.2 (registry+https://github.com/rust-lang/crates.io-index)", - "uuid 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "resolv-conf" -version = "0.6.2" +name = "synstructure" +version = "0.13.1" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c8af7666ab7b6390ab78131fb5b0fce11d6b7a6951602017c35fa82800708971" dependencies = [ - "hostname 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", - "quick-error 1.2.2 (registry+https://github.com/rust-lang/crates.io-index)", + "proc-macro2", + "quote", + "syn 2.0.100", ] [[package]] -name = "ring" -version = "0.13.5" +name = "sysfs_gpio" +version = "0.6.2" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e8808c55bc926565c62ef7838bcaa8add51585236803e2bdfa1472e3a3ab5e17" dependencies = [ - "cc 1.0.29 (registry+https://github.com/rust-lang/crates.io-index)", - "lazy_static 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.49 (registry+https://github.com/rust-lang/crates.io-index)", - "untrusted 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)", + "nix 0.23.2", ] [[package]] -name = "rustc-demangle" -version = "0.1.13" +name = "temp-dir" +version = "0.1.14" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bc1ee6eef34f12f765cb94725905c6312b6610ab2b0940889cfe58dae7bc3c72" [[package]] -name = "rustc_version" -version = "0.1.7" +name = "thiserror" +version = "1.0.69" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b6aaf5339b578ea85b50e080feb250a3e8ae8cfcdff9a461c9ec2904bc923f52" dependencies = [ - "semver 0.1.20 (registry+https://github.com/rust-lang/crates.io-index)", + "thiserror-impl 1.0.69", ] [[package]] -name = "rustc_version" -version = "0.2.3" +name = "thiserror" +version = "2.0.12" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "567b8a2dae586314f7be2a752ec7474332959c6460e02bde30d702a66d488708" dependencies = [ - "semver 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", + "thiserror-impl 2.0.12", ] [[package]] -name = "rustls" -version = "0.13.1" +name = "thiserror-impl" +version = "1.0.69" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4fee6c4efc90059e10f81e6d42c60a18f76588c3d74cb83a0b242a2b6c7504c1" dependencies = [ - "base64 0.9.3 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", - "ring 0.13.5 (registry+https://github.com/rust-lang/crates.io-index)", - "sct 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", - "untrusted 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)", - "webpki 0.18.1 (registry+https://github.com/rust-lang/crates.io-index)", + "proc-macro2", + "quote", + "syn 2.0.100", ] [[package]] -name = "rustls" -version = "0.14.0" +name = "thiserror-impl" +version = "2.0.12" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7f7cf42b4507d8ea322120659672cf1b9dbb93f8f2d4ecfd6e51350ff5b17a1d" dependencies = [ - "base64 0.9.3 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", - "ring 0.13.5 (registry+https://github.com/rust-lang/crates.io-index)", - "sct 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", - "untrusted 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)", - "webpki 0.18.1 (registry+https://github.com/rust-lang/crates.io-index)", + "proc-macro2", + "quote", + "syn 2.0.100", ] [[package]] -name = "ryu" -version = "0.2.7" -source = "registry+https://github.com/rust-lang/crates.io-index" - -[[package]] -name = "safemem" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" - -[[package]] -name = "same-file" -version = "1.0.4" +name = "thread_local" +version = "1.1.8" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8b9ef9bad013ada3808854ceac7b46812a6465ba368859a37e2100283d2d719c" dependencies = [ - "winapi-util 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", + "cfg-if", + "once_cell", ] [[package]] -name = "schannel" -version = "0.1.15" +name = "tinystr" +version = "0.7.6" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9117f5d4db391c1cf6927e7bea3db74b9a1c1add8f7eda9ffd5364f40f57b82f" dependencies = [ - "lazy_static 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)", - "winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", + "displaydoc", + "zerovec", ] [[package]] -name = "scopeguard" -version = "0.3.3" -source = "registry+https://github.com/rust-lang/crates.io-index" - -[[package]] -name = "sct" -version = "0.4.0" +name = "tokio" +version = "1.44.1" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f382da615b842244d4b8738c82ed1275e6c5dd90c459a30941cd07080b06c91a" dependencies = [ - "ring 0.13.5 (registry+https://github.com/rust-lang/crates.io-index)", - "untrusted 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)", + "backtrace", + "bytes", + "libc", + "mio", + "parking_lot 0.12.3", + "pin-project-lite", + "signal-hook-registry", + "socket2 0.5.8", + "tokio-macros", + "windows-sys 0.52.0", ] [[package]] -name = "security-framework" -version = "0.1.16" +name = "tokio-macros" +version = "2.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6e06d43f1345a3bcd39f6a56dbb7dcab2ba47e68e8ac134855e7e2bdbaf8cab8" dependencies = [ - "core-foundation 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", - "core-foundation-sys 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.49 (registry+https://github.com/rust-lang/crates.io-index)", - "security-framework-sys 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)", + "proc-macro2", + "quote", + "syn 2.0.100", ] [[package]] -name = "security-framework" -version = "0.2.2" +name = "tokio-serde" +version = "0.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "caf600e7036b17782571dd44fa0a5cea3c82f60db5137f774a325a76a0d6852b" dependencies = [ - "core-foundation 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)", - "core-foundation-sys 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.49 (registry+https://github.com/rust-lang/crates.io-index)", - "security-framework-sys 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", + "bincode 1.3.3", + "bytes", + "educe", + "futures-core", + "futures-sink", + "pin-project", + "serde", ] [[package]] -name = "security-framework-sys" -version = "0.1.16" +name = "tokio-util" +version = "0.7.16" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "14307c986784f72ef81c89db7d9e28d6ac26d16213b109ea501696195e6e3ce5" dependencies = [ - "core-foundation-sys 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.49 (registry+https://github.com/rust-lang/crates.io-index)", + "bytes", + "futures-core", + "futures-sink", + "pin-project-lite", + "slab", + "tokio", ] [[package]] -name = "security-framework-sys" -version = "0.2.3" +name = "tokio-utils" +version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "de75f75f464153a50fe48b9675360e3cf2ae1d7d81f9751363bd2ee4888f5ce8" dependencies = [ - "MacTypes-sys 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)", - "core-foundation-sys 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.49 (registry+https://github.com/rust-lang/crates.io-index)", + "async-stdin", + "async-throttle", + "shutdown-async", + "tub", ] [[package]] -name = "semver" -version = "0.1.20" +name = "toml_datetime" +version = "0.6.8" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0dd7358ecb8fc2f8d014bf86f6f638ce72ba252a2c3a2572f2a795f1d23efb41" [[package]] -name = "semver" -version = "0.9.0" +name = "toml_edit" +version = "0.22.24" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "17b4795ff5edd201c7cd6dca065ae59972ce77d1b80fa0a84d94950ece7d1474" dependencies = [ - "semver-parser 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", + "indexmap", + "toml_datetime", + "winnow", ] [[package]] -name = "semver-parser" -version = "0.7.0" +name = "tracing" +version = "0.1.41" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "784e0ac535deb450455cbfa28a6f0df145ea1bb7ae51b821cf5e7927fdcfbdd0" +dependencies = [ + "pin-project-lite", + "tracing-attributes", + "tracing-core", +] [[package]] -name = "serde" -version = "1.0.88" +name = "tracing-attributes" +version = "0.1.28" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "395ae124c09f9e6918a2310af6038fba074bcf474ac352496d5910dd59a2226d" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.100", +] [[package]] -name = "serde_derive" -version = "1.0.88" +name = "tracing-core" +version = "0.1.33" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e672c95779cf947c5311f83787af4fa8fffd12fb27e4993211a84bdfd9610f9c" dependencies = [ - "proc-macro2 0.4.27 (registry+https://github.com/rust-lang/crates.io-index)", - "quote 0.6.11 (registry+https://github.com/rust-lang/crates.io-index)", - "syn 0.15.26 (registry+https://github.com/rust-lang/crates.io-index)", + "once_cell", + "valuable", ] [[package]] -name = "serde_json" -version = "1.0.38" +name = "tracing-error" +version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8b1581020d7a273442f5b45074a6a57d5757ad0a47dac0e9f0bd57b81936f3db" dependencies = [ - "itoa 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)", - "ryu 0.2.7 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.88 (registry+https://github.com/rust-lang/crates.io-index)", + "tracing", + "tracing-subscriber", ] [[package]] -name = "serde_urlencoded" -version = "0.5.4" +name = "tracing-futures" +version = "0.2.5" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "97d095ae15e245a057c8e8451bab9b3ee1e1f68e9ba2b4fbc18d0ac5237835f2" dependencies = [ - "dtoa 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)", - "itoa 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.88 (registry+https://github.com/rust-lang/crates.io-index)", - "url 1.7.2 (registry+https://github.com/rust-lang/crates.io-index)", + "pin-project", + "tracing", ] [[package]] -name = "serde_yaml" -version = "0.8.8" +name = "tracing-journald" +version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fc0b4143302cf1022dac868d521e36e8b27691f72c84b3311750d5188ebba657" dependencies = [ - "dtoa 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)", - "linked-hash-map 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 1.0.88 (registry+https://github.com/rust-lang/crates.io-index)", - "yaml-rust 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", + "libc", + "tracing-core", + "tracing-subscriber", ] [[package]] -name = "sha1" -version = "0.6.0" +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 = "signal-hook" -version = "0.1.8" +name = "tracing-subscriber" +version = "0.3.19" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e8189decb5ac0fa7bc8b96b7cb9b2701d60d48805aca84a238004d665fcc4008" dependencies = [ - "arc-swap 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.49 (registry+https://github.com/rust-lang/crates.io-index)", + "matchers", + "nu-ansi-term", + "once_cell", + "regex", + "sharded-slab", + "smallvec 1.14.0", + "thread_local", + "tracing", + "tracing-core", + "tracing-log", ] [[package]] -name = "siphasher" -version = "0.2.3" +name = "tub" +version = "0.3.7" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6bca43faba247bc76eb1d6c1b8b561e4a1c5bdd427cc3d7a007faabea75c683a" +dependencies = [ + "crossbeam-queue", + "tokio", +] [[package]] -name = "slab" -version = "0.4.2" -source = "registry+https://github.com/rust-lang/crates.io-index" +name = "tui-tree-widget" +version = "0.23.0" +source = "git+https://github.com/dvdsk/tui-rs-tree-widget#3bd3eeb0261fc7b64c04b5b6a63c9acdad234dc4" +dependencies = [ + "ratatui", + "unicode-width 0.2.0", +] [[package]] -name = "smallvec" -version = "0.6.9" +name = "typenum" +version = "1.18.0" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1dccffe3ce07af9386bfd29e80c0ab1a8205a2fc34e4bcd40364df902cfa8f3f" [[package]] -name = "socket2" -version = "0.3.8" -source = "registry+https://github.com/rust-lang/crates.io-index" +name = "ui" +version = "0.1.0" dependencies = [ - "cfg-if 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.49 (registry+https://github.com/rust-lang/crates.io-index)", - "redox_syscall 0.1.51 (registry+https://github.com/rust-lang/crates.io-index)", - "winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "spidev" -version = "0.3.0" + "clap", + "color-eyre", + "crossterm", + "data-server", + "data-store", + "derivative", + "gethostname", + "hdrhistogram", + "indextree", + "itertools 0.14.0", + "jiff", + "log-store", + "logger", + "protocol", + "ratatui", + "strip-ansi-escapes", + "thiserror 2.0.12", + "tokio", + "tracing", + "tracing-error", + "tracing-subscriber", + "tui-tree-widget", +] + +[[package]] +name = "unescaper" +version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c878a167baa8afd137494101a688ef8c67125089ff2249284bd2b5f9bfedb815" dependencies = [ - "bitflags 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.49 (registry+https://github.com/rust-lang/crates.io-index)", - "nix 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)", + "thiserror 1.0.69", ] [[package]] -name = "stable_deref_trait" -version = "1.1.1" +name = "unicase" +version = "2.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "75b844d17643ee918803943289730bec8aac480150456169e647ed0b576ba539" [[package]] -name = "string" -version = "0.1.3" +name = "unicode-ident" +version = "1.0.18" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5a5f39404a5da50712a4c1eecf25e90dd62b613502b7e925fd4e4d19b5c96512" [[package]] -name = "strsim" -version = "0.7.0" +name = "unicode-segmentation" +version = "1.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f6ccf251212114b54433ec949fd6a7841275f9ada20dddd2f29e9ceea4501493" [[package]] -name = "syn" -version = "0.15.26" +name = "unicode-truncate" +version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b3644627a5af5fa321c95b9b235a72fd24cd29c648c2c379431e6628655627bf" dependencies = [ - "proc-macro2 0.4.27 (registry+https://github.com/rust-lang/crates.io-index)", - "quote 0.6.11 (registry+https://github.com/rust-lang/crates.io-index)", - "unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", + "itertools 0.13.0", + "unicode-segmentation", + "unicode-width 0.1.14", ] [[package]] -name = "synstructure" -version = "0.10.1" +name = "unicode-width" +version = "0.1.14" source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "proc-macro2 0.4.27 (registry+https://github.com/rust-lang/crates.io-index)", - "quote 0.6.11 (registry+https://github.com/rust-lang/crates.io-index)", - "syn 0.15.26 (registry+https://github.com/rust-lang/crates.io-index)", - "unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", -] +checksum = "7dd6e30e90baa6f72411720665d41d89b9a3d039dc45b8faea1ddd07f617f6af" [[package]] -name = "sysfs_gpio" -version = "0.5.3" -source = "git+https://github.com/rust-embedded/rust-sysfs-gpio#409bab143fbf4004613009aef204df7fc0c0ae8f" -dependencies = [ - "futures 0.1.25 (registry+https://github.com/rust-lang/crates.io-index)", - "mio 0.6.16 (registry+https://github.com/rust-lang/crates.io-index)", - "nix 0.10.0 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio 0.1.15 (registry+https://github.com/rust-lang/crates.io-index)", -] +name = "unicode-width" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1fc81956842c57dac11422a97c3b8195a1ff727f06e85c84ed2e8aa277c9a0fd" [[package]] -name = "sysfs_gpio" -version = "0.5.3" +name = "unsafe-libyaml" +version = "0.2.11" source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "nix 0.10.0 (registry+https://github.com/rust-lang/crates.io-index)", -] +checksum = "673aac59facbab8a9007c7f6108d11f63b603f7cabff99fabf650fea5c32b861" [[package]] -name = "tempdir" -version = "0.3.7" +name = "unty" +version = "0.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "rand 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", - "remove_dir_all 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)", -] +checksum = "6d49784317cd0d1ee7ec5c716dd598ec5b4483ea832a2dced265471cc0f690ae" [[package]] -name = "tempfile" -version = "3.0.7" +name = "url" +version = "2.5.4" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "32f8b686cadd1473f4bd0117a5d28d36b1ade384ea9b5069a1c40aefed7fda60" dependencies = [ - "cfg-if 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.49 (registry+https://github.com/rust-lang/crates.io-index)", - "rand 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)", - "redox_syscall 0.1.51 (registry+https://github.com/rust-lang/crates.io-index)", - "remove_dir_all 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)", - "winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", + "form_urlencoded", + "idna", + "percent-encoding", ] [[package]] -name = "termion" -version = "1.5.1" -source = "registry+https://github.com/rust-lang/crates.io-index" +name = "usb-bridge" +version = "0.1.0" dependencies = [ - "libc 0.2.49 (registry+https://github.com/rust-lang/crates.io-index)", - "redox_syscall 0.1.51 (registry+https://github.com/rust-lang/crates.io-index)", - "redox_termios 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", + "clap", + "color-eyre", + "data-server", + "heapless 0.8.0", + "logger", + "nusb", + "protocol", + "tokio", + "tracing", + "tracing-error", + "tracing-subscriber", + "uzers", ] [[package]] -name = "text_io" -version = "0.1.7" +name = "utf16_iter" +version = "1.0.5" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c8232dd3cdaed5356e0f716d285e4b40b932ac434100fe9b7e0e8e935b9e6246" [[package]] -name = "textwrap" -version = "0.10.0" +name = "utf8_iter" +version = "1.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "unicode-width 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", -] +checksum = "b6c140620e7ffbb22c2dee59cafe6084a59b5ffc27a8859a5f0d494b5d52b6be" [[package]] -name = "thread_local" -version = "0.3.6" +name = "utf8parse" +version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "lazy_static 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)", -] +checksum = "06abde3611657adf66d383f00b093d7faecc7fa57071cce2578660c9f1010821" [[package]] -name = "time" -version = "0.1.42" +name = "uuid" +version = "1.16.0" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "458f7a779bf54acc9f347480ac654f68407d3aab21269a6e3c9f922acd9e2da9" dependencies = [ - "libc 0.2.49 (registry+https://github.com/rust-lang/crates.io-index)", - "redox_syscall 0.1.51 (registry+https://github.com/rust-lang/crates.io-index)", - "winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", + "serde", ] [[package]] -name = "tokio" -version = "0.1.15" +name = "uzers" +version = "0.12.1" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4df81ff504e7d82ad53e95ed1ad5b72103c11253f39238bcc0235b90768a97dd" dependencies = [ - "bytes 0.4.11 (registry+https://github.com/rust-lang/crates.io-index)", - "futures 0.1.25 (registry+https://github.com/rust-lang/crates.io-index)", - "mio 0.6.16 (registry+https://github.com/rust-lang/crates.io-index)", - "num_cpus 1.10.0 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-codec 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-current-thread 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-executor 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-fs 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-io 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-reactor 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-sync 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-tcp 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-threadpool 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-timer 0.2.10 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-udp 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-uds 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)", + "libc", + "log", ] [[package]] -name = "tokio-codec" +name = "valuable" version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "bytes 0.4.11 (registry+https://github.com/rust-lang/crates.io-index)", - "futures 0.1.25 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-io 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)", -] +checksum = "ba73ea9cf16a25df0c8caa16c51acb937d5712a8429db78a3ee29d5dcacd3a65" [[package]] -name = "tokio-current-thread" -version = "0.1.4" +name = "version_check" +version = "0.9.5" source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "futures 0.1.25 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-executor 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", -] +checksum = "0b928f33d975fc6ad9f86c8f283853ad26bdd5b10b7f1542aa2fa15e2289105a" [[package]] -name = "tokio-executor" -version = "0.1.6" +name = "vte" +version = "0.14.1" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "231fdcd7ef3037e8330d8e17e61011a2c244126acc0a982f4040ac3f9f0bc077" dependencies = [ - "crossbeam-utils 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)", - "futures 0.1.25 (registry+https://github.com/rust-lang/crates.io-index)", + "memchr", ] [[package]] -name = "tokio-fs" -version = "0.1.5" +name = "wasi" +version = "0.11.0+wasi-snapshot-preview1" source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "futures 0.1.25 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-io 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-threadpool 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)", -] +checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" [[package]] -name = "tokio-io" -version = "0.1.11" +name = "wasi" +version = "0.14.2+wasi-0.2.4" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9683f9a5a998d873c0d21fcbe3c083009670149a8fab228644b8bd36b2c48cb3" dependencies = [ - "bytes 0.4.11 (registry+https://github.com/rust-lang/crates.io-index)", - "futures 0.1.25 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", + "wit-bindgen-rt", ] [[package]] -name = "tokio-reactor" -version = "0.1.8" +name = "wasm-bindgen" +version = "0.2.100" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1edc8929d7499fc4e8f0be2262a241556cfc54a0bea223790e71446f2aab1ef5" dependencies = [ - "crossbeam-utils 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)", - "futures 0.1.25 (registry+https://github.com/rust-lang/crates.io-index)", - "lazy_static 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", - "mio 0.6.16 (registry+https://github.com/rust-lang/crates.io-index)", - "num_cpus 1.10.0 (registry+https://github.com/rust-lang/crates.io-index)", - "parking_lot 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)", - "slab 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-executor 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-io 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)", + "cfg-if", + "once_cell", + "rustversion", + "wasm-bindgen-macro", ] [[package]] -name = "tokio-rustls" -version = "0.8.1" +name = "wasm-bindgen-backend" +version = "0.2.100" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2f0a0651a5c2bc21487bde11ee802ccaf4c51935d0d3d42a6101f98161700bc6" dependencies = [ - "futures 0.1.25 (registry+https://github.com/rust-lang/crates.io-index)", - "rustls 0.14.0 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-io 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)", - "webpki 0.18.1 (registry+https://github.com/rust-lang/crates.io-index)", + "bumpalo", + "log", + "proc-macro2", + "quote", + "syn 2.0.100", + "wasm-bindgen-shared", ] [[package]] -name = "tokio-signal" -version = "0.2.7" +name = "wasm-bindgen-futures" +version = "0.4.50" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "555d470ec0bc3bb57890405e5d4322cc9ea83cebb085523ced7be4144dac1e61" dependencies = [ - "futures 0.1.25 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.49 (registry+https://github.com/rust-lang/crates.io-index)", - "mio 0.6.16 (registry+https://github.com/rust-lang/crates.io-index)", - "mio-uds 0.6.7 (registry+https://github.com/rust-lang/crates.io-index)", - "signal-hook 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-executor 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-io 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-reactor 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)", - "winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", + "cfg-if", + "js-sys", + "once_cell", + "wasm-bindgen", + "web-sys", ] [[package]] -name = "tokio-sync" -version = "0.1.2" +name = "wasm-bindgen-macro" +version = "0.2.100" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7fe63fc6d09ed3792bd0897b314f53de8e16568c2b3f7982f468c0bf9bd0b407" dependencies = [ - "futures 0.1.25 (registry+https://github.com/rust-lang/crates.io-index)", + "quote", + "wasm-bindgen-macro-support", ] [[package]] -name = "tokio-tcp" -version = "0.1.3" +name = "wasm-bindgen-macro-support" +version = "0.2.100" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8ae87ea40c9f689fc23f209965b6fb8a99ad69aeeb0231408be24920604395de" dependencies = [ - "bytes 0.4.11 (registry+https://github.com/rust-lang/crates.io-index)", - "futures 0.1.25 (registry+https://github.com/rust-lang/crates.io-index)", - "iovec 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", - "mio 0.6.16 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-io 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-reactor 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)", + "proc-macro2", + "quote", + "syn 2.0.100", + "wasm-bindgen-backend", + "wasm-bindgen-shared", ] [[package]] -name = "tokio-threadpool" -version = "0.1.11" +name = "wasm-bindgen-shared" +version = "0.2.100" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1a05d73b933a847d6cccdda8f838a22ff101ad9bf93e33684f39c1f5f0eece3d" dependencies = [ - "crossbeam 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)", - "crossbeam-channel 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", - "crossbeam-deque 0.6.3 (registry+https://github.com/rust-lang/crates.io-index)", - "crossbeam-utils 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)", - "futures 0.1.25 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", - "num_cpus 1.10.0 (registry+https://github.com/rust-lang/crates.io-index)", - "rand 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)", - "slab 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-executor 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", + "unicode-ident", ] [[package]] -name = "tokio-timer" -version = "0.2.10" +name = "web-sys" +version = "0.3.77" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "33b6dd2ef9186f1f2072e409e99cd22a975331a6b3591b12c764e0e55c60d5d2" dependencies = [ - "crossbeam-utils 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)", - "futures 0.1.25 (registry+https://github.com/rust-lang/crates.io-index)", - "slab 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-executor 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", + "js-sys", + "wasm-bindgen", ] [[package]] -name = "tokio-udp" -version = "0.1.3" +name = "web-time" +version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5a6580f308b1fad9207618087a65c04e7a10bc77e02c8e84e9b00dd4b12fa0bb" dependencies = [ - "bytes 0.4.11 (registry+https://github.com/rust-lang/crates.io-index)", - "futures 0.1.25 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", - "mio 0.6.16 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-codec 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-io 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-reactor 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)", + "js-sys", + "wasm-bindgen", ] [[package]] -name = "tokio-uds" -version = "0.2.5" +name = "wide" +version = "0.7.32" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "41b5576b9a81633f3e8df296ce0063042a73507636cbe956c61133dd7034ab22" dependencies = [ - "bytes 0.4.11 (registry+https://github.com/rust-lang/crates.io-index)", - "futures 0.1.25 (registry+https://github.com/rust-lang/crates.io-index)", - "iovec 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.49 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", - "mio 0.6.16 (registry+https://github.com/rust-lang/crates.io-index)", - "mio-uds 0.6.7 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-codec 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-io 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-reactor 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)", + "bytemuck", + "safe_arch", ] [[package]] -name = "tower-service" -version = "0.1.0" +name = "winapi" +version = "0.3.9" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419" dependencies = [ - "futures 0.1.25 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi-i686-pc-windows-gnu", + "winapi-x86_64-pc-windows-gnu", ] [[package]] -name = "traitobject" -version = "0.1.0" +name = "winapi-i686-pc-windows-gnu" +version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" [[package]] -name = "trust-dns-proto" -version = "0.5.0" +name = "winapi-x86_64-pc-windows-gnu" +version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "byteorder 1.3.1 (registry+https://github.com/rust-lang/crates.io-index)", - "failure 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", - "futures 0.1.25 (registry+https://github.com/rust-lang/crates.io-index)", - "idna 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", - "lazy_static 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", - "rand 0.5.6 (registry+https://github.com/rust-lang/crates.io-index)", - "smallvec 0.6.9 (registry+https://github.com/rust-lang/crates.io-index)", - "socket2 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-executor 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-io 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-reactor 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-tcp 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-timer 0.2.10 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-udp 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", - "url 1.7.2 (registry+https://github.com/rust-lang/crates.io-index)", -] +checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" [[package]] -name = "trust-dns-proto" -version = "0.6.3" +name = "windows" +version = "0.48.0" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e686886bc078bc1b0b600cac0147aadb815089b6e4da64016cbd754b6342700f" dependencies = [ - "byteorder 1.3.1 (registry+https://github.com/rust-lang/crates.io-index)", - "failure 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", - "futures 0.1.25 (registry+https://github.com/rust-lang/crates.io-index)", - "idna 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", - "lazy_static 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", - "rand 0.5.6 (registry+https://github.com/rust-lang/crates.io-index)", - "smallvec 0.6.9 (registry+https://github.com/rust-lang/crates.io-index)", - "socket2 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-executor 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-io 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-reactor 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-tcp 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-timer 0.2.10 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio-udp 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", - "url 1.7.2 (registry+https://github.com/rust-lang/crates.io-index)", + "windows-targets 0.48.5", ] [[package]] -name = "trust-dns-resolver" -version = "0.10.3" +name = "windows-sys" +version = "0.48.0" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "677d2418bec65e3338edb076e806bc1ec15693c5d0104683f2efe857f61056a9" dependencies = [ - "cfg-if 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", - "failure 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", - "futures 0.1.25 (registry+https://github.com/rust-lang/crates.io-index)", - "ipconfig 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)", - "lazy_static 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", - "lru-cache 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", - "resolv-conf 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)", - "smallvec 0.6.9 (registry+https://github.com/rust-lang/crates.io-index)", - "tokio 0.1.15 (registry+https://github.com/rust-lang/crates.io-index)", - "trust-dns-proto 0.6.3 (registry+https://github.com/rust-lang/crates.io-index)", + "windows-targets 0.48.5", ] [[package]] -name = "try-lock" -version = "0.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" - -[[package]] -name = "typeable" -version = "0.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" - -[[package]] -name = "ucd-util" -version = "0.1.3" -source = "registry+https://github.com/rust-lang/crates.io-index" - -[[package]] -name = "unicase" -version = "1.4.2" +name = "windows-sys" +version = "0.52.0" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d" dependencies = [ - "version_check 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", + "windows-targets 0.52.6", ] [[package]] -name = "unicase" -version = "2.2.0" +name = "windows-sys" +version = "0.59.0" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e38bc4d79ed67fd075bcc251a1c39b32a1776bbe92e5bef1f0bf1f8c531853b" dependencies = [ - "version_check 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", + "windows-targets 0.52.6", ] [[package]] -name = "unicode-bidi" -version = "0.3.4" +name = "windows-targets" +version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9a2fa6e2155d7247be68c096456083145c183cbbbc2764150dda45a87197940c" dependencies = [ - "matches 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)", + "windows_aarch64_gnullvm 0.48.5", + "windows_aarch64_msvc 0.48.5", + "windows_i686_gnu 0.48.5", + "windows_i686_msvc 0.48.5", + "windows_x86_64_gnu 0.48.5", + "windows_x86_64_gnullvm 0.48.5", + "windows_x86_64_msvc 0.48.5", ] [[package]] -name = "unicode-normalization" -version = "0.1.8" +name = "windows-targets" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973" dependencies = [ - "smallvec 0.6.9 (registry+https://github.com/rust-lang/crates.io-index)", + "windows_aarch64_gnullvm 0.52.6", + "windows_aarch64_msvc 0.52.6", + "windows_i686_gnu 0.52.6", + "windows_i686_gnullvm", + "windows_i686_msvc 0.52.6", + "windows_x86_64_gnu 0.52.6", + "windows_x86_64_gnullvm 0.52.6", + "windows_x86_64_msvc 0.52.6", ] [[package]] -name = "unicode-width" -version = "0.1.5" +name = "windows_aarch64_gnullvm" +version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8" [[package]] -name = "unicode-xid" -version = "0.1.0" +name = "windows_aarch64_gnullvm" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3" [[package]] -name = "untrusted" -version = "0.6.2" +name = "windows_aarch64_msvc" +version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc" [[package]] -name = "url" -version = "1.7.2" +name = "windows_aarch64_msvc" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "encoding 0.2.33 (registry+https://github.com/rust-lang/crates.io-index)", - "idna 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", - "matches 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)", - "percent-encoding 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)", -] +checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469" [[package]] -name = "utf8-ranges" -version = "1.0.2" +name = "windows_i686_gnu" +version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743e" [[package]] -name = "uuid" -version = "0.7.2" +name = "windows_i686_gnu" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "rand 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)", -] +checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b" [[package]] -name = "v_escape" -version = "0.3.2" +name = "windows_i686_gnullvm" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "v_escape_derive 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", - "version_check 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", -] +checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66" [[package]] -name = "v_escape_derive" -version = "0.2.1" +name = "windows_i686_msvc" +version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "nom 4.2.0 (registry+https://github.com/rust-lang/crates.io-index)", - "proc-macro2 0.4.27 (registry+https://github.com/rust-lang/crates.io-index)", - "quote 0.6.11 (registry+https://github.com/rust-lang/crates.io-index)", - "syn 0.15.26 (registry+https://github.com/rust-lang/crates.io-index)", -] +checksum = "8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406" [[package]] -name = "v_htmlescape" -version = "0.3.2" +name = "windows_i686_msvc" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "cfg-if 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", - "v_escape 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)", - "version_check 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", -] +checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66" [[package]] -name = "vcpkg" -version = "0.2.6" +name = "windows_x86_64_gnu" +version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "53d40abd2583d23e4718fddf1ebec84dbff8381c07cae67ff7768bbf19c6718e" [[package]] -name = "vec_map" -version = "0.8.1" +name = "windows_x86_64_gnu" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78" [[package]] -name = "version_check" -version = "0.1.5" +name = "windows_x86_64_gnullvm" +version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc" [[package]] -name = "void" -version = "1.0.2" +name = "windows_x86_64_gnullvm" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d" [[package]] -name = "walkdir" -version = "2.2.7" +name = "windows_x86_64_msvc" +version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "same-file 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)", - "winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", - "winapi-util 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", -] +checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538" [[package]] -name = "want" -version = "0.0.6" +name = "windows_x86_64_msvc" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "futures 0.1.25 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", - "try-lock 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", -] +checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" [[package]] -name = "webpki" -version = "0.18.1" +name = "winnow" +version = "0.7.4" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0e97b544156e9bebe1a0ffbc03484fc1ffe3100cbce3ffb17eac35f7cdd7ab36" dependencies = [ - "ring 0.13.5 (registry+https://github.com/rust-lang/crates.io-index)", - "untrusted 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)", + "memchr", ] [[package]] -name = "webpki-roots" -version = "0.15.0" +name = "wit-bindgen-rt" +version = "0.39.0" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6f42320e61fe2cfd34354ecb597f86f413484a798ba44a8ca1165c58d42da6c1" dependencies = [ - "untrusted 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)", - "webpki 0.18.1 (registry+https://github.com/rust-lang/crates.io-index)", + "bitflags 2.9.0", ] [[package]] -name = "widestring" -version = "0.2.2" +name = "wiznet-echo-tester" +version = "0.1.0" + +[[package]] +name = "write16" +version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d1890f4022759daae28ed4fe62859b1236caebfc61ede2f63ed4e695f3f6d936" [[package]] -name = "winapi" -version = "0.2.8" +name = "writeable" +version = "0.5.5" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e9df38ee2d2c3c5948ea468a8406ff0db0b29ae1ffde1bcf20ef305bcc95c51" [[package]] -name = "winapi" -version = "0.3.6" +name = "yoke" +version = "0.7.5" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "120e6aef9aa629e3d4f52dc8cc43a015c7724194c97dfaf45180d2daf2b77f40" dependencies = [ - "winapi-i686-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", - "winapi-x86_64-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", + "serde", + "stable_deref_trait", + "yoke-derive", + "zerofrom", ] [[package]] -name = "winapi-build" -version = "0.1.1" +name = "yoke-derive" +version = "0.7.5" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2380878cad4ac9aac1e2435f3eb4020e8374b5f13c296cb75b4620ff8e229154" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.100", + "synstructure", +] [[package]] -name = "winapi-i686-pc-windows-gnu" -version = "0.4.0" +name = "zerocopy" +version = "0.8.24" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2586fea28e186957ef732a5f8b3be2da217d65c5969d4b1e17f973ebbe876879" +dependencies = [ + "zerocopy-derive", +] [[package]] -name = "winapi-util" -version = "0.1.2" +name = "zerocopy-derive" +version = "0.8.24" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a996a8f63c5c4448cd959ac1bab0aaa3306ccfd060472f85943ee0750f0169be" dependencies = [ - "winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", + "proc-macro2", + "quote", + "syn 2.0.100", ] [[package]] -name = "winapi-x86_64-pc-windows-gnu" -version = "0.4.0" +name = "zerofrom" +version = "0.1.6" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "50cc42e0333e05660c3587f3bf9d0478688e15d870fab3346451ce7f8c9fbea5" +dependencies = [ + "zerofrom-derive", +] [[package]] -name = "winreg" -version = "0.5.1" +name = "zerofrom-derive" +version = "0.1.6" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d71e5d6e06ab090c67b5e44993ec16b72dcbaabc526db883a360057678b48502" dependencies = [ - "winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", + "proc-macro2", + "quote", + "syn 2.0.100", + "synstructure", ] [[package]] -name = "winutil" -version = "0.1.1" +name = "zerovec" +version = "0.10.4" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "aa2b893d79df23bfb12d5461018d408ea19dfafe76c2c7ef6d4eba614f8ff079" dependencies = [ - "winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", + "yoke", + "zerofrom", + "zerovec-derive", ] [[package]] -name = "ws2_32-sys" -version = "0.2.1" +name = "zerovec-derive" +version = "0.10.3" source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6eafa6dfb17584ea3e2bd6e76e0cc15ad7af12b09abdd1ca55961bed9b1063c6" dependencies = [ - "winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", - "winapi-build 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", + "proc-macro2", + "quote", + "syn 2.0.100", ] [[package]] -name = "yaml-rust" -version = "0.4.2" -source = "registry+https://github.com/rust-lang/crates.io-index" +name = "zigbee-bridge" +version = "0.1.0" dependencies = [ - "linked-hash-map 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[metadata] -"checksum MacTypes-sys 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "eaf9f0d0b1cc33a4d2aee14fb4b2eac03462ef4db29c8ac4057327d8a71ad86f" -"checksum acme-client 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)" = "72202dd6b4bd5d6541d21aac8aae4fea0f3b0205c850fc60e85acd52af9e4395" -"checksum actix 0.7.9 (registry+https://github.com/rust-lang/crates.io-index)" = "6c616db5fa4b0c40702fb75201c2af7f8aa8f3a2e2c1dda3b0655772aa949666" -"checksum actix-net 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)" = "8bebfbe6629e0131730746718c9e032b58f02c6ce06ed7c982b9fef6c8545acd" -"checksum actix-web 0.7.18 (registry+https://github.com/rust-lang/crates.io-index)" = "e9f33c941e5e69a58a6bfef33853228042ed3799fc4b5a4923a36a85776fb690" -"checksum actix-web-httpauth 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "843c8b2e6b9d02d2511c0b26e5e7b59834ea870d266056e474707ba8c80ff3a7" -"checksum actix_derive 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)" = "4300e9431455322ae393d43a2ba1ef96b8080573c0fc23b196219efedfb6ba69" -"checksum adler32 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)" = "7e522997b529f05601e05166c07ed17789691f562762c7f3b987263d2dedee5c" -"checksum aho-corasick 0.6.10 (registry+https://github.com/rust-lang/crates.io-index)" = "81ce3d38065e618af2d7b77e10c5ad9a069859b4be3c2250f674af3840d9c8a5" -"checksum ansi_term 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ee49baf6cb617b853aa8d93bf420db2383fab46d314482ca2803b40d5fde979b" -"checksum antidote 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "34fde25430d87a9388dadbe6e34d7f72a462c8b43ac8d309b42b0a8505d7e2a5" -"checksum arc-swap 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)" = "1025aeae2b664ca0ea726a89d574fe8f4e77dd712d443236ad1de00379450cf6" -"checksum arrayvec 0.4.10 (registry+https://github.com/rust-lang/crates.io-index)" = "92c7fb76bc8826a8b33b4ee5bb07a247a81e76764ab4d55e8f73e3a4d8808c71" -"checksum atty 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)" = "9a7d5b8723950951411ee34d271d99dddcc2035a16ab25310ea2c8cfd4369652" -"checksum autocfg 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "a6d640bee2da49f60a4068a7fae53acde8982514ab7bae8b8cea9e88cbcfd799" -"checksum backtrace 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)" = "cd5a90e2b463010cd0e0ce9a11d4a9d5d58d9f41d4a6ba3dcaf9e68b466e88b4" -"checksum backtrace-sys 0.1.28 (registry+https://github.com/rust-lang/crates.io-index)" = "797c830ac25ccc92a7f8a7b9862bde440715531514594a6154e3d4a54dd769b6" -"checksum base64 0.10.1 (registry+https://github.com/rust-lang/crates.io-index)" = "0b25d992356d2eb0ed82172f5248873db5560c4721f564b13cb5193bda5e668e" -"checksum base64 0.9.3 (registry+https://github.com/rust-lang/crates.io-index)" = "489d6c0ed21b11d038c31b6ceccca973e65d73ba3bd8ecb9a2babf5546164643" -"checksum bincode 1.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "3efe0b4c8eaeed8600549c29f538a6a11bf422858d0ed435b1d70ec4ab101190" -"checksum bitflags 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "32866f4d103c4e438b1db1158aa1b1a80ee078e5d77a59a2f906fd62a577389c" -"checksum bitflags 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "8dead7461c1127cf637931a1e50934eb6eee8bff2f74433ac7909e9afcee04a3" -"checksum bitflags 0.9.1 (registry+https://github.com/rust-lang/crates.io-index)" = "4efd02e230a02e18f92fc2735f44597385ed02ad8f831e7c1c1156ee5e1ab3a5" -"checksum bitflags 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)" = "228047a76f468627ca71776ecdebd732a3423081fcf5125585bcd7c49886ce12" -"checksum bme280 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "d168c341491c9ba4e2c73d59470c108a5961377c67061dc1796a193fa945b452" -"checksum brotli-sys 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)" = "4445dea95f4c2b41cde57cc9fee236ae4dbae88d8fcbdb4750fc1bb5d86aaecd" -"checksum brotli2 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)" = "0cb036c3eade309815c15ddbacec5b22c4d1f3983a774ab2eac2e3e9ea85568e" -"checksum build_const 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "39092a32794787acd8525ee150305ff051b0aa6cc2abaf193924f5ab05425f39" -"checksum byteorder 1.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "a019b10a2a7cdeb292db131fc8113e57ea2a908f6e7894b0c3c671893b65dbeb" -"checksum bytes 0.4.11 (registry+https://github.com/rust-lang/crates.io-index)" = "40ade3d27603c2cb345eb0912aec461a6dec7e06a4ae48589904e808335c7afa" -"checksum cast 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "926013f2860c46252efceabb19f4a6b308197505082c609025aa6706c011d427" -"checksum cc 1.0.29 (registry+https://github.com/rust-lang/crates.io-index)" = "4390a3b5f4f6bce9c1d0c00128379df433e53777fdd30e92f16a529332baec4e" -"checksum cfg-if 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "082bb9b28e00d3c9d39cc03e64ce4cea0f1bb9b3fde493f0cbc008472d22bdf4" -"checksum chrono 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)" = "45912881121cb26fad7c38c17ba7daa18764771836b34fab7d3fbd93ed633878" -"checksum clap 2.32.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b957d88f4b6a63b9d70d5f454ac8011819c6efa7727858f458ab71c756ce2d3e" -"checksum cloudabi 0.0.3 (registry+https://github.com/rust-lang/crates.io-index)" = "ddfc5b9aa5d4507acaf872de71051dfd0e309860e88966e1051e462a077aac4f" -"checksum colored 1.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "6e9a455e156a4271e12fd0246238c380b1e223e3736663c7a18ed8b6362028a9" -"checksum cookie 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)" = "1465f8134efa296b4c19db34d909637cb2bf0f7aaf21299e23e18fa29ac557cf" -"checksum core-foundation 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "25bfd746d203017f7d5cbd31ee5d8e17f94b6521c7af77ece6c9e4b2d4b16c67" -"checksum core-foundation 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "286e0b41c3a20da26536c6000a280585d519fd07b3956b43aed8a79e9edce980" -"checksum core-foundation-sys 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "065a5d7ffdcbc8fa145d6f0746f3555025b9097a9e9cda59f7467abae670c78d" -"checksum core-foundation-sys 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "716c271e8613ace48344f723b60b900a93150271e5be206212d052bbc0883efa" -"checksum crc 1.8.1 (registry+https://github.com/rust-lang/crates.io-index)" = "d663548de7f5cca343f1e0a48d14dcfb0e9eb4e079ec58883b7251539fa10aeb" -"checksum crc32fast 1.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "e91d5240c6975ef33aeb5f148f35275c25eda8e8a5f95abe421978b05b8bf192" -"checksum crossbeam 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ad4c7ea749d9fb09e23c5cb17e3b70650860553a0e2744e38446b1803bf7db94" -"checksum crossbeam-channel 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)" = "0f0ed1a4de2235cabda8558ff5840bffb97fcb64c97827f354a451307df5f72b" -"checksum crossbeam-deque 0.6.3 (registry+https://github.com/rust-lang/crates.io-index)" = "05e44b8cf3e1a625844d1750e1f7820da46044ff6d28f4d43e455ba3e5bb2c13" -"checksum crossbeam-epoch 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)" = "04c9e3102cc2d69cd681412141b390abd55a362afc1540965dad0ad4d34280b4" -"checksum crossbeam-utils 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)" = "f8306fcef4a7b563b76b7dd949ca48f52bc1141aa067d2ea09565f3e2652aa5c" -"checksum dataserver 0.1.0 (git+https://github.com/dskleingeld/dataserver?branch=as_lib)" = "" -"checksum dtoa 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)" = "6d301140eb411af13d3115f9a562c85cc6b541ade9dfa314132244aaee7489dd" -"checksum either 1.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "c67353c641dc847124ea1902d69bd753dee9bb3beff9aa3662ecf86c971d1fac" -"checksum embedded-hal 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "9880e55238830314d41d88f1ac7a819d495799c3cc3bc392cc172bab26428c33" -"checksum encoding 0.2.33 (registry+https://github.com/rust-lang/crates.io-index)" = "6b0d943856b990d12d3b55b359144ff341533e516d94098b1d3fc1ac666d36ec" -"checksum encoding-index-japanese 1.20141219.5 (registry+https://github.com/rust-lang/crates.io-index)" = "04e8b2ff42e9a05335dbf8b5c6f7567e5591d0d916ccef4e0b1710d32a0d0c91" -"checksum encoding-index-korean 1.20141219.5 (registry+https://github.com/rust-lang/crates.io-index)" = "4dc33fb8e6bcba213fe2f14275f0963fd16f0a02c878e3095ecfdf5bee529d81" -"checksum encoding-index-simpchinese 1.20141219.5 (registry+https://github.com/rust-lang/crates.io-index)" = "d87a7194909b9118fc707194baa434a4e3b0fb6a5a757c73c3adb07aa25031f7" -"checksum encoding-index-singlebyte 1.20141219.5 (registry+https://github.com/rust-lang/crates.io-index)" = "3351d5acffb224af9ca265f435b859c7c01537c0849754d3db3fdf2bfe2ae84a" -"checksum encoding-index-tradchinese 1.20141219.5 (registry+https://github.com/rust-lang/crates.io-index)" = "fd0e20d5688ce3cab59eb3ef3a2083a5c77bf496cb798dc6fcdb75f323890c18" -"checksum encoding_index_tests 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "a246d82be1c9d791c5dfde9a2bd045fc3cbba3fa2b11ad558f27d01712f00569" -"checksum encoding_rs 0.8.17 (registry+https://github.com/rust-lang/crates.io-index)" = "4155785c79f2f6701f185eb2e6b4caf0555ec03477cb4c70db67b465311620ed" -"checksum env_logger 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)" = "3ddf21e73e016298f5cb37d6ef8e8da8e39f91f9ec8b0df44b7deb16a9f8cd5b" -"checksum error-chain 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ff511d5dc435d703f4971bc399647c9bc38e20cb41452e3b9feb4765419ed3f3" -"checksum error-chain 0.12.0 (registry+https://github.com/rust-lang/crates.io-index)" = "07e791d3be96241c77c43846b665ef1384606da2cd2a48730abe606a12906e02" -"checksum error-chain 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)" = "6930e04918388a9a2e41d518c25cf679ccafe26733fb4127dbf21993f2575d46" -"checksum failure 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "795bd83d3abeb9220f257e597aa0080a508b27533824adf336529648f6abf7e2" -"checksum failure_derive 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "ea1063915fd7ef4309e222a5a07cf9c319fb9c7836b1f89b85458672dbb127e1" -"checksum fern 0.5.7 (registry+https://github.com/rust-lang/crates.io-index)" = "b48af88aaf938b11baef948a5599e66e709cf92854aa2b87c71f1bcf20f80a01" -"checksum flate2 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)" = "2291c165c8e703ee54ef3055ad6188e3d51108e2ded18e9f2476e774fc5ad3d4" -"checksum fnv 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)" = "2fad85553e09a6f881f739c29f0b00b0f01357c743266d478b68951ce23285f3" -"checksum foreign-types 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)" = "f6f339eb8adc052cd2ca78910fda869aefa38d22d5cb648e6485e4d3fc06f3b1" -"checksum foreign-types-shared 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "00b0228411908ca8685dba7fc2cdd70ec9990a6e753e89b6ac91a84c40fbaf4b" -"checksum fuchsia-cprng 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "a06f77d526c1a601b7c4cdd98f54b5eaabffc14d5f2f0296febdc7f357c6d3ba" -"checksum fuchsia-zircon 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "2e9763c69ebaae630ba35f74888db465e49e259ba1bc0eda7d06f4a067615d82" -"checksum fuchsia-zircon-sys 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "3dcaa9ae7725d12cdb85b3ad99a434db70b468c09ded17e012d86b5c1010f7a7" -"checksum futures 0.1.25 (registry+https://github.com/rust-lang/crates.io-index)" = "49e7653e374fe0d0c12de4250f0bdb60680b8c80eed558c5c7538eec9c89e21b" -"checksum futures-cpupool 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)" = "ab90cde24b3319636588d0c35fe03b1333857621051837ed769faefb4c2162e4" -"checksum fxhash 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "c31b6d751ae2c7f11320402d34e41349dd1016f8d5d45e48c4312bc8625af50c" -"checksum gcc 0.3.55 (registry+https://github.com/rust-lang/crates.io-index)" = "8f5f3913fa0bfe7ee1fd8248b6b9f42a5af4b9d65ec2dd2c3c26132b950ecfc2" -"checksum h2 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)" = "ddb2b25a33e231484694267af28fec74ac63b5ccf51ee2065a5e313b834d836e" -"checksum hostname 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "21ceb46a83a85e824ef93669c8b390009623863b5c195d1ba747292c0c72f94e" -"checksum http 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)" = "fe67e3678f2827030e89cc4b9e7ecd16d52f132c0b940ab5005f88e821500f6a" -"checksum httparse 1.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "e8734b0cfd3bc3e101ec59100e101c2eecd19282202e87808b3037b442777a83" -"checksum hyper 0.10.15 (registry+https://github.com/rust-lang/crates.io-index)" = "df0caae6b71d266b91b4a83111a61d2b94ed2e2bea024c532b933dcff867e58c" -"checksum hyper 0.12.24 (registry+https://github.com/rust-lang/crates.io-index)" = "fdfa9b401ef6c4229745bb6e9b2529192d07b920eed624cdee2a82348cd550af" -"checksum hyper-native-tls 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)" = "72332e4a35d3059583623b50e98e491b78f8b96c5521fcb3f428167955aa56e8" -"checksum hyper-rustls 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)" = "71f7b2e5858ab9e19771dc361159f09ee5031734a6f7471fe0947db0238d92b7" -"checksum hyper-tls 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "32cd73f14ad370d3b4d4b7dce08f69b81536c82e39fcc89731930fe5788cd661" -"checksum i2cdev 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)" = "3dabb8dd1c6c973b20fa6342069a2703a11f062768d613cc57a5db29a3fe325c" -"checksum idna 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "38f09e0f0b1fb55fdee1f17470ad800da77af5186a1a76c026b679358b7e844e" -"checksum indexmap 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7e81a7c05f79578dbc15793d8b619db9ba32b4577003ef3af1a91c416798c58d" -"checksum iovec 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "dbe6e417e7d0975db6512b90796e8ce223145ac4e33c377e4a42882a0e88bb08" -"checksum ipconfig 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)" = "08f7eadeaf4b52700de180d147c4805f199854600b36faa963d91114827b2ffc" -"checksum itertools 0.7.11 (registry+https://github.com/rust-lang/crates.io-index)" = "0d47946d458e94a1b7bcabbf6521ea7c037062c81f534615abcad76e84d4970d" -"checksum itoa 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)" = "1306f3464951f30e30d12373d31c79fbd52d236e5e896fd92f96ec7babbbe60b" -"checksum kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7507624b29483431c0ba2d82aece8ca6cdba9382bff4ddd0f7490560c056098d" -"checksum language-tags 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "a91d884b6667cd606bb5a69aa0c99ba811a115fc68915e7056ec08a46e93199a" -"checksum lazy_static 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)" = "76f033c7ad61445c5b347c7382dd1237847eb1bce590fe50365dcb33d546be73" -"checksum lazy_static 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "bc5729f27f159ddd61f4df6228e827e86643d4d3e7c32183cb30a1c08f604a14" -"checksum lazycell 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "b294d6fa9ee409a054354afc4352b0b9ef7ca222c69b8812cbea9e7d2bf3783f" -"checksum libc 0.2.49 (registry+https://github.com/rust-lang/crates.io-index)" = "413f3dfc802c5dc91dc570b05125b6cda9855edfaa9825c9849807876376e70e" -"checksum libflate 0.1.20 (registry+https://github.com/rust-lang/crates.io-index)" = "54d1ddf9c52870243c5689d7638d888331c1116aa5b398f3ba1acfa7d8758ca1" -"checksum linked-hash-map 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7860ec297f7008ff7a1e3382d7f7e1dcd69efc94751a2284bafc3d013c2aa939" -"checksum linked-hash-map 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "70fb39025bc7cdd76305867c4eccf2f2dcf6e9a57f5b21a93e1c2d86cd03ec9e" -"checksum linux-embedded-hal 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "795096c0eecb0622afb591c3e1a97b1ba046688a7689957b70b8eee9cac8fb84" -"checksum lock_api 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "62ebf1391f6acad60e5c8b43706dde4582df75c06698ab44511d15016bc2442c" -"checksum log 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)" = "e19e8d5c34a3e0e2223db8e060f9e8264aeeb5c5fc64a4ee9965c062211c024b" -"checksum log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)" = "c84ec4b527950aa83a329754b01dbe3f58361d1c5efacd1f6d68c494d08a17c6" -"checksum lru-cache 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "4d06ff7ff06f729ce5f4e227876cb88d10bc59cd4ae1e09fbb2bde15c850dc21" -"checksum matches 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)" = "7ffc5c5338469d4d3ea17d269fa8ea3512ad247247c30bd2df69e68309ed0a08" -"checksum matrixmultiply 0.1.15 (registry+https://github.com/rust-lang/crates.io-index)" = "dcad67dcec2d58ff56f6292582377e6921afdf3bfbd533e26fb8900ae575e002" -"checksum memchr 2.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "2efc7bc57c883d4a4d6e3246905283d8dae951bb3bd32f49d6ef297f546e1c39" -"checksum memoffset 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "0f9dc261e2b62d7a622bf416ea3c5245cdd5d9a7fcc428c0d06804dfce1775b3" -"checksum mime 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)" = "ba626b8a6de5da682e1caa06bdb42a335aee5a84db8e5046a3e8ab17ba0a3ae0" -"checksum mime 0.3.13 (registry+https://github.com/rust-lang/crates.io-index)" = "3e27ca21f40a310bd06d9031785f4801710d566c184a6e15bad4f1d9b65f9425" -"checksum mime_guess 2.0.0-alpha.6 (registry+https://github.com/rust-lang/crates.io-index)" = "30de2e4613efcba1ec63d8133f344076952090c122992a903359be5a4f99c3ed" -"checksum minimal_timeseries 0.1.1 (git+https://github.com/dskleingeld/minimal_timeseries?branch=multithraeded_file_read)" = "" -"checksum miniz-sys 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)" = "0300eafb20369952951699b68243ab4334f4b10a88f411c221d444b36c40e649" -"checksum miniz_oxide 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "c468f2369f07d651a5d0bb2c9079f8488a66d5466efe42d0c5c6466edcb7f71e" -"checksum miniz_oxide_c_api 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "b7fe927a42e3807ef71defb191dc87d4e24479b221e67015fe38ae2b7b447bab" -"checksum mio 0.6.16 (registry+https://github.com/rust-lang/crates.io-index)" = "71646331f2619b1026cc302f87a2b8b648d5c6dd6937846a16cc8ce0f347f432" -"checksum mio-uds 0.6.7 (registry+https://github.com/rust-lang/crates.io-index)" = "966257a94e196b11bb43aca423754d87429960a768de9414f3691d6957abf125" -"checksum miow 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "8c1f2f3b1cf331de6896aabf6e9d55dca90356cc9960cca7eaaf408a355ae919" -"checksum native-tls 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "f74dbadc8b43df7864539cedb7bc91345e532fdd913cfdc23ad94f4d2d40fbc0" -"checksum native-tls 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "ff8e08de0070bbf4c31f452ea2a70db092f36f6f2e4d897adf5674477d488fb2" -"checksum nb 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "69f380b5fe9fab8c0d7a6a99cda23e2cc0463bedb2cbc3aada0813b98496ecdc" -"checksum ndarray 0.12.1 (registry+https://github.com/rust-lang/crates.io-index)" = "7cf380a8af901ad627594013a3bbac903ae0a6f94e176e47e46b5bbc1877b928" -"checksum net2 0.2.33 (registry+https://github.com/rust-lang/crates.io-index)" = "42550d9fb7b6684a6d404d9fa7250c2eb2646df731d1c06afc06dcee9e1bcf88" -"checksum nix 0.10.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b7fd5681d13fda646462cfbd4e5f2051279a89a544d50eb98c365b507246839f" -"checksum nix 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d37e713a259ff641624b6cb20e3b12b2952313ba36b6823c0f16e6cfd9e5de17" -"checksum nix 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "7a7bb1da2be7da3cbffda73fc681d509ffd9e665af478d2bee1907cee0bc64b2" -"checksum nodrop 0.1.13 (registry+https://github.com/rust-lang/crates.io-index)" = "2f9667ddcc6cc8a43afc9b7917599d7216aa09c463919ea32c59ed6cac8bc945" -"checksum nom 4.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b30adc557058ce00c9d0d7cb3c6e0b5bc6f36e2e2eabe74b0ba726d194abd588" -"checksum num 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "cf4825417e1e1406b3782a8ce92f4d53f26ec055e3622e1881ca8e9f5f9e08db" -"checksum num-bigint 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "57450397855d951f1a41305e54851b1a7b8f5d2e349543a02a2effe25459f718" -"checksum num-complex 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "107b9be86cd2481930688277b675b0114578227f034674726605b8a482d8baf8" -"checksum num-integer 0.1.39 (registry+https://github.com/rust-lang/crates.io-index)" = "e83d528d2677f0518c570baf2b7abdcf0cd2d248860b68507bdcb3e91d4c0cea" -"checksum num-iter 0.1.37 (registry+https://github.com/rust-lang/crates.io-index)" = "af3fdbbc3291a5464dc57b03860ec37ca6bf915ed6ee385e7c6c052c422b2124" -"checksum num-rational 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "4e96f040177bb3da242b5b1ecf3f54b5d5af3efbbfb18608977a5d2767b22f10" -"checksum num-traits 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)" = "0b3a5d7cc97d6d30d8b9bc8fa19bf45349ffe46241e8816f50f62f6d6aaabee1" -"checksum num_cpus 1.10.0 (registry+https://github.com/rust-lang/crates.io-index)" = "1a23f0ed30a54abaa0c7e83b1d2d87ada7c3c23078d1d87815af3e3b6385fbba" -"checksum openssl 0.10.18 (registry+https://github.com/rust-lang/crates.io-index)" = "b90119d71b0a3596588da04bf7c2c42f2978cfa1217a94119d8ec9e963c7729c" -"checksum openssl 0.9.24 (registry+https://github.com/rust-lang/crates.io-index)" = "a3605c298474a3aa69de92d21139fb5e2a81688d308262359d85cdd0d12a7985" -"checksum openssl-probe 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "77af24da69f9d9341038eba93a073b1fdaaa1b788221b00a69bce9e762cb32de" -"checksum openssl-sys 0.9.41 (registry+https://github.com/rust-lang/crates.io-index)" = "e4c77cdd67d31759b22aa72cfda3c65c12348f9e6c5420946b403c022fd0311a" -"checksum owning_ref 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "49a4b8ea2179e6a2e27411d3bca09ca6dd630821cf6894c6c7c8467a8ee7ef13" -"checksum parking_lot 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)" = "ab41b4aed082705d1056416ae4468b6ea99d52599ecf3169b00088d43113e337" -"checksum parking_lot_core 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "94c8c7923936b28d546dfd14d4472eaf34c99b14e1c973a32b3e6d4eb04298c9" -"checksum percent-encoding 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "31010dd2e1ac33d5b46a5b413495239882813e0369f8ed8a5e266f173602f831" -"checksum phf 0.7.24 (registry+https://github.com/rust-lang/crates.io-index)" = "b3da44b85f8e8dfaec21adae67f95d93244b2ecf6ad2a692320598dcc8e6dd18" -"checksum phf_codegen 0.7.24 (registry+https://github.com/rust-lang/crates.io-index)" = "b03e85129e324ad4166b06b2c7491ae27fe3ec353af72e72cd1654c7225d517e" -"checksum phf_generator 0.7.24 (registry+https://github.com/rust-lang/crates.io-index)" = "09364cc93c159b8b06b1f4dd8a4398984503483891b0c26b867cf431fb132662" -"checksum phf_shared 0.7.24 (registry+https://github.com/rust-lang/crates.io-index)" = "234f71a15de2288bcb7e3b6515828d22af7ec8598ee6d24c3b526fa0a80b67a0" -"checksum philipshue 0.3.2 (git+https://github.com/dskleingeld/philipshue)" = "" -"checksum pkg-config 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)" = "676e8eb2b1b4c9043511a9b7bea0915320d7e502b0a079fb03f9635a5252b18c" -"checksum proc-macro2 0.4.27 (registry+https://github.com/rust-lang/crates.io-index)" = "4d317f9caece796be1980837fd5cb3dfec5613ebdb04ad0956deea83ce168915" -"checksum quick-error 1.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "9274b940887ce9addde99c4eee6b5c44cc494b182b97e73dc8ffdcb3397fd3f0" -"checksum quote 0.6.11 (registry+https://github.com/rust-lang/crates.io-index)" = "cdd8e04bd9c52e0342b406469d494fcb033be4bdbe5c606016defbb1681411e1" -"checksum rand 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)" = "552840b97013b1a26992c11eac34bdd778e464601a4c2054b5f0bff7c6761293" -"checksum rand 0.5.6 (registry+https://github.com/rust-lang/crates.io-index)" = "c618c47cd3ebd209790115ab837de41425723956ad3ce2e6a7f09890947cacb9" -"checksum rand 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)" = "6d71dacdc3c88c1fde3885a3be3fbab9f35724e6ce99467f7d9c5026132184ca" -"checksum rand_chacha 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "556d3a1ca6600bfcbab7c7c91ccb085ac7fbbcd70e008a98742e7847f4f7bcef" -"checksum rand_core 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "7a6fdeb83b075e8266dcc8762c22776f6877a63111121f5f8c7411e5be7eed4b" -"checksum rand_core 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d0e7a549d590831370895ab7ba4ea0c1b6b011d106b5ff2da6eee112615e6dc0" -"checksum rand_hc 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "7b40677c7be09ae76218dc623efbf7b18e34bced3f38883af07bb75630a21bc4" -"checksum rand_isaac 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "ded997c9d5f13925be2a6fd7e66bf1872597f759fd9dd93513dd7e92e5a5ee08" -"checksum rand_jitter 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "7b9ea758282efe12823e0d952ddb269d2e1897227e464919a554f2a03ef1b832" -"checksum rand_os 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "b7c690732391ae0abafced5015ffb53656abfaec61b342290e5eb56b286a679d" -"checksum rand_pcg 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "abf9b09b01790cfe0364f52bf32995ea3c39f4d2dd011eac241d2914146d0b44" -"checksum rand_xorshift 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "cbf7e9e623549b0e21f6e97cf8ecf247c1a8fd2e8a992ae265314300b2455d5c" -"checksum rawpointer 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ebac11a9d2e11f2af219b8b8d833b76b1ea0e054aa0e8d8e9e4cbde353bdf019" -"checksum rdrand 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "678054eb77286b51581ba43620cc911abf02758c91f93f479767aed0f90458b2" -"checksum redox_syscall 0.1.51 (registry+https://github.com/rust-lang/crates.io-index)" = "423e376fffca3dfa06c9e9790a9ccd282fafb3cc6e6397d01dbf64f9bacc6b85" -"checksum redox_termios 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "7e891cfe48e9100a70a3b6eb652fef28920c117d366339687bd5576160db0f76" -"checksum regex 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)" = "9329abc99e39129fcceabd24cf5d85b4671ef7c29c50e972bc5afe32438ec384" -"checksum regex 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "37e7cbbd370869ce2e8dff25c7018702d10b21a20ef7135316f8daecd6c25b7f" -"checksum regex-syntax 0.5.6 (registry+https://github.com/rust-lang/crates.io-index)" = "7d707a4fa2637f2dca2ef9fd02225ec7661fe01a53623c1e6515b6916511f7a7" -"checksum regex-syntax 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)" = "8c2f35eedad5295fdf00a63d7d4b238135723f92b434ec06774dad15c7ab0861" -"checksum remove_dir_all 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "3488ba1b9a2084d38645c4c08276a1752dcbf2c7130d74f1569681ad5d2799c5" -"checksum reqwest 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)" = "1d56dbe269dbe19d716b76ec8c3efce8ef84e974f5b7e5527463e8c0507d4e17" -"checksum reqwest 0.9.10 (registry+https://github.com/rust-lang/crates.io-index)" = "f205a95638627fc0d21c53901671b06f439dc2830311ff11ecdff34ae2d839a8" -"checksum resolv-conf 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)" = "b263b4aa1b5de9ffc0054a2386f96992058bb6870aab516f8cdeb8a667d56dcb" -"checksum ring 0.13.5 (registry+https://github.com/rust-lang/crates.io-index)" = "2c4db68a2e35f3497146b7e4563df7d4773a2433230c5e4b448328e31740458a" -"checksum rustc-demangle 0.1.13 (registry+https://github.com/rust-lang/crates.io-index)" = "adacaae16d02b6ec37fdc7acfcddf365978de76d1983d3ee22afc260e1ca9619" -"checksum rustc_version 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)" = "c5f5376ea5e30ce23c03eb77cbe4962b988deead10910c372b226388b594c084" -"checksum rustc_version 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "138e3e0acb6c9fb258b19b67cb8abd63c00679d2851805ea151465464fe9030a" -"checksum rustls 0.13.1 (registry+https://github.com/rust-lang/crates.io-index)" = "942b71057b31981152970d57399c25f72e27a6ee0d207a669d8304cabf44705b" -"checksum rustls 0.14.0 (registry+https://github.com/rust-lang/crates.io-index)" = "8b7891791343c75b73ed9a18cadcafd8c8563d11a88ebe2d87f5b8a3182654d9" -"checksum ryu 0.2.7 (registry+https://github.com/rust-lang/crates.io-index)" = "eb9e9b8cde282a9fe6a42dd4681319bfb63f121b8a8ee9439c6f4107e58a46f7" -"checksum safemem 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "8dca453248a96cb0749e36ccdfe2b0b4e54a61bfef89fb97ec621eb8e0a93dd9" -"checksum same-file 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)" = "8f20c4be53a8a1ff4c1f1b2bd14570d2f634628709752f0702ecdd2b3f9a5267" -"checksum schannel 0.1.15 (registry+https://github.com/rust-lang/crates.io-index)" = "f2f6abf258d99c3c1c5c2131d99d064e94b7b3dd5f416483057f308fea253339" -"checksum scopeguard 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "94258f53601af11e6a49f722422f6e3425c52b06245a5cf9bc09908b174f5e27" -"checksum sct 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "cb8f61f9e6eadd062a71c380043d28036304a4706b3c4dd001ff3387ed00745a" -"checksum security-framework 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)" = "dfa44ee9c54ce5eecc9de7d5acbad112ee58755239381f687e564004ba4a2332" -"checksum security-framework 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "bfab8dda0e7a327c696d893df9ffa19cadc4bd195797997f5223cf5831beaf05" -"checksum security-framework-sys 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)" = "5421621e836278a0b139268f36eee0dc7e389b784dc3f79d8f11aabadf41bead" -"checksum security-framework-sys 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "3d6696852716b589dff9e886ff83778bb635150168e83afa8ac6b8a78cb82abc" -"checksum semver 0.1.20 (registry+https://github.com/rust-lang/crates.io-index)" = "d4f410fedcf71af0345d7607d246e7ad15faaadd49d240ee3b24e5dc21a820ac" -"checksum semver 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "1d7eb9ef2c18661902cc47e535f9bc51b78acd254da71d375c2f6720d9a40403" -"checksum semver-parser 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "388a1df253eca08550bef6c72392cfe7c30914bf41df5269b68cbd6ff8f570a3" -"checksum serde 1.0.88 (registry+https://github.com/rust-lang/crates.io-index)" = "9f301d728f2b94c9a7691c90f07b0b4e8a4517181d9461be94c04bddeb4bd850" -"checksum serde_derive 1.0.88 (registry+https://github.com/rust-lang/crates.io-index)" = "beed18e6f5175aef3ba670e57c60ef3b1b74d250d962a26604bff4c80e970dd4" -"checksum serde_json 1.0.38 (registry+https://github.com/rust-lang/crates.io-index)" = "27dce848e7467aa0e2fcaf0a413641499c0b745452aaca1194d24dedde9e13c9" -"checksum serde_urlencoded 0.5.4 (registry+https://github.com/rust-lang/crates.io-index)" = "d48f9f99cd749a2de71d29da5f948de7f2764cc5a9d7f3c97e3514d4ee6eabf2" -"checksum serde_yaml 0.8.8 (registry+https://github.com/rust-lang/crates.io-index)" = "0887a8e097a69559b56aa2526bf7aff7c3048cf627dff781f0b56a6001534593" -"checksum sha1 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "2579985fda508104f7587689507983eadd6a6e84dd35d6d115361f530916fa0d" -"checksum signal-hook 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)" = "97a47ae722318beceb0294e6f3d601205a1e6abaa4437d9d33e3a212233e3021" -"checksum siphasher 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "0b8de496cf83d4ed58b6be86c3a275b8602f6ffe98d3024a869e124147a9a3ac" -"checksum slab 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "c111b5bd5695e56cffe5129854aa230b39c93a305372fdbb2668ca2394eea9f8" -"checksum smallvec 0.6.9 (registry+https://github.com/rust-lang/crates.io-index)" = "c4488ae950c49d403731982257768f48fada354a5203fe81f9bb6f43ca9002be" -"checksum socket2 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)" = "c4d11a52082057d87cb5caa31ad812f4504b97ab44732cd8359df2e9ff9f48e7" -"checksum spidev 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "1ba01d3ef92a37e898fecac76cd3e1b33c999395e2d70787608d9678c4293e04" -"checksum stable_deref_trait 1.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "dba1a27d3efae4351c8051072d619e3ade2820635c3958d826bfea39d59b54c8" -"checksum string 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "b639411d0b9c738748b5397d5ceba08e648f4f1992231aa859af1a017f31f60b" -"checksum strsim 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "bb4f380125926a99e52bc279241539c018323fab05ad6368b56f93d9369ff550" -"checksum syn 0.15.26 (registry+https://github.com/rust-lang/crates.io-index)" = "f92e629aa1d9c827b2bb8297046c1ccffc57c99b947a680d3ccff1f136a3bee9" -"checksum synstructure 0.10.1 (registry+https://github.com/rust-lang/crates.io-index)" = "73687139bf99285483c96ac0add482c3776528beac1d97d444f6e91f203a2015" -"checksum sysfs_gpio 0.5.3 (git+https://github.com/rust-embedded/rust-sysfs-gpio)" = "" -"checksum sysfs_gpio 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)" = "3d68f2cae3c7d39f54ce8a858cc31ffb01974744ee65e5b4999b6037cd691e3f" -"checksum tempdir 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)" = "15f2b5fb00ccdf689e0149d1b1b3c03fead81c2b37735d812fa8bddbbf41b6d8" -"checksum tempfile 3.0.7 (registry+https://github.com/rust-lang/crates.io-index)" = "b86c784c88d98c801132806dadd3819ed29d8600836c4088e855cdf3e178ed8a" -"checksum termion 1.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "689a3bdfaab439fd92bc87df5c4c78417d3cbe537487274e9b0b2dce76e92096" -"checksum text_io 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)" = "9658b61ebd1d2a40c276ba2335890b9eb6550b67458a6fbce2022e58c3350a50" -"checksum textwrap 0.10.0 (registry+https://github.com/rust-lang/crates.io-index)" = "307686869c93e71f94da64286f9a9524c0f308a9e1c87a583de8e9c9039ad3f6" -"checksum thread_local 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)" = "c6b53e329000edc2b34dbe8545fd20e55a333362d0a321909685a19bd28c3f1b" -"checksum time 0.1.42 (registry+https://github.com/rust-lang/crates.io-index)" = "db8dcfca086c1143c9270ac42a2bbd8a7ee477b78ac8e45b19abfb0cbede4b6f" -"checksum tokio 0.1.15 (registry+https://github.com/rust-lang/crates.io-index)" = "e0500b88064f08bebddd0c0bed39e19f5c567a5f30975bee52b0c0d3e2eeb38c" -"checksum tokio-codec 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "5c501eceaf96f0e1793cf26beb63da3d11c738c4a943fdf3746d81d64684c39f" -"checksum tokio-current-thread 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "331c8acc267855ec06eb0c94618dcbbfea45bed2d20b77252940095273fb58f6" -"checksum tokio-executor 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "30c6dbf2d1ad1de300b393910e8a3aa272b724a400b6531da03eed99e329fbf0" -"checksum tokio-fs 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "0e9cbbc8a3698b7ab652340f46633364f9eaa928ddaaee79d8b8f356dd79a09d" -"checksum tokio-io 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)" = "b53aeb9d3f5ccf2ebb29e19788f96987fa1355f8fe45ea193928eaaaf3ae820f" -"checksum tokio-reactor 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)" = "afbcdb0f0d2a1e4c440af82d7bbf0bf91a8a8c0575bcd20c05d15be7e9d3a02f" -"checksum tokio-rustls 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)" = "04a5c8de3797c207c574495724eb77ded1a150160a2db0936c751bf49003c84e" -"checksum tokio-signal 0.2.7 (registry+https://github.com/rust-lang/crates.io-index)" = "dd6dc5276ea05ce379a16de90083ec80836440d5ef8a6a39545a3207373b8296" -"checksum tokio-sync 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "c73850a5ad497d73ccfcfc0ffb494a4502d93f35cb475cfeef4fcf2916d26040" -"checksum tokio-tcp 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "1d14b10654be682ac43efee27401d792507e30fd8d26389e1da3b185de2e4119" -"checksum tokio-threadpool 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)" = "c3fd86cb15547d02daa2b21aadaf4e37dee3368df38a526178a5afa3c034d2fb" -"checksum tokio-timer 0.2.10 (registry+https://github.com/rust-lang/crates.io-index)" = "2910970404ba6fa78c5539126a9ae2045d62e3713041e447f695f41405a120c6" -"checksum tokio-udp 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "66268575b80f4a4a710ef83d087fdfeeabdce9b74c797535fbac18a2cb906e92" -"checksum tokio-uds 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)" = "037ffc3ba0e12a0ab4aca92e5234e0dedeb48fddf6ccd260f1f150a36a9f2445" -"checksum tower-service 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b32f72af77f1bfe3d3d4da8516a238ebe7039b51dd8637a09841ac7f16d2c987" -"checksum traitobject 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "efd1f82c56340fdf16f2a953d7bda4f8fdffba13d93b00844c25572110b26079" -"checksum trust-dns-proto 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "0838272e89f1c693b4df38dc353412e389cf548ceed6f9fd1af5a8d6e0e7cf74" -"checksum trust-dns-proto 0.6.3 (registry+https://github.com/rust-lang/crates.io-index)" = "09144f0992b0870fa8d2972cc069cbf1e3c0fda64d1f3d45c4d68d0e0b52ad4e" -"checksum trust-dns-resolver 0.10.3 (registry+https://github.com/rust-lang/crates.io-index)" = "8a9f877f7a1ad821ab350505e1f1b146a4960402991787191d6d8cab2ce2de2c" -"checksum try-lock 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "e604eb7b43c06650e854be16a2a03155743d3752dd1c943f6829e26b7a36e382" -"checksum typeable 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "1410f6f91f21d1612654e7cc69193b0334f909dcf2c790c4826254fbb86f8887" -"checksum ucd-util 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "535c204ee4d8434478593480b8f86ab45ec9aae0e83c568ca81abf0fd0e88f86" -"checksum unicase 1.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7f4765f83163b74f957c797ad9253caf97f103fb064d3999aea9568d09fc8a33" -"checksum unicase 2.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "9d3218ea14b4edcaccfa0df0a64a3792a2c32cc706f1b336e48867f9d3147f90" -"checksum unicode-bidi 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)" = "49f2bd0c6468a8230e1db229cff8029217cf623c767ea5d60bfbd42729ea54d5" -"checksum unicode-normalization 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)" = "141339a08b982d942be2ca06ff8b076563cbe223d1befd5450716790d44e2426" -"checksum unicode-width 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "882386231c45df4700b275c7ff55b6f3698780a650026380e72dabe76fa46526" -"checksum unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "fc72304796d0818e357ead4e000d19c9c174ab23dc11093ac919054d20a6a7fc" -"checksum untrusted 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)" = "55cd1f4b4e96b46aeb8d4855db4a7a9bd96eeeb5c6a1ab54593328761642ce2f" -"checksum url 1.7.2 (registry+https://github.com/rust-lang/crates.io-index)" = "dd4e7c0d531266369519a4aa4f399d748bd37043b00bde1e4ff1f60a120b355a" -"checksum utf8-ranges 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "796f7e48bef87609f7ade7e06495a87d5cd06c7866e6a5cbfceffc558a243737" -"checksum uuid 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)" = "0238db0c5b605dd1cf51de0f21766f97fba2645897024461d6a00c036819a768" -"checksum v_escape 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)" = "c8b50688edb86f4c092a1a9fe8bda004b0faa3197100897653809e97e09a2814" -"checksum v_escape_derive 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "7cd994c63b487fef7aad31e5394ec04b9e24de7b32ea5251c9fb499cd2cbf44c" -"checksum v_htmlescape 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)" = "020cae817dc82693aa523f01087b291b1c7a9ac8cea5c12297963f21769fb27f" -"checksum vcpkg 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)" = "def296d3eb3b12371b2c7d0e83bfe1403e4db2d7a0bba324a12b21c4ee13143d" -"checksum vec_map 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)" = "05c78687fb1a80548ae3250346c3db86a80a7cdd77bda190189f2d0a0987c81a" -"checksum version_check 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "914b1a6776c4c929a602fafd8bc742e06365d4bcbe48c30f9cca5824f70dc9dd" -"checksum void 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "6a02e4885ed3bc0f2de90ea6dd45ebcbb66dacffe03547fadbb0eeae2770887d" -"checksum walkdir 2.2.7 (registry+https://github.com/rust-lang/crates.io-index)" = "9d9d7ed3431229a144296213105a390676cc49c9b6a72bd19f3176c98e129fa1" -"checksum want 0.0.6 (registry+https://github.com/rust-lang/crates.io-index)" = "797464475f30ddb8830cc529aaaae648d581f99e2036a928877dfde027ddf6b3" -"checksum webpki 0.18.1 (registry+https://github.com/rust-lang/crates.io-index)" = "17d7967316d8411ca3b01821ee6c332bde138ba4363becdb492f12e514daa17f" -"checksum webpki-roots 0.15.0 (registry+https://github.com/rust-lang/crates.io-index)" = "85d1f408918fd590908a70d36b7ac388db2edc221470333e4d6e5b598e44cabf" -"checksum widestring 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7157704c2e12e3d2189c507b7482c52820a16dfa4465ba91add92f266667cadb" -"checksum winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)" = "167dc9d6949a9b857f3451275e911c3f44255842c1f7a76f33c55103a909087a" -"checksum winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)" = "92c1eb33641e276cfa214a0522acad57be5c56b10cb348b3c5117db75f3ac4b0" -"checksum winapi-build 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "2d315eee3b34aca4797b2da6b13ed88266e6d612562a0c46390af8299fc699bc" -"checksum winapi-i686-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" -"checksum winapi-util 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7168bab6e1daee33b4557efd0e95d5ca70a03706d39fa5f3fe7a236f584b03c9" -"checksum winapi-x86_64-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" -"checksum winreg 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "a27a759395c1195c4cc5cda607ef6f8f6498f64e78f7900f5de0a127a424704a" -"checksum winutil 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "7daf138b6b14196e3830a588acf1e86966c694d3e8fb026fb105b8b5dca07e6e" -"checksum ws2_32-sys 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "d59cefebd0c892fa2dd6de581e937301d8552cb44489cdff035c6187cb63fa5e" -"checksum yaml-rust 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "95acf0db5515d07da9965ec0e0ba6cc2d825e2caeb7303b66ca441729801254e" + "color-eyre", + "colorimetry", + "logger", + "protocol", + "rand 0.9.0", + "regex", + "rumqttc", + "serde_json", + "strum 0.27.1", + "thiserror 2.0.12", + "tokio", + "tracing", +] diff --git a/Cargo.toml b/Cargo.toml index 6de71b02..5a84949b 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,34 +1,49 @@ -[package] -name = "HomeAutomation" -version = "0.1.0" -authors = ["David Kleingeld "] -edition = "2018" +[workspace] +resolver = "2" +members = ["crates/*"] +exclude = ["nodes/embassy/bed-lb", "nodes/embassy/bed-sb", +"nodes/esp32/airbox"] +description = "services and ui/interfaces to home automation system" -[dependencies] -actix-web = { version = "0.7.15", features = ["rust-tls"] } -actix-web-httpauth = "0.1.0" -actix = "0.7.5" -serde = "1.0" -serde_yaml = "0.8" -log = "0.4" +[workspace.dependencies] +data-server = { path = "crates/data-server" } +data-store = { path = "crates/data-store" } +log-store = { path = "crates/log-store" } +protocol = { path = "crates/protocol" } +zigbee-bridge = { path = "crates/zigbee-bridge" } +rpc = { path = "crates/rpc" } +logger = { path = "crates/logger" } -#sysfs_gpio = { version = "0.5.3", features = ["use_tokio"] } -sysfs_gpio = { git = "https://github.com/rust-embedded/rust-sysfs-gpio", branch = "master", features = ["use_tokio"] } +byteseries = { git = "https://github.com/dvdsk/byteseries", rev="a9da72e9585e5f5a8cc3cf543d6ca2561ad7007a" } -tokio = "0.1.15" -futures = { version = "0.1"} +serde = { version = "1", features = ["derive"], default-features = false } +tokio = { version = "1.38", features = ["rt-multi-thread"] } +tokio-util = { version = "0.7.16", features = ["codec"] } +itertools = { version = "0.14" } +bincode = { version = "2.0", default-features = false, features = ["serde", "std"] } +gethostname = "0.5" +governor = "0.8" +color-eyre = "0.6.3" +tracing = "0.1.40" +tracing-error = "0.2" +tracing-subscriber = { version = "0.3.18", features = ["env-filter"] } +futures = "0.3.31" +futures-concurrency = "7.6.2" +jiff = "0.1" +clap = { version = "4", features = ["derive"]} +rand = "0.9" +smallvec = { version = "2.0.0-alpha.11" } +strum = { version = "0.27", default-features = false, features = ["derive"] } +ron = "0.9" +thiserror = "2" +reserve-port = "2.2.0" -#dont forget to run cargo update when these change -philipshue = { git = "https://github.com/dskleingeld/philipshue", branch = "master" } -dataserver = { git = "https://github.com/dskleingeld/dataserver", branch = "as_lib" } +[workspace.package] +rust-version = "1.91" +edition = "2021" +license = "GPLv3" +authors = ["David Kleingeld & Eva van Houten"] -#for local dev purpose we use below targets -#dataserver = { path = "../dataserver"} -#philipshue = { path = "../philipshue"} - -linux-embedded-hal = "0.2.2" -bme280 = "0.1.1" - -smallvec = "0.6.6" -chrono = { version = "0.4.6", features = ["serde"] } -bytes = "0.4.11" \ No newline at end of file +[profile.release-with-debug] +inherits = "release" +debug = true diff --git a/crates/brain/.cargo/config.toml b/crates/brain/.cargo/config.toml new file mode 100644 index 00000000..1002fed4 --- /dev/null +++ b/crates/brain/.cargo/config.toml @@ -0,0 +1,2 @@ +[target.aarch64-unknown-linux-musl] +rustflags = ["-Clinker=rust-lld"] diff --git a/crates/brain/Cargo.toml b/crates/brain/Cargo.toml new file mode 100644 index 00000000..4e148408 --- /dev/null +++ b/crates/brain/Cargo.toml @@ -0,0 +1,36 @@ +[package] +name = "brain" +version = "0.1.0" +rust-version.workspace = true +edition.workspace = true +license.workspace = true +authors.workspace = true + +[dependencies] +protocol = { workspace = true, features = ["alloc"] } +data-server = { workspace = true } +zigbee-bridge = { workspace = true } + +futures.workspace = true +tokio = { workspace = true, features = ["full"] } + +serde.workspace = true +serde_yaml = "0.9" + +thiserror.workspace = true + +jiff = { workspace = true, features = ["serde"] } + +sled = "0.34" + +mpd = "0.1" +rand.workspace = true + +futures-util = "0.3.30" +tracing = {workspace = true} +logger.workspace = true +clap = { workspace = true } +futures-concurrency = { workspace = true } +dbstruct = { git = "https://github.com/dvdsk/dbstruct" } +color-eyre.workspace = true +mpdrs = "0.1.0" diff --git a/crates/brain/deploy.sh b/crates/brain/deploy.sh new file mode 100755 index 00000000..5e05c8dd --- /dev/null +++ b/crates/brain/deploy.sh @@ -0,0 +1,17 @@ +#!/usr/bin/env bash +set -e + +SERVER="sgc" # ssh config name or full address + +cargo build --target=aarch64-unknown-linux-musl --release +rsync -vh --progress \ + ../../target/aarch64-unknown-linux-musl/release/brain \ + $SERVER:/tmp/ + +cmds=" +sudo mv /tmp/brain /home/ha/brain +sudo chown ha:ha /home/ha/brain +sudo systemctl restart brain +" + +ssh -t $SERVER "$cmds" diff --git a/crates/brain/profile.sh b/crates/brain/profile.sh new file mode 100755 index 00000000..87e55ab2 --- /dev/null +++ b/crates/brain/profile.sh @@ -0,0 +1,10 @@ +#!/usr/bin/env bash + +cargo build --profile=release-with-debug +echo '1' | sudo tee /proc/sys/kernel/perf_event_paranoid + +samply record ../../target/release-with-debug/brain \ + --data-server 192.168.1.43:1235 \ + --mpd-ip 192.168.1.43 \ + --http-port 34326 \ + --mqtt-ip 192.168.1.43 diff --git a/crates/brain/rust-toolchain.toml b/crates/brain/rust-toolchain.toml new file mode 100644 index 00000000..6e888d40 --- /dev/null +++ b/crates/brain/rust-toolchain.toml @@ -0,0 +1,5 @@ +[toolchain] +channel = "stable" +components = [] +targets = [ "aarch64-unknown-linux-musl" ] +profile = "minimal" diff --git a/crates/brain/src/controller/environment/mod.rs b/crates/brain/src/controller/environment/mod.rs new file mode 100644 index 00000000..83880539 --- /dev/null +++ b/crates/brain/src/controller/environment/mod.rs @@ -0,0 +1,26 @@ +/// will store a short history of the last sensor values +/// useful for debouncing events (someone passing in front +/// light sensor vs a cloud) +use protocol::SensorValue; + +// struct History { +// last_values: Vec, +// } + +pub struct Environment { + // light: History, +} + +impl Environment { + pub fn update(&self, _: SensorValue) {} +} + +impl std::default::Default for Environment { + fn default() -> Self { + Environment { + // light: History { + // last_values: Vec::new(), + // }, + } + } +} diff --git a/crates/brain/src/controller/mod.rs b/crates/brain/src/controller/mod.rs new file mode 100644 index 00000000..c17ffb4d --- /dev/null +++ b/crates/brain/src/controller/mod.rs @@ -0,0 +1,209 @@ +mod rooms; + +use std::future::Future; + +use crate::system::System; +use color_eyre::eyre::Context; +pub use protocol::Reading; +use serde::{Deserialize, Serialize}; +use tokio::sync::broadcast; +use tokio::task::{JoinSet, LocalSet}; + +#[derive(Clone, Debug, Serialize, Deserialize, PartialEq)] +pub enum Event { + Sensor(Reading), + WakeupLB, + WakeupSB, + WakeupKitchen, + StateChangeSB(rooms::small_bedroom::State), +} + +#[derive(Clone)] +pub(crate) struct RestrictedSystem { + allowed_lights: Vec<&'static str>, + allowed_radiators: Vec<&'static str>, + system: System, +} + +impl RestrictedSystem { + async fn one_lamp_ct( + &mut self, + name: &'static str, + kelvin: usize, + bri: f64, + ) { + if self.allowed_lights.contains(&name) { + self.system.zigbee.set_color_temp(name, kelvin); + self.system.zigbee.set_brightness(name, bri); + } + } + + async fn one_lamp_on(&mut self, name: &'static str) { + if self.allowed_lights.contains(&name) { + self.system.zigbee.set_on(name); + } + } + + async fn one_lamp_off(&mut self, name: &'static str) { + if self.allowed_lights.contains(&name) { + self.system.zigbee.set_off(name); + } + } + + async fn all_lamps_ct(&mut self, kelvin: usize, bri: f64) { + for name in &self.allowed_lights { + self.system.zigbee.set_color_temp(name, kelvin); + self.system.zigbee.set_brightness(name, bri); + } + } + + async fn all_lamps_off(&mut self) { + for name in &self.allowed_lights { + self.system.zigbee.set_off(name); + } + } + + async fn all_lamps_on(&mut self) { + for name in &self.allowed_lights { + self.system.zigbee.set_on(name); + } + } + + #[allow(unused)] + async fn all_lamps_but_one_off(&mut self, leave_this_on: &str) { + for name in &self.allowed_lights { + if *name != leave_this_on { + self.system.zigbee.set_off(name); + } + } + } + + #[allow(unused)] + async fn all_lamps_but_one_on(&mut self, leave_this_off: &str) { + for name in &self.allowed_lights { + if *name != leave_this_off { + self.system.zigbee.set_on(name); + } + } + } + + async fn set_radiators_setpoint(&mut self, temperature: f64) { + for name in &self.allowed_radiators { + self.system.zigbee.set_radiator_setpoint(name, temperature); + } + } +} + +#[derive(Default)] +pub struct ControllerTasks { + tasks: JoinSet>, + local_set: LocalSet, +} + +impl ControllerTasks { + fn spawn(&mut self, future: F) + where + F: Future> + 'static, + { + self.tasks.spawn_local_on(future, &self.local_set); + } + + pub async fn await_tasks(self) { + self.local_set.await; + } + + pub async fn report_failed(&mut self) { + while let Some(failure) = self.tasks.join_next().await { + match failure { + Ok(Ok(())) => { + tracing::error!("Task returned, tasks should never return!") + } + Ok(Err(e)) => tracing::error!("Task returned an error: {e}"), + Err(e) => tracing::error!("Task could not join: {e}"), + } + } + } +} + +pub fn start( + subscribed: [broadcast::Receiver; 4], + sender: broadcast::Sender, + system: System, + db: sled::Db, +) -> Result { + tracing::info!("starting"); + let mut tasks = ControllerTasks::default(); + let [rx1, rx2, rx3, rx4] = subscribed; + + let restricted = RestrictedSystem { + system: system.clone(), + allowed_lights: vec![ + "large_bedroom:cabinet", + "large_bedroom:ceiling", + "large_bedroom:desk", + "large_bedroom:wardrobe", + "large_bedroom:bed", + ], + allowed_radiators: vec!["large_bedroom:radiator"], + }; + let ds = db + .open_tree("large_bedroom") + .wrap_err("Opening db subtree for large_bedroom")?; + tasks.spawn(rooms::large_bedroom::run( + rx1, + sender.clone(), + restricted, + ds, + )); + + let restricted = RestrictedSystem { + system: system.clone(), + allowed_lights: vec![ + "small_bedroom:table", + "small_bedroom:bureau", + "small_bedroom:piano", + ], + allowed_radiators: vec!["small_bedroom:radiator"], + }; + let ds = db + .open_tree("small_bedroom") + .wrap_err("Opening db subtree for small_bedroom")?; + tasks.spawn(rooms::small_bedroom::run( + rx2, + sender.clone(), + restricted, + ds, + )); + + let restricted = RestrictedSystem { + system: system.clone(), + allowed_lights: vec![ + "kitchen:ceiling", + "kitchen:hood_left", + "kitchen:hood_right", + "kitchen:fridge", + "kitchen:hallway", + ], + allowed_radiators: vec![], + }; + let ds = db + .open_tree("kitchen") + .wrap_err("Opening db subtree for kitchen")?; + tasks.spawn(rooms::kitchen::run(rx3, sender.clone(), restricted, ds)); + + let restricted = RestrictedSystem { + system: system.clone(), + allowed_lights: vec![ + "hallway:ceiling", + "bathroom:ceiling", + "toilet:ceiling", + ], + allowed_radiators: vec![], + }; + let ds = db + .open_tree("entrance") + .wrap_err("Opening db subtree for entrance")?; + tasks.spawn(rooms::entrance::run(rx4, sender, restricted, ds)); + + Ok(tasks) +} diff --git a/crates/brain/src/controller/rooms.rs b/crates/brain/src/controller/rooms.rs new file mode 100644 index 00000000..82b1a1fe --- /dev/null +++ b/crates/brain/src/controller/rooms.rs @@ -0,0 +1,31 @@ +pub mod common; +pub mod entrance; +pub mod kitchen; +pub mod large_bedroom; +pub mod small_bedroom; + +macro_rules! impl_open_or_wipe { + ($store:ty) => { + /// Maybe the struct has changed so this can no longer be opened. + /// Just wipe it in that case, too lazy to do migrations. + fn open_or_wipe( + tree: sled::Tree, + ) -> Result<$store, color_eyre::Report> { + use ::color_eyre::eyre::WrapErr; + + if let Ok(store) = <$store>::open_tree(tree.clone()) { + Ok(store) + } else { + tracing::error!( + "Could not open {}, wiping it and opening new one", + ::std::stringify!($store) + ); + tree.clear().wrap_err("Error wiping tree")?; + <$store>::open_tree(tree) + .wrap_err("Failed to open tree after wiping") + } + } + }; +} + +use impl_open_or_wipe; diff --git a/crates/brain/src/controller/rooms/common.rs b/crates/brain/src/controller/rooms/common.rs new file mode 100644 index 00000000..a4d80669 --- /dev/null +++ b/crates/brain/src/controller/rooms/common.rs @@ -0,0 +1,32 @@ +use tokio::sync::broadcast::{self, error::RecvError}; +use tracing::warn; + +use crate::controller::Event; + +pub(crate) trait RecvFiltered { + async fn recv_filter_mapped( + &mut self, + filter_map: impl Fn(Event) -> Option, + ) -> T; +} + +impl RecvFiltered for broadcast::Receiver { + async fn recv_filter_mapped( + &mut self, + filter_map: impl Fn(Event) -> Option, + ) -> T { + loop { + let event = match self.recv().await { + Ok(event) => event, + Err(RecvError::Lagged(n)) => { + warn!("A room missed {n} events"); + continue; + } + Err(err) => panic!("{err}"), + }; + if let Some(relevant) = filter_map(event) { + return relevant; + } + } + } +} diff --git a/crates/brain/src/controller/rooms/entrance.rs b/crates/brain/src/controller/rooms/entrance.rs new file mode 100644 index 00000000..b4044f7b --- /dev/null +++ b/crates/brain/src/controller/rooms/entrance.rs @@ -0,0 +1,97 @@ +use std::time::Duration; + +use futures::FutureExt; +use futures_concurrency::future::Race; +use serde::{Deserialize, Serialize}; +use tokio::sync::broadcast; +use tokio::time::{sleep_until, Instant}; + +use crate::controller::rooms::common::RecvFiltered; +use crate::controller::rooms::small_bedroom; +use crate::controller::{Event, RestrictedSystem}; + +const INTERVAL: Duration = Duration::from_secs(5); + +#[derive(PartialEq, Eq, Serialize, Deserialize, Default)] +enum State { + Sleep, + #[default] + Daylight, +} + +#[derive(Debug)] +enum RelevantEvent { + Sleep, + Daylight, +} + +fn filter(event: Event) -> Option { + match event { + Event::StateChangeSB(small_bedroom::State::Sleep) => { + Some(RelevantEvent::Sleep) + } + Event::StateChangeSB(small_bedroom::State::Daylight) => { + Some(RelevantEvent::Daylight) + } + _ => None, + } +} + +#[dbstruct::dbstruct(db=sled)] +struct Store { + #[dbstruct(Default)] + state: State, +} + +super::impl_open_or_wipe!(Store); + +pub async fn run( + mut event_rx: broadcast::Receiver, + // todo if state change message everyone using this + _event_tx: broadcast::Sender, + mut system: RestrictedSystem, + db: sled::Tree, +) -> color_eyre::Result<()> { + enum Res { + Event(RelevantEvent), + ShouldUpdate, + } + + let db = open_or_wipe(db)?; + + let mut next_update = Instant::now() + INTERVAL; + loop { + let get_event = event_rx.recv_filter_mapped(filter).map(Res::Event); + let tick = sleep_until(next_update).map(|_| Res::ShouldUpdate); + + let res = (get_event, tick).race().await; + match res { + Res::Event(RelevantEvent::Sleep) => { + db.state().set(&State::Sleep)?; + system.one_lamp_off("hallway:ceiling").await; + } + Res::Event(RelevantEvent::Daylight) => { + db.state().set(&State::Daylight)?; + + update(&mut system).await; + system.all_lamps_on().await; + } + Res::ShouldUpdate => { + if db.state().get()? == State::Daylight { + update(&mut system).await; + system.all_lamps_on().await; + } + + next_update = Instant::now() + INTERVAL; + } + } + } +} + +async fn update(system: &mut RestrictedSystem) { + let (new_ct, new_bri) = small_bedroom::daylight_now(); + let new_ct = new_ct.clamp(1000, 3000); + let new_bri = new_bri.clamp(0.5, 1.0); + system.all_lamps_ct(new_ct, new_bri).await; + tracing::trace!("updated lamps"); +} diff --git a/crates/brain/src/controller/rooms/kitchen.rs b/crates/brain/src/controller/rooms/kitchen.rs new file mode 100644 index 00000000..39c46dcd --- /dev/null +++ b/crates/brain/src/controller/rooms/kitchen.rs @@ -0,0 +1,159 @@ +use std::time::Duration; + +use futures_concurrency::future::Race; +use futures_util::FutureExt; +use serde::{Deserialize, Serialize}; +use tokio::sync::broadcast; +use tokio::time::{sleep_until, Instant}; +use tracing::{trace, warn}; + +use crate::controller::rooms::common::RecvFiltered; +use crate::controller::rooms::small_bedroom; +use crate::controller::{Event, RestrictedSystem}; +use crate::input::jobs::Job; + +const INTERVAL: Duration = Duration::from_secs(5); + +#[derive(PartialEq, Eq, Serialize, Deserialize, Default)] +enum State { + Sleep, + #[default] + Daylight, + Override, + Wakeup, +} + +#[derive(Debug)] +enum RelevantEvent { + Sleep, + Daylight, + Override, + Wakeup, +} + +fn filter(event: Event) -> Option { + match event { + Event::StateChangeSB(small_bedroom::State::Sleep) => { + Some(RelevantEvent::Sleep) + } + Event::StateChangeSB(small_bedroom::State::Daylight) => { + Some(RelevantEvent::Daylight) + } + Event::StateChangeSB(small_bedroom::State::Override) => { + Some(RelevantEvent::Override) + } + Event::WakeupKitchen => Some(RelevantEvent::Wakeup), + _ => None, + } +} + +#[dbstruct::dbstruct(db=sled)] +struct Store { + #[dbstruct(Default)] + state: State, +} + +super::impl_open_or_wipe!(Store); + +pub async fn run( + mut event_rx: broadcast::Receiver, + // todo if state change message everyone using this + _event_tx: broadcast::Sender, + mut system: RestrictedSystem, + tree: sled::Tree, +) -> color_eyre::Result<()> { + #[derive(Debug)] + enum Res { + Event(RelevantEvent), + ShouldUpdate, + } + + let db = open_or_wipe(tree)?; + let mut next_update = Instant::now() + INTERVAL; + + let wakeup_job = Job::every_day_at(10, 0, Event::WakeupKitchen, None); + let res = system + .system + .jobs + .remove_all_with_event(Event::WakeupKitchen) + .await; + trace!("Kitchen wakeup job remove result: {res:?}"); + let res = system.system.jobs.add(wakeup_job.clone()).await; + trace!("Kitchen wakeup job add result: {res:?}"); + + loop { + let get_event = event_rx.recv_filter_mapped(filter).map(Res::Event); + let tick = sleep_until(next_update).map(|_| Res::ShouldUpdate); + + let res = (get_event, tick).race().await; + match res { + Res::Event(RelevantEvent::Sleep) => { + db.state().set(&State::Sleep)?; + system.all_lamps_off().await; + } + Res::Event(RelevantEvent::Wakeup) => { + db.state().set(&State::Wakeup)?; + trace!("Starting kitchen wakeup"); + wakeup_some_lamps(&mut system).await; + } + Res::Event(RelevantEvent::Daylight) => { + db.state().set(&State::Daylight)?; + update(&mut system).await; + system.all_lamps_on().await; + } + Res::Event(RelevantEvent::Override) => { + db.state().set(&State::Override)?; + system.all_lamps_ct(2000, 1.0).await; + system.all_lamps_on().await; + } + Res::ShouldUpdate => { + if db.state().get()? == State::Daylight { + update(&mut system).await; + system.all_lamps_on().await; + } + next_update = Instant::now() + INTERVAL; + } + } + } +} + +async fn wakeup_some_lamps(system: &mut RestrictedSystem) { + const BRI: f64 = 2. / 254.; + const CT: usize = 2000; + + system.one_lamp_ct("kitchen:hood_left", CT, BRI).await; + + system.one_lamp_on("kitchen:hood_left").await; +} + +async fn update(system: &mut RestrictedSystem) { + let (new_ct, new_bri) = small_bedroom::daylight_now(); + // let (new_ct, new_bri) = _testing_ct_bri(); + system.all_lamps_ct(new_ct, new_bri).await; + tracing::trace!("updated lamps"); +} + +fn _testing_ct_bri() -> (usize, f64) { + let now = crate::time::now(); + // let optimal = match now.hour() { + let optimal = match now.minute() { + min if min % 2 == 0 => (2000, 1.0), // Even hour: orange + min if min % 2 == 1 => (4000, 1.0), // Odd hour: blue + _ => (2000, 1.0), + }; + // if now.minute() == 0 && now.second() <= 9 { + if now.second() <= 9 { + warn!("B: correct color temp is now {}", optimal.0); + } + optimal +} + +// fn handle_event(e: RelevantEvent) { +// use protocol::large_bedroom::DeskButton as D; +// use RelevantEvent as R; +// +// match e { +// R::DeskButton(D::OneOfFour(p)) if p.is_long() => todo!(), +// unhandled => warn!("Unhandled button: {unhandled:?}"), +// } +// } diff --git a/crates/brain/src/controller/rooms/large_bedroom.rs b/crates/brain/src/controller/rooms/large_bedroom.rs new file mode 100644 index 00000000..63774d93 --- /dev/null +++ b/crates/brain/src/controller/rooms/large_bedroom.rs @@ -0,0 +1,187 @@ +use std::time::{Duration, SystemTime}; + +use futures_concurrency::future::Race; +use futures_util::FutureExt; +use serde::{Deserialize, Serialize}; +use tokio::sync::broadcast; +use tokio::time::{sleep_until, Instant}; +use tracing::{info, warn}; + +use crate::controller::rooms::common::RecvFiltered; +use crate::controller::{Event, RestrictedSystem}; + +#[derive(Debug, Clone, PartialEq, Eq, Default, Serialize, Deserialize)] +enum State { + // Sleep, + // Wakeup, + FadeOut(SystemTime), + #[default] + Normal, + Bright, + Off, + // Away, +} + +const INTERVAL: Duration = Duration::from_secs(5); + +#[derive(Debug)] +enum RelevantEvent { + WakeUp, + // WeightLeft(u32), + // WeightRight(u32), + // Brightness(f32), // millilux + DeskButton(protocol::large_bedroom::desk::Button), + BedButton(protocol::large_bedroom::bed::Button), + // BedButton(protocol::large_bedroom::bed::Button), +} + +fn filter(event: Event) -> Option { + use protocol::large_bedroom::bed::Reading as B; + use protocol::large_bedroom::desk::Reading as D; + use protocol::large_bedroom::Reading as R; + use protocol::Reading::LargeBedroom as LB; + use Event::{Sensor, WakeupLB}; + + Some(match event { + WakeupLB => RelevantEvent::WakeUp, + Sensor(LB(R::Desk(D::Button(b)))) => RelevantEvent::DeskButton(b), + Sensor(LB(R::Bed(B::Button(b)))) => RelevantEvent::BedButton(b), + // Sensor(LB(R::Bed(B::Brightness(l)))) => RelevantEvent::Brightness(l), + // Sensor(LB(R::Bed(B::WeightLeft(w)))) => RelevantEvent::WeightLeft(w), + // Sensor(LB(R::Bed(B::WeightRight(w)))) => RelevantEvent::WeightRight(w), + _ => return None, + }) +} + +#[dbstruct::dbstruct(db=sled)] +struct Store { + #[dbstruct(Default)] + state: State, +} + +super::impl_open_or_wipe!(Store); + +pub(crate) async fn run( + mut event_rx: broadcast::Receiver, + // todo if state change message everyone using this + _event_tx: broadcast::Sender, + mut system: RestrictedSystem, + tree: sled::Tree, +) -> Result<(), color_eyre::Report> { + enum Res { + Event(RelevantEvent), + ShouldUpdate, + } + + let db = open_or_wipe(tree)?; + let mut next_update = Instant::now() + INTERVAL; + loop { + let get_event = event_rx.recv_filter_mapped(filter).map(Res::Event); + let tick = sleep_until(next_update).map(|_| Res::ShouldUpdate); + + let res = (get_event, tick).race().await; + let new_state = match res { + Res::Event(e) => handle_event(e), + Res::ShouldUpdate => { + next_update = Instant::now() + INTERVAL; + update(&mut system, &db.state().get()?).await + } + }; + + if let Some(new) = new_state { + info!("transitioning to new state: {new:?}"); + db.state().set(&new)?; + next_update = Instant::now() + INTERVAL; + if update(&mut system, &db.state().get()?).await.is_some() { + warn!("Transiting to a new state while in the first update is not allowed") + } + } + } +} + +async fn update(system: &mut RestrictedSystem, state: &State) -> Option { + match state { + State::Off => { + system.all_lamps_off().await; + /* TODO: make states have destructors, maybe even remove enum in + * favor of polymorphism? */ + } + State::Normal => { + let (new_ct, new_bri) = optimal_ct_bri(); + system.all_lamps_on().await; + system.all_lamps_ct(new_ct, new_bri).await; + } + State::Bright => { + system.all_lamps_on().await; + system.all_lamps_ct(3900, 1.0).await; + } + State::FadeOut(started) => { + system.all_lamps_on().await; + // TODO: this was set to 1 mired (= 1M(!!) Kelvin) and 100% brightness + // not sure that is the intended behaviour + system.all_lamps_ct(3900, 1.0).await; + if !started.elapsed().is_ok_and(|t| t < Duration::from_secs(40)) { + return Some(State::Off); + } + } + } + None +} + +fn optimal_ct_bri() -> (usize, f64) { + let now = crate::time::now(); + match now.hour() { + 0..=5 | 22.. => (2000, 0.67), + 6..=16 => (3900, 1.0), + 17..=19 => (3100, 1.0), + 20..=21 => (3100, 0.87), + _ => (3100, 1.0), + } +} + +fn handle_event(e: RelevantEvent) -> Option { + // use protocol::large_bedroom::DeskButton; + // use RelevantEvent as R; + + match e { + RelevantEvent::WakeUp => None, + // RelevantEvent::WeightLeft(_) => (), + // RelevantEvent::WeightRight(_) => (), + // RelevantEvent::Brightness(_) => (), + RelevantEvent::DeskButton(b) => handle_desk_button(b), + RelevantEvent::BedButton(b) => handle_bed_button(b), + // RelevantEvent::BedButton(_) => (), + } +} + +fn handle_desk_button( + b: protocol::large_bedroom::desk::Button, +) -> Option { + use protocol::large_bedroom::desk::Button; + + println!("button pressed: {b:?}"); + match b { + Button::OneOfFour(press) if press.is_long() => Some(State::Off), + Button::OneOfFour(_) => Some(State::FadeOut(SystemTime::now())), + Button::TwoOfFour(press) if press.is_long() => Some(State::Bright), + Button::FourOfFour(press) if !press.is_long() => Some(State::Normal), + // Button::TwoOfFour(_) => todo!(), + // Button::ThreeOfFour(_) => todo!(), + // Button::OneOfThree(_) => todo!(), + // Button::TwoOfThree(_) => todo!(), + // Button::ThreeOfThree(_) => todo!(), + _ => None, + } +} + +fn handle_bed_button(b: protocol::large_bedroom::bed::Button) -> Option { + use protocol::large_bedroom::bed::Button as B; + + println!("button pressed: {b:?}"); + match b { + B::MiddleOuter(_) => Some(State::Bright), + B::MiddleInner(_) => Some(State::Normal), + B::MiddleCenter(_) => Some(State::FadeOut(SystemTime::now())), + _ => None, + } +} diff --git a/crates/brain/src/controller/rooms/small_bedroom.rs b/crates/brain/src/controller/rooms/small_bedroom.rs new file mode 100644 index 00000000..379d370f --- /dev/null +++ b/crates/brain/src/controller/rooms/small_bedroom.rs @@ -0,0 +1,327 @@ +use std::collections::BTreeMap; +use std::fmt::Debug; +use std::time::Duration; + +use audiocontrol::ForceRewind; +use futures_concurrency::future::Race; +use futures_util::FutureExt; +use jiff::civil::Time; +use jiff::{ToSpan, Zoned}; +use protocol::small_bedroom::{portable_button_panel, ButtonPanel}; +use tokio::sync::broadcast; +use tokio::task::{self, JoinHandle}; +use tokio::time::{sleep_until, Instant}; +use tracing::{info, trace}; + +use self::filter::{RelevantEvent, Trigger}; +use self::state::Room; +pub(crate) use self::state::State; +use crate::controller::rooms::common::RecvFiltered; +use crate::controller::{Event, RestrictedSystem}; +use crate::time; + +mod audiocontrol; +mod filter; +mod state; + +const UPDATE_INTERVAL: Duration = Duration::from_secs(5); +const OFF_DELAY: Duration = Duration::from_secs(60); + +const NAP_TIME: Duration = Duration::from_secs(30 * 60); + +const fn time(hour: i8, minute: i8) -> f64 { + hour as f64 + minute as f64 / 60. +} +const T0_00: f64 = time(0, 0); +const T10_00: f64 = time(10, 0); +const T21_00: f64 = time(21, 0); + +pub async fn run( + mut event_rx: broadcast::Receiver, + event_tx: broadcast::Sender, + system: RestrictedSystem, + db: sled::Tree, +) -> color_eyre::Result<()> { + trace!("Running small bedroom task"); + let mut room = Room::new(event_tx, system.clone(), db)?; + let mut next_update = Instant::now() + UPDATE_INTERVAL; + let mut update_task: Option>> = None; + + let res = system + .system + .jobs + .remove_all_with_event(Event::WakeupSB) + .await; + trace!("Removing old SB wakeup jobs returned: {res:#?}"); + + loop { + let get_event = event_rx + .recv_filter_mapped(filter::filter) + .map(Trigger::Event); + let tick = sleep_until(next_update).map(|_| Trigger::ShouldUpdate); + + let trigger = (get_event, tick).race().await; + match trigger { + Trigger::Event( + event @ RelevantEvent::Button(_) + | event @ RelevantEvent::PortableButton(_), + ) => { + handle_button(&mut room, event).await?; + } + Trigger::Event(RelevantEvent::RadiatorOverride) => { + // trace!("Starting radiator override"); + // room.start_radiator_override(); + } + Trigger::Event(RelevantEvent::Wakeup) => room.set_wakeup().await?, + Trigger::Event(RelevantEvent::Pm2_5(val)) => { + room.store.pm2_5().set(Some(&(val, crate::time::now())))?; + } + Trigger::ShouldUpdate => { + // We don't want this to block if it takes a while, so + // we spawn a separate task for it that we need to abort + // in case it hangs + update_task.map(|task| task.abort()); + update_task = Some(task::spawn_local(update(room.clone()))); + next_update = Instant::now() + UPDATE_INTERVAL; + } + } + } +} + +async fn update(mut room: Room) -> color_eyre::Result<()> { + room.update_airbox().await?; + room.update_radiator().await?; + room.all_lights_daylight().await?; + Ok(()) +} + +async fn handle_button(room: &mut Room, event: RelevantEvent) -> color_eyre::Result<()> { + use portable_button_panel::Reading as P; + use ButtonPanel as B; + + match event { + event @ RelevantEvent::Button(button) => match button { + B::TopLeft(_) | B::TopMiddle(_) | B::TopRight(_) => { + handle_audio_button(room, event).await; + } + B::BottomLeft(_) | B::BottomMiddle(_) | B::BottomRight(_) => { + handle_light_button(room, event).await?; + } + }, + event @ RelevantEvent::PortableButton(button) => match button { + P::PlayPause + | P::TrackNext + | P::TrackPrevious + | P::VolumeUp + | P::VolumeUpHold + | P::VolumeDown + | P::VolumeDownHold + | P::Dots1LongRelease + | P::Dots2LongRelease => { + handle_audio_button(room, event).await; + } + P::Dots1ShortRelease | P::Dots2ShortRelease => { + handle_light_button(room, event).await?; + } + b => info!("Pressed unimplemented button: {b:?}"), + }, + _ => unreachable!(), + } + Ok(()) +} + +async fn handle_audio_button(room: &mut Room, button_event: RelevantEvent) { + use audiocontrol::AudioMode as A; + use portable_button_panel::Reading as P; + use ButtonPanel as B; + use RelevantEvent as E; + + let mut audio = room.audio_controller.lock().await; + match (&audio.mode, button_event) { + // Music, Singing, Meditation back (short) = previous + ( + A::Music | A::Singing | A::Meditation, + E::Button(B::TopLeft(press)), + ) if !press.is_long() => audio.previous(), + ( + A::Music | A::Singing | A::Meditation, + E::PortableButton(P::TrackPrevious), + ) => audio.previous(), + // Podcast back (short) = rewind + (A::Podcast, E::Button(B::TopLeft(press))) if !press.is_long() => { + audio.rewind() + } + (A::Podcast, E::PortableButton(P::TrackPrevious)) => audio.rewind(), + + // Music, Singing, Meditation forward (short) = next + ( + A::Music | A::Singing | A::Meditation, + E::Button(B::TopRight(press)), + ) if !press.is_long() => audio.next(), + ( + A::Music | A::Singing | A::Meditation, + E::PortableButton(P::TrackNext), + ) => audio.next(), + // Podcast forward (short) = skip + (A::Podcast, E::Button(B::TopRight(press))) if !press.is_long() => { + audio.skip() + } + (A::Podcast, E::PortableButton(P::TrackNext)) => audio.skip(), + + (_, E::Button(B::TopMiddle(press))) if !press.is_long() => { + audio.toggle_playback() + } + + (_, E::Button(B::TopLeft(press))) if press.is_long() => { + audio.prev_playlist(); + audio.play(ForceRewind::No) + } + + (_, E::Button(B::TopRight(press))) if press.is_long() => { + audio.next_playlist(); + audio.play(ForceRewind::No) + } + (_, E::PortableButton(P::Dots1LongRelease)) => { + audio.next_playlist(); + audio.play(ForceRewind::No) + } + + (_, E::Button(B::TopMiddle(press))) if press.is_long() => { + audio.next_mode(); + audio.play(ForceRewind::No) + } + (_, E::PortableButton(P::Dots2LongRelease)) => { + audio.next_mode(); + audio.play(ForceRewind::No) + } + (_, E::PortableButton(P::PlayPause)) => { + audio.toggle_playback(); + } + (_, E::PortableButton(P::VolumeUp)) => audio.increase_volume(), + (_, E::PortableButton(P::VolumeDown)) => audio.decrease_volume(), + + (_, b) => info!("Unrecognised button pressed: {b:?}"), + } +} + +async fn handle_light_button( + room: &mut Room, + event: RelevantEvent, +) -> color_eyre::Result<()> { + use portable_button_panel::Reading as P; + use ButtonPanel as B; + use RelevantEvent as E; + + // Dots1 short: toggle sleep/daylight + // + // Dots2 short: wakeup + match event { + // Light buttons + E::Button(B::BottomLeft(_)) => room.set_sleep_delayed().await?, + E::PortableButton(P::Dots1ShortRelease) => { + let now = crate::time::now(); + match time(now.hour(), now.minute()) { + // rust analyzer seems to think this illegal, its not + T21_00.. | T0_00..T10_00 => { + + room.toggle_sleep_nightlight().await? + } + _ => room.toggle_sleep_daylight().await?, + } + } + E::Button(B::BottomMiddle(_)) => room.set_daylight().await?, + E::PortableButton(P::Dots2ShortRelease) => { + room.set_wakeup().await?; + } + E::Button(B::BottomRight(_)) => room.set_override().await?, + _ => (), + } + + Ok(()) +} + +pub(super) fn is_nap_time() -> bool { + let now = time::now().datetime().time(); + + now > Time::new(13, 0, 0, 0).unwrap() + && now < Time::new(20, 0, 0, 0).unwrap() +} + +pub(crate) fn goal_temp_now() -> f64 { + let goals = BTreeMap::from([ + ((0, 00), 19.0), + ((10, 00), 19.5), + ((11, 00), 21.0), + ((12, 00), 22.0), + ((19, 00), 19.0), + ]); + + goal_now(goals, 19.0) +} + +fn air_filtration_now(pm2_5_measurement: &Option<(f32, Zoned)>) -> Option { + const LOW: u16 = 85; + let pm2_5_expiration = 10.minutes(); + let goals = + BTreeMap::from([((00, 00), LOW), ((18, 00), 100), ((21, 30), LOW)]); + + let default = goal_now(goals, LOW); + + let Some((pm2_5, measured_time)) = pm2_5_measurement else { + return Some(default); + }; + + let is_expired = measured_time.checked_add(pm2_5_expiration).unwrap() + < crate::time::now(); + if is_expired { + Some(default) + } else { + // TODO: use pm 2.5 value again + #[allow(clippy::match_single_binding)] + match pm2_5 { + // 0.0..2.0 => Some(0), + // // Don't change anything + // 2.0..4.0 => None, + _ => Some(default), + } + } +} + +// TODO: move to jobs system and remove update trigger +pub(super) fn daylight_now() -> (usize, f64) { + let goals = BTreeMap::from([ + ((0, 00), (1800, 0.5)), + ((8, 00), (2000, 0.5)), + ((9, 00), (3800, 1.0)), + ((19, 00), (3600, 1.0)), + ((19, 30), (3300, 1.0)), + ((19, 45), (3000, 1.0)), + ((20, 00), (2800, 1.0)), + ((20, 15), (2500, 1.0)), + ((20, 30), (2000, 1.0)), + ((21, 00), (1900, 0.8)), + ((21, 30), (1800, 0.5)), + ]); + + goal_now(goals, (2300, 1.0)) +} + +fn goal_now(goals: BTreeMap<(i8, i8), T>, default: T) -> T { + let Some(first_goal) = goals.first_key_value() else { + return default; + }; + + let mut prev_goal_val = first_goal.1.clone(); + + for ((h, m), goal_val) in goals { + let now = crate::time::now().datetime().time(); + let time = Time::new(h, m, 0, 0).unwrap(); + + if now < time { + return prev_goal_val.clone(); + } + prev_goal_val = goal_val + } + + prev_goal_val +} diff --git a/crates/brain/src/controller/rooms/small_bedroom/audiocontrol.rs b/crates/brain/src/controller/rooms/small_bedroom/audiocontrol.rs new file mode 100644 index 00000000..9cba7046 --- /dev/null +++ b/crates/brain/src/controller/rooms/small_bedroom/audiocontrol.rs @@ -0,0 +1,726 @@ +#![allow(clippy::enum_glob_use)] + +use std::fmt; +use std::time::Duration; + +use jiff::civil::Time; +use mpdrs::status::State; +use mpdrs::Playlist; +use mpdrs::{error::Error, Song}; +use rand::seq::IndexedRandom; +use tracing::{debug, info, instrument, trace, warn}; + +use db::Db; +use mpdinterface::MpdInterface; + +mod db; +mod mpdinterface; + +#[derive(Debug)] +enum Direction { + Next, + Previous, +} + +#[allow(clippy::struct_excessive_bools)] +struct Settings { + repeat: bool, + random: bool, + single: bool, + consume: bool, + volume: i8, + + save_playlist: bool, +} + +#[derive(Debug, PartialEq, serde::Serialize, serde::Deserialize, Clone)] +pub enum AudioMode { + Music, + Singing, + Podcast, + Meditation, +} + +impl AudioMode { + fn next(&mut self) { + use AudioMode::*; + *self = match self { + Music => Singing, + Singing => Podcast, + Podcast => Meditation, + Meditation => Music, + } + } + + fn to_prefix(&self) -> &str { + use AudioMode::*; + match self { + Music => "music_", + Singing => "singing_", + Podcast => "podcast_", + Meditation => "meditation_", + } + } + + fn settings(&self) -> Settings { + use AudioMode::*; + match self { + Music | Singing => Settings { + repeat: false, + random: false, + single: false, + consume: false, + volume: 70, + save_playlist: false, + }, + Podcast => Settings { + repeat: false, + random: false, + single: false, + consume: true, + volume: 100, + save_playlist: true, + }, + Meditation => Settings { + repeat: false, + random: false, + consume: false, + single: true, + volume: 100, + save_playlist: false, + }, + } + } + + fn to_bytes(&self) -> [u8; 1] { + use AudioMode::*; + match self { + Music => [1], + Singing => [2], + Podcast => [3], + Meditation => [4], + } + } + + fn from_bytes(bytes: &[u8]) -> Self { + use AudioMode::*; + match bytes { + &[1] => Music, + &[2] => Singing, + &[3] => Podcast, + &[4] => Meditation, + other => panic!("Unexpected serialized mode: {:?}", other), + } + } +} + +#[derive(Debug, PartialEq, Eq)] +pub enum ForceRewind { + Yes, + No, +} + +pub struct AudioController { + ip: String, + port: String, + client: MpdInterface, + db: Db, + pub(crate) mode: AudioMode, +} + +impl fmt::Debug for AudioController { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + f.debug_struct("AudioController") + .field("mode", &self.mode) + .finish() + } +} + +impl AudioController { + pub fn new(ip: &str, port: &str) -> Self { + let address = format!("{}:{}", ip, port); + let client = MpdInterface::connect(&address).unwrap(); + let mut controller = AudioController { + ip: ip.to_owned(), + port: port.to_owned(), + client, + db: Db::open("database/small_bedroom_audio"), + mode: AudioMode::Music, + }; + + if let Some(mode) = controller.fetch_current_mode() { + info!("Initializing with stored mode {:?}", mode); + controller.mode = mode; + } else { + info!("No current mode stored, defaulting to music"); + } + + controller.playing(); + controller + } + + pub fn reconnect(&mut self) -> Result<(), Box> { + let address = format!("{}:{}", self.ip, self.port); + self.client = MpdInterface::connect(&address)?; + Ok(()) + } + + #[allow(unused)] + pub fn rescan(&mut self) { + info!("Rescanning mpd library"); + self.client.rescan().unwrap(); + } + + pub fn playing(&mut self) -> bool { + let status = self.client.status(); + info!("Status: {status:?}"); + let playback_state = status.unwrap().state; + playback_state == State::Play + } + + fn stopped(&mut self) -> bool { + let playback_state = self.client.status().unwrap().state; + playback_state == State::Stop + } + + fn get_playlists(&mut self) -> Vec { + self.client.playlists().unwrap() + } + + #[instrument(ret)] + fn auto_rewind_time(last_played: u64) -> Duration { + const MIN_REWIND: u32 = 2; + + let since_last_played = Db::now_timestamp() - last_played; + info!("{}s since last played", since_last_played); + + #[allow( + clippy::cast_possible_truncation, + clippy::cast_sign_loss, + clippy::cast_precision_loss + )] + let rewind_time = (0.5 * (since_last_played as f64).sqrt()) + .round() + .clamp(0.0, 30.0) as u32; + + if rewind_time < MIN_REWIND { + Duration::from_secs(0) + } else { + Duration::from_secs(rewind_time.into()) + } + } + + fn store_current_pausing(&self) { + if let Some(current_playlist) = self.db.fetch_playlist_name(&self.mode) + { + self.db + .store_last_played(¤t_playlist, Db::now_timestamp()); + } + } + + fn rewind_after_pause(&mut self) { + use AudioMode::*; + const SONG_RESTART_THRESHOLD: Duration = + Duration::from_secs(4 * 60 * 60 * 10000); + const ALMOST_OVER: Duration = Duration::from_secs(30); + + let current_playlist = match self.db.fetch_playlist_name(&self.mode) { + Some(current_playlist) => current_playlist, + None => return, + }; + + let last_played = self.db.fetch_last_played(¤t_playlist); + + match (&self.mode, last_played) { + (Podcast, Some(last_played)) => { + self.rewind_by(Self::auto_rewind_time(last_played)); + } + (Music | Singing | Meditation, Some(last_played)) => { + if let (Some(length), Some(position)) = + (self.get_song_length(), self.get_elapsed()) + { + debug!( + "Song length: {length:?}, song position: {position:?}" + ); + let time_left = length.saturating_sub(position); + if Duration::from_secs(Db::now_timestamp() - last_played) + > SONG_RESTART_THRESHOLD + && time_left > ALMOST_OVER + { + self.seek_in_cur(0); + } + } + } + (_, None) => (), + } + } + + #[instrument] + pub fn toggle_playback(&mut self) { + info!("Toggle playback"); + let was_playing = self.playing(); + info!("Was playing: {was_playing}"); + + if self.stopped() { + self.client.play().unwrap(); + } else { + info!("Toggling pause"); + self.client.toggle_pause().unwrap(); + } + + if was_playing { + self.store_current_pausing(); + } else { + info!("Rewinding after pause"); + self.rewind_after_pause(); + } + } + + #[instrument] + pub fn play(&mut self, force_rewind: ForceRewind) { + if !self.playing() { + self.toggle_playback(); + } else if force_rewind == ForceRewind::Yes { + self.rewind_after_pause() + } + } + + fn get_song_length(&mut self) -> Option { + self.client.status().unwrap().duration + } + + fn get_elapsed(&mut self) -> Option { + self.client.status().unwrap().elapsed + } + + fn get_volume(&mut self) -> Option { + let volume = self.client.status().unwrap().volume; + if volume == -1 { + None + } else { + Some(volume) + } + } + + /// # Panics + /// + /// Panics if new position is over 4,294,967,295 seconds into the song, + /// which is 136 years. I assume this will never happen. + /// + /// Panics if client.rewind() returns an error. This may very well happen. + fn rewind_by(&mut self, duration: Duration) { + if duration == Duration::from_secs(0) { + debug!("0 seconds, not rewinding"); + return; + } + info!("Rewinding by {:?}", duration); + + if let Some(position) = self.get_elapsed() { + self.client + .rewind( + position + .saturating_sub(duration) + .as_secs() + .try_into() + .unwrap(), + ) + .unwrap(); + } + } + + pub fn rewind(&mut self) { + self.rewind_by(Duration::from_secs(15)); + self.play(ForceRewind::No); + } + + /// # Panics + /// + /// Panics if new position is over 4,294,967,295 seconds into the song, + /// which is 136 years. I assume this will never happen. + /// + /// Panics if client.rewind() returns an error. This may very well happen. + pub fn skip(&mut self) { + info!("Skipping by 15 seconds"); + + if let Some(position) = self.get_elapsed() { + self.client + .rewind((position.as_secs() + 15).try_into().unwrap()) + .unwrap(); + } + + self.play(ForceRewind::No); + } + + pub fn previous(&mut self) { + info!("Going to previous track"); + + match self.client.prev() { + Ok(_) => (), + Err(Error::Server(server_error)) => { + info!("Ignoring error during prev: {server_error}"); + assert!( + server_error.detail == "Not playing", + "Unexpected ServerError: {server_error}" + ); + } + Err(other_error) => panic!("Unexpected error: {other_error}"), + }; + // self.play(ForceRewind::No); + } + + #[instrument] + pub fn next(&mut self) { + info!("Next"); + + match self.client.next() { + Ok(_) => (), + Err(Error::Server(server_error)) => { + assert!( + server_error.detail == "Not playing", + "Unexpected ServerError: {server_error}" + ); + } + Err(other_error) => panic!("Unexpected error: {other_error}"), + }; + + self.play(ForceRewind::No); + } + + fn apply_shuffle(&mut self, playlist_name: &str) { + if playlist_name.ends_with("_shuf") { + self.client.random(true).unwrap(); + } else { + let random = self.mode.settings().random; + self.client.random(random).unwrap(); + } + self.client.pause().unwrap(); + } + + pub fn increase_volume(&mut self) { + if let Some(volume) = self.get_volume() { + let new_volume = volume.saturating_add(5).clamp(0, 100); + self.client.volume(new_volume).unwrap(); + } + } + + pub fn decrease_volume(&mut self) { + if let Some(volume) = self.get_volume() { + let new_volume = volume.saturating_sub(5).clamp(0, 100); + self.client.volume(new_volume).unwrap(); + } + } + + #[instrument] + fn switch_playlist(&mut self, direction: Direction) { + let current_playlist_name = + match self.db.fetch_playlist_name(&self.mode) { + Some(playlist_name) => playlist_name, + None => self.first_playlist_for_mode().unwrap(), + }; + self.store_position(¤t_playlist_name); + self.save_playlist_if_necessary(¤t_playlist_name); + self.db + .store_last_played(¤t_playlist_name, Db::now_timestamp()); + + let new_playlist_name = if let Some(playlist_name) = + self.playlist_for_mode(direction, ¤t_playlist_name) + { + playlist_name + } else { + current_playlist_name + }; + + info!("Switching to playlist {}", new_playlist_name); + self.load_playlist(&new_playlist_name); + self.db.store_playlist_name(&self.mode, &new_playlist_name); + self.apply_shuffle(&new_playlist_name); + + let new_position = self.db.fetch_position(&new_playlist_name); + self.load_position(new_position); + + //self.play(ForceRewind::Yes); + } + + pub fn prev_playlist(&mut self) { + self.switch_playlist(Direction::Previous); + } + + pub fn next_playlist(&mut self) { + self.switch_playlist(Direction::Next); + } + + /// Meditation mode is only enabled at night + pub fn is_meditation_time() -> bool { + const START_HOUR: i8 = 22; + const START_MIN: i8 = 30; + const END_HOUR: i8 = 9; + const END_MIN: i8 = 0; + + let now = crate::time::now().time(); + debug!("Checking if it is meditation time: now is {:?}", now); + let start = Time::new(START_HOUR, START_MIN, 0, 0).unwrap(); + let end = Time::new(END_HOUR, END_MIN, 0, 0).unwrap(); + + debug!("Meditation start time: {}, end time: {}", start, end); + let start_sm_now = start < now; + let now_sm_end = now < end; + debug!("start < now: {}, now < end: {}", start_sm_now, now_sm_end); + + start < now || now < end + } + + fn fetch_current_mode(&self) -> Option { + self.db.fetch_mode() + } + + fn store_current_mode(&self) { + self.db.store_mode(&self.mode); + } + + pub fn next_mode(&mut self) { + let current_playlist_name = + match self.db.fetch_playlist_name(&self.mode) { + Some(playlist_name) => playlist_name, + None => self.first_playlist_for_mode().unwrap(), + }; + self.store_position(¤t_playlist_name); + self.save_playlist_if_necessary(¤t_playlist_name); + self.db + .store_last_played(¤t_playlist_name, Db::now_timestamp()); + + self.mode.next(); + info!("Switching to mode {:?}", self.mode); + + if self.mode == AudioMode::Meditation && !Self::is_meditation_time() { + self.mode.next(); + trace!("Skipping meditation"); + } + + // Check if a playlist is stored in the db, and still exists + let new_playlist_name = self.db.fetch_playlist_name(&self.mode); + let new_playlist_name = match new_playlist_name { + Some(playlist_name) + if self.client.playlist_exists(&playlist_name) => + { + playlist_name + } + _ => { + let playlist_name = self.first_playlist_for_mode().unwrap(); + self.db.store_playlist_name(&self.mode, &playlist_name); + playlist_name + } + }; + self.load_playlist(&new_playlist_name); + self.store_current_mode(); + + let new_position = self.db.fetch_position(&new_playlist_name); + self.load_position(new_position); + + self.apply_settings(&self.mode.settings()); + self.apply_shuffle(&new_playlist_name); + } + + fn save_playlist_if_necessary(&mut self, playlist_name: &str) { + if self.mode.settings().save_playlist { + self.client.pl_remove(playlist_name).unwrap(); + self.client.save(playlist_name).unwrap(); + } + } + + #[instrument(ret)] + fn first_playlist_for_mode(&mut self) -> Option { + let playlists = self.get_playlists(); + for playlist in playlists { + if playlist.name.starts_with(self.mode.to_prefix()) { + return Some(playlist.name); + } + } + None + } + + #[instrument(ret)] + fn playlist_for_mode( + &mut self, + direction: Direction, + current_playlist_name: &String, + ) -> Option { + let playlists = self.get_playlists(); + assert!(!playlists.is_empty()); + let playlist_names = playlists.into_iter().map(|pl| pl.name); + let mut playlist_names = playlist_names + .filter(|pl| pl.starts_with(self.mode.to_prefix())) + .collect::>(); + + playlist_names.sort(); + + if let Direction::Previous = direction { + playlist_names.reverse(); + } + assert!(!playlist_names.is_empty()); + let mut playlist_names = playlist_names.iter().cycle().peekable(); + + while *playlist_names.peek().unwrap() != current_playlist_name { + playlist_names.next(); + } + playlist_names.nth(1).map(std::borrow::ToOwned::to_owned) + } + + fn store_position(&mut self, playlist_name: &str) { + let pos_in_pl = if let Some(song) = self.client.status().unwrap().song { + song.pos + } else { + warn!("Unknown pos in pl {playlist_name}, resetting"); + 0 + }; + + let elapsed = if let Some(elapsed) = self.get_elapsed() { + elapsed.as_secs().try_into().unwrap() + } else { + warn!("Unknown elapsed for {playlist_name}, resetting"); + 0 + }; + + let position = db::Position { pos_in_pl, elapsed }; + self.db.store_position(playlist_name, &position); + } + + fn load_playlist(&mut self, playlist_name: &str) { + self.client.clear().unwrap(); + self.client.load(playlist_name, ..).expect("Should exist"); + self.client.pause().unwrap(); + } + + fn load_position(&mut self, position: Option) { + if let Some(position) = position { + self.client.queue().unwrap(); + self.seek_to(position.pos_in_pl, position.elapsed); + } else { + self.seek_to(0, 0); + } + self.client.pause().unwrap(); + } + + fn seek_to(&mut self, pos_in_pl: u32, elapsed: u32) { + match self.client.seek(pos_in_pl, elapsed) { + Ok(_) => (), + Err(Error::Server(server_error)) => { + assert!( + server_error.detail == "Bad song index", + "Unexpected ServerError: {server_error}" + ); + } + Err(other_error) => panic!("Unexpected error: {other_error}"), + } + } + + fn seek_in_cur(&mut self, elapsed: u32) { + if let Some(song) = self.client.currentsong().unwrap() { + if let Some(place) = song.place { + self.seek_to(place.pos, elapsed); + } + } + } + + fn apply_settings(&mut self, audio_settings: &Settings) { + self.client.repeat(audio_settings.repeat).unwrap(); + self.client.random(audio_settings.random).unwrap(); + self.client.single(audio_settings.single).unwrap(); + self.client.consume(audio_settings.consume).unwrap(); + self.client.volume(audio_settings.volume).unwrap(); + self.client.pause().unwrap(); + } + + pub(crate) fn go_to_mode(&mut self, target_mode: &AudioMode) { + while self.mode != *target_mode { + self.next_mode(); + } + } + + pub(crate) fn go_to_playlist( + &mut self, + target_playlist: &str, + ) -> Result<(), String> { + let old_playlist = self.db.fetch_playlist_name(&self.mode).unwrap(); + while self.db.fetch_playlist_name(&self.mode).unwrap() + != *target_playlist + { + self.switch_playlist(Direction::Next); + if self.db.fetch_playlist_name(&self.mode).unwrap() == old_playlist + { + return Err(format!( + "Could not find target playlist {target_playlist:?} to go to" + )); + } + } + + Ok(()) + } + + pub(crate) async fn go_to_mode_playlist( + &mut self, + mode: &AudioMode, + playlist: &str, + ) { + self.go_to_mode(mode); + tokio::time::sleep(Duration::from_millis(100)).await; + match self.go_to_playlist(playlist) { + Ok(()) => (), + Err(e) => println!("{e}"), + }; + } + + pub(crate) async fn start_wakeup_music(&mut self) { + self.reconnect().unwrap(); + tokio::time::sleep(Duration::from_millis(500)).await; + + let pl_name = "music_wakeup"; + self.create_wakeup_playlist(pl_name).await; + self.go_to_mode_playlist(&AudioMode::Music, pl_name).await; + + tokio::time::sleep(Duration::from_millis(100)).await; + self.load_playlist(pl_name); + tokio::time::sleep(Duration::from_millis(100)).await; + self.load_position(None); + tokio::time::sleep(Duration::from_millis(100)).await; + self.play(ForceRewind::No); + } + + async fn create_wakeup_playlist(&mut self, pl_name: &str) { + let slow_songs = self.client.playlist("slow").unwrap(); + tokio::time::sleep(Duration::from_millis(100)).await; + let normal_songs = self.client.playlist("music_all_shuf").unwrap(); + tokio::time::sleep(Duration::from_millis(100)).await; + + self.client.pl_clear(pl_name).unwrap(); + tokio::time::sleep(Duration::from_millis(100)).await; + + let to_add = { + let mut rng = rand::rng(); + + slow_songs + .choose_multiple(&mut rng, 1) + .chain(normal_songs.choose_multiple(&mut rng, 30)) + }; + + self.client + .pl_push( + pl_name, + &Song { + file: "noise.ogg".to_string(), + ..Default::default() + }, + ) + .unwrap(); + for song in to_add { + self.client.pl_push(pl_name, song).unwrap(); + tokio::time::sleep(Duration::from_millis(10)).await; + } + } + + #[allow(unused)] + pub(crate) fn insert_next(&mut self, song_path: &str) { + if let Ok(id) = self.client.push(song_path) { + let _ = self.client.prioid(id, 128); + }; + } +} diff --git a/crates/brain/src/controller/rooms/small_bedroom/audiocontrol/db.rs b/crates/brain/src/controller/rooms/small_bedroom/audiocontrol/db.rs new file mode 100644 index 00000000..013b67c8 --- /dev/null +++ b/crates/brain/src/controller/rooms/small_bedroom/audiocontrol/db.rs @@ -0,0 +1,151 @@ +use tracing::warn; + +use super::AudioMode; +use std::time::{SystemTime, UNIX_EPOCH}; + +#[derive(Debug, serde::Serialize, serde::Deserialize)] +pub(crate) struct Position { + pub(crate) pos_in_pl: u32, + pub(crate) elapsed: u32, +} + +impl Position { + fn to_bytes(&self) -> Vec { + [self.pos_in_pl.to_ne_bytes(), self.elapsed.to_ne_bytes()].concat() + } + + fn from_bytes(bytes: &[u8]) -> Self { + Position { + pos_in_pl: u32::from_ne_bytes(bytes[..4].try_into().unwrap()), + elapsed: u32::from_ne_bytes(bytes[4..].try_into().unwrap()), + } + } +} + +#[derive(Debug)] +pub(crate) struct Db { + database: sled::Db, +} + +impl Db { + pub(crate) fn open(path: &str) -> Self { + Db { + database: sled::Config::default() + .path(path) + .cache_capacity(1_000_000) + .open() + .unwrap(), + } + } + + pub(crate) fn fetch_playlist_name( + &self, + mode: &AudioMode, + ) -> Option { + let key = mode.to_prefix().to_owned() + "cur_playlist"; + self.database + .get(key.as_bytes()) + .unwrap() + .map(|data| String::from_utf8(data.to_vec()).unwrap()) + } + + pub(crate) fn store_playlist_name( + &self, + mode: &AudioMode, + playlist_name: &str, + ) { + let key = mode.to_prefix().to_owned() + "cur_playlist"; + self.database + .insert(key.as_bytes(), playlist_name.as_bytes()) + .unwrap(); + } + + pub(crate) fn fetch_position( + &self, + playlist_name: &str, + ) -> Option { + let key = playlist_name.to_owned() + "_position"; + let position = self + .database + .get(key.as_bytes()) + .unwrap() + .map(|buffer| Position::from_bytes(buffer.as_ref())); + if playlist_name == "podcast_hank-and-john" + || playlist_name == "podcast_ross-and-carrie" + { + warn!("Fetched position: {key}, {position:?}"); + } + position + } + + pub(crate) fn store_position( + &mut self, + playlist_name: &str, + position: &Position, + ) { + let key = playlist_name.to_owned() + "_position"; + if playlist_name == "podcast_hank-and-john" + || playlist_name == "podcast_ross-and-carrie" + { + warn!("Storing position: {key}, {position:?}"); + } + self.database + .insert(key.as_bytes(), position.to_bytes()) + .unwrap(); + } + + pub(crate) fn now_timestamp() -> u64 { + SystemTime::now() + .duration_since(UNIX_EPOCH) + .unwrap() + .as_secs() + } + + pub(crate) fn fetch_last_played(&self, playlist: &str) -> Option { + let key = playlist.to_owned() + "last_played"; + self.database + .get(key.as_bytes()) + .unwrap() + .map(|bytes| u64::from_ne_bytes(bytes[..8].try_into().unwrap())) + } + + pub(crate) fn store_last_played(&self, playlist: &str, last_played: u64) { + let key = playlist.to_owned() + "last_played"; + + self.database + .insert(key.as_bytes(), &last_played.to_ne_bytes()) + .unwrap(); + } + + pub(crate) fn fetch_mode(&self) -> Option { + let key = "current_mode"; + self.database + .get(key.as_bytes()) + .unwrap() + .map(|buffer| AudioMode::from_bytes(buffer.as_ref())) + } + + pub(crate) fn store_mode(&self, mode: &AudioMode) { + let key = "current_mode"; + self.database + .insert(key.as_bytes(), &mode.to_bytes()) + .unwrap(); + } +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn fetch_and_store_last_played() { + let db = Db::open("test_db"); + + let playlist = "test_playlist_name"; + let last_played = Db::now_timestamp(); + + db.store_last_played(playlist, last_played); + let fetched = db.fetch_last_played(playlist).unwrap(); + assert_eq!(fetched, last_played); + } +} diff --git a/crates/brain/src/controller/rooms/small_bedroom/audiocontrol/mpdinterface.rs b/crates/brain/src/controller/rooms/small_bedroom/audiocontrol/mpdinterface.rs new file mode 100644 index 00000000..c434821e --- /dev/null +++ b/crates/brain/src/controller/rooms/small_bedroom/audiocontrol/mpdinterface.rs @@ -0,0 +1,177 @@ +use std::fmt; +use std::thread; + +use mpdrs::error::{Error, Result}; +use mpdrs::song::Range; +use mpdrs::{Playlist, Song, Status}; +use tracing::{debug, instrument}; + +pub(super) struct MpdInterface { + ip: String, + client: mpdrs::Client, +} + +impl fmt::Debug for MpdInterface { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + f.debug_struct("MpdClient").field("ip", &self.ip).finish() + } +} + +macro_rules! ok_or_reconnect_no_args { + ($name: ident, $return_type: ty) => { + pub(crate) fn $name(&mut self) -> Result<$return_type> { + match self.client.$name() { + Err(Error::Io(_)) => (), + Err(Error::Parse(_)) => (), + other => return other, + }; + + debug!("IOError or ParseError, reconnecting..."); + self.client = mpdrs::Client::connect(&self.ip)?; + self.client.$name() + } + }; +} +macro_rules! ok_or_reconnect_one_arg { + ($name: ident, $arg: ident, $arg_type: ty, $return_type: ty) => { + pub(crate) fn $name( + &mut self, + $arg: $arg_type, + ) -> Result<$return_type> { + match self.client.$name($arg) { + Err(Error::Io(_)) => (), + Err(Error::Parse(_)) => (), + other => return other, + }; + + debug!("IOError or ParseError, reconnecting..."); + self.client = mpdrs::Client::connect(&self.ip)?; + self.client.$name($arg) + } + }; +} + +impl MpdInterface { + #[instrument(ret, err)] + pub(crate) fn connect(ip: &str) -> Result { + let client = mpdrs::Client::connect(ip)?; + Ok(MpdInterface { + ip: ip.to_owned(), + client, + }) + } + + #[instrument(ret, err)] + pub(crate) fn rescan(&mut self) -> Result<()> { + use mpdrs::Idle; + + let mut watcher = mpdrs::Client::connect(&self.ip)?; + let thread_join_handle = thread::spawn(move || { + watcher.wait(&[mpdrs::idle::Subsystem::Update]) + }); + self.client.rescan()?; + thread_join_handle.join().unwrap()?; + Ok(()) + } + + ok_or_reconnect_no_args! {toggle_pause, ()} + ok_or_reconnect_no_args! {play, ()} + ok_or_reconnect_no_args! {prev, ()} + ok_or_reconnect_no_args! {next, ()} + ok_or_reconnect_no_args! {playlists, Vec} + ok_or_reconnect_no_args! {queue, Vec} + ok_or_reconnect_no_args! {currentsong, Option} + ok_or_reconnect_no_args! {clear, ()} + + ok_or_reconnect_one_arg! {rewind, pos, u32, ()} + ok_or_reconnect_one_arg! {pl_remove, name, &str, ()} + ok_or_reconnect_one_arg! {pl_clear, name, &str, ()} + ok_or_reconnect_one_arg! {save, name, &str, ()} + ok_or_reconnect_one_arg! {repeat, value, bool, ()} + ok_or_reconnect_one_arg! {random, value, bool, ()} + ok_or_reconnect_one_arg! {single, value, bool, ()} + ok_or_reconnect_one_arg! {consume, value, bool, ()} + ok_or_reconnect_one_arg! {playlist, name, &str, Vec} + ok_or_reconnect_one_arg! {push, path, &str, u32} + ok_or_reconnect_one_arg! {volume, volume, i8, ()} + + pub(crate) fn status(&mut self) -> Result { + match self.client.status() { + Err(Error::Io(_)) => (), + Err(Error::Parse(_)) => (), + // There is not always an error when something goes wrong + // Sometimes we just get the default status and we also + // need to retry, because this makes no sense in the logic + Ok(status) if status == Status::default() => (), + other => return other, + }; + + debug!("IOError or ParseError, reconnecting..."); + self.client = mpdrs::Client::connect(&self.ip)?; + self.client.status() + } + + pub(crate) fn pause(&mut self) -> Result<()> { + match self.client.pause(true) { + Err(Error::Io(_)) => (), + Err(Error::Parse(_)) => (), + other => return other, + }; + + debug!("IOError or ParseError, reconnecting..."); + self.client = mpdrs::Client::connect(&self.ip)?; + self.client.pause(true) + } + + pub(crate) fn load + std::marker::Copy>( + &mut self, + name: &str, + range: T, + ) -> Result<()> { + match self.client.load(name, range) { + Err(Error::Io(_) | Error::Parse(_)) => (), + other => return other, + }; + + debug!("IOError or ParseError, reconnecting..."); + self.client = mpdrs::Client::connect(&self.ip)?; + self.client.load(name, range) + } + + pub(crate) fn pl_push(&mut self, pl_name: &str, song: &Song) -> Result<()> { + match self.client.pl_push(pl_name, &song.file) { + Err(Error::Io(_) | Error::Parse(_)) => (), + other => return other, + }; + + debug!("IOError or ParseError, reconnecting..."); + self.client = mpdrs::Client::connect(&self.ip)?; + self.client.pl_push(pl_name, &song.file) + } + + pub(crate) fn seek(&mut self, place: u32, pos: u32) -> Result<()> { + match self.client.seek(place, pos) { + Err(Error::Io(_) | Error::Parse(_)) => (), + other => return other, + }; + + debug!("IOError or ParseError, reconnecting..."); + self.client = mpdrs::Client::connect(&self.ip)?; + self.client.seek(place, pos) + } + + pub(crate) fn prioid(&mut self, id: u32, prio: u8) -> Result<()> { + match self.client.prioid(id, prio) { + Err(Error::Io(_) | Error::Parse(_)) => (), + other => return other, + }; + + debug!("IOError or ParseError, reconnecting..."); + self.client = mpdrs::Client::connect(&self.ip)?; + self.client.prioid(id, prio) + } + + pub(crate) fn playlist_exists(&mut self, playlist_name: &str) -> bool { + self.playlist(playlist_name).is_ok() + } +} diff --git a/crates/brain/src/controller/rooms/small_bedroom/filter.rs b/crates/brain/src/controller/rooms/small_bedroom/filter.rs new file mode 100644 index 00000000..ad2ee664 --- /dev/null +++ b/crates/brain/src/controller/rooms/small_bedroom/filter.rs @@ -0,0 +1,49 @@ +use tracing::trace; + +use crate::controller::Event; +use protocol::{ + large_bedroom, + small_bedroom::{self, portable_button_panel, radiator}, + Reading, +}; + +#[derive(Debug)] +pub(super) enum Trigger { + Event(RelevantEvent), + ShouldUpdate, +} + +#[derive(Debug)] +pub(super) enum RelevantEvent { + Button(small_bedroom::ButtonPanel), + PortableButton(portable_button_panel::Reading), + Wakeup, + RadiatorOverride, + Pm2_5(f32), +} + +pub(super) fn filter(event: Event) -> Option { + match event { + Event::Sensor(Reading::SmallBedroom( + small_bedroom::Reading::ButtonPanel(button), + )) => Some(RelevantEvent::Button(button)), + Event::Sensor(Reading::SmallBedroom( + small_bedroom::Reading::PortableButtonPanel(button), + )) => Some(RelevantEvent::PortableButton(button)), + Event::Sensor(Reading::SmallBedroom( + small_bedroom::Reading::Radiator(radiator::Reading::SetBy(source)), + )) => { + trace!("SB received radiator setby event"); + if source == protocol::shared::radiator::Source::Manual { + Some(RelevantEvent::RadiatorOverride) + } else { + None + } + } + Event::Sensor(Reading::LargeBedroom(large_bedroom::Reading::Bed( + large_bedroom::bed::Reading::MassPm2_5(val), + ))) => Some(RelevantEvent::Pm2_5(val)), + Event::WakeupSB => Some(RelevantEvent::Wakeup), + _ => None, + } +} diff --git a/crates/brain/src/controller/rooms/small_bedroom/state.rs b/crates/brain/src/controller/rooms/small_bedroom/state.rs new file mode 100644 index 00000000..12a19290 --- /dev/null +++ b/crates/brain/src/controller/rooms/small_bedroom/state.rs @@ -0,0 +1,307 @@ +use std::sync::Arc; +use std::time::Duration; + +use color_eyre::Result; +use jiff::Zoned; +use serde::{Deserialize, Serialize}; +use tokio::io::AsyncWriteExt; +use tokio::net::TcpStream; +use tokio::sync::{broadcast, Mutex}; +use tokio::task::{self, JoinHandle}; +use tokio::time::sleep; +use tracing::{trace, warn}; + +use super::audiocontrol::AudioController; +use super::{ + air_filtration_now, daylight_now, goal_temp_now, is_nap_time, NAP_TIME, + OFF_DELAY, +}; +use crate::controller::{Event, RestrictedSystem}; + +const MPD_IP: &str = "192.168.1.101"; +const MPD_PORT: &str = "6600"; + +#[derive(PartialEq, Eq, Debug, Clone, Serialize, Deserialize, Default)] +pub(crate) enum State { + Sleep, + SleepNoWakeup, + Wakeup, + #[default] + Daylight, + Override, + DelayedOff, + Nightlight, +} + +#[dbstruct::dbstruct(db=sled)] +pub(super) struct Store { + #[dbstruct(Default)] + state: State, + radiator_override: Option, + pub(super) pm2_5: Option<(f32, Zoned)>, +} + +#[derive(Clone)] +pub(super) struct Room { + pub(super) store: Arc, + system: RestrictedSystem, + event_tx: broadcast::Sender, + task_handle: Arc>>>>, + pub(super) audio_controller: Arc>, +} + +super::super::impl_open_or_wipe!(Store); + +impl Room { + pub(super) fn new( + event_tx: broadcast::Sender, + system: RestrictedSystem, + db: sled::Tree, + ) -> Result { + let store = Arc::new(open_or_wipe(db)?); + Ok(Self { + store, + system, + event_tx, + task_handle: Arc::new(Mutex::new(None)), + audio_controller: Arc::new(Mutex::new(AudioController::new( + MPD_IP, MPD_PORT, + ))), + }) + } + + pub(super) async fn update_radiator(&mut self) -> Result<()> { + trace!("Updating radiator"); + // trace!( + // "Room radiator override state: {:?}", + // &self.radiator_override + // ); + // if let Some(override_time) = &self.radiator_override { + // if crate::time::now() + // <= override_time + // .checked_add(RADIATOR_OVERRIDE_MINUTES.minute()) + // .unwrap() + // { + // trace!("Override is set and not expired, do nothing"); + // return; + // } else { + // warn!("Radiator override is expired, resetting"); + // } + // } + let goal_temp = goal_temp_now(); + // trace!("Override is either not set or expired, set to goal temp: {goal_temp}"); + self.system.set_radiators_setpoint(goal_temp).await; + self.store.radiator_override().set(None)?; + + Ok(()) + } + + #[allow(unused)] + //TODO: fix radiator override + pub(crate) fn start_radiator_override(&mut self) -> Result<()> { + // Don't set if the radiator resends the manual state + if self.store.radiator_override().is_none()? { + warn!("Setting radiator override to now"); + let now = crate::time::now(); + self.store.radiator_override().set(Some(&now)); + } + + Ok(()) + } + + pub(super) async fn toggle_sleep_daylight(&mut self) -> Result<()> { + let state = self.store.state().get()?; + match state { + State::Sleep | State::SleepNoWakeup => { + self.set_daylight().await?; + } + State::Daylight + | State::Wakeup + | State::Override + | State::DelayedOff + | State::Nightlight => { + self.set_sleep_immediate().await?; + } + } + Ok(()) + } + + pub(super) async fn toggle_sleep_nightlight(&mut self) -> Result<()> { + let state = self.store.state().get()?; + match state { + State::Sleep | State::SleepNoWakeup => { + self.set_nightlight().await?; + } + State::Daylight + | State::Wakeup + | State::Override + | State::DelayedOff + | State::Nightlight => { + self.set_sleep_immediate().await?; + } + } + Ok(()) + } + + pub(super) async fn set_sleep_immediate(&mut self) -> Result<()> { + self.system.all_lamps_off().await; + self.set_state_cancel_prev(State::Sleep).await?; + Ok(()) + } + + pub(super) async fn set_sleep_delayed(&mut self) -> Result<()> { + self.set_state_cancel_prev(State::DelayedOff).await?; + + self.system.one_lamp_off("small_bedroom:bureau").await; + self.system.one_lamp_off("small_bedroom:piano").await; + + let task_handle = + task::spawn_local(self.clone().delayed_off_then_sleep()); + *self.task_handle.lock().await = Some(task_handle); + Ok(()) + } + + pub(super) async fn set_wakeup(&mut self) -> Result<()> { + if self.store.state().get()? == State::SleepNoWakeup { + warn!("Ignoring wakeup because of override"); + return Ok(()); + } + warn!("Starting wakeup"); + self.set_state_cancel_prev(State::Wakeup).await?; + + let task_handle = + task::spawn_local(self.clone().run_wakeup_then_daylight()); + *self.task_handle.lock().await = Some(task_handle); + Ok(()) + } + + pub(super) async fn set_daylight(&mut self) -> Result<()> { + self.set_state_cancel_prev(State::Daylight).await?; + self.all_lights_daylight().await?; + self.system.all_lamps_on().await; + Ok(()) + } + + pub(super) async fn set_nightlight(&mut self) -> Result<()> { + self.set_state_cancel_prev(State::Nightlight).await?; + self.system + .one_lamp_ct("small_bedroom:table", 1800, 0.1) + .await; + self.system.one_lamp_on("small_bedroom:table").await; + Ok(()) + } + + pub(super) async fn set_override(&mut self) -> Result<()> { + self.set_state_cancel_prev(State::Override).await?; + self.system.all_lamps_ct(2000, 1.0).await; + self.system.all_lamps_on().await; + Ok(()) + } + + async fn set_state_cancel_prev(&mut self, state: State) -> Result<()> { + self.cancel_task().await; + self.store.state().set(&state)?; + let _ = self.event_tx.send(Event::StateChangeSB(state)); + Ok(()) + } + + async fn set_state(&mut self, state: State) -> Result<()> { + self.store.state().set(&state)?; + let _ = self.event_tx.send(Event::StateChangeSB(state)); + Ok(()) + } + + async fn cancel_task(&mut self) { + if let Some(ref task) = *self.task_handle.lock().await { + task.abort(); + } + } + + async fn delayed_off_then_sleep(mut self) -> Result<()> { + sleep(OFF_DELAY).await; + self.system.all_lamps_off().await; + self.set_state(State::Sleep).await?; + + if is_nap_time() { + sleep(NAP_TIME).await; + self.set_state(State::Daylight).await?; + self.all_lights_daylight().await?; + self.system.all_lamps_on().await; + } + Ok(()) + } + + // Returns result simply so the task handle when this is spawned as a task + // is the same as for the other function + async fn run_wakeup_then_daylight(mut self) -> Result<()> { + const LIGHT_NAME: &str = "small_bedroom:table"; + const RUNTIME_MINS: i32 = 5; + const MUSIC_ON_AFTER_MINS: i32 = 5; + + const STEP_SIZE_SECS: i32 = 30; + const N_STEPS: i32 = RUNTIME_MINS * 60 / STEP_SIZE_SECS; + const MUSIC_STEP: i32 = MUSIC_ON_AFTER_MINS * 60 / STEP_SIZE_SECS; + + const START_BRI: f64 = 1. / 254.; + const START_CT: usize = 2000; + const END_BRI: f64 = 1.0; + const END_CT: usize = 3500; + + let bri_growth = (END_BRI / START_BRI).powf(1. / N_STEPS as f64); + let ct_growth = + (END_CT as f64 / START_CT as f64).powf(1. / N_STEPS as f64); + + self.system + .one_lamp_ct(LIGHT_NAME, START_CT, START_BRI) + .await; + self.system.one_lamp_on(LIGHT_NAME).await; + warn!("Wakeup lamp should be on now"); + + for step in 1..=N_STEPS { + sleep(Duration::from_secs( + STEP_SIZE_SECS.try_into().expect("Should be positive"), + )) + .await; + + let new_bri = START_BRI * bri_growth.powi(step); + let new_ct = + (START_CT as f64 * ct_growth.powi(step)).round() as usize; + + self.system.one_lamp_ct(LIGHT_NAME, new_ct, new_bri).await; + + if step == MUSIC_STEP { + let mut audio = self.audio_controller.lock().await; + audio.start_wakeup_music().await; + } + } + + self.set_state(State::Daylight).await?; + self.all_lights_daylight().await?; + self.system.all_lamps_on().await; + warn!("Wakeup done"); + + Ok(()) + } + + // TODO: make private once updates are in job system + pub(super) async fn all_lights_daylight(&mut self) -> Result<()> { + if self.store.state().get()? == State::Daylight { + let (new_ct, new_bri) = daylight_now(); + self.system.all_lamps_ct(new_ct, new_bri).await; + } + Ok(()) + } + + pub(crate) async fn update_airbox(&self) -> Result<()> { + let Some(setting) = air_filtration_now(&self.store.pm2_5().get()?) + else { + return Ok(()); + }; + + if let Ok(mut stream) = TcpStream::connect("192.168.1.103:4444").await { + let message: u16 = 0xDD00 + setting; + let _ = stream.write(&message.to_le_bytes()).await; + } + Ok(()) + } +} diff --git a/crates/brain/src/input/jobs.rs b/crates/brain/src/input/jobs.rs new file mode 100644 index 00000000..790f9fb9 --- /dev/null +++ b/crates/brain/src/input/jobs.rs @@ -0,0 +1,267 @@ +use std::{fmt, sync::Arc, time::Duration}; + +use jiff::{Span, ToSpan, Zoned}; +use serde::{Deserialize, Serialize}; +use tokio::sync::{broadcast, mpsc, Mutex}; +use tokio::{task, time}; +use tracing::{error, info, trace}; + +use crate::{controller::Event, time::to_next_datetime}; + +#[derive(thiserror::Error, Debug)] +pub(crate) enum Error { + #[error("Could not store/edit job on disk")] + Db(#[from] sled::Error), + #[error("Could not inform event timer about new job")] + Comm(#[from] mpsc::error::SendError<()>), + #[error("Dbstruct error")] + DbStruct(#[from] dbstruct::Error), + // #[error("Dbstruct error")] + // DbStructDoubleError(#[from] dbstruct::Error>), +} + +#[derive(Serialize, Deserialize, Debug, Clone, PartialEq)] +pub(crate) struct Job { + pub(crate) time: Zoned, + pub(crate) event: Event, + pub(crate) every_day: bool, + /// how long after the time was missed the job + /// should still be executed + pub(crate) expiration: Option, +} + +impl Job { + #[allow(unused)] + pub(crate) fn at_next( + hour: i8, + min: i8, + event: Event, + expiration: Option, + ) -> Job { + Job { + time: to_next_datetime(hour, min), + every_day: false, + event, + expiration, + } + } + + pub(crate) fn every_day_at( + hour: i8, + min: i8, + event: Event, + expiration: Option, + ) -> Job { + Job { + time: to_next_datetime(hour, min), + every_day: true, + event, + expiration, + } + } + + pub(crate) fn add_one_day(mut self) -> Self { + self.time = self.time.checked_add(1.day()).unwrap(); + self + } +} + +#[derive(Clone)] +pub(crate) struct Jobs { + job_change_tx: mpsc::Sender<()>, + list: Arc>, +} + +impl fmt::Debug for Jobs { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + write!(f, "Jobs db and manager") + } +} + +#[dbstruct::dbstruct(db=sled)] +struct JobList { + jobs: HashMap, +} + +impl Jobs { + pub(crate) fn setup( + event_tx: broadcast::Sender, + db: sled::Db, + ) -> Result { + let db = db.open_tree("JobList")?; + let job_list = Arc::new(Mutex::new(JobList::open_tree(db)?)); + + let (job_change_tx, job_change_rx) = mpsc::channel(250); + let job_list_clone = job_list.clone(); + task::spawn(event_timer(job_list_clone, event_tx, job_change_rx)); + + Ok(Self { + list: job_list, + job_change_tx, + }) + } + + // we decrease the time till the job until there is a place in the database + // as only one job can fire at the time, after a job gets a timeslot + // it is never changed + pub(crate) async fn add(&self, to_add: Job) -> Result { + let id = { + let list = self.list.lock().await; + list.add_job(to_add)? + }; + //signal event timer to update its next job + self.job_change_tx.send(()).await?; + Ok(id) + } + + pub(crate) async fn remove_all_with_event( + &self, + event_to_remove: Event, + ) -> Result, Error> { + let ids_to_remove: Vec<_> = { + let list = self.list.lock().await; + let jobs = list.jobs(); + + jobs.iter() + .filter_map(|res| res.ok()) + .filter(|(_, job)| job.event == event_to_remove) + .map(|(id, _)| id) + .collect() + }; + + let mut removed = Vec::new(); + + for id in ids_to_remove { + let old_job = self.remove(id).await?; + if let Some(old_job) = old_job { + removed.push(old_job); + } + } + + Ok(removed) + } + + pub(crate) async fn remove( + &self, + to_remove: i64, + ) -> Result, Error> { + let removed_job = { self.list.lock().await.remove_job(to_remove)? }; + //signal event timer to update its next job + self.job_change_tx.send(()).await?; + Ok(removed_job) + } + + #[allow(unused)] + pub(crate) async fn get(&self, id: i64) -> Result, Error> { + self.list.lock().await.get_job(id) + } +} + +impl JobList { + fn get_job(&self, id: i64) -> Result, Error> { + Ok(self.jobs().get(&id)?) + } + + // we decrease the id for the job until there is a place in the database + // after a job gets an id it is never changed + /// return the id for the job + fn add_job(&self, new_job: Job) -> Result { + let mut new_id = new_job.time.timestamp().as_millisecond(); + + // create job entry if there is no job at this timestamp yet + // if there is already a job scheduled, and it is not exactly the same, + // change the id for this one until there is a spot free + while let Some(old_job) = self.jobs().get(&new_id)? { + if old_job == new_job { + return Ok(new_id); + } + // create unique key + new_id -= 1; + } + self.jobs().insert(&new_id, &new_job)?; + Ok(new_id) + } + + fn remove_job(&self, to_remove: i64) -> Result, Error> { + let old_job = self.jobs().remove(&to_remove)?; + Ok(old_job) + } + + fn peek_next(&mut self) -> Option<(i64, Job)> { + let list: Vec<_> = self.jobs().iter().filter_map(|r| r.ok()).collect(); + list.first().cloned() + } +} + +async fn event_timer( + job_list: Arc>, + event_tx: broadcast::Sender, + mut job_change_rx: mpsc::Receiver<()>, +) { + loop { + // This can fail + // TODO make sure an non waking error alarm is send to the user + let peeked = { + let mut job_list = job_list.lock().await; + job_list.peek_next() + }; + if let Some((id, current_job)) = peeked { + let now = crate::time::now(); + let timeout = ¤t_job.time - &now; + if let Some(expiration) = current_job.expiration { + if now > ¤t_job.time + Span::try_from(expiration).unwrap() + { + error!("skipping job too far in the past"); + job_list.lock().await.remove_job(id).unwrap(); + continue; // job too far in the past, skip and get next + } + } + let timeout = + Duration::try_from(timeout).unwrap_or(Duration::from_secs(0)); + info!("next job is in: {} seconds", timeout.as_secs()); + + // do we send out the event or should we add or remove a job? + match time::timeout(timeout, job_change_rx.recv()).await { + Ok(Some(_)) => continue, // new job entered, restart loop + Ok(None) => { + error!("1 job_change_rx disconnected"); + return; + } + Err(_) => { + trace!("Sending out event for job {current_job:#?}"); + // time to send the job event + event_tx + .send(current_job.event.clone()) + .expect("controller should listen on this"); + + job_list.lock().await.remove_job(id).unwrap(); + if current_job.every_day { + let new_job = current_job.add_one_day(); + let new_id = job_list + .lock() + .await + .add_job(new_job.clone()) + .unwrap(); + trace!( + "Added repeat job {new_job:#?} with id {new_id}" + ); + } + continue; //get next job + } + } + } else { + //no job to wait on, wait for instructions + info!("no job in the future"); + //A message through the mpsc signals a job has been added + match job_change_rx.recv().await { + // jobs were added or removed, go back and start waiting on them + Some(_) => (), + // can't have timed out thus program should exit + None => { + error!("2 job_change_rx disconnected"); + return; + } + } + } + } +} diff --git a/crates/brain/src/input/mod.rs b/crates/brain/src/input/mod.rs new file mode 100644 index 00000000..40e97747 --- /dev/null +++ b/crates/brain/src/input/mod.rs @@ -0,0 +1,4 @@ +pub mod jobs; +pub mod sensors; +// pub mod mpd_status; +// pub use mpd_status::MpdStatus; diff --git a/crates/brain/src/input/mpd_status.rs b/crates/brain/src/input/mpd_status.rs new file mode 100644 index 00000000..8cac7e25 --- /dev/null +++ b/crates/brain/src/input/mpd_status.rs @@ -0,0 +1,70 @@ +use crate::errors::Error; +use crossbeam_channel::{Receiver, Sender}; +use mpd::{idle::Idle, idle::Subsystem, Client}; +use std::net::{IpAddr, SocketAddr}; +use std::sync::{Arc, RwLock}; +use std::thread; + +//mpd watcher, waits on mpd sys changes and stores in struct/sends updates to whomever needs to know +//mpd command sender (opens new connection for every command?) + +#[derive(Clone)] +pub struct MpdStatus { + inner: Arc>, +} + +impl MpdStatus { + pub fn get_volume(&mut self) -> i8 { + self.inner.read().unwrap().volume + } + + pub fn is_playing(&mut self) -> mpd::status::State { + self.inner.read().unwrap().state + } +} + +fn mpd_watcher(mut client: Client, status: MpdStatus, rx: Receiver<()>) { + client.wait(&[Subsystem::Player, Subsystem::Mixer]).unwrap(); + loop { + //if we have a message that means we should shut down + if let Ok(_) = rx.try_recv() { + return; + } + //this loop is stopped by sending a change to mpd server + if let Ok(_) = client.wait(&[Subsystem::Player, Subsystem::Mixer]) { + //update status + let new_status = client.status().unwrap(); + *(status.inner.write().unwrap()) = new_status; + } else { + return; + } + } +} + +impl MpdStatus { + /*pub fn stop_updating(tx: Sender<()>) { + let mut client = mpd::Client::connect("127.0.0.1:6600").unwrap(); + tx.send(()).unwrap(); //tell mpd watcher to shut down on next check + //make a small change to a subsys that is watched to force mpd_watcher to stop idle mode + let status = client.status().unwrap(); + client.volume(status.volume+1).unwrap(); + client.volume(status.volume).unwrap(); + }*/ + + pub fn start_updating(mpd_ip: IpAddr) -> Result<(Self, thread::JoinHandle<()>, Sender<()>), Error> { + let mut client = mpd::Client::connect(SocketAddr::new(mpd_ip, 6600))?; + let status = client.status()?; + + let mpd_status = Self { + inner: Arc::new(RwLock::new(status)), + }; + let mpd_status_cloned = mpd_status.clone(); + let (tx, rx) = crossbeam_channel::bounded(1); + + let mpd_watcher_thread = thread::spawn(move || { + mpd_watcher(client, mpd_status_cloned, rx); + }); + + Ok((mpd_status, mpd_watcher_thread, tx)) + } +} diff --git a/crates/brain/src/input/sensors.rs b/crates/brain/src/input/sensors.rs new file mode 100644 index 00000000..bcc84637 --- /dev/null +++ b/crates/brain/src/input/sensors.rs @@ -0,0 +1,23 @@ +use std::net::SocketAddr; + +use data_server::api::subscriber::{ReconnectingClient, SubMessage}; +use tokio::sync::broadcast; + +use crate::controller::Event; + +pub async fn subscribe( + event_tx: broadcast::Sender, + data_server: SocketAddr, +) { + let mut sub = + ReconnectingClient::new(data_server, "ha-brain".to_owned()).subscribe(); + loop { + match sub.next().await { + SubMessage::Reading(reading) => { + event_tx.send(Event::Sensor(reading)).unwrap(); + } + SubMessage::ErrorReport(_) + | SubMessage::AffectorControlled { .. } => continue, + } + } +} diff --git a/crates/brain/src/main.rs b/crates/brain/src/main.rs new file mode 100644 index 00000000..03d8ef7b --- /dev/null +++ b/crates/brain/src/main.rs @@ -0,0 +1,69 @@ +use std::array; +use std::net::{IpAddr, SocketAddr}; + +use clap::Parser; +use color_eyre::eyre::eyre; +use tokio::sync::broadcast; + +use self::input::jobs::Jobs; +use self::system::System; + +mod controller; +mod input; +mod system; +mod time; + +#[derive(Parser)] +#[command(version, about, long_about=None)] +struct Opt { + /// IP address where to subscribe for updates + #[clap(long)] + data_server: SocketAddr, + + /// IP address for mpd server + #[clap(long)] + mpd_ip: IpAddr, + + /// http API listens on this port at 127.0.0.1 use + /// a loadbalancer/reverse proxy to get traffic to this + #[clap(long)] + http_port: u16, + + /// IP address for MQTT broker + #[clap(long)] + mqtt_ip: IpAddr, +} + +#[tokio::main] +async fn main() -> Result<(), color_eyre::Report> { + color_eyre::install().unwrap(); + logger::tracing::setup(); + let opt = Opt::parse(); + + // must create all listeners before jobs/alarm events can be send + // or they may be lost. + let (event_tx, _event_rx) = broadcast::channel(250); + let subscribed_rxs = array::from_fn(|_| event_tx.subscribe()); + + let db = sled::Config::default() + .cache_capacity(4_000_000) + .path("database") + .open()?; + let jobs = Jobs::setup(event_tx.clone(), db.clone())?; + + let system = System::init(opt.mqtt_ip, jobs); + let tasks = + controller::start(subscribed_rxs, event_tx.clone(), system, db)?; + + // This never returns, should be replaced by an endless loop if (re)moved + let _subscribe = tokio::task::spawn(input::sensors::subscribe( + event_tx, + opt.data_server, + )); + + tasks.await_tasks().await; + + // TODO: re-enable this by joining? with await_tasks + // tasks.report_failed().await; + Err(eyre!("All tasks have failed! shutting down")) +} diff --git a/crates/brain/src/system.rs b/crates/brain/src/system.rs new file mode 100644 index 00000000..fc0d7e9e --- /dev/null +++ b/crates/brain/src/system.rs @@ -0,0 +1,25 @@ +use std::net::IpAddr; + +// pub mod mpd_control; +use zigbee_bridge::Controller; +// pub use mpd_control::Mpd; + +use crate::input::jobs::Jobs; + +#[derive(Debug, Clone)] +pub struct System { + #[allow(dead_code)] + pub jobs: Jobs, + pub zigbee: Controller, + // pub mpd: Mpd, +} + +impl System { + pub fn init(mqtt_ip: IpAddr, jobs: Jobs) -> Self { + Self { + jobs, + zigbee: Controller::start_bridge(mqtt_ip, "brain"), + // mpd: Mpd, + } + } +} diff --git a/crates/brain/src/system/computer.rs b/crates/brain/src/system/computer.rs new file mode 100644 index 00000000..20df2e15 --- /dev/null +++ b/crates/brain/src/system/computer.rs @@ -0,0 +1,5 @@ + +//thread that keeps an open conn to ssh server on pc? using ssh2 lib +//allows rbtw to execute on linux +//alows shutdown keyboard commands on windows via arduino keyboard +//allows boot pc via pc header pin pulse \ No newline at end of file diff --git a/crates/brain/src/system/mpd_control.rs b/crates/brain/src/system/mpd_control.rs new file mode 100644 index 00000000..7e0f7db0 --- /dev/null +++ b/crates/brain/src/system/mpd_control.rs @@ -0,0 +1,110 @@ +use crate::errors::Error; +use std::time::Duration; +use rand::Rng; +use tracing::warn; + +use crate::input::mpd_status::MpdStatus; + +// TODO make this stuff obj oriented +#[derive(Debug, Clone)] +pub struct Mpd; + +pub fn add_from_playlist( + mpd: &mut mpd::Client, + name: &str, + minimal_play_time: Duration, + maximal_play_time: Duration, +) -> Result<(), mpd::error::Error> { + let mut rng = rand::thread_rng(); + + let songs = mpd.playlist(name); + let mut songs = match songs { + //report all errors except non existing playlist + Ok(songs) => songs, + Err(error) => match error { + mpd::error::Error::Server(serv_error) => match serv_error.code { + mpd::error::ErrorCode::NoExist => { + warn!("could not find playlist: {}", name); + return Ok(()); + } + _ => return Err(mpd::error::Error::Server(serv_error).into()), + }, + _ => return Err(error.into()), + }, + }; + + let mut time = Duration::from_secs(0); + //add random songs until the playtime is larger then the minimum + while time < minimal_play_time && songs.len() > 1 { + let idx = rng.gen_range(0..(songs.len() - 1)); + let song = songs.remove(idx); + if let Some(duration) = song.duration { + if time + duration < maximal_play_time { + time = time + song.duration.unwrap(); + mpd.push(song)?; + } + } + } + Ok(()) +} + +pub fn increase_volume(mpd_status: &mut MpdStatus) -> Result<(), Error> { + const VOLUME_INCREMENT: i8 = 5; + + let mut client = mpd::Client::connect("127.0.0.1:6600")?; + let current_volume = mpd_status.get_volume(); + if current_volume + VOLUME_INCREMENT > 100 { + return Ok(()); + } + + client.volume(current_volume + VOLUME_INCREMENT)?; + Ok(()) +} + +pub fn decrease_volume(mpd_status: &mut MpdStatus) -> Result<(), Error> { + const VOLUME_INCREMENT: i8 = 5; + + let mut client = mpd::Client::connect("127.0.0.1:6600")?; + let current_volume = mpd_status.get_volume(); + if current_volume - VOLUME_INCREMENT < 0 { + return Ok(()); + } + + client.volume(current_volume - VOLUME_INCREMENT)?; + Ok(()) +} + +pub fn next_song() -> Result<(), Error> { + let mut client = mpd::Client::connect("127.0.0.1:6600")?; + client.next()?; + Ok(()) +} + +pub fn prev_song() -> Result<(), Error> { + let mut client = mpd::Client::connect("127.0.0.1:6600")?; + client.prev()?; + Ok(()) +} + +pub fn toggle_playback(mpd_status: &mut MpdStatus) -> Result<(), Error> { + let mut client = mpd::Client::connect("127.0.0.1:6600")?; + + match mpd_status.is_playing() { + mpd::status::State::Stop => client.play()?, + mpd::status::State::Pause => client.toggle_pause()?, + mpd::status::State::Play => client.toggle_pause()?, + } + Ok(()) +} + +pub fn pause() -> Result<(), Error> { + let mut client = mpd::Client::connect("127.0.0.1:6600")?; + client.pause(true)?; + Ok(()) +} + +pub fn save_current_playlist(mpd: &mut mpd::Client) -> Result<(), mpd::error::Error> { + mpd.pl_remove("temp")?; + mpd.save("temp")?; + Ok(()) +} diff --git a/crates/brain/src/time.rs b/crates/brain/src/time.rs new file mode 100644 index 00000000..6c0605f8 --- /dev/null +++ b/crates/brain/src/time.rs @@ -0,0 +1,25 @@ +use jiff::{tz::TimeZone, Timestamp, Zoned}; + +// Because the pi might be set to UTC, we need to manually add the tz +pub(crate) fn now() -> Zoned { + let local = TimeZone::get("Europe/Amsterdam").unwrap(); + Timestamp::now().to_zoned(local) +} + +pub(crate) fn to_next_datetime(hour: i8, min: i8) -> Zoned { + let now = crate::time::now(); + let job_time = now.with().hour(hour).minute(min).second(0).build().unwrap(); + + if job_time < now { + let tomorrow = now.tomorrow().unwrap(); + tomorrow + .with() + .hour(hour) + .minute(min) + .second(0) + .build() + .unwrap() + } else { + job_time + } +} diff --git a/crates/brain/test.sh b/crates/brain/test.sh new file mode 100755 index 00000000..00bad8b1 --- /dev/null +++ b/crates/brain/test.sh @@ -0,0 +1,7 @@ +#!/usr/bin/env bash + +RUST_LOG=brain=trace,zigbee_bridge=info,info RUST_BACKTRACE=1 cargo r -- \ + --data-server 192.168.1.43:1235 \ + --mpd-ip 192.168.1.43 \ + --http-port 34326 \ + --mqtt-ip 192.168.1.43 diff --git a/crates/brain/web/add_song.html b/crates/brain/web/add_song.html new file mode 100755 index 00000000..d8010816 --- /dev/null +++ b/crates/brain/web/add_song.html @@ -0,0 +1,46 @@ + + + + + + + + + + + + \ No newline at end of file diff --git a/web/graph.html b/crates/brain/web/graph.html old mode 100644 new mode 100755 similarity index 100% rename from web/graph.html rename to crates/brain/web/graph.html diff --git a/web/graphDebug.html b/crates/brain/web/graphDebug.html old mode 100644 new mode 100755 similarity index 100% rename from web/graphDebug.html rename to crates/brain/web/graphDebug.html diff --git a/web/login.css b/crates/brain/web/login.css old mode 100644 new mode 100755 similarity index 100% rename from web/login.css rename to crates/brain/web/login.css diff --git a/web/login.html b/crates/brain/web/login.html old mode 100644 new mode 100755 similarity index 100% rename from web/login.html rename to crates/brain/web/login.html diff --git a/web/plot.js b/crates/brain/web/plot.js old mode 100644 new mode 100755 similarity index 54% rename from web/plot.js rename to crates/brain/web/plot.js index 05a79920..0b5f149f --- a/web/plot.js +++ b/crates/brain/web/plot.js @@ -22,6 +22,28 @@ var layout = { //TODO extend id_map to keep track of position is typedArray +Date.prototype.toDateInputValue = (function() { + var local = new Date(this); + local.setMinutes(this.getMinutes() - this.getTimezoneOffset()); + return local.toJSON().slice(0,10); +}); + +// ensure that after conversion to GMT the date will still be correct +Date.prototype.toTimeInputValue = (function() { + var local = new Date(this); + local.setUTCHours(this.getHours(), this.getMinutes(), this.getSeconds(),0); + return local; +}); + +function onLoad(){ + var d = new Date(); + var timeControl = document.getElementById("stop-time"); + timeControl.valueAsDate = d.toTimeInputValue(); + var dateControl = document.getElementById("stop-date"); + dateControl.value = d.toDateInputValue(); +} +window.addEventListener("load", onLoad, false); + function init(){ output = document.getElementById("output"); @@ -32,13 +54,15 @@ function init(){ websocket.onerror = function(evt) { onError(evt) }; } + + function onOpen(evt){ writeToScreen("CONNECTED"); //parse the form //TODO change plot button to "update" var selected = document.forms["choose lines"]; - for (var i = 0; i < selected.length; i++) { + for (var i = 0; i < selected.length; i++) {//TODO selected.for ... of ... (look up) if (selected[i].checked === true) { var input = selected[i].value; let [set_id_str, field_id] = input.split(","); @@ -52,13 +76,25 @@ function onOpen(evt){ } } - var start_timestamp = 0;//placeholder - var stop_timestamp = 0; + //var dateOffset = (24*60*60*1000);//TODO fix this + //var stop_timestamp = new Date( Date.now() ); + + //var start_timestamp = new Date(); + //console.log(stop_timestamp.getTime()); + //start_timestamp.setTime(stop_timestamp.getTime() - dateOffset); + + //TODO improve + //var start_timestamp = document.getElementById('start-date').valueAsDate; + //var stop_timestamp = document.getElementById('stop-date').valueAsDate; + + var start_timestamp = new Date(1553731200000); + var stop_timestamp = new Date(1554508800000); + //generate and send subscribe string for (const [set,fields] of subbed.entries()){ var s = "/select_uncompressed " - +start_timestamp+" " - +stop_timestamp+" " + +start_timestamp.getTime()+" " + +stop_timestamp.getTime()+" " +set+" "; for (var i = 0; i < fields.length; i++ ) { @@ -68,7 +104,7 @@ function onOpen(evt){ } websocket.onmessage = function(evt) { gotMeta(evt) }; - doSend("/meta"); + doSend("/meta 1000"); //1000 is max numb of lines, paramater is optional } function gotMeta(evt){ @@ -76,39 +112,48 @@ function gotMeta(evt){ var id_info; var sets_meta = JSON.parse(evt.data);//add package info (total data size, package size) - console.log(sets_meta); + //console.log(sets_meta); //for every dataset - for (var set_idx=0; set_idx < sets_meta.length; set_idx+=1){ - ({field_ids, traces_meta, numb_of_lines, set_id} = sets_meta[set_idx]); + for (var i=0; i < sets_meta.length; i+=1){ + ({field_ids, traces_meta, n_lines, dataset_id} = sets_meta[i]); + + //console.log("sets_meta"); + //console.log(sets_meta[i]); + var old_len = lines.length; var field_list = []; //append all the metadata to the lines - console.log("lines before"); - console.log(lines); - console.log("traces_meta"); - console.log(traces_meta); + //console.log("lines before"); + //console.log(lines); + //console.log("traces_meta"); + //console.log(traces_meta); lines = lines.concat(traces_meta); - console.log("lines"); - console.log(lines); + //console.log("lines"); + //console.log(lines); //create an x-array for all a dataset - var shared_x = new Float64Array(numb_of_lines); - var len = lines.length; + var shared_x = new Float64Array(n_lines); for (var i= 0; i x*1000); //from seconds to milliseconds //no need to set for all x-axises as they are linked //memcpy equivalent of memcpy(trace+pos, timestamps, len(timestamps)); trace_numb = fields_to_lines[0].trace_numb; - console.log("fields to lines[0]"); - console.log(fields_to_lines[0]); - console.log("fields to lines"); - console.log(fields_to_lines); - console.log("lines"); - console.log(lines); + //console.log("fields to lines[0]"); console.log(fields_to_lines[0]); + //console.log("fields to lines"); console.log(fields_to_lines); + //console.log("lines"); console.log(lines); + //console.log("trace_numb"); console.log(trace_numb); // Copy the new timestamps into the array starting at index pos - //console.log(lines); - lines[trace_numb].x = lines[trace_numb].x.set(timestamps, pos); - //console.log("timestamps"); - //console.log(timestamps); + //console.log("timestamps"); console.log(timestamps); + lines[trace_numb].x.set(timestamps, pos); + //console.log("lines"); console.log(lines); } function setData(data, numb_of_elements, fields_to_lines, pos){ var nTraces_in_set = fields_to_lines.length; var data = new Float32Array(data, 8+numb_of_elements*8, numb_of_elements); + //console.log("data:"); console.log(data); + //console.log("pos"); console.log(pos); + for (var i=0; i < numb_of_elements; i+=1){ for (var j=0; j < nTraces_in_set; j++){ var trace_numb = fields_to_lines[j].trace_numb; lines[trace_numb].y[pos+i] = data[i+j]; + //console.log("trace_numb"); console.log(trace_numb); + //console.log("pos+i"); console.log(pos+i); } } } //allocate data for all chunks function gotDataChunk(evt){ //FIXME only works for one dataset - console.log("evt"); - console.log(evt); + //console.log("evt"); + //console.log(evt); var data = new DataView(evt.data); //check for server signal that all data has been recieved, or an error has //occured - if (data.getInt16(3, true) == 1) { + var chunknumb = data.getInt16(0, true); + console.log("chunknumb: "); console.log(chunknumb); + console.log("data: "); console.log(data); + console.log("lines: "); console.log(lines); + if (chunknumb == 0) { //check if this was the last package (package numb=0) //console.log("got last data chunk, creating plot"); + console.log("lines"); console.log(lines); Plotly.newPlot("plot", lines, layout, {responsive: true}); websocket.onmessage = function(evt) { gotUpdate(evt) }; doSend("/sub"); return; }; - var chunknumb = data.getInt16(0, true); var setid = data.getInt16(2, true); - var fields_to_lines = id_map.get(setid); + var [fields_to_lines, pos] = id_map.get(setid); + //console.log("fields_to_lines:"); console.log(fields_to_lines); + //console.log("id_map:"); console.log(id_map); + //console.log("setid:"); console.log(setid); + var numb_of_elements = (evt.data.byteLength-8)/(4*(fields_to_lines.length)+8); - console.log("numb_of_elements"); - console.log(numb_of_elements); - console.log(evt.data.byteLength); - console.log("evt.data"); - console.log(evt.data); - console.log(fields_to_lines.length); + //console.log("numb_of_elements"); console.log(numb_of_elements); + //console.log("evt.data"); console.log(evt.data); + //console.log(fields_to_lines.length); //FIXME NEEDS TO MOVE TO META DATA, NO TIME TO PRE ALLOC CURRENTLY //next package arrives and is handled before this is done @@ -181,13 +234,16 @@ function gotDataChunk(evt){ //FIXME only works for one dataset //--determine pos not from last (vector/write style) but chunknumber and known chunk sizes //--add check if allocation is finished before continueing (use global bool flag for this) - var pos = chunknumb*package_size; - //console.log("numb of elements"); - //console.log(numb_of_elements); + //console.log("numb_of_elements"); console.log(numb_of_elements); + //console.log("package_size"); console.log(package_size); + + console.log("pos"); console.log(pos); setTimestamps(evt.data, numb_of_elements, fields_to_lines, pos); - debugger; setData(evt.data, numb_of_elements, fields_to_lines, pos); - debugger; + pos += numb_of_elements; + + id_map.set(setid, [fields_to_lines, pos]); + //console.log("lines"); console.log(lines); } function gotUpdate(evt){ @@ -197,7 +253,7 @@ function gotUpdate(evt){ //console.log(setid); //console.log(id_map); - var fields_to_lines = id_map.get(setid); + var fields_to_lines = id_map.get(setid)[0]; //TODO rethink metadata ordening (use nested list) var x_update = []; @@ -206,12 +262,15 @@ function gotUpdate(evt){ //console.log(setid); //console.log(id_map); var len = fields_to_lines.length; - for (var i=0; i < len; i++) { + for (var i=0; i < len; i++) {// for all traces make an update var trace_numb = fields_to_lines[i].trace_numb; updated_traces.push(trace_numb); - x_update.push([new Date(timestamp*1000)]); - y_update.push([data.getFloat32(4*i+10, true)]); + x_update.push(new Float64Array([timestamp*1000])); + y_update.push(new Float32Array([data.getFloat32(4*i+10, true)])); } + console.log(x_update); + console.log(y_update); + console.log(lines); Plotly.extendTraces("plot", {x: x_update, y: y_update}, updated_traces); writeToScreen("Got Update"); @@ -243,5 +302,3 @@ function writeToScreen(message){ pre.innerHTML = message; output.appendChild(pre); } - -//window.addEventListener("load", init, false); diff --git a/web/plot_debug.js b/crates/brain/web/plot_debug.js old mode 100644 new mode 100755 similarity index 100% rename from web/plot_debug.js rename to crates/brain/web/plot_debug.js diff --git a/crates/brain/web/set_alarm.html b/crates/brain/web/set_alarm.html new file mode 100755 index 00000000..b2ea2404 --- /dev/null +++ b/crates/brain/web/set_alarm.html @@ -0,0 +1,103 @@ + + + + + + + + + + + + + diff --git a/web/test.html b/crates/brain/web/test.html old mode 100644 new mode 100755 similarity index 100% rename from web/test.html rename to crates/brain/web/test.html diff --git a/web/test_decode.html b/crates/brain/web/test_decode.html old mode 100644 new mode 100755 similarity index 100% rename from web/test_decode.html rename to crates/brain/web/test_decode.html diff --git a/web/test_graph_updates.html b/crates/brain/web/test_graph_updates.html old mode 100644 new mode 100755 similarity index 100% rename from web/test_graph_updates.html rename to crates/brain/web/test_graph_updates.html diff --git a/web/test_ws_interface.html b/crates/brain/web/test_ws_interface.html old mode 100644 new mode 100755 similarity index 100% rename from web/test_ws_interface.html rename to crates/brain/web/test_ws_interface.html diff --git a/web/websocket.html b/crates/brain/web/websocket.html old mode 100644 new mode 100755 similarity index 100% rename from web/websocket.html rename to crates/brain/web/websocket.html diff --git a/web/websocket_getData.html b/crates/brain/web/websocket_getData.html old mode 100644 new mode 100755 similarity index 100% rename from web/websocket_getData.html rename to crates/brain/web/websocket_getData.html diff --git a/web/websocket_getData2.html b/crates/brain/web/websocket_getData2.html old mode 100644 new mode 100755 similarity index 100% rename from web/websocket_getData2.html rename to crates/brain/web/websocket_getData2.html diff --git a/crates/data-server/.cargo/config.toml b/crates/data-server/.cargo/config.toml new file mode 100644 index 00000000..1002fed4 --- /dev/null +++ b/crates/data-server/.cargo/config.toml @@ -0,0 +1,2 @@ +[target.aarch64-unknown-linux-musl] +rustflags = ["-Clinker=rust-lld"] diff --git a/crates/data-server/.gitignore b/crates/data-server/.gitignore new file mode 100644 index 00000000..53eaa219 --- /dev/null +++ b/crates/data-server/.gitignore @@ -0,0 +1,2 @@ +/target +**/*.rs.bk diff --git a/crates/data-server/Cargo.lock b/crates/data-server/Cargo.lock new file mode 100644 index 00000000..2ecccfc7 --- /dev/null +++ b/crates/data-server/Cargo.lock @@ -0,0 +1,1639 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 3 + +[[package]] +name = "addr2line" +version = "0.21.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8a30b2e23b9e17a9f90641c7ab1549cd9b44f296d3ccbf309d2863cfe398a0cb" +dependencies = [ + "gimli", +] + +[[package]] +name = "adler" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe" + +[[package]] +name = "aho-corasick" +version = "1.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e60d3430d3a69478ad0993f19238d2df97c507009a52b3c10addcd7f6bcb916" +dependencies = [ + "memchr", +] + +[[package]] +name = "anstream" +version = "0.6.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "418c75fa768af9c03be99d17643f93f79bbba589895012a80e3452a19ddda15b" +dependencies = [ + "anstyle", + "anstyle-parse", + "anstyle-query", + "anstyle-wincon", + "colorchoice", + "is_terminal_polyfill", + "utf8parse", +] + +[[package]] +name = "anstyle" +version = "1.0.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "038dfcf04a5feb68e9c60b21c9625a54c2c0616e79b72b0fd87075a056ae1d1b" + +[[package]] +name = "anstyle-parse" +version = "0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c03a11a9034d92058ceb6ee011ce58af4a9bf61491aa7e1e59ecd24bd40d22d4" +dependencies = [ + "utf8parse", +] + +[[package]] +name = "anstyle-query" +version = "1.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a64c907d4e79225ac72e2a354c9ce84d50ebb4586dee56c82b3ee73004f537f5" +dependencies = [ + "windows-sys 0.52.0", +] + +[[package]] +name = "anstyle-wincon" +version = "3.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "61a38449feb7068f52bb06c12759005cf459ee52bb4adc1d5a7c4322d716fb19" +dependencies = [ + "anstyle", + "windows-sys 0.52.0", +] + +[[package]] +name = "atomic-polyfill" +version = "1.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8cf2bce30dfe09ef0bfaef228b9d414faaf7e563035494d7fe092dba54b300f4" +dependencies = [ + "critical-section", +] + +[[package]] +name = "autocfg" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0c4b4d0bd25bd0b74681c0ad21497610ce1b7c91b1022cd21c80c6fbdd9476b0" + +[[package]] +name = "backtrace" +version = "0.3.71" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "26b05800d2e817c8b3b4b54abd461726265fa9789ae34330622f2db9ee696f9d" +dependencies = [ + "addr2line", + "cc", + "cfg-if", + "libc", + "miniz_oxide", + "object", + "rustc-demangle", +] + +[[package]] +name = "bare-metal" +version = "0.2.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5deb64efa5bd81e31fcd1938615a6d98c82eafcbcd787162b6f63b91d6bac5b3" +dependencies = [ + "rustc_version 0.2.3", +] + +[[package]] +name = "bit_field" +version = "0.10.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dc827186963e592360843fb5ba4b973e145841266c1357f7180c43526f2e5b61" + +[[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 = "bosch-bme680" +version = "1.0.2" +source = "git+https://github.com/dvdsk/async-bosch-bme680#455d5d3194f137d9e0403779badc645e1bad7a05" +dependencies = [ + "bitfield 0.14.0", + "defmt", + "embedded-hal 1.0.0", + "embedded-hal-async", + "postcard", + "serde", + "thiserror", +] + +[[package]] +name = "bxcan" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "40ac3d0c0a542d0ab5521211f873f62706a7136df415676f676d347e5a41dd80" +dependencies = [ + "bitflags", + "embedded-hal 0.2.7", + "nb 1.1.0", + "vcell", +] + +[[package]] +name = "byteorder" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" + +[[package]] +name = "bytes" +version = "1.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "514de17de45fdb8dc022b1a7975556c53c86f9f0aa5f534b98977b171857c2c9" + +[[package]] +name = "cc" +version = "1.0.98" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "41c270e7540d725e65ac7f1b212ac8ce349719624d7bcff99f8e2e488e8cf03f" + +[[package]] +name = "cfg-if" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" + +[[package]] +name = "clap" +version = "4.5.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "90bc066a67923782aa8515dbaea16946c5bcc5addbd668bb80af688e53e548a0" +dependencies = [ + "clap_builder", + "clap_derive", +] + +[[package]] +name = "clap_builder" +version = "4.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ae129e2e766ae0ec03484e609954119f123cc1fe650337e155d03b022f24f7b4" +dependencies = [ + "anstream", + "anstyle", + "clap_lex", + "strsim", +] + +[[package]] +name = "clap_derive" +version = "4.5.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "528131438037fd55894f62d6e9f068b8f45ac57ffa77517819645d10aed04f64" +dependencies = [ + "heck 0.5.0", + "proc-macro2", + "quote", + "syn 2.0.65", +] + +[[package]] +name = "clap_lex" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "98cc8fbded0c607b7ba9dd60cd98df59af97e84d24e49c8557331cfc26d301ce" + +[[package]] +name = "cobs" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "67ba02a97a2bd10f4b59b25c7973101c79642302776489e030cd13cdab09ed15" + +[[package]] +name = "color-eyre" +version = "0.6.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "55146f5e46f237f7423d74111267d4597b59b0dad0ffaf7303bce9945d843ad5" +dependencies = [ + "backtrace", + "color-spantrace", + "eyre", + "indenter", + "once_cell", + "owo-colors", + "tracing-error", +] + +[[package]] +name = "color-spantrace" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cd6be1b2a7e382e2b98b43b2adcca6bb0e465af0bdd38123873ae61eb17a72c2" +dependencies = [ + "once_cell", + "owo-colors", + "tracing-core", + "tracing-error", +] + +[[package]] +name = "colorchoice" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b6a852b24ab71dffc585bcb46eaf7959d175cb865a7152e35b348d1b2960422" + +[[package]] +name = "const_format" +version = "0.2.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e3a214c7af3d04997541b18d432afaff4c455e79e2029079647e72fc2bd27673" +dependencies = [ + "const_format_proc_macros", +] + +[[package]] +name = "const_format_proc_macros" +version = "0.2.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c7f6ff08fd20f4f299298a28e2dfa8a8ba1036e6cd2460ac1de7b425d76f2500" +dependencies = [ + "proc-macro2", + "quote", + "unicode-xid", +] + +[[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.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2722f5b7d6ea8583cffa4d247044e280ccbb9fe501bed56552e2ba48b02d5f3d" +dependencies = [ + "cortex-m-rt-macros", +] + +[[package]] +name = "cortex-m-rt-macros" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f0f6f3e36f203cfedbc78b357fb28730aa2c6dc1ab060ee5c2405e843988d3c7" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "crc" +version = "3.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "69e6e4d7b33a94f0991c26729976b10ebde1d34c3ee82408fb536164fa10d636" +dependencies = [ + "crc-catalog", +] + +[[package]] +name = "crc-catalog" +version = "2.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "19d374276b40fb8bbdee95aef7c7fa6b5316ec764510eb64b8dd0e2ed0d7e7f5" + +[[package]] +name = "critical-section" +version = "1.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7059fff8937831a9ae6f0fe4d658ffabf58f2ca96aa9dec1c889f936f705f216" + +[[package]] +name = "data-server" +version = "0.2.0" +dependencies = [ + "clap", + "color-eyre", + "protocol", + "tokio", + "tokio-stream", + "tracing", + "tracing-error", + "tracing-subscriber", +] + +[[package]] +name = "defmt" +version = "0.3.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a99dd22262668b887121d4672af5a64b238f026099f1a2a1b322066c9ecfe9e0" +dependencies = [ + "bitflags", + "defmt-macros", +] + +[[package]] +name = "defmt-macros" +version = "0.3.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e3a9f309eff1f79b3ebdf252954d90ae440599c26c2c553fe87a2d17195f2dcb" +dependencies = [ + "defmt-parser", + "proc-macro-error", + "proc-macro2", + "quote", + "syn 2.0.65", +] + +[[package]] +name = "defmt-parser" +version = "0.3.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ff4a5fefe330e8d7f31b16a318f9ce81000d8e35e69b93eae154d16d2278f70f" +dependencies = [ + "thiserror", +] + +[[package]] +name = "document-features" +version = "0.2.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ef5282ad69563b5fc40319526ba27e0e7363d552a896f0297d54f767717f9b95" +dependencies = [ + "litrs", +] + +[[package]] +name = "embassy-embedded-hal" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eca4a9380d03e61063067b8239f67d2fa9f108ede7c46b4273804f6b79e59a1d" +dependencies = [ + "embassy-futures", + "embassy-sync", + "embassy-time", + "embedded-hal 0.2.7", + "embedded-hal 1.0.0", + "embedded-hal-async", + "embedded-storage", + "embedded-storage-async", + "nb 1.1.0", +] + +[[package]] +name = "embassy-futures" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1f878075b9794c1e4ac788c95b728f26aa6366d32eeb10c7051389f898f7d067" + +[[package]] +name = "embassy-hal-internal" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a0ec47cf8bab914018d4bd2b4f0aaeb46e4f52ab1e7985df88aeef2c6eda5aed" +dependencies = [ + "cortex-m", + "critical-section", + "num-traits", +] + +[[package]] +name = "embassy-net-driver" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "524eb3c489760508f71360112bca70f6e53173e6fe48fc5f0efd0f5ab217751d" + +[[package]] +name = "embassy-stm32" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "32bc0257b5ade13a1b93e8b9949268f44d57e8ce03e599ef1c5a62024a0fbff9" +dependencies = [ + "bit_field", + "bxcan", + "cfg-if", + "cortex-m", + "cortex-m-rt", + "critical-section", + "document-features", + "embassy-embedded-hal", + "embassy-futures", + "embassy-hal-internal", + "embassy-net-driver", + "embassy-sync", + "embassy-usb-driver", + "embedded-hal 0.2.7", + "embedded-hal 1.0.0", + "embedded-hal-async", + "embedded-hal-nb", + "embedded-io 0.6.1", + "embedded-io-async", + "embedded-storage", + "embedded-storage-async", + "futures", + "nb 1.1.0", + "proc-macro2", + "quote", + "rand_core", + "sdio-host", + "stm32-fmc", + "stm32-metapac", + "vcell", +] + +[[package]] +name = "embassy-sync" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dd938f25c0798db4280fcd8026bf4c2f48789aebf8f77b6e5cf8a7693ba114ec" +dependencies = [ + "cfg-if", + "critical-section", + "embedded-io-async", + "futures-util", + "heapless 0.8.0", +] + +[[package]] +name = "embassy-time" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a9c844070d9f80dc66ee739299183312baee2e1cdeb6e90b4ea2af44f4676da5" +dependencies = [ + "cfg-if", + "critical-section", + "document-features", + "embassy-time-driver", + "embassy-time-queue-driver", + "embedded-hal 0.2.7", + "embedded-hal 1.0.0", + "embedded-hal-async", + "futures-util", + "heapless 0.8.0", +] + +[[package]] +name = "embassy-time-driver" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6e0c214077aaa9206958b16411c157961fb7990d4ea628120a78d1a5a28aed24" +dependencies = [ + "document-features", +] + +[[package]] +name = "embassy-time-queue-driver" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f1177859559ebf42cd24ae7ba8fe6ee707489b01d0bf471f8827b7b12dcb0bc0" + +[[package]] +name = "embassy-usb-driver" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4fc247028eae04174b6635104a35b1ed336aabef4654f5e87a8f32327d231970" + +[[package]] +name = "embedded-hal" +version = "0.2.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "35949884794ad573cf46071e41c9b60efb0cb311e3ca01f7af807af1debc66ff" +dependencies = [ + "nb 0.1.3", + "void", +] + +[[package]] +name = "embedded-hal" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "361a90feb7004eca4019fb28352a9465666b24f840f5c3cddf0ff13920590b89" +dependencies = [ + "defmt", +] + +[[package]] +name = "embedded-hal-async" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0c4c685bbef7fe13c3c6dd4da26841ed3980ef33e841cddfa15ce8a8fb3f1884" +dependencies = [ + "defmt", + "embedded-hal 1.0.0", +] + +[[package]] +name = "embedded-hal-nb" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fba4268c14288c828995299e59b12babdbe170f6c6d73731af1b4648142e8605" +dependencies = [ + "embedded-hal 1.0.0", + "nb 1.1.0", +] + +[[package]] +name = "embedded-io" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ef1a6892d9eef45c8fa6b9e0086428a2cca8491aca8f787c534a3d6d0bcb3ced" + +[[package]] +name = "embedded-io" +version = "0.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "edd0f118536f44f5ccd48bcb8b111bdc3de888b58c74639dfb034a357d0f206d" +dependencies = [ + "defmt", +] + +[[package]] +name = "embedded-io-async" +version = "0.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3ff09972d4073aa8c299395be75161d582e7629cd663171d62af73c8d50dba3f" +dependencies = [ + "defmt", + "embedded-io 0.6.1", +] + +[[package]] +name = "embedded-storage" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a21dea9854beb860f3062d10228ce9b976da520a73474aed3171ec276bc0c032" + +[[package]] +name = "embedded-storage-async" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1763775e2323b7d5f0aa6090657f5e21cfa02ede71f5dc40eead06d64dcd15cc" +dependencies = [ + "embedded-storage", +] + +[[package]] +name = "eyre" +version = "0.6.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7cd915d99f24784cdc19fd37ef22b97e3ff0ae756c7e492e9fbfe897d61e2aec" +dependencies = [ + "indenter", + "once_cell", +] + +[[package]] +name = "futures" +version = "0.3.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "645c6916888f6cb6350d2550b80fb63e734897a8498abe35cfb732b6487804b0" +dependencies = [ + "futures-channel", + "futures-core", + "futures-io", + "futures-sink", + "futures-task", + "futures-util", +] + +[[package]] +name = "futures-channel" +version = "0.3.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eac8f7d7865dcb88bd4373ab671c8cf4508703796caa2b1985a9ca867b3fcb78" +dependencies = [ + "futures-core", + "futures-sink", +] + +[[package]] +name = "futures-core" +version = "0.3.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dfc6580bb841c5a68e9ef15c77ccc837b40a7504914d52e47b8b0e9bbda25a1d" + +[[package]] +name = "futures-io" +version = "0.3.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a44623e20b9681a318efdd71c299b6b222ed6f231972bfe2f224ebad6311f0c1" + +[[package]] +name = "futures-macro" +version = "0.3.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "87750cf4b7a4c0625b1529e4c543c2182106e4dedc60a2a6455e00d212c489ac" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.65", +] + +[[package]] +name = "futures-sink" +version = "0.3.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9fb8e00e87438d937621c1c6269e53f536c14d3fbd6a042bb24879e57d474fb5" + +[[package]] +name = "futures-task" +version = "0.3.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "38d84fa142264698cdce1a9f9172cf383a0c82de1bddcf3092901442c4097004" + +[[package]] +name = "futures-util" +version = "0.3.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3d6401deb83407ab3da39eba7e33987a73c3df0c82b4bb5813ee871c19c41d48" +dependencies = [ + "futures-core", + "futures-macro", + "futures-sink", + "futures-task", + "pin-project-lite", + "pin-utils", +] + +[[package]] +name = "gimli" +version = "0.28.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4271d37baee1b8c7e4b708028c57d816cf9d2434acb33a549475f78c181f6253" + +[[package]] +name = "hash32" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b0c35f58762feb77d74ebe43bdbc3210f09be9fe6742234d573bacc26ed92b67" +dependencies = [ + "byteorder", +] + +[[package]] +name = "hash32" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "47d60b12902ba28e2730cd37e95b8c9223af2808df9e902d4df49588d1470606" +dependencies = [ + "byteorder", +] + +[[package]] +name = "heapless" +version = "0.7.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cdc6457c0eb62c71aac4bc17216026d8410337c4126773b9c5daba343f17964f" +dependencies = [ + "atomic-polyfill", + "hash32 0.2.1", + "rustc_version 0.4.0", + "serde", + "spin", + "stable_deref_trait", +] + +[[package]] +name = "heapless" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0bfb9eb618601c89945a70e254898da93b13be0388091d42117462b265bb3fad" +dependencies = [ + "hash32 0.3.1", + "serde", + "stable_deref_trait", +] + +[[package]] +name = "heck" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "95505c38b4572b2d910cecb0281560f54b440a19336cbbcb27bf6ce6adc6f5a8" + +[[package]] +name = "heck" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea" + +[[package]] +name = "indenter" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ce23b50ad8242c51a442f3ff322d56b02f08852c77e4c0b4d3fd684abc89c683" + +[[package]] +name = "is_terminal_polyfill" +version = "1.70.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f8478577c03552c21db0e2724ffb8986a5ce7af88107e6be5d2ee6e158c12800" + +[[package]] +name = "lazy_static" +version = "1.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" + +[[package]] +name = "libc" +version = "0.2.155" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "97b3888a4aecf77e811145cadf6eef5901f4782c53886191b2f693f24761847c" + +[[package]] +name = "litrs" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b4ce301924b7887e9d637144fdade93f9dfff9b60981d4ac161db09720d39aa5" + +[[package]] +name = "lock_api" +version = "0.4.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "07af8b9cdd281b7915f413fa73f29ebd5d55d0d3f0155584dade1ff18cea1b17" +dependencies = [ + "autocfg", + "scopeguard", +] + +[[package]] +name = "log" +version = "0.4.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "90ed8c1e510134f979dbc4f070f87d4313098b704861a105fe34231c70a3901c" + +[[package]] +name = "matchers" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8263075bb86c5a1b1427b5ae862e8889656f126e9f77c484496e8b47cf5c5558" +dependencies = [ + "regex-automata 0.1.10", +] + +[[package]] +name = "max44009" +version = "0.2.0" +source = "git+https://github.com/dvdsk/max44009-rs#7b7df2e3173476c250fca3eb242f0dd366857599" +dependencies = [ + "defmt", + "embedded-hal-async", + "postcard", + "serde", + "thiserror", +] + +[[package]] +name = "memchr" +version = "2.7.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6c8640c5d730cb13ebd907d8d04b52f55ac9a2eec55b440c8892f40d56c76c1d" + +[[package]] +name = "mhzx" +version = "0.3.0" +source = "git+https://github.com/dvdsk/mhzx#08f6e7adb4ec98749fa84f24f8ff9e0e3c83d164" +dependencies = [ + "defmt", + "embedded-io-async", + "heapless 0.8.0", + "postcard", + "serde", + "thiserror", +] + +[[package]] +name = "miniz_oxide" +version = "0.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "87dfd01fe195c66b572b37921ad8803d010623c0aca821bea2302239d155cdae" +dependencies = [ + "adler", +] + +[[package]] +name = "mio" +version = "0.8.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a4a650543ca06a924e8b371db273b2756685faae30f8487da1b56505a8f78b0c" +dependencies = [ + "libc", + "wasi", + "windows-sys 0.48.0", +] + +[[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 = "nu-ansi-term" +version = "0.46.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "77a8165726e8236064dbb45459242600304b42a5ea24ee2948e18e023bf7ba84" +dependencies = [ + "overload", + "winapi", +] + +[[package]] +name = "num-traits" +version = "0.2.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841" +dependencies = [ + "autocfg", +] + +[[package]] +name = "object" +version = "0.32.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a6a622008b6e321afc04970976f62ee297fdbaa6f95318ca343e3eebb9648441" +dependencies = [ + "memchr", +] + +[[package]] +name = "once_cell" +version = "1.19.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3fdb12b2476b595f9358c5161aa467c2438859caa136dec86c26fdd2efe17b92" + +[[package]] +name = "overload" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b15813163c1d831bf4a13c3610c05c0d03b39feb07f7e09fa234dac9b15aaf39" + +[[package]] +name = "owo-colors" +version = "3.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c1b04fb49957986fdce4d6ee7a65027d55d4b6d2265e5848bbb507b58ccfdb6f" + +[[package]] +name = "pin-project-lite" +version = "0.2.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bda66fc9667c18cb2758a2ac84d1167245054bcf85d5d1aaa6923f45801bdd02" + +[[package]] +name = "pin-utils" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" + +[[package]] +name = "postcard" +version = "1.0.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a55c51ee6c0db07e68448e336cf8ea4131a620edefebf9893e759b2d793420f8" +dependencies = [ + "cobs", + "const_format", + "embedded-io 0.4.0", + "heapless 0.7.17", + "postcard-derive", + "serde", +] + +[[package]] +name = "postcard-derive" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fc4b01218787dd4420daf63875163a787a78294ad48a24e9f6fa8c6507759a79" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "proc-macro-error" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "da25490ff9892aab3fcf7c36f08cfb902dd3e71ca0f9f9517bea02a73a5ce38c" +dependencies = [ + "proc-macro-error-attr", + "proc-macro2", + "quote", + "syn 1.0.109", + "version_check", +] + +[[package]] +name = "proc-macro-error-attr" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a1be40180e52ecc98ad80b184934baf3d0d29f979574e439af5a55274b35f869" +dependencies = [ + "proc-macro2", + "quote", + "version_check", +] + +[[package]] +name = "proc-macro2" +version = "1.0.83" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b33eb56c327dec362a9e55b3ad14f9d2f0904fb5a5b03b513ab5465399e9f43" +dependencies = [ + "unicode-ident", +] + +[[package]] +name = "protocol" +version = "0.1.0" +dependencies = [ + "bosch-bme680", + "defmt", + "embassy-embedded-hal", + "embassy-stm32", + "heapless 0.8.0", + "max44009", + "mhzx", + "postcard", + "serde", + "sht31", + "sps30-async", + "strum", +] + +[[package]] +name = "quote" +version = "1.0.36" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0fa76aaf39101c457836aec0ce2316dbdc3ab723cdda1c6bd4e6ad4208acaca7" +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 = "regex" +version = "1.10.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c117dbdfde9c8308975b6a18d71f3f385c89461f7b3fb054288ecf2a2058ba4c" +dependencies = [ + "aho-corasick", + "memchr", + "regex-automata 0.4.6", + "regex-syntax 0.8.3", +] + +[[package]] +name = "regex-automata" +version = "0.1.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6c230d73fb8d8c1b9c0b3135c5142a8acee3a0558fb8db5cf1cb65f8d7862132" +dependencies = [ + "regex-syntax 0.6.29", +] + +[[package]] +name = "regex-automata" +version = "0.4.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "86b83b8b9847f9bf95ef68afb0b8e6cdb80f498442f5179a29fad448fcc1eaea" +dependencies = [ + "aho-corasick", + "memchr", + "regex-syntax 0.8.3", +] + +[[package]] +name = "regex-syntax" +version = "0.6.29" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f162c6dd7b008981e4d40210aca20b4bd0f9b60ca9271061b07f78537722f2e1" + +[[package]] +name = "regex-syntax" +version = "0.8.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "adad44e29e4c806119491a7f06f03de4d1af22c3a680dd47f1e6e179439d1f56" + +[[package]] +name = "rustc-demangle" +version = "0.1.24" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "719b953e2095829ee67db738b3bfa9fa368c94900df327b3f07fe6e794d2fe1f" + +[[package]] +name = "rustc_version" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "138e3e0acb6c9fb258b19b67cb8abd63c00679d2851805ea151465464fe9030a" +dependencies = [ + "semver 0.9.0", +] + +[[package]] +name = "rustc_version" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bfa0f585226d2e68097d4f95d113b15b83a82e819ab25717ec0590d9584ef366" +dependencies = [ + "semver 1.0.23", +] + +[[package]] +name = "rustversion" +version = "1.0.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "955d28af4278de8121b7ebeb796b6a45735dc01436d898801014aced2773a3d6" + +[[package]] +name = "scopeguard" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" + +[[package]] +name = "sdio-host" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f93c025f9cfe4c388c328ece47d11a54a823da3b5ad0370b22d95ad47137f85a" + +[[package]] +name = "semver" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1d7eb9ef2c18661902cc47e535f9bc51b78acd254da71d375c2f6720d9a40403" +dependencies = [ + "semver-parser", +] + +[[package]] +name = "semver" +version = "1.0.23" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "61697e0a1c7e512e84a621326239844a24d8207b4669b41bc18b32ea5cbf988b" + +[[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.202" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "226b61a0d411b2ba5ff6d7f73a476ac4f8bb900373459cd00fab8512828ba395" +dependencies = [ + "serde_derive", +] + +[[package]] +name = "serde_derive" +version = "1.0.202" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6048858004bcff69094cd972ed40a32500f153bd3be9f716b2eed2e8217c4838" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.65", +] + +[[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 = "sht31" +version = "0.3.1" +source = "git+https://github.com/dvdsk/SHT31-rs#a7b6bd94fb137e16bf326eff5fb591624369a2cf" +dependencies = [ + "crc", + "defmt", + "embedded-hal-async", + "postcard", + "serde", + "thiserror", +] + +[[package]] +name = "smallvec" +version = "1.13.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3c5e1a9a646d36c3599cd173a41282daf47c44583ad367b8e6837255952e5c67" + +[[package]] +name = "socket2" +version = "0.5.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ce305eb0b4296696835b71df73eb912e0f1ffd2556a501fcede6e0c50349191c" +dependencies = [ + "libc", + "windows-sys 0.52.0", +] + +[[package]] +name = "spin" +version = "0.9.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6980e8d7511241f8acf4aebddbb1ff938df5eebe98691418c4468d0b72a96a67" +dependencies = [ + "lock_api", +] + +[[package]] +name = "sps30-async" +version = "0.2.0" +source = "git+https://github.com/dvdsk/sps30-async#a5e81ec034727442c048acea2e8eb07fe4be78e4" +dependencies = [ + "defmt", + "embedded-hal-async", + "embedded-io-async", + "heapless 0.8.0", + "postcard", + "serde", + "thiserror", +] + +[[package]] +name = "stable_deref_trait" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a8f112729512f8e442d81f95a8a7ddf2b7c6b8a1a6f509a95864142b30cab2d3" + +[[package]] +name = "stm32-fmc" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "830ed60f33e6194ecb377f5d6ab765dc0e37e7b65e765f1fa87df13336658d63" +dependencies = [ + "embedded-hal 0.2.7", +] + +[[package]] +name = "stm32-metapac" +version = "15.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "deabea56a8821dcea05d0109f3ab3135f31eb572444e5da203d06149c594c8c6" +dependencies = [ + "cortex-m", + "cortex-m-rt", +] + +[[package]] +name = "strsim" +version = "0.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f" + +[[package]] +name = "strum" +version = "0.26.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5d8cec3501a5194c432b2b7976db6b7d10ec95c253208b45f83f7136aa985e29" +dependencies = [ + "strum_macros", +] + +[[package]] +name = "strum_macros" +version = "0.26.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c6cf59daf282c0a494ba14fd21610a0325f9f90ec9d1231dea26bcb1d696c946" +dependencies = [ + "heck 0.4.1", + "proc-macro2", + "quote", + "rustversion", + "syn 2.0.65", +] + +[[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.65" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d2863d96a84c6439701d7a38f9de935ec562c8832cc55d1dde0f513b52fad106" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[package]] +name = "thiserror" +version = "1.0.61" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c546c80d6be4bc6a00c0f01730c08df82eaa7a7a61f11d656526506112cc1709" +dependencies = [ + "thiserror-impl", +] + +[[package]] +name = "thiserror-impl" +version = "1.0.61" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "46c3384250002a6d5af4d114f2845d37b57521033f30d5c3f46c4d70e1197533" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.65", +] + +[[package]] +name = "thread_local" +version = "1.1.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8b9ef9bad013ada3808854ceac7b46812a6465ba368859a37e2100283d2d719c" +dependencies = [ + "cfg-if", + "once_cell", +] + +[[package]] +name = "tokio" +version = "1.37.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1adbebffeca75fcfd058afa480fb6c0b81e165a0323f9c9d39c9697e37c46787" +dependencies = [ + "backtrace", + "bytes", + "libc", + "mio", + "pin-project-lite", + "socket2", + "tokio-macros", + "windows-sys 0.48.0", +] + +[[package]] +name = "tokio-macros" +version = "2.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5b8a1e28f2deaa14e508979454cb3a223b10b938b45af148bc0986de36f1923b" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.65", +] + +[[package]] +name = "tokio-stream" +version = "0.1.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "267ac89e0bec6e691e5813911606935d77c476ff49024f98abcea3e7b15e37af" +dependencies = [ + "futures-core", + "pin-project-lite", + "tokio", +] + +[[package]] +name = "tracing" +version = "0.1.40" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c3523ab5a71916ccf420eebdf5521fcef02141234bbc0b8a49f2fdc4544364ef" +dependencies = [ + "pin-project-lite", + "tracing-attributes", + "tracing-core", +] + +[[package]] +name = "tracing-attributes" +version = "0.1.27" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "34704c8d6ebcbc939824180af020566b01a7c01f80641264eba0999f6c2b6be7" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.65", +] + +[[package]] +name = "tracing-core" +version = "0.1.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c06d3da6113f116aaee68e4d601191614c9053067f9ab7f6edbcb161237daa54" +dependencies = [ + "once_cell", + "valuable", +] + +[[package]] +name = "tracing-error" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d686ec1c0f384b1277f097b2f279a2ecc11afe8c133c1aabf036a27cb4cd206e" +dependencies = [ + "tracing", + "tracing-subscriber", +] + +[[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.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ad0f048c97dbd9faa9b7df56362b8ebcaa52adb06b498c050d2f4e32f90a7a8b" +dependencies = [ + "matchers", + "nu-ansi-term", + "once_cell", + "regex", + "sharded-slab", + "smallvec", + "thread_local", + "tracing", + "tracing-core", + "tracing-log", +] + +[[package]] +name = "unicode-ident" +version = "1.0.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" + +[[package]] +name = "unicode-xid" +version = "0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f962df74c8c05a667b5ee8bcf162993134c104e96440b663c8daa176dc772d8c" + +[[package]] +name = "utf8parse" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "711b9620af191e0cdc7468a8d14e709c3dcdb115b36f838e601583af800a370a" + +[[package]] +name = "valuable" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "830b7e5d4d90034032940e4ace0d9a9a057e7a45cd94e6c007832e39edb82f6d" + +[[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.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" + +[[package]] +name = "void" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6a02e4885ed3bc0f2de90ea6dd45ebcbb66dacffe03547fadbb0eeae2770887d" + +[[package]] +name = "volatile-register" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "de437e2a6208b014ab52972a27e59b33fa2920d3e00fe05026167a1c509d19cc" +dependencies = [ + "vcell", +] + +[[package]] +name = "wasi" +version = "0.11.0+wasi-snapshot-preview1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" + +[[package]] +name = "winapi" +version = "0.3.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419" +dependencies = [ + "winapi-i686-pc-windows-gnu", + "winapi-x86_64-pc-windows-gnu", +] + +[[package]] +name = "winapi-i686-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" + +[[package]] +name = "winapi-x86_64-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" + +[[package]] +name = "windows-sys" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "677d2418bec65e3338edb076e806bc1ec15693c5d0104683f2efe857f61056a9" +dependencies = [ + "windows-targets 0.48.5", +] + +[[package]] +name = "windows-sys" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d" +dependencies = [ + "windows-targets 0.52.5", +] + +[[package]] +name = "windows-targets" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9a2fa6e2155d7247be68c096456083145c183cbbbc2764150dda45a87197940c" +dependencies = [ + "windows_aarch64_gnullvm 0.48.5", + "windows_aarch64_msvc 0.48.5", + "windows_i686_gnu 0.48.5", + "windows_i686_msvc 0.48.5", + "windows_x86_64_gnu 0.48.5", + "windows_x86_64_gnullvm 0.48.5", + "windows_x86_64_msvc 0.48.5", +] + +[[package]] +name = "windows-targets" +version = "0.52.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6f0713a46559409d202e70e28227288446bf7841d3211583a4b53e3f6d96e7eb" +dependencies = [ + "windows_aarch64_gnullvm 0.52.5", + "windows_aarch64_msvc 0.52.5", + "windows_i686_gnu 0.52.5", + "windows_i686_gnullvm", + "windows_i686_msvc 0.52.5", + "windows_x86_64_gnu 0.52.5", + "windows_x86_64_gnullvm 0.52.5", + "windows_x86_64_msvc 0.52.5", +] + +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8" + +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.52.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7088eed71e8b8dda258ecc8bac5fb1153c5cffaf2578fc8ff5d61e23578d3263" + +[[package]] +name = "windows_aarch64_msvc" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc" + +[[package]] +name = "windows_aarch64_msvc" +version = "0.52.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9985fd1504e250c615ca5f281c3f7a6da76213ebd5ccc9561496568a2752afb6" + +[[package]] +name = "windows_i686_gnu" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743e" + +[[package]] +name = "windows_i686_gnu" +version = "0.52.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "88ba073cf16d5372720ec942a8ccbf61626074c6d4dd2e745299726ce8b89670" + +[[package]] +name = "windows_i686_gnullvm" +version = "0.52.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "87f4261229030a858f36b459e748ae97545d6f1ec60e5e0d6a3d32e0dc232ee9" + +[[package]] +name = "windows_i686_msvc" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406" + +[[package]] +name = "windows_i686_msvc" +version = "0.52.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "db3c2bf3d13d5b658be73463284eaf12830ac9a26a90c717b7f771dfe97487bf" + +[[package]] +name = "windows_x86_64_gnu" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "53d40abd2583d23e4718fddf1ebec84dbff8381c07cae67ff7768bbf19c6718e" + +[[package]] +name = "windows_x86_64_gnu" +version = "0.52.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4e4246f76bdeff09eb48875a0fd3e2af6aada79d409d33011886d3e1581517d9" + +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc" + +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.52.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "852298e482cd67c356ddd9570386e2862b5673c85bd5f88df9ab6802b334c596" + +[[package]] +name = "windows_x86_64_msvc" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538" + +[[package]] +name = "windows_x86_64_msvc" +version = "0.52.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bec47e5bfd1bff0eeaf6d8b485cc1074891a197ab4225d504cb7a1ab88b02bf0" diff --git a/crates/data-server/Cargo.toml b/crates/data-server/Cargo.toml new file mode 100644 index 00000000..2913a704 --- /dev/null +++ b/crates/data-server/Cargo.toml @@ -0,0 +1,36 @@ +[package] +name = "data-server" +edition.workspace = true +license.workspace = true +authors.workspace = true + +[features] +api = [] +server = [] +default = ["api", "server"] + +[dependencies] +clap = { workspace = true } +color-eyre = { workspace = true } +tracing = { workspace = true } +tracing-error = { workspace = true } +tracing-subscriber = { workspace = true, features = ["env-filter"] } +logger = { workspace = true } +rpc = { workspace = true } + +protocol = { workspace = true, features = ["alloc", "thiserror"] } +tokio = { workspace = true, features = ["rt", "macros", "net", "sync", "io-util"] } +thiserror.workspace = true +futures.workspace = true +tokio-serde = { version = "0.9.0", features = ["bincode"] } +tokio-util = { workspace = true, features = ["time"] } +serde.workspace = true +futures-concurrency = { workspace = true } +slotmap = "1.0.7" +tracing-futures = "0.2.5" +socket2 = { version = "0.6.0", features = ["all"] } +governor.workspace = true +tokio-utils = "0.1.2" + +[dev-dependencies] +reserve-port = "2" diff --git a/crates/data-server/deploy.sh b/crates/data-server/deploy.sh new file mode 100755 index 00000000..3b255fd2 --- /dev/null +++ b/crates/data-server/deploy.sh @@ -0,0 +1,18 @@ +#!/usr/bin/env bash +set -e + +BUILD_ARG=--release +SERVER="sgc" # ssh config name or full address +NAME=data-server + +cargo build --target=aarch64-unknown-linux-musl $BUILD_ARG +rsync -vh --progress \ + ../../target/aarch64-unknown-linux-musl/release/$NAME \ + $SERVER:/tmp/ + +cmds=" +sudo mv /tmp/$NAME /home/ha/$NAME +sudo chown ha:ha /home/ha/$NAME +sudo systemctl restart $NAME.service +" +ssh -t $SERVER "$cmds" diff --git a/crates/data-server/rust-toolchain.toml b/crates/data-server/rust-toolchain.toml new file mode 100644 index 00000000..6e888d40 --- /dev/null +++ b/crates/data-server/rust-toolchain.toml @@ -0,0 +1,5 @@ +[toolchain] +channel = "stable" +components = [] +targets = [ "aarch64-unknown-linux-musl" ] +profile = "minimal" diff --git a/crates/data-server/src/api.rs b/crates/data-server/src/api.rs new file mode 100644 index 00000000..42a6d58e --- /dev/null +++ b/crates/data-server/src/api.rs @@ -0,0 +1,2 @@ +pub mod data_source; +pub mod subscriber; diff --git a/crates/data-server/src/api/data_source.rs b/crates/data-server/src/api/data_source.rs new file mode 100644 index 00000000..e7c2e5d9 --- /dev/null +++ b/crates/data-server/src/api/data_source.rs @@ -0,0 +1,147 @@ +use protocol::{affector, DecodeMsgError}; +use reconnecting::SendError; +use tokio::io::{AsyncReadExt, AsyncWriteExt}; +use tokio::net::tcp::{OwnedReadHalf, OwnedWriteHalf}; +use tokio::net::{TcpStream, ToSocketAddrs}; + +pub mod reconnecting; + +#[derive(Debug, thiserror::Error)] +pub enum Error { + #[error("Could not connect to data-server")] + Connecting(#[source] std::io::Error), + #[error("Could not send handshake to data-server")] + Handshake(#[source] std::io::Error), + #[error("Too many affectors, max: {max}, requires: {requires}")] + TooManyAffectors { max: usize, requires: usize }, +} + +pub struct Client { + pub sender: Sender, + pub receiver: Receiver, +} + +impl Client { + /// Needs a list of the affectors that can be controlled through this + /// node as an argument. If your node provides not controllable affectors + /// pass in an empty Vec. + pub async fn connect( + addr: impl ToSocketAddrs, + affectors: Vec, + ) -> Result { + let mut stream = TcpStream::connect(addr).await.map_err(Error::Connecting)?; + let mut list = protocol::affector::ListMessage::<50>::empty(); + + if affectors.len() > list.values.capacity() { + return Err(Error::TooManyAffectors { + max: list.values.capacity(), + requires: affectors.len(), + }); + } + for affector in affectors { + list.values.push(affector).expect("Is checked right above"); + } + let handshake = protocol::Msg::AffectorList(list); + let handshake = handshake.encode(); + stream + .write_all(&handshake) + .await + .map_err(Error::Handshake)?; + + let (reader, writer) = stream.into_split(); + + Ok(Self { + receiver: Receiver::from_reader(reader), + sender: Sender(writer), + }) + } +} + +#[derive(Debug, thiserror::Error)] +pub enum SendPreEncodedError { + #[error("Pre-encoded message, could not be decoded it might be from a previous version")] + EncodingCheck(#[source] DecodeMsgError), + #[error("Error while sending pre-encoded msg")] + Sending(#[source] SendError), +} + +impl Sender { + pub(crate) async fn send_bytes(&mut self, bytes: &[u8]) -> Result<(), std::io::Error> { + self.0.write_all(bytes).await + } + + pub async fn send_reading(&mut self, reading: protocol::Reading) -> Result<(), std::io::Error> { + let mut readings = protocol::SensorMessage::<1>::default(); + readings + .values + .push(reading) + .expect("capacity allows one push"); + let msg = protocol::Msg::Readings(readings); + let bytes = msg.encode(); + + self.0.write_all(&bytes).await + } + + pub async fn send_error(&mut self, report: protocol::Error) -> Result<(), std::io::Error> { + let msg = protocol::Msg::<1>::ErrorReport(protocol::ErrorReport::new(report)); + let bytes = msg.encode(); + + self.0.write_all(&bytes).await + } +} + +#[derive(Debug, thiserror::Error)] +pub enum ReceiveError { + #[error("General io error while receiving data from data-server")] + Io(#[source] std::io::Error), + #[error("The connection was closed by the data-server")] + ConnClosed, + #[error("Could not deserialize")] + Deserialize(affector::DeserializeError), +} + +pub struct Sender(OwnedWriteHalf); +pub struct Receiver { + reader: OwnedReadHalf, + decoder: affector::Decoder, + buffer: Vec, +} + +impl Receiver { + fn from_reader(reader: OwnedReadHalf) -> Self { + Self { + reader, + decoder: affector::Decoder::default(), + buffer: Vec::new(), + } + } + + pub async fn receive(&mut self) -> Result { + loop { + if !self.buffer.is_empty() { + if let Some((item, remaining)) = self + .decoder + // this should shrink the buffer on deserialize error, it does + // not however. For now its okay (no more errors) however if + // something goes wrong in the future this is where to look first + .feed(&self.buffer) + .map_err(ReceiveError::Deserialize)? + { + let new_buffer = remaining.to_vec(); + self.buffer = new_buffer; + return Ok(item); + } + } + + self.buffer.resize(100, 0); + let res = self.reader.read(&mut self.buffer).await; + + let n_read = match res { + Ok(0) => return Err(ReceiveError::ConnClosed), + Ok(n_read) => n_read, + Err(e) => return Err(ReceiveError::Io(e)), + }; + self.buffer.truncate(n_read); + } + } +} diff --git a/crates/data-server/src/api/data_source/reconnecting.rs b/crates/data-server/src/api/data_source/reconnecting.rs new file mode 100644 index 00000000..e167f4a3 --- /dev/null +++ b/crates/data-server/src/api/data_source/reconnecting.rs @@ -0,0 +1,305 @@ +use futures_concurrency::future::Race; +use protocol::Affector; +use std::collections::VecDeque; +use std::net::SocketAddr; +use std::time::{Duration, Instant}; +use tokio::sync::{mpsc, oneshot}; +use tokio::task::JoinHandle; +use tokio::time::{sleep, timeout}; +use tracing::{info, warn}; + +use super::SendPreEncodedError; + +pub struct Client { + _conn_handler_task: AbortOnDrop, + to_send_tx: mpsc::Sender, +} + +struct AbortOnDrop(JoinHandle<()>); +impl Drop for AbortOnDrop { + fn drop(&mut self) { + self.0.abort(); + } +} + +#[derive(Debug)] +enum QueuedItem { + Retry { item: SendItem, prev_err: SendError }, + Fresh(SendItem), +} + +struct SendQueue { + rx: mpsc::Receiver, + need_retry: VecDeque<(SendItem, SendError)>, +} + +impl SendQueue { + async fn next(&mut self) -> QueuedItem { + if let Some((item, prev_err)) = self.need_retry.pop_front() { + QueuedItem::Retry { item, prev_err } + } else { + QueuedItem::Fresh(self.rx.recv().await.expect( + "this is canceled before the corrosponding sender is dropped", + )) + } + } + + fn push(&mut self, needs_retry: SendItem, error: SendError) { + self.need_retry.push_back((needs_retry, error)); + } +} + +// Not cancel safe, should never be canceled +async fn handle_conn( + addr: SocketAddr, + affectors: Vec, + msgs_to_send: mpsc::Receiver, + msgs_recieved: Option>, +) { + let mut to_send = SendQueue { + rx: msgs_to_send, + need_retry: VecDeque::new(), + }; + loop { + let mut retry_period = Duration::from_millis(200); + let conn = reconnect(addr, &affectors, &mut retry_period).await; + + if let Some(ref msgs_recieved) = msgs_recieved { + ( + handle_sending(conn.sender, &mut to_send), + handle_recieving(conn.receiver, msgs_recieved), + ) + .race() + .await; + } else { + handle_sending(conn.sender, &mut to_send).await; + } + } +} + +#[derive(Debug)] +struct SendItem { + bytes: Vec, + feedback: oneshot::Sender>, + deadline: Instant, +} + +async fn handle_sending(mut sender: super::Sender, to_send: &mut SendQueue) { + loop { + match to_send.next().await { + QueuedItem::Retry { item, .. } | QueuedItem::Fresh(item) + if item.deadline.elapsed().is_zero() => + { + if let Err(err) = sender.send_bytes(&item.bytes).await { + tracing::warn!("Error sending reading or sensor: {err}"); + to_send.push(item, SendError::Io(err.to_string())); + return; + } else { + let _ = item.feedback.send(Ok(())); + } + } + // expired + QueuedItem::Fresh(item) => { + let _ = item.feedback.send(Err(SendError::Outdated)); + } + QueuedItem::Retry { item, prev_err } => { + let _ = item.feedback.send(Err(prev_err)); + } + } + } +} + +#[derive(Debug, Clone, thiserror::Error)] +pub enum SendError { + #[error("Io error while sending data to data-server: {0}")] + Io(String), + #[error( + "Sending the data was aborted, probably due to \ + reconnect due to failed recieve" + )] + Aborted, + /// returns the encoded message that you tried to send + #[error( + "Sender queue is full, it has probably been disconnected for a while" + )] + Overloaded { bytes: Vec }, + #[error("Could not send in time (deadline expired)")] + Outdated, +} + +async fn handle_recieving( + mut receiver: super::Receiver, + msgs_recieved: &mpsc::Sender, +) { + loop { + let msg = match receiver.receive().await { + Ok(msg) => msg, + Err(err) => { + tracing::error!("Error receiving affector orders: {err}"); + return; + } + }; + + tracing::debug!("recv item: {msg:?}"); + msgs_recieved + .send(msg) + .await + .expect("Reciever in the 'Client' is never dropped") + } +} + +#[derive(Debug, thiserror::Error)] +#[error("Invalid address: {0}")] +pub struct InvalidAddress(String); + +impl Client { + /// Needs a list of the affectors that can be controlled through this + /// node as an argument. If your node provides not controllable affectors + /// pass in an empty Vec. + /// + /// # Errors + /// returns an error if the address could not looked up + pub async fn new( + addr: A, + affectors: Vec, + affector_tx: Option>, + ) -> Result { + let addr: SocketAddr = tokio::net::lookup_host(addr) + .await + .map_err(|e| e.to_string()) + .map_err(InvalidAddress)? + .next() + .ok_or_else(|| { + InvalidAddress("No address passed in".to_string()) + })?; + + let (to_send_tx, to_send_rx) = mpsc::channel(100); + let task = handle_conn(addr, affectors, to_send_rx, affector_tx); + let handle = tokio::spawn(task); + Ok(Self { + _conn_handler_task: AbortOnDrop(handle), + to_send_tx, + }) + } + + async fn send_bytes( + &mut self, + bytes: Vec, + deadline: Instant, + ) -> Result<(), SendError> { + let (tx, rx) = oneshot::channel(); + match self.to_send_tx.try_send(SendItem { + bytes, + feedback: tx, + deadline, + }) { + Ok(()) => (), + Err(mpsc::error::TrySendError::Full(SendItem { + bytes, .. + })) => return Err(SendError::Overloaded { bytes }), + Err(mpsc::error::TrySendError::Closed(_)) => { + panic!("re-connect loop should never end") + } + } + match rx.await { + Ok(Ok(())) => Ok(()), + Ok(Err(send_error)) => Err(send_error), + Err(_) => Err(SendError::Aborted), + } + } + + /// # Cancel safety + /// This is cancel safe however the connection will need to be re-established + /// the next time its called. This will retry forever, you should call this + /// in a timeout future if that is a problem. + pub async fn send_reading( + &mut self, + reading: protocol::Reading, + ) -> Result<(), SendError> { + let deadline = + Instant::now() + reading.device().info().temporal_resolution; + + let mut readings = protocol::SensorMessage::<1>::default(); + readings + .values + .push(reading) + .expect("capacity allows one push"); + let msg = protocol::Msg::Readings(readings); + let bytes = msg.encode(); + + self.send_bytes(bytes, deadline).await + } + + const ERROR_REPORT_SEND_DEADLINE: Duration = Duration::from_secs(60 * 15); + /// # Cancel safety + /// This is cancel safe however the connection will need to be re-established + /// the next time its called. This will retry forever, you should call this + /// in a timeout future if that is a problem. + /// + /// # Warning + /// Message is not send if it could not be send within 15 minutes. Client + /// should re-send the error then. + pub async fn send_error( + &mut self, + report: protocol::Error, + ) -> Result<(), SendError> { + let msg = + protocol::Msg::<1>::ErrorReport(protocol::ErrorReport::new(report)); + let bytes = msg.encode(); + + self.send_bytes( + bytes, + Instant::now() + Self::ERROR_REPORT_SEND_DEADLINE, + ) + .await + } + + pub async fn check_send_encoded( + &mut self, + msg: Vec, + ) -> Result<(), SendPreEncodedError> { + let decoded = protocol::Msg::<50>::decode(msg.to_vec()) + .map_err(SendPreEncodedError::EncodingCheck)?; + let deadline = match decoded { + protocol::Msg::Readings(sensor_message) => sensor_message.values.iter().map(|v| v.device().info().temporal_resolution).min().expect("empty sensormessages are forbidden"), + protocol::Msg::ErrorReport(_) => Self::ERROR_REPORT_SEND_DEADLINE, + protocol::Msg::AffectorList(_) => unreachable!("send by client on reconnect only, never send by user of client"), + }; + + self.send_bytes(msg, Instant::now() + deadline) + .await + .map_err(SendPreEncodedError::Sending) + } +} + +async fn reconnect( + addr: SocketAddr, + affectors: &[protocol::Affector], + retry_period: &mut Duration, +) -> super::Client { + loop { + match timeout( + Duration::from_millis(500), + super::Client::connect(addr, affectors.to_vec()), + ) + .await + { + Ok(Ok(conn)) => { + info!("Successfully (re)connected to data-server"); + return conn; + } + Ok(Err(e)) => warn!( + "Failed to (re)connect: {e}\n\ + retrying in {:?}", + retry_period + ), + Err(_) => warn!( + "Failed to (re)connect, timed out.\n\ + retrying in {:?}", + retry_period + ), + } + sleep(*retry_period).await; + *retry_period = (*retry_period * 2).min(Duration::from_secs(5)); + } +} diff --git a/crates/data-server/src/api/subscriber.rs b/crates/data-server/src/api/subscriber.rs new file mode 100644 index 00000000..edc0e511 --- /dev/null +++ b/crates/data-server/src/api/subscriber.rs @@ -0,0 +1,46 @@ +pub use client::reconnecting::Client as ReconnectingClient; +pub use client::reconnecting::SubscribedClient as ReconnectingSubscribedClient; +pub use client::Client; +pub use client::Subscribed as SubscribedClient; +use serde::{Deserialize, Serialize}; + +pub use crate::server::affector::AffectorError; +pub mod client; + +#[derive(Debug, Clone, Serialize, Deserialize)] +pub enum Request { + Handshake { name: String }, + Actuate(protocol::Affector), + ListAffectors, +} + +#[derive(Debug, Clone, Serialize, Deserialize)] +pub enum Response { + Handshake, + Error(ServerError), + Actuate(Result<(), AffectorError>), + ListAffectors(Vec), + SubUpdate(SubMessage), + Subscribe, +} + +#[derive(Debug, Clone, Serialize, Deserialize)] +pub enum SubMessage { + Reading(protocol::Reading), + // An affector was moved/updated + AffectorControlled { + affector: protocol::Affector, + controlled_by: String, + }, + ErrorReport(Box), +} + +#[derive(Clone, Debug, thiserror::Error, Serialize, Deserialize)] +#[error("placeholder")] +pub struct SubscribeError; + +#[derive(Clone, Debug, thiserror::Error, Serialize, Deserialize)] +pub enum ServerError { + #[error("Could not activate affector")] + FailedToSpread, +} diff --git a/crates/data-server/src/api/subscriber/client.rs b/crates/data-server/src/api/subscriber/client.rs new file mode 100644 index 00000000..3628ca83 --- /dev/null +++ b/crates/data-server/src/api/subscriber/client.rs @@ -0,0 +1,95 @@ +use rpc::client::RpcClient; +use rpc::client::RpcError; +use tokio::net::ToSocketAddrs; + +use super::AffectorError; +use super::Request; +use super::Response; + +use crate::api::subscriber; +pub(crate) mod reconnecting; + +#[derive(Debug)] +pub struct Client(rpc::client::RpcClient); + +impl Client { + pub async fn connect( + addr: impl ToSocketAddrs, + name: String, + ) -> Result { + let rpc_client = RpcClient::connect(addr, name).await?; + Ok(Self(rpc_client)) + } + + pub async fn actuate_affector( + &mut self, + affector: protocol::Affector, + ) -> Result<(), Error> { + let request = Request::Actuate(affector); + match self.0.send_receive(request.clone()).await? { + Response::Actuate(res) => res.map_err(Error::Request), + response => Err(Error::Comms(RpcError::IncorrectResponse { + request: format!("{request:?}"), + response: format!("{response:?}"), + })), + } + } + + pub async fn list_affectors( + &mut self, + ) -> Result, Error> { + let request = Request::ListAffectors; + match self.0.send_receive(request.clone()).await? { + Response::ListAffectors(list) => Ok(list), + response => Err(Error::Comms(RpcError::IncorrectResponse { + request: format!("{request:?}"), + response: format!("{response:?}"), + })), + } + } + + pub async fn subscribe( + mut self, + ) -> Result> { + self.0.subscribe().await?; + Ok(Subscribed(self)) + } +} + +#[derive(Debug)] +pub struct Subscribed(Client); + +impl Subscribed { + pub async fn next( + &mut self, + ) -> Result> { + let received = self.0 .0.next().await?; + + if let subscriber::Response::SubUpdate(update) = received { + Ok(update) + } else { + Err(Error::Comms(RpcError::IncorrectResponse { + request: "none, we are subscribed".to_string(), + response: format!("{received:?}"), + })) + } + } +} + +#[derive(Debug, thiserror::Error)] +pub enum Error { + #[error("Error while sending request")] + Sending(#[source] std::io::Error), + #[error("Error while sending request")] + Receiving(#[source] std::io::Error), + #[error("General error while processing request")] + Server(#[source] subscriber::ServerError), + #[error("Server ran into an specific error with our request")] + Request(#[source] T), + #[error("Error while communicating with server")] + Comms( + #[from] + #[source] + RpcError, + ), +} diff --git a/crates/data-server/src/api/subscriber/client/reconnecting.rs b/crates/data-server/src/api/subscriber/client/reconnecting.rs new file mode 100644 index 00000000..f6dd3712 --- /dev/null +++ b/crates/data-server/src/api/subscriber/client/reconnecting.rs @@ -0,0 +1,211 @@ +use crate::api::subscriber; + +use std::net::SocketAddr; +use std::time::Duration; +use tokio::time::{sleep, timeout}; +use tracing::{info, warn}; + +#[derive(Debug)] +pub struct Client { + retry_period: Duration, + connection: Option, + addr: SocketAddr, + name: String, +} + +impl Client { + #[must_use] + pub fn new(addr: SocketAddr, name: String) -> Self { + Self { + retry_period: Duration::from_millis(200), + connection: None, + addr, + name, + } + } + + #[must_use] + pub fn subscribe(self) -> SubscribedClient { + SubscribedClient { + retry_period: self.retry_period, + connection: self.connection.map(ConnState::Connected), + addr: self.addr, + name: self.name, + } + } + + /// # Cancel safety + /// This is cancel safe however the connection will need to be re-established + /// the next time its called. This will retry forever, you should call this + /// in a timeout future. + pub async fn actuate_affector(&mut self, affector: protocol::Affector) { + loop { + let mut conn = if let Some(conn) = self.connection.take() { + conn + } else { + get_connection_or_reconnect( + self.addr, + &self.name, + &mut self.retry_period, + ) + .await + }; + + match conn.actuate_affector(affector).await { + Ok(msg) => { + self.retry_period /= 2; + self.retry_period = + self.retry_period.max(Duration::from_millis(200)); + self.connection = Some(conn); + return msg; + } + Err(issue) => { + warn!("Conn issue while getting next_msg: {issue}, reconnecting"); + } + }; + } + } + + /// # Cancel safety + /// This is cancel safe however the connection will need to be re-established + /// the next time its called. This will retry forever, you should call this + /// in a timeout future. + pub async fn list_affectors(&mut self) -> Vec { + loop { + let mut conn = if let Some(conn) = self.connection.take() { + conn + } else { + get_connection_or_reconnect( + self.addr, + &self.name, + &mut self.retry_period, + ) + .await + }; + + match conn.list_affectors().await { + Ok(list) => { + self.retry_period /= 2; + self.retry_period = + self.retry_period.max(Duration::from_millis(200)); + self.connection = Some(conn); + return list; + } + Err(issue) => { + warn!("Conn issue while getting next_msg: {issue}, reconnecting"); + } + }; + } + } +} + +#[derive(Debug)] +enum ConnState { + Connected(super::Client), + Subbed(super::Subscribed), +} + +impl ConnState { + fn expect_subbed(&mut self, msg: &str) -> &mut super::Subscribed { + match self { + ConnState::Connected(_) => panic!("{msg}"), + ConnState::Subbed(subscribed) => subscribed, + } + } +} + +#[derive(Debug)] +pub struct SubscribedClient { + retry_period: Duration, + connection: Option, + addr: SocketAddr, + name: String, +} + +impl SubscribedClient { + /// # Cancel safety, + /// + /// This is cancel safe + pub async fn next(&mut self) -> subscriber::SubMessage { + loop { + let conn = if let Some(conn) = self.connection.take() { + conn + } else { + ConnState::Connected( + get_connection_or_reconnect( + self.addr, + &self.name, + &mut self.retry_period, + ) + .await, + ) + }; + + let subbed = match conn { + ConnState::Connected(conn) => match conn.subscribe().await { + Ok(subbed) => subbed, + Err(e) => { + tracing::warn!("Error subscribing to data-server: {e}"); + continue; + } + }, + ConnState::Subbed(subbed) => subbed, + }; + + // for the above we want any cancellation to lead to a full reconnect + // and resubscribe. Anything below here should resume fine so should + // stay connected under cancellation. + self.connection = Some(ConnState::Subbed(subbed)); + let subbed = self + .connection + .as_mut() + .expect("set to Some one line up") + .expect_subbed("set to Subbed one line up"); + + match subbed.next().await { + Ok(msg) => { + self.retry_period /= 2; + self.retry_period = + self.retry_period.max(Duration::from_millis(200)); + return msg; + } + Err(issue) => { + self.connection = None; + warn!("Conn issue while getting next_msg: {issue}, reconnecting"); + } + }; + } + } +} + +async fn get_connection_or_reconnect( + addr: SocketAddr, + name: &str, + retry_period: &mut Duration, +) -> super::Client { + loop { + match timeout( + Duration::from_millis(500), + super::Client::connect(addr, name.to_owned()), + ) + .await + { + Ok(Ok(conn)) => { + info!("Successfully (re)connected to data-server"); + return conn; + } + Ok(Err(e)) => warn!( + "Failed to (re)connect: {e}\n\ + retrying in {:?}", + retry_period + ), + Err(_) => warn!( + "Failed to (re)connect, timed out.\n\ + retrying in {:?}", + retry_period + ), + } + sleep(*retry_period).await; + *retry_period = (*retry_period * 2).min(Duration::from_secs(5)); + } +} diff --git a/crates/data-server/src/lib.rs b/crates/data-server/src/lib.rs new file mode 100644 index 00000000..4a619a91 --- /dev/null +++ b/crates/data-server/src/lib.rs @@ -0,0 +1,7 @@ +#![allow(clippy::missing_panics_doc, clippy::missing_errors_doc)] + +#[cfg(feature = "api")] +pub mod api; + +#[cfg(feature = "server")] +pub mod server; diff --git a/crates/data-server/src/main.rs b/crates/data-server/src/main.rs new file mode 100644 index 00000000..33b054b3 --- /dev/null +++ b/crates/data-server/src/main.rs @@ -0,0 +1,61 @@ +use std::net::SocketAddr; + +use tokio::select; +use tokio::sync::mpsc; + +use clap::Parser; +use color_eyre::Result; +use tracing::info; + +use data_server::server; + +#[derive(Parser)] +#[command(name = "data server")] +#[command(version = "1.0")] +#[command(about = "Receives sensor events and spreads those to subscribed services")] +struct Cli { + /// Addr to which subscribers can connect + #[arg(short, long)] + subscribe_addr: SocketAddr, + + /// Addr to which data-source can supply messages + #[arg(short, long)] + update_addr: SocketAddr, + + /// Reset data-sources that have missing or slow sensors + #[arg(short, long)] + enable_reset: bool, +} + +#[tokio::main(flavor = "current_thread")] +async fn main() -> Result<()> { + logger::tracing::setup(); + + let Cli { + subscribe_addr, + update_addr, + enable_reset, + } = Cli::parse(); + assert_ne!(subscribe_addr, update_addr); + + info!("listening for updates on: {update_addr}"); + info!("serving subscribers on: {subscribe_addr}"); + + let affectors = server::AffectorRegistar::default(); + let (tx, rx) = mpsc::channel(2000); + + if enable_reset { + select! { + e = server::client::handle(subscribe_addr, tx.clone(), affectors.clone()) => e, + e = server::handle_nodes(update_addr, &tx, affectors.clone()) => e, + e = server::handle_updates(rx) => e, + _ = server::node_watchdog(affectors, &tx) => Ok(()), + } + } else { + select! { + e = server::client::handle(subscribe_addr, tx.clone(), affectors.clone()) => e, + e = server::handle_nodes(update_addr, &tx, affectors.clone()) => e, + e = server::handle_updates(rx) => e, + } + } +} diff --git a/crates/data-server/src/server.rs b/crates/data-server/src/server.rs new file mode 100644 index 00000000..84a71179 --- /dev/null +++ b/crates/data-server/src/server.rs @@ -0,0 +1,38 @@ +use color_eyre::Result; +use protocol::Reading; +use tokio::net::TcpStream; +use tokio::sync::mpsc; +use tokio_serde::formats::Bincode; +use tokio_util::codec::{Framed, LengthDelimitedCodec}; + +pub mod affector; +pub mod client; +mod data_source; +mod subscribe; +mod watch; + +pub use affector::Registar as AffectorRegistar; +pub use data_source::handle_nodes; +pub use subscribe::handle_updates; +pub use watch::node_watchdog; + +use crate::api::subscriber::{self, SubMessage}; + +pub type Conn = tokio_serde::Framed< + Framed, + subscriber::Request, + subscriber::Response, + Bincode, +>; + +#[derive(Debug)] +pub enum Event { + NewSub { + tx: mpsc::Sender, + }, + NewReading(Result>), + AffectorControlled { + affector: protocol::Affector, + controlled_by: String, + }, +} diff --git a/crates/data-server/src/server/affector.rs b/crates/data-server/src/server/affector.rs new file mode 100644 index 00000000..5a95deae --- /dev/null +++ b/crates/data-server/src/server/affector.rs @@ -0,0 +1,146 @@ +use std::num::NonZeroU32; +use std::sync::{Arc, Mutex}; + +use color_eyre::Result; +use governor::Quota; +use protocol::{Affector, IsSameAs}; +use serde::{Deserialize, Serialize}; +use slotmap::{DefaultKey, SlotMap}; +use tokio::io::AsyncWriteExt; +use tokio::net::tcp::OwnedWriteHalf; +use tokio::sync::mpsc::{Receiver, Sender}; + +use tracing::{instrument, warn}; + +pub(crate) struct Registration { + tx: tokio::sync::mpsc::Sender, + controls: Vec, + rate_limiter: governor::DefaultDirectRateLimiter, +} + +impl std::fmt::Debug for Registration { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + f.debug_struct("Registration") + .field("controls", &self.controls) + .finish() + } +} + +impl Registration { + fn update(&mut self, new: Affector) { + let curr = self + .controls + .iter_mut() + .find(|a| a.is_same_as(&new)) + .unwrap(); + *curr = new; + } +} + +#[derive(Clone, Default)] +pub struct Registar(Arc>>); + +impl std::fmt::Debug for Registar { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + let this = self.0.lock().unwrap(); + let list: Vec<_> = this.values().map(|r| format!("{r:?}")).collect(); + f.debug_struct("Registar").field("0", &list).finish() + } +} + +impl Registar { + pub(crate) fn register( + &self, + tx: Sender, + affectors: Vec, + ) -> DefaultKey { + let mut this = self.0.lock().expect("nothing should panic"); + + let to_remove: Vec<_> = this + .iter_mut() + .filter(|(_, reg)| { + reg.controls.iter().any(|control| { + affectors + .iter() + .any(|affector| affector.is_same_as(control)) + }) + }) + .map(|(key, _)| key) + .collect(); + + for key in to_remove { + this.remove(key) + .expect("held lock so can not have been removed"); + } + + this.insert(Registration { + tx, + controls: affectors, + rate_limiter: governor::DefaultDirectRateLimiter::direct( + Quota::per_second(NonZeroU32::new(1).expect("not zero")) + .allow_burst(NonZeroU32::new(5).expect("not zero")), + ), + }) + } + + pub(crate) fn remove(&self, key: DefaultKey) { + let mut this = self.0.lock().expect("nothing should panic"); + let _ = this.remove(key); // Could have been removed by register + } + + pub(crate) fn activate( + &self, + order: Affector, + ) -> Result<(), AffectorError> { + tracing::debug!("client is trying to activate: {order:?}"); + let mut this = self.0.lock().expect("nothing should panic"); + for possible_controller in + this.iter_mut().map(|(_, reg)| reg).filter(|reg| { + reg.controls + .iter() + .any(|control| control.is_same_as(&order)) + }) + { + if possible_controller.rate_limiter.check().is_err() { + return Err(AffectorError::RateLimited); + } + if possible_controller.tx.try_send(order).is_ok() { + possible_controller.update(order); + tracing::info!("client activated: {order:?}"); + return Ok(()); + }; + } + + Err(AffectorError::Offline) + } + + pub(crate) fn list(&self) -> Vec { + let this = self.0.lock().expect("nothing should panic"); + this.iter() + .flat_map(|(_, reg)| reg.controls.iter()) + .cloned() + .collect() + } +} + +#[derive(Debug, thiserror::Error, Clone, Serialize, Deserialize)] +pub enum AffectorError { + #[error("Sensor node to which the affector belongs is offline")] + Offline, + #[error("Too many requests, ratelimited")] + RateLimited, +} + +#[instrument(skip_all)] +pub(super) async fn control_affectors( + mut writer: OwnedWriteHalf, + mut rx: Receiver, +) { + while let Some(new_order) = rx.recv().await { + let buf = new_order.encode(); + if let Err(e) = writer.write_all(&buf).await { + warn!("Could not send affector order: {e}"); + break; + } + } +} diff --git a/crates/data-server/src/server/client.rs b/crates/data-server/src/server/client.rs new file mode 100644 index 00000000..b7dbdcbb --- /dev/null +++ b/crates/data-server/src/server/client.rs @@ -0,0 +1,103 @@ +use futures::{stream, Stream}; +use std::net::SocketAddr; +use tokio::sync::mpsc; + +use color_eyre::Result; + +use crate::api::subscriber; + +use super::{affector::Registar, Event}; + +#[derive(Debug, Clone)] +struct SubHandler { + new_events: mpsc::Sender, +} + +async fn do_setup( + new_events: mpsc::Sender, +) -> impl Stream + Send + 'static { + let (tx, rx) = tokio::sync::mpsc::channel(100); + new_events + .send(Event::NewSub { tx }) + .await + .expect("Events processor (rx) should never stop"); + stream::unfold(rx, |mut rx| async move { + rx.recv() + .await + .map(subscriber::Response::SubUpdate) + .map(|yielded| (yielded, rx)) + }) +} + +impl rpc::SubscriberHandler for SubHandler { + type Update = subscriber::Response; + + fn setup( + &mut self, + ) -> impl std::future::Future< + Output = impl futures::prelude::Stream + Send + 'static, + > + Send + + 'static { + do_setup(self.new_events.clone()) + } +} + +pub async fn handle( + addr: SocketAddr, + tx: mpsc::Sender, + affectors: Registar, +) -> color_eyre::Result<()> { + let port = addr.port(); + let handler = SubHandler { + new_events: tx.clone(), + }; + rpc::server::run( + port, + move |req, name| { + let tx = tx.clone(); + let affectors = affectors.clone(); + perform_request(req, name.to_owned(), tx, affectors) + }, + Some(handler), + ) + .await +} + +async fn perform_request( + request: subscriber::Request, + client_name: String, + new_event: mpsc::Sender, + affectors: Registar, +) -> subscriber::Response { + match perform_request_inner(request, client_name, new_event, affectors).await { + Ok(response) => response, + Err(error) => subscriber::Response::Error(error), + } +} + +async fn perform_request_inner( + request: subscriber::Request, + client_name: String, + new_event: mpsc::Sender, + affectors: Registar, +) -> Result { + Ok(match request { + subscriber::Request::Handshake { .. } => { + unreachable!("handshake only takes place during connection") + } + subscriber::Request::Actuate(affector) => match affectors.activate(affector) { + Ok(()) => { + new_event + .send(Event::AffectorControlled { + affector, + controlled_by: client_name.to_owned(), + }) + .await + .map_err(|_| subscriber::ServerError::FailedToSpread)?; + subscriber::Response::Actuate(Ok(())) + } + Err(err) => subscriber::Response::Actuate(Err(err)), + }, + subscriber::Request::ListAffectors => subscriber::Response::ListAffectors(affectors.list()), + }) +} diff --git a/crates/data-server/src/server/data_source.rs b/crates/data-server/src/server/data_source.rs new file mode 100644 index 00000000..c4e8f815 --- /dev/null +++ b/crates/data-server/src/server/data_source.rs @@ -0,0 +1,206 @@ +use std::net::SocketAddr; +use std::num::NonZeroU32; +use std::time::Duration; + +use color_eyre::eyre::{eyre, Context}; +use color_eyre::{Result, Section}; +use futures_concurrency::future::Race; +use governor::clock::Clock; +use governor::{Quota, RateLimiter}; +use protocol::Affector; +use socket2::{Socket, TcpKeepalive}; +use tokio::io::{AsyncBufReadExt, BufReader}; +use tokio::net::tcp::OwnedReadHalf; +use tokio::net::TcpStream; +use tokio::sync::mpsc::Sender; + +use super::Event; +use tracing::{error, info, instrument, warn}; + +use super::affector::{control_affectors, Registar}; + +/// spawns tasks for all nodes that connect. Those tasks push the readings +/// their nodes report into share and send relevant affector orders to the +/// node if they get them via the registar. +pub async fn handle_nodes( + addr: SocketAddr, + share: &Sender, + registar: Registar, +) -> Result<()> { + let socket = + Socket::new(socket2::Domain::IPV4, socket2::Type::STREAM, None)?; + socket + .set_tcp_nodelay(true) + .expect("should be able to disable nagle algorithm"); + socket + .set_tcp_mss(2048) + .expect("should be able to set max segment size for outgoing packets"); + socket + .bind(&addr.into()) + .wrap_err("Could not bind to addr for new subscribers") + .with_note(|| format!("trying to listen on: {addr}"))?; + socket + .listen(128) + .wrap_err("Could not start listening for new subscribers") + .with_note(|| format!("trying to listen on: {addr}"))?; + let listener: std::net::TcpListener = socket.into(); + listener + .set_nonblocking(true) + .expect("Should be able to set nonblocking mode"); + let listener = tokio::net::TcpListener::from_std(listener) + .expect("Conversion from std to tokio listener should always succeed"); + + loop { + let res = listener.accept().await; + match res { + Ok((stream, source)) => { + info!("new data source connected from: {source}"); + tokio::spawn(handle_node( + stream, + source, + share.clone(), + registar.clone(), + )); + } + Err(e) => { + warn!("new connection failed: {e}"); + continue; + } + }; + } +} + +pub async fn read_and_decode_packet( + reader: &mut BufReader, + buf: &mut Vec, +) -> color_eyre::Result> { + buf.clear(); + let n_read = reader + .read_until(0, buf) + .await + .wrap_err("Connection failed/closed")?; + + let bytes = &mut buf[0..n_read]; + if bytes.is_empty() { + return Err(eyre!("End of stream, connection is closed")); + } + + protocol::Msg::<50>::decode(bytes).wrap_err("decode failed") +} + +#[instrument(skip(stream, queue, registar))] +async fn handle_node( + stream: TcpStream, + source: SocketAddr, + queue: Sender, + registar: Registar, +) { + use tracing_futures::Instrument; + + let sock_ref = socket2::SockRef::from(&stream); + sock_ref + .set_tcp_keepalive( + &TcpKeepalive::new() + .with_time(Duration::from_secs(5)) + .with_retries(1) // 1 is minimum + .with_interval(Duration::from_secs(1)), + ) + .expect("4 sec keepalive should work on tcp stream"); + let (reader, writer) = stream.into_split(); + let mut reader = BufReader::new(reader); + + let affectors = match handshake(&mut reader).await { + Ok(affectors) => affectors, + Err(e) => { + error!("failed node handshake: {e}"); + return; + } + }; + info!("new node connected with affectors: {affectors:?}"); + + let (tx, rx) = tokio::sync::mpsc::channel(10); + let key = registar.register(tx, affectors); + ( + receive_and_spread_updates(reader, queue).in_current_span(), + control_affectors(writer, rx).in_current_span(), + ) + .race() + .await; + + registar.remove(key); + warn!("node removed (lost connection)"); +} + +async fn handshake( + reader: &mut BufReader, +) -> Result, String> { + let mut buf = Vec::new(); + let msg = match read_and_decode_packet(reader, &mut buf).await { + Ok(decoded) => decoded, + Err(e) => { + return Err(format!( + "Error while reading and decoding packet: {e}" + )); + } + }; + let protocol::Msg::AffectorList(list) = msg else { + return Err( + "Must get affector list as first message (handshake)".to_owned() + ); + }; + + Ok(list.values.to_vec()) +} + +#[instrument(skip_all)] +async fn receive_and_spread_updates( + mut reader: BufReader, + queue: Sender, +) { + let quota = Quota::per_second(NonZeroU32::new(40).unwrap()) + .allow_burst(NonZeroU32::new(200u32).unwrap()); + let limiter = RateLimiter::direct(quota); + + let mut buf = Vec::new(); + loop { + if let Err(allowed_again) = limiter.check() { + let now = governor::clock::DefaultClock::default().now(); + let allowed_in = allowed_again.wait_time_from(now); + error!( + "Refusing to read packet: (generous) ratelimit surpassed. \ + Next packet allowed in {allowed_in:?}. Sleeping till then" + ); + tokio::time::sleep(allowed_in).await; + } + + let msg = match read_and_decode_packet(&mut reader, &mut buf).await { + Ok(decoded) => decoded, + Err(e) => { + error!("Error while reading and decoding packet: {e}"); + return; + } + }; + + match msg { + protocol::Msg::Readings(list) => { + for value in list.values { + queue + .send(Event::NewReading(Ok(value))) + .await + .expect("fn spread_updates should stay running"); + } + } + protocol::Msg::ErrorReport(report) => { + let boxed = Box::new(report.error); + queue + .send(Event::NewReading(Err(boxed))) + .await + .expect("fn spread_updates should stay running"); + } + protocol::Msg::AffectorList(_) => { + error!("Affector list should only be send at the start of the connection"); + return; + } + } + } // Loop +} diff --git a/crates/data-server/src/server/subscribe.rs b/crates/data-server/src/server/subscribe.rs new file mode 100644 index 00000000..98bdc3cb --- /dev/null +++ b/crates/data-server/src/server/subscribe.rs @@ -0,0 +1,153 @@ +use protocol::reading::tree::Tree; +use protocol::reading::ReadingId; +use protocol::{pir, Reading}; +use std::collections::HashMap; +use std::mem; +use std::time::{Duration, Instant}; +use tokio::sync::mpsc; +use tokio::sync::mpsc::error::TrySendError; +use tokio_util::time::FutureExt; +use tracing::trace; + +use color_eyre::Result; + +use super::Event; +use crate::api::subscriber::SubMessage; + +pub async fn handle_updates(mut events: mpsc::Receiver) -> Result<()> { + let mut pir_state_tracker = PirStateTracker::new(); + let mut subscribers = Vec::new(); + + loop { + let update = events + .recv() + .timeout_at(pir_state_tracker.call_again_at.into()) + .await + .map(|recv_res| { + recv_res.expect("queue is kept open by register_subs") + }); + trace!("update: {update:?}"); + + match update { + Err(_timeout) => { + for pir_went_dark in pir_state_tracker.dark_pirs() { + broadcast_reading( + &mut subscribers, + SubMessage::Reading(pir_went_dark), + ); + } + } + Ok(event) => { + spread_updates(&mut pir_state_tracker, &mut subscribers, event) + } + } + } +} + +fn spread_updates( + pir_state_tracker: &mut PirStateTracker, + subscribers: &mut Vec>, + event: Event, +) { + let to_forward = match event { + Event::NewSub { tx } => { + subscribers.push(tx); + return; + } + Event::NewReading(Ok(reading)) => { + if let Some(reading) = + pir_state_tracker.intercept_pir_status(reading) + { + SubMessage::Reading(reading) + } else { + return; + } + } + Event::NewReading(Err(err)) => SubMessage::ErrorReport(err), + Event::AffectorControlled { + affector, + controlled_by, + } => SubMessage::AffectorControlled { + affector, + controlled_by, + }, + }; + broadcast_reading(subscribers, to_forward); +} + +fn broadcast_reading( + subscribers: &mut Vec>, + to_forward: SubMessage, +) { + let subs = mem::take(subscribers); + for sub in subs { + let res = sub.try_send(to_forward.clone()); + if let Ok(()) | Err(TrySendError::Full(_)) = res { + subscribers.push(sub) + } + } +} + +/// Pirs should send Status::Active every 5 seconds to confirm they have not +/// gone down/defective. It makes no sense to store Status::Active every 5 +/// seconds. +/// +/// - drops a Status::Active if one was already send +/// - inserts a Status::Unknown if no Status::Active was received in the last +/// 6s. Unless a Status::InActive was received in between +struct PirStateTracker { + active: HashMap, + call_again_at: Instant, +} + +const ACTIVE_PIR_HEARTBEAT: Duration = Duration::from_secs(5); + +impl PirStateTracker { + fn new() -> Self { + Self { + active: HashMap::new(), + call_again_at: Instant::now(), + } + } + fn dark_pirs<'a>(&'a mut self) -> impl Iterator + 'a { + self.active + .extract_if(|_, (last_active, _)| { + last_active.elapsed() > ACTIVE_PIR_HEARTBEAT + }) + .map(|(_, (_, mut reading))| { + let pir_status = reading + .value_mut() + .downcast_mut::() + .expect("we only insert pir::Status"); + *pir_status = pir::Status::Unknown; + reading + }) + } + + fn intercept_pir_status( + &mut self, + mut reading: Reading, + ) -> Option { + match reading.value_mut().downcast_ref() { + Some(pir::Status::OngoingActivity) => { + if self + .active + .insert(reading.id(), (Instant::now(), reading.clone())) + .is_none() + { + Some(reading) + } else { + None + } + } + Some(pir::Status::NoActivity) => { + self.active.remove(&reading.id()); + Some(reading) + } + Some(pir::Status::Unknown) => { + unreachable!("Should never be send by node") + } + None => Some(reading), + } + } +} diff --git a/crates/data-server/src/server/watch.rs b/crates/data-server/src/server/watch.rs new file mode 100644 index 00000000..ecf6e2fd --- /dev/null +++ b/crates/data-server/src/server/watch.rs @@ -0,0 +1,140 @@ +use crate::api::subscriber::SubMessage; +use std::time::Duration; + +use super::{AffectorRegistar, Event}; +use protocol::reading::tree::Tree; +use protocol::{large_bedroom, small_bedroom, Affector, IsSameAs, Reading}; +use tokio::sync::mpsc; +use tokio::time::{timeout_at, Instant}; +use tracing::warn; + +const CHECK_INTERVAL: Duration = Duration::from_secs(5); +const MIN_RESET_INTERVAL: Duration = Duration::from_secs(600); + +#[derive(Default)] +struct LastSeen { + map: Vec<(Reading, Instant)>, + last_reset: Vec<(Affector, Instant)>, +} + +impl LastSeen { + fn update(&mut self, reading: Reading) { + if let Some((_, time)) = + self.map.iter_mut().find(|(r, _)| r.is_same_as(&reading)) + { + *time = Instant::now(); + } else { + self.map.push((reading, Instant::now())); + } + } + + fn mark_reset(&mut self, affector: Affector) { + if let Some((_, last)) = self + .last_reset + .iter_mut() + .find(|(a, _)| a.is_same_as(&affector)) + { + *last = Instant::now(); + } else { + self.last_reset.push((affector, Instant::now())); + } + } + + fn check_and_bite(&mut self, registar: &AffectorRegistar) { + let to_reset = self.map.iter().filter(|(reading, last_seen)| { + let max_interval = reading.info().device.info().max_sample_interval; + last_seen.elapsed() > max_interval.saturating_mul(10) + }); + + let mut reset_commands: Vec<_> = to_reset + .filter_map(|(reading, _)| { + match reading { + Reading::LargeBedroom(large_bedroom::Reading::Bed(_)) => { + Some(Affector::LargeBedroom( + large_bedroom::Affector::Bed( + large_bedroom::bed::Affector::ResetNode, + ), + )) + } + Reading::SmallBedroom(small_bedroom::Reading::Bed(_)) => { + Some(Affector::SmallBedroom( + small_bedroom::Affector::Bed( + small_bedroom::bed::Affector::ResetNode, + ), + )) + } + Reading::LargeBedroom(large_bedroom::Reading::Airbox( + _, + )) => Some(Affector::LargeBedroom( + large_bedroom::Affector::Airbox( + large_bedroom::airbox::Affector::ResetNode, + ), + )), + Reading::LargeBedroom(large_bedroom::Reading::Desk(_)) + | Reading::LargeBedroom( + large_bedroom::Reading::DeskRight(_), + ) + | Reading::LargeBedroom( + large_bedroom::Reading::Radiator(_), + ) + | Reading::SmallBedroom(small_bedroom::Reading::Desk(_)) + | Reading::SmallBedroom( + small_bedroom::Reading::Radiator(_), + ) + | Reading::SmallBedroom( + small_bedroom::Reading::ButtonPanel(_), + ) + | Reading::SmallBedroom( + small_bedroom::Reading::PortableButtonPanel(_), + ) => None, + } + .map(|reset_cmd| (reading, reset_cmd)) + }) + .filter(|(_, reset_cmd)| { + let last_reset = self + .last_reset + .iter() + .find(|(a, _)| a.is_same_as(reset_cmd)) + .map(|(_, at)| at) + .copied(); + !last_reset.is_some_and(|last_reset| { + last_reset.elapsed() > MIN_RESET_INTERVAL + }) + }) + .map(|(reading, reset_cmd)| (reading.clone(), reset_cmd)) + .collect(); + reset_commands.dedup_by(|(_, a), (_, b)| a.is_same_as(b)); + + for (reading, cmd) in reset_commands { + warn!("resetting node with problematic reading: {reading:?}, using: {cmd:?}"); + if registar.activate(cmd).is_ok() { + self.mark_reset(cmd); + } + } + } +} + +pub async fn node_watchdog( + registar: AffectorRegistar, + sub_tx: &mpsc::Sender, +) -> ! { + let (tx, mut rx) = mpsc::channel(128); + sub_tx + .send(Event::NewSub { tx }) + .await + .expect("handle_sub_should_still_run"); + + let mut next_check = tokio::time::Instant::now() + CHECK_INTERVAL; + let mut last_seen = LastSeen::default(); + loop { + match timeout_at(next_check, rx.recv()).await { + Ok(None) => unreachable!("subscribers should never be dropped"), + Ok(Some(SubMessage::Reading(r))) => last_seen.update(r), + Ok(Some(_)) => (), + Err(_timeout) => { + last_seen.check_and_bite(®istar); + next_check = Instant::now() + CHECK_INTERVAL; + } + } + } +} diff --git a/crates/data-server/tests/pir-status.rs b/crates/data-server/tests/pir-status.rs new file mode 100644 index 00000000..f6d0049d --- /dev/null +++ b/crates/data-server/tests/pir-status.rs @@ -0,0 +1,101 @@ +use std::net::{Ipv4Addr, SocketAddr}; +use std::time::Duration; + +use color_eyre::Result; +use data_server::api::subscriber::{Client, SubMessage}; +use data_server::server::{self, AffectorRegistar}; +use protocol::large_bedroom; +use protocol::large_bedroom::desk_right; +use protocol::{pir, Reading}; +use tokio::io::AsyncWriteExt; +use tokio::net::TcpStream; +use tokio::select; +use tokio::sync::mpsc; +use tokio::time::sleep; + +#[derive(Debug, PartialEq)] +enum Done { + RunServer, + SendValue, + Test, +} + +const TEST_PIR_ACTIVE: Reading = + Reading::LargeBedroom(large_bedroom::Reading::DeskRight( + desk_right::Reading::Pir(pir::Status::OngoingActivity), + )); +const TEST_PIR_WENT_DARK: Reading = + Reading::LargeBedroom(large_bedroom::Reading::DeskRight( + desk_right::Reading::Pir(pir::Status::Unknown), + )); + +async fn run_server( + client_addr: impl Into, + data_port: impl Into, +) -> Result { + let (tx, rx) = mpsc::channel(2000); + let affectors = AffectorRegistar::default(); + select! { + e = server::client::handle(client_addr.into(), tx.clone(), affectors.clone()) => e.unwrap(), + e = server::handle_nodes(data_port.into(), &tx, affectors) => e.unwrap(), + e = server::handle_updates(rx) => e?, + }; + + Ok(Done::RunServer) +} + +async fn send_pir_active(data_port: u16) -> Result { + tokio::time::sleep(Duration::from_millis(400)).await; + + let list = protocol::affector::ListMessage::<50>::empty(); + let handshake = protocol::Msg::AffectorList(list).encode(); + + let mut conn = TcpStream::connect(("127.0.0.1", data_port)).await.unwrap(); + conn.write_all(&handshake).await.unwrap(); + + let mut sensor_msg = protocol::SensorMessage::<50>::default(); + sensor_msg.values.push(TEST_PIR_ACTIVE).unwrap(); + let sensor_msg = protocol::Msg::Readings(sensor_msg).encode(); + conn.write_all(&sensor_msg).await.unwrap(); + + sleep(Duration::from_secs(999)).await; + Ok(Done::SendValue) +} + +async fn wait_for_pir_then_unknown(sub_port: u16) -> Result { + tokio::time::sleep(Duration::from_millis(100)).await; + let mut sub = Client::connect( + (Ipv4Addr::LOCALHOST, sub_port), + "api_integration_tests".to_owned(), + ) + .await + .unwrap() + .subscribe() + .await + .unwrap(); + + let received = sub.next().await.unwrap(); + assert!(matches!(received, SubMessage::Reading(TEST_PIR_ACTIVE))); + tokio::time::sleep(Duration::from_millis(5100)).await; + let received = sub.next().await.unwrap(); + assert!( + matches!(received, SubMessage::Reading(TEST_PIR_WENT_DARK)), + "got: {received:?}" + ); + + Ok(Done::Test) +} + +#[tokio::test] +async fn pir_unknown_send_if_active_pir_heartbeat_stops() { + logger::tracing::setup_for_tests(); + + let sub_port = reserve_port::ReservedPort::random().unwrap(); + let data_port = reserve_port::ReservedPort::random().unwrap(); + let res = select! { + e = run_server(([127,0,0,1], sub_port.port()), ([127,0,0,1], data_port.port())) => e, + e = send_pir_active(data_port.port()) => e, + e = wait_for_pir_then_unknown(sub_port.port()) => e, + }; + assert_eq!(res.unwrap(), Done::Test); +} diff --git a/crates/data-server/tests/source_api.rs b/crates/data-server/tests/source_api.rs new file mode 100644 index 00000000..50a78f06 --- /dev/null +++ b/crates/data-server/tests/source_api.rs @@ -0,0 +1,184 @@ +use std::future::pending; +use std::net::{Ipv4Addr, SocketAddr}; +use std::time::Duration; + +use color_eyre::Result; +use data_server::api::data_source; +use data_server::api::subscriber::{Client, SubMessage}; +use data_server::server::{self, AffectorRegistar}; +use protocol::large_bedroom::bed; +use protocol::Reading; +use protocol::{large_bedroom, Affector}; +use tokio::io::AsyncWriteExt; +use tokio::net::TcpStream; +use tokio::select; +use tokio::sync::mpsc; +use tokio::time::sleep; + +#[derive(Debug, PartialEq)] +enum Done { + RunServer, + SendValue, + Test, +} + +const TEST_READING: Reading = Reading::LargeBedroom( + large_bedroom::Reading::Bed(bed::Reading::NumberPm2_5(0.0)), +); +const TEST_AFFECTOR: Affector = Affector::LargeBedroom( + large_bedroom::Affector::Bed(bed::Affector::ResetNode), +); + +async fn run_server( + client_addr: impl Into, + data_port: impl Into, +) -> Result { + let (tx, rx) = mpsc::channel(2000); + let affectors = AffectorRegistar::default(); + select! { + e = server::client::handle(client_addr.into(), tx.clone(), affectors.clone()) => e.unwrap(), + e = server::handle_nodes(data_port.into(), &tx, affectors) => e.unwrap(), + e = server::handle_updates(rx) => e?, + }; + + Ok(Done::RunServer) +} + +async fn send_sensor_value(data_port: u16) -> Result { + tokio::time::sleep(Duration::from_millis(400)).await; + + let mut list = protocol::affector::ListMessage::<50>::empty(); + list.values + .push(protocol::Affector::LargeBedroom( + large_bedroom::Affector::Bed(bed::Affector::Sps30FanClean), + )) + .unwrap(); + let handshake = protocol::Msg::AffectorList(list).encode(); + + let mut conn = TcpStream::connect(("127.0.0.1", data_port)).await.unwrap(); + conn.write_all(&handshake).await.unwrap(); + + let mut sensor_msg = protocol::SensorMessage::<50>::default(); + sensor_msg.values.push(TEST_READING).unwrap(); + let sensor_msg = protocol::Msg::Readings(sensor_msg).encode(); + conn.write_all(&sensor_msg).await.unwrap(); + + sleep(Duration::from_secs(999)).await; + Ok(Done::SendValue) +} + +async fn subscribe_and_receive_inner(sub_port: u16) -> Result { + tokio::time::sleep(Duration::from_millis(100)).await; + let mut sub = Client::connect( + (Ipv4Addr::LOCALHOST, sub_port), + "api_integration_tests".to_owned(), + ) + .await + .unwrap() + .subscribe() + .await + .unwrap(); + + let received = sub.next().await.unwrap(); + assert!(matches!(received, SubMessage::Reading(TEST_READING))); + + Ok(Done::Test) +} + +async fn list_affectors_inner(sub_port: u16) -> Result { + tokio::time::sleep(Duration::from_millis(500)).await; + let list = Client::connect( + (Ipv4Addr::LOCALHOST, sub_port), + "api_integration_tests".to_owned(), + ) + .await + .unwrap() + .list_affectors() + .await + .unwrap(); + + assert_eq!( + list, + [protocol::Affector::LargeBedroom( + large_bedroom::Affector::Bed(bed::Affector::Sps30FanClean) + )] + ); + + Ok(Done::Test) +} + +#[tokio::test] +async fn subscribe_and_receive() { + logger::tracing::setup_for_tests(); + + let sub_port = reserve_port::ReservedPort::random().unwrap(); + let data_port = reserve_port::ReservedPort::random().unwrap(); + let res = select! { + e = run_server(([127,0,0,1], sub_port.port()), ([127,0,0,1], data_port.port())) => e, + e = send_sensor_value(data_port.port()) => e, + e = subscribe_and_receive_inner(sub_port.port()) => e, + }; + assert_eq!(res.unwrap(), Done::Test); +} + +#[tokio::test] +async fn list_affectors() { + logger::tracing::setup_for_tests(); + + let sub_port = reserve_port::ReservedPort::random().unwrap(); + let data_port = reserve_port::ReservedPort::random().unwrap(); + let res = select! { + e = run_server(([127,0,0,1], sub_port.port()), ([127,0,0,1], data_port.port())) => e, + e = send_sensor_value(data_port.port()) => e, + e = list_affectors_inner(sub_port.port()) => e, + }; + assert_eq!(res.unwrap(), Done::Test); +} + +async fn trigger_affector(sub_port: u16) -> Result { + tokio::time::sleep(Duration::from_millis(100)).await; + let mut client = Client::connect( + (Ipv4Addr::LOCALHOST, sub_port), + "api_integration_tests".to_owned(), + ) + .await + .unwrap(); + + client.actuate_affector(TEST_AFFECTOR).await.unwrap(); + Ok(pending::().await) +} + +async fn recv_affector_order(data_port: u16) -> Result { + let (tx, mut rx) = mpsc::channel(2); + let _client = data_source::reconnecting::Client::new( + (Ipv4Addr::LOCALHOST, data_port), + vec![TEST_AFFECTOR], + Some(tx), + ) + .await + .unwrap(); + + let affector_order = + tokio::time::timeout(Duration::from_secs(1), rx.recv()) + .await + .unwrap() + .unwrap(); + + assert_eq!(affector_order, TEST_AFFECTOR); + + Ok(Done::Test) +} + +#[tokio::test] +async fn recv_affector() { + logger::tracing::setup_for_tests(); + + let sub_port = reserve_port::ReservedPort::random().unwrap(); + let data_port = reserve_port::ReservedPort::random().unwrap(); + let res = select! { + e = run_server(([127,0,0,1], sub_port.port()), ([127,0,0,1], data_port.port())) => e, + e = recv_affector_order(data_port.port()) => e, + e = trigger_affector(sub_port.port()) => e, + }; + assert_eq!(res.unwrap(), Done::Test); +} diff --git a/crates/data-server/tests/subscriber_api.rs b/crates/data-server/tests/subscriber_api.rs new file mode 100644 index 00000000..be166ee4 --- /dev/null +++ b/crates/data-server/tests/subscriber_api.rs @@ -0,0 +1,153 @@ +use std::net::{Ipv4Addr, SocketAddr}; +use std::time::Duration; + +use color_eyre::Result; +use data_server::api::subscriber::{Client, SubMessage}; +use data_server::server::{self, AffectorRegistar}; +use protocol::large_bedroom; +use protocol::large_bedroom::bed; +use protocol::Reading; +use tokio::io::AsyncWriteExt; +use tokio::net::TcpStream; +use tokio::select; +use tokio::sync::mpsc; +use tokio::time::sleep; + +#[derive(Debug, PartialEq)] +enum Done { + RunServer, + SendValue, + Test, +} + +async fn run_server( + client_addr: impl Into, + data_port: impl Into, +) -> Result { + let (tx, rx) = mpsc::channel(2000); + let affectors = AffectorRegistar::default(); + select! { + e = server::client::handle(client_addr.into(), tx.clone(), affectors.clone()) => e.unwrap(), + e = server::handle_nodes(data_port.into(), &tx, affectors) => e.unwrap(), + e = server::handle_updates(rx) => e?, + }; + + Ok(Done::RunServer) +} + +const TEST_READING: Reading = + Reading::LargeBedroom(large_bedroom::Reading::Bed(bed::Reading::NumberPm2_5(0.0))); + +async fn send_sensor_value(data_port: u16) -> Result { + tokio::time::sleep(Duration::from_millis(500)).await; + + let mut list = protocol::affector::ListMessage::<50>::empty(); + list.values + .push(protocol::Affector::LargeBedroom( + large_bedroom::Affector::Bed(bed::Affector::Sps30FanClean), + )) + .unwrap(); + let handshake = protocol::Msg::AffectorList(list).encode(); + + let mut conn = TcpStream::connect(("127.0.0.1", data_port)).await.unwrap(); + conn.write_all(&handshake).await.unwrap(); + + let mut sensor_msg = protocol::SensorMessage::<50>::default(); + sensor_msg.values.push(TEST_READING).unwrap(); + let sensor_msg = protocol::Msg::Readings(sensor_msg).encode(); + conn.write_all(&sensor_msg).await.unwrap(); + + sleep(Duration::from_secs(999)).await; + Ok(Done::SendValue) +} + +async fn subscribe_and_receive_inner(sub_port: u16) -> Result { + tokio::time::sleep(Duration::from_millis(100)).await; + let mut sub = Client::connect( + (Ipv4Addr::LOCALHOST, sub_port), + "api_integration_tests".to_owned(), + ) + .await + .unwrap() + .subscribe() + .await + .unwrap(); + + let received = sub.next().await.unwrap(); + assert!(matches!(received, SubMessage::Reading(TEST_READING))); + + Ok(Done::Test) +} + +async fn list_affectors_inner(sub_port: u16) -> Result { + tokio::time::sleep(Duration::from_millis(1000)).await; + let list = Client::connect( + (Ipv4Addr::LOCALHOST, sub_port), + "api_integration_tests".to_owned(), + ) + .await + .unwrap() + .list_affectors() + .await + .unwrap(); + + assert_eq!( + list, + [protocol::Affector::LargeBedroom( + large_bedroom::Affector::Bed(bed::Affector::Sps30FanClean) + )] + ); + + Ok(Done::Test) +} + +#[tokio::test] +async fn subscribe_and_receive() { + setup_tracing(); + + let sub_port = reserve_port::ReservedPort::random().unwrap(); + let data_port = reserve_port::ReservedPort::random().unwrap(); + let res = select! { + e = run_server(([127,0,0,1], sub_port.port()), ([127,0,0,1], data_port.port())) => e, + e = send_sensor_value(data_port.port()) => e, + e = subscribe_and_receive_inner(sub_port.port()) => e, + }; + assert_eq!(res.unwrap(), Done::Test); +} + +#[tokio::test] +async fn list_affectors() { + setup_tracing(); + + let sub_port = reserve_port::ReservedPort::random().unwrap(); + let data_port = reserve_port::ReservedPort::random().unwrap(); + let res = select! { + e = run_server(([127,0,0,1], sub_port.port()), ([127,0,0,1], data_port.port())) => e, + e = send_sensor_value(data_port.port()) => e, + e = list_affectors_inner(sub_port.port()) => e, + }; + assert_eq!(res.unwrap(), Done::Test); +} + +fn setup_tracing() { + use std::sync::Once; + use tracing_error::ErrorLayer; + use tracing_subscriber::{self, layer::SubscriberExt, util::SubscriberInitExt, Layer}; + + static INIT: Once = Once::new(); + + INIT.call_once(|| { + color_eyre::install().unwrap(); + + let file_subscriber = tracing_subscriber::fmt::layer() + .with_file(true) + .with_line_number(true) + .with_target(false) + .with_ansi(false) + .with_filter(tracing_subscriber::filter::EnvFilter::from_default_env()); + tracing_subscriber::registry() + .with(file_subscriber) + .with(ErrorLayer::default()) + .init(); + }) +} diff --git a/crates/data-store/.cargo/config.toml b/crates/data-store/.cargo/config.toml new file mode 100644 index 00000000..1002fed4 --- /dev/null +++ b/crates/data-store/.cargo/config.toml @@ -0,0 +1,2 @@ +[target.aarch64-unknown-linux-musl] +rustflags = ["-Clinker=rust-lld"] diff --git a/crates/data-store/Cargo.toml b/crates/data-store/Cargo.toml new file mode 100644 index 00000000..69fd6223 --- /dev/null +++ b/crates/data-store/Cargo.toml @@ -0,0 +1,45 @@ +[package] +name = "data-store" +version = "0.1.0" +rust-version.workspace = true +edition.workspace = true +license.workspace = true +authors.workspace = true + +[features] +api = [] +server = [] +export = [] +default = ["api", "server", "export"] + +[dependencies] +clap = { workspace = true } +color-eyre = { workspace = true } +logger.workspace = true +tracing = { workspace = true } +tracing-error = { workspace = true } +tracing-subscriber = { workspace = true, features = ["env-filter"] } +jiff = { workspace =true, features = ["serde"] } +rpc = { workspace = true } + +protocol = { workspace = true, features = ["alloc", "thiserror"] } +data-server = { workspace = true } + +byteseries = { workspace = true } +tokio = { workspace = true, features = ["fs", "net", "rt-multi-thread", "sync"] } +futures-concurrency = { workspace = true } +serde.workspace = true +thiserror = { workspace = true } +futures.workspace = true +smallvec.workspace = true +num = "0.4.3" +ron.workspace = true +indicatif = "0.17.9" +itertools.workspace = true +rstest = "0.25" + +[dev-dependencies] +futures-concurrency.workspace = true +nucleo-matcher = "0.3.1" +reserve-port.workspace = true +temp-dir = "0.1.13" diff --git a/crates/data-store/deploy.sh b/crates/data-store/deploy.sh new file mode 100755 index 00000000..f91b103d --- /dev/null +++ b/crates/data-store/deploy.sh @@ -0,0 +1,19 @@ +#!/usr/bin/env bash +set -e + +BUILD_ARG=--release +SERVER="sgc" # ssh config name or full address +NAME=data-store + +cargo build --target=aarch64-unknown-linux-musl $BUILD_ARG +rsync -vh --progress \ + ../../target/aarch64-unknown-linux-musl/release/$NAME \ + $SERVER:/tmp/ + +cmds=" +sudo mv /tmp/$NAME /home/ha/$NAME +sudo chown ha:ha /home/ha/$NAME +sudo systemctl restart $NAME.service +" + +ssh -t $SERVER "$cmds" diff --git a/crates/data-store/examples/last_15m.rs b/crates/data-store/examples/last_15m.rs new file mode 100644 index 00000000..e13b643a --- /dev/null +++ b/crates/data-store/examples/last_15m.rs @@ -0,0 +1,67 @@ +use jiff::ToSpan; +use nucleo_matcher::pattern::Pattern; +use protocol::Reading; +use std::net::SocketAddr; + +use data_store::api::Client; +use nucleo_matcher::pattern::{AtomKind, CaseMatching, Normalization}; + +use clap::Parser; + +#[derive(Parser)] +#[command(version, about, long_about = None)] +struct Cli { + /// the address of the store + #[arg(short, long, default_value_t = SocketAddr::from(([127,0,0,1], 1236)))] + addr: SocketAddr, + reading: String, +} + +fn to_path(reading: &Reading) -> String { + let path = format!("{:?}", reading); + let (path, _) = path.rsplit_once('(').unwrap(); + let path = path.replace('(', " "); + path +} + +#[tokio::main] +async fn main() { + let cli = Cli::parse(); + let mut client = Client::connect(cli.addr, "data_store_example".to_owned()) + .await + .unwrap(); + let readings = client.list_data().await.unwrap(); + + let mut matcher = nucleo_matcher::Matcher::new(nucleo_matcher::Config::DEFAULT); + let pattern = Pattern::new( + &cli.reading, + CaseMatching::Ignore, + Normalization::Smart, + AtomKind::Fuzzy, + ); + + let mut buf = Vec::new(); + let best_scored = readings + .into_iter() + .map(|r| { + ( + pattern.score( + nucleo_matcher::Utf32Str::new(to_path(&r).as_str(), &mut buf), + &mut matcher, + ), + r, + ) + }) + .max_by_key(|(score, _)| score.unwrap_or(0)) + .unwrap() + .1; + + println!("Showing results for: {best_scored:?}"); + let now = jiff::Timestamp::now(); + let data = client + .get_data(now - 5.minutes(), now, best_scored, 10) + .await + .unwrap(); + + eprintln!("{:?}", data); +} diff --git a/crates/data-store/src/api.rs b/crates/data-store/src/api.rs new file mode 100644 index 00000000..b35edb69 --- /dev/null +++ b/crates/data-store/src/api.rs @@ -0,0 +1,61 @@ +use std::time::Duration; + +use protocol::Reading; + +use serde::{Deserialize, Serialize}; + +pub mod client; +pub use client::Client; + +#[derive(Debug, Clone, Serialize, Deserialize)] +pub(crate) enum Request { + ListData, + GetData { + reading: Reading, + start: jiff::Timestamp, + end: jiff::Timestamp, + n: usize, + }, +} + +#[derive(Debug, Clone, Serialize, Deserialize, thiserror::Error)] +pub enum ServerError { + #[error("We do not have any data for this reading: {reading:?}")] + NotInStore { reading: Reading }, + #[error("Internal error while reading data, error: {0}")] + ReadingFromStore(String), + #[error("Connect request should only be send once")] + AlreadyConnected, + #[error("Too many requests, rate limited, next requested allowed in: {0:?}")] + TooManyRequests(Duration), +} + +#[derive(Debug, Clone, Serialize, Deserialize)] +pub struct Data { + pub time: Vec, + pub values: Vec, +} + +#[derive(Debug, Clone, Serialize, Deserialize)] +pub(crate) enum Response { + ListData(Vec), + GetData(Result), + Error(ServerError), + Handshake, +} + +#[derive(Debug, Clone, Serialize, Deserialize, thiserror::Error)] +pub enum GetDataError { + #[error("could not find timestamp in this series")] + NotFound, + #[error("data file is empty")] + EmptyFile, + #[error("no data to return as the start time is after the last time in the data")] + StartAfterData, + #[error("no data to return as the stop time is before the data")] + StopBeforeData, + #[error("We do not have any data for this reading: {reading:?}")] + NotInStore { reading: Reading }, + #[error("Internal error while reading data, error: {0}")] + ReadingFromStore(String), +} diff --git a/crates/data-store/src/api/client.rs b/crates/data-store/src/api/client.rs new file mode 100644 index 00000000..5e1455f8 --- /dev/null +++ b/crates/data-store/src/api/client.rs @@ -0,0 +1,74 @@ +pub use rpc::client::{RpcError, ConnectError}; +use rpc::client::RpcClient; +use tokio::net::ToSocketAddrs; + +use super::Response; +use crate::api; + +#[derive(Debug, thiserror::Error)] +pub enum Error { + #[error("Server ran into an specific error with our request: {0}")] + Request(T), + #[error("Error while communicating with server: {0}")] + Comms(#[from] RpcError), +} + +pub struct Client(rpc::client::RpcClient); + +impl Client { + pub async fn connect( + addr: impl ToSocketAddrs, + name: String, + ) -> Result { + let rpc_client = RpcClient::connect(addr, name).await?; + Ok(Self(rpc_client)) + } + + pub async fn list_data(&mut self) -> Result, RpcError> { + let request = super::Request::ListData; + match self.0.send_receive(request.clone()).await? { + Response::ListData(list) => Ok(list), + response => Err(RpcError::IncorrectResponse { + request: format!("{request:?}"), + response: format!("{response:?}"), + }), + } + } + + pub async fn get_data( + &mut self, + start: jiff::Timestamp, + end: jiff::Timestamp, + reading: protocol::Reading, + n: usize, + ) -> Result> { + let request = super::Request::GetData { + reading, + start, + end, + n, + }; + match self.0.send_receive(request.clone()).await? { + Response::GetData(Ok(data)) => Ok(data), + Response::GetData(Err(err)) => Err(Error::Request(err)), + response => Err(Error::Comms(RpcError::IncorrectResponse { + request: format!("{request:?}"), + response: format!("{response:?}"), + })), + } + } +} + +#[derive(Debug, thiserror::Error)] +pub enum GetDataError { + #[error("could not find timestamp in this series")] + NotFound, + #[error("data file is empty")] + EmptyFile, + #[error("no data to return as the start time is after the last time in the data")] + StartAfterData, + #[error("no data to return as the stop time is before the data")] + StopBeforeData, + #[error("Error while communicating with server: {0}")] + Comms(#[from] RpcError), +} diff --git a/crates/data-store/src/data.rs b/crates/data-store/src/data.rs new file mode 100644 index 00000000..101a12c9 --- /dev/null +++ b/crates/data-store/src/data.rs @@ -0,0 +1,68 @@ +use std::collections::HashMap; +use std::sync::Arc; + +use tokio::sync::Mutex; + +pub mod series; +use series::Series; + +use crate::api; + +#[derive(Debug, Clone)] +pub(crate) struct Data( + pub(crate) Arc>>, +); + +impl Data { + pub(crate) async fn list_readings(&self) -> Vec { + self.0 + .lock() + .await + .keys() + .flat_map(|dev| dev.info().affects_readings) + .cloned() + .collect() + } + pub(crate) async fn get( + &self, + reading: protocol::Reading, + start: jiff::Timestamp, + end: jiff::Timestamp, + n: usize, + ) -> Result { + use byteseries::seek::Error as Se; + use byteseries::series::Error as Be; + + let key = reading.device(); + let mut all_series = self.0.lock().await; + let series = all_series.get_mut(&key).ok_or_else(|| { + api::GetDataError::NotInStore { + reading: reading.clone(), + } + })?; + + let (time, mut data) = + series + .read(&[reading], start, end, n) + .map_err(|e| match e { + Be::InvalidRange(Se::NotFound) => { + api::GetDataError::NotFound + } + Be::InvalidRange(Se::EmptyFile) => { + api::GetDataError::EmptyFile + } + Be::InvalidRange(Se::StartAfterData { .. }) => { + api::GetDataError::StartAfterData + } + Be::InvalidRange(Se::StopBeforeData) => { + api::GetDataError::StopBeforeData + } + _ => api::GetDataError::ReadingFromStore(e.to_string()), + })?; + Ok(api::Data { + time, + values: data.pop().expect("one reading is put in so one comes out"), + }) + } + +} diff --git a/crates/data-store/src/data/series.rs b/crates/data-store/src/data/series.rs new file mode 100644 index 00000000..56dd38f7 --- /dev/null +++ b/crates/data-store/src/data/series.rs @@ -0,0 +1,487 @@ +use std::fs::create_dir_all; +use std::io; +use std::path::{Path, PathBuf}; +use std::time::{Duration, Instant}; + +use byteseries::{downsample, series, ByteSeries}; +use color_eyre::eyre::{eyre, OptionExt, WrapErr}; +use color_eyre::{Result, Section}; +use protocol::reading::tree::{Item, Tree}; +use protocol::{reading, IsSameAs}; +use serde::{Deserialize, Serialize}; +use tracing::{instrument, trace}; + +use byteseries::file::OpenError as FileOpenError; +use series::data::OpenError as DataOpenError; +use series::Error::Open; + +pub mod bitspec; +mod resampler; + +use self::resampler::Resampler; + +use super::Data; + +#[derive(Debug)] +pub(crate) struct Meta { + pub(crate) reading: protocol::Reading, + pub(crate) field: bitspec::Field, + set_at: Option, +} + +#[derive(Debug)] +pub(crate) struct Series { + line: Vec, + meta_list: Vec, + last_timestamp_pushed: Option, + byteseries: ByteSeries, +} + +#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)] +pub(crate) struct Header { + pub(crate) readings: Vec, + pub(crate) encoding: Vec>, +} + +impl Header { + pub(crate) fn serialized(&self) -> Result> { + let config = ron::ser::PrettyConfig::new(); + ron::ser::to_string_pretty(self, config) + .map(|s| s.into_bytes()) + .wrap_err("Could not serialize header") + } +} + +impl Series { + #[instrument] + fn open_or_create(reading: &protocol::Reading, dir: &Path) -> Result { + let readings = reading.device().info().affects_readings; + let specs = to_speclist(readings); + let fields = bitspec::speclist_to_fields(specs); + let (meta_list, payload_size) = + meta_list_and_payload_size(readings, &fields); + + let expected_header = Header { + readings: readings.to_vec(), + encoding: fields.clone(), + } + .serialized()?; + + let (resampler, configs) = resample_setup(&fields, payload_size); + + let path = base_path(reading); + let path = dir.join(path); + let res = ByteSeries::builder() + .payload_size(payload_size) + .with_downsampled_cache(resampler.clone(), configs.clone()) + .with_header(expected_header.clone()) + .open(&path); + + let byteseries = match res { + Ok((byteseries, _)) => byteseries, + Err(Open(DataOpenError::File { + source: FileOpenError::Io(e), + .. + })) if e.kind() == io::ErrorKind::NotFound => { + if let Some(dirs) = path.parent() { + create_dir_all(dirs) + .wrap_err("Could not create dirs structure for reading") + .with_note(|| format!("dirs: {}", dirs.display()))?; + } + + ByteSeries::builder() + .payload_size(payload_size) + .with_downsampled_cache(resampler, configs) + .with_header(expected_header) + .create_new(true) + .open(&path) + .wrap_err("Could not create new byteseries") + .with_note(|| format!("path: {}", path.display())) + .map(|(db, _)| db)? + } + Err(e) => { + return Err(e) + .wrap_err("Could not open existing byteseries") + .with_note(|| format!("path: {}", path.display()))? + } + }; + + Ok(Self { + line: vec![0; payload_size], + meta_list, + last_timestamp_pushed: None, + byteseries, + }) + } + + #[instrument(skip(self))] + fn append(&mut self, reading: &protocol::Reading) -> Result<()> { + let res = reading + .device() + .info() + .affects_readings + .iter() + .map(|r| r.info().branch_id) + .position(|id_in_list| id_in_list == reading.info().branch_id); + let index = wrap_inder_err(res, reading)?; + + let meta = &mut self.meta_list[index]; + if !reading.info().range.contains(&reading.info().val) { + return Err(eyre!( + "value {} is out of range: {:?}", + reading.info().val, + reading.info().range + )); + } + + meta.field.encode(reading.info().val, &mut self.line); + meta.set_at = Some(Instant::now()); + + let max_interval = reading.device().info().max_sample_interval; + + if self + .meta_list + .iter() + .map(|Meta { set_at, .. }| set_at) + .all(|set| set.is_some_and(|set| set.elapsed() < max_interval)) + { + let time = jiff::Timestamp::now(); + + let device_info = reading.info().device.info(); + let scale_factor = millis_to_minimal_representation(device_info); + let scaled_time = time.as_millisecond() as u64 / scale_factor; + let new_ts = scaled_time; + + if self.last_timestamp_pushed.is_some_and(|ts| ts == new_ts) { + tracing::trace!("Skipping datapoint with same timestamp"); + return Ok(()); + } else { + self.last_timestamp_pushed = Some(new_ts); + } + + self.byteseries + .push_line(new_ts, &self.line) + .wrap_err("Could not write to timeseries on disk")?; + self.line.fill(0); + + for meta in &mut self.meta_list { + meta.set_at = None; + } + } + + Ok(()) + } + + /// # Panics + /// If any of the requested readings are not part of this series. + #[instrument(skip(self))] + pub fn read( + &mut self, + readings: &[protocol::Reading], + start: jiff::Timestamp, + end: jiff::Timestamp, + n: usize, + ) -> Result<(Vec, Vec>), byteseries::series::Error> + { + let device_info = readings + .first() + .expect("There is at least one reading to read") + .info() + .device + .info(); + let scale_factor = millis_to_minimal_representation(device_info); + let start = start.as_millisecond() as u64 / scale_factor; + let end = end.as_millisecond() as u64 / scale_factor; + let range = start..=end; + let fields = readings + .iter() + .map(|requested| { + self.meta_list + .iter() + .find(|meta| requested.is_same_as(&meta.reading)) + .inspect(|meta| trace!("meta used for decoding: {meta:?}")) + .map(|meta| meta.field.clone()) + .unwrap_or_else(|| { + panic!( + "caller of read makes sure all readings are part of this \ + series.\n\tseries: {:?},\n\trequested: {:?}", + self.meta_list, readings + ) + }) + }) + .collect(); + let mut resampler = Resampler::from_fields(fields, self.line.len()); + + let mut timestamps = Vec::with_capacity(n * 2); + let mut interleaved_data = Vec::with_capacity(n * 2); + + self.byteseries.read_n( + n, + range, + &mut resampler, + &mut timestamps, + &mut interleaved_data, + false, + )?; + + let time = timestamps + .into_iter() + .map(|ts| { + let millis = ts * scale_factor; + jiff::Timestamp::from_millisecond(millis as i64) + .expect("timestamps are between MIN and MAX times of Timestamp type") + }) + .collect(); + + let len = interleaved_data + .first() + .expect("read returns an error if there is not data") + .len(); + let mut data = vec![Vec::new(); len]; + for interleaved in interleaved_data { + for (interleaved, data) in + interleaved.into_iter().zip(data.iter_mut()) + { + data.push(interleaved); + } + } + Ok((time, data)) + } +} + +fn wrap_inder_err( + res: Option, + reading: &protocol::Reading, +) -> Result { + res.ok_or_eyre( + "Could not find reading index, branch id does not match + any in readings affected by the device", + ) + .suggestion("In protocol lib, is every reading variant in the affected readings list?") + .with_note(|| format!("reading: {reading:?}")) + .with_note(|| format!("reading branch id: {:?}", reading.info().branch_id)) + .with_note(|| { + format!( + "affected readings: {:?}", + reading + .device() + .info() + .affects_readings + .into_iter() + .map(|r| r.info()) + .collect::>() + ) + }) +} + +pub(crate) fn meta_list_and_payload_size( + readings: &[protocol::Reading], + fields: &[bitspec::Field], +) -> (Vec, usize) { + let meta = readings + .iter() + .zip(fields.iter()) + .map(|(reading, field)| Meta { + reading: reading.clone(), + field: field.clone(), + set_at: None, + }) + .collect(); + + let payload_size = fields + .iter() + .map(|spec| spec.length as usize) + .sum::() + .div_ceil(8); + (meta, payload_size) +} + +/// Scaling factor, when applied to milliseconds it returns some other +/// unit that is the most minimal representation of time for this device. +/// +/// Example given a device with +/// - minimal sample interval 5 seconds +/// - the temporal_resolution 10 seconds +/// We only need to store something every 5 seconds and we can be up to 5 +/// seconds off in both directions. Thus one 'minimal representation unit' is +/// 5 seconds +pub fn millis_to_minimal_representation( + device_info: protocol::DeviceInfo, +) -> u64 { + assert!( + device_info.min_sample_interval > Duration::ZERO, + "min sample interval may not be zero, device info: {device_info:?}" + ); + let needed_interval = device_info + .temporal_resolution + .min(device_info.min_sample_interval) + .as_secs_f32(); + let mul_factor = 0.001 / needed_interval; + let div_factor = 1. / mul_factor; + let factor = div_factor.round() as u64; + assert_ne!(factor, 0); + factor +} + +#[instrument(level = "debug", skip(data))] +pub(crate) async fn store( + data: &Data, + reading: &protocol::Reading, + data_dir: &Path, +) -> Result<()> { + let mut data = data.0.lock().await; + + let key = reading.device(); + if let Some(series) = data.get_mut(&key) { + series + .append(reading) + .wrap_err("failed to append to existing timeseries")?; + } else { + let mut series = Series::open_or_create(reading, data_dir) + .wrap_err("Could not open new series") + .with_note(|| format!("reading was: {reading:?}"))?; + series + .append(reading) + .wrap_err("failed to newly created timeseries")?; + let existing = data.insert(key, series); + assert!(existing.is_none(), "should not race we still hold the lock"); + } + trace!("stored new reading"); + + Ok(()) +} + +pub(crate) fn to_speclist(readings: &[protocol::Reading]) -> Vec { + readings + .iter() + .map(|r| bitspec::RangeWithRes { + range: r.range(), + resolution: r.resolution(), + }) + .map(bitspec::LengthWithOps::from) + .collect() +} + +/// relative path without extension +fn base_path(reading: &protocol::Reading) -> PathBuf { + let mut parts = Vec::new(); + let mut current = reading as &dyn Tree; + loop { + match current.inner() { + Item::Leaf(reading::Info { device, .. }) => { + parts.push(device.info().name.to_lowercase()); + break; + } + Item::Node(inner) => { + parts.push(current.name().to_lowercase()); + current = inner; + continue; + } + } + } + parts.into_iter().collect() +} + +fn resample_setup( + fields: &[bitspec::Field], + payload_size: usize, +) -> (Resampler, Vec) { + let resampler = Resampler::from_fields(fields.to_vec(), payload_size); + let resample_configs = vec![ + downsample::Config { + max_gap: None, + bucket_size: 10, + }, + downsample::Config { + max_gap: None, + bucket_size: 100, + }, + downsample::Config { + max_gap: None, + bucket_size: 1000, + }, + ]; + (resampler, resample_configs) +} + +#[cfg(test)] +mod test { + use super::*; + use protocol::large_bedroom::{bed, desk}; + use protocol::{large_bedroom, Reading}; + + #[test] + #[should_panic(expected = "min sample interval may not be zero")] + fn millis_to_minimal_representation_factor_is_not_zero() { + let info = protocol::DeviceInfo { + name: "test", + affects_readings: &[], + min_sample_interval: std::time::Duration::ZERO, + max_sample_interval: std::time::Duration::MAX, + temporal_resolution: std::time::Duration::from_secs(5), + affectors: &[], + }; + let factor = millis_to_minimal_representation(info); + assert_eq!(5000 / factor, 5); + } + + #[test] + fn millis_to_minimal_representation_factor_makes_sense() { + let info = protocol::DeviceInfo { + name: "test", + affects_readings: &[], + min_sample_interval: std::time::Duration::from_secs(5), + max_sample_interval: std::time::Duration::from_secs(5), + temporal_resolution: std::time::Duration::from_secs(1), + affectors: &[], + }; + let factor = millis_to_minimal_representation(info); + assert_eq!(5000 / factor, 5); + + let info = protocol::DeviceInfo { + name: "test", + affects_readings: &[], + min_sample_interval: std::time::Duration::from_secs(5), + max_sample_interval: std::time::Duration::from_secs(5), + temporal_resolution: std::time::Duration::from_millis(1), + affectors: &[], + }; + let factor = millis_to_minimal_representation(info); + assert_eq!(5005 / factor, 5005) + } + + #[test] + fn readings_from_same_device_have_same_path() { + let reading_a = Reading::LargeBedroom(large_bedroom::Reading::Bed( + bed::Reading::Temperature(0.0), + )); + let reading_b = Reading::LargeBedroom(large_bedroom::Reading::Bed( + bed::Reading::Humidity(0.0), + )); + + assert_eq!(base_path(&reading_a), base_path(&reading_b)); + } + + #[test] + fn reading_path_different_between_locations() { + let reading_a = Reading::LargeBedroom(large_bedroom::Reading::Bed( + bed::Reading::Humidity(0.0), + )); + let reading_b = Reading::LargeBedroom(large_bedroom::Reading::Desk( + desk::Reading::Humidity(0.0), + )); + + assert_ne!(base_path(&reading_a), base_path(&reading_b)); + } + + #[test] + fn reading_path_is_expected() { + let reading = Reading::LargeBedroom(large_bedroom::Reading::Bed( + bed::Reading::Humidity(0.0), + )); + assert_eq!( + base_path(&reading), + PathBuf::from("largebedroom/bed/sht31") + ); + } +} diff --git a/crates/data-store/src/data/series/bitspec.rs b/crates/data-store/src/data/series/bitspec.rs new file mode 100644 index 00000000..d8c7756f --- /dev/null +++ b/crates/data-store/src/data/series/bitspec.rs @@ -0,0 +1,6 @@ +mod compression; +mod field; +mod spec; + +pub use field::Field; +pub use spec::{LengthWithOps, RangeWithRes, speclist_to_fields}; diff --git a/crates/data-store/src/data/series/bitspec/compression.rs b/crates/data-store/src/data/series/bitspec/compression.rs new file mode 100644 index 00000000..12d0e5bb --- /dev/null +++ b/crates/data-store/src/data/series/bitspec/compression.rs @@ -0,0 +1,315 @@ +/// ```txt +/// array's with bytes in them follow Little Endian byte order +/// (not relevant) to the algo but might be nice to know. It can +/// get a little confusing given the lowest bit is printed right most +/// given these strange bit 1 is next to bit 16 situations. See diagram: +/// +/// byte 1 byte 2 byte 3 +/// [ 8|7|6|5|4|3|2|1, 16|15|14|13|12|11|10|9, 24|23|22|21|20|19|18|17 ] +/// |____________________________________________| +/// |________| encoded B +/// encoded lower part of B higher part of B +/// value stored in lower part stored in higher +/// A of byte 1 part of byte 3 +/// +/// B: length = 16, offest = 4, at byte 3 bits read = 12 +/// ``` + +#[inline] +#[allow(clippy::cast_possible_truncation)] +/// Decodes `length` bytes starting at `bit_offset` from `line`. +pub fn decode(line: &[u8], bit_offset: u8, length: u8) -> u32 { + let first_byte = (bit_offset / 8) as usize; + + // build mask to get lowest bits of first byte + let start_mask: u8 = !0 >> (bit_offset % 8); + // second mask for sources with length smaller then 8 bits + let start_mask = if length < (bit_offset % 8) { + start_mask & !(!0 << length) + } else { + start_mask + }; + + //decode first bit (never needs shifting (lowest part is used)) + let mut decoded: u32 = u32::from(line[first_byte] & start_mask); + let mut bits_read = (8 - (bit_offset % 8)).min(length); + + let last_byte_new = ((bit_offset + length).div_ceil(8)) as usize; + let last_byte_idx = last_byte_new - 1; + if length > 8 { + //decode middle bits, no masking needed + for byte in &line[first_byte + 1..last_byte_idx] { + decoded |= u32::from(*byte) << bits_read; + bits_read += 8; + } + } + + // build mask to get highest bits of last byte + let bits_still_needed = length - bits_read; + // shifting 8 bits to get mask 0b1111_1111 panics with `u8` + let end_mask = if bits_still_needed == 8 { + 0b1111_1111 + } else { + !(!0 >> bits_still_needed) + }; + + // let bits_in_last_byte = bits_still_needed; + let shift_back = 8 - bits_still_needed; + let shift_in_position = bits_read; + + decoded |= u32::from(line[last_byte_idx] & end_mask) >> shift_back + << shift_in_position; + + decoded +} + +#[inline] +#[allow(clippy::cast_possible_truncation)] +/// Encode the lower `length` bits of `to_encode` in a zero-ed byte slice +/// starting at the `bit_offset` bit. +/// +/// If `bit_offset` mod 8 is not zero this means we skip the that amount of +/// higher bits in the first byte used for encoding. Inversely +/// if `bit_offset` + `length` mod 8 is not zero that means we only use +/// that amount of lower bits of the last byte. +/// +/// # The first byte +/// Only using the free lower bits in the first byte is done by masking off +/// the higher part of the lower 8 bits of `to_encode`. That mask when AND-ed +/// makes the highest bits zero. Specifically the `bit_offset` mod 8 highest +/// bits are made zero. +/// +/// Then the remaining bits are shifted up such that they fill out the free +/// space in the highest bits of the first byte +/// +/// Example: store 8 bits starting at bit 4: +/// bit_offset: 4, used: 4 mod 8 = 4 +/// length: 8 +/// bits_in_first: 8 - (4 mod 8) = 4 +/// mask: 0b0000_1111 +/// shift: 4 up +/// +/// Example mask, store 4 bits starting at bit 5: +/// bit_offset: 5, used: 5 mod 8 = 5 +/// length: 4 +/// bits_in_first: 8 - (5 mod 8) = 3 +/// mask: 0b0000_0111 # Note how only 3 bits are selected +/// shift: 5 up +/// +/// # The last byte +/// We fit `bit_offest` mod 8 bits in the first byte, lets call that `bits_in_first`. +/// Then N * 8 more in the bytes in between the first and last byte used. This leaves +/// (`length` - `bits_in_first`) mod 8 bits to still encode. These are the highest +/// bits in `to_encode`. We again select them using a mask and AND. +/// +/// This mask is ones for the `bits_in_last` highest bits from `to_encode` and +/// zeros otherwise. Then the bits are shifted all the way down so they fit +/// the lower bits of the last byte in the slice used to store `to_encode`. +/// +/// Example: store 20 bits starting at bit 4 +/// bit_offset: 4 +/// length: 22 +/// bits_in_first: 4 +/// bits_in_last: (length - bits_in_first) mod 8 = 2 +/// mask: 0b0000_0000__0011_0000__0000_0000__0000_0000 +/// shift: 20 down +/// +/// Example: store 7 bits starting at bit 13 +/// bit_offset: 13 +/// length: 7 +/// bits_in_first: 8 - (5 mod 8) = 3 +/// bits_in_last: (length - bits_in_first) mod 8 = 4 +/// mask: 0b0000_0000__0000_0000__0000_0000__0111_1000 +/// shift: 7 down +/// +pub fn encode(to_encode: u32, line: &mut [u8], bit_offset: u8, length: u8) { + let start_mask = !0 >> (bit_offset % 8); + + let first_byte = (bit_offset / 8) as usize; + + //encode first bit (never needs shifting (lowest part is used)) + line[first_byte] |= (to_encode as u8) & start_mask; + let mut bits_written = (8 - (bit_offset % 8)).min(length); + + // this writes the last bit too when the offset + length is a multiple of 8 + // that is okay since then the byte is full used so no masking is needed. + let last_byte = ((bit_offset + length) / 8) as usize; + if length > 8 { + //decode middle bits, no masking needed + for byte in &mut line[first_byte + 1..last_byte] { + *byte |= (to_encode >> bits_written) as u8; + bits_written += 8; + } + } + + let used_bits = bit_offset + length - last_byte as u8 * 8; + let end_mask = !(!0 >> used_bits); + let last_byte = (bit_offset + length).div_ceil(8) as usize; //starts at 0 + + if bits_written < length { + // lets say to_encode is: 1100_0000_0000 + // and that 11 still needs to be encoded (bits written = 10, length = 12) + // then we should shift them all the way down (shift 10) and then up into + // the place where they are stored in the last byte. In this case the upper + // 2 bits. So shift back up 6. Total shift is 4 down/right or: + // + // bits_written 10 - (8 - bits to use in last byte) + // + // now if we encode is: 11 + // and only the left most (higher) 1 still needs to be encoded. But it + // will need to be encoded in the highest bit in the next byte. So it + // must be shifted 7 up/left. + let to_shift = bits_written as i16 - (8 - used_bits as i16); + if to_shift > 0 { + line[last_byte - 1] |= (to_encode >> to_shift) as u8 & end_mask; + } else { + line[last_byte - 1] |= + (to_encode << to_shift.abs()) as u8 & end_mask; + } + } +} + +#[cfg(test)] +mod tests { + use rstest::rstest; + + use super::*; + + #[test] + fn encode_and_decode_multiple_edge_case() { + let mut line = vec![0, 0, 0, 0, 0, 0, 0, 0]; + encode(1, &mut line, 0, 8); + + print!("binary repr: "); + for byte in &line { + print!("{:b}, ", byte); + } + println!(); + + encode(2, &mut line, 8, 8); + + print!("binary repr: "); + for byte in &line { + print!("{:b}, ", byte); + } + println!(); + + let decoded1 = decode(&line, 0, 8); + let decoded2 = decode(&line, 8, 8); + + println!("0-10 {} {:b}", decoded1, decoded1); + println!("10-20 {} {:b}", decoded2, decoded2); + assert_eq!(decoded1, 1); + assert_eq!(decoded2, 2); + } + + #[test] + fn encode_and_decode_edge_case() { + let test_case = u32::max_value(); + let mut line = vec![0, 0, 0, 0]; + encode(test_case, &mut line, 0, 32); + + print!("binary repr: "); + for byte in &line { + print!("{:b}, ", byte); + } + println!(); + + let decoded1 = decode(&line, 0, 32); + + println!("0-{} {} {:b}", 32, decoded1, decoded1); + assert_eq!(decoded1, test_case); + } + + #[test] + fn encode_and_decode_start_case() { + let test_case = 1023; + let mut line = vec![0, 0, 0, 0]; + encode(test_case, &mut line, 0, 10); + + print!("binary repr: "); + for byte in &line { + print!("{:b}, ", byte); + } + println!(); + + print!("array repr: "); + for byte in &line { + print!("{}, ", byte); + } + println!(); + + let decoded1 = decode(&line, 0, 10); + + println!("0-{} {} {:b}", 10, decoded1, decoded1); + assert_eq!(decoded1, test_case); + } + + #[rstest] + fn encode_and_decode_max( + #[values(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17)] + length: u8, + ) { + // > 2 bytes + for offset in 0..=16 { + let max_we_can_store = 2u32.pow(length as u32 - 1); + + let mut array = vec![0; 12]; + encode(max_we_can_store, array.as_mut_slice(), offset, length); + let decoded = decode(array.as_slice(), offset, length); + + assert_eq!(max_we_can_store, decoded, "should decode {max_we_can_store}, got {decoded}, \noffset: {offset},\nlength: {length}" + ); + } + } + + fn print_vec_bin(array: Vec) -> String { + let mut outstr = String::from("binary repr: "); + for byte in &array { + outstr.push_str(&format!("{:b}, ", byte)); + } + outstr.push_str("\n"); + outstr + } + + #[test] + fn encode_and_decode_various_numbers() { + for length in 8..32 { + for offset in 0..16 { + for _power in 0..length as u16 * 10 { + let power = _power as f32 * 0.1; + let mut array = vec![0; 8]; + let test_numb = 2f32.powf(power) as u32; + encode(test_numb, array.as_mut_slice(), offset, length); + + let decoded_test_numb = + decode(array.as_slice(), offset, length); + assert_eq!( + test_numb, + decoded_test_numb, + "offset: {}, length: {} {}", + offset, + length, + print_vec_bin(array) + ); + } + } + } + } + + #[test] + fn edge_case_1() { + let line = [206, 84, 2, 0]; + let offset = 13; + let length = 7; + decode(&line, offset, length); + } + + #[test] + fn edge_case_2() { + let line = [206, 84, 2, 0]; + let offset = 20; + let length = 2; + decode(&line, offset, length); + } +} diff --git a/crates/data-store/src/data/series/bitspec/field.rs b/crates/data-store/src/data/series/bitspec/field.rs new file mode 100644 index 00000000..3cb825cd --- /dev/null +++ b/crates/data-store/src/data/series/bitspec/field.rs @@ -0,0 +1,102 @@ +use serde::{Deserialize, Serialize}; + +use super::compression; + +#[derive(Debug, PartialEq, Clone, Serialize, Deserialize)] +pub struct Field { + pub offset: u8, //bits + pub length: u8, //bits (max 32 bit variables) + + pub decode_scale: T, + pub decode_add: T, +} + +#[allow(dead_code)] +impl Field +where + T: num::cast::NumCast + + core::ops::Add + + core::ops::SubAssign + + core::ops::DivAssign + + core::ops::MulAssign + + core::marker::Copy + + core::fmt::Display + + core::fmt::Debug, +{ + pub fn decode(&self, line: &[u8]) -> D + where + D: num::cast::NumCast + + core::fmt::Display + + core::ops::Add + + core::ops::SubAssign + + core::ops::MulAssign + + core::ops::AddAssign, + { + let int_repr: u32 = compression::decode(line, self.offset, self.length); + let mut decoded: D = num::cast(int_repr).unwrap(); + + decoded *= num::cast(self.decode_scale).unwrap(); //FIXME flip decode scale / and * + decoded += num::cast(self.decode_add).unwrap(); + + decoded + } + pub fn encode(&self, mut numb: T, line: &mut [u8]) + where + T: num::cast::NumCast + + core::fmt::Display + + core::ops::Add + + core::ops::SubAssign + + core::ops::AddAssign + + core::ops::DivAssign, + { + numb -= num::cast(self.decode_add).unwrap(); + numb /= num::cast(self.decode_scale).unwrap(); + + let to_encode: u32 = num::cast(numb).unwrap_or_else(|| { + panic!("could not cast numb to u32, numb: {numb}, field: {self:?}",) + }); + + compression::encode(to_encode, line, self.offset, self.length); + } +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn test() { + let fields = &[ + // Ble_reliability_testing_dataset + Field:: { + // Sine + decode_add: -5000.0000000000, + decode_scale: 1.0000000000, + length: 14, + offset: 0, + }, + Field:: { + // Triangle + decode_add: -10.0000000000, + decode_scale: 0.0500000007, + length: 10, + offset: 14, + }, + ]; + + for i in 0..100 { + let sine = -5000.0 + i as f32 * (5000.0 * 2.0) / 100.0; + let triangle = 20.0 - i as f32 * (20.0 + 10.0) / 100.0; + + let mut line = [0u8, 0, 0]; + fields[0].encode(sine, &mut line); + fields[1].encode(triangle, &mut line); + + let decoded_sine: f32 = fields[0].decode(&line); + let decoded_triangle: f32 = fields[1].decode(&line); + + assert!(sine - decoded_sine <= 1. + 0.001); + assert!(triangle - decoded_triangle <= 0.05 + 0.001); + } + } +} diff --git a/crates/data-store/src/data/series/bitspec/spec.rs b/crates/data-store/src/data/series/bitspec/spec.rs new file mode 100644 index 00000000..4bd37578 --- /dev/null +++ b/crates/data-store/src/data/series/bitspec/spec.rs @@ -0,0 +1,55 @@ +use std::ops::RangeInclusive; + +use serde::{Deserialize, Serialize}; + +use super::field::Field; + +#[derive(Debug, PartialEq, Clone, Serialize, Deserialize)] +pub struct RangeWithRes { + pub range: RangeInclusive, + pub resolution: f32, +} + +#[derive(Debug, PartialEq, Clone, Serialize, Deserialize)] +pub struct LengthWithOps { + pub(crate) length: u8, + pub(crate) decode_scale: f32, + pub(crate) decode_add: f32, +} + +impl From for LengthWithOps { + #[allow(clippy::cast_sign_loss, clippy::cast_possible_truncation)] + fn from(field: RangeWithRes) -> Self { + let given_range = field.range.end() - field.range.start(); + let needed_range = given_range / field.resolution; + let length = needed_range.log2().ceil() as u32; + let length = length.try_into().expect("max field length is 256 bits"); + let decode_scale = field.resolution; + + let decode_add = *field.range.start(); + LengthWithOps { + length, + decode_scale, + decode_add, + } + } +} + +pub fn speclist_to_fields(input: Vec) -> Vec> { + let mut res = Vec::new(); + + let mut start_bit = 0; + for field in input { + res.push(Field:: { + offset: start_bit, + length: field.length, + decode_scale: field.decode_scale, + decode_add: field.decode_add, + }); + start_bit = start_bit + .checked_add(field.length) + .expect("line longer the 256 bits are not supported"); + } + + res +} diff --git a/crates/data-store/src/data/series/resampler.rs b/crates/data-store/src/data/series/resampler.rs new file mode 100644 index 00000000..401a405a --- /dev/null +++ b/crates/data-store/src/data/series/resampler.rs @@ -0,0 +1,94 @@ +use super::bitspec; +use smallvec::smallvec; + +#[derive(Debug, Clone)] +pub(crate) struct Resampler { + pub(crate) fields: Vec>, + pub(crate) payload_size: usize, +} + +impl Resampler { + pub(crate) fn from_fields( + fields: Vec>, + payload_size: usize, + ) -> Self { + Self { + fields, + payload_size, + } + } +} + +impl byteseries::Resampler for Resampler { + type State = smallvec::SmallVec; + + fn state(&self) -> Self::State { + smallvec![0f32; self.fields.len()] + } +} + +impl byteseries::Decoder for Resampler { + type Item = smallvec::SmallVec; + + fn decode_payload(&mut self, payload: &[u8]) -> Self::Item { + self.fields + .iter() + .map(|field| field.decode(payload)) + .collect() + } +} + +impl byteseries::Encoder for Resampler { + type Item = smallvec::SmallVec; + + // PERF: should probably take a &mut[u8] instead of returning vec + // + fn encode_item(&mut self, item: &Self::Item) -> Vec { + let mut encoded = vec![0u8; self.payload_size]; + for (field, item) in self.fields.iter().zip(item) { + field.encode(*item, &mut encoded); + } + encoded + } +} + +#[cfg(test)] +mod test { + use byteseries::{Decoder, Encoder}; + use smallvec::SmallVec; + + use super::*; + + #[test] + fn decoded_is_correct() { + let reading = protocol::Reading::LargeBedroom( + protocol::large_bedroom::Reading::Bed( + protocol::large_bedroom::bed::Reading::Temperature(0.5), + ), + ); + + let readings = reading.device().info().affects_readings; + let specs = crate::data::series::to_speclist(readings); + let fields = bitspec::speclist_to_fields(specs); + + let payload_size = fields + .iter() + .map(|spec| spec.length as usize) + .sum::() + .div_ceil(8); + let mut resampler = + Resampler::from_fields(fields.clone(), payload_size); + let mut item: SmallVec = SmallVec::new(); + item.push(0.5f32); + item.push(0.5f32); + let bytes = resampler.encode_item(&item); + let decoded = resampler.decode_payload(&bytes); + assert!( + decoded + .iter() + .zip(item.clone()) + .all(|(a, b)| (a - b).abs() < 0.01), + "decoded and original different, decoded: {decoded:?}, org: {item:?}" + ); + } +} diff --git a/crates/data-store/src/export.rs b/crates/data-store/src/export.rs new file mode 100644 index 00000000..4159913b --- /dev/null +++ b/crates/data-store/src/export.rs @@ -0,0 +1,254 @@ +use std::ffi::OsStr; +use std::fs; +use std::fs::DirEntry; +use std::io::{ErrorKind, Read}; +use std::path::{Path, PathBuf}; +use std::sync::atomic::{AtomicUsize, Ordering}; +use std::sync::Arc; + +use byteseries::ByteSeries; +use color_eyre::eyre::{bail, Context, OptionExt, Result}; +use color_eyre::Section; +use indicatif::{MultiProgress, ProgressBar}; +use itertools::Itertools; +use protocol::reading::tree::Tree; +use protocol::Reading; +use tracing::warn; + +use crate::data::series; + +mod csv; +use csv::Csv; +mod decoder; +use decoder::ExportDecoder; + +pub fn perform(data_dir: &Path, only: Option) -> Result<()> { + let list = files_to_export(data_dir)?; + if list.is_empty() { + bail!("No files left to export") + } + + let to_handle: Vec<_> = list + .iter() + .filter(|p| { + only.as_ref().is_none_or(|allowed| { + p.ends_with(allowed) || p.with_extension("").ends_with(allowed) + }) + }) + .collect(); + + if to_handle.is_empty() { + return crate::no_filter_match_err(list, only); + } + + let bars = MultiProgress::new(); + let files_bar = + ProgressBar::new(to_handle.len() as u64).with_style(crate::bar_style()); + let files_bar = bars.insert(0, files_bar); + files_bar.inc(0); // make the bar appear + + for path in &to_handle { + handle_file(&path, bars.clone()) + .wrap_err("Failed to export data") + .with_note(|| format!("Input file: {}", path.display()))?; + files_bar.inc(1); + } + + drop(bars); + tracing::info!( + "Done, exported {} files to {}", + to_handle.len(), + data_dir.display() + ); + + Ok(()) +} + +pub fn handle_file(path: &Path, bars: MultiProgress) -> Result<()> { + let metadata = + read_metadata(path).wrap_err("Could not extract metadata")?; + let series::Header { readings, encoding } = + ron::from_str(&metadata).wrap_err("Could not deserialize metadata")?; + let (meta, payload_size) = + series::meta_list_and_payload_size(&readings, &encoding); + + let corrupt_sections_skipped = Arc::new(AtomicUsize::new(0)); + let callback = { + let corrupt_sections_skipped = corrupt_sections_skipped.clone(); + Box::new(move || { + corrupt_sections_skipped.fetch_add(1, Ordering::Relaxed); + true + }) + }; + let (input_series, _) = ByteSeries::builder() + .payload_size(payload_size) + .with_header(metadata.as_bytes().to_vec()) + .with_callback_on_recoverable_corruption(callback) + .open(path) + .wrap_err("Could not open byteseries")?; + + let decoder = ExportDecoder::from_fields( + meta.iter().map(|m| m.field.clone()).collect(), + ); + let output = Csv::open(&readings, path.with_extension("csv")) + .wrap_err("Failed to open output csv") + .suggestion("If the file already exists remove it")?; + + let copy_bar = ProgressBar::new(input_series.len()) + .with_style(crate::bar_style()) + .with_message(format!( + "{:?}", + path.file_name().expect("we only handle files with names") + )); + let copy_bar = bars.insert(1, copy_bar); + copy_over_content( + input_series, + decoder, + readings, + output, + copy_bar.clone(), + ) + .wrap_err("Failed to copy over content")?; + bars.remove(©_bar); + + let skipped = corrupt_sections_skipped.load(Ordering::Relaxed); + if skipped > 0 { + bars.suspend(|| { + warn!( + "Skipped {skipped} corrupt meta data sections and data from \ + that section until the next intact metadata section" + ) + }) + } + Ok(()) +} + +fn copy_over_content( + mut input_series: ByteSeries, + mut decoder: ExportDecoder, + readings: Vec, + mut output: Csv, + copy_bar: ProgressBar, +) -> Result<()> { + let mut read_start = 0; + let precisions = readings + .into_iter() + .map(|r| r.info().precision()) + .collect_vec(); + + loop { + let mut timestamps = Vec::new(); + let mut data = Vec::new(); + + if let Err(byteseries::series::Error::InvalidRange( + byteseries::seek::Error::StartAfterData { .. }, + )) = input_series.read_first_n( + 100_000, + &mut decoder, + read_start.., + &mut timestamps, + &mut data, + ) { + copy_bar.finish(); + break Ok(()); + } + + let Some(last_ts) = timestamps.last() else { + break Ok(()); // all data consumed + }; + + read_start = *last_ts + 1; + for (ts, line) in timestamps.into_iter().zip(data.into_iter()) { + copy_bar.inc(1); + output + .write_line(ts, &line, &precisions) + .wrap_err("failed to write line to csv")?; + } + } +} + +fn read_metadata(path: &Path) -> Result { + const HEADER_END: &'static str = "In the case the creator of this \ + file wanted to store metadata in it that\n follows now:"; + + let file = fs::File::open(path) + .wrap_err("Could not open file for reading metadata")?; + let mut buf = Vec::with_capacity(12_000); + file.take(12_000) + .read_to_end(&mut buf) + .wrap_err("Could not read first 12_000 bytes or end")?; + let header = String::from_utf8_lossy(&buf); + let Some((_, metadata_and_rest)) = header.split_once(HEADER_END) else { + bail!("Could not find end of byteseries header") + }; + + let metadata = take_around_parenthesis(metadata_and_rest) + .wrap_err("Could not extract metadata around parenthesis")?; + + Ok(metadata.to_string()) +} + +/// reads till first parenthesis it sees then looks for +/// the corresponding closing one +fn take_around_parenthesis(input: &str) -> Result<&str> { + let start = input.find('(').ok_or_eyre("Missing starting parenthesis")?; + let input = &input[start..]; + + let mut end = None; + let mut depth = 0; + for (idx, char) in input.char_indices() { + match char { + '(' => { + depth += 1; + } + ')' => { + depth -= 1; + if depth == 0 { + end = Some(idx); + break; + } + } + _ => (), + } + } + + let end = end + .ok_or_eyre( + "Could not find matching closing parenthesis before end of input", + ) + .with_note(|| format!("meta was:```\n{}\n```", input))?; + + Ok(&input[..=end]) +} + +fn files_to_export( + data_dir: &Path, +) -> Result, color_eyre::eyre::Error> { + const HEADER_START: &'static str = "This is a byteseries 1 file, an embedded \ + timeseries file. Time may here may\n be whatever value as long as it is \ + monotonically increasing. The entries\n have a fixed length that \ + never changes."; + + let mut buf = [0u8; 300]; + let mut res = Vec::new(); + crate::visit_dirs(data_dir, &mut |entry: &DirEntry| { + if entry.path().extension() == Some(OsStr::new("byteseries")) { + let mut file = + fs::File::open(entry.path()).wrap_err("Could not open file")?; + + match file.read_exact(&mut buf) { + Ok(()) => (), + Err(e) if e.kind() == ErrorKind::UnexpectedEof => return Ok(()), + other => other.wrap_err("Could not read first 300 bytes")?, + } + + let header = String::from_utf8_lossy(&buf); + if header.contains(HEADER_START) { + res.push(entry.path()); + } + } + Ok(()) + }) + .wrap_err("Could not search for byteseries files")?; + Ok(res) +} diff --git a/crates/data-store/src/export/csv.rs b/crates/data-store/src/export/csv.rs new file mode 100644 index 00000000..5748df9a --- /dev/null +++ b/crates/data-store/src/export/csv.rs @@ -0,0 +1,53 @@ +use color_eyre::eyre::Context; +use color_eyre::eyre::Result; +use color_eyre::Section; + +use std::fs; +use std::io::BufWriter; +use std::io::Write; +use std::path::PathBuf; + +/// https://www.rfc-editor.org/rfc/rfc4180 +pub(crate) struct Csv { + pub(crate) file: BufWriter, +} + +impl Csv { + pub(crate) fn open( + readings: &[protocol::Reading], + path: PathBuf, + ) -> Result { + let file = fs::OpenOptions::new() + .create_new(true) + .write(true) + .open(&path) + .wrap_err("Could not open output csv path") + .with_note(|| format!("csv path: {}", path.display()))?; + let mut file = BufWriter::new(file); + write!(file, "ts").wrap_err("Could not write header")?; + for reading in readings { + let encoded = ron::to_string(reading).expect("can be encoded"); + write!(file, ",{encoded}").wrap_err("Could not write header")?; + } + write!(file, "\r\n").wrap_err("Could not write header")?; + + Ok(Self { file }) + } + + pub(crate) fn write_line( + &mut self, + ts: u64, + line: &[f32], + precisions: &[usize], + ) -> Result<()> { + write!(self.file, "{ts}").wrap_err("Could not write ts to file")?; + for (val, precision) in line.into_iter().zip(precisions) { + write!(self.file, ",{0:.1$}", val, precision) + .wrap_err("Could not write float value to file")?; + } + write!(self.file, "\r\n") + .wrap_err("Could not write lineend to file")?; + + Ok(()) + } +} diff --git a/crates/data-store/src/export/decoder.rs b/crates/data-store/src/export/decoder.rs new file mode 100644 index 00000000..c0a169e8 --- /dev/null +++ b/crates/data-store/src/export/decoder.rs @@ -0,0 +1,23 @@ +use crate::data::series::bitspec; + +#[derive(Debug, Clone)] +pub(crate) struct ExportDecoder { + pub(crate) fields: Vec>, +} + +impl ExportDecoder { + pub(crate) fn from_fields(fields: Vec>) -> Self { + Self { fields } + } +} + +impl byteseries::Decoder for ExportDecoder { + type Item = smallvec::SmallVec; + + fn decode_payload(&mut self, payload: &[u8]) -> Self::Item { + self.fields + .iter() + .map(|field| field.decode(payload)) + .collect() + } +} diff --git a/crates/data-store/src/import.rs b/crates/data-store/src/import.rs new file mode 100644 index 00000000..3fb2086f --- /dev/null +++ b/crates/data-store/src/import.rs @@ -0,0 +1,261 @@ +use byteseries::ByteSeries; +use color_eyre::eyre::{bail, Context, OptionExt}; +use color_eyre::{Result, Section}; +use indicatif::{MultiProgress, ProgressBar}; +use std::ffi::OsStr; +use std::fs::{self, DirEntry}; +use std::io::{BufRead, BufReader, ErrorKind, Read}; +use std::path::{Path, PathBuf}; +use tracing::warn; + +use crate::data::series::Meta; + +pub fn perform( + data_dir: &Path, + only: Option, + allow_corrupt: bool, +) -> Result<()> { + let list = files_to_import(data_dir)?; + if list.is_empty() { + bail!("No files left to import") + } + + let to_handle: Vec<_> = list + .iter() + .filter(|p| { + only.as_ref().is_none_or(|allowed| { + p.ends_with(allowed) || p.with_extension("").ends_with(allowed) + }) + }) + .collect(); + + if to_handle.is_empty() { + return crate::no_filter_match_err(list, only); + } + + let bars = MultiProgress::new(); + let files_bar = + ProgressBar::new(to_handle.len() as u64).with_style(crate::bar_style()); + let files_bar = bars.insert(0, files_bar); + files_bar.inc(0); // make the bar appear + + for path in &to_handle { + handle_file(&path, bars.clone(), allow_corrupt) + .wrap_err("Failed to import data") + .with_note(|| format!("Input file: {}", path.display()))?; + files_bar.inc(1); + } + + drop(bars); + tracing::info!( + "Done, imported {} files to {}", + to_handle.len(), + data_dir.display() + ); + + Ok(()) +} + +fn files_to_import( + data_dir: &Path, +) -> Result, color_eyre::eyre::Error> { + let mut buf = [0u8; 3]; + let mut res = Vec::new(); + + crate::visit_dirs(data_dir, &mut |entry: &DirEntry| { + if entry.path().extension() == Some(OsStr::new("csv")) { + let mut file = + fs::File::open(entry.path()).wrap_err("Could not open file")?; + + match file.read_exact(&mut buf) { + Ok(()) => (), + Err(e) if e.kind() == ErrorKind::UnexpectedEof => return Ok(()), + other => other.wrap_err("Could not read first 3 bytes")?, + } + + let header = String::from_utf8_lossy(&buf); + if header.contains("ts,") { + res.push(entry.path()); + } + } + Ok(()) + }) + .wrap_err("Could not search for csv files")?; + Ok(res) +} + +fn resolve_readings( + csv: &mut BufReader, +) -> color_eyre::Result<(Vec, usize)> { + let mut csv_header = String::new(); + let header_len = csv + .read_line(&mut csv_header) + .wrap_err("Could not read csv header")?; + let readings = csv_header + .trim() + .strip_prefix("ts,") + .ok_or_eyre("Csv header is missing the timestamp column header: 'ts,'") + .with_note(|| format!("header is: {csv_header}"))? + .split(',') + .map(|s| { + ron::from_str::(s) + .wrap_err("Could not decode Reading from string") + .with_note(|| format!("string was: {s}")) + }) + .collect::>>()?; + Ok((readings, header_len)) +} + +/// must be called after `resolve_readings` +/// this is a guess since some lines are longer some shorter. +fn number_of_lines( + csv: &mut BufReader, + header_len: usize, +) -> color_eyre::Result { + let file = csv.get_mut(); + let data_length = file + .metadata() + .wrap_err("Could not get file metadata")? + .len() + - header_len as u64; + let _ = file; + + if data_length == 0 { + return Ok(0); + } + + let mut line = String::new(); + let line_size = csv + .read_line(&mut line) + .wrap_err("Could not read data line from csv")?; + csv.seek_relative(-(line_size as i64)) + .wrap_err("Could not seek back to start of csv data")?; + + Ok(data_length / line_size as u64) +} + +fn handle_file( + path: &Path, + bars: MultiProgress, + allow_corrupt: bool, +) -> Result<()> { + let input_csv = fs::File::open(path).wrap_err("Could not open file")?; + let mut input_csv = BufReader::new(input_csv); + let (readings, header_len) = resolve_readings(&mut input_csv)?; + let lines = number_of_lines(&mut input_csv, header_len)?; + + let specs = crate::data::series::to_speclist(&readings); + let fields = crate::data::series::bitspec::speclist_to_fields(specs); + let (meta_list, payload_size) = + crate::data::series::meta_list_and_payload_size(&readings, &fields); + for (Meta { reading, .. }, in_csv) in meta_list.iter().zip(&readings) { + assert_eq!(reading, in_csv); + } + + let header = crate::data::series::Header { + readings: readings.to_vec(), + encoding: fields.clone(), + } + .serialized()?; + + let (bs, _) = byteseries::ByteSeries::builder() + .payload_size(payload_size) + .with_header(header) + .create_new(true) + .open(path.with_extension("byteseries")) + .wrap_err("Could not open output series")?; + + let copy_bar = ProgressBar::new(lines) + .with_style(crate::bar_style()) + .with_message(format!( + "{:?}", + path.file_name().expect("we only handle files with names") + )); + let copy_bar = bars.insert(1, copy_bar); + + let mut skipped_sections = 0; + let mut last_correct_before_corrupt = 0; + if allow_corrupt { + copy_over_content( + input_csv, + bs, + meta_list, + copy_bar.clone(), + |_, prev| { + if prev != last_correct_before_corrupt { + skipped_sections += 1; + } else { + last_correct_before_corrupt = prev; + } + true + }, + ) + .wrap_err("Failed to copy over content")?; + } else { + copy_over_content( + input_csv, + bs, + meta_list, + copy_bar.clone(), + |_, _| false, + ) + .wrap_err("Failed to copy over content")?; + } + + if skipped_sections > 0 { + bars.suspend(|| { + warn!( + "skipped {skipped_sections} sections of data due to \ + corrupt full meta ts" + ); + }) + } + + bars.remove(©_bar); + + Ok(()) +} + +fn copy_over_content( + input_csv: BufReader, + mut bs: ByteSeries, + meta_list: Vec, + copy_bar: ProgressBar, + mut on_invalid_ts: impl FnMut(u64, u64) -> bool, +) -> color_eyre::Result<()> { + use byteseries::series::Error as BsError; + + let mut encoded_line = vec![0; bs.payload_size()]; + for (i, line) in input_csv.lines().enumerate() { + let line = line.wrap_err("Could not read line from csv")?; + let (ts, line) = + line.split_once(',').ok_or_eyre("Empty line in csv")?; + let ts: u64 = ts + .parse() + .wrap_err("Could not parse timestamp as integer") + .with_note(|| format!("timestamp: {ts}"))?; + + encoded_line.fill(0); + for (value, Meta { field, .. }) in line.split(',').zip(&meta_list) { + let value: f32 = + value.parse().wrap_err("Could not parse field as f32")?; + field.encode(value, &mut encoded_line); + } + + match bs.push_line(ts, &encoded_line) { + Ok(()) => (), + Err(BsError::TimeNotAfterLast { new, prev }) + if on_invalid_ts(new, prev) => + { + () + } + Err(other) => Err(other) + .wrap_err("Could not push line to output") + .with_note(|| format!("line {} in file", i + 1))?, + }; + + copy_bar.inc(1); + } + + Ok(()) +} diff --git a/crates/data-store/src/lib.rs b/crates/data-store/src/lib.rs new file mode 100644 index 00000000..a0518314 --- /dev/null +++ b/crates/data-store/src/lib.rs @@ -0,0 +1,71 @@ +#![allow(clippy::missing_errors_doc, clippy::missing_panics_doc)] + +use std::fs::DirEntry; +use std::path::{Path, PathBuf}; + +use color_eyre::eyre::Context; +use color_eyre::Section; +use indicatif::ProgressStyle; +use itertools::Itertools; + +#[cfg(feature = "api")] +pub mod api; +#[cfg(feature = "server")] +pub mod data; +#[cfg(feature = "server")] +pub mod export; +#[cfg(feature = "server")] +pub mod import; +#[cfg(feature = "server")] +pub mod server; + +pub(crate) fn visit_dirs( + dir: &Path, + mut cb: &mut dyn FnMut(&DirEntry) -> color_eyre::Result<()>, +) -> color_eyre::Result<()> { + if dir.is_dir() { + for entry in std::fs::read_dir(dir).wrap_err("Could not read dir")? { + let entry = entry.wrap_err("Error walking dir")?; + let path = entry.path(); + if path.is_dir() { + visit_dirs(&path, &mut cb)?; + } else { + cb(&entry) + .wrap_err("Could not check file header") + .with_note(|| { + format!("file: {}", entry.path().display()) + })?; + } + } + } + Ok(()) +} + +pub(crate) fn no_filter_match_err( + list: Vec, + only: Option, +) -> color_eyre::Result<()> { + return Err(color_eyre::Report::msg( + "None of the paths ended with required argument", + )) + .with_note(|| { + format!("filter argument (--only) {}", only.unwrap().display()) + }) + .with_note(|| { + format!( + "examples of files: \n\t- {}", + list.iter() + .map(|p| p.display().to_string()) + .take(5) + .join("\n\t- ") + ) + }); +} + +fn bar_style() -> ProgressStyle { + ProgressStyle::with_template( + "[{elapsed_precise}] {bar:40.cyan/blue} {pos:>7}/{len:7} {msg} [{eta}]", + ) + .unwrap() + .progress_chars("##-") +} diff --git a/crates/data-store/src/main.rs b/crates/data-store/src/main.rs new file mode 100644 index 00000000..02e532d3 --- /dev/null +++ b/crates/data-store/src/main.rs @@ -0,0 +1,70 @@ +use std::net::SocketAddr; +use std::path::PathBuf; + +use clap::Parser; +use color_eyre::eyre::Result; + +#[derive(Parser, Debug)] +#[command(name = "data server")] +#[command(version = "1.0")] +#[command( + about = "Receives sensor events and spreads those to subscribed services" +)] +struct Cli { + #[command(subcommand)] + command: Command, + + #[arg(long, default_value = ".")] + data_dir: PathBuf, +} + +#[derive(clap::Subcommand, Debug)] +enum Command { + Run { + /// data server + #[arg(short, long)] + data_server: SocketAddr, + + #[arg(short, long)] + client_port: u16, + }, + Export { + /// export only one dataset at this path + /// `largebedroom/bed/nau7802right` + #[arg(short, long)] + only: Option, + }, + Import { + /// import a dataset at this path for example: + /// `largebedroom/bed/nau7802right` + #[arg(short, long)] + only: Option, + /// skip data that is out of order, this is useful as it fixes an + /// issue caused by a bug in Byteseries. + skip_corrupt: bool, + }, +} + +#[tokio::main] +async fn main() -> Result<()> { + logger::tracing::setup(); + color_eyre::install().unwrap(); + let cli = Cli::parse(); + tracing::info!("started data-server, args: {cli:?}"); + + match cli.command { + Command::Run { + data_server, + client_port, + } => { + data_store::server::run(data_server, client_port, &cli.data_dir) + .await + } + Command::Export { only } => { + data_store::export::perform(&cli.data_dir, only) + } + Command::Import { only, skip_corrupt } => { + data_store::import::perform(&cli.data_dir, only, skip_corrupt) + } + } +} diff --git a/crates/data-store/src/server.rs b/crates/data-store/src/server.rs new file mode 100644 index 00000000..7901746f --- /dev/null +++ b/crates/data-store/src/server.rs @@ -0,0 +1,31 @@ +use color_eyre::Result; +use futures_concurrency::future::Race; +use std::collections::HashMap; +use std::net::SocketAddr; +use std::path::Path; +use std::sync::Arc; +use tokio::sync::Mutex; + +mod clients; +mod db; + +// used from main and tests +pub async fn run( + data_server: SocketAddr, + client_port: u16, + data_dir: &Path, +) -> Result<()> { + let data = crate::data::Data(Arc::new(Mutex::new(HashMap::new()))); + + let error = ( + db::run(data_server, data.clone(), data_dir), + clients::handle(client_port, data), + ) + .race() + .await; + assert!( + error.is_err(), + "db::run and client::handle never return unless an error happens" + ); + error +} diff --git a/crates/data-store/src/server/clients.rs b/crates/data-store/src/server/clients.rs new file mode 100644 index 00000000..4919d11a --- /dev/null +++ b/crates/data-store/src/server/clients.rs @@ -0,0 +1,38 @@ +use crate::data::Data; +use crate::api::{self, ServerError}; + +pub(crate) async fn handle(port: u16, data: Data) -> color_eyre::Result<()> { + rpc::server::run( + port, + move |req, _| { + let data = data.clone(); + perform_request(req, data) + }, + Option::>::None, + ) + .await +} +async fn perform_request(request: api::Request, data: Data) -> api::Response { + match perform_request_inner(request, data).await { + Ok(resp) => resp, + Err(e) => api::Response::Error(e), + } +} + +async fn perform_request_inner( + request: api::Request, + data: Data, +) -> Result { + Ok(match request { + api::Request::ListData => api::Response::ListData(data.list_readings().await), + api::Request::GetData { + reading, + start, + end, + n, + } => { + let res = data.get(reading, start, end, n).await; + api::Response::GetData(res) + } + }) +} diff --git a/crates/data-store/src/server/db.rs b/crates/data-store/src/server/db.rs new file mode 100644 index 00000000..3526a2a9 --- /dev/null +++ b/crates/data-store/src/server/db.rs @@ -0,0 +1,44 @@ +use std::net::SocketAddr; +use std::path::Path; +use std::time::{Duration, Instant}; + +use data_server::api::subscriber::ReconnectingClient; +use data_server::api::subscriber::SubMessage; + +use color_eyre::{Result, Section}; + +use crate::data::Data; + +pub(crate) async fn run( + data_server_addr: SocketAddr, + data: Data, + data_dir: &Path, +) -> Result<()> { + let mut sub = + ReconnectingClient::new(data_server_addr, "ha-data-store".to_string()) + .subscribe(); + + let mut recently_logged = (Instant::now(), String::new()); + loop { + let msg = sub.next().await; + let SubMessage::Reading(reading) = msg else { + continue; + }; + + let res = crate::data::series::store(&data, &reading, data_dir) + .await + .with_note(|| format!("reading: {reading:?}")); + + const FIVE_MIN: Duration = Duration::from_secs(60 * 5); + if let Err(report) = res { + let e = format!("{report:?}"); + if recently_logged.1 == e && recently_logged.0.elapsed() <= FIVE_MIN + { + continue; + } else { + tracing::error!("Error processing new reading {reading:?},\nerror: {e}"); + recently_logged = (Instant::now(), e); + } + } + } +} diff --git a/crates/data-store/test.sh b/crates/data-store/test.sh new file mode 100755 index 00000000..0e3c6fba --- /dev/null +++ b/crates/data-store/test.sh @@ -0,0 +1,6 @@ +rm data/smallbedroom/radiator/radiator.csv +cargo r -- --data-dir data export --only smallbedroom/radiator/radiator + + +# rm data/smallbedroom/radiator/radiator.csv +# cargo r -- --data-dir data export --only smallbedroom/radiator/radiator diff --git a/crates/data-store/test_import_export.sh b/crates/data-store/test_import_export.sh new file mode 100755 index 00000000..21c4bfb0 --- /dev/null +++ b/crates/data-store/test_import_export.sh @@ -0,0 +1,18 @@ +#!/usr/bin/env bash + +# restore test file +cp data_updated/largebedroom/desk/bme280.csv{2,} + +rm data_updated/largebedroom/desk/bme280.byteseries +rm data_updated/largebedroom/desk/bme280.byteseries_index +cargo r --release -- --data-dir data_updated import --only largebedroom/desk/bme280 + +rm data_updated/largebedroom/desk/bme280.csv +cargo r --release -- --data-dir data_updated export --only largebedroom/desk/bme280 + +diff -q data_updated/largebedroom/desk/bme280.csv{2,} + +echo "Tail of input/correct file" +tail -n 2 data_updated/largebedroom/desk/bme280.csv2 +echo "Tail of output" +tail -n 2 data_updated/largebedroom/desk/bme280.csv diff --git a/crates/data-store/tests/list_data.rs b/crates/data-store/tests/list_data.rs new file mode 100644 index 00000000..3e7350a6 --- /dev/null +++ b/crates/data-store/tests/list_data.rs @@ -0,0 +1,214 @@ +use std::net::SocketAddr; +use std::sync::Once; +use std::time::Duration; + +use data_server::server::AffectorRegistar; +use data_store::api::Data; +use futures::FutureExt; +use futures_concurrency::future::Race; +use protocol::large_bedroom::bed; +use protocol::{large_bedroom, Reading}; +use temp_dir::TempDir; +use tokio::io::AsyncWriteExt; +use tokio::net::TcpStream; +use tokio::sync::{mpsc, Notify}; +use tokio::time::sleep; +use tracing_error::ErrorLayer; +use tracing_subscriber::layer::SubscriberExt; +use tracing_subscriber::util::SubscriberInitExt; + +const fn test_readings(v: f32) -> [Reading; 2] { + [ + Reading::LargeBedroom(large_bedroom::Reading::Bed(bed::Reading::Temperature(v))), + Reading::LargeBedroom(large_bedroom::Reading::Bed(bed::Reading::Humidity(v))), + ] +} + +async fn data_server(client_addr: impl Into, data_port: impl Into) { + use data_server::server; + + let (tx, rx) = mpsc::channel(2000); + let affectors = AffectorRegistar::default(); + tokio::select! { + e = server::client::handle(client_addr.into(), tx.clone(), affectors.clone()) => e.unwrap(), + e = server::handle_nodes(data_port.into(), &tx, affectors) => e.unwrap(), + e = server::handle_updates(rx) => e.unwrap(), + }; +} + +async fn send_sensor_values(data_port: u16, values: &[f32], data_send: &Notify) { + let mut conn = TcpStream::connect(("127.0.0.1", data_port)).await.unwrap(); + let list = protocol::affector::ListMessage::<50>::empty(); + let handshake = protocol::Msg::AffectorList(list).encode(); + conn.write_all(&handshake).await.unwrap(); + + for v in values { + let mut sensor_msg = protocol::SensorMessage::<50>::default(); + for val in test_readings(*v) { + sensor_msg.values.push(val).unwrap(); + } + let encoded = protocol::Msg::Readings(sensor_msg).encode(); + conn.write_all(&encoded).await.unwrap(); + sleep(Duration::from_secs_f32(1.1)).await; + } + data_send.notify_waiters(); + sleep(Duration::from_secs(999)).await; +} + +async fn check_client_list_data(data_store_addr: SocketAddr, data_send: &Notify) { + data_send.notified().await; + sleep(Duration::from_secs_f32(0.1)).await; + + let mut client = + data_store::api::Client::connect(data_store_addr, "data_store_example".to_owned()) + .await + .unwrap(); + let list = client.list_data().await.unwrap(); + + assert!( + !list.is_empty(), + "list is empty, should contain one reading" + ); + assert!( + list.iter().any(|r| { + if let protocol::Reading::LargeBedroom(protocol::large_bedroom::Reading::Bed( + protocol::large_bedroom::bed::Reading::Temperature(_), + )) = r + { + true + } else { + false + } + }), + "list is missing expected reading bed::Reading::Temperature. \ + Full list is: {list:?}" + ) +} + +async fn check_client_get_data( + data_store_addr: SocketAddr, + sensor_values: &[f32], + data_send: &Notify, +) { + data_send.notified().await; + sleep(Duration::from_secs_f32(0.1)).await; + let mut client = + data_store::api::Client::connect(data_store_addr, "data_store_example".to_owned()) + .await + .unwrap(); + let Data { time, values: data } = client + .get_data( + jiff::Timestamp::now() - jiff::Span::default().seconds(30), + jiff::Timestamp::now() + jiff::Span::default().seconds(30), + test_readings(0.0)[0].clone(), + 5, + ) + .await + .unwrap(); + + assert_eq!(time.len(), data.len()); + assert!(data + .into_iter() + .zip(sensor_values.into_iter().copied()) + .inspect(|r| println!("(got, expected): {r:?}")) + .all(|(a, b)| (a - b).abs() < 0.1)) +} + +static SETUP_REPORTING: Once = Once::new(); + +fn setup_reporting() { + SETUP_REPORTING.call_once(|| { + color_eyre::install().unwrap(); + tracing_subscriber::registry() + .with(ErrorLayer::default()) + .with(tracing_subscriber::fmt::layer().pretty().with_test_writer()) + .init(); + }); +} + +#[tokio::test] +async fn list_data() { + const DATA_SERVER_STARTUP: Duration = Duration::from_millis(20); + const DATA_STORE_STARTUP: Duration = Duration::from_millis(20); + const FIRST_MSG_PROCESSED: Duration = Duration::from_millis(1000); + + setup_reporting(); + + let test_dir = TempDir::new().unwrap(); + + let sub_port = reserve_port::ReservedPort::random().unwrap(); + let data_port = reserve_port::ReservedPort::random().unwrap(); + let store_port = reserve_port::ReservedPort::random().unwrap(); + + let data_server_addr = SocketAddr::from(([127, 0, 0, 1], sub_port.port())); + let data_store_addr = SocketAddr::from(([127, 0, 0, 1], store_port.port())); + + let data_send = Notify::new(); + let run_data_server = data_server( + ([127, 0, 0, 1], sub_port.port()), + ([127, 0, 0, 1], data_port.port()), + ); + let run_data_store = sleep(DATA_SERVER_STARTUP).then(|()| { + data_store::server::run(data_server_addr, data_store_addr.port(), test_dir.path()) + }); + let send_sensor_value = sleep(DATA_SERVER_STARTUP + DATA_STORE_STARTUP) + .then(|()| send_sensor_values(data_port.port(), &[0.0], &data_send)); + let run_test = sleep(DATA_SERVER_STARTUP + DATA_STORE_STARTUP + FIRST_MSG_PROCESSED) + .then(|()| check_client_list_data(data_store_addr, &data_send)); + + let res = ( + run_test.map(Result::Ok), + send_sensor_value.map(Result::Ok), + run_data_store, + run_data_server.map(Result::Ok), + ) + .race() + .await; + + res.unwrap(); +} + +#[tokio::test] +async fn read_data() { + const DATA_SERVER_STARTUP: Duration = Duration::from_millis(20); + const DATA_STORE_STARTUP: Duration = Duration::from_millis(20); + const FIRST_MSG_PROCESSED: Duration = Duration::from_millis(1000); + + let test_dir = TempDir::new().unwrap(); + std::env::set_current_dir(test_dir.path()).unwrap(); + + setup_reporting(); + + let sub_port = reserve_port::ReservedPort::random().unwrap(); + let data_port = reserve_port::ReservedPort::random().unwrap(); + let store_port = reserve_port::ReservedPort::random().unwrap(); + + let data_server_addr = SocketAddr::from(([127, 0, 0, 1], sub_port.port())); + let data_store_addr = SocketAddr::from(([127, 0, 0, 1], store_port.port())); + + let data_send = Notify::new(); + let sensor_values = [0.5]; + // let sensor_values = [0.0, 0.1, 0.2, 0.3]; + let run_data_server = data_server( + ([127, 0, 0, 1], sub_port.port()), + ([127, 0, 0, 1], data_port.port()), + ); + let run_data_store = sleep(DATA_SERVER_STARTUP).then(|()| { + data_store::server::run(data_server_addr, data_store_addr.port(), test_dir.path()) + }); + let send_sensor_value = sleep(DATA_SERVER_STARTUP + DATA_STORE_STARTUP) + .then(|()| send_sensor_values(data_port.port(), &sensor_values, &data_send)); + let run_test = sleep(DATA_SERVER_STARTUP + DATA_STORE_STARTUP + FIRST_MSG_PROCESSED) + .then(|()| check_client_get_data(data_store_addr, &sensor_values, &data_send)); + + let res = ( + run_test.map(Result::Ok), + send_sensor_value.map(Result::Ok), + run_data_store, + run_data_server.map(Result::Ok), + ) + .race() + .await; + + res.unwrap(); +} diff --git a/crates/data-store/update_data.sh b/crates/data-store/update_data.sh new file mode 100755 index 00000000..13aab61a --- /dev/null +++ b/crates/data-store/update_data.sh @@ -0,0 +1,88 @@ +#!/usr/bin/env bash + +set -e + +function download_and_export_to_csv { + if [ -d data_updated ]; then + echo "nothing to do: data_updated directory already exists" + return + fi + + if [ ! -d data ]; then + ssh sgc -q <<- ENDSSH + set -e + sudo systemctl stop data-store + cd /home/ha + sudo tar -czf data.tar.gz data + sudo chown david:david data.tar.gz + cp data.tar.gz /tmp/data.tar.gz + ENDSSH + + rsync sgc:/tmp/data.tar.gz . + tar -xzf data.tar.gz + else + echo "data directory already exists, skipping fetch data from server" + fi + + cargo r --release -- --data-dir data export + cp -r data data_updated + + rm $(find data_updated | grep '.byteseries') +} + +function import_from_csv_and_upload { + if [ ! -f data_updated.tar.gz ]; then + cargo r --release -- --data-dir data_updated import + rm $(find data_updated | grep '.csv') + tar -czf data_updated.tar.gz data_updated + else + echo "data_updated.tar.gz already exists skipping importing" + fi + + rsync $(pwd)/data_updated.tar.gz sgc:/tmp/ + + result=$(ssh sgc -q <<- ENDSSH + set -e + if [ -d /home/ha/data ]; then + sudo mv /home/ha/data{,_backup} + fi + sudo tar -xzf /tmp/data_updated.tar.gz -C /home/ha + sudo mv /home/ha/data{_updated,} + sudo chown -R ha:ha /home/ha/data + echo success + ENDSSH + ) + + if [[ $result != *success ]]; then + echo "Error, unpacking failed on server." + echo "$result" + exit + fi + + ssh sgc -q <<- ENDSSH + sudo systemctl start data-store + ENDSSH + + sleep 5 + ssh sgc -q <<- ENDSSH + sudo systemctl status data-store + ENDSSH +} + +echo -e "updating to a new encoding (range changed for example) is a two step process:\n\ + 1. download encoded data and export with the current encoding\n\ + 2. switch to the new data-store build\n\ + 3. import the data from the exported csv's\n\ +" + +while true +do + read -r -p 'at which step are you? (n to abort)' choice + case "$choice" in + n|N) break;; + 1) download_and_export_to_csv;; + 2) echo 'The script can not do that for you! do it then continue';; + 3) import_from_csv_and_upload && break;; + *) echo 'Response not valid try: 1,2,3 or n';; + esac +done diff --git a/crates/desk-sensors/.cargo/config.toml b/crates/desk-sensors/.cargo/config.toml new file mode 100644 index 00000000..0127ae27 --- /dev/null +++ b/crates/desk-sensors/.cargo/config.toml @@ -0,0 +1,5 @@ +[target.aarch64-unknown-linux-musl] +rustflags = ["-Clinker=rust-lld"] + +[target.armv7-unknown-linux-musleabihf] +rustflags = ["-Clinker=rust-lld"] diff --git a/crates/desk-sensors/.gitignore b/crates/desk-sensors/.gitignore new file mode 100644 index 00000000..ea8c4bf7 --- /dev/null +++ b/crates/desk-sensors/.gitignore @@ -0,0 +1 @@ +/target diff --git a/crates/desk-sensors/Cargo.lock b/crates/desk-sensors/Cargo.lock new file mode 100644 index 00000000..261ab945 --- /dev/null +++ b/crates/desk-sensors/Cargo.lock @@ -0,0 +1,1789 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 3 + +[[package]] +name = "addr2line" +version = "0.21.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8a30b2e23b9e17a9f90641c7ab1549cd9b44f296d3ccbf309d2863cfe398a0cb" +dependencies = [ + "gimli", +] + +[[package]] +name = "adler" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe" + +[[package]] +name = "aho-corasick" +version = "1.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e60d3430d3a69478ad0993f19238d2df97c507009a52b3c10addcd7f6bcb916" +dependencies = [ + "memchr", +] + +[[package]] +name = "anstream" +version = "0.6.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "418c75fa768af9c03be99d17643f93f79bbba589895012a80e3452a19ddda15b" +dependencies = [ + "anstyle", + "anstyle-parse", + "anstyle-query", + "anstyle-wincon", + "colorchoice", + "is_terminal_polyfill", + "utf8parse", +] + +[[package]] +name = "anstyle" +version = "1.0.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "038dfcf04a5feb68e9c60b21c9625a54c2c0616e79b72b0fd87075a056ae1d1b" + +[[package]] +name = "anstyle-parse" +version = "0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c03a11a9034d92058ceb6ee011ce58af4a9bf61491aa7e1e59ecd24bd40d22d4" +dependencies = [ + "utf8parse", +] + +[[package]] +name = "anstyle-query" +version = "1.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a64c907d4e79225ac72e2a354c9ce84d50ebb4586dee56c82b3ee73004f537f5" +dependencies = [ + "windows-sys", +] + +[[package]] +name = "anstyle-wincon" +version = "3.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "61a38449feb7068f52bb06c12759005cf459ee52bb4adc1d5a7c4322d716fb19" +dependencies = [ + "anstyle", + "windows-sys", +] + +[[package]] +name = "atomic-polyfill" +version = "1.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8cf2bce30dfe09ef0bfaef228b9d414faaf7e563035494d7fe092dba54b300f4" +dependencies = [ + "critical-section", +] + +[[package]] +name = "autocfg" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0c4b4d0bd25bd0b74681c0ad21497610ce1b7c91b1022cd21c80c6fbdd9476b0" + +[[package]] +name = "backtrace" +version = "0.3.71" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "26b05800d2e817c8b3b4b54abd461726265fa9789ae34330622f2db9ee696f9d" +dependencies = [ + "addr2line", + "cc", + "cfg-if", + "libc", + "miniz_oxide", + "object", + "rustc-demangle", +] + +[[package]] +name = "bare-metal" +version = "0.2.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5deb64efa5bd81e31fcd1938615a6d98c82eafcbcd787162b6f63b91d6bac5b3" +dependencies = [ + "rustc_version 0.2.3", +] + +[[package]] +name = "bit_field" +version = "0.10.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dc827186963e592360843fb5ba4b973e145841266c1357f7180c43526f2e5b61" + +[[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.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cf4b9d6a944f767f8e5e0db018570623c85f3d925ac718db4e06d0187adb21c1" + +[[package]] +name = "bme280" +version = "0.5.1" +source = "git+https://github.com/dvdsk/bme280-rs#4999b005d26a16312acb3dbc64b72658df49a16d" +dependencies = [ + "defmt", + "derive_more", + "embedded-hal 1.0.0", + "maybe-async-cfg", + "postcard", + "serde", +] + +[[package]] +name = "bosch-bme680" +version = "1.0.2" +source = "git+https://github.com/dvdsk/async-bosch-bme680#455d5d3194f137d9e0403779badc645e1bad7a05" +dependencies = [ + "bitfield 0.14.0", + "defmt", + "embedded-hal 1.0.0", + "embedded-hal-async", + "postcard", + "serde", + "thiserror", +] + +[[package]] +name = "bxcan" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "40ac3d0c0a542d0ab5521211f873f62706a7136df415676f676d347e5a41dd80" +dependencies = [ + "bitflags 1.3.2", + "embedded-hal 0.2.7", + "nb 1.1.0", + "vcell", +] + +[[package]] +name = "byteorder" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" + +[[package]] +name = "cast" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "37b2a672a2cb129a2e41c10b1224bb368f9f37a2b16b612598138befd7b37eb5" + +[[package]] +name = "cc" +version = "1.0.98" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "41c270e7540d725e65ac7f1b212ac8ce349719624d7bcff99f8e2e488e8cf03f" + +[[package]] +name = "cfg-if" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" + +[[package]] +name = "cfg_aliases" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fd16c4719339c4530435d38e511904438d07cce7950afa3718a84ac36c10e89e" + +[[package]] +name = "cfg_aliases" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "613afe47fcd5fac7ccf1db93babcb082c5994d996f20b8b159f2ad1658eb5724" + +[[package]] +name = "clap" +version = "4.5.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "90bc066a67923782aa8515dbaea16946c5bcc5addbd668bb80af688e53e548a0" +dependencies = [ + "clap_builder", + "clap_derive", +] + +[[package]] +name = "clap_builder" +version = "4.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ae129e2e766ae0ec03484e609954119f123cc1fe650337e155d03b022f24f7b4" +dependencies = [ + "anstream", + "anstyle", + "clap_lex", + "strsim", +] + +[[package]] +name = "clap_derive" +version = "4.5.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "528131438037fd55894f62d6e9f068b8f45ac57ffa77517819645d10aed04f64" +dependencies = [ + "heck 0.5.0", + "proc-macro2", + "quote", + "syn 2.0.66", +] + +[[package]] +name = "clap_lex" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "98cc8fbded0c607b7ba9dd60cd98df59af97e84d24e49c8557331cfc26d301ce" + +[[package]] +name = "cobs" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "67ba02a97a2bd10f4b59b25c7973101c79642302776489e030cd13cdab09ed15" + +[[package]] +name = "color-eyre" +version = "0.6.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "55146f5e46f237f7423d74111267d4597b59b0dad0ffaf7303bce9945d843ad5" +dependencies = [ + "backtrace", + "color-spantrace", + "eyre", + "indenter", + "once_cell", + "owo-colors", + "tracing-error", +] + +[[package]] +name = "color-spantrace" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cd6be1b2a7e382e2b98b43b2adcca6bb0e465af0bdd38123873ae61eb17a72c2" +dependencies = [ + "once_cell", + "owo-colors", + "tracing-core", + "tracing-error", +] + +[[package]] +name = "colorchoice" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b6a852b24ab71dffc585bcb46eaf7959d175cb865a7152e35b348d1b2960422" + +[[package]] +name = "const_format" +version = "0.2.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e3a214c7af3d04997541b18d432afaff4c455e79e2029079647e72fc2bd27673" +dependencies = [ + "const_format_proc_macros", +] + +[[package]] +name = "const_format_proc_macros" +version = "0.2.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c7f6ff08fd20f4f299298a28e2dfa8a8ba1036e6cd2460ac1de7b425d76f2500" +dependencies = [ + "proc-macro2", + "quote", + "unicode-xid", +] + +[[package]] +name = "convert_case" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6245d59a3e82a7fc217c5828a6692dbc6dfb63a0c8c90495621f7b9d79704a0e" + +[[package]] +name = "core-foundation-sys" +version = "0.8.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "06ea2b9bc92be3c2baa9334a323ebca2d6f074ff852cd1d7b11064035cd3868f" + +[[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.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ee84e813d593101b1723e13ec38b6ab6abbdbaaa4546553f5395ed274079ddb1" +dependencies = [ + "cortex-m-rt-macros", +] + +[[package]] +name = "cortex-m-rt-macros" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f0f6f3e36f203cfedbc78b357fb28730aa2c6dc1ab060ee5c2405e843988d3c7" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "crc" +version = "3.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "69e6e4d7b33a94f0991c26729976b10ebde1d34c3ee82408fb536164fa10d636" +dependencies = [ + "crc-catalog", +] + +[[package]] +name = "crc-catalog" +version = "2.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "19d374276b40fb8bbdee95aef7c7fa6b5316ec764510eb64b8dd0e2ed0d7e7f5" + +[[package]] +name = "critical-section" +version = "1.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7059fff8937831a9ae6f0fe4d658ffabf58f2ca96aa9dec1c889f936f705f216" + +[[package]] +name = "defmt" +version = "0.3.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a99dd22262668b887121d4672af5a64b238f026099f1a2a1b322066c9ecfe9e0" +dependencies = [ + "bitflags 1.3.2", + "defmt-macros", +] + +[[package]] +name = "defmt-macros" +version = "0.3.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e3a9f309eff1f79b3ebdf252954d90ae440599c26c2c553fe87a2d17195f2dcb" +dependencies = [ + "defmt-parser", + "proc-macro-error", + "proc-macro2", + "quote", + "syn 2.0.66", +] + +[[package]] +name = "defmt-parser" +version = "0.3.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ff4a5fefe330e8d7f31b16a318f9ce81000d8e35e69b93eae154d16d2278f70f" +dependencies = [ + "thiserror", +] + +[[package]] +name = "derive_more" +version = "0.99.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4fb810d30a7c1953f91334de7244731fc3f3c10d7fe163338a35b9f640960321" +dependencies = [ + "convert_case", + "proc-macro2", + "quote", + "rustc_version 0.4.0", + "syn 1.0.109", +] + +[[package]] +name = "desk_sensors" +version = "0.2.0" +dependencies = [ + "bme280", + "clap", + "color-eyre", + "gpio-cdev", + "linux-embedded-hal", + "nix 0.29.0", + "protocol", + "tracing", + "tracing-error", + "tracing-subscriber", +] + +[[package]] +name = "document-features" +version = "0.2.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ef5282ad69563b5fc40319526ba27e0e7363d552a896f0297d54f767717f9b95" +dependencies = [ + "litrs", +] + +[[package]] +name = "embassy-embedded-hal" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eca4a9380d03e61063067b8239f67d2fa9f108ede7c46b4273804f6b79e59a1d" +dependencies = [ + "embassy-futures", + "embassy-sync", + "embassy-time", + "embedded-hal 0.2.7", + "embedded-hal 1.0.0", + "embedded-hal-async", + "embedded-storage", + "embedded-storage-async", + "nb 1.1.0", +] + +[[package]] +name = "embassy-futures" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1f878075b9794c1e4ac788c95b728f26aa6366d32eeb10c7051389f898f7d067" + +[[package]] +name = "embassy-hal-internal" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a0ec47cf8bab914018d4bd2b4f0aaeb46e4f52ab1e7985df88aeef2c6eda5aed" +dependencies = [ + "cortex-m", + "critical-section", + "num-traits", +] + +[[package]] +name = "embassy-net-driver" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "524eb3c489760508f71360112bca70f6e53173e6fe48fc5f0efd0f5ab217751d" + +[[package]] +name = "embassy-stm32" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "32bc0257b5ade13a1b93e8b9949268f44d57e8ce03e599ef1c5a62024a0fbff9" +dependencies = [ + "bit_field", + "bxcan", + "cfg-if", + "cortex-m", + "cortex-m-rt", + "critical-section", + "document-features", + "embassy-embedded-hal", + "embassy-futures", + "embassy-hal-internal", + "embassy-net-driver", + "embassy-sync", + "embassy-usb-driver", + "embedded-hal 0.2.7", + "embedded-hal 1.0.0", + "embedded-hal-async", + "embedded-hal-nb", + "embedded-io 0.6.1", + "embedded-io-async", + "embedded-storage", + "embedded-storage-async", + "futures", + "nb 1.1.0", + "proc-macro2", + "quote", + "rand_core", + "sdio-host", + "stm32-fmc", + "stm32-metapac", + "vcell", +] + +[[package]] +name = "embassy-sync" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dd938f25c0798db4280fcd8026bf4c2f48789aebf8f77b6e5cf8a7693ba114ec" +dependencies = [ + "cfg-if", + "critical-section", + "embedded-io-async", + "futures-util", + "heapless 0.8.0", +] + +[[package]] +name = "embassy-time" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a9c844070d9f80dc66ee739299183312baee2e1cdeb6e90b4ea2af44f4676da5" +dependencies = [ + "cfg-if", + "critical-section", + "document-features", + "embassy-time-driver", + "embassy-time-queue-driver", + "embedded-hal 0.2.7", + "embedded-hal 1.0.0", + "embedded-hal-async", + "futures-util", + "heapless 0.8.0", +] + +[[package]] +name = "embassy-time-driver" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6e0c214077aaa9206958b16411c157961fb7990d4ea628120a78d1a5a28aed24" +dependencies = [ + "document-features", +] + +[[package]] +name = "embassy-time-queue-driver" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f1177859559ebf42cd24ae7ba8fe6ee707489b01d0bf471f8827b7b12dcb0bc0" + +[[package]] +name = "embassy-usb-driver" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4fc247028eae04174b6635104a35b1ed336aabef4654f5e87a8f32327d231970" + +[[package]] +name = "embedded-hal" +version = "0.2.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "35949884794ad573cf46071e41c9b60efb0cb311e3ca01f7af807af1debc66ff" +dependencies = [ + "nb 0.1.3", + "void", +] + +[[package]] +name = "embedded-hal" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "361a90feb7004eca4019fb28352a9465666b24f840f5c3cddf0ff13920590b89" +dependencies = [ + "defmt", +] + +[[package]] +name = "embedded-hal-async" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0c4c685bbef7fe13c3c6dd4da26841ed3980ef33e841cddfa15ce8a8fb3f1884" +dependencies = [ + "defmt", + "embedded-hal 1.0.0", +] + +[[package]] +name = "embedded-hal-nb" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fba4268c14288c828995299e59b12babdbe170f6c6d73731af1b4648142e8605" +dependencies = [ + "embedded-hal 1.0.0", + "nb 1.1.0", +] + +[[package]] +name = "embedded-io" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ef1a6892d9eef45c8fa6b9e0086428a2cca8491aca8f787c534a3d6d0bcb3ced" + +[[package]] +name = "embedded-io" +version = "0.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "edd0f118536f44f5ccd48bcb8b111bdc3de888b58c74639dfb034a357d0f206d" +dependencies = [ + "defmt", +] + +[[package]] +name = "embedded-io-async" +version = "0.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3ff09972d4073aa8c299395be75161d582e7629cd663171d62af73c8d50dba3f" +dependencies = [ + "defmt", + "embedded-io 0.6.1", +] + +[[package]] +name = "embedded-storage" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a21dea9854beb860f3062d10228ce9b976da520a73474aed3171ec276bc0c032" + +[[package]] +name = "embedded-storage-async" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1763775e2323b7d5f0aa6090657f5e21cfa02ede71f5dc40eead06d64dcd15cc" +dependencies = [ + "embedded-storage", +] + +[[package]] +name = "eyre" +version = "0.6.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7cd915d99f24784cdc19fd37ef22b97e3ff0ae756c7e492e9fbfe897d61e2aec" +dependencies = [ + "indenter", + "once_cell", +] + +[[package]] +name = "futures" +version = "0.3.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "645c6916888f6cb6350d2550b80fb63e734897a8498abe35cfb732b6487804b0" +dependencies = [ + "futures-channel", + "futures-core", + "futures-io", + "futures-sink", + "futures-task", + "futures-util", +] + +[[package]] +name = "futures-channel" +version = "0.3.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eac8f7d7865dcb88bd4373ab671c8cf4508703796caa2b1985a9ca867b3fcb78" +dependencies = [ + "futures-core", + "futures-sink", +] + +[[package]] +name = "futures-core" +version = "0.3.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dfc6580bb841c5a68e9ef15c77ccc837b40a7504914d52e47b8b0e9bbda25a1d" + +[[package]] +name = "futures-io" +version = "0.3.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a44623e20b9681a318efdd71c299b6b222ed6f231972bfe2f224ebad6311f0c1" + +[[package]] +name = "futures-macro" +version = "0.3.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "87750cf4b7a4c0625b1529e4c543c2182106e4dedc60a2a6455e00d212c489ac" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.66", +] + +[[package]] +name = "futures-sink" +version = "0.3.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9fb8e00e87438d937621c1c6269e53f536c14d3fbd6a042bb24879e57d474fb5" + +[[package]] +name = "futures-task" +version = "0.3.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "38d84fa142264698cdce1a9f9172cf383a0c82de1bddcf3092901442c4097004" + +[[package]] +name = "futures-util" +version = "0.3.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3d6401deb83407ab3da39eba7e33987a73c3df0c82b4bb5813ee871c19c41d48" +dependencies = [ + "futures-core", + "futures-macro", + "futures-sink", + "futures-task", + "pin-project-lite", + "pin-utils", +] + +[[package]] +name = "gimli" +version = "0.28.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4271d37baee1b8c7e4b708028c57d816cf9d2434acb33a549475f78c181f6253" + +[[package]] +name = "gpio-cdev" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "09831ec59b80be69e75d29cf36e16afbbe5fd1af9c1bf4689ad91c77db5aa6a6" +dependencies = [ + "bitflags 2.5.0", + "libc", + "nix 0.27.1", +] + +[[package]] +name = "hash32" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b0c35f58762feb77d74ebe43bdbc3210f09be9fe6742234d573bacc26ed92b67" +dependencies = [ + "byteorder", +] + +[[package]] +name = "hash32" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "47d60b12902ba28e2730cd37e95b8c9223af2808df9e902d4df49588d1470606" +dependencies = [ + "byteorder", +] + +[[package]] +name = "heapless" +version = "0.7.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cdc6457c0eb62c71aac4bc17216026d8410337c4126773b9c5daba343f17964f" +dependencies = [ + "atomic-polyfill", + "hash32 0.2.1", + "rustc_version 0.4.0", + "serde", + "spin", + "stable_deref_trait", +] + +[[package]] +name = "heapless" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0bfb9eb618601c89945a70e254898da93b13be0388091d42117462b265bb3fad" +dependencies = [ + "hash32 0.3.1", + "serde", + "stable_deref_trait", +] + +[[package]] +name = "heck" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "95505c38b4572b2d910cecb0281560f54b440a19336cbbcb27bf6ce6adc6f5a8" + +[[package]] +name = "heck" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea" + +[[package]] +name = "i2cdev" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "597f56d08cebc0fb3e67d49f48124f49e1c7ac297a21d60bc90a28b9482fb35c" +dependencies = [ + "bitflags 2.5.0", + "byteorder", + "libc", + "nix 0.26.4", +] + +[[package]] +name = "indenter" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ce23b50ad8242c51a442f3ff322d56b02f08852c77e4c0b4d3fd684abc89c683" + +[[package]] +name = "io-kit-sys" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "617ee6cf8e3f66f3b4ea67a4058564628cde41901316e19f559e14c7c72c5e7b" +dependencies = [ + "core-foundation-sys", + "mach2", +] + +[[package]] +name = "is_terminal_polyfill" +version = "1.70.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f8478577c03552c21db0e2724ffb8986a5ce7af88107e6be5d2ee6e158c12800" + +[[package]] +name = "lazy_static" +version = "1.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" + +[[package]] +name = "libc" +version = "0.2.155" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "97b3888a4aecf77e811145cadf6eef5901f4782c53886191b2f693f24761847c" + +[[package]] +name = "linux-embedded-hal" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a8d566b726e1b6810f66c6f1c769889248439c27f06a59df2881a735454cfa02" +dependencies = [ + "cast", + "embedded-hal 1.0.0", + "embedded-hal-nb", + "gpio-cdev", + "i2cdev", + "nb 1.1.0", + "nix 0.27.1", + "serialport", + "spidev", + "sysfs_gpio", +] + +[[package]] +name = "litrs" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b4ce301924b7887e9d637144fdade93f9dfff9b60981d4ac161db09720d39aa5" + +[[package]] +name = "lock_api" +version = "0.4.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "07af8b9cdd281b7915f413fa73f29ebd5d55d0d3f0155584dade1ff18cea1b17" +dependencies = [ + "autocfg", + "scopeguard", +] + +[[package]] +name = "log" +version = "0.4.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "90ed8c1e510134f979dbc4f070f87d4313098b704861a105fe34231c70a3901c" + +[[package]] +name = "mach2" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "19b955cdeb2a02b9117f121ce63aa52d08ade45de53e48fe6a38b39c10f6f709" +dependencies = [ + "libc", +] + +[[package]] +name = "matchers" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8263075bb86c5a1b1427b5ae862e8889656f126e9f77c484496e8b47cf5c5558" +dependencies = [ + "regex-automata 0.1.10", +] + +[[package]] +name = "max44009" +version = "0.2.0" +source = "git+https://github.com/dvdsk/max44009-rs#7b7df2e3173476c250fca3eb242f0dd366857599" +dependencies = [ + "defmt", + "embedded-hal-async", + "postcard", + "serde", + "thiserror", +] + +[[package]] +name = "maybe-async-cfg" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "21fb8fac02158b9b529eb692491895d8459dbac939f3bc6e32159969646ffe55" +dependencies = [ + "proc-macro-error", + "proc-macro2", + "pulldown-cmark", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "memchr" +version = "2.7.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6c8640c5d730cb13ebd907d8d04b52f55ac9a2eec55b440c8892f40d56c76c1d" + +[[package]] +name = "memoffset" +version = "0.6.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5aa361d4faea93603064a027415f07bd8e1d5c88c9fbf68bf56a285428fd79ce" +dependencies = [ + "autocfg", +] + +[[package]] +name = "memoffset" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5de893c32cde5f383baa4c04c5d6dbdd735cfd4a794b0debdb2bb1b421da5ff4" +dependencies = [ + "autocfg", +] + +[[package]] +name = "mhzx" +version = "0.3.0" +source = "git+https://github.com/dvdsk/mhzx#08f6e7adb4ec98749fa84f24f8ff9e0e3c83d164" +dependencies = [ + "defmt", + "embedded-io-async", + "heapless 0.8.0", + "postcard", + "serde", + "thiserror", +] + +[[package]] +name = "miniz_oxide" +version = "0.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "87dfd01fe195c66b572b37921ad8803d010623c0aca821bea2302239d155cdae" +dependencies = [ + "adler", +] + +[[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 = "nix" +version = "0.23.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f3790c00a0150112de0f4cd161e3d7fc4b2d8a5542ffc35f099a2562aecb35c" +dependencies = [ + "bitflags 1.3.2", + "cc", + "cfg-if", + "libc", + "memoffset 0.6.5", +] + +[[package]] +name = "nix" +version = "0.26.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "598beaf3cc6fdd9a5dfb1630c2800c7acd31df7aaf0f565796fba2b53ca1af1b" +dependencies = [ + "bitflags 1.3.2", + "cfg-if", + "libc", + "memoffset 0.7.1", + "pin-utils", +] + +[[package]] +name = "nix" +version = "0.27.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2eb04e9c688eff1c89d72b407f168cf79bb9e867a9d3323ed6c01519eb9cc053" +dependencies = [ + "bitflags 2.5.0", + "cfg-if", + "libc", +] + +[[package]] +name = "nix" +version = "0.28.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ab2156c4fce2f8df6c499cc1c763e4394b7482525bf2a9701c9d79d215f519e4" +dependencies = [ + "bitflags 2.5.0", + "cfg-if", + "cfg_aliases 0.1.1", + "libc", +] + +[[package]] +name = "nix" +version = "0.29.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "71e2746dc3a24dd78b3cfcb7be93368c6de9963d30f43a6a73998a9cf4b17b46" +dependencies = [ + "bitflags 2.5.0", + "cfg-if", + "cfg_aliases 0.2.1", + "libc", +] + +[[package]] +name = "nu-ansi-term" +version = "0.46.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "77a8165726e8236064dbb45459242600304b42a5ea24ee2948e18e023bf7ba84" +dependencies = [ + "overload", + "winapi", +] + +[[package]] +name = "num-traits" +version = "0.2.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841" +dependencies = [ + "autocfg", +] + +[[package]] +name = "object" +version = "0.32.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a6a622008b6e321afc04970976f62ee297fdbaa6f95318ca343e3eebb9648441" +dependencies = [ + "memchr", +] + +[[package]] +name = "once_cell" +version = "1.19.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3fdb12b2476b595f9358c5161aa467c2438859caa136dec86c26fdd2efe17b92" + +[[package]] +name = "overload" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b15813163c1d831bf4a13c3610c05c0d03b39feb07f7e09fa234dac9b15aaf39" + +[[package]] +name = "owo-colors" +version = "3.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c1b04fb49957986fdce4d6ee7a65027d55d4b6d2265e5848bbb507b58ccfdb6f" + +[[package]] +name = "pin-project-lite" +version = "0.2.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bda66fc9667c18cb2758a2ac84d1167245054bcf85d5d1aaa6923f45801bdd02" + +[[package]] +name = "pin-utils" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" + +[[package]] +name = "postcard" +version = "1.0.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a55c51ee6c0db07e68448e336cf8ea4131a620edefebf9893e759b2d793420f8" +dependencies = [ + "cobs", + "const_format", + "embedded-io 0.4.0", + "heapless 0.7.17", + "postcard-derive", + "serde", +] + +[[package]] +name = "postcard-derive" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fc4b01218787dd4420daf63875163a787a78294ad48a24e9f6fa8c6507759a79" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "proc-macro-error" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "da25490ff9892aab3fcf7c36f08cfb902dd3e71ca0f9f9517bea02a73a5ce38c" +dependencies = [ + "proc-macro-error-attr", + "proc-macro2", + "quote", + "syn 1.0.109", + "version_check", +] + +[[package]] +name = "proc-macro-error-attr" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a1be40180e52ecc98ad80b184934baf3d0d29f979574e439af5a55274b35f869" +dependencies = [ + "proc-macro2", + "quote", + "version_check", +] + +[[package]] +name = "proc-macro2" +version = "1.0.83" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b33eb56c327dec362a9e55b3ad14f9d2f0904fb5a5b03b513ab5465399e9f43" +dependencies = [ + "unicode-ident", +] + +[[package]] +name = "protocol" +version = "0.1.0" +dependencies = [ + "bme280", + "bosch-bme680", + "defmt", + "embassy-embedded-hal", + "embassy-stm32", + "embedded-hal 1.0.0", + "heapless 0.8.0", + "linux-embedded-hal", + "max44009", + "mhzx", + "nix 0.28.0", + "postcard", + "serde", + "sht31", + "sps30-async", + "strum", +] + +[[package]] +name = "pulldown-cmark" +version = "0.9.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "57206b407293d2bcd3af849ce869d52068623f19e1b5ff8e8778e3309439682b" +dependencies = [ + "bitflags 2.5.0", + "memchr", + "unicase", +] + +[[package]] +name = "quote" +version = "1.0.36" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0fa76aaf39101c457836aec0ce2316dbdc3ab723cdda1c6bd4e6ad4208acaca7" +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 = "regex" +version = "1.10.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c117dbdfde9c8308975b6a18d71f3f385c89461f7b3fb054288ecf2a2058ba4c" +dependencies = [ + "aho-corasick", + "memchr", + "regex-automata 0.4.6", + "regex-syntax 0.8.3", +] + +[[package]] +name = "regex-automata" +version = "0.1.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6c230d73fb8d8c1b9c0b3135c5142a8acee3a0558fb8db5cf1cb65f8d7862132" +dependencies = [ + "regex-syntax 0.6.29", +] + +[[package]] +name = "regex-automata" +version = "0.4.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "86b83b8b9847f9bf95ef68afb0b8e6cdb80f498442f5179a29fad448fcc1eaea" +dependencies = [ + "aho-corasick", + "memchr", + "regex-syntax 0.8.3", +] + +[[package]] +name = "regex-syntax" +version = "0.6.29" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f162c6dd7b008981e4d40210aca20b4bd0f9b60ca9271061b07f78537722f2e1" + +[[package]] +name = "regex-syntax" +version = "0.8.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "adad44e29e4c806119491a7f06f03de4d1af22c3a680dd47f1e6e179439d1f56" + +[[package]] +name = "rustc-demangle" +version = "0.1.24" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "719b953e2095829ee67db738b3bfa9fa368c94900df327b3f07fe6e794d2fe1f" + +[[package]] +name = "rustc_version" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "138e3e0acb6c9fb258b19b67cb8abd63c00679d2851805ea151465464fe9030a" +dependencies = [ + "semver 0.9.0", +] + +[[package]] +name = "rustc_version" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bfa0f585226d2e68097d4f95d113b15b83a82e819ab25717ec0590d9584ef366" +dependencies = [ + "semver 1.0.23", +] + +[[package]] +name = "rustversion" +version = "1.0.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "955d28af4278de8121b7ebeb796b6a45735dc01436d898801014aced2773a3d6" + +[[package]] +name = "scopeguard" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" + +[[package]] +name = "sdio-host" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f93c025f9cfe4c388c328ece47d11a54a823da3b5ad0370b22d95ad47137f85a" + +[[package]] +name = "semver" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1d7eb9ef2c18661902cc47e535f9bc51b78acd254da71d375c2f6720d9a40403" +dependencies = [ + "semver-parser", +] + +[[package]] +name = "semver" +version = "1.0.23" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "61697e0a1c7e512e84a621326239844a24d8207b4669b41bc18b32ea5cbf988b" + +[[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.202" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "226b61a0d411b2ba5ff6d7f73a476ac4f8bb900373459cd00fab8512828ba395" +dependencies = [ + "serde_derive", +] + +[[package]] +name = "serde_derive" +version = "1.0.202" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6048858004bcff69094cd972ed40a32500f153bd3be9f716b2eed2e8217c4838" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.66", +] + +[[package]] +name = "serialport" +version = "4.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f5a15d0be940df84846264b09b51b10b931fb2f275becb80934e3568a016828" +dependencies = [ + "bitflags 2.5.0", + "cfg-if", + "core-foundation-sys", + "io-kit-sys", + "mach2", + "nix 0.26.4", + "regex", + "scopeguard", + "unescaper", + "winapi", +] + +[[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 = "sht31" +version = "0.3.1" +source = "git+https://github.com/dvdsk/SHT31-rs#a7b6bd94fb137e16bf326eff5fb591624369a2cf" +dependencies = [ + "crc", + "defmt", + "embedded-hal-async", + "postcard", + "serde", + "thiserror", +] + +[[package]] +name = "smallvec" +version = "1.13.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3c5e1a9a646d36c3599cd173a41282daf47c44583ad367b8e6837255952e5c67" + +[[package]] +name = "spidev" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c2800c129338c77998c1dcb6d4200447e018beb7d29959eb104cba2d45f83c1a" +dependencies = [ + "bitflags 2.5.0", + "libc", + "nix 0.26.4", +] + +[[package]] +name = "spin" +version = "0.9.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6980e8d7511241f8acf4aebddbb1ff938df5eebe98691418c4468d0b72a96a67" +dependencies = [ + "lock_api", +] + +[[package]] +name = "sps30-async" +version = "0.2.0" +source = "git+https://github.com/dvdsk/sps30-async#a5e81ec034727442c048acea2e8eb07fe4be78e4" +dependencies = [ + "defmt", + "embedded-hal-async", + "embedded-io-async", + "heapless 0.8.0", + "postcard", + "serde", + "thiserror", +] + +[[package]] +name = "stable_deref_trait" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a8f112729512f8e442d81f95a8a7ddf2b7c6b8a1a6f509a95864142b30cab2d3" + +[[package]] +name = "stm32-fmc" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "830ed60f33e6194ecb377f5d6ab765dc0e37e7b65e765f1fa87df13336658d63" +dependencies = [ + "embedded-hal 0.2.7", +] + +[[package]] +name = "stm32-metapac" +version = "15.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "deabea56a8821dcea05d0109f3ab3135f31eb572444e5da203d06149c594c8c6" +dependencies = [ + "cortex-m", + "cortex-m-rt", +] + +[[package]] +name = "strsim" +version = "0.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f" + +[[package]] +name = "strum" +version = "0.26.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5d8cec3501a5194c432b2b7976db6b7d10ec95c253208b45f83f7136aa985e29" +dependencies = [ + "strum_macros", +] + +[[package]] +name = "strum_macros" +version = "0.26.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c6cf59daf282c0a494ba14fd21610a0325f9f90ec9d1231dea26bcb1d696c946" +dependencies = [ + "heck 0.4.1", + "proc-macro2", + "quote", + "rustversion", + "syn 2.0.66", +] + +[[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.66" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c42f3f41a2de00b01c0aaad383c5a45241efc8b2d1eda5661812fda5f3cdcff5" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[package]] +name = "sysfs_gpio" +version = "0.6.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e8808c55bc926565c62ef7838bcaa8add51585236803e2bdfa1472e3a3ab5e17" +dependencies = [ + "nix 0.23.2", +] + +[[package]] +name = "thiserror" +version = "1.0.61" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c546c80d6be4bc6a00c0f01730c08df82eaa7a7a61f11d656526506112cc1709" +dependencies = [ + "thiserror-impl", +] + +[[package]] +name = "thiserror-impl" +version = "1.0.61" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "46c3384250002a6d5af4d114f2845d37b57521033f30d5c3f46c4d70e1197533" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.66", +] + +[[package]] +name = "thread_local" +version = "1.1.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8b9ef9bad013ada3808854ceac7b46812a6465ba368859a37e2100283d2d719c" +dependencies = [ + "cfg-if", + "once_cell", +] + +[[package]] +name = "tracing" +version = "0.1.40" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c3523ab5a71916ccf420eebdf5521fcef02141234bbc0b8a49f2fdc4544364ef" +dependencies = [ + "pin-project-lite", + "tracing-attributes", + "tracing-core", +] + +[[package]] +name = "tracing-attributes" +version = "0.1.27" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "34704c8d6ebcbc939824180af020566b01a7c01f80641264eba0999f6c2b6be7" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.66", +] + +[[package]] +name = "tracing-core" +version = "0.1.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c06d3da6113f116aaee68e4d601191614c9053067f9ab7f6edbcb161237daa54" +dependencies = [ + "once_cell", + "valuable", +] + +[[package]] +name = "tracing-error" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d686ec1c0f384b1277f097b2f279a2ecc11afe8c133c1aabf036a27cb4cd206e" +dependencies = [ + "tracing", + "tracing-subscriber", +] + +[[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.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ad0f048c97dbd9faa9b7df56362b8ebcaa52adb06b498c050d2f4e32f90a7a8b" +dependencies = [ + "matchers", + "nu-ansi-term", + "once_cell", + "regex", + "sharded-slab", + "smallvec", + "thread_local", + "tracing", + "tracing-core", + "tracing-log", +] + +[[package]] +name = "unescaper" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0adf6ad32eb5b3cadff915f7b770faaac8f7ff0476633aa29eb0d9584d889d34" +dependencies = [ + "thiserror", +] + +[[package]] +name = "unicase" +version = "2.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f7d2d4dafb69621809a81864c9c1b864479e1235c0dd4e199924b9742439ed89" +dependencies = [ + "version_check", +] + +[[package]] +name = "unicode-ident" +version = "1.0.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" + +[[package]] +name = "unicode-xid" +version = "0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f962df74c8c05a667b5ee8bcf162993134c104e96440b663c8daa176dc772d8c" + +[[package]] +name = "utf8parse" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "711b9620af191e0cdc7468a8d14e709c3dcdb115b36f838e601583af800a370a" + +[[package]] +name = "valuable" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "830b7e5d4d90034032940e4ace0d9a9a057e7a45cd94e6c007832e39edb82f6d" + +[[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.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" + +[[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 = "winapi" +version = "0.3.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419" +dependencies = [ + "winapi-i686-pc-windows-gnu", + "winapi-x86_64-pc-windows-gnu", +] + +[[package]] +name = "winapi-i686-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" + +[[package]] +name = "winapi-x86_64-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" + +[[package]] +name = "windows-sys" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d" +dependencies = [ + "windows-targets", +] + +[[package]] +name = "windows-targets" +version = "0.52.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6f0713a46559409d202e70e28227288446bf7841d3211583a4b53e3f6d96e7eb" +dependencies = [ + "windows_aarch64_gnullvm", + "windows_aarch64_msvc", + "windows_i686_gnu", + "windows_i686_gnullvm", + "windows_i686_msvc", + "windows_x86_64_gnu", + "windows_x86_64_gnullvm", + "windows_x86_64_msvc", +] + +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.52.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7088eed71e8b8dda258ecc8bac5fb1153c5cffaf2578fc8ff5d61e23578d3263" + +[[package]] +name = "windows_aarch64_msvc" +version = "0.52.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9985fd1504e250c615ca5f281c3f7a6da76213ebd5ccc9561496568a2752afb6" + +[[package]] +name = "windows_i686_gnu" +version = "0.52.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "88ba073cf16d5372720ec942a8ccbf61626074c6d4dd2e745299726ce8b89670" + +[[package]] +name = "windows_i686_gnullvm" +version = "0.52.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "87f4261229030a858f36b459e748ae97545d6f1ec60e5e0d6a3d32e0dc232ee9" + +[[package]] +name = "windows_i686_msvc" +version = "0.52.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "db3c2bf3d13d5b658be73463284eaf12830ac9a26a90c717b7f771dfe97487bf" + +[[package]] +name = "windows_x86_64_gnu" +version = "0.52.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4e4246f76bdeff09eb48875a0fd3e2af6aada79d409d33011886d3e1581517d9" + +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.52.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "852298e482cd67c356ddd9570386e2862b5673c85bd5f88df9ab6802b334c596" + +[[package]] +name = "windows_x86_64_msvc" +version = "0.52.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bec47e5bfd1bff0eeaf6d8b485cc1074891a197ab4225d504cb7a1ab88b02bf0" diff --git a/crates/desk-sensors/Cargo.toml b/crates/desk-sensors/Cargo.toml new file mode 100644 index 00000000..46b0d743 --- /dev/null +++ b/crates/desk-sensors/Cargo.toml @@ -0,0 +1,24 @@ +[package] +name = "desk-sensors" +version = "0.2.0" +edition.workspace = true +license.workspace = true +authors.workspace = true + +[dependencies] +linux-embedded-hal = "0.4" +bme280 = { version = "0.5", git = "https://github.com/dvdsk/bme280-rs", features = ["postcard", "serde", "with_std"] } + +data-server = { workspace = true } +protocol = { workspace = true, features = ["alloc"] } + +clap = { workspace = true} +color-eyre = { workspace = true } +tracing = { workspace = true } +tracing-subscriber = { workspace =true, features = ["env-filter"] } +tracing-error = { workspace = true } +logger = { workspace = true } + +tokio = { workspace = true, features = ["rt", "time", "macros"] } +heapless = "0.8.0" +governor.workspace = true diff --git a/crates/desk-sensors/deploy.sh b/crates/desk-sensors/deploy.sh new file mode 100755 index 00000000..34184325 --- /dev/null +++ b/crates/desk-sensors/deploy.sh @@ -0,0 +1,32 @@ +#!/usr/bin/env bash +set -e + +BUILD_ARG=--release +NAME=desk-sensors + +cargo build --target=aarch64-unknown-linux-musl $BUILD_ARG + +for server in "atlantis"; do + if [ $server == "atlantis" ]; then + sed -i 's/--bedroom large/--bedroom small/' $NAME.service + else + sed -i 's/--bedroom small/--bedroom large/' $NAME.service + fi + + rsync -vh --progress \ + ../../target/aarch64-unknown-linux-musl/release/$NAME \ + $server:/tmp/ + rsync -vh --progress \ + $NAME.service \ + $server:/tmp/ + + cmds=" + sudo mv /tmp/$NAME /usr/bin/ + sudo mv /tmp/$NAME.service /etc/systemd/system + sudo systemctl daemon-reload + sudo systemctl enable $NAME.service + sudo systemctl restart $NAME.service + " + + ssh -t $server "$cmds" +done diff --git a/crates/desk-sensors/desk-sensors.service b/crates/desk-sensors/desk-sensors.service new file mode 100644 index 00000000..e180eab0 --- /dev/null +++ b/crates/desk-sensors/desk-sensors.service @@ -0,0 +1,20 @@ +[Unit] +Description=Usb bridge +After=network-online.target +Wants=network-online.target + +[Service] +Type=exec +DynamicUser=yes +User=desk-sensors +Group=desk-sensors +SupplementaryGroups=i2c +Environment="RUST_BACKTRACE=1" +Environment="RUST_LOG=nusb=warn,info" +ExecStart=/usr/bin/desk-sensors \ + --bedroom small \ + --data-server sgc:1234 +ExecStop=/bin/kill -s SIGKILL $MAINPID + +[Install] +WantedBy=multi-user.target diff --git a/crates/desk-sensors/rust-toolchain.toml b/crates/desk-sensors/rust-toolchain.toml new file mode 100644 index 00000000..6e888d40 --- /dev/null +++ b/crates/desk-sensors/rust-toolchain.toml @@ -0,0 +1,5 @@ +[toolchain] +channel = "stable" +components = [] +targets = [ "aarch64-unknown-linux-musl" ] +profile = "minimal" diff --git a/crates/desk-sensors/src/bedroom.rs b/crates/desk-sensors/src/bedroom.rs new file mode 100644 index 00000000..028d6ff9 --- /dev/null +++ b/crates/desk-sensors/src/bedroom.rs @@ -0,0 +1,95 @@ +use protocol::Reading; + +#[derive(Debug, Clone, Copy, clap::ValueEnum)] +pub(crate) enum Bedroom { + Large, + Small, +} + +impl Bedroom { + pub(crate) fn make_temperature_reading(&self, value: f32) -> Reading { + match self { + Self::Large => { + use protocol::large_bedroom::desk::Reading as DeskReading; + wrap_large(DeskReading::Temperature(value)) + } + Self::Small => { + use protocol::small_bedroom::desk::Reading as DeskReading; + wrap_small(DeskReading::Temperature(value)) + } + } + } + pub(crate) fn make_humidity_reading(&self, value: f32) -> Reading { + match self { + Self::Large => { + use protocol::large_bedroom::desk::Reading as DeskReading; + wrap_large(DeskReading::Humidity(value)) + } + Self::Small => { + use protocol::small_bedroom::desk::Reading as DeskReading; + wrap_small(DeskReading::Humidity(value)) + } + } + } + pub(crate) fn make_pressure_reading(&self, value: f32) -> Reading { + match self { + Self::Large => { + use protocol::large_bedroom::desk::Reading as DeskReading; + wrap_large(DeskReading::Pressure(value)) + } + Self::Small => { + use protocol::small_bedroom::desk::Reading as DeskReading; + wrap_small(DeskReading::Pressure(value)) + } + } + } + + pub(crate) fn make_setup_error(&self, e: heapless::String<200>) -> protocol::Error { + match self { + Self::Large => { + use protocol::large_bedroom::desk; + let e = desk::SensorError::BmeError(e); + let e = desk::Error::Setup(e); + let e = protocol::large_bedroom::Error::Desk(e); + protocol::Error::LargeBedroom(e) + } + Self::Small => { + use protocol::small_bedroom::desk; + let e = desk::SensorError::BmeError(e); + let e = desk::Error::Setup(e); + let e = protocol::small_bedroom::Error::Desk(e); + protocol::Error::SmallBedroom(e) + } + } + } + + pub(crate) fn make_run_error(&self, e: heapless::String<200>) -> protocol::Error { + match self { + Self::Large => { + use protocol::large_bedroom::desk; + let e = desk::SensorError::BmeError(e); + let e = desk::Error::Running(e); + let e = protocol::large_bedroom::Error::Desk(e); + protocol::Error::LargeBedroom(e) + } + Self::Small => { + use protocol::small_bedroom::desk; + let e = desk::SensorError::BmeError(e); + let e = desk::Error::Running(e); + let e = protocol::small_bedroom::Error::Desk(e); + protocol::Error::SmallBedroom(e) + } + } + } +} + +fn wrap_small(reading: protocol::small_bedroom::desk::Reading) -> Reading { + use protocol::small_bedroom::Reading::Desk; + use protocol::Reading::SmallBedroom; + SmallBedroom(Desk(reading)) +} +fn wrap_large(reading: protocol::large_bedroom::desk::Reading) -> Reading { + use protocol::large_bedroom::Reading::Desk; + use protocol::Reading::LargeBedroom; + LargeBedroom(Desk(reading)) +} diff --git a/crates/desk-sensors/src/buttons.rs b/crates/desk-sensors/src/buttons.rs new file mode 100644 index 00000000..3b74e0e9 --- /dev/null +++ b/crates/desk-sensors/src/buttons.rs @@ -0,0 +1,96 @@ +use embedded_hal_async::digital::Wait; +use protocol::{make_error_string, button::Press, Reading}; +use std::sync::mpsc::Sender; +use std::time::{Duration, Instant}; +use tracing::{debug, error, info, trace}; + +use std::thread; + +use protocol::large_bedroom::desk::Button; + +use crate::{send_error, send_reading}; + +const CHIP: &str = "/dev/gpiochip0"; + +async fn watch_pin( + offset: u32, + as_button: impl Fn(Press) -> Button, + tx: &Sender>, +) { + use protocol::large_bedroom::desk; + + const DEBOUNCE: Duration = Duration::from_millis(5); + const MAX_PRESS: Duration = Duration::from_secs(10); + + // pins are pulled down to ground + let mut pin = match gpiocdev_embedded_hal::tokio::InputPin::new(CHIP, offset) { + Ok(pin) => pin, + Err(error) => { + error!("error opening gpio {offset} on {CHIP}: {error}"); + let error = make_error_string(error); + let error = desk::Error::Setup(SetupError::Gpio(error)); + send_error(tx, error); + return; + } + }; + + info!("opened_pin: {offset}"); + + loop { + if let Err(error) = pin.wait_for_rising_edge().await { + error!("error waiting for rising edge for gpio {offset} on {CHIP}: {error}"); + let error = make_error_string(error); + let error = desk::Error::Running(desk::SensorError::Gpio(error)); + send_error(tx, error); + return; + } + + let now = Instant::now(); + trace!("waiting for button to be released"); + match tokio::time::timeout(MAX_PRESS, pin.wait_for_falling_edge()).await { + Ok(Err(error)) => { + error!("error waiting for falling edge for gpio {offset} on {CHIP}: {error}"); + let error = make_error_string(error); + let error = desk::Error::Running(desk::SensorError::Gpio(error)); + send_error(tx, error); + return; + } + Ok(Ok(())) => (), + Err(_timeout) => continue, + } + + let press = now.elapsed(); + if press > DEBOUNCE { + debug!("sending button press (pressed for: {press:?})"); + let button = (as_button)(Press(press.as_millis() as u16)); + let reading = desk::Reading::Button(button); + send_reading(tx, reading); + } else { + trace!("press too short, caught as bounce: {offset}"); + } + } +} + +async fn watch_pins(tx: &Sender>) { + tokio::join!( + watch_pin(27, Button::OneOfThree, tx), + watch_pin(22, Button::TwoOfThree, tx), + watch_pin(18, Button::ThreeOfThree, tx), + watch_pin(23, Button::FourOfFour, tx), + watch_pin(24, Button::ThreeOfFour, tx), + watch_pin(26, Button::TwoOfFour, tx), + watch_pin(17, Button::OneOfFour, tx), + ); + unreachable!("none of those should return, and never all of them"); +} + +pub fn start_monitoring(tx: Sender>) { + thread::spawn(move || { + let rt = tokio::runtime::Builder::new_current_thread() + .enable_io() + .enable_time() + .build() + .unwrap(); + rt.block_on(watch_pins(&tx)) + }); +} diff --git a/crates/desk-sensors/src/main.rs b/crates/desk-sensors/src/main.rs new file mode 100644 index 00000000..c0375dc2 --- /dev/null +++ b/crates/desk-sensors/src/main.rs @@ -0,0 +1,68 @@ +use clap::Parser; +use color_eyre::eyre::Context; +use data_server::api::data_source::reconnecting::Client; +use std::net::SocketAddr; + +use tokio::sync::mpsc; + +use tracing::info; + +mod bedroom; +mod sensors; + +#[derive(Parser)] +#[command(name = "local sensors")] +#[command(version = "1.0")] +#[command(about = "reads sensors attached to rpi gpio pins and i2c perhipheral")] +struct Cli { + /// Where to send the data on the local system + #[arg(short, long("data-server"), + default_value = "sgc:1234", value_parser = resolve_socketaddr)] + data_server: SocketAddr, + /// Is this the pi in the large bedroom or small bedroom? + #[arg(short, long)] + bedroom: bedroom::Bedroom, +} + +#[tokio::main(flavor = "current_thread")] +async fn main() { + color_eyre::install().unwrap(); + let cli = Cli::parse(); + + logger::tracing::setup(); + + let (tx, mut rx) = mpsc::channel(100); + sensors::start_monitoring(tx.clone(), cli.bedroom); + + info!("connecting to dataserver on: {}", cli.data_server); + let mut client = Client::new(cli.data_server, Vec::new(), None) + .await + .unwrap(); + + loop { + let res = match rx.recv().await.expect("sensor monitoring never stops") { + Ok(reading) => client + .send_reading(reading) + .await + .wrap_err("Sending reading"), + Err(report) => client + .send_error(report) + .await + .wrap_err("Sending error report"), + }; + + if let Err(e) = res { + tracing::warn!("{e}"); + } + } +} + +pub fn resolve_socketaddr(arg: &str) -> Result { + use std::net::ToSocketAddrs; + + let mut addrs_iter = arg.to_socket_addrs()?; + addrs_iter.next().ok_or(std::io::Error::new( + std::io::ErrorKind::Other, + "Must pass one address", + )) +} diff --git a/crates/desk-sensors/src/sensors.rs b/crates/desk-sensors/src/sensors.rs new file mode 100644 index 00000000..80fee774 --- /dev/null +++ b/crates/desk-sensors/src/sensors.rs @@ -0,0 +1,104 @@ +use bme280::i2c::BME280 as Bme280; +use bme280::{self, Measurements}; +use governor::clock::{QuantaClock, QuantaInstant}; +use governor::middleware::NoOpMiddleware; +use governor::state::{InMemoryState, NotKeyed}; +use governor::{Quota, RateLimiter}; +use hal::{Delay, I2cdev}; +use linux_embedded_hal as hal; +use protocol::{ErrorString, Reading}; +use tracing::debug; + +use std::num::NonZeroU32; +use std::thread; +use std::time::Duration; +use tokio::sync::mpsc::Sender; + +use crate::bedroom; + +#[allow(clippy::result_large_err)] // its send directly after +pub fn init() -> Result, ErrorString> { + let i2c_bus = I2cdev::new("/dev/i2c-1") + .inspect_err(|e| tracing::error!("Could not open i2c bus: {e}")) + .map_err(protocol::make_error_string)?; + + let mut bme280 = Bme280::new_primary(i2c_bus); + bme280 + .init(&mut Delay) + .inspect_err(|e| tracing::error!("Could not init bme280 sensor: {e}")) + .map_err(protocol::make_error_string)?; + Ok(bme280) +} + +pub fn start_monitoring(tx: Sender>, room: bedroom::Bedroom) { + let quota = + Quota::per_hour(NonZeroU32::new(4).unwrap()).allow_burst(NonZeroU32::new(20).unwrap()); + let mut err_report_limiter = governor::RateLimiter::direct(quota); + let mut bme = None; + + thread::spawn(move || loop { + std::thread::sleep(Duration::from_secs(5)); + + if bme.is_none() { + bme = match init() { + Ok(driver) => Some(driver), + Err(e) => { + tracing::error!("Could not setup bme280 sensor: {e}"); + tx.blocking_send(Err(room.make_setup_error(e))) + .expect("main should not return or panic"); + continue; + } + }; + } + + if let Some(mut driver) = bme.take() { + match driver.measure(&mut Delay) { + Ok(measurements) => { + bme = Some(driver); + send_measurements(measurements, &tx, room); + } + Err(e) => { + send_error(e, &tx, room, &mut err_report_limiter); + break; + } + } + } + }); +} + +fn send_error( + e: bme280::Error, + tx: &Sender>, + room: bedroom::Bedroom, + limiter: &mut RateLimiter>, +) { + if limiter.check().is_err() { + return; + } + + tracing::error!("Could not read bme280 sensor: {e}"); + let e = protocol::make_error_string(e); + tx.blocking_send(Err(room.make_run_error(e))) + .expect("main should not return or panic"); +} + +fn send_measurements( + measurements: Measurements, + tx: &Sender>, + room: bedroom::Bedroom, +) { + debug!("got measurements: {measurements:?}"); + + let Measurements { + temperature, + pressure, + humidity, + } = measurements; + + tx.blocking_send(Ok(room.make_temperature_reading(temperature))) + .expect("main should not return or panic"); + tx.blocking_send(Ok(room.make_humidity_reading(humidity))) + .expect("main should not return or panic"); + tx.blocking_send(Ok(room.make_pressure_reading(pressure))) + .expect("main should not return or panic"); +} diff --git a/crates/log-store/.cargo/config.toml b/crates/log-store/.cargo/config.toml new file mode 100644 index 00000000..1002fed4 --- /dev/null +++ b/crates/log-store/.cargo/config.toml @@ -0,0 +1,2 @@ +[target.aarch64-unknown-linux-musl] +rustflags = ["-Clinker=rust-lld"] diff --git a/crates/log-store/Cargo.toml b/crates/log-store/Cargo.toml new file mode 100644 index 00000000..c4de9fea --- /dev/null +++ b/crates/log-store/Cargo.toml @@ -0,0 +1,43 @@ +[package] +name = "log-store" +version = "0.1.0" +rust-version.workspace = true +edition.workspace = true +license.workspace = true +authors.workspace = true + +[features] +api = [] +server = [] +default = ["api", "server"] + +[dependencies] +clap = { workspace = true } +color-eyre = { workspace = true } +logger = { workspace = true } +tracing = { workspace = true } +tracing-error = { workspace = true } +tracing-subscriber = { workspace = true, features = ["env-filter"] } +jiff = { workspace =true, features = ["serde"] } + +protocol = { workspace = true, features = ["alloc", "thiserror"] } +data-server = { workspace = true } +byteseries = { workspace = true } +rpc = { workspace = true } + +tokio = { workspace = true, features = ["fs", "net", "rt-multi-thread", "sync"] } +futures-concurrency = { workspace = true } +serde.workspace = true +bincode.workspace = true +thiserror.workspace = true +futures.workspace = true +smallvec.workspace = true +hdrhistogram = "7.5.4" +derivative = "2.2.0" + +[dev-dependencies] +futures-concurrency = { workspace = true } +heapless = "0.8.0" +nucleo-matcher = "0.3.1" +reserve-port.workspace = true +temp-dir = "0.1.13" diff --git a/crates/log-store/deploy.sh b/crates/log-store/deploy.sh new file mode 100755 index 00000000..2896f5d5 --- /dev/null +++ b/crates/log-store/deploy.sh @@ -0,0 +1,19 @@ +#!/usr/bin/env bash +set -e + +BUILD_ARG=--release +SERVER="sgc" # ssh config name or full address +NAME=log-store + +cargo build --target=aarch64-unknown-linux-musl $BUILD_ARG +rsync -vh --progress \ + ../../target/aarch64-unknown-linux-musl/release/$NAME \ + $SERVER:/tmp/ + +cmds=" +sudo mv /tmp/$NAME /home/ha/$NAME +sudo chown ha:ha /home/ha/$NAME +sudo systemctl restart $NAME.service +" + +ssh -t $SERVER "$cmds" diff --git a/crates/log-store/src/api.rs b/crates/log-store/src/api.rs new file mode 100644 index 00000000..0523b57d --- /dev/null +++ b/crates/log-store/src/api.rs @@ -0,0 +1,73 @@ +use std::ops::RangeInclusive; +use std::time::Duration; + +use protocol::{Device, Reading}; + +use serde::{Deserialize, Serialize}; + +pub mod client; +pub use client::Client; + +#[derive(Debug, Clone, Serialize, Deserialize)] +pub(crate) enum Request { + Handshake { + name: String, + }, + GetLog { + device: protocol::Device, + range: RangeInclusive, + }, + GetStats(protocol::Device), + ListDevices, +} + +#[derive(Debug, Clone, Serialize, Deserialize, thiserror::Error)] +pub enum ServerError { + #[error("Connect request should only be send once")] + AlreadyConnected, + #[error("Too many requests, rate limited, next requested allowed in: {0:?}")] + TooManyRequests(Duration), +} + +#[derive(Debug, Clone, Serialize, Deserialize, thiserror::Error)] +pub enum GetStatsError { + #[error("We do not have any data for this reading: {reading:?}")] + NotInStore { reading: Reading }, + #[error("Internal error while reading data, error: {0}")] + InternalError(String), +} + +#[derive(Debug, Clone, Serialize, Deserialize)] +pub struct Percentile { + pub bucket_ends: u64, + pub percentile: f64, + pub count_in_bucket: u64, +} + +#[derive(Debug, Clone, Serialize, Deserialize)] +pub struct ErrorEvent { + pub start: jiff::Timestamp, + /// if None then the error is ongoing + pub end: Option, + pub error: protocol::Error, +} + +#[derive(Debug, Clone, Serialize, Deserialize)] +pub(crate) enum GetLogResponse { + Err(String), + /// all logs between requested ranges + All(Vec), + /// could not send more logs due to rate limits + /// user should request more starting at the last + /// item in the list + Partial(Vec), +} + +#[derive(Debug, Clone, Serialize, Deserialize)] +pub(crate) enum Response { + GetLog(GetLogResponse), + ListDevices(Vec), + GetStats(Result, GetStatsError>), + Error(ServerError), + Handshake, +} diff --git a/crates/log-store/src/api/client.rs b/crates/log-store/src/api/client.rs new file mode 100644 index 00000000..60c7e766 --- /dev/null +++ b/crates/log-store/src/api/client.rs @@ -0,0 +1,105 @@ +use std::ops::RangeInclusive; +use std::time::Duration; + +use protocol::Device; +use rpc::client::RpcClient; +use rpc::client::RpcError; +use tokio::net::ToSocketAddrs; +use tokio::time::sleep; +use tracing::instrument; + +use crate::api::Percentile; + +use super::ErrorEvent; +use super::GetLogResponse; +use super::GetStatsError; +use super::Response; + +pub struct Client(rpc::client::RpcClient); +pub use rpc::client::ConnectError; + +#[derive(Debug, thiserror::Error)] +pub enum Error { + #[error("Server ran into an specific error with our request: {0}")] + Request(T), + #[error("Error while communicating with server: {0}")] + Comms(#[from] RpcError), +} + +impl Client { + pub async fn connect( + addr: impl ToSocketAddrs, + name: String, + ) -> Result { + let rpc_client = RpcClient::connect(addr, name).await?; + Ok(Self(rpc_client)) + } + + pub async fn get_percentiles( + &mut self, + device: protocol::Device, + ) -> Result, Error> { + let request = super::Request::GetStats(device); + match self.0.send_receive(request.clone()).await? { + Response::GetStats(Ok(percentiles)) => Ok(percentiles), + Response::GetStats(Err(e)) => Err(Error::Request(e)), + response => Err(Error::Comms(RpcError::IncorrectResponse { + request: format!("{request:?}"), + response: format!("{response:?}"), + })), + } + } + + #[instrument(skip(self))] + pub async fn get_logs( + &mut self, + device: protocol::Device, + mut range: RangeInclusive, + ) -> Result, Error> { + tracing::debug!("get all logs between: {range:?}"); + let mut all = Vec::new(); + + while !range.is_empty() { + let request = super::Request::GetLog { + device: device.clone(), + range: range.clone(), + }; + let partial = match self.0.send_receive(request.clone()).await? { + Response::GetLog(GetLogResponse::All(log)) => { + all.extend_from_slice(&log); + return Ok(all); + } + Response::GetLog(GetLogResponse::Partial(log)) => log, + Response::GetLog(GetLogResponse::Err(e)) => return Err(Error::Request(e)), + response => { + return Err(Error::Comms(RpcError::IncorrectResponse { + request: format!("{request:?}"), + response: format!("{response:?}"), + })) + } + }; + + let partial_ends = partial + .last() + .expect("if log.len() == 0 then response is GetLogResponse::All") + .start; + range = RangeInclusive::new(partial_ends + jiff::Span::new().seconds(1), *range.end()); + tracing::debug!("Got logs up till {partial_ends}, next requesting: {range:?}"); + all.extend_from_slice(&partial); + // do not overburden the server + sleep(Duration::from_millis(100)).await; + } + Ok(all) + } + + pub async fn list_devices(&mut self) -> Result, Error> { + let request = super::Request::ListDevices; + match self.0.send_receive(request.clone()).await? { + Response::ListDevices(logs) => Ok(logs), + response => Err(Error::Comms(RpcError::IncorrectResponse { + request: format!("{request:?}"), + response: format!("{response:?}"), + })), + } + } +} diff --git a/crates/log-store/src/lib.rs b/crates/log-store/src/lib.rs new file mode 100644 index 00000000..3ca113c0 --- /dev/null +++ b/crates/log-store/src/lib.rs @@ -0,0 +1,6 @@ +#![allow(clippy::missing_errors_doc, clippy::missing_panics_doc)] + +#[cfg(feature = "api")] +pub mod api; +#[cfg(feature = "server")] +pub mod server; diff --git a/crates/log-store/src/main.rs b/crates/log-store/src/main.rs new file mode 100644 index 00000000..bac872a7 --- /dev/null +++ b/crates/log-store/src/main.rs @@ -0,0 +1,30 @@ +use std::net::SocketAddr; +use std::path::PathBuf; + +use clap::Parser; +use color_eyre::eyre::Result; + +#[derive(Parser, Debug)] +#[command(name = "data server")] +#[command(version = "1.0")] +#[command(about = "Receives sensor events then logs errors and tracks timing")] +struct Cli { + /// data server + #[arg(short, long)] + data_server: SocketAddr, + + #[arg(short, long)] + client_port: u16, + + #[arg(long, default_value = ".")] + log_dir: PathBuf, +} + +#[tokio::main] +async fn main() -> Result<()> { + logger::tracing::setup(); + let cli = Cli::parse(); + tracing::info!("started log-store, args: {cli:?}"); + + log_store::server::run(cli.data_server, cli.client_port, &cli.log_dir).await +} diff --git a/crates/log-store/src/server.rs b/crates/log-store/src/server.rs new file mode 100644 index 00000000..6bf8f151 --- /dev/null +++ b/crates/log-store/src/server.rs @@ -0,0 +1,33 @@ +use color_eyre::Result; +use futures_concurrency::future::Race; +use std::collections::HashMap; +use std::net::SocketAddr; +use std::path::Path; +use std::sync::Arc; +use tokio::sync::Mutex; + +mod clients; +mod db; + +// used from main and tests +pub async fn run(data_server: SocketAddr, client_port: u16, log_dir: &Path) -> Result<()> { + let stats = db::Stats(Arc::new(Mutex::new(HashMap::new()))); + let logs = db::Logs(Arc::new(Mutex::new(HashMap::new()))); + + let error = ( + db::run( + data_server, + stats.clone(), + logs.clone(), + log_dir, + ), + clients::handle(client_port, stats, logs), + ) + .race() + .await; + assert!( + error.is_err(), + "db::run and client::handle never return unless an error happens" + ); + error +} diff --git a/crates/log-store/src/server/clients.rs b/crates/log-store/src/server/clients.rs new file mode 100644 index 00000000..19a88944 --- /dev/null +++ b/crates/log-store/src/server/clients.rs @@ -0,0 +1,34 @@ +use super::db::{Logs, Stats}; +use crate::api::{self, ServerError}; + +pub(crate) async fn handle(port: u16, stats: Stats, logs: Logs) -> color_eyre::Result<()> { + rpc::server::run( + port, + move |req, _| { + let stats = stats.clone(); + let logs = logs.clone(); + perform_request(req, stats, logs) + }, + Option::>::None, + ) + .await +} + +async fn perform_request(request: api::Request, stats: Stats, logs: Logs) -> api::Response { + match perform_request_inner(request, stats, logs).await { + Ok(resp) => resp, + Err(e) => api::Response::Error(e), + } +} +async fn perform_request_inner( + request: api::Request, + stats: Stats, + logs: Logs, +) -> Result { + Ok(match request { + api::Request::Handshake { .. } => return Err(ServerError::AlreadyConnected), + api::Request::GetLog { device, range } => api::Response::GetLog(logs.get(&device, range).await), + api::Request::GetStats(device) => api::Response::GetStats(stats.get(&device).await), + api::Request::ListDevices => api::Response::ListDevices(logs.list_devices().await), + }) +} diff --git a/crates/log-store/src/server/db.rs b/crates/log-store/src/server/db.rs new file mode 100644 index 00000000..251015b4 --- /dev/null +++ b/crates/log-store/src/server/db.rs @@ -0,0 +1,54 @@ +use std::net::SocketAddr; +use std::path::Path; +use std::time::{Duration, Instant}; + +use data_server::api::subscriber::ReconnectingClient; +use data_server::api::subscriber::SubMessage; + +use color_eyre::Result; + +mod log; +pub(crate) use log::Logs; + +mod stats; +pub(crate) use stats::Stats; +use tracing::debug; + +pub(crate) async fn run( + data_server_addr: SocketAddr, + stats: Stats, + logs: Logs, + log_dir: &Path, +) -> Result<()> { + let mut sub = + ReconnectingClient::new(data_server_addr, "ha-log-store".to_string()).subscribe(); + + let mut recently_logged = (Instant::now(), String::new()); + loop { + let msg = sub.next().await; + debug!("Got msg from data-server: {msg:?}"); + let res = match msg { + SubMessage::Reading(reading) => { + if let Err(e) = stats.increment(reading.device()).await { + Err(e) + } else { + logs.clear_err(reading.device()).await + } + } + SubMessage::ErrorReport(report) => logs.set_err(*report, log_dir).await, + SubMessage::AffectorControlled { .. } => continue, + }; + + const FIVE_MIN: Duration = Duration::from_secs(60 * 5); + if let Err(report) = res { + let e = format!("got error with report: {report:?}"); + tracing::warn!("test: {e}"); + if recently_logged.1 == e && recently_logged.0.elapsed() <= FIVE_MIN { + continue; + } else { + tracing::error!("Error processing new reading: {e}"); + recently_logged = (Instant::now(), e); + } + } + } +} diff --git a/crates/log-store/src/server/db/log.rs b/crates/log-store/src/server/db/log.rs new file mode 100644 index 00000000..f768f7d4 --- /dev/null +++ b/crates/log-store/src/server/db/log.rs @@ -0,0 +1,369 @@ +use std::collections::HashMap; +use std::io::{self, Read, Write}; +use std::iter; +use std::ops::RangeInclusive; +use std::path::{Path, PathBuf}; +use std::sync::Arc; + +use byteseries::file::OpenError as FileOpenError; +use byteseries::{series, ByteSeries}; +use color_eyre::eyre::Context; +use color_eyre::{Result, Section}; +use protocol::Device; +use serde::{Deserialize, Serialize}; +use series::data::OpenError as DataOpenError; +use series::Error::Open; +use tokio::sync::Mutex; +use tracing::{debug, info, instrument, warn}; + +use crate::api::{self, ErrorEvent, GetLogResponse}; + +#[derive(derivative::Derivative)] +#[derivative(Debug)] +pub(crate) struct Log { + #[derivative(Debug = "ignore")] + history: ByteSeries, + current: CurrentError, +} + +#[derive(Debug)] +struct CurrentError { + file: std::fs::File, + value: Option<(jiff::Timestamp, protocol::Error)>, +} + +impl CurrentError { + fn open_or_create(path: &Path) -> Result { + let path = path.with_extension("current_error"); + let mut file = std::fs::OpenOptions::new() + .read(true) + .write(true) + .create(true) + .truncate(false) + .open(path) + .wrap_err("Could not open or create on disk backup")?; + let mut buf = Vec::new(); + file.read_to_end(&mut buf) + .wrap_err("Failed to read from on disk backup")?; + + let value = if buf.is_empty() { + None + } else { + match bincode::serde::decode_from_slice( + &buf, + bincode::config::standard(), + ) { + Ok((value, _)) => Some(value), + Err(err) => { + tracing::debug!("Data was: {buf:?}"); + warn!( + "On disk backup failed to deserialize, setting to None, \ + error was: {err}" + ); + file.set_len(0).wrap_err( + "Could not set on disk backup to value None after \ + failing deserialize", + )?; + None + } + } + }; + + Ok(Self { file, value }) + } + + fn take(&mut self) -> Result> { + self.file.set_len(0).wrap_err( + "Could not set on disk backup of current error to None", + )?; + Ok(self.value.take()) + } + + fn set(&mut self, report: protocol::Error) -> Result<()> { + let value = (jiff::Timestamp::now(), report); + let bytes = + bincode::serde::encode_to_vec(&value, bincode::config::standard()) + .wrap_err("could not serialize current error")?; + self.file + .set_len(0) + .wrap_err("Could not clear file prior to backing up value")?; + self.file + .write_all(&bytes) + .wrap_err("could not backup current error to disk")?; + self.file + .flush() + .wrap_err("failed to flush current err backup to disk")?; + + self.value = Some(value); + Ok(()) + } + + fn get(&self) -> &Option<(jiff::Timestamp, protocol::Error)> { + &self.value + } +} + +impl Log { + #[instrument] + pub fn open_or_create(dir: &Path, device: &Device) -> Result { + let path = base_path(device); + let path = dir.join(path); + + let payload_size = protocol::Error::max_size(); + let header = format!( + "Bincode encoded error logs for {device:?}. \ + Each line has size: {payload_size} + 2" + ); + + let res = ByteSeries::builder() + .payload_size(payload_size) + .with_header(header.as_bytes().to_vec()) + .open(&path); + + let history = match res { + Ok((byteseries, _)) => byteseries, + Err(Open(DataOpenError::File { + source: FileOpenError::Io(e), + .. + })) if e.kind() == io::ErrorKind::NotFound => { + if let Some(dirs) = path.parent() { + std::fs::create_dir_all(dirs) + .wrap_err("Could not create dirs structure for reading") + .with_note(|| format!("dirs: {}", dirs.display()))?; + } + info!("creating new byteseries"); + ByteSeries::builder() + .payload_size(payload_size) + .with_header(header.into_bytes()) + .create_new(true) + .open(&path) + .wrap_err("Could not create new byteseries") + .with_note(|| format!("path: {}", path.display()))? + .0 + } + Err(e) => { + return Err(e) + .wrap_err("Could not open existing byteseries") + .with_note(|| format!("path: {}", path.display())) + } + }; + + Ok(Self { + history, + current: CurrentError::open_or_create(&path) + .wrap_err("Could not setup current error store") + .with_note(|| format!("device: {device:?}")) + .with_note(|| format!("path: {}", path.display()))?, + }) + } + + #[instrument] + pub fn set_err(&mut self, new_report: protocol::Error) -> Result<()> { + if let Some((started, report)) = self.current.get() { + if report == &new_report { + return Ok(()); + } + let line = StoredErrorEvent { + end: jiff::Timestamp::now(), + error: report.clone(), + }; + let line = bincode::serde::encode_to_vec( + &line, + bincode::config::standard(), + ) + .wrap_err("Could not serialize ErrorEvent")?; + let payload_size = protocol::Error::max_size(); + let line: Vec<_> = line + .into_iter() + .chain(iter::repeat(0)) + .take(payload_size) + .collect(); + + self.history + .push_line(started.as_second() as u64, line) + .wrap_err("Could not push new ErrorEvent into history")?; + } + + debug!("Registered new error: {new_report}"); + self.current + .set(new_report) + .wrap_err("Failed to set new error in current error store") + } + + #[instrument] + fn clear(&mut self) -> Result<()> { + self.current + .take() + .wrap_err("failed to set value of current error to None")?; + debug!("Cleared any error"); + Ok(()) + } + + fn get( + &mut self, + range: RangeInclusive, + ) -> GetLogResponse { + use byteseries::seek::Error::{ + EmptyFile, StartAfterData, StopBeforeData, + }; + use byteseries::series::Error::InvalidRange; + const MAX_IN_ONE_READ: usize = 200; + + let ts_range = RangeInclusive::new( + range.start().as_second() as u64, + range.end().as_second() as u64, + ); + + let current = self + .current + .value + .as_ref() + .map(|(ts, event)| api::ErrorEvent { + start: *ts, + end: None, + error: event.clone(), + }) + .into_iter(); + + let mut timestamps = Vec::new(); + let mut data = Vec::new(); + match self.history.read_first_n( + MAX_IN_ONE_READ, + &mut Decoder, + ts_range, + &mut timestamps, + &mut data, + ) { + Ok(()) => (), + Err(InvalidRange( + StopBeforeData | StartAfterData { .. } | EmptyFile, + )) => return GetLogResponse::All(current.collect()), + Err(other) => { + dbg!(&other); + let report = color_eyre::eyre::Report::new(other) + .wrap_err("Could not read log events from disk"); + let report = format!("{report:?}"); + return GetLogResponse::Err(report); + } + } + + let mut res: Vec<_> = timestamps + .into_iter() + .zip(data) + .map(|(start, StoredErrorEvent { end, error })| api::ErrorEvent { + start: jiff::Timestamp::from_second(start as i64) + .expect("was a jiff::Timestamp before it became a u64"), + end: Some(end), + error, + }) + .collect(); + + if res.len() < MAX_IN_ONE_READ { + res.extend(current.filter(|ErrorEvent { start, .. }| { + start >= range.start() && start <= range.end() + })); + + GetLogResponse::All(res) + } else { + GetLogResponse::Partial(res) + } + } +} + +#[derive(Debug, Clone, Serialize, Deserialize)] +struct StoredErrorEvent { + end: jiff::Timestamp, + error: protocol::Error, +} + +#[derive(Debug)] +struct Decoder; +impl byteseries::Decoder for Decoder { + type Item = StoredErrorEvent; + + fn decode_payload(&mut self, payload: &[u8]) -> Self::Item { + bincode::serde::decode_from_slice(payload, bincode::config::standard()) + .expect("if its successfully serialized it should deserialize") + .0 + } +} + +#[derive(Debug, Clone)] +pub(crate) struct Logs(pub(crate) Arc>>); + +impl Logs { + pub async fn set_err( + &self, + report: protocol::Error, + log_dir: &Path, + ) -> Result<()> { + let device = report.device(); + let mut map = self.0.lock().await; + if let Some(log) = map.get_mut(&device) { + log.set_err(report)?; + } else { + let mut log = Log::open_or_create(log_dir, &device) + .wrap_err("Failed to open or create error Log")?; + log.set_err(report)?; + map.insert(device, log); + } + Ok(()) + } + + pub async fn get( + &self, + device: &protocol::Device, + range: RangeInclusive, + ) -> api::GetLogResponse { + let mut map = self.0.lock().await; + if let Some(log) = map.get_mut(device) { + log.get(range) + } else { + api::GetLogResponse::All(Vec::new()) + } + } + + pub(crate) async fn clear_err( + &self, + device: protocol::Device, + ) -> Result<()> { + let mut map = self.0.lock().await; + if let Some(log) = map.get_mut(&device) { + log.clear()?; + } + Ok(()) + } + + pub(crate) async fn list_devices(&self) -> Vec { + let map = self.0.lock().await; + map.iter().map(|(key, _)| key.clone()).collect() + } +} + +/// Relative path without extension +fn base_path(device: &protocol::Device) -> PathBuf { + use protocol::reading::tree::{Item, Tree}; + use protocol::reading::Info; + + let mut parts = Vec::new(); + let mut current = device + .info() + .affects_readings + .first() + .expect("a device has at least one reading it affects") + as &dyn Tree; + loop { + match current.inner() { + Item::Leaf(Info { device, .. }) => { + parts.push(device.info().name.to_lowercase()); + break; + } + Item::Node(inner) => { + parts.push(current.name().to_lowercase()); + current = inner; + continue; + } + } + } + parts.into_iter().collect() +} diff --git a/crates/log-store/src/server/db/stats.rs b/crates/log-store/src/server/db/stats.rs new file mode 100644 index 00000000..6f20db3d --- /dev/null +++ b/crates/log-store/src/server/db/stats.rs @@ -0,0 +1,68 @@ +use color_eyre::eyre::WrapErr; +use color_eyre::{Result, Section}; +use std::collections::HashMap; +use std::sync::Arc; +use std::time::Instant; + +use tokio::sync::Mutex; + +use crate::api::{self, Percentile}; + +#[derive(Debug)] +pub(crate) struct Histogram { + last_reading: Instant, + histogram: hdrhistogram::Histogram, +} + +impl Histogram { + fn new() -> Result { + Ok(Self { + last_reading: Instant::now(), + histogram: hdrhistogram::Histogram::new_with_bounds(1, 24 * 60 * 60 * 1000, 2) + .wrap_err("Could not create empty histogram")?, + }) + } + fn increment(&mut self) -> Result<()> { + let val = self.last_reading.elapsed().as_millis(); + self.last_reading = Instant::now(); + self.histogram + .record(val as u64) + .wrap_err("Could not record event") + .with_note(|| format!("duration was: {val}ms")) + } +} + +#[derive(Debug, Clone)] +pub(crate) struct Stats(pub(crate) Arc>>); + +impl Stats { + pub async fn increment(&self, device: protocol::Device) -> Result<()> { + let mut map = self.0.lock().await; + if let Some(hist) = map.get_mut(&device) { + hist.increment()?; + } else { + map.insert(device, Histogram::new()?); + } + Ok(()) + } + + pub(crate) async fn get( + &self, + device: &protocol::Device, + ) -> Result, api::GetStatsError> { + let mut map = self.0.lock().await; + Ok(if let Some(timings) = map.get_mut(device) { + timings + .histogram + .iter_quantiles(1) + .map(|it| Percentile { + bucket_ends: it.value_iterated_to(), + percentile: it.percentile(), + count_in_bucket: it.count_at_value(), + }) + .collect() + } else { + Vec::new() + }) + } +} diff --git a/crates/log-store/tests/list_data.rs b/crates/log-store/tests/list_data.rs new file mode 100644 index 00000000..4b483bd3 --- /dev/null +++ b/crates/log-store/tests/list_data.rs @@ -0,0 +1,208 @@ +use std::net::SocketAddr; +use std::str::FromStr; +use std::sync::Once; +use std::time::Duration; + +use data_server::server::AffectorRegistar; +use futures::FutureExt; +use futures_concurrency::future::Race; +use protocol::large_bedroom::bed; +use protocol::{large_bedroom, Reading}; +use temp_dir::TempDir; +use tokio::io::AsyncWriteExt; +use tokio::net::TcpStream; +use tokio::sync::{mpsc, Notify}; +use tokio::time::sleep; +use tracing_error::ErrorLayer; +use tracing_subscriber::layer::SubscriberExt; +use tracing_subscriber::util::SubscriberInitExt; + +const fn test_readings(v: f32) -> [Reading; 2] { + [ + Reading::LargeBedroom(large_bedroom::Reading::Bed(bed::Reading::Temperature(v))), + Reading::LargeBedroom(large_bedroom::Reading::Bed(bed::Reading::Humidity(v))), + ] +} + +fn test_error(text: &str) -> protocol::Error { + protocol::Error::LargeBedroom(large_bedroom::Error::Bed(bed::Error::Setup( + bed::SensorError::Sht31(heapless::String::from_str(text).unwrap()), + ))) +} + +async fn data_server(client_addr: impl Into, data_port: impl Into) { + use data_server::server; + + let affectors = AffectorRegistar::default(); + let (tx, rx) = mpsc::channel(2000); + tokio::select! { + e = server::client::handle(client_addr.into(), tx.clone(), affectors.clone()) => e.unwrap(), + e = server::handle_nodes(data_port.into(), &tx, affectors) => e.unwrap(), + e = server::handle_updates(rx) => e.unwrap(), + }; +} + +async fn send_sensor_values(data_port: u16, data_send: &Notify) { + let mut conn = TcpStream::connect(("127.0.0.1", data_port)).await.unwrap(); + let list = protocol::affector::ListMessage::<50>::empty(); + let handshake = protocol::Msg::AffectorList(list).encode(); + conn.write_all(&handshake).await.unwrap(); + + for v in [0.1, 0.2, 0.3] { + let mut sensor_msg = protocol::SensorMessage::<50>::default(); + for val in test_readings(v) { + sensor_msg.values.push(val).unwrap(); + } + let encoded = protocol::Msg::Readings(sensor_msg).encode(); + conn.write_all(&encoded).await.unwrap(); + sleep(Duration::from_secs_f32(1.1)).await; + } + data_send.notify_waiters(); + sleep(Duration::from_secs(999)).await; +} + +async fn send_sensor_errors(data_port: u16, data_send: &Notify) { + let mut conn = TcpStream::connect(("127.0.0.1", data_port)).await.unwrap(); + let list = protocol::affector::ListMessage::<50>::empty(); + let handshake = protocol::Msg::AffectorList(list).encode(); + conn.write_all(&handshake).await.unwrap(); + + for error_type in [1, 1, 2, 1] { + let report = protocol::ErrorReport::new(test_error(&format!( + "log server integration test error: {error_type}" + ))); + let encoded = protocol::Msg::<50>::ErrorReport(report).encode(); + conn.write_all(&encoded).await.unwrap(); + sleep(Duration::from_secs_f32(1.1)).await; + } + data_send.notify_waiters(); + sleep(Duration::from_secs(999)).await; +} + +async fn check_client_get_percentiles(data_store_addr: SocketAddr, data_send: &Notify) { + data_send.notified().await; + sleep(Duration::from_secs_f32(0.1)).await; + + let mut client = + log_store::api::Client::connect(data_store_addr, "data_store_example".to_owned()) + .await + .unwrap(); + let test_device = test_readings(0.0).first().unwrap().device(); + let list = client.get_percentiles(test_device).await.unwrap(); + + assert!( + !list.is_empty(), + "list is empty, should contain one reading" + ); +} + +async fn check_client_get_logs(data_store_addr: SocketAddr, data_send: &Notify) { + data_send.notified().await; + sleep(Duration::from_secs_f32(0.1)).await; + let mut client = log_store::api::Client::connect(data_store_addr, "log_store_test".to_owned()) + .await + .unwrap(); + + let test_device = test_readings(0.0).first().unwrap().device(); + let range = jiff::Timestamp::new(0, 0).unwrap()..=jiff::Timestamp::now(); + let logs = client.get_logs(test_device, range).await.unwrap(); + + assert_eq!(logs.len(), 3); +} + +static SETUP_REPORTING: Once = Once::new(); + +fn setup_reporting() { + SETUP_REPORTING.call_once(|| { + color_eyre::install().unwrap(); + tracing_subscriber::registry() + .with(ErrorLayer::default()) + .with(tracing_subscriber::fmt::layer().pretty().with_test_writer()) + .init(); + }); +} + +#[tokio::test] +async fn get_logs() { + const DATA_SERVER_STARTUP: Duration = Duration::from_millis(20); + const DATA_STORE_STARTUP: Duration = Duration::from_millis(20); + const FIRST_MSG_PROCESSED: Duration = Duration::from_millis(1000); + + setup_reporting(); + + let test_dir = TempDir::new().unwrap(); + + let sub_port = reserve_port::ReservedPort::random().unwrap(); + let data_port = reserve_port::ReservedPort::random().unwrap(); + let store_port = reserve_port::ReservedPort::random().unwrap(); + + let data_server_addr = SocketAddr::from(([127, 0, 0, 1], sub_port.port())); + let data_store_addr = SocketAddr::from(([127, 0, 0, 1], store_port.port())); + + let errors_send = Notify::new(); + let run_data_server = data_server( + ([127, 0, 0, 1], sub_port.port()), + ([127, 0, 0, 1], data_port.port()), + ); + let run_data_store = sleep(DATA_SERVER_STARTUP).then(|()| { + log_store::server::run(data_server_addr, data_store_addr.port(), test_dir.path()) + }); + let send_sensor_value = sleep(DATA_SERVER_STARTUP + DATA_STORE_STARTUP) + .then(|()| send_sensor_errors(data_port.port(), &errors_send)); + let run_test = sleep(DATA_SERVER_STARTUP + DATA_STORE_STARTUP + FIRST_MSG_PROCESSED) + .then(|()| check_client_get_logs(data_store_addr, &errors_send)); + + let res = ( + run_test.map(Result::Ok), + send_sensor_value.map(Result::Ok), + run_data_store, + run_data_server.map(Result::Ok), + ) + .race() + .await; + + res.unwrap(); +} + +#[tokio::test] +async fn get_percentiles() { + const DATA_SERVER_STARTUP: Duration = Duration::from_millis(20); + const DATA_STORE_STARTUP: Duration = Duration::from_millis(20); + const FIRST_MSG_PROCESSED: Duration = Duration::from_millis(1000); + + let test_dir = TempDir::new().unwrap(); + std::env::set_current_dir(test_dir.path()).unwrap(); + + setup_reporting(); + + let sub_port = reserve_port::ReservedPort::random().unwrap(); + let data_port = reserve_port::ReservedPort::random().unwrap(); + let store_port = reserve_port::ReservedPort::random().unwrap(); + + let data_server_addr = SocketAddr::from(([127, 0, 0, 1], sub_port.port())); + let data_store_addr = SocketAddr::from(([127, 0, 0, 1], store_port.port())); + + let data_send = Notify::new(); + let run_data_server = data_server( + ([127, 0, 0, 1], sub_port.port()), + ([127, 0, 0, 1], data_port.port()), + ); + let run_data_store = sleep(DATA_SERVER_STARTUP).then(|()| { + log_store::server::run(data_server_addr, data_store_addr.port(), test_dir.path()) + }); + let send_sensor_value = sleep(DATA_SERVER_STARTUP + DATA_STORE_STARTUP) + .then(|()| send_sensor_values(data_port.port(), &data_send)); + let run_test = sleep(DATA_SERVER_STARTUP + DATA_STORE_STARTUP + FIRST_MSG_PROCESSED) + .then(|()| check_client_get_percentiles(data_store_addr, &data_send)); + + let res = ( + run_test.map(Result::Ok), + send_sensor_value.map(Result::Ok), + run_data_store, + run_data_server.map(Result::Ok), + ) + .race() + .await; + + res.unwrap(); +} diff --git a/crates/logger/Cargo.toml b/crates/logger/Cargo.toml new file mode 100644 index 00000000..d9dcd350 --- /dev/null +++ b/crates/logger/Cargo.toml @@ -0,0 +1,17 @@ +[package] +name = "logger" +version = "0.1.0" +rust-version.workspace = true +edition.workspace = true +license.workspace = true +authors.workspace = true + +[dependencies] +tracing = { workspace = true } +tracing-error = { workspace = true } +tracing-subscriber = { workspace = true, features = ["env-filter"] } +tracing-journald = "0.3" +libsystemd = "0.7" +governor.workspace = true +tracing-core = "0.1.32" +color-eyre.workspace = true diff --git a/crates/logger/examples/log.rs b/crates/logger/examples/log.rs new file mode 100644 index 00000000..79f5a43f --- /dev/null +++ b/crates/logger/examples/log.rs @@ -0,0 +1,48 @@ +// use logger::{ratelimited::Logger, warn}; +// +// fn main() { +// logger::tracing::setup(); +// +// let mut logger = Logger::default().with_per_msg_period(Duration::from_millis(800)); +// +// for i in 0..10 { +// warn!(logger; "constant message always the same"); +// warn!(logger; "oh no the number is: {}", i); +// thread::sleep(Duration::from_millis(100)); +// } +// } + +use std::time::Duration; + +fn log_a() { + tracing::info!("a"); +} + +fn log_b() { + tracing::info!("b"); +} + +fn log_c() { + tracing::info!("c"); +} + + +fn main() { + logger::tracing::setup(); + + // functions otherwise the callsite will be different + log_a(); + log_a(); + log_a(); + log_b(); + log_a(); + log_b(); + log_a(); + log_c(); + log_a(); + + std::thread::sleep(Duration::from_secs(2)); + log_a(); + log_b(); + log_c(); +} diff --git a/crates/logger/src/lib.rs b/crates/logger/src/lib.rs new file mode 100644 index 00000000..8846840a --- /dev/null +++ b/crates/logger/src/lib.rs @@ -0,0 +1,2 @@ +pub mod ratelimited; +pub mod tracing; diff --git a/crates/logger/src/ratelimited.rs b/crates/logger/src/ratelimited.rs new file mode 100644 index 00000000..509eaa1f --- /dev/null +++ b/crates/logger/src/ratelimited.rs @@ -0,0 +1,324 @@ +use governor::clock::DefaultClock; +use governor::middleware::NoOpMiddleware; +use governor::state::InMemoryState; +use governor::state::NotKeyed; +use governor::Quota; +use governor::RateLimiter; +use std::collections::HashMap; +use std::num::NonZero; +use std::sync::Mutex; +use std::time::Duration; +use tracing::field::Visit; +use tracing::Event; +use tracing::Metadata; +use tracing::Subscriber; +use tracing_core::callsite; +use tracing_core::Interest; +use tracing_subscriber::layer::Context; + +struct LimitState { + limiter: RateLimiter, + supressed: usize, +} +impl LimitState { + fn new(quota: Quota) -> Self { + Self { + limiter: RateLimiter::direct(quota), + supressed: 0, + } + } +} + +#[derive(Debug, PartialEq, Eq, Hash)] +struct LogMsgHash(u64); +struct CallSite { + state: LimitState, + msg: HashMap, +} + +struct Inner { + pub callsite: HashMap, + pub global: LimitState, +} + +impl Inner { + fn event_enabled(&mut self, event: &Event<'_>, quoti: &Quoti) -> bool { + if self.global.limiter.check().is_err() { + self.global.supressed += 1; + } else if self.global.supressed > 0 { + eprintln!( + "Logs are being ratelimitted, supressed {} messages", + self.global.supressed + ); + self.global.supressed = 0; + } + + let callsite = self + .callsite + .entry(event.metadata().callsite().clone()) + .or_insert(CallSite { + state: LimitState { + limiter: RateLimiter::direct(quoti.callsite), + supressed: 0, + }, + msg: HashMap::new(), + }); + + if callsite.state.limiter.check().is_err() { + callsite.state.supressed += 1; + return false; + } else if callsite.state.supressed > 0 { + eprintln!( + "Logs from this callsite are ratelimitted, \ + supressed {} messages", + callsite.state.supressed + ); + callsite.state.supressed = 0; + } + + let mut visitor = Visitor { + hash: LogMsgHash(0), // placeholder + }; + event.record(&mut visitor); + let msg = + callsite + .msg + .entry(visitor.hash) + .or_insert_with(|| LimitState { + limiter: RateLimiter::direct(quoti.msg), + supressed: 0, + }); + + if msg.limiter.check().is_err() { + msg.supressed += 1; + false + } else if msg.supressed > 0 { + eprintln!( + "Logs with this exact message are ratelimitted, \ + supressed {} messages", + msg.supressed + ); + msg.supressed = 0; + true + } else { + true + } + } +} + +struct Quoti { + global: Quota, + callsite: Quota, + msg: Quota, +} + +impl Default for Quoti { + fn default() -> Self { + Self { + global: Quota::per_second(NonZero::new(9).unwrap()) + .allow_burst(NonZero::new(9).unwrap()), + callsite: Quota::per_second(NonZero::new(6).unwrap()) + .allow_burst(NonZero::new(6).unwrap()), + msg: Quota::per_second(NonZero::new(1).unwrap()) + .allow_burst(NonZero::new(1).unwrap()), + } + } +} + +pub struct Limiter { + inner: Mutex, + quoti: Quoti, +} + +impl tracing_subscriber::layer::Filter for Limiter { + /// Returns `true` if this layer is interested in a span or event with the + /// given [`Metadata`] in the current [`Context`], similarly to + /// [`Subscriber::enabled`]. + /// + /// If this returns `false`, the span or event will be disabled _for the + /// wrapped [`Layer`]_. Unlike [`Layer::enabled`], the span or event will + /// still be recorded if any _other_ layers choose to enable it. However, + /// the layer [filtered] by this filter will skip recording that span or + /// event. + /// + /// If all layers indicate that they do not wish to see this span or event, + /// it will be disabled. + /// + /// [`metadata`]: tracing_core::Metadata + /// [`Subscriber::enabled`]: tracing_core::Subscriber::enabled + /// [filtered]: crate::filter::Filtered + fn enabled(&self, _: &Metadata<'_>, _: &Context<'_, S>) -> bool { + // all filtering is done based on event_enabled + true + } + + fn event_enabled(&self, event: &Event<'_>, _: &Context<'_, S>) -> bool { + self.inner.lock().unwrap().event_enabled(event, &self.quoti) + } + + fn callsite_enabled(&self, _: &'static Metadata<'static>) -> Interest { + Interest::sometimes() + } +} + +struct Visitor { + hash: LogMsgHash, +} + +impl Visit for Visitor { + fn record_debug( + &mut self, + _field: &tracing_core::Field, + value: &dyn std::fmt::Debug, + ) { + self.hash = debug_hash(&value) + } +} + +// adapted from tracing-subscriber/src/filter/env.field.rs +// by Tokio Contributors +fn debug_hash(debug: &impl std::fmt::Debug) -> LogMsgHash { + // Naively, we would probably hash a value's `fmt::Debug` output by + // formatting it to a string, and then calculating the stings hash This + // would however require allocating every time we want to hash a field + // value + // + // Instead, we implement `fmt::Write` for a type that, rather than + // actually _writing_ the strings to something, hashes them. + use std::fmt; + use std::fmt::Write; + use std::hash::DefaultHasher; + use std::hash::Hasher; + + struct FmtHasher { + hash_state: DefaultHasher, + } + + impl fmt::Write for FmtHasher { + fn write_str(&mut self, s: &str) -> fmt::Result { + for byte in s.bytes() { + self.hash_state.write_u8(byte); + } + Ok(()) + } + } + let mut hasher = FmtHasher { + hash_state: DefaultHasher::new(), + }; + + // Try to "write" the value's `fmt::Debug` output to a `Matcher`. This + // returns an error if the `fmt::Debug` implementation wrote any + // characters that did not match the expected pattern. + write!(hasher, "{:?}", debug).expect("hashing can not go wrong"); + LogMsgHash(hasher.hash_state.finish()) +} + +impl Default for Limiter { + fn default() -> Self { + Self { + inner: Mutex::new(Inner { + callsite: HashMap::new(), + global: LimitState::new(Quoti::default().global), + }), + quoti: Quoti::default(), + } + } +} + +impl Limiter { + pub fn with_global_period(mut self, one_log_per: Duration) -> Self { + self.quoti.global = Quota::with_period(one_log_per) + .expect("duration may not be zero") + .allow_burst(self.quoti.global.burst_size()); + + { + let mut inner = self.inner.lock().unwrap(); + inner.global.limiter = RateLimiter::direct(self.quoti.global) + } + + self + } + pub fn with_callsite_period( + mut self, + one_callsite_log_per: Duration, + ) -> Self { + self.quoti.callsite = Quota::with_period(one_callsite_log_per) + .expect("duration may not be zero") + .allow_burst(self.quoti.callsite.burst_size()); + + { + let mut inner = self.inner.lock().unwrap(); + for CallSite { state, .. } in inner.callsite.values_mut() { + state.limiter = RateLimiter::direct(self.quoti.callsite) + } + } + + self + } + pub fn with_msg_period(mut self, one_msg_per: Duration) -> Self { + self.quoti.msg = Quota::with_period(one_msg_per) + .expect("duration may not be zero") + .allow_burst(self.quoti.msg.burst_size()); + + { + let mut inner = self.inner.lock().unwrap(); + for msg_state in inner + .callsite + .values_mut() + .flat_map(|CallSite { msg, .. }| msg.values_mut()) + { + msg_state.limiter = RateLimiter::direct(self.quoti.msg) + } + } + + self + } + + pub fn with_global_burst(mut self, burst_size: u32) -> Self { + self.quoti.global = + Quota::with_period(self.quoti.global.replenish_interval()) + .expect("duration may not be zero") + .allow_burst(NonZero::new(burst_size).unwrap()); + + { + let mut inner = self.inner.lock().unwrap(); + inner.global.limiter = RateLimiter::direct(self.quoti.global) + } + + self + } + pub fn with_callsite_burst(mut self, burst_size: u32) -> Self { + self.quoti.callsite = + Quota::with_period(self.quoti.callsite.replenish_interval()) + .expect("duration may not be zero") + .allow_burst(NonZero::new(burst_size).unwrap()); + + { + let mut inner = self.inner.lock().unwrap(); + for CallSite { state, .. } in inner.callsite.values_mut() { + state.limiter = RateLimiter::direct(self.quoti.callsite) + } + } + + self + } + pub fn with_msg_burst(mut self, burst_size: u32) -> Self { + self.quoti.callsite = + Quota::with_period(self.quoti.msg.replenish_interval()) + .expect("duration may not be zero") + .allow_burst(NonZero::new(burst_size).unwrap()); + + { + let mut inner = self.inner.lock().unwrap(); + for msg_state in inner + .callsite + .values_mut() + .flat_map(|CallSite { msg, .. }| msg.values_mut()) + { + msg_state.limiter = RateLimiter::direct(self.quoti.msg) + } + } + + self + } +} diff --git a/crates/logger/src/tracing.rs b/crates/logger/src/tracing.rs new file mode 100644 index 00000000..5296c05b --- /dev/null +++ b/crates/logger/src/tracing.rs @@ -0,0 +1,187 @@ +use std::time::Duration; + +use crate::ratelimited; + +use tracing::level_filters::LevelFilter; +use tracing_error::ErrorLayer; +use tracing_subscriber::filter; +use tracing_subscriber::fmt; +use tracing_subscriber::util::SubscriberInitExt; +use tracing_subscriber::Layer; +use tracing_subscriber::{self, layer::SubscriberExt}; + +/// # WARNING +/// part of the filter syntax is broken (sad) +/// see: https://github.com/tokio-rs/tracing/issues/1181 +/// +/// ## what does work +/// +/// ### log everything in module: +/// Filter directives like: +/// `RUST_LOG=crate::module::submodule=trace,crate::module=info,error` +/// which logs everything in `submodule`, in `module` things are logged at level +/// info, warn or error and for the rest of the crate and all dependencies only +/// errors are logged +/// +/// ### log everything in function +/// Note the function must be instrumented for this to work +/// (such that a span is created with the functions name) +/// RUST_LOG='[function_name]=trace' +/// +/// ### Print if argument matches regex: +/// you can do this with: RUST_LOG='[{topic=.*small_bedroom:piano.*}]=trace,info' +/// that will print every log at trace level or higher that is inside an +/// instrumented function with an argument topic for which the regex +/// .*small_bedroom.* evaluates as true +/// +/// ## what should work but only does so sporadically +/// Filter directives allowing you to match field values (values recorded by for +/// example `#[instrument]`), +/// +/// their syntax: +/// RUST_LOG=target[span{field=value}]=level +/// +/// field value will be interpreted as regular expressions if it cannot be interpreted as +/// bool, i64, u64, or f64 literal. Regex syntax follows the regex crate. +/// +/// ### Example: +/// run something like this with: RUST_LOG='[shave{yak=2}]' and it should only +/// print the trace message once +/// ```rust +/// #[tracing::instrument] +/// pub fn shave(yak: usize) { +/// tracing::trace!("I am going to shave a yak :)") +/// } +/// +/// fn main() { +/// shave(1); +/// shave(2); +/// shave(3); +/// } +/// ``` +/// +/// for full docs see: https://docs.rs/tracing-subscriber/latest/tracing_subscriber/filter/struct.EnvFilter.html +/// +/// # Note +/// If the service runs under systemd it logs to the sysjournal. Then: +/// +/// The standard journald CODE_LINE and CODE_FILE fields are automatically +/// emitted. A TARGET field is emitted containing the event’s target. For +/// events recorded inside spans, an additional SPAN_NAME field is emitted +/// with the name of each of the event’s parent spans. User-defined fields +/// other than the event message field have a prefix applied by default to +/// prevent collision with standard fields. +/// +/// example: `journalctl -fu desk-sensors +/// --output-fields=CODE_FILE,CODE_LINE,MESSAGE -o cat` +pub fn setup() { + let env_filter = filter::EnvFilter::builder() + .with_regex(true) + .try_from_env() + .unwrap_or_else(|_| { + filter::EnvFilter::builder() + .with_default_directive(LevelFilter::INFO.into()) + .parse_lossy("") + }); + + let ratelimiter = ratelimited::Limiter::default() + .with_global_period(Duration::from_secs(1)) + .with_global_burst(20) + .with_callsite_period(Duration::from_secs(5)) + .with_global_burst(10) + .with_msg_period(Duration::from_secs(20)) + .with_msg_burst(10); + + let fmt = fmt::layer() + .pretty() + .with_writer(std::io::stderr) // to stderr as to not disrupt TUI's + .with_file(true) + .with_line_number(true) + .with_target(false) + .with_ansi(true); + + let registry = + tracing_subscriber::Registry::default().with(ErrorLayer::default()); + + if libsystemd::logging::connected_to_journal() { + match tracing_journald::layer() { + Ok(journal) => { + registry + .with( + journal + .with_filter(ratelimiter) + .with_filter(env_filter), + ) + .init(); + tracing::info!("Started logging & tracing to journald"); + } + Err(err) => { + registry + .with(fmt.with_filter(ratelimiter).with_filter(env_filter)) + .init(); + tracing::error!( + "Could not log to journald directly. Logging to stderr \ + as fallback. Error connecting to journald:: {err}" + ); + } + }; + } else { + registry + .with(fmt.with_filter(ratelimiter).with_filter(env_filter)) + .init(); + tracing::info!("Started logging & tracing to stderr"); + } +} + +pub fn setup_unlimited() { + let env_filter = filter::EnvFilter::builder() + .with_regex(true) + .try_from_env() + .unwrap_or_else(|_| { + filter::EnvFilter::builder() + .with_default_directive(LevelFilter::INFO.into()) + .parse_lossy("") + }); + + let fmt = fmt::layer() + .pretty() + .with_writer(std::io::stderr) // to stderr as to not disrupt TUI's + .with_file(true) + .with_line_number(true) + .with_target(false) + .with_ansi(true); + + tracing_subscriber::Registry::default() + .with(ErrorLayer::default()) + .with(fmt.with_filter(env_filter)) + .init(); +} + +pub fn setup_for_tests() { + use std::sync::Once; + use tracing_error::ErrorLayer; + use tracing_subscriber::{ + self, layer::SubscriberExt, util::SubscriberInitExt, Layer, + }; + + static INIT: Once = Once::new(); + + INIT.call_once(|| { + color_eyre::install().unwrap(); + + let file_subscriber = tracing_subscriber::fmt::layer() + .with_test_writer() + .with_file(true) + .with_line_number(true) + .with_target(false) + .with_ansi(true) + .pretty() + .with_filter( + tracing_subscriber::filter::EnvFilter::from_default_env(), + ); + tracing_subscriber::registry() + .with(file_subscriber) + .with(ErrorLayer::default()) + .init(); + }) +} diff --git a/crates/protocol/Cargo.lock b/crates/protocol/Cargo.lock new file mode 100644 index 00000000..7096c465 --- /dev/null +++ b/crates/protocol/Cargo.lock @@ -0,0 +1,264 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 3 + +[[package]] +name = "atomic-polyfill" +version = "1.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8cf2bce30dfe09ef0bfaef228b9d414faaf7e563035494d7fe092dba54b300f4" +dependencies = [ + "critical-section", +] + +[[package]] +name = "autocfg" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f1fdabc7756949593fe60f30ec81974b613357de856987752631dea1e3394c80" + +[[package]] +name = "byteorder" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" + +[[package]] +name = "cobs" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "67ba02a97a2bd10f4b59b25c7973101c79642302776489e030cd13cdab09ed15" + +[[package]] +name = "const_format" +version = "0.2.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e3a214c7af3d04997541b18d432afaff4c455e79e2029079647e72fc2bd27673" +dependencies = [ + "const_format_proc_macros", +] + +[[package]] +name = "const_format_proc_macros" +version = "0.2.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c7f6ff08fd20f4f299298a28e2dfa8a8ba1036e6cd2460ac1de7b425d76f2500" +dependencies = [ + "proc-macro2", + "quote", + "unicode-xid", +] + +[[package]] +name = "critical-section" +version = "1.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7059fff8937831a9ae6f0fe4d658ffabf58f2ca96aa9dec1c889f936f705f216" + +[[package]] +name = "embedded-io" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ef1a6892d9eef45c8fa6b9e0086428a2cca8491aca8f787c534a3d6d0bcb3ced" + +[[package]] +name = "hash32" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b0c35f58762feb77d74ebe43bdbc3210f09be9fe6742234d573bacc26ed92b67" +dependencies = [ + "byteorder", +] + +[[package]] +name = "hash32" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "47d60b12902ba28e2730cd37e95b8c9223af2808df9e902d4df49588d1470606" +dependencies = [ + "byteorder", +] + +[[package]] +name = "heapless" +version = "0.7.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cdc6457c0eb62c71aac4bc17216026d8410337c4126773b9c5daba343f17964f" +dependencies = [ + "atomic-polyfill", + "hash32 0.2.1", + "rustc_version", + "serde", + "spin", + "stable_deref_trait", +] + +[[package]] +name = "heapless" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0bfb9eb618601c89945a70e254898da93b13be0388091d42117462b265bb3fad" +dependencies = [ + "hash32 0.3.1", + "serde", + "stable_deref_trait", +] + +[[package]] +name = "lock_api" +version = "0.4.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "07af8b9cdd281b7915f413fa73f29ebd5d55d0d3f0155584dade1ff18cea1b17" +dependencies = [ + "autocfg", + "scopeguard", +] + +[[package]] +name = "postcard" +version = "1.0.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a55c51ee6c0db07e68448e336cf8ea4131a620edefebf9893e759b2d793420f8" +dependencies = [ + "cobs", + "const_format", + "embedded-io", + "heapless 0.7.17", + "postcard-derive", + "serde", +] + +[[package]] +name = "postcard-derive" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fc4b01218787dd4420daf63875163a787a78294ad48a24e9f6fa8c6507759a79" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "proc-macro2" +version = "1.0.81" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3d1597b0c024618f09a9c3b8655b7e430397a36d23fdafec26d6965e9eec3eba" +dependencies = [ + "unicode-ident", +] + +[[package]] +name = "protocol" +version = "0.1.0" +dependencies = [ + "heapless 0.8.0", + "postcard", + "serde", + "strum", +] + +[[package]] +name = "quote" +version = "1.0.36" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0fa76aaf39101c457836aec0ce2316dbdc3ab723cdda1c6bd4e6ad4208acaca7" +dependencies = [ + "proc-macro2", +] + +[[package]] +name = "rustc_version" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bfa0f585226d2e68097d4f95d113b15b83a82e819ab25717ec0590d9584ef366" +dependencies = [ + "semver", +] + +[[package]] +name = "scopeguard" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" + +[[package]] +name = "semver" +version = "1.0.22" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "92d43fe69e652f3df9bdc2b85b2854a0825b86e4fb76bc44d945137d053639ca" + +[[package]] +name = "serde" +version = "1.0.198" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9846a40c979031340571da2545a4e5b7c4163bdae79b301d5f86d03979451fcc" +dependencies = [ + "serde_derive", +] + +[[package]] +name = "serde_derive" +version = "1.0.198" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e88edab869b01783ba905e7d0153f9fc1a6505a96e4ad3018011eedb838566d9" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.60", +] + +[[package]] +name = "spin" +version = "0.9.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6980e8d7511241f8acf4aebddbb1ff938df5eebe98691418c4468d0b72a96a67" +dependencies = [ + "lock_api", +] + +[[package]] +name = "stable_deref_trait" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a8f112729512f8e442d81f95a8a7ddf2b7c6b8a1a6f509a95864142b30cab2d3" + +[[package]] +name = "strum" +version = "0.26.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5d8cec3501a5194c432b2b7976db6b7d10ec95c253208b45f83f7136aa985e29" + +[[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.60" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "909518bc7b1c9b779f1bbf07f2929d35af9f0f37e47c6e9ef7f9dddc1e1821f3" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[package]] +name = "unicode-ident" +version = "1.0.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" + +[[package]] +name = "unicode-xid" +version = "0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f962df74c8c05a667b5ee8bcf162993134c104e96440b663c8daa176dc772d8c" diff --git a/crates/protocol/Cargo.toml b/crates/protocol/Cargo.toml new file mode 100644 index 00000000..d410dbeb --- /dev/null +++ b/crates/protocol/Cargo.toml @@ -0,0 +1,20 @@ +[package] +name = "protocol" +version = "0.1.0" +rust-version.workspace = true +edition.workspace = true +license.workspace = true +authors.workspace = true + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] +serde.workspace = true +postcard = { version = "1.0.10", features = ["experimental-derive", "use-defmt"] } +heapless = { version = "0.8.0", features = ["serde", "defmt-03"] } +strum.workspace = true +thiserror = { workspace = true, optional = true } +defmt = "0.3.6" + +[features] +alloc = ["postcard/alloc", "serde/std"] diff --git a/crates/protocol/src/affector.rs b/crates/protocol/src/affector.rs new file mode 100644 index 00000000..3b1e37a0 --- /dev/null +++ b/crates/protocol/src/affector.rs @@ -0,0 +1,193 @@ +#[cfg(feature = "alloc")] +use core::ops::Range; + +use postcard::accumulator::{CobsAccumulator, FeedResult}; +use postcard::experimental::max_size::MaxSize; +use serde::{Deserialize, Serialize}; + +use crate::msg::cobs_overhead; +use crate::{large_bedroom, small_bedroom, DecodeMsgError}; + +#[cfg(feature = "alloc")] +pub mod tree; + +#[derive( + strum::EnumDiscriminants, + Clone, + Copy, + Debug, + defmt::Format, + Serialize, + Deserialize, + MaxSize, + PartialEq, + Eq, + Hash, +)] +#[strum_discriminants(derive(Hash))] +pub enum Affector { + LargeBedroom(large_bedroom::Affector), + SmallBedroom(small_bedroom::Affector), +} + +#[cfg(feature = "alloc")] +tree::all_nodes! {Affector; AffectorDiscriminants; LargeBedroom, SmallBedroom} + +#[cfg(feature = "alloc")] +#[derive(Debug, Clone)] +pub struct Info { + pub description: &'static str, +} + +#[cfg(feature = "alloc")] +pub enum ControlValue<'a> { + Trigger, + /// If you need floats just map this to a float + /// in the affector device like: `range = range/x + y` + SetNum { + valid_range: Range, + /// FnOnce such that value does become outdated + setter: Option>, + value: usize, + }, +} + +#[cfg(feature = "alloc")] +pub struct Control<'a> { + pub name: &'static str, + pub value: ControlValue<'a>, +} + +impl Affector { + pub const ENCODED_SIZE: usize = Affector::POSTCARD_MAX_SIZE + + cobs_overhead(Affector::POSTCARD_MAX_SIZE); + + #[cfg(feature = "alloc")] + #[must_use] + pub fn encode(&self) -> Vec { + postcard::to_allocvec_cobs(self).expect("Encoding should not fail") + } + + pub fn decode(mut bytes: impl AsMut<[u8]>) -> Result { + postcard::from_bytes_cobs(bytes.as_mut()) + .map_err(DecodeMsgError::CorruptEncoding) + } + + // Info() is explicitly not defined, use the tree impl to get at it + #[cfg(feature = "alloc")] + pub fn controls(&mut self) -> Vec> { + match self { + Affector::LargeBedroom(a) => a.controls(), + Affector::SmallBedroom(a) => a.controls(), + } + } +} + +pub struct Decoder { + cobs_buf: CobsAccumulator<{ 2 * Affector::ENCODED_SIZE }>, +} + +impl Default for Decoder { + fn default() -> Self { + Self { + cobs_buf: CobsAccumulator::new(), + } + } +} + +#[derive(Debug, defmt::Format)] +pub struct DeserializeError; + +impl Decoder { + /// If this returns Some(_, remaining) move the remaining into it again + pub fn feed<'a>( + &mut self, + read_bytes: &'a [u8], + ) -> Result, DeserializeError> { + let mut window = read_bytes; + while !window.is_empty() { + window = match self.cobs_buf.feed::(read_bytes) { + FeedResult::Consumed => break, + FeedResult::OverFull(new_window) => new_window, + FeedResult::DeserError(_) => return Err(DeserializeError), + FeedResult::Success { data, remaining } => { + return Ok(Some((data, remaining))) + } + } + } + Ok(None) + } +} + +#[derive(Debug, Clone, Serialize, Deserialize)] +pub struct ListMessage { + pub values: heapless::Vec, + pub version: u8, +} + +impl ListMessage { + /// +2 is for the version + /// +4 covers the length of the heapless list + pub const HALF_ENCODED_SIZE: usize = + (MAX_ITEMS * Affector::POSTCARD_MAX_SIZE + 2 + 4); + /// cobs and postcard encoded + pub const ENCODED_SIZE: usize = + Self::HALF_ENCODED_SIZE + cobs_overhead(Self::HALF_ENCODED_SIZE); + + #[cfg(feature = "alloc")] + #[must_use] + pub fn encode(&self) -> Vec { + postcard::to_allocvec_cobs(self).expect("Encoding should not fail") + } + + /// Buffer should be at least `Self::ENCODED_SIZE` long. The returned slice contains + /// the serialized data. It can be shorter then the input buffer. + #[must_use] + pub fn encode_slice<'a>(&self, buf: &'a mut [u8]) -> &'a mut [u8] { + postcard::to_slice_cobs(self, buf).expect("Encoding should not fail") + } + + #[must_use] + pub fn empty() -> Self { + Self { + values: heapless::Vec::new(), + version: 1, + } + } + + pub fn decode(mut bytes: impl AsMut<[u8]>) -> Result { + postcard::from_bytes_cobs(bytes.as_mut()) + .map_err(DecodeMsgError::CorruptEncoding) + } +} + +#[cfg(all(test, feature = "alloc"))] +mod test { + use super::*; + use large_bedroom::bed; + + #[test] + fn decoder_decodes_encoded() { + let test_affector = Affector::LargeBedroom( + large_bedroom::Affector::Bed(bed::Affector::RgbLed { + red: 0, + green: 5, + blue: 0, + }), + ); + + let encoded = test_affector.encode(); + let mut encoded_copy = encoded.clone(); + let decoded: Affector = + postcard::from_bytes_cobs(encoded_copy.as_mut_slice()).unwrap(); + assert_eq!(decoded, test_affector); + + let mut decoder = Decoder::default(); + + decoder.feed(&encoded).unwrap(); + let res = decoder.feed(&encoded).unwrap(); + + let empty_slice = [].as_slice(); + assert_eq!(res, Some((test_affector, empty_slice))); + } +} diff --git a/crates/protocol/src/affector/tree.rs b/crates/protocol/src/affector/tree.rs new file mode 100644 index 00000000..e7d22780 --- /dev/null +++ b/crates/protocol/src/affector/tree.rs @@ -0,0 +1,67 @@ +use super::Info; + +pub type Id = u8; +#[derive(Debug)] +pub enum Item<'a> { + Leaf(Info), + Node(&'a dyn Tree), +} + +pub trait Tree: core::fmt::Debug { + fn inner(&self) -> Item<'_>; + fn leaf(&self) -> Info + where + Self: Sized, + { + let mut current = self as &dyn Tree; + loop { + match current.inner() { + Item::Node(node) => current = node, + Item::Leaf(leaf) => return leaf, + } + } + } + fn name(&self) -> String { + let dbg_repr = format!("{self:?}"); + let split = dbg_repr.find('(').unwrap_or(dbg_repr.len()); + dbg_repr.split_at(split).0.to_string() + } + fn branch_id(&self) -> Id; +} + +macro_rules! impl_zero { + ($name:ident; $($var:ident),*) => { + impl crate::IsSameAs for $name { + #[allow(unreachable_patterns)] + fn is_same_as(&self, other: &Self) -> bool { + match (self, other) { + $(($name::$var(a), $name::$var(b)) => a.is_same_as(b),)* + (_, _) => false, + } + } + } + + }; +} +pub(crate) use impl_zero; + +macro_rules! all_nodes { + ($name:ident; $variant:ident; $($var:ident),*) => { + impl crate::affector::tree::Tree for $name { + fn inner(&self) -> crate::affector::tree::Item<'_> { + match self { + $( + $name::$var(inner) => crate::affector::tree::Item::Node(inner as &dyn crate::affector::tree::Tree) + ),* + } + } + + fn branch_id(&self) -> crate::affector::tree::Id { + $variant::from(self) as crate::affector::tree::Id + } + + } + crate::affector::tree::impl_zero!{$name; $($var),*} + }; +} +pub(crate) use all_nodes; diff --git a/crates/protocol/src/button.rs b/crates/protocol/src/button.rs new file mode 100644 index 00000000..d27f06f7 --- /dev/null +++ b/crates/protocol/src/button.rs @@ -0,0 +1,140 @@ +#[cfg(feature = "alloc")] +use crate::reading::LabelFormatter; +use serde::{Deserialize, Serialize}; + +// Duration of the press in milliseconds +#[derive( + Clone, + Copy, + Debug, + Serialize, + Deserialize, + postcard::experimental::max_size::MaxSize, + defmt::Format, + PartialEq, + Eq, +)] +pub struct Press(pub u16); + +impl Press { + #[must_use] + pub fn is_long(&self) -> bool { + self.0 > 300 + } +} + +/// turns an enum of empty variants into one with [`Press`](crate::Press) inside each variant also +/// adds a method `press(&self)` that returns an instance of [`Press`](crate::Press). It can be +/// used to quickly find out if a button event is a long or short press. +macro_rules! button_enum { + ( + $(#[$outer:meta])* + $name:ident {$($variant:ident,)*} + $device:expr; + ) => { + #[derive(strum::VariantNames)] + #[derive( + Clone, + Copy, + Debug, + serde::Serialize, + serde::Deserialize, + defmt::Format, + postcard::experimental::max_size::MaxSize, + PartialEq, + Eq, + )] + $(#[$outer])* // docs + /// SAFETY: must be repr(u8) or id `fn` will create undefined behavior + #[repr(u8)] + pub enum $name { + $($variant(crate::button::Press),)* + } + + impl $name { + #[must_use] + pub fn press(&self) -> crate::button::Press { + match self { + $(Self::$variant(d) => *d,)* + } + } + + pub fn variant_name(&self) -> &'static str { + match self { + $(Self::$variant(_) => stringify!($variant),)* + } + } + } + + impl From<$name> for f32 { + fn from(val: $name) -> Self { + match val { + $($name::$variant(p) if p.is_long() => 2.0,)* + $($name::$variant(_) => 1.0,)* + } + } + } + + #[cfg(feature = "alloc")] + impl crate::reading::tree::Tree for $name { + fn inner(&self) -> crate::reading::tree::Item<'_> { + let info = crate::reading::Info { + val: (*self).into(), + device: $device, + description: "button", + range: 0.0..=2.0, + resolution: 1.0, + unit: crate::Unit::None, + branch_id: self.branch_id(), + label_formatter: Box::new(crate::button::ButtonLabelFormatter), + }; + crate::reading::tree::Item::Leaf(info) + } + fn inner_mut(&mut self) -> crate::reading::tree::ItemMut<'_> { + crate::reading::tree::ItemMut::Leaf(self as &mut dyn core::any::Any) + } + + fn name(&self) -> String { + self.variant_name().to_owned() + } + fn branch_id(&self) -> crate::reading::tree::Id { + // SAFETY: Because `Self` is marked `repr(u8)`, its layout is a + // `repr(C)` `union` between `repr(C)` structs, each of which + // has the `u8` discriminant as its first field, so we can read + // the discriminant without offsetting the pointer. + let discriminant = unsafe { *<*const _>::from(self).cast::() }; + discriminant as crate::reading::tree::Id + } + } + + impl crate::IsSameAs for $name { + fn is_same_as(&self, other: &Self) -> bool { + match (self, other) { + $(($name::$variant(_), $name::$variant(_)) => true,)* + (_, _) => false, + } + } + } + }; +} +pub(crate) use button_enum; + +#[cfg(feature = "alloc")] +#[derive(Debug)] +pub struct ButtonLabelFormatter; + +#[cfg(feature = "alloc")] +impl LabelFormatter for ButtonLabelFormatter { + fn format(&self, value: f64, _: &crate::reading::Info) -> String { + match value { + 2.0 => "long press", + 1.0 => "short press", + 0.0 => "not pressed", + _ => "ButtonLabelFormatter error", + } + .to_string() + } + fn box_clone(&self) -> Box { + Box::new(Self) + } +} diff --git a/crates/protocol/src/device.rs b/crates/protocol/src/device.rs new file mode 100644 index 00000000..f9beeb0f --- /dev/null +++ b/crates/protocol/src/device.rs @@ -0,0 +1,54 @@ +use core::time::Duration; + +use postcard::experimental::max_size::MaxSize; +use serde::{Deserialize, Serialize}; + +use crate::{large_bedroom, small_bedroom, Affector, Reading}; + +#[derive( + Clone, + Debug, + defmt::Format, + Serialize, + Deserialize, + MaxSize, + PartialEq, + Eq, + Hash, +)] +pub enum Device { + LargeBedroom(large_bedroom::Device), + SmallBedroom(small_bedroom::Device), +} +impl Device { + #[must_use] + pub const fn info(&self) -> Info { + match self { + Device::LargeBedroom(dev) => dev.info(), + Device::SmallBedroom(dev) => dev.info(), + } + } +} + +#[derive(Debug)] +pub struct Info { + pub name: &'static str, + pub affects_readings: &'static [Reading], + pub affectors: &'static [Affector], + pub min_sample_interval: Duration, + pub max_sample_interval: Duration, + pub temporal_resolution: Duration, +} + +impl Info { + pub(crate) const fn button_defaults() -> Self { + Self { + name: "Buttons", + affects_readings: &[], + temporal_resolution: Duration::from_millis(1), + min_sample_interval: Duration::from_millis(2), + max_sample_interval: Duration::MAX, + affectors: &[], + } + } +} diff --git a/crates/protocol/src/device_tree.rs b/crates/protocol/src/device_tree.rs new file mode 100644 index 00000000..e69de29b diff --git a/crates/protocol/src/error.rs b/crates/protocol/src/error.rs new file mode 100644 index 00000000..d7d3de14 --- /dev/null +++ b/crates/protocol/src/error.rs @@ -0,0 +1,45 @@ +use postcard::experimental::max_size::MaxSize; +use serde::{Deserialize, Serialize}; + +use crate::{large_bedroom, small_bedroom, Device}; + +#[derive( + strum::EnumDiscriminants, + strum::VariantNames, + Clone, + Debug, + defmt::Format, + Serialize, + Deserialize, + MaxSize, + PartialEq, + Eq, +)] +pub enum Error { + LargeBedroom(large_bedroom::Error), + SmallBedroom(small_bedroom::Error), +} + +impl Error { + #[must_use] + pub fn device(&self) -> Device { + match self { + Error::LargeBedroom(error) => Device::LargeBedroom(error.device()), + Error::SmallBedroom(error) => Device::SmallBedroom(error.device()), + } + } + + #[must_use] + pub const fn max_size() -> usize { + Self::POSTCARD_MAX_SIZE + } +} + +impl core::fmt::Display for Error { + fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { + match self { + Error::LargeBedroom(error) => write!(f, "{error}"), + Error::SmallBedroom(error) => write!(f, "{error}"), + } + } +} diff --git a/crates/protocol/src/large_bedroom.rs b/crates/protocol/src/large_bedroom.rs new file mode 100644 index 00000000..cba205c9 --- /dev/null +++ b/crates/protocol/src/large_bedroom.rs @@ -0,0 +1,136 @@ +use postcard::experimental::max_size::MaxSize; +use serde::{Deserialize, Serialize}; + +#[cfg(feature = "alloc")] +use crate::{affector, reading}; + +pub mod airbox; +pub mod bed; +pub mod desk; +pub mod desk_right; +pub mod radiator; + +#[derive( + strum::EnumDiscriminants, + Clone, + Copy, + Debug, + defmt::Format, + Serialize, + Deserialize, + MaxSize, + PartialEq, +)] +#[strum_discriminants(derive(Hash))] +#[repr(u8)] +pub enum Reading { + Bed(bed::Reading) = 0, + Desk(desk::Reading) = 1, + DeskRight(desk_right::Reading) = 4, + Radiator(radiator::Reading) = 2, + Airbox(airbox::Reading) = 3, +} + +#[cfg(feature = "alloc")] +reading::tree::all_nodes! {Reading; ReadingDiscriminants; Bed, Desk, Radiator, Airbox, DeskRight} + +#[derive( + strum::EnumDiscriminants, + Clone, + Debug, + defmt::Format, + Serialize, + Deserialize, + MaxSize, + Eq, + PartialEq, +)] +pub enum Error { + Bed(bed::Error), + Desk(desk::Error), + Airbox(airbox::Error), +} + +impl Error { + #[must_use] + pub fn device(&self) -> Device { + match self { + Error::Bed(error) => Device::Bed(error.device()), + Error::Desk(error) => Device::Desk(error.device()), + Error::Airbox(error) => Device::Airbox(error.device()), + } + } +} + +impl core::fmt::Display for Error { + fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { + match self { + Error::Bed(error) => write!(f, "{error}"), + Error::Desk(error) => write!(f, "{error}"), + Error::Airbox(error) => write!(f, "{error}"), + } + } +} + +#[derive( + Clone, + Debug, + defmt::Format, + Serialize, + Deserialize, + MaxSize, + Eq, + PartialEq, + Hash, +)] +pub enum Device { + Bed(bed::Device), + Desk(desk::Device), + DeskRight(desk_right::Device), + Radiator(radiator::Device), + Airbox(airbox::Device), +} + +impl Device { + #[must_use] + pub const fn info(&self) -> crate::DeviceInfo { + match self { + Self::Bed(dev) => dev.info(), + Self::Desk(dev) => dev.info(), + Self::DeskRight(dev) => dev.info(), + Self::Radiator(dev) => dev.info(), + Self::Airbox(dev) => dev.info(), + } + } +} + +#[derive( + strum::EnumDiscriminants, + Clone, + Copy, + Debug, + defmt::Format, + Serialize, + Deserialize, + MaxSize, + PartialEq, + Eq, + Hash, +)] +#[strum_discriminants(derive(Hash))] +pub enum Affector { + Bed(bed::Affector), + Airbox(airbox::Affector), +} +impl Affector { + #[cfg(feature = "alloc")] + pub(crate) fn controls(&mut self) -> Vec> { + match self { + Affector::Bed(a) => a.controls(), + Affector::Airbox(a) => a.controls(), + } + } +} + +#[cfg(feature = "alloc")] +affector::tree::all_nodes! {Affector; AffectorDiscriminants; Bed, Airbox} diff --git a/crates/protocol/src/large_bedroom/airbox.rs b/crates/protocol/src/large_bedroom/airbox.rs new file mode 100644 index 00000000..ad013488 --- /dev/null +++ b/crates/protocol/src/large_bedroom/airbox.rs @@ -0,0 +1,305 @@ +use core::time::Duration; + +#[cfg(feature = "alloc")] +use crate::affector::{self, Control, ControlValue}; +use crate::button::Press; +use postcard::experimental::max_size::MaxSize; +use serde::{Deserialize, Serialize}; + +#[cfg(feature = "alloc")] +use crate::reading::tree::{Item, ItemMut, Tree}; +#[cfg(feature = "alloc")] +use crate::reading::FloatLabelFormatter; +#[cfg(feature = "alloc")] +use crate::reading::Info; +use crate::shared::impl_is_same_as; +#[cfg(feature = "alloc")] +use crate::Unit; + +#[derive( + strum::EnumDiscriminants, + Clone, + Copy, + Debug, + defmt::Format, + Serialize, + Deserialize, + MaxSize, + PartialEq, +)] +#[strum_discriminants(derive(Hash))] +#[repr(u8)] +pub enum Reading { + Temperature(f32) = 0, + Pressure(f32) = 1, + FanPower(f32) = 2, + Button(Press) = 3, +} + +impl_is_same_as! {Reading; Temperature, Pressure, FanPower, Button} + +#[cfg(feature = "alloc")] +impl Tree for Reading { + fn inner(&self) -> Item<'_> { + let info = match self { + Reading::Temperature(val) => Info { + val: *val, + device: Device::Bme280.rooted(), + resolution: 0.01, + range: -10.0..=45.0, + unit: Unit::C, + description: "Temperature", + branch_id: self.branch_id(), + label_formatter: Box::new(FloatLabelFormatter), + }, + Reading::Pressure(val) => Info { + val: *val, + device: Device::Bme280.rooted(), + range: 87_000.0..=108_100.0, + resolution: 0.18, + unit: Unit::Pa, + description: "Air pressure", + branch_id: self.branch_id(), + label_formatter: Box::new(FloatLabelFormatter), + }, + Reading::FanPower(val) => Info { + val: *val as u8 as f32, + device: crate::Device::LargeBedroom(super::Device::Airbox( + Device::Fans, + )), + resolution: 1.0, + range: 0.0..=100.0, + unit: Unit::RelativePower, + description: "Fan power", + branch_id: self.branch_id(), + label_formatter: Box::new(FloatLabelFormatter), + }, + Reading::Button(press) => Info { + val: if press.is_long() { 2.0 } else { 1.0 }, + device: crate::Device::LargeBedroom(super::Device::Airbox( + Device::Gpio, + )), + description: "button", + range: 0.0..=2.0, + resolution: 1.0, + unit: crate::Unit::None, + branch_id: self.branch_id(), + label_formatter: Box::new(crate::button::ButtonLabelFormatter), + }, + }; + Item::Leaf(info) + } + + fn inner_mut(&mut self) -> ItemMut<'_> { + use crate::reading::tree::field_as_any; + + let value = + field_as_any!(self, Temperature, Pressure, FanPower, Button); + ItemMut::Leaf(value) + } + + fn branch_id(&self) -> crate::reading::tree::Id { + ReadingDiscriminants::from(self) as crate::reading::tree::Id + } +} + +#[derive( + Clone, Debug, defmt::Format, Serialize, Deserialize, MaxSize, Eq, PartialEq, +)] +pub enum Error { + Running(DeviceError), + Setup(DeviceError), + SetupTimedOut(Device), + Timeout(Device), +} + +impl Error { + pub fn device(&self) -> Device { + match self { + Self::Running(sensor_err) | Self::Setup(sensor_err) => { + sensor_err.device() + } + Self::SetupTimedOut(device) | Self::Timeout(device) => { + device.clone() + } + } + } +} + +impl core::fmt::Display for Error { + fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { + match self { + Error::Running(e) => { + write!(f, "{} ran into error: {e}", e.device()) + } + Error::Setup(e) => { + write!(f, "{} errored during setup: {e}", e.device()) + } + Error::SetupTimedOut(d) => write!(f, "{d} timed out during setup"), + Error::Timeout(d) => write!(f, "{d} timed out while running"), + } + } +} + +#[derive( + Clone, Debug, defmt::Format, Serialize, Deserialize, Eq, PartialEq, +)] +pub enum DeviceError { + BmeError(heapless::String<200>), + Pwm(heapless::String<200>), +} + +impl DeviceError { + fn device(&self) -> Device { + Device::Bme280 + } +} + +impl core::fmt::Display for DeviceError { + fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { + match self { + DeviceError::BmeError(e) => write!(f, "Bme error: {e}"), + DeviceError::Pwm(e) => write!(f, "Pwm error:{e}"), + } + } +} + +impl MaxSize for DeviceError { + const POSTCARD_MAX_SIZE: usize = 200 + 1; +} + +#[derive( + Clone, + Debug, + defmt::Format, + Serialize, + Deserialize, + MaxSize, + Eq, + PartialEq, + Hash, +)] +pub enum Device { + Bme280, + Fans, + Gpio, +} + +impl core::fmt::Display for Device { + fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { + write!(f, "{}", self.info().name) + } +} + +macro_rules! tree { + [$thing:ident; $($item:expr),+] => { + [$(crate::$thing::LargeBedroom( + crate::large_bedroom::$thing::Airbox($item), + )),+] + }; +} + +impl Device { + #[must_use] + pub fn rooted(self) -> crate::Device { + crate::Device::LargeBedroom(crate::large_bedroom::Device::Airbox(self)) + } + + /// Note the order in which the `affects_readings` occur is the order in which + /// they will be stored, do not change it! + #[must_use] + pub const fn info(&self) -> crate::DeviceInfo { + match self { + Device::Bme280 => crate::DeviceInfo { + name: "Bme280", + affects_readings: &tree![ + Reading; Reading::Temperature(0.0), Reading::Pressure(0.0)], + temporal_resolution: Duration::from_secs(5), // unknown + min_sample_interval: Duration::from_secs(5), // unknown + max_sample_interval: Duration::MAX, + affectors: &[], + }, + Device::Fans => crate::DeviceInfo { + name: "Fans", + affects_readings: &tree![Reading; Reading::FanPower(0.0) ], + temporal_resolution: Duration::from_secs(5), // unknown + min_sample_interval: Duration::from_secs(5), // unknown + max_sample_interval: Duration::MAX, + affectors: &[], + }, + Self::Gpio => crate::DeviceInfo { + name: "Gpio", + affects_readings: &tree![Reading; Reading::Button(Press(0)) ], + temporal_resolution: Duration::from_millis(50), // unknown + min_sample_interval: Duration::from_millis(50), // unknown + max_sample_interval: Duration::MAX, + affectors: &[], + }, + } + } +} + +#[derive( + strum::EnumDiscriminants, + Clone, + Copy, + Debug, + defmt::Format, + Serialize, + Deserialize, + MaxSize, + PartialEq, + Eq, + Hash, +)] +#[strum_discriminants(derive(Hash))] +pub enum Affector { + FanPower { power: u8 }, + ResetNode, +} + +impl crate::IsSameAs for Affector { + fn is_same_as(&self, other: &Self) -> bool { + matches!( + (self, other), + (Affector::FanPower { .. }, Affector::FanPower { .. }) + | (Affector::ResetNode, Affector::ResetNode) + ) + } +} + +impl Affector { + #[cfg(feature = "alloc")] + pub fn controls(&mut self) -> Vec> { + match self { + Affector::FanPower { power } => vec![Control { + name: "red", + value: ControlValue::SetNum { + valid_range: 0..100, + value: *power as usize, + setter: Some(Box::new(|input: usize| *power = input as u8)), + }, + }], + Affector::ResetNode => vec![Control { + name: "reset the node", + value: ControlValue::Trigger, + }], + } + } +} + +#[cfg(feature = "alloc")] +impl affector::tree::Tree for Affector { + fn inner(&self) -> affector::tree::Item<'_> { + let description = match self { + Affector::FanPower { .. } => "Set the power of the fans", + Affector::ResetNode => "Reset the node, this might fix errors such as I2c getting stuck after Arbitration Error", + }; + + affector::tree::Item::Leaf(affector::Info { description }) + } + + fn branch_id(&self) -> affector::tree::Id { + AffectorDiscriminants::from(self) as affector::tree::Id + } +} diff --git a/crates/protocol/src/large_bedroom/bed.rs b/crates/protocol/src/large_bedroom/bed.rs new file mode 100644 index 00000000..208c560e --- /dev/null +++ b/crates/protocol/src/large_bedroom/bed.rs @@ -0,0 +1,640 @@ +use core::time::Duration; + +#[cfg(feature = "alloc")] +use crate::affector::{Control, ControlValue}; +use crate::button::Press; +use crate::button_enum; +#[cfg(feature = "alloc")] +use crate::reading::tree::{Id, Item, ItemMut, Tree}; +#[cfg(feature = "alloc")] +use crate::reading::FloatLabelFormatter; +#[cfg(feature = "alloc")] +use crate::reading::Info; +use crate::shared::impl_is_same_as; +#[cfg(feature = "alloc")] +use crate::{affector, Unit}; + +use postcard::experimental::max_size::MaxSize; +use serde::{Deserialize, Serialize}; + +button_enum! { + /// All button are on the headboard of the bed. As seen from the foot of the + /// bed it looks like this: + /// + /// LR----------------------------| + /// |--------------|--------------| + /// |-----------321|123-----------| + /// |654-----------|-----------456| + /// + /// Legend: + /// L: TopLeft, R: TopRight, 1: MiddleInner, 2: MiddleCenter, 3: MiddleOuter, + /// 4: OuterInner, 5: OuterCenter, 6: OuterOuter + Button { + Top, + MiddleInner, + MiddleCenter, + MiddleOuter, + LowerInner, + LowerCenter, + LowerOuter, + } + crate::Device::LargeBedroom(crate::large_bedroom::Device::Bed(Device::Gpio)); +} + +#[derive( + strum::EnumDiscriminants, + Clone, + Copy, + Debug, + defmt::Format, + Serialize, + Deserialize, + MaxSize, + PartialEq, +)] +#[strum_discriminants(derive(Hash))] +#[repr(u8)] +pub enum Reading { + Button(Button) = 0, + Brightness(f32) = 1, + Temperature(f32) = 2, + Humidity(f32) = 3, + GassResistance(f32) = 4, // In Ohm + Pressure(f32) = 5, + /// Parts per million + Co2(u16) = 6, + /// Weight on the left side of the bed + WeightLeft(u32) = 7, + /// Weight on the right side of the bed + WeightRight(u32) = 8, + + /// Mass Concentration PM1.0 \[μg/m³\] + MassPm1_0(f32) = 9, + /// Mass Concentration PM2.5 \[μg/m³\] + MassPm2_5(f32) = 10, + /// Mass Concentration PM4.0 \[μg/m³\] + MassPm4_0(f32) = 11, + /// Mass Concentration PM10 \[μg/m³\] + MassPm10(f32) = 12, + /// Number Concentration PM0.5 \[#/cm³\] + NumberPm0_5(f32) = 13, + /// Number Concentration PM1.0 \[#/cm³\] + NumberPm1_0(f32) = 14, + /// Number Concentration PM2.5 \[#/cm³\] + NumberPm2_5(f32) = 15, + /// Number Concentration PM4.0 \[#/cm³\] + NumberPm4_0(f32) = 16, + /// Number Concentration PM10 \[#/cm³\] + NumberPm10(f32) = 17, + /// Typical Particle Size8 \[μm\] + TypicalParticleSize(f32) = 18, +} + +#[cfg(feature = "alloc")] +impl Tree for Reading { + #[allow(clippy::too_many_lines)] + #[allow(clippy::cast_precision_loss)] + fn inner(&self) -> Item<'_> { + let (val, device, range, resolution, unit, description) = match self { + Reading::Brightness(val) => ( + *val, + Device::Max44.rooted(), + 0.0..=188_000.0, + 0.045, + Unit::Lux, + "Brightness", + ), + Reading::Temperature(val) => ( + *val, + Device::Sht31.rooted(), + -10.0..=45.0, + 0.01, + Unit::C, + "Temperature", + ), + Reading::Humidity(val) => ( + *val, + Device::Sht31.rooted(), + 0.0..=100.0, + 0.01, + Unit::RH, + "Relative humidity", + ), + // air quality: comp_gas = log(R_gas[ohm]) + 0.04 log(Ohm)/%rh * hum[%rh] + Reading::GassResistance(val) => ( + *val, + Device::Bme680.rooted(), + 0.0..=1_000_000.0, + 1.0, + Unit::Ohm, + "Gass resistance", + ), + // record air pressure + // - 1.081hPa (dead sea 430 below normal sea level) + // - 870hPa (middle of a tornado) + Reading::Pressure(val) => ( + *val, + Device::Bme680.rooted(), + 87_000.0..=108_100.0, + 0.18, + Unit::Pa, + "Air pressure", + ), + Reading::Co2(val) => ( + f32::from(*val), + Device::Mhz14.rooted(), + 400.0..=2_000.0, + 1.0, + Unit::Ppm, + "Co2 concentration", + ), + Reading::WeightLeft(val) => ( + *val as f32, + Device::Nau7802Left.rooted(), + 0.0..=24.0_f32.exp2(), + 1.0, + Unit::Ohm, + "Left weight sensor resistance", + ), + Reading::WeightRight(val) => ( + *val as f32, + Device::Nau7802Right.rooted(), + 0.0..=24.0_f32.exp2(), + 1.0, + Unit::Ohm, + "Right weight sensor resistance", + ), + Reading::Button(button) => return Item::Node(button), + Reading::MassPm1_0(val) => ( + *val, + Device::Sps30.rooted(), + 0.0..=1000.0, + 0.1, + Unit::MicrogramPerM3, + "Mass concentration particles between 0.3 to 1.0 μm", + ), + Reading::MassPm2_5(val) => ( + *val, + Device::Sps30.rooted(), + 0.0..=1000.0, + 0.1, + Unit::MicrogramPerM3, + "Mass concentration particles between 0.3 to 2.5 μm", + ), + Reading::MassPm4_0(val) => ( + *val, + Device::Sps30.rooted(), + 0.0..=1000.0, + 0.1, + Unit::MicrogramPerM3, + "Mass concentration particles between 0.3 to 4.0 μm", + ), + Reading::MassPm10(val) => ( + *val, + Device::Sps30.rooted(), + 0.0..=1000.0, + 0.1, + Unit::MicrogramPerM3, + "Mass concentration particles between 0.3 to 10.0 μm", + ), + Reading::NumberPm0_5(val) => ( + *val, + Device::Sps30.rooted(), + 0.0..=3000.0, + 0.1, + Unit::NumberPerCm3, + "Concentration of particles between 0.3 to 0.5 μm", + ), + Reading::NumberPm1_0(val) => ( + *val, + Device::Sps30.rooted(), + 0.0..=3000.0, + 0.1, + Unit::NumberPerCm3, + "Concentration of particles between 0.3 to 1.0 μm", + ), + Reading::NumberPm2_5(val) => ( + *val, + Device::Sps30.rooted(), + 0.0..=3000.0, + 0.1, + Unit::NumberPerCm3, + "Concentration of particles between 0.3 to 2.5 μm", + ), + Reading::NumberPm4_0(val) => ( + *val, + Device::Sps30.rooted(), + 0.0..=3000.0, + 0.1, + Unit::NumberPerCm3, + "Concentration of particles between 0.3 to 4.0 μm", + ), + Reading::NumberPm10(val) => ( + *val, + Device::Sps30.rooted(), + 0.0..=3000.0, + 0.1, + Unit::NumberPerCm3, + "Concentration of particles between 0.3 to 10.5 μm", + ), + Reading::TypicalParticleSize(val) => ( + *val, + Device::Sps30.rooted(), + 0.0..=10_000.0, + 0.5, + Unit::NanoMeter, + "Typical particle size", + ), + }; + + let info = Info { + val, + device, + resolution, + range, + unit, + description, + branch_id: self.branch_id(), + label_formatter: Box::new(FloatLabelFormatter), + }; + + Item::Leaf(info) + } + + fn inner_mut(&mut self) -> ItemMut<'_> { + use crate::reading::tree::field_as_any; + + let value = field_as_any!( + self, + Brightness, + Temperature, + Humidity, + GassResistance, + Pressure, + Co2, + WeightLeft, + WeightRight, + MassPm1_0, + MassPm2_5, + MassPm4_0, + MassPm10, + NumberPm0_5, + NumberPm1_0, + NumberPm2_5, + NumberPm4_0, + NumberPm10, + TypicalParticleSize, + Button + ); + ItemMut::Leaf(value) + } + + fn branch_id(&self) -> Id { + ReadingDiscriminants::from(self) as Id + } +} + +impl_is_same_as! {Reading; Brightness, Temperature, Humidity, GassResistance, Pressure, + Co2, WeightLeft, WeightRight, MassPm1_0, MassPm2_5, MassPm4_0, MassPm10, NumberPm0_5, + NumberPm1_0, NumberPm2_5, NumberPm4_0, NumberPm10, TypicalParticleSize; + (Self::Button(a), Self::Button(b)) => a.is_same_as(b) +} + +#[derive( + Clone, Debug, defmt::Format, Serialize, Deserialize, MaxSize, Eq, PartialEq, +)] +pub enum Error { + Running(SensorError), + Setup(SensorError), + SetupTimedOut(Device), + Timeout(Device), +} + +impl Error { + #[must_use] + pub(crate) fn device(&self) -> Device { + match self { + Self::Running(sensor_err) | Self::Setup(sensor_err) => { + sensor_err.device() + } + Self::SetupTimedOut(device) | Self::Timeout(device) => { + device.clone() + } + } + } +} + +impl core::fmt::Display for Error { + fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { + match self { + Error::Running(e) => write!(f, "{e}"), + Error::Setup(e) => write!(f, "setup: {e}"), + Error::SetupTimedOut(_) => write!(f, "setup timed out"), + Error::Timeout(_) => write!(f, "timed out running"), + } + } +} + +#[derive( + Clone, Debug, defmt::Format, Serialize, Deserialize, Eq, PartialEq, +)] +pub enum SensorError { + Sht31(heapless::String<200>), + Bme680(heapless::String<200>), + Max44(heapless::String<200>), + Mhz14(heapless::String<200>), + Sps30(heapless::String<200>), + Button(heapless::String<200>), + Nau7802Left(heapless::String<200>), + Nau7802Right(heapless::String<200>), +} + +impl core::fmt::Display for SensorError { + fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { + match self { + SensorError::Sht31(e) + | SensorError::Bme680(e) + | SensorError::Max44(e) + | SensorError::Mhz14(e) + | SensorError::Sps30(e) + | SensorError::Button(e) + | SensorError::Nau7802Left(e) + | SensorError::Nau7802Right(e) => write!(f, "{e}"), + } + } +} + +impl MaxSize for SensorError { + const POSTCARD_MAX_SIZE: usize = 201; +} + +impl SensorError { + #[must_use] + pub fn device(&self) -> Device { + match self { + SensorError::Sht31(_) => Device::Sht31, + SensorError::Bme680(_) => Device::Bme680, + SensorError::Max44(_) => Device::Max44, + SensorError::Mhz14(_) => Device::Mhz14, + SensorError::Sps30(_) => Device::Sps30, + SensorError::Button(_) => Device::Gpio, + SensorError::Nau7802Left(_) => Device::Nau7802Right, + SensorError::Nau7802Right(_) => Device::Nau7802Right, + } + } +} + +#[derive( + Clone, + Debug, + defmt::Format, + Serialize, + Deserialize, + MaxSize, + Eq, + PartialEq, + Hash, +)] +pub enum Device { + Sht31, + Bme680, + Max44, + Mhz14, + Sps30, + Nau7802Right, + Nau7802Left, + Gpio, +} + +impl core::fmt::Display for Device { + fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { + write!(f, "{}", self.info().name) + } +} + +macro_rules! tree { + [$thing:ident; $($item:expr),+] => { + [$(crate::$thing::LargeBedroom( + crate::large_bedroom::$thing::Bed($item), + )),+] + }; +} + +impl Device { + /// Note the order in which the `affects_readings` occur is the order in which + /// they will be stored, do not change it! + #[must_use] + pub const fn info(&self) -> crate::DeviceInfo { + let min_sample_interval = Duration::from_secs(5); + let max_sample_interval = Duration::from_secs(5); + let temporal_resolution = Duration::from_secs(1); + match self { + Device::Sht31 => crate::DeviceInfo { + name: "Sht31", + affects_readings: &tree![Reading; Reading::Temperature(0.0), Reading::Humidity(0.0)], + temporal_resolution, + min_sample_interval, + max_sample_interval, + affectors: &[], + }, + Device::Bme680 => crate::DeviceInfo { + name: "Bme680", + affects_readings: &tree![Reading; + Reading::GassResistance(0.0), + Reading::Pressure(0.0) + ], + temporal_resolution, + min_sample_interval, + max_sample_interval, + affectors: &[], + }, + Device::Max44 => crate::DeviceInfo { + name: "Max44", + affects_readings: &tree![Reading; Reading::Brightness(0.0)], + temporal_resolution: Duration::from_millis(50), + min_sample_interval: Duration::from_millis(50), + max_sample_interval, + affectors: &[], + }, + Device::Mhz14 => crate::DeviceInfo { + name: "Mhz14", + affects_readings: &tree![Reading; Reading::Co2(0)], + temporal_resolution, + min_sample_interval, + max_sample_interval, + affectors: &tree!(Affector; Affector::MhzZeroPointCalib), + }, + Device::Sps30 => crate::DeviceInfo { + name: "Sps30", + affects_readings: &tree![Reading; + Reading::MassPm1_0(0.0), + Reading::MassPm2_5(0.0), + Reading::MassPm4_0(0.0), + Reading::MassPm10(0.0), + Reading::NumberPm0_5(0.0), + Reading::NumberPm1_0(0.0), + Reading::NumberPm2_5(0.0), + Reading::NumberPm4_0(0.0), + Reading::NumberPm10(0.0), + Reading::TypicalParticleSize(0.0) + ], + temporal_resolution, + min_sample_interval, + max_sample_interval, + affectors: &tree!(Affector; Affector::Sps30FanClean), + }, + Device::Nau7802Left => crate::DeviceInfo { + name: "Nau7802Left", + affects_readings: &tree![Reading; Reading::WeightLeft(0)], + temporal_resolution: Duration::from_millis(100), + min_sample_interval: Duration::from_millis(100), + max_sample_interval, + affectors: &tree!(Affector; Affector::Nau7802LeftCalib), + }, + Device::Nau7802Right => crate::DeviceInfo { + name: "Nau7802Right", + affects_readings: &tree![Reading; Reading::WeightRight(0)], + temporal_resolution: Duration::from_millis(100), + min_sample_interval: Duration::from_millis(100), + max_sample_interval, + affectors: &tree!(Affector; Affector::Nau7802RightCalib), + }, + Device::Gpio => crate::DeviceInfo { + affects_readings: &tree![Reading; + Reading::Button(Button::Top(Press(0))), + Reading::Button(Button::MiddleInner(Press(0))), + Reading::Button(Button::MiddleCenter(Press(0))), + Reading::Button(Button::MiddleOuter(Press(0))), + Reading::Button(Button::LowerInner(Press(0))), + Reading::Button(Button::LowerCenter(Press(0))), + Reading::Button(Button::LowerOuter(Press(0))) + ], + ..crate::DeviceInfo::button_defaults() + }, + } + } + + #[cfg(feature = "alloc")] + #[must_use] + const fn rooted(self) -> crate::Device { + crate::Device::LargeBedroom(crate::large_bedroom::Device::Bed(self)) + } +} + +#[derive( + strum::EnumDiscriminants, + Clone, + Copy, + Debug, + defmt::Format, + Serialize, + Deserialize, + MaxSize, + PartialEq, + Eq, + Hash, +)] +#[strum_discriminants(derive(Hash))] +pub enum Affector { + Sps30FanClean, + MhzZeroPointCalib, + Nau7802LeftCalib, + Nau7802RightCalib, + RgbLed { red: u8, green: u8, blue: u8 }, + ResetNode, +} + +impl crate::IsSameAs for Affector { + fn is_same_as(&self, other: &Self) -> bool { + #[allow(clippy::match_like_matches_macro)] + match (self, other) { + (Affector::Sps30FanClean, Affector::Sps30FanClean) => true, + (Affector::MhzZeroPointCalib, Affector::MhzZeroPointCalib) => true, + (Affector::Nau7802LeftCalib, Affector::Nau7802LeftCalib) => true, + (Affector::Nau7802RightCalib, Affector::Nau7802RightCalib) => true, + (Affector::RgbLed { .. }, Affector::RgbLed { .. }) => true, + (Affector::ResetNode, Affector::ResetNode) => true, + _ => false, + } + } +} + +impl Affector { + #[cfg(feature = "alloc")] + pub fn controls(&mut self) -> Vec> { + match self { + Affector::Sps30FanClean => vec![Control { + name: "start fan cleaning", + value: ControlValue::Trigger, + }], + Affector::MhzZeroPointCalib => vec![Control { + name: "calibrate current reading as 400 ppm", + value: ControlValue::Trigger, + }], + Affector::Nau7802LeftCalib => vec![Control { + name: "things with ac power noise or something", + value: ControlValue::Trigger, + }], + Affector::Nau7802RightCalib => vec![Control { + name: "things with ac power noise or something", + value: ControlValue::Trigger, + }], + Affector::RgbLed { red, green, blue } => vec![ + Control { + name: "red", + value: ControlValue::SetNum { + valid_range: 0..255, + value: *red as usize, + setter: Some(Box::new(|input: usize| { + *red = input as u8 + })), + }, + }, + Control { + name: "green", + value: ControlValue::SetNum { + valid_range: 0..255, + value: *green as usize, + setter: Some(Box::new(|input: usize| { + *green = input as u8 + })), + }, + }, + Control { + name: "blue", + value: ControlValue::SetNum { + valid_range: 0..255, + value: *blue as usize, + setter: Some(Box::new(|input: usize| { + *blue = input as u8 + })), + }, + }, + ], + Affector::ResetNode => vec![Control { + name: "reset the node", + value: ControlValue::Trigger, + }], + } + } +} + +#[cfg(feature = "alloc")] +impl affector::tree::Tree for Affector { + fn inner(&self) -> affector::tree::Item<'_> { + let description = match self { + Affector::Sps30FanClean => "Accelerate the fan to maximum speed for 10 seconds in order to blow out the dust accumulated in the fan", + Affector::MhzZeroPointCalib => "Set the current co2 value as 400ppm", + Affector::Nau7802LeftCalib | + Affector::Nau7802RightCalib => "Detect and correct power supply and temperature variations to ADC", + Affector::RgbLed {..} => "Set color & power of the RGB led at the top of the bed post", + Affector::ResetNode => "Reset the node, this might fix errors such as I2c getting stuck after Arbitration Error", + }; + + affector::tree::Item::Leaf(affector::Info { description }) + } + + fn branch_id(&self) -> affector::tree::Id { + AffectorDiscriminants::from(self) as Id + } +} diff --git a/crates/protocol/src/large_bedroom/desk.rs b/crates/protocol/src/large_bedroom/desk.rs new file mode 100644 index 00000000..2185a986 --- /dev/null +++ b/crates/protocol/src/large_bedroom/desk.rs @@ -0,0 +1,243 @@ +use core::time::Duration; + +use postcard::experimental::max_size::MaxSize; +use serde::{Deserialize, Serialize}; + +use crate::button::Press; +#[cfg(feature = "alloc")] +use crate::reading::tree::{Item, Tree}; +#[cfg(feature = "alloc")] +use crate::reading::FloatLabelFormatter; +#[cfg(feature = "alloc")] +use crate::reading::Info; +use crate::shared::impl_is_same_as; +#[cfg(feature = "alloc")] +use crate::Unit; +use crate::{button_enum, DeviceInfo}; + +button_enum! { + /// No these are not borg, these are buttons on a string of cat5. + /// They are numbered starting at the farthest from the end + Button { + OneOfFour, + TwoOfFour, + ThreeOfFour, + FourOfFour, + OneOfThree, + TwoOfThree, + ThreeOfThree, + } + crate::Device::LargeBedroom(crate::large_bedroom::Device::Desk(Device::Gpio)); +} + +#[derive( + strum::EnumDiscriminants, + Clone, + Copy, + Debug, + defmt::Format, + Serialize, + Deserialize, + MaxSize, + PartialEq, +)] +#[strum_discriminants(derive(Hash))] +#[repr(u8)] +pub enum Reading { + Temperature(f32) = 0, + Humidity(f32) = 1, + Pressure(f32) = 2, + Button(Button) = 3, +} + +#[cfg(feature = "alloc")] +impl Tree for Reading { + fn inner(&self) -> Item<'_> { + let info = match self { + Reading::Temperature(val) => Info { + val: *val, + device: Device::Bme280.rooted(), + resolution: 0.01, + range: -10.0..=45.0, + unit: Unit::C, + description: "Temperature", + branch_id: self.branch_id(), + label_formatter: Box::new(FloatLabelFormatter), + }, + Reading::Humidity(val) => Info { + val: *val, + device: Device::Bme280.rooted(), + resolution: 0.008, + range: 0.0..=100.0, + unit: Unit::RH, + description: "Humidity", + branch_id: self.branch_id(), + label_formatter: Box::new(FloatLabelFormatter), + }, + Reading::Pressure(val) => Info { + val: *val, + device: Device::Bme280.rooted(), + range: 87_000.0..=108_100.0, + resolution: 0.18, + unit: Unit::Pa, + description: "Air pressure", + branch_id: self.branch_id(), + label_formatter: Box::new(FloatLabelFormatter), + }, + Reading::Button(val) => return Item::Node(val as &dyn Tree), + }; + + Item::Leaf(info) + } + + fn inner_mut(&mut self) -> crate::reading::tree::ItemMut<'_> { + use crate::reading::tree::field_as_any; + + let value = + field_as_any!(self, Temperature, Humidity, Pressure, Button); + crate::reading::tree::ItemMut::Leaf(value) + } + + fn branch_id(&self) -> crate::reading::tree::Id { + ReadingDiscriminants::from(self) as crate::reading::tree::Id + } +} + +impl_is_same_as! {Reading; Temperature, Humidity, Pressure; +(Reading::Button(a), Self::Button(b)) => a.is_same_as(b)} + +#[derive( + Clone, Debug, defmt::Format, Serialize, Deserialize, MaxSize, Eq, PartialEq, +)] +pub enum Error { + Running(SensorError), + Setup(SensorError), + SetupTimedOut(Device), + Timeout(Device), +} + +impl Error { + #[must_use] + pub fn device(&self) -> Device { + match self { + Self::Running(sensor_err) | Self::Setup(sensor_err) => { + sensor_err.device() + } + Self::SetupTimedOut(device) | Self::Timeout(device) => { + device.clone() + } + } + } +} + +impl core::fmt::Display for Error { + fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { + match self { + Error::Running(e) => { + write!(f, "{} ran into error: {e}", e.device()) + } + Error::Setup(e) => { + write!(f, "{} errored during setup: {e}", e.device()) + } + Error::SetupTimedOut(d) => write!(f, "{d} timed out during setup"), + Error::Timeout(d) => write!(f, "{d} timed out while running"), + } + } +} + +#[derive( + Clone, Debug, defmt::Format, Serialize, Deserialize, Eq, PartialEq, +)] +pub enum SensorError { + BmeError(heapless::String<200>), + Gpio(heapless::String<200>), +} + +impl MaxSize for SensorError { + const POSTCARD_MAX_SIZE: usize = 200 + 1; +} + +impl SensorError { + #[must_use] + pub fn device(&self) -> Device { + match self { + SensorError::BmeError(_) => Device::Bme280, + SensorError::Gpio(_) => Device::Gpio, + } + } +} + +impl core::fmt::Display for SensorError { + fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { + match self { + SensorError::BmeError(e) | SensorError::Gpio(e) => write!(f, "{e}"), + } + } +} + +#[derive( + Clone, + Debug, + defmt::Format, + Serialize, + Deserialize, + MaxSize, + Eq, + PartialEq, + Hash, +)] +pub enum Device { + Bme280, + Gpio, +} + +impl core::fmt::Display for Device { + fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { + write!(f, "{}", self.info().name) + } +} + +macro_rules! rtree { + [$($reading:expr),+] => { + [$(crate::Reading::LargeBedroom( + crate::large_bedroom::Reading::Desk($reading), + )),+] + }; +} + +impl Device { + #[must_use] + pub fn rooted(self) -> crate::Device { + crate::Device::LargeBedroom(crate::large_bedroom::Device::Desk(self)) + } + + #[must_use] + pub const fn info(&self) -> crate::DeviceInfo { + match self { + Device::Bme280 => crate::DeviceInfo { + name: "Bme280", + affects_readings: &rtree![ + Reading::Temperature(0.0), + Reading::Humidity(0.0), + Reading::Pressure(0.0) + ], + affectors: &[], + min_sample_interval: Duration::from_secs(5), + max_sample_interval: Duration::from_secs(5), + temporal_resolution: Duration::from_secs(1), + }, + Device::Gpio => crate::DeviceInfo { + affects_readings: &rtree![ + Reading::Button(Button::OneOfFour(Press(0))), + Reading::Button(Button::TwoOfFour(Press(0))), + Reading::Button(Button::ThreeOfFour(Press(0))), + Reading::Button(Button::FourOfFour(Press(0))), + Reading::Button(Button::OneOfThree(Press(0))), + Reading::Button(Button::TwoOfThree(Press(0))), + Reading::Button(Button::ThreeOfThree(Press(0))) + ], + ..DeviceInfo::button_defaults() + }, + } + } +} diff --git a/crates/protocol/src/large_bedroom/desk_right.rs b/crates/protocol/src/large_bedroom/desk_right.rs new file mode 100644 index 00000000..8c6f53ab --- /dev/null +++ b/crates/protocol/src/large_bedroom/desk_right.rs @@ -0,0 +1,136 @@ +use postcard::experimental::max_size::MaxSize; +use serde::{Deserialize, Serialize}; + +#[cfg(feature = "alloc")] +use crate::reading::tree::{self, Tree}; +use crate::{pir, IsSameAs}; + +crate::button_enum! { + /// +----------------------------------------------------+ + /// | LL | LM | LR RLm | RL | RR | RRm | + /// +----------------------------------------------------+ + /// + /// LL LeftLeft, + /// LN LeftMiddle, + /// LR LeftRight, + /// RLm RightLeftmost, + /// RL RightLeft, + /// RR RightRight, + /// RRm RightRightmost, + Button { + LeftLeft, + LeftMiddle, + LeftRight, + RightLeftmost, + RightLeft, + RightRight, + RightRightmost, + } + crate::Device::LargeBedroom(super::Device::DeskRight(Device)); +} + +#[derive( + strum::EnumDiscriminants, + Clone, + Copy, + Debug, + defmt::Format, + Serialize, + Deserialize, + MaxSize, + PartialEq, +)] +#[strum_discriminants(derive(Hash))] +#[repr(u8)] +pub enum Reading { + Button(Button), + Pir(pir::Status), +} + +#[cfg(feature = "alloc")] +impl Tree for Reading { + fn inner(&self) -> tree::Item<'_> { + match self { + Reading::Button(button_panel) => button_panel.inner(), + Reading::Pir(status) => { + use crate::reading::Info; + + let info = Info { + val: *status as u8 as f32, + device: Device.rooted(), + description: "Pir motion detector", + range: 0.0..=2.0, + resolution: 1.0, + unit: crate::Unit::None, + branch_id: self.branch_id(), + label_formatter: Box::new(crate::pir::PirLabelFormatter), + }; + + tree::Item::Leaf(info) + } + } + } + + fn inner_mut(&mut self) -> tree::ItemMut<'_> { + use crate::reading::tree::field_as_any; + + let value = field_as_any!(self, Button, Pir); + tree::ItemMut::Leaf(value) + } + + fn branch_id(&self) -> tree::Id { + ReadingDiscriminants::from(self) as tree::Id + } +} + +impl IsSameAs for Reading { + fn is_same_as(&self, other: &Self) -> bool { + match (self, other) { + (Self::Button(a), Self::Button(b)) => a.is_same_as(b), + (Self::Pir(_), Self::Pir(_)) => true, + (_, _) => false, + } + } +} + +#[derive( + Clone, + Debug, + defmt::Format, + Serialize, + Deserialize, + MaxSize, + Eq, + PartialEq, + Hash, +)] +pub struct Device; + +impl Device { + #[must_use] + pub fn rooted(self) -> crate::Device { + crate::Device::LargeBedroom(crate::large_bedroom::Device::DeskRight( + self, + )) + } + + #[must_use] + pub const fn info(&self) -> crate::DeviceInfo { + macro_rules! rtree { + [$($reading:expr),+] => { + [$(crate::Reading::LargeBedroom( + crate::large_bedroom::Reading::DeskRight($reading), + )),+] + }; + } + + crate::DeviceInfo { + name: "Desk Buttons and Pir", + affects_readings: &rtree![ + Reading::Button(Button::LeftLeft(crate::button::Press(0))), + Reading::Pir(crate::pir::Status::Unknown) + ], + ..crate::DeviceInfo::button_defaults() + } + } +} diff --git a/crates/protocol/src/large_bedroom/radiator.rs b/crates/protocol/src/large_bedroom/radiator.rs new file mode 100644 index 00000000..8ed9a81c --- /dev/null +++ b/crates/protocol/src/large_bedroom/radiator.rs @@ -0,0 +1,152 @@ +use core::time::Duration; + +use postcard::experimental::max_size::MaxSize; +use serde::{Deserialize, Serialize}; + +#[cfg(feature = "alloc")] +use crate::reading::tree::{Item, ItemMut, Tree}; +#[cfg(feature = "alloc")] +use crate::reading::FloatLabelFormatter; +#[cfg(feature = "alloc")] +use crate::reading::Info; +use crate::shared::{self, impl_is_same_as}; +#[cfg(feature = "alloc")] +use crate::Unit; + +#[derive( + strum::EnumDiscriminants, + Clone, + Copy, + Debug, + defmt::Format, + Serialize, + Deserialize, + MaxSize, + PartialEq, +)] +#[strum_discriminants(derive(Hash))] +#[repr(u8)] +pub enum Reading { + Temperature(f32) = 0, + Heating(f32) = 1, + SetBy(shared::radiator::Source) = 2, + Setpoint(f32) = 3, +} + +impl_is_same_as!{Reading; Temperature, Heating, SetBy, Setpoint} + +#[cfg(feature = "alloc")] +impl Tree for Reading { + fn inner(&self) -> Item<'_> { + let info = match self { + Reading::Temperature(val) => Info { + val: *val, + device: crate::Device::LargeBedroom(super::Device::Radiator( + Device, + )), + resolution: 0.01, + range: -10.0..=45.0, + unit: Unit::C, + description: "Temperature", + branch_id: self.branch_id(), + label_formatter: Box::new(FloatLabelFormatter), + }, + Reading::Heating(val) => Info { + val: *val, + device: crate::Device::LargeBedroom(super::Device::Radiator( + Device, + )), + resolution: 1.0, + range: 0.0..=100.0, + unit: Unit::RelativePower, + description: "Heating valve", + branch_id: self.branch_id(), + label_formatter: Box::new(FloatLabelFormatter), + }, + Reading::SetBy(val) => Info { + val: *val as u8 as f32, + device: crate::Device::LargeBedroom(super::Device::Radiator( + Device, + )), + resolution: 1.0, + range: 0.0..=3.0, + unit: Unit::None, + description: "Manual value set", + branch_id: self.branch_id(), + label_formatter: Box::new( + shared::radiator::SetByLabelFormatter, + ), + }, + Reading::Setpoint(val) => Info { + val: *val, + device: crate::Device::LargeBedroom(super::Device::Radiator( + Device, + )), + resolution: 0.5, + range: 0.0..=30.0, + unit: Unit::C, + description: "Set point", + branch_id: self.branch_id(), + label_formatter: Box::new(FloatLabelFormatter), + }, + }; + + Item::Leaf(info) + } + fn inner_mut(&mut self) -> ItemMut<'_> { + use crate::reading::tree::field_as_any; + + let value = field_as_any!(self, Temperature, Heating, SetBy, Setpoint); + ItemMut::Leaf(value) + } + + fn branch_id(&self) -> crate::reading::tree::Id { + ReadingDiscriminants::from(self) as crate::reading::tree::Id + } +} + +#[derive( + Clone, + Debug, + defmt::Format, + Serialize, + Deserialize, + MaxSize, + Eq, + PartialEq, + Hash, +)] +pub struct Device; + +impl core::fmt::Display for Device { + fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { + write!(f, "{}", self.info().name) + } +} + +macro_rules! tree { + [$thing:ident; $($item:expr),+] => { + [$(crate::$thing::LargeBedroom( + crate::large_bedroom::$thing::Radiator($item), + )),+] + }; +} + +impl Device { + /// Note the order in which the `affects_readings` occur is the order in which + /// they will be stored, do not change it! + #[must_use] + pub const fn info(&self) -> crate::DeviceInfo { + crate::DeviceInfo { + name: "Radiator", + affects_readings: &tree![ + Reading; Reading::Temperature(0.0), Reading::Heating(0.0), + Reading::SetBy(shared::radiator::Source::Manual), + Reading::Setpoint(0.0)], + temporal_resolution: Duration::from_secs(5), // unknown + min_sample_interval: Duration::from_secs(5), // unknown + max_sample_interval: Duration::MAX, + affectors: &[], + } + } +} diff --git a/crates/protocol/src/lib.rs b/crates/protocol/src/lib.rs new file mode 100644 index 00000000..82956533 --- /dev/null +++ b/crates/protocol/src/lib.rs @@ -0,0 +1,70 @@ +#![cfg_attr(not(feature = "alloc"), no_std)] +#![allow(clippy::missing_panics_doc, clippy::missing_errors_doc)] + +use core::fmt::Display; + +pub mod button; +pub(crate) use button::button_enum; + +pub mod large_bedroom; +pub mod small_bedroom; +pub mod shared; + +pub mod affector; +mod device; +mod error; +pub mod pir; +pub mod reading; +pub mod usb; + +mod msg; +pub use affector::Affector; +pub use device::Device; +pub use device::Info as DeviceInfo; +pub use error::Error; +pub use msg::error::{make_error_string, ErrorReport, ErrorString}; +pub use msg::sensor::SensorMessage; +pub use msg::{DecodeMsgError, Msg}; +pub use reading::Reading; + +#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] +pub enum Unit { + C, + Lux, + MicrogramPerM3, + NanoMeter, + None, // for buttons & pir + NumberPerCm3, + Ohm, + Pa, + RelativePower, + Ppm, + RH, +} + +impl Display for Unit { + fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { + match self { + Unit::C => f.write_str("°C"), + Unit::Lux => f.write_str("lx"), + Unit::MicrogramPerM3 => f.write_str("µg/m³"), + Unit::NanoMeter => f.write_str("nm"), + Unit::None => f.write_str(""), + Unit::NumberPerCm3 => f.write_str("#/cm³"), + Unit::Ohm => f.write_str("Ω"), + Unit::Pa => f.write_str("Pa"), + Unit::RelativePower => f.write_str("% power"), + Unit::Ppm => f.write_str("ppm"), + Unit::RH => f.write_str("%RH"), + } + } +} + +/// Is this the same variant as the other? +/// Example: +/// Temperature(5) is the same as Temperature(6) +pub trait IsSameAs { + /// Is this the same variant as the other? + #[must_use] + fn is_same_as(&self, other: &Self) -> bool; +} diff --git a/crates/protocol/src/msg.rs b/crates/protocol/src/msg.rs new file mode 100644 index 00000000..d9a361c1 --- /dev/null +++ b/crates/protocol/src/msg.rs @@ -0,0 +1,121 @@ +use crate::affector; + +pub(crate) mod error; +pub(crate) mod sensor; + +#[derive(Debug)] +#[allow(clippy::large_enum_variant)] // Can not use Box on embedded +pub enum Msg { + Readings(sensor::SensorMessage), + ErrorReport(error::ErrorReport), + AffectorList(affector::ListMessage), +} + +impl Msg { + pub const READINGS: u8 = 1; + pub const ERROR_REPORT: u8 = 2; + pub const AFFECTOR_LIST: u8 = 3; + + #[must_use] + pub const fn max_size() -> usize { + const fn max(a: usize, b: usize) -> usize { + [a, b][(a < b) as usize] + } + + 1 + max( + max( + sensor::SensorMessage::::ENCODED_SIZE, + error::ErrorReport::ENCODED_SIZE, + ), + affector::ListMessage::<5>::ENCODED_SIZE, + ) + } + + #[must_use] + pub fn header(&self) -> u8 { + let header = match self { + Msg::Readings(_) => Self::READINGS, + Msg::ErrorReport(_) => Self::ERROR_REPORT, + Msg::AffectorList(_) => Self::AFFECTOR_LIST, + }; + assert_ne!(header, 0, "0 is reserved for cobs encoding"); + header + } + + pub fn decode(mut bytes: impl AsMut<[u8]>) -> Result { + let bytes = bytes.as_mut(); + assert!(!bytes.is_empty(), "can not decode nothing (zero bytes)"); + + let msg_type = bytes[0]; + let bytes = &mut bytes[1..]; + + if msg_type == Self::READINGS { + Ok(Self::Readings(sensor::SensorMessage::::decode(bytes)?)) + } else if msg_type == Self::ERROR_REPORT { + Ok(Self::ErrorReport(error::ErrorReport::decode(bytes)?)) + } else if msg_type == Self::AFFECTOR_LIST { + Ok(Self::AffectorList(affector::ListMessage::::decode( + bytes, + )?)) + } else { + Err(DecodeMsgError::IncorrectMsgType(msg_type)) + } + } + + #[cfg(feature = "alloc")] + #[must_use] + pub fn encode(&self) -> Vec { + let mut bytes = match self { + Msg::Readings(readings) => readings.encode(), + Msg::ErrorReport(report) => report.encode(), + Msg::AffectorList(list) => list.encode(), + }; + + bytes.insert(0, self.header()); + bytes + } + + #[must_use] + pub fn encode_slice<'a>(&self, buf: &'a mut [u8]) -> &'a mut [u8] { + buf[0] = self.header(); + match self { + Msg::Readings(msg) => { + let len = msg.encode_slice(&mut buf[1..]).len(); + &mut buf[..1 + len] + } + Msg::ErrorReport(report) => { + let len = report.encode_slice(&mut buf[1..]).len(); + &mut buf[..1 + len] + } + Msg::AffectorList(list) => { + let len = list.encode_slice(&mut buf[1..]).len(); + &mut buf[..1 + len] + } + } + } +} + +#[derive(Debug, Clone, defmt::Format)] +#[cfg_attr(feature = "thiserror", derive(thiserror::Error))] +pub enum DecodeMsgError { + #[cfg_attr( + feature = "thiserror", + error("Could not decode SensorMessage: {0}") + )] + CorruptEncoding(postcard::Error), + #[cfg_attr( + feature = "thiserror", + error("Got an unknown message type, expected zero or one got: {0}") + )] + IncorrectMsgType(u8), +} + +pub(crate) const fn cobs_overhead(uncobsed_size: usize) -> usize { + // COBS requires a minimum of 1 byte overhead, and a maximum of ⌈n/254⌉ + // bytes for n data bytes (one byte in 254, rounded up). (wiki) + + // div_ceil does not round up to one for zero, but messages of 0 bytes + // make no sense + assert!(uncobsed_size > 0, "does not support zero length messages"); + uncobsed_size.div_ceil(254) +} diff --git a/crates/protocol/src/msg/error.rs b/crates/protocol/src/msg/error.rs new file mode 100644 index 00000000..c32f0b67 --- /dev/null +++ b/crates/protocol/src/msg/error.rs @@ -0,0 +1,60 @@ +#![allow(clippy::module_name_repetitions)] + +use postcard::experimental::max_size::MaxSize; +use serde::{Deserialize, Serialize}; + +use crate::Error; + +use super::{cobs_overhead, DecodeMsgError}; + +#[allow(clippy::large_enum_variant)] // can not use Box on embedded +#[derive(Debug, Clone, Serialize, Deserialize)] +pub struct ErrorReport { + pub error: Error, + pub version: u8, +} + +impl ErrorReport { + /// +2 is for the version + /// cobs encoding still needed + const HALF_ENCODED_SIZE: usize = Error::POSTCARD_MAX_SIZE + 2; + + /// cobs and postcard encoded + pub const ENCODED_SIZE: usize = + Self::HALF_ENCODED_SIZE + cobs_overhead(Self::HALF_ENCODED_SIZE); + + #[must_use] + pub fn new(error: Error) -> Self { + Self { error, version: 0 } + } + + #[cfg(feature = "alloc")] + #[must_use] + pub fn encode(&self) -> Vec { + postcard::to_allocvec_cobs(self).expect("Encoding should not fail") + } + + /// Buffer should be at least `Self::ENCODED_SIZE` long. The returned slice contains + /// the serialized data. It can be shorter then the input buffer. + #[must_use] + pub fn encode_slice<'a>(&self, buf: &'a mut [u8]) -> &'a mut [u8] { + postcard::to_slice_cobs(self, buf).expect("Encoding should not fail") + } + + pub fn decode(mut bytes: impl AsMut<[u8]>) -> Result { + postcard::from_bytes_cobs(bytes.as_mut()) + .map_err(DecodeMsgError::CorruptEncoding) + } +} + +pub type ErrorString = heapless::String<200>; +// thiserror does not work on nostd. That will change when this lands: +// https://github.com/rust-lang/rust/issues/103765 +// at that point try switching this to fmt::Display +pub fn make_error_string(e: impl core::fmt::Debug) -> ErrorString { + use core::fmt::Write; + + let mut s = ErrorString::new(); + core::write!(s, "{e:?}").ok(); + s +} diff --git a/crates/protocol/src/msg/sensor.rs b/crates/protocol/src/msg/sensor.rs new file mode 100644 index 00000000..0ad51e3a --- /dev/null +++ b/crates/protocol/src/msg/sensor.rs @@ -0,0 +1,61 @@ +#![allow(clippy::module_name_repetitions)] + +use postcard::experimental::max_size::MaxSize; +use serde::{Deserialize, Serialize}; + +use crate::Reading; + +use super::{cobs_overhead, DecodeMsgError}; + +#[derive(Debug, Clone, Serialize, Deserialize)] +pub struct SensorMessage { + pub values: heapless::Vec, + pub version: u8, +} + +impl Default for SensorMessage { + fn default() -> Self { + Self { + values: heapless::Vec::new(), + version: 0, + } + } +} +impl SensorMessage { + /// +2 is for the version + /// +4 covers the length of the heapless list + pub const HALF_ENCODED_SIZE: usize = + (MAX_ITEMS * Reading::POSTCARD_MAX_SIZE + 2 + 4); + + /// cobs and postcard encoded + pub const ENCODED_SIZE: usize = + Self::HALF_ENCODED_SIZE + cobs_overhead(Self::HALF_ENCODED_SIZE); + + #[must_use] + pub fn space_left(&self) -> bool { + self.values.len() < self.values.capacity() + } + + #[cfg(feature = "alloc")] + #[must_use] + pub fn encode(&self) -> Vec { + postcard::to_allocvec_cobs(self).expect("Encoding should not fail") + } + + /// Buffer should be at least `Self::ENCODED_SIZE` long. The returned slice contains + /// the serialized data. It can be shorter then the input buffer. + #[must_use] + pub fn encode_slice<'a>(&self, buf: &'a mut [u8]) -> &'a mut [u8] { + postcard::to_slice_cobs(self, buf).expect("Encoding should not fail") + } + + pub fn decode(mut bytes: impl AsMut<[u8]>) -> Result { + postcard::from_bytes_cobs(bytes.as_mut()) + .map_err(DecodeMsgError::CorruptEncoding) + } + + #[must_use] + pub fn version(&self) -> u8 { + self.version + } +} diff --git a/crates/protocol/src/pir.rs b/crates/protocol/src/pir.rs new file mode 100644 index 00000000..a0bf6476 --- /dev/null +++ b/crates/protocol/src/pir.rs @@ -0,0 +1,42 @@ +#[cfg(feature = "alloc")] +use crate::reading::LabelFormatter; +use postcard::experimental::max_size::MaxSize; + +#[derive( + strum::EnumDiscriminants, + Clone, + Copy, + Debug, + defmt::Format, + serde::Serialize, + serde::Deserialize, + MaxSize, + PartialEq, +)] +#[repr(u8)] +pub enum Status { + OngoingActivity = 2, + NoActivity = 0, + /// because the node went offline + Unknown = 1, +} + +#[cfg(feature = "alloc")] +#[derive(Debug)] +pub struct PirLabelFormatter; + +#[cfg(feature = "alloc")] +impl LabelFormatter for PirLabelFormatter { + fn format(&self, value: f64, _: &crate::reading::Info) -> String { + match value { + 0.0 => "activity ended", + 1.0 => "node went down mid activity", + 2.0 => "activity started", + _ => "ButtonLabelFormatter error", + } + .to_string() + } + fn box_clone(&self) -> Box { + Box::new(Self) + } +} diff --git a/crates/protocol/src/reading.rs b/crates/protocol/src/reading.rs new file mode 100644 index 00000000..0198263e --- /dev/null +++ b/crates/protocol/src/reading.rs @@ -0,0 +1,176 @@ +use postcard::experimental::max_size::MaxSize; +use serde::{Deserialize, Serialize}; + +#[cfg(feature = "alloc")] +use crate::Device; +#[cfg(feature = "alloc")] +use crate::Unit; +use crate::{large_bedroom, small_bedroom}; + +#[cfg(feature = "alloc")] +pub mod tree; + +#[derive( + strum::EnumDiscriminants, + strum::VariantNames, + Clone, + Debug, + defmt::Format, + Serialize, + Deserialize, + MaxSize, + PartialEq, +)] +#[strum_discriminants(derive(Hash))] +#[repr(u8)] +pub enum Reading { + LargeBedroom(large_bedroom::Reading) = 0, + SmallBedroom(small_bedroom::Reading) = 1, + // Test, +} + +#[cfg(feature = "alloc")] +/// Unique Id for a specific reading (not the value) +#[derive(Debug, Hash, PartialEq, Eq)] +pub struct ReadingId([tree::Id; 8]); + +#[cfg(feature = "alloc")] +impl Reading { + #[must_use] + pub fn from_same_device(&self) -> &'static [Reading] { + use tree::Tree; + self.info().from_same_device() + } + #[must_use] + pub fn range(&self) -> core::ops::RangeInclusive { + use tree::Tree; + self.info().range + } + #[must_use] + /// the step between the two closest data-points that are not the same + pub fn resolution(&self) -> f32 { + use tree::Tree; + self.info().resolution + } + #[must_use] + pub fn device(&self) -> Device { + use tree::Tree; + self.info().device + } + // This means the enum can not go deeper then 8 + // but that seems reasonable + pub fn id(&self) -> ReadingId { + use crate::reading::tree::Tree; + + let mut current = self as &dyn Tree; + let mut res = [0; 8]; + for i in 0.. { + *res.get_mut(i) + .expect("Reading tree should not go deeper then 8") = + current.branch_id(); + match current.inner() { + tree::Item::Node(node) => current = node, + tree::Item::Leaf(info) => { + *res.get_mut(i + 1) + .expect("Reading tree should not go deeper then 8") = + info.branch_id; + break; + } + } + } + + ReadingId(res) + } +} +impl Reading { + #[must_use] + pub fn version() -> u8 { + 0u8 + } +} + +// todo make axis fixed for some info's? +pub enum LabelPositions { + Flexible, + Fixed(&'static [f64]), +} + +#[cfg(feature = "alloc")] +pub trait LabelFormatter: core::fmt::Debug { + fn format(&self, value: f64, info: &Info) -> String; + fn box_clone(&self) -> Box; + fn positions(&self) -> LabelPositions { + LabelPositions::Flexible + } +} + +#[cfg(feature = "alloc")] +impl Clone for Box { + fn clone(&self) -> Self { + self.box_clone() + } +} + +#[cfg(feature = "alloc")] +#[derive(Debug)] +pub struct FloatLabelFormatter; + +#[cfg(feature = "alloc")] +impl LabelFormatter for FloatLabelFormatter { + fn format(&self, value: f64, info: &Info) -> String { + format!("{0:.1$}", value, info.precision()) + } + fn box_clone(&self) -> Box { + Box::new(Self) + } +} + +#[cfg(feature = "alloc")] +#[derive(Debug, Clone)] +pub struct Info { + pub val: f32, + pub device: Device, + /// smallest step size the data can make + pub resolution: f32, + pub range: core::ops::RangeInclusive, + pub unit: Unit, + pub description: &'static str, + pub branch_id: u8, + pub label_formatter: Box, +} + +#[cfg(feature = "alloc")] +impl Info { + #[must_use] + pub fn from_same_device(&self) -> &'static [Reading] { + self.device.info().affects_readings + } + + /// useful for printing/formatting floats + /// # Example + /// ```rust + /// use protocol::Reading; + /// use protocol::large_bedroom; + /// use protocol::large_bedroom::desk; + /// use protocol::reading::tree::Tree; + /// + /// let reading = + /// Reading::LargeBedroom(large_bedroom::Reading::Desk(desk::Reading::Temperature(22.428124))); + /// + /// let info = reading.info(); + /// let printed = format!("{0:.1$}", info.val, info.precision()); + /// assert_eq!(printed, "22.43"); + /// ``` + #[must_use] + #[allow(clippy::cast_sign_loss, clippy::cast_possible_truncation)] + pub fn precision(&self) -> usize { + if self.resolution > 1.0 { + 0 + } else { + self.resolution.log10().abs() as usize + } + } +} + +#[cfg(feature = "alloc")] +tree::all_nodes! {Reading; ReadingDiscriminants; LargeBedroom, SmallBedroom} diff --git a/crates/protocol/src/reading/tree.rs b/crates/protocol/src/reading/tree.rs new file mode 100644 index 00000000..038365b8 --- /dev/null +++ b/crates/protocol/src/reading/tree.rs @@ -0,0 +1,112 @@ +use core::any::Any; + +use super::Info; + +pub type Id = u8; +#[derive(Debug)] +pub enum Item<'a> { + Leaf(Info), + Node(&'a dyn Tree), +} + +pub enum ItemMut<'a> { + Leaf(&'a mut dyn Any), + Node(&'a mut dyn Tree), +} + +pub trait Tree: core::fmt::Debug { + #[must_use] + fn inner(&self) -> Item<'_>; + fn inner_mut(&mut self) -> ItemMut<'_>; + + fn info(&self) -> Info + where + Self: Sized, + { + let mut current = self as &dyn Tree; + loop { + match current.inner() { + Item::Node(node) => current = node, + Item::Leaf(info) => return info, + } + } + } + fn value_mut(&mut self) -> &mut (dyn Any + 'static) + where + Self: Sized, + { + let mut current = self as &mut dyn Tree; + loop { + match current.inner_mut() { + ItemMut::Node(node) => current = node, + ItemMut::Leaf(value) => return value, + } + } + } + fn name(&self) -> String { + let dbg_repr = format!("{self:?}"); + dbg_repr + .split_once('(') + .map_or("_", |(name, _)| name) + .to_string() + } + #[must_use] + fn branch_id(&self) -> Id; +} + +macro_rules! field_as_any { + ($self:ident, $($field_name:ident),+) => { + match $self { + $( + Reading::$field_name(inner) => inner as &mut dyn core::any::Any, + )+ + } + }; +} +pub(crate) use field_as_any; + +macro_rules! impl_zero { + ($name:ident; $($var:ident),*) => { + impl $crate::IsSameAs for $name { + fn is_same_as(&self, other: &Self) -> bool { + #[allow(unused_imports)] + use $crate::IsSameAs; + match (self, other) { + $(($name::$var(a), $name::$var(b)) => a.is_same_as(b),)* + (_, _) => false, + } + } + } + + }; +} +pub(crate) use impl_zero; + +macro_rules! all_nodes { + ($name:ident; $variant:ident; $($var:ident),*) => { + impl crate::reading::tree::Tree for $name { + fn inner(&self) -> crate::reading::tree::Item<'_> { + match self { + $( + $name::$var(inner) => crate::reading::tree::Item::Node(inner as &dyn crate::reading::tree::Tree) + ),* + } + } + fn inner_mut(&mut self) -> crate::reading::tree::ItemMut<'_> { + match self { + $( + $name::$var(inner) => crate::reading::tree::ItemMut::Node(inner as &mut dyn crate::reading::tree::Tree) + ),* + } + + } + + fn branch_id(&self) -> crate::reading::tree::Id { + $variant::from(self) as crate::reading::tree::Id + } + + } + crate::reading::tree::impl_zero!{$name; $($var),*} + }; +} +pub(crate) use all_nodes; diff --git a/crates/protocol/src/shared.rs b/crates/protocol/src/shared.rs new file mode 100644 index 00000000..8ebda5af --- /dev/null +++ b/crates/protocol/src/shared.rs @@ -0,0 +1,23 @@ +pub mod radiator; + +// doc test is no compile as macro is pub(crate) +/// implements the `IsSameAs` trait for enum `thing` with variants `variant` +/// example usage: +/// ```no_compile +/// impl_is_same_as!(Reading; Temperature, Heating, SetBy, Setpoint); +/// ``` +macro_rules! impl_is_same_as { + ($thing:ident; $($variant:ident),+$(; $extra:pat => $todo:expr);*) => { + impl crate::IsSameAs for $thing { + fn is_same_as(&self, other: &Self) -> bool { + match (self, other) { + $((Self::$variant(_), Self::$variant(_)))|+ => true, + $($extra => $todo,)* + _ => false, + } + } + } + }; +} + +pub(crate) use impl_is_same_as; diff --git a/crates/protocol/src/shared/radiator.rs b/crates/protocol/src/shared/radiator.rs new file mode 100644 index 00000000..38dc2bb1 --- /dev/null +++ b/crates/protocol/src/shared/radiator.rs @@ -0,0 +1,48 @@ +use postcard::experimental::max_size::MaxSize; +use serde::{Deserialize, Serialize}; + +#[cfg(feature = "alloc")] +use crate::reading; +#[cfg(feature = "alloc")] +use crate::reading::LabelFormatter; + +#[derive( + strum::EnumDiscriminants, + Clone, + Copy, + Debug, + defmt::Format, + Serialize, + Deserialize, + MaxSize, + PartialEq, +)] +#[strum_discriminants(derive(Hash))] +#[repr(u8)] +pub enum Source { + Manual = 0, + Schedule = 1, + External = 2, +} + +#[cfg(feature = "alloc")] +#[derive(Debug)] +pub struct SetByLabelFormatter; + +#[cfg(feature = "alloc")] +impl LabelFormatter for SetByLabelFormatter { + fn format(&self, value: f64, _info: &reading::Info) -> String { + match value { + 0.0 => "Manual", + 1.0 => "Schedule", + 2.0 => "External", + _ => "SetpointLabelFormatterError", + } + .to_string() + } + + fn box_clone(&self) -> Box { + Box::new(Self) + } +} + diff --git a/crates/protocol/src/small_bedroom.rs b/crates/protocol/src/small_bedroom.rs new file mode 100644 index 00000000..13b4f046 --- /dev/null +++ b/crates/protocol/src/small_bedroom.rs @@ -0,0 +1,174 @@ +use core::time::Duration; + +use postcard::experimental::max_size::MaxSize; +use serde::{Deserialize, Serialize}; + +#[cfg(feature = "alloc")] +use crate::affector; +use crate::button::Press; + +pub mod bed; +pub mod desk; +pub mod portable_button_panel; +pub mod radiator; + +crate::button_enum! { + /// +-----------------------------------------+ + /// | TopLeft | TopMiddle | TopRight | + /// +-----------------------------------------+ + /// | BottomLeft | BottomMiddle | BottomRight | + /// +-----------------------------------------+ + ButtonPanel { + TopLeft, + TopMiddle, + TopRight, + BottomLeft, + BottomMiddle, + BottomRight, + } + crate::Device::SmallBedroom(crate::small_bedroom::Device::Gpio); +} + +#[derive( + strum::EnumDiscriminants, + Clone, + Copy, + Debug, + defmt::Format, + Serialize, + Deserialize, + MaxSize, + PartialEq, +)] +#[repr(u8)] +pub enum Reading { + PortableButtonPanel(portable_button_panel::Reading) = 4, + ButtonPanel(ButtonPanel) = 0, + Desk(desk::Reading) = 1, + Bed(bed::Reading) = 2, + Radiator(radiator::Reading) = 3, +} + +#[cfg(feature = "alloc")] +crate::reading::tree::all_nodes! {Reading; ReadingDiscriminants; ButtonPanel, Desk, Bed, Radiator, PortableButtonPanel} + +#[derive( + strum::EnumDiscriminants, + Clone, + Debug, + defmt::Format, + Serialize, + Deserialize, + MaxSize, + Eq, + PartialEq, +)] +pub enum Error { + Desk(desk::Error), + Bed(bed::Error), +} + +impl Error { + #[must_use] + pub fn device(&self) -> Device { + match self { + Error::Desk(error) => Device::Desk(error.device()), + Error::Bed(error) => Device::Bed(error.device()), + } + } +} + +impl core::fmt::Display for Error { + fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { + match self { + Error::Desk(error) => write!(f, "{error}"), + Error::Bed(error) => write!(f, "{error}"), + } + } +} + +#[derive( + Clone, + Debug, + defmt::Format, + Serialize, + Deserialize, + MaxSize, + Hash, + PartialEq, + Eq, +)] +pub enum Device { + Gpio, + Desk(desk::Device), + Bed(bed::Device), + Radiator(radiator::Device), + PortableButtonPanel(portable_button_panel::Device), +} + +macro_rules! tree { + [$($button:expr),+] => { + [$(crate::Reading::SmallBedroom( + crate::small_bedroom::Reading::ButtonPanel($button), + )),+] + }; +} + +impl Device { + /// Note the order in which the `affects_readings` occur is the order in which + /// they will be stored, do not change it! + #[must_use] + pub const fn info(&self) -> crate::DeviceInfo { + match self { + Device::Gpio => crate::DeviceInfo { + name: "Gpio", + affects_readings: &tree![ + ButtonPanel::TopLeft(Press(0)), + ButtonPanel::TopMiddle(Press(0)), + ButtonPanel::TopRight(Press(0)), + ButtonPanel::BottomLeft(Press(0)), + ButtonPanel::BottomMiddle(Press(0)), + ButtonPanel::BottomRight(Press(0)) + ], + affectors: &[], + temporal_resolution: Duration::from_millis(1), + min_sample_interval: Duration::from_millis(2), + max_sample_interval: Duration::MAX, + }, + Device::Desk(device) => device.info(), + Device::Bed(device) => device.info(), + Device::Radiator(device) => device.info(), + Device::PortableButtonPanel(device) => device.info(), + } + } +} + +#[derive( + strum::EnumDiscriminants, + Clone, + Copy, + Debug, + defmt::Format, + Serialize, + Deserialize, + MaxSize, + PartialEq, + Eq, + Hash, +)] +#[strum_discriminants(derive(Hash))] +pub enum Affector { + Bed(bed::Affector), +} + +impl Affector { + #[cfg(feature = "alloc")] + pub(crate) fn controls(&mut self) -> Vec> { + match self { + Affector::Bed(a) => a.controls(), + } + } +} + +#[cfg(feature = "alloc")] +affector::tree::all_nodes! {Affector; AffectorDiscriminants; Bed} diff --git a/crates/protocol/src/small_bedroom/bed.rs b/crates/protocol/src/small_bedroom/bed.rs new file mode 100644 index 00000000..53b6e107 --- /dev/null +++ b/crates/protocol/src/small_bedroom/bed.rs @@ -0,0 +1,580 @@ +use core::time::Duration; + +#[cfg(feature = "alloc")] +use crate::affector::{Control, ControlValue}; +use crate::button::Press; +#[cfg(feature = "alloc")] +use crate::reading::tree::{Id, Item, ItemMut, Tree}; +#[cfg(feature = "alloc")] +use crate::reading::FloatLabelFormatter; +#[cfg(feature = "alloc")] +use crate::reading::Info; +use crate::shared::impl_is_same_as; +#[cfg(feature = "alloc")] +use crate::{affector, Unit}; + +use postcard::experimental::max_size::MaxSize; +use serde::{Deserialize, Serialize}; + +crate::button_enum! { + /// |-----------------------------------------| + /// | bed towards wall ^ | + /// | towards headboard -> | + /// +-----------------------------------------+ + /// | Left | LeftMiddle | RightMiddle | Right | + /// +-----------------------------------------+ + Button { + Left, + LeftMiddle, + RightMiddle, + Right, + } + crate::Device::SmallBedroom(crate::small_bedroom::Device::Bed(crate::small_bedroom::bed::Device::Gpio)); +} + +#[derive( + strum::EnumDiscriminants, + Clone, + Copy, + Debug, + defmt::Format, + Serialize, + Deserialize, + MaxSize, + PartialEq, +)] +#[strum_discriminants(derive(Hash))] +#[repr(u8)] +pub enum Reading { + Button(Button) = 0, + Brightness(f32) = 1, + Temperature(f32) = 2, + Humidity(f32) = 3, + GassResistance(f32) = 4, // In Ohm + Pressure(f32) = 5, + /// Parts per million + Co2(u16) = 6, + /// Weight on the bed + Weight(u32) = 7, + + /// Mass Concentration PM1.0 \[μg/m³\] + MassPm1_0(f32) = 9, + /// Mass Concentration PM2.5 \[μg/m³\] + MassPm2_5(f32) = 10, + /// Mass Concentration PM4.0 \[μg/m³\] + MassPm4_0(f32) = 11, + /// Mass Concentration PM10 \[μg/m³\] + MassPm10(f32) = 12, + /// Number Concentration PM0.5 \[#/cm³\] + NumberPm0_5(f32) = 13, + /// Number Concentration PM1.0 \[#/cm³\] + NumberPm1_0(f32) = 14, + /// Number Concentration PM2.5 \[#/cm³\] + NumberPm2_5(f32) = 15, + /// Number Concentration PM4.0 \[#/cm³\] + NumberPm4_0(f32) = 16, + /// Number Concentration PM10 \[#/cm³\] + NumberPm10(f32) = 17, + /// Typical Particle Size8 \[μm\] + TypicalParticleSize(f32) = 18, +} + +#[cfg(feature = "alloc")] +impl Tree for Reading { + #[allow(clippy::too_many_lines)] + #[allow(clippy::cast_precision_loss)] + fn inner(&self) -> Item<'_> { + let (val, device, range, resolution, unit, description) = match self { + Reading::Brightness(val) => ( + *val, + Device::Max44.rooted(), + 0.0..=188_000.0, + 0.045, + Unit::Lux, + "Brightness", + ), + Reading::Temperature(val) => ( + *val, + Device::Sht31.rooted(), + -10.0..=45.0, + 0.01, + Unit::C, + "Temperature", + ), + Reading::Humidity(val) => ( + *val, + Device::Sht31.rooted(), + 0.0..=100.0, + 0.01, + Unit::RH, + "Relative humidity", + ), + // air quality: comp_gas = log(R_gas[ohm]) + 0.04 log(Ohm)/%rh * hum[%rh] + Reading::GassResistance(val) => ( + *val, + Device::Bme680.rooted(), + 0.0..=1_000_000.0, + 1.0, + Unit::Ohm, + "Gass resistance", + ), + // record air pressure + // - 1.081hPa (dead sea 430 below normal sea level) + // - 870hPa (middle of a tornado) + Reading::Pressure(val) => ( + *val, + Device::Bme680.rooted(), + 87_000.0..=108_100.0, + 0.18, + Unit::Pa, + "Air pressure", + ), + Reading::Co2(val) => ( + f32::from(*val), + Device::Mhz14.rooted(), + 400.0..=2_000.0, + 1.0, + Unit::Ppm, + "Co2 concentration", + ), + Reading::Weight(val) => ( + *val as f32, + Device::Nau7802.rooted(), + 0.0..=24.0_f32.exp2(), + 1.0, + Unit::Ohm, + "weight sensor resistance", + ), + Reading::Button(button) => return Item::Node(button), + Reading::MassPm1_0(val) => ( + *val, + Device::Sps30.rooted(), + 0.0..=1000.0, + 0.1, + Unit::MicrogramPerM3, + "Mass concentration particles between 0.3 to 1.0 μm", + ), + Reading::MassPm2_5(val) => ( + *val, + Device::Sps30.rooted(), + 0.0..=1000.0, + 0.1, + Unit::MicrogramPerM3, + "Mass concentration particles between 0.3 to 2.5 μm", + ), + Reading::MassPm4_0(val) => ( + *val, + Device::Sps30.rooted(), + 0.0..=1000.0, + 0.1, + Unit::MicrogramPerM3, + "Mass concentration particles between 0.3 to 4.0 μm", + ), + Reading::MassPm10(val) => ( + *val, + Device::Sps30.rooted(), + 0.0..=1000.0, + 0.1, + Unit::MicrogramPerM3, + "Mass concentration particles between 0.3 to 10.0 μm", + ), + Reading::NumberPm0_5(val) => ( + *val, + Device::Sps30.rooted(), + 0.0..=3000.0, + 0.1, + Unit::NumberPerCm3, + "Concentration of particles between 0.3 to 0.5 μm", + ), + Reading::NumberPm1_0(val) => ( + *val, + Device::Sps30.rooted(), + 0.0..=3000.0, + 0.1, + Unit::NumberPerCm3, + "Concentration of particles between 0.3 to 1.0 μm", + ), + Reading::NumberPm2_5(val) => ( + *val, + Device::Sps30.rooted(), + 0.0..=3000.0, + 0.1, + Unit::NumberPerCm3, + "Concentration of particles between 0.3 to 2.5 μm", + ), + Reading::NumberPm4_0(val) => ( + *val, + Device::Sps30.rooted(), + 0.0..=3000.0, + 0.1, + Unit::NumberPerCm3, + "Concentration of particles between 0.3 to 4.0 μm", + ), + Reading::NumberPm10(val) => ( + *val, + Device::Sps30.rooted(), + 0.0..=3000.0, + 0.1, + Unit::NumberPerCm3, + "Concentration of particles between 0.3 to 10.5 μm", + ), + Reading::TypicalParticleSize(val) => ( + *val, + Device::Sps30.rooted(), + 0.0..=10_000.0, + 0.5, + Unit::NanoMeter, + "Typical particle size", + ), + }; + + let info = Info { + val, + device, + resolution, + range, + unit, + description, + branch_id: self.branch_id(), + label_formatter: Box::new(FloatLabelFormatter), + }; + + Item::Leaf(info) + } + + fn inner_mut(&mut self) -> ItemMut<'_> { + use crate::reading::tree::field_as_any; + + let value = field_as_any!( + self, + Button, + Brightness, + Temperature, + Humidity, + GassResistance, + Pressure, + Co2, + Weight, + MassPm1_0, + MassPm2_5, + MassPm4_0, + MassPm10, + NumberPm0_5, + NumberPm1_0, + NumberPm2_5, + NumberPm4_0, + NumberPm10, + TypicalParticleSize + ); + + ItemMut::Leaf(value) + } + + fn branch_id(&self) -> Id { + ReadingDiscriminants::from(self) as Id + } +} + +impl_is_same_as! {Reading; + Brightness, Temperature, Humidity, GassResistance, Pressure, Co2, Weight, + MassPm1_0, MassPm2_5, MassPm4_0, MassPm10, NumberPm0_5, NumberPm1_0, + NumberPm2_5, NumberPm4_0, NumberPm10, TypicalParticleSize; + (Self::Button(a), Self::Button(b)) => a.is_same_as(b) +} + +#[derive( + Clone, Debug, defmt::Format, Serialize, Deserialize, MaxSize, Eq, PartialEq, +)] +pub enum Error { + Running(SensorError), + Setup(SensorError), + SetupTimedOut(Device), + Timeout(Device), +} + +impl Error { + #[must_use] + pub(crate) fn device(&self) -> Device { + match self { + Self::Running(sensor_err) | Self::Setup(sensor_err) => { + sensor_err.device() + } + Self::SetupTimedOut(device) | Self::Timeout(device) => { + device.clone() + } + } + } +} + +impl core::fmt::Display for Error { + fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { + match self { + Error::Running(e) => write!(f, "{e}"), + Error::Setup(e) => write!(f, "setup: {e}"), + Error::SetupTimedOut(_) => write!(f, "setup timed out"), + Error::Timeout(_) => write!(f, "timed out running"), + } + } +} + +#[derive( + Clone, Debug, defmt::Format, Serialize, Deserialize, Eq, PartialEq, +)] +pub enum SensorError { + Sht31(heapless::String<200>), + Bme680(heapless::String<200>), + Max44(heapless::String<200>), + Mhz14(heapless::String<200>), + Sps30(heapless::String<200>), + Button(heapless::String<200>), + Nau7802(heapless::String<200>), +} + +impl core::fmt::Display for SensorError { + fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { + match self { + SensorError::Sht31(e) + | SensorError::Bme680(e) + | SensorError::Max44(e) + | SensorError::Mhz14(e) + | SensorError::Sps30(e) + | SensorError::Button(e) + | SensorError::Nau7802(e) => write!(f, "{e}"), + } + } +} + +impl MaxSize for SensorError { + const POSTCARD_MAX_SIZE: usize = 201; +} + +impl SensorError { + #[must_use] + pub fn device(&self) -> Device { + match self { + SensorError::Sht31(_) => Device::Sht31, + SensorError::Bme680(_) => Device::Bme680, + SensorError::Max44(_) => Device::Max44, + SensorError::Mhz14(_) => Device::Mhz14, + SensorError::Sps30(_) => Device::Sps30, + SensorError::Button(_) => Device::Gpio, + SensorError::Nau7802(_) => Device::Nau7802, + } + } +} + +#[derive( + Clone, + Debug, + defmt::Format, + Serialize, + Deserialize, + MaxSize, + Eq, + PartialEq, + Hash, +)] +pub enum Device { + Sht31, + Bme680, + Max44, + Mhz14, + Sps30, + Nau7802, + Gpio, +} + +impl core::fmt::Display for Device { + fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { + write!(f, "{}", self.info().name) + } +} + +macro_rules! tree { + [$thing:ident; $($item:expr),+] => { + [$(crate::$thing::SmallBedroom( + crate::small_bedroom::$thing::Bed($item), + )),+] + }; +} + +impl Device { + /// Note the order in which the `affects_readings` occur is the order in which + /// they will be stored, do not change it! + #[must_use] + pub const fn info(&self) -> crate::DeviceInfo { + let min_sample_interval = Duration::from_secs(5); + let max_sample_interval = Duration::from_secs(5); + let temporal_resolution = Duration::from_secs(1); + match self { + Device::Sht31 => crate::DeviceInfo { + name: "Sht31", + affects_readings: &tree![Reading; Reading::Temperature(0.0), Reading::Humidity(0.0)], + temporal_resolution, + min_sample_interval, + max_sample_interval, + affectors: &[], + }, + Device::Bme680 => crate::DeviceInfo { + name: "Bme680", + affects_readings: &tree![Reading; + Reading::GassResistance(0.0), + Reading::Pressure(0.0) + ], + temporal_resolution, + min_sample_interval, + max_sample_interval, + affectors: &[], + }, + Device::Max44 => crate::DeviceInfo { + name: "Max44", + affects_readings: &tree![Reading; Reading::Brightness(0.0)], + temporal_resolution: Duration::from_millis(50), + min_sample_interval: Duration::from_millis(50), + max_sample_interval, + affectors: &[], + }, + Device::Mhz14 => crate::DeviceInfo { + name: "Mhz14", + affects_readings: &tree![Reading; Reading::Co2(0)], + temporal_resolution, + min_sample_interval, + max_sample_interval, + affectors: &tree!(Affector; Affector::MhzZeroPointCalib), + }, + Device::Sps30 => crate::DeviceInfo { + name: "Sps30", + affects_readings: &tree![Reading; + Reading::MassPm1_0(0.0), + Reading::MassPm2_5(0.0), + Reading::MassPm4_0(0.0), + Reading::MassPm10(0.0), + Reading::NumberPm0_5(0.0), + Reading::NumberPm1_0(0.0), + Reading::NumberPm2_5(0.0), + Reading::NumberPm4_0(0.0), + Reading::NumberPm10(0.0), + Reading::TypicalParticleSize(0.0) + ], + temporal_resolution, + min_sample_interval, + max_sample_interval, + affectors: &tree!(Affector; Affector::Sps30FanClean), + }, + Device::Nau7802 => crate::DeviceInfo { + name: "Nau7802Right", + affects_readings: &tree![Reading; Reading::Weight(0)], + temporal_resolution: Duration::from_millis(100), + min_sample_interval: Duration::from_millis(100), + max_sample_interval, + affectors: &tree!(Affector; Affector::Nau7802Calib), + }, + Device::Gpio => crate::DeviceInfo { + name: "Gpio", + affects_readings: &tree![Reading; + Reading::Button(Button::Left(Press(0))), + Reading::Button(Button::LeftMiddle(Press(0))), + Reading::Button(Button::RightMiddle(Press(0))), + Reading::Button(Button::Right(Press(0))) + ], + ..crate::DeviceInfo::button_defaults() + }, + } + } + + #[cfg(feature = "alloc")] + #[must_use] + const fn rooted(self) -> crate::Device { + crate::Device::SmallBedroom(crate::small_bedroom::Device::Bed(self)) + } +} + +#[derive( + strum::EnumDiscriminants, + Clone, + Copy, + Debug, + defmt::Format, + Serialize, + Deserialize, + MaxSize, + PartialEq, + Eq, + Hash, +)] +#[strum_discriminants(derive(Hash))] +pub enum Affector { + Sps30FanClean, + MhzZeroPointCalib, + Nau7802Calib, + ResetNode, +} + +impl crate::IsSameAs for Affector { + fn is_same_as(&self, other: &Self) -> bool { + self.eq(other) + } +} +impl Affector { + #[cfg(feature = "alloc")] + pub fn controls(&mut self) -> Vec> { + match self { + Affector::Sps30FanClean => vec![Control { + name: "start fan cleaning", + value: ControlValue::Trigger, + }], + Affector::MhzZeroPointCalib => vec![Control { + name: "calibrate current reading as 400 ppm", + value: ControlValue::Trigger, + }], + Affector::Nau7802Calib => vec![Control { + name: "things with ac power noise or something", + value: ControlValue::Trigger, + }], + Affector::ResetNode => vec![Control { + name: "reset the node", + value: ControlValue::Trigger, + }], + } + } +} + +#[cfg(feature = "alloc")] +impl affector::tree::Tree for Affector { + fn inner(&self) -> affector::tree::Item<'_> { + let description = match self { + Affector::Sps30FanClean => "Accelerate the fan to maximum speed for 10 seconds in order to blow out the dust accumulated in the fan", + Affector::MhzZeroPointCalib => "Set the current co2 value as 400ppm", + Affector::Nau7802Calib => "Detect and correct power supply and temperature variations to ADC", + Affector::ResetNode => "Reset the node, this might fix errors such as I2c getting stuck after Arbitration Error", + }; + + affector::tree::Item::Leaf(affector::Info { description }) + } + + fn branch_id(&self) -> affector::tree::Id { + AffectorDiscriminants::from(self) as Id + } +} + +#[cfg(test)] +mod test { + use super::*; + + #[test] + #[cfg(feature = "alloc")] + fn test_is_same_as() { + use crate::IsSameAs; + + assert!(Reading::Co2(5).is_same_as(&Reading::Co2(0))); + + let a = crate::Reading::SmallBedroom( + crate::small_bedroom::Reading::Bed(Reading::Co2(5)), + ); + let b = crate::Reading::SmallBedroom( + crate::small_bedroom::Reading::Bed(Reading::Co2(0)), + ); + + assert!(a.is_same_as(&b)); + } +} diff --git a/crates/protocol/src/small_bedroom/desk.rs b/crates/protocol/src/small_bedroom/desk.rs new file mode 100644 index 00000000..7d834d7d --- /dev/null +++ b/crates/protocol/src/small_bedroom/desk.rs @@ -0,0 +1,207 @@ +use core::time::Duration; + +use postcard::experimental::max_size::MaxSize; +use serde::{Deserialize, Serialize}; + +#[cfg(feature = "alloc")] +use crate::reading::tree::{Item, ItemMut, Tree}; +#[cfg(feature = "alloc")] +use crate::reading::FloatLabelFormatter; +#[cfg(feature = "alloc")] +use crate::reading::Info; +use crate::shared::impl_is_same_as; +#[cfg(feature = "alloc")] +use crate::Unit; + +#[derive( + strum::EnumDiscriminants, + Clone, + Copy, + Debug, + defmt::Format, + Serialize, + Deserialize, + MaxSize, + PartialEq, +)] +#[strum_discriminants(derive(Hash))] +#[repr(u8)] +pub enum Reading { + Temperature(f32) = 0, + Humidity(f32) = 1, + Pressure(f32) = 2, +} + +#[cfg(feature = "alloc")] +impl Tree for Reading { + fn inner(&self) -> Item<'_> { + let info = match self { + Reading::Temperature(val) => Info { + val: *val, + device: Device::Bme280.rooted(), + resolution: 0.01, + range: -10.0..=45.0, + unit: Unit::C, + description: "Temperature", + branch_id: self.branch_id(), + label_formatter: Box::new(FloatLabelFormatter), + }, + Reading::Humidity(val) => Info { + val: *val, + device: Device::Bme280.rooted(), + resolution: 0.008, + range: 0.0..=100.0, + unit: Unit::RH, + description: "Humidity", + branch_id: self.branch_id(), + label_formatter: Box::new(FloatLabelFormatter), + }, + Reading::Pressure(val) => Info { + val: *val, + device: Device::Bme280.rooted(), + range: 87_000.0..=108_100.0, + resolution: 0.18, + unit: Unit::Pa, + description: "Air pressure", + branch_id: self.branch_id(), + label_formatter: Box::new(FloatLabelFormatter), + }, + }; + + Item::Leaf(info) + } + + fn inner_mut(&mut self) -> ItemMut<'_> { + use crate::reading::tree::field_as_any; + + let value = field_as_any!(self, Temperature, Humidity, Pressure); + ItemMut::Leaf(value) + } + + fn branch_id(&self) -> crate::reading::tree::Id { + ReadingDiscriminants::from(self) as crate::reading::tree::Id + } +} + +impl_is_same_as!(Reading; Temperature, Humidity, Pressure); + +#[derive( + Clone, Debug, defmt::Format, Serialize, Deserialize, MaxSize, Eq, PartialEq, +)] +pub enum Error { + Running(SensorError), + Setup(SensorError), + SetupTimedOut(Device), + Timeout(Device), +} + +impl Error { + #[must_use] + pub fn device(&self) -> Device { + match self { + Self::Running(sensor_err) | Self::Setup(sensor_err) => { + sensor_err.device() + } + Self::SetupTimedOut(device) | Self::Timeout(device) => { + device.clone() + } + } + } +} + +impl core::fmt::Display for Error { + fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { + match self { + Error::Running(e) => { + write!(f, "{} ran into error: {e}", e.device()) + } + Error::Setup(e) => { + write!(f, "{} errored during setup: {e}", e.device()) + } + Error::SetupTimedOut(d) => write!(f, "{d} timed out during setup"), + Error::Timeout(d) => write!(f, "{d} timed out while running"), + } + } +} + +#[derive( + Clone, Debug, defmt::Format, Serialize, Deserialize, Eq, PartialEq, +)] +pub enum SensorError { + BmeError(heapless::String<200>), +} + +impl MaxSize for SensorError { + const POSTCARD_MAX_SIZE: usize = 200 + 1; +} + +impl SensorError { + #[must_use] + pub fn device(&self) -> Device { + match self { + SensorError::BmeError(_) => Device::Bme280, + } + } +} + +impl core::fmt::Display for SensorError { + fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { + match self { + SensorError::BmeError(e) => write!(f, "{e}"), + } + } +} + +#[derive( + Clone, + Debug, + defmt::Format, + Serialize, + Deserialize, + MaxSize, + Eq, + PartialEq, + Hash, +)] +pub enum Device { + Bme280, +} + +impl core::fmt::Display for Device { + fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { + write!(f, "{}", self.info().name) + } +} + +macro_rules! rtree { + [$($reading:expr),+] => { + [$(crate::Reading::SmallBedroom( + crate::small_bedroom::Reading::Desk($reading), + )),+] + }; +} + +impl Device { + #[must_use] + pub fn rooted(self) -> crate::Device { + crate::Device::SmallBedroom(crate::small_bedroom::Device::Desk(self)) + } + + #[must_use] + pub const fn info(&self) -> crate::DeviceInfo { + match self { + Device::Bme280 => crate::DeviceInfo { + name: "Bme280", + affects_readings: &rtree![ + Reading::Temperature(0.0), + Reading::Humidity(0.0), + Reading::Pressure(0.0) + ], + affectors: &[], + min_sample_interval: Duration::from_secs(5), + max_sample_interval: Duration::from_secs(5), + temporal_resolution: Duration::from_secs(1), + }, + } + } +} diff --git a/crates/protocol/src/small_bedroom/portable_button_panel.rs b/crates/protocol/src/small_bedroom/portable_button_panel.rs new file mode 100644 index 00000000..f6d3196b --- /dev/null +++ b/crates/protocol/src/small_bedroom/portable_button_panel.rs @@ -0,0 +1,142 @@ +use core::time::Duration; + +use postcard::experimental::max_size::MaxSize; +use serde::{Deserialize, Serialize}; + +#[cfg(feature = "alloc")] +use crate::reading::tree::{Item, Tree}; +#[cfg(feature = "alloc")] +use crate::reading::FloatLabelFormatter; +use crate::IsSameAs; + +#[derive( + strum::EnumDiscriminants, + Clone, + Copy, + Debug, + defmt::Format, + Serialize, + Deserialize, + MaxSize, + PartialEq, +)] +#[repr(u8)] +pub enum Reading { + PlayPause, + TrackNext, + TrackPrevious, + VolumeUp, + VolumeUpHold, + VolumeDown, + VolumeDownHold, + Dots1InitialPress, + Dots1ShortRelease, + Dots1DoublePress, + Dots1LongPress, + Dots1LongRelease, + Dots2InitialPress, + Dots2ShortRelease, + Dots2DoublePress, + Dots2LongPress, + Dots2LongRelease, +} + +#[cfg(feature = "alloc")] +impl Tree for Reading { + fn inner(&self) -> Item<'_> { + let info = crate::reading::Info { + val: 1.0, // This is wrong and should be treated like button + device: crate::Device::SmallBedroom( + super::Device::PortableButtonPanel(Device), + ), + description: "button", + range: 0.0..=2.0, + resolution: 1.0, + unit: crate::Unit::None, + branch_id: self.branch_id(), + label_formatter: Box::new(FloatLabelFormatter), + }; + + Item::Leaf(info) + } + + fn inner_mut(&mut self) -> crate::reading::tree::ItemMut<'_> { + crate::reading::tree::ItemMut::Leaf(self) + } + + fn name(&self) -> String { + let dbg_repr = format!("{self:?}"); + dbg_repr + } + + fn branch_id(&self) -> crate::reading::tree::Id { + ReadingDiscriminants::from(self) as crate::reading::tree::Id + } +} + +impl IsSameAs for Reading { + fn is_same_as(&self, other: &Self) -> bool { + self.eq(other) + } +} + +#[derive( + Clone, + Debug, + defmt::Format, + Serialize, + Deserialize, + MaxSize, + Eq, + PartialEq, + Hash, +)] +pub struct Device; + +impl core::fmt::Display for Device { + fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { + write!(f, "{}", self.info().name) + } +} + +macro_rules! tree { + [$thing:ident; $($item:expr),+] => { + [$(crate::$thing::SmallBedroom( + crate::small_bedroom::$thing::PortableButtonPanel($item), + )),+] + }; +} + +impl Device { + /// Note the order in which the `affects_readings` occur is the order in which + /// they will be stored, do not change it! + #[must_use] + pub const fn info(&self) -> crate::DeviceInfo { + crate::DeviceInfo { + name: "Ikea Symfonisk", + affects_readings: &tree![Reading; + Reading::PlayPause, + Reading::TrackNext, + Reading::TrackPrevious, + Reading::VolumeUp, + Reading::VolumeUpHold, + Reading::VolumeDown, + Reading::VolumeDownHold, + Reading::Dots1InitialPress, + Reading::Dots1ShortRelease, + Reading::Dots1DoublePress, + Reading::Dots1LongPress, + Reading::Dots1LongRelease, + Reading::Dots2InitialPress, + Reading::Dots2ShortRelease, + Reading::Dots2DoublePress, + Reading::Dots2LongPress, + Reading::Dots2LongRelease + ], + temporal_resolution: Duration::from_secs(1), // unknown + min_sample_interval: Duration::from_secs(5), // unknown + max_sample_interval: Duration::MAX, + affectors: &[], + } + } +} diff --git a/crates/protocol/src/small_bedroom/radiator.rs b/crates/protocol/src/small_bedroom/radiator.rs new file mode 100644 index 00000000..80f48fb4 --- /dev/null +++ b/crates/protocol/src/small_bedroom/radiator.rs @@ -0,0 +1,154 @@ +use core::time::Duration; + +use postcard::experimental::max_size::MaxSize; +use serde::{Deserialize, Serialize}; + +#[cfg(feature = "alloc")] +use crate::reading::tree::{Item, Tree}; +#[cfg(feature = "alloc")] +use crate::reading::FloatLabelFormatter; +#[cfg(feature = "alloc")] +use crate::reading::Info; +use crate::shared::impl_is_same_as; +#[cfg(feature = "alloc")] +use crate::Unit; + +#[derive( + strum::EnumDiscriminants, + Clone, + Copy, + Debug, + defmt::Format, + Serialize, + Deserialize, + MaxSize, + PartialEq, +)] +#[strum_discriminants(derive(Hash))] +#[repr(u8)] +pub enum Reading { + Temperature(f32) = 0, + Heating(f32) = 1, + SetBy(crate::shared::radiator::Source) = 2, + Setpoint(f32) = 3, +} + +impl_is_same_as!(Reading; Temperature, Heating, SetBy, Setpoint); + +#[cfg(feature = "alloc")] +impl Tree for Reading { + fn inner(&self) -> Item<'_> { + let info = match self { + Reading::Temperature(val) => Info { + val: *val, + device: crate::Device::SmallBedroom(super::Device::Radiator( + Device, + )), + resolution: 0.01, + range: -10.0..=45.0, + unit: Unit::C, + description: "Temperature", + branch_id: self.branch_id(), + label_formatter: Box::new(FloatLabelFormatter), + }, + Reading::Heating(val) => Info { + val: *val, + device: crate::Device::SmallBedroom(super::Device::Radiator( + Device, + )), + resolution: 1.0, + range: 0.0..=100.0, + unit: Unit::RelativePower, + description: "Heating valve", + branch_id: self.branch_id(), + label_formatter: Box::new(FloatLabelFormatter), + }, + Reading::SetBy(val) => Info { + val: *val as u8 as f32, + device: crate::Device::SmallBedroom(super::Device::Radiator( + Device, + )), + resolution: 1.0, + range: 0.0..=2.0, + unit: Unit::None, + description: "Manual value set", + branch_id: self.branch_id(), + label_formatter: Box::new( + crate::shared::radiator::SetByLabelFormatter, + ), + }, + Reading::Setpoint(val) => Info { + val: *val, + device: crate::Device::SmallBedroom(super::Device::Radiator( + Device, + )), + resolution: 0.5, + range: 0.0..=30.0, + unit: Unit::C, + description: "Set point", + branch_id: self.branch_id(), + label_formatter: Box::new(FloatLabelFormatter), + }, + }; + + Item::Leaf(info) + } + + fn inner_mut(&mut self) -> crate::reading::tree::ItemMut<'_> { + use crate::reading::tree::{field_as_any, ItemMut}; + + let value = field_as_any!(self, Temperature, Heating, SetBy, Setpoint); + ItemMut::Leaf(value) + + } + + fn branch_id(&self) -> crate::reading::tree::Id { + ReadingDiscriminants::from(self) as crate::reading::tree::Id + } +} + +#[derive( + Clone, + Debug, + defmt::Format, + Serialize, + Deserialize, + MaxSize, + Eq, + PartialEq, + Hash, +)] +pub struct Device; + +impl core::fmt::Display for Device { + fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { + write!(f, "{}", self.info().name) + } +} + +macro_rules! tree { + [$thing:ident; $($item:expr),+] => { + [$(crate::$thing::SmallBedroom( + crate::small_bedroom::$thing::Radiator($item), + )),+] + }; +} + +impl Device { + /// Note the order in which the `affects_readings` occur is the order in which + /// they will be stored, do not change it! + #[must_use] + pub const fn info(&self) -> crate::DeviceInfo { + crate::DeviceInfo { + name: "Radiator", + affects_readings: &tree![Reading; + Reading::Temperature(0.0), Reading::Heating(0.0), + Reading::SetBy(crate::shared::radiator::Source::Manual), + Reading::Setpoint(0.0)], + temporal_resolution: Duration::from_secs(5), // unknown + min_sample_interval: Duration::from_secs(5), // unknown + max_sample_interval: Duration::MAX, + affectors: &[], + } + } +} diff --git a/crates/protocol/src/usb.rs b/crates/protocol/src/usb.rs new file mode 100644 index 00000000..3801ef2e --- /dev/null +++ b/crates/protocol/src/usb.rs @@ -0,0 +1,6 @@ +pub const GET_QUEUED_MESSAGES: u8 = 101; +pub const AFFECTOR_ORDER: u8 = 100; +pub const GET_AFFECTOR_LIST: u8 = 102; + +// USB full speed devices have a max data packet size of 1023 +pub const SEND_BUFFER_SIZE: usize = 208; diff --git a/crates/radiator-bridge/.cargo/config.toml b/crates/radiator-bridge/.cargo/config.toml new file mode 100644 index 00000000..6f758d47 --- /dev/null +++ b/crates/radiator-bridge/.cargo/config.toml @@ -0,0 +1,7 @@ +[target.aarch64-unknown-linux-musl] +rustflags = ["-Clinker=rust-lld"] + +[target.armv7-unknown-linux-musleabihf] +rustflags = ["-Clinker=rust-lld"] + +#Note: If you're using lld or mold on Linux, you must use the --no-rosegment flag. Otherwise perf will not be able to generate accurate stack traces (explanation). For example, for lld: diff --git a/crates/radiator-bridge/Cargo.toml b/crates/radiator-bridge/Cargo.toml new file mode 100644 index 00000000..ce7f00d3 --- /dev/null +++ b/crates/radiator-bridge/Cargo.toml @@ -0,0 +1,20 @@ +[package] +name = "radiator-bridge" +version = "0.1.0" +rust-version.workspace = true +edition.workspace = true +license.workspace = true +authors.workspace = true + +[dependencies] +protocol = { workspace = true, features = ["alloc"] } +data-server = { workspace = true } +zigbee-bridge = { workspace = true } + +tokio = { workspace = true } +clap = { workspace = true } +logger = { workspace = true } +tracing = { workspace = true } +color-eyre.workspace = true +futures-concurrency.workspace = true +futures = "0.3.31" diff --git a/crates/radiator-bridge/deploy.sh b/crates/radiator-bridge/deploy.sh new file mode 100755 index 00000000..65f7205a --- /dev/null +++ b/crates/radiator-bridge/deploy.sh @@ -0,0 +1,19 @@ +#!/usr/bin/env bash +set -e + +BUILD_ARG=--release +SERVER="sgc" # ssh config name or full address +NAME=radiator-bridge + +cargo build --target=aarch64-unknown-linux-musl $BUILD_ARG +rsync -vh --progress \ + ../../target/aarch64-unknown-linux-musl/release/$NAME \ + $SERVER:/tmp/ + +cmds=" +sudo mv /tmp/$NAME /home/ha/$NAME +sudo chown ha:ha /home/ha/$NAME +sudo systemctl restart $NAME.service +" + +ssh -t $SERVER "$cmds" diff --git a/crates/radiator-bridge/profile.sh b/crates/radiator-bridge/profile.sh new file mode 100755 index 00000000..2867bc21 --- /dev/null +++ b/crates/radiator-bridge/profile.sh @@ -0,0 +1,29 @@ +#!/usr/bin/env bash + +set -e + +# Print if argument matches regex: +# +# you can do this with: RUST_LOG='[{topic=.*small_bedroom:piano.*}]=trace,info' +# that will print every log at trace level or higher that is inside an +# instrumented function with an argument topic for which the regex +# .*small_bedroom.* evaluates as true +# +# +# Print if in function: +# RUST_LOG='[function_name]=trace' + +# RUST_LOG='[parse_message]=trace,[{device_name=.*:radi.*}]=trace,[{friendly_name=.*:radi.*}]=trace,info' + +cargo build --profile=release-with-debug +echo '1' | sudo tee /proc/sys/kernel/perf_event_paranoid + +# samply record ../../target/release-with-debug/radiator-bridge \ +# --data-server-subscribe=192.168.1.43:1235 \ +# --data-server-update=192.168.1.43:1234 \ +# --mqtt-ip=192.168.1.43 + +flamegraph -- ../../target/release-with-debug/radiator-bridge \ + --data-server-subscribe=192.168.1.43:1235 \ + --data-server-update=192.168.1.43:1234 \ + --mqtt-ip=192.168.1.43 diff --git a/crates/radiator-bridge/src/main.rs b/crates/radiator-bridge/src/main.rs new file mode 100644 index 00000000..66da7d52 --- /dev/null +++ b/crates/radiator-bridge/src/main.rs @@ -0,0 +1,189 @@ +use std::net::{IpAddr, SocketAddr}; +use std::time::{Duration, Instant}; + +use clap::Parser; +use data_server::api::data_source; +use data_server::api::subscriber; +use data_server::api::subscriber::SubMessage as M; +use futures::FutureExt; +use futures_concurrency::future::Race; +use tracing::warn; +use zigbee_bridge::Controller; + +#[derive(Parser)] +#[command(version, about, long_about=None)] +struct Opt { + /// IP address where to subscribe for updates + #[clap(long)] + data_server_subscribe: SocketAddr, + + /// IP address where to send readings + #[clap(long)] + data_server_update: SocketAddr, + + /// IP address for MQTT broker + #[clap(long)] + mqtt_ip: IpAddr, +} + +enum RelevantMsg { + SmallBedroom(f64), + LargeBedroom(f64), +} + +#[derive(Debug, Default)] +struct RadiatorState { + last_set_at: Option, + last_set_value: Option, +} + +impl RadiatorState { + // You *must* set the `External_measured_room_sensor` property *at least* + // every 3 hours. After 3 hours the TRV disables this function and resets + // the value of the `External_measured_room_sensor` property to -8000 + // (disabled). + // + // You *should* set the `External_measured_room_sensor` + // property *at most* every 30 minutes or every 0.1°C change in measured + // room temperature. + // + // If `Radiator_covered` is `true` (Room Sensor Mode): + // You *must* set the `External_measured_room_sensor` property *at least* + // every 30 minutes. After 35 minutes the TRV disables this function and + // resets the value of the `External_measured_room_sensor` property to + // -8000 (disabled). + // + // You *should* set the `External_measured_room_sensor` + // property *at most* every 5 minutes or every 0.1°C change in measured + // room temperature. The unit of this value is 0.01 `°C` (so e.g. 21°C + // would be represented as 2100). + fn should_update_given(&mut self, temp: f64) -> bool { + const T30MINUTES: Duration = Duration::from_secs(60 * 30); + + if self + .last_set_value + .is_none_or(|val| (val - temp).abs() >= 0.1) + || self.last_set_at.is_none_or(|at| at.elapsed() > T30MINUTES) + { + self.last_set_at = Some(Instant::now()); + self.last_set_value = Some(temp); + true + } else { + false + } + } +} + +// #[tokio::main(flavor = "current_thread")] +#[tokio::main] +async fn main() { + let args = Opt::parse(); + color_eyre::install().unwrap(); + logger::tracing::setup(); + + let mut data_subscriber = subscriber::ReconnectingClient::new( + args.data_server_subscribe, + env!("CARGO_PKG_NAME").to_owned(), + ) + .subscribe(); + + let mut data_source = data_source::reconnecting::Client::new( + args.data_server_update, + Vec::new(), + None, + ) + .await + .expect("address is correct"); + + let (reading_tx, mut reading_rx) = tokio::sync::mpsc::channel(1024); + let callback = move |reading| { + reading_tx + .try_send(reading) + .expect("reading_rx should keep up and never drop") + }; + let controller = Controller::start_bridge_with_reading_callback( + args.mqtt_ip, + "temp-bridge", + callback, + ); + + let mut radiators = Radiators { + controller, + small_bedroom: RadiatorState::default(), + large_bedroom: RadiatorState::default(), + }; + + loop { + let get_reading = reading_rx + .recv() + .map(|r| r.expect("reading_tx should not drop")) + .map(Event::ZigbeeReading); + let get_msg = data_subscriber.next().map(Event::DataServerMsg); + let event = (get_reading, get_msg).race().await; + + match event { + Event::ZigbeeReading(reading) => { + if let Err(e) = data_source.send_reading(reading).await { + warn!("Error sending new reading to data-store: {e}") + } + } + Event::DataServerMsg(msg) => radiators.update_if_relevant(msg), + } + } +} + +struct Radiators { + controller: Controller, + small_bedroom: RadiatorState, + large_bedroom: RadiatorState, +} + +impl Radiators { + fn update_if_relevant(&mut self, msg: M) { + let Some(relevant_msg) = RelevantMsg::from(msg) else { + return; + }; + + match relevant_msg { + RelevantMsg::SmallBedroom(temp) => { + if self.small_bedroom.should_update_given(temp) { + self.controller + .set_radiator_reference("small_bedroom:radiator", temp) + } + } + RelevantMsg::LargeBedroom(temp) => { + if self.large_bedroom.should_update_given(temp) { + self.controller + .set_radiator_reference("large_bedroom:radiator", temp) + } + } + } + } +} + +enum Event { + DataServerMsg(data_server::api::subscriber::SubMessage), + ZigbeeReading(protocol::Reading), +} + +impl RelevantMsg { + fn from(msg: M) -> Option { + use protocol::large_bedroom; + use protocol::large_bedroom::desk as ldesk; + use protocol::small_bedroom; + use protocol::small_bedroom::desk as sdesk; + use protocol::Reading; + + match msg { + M::Reading(Reading::LargeBedroom( + large_bedroom::Reading::Desk(ldesk::Reading::Temperature(temp)), + )) => Some(RelevantMsg::LargeBedroom(temp as f64)), + M::Reading(Reading::SmallBedroom( + small_bedroom::Reading::Desk(sdesk::Reading::Temperature(temp)), + )) => Some(RelevantMsg::SmallBedroom(temp as f64)), + M::ErrorReport(_) + | M::Reading(_) + | M::AffectorControlled { .. } => None, + } + } +} diff --git a/crates/radiator-bridge/test.sh b/crates/radiator-bridge/test.sh new file mode 100755 index 00000000..40fd359e --- /dev/null +++ b/crates/radiator-bridge/test.sh @@ -0,0 +1,19 @@ +#!/usr/bin/env bash + +# Print if argument matches regex: +# +# you can do this with: RUST_LOG='[{topic=.*small_bedroom:piano.*}]=trace,info' +# that will print every log at trace level or higher that is inside an +# instrumented function with an argument topic for which the regex +# .*small_bedroom.* evaluates as true +# +# +# Print if in function: +# RUST_LOG='[function_name]=trace' + +# RUST_LOG='[parse_message]=trace,[{device_name=.*:radi.*}]=trace,[{friendly_name=.*:radi.*}]=trace,info' + +cargo r -- \ + --data-server-subscribe=192.168.1.43:1235 \ + --data-server-update=192.168.1.43:1234 \ + --mqtt-ip=192.168.1.43 diff --git a/crates/rpc/Cargo.toml b/crates/rpc/Cargo.toml new file mode 100644 index 00000000..4e1f9876 --- /dev/null +++ b/crates/rpc/Cargo.toml @@ -0,0 +1,19 @@ +[package] +name = "rpc" +version = "0.1.0" +rust-version.workspace = true +edition.workspace = true +license.workspace = true +authors.workspace = true + +[dependencies] +color-eyre.workspace = true +futures.workspace = true +governor.workspace = true +tokio = { workspace = true, features = ["net", "rt", "sync", "time"] } +tokio-util.workspace = true +tracing.workspace = true + +serde.workspace = true +tokio-serde = { version = "0.9.0", features = ["bincode"] } +thiserror.workspace = true diff --git a/crates/rpc/src/client.rs b/crates/rpc/src/client.rs new file mode 100644 index 00000000..57017b21 --- /dev/null +++ b/crates/rpc/src/client.rs @@ -0,0 +1,195 @@ +use core::fmt; +use std::marker::Unpin; +use std::time::Duration; + +use futures::{SinkExt, TryStreamExt}; +use serde::de::DeserializeOwned; +use serde::Serialize; +use tokio::net::TcpStream; +use tokio::net::ToSocketAddrs; +use tokio::time::error::Elapsed; +use tokio::time::timeout_at; +use tokio::time::Instant; +use tokio_serde::formats::Bincode; +use tokio_util::codec::{Framed, LengthDelimitedCodec}; + +use crate::Request; +use crate::Response; + +type Stream = tokio_serde::Framed< + Framed, + Response, + Request, + Bincode, Request>, +>; + +pub struct RpcClient +where + RpcResp: Serialize, +{ + stream: Stream, +} + +impl fmt::Debug for RpcClient { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + f.debug_struct("RpcClient").finish() + } +} + +#[derive(Debug, thiserror::Error)] +pub enum ConnectError { + #[error("Error while connecting to server")] + Io(#[source] std::io::Error), + #[error("Could not send handshake")] + Sending(#[source] std::io::Error), + #[error("Timed out waiting for server")] + Timeout, + #[error("Server unexpectedly closed the connection")] + Closed, + #[error("Could not receive server response")] + Receiving(#[source] std::io::Error), + #[error("Client was already connected")] + AlreadyConnected, + #[error("Client tried to connected too many times, allowed again in: {0:?}")] + RateLimited(Duration), +} + +#[derive(Debug, thiserror::Error)] +pub enum RpcError { + #[error("Got unexpected response response to request.\nRequest was: {request:?},\nGot response: {response:?}")] + IncorrectResponse { request: String, response: String }, + #[error("Error while sending request")] + Sending(#[source] std::io::Error), + #[error("Error while sending request")] + Receiving(#[source] std::io::Error), + #[error("Server closed connection before it awnserd")] + ConnectionClosed, +} + +impl RpcClient +where + RpcReq: Unpin + Serialize + fmt::Debug, + RpcResp: Unpin + Serialize + DeserializeOwned + fmt::Debug, +{ + async fn try_connect( + addr: impl ToSocketAddrs, + name: String, + ) -> Result, ConnectError> { + let stream = TcpStream::connect(addr).await.map_err(ConnectError::Io)?; + let _ignore_error = stream.set_nodelay(true); + + let length_delimited = Framed::new( + stream, + LengthDelimitedCodec::builder() + .max_frame_length(super::MAX_PACKAGE_SIZE) + .new_codec(), + ); + + let mut stream = tokio_serde::Framed::new(length_delimited, Bincode::default()); + stream + .send(Request::Handshake { client_name: name }) + .await + .map_err(ConnectError::Sending)?; + Ok(stream) + } + + pub async fn connect(addr: impl ToSocketAddrs, name: String) -> Result { + let mut stream = Self::try_connect(addr, name).await?; + match tokio::time::timeout(Duration::from_secs(2), stream.try_next()).await { + Ok(Ok(Some(Response::HandshakeOk))) => Ok(Self { stream }), + Ok(Ok(Some(Response::AlreadyConnected))) => Err(ConnectError::AlreadyConnected), + Ok(Ok(Some(Response::TooManyReq { allowed_in }))) => { + Err(ConnectError::RateLimited(allowed_in)) + } + + Ok(Ok(Some(other))) => unreachable!( + "Server should return handshake response or error after sending \ + first handshake, got impossible response: {other:?}" + ), + Ok(Ok(None)) => Err(ConnectError::Closed), + Ok(Err(e)) => Err(ConnectError::Receiving(e)), + Err(_) => Err(ConnectError::Timeout), + } + } + + pub async fn subscribe(&mut self) -> Result<(), RpcError> { + fn send_timeout_err(_: Elapsed) -> RpcError { + RpcError::Sending(std::io::Error::new(std::io::ErrorKind::TimedOut, "")) + } + fn receive_timeout_err(_: Elapsed) -> RpcError { + RpcError::Receiving(std::io::Error::new(std::io::ErrorKind::TimedOut, "")) + } + + let deadline = Instant::now() + Duration::from_secs(5); + let request = Request::Subscribe; + timeout_at(deadline, self.stream.send(request)) + .await + .map_err(send_timeout_err)? + .map_err(RpcError::Sending)?; + + let response = timeout_at(deadline, self.stream.try_next()) + .await + .map_err(receive_timeout_err)? + .map_err(RpcError::Receiving)? + .ok_or(RpcError::ConnectionClosed)?; + match response { + Response::AlreadyConnected + | Response::RpcResponse(_) + | Response::Update(_) + | Response::TooManyReq { .. } + | Response::HandshakeOk => { + unreachable!("incorrect response to subscribe: {response:?}") + } + Response::SubscribeOk => Ok(()), + } + } + + pub async fn next(&mut self) -> Result { + let received = self + .stream + .try_next() + .await + .map_err(RpcError::Receiving)? + .ok_or(RpcError::ConnectionClosed)?; + + match received { + Response::AlreadyConnected + | Response::RpcResponse(_) + | Response::TooManyReq { .. } + | Response::HandshakeOk + | Response::SubscribeOk => { + unreachable!("incorrect response to get next, are we subscribed?") + } + Response::Update(v) => Ok(v), + } + } + + pub async fn send_receive(&mut self, request: RpcReq) -> Result { + fn send_timeout_err(_: Elapsed) -> RpcError { + RpcError::Sending(std::io::Error::new(std::io::ErrorKind::TimedOut, "")) + } + fn receive_timeout_err(_: Elapsed) -> RpcError { + RpcError::Receiving(std::io::Error::new(std::io::ErrorKind::TimedOut, "")) + } + + let deadline = Instant::now() + Duration::from_secs(5); + let request = Request::Rpc(request); + timeout_at(deadline, self.stream.send(request)) + .await + .map_err(send_timeout_err)? + .map_err(RpcError::Sending)?; + match timeout_at(deadline, self.stream.try_next()) + .await + .map_err(receive_timeout_err)? + .map_err(RpcError::Receiving)? + .ok_or(RpcError::ConnectionClosed)? + { + Response::AlreadyConnected + | Response::Update(_) + | Response::TooManyReq { .. } + | Response::HandshakeOk + | Response::SubscribeOk => unreachable!("only expected after a subscribe"), + Response::RpcResponse(v) => Ok(v), + } + } +} diff --git a/crates/rpc/src/lib.rs b/crates/rpc/src/lib.rs new file mode 100644 index 00000000..dce82eea --- /dev/null +++ b/crates/rpc/src/lib.rs @@ -0,0 +1,64 @@ +use std::future; +use std::marker::PhantomData; +use std::time::Duration; + +use futures::{stream, Stream}; +use serde::{Deserialize, Serialize}; + +pub mod client; +pub mod server; + +// 8 MB +pub(crate) const MAX_PACKAGE_SIZE: usize = 8 * 1024 * 1024; + +pub trait SubscriberHandler: Send + 'static { + type Update; + + /// The returned stream should never end before the client disconnects. + #[allow(async_fn_in_trait)] + fn setup( + &mut self, + ) -> impl std::future::Future + Send + 'static> + + Send + + 'static; +} + +/// needed (I know ugly) to give the Option::None a complete type +/// for the server::run function (which takes a Option) +#[derive(Debug, Clone)] +pub struct SubscribersUnsupported { + phantom: PhantomData, +} + +impl SubscriberHandler for SubscribersUnsupported { + type Update = Update; + + fn setup( + &mut self, + ) -> impl std::future::Future< + Output = impl futures::prelude::Stream + Send + 'static, + > + Send + + 'static { + future::pending::>() + } +} + +#[derive(Debug, Clone, Serialize, Deserialize)] +pub enum Request { + Handshake { client_name: String }, + Subscribe, + Rpc(R), +} + +#[derive(Debug, Clone, Serialize, Deserialize)] +pub enum Response +where + V: Serialize, +{ + HandshakeOk, + SubscribeOk, + AlreadyConnected, + TooManyReq { allowed_in: Duration }, + RpcResponse(V), + Update(V), +} diff --git a/crates/rpc/src/server.rs b/crates/rpc/src/server.rs new file mode 100644 index 00000000..5852f388 --- /dev/null +++ b/crates/rpc/src/server.rs @@ -0,0 +1,199 @@ +use std::fmt; +use std::marker::Unpin; +use std::net::SocketAddr; +use std::num::NonZeroU32; +use std::time::Duration; + +use color_eyre::eyre::Context; +use color_eyre::Section; +use futures::{SinkExt, StreamExt, TryStreamExt}; +use governor::clock::{Clock, DefaultClock}; +use governor::{Quota, RateLimiter}; +use serde::de::DeserializeOwned; +use serde::Serialize; +use tokio::net::{TcpListener, TcpStream}; +use tokio::pin; +use tokio_serde::formats::Bincode; +use tokio_util::codec::{Framed, LengthDelimitedCodec}; + +use tracing::{debug, error, instrument}; + +type Conn = tokio_serde::Framed< + Framed, + crate::Request, + crate::Response, + Bincode, crate::Response>, +>; + +pub async fn run( + port: u16, + perform_request: impl Fn(RpcReq, &str) -> PerfFut + Clone + Send + 'static, + sub_handler: Option< + impl SubscriberHandler + Clone + 'static, + >, +) -> color_eyre::Result<()> +where + RpcReq: Unpin + Serialize + DeserializeOwned + fmt::Debug + Send + 'static, + RpcResp: Unpin + Serialize + DeserializeOwned + fmt::Debug + Send + 'static, + PerfFut: Future + Send + 'static, +{ + let quota = Quota::with_period(Duration::from_secs(1)) + .unwrap() + .allow_burst(NonZeroU32::new(30u32).unwrap()); + let limiter = RateLimiter::keyed(quota); + let listener = TcpListener::bind(format!("0.0.0.0:{port}")) + .await + .wrap_err("Could not bind to address") + .with_note(|| format!("port: {port}"))?; + + loop { + let (socket, source) = match listener.accept().await { + Err(e) => { + tracing::warn!("client could not connect: {e}"); + continue; + } + Ok(res) => res, + }; + + let Some((mut conn, name)) = + handshake_and_log::(socket, source).await + else { + continue; + }; + + if let Err(allowed_again) = + limiter.check_key(&(source.ip(), name.clone())) + { + let allowed_in = + allowed_again.wait_time_from(DefaultClock::default().now()); + let _ignore_err = + conn.send(crate::Response::TooManyReq { allowed_in }).await; + continue; + } + + debug!("Client {name} connected from {source}"); + let Ok(()) = conn.send(crate::Response::HandshakeOk).await else { + continue; + }; + + tokio::task::spawn(handle_client( + conn, + name, + perform_request.clone(), + sub_handler.clone(), + )); + } +} + +async fn handshake_and_log( + stream: TcpStream, + source: SocketAddr, +) -> Option<(Conn, String)> +where + RpcReq: Unpin + Serialize + DeserializeOwned + fmt::Debug + Send + 'static, + RpcResp: Unpin + Serialize + DeserializeOwned + fmt::Debug + Send + 'static, +{ + let length_delimited = Framed::new( + stream, + LengthDelimitedCodec::builder() + .max_frame_length(super::MAX_PACKAGE_SIZE) + .new_codec(), + ); + let mut stream: tokio_serde::Framed< + _, + crate::Request, + crate::Response, + _, + > = tokio_serde::Framed::new(length_delimited, Bincode::default()); + + match stream.try_next().await { + Ok(Some(crate::Request::Handshake { client_name })) => { + return Some((stream, client_name)); + } + Ok(Some(other)) => { + tracing::warn!("client from {source} tried to connected without handshake, it send: {other:?}") + } + Ok(None) => { + tracing::warn!("client from {source} closed connection immediately") + } + Err(e) => { + tracing::warn!("connection or decoding issue while receiving handshake from {source}, error: {e:?}") + } + } + + None +} + +use core::future::Future; + +use crate::SubscriberHandler; +#[instrument(skip(conn, perform_request, sub_handler))] +/// When the provided sub_handler is used to create a stream that stream should +/// never end before the client disconnects +async fn handle_client( + mut conn: Conn, + client_name: String, + perform_request: impl Fn(RpcReq, &str) -> PerfFut + Clone + Send + 'static, + mut sub_handler: Option + 'static>, +) where + RpcReq: Unpin + Serialize + DeserializeOwned + fmt::Debug + Send + 'static, + RpcResp: Unpin + Serialize + DeserializeOwned + fmt::Debug + Send + 'static, + PerfFut: Future + Send + 'static, +{ + loop { + let request = match conn.try_next().await { + Ok(Some(request)) => request, + Ok(None) => { + debug!("Connection ended"); + return; + } + Err(e) => { + error!("Could not receive request: {e:?}"); + return; + } + }; + match request { + crate::Request::Rpc(rpc_request) => { + let response = perform_request(rpc_request, &client_name).await; + if let Err(e) = + conn.send(crate::Response::RpcResponse(response)).await + { + error!("Error sending response to client: {e:?}"); + return; + } + } + crate::Request::Subscribe => { + if let Some(mut sub_handler) = sub_handler.take() { + let stream = sub_handler.setup().await; + pin!(stream); + if let Err(e) = + conn.send(crate::Response::SubscribeOk).await + { + debug!("Error sending response to client: {e:?}"); + return; + } + + loop { + let update = stream + .next() + .await + .expect("subscribe stream should never end"); + if let Err(e) = + conn.send(crate::Response::Update(update)).await + { + debug!("Error sending response to client: {e:?}"); + return; + } + } + } else { + error!("Got subscribe request but no subscribe possible"); + return; + } + } + crate::Request::Handshake { .. } => { + error!("Handshake request only allowed during connect"); + return; + } + }; + } +} diff --git a/crates/text-widget/Cargo.toml b/crates/text-widget/Cargo.toml new file mode 100644 index 00000000..48793364 --- /dev/null +++ b/crates/text-widget/Cargo.toml @@ -0,0 +1,28 @@ +[package] +name = "ha-text-widget" +version = "0.1.0" +rust-version.workspace = true +edition.workspace = true +license.workspace = true +authors.workspace = true +description = "Widget for a desktop environment bar which displays sensor readings" + +[dependencies] +clap.workspace = true +color-eyre = { workspace = true } +protocol = { workspace = true, features = ["alloc", "thiserror"] } +data-server = { workspace = true } +data-store = { workspace = true } +nucleo-matcher = "0.3.1" +tokio = { workspace = true} +gethostname.workspace = true + +itertools.workspace = true +logger.workspace = true +tracing.workspace = true +tracing-error.workspace = true +tracing-subscriber.workspace = true +dirs = "6.0" +serde.workspace = true +promptly = "0.3.1" +ron.workspace = true diff --git a/crates/text-widget/deploy.sh b/crates/text-widget/deploy.sh new file mode 100755 index 00000000..cc6441a8 --- /dev/null +++ b/crates/text-widget/deploy.sh @@ -0,0 +1,5 @@ +#!/usr/bin/env bash + +set -e + +cargo install --path . diff --git a/crates/text-widget/src/cache.rs b/crates/text-widget/src/cache.rs new file mode 100644 index 00000000..bc66825e --- /dev/null +++ b/crates/text-widget/src/cache.rs @@ -0,0 +1,72 @@ +use std::collections::HashMap; +use std::io::ErrorKind; +use std::path::PathBuf; + +use color_eyre::eyre::Context; +use color_eyre::{Result, Section}; +use protocol::Reading; +use tokio::fs; + +pub(crate) async fn store_to_file( + fully_qualified: &[Reading], + queries: &[String], +) -> Result<()> { + let mut entries = load_entries() + .await + .wrap_err("Could not load existing cache")? + .unwrap_or_default(); + + entries + .extend(queries.iter().cloned().zip(fully_qualified.iter().cloned())); + let serialized = ron::to_string(&entries) + .wrap_err("Could not serialize query resolve result")?; + + let path = path()?; + fs::write(path, serialized.as_bytes()) + .await + .wrap_err("Could not update file") +} + +fn path() -> Result { + Ok(dirs::data_local_dir() + .ok_or(color_eyre::eyre::eyre!( + "Could not load where to load query from" + ))? + .join(concat!(env!("CARGO_PKG_NAME"), ".ron"))) +} + +type Query = String; +pub(crate) async fn load_entries() -> Result>> { + let path = path()?; + let entries = match fs::read_to_string(&path).await { + Ok(entries) => entries, + Err(e) if e.kind() == ErrorKind::NotFound => return Ok(None), + other_err => other_err + .wrap_err("Could not read cache to string") + .with_note(|| format!("path: {}", path.display()))?, + }; + Ok(Some( + ron::from_str(&entries) + .wrap_err("Could not deserialize resolve cache") + .with_note(|| format!("path: {}", path.display()))?, + )) +} + +pub(crate) async fn load_from_file( + queries: &Vec, +) -> Result>> { + let Some(mut entries) = load_entries().await? else { + return Ok(queries.iter().map(|_| None).collect()); + }; + + Ok(queries.iter().map(|q| entries.remove(q)).collect()) +} + +pub(crate) async fn clear() -> Result<()> { + let path = path()?; + match fs::remove_file(path).await { + Ok(()) => Ok(()), + Err(e) if e.kind() == ErrorKind::NotFound => Ok(()), + Err(e) => Err(e).wrap_err("io error"), + } +} diff --git a/crates/text-widget/src/main.rs b/crates/text-widget/src/main.rs new file mode 100644 index 00000000..5cd50089 --- /dev/null +++ b/crates/text-widget/src/main.rs @@ -0,0 +1,219 @@ +use color_eyre::eyre::{eyre, Context}; +use color_eyre::Result; +use data_server::api::subscriber::SubMessage; +use data_server::api::subscriber::{ + ReconnectingClient, ReconnectingSubscribedClient, +}; +use gethostname::gethostname; +use itertools::Itertools; +use protocol::reading::tree::Tree; +use protocol::{IsSameAs, Reading}; +use std::net::SocketAddr; +use std::time::Duration; +use tokio::time::{timeout_at, Instant}; + +use clap::Parser; + +mod cache; +mod resolve; + +#[derive(Parser)] +#[command(version, about, long_about = None)] +struct Cli { + /// the address of the store, optional, speeds up resolving the argument + #[arg(long)] + store: Option, + + /// the address of the data server + #[arg(long, default_value_t = SocketAddr::from(([127,0,0,1], 1235)))] + server: SocketAddr, + + /// print json format where for each query passed in there are two key value pairs: + /// example for the query `temp`: + /// { "temp": 23.40, "temp-unit": "C" } + #[arg(short, long)] + json: bool, + + /// wipe and redo setup + #[arg(short, long)] + setup: bool, + + /// print a custom separator between multiple printed values + #[arg(short = 'd', long, default_value_t = String::from(" "))] + separator: String, + + /// String describing the reading. Something like temp can resolve to + /// `large_bedroom desk temperature`. + /// + /// Run with RUST_LOG=debug to print the resolved string + readings: Vec, +} + +type Index = usize; +async fn wait_for_update( + client: &mut ReconnectingSubscribedClient, + needed: &[Reading], +) -> (Reading, Index) { + loop { + let SubMessage::Reading(update) = client.next().await else { + continue; + }; + if let Some(idx) = + needed.iter().position(|watched| update.is_same_as(watched)) + { + return (update, idx); + } + } +} + +async fn setup( + cli: &Cli, + client: &mut ReconnectingSubscribedClient, +) -> Result> { + let available = resolve::available_readings(cli.store, client).await; + let mut fully_qualified = Vec::new(); + for query in &cli.readings { + let reading = resolve::query(&available, query) + .wrap_err("Could not resolve query to reading")?; + fully_qualified.push(reading); + } + + cache::store_to_file(&fully_qualified, &cli.readings).await?; + Ok(fully_qualified) +} + +#[tokio::main] +async fn main() -> Result<()> { + color_eyre::install().unwrap(); + let cli = Cli::parse(); + logger::tracing::setup(); + + let mut client = ReconnectingClient::new(cli.server, name()).subscribe(); + assert!( + !cli.readings.is_empty(), + "must provide at least one sensor to display" + ); + + if cli.setup { + cache::clear().await.wrap_err("Could not clear cache")?; + } + + let readings = match cache::load_from_file(&cli.readings).await { + Ok(readings) if readings.iter().any(Option::is_none) => { + println!("RunSetup"); + setup(&cli, &mut client).await? + } + Ok(readings) => readings.into_iter().map(Option::unwrap).collect(), + Err(e) => { + println!("Error"); + return Err(eyre!( + "Error, could not load resolved from file: {e:?}" + )); + } + }; + + tracing::debug!("Will be showing: {readings:?}"); + let mut next_timeout_at = + tokio::time::Instant::now() + Duration::from_secs(100); + + let mut entries: Vec<_> = readings + .iter() + .map(|reading| Entry::new_for(reading)) + .collect(); + loop { + let get_update = wait_for_update(&mut client, &readings); + if let Ok((new, idx)) = timeout_at(next_timeout_at, get_update).await { + entries[idx].curr_value = Some(new); + entries[idx].last_updated_at = Instant::now(); + } + + for entry in entries.iter_mut().filter(|e| e.curr_value.is_some()) { + if entry.last_updated_at.elapsed() > entry.timeout_interval { + entry.curr_value = None; + } + } + + if cli.json { + update_stdout_json(&entries, &cli.readings); + } else { + update_stdout(&entries, &cli.separator); + } + + next_timeout_at = Instant::now() + + entries + .iter() + .filter(|Entry { curr_value, .. }| curr_value.is_some()) + .map( + |Entry { + last_updated_at, + timeout_interval, + .. + }| { + timeout_interval + .saturating_sub(last_updated_at.elapsed()) + }, + ) + .min() + .unwrap_or(Duration::from_secs(100)); + } +} + +#[derive(Debug)] +struct Entry { + curr_value: Option, + last_updated_at: Instant, + timeout_interval: Duration, +} + +impl Entry { + fn new_for(reading: &Reading) -> Self { + Self { + curr_value: None, + last_updated_at: Instant::now(), + timeout_interval: reading.info().device.info().max_sample_interval + + Duration::from_secs(1), + } + } + + fn format(&self) -> String { + if let Some(reading) = &self.curr_value { + let info = reading.info(); + format!("{0:.1$} {2}", info.val, info.precision(), info.unit) + } else { + "X".to_string() + } + } +} + +fn update_stdout_json(entries: &[Entry], used_queries: &[String]) { + let json_body = used_queries + .iter() + .zip(entries) + .map(|(query, Entry { curr_value, .. })| { + let value = curr_value + .as_ref() + .map(|r| r.info()) + .map(|info| format!("{0:.1$}", info.val, info.precision())) + .unwrap_or("X".to_string()); + let unit = curr_value + .as_ref() + .map(|r| r.info().unit) + .unwrap_or(protocol::Unit::None); + + format!("\"{query}\": {}, \"{query}-unit\": \"{}\"", value, unit) + }) + .join(", "); + println!("{{ {json_body} }}") +} + +fn update_stdout(entries: &[Entry], separator: &str) { + let mut updates = entries.iter().map(|entry| entry.format()); + let updates: String = updates.join(separator); + println!("{}", updates) +} + +fn name() -> String { + let host = gethostname(); + let host = host.to_string_lossy(); + format!("text-widget@{host}") +} diff --git a/crates/text-widget/src/resolve.rs b/crates/text-widget/src/resolve.rs new file mode 100644 index 00000000..13159388 --- /dev/null +++ b/crates/text-widget/src/resolve.rs @@ -0,0 +1,104 @@ +use color_eyre::eyre::{eyre, Context}; +use data_server::api::subscriber::ReconnectingSubscribedClient; +use itertools::Itertools; +use nucleo_matcher::pattern::Pattern; +use protocol::Reading; +use std::net::SocketAddr; +use std::time::Duration; +use tokio::time::timeout; + +use nucleo_matcher::pattern::{AtomKind, CaseMatching, Normalization}; + +mod fetch; + +pub async fn available_readings( + store_addr: Option, + client: &mut ReconnectingSubscribedClient, +) -> Vec { + if let Some(store_addr) = store_addr { + fetch::datalist_on_store(store_addr, crate::name()) + .await + .unwrap_or(Vec::new()) + } else { + let mut list = Vec::new(); + let _ignore_res = timeout( + Duration::from_secs(7), + fetch::datalist_from_updates(client, &mut list), + ) + .await; + list + } +} + +pub fn query( + list: &[Reading], + reading_query: &str, +) -> color_eyre::Result { + tracing::trace!("{:?}", list); + let options = rank_options(&reading_query, &list); + if options.is_empty() { + return Err(eyre!("No idea whats meant by: {reading_query}")); + }; + + for reading in options.into_iter().take(3) { + let reading_path = to_path(&reading); + if promptly::prompt_default( + format!( + "Is {reading_path:?} what you meant with: {reading_query}?" + ), + false, + ) + .wrap_err("Failed to read user confirmation")? + { + return Ok(reading); + } + } + + Err(eyre!("Could not identify reading meant by user")) +} + +fn to_path(reading: &Reading) -> String { + let path = format!("{:?}", reading); + let (path, _) = path + .rsplit_once('(') + .expect("Reading is tree with at least deph 2"); + path.replace('(', " ") +} + +fn rank_options(query: &str, options: &[Reading]) -> Vec { + let query = query.replace("_", " ").replace("-", " "); + + if options.is_empty() { + return Vec::new(); + } + + let mut matcher = + nucleo_matcher::Matcher::new(nucleo_matcher::Config::DEFAULT); + let pattern = Pattern::new( + &query, + CaseMatching::Ignore, + Normalization::Smart, + AtomKind::Fuzzy, + ); + + let mut buf = Vec::new(); + options + .iter() + .map(|r| { + ( + pattern.score( + nucleo_matcher::Utf32Str::new( + to_path(r).as_str(), + &mut buf, + ), + &mut matcher, + ), + r, + ) + }) + .filter_map(|(score, reading)| score.zip(Some(reading))) + .sorted_unstable_by_key(|(score, _)| *score) + .rev() + .map(|(_, reading)| reading.clone()) + .collect() +} diff --git a/crates/text-widget/src/resolve/fetch.rs b/crates/text-widget/src/resolve/fetch.rs new file mode 100644 index 00000000..f3a2cfc4 --- /dev/null +++ b/crates/text-widget/src/resolve/fetch.rs @@ -0,0 +1,32 @@ +use color_eyre::eyre::Context; +use data_server::api::subscriber::ReconnectingSubscribedClient; +use data_server::api::subscriber::SubMessage; +use protocol::IsSameAs; +use std::net::SocketAddr; + +use data_store::api::Client; + +pub(super) async fn datalist_on_store( + store: SocketAddr, + name: String, +) -> color_eyre::Result> { + Client::connect(store, name) + .await + .wrap_err("failed to connect to data store to list data")? + .list_data() + .await + .wrap_err("connected bu list data call failed") +} + +pub(super) async fn datalist_from_updates( + client: &mut ReconnectingSubscribedClient, + list: &mut Vec, +) { + loop { + if let SubMessage::Reading(new) = client.next().await { + if !list.iter().any(|in_list| new.is_same_as(in_list)) { + list.push(new); + } + } + } +} diff --git a/crates/ui/.gitignore b/crates/ui/.gitignore new file mode 100644 index 00000000..f3508536 --- /dev/null +++ b/crates/ui/.gitignore @@ -0,0 +1,2 @@ +/target +log.txt diff --git a/crates/ui/Cargo.lock b/crates/ui/Cargo.lock new file mode 100644 index 00000000..32de1ed9 --- /dev/null +++ b/crates/ui/Cargo.lock @@ -0,0 +1,1717 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 3 + +[[package]] +name = "addr2line" +version = "0.21.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8a30b2e23b9e17a9f90641c7ab1549cd9b44f296d3ccbf309d2863cfe398a0cb" +dependencies = [ + "gimli", +] + +[[package]] +name = "adler" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe" + +[[package]] +name = "ahash" +version = "0.8.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e89da841a80418a9b391ebaea17f5c112ffaaa96f621d2c285b5174da76b9011" +dependencies = [ + "cfg-if", + "once_cell", + "version_check", + "zerocopy", +] + +[[package]] +name = "aho-corasick" +version = "1.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e60d3430d3a69478ad0993f19238d2df97c507009a52b3c10addcd7f6bcb916" +dependencies = [ + "memchr", +] + +[[package]] +name = "allocator-api2" +version = "0.2.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c6cb57a04249c6480766f7f7cef5467412af1490f8d1e243141daddada3264f" + +[[package]] +name = "atomic-polyfill" +version = "1.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8cf2bce30dfe09ef0bfaef228b9d414faaf7e563035494d7fe092dba54b300f4" +dependencies = [ + "critical-section", +] + +[[package]] +name = "autocfg" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0c4b4d0bd25bd0b74681c0ad21497610ce1b7c91b1022cd21c80c6fbdd9476b0" + +[[package]] +name = "backtrace" +version = "0.3.71" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "26b05800d2e817c8b3b4b54abd461726265fa9789ae34330622f2db9ee696f9d" +dependencies = [ + "addr2line", + "cc", + "cfg-if", + "libc", + "miniz_oxide", + "object", + "rustc-demangle", +] + +[[package]] +name = "bare-metal" +version = "0.2.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5deb64efa5bd81e31fcd1938615a6d98c82eafcbcd787162b6f63b91d6bac5b3" +dependencies = [ + "rustc_version 0.2.3", +] + +[[package]] +name = "bit_field" +version = "0.10.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dc827186963e592360843fb5ba4b973e145841266c1357f7180c43526f2e5b61" + +[[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.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cf4b9d6a944f767f8e5e0db018570623c85f3d925ac718db4e06d0187adb21c1" + +[[package]] +name = "bosch-bme680" +version = "1.0.2" +dependencies = [ + "bitfield 0.14.0", + "defmt", + "embedded-hal 1.0.0", + "embedded-hal-async", + "postcard", + "serde", +] + +[[package]] +name = "bxcan" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "40ac3d0c0a542d0ab5521211f873f62706a7136df415676f676d347e5a41dd80" +dependencies = [ + "bitflags 1.3.2", + "embedded-hal 0.2.7", + "nb 1.1.0", + "vcell", +] + +[[package]] +name = "byteorder" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" + +[[package]] +name = "cassowary" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "df8670b8c7b9dae1793364eafadf7239c40d669904660c5960d74cfd80b46a53" + +[[package]] +name = "castaway" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8a17ed5635fc8536268e5d4de1e22e81ac34419e5f052d4d51f4e01dcc263fcc" +dependencies = [ + "rustversion", +] + +[[package]] +name = "cc" +version = "1.0.97" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "099a5357d84c4c61eb35fc8eafa9a79a902c2f76911e5747ced4e032edd8d9b4" + +[[package]] +name = "cfg-if" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" + +[[package]] +name = "cobs" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "67ba02a97a2bd10f4b59b25c7973101c79642302776489e030cd13cdab09ed15" + +[[package]] +name = "color-eyre" +version = "0.6.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "55146f5e46f237f7423d74111267d4597b59b0dad0ffaf7303bce9945d843ad5" +dependencies = [ + "backtrace", + "color-spantrace", + "eyre", + "indenter", + "once_cell", + "owo-colors", + "tracing-error", +] + +[[package]] +name = "color-spantrace" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cd6be1b2a7e382e2b98b43b2adcca6bb0e465af0bdd38123873ae61eb17a72c2" +dependencies = [ + "once_cell", + "owo-colors", + "tracing-core", + "tracing-error", +] + +[[package]] +name = "compact_str" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f86b9c4c00838774a6d902ef931eff7470720c51d90c2e32cfe15dc304737b3f" +dependencies = [ + "castaway", + "cfg-if", + "itoa", + "ryu", + "static_assertions", +] + +[[package]] +name = "const_format" +version = "0.2.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e3a214c7af3d04997541b18d432afaff4c455e79e2029079647e72fc2bd27673" +dependencies = [ + "const_format_proc_macros", +] + +[[package]] +name = "const_format_proc_macros" +version = "0.2.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c7f6ff08fd20f4f299298a28e2dfa8a8ba1036e6cd2460ac1de7b425d76f2500" +dependencies = [ + "proc-macro2", + "quote", + "unicode-xid", +] + +[[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.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2722f5b7d6ea8583cffa4d247044e280ccbb9fe501bed56552e2ba48b02d5f3d" +dependencies = [ + "cortex-m-rt-macros", +] + +[[package]] +name = "cortex-m-rt-macros" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f0f6f3e36f203cfedbc78b357fb28730aa2c6dc1ab060ee5c2405e843988d3c7" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "crc" +version = "3.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "69e6e4d7b33a94f0991c26729976b10ebde1d34c3ee82408fb536164fa10d636" +dependencies = [ + "crc-catalog", +] + +[[package]] +name = "crc-catalog" +version = "2.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "19d374276b40fb8bbdee95aef7c7fa6b5316ec764510eb64b8dd0e2ed0d7e7f5" + +[[package]] +name = "critical-section" +version = "1.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7059fff8937831a9ae6f0fe4d658ffabf58f2ca96aa9dec1c889f936f705f216" + +[[package]] +name = "crossterm" +version = "0.27.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f476fe445d41c9e991fd07515a6f463074b782242ccf4a5b7b1d1012e70824df" +dependencies = [ + "bitflags 2.5.0", + "crossterm_winapi", + "libc", + "mio", + "parking_lot", + "signal-hook", + "signal-hook-mio", + "winapi", +] + +[[package]] +name = "crossterm_winapi" +version = "0.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "acdd7c62a3665c7f6830a51635d9ac9b23ed385797f70a83bb8bafe9c572ab2b" +dependencies = [ + "winapi", +] + +[[package]] +name = "defmt" +version = "0.3.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3939552907426de152b3c2c6f51ed53f98f448babd26f28694c95f5906194595" +dependencies = [ + "bitflags 1.3.2", + "defmt-macros", +] + +[[package]] +name = "defmt-macros" +version = "0.3.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "18bdc7a7b92ac413e19e95240e75d3a73a8d8e78aa24a594c22cbb4d44b4bbda" +dependencies = [ + "defmt-parser", + "proc-macro-error", + "proc-macro2", + "quote", + "syn 2.0.60", +] + +[[package]] +name = "defmt-parser" +version = "0.3.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ff4a5fefe330e8d7f31b16a318f9ce81000d8e35e69b93eae154d16d2278f70f" +dependencies = [ + "thiserror", +] + +[[package]] +name = "document-features" +version = "0.2.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ef5282ad69563b5fc40319526ba27e0e7363d552a896f0297d54f767717f9b95" +dependencies = [ + "litrs", +] + +[[package]] +name = "either" +version = "1.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a47c1c47d2f5964e29c61246e81db715514cd532db6b5116a25ea3c03d6780a2" + +[[package]] +name = "embassy-embedded-hal" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eca4a9380d03e61063067b8239f67d2fa9f108ede7c46b4273804f6b79e59a1d" +dependencies = [ + "embassy-futures", + "embassy-sync", + "embassy-time", + "embedded-hal 0.2.7", + "embedded-hal 1.0.0", + "embedded-hal-async", + "embedded-storage", + "embedded-storage-async", + "nb 1.1.0", +] + +[[package]] +name = "embassy-futures" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1f878075b9794c1e4ac788c95b728f26aa6366d32eeb10c7051389f898f7d067" + +[[package]] +name = "embassy-hal-internal" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a0ec47cf8bab914018d4bd2b4f0aaeb46e4f52ab1e7985df88aeef2c6eda5aed" +dependencies = [ + "cortex-m", + "critical-section", + "num-traits", +] + +[[package]] +name = "embassy-net-driver" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "524eb3c489760508f71360112bca70f6e53173e6fe48fc5f0efd0f5ab217751d" + +[[package]] +name = "embassy-stm32" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "32bc0257b5ade13a1b93e8b9949268f44d57e8ce03e599ef1c5a62024a0fbff9" +dependencies = [ + "bit_field", + "bxcan", + "cfg-if", + "cortex-m", + "cortex-m-rt", + "critical-section", + "document-features", + "embassy-embedded-hal", + "embassy-futures", + "embassy-hal-internal", + "embassy-net-driver", + "embassy-sync", + "embassy-usb-driver", + "embedded-hal 0.2.7", + "embedded-hal 1.0.0", + "embedded-hal-async", + "embedded-hal-nb", + "embedded-io", + "embedded-io-async", + "embedded-storage", + "embedded-storage-async", + "futures", + "nb 1.1.0", + "proc-macro2", + "quote", + "rand_core", + "sdio-host", + "stm32-fmc", + "stm32-metapac", + "vcell", +] + +[[package]] +name = "embassy-sync" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dd938f25c0798db4280fcd8026bf4c2f48789aebf8f77b6e5cf8a7693ba114ec" +dependencies = [ + "cfg-if", + "critical-section", + "embedded-io-async", + "futures-util", + "heapless 0.8.0", +] + +[[package]] +name = "embassy-time" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a9c844070d9f80dc66ee739299183312baee2e1cdeb6e90b4ea2af44f4676da5" +dependencies = [ + "cfg-if", + "critical-section", + "document-features", + "embassy-time-driver", + "embassy-time-queue-driver", + "embedded-hal 0.2.7", + "embedded-hal 1.0.0", + "embedded-hal-async", + "futures-util", + "heapless 0.8.0", +] + +[[package]] +name = "embassy-time-driver" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6e0c214077aaa9206958b16411c157961fb7990d4ea628120a78d1a5a28aed24" +dependencies = [ + "document-features", +] + +[[package]] +name = "embassy-time-queue-driver" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f1177859559ebf42cd24ae7ba8fe6ee707489b01d0bf471f8827b7b12dcb0bc0" + +[[package]] +name = "embassy-usb-driver" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4fc247028eae04174b6635104a35b1ed336aabef4654f5e87a8f32327d231970" + +[[package]] +name = "embedded-hal" +version = "0.2.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "35949884794ad573cf46071e41c9b60efb0cb311e3ca01f7af807af1debc66ff" +dependencies = [ + "nb 0.1.3", + "void", +] + +[[package]] +name = "embedded-hal" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "361a90feb7004eca4019fb28352a9465666b24f840f5c3cddf0ff13920590b89" +dependencies = [ + "defmt", +] + +[[package]] +name = "embedded-hal-async" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0c4c685bbef7fe13c3c6dd4da26841ed3980ef33e841cddfa15ce8a8fb3f1884" +dependencies = [ + "defmt", + "embedded-hal 1.0.0", +] + +[[package]] +name = "embedded-hal-nb" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fba4268c14288c828995299e59b12babdbe170f6c6d73731af1b4648142e8605" +dependencies = [ + "embedded-hal 1.0.0", + "nb 1.1.0", +] + +[[package]] +name = "embedded-io" +version = "0.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "edd0f118536f44f5ccd48bcb8b111bdc3de888b58c74639dfb034a357d0f206d" +dependencies = [ + "defmt", +] + +[[package]] +name = "embedded-io-async" +version = "0.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3ff09972d4073aa8c299395be75161d582e7629cd663171d62af73c8d50dba3f" +dependencies = [ + "defmt", + "embedded-io", +] + +[[package]] +name = "embedded-storage" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a21dea9854beb860f3062d10228ce9b976da520a73474aed3171ec276bc0c032" + +[[package]] +name = "embedded-storage-async" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1763775e2323b7d5f0aa6090657f5e21cfa02ede71f5dc40eead06d64dcd15cc" +dependencies = [ + "embedded-storage", +] + +[[package]] +name = "eyre" +version = "0.6.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7cd915d99f24784cdc19fd37ef22b97e3ff0ae756c7e492e9fbfe897d61e2aec" +dependencies = [ + "indenter", + "once_cell", +] + +[[package]] +name = "futures" +version = "0.3.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "645c6916888f6cb6350d2550b80fb63e734897a8498abe35cfb732b6487804b0" +dependencies = [ + "futures-channel", + "futures-core", + "futures-io", + "futures-sink", + "futures-task", + "futures-util", +] + +[[package]] +name = "futures-channel" +version = "0.3.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eac8f7d7865dcb88bd4373ab671c8cf4508703796caa2b1985a9ca867b3fcb78" +dependencies = [ + "futures-core", + "futures-sink", +] + +[[package]] +name = "futures-core" +version = "0.3.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dfc6580bb841c5a68e9ef15c77ccc837b40a7504914d52e47b8b0e9bbda25a1d" + +[[package]] +name = "futures-io" +version = "0.3.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a44623e20b9681a318efdd71c299b6b222ed6f231972bfe2f224ebad6311f0c1" + +[[package]] +name = "futures-macro" +version = "0.3.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "87750cf4b7a4c0625b1529e4c543c2182106e4dedc60a2a6455e00d212c489ac" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.60", +] + +[[package]] +name = "futures-sink" +version = "0.3.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9fb8e00e87438d937621c1c6269e53f536c14d3fbd6a042bb24879e57d474fb5" + +[[package]] +name = "futures-task" +version = "0.3.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "38d84fa142264698cdce1a9f9172cf383a0c82de1bddcf3092901442c4097004" + +[[package]] +name = "futures-util" +version = "0.3.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3d6401deb83407ab3da39eba7e33987a73c3df0c82b4bb5813ee871c19c41d48" +dependencies = [ + "futures-core", + "futures-macro", + "futures-sink", + "futures-task", + "pin-project-lite", + "pin-utils", +] + +[[package]] +name = "gimli" +version = "0.28.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4271d37baee1b8c7e4b708028c57d816cf9d2434acb33a549475f78c181f6253" + +[[package]] +name = "hash32" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b0c35f58762feb77d74ebe43bdbc3210f09be9fe6742234d573bacc26ed92b67" +dependencies = [ + "byteorder", +] + +[[package]] +name = "hash32" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "47d60b12902ba28e2730cd37e95b8c9223af2808df9e902d4df49588d1470606" +dependencies = [ + "byteorder", +] + +[[package]] +name = "hashbrown" +version = "0.14.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e5274423e17b7c9fc20b6e7e208532f9b19825d82dfd615708b70edd83df41f1" +dependencies = [ + "ahash", + "allocator-api2", +] + +[[package]] +name = "heapless" +version = "0.7.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cdc6457c0eb62c71aac4bc17216026d8410337c4126773b9c5daba343f17964f" +dependencies = [ + "atomic-polyfill", + "hash32 0.2.1", + "rustc_version 0.4.0", + "serde", + "spin", + "stable_deref_trait", +] + +[[package]] +name = "heapless" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0bfb9eb618601c89945a70e254898da93b13be0388091d42117462b265bb3fad" +dependencies = [ + "hash32 0.3.1", + "serde", + "stable_deref_trait", +] + +[[package]] +name = "heck" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "95505c38b4572b2d910cecb0281560f54b440a19336cbbcb27bf6ce6adc6f5a8" + +[[package]] +name = "histogram" +version = "0.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5bd81cb9a629d0a868f2092937332fca5fd985971d2155bf6fcc225ef8a6be2c" +dependencies = [ + "thiserror", +] + +[[package]] +name = "indenter" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ce23b50ad8242c51a442f3ff322d56b02f08852c77e4c0b4d3fd684abc89c683" + +[[package]] +name = "indoc" +version = "2.0.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b248f5224d1d606005e02c97f5aa4e88eeb230488bcc03bc9ca4d7991399f2b5" + +[[package]] +name = "itertools" +version = "0.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ba291022dbbd398a455acf126c1e341954079855bc60dfdda641363bd6922569" +dependencies = [ + "either", +] + +[[package]] +name = "itoa" +version = "1.0.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "49f1f14873335454500d59611f1cf4a4b0f786f9ac11f4312a78e4cf2566695b" + +[[package]] +name = "lazy_static" +version = "1.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" + +[[package]] +name = "libc" +version = "0.2.154" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ae743338b92ff9146ce83992f766a31066a91a8c84a45e0e9f21e7cf6de6d346" + +[[package]] +name = "litrs" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b4ce301924b7887e9d637144fdade93f9dfff9b60981d4ac161db09720d39aa5" + +[[package]] +name = "lock_api" +version = "0.4.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "07af8b9cdd281b7915f413fa73f29ebd5d55d0d3f0155584dade1ff18cea1b17" +dependencies = [ + "autocfg", + "scopeguard", +] + +[[package]] +name = "log" +version = "0.4.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "90ed8c1e510134f979dbc4f070f87d4313098b704861a105fe34231c70a3901c" + +[[package]] +name = "lru" +version = "0.12.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d3262e75e648fce39813cb56ac41f3c3e3f65217ebf3844d818d1f9398cfb0dc" +dependencies = [ + "hashbrown", +] + +[[package]] +name = "matchers" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8263075bb86c5a1b1427b5ae862e8889656f126e9f77c484496e8b47cf5c5558" +dependencies = [ + "regex-automata 0.1.10", +] + +[[package]] +name = "max44009" +version = "0.2.0" +source = "git+https://github.com/dvdsk/max44009-rs#207e39cec2dcc4d254b46fada1954d6f637d4a5d" +dependencies = [ + "defmt", + "embedded-hal-async", + "postcard", + "serde", +] + +[[package]] +name = "memchr" +version = "2.7.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6c8640c5d730cb13ebd907d8d04b52f55ac9a2eec55b440c8892f40d56c76c1d" + +[[package]] +name = "mhzx" +version = "0.3.0" +dependencies = [ + "defmt", + "embedded-io-async", + "heapless 0.8.0", + "postcard", + "serde", +] + +[[package]] +name = "miniz_oxide" +version = "0.7.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9d811f3e15f28568be3407c8e7fdb6514c1cda3cb30683f15b6a1a1dc4ea14a7" +dependencies = [ + "adler", +] + +[[package]] +name = "mio" +version = "0.8.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a4a650543ca06a924e8b371db273b2756685faae30f8487da1b56505a8f78b0c" +dependencies = [ + "libc", + "log", + "wasi", + "windows-sys", +] + +[[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 = "nu-ansi-term" +version = "0.46.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "77a8165726e8236064dbb45459242600304b42a5ea24ee2948e18e023bf7ba84" +dependencies = [ + "overload", + "winapi", +] + +[[package]] +name = "num-traits" +version = "0.2.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841" +dependencies = [ + "autocfg", +] + +[[package]] +name = "object" +version = "0.32.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a6a622008b6e321afc04970976f62ee297fdbaa6f95318ca343e3eebb9648441" +dependencies = [ + "memchr", +] + +[[package]] +name = "once_cell" +version = "1.19.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3fdb12b2476b595f9358c5161aa467c2438859caa136dec86c26fdd2efe17b92" + +[[package]] +name = "overload" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b15813163c1d831bf4a13c3610c05c0d03b39feb07f7e09fa234dac9b15aaf39" + +[[package]] +name = "owo-colors" +version = "3.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c1b04fb49957986fdce4d6ee7a65027d55d4b6d2265e5848bbb507b58ccfdb6f" + +[[package]] +name = "parking_lot" +version = "0.12.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7e4af0ca4f6caed20e900d564c242b8e5d4903fdacf31d3daf527b66fe6f42fb" +dependencies = [ + "lock_api", + "parking_lot_core", +] + +[[package]] +name = "parking_lot_core" +version = "0.9.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e401f977ab385c9e4e3ab30627d6f26d00e2c73eef317493c4ec6d468726cf8" +dependencies = [ + "cfg-if", + "libc", + "redox_syscall", + "smallvec", + "windows-targets 0.52.5", +] + +[[package]] +name = "paste" +version = "1.0.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "de3145af08024dea9fa9914f381a17b8fc6034dfb00f3a84013f7ff43f29ed4c" + +[[package]] +name = "pin-project-lite" +version = "0.2.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bda66fc9667c18cb2758a2ac84d1167245054bcf85d5d1aaa6923f45801bdd02" + +[[package]] +name = "pin-utils" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" + +[[package]] +name = "postcard" +version = "1.0.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a55c51ee6c0db07e68448e336cf8ea4131a620edefebf9893e759b2d793420f8" +dependencies = [ + "cobs", + "const_format", + "heapless 0.7.17", + "postcard-derive", + "serde", +] + +[[package]] +name = "postcard-derive" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fc4b01218787dd4420daf63875163a787a78294ad48a24e9f6fa8c6507759a79" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "proc-macro-error" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "da25490ff9892aab3fcf7c36f08cfb902dd3e71ca0f9f9517bea02a73a5ce38c" +dependencies = [ + "proc-macro-error-attr", + "proc-macro2", + "quote", + "syn 1.0.109", + "version_check", +] + +[[package]] +name = "proc-macro-error-attr" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a1be40180e52ecc98ad80b184934baf3d0d29f979574e439af5a55274b35f869" +dependencies = [ + "proc-macro2", + "quote", + "version_check", +] + +[[package]] +name = "proc-macro2" +version = "1.0.81" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3d1597b0c024618f09a9c3b8655b7e430397a36d23fdafec26d6965e9eec3eba" +dependencies = [ + "unicode-ident", +] + +[[package]] +name = "protocol" +version = "0.1.0" +dependencies = [ + "bosch-bme680", + "defmt", + "embassy-embedded-hal", + "embassy-stm32", + "heapless 0.8.0", + "max44009", + "mhzx", + "postcard", + "serde", + "sht31", + "sps30-async", + "strum", +] + +[[package]] +name = "quote" +version = "1.0.36" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0fa76aaf39101c457836aec0ce2316dbdc3ab723cdda1c6bd4e6ad4208acaca7" +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 = "ratatui" +version = "0.26.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a564a852040e82671dc50a37d88f3aa83bbc690dfc6844cfe7a2591620206a80" +dependencies = [ + "bitflags 2.5.0", + "cassowary", + "compact_str", + "crossterm", + "indoc", + "itertools", + "lru", + "paste", + "stability", + "strum", + "unicode-segmentation", + "unicode-width", +] + +[[package]] +name = "redox_syscall" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "469052894dcb553421e483e4209ee581a45100d31b4018de03e5a7ad86374a7e" +dependencies = [ + "bitflags 2.5.0", +] + +[[package]] +name = "regex" +version = "1.10.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c117dbdfde9c8308975b6a18d71f3f385c89461f7b3fb054288ecf2a2058ba4c" +dependencies = [ + "aho-corasick", + "memchr", + "regex-automata 0.4.6", + "regex-syntax 0.8.3", +] + +[[package]] +name = "regex-automata" +version = "0.1.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6c230d73fb8d8c1b9c0b3135c5142a8acee3a0558fb8db5cf1cb65f8d7862132" +dependencies = [ + "regex-syntax 0.6.29", +] + +[[package]] +name = "regex-automata" +version = "0.4.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "86b83b8b9847f9bf95ef68afb0b8e6cdb80f498442f5179a29fad448fcc1eaea" +dependencies = [ + "aho-corasick", + "memchr", + "regex-syntax 0.8.3", +] + +[[package]] +name = "regex-syntax" +version = "0.6.29" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f162c6dd7b008981e4d40210aca20b4bd0f9b60ca9271061b07f78537722f2e1" + +[[package]] +name = "regex-syntax" +version = "0.8.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "adad44e29e4c806119491a7f06f03de4d1af22c3a680dd47f1e6e179439d1f56" + +[[package]] +name = "rustc-demangle" +version = "0.1.24" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "719b953e2095829ee67db738b3bfa9fa368c94900df327b3f07fe6e794d2fe1f" + +[[package]] +name = "rustc_version" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "138e3e0acb6c9fb258b19b67cb8abd63c00679d2851805ea151465464fe9030a" +dependencies = [ + "semver 0.9.0", +] + +[[package]] +name = "rustc_version" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bfa0f585226d2e68097d4f95d113b15b83a82e819ab25717ec0590d9584ef366" +dependencies = [ + "semver 1.0.22", +] + +[[package]] +name = "rustversion" +version = "1.0.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "80af6f9131f277a45a3fba6ce8e2258037bb0477a67e610d3c1fe046ab31de47" + +[[package]] +name = "ryu" +version = "1.0.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e86697c916019a8588c99b5fac3cead74ec0b4b819707a682fd4d23fa0ce1ba1" + +[[package]] +name = "scopeguard" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" + +[[package]] +name = "sdio-host" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f93c025f9cfe4c388c328ece47d11a54a823da3b5ad0370b22d95ad47137f85a" + +[[package]] +name = "semver" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1d7eb9ef2c18661902cc47e535f9bc51b78acd254da71d375c2f6720d9a40403" +dependencies = [ + "semver-parser", +] + +[[package]] +name = "semver" +version = "1.0.22" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "92d43fe69e652f3df9bdc2b85b2854a0825b86e4fb76bc44d945137d053639ca" + +[[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.200" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ddc6f9cc94d67c0e21aaf7eda3a010fd3af78ebf6e096aa6e2e13c79749cce4f" +dependencies = [ + "serde_derive", +] + +[[package]] +name = "serde_derive" +version = "1.0.200" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "856f046b9400cee3c8c94ed572ecdb752444c24528c035cd35882aad6f492bcb" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.60", +] + +[[package]] +name = "server" +version = "0.1.0" +dependencies = [ + "color-eyre", + "crossterm", + "histogram", + "protocol", + "ratatui", + "tracing", + "tracing-error", + "tracing-subscriber", +] + +[[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 = "sht31" +version = "0.3.1" +source = "git+https://github.com/dvdsk/SHT31-rs#a7b6bd94fb137e16bf326eff5fb591624369a2cf" +dependencies = [ + "crc", + "defmt", + "embedded-hal-async", + "postcard", + "serde", +] + +[[package]] +name = "signal-hook" +version = "0.3.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8621587d4798caf8eb44879d42e56b9a93ea5dcd315a6487c357130095b62801" +dependencies = [ + "libc", + "signal-hook-registry", +] + +[[package]] +name = "signal-hook-mio" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "29ad2e15f37ec9a6cc544097b78a1ec90001e9f71b81338ca39f430adaca99af" +dependencies = [ + "libc", + "mio", + "signal-hook", +] + +[[package]] +name = "signal-hook-registry" +version = "1.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a9e9e0b4211b72e7b8b6e85c807d36c212bdb33ea8587f7569562a84df5465b1" +dependencies = [ + "libc", +] + +[[package]] +name = "smallvec" +version = "1.13.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3c5e1a9a646d36c3599cd173a41282daf47c44583ad367b8e6837255952e5c67" + +[[package]] +name = "spin" +version = "0.9.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6980e8d7511241f8acf4aebddbb1ff938df5eebe98691418c4468d0b72a96a67" +dependencies = [ + "lock_api", +] + +[[package]] +name = "sps30-async" +version = "0.2.0" +dependencies = [ + "defmt", + "embedded-hal-async", + "embedded-io-async", + "heapless 0.8.0", + "postcard", + "serde", +] + +[[package]] +name = "stability" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2ff9eaf853dec4c8802325d8b6d3dffa86cc707fd7a1a4cdbf416e13b061787a" +dependencies = [ + "quote", + "syn 2.0.60", +] + +[[package]] +name = "stable_deref_trait" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a8f112729512f8e442d81f95a8a7ddf2b7c6b8a1a6f509a95864142b30cab2d3" + +[[package]] +name = "static_assertions" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f" + +[[package]] +name = "stm32-fmc" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "830ed60f33e6194ecb377f5d6ab765dc0e37e7b65e765f1fa87df13336658d63" +dependencies = [ + "embedded-hal 0.2.7", +] + +[[package]] +name = "stm32-metapac" +version = "15.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "deabea56a8821dcea05d0109f3ab3135f31eb572444e5da203d06149c594c8c6" +dependencies = [ + "cortex-m", + "cortex-m-rt", +] + +[[package]] +name = "strum" +version = "0.26.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5d8cec3501a5194c432b2b7976db6b7d10ec95c253208b45f83f7136aa985e29" +dependencies = [ + "strum_macros", +] + +[[package]] +name = "strum_macros" +version = "0.26.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c6cf59daf282c0a494ba14fd21610a0325f9f90ec9d1231dea26bcb1d696c946" +dependencies = [ + "heck", + "proc-macro2", + "quote", + "rustversion", + "syn 2.0.60", +] + +[[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.60" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "909518bc7b1c9b779f1bbf07f2929d35af9f0f37e47c6e9ef7f9dddc1e1821f3" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[package]] +name = "thiserror" +version = "1.0.59" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f0126ad08bff79f29fc3ae6a55cc72352056dfff61e3ff8bb7129476d44b23aa" +dependencies = [ + "thiserror-impl", +] + +[[package]] +name = "thiserror-impl" +version = "1.0.59" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d1cd413b5d558b4c5bf3680e324a6fa5014e7b7c067a51e69dbdf47eb7148b66" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.60", +] + +[[package]] +name = "thread_local" +version = "1.1.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8b9ef9bad013ada3808854ceac7b46812a6465ba368859a37e2100283d2d719c" +dependencies = [ + "cfg-if", + "once_cell", +] + +[[package]] +name = "tracing" +version = "0.1.40" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c3523ab5a71916ccf420eebdf5521fcef02141234bbc0b8a49f2fdc4544364ef" +dependencies = [ + "pin-project-lite", + "tracing-attributes", + "tracing-core", +] + +[[package]] +name = "tracing-attributes" +version = "0.1.27" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "34704c8d6ebcbc939824180af020566b01a7c01f80641264eba0999f6c2b6be7" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.60", +] + +[[package]] +name = "tracing-core" +version = "0.1.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c06d3da6113f116aaee68e4d601191614c9053067f9ab7f6edbcb161237daa54" +dependencies = [ + "once_cell", + "valuable", +] + +[[package]] +name = "tracing-error" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d686ec1c0f384b1277f097b2f279a2ecc11afe8c133c1aabf036a27cb4cd206e" +dependencies = [ + "tracing", + "tracing-subscriber", +] + +[[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.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ad0f048c97dbd9faa9b7df56362b8ebcaa52adb06b498c050d2f4e32f90a7a8b" +dependencies = [ + "matchers", + "nu-ansi-term", + "once_cell", + "regex", + "sharded-slab", + "smallvec", + "thread_local", + "tracing", + "tracing-core", + "tracing-log", +] + +[[package]] +name = "unicode-ident" +version = "1.0.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" + +[[package]] +name = "unicode-segmentation" +version = "1.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d4c87d22b6e3f4a18d4d40ef354e97c90fcb14dd91d7dc0aa9d8a1172ebf7202" + +[[package]] +name = "unicode-width" +version = "0.1.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "68f5e5f3158ecfd4b8ff6fe086db7c8467a2dfdac97fe420f2b7c4aa97af66d6" + +[[package]] +name = "unicode-xid" +version = "0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f962df74c8c05a667b5ee8bcf162993134c104e96440b663c8daa176dc772d8c" + +[[package]] +name = "valuable" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "830b7e5d4d90034032940e4ace0d9a9a057e7a45cd94e6c007832e39edb82f6d" + +[[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.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" + +[[package]] +name = "void" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6a02e4885ed3bc0f2de90ea6dd45ebcbb66dacffe03547fadbb0eeae2770887d" + +[[package]] +name = "volatile-register" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "de437e2a6208b014ab52972a27e59b33fa2920d3e00fe05026167a1c509d19cc" +dependencies = [ + "vcell", +] + +[[package]] +name = "wasi" +version = "0.11.0+wasi-snapshot-preview1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" + +[[package]] +name = "winapi" +version = "0.3.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419" +dependencies = [ + "winapi-i686-pc-windows-gnu", + "winapi-x86_64-pc-windows-gnu", +] + +[[package]] +name = "winapi-i686-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" + +[[package]] +name = "winapi-x86_64-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" + +[[package]] +name = "windows-sys" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "677d2418bec65e3338edb076e806bc1ec15693c5d0104683f2efe857f61056a9" +dependencies = [ + "windows-targets 0.48.5", +] + +[[package]] +name = "windows-targets" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9a2fa6e2155d7247be68c096456083145c183cbbbc2764150dda45a87197940c" +dependencies = [ + "windows_aarch64_gnullvm 0.48.5", + "windows_aarch64_msvc 0.48.5", + "windows_i686_gnu 0.48.5", + "windows_i686_msvc 0.48.5", + "windows_x86_64_gnu 0.48.5", + "windows_x86_64_gnullvm 0.48.5", + "windows_x86_64_msvc 0.48.5", +] + +[[package]] +name = "windows-targets" +version = "0.52.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6f0713a46559409d202e70e28227288446bf7841d3211583a4b53e3f6d96e7eb" +dependencies = [ + "windows_aarch64_gnullvm 0.52.5", + "windows_aarch64_msvc 0.52.5", + "windows_i686_gnu 0.52.5", + "windows_i686_gnullvm", + "windows_i686_msvc 0.52.5", + "windows_x86_64_gnu 0.52.5", + "windows_x86_64_gnullvm 0.52.5", + "windows_x86_64_msvc 0.52.5", +] + +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8" + +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.52.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7088eed71e8b8dda258ecc8bac5fb1153c5cffaf2578fc8ff5d61e23578d3263" + +[[package]] +name = "windows_aarch64_msvc" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc" + +[[package]] +name = "windows_aarch64_msvc" +version = "0.52.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9985fd1504e250c615ca5f281c3f7a6da76213ebd5ccc9561496568a2752afb6" + +[[package]] +name = "windows_i686_gnu" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743e" + +[[package]] +name = "windows_i686_gnu" +version = "0.52.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "88ba073cf16d5372720ec942a8ccbf61626074c6d4dd2e745299726ce8b89670" + +[[package]] +name = "windows_i686_gnullvm" +version = "0.52.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "87f4261229030a858f36b459e748ae97545d6f1ec60e5e0d6a3d32e0dc232ee9" + +[[package]] +name = "windows_i686_msvc" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406" + +[[package]] +name = "windows_i686_msvc" +version = "0.52.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "db3c2bf3d13d5b658be73463284eaf12830ac9a26a90c717b7f771dfe97487bf" + +[[package]] +name = "windows_x86_64_gnu" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "53d40abd2583d23e4718fddf1ebec84dbff8381c07cae67ff7768bbf19c6718e" + +[[package]] +name = "windows_x86_64_gnu" +version = "0.52.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4e4246f76bdeff09eb48875a0fd3e2af6aada79d409d33011886d3e1581517d9" + +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc" + +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.52.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "852298e482cd67c356ddd9570386e2862b5673c85bd5f88df9ab6802b334c596" + +[[package]] +name = "windows_x86_64_msvc" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538" + +[[package]] +name = "windows_x86_64_msvc" +version = "0.52.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bec47e5bfd1bff0eeaf6d8b485cc1074891a197ab4225d504cb7a1ab88b02bf0" + +[[package]] +name = "zerocopy" +version = "0.7.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "74d4d3961e53fa4c9a25a8637fc2bfaf2595b3d3ae34875568a5cf64787716be" +dependencies = [ + "zerocopy-derive", +] + +[[package]] +name = "zerocopy-derive" +version = "0.7.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9ce1b18ccd8e73a9321186f97e46f9f04b778851177567b1975109d26a08d2a6" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.60", +] diff --git a/crates/ui/Cargo.toml b/crates/ui/Cargo.toml new file mode 100644 index 00000000..8efa5bb2 --- /dev/null +++ b/crates/ui/Cargo.toml @@ -0,0 +1,35 @@ +[package] +name = "ui" +version = "0.1.0" +edition.workspace = true +license.workspace = true +authors.workspace = true +description = "A tui app for viewing data from and controlling the home automation system" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] +color-eyre = { workspace = true } +crossterm = "0.28" +hdrhistogram = "7.5" +ratatui = "0.29" +tui-tree-widget = { version = "0.23.0", git = "https://github.com/dvdsk/tui-rs-tree-widget" } +clap = { workspace = true } + +tokio = { workspace = true, features = ["macros"] } +logger = { workspace = true } +tracing.workspace = true +tracing-error = { workspace = true } +tracing-subscriber.workspace = true + +protocol = { workspace = true, features = ["alloc"] } +data-server = { workspace = true } +data-store = { workspace = true } +log-store = { workspace = true, features = ["api"] } +jiff = { workspace = true } +thiserror.workspace = true +itertools.workspace = true +gethostname.workspace = true +strip-ansi-escapes = "0.2.0" +indextree = "4.7.2" +derivative = "2.2.0" diff --git a/crates/ui/examples/chart_gaps.rs b/crates/ui/examples/chart_gaps.rs new file mode 100644 index 00000000..b7b14ffa --- /dev/null +++ b/crates/ui/examples/chart_gaps.rs @@ -0,0 +1,64 @@ +use std::io::stdout; + +use crossterm::terminal::{ + disable_raw_mode, enable_raw_mode, EnterAlternateScreen, + LeaveAlternateScreen, +}; +use crossterm::{event, ExecutableCommand}; +use protocol::reading::FloatLabelFormatter; +use ratatui::backend::CrosstermBackend; +use ratatui::{Frame, Terminal}; +use ui::tui::readings::render::chart; +use ui::tui::readings::sensor_info::ChartParts; +use ui::tui::readings::UiState; + +fn data_with_gap(buffer: &mut Vec<(f64, f64)>) -> ChartParts<'_> { + buffer.extend((0..10).into_iter().map(|i| (i as f64, 2.0))); + buffer.extend((30..35).into_iter().map(|i| (i as f64, 5.0))); + buffer.extend((50..55).into_iter().map(|i| (i as f64, 1.0))); + + let info = protocol::reading::Info { + val: 0.0, + device: protocol::Device::SmallBedroom( + protocol::small_bedroom::Device::Bed( + protocol::small_bedroom::bed::Device::Bme680, + ), + ), + resolution: 1.0, + range: 0.0..=5.0, + unit: protocol::Unit::Ohm, + description: "test data with gaps", + branch_id: 0, + label_formatter: Box::new(FloatLabelFormatter), + }; + + ChartParts { + info, + data: buffer.as_mut_slice(), + reading: protocol::Reading::SmallBedroom( + protocol::small_bedroom::Reading::Bed( + protocol::small_bedroom::bed::Reading::Temperature(0.0), + ), + ), + } +} + +fn chart(frame: &mut Frame) { + let layout = frame.area(); + let mut tab = UiState::default(); + let mut buffer = Vec::new(); + chart::render(frame, layout, &mut tab, &mut [data_with_gap(&mut buffer)]); +} + +fn main() { + stdout().execute(EnterAlternateScreen).unwrap(); + enable_raw_mode().unwrap(); + let mut terminal = Terminal::new(CrosstermBackend::new(stdout())).unwrap(); + terminal.clear().unwrap(); + + terminal.draw(chart).unwrap(); + event::read().unwrap(); + + stdout().execute(LeaveAlternateScreen).unwrap(); + disable_raw_mode().unwrap(); +} diff --git a/crates/ui/src/control.rs b/crates/ui/src/control.rs new file mode 100644 index 00000000..c2d1a938 --- /dev/null +++ b/crates/ui/src/control.rs @@ -0,0 +1,99 @@ +use std::net::SocketAddr; +use std::time::Duration; + +use data_server::api::subscriber::client::Error; +use data_server::api::subscriber::{AffectorError, Client}; +use protocol::Affector; +use std::sync::mpsc as std_mpsc; +use tokio::sync::mpsc; +use tokio::time::sleep; +use tracing::error; + +use crate::{client_name, Update}; + +#[derive(Debug)] +pub enum AffectorStatus { + Send, + RateLimited, + NodeOffline, + /// connection to data_server is/was down, retrying + ConnIssues, +} + +impl std::fmt::Display for AffectorStatus { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + match self { + AffectorStatus::Send => f.write_str("Send succesfully"), + AffectorStatus::RateLimited => f.write_str( + "Dropped, affector is rate limited, try again later", + ), + AffectorStatus::NodeOffline => { + f.write_str("Dropped, node is offline") + } + AffectorStatus::ConnIssues => { + f.write_str("Queued, trying to resolve connection issues") + } + } + } +} + +pub async fn watch_and_send( + data_server: SocketAddr, + mut rx: mpsc::Receiver, + tx: std_mpsc::Sender, +) { + let mut connected_client: Option = None; + let mut queued = None; + + loop { + let order = match queued.take() { + Some(order) => order, + None => match rx.recv().await { + Some(order) => order, + None => return, + }, + }; + + tracing::debug!("got affect order: {order:?}"); + if let Some(mut client) = connected_client.take() { + let status = match client.actuate_affector(order).await { + Ok(()) => { + connected_client = Some(client); + AffectorStatus::Send + } + Err(Error::Request(AffectorError::RateLimited)) => { + connected_client = Some(client); + AffectorStatus::RateLimited + } + Err(Error::Request(AffectorError::Offline)) => { + connected_client = Some(client); + AffectorStatus::NodeOffline + } + Err(e) => { + queued = Some(order); + error!( + "Could not actuate affector, error interfacing with data-server, \ + queing order for when its resolved: {e:?}" + ); + AffectorStatus::ConnIssues + } + }; + tx.send(Update::AffectorOrderStatus { + affector: order.clone(), + status, + }) + .expect("Update listener only stops on program exit"); + } else { + match Client::connect(data_server, client_name()).await { + Ok(c) => { + queued = Some(order); + connected_client = Some(c) + } + Err(e) => { + error!("Could not connect to data_server: {e}"); + sleep(Duration::from_secs(5)).await; + } + } + } + } +} diff --git a/crates/ui/src/fetch.rs b/crates/ui/src/fetch.rs new file mode 100644 index 00000000..323c1660 --- /dev/null +++ b/crates/ui/src/fetch.rs @@ -0,0 +1,527 @@ +use std::collections::VecDeque; +use std::future::Future; +use std::net::SocketAddr; +use std::ops::RangeInclusive; +use std::sync::{mpsc, Arc}; +use std::time::Duration; + +use color_eyre::eyre::{self, Context, Report}; +use color_eyre::Result; +use jiff::Timestamp; +use log_store::api::{ErrorEvent, Percentile}; +use protocol::{IsSameAs, Reading}; +use std::sync::Mutex; +use tokio::time::Instant; +use tracing::{debug, instrument}; + +use crate::tui::readings::plot_range; +use crate::tui::readings::sensor_info::Cover; +use crate::{client_name, Fetchable, Update}; + +const MAX_IN_FLIGHT_REQUESTS: usize = 6; + +#[derive(Debug, Clone)] +pub struct Data { + reading: Reading, + range: RangeInclusive, +} + +#[derive(Debug, Clone)] +pub struct Logs { + reading: Reading, + range: RangeInclusive, +} + +#[derive(Debug, Clone)] +pub struct Hist { + reading: Reading, + range: RangeInclusive, +} + +#[derive(Debug, Clone)] +pub enum Request { + Data(Data), + Logs(Logs), + Hist(Hist), +} + +impl Request { + fn data(&self) -> Option<&Data> { + match self { + Request::Data(d) => Some(d), + _ => None, + } + } +} + +pub struct Fetch { + pub recently_issued: VecDeque, + pub tx: tokio::sync::mpsc::Sender, +} + +impl Fetch { + pub fn new( + data_store: SocketAddr, + log_store: SocketAddr, + update_tx: mpsc::Sender, + ) -> Self { + let (tx, rx) = tokio::sync::mpsc::channel(32); + + tokio::spawn(handle_requests(data_store, log_store, rx, update_tx)); + Self { + recently_issued: VecDeque::new(), + tx, + } + } + + #[instrument(skip(self, on_fetch_start))] + pub fn assure_up_to_date( + &mut self, + plot_range: plot_range::Range, + on_fetch_start: impl FnOnce(), + reading: Reading, + data_covers: Cover, + logs_covers: Cover, + hist_covers: Option>, + ) { + if !self.current_or_requested_data_suffice(&reading, plot_range, data_covers) { + debug!("Requesting history for {reading:?}"); + self.request(Request::Data(Data { + reading: reading.clone(), + range: plot_range.range_inclusive(), + })); + (on_fetch_start)(); + } + if !self.current_or_requested_logs_suffice(&reading, plot_range, logs_covers) { + debug!("Requesting logs for {reading:?}"); + self.request(Request::Logs(Logs { + reading: reading.clone(), + range: plot_range.range_inclusive(), + })) + } + if !self.current_or_requested_hist_suffices(&reading, plot_range, hist_covers) { + debug!("Requesting percentiles for {reading:?}"); + self.request(Request::Hist(Hist { + reading: reading.clone(), + range: plot_range.range_inclusive(), + })) + } + } + + #[instrument(skip(self))] + fn current_or_requested_data_suffice( + &mut self, + reading: &Reading, + needed: plot_range::Range, + current_data: Cover, + ) -> bool { + match current_data { + Cover::Overlapping { store, local } => { + if local.start() < needed.range_inclusive().start() { + return true; + } + let start = store.start().min(local.start()).clone(); + let end = store.end().max(local.end()).clone(); + if range_is_acceptable(&needed, start..=end) && resolution_ok(needed, store, local) + { + return true; + } + } + Cover::OnlyLocal(r) | Cover::OnlyStore(r) => { + if range_is_acceptable(&needed, r) { + return true; + } + } + Cover::Distinct { store, local } => { + if local.start() < needed.range_inclusive().start() { + return true; + } + if range_is_acceptable(&needed, store) { + return true; + } + } + Cover::None => (), + } + + self.recently_issued + .iter() + .filter_map(Request::data) + .filter(|req| req.reading.is_same_as(reading)) + .map(|fetch| fetch.range.clone()) + .any(|range| range_is_acceptable(&needed, range)) + } + + fn current_or_requested_logs_suffice( + &mut self, + reading: &Reading, + needed: plot_range::Range, + logs_cover: Cover, + ) -> bool { + let needed_range = needed.range_inclusive(); + match logs_cover { + Cover::Overlapping { store, local } => { + if local.start() < needed_range.start() { + return true; + } + if store + .start() + .duration_until(*needed_range.start()) + .is_positive() + && needed_range + .end() + .duration_until(*store.end()) + .is_positive() + { + return true; + } + } + Cover::OnlyLocal(r) | Cover::OnlyStore(r) => { + if r.start() + .duration_until(*needed_range.start()) + .is_positive() + && needed_range.end().duration_until(*r.end()).is_positive() + { + return true; + } + } + Cover::Distinct { store, local } => { + if local.start() < needed_range.start() { + return true; + } + if store + .start() + .duration_until(*needed_range.start()) + .is_positive() + && needed_range + .end() + .duration_until(*store.end()) + .is_positive() + { + return true; + } + } + Cover::None => (), + } + + !self + .recently_issued + .iter() + .filter_map(Request::data) + .filter(|req| req.reading.is_same_as(reading)) + .map(|fetch| fetch.range.clone()) + .any(|range| range_is_acceptable(&needed, range)) + } + + fn current_or_requested_hist_suffices( + &mut self, + reading: &Reading, + needed: plot_range::Range, + hist_range: Option>, + ) -> bool { + let Some(hist_range) = hist_range else { + return true; + }; + + !self + .recently_issued + .iter() + .filter_map(Request::data) + .filter(|req| req.reading.is_same_as(reading)) + .map(|fetch| fetch.range.clone()) + .chain(Some(hist_range)) // or does the current data satisfy? + .any(|range| range_is_acceptable(&needed, range)) + } + + fn request(&mut self, req: Request) { + self.tx.blocking_send(req.clone()).unwrap(); + self.recently_issued.push_front(req); + // Might get out of sync with request handler, that is okay + // false positives in `self.recently_issued` are allowed. They only + // delay an update by a single frame. + if self.recently_issued.len() > MAX_IN_FLIGHT_REQUESTS { + self.recently_issued.pop_back(); + } + } +} + +/// store might be resampled low resolution. If we use n% of all +/// stored data for less then n% of the needed range the resolution +/// will be high enough. +fn resolution_ok( + needed: plot_range::Range, + store: RangeInclusive, + local: RangeInclusive, +) -> bool { + let part_of_needed_coverd = needed + .range_inclusive() + .start() + .duration_until(*local.start().min(needed.range_inclusive().end())) + .unsigned_abs(); + let part_coverd_by_store = part_of_needed_coverd.div_duration_f32(needed.duration()); + let stored_duration = store.start().duration_until(*store.end()).unsigned_abs(); + let part_of_store_used = part_of_needed_coverd.div_duration_f32(stored_duration); + + part_coverd_by_store < part_of_store_used +} + +fn range_is_acceptable(needed: &plot_range::Range, range: RangeInclusive) -> bool { + let needed_range = needed.range_inclusive(); + let max_deviation = needed_range + .start() + .duration_until(*needed_range.end()) + .mul_f64(0.1); + assert!( + !max_deviation.is_negative(), + "needed_range: {needed_range:?}" + ); + + let data_start_is_ok = + range.start().duration_until(*needed_range.start()).abs() < max_deviation; + let data_end_is_ok = if needed.is_relative() { + range // allow range to end early + .end() + .duration_since(*needed_range.end()) + .abs() + < max_deviation + } else { + range.end().duration_since(*needed_range.end()) < max_deviation + }; + data_start_is_ok && data_end_is_ok +} + +pub(crate) async fn handle_requests( + data_store: SocketAddr, + log_store: SocketAddr, + mut rx: tokio::sync::mpsc::Receiver, + tx: mpsc::Sender, +) { + let data_store_queue = Queue::default(); + let log_store_queue = Queue::default(); + + let mut inflight_request = VecDeque::new(); + while let Some(request) = rx.recv().await { + let tx = tx.clone(); + let handle = match request { + Request::Data(Data { reading, range }) => { + let reading_clone = reading.clone(); + tokio::spawn(get_retry_then_wrap_send( + move || get_data(data_store, reading.clone(), range.clone()), + data_store_queue.clone(), + "Could not fetch data for graph", + move |res| match res { + Ok(data) => Update::Fetched { + reading: reading_clone, + thing: Fetchable::Data { + timestamps: data.0, + data: data.1, + }, + }, + Err(err) => Update::FetchError(err), + }, + tx, + )) + } + Request::Logs(Logs { reading, range }) => { + let reading_clone = reading.clone(); + let range_clone = range.clone(); + tokio::spawn(get_retry_then_wrap_send( + move || get_logs(log_store, reading.clone(), range.clone()), + log_store_queue.clone(), + "Could not fetch logs", + move |res| match res { + Ok(logs) => Update::Fetched { + reading: reading_clone, + thing: Fetchable::Logs { + logs, + start_at: *range_clone.start(), + }, + }, + Err(err) => Update::FetchError(err), + }, + tx, + )) + } + Request::Hist(Hist { reading, range }) => { + let reading_clone = reading.clone(); + tokio::spawn(get_retry_then_wrap_send( + move || get_percentiles(log_store, reading.clone()), + log_store_queue.clone(), + "Could not fetch percentiles for histogram", + move |res| match res { + Ok(percentiles) => Update::Fetched { + reading: reading_clone, + thing: Fetchable::Hist { percentiles, range }, + }, + Err(err) => Update::FetchError(err), + }, + tx, + )) + } + }; + inflight_request.push_front(handle); + if inflight_request.len() > 6 { + let to_cancel = inflight_request.pop_back().expect("more then 0 items"); + to_cancel.abort(); + } + } +} + +#[derive(Debug, Clone, Default)] +struct Queue(Arc>); + +impl Queue { + fn register(&self) -> usize { + let mut this = self.0.lock().unwrap(); + let most_recent_request = &mut this.most_recent_request; + *most_recent_request += 1; + *most_recent_request + } + + fn set_next_allowed(&self, at: Instant) { + let mut this = self.0.lock().unwrap(); + this.next_allowed = Some(at); + } + + fn our_turn(&self, id: usize) -> Result, Instant> { + let this = self.0.lock().unwrap(); + if let Some(next_allowed) = this.next_allowed { + let until = next_allowed.saturating_duration_since(Instant::now()); + + if until.is_zero() { + Ok(None) + } else if this.most_recent_request == id { + Ok(Some(next_allowed)) + } else { + // Queue behind highest priority + Err(next_allowed + Duration::from_millis(10)) + } + } else { + Ok(None) + } + } +} + +#[derive(Debug, Default)] +struct InnerLimits { + next_allowed: Option, + most_recent_request: usize, +} + +#[must_use] +enum GetResult { + Ok(T), + Err(eyre::Error), + RateLimited { allowed_in: Duration }, +} + +impl From> for GetResult { + fn from(value: Result) -> Self { + match value { + Ok(v) => Self::Ok(v), + Err(e) => Self::Err(e), + } + } +} + +async fn get_retry_then_wrap_send>>( + getter: impl Fn() -> F, + queue: Queue, + err_text: &'static str, + wrapper: impl FnOnce(Result) -> Update, + tx: mpsc::Sender, +) { + let id = queue.register(); + + let update = loop { + match queue.our_turn(id) { + Ok(Some(allowed_at)) => { + tokio::time::sleep_until(allowed_at).await; + } + Ok(None) => (), + Err(recheck_at) => { + tokio::time::sleep_until(recheck_at).await; + continue; + } + } + + match getter().await { + GetResult::Ok(val) => break wrapper(Ok(val)), + GetResult::Err(e) => break wrapper(Err(e).wrap_err(err_text)), + GetResult::RateLimited { allowed_in } => { + queue.set_next_allowed(Instant::now() + allowed_in); + } + } + }; + tx.send(update).unwrap(); +} + +async fn get_data( + data_store: SocketAddr, + reading: Reading, + range: RangeInclusive, +) -> GetResult<(Vec, Vec)> { + use data_store::api::{client::ConnectError, client::Error, Data, GetDataError}; + + let mut api = match data_store::api::Client::connect(data_store, client_name()).await { + Ok(api) => api, + Err(ConnectError::RateLimited(d)) => return GetResult::RateLimited { allowed_in: d }, + Err(other) => { + return GetResult::Err(Report::new(other).wrap_err("Could not connect to data-store")) + } + }; + + match api + .get_data(*range.start(), *range.end(), reading, 300) + .await + { + Ok(Data { time, values }) => GetResult::Ok((time, values)), + Err(Error::Request(GetDataError::NotFound)) + | Err(Error::Request(GetDataError::EmptyFile)) + | Err(Error::Request(GetDataError::StartAfterData)) + | Err(Error::Request(GetDataError::StopBeforeData)) + | Err(Error::Request(GetDataError::NotInStore { .. })) => { + GetResult::Ok((Vec::new(), Vec::new())) + } + Err(other) => GetResult::Err( + Report::new(other).wrap_err("Data-store returned an error to our request"), + ), + } +} + +async fn get_logs( + log_store: SocketAddr, + reading: Reading, + range: RangeInclusive, +) -> GetResult> { + use log_store::api::client::{Client, ConnectError}; + + let mut api = match Client::connect(log_store, client_name()).await { + Ok(api) => api, + Err(ConnectError::RateLimited(d)) => return GetResult::RateLimited { allowed_in: d }, + Err(other) => { + return GetResult::Err(Report::new(other).wrap_err("Could not connect to log-store")) + } + }; + + api.get_logs(reading.device(), range) + .await + .wrap_err("Log store returned an error to our request") + .into() +} + +async fn get_percentiles(log_store: SocketAddr, reading: Reading) -> GetResult> { + use log_store::api::client::{Client, ConnectError}; + + let mut api = match Client::connect(log_store, client_name()).await { + Ok(api) => api, + Err(ConnectError::RateLimited(d)) => return GetResult::RateLimited { allowed_in: d }, + Err(other) => { + return GetResult::Err(Report::new(other).wrap_err("Could not connect to log-store")) + } + }; + + api.get_percentiles(reading.device()) + .await + .wrap_err("Log store returned an error to our request") + .into() +} diff --git a/crates/ui/src/lib.rs b/crates/ui/src/lib.rs new file mode 100644 index 00000000..5b5bf0be --- /dev/null +++ b/crates/ui/src/lib.rs @@ -0,0 +1,60 @@ +pub mod control; +mod fetch; +pub mod populate; +pub mod receive; +mod time; +pub mod tui; + +pub use fetch::Fetch; +use log_store::api::{ErrorEvent, Percentile}; +use protocol::Reading; +use std::ops::RangeInclusive; + +fn client_name() -> String { + let host = gethostname::gethostname(); + let host = host.to_string_lossy(); + format!("sensor-tui@{host}") +} + +pub enum Fetchable { + Data { + timestamps: Vec, + data: Vec, + }, + Logs { + logs: Vec, + start_at: jiff::Timestamp, + }, + Hist { + percentiles: Vec, + range: RangeInclusive, + }, +} + +pub enum Update { + ReadingList(Vec), + Fetched { + reading: Reading, + thing: Fetchable, + }, + FetchError(color_eyre::Report), + SensorReading(protocol::Reading), + SensorError(Box), + SubscribeError(color_eyre::Report), + DeviceList(Vec), + AffectorControlled { + affector: protocol::Affector, + controlled_by: String, + }, + AffectorList(Vec), + AffectorOrderStatus { + affector: protocol::Affector, + status: control::AffectorStatus, + }, + PopulateError(color_eyre::Report), +} + +#[derive(Debug, PartialEq, Eq)] +pub enum UserIntent { + Shutdown, +} diff --git a/crates/ui/src/main.rs b/crates/ui/src/main.rs new file mode 100644 index 00000000..979d70cd --- /dev/null +++ b/crates/ui/src/main.rs @@ -0,0 +1,90 @@ +use std::net::SocketAddr; +use std::sync::mpsc; +use std::thread; + +use clap::Parser; +use color_eyre::Result; +use tokio::task; +use ui::control; +use ui::UserIntent; + +use ui::populate; +use ui::receive; +use ui::Fetch; + +#[derive(Parser)] +#[command(name = "home automation UI")] +#[command(version = "1.0")] +#[command(about = "View sensor values")] +struct Cli { + /// Server where we can subscribe for sensor data updates + #[arg(short, long, default_value_t = SocketAddr::from(([192,168,1,43], 1235)))] + data_server: SocketAddr, + + /// Server where we can fetch historical sensor data + #[arg(short='s', long, default_value_t = SocketAddr::from(([192,168,1,43], 1236)))] + data_store: SocketAddr, + + /// Server where we can fetch logs and timing information + #[arg(short, long, default_value_t = SocketAddr::from(([192,168,1,43], 1237)))] + log_store: SocketAddr, +} + +#[tokio::main] +async fn main() -> Result<()> { + logger::tracing::setup(); + + let Cli { + data_server, + data_store, + log_store, + } = Cli::parse(); + + let (tx1, rx1) = mpsc::channel(); + let (tx2, rx2) = mpsc::channel(); + let (tx3, rx3) = tokio::sync::mpsc::channel(100); + + let fetcher = Fetch::new(data_store, log_store, tx1.clone()); + + let tx1_clone1 = tx1.clone(); + let tx1_clone2 = tx1.clone(); + + thread::spawn(move || ui::tui::run(rx1, tx2, tx3, fetcher)); + task::spawn(receive::receive_data(data_server, tx1_clone1)); + task::spawn(populate::tree( + data_server, + data_store, + log_store, + tx1_clone2, + )); + task::spawn(control::watch_and_send(data_server, rx3, tx1)); + + let UserIntent::Shutdown = rx2.recv()?; + Ok(()) +} + +/// Similar to the `std::dbg!` macro, but generates `tracing` events rather +/// than printing to standard output. +/// +/// By default, the verbosity level for the generated events is `DEBUG`, but +/// this can be customized. +#[macro_export] +macro_rules! trace_dbg { + (target: $target:expr, level: $level:expr, $ex:expr) => {{ + match $ex { + value => { + tracing::event!(target: $target, $level, ?value, stringify!($ex)); + value + } + } + }}; + (level: $level:expr, $ex:expr) => { + trace_dbg!(target: module_path!(), level: $level, $ex) + }; + (target: $target:expr, $ex:expr) => { + trace_dbg!(target: $target, level: tracing::Level::DEBUG, $ex) + }; + ($ex:expr) => { + trace_dbg!(level: tracing::Level::DEBUG, $ex) + }; +} diff --git a/crates/ui/src/populate.rs b/crates/ui/src/populate.rs new file mode 100644 index 00000000..119f08b3 --- /dev/null +++ b/crates/ui/src/populate.rs @@ -0,0 +1,74 @@ +use std::future::Future; +use std::net::SocketAddr; +use std::sync::mpsc; + +use color_eyre::Result; +use data_server::api::subscriber; +use tracing::instrument; + +use crate::{client_name, Update}; + +pub async fn send_result( + f: impl Future>, + err_text: &'static str, + tx: mpsc::Sender, +) { + match f.await { + Ok(update) => tx.send(update), + Err(e) => tx.send(Update::PopulateError(e.wrap_err(err_text))), + } + .expect("ui should be listening for these updates") +} + +pub async fn tree( + data_server_addr: SocketAddr, + data_store_addr: SocketAddr, + log_store_addr: SocketAddr, + tx: mpsc::Sender, +) { + let _ = tokio::join!( + send_result( + list_from_server(data_server_addr), + "Could not get affector list from data-server", + tx.clone() + ), + send_result( + list_from_store(data_store_addr), + "Coult not get reading list from data-store", + tx.clone() + ), + send_result( + list_from_logs(log_store_addr), + "Could not get logs and histogram from log-store", + tx + ) + ); +} + +#[instrument] +async fn list_from_server(data_server_addr: SocketAddr) -> Result { + let mut client = + subscriber::Client::connect(data_server_addr, client_name()).await?; + let list = client.list_affectors().await?; + tracing::debug!("affector list: {list:?}"); + Ok(Update::AffectorList(list)) +} + +#[instrument] +async fn list_from_store(data_store_addr: SocketAddr) -> Result { + let mut client = + data_store::api::Client::connect(data_store_addr, client_name()) + .await?; + let list = client.list_data().await?; + tracing::debug!("data list: {list:?}"); + Ok(Update::ReadingList(list)) +} + +#[instrument] +async fn list_from_logs(log_store_addr: SocketAddr) -> Result { + let mut client = + log_store::api::Client::connect(log_store_addr, client_name()).await?; + let list = client.list_devices().await?; + tracing::debug!("log list: {list:?}"); + Ok(Update::DeviceList(list)) +} diff --git a/crates/ui/src/receive.rs b/crates/ui/src/receive.rs new file mode 100644 index 00000000..811f6375 --- /dev/null +++ b/crates/ui/src/receive.rs @@ -0,0 +1,57 @@ +use std::net::SocketAddr; +use std::sync::mpsc; + +use color_eyre::eyre::{Report, WrapErr}; +use data_server::api::subscriber::{Client, SubMessage}; + +use crate::{client_name, Update}; + +pub async fn receive_data(data_server: SocketAddr, tx: mpsc::Sender) { + let client = match Client::connect(data_server, client_name()).await { + Ok(client) => client, + Err(err) => { + let _ignore_panicked_ui = tx.send(Update::SubscribeError( + Report::new(err).wrap_err("Could not connect to data server"), + )); + return; + } + }; + + let mut subbed = match client.subscribe().await { + Ok(client) => client, + Err(err) => { + let _ignore_panicked_ui = tx.send(Update::SubscribeError( + Report::new(err).wrap_err("Could not subscribe to data server"), + )); + return; + } + }; + + loop { + let res = subbed + .next() + .await + .wrap_err("Error getting next reading from server") + .map(|msg| match msg { + SubMessage::Reading(reading) => Update::SensorReading(reading), + SubMessage::ErrorReport(error) => Update::SensorError(error), + SubMessage::AffectorControlled { + affector, + controlled_by, + } => Update::AffectorControlled { + affector, + controlled_by, + }, + }); + + match res { + Ok(msg) => { + tx.send(msg).unwrap(); + } + Err(err) => { + tx.send(Update::SubscribeError(err)).unwrap(); + break; + } + } + } +} diff --git a/crates/ui/src/time.rs b/crates/ui/src/time.rs new file mode 100644 index 00000000..0d94d8f8 --- /dev/null +++ b/crates/ui/src/time.rs @@ -0,0 +1,2 @@ +pub mod format; +pub mod parse; diff --git a/crates/ui/src/time/format.rs b/crates/ui/src/time/format.rs new file mode 100644 index 00000000..03c093fb --- /dev/null +++ b/crates/ui/src/time/format.rs @@ -0,0 +1,81 @@ +pub mod progressively_more_specified; + +struct FmtOption { + unit: &'static str, + factor: usize, + /// At a max display this numb of items + /// before going to the bigger FmtOption + next: usize, +} + +impl FmtOption { + fn scale(&self, seconds: f64) -> usize { + (seconds / self.factor as f64).floor() as usize + } +} +pub fn duration(secs: f64) -> String { + #[rustfmt::skip] + let mut options = [ + // Next is purposefully set wrong, we set it in a loop below + FmtOption{unit: "s", factor: 1, next: 0}, + FmtOption{unit: "m", factor: 60, next: 0}, + FmtOption{unit: "h", factor: 60 * 60, next: 0}, + FmtOption{unit: "d", factor: 60 * 60 * 24, next: 0}, + FmtOption{unit: "w", factor: 60 * 60 * 24 * 7, next: 0}, + FmtOption{unit: "y", factor: 60 * 60 * 24 * 365, next: 0}, + ]; + + let mut next = usize::MAX; + for fmt in options.iter_mut().rev() { + fmt.next = next; + next = fmt.factor; + } + + let mut small = &options[0]; + for big in &options[1..] { + if big.scale(secs) == 0 { + return format!("{}{}", small.scale(secs), small.unit); + } + + if secs >= big.next as f64 { + small = big; + continue; + } + + if small.scale(secs % small.next as f64) == 0 { + return format!("{}{}", big.scale(secs), big.unit); + } + + return format!( + "{}{}{}{}", + big.scale(secs), + big.unit, + small.scale(secs % small.next as f64), + small.unit + ); + } + + unreachable!() +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn test_fmt_x() { + let cases = [ + (5, "5s"), + (92, "1m32s"), + (60 * 60 * 12, "12h"), + (60 * 60 * 24 * 2, "2d"), + (60 * 60 * 24 * 7, "1w"), + (60 * 60 * 24 * 366, "1y"), + (60 * 60 * 24 * 365 * 14 + 60 * 60 * 24 * 7 * 6, "14y6w"), + ]; + + for (input, correct_output) in cases { + assert_eq!(duration(input as f64), correct_output); + } + } +} diff --git a/crates/ui/src/time/format/progressively_more_specified.rs b/crates/ui/src/time/format/progressively_more_specified.rs new file mode 100644 index 00000000..1a09f73e --- /dev/null +++ b/crates/ui/src/time/format/progressively_more_specified.rs @@ -0,0 +1,87 @@ +use std::fmt::Display; +use std::time::Duration; + +use super::duration; + +#[derive(Debug, PartialEq, Eq)] +pub(crate) enum FmtScale { + RelativeDuration, + HourMinute, + DayHour, + MonthDay, + YearMonth, +} + +impl Display for FmtScale { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + match self { + FmtScale::RelativeDuration => f.write_str("elapsed"), + FmtScale::HourMinute => f.write_str(":"), + FmtScale::DayHour => f.write_str(" "), + FmtScale::MonthDay => f.write_str(" "), + FmtScale::YearMonth => f.write_str(" "), + } + } +} + +impl FmtScale { + /// figure out optimal time description for every label point + /// for example use 15:30 for something 3h ago but 2024/05 for + /// a label 3 years ago. + pub fn optimal_for(t: jiff::Timestamp, elapsed: Duration) -> Self { + pub(crate) const HOUR: Duration = Duration::from_secs(60 * 60); + + let t = t.to_zoned(jiff::tz::TimeZone::system()); + let one_month_ago = jiff::Zoned::now() + .checked_sub(jiff::Span::new().months(1)) + .unwrap(); + let one_year_ago = jiff::Zoned::now() + .checked_sub(jiff::Span::new().years(1)) + .unwrap(); + + if elapsed < 2 * HOUR { + Self::RelativeDuration + } else if elapsed < 24 * HOUR { + Self::HourMinute + } else if t > one_month_ago { + Self::DayHour + } else if t > one_year_ago { + Self::MonthDay + } else { + Self::YearMonth + } + } + + pub(crate) fn render( + &self, + t: jiff::Timestamp, + elapsed: Duration, + duration_postfix: &str, + ) -> String { + if elapsed.is_zero() { + return "now".to_string(); + } + + let t = t.to_zoned(jiff::tz::TimeZone::system()); + match self { + FmtScale::RelativeDuration => duration(elapsed.as_secs_f64()) + duration_postfix, + FmtScale::HourMinute => t.strftime("%H:%M").to_string(), + FmtScale::DayHour => t.strftime("%dth %Hh").to_string(), + FmtScale::MonthDay => t.strftime("%d %b").to_string(), + FmtScale::YearMonth => t.strftime("%b %Y").to_string(), + } + } +} + +#[cfg(test)] +mod test { + use super::*; + + #[test] + fn month_ago() { + let t = jiff::Timestamp::now() - jiff::Span::new().hours(40 * 24); + let elapsed = jiff::Timestamp::now().duration_since(t).unsigned_abs(); + let res = FmtScale::optimal_for(t, elapsed); + assert_eq!(res, FmtScale::MonthDay) + } +} diff --git a/crates/ui/src/time/parse.rs b/crates/ui/src/time/parse.rs new file mode 100644 index 00000000..88032e50 --- /dev/null +++ b/crates/ui/src/time/parse.rs @@ -0,0 +1,80 @@ +use std::num::ParseFloatError; +use std::time::Duration; + +#[derive(Debug, thiserror::Error)] +pub enum ParseError { + #[error("Could not parse the seconds, input: {1}, error: {0}")] + Second(ParseFloatError, String), + #[error("Could not parse the minutes, input: {1}, error: {0}")] + Minute(ParseFloatError, String), + #[error("Could not parse the hours, input: {1}, error: {0}")] + Hour(ParseFloatError, String), + #[error("Durations need a suffix or one `:`")] + NoColonOrUnit(String), +} + +fn second_err(e: ParseFloatError, s: &str) -> ParseError { + ParseError::Second(e, s.to_owned()) +} +fn minute_err(e: ParseFloatError, s: &str) -> ParseError { + ParseError::Minute(e, s.to_owned()) +} +fn hour_err(e: ParseFloatError, s: &str) -> ParseError { + ParseError::Hour(e, s.to_owned()) +} + +/// Parses a string in format +/// hh:mm:ss, +/// mm:ss, +/// :ss, +pub(crate) fn parse_colon_duration(arg: &str) -> Result { + let Some((rest, seconds)) = arg.rsplit_once(':') else { + return Err(ParseError::NoColonOrUnit(arg.to_string())); + }; + + let mut seconds = seconds.parse().map_err(|e| second_err(e, arg))?; + if rest.is_empty() { + return Ok(seconds); + } + + let Some((hours, minutes)) = rest.rsplit_once(':') else { + let minutes: f32 = rest.parse().map_err(|e| minute_err(e, arg))?; + seconds += 60.0 * minutes; + return Ok(seconds); + }; + seconds += 60.0 * minutes.parse::().map_err(|e| minute_err(e, minutes))?; + if hours.is_empty() { + return Ok(seconds); + }; + seconds += 60.0 * 60.0 * hours.parse::().map_err(|e| hour_err(e, hours))?; + Ok(seconds) +} + +/// Parse a string in two different formats to a `Duration`. The formats are: +/// - 10h +/// - 15m +/// - 30s +/// - hh:mm:ss, +/// - mm:ss, +/// - :ss, +/// +/// suffixes like d (days), w (weeks) and y (years) are also supported +pub(crate) fn parse_duration(arg: &str) -> Result { + let suffix_and_factor = [ + ('y', 365 * 24 * 60 * 60), + ('w', 7 * 24 * 60 * 60), + ('d', 24 * 60 * 60), + ('h', 60 * 60), + ('m', 60), + ('s', 1), + ]; + + for (suffix, factor) in suffix_and_factor { + if let Some(num) = arg.strip_suffix(suffix) { + let num = num.parse::().map_err(|e| hour_err(e, num))?; + return Ok(std::time::Duration::from_secs_f32(num * factor as f32)); + } + } + let seconds = parse_colon_duration(arg)?; + Ok(std::time::Duration::from_secs_f32(seconds)) +} diff --git a/crates/ui/src/tui.rs b/crates/ui/src/tui.rs new file mode 100644 index 00000000..57aa9a82 --- /dev/null +++ b/crates/ui/src/tui.rs @@ -0,0 +1,197 @@ +use crossterm::{ + event::{self, KeyCode, KeyEventKind, KeyModifiers}, + terminal::{ + disable_raw_mode, enable_raw_mode, EnterAlternateScreen, + LeaveAlternateScreen, + }, + ExecutableCommand, +}; +use protocol::Affector; +use ratatui::{ + prelude::{CrosstermBackend, Terminal}, + style::{Color, Style}, +}; +use render::render; +use std::{ + io::{stdout, Stdout}, + sync::mpsc, + time::Duration, +}; + +use crate::{Fetch, Update, UserIntent}; + +mod affectors; +pub mod readings; +mod render; +mod reports; + +#[derive(Debug, Clone, Copy, PartialEq, Eq, Default)] +enum ActiveTab { + #[default] + Readings, + Affectors, +} + +impl ActiveTab { + fn swap(self) -> Self { + match self { + Self::Readings => Self::Affectors, + Self::Affectors => Self::Readings, + } + } + + fn number(&self) -> usize { + match self { + ActiveTab::Readings => 0, + ActiveTab::Affectors => 1, + } + } +} + +pub struct Theme { + bars: Style, + centered_text: Style, +} + +impl Default for Theme { + fn default() -> Self { + Self { + bars: Style::new().bg(Color::Gray).fg(Color::Black), + centered_text: Style::new(), + } + } +} + +pub fn run( + rx: mpsc::Receiver, + shutdown_tx: mpsc::Sender, + control_tx: tokio::sync::mpsc::Sender, + fetcher: Fetch, +) -> Result<(), std::io::Error> { + stdout().execute(EnterAlternateScreen)?; + enable_raw_mode()?; + let mut terminal = Terminal::new(CrosstermBackend::new(stdout()))?; + terminal.clear()?; + + let res = App::default().run(terminal, rx, control_tx, fetcher); + shutdown_tx.send(UserIntent::Shutdown).unwrap(); + + stdout().execute(LeaveAlternateScreen)?; + disable_raw_mode()?; + + res +} + +#[derive(Default)] +struct App { + theme: Theme, + active_tab: ActiveTab, + readings_tab: readings::Tab, + affectors_tab: affectors::Tab, + reports: reports::Reports, +} + +impl App { + pub fn run( + &mut self, + mut terminal: Terminal>, + rx: mpsc::Receiver, + mut control_tx: tokio::sync::mpsc::Sender, + mut fetcher: Fetch, + ) -> Result<(), std::io::Error> { + loop { + terminal.draw(|frame| { + let layout = render(frame, self); + match self.active_tab { + ActiveTab::Readings => { + self.readings_tab.render(frame, layout, &self.theme) + } + ActiveTab::Affectors => { + self.affectors_tab.render(frame, layout, &self.theme) + } + } + })?; + + if let ActiveTab::Readings = self.active_tab { + self.readings_tab.fetch_if_needed(&mut fetcher); + } + + if event::poll(Duration::from_millis(16))? { + if let event::Event::Key(key) = event::read()? { + tracing::trace!("key pressed: {key:?}"); + if key.kind == KeyEventKind::Press { + let res = match key.code { + KeyCode::Char('c') + if key + .modifiers + .contains(KeyModifiers::CONTROL) => + { + break Ok(()); + } + _ => Some(key), + } + .and_then(|key| match self.active_tab { + ActiveTab::Readings => { + self.readings_tab.handle_key(key) + } + ActiveTab::Affectors => self + .affectors_tab + .handle_key(key, &mut control_tx), + }) + .and_then(|key| self.reports.handle_key(key)); + + if let Some(unhandled_key) = res { + match unhandled_key.code { + KeyCode::Left => { + self.active_tab = self.active_tab.swap(); + } + KeyCode::Right => { + self.active_tab = self.active_tab.swap(); + } + KeyCode::Char('q') | KeyCode::Esc => { + return Ok(()) + } + _ => (), + } + } + } + } + } + + let Ok(update) = rx.try_recv() else { + continue; + }; + + let Some(update) = self.register_errors(update) else { + continue; + }; + let Some(update) = self.affectors_tab.process_update(update) else { + continue; + }; + self.readings_tab.process_update(update); + } + } + + fn register_errors(&mut self, update: Update) -> Option { + match update { + Update::AffectorControlled { .. } + | Update::AffectorList(_) + | Update::DeviceList(_) + | Update::Fetched { .. } + | Update::ReadingList(_) + | Update::SensorError(_) + | Update::AffectorOrderStatus { .. } + | Update::SensorReading(_) => return Some(update), + Update::PopulateError(e) => { + self.reports.add(e.wrap_err("Error populating lists")) + } + Update::FetchError(e) => { + self.reports.add(e.wrap_err("Error fetching")) + } + Update::SubscribeError(e) => self + .reports + .add(e.wrap_err("Error while subscribing to data-server")), + } + None + } +} diff --git a/crates/ui/src/tui/affectors.rs b/crates/ui/src/tui/affectors.rs new file mode 100644 index 00000000..923f7530 --- /dev/null +++ b/crates/ui/src/tui/affectors.rs @@ -0,0 +1,284 @@ +use std::collections::HashMap; +use std::time::Instant; + +use crossterm::event::{KeyCode, KeyEvent}; +use protocol::{affector, Affector}; +use ratatui::layout::{Constraint, Layout, Rect}; +use ratatui::Frame; +use tokio::sync::mpsc; +use tui_tree_widget::{TreeItem, TreeState}; + +use crate::control; +use crate::Update; + +use super::Theme; +use protocol::affector::tree::Item; +use protocol::affector::tree::Tree as AffectorTree; + +mod handle_key; +mod render; + +pub type TreeKey = [u8; 6]; + +#[derive(Debug)] +struct AffectorState { + affector: Affector, + selected_control: usize, + last_input: Option, + last_controlled_by: Option, + last_order_status: Option, + info: affector::Info, + device_broken: DeviceBroken, +} + +#[derive(Default)] +pub struct Tab { + tree_state: TreeState, + pub ground: Vec>, + data: HashMap, +} + +impl Tab { + pub fn render(&mut self, frame: &mut Frame, layout: Rect, theme: &Theme) { + let [main, footer] = + Layout::vertical([Constraint::Fill(1), Constraint::Max(1)]) + .areas(layout); + let [left, right] = + Layout::horizontal([Constraint::Fill(1), Constraint::Fill(1)]) + .areas(main); + + render::tree(frame, left, &self.ground, &mut self.tree_state); + + let mut data = self + .tree_state + .selected() + .last() // unique leaf id + .and_then(|key| self.data.get_mut(key)); + + if let Some(ref mut data) = data { + let [top, bottom] = + Layout::vertical([Constraint::Fill(1), Constraint::Fill(1)]) + .areas(right); + render::details(frame, data, top); + render::controls(frame, data, bottom); + }; + render::footer(frame, footer, data, theme) + } + + pub fn handle_key( + &mut self, + key: KeyEvent, + control: &mut mpsc::Sender, + ) -> Option { + let data = self + .tree_state + .selected() + .last() // unique leaf id + .and_then(|key| self.data.get_mut(key)); + + match key.code { + KeyCode::Down => { + self.tree_state.key_down(); + } + KeyCode::Up => { + self.tree_state.key_up(); + } + KeyCode::Enter => { + self.tree_state.toggle_selected(); + } + _ => { + if let Some(state) = data { + handle_key::handle(key, state, control)?; + } + return Some(key); + } + } + None + } + + pub fn process_update(&mut self, update: Update) -> Option { + let update = match update { + Update::ReadingList(_) + | Update::Fetched { .. } + | Update::FetchError(_) + | Update::SensorReading(_) + | Update::DeviceList(_) + | Update::PopulateError(_) + | Update::SubscribeError(_) => Some(update), + Update::AffectorControlled { + affector, + controlled_by, + } => { + self.mark_controlled(&affector, controlled_by); + None + } + Update::SensorError(ref err) => { + let broken = err.device().info().affectors; + for affector in broken { + self.mark_broken(affector); + } + Some(update) + } + Update::AffectorList(affectors) => { + for affector in affectors { + self.add(&affector); + } + None + } + Update::AffectorOrderStatus { affector, status } => { + self.update_order_status(&affector, status); + None + } + }; + + if self.tree_state.selected().is_empty() { + self.tree_state.select_first(); + } + + update + } +} + +#[derive(Debug)] +enum DeviceBroken { + Yes, + No, +} + +impl Tab { + fn mark_controlled( + &mut self, + affector: &protocol::Affector, + controlled_by: String, + ) { + self.update_tree(affector, move |state| { + state.last_controlled_by = Some(controlled_by); + }) + } + + fn mark_broken(&mut self, affector: &protocol::Affector) { + self.update_tree(affector, move |state| { + state.device_broken = DeviceBroken::Yes; + }) + } + + fn add(&mut self, affector: &protocol::Affector) { + self.update_tree(affector, move |state| { + state.affector = *affector; + }) + } + + fn update_order_status( + &mut self, + affector: &protocol::Affector, + status: control::AffectorStatus, + ) { + self.update_tree(affector, move |state| { + state.last_order_status = Some(status); + }) + } + + fn update_tree( + &mut self, + affector: &protocol::Affector, + update: impl FnOnce(&mut AffectorState) -> (), + ) { + let key = tree_key(affector); + + let mut tree = + add_root(affector as &dyn AffectorTree, &mut self.ground); + let mut tree_node = match affector.inner() { + Item::Leaf(_) => unreachable!("no values at level 0"), + Item::Node(inner) => inner, + }; + loop { + match tree_node.inner() { + Item::Leaf(info) => { + let text = tree_node.name(); + add_leaf(text, tree, key); + let item = self.data.entry(key).or_insert(AffectorState { + affector: *affector, + info, + selected_control: 0, + last_controlled_by: None, + device_broken: DeviceBroken::No, + last_input: None, + last_order_status: None, + }); + update(item); + return; + } + Item::Node(inner) => { + tree = add_node(tree_node, tree); + tree_node = inner; + } + }; + } + } +} + +fn add_leaf(text: String, tree: &mut TreeItem<'static, TreeKey>, key: TreeKey) { + let new_item = TreeItem::new_leaf(key, text.clone()); + // todo is exists its fine handle that + let _ignore_existing = tree.add_child(new_item); // errors when identifier already exists + + let new_child = tree + .children() + .iter() + .position(|item| *item.identifier() == key) + .expect("just added it"); + let existing = tree.child_mut(new_child).expect("just added it"); + existing.update_text(text); +} + +fn add_root<'a>( + tomato: &dyn AffectorTree, + ground: &'a mut Vec>, +) -> &'a mut TreeItem<'static, TreeKey> { + let key = [tomato.branch_id(); 6]; + let exists = ground.iter().any(|item| *item.identifier() == key); + if !exists { + let new_root = TreeItem::new(key, tomato.name(), vec![]).unwrap(); + ground.push(new_root); + } + + ground + .iter_mut() + .find(|item| *item.identifier() == key) + .expect("checked and added if missing") +} + +fn add_node<'a>( + tomato: &dyn AffectorTree, + tree: &'a mut TreeItem<'static, TreeKey>, +) -> &'a mut TreeItem<'static, TreeKey> { + let key = [tomato.branch_id(); 6]; + let new_item = TreeItem::new(key, tomato.name(), Vec::new()).unwrap(); + // add just in case it was not there yet + let _ignore_existing = tree.add_child(new_item); + let new_child = tree + .children() + .iter() + .position(|item| *item.identifier() == key) + .expect("just added it"); + tree.child_mut(new_child).expect("just added it") +} + +pub(crate) fn tree_key(affector: &protocol::Affector) -> TreeKey { + let mut key = [0u8; 6]; + key[0] = affector.branch_id(); + + let mut reading = affector as &dyn AffectorTree; + for byte in &mut key[1..] { + reading = match reading.inner() { + Item::Node(inner) => { + *byte = inner.branch_id(); + inner + } + Item::Leaf(affector::Info { .. }) => { + return key; + } + }; + } + unreachable!("reading should not be deeper then key size") +} diff --git a/crates/ui/src/tui/affectors/handle_key.rs b/crates/ui/src/tui/affectors/handle_key.rs new file mode 100644 index 00000000..d2e69b74 --- /dev/null +++ b/crates/ui/src/tui/affectors/handle_key.rs @@ -0,0 +1,86 @@ +use std::time::Instant; + +use crossterm::event::{KeyCode, KeyEvent}; +use protocol::affector::ControlValue as C; +use tokio::sync::mpsc; +use tokio::sync::mpsc::error::TrySendError; +use tracing::{error, warn}; + +use super::AffectorState; + +pub(crate) fn handle( + key: KeyEvent, + state: &mut AffectorState, + control_tx: &mut mpsc::Sender, +) -> Option { + state.last_input = Some(Instant::now()); + let mut controls = state.affector.controls(); + let control = &mut controls[state.selected_control].value; + + match key.code { + KeyCode::Char('t') => handle_trigger(control), + KeyCode::Char('f') => handle_increase(control), + KeyCode::Char('b') => handle_decrease(control), + + // Otherwise return since we have not changed the affector + KeyCode::Char('d') => { + state.selected_control = (state.selected_control + 1).min(controls.len() - 1); + return None; + } + KeyCode::Char('u') => { + state.selected_control = state.selected_control.saturating_sub(1); + return None; + } + _ => return Some(key), + }; + + core::mem::drop(controls); + match control_tx.try_send(state.affector) { + Ok(_) => (), + Err(TrySendError::Full(_)) => warn!("control lagging behind ui inputs"), + Err(TrySendError::Closed(_)) => error!("control lost connection to data-server"), + } + + None +} + +fn handle_trigger(control: &mut C) { + match control { + C::Trigger => (), + C::SetNum { .. } => (), + } +} + +fn handle_increase(control: &mut C) { + match control { + C::Trigger => (), + C::SetNum { + valid_range, + setter, + value, + } => { + let new_value = *value + 1; + let new_value = new_value as u64; + let new_value = new_value.clamp(valid_range.start, valid_range.end); + let setter = setter.take().expect("just created controls"); + setter(new_value as usize); + } + } +} + +fn handle_decrease(control: &mut C) { + match control { + C::Trigger => (), + C::SetNum { + valid_range, + setter, + value, + } => { + let new_value = value.saturating_sub(1); + let new_value = new_value as u64; + let new_value = new_value.clamp(valid_range.start, valid_range.end); + let setter = setter.take().expect("just created controls"); + setter(new_value as usize); + } + } +} diff --git a/crates/ui/src/tui/affectors/render.rs b/crates/ui/src/tui/affectors/render.rs new file mode 100644 index 00000000..5796c93c --- /dev/null +++ b/crates/ui/src/tui/affectors/render.rs @@ -0,0 +1,176 @@ +use core::iter; +use protocol::affector; +use ratatui::layout::{Alignment, Constraint, Layout, Rect}; +use ratatui::style::{Modifier, Style, Stylize}; +use ratatui::text::Text; +use ratatui::widgets::{self, Block, Borders, Gauge}; +use ratatui::Frame; +use tui_tree_widget::Tree; +use tui_tree_widget::{TreeItem, TreeState}; + +use crate::tui::Theme; + +use super::{AffectorState, DeviceBroken, TreeKey}; + +pub(super) fn tree( + frame: &mut Frame, + left: Rect, + ground: &[TreeItem], + state: &mut TreeState, +) { + frame.render_stateful_widget( + Tree::new(ground) + .expect("all item identifiers should be unique") + .block( + Block::default() + .title("Controllable affectors") + .borders(Borders::ALL), + ) + .highlight_style(Style::default().add_modifier(Modifier::ITALIC)) + .highlight_symbol(">>"), + left, + state, + ); +} + +pub(super) fn details(frame: &mut Frame, data: &mut AffectorState, top: Rect) { + let mut text = vec![data.info.description.to_owned()]; + if let Some(ref name) = data.last_controlled_by { + text.push(format!("\nlast controlled by: {name}")); + } + if let Some(ref at) = data.last_input { + let input_action = match data + .affector + .controls() + .get(data.selected_control) + .expect("controls are never removed") + .value + { + affector::ControlValue::Trigger => "trigged", + affector::ControlValue::SetNum { .. } => "set", + }; + let elapsed = crate::time::format::duration(at.elapsed().as_secs_f64()); + text.push(format!("\nwe last {input_action}: {elapsed} ago")); + } + if let Some(ref status) = data.last_order_status { + text.push(format!("\nstatus: {status}")); + } + if let DeviceBroken::Yes = data.device_broken { + text.push( + "\nWarning: Device reports error, affector might not work" + .to_owned(), + ); + } + let text = text.join("\n"); + + frame.render_widget( + widgets::Paragraph::new(text) + .block(Block::bordered().title("Details")) + .wrap(widgets::Wrap { trim: true }), + top, + ) +} + +pub(crate) fn controls( + frame: &mut Frame, + data: &mut &mut AffectorState, + bottom: Rect, +) { + use affector::ControlValue as V; + + let controls = data.affector.controls(); + let constraints = iter::once(Constraint::Max(1)) + .chain(controls.iter().map(|_| Constraint::Max(3))); + let layout = Layout::default().constraints(constraints).split(bottom); + let mut layout = layout.iter(); + + frame.render_widget( + Block::new().title("Controls").borders(Borders::TOP), + *layout.next().expect("has at least one element"), + ); + + for (i, (control, layout)) in controls.iter().zip(layout).enumerate() { + let is_selected = i == data.selected_control; + match &control.value { + V::Trigger => render_trigger(frame, *layout, i), + V::SetNum { + valid_range, value, .. + } => render_slider( + frame, + *layout, + control.name, + &valid_range, + *value, + is_selected, + ), + } + } +} + +#[tracing::instrument(skip(frame, layout))] +fn render_slider( + frame: &mut Frame, + layout: Rect, + name: &str, + valid_range: &std::ops::Range, + current_value: usize, + is_active: bool, +) { + let style = if is_active { + Style::default().black() + } else { + Style::default() + }; + + let percentage = + (current_value as u64 * 100) / (valid_range.end - valid_range.start); + frame.render_widget( + Gauge::default() + .block(Block::bordered().title(name).style(style)) + .gauge_style(Style::default().add_modifier(Modifier::ITALIC)) + .label(format!( + "{current_value} of {}-{}", + valid_range.start, valid_range.end + )) + .percent(percentage as u16), + layout, + ) +} + +fn render_trigger(frame: &mut Frame, layout: Rect, _control_idx: usize) { + frame.render_widget( + widgets::Paragraph::new("activate") + .block(Block::bordered().title("Controls")) + .wrap(widgets::Wrap { trim: true }), + layout, + ) +} + +pub(crate) fn footer( + frame: &mut Frame, + layout: Rect, + data: Option<&mut AffectorState>, + theme: &Theme, +) { + let mut footer = Vec::new(); + + use affector::ControlValue as C; + if let Some(AffectorState { + affector, + selected_control, + .. + }) = data + { + footer.push("u/d: select prev/next"); + match affector.controls()[*selected_control].value { + C::Trigger => footer.push("t: trigger affector"), + C::SetNum { .. } => footer.push("f/b increase/decrease"), + } + } + + let footer = footer.join(" "); + let footer = Text::raw(footer) + .alignment(Alignment::Center) + .style(theme.bars); + frame.render_widget(footer, layout) +} diff --git a/crates/ui/src/tui/readings.rs b/crates/ui/src/tui/readings.rs new file mode 100644 index 00000000..8a0ece42 --- /dev/null +++ b/crates/ui/src/tui/readings.rs @@ -0,0 +1,290 @@ +use std::collections::HashSet; +use std::time::Instant; + +use crossterm::event::KeyEvent; +use log_store::api::Percentile; +use protocol::IsSameAs; +use ratatui::layout::Rect; +use ratatui::widgets::TableState; +use ratatui::Frame; +use tui_tree_widget::TreeState; + +mod handle_key; +pub(crate) mod plot_range; +pub mod render; +pub mod sensor_info; +use plot_range::PlotRange; + +use crate::{fetch::Fetch, Update}; +use sensor_info::{is_leaf_id, ChartParts, Readings}; + +use super::Theme; + +#[derive(Debug, Default, Clone, Copy)] +struct InputMode { + editing_bounds: bool, + chart_cursor: bool, +} + +#[derive(Debug, Clone, Copy)] +pub struct ChartCursor { + enabled: bool, + steps: i32, + chart_width: Option, +} + +impl Default for ChartCursor { + fn default() -> Self { + Self { + enabled: false, + steps: 0, + chart_width: None, + } + } +} + +impl ChartCursor { + fn is_enabled(&self) -> bool { + self.enabled + } + fn toggle(&mut self) { + self.enabled = !self.enabled; + } + fn shift(&mut self, offset: i32) { + self.steps += offset; + } + + fn get(&mut self, chart_width: u16) -> Option { + self.chart_width = Some(chart_width); + if !self.enabled { + return None; + } + + self.steps = if self.steps >= chart_width as i32 { + 0 + } else if self.steps < 0 { + chart_width as i32 - 1 + } else { + self.steps + }; + + Some(self.steps as u16) + } + + fn zoom_in(&self) -> [f64; 2] { + let Some(chart_width) = self.chart_width else { + return [1.0, 1.0]; + }; + + let pos = self.steps as f64 / chart_width as f64; + [pos - 0.1, pos + 0.1] + } + + fn zoom_out(&self) -> [f64; 2] { + let Some(chart_width) = self.chart_width else { + return [1.0, 1.0]; + }; + + let pos = self.steps as f64 / chart_width as f64; + [pos - 10.0, pos + 10.0] + } +} + +#[derive(Default)] +pub struct UiState { + show_histogram: bool, + show_logs: bool, + show_complete_help: bool, + chart_cursor: ChartCursor, + plot_range: PlotRange, + input_mode: InputMode, + tree_state: TreeState, + logs_table_state: TableState, + reading_selected: bool, + comparing: HashSet, +} + +pub struct Tab { + ui_state: UiState, + readings: Readings, + plot_bufs: Vec>, +} + +impl Default for Tab { + fn default() -> Self { + Self { + ui_state: UiState::default(), + readings: Readings::new(), + plot_bufs: Vec::new(), + } + } +} + +#[derive(Default)] +struct DataToDisplay<'a> { + chart_parts: Vec>, + precentiles: Vec, + details: Option, + logs: Option, +} + +fn fill_data<'a>( + to_display: Vec, + readings: &mut Readings, + plot_bufs: &'a mut Vec>, + history_len: &plot_range::Range, +) -> DataToDisplay<'a> { + for buf in plot_bufs.iter_mut() { + buf.clear(); + } + plot_bufs.resize_with(to_display.len().max(plot_bufs.len()), Vec::new); + let mut res = DataToDisplay::default(); + for (i, (ui_id, buf)) in to_display.into_iter().zip(plot_bufs).enumerate() { + let Some(info) = readings.get_by_ui_id(ui_id) else { + continue; + }; + + if i == 0 { + // TODO merge? if possible; + res.precentiles = info.percentiles(); + // TODO merge to show details from all plots + res.details = Some(info.details()); + // TODO merge to show logs interleaved + res.logs = Some(info.logs()); + } + + res.chart_parts.push(info.chart(buf, &history_len)); + } + res +} + +impl Tab { + pub fn render(&mut self, frame: &mut Frame, layout: Rect, theme: &Theme) { + let Self { + ui_state, + readings, + plot_bufs, + } = self; + + let DataToDisplay { + chart_parts, + precentiles, + details, + logs, + } = { + let selected = ui_state.tree_state.selected().last(); + ui_state.reading_selected = selected.copied().is_some_and(is_leaf_id); + + let mut to_display: Vec<_> = selected + .into_iter() + .chain(ui_state.comparing.iter()) + .copied() + .collect(); + to_display.sort(); + to_display.dedup(); + fill_data(to_display, readings, plot_bufs, &ui_state.plot_range.range) + }; + + let [top, bottom, footer] = render::layout( + frame, + layout, + readings, + !chart_parts.is_empty(), + logs.is_some(), + ui_state, + ); + + let have_details = details.is_some(); + render::readings_and_details(frame, top, ui_state, readings, details); + if have_details { + render::graph_hist_logs( + frame, + bottom, + ui_state, + &precentiles, + logs, + chart_parts, + theme, + ); + } + render::footer(frame, footer, ui_state, theme); + } + + pub fn handle_key(&mut self, key: KeyEvent) -> Option { + self.ui_state.handle_key_all(key)?; + if self.ui_state.input_mode.editing_bounds { + self.ui_state.handle_key_bounds(key)?; + } else { + self.ui_state.handle_key_normal_mode(key)?; + }; + if self.ui_state.input_mode.chart_cursor { + self.ui_state.handle_key_cursor(key)?; + } + + Some(key) + } + + pub fn process_update(&mut self, update: Update) { + let data = self + .ui_state + .tree_state + .selected() + .last() // Unique leaf id + .and_then(|key| self.readings.get_by_ui_id(*key)); + + match update { + Update::SensorReading(reading) => { + self.readings.update(reading); + } + Update::ReadingList(list) => { + self.readings.populate_from_reading_list(list); + } + Update::DeviceList(list) => { + self.readings.populate_from_device_list(list); + } + Update::SensorError(err) => self.readings.add_error(err), + Update::Fetched { + reading, + thing: fetched, + } => { + if data + .as_ref() + .is_some_and(|i| i.reading.is_same_as(&reading)) + { + self.ui_state.plot_range.state = plot_range::State::Fetched; + } + self.readings.add_fetched(reading, fetched); + } + + _ => (), + } + + if self.ui_state.tree_state.selected().is_empty() { + self.ui_state.tree_state.select_first(); + } + } + + pub(crate) fn fetch_if_needed(&mut self, fetcher: &mut Fetch) { + let selected = self.ui_state.tree_state.selected().last(); + let needed = selected + .into_iter() + .chain(self.ui_state.comparing.iter()) + .copied(); + + let history_len = &mut self.ui_state.plot_range.state; + for data in needed { + let Some(data) = self.readings.get_by_ui_id(data) else { + continue; + }; + + fetcher.assure_up_to_date( + self.ui_state.plot_range.range, + || *history_len = plot_range::State::Fetching(Instant::now()), + data.reading.clone(), + data.covers(), + data.logs.covers(), + data.histogram_range.clone(), + ); + } + } +} diff --git a/crates/ui/src/tui/readings/handle_key.rs b/crates/ui/src/tui/readings/handle_key.rs new file mode 100644 index 00000000..49667568 --- /dev/null +++ b/crates/ui/src/tui/readings/handle_key.rs @@ -0,0 +1,103 @@ +use super::UiState; +use crossterm::event::{KeyCode, KeyEvent, KeyModifiers}; + +impl UiState { + pub(crate) fn handle_key_normal_mode(&mut self, key: KeyEvent) -> Option { + match key.code { + KeyCode::Char('?') => { + self.show_complete_help = !self.show_complete_help; + } + _ => { + if self.reading_selected { + self.handle_key_reading_selected(key)?; + } + return Some(key); + } + } + + None + } + + fn handle_key_reading_selected(&mut self, key: KeyEvent) -> Option { + match key.code { + KeyCode::Char('b') => { + self.plot_range.start_editing(); + self.input_mode.editing_bounds = true; + } + KeyCode::Char('h') => { + self.show_histogram = !self.show_histogram; + } + KeyCode::Char('l') => { + self.show_logs = !self.show_logs; + } + KeyCode::Char('x') => { + self.chart_cursor.toggle(); + self.input_mode.chart_cursor = self.chart_cursor.is_enabled(); + } + KeyCode::Char('i') if self.chart_cursor.is_enabled() => { + let change = self.chart_cursor.zoom_in(); + self.plot_range.change(change); + } + KeyCode::Char('o') if self.chart_cursor.is_enabled() => { + let change = self.chart_cursor.zoom_out(); + self.plot_range.change(change); + } + KeyCode::Char('c') => { + let id = *self + .tree_state + .selected() + .last() + .expect("reading_selected is true"); + if !self.comparing.remove(&id) { + self.comparing.insert(id); + } + } + _ => return Some(key), + } + + None + } + + pub(crate) fn handle_key_cursor(&mut self, key: KeyEvent) -> Option { + let mod_on = key.modifiers.contains(KeyModifiers::SHIFT) + | key.modifiers.contains(KeyModifiers::CONTROL); + + let offset = match key.code { + KeyCode::Left if mod_on => -10, + KeyCode::Right if mod_on => 10, + KeyCode::Left => -1, + KeyCode::Right => 1, + _ => return Some(key), + }; + + self.chart_cursor.shift(offset); + None + } + + pub(crate) fn handle_key_bounds(&mut self, key: KeyEvent) -> Option { + match key.code { + KeyCode::Char('q') | KeyCode::Esc => { + self.plot_range.exit_editing(); + self.input_mode.editing_bounds = false; + None + } + _ => self.plot_range.process(key), + } + } + + pub(crate) fn handle_key_all(&mut self, key: KeyEvent) -> Option { + match key.code { + KeyCode::Down => { + self.tree_state.key_down(); + } + KeyCode::Up => { + self.tree_state.key_up(); + } + KeyCode::Enter => { + self.tree_state.toggle_selected(); + } + _ => return Some(key), + } + None + } +} diff --git a/crates/ui/src/tui/readings/plot_range.rs b/crates/ui/src/tui/readings/plot_range.rs new file mode 100644 index 00000000..fcd0bfde --- /dev/null +++ b/crates/ui/src/tui/readings/plot_range.rs @@ -0,0 +1,206 @@ +use crossterm::event::{KeyCode, KeyEvent}; +use jiff::{SignedDuration, Timestamp}; +use ratatui::{ + style::{Color, Modifier, Style}, + text::Span, +}; +use std::{ + ops::RangeInclusive, + time::{Duration, Instant}, +}; + +use crate::time::format::duration; +use crate::time::parse::parse_duration; + +#[derive(Debug, Clone, Copy)] +pub enum State { + Empty, + Invalid, + Valid, + Fetching(Instant), + Fetched, +} + +#[derive(Debug, Clone, Copy)] +pub enum Range { + Relative(Duration), + Window([jiff::Timestamp; 2]), +} + +impl Range { + pub(crate) fn is_relative(&self) -> bool { + matches!(self, Range::Relative(_)) + } + + pub(crate) fn range_inclusive(&self) -> RangeInclusive { + match self { + Range::Relative(dur) => { + let dur = jiff::Span::try_from(dur.clone()).unwrap(); + let now = jiff::Timestamp::now(); + (now - dur)..=now + } + Range::Window([start, end]) => *start..=*end, + } + } + pub(crate) fn duration(&self) -> Duration { + match self { + Range::Relative(dur) => dur.clone(), + Range::Window([start, end]) => start.duration_until(*end).unsigned_abs(), + } + } +} + +pub struct PlotRange { + pub text_input: String, + pub editing: bool, + pub state: State, + pub range: Range, +} + +impl Default for PlotRange { + fn default() -> Self { + let dur = Duration::from_secs(15 * 60); + let text_input = duration(dur.as_secs_f64()); + Self { + text_input, + editing: false, + state: State::Empty, + range: Range::Relative(dur), + } + } +} + +impl PlotRange { + pub(crate) fn process(&mut self, key: KeyEvent) -> Option { + match key.code { + KeyCode::Char(c) => { + self.text_input.push(c); + } + KeyCode::Backspace => { + self.text_input.pop(); + } + _other => return Some(key), + } + + if let Ok(dur) = parse_duration(&self.text_input) { + self.state = State::Valid; + self.range = Range::Relative(dur); + } else if self.text_input.is_empty() { + self.state = State::Empty; + } else { + self.state = State::Invalid; + } + + None + } + + pub(crate) fn style_left_x_label(&self, org_label: Span<'static>) -> Span<'static> { + let mut text = self.text_input.clone(); + if self.editing { + text.push('_'); + } + match self.state { + State::Empty => { + let style = Style::default() + .fg(Color::Red) + .add_modifier(Modifier::SLOW_BLINK); + Span::raw(text).style(style) + } + State::Invalid => { + let style = Style::default() + .fg(Color::Red) + .add_modifier(Modifier::ITALIC); + Span::raw(text).style(style) + } + State::Valid => { + let style = Style::default().add_modifier(Modifier::ITALIC); + Span::raw(text).style(style) + } + State::Fetching(started) if started.elapsed() > Duration::from_secs(2) => { + let style = Style::default().add_modifier(Modifier::ITALIC); + text.push_str(" (fetching)"); + Span::raw(text).style(style) + } + State::Fetched | State::Fetching(_) => { + if self.editing { + Span::raw(text) + } else { + org_label + } + } + } + } + + pub(crate) fn exit_editing(&mut self) { + self.editing = false; + self.state = match self.state { + State::Empty | State::Invalid => State::Fetched, + State::Valid | State::Fetching(_) | State::Fetched => self.state, + } + } + + pub(crate) fn start_editing(&mut self) { + self.editing = true; + self.text_input.clear(); + } + + pub(crate) fn label_bounds(&self) -> [f64; 2] { + let bounds = match self.range { + Range::Relative(dur) => [0f64, dur.as_secs_f64()], + Range::Window([start, end]) => { + let now = Timestamp::now(); + [ + end.until(now) + .expect("now should be in the future") + .round(jiff::Unit::Second) + .expect("Timestamp.until(Timestamp) < Timestamp::Max") + .get_seconds() as f64, + start + .until(now) + .expect("now should be in the future") + .round(jiff::Unit::Second) + .expect("Timestamp.until(Timestamp) < Timestamp::Max") + .get_seconds() as f64, + ] + } + }; + assert!(bounds[0] >= 0.0, "bounds must be >= zero: {bounds:?}"); + assert!(bounds[1] >= 0.0, "bounds must be >= zero: {bounds:?}"); + bounds + } + + pub(crate) fn data_bounds(&self) -> [f64; 2] { + let dur = match self.range { + Range::Relative(dur) => dur.as_secs_f64(), + Range::Window([start, end]) => start + .until(end) + .expect("end should be in the future") + .total(jiff::Unit::Second) + .expect("Timestamp.until(Timestamp) < Timestamp::Max"), + }; + [0f64, dur] + } + + pub(crate) fn change(&mut self, [mul_start, mul_end]: [f64; 2]) { + let (dur, start) = match self.range { + Range::Relative(dur) => { + let start = Timestamp::now() - dur; + (dur.as_secs_f64(), start) + } + Range::Window([start, end]) => { + let dur = start + .until(end) + .expect("timestamps can be subtraced") + .round(jiff::Unit::Second) + .expect("Timestamp.until(Timestamp) < Timestamp::Max") + .get_seconds() as f64; + (dur, start) + } + }; + let start = start + SignedDuration::from_secs_f64(dur * mul_start); + let end = start + SignedDuration::from_secs_f64(dur * mul_end); + let end = end.min(Timestamp::now()); + self.range = Range::Window([start, end]); + self.state = State::Valid; + } +} diff --git a/crates/ui/src/tui/readings/render.rs b/crates/ui/src/tui/readings/render.rs new file mode 100644 index 00000000..9cbbeb0a --- /dev/null +++ b/crates/ui/src/tui/readings/render.rs @@ -0,0 +1,302 @@ +use jiff::Timestamp; +use log_store::api::Percentile; +use ratatui::{ + self, + layout::{Alignment, Constraint, Direction, Flex, Layout, Rect}, + style::{Modifier, Style}, + text::{Line, Text}, + widgets::{self, Bar, BarChart, BarGroup, Block, Borders}, + Frame, +}; +use tui_tree_widget::Tree; + +use crate::tui::Theme; + +use super::{ + sensor_info::{ChartParts, Details, ErrorDensity, LogList, Readings}, + UiState, +}; + +pub mod chart; +mod logs; +mod tree; + +pub(crate) fn layout( + frame: &mut Frame, + layout: Rect, + readings: &Readings, + chart: bool, + logs: bool, + ui_state: &UiState, +) -> [Rect; 3] { + let [list_constraint, graph_constraint] = if chart { + let tree_height = 2 + readings + .arena + .iter() + .filter(|node| node.is_removed()) + .count(); + let details_height = 9; + if (frame.area().height as f32) / 3. > tree_height as f32 { + [ + Constraint::Min(tree_height.max(details_height) as u16), + Constraint::Percentage(100), + ] + } else { + [Constraint::Ratio(1, 3), Constraint::Ratio(2, 3)] + } + } else if logs { + [Constraint::Percentage(60), Constraint::Percentage(40)] + } else { + [Constraint::Percentage(100), Constraint::Percentage(0)] + }; + + let help_size = 1 + ui_state.show_complete_help as u16; + Layout::vertical([ + list_constraint, + graph_constraint, + Constraint::Min(help_size), + ]) + .flex(Flex::Legacy) + .areas(layout) +} + +pub(crate) fn footer(frame: &mut Frame, layout: Rect, app: &mut UiState, theme: &Theme) { + let mut main = Vec::new(); + + if app.plot_range.editing { + main.push("ESC or q: stop bound editing"); + } else { + main.push("ESC or q: quit"); + } + + if app.reading_selected { + if !app.plot_range.editing { + main.push("b: edit graph start"); + } + + if app.show_histogram { + main.push("h: hide histogram"); + } else { + main.push("h: show histogram"); + } + + if app.show_logs { + main.push("l: hide logs"); + } else { + main.push("l: show logs"); + } + + if app.show_complete_help { + main.push("?: hide more help"); + } else { + main.push("?: show more help"); + } + } + + let layout = if app.show_complete_help { + let [top, bottom] = Layout::vertical([Constraint::Min(1), Constraint::Min(1)]) + .flex(Flex::Legacy) + .areas(layout); + + let mut extra = Vec::new(); + if app.reading_selected { + extra.push("c: toggle compare"); + if app.chart_cursor.is_enabled() { + extra.push("x: disable cursor"); + } else { + extra.push("x: enable cursor"); + } + } + let footer = extra.join(" "); + let footer = Text::raw(footer) + .alignment(Alignment::Center) + .style(theme.bars); + frame.render_widget(footer, bottom); + top + } else { + layout + }; + + let footer = main.join(" "); + let footer = Text::raw(footer) + .alignment(Alignment::Center) + .style(theme.bars); + frame.render_widget(footer, layout) +} + +pub(crate) fn graph_hist_logs( + frame: &mut Frame, + layout: Rect, + app: &mut UiState, + percentiles: &[Percentile], + logs: Option, + mut chart: Vec, + theme: &Theme, +) { + let num_elems = 1usize + app.show_histogram as usize + app.show_logs as usize; + + let mut constraints = [Constraint::Max(2); 3]; + if !chart.is_empty() { + constraints[0] = Constraint::Fill(10); + } + if logs + .as_ref() + .is_some_and(|LogList { items, .. }| !items.is_empty()) + && app.show_logs + { + constraints[1] = Constraint::Fill(10); + } + if !percentiles.is_empty() && app.show_histogram { + let idx = 1 + app.show_logs as usize; + constraints[idx] = Constraint::Fill(10); + } + + let layout = Layout::default() + .direction(Direction::Vertical) + .constraints(&constraints[..num_elems]) + .flex(Flex::Legacy) + .split(layout); + + let mut layout = layout.iter().cloned(); + + if chart.is_empty() { + centered_text( + "No chart as there is no data", + frame, + layout.next().unwrap(), + theme, + ) + } else { + chart::render(frame, layout.next().unwrap(), app, &mut chart); + } + + if app.show_logs { + logs::render( + frame, + layout.next().unwrap(), + &mut app.logs_table_state, + logs, + theme, + ) + } + + if app.show_histogram { + if percentiles.is_empty() { + centered_text( + "No histogram as there is no timing information", + frame, + layout.next().unwrap(), + theme, + ) + } else { + render_histogram(frame, layout.next().unwrap(), percentiles); + } + } +} + +fn render_histogram(frame: &mut Frame, lower: Rect, percentiles: &[Percentile]) { + let histogram = histogram_bars(percentiles); + let barchart = BarChart::default() + .block(Block::bordered().title("Histogram")) + .data(BarGroup::default().bars(&histogram)) + .bar_width(12); + frame.render_widget(barchart, lower) +} + +fn histogram_bars(percentiles: &[log_store::api::Percentile]) -> Vec> { + percentiles + .iter() + .map( + |log_store::api::Percentile { + bucket_ends, + percentile, + count_in_bucket, + }| { + Bar::default() + .value(*count_in_bucket) + .text_value(format!("p{percentile}: {}", count_in_bucket)) + .label(Line::from(format!("..{}", bucket_ends))) + }, + ) + .collect() +} + +pub(crate) fn readings_and_details( + frame: &mut Frame, + layout: Rect, + app: &mut UiState, + readings: &Readings, + details: Option
, +) { + let [left, right] = + Layout::horizontal([Constraint::Percentage(50), Constraint::Percentage(50)]) + .flex(Flex::Legacy) + .areas(layout); + + let tree = tree::build_ui(readings, &app.comparing); + frame.render_stateful_widget( + Tree::new(&tree) + .expect("all item identifiers should be unique") + .block( + Block::default() + .title("Sensor readings") + .borders(Borders::ALL), + ) + .highlight_style(Style::default().add_modifier(Modifier::ITALIC)) + .highlight_symbol(">>"), + left, + &mut app.tree_state, + ); + if let Some(details) = details { + render_details(frame, right, details); + } +} + +fn render_details(frame: &mut Frame, layout: Rect, details: Details) { + let Details { + last_reading, + condition, + description, + errors_since, + } = details; + let last_reading = match last_reading { + None => "last read: Never".to_owned(), + Some((ts, val)) => { + let seconds_ago = Timestamp::now() + .since(ts) + .expect("should make sense") + .get_seconds(); + let time_ago = crate::time::format::duration(seconds_ago as f64); + format!("last read: {time_ago} ago, value: {val}") + } + }; + + let condition = match condition { + Ok(()) => String::new(), + Err(err) => format!("error: {err}\n"), + }; + + let ErrorDensity { + t5_min, + t15_min, + t30_min, + t45_min, + t60_min, + } = errors_since; + let errors_since = format!("errors in the past:\n5min: {t5_min:.2}, 15min: {t15_min:.2}, 30min: {t30_min:.2}, 45min {t45_min:.2}, 60m: {t60_min:.2}"); + + let text = format!("{description}\n{last_reading}\n{condition}{errors_since}"); + frame.render_widget( + widgets::Paragraph::new(text) + .block(Block::bordered().title("Details")) + .wrap(widgets::Wrap { trim: true }), + layout, + ) +} + +fn centered_text(text: &str, frame: &mut Frame, area: Rect, theme: &Theme) { + let footer = Text::raw(text) + .alignment(Alignment::Center) + .style(theme.centered_text); + frame.render_widget(footer, area) +} diff --git a/crates/ui/src/tui/readings/render/chart.rs b/crates/ui/src/tui/readings/render/chart.rs new file mode 100644 index 00000000..a3131852 --- /dev/null +++ b/crates/ui/src/tui/readings/render/chart.rs @@ -0,0 +1,272 @@ +use std::iter; + +use cursor::{CursorData, TooInaccurate}; +use protocol::reading; +use ratatui::{ + layout::{Alignment, Rect}, + style::{Color, Style}, + symbols, + text::{Line, Text}, + widgets::{Axis, Block, Chart, Clear, Dataset, GraphType}, + Frame, +}; + +use crate::{ + time::format::progressively_more_specified::FmtScale, + tui::readings::{sensor_info::ChartParts, UiState}, +}; + +mod cursor; +mod labels; +mod split; + +/// mul then add to get original from points between 0 and 1 +#[derive(Debug)] +struct Scaling { + mul: f64, + add: f64, +} + +impl Scaling { + fn to_normalize([min, max]: Bounds) -> Self { + Self { + mul: max - min, + add: -min, + } + } + fn normalized(&self, y: f64) -> f64 { + (y + self.add) / self.mul + } +} + +// excludes: +// - light colors: same as the normal colors on some terminals +// - gray: to light to see +// - magenta: looks the same as red +const ALL_COLORS: &[Color] = &[ + Color::Black, + Color::Red, + Color::Green, + Color::Yellow, + Color::Blue, + Color::Cyan, + Color::DarkGray, +]; + +fn plot_colors(unit: protocol::Unit) -> impl Iterator { + use protocol::Unit as U; + use Color::*; + + let preferred = match unit { + U::Pa => &[Black, Cyan, Blue] as &'static [Color], + U::C => &[Red] as &'static [Color], + U::RH => &[Blue, Cyan] as &'static [Color], + U::Lux => &[Yellow] as &'static [Color], + U::Ohm => &[DarkGray] as &'static [Color], + U::Ppm | U::MicrogramPerM3 | U::NumberPerCm3 | U::NanoMeter => { + &[Green, Cyan] as &'static [Color] + } + U::None => &[] as &'static [Color], + U::RelativePower => &[Red] as &'static [Color], + }; + preferred.iter().chain(ALL_COLORS.iter()).copied() +} + +pub fn render(frame: &mut Frame, layout: Rect, ui: &mut UiState, charts: &mut [ChartParts]) { + let (colors, merged_y_bounds) = bounds_and_colors(charts, layout); + let (y_labels, y_title) = labels::y_and_title(&merged_y_bounds, layout); + + let (x_labels, x_title, scale) = labels::x_and_title(layout, &ui.plot_range); + let data_bounds = ui.plot_range.data_bounds(); + + let x_axis = Axis::default() + .title(x_title) + .style(Style::default()) + .bounds(data_bounds) + .labels(x_labels) + .labels_alignment(Alignment::Center); + + let y_axis_width = y_labels.iter().map(|l| l.len()).max().unwrap_or(0) as u16; + let y_axis = Axis::default() + .title(y_title) + .style(Style::default()) + .bounds([0.0, 1.0]) + .labels(y_labels); + + let chart_width = layout.width - y_axis_width - 3; + let cursor = if let Some(steps) = ui.chart_cursor.get(chart_width) { + Some(CursorData::new(steps, data_bounds, charts, chart_width)) + } else { + None + }; + + let datasets = datasets(charts, &colors, merged_y_bounds, layout); + let linechart = Chart::new(datasets) + .block(Block::bordered().title("History")) + .x_axis(x_axis) + .y_axis(y_axis); + frame.render_widget(linechart, layout); + + if charts.len() > 1 || cursor.is_some() { + render_legend(layout, frame, charts, colors, cursor, scale); + } + if let Some(steps) = ui.chart_cursor.get(chart_width) { + cursor::render(layout, frame, steps, y_axis_width); + } +} + +fn datasets<'a>( + charts: &'a mut [ChartParts], + colors: &Vec, + mut merged_y_bounds: Vec<(reading::Info, [f64; 2])>, + layout: Rect, +) -> Vec> { + let datasets = charts + .iter_mut() + .zip(colors.iter()) + .flat_map(|(chart, color)| { + let (_, y_bounds) = merged_y_bounds + .iter_mut() + .find(|(info, _)| info.unit == chart.info.unit) + .expect("made bound for every chart"); + let scaling = Scaling::to_normalize(*y_bounds); + + for (_, y) in chart.data.iter_mut() { + *y = scaling.normalized(*y) + } + + let color = color.clone(); + split::split(chart, layout.width).map(move |line| { + Dataset::default() + .marker(symbols::Marker::Braille) + .graph_type(GraphType::Line) + .style(Style::default().fg(color)) + .data(line) + }) + }) + .collect(); + datasets +} + +fn bounds_and_colors( + charts: &mut [ChartParts], + layout: Rect, +) -> (Vec, Vec<(reading::Info, [f64; 2])>) { + let mut colors: Vec = Vec::new(); + // same order as charts + let mut merged_y_bounds: Vec<(reading::Info, [f64; 2])> = Vec::new(); + 'outer: for chart in charts.iter() { + let color = plot_colors(chart.info.unit) + .find(|color| !colors.contains(&color)) + .clone() + .unwrap_or(Color::Black); + colors.push(color); + let y_bounds = ybounds(chart, layout); + + for (info, existing) in merged_y_bounds.iter_mut() { + if info.unit == chart.info.unit { + existing[0] = existing[0].min(y_bounds[0]); + existing[1] = existing[1].max(y_bounds[1]); + continue 'outer; + } + } + merged_y_bounds.push((chart.info.clone(), y_bounds)); + } + (colors, merged_y_bounds) +} + +fn render_legend( + layout: Rect, + frame: &mut Frame, + charts: &mut [ChartParts], + colors: Vec, + cursor: Option, + scale: FmtScale, +) { + let (values, cursor_label) = if let Some(CursorData { pos, values }) = cursor { + let renderd = labels::fmt(pos, &scale); + let label = format!("cursor: {} {}", renderd, scale); + let label = Line::styled(label, Style::default().bg(Color::Gray)); + (values, Some(label)) + } else { + (Vec::new(), None) + }; + let values = values.into_iter().map(Some).chain(iter::repeat(None)); + + let text: Text = charts + .iter() + .map(|ChartParts { reading, .. }| reading) + .zip(colors) + .zip(values) + .map(fmt_reading) + .chain(cursor_label) + .collect(); + + let area = legend_area(&text, layout); + frame.render_widget(Clear, area); + frame.render_widget(text, area); +} + +fn legend_area(text: &Text, chart: Rect) -> Rect { + let lines = text.iter().count() as u16; + let columns = text + .iter() + .map(|l| l.iter().map(|s| s.content.len() as u16).sum::()) + .max() + .expect("legend is never empty"); + + Rect { + x: chart.right() - columns - 2, + y: chart.top() + 1, + width: columns, + height: lines, + } +} + +fn fmt_reading( + ((reading, color), cursor_value): ( + (&protocol::Reading, Color), + Option>, + ), +) -> Line<'_> { + use protocol::reading::tree::{Item, Tree}; + let mut node = reading as &dyn Tree; + let mut text = node.name(); + + loop { + match node.inner() { + Item::Node(inner) => node = inner, + Item::Leaf(_) => break, + } + text.push('/'); + text.push_str(&node.name()); + } + match cursor_value { + Some(Ok(v)) => text.push_str(&format!(": {0:.1$}", v, reading.info().precision())), + Some(Err(TooInaccurate)) => text.push_str(" x"), + None => (), + } + Line::styled(text, Style::default().fg(color).bg(Color::Gray)) +} + +type Bounds = [f64; 2]; +fn ybounds(chart: &ChartParts, layout: Rect) -> Bounds { + let bounds = chart + .data + .iter() + .map(|(_, y)| y) + .fold([f64::MAX, f64::MIN], |[start, end], y| { + [start.min(*y), end.max(*y)] + }); + let y_range = bounds[1] - bounds[0]; + let margin = 5.0 / layout.height as f64; + + let range = &chart.info.range; + let resolution = chart.info.resolution as f64; + let y_margin = f64::max(y_range * margin, resolution / 2.0); + let bounds = [bounds[0] - y_margin, bounds[1] + y_margin]; + [ + bounds[0].max(*range.start() as f64), + bounds[1].min(*range.end() as f64), + ] +} diff --git a/crates/ui/src/tui/readings/render/chart/cursor.rs b/crates/ui/src/tui/readings/render/chart/cursor.rs new file mode 100644 index 00000000..8be9c47a --- /dev/null +++ b/crates/ui/src/tui/readings/render/chart/cursor.rs @@ -0,0 +1,123 @@ +use ratatui::prelude::Rect; +use ratatui::text::Span; +use ratatui::widgets::Clear; + +use crate::tui::readings::sensor_info::ChartParts; + +#[derive(Debug, Clone, Copy)] +pub struct TooInaccurate; + +pub struct CursorData { + pub pos: f64, + /// None means too far from cursor pos to be accurate + pub values: Vec>, +} +impl CursorData { + pub(crate) fn new( + steps: u16, + x_bounds: [f64; 2], + charts: &mut [ChartParts], + chart_width: u16, + ) -> Self { + let pos = resolve_pos(steps, x_bounds, chart_width).clamp(0.0, f64::MAX); + + // chart data has x axis reversed correct + // for that here + let flipped_pos = x_bounds[1] - pos; + // one character + let max_deviation = (x_bounds[1] - x_bounds[0]) / chart_width as f64; + let values = find_values(flipped_pos, max_deviation, charts); + CursorData { pos, values } + } +} + +/// # panics +/// if x is not >= ax and <= db +fn interpolate(a: (f64, f64), b: (f64, f64), x: f64) -> f64 { + assert!(x >= a.0); + assert!(x <= b.0); + + let dx = b.0 - a.0; + let dy = b.1 - a.1; + let dydx = dy / dx; + let delta_x = x - a.0; + + a.1 + delta_x * dydx +} + +/// do not interpolate large gaps +fn maybe_interpolate( + a: (f64, f64), + b: (f64, f64), + x: f64, + max_deviation: f64, +) -> Result { + if b.0 - a.0 > max_deviation { + if b.0 - x < max_deviation { + Ok(b.1) + } else if x - a.0 < max_deviation { + Ok(a.1) + } else { + Err(TooInaccurate) + } + } else { + Ok(interpolate(a, b, x)) + } +} + +fn find_values( + pos: f64, + max_deviation: f64, + charts: &mut [ChartParts], +) -> Vec> { + charts + .iter() + .map(|ChartParts { data, .. }| data) + .map(|data| { + let mut left = None; + let mut right = None; + for (x, y) in data.iter() { + if *x < pos { + left = Some((*x, *y)); + } else { + right = Some((*x, *y)); + break; + } + } + (left, right) + }) + .map(|(left, right)| match (left, right) { + (None, None) => Err(TooInaccurate), + (None, Some((x, y))) | (Some((x, y)), None) => { + if (pos - x).abs() <= max_deviation { + Ok(y) + } else { + Err(TooInaccurate) + } + } + (Some(a), Some(b)) => maybe_interpolate(a, b, pos, max_deviation), + }) + .collect() +} + +pub(crate) fn resolve_pos(steps: u16, x_bounds: [f64; 2], chart_width: u16) -> f64 { + let bounds_width = x_bounds[1] - x_bounds[0]; + let dist = bounds_width / chart_width as f64; + x_bounds[1] - dist * steps as f64 +} + +pub(crate) fn render(chart: Rect, frame: &mut ratatui::Frame, steps: u16, axis_label_width: u16) { + let left = chart + .left() + .saturating_add(steps) + .saturating_add(axis_label_width) + .saturating_add(2); + let area = Rect { + x: left.clamp(chart.x, chart.x + chart.width - 2), + y: chart.bottom() - 3, + width: 1, + height: 1, + }; + frame.render_widget(Clear, area); + frame.render_widget(Span::raw("*"), area); +} diff --git a/crates/ui/src/tui/readings/render/chart/labels.rs b/crates/ui/src/tui/readings/render/chart/labels.rs new file mode 100644 index 00000000..a80b80de --- /dev/null +++ b/crates/ui/src/tui/readings/render/chart/labels.rs @@ -0,0 +1,114 @@ +use std::time::Duration; + +use protocol::reading; +use ratatui::layout::Rect; +use ratatui::text::Span; + +use crate::time::format::progressively_more_specified::{self, FmtScale}; +use crate::tui::readings::plot_range::PlotRange; + +use super::Bounds; + +const Y_LABEL_SPACING: u16 = 10; + +pub fn y_and_title( + merged_y_bounds: &Vec<(reading::Info, [f64; 2])>, + layout: Rect, +) -> (Vec, String) { + let mut title = String::new(); + let mut labels = Vec::new(); + for (info, y_bounds) in merged_y_bounds.iter() { + title.push_str(&info.unit.to_string()); + title.push(' '); + + let new = y_labels(info, layout, *y_bounds); + if labels.is_empty() { + labels = new; + } else { + for (existing, new) in labels.iter_mut().zip(new) { + existing.push(' '); + existing.push_str(new.as_str()); + } + } + } + (labels, title) +} + +fn y_labels( + info: &reading::Info, + layout: Rect, + y_bounds: Bounds, +) -> Vec { + use reading::LabelPositions as L; + // Characters are about twice as high as wide + match info.label_formatter.positions() { + L::Flexible => evenly_spaced_ylabels( + layout.height / Y_LABEL_SPACING, + info.resolution as f64, + y_bounds, + ) + .map(|y| info.label_formatter.format(y, &info)) + .collect(), + L::Fixed(at) => at + .into_iter() + .map(|y| info.label_formatter.format(*y, &info)) + .collect(), + } +} + +type Labels = Vec>; +pub fn x_and_title( + layout: Rect, + plot_range: &PlotRange, +) -> (Labels, String, FmtScale) { + // Characters are about twice as high as wide + let max_labels = layout.width / Y_LABEL_SPACING / 2; + let n_labels = max_labels.max(2); + + let bounds = plot_range.label_bounds(); + let spacing = (bounds[1] - bounds[0]) / n_labels as f64; + + let scale = scale(bounds[1]); + let mut labels: Labels = (0..=n_labels) + .map(move |i| bounds[0] + spacing * i as f64) + .rev() + .map(|x| fmt(x, &scale)) + .map(Into::into) + .collect(); + + let borrowed = labels.first_mut().expect("min labels is 2"); + let owned = std::mem::take(borrowed); + labels[0] = plot_range.style_left_x_label(owned); + + let title = format!("Time ({scale})"); + (labels, title, scale) +} + +pub fn fmt(x: f64, scale: &progressively_more_specified::FmtScale) -> String { + let now = jiff::Timestamp::now(); + let elapsed = Duration::from_secs_f64(x); + let time = now - elapsed; + scale.render(time, elapsed, "") +} + +pub fn scale(secs: f64) -> progressively_more_specified::FmtScale { + assert!(secs >= 0.0, "Argument must be larger then or equal to zero"); + let now = jiff::Timestamp::now(); + let elapsed = Duration::from_secs_f64(secs); + let time = now - elapsed; + + progressively_more_specified::FmtScale::optimal_for(time, elapsed) +} + +fn evenly_spaced_ylabels( + max_labels: u16, + resolution: f64, + bounds: Bounds, +) -> impl DoubleEndedIterator { + let steps_in_data = (bounds[1] - bounds[0]) / resolution; + + let n_labels = max_labels.min(steps_in_data as u16).max(2); + + let y_spacing = (bounds[1] - bounds[0]) / n_labels as f64; + (0..=n_labels).map(move |i| bounds[0] + y_spacing * i as f64) +} diff --git a/crates/ui/src/tui/readings/render/chart/split.rs b/crates/ui/src/tui/readings/render/chart/split.rs new file mode 100644 index 00000000..12726d17 --- /dev/null +++ b/crates/ui/src/tui/readings/render/chart/split.rs @@ -0,0 +1,109 @@ +use std::iter; + +use itertools::Itertools; + +use crate::tui::readings::sensor_info::ChartParts; + +/// split data into separate lines if +/// - the gap between point groups is larger then what is expected for +/// the given sensor with 20% margin +/// +/// and +/// - the gap is larger then the medium in the data +/// +/// # Note +/// the splits line groups are returned from right to left +/// +// An alternative would have been to use the median though that is slower and +// we have this information anyway +pub(crate) fn split<'a>( + chart: &'a ChartParts, + chart_width: u16, +) -> impl Iterator { + let min_dist = + chart.info.device.info().max_sample_interval.as_secs_f64() * 1.2; // 20% margin + + let chart_resolution = chart + .data + .first() + .map(|(x, _)| x) + .and_then(|start| chart.data.last().map(|(x, _)| (start, x))) + .map(|(start, end)| end - start) + .map(|x_len| x_len / (chart_width as f64)) + .unwrap_or(f64::MIN); + + let min_dist = min_dist.max(chart_resolution); + + let splits = chart + .data + .iter() + .map(|(x, _)| x) + .enumerate() + .rev() + .tuple_windows() + .filter(move |((_, b), (_, a))| **b - **a > min_dist) + .map(|((ib, _), _)| ib); + + let mut data = &*chart.data; + splits.chain(iter::once(0)).map(move |mid| { + let (left, line) = data.split_at(mid); + data = left; + line + }) +} + +#[cfg(test)] +mod test { + use protocol::reading::FloatLabelFormatter; + use protocol::{large_bedroom, Device}; + + use super::*; + + fn test_data() -> Vec<(f64, f64)> { + let mut data = Vec::new(); + for segment in 0..5 { + let x = ((segment * 100)..(segment * 100 + 5)).into_iter(); + data.extend(x.map(|x| (x as f64, 5.0))); + } + data + } + + #[test] + fn test_split() { + let mut test_data = test_data(); + let test_chart = ChartParts { + info: protocol::reading::Info { + val: 0.0, + device: Device::LargeBedroom(large_bedroom::Device::Bed( + large_bedroom::bed::Device::Bme680, + )), + resolution: 1.0, + range: 0.0..=200.0, + unit: protocol::Unit::C, + description: "test", + branch_id: 1, + label_formatter: Box::new(FloatLabelFormatter), + }, + data: &mut test_data, + reading: protocol::Reading::LargeBedroom( + large_bedroom::Reading::Bed( + large_bedroom::bed::Reading::GassResistance(0.0), + ), + ), + }; + assert_eq!(split(&test_chart, 500).count(), 5); + assert_eq!( + split(&test_chart, 500).next(), + Some( + [ + (400.0, 5.0), + (401.0, 5.0), + (402.0, 5.0), + (403.0, 5.0), + (404.0, 5.0) + ] + .as_slice() + ) + ); + } +} diff --git a/crates/ui/src/tui/readings/render/logs.rs b/crates/ui/src/tui/readings/render/logs.rs new file mode 100644 index 00000000..0b7fcc86 --- /dev/null +++ b/crates/ui/src/tui/readings/render/logs.rs @@ -0,0 +1,168 @@ +use std::ops::Bound; + +use jiff::tz::TimeZone; +use jiff::Zoned; +use log_store::api::ErrorEvent; +use ratatui::layout::{Constraint, Direction, Flex, Layout, Rect}; +use ratatui::style::{Color, Modifier, Style, Stylize}; +use ratatui::text::Text; +use ratatui::widgets::{Cell, HighlightSpacing, Row, Table, TableState}; +use ratatui::Frame; + +use crate::time::format::progressively_more_specified::FmtScale; +use crate::tui::readings::sensor_info::{LogList, LogSource}; + +use super::centered_text; + +pub fn render_log_range((start, stop): (Bound, Bound)) -> String { + let start = match start { + Bound::Included(start) | Bound::Excluded(start) => { + let elapsed = start.duration_until(jiff::Timestamp::now()).unsigned_abs(); + FmtScale::optimal_for(start, elapsed).render(start, elapsed, " ago") + } + Bound::Unbounded => unreachable!("unbounded not allowed for log range start"), + }; + let stop = match stop { + Bound::Included(stop) | Bound::Excluded(stop) => { + let elapsed = stop.duration_until(jiff::Timestamp::now()).unsigned_abs(); + FmtScale::optimal_for(stop, elapsed).render(stop, elapsed, " ago") + } + Bound::Unbounded => "now".to_owned(), + }; + + format!("{start} and {stop}") +} + +pub fn render( + frame: &mut Frame, + layout: Rect, + table_state: &mut TableState, + logs: Option, + theme: &super::Theme, +) { + match logs { + Some(LogList { + items, + source: LogSource::Store, + covers, + }) => { + if items.is_empty() { + let text = format!("No logs between {}", render_log_range(covers)); + centered_text(&text, frame, layout, theme) + } else { + render_table(frame, layout, table_state, items) + } + } + Some(LogList { + items, + source: LogSource::Local, + covers, + }) => { + let [status, layout] = Layout::new( + Direction::Vertical, + [Constraint::Max(1), Constraint::Fill(1)], + ) + .areas(layout); + + centered_text( + "Loading additional logs from store ..", + frame, + status, + theme, + ); + if items.is_empty() { + let text = format!("No local logs between {}", render_log_range(covers)); + centered_text(&text, frame, layout, theme) + } else { + render_table(frame, layout, table_state, items); + } + } + None => centered_text("This item can not have logs", frame, layout, theme), + } +} + +pub fn render_table( + frame: &mut Frame, + layout: Rect, + table_state: &mut TableState, + logs: Vec, +) { + let header_style = Style::default().fg(Color::Black).bg(Color::Gray); + let selected_style = Style::default() + .add_modifier(Modifier::REVERSED) + .fg(Color::White); + + let header = ["Error", "Started at", "Cleared at"] + .into_iter() + .map(Cell::from) + .collect::() + .style(header_style) + .height(1); + + let longest_error_msg = logs + .iter() + .map(|ErrorEvent { error, .. }| error.to_string().chars().count() as u16) + .max() + .unwrap_or_default(); + + let now = Zoned::now(); + let rows = logs + .into_iter() + .rev() + .enumerate() + .map(|(i, ErrorEvent { start, end, error })| { + let color = match i % 2 { + 0 => Color::Gray, + _ => Color::White, + }; + + let start = start.to_zoned(TimeZone::system()); + let start = if start.day() == now.day() && start.year() == now.year() { + format!("{}", start.strftime("%H:%M:%S")) + } else { + format!("{}", start.strftime("%D %H:%M:%S")) + }; + + let end = if let Some(end) = end { + let end = end.to_zoned(TimeZone::system()); + if end.day() == now.day() && end.year() == now.year() { + format!("{}", end.strftime("%H:%M:%S")) + } else { + format!("{}", end.strftime("%D %H:%M:%S")) + } + } else { + "ongoing".to_owned() + }; + let item = [format!("{error}"), start, end]; + item.into_iter() + .map(Text::from) + .map(Cell::from) + .collect::() + .style(Style::new().fg(Color::Black).bg(color)) + .height(1) + }); + + let bar = " â–ˆ "; + let table = Table::new( + rows, + [ + Constraint::Max(longest_error_msg), + Constraint::Max(18), + Constraint::Max(18), + ], + ) + .header(header) + .flex(Flex::SpaceAround) + .column_spacing(1) + .row_highlight_style(selected_style) + .highlight_symbol(Text::from(vec![ + "".into(), + bar.into(), + bar.into(), + "".into(), + ])) + .bg(Color::White) + .highlight_spacing(HighlightSpacing::Always); + + frame.render_stateful_widget(table, layout, table_state); +} diff --git a/crates/ui/src/tui/readings/render/time.rs b/crates/ui/src/tui/readings/render/time.rs new file mode 100644 index 00000000..e69de29b diff --git a/crates/ui/src/tui/readings/render/tree.rs b/crates/ui/src/tui/readings/render/tree.rs new file mode 100644 index 00000000..6275259d --- /dev/null +++ b/crates/ui/src/tui/readings/render/tree.rs @@ -0,0 +1,95 @@ +use std::collections::HashSet; + +use indextree::Arena; +use ratatui::style::{Style, Stylize}; +use ratatui::text::Text; +use tui_tree_widget::TreeItem; + +use crate::tui::readings::sensor_info::{Node, Readings, SensorInfo}; + +#[derive(Default)] +struct IdGen(u16); + +impl IdGen { + fn next(&mut self) -> u16 { + self.0 += 1; + assert!(self.0 < 10_000, "to many id's generated"); + self.0 + } +} + +pub(crate) fn build_ui<'a>( + readings: &'a Readings, + comparing: &HashSet, +) -> Vec> { + let mut id_gen = IdGen::default(); + + readings + .root + .children(&readings.arena) + .map( + |subroot| match readings.arena.get(subroot).expect("child exists").get() { + Node::Sensor(info) => new_leaf(info, comparing), + Node::Branch(name) => TreeItem::new( + id_gen.next(), + name.as_str(), + recusive_call(subroot, &readings.arena, &mut id_gen, comparing), + ) + .expect("no duplicate ids"), + Node::Root => unreachable!("Root is not a descendant"), + }, + ) + .collect() +} + +fn recusive_call<'a>( + root: indextree::NodeId, + arena: &'a Arena, + id_gen: &mut IdGen, + comparing: &HashSet, +) -> Vec> { + root.children(arena) + .map(|child_id| { + let child_node = arena.get(child_id).expect("child exists").get(); + match child_node { + Node::Sensor(info) => new_leaf(info, comparing), + Node::Branch(name) => TreeItem::new( + id_gen.next(), + name.as_str(), + recusive_call(child_id, arena, id_gen, comparing), + ) + .expect("no duplicate ids"), + Node::Root => unreachable!("Root is not a descendant"), + } + }) + .collect() +} + +fn new_leaf<'a>(info: &'a SensorInfo, comparing: &HashSet) -> TreeItem<'a, u16> { + use protocol::reading::tree::{Item, Tree}; + + let mut node = &info.reading as &dyn Tree; + while let Item::Node(inner) = node.inner() { + node = inner; + } + + let style = if comparing.contains(&info.ui_id) { + Style::new().italic().blue() + } else { + Style::new() + }; + + let text = if info.is_placeholder { + node.name() + } else { + format!( + "{0}: {1:.2$} {3}", + node.name(), + info.info.val, + info.info.precision(), + info.info.unit + ) + }; + + TreeItem::new_leaf(info.ui_id, Text::styled(text, style)) +} diff --git a/crates/ui/src/tui/readings/sensor_info.rs b/crates/ui/src/tui/readings/sensor_info.rs new file mode 100644 index 00000000..7969472e --- /dev/null +++ b/crates/ui/src/tui/readings/sensor_info.rs @@ -0,0 +1,502 @@ +use hdrhistogram::Histogram; +use indextree::{Arena, NodeId}; +use itertools::Itertools; +use jiff::Unit; +use log_store::api::{self, Percentile}; +use protocol::{reading, IsSameAs}; +use protocol::reading::tree::{Item, Tree}; +use protocol::Reading; +use protocol::{Device, Error}; + +use std::ops::RangeInclusive; + +use crate::Fetchable; + +mod logs; +pub(crate) use logs::List as LogList; +pub(crate) use logs::LogSource; + +use super::plot_range; + +#[derive(Debug)] +pub(crate) enum Cover { + Overlapping { + store: RangeInclusive, + local: RangeInclusive, + }, + OnlyLocal(RangeInclusive), + OnlyStore(RangeInclusive), + Distinct { + store: RangeInclusive, + local: RangeInclusive, + }, + None, +} + +#[expect( + clippy::large_enum_variant, + reason = "Stored on the heap through Vec, mem waste of Branches is \ + worth the perf of not boxing SensorInfo" +)] +#[derive(Debug)] +pub enum Node { + Sensor(SensorInfo), + Branch(String), + Root, +} + +#[derive(derivative::Derivative)] +#[derivative(Debug)] +pub struct SensorInfo { + /// unique id used by the rendered tree to refer back to + /// this specific item. + pub ui_id: u16, + #[derivative(Debug = "ignore")] + pub info: reading::Info, + /// This value is not up to date, only use for requesting + /// data use the last element of recent_history for printing + pub reading: Reading, + #[derivative(Debug = "ignore")] + timing: Histogram, + #[derivative(Debug = "ignore")] + pub percentiles_from_store: Vec, + #[derivative(Debug = "ignore")] + recent_history: Vec<(jiff::Timestamp, f32)>, + pub histogram_range: Option>, + #[derivative(Debug = "ignore")] + pub history_from_store: Vec<(jiff::Timestamp, f32)>, + condition: Result<(), Box>, + #[derivative(Debug = "ignore")] + pub(crate) logs: logs::Logs, + pub is_placeholder: bool, +} + +impl SensorInfo { + fn new(reading: &Reading, is_placeholder: bool, ui_id: u16) -> Self { + let time = jiff::Timestamp::now(); + let recent_history = if is_placeholder { + Vec::new() + } else { + vec![(time, reading.info().val)] + }; + + Self { + info: reading.info(), + reading: reading.clone(), + timing: Histogram::new_with_bounds(1, 60 * 60 * 1000, 2).unwrap(), + percentiles_from_store: Vec::new(), + histogram_range: None, + + recent_history, + history_from_store: Vec::new(), + + condition: Ok(()), + logs: logs::Logs::new_empty(), + is_placeholder, + ui_id, + } + } + + fn new_err(error: &Error, broken: &Reading, ui_id: u16) -> Self { + let logs = logs::Logs::new_from(error); + SensorInfo { + info: broken.info(), + reading: broken.clone(), + timing: Histogram::new_with_bounds(1, 60 * 60 * 1000, 2).unwrap(), + percentiles_from_store: Vec::new(), + histogram_range: None, + + recent_history: Vec::new(), + history_from_store: Vec::new(), + + condition: Err(Box::new(error.clone())), + logs, + is_placeholder: true, + ui_id, + } + } + + fn update(&mut self, reading: &Reading) { + let time = jiff::Timestamp::now(); + self.info = reading.info(); + if let Some(last_reading) = self.last_at() { + self.timing += (time - last_reading) + .total(Unit::Millisecond) + .expect("no calander units involved") as u64 + } + self.recent_history.push((time, reading.info().val)); + self.is_placeholder = false; + self.condition = Ok(()); + } +} + +pub struct ErrorDensity { + pub t5_min: f32, + pub t15_min: f32, + pub t30_min: f32, + pub t45_min: f32, + pub t60_min: f32, +} + +impl ErrorDensity { + fn from_log(log: &logs::Logs) -> Self { + let buckets = [5, 15, 30, 45, 60].map(|min| jiff::Span::new().minutes(min)); + let counts = log.density(buckets); + + Self { + t5_min: counts[0], + t15_min: counts[1], + t30_min: counts[2], + t45_min: counts[3], + t60_min: counts[4], + } + } +} + +pub struct Details { + pub last_reading: Option<(jiff::Timestamp, String)>, + pub condition: Result<(), Box>, + pub description: String, + pub errors_since: ErrorDensity, +} + +impl SensorInfo { + fn last_at(&self) -> Option { + self.condition.clone().ok(); + self.recent_history.last().map(|(ts, _)| ts).copied() + } + + pub fn details(&self) -> Details { + let last_reading = self.recent_history.last().copied().map(|(ts, val)| { + let val = format!("{0:.1$} {2}", val, self.info.precision(), self.info.unit); + (ts, val) + }); + Details { + last_reading, + condition: self.condition.clone(), + description: self.info.description.to_owned(), + errors_since: ErrorDensity::from_log(&self.logs), + } + } + + pub fn percentiles(&self) -> Vec { + let older_then_15s = |range: &RangeInclusive| { + jiff::Timestamp::now() + .since(*range.end()) + .unwrap() + .get_seconds() + > 15 + }; + + if self.histogram_range.is_none() + || self.histogram_range.as_ref().is_some_and(older_then_15s) + { + self.fallback_local_hist() + } else { + self.percentiles_from_store.clone() + } + } + + pub fn fallback_local_hist(&self) -> Vec { + self.timing + .iter_quantiles(1) + .map(|it| log_store::api::Percentile { + percentile: it.percentile(), + bucket_ends: it.value_iterated_to(), + count_in_bucket: it.count_at_value(), + }) + .dedup_by(|a, b| { + a.bucket_ends == b.bucket_ends + && a.percentile.total_cmp(&b.percentile).is_eq() + && a.count_in_bucket == b.count_in_bucket + }) + .collect_vec() + } + + pub fn chart<'a>( + &mut self, + plot_buf: &'a mut Vec<(f64, f64)>, + range: &plot_range::Range, + ) -> ChartParts<'a> { + let start = *range.range_inclusive().start(); + let before_start = |t: &jiff::Timestamp| t < &start; + + let first_recent = self.recent_history.first().map(|(t, _)| t).cloned(); + let not_recent = |t: &jiff::Timestamp| !first_recent.is_some_and(|recent| t > &recent); + + let end = *range.range_inclusive().end(); + let before_end = |t: &jiff::Timestamp| t < &end; + + plot_buf.clear(); + let plot = self + .history_from_store + .iter() + .take_while(|(t, _)| not_recent(t)) + .chain(self.recent_history.iter()) + .skip_while(|(t, _)| before_start(t)) + .take_while(|(t, _)| before_end(t)) + .collect_vec(); + + for (x, y) in plot { + plot_buf.push(( + (*x - start) + .total(jiff::Unit::Second) + .expect("unit is not a calander unit"), + *y as f64, + )) + } + + for (i, (x, _)) in plot_buf.iter().enumerate() { + assert!( + *x >= 0.0, + "negative x is not allowed. Info: + \t x: {x}, + \t index: {i}, + \t range: {range:?} + \t first_recent: {first_recent:?} + \t start: {start}" + ); + } + + ChartParts { + info: self.info.clone(), + reading: self.reading.clone(), + data: plot_buf, + } + } + + pub(crate) fn logs(&self) -> logs::List { + self.logs.list() + } + + pub(crate) fn covers(&self) -> Cover { + use jiff::Timestamp as Ts; + let are_overlapping = + |store: &RangeInclusive, local: &RangeInclusive| local.start() <= store.end(); + + match ( + self.history_from_store + .first() + .map(|(ts, _)| ts) + .zip(self.history_from_store.last().map(|(ts, _)| ts)) + .map(|(a, b)| *a..=*b), + self.recent_history + .first() + .map(|(ts, _)| ts) + .zip(self.recent_history.last().map(|(ts, _)| ts)) + .map(|(a, b)| *a..=*b), + ) { + (None, None) => Cover::None, + (None, Some(local)) => Cover::OnlyLocal(local), + (Some(store), None) => Cover::OnlyStore(store), + (Some(store), Some(local)) if are_overlapping(&store, &local) => { + Cover::Overlapping { store, local } + } + (Some(store), Some(local)) => Cover::Distinct { store, local }, + } + } +} + +pub struct IdGen(u16); +impl IdGen { + fn new() -> Self { + Self(10_000) + } + fn next(&mut self) -> u16 { + self.0 += 1; + self.0 + } +} + +pub fn is_leaf_id(id: u16) -> bool { + id > 10_000 +} + +/// Guaranteed to be unique for a leaf, +/// the path to the leaf (through branch-id's) is +/// encoded with the last byte byte being the leaf's id +pub type TreeKey = [u8; 6]; +pub struct Readings { + pub lookup_by_reading: Vec<(Reading, indextree::NodeId)>, + pub lookup_by_ui_id: Vec<(u16, indextree::NodeId)>, + pub arena: indextree::Arena, + pub root: NodeId, + pub idgen: IdGen, +} + +impl Readings { + pub fn get_by_ui_id(&mut self, id: u16) -> Option<&mut SensorInfo> { + self.lookup_by_ui_id + .iter_mut() + .find(|(ui_id, _)| id == *ui_id) + .map(|(_, node_id)| node_id) + .and_then(|id| self.arena.get_mut(*id)) + .map(indextree::Node::get_mut) + .map(|node| match node { + Node::Sensor(info) => info, + Node::Branch(_) | Node::Root => { + unreachable!("Only Sensor nodes are put in the lookup table") + } + }) + } + + pub fn update(&mut self, reading: Reading) { + self.update_tree(&reading, false); + } + + pub(crate) fn populate_from_reading_list(&mut self, list: Vec) { + for reading in list { + self.update_tree(&reading, true); + } + } + + pub(crate) fn populate_from_device_list(&mut self, list: Vec) { + for reading in list.iter().flat_map(|d| d.info().affects_readings) { + self.update_tree(reading, true); + } + } + + pub fn add_error(&mut self, error: Box) { + self.update_tree_err(&error); + } + + fn update_tree(&mut self, reading: &Reading, is_placeholder: bool) { + let existing = self + .lookup_by_reading + .iter() + .find(|(r, _)| r.is_same_as(reading)) + .map(|(_, id)| id) + .and_then(|id| self.arena.get_mut(*id)) + .map(indextree::Node::get_mut); + + if let Some(node) = existing { + let Node::Sensor(ref mut info) = node else { + panic!("got other node then Sensor for reading"); + }; + + if is_placeholder { + return; // can receive sensor update before populating from list + } + info.update(reading); + } else { + let ui_id = self.idgen.next(); + let info = SensorInfo::new(reading, is_placeholder, ui_id); + let node_id = self.arena.new_node(Node::Sensor(info)); + let parent = build_parents(&mut self.arena, self.root, reading); + parent.append(node_id, &mut self.arena); + self.lookup_by_reading.push((reading.clone(), node_id)); + self.lookup_by_ui_id.push((ui_id, node_id)); + } + } + + fn update_tree_err(&mut self, error: &Error) { + for broken in error.device().info().affects_readings { + let existing = self + .lookup_by_reading + .iter() + .find(|(r, _)| r.is_same_as(broken)) + .map(|(_, id)| id) + .and_then(|id| self.arena.get_mut(*id)) + .map(indextree::Node::get_mut); + + if let Some(node) = existing { + let Node::Sensor(ref mut info) = node else { + panic!("got other node then Sensor for Error"); + }; + info.condition = Err(Box::new(error.clone())); + info.logs.add(error); + } else { + let ui_id = self.idgen.next(); + let info = SensorInfo::new_err(error, broken, ui_id); + let node_id = self.arena.new_node(Node::Sensor(info)); + self.lookup_by_reading.push((broken.clone(), node_id)); + self.lookup_by_ui_id.push((ui_id, node_id)); + } + } + } + + pub(crate) fn add_fetched(&mut self, reading: Reading, fetched: Fetchable) { + let Node::Sensor(info) = self + .lookup_by_reading + .iter() + .find(|(r, _)| r.is_same_as(&reading)) + .map(|(_, id)| id) + .and_then(|id| self.arena.get_mut(*id)) + .map(indextree::Node::get_mut) + .expect("Data can only be fetched if it exists in the tree") + else { + panic!("Node for a reading should always be a sensornode"); + }; + + match fetched { + Fetchable::Data { timestamps, data } => { + info.history_from_store = timestamps.into_iter().zip(data).collect(); + } + Fetchable::Logs { logs, start_at } => { + info.logs.from_store = Some(logs::FromStore { + list: logs, + since: start_at, + }) + } + Fetchable::Hist { percentiles, range } => { + info.percentiles_from_store = percentiles; + info.histogram_range = Some(range); + } + } + } + + pub(crate) fn new() -> Self { + let mut arena = Arena::new(); + let root = arena.new_node(Node::Root); + Self { + lookup_by_reading: Vec::new(), + lookup_by_ui_id: Vec::new(), + arena, + root, + idgen: IdGen::new(), + } + } +} + +fn build_parents(arena: &mut Arena, root: NodeId, reading: &Reading) -> NodeId { + let mut curr = reading as &dyn Tree; + let mut parent = root; + loop { + match curr.inner() { + Item::Leaf(_) => return parent, + Item::Node(inner) => { + parent = get_child_by_name(arena, parent, curr.name()).unwrap_or_else(|| { + let new = arena.new_node(Node::Branch(curr.name())); + parent.append(new, arena); + new + }); + curr = inner; + } + } + } +} + +fn get_child_by_name( + arena: &mut Arena, + root: NodeId, + name_to_find: String, +) -> Option { + root.children(arena).find(|node| { + match arena + .get(*node) + .expect("no changes since .children()") + .get() + { + Node::Root => unreachable!("root node is never a child"), + Node::Sensor(_) => false, + Node::Branch(name) => *name == name_to_find, + } + }) +} + +pub struct ChartParts<'a> { + pub info: reading::Info, + pub reading: Reading, + /// array of time, y + pub data: &'a mut [(f64, f64)], +} diff --git a/crates/ui/src/tui/readings/sensor_info/logs.rs b/crates/ui/src/tui/readings/sensor_info/logs.rs new file mode 100644 index 00000000..3ec3d08c --- /dev/null +++ b/crates/ui/src/tui/readings/sensor_info/logs.rs @@ -0,0 +1,169 @@ +use std::ops::{Bound, RangeBounds}; + +use jiff::Unit; +use log_store::api::{self, ErrorEvent}; + +use super::Cover; + +#[derive(Debug)] +pub(crate) struct FromStore { + pub(crate) list: Vec, + pub(crate) since: jiff::Timestamp, +} + +#[derive(Debug)] +pub(crate) struct Local { + pub(crate) list: Vec, + pub(crate) since: jiff::Timestamp, +} + +#[derive(Debug)] +pub(crate) struct Logs { + current: Option, + pub local: Local, + pub from_store: Option, +} + +impl Logs { + pub(crate) fn new_from(error: &protocol::Error) -> Self { + Self { + current: Some(ErrorEvent { + start: jiff::Timestamp::now(), + end: None, + error: error.clone(), + }), + local: Local { + list: Vec::new(), + since: jiff::Timestamp::now(), + }, + from_store: None, + } + } + + pub(crate) fn new_empty() -> Self { + Self { + current: None, + local: Local { + list: Vec::new(), + since: jiff::Timestamp::now(), + }, + from_store: None, + } + } + + pub(crate) fn add(&mut self, new_error: &protocol::Error) { + if let Some(ErrorEvent { start, error, .. }) = self.current.take() { + if &error == new_error { + return; + } + + self.local.list.push(api::ErrorEvent { + start, + end: Some(jiff::Timestamp::now()), + error, + }) + } + + self.current = Some(ErrorEvent { + start: jiff::Timestamp::now(), + end: None, + error: new_error.clone(), + }) + } + + pub(crate) fn density(&self, buckets: [jiff::Span; N]) -> [f32; N] { + let now = jiff::Timestamp::now(); + let mut buckets = buckets.map(|bound| (bound, 0.0)); + for ErrorEvent { start, end, .. } in self.local.list.iter().rev() { + for (bound, count) in &mut buckets { + let bound_start = now - *bound; + let start = start.max(&bound_start); + let end = if let Some(end) = end { end } else { &now }; + let error_time = end.since(*start).expect("duration should fit type"); + if !error_time.is_negative() { + *count += error_time.total(Unit::Second).expect("smaller then day") + / bound.total(Unit::Second).expect("smaller then day"); + } + } + } + buckets.map(|(_, count)| count as f32) + } + + pub(crate) fn list(&self) -> List { + let last = self + .from_store + .as_ref() + .map(|FromStore { list, .. }| list) + .and_then(|list| list.last()) + .map(|ErrorEvent { start, .. }| *start) + .unwrap_or(jiff::Timestamp::from_second(0).unwrap()); + let without_duplicates = self + .local + .list + .iter() + .skip_while(|ErrorEvent { start, .. }| start < &last) + .cloned(); + let mut items = self + .from_store + .as_ref() + .map(|FromStore { list, .. }| list) + .cloned() + .unwrap_or(Vec::new()); + items.extend(without_duplicates); + + let covers = if let Some(ref from_store) = self.from_store { + from_store.since.. + } else { + self.local.since.. + }; + let covers = (covers.start_bound().cloned(), covers.end_bound().cloned()); + + if self.from_store.is_some() { + List { + items, + source: LogSource::Store, + covers, + } + } else { + List { + items, + source: LogSource::Local, + covers, + } + } + } + + pub(crate) fn covers(&self) -> Cover { + let store = self.from_store.as_ref().map(|FromStore { since, list }| { + let until = list + .iter() + .rev() + .filter_map(|ErrorEvent { end, .. }| *end) + .next() + .unwrap_or(*since); + *since..=until + }); + let local = self.local.since..=jiff::Timestamp::now(); + if let Some(store) = store { + let gap = store.end().duration_until(*local.start()); + if gap.is_negative() { + Cover::Overlapping { store, local } + } else { + Cover::Distinct { store, local } + } + } else { + Cover::OnlyLocal(local) + } + } +} + +pub(crate) struct List { + pub items: Vec, + pub source: LogSource, + pub covers: (Bound, Bound), +} + +pub enum LogSource { + Local, + Store, +} diff --git a/crates/ui/src/tui/render.rs b/crates/ui/src/tui/render.rs new file mode 100644 index 00000000..1eda547a --- /dev/null +++ b/crates/ui/src/tui/render.rs @@ -0,0 +1,37 @@ +use ratatui::layout::{Constraint, Flex, Layout, Rect}; +use ratatui::widgets::Tabs; +use ratatui::Frame; + +use super::App; + +pub(super) fn render(frame: &mut Frame, app: &App) -> Rect { + let report_needs_lines = app.reports.needed_lines(); + let constraints = report_needs_lines + .map(Constraint::Max) + .into_iter() + .chain([Constraint::Min(1), Constraint::Fill(1)]); + let layout = Layout::default() + .constraints(constraints) + .flex(Flex::Legacy) + .split(frame.area()); + let mut layout = layout.iter(); + + if report_needs_lines.is_some() { + app.reports + .render(frame, *layout.next().expect("is long enough")) + } + + render_tab_bar(app, frame, *layout.next().expect("is long enough")); + + *layout.next().expect("is long enough") +} + +fn render_tab_bar(app: &App, frame: &mut Frame, topline: Rect) { + let tabs = Tabs::new(vec!["Readings", "Affectors"]) + .style(app.theme.bars) + .select(app.active_tab.number()) + .divider("|") + .padding(" ", " "); + + frame.render_widget(tabs, topline); +} diff --git a/crates/ui/src/tui/reports.rs b/crates/ui/src/tui/reports.rs new file mode 100644 index 00000000..0a7fd7ab --- /dev/null +++ b/crates/ui/src/tui/reports.rs @@ -0,0 +1,144 @@ +use std::collections::{HashSet, VecDeque}; + +use color_eyre::eyre; +use crossterm::event::{KeyCode, KeyEvent}; +use ratatui::layout::{Alignment, Constraint, Layout, Rect}; +use ratatui::style::{Color, Style, Stylize}; +use ratatui::text::Text; +use ratatui::widgets::{Paragraph, Wrap}; +use ratatui::Frame; + +#[derive(Debug, PartialEq, Eq, Hash)] +struct Report { + short: String, + detailed: String, +} + +impl From for Report { + fn from(value: eyre::Report) -> Self { + let detailed = format!("{value:?}"); + let mut detailed = strip_ansi_escapes::strip_str(&detailed); + let last_paragraph = detailed + .rfind("Location:") + .expect("Detailed report always lists a location"); + let backtrace_start = detailed[last_paragraph..] + .find("\n\n") + .map(|pos| pos + last_paragraph); + + if let Some(pos) = backtrace_start { + detailed.truncate(pos); + } + + Self { + short: value.to_string(), + detailed, + } + } +} + +#[derive(Debug, Default)] +pub(super) struct Reports { + list: VecDeque, + current: Option, + to_ignore: HashSet, + show_details: bool, +} + +impl Reports { + pub(super) fn add(&mut self, raw_report: eyre::Report) { + let report = Report::from(raw_report); + tracing::debug!("report: {report:?}"); + if self.to_ignore.contains(&report) { + return; + } + + if let Some(prev) = self.current.take() { + self.list.push_front(prev); + } + self.current = Some(report); + } + + pub(super) fn render(&self, frame: &mut Frame, layout: Rect) { + let current = self.current.as_ref().expect( + "should only be called when current is Some/needed lines > 0", + ); + + let [hint, error] = + Layout::vertical([Constraint::Max(1), Constraint::Min(1)]) + .areas(layout); + + let error_style = Style::default().on_light_red().fg(Color::White); + + if self.show_details { + frame.render_widget( + Text::raw("e: hide details, x: close this error, i: ignore this error") + .alignment(Alignment::Center) + .style(error_style), + hint, + ); + frame.render_widget( + Paragraph::new(current.detailed.as_str()) + .wrap(Wrap { trim: false }) + .style(error_style), + error, + ); + } else { + frame.render_widget( + Text::raw("e: show details, x: close this error, i: ignore this error") + .alignment(Alignment::Center) + .style(error_style), + hint, + ); + frame.render_widget( + Text::raw(¤t.short).style(error_style), + error, + ); + } + } + + pub(super) fn needed_lines(&self) -> Option { + let current = self.current.as_ref()?; + + Some(if self.show_details { + 2 + current.detailed.lines().count() as u16 + } else { + 1 + current.short.lines().count() as u16 + }) + } + + fn close_current(&mut self) { + let Some(current) = self.current.take() else { + return; + }; + + self.list.retain(|report| *report != current); + self.current = self.list.pop_front(); + } + + fn ignore_current(&mut self) { + let Some(current) = self.current.take() else { + return; // may have closed + }; + + self.list.retain(|report| *report != current); + + self.to_ignore.insert(current); + self.close_current() + } + + pub(crate) fn handle_key(&mut self, key: KeyEvent) -> Option { + match key.code { + KeyCode::Char('e') => { + self.show_details = !self.show_details; + } + KeyCode::Char('x') => { + self.close_current(); + } + KeyCode::Char('i') => { + self.ignore_current(); + } + _ => return Some(key), + } + None + } +} diff --git a/crates/usb-bridge/.cargo/config.toml b/crates/usb-bridge/.cargo/config.toml new file mode 100644 index 00000000..0127ae27 --- /dev/null +++ b/crates/usb-bridge/.cargo/config.toml @@ -0,0 +1,5 @@ +[target.aarch64-unknown-linux-musl] +rustflags = ["-Clinker=rust-lld"] + +[target.armv7-unknown-linux-musleabihf] +rustflags = ["-Clinker=rust-lld"] diff --git a/crates/usb-bridge/Cargo.lock b/crates/usb-bridge/Cargo.lock new file mode 100644 index 00000000..ebc632be --- /dev/null +++ b/crates/usb-bridge/Cargo.lock @@ -0,0 +1,2106 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 3 + +[[package]] +name = "addr2line" +version = "0.21.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8a30b2e23b9e17a9f90641c7ab1549cd9b44f296d3ccbf309d2863cfe398a0cb" +dependencies = [ + "gimli", +] + +[[package]] +name = "adler" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe" + +[[package]] +name = "aho-corasick" +version = "1.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e60d3430d3a69478ad0993f19238d2df97c507009a52b3c10addcd7f6bcb916" +dependencies = [ + "memchr", +] + +[[package]] +name = "anstream" +version = "0.6.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "64e15c1ab1f89faffbf04a634d5e1962e9074f2741eef6d97f3c4e322426d526" +dependencies = [ + "anstyle", + "anstyle-parse", + "anstyle-query", + "anstyle-wincon", + "colorchoice", + "is_terminal_polyfill", + "utf8parse", +] + +[[package]] +name = "anstyle" +version = "1.0.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1bec1de6f59aedf83baf9ff929c98f2ad654b97c9510f4e70cf6f661d49fd5b1" + +[[package]] +name = "anstyle-parse" +version = "0.2.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eb47de1e80c2b463c735db5b217a0ddc39d612e7ac9e2e96a5aed1f57616c1cb" +dependencies = [ + "utf8parse", +] + +[[package]] +name = "anstyle-query" +version = "1.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6d36fc52c7f6c869915e99412912f22093507da8d9e942ceaf66fe4b7c14422a" +dependencies = [ + "windows-sys 0.52.0", +] + +[[package]] +name = "anstyle-wincon" +version = "3.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5bf74e1b6e971609db8ca7a9ce79fd5768ab6ae46441c572e46cf596f59e57f8" +dependencies = [ + "anstyle", + "windows-sys 0.52.0", +] + +[[package]] +name = "atomic-polyfill" +version = "1.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8cf2bce30dfe09ef0bfaef228b9d414faaf7e563035494d7fe092dba54b300f4" +dependencies = [ + "critical-section", +] + +[[package]] +name = "atomic-waker" +version = "1.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1505bd5d3d116872e7271a6d4e16d81d0c8570876c8de68093a09ac269d8aac0" + +[[package]] +name = "autocfg" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0c4b4d0bd25bd0b74681c0ad21497610ce1b7c91b1022cd21c80c6fbdd9476b0" + +[[package]] +name = "backtrace" +version = "0.3.71" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "26b05800d2e817c8b3b4b54abd461726265fa9789ae34330622f2db9ee696f9d" +dependencies = [ + "addr2line", + "cc", + "cfg-if", + "libc", + "miniz_oxide", + "object", + "rustc-demangle", +] + +[[package]] +name = "bincode" +version = "1.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b1f45e9417d87227c7a56d22e471c6206462cba514c7590c09aff4cf6d1ddcad" +dependencies = [ + "serde", +] + +[[package]] +name = "bitflags" +version = "1.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" + +[[package]] +name = "bitflags" +version = "2.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b048fb63fd8b5923fc5aa7b340d8e156aec7ec02f0c78fa8a6ddc2613f6f71de" + +[[package]] +name = "bitvec" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1bc2832c24239b0141d5674bb9174f9d68a8b5b3f2753311927c172ca46f7e9c" +dependencies = [ + "funty", + "radium", + "tap", + "wyz", +] + +[[package]] +name = "bumpalo" +version = "3.16.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "79296716171880943b8470b5f8d03aa55eb2e645a4874bdbb28adb49162e012c" + +[[package]] +name = "byteorder" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" + +[[package]] +name = "bytes" +version = "1.7.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "428d9aa8fbc0670b7b8d6030a7fadd0f86151cae55e4dbbece15f3780a3dfaf3" + +[[package]] +name = "cc" +version = "1.1.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "07b1695e2c7e8fc85310cde85aeaab7e3097f593c91d209d3f9df76c928100f0" +dependencies = [ + "shlex", +] + +[[package]] +name = "cfg-if" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" + +[[package]] +name = "clap" +version = "4.5.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b0956a43b323ac1afaffc053ed5c4b7c1f1800bacd1683c353aabbb752515dd3" +dependencies = [ + "clap_builder", + "clap_derive", +] + +[[package]] +name = "clap_builder" +version = "4.5.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4d72166dd41634086d5803a47eb71ae740e61d84709c36f3c34110173db3961b" +dependencies = [ + "anstream", + "anstyle", + "clap_lex", + "strsim", +] + +[[package]] +name = "clap_derive" +version = "4.5.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4ac6a0c7b1a9e9a5186361f67dfa1b88213572f427fb9ab038efb2bd8c582dab" +dependencies = [ + "heck", + "proc-macro2", + "quote", + "syn 2.0.77", +] + +[[package]] +name = "clap_lex" +version = "0.7.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1462739cb27611015575c0c11df5df7601141071f07518d56fcc1be504cbec97" + +[[package]] +name = "cobs" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "67ba02a97a2bd10f4b59b25c7973101c79642302776489e030cd13cdab09ed15" + +[[package]] +name = "color-eyre" +version = "0.6.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "55146f5e46f237f7423d74111267d4597b59b0dad0ffaf7303bce9945d843ad5" +dependencies = [ + "backtrace", + "color-spantrace", + "eyre", + "indenter", + "once_cell", + "owo-colors", + "tracing-error", +] + +[[package]] +name = "color-spantrace" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cd6be1b2a7e382e2b98b43b2adcca6bb0e465af0bdd38123873ae61eb17a72c2" +dependencies = [ + "once_cell", + "owo-colors", + "tracing-core", + "tracing-error", +] + +[[package]] +name = "colorchoice" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d3fd119d74b830634cea2a0f58bbd0d54540518a14397557951e79340abc28c0" + +[[package]] +name = "cordyceps" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ec10f0a762d93c4498d2e97a333805cb6250d60bead623f71d8034f9a4152ba3" +dependencies = [ + "loom 0.5.6", + "tracing", +] + +[[package]] +name = "core-foundation" +version = "0.9.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "91e195e091a93c46f7102ec7818a2aa394e1e1771c3ab4825963fa03e45afb8f" +dependencies = [ + "core-foundation-sys", + "libc", +] + +[[package]] +name = "core-foundation-sys" +version = "0.8.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "773648b94d0e5d620f64f280777445740e61fe701025087ec8b57f45c791888b" + +[[package]] +name = "critical-section" +version = "1.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f64009896348fc5af4222e9cf7d7d82a95a256c634ebcf61c53e4ea461422242" + +[[package]] +name = "crossbeam-utils" +version = "0.8.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "22ec99545bb0ed0ea7bb9b8e1e9122ea386ff8a48c0922e43f36d45ab09e0e80" + +[[package]] +name = "darling" +version = "0.20.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6f63b86c8a8826a49b8c21f08a2d07338eec8d900540f8630dc76284be802989" +dependencies = [ + "darling_core", + "darling_macro", +] + +[[package]] +name = "darling_core" +version = "0.20.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "95133861a8032aaea082871032f5815eb9e98cef03fa916ab4500513994df9e5" +dependencies = [ + "fnv", + "ident_case", + "proc-macro2", + "quote", + "strsim", + "syn 2.0.77", +] + +[[package]] +name = "darling_macro" +version = "0.20.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d336a2a514f6ccccaa3e09b02d41d35330c07ddf03a62165fcec10bb561c7806" +dependencies = [ + "darling_core", + "quote", + "syn 2.0.77", +] + +[[package]] +name = "dashmap" +version = "5.5.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "978747c1d849a7d2ee5e8adc0159961c48fb7e5db2f06af6723b80123bb53856" +dependencies = [ + "cfg-if", + "hashbrown", + "lock_api", + "once_cell", + "parking_lot_core", +] + +[[package]] +name = "data-server" +version = "0.0.0" +dependencies = [ + "clap", + "color-eyre", + "futures", + "futures-concurrency", + "governor", + "protocol", + "rpc", + "serde", + "slotmap", + "socket2", + "thiserror", + "tokio", + "tokio-serde", + "tokio-stream", + "tokio-util", + "tracing", + "tracing-error", + "tracing-futures", + "tracing-subscriber", +] + +[[package]] +name = "defmt" +version = "0.3.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a99dd22262668b887121d4672af5a64b238f026099f1a2a1b322066c9ecfe9e0" +dependencies = [ + "bitflags 1.3.2", + "defmt-macros", +] + +[[package]] +name = "defmt-macros" +version = "0.3.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e3a9f309eff1f79b3ebdf252954d90ae440599c26c2c553fe87a2d17195f2dcb" +dependencies = [ + "defmt-parser", + "proc-macro-error", + "proc-macro2", + "quote", + "syn 2.0.77", +] + +[[package]] +name = "defmt-parser" +version = "0.3.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ff4a5fefe330e8d7f31b16a318f9ce81000d8e35e69b93eae154d16d2278f70f" +dependencies = [ + "thiserror", +] + +[[package]] +name = "diatomic-waker" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ab03c107fafeb3ee9f5925686dbb7a73bc76e3932abb0d2b365cb64b169cf04c" + +[[package]] +name = "educe" +version = "0.5.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e4bd92664bf78c4d3dba9b7cdafce6fa15b13ed3ed16175218196942e99168a8" +dependencies = [ + "enum-ordinalize", + "proc-macro2", + "quote", + "syn 2.0.77", +] + +[[package]] +name = "embedded-io" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ef1a6892d9eef45c8fa6b9e0086428a2cca8491aca8f787c534a3d6d0bcb3ced" + +[[package]] +name = "embedded-io" +version = "0.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "edd0f118536f44f5ccd48bcb8b111bdc3de888b58c74639dfb034a357d0f206d" + +[[package]] +name = "enum-ordinalize" +version = "4.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fea0dcfa4e54eeb516fe454635a95753ddd39acda650ce703031c6973e315dd5" +dependencies = [ + "enum-ordinalize-derive", +] + +[[package]] +name = "enum-ordinalize-derive" +version = "4.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0d28318a75d4aead5c4db25382e8ef717932d0346600cacae6357eb5941bc5ff" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.77", +] + +[[package]] +name = "errno" +version = "0.3.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "534c5cf6194dfab3db3242765c03bbe257cf92f22b38f6bc0c58d59108a820ba" +dependencies = [ + "libc", + "windows-sys 0.52.0", +] + +[[package]] +name = "eyre" +version = "0.6.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7cd915d99f24784cdc19fd37ef22b97e3ff0ae756c7e492e9fbfe897d61e2aec" +dependencies = [ + "indenter", + "once_cell", +] + +[[package]] +name = "fastrand" +version = "1.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e51093e27b0797c359783294ca4f0a911c270184cb10f85783b118614a1501be" +dependencies = [ + "instant", +] + +[[package]] +name = "fnv" +version = "1.0.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" + +[[package]] +name = "funty" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e6d5a32815ae3f33302d95fdcb2ce17862f8c65363dcfd29360480ba1001fc9c" + +[[package]] +name = "futures" +version = "0.3.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "645c6916888f6cb6350d2550b80fb63e734897a8498abe35cfb732b6487804b0" +dependencies = [ + "futures-channel", + "futures-core", + "futures-executor", + "futures-io", + "futures-sink", + "futures-task", + "futures-util", +] + +[[package]] +name = "futures-buffered" +version = "0.2.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "91fa130f3777d0d4b0993653c20bc433026d3290627693c4ed1b18dd237357ab" +dependencies = [ + "diatomic-waker", + "futures-core", + "pin-project-lite", +] + +[[package]] +name = "futures-channel" +version = "0.3.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eac8f7d7865dcb88bd4373ab671c8cf4508703796caa2b1985a9ca867b3fcb78" +dependencies = [ + "futures-core", + "futures-sink", +] + +[[package]] +name = "futures-concurrency" +version = "7.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4b14ac911e85d57c5ea6eef76d7b4d4a3177ecd15f4bea2e61927e9e3823e19f" +dependencies = [ + "bitvec", + "futures-buffered", + "futures-core", + "futures-lite", + "pin-project", + "slab", + "smallvec", +] + +[[package]] +name = "futures-core" +version = "0.3.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dfc6580bb841c5a68e9ef15c77ccc837b40a7504914d52e47b8b0e9bbda25a1d" + +[[package]] +name = "futures-executor" +version = "0.3.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a576fc72ae164fca6b9db127eaa9a9dda0d61316034f33a0a0d4eda41f02b01d" +dependencies = [ + "futures-core", + "futures-task", + "futures-util", +] + +[[package]] +name = "futures-io" +version = "0.3.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a44623e20b9681a318efdd71c299b6b222ed6f231972bfe2f224ebad6311f0c1" + +[[package]] +name = "futures-lite" +version = "1.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "49a9d51ce47660b1e808d3c990b4709f2f415d928835a17dfd16991515c46bce" +dependencies = [ + "fastrand", + "futures-core", + "futures-io", + "memchr", + "parking", + "pin-project-lite", + "waker-fn", +] + +[[package]] +name = "futures-macro" +version = "0.3.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "87750cf4b7a4c0625b1529e4c543c2182106e4dedc60a2a6455e00d212c489ac" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.77", +] + +[[package]] +name = "futures-sink" +version = "0.3.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9fb8e00e87438d937621c1c6269e53f536c14d3fbd6a042bb24879e57d474fb5" + +[[package]] +name = "futures-task" +version = "0.3.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "38d84fa142264698cdce1a9f9172cf383a0c82de1bddcf3092901442c4097004" + +[[package]] +name = "futures-timer" +version = "3.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f288b0a4f20f9a56b5d1da57e2227c661b7b16168e2f72365f57b63326e29b24" + +[[package]] +name = "futures-util" +version = "0.3.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3d6401deb83407ab3da39eba7e33987a73c3df0c82b4bb5813ee871c19c41d48" +dependencies = [ + "futures-channel", + "futures-core", + "futures-io", + "futures-macro", + "futures-sink", + "futures-task", + "memchr", + "pin-project-lite", + "pin-utils", + "slab", +] + +[[package]] +name = "generator" +version = "0.7.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5cc16584ff22b460a382b7feec54b23d2908d858152e5739a120b949293bd74e" +dependencies = [ + "cc", + "libc", + "log", + "rustversion", + "windows 0.48.0", +] + +[[package]] +name = "generator" +version = "0.8.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dbb949699c3e4df3a183b1d2142cb24277057055ed23c68ed58894f76c517223" +dependencies = [ + "cfg-if", + "libc", + "log", + "rustversion", + "windows 0.58.0", +] + +[[package]] +name = "getrandom" +version = "0.2.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c4567c8db10ae91089c99af84c68c38da3ec2f087c3f82960bcdbf3656b6f4d7" +dependencies = [ + "cfg-if", + "libc", + "wasi", +] + +[[package]] +name = "gimli" +version = "0.28.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4271d37baee1b8c7e4b708028c57d816cf9d2434acb33a549475f78c181f6253" + +[[package]] +name = "governor" +version = "0.6.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "68a7f542ee6b35af73b06abc0dad1c1bae89964e4e253bc4b587b91c9637867b" +dependencies = [ + "cfg-if", + "dashmap", + "futures", + "futures-timer", + "no-std-compat", + "nonzero_ext", + "parking_lot", + "portable-atomic", + "quanta", + "rand", + "smallvec", + "spinning_top", +] + +[[package]] +name = "hash32" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b0c35f58762feb77d74ebe43bdbc3210f09be9fe6742234d573bacc26ed92b67" +dependencies = [ + "byteorder", +] + +[[package]] +name = "hash32" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "47d60b12902ba28e2730cd37e95b8c9223af2808df9e902d4df49588d1470606" +dependencies = [ + "byteorder", +] + +[[package]] +name = "hashbrown" +version = "0.14.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e5274423e17b7c9fc20b6e7e208532f9b19825d82dfd615708b70edd83df41f1" + +[[package]] +name = "heapless" +version = "0.7.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cdc6457c0eb62c71aac4bc17216026d8410337c4126773b9c5daba343f17964f" +dependencies = [ + "atomic-polyfill", + "hash32 0.2.1", + "rustc_version", + "serde", + "spin", + "stable_deref_trait", +] + +[[package]] +name = "heapless" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0bfb9eb618601c89945a70e254898da93b13be0388091d42117462b265bb3fad" +dependencies = [ + "defmt", + "hash32 0.3.1", + "serde", + "stable_deref_trait", +] + +[[package]] +name = "heck" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea" + +[[package]] +name = "hermit-abi" +version = "0.3.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d231dfb89cfffdbc30e7fc41579ed6066ad03abda9e567ccafae602b97ec5024" + +[[package]] +name = "host" +version = "0.1.0" +dependencies = [ + "clap", + "data-server", + "heapless 0.8.0", + "postcard", + "postcard-rpc", + "protocol", + "ratelimited", + "schema", + "tokio", + "tracing", + "tracing-error", + "tracing-subscriber", +] + +[[package]] +name = "ident_case" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b9e0384b61958566e926dc50660321d12159025e767c18e043daf26b70104c39" + +[[package]] +name = "indenter" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ce23b50ad8242c51a442f3ff322d56b02f08852c77e4c0b4d3fd684abc89c683" + +[[package]] +name = "instant" +version = "0.1.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e0242819d153cba4b4b05a5a8f2a7e9bbf97b6055b2a002b395c96b5ff3c0222" +dependencies = [ + "cfg-if", +] + +[[package]] +name = "io-kit-sys" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "617ee6cf8e3f66f3b4ea67a4058564628cde41901316e19f559e14c7c72c5e7b" +dependencies = [ + "core-foundation-sys", + "mach2", +] + +[[package]] +name = "is_terminal_polyfill" +version = "1.70.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7943c866cc5cd64cbc25b2e01621d07fa8eb2a1a23160ee81ce38704e97b8ecf" + +[[package]] +name = "js-sys" +version = "0.3.70" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1868808506b929d7b0cfa8f75951347aa71bb21144b7791bae35d9bccfcfe37a" +dependencies = [ + "wasm-bindgen", +] + +[[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.158" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d8adc4bb1803a324070e64a98ae98f38934d91957a99cfb3a43dcbc01bc56439" + +[[package]] +name = "linux-raw-sys" +version = "0.4.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "78b3ae25bc7c8c38cec158d1f2757ee79e9b3740fbc7ccf0e59e4b08d793fa89" + +[[package]] +name = "lock_api" +version = "0.4.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "07af8b9cdd281b7915f413fa73f29ebd5d55d0d3f0155584dade1ff18cea1b17" +dependencies = [ + "autocfg", + "scopeguard", +] + +[[package]] +name = "log" +version = "0.4.22" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a7a70ba024b9dc04c27ea2f0c0548feb474ec5c54bba33a7f72f873a39d07b24" + +[[package]] +name = "loom" +version = "0.5.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ff50ecb28bb86013e935fb6683ab1f6d3a20016f123c76fd4c27470076ac30f5" +dependencies = [ + "cfg-if", + "generator 0.7.5", + "scoped-tls", + "tracing", + "tracing-subscriber", +] + +[[package]] +name = "loom" +version = "0.7.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "419e0dc8046cb947daa77eb95ae174acfbddb7673b4151f56d1eed8e93fbfaca" +dependencies = [ + "cfg-if", + "generator 0.8.3", + "scoped-tls", + "tracing", + "tracing-subscriber", +] + +[[package]] +name = "mach2" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "19b955cdeb2a02b9117f121ce63aa52d08ade45de53e48fe6a38b39c10f6f709" +dependencies = [ + "libc", +] + +[[package]] +name = "maitake-sync" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6816ab14147f80234c675b80ed6dc4f440d8a1cefc158e766067aedb84c0bcd5" +dependencies = [ + "cordyceps", + "loom 0.7.2", + "mycelium-bitfield", + "pin-project", + "portable-atomic", +] + +[[package]] +name = "matchers" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8263075bb86c5a1b1427b5ae862e8889656f126e9f77c484496e8b47cf5c5558" +dependencies = [ + "regex-automata 0.1.10", +] + +[[package]] +name = "memchr" +version = "2.7.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "78ca9ab1a0babb1e7d5695e3530886289c18cf2f87ec19a575a0abdce112e3a3" + +[[package]] +name = "miniz_oxide" +version = "0.7.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b8a240ddb74feaf34a79a7add65a741f3167852fba007066dcac1ca548d89c08" +dependencies = [ + "adler", +] + +[[package]] +name = "mio" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "80e04d1dcff3aae0704555fe5fee3bcfaf3d1fdf8a7e521d5b9d2b42acb52cec" +dependencies = [ + "hermit-abi", + "libc", + "wasi", + "windows-sys 0.52.0", +] + +[[package]] +name = "mycelium-bitfield" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "24e0cc5e2c585acbd15c5ce911dff71e1f4d5313f43345873311c4f5efd741cc" + +[[package]] +name = "no-std-compat" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b93853da6d84c2e3c7d730d6473e8817692dd89be387eb01b94d7f108ecb5b8c" + +[[package]] +name = "nonzero_ext" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "38bf9645c8b145698bb0b18a4637dcacbc421ea49bef2317e4fd8065a387cf21" + +[[package]] +name = "nu-ansi-term" +version = "0.46.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "77a8165726e8236064dbb45459242600304b42a5ea24ee2948e18e023bf7ba84" +dependencies = [ + "overload", + "winapi", +] + +[[package]] +name = "nusb" +version = "0.1.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1ac267a828c32759883a6097809fc4c32d76925099725aae562717cb023b431c" +dependencies = [ + "atomic-waker", + "core-foundation", + "core-foundation-sys", + "io-kit-sys", + "log", + "once_cell", + "rustix", + "slab", + "windows-sys 0.48.0", +] + +[[package]] +name = "object" +version = "0.32.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a6a622008b6e321afc04970976f62ee297fdbaa6f95318ca343e3eebb9648441" +dependencies = [ + "memchr", +] + +[[package]] +name = "once_cell" +version = "1.19.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3fdb12b2476b595f9358c5161aa467c2438859caa136dec86c26fdd2efe17b92" + +[[package]] +name = "overload" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b15813163c1d831bf4a13c3610c05c0d03b39feb07f7e09fa234dac9b15aaf39" + +[[package]] +name = "owo-colors" +version = "3.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c1b04fb49957986fdce4d6ee7a65027d55d4b6d2265e5848bbb507b58ccfdb6f" + +[[package]] +name = "parking" +version = "2.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f38d5652c16fde515bb1ecef450ab0f6a219d619a7274976324d5e377f7dceba" + +[[package]] +name = "parking_lot" +version = "0.12.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f1bf18183cf54e8d6059647fc3063646a1801cf30896933ec2311622cc4b9a27" +dependencies = [ + "lock_api", + "parking_lot_core", +] + +[[package]] +name = "parking_lot_core" +version = "0.9.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e401f977ab385c9e4e3ab30627d6f26d00e2c73eef317493c4ec6d468726cf8" +dependencies = [ + "cfg-if", + "libc", + "redox_syscall", + "smallvec", + "windows-targets 0.52.6", +] + +[[package]] +name = "pin-project" +version = "1.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b6bf43b791c5b9e34c3d182969b4abb522f9343702850a2e57f460d00d09b4b3" +dependencies = [ + "pin-project-internal", +] + +[[package]] +name = "pin-project-internal" +version = "1.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2f38a4412a78282e09a2cf38d195ea5420d15ba0602cb375210efbc877243965" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.77", +] + +[[package]] +name = "pin-project-lite" +version = "0.2.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bda66fc9667c18cb2758a2ac84d1167245054bcf85d5d1aaa6923f45801bdd02" + +[[package]] +name = "pin-utils" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" + +[[package]] +name = "portable-atomic" +version = "1.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d30538d42559de6b034bc76fd6dd4c38961b1ee5c6c56e3808c50128fdbc22ce" + +[[package]] +name = "postcard" +version = "1.0.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5f7f0a8d620d71c457dd1d47df76bb18960378da56af4527aaa10f515eee732e" +dependencies = [ + "cobs", + "embedded-io 0.4.0", + "embedded-io 0.6.1", + "heapless 0.7.17", + "postcard-derive", + "serde", +] + +[[package]] +name = "postcard-derive" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0239fa9c1d225d4b7eb69925c25c5e082307a141e470573fbbe3a817ce6a7a37" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "postcard-rpc" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "03b6bf6dce5532b37ad9ce1dfc70e8f892f3c241306cdd2952d5156f9b35f43a" +dependencies = [ + "heapless 0.8.0", + "maitake-sync", + "nusb", + "postcard", + "serde", + "thiserror", + "tokio", + "tracing", + "trait-variant", +] + +[[package]] +name = "ppv-lite86" +version = "0.2.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "77957b295656769bb8ad2b6a6b09d897d94f05c41b069aede1fcdaa675eaea04" +dependencies = [ + "zerocopy", +] + +[[package]] +name = "proc-macro-error" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "da25490ff9892aab3fcf7c36f08cfb902dd3e71ca0f9f9517bea02a73a5ce38c" +dependencies = [ + "proc-macro-error-attr", + "proc-macro2", + "quote", + "syn 1.0.109", + "version_check", +] + +[[package]] +name = "proc-macro-error-attr" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a1be40180e52ecc98ad80b184934baf3d0d29f979574e439af5a55274b35f869" +dependencies = [ + "proc-macro2", + "quote", + "version_check", +] + +[[package]] +name = "proc-macro2" +version = "1.0.86" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5e719e8df665df0d1c8fbfd238015744736151d4445ec0836b8e628aae103b77" +dependencies = [ + "unicode-ident", +] + +[[package]] +name = "protocol" +version = "0.1.0" +dependencies = [ + "defmt", + "heapless 0.8.0", + "postcard", + "serde", + "strum", + "thiserror", +] + +[[package]] +name = "quanta" +version = "0.12.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e5167a477619228a0b284fac2674e3c388cba90631d7b7de620e6f1fcd08da5" +dependencies = [ + "crossbeam-utils", + "libc", + "once_cell", + "raw-cpuid", + "wasi", + "web-sys", + "winapi", +] + +[[package]] +name = "quote" +version = "1.0.37" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b5b9d34b8991d19d98081b46eacdd8eb58c6f2b201139f7c5f643cc155a633af" +dependencies = [ + "proc-macro2", +] + +[[package]] +name = "radium" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dc33ff2d4973d518d823d61aa239014831e521c75da58e3df4840d3f47749d09" + +[[package]] +name = "rand" +version = "0.8.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404" +dependencies = [ + "libc", + "rand_chacha", + "rand_core", +] + +[[package]] +name = "rand_chacha" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88" +dependencies = [ + "ppv-lite86", + "rand_core", +] + +[[package]] +name = "rand_core" +version = "0.6.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" +dependencies = [ + "getrandom", +] + +[[package]] +name = "ratelimited" +version = "0.1.0" +dependencies = [ + "governor", + "tracing", + "tracing-error", + "tracing-subscriber", +] + +[[package]] +name = "raw-cpuid" +version = "11.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cb9ee317cfe3fbd54b36a511efc1edd42e216903c9cd575e686dd68a2ba90d8d" +dependencies = [ + "bitflags 2.6.0", +] + +[[package]] +name = "redox_syscall" +version = "0.5.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0884ad60e090bf1345b93da0a5de8923c93884cd03f40dfcfddd3b4bee661853" +dependencies = [ + "bitflags 2.6.0", +] + +[[package]] +name = "regex" +version = "1.10.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4219d74c6b67a3654a9fbebc4b419e22126d13d2f3c4a07ee0cb61ff79a79619" +dependencies = [ + "aho-corasick", + "memchr", + "regex-automata 0.4.7", + "regex-syntax 0.8.4", +] + +[[package]] +name = "regex-automata" +version = "0.1.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6c230d73fb8d8c1b9c0b3135c5142a8acee3a0558fb8db5cf1cb65f8d7862132" +dependencies = [ + "regex-syntax 0.6.29", +] + +[[package]] +name = "regex-automata" +version = "0.4.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "38caf58cc5ef2fed281f89292ef23f6365465ed9a41b7a7754eb4e26496c92df" +dependencies = [ + "aho-corasick", + "memchr", + "regex-syntax 0.8.4", +] + +[[package]] +name = "regex-syntax" +version = "0.6.29" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f162c6dd7b008981e4d40210aca20b4bd0f9b60ca9271061b07f78537722f2e1" + +[[package]] +name = "regex-syntax" +version = "0.8.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7a66a03ae7c801facd77a29370b4faec201768915ac14a721ba36f20bc9c209b" + +[[package]] +name = "rpc" +version = "0.1.0" +dependencies = [ + "color-eyre", + "futures", + "governor", + "ratelimited", + "serde", + "thiserror", + "tokio", + "tokio-serde", + "tokio-util", + "tracing", +] + +[[package]] +name = "rustc-demangle" +version = "0.1.24" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "719b953e2095829ee67db738b3bfa9fa368c94900df327b3f07fe6e794d2fe1f" + +[[package]] +name = "rustc_version" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cfcb3a22ef46e85b45de6ee7e79d063319ebb6594faafcf1c225ea92ab6e9b92" +dependencies = [ + "semver", +] + +[[package]] +name = "rustix" +version = "0.38.37" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8acb788b847c24f28525660c4d7758620a7210875711f79e7f663cc152726811" +dependencies = [ + "bitflags 2.6.0", + "errno", + "libc", + "linux-raw-sys", + "windows-sys 0.52.0", +] + +[[package]] +name = "rustversion" +version = "1.0.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "955d28af4278de8121b7ebeb796b6a45735dc01436d898801014aced2773a3d6" + +[[package]] +name = "schema" +version = "0.1.0" +dependencies = [ + "heapless 0.8.0", + "postcard", + "postcard-rpc", + "protocol", + "serde", + "serde_with", +] + +[[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 = "1.0.23" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "61697e0a1c7e512e84a621326239844a24d8207b4669b41bc18b32ea5cbf988b" + +[[package]] +name = "serde" +version = "1.0.210" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c8e3592472072e6e22e0a54d5904d9febf8508f65fb8552499a1abc7d1078c3a" +dependencies = [ + "serde_derive", +] + +[[package]] +name = "serde_derive" +version = "1.0.210" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "243902eda00fad750862fc144cea25caca5e20d615af0a81bee94ca738f1df1f" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.77", +] + +[[package]] +name = "serde_with" +version = "3.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "69cecfa94848272156ea67b2b1a53f20fc7bc638c4a46d2f8abde08f05f4b857" +dependencies = [ + "serde", + "serde_derive", + "serde_with_macros", +] + +[[package]] +name = "serde_with_macros" +version = "3.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a8fee4991ef4f274617a51ad4af30519438dacb2f56ac773b08a1922ff743350" +dependencies = [ + "darling", + "proc-macro2", + "quote", + "syn 2.0.77", +] + +[[package]] +name = "sharded-slab" +version = "0.1.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f40ca3c46823713e0d4209592e8d6e826aa57e928f09752619fc696c499637f6" +dependencies = [ + "lazy_static", +] + +[[package]] +name = "shlex" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64" + +[[package]] +name = "slab" +version = "0.4.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f92a496fb766b417c996b9c5e57daf2f7ad3b0bebe1ccfca4856390e3d3bb67" +dependencies = [ + "autocfg", +] + +[[package]] +name = "slotmap" +version = "1.0.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dbff4acf519f630b3a3ddcfaea6c06b42174d9a44bc70c620e9ed1649d58b82a" +dependencies = [ + "version_check", +] + +[[package]] +name = "smallvec" +version = "1.13.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3c5e1a9a646d36c3599cd173a41282daf47c44583ad367b8e6837255952e5c67" + +[[package]] +name = "socket2" +version = "0.5.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ce305eb0b4296696835b71df73eb912e0f1ffd2556a501fcede6e0c50349191c" +dependencies = [ + "libc", + "windows-sys 0.52.0", +] + +[[package]] +name = "spin" +version = "0.9.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6980e8d7511241f8acf4aebddbb1ff938df5eebe98691418c4468d0b72a96a67" +dependencies = [ + "lock_api", +] + +[[package]] +name = "spinning_top" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d96d2d1d716fb500937168cc09353ffdc7a012be8475ac7308e1bdf0e3923300" +dependencies = [ + "lock_api", +] + +[[package]] +name = "stable_deref_trait" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a8f112729512f8e442d81f95a8a7ddf2b7c6b8a1a6f509a95864142b30cab2d3" + +[[package]] +name = "strsim" +version = "0.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f" + +[[package]] +name = "strum" +version = "0.26.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8fec0f0aef304996cf250b31b5a10dee7980c85da9d759361292b8bca5a18f06" +dependencies = [ + "strum_macros", +] + +[[package]] +name = "strum_macros" +version = "0.26.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4c6bee85a5a24955dc440386795aa378cd9cf82acd5f764469152d2270e581be" +dependencies = [ + "heck", + "proc-macro2", + "quote", + "rustversion", + "syn 2.0.77", +] + +[[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.77" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9f35bcdf61fd8e7be6caf75f429fdca8beb3ed76584befb503b1569faee373ed" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[package]] +name = "tap" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "55937e1799185b12863d447f42597ed69d9928686b8d88a1df17376a097d8369" + +[[package]] +name = "thiserror" +version = "1.0.64" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d50af8abc119fb8bb6dbabcfa89656f46f84aa0ac7688088608076ad2b459a84" +dependencies = [ + "thiserror-impl", +] + +[[package]] +name = "thiserror-impl" +version = "1.0.64" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "08904e7672f5eb876eaaf87e0ce17857500934f4981c4a0ab2b4aa98baac7fc3" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.77", +] + +[[package]] +name = "thread_local" +version = "1.1.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8b9ef9bad013ada3808854ceac7b46812a6465ba368859a37e2100283d2d719c" +dependencies = [ + "cfg-if", + "once_cell", +] + +[[package]] +name = "tokio" +version = "1.40.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e2b070231665d27ad9ec9b8df639893f46727666c6767db40317fbe920a5d998" +dependencies = [ + "backtrace", + "bytes", + "libc", + "mio", + "pin-project-lite", + "socket2", + "tokio-macros", + "windows-sys 0.52.0", +] + +[[package]] +name = "tokio-macros" +version = "2.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "693d596312e88961bc67d7f1f97af8a70227d9f90c31bba5806eec004978d752" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.77", +] + +[[package]] +name = "tokio-serde" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "caf600e7036b17782571dd44fa0a5cea3c82f60db5137f774a325a76a0d6852b" +dependencies = [ + "bincode", + "bytes", + "educe", + "futures-core", + "futures-sink", + "pin-project", + "serde", +] + +[[package]] +name = "tokio-stream" +version = "0.1.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4f4e6ce100d0eb49a2734f8c0812bcd324cf357d21810932c5df6b96ef2b86f1" +dependencies = [ + "futures-core", + "pin-project-lite", + "tokio", +] + +[[package]] +name = "tokio-util" +version = "0.7.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "61e7c3654c13bcd040d4a03abee2c75b1d14a37b423cf5a813ceae1cc903ec6a" +dependencies = [ + "bytes", + "futures-core", + "futures-sink", + "pin-project-lite", + "tokio", +] + +[[package]] +name = "tracing" +version = "0.1.40" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c3523ab5a71916ccf420eebdf5521fcef02141234bbc0b8a49f2fdc4544364ef" +dependencies = [ + "pin-project-lite", + "tracing-attributes", + "tracing-core", +] + +[[package]] +name = "tracing-attributes" +version = "0.1.27" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "34704c8d6ebcbc939824180af020566b01a7c01f80641264eba0999f6c2b6be7" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.77", +] + +[[package]] +name = "tracing-core" +version = "0.1.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c06d3da6113f116aaee68e4d601191614c9053067f9ab7f6edbcb161237daa54" +dependencies = [ + "once_cell", + "valuable", +] + +[[package]] +name = "tracing-error" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d686ec1c0f384b1277f097b2f279a2ecc11afe8c133c1aabf036a27cb4cd206e" +dependencies = [ + "tracing", + "tracing-subscriber", +] + +[[package]] +name = "tracing-futures" +version = "0.2.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "97d095ae15e245a057c8e8451bab9b3ee1e1f68e9ba2b4fbc18d0ac5237835f2" +dependencies = [ + "pin-project", + "tracing", +] + +[[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.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ad0f048c97dbd9faa9b7df56362b8ebcaa52adb06b498c050d2f4e32f90a7a8b" +dependencies = [ + "matchers", + "nu-ansi-term", + "once_cell", + "regex", + "sharded-slab", + "smallvec", + "thread_local", + "tracing", + "tracing-core", + "tracing-log", +] + +[[package]] +name = "trait-variant" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "70977707304198400eb4835a78f6a9f928bf41bba420deb8fdb175cd965d77a7" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.77", +] + +[[package]] +name = "unicode-ident" +version = "1.0.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e91b56cd4cadaeb79bbf1a5645f6b4f8dc5bde8834ad5894a8db35fda9efa1fe" + +[[package]] +name = "utf8parse" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "06abde3611657adf66d383f00b093d7faecc7fa57071cce2578660c9f1010821" + +[[package]] +name = "valuable" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "830b7e5d4d90034032940e4ace0d9a9a057e7a45cd94e6c007832e39edb82f6d" + +[[package]] +name = "version_check" +version = "0.9.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b928f33d975fc6ad9f86c8f283853ad26bdd5b10b7f1542aa2fa15e2289105a" + +[[package]] +name = "waker-fn" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "317211a0dc0ceedd78fb2ca9a44aed3d7b9b26f81870d485c07122b4350673b7" + +[[package]] +name = "wasi" +version = "0.11.0+wasi-snapshot-preview1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" + +[[package]] +name = "wasm-bindgen" +version = "0.2.93" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a82edfc16a6c469f5f44dc7b571814045d60404b55a0ee849f9bcfa2e63dd9b5" +dependencies = [ + "cfg-if", + "once_cell", + "wasm-bindgen-macro", +] + +[[package]] +name = "wasm-bindgen-backend" +version = "0.2.93" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9de396da306523044d3302746f1208fa71d7532227f15e347e2d93e4145dd77b" +dependencies = [ + "bumpalo", + "log", + "once_cell", + "proc-macro2", + "quote", + "syn 2.0.77", + "wasm-bindgen-shared", +] + +[[package]] +name = "wasm-bindgen-macro" +version = "0.2.93" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "585c4c91a46b072c92e908d99cb1dcdf95c5218eeb6f3bf1efa991ee7a68cccf" +dependencies = [ + "quote", + "wasm-bindgen-macro-support", +] + +[[package]] +name = "wasm-bindgen-macro-support" +version = "0.2.93" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "afc340c74d9005395cf9dd098506f7f44e38f2b4a21c6aaacf9a105ea5e1e836" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.77", + "wasm-bindgen-backend", + "wasm-bindgen-shared", +] + +[[package]] +name = "wasm-bindgen-shared" +version = "0.2.93" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c62a0a307cb4a311d3a07867860911ca130c3494e8c2719593806c08bc5d0484" + +[[package]] +name = "web-sys" +version = "0.3.70" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "26fdeaafd9bd129f65e7c031593c24d62186301e0c72c8978fa1678be7d532c0" +dependencies = [ + "js-sys", + "wasm-bindgen", +] + +[[package]] +name = "winapi" +version = "0.3.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419" +dependencies = [ + "winapi-i686-pc-windows-gnu", + "winapi-x86_64-pc-windows-gnu", +] + +[[package]] +name = "winapi-i686-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" + +[[package]] +name = "winapi-x86_64-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" + +[[package]] +name = "windows" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e686886bc078bc1b0b600cac0147aadb815089b6e4da64016cbd754b6342700f" +dependencies = [ + "windows-targets 0.48.5", +] + +[[package]] +name = "windows" +version = "0.58.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dd04d41d93c4992d421894c18c8b43496aa748dd4c081bac0dc93eb0489272b6" +dependencies = [ + "windows-core", + "windows-targets 0.52.6", +] + +[[package]] +name = "windows-core" +version = "0.58.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6ba6d44ec8c2591c134257ce647b7ea6b20335bf6379a27dac5f1641fcf59f99" +dependencies = [ + "windows-implement", + "windows-interface", + "windows-result", + "windows-strings", + "windows-targets 0.52.6", +] + +[[package]] +name = "windows-implement" +version = "0.58.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2bbd5b46c938e506ecbce286b6628a02171d56153ba733b6c741fc627ec9579b" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.77", +] + +[[package]] +name = "windows-interface" +version = "0.58.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "053c4c462dc91d3b1504c6fe5a726dd15e216ba718e84a0e46a88fbe5ded3515" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.77", +] + +[[package]] +name = "windows-result" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1d1043d8214f791817bab27572aaa8af63732e11bf84aa21a45a78d6c317ae0e" +dependencies = [ + "windows-targets 0.52.6", +] + +[[package]] +name = "windows-strings" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4cd9b125c486025df0eabcb585e62173c6c9eddcec5d117d3b6e8c30e2ee4d10" +dependencies = [ + "windows-result", + "windows-targets 0.52.6", +] + +[[package]] +name = "windows-sys" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "677d2418bec65e3338edb076e806bc1ec15693c5d0104683f2efe857f61056a9" +dependencies = [ + "windows-targets 0.48.5", +] + +[[package]] +name = "windows-sys" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d" +dependencies = [ + "windows-targets 0.52.6", +] + +[[package]] +name = "windows-targets" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9a2fa6e2155d7247be68c096456083145c183cbbbc2764150dda45a87197940c" +dependencies = [ + "windows_aarch64_gnullvm 0.48.5", + "windows_aarch64_msvc 0.48.5", + "windows_i686_gnu 0.48.5", + "windows_i686_msvc 0.48.5", + "windows_x86_64_gnu 0.48.5", + "windows_x86_64_gnullvm 0.48.5", + "windows_x86_64_msvc 0.48.5", +] + +[[package]] +name = "windows-targets" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973" +dependencies = [ + "windows_aarch64_gnullvm 0.52.6", + "windows_aarch64_msvc 0.52.6", + "windows_i686_gnu 0.52.6", + "windows_i686_gnullvm", + "windows_i686_msvc 0.52.6", + "windows_x86_64_gnu 0.52.6", + "windows_x86_64_gnullvm 0.52.6", + "windows_x86_64_msvc 0.52.6", +] + +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8" + +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3" + +[[package]] +name = "windows_aarch64_msvc" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc" + +[[package]] +name = "windows_aarch64_msvc" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469" + +[[package]] +name = "windows_i686_gnu" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743e" + +[[package]] +name = "windows_i686_gnu" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b" + +[[package]] +name = "windows_i686_gnullvm" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66" + +[[package]] +name = "windows_i686_msvc" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406" + +[[package]] +name = "windows_i686_msvc" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66" + +[[package]] +name = "windows_x86_64_gnu" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "53d40abd2583d23e4718fddf1ebec84dbff8381c07cae67ff7768bbf19c6718e" + +[[package]] +name = "windows_x86_64_gnu" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78" + +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc" + +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d" + +[[package]] +name = "windows_x86_64_msvc" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538" + +[[package]] +name = "windows_x86_64_msvc" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" + +[[package]] +name = "wyz" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "05f360fc0b24296329c78fda852a1e9ae82de9cf7b27dae4b7f62f118f77b9ed" +dependencies = [ + "tap", +] + +[[package]] +name = "zerocopy" +version = "0.7.35" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1b9b4fd18abc82b8136838da5d50bae7bdea537c574d8dc1a34ed098d6c166f0" +dependencies = [ + "byteorder", + "zerocopy-derive", +] + +[[package]] +name = "zerocopy-derive" +version = "0.7.35" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fa4f8080344d4671fb4e831a13ad1e68092748387dfc4f55e356242fae12ce3e" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.77", +] diff --git a/crates/usb-bridge/Cargo.toml b/crates/usb-bridge/Cargo.toml new file mode 100644 index 00000000..d1b78d17 --- /dev/null +++ b/crates/usb-bridge/Cargo.toml @@ -0,0 +1,23 @@ +[package] +name = "usb-bridge" +version = "0.1.0" +rust-version = "1.78" +edition = "2021" +license = "GPLv3" +authors = ["David Kleingeld & Eva van Houten"] + +[dependencies] +heapless = "0.8.0" + +protocol = { workspace = true } +data-server = { workspace = true } +logger = { workspace = true } + +tokio = { workspace = true } +clap = { workspace = true } +tracing-subscriber = { workspace = true } +tracing-error = { workspace = true } +tracing = { workspace = true } +nusb = "0.1.10" +color-eyre.workspace = true +uzers = "0.12.0" diff --git a/crates/usb-bridge/deploy.sh b/crates/usb-bridge/deploy.sh new file mode 100755 index 00000000..91ae0272 --- /dev/null +++ b/crates/usb-bridge/deploy.sh @@ -0,0 +1,32 @@ +#!/usr/bin/env bash +set -e + +BUILD_ARG=--release +NAME=usb-bridge + +cargo build --target=aarch64-unknown-linux-musl $BUILD_ARG + +for server in "atlantis"; do + rsync -vh --progress \ + ../../target/aarch64-unknown-linux-musl/release/$NAME \ + $server:/tmp/ + rsync -vh --progress \ + $NAME.service \ + $server:/tmp/ + rsync -vh --progress \ + $NAME.rules \ + $server:/tmp/ + + cmds=" + sudo mv /tmp/$NAME /usr/bin/ + sudo mv /tmp/$NAME.service /etc/systemd/system + sudo mv /tmp/$NAME.rules /etc/udev/rules.d + sudo udevadm control --reload-rules + sudo udevadm trigger + sudo systemctl daemon-reload + sudo systemctl enable $NAME.service + sudo systemctl restart $NAME.service + " + + ssh -t $server "$cmds" +done diff --git a/crates/usb-bridge/src/main.rs b/crates/usb-bridge/src/main.rs new file mode 100644 index 00000000..8ef6b31b --- /dev/null +++ b/crates/usb-bridge/src/main.rs @@ -0,0 +1,66 @@ +use std::net::SocketAddr; + +use clap::Parser; + +use color_eyre::eyre::Context; +use data_server::api::data_source::reconnecting::SendError; +use data_server::api::data_source::{reconnecting, SendPreEncodedError}; +use tracing::{debug, warn}; + +mod usb; + +#[derive(Parser)] +#[command(name = "usb-bridge")] +#[command(version = "1.0")] +#[command( + about = "forwards sensor info from and affector orders to nodes attached to usb" +)] +struct Cli { + /// Where to send the data on the local system + #[arg(short, long("data-server"), + default_value = "192.168.1.43:1234", value_parser = resolve_socketaddr)] + data_server: SocketAddr, + /// Serial number of the device to connect case insensitive + #[arg(short, long)] + serial_number: String, +} + +#[tokio::main(flavor = "current_thread")] +async fn main() -> Result<(), color_eyre::Report> { + color_eyre::install().unwrap(); + logger::tracing::setup(); + + let args = Cli::parse(); + debug!("Started usb-bridge"); + + let (order_tx, order_rx) = tokio::sync::mpsc::channel(10); + let mut usb = usb::ReconnectingUsb::new(args.serial_number, order_rx); + let affectors = usb + .get_affectors() + .await + .wrap_err("Could not get affector list")?; + let mut server_client = + reconnecting::Client::new(args.data_server, affectors, Some(order_tx)) + .await?; + + loop { + let encoded_msg = usb.handle_usb().await; + match server_client.check_send_encoded(encoded_msg).await { + Ok(()) => (), + Err(SendPreEncodedError::Sending(SendError::Outdated)) => { + warn!("Did not send data because it is outdated") + } + other @ Err(_) => other?, + } + } +} + +pub fn resolve_socketaddr(arg: &str) -> Result { + use std::net::ToSocketAddrs; + + let mut addrs_iter = arg.to_socket_addrs()?; + addrs_iter.next().ok_or(std::io::Error::new( + std::io::ErrorKind::Other, + "Must pass one address", + )) +} diff --git a/crates/usb-bridge/src/usb.rs b/crates/usb-bridge/src/usb.rs new file mode 100644 index 00000000..b3f92ed7 --- /dev/null +++ b/crates/usb-bridge/src/usb.rs @@ -0,0 +1,172 @@ +use nusb::transfer; +use tokio::sync::mpsc; + +use tokio::time::{sleep, sleep_until, timeout}; + +use protocol::Affector; +use std::time::Duration; +use std::vec; + +use color_eyre::eyre::{bail, Context}; + +use tokio::time::Instant; + +mod device; + +pub(crate) struct ReconnectingUsb { + pub(crate) serial_number: String, + /// when we are allowed to poll the usb + /// device for more data again + pub(crate) next_poll: Instant, + pub(crate) conn: Option, + pub(crate) bytes: vec::IntoIter, + pub(crate) to_send: mpsc::Receiver, +} + +pub(crate) enum Status { + Done, + CallAgain, +} + +impl ReconnectingUsb { + pub(crate) fn new(serial_number: String, to_send: mpsc::Receiver) -> Self { + ReconnectingUsb { + serial_number, + next_poll: Instant::now(), + conn: None, + bytes: Vec::new().into_iter(), + to_send, + } + } + + pub(crate) async fn get_affectors(&mut self) -> color_eyre::Result> { + let msg = loop { + match self + .try_request_data(device::get(protocol::usb::GET_AFFECTOR_LIST)) + .await + { + Ok(Some(msg)) => break msg, + Ok(None) => continue, // needs another call to decode more + Err(e) => { + tracing::warn!("Error trying get affector list: {e:?}"); + sleep(Duration::from_secs(5)).await; + } + } + }; + let msg = protocol::Msg::<50>::decode(msg.to_vec()).wrap_err( + "Could not decode protocol::Msg, maybe the protocol library \ + has changed since this was compiled", + )?; + let protocol::Msg::AffectorList(list) = msg else { + unreachable!("affector list request is only anwserd by affector list msg"); + }; + + Ok(list.values.to_vec()) + } + + pub(crate) async fn handle_usb(&mut self) -> Vec { + let mut retry_period = Duration::from_millis(100); + loop { + if let Some(len) = self.bytes.next() { + if len == 0 { + self.bytes = Vec::new().into_iter(); + continue; + } + return self.bytes.by_ref().take(len as usize).collect(); + } + + if let Ok(order) = self.to_send.try_recv() { + self.send_order(&mut retry_period, order).await; + } + + self.receive_bytes(&mut retry_period).await; + } + } + + pub(crate) async fn receive_bytes(&mut self, retry_period: &mut Duration) { + self.bytes = loop { + sleep_until(self.next_poll).await; + self.next_poll = Instant::now() + Duration::from_millis(100); + + match self + .try_request_data(device::get(protocol::usb::GET_QUEUED_MESSAGES)) + .await + { + Ok(Some(bytes)) => break bytes.into_iter(), + Ok(None) => continue, + Err(e) => { + tracing::warn!("could not receive sensor message: {e:?}"); + *retry_period *= 2; + *retry_period = (*retry_period).min(Duration::from_secs(30)); + sleep(*retry_period).await; + } + }; + }; + } + + pub(crate) async fn send_order(&mut self, retry_period: &mut Duration, order: Affector) { + tracing::info!("sending order"); + let data = order.encode(); + for _ in 0..2 { + match self + .try_send_data(device::send(protocol::usb::AFFECTOR_ORDER, &data)) + .await + { + Ok(Status::Done) => break, + Ok(Status::CallAgain) => continue, + Err(e) => { + tracing::warn!("could not send affector order: {e:?}"); + *retry_period *= 2; + *retry_period = (*retry_period).min(Duration::from_secs(30)); + sleep(*retry_period).await; + } + } + } + } + + pub(crate) async fn try_request_data( + &mut self, + request: transfer::ControlIn, + ) -> color_eyre::Result>> { + if let Some(device) = self.conn.take() { + let do_request = device.control_in(request); + let msg = match timeout(Duration::from_secs(1), do_request) + .await + .map(|res| res.into_result()) + { + Ok(Ok(msg)) => msg, + Ok(e @ Err(_)) => e.wrap_err("Something went wrong with control_in request")?, + Err(_timeout) => bail!("Usb control_in request timed out"), + }; + + self.conn = Some(device); + return Ok(Some(msg)); + } + + let list = device::list_usb_devices(&self.serial_number)?; + self.conn = Some(device::get_usb_device(list, &self.serial_number)?); + + Ok(None) // no errors but not done yet, call us again + } + + pub(crate) async fn try_send_data( + &mut self, + request: transfer::ControlOut<'_>, + ) -> color_eyre::Result { + if let Some(device) = self.conn.take() { + device + .control_out(request) + .await + .into_result() + .wrap_err("Something went wrong with control_out request")?; + + self.conn = Some(device); + return Ok(Status::Done); + } + + let list = device::list_usb_devices(&self.serial_number)?; + self.conn = Some(device::get_usb_device(list, &self.serial_number)?); + + Ok(Status::CallAgain) // no errors but not done yet, call us again + } +} diff --git a/crates/usb-bridge/src/usb/device.rs b/crates/usb-bridge/src/usb/device.rs new file mode 100644 index 00000000..930a942a --- /dev/null +++ b/crates/usb-bridge/src/usb/device.rs @@ -0,0 +1,83 @@ +use color_eyre::eyre::{eyre, Context}; +use color_eyre::Section; +use nusb::transfer; + +pub(crate) fn get(request: u8) -> transfer::ControlIn { + transfer::ControlIn { + control_type: transfer::ControlType::Vendor, + recipient: transfer::Recipient::Interface, + request, + value: 0, + index: 0, + length: protocol::usb::SEND_BUFFER_SIZE.try_into().expect("fits"), + } +} + +pub(crate) fn send(request: u8, data: &[u8]) -> transfer::ControlOut<'_> { + transfer::ControlOut { + control_type: transfer::ControlType::Vendor, + recipient: transfer::Recipient::Interface, + request, + value: 0, + index: 0, + data, + } +} + +pub(crate) fn list_usb_devices( + serial_number: &str, +) -> Result, color_eyre::eyre::Error> { + let list: Vec<_> = nusb::list_devices() + .wrap_err("Could not list usb devices")? + .filter(|d| { + d.serial_number() + .is_some_and(|d| d.eq_ignore_ascii_case(serial_number)) + }) + .collect(); + Ok(list) +} + +pub(crate) fn get_usb_device( + list: Vec, + serial_number: &str, +) -> Result { + match list.as_slice() { + [dev] => dev, + [] => { + return Err(eyre!("No usb device found with the correct serial")) + .with_note(|| { + format!("looking for device with serial: {serial_number}") + }) + .suggestion( + "Is the device working (sometimes programming fails) \ + & connected?", + ); + } + more => { + return Err(eyre!( + "Multiple usb devices have the same serial number" + ) + .with_note(|| format!("they are: {more:?}"))); + } + } + .open() + .wrap_err("Could not open the usb device") + .suggestion("Try running as sudo") + .with_suggestion(|| edit_udev_rules_instruction(serial_number)) +} + +fn edit_udev_rules_instruction(serial_number: &str) -> String { + if let Some(group) = uzers::get_current_groupname() { + let group = group.to_string_lossy(); + format!( + "Add a .rules file in /etc/udev/rules.d with line: \n\ + ATTRS{{serial}}==\"{serial_number}\", MODE=\"660\", GROUP=\"{group}\", TAG+=\"uaccess\"\n\ + Then run: sudo udevadm control --reload && sudo udevadm trigger", + ) + } else { + "Look up this users primary group then add a .rules file + in /etc/udev/rules.d, replace with the primary group: \n\ + ATTRS{{serial}}==\"{serial_number}\", MODE=\"660\", GROUP=\"\", TAG+=\"uaccess\"\n\ + Then run: sudo udevadm control --reload && sudo udevadm trigger".to_string() + } +} diff --git a/crates/usb-bridge/usb-bridge.rules b/crates/usb-bridge/usb-bridge.rules new file mode 100644 index 00000000..71af6af9 --- /dev/null +++ b/crates/usb-bridge/usb-bridge.rules @@ -0,0 +1,2 @@ +ATTRS{serial}=="2139874", MODE="660", GROUP="plugdev", TAG+="uaccess" +ATTRS{serial}=="87244", MODE="660", GROUP="plugdev", TAG+="uaccess" diff --git a/crates/usb-bridge/usb-bridge.service b/crates/usb-bridge/usb-bridge.service new file mode 100644 index 00000000..7f7d0874 --- /dev/null +++ b/crates/usb-bridge/usb-bridge.service @@ -0,0 +1,20 @@ +[Unit] +Description=Usb bridge +After=network-online.target +Wants=network-online.target + +[Service] +Type=exec +DynamicUser=yes +User=usb-bridge +Group=usb-bridge +SupplementaryGroups=plugdev +Environment="RUST_BACKTRACE=1" +Environment="RUST_LOG=nusb=warn,info" +ExecStart=/usr/bin/usb-bridge \ + --data-server sgc:1234 \ + --serial-number 87244 +ExecStop=/bin/kill -s SIGKILL $MAINPID + +[Install] +WantedBy=multi-user.target diff --git a/crates/wiznet-echo-tester/Cargo.toml b/crates/wiznet-echo-tester/Cargo.toml new file mode 100644 index 00000000..8c7b90b6 --- /dev/null +++ b/crates/wiznet-echo-tester/Cargo.toml @@ -0,0 +1,9 @@ +[package] +name = "wiznet-echo-tester" +version = "0.1.0" +rust-version.workspace = true +edition.workspace = true +license.workspace = true +authors.workspace = true + +[dependencies] diff --git a/crates/wiznet-echo-tester/rust-toolchain.toml b/crates/wiznet-echo-tester/rust-toolchain.toml new file mode 100644 index 00000000..6e888d40 --- /dev/null +++ b/crates/wiznet-echo-tester/rust-toolchain.toml @@ -0,0 +1,5 @@ +[toolchain] +channel = "stable" +components = [] +targets = [ "aarch64-unknown-linux-musl" ] +profile = "minimal" diff --git a/crates/wiznet-echo-tester/src/main.rs b/crates/wiznet-echo-tester/src/main.rs new file mode 100644 index 00000000..bf8c2014 --- /dev/null +++ b/crates/wiznet-echo-tester/src/main.rs @@ -0,0 +1,40 @@ +use std::io::{Read, Write}; +use std::net::TcpListener; +use std::thread; +use std::time::Duration; + +fn main() { + let listener = TcpListener::bind("0.0.0.0:6969").unwrap(); + + println!("waiting for incoming connections"); + for conn in listener.incoming() { + let mut conn = match conn { + Ok(conn) => conn, + Err(e) => { + eprintln!("error with incoming connection: {e}"); + continue; + }, + }; + + println!("Got connection from: {:?}", conn.peer_addr()); + let mut buf = [0u8; 100]; + for i in 0u64.. { + buf[0..8].copy_from_slice(&i.to_be_bytes()); + if let Err(e) = conn.write_all(&buf) { + eprintln!("Could not write to incoming conn: {e}"); + break; + } + if let Err(e) = conn.read_exact(&mut buf) { + eprintln!("Could not read echo from incoming conn: {e}"); + break; + } + + assert_eq!(i, u64::from_be_bytes(buf[0..8].try_into().unwrap())); + + if i % 1000 == 0 { + println!("Performed {i} echos"); + } + thread::sleep(Duration::from_millis(100)); + } + } +} diff --git a/crates/zigbee-bridge/Cargo.toml b/crates/zigbee-bridge/Cargo.toml new file mode 100644 index 00000000..82fd9263 --- /dev/null +++ b/crates/zigbee-bridge/Cargo.toml @@ -0,0 +1,25 @@ +[package] +name = "zigbee-bridge" +version = "0.1.0" +rust-version.workspace = true +edition.workspace = true +license.workspace = true +authors.workspace = true + +[dependencies] +protocol.workspace = true +colorimetry = { git = "https://github.com/harbik/colorimetry", features = ["cct"] } +# default-features enable rustls which we do not need and drags in +# C dependencies making deployment a chore +rumqttc = { version = "0.24.0", default-features = false } +serde_json = "1.0.132" +thiserror.workspace = true +tokio = { workspace = true, features = ["sync"] } +tracing = { workspace = true } +strum.workspace = true +color-eyre.workspace = true +regex = "1.11.1" +rand.workspace = true + +[dev-dependencies] +logger.workspace = true diff --git a/crates/zigbee-bridge/examples/change_fridge_light.rs b/crates/zigbee-bridge/examples/change_fridge_light.rs new file mode 100644 index 00000000..f25f0966 --- /dev/null +++ b/crates/zigbee-bridge/examples/change_fridge_light.rs @@ -0,0 +1,36 @@ +use zigbee_bridge::Controller; +use std::time::Duration; + +#[tokio::main] +async fn main() { + logger::tracing::setup_for_tests(); + + let controller = Controller::start_bridge( + "192.168.1.43".parse().unwrap(), + "test change fridge light", + ); + let light = "kitchen:fridge"; + + println!("Setting to on, 2200"); + controller.set_on(light); + controller.set_color_temp(light, 2200); + + tokio::time::sleep(Duration::from_secs(1)).await; + + println!("Turning off"); + controller.set_off(light); + + tokio::time::sleep(Duration::from_secs(1)).await; + + println!("Turning on to 4000"); + controller.set_on(light); + controller.set_color_temp(light, 4000); + + tokio::time::sleep(Duration::from_secs(1)).await; + + println!("Setting bri to 1.0"); + controller.set_brightness(light, 1.0); + + let () = std::future::pending().await; + unreachable!(); +} diff --git a/crates/zigbee-bridge/examples/change_radiator_reference.rs b/crates/zigbee-bridge/examples/change_radiator_reference.rs new file mode 100644 index 00000000..308755e2 --- /dev/null +++ b/crates/zigbee-bridge/examples/change_radiator_reference.rs @@ -0,0 +1,17 @@ +use zigbee_bridge::Controller; + +#[tokio::main] +async fn main() { + logger::tracing::setup_for_tests(); + + let controller = Controller::start_bridge( + "192.168.1.43".parse().unwrap(), + "test change radiator temp", + ); + let radiator = "small_bedroom:radiator"; + + controller.set_radiator_reference(radiator, 22.); + + let () = std::future::pending().await; + unreachable!(); +} diff --git a/crates/zigbee-bridge/examples/change_radiator_set_point.rs b/crates/zigbee-bridge/examples/change_radiator_set_point.rs new file mode 100644 index 00000000..4e47998e --- /dev/null +++ b/crates/zigbee-bridge/examples/change_radiator_set_point.rs @@ -0,0 +1,17 @@ +use zigbee_bridge::Controller; + +#[tokio::main] +async fn main() { + logger::tracing::setup_for_tests(); + + let controller = Controller::start_bridge( + "192.168.1.43".parse().unwrap(), + "test change radiator temp", + ); + let radiator = "small_bedroom:radiator"; + + controller.set_radiator_setpoint(radiator, 22.); + + let () = std::future::pending().await; + unreachable!(); +} diff --git a/crates/zigbee-bridge/src/cached_bridge.rs b/crates/zigbee-bridge/src/cached_bridge.rs new file mode 100644 index 00000000..41a7a2c7 --- /dev/null +++ b/crates/zigbee-bridge/src/cached_bridge.rs @@ -0,0 +1,78 @@ +use std::{net::IpAddr, time::Duration}; + +use rumqttc::v5::{AsyncClient, MqttOptions}; +use tokio::sync::{mpsc, RwLock}; +use tracing::trace; + +use self::mqtt::Mqtt; +use crate::device::{init_states, Property}; +use crate::{LIGHT_MODELS, MQTT_PORT, RADIATOR_NAMES}; + +mod changes; +mod mqtt; +mod poll; + +const MQTT_MIGHT_BE_DOWN_TIMEOUT: Duration = Duration::from_secs(500); +const WAIT_FOR_INIT_STATES: Duration = Duration::from_millis(500); +// unfortunately we have to use the zigbee-herdsman timeout to prevent +// the z2m queue from getting filled up +const TIME_IT_TAKES_TO_APPLY_CHANGE: Duration = Duration::from_secs(10); +const CHANGE_ACCUMULATION_TIME: Duration = Duration::from_millis(100); +const MIN_TIME_BETWEEN_SENDS: Duration = Duration::from_millis(200); +const OFFLINE_CHECK_INTERVAL: Duration = Duration::from_millis(500); + +pub(super) async fn run( + mqtt_ip: IpAddr, + change_receiver: mpsc::UnboundedReceiver<(String, Property)>, + name: String, + reading_callback: impl Fn(protocol::Reading), +) -> ! { + // The id string must be random or subscribe does not work + let id = name + " " + &rand::random::().to_string(); + let mut options = MqttOptions::new(id, mqtt_ip.to_string(), MQTT_PORT); + // Set max mqtt packet size to 4kB + options.set_max_packet_size(Some(8192)); + // Keep subscriptions when reconnecting!!!! + options.set_clean_start(false); + + let known_states = RwLock::new(init_states()); + let needed_states = init_states(); + + // Reconnecting to broker is handled by Eventloop::poll + let channel_capacity = 128; + let (client, eventloop) = + AsyncClient::new(options.clone(), channel_capacity); + let mut mqtt = Mqtt::new(client); + + mqtt.subscribe("zigbee2mqtt/bridge/logging").await.unwrap(); + mqtt.subscribe("zigbee2mqtt/bridge/event").await.unwrap(); + for (light, _) in LIGHT_MODELS { + mqtt.subscribe(&format!("zigbee2mqtt/{light}")) + .await + .unwrap(); + mqtt.request_state(light).await; + } + for radiator in RADIATOR_NAMES { + mqtt.subscribe(&format!("zigbee2mqtt/{radiator}")) + .await + .unwrap(); + mqtt.request_state(radiator).await; + } + mqtt.subscribe("zigbee2mqtt/small_bedroom:portable_button_panel") + .await + .unwrap(); + + trace!("Starting main zigbee management loops"); + let poll_mqtt = poll::poll_mqtt(eventloop, &known_states, reading_callback); + let handle_changes = changes::handle( + change_receiver, + &mut mqtt, + &known_states, + needed_states, + ); + + tokio::select! { + () = handle_changes => unreachable!("should not panic"), + () = poll_mqtt => unreachable!("should not panic") + } +} diff --git a/crates/zigbee-bridge/src/cached_bridge/changes.rs b/crates/zigbee-bridge/src/cached_bridge/changes.rs new file mode 100644 index 00000000..c0c3f32c --- /dev/null +++ b/crates/zigbee-bridge/src/cached_bridge/changes.rs @@ -0,0 +1,119 @@ +use std::collections::HashMap; +use std::time::{Duration, Instant}; + +use tokio::sync::{mpsc, RwLock}; +use tokio::time::{sleep, timeout}; +use tracing::{error, instrument, warn}; + +use super::mqtt::Mqtt; +use super::{ + CHANGE_ACCUMULATION_TIME, MQTT_MIGHT_BE_DOWN_TIMEOUT, + OFFLINE_CHECK_INTERVAL, WAIT_FOR_INIT_STATES, +}; +use crate::device::{Device, Property}; + +pub(super) async fn handle( + mut change_receiver: mpsc::UnboundedReceiver<(String, Property)>, + mqtt: &mut Mqtt, + known_states: &RwLock>>, + // Must be passed so it can be statically initialized in cached_bridge + // with concrete types + mut needed_states: HashMap>, +) -> ! { + // Give the initial known states a chance to be fetched + sleep(WAIT_FOR_INIT_STATES).await; + + let mut call_at_least_in = MQTT_MIGHT_BE_DOWN_TIMEOUT; + + loop { + match timeout(call_at_least_in, change_receiver.recv()).await { + // On change, update needed, but only actually send the changes + // after a timeout + Ok(update) => { + let (device_name, change) = + update.expect("Channel should never close"); + + apply_change_to_needed(device_name, change, &mut needed_states); + + // When there hasn't been a new change in 100 milliseconds, we + // will timeout and send the accumulated changes + call_at_least_in = CHANGE_ACCUMULATION_TIME; + } + _ => { + // Send the accumulated changes and get the timeout for re-sending + call_at_least_in = + send_diff_get_timeout(known_states, &needed_states, mqtt) + .await + .min(MQTT_MIGHT_BE_DOWN_TIMEOUT); + } + }; + } +} + +/// Might not be done in case a device property in needed does not match known +/// however has recently been set/send. Needs a recheck in the near future to +/// make sure the set/send takes effect. We do not send it again now as that +/// would be a little spammy. Returns when we need to recheck. If we do not need +/// to do so we return Duration::MAX. +#[instrument(skip_all)] +async fn send_diff_get_timeout( + known_states: &RwLock>>, + needed_states: &HashMap>, + mqtt: &mut Mqtt, +) -> Duration { + let known_states = known_states.read().await; + let mut device_deadlines = Vec::new(); + + for (device_name, needed) in needed_states { + tracing::Span::current().record("device_name", device_name); + + let diff = match known_states.get(device_name) { + Some(known) => needed.changes_relative_to(known.as_ref()), + None => needed.all_set_properties().values().cloned().collect(), + }; + + let is_online = match known_states.get(device_name) { + Some(known) => known.is_online(), + // we assume the device is online so that init messages get sent + None => true, + }; + + if is_online { + let merged_payloads = needed.needs_merged_payloads(); + // This is where we can send changes, and thus the deadline can change + let _ = mqtt + .send_diff_where_due(device_name, merged_payloads, &diff) + .await; + // Only check what the next deadline is if it could have changed + if let Some(deadline) = mqtt.next_deadline(device_name, &diff) { + device_deadlines.push(deadline); + } + } else { + // If the device is offline, the deadline can't have changed, so + // we use the offline check interval + device_deadlines.push(Instant::now() + OFFLINE_CHECK_INTERVAL); + } + } + + device_deadlines + .into_iter() + .min() + .map(|deadline| deadline.saturating_duration_since(Instant::now())) + .unwrap_or(Duration::MAX) +} + +#[instrument(skip(needed_states))] +fn apply_change_to_needed( + device_name: String, + change: Property, + needed_states: &mut HashMap>, +) { + let Some(needed) = needed_states.get(&device_name) else { + error!("Unknown device name, not applying change!"); + return; + }; + + let mut needed = needed.clone(); + needed.apply(change); + needed_states.insert(device_name, needed.clone()); +} diff --git a/crates/zigbee-bridge/src/cached_bridge/mqtt.rs b/crates/zigbee-bridge/src/cached_bridge/mqtt.rs new file mode 100644 index 00000000..decd511a --- /dev/null +++ b/crates/zigbee-bridge/src/cached_bridge/mqtt.rs @@ -0,0 +1,182 @@ +use std::collections::HashMap; +use std::time::Instant; + +use rumqttc::v5::mqttbytes::QoS; +use rumqttc::v5::{AsyncClient, ClientError}; +use serde_json::json; +use tokio::time::sleep; +use tracing::{instrument, trace}; + +use crate::device::{Property, PropertyDiscriminants}; + +use super::{MIN_TIME_BETWEEN_SENDS, TIME_IT_TAKES_TO_APPLY_CHANGE}; + +pub(super) struct Mqtt { + client: AsyncClient, + // TODO: extract into SendTracker struct? + last_sent: + HashMap>, +} + +impl Mqtt { + pub(super) fn new(client: AsyncClient) -> Self { + Mqtt { + client, + last_sent: HashMap::new(), + } + } + + pub(super) async fn subscribe( + &self, + topic: &str, + ) -> Result<(), ClientError> { + // Its okay for messages to arrive twice or more. MQTT guarantees + // ordering and we only do something if the cached bridge indicates we + // need to so device states arriving twice is not an issue. + self.client.subscribe(topic, QoS::AtLeastOnce).await + } + + pub(super) async fn request_state(&self, name: &str) { + trace!("Requesting state for device {name}"); + let payload = json!({"state": ""}); + + self.get(name, payload.to_string()).await.unwrap(); + } + + pub(super) fn next_deadline( + &self, + device_name: &str, + diff: &[Property], + ) -> Option { + diff.iter() + .map(|change| self.change_next_due(device_name, change)) + .min() + } + + fn change_next_due(&self, device_name: &str, change: &Property) -> Instant { + let Some(device_send_record) = self.last_sent.get(device_name) else { + // lamp has never been sent before + return Instant::now(); + }; + + let Some((sent_at, prev_change)) = + device_send_record.get(&(*change).into()) + else { + // property has never been sent before + return Instant::now(); + }; + + // there is a new change + if prev_change != change { + return Instant::now(); + } + + // we are overdue + if sent_at.elapsed() > TIME_IT_TAKES_TO_APPLY_CHANGE { + return Instant::now(); + } + + *sent_at + TIME_IT_TAKES_TO_APPLY_CHANGE + } + + fn is_due(&self, device_name: &str, change: &Property) -> bool { + let deadline = self.change_next_due(device_name, change); + deadline < Instant::now() + } + + pub(super) async fn send_diff_where_due( + &mut self, + device_name: &str, + merged_payloads: bool, + diff: &[Property], + ) -> Result<(), ClientError> { + let mut due_changes = Vec::new(); + + for change in diff { + if self.is_due(device_name, change) { + due_changes.push(change); + + let device_send_record = + self.last_sent.entry(device_name.to_owned()).or_default(); + device_send_record + .insert((*change).into(), (Instant::now(), *change)); + } + } + + if !due_changes.is_empty() { + if merged_payloads { + let payload = merge_payloads(due_changes); + self.set(device_name, payload.to_string()).await?; + } else { + for change in due_changes { + // Send twice because... issues + self.set(device_name, change.payload().to_string()).await?; + sleep(MIN_TIME_BETWEEN_SENDS).await; + self.set(device_name, change.payload().to_string()).await?; + sleep(MIN_TIME_BETWEEN_SENDS).await; + } + } + } + + Ok(()) + } + + #[instrument(skip(self))] + async fn set( + &self, + friendly_name: &str, + payload: String, + ) -> Result<(), ClientError> { + let topic = format!("zigbee2mqtt/{friendly_name}/set"); + + self.publish(&topic, payload).await?; + Ok(()) + } + + async fn get( + &self, + friendly_name: &str, + payload: String, + ) -> Result<(), ClientError> { + let topic = format!("zigbee2mqtt/{friendly_name}/get"); + + self.publish(&topic, payload).await?; + Ok(()) + } + + #[instrument(skip(self))] + async fn publish( + &self, + topic: &str, + payload: String, + ) -> Result<(), ClientError> { + let properties = rumqttc::v5::mqttbytes::v5::PublishProperties { + message_expiry_interval: Some(5), // seconds + ..Default::default() + }; + + trace!("publishing"); + self.client + .publish_with_properties( + topic, + QoS::AtLeastOnce, + false, + payload, + properties, + ) + .await + } +} + +fn merge_payloads(mut changes: Vec<&Property>) -> serde_json::Value { + let payload = changes + .iter_mut() + .map(|c| c.payload()) + .map(|p| p.as_object().expect("Should be a map").to_owned()) + .reduce(|mut acc, mut e| { + acc.append(&mut e); + acc + }) + .unwrap(); + serde_json::Value::Object(payload.clone()) +} diff --git a/crates/zigbee-bridge/src/cached_bridge/poll.rs b/crates/zigbee-bridge/src/cached_bridge/poll.rs new file mode 100644 index 00000000..64ef788b --- /dev/null +++ b/crates/zigbee-bridge/src/cached_bridge/poll.rs @@ -0,0 +1,224 @@ +use std::{collections::HashMap, time::Duration}; + +use color_eyre::eyre::{Context, OptionExt}; +use color_eyre::{Result, Section}; +use regex::Regex; +use rumqttc::v5::{Event, EventLoop, Incoming}; +use serde_json::Value; +use tokio::{sync::RwLock, time::sleep}; +use tracing::{error, instrument, trace, warn}; + +use crate::device::{Device, Property}; +use crate::lamp::LampProperty; +use crate::parse; +use crate::radiator::RadiatorProperty; +use crate::{light_names, RADIATOR_NAMES}; + +pub(super) async fn poll_mqtt( + mut eventloop: EventLoop, + known_states: &RwLock>>, + reading_callback: impl Fn(protocol::Reading), +) -> ! { + loop { + let message = match eventloop.poll().await { + Ok(message) => message, + Err(err) => { + trace!("Error while polling: {err}"); + sleep(Duration::from_millis(100)).await; + continue; + } + }; + + let message = match parse_message(message) { + Ok(message) => message, + Err(err) => { + // zigbee2mqtt is quite fragile and frequently sends incorrect + // json. It seems to recover directly after though. + // + // The plan is to migrate away from zigbee2mqtt in the future to a + // custom build solution (because of the mentioned fragility). + // + // Until then this (zigbee bridge) is in maintenance only + // mode. For that reason we ignore any parsing error. + trace!("ZB error parsing mqtt message: {err:?}"); + continue; + } + }; + + match message { + Message::Update { + device_name, + changed, + readings, + } => { + for reading in readings { + reading_callback(reading); + } + update_state(known_states, &device_name, changed).await; + } + Message::Irrelevant => (), + } + } +} + +#[instrument(skip(known_states))] +async fn update_state( + known_states: &RwLock>>, + device_name: &str, + new: Vec, +) { + let mut known_states = known_states.write().await; + let Some(current_device) = known_states.get_mut(device_name) else { + if device_name != "small_bedroom:portable_button_panel" { + error!("Trying to update state for unknown device {device_name}, ignoring!"); + } + return; + }; + + for property in new { + current_device.apply(property); + } +} + +#[instrument(skip_all)] +fn parse_message(event: Event) -> Result { + let Event::Incoming(incoming) = event else { + return Ok(Message::Irrelevant); + }; + + let Incoming::Publish(message) = incoming else { + return Ok(Message::Irrelevant); + }; + + let topic: &str = &String::from_utf8_lossy(&message.topic); + match topic { + "zigbee2mqtt/bridge/event" => { + let json: Value = serde_json::from_slice(&message.payload) + .wrap_err("could not parse message payload as json")?; + let bridge_event = json + .as_object() + .ok_or_eyre("log should be map it is not") + .with_note(|| format!("json was: {json:?}"))?; + parse_bridge_event(bridge_event) + } + "zigbee2mqtt/bridge/logging" => { + let json: Value = serde_json::from_slice(&message.payload) + .wrap_err("could not parse message payload as json")?; + let log = json + .as_object() + .ok_or_eyre("log should be map it is not") + .with_note(|| format!("json was: {json:?}"))?; + parse_log_message(log) + } + topic => { + let topic: Vec<_> = topic.split('/').collect(); + let device_name = topic[1].to_string(); + let json: Value = serde_json::from_slice(&message.payload) + .wrap_err("Could not deserialize")?; + let map = json + .as_object() + .ok_or_eyre("Top level json must be object")?; + let changed = parse::properties(&device_name, map) + .wrap_err("failed to parse device state") + .with_note(|| format!("topic: {topic:?}"))?; + let mut readings = parse::radiator_readings(&device_name, map) + .wrap_err("failed to parse device readings") + .with_note(|| format!("topic: {topic:?}"))?; + let button_readings = + parse::portable_button_panel(&device_name, map) + .wrap_err("failed to parse media buttons") + .with_note(|| format!("topic: {topic:?}"))?; + readings.extend(button_readings); + Ok(Message::Update { + device_name, + changed, + readings, + }) + } + } +} + +fn parse_bridge_event( + payload: &serde_json::Map, +) -> Result { + let event = payload + .get("type") + .ok_or_eyre("no type in bridge event")? + .as_str() + .ok_or_eyre("bridge event type is not a string")?; + let data = payload + .get("data") + .ok_or_eyre("no data in bridge event")? + .as_object() + .ok_or_eyre("bridge event data is not a map")?; + let device_name = data + .get("friendly_name") + .ok_or_eyre("no name in bridge event data")? + .as_str() + .ok_or_eyre("bridge event friendly name is not a string")? + .to_owned(); + + let is_online = match event { + "device_joined" | "device_announce" => true, + "device_leave" => false, + _ => return Ok(Message::Irrelevant), + }; + + Ok(online_message(device_name, is_online)) +} + +fn parse_log_message(log: &serde_json::Map) -> Result { + let level = log.get("level").ok_or_eyre("no level in log message")?; + let message = log + .get("message") + .ok_or_eyre("no message in log message")? + .as_str() + .ok_or_eyre("log message is not a string")?; + + if level != "error" { + return Ok(Message::Irrelevant); + } + + let regex = Regex::new(r"Publish.*? to '(.*?)' failed").unwrap(); + + if level == "error" { + if let Some(caps) = regex.captures(message) { + let device_name = caps[1].to_string(); + + return Ok(online_message(device_name, false)); + } + } + + Ok(Message::Irrelevant) +} + +fn online_message(device_name: String, is_online: bool) -> Message { + if light_names().contains(&device_name.as_str()) { + Message::Update { + device_name, + changed: vec![LampProperty::Online(is_online).into()], + readings: Vec::new(), + } + } else if RADIATOR_NAMES.contains(&device_name.as_str()) { + Message::Update { + device_name, + changed: vec![RadiatorProperty::Online(is_online).into()], + readings: Vec::new(), + } + } else { + if device_name != "small_bedroom:portable_button_panel" { + error!("Unknown device name {device_name}, could not parse log"); + } + Message::Irrelevant + } +} + +#[derive(Debug)] +enum Message { + Update { + device_name: String, + changed: Vec, + readings: Vec, + }, + Irrelevant, +} diff --git a/crates/zigbee-bridge/src/conversion.rs b/crates/zigbee-bridge/src/conversion.rs new file mode 100644 index 00000000..8c7909dd --- /dev/null +++ b/crates/zigbee-bridge/src/conversion.rs @@ -0,0 +1,49 @@ +use colorimetry::{cct::CCT, xyz::XYZ}; + +#[must_use] +pub(super) fn mired_to_kelvin(mired: usize) -> usize { + 1_000_000 / mired +} + +#[must_use] +pub(super) fn kelvin_to_mired(kelvin: usize) -> usize { + 1_000_000 / kelvin +} + +#[must_use] +pub(super) fn normalize(brightness: u8) -> f64 { + f64::from(brightness) / 254. +} + +#[must_use] +#[allow(clippy::cast_possible_truncation, clippy::cast_sign_loss)] +pub(super) fn denormalize(brightness: f64) -> u8 { + (brightness * 254.).round() as u8 +} + +pub(super) fn round_to_half(setpoint: f64) -> f64 { + (setpoint * 2.).round() / 2. +} + +pub(super) fn times_100_int(reference: f64) -> usize { + (reference * 100.).round() as usize +} + +#[allow(clippy::doc_markdown)] +/// 1000K < `color_temp` < 1_000_000K +pub(super) fn temp_to_xy( + color_temp_k: usize, + color_deviation: f64, +) -> (f64, f64) { + #[allow(clippy::cast_precision_loss)] + let cct = CCT::try_new(color_temp_k as f64, color_deviation).unwrap(); + let xyz: XYZ = cct.try_into().unwrap(); + + let (x, y) = xyz_to_xy(xyz); + (x.clamp(0.0, 1.0), y.clamp(0.0, 1.0)) +} + +fn xyz_to_xy(xyz: XYZ) -> (f64, f64) { + let [x, y, z] = xyz.values(); + (x / (x + y + z), y / (x + y + z)) +} diff --git a/crates/zigbee-bridge/src/device.rs b/crates/zigbee-bridge/src/device.rs new file mode 100644 index 00000000..47a85d1a --- /dev/null +++ b/crates/zigbee-bridge/src/device.rs @@ -0,0 +1,76 @@ +use std::collections::HashMap; +use std::fmt::Debug; + +use crate::lamp::{Lamp, LampProperty, LampPropertyDiscriminants}; +use crate::radiator::{ + Radiator, RadiatorProperty, RadiatorPropertyDiscriminants, +}; +use crate::{LIGHT_MODELS, RADIATOR_NAMES}; + +#[derive(PartialEq, Debug, Clone, Copy)] +pub(crate) enum Property { + Lamp(LampProperty), + Radiator(RadiatorProperty), +} + +impl Property { + pub(crate) fn payload(&self) -> serde_json::Value { + match self { + Property::Lamp(lamp_prop) => lamp_prop.payload(), + Property::Radiator(rad_prop) => rad_prop.payload(), + } + } +} + +#[derive(PartialEq, Eq, Hash, Debug)] +pub(crate) enum PropertyDiscriminants { + Lamp(LampPropertyDiscriminants), + Radiator(RadiatorPropertyDiscriminants), +} + +impl From for PropertyDiscriminants { + fn from(val: Property) -> Self { + match val { + Property::Lamp(lamp_prop) => { + PropertyDiscriminants::Lamp(lamp_prop.into()) + } + Property::Radiator(rad_prop) => { + PropertyDiscriminants::Radiator(rad_prop.into()) + } + } + } +} + +pub(crate) trait Device: Sync + Send + Debug { + fn new(name: &str) -> Self + where + Self: Sized; + + fn clone_dyn(&self) -> Box; + + fn apply(&mut self, change: Property); + fn changes_relative_to(&self, other: &dyn Device) -> Vec; + fn all_set_properties(&self) -> HashMap; + + fn needs_merged_payloads(&self) -> bool; + fn is_online(&self) -> bool; +} + +impl Clone for Box { + fn clone(&self) -> Self { + self.clone_dyn() + } +} + +pub(crate) fn init_states() -> HashMap> { + let mut states = HashMap::new(); + for (light_name, _) in LIGHT_MODELS { + let device: Box = Box::new(Lamp::new(light_name)); + states.insert(light_name.to_owned(), device); + } + for radiator_name in RADIATOR_NAMES { + let device: Box = Box::new(Radiator::new(radiator_name)); + states.insert(radiator_name.to_owned(), device); + } + states +} diff --git a/crates/zigbee-bridge/src/lamp.rs b/crates/zigbee-bridge/src/lamp.rs new file mode 100644 index 00000000..6bce9ec0 --- /dev/null +++ b/crates/zigbee-bridge/src/lamp.rs @@ -0,0 +1,149 @@ +use std::collections::HashMap; + +use strum::IntoEnumIterator; +use tracing::{error, instrument}; + +use super::conversion::temp_to_xy; +use crate::device::{Device, Property, PropertyDiscriminants}; +pub(crate) use model::Model; +pub(crate) use property::{LampProperty, LampPropertyDiscriminants}; + +mod model; +mod property; +mod color_correction; + +#[derive(Clone, Copy, Debug)] +enum Color { + TempK(usize), + XY((f64, f64)), +} + +impl Color { + fn xy_from_temp(temp: usize, model: &Model) -> Color { + Color::XY(temp_to_xy(temp, model.color_deviation(temp))) + } +} + +// TODO: some way to enforce read-only (thus known-updatable-only) fields? +#[derive(Clone, Debug)] +pub(crate) struct Lamp { + model: Model, + is_online: bool, + brightness: Option, + color: Option, + is_on: Option, + color_temp_startup: property::ColorTempStartup, +} + +impl Device for Lamp { + fn new(name: &str) -> Self { + Self { + model: Model::from_light(name), + // we assume the lamp is online so that init messages get sent + is_online: true, + brightness: None, + color: None, + is_on: None, + color_temp_startup: property::ColorTempStartup::default(), + } + } + + fn clone_dyn(&self) -> Box { + Box::new(self.clone()) + } + + fn needs_merged_payloads(&self) -> bool { + self.model.is_hue() + } + + fn is_online(&self) -> bool { + self.is_online + } + + #[instrument] + fn changes_relative_to(&self, other: &dyn Device) -> Vec { + let mut res = Vec::new(); + + let self_properties = self.all_set_properties(); + let other_properties = other.all_set_properties(); + + for property in LampProperty::iter() { + let self_prop = self_properties.get(&property.into()); + let other_prop = other_properties.get(&property.into()); + + // Ignore model (not a prop) and online, because they are read-only + if let Some(Property::Lamp(LampProperty::Online(_))) = self_prop { + continue; + } + + if let Some(self_prop) = self_prop { + if other_prop.is_none_or(|other_prop| self_prop != other_prop) { + res.push(*self_prop); + } + } + } + + res + } + + fn apply(&mut self, change: Property) { + let Property::Lamp(change) = change else { + error!("Trying to apply non-lamp change {change:?} to lamp!"); + return; + }; + + match change { + LampProperty::On(is_on) => self.is_on = Some(is_on), + LampProperty::Brightness(bri) => self.brightness = Some(bri), + LampProperty::ColorTempK(temp) => { + // if we know the model, we know how to apply temp + if self.model.supports_xy() { + self.color = Some(Color::xy_from_temp(temp, &self.model)); + } else { + let range = self.model.temp_k_range(); + let temp = temp.clamp(range.start, range.end); + self.color = Some(Color::TempK(temp)) + } + } + LampProperty::ColorXY(xy) => { + // don't apply xy to unknown or non-color lamp + if self.model.supports_xy() { + self.color = Some(Color::XY(xy)) + } + } + LampProperty::ColorTempStartup(behaviour) => { + self.color_temp_startup = behaviour + } + LampProperty::Online(is_online) => self.is_online = is_online, + } + } + + fn all_set_properties(&self) -> HashMap { + let mut properties: HashMap = + HashMap::new(); + + let mut insert_prop = + |prop: LampProperty| properties.insert(prop.into(), prop.into()); + + // Ignore model and is_online, because they are read-only + + if let Some(val) = self.brightness { + insert_prop(LampProperty::Brightness(val)); + } + if let Some(val) = self.color { + match val { + Color::XY(xy) => { + insert_prop(LampProperty::ColorXY(xy)); + } + Color::TempK(temp) => { + insert_prop(LampProperty::ColorTempK(temp)); + } + } + } + if let Some(val) = self.is_on { + insert_prop(LampProperty::On(val)); + } + insert_prop(LampProperty::ColorTempStartup(self.color_temp_startup)); + properties + } +} diff --git a/crates/zigbee-bridge/src/lamp/color_correction.rs b/crates/zigbee-bridge/src/lamp/color_correction.rs new file mode 100644 index 00000000..e1524a38 --- /dev/null +++ b/crates/zigbee-bridge/src/lamp/color_correction.rs @@ -0,0 +1,141 @@ +use std::collections::BTreeMap; + +use tracing::error; + +use super::Model; + +pub(super) fn temp_correction(model: &Model, color_temp: usize) -> isize { + interpolate(color_temp, temp_table(model)).round() as isize +} + +pub(super) fn blackbody_deviation(model: &Model, color_temp: usize) -> f64 { + interpolate(color_temp, blackbody_table(model)) +} + +// Value for actual color temp (after temp correction) +fn blackbody_table(model: &Model) -> BTreeMap { + match model { + // 604.391.68 data + Model::TradfriE27 | Model::TradfriOther(_) => vec![ + (1964, -0.003), + (2090, 0.0014), + (2668, 0.0015), + (3046, 0.001), + (3499, 0.0015), + (3605, -0.0011), + (4098, -0.0017), + (4110, -0.0009), + (4250, 0.0007), + ], + // 204.391.94 data + Model::TradfriE14Color => vec![ + (1841, -0.0032), + (2055, -0.0034), + (2120, 0.0012), + (2738, -0.0005), + (3070, 0.0004), + (3467, 0.0045), + (3555, 0.00), + (3981, 0.0009), + (4113, 0.0037), + ], + // LCA005 data + Model::HueGen1 + | Model::HueGen2 + | Model::Hue1600Lm + | Model::HueOther(_) => vec![ + (1998, 0.0005), + (2197, 0.00000), + (2519, -0.0004), + (2695, -0.0007), + (2849, -0.001), + (2990, -0.0011), + (3155, -0.0012), + (3358, -0.0013), + (3633, -0.0012), + (3864, -0.0011), + (4010, -0.0009), + (5455, 0.0005), + (6495, 0.0014), + ], + Model::TradfriGU10 => vec![ + (2112, 0.0032), + (2354, 0.0003), + (2744, -0.0018), + (3109, -0.0023), + (3352, -0.002), + (3826, -0.0002), + (4035, 0.0005), + (4147, 0.0011), + ], + Model::Other(_) => vec![(2500, 0.)], + Model::TradfriCandle | Model::TradfriE14White => { + error!("Trying to color correct for non-color bulb {model:?}"); + vec![(2500, 0.)] + } + } + .into_iter() + .collect() +} + +// Value to add to requested color temp +fn temp_table(model: &Model) -> BTreeMap { + match model { + // 604.391.68 data + Model::TradfriE27 | Model::TradfriOther(_) => { + vec![(2200, 110.), (2700, 30.), (4000, -110.)] + } + // 204.391.94 data + Model::TradfriE14Color => { + vec![(2200, 70.), (2700, -40.), (4000, 20.)] + } + // A19 Color 9.5W data + Model::HueGen1 + | Model::HueGen2 + | Model::Hue1600Lm + | Model::HueOther(_) => { + vec![ + (2200, 2.), + (2700, 5.), + (4000, -10.), + (5500, 45.), + (6500, 5.), + ] + } + Model::TradfriGU10 => vec![(2200, -90.), (2700, 40.), (4000, 40.)], + Model::Other(_) => vec![(2500, 0.)], + Model::TradfriCandle | Model::TradfriE14White => { + error!("Trying to color correct for non-color bulb {model:?}"); + vec![(2500, 0.)] + } + } + .into_iter() + .collect() +} + +fn interpolate(temp: usize, table: BTreeMap) -> f64 { + if let Some(val) = table.get(&temp) { + return *val; + } + + let larger = table + .iter() + .filter(|(k, _)| *k > &temp) + .min_by_key(|(k, _)| *k); + let smaller = table + .iter() + .filter(|(k, _)| *k < &temp) + .max_by_key(|(k, _)| *k); + + if let (Some(smaller), Some(larger)) = (smaller, larger) { + // Linear interpolation + return smaller.1 + + (temp - smaller.0) as f64 * (larger.1 - smaller.1) + / (*larger.0 as f64 - *smaller.0 as f64); + } + + match smaller.or(larger) { + Some(nearest) => *nearest.1, + None => 0.0, + } +} diff --git a/crates/zigbee-bridge/src/lamp/model.rs b/crates/zigbee-bridge/src/lamp/model.rs new file mode 100644 index 00000000..7354dc4f --- /dev/null +++ b/crates/zigbee-bridge/src/lamp/model.rs @@ -0,0 +1,104 @@ +use std::{collections::HashMap, ops::Range}; + +use tracing::warn; + +use crate::LIGHT_MODELS; + +use super::color_correction; + +#[derive(Debug, Clone, PartialEq, Eq)] +pub(crate) enum Model { + /// LED2107C4 TRADFRI bulb E14, white spectrum, candle, opal, 470 lm + TradfriCandle, + /// LED2109G6 TRADFRI bulb E26/E27, color/white spectrum, globe, opal, 800/806/810 lm + TradfriE27, + /// LED1923R5 TRADFRI bulb GU10, color/white spectrum, 345/380 lm + TradfriGU10, + /// LED2111G6 TRADFRI bulb E14, color/white spectrum, globe, opal, 806 lm + TradfriE14Color, + /// LED2101G4 TRADFRI bulb E12/E14, white spectrum, globe, opal, 450/470 lm + TradfriE14White, + /// 9290012573A Hue white and color ambiance E26/E27/E14 + /// 600 lm + /// LCT001 + HueGen1, + /// 9290012573A Hue white and color ambiance E26/E27/E14 + /// 800 lm + /// LCT007 + HueGen2, + /// 9290038536H Hue white ambiance and color + /// 1600 lm + /// LCA012 + Hue1600Lm, + #[allow(unused)] + TradfriOther(String), + #[allow(unused)] + HueOther(String), + Other(String), +} + +impl Model { + pub(super) fn from_light(name: &str) -> Self { + let map = HashMap::from(LIGHT_MODELS); + match map.get(name) { + Some(model) => model.clone(), + None => { + warn!("No model known for light {name}"); + Model::Other(String::from("Unknown")) + } + } + } + + pub(super) fn supports_xy(&self) -> bool { + #[allow(clippy::match_same_arms)] // clearer comment + match self { + Model::TradfriE27 + | Model::TradfriE14Color + | Model::HueGen1 + | Model::HueGen2 + | Model::Hue1600Lm + | Model::TradfriGU10 => true, + Model::TradfriCandle | Model::TradfriE14White => false, + // We assume no so that things at least don't break + Model::TradfriOther(_) | Model::HueOther(_) | Model::Other(_) => { + false + } + } + } + + pub(super) fn temp_k_range(&self) -> Range { + match self { + Model::TradfriCandle | Model::TradfriGU10 => 2200..4000, + Model::TradfriE27 | Model::TradfriE14Color => 1780..4000, + Model::TradfriE14White => 2000..4000, + Model::HueGen1 | Model::HueGen2 | Model::Hue1600Lm => 2000..6500, + Model::TradfriOther(_) => 2200..4000, + Model::HueOther(_) => 2200..6500, + Model::Other(_) => 2200..4000, + } + } + + pub(super) fn color_deviation(&self, color_temp: usize) -> f64 { + let temp = color_temp.saturating_add_signed( + color_correction::temp_correction(self, color_temp), + ); + color_correction::blackbody_deviation(self, temp) + } + + pub(crate) fn is_hue(&self) -> bool { + match self { + Model::TradfriCandle + | Model::TradfriE27 + | Model::TradfriGU10 + | Model::TradfriE14Color + | Model::TradfriE14White + | Model::TradfriOther(_) => false, + Model::HueGen1 + | Model::HueGen2 + | Model::Hue1600Lm + | Model::HueOther(_) => true, + // I guess we default to sending payloads separately + Model::Other(_) => false, + } + } +} diff --git a/crates/zigbee-bridge/src/lamp/property.rs b/crates/zigbee-bridge/src/lamp/property.rs new file mode 100644 index 00000000..b7c18020 --- /dev/null +++ b/crates/zigbee-bridge/src/lamp/property.rs @@ -0,0 +1,115 @@ +use serde_json::json; +use strum::{EnumDiscriminants, EnumIter}; +use tracing::error; + +use crate::{ + conversion::{denormalize, kelvin_to_mired}, + device::{Property, PropertyDiscriminants}, +}; + +#[derive(Debug, Default, Clone, Copy, PartialEq, Eq)] +pub(crate) enum ColorTempStartup { + #[default] + Previous, +} + +#[derive(Debug, EnumDiscriminants, EnumIter, Clone, Copy)] +#[strum_discriminants(derive(Hash))] +pub(crate) enum LampProperty { + Online(bool), + Brightness(f64), + ColorTempK(usize), + ColorXY((f64, f64)), + On(bool), + ColorTempStartup(ColorTempStartup), +} + +impl From for Property { + fn from(value: LampProperty) -> Self { + Self::Lamp(value) + } +} + +impl From for PropertyDiscriminants { + fn from(value: LampProperty) -> Self { + Self::Lamp(value.into()) + } +} + +impl TryFrom for LampProperty { + type Error = String; + + fn try_from(value: Property) -> Result { + match value { + Property::Lamp(lamp_prop) => Ok(lamp_prop), + _ => Err("Tried to interpret non-lamp property as lamp property" + .to_owned()), + } + } +} + +impl PartialEq for LampProperty { + fn eq(&self, other: &Self) -> bool { + match (self, other) { + (LampProperty::Brightness(a), LampProperty::Brightness(b)) => { + bri_is_close(*a, *b) + } + (LampProperty::ColorTempK(a), LampProperty::ColorTempK(b)) => { + temp_is_close(*a, *b) + } + (LampProperty::ColorXY(a), LampProperty::ColorXY(b)) => { + xy_is_close(*a, *b) + } + (LampProperty::On(a), LampProperty::On(b)) => a == b, + ( + LampProperty::ColorTempStartup(a), + LampProperty::ColorTempStartup(b), + ) => a == b, + // we never need to update this, thus we always consider it the same + (LampProperty::Online(_), LampProperty::Online(_)) => true, + (_, _) => false, + } + } +} + +impl Eq for LampProperty {} + +impl LampProperty { + pub(crate) fn payload(&self) -> serde_json::Value { + match *self { + LampProperty::Brightness(bri) => { + json!({ "brightness": denormalize(bri) }) + } + LampProperty::ColorTempK(k) => { + json!({ "color_temp": kelvin_to_mired(k) }) + } + LampProperty::ColorXY((x, y)) => { + json!({ "color": {"x": x, "y": y} }) + } + LampProperty::On(lamp_on) if lamp_on => json!({"state": "ON"}), + LampProperty::On(_) => json!({"state": "OFF"}), + LampProperty::ColorTempStartup(ColorTempStartup::Previous) => { + json!({"color_temp_startup": "previous"}) + } + // read-only, shouldn't be called, safe default + LampProperty::Online(_) => { + error!("Tried to convert Online to payload"); + json!({"state": ""}) + } + } + } +} + +pub(super) fn bri_is_close(a: f64, b: f64) -> bool { + (a - b).abs() < 1. / 250. +} + +fn temp_is_close(a: usize, b: usize) -> bool { + a.abs_diff(b) < 50 +} + +fn xy_is_close(a: (f64, f64), b: (f64, f64)) -> bool { + let d_color_x = (a.0 - b.0).abs(); + let d_color_y = (a.1 - b.1).abs(); + d_color_x < 0.01 && d_color_y < 0.01 +} diff --git a/crates/zigbee-bridge/src/lib.rs b/crates/zigbee-bridge/src/lib.rs new file mode 100644 index 00000000..22188bdd --- /dev/null +++ b/crates/zigbee-bridge/src/lib.rs @@ -0,0 +1,118 @@ +#![allow(clippy::missing_panics_doc)] +use std::net::IpAddr; + +use tokio::sync::mpsc; +use tracing::trace; + +pub(crate) use lamp::Model; + +use self::{device::Property, lamp::LampProperty, radiator::RadiatorProperty}; + +mod cached_bridge; +mod conversion; +mod device; +pub(crate) mod lamp; +mod parse; +mod radiator; + +const MQTT_PORT: u16 = 1883; +const LIGHT_MODELS: [(&str, Model); 16] = [ + ("kitchen:fridge", Model::TradfriE14Color), + ("kitchen:hallway", Model::TradfriE27), + ("kitchen:hood_left", Model::TradfriCandle), + ("kitchen:hood_right", Model::TradfriCandle), + ("kitchen:ceiling", Model::Hue1600Lm), + ("large_bedroom:cabinet", Model::TradfriGU10), + ("large_bedroom:ceiling", Model::TradfriE27), + ("large_bedroom:desk", Model::TradfriE27), + ("large_bedroom:wardrobe", Model::TradfriE27), + ("large_bedroom:bed", Model::TradfriE14White), + ("small_bedroom:table", Model::Hue1600Lm), + ("small_bedroom:bureau", Model::HueGen1), + ("small_bedroom:piano", Model::TradfriE27), + ("bathroom:ceiling", Model::HueGen1), + ("hallway:ceiling", Model::TradfriE27), + ("toilet:ceiling", Model::HueGen2), +]; +const RADIATOR_NAMES: [&str; 2] = + ["small_bedroom:radiator", "large_bedroom:radiator"]; + +fn light_names() -> Vec<&'static str> { + LIGHT_MODELS.into_iter().map(|(k, _)| k).collect() +} + +#[derive(Debug, Clone)] +pub struct Controller { + change_sender: mpsc::UnboundedSender<(String, Property)>, +} + +impl Controller { + #[must_use] + pub fn start_bridge(mqtt_ip: IpAddr, name: &str) -> Self { + Self::start_bridge_with_reading_callback(mqtt_ip, name, |_| ()) + } + #[must_use] + pub fn start_bridge_with_reading_callback( + mqtt_ip: IpAddr, + name: &str, + reading_callback: impl Fn(protocol::Reading) + Send + 'static, + ) -> Self { + let (change_sender, change_receiver) = mpsc::unbounded_channel(); + + let run_bridge = cached_bridge::run( + mqtt_ip, + change_receiver, + name.to_string(), + reading_callback, + ); + trace!("Spawning zigbee bridge task"); + tokio::task::spawn(run_bridge); + + Self { change_sender } + } + + pub fn set_on(&self, light_name: &str) { + self.send_to_light(light_name, LampProperty::On(true)); + } + + pub fn set_off(&self, light_name: &str) { + self.send_to_light(light_name, LampProperty::On(false)); + } + + /// Brightness from 0 to 1 + pub fn set_brightness(&self, light_name: &str, brightness: f64) { + self.send_to_light(light_name, LampProperty::Brightness(brightness)); + } + + pub fn set_color_temp(&self, light_name: &str, kelvin: usize) { + self.send_to_light(light_name, LampProperty::ColorTempK(kelvin)); + } + + pub fn set_color_xy(&self, light_name: &str, xy: (f64, f64)) { + self.send_to_light(light_name, LampProperty::ColorXY(xy)); + } + + pub fn set_radiator_setpoint(&self, radiator_name: &str, setpoint: f64) { + self.change_sender + .send(( + radiator_name.to_owned(), + RadiatorProperty::Setpoint(setpoint).into(), + )) + .expect("Sender should never be dropped"); + } + + pub fn set_radiator_reference(&self, radiator_name: &str, reference: f64) { + self.change_sender + .send(( + radiator_name.to_owned(), + RadiatorProperty::Reference(reference).into(), + )) + .expect("Sender should never be dropped"); + } + + fn send_to_light(&self, light_name: &str, lamp_property: LampProperty) { + self.change_sender + .send((light_name.to_string(), lamp_property.into())) + .expect("Sender should never be dropped"); + } +} diff --git a/crates/zigbee-bridge/src/parse.rs b/crates/zigbee-bridge/src/parse.rs new file mode 100644 index 00000000..7dd486f0 --- /dev/null +++ b/crates/zigbee-bridge/src/parse.rs @@ -0,0 +1,306 @@ +use color_eyre::eyre::{bail, Context, OptionExt, Report, Result}; +use color_eyre::Section; +use protocol::small_bedroom; +use serde_json::{Map, Value}; +use tracing::instrument; + +use crate::conversion::{mired_to_kelvin, normalize}; +use crate::device::Property; +use crate::lamp::LampProperty; +use crate::radiator::RadiatorProperty; +use crate::{light_names, RADIATOR_NAMES}; + +#[instrument(skip(map))] +pub(super) fn properties( + device_name: &str, + map: &Map, +) -> Result> { + if light_names().contains(&device_name) { + parse_lamp_properties(map) + } else if RADIATOR_NAMES.contains(&device_name) { + parse_radiator_properties(map) + } else { + Ok(Vec::new()) + } +} + +pub(crate) fn portable_button_panel( + device_name: &str, + map: &Map, +) -> Result> { + use protocol::small_bedroom::portable_button_panel::Reading as R; + let action_reading_mapping = [ + ("toggle", R::PlayPause), + ("track_next", R::TrackNext), + ("track_previous", R::TrackPrevious), + ("volume_up", R::VolumeUp), + ("volume_up_hold", R::VolumeUpHold), + ("volume_down", R::VolumeDown), + ("volume_down_hold", R::VolumeDownHold), + ("dots_1_initial_press", R::Dots1InitialPress), + ("dots_1_short_release", R::Dots1ShortRelease), + ("dots_1_double_press", R::Dots1DoublePress), + ("dots_1_long_press", R::Dots1LongPress), + ("dots_1_long_release", R::Dots1LongRelease), + ("dots_2_initial_press", R::Dots2InitialPress), + ("dots_2_short_release", R::Dots2ShortRelease), + ("dots_2_double_press", R::Dots2DoublePress), + ("dots_2_long_press", R::Dots2LongPress), + ("dots_2_long_release", R::Dots2LongRelease), + ]; + + if device_name == "small_bedroom:portable_button_panel" { + let action = map.get("action"); + // Ignore when it is Null for some reason + // or an empty string...... + if action == Some(&Value::Null) + || action == Some(&Value::String("".to_string())) + { + return Ok(None); + } + action + .map(json_to_str) + .transpose()? + .map(|action| { + action_reading_mapping + .iter() + .find(|(a, _)| action == *a) + .map(|(_, reading)| *reading) + .map(small_bedroom::Reading::PortableButtonPanel) + .map(protocol::Reading::SmallBedroom) + .ok_or_eyre( + "every action should have a corrosponding reading", + ) + .with_note(|| format!("action was: {action}")) + }) + .transpose() + } else { + Ok(None) + } +} + +pub(crate) fn radiator_readings( + device_name: &str, + map: &Map, +) -> Result> { + use protocol::{large_bedroom, small_bedroom, Reading}; + + macro_rules! radiator_readings { + ($protocol_module:ident, $ReadingVariant:ident) => { + Ok(std::iter::empty() + .into_iter() + .chain( + map.get("local_temperature") + .map(json_to_f32) + .transpose()? + .map($protocol_module::radiator::Reading::Temperature) + .map($protocol_module::Reading::Radiator) + .map(Reading::$ReadingVariant), + ) + .chain( + map.get("pi_heating_demand") + .map(json_to_f32) + .transpose()? + .map($protocol_module::radiator::Reading::Heating) + .map($protocol_module::Reading::Radiator) + .map(Reading::$ReadingVariant), + ) + .chain( + map.get("setpoint_change_source") + .map(json_to_str) + .transpose()? + .map(|val| match val.to_lowercase().as_str() { + "manual" => { + Ok(protocol::shared::radiator::Source::Manual) + } + "schedule" => { + Ok(protocol::shared::radiator::Source::Schedule) + } + "externally" => { + Ok(protocol::shared::radiator::Source::External) + } + _ => Err(color_eyre::eyre::eyre!( + "Unexpected change source {val}" + )), + }) + .transpose()? + .map($protocol_module::radiator::Reading::SetBy) + .map($protocol_module::Reading::Radiator) + .map(Reading::$ReadingVariant), + ) + .chain( + map.get("occupied_heating_setpoint") + .map(json_to_f32) + .transpose()? + .map($protocol_module::radiator::Reading::Setpoint) + .map($protocol_module::Reading::Radiator) + .map(Reading::$ReadingVariant), + ) + .collect()) + }; + } + + match device_name { + "small_bedroom:radiator" => { + radiator_readings!(small_bedroom, SmallBedroom) + } + "large_bedroom:radiator" => { + radiator_readings!(large_bedroom, LargeBedroom) + } + _ => Ok(Vec::new()), + } +} + +fn parse_radiator_properties( + map: &Map, +) -> Result> { + let mut list = Vec::new(); + + if let Some(setpoint) = map + .get("occupied_heating_setpoint") + .map(json_to_f64) + .transpose()? + { + list.push(RadiatorProperty::Setpoint(setpoint).into()); + } + + if let Some(reference) = map + .get("external_measured_room_sensor") + .map(json_to_i64) + .transpose()? + { + if reference == -8000 { + list.push(RadiatorProperty::NoReference.into()); + } else { + let reference = reference as f64 / 100.; + list.push(RadiatorProperty::Reference(reference).into()); + } + } + + if let Some(set_method) = map + .get("setpoint_change_source") + .map(|s| { + s.as_str() + .ok_or_eyre("Setpoint change source not a string") + .with_note(|| format!("Received: {s}")) + .map(|s| s.parse().unwrap()) + }) + .transpose()? + { + list.push(RadiatorProperty::SetByMethod(set_method).into()); + } + + Ok(list) +} + +fn parse_lamp_properties(map: &Map) -> Result> { + let mut list = Vec::new(); + + if let Some(kelvin) = map + .get("color_temp") + .map(json_to_usize) + .transpose()? + .map(mired_to_kelvin) + { + list.push(LampProperty::ColorTempK(kelvin).into()); + } + + if let Some(xy) = map + .get("color") + .map(|color| { + let color = color + .as_object() + .ok_or_eyre("Color json should be an object")?; + let color_x = + json_to_f64(color.get("x").ok_or_eyre("Need a key 'x'")?)?; + let color_y = + json_to_f64(color.get("y").ok_or_eyre("Need a key 'y'")?)?; + Ok::<_, Report>((color_x, color_y)) + }) + .transpose()? + { + list.push(LampProperty::ColorXY(xy).into()); + } + + if let Some(brightness) = map + .get("brightness") + .map(json_to_u8) + .transpose()? + .map(normalize) + { + list.push(LampProperty::Brightness(brightness).into()); + } + + if let Some(on) = map + .get("state") + .map(|on| { + let state = on.as_str().ok_or_eyre("state should be a string")?; + let on = match state { + "ON" => true, + "OFF" => false, + _ => bail!("state string should be ON or OFF"), + }; + Ok(on) + }) + .transpose()? + { + list.push(LampProperty::On(on).into()); + } + + // we have just received a state message, so the lamp must be online + list.push(LampProperty::Online(true).into()); + + Ok(list) +} + +fn json_to_usize(json: &Value) -> Result { + json_to_u64(json)? + .try_into() + .wrap_err("Should be a usize integer") + .with_note(|| format!("got: {json:?}")) +} + +fn json_to_u8(json: &Value) -> Result { + json_to_u64(json)? + .try_into() + .wrap_err("Should be a 8 bit integer") + .with_note(|| format!("got: {json:?}")) +} + +fn json_to_u64(json: &Value) -> Result { + json.as_number() + .ok_or_eyre("Must be a number") + .with_note(|| format!("got: {json:?}"))? + .as_u64() + .ok_or_eyre("Must be a positive integer") + .with_note(|| format!("got: {json:?}")) +} + +fn json_to_i64(json: &Value) -> Result { + json.as_number() + .ok_or_eyre("Must be a number") + .with_note(|| format!("got: {json:?}"))? + .as_i64() + .ok_or_eyre("Must be an integer") + .with_note(|| format!("got: {json:?}")) +} + +fn json_to_f64(json: &Value) -> Result { + Ok(json + .as_number() + .ok_or_eyre("Must be a number") + .with_note(|| format!("got: {json:?}"))? + .as_f64() + .expect("Should be Some if not using arbitrary precision")) +} + +fn json_to_str(json: &Value) -> Result<&str> { + json + .as_str() + .ok_or_eyre("Must be a string") + .with_note(|| format!("got: {json:?}")) +} + +fn json_to_f32(json: &Value) -> Result { + json_to_f64(json).map(|v| v as f32) +} diff --git a/crates/zigbee-bridge/src/radiator.rs b/crates/zigbee-bridge/src/radiator.rs new file mode 100644 index 00000000..4e359b72 --- /dev/null +++ b/crates/zigbee-bridge/src/radiator.rs @@ -0,0 +1,228 @@ +use std::{collections::HashMap, str::FromStr}; + +use serde_json::json; +use strum::{EnumDiscriminants, EnumIter, IntoEnumIterator}; +use tracing::{error, instrument}; + +use crate::{ + conversion::{round_to_half, times_100_int}, + device::{Device, Property, PropertyDiscriminants}, +}; + +#[derive(Debug, Clone)] +pub(crate) struct Radiator { + is_online: bool, + setpoint: Option, + reference: Option, + set_by_method: Option, +} + +#[derive(Debug, Clone, Copy, Default)] +pub(crate) enum SetMethod { + Manual, + Schedule, + #[default] + External, +} + +impl FromStr for SetMethod { + type Err = String; + + fn from_str(s: &str) -> Result { + match s.to_lowercase().as_str() { + "manual" => Ok(SetMethod::Manual), + "schedule" => Ok(SetMethod::Schedule), + "externally" => Ok(SetMethod::External), + invalid => { + Err(format!("Unknown set method encountered: {invalid}")) + } + } + } +} + +impl Device for Radiator { + fn new(_name: &str) -> Self + where + Self: Sized, + { + Self { + is_online: true, + setpoint: None, + reference: None, + set_by_method: None, + } + } + + fn clone_dyn(&self) -> Box { + Box::new(self.clone()) + } + + #[instrument] + fn apply(&mut self, change: Property) { + let Property::Radiator(change) = change else { + error!( + "Trying to apply non-radiator change {change:?} to radiator!" + ); + return; + }; + + match change { + RadiatorProperty::Online(is_online) => self.is_online = is_online, + RadiatorProperty::Setpoint(setpoint) => { + self.setpoint = Some(setpoint) + } + RadiatorProperty::Reference(reference) => { + self.reference = Some(reference) + } + // Ignore radiator reporting reference expired, so we don't start + // sending an old value + RadiatorProperty::NoReference => (), + RadiatorProperty::SetByMethod(set_method) => { + self.set_by_method = Some(set_method) + } + } + } + + fn changes_relative_to(&self, other: &dyn Device) -> Vec { + let mut res = Vec::new(); + + let self_properties = self.all_set_properties(); + let other_properties = other.all_set_properties(); + + for property in RadiatorProperty::iter() { + let self_prop = self_properties.get(&property.into()); + let other_prop = other_properties.get(&property.into()); + + // Ignore set_by_method and online, because they are read-only + if let Some(Property::Radiator( + RadiatorProperty::Online(_) | RadiatorProperty::SetByMethod(_), + )) = self_prop + { + continue; + } + + if let Some(self_prop) = self_prop { + if other_prop.is_none_or(|other_prop| self_prop != other_prop) { + res.push(*self_prop); + } + } + } + + res + } + + fn all_set_properties( + &self, + ) -> std::collections::HashMap { + let mut properties: HashMap = + HashMap::new(); + + let mut insert_prop = |prop: RadiatorProperty| { + properties.insert(prop.into(), prop.into()) + }; + + // Ignore set_by_method and online, because they are read-only + + if let Some(val) = self.setpoint { + insert_prop(RadiatorProperty::Setpoint(val)); + } + if let Some(val) = self.reference { + insert_prop(RadiatorProperty::Reference(val)); + } + + properties + } + + fn needs_merged_payloads(&self) -> bool { + false + } + + fn is_online(&self) -> bool { + self.is_online + } +} + +#[derive(Debug, EnumDiscriminants, EnumIter, Clone, Copy)] +#[strum_discriminants(derive(Hash))] +pub(crate) enum RadiatorProperty { + Online(bool), + Setpoint(f64), + Reference(f64), + NoReference, + SetByMethod(SetMethod), +} + +impl PartialEq for RadiatorProperty { + fn eq(&self, other: &Self) -> bool { + match (*self, *other) { + (RadiatorProperty::Setpoint(a), RadiatorProperty::Setpoint(b)) => { + round_to_half(a) == round_to_half(b) + } + ( + RadiatorProperty::Reference(a), + RadiatorProperty::Reference(b), + ) => times_100_int(a) == times_100_int(b), + // we never need to update these, so we always consider them the same + (RadiatorProperty::Online(_), RadiatorProperty::Online(_)) => true, + ( + RadiatorProperty::SetByMethod(_), + RadiatorProperty::SetByMethod(_), + ) => true, + (_, _) => false, + } + } +} + +impl RadiatorProperty { + pub(crate) fn payload(&self) -> serde_json::Value { + match *self { + RadiatorProperty::Setpoint(setpoint) => { + json!({"occupied_heating_setpoint": round_to_half(setpoint) }) + } + RadiatorProperty::Reference(reference) => { + json!({"external_measured_room_sensor": times_100_int(reference) }) + } + // read-only, shouldn't be called, safe default + RadiatorProperty::NoReference => { + error!("Tried to convert NoReference to payload"); + json!({"state": ""}) + } + // read-only, shouldn't be called, safe default + RadiatorProperty::Online(_) => { + error!("Tried to convert Online to payload"); + json!({"state": ""}) + } + // read-only, shouldn't be called, safe default + RadiatorProperty::SetByMethod(_) => { + error!("Tried to convert SetByMethod to payload"); + json!({"state": ""}) + } + } + } +} + +impl From for Property { + fn from(value: RadiatorProperty) -> Self { + Self::Radiator(value) + } +} + +impl From for PropertyDiscriminants { + fn from(value: RadiatorProperty) -> Self { + Self::Radiator(value.into()) + } +} + +impl TryFrom for RadiatorProperty { + type Error = String; + + fn try_from(value: Property) -> Result { + match value { + Property::Radiator(lamp_prop) => Ok(lamp_prop), + _ => Err( + "Tried to interpret non-radiator property as radiator property" + .to_owned(), + ), + } + } +} diff --git a/deploy_all.sh b/deploy_all.sh new file mode 100755 index 00000000..67addb4f --- /dev/null +++ b/deploy_all.sh @@ -0,0 +1,11 @@ +#!/usr/bin/env bash + +set -e + +for script in `find . -type f -name "deploy.sh"`; do + dir=`dirname "$script"` + cd "$dir" + # the deploy scripts need to run in the right working directory + . `basename "$script"` + cd - +done diff --git a/flake.lock b/flake.lock new file mode 100644 index 00000000..bf0440ad --- /dev/null +++ b/flake.lock @@ -0,0 +1,82 @@ +{ + "nodes": { + "flake-utils": { + "inputs": { + "systems": "systems" + }, + "locked": { + "lastModified": 1731533236, + "narHash": "sha256-l0KFg5HjrsfsO/JpG+r7fRrqm12kzFHyUHqHCVpMMbI=", + "owner": "numtide", + "repo": "flake-utils", + "rev": "11707dc2f618dd54ca8739b309ec4fc024de578b", + "type": "github" + }, + "original": { + "owner": "numtide", + "repo": "flake-utils", + "type": "github" + } + }, + "nixpkgs": { + "locked": { + "lastModified": 1765186076, + "narHash": "sha256-hM20uyap1a0M9d344I692r+ik4gTMyj60cQWO+hAYP8=", + "owner": "NixOS", + "repo": "nixpkgs", + "rev": "addf7cf5f383a3101ecfba091b98d0a1263dc9b8", + "type": "github" + }, + "original": { + "owner": "NixOS", + "ref": "nixos-unstable", + "repo": "nixpkgs", + "type": "github" + } + }, + "root": { + "inputs": { + "flake-utils": "flake-utils", + "nixpkgs": "nixpkgs", + "rust-overlay": "rust-overlay" + } + }, + "rust-overlay": { + "inputs": { + "nixpkgs": [ + "nixpkgs" + ] + }, + "locked": { + "lastModified": 1765248027, + "narHash": "sha256-ngar+yP06x3+2k2Iey29uU0DWx5ur06h3iPBQXlU+yI=", + "owner": "oxalica", + "repo": "rust-overlay", + "rev": "7b50ad68415ae5be7ee4cc68fa570c420741b644", + "type": "github" + }, + "original": { + "owner": "oxalica", + "repo": "rust-overlay", + "type": "github" + } + }, + "systems": { + "locked": { + "lastModified": 1681028828, + "narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=", + "owner": "nix-systems", + "repo": "default", + "rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e", + "type": "github" + }, + "original": { + "owner": "nix-systems", + "repo": "default", + "type": "github" + } + } + }, + "root": "root", + "version": 7 +} diff --git a/flake.nix b/flake.nix new file mode 100644 index 00000000..ce5c564e --- /dev/null +++ b/flake.nix @@ -0,0 +1,101 @@ +{ + description = "Home automation system, services and ui/interfaces"; + + inputs = { + nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable"; + flake-utils.url = "github:numtide/flake-utils"; + rust-overlay = { + url = "github:oxalica/rust-overlay"; + inputs = { + nixpkgs.follows = "nixpkgs"; + }; + }; + }; + + outputs = { self, nixpkgs, flake-utils, rust-overlay }: + flake-utils.lib.eachDefaultSystem + (system: + let + overlays = [ (import rust-overlay) ]; + pkgs = import nixpkgs { inherit system overlays; }; + rustToolchain = pkgs.rust-bin.fromRustupToolchainFile ./rust-toolchain.toml; + rust = pkgs.makeRustPlatform { + cargo = rustToolchain; + rustc = rustToolchain; + }; + + src = ./.; + cargoLock = { + lockFile = "${src}/Cargo.lock"; + outputHashes = { + "bme280-0.5.1" = "sha256-EV1V6XeYxjoIwI/mzTJp1CZriYKucCr14SkRWC8DaLE="; + "byteseries-0.7.1" = "sha256-Gz+uj56L5iCL6gHSEq9uFYLKYUaMXKkhWx8RhNKH77c="; + "colorimetry-0.0.2" = "sha256-Olxp0GMmUDDfeUiTusScwAidY5POOoe45K8ezAojN4Q="; + "dbstruct-0.6.0" = "sha256-3ACZN0+MJe3r9l/0/Lif3004D8NlBYs56gH3UQWqotY="; + "tui-tree-widget-0.23.0" = "sha256-rVHmuBg6x592pNBTzjVbzQ87J8HlbTAY9vz8ZPJwmYc="; + }; + }; + + #################################################################### + #### text widget package #### + #################################################################### + text-widget = with pkgs; let + cargoTOML = lib.importTOML "${src}/crates/text-widget/Cargo.toml"; + inherit rustToolchain rust; + in + rust.buildRustPackage + { + pname = cargoTOML.package.name; + version = cargoTOML.package.version; + + inherit src cargoLock; + + meta = { + inherit (cargoTOML.package) description homepage; + maintainers = cargoTOML.package.authors; + }; + }; + + + #################################################################### + #### text widget package #### + #################################################################### + ui = with pkgs; let + cargoTOML = lib.importTOML "${src}/crates/ui/Cargo.toml"; + inherit rustToolchain rust; + in + rust.buildRustPackage + { + pname = cargoTOML.package.name; + version = cargoTOML.package.version; + + inherit src cargoLock; + + meta = { + inherit (cargoTOML.package) description homepage; + maintainers = cargoTOML.package.authors; + }; + }; + + #################################################################### + #### dev shell #### + #################################################################### + devShell = with pkgs; + mkShell { + name = "ha"; + inputsFrom = [ text-widget ]; + RUST_SRC_PATH = "${rustPlatform.rustLibSrc}"; + CARGO_TERM_COLOR = "always"; + }; + in + { + ui = ui; + devShells.default = devShell; + defaultPackage = text-widget; + }) // { + overlays.default = _: prev: { + text-widget = self.defaultPackage.${prev.system}; + ui = self.ui.${prev.system}; + }; + }; +} diff --git a/nodes/Readme.md b/nodes/Readme.md new file mode 100644 index 00000000..015602fc --- /dev/null +++ b/nodes/Readme.md @@ -0,0 +1 @@ +While esp32 nodes use embassy they need a different time driver which causes linking issues if they are in the same workspace diff --git a/nodes/embassy/Cargo.lock b/nodes/embassy/Cargo.lock new file mode 100644 index 00000000..403bf4c5 --- /dev/null +++ b/nodes/embassy/Cargo.lock @@ -0,0 +1,1500 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 3 + +[[package]] +name = "ahash" +version = "0.8.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e89da841a80418a9b391ebaea17f5c112ffaaa96f621d2c285b5174da76b9011" +dependencies = [ + "cfg-if", + "once_cell", + "version_check", + "zerocopy", +] + +[[package]] +name = "aligned" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "377e4c0ba83e4431b10df45c1d4666f178ea9c552cac93e60c3a88bf32785923" +dependencies = [ + "as-slice", +] + +[[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 = "atomic-polyfill" +version = "1.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8cf2bce30dfe09ef0bfaef228b9d414faaf7e563035494d7fe092dba54b300f4" +dependencies = [ + "critical-section", +] + +[[package]] +name = "autocfg" +version = "1.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ace50bade8e6234aa140d9a2f552bbee1db4d353f69b8217bc503490fc1a9f26" + +[[package]] +name = "bare-metal" +version = "0.2.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5deb64efa5bd81e31fcd1938615a6d98c82eafcbcd787162b6f63b91d6bac5b3" +dependencies = [ + "rustc_version 0.2.3", +] + +[[package]] +name = "bed" +version = "0.2.0" +dependencies = [ + "cortex-m", + "cortex-m-rt", + "defmt 1.0.1", + "defmt-rtt", + "embassy-embedded-hal", + "embassy-executor", + "embassy-futures", + "embassy-stm32", + "embassy-sync", + "embassy-time", + "embassy-usb", + "embedded-hal 1.0.0", + "embedded-hal-async", + "embedded-hal-bus", + "embedded-io-async", + "futures", + "heapless 0.8.0 (git+https://github.com/rust-embedded/heapless?rev=0ebca23)", + "panic-probe", + "protocol", + "sensors", + "usb-bridge-client", +] + +[[package]] +name = "bit_field" +version = "0.10.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dc827186963e592360843fb5ba4b973e145841266c1357f7180c43526f2e5b61" + +[[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.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c8214115b7bf84099f1309324e63141d4c5d7cc26862f97a0a857dbefe165bd" + +[[package]] +name = "block-device-driver" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "44c051592f59fe68053524b4c4935249b806f72c1f544cfb7abe4f57c3be258e" +dependencies = [ + "aligned", +] + +[[package]] +name = "bosch-bme680" +version = "1.0.2" +dependencies = [ + "bitfield 0.14.0", + "defmt 0.3.100", + "embedded-hal 1.0.0", + "embedded-hal-async", +] + +[[package]] +name = "byteorder" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" + +[[package]] +name = "cfg-if" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" + +[[package]] +name = "cobs" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "67ba02a97a2bd10f4b59b25c7973101c79642302776489e030cd13cdab09ed15" + +[[package]] +name = "cortex-m" +version = "0.7.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8ec610d8f49840a5b376c69663b6369e71f4b34484b9b2eb29fb918d92516cb9" +dependencies = [ + "bare-metal", + "bitfield 0.13.2", + "critical-section", + "embedded-hal 0.2.7", + "volatile-register", +] + +[[package]] +name = "cortex-m-rt" +version = "0.7.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "801d4dec46b34c299ccf6b036717ae0fce602faa4f4fe816d9013b9a7c9f5ba6" +dependencies = [ + "cortex-m-rt-macros", +] + +[[package]] +name = "cortex-m-rt-macros" +version = "0.7.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e37549a379a9e0e6e576fd208ee60394ccb8be963889eebba3ffe0980364f472" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.100", +] + +[[package]] +name = "crc" +version = "3.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "69e6e4d7b33a94f0991c26729976b10ebde1d34c3ee82408fb536164fa10d636" +dependencies = [ + "crc-catalog", +] + +[[package]] +name = "crc-catalog" +version = "2.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "19d374276b40fb8bbdee95aef7c7fa6b5316ec764510eb64b8dd0e2ed0d7e7f5" + +[[package]] +name = "critical-section" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "790eea4361631c5e7d22598ecd5723ff611904e3344ce8720784c93e3d83d40b" + +[[package]] +name = "darling" +version = "0.20.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6f63b86c8a8826a49b8c21f08a2d07338eec8d900540f8630dc76284be802989" +dependencies = [ + "darling_core", + "darling_macro", +] + +[[package]] +name = "darling_core" +version = "0.20.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "95133861a8032aaea082871032f5815eb9e98cef03fa916ab4500513994df9e5" +dependencies = [ + "fnv", + "ident_case", + "proc-macro2", + "quote", + "strsim", + "syn 2.0.100", +] + +[[package]] +name = "darling_macro" +version = "0.20.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d336a2a514f6ccccaa3e09b02d41d35330c07ddf03a62165fcec10bb561c7806" +dependencies = [ + "darling_core", + "quote", + "syn 2.0.100", +] + +[[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.100", +] + +[[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.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b2cac3b8a5644a9e02b75085ebad3b6deafdbdbdec04bb25086523828aa4dfd1" +dependencies = [ + "critical-section", + "defmt 1.0.1", +] + +[[package]] +name = "document-features" +version = "0.2.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "95249b50c6c185bee49034bcb378a49dc2b5dff0be90ff6616d31d64febab05d" +dependencies = [ + "litrs", +] + +[[package]] +name = "embassy-embedded-hal" +version = "0.3.1" +source = "git+https://github.com/embassy-rs/embassy?rev=2cae242#2cae242f51cd1553ca9deb1cfd73daed606c5476" +dependencies = [ + "defmt 1.0.1", + "embassy-futures", + "embassy-hal-internal", + "embassy-sync", + "embassy-time", + "embedded-hal 0.2.7", + "embedded-hal 1.0.0", + "embedded-hal-async", + "embedded-storage", + "embedded-storage-async", + "nb 1.1.0", +] + +[[package]] +name = "embassy-executor" +version = "0.7.0" +source = "git+https://github.com/embassy-rs/embassy?rev=2cae242#2cae242f51cd1553ca9deb1cfd73daed606c5476" +dependencies = [ + "cortex-m", + "critical-section", + "defmt 1.0.1", + "document-features", + "embassy-executor-macros", +] + +[[package]] +name = "embassy-executor-macros" +version = "0.6.2" +source = "git+https://github.com/embassy-rs/embassy?rev=2cae242#2cae242f51cd1553ca9deb1cfd73daed606c5476" +dependencies = [ + "darling", + "proc-macro2", + "quote", + "syn 2.0.100", +] + +[[package]] +name = "embassy-futures" +version = "0.1.1" +source = "git+https://github.com/embassy-rs/embassy?rev=2cae242#2cae242f51cd1553ca9deb1cfd73daed606c5476" + +[[package]] +name = "embassy-hal-internal" +version = "0.3.0" +source = "git+https://github.com/embassy-rs/embassy?rev=2cae242#2cae242f51cd1553ca9deb1cfd73daed606c5476" +dependencies = [ + "cortex-m", + "critical-section", + "defmt 1.0.1", + "num-traits", +] + +[[package]] +name = "embassy-net" +version = "0.7.0" +source = "git+https://github.com/embassy-rs/embassy?rev=2cae242#2cae242f51cd1553ca9deb1cfd73daed606c5476" +dependencies = [ + "defmt 1.0.1", + "document-features", + "embassy-net-driver", + "embassy-sync", + "embassy-time", + "embedded-io-async", + "embedded-nal-async", + "heapless 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)", + "managed", + "smoltcp", +] + +[[package]] +name = "embassy-net-driver" +version = "0.2.0" +source = "git+https://github.com/embassy-rs/embassy?rev=2cae242#2cae242f51cd1553ca9deb1cfd73daed606c5476" +dependencies = [ + "defmt 1.0.1", +] + +[[package]] +name = "embassy-net-driver-channel" +version = "0.3.1" +source = "git+https://github.com/embassy-rs/embassy?rev=2cae242#2cae242f51cd1553ca9deb1cfd73daed606c5476" +dependencies = [ + "embassy-futures", + "embassy-net-driver", + "embassy-sync", +] + +[[package]] +name = "embassy-net-wiznet" +version = "0.2.0" +source = "git+https://github.com/embassy-rs/embassy?rev=2cae242#2cae242f51cd1553ca9deb1cfd73daed606c5476" +dependencies = [ + "defmt 1.0.1", + "embassy-futures", + "embassy-net-driver-channel", + "embassy-time", + "embedded-hal 1.0.0", + "embedded-hal-async", +] + +[[package]] +name = "embassy-stm32" +version = "0.2.0" +source = "git+https://github.com/embassy-rs/embassy?rev=2cae242#2cae242f51cd1553ca9deb1cfd73daed606c5476" +dependencies = [ + "aligned", + "bit_field", + "bitflags 2.9.0", + "block-device-driver", + "cfg-if", + "cortex-m", + "cortex-m-rt", + "critical-section", + "defmt 1.0.1", + "document-features", + "embassy-embedded-hal", + "embassy-futures", + "embassy-hal-internal", + "embassy-net-driver", + "embassy-sync", + "embassy-time", + "embassy-time-driver", + "embassy-time-queue-utils", + "embassy-usb-driver", + "embassy-usb-synopsys-otg", + "embedded-can", + "embedded-hal 0.2.7", + "embedded-hal 1.0.0", + "embedded-hal-async", + "embedded-hal-nb", + "embedded-io", + "embedded-io-async", + "embedded-storage", + "embedded-storage-async", + "futures-util", + "nb 1.1.0", + "proc-macro2", + "quote", + "rand_core 0.6.4", + "rand_core 0.9.3", + "sdio-host", + "static_assertions", + "stm32-fmc", + "stm32-metapac", + "vcell", + "volatile-register", +] + +[[package]] +name = "embassy-sync" +version = "0.7.0" +source = "git+https://github.com/embassy-rs/embassy?rev=2cae242#2cae242f51cd1553ca9deb1cfd73daed606c5476" +dependencies = [ + "cfg-if", + "critical-section", + "defmt 1.0.1", + "embedded-io-async", + "futures-core", + "futures-sink", + "heapless 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "embassy-time" +version = "0.4.0" +source = "git+https://github.com/embassy-rs/embassy?rev=2cae242#2cae242f51cd1553ca9deb1cfd73daed606c5476" +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.0" +source = "git+https://github.com/embassy-rs/embassy?rev=2cae242#2cae242f51cd1553ca9deb1cfd73daed606c5476" +dependencies = [ + "document-features", +] + +[[package]] +name = "embassy-time-queue-utils" +version = "0.1.0" +source = "git+https://github.com/embassy-rs/embassy?rev=2cae242#2cae242f51cd1553ca9deb1cfd73daed606c5476" +dependencies = [ + "embassy-executor", + "heapless 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "embassy-usb" +version = "0.5.0" +source = "git+https://github.com/embassy-rs/embassy?rev=2cae242#2cae242f51cd1553ca9deb1cfd73daed606c5476" +dependencies = [ + "defmt 1.0.1", + "embassy-futures", + "embassy-net-driver-channel", + "embassy-sync", + "embassy-usb-driver", + "embedded-io-async", + "heapless 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)", + "ssmarshal", + "usbd-hid", +] + +[[package]] +name = "embassy-usb-driver" +version = "0.2.0" +source = "git+https://github.com/embassy-rs/embassy?rev=2cae242#2cae242f51cd1553ca9deb1cfd73daed606c5476" +dependencies = [ + "defmt 1.0.1", + "embedded-io-async", +] + +[[package]] +name = "embassy-usb-synopsys-otg" +version = "0.2.0" +source = "git+https://github.com/embassy-rs/embassy?rev=2cae242#2cae242f51cd1553ca9deb1cfd73daed606c5476" +dependencies = [ + "critical-section", + "defmt 1.0.1", + "embassy-sync", + "embassy-usb-driver", +] + +[[package]] +name = "embedded-can" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e9d2e857f87ac832df68fa498d18ddc679175cf3d2e4aa893988e5601baf9438" +dependencies = [ + "nb 1.1.0", +] + +[[package]] +name = "embedded-hal" +version = "0.2.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "35949884794ad573cf46071e41c9b60efb0cb311e3ca01f7af807af1debc66ff" +dependencies = [ + "nb 0.1.3", + "void", +] + +[[package]] +name = "embedded-hal" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "361a90feb7004eca4019fb28352a9465666b24f840f5c3cddf0ff13920590b89" +dependencies = [ + "defmt 0.3.100", +] + +[[package]] +name = "embedded-hal-async" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0c4c685bbef7fe13c3c6dd4da26841ed3980ef33e841cddfa15ce8a8fb3f1884" +dependencies = [ + "defmt 0.3.100", + "embedded-hal 1.0.0", +] + +[[package]] +name = "embedded-hal-bus" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0d3980bf28e8577db59fe2bdb3df868a419469d2cecb363644eea2b6f7797669" +dependencies = [ + "critical-section", + "defmt 0.3.100", + "embedded-hal 1.0.0", + "embedded-hal-async", + "portable-atomic", +] + +[[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" +dependencies = [ + "defmt 0.3.100", +] + +[[package]] +name = "embedded-io-async" +version = "0.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3ff09972d4073aa8c299395be75161d582e7629cd663171d62af73c8d50dba3f" +dependencies = [ + "defmt 0.3.100", + "embedded-io", +] + +[[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.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "76959917cd2b86f40a98c28dd5624eddd1fa69d746241c8257eac428d83cb211" +dependencies = [ + "embedded-io-async", + "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 = "encode_unicode" +version = "0.3.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a357d28ed41a50f9c765dbfe56cbc04a64e53e5fc58ba79fbc34c10ef3df831f" + +[[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.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "65bc07b1a8bc7c85c5f2e110c476c7389b4554ba72af57d8445ea63a576b0876" +dependencies = [ + "futures-channel", + "futures-core", + "futures-io", + "futures-sink", + "futures-task", + "futures-util", +] + +[[package]] +name = "futures-channel" +version = "0.3.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2dff15bf788c671c1934e366d07e30c1814a8ef514e1af724a602e8a2fbe1b10" +dependencies = [ + "futures-core", + "futures-sink", +] + +[[package]] +name = "futures-core" +version = "0.3.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "05f29059c0c2090612e8d742178b0580d2dc940c837851ad723096f87af6663e" + +[[package]] +name = "futures-io" +version = "0.3.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9e5c1b78ca4aae1ac06c48a526a655760685149f0d465d21f37abfe57ce075c6" + +[[package]] +name = "futures-macro" +version = "0.3.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "162ee34ebcb7c64a8abebc059ce0fee27c2262618d7b60ed8faf72fef13c3650" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.100", +] + +[[package]] +name = "futures-sink" +version = "0.3.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e575fab7d1e0dcb8d0c7bcf9a63ee213816ab51902e6d244a95819acacf1d4f7" + +[[package]] +name = "futures-task" +version = "0.3.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f90f7dce0722e95104fcb095585910c0977252f286e354b5e3bd38902cd99988" + +[[package]] +name = "futures-util" +version = "0.3.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9fa08315bb612088cc391249efdc3bc77536f16c91f6cf495e6fbe85b20a4a81" +dependencies = [ + "futures-core", + "futures-macro", + "futures-sink", + "futures-task", + "pin-project-lite", + "pin-utils", +] + +[[package]] +name = "hash32" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b0c35f58762feb77d74ebe43bdbc3210f09be9fe6742234d573bacc26ed92b67" +dependencies = [ + "byteorder", +] + +[[package]] +name = "hash32" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "47d60b12902ba28e2730cd37e95b8c9223af2808df9e902d4df49588d1470606" +dependencies = [ + "byteorder", +] + +[[package]] +name = "hashbrown" +version = "0.13.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "43a3c133739dddd0d2990f9a4bdf8eb4b21ef50e4851ca85ab661199821d510e" +dependencies = [ + "ahash", +] + +[[package]] +name = "heapless" +version = "0.7.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cdc6457c0eb62c71aac4bc17216026d8410337c4126773b9c5daba343f17964f" +dependencies = [ + "atomic-polyfill", + "hash32 0.2.1", + "rustc_version 0.4.1", + "serde", + "spin", + "stable_deref_trait", +] + +[[package]] +name = "heapless" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0bfb9eb618601c89945a70e254898da93b13be0388091d42117462b265bb3fad" +dependencies = [ + "defmt 0.3.100", + "hash32 0.3.1", + "serde", + "stable_deref_trait", +] + +[[package]] +name = "heapless" +version = "0.8.0" +source = "git+https://github.com/rust-embedded/heapless?rev=0ebca23#0ebca2320970b8a1aa3e58ceba924f8c65385946" +dependencies = [ + "hash32 0.3.1", + "stable_deref_trait", +] + +[[package]] +name = "heck" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea" + +[[package]] +name = "ident_case" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b9e0384b61958566e926dc50660321d12159025e767c18e043daf26b70104c39" + +[[package]] +name = "large-bedroom-bed" +version = "0.2.0" +dependencies = [ + "cortex-m", + "cortex-m-rt", + "defmt 1.0.1", + "defmt-rtt", + "embassy-embedded-hal", + "embassy-executor", + "embassy-futures", + "embassy-net", + "embassy-net-wiznet", + "embassy-stm32", + "embassy-sync", + "embassy-time", + "embedded-hal 1.0.0", + "embedded-hal-async", + "embedded-hal-bus", + "embedded-io-async", + "futures", + "heapless 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)", + "panic-probe", + "protocol", + "rand", + "sensors", + "static_cell", +] + +[[package]] +name = "large-bedroom-desk" +version = "0.2.0" +dependencies = [ + "cortex-m", + "cortex-m-rt", + "defmt 1.0.1", + "defmt-rtt", + "embassy-embedded-hal", + "embassy-executor", + "embassy-futures", + "embassy-stm32", + "embassy-sync", + "embassy-time", + "embassy-usb", + "embedded-hal 1.0.0", + "embedded-hal-async", + "embedded-hal-bus", + "embedded-io-async", + "futures", + "heapless 0.8.0 (git+https://github.com/rust-embedded/heapless?rev=0ebca23)", + "panic-probe", + "protocol", + "sensors", + "usb-bridge-client", +] + +[[package]] +name = "litrs" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b4ce301924b7887e9d637144fdade93f9dfff9b60981d4ac161db09720d39aa5" + +[[package]] +name = "lock_api" +version = "0.4.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "07af8b9cdd281b7915f413fa73f29ebd5d55d0d3f0155584dade1ff18cea1b17" +dependencies = [ + "autocfg", + "scopeguard", +] + +[[package]] +name = "log" +version = "0.4.27" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "13dc2df351e3202783a1fe0d44375f7295ffb4049267b0f3018346dc122a1d94" + +[[package]] +name = "managed" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0ca88d725a0a943b096803bd34e73a4437208b6077654cc4ecb2947a5f91618d" + +[[package]] +name = "max44009" +version = "0.2.0" +source = "git+https://github.com/dvdsk/max44009-rs#7b7df2e3173476c250fca3eb242f0dd366857599" +dependencies = [ + "defmt 0.3.100", + "embedded-hal-async", +] + +[[package]] +name = "mhzx" +version = "0.3.0" +dependencies = [ + "defmt 0.3.100", + "embedded-io-async", + "heapless 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)", + "postcard", + "serde", +] + +[[package]] +name = "nau7802-async" +version = "0.2.0" +dependencies = [ + "byteorder", + "defmt 0.3.100", + "embedded-hal-async", + "postcard", + "serde", +] + +[[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 = "num-traits" +version = "0.2.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841" +dependencies = [ + "autocfg", +] + +[[package]] +name = "once_cell" +version = "1.21.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d75b0bedcc4fe52caa0e03d9f1151a323e4aa5e2d78ba3580400cd3c9e2bc4bc" + +[[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 = "pin-project-lite" +version = "0.2.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3b3cff922bd51709b605d9ead9aa71031d81447142d828eb4a6eba76fe619f9b" + +[[package]] +name = "pin-utils" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" + +[[package]] +name = "portable-atomic" +version = "1.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "350e9b48cbc6b0e028b0473b114454c6316e57336ee184ceab6e53f72c178b3e" + +[[package]] +name = "postcard" +version = "1.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "170a2601f67cc9dba8edd8c4870b15f71a6a2dc196daec8c83f72b59dff628a8" +dependencies = [ + "cobs", + "defmt 0.3.100", + "heapless 0.7.17", + "postcard-derive", + "serde", +] + +[[package]] +name = "postcard-derive" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0239fa9c1d225d4b7eb69925c25c5e082307a141e470573fbbe3a817ce6a7a37" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[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.100", +] + +[[package]] +name = "proc-macro2" +version = "1.0.94" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a31971752e70b8b2686d7e46ec17fb38dad4051d94024c88df49b667caea9c84" +dependencies = [ + "unicode-ident", +] + +[[package]] +name = "protocol" +version = "0.1.0" +dependencies = [ + "defmt 0.3.100", + "heapless 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)", + "postcard", + "serde", + "strum", +] + +[[package]] +name = "quote" +version = "1.0.40" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1885c039570dc00dcb4ff087a89e185fd56bae234ddc7f056a945bf36467248d" +dependencies = [ + "proc-macro2", +] + +[[package]] +name = "rand" +version = "0.8.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404" +dependencies = [ + "rand_core 0.6.4", +] + +[[package]] +name = "rand_core" +version = "0.6.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" + +[[package]] +name = "rand_core" +version = "0.9.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "99d9a13982dcf210057a8a78572b2217b667c3beacbf3a0d8b454f6f82837d38" + +[[package]] +name = "rustc_version" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "138e3e0acb6c9fb258b19b67cb8abd63c00679d2851805ea151465464fe9030a" +dependencies = [ + "semver 0.9.0", +] + +[[package]] +name = "rustc_version" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cfcb3a22ef46e85b45de6ee7e79d063319ebb6594faafcf1c225ea92ab6e9b92" +dependencies = [ + "semver 1.0.26", +] + +[[package]] +name = "rustversion" +version = "1.0.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eded382c5f5f786b989652c49544c4877d9f015cc22e145a5ea8ea66c2921cd2" + +[[package]] +name = "scopeguard" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" + +[[package]] +name = "sdio-host" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b328e2cb950eeccd55b7f55c3a963691455dcd044cfb5354f0c5e68d2c2d6ee2" + +[[package]] +name = "semver" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1d7eb9ef2c18661902cc47e535f9bc51b78acd254da71d375c2f6720d9a40403" +dependencies = [ + "semver-parser", +] + +[[package]] +name = "semver" +version = "1.0.26" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "56e6fa9c48d24d85fb3de5ad847117517440f6beceb7798af16b4a87d616b8d0" + +[[package]] +name = "semver-parser" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "388a1df253eca08550bef6c72392cfe7c30914bf41df5269b68cbd6ff8f570a3" + +[[package]] +name = "sensors" +version = "0.1.0" +dependencies = [ + "bosch-bme680", + "defmt 1.0.1", + "embassy-embedded-hal", + "embassy-futures", + "embassy-stm32", + "embassy-sync", + "embassy-time", + "embedded-hal 1.0.0", + "embedded-hal-async", + "max44009", + "mhzx", + "nau7802-async", + "protocol", + "sht31", + "sps30-async", +] + +[[package]] +name = "serde" +version = "1.0.219" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5f0e2c6ed6606019b4e29e69dbaba95b11854410e5347d525002456dbbb786b6" +dependencies = [ + "serde_derive", +] + +[[package]] +name = "serde_derive" +version = "1.0.219" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5b0276cf7f2c73365f7157c8123c21cd9a50fbbd844757af28ca1f5925fc2a00" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.100", +] + +[[package]] +name = "sht31" +version = "0.3.1" +source = "git+https://github.com/dvdsk/SHT31-rs#a7b6bd94fb137e16bf326eff5fb591624369a2cf" +dependencies = [ + "crc", + "defmt 0.3.100", + "embedded-hal-async", + "postcard", +] + +[[package]] +name = "small-bedroom-button-panel" +version = "0.2.0" +dependencies = [ + "cortex-m", + "cortex-m-rt", + "defmt 1.0.1", + "defmt-rtt", + "embassy-embedded-hal", + "embassy-executor", + "embassy-futures", + "embassy-stm32", + "embassy-sync", + "embassy-time", + "embassy-usb", + "embedded-hal 1.0.0", + "embedded-hal-async", + "embedded-hal-bus", + "embedded-io-async", + "futures", + "heapless 0.8.0 (git+https://github.com/rust-embedded/heapless?rev=0ebca23)", + "panic-probe", + "protocol", + "usb-bridge-client", +] + +[[package]] +name = "smoltcp" +version = "0.12.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dad095989c1533c1c266d9b1e8d70a1329dd3723c3edac6d03bbd67e7bf6f4bb" +dependencies = [ + "bitflags 1.3.2", + "byteorder", + "cfg-if", + "defmt 0.3.100", + "heapless 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)", + "managed", +] + +[[package]] +name = "spin" +version = "0.9.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6980e8d7511241f8acf4aebddbb1ff938df5eebe98691418c4468d0b72a96a67" +dependencies = [ + "lock_api", +] + +[[package]] +name = "sps30-async" +version = "0.3.0" +dependencies = [ + "defmt 0.3.100", + "embedded-hal-async", + "embedded-io-async", + "futures", + "heapless 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)", + "postcard", + "serde", +] + +[[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.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a8f112729512f8e442d81f95a8a7ddf2b7c6b8a1a6f509a95864142b30cab2d3" + +[[package]] +name = "static_assertions" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f" + +[[package]] +name = "static_cell" +version = "2.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d89b0684884a883431282db1e4343f34afc2ff6996fe1f4a1664519b66e14c1e" +dependencies = [ + "portable-atomic", +] + +[[package]] +name = "stm32-fmc" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c7f0639399e2307c2446c54d91d4f1596343a1e1d5cab605b9cce11d0ab3858c" +dependencies = [ + "embedded-hal 0.2.7", +] + +[[package]] +name = "stm32-metapac" +version = "16.0.0" +source = "git+https://github.com/embassy-rs/stm32-data-generated?tag=stm32-data-dded8a33a460ae0eb182aee3ccb048beb659982b#6ca0dbc4fb27b3482642d2db484633be3298b528" +dependencies = [ + "cortex-m", + "cortex-m-rt", +] + +[[package]] +name = "strsim" +version = "0.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f" + +[[package]] +name = "strum" +version = "0.27.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f64def088c51c9510a8579e3c5d67c65349dcf755e5479ad3d010aa6454e2c32" +dependencies = [ + "strum_macros", +] + +[[package]] +name = "strum_macros" +version = "0.27.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c77a8c5abcaf0f9ce05d62342b7d298c346515365c36b673df4ebe3ced01fde8" +dependencies = [ + "heck", + "proc-macro2", + "quote", + "rustversion", + "syn 2.0.100", +] + +[[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.100" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b09a44accad81e1ba1cd74a32461ba89dee89095ba17b32f5d03683b1b1fc2a0" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[package]] +name = "test-wiznet" +version = "0.2.0" +dependencies = [ + "cortex-m", + "cortex-m-rt", + "defmt 1.0.1", + "defmt-rtt", + "embassy-executor", + "embassy-net", + "embassy-net-wiznet", + "embassy-stm32", + "embassy-time", + "embedded-hal-bus", + "embedded-io-async", + "heapless 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)", + "panic-probe", + "rand", + "static_cell", +] + +[[package]] +name = "thiserror" +version = "2.0.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "567b8a2dae586314f7be2a752ec7474332959c6460e02bde30d702a66d488708" +dependencies = [ + "thiserror-impl", +] + +[[package]] +name = "thiserror-impl" +version = "2.0.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7f7cf42b4507d8ea322120659672cf1b9dbb93f8f2d4ecfd6e51350ff5b17a1d" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.100", +] + +[[package]] +name = "unicode-ident" +version = "1.0.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5a5f39404a5da50712a4c1eecf25e90dd62b613502b7e925fd4e4d19b5c96512" + +[[package]] +name = "usb-bridge-client" +version = "0.1.0" +dependencies = [ + "defmt 1.0.1", + "embassy-sync", + "embassy-usb", + "heapless 0.8.0 (git+https://github.com/rust-embedded/heapless?rev=0ebca23)", + "protocol", +] + +[[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 (registry+https://github.com/rust-lang/crates.io-index)", + "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", + "log", + "proc-macro2", + "quote", + "serde", + "syn 1.0.109", + "usbd-hid-descriptors", +] + +[[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 = "zerocopy" +version = "0.7.35" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1b9b4fd18abc82b8136838da5d50bae7bdea537c574d8dc1a34ed098d6c166f0" +dependencies = [ + "zerocopy-derive", +] + +[[package]] +name = "zerocopy-derive" +version = "0.7.35" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fa4f8080344d4671fb4e831a13ad1e68092748387dfc4f55e356242fae12ce3e" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.100", +] diff --git a/nodes/embassy/Cargo.toml b/nodes/embassy/Cargo.toml new file mode 100644 index 00000000..f2235ad7 --- /dev/null +++ b/nodes/embassy/Cargo.toml @@ -0,0 +1,77 @@ +[workspace] +resolver = "2" +members = ["large-bedroom-bed", "small-bedroom-bed", +"small-bedroom-button-panel", "large-bedroom-desk", "sensors", "usb-bridge-client", "test-wiznet"] + +[workspace.dependencies] +protocol = { path = "../../crates/protocol" } +sensors = { path = "sensors" } +usb-bridge-client = { path = "usb-bridge-client" } + +cortex-m = { version = "0.7.6", features = ["inline-asm", "critical-section-single-core"] } +cortex-m-rt = "0.7.0" + +embassy-stm32 = { version = "0.2.0", features = [ "defmt", "stm32f401cc", +"unstable-pac", "memory-x", "time-driver-tim9", "time", "exti" ] } +embassy-net = { version = "0.7.0", features = ["defmt", "proto-ipv4", "tcp", "dhcpv4","medium-ethernet"] } +embassy-net-wiznet = { version = "0.2.0", features = ["defmt"] } +embassy-sync = { version = "0.7", features = ["defmt"] } +embassy-executor = { version = "0.7", features = ["arch-cortex-m", +"executor-thread", "defmt", "executor-interrupt"] } +embassy-embedded-hal = { version = "0.3.0" } +embassy-time = { version = "0.4", features = ["defmt", +"defmt-timestamp-uptime-ms", "tick-hz-32_768"] } +embassy-futures = { version = "0.1.1"} +embassy-usb = { version = "0.5.0", features = ["defmt"] } + +embedded-hal = "1.0.0" +embedded-hal-async = "1.0" +embedded-hal-bus = { version = "0.2", features = ["async", "defmt-03"] } +embedded-io-async = { version = "0.6.1", features = ["defmt-03"] } +futures = { version = "0.3.31", default-features = false, features = ["async-await"] } + +heapless = { git = "https://github.com/rust-embedded/heapless", version = "0.8", rev = "0ebca23", default-features = false } + +defmt = "1.0" +defmt-rtt = "1.0" +panic-probe = { version = "1.0", features = ["print-defmt"] } + +[patch.crates-io] +embassy-stm32 = {git = "https://github.com/embassy-rs/embassy", rev = "2cae242" } +embassy-net = {git = "https://github.com/embassy-rs/embassy", rev = "2cae242" } +embassy-net-wiznet = {git = "https://github.com/embassy-rs/embassy", rev = "2cae242" } +embassy-sync = {git = "https://github.com/embassy-rs/embassy", rev = "2cae242" } +embassy-executor = {git = "https://github.com/embassy-rs/embassy", rev = "2cae242" } +embassy-embedded-hal = {git = "https://github.com/embassy-rs/embassy", rev = "2cae242" } +embassy-futures = {git = "https://github.com/embassy-rs/embassy", rev = "2cae242" } +embassy-time = {git = "https://github.com/embassy-rs/embassy", rev = "2cae242" } +embassy-time-driver = {git = "https://github.com/embassy-rs/embassy", rev = "2cae242" } +embassy-usb = {git = "https://github.com/embassy-rs/embassy", rev = "2cae242" } + +# embassy-stm32 = {path = "/home/david/Documents/embassy/embassy-stm32" } +# embassy-net = {path = "/home/david/Documents/embassy/embassy-net" } +# embassy-net-wiznet = {path = "/home/david/Documents/embassy/embassy-net-wiznet" } +# embassy-sync = {path = "/home/david/Documents/embassy/embassy-sync" } +# embassy-executor = {path = "/home/david/Documents/embassy/embassy-executor" } +# embassy-embedded-hal = {path = "/home/david/Documents/embassy/embassy-embedded-hal" } +# embassy-futures = {path = "/home/david/Documents/embassy/embassy-futures" } +# embassy-time = {path = "/home/david/Documents/embassy/embassy-time" } +# embassy-time-driver = {path = "/home/david/Documents/embassy/embassy-time-driver" } +# embassy-usb = {path = "/home/david/Documents/embassy/embassy-usb" } + +[workspace.package] +rust-version = "1.78" +edition = "2021" +license = "GPLv3" +authors = ["David Kleingeld & Eva van Houten"] + +[profile.dev] +opt-level = "s" + +[profile.release] +lto = "fat" +opt-level = "s" +incremental = false +codegen-units = 1 +# note: debug = true is okay - debuginfo isn't flashed to the device! +debug = true diff --git a/nodes/embassy/large-bedroom-bed/.cargo/config.toml b/nodes/embassy/large-bedroom-bed/.cargo/config.toml new file mode 100644 index 00000000..1c28d62e --- /dev/null +++ b/nodes/embassy/large-bedroom-bed/.cargo/config.toml @@ -0,0 +1,17 @@ +[target.'cfg(all(target_arch = "arm", target_os = "none"))'] +# replace STM32F103C8 with your chip as listed in `probe-rs chip list` +# runner = "probe-rs run --chip STM32F103C8" +runner = "probe-rs run --chip STM32F401CCUx --host ws://192.168.1.43:3000 --token secret_token_redacted --probe c251:f001:202108120001" +linker = "flip-link" + +[build] +# target = "thumbv7m-none-eabi" for f103 +target = "thumbv7em-none-eabihf" + +[env] +DEFMT_LOG = "debug,sps30_async=warn,bosch_bme680=info" +EMBASSY_EXECUTOR_TASK_ARENA_SIZE="10900" + +# [unstable] +# build-std = ["core"] +# build-std-features = ["panic_immediate_abort"] diff --git a/nodes/embassy/large-bedroom-bed/Cargo.lock b/nodes/embassy/large-bedroom-bed/Cargo.lock new file mode 100644 index 00000000..50cd7987 --- /dev/null +++ b/nodes/embassy/large-bedroom-bed/Cargo.lock @@ -0,0 +1,1274 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 3 + +[[package]] +name = "ahash" +version = "0.8.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e89da841a80418a9b391ebaea17f5c112ffaaa96f621d2c285b5174da76b9011" +dependencies = [ + "cfg-if", + "once_cell", + "version_check", + "zerocopy", +] + +[[package]] +name = "aligned" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "377e4c0ba83e4431b10df45c1d4666f178ea9c552cac93e60c3a88bf32785923" +dependencies = [ + "as-slice", +] + +[[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 = "atomic-polyfill" +version = "1.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8cf2bce30dfe09ef0bfaef228b9d414faaf7e563035494d7fe092dba54b300f4" +dependencies = [ + "critical-section", +] + +[[package]] +name = "autocfg" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0c4b4d0bd25bd0b74681c0ad21497610ce1b7c91b1022cd21c80c6fbdd9476b0" + +[[package]] +name = "bare-metal" +version = "0.2.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5deb64efa5bd81e31fcd1938615a6d98c82eafcbcd787162b6f63b91d6bac5b3" +dependencies = [ + "rustc_version 0.2.3", +] + +[[package]] +name = "bed-sensors" +version = "0.2.0" +dependencies = [ + "bosch-bme680", + "cortex-m", + "cortex-m-rt", + "defmt", + "defmt-rtt", + "embassy-embedded-hal", + "embassy-executor", + "embassy-futures", + "embassy-stm32", + "embassy-sync", + "embassy-time", + "embassy-usb", + "embedded-hal 1.0.0", + "embedded-hal-async", + "embedded-hal-bus", + "embedded-io-async", + "futures", + "heapless 0.8.0", + "max44009", + "mhzx", + "nau7802-async", + "nb 1.1.0", + "panic-probe", + "protocol", + "rand", + "sht31", + "sps30-async", + "static_cell", +] + +[[package]] +name = "bit_field" +version = "0.10.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dc827186963e592360843fb5ba4b973e145841266c1357f7180c43526f2e5b61" + +[[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.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b048fb63fd8b5923fc5aa7b340d8e156aec7ec02f0c78fa8a6ddc2613f6f71de" + +[[package]] +name = "block-device-driver" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "44c051592f59fe68053524b4c4935249b806f72c1f544cfb7abe4f57c3be258e" +dependencies = [ + "aligned", +] + +[[package]] +name = "bosch-bme680" +version = "1.0.2" +dependencies = [ + "bitfield 0.14.0", + "defmt", + "embedded-hal 1.0.0", + "embedded-hal-async", +] + +[[package]] +name = "byteorder" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" + +[[package]] +name = "cfg-if" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" + +[[package]] +name = "cobs" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "67ba02a97a2bd10f4b59b25c7973101c79642302776489e030cd13cdab09ed15" + +[[package]] +name = "cortex-m" +version = "0.7.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8ec610d8f49840a5b376c69663b6369e71f4b34484b9b2eb29fb918d92516cb9" +dependencies = [ + "bare-metal", + "bitfield 0.13.2", + "critical-section", + "embedded-hal 0.2.7", + "volatile-register", +] + +[[package]] +name = "cortex-m-rt" +version = "0.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ee84e813d593101b1723e13ec38b6ab6abbdbaaa4546553f5395ed274079ddb1" +dependencies = [ + "cortex-m-rt-macros", +] + +[[package]] +name = "cortex-m-rt-macros" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f0f6f3e36f203cfedbc78b357fb28730aa2c6dc1ab060ee5c2405e843988d3c7" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "crc" +version = "3.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "69e6e4d7b33a94f0991c26729976b10ebde1d34c3ee82408fb536164fa10d636" +dependencies = [ + "crc-catalog", +] + +[[package]] +name = "crc-catalog" +version = "2.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "19d374276b40fb8bbdee95aef7c7fa6b5316ec764510eb64b8dd0e2ed0d7e7f5" + +[[package]] +name = "critical-section" +version = "1.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f64009896348fc5af4222e9cf7d7d82a95a256c634ebcf61c53e4ea461422242" + +[[package]] +name = "darling" +version = "0.20.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6f63b86c8a8826a49b8c21f08a2d07338eec8d900540f8630dc76284be802989" +dependencies = [ + "darling_core", + "darling_macro", +] + +[[package]] +name = "darling_core" +version = "0.20.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "95133861a8032aaea082871032f5815eb9e98cef03fa916ab4500513994df9e5" +dependencies = [ + "fnv", + "ident_case", + "proc-macro2", + "quote", + "strsim", + "syn 2.0.77", +] + +[[package]] +name = "darling_macro" +version = "0.20.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d336a2a514f6ccccaa3e09b02d41d35330c07ddf03a62165fcec10bb561c7806" +dependencies = [ + "darling_core", + "quote", + "syn 2.0.77", +] + +[[package]] +name = "defmt" +version = "0.3.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a99dd22262668b887121d4672af5a64b238f026099f1a2a1b322066c9ecfe9e0" +dependencies = [ + "bitflags 1.3.2", + "defmt-macros", +] + +[[package]] +name = "defmt-macros" +version = "0.3.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e3a9f309eff1f79b3ebdf252954d90ae440599c26c2c553fe87a2d17195f2dcb" +dependencies = [ + "defmt-parser", + "proc-macro-error", + "proc-macro2", + "quote", + "syn 2.0.77", +] + +[[package]] +name = "defmt-parser" +version = "0.3.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ff4a5fefe330e8d7f31b16a318f9ce81000d8e35e69b93eae154d16d2278f70f" +dependencies = [ + "thiserror", +] + +[[package]] +name = "defmt-rtt" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bab697b3dbbc1750b7c8b821aa6f6e7f2480b47a99bc057a2ed7b170ebef0c51" +dependencies = [ + "critical-section", + "defmt", +] + +[[package]] +name = "document-features" +version = "0.2.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cb6969eaabd2421f8a2775cfd2471a2b634372b4a25d41e3bd647b79912850a0" +dependencies = [ + "litrs", +] + +[[package]] +name = "embassy-embedded-hal" +version = "0.2.0" +source = "git+https://github.com/embassy-rs/embassy?rev=d7780fc#d7780fcf83a8a35d7b09e5df7b62dd8218436715" +dependencies = [ + "defmt", + "embassy-futures", + "embassy-sync", + "embassy-time", + "embedded-hal 0.2.7", + "embedded-hal 1.0.0", + "embedded-hal-async", + "embedded-storage", + "embedded-storage-async", + "nb 1.1.0", +] + +[[package]] +name = "embassy-executor" +version = "0.6.0" +source = "git+https://github.com/embassy-rs/embassy?rev=d7780fc#d7780fcf83a8a35d7b09e5df7b62dd8218436715" +dependencies = [ + "cortex-m", + "critical-section", + "defmt", + "document-features", + "embassy-executor-macros", + "embassy-time-driver", + "embassy-time-queue-driver", +] + +[[package]] +name = "embassy-executor-macros" +version = "0.5.0" +source = "git+https://github.com/embassy-rs/embassy?rev=d7780fc#d7780fcf83a8a35d7b09e5df7b62dd8218436715" +dependencies = [ + "darling", + "proc-macro2", + "quote", + "syn 2.0.77", +] + +[[package]] +name = "embassy-futures" +version = "0.1.1" +source = "git+https://github.com/embassy-rs/embassy?rev=d7780fc#d7780fcf83a8a35d7b09e5df7b62dd8218436715" + +[[package]] +name = "embassy-hal-internal" +version = "0.2.0" +source = "git+https://github.com/embassy-rs/embassy?rev=d7780fc#d7780fcf83a8a35d7b09e5df7b62dd8218436715" +dependencies = [ + "cortex-m", + "critical-section", + "defmt", + "num-traits", +] + +[[package]] +name = "embassy-net-driver" +version = "0.2.0" +source = "git+https://github.com/embassy-rs/embassy?rev=d7780fc#d7780fcf83a8a35d7b09e5df7b62dd8218436715" +dependencies = [ + "defmt", +] + +[[package]] +name = "embassy-net-driver-channel" +version = "0.3.0" +source = "git+https://github.com/embassy-rs/embassy?rev=d7780fc#d7780fcf83a8a35d7b09e5df7b62dd8218436715" +dependencies = [ + "embassy-futures", + "embassy-net-driver", + "embassy-sync", +] + +[[package]] +name = "embassy-stm32" +version = "0.1.0" +source = "git+https://github.com/embassy-rs/embassy?rev=d7780fc#d7780fcf83a8a35d7b09e5df7b62dd8218436715" +dependencies = [ + "aligned", + "bit_field", + "bitflags 2.6.0", + "block-device-driver", + "cfg-if", + "cortex-m", + "cortex-m-rt", + "critical-section", + "defmt", + "document-features", + "embassy-embedded-hal", + "embassy-futures", + "embassy-hal-internal", + "embassy-net-driver", + "embassy-sync", + "embassy-time", + "embassy-time-driver", + "embassy-usb-driver", + "embassy-usb-synopsys-otg", + "embedded-can", + "embedded-hal 0.2.7", + "embedded-hal 1.0.0", + "embedded-hal-async", + "embedded-hal-nb", + "embedded-io", + "embedded-io-async", + "embedded-storage", + "embedded-storage-async", + "futures-util", + "nb 1.1.0", + "proc-macro2", + "quote", + "rand_core", + "sdio-host", + "static_assertions", + "stm32-fmc", + "stm32-metapac", + "vcell", + "volatile-register", +] + +[[package]] +name = "embassy-sync" +version = "0.6.0" +source = "git+https://github.com/embassy-rs/embassy?rev=d7780fc#d7780fcf83a8a35d7b09e5df7b62dd8218436715" +dependencies = [ + "cfg-if", + "critical-section", + "defmt", + "embedded-io-async", + "futures-util", + "heapless 0.8.0", +] + +[[package]] +name = "embassy-time" +version = "0.3.2" +source = "git+https://github.com/embassy-rs/embassy?rev=d7780fc#d7780fcf83a8a35d7b09e5df7b62dd8218436715" +dependencies = [ + "cfg-if", + "critical-section", + "defmt", + "document-features", + "embassy-time-driver", + "embassy-time-queue-driver", + "embedded-hal 0.2.7", + "embedded-hal 1.0.0", + "embedded-hal-async", + "futures-util", + "heapless 0.8.0", +] + +[[package]] +name = "embassy-time-driver" +version = "0.1.0" +source = "git+https://github.com/embassy-rs/embassy?rev=d7780fc#d7780fcf83a8a35d7b09e5df7b62dd8218436715" +dependencies = [ + "document-features", +] + +[[package]] +name = "embassy-time-queue-driver" +version = "0.1.0" +source = "git+https://github.com/embassy-rs/embassy?rev=d7780fc#d7780fcf83a8a35d7b09e5df7b62dd8218436715" + +[[package]] +name = "embassy-usb" +version = "0.3.0" +source = "git+https://github.com/embassy-rs/embassy?rev=d7780fc#d7780fcf83a8a35d7b09e5df7b62dd8218436715" +dependencies = [ + "defmt", + "embassy-futures", + "embassy-net-driver-channel", + "embassy-sync", + "embassy-usb-driver", + "heapless 0.8.0", + "ssmarshal", + "usbd-hid", +] + +[[package]] +name = "embassy-usb-driver" +version = "0.1.0" +source = "git+https://github.com/embassy-rs/embassy?rev=d7780fc#d7780fcf83a8a35d7b09e5df7b62dd8218436715" +dependencies = [ + "defmt", +] + +[[package]] +name = "embassy-usb-synopsys-otg" +version = "0.1.0" +source = "git+https://github.com/embassy-rs/embassy?rev=d7780fc#d7780fcf83a8a35d7b09e5df7b62dd8218436715" +dependencies = [ + "critical-section", + "embassy-sync", + "embassy-usb-driver", +] + +[[package]] +name = "embedded-can" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e9d2e857f87ac832df68fa498d18ddc679175cf3d2e4aa893988e5601baf9438" +dependencies = [ + "nb 1.1.0", +] + +[[package]] +name = "embedded-hal" +version = "0.2.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "35949884794ad573cf46071e41c9b60efb0cb311e3ca01f7af807af1debc66ff" +dependencies = [ + "nb 0.1.3", + "void", +] + +[[package]] +name = "embedded-hal" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "361a90feb7004eca4019fb28352a9465666b24f840f5c3cddf0ff13920590b89" +dependencies = [ + "defmt", +] + +[[package]] +name = "embedded-hal-async" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0c4c685bbef7fe13c3c6dd4da26841ed3980ef33e841cddfa15ce8a8fb3f1884" +dependencies = [ + "defmt", + "embedded-hal 1.0.0", +] + +[[package]] +name = "embedded-hal-bus" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0d3980bf28e8577db59fe2bdb3df868a419469d2cecb363644eea2b6f7797669" +dependencies = [ + "critical-section", + "defmt", + "embedded-hal 1.0.0", + "embedded-hal-async", + "portable-atomic", +] + +[[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" +dependencies = [ + "defmt", +] + +[[package]] +name = "embedded-io-async" +version = "0.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3ff09972d4073aa8c299395be75161d582e7629cd663171d62af73c8d50dba3f" +dependencies = [ + "defmt", + "embedded-io", +] + +[[package]] +name = "embedded-storage" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a21dea9854beb860f3062d10228ce9b976da520a73474aed3171ec276bc0c032" + +[[package]] +name = "embedded-storage-async" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1763775e2323b7d5f0aa6090657f5e21cfa02ede71f5dc40eead06d64dcd15cc" +dependencies = [ + "embedded-storage", +] + +[[package]] +name = "encode_unicode" +version = "0.3.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a357d28ed41a50f9c765dbfe56cbc04a64e53e5fc58ba79fbc34c10ef3df831f" + +[[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.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "645c6916888f6cb6350d2550b80fb63e734897a8498abe35cfb732b6487804b0" +dependencies = [ + "futures-channel", + "futures-core", + "futures-io", + "futures-sink", + "futures-task", + "futures-util", +] + +[[package]] +name = "futures-channel" +version = "0.3.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eac8f7d7865dcb88bd4373ab671c8cf4508703796caa2b1985a9ca867b3fcb78" +dependencies = [ + "futures-core", + "futures-sink", +] + +[[package]] +name = "futures-core" +version = "0.3.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dfc6580bb841c5a68e9ef15c77ccc837b40a7504914d52e47b8b0e9bbda25a1d" + +[[package]] +name = "futures-io" +version = "0.3.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a44623e20b9681a318efdd71c299b6b222ed6f231972bfe2f224ebad6311f0c1" + +[[package]] +name = "futures-macro" +version = "0.3.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "87750cf4b7a4c0625b1529e4c543c2182106e4dedc60a2a6455e00d212c489ac" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.77", +] + +[[package]] +name = "futures-sink" +version = "0.3.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9fb8e00e87438d937621c1c6269e53f536c14d3fbd6a042bb24879e57d474fb5" + +[[package]] +name = "futures-task" +version = "0.3.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "38d84fa142264698cdce1a9f9172cf383a0c82de1bddcf3092901442c4097004" + +[[package]] +name = "futures-util" +version = "0.3.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3d6401deb83407ab3da39eba7e33987a73c3df0c82b4bb5813ee871c19c41d48" +dependencies = [ + "futures-core", + "futures-macro", + "futures-sink", + "futures-task", + "pin-project-lite", + "pin-utils", +] + +[[package]] +name = "hash32" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b0c35f58762feb77d74ebe43bdbc3210f09be9fe6742234d573bacc26ed92b67" +dependencies = [ + "byteorder", +] + +[[package]] +name = "hash32" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "47d60b12902ba28e2730cd37e95b8c9223af2808df9e902d4df49588d1470606" +dependencies = [ + "byteorder", +] + +[[package]] +name = "hashbrown" +version = "0.13.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "43a3c133739dddd0d2990f9a4bdf8eb4b21ef50e4851ca85ab661199821d510e" +dependencies = [ + "ahash", +] + +[[package]] +name = "heapless" +version = "0.7.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cdc6457c0eb62c71aac4bc17216026d8410337c4126773b9c5daba343f17964f" +dependencies = [ + "atomic-polyfill", + "hash32 0.2.1", + "rustc_version 0.4.1", + "serde", + "spin", + "stable_deref_trait", +] + +[[package]] +name = "heapless" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0bfb9eb618601c89945a70e254898da93b13be0388091d42117462b265bb3fad" +dependencies = [ + "defmt", + "hash32 0.3.1", + "serde", + "stable_deref_trait", +] + +[[package]] +name = "heck" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea" + +[[package]] +name = "ident_case" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b9e0384b61958566e926dc50660321d12159025e767c18e043daf26b70104c39" + +[[package]] +name = "litrs" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b4ce301924b7887e9d637144fdade93f9dfff9b60981d4ac161db09720d39aa5" + +[[package]] +name = "lock_api" +version = "0.4.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "07af8b9cdd281b7915f413fa73f29ebd5d55d0d3f0155584dade1ff18cea1b17" +dependencies = [ + "autocfg", + "scopeguard", +] + +[[package]] +name = "log" +version = "0.4.22" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a7a70ba024b9dc04c27ea2f0c0548feb474ec5c54bba33a7f72f873a39d07b24" + +[[package]] +name = "max44009" +version = "0.2.0" +source = "git+https://github.com/dvdsk/max44009-rs#7b7df2e3173476c250fca3eb242f0dd366857599" +dependencies = [ + "defmt", + "embedded-hal-async", +] + +[[package]] +name = "mhzx" +version = "0.3.0" +dependencies = [ + "defmt", + "embedded-io-async", + "heapless 0.8.0", + "postcard", + "serde", +] + +[[package]] +name = "nau7802-async" +version = "0.2.0" +dependencies = [ + "byteorder", + "defmt", + "embedded-hal-async", + "postcard", + "serde", +] + +[[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 = "num-traits" +version = "0.2.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841" +dependencies = [ + "autocfg", +] + +[[package]] +name = "once_cell" +version = "1.19.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3fdb12b2476b595f9358c5161aa467c2438859caa136dec86c26fdd2efe17b92" + +[[package]] +name = "panic-probe" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4047d9235d1423d66cc97da7d07eddb54d4f154d6c13805c6d0793956f4f25b0" +dependencies = [ + "cortex-m", + "defmt", +] + +[[package]] +name = "pin-project-lite" +version = "0.2.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bda66fc9667c18cb2758a2ac84d1167245054bcf85d5d1aaa6923f45801bdd02" + +[[package]] +name = "pin-utils" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" + +[[package]] +name = "portable-atomic" +version = "1.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d30538d42559de6b034bc76fd6dd4c38961b1ee5c6c56e3808c50128fdbc22ce" + +[[package]] +name = "postcard" +version = "1.0.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5f7f0a8d620d71c457dd1d47df76bb18960378da56af4527aaa10f515eee732e" +dependencies = [ + "cobs", + "defmt", + "heapless 0.7.17", + "postcard-derive", + "serde", +] + +[[package]] +name = "postcard-derive" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0239fa9c1d225d4b7eb69925c25c5e082307a141e470573fbbe3a817ce6a7a37" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "proc-macro-error" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "da25490ff9892aab3fcf7c36f08cfb902dd3e71ca0f9f9517bea02a73a5ce38c" +dependencies = [ + "proc-macro-error-attr", + "proc-macro2", + "quote", + "syn 1.0.109", + "version_check", +] + +[[package]] +name = "proc-macro-error-attr" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a1be40180e52ecc98ad80b184934baf3d0d29f979574e439af5a55274b35f869" +dependencies = [ + "proc-macro2", + "quote", + "version_check", +] + +[[package]] +name = "proc-macro2" +version = "1.0.86" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5e719e8df665df0d1c8fbfd238015744736151d4445ec0836b8e628aae103b77" +dependencies = [ + "unicode-ident", +] + +[[package]] +name = "protocol" +version = "0.1.0" +dependencies = [ + "defmt", + "heapless 0.8.0", + "postcard", + "serde", + "strum", +] + +[[package]] +name = "quote" +version = "1.0.37" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b5b9d34b8991d19d98081b46eacdd8eb58c6f2b201139f7c5f643cc155a633af" +dependencies = [ + "proc-macro2", +] + +[[package]] +name = "rand" +version = "0.8.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404" +dependencies = [ + "rand_core", +] + +[[package]] +name = "rand_core" +version = "0.6.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" + +[[package]] +name = "rustc_version" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "138e3e0acb6c9fb258b19b67cb8abd63c00679d2851805ea151465464fe9030a" +dependencies = [ + "semver 0.9.0", +] + +[[package]] +name = "rustc_version" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cfcb3a22ef46e85b45de6ee7e79d063319ebb6594faafcf1c225ea92ab6e9b92" +dependencies = [ + "semver 1.0.23", +] + +[[package]] +name = "rustversion" +version = "1.0.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "955d28af4278de8121b7ebeb796b6a45735dc01436d898801014aced2773a3d6" + +[[package]] +name = "scopeguard" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" + +[[package]] +name = "sdio-host" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f93c025f9cfe4c388c328ece47d11a54a823da3b5ad0370b22d95ad47137f85a" + +[[package]] +name = "semver" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1d7eb9ef2c18661902cc47e535f9bc51b78acd254da71d375c2f6720d9a40403" +dependencies = [ + "semver-parser", +] + +[[package]] +name = "semver" +version = "1.0.23" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "61697e0a1c7e512e84a621326239844a24d8207b4669b41bc18b32ea5cbf988b" + +[[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.210" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c8e3592472072e6e22e0a54d5904d9febf8508f65fb8552499a1abc7d1078c3a" +dependencies = [ + "serde_derive", +] + +[[package]] +name = "serde_derive" +version = "1.0.210" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "243902eda00fad750862fc144cea25caca5e20d615af0a81bee94ca738f1df1f" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.77", +] + +[[package]] +name = "sht31" +version = "0.3.1" +source = "git+https://github.com/dvdsk/SHT31-rs#a7b6bd94fb137e16bf326eff5fb591624369a2cf" +dependencies = [ + "crc", + "defmt", + "embedded-hal-async", + "postcard", +] + +[[package]] +name = "spin" +version = "0.9.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6980e8d7511241f8acf4aebddbb1ff938df5eebe98691418c4468d0b72a96a67" +dependencies = [ + "lock_api", +] + +[[package]] +name = "sps30-async" +version = "0.3.0" +dependencies = [ + "defmt", + "embedded-hal-async", + "embedded-io-async", + "futures", + "heapless 0.8.0", + "postcard", + "serde", +] + +[[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.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a8f112729512f8e442d81f95a8a7ddf2b7c6b8a1a6f509a95864142b30cab2d3" + +[[package]] +name = "static_assertions" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f" + +[[package]] +name = "static_cell" +version = "2.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d89b0684884a883431282db1e4343f34afc2ff6996fe1f4a1664519b66e14c1e" +dependencies = [ + "portable-atomic", +] + +[[package]] +name = "stm32-fmc" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c7f0639399e2307c2446c54d91d4f1596343a1e1d5cab605b9cce11d0ab3858c" +dependencies = [ + "embedded-hal 0.2.7", +] + +[[package]] +name = "stm32-metapac" +version = "15.0.0" +source = "git+https://github.com/embassy-rs/stm32-data-generated?tag=stm32-data-ad00827345b4b758b2453082809d6e3b634b5364#e442835159a7a311410cd4a2879da52c6f57af52" +dependencies = [ + "cortex-m", + "cortex-m-rt", +] + +[[package]] +name = "strsim" +version = "0.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f" + +[[package]] +name = "strum" +version = "0.26.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8fec0f0aef304996cf250b31b5a10dee7980c85da9d759361292b8bca5a18f06" +dependencies = [ + "strum_macros", +] + +[[package]] +name = "strum_macros" +version = "0.26.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4c6bee85a5a24955dc440386795aa378cd9cf82acd5f764469152d2270e581be" +dependencies = [ + "heck", + "proc-macro2", + "quote", + "rustversion", + "syn 2.0.77", +] + +[[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.77" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9f35bcdf61fd8e7be6caf75f429fdca8beb3ed76584befb503b1569faee373ed" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[package]] +name = "thiserror" +version = "1.0.64" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d50af8abc119fb8bb6dbabcfa89656f46f84aa0ac7688088608076ad2b459a84" +dependencies = [ + "thiserror-impl", +] + +[[package]] +name = "thiserror-impl" +version = "1.0.64" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "08904e7672f5eb876eaaf87e0ce17857500934f4981c4a0ab2b4aa98baac7fc3" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.77", +] + +[[package]] +name = "unicode-ident" +version = "1.0.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e91b56cd4cadaeb79bbf1a5645f6b4f8dc5bde8834ad5894a8db35fda9efa1fe" + +[[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", + "log", + "proc-macro2", + "quote", + "serde", + "syn 1.0.109", + "usbd-hid-descriptors", +] + +[[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 = "zerocopy" +version = "0.7.35" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1b9b4fd18abc82b8136838da5d50bae7bdea537c574d8dc1a34ed098d6c166f0" +dependencies = [ + "zerocopy-derive", +] + +[[package]] +name = "zerocopy-derive" +version = "0.7.35" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fa4f8080344d4671fb4e831a13ad1e68092748387dfc4f55e356242fae12ce3e" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.77", +] diff --git a/nodes/embassy/large-bedroom-bed/Cargo.toml b/nodes/embassy/large-bedroom-bed/Cargo.toml new file mode 100644 index 00000000..da44dc4c --- /dev/null +++ b/nodes/embassy/large-bedroom-bed/Cargo.toml @@ -0,0 +1,40 @@ +[package] +name = "large-bedroom-bed" +version = "0.2.0" +rust-version.workspace = true +edition.workspace = true +license = "GPLv3" +authors = ["David Kleingeld & Eva van Houten"] + +[dependencies] +cortex-m.workspace = true +cortex-m-rt.workspace = true + +embassy-stm32.workspace = true +embassy-sync.workspace = true +embassy-executor.workspace = true +embassy-net.workspace = true +embassy-net-wiznet.workspace = true +embassy-embedded-hal.workspace = true +embassy-time.workspace = true +embassy-futures.workspace = true + +defmt.workspace = true +defmt-rtt.workspace = true + +embedded-hal.workspace = true +embedded-hal-async.workspace = true +embedded-hal-bus.workspace = true +embedded-io-async.workspace = true + +panic-probe.workspace = true +futures.workspace = true +static_cell = "2.0.0" +rand = { version = "0.8.5", default-features = false, features = ["small_rng"] } +heapless = { version = "0.8", default-features = false } + +# sensors +sensors.workspace = true + +# encoding +protocol = { workspace = true } diff --git a/nodes/embassy/large-bedroom-bed/build.rs b/nodes/embassy/large-bedroom-bed/build.rs new file mode 100644 index 00000000..8cd32d7e --- /dev/null +++ b/nodes/embassy/large-bedroom-bed/build.rs @@ -0,0 +1,5 @@ +fn main() { + println!("cargo:rustc-link-arg-bins=--nmagic"); + println!("cargo:rustc-link-arg-bins=-Tlink.x"); + println!("cargo:rustc-link-arg-bins=-Tdefmt.x"); +} diff --git a/nodes/embassy/large-bedroom-bed/rust-toolchain.toml b/nodes/embassy/large-bedroom-bed/rust-toolchain.toml new file mode 100644 index 00000000..c17f644e --- /dev/null +++ b/nodes/embassy/large-bedroom-bed/rust-toolchain.toml @@ -0,0 +1,6 @@ +[toolchain] +channel = "stable" +components = [ "rust-src", "rustfmt", "llvm-tools" ] +targets = [ + "thumbv7em-none-eabihf", +] diff --git a/nodes/embassy/large-bedroom-bed/src/channel.rs b/nodes/embassy/large-bedroom-bed/src/channel.rs new file mode 100644 index 00000000..c30eb5d5 --- /dev/null +++ b/nodes/embassy/large-bedroom-bed/src/channel.rs @@ -0,0 +1,138 @@ +use embassy_futures::select::{self, Either}; +use embassy_sync::blocking_mutex::raw::ThreadModeRawMutex; +use embassy_sync::channel::Channel; +use embassy_sync::mutex::Mutex; +use embassy_sync::priority_channel::{self, PriorityChannel}; +use embassy_time::{Duration, Instant}; +use heapless::HistoryBuffer; +use protocol::large_bedroom::bed::Reading; + +pub struct Queues { + sensor_queue: PriorityChannel< + ThreadModeRawMutex, + PriorityValue, + priority_channel::Max, + 20, + >, + error_queue: Channel, + recent_errors: Mutex>, + recent_is_since: Instant, +} + +pub enum QueueItem { + Reading(PriorityValue), + Error(sensors::Error), +} + +impl Queues { + pub const fn new() -> Self { + Self { + sensor_queue: PriorityChannel::new(), + error_queue: Channel::new(), + recent_errors: Mutex::new(HistoryBuffer::new()), + recent_is_since: Instant::MIN, // time since CPU start + } + } + + pub async fn clear(&self) { + while self.sensor_queue.try_receive().is_ok() {} + self.recent_errors.lock().await.clear(); + } + + pub async fn receive(&self) -> QueueItem { + if let Ok(val) = self.sensor_queue.try_receive() { + return QueueItem::Reading(val); + } + + let race = select::select( + self.sensor_queue.receive(), + self.error_queue.receive(), + ); + match race.await { + Either::First(reading) => QueueItem::Reading(reading), + Either::Second(error) => QueueItem::Error(error), + } + } + + pub async fn receive_reading(&self) -> PriorityValue { + self.sensor_queue.receive().await + } + + pub fn next_ready(&self) -> Option { + self.sensor_queue.try_receive().ok() + } + + pub fn queue_error(&self, error: sensors::Error) { + // unwrap safe: is not used in interrupts + let mut recent_errors = defmt::unwrap!(self.recent_errors.try_lock()); + if self.recent_is_since.elapsed() > Duration::from_secs(60 * 5) { + recent_errors.clear(); + } + if recent_errors.contains(&error) { + return; + } + + defmt::debug!("queueing error: {:?}", error); + let Ok(()) = self.error_queue.try_send(error.clone()) else { + return; + }; + recent_errors.write(error); + } + + pub fn send_p0(&self, value: Reading) { + use protocol::large_bedroom::Reading::Bed; + let entry = PriorityValue { + priority: 0, + value: protocol::Reading::LargeBedroom(Bed(value)), + }; + let _ignore_full = self.sensor_queue.try_send(entry); + } + pub fn send_p1(&self, value: Reading) { + use protocol::large_bedroom::Reading::Bed; + let entry = PriorityValue { + priority: 1, + value: protocol::Reading::LargeBedroom(Bed(value)), + }; + let _ignore_full = self.sensor_queue.try_send(entry); + } + + pub fn send_p2(&self, value: Reading) { + use protocol::large_bedroom::Reading::Bed; + let entry = PriorityValue { + priority: 2, + value: protocol::Reading::LargeBedroom(Bed(value)), + }; + let _ignore_full = self.sensor_queue.try_send(entry); + } +} + +/// Higher priority will be send earlier +pub struct PriorityValue { + priority: u8, + pub value: protocol::Reading, +} + +impl PriorityValue { + pub fn low_priority(&self) -> bool { + self.priority < 2 + } +} + +impl Eq for PriorityValue {} +impl PartialEq for PriorityValue { + fn eq(&self, other: &Self) -> bool { + self.priority.eq(&other.priority) + } +} + +impl PartialOrd for PriorityValue { + fn partial_cmp(&self, other: &Self) -> Option { + Some(self.priority.cmp(&other.priority)) + } +} + +impl Ord for PriorityValue { + fn cmp(&self, other: &Self) -> core::cmp::Ordering { + self.priority.cmp(&other.priority) + } +} diff --git a/nodes/embassy/large-bedroom-bed/src/main.rs b/nodes/embassy/large-bedroom-bed/src/main.rs new file mode 100644 index 00000000..8d2b7340 --- /dev/null +++ b/nodes/embassy/large-bedroom-bed/src/main.rs @@ -0,0 +1,257 @@ +#![no_std] +#![no_main] + +use embassy_executor::Spawner; +use embassy_net::{Ipv4Address, Ipv4Cidr, StackResources}; +use embassy_net_wiznet::{chip::W5500, Device, Runner, State}; +use embassy_stm32::exti::ExtiInput; +use embassy_stm32::gpio::{Level, Output, Pull, Speed}; +use embassy_stm32::i2c::{self, I2c}; +use embassy_stm32::mode::Async; +use embassy_stm32::peripherals::IWDG; +use embassy_stm32::spi::{Config as SpiConfig, Spi}; +use embassy_stm32::time::Hertz; +use embassy_stm32::usart::{self, DataBits, Parity, StopBits, Uart}; +use embassy_stm32::wdg::IndependentWatchdog; +use embassy_stm32::Config; +use embassy_sync::blocking_mutex::raw::{NoopRawMutex, ThreadModeRawMutex}; +use embassy_sync::channel::Channel; +use embassy_sync::mutex::Mutex; +use embassy_time::{Delay, Timer}; +use embedded_hal_bus::spi::ExclusiveDevice; +use heapless::Vec; +use rgb_led::{control_leds, LedHandle}; +use sensors::fast::ButtonInputs; +use sensors::slow; +use static_cell::StaticCell; + +use defmt::{trace, unwrap}; +use {defmt_rtt as _, panic_probe as _}; + +mod channel; +mod network; +mod rgb_led; +mod rng; +mod sensors; +use crate::channel::Queues; + +embassy_stm32::bind_interrupts!(struct Irqs { + I2C1_EV => embassy_stm32::i2c::EventInterruptHandler; + I2C1_ER => embassy_stm32::i2c::ErrorInterruptHandler; + I2C3_EV => embassy_stm32::i2c::EventInterruptHandler; + I2C3_ER => embassy_stm32::i2c::ErrorInterruptHandler; + USART1 => embassy_stm32::usart::InterruptHandler; + USART2 => embassy_stm32::usart::InterruptHandler; +}); + +type EthernetSPI = ExclusiveDevice, Output<'static>, Delay>; +#[embassy_executor::task] +async fn ethernet_task( + runner: Runner< + 'static, + W5500, + EthernetSPI, + ExtiInput<'static>, + Output<'static>, + >, +) -> ! { + runner.run().await +} + +#[embassy_executor::task] +async fn net_task( + mut runner: embassy_net::Runner<'static, Device<'static>>, +) -> ! { + runner.run().await +} + +static PUBLISH: Queues = Queues::new(); + +// 84 Mhz clock stm32f401 +fn config() -> Config { + use embassy_stm32::rcc::{ + AHBPrescaler, APBPrescaler, Hse, HseMode, Pll, PllMul, PllPDiv, + PllPreDiv, PllSource, Sysclk, + }; + + let mut config = Config::default(); + config.rcc.hse = Some(Hse { + freq: Hertz(25_000_000), + mode: HseMode::Oscillator, + }); + config.rcc.pll_src = PllSource::HSE; + config.rcc.pll = Some(Pll { + prediv: PllPreDiv::DIV25, + mul: PllMul::MUL336, + divp: Some(PllPDiv::DIV4), + divq: None, + divr: None, + }); + config.rcc.ahb_pre = AHBPrescaler::DIV1; + config.rcc.apb1_pre = APBPrescaler::DIV2; + config.rcc.apb2_pre = APBPrescaler::DIV1; + config.rcc.sys = Sysclk::PLL1_P; + config +} + +#[embassy_executor::main] +async fn main(spawner: Spawner) { + let p = embassy_stm32::init(config()); + let mut dog = IndependentWatchdog::new( + p.IWDG, 10_000_000, // microseconds + ); + dog.unleash(); + let seed = rng::generate_seed_blocking(p.ADC1).await; + defmt::info!("random seed: {}", seed); + + let mut usart_config = usart::Config::default(); + usart_config.baudrate = 9600; + usart_config.data_bits = DataBits::DataBits8; + usart_config.stop_bits = StopBits::STOP1; + let usart_mhz = unwrap!(Uart::new( + p.USART1, + p.PB7, + p.PB6, + Irqs, + p.DMA2_CH7, + p.DMA2_CH2, + usart_config, + )); + + let mut usart_config = usart::Config::default(); + usart_config.baudrate = 115_200; // sps30 only works at this baud + usart_config.data_bits = DataBits::DataBits8; + usart_config.stop_bits = StopBits::STOP1; + usart_config.parity = Parity::ParityNone; + let usart_sps30 = unwrap!(Uart::new( + p.USART2, + p.PA3, + p.PA2, + Irqs, + p.DMA1_CH6, + p.DMA1_CH5, + usart_config, + )); + + // We are out of DMA, so we need to use a blocking interface + // these sensors are only read once every 5 seconds + let i2c_1 = I2c::new( + p.I2C1, + p.PB8, + p.PB9, + Irqs, + p.DMA1_CH7, + p.DMA1_CH0, + Hertz(150_000), + i2c::Config::default(), + ); + let i2c_1: Mutex = Mutex::new(i2c_1); + + let i2c_2 = I2c::new_blocking( + p.I2C2, + p.PB10, + p.PB3, + // Extra slow, helps with longer cable run + // to the right weight sensor + Hertz(100_000), + i2c::Config::default(), + ); + // Even though its used by only one device we still use the (zero cost) + // mutex. It allows us to match/reuse the API for syn & async nau7802 + let i2c_2: Mutex = Mutex::new(i2c_2); + + let i2c_3 = I2c::new( + p.I2C3, + p.PA8, + p.PB4, + Irqs, + p.DMA1_CH4, + p.DMA1_CH1, + // Extra slow, helps with longer cable runs + Hertz(150_000), + i2c::Config::default(), + ); + let i2c_3: Mutex = Mutex::new(i2c_3); + + let buttons = ButtonInputs { + top: ExtiInput::new(p.PC14, p.EXTI14, Pull::Down), + middle_inner: ExtiInput::new(p.PA9, p.EXTI9, Pull::Down), + middle_center: ExtiInput::new(p.PC13, p.EXTI13, Pull::Down), + middle_outer: ExtiInput::new(p.PA10, p.EXTI10, Pull::Down), + lower_inner: ExtiInput::new(p.PA12, p.EXTI12, Pull::Down), + lower_center: ExtiInput::new(p.PA15, p.EXTI15, Pull::Down), + lower_outer: ExtiInput::new(p.PB5, p.EXTI5, Pull::Down), + }; + + let mut spi_cfg = SpiConfig::default(); + spi_cfg.frequency = Hertz(5_000_000); // Up to 50m works + let (miso, mosi, clk) = (p.PA6, p.PA7, p.PA5); + let spi = + Spi::new(p.SPI1, clk, mosi, miso, p.DMA2_CH3, p.DMA2_CH0, spi_cfg); + let cs = Output::new(p.PA4, Level::High, Speed::VeryHigh); + let spi = unwrap!(ExclusiveDevice::new(spi, cs, Delay)); + + let w5500_int = ExtiInput::new(p.PB0, p.EXTI0, Pull::Up); + let w5500_reset = Output::new(p.PB1, Level::High, Speed::Medium); + + let mac_addr = [0x02, 234, 3, 4, 82, 231]; + static STATE: StaticCell> = StaticCell::new(); + let state = STATE.init(State::<3, 2>::new()); + let (device, runner) = unwrap!( + embassy_net_wiznet::new(mac_addr, state, spi, w5500_int, w5500_reset) + .await + ); + unwrap!(spawner.spawn(ethernet_task(runner))); + + // Init network stack + static RESOURCES: StaticCell> = StaticCell::new(); + let config = + embassy_net::Config::ipv4_static(embassy_net::StaticConfigV4 { + address: Ipv4Cidr::new(Ipv4Address::new(192, 168, 1, 7), 24), + gateway: Some(Ipv4Address::new(192, 168, 1, 1)), + dns_servers: Vec::new(), + }); + let (stack, runner) = embassy_net::new( + device, + config, + RESOURCES.init(StackResources::new()), + seed, + ); + + // Launch network task + unwrap!(spawner.spawn(net_task(runner))); + + static LED_COMMS: Channel = + Channel::new(); + let control_leds = control_leds(p.TIM1, p.PB14, p.PB13, p.PB15, &LED_COMMS); + let led_handle = LedHandle::new(&LED_COMMS); + + static DRIVER_ORDERERS: slow::DriverOrderers = slow::DriverOrderers::new(); + let handle_network = + network::handle(stack, &PUBLISH, led_handle.clone(), &DRIVER_ORDERERS); + + let init_then_measure = sensors::init_then_measure( + &DRIVER_ORDERERS, + led_handle, + i2c_1, + i2c_2, + i2c_3, + usart_mhz, + usart_sps30, + buttons, + ); + + spawner.must_spawn(init_then_measure); + spawner.must_spawn(handle_network); + spawner.must_spawn(control_leds); + + keep_dog_happy(dog).await; +} + +async fn keep_dog_happy(mut dog: IndependentWatchdog<'_, IWDG>) { + loop { + Timer::after_secs(8).await; + trace!("petting dog"); + dog.pet(); + } +} diff --git a/nodes/embassy/large-bedroom-bed/src/network.rs b/nodes/embassy/large-bedroom-bed/src/network.rs new file mode 100644 index 00000000..ade0958a --- /dev/null +++ b/nodes/embassy/large-bedroom-bed/src/network.rs @@ -0,0 +1,266 @@ +use defmt::{debug, info, unwrap, warn}; +use embassy_executor::task; +use embassy_futures::select::{self, select}; +use embassy_net::tcp::{TcpReader, TcpSocket, TcpWriter}; +use embassy_net::{Ipv4Address, Stack}; +use embassy_time::{with_timeout, Duration, Instant, Timer}; +use embedded_io_async::Write; +use protocol::affector::DeserializeError; +use protocol::large_bedroom::{self, bed}; +use protocol::{affector, Affector, ErrorReport, SensorMessage}; + +use crate::channel::{PriorityValue, QueueItem, Queues}; +use crate::rgb_led::LedHandle; +use crate::sensors::slow; + +type SensMsg = SensorMessage<10>; + +async fn collect_pending( + publish: &Queues, + reading: PriorityValue, +) -> SensorMessage<10> { + let mut msg = SensMsg::default(); + let low_priority = reading.low_priority(); + unwrap!(msg.values.push(reading.value)); + + if low_priority { + let deadline = Instant::now() + Duration::from_millis(200); + while msg.space_left() { + let until = deadline.saturating_duration_since(Instant::now()); + match with_timeout(until, publish.receive_reading()).await { + Ok(new) if new.low_priority() => { + unwrap!(msg.values.push(new.value)); + } + Ok(new) => { + unwrap!(msg.values.push(new.value)); + break; + } + Err(_timeout) => break, + } + } + } else { + while msg.space_left() { + let Some(next) = publish.next_ready() else { + break; + }; + unwrap!(msg.values.push(next.value)); + } + } + msg +} + +async fn get_messages<'a>(publish: &Queues, buf: &'a mut [u8]) -> &'a [u8] { + let next = publish.receive().await; + match next { + QueueItem::Reading(reading) => { + let msg = collect_pending(publish, reading).await; + let encoded_len = msg.encode_slice(&mut buf[1..]).len(); + buf[0] = protocol::Msg::<0>::READINGS; + &buf[..=encoded_len] + } + QueueItem::Error(error) => { + let error = protocol::large_bedroom::Error::Bed(error.into()); + let error = protocol::Error::LargeBedroom(error); + let encoded_len = + ErrorReport::new(error).encode_slice(&mut buf[1..]).len(); + buf[0] = protocol::Msg::<0>::ERROR_REPORT; + &buf[..=encoded_len] + } + } +} + +const fn max(a: usize, b: usize) -> usize { + [a, b][(a < b) as usize] +} + +#[task] +pub async fn handle( + stack: Stack<'static>, + publish: &'static Queues, + led: LedHandle, + driver_orderers: &'static slow::DriverOrderers, +) { + let mut rx_buffer = [0; 4096]; + let mut tx_buffer = [0; max( + max(SensMsg::ENCODED_SIZE, ErrorReport::ENCODED_SIZE) * 2, + 4096, + )]; + + let mut socket = TcpSocket::new(stack, &mut rx_buffer, &mut tx_buffer); + socket.set_timeout(Some(Duration::from_secs(5))); + socket.set_keep_alive(Some(Duration::from_secs(1))); + let host_addr = Ipv4Address::new(192, 168, 1, 43); + let host_port = 1234; + + let mut sequential_errors = 0; + + debug!("Configured socket and connecting"); + loop { + debug!("socket state: {:?}", socket.state()); + if let Err(e) = socket.connect((host_addr, host_port)).await { + if sequential_errors > 3 { + defmt::info!("failing to reconnect, resetting node"); + defmt::flush(); + Timer::after_secs(1).await; + cortex_m::peripheral::SCB::sys_reset(); + } + warn!("connect error: {}", e); + sequential_errors += 1; + Timer::after_secs(5).await; + continue; + } + + info!("(re-)connected"); + sequential_errors = 0; + // Prevent out-dated data from being send + publish.clear().await; + + let (reader, writer) = socket.split(); + match select( + send_messages(writer, publish), + receive_orders(reader, &led, driver_orderers), + ) + .await + { + select::Either::First(e) => { + warn!("Error while sending messages: {}", e) + } + select::Either::Second(e) => warn!("Error receiving orders: {}", e), + }; + // Or the socket will hang for a while waiting to close this makes sure + // we can reconnect instantly + socket.abort(); + Timer::after_secs(60).await; // Experiment: does this help? + } +} + +fn affector_list() -> affector::ListMessage<6> { + let mut list = affector::ListMessage::<6>::empty(); + unwrap!(list.values.push(Affector::LargeBedroom( + protocol::large_bedroom::Affector::Bed(bed::Affector::RgbLed { + red: 0, + green: 0, + blue: 0, + }), + ))); + unwrap!(list.values.push(Affector::LargeBedroom( + protocol::large_bedroom::Affector::Bed(bed::Affector::Sps30FanClean), + ))); + unwrap!(list.values.push(Affector::LargeBedroom( + protocol::large_bedroom::Affector::Bed( + bed::Affector::MhzZeroPointCalib + ), + ))); + unwrap!(list.values.push(Affector::LargeBedroom( + protocol::large_bedroom::Affector::Bed(bed::Affector::Nau7802LeftCalib), + ))); + unwrap!(list.values.push(Affector::LargeBedroom( + protocol::large_bedroom::Affector::Bed( + bed::Affector::Nau7802RightCalib + ), + ))); + unwrap!(list.values.push(Affector::LargeBedroom( + protocol::large_bedroom::Affector::Bed(bed::Affector::ResetNode) + ))); + + list +} + +async fn send_messages( + mut tcp: TcpWriter<'_>, + publish: &Queues, +) -> embassy_net::tcp::Error { + let mut buf = [0; 1 + max( + max(SensMsg::ENCODED_SIZE, ErrorReport::ENCODED_SIZE), + affector::ListMessage::<5>::ENCODED_SIZE, + )]; + let encoded_len = affector_list().encode_slice(&mut buf[1..]).len(); + buf[0] = protocol::Msg::<5>::AFFECTOR_LIST; + let to_send = &buf[..=encoded_len]; + if let Err(e) = tcp.write_all(to_send).await { + return e; + } + if let Err(e) = tcp.flush().await { + return e; + } + + loop { + let to_send = get_messages(publish, &mut buf).await; + if let Err(e) = tcp.write_all(to_send).await { + return e; + } + if let Err(e) = tcp.flush().await { + return e; + } + } +} + +#[derive(defmt::Format)] +enum ReadError { + ConnectionClosed, + TcpError(embassy_net::tcp::Error), + Deserialize(DeserializeError), +} + +async fn receive_orders( + mut tcp: TcpReader<'_>, + led: &LedHandle, + driver_orderers: &slow::DriverOrderers, +) -> ReadError { + defmt::debug!("ready to receive orders"); + let mut decoder = affector::Decoder::default(); + let mut buf = [0u8; 100]; + loop { + let res = tcp.read(&mut buf).await; + let n_read = match res { + Ok(0) => return ReadError::ConnectionClosed, + Ok(n_read) => n_read, + Err(e) => return ReadError::TcpError(e), + }; + let mut read = &buf[..n_read]; + + loop { + let (item, remaining) = match decoder.feed(read) { + Ok(Some((item, remaining))) => (item, remaining), + Ok(None) => break, + Err(e) => return ReadError::Deserialize(e), + }; + + read = remaining; + + let Affector::LargeBedroom(large_bedroom::Affector::Bed(affector)) = + item + else { + defmt::error!("Got affector for other node"); + continue; + }; + + defmt::info!("got affector order: {:?}", affector); + match affector { + bed::Affector::Nau7802LeftCalib + | bed::Affector::Nau7802RightCalib => { + defmt::warn!("unimplemented affector: {:?}", affector) + } + bed::Affector::MhzZeroPointCalib => { + driver_orderers.mhz.send(()).await; + } + bed::Affector::Sps30FanClean => { + driver_orderers.sps.send(()).await; + } + bed::Affector::RgbLed { red, green, blue } => { + led.set_color( + red as f32 / u8::MAX as f32, + green as f32 / u8::MAX as f32, + blue as f32 / u8::MAX as f32, + ) + .await + } + bed::Affector::ResetNode => { + defmt::info!("resetting node as orderd via affector"); + defmt::flush(); + cortex_m::peripheral::SCB::sys_reset(); + } + } + } + } +} diff --git a/nodes/embassy/large-bedroom-bed/src/rgb_led.rs b/nodes/embassy/large-bedroom-bed/src/rgb_led.rs new file mode 100644 index 00000000..43874cdc --- /dev/null +++ b/nodes/embassy/large-bedroom-bed/src/rgb_led.rs @@ -0,0 +1,159 @@ +use embassy_executor::task; +use embassy_stm32::gpio::OutputType; +use embassy_stm32::peripherals::{PB13, PB14, PB15, TIM1}; +use embassy_stm32::time::khz; +use embassy_stm32::timer::complementary_pwm::{ + ComplementaryPwm, ComplementaryPwmPin, +}; +use embassy_stm32::{timer, Peri}; +use embassy_sync::blocking_mutex::raw::ThreadModeRawMutex; +use embassy_sync::channel::Channel; + +struct RgbLed { + pwm: ComplementaryPwm<'static, TIM1>, + r: f32, + g: f32, + b: f32, +} + +impl RgbLed { + fn new( + timer: Peri<'static, TIM1>, + b: Peri<'static, PB15>, + r: Peri<'static, PB14>, + g: Peri<'static, PB13>, + ) -> Self { + use embassy_stm32::timer::Channel; + + let b = ComplementaryPwmPin::new(b, OutputType::PushPull); + let r = ComplementaryPwmPin::new(r, OutputType::PushPull); + let g = ComplementaryPwmPin::new(g, OutputType::PushPull); + + let mut pwm = ComplementaryPwm::new( + timer, + None, + Some(g), + None, + Some(r), + None, + Some(b), + None, + None, + khz(10), + Default::default(), + ); + + for channel in [Channel::Ch1, Channel::Ch2, Channel::Ch3] { + pwm.set_duty(channel, pwm.get_max_duty()); + pwm.enable(channel); + } + + Self { + pwm, + r: 1.0, + g: 1.0, + b: 1.0, + } + } + + fn set(&mut self, channel: timer::Channel, brightness: f32) { + let max = self.pwm.get_max_duty(); + let scaled = (brightness * max as f32) as u16; + let complementary_duty = max - scaled; + self.pwm.set_duty(channel, complementary_duty); + } + + fn set_red(&mut self, brightness: f32) { + self.set(timer::Channel::Ch1, brightness); + } + + fn set_blue(&mut self, brightness: f32) { + self.set(timer::Channel::Ch2, brightness); + } + + fn set_green(&mut self, brightness: f32) { + self.set(timer::Channel::Ch3, brightness); + } + + fn update(&mut self, bri: f32) { + let sum = (self.r + self.b + self.g).min(1.0); + let r = self.r / sum; + let b = self.b / sum; + let g = self.g / sum; + self.set_red(bri * r); + self.set_blue(bri * b); + self.set_green(bri * g); + } +} + +pub(crate) enum Event { + SetColor { r: f32, g: f32, b: f32 }, + LuxChanged(f32), +} + +#[derive(Clone)] +pub struct LedHandle { + led_comms: &'static Channel, +} + +impl LedHandle { + pub const fn new( + led_comms: &'static Channel, + ) -> Self { + Self { led_comms } + } + pub async fn set_color(&self, r: f32, g: f32, b: f32) { + self.led_comms.send(Event::SetColor { r, g, b }).await + } + + pub async fn update_lux(&self, lux: f32) { + self.led_comms.send(Event::LuxChanged(lux)).await + } +} + +fn lookup_bri(lux: f32) -> f32 { + const LOOKUP_TABLE: [(f32, f32); 7] = [ + (5., 0.01), + (10., 0.05), + (20., 0.1), + (40., 0.2), + (80., 0.4), + (160., 0.5), + (320., 0.6), + ]; + + LOOKUP_TABLE + .iter() + .find(|(lux_entry, _)| *lux_entry > lux) + .map(|(_, bri)| bri) + .copied() + .unwrap_or(0.6) +} + +#[task] +pub(crate) async fn control_leds( + timer: Peri<'static, TIM1>, + r: Peri<'static, PB14>, + g: Peri<'static, PB13>, + b: Peri<'static, PB15>, + led_comms: &'static Channel, +) { + let mut led = RgbLed::new(timer, b, r, g); + let mut bri = 0.01; // Start with minimal bri + + loop { + let order = led_comms.receive().await; + match order { + Event::SetColor { r, g, b } => { + led.r = r; + led.g = g; + led.b = b; + } + Event::LuxChanged(new) => { + bri = lookup_bri(new); + } + } + + led.update(bri); + } +} diff --git a/nodes/embassy/large-bedroom-bed/src/rng.rs b/nodes/embassy/large-bedroom-bed/src/rng.rs new file mode 100644 index 00000000..f489557d --- /dev/null +++ b/nodes/embassy/large-bedroom-bed/src/rng.rs @@ -0,0 +1,31 @@ +use embassy_stm32::peripherals::ADC1; +use embassy_time::Timer; +use rand::{RngCore, SeedableRng}; + +use embassy_stm32::adc::{Adc, Temperature, VrefInt}; +/// #Warning +/// Should only be called before async tasks are spawned. This takes a lot of +/// time to run and will disturb any async task running. +pub async fn generate_seed_blocking(adc: embassy_stm32::Peri<'_, ADC1>) -> u64 { + let mut adc = Adc::new(adc); + + let mut vrefint = adc.enable_vrefint(); + let mut temp = adc.enable_temperature(); + + // Startup delay can be combined to the maximum of either + Timer::after_micros(Temperature::start_time_us().max(VrefInt::start_time_us()) as u64).await; + + let mut seed = [0u8; 16]; + let mut bytes = seed.chunks_exact_mut(2); + while let Some([byte1, byte2]) = bytes.next() { + let sample = adc.blocking_read(&mut temp); + let most_noisy_byte = (sample & 0b0000_0000_1111_1111) as u8; + *byte1 = most_noisy_byte; + let sample = adc.blocking_read(&mut vrefint); + let most_noisy_byte = (sample & 0b0000_0000_1111_1111) as u8; + *byte2 = most_noisy_byte; + } + + let mut rng = rand::rngs::SmallRng::from_seed(seed); + rng.next_u64() +} diff --git a/nodes/embassy/large-bedroom-bed/src/sensors.rs b/nodes/embassy/large-bedroom-bed/src/sensors.rs new file mode 100644 index 00000000..04565f91 --- /dev/null +++ b/nodes/embassy/large-bedroom-bed/src/sensors.rs @@ -0,0 +1,68 @@ +use defmt::info; +use embassy_executor::task; +use embassy_futures::join; +use embassy_stm32::i2c::{I2c, Master}; +use embassy_stm32::mode::{Async, Blocking}; +use embassy_stm32::usart::Uart; +use embassy_sync::blocking_mutex::raw::NoopRawMutex; +use embassy_sync::mutex::Mutex; +use fast::ButtonInputs; +use protocol::large_bedroom::bed::Device; + +use crate::rgb_led; +use sensors::{I2cWrapper, Nau7802DriverBlocking, SPS30_UART_BUF_SIZE}; +pub mod fast; +pub mod slow; + +use sensors::{ + Bme680Driver, Max44Driver, MhzDriver, Nau7802Driver, Sht31Driver, + Sps30Driver, +}; + +fn local_dev(dev: protocol::large_bedroom::bed::Device) -> protocol::Device { + protocol::Device::LargeBedroom(protocol::large_bedroom::Device::Bed(dev)) +} + +#[task] +pub async fn init_then_measure( + orderers: &'static slow::DriverOrderers, + rgb_led: rgb_led::LedHandle, + i2c_1: Mutex>, + i2c_2: Mutex>, + i2c_3: Mutex>, + usart_mhz: Uart<'static, Async>, + usart_sps: Uart<'static, Async>, + buttons: ButtonInputs, +) -> ! { + info!("initializing sensors"); + let bme = Bme680Driver::new(&i2c_3, local_dev(Device::Bme680)); + let max44009 = Max44Driver::new(&i2c_1, local_dev(Device::Max44)); + let sht = Sht31Driver::new(&i2c_1, local_dev(Device::Sht31)); + let i2c_2 = I2cWrapper(i2c_2); + let nau_right = + Nau7802DriverBlocking::new(&i2c_2, local_dev(Device::Nau7802Right)); + let nau_left = Nau7802Driver::new(&i2c_3, local_dev(Device::Nau7802Left)); + + let (tx, rx) = usart_mhz.split(); + let mut usart_buf = [0u8; 9 * 10]; // 9 byte messages + let rx = rx.into_ring_buffered(&mut usart_buf); + let mhz = MhzDriver::new(tx, rx, local_dev(Device::Mhz14)); + + let (tx, rx) = usart_sps.split(); + let mut usart_buf = [0u8; SPS30_UART_BUF_SIZE]; + let rx = rx.into_ring_buffered(&mut usart_buf); + let sps30 = Sps30Driver::init(tx, rx, local_dev(Device::Sps30)); + + let sensors_fast = + fast::read(max44009, nau_right, nau_left, buttons, rgb_led); + let drivers = slow::Drivers { + sht, + bme, + mhz, + sps: sps30, + }; + let sensors_slow = slow::read(drivers, orderers); + join::join(sensors_fast, sensors_slow).await; + + defmt::unreachable!(); +} diff --git a/nodes/embassy/large-bedroom-bed/src/sensors/fast.rs b/nodes/embassy/large-bedroom-bed/src/sensors/fast.rs new file mode 100644 index 00000000..bc7eb348 --- /dev/null +++ b/nodes/embassy/large-bedroom-bed/src/sensors/fast.rs @@ -0,0 +1,200 @@ +use embassy_futures::{ + join::{self, join3, join4}, + yield_now, +}; +use embassy_stm32::exti::ExtiInput; +use embassy_time::{Duration, Instant, Timer}; + +use protocol::large_bedroom::{bed::Button, bed::Reading}; + +use crate::{rgb_led, PUBLISH}; +use sensors::{Max44Driver, Nau7802Driver, Nau7802DriverBlocking}; + +fn sig_lux_diff(old: f32, new: f32) -> bool { + let diff = old - new; + // we do not have f32::abs on embedded + diff > old / 20.0 || -diff > old / 20.0 +} + +fn sig_weight_diff(old: u32, new: u32) -> bool { + let diff = new.abs_diff(old); + diff > 15 +} + +async fn report_lux(mut max44: Max44Driver<'_>, rgb_led: rgb_led::LedHandle) { + const MAX_INTERVAL: Duration = Duration::from_secs(5); + + let mut prev_lux = f32::MAX; + let mut last_lux = Instant::now(); + + loop { + Timer::after_millis(50).await; + let lux = match max44.try_measure().await { + Ok(lux) => lux, + Err(err) if last_lux.elapsed() > MAX_INTERVAL => { + PUBLISH.queue_error(err); + continue; + } + Err(_) => continue, + }; + + if sig_lux_diff(prev_lux, lux) { + PUBLISH.send_p2(Reading::Brightness(lux)); + rgb_led.update_lux(lux).await; + } else if last_lux.elapsed() > MAX_INTERVAL { + PUBLISH.send_p1(Reading::Brightness(lux)); + } else { + yield_now().await; + continue; + }; + + prev_lux = lux; + last_lux = Instant::now(); + } +} + +trait Nau { + async fn try_measure(&mut self) -> Result; +} + +impl Nau for Nau7802Driver<'_> { + async fn try_measure(&mut self) -> Result { + Nau7802Driver::try_measure(self).await + } +} + +impl Nau for Nau7802DriverBlocking<'_> { + async fn try_measure(&mut self) -> Result { + Nau7802DriverBlocking::try_measure(self).await + } +} + +enum Position { + Left, + Right, +} + +async fn report_weight( + mut nau: impl Nau, + wrap_reading: impl Fn(u32) -> Reading, + position: Position, +) { + const MAX_INTERVAL: Duration = Duration::from_secs(5); + + let mut prev_weight = u32::MAX; + let mut reported_at = Instant::now(); + + loop { + Timer::after_millis(100).await; + let weight = match nau.try_measure().await { + Ok(lux) => lux, + Err(err) if reported_at.elapsed() > MAX_INTERVAL => { + let err = if matches!(position, Position::Right) { + err.into_right() + } else { + err // default is left + }; + PUBLISH.queue_error(err); + continue; + } + Err(_) => continue, + }; + + if sig_weight_diff(prev_weight, weight) { + PUBLISH.send_p2(wrap_reading(weight)); + } else if reported_at.elapsed() > MAX_INTERVAL { + PUBLISH.send_p1(wrap_reading(weight)); + } else { + yield_now().await; + continue; + }; + + prev_weight = weight; + reported_at = Instant::now(); + } +} + +async fn watch_button( + mut input: ExtiInput<'static>, + event: impl Fn(protocol::button::Press) -> Button, +) { + use sensors::{errors::PressTooLong, errors::SensorError, Error}; + + loop { + Timer::after(Duration::from_secs(200)).await; + } + // let mut went_high_at: Option = None; + // loop { + // if let Some(went_high_at) = went_high_at.take() { + // input.wait_for_low().await; + // let press = went_high_at.elapsed(); + // let Ok(press) = press.as_millis().try_into() else { + // let event_for_printing = (event)(protocol::button::Press(0)); + // let name = event_for_printing.variant_name(); + // PUBLISH.queue_error(Error::Running(SensorError::Button( + // PressTooLong { button: name }, + // ))); + // continue; + // }; + // let event = (event)(protocol::button::Press(press)); + // PUBLISH.send_p2(Reading::Button(event)); + // } else { + // input.wait_for_high().await; + // let now = Instant::now(); + // Timer::after(Duration::from_millis(80)).await; + // if input.is_low() { + // continue; + // } else { + // went_high_at = Some(now); + // } + // } + // } +} + +pub struct ButtonInputs { + pub top: ExtiInput<'static>, + pub middle_inner: ExtiInput<'static>, + pub middle_center: ExtiInput<'static>, + pub middle_outer: ExtiInput<'static>, + pub lower_inner: ExtiInput<'static>, + pub lower_center: ExtiInput<'static>, + pub lower_outer: ExtiInput<'static>, +} + +pub(crate) async fn read( + max44: Max44Driver<'_>, + nau_right: Nau7802DriverBlocking<'_>, + nau_left: Nau7802Driver<'_>, + inputs: ButtonInputs, + rgb_led: rgb_led::LedHandle, +) { + use protocol::large_bedroom::bed::Button; + + let watch_buttons_1 = join4( + watch_button(inputs.top, Button::Top), + watch_button(inputs.middle_inner, Button::MiddleInner), + watch_button(inputs.middle_center, Button::MiddleCenter), + watch_button(inputs.middle_outer, Button::MiddleOuter), + ); + + let watch_buttons_2 = join3( + watch_button(inputs.lower_inner, Button::LowerInner), + watch_button(inputs.lower_center, Button::LowerCenter), + watch_button(inputs.lower_outer, Button::LowerOuter), + ); + + let watch_lux = report_lux(max44, rgb_led); + let report_right_weight = + report_weight(nau_right, Reading::WeightRight, Position::Right); + let report_left_weight = + report_weight(nau_left, Reading::WeightLeft, Position::Left); + + join::join5( + report_left_weight, + report_right_weight, + watch_lux, + watch_buttons_1, + watch_buttons_2, + ) + .await; +} diff --git a/nodes/embassy/large-bedroom-bed/src/sensors/slow.rs b/nodes/embassy/large-bedroom-bed/src/sensors/slow.rs new file mode 100644 index 00000000..a6d80462 --- /dev/null +++ b/nodes/embassy/large-bedroom-bed/src/sensors/slow.rs @@ -0,0 +1,189 @@ +use defmt::unwrap; +use embassy_futures::join::join5; +use embassy_futures::select; +use embassy_sync::blocking_mutex::raw::ThreadModeRawMutex; +use embassy_sync::channel::Channel; +use embassy_time::Timer; +use embassy_time::{with_timeout, Duration}; + +use protocol::large_bedroom::bed::Reading; + +use crate::PUBLISH; +use sensors::measurements; +use sensors::{Bme680Driver, Driver, Sht31Driver, Sps30Driver}; +use sensors::{Error, MhzDriver}; + +type Signal = embassy_sync::signal::Signal; + +/// Measure when signal is received or control the device's +/// affector when it is ordered +#[inline(always)] +async fn measure_and_control( + mut driver: D, + order: &Channel, + send: F, + signal: &Signal, +) where + D: Driver, + F: Fn(Result), +{ + let timeout = Duration::from_secs(15); + loop { + match select::select(signal.wait(), order.receive()).await { + select::Either::First(_) => { + let try_measure = Driver::try_measure(&mut driver); + let res = match with_timeout(timeout, try_measure).await { + Ok(res) => res, + Err(_) => Err(Error::Timeout(driver.device())), + }; + send(res); + } + select::Either::Second(order) => { + let affect = Driver::affect(&mut driver, order); + let res = match with_timeout(timeout, affect).await { + Ok(Ok(_)) => continue, + Ok(Err(e)) => Err(e), + Err(_) => Err(Error::Timeout(driver.device())), + }; + send(res); + } + } + } +} + +async fn order_measurements_every_period(signals: &[Signal]) { + loop { + for signal in signals { + signal.signal(()); + } + Timer::after_secs(5).await; + } +} + +pub(crate) struct Drivers<'a> { + pub sht: Sht31Driver<'a>, + pub bme: Bme680Driver<'a>, + pub mhz: MhzDriver<'a>, + pub sps: Sps30Driver<'a>, +} + +pub(crate) struct DriverOrderers { + pub sht: Channel, + pub bme: Channel, + pub mhz: Channel, + pub sps: Channel, +} +impl DriverOrderers { + pub(crate) const fn new() -> Self { + Self { + sht: Channel::new(), + bme: Channel::new(), + mhz: Channel::new(), + sps: Channel::new(), + } + } +} + +#[inline(always)] +pub async fn read(drivers: Drivers<'_>, orderers: &DriverOrderers) { + let signals = [const { Signal::new() }; 4]; + + join5( + order_measurements_every_period(&signals), + measure_and_control( + drivers.sht, + &orderers.sht, + publish_sht_result, + &signals[0], + ), + measure_and_control( + drivers.bme, + &orderers.bme, + publish_bme_result, + &signals[1], + ), + measure_and_control( + drivers.mhz, + &orderers.mhz, + publish_mhz_result, + &signals[2], + ), + measure_and_control( + drivers.sps, + &orderers.sps, + publish_sps_result, + &signals[3], + ), + ) + .await; +} + +fn publish_sps_result(sps_res: Result) { + match sps_res { + Ok(measurements::Sps30 { + mass_pm1_0, + mass_pm2_5, + mass_pm4_0, + mass_pm10, + number_pm0_5, + number_pm1_0, + number_pm2_5, + number_pm4_0, + number_pm10, + typical_particle_size, + .. + }) => { + PUBLISH.send_p0(Reading::MassPm1_0(mass_pm1_0)); + PUBLISH.send_p0(Reading::MassPm2_5(mass_pm2_5)); + PUBLISH.send_p0(Reading::MassPm4_0(mass_pm4_0)); + PUBLISH.send_p0(Reading::MassPm10(mass_pm10)); + PUBLISH.send_p0(Reading::NumberPm0_5(number_pm0_5)); + PUBLISH.send_p0(Reading::NumberPm1_0(number_pm1_0)); + PUBLISH.send_p0(Reading::NumberPm2_5(number_pm2_5)); + PUBLISH.send_p0(Reading::NumberPm4_0(number_pm4_0)); + PUBLISH.send_p0(Reading::NumberPm10(number_pm10)); + PUBLISH + .send_p0(Reading::TypicalParticleSize(typical_particle_size)); + } + Err(err) => PUBLISH.queue_error(err), + } +} + +fn publish_mhz_result(mhz_res: Result) { + match mhz_res { + Ok(measurements::Mhz { co2, .. }) => { + PUBLISH.send_p0(Reading::Co2(co2)); + } + Err(err) => { + PUBLISH.queue_error(err); + } + } +} + +fn publish_sht_result(sht_res: Result) { + match sht_res { + Ok(measurements::Sht31 { + temperature, + humidity, + }) => { + PUBLISH.send_p0(Reading::Temperature(temperature)); + PUBLISH.send_p0(Reading::Humidity(humidity)); + } + Err(err) => PUBLISH.queue_error(err), + } +} + +fn publish_bme_result(bme_res: Result) { + match bme_res { + Ok(measurements::Bme { + pressure, + gas_resistance, + .. + }) => { + let gas_resistance = unwrap!(gas_resistance); // sensor is on + PUBLISH.send_p0(Reading::GassResistance(gas_resistance)); + PUBLISH.send_p0(Reading::Pressure(pressure)); + } + Err(err) => PUBLISH.queue_error(err), + } +} diff --git a/nodes/embassy/large-bedroom-bed/stm32f401.svd b/nodes/embassy/large-bedroom-bed/stm32f401.svd new file mode 100644 index 00000000..b9353d01 --- /dev/null +++ b/nodes/embassy/large-bedroom-bed/stm32f401.svd @@ -0,0 +1,35196 @@ + + + STM32F401 + 1.1 + STM32F401 + + CM4 + r1p0 + little + false + false + 4 + false + + 8 + 32 + 0x20 + 0x00000000 + 0xFFFFFFFF + + + ADC_Common + ADC common registers + ADC_Common + 0x40012300 + + 0x0 + 0x9 + registers + + + FPU + FPU interrupt + 81 + + + + CCR + CCR + ADC common control register + 0x4 + 0x20 + read-write + 0x00000000 + + + TSVREFE + Temperature sensor and VREFINT + enable + 23 + 1 + + TSVREFE + read-write + + Disabled + Temperature sensor and V_REFINT channel disabled + 0 + + + Enabled + Temperature sensor and V_REFINT channel enabled + 1 + + + + + VBATE + VBAT enable + 22 + 1 + + VBATE + read-write + + Disabled + V_BAT channel disabled + 0 + + + Enabled + V_BAT channel enabled + 1 + + + + + ADCPRE + ADC prescaler + 16 + 2 + + ADCPRE + read-write + + Div2 + PCLK2 divided by 2 + 0 + + + Div4 + PCLK2 divided by 4 + 1 + + + Div6 + PCLK2 divided by 6 + 2 + + + Div8 + PCLK2 divided by 8 + 3 + + + + + + + + + ADC1 + Analog-to-digital converter + ADC + 0x40012000 + + 0x0 + 0x51 + registers + + + ADC + ADC1 global interrupt + 18 + + + + SR + SR + status register + 0x0 + 0x20 + read-write + 0x00000000 + + + OVR + Overrun + 5 + 1 + zeroToClear + + OVRR + read + + NoOverrun + No overrun occurred + 0 + + + Overrun + Overrun occurred + 1 + + + + OVRW + write + + Clear + Clear flag + 0 + + + + + STRT + Regular channel start flag + 4 + 1 + zeroToClear + + STRTR + read + + NotStarted + No regular channel conversion started + 0 + + + Started + Regular channel conversion has started + 1 + + + + STRTW + write + + Clear + Clear flag + 0 + + + + + JSTRT + Injected channel start + flag + 3 + 1 + zeroToClear + + JSTRTR + read + + NotStarted + No injected channel conversion started + 0 + + + Started + Injected channel conversion has started + 1 + + + + JSTRTW + write + + Clear + Clear flag + 0 + + + + + JEOC + Injected channel end of + conversion + 2 + 1 + zeroToClear + + JEOCR + read + + NotComplete + Conversion is not complete + 0 + + + Complete + Conversion complete + 1 + + + + JEOCW + write + + Clear + Clear flag + 0 + + + + + EOC + Regular channel end of + conversion + 1 + 1 + zeroToClear + + EOCR + read + + NotComplete + Conversion is not complete + 0 + + + Complete + Conversion complete + 1 + + + + EOCW + write + + Clear + Clear flag + 0 + + + + + AWD + Analog watchdog flag + 0 + 1 + zeroToClear + + AWDR + read + + NoEvent + No analog watchdog event occurred + 0 + + + Event + Analog watchdog event occurred + 1 + + + + AWDW + write + + Clear + Clear flag + 0 + + + + + + + CR1 + CR1 + control register 1 + 0x4 + 0x20 + read-write + 0x00000000 + + + OVRIE + Overrun interrupt enable + 26 + 1 + + OVRIE + read-write + + Disabled + Overrun interrupt disabled + 0 + + + Enabled + Overrun interrupt enabled + 1 + + + + + RES + Resolution + 24 + 2 + + RES + read-write + + TwelveBit + 12-bit (15 ADCCLK cycles) + 0 + + + TenBit + 10-bit (13 ADCCLK cycles) + 1 + + + EightBit + 8-bit (11 ADCCLK cycles) + 2 + + + SixBit + 6-bit (9 ADCCLK cycles) + 3 + + + + + AWDEN + Analog watchdog enable on regular + channels + 23 + 1 + + AWDEN + read-write + + Disabled + Analog watchdog disabled on regular channels + 0 + + + Enabled + Analog watchdog enabled on regular channels + 1 + + + + + JAWDEN + Analog watchdog enable on injected + channels + 22 + 1 + + JAWDEN + read-write + + Disabled + Analog watchdog disabled on injected channels + 0 + + + Enabled + Analog watchdog enabled on injected channels + 1 + + + + + DISCNUM + Discontinuous mode channel + count + 13 + 3 + + + 0 + 7 + + + + + JDISCEN + Discontinuous mode on injected + channels + 12 + 1 + + JDISCEN + read-write + + Disabled + Discontinuous mode on injected channels disabled + 0 + + + Enabled + Discontinuous mode on injected channels enabled + 1 + + + + + DISCEN + Discontinuous mode on regular + channels + 11 + 1 + + DISCEN + read-write + + Disabled + Discontinuous mode on regular channels disabled + 0 + + + Enabled + Discontinuous mode on regular channels enabled + 1 + + + + + JAUTO + Automatic injected group + conversion + 10 + 1 + + JAUTO + read-write + + Disabled + Automatic injected group conversion disabled + 0 + + + Enabled + Automatic injected group conversion enabled + 1 + + + + + AWDSGL + Enable the watchdog on a single channel + in scan mode + 9 + 1 + + AWDSGL + read-write + + AllChannels + Analog watchdog enabled on all channels + 0 + + + SingleChannel + Analog watchdog enabled on a single channel + 1 + + + + + SCAN + Scan mode + 8 + 1 + + SCAN + read-write + + Disabled + Scan mode disabled + 0 + + + Enabled + Scan mode enabled + 1 + + + + + JEOCIE + Interrupt enable for injected + channels + 7 + 1 + + JEOCIE + read-write + + Disabled + JEOC interrupt disabled + 0 + + + Enabled + JEOC interrupt enabled + 1 + + + + + AWDIE + Analog watchdog interrupt + enable + 6 + 1 + + AWDIE + read-write + + Disabled + Analogue watchdog interrupt disabled + 0 + + + Enabled + Analogue watchdog interrupt enabled + 1 + + + + + EOCIE + Interrupt enable for EOC + 5 + 1 + + EOCIE + read-write + + Disabled + EOC interrupt disabled + 0 + + + Enabled + EOC interrupt enabled + 1 + + + + + AWDCH + Analog watchdog channel select + bits + 0 + 5 + + + 0 + 18 + + + + + + + CR2 + CR2 + control register 2 + 0x8 + 0x20 + read-write + 0x00000000 + + + SWSTART + Start conversion of regular + channels + 30 + 1 + + SWSTARTW + write + + Start + Starts conversion of regular channels + 1 + + + + + EXTEN + External trigger enable for regular + channels + 28 + 2 + + EXTEN + read-write + + Disabled + Trigger detection disabled + 0 + + + RisingEdge + Trigger detection on the rising edge + 1 + + + FallingEdge + Trigger detection on the falling edge + 2 + + + BothEdges + Trigger detection on both the rising and falling edges + 3 + + + + + EXTSEL + External event select for regular + group + 24 + 4 + + EXTSEL + read-write + + TIM1CC1 + Timer 1 CC1 event + 0 + + + TIM1CC2 + Timer 1 CC2 event + 1 + + + TIM1CC3 + Timer 1 CC3 event + 2 + + + TIM2CC2 + Timer 2 CC2 event + 3 + + + TIM2CC3 + Timer 2 CC3 event + 4 + + + TIM2CC4 + Timer 2 CC4 event + 5 + + + TIM2TRGO + Timer 2 TRGO event + 6 + + + TIM3CC1 + Timer 3 CC1 event + 7 + + + TIM3TRGO + Timer 3 TRGO event + 8 + + + TIM4CC4 + Timer 4 CC4 event + 9 + + + TIM5CC1 + Timer 5 CC1 event + 10 + + + TIM5CC2 + Timer 5 CC2 event + 11 + + + TIM5CC3 + Timer 5 CC3 event + 12 + + + EXTI11 + EXTI line 11 + 15 + + + + + JSWSTART + Start conversion of injected + channels + 22 + 1 + + JSWSTARTW + write + + Start + Starts conversion of injected channels + 1 + + + + + JEXTEN + External trigger enable for injected + channels + 20 + 2 + + JEXTEN + read-write + + Disabled + Trigger detection disabled + 0 + + + RisingEdge + Trigger detection on the rising edge + 1 + + + FallingEdge + Trigger detection on the falling edge + 2 + + + BothEdges + Trigger detection on both the rising and falling edges + 3 + + + + + JEXTSEL + External event select for injected + group + 16 + 4 + + JEXTSEL + read-write + + TIM1CC4 + Timer 1 CC4 event + 0 + + + TIM1TRGO + Timer 1 TRGO event + 1 + + + TIM2CC1 + Timer 2 CC1 event + 2 + + + TIM2TRGO + Timer 2 TRGO event + 3 + + + TIM3CC2 + Timer 3 CC2 event + 4 + + + TIM3CC4 + Timer 3 CC4 event + 5 + + + TIM4CC1 + Timer 4 CC1 event + 6 + + + TIM4CC2 + Timer 4 CC2 event + 7 + + + TIM4CC3 + Timer 4 CC3 event + 8 + + + TIM4TRGO + Timer 4 TRGO event + 9 + + + TIM5CC4 + Timer 5 CC4 event + 10 + + + TIM5TRGO + Timer 5 TRGO event + 11 + + + EXTI15 + EXTI line 15 + 15 + + + + + ALIGN + Data alignment + 11 + 1 + + ALIGN + read-write + + Right + Right alignment + 0 + + + Left + Left alignment + 1 + + + + + EOCS + End of conversion + selection + 10 + 1 + + EOCS + read-write + + EachSequence + The EOC bit is set at the end of each sequence of regular conversions + 0 + + + EachConversion + The EOC bit is set at the end of each regular conversion + 1 + + + + + DDS + DMA disable selection (for single ADC + mode) + 9 + 1 + + DDS + read-write + + Single + No new DMA request is issued after the last transfer + 0 + + + Continuous + DMA requests are issued as long as data are converted and DMA=1 + 1 + + + + + DMA + Direct memory access mode (for single + ADC mode) + 8 + 1 + + DMA + read-write + + Disabled + DMA mode disabled + 0 + + + Enabled + DMA mode enabled + 1 + + + + + CONT + Continuous conversion + 1 + 1 + + CONT + read-write + + Single + Single conversion mode + 0 + + + Continuous + Continuous conversion mode + 1 + + + + + ADON + A/D Converter ON / OFF + 0 + 1 + + ADON + read-write + + Disabled + Disable ADC conversion and go to power down mode + 0 + + + Enabled + Enable ADC + 1 + + + + + + + SMPR1 + SMPR1 + sample time register 1 + 0xC + 0x20 + read-write + 0x00000000 + + + SMP18 + Channel 18 sampling time selection + 24 + 3 + + + + SMP17 + Channel 17 sampling time selection + 21 + 3 + + + + SMP16 + Channel 16 sampling time selection + 18 + 3 + + + + SMP15 + Channel 15 sampling time selection + 15 + 3 + + + + SMP14 + Channel 14 sampling time selection + 12 + 3 + + + + SMP13 + Channel 13 sampling time selection + 9 + 3 + + + + SMP12 + Channel 12 sampling time selection + 6 + 3 + + + + SMP11 + Channel 11 sampling time selection + 3 + 3 + + + + SMP10 + Channel 10 sampling time selection + 0 + 3 + + SMP10 + read-write + + Cycles3 + 3 cycles + 0 + + + Cycles15 + 15 cycles + 1 + + + Cycles28 + 28 cycles + 2 + + + Cycles56 + 56 cycles + 3 + + + Cycles84 + 84 cycles + 4 + + + Cycles112 + 112 cycles + 5 + + + Cycles144 + 144 cycles + 6 + + + Cycles480 + 480 cycles + 7 + + + + + + + SMPR2 + SMPR2 + sample time register 2 + 0x10 + 0x20 + read-write + 0x00000000 + + + SMP9 + Channel 9 sampling time selection + 27 + 3 + + + + SMP8 + Channel 8 sampling time selection + 24 + 3 + + + + SMP7 + Channel 7 sampling time selection + 21 + 3 + + + + SMP6 + Channel 6 sampling time selection + 18 + 3 + + + + SMP5 + Channel 5 sampling time selection + 15 + 3 + + + + SMP4 + Channel 4 sampling time selection + 12 + 3 + + + + SMP3 + Channel 3 sampling time selection + 9 + 3 + + + + SMP2 + Channel 2 sampling time selection + 6 + 3 + + + + SMP1 + Channel 1 sampling time selection + 3 + 3 + + + + SMP0 + Channel 0 sampling time selection + 0 + 3 + + SMP0 + read-write + + Cycles3 + 3 cycles + 0 + + + Cycles15 + 15 cycles + 1 + + + Cycles28 + 28 cycles + 2 + + + Cycles56 + 56 cycles + 3 + + + Cycles84 + 84 cycles + 4 + + + Cycles112 + 112 cycles + 5 + + + Cycles144 + 144 cycles + 6 + + + Cycles480 + 480 cycles + 7 + + + + + + + 4 + 0x4 + 1-4 + JOFR%s + JOFR1 + injected channel data offset register + x + 0x14 + 0x20 + read-write + 0x00000000 + + + JOFFSET + Data offset for injected channel + x + 0 + 12 + + + 0 + 4095 + + + + + + + HTR + HTR + watchdog higher threshold + register + 0x24 + 0x20 + read-write + 0x00000FFF + + + HT + Analog watchdog higher + threshold + 0 + 12 + + + 0 + 4095 + + + + + + + LTR + LTR + watchdog lower threshold + register + 0x28 + 0x20 + read-write + 0x00000000 + + + LT + Analog watchdog lower + threshold + 0 + 12 + + + 0 + 4095 + + + + + + + SQR1 + SQR1 + regular sequence register 1 + 0x2C + 0x20 + read-write + 0x00000000 + + + L + Regular channel sequence + length + 20 + 4 + + + 0 + 15 + + + + + SQ16 + 16th conversion in regular + sequence + 15 + 5 + + + 0 + 18 + + + + + SQ15 + 15th conversion in regular + sequence + 10 + 5 + + + 0 + 18 + + + + + SQ14 + 14th conversion in regular + sequence + 5 + 5 + + + 0 + 18 + + + + + SQ13 + 13th conversion in regular + sequence + 0 + 5 + + + 0 + 18 + + + + + + + SQR2 + SQR2 + regular sequence register 2 + 0x30 + 0x20 + read-write + 0x00000000 + + + SQ12 + 12th conversion in regular + sequence + 25 + 5 + + + 0 + 18 + + + + + SQ11 + 11th conversion in regular + sequence + 20 + 5 + + + 0 + 18 + + + + + SQ10 + 10th conversion in regular + sequence + 15 + 5 + + + 0 + 18 + + + + + SQ9 + 9th conversion in regular + sequence + 10 + 5 + + + 0 + 18 + + + + + SQ8 + 8th conversion in regular + sequence + 5 + 5 + + + 0 + 18 + + + + + SQ7 + 7th conversion in regular + sequence + 0 + 5 + + + 0 + 18 + + + + + + + SQR3 + SQR3 + regular sequence register 3 + 0x34 + 0x20 + read-write + 0x00000000 + + + SQ6 + 6th conversion in regular + sequence + 25 + 5 + + + 0 + 18 + + + + + SQ5 + 5th conversion in regular + sequence + 20 + 5 + + + 0 + 18 + + + + + SQ4 + 4th conversion in regular + sequence + 15 + 5 + + + 0 + 18 + + + + + SQ3 + 3rd conversion in regular + sequence + 10 + 5 + + + 0 + 18 + + + + + SQ2 + 2nd conversion in regular + sequence + 5 + 5 + + + 0 + 18 + + + + + SQ1 + 1st conversion in regular + sequence + 0 + 5 + + + 0 + 18 + + + + + + + JSQR + JSQR + injected sequence register + 0x38 + 0x20 + read-write + 0x00000000 + + + JL + Injected sequence length + 20 + 2 + + + 0 + 3 + + + + + JSQ4 + 4th conversion in injected + sequence + 15 + 5 + + + 0 + 18 + + + + + JSQ3 + 3rd conversion in injected + sequence + 10 + 5 + + + 0 + 18 + + + + + JSQ2 + 2nd conversion in injected + sequence + 5 + 5 + + + 0 + 18 + + + + + JSQ1 + 1st conversion in injected + sequence + 0 + 5 + + + 0 + 18 + + + + + + + 4 + 0x4 + 1-4 + JDR%s + JDR1 + injected data register x + 0x3C + 0x20 + read-only + 0x00000000 + + + JDATA + Injected data + 0 + 16 + + + + + DR + DR + regular data register + 0x4C + 0x20 + read-only + 0x00000000 + + + DATA + Regular data + 0 + 16 + + + + + + + CRC + Cryptographic processor + CRC + 0x40023000 + + 0x0 + 0x400 + registers + + + + DR + DR + Data register + 0x0 + 0x20 + read-write + 0xFFFFFFFF + + + DR + Data Register + 0 + 32 + + + 0 + 4294967295 + + + + + + + IDR + IDR + Independent Data register + 0x4 + 0x20 + read-write + 0x00000000 + + + IDR + Independent Data register + 0 + 8 + + + 0 + 255 + + + + + + + CR + CR + Control register + 0x8 + 0x20 + write-only + 0x00000000 + + + RESET + Control regidter + 0 + 1 + + RESETW + write + + Reset + Resets the CRC calculation unit and sets the data register to 0xFFFF FFFF + 1 + + + + + + + + + DBGMCU + Debug support + DBG + 0xE0042000 + + 0x0 + 0x400 + registers + + + + IDCODE + IDCODE + IDCODE + 0x0 + 0x20 + read-only + 0x10006411 + + + DEV_ID + DEV_ID + 0 + 12 + + + REV_ID + REV_ID + 16 + 16 + + + + + CR + CR + Control Register + 0x4 + 0x20 + read-write + 0x00000000 + + + DBG_SLEEP + DBG_SLEEP + 0 + 1 + + + DBG_STOP + DBG_STOP + 1 + 1 + + + DBG_STANDBY + DBG_STANDBY + 2 + 1 + + + TRACE_IOEN + TRACE_IOEN + 5 + 1 + + + TRACE_MODE + TRACE_MODE + 6 + 2 + + + + + APB1_FZ + APB1_FZ + Debug MCU APB1 Freeze registe + 0x8 + 0x20 + read-write + 0x00000000 + + + DBG_TIM2_STOP + DBG_TIM2_STOP + 0 + 1 + + + DBG_TIM3_STOP + DBG_TIM3 _STOP + 1 + 1 + + + DBG_TIM4_STOP + DBG_TIM4_STOP + 2 + 1 + + + DBG_TIM5_STOP + DBG_TIM5_STOP + 3 + 1 + + + DBG_RTC_Stop + RTC stopped when Core is + halted + 10 + 1 + + + DBG_WWDG_STOP + DBG_WWDG_STOP + 11 + 1 + + + DBG_IWDG_STOP + DBG_IWDEG_STOP + 12 + 1 + + + DBG_I2C1_SMBUS_TIMEOUT + DBG_J2C1_SMBUS_TIMEOUT + 21 + 1 + + + DBG_I2C2_SMBUS_TIMEOUT + DBG_J2C2_SMBUS_TIMEOUT + 22 + 1 + + + DBG_I2C3SMBUS_TIMEOUT + DBG_J2C3SMBUS_TIMEOUT + 23 + 1 + + + + + APB2_FZ + APB2_FZ + Debug MCU APB2 Freeze registe + 0xC + 0x20 + read-write + 0x00000000 + + + DBG_TIM1_STOP + TIM1 counter stopped when core is + halted + 0 + 1 + + + DBG_TIM9_STOP + TIM9 counter stopped when core is + halted + 16 + 1 + + + DBG_TIM10_STOP + TIM10 counter stopped when core is + halted + 17 + 1 + + + DBG_TIM11_STOP + TIM11 counter stopped when core is + halted + 18 + 1 + + + + + + + EXTI + External interrupt/event + controller + EXTI + 0x40013C00 + + 0x0 + 0x400 + registers + + + TAMP_STAMP + Tamper and TimeStamp interrupts through the + EXTI line + 2 + + + EXTI0 + EXTI Line0 interrupt + 6 + + + EXTI1 + EXTI Line1 interrupt + 7 + + + EXTI2 + EXTI Line2 interrupt + 8 + + + EXTI3 + EXTI Line3 interrupt + 9 + + + EXTI4 + EXTI Line4 interrupt + 10 + + + EXTI9_5 + EXTI Line[9:5] interrupts + 23 + + + EXTI15_10 + EXTI Line[15:10] interrupts + 40 + + + + IMR + IMR + Interrupt mask register + (EXTI_IMR) + 0x0 + 0x20 + read-write + 0x00000000 + + + MR0 + Interrupt Mask on line 0 + 0 + 1 + + MR0 + read-write + + Masked + Interrupt request line is masked + 0 + + + Unmasked + Interrupt request line is unmasked + 1 + + + + + MR1 + Interrupt Mask on line 1 + 1 + 1 + + + + MR2 + Interrupt Mask on line 2 + 2 + 1 + + + + MR3 + Interrupt Mask on line 3 + 3 + 1 + + + + MR4 + Interrupt Mask on line 4 + 4 + 1 + + + + MR5 + Interrupt Mask on line 5 + 5 + 1 + + + + MR6 + Interrupt Mask on line 6 + 6 + 1 + + + + MR7 + Interrupt Mask on line 7 + 7 + 1 + + + + MR8 + Interrupt Mask on line 8 + 8 + 1 + + + + MR9 + Interrupt Mask on line 9 + 9 + 1 + + + + MR10 + Interrupt Mask on line 10 + 10 + 1 + + + + MR11 + Interrupt Mask on line 11 + 11 + 1 + + + + MR12 + Interrupt Mask on line 12 + 12 + 1 + + + + MR13 + Interrupt Mask on line 13 + 13 + 1 + + + + MR14 + Interrupt Mask on line 14 + 14 + 1 + + + + MR15 + Interrupt Mask on line 15 + 15 + 1 + + + + MR16 + Interrupt Mask on line 16 + 16 + 1 + + + + MR17 + Interrupt Mask on line 17 + 17 + 1 + + + + MR18 + Interrupt Mask on line 18 + 18 + 1 + + + + MR19 + Interrupt Mask on line 19 + 19 + 1 + + + + MR20 + Interrupt Mask on line 20 + 20 + 1 + + + + MR21 + Interrupt Mask on line 21 + 21 + 1 + + + + MR22 + Interrupt Mask on line 22 + 22 + 1 + + + + + + EMR + EMR + Event mask register (EXTI_EMR) + 0x4 + 0x20 + read-write + 0x00000000 + + + MR0 + Event Mask on line 0 + 0 + 1 + + MR0 + read-write + + Masked + Interrupt request line is masked + 0 + + + Unmasked + Interrupt request line is unmasked + 1 + + + + + MR1 + Event Mask on line 1 + 1 + 1 + + + + MR2 + Event Mask on line 2 + 2 + 1 + + + + MR3 + Event Mask on line 3 + 3 + 1 + + + + MR4 + Event Mask on line 4 + 4 + 1 + + + + MR5 + Event Mask on line 5 + 5 + 1 + + + + MR6 + Event Mask on line 6 + 6 + 1 + + + + MR7 + Event Mask on line 7 + 7 + 1 + + + + MR8 + Event Mask on line 8 + 8 + 1 + + + + MR9 + Event Mask on line 9 + 9 + 1 + + + + MR10 + Event Mask on line 10 + 10 + 1 + + + + MR11 + Event Mask on line 11 + 11 + 1 + + + + MR12 + Event Mask on line 12 + 12 + 1 + + + + MR13 + Event Mask on line 13 + 13 + 1 + + + + MR14 + Event Mask on line 14 + 14 + 1 + + + + MR15 + Event Mask on line 15 + 15 + 1 + + + + MR16 + Event Mask on line 16 + 16 + 1 + + + + MR17 + Event Mask on line 17 + 17 + 1 + + + + MR18 + Event Mask on line 18 + 18 + 1 + + + + MR19 + Event Mask on line 19 + 19 + 1 + + + + MR20 + Event Mask on line 20 + 20 + 1 + + + + MR21 + Event Mask on line 21 + 21 + 1 + + + + MR22 + Event Mask on line 22 + 22 + 1 + + + + + + RTSR + RTSR + Rising Trigger selection register + (EXTI_RTSR) + 0x8 + 0x20 + read-write + 0x00000000 + + + TR0 + Rising trigger event configuration of + line 0 + 0 + 1 + + TR0 + read-write + + Disabled + Rising edge trigger is disabled + 0 + + + Enabled + Rising edge trigger is enabled + 1 + + + + + TR1 + Rising trigger event configuration of + line 1 + 1 + 1 + + + + TR2 + Rising trigger event configuration of + line 2 + 2 + 1 + + + + TR3 + Rising trigger event configuration of + line 3 + 3 + 1 + + + + TR4 + Rising trigger event configuration of + line 4 + 4 + 1 + + + + TR5 + Rising trigger event configuration of + line 5 + 5 + 1 + + + + TR6 + Rising trigger event configuration of + line 6 + 6 + 1 + + + + TR7 + Rising trigger event configuration of + line 7 + 7 + 1 + + + + TR8 + Rising trigger event configuration of + line 8 + 8 + 1 + + + + TR9 + Rising trigger event configuration of + line 9 + 9 + 1 + + + + TR10 + Rising trigger event configuration of + line 10 + 10 + 1 + + + + TR11 + Rising trigger event configuration of + line 11 + 11 + 1 + + + + TR12 + Rising trigger event configuration of + line 12 + 12 + 1 + + + + TR13 + Rising trigger event configuration of + line 13 + 13 + 1 + + + + TR14 + Rising trigger event configuration of + line 14 + 14 + 1 + + + + TR15 + Rising trigger event configuration of + line 15 + 15 + 1 + + + + TR16 + Rising trigger event configuration of + line 16 + 16 + 1 + + + + TR17 + Rising trigger event configuration of + line 17 + 17 + 1 + + + + TR18 + Rising trigger event configuration of + line 18 + 18 + 1 + + + + TR19 + Rising trigger event configuration of + line 19 + 19 + 1 + + + + TR20 + Rising trigger event configuration of + line 20 + 20 + 1 + + + + TR21 + Rising trigger event configuration of + line 21 + 21 + 1 + + + + TR22 + Rising trigger event configuration of + line 22 + 22 + 1 + + + + + + FTSR + FTSR + Falling Trigger selection register + (EXTI_FTSR) + 0xC + 0x20 + read-write + 0x00000000 + + + TR0 + Falling trigger event configuration of + line 0 + 0 + 1 + + TR0 + read-write + + Disabled + Falling edge trigger is disabled + 0 + + + Enabled + Falling edge trigger is enabled + 1 + + + + + TR1 + Falling trigger event configuration of + line 1 + 1 + 1 + + + + TR2 + Falling trigger event configuration of + line 2 + 2 + 1 + + + + TR3 + Falling trigger event configuration of + line 3 + 3 + 1 + + + + TR4 + Falling trigger event configuration of + line 4 + 4 + 1 + + + + TR5 + Falling trigger event configuration of + line 5 + 5 + 1 + + + + TR6 + Falling trigger event configuration of + line 6 + 6 + 1 + + + + TR7 + Falling trigger event configuration of + line 7 + 7 + 1 + + + + TR8 + Falling trigger event configuration of + line 8 + 8 + 1 + + + + TR9 + Falling trigger event configuration of + line 9 + 9 + 1 + + + + TR10 + Falling trigger event configuration of + line 10 + 10 + 1 + + + + TR11 + Falling trigger event configuration of + line 11 + 11 + 1 + + + + TR12 + Falling trigger event configuration of + line 12 + 12 + 1 + + + + TR13 + Falling trigger event configuration of + line 13 + 13 + 1 + + + + TR14 + Falling trigger event configuration of + line 14 + 14 + 1 + + + + TR15 + Falling trigger event configuration of + line 15 + 15 + 1 + + + + TR16 + Falling trigger event configuration of + line 16 + 16 + 1 + + + + TR17 + Falling trigger event configuration of + line 17 + 17 + 1 + + + + TR18 + Falling trigger event configuration of + line 18 + 18 + 1 + + + + TR19 + Falling trigger event configuration of + line 19 + 19 + 1 + + + + TR20 + Falling trigger event configuration of + line 20 + 20 + 1 + + + + TR21 + Falling trigger event configuration of + line 21 + 21 + 1 + + + + TR22 + Falling trigger event configuration of + line 22 + 22 + 1 + + + + + + SWIER + SWIER + Software interrupt event register + (EXTI_SWIER) + 0x10 + 0x20 + read-write + 0x00000000 + + + SWIER0 + Software Interrupt on line + 0 + 0 + 1 + + SWIER0W + write + + Pend + Generates an interrupt request + 1 + + + + + SWIER1 + Software Interrupt on line + 1 + 1 + 1 + + + + SWIER2 + Software Interrupt on line + 2 + 2 + 1 + + + + SWIER3 + Software Interrupt on line + 3 + 3 + 1 + + + + SWIER4 + Software Interrupt on line + 4 + 4 + 1 + + + + SWIER5 + Software Interrupt on line + 5 + 5 + 1 + + + + SWIER6 + Software Interrupt on line + 6 + 6 + 1 + + + + SWIER7 + Software Interrupt on line + 7 + 7 + 1 + + + + SWIER8 + Software Interrupt on line + 8 + 8 + 1 + + + + SWIER9 + Software Interrupt on line + 9 + 9 + 1 + + + + SWIER10 + Software Interrupt on line + 10 + 10 + 1 + + + + SWIER11 + Software Interrupt on line + 11 + 11 + 1 + + + + SWIER12 + Software Interrupt on line + 12 + 12 + 1 + + + + SWIER13 + Software Interrupt on line + 13 + 13 + 1 + + + + SWIER14 + Software Interrupt on line + 14 + 14 + 1 + + + + SWIER15 + Software Interrupt on line + 15 + 15 + 1 + + + + SWIER16 + Software Interrupt on line + 16 + 16 + 1 + + + + SWIER17 + Software Interrupt on line + 17 + 17 + 1 + + + + SWIER18 + Software Interrupt on line + 18 + 18 + 1 + + + + SWIER19 + Software Interrupt on line + 19 + 19 + 1 + + + + SWIER20 + Software Interrupt on line + 20 + 20 + 1 + + + + SWIER21 + Software Interrupt on line + 21 + 21 + 1 + + + + SWIER22 + Software Interrupt on line + 22 + 22 + 1 + + + + + + PR + PR + Pending register (EXTI_PR) + 0x14 + 0x20 + read-write + 0x00000000 + + + PR0 + Pending bit 0 + 0 + 1 + oneToClear + + PR0R + read + + NotPending + No trigger request occurred + 0 + + + Pending + Selected trigger request occurred + 1 + + + + PR0W + write + + Clear + Clears pending bit + 1 + + + + + PR1 + Pending bit 1 + 1 + 1 + oneToClear + + read + + + write + + + + PR2 + Pending bit 2 + 2 + 1 + oneToClear + + read + + + write + + + + PR3 + Pending bit 3 + 3 + 1 + oneToClear + + read + + + write + + + + PR4 + Pending bit 4 + 4 + 1 + oneToClear + + read + + + write + + + + PR5 + Pending bit 5 + 5 + 1 + oneToClear + + read + + + write + + + + PR6 + Pending bit 6 + 6 + 1 + oneToClear + + read + + + write + + + + PR7 + Pending bit 7 + 7 + 1 + oneToClear + + read + + + write + + + + PR8 + Pending bit 8 + 8 + 1 + oneToClear + + read + + + write + + + + PR9 + Pending bit 9 + 9 + 1 + oneToClear + + read + + + write + + + + PR10 + Pending bit 10 + 10 + 1 + oneToClear + + read + + + write + + + + PR11 + Pending bit 11 + 11 + 1 + oneToClear + + read + + + write + + + + PR12 + Pending bit 12 + 12 + 1 + oneToClear + + read + + + write + + + + PR13 + Pending bit 13 + 13 + 1 + oneToClear + + read + + + write + + + + PR14 + Pending bit 14 + 14 + 1 + oneToClear + + read + + + write + + + + PR15 + Pending bit 15 + 15 + 1 + oneToClear + + read + + + write + + + + PR16 + Pending bit 16 + 16 + 1 + oneToClear + + read + + + write + + + + PR17 + Pending bit 17 + 17 + 1 + oneToClear + + read + + + write + + + + PR18 + Pending bit 18 + 18 + 1 + oneToClear + + read + + + write + + + + PR19 + Pending bit 19 + 19 + 1 + oneToClear + + read + + + write + + + + PR20 + Pending bit 20 + 20 + 1 + oneToClear + + read + + + write + + + + PR21 + Pending bit 21 + 21 + 1 + oneToClear + + read + + + write + + + + PR22 + Pending bit 22 + 22 + 1 + oneToClear + + read + + + write + + + + + + + + FLASH + FLASH + FLASH + 0x40023C00 + + 0x0 + 0x400 + registers + + + FLASH + FLASH global interrupt + 4 + + + + ACR + ACR + Flash access control register + 0x0 + 0x20 + 0x00000000 + + + LATENCY + Latency + 0 + 4 + read-write + + LATENCY + read-write + + WS0 + 0 wait states + 0 + + + WS1 + 1 wait states + 1 + + + WS2 + 2 wait states + 2 + + + WS3 + 3 wait states + 3 + + + WS4 + 4 wait states + 4 + + + WS5 + 5 wait states + 5 + + + WS6 + 6 wait states + 6 + + + WS7 + 7 wait states + 7 + + + WS8 + 8 wait states + 8 + + + WS9 + 9 wait states + 9 + + + WS10 + 10 wait states + 10 + + + WS11 + 11 wait states + 11 + + + WS12 + 12 wait states + 12 + + + WS13 + 13 wait states + 13 + + + WS14 + 14 wait states + 14 + + + WS15 + 15 wait states + 15 + + + + + PRFTEN + Prefetch enable + 8 + 1 + read-write + + PRFTEN + read-write + + Disabled + Prefetch is disabled + 0 + + + Enabled + Prefetch is enabled + 1 + + + + + ICEN + Instruction cache enable + 9 + 1 + read-write + + ICEN + read-write + + Disabled + Instruction cache is disabled + 0 + + + Enabled + Instruction cache is enabled + 1 + + + + + DCEN + Data cache enable + 10 + 1 + read-write + + DCEN + read-write + + Disabled + Data cache is disabled + 0 + + + Enabled + Data cache is enabled + 1 + + + + + ICRST + Instruction cache reset + 11 + 1 + write-only + + ICRST + write + + NotReset + Instruction cache is not reset + 0 + + + Reset + Instruction cache is reset + 1 + + + + + DCRST + Data cache reset + 12 + 1 + read-write + + DCRST + read-write + + NotReset + Data cache is not reset + 0 + + + Reset + Data cache is reset + 1 + + + + + + + KEYR + KEYR + Flash key register + 0x4 + 0x20 + write-only + 0x00000000 + + + KEY + FPEC key + 0 + 32 + + + 0 + 4294967295 + + + + + + + OPTKEYR + OPTKEYR + Flash option key register + 0x8 + 0x20 + write-only + 0x00000000 + + + OPTKEY + Option byte key + 0 + 32 + + + 0 + 4294967295 + + + + + + + SR + SR + Status register + 0xC + 0x20 + 0x00000000 + + + EOP + End of operation + 0 + 1 + read-write + oneToClear + + EOPW + write + + Clear + Clear error flag + 1 + + + + + OPERR + Operation error + 1 + 1 + read-write + oneToClear + + OPERRW + write + + Clear + Clear error flag + 1 + + + + + WRPERR + Write protection error + 4 + 1 + read-write + oneToClear + + WRPERRW + write + + Clear + Clear error flag + 1 + + + + + PGAERR + Programming alignment + error + 5 + 1 + read-write + oneToClear + + PGAERRW + write + + Clear + Clear error flag + 1 + + + + + PGPERR + Programming parallelism + error + 6 + 1 + read-write + oneToClear + + PGPERRW + write + + Clear + Clear error flag + 1 + + + + + PGSERR + Programming sequence error + 7 + 1 + read-write + oneToClear + + PGSERRW + write + + Clear + Clear error flag + 1 + + + + + BSY + Busy + 16 + 1 + read-only + + BSYR + read + + NotBusy + no Flash memory operation ongoing + 0 + + + Busy + Flash memory operation ongoing + 1 + + + + + + + CR + CR + Control register + 0x10 + 0x20 + read-write + 0x80000000 + + + PG + Programming + 0 + 1 + + PG + read-write + + Program + Flash programming activated + 1 + + + + + SER + Sector Erase + 1 + 1 + + SER + read-write + + SectorErase + Erase activated for selected sector + 1 + + + + + MER + Mass Erase + 2 + 1 + + MER + read-write + + MassErase + Erase activated for all user sectors + 1 + + + + + SNB + Sector number + 3 + 4 + + + 0 + 11 + + + + + PSIZE + Program size + 8 + 2 + + PSIZE + read-write + + PSIZE8 + Program x8 + 0 + + + PSIZE16 + Program x16 + 1 + + + PSIZE32 + Program x32 + 2 + + + PSIZE64 + Program x64 + 3 + + + + + STRT + Start + 16 + 1 + + STRT + read-write + + Start + Trigger an erase operation + 1 + + + + + EOPIE + End of operation interrupt + enable + 24 + 1 + + EOPIE + read-write + + Disabled + End of operation interrupt disabled + 0 + + + Enabled + End of operation interrupt enabled + 1 + + + + + ERRIE + Error interrupt enable + 25 + 1 + + ERRIE + read-write + + Disabled + Error interrupt generation disabled + 0 + + + Enabled + Error interrupt generation enabled + 1 + + + + + LOCK + Lock + 31 + 1 + + LOCK + read-write + + Unlocked + FLASH_CR register is unlocked + 0 + + + Locked + FLASH_CR register is locked + 1 + + + + + + + OPTCR + OPTCR + Flash option control register + 0x14 + 0x20 + read-write + 0x00000014 + + + OPTLOCK + Option lock + 0 + 1 + + + OPTSTRT + Option start + 1 + 1 + + + BOR_LEV + BOR reset Level + 2 + 2 + + + WDG_SW + WDG_SW User option bytes + 5 + 1 + + + nRST_STOP + nRST_STOP User option + bytes + 6 + 1 + + + nRST_STDBY + nRST_STDBY User option + bytes + 7 + 1 + + + RDP + Read protect + 8 + 8 + + + nWRP + Not write protect + 16 + 12 + + + + + + + IWDG + Independent watchdog + IWDG + 0x40003000 + + 0x0 + 0x400 + registers + + + + KR + KR + Key register + 0x0 + 0x20 + write-only + 0x00000000 + + + KEY + Key value + 0 + 16 + + KEY + write + + Enable + Enable access to PR, RLR and WINR registers (0x5555) + 21845 + + + Reset + Reset the watchdog value (0xAAAA) + 43690 + + + Start + Start the watchdog (0xCCCC) + 52428 + + + + + + + PR + PR + Prescaler register + 0x4 + 0x20 + read-write + 0x00000000 + + + PR + Prescaler divider + 0 + 3 + + PR + read-write + + DivideBy4 + Divider /4 + 0 + + + DivideBy8 + Divider /8 + 1 + + + DivideBy16 + Divider /16 + 2 + + + DivideBy32 + Divider /32 + 3 + + + DivideBy64 + Divider /64 + 4 + + + DivideBy128 + Divider /128 + 5 + + + DivideBy256 + Divider /256 + 6 + + + DivideBy256bis + Divider /256 + 7 + + + + + + + RLR + RLR + Reload register + 0x8 + 0x20 + read-write + 0x00000FFF + + + RL + Watchdog counter reload + value + 0 + 12 + + + 0 + 4095 + + + + + + + SR + SR + Status register + 0xC + 0x20 + read-only + 0x00000000 + + + RVU + Watchdog counter reload value + update + 1 + 1 + + + PVU + Watchdog prescaler value + update + 0 + 1 + + + + + + + OTG_FS_DEVICE + USB on the go full speed + USB_OTG_FS + 0x50000800 + + 0x0 + 0x400 + registers + + + + DCFG + DCFG + OTG_FS device configuration register + (OTG_FS_DCFG) + 0x0 + 0x20 + read-write + 0x02200000 + + + DSPD + Device speed + 0 + 2 + + + NZLSOHSK + Non-zero-length status OUT + handshake + 2 + 1 + + + DAD + Device address + 4 + 7 + + + PFIVL + Periodic frame interval + 11 + 2 + + + + + DCTL + DCTL + OTG_FS device control register + (OTG_FS_DCTL) + 0x4 + 0x20 + 0x00000000 + + + RWUSIG + Remote wakeup signaling + 0 + 1 + read-write + + + SDIS + Soft disconnect + 1 + 1 + read-write + + + GINSTS + Global IN NAK status + 2 + 1 + read-only + + + GONSTS + Global OUT NAK status + 3 + 1 + read-only + + + TCTL + Test control + 4 + 3 + read-write + + + SGINAK + Set global IN NAK + 7 + 1 + read-write + + + CGINAK + Clear global IN NAK + 8 + 1 + read-write + + + SGONAK + Set global OUT NAK + 9 + 1 + read-write + + + CGONAK + Clear global OUT NAK + 10 + 1 + read-write + + + POPRGDNE + Power-on programming done + 11 + 1 + read-write + + + + + DSTS + DSTS + OTG_FS device status register + (OTG_FS_DSTS) + 0x8 + 0x20 + read-only + 0x00000010 + + + SUSPSTS + Suspend status + 0 + 1 + + + ENUMSPD + Enumerated speed + 1 + 2 + + + EERR + Erratic error + 3 + 1 + + + FNSOF + Frame number of the received + SOF + 8 + 14 + + + + + DIEPMSK + DIEPMSK + OTG_FS device IN endpoint common interrupt + mask register (OTG_FS_DIEPMSK) + 0x10 + 0x20 + read-write + 0x00000000 + + + XFRCM + Transfer completed interrupt + mask + 0 + 1 + + + EPDM + Endpoint disabled interrupt + mask + 1 + 1 + + + TOM + Timeout condition mask (Non-isochronous + endpoints) + 3 + 1 + + + ITTXFEMSK + IN token received when TxFIFO empty + mask + 4 + 1 + + + INEPNMM + IN token received with EP mismatch + mask + 5 + 1 + + + INEPNEM + IN endpoint NAK effective + mask + 6 + 1 + + + + + DOEPMSK + DOEPMSK + OTG_FS device OUT endpoint common interrupt + mask register (OTG_FS_DOEPMSK) + 0x14 + 0x20 + read-write + 0x00000000 + + + XFRCM + Transfer completed interrupt + mask + 0 + 1 + + + EPDM + Endpoint disabled interrupt + mask + 1 + 1 + + + STUPM + SETUP phase done mask + 3 + 1 + + + OTEPDM + OUT token received when endpoint + disabled mask + 4 + 1 + + + + + DAINT + DAINT + OTG_FS device all endpoints interrupt + register (OTG_FS_DAINT) + 0x18 + 0x20 + read-only + 0x00000000 + + + IEPINT + IN endpoint interrupt bits + 0 + 16 + + + OEPINT + OUT endpoint interrupt + bits + 16 + 16 + + + + + DAINTMSK + DAINTMSK + OTG_FS all endpoints interrupt mask register + (OTG_FS_DAINTMSK) + 0x1C + 0x20 + read-write + 0x00000000 + + + IEPM + IN EP interrupt mask bits + 0 + 16 + + + OEPM + OUT EP interrupt mask bits + 16 + 16 + + + + + DVBUSDIS + DVBUSDIS + OTG_FS device VBUS discharge time + register + 0x28 + 0x20 + read-write + 0x000017D7 + + + VBUSDT + Device VBUS discharge time + 0 + 16 + + + + + DVBUSPULSE + DVBUSPULSE + OTG_FS device VBUS pulsing time + register + 0x2C + 0x20 + read-write + 0x000005B8 + + + DVBUSP + Device VBUS pulsing time + 0 + 12 + + + + + DIEPEMPMSK + DIEPEMPMSK + OTG_FS device IN endpoint FIFO empty + interrupt mask register + 0x34 + 0x20 + read-write + 0x00000000 + + + INEPTXFEM + IN EP Tx FIFO empty interrupt mask + bits + 0 + 16 + + + + + DIEP0 + Device IN endpoint 0 + 0x100 + + CTL + DIEPCTL0 + OTG_FS device control IN endpoint 0 control + register (OTG_FS_DIEPCTL0) + 0x0 + 0x20 + 0x00000000 + + + MPSIZ + Maximum packet size + 0 + 2 + read-write + + + USBAEP + USB active endpoint + 15 + 1 + read-only + + + NAKSTS + NAK status + 17 + 1 + read-only + + + EPTYP + Endpoint type + 18 + 2 + read-only + + + STALL + STALL handshake + 21 + 1 + read-write + + + TXFNUM + TxFIFO number + 22 + 4 + read-write + + + CNAK + Clear NAK + 26 + 1 + write-only + + + SNAK + Set NAK + 27 + 1 + write-only + + + EPDIS + Endpoint disable + 30 + 1 + read-only + + + EPENA + Endpoint enable + 31 + 1 + read-write + + + + + INT + DIEPINT0 + device endpoint-x interrupt + register + 0x8 + 0x20 + 0x00000080 + + + TXFE + TXFE + 7 + 1 + read-only + + + INEPNE + INEPNE + 6 + 1 + read-write + + + ITTXFE + ITTXFE + 4 + 1 + read-write + + + TOC + TOC + 3 + 1 + read-write + + + EPDISD + EPDISD + 1 + 1 + read-write + + + XFRC + XFRC + 0 + 1 + read-write + + + + + TSIZ + DIEPTSIZ0 + device endpoint-0 transfer size + register + 0x10 + 0x20 + read-write + 0x00000000 + + + PKTCNT + Packet count + 19 + 2 + + + XFRSIZ + Transfer size + 0 + 7 + + + + + TXFSTS + DTXFSTS0 + OTG_FS device IN endpoint transmit FIFO + status register + 0x18 + 0x20 + read-only + 0x00000000 + + + INEPTFSAV + IN endpoint TxFIFO space + available + 0 + 16 + + + + + + 3 + 0x20 + 1-3 + DIEP%s + Device IN endpoint X + 0x120 + + CTL + DIEPCTL1 + OTG device endpoint-1 control + register + 0x0 + 0x20 + 0x00000000 + + + EPENA + EPENA + 31 + 1 + read-write + + + EPDIS + EPDIS + 30 + 1 + read-write + + + SODDFRM_SD1PID + SODDFRM/SD1PID + 29 + 1 + write-only + + + SD0PID_SEVNFRM + SD0PID/SEVNFRM + 28 + 1 + write-only + + + SNAK + SNAK + 27 + 1 + write-only + + + CNAK + CNAK + 26 + 1 + write-only + + + TXFNUM + TXFNUM + 22 + 4 + read-write + + + STALL + STALL handshake + 21 + 1 + read-write + + + EPTYP + EPTYP + 18 + 2 + read-write + + + NAKSTS + NAKSTS + 17 + 1 + read-only + + + EONUM_DPID + EONUM/DPID + 16 + 1 + read-only + + + USBAEP + USBAEP + 15 + 1 + read-write + + + MPSIZ + MPSIZ + 0 + 11 + read-write + + + + + INT + DIEPINT1 + device endpoint-1 interrupt + register + 0x8 + 0x20 + 0x00000080 + + + TXFE + TXFE + 7 + 1 + read-only + + + INEPNE + INEPNE + 6 + 1 + read-write + + + ITTXFE + ITTXFE + 4 + 1 + read-write + + + TOC + TOC + 3 + 1 + read-write + + + EPDISD + EPDISD + 1 + 1 + read-write + + + XFRC + XFRC + 0 + 1 + read-write + + + + + TSIZ + DIEPTSIZ1 + device endpoint-1 transfer size + register + 0x10 + 0x20 + read-write + 0x00000000 + + + MCNT + Multi count + 29 + 2 + + + PKTCNT + Packet count + 19 + 10 + + + XFRSIZ + Transfer size + 0 + 19 + + + + + TXFSTS + DTXFSTS1 + OTG_FS device IN endpoint transmit FIFO + status register + 0x18 + 0x20 + read-only + 0x00000000 + + + INEPTFSAV + IN endpoint TxFIFO space + available + 0 + 16 + + + + + + DOEP0 + Device OUT endpoint 0 + 0x300 + + CTL + DOEPCTL0 + device endpoint-0 control + register + 0x0 + 0x20 + 0x00008000 + + + EPENA + EPENA + 31 + 1 + read-write + + + EPDIS + EPDIS + 30 + 1 + read-only + + + SNAK + SNAK + 27 + 1 + write-only + + + CNAK + CNAK + 26 + 1 + write-only + + + STALL + STALL handshake + 21 + 1 + read-write + + + SNPM + SNPM + 20 + 1 + read-write + + + EPTYP + EPTYP + 18 + 2 + read-only + + + NAKSTS + NAKSTS + 17 + 1 + read-only + + + USBAEP + USBAEP + 15 + 1 + read-only + + + MPSIZ + MPSIZ + 0 + 2 + read-only + + + + + INT + DOEPINT0 + device endpoint-0 interrupt + register + 0x8 + 0x20 + read-write + 0x00000080 + + + B2BSTUP + B2BSTUP + 6 + 1 + + + OTEPDIS + OTEPDIS + 4 + 1 + + + STUP + STUP + 3 + 1 + + + EPDISD + EPDISD + 1 + 1 + + + XFRC + XFRC + 0 + 1 + + + + + TSIZ + DOEPTSIZ0 + device OUT endpoint-0 transfer size + register + 0x10 + 0x20 + read-write + 0x00000000 + + + STUPCNT + SETUP packet count + 29 + 2 + + + PKTCNT + Packet count + 19 + 1 + + + XFRSIZ + Transfer size + 0 + 7 + + + + + + 3 + 0x20 + 1-3 + DOEP%s + Device IN endpoint X + 0x320 + + CTL + DOEPCTL1 + device endpoint-1 control + register + 0x0 + 0x20 + 0x00000000 + + + EPENA + EPENA + 31 + 1 + read-write + + + EPDIS + EPDIS + 30 + 1 + read-write + + + SODDFRM + SODDFRM + 29 + 1 + write-only + + + SD0PID_SEVNFRM + SD0PID/SEVNFRM + 28 + 1 + write-only + + + SNAK + SNAK + 27 + 1 + write-only + + + CNAK + CNAK + 26 + 1 + write-only + + + STALL + STALL handshake + 21 + 1 + read-write + + + SNPM + SNPM + 20 + 1 + read-write + + + EPTYP + EPTYP + 18 + 2 + read-write + + + NAKSTS + NAKSTS + 17 + 1 + read-only + + + EONUM_DPID + EONUM/DPID + 16 + 1 + read-only + + + USBAEP + USBAEP + 15 + 1 + read-write + + + MPSIZ + MPSIZ + 0 + 11 + read-write + + + + + INT + DOEPINT1 + device endpoint-1 interrupt + register + 0x8 + 0x20 + read-write + 0x00000080 + + + B2BSTUP + B2BSTUP + 6 + 1 + + + OTEPDIS + OTEPDIS + 4 + 1 + + + STUP + STUP + 3 + 1 + + + EPDISD + EPDISD + 1 + 1 + + + XFRC + XFRC + 0 + 1 + + + + + TSIZ + DOEPTSIZ1 + device OUT endpoint-1 transfer size + register + 0x10 + 0x20 + read-write + 0x00000000 + + + RXDPID_STUPCNT + Received data PID/SETUP packet + count + 29 + 2 + + + PKTCNT + Packet count + 19 + 10 + + + XFRSIZ + Transfer size + 0 + 19 + + + + + + + + OTG_FS_GLOBAL + USB on the go full speed + USB_OTG_FS + 0x50000000 + + 0x0 + 0x400 + registers + + + + GOTGCTL + GOTGCTL + OTG_FS control and status register + (OTG_FS_GOTGCTL) + 0x0 + 0x20 + 0x00000800 + + + SRQSCS + Session request success + 0 + 1 + read-only + + + SRQ + Session request + 1 + 1 + read-write + + + HNGSCS + Host negotiation success + 8 + 1 + read-only + + + HNPRQ + HNP request + 9 + 1 + read-write + + + HSHNPEN + Host set HNP enable + 10 + 1 + read-write + + + DHNPEN + Device HNP enabled + 11 + 1 + read-write + + + CIDSTS + Connector ID status + 16 + 1 + read-only + + + DBCT + Long/short debounce time + 17 + 1 + read-only + + + ASVLD + A-session valid + 18 + 1 + read-only + + + BSVLD + B-session valid + 19 + 1 + read-only + + + + + GOTGINT + GOTGINT + OTG_FS interrupt register + (OTG_FS_GOTGINT) + 0x4 + 0x20 + read-write + 0x00000000 + + + SEDET + Session end detected + 2 + 1 + + + SRSSCHG + Session request success status + change + 8 + 1 + + + HNSSCHG + Host negotiation success status + change + 9 + 1 + + + HNGDET + Host negotiation detected + 17 + 1 + + + ADTOCHG + A-device timeout change + 18 + 1 + + + DBCDNE + Debounce done + 19 + 1 + + + + + GAHBCFG + GAHBCFG + OTG_FS AHB configuration register + (OTG_FS_GAHBCFG) + 0x8 + 0x20 + read-write + 0x00000000 + + + GINT + Global interrupt mask + 0 + 1 + + + TXFELVL + TxFIFO empty level + 7 + 1 + + + PTXFELVL + Periodic TxFIFO empty + level + 8 + 1 + + + + + GUSBCFG + GUSBCFG + OTG_FS USB configuration register + (OTG_FS_GUSBCFG) + 0xC + 0x20 + 0x00000A00 + + + TOCAL + FS timeout calibration + 0 + 3 + read-write + + + PHYSEL + Full Speed serial transceiver + select + 6 + 1 + write-only + + + SRPCAP + SRP-capable + 8 + 1 + read-write + + + HNPCAP + HNP-capable + 9 + 1 + read-write + + + TRDT + USB turnaround time + 10 + 4 + read-write + + + FHMOD + Force host mode + 29 + 1 + read-write + + + FDMOD + Force device mode + 30 + 1 + read-write + + + CTXPKT + Corrupt Tx packet + 31 + 1 + read-write + + + + + GRSTCTL + GRSTCTL + OTG_FS reset register + (OTG_FS_GRSTCTL) + 0x10 + 0x20 + 0x20000000 + + + CSRST + Core soft reset + 0 + 1 + read-write + + + HSRST + HCLK soft reset + 1 + 1 + read-write + + + FCRST + Host frame counter reset + 2 + 1 + read-write + + + RXFFLSH + RxFIFO flush + 4 + 1 + read-write + + + TXFFLSH + TxFIFO flush + 5 + 1 + read-write + + + TXFNUM + TxFIFO number + 6 + 5 + read-write + + + AHBIDL + AHB master idle + 31 + 1 + read-only + + + + + GINTSTS + GINTSTS + OTG_FS core interrupt register + (OTG_FS_GINTSTS) + 0x14 + 0x20 + 0x04000020 + + + CMOD + Current mode of operation + 0 + 1 + read-only + + + MMIS + Mode mismatch interrupt + 1 + 1 + read-write + + + OTGINT + OTG interrupt + 2 + 1 + read-only + + + SOF + Start of frame + 3 + 1 + read-write + + + RXFLVL + RxFIFO non-empty + 4 + 1 + read-only + + + NPTXFE + Non-periodic TxFIFO empty + 5 + 1 + read-only + + + GINAKEFF + Global IN non-periodic NAK + effective + 6 + 1 + read-only + + + GOUTNAKEFF + Global OUT NAK effective + 7 + 1 + read-only + + + ESUSP + Early suspend + 10 + 1 + read-write + + + USBSUSP + USB suspend + 11 + 1 + read-write + + + USBRST + USB reset + 12 + 1 + read-write + + + ENUMDNE + Enumeration done + 13 + 1 + read-write + + + ISOODRP + Isochronous OUT packet dropped + interrupt + 14 + 1 + read-write + + + EOPF + End of periodic frame + interrupt + 15 + 1 + read-write + + + IEPINT + IN endpoint interrupt + 18 + 1 + read-only + + + OEPINT + OUT endpoint interrupt + 19 + 1 + read-only + + + IISOIXFR + Incomplete isochronous IN + transfer + 20 + 1 + read-write + + + IPXFR_INCOMPISOOUT + Incomplete periodic transfer(Host + mode)/Incomplete isochronous OUT transfer(Device + mode) + 21 + 1 + read-write + + + HPRTINT + Host port interrupt + 24 + 1 + read-only + + + HCINT + Host channels interrupt + 25 + 1 + read-only + + + PTXFE + Periodic TxFIFO empty + 26 + 1 + read-only + + + CIDSCHG + Connector ID status change + 28 + 1 + read-write + + + DISCINT + Disconnect detected + interrupt + 29 + 1 + read-write + + + SRQINT + Session request/new session detected + interrupt + 30 + 1 + read-write + + + WKUPINT + Resume/remote wakeup detected + interrupt + 31 + 1 + read-write + + + + + GINTMSK + GINTMSK + OTG_FS interrupt mask register + (OTG_FS_GINTMSK) + 0x18 + 0x20 + 0x00000000 + + + MMISM + Mode mismatch interrupt + mask + 1 + 1 + read-write + + + OTGINT + OTG interrupt mask + 2 + 1 + read-write + + + SOFM + Start of frame mask + 3 + 1 + read-write + + + RXFLVLM + Receive FIFO non-empty + mask + 4 + 1 + read-write + + + NPTXFEM + Non-periodic TxFIFO empty + mask + 5 + 1 + read-write + + + GINAKEFFM + Global non-periodic IN NAK effective + mask + 6 + 1 + read-write + + + GONAKEFFM + Global OUT NAK effective + mask + 7 + 1 + read-write + + + ESUSPM + Early suspend mask + 10 + 1 + read-write + + + USBSUSPM + USB suspend mask + 11 + 1 + read-write + + + USBRST + USB reset mask + 12 + 1 + read-write + + + ENUMDNEM + Enumeration done mask + 13 + 1 + read-write + + + ISOODRPM + Isochronous OUT packet dropped interrupt + mask + 14 + 1 + read-write + + + EOPFM + End of periodic frame interrupt + mask + 15 + 1 + read-write + + + EPMISM + Endpoint mismatch interrupt + mask + 17 + 1 + read-write + + + IEPINT + IN endpoints interrupt + mask + 18 + 1 + read-write + + + OEPINT + OUT endpoints interrupt + mask + 19 + 1 + read-write + + + IISOIXFRM + Incomplete isochronous IN transfer + mask + 20 + 1 + read-write + + + IPXFRM_IISOOXFRM + Incomplete periodic transfer mask(Host + mode)/Incomplete isochronous OUT transfer mask(Device + mode) + 21 + 1 + read-write + + + PRTIM + Host port interrupt mask + 24 + 1 + read-write + + + HCIM + Host channels interrupt + mask + 25 + 1 + read-write + + + PTXFEM + Periodic TxFIFO empty mask + 26 + 1 + read-write + + + CIDSCHGM + Connector ID status change + mask + 28 + 1 + read-write + + + DISCINT + Disconnect detected interrupt + mask + 29 + 1 + read-write + + + SRQIM + Session request/new session detected + interrupt mask + 30 + 1 + read-write + + + WUIM + Resume/remote wakeup detected interrupt + mask + 31 + 1 + read-write + + + + + GRXSTSR_Device + GRXSTSR_Device + OTG_FS Receive status debug read(Device + mode) + 0x1C + 0x20 + read-only + 0x00000000 + + + EPNUM + Endpoint number + 0 + 4 + + + BCNT + Byte count + 4 + 11 + + + DPID + Data PID + 15 + 2 + + + PKTSTS + Packet status + 17 + 4 + + + FRMNUM + Frame number + 21 + 4 + + + + + GRXSTSR_Host + GRXSTSR_Host + OTG status debug read (host mode) + GRXSTSR_Device + 0x1C + 0x20 + read-only + 0x00000000 + + + CHNUM + Channel number + 0 + 4 + + + BCNT + Byte count + 4 + 11 + + + DPID + Data PID + 15 + 2 + + + PKTSTS + Packet status + 17 + 4 + + + + + GRXFSIZ + GRXFSIZ + OTG_FS Receive FIFO size register + (OTG_FS_GRXFSIZ) + 0x24 + 0x20 + read-write + 0x00000200 + + + RXFD + RxFIFO depth + 0 + 16 + + + + + DIEPTXF0 + DIEPTXF0 + OTG_FS non-periodic transmit FIFO size + register (Device mode) + 0x28 + 0x20 + read-write + 0x00000200 + + + TX0FSA + Endpoint 0 transmit RAM start + address + 0 + 16 + + + TX0FD + Endpoint 0 TxFIFO depth + 16 + 16 + + + + + HNPTXFSIZ + HNPTXFSIZ + OTG_FS non-periodic transmit FIFO size + register (Host mode) + DIEPTXF0 + 0x28 + 0x20 + read-write + 0x00000200 + + + NPTXFSA + Non-periodic transmit RAM start + address + 0 + 16 + + + NPTXFD + Non-periodic TxFIFO depth + 16 + 16 + + + + + GNPTXSTS + GNPTXSTS + OTG_FS non-periodic transmit FIFO/queue + status register (OTG_FS_GNPTXSTS) + 0x2C + 0x20 + read-only + 0x00080200 + + + NPTXFSAV + Non-periodic TxFIFO space + available + 0 + 16 + + + NPTQXSAV + Non-periodic transmit request queue + space available + 16 + 8 + + + NPTXQTOP + Top of the non-periodic transmit request + queue + 24 + 7 + + + + + GCCFG + GCCFG + OTG_FS general core configuration register + (OTG_FS_GCCFG) + 0x38 + 0x20 + read-write + 0x00000000 + + + PWRDWN + Power down + 16 + 1 + + + VBUSASEN + Enable the VBUS sensing + device + 18 + 1 + + + VBUSBSEN + Enable the VBUS sensing + device + 19 + 1 + + + SOFOUTEN + SOF output enable + 20 + 1 + + + NOVBUSSENS + Vbus sensing disable option + 21 + 1 + + + + + CID + CID + core ID register + 0x3C + 0x20 + read-write + 0x00001000 + + + PRODUCT_ID + Product ID field + 0 + 32 + + + + + HPTXFSIZ + HPTXFSIZ + OTG_FS Host periodic transmit FIFO size + register (OTG_FS_HPTXFSIZ) + 0x100 + 0x20 + read-write + 0x02000600 + + + PTXSA + Host periodic TxFIFO start + address + 0 + 16 + + + PTXFSIZ + Host periodic TxFIFO depth + 16 + 16 + + + + + 3 + 0x4 + 1-3 + DIEPTXF%s + DIEPTXF1 + OTF_FS device IN endpoint transmit FIFO size register + 0x104 + 0x20 + read-write + 0x02000400 + + + INEPTXSA + IN endpoint FIFO2 transmit RAM start + address + 0 + 16 + + + INEPTXFD + IN endpoint TxFIFO depth + 16 + 16 + + + + + GRXSTSP_Device + OTG status read and pop (device mode) + 0x20 + 0x20 + read-only + 0x00000000 + + + FRMNUM + Frame number + 21 + 4 + + + PKTSTS + Packet status + 17 + 4 + + + DPID + Data PID + 15 + 2 + + + BCNT + Byte count + 4 + 11 + + + EPNUM + Endpoint number + 0 + 4 + + + + + GRXSTSP_Host + OTG status read and pop (host mode) + GRXSTSP_Device + 0x20 + 0x20 + read-only + 0x00000000 + + + PKTSTS + Packet status + 17 + 4 + + + DPID + Data PID + 15 + 2 + + + BCNT + Byte count + 4 + 11 + + + CHNUM + Channel number + 0 + 4 + + + + + + + OTG_FS_HOST + USB on the go full speed + USB_OTG_FS + 0x50000400 + + 0x0 + 0x400 + registers + + + + HCFG + HCFG + OTG_FS host configuration register + (OTG_FS_HCFG) + 0x0 + 0x20 + 0x00000000 + + + FSLSPCS + FS/LS PHY clock select + 0 + 2 + read-write + + + FSLSS + FS- and LS-only support + 2 + 1 + read-write + + + + + HFIR + HFIR + OTG_FS Host frame interval + register + 0x4 + 0x20 + read-write + 0x0000EA60 + + + FRIVL + Frame interval + 0 + 16 + + + + + HFNUM + HFNUM + OTG_FS host frame number/frame time + remaining register (OTG_FS_HFNUM) + 0x8 + 0x20 + read-only + 0x00003FFF + + + FRNUM + Frame number + 0 + 16 + + + FTREM + Frame time remaining + 16 + 16 + + + + + HPTXSTS + HPTXSTS + OTG_FS_Host periodic transmit FIFO/queue + status register (OTG_FS_HPTXSTS) + 0x10 + 0x20 + 0x00080100 + + + PTXFSAVL + Periodic transmit data FIFO space + available + 0 + 16 + read-write + + + PTXQSAV + Periodic transmit request queue space + available + 16 + 8 + read-only + + + PTXQTOP + Top of the periodic transmit request + queue + 24 + 8 + read-only + + + + + HAINT + HAINT + OTG_FS Host all channels interrupt + register + 0x14 + 0x20 + read-only + 0x00000000 + + + HAINT + Channel interrupts + 0 + 16 + + + + + HAINTMSK + HAINTMSK + OTG_FS host all channels interrupt mask + register + 0x18 + 0x20 + read-write + 0x00000000 + + + HAINTM + Channel interrupt mask + 0 + 16 + + + + + HPRT + HPRT + OTG_FS host port control and status register + (OTG_FS_HPRT) + 0x40 + 0x20 + 0x00000000 + + + PCSTS + Port connect status + 0 + 1 + read-only + + + PCDET + Port connect detected + 1 + 1 + read-write + + + PENA + Port enable + 2 + 1 + read-write + + + PENCHNG + Port enable/disable change + 3 + 1 + read-write + + + POCA + Port overcurrent active + 4 + 1 + read-only + + + POCCHNG + Port overcurrent change + 5 + 1 + read-write + + + PRES + Port resume + 6 + 1 + read-write + + + PSUSP + Port suspend + 7 + 1 + read-write + + + PRST + Port reset + 8 + 1 + read-write + + + PLSTS + Port line status + 10 + 2 + read-only + + + PPWR + Port power + 12 + 1 + read-write + + + PTCTL + Port test control + 13 + 4 + read-write + + + PSPD + Port speed + 17 + 2 + read-only + + + + + 8 + 0x20 + 0-7 + HC%s + Host channel + 0x100 + + CHAR + HCCHAR0 + OTG_FS host channel-0 characteristics + register (OTG_FS_HCCHAR0) + 0x0 + 0x20 + read-write + 0x00000000 + + + MPSIZ + Maximum packet size + 0 + 11 + + + EPNUM + Endpoint number + 11 + 4 + + + EPDIR + Endpoint direction + 15 + 1 + + + LSDEV + Low-speed device + 17 + 1 + + + EPTYP + Endpoint type + 18 + 2 + + + MCNT + Multicount + 20 + 2 + + + DAD + Device address + 22 + 7 + + + ODDFRM + Odd frame + 29 + 1 + + + CHDIS + Channel disable + 30 + 1 + + + CHENA + Channel enable + 31 + 1 + + + + + INT + HCINT0 + OTG_FS host channel-0 interrupt register + (OTG_FS_HCINT0) + 0x8 + 0x20 + read-write + 0x00000000 + + + XFRC + Transfer completed + 0 + 1 + + + CHH + Channel halted + 1 + 1 + + + STALL + STALL response received + interrupt + 3 + 1 + + + NAK + NAK response received + interrupt + 4 + 1 + + + ACK + ACK response received/transmitted + interrupt + 5 + 1 + + + TXERR + Transaction error + 7 + 1 + + + BBERR + Babble error + 8 + 1 + + + FRMOR + Frame overrun + 9 + 1 + + + DTERR + Data toggle error + 10 + 1 + + + + + INTMSK + HCINTMSK0 + OTG_FS host channel-0 mask register + (OTG_FS_HCINTMSK0) + 0xC + 0x20 + read-write + 0x00000000 + + + XFRCM + Transfer completed mask + 0 + 1 + + + CHHM + Channel halted mask + 1 + 1 + + + STALLM + STALL response received interrupt + mask + 3 + 1 + + + NAKM + NAK response received interrupt + mask + 4 + 1 + + + ACKM + ACK response received/transmitted + interrupt mask + 5 + 1 + + + NYET + response received interrupt + mask + 6 + 1 + + + TXERRM + Transaction error mask + 7 + 1 + + + BBERRM + Babble error mask + 8 + 1 + + + FRMORM + Frame overrun mask + 9 + 1 + + + DTERRM + Data toggle error mask + 10 + 1 + + + + + TSIZ + HCTSIZ0 + OTG_FS host channel-0 transfer size + register + 0x10 + 0x20 + read-write + 0x00000000 + + + XFRSIZ + Transfer size + 0 + 19 + + + PKTCNT + Packet count + 19 + 10 + + + DPID + Data PID + 29 + 2 + + + + + + + + OTG_FS_PWRCLK + USB on the go full speed + USB_OTG_FS + 0x50000E00 + + 0x0 + 0x400 + registers + + + + PCGCCTL + PCGCCTL + OTG_FS power and clock gating control + register + 0x0 + 0x20 + read-write + 0x00000000 + + + STPPCLK + Stop PHY clock + 0 + 1 + + + GATEHCLK + Gate HCLK + 1 + 1 + + + PHYSUSP + PHY Suspended + 4 + 1 + + + + + + + PWR + Power control + PWR + 0x40007000 + + 0x0 + 0x400 + registers + + + + CR + CR + power control register + 0x0 + 0x20 + read-write + 0x00000000 + + + VOS + Regulator voltage scaling output + selection + 14 + 2 + + + ADCDC1 + ADCDC1 + 13 + 1 + + + FPDS + Flash power down in Stop + mode + 9 + 1 + + + DBP + Disable backup domain write + protection + 8 + 1 + + + PLS + PVD level selection + 5 + 3 + + + PVDE + Power voltage detector + enable + 4 + 1 + + + CSBF + Clear standby flag + 3 + 1 + + + CWUF + Clear wakeup flag + 2 + 1 + + + PDDS + Power down deepsleep + 1 + 1 + + + LPDS + Low-power deep sleep + 0 + 1 + + + + + CSR + CSR + power control/status register + 0x4 + 0x20 + 0x00000000 + + + WUF + Wakeup flag + 0 + 1 + read-only + + + SBF + Standby flag + 1 + 1 + read-only + + + PVDO + PVD output + 2 + 1 + read-only + + + BRR + Backup regulator ready + 3 + 1 + read-only + + + EWUP + Enable WKUP pin + 8 + 1 + read-write + + + BRE + Backup regulator enable + 9 + 1 + read-write + + + VOSRDY + Regulator voltage scaling output + selection ready bit + 14 + 1 + read-write + + + + + + + RCC + Reset and clock control + RCC + 0x40023800 + + 0x0 + 0x400 + registers + + + I2C1_EV + I2C1 event interrupt + 31 + + + I2C1_ER + I2C1 error interrupt + 32 + + + + CR + CR + clock control register + 0x0 + 0x20 + 0x00000083 + + + PLLI2SRDY + PLLI2S clock ready flag + 27 + 1 + read-only + + + + PLLI2SON + PLLI2S enable + 26 + 1 + read-write + + + + PLLRDY + Main PLL (PLL) clock ready + flag + 25 + 1 + read-only + + + + PLLON + Main PLL (PLL) enable + 24 + 1 + read-write + + + + CSSON + Clock security system + enable + 19 + 1 + read-write + + CSSON + read-write + + Off + Clock security system disabled (clock detector OFF) + 0 + + + On + Clock security system enable (clock detector ON if the HSE is ready, OFF if not) + 1 + + + + + HSEBYP + HSE clock bypass + 18 + 1 + read-write + + HSEBYP + read-write + + NotBypassed + HSE crystal oscillator not bypassed + 0 + + + Bypassed + HSE crystal oscillator bypassed with external clock + 1 + + + + + HSERDY + HSE clock ready flag + 17 + 1 + read-only + + + + HSEON + HSE clock enable + 16 + 1 + read-write + + + + HSICAL + Internal high-speed clock + calibration + 8 + 8 + read-only + + + 0 + 255 + + + + + HSITRIM + Internal high-speed clock + trimming + 3 + 5 + read-write + + + 0 + 31 + + + + + HSIRDY + Internal high-speed clock ready + flag + 1 + 1 + read-only + + HSIRDYR + read + + NotReady + Clock not ready + 0 + + + Ready + Clock ready + 1 + + + + + HSION + Internal high-speed clock + enable + 0 + 1 + read-write + + HSION + read-write + + Off + Clock Off + 0 + + + On + Clock On + 1 + + + + + + + PLLCFGR + PLLCFGR + PLL configuration register + 0x4 + 0x20 + read-write + 0x24003010 + + + PLLSRC + Main PLL(PLL) and audio PLL (PLLI2S) + entry clock source + 22 + 1 + + PLLSRC + read-write + + HSI + HSI clock selected as PLL and PLLI2S clock entry + 0 + + + HSE + HSE oscillator clock selected as PLL and PLLI2S clock entry + 1 + + + + + PLLM + Division factor for the main PLL (PLL) + and audio PLL (PLLI2S) input clock + 0 + 6 + + + 2 + 63 + + + + + PLLN + Main PLL (PLL) multiplication factor for + VCO + 6 + 9 + + + 50 + 432 + + + + + PLLP + Main PLL (PLL) division factor for main + system clock + 16 + 2 + + PLLP + read-write + + Div2 + PLLP=2 + 0 + + + Div4 + PLLP=4 + 1 + + + Div6 + PLLP=6 + 2 + + + Div8 + PLLP=8 + 3 + + + + + PLLQ + Main PLL (PLL) division factor for USB + OTG FS, SDIO and random number generator + clocks + 24 + 4 + + + 2 + 15 + + + + + + + CFGR + CFGR + clock configuration register + 0x8 + 0x20 + 0x00000000 + + + MCO2 + Microcontroller clock output + 2 + 30 + 2 + read-write + + MCO2 + read-write + + SYSCLK + System clock (SYSCLK) selected + 0 + + + PLLI2S + PLLI2S clock selected + 1 + + + HSE + HSE oscillator clock selected + 2 + + + PLL + PLL clock selected + 3 + + + + + MCO2PRE + MCO2 prescaler + 27 + 3 + read-write + + + + MCO1PRE + MCO1 prescaler + 24 + 3 + read-write + + MCO1PRE + read-write + + Div1 + No division + 0 + + + Div2 + Division by 2 + 4 + + + Div3 + Division by 3 + 5 + + + Div4 + Division by 4 + 6 + + + Div5 + Division by 5 + 7 + + + + + I2SSRC + I2S clock selection + 23 + 1 + read-write + + I2SSRC + read-write + + PLLI2S + PLLI2S clock used as I2S clock source + 0 + + + CKIN + External clock mapped on the I2S_CKIN pin used as I2S clock source + 1 + + + + + MCO1 + Microcontroller clock output + 1 + 21 + 2 + read-write + + MCO1 + read-write + + HSI + HSI clock selected + 0 + + + LSE + LSE oscillator selected + 1 + + + HSE + HSE oscillator clock selected + 2 + + + PLL + PLL clock selected + 3 + + + + + RTCPRE + HSE division factor for RTC + clock + 16 + 5 + read-write + + + 0 + 31 + + + + + PPRE2 + APB high-speed prescaler + (APB2) + 13 + 3 + read-write + + + + PPRE1 + APB Low speed prescaler + (APB1) + 10 + 3 + read-write + + PPRE1 + read-write + + Div1 + HCLK not divided + 0 + + + Div2 + HCLK divided by 2 + 4 + + + Div4 + HCLK divided by 4 + 5 + + + Div8 + HCLK divided by 8 + 6 + + + Div16 + HCLK divided by 16 + 7 + + + + + HPRE + AHB prescaler + 4 + 4 + read-write + + HPRE + read-write + + Div1 + SYSCLK not divided + 0 + + + Div2 + SYSCLK divided by 2 + 8 + + + Div4 + SYSCLK divided by 4 + 9 + + + Div8 + SYSCLK divided by 8 + 10 + + + Div16 + SYSCLK divided by 16 + 11 + + + Div64 + SYSCLK divided by 64 + 12 + + + Div128 + SYSCLK divided by 128 + 13 + + + Div256 + SYSCLK divided by 256 + 14 + + + Div512 + SYSCLK divided by 512 + 15 + + + + + SW + System clock switch + 0 + 2 + + SW + read-write + + HSI + HSI selected as system clock + 0 + + + HSE + HSE selected as system clock + 1 + + + PLL + PLL selected as system clock + 2 + + + + + SWS + System clock switch status + 2 + 2 + + SWSR + read + + HSI + HSI oscillator used as system clock + 0 + + + HSE + HSE oscillator used as system clock + 1 + + + PLL + PLL used as system clock + 2 + + + + + + + CIR + CIR + clock interrupt register + 0xC + 0x20 + 0x00000000 + + + CSSC + Clock security system interrupt + clear + 23 + 1 + write-only + + CSSCW + write + + Clear + Clear CSSF flag + 1 + + + + + PLLI2SRDYC + PLLI2S ready interrupt + clear + 21 + 1 + write-only + + + + PLLRDYC + Main PLL(PLL) ready interrupt + clear + 20 + 1 + write-only + + + + HSERDYC + HSE ready interrupt clear + 19 + 1 + write-only + + + + HSIRDYC + HSI ready interrupt clear + 18 + 1 + write-only + + + + LSERDYC + LSE ready interrupt clear + 17 + 1 + write-only + + + + LSIRDYC + LSI ready interrupt clear + 16 + 1 + write-only + + LSIRDYCW + write + + Clear + Clear interrupt flag + 1 + + + + + PLLI2SRDYIE + PLLI2S ready interrupt + enable + 13 + 1 + read-write + + + + PLLRDYIE + Main PLL (PLL) ready interrupt + enable + 12 + 1 + read-write + + + + HSERDYIE + HSE ready interrupt enable + 11 + 1 + read-write + + + + HSIRDYIE + HSI ready interrupt enable + 10 + 1 + read-write + + + + LSERDYIE + LSE ready interrupt enable + 9 + 1 + read-write + + + + LSIRDYIE + LSI ready interrupt enable + 8 + 1 + read-write + + LSIRDYIE + read-write + + Disabled + Interrupt disabled + 0 + + + Enabled + Interrupt enabled + 1 + + + + + CSSF + Clock security system interrupt + flag + 7 + 1 + read-only + + CSSFR + read + + NotInterrupted + No clock security interrupt caused by HSE clock failure + 0 + + + Interrupted + Clock security interrupt caused by HSE clock failure + 1 + + + + + PLLI2SRDYF + PLLI2S ready interrupt + flag + 5 + 1 + read-only + + + + PLLRDYF + Main PLL (PLL) ready interrupt + flag + 4 + 1 + read-only + + + + HSERDYF + HSE ready interrupt flag + 3 + 1 + read-only + + + + HSIRDYF + HSI ready interrupt flag + 2 + 1 + read-only + + + + LSERDYF + LSE ready interrupt flag + 1 + 1 + read-only + + + + LSIRDYF + LSI ready interrupt flag + 0 + 1 + read-only + + LSIRDYFR + read + + NotInterrupted + No clock ready interrupt + 0 + + + Interrupted + Clock ready interrupt + 1 + + + + + + + AHB1RSTR + AHB1RSTR + AHB1 peripheral reset register + 0x10 + 0x20 + read-write + 0x00000000 + + + DMA2RST + DMA2 reset + 22 + 1 + + + + DMA1RST + DMA2 reset + 21 + 1 + + + + CRCRST + CRC reset + 12 + 1 + + + + GPIOHRST + IO port H reset + 7 + 1 + + + + GPIOERST + IO port E reset + 4 + 1 + + + + GPIODRST + IO port D reset + 3 + 1 + + + + GPIOCRST + IO port C reset + 2 + 1 + + + + GPIOBRST + IO port B reset + 1 + 1 + + + + GPIOARST + IO port A reset + 0 + 1 + + GPIOARST + read-write + + Reset + Reset the selected module + 1 + + + + + + + AHB2RSTR + AHB2RSTR + AHB2 peripheral reset register + 0x14 + 0x20 + read-write + 0x00000000 + + + OTGFSRST + USB OTG FS module reset + 7 + 1 + + OTGFSRST + read-write + + Reset + Reset the selected module + 1 + + + + + + + APB1RSTR + APB1RSTR + APB1 peripheral reset register + 0x20 + 0x20 + read-write + 0x00000000 + + + PWRRST + Power interface reset + 28 + 1 + + + + I2C3RST + I2C3 reset + 23 + 1 + + + + I2C2RST + I2C 2 reset + 22 + 1 + + + + I2C1RST + I2C 1 reset + 21 + 1 + + + + USART2RST + USART 2 reset + 17 + 1 + + + + SPI3RST + SPI 3 reset + 15 + 1 + + + + SPI2RST + SPI 2 reset + 14 + 1 + + + + WWDGRST + Window watchdog reset + 11 + 1 + + + + TIM5RST + TIM5 reset + 3 + 1 + + + + TIM4RST + TIM4 reset + 2 + 1 + + + + TIM3RST + TIM3 reset + 1 + 1 + + + + TIM2RST + TIM2 reset + 0 + 1 + + TIM2RST + read-write + + Reset + Reset the selected module + 1 + + + + + + + APB2RSTR + APB2RSTR + APB2 peripheral reset register + 0x24 + 0x20 + read-write + 0x00000000 + + + TIM11RST + TIM11 reset + 18 + 1 + + + + TIM10RST + TIM10 reset + 17 + 1 + + + + TIM9RST + TIM9 reset + 16 + 1 + + + + SYSCFGRST + System configuration controller + reset + 14 + 1 + + + + SPI1RST + SPI 1 reset + 12 + 1 + + + + SDIORST + SDIO reset + 11 + 1 + + + + ADCRST + ADC interface reset (common to all + ADCs) + 8 + 1 + + + + USART6RST + USART6 reset + 5 + 1 + + + + USART1RST + USART1 reset + 4 + 1 + + + + TIM1RST + TIM1 reset + 0 + 1 + + TIM1RST + read-write + + Reset + Reset the selected module + 1 + + + + + SPI4RST + SPI4 reset + 13 + 1 + + + + + + AHB1ENR + AHB1ENR + AHB1 peripheral clock register + 0x30 + 0x20 + read-write + 0x00100000 + + + DMA2EN + DMA2 clock enable + 22 + 1 + + + + DMA1EN + DMA1 clock enable + 21 + 1 + + + + CRCEN + CRC clock enable + 12 + 1 + + + + GPIOHEN + IO port H clock enable + 7 + 1 + + + + GPIOEEN + IO port E clock enable + 4 + 1 + + + + GPIODEN + IO port D clock enable + 3 + 1 + + + + GPIOCEN + IO port C clock enable + 2 + 1 + + + + GPIOBEN + IO port B clock enable + 1 + 1 + + + + GPIOAEN + IO port A clock enable + 0 + 1 + + GPIOAEN + read-write + + Disabled + The selected clock is disabled + 0 + + + Enabled + The selected clock is enabled + 1 + + + + + + + AHB2ENR + AHB2ENR + AHB2 peripheral clock enable + register + 0x34 + 0x20 + read-write + 0x00000000 + + + OTGFSEN + USB OTG FS clock enable + 7 + 1 + + OTGFSEN + read-write + + Disabled + The selected clock is disabled + 0 + + + Enabled + The selected clock is enabled + 1 + + + + + + + APB1ENR + APB1ENR + APB1 peripheral clock enable + register + 0x40 + 0x20 + read-write + 0x00000000 + + + PWREN + Power interface clock + enable + 28 + 1 + + + + I2C3EN + I2C3 clock enable + 23 + 1 + + + + I2C2EN + I2C2 clock enable + 22 + 1 + + + + I2C1EN + I2C1 clock enable + 21 + 1 + + + + USART2EN + USART 2 clock enable + 17 + 1 + + + + SPI3EN + SPI3 clock enable + 15 + 1 + + + + SPI2EN + SPI2 clock enable + 14 + 1 + + + + WWDGEN + Window watchdog clock + enable + 11 + 1 + + + + TIM5EN + TIM5 clock enable + 3 + 1 + + + + TIM4EN + TIM4 clock enable + 2 + 1 + + + + TIM3EN + TIM3 clock enable + 1 + 1 + + + + TIM2EN + TIM2 clock enable + 0 + 1 + + TIM2EN + read-write + + Disabled + The selected clock is disabled + 0 + + + Enabled + The selected clock is enabled + 1 + + + + + + + APB2ENR + APB2ENR + APB2 peripheral clock enable + register + 0x44 + 0x20 + read-write + 0x00000000 + + + TIM11EN + TIM11 clock enable + 18 + 1 + + + + TIM10EN + TIM10 clock enable + 17 + 1 + + + + TIM9EN + TIM9 clock enable + 16 + 1 + + + + SYSCFGEN + System configuration controller clock + enable + 14 + 1 + + + + SPI1EN + SPI1 clock enable + 12 + 1 + + + + SDIOEN + SDIO clock enable + 11 + 1 + + + + ADC1EN + ADC1 clock enable + 8 + 1 + + + + USART6EN + USART6 clock enable + 5 + 1 + + + + USART1EN + USART1 clock enable + 4 + 1 + + + + TIM1EN + TIM1 clock enable + 0 + 1 + + TIM1EN + read-write + + Disabled + The selected clock is disabled + 0 + + + Enabled + The selected clock is enabled + 1 + + + + + SPI4EN + SPI4 clock enable + 13 + 1 + + + + + + AHB1LPENR + AHB1LPENR + AHB1 peripheral clock enable in low power + mode register + 0x50 + 0x20 + read-write + 0x7E6791FF + + + DMA2LPEN + DMA2 clock enable during Sleep + mode + 22 + 1 + + + + DMA1LPEN + DMA1 clock enable during Sleep + mode + 21 + 1 + + + + SRAM1LPEN + SRAM 1interface clock enable during + Sleep mode + 16 + 1 + + + + FLITFLPEN + Flash interface clock enable during + Sleep mode + 15 + 1 + + + + CRCLPEN + CRC clock enable during Sleep + mode + 12 + 1 + + + + GPIOHLPEN + IO port H clock enable during Sleep + mode + 7 + 1 + + + + GPIOELPEN + IO port E clock enable during Sleep + mode + 4 + 1 + + + + GPIODLPEN + IO port D clock enable during Sleep + mode + 3 + 1 + + + + GPIOCLPEN + IO port C clock enable during Sleep + mode + 2 + 1 + + + + GPIOBLPEN + IO port B clock enable during Sleep + mode + 1 + 1 + + + + GPIOALPEN + IO port A clock enable during sleep + mode + 0 + 1 + + GPIOALPEN + read-write + + DisabledInSleep + Selected module is disabled during Sleep mode + 0 + + + EnabledInSleep + Selected module is enabled during Sleep mode + 1 + + + + + + + AHB2LPENR + AHB2LPENR + AHB2 peripheral clock enable in low power + mode register + 0x54 + 0x20 + read-write + 0x000000F1 + + + OTGFSLPEN + USB OTG FS clock enable during Sleep + mode + 7 + 1 + + OTGFSLPEN + read-write + + DisabledInSleep + Selected module is disabled during Sleep mode + 0 + + + EnabledInSleep + Selected module is enabled during Sleep mode + 1 + + + + + + + APB1LPENR + APB1LPENR + APB1 peripheral clock enable in low power + mode register + 0x60 + 0x20 + read-write + 0x36FEC9FF + + + PWRLPEN + Power interface clock enable during + Sleep mode + 28 + 1 + + + + I2C3LPEN + I2C3 clock enable during Sleep + mode + 23 + 1 + + + + I2C2LPEN + I2C2 clock enable during Sleep + mode + 22 + 1 + + + + I2C1LPEN + I2C1 clock enable during Sleep + mode + 21 + 1 + + + + USART2LPEN + USART2 clock enable during Sleep + mode + 17 + 1 + + + + SPI3LPEN + SPI3 clock enable during Sleep + mode + 15 + 1 + + + + SPI2LPEN + SPI2 clock enable during Sleep + mode + 14 + 1 + + + + WWDGLPEN + Window watchdog clock enable during + Sleep mode + 11 + 1 + + + + TIM5LPEN + TIM5 clock enable during Sleep + mode + 3 + 1 + + + + TIM4LPEN + TIM4 clock enable during Sleep + mode + 2 + 1 + + + + TIM3LPEN + TIM3 clock enable during Sleep + mode + 1 + 1 + + + + TIM2LPEN + TIM2 clock enable during Sleep + mode + 0 + 1 + + TIM2LPEN + read-write + + DisabledInSleep + Selected module is disabled during Sleep mode + 0 + + + EnabledInSleep + Selected module is enabled during Sleep mode + 1 + + + + + + + APB2LPENR + APB2LPENR + APB2 peripheral clock enabled in low power + mode register + 0x64 + 0x20 + read-write + 0x00075F33 + + + TIM11LPEN + TIM11 clock enable during Sleep + mode + 18 + 1 + + + + TIM10LPEN + TIM10 clock enable during Sleep + mode + 17 + 1 + + + + TIM9LPEN + TIM9 clock enable during sleep + mode + 16 + 1 + + + + SYSCFGLPEN + System configuration controller clock + enable during Sleep mode + 14 + 1 + + + + SPI1LPEN + SPI 1 clock enable during Sleep + mode + 12 + 1 + + + + SDIOLPEN + SDIO clock enable during Sleep + mode + 11 + 1 + + + + ADC1LPEN + ADC1 clock enable during Sleep + mode + 8 + 1 + + + + USART6LPEN + USART6 clock enable during Sleep + mode + 5 + 1 + + + + USART1LPEN + USART1 clock enable during Sleep + mode + 4 + 1 + + + + TIM1LPEN + TIM1 clock enable during Sleep + mode + 0 + 1 + + TIM1LPEN + read-write + + DisabledInSleep + Selected module is disabled during Sleep mode + 0 + + + EnabledInSleep + Selected module is enabled during Sleep mode + 1 + + + + + SPI4LPEN + SPI4 clock enable during Sleep mode + 13 + 1 + + + + + + BDCR + BDCR + Backup domain control register + 0x70 + 0x20 + 0x00000000 + + + BDRST + Backup domain software + reset + 16 + 1 + read-write + + BDRST + read-write + + Disabled + Reset not activated + 0 + + + Enabled + Reset the entire RTC domain + 1 + + + + + RTCEN + RTC clock enable + 15 + 1 + read-write + + RTCEN + read-write + + Disabled + RTC clock disabled + 0 + + + Enabled + RTC clock enabled + 1 + + + + + LSEBYP + External low-speed oscillator + bypass + 2 + 1 + read-write + + LSEBYP + read-write + + NotBypassed + LSE crystal oscillator not bypassed + 0 + + + Bypassed + LSE crystal oscillator bypassed with external clock + 1 + + + + + LSERDY + External low-speed oscillator + ready + 1 + 1 + read-only + + LSERDYR + read + + NotReady + LSE oscillator not ready + 0 + + + Ready + LSE oscillator ready + 1 + + + + + LSEON + External low-speed oscillator + enable + 0 + 1 + read-write + + LSEON + read-write + + Off + LSE oscillator Off + 0 + + + On + LSE oscillator On + 1 + + + + + RTCSEL + RTC clock source selection + 8 + 2 + + RTCSEL + read-write + + NoClock + No clock + 0 + + + LSE + LSE oscillator clock used as RTC clock + 1 + + + LSI + LSI oscillator clock used as RTC clock + 2 + + + HSE + HSE oscillator clock divided by a prescaler used as RTC clock + 3 + + + + + + + CSR + CSR + clock control & status + register + 0x74 + 0x20 + 0x0E000000 + + + LPWRRSTF + Low-power reset flag + 31 + 1 + read-write + + + + WWDGRSTF + Window watchdog reset flag + 30 + 1 + read-write + + + + WDGRSTF + Independent watchdog reset + flag + 29 + 1 + read-write + + + + SFTRSTF + Software reset flag + 28 + 1 + read-write + + + + PORRSTF + POR/PDR reset flag + 27 + 1 + read-write + + + + PADRSTF + PIN reset flag + 26 + 1 + read-write + + + + BORRSTF + BOR reset flag + 25 + 1 + read-write + + BORRSTFR + read + + NoReset + No reset has occured + 0 + + + Reset + A reset has occured + 1 + + + + + RMVF + Remove reset flag + 24 + 1 + read-write + + RMVFW + write + + Clear + Clears the reset flag + 1 + + + + + LSIRDY + Internal low-speed oscillator + ready + 1 + 1 + read-only + + LSIRDYR + read + + NotReady + LSI oscillator not ready + 0 + + + Ready + LSI oscillator ready + 1 + + + + + LSION + Internal low-speed oscillator + enable + 0 + 1 + read-write + + LSION + read-write + + Off + LSI oscillator Off + 0 + + + On + LSI oscillator On + 1 + + + + + + + SSCGR + SSCGR + spread spectrum clock generation + register + 0x80 + 0x20 + read-write + 0x00000000 + + + SSCGEN + Spread spectrum modulation + enable + 31 + 1 + + SSCGEN + read-write + + Disabled + Spread spectrum modulation disabled + 0 + + + Enabled + Spread spectrum modulation enabled + 1 + + + + + SPREADSEL + Spread Select + 30 + 1 + + SPREADSEL + read-write + + Center + Center spread + 0 + + + Down + Down spread + 1 + + + + + INCSTEP + Incrementation step + 13 + 15 + + + 0 + 32767 + + + + + MODPER + Modulation period + 0 + 13 + + + 0 + 8191 + + + + + + + PLLI2SCFGR + PLLI2SCFGR + PLLI2S configuration register + 0x84 + 0x20 + read-write + 0x20003000 + + + PLLI2SR + PLLI2S division factor for I2S + clocks + 28 + 3 + + + 2 + 7 + + + + + PLLI2SN + PLLI2S multiplication factor for + VCO + 6 + 9 + + + 50 + 432 + + + + + + + DCKCFGR + RCC Dedicated Clock Configuration Register + 0x8C + 0x20 + read-write + 0x00000000 + + + TIMPRE + Timers clocks prescalers selection + 24 + 1 + + TIMPRE + read-write + + Mul1Or2 + If the APB prescaler is configured 1, TIMxCLK = PCLKx. Otherwise, TIMxCLK = 2xPCLKx + 0 + + + Mul1Or4 + If the APB prescaler is configured 1, 2 or 4, TIMxCLK = HCLK. Otherwise, TIMxCLK = 4xPCLKx + 1 + + + + + + + + + RTC + Real-time clock + RTC + 0x40002800 + + 0x0 + 0x400 + registers + + + I2C2_EV + I2C2 event interrupt + 33 + + + I2C2_ER + I2C2 error interrupt + 34 + + + + TR + TR + time register + 0x0 + 0x20 + read-write + 0x00000000 + + + PM + AM/PM notation + 22 + 1 + + PM + read-write + + AM + AM or 24-hour format + 0 + + + PM + PM + 1 + + + + + HT + Hour tens in BCD format + 20 + 2 + + + 0 + 3 + + + + + HU + Hour units in BCD format + 16 + 4 + + + 0 + 15 + + + + + MNT + Minute tens in BCD format + 12 + 3 + + + 0 + 7 + + + + + MNU + Minute units in BCD format + 8 + 4 + + + 0 + 15 + + + + + ST + Second tens in BCD format + 4 + 3 + + + 0 + 7 + + + + + SU + Second units in BCD format + 0 + 4 + + + 0 + 15 + + + + + + + DR + DR + date register + 0x4 + 0x20 + read-write + 0x00002101 + + + YT + Year tens in BCD format + 20 + 4 + + + 0 + 15 + + + + + YU + Year units in BCD format + 16 + 4 + + + 0 + 15 + + + + + WDU + Week day units + 13 + 3 + + + 1 + 7 + + + + + MT + Month tens in BCD format + 12 + 1 + + MT + read-write + + Zero + Month tens is 0 + 0 + + + One + Month tens is 1 + 1 + + + + + MU + Month units in BCD format + 8 + 4 + + + 0 + 15 + + + + + DT + Date tens in BCD format + 4 + 2 + + + 0 + 3 + + + + + DU + Date units in BCD format + 0 + 4 + + + 0 + 15 + + + + + + + CR + CR + control register + 0x8 + 0x20 + read-write + 0x00000000 + + + COE + Calibration output enable + 23 + 1 + + COE + read-write + + Disabled + Calibration output disabled + 0 + + + Enabled + Calibration output enabled + 1 + + + + + OSEL + Output selection + 21 + 2 + + OSEL + read-write + + Disabled + Output disabled + 0 + + + AlarmA + Alarm A output enabled + 1 + + + AlarmB + Alarm B output enabled + 2 + + + Wakeup + Wakeup output enabled + 3 + + + + + POL + Output polarity + 20 + 1 + + POL + read-write + + High + The pin is high when ALRAF/ALRBF/WUTF is asserted (depending on OSEL[1:0]) + 0 + + + Low + The pin is low when ALRAF/ALRBF/WUTF is asserted (depending on OSEL[1:0]) + 1 + + + + + COSEL + Calibration Output + selection + 19 + 1 + + COSEL + read-write + + CalFreq_512Hz + Calibration output is 512 Hz (with default prescaler setting) + 0 + + + CalFreq_1Hz + Calibration output is 1 Hz (with default prescaler setting) + 1 + + + + + BKP + Backup + 18 + 1 + + BKP + read-write + + DST_Not_Changed + Daylight Saving Time change has not been performed + 0 + + + DST_Changed + Daylight Saving Time change has been performed + 1 + + + + + SUB1H + Subtract 1 hour (winter time + change) + 17 + 1 + + SUB1HW + write + + Sub1 + Subtracts 1 hour to the current time. This can be used for winter time change outside initialization mode + 1 + + + + + ADD1H + Add 1 hour (summer time + change) + 16 + 1 + + ADD1HW + write + + Add1 + Adds 1 hour to the current time. This can be used for summer time change outside initialization mode + 1 + + + + + TSIE + Time-stamp interrupt + enable + 15 + 1 + + TSIE + read-write + + Disabled + Time-stamp Interrupt disabled + 0 + + + Enabled + Time-stamp Interrupt enabled + 1 + + + + + WUTIE + Wakeup timer interrupt + enable + 14 + 1 + + WUTIE + read-write + + Disabled + Wakeup timer interrupt disabled + 0 + + + Enabled + Wakeup timer interrupt enabled + 1 + + + + + ALRBIE + Alarm B interrupt enable + 13 + 1 + + ALRBIE + read-write + + Disabled + Alarm B Interrupt disabled + 0 + + + Enabled + Alarm B Interrupt enabled + 1 + + + + + ALRAIE + Alarm A interrupt enable + 12 + 1 + + ALRAIE + read-write + + Disabled + Alarm A interrupt disabled + 0 + + + Enabled + Alarm A interrupt enabled + 1 + + + + + TSE + Time stamp enable + 11 + 1 + + TSE + read-write + + Disabled + Timestamp disabled + 0 + + + Enabled + Timestamp enabled + 1 + + + + + WUTE + Wakeup timer enable + 10 + 1 + + WUTE + read-write + + Disabled + Wakeup timer disabled + 0 + + + Enabled + Wakeup timer enabled + 1 + + + + + ALRBE + Alarm B enable + 9 + 1 + + ALRBE + read-write + + Disabled + Alarm B disabled + 0 + + + Enabled + Alarm B enabled + 1 + + + + + ALRAE + Alarm A enable + 8 + 1 + + ALRAE + read-write + + Disabled + Alarm A disabled + 0 + + + Enabled + Alarm A enabled + 1 + + + + + DCE + Coarse digital calibration + enable + 7 + 1 + + + FMT + Hour format + 6 + 1 + + FMT + read-write + + Twenty_Four_Hour + 24 hour/day format + 0 + + + AM_PM + AM/PM hour format + 1 + + + + + BYPSHAD + Bypass the shadow + registers + 5 + 1 + + BYPSHAD + read-write + + ShadowReg + Calendar values (when reading from RTC_SSR, RTC_TR, and RTC_DR) are taken from the shadow registers, which are updated once every two RTCCLK cycles + 0 + + + BypassShadowReg + Calendar values (when reading from RTC_SSR, RTC_TR, and RTC_DR) are taken directly from the calendar counters + 1 + + + + + REFCKON + Reference clock detection enable (50 or + 60 Hz) + 4 + 1 + + REFCKON + read-write + + Disabled + RTC_REFIN detection disabled + 0 + + + Enabled + RTC_REFIN detection enabled + 1 + + + + + TSEDGE + Time-stamp event active + edge + 3 + 1 + + TSEDGE + read-write + + RisingEdge + RTC_TS input rising edge generates a time-stamp event + 0 + + + FallingEdge + RTC_TS input falling edge generates a time-stamp event + 1 + + + + + WUCKSEL + Wakeup clock selection + 0 + 3 + + WUCKSEL + read-write + + Div16 + RTC/16 clock is selected + 0 + + + Div8 + RTC/8 clock is selected + 1 + + + Div4 + RTC/4 clock is selected + 2 + + + Div2 + RTC/2 clock is selected + 3 + + + ClockSpare + ck_spre (usually 1 Hz) clock is selected + 4 + + + ClockSpareWithOffset + ck_spre (usually 1 Hz) clock is selected and 2^16 is added to the WUT counter value + 6 + + + + + + + ISR + ISR + initialization and status + register + 0xC + 0x20 + 0x00000007 + + + ALRAWF + Alarm A write flag + 0 + 1 + read-only + + ALRAWFR + read + + UpdateNotAllowed + Alarm update not allowed + 0 + + + UpdateAllowed + Alarm update allowed + 1 + + + + + ALRBWF + Alarm B write flag + 1 + 1 + read-only + + + + WUTWF + Wakeup timer write flag + 2 + 1 + read-only + + WUTWFR + read + + UpdateNotAllowed + Wakeup timer configuration update not allowed + 0 + + + UpdateAllowed + Wakeup timer configuration update allowed + 1 + + + + + SHPF + Shift operation pending + 3 + 1 + read-write + + SHPFR + read + + NoShiftPending + No shift operation is pending + 0 + + + ShiftPending + A shift operation is pending + 1 + + + + + INITS + Initialization status flag + 4 + 1 + read-only + + INITSR + read + + NotInitalized + Calendar has not been initialized + 0 + + + Initalized + Calendar has been initialized + 1 + + + + + RSF + Registers synchronization + flag + 5 + 1 + read-write + zeroToClear + + RSFR + read + + NotSynced + Calendar shadow registers not yet synchronized + 0 + + + Synced + Calendar shadow registers synchronized + 1 + + + + RSFW + write + + Clear + This flag is cleared by software by writing 0 + 0 + + + + + INITF + Initialization flag + 6 + 1 + read-only + + INITFR + read + + NotAllowed + Calendar registers update is not allowed + 0 + + + Allowed + Calendar registers update is allowed + 1 + + + + + INIT + Initialization mode + 7 + 1 + read-write + + INIT + read-write + + FreeRunningMode + Free running mode + 0 + + + InitMode + Initialization mode used to program time and date register (RTC_TR and RTC_DR), and prescaler register (RTC_PRER). Counters are stopped and start counting from the new value when INIT is reset. + 1 + + + + + ALRAF + Alarm A flag + 8 + 1 + read-write + zeroToClear + + ALRAFR + read + + Match + This flag is set by hardware when the time/date registers (RTC_TR and RTC_DR) match the Alarm A register (RTC_ALRMAR) + 1 + + + + ALRAFW + write + + Clear + This flag is cleared by software by writing 0 + 0 + + + + + ALRBF + Alarm B flag + 9 + 1 + read-write + zeroToClear + + ALRBFR + read + + Match + This flag is set by hardware when the time/date registers (RTC_TR and RTC_DR) match the Alarm B register (RTC_ALRMBR) + 1 + + + + ALRBFW + write + + Clear + This flag is cleared by software by writing 0 + 0 + + + + + WUTF + Wakeup timer flag + 10 + 1 + read-write + zeroToClear + + WUTFR + read + + Zero + This flag is set by hardware when the wakeup auto-reload counter reaches 0 + 1 + + + + WUTFW + write + + Clear + This flag is cleared by software by writing 0 + 0 + + + + + TSF + Time-stamp flag + 11 + 1 + read-write + zeroToClear + + TSFR + read + + TimestampEvent + This flag is set by hardware when a time-stamp event occurs + 1 + + + + TSFW + write + + Clear + This flag is cleared by software by writing 0 + 0 + + + + + TSOVF + Time-stamp overflow flag + 12 + 1 + read-write + zeroToClear + + TSOVFR + read + + Overflow + This flag is set by hardware when a time-stamp event occurs while TSF is already set + 1 + + + + TSOVFW + write + + Clear + This flag is cleared by software by writing 0 + 0 + + + + + TAMP1F + Tamper detection flag + 13 + 1 + read-write + zeroToClear + + TAMP1FR + read + + Tampered + This flag is set by hardware when a tamper detection event is detected on the RTC_TAMPx input + 1 + + + + TAMP1FW + write + + Clear + Flag cleared by software writing 0 + 0 + + + + + TAMP2F + TAMPER2 detection flag + 14 + 1 + read-write + zeroToClear + + read + + + write + + + + RECALPF + Recalibration pending Flag + 16 + 1 + read-only + + RECALPFR + read + + Pending + The RECALPF status flag is automatically set to 1 when software writes to the RTC_CALR register, indicating that the RTC_CALR register is blocked. When the new calibration settings are taken into account, this bit returns to 0 + 1 + + + + + + + PRER + PRER + prescaler register + 0x10 + 0x20 + read-write + 0x007F00FF + + + PREDIV_A + Asynchronous prescaler + factor + 16 + 7 + + + 0 + 127 + + + + + PREDIV_S + Synchronous prescaler + factor + 0 + 15 + + + 0 + 32767 + + + + + + + WUTR + WUTR + wakeup timer register + 0x14 + 0x20 + read-write + 0x0000FFFF + + + WUT + Wakeup auto-reload value + bits + 0 + 16 + + + 0 + 65535 + + + + + + + CALIBR + CALIBR + calibration register + 0x18 + 0x20 + read-write + 0x00000000 + + + DCS + Digital calibration sign + 7 + 1 + + + DC + Digital calibration + 0 + 5 + + + + + 2 + 0x4 + A,B + ALRM%sR + ALRMAR + Alarm register + 0x1C + 0x20 + read-write + 0x00000000 + + + MSK4 + Alarm date mask + 31 + 1 + + + + WDSEL + Week day selection + 30 + 1 + + WDSEL + read-write + + DateUnits + DU[3:0] represents the date units + 0 + + + WeekDay + DU[3:0] represents the week day. DT[1:0] is don’t care. + 1 + + + + + DT + Date tens in BCD format + 28 + 2 + + + 0 + 3 + + + + + DU + Date units or day in BCD format + 24 + 4 + + + 0 + 15 + + + + + MSK3 + Alarm hours mask + 23 + 1 + + + + PM + AM/PM notation + 22 + 1 + + PM + read-write + + AM + AM or 24-hour format + 0 + + + PM + PM + 1 + + + + + HT + Hour tens in BCD format + 20 + 2 + + + 0 + 3 + + + + + HU + Hour units in BCD format + 16 + 4 + + + 0 + 15 + + + + + MSK2 + Alarm minutes mask + 15 + 1 + + + + MNT + Minute tens in BCD format + 12 + 3 + + + 0 + 7 + + + + + MNU + Minute units in BCD format + 8 + 4 + + + 0 + 15 + + + + + MSK1 + Alarm seconds mask + 7 + 1 + + MSK1 + read-write + + Mask + Alarm set if the date/day match + 0 + + + NotMask + Date/day don’t care in Alarm comparison + 1 + + + + + ST + Second tens in BCD format + 4 + 3 + + + 0 + 7 + + + + + SU + Second units in BCD format + 0 + 4 + + + 0 + 15 + + + + + + + WPR + WPR + write protection register + 0x24 + 0x20 + write-only + 0x00000000 + + + KEY + Write protection key + 0 + 8 + + + 0 + 255 + + + + + + + SSR + SSR + sub second register + 0x28 + 0x20 + read-only + 0x00000000 + + + SS + Sub second value + 0 + 16 + + + 0 + 65535 + + + + + + + SHIFTR + SHIFTR + shift control register + 0x2C + 0x20 + write-only + 0x00000000 + + + ADD1S + Add one second + 31 + 1 + + ADD1SW + write + + Add1 + Add one second to the clock/calendar + 1 + + + + + SUBFS + Subtract a fraction of a + second + 0 + 15 + + + 0 + 32767 + + + + + + + TSTR + TSTR + time stamp time register + 0x30 + + + TSDR + TSDR + time stamp date register + 0x34 + + + TSSSR + TSSSR + timestamp sub second register + 0x38 + + + CALR + CALR + calibration register + 0x3C + 0x20 + read-write + 0x00000000 + + + CALP + Increase frequency of RTC by 488.5 + ppm + 15 + 1 + + CALP + read-write + + NoChange + No RTCCLK pulses are added + 0 + + + IncreaseFreq + One RTCCLK pulse is effectively inserted every 2^11 pulses (frequency increased by 488.5 ppm) + 1 + + + + + CALW8 + Use an 8-second calibration cycle + period + 14 + 1 + + CALW8 + read-write + + Eight_Second + When CALW8 is set to ‘1’, the 8-second calibration cycle period is selected + 1 + + + + + CALW16 + Use a 16-second calibration cycle + period + 13 + 1 + + CALW16 + read-write + + Sixteen_Second + When CALW16 is set to ‘1’, the 16-second calibration cycle period is selected.This bit must not be set to ‘1’ if CALW8=1 + 1 + + + + + CALM + Calibration minus + 0 + 9 + + + 0 + 511 + + + + + + + TAFCR + TAFCR + tamper and alternate function configuration + register + 0x40 + 0x20 + read-write + 0x00000000 + + + ALARMOUTTYPE + AFO_ALARM output type + 18 + 1 + + + TSINSEL + TIMESTAMP mapping + 17 + 1 + + + TAMP1INSEL + TAMPER1 mapping + 16 + 1 + + + TAMPPUDIS + TAMPER pull-up disable + 15 + 1 + + + TAMPPRCH + Tamper precharge duration + 13 + 2 + + + TAMPFLT + Tamper filter count + 11 + 2 + + + TAMPFREQ + Tamper sampling frequency + 8 + 3 + + + TAMPTS + Activate timestamp on tamper detection + event + 7 + 1 + + + TAMP2TRG + Active level for tamper 2 + 4 + 1 + + + TAMP2E + Tamper 2 detection enable + 3 + 1 + + + TAMPIE + Tamper interrupt enable + 2 + 1 + + + TAMP1TRG + Active level for tamper 1 + 1 + 1 + + + TAMP1E + Tamper 1 detection enable + 0 + 1 + + + + + 2 + 0x4 + A,B + ALRM%sSSR + ALRMASSR + Alarm sub-second register + 0x44 + 0x20 + read-write + 0x00000000 + + + MASKSS + Mask the most-significant bits starting + at this bit + 24 + 4 + + + 0 + 15 + + + + + SS + Sub seconds value + 0 + 15 + + + 0 + 32767 + + + + + + + 20 + 0x4 + 0-19 + BKP%sR + BKP0R + backup register + 0x50 + 0x20 + read-write + 0x00000000 + + + BKP + BKP + 0 + 32 + + + 0 + 4294967295 + + + + + + + + + SDIO + Secure digital input/output + interface + SDIO + 0x40012C00 + + 0x0 + 0x400 + registers + + + I2C3_EV + I2C3 event interrupt + 72 + + + I2C3_ER + I2C3 error interrupt + 73 + + + + POWER + POWER + power control register + 0x0 + 0x20 + read-write + 0x00000000 + + + PWRCTRL + PWRCTRL + 0 + 2 + + PWRCTRL + read-write + + PowerOff + Power off + 0 + + + PowerOn + Power on + 3 + + + + + + + CLKCR + CLKCR + SDI clock control register + 0x4 + 0x20 + read-write + 0x00000000 + + + HWFC_EN + HW Flow Control enable + 14 + 1 + + HWFC_EN + read-write + + Disabled + HW Flow Control is disabled + 0 + + + Enabled + HW Flow Control is enabled + 1 + + + + + NEGEDGE + SDIO_CK dephasing selection + bit + 13 + 1 + + NEGEDGE + read-write + + Rising + SDIO_CK generated on the rising edge + 0 + + + Falling + SDIO_CK generated on the falling edge + 1 + + + + + WIDBUS + Wide bus mode enable bit + 11 + 2 + + WIDBUS + read-write + + BusWidth1 + 1 lane wide bus + 0 + + + BusWidth4 + 4 lane wide bus + 1 + + + BusWidth8 + 8 lane wide bus + 2 + + + + + BYPASS + Clock divider bypass enable + bit + 10 + 1 + + BYPASS + read-write + + Disabled + SDIOCLK is divided according to the CLKDIV value before driving the SDIO_CK output signal. + 0 + + + Enabled + SDIOCLK directly drives the SDIO_CK output signal + 1 + + + + + PWRSAV + Power saving configuration + bit + 9 + 1 + + PWRSAV + read-write + + Enabled + SDIO_CK clock is always enabled + 0 + + + Disabled + SDIO_CK is only enabled when the bus is active + 1 + + + + + CLKEN + Clock enable bit + 8 + 1 + + CLKEN + read-write + + Disabled + Disable clock + 0 + + + Enabled + Enable clock + 1 + + + + + CLKDIV + Clock divide factor + 0 + 8 + + + 0 + 255 + + + + + + + ARG + ARG + argument register + 0x8 + 0x20 + read-write + 0x00000000 + + + CMDARG + Command argument + 0 + 32 + + + 0 + 4294967295 + + + + + + + CMD + CMD + command register + 0xC + 0x20 + read-write + 0x00000000 + + + CE_ATACMD + CE-ATA command + 14 + 1 + + CE_ATACMD + read-write + + Disabled + CE-ATA command disabled + 0 + + + Enabled + CE-ATA command enabled + 1 + + + + + nIEN + not Interrupt Enable + 13 + 1 + + nIEN + read-write + + Disabled + Interrupts to the CE-ATA not disabled + 0 + + + Enabled + Interrupt to the CE-ATA are disabled + 1 + + + + + ENCMDcompl + Enable CMD completion + 12 + 1 + + ENCMDcompl + read-write + + Disabled + Command complete signal disabled + 0 + + + Enabled + Command complete signal enabled + 1 + + + + + SDIOSuspend + SD I/O suspend command + 11 + 1 + + SDIOSuspend + read-write + + Disabled + Next command is not a SDIO suspend command + 0 + + + Enabled + Next command send is a SDIO suspend command + 1 + + + + + CPSMEN + Command path state machine (CPSM) Enable + bit + 10 + 1 + + CPSMEN + read-write + + Disabled + Command path state machine disabled + 0 + + + Enabled + Command path state machine enabled + 1 + + + + + WAITPEND + CPSM Waits for ends of data transfer + (CmdPend internal signal). + 9 + 1 + + WAITPEND + read-write + + Disabled + Don't wait for data end + 0 + + + Enabled + Wait for end of data transfer signal before sending command + 1 + + + + + WAITINT + CPSM waits for interrupt + request + 8 + 1 + + WAITINT + read-write + + Disabled + Don't wait for interrupt request + 0 + + + Enabled + Wait for interrupt request + 1 + + + + + WAITRESP + Wait for response bits + 6 + 2 + + WAITRESP + read-write + + NoResponse + No response + 0 + + + ShortResponse + Short response + 1 + + + NoResponse2 + No reponse + 2 + + + LongResponse + Long reponse + 3 + + + + + CMDINDEX + Command index + 0 + 6 + + + 0 + 63 + + + + + + + RESPCMD + RESPCMD + command response register + 0x10 + 0x20 + read-only + 0x00000000 + + + RESPCMD + Response command index + 0 + 6 + + + 0 + 63 + + + + + + + RESP1 + RESP1 + response 1..4 register + 0x14 + 0x20 + read-only + 0x00000000 + + + CARDSTATUS1 + Card Status + 0 + 32 + + + 0 + 4294967295 + + + + + + + RESP2 + RESP2 + response 1..4 register + 0x18 + 0x20 + read-only + 0x00000000 + + + CARDSTATUS2 + Card Status + 0 + 32 + + + 0 + 4294967295 + + + + + + + RESP3 + RESP3 + response 1..4 register + 0x1C + 0x20 + read-only + 0x00000000 + + + CARDSTATUS3 + Card Status + 0 + 32 + + + 0 + 4294967295 + + + + + + + RESP4 + RESP4 + response 1..4 register + 0x20 + 0x20 + read-only + 0x00000000 + + + CARDSTATUS4 + Card Status + 0 + 32 + + + 0 + 4294967295 + + + + + + + DTIMER + DTIMER + data timer register + 0x24 + 0x20 + read-write + 0x00000000 + + + DATATIME + Data timeout period + 0 + 32 + + + 0 + 4294967295 + + + + + + + DLEN + DLEN + data length register + 0x28 + 0x20 + read-write + 0x00000000 + + + DATALENGTH + Data length value + 0 + 25 + + + 0 + 33554431 + + + + + + + DCTRL + DCTRL + data control register + 0x2C + 0x20 + read-write + 0x00000000 + + + SDIOEN + SD I/O enable functions + 11 + 1 + + SDIOEN + read-write + + Disabled + SDIO operations disabled + 0 + + + Enabled + SDIO operations enabled + 1 + + + + + RWMOD + Read wait mode + 10 + 1 + + RWMOD + read-write + + D2 + Read wait control stopping using SDIO_D2 + 0 + + + Ck + Read wait control using SDIO_CK + 1 + + + + + RWSTOP + Read wait stop + 9 + 1 + + RWSTOP + read-write + + Disabled + Read wait in progress if RWSTART is enabled + 0 + + + Enabled + Enable for read wait stop if RWSTART is enabled + 1 + + + + + RWSTART + Read wait start + 8 + 1 + + RWSTART + read-write + + Disabled + Don't start read wait operation + 0 + + + Enabled + Read wait operation starts + 1 + + + + + DBLOCKSIZE + Data block size + 4 + 4 + + + 0 + 15 + + + + + DMAEN + DMA enable bit + 3 + 1 + + DMAEN + read-write + + Disabled + Dma disabled + 0 + + + Enabled + Dma enabled + 1 + + + + + DTMODE + Data transfer mode selection 1: Stream + or SDIO multibyte data transfer. + 2 + 1 + + DTMODE + read-write + + BlockMode + Bloack data transfer + 0 + + + StreamMode + Stream or SDIO multibyte data transfer + 1 + + + + + DTDIR + Data transfer direction + selection + 1 + 1 + + DTDIR + read-write + + ControllerToCard + From controller to card + 0 + + + CardToController + From card to controller + 1 + + + + + DTEN + DTEN + 0 + 1 + + DTEN + read-write + + Disabled + Disabled + 0 + + + Enabled + Start transfer + 1 + + + + + + + DCOUNT + DCOUNT + data counter register + 0x30 + 0x20 + read-only + 0x00000000 + + + DATACOUNT + Data count value + 0 + 25 + + + 0 + 33554431 + + + + + + + STA + STA + status register + 0x34 + 0x20 + read-only + 0x00000000 + + + CEATAEND + CE-ATA command completion signal + received for CMD61 + 23 + 1 + + CEATAEND + read + + NotReceived + Completion signal not received + 0 + + + Received + CE-ATA command completion signal received for CMD61 + 1 + + + + + SDIOIT + SDIO interrupt received + 22 + 1 + + SDIOIT + read + + NotReceived + SDIO interrupt not receieved + 0 + + + Received + SDIO interrupt received + 1 + + + + + RXDAVL + Data available in receive + FIFO + 21 + 1 + + RXDAVL + read + + NotAvailable + Data not available in receive FIFO + 0 + + + Available + Data available in receive FIFO + 1 + + + + + TXDAVL + Data available in transmit + FIFO + 20 + 1 + + TXDAVL + read + + NotAvailable + Data not available in transmit FIFO + 0 + + + Available + Data available in transmit FIFO + 1 + + + + + RXFIFOE + Receive FIFO empty + 19 + 1 + + RXFIFOE + read + + NotEmpty + Receive FIFO not empty + 0 + + + Empty + Receive FIFO empty + 1 + + + + + TXFIFOE + Transmit FIFO empty + 18 + 1 + + TXFIFOE + read + + NotEmpty + Transmit FIFO not empty + 0 + + + Empty + Transmit FIFO empty. When HW Flow Control is enabled, TXFIFOE signals becomes activated when the FIFO contains 2 words. + 1 + + + + + RXFIFOF + Receive FIFO full + 17 + 1 + + RXFIFOF + read + + NotFull + Transmit FIFO not full + 0 + + + Full + Receive FIFO full. When HW Flow Control is enabled, RXFIFOF signals becomes activated 2 words before the FIFO is full. + 1 + + + + + TXFIFOF + Transmit FIFO full + 16 + 1 + + TXFIFOF + read + + NotFull + Transmit FIFO not full + 0 + + + Full + Transmit FIFO full + 1 + + + + + RXFIFOHF + Receive FIFO half full: there are at + least 8 words in the FIFO + 15 + 1 + + RXFIFOHF + read + + NotHalfFull + Receive FIFO not half full + 0 + + + HalfFull + Receive FIFO half full. At least 8 words in the FIFO + 1 + + + + + TXFIFOHE + Transmit FIFO half empty: at least 8 + words can be written into the FIFO + 14 + 1 + + TXFIFOHE + read + + NotHalfEmpty + Transmit FIFO not half empty + 0 + + + HalfEmpty + Transmit FIFO half empty. At least 8 words can be written into the FIFO + 1 + + + + + RXACT + Data receive in progress + 13 + 1 + + RXACT + read + + NotInProgress + Data receive not in progress + 0 + + + InProgress + Data receive in progress + 1 + + + + + TXACT + Data transmit in progress + 12 + 1 + + TXACT + read + + NotInProgress + Data transmit is not in progress + 0 + + + InProgress + Data transmit in progress + 1 + + + + + CMDACT + Command transfer in + progress + 11 + 1 + + CMDACT + read + + NotInProgress + Command transfer not in progress + 0 + + + InProgress + Command tranfer in progress + 1 + + + + + DBCKEND + Data block sent/received (CRC check + passed) + 10 + 1 + + DBCKEND + read + + NotTransferred + Data block not sent/received (CRC check failed) + 0 + + + Transferred + Data block sent/received (CRC check passed) + 1 + + + + + STBITERR + Start bit not detected on all data + signals in wide bus mode + 9 + 1 + + STBITERR + read + + Detected + No start bit detected error + 0 + + + NotDetected + Start bit not detected error + 1 + + + + + DATAEND + Data end (data counter, SDIDCOUNT, is + zero) + 8 + 1 + + DATAEND + read + + NotDone + Not done + 0 + + + Done + Data end (DCOUNT, is zero) + 1 + + + + + CMDSENT + Command sent (no response + required) + 7 + 1 + + CMDSENT + read + + NotSent + Command not sent + 0 + + + Sent + Command sent (no response required) + 1 + + + + + CMDREND + Command response received (CRC check + passed) + 6 + 1 + + CMDREND + read + + NotDone + Command not done + 0 + + + Done + Command response received (CRC check passed) + 1 + + + + + RXOVERR + Received FIFO overrun + error + 5 + 1 + + RXOVERR + read + + NoOverrun + No FIFO overrun error + 0 + + + Overrun + Receive FIFO overrun error + 1 + + + + + TXUNDERR + Transmit FIFO underrun + error + 4 + 1 + + TXUNDERR + read + + NoUnderrun + No transmit FIFO underrun error + 0 + + + Underrun + Transmit FIFO underrun error + 1 + + + + + DTIMEOUT + Data timeout + 3 + 1 + + DTIMEOUT + read + + NoTimeout + No data timeout + 0 + + + Timeout + Data timeout + 1 + + + + + CTIMEOUT + Command response timeout + 2 + 1 + + CTIMEOUT + read + + NoTimeout + No Command timeout + 0 + + + Timeout + Command timeout + 1 + + + + + DCRCFAIL + Data block sent/received (CRC check + failed) + 1 + 1 + + DCRCFAIL + read + + NotFailed + No Data block sent/received crc check fail + 0 + + + Failed + Data block sent/received crc failed + 1 + + + + + CCRCFAIL + Command response received (CRC check + failed) + 0 + 1 + + CCRCFAIL + read + + NotFailed + Command response received, crc check passed + 0 + + + Failed + Command response received, crc check failed + 1 + + + + + + + ICR + ICR + interrupt clear register + 0x38 + 0x20 + read-write + 0x00000000 + + + CEATAENDC + CEATAEND flag clear bit + 23 + 1 + + + + SDIOITC + SDIOIT flag clear bit + 22 + 1 + + + + DBCKENDC + DBCKEND flag clear bit + 10 + 1 + + + + STBITERRC + STBITERR flag clear bit + 9 + 1 + + + + DATAENDC + DATAEND flag clear bit + 8 + 1 + + + + CMDSENTC + CMDSENT flag clear bit + 7 + 1 + + + + CMDRENDC + CMDREND flag clear bit + 6 + 1 + + + + RXOVERRC + RXOVERR flag clear bit + 5 + 1 + + + + TXUNDERRC + TXUNDERR flag clear bit + 4 + 1 + + + + DTIMEOUTC + DTIMEOUT flag clear bit + 3 + 1 + + + + CTIMEOUTC + CTIMEOUT flag clear bit + 2 + 1 + + + + DCRCFAILC + DCRCFAIL flag clear bit + 1 + 1 + + + + CCRCFAILC + CCRCFAIL flag clear bit + 0 + 1 + + CCRCFAILCW + write + + Clear + Clear flag + 1 + + + + + + + MASK + MASK + mask register + 0x3C + 0x20 + read-write + 0x00000000 + + + CEATAENDIE + CE-ATA command completion signal + received interrupt enable + 23 + 1 + + + + SDIOITIE + SDIO mode interrupt received interrupt + enable + 22 + 1 + + + + RXDAVLIE + Data available in Rx FIFO interrupt + enable + 21 + 1 + + + + TXDAVLIE + Data available in Tx FIFO interrupt + enable + 20 + 1 + + + + RXFIFOEIE + Rx FIFO empty interrupt + enable + 19 + 1 + + + + TXFIFOEIE + Tx FIFO empty interrupt + enable + 18 + 1 + + + + RXFIFOFIE + Rx FIFO full interrupt + enable + 17 + 1 + + + + TXFIFOFIE + Tx FIFO full interrupt + enable + 16 + 1 + + + + RXFIFOHFIE + Rx FIFO half full interrupt + enable + 15 + 1 + + + + TXFIFOHEIE + Tx FIFO half empty interrupt + enable + 14 + 1 + + + + RXACTIE + Data receive acting interrupt + enable + 13 + 1 + + + + TXACTIE + Data transmit acting interrupt + enable + 12 + 1 + + + + CMDACTIE + Command acting interrupt + enable + 11 + 1 + + + + DBCKENDIE + Data block end interrupt + enable + 10 + 1 + + + + STBITERRIE + Start bit error interrupt + enable + 9 + 1 + + + + DATAENDIE + Data end interrupt enable + 8 + 1 + + + + CMDSENTIE + Command sent interrupt + enable + 7 + 1 + + + + CMDRENDIE + Command response received interrupt + enable + 6 + 1 + + + + RXOVERRIE + Rx FIFO overrun error interrupt + enable + 5 + 1 + + + + TXUNDERRIE + Tx FIFO underrun error interrupt + enable + 4 + 1 + + + + DTIMEOUTIE + Data timeout interrupt + enable + 3 + 1 + + + + CTIMEOUTIE + Command timeout interrupt + enable + 2 + 1 + + + + DCRCFAILIE + Data CRC fail interrupt + enable + 1 + 1 + + + + CCRCFAILIE + Command CRC fail interrupt + enable + 0 + 1 + + CCRCFAILIE + read-write + + Disabled + Interrupt disabled + 0 + + + Enabled + Interrupt enabled + 1 + + + + + + + FIFOCNT + FIFOCNT + FIFO counter register + 0x48 + 0x20 + read-only + 0x00000000 + + + FIFOCOUNT + Remaining number of words to be written + to or read from the FIFO. + 0 + 24 + + + 0 + 16777215 + + + + + + + FIFO + FIFO + data FIFO register + 0x80 + 0x20 + read-write + 0x00000000 + + + FIFOData + Receive and transmit FIFO + data + 0 + 32 + + + 0 + 4294967295 + + + + + + + + + SYSCFG + System configuration controller + SYSCFG + 0x40013800 + + 0x0 + 0x400 + registers + + + + MEMRM + MEMRM + memory remap register + 0x0 + 0x20 + read-write + 0x00000000 + + + MEM_MODE + MEM_MODE + 0 + 2 + + + + + PMC + PMC + peripheral mode configuration + register + 0x4 + 0x20 + read-write + 0x00000000 + + + ADC1DC2 + ADC1DC2 + 16 + 1 + + + + + EXTICR1 + EXTICR1 + external interrupt configuration register + 1 + 0x8 + 0x20 + read-write + 0x00000000 + + + EXTI3 + EXTI x configuration (x = 0 to + 3) + 12 + 4 + + + EXTI2 + EXTI x configuration (x = 0 to + 3) + 8 + 4 + + + EXTI1 + EXTI x configuration (x = 0 to + 3) + 4 + 4 + + + EXTI0 + EXTI x configuration (x = 0 to + 3) + 0 + 4 + + + + + EXTICR2 + EXTICR2 + external interrupt configuration register + 2 + 0xC + 0x20 + read-write + 0x00000000 + + + EXTI7 + EXTI x configuration (x = 4 to + 7) + 12 + 4 + + + EXTI6 + EXTI x configuration (x = 4 to + 7) + 8 + 4 + + + EXTI5 + EXTI x configuration (x = 4 to + 7) + 4 + 4 + + + EXTI4 + EXTI x configuration (x = 4 to + 7) + 0 + 4 + + + + + EXTICR3 + EXTICR3 + external interrupt configuration register + 3 + 0x10 + 0x20 + read-write + 0x00000000 + + + EXTI11 + EXTI x configuration (x = 8 to + 11) + 12 + 4 + + + EXTI10 + EXTI10 + 8 + 4 + + + EXTI9 + EXTI x configuration (x = 8 to + 11) + 4 + 4 + + + EXTI8 + EXTI x configuration (x = 8 to + 11) + 0 + 4 + + + + + EXTICR4 + EXTICR4 + external interrupt configuration register + 4 + 0x14 + 0x20 + read-write + 0x00000000 + + + EXTI15 + EXTI x configuration (x = 12 to + 15) + 12 + 4 + + + EXTI14 + EXTI x configuration (x = 12 to + 15) + 8 + 4 + + + EXTI13 + EXTI x configuration (x = 12 to + 15) + 4 + 4 + + + EXTI12 + EXTI x configuration (x = 12 to + 15) + 0 + 4 + + + + + CMPCR + CMPCR + Compensation cell control + register + 0x20 + 0x20 + read-only + 0x00000000 + + + READY + READY + 8 + 1 + + + CMP_PD + Compensation cell + power-down + 0 + 1 + + + + + + + TIM1 + Advanced-timers + TIM + 0x40010000 + + 0x0 + 0x400 + registers + + + + CR1 + CR1 + control register 1 + 0x0 + 0x20 + read-write + 0x00000000 + + + CKD + Clock division + 8 + 2 + + CKD + read-write + + Div1 + t_DTS = t_CK_INT + 0 + + + Div2 + t_DTS = 2 × t_CK_INT + 1 + + + Div4 + t_DTS = 4 × t_CK_INT + 2 + + + + + ARPE + Auto-reload preload enable + 7 + 1 + + ARPE + read-write + + Disabled + TIMx_APRR register is not buffered + 0 + + + Enabled + TIMx_APRR register is buffered + 1 + + + + + CMS + Center-aligned mode + selection + 5 + 2 + + CMS + read-write + + EdgeAligned + The counter counts up or down depending on the direction bit + 0 + + + CenterAligned1 + The counter counts up and down alternatively. Output compare interrupt flags are set only when the counter is counting down. + 1 + + + CenterAligned2 + The counter counts up and down alternatively. Output compare interrupt flags are set only when the counter is counting up. + 2 + + + CenterAligned3 + The counter counts up and down alternatively. Output compare interrupt flags are set both when the counter is counting up or down. + 3 + + + + + DIR + Direction + 4 + 1 + + DIR + read-write + + Up + Counter used as upcounter + 0 + + + Down + Counter used as downcounter + 1 + + + + + OPM + One-pulse mode + 3 + 1 + + OPM + read-write + + Disabled + Counter is not stopped at update event + 0 + + + Enabled + Counter stops counting at the next update event (clearing the CEN bit) + 1 + + + + + URS + Update request source + 2 + 1 + + URS + read-write + + AnyEvent + Any of counter overflow/underflow, setting UG, or update through slave mode, generates an update interrupt or DMA request + 0 + + + CounterOnly + Only counter overflow/underflow generates an update interrupt or DMA request + 1 + + + + + UDIS + Update disable + 1 + 1 + + UDIS + read-write + + Enabled + Update event enabled + 0 + + + Disabled + Update event disabled + 1 + + + + + CEN + Counter enable + 0 + 1 + + CEN + read-write + + Disabled + Counter disabled + 0 + + + Enabled + Counter enabled + 1 + + + + + + + CR2 + CR2 + control register 2 + 0x4 + 0x20 + read-write + 0x00000000 + + + OIS4 + Output Idle state 4 + 14 + 1 + + + + OIS3N + Output Idle state 3 + 13 + 1 + + + + OIS3 + Output Idle state 3 + 12 + 1 + + + + OIS2N + Output Idle state 2 + 11 + 1 + + + + OIS2 + Output Idle state 2 + 10 + 1 + + + + OIS1N + Output Idle state 1 + 9 + 1 + + OIS1N + read-write + + Reset + OCxN=0 after a dead-time when MOE=0 + 0 + + + Set + OCxN=1 after a dead-time when MOE=0 + 1 + + + + + OIS1 + Output Idle state 1 + 8 + 1 + + OIS1 + read-write + + Reset + OCx=0 (after a dead-time if OCx(N) is implemented) when MOE=0 + 0 + + + Set + OCx=1 (after a dead-time if OCx(N) is implemented) when MOE=0 + 1 + + + + + TI1S + TI1 selection + 7 + 1 + + TI1S + read-write + + Normal + The TIMx_CH1 pin is connected to TI1 input + 0 + + + XOR + The TIMx_CH1, CH2, CH3 pins are connected to TI1 input + 1 + + + + + MMS + Master mode selection + 4 + 3 + + MMS + read-write + + Reset + The UG bit from the TIMx_EGR register is used as trigger output + 0 + + + Enable + The counter enable signal, CNT_EN, is used as trigger output + 1 + + + Update + The update event is selected as trigger output + 2 + + + ComparePulse + The trigger output send a positive pulse when the CC1IF flag it to be set, as soon as a capture or a compare match occurred + 3 + + + CompareOC1 + OC1REF signal is used as trigger output + 4 + + + CompareOC2 + OC2REF signal is used as trigger output + 5 + + + CompareOC3 + OC3REF signal is used as trigger output + 6 + + + CompareOC4 + OC4REF signal is used as trigger output + 7 + + + + + CCDS + Capture/compare DMA + selection + 3 + 1 + + CCDS + read-write + + OnCompare + CCx DMA request sent when CCx event occurs + 0 + + + OnUpdate + CCx DMA request sent when update event occurs + 1 + + + + + CCUS + Capture/compare control update + selection + 2 + 1 + + + CCPC + Capture/compare preloaded + control + 0 + 1 + + + + + SMCR + SMCR + slave mode control register + 0x8 + 0x20 + read-write + 0x00000000 + + + ETP + External trigger polarity + 15 + 1 + + ETP + read-write + + NotInverted + ETR is noninverted, active at high level or rising edge + 0 + + + Inverted + ETR is inverted, active at low level or falling edge + 1 + + + + + ECE + External clock enable + 14 + 1 + + ECE + read-write + + Disabled + External clock mode 2 disabled + 0 + + + Enabled + External clock mode 2 enabled. The counter is clocked by any active edge on the ETRF signal. + 1 + + + + + ETPS + External trigger prescaler + 12 + 2 + + ETPS + read-write + + Div1 + Prescaler OFF + 0 + + + Div2 + ETRP frequency divided by 2 + 1 + + + Div4 + ETRP frequency divided by 4 + 2 + + + Div8 + ETRP frequency divided by 8 + 3 + + + + + ETF + External trigger filter + 8 + 4 + + ETF + read-write + + NoFilter + No filter, sampling is done at fDTS + 0 + + + FCK_INT_N2 + fSAMPLING=fCK_INT, N=2 + 1 + + + FCK_INT_N4 + fSAMPLING=fCK_INT, N=4 + 2 + + + FCK_INT_N8 + fSAMPLING=fCK_INT, N=8 + 3 + + + FDTS_Div2_N6 + fSAMPLING=fDTS/2, N=6 + 4 + + + FDTS_Div2_N8 + fSAMPLING=fDTS/2, N=8 + 5 + + + FDTS_Div4_N6 + fSAMPLING=fDTS/4, N=6 + 6 + + + FDTS_Div4_N8 + fSAMPLING=fDTS/4, N=8 + 7 + + + FDTS_Div8_N6 + fSAMPLING=fDTS/8, N=6 + 8 + + + FDTS_Div8_N8 + fSAMPLING=fDTS/8, N=8 + 9 + + + FDTS_Div16_N5 + fSAMPLING=fDTS/16, N=5 + 10 + + + FDTS_Div16_N6 + fSAMPLING=fDTS/16, N=6 + 11 + + + FDTS_Div16_N8 + fSAMPLING=fDTS/16, N=8 + 12 + + + FDTS_Div32_N5 + fSAMPLING=fDTS/32, N=5 + 13 + + + FDTS_Div32_N6 + fSAMPLING=fDTS/32, N=6 + 14 + + + FDTS_Div32_N8 + fSAMPLING=fDTS/32, N=8 + 15 + + + + + MSM + Master/Slave mode + 7 + 1 + + MSM + read-write + + NoSync + No action + 0 + + + Sync + The effect of an event on the trigger input (TRGI) is delayed to allow a perfect synchronization between the current timer and its slaves (through TRGO). It is useful if we want to synchronize several timers on a single external event. + 1 + + + + + TS + Trigger selection + 4 + 3 + + TS + read-write + + ITR0 + Internal Trigger 0 (ITR0) + 0 + + + ITR1 + Internal Trigger 1 (ITR1) + 1 + + + ITR2 + Internal Trigger 2 (ITR2) + 2 + + + TI1F_ED + TI1 Edge Detector (TI1F_ED) + 4 + + + TI1FP1 + Filtered Timer Input 1 (TI1FP1) + 5 + + + TI2FP2 + Filtered Timer Input 2 (TI2FP2) + 6 + + + ETRF + External Trigger input (ETRF) + 7 + + + + + SMS + Slave mode selection + 0 + 3 + + SMS + read-write + + Disabled + Slave mode disabled - if CEN = ‘1 then the prescaler is clocked directly by the internal clock. + 0 + + + Encoder_Mode_1 + Encoder mode 1 - Counter counts up/down on TI2FP1 edge depending on TI1FP2 level. + 1 + + + Encoder_Mode_2 + Encoder mode 2 - Counter counts up/down on TI1FP2 edge depending on TI2FP1 level. + 2 + + + Encoder_Mode_3 + Encoder mode 3 - Counter counts up/down on both TI1FP1 and TI2FP2 edges depending on the level of the other input. + 3 + + + Reset_Mode + Reset Mode - Rising edge of the selected trigger input (TRGI) reinitializes the counter and generates an update of the registers. + 4 + + + Gated_Mode + Gated Mode - The counter clock is enabled when the trigger input (TRGI) is high. The counter stops (but is not reset) as soon as the trigger becomes low. Both start and stop of the counter are controlled. + 5 + + + Trigger_Mode + Trigger Mode - The counter starts at a rising edge of the trigger TRGI (but it is not reset). Only the start of the counter is controlled. + 6 + + + Ext_Clock_Mode + External Clock Mode 1 - Rising edges of the selected trigger (TRGI) clock the counter. + 7 + + + + + + + DIER + DIER + DMA/Interrupt enable register + 0xC + 0x20 + read-write + 0x00000000 + + + TDE + Trigger DMA request enable + 14 + 1 + + TDE + read-write + + Disabled + Trigger DMA request disabled + 0 + + + Enabled + Trigger DMA request enabled + 1 + + + + + COMDE + COM DMA request enable + 13 + 1 + + + CC4DE + Capture/Compare 4 DMA request + enable + 12 + 1 + + + + CC3DE + Capture/Compare 3 DMA request + enable + 11 + 1 + + + + CC2DE + Capture/Compare 2 DMA request + enable + 10 + 1 + + + + CC1DE + Capture/Compare 1 DMA request + enable + 9 + 1 + + CC1DE + read-write + + Disabled + CCx DMA request disabled + 0 + + + Enabled + CCx DMA request enabled + 1 + + + + + UDE + Update DMA request enable + 8 + 1 + + UDE + read-write + + Disabled + Update DMA request disabled + 0 + + + Enabled + Update DMA request enabled + 1 + + + + + BIE + Break interrupt enable + 7 + 1 + + + TIE + Trigger interrupt enable + 6 + 1 + + TIE + read-write + + Disabled + Trigger interrupt disabled + 0 + + + Enabled + Trigger interrupt enabled + 1 + + + + + COMIE + COM interrupt enable + 5 + 1 + + + CC4IE + Capture/Compare 4 interrupt + enable + 4 + 1 + + + + CC3IE + Capture/Compare 3 interrupt + enable + 3 + 1 + + + + CC2IE + Capture/Compare 2 interrupt + enable + 2 + 1 + + + + CC1IE + Capture/Compare 1 interrupt + enable + 1 + 1 + + CC1IE + read-write + + Disabled + CCx interrupt disabled + 0 + + + Enabled + CCx interrupt enabled + 1 + + + + + UIE + Update interrupt enable + 0 + 1 + + UIE + read-write + + Disabled + Update interrupt disabled + 0 + + + Enabled + Update interrupt enabled + 1 + + + + + + + SR + SR + status register + 0x10 + 0x20 + read-write + 0x00000000 + + + CC4OF + Capture/Compare 4 overcapture + flag + 12 + 1 + zeroToClear + + read + + + write + + + + CC3OF + Capture/Compare 3 overcapture + flag + 11 + 1 + zeroToClear + + read + + + write + + + + CC2OF + Capture/compare 2 overcapture + flag + 10 + 1 + zeroToClear + + read + + + write + + + + CC1OF + Capture/Compare 1 overcapture + flag + 9 + 1 + zeroToClear + + CC1OFR + read + + Overcapture + The counter value has been captured in TIMx_CCRx register while CCxIF flag was already set + 1 + + + + CC1OFW + write + + Clear + Clear flag + 0 + + + + + BIF + Break interrupt flag + 7 + 1 + + + TIF + Trigger interrupt flag + 6 + 1 + zeroToClear + + TIFR + read + + NoTrigger + No trigger event occurred + 0 + + + Trigger + Trigger interrupt pending + 1 + + + + TIFW + write + + Clear + Clear flag + 0 + + + + + COMIF + COM interrupt flag + 5 + 1 + + + CC4IF + Capture/Compare 4 interrupt + flag + 4 + 1 + zeroToClear + + read + + + write + + + + CC3IF + Capture/Compare 3 interrupt + flag + 3 + 1 + zeroToClear + + read + + + write + + + + CC2IF + Capture/Compare 2 interrupt + flag + 2 + 1 + zeroToClear + + read + + + write + + + + CC1IF + Capture/compare 1 interrupt + flag + 1 + 1 + zeroToClear + + CC1IFR + read + + Match + If CC1 is an output: The content of the counter TIMx_CNT matches the content of the TIMx_CCR1 register. If CC1 is an input: The counter value has been captured in TIMx_CCR1 register. + 1 + + + + CC1IFW + write + + Clear + Clear flag + 0 + + + + + UIF + Update interrupt flag + 0 + 1 + zeroToClear + + UIFR + read + + NoUpdateOccurred + No update occurred + 0 + + + UpdatePending + Update interrupt pending + 1 + + + + UIFW + write + + Clear + Clear flag + 0 + + + + + + + EGR + EGR + event generation register + 0x14 + 0x20 + write-only + 0x00000000 + + + BG + Break generation + 7 + 1 + + + TG + Trigger generation + 6 + 1 + + TGW + write + + Trigger + The TIF flag is set in TIMx_SR register. Related interrupt or DMA transfer can occur if enabled. + 1 + + + + + COMG + Capture/Compare control update + generation + 5 + 1 + + + CC4G + Capture/compare 4 + generation + 4 + 1 + + + + CC3G + Capture/compare 3 + generation + 3 + 1 + + + + CC2G + Capture/compare 2 + generation + 2 + 1 + + + + CC1G + Capture/compare 1 + generation + 1 + 1 + + CC1GW + write + + Trigger + If CC1 is an output: CC1IF flag is set, Corresponding interrupt or DMA request is sent if enabled. If CC1 is an input: The current value of the counter is captured in TIMx_CCR1 register. + 1 + + + + + UG + Update generation + 0 + 1 + + UG + write + + Update + Re-initializes the timer counter and generates an update of the registers. + 1 + + + + + + + CCMR1_Output + CCMR1_Output + capture/compare mode register 1 (output + mode) + 0x18 + 0x20 + read-write + 0x00000000 + + + OC2CE + Output Compare 2 clear + enable + 15 + 1 + + + OC2M + Output Compare 2 mode + 12 + 3 + + + + OC2PE + Output Compare 2 preload + enable + 11 + 1 + + OC2PE + read-write + + Disabled + Preload register on CCR2 disabled. New values written to CCR2 are taken into account immediately + 0 + + + Enabled + Preload register on CCR2 enabled. Preload value is loaded into active register on each update event + 1 + + + + + OC2FE + Output Compare 2 fast + enable + 10 + 1 + + + CC2S + Capture/Compare 2 + selection + 8 + 2 + + CC2S + read-write + + Output + CC2 channel is configured as output + 0 + + + + + OC1CE + Output Compare 1 clear + enable + 7 + 1 + + + OC1M + Output Compare 1 mode + 4 + 3 + + OC1M + read-write + + Frozen + The comparison between the output compare register TIMx_CCRy and the counter TIMx_CNT has no effect on the outputs + 0 + + + ActiveOnMatch + Set channel to active level on match. OCyREF signal is forced high when the counter matches the capture/compare register + 1 + + + InactiveOnMatch + Set channel to inactive level on match. OCyREF signal is forced low when the counter matches the capture/compare register + 2 + + + Toggle + OCyREF toggles when TIMx_CNT=TIMx_CCRy + 3 + + + ForceInactive + OCyREF is forced low + 4 + + + ForceActive + OCyREF is forced high + 5 + + + PwmMode1 + In upcounting, channel is active as long as TIMx_CNT<TIMx_CCRy else inactive. In downcounting, channel is inactive as long as TIMx_CNT>TIMx_CCRy else active + 6 + + + PwmMode2 + Inversely to PwmMode1 + 7 + + + + + OC1PE + Output Compare 1 preload + enable + 3 + 1 + + OC1PE + read-write + + Disabled + Preload register on CCR1 disabled. New values written to CCR1 are taken into account immediately + 0 + + + Enabled + Preload register on CCR1 enabled. Preload value is loaded into active register on each update event + 1 + + + + + OC1FE + Output Compare 1 fast + enable + 2 + 1 + + + CC1S + Capture/Compare 1 + selection + 0 + 2 + + CC1S + read-write + + Output + CC1 channel is configured as output + 0 + + + + + + + CCMR1_Input + CCMR1_Input + capture/compare mode register 1 (input + mode) + CCMR1_Output + 0x18 + 0x20 + read-write + 0x00000000 + + + IC2F + Input capture 2 filter + 12 + 4 + + + 0 + 15 + + + + + IC2PSC + Input capture 2 prescaler + 10 + 2 + + + CC2S + Capture/Compare 2 + selection + 8 + 2 + + CC2S + read-write + + TI2 + CC2 channel is configured as input, IC2 is mapped on TI2 + 1 + + + TI1 + CC2 channel is configured as input, IC2 is mapped on TI1 + 2 + + + TRC + CC2 channel is configured as input, IC2 is mapped on TRC + 3 + + + + + IC1F + Input capture 1 filter + 4 + 4 + + IC1F + read-write + + NoFilter + No filter, sampling is done at fDTS + 0 + + + FCK_INT_N2 + fSAMPLING=fCK_INT, N=2 + 1 + + + FCK_INT_N4 + fSAMPLING=fCK_INT, N=4 + 2 + + + FCK_INT_N8 + fSAMPLING=fCK_INT, N=8 + 3 + + + FDTS_Div2_N6 + fSAMPLING=fDTS/2, N=6 + 4 + + + FDTS_Div2_N8 + fSAMPLING=fDTS/2, N=8 + 5 + + + FDTS_Div4_N6 + fSAMPLING=fDTS/4, N=6 + 6 + + + FDTS_Div4_N8 + fSAMPLING=fDTS/4, N=8 + 7 + + + FDTS_Div8_N6 + fSAMPLING=fDTS/8, N=6 + 8 + + + FDTS_Div8_N8 + fSAMPLING=fDTS/8, N=8 + 9 + + + FDTS_Div16_N5 + fSAMPLING=fDTS/16, N=5 + 10 + + + FDTS_Div16_N6 + fSAMPLING=fDTS/16, N=6 + 11 + + + FDTS_Div16_N8 + fSAMPLING=fDTS/16, N=8 + 12 + + + FDTS_Div32_N5 + fSAMPLING=fDTS/32, N=5 + 13 + + + FDTS_Div32_N6 + fSAMPLING=fDTS/32, N=6 + 14 + + + FDTS_Div32_N8 + fSAMPLING=fDTS/32, N=8 + 15 + + + + + IC1PSC + Input capture 1 prescaler + 2 + 2 + + + CC1S + Capture/Compare 1 + selection + 0 + 2 + + CC1S + read-write + + TI1 + CC1 channel is configured as input, IC1 is mapped on TI1 + 1 + + + TI2 + CC1 channel is configured as input, IC1 is mapped on TI2 + 2 + + + TRC + CC1 channel is configured as input, IC1 is mapped on TRC + 3 + + + + + + + CCMR2_Output + CCMR2_Output + capture/compare mode register 2 (output + mode) + 0x1C + 0x20 + read-write + 0x00000000 + + + OC4CE + Output compare 4 clear + enable + 15 + 1 + + + OC4M + Output compare 4 mode + 12 + 3 + + + + OC4PE + Output compare 4 preload + enable + 11 + 1 + + OC4PE + read-write + + Disabled + Preload register on CCR4 disabled. New values written to CCR4 are taken into account immediately + 0 + + + Enabled + Preload register on CCR4 enabled. Preload value is loaded into active register on each update event + 1 + + + + + OC4FE + Output compare 4 fast + enable + 10 + 1 + + + CC4S + Capture/Compare 4 + selection + 8 + 2 + + CC4S + read-write + + Output + CC4 channel is configured as output + 0 + + + + + OC3CE + Output compare 3 clear + enable + 7 + 1 + + + OC3M + Output compare 3 mode + 4 + 3 + + OC3M + read-write + + Frozen + The comparison between the output compare register TIMx_CCRy and the counter TIMx_CNT has no effect on the outputs + 0 + + + ActiveOnMatch + Set channel to active level on match. OCyREF signal is forced high when the counter matches the capture/compare register + 1 + + + InactiveOnMatch + Set channel to inactive level on match. OCyREF signal is forced low when the counter matches the capture/compare register + 2 + + + Toggle + OCyREF toggles when TIMx_CNT=TIMx_CCRy + 3 + + + ForceInactive + OCyREF is forced low + 4 + + + ForceActive + OCyREF is forced high + 5 + + + PwmMode1 + In upcounting, channel is active as long as TIMx_CNT<TIMx_CCRy else inactive. In downcounting, channel is inactive as long as TIMx_CNT>TIMx_CCRy else active + 6 + + + PwmMode2 + Inversely to PwmMode1 + 7 + + + + + OC3PE + Output compare 3 preload + enable + 3 + 1 + + OC3PE + read-write + + Disabled + Preload register on CCR3 disabled. New values written to CCR3 are taken into account immediately + 0 + + + Enabled + Preload register on CCR3 enabled. Preload value is loaded into active register on each update event + 1 + + + + + OC3FE + Output compare 3 fast + enable + 2 + 1 + + + CC3S + Capture/Compare 3 + selection + 0 + 2 + + CC3S + read-write + + Output + CC3 channel is configured as output + 0 + + + + + + + CCMR2_Input + CCMR2_Input + capture/compare mode register 2 (input + mode) + CCMR2_Output + 0x1C + 0x20 + read-write + 0x00000000 + + + IC4F + Input capture 4 filter + 12 + 4 + + + 0 + 15 + + + + + IC4PSC + Input capture 4 prescaler + 10 + 2 + + + 0 + 3 + + + + + CC4S + Capture/Compare 4 + selection + 8 + 2 + + CC4S + read-write + + TI4 + CC4 channel is configured as input, IC4 is mapped on TI4 + 1 + + + TI3 + CC4 channel is configured as input, IC4 is mapped on TI3 + 2 + + + TRC + CC4 channel is configured as input, IC4 is mapped on TRC + 3 + + + + + IC3F + Input capture 3 filter + 4 + 4 + + + 0 + 15 + + + + + IC3PSC + Input capture 3 prescaler + 2 + 2 + + + 0 + 3 + + + + + CC3S + Capture/compare 3 + selection + 0 + 2 + + CC3S + read-write + + TI3 + CC3 channel is configured as input, IC3 is mapped on TI3 + 1 + + + TI4 + CC3 channel is configured as input, IC3 is mapped on TI4 + 2 + + + TRC + CC3 channel is configured as input, IC3 is mapped on TRC + 3 + + + + + + + CCER + CCER + capture/compare enable + register + 0x20 + 0x20 + read-write + 0x00000000 + + + CC4P + Capture/Compare 3 output + Polarity + 13 + 1 + + + CC4E + Capture/Compare 4 output + enable + 12 + 1 + + + CC3NP + Capture/Compare 3 output + Polarity + 11 + 1 + + + CC3NE + Capture/Compare 3 complementary output + enable + 10 + 1 + + + CC3P + Capture/Compare 3 output + Polarity + 9 + 1 + + + CC3E + Capture/Compare 3 output + enable + 8 + 1 + + + CC2NP + Capture/Compare 2 output + Polarity + 7 + 1 + + + CC2NE + Capture/Compare 2 complementary output + enable + 6 + 1 + + + CC2P + Capture/Compare 2 output + Polarity + 5 + 1 + + + CC2E + Capture/Compare 2 output + enable + 4 + 1 + + + CC1NP + Capture/Compare 1 output + Polarity + 3 + 1 + + + CC1NE + Capture/Compare 1 complementary output + enable + 2 + 1 + + + CC1P + Capture/Compare 1 output + Polarity + 1 + 1 + + + CC1E + Capture/Compare 1 output + enable + 0 + 1 + + + + + CNT + CNT + counter + 0x24 + 0x20 + read-write + 0x00000000 + + + CNT + counter value + 0 + 16 + + + 0 + 65535 + + + + + + + PSC + PSC + prescaler + 0x28 + 0x20 + read-write + 0x00000000 + + + PSC + Prescaler value + 0 + 16 + + + 0 + 65535 + + + + + + + ARR + ARR + auto-reload register + 0x2C + 0x20 + read-write + 0x00000000 + + + ARR + Auto-reload value + 0 + 16 + + + 0 + 65535 + + + + + + + 4 + 0x4 + 1-4 + CCR%s + CCR1 + capture/compare register + 0x34 + 0x20 + read-write + 0x00000000 + + + CCR + Capture/Compare value + 0 + 16 + + + 0 + 65535 + + + + + + + DCR + DCR + DMA control register + 0x48 + 0x20 + read-write + 0x00000000 + + + DBL + DMA burst length + 8 + 5 + + + 0 + 18 + + + + + DBA + DMA base address + 0 + 5 + + + 0 + 31 + + + + + + + DMAR + DMAR + DMA address for full transfer + 0x4C + 0x20 + read-write + 0x00000000 + + + DMAB + DMA register for burst + accesses + 0 + 16 + + + + + RCR + RCR + repetition counter register + 0x30 + 0x20 + read-write + 0x00000000 + + + REP + Repetition counter value + 0 + 8 + + + + + BDTR + BDTR + break and dead-time register + 0x44 + 0x20 + read-write + 0x00000000 + + + MOE + Main output enable + 15 + 1 + + MOE + read-write + + DisabledIdle + OC/OCN are disabled or forced idle depending on OSSI + 0 + + + Enabled + OC/OCN are enabled if CCxE/CCxNE are set + 1 + + + + + AOE + Automatic output enable + 14 + 1 + + AOE + read-write + + Manual + MOE can be set only by software + 0 + + + Automatic + MOE can be set by software or automatically at the next update event (if none of the break inputs BRK and BRK2 is active) + 1 + + + + + BKP + Break polarity + 13 + 1 + + BKP + read-write + + ActiveLow + Break input BRKx is active low + 0 + + + ActiveHigh + Break input BRKx is active high + 1 + + + + + BKE + Break enable + 12 + 1 + + BKE + read-write + + Disabled + Break function x disabled + 0 + + + Enabled + Break function x disabled + 1 + + + + + OSSR + Off-state selection for Run + mode + 11 + 1 + + OSSR + read-write + + Disabled + When inactive, OC/OCN outputs are disabled + 0 + + + IdleLevel + When inactive, OC/OCN outputs are enabled with their inactive level + 1 + + + + + OSSI + Off-state selection for Idle + mode + 10 + 1 + + OSSI + read-write + + Disabled + When inactive, OC/OCN outputs are disabled + 0 + + + IdleLevel + When inactive, OC/OCN outputs are forced to idle level + 1 + + + + + LOCK + Lock configuration + 8 + 2 + + LOCK + read-write + + Off + No bit is write protected + 0 + + + Level1 + Any bits except MOE, OSSR, OSSI and LOCK in TIMx_BDTR register, OISx and OISxN bits in TIMx_CR2 register can no longer be written + 1 + + + Level2 + LOCK Level 1 + CC Polarity bits (CCxP/CCxNP bits in TIMx_CCER register, as long as the related channel is configured in output through the CCxS bits) as well as OSSR and OSSI bits can no longer be written + 2 + + + Level3 + LOCK Level 2 + CC Control bits (OCxM and OCxPE bits in TIMx_CCMRx registers, as long as the related channel is configured in output through the CCxS bits) can no longer be written + 3 + + + + + DTG + Dead-time generator setup + 0 + 8 + + + 0 + 255 + + + + + + + + + TIM10 + General-purpose-timers + TIM + 0x40014400 + + 0x0 + 0x400 + registers + + + SPI1 + SPI1 global interrupt + 35 + + + + CR1 + CR1 + control register 1 + 0x0 + 0x20 + read-write + 0x00000000 + + + CKD + Clock division + 8 + 2 + + CKD + read-write + + Div1 + t_DTS = t_CK_INT + 0 + + + Div2 + t_DTS = 2 × t_CK_INT + 1 + + + Div4 + t_DTS = 4 × t_CK_INT + 2 + + + + + ARPE + Auto-reload preload enable + 7 + 1 + + ARPE + read-write + + Disabled + TIMx_APRR register is not buffered + 0 + + + Enabled + TIMx_APRR register is buffered + 1 + + + + + URS + Update request source + 2 + 1 + + URS + read-write + + AnyEvent + Any of counter overflow/underflow, setting UG, or update through slave mode, generates an update interrupt or DMA request + 0 + + + CounterOnly + Only counter overflow/underflow generates an update interrupt or DMA request + 1 + + + + + UDIS + Update disable + 1 + 1 + + UDIS + read-write + + Enabled + Update event enabled + 0 + + + Disabled + Update event disabled + 1 + + + + + CEN + Counter enable + 0 + 1 + + CEN + read-write + + Disabled + Counter disabled + 0 + + + Enabled + Counter enabled + 1 + + + + + OPM + One-pulse mode + 3 + 1 + + OPM + read-write + + Disabled + Counter is not stopped at update event + 0 + + + Enabled + Counter stops counting at the next update event (clearing the CEN bit) + 1 + + + + + + + DIER + DIER + DMA/Interrupt enable register + 0xC + 0x20 + read-write + 0x00000000 + + + CC1IE + Capture/Compare 1 interrupt + enable + 1 + 1 + + + UIE + Update interrupt enable + 0 + 1 + + UIE + read-write + + Disabled + Update interrupt disabled + 0 + + + Enabled + Update interrupt enabled + 1 + + + + + + + SR + SR + status register + 0x10 + 0x20 + read-write + 0x00000000 + + + CC1OF + Capture/Compare 1 overcapture + flag + 9 + 1 + + + CC1IF + Capture/compare 1 interrupt + flag + 1 + 1 + + + UIF + Update interrupt flag + 0 + 1 + zeroToClear + + UIFR + read + + NoUpdateOccurred + No update occurred + 0 + + + UpdatePending + Update interrupt pending + 1 + + + + UIFW + write + + Clear + Clear flag + 0 + + + + + + + EGR + EGR + event generation register + 0x14 + 0x20 + write-only + 0x00000000 + + + CC1G + Capture/compare 1 + generation + 1 + 1 + + + UG + Update generation + 0 + 1 + + UG + write + + Update + Re-initializes the timer counter and generates an update of the registers. + 1 + + + + + + + CCMR1_Output + CCMR1_Output + capture/compare mode register 1 (output + mode) + 0x18 + 0x20 + read-write + 0x00000000 + + + OC1M + Output Compare 1 mode + 4 + 3 + + OC1M + read-write + + Frozen + The comparison between the output compare register TIMx_CCRy and the counter TIMx_CNT has no effect on the outputs + 0 + + + ActiveOnMatch + Set channel to active level on match. OCyREF signal is forced high when the counter matches the capture/compare register + 1 + + + InactiveOnMatch + Set channel to inactive level on match. OCyREF signal is forced low when the counter matches the capture/compare register + 2 + + + Toggle + OCyREF toggles when TIMx_CNT=TIMx_CCRy + 3 + + + ForceInactive + OCyREF is forced low + 4 + + + ForceActive + OCyREF is forced high + 5 + + + PwmMode1 + In upcounting, channel is active as long as TIMx_CNT<TIMx_CCRy else inactive. In downcounting, channel is inactive as long as TIMx_CNT>TIMx_CCRy else active + 6 + + + PwmMode2 + Inversely to PwmMode1 + 7 + + + + + OC1PE + Output Compare 1 preload + enable + 3 + 1 + + + OC1FE + Output Compare 1 fast + enable + 2 + 1 + + + CC1S + Capture/Compare 1 + selection + 0 + 2 + + + + + CCMR1_Input + CCMR1_Input + capture/compare mode register 1 (input + mode) + CCMR1_Output + 0x18 + 0x20 + read-write + 0x00000000 + + + IC1F + Input capture 1 filter + 4 + 4 + + + IC1PSC + Input capture 1 prescaler + 2 + 2 + + + CC1S + Capture/Compare 1 + selection + 0 + 2 + + + + + CCER + CCER + capture/compare enable + register + 0x20 + 0x20 + read-write + 0x00000000 + + + CC1NP + Capture/Compare 1 output + Polarity + 3 + 1 + + + CC1P + Capture/Compare 1 output + Polarity + 1 + 1 + + + CC1E + Capture/Compare 1 output + enable + 0 + 1 + + + + + CNT + CNT + counter + 0x24 + 0x20 + read-write + 0x00000000 + + + CNT + counter value + 0 + 16 + + + + + PSC + PSC + prescaler + 0x28 + 0x20 + read-write + 0x00000000 + + + PSC + Prescaler value + 0 + 16 + + + 0 + 65535 + + + + + + + ARR + ARR + auto-reload register + 0x2C + 0x20 + read-write + 0x00000000 + + + ARR + Auto-reload value + 0 + 16 + + + + + 1 + 0x0 + 1-1 + CCR%s + CCR1 + capture/compare register + 0x34 + 0x20 + read-write + 0x00000000 + + + CCR + Capture/Compare value + 0 + 16 + + + + + + + TIM11 + General-purpose-timers + TIM + 0x40014800 + + 0x0 + 0x400 + registers + + + SPI2 + SPI2 global interrupt + 36 + + + + CR1 + CR1 + control register 1 + 0x0 + 0x20 + read-write + 0x00000000 + + + CKD + Clock division + 8 + 2 + + CKD + read-write + + Div1 + t_DTS = t_CK_INT + 0 + + + Div2 + t_DTS = 2 × t_CK_INT + 1 + + + Div4 + t_DTS = 4 × t_CK_INT + 2 + + + + + ARPE + Auto-reload preload enable + 7 + 1 + + ARPE + read-write + + Disabled + TIMx_APRR register is not buffered + 0 + + + Enabled + TIMx_APRR register is buffered + 1 + + + + + URS + Update request source + 2 + 1 + + URS + read-write + + AnyEvent + Any of counter overflow/underflow, setting UG, or update through slave mode, generates an update interrupt or DMA request + 0 + + + CounterOnly + Only counter overflow/underflow generates an update interrupt or DMA request + 1 + + + + + UDIS + Update disable + 1 + 1 + + UDIS + read-write + + Enabled + Update event enabled + 0 + + + Disabled + Update event disabled + 1 + + + + + CEN + Counter enable + 0 + 1 + + CEN + read-write + + Disabled + Counter disabled + 0 + + + Enabled + Counter enabled + 1 + + + + + OPM + One-pulse mode + 3 + 1 + + OPM + read-write + + Disabled + Counter is not stopped at update event + 0 + + + Enabled + Counter stops counting at the next update event (clearing the CEN bit) + 1 + + + + + + + DIER + DIER + DMA/Interrupt enable register + 0xC + 0x20 + read-write + 0x00000000 + + + CC1IE + Capture/Compare 1 interrupt + enable + 1 + 1 + + + UIE + Update interrupt enable + 0 + 1 + + UIE + read-write + + Disabled + Update interrupt disabled + 0 + + + Enabled + Update interrupt enabled + 1 + + + + + + + SR + SR + status register + 0x10 + 0x20 + read-write + 0x00000000 + + + CC1OF + Capture/Compare 1 overcapture + flag + 9 + 1 + + + CC1IF + Capture/compare 1 interrupt + flag + 1 + 1 + + + UIF + Update interrupt flag + 0 + 1 + zeroToClear + + UIFR + read + + NoUpdateOccurred + No update occurred + 0 + + + UpdatePending + Update interrupt pending + 1 + + + + UIFW + write + + Clear + Clear flag + 0 + + + + + + + EGR + EGR + event generation register + 0x14 + 0x20 + write-only + 0x00000000 + + + CC1G + Capture/compare 1 + generation + 1 + 1 + + + UG + Update generation + 0 + 1 + + UG + write + + Update + Re-initializes the timer counter and generates an update of the registers. + 1 + + + + + + + CCMR1_Output + CCMR1_Output + capture/compare mode register 1 (output + mode) + 0x18 + 0x20 + read-write + 0x00000000 + + + OC1M + Output Compare 1 mode + 4 + 3 + + OC1M + read-write + + Frozen + The comparison between the output compare register TIMx_CCRy and the counter TIMx_CNT has no effect on the outputs + 0 + + + ActiveOnMatch + Set channel to active level on match. OCyREF signal is forced high when the counter matches the capture/compare register + 1 + + + InactiveOnMatch + Set channel to inactive level on match. OCyREF signal is forced low when the counter matches the capture/compare register + 2 + + + Toggle + OCyREF toggles when TIMx_CNT=TIMx_CCRy + 3 + + + ForceInactive + OCyREF is forced low + 4 + + + ForceActive + OCyREF is forced high + 5 + + + PwmMode1 + In upcounting, channel is active as long as TIMx_CNT<TIMx_CCRy else inactive. In downcounting, channel is inactive as long as TIMx_CNT>TIMx_CCRy else active + 6 + + + PwmMode2 + Inversely to PwmMode1 + 7 + + + + + OC1PE + Output Compare 1 preload + enable + 3 + 1 + + + OC1FE + Output Compare 1 fast + enable + 2 + 1 + + + CC1S + Capture/Compare 1 + selection + 0 + 2 + + + + + CCMR1_Input + CCMR1_Input + capture/compare mode register 1 (input + mode) + CCMR1_Output + 0x18 + 0x20 + read-write + 0x00000000 + + + IC1F + Input capture 1 filter + 4 + 4 + + + IC1PSC + Input capture 1 prescaler + 2 + 2 + + + CC1S + Capture/Compare 1 + selection + 0 + 2 + + + + + CCER + CCER + capture/compare enable + register + 0x20 + 0x20 + read-write + 0x00000000 + + + CC1NP + Capture/Compare 1 output + Polarity + 3 + 1 + + + CC1P + Capture/Compare 1 output + Polarity + 1 + 1 + + + CC1E + Capture/Compare 1 output + enable + 0 + 1 + + + + + CNT + CNT + counter + 0x24 + 0x20 + read-write + 0x00000000 + + + CNT + counter value + 0 + 16 + + + + + PSC + PSC + prescaler + 0x28 + 0x20 + read-write + 0x00000000 + + + PSC + Prescaler value + 0 + 16 + + + 0 + 65535 + + + + + + + ARR + ARR + auto-reload register + 0x2C + 0x20 + read-write + 0x00000000 + + + ARR + Auto-reload value + 0 + 16 + + + + + 1 + 0x0 + 1-1 + CCR%s + CCR1 + capture/compare register + 0x34 + 0x20 + read-write + 0x00000000 + + + CCR + Capture/Compare value + 0 + 16 + + + + + OR + OR + option register + 0x50 + 0x20 + read-write + 0x00000000 + + + RMP + Input 1 remapping + capability + 0 + 2 + + + + + + + TIM2 + General purpose timers + TIM + 0x40000000 + + 0x0 + 0x400 + registers + + + SPI3 + SPI3 global interrupt + 51 + + + + CR1 + CR1 + control register 1 + 0x0 + 0x20 + read-write + 0x00000000 + + + CKD + Clock division + 8 + 2 + + CKD + read-write + + Div1 + t_DTS = t_CK_INT + 0 + + + Div2 + t_DTS = 2 × t_CK_INT + 1 + + + Div4 + t_DTS = 4 × t_CK_INT + 2 + + + + + ARPE + Auto-reload preload enable + 7 + 1 + + ARPE + read-write + + Disabled + TIMx_APRR register is not buffered + 0 + + + Enabled + TIMx_APRR register is buffered + 1 + + + + + CMS + Center-aligned mode + selection + 5 + 2 + + CMS + read-write + + EdgeAligned + The counter counts up or down depending on the direction bit + 0 + + + CenterAligned1 + The counter counts up and down alternatively. Output compare interrupt flags are set only when the counter is counting down. + 1 + + + CenterAligned2 + The counter counts up and down alternatively. Output compare interrupt flags are set only when the counter is counting up. + 2 + + + CenterAligned3 + The counter counts up and down alternatively. Output compare interrupt flags are set both when the counter is counting up or down. + 3 + + + + + DIR + Direction + 4 + 1 + + DIR + read-write + + Up + Counter used as upcounter + 0 + + + Down + Counter used as downcounter + 1 + + + + + OPM + One-pulse mode + 3 + 1 + + OPM + read-write + + Disabled + Counter is not stopped at update event + 0 + + + Enabled + Counter stops counting at the next update event (clearing the CEN bit) + 1 + + + + + URS + Update request source + 2 + 1 + + URS + read-write + + AnyEvent + Any of counter overflow/underflow, setting UG, or update through slave mode, generates an update interrupt or DMA request + 0 + + + CounterOnly + Only counter overflow/underflow generates an update interrupt or DMA request + 1 + + + + + UDIS + Update disable + 1 + 1 + + UDIS + read-write + + Enabled + Update event enabled + 0 + + + Disabled + Update event disabled + 1 + + + + + CEN + Counter enable + 0 + 1 + + CEN + read-write + + Disabled + Counter disabled + 0 + + + Enabled + Counter enabled + 1 + + + + + + + CR2 + CR2 + control register 2 + 0x4 + 0x20 + read-write + 0x00000000 + + + TI1S + TI1 selection + 7 + 1 + + TI1S + read-write + + Normal + The TIMx_CH1 pin is connected to TI1 input + 0 + + + XOR + The TIMx_CH1, CH2, CH3 pins are connected to TI1 input + 1 + + + + + MMS + Master mode selection + 4 + 3 + + MMS + read-write + + Reset + The UG bit from the TIMx_EGR register is used as trigger output + 0 + + + Enable + The counter enable signal, CNT_EN, is used as trigger output + 1 + + + Update + The update event is selected as trigger output + 2 + + + ComparePulse + The trigger output send a positive pulse when the CC1IF flag it to be set, as soon as a capture or a compare match occurred + 3 + + + CompareOC1 + OC1REF signal is used as trigger output + 4 + + + CompareOC2 + OC2REF signal is used as trigger output + 5 + + + CompareOC3 + OC3REF signal is used as trigger output + 6 + + + CompareOC4 + OC4REF signal is used as trigger output + 7 + + + + + CCDS + Capture/compare DMA + selection + 3 + 1 + + CCDS + read-write + + OnCompare + CCx DMA request sent when CCx event occurs + 0 + + + OnUpdate + CCx DMA request sent when update event occurs + 1 + + + + + + + SMCR + SMCR + slave mode control register + 0x8 + 0x20 + read-write + 0x00000000 + + + ETP + External trigger polarity + 15 + 1 + + ETP + read-write + + NotInverted + ETR is noninverted, active at high level or rising edge + 0 + + + Inverted + ETR is inverted, active at low level or falling edge + 1 + + + + + ECE + External clock enable + 14 + 1 + + ECE + read-write + + Disabled + External clock mode 2 disabled + 0 + + + Enabled + External clock mode 2 enabled. The counter is clocked by any active edge on the ETRF signal. + 1 + + + + + ETPS + External trigger prescaler + 12 + 2 + + ETPS + read-write + + Div1 + Prescaler OFF + 0 + + + Div2 + ETRP frequency divided by 2 + 1 + + + Div4 + ETRP frequency divided by 4 + 2 + + + Div8 + ETRP frequency divided by 8 + 3 + + + + + ETF + External trigger filter + 8 + 4 + + ETF + read-write + + NoFilter + No filter, sampling is done at fDTS + 0 + + + FCK_INT_N2 + fSAMPLING=fCK_INT, N=2 + 1 + + + FCK_INT_N4 + fSAMPLING=fCK_INT, N=4 + 2 + + + FCK_INT_N8 + fSAMPLING=fCK_INT, N=8 + 3 + + + FDTS_Div2_N6 + fSAMPLING=fDTS/2, N=6 + 4 + + + FDTS_Div2_N8 + fSAMPLING=fDTS/2, N=8 + 5 + + + FDTS_Div4_N6 + fSAMPLING=fDTS/4, N=6 + 6 + + + FDTS_Div4_N8 + fSAMPLING=fDTS/4, N=8 + 7 + + + FDTS_Div8_N6 + fSAMPLING=fDTS/8, N=6 + 8 + + + FDTS_Div8_N8 + fSAMPLING=fDTS/8, N=8 + 9 + + + FDTS_Div16_N5 + fSAMPLING=fDTS/16, N=5 + 10 + + + FDTS_Div16_N6 + fSAMPLING=fDTS/16, N=6 + 11 + + + FDTS_Div16_N8 + fSAMPLING=fDTS/16, N=8 + 12 + + + FDTS_Div32_N5 + fSAMPLING=fDTS/32, N=5 + 13 + + + FDTS_Div32_N6 + fSAMPLING=fDTS/32, N=6 + 14 + + + FDTS_Div32_N8 + fSAMPLING=fDTS/32, N=8 + 15 + + + + + MSM + Master/Slave mode + 7 + 1 + + MSM + read-write + + NoSync + No action + 0 + + + Sync + The effect of an event on the trigger input (TRGI) is delayed to allow a perfect synchronization between the current timer and its slaves (through TRGO). It is useful if we want to synchronize several timers on a single external event. + 1 + + + + + TS + Trigger selection + 4 + 3 + + TS + read-write + + ITR0 + Internal Trigger 0 (ITR0) + 0 + + + ITR1 + Internal Trigger 1 (ITR1) + 1 + + + ITR2 + Internal Trigger 2 (ITR2) + 2 + + + TI1F_ED + TI1 Edge Detector (TI1F_ED) + 4 + + + TI1FP1 + Filtered Timer Input 1 (TI1FP1) + 5 + + + TI2FP2 + Filtered Timer Input 2 (TI2FP2) + 6 + + + ETRF + External Trigger input (ETRF) + 7 + + + + + SMS + Slave mode selection + 0 + 3 + + SMS + read-write + + Disabled + Slave mode disabled - if CEN = ‘1 then the prescaler is clocked directly by the internal clock. + 0 + + + Encoder_Mode_1 + Encoder mode 1 - Counter counts up/down on TI2FP1 edge depending on TI1FP2 level. + 1 + + + Encoder_Mode_2 + Encoder mode 2 - Counter counts up/down on TI1FP2 edge depending on TI2FP1 level. + 2 + + + Encoder_Mode_3 + Encoder mode 3 - Counter counts up/down on both TI1FP1 and TI2FP2 edges depending on the level of the other input. + 3 + + + Reset_Mode + Reset Mode - Rising edge of the selected trigger input (TRGI) reinitializes the counter and generates an update of the registers. + 4 + + + Gated_Mode + Gated Mode - The counter clock is enabled when the trigger input (TRGI) is high. The counter stops (but is not reset) as soon as the trigger becomes low. Both start and stop of the counter are controlled. + 5 + + + Trigger_Mode + Trigger Mode - The counter starts at a rising edge of the trigger TRGI (but it is not reset). Only the start of the counter is controlled. + 6 + + + Ext_Clock_Mode + External Clock Mode 1 - Rising edges of the selected trigger (TRGI) clock the counter. + 7 + + + + + + + DIER + DIER + DMA/Interrupt enable register + 0xC + 0x20 + read-write + 0x00000000 + + + TDE + Trigger DMA request enable + 14 + 1 + + TDE + read-write + + Disabled + Trigger DMA request disabled + 0 + + + Enabled + Trigger DMA request enabled + 1 + + + + + CC4DE + Capture/Compare 4 DMA request + enable + 12 + 1 + + + + CC3DE + Capture/Compare 3 DMA request + enable + 11 + 1 + + + + CC2DE + Capture/Compare 2 DMA request + enable + 10 + 1 + + + + CC1DE + Capture/Compare 1 DMA request + enable + 9 + 1 + + CC1DE + read-write + + Disabled + CCx DMA request disabled + 0 + + + Enabled + CCx DMA request enabled + 1 + + + + + UDE + Update DMA request enable + 8 + 1 + + UDE + read-write + + Disabled + Update DMA request disabled + 0 + + + Enabled + Update DMA request enabled + 1 + + + + + TIE + Trigger interrupt enable + 6 + 1 + + TIE + read-write + + Disabled + Trigger interrupt disabled + 0 + + + Enabled + Trigger interrupt enabled + 1 + + + + + CC4IE + Capture/Compare 4 interrupt + enable + 4 + 1 + + + + CC3IE + Capture/Compare 3 interrupt + enable + 3 + 1 + + + + CC2IE + Capture/Compare 2 interrupt + enable + 2 + 1 + + + + CC1IE + Capture/Compare 1 interrupt + enable + 1 + 1 + + CC1IE + read-write + + Disabled + CCx interrupt disabled + 0 + + + Enabled + CCx interrupt enabled + 1 + + + + + UIE + Update interrupt enable + 0 + 1 + + UIE + read-write + + Disabled + Update interrupt disabled + 0 + + + Enabled + Update interrupt enabled + 1 + + + + + + + SR + SR + status register + 0x10 + 0x20 + read-write + 0x00000000 + + + CC4OF + Capture/Compare 4 overcapture + flag + 12 + 1 + zeroToClear + + read + + + write + + + + CC3OF + Capture/Compare 3 overcapture + flag + 11 + 1 + zeroToClear + + read + + + write + + + + CC2OF + Capture/compare 2 overcapture + flag + 10 + 1 + zeroToClear + + read + + + write + + + + CC1OF + Capture/Compare 1 overcapture + flag + 9 + 1 + zeroToClear + + CC1OFR + read + + Overcapture + The counter value has been captured in TIMx_CCRx register while CCxIF flag was already set + 1 + + + + CC1OFW + write + + Clear + Clear flag + 0 + + + + + TIF + Trigger interrupt flag + 6 + 1 + zeroToClear + + TIFR + read + + NoTrigger + No trigger event occurred + 0 + + + Trigger + Trigger interrupt pending + 1 + + + + TIFW + write + + Clear + Clear flag + 0 + + + + + CC4IF + Capture/Compare 4 interrupt + flag + 4 + 1 + zeroToClear + + read + + + write + + + + CC3IF + Capture/Compare 3 interrupt + flag + 3 + 1 + zeroToClear + + read + + + write + + + + CC2IF + Capture/Compare 2 interrupt + flag + 2 + 1 + zeroToClear + + read + + + write + + + + CC1IF + Capture/compare 1 interrupt + flag + 1 + 1 + zeroToClear + + CC1IFR + read + + Match + If CC1 is an output: The content of the counter TIMx_CNT matches the content of the TIMx_CCR1 register. If CC1 is an input: The counter value has been captured in TIMx_CCR1 register. + 1 + + + + CC1IFW + write + + Clear + Clear flag + 0 + + + + + UIF + Update interrupt flag + 0 + 1 + zeroToClear + + UIFR + read + + NoUpdateOccurred + No update occurred + 0 + + + UpdatePending + Update interrupt pending + 1 + + + + UIFW + write + + Clear + Clear flag + 0 + + + + + + + EGR + EGR + event generation register + 0x14 + 0x20 + write-only + 0x00000000 + + + TG + Trigger generation + 6 + 1 + + TGW + write + + Trigger + The TIF flag is set in TIMx_SR register. Related interrupt or DMA transfer can occur if enabled. + 1 + + + + + CC4G + Capture/compare 4 + generation + 4 + 1 + + + + CC3G + Capture/compare 3 + generation + 3 + 1 + + + + CC2G + Capture/compare 2 + generation + 2 + 1 + + + + CC1G + Capture/compare 1 + generation + 1 + 1 + + CC1GW + write + + Trigger + If CC1 is an output: CC1IF flag is set, Corresponding interrupt or DMA request is sent if enabled. If CC1 is an input: The current value of the counter is captured in TIMx_CCR1 register. + 1 + + + + + UG + Update generation + 0 + 1 + + UG + write + + Update + Re-initializes the timer counter and generates an update of the registers. + 1 + + + + + + + CCMR1_Output + CCMR1_Output + capture/compare mode register 1 (output + mode) + 0x18 + 0x20 + read-write + 0x00000000 + + + OC2CE + OC2CE + 15 + 1 + + + OC2M + OC2M + 12 + 3 + + + + OC2PE + OC2PE + 11 + 1 + + OC2PE + read-write + + Disabled + Preload register on CCR2 disabled. New values written to CCR2 are taken into account immediately + 0 + + + Enabled + Preload register on CCR2 enabled. Preload value is loaded into active register on each update event + 1 + + + + + OC2FE + OC2FE + 10 + 1 + + + CC2S + CC2S + 8 + 2 + + CC2S + read-write + + Output + CC2 channel is configured as output + 0 + + + + + OC1CE + OC1CE + 7 + 1 + + + OC1M + OC1M + 4 + 3 + + OC1M + read-write + + Frozen + The comparison between the output compare register TIMx_CCRy and the counter TIMx_CNT has no effect on the outputs + 0 + + + ActiveOnMatch + Set channel to active level on match. OCyREF signal is forced high when the counter matches the capture/compare register + 1 + + + InactiveOnMatch + Set channel to inactive level on match. OCyREF signal is forced low when the counter matches the capture/compare register + 2 + + + Toggle + OCyREF toggles when TIMx_CNT=TIMx_CCRy + 3 + + + ForceInactive + OCyREF is forced low + 4 + + + ForceActive + OCyREF is forced high + 5 + + + PwmMode1 + In upcounting, channel is active as long as TIMx_CNT<TIMx_CCRy else inactive. In downcounting, channel is inactive as long as TIMx_CNT>TIMx_CCRy else active + 6 + + + PwmMode2 + Inversely to PwmMode1 + 7 + + + + + OC1PE + OC1PE + 3 + 1 + + OC1PE + read-write + + Disabled + Preload register on CCR1 disabled. New values written to CCR1 are taken into account immediately + 0 + + + Enabled + Preload register on CCR1 enabled. Preload value is loaded into active register on each update event + 1 + + + + + OC1FE + OC1FE + 2 + 1 + + + CC1S + CC1S + 0 + 2 + + CC1S + read-write + + Output + CC1 channel is configured as output + 0 + + + + + + + CCMR1_Input + CCMR1_Input + capture/compare mode register 1 (input + mode) + CCMR1_Output + 0x18 + 0x20 + read-write + 0x00000000 + + + IC2F + Input capture 2 filter + 12 + 4 + + + 0 + 15 + + + + + IC2PSC + Input capture 2 prescaler + 10 + 2 + + + CC2S + Capture/Compare 2 + selection + 8 + 2 + + CC2S + read-write + + TI2 + CC2 channel is configured as input, IC2 is mapped on TI2 + 1 + + + TI1 + CC2 channel is configured as input, IC2 is mapped on TI1 + 2 + + + TRC + CC2 channel is configured as input, IC2 is mapped on TRC + 3 + + + + + IC1F + Input capture 1 filter + 4 + 4 + + IC1F + read-write + + NoFilter + No filter, sampling is done at fDTS + 0 + + + FCK_INT_N2 + fSAMPLING=fCK_INT, N=2 + 1 + + + FCK_INT_N4 + fSAMPLING=fCK_INT, N=4 + 2 + + + FCK_INT_N8 + fSAMPLING=fCK_INT, N=8 + 3 + + + FDTS_Div2_N6 + fSAMPLING=fDTS/2, N=6 + 4 + + + FDTS_Div2_N8 + fSAMPLING=fDTS/2, N=8 + 5 + + + FDTS_Div4_N6 + fSAMPLING=fDTS/4, N=6 + 6 + + + FDTS_Div4_N8 + fSAMPLING=fDTS/4, N=8 + 7 + + + FDTS_Div8_N6 + fSAMPLING=fDTS/8, N=6 + 8 + + + FDTS_Div8_N8 + fSAMPLING=fDTS/8, N=8 + 9 + + + FDTS_Div16_N5 + fSAMPLING=fDTS/16, N=5 + 10 + + + FDTS_Div16_N6 + fSAMPLING=fDTS/16, N=6 + 11 + + + FDTS_Div16_N8 + fSAMPLING=fDTS/16, N=8 + 12 + + + FDTS_Div32_N5 + fSAMPLING=fDTS/32, N=5 + 13 + + + FDTS_Div32_N6 + fSAMPLING=fDTS/32, N=6 + 14 + + + FDTS_Div32_N8 + fSAMPLING=fDTS/32, N=8 + 15 + + + + + IC1PSC + Input capture 1 prescaler + 2 + 2 + + + CC1S + Capture/Compare 1 + selection + 0 + 2 + + CC1S + read-write + + TI1 + CC1 channel is configured as input, IC1 is mapped on TI1 + 1 + + + TI2 + CC1 channel is configured as input, IC1 is mapped on TI2 + 2 + + + TRC + CC1 channel is configured as input, IC1 is mapped on TRC + 3 + + + + + + + CCMR2_Output + CCMR2_Output + capture/compare mode register 2 (output + mode) + 0x1C + 0x20 + read-write + 0x00000000 + + + OC4CE + O24CE + 15 + 1 + + + OC4M + OC4M + 12 + 3 + + + + OC4PE + OC4PE + 11 + 1 + + OC4PE + read-write + + Disabled + Preload register on CCR4 disabled. New values written to CCR4 are taken into account immediately + 0 + + + Enabled + Preload register on CCR4 enabled. Preload value is loaded into active register on each update event + 1 + + + + + OC4FE + OC4FE + 10 + 1 + + + CC4S + CC4S + 8 + 2 + + CC4S + read-write + + Output + CC4 channel is configured as output + 0 + + + + + OC3CE + OC3CE + 7 + 1 + + + OC3M + OC3M + 4 + 3 + + OC3M + read-write + + Frozen + The comparison between the output compare register TIMx_CCRy and the counter TIMx_CNT has no effect on the outputs + 0 + + + ActiveOnMatch + Set channel to active level on match. OCyREF signal is forced high when the counter matches the capture/compare register + 1 + + + InactiveOnMatch + Set channel to inactive level on match. OCyREF signal is forced low when the counter matches the capture/compare register + 2 + + + Toggle + OCyREF toggles when TIMx_CNT=TIMx_CCRy + 3 + + + ForceInactive + OCyREF is forced low + 4 + + + ForceActive + OCyREF is forced high + 5 + + + PwmMode1 + In upcounting, channel is active as long as TIMx_CNT<TIMx_CCRy else inactive. In downcounting, channel is inactive as long as TIMx_CNT>TIMx_CCRy else active + 6 + + + PwmMode2 + Inversely to PwmMode1 + 7 + + + + + OC3PE + OC3PE + 3 + 1 + + OC3PE + read-write + + Disabled + Preload register on CCR3 disabled. New values written to CCR3 are taken into account immediately + 0 + + + Enabled + Preload register on CCR3 enabled. Preload value is loaded into active register on each update event + 1 + + + + + OC3FE + OC3FE + 2 + 1 + + + CC3S + CC3S + 0 + 2 + + CC3S + read-write + + Output + CC3 channel is configured as output + 0 + + + + + + + CCMR2_Input + CCMR2_Input + capture/compare mode register 2 (input + mode) + CCMR2_Output + 0x1C + 0x20 + read-write + 0x00000000 + + + IC4F + Input capture 4 filter + 12 + 4 + + + 0 + 15 + + + + + IC4PSC + Input capture 4 prescaler + 10 + 2 + + + 0 + 3 + + + + + CC4S + Capture/Compare 4 + selection + 8 + 2 + + CC4S + read-write + + TI4 + CC4 channel is configured as input, IC4 is mapped on TI4 + 1 + + + TI3 + CC4 channel is configured as input, IC4 is mapped on TI3 + 2 + + + TRC + CC4 channel is configured as input, IC4 is mapped on TRC + 3 + + + + + IC3F + Input capture 3 filter + 4 + 4 + + + 0 + 15 + + + + + IC3PSC + Input capture 3 prescaler + 2 + 2 + + + 0 + 3 + + + + + CC3S + Capture/compare 3 + selection + 0 + 2 + + CC3S + read-write + + TI3 + CC3 channel is configured as input, IC3 is mapped on TI3 + 1 + + + TI4 + CC3 channel is configured as input, IC3 is mapped on TI4 + 2 + + + TRC + CC3 channel is configured as input, IC3 is mapped on TRC + 3 + + + + + + + CCER + CCER + capture/compare enable + register + 0x20 + 0x20 + read-write + 0x00000000 + + + CC4NP + Capture/Compare 4 output + Polarity + 15 + 1 + + + CC4P + Capture/Compare 3 output + Polarity + 13 + 1 + + + CC4E + Capture/Compare 4 output + enable + 12 + 1 + + + CC3NP + Capture/Compare 3 output + Polarity + 11 + 1 + + + CC3P + Capture/Compare 3 output + Polarity + 9 + 1 + + + CC3E + Capture/Compare 3 output + enable + 8 + 1 + + + CC2NP + Capture/Compare 2 output + Polarity + 7 + 1 + + + CC2P + Capture/Compare 2 output + Polarity + 5 + 1 + + + CC2E + Capture/Compare 2 output + enable + 4 + 1 + + + CC1NP + Capture/Compare 1 output + Polarity + 3 + 1 + + + CC1P + Capture/Compare 1 output + Polarity + 1 + 1 + + + CC1E + Capture/Compare 1 output + enable + 0 + 1 + + + + + CNT + CNT + counter + 0x24 + 0x20 + read-write + 0x00000000 + + + CNT + Counter value + 0 + 32 + + + 0 + 4294967295 + + + + + + + PSC + PSC + prescaler + 0x28 + 0x20 + read-write + 0x00000000 + + + PSC + Prescaler value + 0 + 16 + + + 0 + 65535 + + + + + + + ARR + ARR + auto-reload register + 0x2C + 0x20 + read-write + 0x00000000 + + + ARR + Auto-reload value + 0 + 32 + + + 0 + 4294967295 + + + + + + + 4 + 0x4 + 1-4 + CCR%s + CCR1 + capture/compare register + 0x34 + 0x20 + read-write + 0x00000000 + + + CCR + Capture/Compare value + 0 + 32 + + + 0 + 4294967295 + + + + + + + DCR + DCR + DMA control register + 0x48 + 0x20 + read-write + 0x00000000 + + + DBL + DMA burst length + 8 + 5 + + + 0 + 18 + + + + + DBA + DMA base address + 0 + 5 + + + 0 + 31 + + + + + + + DMAR + DMAR + DMA address for full transfer + 0x4C + 0x20 + read-write + 0x00000000 + + + DMAB + DMA register for burst + accesses + 0 + 16 + + + + + OR + OR + TIM5 option register + 0x50 + 0x20 + read-write + 0x00000000 + + + ITR1_RMP + Timer Input 4 remap + 10 + 2 + + + + + + + TIM3 + General purpose timers + TIM + 0x40000400 + + 0x0 + 0x400 + registers + + + SPI4 + SPI4 global interrupt + 84 + + + TIM4 + TIM4 global interrupt + 30 + + + TIM5 + TIM5 global interrupt + 50 + + + + CR1 + CR1 + control register 1 + 0x0 + 0x20 + read-write + 0x00000000 + + + CKD + Clock division + 8 + 2 + + CKD + read-write + + Div1 + t_DTS = t_CK_INT + 0 + + + Div2 + t_DTS = 2 × t_CK_INT + 1 + + + Div4 + t_DTS = 4 × t_CK_INT + 2 + + + + + ARPE + Auto-reload preload enable + 7 + 1 + + ARPE + read-write + + Disabled + TIMx_APRR register is not buffered + 0 + + + Enabled + TIMx_APRR register is buffered + 1 + + + + + CMS + Center-aligned mode + selection + 5 + 2 + + CMS + read-write + + EdgeAligned + The counter counts up or down depending on the direction bit + 0 + + + CenterAligned1 + The counter counts up and down alternatively. Output compare interrupt flags are set only when the counter is counting down. + 1 + + + CenterAligned2 + The counter counts up and down alternatively. Output compare interrupt flags are set only when the counter is counting up. + 2 + + + CenterAligned3 + The counter counts up and down alternatively. Output compare interrupt flags are set both when the counter is counting up or down. + 3 + + + + + DIR + Direction + 4 + 1 + + DIR + read-write + + Up + Counter used as upcounter + 0 + + + Down + Counter used as downcounter + 1 + + + + + OPM + One-pulse mode + 3 + 1 + + OPM + read-write + + Disabled + Counter is not stopped at update event + 0 + + + Enabled + Counter stops counting at the next update event (clearing the CEN bit) + 1 + + + + + URS + Update request source + 2 + 1 + + URS + read-write + + AnyEvent + Any of counter overflow/underflow, setting UG, or update through slave mode, generates an update interrupt or DMA request + 0 + + + CounterOnly + Only counter overflow/underflow generates an update interrupt or DMA request + 1 + + + + + UDIS + Update disable + 1 + 1 + + UDIS + read-write + + Enabled + Update event enabled + 0 + + + Disabled + Update event disabled + 1 + + + + + CEN + Counter enable + 0 + 1 + + CEN + read-write + + Disabled + Counter disabled + 0 + + + Enabled + Counter enabled + 1 + + + + + + + CR2 + CR2 + control register 2 + 0x4 + 0x20 + read-write + 0x00000000 + + + TI1S + TI1 selection + 7 + 1 + + TI1S + read-write + + Normal + The TIMx_CH1 pin is connected to TI1 input + 0 + + + XOR + The TIMx_CH1, CH2, CH3 pins are connected to TI1 input + 1 + + + + + MMS + Master mode selection + 4 + 3 + + MMS + read-write + + Reset + The UG bit from the TIMx_EGR register is used as trigger output + 0 + + + Enable + The counter enable signal, CNT_EN, is used as trigger output + 1 + + + Update + The update event is selected as trigger output + 2 + + + ComparePulse + The trigger output send a positive pulse when the CC1IF flag it to be set, as soon as a capture or a compare match occurred + 3 + + + CompareOC1 + OC1REF signal is used as trigger output + 4 + + + CompareOC2 + OC2REF signal is used as trigger output + 5 + + + CompareOC3 + OC3REF signal is used as trigger output + 6 + + + CompareOC4 + OC4REF signal is used as trigger output + 7 + + + + + CCDS + Capture/compare DMA + selection + 3 + 1 + + CCDS + read-write + + OnCompare + CCx DMA request sent when CCx event occurs + 0 + + + OnUpdate + CCx DMA request sent when update event occurs + 1 + + + + + + + SMCR + SMCR + slave mode control register + 0x8 + 0x20 + read-write + 0x00000000 + + + ETP + External trigger polarity + 15 + 1 + + ETP + read-write + + NotInverted + ETR is noninverted, active at high level or rising edge + 0 + + + Inverted + ETR is inverted, active at low level or falling edge + 1 + + + + + ECE + External clock enable + 14 + 1 + + ECE + read-write + + Disabled + External clock mode 2 disabled + 0 + + + Enabled + External clock mode 2 enabled. The counter is clocked by any active edge on the ETRF signal. + 1 + + + + + ETPS + External trigger prescaler + 12 + 2 + + ETPS + read-write + + Div1 + Prescaler OFF + 0 + + + Div2 + ETRP frequency divided by 2 + 1 + + + Div4 + ETRP frequency divided by 4 + 2 + + + Div8 + ETRP frequency divided by 8 + 3 + + + + + ETF + External trigger filter + 8 + 4 + + ETF + read-write + + NoFilter + No filter, sampling is done at fDTS + 0 + + + FCK_INT_N2 + fSAMPLING=fCK_INT, N=2 + 1 + + + FCK_INT_N4 + fSAMPLING=fCK_INT, N=4 + 2 + + + FCK_INT_N8 + fSAMPLING=fCK_INT, N=8 + 3 + + + FDTS_Div2_N6 + fSAMPLING=fDTS/2, N=6 + 4 + + + FDTS_Div2_N8 + fSAMPLING=fDTS/2, N=8 + 5 + + + FDTS_Div4_N6 + fSAMPLING=fDTS/4, N=6 + 6 + + + FDTS_Div4_N8 + fSAMPLING=fDTS/4, N=8 + 7 + + + FDTS_Div8_N6 + fSAMPLING=fDTS/8, N=6 + 8 + + + FDTS_Div8_N8 + fSAMPLING=fDTS/8, N=8 + 9 + + + FDTS_Div16_N5 + fSAMPLING=fDTS/16, N=5 + 10 + + + FDTS_Div16_N6 + fSAMPLING=fDTS/16, N=6 + 11 + + + FDTS_Div16_N8 + fSAMPLING=fDTS/16, N=8 + 12 + + + FDTS_Div32_N5 + fSAMPLING=fDTS/32, N=5 + 13 + + + FDTS_Div32_N6 + fSAMPLING=fDTS/32, N=6 + 14 + + + FDTS_Div32_N8 + fSAMPLING=fDTS/32, N=8 + 15 + + + + + MSM + Master/Slave mode + 7 + 1 + + MSM + read-write + + NoSync + No action + 0 + + + Sync + The effect of an event on the trigger input (TRGI) is delayed to allow a perfect synchronization between the current timer and its slaves (through TRGO). It is useful if we want to synchronize several timers on a single external event. + 1 + + + + + TS + Trigger selection + 4 + 3 + + TS + read-write + + ITR0 + Internal Trigger 0 (ITR0) + 0 + + + ITR1 + Internal Trigger 1 (ITR1) + 1 + + + ITR2 + Internal Trigger 2 (ITR2) + 2 + + + TI1F_ED + TI1 Edge Detector (TI1F_ED) + 4 + + + TI1FP1 + Filtered Timer Input 1 (TI1FP1) + 5 + + + TI2FP2 + Filtered Timer Input 2 (TI2FP2) + 6 + + + ETRF + External Trigger input (ETRF) + 7 + + + + + SMS + Slave mode selection + 0 + 3 + + SMS + read-write + + Disabled + Slave mode disabled - if CEN = ‘1 then the prescaler is clocked directly by the internal clock. + 0 + + + Encoder_Mode_1 + Encoder mode 1 - Counter counts up/down on TI2FP1 edge depending on TI1FP2 level. + 1 + + + Encoder_Mode_2 + Encoder mode 2 - Counter counts up/down on TI1FP2 edge depending on TI2FP1 level. + 2 + + + Encoder_Mode_3 + Encoder mode 3 - Counter counts up/down on both TI1FP1 and TI2FP2 edges depending on the level of the other input. + 3 + + + Reset_Mode + Reset Mode - Rising edge of the selected trigger input (TRGI) reinitializes the counter and generates an update of the registers. + 4 + + + Gated_Mode + Gated Mode - The counter clock is enabled when the trigger input (TRGI) is high. The counter stops (but is not reset) as soon as the trigger becomes low. Both start and stop of the counter are controlled. + 5 + + + Trigger_Mode + Trigger Mode - The counter starts at a rising edge of the trigger TRGI (but it is not reset). Only the start of the counter is controlled. + 6 + + + Ext_Clock_Mode + External Clock Mode 1 - Rising edges of the selected trigger (TRGI) clock the counter. + 7 + + + + + + + DIER + DIER + DMA/Interrupt enable register + 0xC + 0x20 + read-write + 0x00000000 + + + TDE + Trigger DMA request enable + 14 + 1 + + TDE + read-write + + Disabled + Trigger DMA request disabled + 0 + + + Enabled + Trigger DMA request enabled + 1 + + + + + CC4DE + Capture/Compare 4 DMA request + enable + 12 + 1 + + + + CC3DE + Capture/Compare 3 DMA request + enable + 11 + 1 + + + + CC2DE + Capture/Compare 2 DMA request + enable + 10 + 1 + + + + CC1DE + Capture/Compare 1 DMA request + enable + 9 + 1 + + CC1DE + read-write + + Disabled + CCx DMA request disabled + 0 + + + Enabled + CCx DMA request enabled + 1 + + + + + UDE + Update DMA request enable + 8 + 1 + + UDE + read-write + + Disabled + Update DMA request disabled + 0 + + + Enabled + Update DMA request enabled + 1 + + + + + TIE + Trigger interrupt enable + 6 + 1 + + TIE + read-write + + Disabled + Trigger interrupt disabled + 0 + + + Enabled + Trigger interrupt enabled + 1 + + + + + CC4IE + Capture/Compare 4 interrupt + enable + 4 + 1 + + + + CC3IE + Capture/Compare 3 interrupt + enable + 3 + 1 + + + + CC2IE + Capture/Compare 2 interrupt + enable + 2 + 1 + + + + CC1IE + Capture/Compare 1 interrupt + enable + 1 + 1 + + CC1IE + read-write + + Disabled + CCx interrupt disabled + 0 + + + Enabled + CCx interrupt enabled + 1 + + + + + UIE + Update interrupt enable + 0 + 1 + + UIE + read-write + + Disabled + Update interrupt disabled + 0 + + + Enabled + Update interrupt enabled + 1 + + + + + + + SR + SR + status register + 0x10 + 0x20 + read-write + 0x00000000 + + + CC4OF + Capture/Compare 4 overcapture + flag + 12 + 1 + zeroToClear + + read + + + write + + + + CC3OF + Capture/Compare 3 overcapture + flag + 11 + 1 + zeroToClear + + read + + + write + + + + CC2OF + Capture/compare 2 overcapture + flag + 10 + 1 + zeroToClear + + read + + + write + + + + CC1OF + Capture/Compare 1 overcapture + flag + 9 + 1 + zeroToClear + + CC1OFR + read + + Overcapture + The counter value has been captured in TIMx_CCRx register while CCxIF flag was already set + 1 + + + + CC1OFW + write + + Clear + Clear flag + 0 + + + + + TIF + Trigger interrupt flag + 6 + 1 + zeroToClear + + TIFR + read + + NoTrigger + No trigger event occurred + 0 + + + Trigger + Trigger interrupt pending + 1 + + + + TIFW + write + + Clear + Clear flag + 0 + + + + + CC4IF + Capture/Compare 4 interrupt + flag + 4 + 1 + zeroToClear + + read + + + write + + + + CC3IF + Capture/Compare 3 interrupt + flag + 3 + 1 + zeroToClear + + read + + + write + + + + CC2IF + Capture/Compare 2 interrupt + flag + 2 + 1 + zeroToClear + + read + + + write + + + + CC1IF + Capture/compare 1 interrupt + flag + 1 + 1 + zeroToClear + + CC1IFR + read + + Match + If CC1 is an output: The content of the counter TIMx_CNT matches the content of the TIMx_CCR1 register. If CC1 is an input: The counter value has been captured in TIMx_CCR1 register. + 1 + + + + CC1IFW + write + + Clear + Clear flag + 0 + + + + + UIF + Update interrupt flag + 0 + 1 + zeroToClear + + UIFR + read + + NoUpdateOccurred + No update occurred + 0 + + + UpdatePending + Update interrupt pending + 1 + + + + UIFW + write + + Clear + Clear flag + 0 + + + + + + + EGR + EGR + event generation register + 0x14 + 0x20 + write-only + 0x00000000 + + + TG + Trigger generation + 6 + 1 + + TGW + write + + Trigger + The TIF flag is set in TIMx_SR register. Related interrupt or DMA transfer can occur if enabled. + 1 + + + + + CC4G + Capture/compare 4 + generation + 4 + 1 + + + + CC3G + Capture/compare 3 + generation + 3 + 1 + + + + CC2G + Capture/compare 2 + generation + 2 + 1 + + + + CC1G + Capture/compare 1 + generation + 1 + 1 + + CC1GW + write + + Trigger + If CC1 is an output: CC1IF flag is set, Corresponding interrupt or DMA request is sent if enabled. If CC1 is an input: The current value of the counter is captured in TIMx_CCR1 register. + 1 + + + + + UG + Update generation + 0 + 1 + + UG + write + + Update + Re-initializes the timer counter and generates an update of the registers. + 1 + + + + + + + CCMR1_Output + CCMR1_Output + capture/compare mode register 1 (output + mode) + 0x18 + 0x20 + read-write + 0x00000000 + + + OC2CE + OC2CE + 15 + 1 + + + OC2M + OC2M + 12 + 3 + + + + OC2PE + OC2PE + 11 + 1 + + OC2PE + read-write + + Disabled + Preload register on CCR2 disabled. New values written to CCR2 are taken into account immediately + 0 + + + Enabled + Preload register on CCR2 enabled. Preload value is loaded into active register on each update event + 1 + + + + + OC2FE + OC2FE + 10 + 1 + + + CC2S + CC2S + 8 + 2 + + CC2S + read-write + + Output + CC2 channel is configured as output + 0 + + + + + OC1CE + OC1CE + 7 + 1 + + + OC1M + OC1M + 4 + 3 + + OC1M + read-write + + Frozen + The comparison between the output compare register TIMx_CCRy and the counter TIMx_CNT has no effect on the outputs + 0 + + + ActiveOnMatch + Set channel to active level on match. OCyREF signal is forced high when the counter matches the capture/compare register + 1 + + + InactiveOnMatch + Set channel to inactive level on match. OCyREF signal is forced low when the counter matches the capture/compare register + 2 + + + Toggle + OCyREF toggles when TIMx_CNT=TIMx_CCRy + 3 + + + ForceInactive + OCyREF is forced low + 4 + + + ForceActive + OCyREF is forced high + 5 + + + PwmMode1 + In upcounting, channel is active as long as TIMx_CNT<TIMx_CCRy else inactive. In downcounting, channel is inactive as long as TIMx_CNT>TIMx_CCRy else active + 6 + + + PwmMode2 + Inversely to PwmMode1 + 7 + + + + + OC1PE + OC1PE + 3 + 1 + + OC1PE + read-write + + Disabled + Preload register on CCR1 disabled. New values written to CCR1 are taken into account immediately + 0 + + + Enabled + Preload register on CCR1 enabled. Preload value is loaded into active register on each update event + 1 + + + + + OC1FE + OC1FE + 2 + 1 + + + CC1S + CC1S + 0 + 2 + + CC1S + read-write + + Output + CC1 channel is configured as output + 0 + + + + + + + CCMR1_Input + CCMR1_Input + capture/compare mode register 1 (input + mode) + CCMR1_Output + 0x18 + 0x20 + read-write + 0x00000000 + + + IC2F + Input capture 2 filter + 12 + 4 + + + 0 + 15 + + + + + IC2PSC + Input capture 2 prescaler + 10 + 2 + + + CC2S + Capture/Compare 2 + selection + 8 + 2 + + CC2S + read-write + + TI2 + CC2 channel is configured as input, IC2 is mapped on TI2 + 1 + + + TI1 + CC2 channel is configured as input, IC2 is mapped on TI1 + 2 + + + TRC + CC2 channel is configured as input, IC2 is mapped on TRC + 3 + + + + + IC1F + Input capture 1 filter + 4 + 4 + + IC1F + read-write + + NoFilter + No filter, sampling is done at fDTS + 0 + + + FCK_INT_N2 + fSAMPLING=fCK_INT, N=2 + 1 + + + FCK_INT_N4 + fSAMPLING=fCK_INT, N=4 + 2 + + + FCK_INT_N8 + fSAMPLING=fCK_INT, N=8 + 3 + + + FDTS_Div2_N6 + fSAMPLING=fDTS/2, N=6 + 4 + + + FDTS_Div2_N8 + fSAMPLING=fDTS/2, N=8 + 5 + + + FDTS_Div4_N6 + fSAMPLING=fDTS/4, N=6 + 6 + + + FDTS_Div4_N8 + fSAMPLING=fDTS/4, N=8 + 7 + + + FDTS_Div8_N6 + fSAMPLING=fDTS/8, N=6 + 8 + + + FDTS_Div8_N8 + fSAMPLING=fDTS/8, N=8 + 9 + + + FDTS_Div16_N5 + fSAMPLING=fDTS/16, N=5 + 10 + + + FDTS_Div16_N6 + fSAMPLING=fDTS/16, N=6 + 11 + + + FDTS_Div16_N8 + fSAMPLING=fDTS/16, N=8 + 12 + + + FDTS_Div32_N5 + fSAMPLING=fDTS/32, N=5 + 13 + + + FDTS_Div32_N6 + fSAMPLING=fDTS/32, N=6 + 14 + + + FDTS_Div32_N8 + fSAMPLING=fDTS/32, N=8 + 15 + + + + + IC1PSC + Input capture 1 prescaler + 2 + 2 + + + CC1S + Capture/Compare 1 + selection + 0 + 2 + + CC1S + read-write + + TI1 + CC1 channel is configured as input, IC1 is mapped on TI1 + 1 + + + TI2 + CC1 channel is configured as input, IC1 is mapped on TI2 + 2 + + + TRC + CC1 channel is configured as input, IC1 is mapped on TRC + 3 + + + + + + + CCMR2_Output + CCMR2_Output + capture/compare mode register 2 (output + mode) + 0x1C + 0x20 + read-write + 0x00000000 + + + OC4CE + O24CE + 15 + 1 + + + OC4M + OC4M + 12 + 3 + + + + OC4PE + OC4PE + 11 + 1 + + OC4PE + read-write + + Disabled + Preload register on CCR4 disabled. New values written to CCR4 are taken into account immediately + 0 + + + Enabled + Preload register on CCR4 enabled. Preload value is loaded into active register on each update event + 1 + + + + + OC4FE + OC4FE + 10 + 1 + + + CC4S + CC4S + 8 + 2 + + CC4S + read-write + + Output + CC4 channel is configured as output + 0 + + + + + OC3CE + OC3CE + 7 + 1 + + + OC3M + OC3M + 4 + 3 + + OC3M + read-write + + Frozen + The comparison between the output compare register TIMx_CCRy and the counter TIMx_CNT has no effect on the outputs + 0 + + + ActiveOnMatch + Set channel to active level on match. OCyREF signal is forced high when the counter matches the capture/compare register + 1 + + + InactiveOnMatch + Set channel to inactive level on match. OCyREF signal is forced low when the counter matches the capture/compare register + 2 + + + Toggle + OCyREF toggles when TIMx_CNT=TIMx_CCRy + 3 + + + ForceInactive + OCyREF is forced low + 4 + + + ForceActive + OCyREF is forced high + 5 + + + PwmMode1 + In upcounting, channel is active as long as TIMx_CNT<TIMx_CCRy else inactive. In downcounting, channel is inactive as long as TIMx_CNT>TIMx_CCRy else active + 6 + + + PwmMode2 + Inversely to PwmMode1 + 7 + + + + + OC3PE + OC3PE + 3 + 1 + + OC3PE + read-write + + Disabled + Preload register on CCR3 disabled. New values written to CCR3 are taken into account immediately + 0 + + + Enabled + Preload register on CCR3 enabled. Preload value is loaded into active register on each update event + 1 + + + + + OC3FE + OC3FE + 2 + 1 + + + CC3S + CC3S + 0 + 2 + + CC3S + read-write + + Output + CC3 channel is configured as output + 0 + + + + + + + CCMR2_Input + CCMR2_Input + capture/compare mode register 2 (input + mode) + CCMR2_Output + 0x1C + 0x20 + read-write + 0x00000000 + + + IC4F + Input capture 4 filter + 12 + 4 + + + 0 + 15 + + + + + IC4PSC + Input capture 4 prescaler + 10 + 2 + + + 0 + 3 + + + + + CC4S + Capture/Compare 4 + selection + 8 + 2 + + CC4S + read-write + + TI4 + CC4 channel is configured as input, IC4 is mapped on TI4 + 1 + + + TI3 + CC4 channel is configured as input, IC4 is mapped on TI3 + 2 + + + TRC + CC4 channel is configured as input, IC4 is mapped on TRC + 3 + + + + + IC3F + Input capture 3 filter + 4 + 4 + + + 0 + 15 + + + + + IC3PSC + Input capture 3 prescaler + 2 + 2 + + + 0 + 3 + + + + + CC3S + Capture/compare 3 + selection + 0 + 2 + + CC3S + read-write + + TI3 + CC3 channel is configured as input, IC3 is mapped on TI3 + 1 + + + TI4 + CC3 channel is configured as input, IC3 is mapped on TI4 + 2 + + + TRC + CC3 channel is configured as input, IC3 is mapped on TRC + 3 + + + + + + + CCER + CCER + capture/compare enable + register + 0x20 + 0x20 + read-write + 0x00000000 + + + CC4NP + Capture/Compare 4 output + Polarity + 15 + 1 + + + CC4P + Capture/Compare 3 output + Polarity + 13 + 1 + + + CC4E + Capture/Compare 4 output + enable + 12 + 1 + + + CC3NP + Capture/Compare 3 output + Polarity + 11 + 1 + + + CC3P + Capture/Compare 3 output + Polarity + 9 + 1 + + + CC3E + Capture/Compare 3 output + enable + 8 + 1 + + + CC2NP + Capture/Compare 2 output + Polarity + 7 + 1 + + + CC2P + Capture/Compare 2 output + Polarity + 5 + 1 + + + CC2E + Capture/Compare 2 output + enable + 4 + 1 + + + CC1NP + Capture/Compare 1 output + Polarity + 3 + 1 + + + CC1P + Capture/Compare 1 output + Polarity + 1 + 1 + + + CC1E + Capture/Compare 1 output + enable + 0 + 1 + + + + + CNT + CNT + counter + 0x24 + 0x20 + read-write + 0x00000000 + + + CNT + Counter value + 0 + 16 + + + 0 + 65535 + + + + + + + PSC + PSC + prescaler + 0x28 + 0x20 + read-write + 0x00000000 + + + PSC + Prescaler value + 0 + 16 + + + 0 + 65535 + + + + + + + ARR + ARR + auto-reload register + 0x2C + 0x20 + read-write + 0x00000000 + + + ARR + Auto-reload value + 0 + 16 + + + 0 + 65535 + + + + + + + 4 + 0x4 + 1-4 + CCR%s + CCR1 + capture/compare register + 0x34 + 0x20 + read-write + 0x00000000 + + + CCR + Capture/Compare value + 0 + 16 + + + 0 + 65535 + + + + + + + DCR + DCR + DMA control register + 0x48 + 0x20 + read-write + 0x00000000 + + + DBL + DMA burst length + 8 + 5 + + + 0 + 18 + + + + + DBA + DMA base address + 0 + 5 + + + 0 + 31 + + + + + + + DMAR + DMAR + DMA address for full transfer + 0x4C + 0x20 + read-write + 0x00000000 + + + DMAB + DMA register for burst + accesses + 0 + 16 + + + + + + + TIM4 + TIM + 0x40000800 + + + TIM5 + General-purpose-timers + TIM + 0x40000C00 + + 0x0 + 0x400 + registers + + + + CR1 + CR1 + control register 1 + 0x0 + 0x20 + read-write + 0x00000000 + + + CKD + Clock division + 8 + 2 + + CKD + read-write + + Div1 + t_DTS = t_CK_INT + 0 + + + Div2 + t_DTS = 2 × t_CK_INT + 1 + + + Div4 + t_DTS = 4 × t_CK_INT + 2 + + + + + ARPE + Auto-reload preload enable + 7 + 1 + + ARPE + read-write + + Disabled + TIMx_APRR register is not buffered + 0 + + + Enabled + TIMx_APRR register is buffered + 1 + + + + + CMS + Center-aligned mode + selection + 5 + 2 + + CMS + read-write + + EdgeAligned + The counter counts up or down depending on the direction bit + 0 + + + CenterAligned1 + The counter counts up and down alternatively. Output compare interrupt flags are set only when the counter is counting down. + 1 + + + CenterAligned2 + The counter counts up and down alternatively. Output compare interrupt flags are set only when the counter is counting up. + 2 + + + CenterAligned3 + The counter counts up and down alternatively. Output compare interrupt flags are set both when the counter is counting up or down. + 3 + + + + + DIR + Direction + 4 + 1 + + DIR + read-write + + Up + Counter used as upcounter + 0 + + + Down + Counter used as downcounter + 1 + + + + + OPM + One-pulse mode + 3 + 1 + + OPM + read-write + + Disabled + Counter is not stopped at update event + 0 + + + Enabled + Counter stops counting at the next update event (clearing the CEN bit) + 1 + + + + + URS + Update request source + 2 + 1 + + URS + read-write + + AnyEvent + Any of counter overflow/underflow, setting UG, or update through slave mode, generates an update interrupt or DMA request + 0 + + + CounterOnly + Only counter overflow/underflow generates an update interrupt or DMA request + 1 + + + + + UDIS + Update disable + 1 + 1 + + UDIS + read-write + + Enabled + Update event enabled + 0 + + + Disabled + Update event disabled + 1 + + + + + CEN + Counter enable + 0 + 1 + + CEN + read-write + + Disabled + Counter disabled + 0 + + + Enabled + Counter enabled + 1 + + + + + + + CR2 + CR2 + control register 2 + 0x4 + 0x20 + read-write + 0x00000000 + + + TI1S + TI1 selection + 7 + 1 + + TI1S + read-write + + Normal + The TIMx_CH1 pin is connected to TI1 input + 0 + + + XOR + The TIMx_CH1, CH2, CH3 pins are connected to TI1 input + 1 + + + + + MMS + Master mode selection + 4 + 3 + + MMS + read-write + + Reset + The UG bit from the TIMx_EGR register is used as trigger output + 0 + + + Enable + The counter enable signal, CNT_EN, is used as trigger output + 1 + + + Update + The update event is selected as trigger output + 2 + + + ComparePulse + The trigger output send a positive pulse when the CC1IF flag it to be set, as soon as a capture or a compare match occurred + 3 + + + CompareOC1 + OC1REF signal is used as trigger output + 4 + + + CompareOC2 + OC2REF signal is used as trigger output + 5 + + + CompareOC3 + OC3REF signal is used as trigger output + 6 + + + CompareOC4 + OC4REF signal is used as trigger output + 7 + + + + + CCDS + Capture/compare DMA + selection + 3 + 1 + + CCDS + read-write + + OnCompare + CCx DMA request sent when CCx event occurs + 0 + + + OnUpdate + CCx DMA request sent when update event occurs + 1 + + + + + + + SMCR + SMCR + slave mode control register + 0x8 + 0x20 + read-write + 0x00000000 + + + ETP + External trigger polarity + 15 + 1 + + ETP + read-write + + NotInverted + ETR is noninverted, active at high level or rising edge + 0 + + + Inverted + ETR is inverted, active at low level or falling edge + 1 + + + + + ECE + External clock enable + 14 + 1 + + ECE + read-write + + Disabled + External clock mode 2 disabled + 0 + + + Enabled + External clock mode 2 enabled. The counter is clocked by any active edge on the ETRF signal. + 1 + + + + + ETPS + External trigger prescaler + 12 + 2 + + ETPS + read-write + + Div1 + Prescaler OFF + 0 + + + Div2 + ETRP frequency divided by 2 + 1 + + + Div4 + ETRP frequency divided by 4 + 2 + + + Div8 + ETRP frequency divided by 8 + 3 + + + + + ETF + External trigger filter + 8 + 4 + + ETF + read-write + + NoFilter + No filter, sampling is done at fDTS + 0 + + + FCK_INT_N2 + fSAMPLING=fCK_INT, N=2 + 1 + + + FCK_INT_N4 + fSAMPLING=fCK_INT, N=4 + 2 + + + FCK_INT_N8 + fSAMPLING=fCK_INT, N=8 + 3 + + + FDTS_Div2_N6 + fSAMPLING=fDTS/2, N=6 + 4 + + + FDTS_Div2_N8 + fSAMPLING=fDTS/2, N=8 + 5 + + + FDTS_Div4_N6 + fSAMPLING=fDTS/4, N=6 + 6 + + + FDTS_Div4_N8 + fSAMPLING=fDTS/4, N=8 + 7 + + + FDTS_Div8_N6 + fSAMPLING=fDTS/8, N=6 + 8 + + + FDTS_Div8_N8 + fSAMPLING=fDTS/8, N=8 + 9 + + + FDTS_Div16_N5 + fSAMPLING=fDTS/16, N=5 + 10 + + + FDTS_Div16_N6 + fSAMPLING=fDTS/16, N=6 + 11 + + + FDTS_Div16_N8 + fSAMPLING=fDTS/16, N=8 + 12 + + + FDTS_Div32_N5 + fSAMPLING=fDTS/32, N=5 + 13 + + + FDTS_Div32_N6 + fSAMPLING=fDTS/32, N=6 + 14 + + + FDTS_Div32_N8 + fSAMPLING=fDTS/32, N=8 + 15 + + + + + MSM + Master/Slave mode + 7 + 1 + + MSM + read-write + + NoSync + No action + 0 + + + Sync + The effect of an event on the trigger input (TRGI) is delayed to allow a perfect synchronization between the current timer and its slaves (through TRGO). It is useful if we want to synchronize several timers on a single external event. + 1 + + + + + TS + Trigger selection + 4 + 3 + + TS + read-write + + ITR0 + Internal Trigger 0 (ITR0) + 0 + + + ITR1 + Internal Trigger 1 (ITR1) + 1 + + + ITR2 + Internal Trigger 2 (ITR2) + 2 + + + TI1F_ED + TI1 Edge Detector (TI1F_ED) + 4 + + + TI1FP1 + Filtered Timer Input 1 (TI1FP1) + 5 + + + TI2FP2 + Filtered Timer Input 2 (TI2FP2) + 6 + + + ETRF + External Trigger input (ETRF) + 7 + + + + + SMS + Slave mode selection + 0 + 3 + + SMS + read-write + + Disabled + Slave mode disabled - if CEN = ‘1 then the prescaler is clocked directly by the internal clock. + 0 + + + Encoder_Mode_1 + Encoder mode 1 - Counter counts up/down on TI2FP1 edge depending on TI1FP2 level. + 1 + + + Encoder_Mode_2 + Encoder mode 2 - Counter counts up/down on TI1FP2 edge depending on TI2FP1 level. + 2 + + + Encoder_Mode_3 + Encoder mode 3 - Counter counts up/down on both TI1FP1 and TI2FP2 edges depending on the level of the other input. + 3 + + + Reset_Mode + Reset Mode - Rising edge of the selected trigger input (TRGI) reinitializes the counter and generates an update of the registers. + 4 + + + Gated_Mode + Gated Mode - The counter clock is enabled when the trigger input (TRGI) is high. The counter stops (but is not reset) as soon as the trigger becomes low. Both start and stop of the counter are controlled. + 5 + + + Trigger_Mode + Trigger Mode - The counter starts at a rising edge of the trigger TRGI (but it is not reset). Only the start of the counter is controlled. + 6 + + + Ext_Clock_Mode + External Clock Mode 1 - Rising edges of the selected trigger (TRGI) clock the counter. + 7 + + + + + + + DIER + DIER + DMA/Interrupt enable register + 0xC + 0x20 + read-write + 0x00000000 + + + TDE + Trigger DMA request enable + 14 + 1 + + TDE + read-write + + Disabled + Trigger DMA request disabled + 0 + + + Enabled + Trigger DMA request enabled + 1 + + + + + CC4DE + Capture/Compare 4 DMA request + enable + 12 + 1 + + + + CC3DE + Capture/Compare 3 DMA request + enable + 11 + 1 + + + + CC2DE + Capture/Compare 2 DMA request + enable + 10 + 1 + + + + CC1DE + Capture/Compare 1 DMA request + enable + 9 + 1 + + CC1DE + read-write + + Disabled + CCx DMA request disabled + 0 + + + Enabled + CCx DMA request enabled + 1 + + + + + UDE + Update DMA request enable + 8 + 1 + + UDE + read-write + + Disabled + Update DMA request disabled + 0 + + + Enabled + Update DMA request enabled + 1 + + + + + TIE + Trigger interrupt enable + 6 + 1 + + TIE + read-write + + Disabled + Trigger interrupt disabled + 0 + + + Enabled + Trigger interrupt enabled + 1 + + + + + CC4IE + Capture/Compare 4 interrupt + enable + 4 + 1 + + + + CC3IE + Capture/Compare 3 interrupt + enable + 3 + 1 + + + + CC2IE + Capture/Compare 2 interrupt + enable + 2 + 1 + + + + CC1IE + Capture/Compare 1 interrupt + enable + 1 + 1 + + CC1IE + read-write + + Disabled + CCx interrupt disabled + 0 + + + Enabled + CCx interrupt enabled + 1 + + + + + UIE + Update interrupt enable + 0 + 1 + + UIE + read-write + + Disabled + Update interrupt disabled + 0 + + + Enabled + Update interrupt enabled + 1 + + + + + + + SR + SR + status register + 0x10 + 0x20 + read-write + 0x00000000 + + + CC4OF + Capture/Compare 4 overcapture + flag + 12 + 1 + zeroToClear + + read + + + write + + + + CC3OF + Capture/Compare 3 overcapture + flag + 11 + 1 + zeroToClear + + read + + + write + + + + CC2OF + Capture/compare 2 overcapture + flag + 10 + 1 + zeroToClear + + read + + + write + + + + CC1OF + Capture/Compare 1 overcapture + flag + 9 + 1 + zeroToClear + + CC1OFR + read + + Overcapture + The counter value has been captured in TIMx_CCRx register while CCxIF flag was already set + 1 + + + + CC1OFW + write + + Clear + Clear flag + 0 + + + + + TIF + Trigger interrupt flag + 6 + 1 + zeroToClear + + TIFR + read + + NoTrigger + No trigger event occurred + 0 + + + Trigger + Trigger interrupt pending + 1 + + + + TIFW + write + + Clear + Clear flag + 0 + + + + + CC4IF + Capture/Compare 4 interrupt + flag + 4 + 1 + zeroToClear + + read + + + write + + + + CC3IF + Capture/Compare 3 interrupt + flag + 3 + 1 + zeroToClear + + read + + + write + + + + CC2IF + Capture/Compare 2 interrupt + flag + 2 + 1 + zeroToClear + + read + + + write + + + + CC1IF + Capture/compare 1 interrupt + flag + 1 + 1 + zeroToClear + + CC1IFR + read + + Match + If CC1 is an output: The content of the counter TIMx_CNT matches the content of the TIMx_CCR1 register. If CC1 is an input: The counter value has been captured in TIMx_CCR1 register. + 1 + + + + CC1IFW + write + + Clear + Clear flag + 0 + + + + + UIF + Update interrupt flag + 0 + 1 + zeroToClear + + UIFR + read + + NoUpdateOccurred + No update occurred + 0 + + + UpdatePending + Update interrupt pending + 1 + + + + UIFW + write + + Clear + Clear flag + 0 + + + + + + + EGR + EGR + event generation register + 0x14 + 0x20 + write-only + 0x00000000 + + + TG + Trigger generation + 6 + 1 + + TGW + write + + Trigger + The TIF flag is set in TIMx_SR register. Related interrupt or DMA transfer can occur if enabled. + 1 + + + + + CC4G + Capture/compare 4 + generation + 4 + 1 + + + + CC3G + Capture/compare 3 + generation + 3 + 1 + + + + CC2G + Capture/compare 2 + generation + 2 + 1 + + + + CC1G + Capture/compare 1 + generation + 1 + 1 + + CC1GW + write + + Trigger + If CC1 is an output: CC1IF flag is set, Corresponding interrupt or DMA request is sent if enabled. If CC1 is an input: The current value of the counter is captured in TIMx_CCR1 register. + 1 + + + + + UG + Update generation + 0 + 1 + + UG + write + + Update + Re-initializes the timer counter and generates an update of the registers. + 1 + + + + + + + CCMR1_Output + CCMR1_Output + capture/compare mode register 1 (output + mode) + 0x18 + 0x20 + read-write + 0x00000000 + + + OC2CE + OC2CE + 15 + 1 + + + OC2M + OC2M + 12 + 3 + + + + OC2PE + OC2PE + 11 + 1 + + OC2PE + read-write + + Disabled + Preload register on CCR2 disabled. New values written to CCR2 are taken into account immediately + 0 + + + Enabled + Preload register on CCR2 enabled. Preload value is loaded into active register on each update event + 1 + + + + + OC2FE + OC2FE + 10 + 1 + + + CC2S + CC2S + 8 + 2 + + CC2S + read-write + + Output + CC2 channel is configured as output + 0 + + + + + OC1CE + OC1CE + 7 + 1 + + + OC1M + OC1M + 4 + 3 + + OC1M + read-write + + Frozen + The comparison between the output compare register TIMx_CCRy and the counter TIMx_CNT has no effect on the outputs + 0 + + + ActiveOnMatch + Set channel to active level on match. OCyREF signal is forced high when the counter matches the capture/compare register + 1 + + + InactiveOnMatch + Set channel to inactive level on match. OCyREF signal is forced low when the counter matches the capture/compare register + 2 + + + Toggle + OCyREF toggles when TIMx_CNT=TIMx_CCRy + 3 + + + ForceInactive + OCyREF is forced low + 4 + + + ForceActive + OCyREF is forced high + 5 + + + PwmMode1 + In upcounting, channel is active as long as TIMx_CNT<TIMx_CCRy else inactive. In downcounting, channel is inactive as long as TIMx_CNT>TIMx_CCRy else active + 6 + + + PwmMode2 + Inversely to PwmMode1 + 7 + + + + + OC1PE + OC1PE + 3 + 1 + + OC1PE + read-write + + Disabled + Preload register on CCR1 disabled. New values written to CCR1 are taken into account immediately + 0 + + + Enabled + Preload register on CCR1 enabled. Preload value is loaded into active register on each update event + 1 + + + + + OC1FE + OC1FE + 2 + 1 + + + CC1S + CC1S + 0 + 2 + + CC1S + read-write + + Output + CC1 channel is configured as output + 0 + + + + + + + CCMR1_Input + CCMR1_Input + capture/compare mode register 1 (input + mode) + CCMR1_Output + 0x18 + 0x20 + read-write + 0x00000000 + + + IC2F + Input capture 2 filter + 12 + 4 + + + 0 + 15 + + + + + IC2PSC + Input capture 2 prescaler + 10 + 2 + + + CC2S + Capture/Compare 2 + selection + 8 + 2 + + CC2S + read-write + + TI2 + CC2 channel is configured as input, IC2 is mapped on TI2 + 1 + + + TI1 + CC2 channel is configured as input, IC2 is mapped on TI1 + 2 + + + TRC + CC2 channel is configured as input, IC2 is mapped on TRC + 3 + + + + + IC1F + Input capture 1 filter + 4 + 4 + + IC1F + read-write + + NoFilter + No filter, sampling is done at fDTS + 0 + + + FCK_INT_N2 + fSAMPLING=fCK_INT, N=2 + 1 + + + FCK_INT_N4 + fSAMPLING=fCK_INT, N=4 + 2 + + + FCK_INT_N8 + fSAMPLING=fCK_INT, N=8 + 3 + + + FDTS_Div2_N6 + fSAMPLING=fDTS/2, N=6 + 4 + + + FDTS_Div2_N8 + fSAMPLING=fDTS/2, N=8 + 5 + + + FDTS_Div4_N6 + fSAMPLING=fDTS/4, N=6 + 6 + + + FDTS_Div4_N8 + fSAMPLING=fDTS/4, N=8 + 7 + + + FDTS_Div8_N6 + fSAMPLING=fDTS/8, N=6 + 8 + + + FDTS_Div8_N8 + fSAMPLING=fDTS/8, N=8 + 9 + + + FDTS_Div16_N5 + fSAMPLING=fDTS/16, N=5 + 10 + + + FDTS_Div16_N6 + fSAMPLING=fDTS/16, N=6 + 11 + + + FDTS_Div16_N8 + fSAMPLING=fDTS/16, N=8 + 12 + + + FDTS_Div32_N5 + fSAMPLING=fDTS/32, N=5 + 13 + + + FDTS_Div32_N6 + fSAMPLING=fDTS/32, N=6 + 14 + + + FDTS_Div32_N8 + fSAMPLING=fDTS/32, N=8 + 15 + + + + + IC1PSC + Input capture 1 prescaler + 2 + 2 + + + CC1S + Capture/Compare 1 + selection + 0 + 2 + + CC1S + read-write + + TI1 + CC1 channel is configured as input, IC1 is mapped on TI1 + 1 + + + TI2 + CC1 channel is configured as input, IC1 is mapped on TI2 + 2 + + + TRC + CC1 channel is configured as input, IC1 is mapped on TRC + 3 + + + + + + + CCMR2_Output + CCMR2_Output + capture/compare mode register 2 (output + mode) + 0x1C + 0x20 + read-write + 0x00000000 + + + OC4CE + O24CE + 15 + 1 + + + OC4M + OC4M + 12 + 3 + + + + OC4PE + OC4PE + 11 + 1 + + OC4PE + read-write + + Disabled + Preload register on CCR4 disabled. New values written to CCR4 are taken into account immediately + 0 + + + Enabled + Preload register on CCR4 enabled. Preload value is loaded into active register on each update event + 1 + + + + + OC4FE + OC4FE + 10 + 1 + + + CC4S + CC4S + 8 + 2 + + CC4S + read-write + + Output + CC4 channel is configured as output + 0 + + + + + OC3CE + OC3CE + 7 + 1 + + + OC3M + OC3M + 4 + 3 + + OC3M + read-write + + Frozen + The comparison between the output compare register TIMx_CCRy and the counter TIMx_CNT has no effect on the outputs + 0 + + + ActiveOnMatch + Set channel to active level on match. OCyREF signal is forced high when the counter matches the capture/compare register + 1 + + + InactiveOnMatch + Set channel to inactive level on match. OCyREF signal is forced low when the counter matches the capture/compare register + 2 + + + Toggle + OCyREF toggles when TIMx_CNT=TIMx_CCRy + 3 + + + ForceInactive + OCyREF is forced low + 4 + + + ForceActive + OCyREF is forced high + 5 + + + PwmMode1 + In upcounting, channel is active as long as TIMx_CNT<TIMx_CCRy else inactive. In downcounting, channel is inactive as long as TIMx_CNT>TIMx_CCRy else active + 6 + + + PwmMode2 + Inversely to PwmMode1 + 7 + + + + + OC3PE + OC3PE + 3 + 1 + + OC3PE + read-write + + Disabled + Preload register on CCR3 disabled. New values written to CCR3 are taken into account immediately + 0 + + + Enabled + Preload register on CCR3 enabled. Preload value is loaded into active register on each update event + 1 + + + + + OC3FE + OC3FE + 2 + 1 + + + CC3S + CC3S + 0 + 2 + + CC3S + read-write + + Output + CC3 channel is configured as output + 0 + + + + + + + CCMR2_Input + CCMR2_Input + capture/compare mode register 2 (input + mode) + CCMR2_Output + 0x1C + 0x20 + read-write + 0x00000000 + + + IC4F + Input capture 4 filter + 12 + 4 + + + 0 + 15 + + + + + IC4PSC + Input capture 4 prescaler + 10 + 2 + + + 0 + 3 + + + + + CC4S + Capture/Compare 4 + selection + 8 + 2 + + CC4S + read-write + + TI4 + CC4 channel is configured as input, IC4 is mapped on TI4 + 1 + + + TI3 + CC4 channel is configured as input, IC4 is mapped on TI3 + 2 + + + TRC + CC4 channel is configured as input, IC4 is mapped on TRC + 3 + + + + + IC3F + Input capture 3 filter + 4 + 4 + + + 0 + 15 + + + + + IC3PSC + Input capture 3 prescaler + 2 + 2 + + + 0 + 3 + + + + + CC3S + Capture/compare 3 + selection + 0 + 2 + + CC3S + read-write + + TI3 + CC3 channel is configured as input, IC3 is mapped on TI3 + 1 + + + TI4 + CC3 channel is configured as input, IC3 is mapped on TI4 + 2 + + + TRC + CC3 channel is configured as input, IC3 is mapped on TRC + 3 + + + + + + + CCER + CCER + capture/compare enable + register + 0x20 + 0x20 + read-write + 0x00000000 + + + CC4NP + Capture/Compare 4 output + Polarity + 15 + 1 + + + CC4P + Capture/Compare 3 output + Polarity + 13 + 1 + + + CC4E + Capture/Compare 4 output + enable + 12 + 1 + + + CC3NP + Capture/Compare 3 output + Polarity + 11 + 1 + + + CC3P + Capture/Compare 3 output + Polarity + 9 + 1 + + + CC3E + Capture/Compare 3 output + enable + 8 + 1 + + + CC2NP + Capture/Compare 2 output + Polarity + 7 + 1 + + + CC2P + Capture/Compare 2 output + Polarity + 5 + 1 + + + CC2E + Capture/Compare 2 output + enable + 4 + 1 + + + CC1NP + Capture/Compare 1 output + Polarity + 3 + 1 + + + CC1P + Capture/Compare 1 output + Polarity + 1 + 1 + + + CC1E + Capture/Compare 1 output + enable + 0 + 1 + + + + + CNT + CNT + counter + 0x24 + 0x20 + read-write + 0x00000000 + + + CNT + Counter value + 0 + 32 + + + 0 + 4294967295 + + + + + + + PSC + PSC + prescaler + 0x28 + 0x20 + read-write + 0x00000000 + + + PSC + Prescaler value + 0 + 16 + + + 0 + 65535 + + + + + + + ARR + ARR + auto-reload register + 0x2C + 0x20 + read-write + 0x00000000 + + + ARR + Auto-reload value + 0 + 32 + + + 0 + 4294967295 + + + + + + + 4 + 0x4 + 1-4 + CCR%s + CCR1 + capture/compare register + 0x34 + 0x20 + read-write + 0x00000000 + + + CCR + Capture/Compare value + 0 + 32 + + + 0 + 4294967295 + + + + + + + DCR + DCR + DMA control register + 0x48 + 0x20 + read-write + 0x00000000 + + + DBL + DMA burst length + 8 + 5 + + + 0 + 18 + + + + + DBA + DMA base address + 0 + 5 + + + 0 + 31 + + + + + + + DMAR + DMAR + DMA address for full transfer + 0x4C + 0x20 + read-write + 0x00000000 + + + DMAB + DMA register for burst + accesses + 0 + 16 + + + + + OR + OR + TIM5 option register + 0x50 + 0x20 + read-write + 0x00000000 + + + IT4_RMP + Timer Input 4 remap + 6 + 2 + + + + + + + TIM9 + General purpose timers + TIM + 0x40014000 + + 0x0 + 0x400 + registers + + + + CR1 + CR1 + control register 1 + 0x0 + 0x20 + read-write + 0x00000000 + + + CKD + Clock division + 8 + 2 + + CKD + read-write + + Div1 + t_DTS = t_CK_INT + 0 + + + Div2 + t_DTS = 2 × t_CK_INT + 1 + + + Div4 + t_DTS = 4 × t_CK_INT + 2 + + + + + ARPE + Auto-reload preload enable + 7 + 1 + + ARPE + read-write + + Disabled + TIMx_APRR register is not buffered + 0 + + + Enabled + TIMx_APRR register is buffered + 1 + + + + + OPM + One-pulse mode + 3 + 1 + + OPM + read-write + + Disabled + Counter is not stopped at update event + 0 + + + Enabled + Counter stops counting at the next update event (clearing the CEN bit) + 1 + + + + + URS + Update request source + 2 + 1 + + URS + read-write + + AnyEvent + Any of counter overflow/underflow, setting UG, or update through slave mode, generates an update interrupt or DMA request + 0 + + + CounterOnly + Only counter overflow/underflow generates an update interrupt or DMA request + 1 + + + + + UDIS + Update disable + 1 + 1 + + UDIS + read-write + + Enabled + Update event enabled + 0 + + + Disabled + Update event disabled + 1 + + + + + CEN + Counter enable + 0 + 1 + + CEN + read-write + + Disabled + Counter disabled + 0 + + + Enabled + Counter enabled + 1 + + + + + + + CR2 + CR2 + control register 2 + 0x4 + 0x20 + read-write + 0x00000000 + + + MMS + Master mode selection + 4 + 3 + + + + + SMCR + SMCR + slave mode control register + 0x8 + 0x20 + read-write + 0x00000000 + + + MSM + Master/Slave mode + 7 + 1 + + + TS + Trigger selection + 4 + 3 + + + SMS + Slave mode selection + 0 + 3 + + + + + DIER + DIER + DMA/Interrupt enable register + 0xC + 0x20 + read-write + 0x00000000 + + + TIE + Trigger interrupt enable + 6 + 1 + + + CC2IE + Capture/Compare 2 interrupt + enable + 2 + 1 + + + CC1IE + Capture/Compare 1 interrupt + enable + 1 + 1 + + + UIE + Update interrupt enable + 0 + 1 + + UIE + read-write + + Disabled + Update interrupt disabled + 0 + + + Enabled + Update interrupt enabled + 1 + + + + + + + SR + SR + status register + 0x10 + 0x20 + read-write + 0x00000000 + + + CC2OF + Capture/compare 2 overcapture + flag + 10 + 1 + + + CC1OF + Capture/Compare 1 overcapture + flag + 9 + 1 + + + TIF + Trigger interrupt flag + 6 + 1 + + + CC2IF + Capture/Compare 2 interrupt + flag + 2 + 1 + + + CC1IF + Capture/compare 1 interrupt + flag + 1 + 1 + + + UIF + Update interrupt flag + 0 + 1 + zeroToClear + + UIFR + read + + NoUpdateOccurred + No update occurred + 0 + + + UpdatePending + Update interrupt pending + 1 + + + + UIFW + write + + Clear + Clear flag + 0 + + + + + + + EGR + EGR + event generation register + 0x14 + 0x20 + write-only + 0x00000000 + + + TG + Trigger generation + 6 + 1 + + + CC2G + Capture/compare 2 + generation + 2 + 1 + + + CC1G + Capture/compare 1 + generation + 1 + 1 + + + UG + Update generation + 0 + 1 + + UG + write + + Update + Re-initializes the timer counter and generates an update of the registers. + 1 + + + + + + + CCMR1_Output + CCMR1_Output + capture/compare mode register 1 (output + mode) + 0x18 + 0x20 + read-write + 0x00000000 + + + OC2M + Output Compare 2 mode + 12 + 3 + + + + OC2PE + Output Compare 2 preload + enable + 11 + 1 + + + OC2FE + Output Compare 2 fast + enable + 10 + 1 + + + CC2S + Capture/Compare 2 + selection + 8 + 2 + + + OC1M + Output Compare 1 mode + 4 + 3 + + OC1M + read-write + + Frozen + The comparison between the output compare register TIMx_CCRy and the counter TIMx_CNT has no effect on the outputs + 0 + + + ActiveOnMatch + Set channel to active level on match. OCyREF signal is forced high when the counter matches the capture/compare register + 1 + + + InactiveOnMatch + Set channel to inactive level on match. OCyREF signal is forced low when the counter matches the capture/compare register + 2 + + + Toggle + OCyREF toggles when TIMx_CNT=TIMx_CCRy + 3 + + + ForceInactive + OCyREF is forced low + 4 + + + ForceActive + OCyREF is forced high + 5 + + + PwmMode1 + In upcounting, channel is active as long as TIMx_CNT<TIMx_CCRy else inactive. In downcounting, channel is inactive as long as TIMx_CNT>TIMx_CCRy else active + 6 + + + PwmMode2 + Inversely to PwmMode1 + 7 + + + + + OC1PE + Output Compare 1 preload + enable + 3 + 1 + + + OC1FE + Output Compare 1 fast + enable + 2 + 1 + + + CC1S + Capture/Compare 1 + selection + 0 + 2 + + + + + CCMR1_Input + CCMR1_Input + capture/compare mode register 1 (input + mode) + CCMR1_Output + 0x18 + 0x20 + read-write + 0x00000000 + + + IC2F + Input capture 2 filter + 12 + 3 + + + IC2PSC + Input capture 2 prescaler + 10 + 2 + + + CC2S + Capture/Compare 2 + selection + 8 + 2 + + + IC1F + Input capture 1 filter + 4 + 3 + + + IC1PSC + Input capture 1 prescaler + 2 + 2 + + + CC1S + Capture/Compare 1 + selection + 0 + 2 + + + + + CCER + CCER + capture/compare enable + register + 0x20 + 0x20 + read-write + 0x00000000 + + + CC2NP + Capture/Compare 2 output + Polarity + 7 + 1 + + + CC2P + Capture/Compare 2 output + Polarity + 5 + 1 + + + CC2E + Capture/Compare 2 output + enable + 4 + 1 + + + CC1NP + Capture/Compare 1 output + Polarity + 3 + 1 + + + CC1P + Capture/Compare 1 output + Polarity + 1 + 1 + + + CC1E + Capture/Compare 1 output + enable + 0 + 1 + + + + + CNT + CNT + counter + 0x24 + 0x20 + read-write + 0x00000000 + + + CNT + counter value + 0 + 16 + + + + + PSC + PSC + prescaler + 0x28 + 0x20 + read-write + 0x00000000 + + + PSC + Prescaler value + 0 + 16 + + + 0 + 65535 + + + + + + + ARR + ARR + auto-reload register + 0x2C + 0x20 + read-write + 0x00000000 + + + ARR + Auto-reload value + 0 + 16 + + + + + 2 + 0x4 + 1-2 + CCR%s + CCR1 + capture/compare register + 0x34 + 0x20 + read-write + 0x00000000 + + + CCR + Capture/Compare value + 0 + 16 + + + + + + + USART1 + Universal synchronous asynchronous receiver + transmitter + USART + 0x40011000 + + 0x0 + 0x400 + registers + + + OTG_FS_WKUP + USB On-The-Go FS Wakeup through EXTI line + interrupt + 42 + + + OTG_FS + USB On The Go FS global + interrupt + 67 + + + USART1 + USART1 global interrupt + 37 + + + USART2 + USART2 global interrupt + 38 + + + USART6 + USART6 global interrupt + 71 + + + + SR + SR + Status register + 0x0 + 0x20 + 0x00C00000 + + + CTS + CTS flag + 9 + 1 + read-write + + + LBD + LIN break detection flag + 8 + 1 + read-write + + + TXE + Transmit data register + empty + 7 + 1 + read-only + + + TC + Transmission complete + 6 + 1 + read-write + + + RXNE + Read data register not + empty + 5 + 1 + read-write + + + IDLE + IDLE line detected + 4 + 1 + read-only + + + ORE + Overrun error + 3 + 1 + read-only + + + NF + Noise detected flag + 2 + 1 + read-only + + + FE + Framing error + 1 + 1 + read-only + + + PE + Parity error + 0 + 1 + read-only + + + + + DR + DR + Data register + 0x4 + 0x20 + read-write + 0x00000000 + + + DR + Data value + 0 + 9 + + + 0 + 511 + + + + + + + BRR + BRR + Baud rate register + 0x8 + 0x20 + read-write + 0x00000000 + + + DIV_Mantissa + mantissa of USARTDIV + 4 + 12 + + + 0 + 4095 + + + + + DIV_Fraction + fraction of USARTDIV + 0 + 4 + + + 0 + 15 + + + + + + + CR1 + CR1 + Control register 1 + 0xC + 0x20 + read-write + 0x00000000 + + + OVER8 + Oversampling mode + 15 + 1 + + OVER8 + read-write + + Oversample16 + Oversampling by 16 + 0 + + + Oversample8 + Oversampling by 8 + 1 + + + + + UE + USART enable + 13 + 1 + + UE + read-write + + Disabled + USART prescaler and outputs disabled + 0 + + + Enabled + USART enabled + 1 + + + + + M + Word length + 12 + 1 + + M + read-write + + M8 + 8 data bits + 0 + + + M9 + 9 data bits + 1 + + + + + WAKE + Wakeup method + 11 + 1 + + WAKE + read-write + + IdleLine + USART wakeup on idle line + 0 + + + AddressMark + USART wakeup on address mark + 1 + + + + + PCE + Parity control enable + 10 + 1 + + PCE + read-write + + Disabled + Parity control disabled + 0 + + + Enabled + Parity control enabled + 1 + + + + + PS + Parity selection + 9 + 1 + + PS + read-write + + Even + Even parity + 0 + + + Odd + Odd parity + 1 + + + + + PEIE + PE interrupt enable + 8 + 1 + + PEIE + read-write + + Disabled + PE interrupt disabled + 0 + + + Enabled + PE interrupt enabled + 1 + + + + + TXEIE + TXE interrupt enable + 7 + 1 + + TXEIE + read-write + + Disabled + TXE interrupt disabled + 0 + + + Enabled + TXE interrupt enabled + 1 + + + + + TCIE + Transmission complete interrupt + enable + 6 + 1 + + TCIE + read-write + + Disabled + TC interrupt disabled + 0 + + + Enabled + TC interrupt enabled + 1 + + + + + RXNEIE + RXNE interrupt enable + 5 + 1 + + RXNEIE + read-write + + Disabled + RXNE interrupt disabled + 0 + + + Enabled + RXNE interrupt enabled + 1 + + + + + IDLEIE + IDLE interrupt enable + 4 + 1 + + IDLEIE + read-write + + Disabled + IDLE interrupt disabled + 0 + + + Enabled + IDLE interrupt enabled + 1 + + + + + TE + Transmitter enable + 3 + 1 + + TE + read-write + + Disabled + Transmitter disabled + 0 + + + Enabled + Transmitter enabled + 1 + + + + + RE + Receiver enable + 2 + 1 + + RE + read-write + + Disabled + Receiver disabled + 0 + + + Enabled + Receiver enabled + 1 + + + + + RWU + Receiver wakeup + 1 + 1 + + RWU + read-write + + Active + Receiver in active mode + 0 + + + Mute + Receiver in mute mode + 1 + + + + + SBK + Send break + 0 + 1 + + SBK + read-write + + NoBreak + No break character is transmitted + 0 + + + Break + Break character transmitted + 1 + + + + + + + CR2 + CR2 + Control register 2 + 0x10 + 0x20 + read-write + 0x00000000 + + + LINEN + LIN mode enable + 14 + 1 + + LINEN + read-write + + Disabled + LIN mode disabled + 0 + + + Enabled + LIN mode enabled + 1 + + + + + STOP + STOP bits + 12 + 2 + + STOP + read-write + + Stop1 + 1 stop bit + 0 + + + Stop0p5 + 0.5 stop bits + 1 + + + Stop2 + 2 stop bits + 2 + + + Stop1p5 + 1.5 stop bits + 3 + + + + + CLKEN + Clock enable + 11 + 1 + + CLKEN + read-write + + Disabled + CK pin disabled + 0 + + + Enabled + CK pin enabled + 1 + + + + + CPOL + Clock polarity + 10 + 1 + + CPOL + read-write + + Low + Steady low value on CK pin outside transmission window + 0 + + + High + Steady high value on CK pin outside transmission window + 1 + + + + + CPHA + Clock phase + 9 + 1 + + CPHA + read-write + + First + The first clock transition is the first data capture edge + 0 + + + Second + The second clock transition is the first data capture edge + 1 + + + + + LBCL + Last bit clock pulse + 8 + 1 + + + LBDIE + LIN break detection interrupt + enable + 6 + 1 + + LBDIE + read-write + + Disabled + LIN break detection interrupt disabled + 0 + + + Enabled + LIN break detection interrupt enabled + 1 + + + + + LBDL + lin break detection length + 5 + 1 + + LBDL + read-write + + LBDL10 + 10-bit break detection + 0 + + + LBDL11 + 11-bit break detection + 1 + + + + + ADD + Address of the USART node + 0 + 4 + + + 0 + 15 + + + + + + + CR3 + CR3 + Control register 3 + 0x14 + 0x20 + read-write + 0x00000000 + + + ONEBIT + One sample bit method + enable + 11 + 1 + + ONEBIT + read-write + + Sample3 + Three sample bit method + 0 + + + Sample1 + One sample bit method + 1 + + + + + CTSIE + CTS interrupt enable + 10 + 1 + + CTSIE + read-write + + Disabled + CTS interrupt disabled + 0 + + + Enabled + CTS interrupt enabled + 1 + + + + + CTSE + CTS enable + 9 + 1 + + CTSE + read-write + + Disabled + CTS hardware flow control disabled + 0 + + + Enabled + CTS hardware flow control enabled + 1 + + + + + RTSE + RTS enable + 8 + 1 + + RTSE + read-write + + Disabled + RTS hardware flow control disabled + 0 + + + Enabled + RTS hardware flow control enabled + 1 + + + + + DMAT + DMA enable transmitter + 7 + 1 + + DMAT + read-write + + Disabled + DMA mode is disabled for transmission + 0 + + + Enabled + DMA mode is enabled for transmission + 1 + + + + + DMAR + DMA enable receiver + 6 + 1 + + DMAR + read-write + + Disabled + DMA mode is disabled for reception + 0 + + + Enabled + DMA mode is enabled for reception + 1 + + + + + SCEN + Smartcard mode enable + 5 + 1 + + SCEN + read-write + + Disabled + Smartcard mode disabled + 0 + + + Enabled + Smartcard mode enabled + 1 + + + + + NACK + Smartcard NACK enable + 4 + 1 + + NACK + read-write + + Disabled + NACK transmission in case of parity error is disabled + 0 + + + Enabled + NACK transmission during parity error is enabled + 1 + + + + + HDSEL + Half-duplex selection + 3 + 1 + + HDSEL + read-write + + FullDuplex + Half duplex mode is not selected + 0 + + + HalfDuplex + Half duplex mode is selected + 1 + + + + + IRLP + IrDA low-power + 2 + 1 + + IRLP + read-write + + Normal + Normal mode + 0 + + + LowPower + Low-power mode + 1 + + + + + IREN + IrDA mode enable + 1 + 1 + + IREN + read-write + + Disabled + IrDA disabled + 0 + + + Enabled + IrDA enabled + 1 + + + + + EIE + Error interrupt enable + 0 + 1 + + EIE + read-write + + Disabled + Error interrupt disabled + 0 + + + Enabled + Error interrupt enabled + 1 + + + + + + + GTPR + GTPR + Guard time and prescaler + register + 0x18 + 0x20 + read-write + 0x00000000 + + + GT + Guard time value + 8 + 8 + + + PSC + Prescaler value + 0 + 8 + + + + + + + USART2 + 0x40004400 + + + USART6 + 0x40011400 + + + WWDG + Window watchdog + WWDG + 0x40002C00 + + 0x0 + 0x400 + registers + + + PVD + PVD through EXTI line detection + interrupt + 1 + + + + CR + CR + Control register + 0x0 + 0x20 + read-write + 0x0000007F + + + WDGA + Activation bit + 7 + 1 + + WDGA + read-write + + Disabled + Watchdog disabled + 0 + + + Enabled + Watchdog enabled + 1 + + + + + T + 7-bit counter (MSB to LSB) + 0 + 7 + + + 0 + 127 + + + + + + + CFR + CFR + Configuration register + 0x4 + 0x20 + read-write + 0x0000007F + + + EWI + Early wakeup interrupt + 9 + 1 + + EWIW + write + + Enable + interrupt occurs whenever the counter reaches the value 0x40 + 1 + + + + + W + 7-bit window value + 0 + 7 + + + 0 + 127 + + + + + WDGTB + Timer base + 7 + 2 + + WDGTB + read-write + + Div1 + Counter clock (PCLK1 div 4096) div 1 + 0 + + + Div2 + Counter clock (PCLK1 div 4096) div 2 + 1 + + + Div4 + Counter clock (PCLK1 div 4096) div 4 + 2 + + + Div8 + Counter clock (PCLK1 div 4096) div 8 + 3 + + + + + + + SR + SR + Status register + 0x8 + 0x20 + read-write + 0x00000000 + + + EWIF + Early wakeup interrupt + flag + 0 + 1 + zeroToClear + + EWIFR + read + + Finished + The EWI Interrupt Service Routine has been serviced + 0 + + + Pending + The EWI Interrupt Service Routine has been triggered + 1 + + + + EWIFW + write + + Finished + The EWI Interrupt Service Routine has been serviced + 0 + + + + + + + + + DMA2 + DMA controller + DMA + 0x40026400 + + 0x0 + 0x400 + registers + + + RCC + RCC global interrupt + 5 + + + DMA1_STREAM0 + DMA1_STREAM0 global interrupt + 11 + + + DMA1_STREAM1 + DMA1_STREAM1 global interrupt + 12 + + + DMA1_STREAM2 + DMA1_STREAM2 global interrupt + 13 + + + DMA1_STREAM3 + DMA1_STREAM3 global interrupt + 14 + + + DMA1_STREAM4 + DMA1_STREAM4 global interrupt + 15 + + + DMA1_STREAM5 + DMA1_STREAM5 global interrupt + 16 + + + DMA1_STREAM6 + DMA1_STREAM6 global interrupt + 17 + + + DMA1_STREAM7 + DMA1_STREAM7 global interrupt + 47 + + + DMA2_STREAM0 + DMA2_STREAM0 global interrupt + 56 + + + DMA2_STREAM1 + DMA2_STREAM1 global interrupt + 57 + + + DMA2_STREAM2 + DMA2_STREAM2 global interrupt + 58 + + + DMA2_STREAM3 + DMA2_STREAM3 global interrupt + 59 + + + DMA2_STREAM4 + DMA2_STREAM4 global interrupt + 60 + + + DMA2_STREAM5 + DMA2_STREAM5 global interrupt + 68 + + + DMA2_STREAM6 + DMA2_STREAM6 global interrupt + 69 + + + DMA2_STREAM7 + DMA2_STREAM7 global interrupt + 70 + + + + LISR + LISR + low interrupt status register + 0x0 + 0x20 + read-only + 0x00000000 + + + TCIF3 + Stream x transfer complete interrupt + flag (x = 3..0) + 27 + 1 + + + + HTIF3 + Stream x half transfer interrupt flag + (x=3..0) + 26 + 1 + + + + TEIF3 + Stream x transfer error interrupt flag + (x=3..0) + 25 + 1 + + + + DMEIF3 + Stream x direct mode error interrupt + flag (x=3..0) + 24 + 1 + + + + FEIF3 + Stream x FIFO error interrupt flag + (x=3..0) + 22 + 1 + + + + TCIF2 + Stream x transfer complete interrupt + flag (x = 3..0) + 21 + 1 + + + + HTIF2 + Stream x half transfer interrupt flag + (x=3..0) + 20 + 1 + + + + TEIF2 + Stream x transfer error interrupt flag + (x=3..0) + 19 + 1 + + + + DMEIF2 + Stream x direct mode error interrupt + flag (x=3..0) + 18 + 1 + + + + FEIF2 + Stream x FIFO error interrupt flag + (x=3..0) + 16 + 1 + + + + TCIF1 + Stream x transfer complete interrupt + flag (x = 3..0) + 11 + 1 + + + + HTIF1 + Stream x half transfer interrupt flag + (x=3..0) + 10 + 1 + + + + TEIF1 + Stream x transfer error interrupt flag + (x=3..0) + 9 + 1 + + + + DMEIF1 + Stream x direct mode error interrupt + flag (x=3..0) + 8 + 1 + + + + FEIF1 + Stream x FIFO error interrupt flag + (x=3..0) + 6 + 1 + + + + TCIF0 + Stream x transfer complete interrupt + flag (x = 3..0) + 5 + 1 + + TCIF0 + read + + NotComplete + No transfer complete event on stream x + 0 + + + Complete + A transfer complete event occurred on stream x + 1 + + + + + HTIF0 + Stream x half transfer interrupt flag + (x=3..0) + 4 + 1 + + HTIF0 + read + + NotHalf + No half transfer event on stream x + 0 + + + Half + A half transfer event occurred on stream x + 1 + + + + + TEIF0 + Stream x transfer error interrupt flag + (x=3..0) + 3 + 1 + + TEIF0 + read + + NoError + No transfer error on stream x + 0 + + + Error + A transfer error occurred on stream x + 1 + + + + + DMEIF0 + Stream x direct mode error interrupt + flag (x=3..0) + 2 + 1 + + DMEIF0 + read + + NoError + No Direct Mode error on stream x + 0 + + + Error + A Direct Mode error occurred on stream x + 1 + + + + + FEIF0 + Stream x FIFO error interrupt flag + (x=3..0) + 0 + 1 + + FEIF0 + read + + NoError + No FIFO error event on stream x + 0 + + + Error + A FIFO error event occurred on stream x + 1 + + + + + + + HISR + HISR + high interrupt status register + 0x4 + 0x20 + read-only + 0x00000000 + + + TCIF7 + Stream x transfer complete interrupt + flag (x=7..4) + 27 + 1 + + + + HTIF7 + Stream x half transfer interrupt flag + (x=7..4) + 26 + 1 + + + + TEIF7 + Stream x transfer error interrupt flag + (x=7..4) + 25 + 1 + + + + DMEIF7 + Stream x direct mode error interrupt + flag (x=7..4) + 24 + 1 + + + + FEIF7 + Stream x FIFO error interrupt flag + (x=7..4) + 22 + 1 + + + + TCIF6 + Stream x transfer complete interrupt + flag (x=7..4) + 21 + 1 + + + + HTIF6 + Stream x half transfer interrupt flag + (x=7..4) + 20 + 1 + + + + TEIF6 + Stream x transfer error interrupt flag + (x=7..4) + 19 + 1 + + + + DMEIF6 + Stream x direct mode error interrupt + flag (x=7..4) + 18 + 1 + + + + FEIF6 + Stream x FIFO error interrupt flag + (x=7..4) + 16 + 1 + + + + TCIF5 + Stream x transfer complete interrupt + flag (x=7..4) + 11 + 1 + + + + HTIF5 + Stream x half transfer interrupt flag + (x=7..4) + 10 + 1 + + + + TEIF5 + Stream x transfer error interrupt flag + (x=7..4) + 9 + 1 + + + + DMEIF5 + Stream x direct mode error interrupt + flag (x=7..4) + 8 + 1 + + + + FEIF5 + Stream x FIFO error interrupt flag + (x=7..4) + 6 + 1 + + + + TCIF4 + Stream x transfer complete interrupt + flag (x=7..4) + 5 + 1 + + TCIF4 + read + + NotComplete + No transfer complete event on stream x + 0 + + + Complete + A transfer complete event occurred on stream x + 1 + + + + + HTIF4 + Stream x half transfer interrupt flag + (x=7..4) + 4 + 1 + + HTIF4 + read + + NotHalf + No half transfer event on stream x + 0 + + + Half + A half transfer event occurred on stream x + 1 + + + + + TEIF4 + Stream x transfer error interrupt flag + (x=7..4) + 3 + 1 + + TEIF4 + read + + NoError + No transfer error on stream x + 0 + + + Error + A transfer error occurred on stream x + 1 + + + + + DMEIF4 + Stream x direct mode error interrupt + flag (x=7..4) + 2 + 1 + + DMEIF4 + read + + NoError + No Direct Mode error on stream x + 0 + + + Error + A Direct Mode error occurred on stream x + 1 + + + + + FEIF4 + Stream x FIFO error interrupt flag + (x=7..4) + 0 + 1 + + FEIF4 + read + + NoError + No FIFO error event on stream x + 0 + + + Error + A FIFO error event occurred on stream x + 1 + + + + + + + LIFCR + LIFCR + low interrupt flag clear + register + 0x8 + 0x20 + write-only + 0x00000000 + + + CTCIF3 + Stream x clear transfer complete + interrupt flag (x = 3..0) + 27 + 1 + + + + CHTIF3 + Stream x clear half transfer interrupt + flag (x = 3..0) + 26 + 1 + + + + CTEIF3 + Stream x clear transfer error interrupt + flag (x = 3..0) + 25 + 1 + + + + CDMEIF3 + Stream x clear direct mode error + interrupt flag (x = 3..0) + 24 + 1 + + + + CFEIF3 + Stream x clear FIFO error interrupt flag + (x = 3..0) + 22 + 1 + + + + CTCIF2 + Stream x clear transfer complete + interrupt flag (x = 3..0) + 21 + 1 + + + + CHTIF2 + Stream x clear half transfer interrupt + flag (x = 3..0) + 20 + 1 + + + + CTEIF2 + Stream x clear transfer error interrupt + flag (x = 3..0) + 19 + 1 + + + + CDMEIF2 + Stream x clear direct mode error + interrupt flag (x = 3..0) + 18 + 1 + + + + CFEIF2 + Stream x clear FIFO error interrupt flag + (x = 3..0) + 16 + 1 + + + + CTCIF1 + Stream x clear transfer complete + interrupt flag (x = 3..0) + 11 + 1 + + + + CHTIF1 + Stream x clear half transfer interrupt + flag (x = 3..0) + 10 + 1 + + + + CTEIF1 + Stream x clear transfer error interrupt + flag (x = 3..0) + 9 + 1 + + + + CDMEIF1 + Stream x clear direct mode error + interrupt flag (x = 3..0) + 8 + 1 + + + + CFEIF1 + Stream x clear FIFO error interrupt flag + (x = 3..0) + 6 + 1 + + + + CTCIF0 + Stream x clear transfer complete + interrupt flag (x = 3..0) + 5 + 1 + + CTCIF0 + write + + Clear + Clear the corresponding TCIFx flag + 1 + + + + + CHTIF0 + Stream x clear half transfer interrupt + flag (x = 3..0) + 4 + 1 + + CHTIF0 + write + + Clear + Clear the corresponding HTIFx flag + 1 + + + + + CTEIF0 + Stream x clear transfer error interrupt + flag (x = 3..0) + 3 + 1 + + CTEIF0 + write + + Clear + Clear the corresponding TEIFx flag + 1 + + + + + CDMEIF0 + Stream x clear direct mode error + interrupt flag (x = 3..0) + 2 + 1 + + CDMEIF0 + write + + Clear + Clear the corresponding DMEIFx flag + 1 + + + + + CFEIF0 + Stream x clear FIFO error interrupt flag + (x = 3..0) + 0 + 1 + + CFEIF0 + write + + Clear + Clear the corresponding CFEIFx flag + 1 + + + + + + + HIFCR + HIFCR + high interrupt flag clear + register + 0xC + 0x20 + write-only + 0x00000000 + + + CTCIF7 + Stream x clear transfer complete + interrupt flag (x = 7..4) + 27 + 1 + + + + CHTIF7 + Stream x clear half transfer interrupt + flag (x = 7..4) + 26 + 1 + + + + CTEIF7 + Stream x clear transfer error interrupt + flag (x = 7..4) + 25 + 1 + + + + CDMEIF7 + Stream x clear direct mode error + interrupt flag (x = 7..4) + 24 + 1 + + + + CFEIF7 + Stream x clear FIFO error interrupt flag + (x = 7..4) + 22 + 1 + + + + CTCIF6 + Stream x clear transfer complete + interrupt flag (x = 7..4) + 21 + 1 + + + + CHTIF6 + Stream x clear half transfer interrupt + flag (x = 7..4) + 20 + 1 + + + + CTEIF6 + Stream x clear transfer error interrupt + flag (x = 7..4) + 19 + 1 + + + + CDMEIF6 + Stream x clear direct mode error + interrupt flag (x = 7..4) + 18 + 1 + + + + CFEIF6 + Stream x clear FIFO error interrupt flag + (x = 7..4) + 16 + 1 + + + + CTCIF5 + Stream x clear transfer complete + interrupt flag (x = 7..4) + 11 + 1 + + + + CHTIF5 + Stream x clear half transfer interrupt + flag (x = 7..4) + 10 + 1 + + + + CTEIF5 + Stream x clear transfer error interrupt + flag (x = 7..4) + 9 + 1 + + + + CDMEIF5 + Stream x clear direct mode error + interrupt flag (x = 7..4) + 8 + 1 + + + + CFEIF5 + Stream x clear FIFO error interrupt flag + (x = 7..4) + 6 + 1 + + + + CTCIF4 + Stream x clear transfer complete + interrupt flag (x = 7..4) + 5 + 1 + + CTCIF4 + write + + Clear + Clear the corresponding TCIFx flag + 1 + + + + + CHTIF4 + Stream x clear half transfer interrupt + flag (x = 7..4) + 4 + 1 + + CHTIF4 + write + + Clear + Clear the corresponding HTIFx flag + 1 + + + + + CTEIF4 + Stream x clear transfer error interrupt + flag (x = 7..4) + 3 + 1 + + CTEIF4 + write + + Clear + Clear the corresponding TEIFx flag + 1 + + + + + CDMEIF4 + Stream x clear direct mode error + interrupt flag (x = 7..4) + 2 + 1 + + CDMEIF4 + write + + Clear + Clear the corresponding DMEIFx flag + 1 + + + + + CFEIF4 + Stream x clear FIFO error interrupt flag + (x = 7..4) + 0 + 1 + + CFEIF4 + write + + Clear + Clear the corresponding CFEIFx flag + 1 + + + + + + + 8 + 0x18 + 0-7 + ST%s + Stream cluster: S?CR, S?NDTR, S?M0AR, S?M1AR and S?FCR registers + 0x10 + + CR + S0CR + stream x configuration + register + 0x0 + 0x20 + read-write + 0x00000000 + + + CHSEL + Channel selection + 25 + 3 + + + 0 + 7 + + + + + MBURST + Memory burst transfer + configuration + 23 + 2 + + + + PBURST + Peripheral burst transfer + configuration + 21 + 2 + + PBURST + read-write + + Single + Single transfer + 0 + + + INCR4 + Incremental burst of 4 beats + 1 + + + INCR8 + Incremental burst of 8 beats + 2 + + + INCR16 + Incremental burst of 16 beats + 3 + + + + + CT + Current target (only in double buffer + mode) + 19 + 1 + + CT + read-write + + Memory0 + The current target memory is Memory 0 + 0 + + + Memory1 + The current target memory is Memory 1 + 1 + + + + + DBM + Double buffer mode + 18 + 1 + + DBM + read-write + + Disabled + No buffer switching at the end of transfer + 0 + + + Enabled + Memory target switched at the end of the DMA transfer + 1 + + + + + PL + Priority level + 16 + 2 + + PL + read-write + + Low + Low + 0 + + + Medium + Medium + 1 + + + High + High + 2 + + + VeryHigh + Very high + 3 + + + + + PINCOS + Peripheral increment offset + size + 15 + 1 + + PINCOS + read-write + + PSIZE + The offset size for the peripheral address calculation is linked to the PSIZE + 0 + + + Fixed4 + The offset size for the peripheral address calculation is fixed to 4 (32-bit alignment) + 1 + + + + + MSIZE + Memory data size + 13 + 2 + + + + PSIZE + Peripheral data size + 11 + 2 + + PSIZE + read-write + + Bits8 + Byte (8-bit) + 0 + + + Bits16 + Half-word (16-bit) + 1 + + + Bits32 + Word (32-bit) + 2 + + + + + MINC + Memory increment mode + 10 + 1 + + + + PINC + Peripheral increment mode + 9 + 1 + + PINC + read-write + + Fixed + Address pointer is fixed + 0 + + + Incremented + Address pointer is incremented after each data transfer + 1 + + + + + CIRC + Circular mode + 8 + 1 + + CIRC + read-write + + Disabled + Circular mode disabled + 0 + + + Enabled + Circular mode enabled + 1 + + + + + DIR + Data transfer direction + 6 + 2 + + DIR + read-write + + PeripheralToMemory + Peripheral-to-memory + 0 + + + MemoryToPeripheral + Memory-to-peripheral + 1 + + + MemoryToMemory + Memory-to-memory + 2 + + + + + PFCTRL + Peripheral flow controller + 5 + 1 + + PFCTRL + read-write + + DMA + The DMA is the flow controller + 0 + + + Peripheral + The peripheral is the flow controller + 1 + + + + + TCIE + Transfer complete interrupt + enable + 4 + 1 + + TCIE + read-write + + Disabled + TC interrupt disabled + 0 + + + Enabled + TC interrupt enabled + 1 + + + + + HTIE + Half transfer interrupt + enable + 3 + 1 + + HTIE + read-write + + Disabled + HT interrupt disabled + 0 + + + Enabled + HT interrupt enabled + 1 + + + + + TEIE + Transfer error interrupt + enable + 2 + 1 + + TEIE + read-write + + Disabled + TE interrupt disabled + 0 + + + Enabled + TE interrupt enabled + 1 + + + + + DMEIE + Direct mode error interrupt + enable + 1 + 1 + + DMEIE + read-write + + Disabled + DME interrupt disabled + 0 + + + Enabled + DME interrupt enabled + 1 + + + + + EN + Stream enable / flag stream ready when + read low + 0 + 1 + + EN + read-write + + Disabled + Stream disabled + 0 + + + Enabled + Stream enabled + 1 + + + + + + + NDTR + S0NDTR + stream x number of data + register + 0x4 + 0x20 + read-write + 0x00000000 + + + NDT + Number of data items to + transfer + 0 + 16 + + + 0 + 65535 + + + + + + + PAR + S0PAR + stream x peripheral address + register + 0x8 + 0x20 + read-write + 0x00000000 + + + PA + Peripheral address + 0 + 32 + + + + + M0AR + S0M0AR + stream x memory 0 address + register + 0xC + 0x20 + read-write + 0x00000000 + + + M0A + Memory 0 address + 0 + 32 + + + + + M1AR + S0M1AR + stream x memory 1 address + register + 0x10 + 0x20 + read-write + 0x00000000 + + + M1A + Memory 1 address (used in case of Double + buffer mode) + 0 + 32 + + + + + FCR + S0FCR + stream x FIFO control register + 0x14 + 0x20 + 0x00000021 + + + FEIE + FIFO error interrupt + enable + 7 + 1 + read-write + + FEIE + read-write + + Disabled + FE interrupt disabled + 0 + + + Enabled + FE interrupt enabled + 1 + + + + + FS + FIFO status + 3 + 3 + read-only + + FS + read + + Quarter1 + 0 < fifo_level < 1/4 + 0 + + + Quarter2 + 1/4 <= fifo_level < 1/2 + 1 + + + Quarter3 + 1/2 <= fifo_level < 3/4 + 2 + + + Quarter4 + 3/4 <= fifo_level < full + 3 + + + Empty + FIFO is empty + 4 + + + Full + FIFO is full + 5 + + + + + DMDIS + Direct mode disable + 2 + 1 + read-write + + DMDIS + read-write + + Enabled + Direct mode is enabled + 0 + + + Disabled + Direct mode is disabled + 1 + + + + + FTH + FIFO threshold selection + 0 + 2 + read-write + + FTH + read-write + + Quarter + 1/4 full FIFO + 0 + + + Half + 1/2 full FIFO + 1 + + + ThreeQuarters + 3/4 full FIFO + 2 + + + Full + Full FIFO + 3 + + + + + + + + + + DMA1 + 0x40026000 + + RTC_WKUP + RTC Wakeup interrupt through the EXTI + line + 3 + + + RTC_Alarm + RTC Alarms (A and B) through EXTI line + interrupt + 41 + + + + GPIOH + General-purpose I/Os + GPIO + 0x40021C00 + + 0x0 + 0x400 + registers + + + SDIO + SDIO global interrupt + 49 + + + + MODER + MODER + GPIO port mode register + 0x0 + 0x20 + read-write + 0x00000000 + + + MODER15 + Port x configuration bits (y = + 0..15) + 30 + 2 + + + + MODER14 + Port x configuration bits (y = + 0..15) + 28 + 2 + + + + MODER13 + Port x configuration bits (y = + 0..15) + 26 + 2 + + + + MODER12 + Port x configuration bits (y = + 0..15) + 24 + 2 + + + + MODER11 + Port x configuration bits (y = + 0..15) + 22 + 2 + + + + MODER10 + Port x configuration bits (y = + 0..15) + 20 + 2 + + + + MODER9 + Port x configuration bits (y = + 0..15) + 18 + 2 + + + + MODER8 + Port x configuration bits (y = + 0..15) + 16 + 2 + + + + MODER7 + Port x configuration bits (y = + 0..15) + 14 + 2 + + + + MODER6 + Port x configuration bits (y = + 0..15) + 12 + 2 + + + + MODER5 + Port x configuration bits (y = + 0..15) + 10 + 2 + + + + MODER4 + Port x configuration bits (y = + 0..15) + 8 + 2 + + + + MODER3 + Port x configuration bits (y = + 0..15) + 6 + 2 + + + + MODER2 + Port x configuration bits (y = + 0..15) + 4 + 2 + + + + MODER1 + Port x configuration bits (y = + 0..15) + 2 + 2 + + + + MODER0 + Port x configuration bits (y = + 0..15) + 0 + 2 + + MODER0 + read-write + + Input + Input mode (reset state) + 0 + + + Output + General purpose output mode + 1 + + + Alternate + Alternate function mode + 2 + + + Analog + Analog mode + 3 + + + + + + + OTYPER + OTYPER + GPIO port output type register + 0x4 + 0x20 + read-write + 0x00000000 + + + OT15 + Port x configuration bits (y = + 0..15) + 15 + 1 + + + + OT14 + Port x configuration bits (y = + 0..15) + 14 + 1 + + + + OT13 + Port x configuration bits (y = + 0..15) + 13 + 1 + + + + OT12 + Port x configuration bits (y = + 0..15) + 12 + 1 + + + + OT11 + Port x configuration bits (y = + 0..15) + 11 + 1 + + + + OT10 + Port x configuration bits (y = + 0..15) + 10 + 1 + + + + OT9 + Port x configuration bits (y = + 0..15) + 9 + 1 + + + + OT8 + Port x configuration bits (y = + 0..15) + 8 + 1 + + + + OT7 + Port x configuration bits (y = + 0..15) + 7 + 1 + + + + OT6 + Port x configuration bits (y = + 0..15) + 6 + 1 + + + + OT5 + Port x configuration bits (y = + 0..15) + 5 + 1 + + + + OT4 + Port x configuration bits (y = + 0..15) + 4 + 1 + + + + OT3 + Port x configuration bits (y = + 0..15) + 3 + 1 + + + + OT2 + Port x configuration bits (y = + 0..15) + 2 + 1 + + + + OT1 + Port x configuration bits (y = + 0..15) + 1 + 1 + + + + OT0 + Port x configuration bits (y = + 0..15) + 0 + 1 + + OT0 + read-write + + PushPull + Output push-pull (reset state) + 0 + + + OpenDrain + Output open-drain + 1 + + + + + + + OSPEEDR + OSPEEDR + GPIO port output speed + register + 0x8 + 0x20 + read-write + 0x00000000 + + + OSPEEDR15 + Port x configuration bits (y = + 0..15) + 30 + 2 + + + + OSPEEDR14 + Port x configuration bits (y = + 0..15) + 28 + 2 + + + + OSPEEDR13 + Port x configuration bits (y = + 0..15) + 26 + 2 + + + + OSPEEDR12 + Port x configuration bits (y = + 0..15) + 24 + 2 + + + + OSPEEDR11 + Port x configuration bits (y = + 0..15) + 22 + 2 + + + + OSPEEDR10 + Port x configuration bits (y = + 0..15) + 20 + 2 + + + + OSPEEDR9 + Port x configuration bits (y = + 0..15) + 18 + 2 + + + + OSPEEDR8 + Port x configuration bits (y = + 0..15) + 16 + 2 + + + + OSPEEDR7 + Port x configuration bits (y = + 0..15) + 14 + 2 + + + + OSPEEDR6 + Port x configuration bits (y = + 0..15) + 12 + 2 + + + + OSPEEDR5 + Port x configuration bits (y = + 0..15) + 10 + 2 + + + + OSPEEDR4 + Port x configuration bits (y = + 0..15) + 8 + 2 + + + + OSPEEDR3 + Port x configuration bits (y = + 0..15) + 6 + 2 + + + + OSPEEDR2 + Port x configuration bits (y = + 0..15) + 4 + 2 + + + + OSPEEDR1 + Port x configuration bits (y = + 0..15) + 2 + 2 + + + + OSPEEDR0 + Port x configuration bits (y = + 0..15) + 0 + 2 + + OSPEEDR0 + read-write + + LowSpeed + Low speed + 0 + + + MediumSpeed + Medium speed + 1 + + + HighSpeed + High speed + 2 + + + VeryHighSpeed + Very high speed + 3 + + + + + + + PUPDR + PUPDR + GPIO port pull-up/pull-down + register + 0xC + 0x20 + read-write + 0x00000000 + + + PUPDR15 + Port x configuration bits (y = + 0..15) + 30 + 2 + + + + PUPDR14 + Port x configuration bits (y = + 0..15) + 28 + 2 + + + + PUPDR13 + Port x configuration bits (y = + 0..15) + 26 + 2 + + + + PUPDR12 + Port x configuration bits (y = + 0..15) + 24 + 2 + + + + PUPDR11 + Port x configuration bits (y = + 0..15) + 22 + 2 + + + + PUPDR10 + Port x configuration bits (y = + 0..15) + 20 + 2 + + + + PUPDR9 + Port x configuration bits (y = + 0..15) + 18 + 2 + + + + PUPDR8 + Port x configuration bits (y = + 0..15) + 16 + 2 + + + + PUPDR7 + Port x configuration bits (y = + 0..15) + 14 + 2 + + + + PUPDR6 + Port x configuration bits (y = + 0..15) + 12 + 2 + + + + PUPDR5 + Port x configuration bits (y = + 0..15) + 10 + 2 + + + + PUPDR4 + Port x configuration bits (y = + 0..15) + 8 + 2 + + + + PUPDR3 + Port x configuration bits (y = + 0..15) + 6 + 2 + + + + PUPDR2 + Port x configuration bits (y = + 0..15) + 4 + 2 + + + + PUPDR1 + Port x configuration bits (y = + 0..15) + 2 + 2 + + + + PUPDR0 + Port x configuration bits (y = + 0..15) + 0 + 2 + + PUPDR0 + read-write + + Floating + No pull-up, pull-down + 0 + + + PullUp + Pull-up + 1 + + + PullDown + Pull-down + 2 + + + + + + + IDR + IDR + GPIO port input data register + 0x10 + 0x20 + read-only + 0x00000000 + + + IDR15 + Port input data (y = + 0..15) + 15 + 1 + + + + IDR14 + Port input data (y = + 0..15) + 14 + 1 + + + + IDR13 + Port input data (y = + 0..15) + 13 + 1 + + + + IDR12 + Port input data (y = + 0..15) + 12 + 1 + + + + IDR11 + Port input data (y = + 0..15) + 11 + 1 + + + + IDR10 + Port input data (y = + 0..15) + 10 + 1 + + + + IDR9 + Port input data (y = + 0..15) + 9 + 1 + + + + IDR8 + Port input data (y = + 0..15) + 8 + 1 + + + + IDR7 + Port input data (y = + 0..15) + 7 + 1 + + + + IDR6 + Port input data (y = + 0..15) + 6 + 1 + + + + IDR5 + Port input data (y = + 0..15) + 5 + 1 + + + + IDR4 + Port input data (y = + 0..15) + 4 + 1 + + + + IDR3 + Port input data (y = + 0..15) + 3 + 1 + + + + IDR2 + Port input data (y = + 0..15) + 2 + 1 + + + + IDR1 + Port input data (y = + 0..15) + 1 + 1 + + + + IDR0 + Port input data (y = + 0..15) + 0 + 1 + + IDR0 + read + + Low + Input is logic low + 0 + + + High + Input is logic high + 1 + + + + + + + ODR + ODR + GPIO port output data register + 0x14 + 0x20 + read-write + 0x00000000 + + + ODR15 + Port output data (y = + 0..15) + 15 + 1 + + + + ODR14 + Port output data (y = + 0..15) + 14 + 1 + + + + ODR13 + Port output data (y = + 0..15) + 13 + 1 + + + + ODR12 + Port output data (y = + 0..15) + 12 + 1 + + + + ODR11 + Port output data (y = + 0..15) + 11 + 1 + + + + ODR10 + Port output data (y = + 0..15) + 10 + 1 + + + + ODR9 + Port output data (y = + 0..15) + 9 + 1 + + + + ODR8 + Port output data (y = + 0..15) + 8 + 1 + + + + ODR7 + Port output data (y = + 0..15) + 7 + 1 + + + + ODR6 + Port output data (y = + 0..15) + 6 + 1 + + + + ODR5 + Port output data (y = + 0..15) + 5 + 1 + + + + ODR4 + Port output data (y = + 0..15) + 4 + 1 + + + + ODR3 + Port output data (y = + 0..15) + 3 + 1 + + + + ODR2 + Port output data (y = + 0..15) + 2 + 1 + + + + ODR1 + Port output data (y = + 0..15) + 1 + 1 + + + + ODR0 + Port output data (y = + 0..15) + 0 + 1 + + ODR0 + read-write + + Low + Set output to logic low + 0 + + + High + Set output to logic high + 1 + + + + + + + BSRR + BSRR + GPIO port bit set/reset + register + 0x18 + 0x20 + write-only + 0x00000000 + + + BR15 + Port x reset bit y (y = + 0..15) + 31 + 1 + + + + BR14 + Port x reset bit y (y = + 0..15) + 30 + 1 + + + + BR13 + Port x reset bit y (y = + 0..15) + 29 + 1 + + + + BR12 + Port x reset bit y (y = + 0..15) + 28 + 1 + + + + BR11 + Port x reset bit y (y = + 0..15) + 27 + 1 + + + + BR10 + Port x reset bit y (y = + 0..15) + 26 + 1 + + + + BR9 + Port x reset bit y (y = + 0..15) + 25 + 1 + + + + BR8 + Port x reset bit y (y = + 0..15) + 24 + 1 + + + + BR7 + Port x reset bit y (y = + 0..15) + 23 + 1 + + + + BR6 + Port x reset bit y (y = + 0..15) + 22 + 1 + + + + BR5 + Port x reset bit y (y = + 0..15) + 21 + 1 + + + + BR4 + Port x reset bit y (y = + 0..15) + 20 + 1 + + + + BR3 + Port x reset bit y (y = + 0..15) + 19 + 1 + + + + BR2 + Port x reset bit y (y = + 0..15) + 18 + 1 + + + + BR1 + Port x reset bit y (y = + 0..15) + 17 + 1 + + + + BR0 + Port x set bit y (y= + 0..15) + 16 + 1 + + BR0W + write + + Reset + Resets the corresponding ODRx bit + 1 + + + + + BS15 + Port x set bit y (y= + 0..15) + 15 + 1 + + + + BS14 + Port x set bit y (y= + 0..15) + 14 + 1 + + + + BS13 + Port x set bit y (y= + 0..15) + 13 + 1 + + + + BS12 + Port x set bit y (y= + 0..15) + 12 + 1 + + + + BS11 + Port x set bit y (y= + 0..15) + 11 + 1 + + + + BS10 + Port x set bit y (y= + 0..15) + 10 + 1 + + + + BS9 + Port x set bit y (y= + 0..15) + 9 + 1 + + + + BS8 + Port x set bit y (y= + 0..15) + 8 + 1 + + + + BS7 + Port x set bit y (y= + 0..15) + 7 + 1 + + + + BS6 + Port x set bit y (y= + 0..15) + 6 + 1 + + + + BS5 + Port x set bit y (y= + 0..15) + 5 + 1 + + + + BS4 + Port x set bit y (y= + 0..15) + 4 + 1 + + + + BS3 + Port x set bit y (y= + 0..15) + 3 + 1 + + + + BS2 + Port x set bit y (y= + 0..15) + 2 + 1 + + + + BS1 + Port x set bit y (y= + 0..15) + 1 + 1 + + + + BS0 + Port x set bit y (y= + 0..15) + 0 + 1 + + BS0W + write + + Set + Sets the corresponding ODRx bit + 1 + + + + + + + LCKR + LCKR + GPIO port configuration lock + register + 0x1C + 0x20 + read-write + 0x00000000 + + + LCKK + Port x lock bit y (y= + 0..15) + 16 + 1 + + LCKK + read-write + + NotActive + Port configuration lock key not active + 0 + + + Active + Port configuration lock key active + 1 + + + + + LCK15 + Port x lock bit y (y= + 0..15) + 15 + 1 + + + + LCK14 + Port x lock bit y (y= + 0..15) + 14 + 1 + + + + LCK13 + Port x lock bit y (y= + 0..15) + 13 + 1 + + + + LCK12 + Port x lock bit y (y= + 0..15) + 12 + 1 + + + + LCK11 + Port x lock bit y (y= + 0..15) + 11 + 1 + + + + LCK10 + Port x lock bit y (y= + 0..15) + 10 + 1 + + + + LCK9 + Port x lock bit y (y= + 0..15) + 9 + 1 + + + + LCK8 + Port x lock bit y (y= + 0..15) + 8 + 1 + + + + LCK7 + Port x lock bit y (y= + 0..15) + 7 + 1 + + + + LCK6 + Port x lock bit y (y= + 0..15) + 6 + 1 + + + + LCK5 + Port x lock bit y (y= + 0..15) + 5 + 1 + + + + LCK4 + Port x lock bit y (y= + 0..15) + 4 + 1 + + + + LCK3 + Port x lock bit y (y= + 0..15) + 3 + 1 + + + + LCK2 + Port x lock bit y (y= + 0..15) + 2 + 1 + + + + LCK1 + Port x lock bit y (y= + 0..15) + 1 + 1 + + + + LCK0 + Port x lock bit y (y= + 0..15) + 0 + 1 + + LCK0 + read-write + + Unlocked + Port configuration not locked + 0 + + + Locked + Port configuration locked + 1 + + + + + + + AFRL + AFRL + GPIO alternate function low + register + 0x20 + 0x20 + read-write + 0x00000000 + + + AFRL7 + Alternate function selection for port x + bit y (y = 0..7) + 28 + 4 + + + + AFRL6 + Alternate function selection for port x + bit y (y = 0..7) + 24 + 4 + + + + AFRL5 + Alternate function selection for port x + bit y (y = 0..7) + 20 + 4 + + + + AFRL4 + Alternate function selection for port x + bit y (y = 0..7) + 16 + 4 + + + + AFRL3 + Alternate function selection for port x + bit y (y = 0..7) + 12 + 4 + + + + AFRL2 + Alternate function selection for port x + bit y (y = 0..7) + 8 + 4 + + + + AFRL1 + Alternate function selection for port x + bit y (y = 0..7) + 4 + 4 + + + + AFRL0 + Alternate function selection for port x + bit y (y = 0..7) + 0 + 4 + + AFRL0 + read-write + + AF0 + AF0 + 0 + + + AF1 + AF1 + 1 + + + AF2 + AF2 + 2 + + + AF3 + AF3 + 3 + + + AF4 + AF4 + 4 + + + AF5 + AF5 + 5 + + + AF6 + AF6 + 6 + + + AF7 + AF7 + 7 + + + AF8 + AF8 + 8 + + + AF9 + AF9 + 9 + + + AF10 + AF10 + 10 + + + AF11 + AF11 + 11 + + + AF12 + AF12 + 12 + + + AF13 + AF13 + 13 + + + AF14 + AF14 + 14 + + + AF15 + AF15 + 15 + + + + + + + AFRH + AFRH + GPIO alternate function high + register + 0x24 + 0x20 + read-write + 0x00000000 + + + AFRH15 + Alternate function selection for port x + bit y (y = 8..15) + 28 + 4 + + + + AFRH14 + Alternate function selection for port x + bit y (y = 8..15) + 24 + 4 + + + + AFRH13 + Alternate function selection for port x + bit y (y = 8..15) + 20 + 4 + + + + AFRH12 + Alternate function selection for port x + bit y (y = 8..15) + 16 + 4 + + + + AFRH11 + Alternate function selection for port x + bit y (y = 8..15) + 12 + 4 + + + + AFRH10 + Alternate function selection for port x + bit y (y = 8..15) + 8 + 4 + + + + AFRH9 + Alternate function selection for port x + bit y (y = 8..15) + 4 + 4 + + + + AFRH8 + Alternate function selection for port x + bit y (y = 8..15) + 0 + 4 + + AFRH8 + read-write + + AF0 + AF0 + 0 + + + AF1 + AF1 + 1 + + + AF2 + AF2 + 2 + + + AF3 + AF3 + 3 + + + AF4 + AF4 + 4 + + + AF5 + AF5 + 5 + + + AF6 + AF6 + 6 + + + AF7 + AF7 + 7 + + + AF8 + AF8 + 8 + + + AF9 + AF9 + 9 + + + AF10 + AF10 + 10 + + + AF11 + AF11 + 11 + + + AF12 + AF12 + 12 + + + AF13 + AF13 + 13 + + + AF14 + AF14 + 14 + + + AF15 + AF15 + 15 + + + + + + + + + GPIOE + 0x40021000 + + + GPIOD + 0x40020C00 + + TIM1_BRK_TIM9 + TIM1 Break interrupt and TIM9 global + interrupt + 24 + + + TIM1_UP_TIM10 + TIM1 Update interrupt and TIM10 global + interrupt + 25 + + + TIM1_TRG_COM_TIM11 + TIM1 Trigger and Commutation interrupts and + TIM11 global interrupt + 26 + + + TIM1_CC + TIM1 Capture Compare interrupt + 27 + + + + GPIOC + 0x40020800 + + TIM1_UP_TIM10 + TIM1 Update interrupt and TIM10 global + interrupt + 25 + + + + GPIOB + General-purpose I/Os + GPIO + 0x40020400 + + 0x0 + 0x400 + registers + + + TIM1_TRG_COM_TIM11 + TIM1 Trigger and Commutation interrupts and + TIM11 global interrupt + 26 + + + + MODER + MODER + GPIO port mode register + 0x0 + 0x20 + read-write + 0x00000280 + + + MODER15 + Port x configuration bits (y = + 0..15) + 30 + 2 + + + + MODER14 + Port x configuration bits (y = + 0..15) + 28 + 2 + + + + MODER13 + Port x configuration bits (y = + 0..15) + 26 + 2 + + + + MODER12 + Port x configuration bits (y = + 0..15) + 24 + 2 + + + + MODER11 + Port x configuration bits (y = + 0..15) + 22 + 2 + + + + MODER10 + Port x configuration bits (y = + 0..15) + 20 + 2 + + + + MODER9 + Port x configuration bits (y = + 0..15) + 18 + 2 + + + + MODER8 + Port x configuration bits (y = + 0..15) + 16 + 2 + + + + MODER7 + Port x configuration bits (y = + 0..15) + 14 + 2 + + + + MODER6 + Port x configuration bits (y = + 0..15) + 12 + 2 + + + + MODER5 + Port x configuration bits (y = + 0..15) + 10 + 2 + + + + MODER4 + Port x configuration bits (y = + 0..15) + 8 + 2 + + + + MODER3 + Port x configuration bits (y = + 0..15) + 6 + 2 + + + + MODER2 + Port x configuration bits (y = + 0..15) + 4 + 2 + + + + MODER1 + Port x configuration bits (y = + 0..15) + 2 + 2 + + + + MODER0 + Port x configuration bits (y = + 0..15) + 0 + 2 + + MODER0 + read-write + + Input + Input mode (reset state) + 0 + + + Output + General purpose output mode + 1 + + + Alternate + Alternate function mode + 2 + + + Analog + Analog mode + 3 + + + + + + + OTYPER + OTYPER + GPIO port output type register + 0x4 + 0x20 + read-write + 0x00000000 + + + OT15 + Port x configuration bits (y = + 0..15) + 15 + 1 + + + + OT14 + Port x configuration bits (y = + 0..15) + 14 + 1 + + + + OT13 + Port x configuration bits (y = + 0..15) + 13 + 1 + + + + OT12 + Port x configuration bits (y = + 0..15) + 12 + 1 + + + + OT11 + Port x configuration bits (y = + 0..15) + 11 + 1 + + + + OT10 + Port x configuration bits (y = + 0..15) + 10 + 1 + + + + OT9 + Port x configuration bits (y = + 0..15) + 9 + 1 + + + + OT8 + Port x configuration bits (y = + 0..15) + 8 + 1 + + + + OT7 + Port x configuration bits (y = + 0..15) + 7 + 1 + + + + OT6 + Port x configuration bits (y = + 0..15) + 6 + 1 + + + + OT5 + Port x configuration bits (y = + 0..15) + 5 + 1 + + + + OT4 + Port x configuration bits (y = + 0..15) + 4 + 1 + + + + OT3 + Port x configuration bits (y = + 0..15) + 3 + 1 + + + + OT2 + Port x configuration bits (y = + 0..15) + 2 + 1 + + + + OT1 + Port x configuration bits (y = + 0..15) + 1 + 1 + + + + OT0 + Port x configuration bits (y = + 0..15) + 0 + 1 + + OT0 + read-write + + PushPull + Output push-pull (reset state) + 0 + + + OpenDrain + Output open-drain + 1 + + + + + + + OSPEEDR + OSPEEDR + GPIO port output speed + register + 0x8 + 0x20 + read-write + 0x000000C0 + + + OSPEEDR15 + Port x configuration bits (y = + 0..15) + 30 + 2 + + + + OSPEEDR14 + Port x configuration bits (y = + 0..15) + 28 + 2 + + + + OSPEEDR13 + Port x configuration bits (y = + 0..15) + 26 + 2 + + + + OSPEEDR12 + Port x configuration bits (y = + 0..15) + 24 + 2 + + + + OSPEEDR11 + Port x configuration bits (y = + 0..15) + 22 + 2 + + + + OSPEEDR10 + Port x configuration bits (y = + 0..15) + 20 + 2 + + + + OSPEEDR9 + Port x configuration bits (y = + 0..15) + 18 + 2 + + + + OSPEEDR8 + Port x configuration bits (y = + 0..15) + 16 + 2 + + + + OSPEEDR7 + Port x configuration bits (y = + 0..15) + 14 + 2 + + + + OSPEEDR6 + Port x configuration bits (y = + 0..15) + 12 + 2 + + + + OSPEEDR5 + Port x configuration bits (y = + 0..15) + 10 + 2 + + + + OSPEEDR4 + Port x configuration bits (y = + 0..15) + 8 + 2 + + + + OSPEEDR3 + Port x configuration bits (y = + 0..15) + 6 + 2 + + + + OSPEEDR2 + Port x configuration bits (y = + 0..15) + 4 + 2 + + + + OSPEEDR1 + Port x configuration bits (y = + 0..15) + 2 + 2 + + + + OSPEEDR0 + Port x configuration bits (y = + 0..15) + 0 + 2 + + OSPEEDR0 + read-write + + LowSpeed + Low speed + 0 + + + MediumSpeed + Medium speed + 1 + + + HighSpeed + High speed + 2 + + + VeryHighSpeed + Very high speed + 3 + + + + + + + PUPDR + PUPDR + GPIO port pull-up/pull-down + register + 0xC + 0x20 + read-write + 0x00000100 + + + PUPDR15 + Port x configuration bits (y = + 0..15) + 30 + 2 + + + + PUPDR14 + Port x configuration bits (y = + 0..15) + 28 + 2 + + + + PUPDR13 + Port x configuration bits (y = + 0..15) + 26 + 2 + + + + PUPDR12 + Port x configuration bits (y = + 0..15) + 24 + 2 + + + + PUPDR11 + Port x configuration bits (y = + 0..15) + 22 + 2 + + + + PUPDR10 + Port x configuration bits (y = + 0..15) + 20 + 2 + + + + PUPDR9 + Port x configuration bits (y = + 0..15) + 18 + 2 + + + + PUPDR8 + Port x configuration bits (y = + 0..15) + 16 + 2 + + + + PUPDR7 + Port x configuration bits (y = + 0..15) + 14 + 2 + + + + PUPDR6 + Port x configuration bits (y = + 0..15) + 12 + 2 + + + + PUPDR5 + Port x configuration bits (y = + 0..15) + 10 + 2 + + + + PUPDR4 + Port x configuration bits (y = + 0..15) + 8 + 2 + + + + PUPDR3 + Port x configuration bits (y = + 0..15) + 6 + 2 + + + + PUPDR2 + Port x configuration bits (y = + 0..15) + 4 + 2 + + + + PUPDR1 + Port x configuration bits (y = + 0..15) + 2 + 2 + + + + PUPDR0 + Port x configuration bits (y = + 0..15) + 0 + 2 + + PUPDR0 + read-write + + Floating + No pull-up, pull-down + 0 + + + PullUp + Pull-up + 1 + + + PullDown + Pull-down + 2 + + + + + + + IDR + IDR + GPIO port input data register + 0x10 + 0x20 + read-only + 0x00000000 + + + IDR15 + Port input data (y = + 0..15) + 15 + 1 + + + + IDR14 + Port input data (y = + 0..15) + 14 + 1 + + + + IDR13 + Port input data (y = + 0..15) + 13 + 1 + + + + IDR12 + Port input data (y = + 0..15) + 12 + 1 + + + + IDR11 + Port input data (y = + 0..15) + 11 + 1 + + + + IDR10 + Port input data (y = + 0..15) + 10 + 1 + + + + IDR9 + Port input data (y = + 0..15) + 9 + 1 + + + + IDR8 + Port input data (y = + 0..15) + 8 + 1 + + + + IDR7 + Port input data (y = + 0..15) + 7 + 1 + + + + IDR6 + Port input data (y = + 0..15) + 6 + 1 + + + + IDR5 + Port input data (y = + 0..15) + 5 + 1 + + + + IDR4 + Port input data (y = + 0..15) + 4 + 1 + + + + IDR3 + Port input data (y = + 0..15) + 3 + 1 + + + + IDR2 + Port input data (y = + 0..15) + 2 + 1 + + + + IDR1 + Port input data (y = + 0..15) + 1 + 1 + + + + IDR0 + Port input data (y = + 0..15) + 0 + 1 + + IDR0 + read + + Low + Input is logic low + 0 + + + High + Input is logic high + 1 + + + + + + + ODR + ODR + GPIO port output data register + 0x14 + 0x20 + read-write + 0x00000000 + + + ODR15 + Port output data (y = + 0..15) + 15 + 1 + + + + ODR14 + Port output data (y = + 0..15) + 14 + 1 + + + + ODR13 + Port output data (y = + 0..15) + 13 + 1 + + + + ODR12 + Port output data (y = + 0..15) + 12 + 1 + + + + ODR11 + Port output data (y = + 0..15) + 11 + 1 + + + + ODR10 + Port output data (y = + 0..15) + 10 + 1 + + + + ODR9 + Port output data (y = + 0..15) + 9 + 1 + + + + ODR8 + Port output data (y = + 0..15) + 8 + 1 + + + + ODR7 + Port output data (y = + 0..15) + 7 + 1 + + + + ODR6 + Port output data (y = + 0..15) + 6 + 1 + + + + ODR5 + Port output data (y = + 0..15) + 5 + 1 + + + + ODR4 + Port output data (y = + 0..15) + 4 + 1 + + + + ODR3 + Port output data (y = + 0..15) + 3 + 1 + + + + ODR2 + Port output data (y = + 0..15) + 2 + 1 + + + + ODR1 + Port output data (y = + 0..15) + 1 + 1 + + + + ODR0 + Port output data (y = + 0..15) + 0 + 1 + + ODR0 + read-write + + Low + Set output to logic low + 0 + + + High + Set output to logic high + 1 + + + + + + + BSRR + BSRR + GPIO port bit set/reset + register + 0x18 + 0x20 + write-only + 0x00000000 + + + BR15 + Port x reset bit y (y = + 0..15) + 31 + 1 + + + + BR14 + Port x reset bit y (y = + 0..15) + 30 + 1 + + + + BR13 + Port x reset bit y (y = + 0..15) + 29 + 1 + + + + BR12 + Port x reset bit y (y = + 0..15) + 28 + 1 + + + + BR11 + Port x reset bit y (y = + 0..15) + 27 + 1 + + + + BR10 + Port x reset bit y (y = + 0..15) + 26 + 1 + + + + BR9 + Port x reset bit y (y = + 0..15) + 25 + 1 + + + + BR8 + Port x reset bit y (y = + 0..15) + 24 + 1 + + + + BR7 + Port x reset bit y (y = + 0..15) + 23 + 1 + + + + BR6 + Port x reset bit y (y = + 0..15) + 22 + 1 + + + + BR5 + Port x reset bit y (y = + 0..15) + 21 + 1 + + + + BR4 + Port x reset bit y (y = + 0..15) + 20 + 1 + + + + BR3 + Port x reset bit y (y = + 0..15) + 19 + 1 + + + + BR2 + Port x reset bit y (y = + 0..15) + 18 + 1 + + + + BR1 + Port x reset bit y (y = + 0..15) + 17 + 1 + + + + BR0 + Port x set bit y (y= + 0..15) + 16 + 1 + + BR0W + write + + Reset + Resets the corresponding ODRx bit + 1 + + + + + BS15 + Port x set bit y (y= + 0..15) + 15 + 1 + + + + BS14 + Port x set bit y (y= + 0..15) + 14 + 1 + + + + BS13 + Port x set bit y (y= + 0..15) + 13 + 1 + + + + BS12 + Port x set bit y (y= + 0..15) + 12 + 1 + + + + BS11 + Port x set bit y (y= + 0..15) + 11 + 1 + + + + BS10 + Port x set bit y (y= + 0..15) + 10 + 1 + + + + BS9 + Port x set bit y (y= + 0..15) + 9 + 1 + + + + BS8 + Port x set bit y (y= + 0..15) + 8 + 1 + + + + BS7 + Port x set bit y (y= + 0..15) + 7 + 1 + + + + BS6 + Port x set bit y (y= + 0..15) + 6 + 1 + + + + BS5 + Port x set bit y (y= + 0..15) + 5 + 1 + + + + BS4 + Port x set bit y (y= + 0..15) + 4 + 1 + + + + BS3 + Port x set bit y (y= + 0..15) + 3 + 1 + + + + BS2 + Port x set bit y (y= + 0..15) + 2 + 1 + + + + BS1 + Port x set bit y (y= + 0..15) + 1 + 1 + + + + BS0 + Port x set bit y (y= + 0..15) + 0 + 1 + + BS0W + write + + Set + Sets the corresponding ODRx bit + 1 + + + + + + + LCKR + LCKR + GPIO port configuration lock + register + 0x1C + 0x20 + read-write + 0x00000000 + + + LCKK + Port x lock bit y (y= + 0..15) + 16 + 1 + + LCKK + read-write + + NotActive + Port configuration lock key not active + 0 + + + Active + Port configuration lock key active + 1 + + + + + LCK15 + Port x lock bit y (y= + 0..15) + 15 + 1 + + + + LCK14 + Port x lock bit y (y= + 0..15) + 14 + 1 + + + + LCK13 + Port x lock bit y (y= + 0..15) + 13 + 1 + + + + LCK12 + Port x lock bit y (y= + 0..15) + 12 + 1 + + + + LCK11 + Port x lock bit y (y= + 0..15) + 11 + 1 + + + + LCK10 + Port x lock bit y (y= + 0..15) + 10 + 1 + + + + LCK9 + Port x lock bit y (y= + 0..15) + 9 + 1 + + + + LCK8 + Port x lock bit y (y= + 0..15) + 8 + 1 + + + + LCK7 + Port x lock bit y (y= + 0..15) + 7 + 1 + + + + LCK6 + Port x lock bit y (y= + 0..15) + 6 + 1 + + + + LCK5 + Port x lock bit y (y= + 0..15) + 5 + 1 + + + + LCK4 + Port x lock bit y (y= + 0..15) + 4 + 1 + + + + LCK3 + Port x lock bit y (y= + 0..15) + 3 + 1 + + + + LCK2 + Port x lock bit y (y= + 0..15) + 2 + 1 + + + + LCK1 + Port x lock bit y (y= + 0..15) + 1 + 1 + + + + LCK0 + Port x lock bit y (y= + 0..15) + 0 + 1 + + LCK0 + read-write + + Unlocked + Port configuration not locked + 0 + + + Locked + Port configuration locked + 1 + + + + + + + AFRL + AFRL + GPIO alternate function low + register + 0x20 + 0x20 + read-write + 0x00000000 + + + AFRL7 + Alternate function selection for port x + bit y (y = 0..7) + 28 + 4 + + + + AFRL6 + Alternate function selection for port x + bit y (y = 0..7) + 24 + 4 + + + + AFRL5 + Alternate function selection for port x + bit y (y = 0..7) + 20 + 4 + + + + AFRL4 + Alternate function selection for port x + bit y (y = 0..7) + 16 + 4 + + + + AFRL3 + Alternate function selection for port x + bit y (y = 0..7) + 12 + 4 + + + + AFRL2 + Alternate function selection for port x + bit y (y = 0..7) + 8 + 4 + + + + AFRL1 + Alternate function selection for port x + bit y (y = 0..7) + 4 + 4 + + + + AFRL0 + Alternate function selection for port x + bit y (y = 0..7) + 0 + 4 + + AFRL0 + read-write + + AF0 + AF0 + 0 + + + AF1 + AF1 + 1 + + + AF2 + AF2 + 2 + + + AF3 + AF3 + 3 + + + AF4 + AF4 + 4 + + + AF5 + AF5 + 5 + + + AF6 + AF6 + 6 + + + AF7 + AF7 + 7 + + + AF8 + AF8 + 8 + + + AF9 + AF9 + 9 + + + AF10 + AF10 + 10 + + + AF11 + AF11 + 11 + + + AF12 + AF12 + 12 + + + AF13 + AF13 + 13 + + + AF14 + AF14 + 14 + + + AF15 + AF15 + 15 + + + + + + + AFRH + AFRH + GPIO alternate function high + register + 0x24 + 0x20 + read-write + 0x00000000 + + + AFRH15 + Alternate function selection for port x + bit y (y = 8..15) + 28 + 4 + + + + AFRH14 + Alternate function selection for port x + bit y (y = 8..15) + 24 + 4 + + + + AFRH13 + Alternate function selection for port x + bit y (y = 8..15) + 20 + 4 + + + + AFRH12 + Alternate function selection for port x + bit y (y = 8..15) + 16 + 4 + + + + AFRH11 + Alternate function selection for port x + bit y (y = 8..15) + 12 + 4 + + + + AFRH10 + Alternate function selection for port x + bit y (y = 8..15) + 8 + 4 + + + + AFRH9 + Alternate function selection for port x + bit y (y = 8..15) + 4 + 4 + + + + AFRH8 + Alternate function selection for port x + bit y (y = 8..15) + 0 + 4 + + AFRH8 + read-write + + AF0 + AF0 + 0 + + + AF1 + AF1 + 1 + + + AF2 + AF2 + 2 + + + AF3 + AF3 + 3 + + + AF4 + AF4 + 4 + + + AF5 + AF5 + 5 + + + AF6 + AF6 + 6 + + + AF7 + AF7 + 7 + + + AF8 + AF8 + 8 + + + AF9 + AF9 + 9 + + + AF10 + AF10 + 10 + + + AF11 + AF11 + 11 + + + AF12 + AF12 + 12 + + + AF13 + AF13 + 13 + + + AF14 + AF14 + 14 + + + AF15 + AF15 + 15 + + + + + + + + + GPIOA + General-purpose I/Os + GPIO + 0x40020000 + + 0x0 + 0x400 + registers + + + TIM2 + TIM2 global interrupt + 28 + + + + MODER + MODER + GPIO port mode register + 0x0 + 0x20 + read-write + 0xA8000000 + + + MODER15 + Port x configuration bits (y = + 0..15) + 30 + 2 + + + + MODER14 + Port x configuration bits (y = + 0..15) + 28 + 2 + + + + MODER13 + Port x configuration bits (y = + 0..15) + 26 + 2 + + + + MODER12 + Port x configuration bits (y = + 0..15) + 24 + 2 + + + + MODER11 + Port x configuration bits (y = + 0..15) + 22 + 2 + + + + MODER10 + Port x configuration bits (y = + 0..15) + 20 + 2 + + + + MODER9 + Port x configuration bits (y = + 0..15) + 18 + 2 + + + + MODER8 + Port x configuration bits (y = + 0..15) + 16 + 2 + + + + MODER7 + Port x configuration bits (y = + 0..15) + 14 + 2 + + + + MODER6 + Port x configuration bits (y = + 0..15) + 12 + 2 + + + + MODER5 + Port x configuration bits (y = + 0..15) + 10 + 2 + + + + MODER4 + Port x configuration bits (y = + 0..15) + 8 + 2 + + + + MODER3 + Port x configuration bits (y = + 0..15) + 6 + 2 + + + + MODER2 + Port x configuration bits (y = + 0..15) + 4 + 2 + + + + MODER1 + Port x configuration bits (y = + 0..15) + 2 + 2 + + + + MODER0 + Port x configuration bits (y = + 0..15) + 0 + 2 + + MODER0 + read-write + + Input + Input mode (reset state) + 0 + + + Output + General purpose output mode + 1 + + + Alternate + Alternate function mode + 2 + + + Analog + Analog mode + 3 + + + + + + + OTYPER + OTYPER + GPIO port output type register + 0x4 + 0x20 + read-write + 0x00000000 + + + OT15 + Port x configuration bits (y = + 0..15) + 15 + 1 + + + + OT14 + Port x configuration bits (y = + 0..15) + 14 + 1 + + + + OT13 + Port x configuration bits (y = + 0..15) + 13 + 1 + + + + OT12 + Port x configuration bits (y = + 0..15) + 12 + 1 + + + + OT11 + Port x configuration bits (y = + 0..15) + 11 + 1 + + + + OT10 + Port x configuration bits (y = + 0..15) + 10 + 1 + + + + OT9 + Port x configuration bits (y = + 0..15) + 9 + 1 + + + + OT8 + Port x configuration bits (y = + 0..15) + 8 + 1 + + + + OT7 + Port x configuration bits (y = + 0..15) + 7 + 1 + + + + OT6 + Port x configuration bits (y = + 0..15) + 6 + 1 + + + + OT5 + Port x configuration bits (y = + 0..15) + 5 + 1 + + + + OT4 + Port x configuration bits (y = + 0..15) + 4 + 1 + + + + OT3 + Port x configuration bits (y = + 0..15) + 3 + 1 + + + + OT2 + Port x configuration bits (y = + 0..15) + 2 + 1 + + + + OT1 + Port x configuration bits (y = + 0..15) + 1 + 1 + + + + OT0 + Port x configuration bits (y = + 0..15) + 0 + 1 + + OT0 + read-write + + PushPull + Output push-pull (reset state) + 0 + + + OpenDrain + Output open-drain + 1 + + + + + + + OSPEEDR + OSPEEDR + GPIO port output speed + register + 0x8 + 0x20 + read-write + 0x00000000 + + + OSPEEDR15 + Port x configuration bits (y = + 0..15) + 30 + 2 + + + + OSPEEDR14 + Port x configuration bits (y = + 0..15) + 28 + 2 + + + + OSPEEDR13 + Port x configuration bits (y = + 0..15) + 26 + 2 + + + + OSPEEDR12 + Port x configuration bits (y = + 0..15) + 24 + 2 + + + + OSPEEDR11 + Port x configuration bits (y = + 0..15) + 22 + 2 + + + + OSPEEDR10 + Port x configuration bits (y = + 0..15) + 20 + 2 + + + + OSPEEDR9 + Port x configuration bits (y = + 0..15) + 18 + 2 + + + + OSPEEDR8 + Port x configuration bits (y = + 0..15) + 16 + 2 + + + + OSPEEDR7 + Port x configuration bits (y = + 0..15) + 14 + 2 + + + + OSPEEDR6 + Port x configuration bits (y = + 0..15) + 12 + 2 + + + + OSPEEDR5 + Port x configuration bits (y = + 0..15) + 10 + 2 + + + + OSPEEDR4 + Port x configuration bits (y = + 0..15) + 8 + 2 + + + + OSPEEDR3 + Port x configuration bits (y = + 0..15) + 6 + 2 + + + + OSPEEDR2 + Port x configuration bits (y = + 0..15) + 4 + 2 + + + + OSPEEDR1 + Port x configuration bits (y = + 0..15) + 2 + 2 + + + + OSPEEDR0 + Port x configuration bits (y = + 0..15) + 0 + 2 + + OSPEEDR0 + read-write + + LowSpeed + Low speed + 0 + + + MediumSpeed + Medium speed + 1 + + + HighSpeed + High speed + 2 + + + VeryHighSpeed + Very high speed + 3 + + + + + + + PUPDR + PUPDR + GPIO port pull-up/pull-down + register + 0xC + 0x20 + read-write + 0x64000000 + + + PUPDR15 + Port x configuration bits (y = + 0..15) + 30 + 2 + + + + PUPDR14 + Port x configuration bits (y = + 0..15) + 28 + 2 + + + + PUPDR13 + Port x configuration bits (y = + 0..15) + 26 + 2 + + + + PUPDR12 + Port x configuration bits (y = + 0..15) + 24 + 2 + + + + PUPDR11 + Port x configuration bits (y = + 0..15) + 22 + 2 + + + + PUPDR10 + Port x configuration bits (y = + 0..15) + 20 + 2 + + + + PUPDR9 + Port x configuration bits (y = + 0..15) + 18 + 2 + + + + PUPDR8 + Port x configuration bits (y = + 0..15) + 16 + 2 + + + + PUPDR7 + Port x configuration bits (y = + 0..15) + 14 + 2 + + + + PUPDR6 + Port x configuration bits (y = + 0..15) + 12 + 2 + + + + PUPDR5 + Port x configuration bits (y = + 0..15) + 10 + 2 + + + + PUPDR4 + Port x configuration bits (y = + 0..15) + 8 + 2 + + + + PUPDR3 + Port x configuration bits (y = + 0..15) + 6 + 2 + + + + PUPDR2 + Port x configuration bits (y = + 0..15) + 4 + 2 + + + + PUPDR1 + Port x configuration bits (y = + 0..15) + 2 + 2 + + + + PUPDR0 + Port x configuration bits (y = + 0..15) + 0 + 2 + + PUPDR0 + read-write + + Floating + No pull-up, pull-down + 0 + + + PullUp + Pull-up + 1 + + + PullDown + Pull-down + 2 + + + + + + + IDR + IDR + GPIO port input data register + 0x10 + 0x20 + read-only + 0x00000000 + + + IDR15 + Port input data (y = + 0..15) + 15 + 1 + + + + IDR14 + Port input data (y = + 0..15) + 14 + 1 + + + + IDR13 + Port input data (y = + 0..15) + 13 + 1 + + + + IDR12 + Port input data (y = + 0..15) + 12 + 1 + + + + IDR11 + Port input data (y = + 0..15) + 11 + 1 + + + + IDR10 + Port input data (y = + 0..15) + 10 + 1 + + + + IDR9 + Port input data (y = + 0..15) + 9 + 1 + + + + IDR8 + Port input data (y = + 0..15) + 8 + 1 + + + + IDR7 + Port input data (y = + 0..15) + 7 + 1 + + + + IDR6 + Port input data (y = + 0..15) + 6 + 1 + + + + IDR5 + Port input data (y = + 0..15) + 5 + 1 + + + + IDR4 + Port input data (y = + 0..15) + 4 + 1 + + + + IDR3 + Port input data (y = + 0..15) + 3 + 1 + + + + IDR2 + Port input data (y = + 0..15) + 2 + 1 + + + + IDR1 + Port input data (y = + 0..15) + 1 + 1 + + + + IDR0 + Port input data (y = + 0..15) + 0 + 1 + + IDR0 + read + + Low + Input is logic low + 0 + + + High + Input is logic high + 1 + + + + + + + ODR + ODR + GPIO port output data register + 0x14 + 0x20 + read-write + 0x00000000 + + + ODR15 + Port output data (y = + 0..15) + 15 + 1 + + + + ODR14 + Port output data (y = + 0..15) + 14 + 1 + + + + ODR13 + Port output data (y = + 0..15) + 13 + 1 + + + + ODR12 + Port output data (y = + 0..15) + 12 + 1 + + + + ODR11 + Port output data (y = + 0..15) + 11 + 1 + + + + ODR10 + Port output data (y = + 0..15) + 10 + 1 + + + + ODR9 + Port output data (y = + 0..15) + 9 + 1 + + + + ODR8 + Port output data (y = + 0..15) + 8 + 1 + + + + ODR7 + Port output data (y = + 0..15) + 7 + 1 + + + + ODR6 + Port output data (y = + 0..15) + 6 + 1 + + + + ODR5 + Port output data (y = + 0..15) + 5 + 1 + + + + ODR4 + Port output data (y = + 0..15) + 4 + 1 + + + + ODR3 + Port output data (y = + 0..15) + 3 + 1 + + + + ODR2 + Port output data (y = + 0..15) + 2 + 1 + + + + ODR1 + Port output data (y = + 0..15) + 1 + 1 + + + + ODR0 + Port output data (y = + 0..15) + 0 + 1 + + ODR0 + read-write + + Low + Set output to logic low + 0 + + + High + Set output to logic high + 1 + + + + + + + BSRR + BSRR + GPIO port bit set/reset + register + 0x18 + 0x20 + write-only + 0x00000000 + + + BR15 + Port x reset bit y (y = + 0..15) + 31 + 1 + + + + BR14 + Port x reset bit y (y = + 0..15) + 30 + 1 + + + + BR13 + Port x reset bit y (y = + 0..15) + 29 + 1 + + + + BR12 + Port x reset bit y (y = + 0..15) + 28 + 1 + + + + BR11 + Port x reset bit y (y = + 0..15) + 27 + 1 + + + + BR10 + Port x reset bit y (y = + 0..15) + 26 + 1 + + + + BR9 + Port x reset bit y (y = + 0..15) + 25 + 1 + + + + BR8 + Port x reset bit y (y = + 0..15) + 24 + 1 + + + + BR7 + Port x reset bit y (y = + 0..15) + 23 + 1 + + + + BR6 + Port x reset bit y (y = + 0..15) + 22 + 1 + + + + BR5 + Port x reset bit y (y = + 0..15) + 21 + 1 + + + + BR4 + Port x reset bit y (y = + 0..15) + 20 + 1 + + + + BR3 + Port x reset bit y (y = + 0..15) + 19 + 1 + + + + BR2 + Port x reset bit y (y = + 0..15) + 18 + 1 + + + + BR1 + Port x reset bit y (y = + 0..15) + 17 + 1 + + + + BR0 + Port x set bit y (y= + 0..15) + 16 + 1 + + BR0W + write + + Reset + Resets the corresponding ODRx bit + 1 + + + + + BS15 + Port x set bit y (y= + 0..15) + 15 + 1 + + + + BS14 + Port x set bit y (y= + 0..15) + 14 + 1 + + + + BS13 + Port x set bit y (y= + 0..15) + 13 + 1 + + + + BS12 + Port x set bit y (y= + 0..15) + 12 + 1 + + + + BS11 + Port x set bit y (y= + 0..15) + 11 + 1 + + + + BS10 + Port x set bit y (y= + 0..15) + 10 + 1 + + + + BS9 + Port x set bit y (y= + 0..15) + 9 + 1 + + + + BS8 + Port x set bit y (y= + 0..15) + 8 + 1 + + + + BS7 + Port x set bit y (y= + 0..15) + 7 + 1 + + + + BS6 + Port x set bit y (y= + 0..15) + 6 + 1 + + + + BS5 + Port x set bit y (y= + 0..15) + 5 + 1 + + + + BS4 + Port x set bit y (y= + 0..15) + 4 + 1 + + + + BS3 + Port x set bit y (y= + 0..15) + 3 + 1 + + + + BS2 + Port x set bit y (y= + 0..15) + 2 + 1 + + + + BS1 + Port x set bit y (y= + 0..15) + 1 + 1 + + + + BS0 + Port x set bit y (y= + 0..15) + 0 + 1 + + BS0W + write + + Set + Sets the corresponding ODRx bit + 1 + + + + + + + LCKR + LCKR + GPIO port configuration lock + register + 0x1C + 0x20 + read-write + 0x00000000 + + + LCKK + Port x lock bit y (y= + 0..15) + 16 + 1 + + LCKK + read-write + + NotActive + Port configuration lock key not active + 0 + + + Active + Port configuration lock key active + 1 + + + + + LCK15 + Port x lock bit y (y= + 0..15) + 15 + 1 + + + + LCK14 + Port x lock bit y (y= + 0..15) + 14 + 1 + + + + LCK13 + Port x lock bit y (y= + 0..15) + 13 + 1 + + + + LCK12 + Port x lock bit y (y= + 0..15) + 12 + 1 + + + + LCK11 + Port x lock bit y (y= + 0..15) + 11 + 1 + + + + LCK10 + Port x lock bit y (y= + 0..15) + 10 + 1 + + + + LCK9 + Port x lock bit y (y= + 0..15) + 9 + 1 + + + + LCK8 + Port x lock bit y (y= + 0..15) + 8 + 1 + + + + LCK7 + Port x lock bit y (y= + 0..15) + 7 + 1 + + + + LCK6 + Port x lock bit y (y= + 0..15) + 6 + 1 + + + + LCK5 + Port x lock bit y (y= + 0..15) + 5 + 1 + + + + LCK4 + Port x lock bit y (y= + 0..15) + 4 + 1 + + + + LCK3 + Port x lock bit y (y= + 0..15) + 3 + 1 + + + + LCK2 + Port x lock bit y (y= + 0..15) + 2 + 1 + + + + LCK1 + Port x lock bit y (y= + 0..15) + 1 + 1 + + + + LCK0 + Port x lock bit y (y= + 0..15) + 0 + 1 + + LCK0 + read-write + + Unlocked + Port configuration not locked + 0 + + + Locked + Port configuration locked + 1 + + + + + + + AFRL + AFRL + GPIO alternate function low + register + 0x20 + 0x20 + read-write + 0x00000000 + + + AFRL7 + Alternate function selection for port x + bit y (y = 0..7) + 28 + 4 + + + + AFRL6 + Alternate function selection for port x + bit y (y = 0..7) + 24 + 4 + + + + AFRL5 + Alternate function selection for port x + bit y (y = 0..7) + 20 + 4 + + + + AFRL4 + Alternate function selection for port x + bit y (y = 0..7) + 16 + 4 + + + + AFRL3 + Alternate function selection for port x + bit y (y = 0..7) + 12 + 4 + + + + AFRL2 + Alternate function selection for port x + bit y (y = 0..7) + 8 + 4 + + + + AFRL1 + Alternate function selection for port x + bit y (y = 0..7) + 4 + 4 + + + + AFRL0 + Alternate function selection for port x + bit y (y = 0..7) + 0 + 4 + + AFRL0 + read-write + + AF0 + AF0 + 0 + + + AF1 + AF1 + 1 + + + AF2 + AF2 + 2 + + + AF3 + AF3 + 3 + + + AF4 + AF4 + 4 + + + AF5 + AF5 + 5 + + + AF6 + AF6 + 6 + + + AF7 + AF7 + 7 + + + AF8 + AF8 + 8 + + + AF9 + AF9 + 9 + + + AF10 + AF10 + 10 + + + AF11 + AF11 + 11 + + + AF12 + AF12 + 12 + + + AF13 + AF13 + 13 + + + AF14 + AF14 + 14 + + + AF15 + AF15 + 15 + + + + + + + AFRH + AFRH + GPIO alternate function high + register + 0x24 + 0x20 + read-write + 0x00000000 + + + AFRH15 + Alternate function selection for port x + bit y (y = 8..15) + 28 + 4 + + + + AFRH14 + Alternate function selection for port x + bit y (y = 8..15) + 24 + 4 + + + + AFRH13 + Alternate function selection for port x + bit y (y = 8..15) + 20 + 4 + + + + AFRH12 + Alternate function selection for port x + bit y (y = 8..15) + 16 + 4 + + + + AFRH11 + Alternate function selection for port x + bit y (y = 8..15) + 12 + 4 + + + + AFRH10 + Alternate function selection for port x + bit y (y = 8..15) + 8 + 4 + + + + AFRH9 + Alternate function selection for port x + bit y (y = 8..15) + 4 + 4 + + + + AFRH8 + Alternate function selection for port x + bit y (y = 8..15) + 0 + 4 + + AFRH8 + read-write + + AF0 + AF0 + 0 + + + AF1 + AF1 + 1 + + + AF2 + AF2 + 2 + + + AF3 + AF3 + 3 + + + AF4 + AF4 + 4 + + + AF5 + AF5 + 5 + + + AF6 + AF6 + 6 + + + AF7 + AF7 + 7 + + + AF8 + AF8 + 8 + + + AF9 + AF9 + 9 + + + AF10 + AF10 + 10 + + + AF11 + AF11 + 11 + + + AF12 + AF12 + 12 + + + AF13 + AF13 + 13 + + + AF14 + AF14 + 14 + + + AF15 + AF15 + 15 + + + + + + + + + I2C3 + 0x40005C00 + + TIM3 + TIM3 global interrupt + 29 + + + + I2C2 + 0x40005800 + + I2C3_EV + I2C3 event interrupt + 72 + + + I2C3_ER + I2C3 error interrupt + 73 + + + + I2C1 + Inter-integrated circuit + I2C + 0x40005400 + + 0x0 + 0x400 + registers + + + I2C2_EV + I2C2 event interrupt + 33 + + + I2C2_ER + I2C2 error interrupt + 34 + + + + CR1 + CR1 + Control register 1 + 0x0 + 0x20 + read-write + 0x00000000 + + + SWRST + Software reset + 15 + 1 + + SWRST + read-write + + NotReset + I2C peripheral not under reset + 0 + + + Reset + I2C peripheral under reset + 1 + + + + + ALERT + SMBus alert + 13 + 1 + + ALERT + read-write + + Release + SMBA pin released high + 0 + + + Drive + SMBA pin driven low + 1 + + + + + PEC + Packet error checking + 12 + 1 + + PEC + read-write + + Disabled + No PEC transfer + 0 + + + Enabled + PEC transfer + 1 + + + + + POS + Acknowledge/PEC Position (for data + reception) + 11 + 1 + + POS + read-write + + Current + ACK bit controls the (N)ACK of the current byte being received + 0 + + + Next + ACK bit controls the (N)ACK of the next byte to be received + 1 + + + + + ACK + Acknowledge enable + 10 + 1 + + ACK + read-write + + NAK + No acknowledge returned + 0 + + + ACK + Acknowledge returned after a byte is received + 1 + + + + + STOP + Stop generation + 9 + 1 + + STOP + read-write + + NoStop + No Stop generation + 0 + + + Stop + In master mode: stop generation after current byte/start, in slave mode: release SCL and SDA after current byte + 1 + + + + + START + Start generation + 8 + 1 + + START + read-write + + NoStart + No Start generation + 0 + + + Start + In master mode: repeated start generation, in slave mode: start generation when bus is free + 1 + + + + + NOSTRETCH + Clock stretching disable (Slave + mode) + 7 + 1 + + NOSTRETCH + read-write + + Enabled + Clock stretching enabled + 0 + + + Disabled + Clock stretching disabled + 1 + + + + + ENGC + General call enable + 6 + 1 + + ENGC + read-write + + Disabled + General call disabled + 0 + + + Enabled + General call enabled + 1 + + + + + ENPEC + PEC enable + 5 + 1 + + ENPEC + read-write + + Disabled + PEC calculation disabled + 0 + + + Enabled + PEC calculation enabled + 1 + + + + + ENARP + ARP enable + 4 + 1 + + ENARP + read-write + + Disabled + ARP disabled + 0 + + + Enabled + ARP enabled + 1 + + + + + SMBTYPE + SMBus type + 3 + 1 + + SMBTYPE + read-write + + Device + SMBus Device + 0 + + + Host + SMBus Host + 1 + + + + + SMBUS + SMBus mode + 1 + 1 + + SMBUS + read-write + + I2C + I2C Mode + 0 + + + SMBus + SMBus + 1 + + + + + PE + Peripheral enable + 0 + 1 + + PE + read-write + + Disabled + Peripheral disabled + 0 + + + Enabled + Peripheral enabled + 1 + + + + + + + CR2 + CR2 + Control register 2 + 0x4 + 0x20 + read-write + 0x00000000 + + + LAST + DMA last transfer + 12 + 1 + + LAST + read-write + + NotLast + Next DMA EOT is not the last transfer + 0 + + + Last + Next DMA EOT is the last transfer + 1 + + + + + DMAEN + DMA requests enable + 11 + 1 + + DMAEN + read-write + + Disabled + DMA requests disabled + 0 + + + Enabled + DMA request enabled when TxE=1 or RxNE=1 + 1 + + + + + ITBUFEN + Buffer interrupt enable + 10 + 1 + + ITBUFEN + read-write + + Disabled + TxE=1 or RxNE=1 does not generate any interrupt + 0 + + + Enabled + TxE=1 or RxNE=1 generates Event interrupt + 1 + + + + + ITEVTEN + Event interrupt enable + 9 + 1 + + ITEVTEN + read-write + + Disabled + Event interrupt disabled + 0 + + + Enabled + Event interrupt enabled + 1 + + + + + ITERREN + Error interrupt enable + 8 + 1 + + ITERREN + read-write + + Disabled + Error interrupt disabled + 0 + + + Enabled + Error interrupt enabled + 1 + + + + + FREQ + Peripheral clock frequency + 0 + 6 + + + 2 + 50 + + + + + + + OAR1 + OAR1 + Own address register 1 + 0x8 + 0x20 + read-write + 0x00000000 + + + ADDMODE + Addressing mode (slave + mode) + 15 + 1 + + ADDMODE + read-write + + ADD7 + 7-bit slave address + 0 + + + ADD10 + 10-bit slave address + 1 + + + + + ADD + Interface address + 0 + 10 + + + 0 + 1023 + + + + + + + OAR2 + OAR2 + Own address register 2 + 0xC + 0x20 + read-write + 0x00000000 + + + ADD2 + Interface address + 1 + 7 + + + 0 + 127 + + + + + ENDUAL + Dual addressing mode + enable + 0 + 1 + + ENDUAL + read-write + + Single + Single addressing mode + 0 + + + Dual + Dual addressing mode + 1 + + + + + + + DR + DR + Data register + 0x10 + 0x20 + read-write + 0x00000000 + + + DR + 8-bit data register + 0 + 8 + + + 0 + 255 + + + + + + + SR1 + SR1 + Status register 1 + 0x14 + 0x20 + 0x00000000 + + + SMBALERT + SMBus alert + 15 + 1 + read-write + zeroToClear + + SMBALERTR + read + + NoAlert + No SMBALERT occured + 0 + + + Alert + SMBALERT occurred + 1 + + + + SMBALERTW + write + + Clear + Clear flag + 0 + + + + + TIMEOUT + Timeout or Tlow error + 14 + 1 + read-write + zeroToClear + + TIMEOUTR + read + + NoTimeout + No Timeout error + 0 + + + Timeout + SCL remained LOW for 25 ms + 1 + + + + TIMEOUTW + write + + Clear + Clear flag + 0 + + + + + PECERR + PEC Error in reception + 12 + 1 + read-write + zeroToClear + + PECERRR + read + + NoError + no PEC error: receiver returns ACK after PEC reception (if ACK=1) + 0 + + + Error + PEC error: receiver returns NACK after PEC reception (whatever ACK) + 1 + + + + PECERRW + write + + Clear + Clear flag + 0 + + + + + OVR + Overrun/Underrun + 11 + 1 + read-write + zeroToClear + + OVRR + read + + NoOverrun + No overrun/underrun occured + 0 + + + Overrun + Overrun/underrun occured + 1 + + + + OVRW + write + + Clear + Clear flag + 0 + + + + + AF + Acknowledge failure + 10 + 1 + read-write + zeroToClear + + AFR + read + + NoFailure + No acknowledge failure + 0 + + + Failure + Acknowledge failure + 1 + + + + AFW + write + + Clear + Clear flag + 0 + + + + + ARLO + Arbitration lost (master + mode) + 9 + 1 + read-write + zeroToClear + + ARLOR + read + + NoLost + No Arbitration Lost detected + 0 + + + Lost + Arbitration Lost detected + 1 + + + + ARLOW + write + + Clear + Clear flag + 0 + + + + + BERR + Bus error + 8 + 1 + read-write + zeroToClear + + BERRR + read + + NoError + No misplaced Start or Stop condition + 0 + + + Error + Misplaced Start or Stop condition + 1 + + + + BERRW + write + + Clear + Clear flag + 0 + + + + + TxE + Data register empty + (transmitters) + 7 + 1 + read-only + + TxE + read + + NotEmpty + Data register not empty + 0 + + + Empty + Data register empty + 1 + + + + + RxNE + Data register not empty + (receivers) + 6 + 1 + read-only + + RxNE + read + + Empty + Data register empty + 0 + + + NotEmpty + Data register not empty + 1 + + + + + STOPF + Stop detection (slave + mode) + 4 + 1 + read-only + + STOPF + read + + NoStop + No Stop condition detected + 0 + + + Stop + Stop condition detected + 1 + + + + + ADD10 + 10-bit header sent (Master + mode) + 3 + 1 + read-only + + + BTF + Byte transfer finished + 2 + 1 + read-only + + BTF + read + + NotFinished + Data byte transfer not done + 0 + + + Finished + Data byte transfer successful + 1 + + + + + ADDR + Address sent (master mode)/matched + (slave mode) + 1 + 1 + read-only + + ADDR + read + + NotMatch + Adress mismatched or not received + 0 + + + Match + Received slave address matched with one of the enabled slave addresses + 1 + + + + + SB + Start bit (Master mode) + 0 + 1 + read-only + + SB + read + + NoStart + No Start condition + 0 + + + Start + Start condition generated + 1 + + + + + + + SR2 + SR2 + Status register 2 + 0x18 + 0x20 + read-only + 0x00000000 + + + PEC + acket error checking + register + 8 + 8 + + + DUALF + Dual flag (Slave mode) + 7 + 1 + + + SMBHOST + SMBus host header (Slave + mode) + 6 + 1 + + + SMBDEFAULT + SMBus device default address (Slave + mode) + 5 + 1 + + + GENCALL + General call address (Slave + mode) + 4 + 1 + + + TRA + Transmitter/receiver + 2 + 1 + + + BUSY + Bus busy + 1 + 1 + + + MSL + Master/slave + 0 + 1 + + + + + CCR + CCR + Clock control register + 0x1C + 0x20 + read-write + 0x00000000 + + + F_S + I2C master mode selection + 15 + 1 + + F_S + read-write + + Standard + Standard mode I2C + 0 + + + Fast + Fast mode I2C + 1 + + + + + DUTY + Fast mode duty cycle + 14 + 1 + + DUTY + read-write + + Duty2_1 + Duty cycle t_low/t_high = 2/1 + 0 + + + Duty16_9 + Duty cycle t_low/t_high = 16/9 + 1 + + + + + CCR + Clock control register in Fast/Standard + mode (Master mode) + 0 + 12 + + + 1 + 4095 + + + + + + + TRISE + TRISE + TRISE register + 0x20 + 0x20 + read-write + 0x00000002 + + + TRISE + Maximum rise time in Fast/Standard mode + (Master mode) + 0 + 6 + + + 0 + 63 + + + + + + + FLTR + FLTR register + 0x24 + read-write + 0x00000000 + + + ANOFF + Analog noise filter + 4 + 1 + + ANOFF + read-write + + Enabled + Analog noise filter enabled + 0 + + + Disabled + Analog noise filter disabled + 1 + + + + + DNF + Digital noise filter + 0 + 4 + + DNF + read-write + + NoFilter + Digital filter disabled + 0 + + + Filter1 + Digital filter enabled and filtering capability up to 1 tI2CCLK + 1 + + + Filter2 + Digital filter enabled and filtering capability up to 2 tI2CCLK + 2 + + + Filter3 + Digital filter enabled and filtering capability up to 3 tI2CCLK + 3 + + + Filter4 + Digital filter enabled and filtering capability up to 4 tI2CCLK + 4 + + + Filter5 + Digital filter enabled and filtering capability up to 5 tI2CCLK + 5 + + + Filter6 + Digital filter enabled and filtering capability up to 6 tI2CCLK + 6 + + + Filter7 + Digital filter enabled and filtering capability up to 7 tI2CCLK + 7 + + + Filter8 + Digital filter enabled and filtering capability up to 8 tI2CCLK + 8 + + + Filter9 + Digital filter enabled and filtering capability up to 9 tI2CCLK + 9 + + + Filter10 + Digital filter enabled and filtering capability up to 10 tI2CCLK + 10 + + + Filter11 + Digital filter enabled and filtering capability up to 11 tI2CCLK + 11 + + + Filter12 + Digital filter enabled and filtering capability up to 12 tI2CCLK + 12 + + + Filter13 + Digital filter enabled and filtering capability up to 13 tI2CCLK + 13 + + + Filter14 + Digital filter enabled and filtering capability up to 14 tI2CCLK + 14 + + + Filter15 + Digital filter enabled and filtering capability up to 15 tI2CCLK + 15 + + + + + + + + + I2S2ext + 0x40003400 + + I2C1_EV + I2C1 event interrupt + 31 + + + I2C1_ER + I2C1 error interrupt + 32 + + + + I2S3ext + 0x40004000 + + + SPI1 + Serial peripheral interface + SPI + 0x40013000 + + 0x0 + 0x400 + registers + + + + CR1 + CR1 + control register 1 + 0x0 + 0x20 + read-write + 0x00000000 + + + BIDIMODE + Bidirectional data mode + enable + 15 + 1 + + BIDIMODE + read-write + + Unidirectional + 2-line unidirectional data mode selected + 0 + + + Bidirectional + 1-line bidirectional data mode selected + 1 + + + + + BIDIOE + Output enable in bidirectional + mode + 14 + 1 + + BIDIOE + read-write + + OutputDisabled + Output disabled (receive-only mode) + 0 + + + OutputEnabled + Output enabled (transmit-only mode) + 1 + + + + + CRCEN + Hardware CRC calculation + enable + 13 + 1 + + CRCEN + read-write + + Disabled + CRC calculation disabled + 0 + + + Enabled + CRC calculation enabled + 1 + + + + + CRCNEXT + CRC transfer next + 12 + 1 + + CRCNEXT + read-write + + TxBuffer + Next transmit value is from Tx buffer + 0 + + + CRC + Next transmit value is from Tx CRC register + 1 + + + + + DFF + Data frame format + 11 + 1 + + DFF + read-write + + EightBit + 8-bit data frame format is selected for transmission/reception + 0 + + + SixteenBit + 16-bit data frame format is selected for transmission/reception + 1 + + + + + RXONLY + Receive only + 10 + 1 + + RXONLY + read-write + + FullDuplex + Full duplex (Transmit and receive) + 0 + + + OutputDisabled + Output disabled (Receive-only mode) + 1 + + + + + SSM + Software slave management + 9 + 1 + + SSM + read-write + + Disabled + Software slave management disabled + 0 + + + Enabled + Software slave management enabled + 1 + + + + + SSI + Internal slave select + 8 + 1 + + SSI + read-write + + SlaveSelected + 0 is forced onto the NSS pin and the I/O value of the NSS pin is ignored + 0 + + + SlaveNotSelected + 1 is forced onto the NSS pin and the I/O value of the NSS pin is ignored + 1 + + + + + LSBFIRST + Frame format + 7 + 1 + + LSBFIRST + read-write + + MSBFirst + Data is transmitted/received with the MSB first + 0 + + + LSBFirst + Data is transmitted/received with the LSB first + 1 + + + + + SPE + SPI enable + 6 + 1 + + SPE + read-write + + Disabled + Peripheral disabled + 0 + + + Enabled + Peripheral enabled + 1 + + + + + BR + Baud rate control + 3 + 3 + + BR + read-write + + Div2 + f_PCLK / 2 + 0 + + + Div4 + f_PCLK / 4 + 1 + + + Div8 + f_PCLK / 8 + 2 + + + Div16 + f_PCLK / 16 + 3 + + + Div32 + f_PCLK / 32 + 4 + + + Div64 + f_PCLK / 64 + 5 + + + Div128 + f_PCLK / 128 + 6 + + + Div256 + f_PCLK / 256 + 7 + + + + + MSTR + Master selection + 2 + 1 + + MSTR + read-write + + Slave + Slave configuration + 0 + + + Master + Master configuration + 1 + + + + + CPOL + Clock polarity + 1 + 1 + + CPOL + read-write + + IdleLow + CK to 0 when idle + 0 + + + IdleHigh + CK to 1 when idle + 1 + + + + + CPHA + Clock phase + 0 + 1 + + CPHA + read-write + + FirstEdge + The first clock transition is the first data capture edge + 0 + + + SecondEdge + The second clock transition is the first data capture edge + 1 + + + + + + + CR2 + CR2 + control register 2 + 0x4 + 0x20 + read-write + 0x00000000 + + + TXEIE + Tx buffer empty interrupt + enable + 7 + 1 + + TXEIE + read-write + + Masked + TXE interrupt masked + 0 + + + NotMasked + TXE interrupt not masked + 1 + + + + + RXNEIE + RX buffer not empty interrupt + enable + 6 + 1 + + RXNEIE + read-write + + Masked + RXE interrupt masked + 0 + + + NotMasked + RXE interrupt not masked + 1 + + + + + ERRIE + Error interrupt enable + 5 + 1 + + ERRIE + read-write + + Masked + Error interrupt masked + 0 + + + NotMasked + Error interrupt not masked + 1 + + + + + FRF + Frame format + 4 + 1 + + FRF + read-write + + Motorola + SPI Motorola mode + 0 + + + TI + SPI TI mode + 1 + + + + + SSOE + SS output enable + 2 + 1 + + SSOE + read-write + + Disabled + SS output is disabled in master mode + 0 + + + Enabled + SS output is enabled in master mode + 1 + + + + + TXDMAEN + Tx buffer DMA enable + 1 + 1 + + TXDMAEN + read-write + + Disabled + Tx buffer DMA disabled + 0 + + + Enabled + Tx buffer DMA enabled + 1 + + + + + RXDMAEN + Rx buffer DMA enable + 0 + 1 + + RXDMAEN + read-write + + Disabled + Rx buffer DMA disabled + 0 + + + Enabled + Rx buffer DMA enabled + 1 + + + + + + + SR + SR + status register + 0x8 + 0x20 + 0x00000002 + + + FRE + TI frame format error + 8 + 1 + read-only + + FRER + read + + NoError + No frame format error + 0 + + + Error + A frame format error occurred + 1 + + + + + BSY + Busy flag + 7 + 1 + read-only + + BSYR + read + + NotBusy + SPI not busy + 0 + + + Busy + SPI busy + 1 + + + + + OVR + Overrun flag + 6 + 1 + read-only + + OVRR + read + + NoOverrun + No overrun occurred + 0 + + + Overrun + Overrun occurred + 1 + + + + + MODF + Mode fault + 5 + 1 + read-only + + MODFR + read + + NoFault + No mode fault occurred + 0 + + + Fault + Mode fault occurred + 1 + + + + + CRCERR + CRC error flag + 4 + 1 + read-write + zeroToClear + + CRCERRR + read + + Match + CRC value received matches the SPIx_RXCRCR value + 0 + + + NoMatch + CRC value received does not match the SPIx_RXCRCR value + 1 + + + + CRCERRW + write + + Clear + Clear flag + 0 + + + + + UDR + Underrun flag + 3 + 1 + read-only + + UDRR + read + + NoUnderrun + No underrun occurred + 0 + + + Underrun + Underrun occurred + 1 + + + + + CHSIDE + Channel side + 2 + 1 + read-only + + CHSIDE + read + + Left + Channel left has to be transmitted or has been received + 0 + + + Right + Channel right has to be transmitted or has been received + 1 + + + + + TXE + Transmit buffer empty + 1 + 1 + read-only + + TXE + read + + NotEmpty + Tx buffer not empty + 0 + + + Empty + Tx buffer empty + 1 + + + + + RXNE + Receive buffer not empty + 0 + 1 + read-only + + RXNE + read + + Empty + Rx buffer empty + 0 + + + NotEmpty + Rx buffer not empty + 1 + + + + + + + DR + DR + data register + 0xC + 0x20 + read-write + 0x00000000 + + + DR + Data register + 0 + 16 + + + 0 + 65535 + + + + + + + CRCPR + CRCPR + CRC polynomial register + 0x10 + 0x20 + read-write + 0x00000007 + + + CRCPOLY + CRC polynomial register + 0 + 16 + + + 0 + 65535 + + + + + + + RXCRCR + RXCRCR + RX CRC register + 0x14 + 0x20 + read-only + 0x00000000 + + + RxCRC + Rx CRC register + 0 + 16 + + + 0 + 65535 + + + + + + + TXCRCR + TXCRCR + TX CRC register + 0x18 + 0x20 + read-only + 0x00000000 + + + TxCRC + Tx CRC register + 0 + 16 + + + 0 + 65535 + + + + + + + I2SCFGR + I2SCFGR + I2S configuration register + 0x1C + 0x20 + read-write + 0x00000000 + + + I2SMOD + I2S mode selection + 11 + 1 + + I2SMOD + read-write + + SPIMode + SPI mode is selected + 0 + + + I2SMode + I2S mode is selected + 1 + + + + + I2SE + I2S Enable + 10 + 1 + + I2SE + read-write + + Disabled + I2S peripheral is disabled + 0 + + + Enabled + I2S peripheral is enabled + 1 + + + + + I2SCFG + I2S configuration mode + 8 + 2 + + I2SCFG + read-write + + SlaveTx + Slave - transmit + 0 + + + SlaveRx + Slave - receive + 1 + + + MasterTx + Master - transmit + 2 + + + MasterRx + Master - receive + 3 + + + + + PCMSYNC + PCM frame synchronization + 7 + 1 + + PCMSYNC + read-write + + Short + Short frame synchronisation + 0 + + + Long + Long frame synchronisation + 1 + + + + + I2SSTD + I2S standard selection + 4 + 2 + + I2SSTD + read-write + + Philips + I2S Philips standard + 0 + + + MSB + MSB justified standard + 1 + + + LSB + LSB justified standard + 2 + + + PCM + PCM standard + 3 + + + + + CKPOL + Steady state clock + polarity + 3 + 1 + + CKPOL + read-write + + IdleLow + I2S clock inactive state is low level + 0 + + + IdleHigh + I2S clock inactive state is high level + 1 + + + + + DATLEN + Data length to be + transferred + 1 + 2 + + DATLEN + read-write + + SixteenBit + 16-bit data length + 0 + + + TwentyFourBit + 24-bit data length + 1 + + + ThirtyTwoBit + 32-bit data length + 2 + + + + + CHLEN + Channel length (number of bits per audio + channel) + 0 + 1 + + CHLEN + read-write + + SixteenBit + 16-bit wide + 0 + + + ThirtyTwoBit + 32-bit wide + 1 + + + + + + + I2SPR + I2SPR + I2S prescaler register + 0x20 + 0x20 + read-write + 0x0000000A + + + MCKOE + Master clock output enable + 9 + 1 + + MCKOE + read-write + + Disabled + Master clock output is disabled + 0 + + + Enabled + Master clock output is enabled + 1 + + + + + ODD + Odd factor for the + prescaler + 8 + 1 + + ODD + read-write + + Even + Real divider value is I2SDIV * 2 + 0 + + + Odd + Real divider value is (I2SDIV * 2) + 1 + 1 + + + + + I2SDIV + I2S Linear prescaler + 0 + 8 + + + 2 + 255 + + + + + + + + + SPI2 + 0x40003800 + + SPI1 + SPI1 global interrupt + 35 + + + + SPI3 + 0x40003C00 + + SPI2 + SPI2 global interrupt + 36 + + + + SPI4 + 0x40013400 + + SPI3 + SPI3 global interrupt + 51 + + + + NVIC + Nested Vectored Interrupt + Controller + NVIC + 0xE000E100 + + 0x0 + 0x351 + registers + + + + ISER0 + ISER0 + Interrupt Set-Enable Register + 0x0 + 0x20 + read-write + 0x00000000 + + + SETENA + SETENA + 0 + 32 + + + + + ISER1 + ISER1 + Interrupt Set-Enable Register + 0x4 + 0x20 + read-write + 0x00000000 + + + SETENA + SETENA + 0 + 32 + + + + + ISER2 + ISER2 + Interrupt Set-Enable Register + 0x8 + 0x20 + read-write + 0x00000000 + + + SETENA + SETENA + 0 + 32 + + + + + ICER0 + ICER0 + Interrupt Clear-Enable + Register + 0x80 + 0x20 + read-write + 0x00000000 + + + CLRENA + CLRENA + 0 + 32 + + + + + ICER1 + ICER1 + Interrupt Clear-Enable + Register + 0x84 + 0x20 + read-write + 0x00000000 + + + CLRENA + CLRENA + 0 + 32 + + + + + ICER2 + ICER2 + Interrupt Clear-Enable + Register + 0x88 + 0x20 + read-write + 0x00000000 + + + CLRENA + CLRENA + 0 + 32 + + + + + ISPR0 + ISPR0 + Interrupt Set-Pending Register + 0x100 + 0x20 + read-write + 0x00000000 + + + SETPEND + SETPEND + 0 + 32 + + + + + ISPR1 + ISPR1 + Interrupt Set-Pending Register + 0x104 + 0x20 + read-write + 0x00000000 + + + SETPEND + SETPEND + 0 + 32 + + + + + ISPR2 + ISPR2 + Interrupt Set-Pending Register + 0x108 + 0x20 + read-write + 0x00000000 + + + SETPEND + SETPEND + 0 + 32 + + + + + ICPR0 + ICPR0 + Interrupt Clear-Pending + Register + 0x180 + 0x20 + read-write + 0x00000000 + + + CLRPEND + CLRPEND + 0 + 32 + + + + + ICPR1 + ICPR1 + Interrupt Clear-Pending + Register + 0x184 + 0x20 + read-write + 0x00000000 + + + CLRPEND + CLRPEND + 0 + 32 + + + + + ICPR2 + ICPR2 + Interrupt Clear-Pending + Register + 0x188 + 0x20 + read-write + 0x00000000 + + + CLRPEND + CLRPEND + 0 + 32 + + + + + IABR0 + IABR0 + Interrupt Active Bit Register + 0x200 + 0x20 + read-only + 0x00000000 + + + ACTIVE + ACTIVE + 0 + 32 + + + + + IABR1 + IABR1 + Interrupt Active Bit Register + 0x204 + 0x20 + read-only + 0x00000000 + + + ACTIVE + ACTIVE + 0 + 32 + + + + + IABR2 + IABR2 + Interrupt Active Bit Register + 0x208 + 0x20 + read-only + 0x00000000 + + + ACTIVE + ACTIVE + 0 + 32 + + + + + IPR0 + IPR0 + Interrupt Priority Register + 0x300 + 0x20 + read-write + 0x00000000 + + + IPR_N0 + IPR_N0 + 0 + 8 + + + IPR_N1 + IPR_N1 + 8 + 8 + + + IPR_N2 + IPR_N2 + 16 + 8 + + + IPR_N3 + IPR_N3 + 24 + 8 + + + + + IPR1 + IPR1 + Interrupt Priority Register + 0x304 + 0x20 + read-write + 0x00000000 + + + IPR_N0 + IPR_N0 + 0 + 8 + + + IPR_N1 + IPR_N1 + 8 + 8 + + + IPR_N2 + IPR_N2 + 16 + 8 + + + IPR_N3 + IPR_N3 + 24 + 8 + + + + + IPR2 + IPR2 + Interrupt Priority Register + 0x308 + 0x20 + read-write + 0x00000000 + + + IPR_N0 + IPR_N0 + 0 + 8 + + + IPR_N1 + IPR_N1 + 8 + 8 + + + IPR_N2 + IPR_N2 + 16 + 8 + + + IPR_N3 + IPR_N3 + 24 + 8 + + + + + IPR3 + IPR3 + Interrupt Priority Register + 0x30C + 0x20 + read-write + 0x00000000 + + + IPR_N0 + IPR_N0 + 0 + 8 + + + IPR_N1 + IPR_N1 + 8 + 8 + + + IPR_N2 + IPR_N2 + 16 + 8 + + + IPR_N3 + IPR_N3 + 24 + 8 + + + + + IPR4 + IPR4 + Interrupt Priority Register + 0x310 + 0x20 + read-write + 0x00000000 + + + IPR_N0 + IPR_N0 + 0 + 8 + + + IPR_N1 + IPR_N1 + 8 + 8 + + + IPR_N2 + IPR_N2 + 16 + 8 + + + IPR_N3 + IPR_N3 + 24 + 8 + + + + + IPR5 + IPR5 + Interrupt Priority Register + 0x314 + 0x20 + read-write + 0x00000000 + + + IPR_N0 + IPR_N0 + 0 + 8 + + + IPR_N1 + IPR_N1 + 8 + 8 + + + IPR_N2 + IPR_N2 + 16 + 8 + + + IPR_N3 + IPR_N3 + 24 + 8 + + + + + IPR6 + IPR6 + Interrupt Priority Register + 0x318 + 0x20 + read-write + 0x00000000 + + + IPR_N0 + IPR_N0 + 0 + 8 + + + IPR_N1 + IPR_N1 + 8 + 8 + + + IPR_N2 + IPR_N2 + 16 + 8 + + + IPR_N3 + IPR_N3 + 24 + 8 + + + + + IPR7 + IPR7 + Interrupt Priority Register + 0x31C + 0x20 + read-write + 0x00000000 + + + IPR_N0 + IPR_N0 + 0 + 8 + + + IPR_N1 + IPR_N1 + 8 + 8 + + + IPR_N2 + IPR_N2 + 16 + 8 + + + IPR_N3 + IPR_N3 + 24 + 8 + + + + + IPR8 + IPR8 + Interrupt Priority Register + 0x320 + 0x20 + read-write + 0x00000000 + + + IPR_N0 + IPR_N0 + 0 + 8 + + + IPR_N1 + IPR_N1 + 8 + 8 + + + IPR_N2 + IPR_N2 + 16 + 8 + + + IPR_N3 + IPR_N3 + 24 + 8 + + + + + IPR9 + IPR9 + Interrupt Priority Register + 0x324 + 0x20 + read-write + 0x00000000 + + + IPR_N0 + IPR_N0 + 0 + 8 + + + IPR_N1 + IPR_N1 + 8 + 8 + + + IPR_N2 + IPR_N2 + 16 + 8 + + + IPR_N3 + IPR_N3 + 24 + 8 + + + + + IPR10 + IPR10 + Interrupt Priority Register + 0x328 + 0x20 + read-write + 0x00000000 + + + IPR_N0 + IPR_N0 + 0 + 8 + + + IPR_N1 + IPR_N1 + 8 + 8 + + + IPR_N2 + IPR_N2 + 16 + 8 + + + IPR_N3 + IPR_N3 + 24 + 8 + + + + + IPR11 + IPR11 + Interrupt Priority Register + 0x32C + 0x20 + read-write + 0x00000000 + + + IPR_N0 + IPR_N0 + 0 + 8 + + + IPR_N1 + IPR_N1 + 8 + 8 + + + IPR_N2 + IPR_N2 + 16 + 8 + + + IPR_N3 + IPR_N3 + 24 + 8 + + + + + IPR12 + IPR12 + Interrupt Priority Register + 0x330 + 0x20 + read-write + 0x00000000 + + + IPR_N0 + IPR_N0 + 0 + 8 + + + IPR_N1 + IPR_N1 + 8 + 8 + + + IPR_N2 + IPR_N2 + 16 + 8 + + + IPR_N3 + IPR_N3 + 24 + 8 + + + + + IPR13 + IPR13 + Interrupt Priority Register + 0x334 + 0x20 + read-write + 0x00000000 + + + IPR_N0 + IPR_N0 + 0 + 8 + + + IPR_N1 + IPR_N1 + 8 + 8 + + + IPR_N2 + IPR_N2 + 16 + 8 + + + IPR_N3 + IPR_N3 + 24 + 8 + + + + + IPR14 + IPR14 + Interrupt Priority Register + 0x338 + 0x20 + read-write + 0x00000000 + + + IPR_N0 + IPR_N0 + 0 + 8 + + + IPR_N1 + IPR_N1 + 8 + 8 + + + IPR_N2 + IPR_N2 + 16 + 8 + + + IPR_N3 + IPR_N3 + 24 + 8 + + + + + IPR15 + IPR15 + Interrupt Priority Register + 0x33C + 0x20 + read-write + 0x00000000 + + + IPR_N0 + IPR_N0 + 0 + 8 + + + IPR_N1 + IPR_N1 + 8 + 8 + + + IPR_N2 + IPR_N2 + 16 + 8 + + + IPR_N3 + IPR_N3 + 24 + 8 + + + + + IPR16 + IPR16 + Interrupt Priority Register + 0x340 + 0x20 + read-write + 0x00000000 + + + IPR_N0 + IPR_N0 + 0 + 8 + + + IPR_N1 + IPR_N1 + 8 + 8 + + + IPR_N2 + IPR_N2 + 16 + 8 + + + IPR_N3 + IPR_N3 + 24 + 8 + + + + + IPR17 + IPR17 + Interrupt Priority Register + 0x344 + 0x20 + read-write + 0x00000000 + + + IPR_N0 + IPR_N0 + 0 + 8 + + + IPR_N1 + IPR_N1 + 8 + 8 + + + IPR_N2 + IPR_N2 + 16 + 8 + + + IPR_N3 + IPR_N3 + 24 + 8 + + + + + IPR18 + IPR18 + Interrupt Priority Register + 0x348 + 0x20 + read-write + 0x00000000 + + + IPR_N0 + IPR_N0 + 0 + 8 + + + IPR_N1 + IPR_N1 + 8 + 8 + + + IPR_N2 + IPR_N2 + 16 + 8 + + + IPR_N3 + IPR_N3 + 24 + 8 + + + + + IPR19 + IPR19 + Interrupt Priority Register + 0x34C + 0x20 + read-write + 0x00000000 + + + IPR_N0 + IPR_N0 + 0 + 8 + + + IPR_N1 + IPR_N1 + 8 + 8 + + + IPR_N2 + IPR_N2 + 16 + 8 + + + IPR_N3 + IPR_N3 + 24 + 8 + + + + + + + FPU + Floting point unit + FPU + 0xE000EF34 + + 0x0 + 0xD + registers + + + FPU + Floating point unit interrupt + 81 + + + + FPCCR + FPCCR + Floating-point context control + register + 0x0 + 0x20 + read-write + 0x00000000 + + + LSPACT + LSPACT + 0 + 1 + + + USER + USER + 1 + 1 + + + THREAD + THREAD + 3 + 1 + + + HFRDY + HFRDY + 4 + 1 + + + MMRDY + MMRDY + 5 + 1 + + + BFRDY + BFRDY + 6 + 1 + + + MONRDY + MONRDY + 8 + 1 + + + LSPEN + LSPEN + 30 + 1 + + + ASPEN + ASPEN + 31 + 1 + + + + + FPCAR + FPCAR + Floating-point context address + register + 0x4 + 0x20 + read-write + 0x00000000 + + + ADDRESS + Location of unpopulated + floating-point + 3 + 29 + + + + + FPSCR + FPSCR + Floating-point status control + register + 0x8 + 0x20 + read-write + 0x00000000 + + + IOC + Invalid operation cumulative exception + bit + 0 + 1 + + + DZC + Division by zero cumulative exception + bit. + 1 + 1 + + + OFC + Overflow cumulative exception + bit + 2 + 1 + + + UFC + Underflow cumulative exception + bit + 3 + 1 + + + IXC + Inexact cumulative exception + bit + 4 + 1 + + + IDC + Input denormal cumulative exception + bit. + 7 + 1 + + + RMode + Rounding Mode control + field + 22 + 2 + + + FZ + Flush-to-zero mode control + bit: + 24 + 1 + + + DN + Default NaN mode control + bit + 25 + 1 + + + AHP + Alternative half-precision control + bit + 26 + 1 + + + V + Overflow condition code + flag + 28 + 1 + + + C + Carry condition code flag + 29 + 1 + + + Z + Zero condition code flag + 30 + 1 + + + N + Negative condition code + flag + 31 + 1 + + + + + + + MPU + Memory protection unit + MPU + 0xE000ED90 + + 0x0 + 0x15 + registers + + + + TYPER + TYPER + MPU type register + 0x0 + 0x20 + read-only + 0x00000800 + + + SEPARATE + Separate flag + 0 + 1 + + + DREGION + Number of MPU data regions + 8 + 8 + + + IREGION + Number of MPU instruction + regions + 16 + 8 + + + + + CTRL + CTRL + MPU control register + 0x4 + 0x20 + read-only + 0x00000000 + + + ENABLE + Enables the MPU + 0 + 1 + + + HFNMIENA + Enables the operation of MPU during hard + fault + 1 + 1 + + + PRIVDEFENA + Enable priviliged software access to + default memory map + 2 + 1 + + + + + RNR + RNR + MPU region number register + 0x8 + 0x20 + read-write + 0x00000000 + + + REGION + MPU region + 0 + 8 + + + + + RBAR + RBAR + MPU region base address + register + 0xC + 0x20 + read-write + 0x00000000 + + + REGION + MPU region field + 0 + 4 + + + VALID + MPU region number valid + 4 + 1 + + + ADDR + Region base address field + 5 + 27 + + + + + RASR + RASR + MPU region attribute and size + register + 0x10 + 0x20 + read-write + 0x00000000 + + + ENABLE + Region enable bit. + 0 + 1 + + + SIZE + Size of the MPU protection + region + 1 + 5 + + + SRD + Subregion disable bits + 8 + 8 + + + B + memory attribute + 16 + 1 + + + C + memory attribute + 17 + 1 + + + S + Shareable memory attribute + 18 + 1 + + + TEX + memory attribute + 19 + 3 + + + AP + Access permission + 24 + 3 + + + XN + Instruction access disable + bit + 28 + 1 + + + + + + + STK + SysTick timer + STK + 0xE000E010 + + 0x0 + 0x11 + registers + + + + CTRL + CTRL + SysTick control and status + register + 0x0 + 0x20 + read-write + 0x00000000 + + + ENABLE + Counter enable + 0 + 1 + + + TICKINT + SysTick exception request + enable + 1 + 1 + + + CLKSOURCE + Clock source selection + 2 + 1 + + + COUNTFLAG + COUNTFLAG + 16 + 1 + + + + + LOAD + LOAD + SysTick reload value register + 0x4 + 0x20 + read-write + 0x00000000 + + + RELOAD + RELOAD value + 0 + 24 + + + + + VAL + VAL + SysTick current value register + 0x8 + 0x20 + read-write + 0x00000000 + + + CURRENT + Current counter value + 0 + 24 + + + + + CALIB + CALIB + SysTick calibration value + register + 0xC + 0x20 + read-write + 0x00000000 + + + TENMS + Calibration value + 0 + 24 + + + SKEW + SKEW flag: Indicates whether the TENMS + value is exact + 30 + 1 + + + NOREF + NOREF flag. Reads as zero + 31 + 1 + + + + + + + SCB + System control block + SCB + 0xE000ED00 + + 0x0 + 0x41 + registers + + + + CPUID + CPUID + CPUID base register + 0x0 + 0x20 + read-only + 0x410FC241 + + + Revision + Revision number + 0 + 4 + + + PartNo + Part number of the + processor + 4 + 12 + + + Constant + Reads as 0xF + 16 + 4 + + + Variant + Variant number + 20 + 4 + + + Implementer + Implementer code + 24 + 8 + + + + + ICSR + ICSR + Interrupt control and state + register + 0x4 + 0x20 + read-write + 0x00000000 + + + VECTACTIVE + Active vector + 0 + 9 + + + RETTOBASE + Return to base level + 11 + 1 + + + VECTPENDING + Pending vector + 12 + 7 + + + ISRPENDING + Interrupt pending flag + 22 + 1 + + + PENDSTCLR + SysTick exception clear-pending + bit + 25 + 1 + + + PENDSTSET + SysTick exception set-pending + bit + 26 + 1 + + + PENDSVCLR + PendSV clear-pending bit + 27 + 1 + + + PENDSVSET + PendSV set-pending bit + 28 + 1 + + + NMIPENDSET + NMI set-pending bit. + 31 + 1 + + + + + VTOR + VTOR + Vector table offset register + 0x8 + 0x20 + read-write + 0x00000000 + + + TBLOFF + Vector table base offset + field + 9 + 21 + + + + + AIRCR + AIRCR + Application interrupt and reset control + register + 0xC + 0x20 + read-write + 0x00000000 + + + VECTRESET + VECTRESET + 0 + 1 + + + VECTCLRACTIVE + VECTCLRACTIVE + 1 + 1 + + + SYSRESETREQ + SYSRESETREQ + 2 + 1 + + + PRIGROUP + PRIGROUP + 8 + 3 + + + ENDIANESS + ENDIANESS + 15 + 1 + + + VECTKEYSTAT + Register key + 16 + 16 + + + + + SCR + SCR + System control register + 0x10 + 0x20 + read-write + 0x00000000 + + + SLEEPONEXIT + SLEEPONEXIT + 1 + 1 + + + SLEEPDEEP + SLEEPDEEP + 2 + 1 + + + SEVEONPEND + Send Event on Pending bit + 4 + 1 + + + + + CCR + CCR + Configuration and control + register + 0x14 + 0x20 + read-write + 0x00000000 + + + NONBASETHRDENA + Configures how the processor enters + Thread mode + 0 + 1 + + + USERSETMPEND + USERSETMPEND + 1 + 1 + + + UNALIGN__TRP + UNALIGN_ TRP + 3 + 1 + + + DIV_0_TRP + DIV_0_TRP + 4 + 1 + + + BFHFNMIGN + BFHFNMIGN + 8 + 1 + + + STKALIGN + STKALIGN + 9 + 1 + + + + + SHPR1 + SHPR1 + System handler priority + registers + 0x18 + 0x20 + read-write + 0x00000000 + + + PRI_4 + Priority of system handler + 4 + 0 + 8 + + + PRI_5 + Priority of system handler + 5 + 8 + 8 + + + PRI_6 + Priority of system handler + 6 + 16 + 8 + + + + + SHPR2 + SHPR2 + System handler priority + registers + 0x1C + 0x20 + read-write + 0x00000000 + + + PRI_11 + Priority of system handler + 11 + 24 + 8 + + + + + SHPR3 + SHPR3 + System handler priority + registers + 0x20 + 0x20 + read-write + 0x00000000 + + + PRI_14 + Priority of system handler + 14 + 16 + 8 + + + PRI_15 + Priority of system handler + 15 + 24 + 8 + + + + + SHCRS + SHCRS + System handler control and state + register + 0x24 + 0x20 + read-write + 0x00000000 + + + MEMFAULTACT + Memory management fault exception active + bit + 0 + 1 + + + BUSFAULTACT + Bus fault exception active + bit + 1 + 1 + + + USGFAULTACT + Usage fault exception active + bit + 3 + 1 + + + SVCALLACT + SVC call active bit + 7 + 1 + + + MONITORACT + Debug monitor active bit + 8 + 1 + + + PENDSVACT + PendSV exception active + bit + 10 + 1 + + + SYSTICKACT + SysTick exception active + bit + 11 + 1 + + + USGFAULTPENDED + Usage fault exception pending + bit + 12 + 1 + + + MEMFAULTPENDED + Memory management fault exception + pending bit + 13 + 1 + + + BUSFAULTPENDED + Bus fault exception pending + bit + 14 + 1 + + + SVCALLPENDED + SVC call pending bit + 15 + 1 + + + MEMFAULTENA + Memory management fault enable + bit + 16 + 1 + + + BUSFAULTENA + Bus fault enable bit + 17 + 1 + + + USGFAULTENA + Usage fault enable bit + 18 + 1 + + + + + CFSR_UFSR_BFSR_MMFSR + CFSR_UFSR_BFSR_MMFSR + Configurable fault status + register + 0x28 + 0x20 + read-write + 0x00000000 + + + IACCVIOL + Instruction access violation + flag + 1 + 1 + + + MUNSTKERR + Memory manager fault on unstacking for a + return from exception + 3 + 1 + + + MSTKERR + Memory manager fault on stacking for + exception entry. + 4 + 1 + + + MLSPERR + MLSPERR + 5 + 1 + + + MMARVALID + Memory Management Fault Address Register + (MMAR) valid flag + 7 + 1 + + + IBUSERR + Instruction bus error + 8 + 1 + + + PRECISERR + Precise data bus error + 9 + 1 + + + IMPRECISERR + Imprecise data bus error + 10 + 1 + + + UNSTKERR + Bus fault on unstacking for a return + from exception + 11 + 1 + + + STKERR + Bus fault on stacking for exception + entry + 12 + 1 + + + LSPERR + Bus fault on floating-point lazy state + preservation + 13 + 1 + + + BFARVALID + Bus Fault Address Register (BFAR) valid + flag + 15 + 1 + + + UNDEFINSTR + Undefined instruction usage + fault + 16 + 1 + + + INVSTATE + Invalid state usage fault + 17 + 1 + + + INVPC + Invalid PC load usage + fault + 18 + 1 + + + NOCP + No coprocessor usage + fault. + 19 + 1 + + + UNALIGNED + Unaligned access usage + fault + 24 + 1 + + + DIVBYZERO + Divide by zero usage fault + 25 + 1 + + + + + HFSR + HFSR + Hard fault status register + 0x2C + 0x20 + read-write + 0x00000000 + + + VECTTBL + Vector table hard fault + 1 + 1 + + + FORCED + Forced hard fault + 30 + 1 + + + DEBUG_VT + Reserved for Debug use + 31 + 1 + + + + + MMFAR + MMFAR + Memory management fault address + register + 0x34 + 0x20 + read-write + 0x00000000 + + + MMFAR + Memory management fault + address + 0 + 32 + + + + + BFAR + BFAR + Bus fault address register + 0x38 + 0x20 + read-write + 0x00000000 + + + BFAR + Bus fault address + 0 + 32 + + + + + AFSR + AFSR + Auxiliary fault status + register + 0x3C + 0x20 + read-write + 0x00000000 + + + IMPDEF + Implementation defined + 0 + 32 + + + + + + + NVIC_STIR + Nested vectored interrupt + controller + NVIC + 0xE000EF00 + + 0x0 + 0x5 + registers + + + + STIR + STIR + Software trigger interrupt + register + 0x0 + 0x20 + read-write + 0x00000000 + + + INTID + Software generated interrupt + ID + 0 + 9 + + + + + + + FPU_CPACR + Floating point unit CPACR + FPU + 0xE000ED88 + + 0x0 + 0x5 + registers + + + + CPACR + CPACR + Coprocessor access control + register + 0x0 + 0x20 + read-write + 0x00000000 + + + CP + CP + 20 + 4 + + + + + + + SCB_ACTRL + System control block ACTLR + SCB + 0xE000E008 + + 0x0 + 0x5 + registers + + + + ACTRL + ACTRL + Auxiliary control register + 0x0 + 0x20 + read-write + 0x00000000 + + + DISMCYCINT + DISMCYCINT + 0 + 1 + + + DISDEFWBUF + DISDEFWBUF + 1 + 1 + + + DISFOLD + DISFOLD + 2 + 1 + + + DISFPCA + DISFPCA + 8 + 1 + + + DISOOFP + DISOOFP + 9 + 1 + + + + + + + \ No newline at end of file diff --git a/nodes/embassy/large-bedroom-desk/.cargo/config.toml b/nodes/embassy/large-bedroom-desk/.cargo/config.toml new file mode 100644 index 00000000..f00aaa5f --- /dev/null +++ b/nodes/embassy/large-bedroom-desk/.cargo/config.toml @@ -0,0 +1,18 @@ +[target.'cfg(all(target_arch = "arm", target_os = "none"))'] +# replace STM32F103C8 with your chip as listed in `probe-rs chip list` +# runner = "probe-rs run --chip STM32F103C8" +runner = "probe-rs run --chip STM32F401CCUx" +# runner = "probe-rs run --chip STM32F401CCUx --host ws://192.168.1.43:3000 --token secret_token_redacted --probe c251:f001:202108120001" +linker = "flip-link" + +[build] +# target = "thumbv7m-none-eabi" for f103 +target = "thumbv7em-none-eabihf" + +[env] +DEFMT_LOG = "debug,sps30_async=warn,bosch_bme680=info" +EMBASSY_EXECUTOR_TASK_ARENA_SIZE="10900" + +# [unstable] +# build-std = ["core"] +# build-std-features = ["panic_immediate_abort"] diff --git a/nodes/embassy/large-bedroom-desk/Cargo.toml b/nodes/embassy/large-bedroom-desk/Cargo.toml new file mode 100644 index 00000000..b1a00cf6 --- /dev/null +++ b/nodes/embassy/large-bedroom-desk/Cargo.toml @@ -0,0 +1,38 @@ +[package] +name = "large-bedroom-desk" +version = "0.2.0" +rust-version = "1.85" +edition = "2024" +license = "GPLv3" +authors = ["David Kleingeld & Eva van Houten"] + +[dependencies] +cortex-m.workspace = true +cortex-m-rt.workspace = true + +embassy-stm32.workspace = true +embassy-sync.workspace = true +embassy-executor.workspace = true +embassy-embedded-hal.workspace = true +embassy-time.workspace = true +embassy-futures.workspace = true +embassy-usb.workspace = true + +defmt.workspace = true +defmt-rtt.workspace = true + +embedded-hal.workspace = true +embedded-hal-async.workspace = true +embedded-hal-bus.workspace = true +embedded-io-async.workspace = true + +panic-probe.workspace = true +futures.workspace = true +heapless.workspace = true + +# encoding + +protocol.workspace = true +sensors.workspace = true + +usb-bridge-client.workspace = true diff --git a/nodes/embassy/large-bedroom-desk/build.rs b/nodes/embassy/large-bedroom-desk/build.rs new file mode 100644 index 00000000..8cd32d7e --- /dev/null +++ b/nodes/embassy/large-bedroom-desk/build.rs @@ -0,0 +1,5 @@ +fn main() { + println!("cargo:rustc-link-arg-bins=--nmagic"); + println!("cargo:rustc-link-arg-bins=-Tlink.x"); + println!("cargo:rustc-link-arg-bins=-Tdefmt.x"); +} diff --git a/nodes/embassy/large-bedroom-desk/rust-toolchain.toml b/nodes/embassy/large-bedroom-desk/rust-toolchain.toml new file mode 100644 index 00000000..c17f644e --- /dev/null +++ b/nodes/embassy/large-bedroom-desk/rust-toolchain.toml @@ -0,0 +1,6 @@ +[toolchain] +channel = "stable" +components = [ "rust-src", "rustfmt", "llvm-tools" ] +targets = [ + "thumbv7em-none-eabihf", +] diff --git a/nodes/embassy/large-bedroom-desk/src/comms.rs b/nodes/embassy/large-bedroom-desk/src/comms.rs new file mode 100644 index 00000000..64de4ef0 --- /dev/null +++ b/nodes/embassy/large-bedroom-desk/src/comms.rs @@ -0,0 +1,67 @@ +use defmt::warn; +use embassy_time::{Duration, Instant}; +use heapless::HistoryBuffer; +use protocol::{SensorMessage, affector}; +use usb_bridge_client::{NoSpaceInQueue, UsbHandle, UsbSender}; + +pub async fn handle(usb: UsbHandle<'_>) -> ! { + const MIN_BETWEEN_COMM_ERRS: Duration = Duration::from_secs(30); + let mut last_errors_at: HistoryBuffer<_, 5> = HistoryBuffer::new(); + + loop { + crate::PUBLISH.clear(); + + let (writer, _) = usb.split(); + send_messages(writer).await; + warn!("Error while sending messages"); + + let mut error_after = Instant::now(); + if last_errors_at.oldest_ordered().rev().copied().all( + |error: Instant| { + let is_recent = + error_after.duration_since(error) < MIN_BETWEEN_COMM_ERRS; + error_after = error; + is_recent + }, + ) { + defmt::error!( + "Something is terribly wrong with the connection, \ + 5 errors occured each within 30 seconds of the previous. \ + Resetting entire node" + ); + cortex_m::peripheral::SCB::sys_reset(); + } else { + last_errors_at.write(Instant::now()); + } + } +} + +const AFFECTOR_LIST_MAX_SIZE: usize = protocol::Msg::<5>::max_size(); +pub fn affector_list() -> heapless::Vec { + let list = affector::ListMessage::<5>::empty(); + let mut buf = heapless::Vec::new(); + defmt::unwrap!(buf.resize_default(AFFECTOR_LIST_MAX_SIZE)); + let encoded_len = list.encode_slice(&mut buf).len(); + buf.truncate(encoded_len); + buf +} + +async fn collect_msg() -> SensorMessage<10> { + let mut msg = SensorMessage::<10>::default(); + let reading = crate::PUBLISH.receive().await; + defmt::unwrap!(msg.values.push(reading)); + msg +} + +async fn send_messages(usb: UsbSender<'_>) { + let mut buf = [0; protocol::Msg::<5>::max_size()]; + loop { + let msg = collect_msg().await; + let encoded_len = msg.encode_slice(&mut buf[1..]).len(); + buf[0] = protocol::Msg::<0>::READINGS; + let to_send = &buf[..=encoded_len]; + while let Err(NoSpaceInQueue) = usb.send(to_send, true).await { + usb.wait_till_queue_free().await; + } + } +} diff --git a/nodes/embassy/large-bedroom-desk/src/main.rs b/nodes/embassy/large-bedroom-desk/src/main.rs new file mode 100644 index 00000000..52f9de4f --- /dev/null +++ b/nodes/embassy/large-bedroom-desk/src/main.rs @@ -0,0 +1,196 @@ +#![no_std] +#![no_main] + +use core::time::Duration; + +use embassy_executor::Spawner; +use embassy_futures::join; +use embassy_stm32::exti::ExtiInput; +use embassy_stm32::gpio::Pull; +use embassy_stm32::peripherals::IWDG; +use embassy_stm32::time::Hertz; +use embassy_stm32::wdg::IndependentWatchdog; +use embassy_stm32::{Config, usb}; +use embassy_sync::blocking_mutex::raw::ThreadModeRawMutex; +use embassy_sync::channel::Channel; +use embassy_time::Timer; +use futures::pin_mut; + +use defmt::trace; +use {defmt_rtt as _, panic_probe as _}; + +mod comms; + +embassy_stm32::bind_interrupts!(struct Irqs { + OTG_FS => embassy_stm32::usb::InterruptHandler; +}); + +static PUBLISH: Channel = + Channel::new(); + +// 84 Mhz clock stm32f401 +// 48 Mhz clock for usb +fn config() -> Config { + use embassy_stm32::rcc::mux; + use embassy_stm32::rcc::{ + AHBPrescaler, APBPrescaler, Hse, HseMode, Pll, PllMul, PllPDiv, + PllPreDiv, PllQDiv, PllSource, Sysclk, + }; + + let mut config = Config::default(); + config.rcc.hse = Some(Hse { + freq: Hertz(25_000_000), + mode: HseMode::Oscillator, + }); + config.rcc.pll_src = PllSource::HSE; + config.rcc.pll = Some(Pll { + prediv: PllPreDiv::DIV25, + mul: PllMul::MUL336, + divp: Some(PllPDiv::DIV4), // 25mhz / 25 * 336 / 4 = 84Mhz. + divq: Some(PllQDiv::DIV7), // 25mhz / 25 * 336 / 7 = 48Mhz. + divr: None, + }); + config.rcc.ahb_pre = AHBPrescaler::DIV1; + config.rcc.apb1_pre = APBPrescaler::DIV2; + config.rcc.apb2_pre = APBPrescaler::DIV1; + config.rcc.sys = Sysclk::PLL1_P; + config.rcc.mux.clk48sel = mux::Clk48sel::PLL1_Q; + config +} + +#[embassy_executor::main] +async fn main(_spawner: Spawner) { + let p = embassy_stm32::init(config()); + let dog = IndependentWatchdog::new( + p.IWDG, + Duration::from_secs(5).as_micros() as u32, + ); + + use protocol::large_bedroom::desk_right; + use protocol::large_bedroom::desk_right::Button; + type IntoButton = fn(protocol::button::Press) -> Button; + let buttons = [ + ( + ExtiInput::new(p.PC15, p.EXTI15, Pull::Down), + Button::LeftLeft as IntoButton, + ), + ( + ExtiInput::new(p.PB0, p.EXTI0, Pull::Down), + Button::LeftMiddle as IntoButton, + ), + ( + ExtiInput::new(p.PC14, p.EXTI14, Pull::Down), + Button::LeftRight as IntoButton, + ), + ( + ExtiInput::new(p.PB12, p.EXTI12, Pull::Down), + Button::RightLeftmost as IntoButton, + ), + ( + ExtiInput::new(p.PB13, p.EXTI13, Pull::Down), + Button::RightLeft as IntoButton, + ), + ( + ExtiInput::new(p.PB8, p.EXTI8, Pull::Down), + Button::RightRight as IntoButton, + ), + ( + ExtiInput::new(p.PB6, p.EXTI6, Pull::Down), + Button::RightRightmost as IntoButton, + ), + ]; + + let pirs = [( + ExtiInput::new(p.PA5, p.EXTI5, Pull::Down), + desk_right::Reading::Pir, + )]; + + let mut usb_driver_config = embassy_stm32::usb::Config::default(); + // Do not enable vbus_detection. This is a safe default that works in all + // boards. However, if your USB device is self-powered (can stay powered on + // if USB is unplugged), you need to enable vbus_detection to comply with + // the USB spec. If you enable it, the board + usb_driver_config.vbus_detection = false; + + let mut ep_out_buffer = [0u8; 256]; + let usb_driver = usb::Driver::new_fs( + p.USB_OTG_FS, + Irqs, + p.PA12, + p.PA11, + &mut ep_out_buffer, + usb_driver_config, + ); + + let affector_list = comms::affector_list(); + let stack_a = usb_bridge_client::StackA::new(); + let mut stack_b = usb_bridge_client::StackB::new(&stack_a, &affector_list); + let (mut usb_bus, usb_handle) = usb_bridge_client::new( + &stack_a, + &mut stack_b, + usb_bridge_client::config!("large-bedroom-righ", "87244"), + usb_driver, + ); + + let handle_network = comms::handle(usb_handle); + pin_mut!(handle_network); + + let watch_buttons = sensors::button::watch_array(buttons, |button| { + let _err = PUBLISH.try_send(button_into_reading(button)); + }); + let watch_pir = sensors::pir::watch_array(pirs, |pir| { + let _err = PUBLISH.try_send(into_reading(pir)); + }); + + join::join5( + &mut handle_network, + watch_buttons, + watch_pir, + usb_bus.run(), + keep_dog_happy(dog), + ) + .await; +} + +pub fn usb_config() -> embassy_usb::Config<'static> { + // Create embassy-usb Config + let mut config = embassy_usb::Config::new(0x16c0, 0x27DD); + config.manufacturer = Some("Vid"); + config.product = Some("Sensor node"); + config.serial_number = Some("2478437"); + + // Required for windows compatibility. + // https://developer.nordicsemi.com/nRF_Connect_SDK/doc/1.9.1/kconfig/CONFIG_CDC_ACM_IAD.html#help + config.device_class = 0xEF; + config.device_sub_class = 0x02; + config.device_protocol = 0x01; + config.composite_with_iads = true; + + config +} + +async fn keep_dog_happy(mut dog: IndependentWatchdog<'_, IWDG>) -> ! { + loop { + Timer::after_secs(1).await; + trace!("petting dog"); + dog.pet(); + } +} + +fn button_into_reading( + button: protocol::large_bedroom::desk_right::Button, +) -> protocol::Reading { + protocol::Reading::LargeBedroom( + protocol::large_bedroom::Reading::DeskRight( + protocol::large_bedroom::desk_right::Reading::Button(button), + ), + ) +} + +fn into_reading( + pir: protocol::large_bedroom::desk_right::Reading, +) -> protocol::Reading { + protocol::Reading::LargeBedroom( + protocol::large_bedroom::Reading::DeskRight(pir), + ) +} diff --git a/nodes/embassy/large-bedroom-desk/stm32f401.svd b/nodes/embassy/large-bedroom-desk/stm32f401.svd new file mode 100644 index 00000000..b9353d01 --- /dev/null +++ b/nodes/embassy/large-bedroom-desk/stm32f401.svd @@ -0,0 +1,35196 @@ + + + STM32F401 + 1.1 + STM32F401 + + CM4 + r1p0 + little + false + false + 4 + false + + 8 + 32 + 0x20 + 0x00000000 + 0xFFFFFFFF + + + ADC_Common + ADC common registers + ADC_Common + 0x40012300 + + 0x0 + 0x9 + registers + + + FPU + FPU interrupt + 81 + + + + CCR + CCR + ADC common control register + 0x4 + 0x20 + read-write + 0x00000000 + + + TSVREFE + Temperature sensor and VREFINT + enable + 23 + 1 + + TSVREFE + read-write + + Disabled + Temperature sensor and V_REFINT channel disabled + 0 + + + Enabled + Temperature sensor and V_REFINT channel enabled + 1 + + + + + VBATE + VBAT enable + 22 + 1 + + VBATE + read-write + + Disabled + V_BAT channel disabled + 0 + + + Enabled + V_BAT channel enabled + 1 + + + + + ADCPRE + ADC prescaler + 16 + 2 + + ADCPRE + read-write + + Div2 + PCLK2 divided by 2 + 0 + + + Div4 + PCLK2 divided by 4 + 1 + + + Div6 + PCLK2 divided by 6 + 2 + + + Div8 + PCLK2 divided by 8 + 3 + + + + + + + + + ADC1 + Analog-to-digital converter + ADC + 0x40012000 + + 0x0 + 0x51 + registers + + + ADC + ADC1 global interrupt + 18 + + + + SR + SR + status register + 0x0 + 0x20 + read-write + 0x00000000 + + + OVR + Overrun + 5 + 1 + zeroToClear + + OVRR + read + + NoOverrun + No overrun occurred + 0 + + + Overrun + Overrun occurred + 1 + + + + OVRW + write + + Clear + Clear flag + 0 + + + + + STRT + Regular channel start flag + 4 + 1 + zeroToClear + + STRTR + read + + NotStarted + No regular channel conversion started + 0 + + + Started + Regular channel conversion has started + 1 + + + + STRTW + write + + Clear + Clear flag + 0 + + + + + JSTRT + Injected channel start + flag + 3 + 1 + zeroToClear + + JSTRTR + read + + NotStarted + No injected channel conversion started + 0 + + + Started + Injected channel conversion has started + 1 + + + + JSTRTW + write + + Clear + Clear flag + 0 + + + + + JEOC + Injected channel end of + conversion + 2 + 1 + zeroToClear + + JEOCR + read + + NotComplete + Conversion is not complete + 0 + + + Complete + Conversion complete + 1 + + + + JEOCW + write + + Clear + Clear flag + 0 + + + + + EOC + Regular channel end of + conversion + 1 + 1 + zeroToClear + + EOCR + read + + NotComplete + Conversion is not complete + 0 + + + Complete + Conversion complete + 1 + + + + EOCW + write + + Clear + Clear flag + 0 + + + + + AWD + Analog watchdog flag + 0 + 1 + zeroToClear + + AWDR + read + + NoEvent + No analog watchdog event occurred + 0 + + + Event + Analog watchdog event occurred + 1 + + + + AWDW + write + + Clear + Clear flag + 0 + + + + + + + CR1 + CR1 + control register 1 + 0x4 + 0x20 + read-write + 0x00000000 + + + OVRIE + Overrun interrupt enable + 26 + 1 + + OVRIE + read-write + + Disabled + Overrun interrupt disabled + 0 + + + Enabled + Overrun interrupt enabled + 1 + + + + + RES + Resolution + 24 + 2 + + RES + read-write + + TwelveBit + 12-bit (15 ADCCLK cycles) + 0 + + + TenBit + 10-bit (13 ADCCLK cycles) + 1 + + + EightBit + 8-bit (11 ADCCLK cycles) + 2 + + + SixBit + 6-bit (9 ADCCLK cycles) + 3 + + + + + AWDEN + Analog watchdog enable on regular + channels + 23 + 1 + + AWDEN + read-write + + Disabled + Analog watchdog disabled on regular channels + 0 + + + Enabled + Analog watchdog enabled on regular channels + 1 + + + + + JAWDEN + Analog watchdog enable on injected + channels + 22 + 1 + + JAWDEN + read-write + + Disabled + Analog watchdog disabled on injected channels + 0 + + + Enabled + Analog watchdog enabled on injected channels + 1 + + + + + DISCNUM + Discontinuous mode channel + count + 13 + 3 + + + 0 + 7 + + + + + JDISCEN + Discontinuous mode on injected + channels + 12 + 1 + + JDISCEN + read-write + + Disabled + Discontinuous mode on injected channels disabled + 0 + + + Enabled + Discontinuous mode on injected channels enabled + 1 + + + + + DISCEN + Discontinuous mode on regular + channels + 11 + 1 + + DISCEN + read-write + + Disabled + Discontinuous mode on regular channels disabled + 0 + + + Enabled + Discontinuous mode on regular channels enabled + 1 + + + + + JAUTO + Automatic injected group + conversion + 10 + 1 + + JAUTO + read-write + + Disabled + Automatic injected group conversion disabled + 0 + + + Enabled + Automatic injected group conversion enabled + 1 + + + + + AWDSGL + Enable the watchdog on a single channel + in scan mode + 9 + 1 + + AWDSGL + read-write + + AllChannels + Analog watchdog enabled on all channels + 0 + + + SingleChannel + Analog watchdog enabled on a single channel + 1 + + + + + SCAN + Scan mode + 8 + 1 + + SCAN + read-write + + Disabled + Scan mode disabled + 0 + + + Enabled + Scan mode enabled + 1 + + + + + JEOCIE + Interrupt enable for injected + channels + 7 + 1 + + JEOCIE + read-write + + Disabled + JEOC interrupt disabled + 0 + + + Enabled + JEOC interrupt enabled + 1 + + + + + AWDIE + Analog watchdog interrupt + enable + 6 + 1 + + AWDIE + read-write + + Disabled + Analogue watchdog interrupt disabled + 0 + + + Enabled + Analogue watchdog interrupt enabled + 1 + + + + + EOCIE + Interrupt enable for EOC + 5 + 1 + + EOCIE + read-write + + Disabled + EOC interrupt disabled + 0 + + + Enabled + EOC interrupt enabled + 1 + + + + + AWDCH + Analog watchdog channel select + bits + 0 + 5 + + + 0 + 18 + + + + + + + CR2 + CR2 + control register 2 + 0x8 + 0x20 + read-write + 0x00000000 + + + SWSTART + Start conversion of regular + channels + 30 + 1 + + SWSTARTW + write + + Start + Starts conversion of regular channels + 1 + + + + + EXTEN + External trigger enable for regular + channels + 28 + 2 + + EXTEN + read-write + + Disabled + Trigger detection disabled + 0 + + + RisingEdge + Trigger detection on the rising edge + 1 + + + FallingEdge + Trigger detection on the falling edge + 2 + + + BothEdges + Trigger detection on both the rising and falling edges + 3 + + + + + EXTSEL + External event select for regular + group + 24 + 4 + + EXTSEL + read-write + + TIM1CC1 + Timer 1 CC1 event + 0 + + + TIM1CC2 + Timer 1 CC2 event + 1 + + + TIM1CC3 + Timer 1 CC3 event + 2 + + + TIM2CC2 + Timer 2 CC2 event + 3 + + + TIM2CC3 + Timer 2 CC3 event + 4 + + + TIM2CC4 + Timer 2 CC4 event + 5 + + + TIM2TRGO + Timer 2 TRGO event + 6 + + + TIM3CC1 + Timer 3 CC1 event + 7 + + + TIM3TRGO + Timer 3 TRGO event + 8 + + + TIM4CC4 + Timer 4 CC4 event + 9 + + + TIM5CC1 + Timer 5 CC1 event + 10 + + + TIM5CC2 + Timer 5 CC2 event + 11 + + + TIM5CC3 + Timer 5 CC3 event + 12 + + + EXTI11 + EXTI line 11 + 15 + + + + + JSWSTART + Start conversion of injected + channels + 22 + 1 + + JSWSTARTW + write + + Start + Starts conversion of injected channels + 1 + + + + + JEXTEN + External trigger enable for injected + channels + 20 + 2 + + JEXTEN + read-write + + Disabled + Trigger detection disabled + 0 + + + RisingEdge + Trigger detection on the rising edge + 1 + + + FallingEdge + Trigger detection on the falling edge + 2 + + + BothEdges + Trigger detection on both the rising and falling edges + 3 + + + + + JEXTSEL + External event select for injected + group + 16 + 4 + + JEXTSEL + read-write + + TIM1CC4 + Timer 1 CC4 event + 0 + + + TIM1TRGO + Timer 1 TRGO event + 1 + + + TIM2CC1 + Timer 2 CC1 event + 2 + + + TIM2TRGO + Timer 2 TRGO event + 3 + + + TIM3CC2 + Timer 3 CC2 event + 4 + + + TIM3CC4 + Timer 3 CC4 event + 5 + + + TIM4CC1 + Timer 4 CC1 event + 6 + + + TIM4CC2 + Timer 4 CC2 event + 7 + + + TIM4CC3 + Timer 4 CC3 event + 8 + + + TIM4TRGO + Timer 4 TRGO event + 9 + + + TIM5CC4 + Timer 5 CC4 event + 10 + + + TIM5TRGO + Timer 5 TRGO event + 11 + + + EXTI15 + EXTI line 15 + 15 + + + + + ALIGN + Data alignment + 11 + 1 + + ALIGN + read-write + + Right + Right alignment + 0 + + + Left + Left alignment + 1 + + + + + EOCS + End of conversion + selection + 10 + 1 + + EOCS + read-write + + EachSequence + The EOC bit is set at the end of each sequence of regular conversions + 0 + + + EachConversion + The EOC bit is set at the end of each regular conversion + 1 + + + + + DDS + DMA disable selection (for single ADC + mode) + 9 + 1 + + DDS + read-write + + Single + No new DMA request is issued after the last transfer + 0 + + + Continuous + DMA requests are issued as long as data are converted and DMA=1 + 1 + + + + + DMA + Direct memory access mode (for single + ADC mode) + 8 + 1 + + DMA + read-write + + Disabled + DMA mode disabled + 0 + + + Enabled + DMA mode enabled + 1 + + + + + CONT + Continuous conversion + 1 + 1 + + CONT + read-write + + Single + Single conversion mode + 0 + + + Continuous + Continuous conversion mode + 1 + + + + + ADON + A/D Converter ON / OFF + 0 + 1 + + ADON + read-write + + Disabled + Disable ADC conversion and go to power down mode + 0 + + + Enabled + Enable ADC + 1 + + + + + + + SMPR1 + SMPR1 + sample time register 1 + 0xC + 0x20 + read-write + 0x00000000 + + + SMP18 + Channel 18 sampling time selection + 24 + 3 + + + + SMP17 + Channel 17 sampling time selection + 21 + 3 + + + + SMP16 + Channel 16 sampling time selection + 18 + 3 + + + + SMP15 + Channel 15 sampling time selection + 15 + 3 + + + + SMP14 + Channel 14 sampling time selection + 12 + 3 + + + + SMP13 + Channel 13 sampling time selection + 9 + 3 + + + + SMP12 + Channel 12 sampling time selection + 6 + 3 + + + + SMP11 + Channel 11 sampling time selection + 3 + 3 + + + + SMP10 + Channel 10 sampling time selection + 0 + 3 + + SMP10 + read-write + + Cycles3 + 3 cycles + 0 + + + Cycles15 + 15 cycles + 1 + + + Cycles28 + 28 cycles + 2 + + + Cycles56 + 56 cycles + 3 + + + Cycles84 + 84 cycles + 4 + + + Cycles112 + 112 cycles + 5 + + + Cycles144 + 144 cycles + 6 + + + Cycles480 + 480 cycles + 7 + + + + + + + SMPR2 + SMPR2 + sample time register 2 + 0x10 + 0x20 + read-write + 0x00000000 + + + SMP9 + Channel 9 sampling time selection + 27 + 3 + + + + SMP8 + Channel 8 sampling time selection + 24 + 3 + + + + SMP7 + Channel 7 sampling time selection + 21 + 3 + + + + SMP6 + Channel 6 sampling time selection + 18 + 3 + + + + SMP5 + Channel 5 sampling time selection + 15 + 3 + + + + SMP4 + Channel 4 sampling time selection + 12 + 3 + + + + SMP3 + Channel 3 sampling time selection + 9 + 3 + + + + SMP2 + Channel 2 sampling time selection + 6 + 3 + + + + SMP1 + Channel 1 sampling time selection + 3 + 3 + + + + SMP0 + Channel 0 sampling time selection + 0 + 3 + + SMP0 + read-write + + Cycles3 + 3 cycles + 0 + + + Cycles15 + 15 cycles + 1 + + + Cycles28 + 28 cycles + 2 + + + Cycles56 + 56 cycles + 3 + + + Cycles84 + 84 cycles + 4 + + + Cycles112 + 112 cycles + 5 + + + Cycles144 + 144 cycles + 6 + + + Cycles480 + 480 cycles + 7 + + + + + + + 4 + 0x4 + 1-4 + JOFR%s + JOFR1 + injected channel data offset register + x + 0x14 + 0x20 + read-write + 0x00000000 + + + JOFFSET + Data offset for injected channel + x + 0 + 12 + + + 0 + 4095 + + + + + + + HTR + HTR + watchdog higher threshold + register + 0x24 + 0x20 + read-write + 0x00000FFF + + + HT + Analog watchdog higher + threshold + 0 + 12 + + + 0 + 4095 + + + + + + + LTR + LTR + watchdog lower threshold + register + 0x28 + 0x20 + read-write + 0x00000000 + + + LT + Analog watchdog lower + threshold + 0 + 12 + + + 0 + 4095 + + + + + + + SQR1 + SQR1 + regular sequence register 1 + 0x2C + 0x20 + read-write + 0x00000000 + + + L + Regular channel sequence + length + 20 + 4 + + + 0 + 15 + + + + + SQ16 + 16th conversion in regular + sequence + 15 + 5 + + + 0 + 18 + + + + + SQ15 + 15th conversion in regular + sequence + 10 + 5 + + + 0 + 18 + + + + + SQ14 + 14th conversion in regular + sequence + 5 + 5 + + + 0 + 18 + + + + + SQ13 + 13th conversion in regular + sequence + 0 + 5 + + + 0 + 18 + + + + + + + SQR2 + SQR2 + regular sequence register 2 + 0x30 + 0x20 + read-write + 0x00000000 + + + SQ12 + 12th conversion in regular + sequence + 25 + 5 + + + 0 + 18 + + + + + SQ11 + 11th conversion in regular + sequence + 20 + 5 + + + 0 + 18 + + + + + SQ10 + 10th conversion in regular + sequence + 15 + 5 + + + 0 + 18 + + + + + SQ9 + 9th conversion in regular + sequence + 10 + 5 + + + 0 + 18 + + + + + SQ8 + 8th conversion in regular + sequence + 5 + 5 + + + 0 + 18 + + + + + SQ7 + 7th conversion in regular + sequence + 0 + 5 + + + 0 + 18 + + + + + + + SQR3 + SQR3 + regular sequence register 3 + 0x34 + 0x20 + read-write + 0x00000000 + + + SQ6 + 6th conversion in regular + sequence + 25 + 5 + + + 0 + 18 + + + + + SQ5 + 5th conversion in regular + sequence + 20 + 5 + + + 0 + 18 + + + + + SQ4 + 4th conversion in regular + sequence + 15 + 5 + + + 0 + 18 + + + + + SQ3 + 3rd conversion in regular + sequence + 10 + 5 + + + 0 + 18 + + + + + SQ2 + 2nd conversion in regular + sequence + 5 + 5 + + + 0 + 18 + + + + + SQ1 + 1st conversion in regular + sequence + 0 + 5 + + + 0 + 18 + + + + + + + JSQR + JSQR + injected sequence register + 0x38 + 0x20 + read-write + 0x00000000 + + + JL + Injected sequence length + 20 + 2 + + + 0 + 3 + + + + + JSQ4 + 4th conversion in injected + sequence + 15 + 5 + + + 0 + 18 + + + + + JSQ3 + 3rd conversion in injected + sequence + 10 + 5 + + + 0 + 18 + + + + + JSQ2 + 2nd conversion in injected + sequence + 5 + 5 + + + 0 + 18 + + + + + JSQ1 + 1st conversion in injected + sequence + 0 + 5 + + + 0 + 18 + + + + + + + 4 + 0x4 + 1-4 + JDR%s + JDR1 + injected data register x + 0x3C + 0x20 + read-only + 0x00000000 + + + JDATA + Injected data + 0 + 16 + + + + + DR + DR + regular data register + 0x4C + 0x20 + read-only + 0x00000000 + + + DATA + Regular data + 0 + 16 + + + + + + + CRC + Cryptographic processor + CRC + 0x40023000 + + 0x0 + 0x400 + registers + + + + DR + DR + Data register + 0x0 + 0x20 + read-write + 0xFFFFFFFF + + + DR + Data Register + 0 + 32 + + + 0 + 4294967295 + + + + + + + IDR + IDR + Independent Data register + 0x4 + 0x20 + read-write + 0x00000000 + + + IDR + Independent Data register + 0 + 8 + + + 0 + 255 + + + + + + + CR + CR + Control register + 0x8 + 0x20 + write-only + 0x00000000 + + + RESET + Control regidter + 0 + 1 + + RESETW + write + + Reset + Resets the CRC calculation unit and sets the data register to 0xFFFF FFFF + 1 + + + + + + + + + DBGMCU + Debug support + DBG + 0xE0042000 + + 0x0 + 0x400 + registers + + + + IDCODE + IDCODE + IDCODE + 0x0 + 0x20 + read-only + 0x10006411 + + + DEV_ID + DEV_ID + 0 + 12 + + + REV_ID + REV_ID + 16 + 16 + + + + + CR + CR + Control Register + 0x4 + 0x20 + read-write + 0x00000000 + + + DBG_SLEEP + DBG_SLEEP + 0 + 1 + + + DBG_STOP + DBG_STOP + 1 + 1 + + + DBG_STANDBY + DBG_STANDBY + 2 + 1 + + + TRACE_IOEN + TRACE_IOEN + 5 + 1 + + + TRACE_MODE + TRACE_MODE + 6 + 2 + + + + + APB1_FZ + APB1_FZ + Debug MCU APB1 Freeze registe + 0x8 + 0x20 + read-write + 0x00000000 + + + DBG_TIM2_STOP + DBG_TIM2_STOP + 0 + 1 + + + DBG_TIM3_STOP + DBG_TIM3 _STOP + 1 + 1 + + + DBG_TIM4_STOP + DBG_TIM4_STOP + 2 + 1 + + + DBG_TIM5_STOP + DBG_TIM5_STOP + 3 + 1 + + + DBG_RTC_Stop + RTC stopped when Core is + halted + 10 + 1 + + + DBG_WWDG_STOP + DBG_WWDG_STOP + 11 + 1 + + + DBG_IWDG_STOP + DBG_IWDEG_STOP + 12 + 1 + + + DBG_I2C1_SMBUS_TIMEOUT + DBG_J2C1_SMBUS_TIMEOUT + 21 + 1 + + + DBG_I2C2_SMBUS_TIMEOUT + DBG_J2C2_SMBUS_TIMEOUT + 22 + 1 + + + DBG_I2C3SMBUS_TIMEOUT + DBG_J2C3SMBUS_TIMEOUT + 23 + 1 + + + + + APB2_FZ + APB2_FZ + Debug MCU APB2 Freeze registe + 0xC + 0x20 + read-write + 0x00000000 + + + DBG_TIM1_STOP + TIM1 counter stopped when core is + halted + 0 + 1 + + + DBG_TIM9_STOP + TIM9 counter stopped when core is + halted + 16 + 1 + + + DBG_TIM10_STOP + TIM10 counter stopped when core is + halted + 17 + 1 + + + DBG_TIM11_STOP + TIM11 counter stopped when core is + halted + 18 + 1 + + + + + + + EXTI + External interrupt/event + controller + EXTI + 0x40013C00 + + 0x0 + 0x400 + registers + + + TAMP_STAMP + Tamper and TimeStamp interrupts through the + EXTI line + 2 + + + EXTI0 + EXTI Line0 interrupt + 6 + + + EXTI1 + EXTI Line1 interrupt + 7 + + + EXTI2 + EXTI Line2 interrupt + 8 + + + EXTI3 + EXTI Line3 interrupt + 9 + + + EXTI4 + EXTI Line4 interrupt + 10 + + + EXTI9_5 + EXTI Line[9:5] interrupts + 23 + + + EXTI15_10 + EXTI Line[15:10] interrupts + 40 + + + + IMR + IMR + Interrupt mask register + (EXTI_IMR) + 0x0 + 0x20 + read-write + 0x00000000 + + + MR0 + Interrupt Mask on line 0 + 0 + 1 + + MR0 + read-write + + Masked + Interrupt request line is masked + 0 + + + Unmasked + Interrupt request line is unmasked + 1 + + + + + MR1 + Interrupt Mask on line 1 + 1 + 1 + + + + MR2 + Interrupt Mask on line 2 + 2 + 1 + + + + MR3 + Interrupt Mask on line 3 + 3 + 1 + + + + MR4 + Interrupt Mask on line 4 + 4 + 1 + + + + MR5 + Interrupt Mask on line 5 + 5 + 1 + + + + MR6 + Interrupt Mask on line 6 + 6 + 1 + + + + MR7 + Interrupt Mask on line 7 + 7 + 1 + + + + MR8 + Interrupt Mask on line 8 + 8 + 1 + + + + MR9 + Interrupt Mask on line 9 + 9 + 1 + + + + MR10 + Interrupt Mask on line 10 + 10 + 1 + + + + MR11 + Interrupt Mask on line 11 + 11 + 1 + + + + MR12 + Interrupt Mask on line 12 + 12 + 1 + + + + MR13 + Interrupt Mask on line 13 + 13 + 1 + + + + MR14 + Interrupt Mask on line 14 + 14 + 1 + + + + MR15 + Interrupt Mask on line 15 + 15 + 1 + + + + MR16 + Interrupt Mask on line 16 + 16 + 1 + + + + MR17 + Interrupt Mask on line 17 + 17 + 1 + + + + MR18 + Interrupt Mask on line 18 + 18 + 1 + + + + MR19 + Interrupt Mask on line 19 + 19 + 1 + + + + MR20 + Interrupt Mask on line 20 + 20 + 1 + + + + MR21 + Interrupt Mask on line 21 + 21 + 1 + + + + MR22 + Interrupt Mask on line 22 + 22 + 1 + + + + + + EMR + EMR + Event mask register (EXTI_EMR) + 0x4 + 0x20 + read-write + 0x00000000 + + + MR0 + Event Mask on line 0 + 0 + 1 + + MR0 + read-write + + Masked + Interrupt request line is masked + 0 + + + Unmasked + Interrupt request line is unmasked + 1 + + + + + MR1 + Event Mask on line 1 + 1 + 1 + + + + MR2 + Event Mask on line 2 + 2 + 1 + + + + MR3 + Event Mask on line 3 + 3 + 1 + + + + MR4 + Event Mask on line 4 + 4 + 1 + + + + MR5 + Event Mask on line 5 + 5 + 1 + + + + MR6 + Event Mask on line 6 + 6 + 1 + + + + MR7 + Event Mask on line 7 + 7 + 1 + + + + MR8 + Event Mask on line 8 + 8 + 1 + + + + MR9 + Event Mask on line 9 + 9 + 1 + + + + MR10 + Event Mask on line 10 + 10 + 1 + + + + MR11 + Event Mask on line 11 + 11 + 1 + + + + MR12 + Event Mask on line 12 + 12 + 1 + + + + MR13 + Event Mask on line 13 + 13 + 1 + + + + MR14 + Event Mask on line 14 + 14 + 1 + + + + MR15 + Event Mask on line 15 + 15 + 1 + + + + MR16 + Event Mask on line 16 + 16 + 1 + + + + MR17 + Event Mask on line 17 + 17 + 1 + + + + MR18 + Event Mask on line 18 + 18 + 1 + + + + MR19 + Event Mask on line 19 + 19 + 1 + + + + MR20 + Event Mask on line 20 + 20 + 1 + + + + MR21 + Event Mask on line 21 + 21 + 1 + + + + MR22 + Event Mask on line 22 + 22 + 1 + + + + + + RTSR + RTSR + Rising Trigger selection register + (EXTI_RTSR) + 0x8 + 0x20 + read-write + 0x00000000 + + + TR0 + Rising trigger event configuration of + line 0 + 0 + 1 + + TR0 + read-write + + Disabled + Rising edge trigger is disabled + 0 + + + Enabled + Rising edge trigger is enabled + 1 + + + + + TR1 + Rising trigger event configuration of + line 1 + 1 + 1 + + + + TR2 + Rising trigger event configuration of + line 2 + 2 + 1 + + + + TR3 + Rising trigger event configuration of + line 3 + 3 + 1 + + + + TR4 + Rising trigger event configuration of + line 4 + 4 + 1 + + + + TR5 + Rising trigger event configuration of + line 5 + 5 + 1 + + + + TR6 + Rising trigger event configuration of + line 6 + 6 + 1 + + + + TR7 + Rising trigger event configuration of + line 7 + 7 + 1 + + + + TR8 + Rising trigger event configuration of + line 8 + 8 + 1 + + + + TR9 + Rising trigger event configuration of + line 9 + 9 + 1 + + + + TR10 + Rising trigger event configuration of + line 10 + 10 + 1 + + + + TR11 + Rising trigger event configuration of + line 11 + 11 + 1 + + + + TR12 + Rising trigger event configuration of + line 12 + 12 + 1 + + + + TR13 + Rising trigger event configuration of + line 13 + 13 + 1 + + + + TR14 + Rising trigger event configuration of + line 14 + 14 + 1 + + + + TR15 + Rising trigger event configuration of + line 15 + 15 + 1 + + + + TR16 + Rising trigger event configuration of + line 16 + 16 + 1 + + + + TR17 + Rising trigger event configuration of + line 17 + 17 + 1 + + + + TR18 + Rising trigger event configuration of + line 18 + 18 + 1 + + + + TR19 + Rising trigger event configuration of + line 19 + 19 + 1 + + + + TR20 + Rising trigger event configuration of + line 20 + 20 + 1 + + + + TR21 + Rising trigger event configuration of + line 21 + 21 + 1 + + + + TR22 + Rising trigger event configuration of + line 22 + 22 + 1 + + + + + + FTSR + FTSR + Falling Trigger selection register + (EXTI_FTSR) + 0xC + 0x20 + read-write + 0x00000000 + + + TR0 + Falling trigger event configuration of + line 0 + 0 + 1 + + TR0 + read-write + + Disabled + Falling edge trigger is disabled + 0 + + + Enabled + Falling edge trigger is enabled + 1 + + + + + TR1 + Falling trigger event configuration of + line 1 + 1 + 1 + + + + TR2 + Falling trigger event configuration of + line 2 + 2 + 1 + + + + TR3 + Falling trigger event configuration of + line 3 + 3 + 1 + + + + TR4 + Falling trigger event configuration of + line 4 + 4 + 1 + + + + TR5 + Falling trigger event configuration of + line 5 + 5 + 1 + + + + TR6 + Falling trigger event configuration of + line 6 + 6 + 1 + + + + TR7 + Falling trigger event configuration of + line 7 + 7 + 1 + + + + TR8 + Falling trigger event configuration of + line 8 + 8 + 1 + + + + TR9 + Falling trigger event configuration of + line 9 + 9 + 1 + + + + TR10 + Falling trigger event configuration of + line 10 + 10 + 1 + + + + TR11 + Falling trigger event configuration of + line 11 + 11 + 1 + + + + TR12 + Falling trigger event configuration of + line 12 + 12 + 1 + + + + TR13 + Falling trigger event configuration of + line 13 + 13 + 1 + + + + TR14 + Falling trigger event configuration of + line 14 + 14 + 1 + + + + TR15 + Falling trigger event configuration of + line 15 + 15 + 1 + + + + TR16 + Falling trigger event configuration of + line 16 + 16 + 1 + + + + TR17 + Falling trigger event configuration of + line 17 + 17 + 1 + + + + TR18 + Falling trigger event configuration of + line 18 + 18 + 1 + + + + TR19 + Falling trigger event configuration of + line 19 + 19 + 1 + + + + TR20 + Falling trigger event configuration of + line 20 + 20 + 1 + + + + TR21 + Falling trigger event configuration of + line 21 + 21 + 1 + + + + TR22 + Falling trigger event configuration of + line 22 + 22 + 1 + + + + + + SWIER + SWIER + Software interrupt event register + (EXTI_SWIER) + 0x10 + 0x20 + read-write + 0x00000000 + + + SWIER0 + Software Interrupt on line + 0 + 0 + 1 + + SWIER0W + write + + Pend + Generates an interrupt request + 1 + + + + + SWIER1 + Software Interrupt on line + 1 + 1 + 1 + + + + SWIER2 + Software Interrupt on line + 2 + 2 + 1 + + + + SWIER3 + Software Interrupt on line + 3 + 3 + 1 + + + + SWIER4 + Software Interrupt on line + 4 + 4 + 1 + + + + SWIER5 + Software Interrupt on line + 5 + 5 + 1 + + + + SWIER6 + Software Interrupt on line + 6 + 6 + 1 + + + + SWIER7 + Software Interrupt on line + 7 + 7 + 1 + + + + SWIER8 + Software Interrupt on line + 8 + 8 + 1 + + + + SWIER9 + Software Interrupt on line + 9 + 9 + 1 + + + + SWIER10 + Software Interrupt on line + 10 + 10 + 1 + + + + SWIER11 + Software Interrupt on line + 11 + 11 + 1 + + + + SWIER12 + Software Interrupt on line + 12 + 12 + 1 + + + + SWIER13 + Software Interrupt on line + 13 + 13 + 1 + + + + SWIER14 + Software Interrupt on line + 14 + 14 + 1 + + + + SWIER15 + Software Interrupt on line + 15 + 15 + 1 + + + + SWIER16 + Software Interrupt on line + 16 + 16 + 1 + + + + SWIER17 + Software Interrupt on line + 17 + 17 + 1 + + + + SWIER18 + Software Interrupt on line + 18 + 18 + 1 + + + + SWIER19 + Software Interrupt on line + 19 + 19 + 1 + + + + SWIER20 + Software Interrupt on line + 20 + 20 + 1 + + + + SWIER21 + Software Interrupt on line + 21 + 21 + 1 + + + + SWIER22 + Software Interrupt on line + 22 + 22 + 1 + + + + + + PR + PR + Pending register (EXTI_PR) + 0x14 + 0x20 + read-write + 0x00000000 + + + PR0 + Pending bit 0 + 0 + 1 + oneToClear + + PR0R + read + + NotPending + No trigger request occurred + 0 + + + Pending + Selected trigger request occurred + 1 + + + + PR0W + write + + Clear + Clears pending bit + 1 + + + + + PR1 + Pending bit 1 + 1 + 1 + oneToClear + + read + + + write + + + + PR2 + Pending bit 2 + 2 + 1 + oneToClear + + read + + + write + + + + PR3 + Pending bit 3 + 3 + 1 + oneToClear + + read + + + write + + + + PR4 + Pending bit 4 + 4 + 1 + oneToClear + + read + + + write + + + + PR5 + Pending bit 5 + 5 + 1 + oneToClear + + read + + + write + + + + PR6 + Pending bit 6 + 6 + 1 + oneToClear + + read + + + write + + + + PR7 + Pending bit 7 + 7 + 1 + oneToClear + + read + + + write + + + + PR8 + Pending bit 8 + 8 + 1 + oneToClear + + read + + + write + + + + PR9 + Pending bit 9 + 9 + 1 + oneToClear + + read + + + write + + + + PR10 + Pending bit 10 + 10 + 1 + oneToClear + + read + + + write + + + + PR11 + Pending bit 11 + 11 + 1 + oneToClear + + read + + + write + + + + PR12 + Pending bit 12 + 12 + 1 + oneToClear + + read + + + write + + + + PR13 + Pending bit 13 + 13 + 1 + oneToClear + + read + + + write + + + + PR14 + Pending bit 14 + 14 + 1 + oneToClear + + read + + + write + + + + PR15 + Pending bit 15 + 15 + 1 + oneToClear + + read + + + write + + + + PR16 + Pending bit 16 + 16 + 1 + oneToClear + + read + + + write + + + + PR17 + Pending bit 17 + 17 + 1 + oneToClear + + read + + + write + + + + PR18 + Pending bit 18 + 18 + 1 + oneToClear + + read + + + write + + + + PR19 + Pending bit 19 + 19 + 1 + oneToClear + + read + + + write + + + + PR20 + Pending bit 20 + 20 + 1 + oneToClear + + read + + + write + + + + PR21 + Pending bit 21 + 21 + 1 + oneToClear + + read + + + write + + + + PR22 + Pending bit 22 + 22 + 1 + oneToClear + + read + + + write + + + + + + + + FLASH + FLASH + FLASH + 0x40023C00 + + 0x0 + 0x400 + registers + + + FLASH + FLASH global interrupt + 4 + + + + ACR + ACR + Flash access control register + 0x0 + 0x20 + 0x00000000 + + + LATENCY + Latency + 0 + 4 + read-write + + LATENCY + read-write + + WS0 + 0 wait states + 0 + + + WS1 + 1 wait states + 1 + + + WS2 + 2 wait states + 2 + + + WS3 + 3 wait states + 3 + + + WS4 + 4 wait states + 4 + + + WS5 + 5 wait states + 5 + + + WS6 + 6 wait states + 6 + + + WS7 + 7 wait states + 7 + + + WS8 + 8 wait states + 8 + + + WS9 + 9 wait states + 9 + + + WS10 + 10 wait states + 10 + + + WS11 + 11 wait states + 11 + + + WS12 + 12 wait states + 12 + + + WS13 + 13 wait states + 13 + + + WS14 + 14 wait states + 14 + + + WS15 + 15 wait states + 15 + + + + + PRFTEN + Prefetch enable + 8 + 1 + read-write + + PRFTEN + read-write + + Disabled + Prefetch is disabled + 0 + + + Enabled + Prefetch is enabled + 1 + + + + + ICEN + Instruction cache enable + 9 + 1 + read-write + + ICEN + read-write + + Disabled + Instruction cache is disabled + 0 + + + Enabled + Instruction cache is enabled + 1 + + + + + DCEN + Data cache enable + 10 + 1 + read-write + + DCEN + read-write + + Disabled + Data cache is disabled + 0 + + + Enabled + Data cache is enabled + 1 + + + + + ICRST + Instruction cache reset + 11 + 1 + write-only + + ICRST + write + + NotReset + Instruction cache is not reset + 0 + + + Reset + Instruction cache is reset + 1 + + + + + DCRST + Data cache reset + 12 + 1 + read-write + + DCRST + read-write + + NotReset + Data cache is not reset + 0 + + + Reset + Data cache is reset + 1 + + + + + + + KEYR + KEYR + Flash key register + 0x4 + 0x20 + write-only + 0x00000000 + + + KEY + FPEC key + 0 + 32 + + + 0 + 4294967295 + + + + + + + OPTKEYR + OPTKEYR + Flash option key register + 0x8 + 0x20 + write-only + 0x00000000 + + + OPTKEY + Option byte key + 0 + 32 + + + 0 + 4294967295 + + + + + + + SR + SR + Status register + 0xC + 0x20 + 0x00000000 + + + EOP + End of operation + 0 + 1 + read-write + oneToClear + + EOPW + write + + Clear + Clear error flag + 1 + + + + + OPERR + Operation error + 1 + 1 + read-write + oneToClear + + OPERRW + write + + Clear + Clear error flag + 1 + + + + + WRPERR + Write protection error + 4 + 1 + read-write + oneToClear + + WRPERRW + write + + Clear + Clear error flag + 1 + + + + + PGAERR + Programming alignment + error + 5 + 1 + read-write + oneToClear + + PGAERRW + write + + Clear + Clear error flag + 1 + + + + + PGPERR + Programming parallelism + error + 6 + 1 + read-write + oneToClear + + PGPERRW + write + + Clear + Clear error flag + 1 + + + + + PGSERR + Programming sequence error + 7 + 1 + read-write + oneToClear + + PGSERRW + write + + Clear + Clear error flag + 1 + + + + + BSY + Busy + 16 + 1 + read-only + + BSYR + read + + NotBusy + no Flash memory operation ongoing + 0 + + + Busy + Flash memory operation ongoing + 1 + + + + + + + CR + CR + Control register + 0x10 + 0x20 + read-write + 0x80000000 + + + PG + Programming + 0 + 1 + + PG + read-write + + Program + Flash programming activated + 1 + + + + + SER + Sector Erase + 1 + 1 + + SER + read-write + + SectorErase + Erase activated for selected sector + 1 + + + + + MER + Mass Erase + 2 + 1 + + MER + read-write + + MassErase + Erase activated for all user sectors + 1 + + + + + SNB + Sector number + 3 + 4 + + + 0 + 11 + + + + + PSIZE + Program size + 8 + 2 + + PSIZE + read-write + + PSIZE8 + Program x8 + 0 + + + PSIZE16 + Program x16 + 1 + + + PSIZE32 + Program x32 + 2 + + + PSIZE64 + Program x64 + 3 + + + + + STRT + Start + 16 + 1 + + STRT + read-write + + Start + Trigger an erase operation + 1 + + + + + EOPIE + End of operation interrupt + enable + 24 + 1 + + EOPIE + read-write + + Disabled + End of operation interrupt disabled + 0 + + + Enabled + End of operation interrupt enabled + 1 + + + + + ERRIE + Error interrupt enable + 25 + 1 + + ERRIE + read-write + + Disabled + Error interrupt generation disabled + 0 + + + Enabled + Error interrupt generation enabled + 1 + + + + + LOCK + Lock + 31 + 1 + + LOCK + read-write + + Unlocked + FLASH_CR register is unlocked + 0 + + + Locked + FLASH_CR register is locked + 1 + + + + + + + OPTCR + OPTCR + Flash option control register + 0x14 + 0x20 + read-write + 0x00000014 + + + OPTLOCK + Option lock + 0 + 1 + + + OPTSTRT + Option start + 1 + 1 + + + BOR_LEV + BOR reset Level + 2 + 2 + + + WDG_SW + WDG_SW User option bytes + 5 + 1 + + + nRST_STOP + nRST_STOP User option + bytes + 6 + 1 + + + nRST_STDBY + nRST_STDBY User option + bytes + 7 + 1 + + + RDP + Read protect + 8 + 8 + + + nWRP + Not write protect + 16 + 12 + + + + + + + IWDG + Independent watchdog + IWDG + 0x40003000 + + 0x0 + 0x400 + registers + + + + KR + KR + Key register + 0x0 + 0x20 + write-only + 0x00000000 + + + KEY + Key value + 0 + 16 + + KEY + write + + Enable + Enable access to PR, RLR and WINR registers (0x5555) + 21845 + + + Reset + Reset the watchdog value (0xAAAA) + 43690 + + + Start + Start the watchdog (0xCCCC) + 52428 + + + + + + + PR + PR + Prescaler register + 0x4 + 0x20 + read-write + 0x00000000 + + + PR + Prescaler divider + 0 + 3 + + PR + read-write + + DivideBy4 + Divider /4 + 0 + + + DivideBy8 + Divider /8 + 1 + + + DivideBy16 + Divider /16 + 2 + + + DivideBy32 + Divider /32 + 3 + + + DivideBy64 + Divider /64 + 4 + + + DivideBy128 + Divider /128 + 5 + + + DivideBy256 + Divider /256 + 6 + + + DivideBy256bis + Divider /256 + 7 + + + + + + + RLR + RLR + Reload register + 0x8 + 0x20 + read-write + 0x00000FFF + + + RL + Watchdog counter reload + value + 0 + 12 + + + 0 + 4095 + + + + + + + SR + SR + Status register + 0xC + 0x20 + read-only + 0x00000000 + + + RVU + Watchdog counter reload value + update + 1 + 1 + + + PVU + Watchdog prescaler value + update + 0 + 1 + + + + + + + OTG_FS_DEVICE + USB on the go full speed + USB_OTG_FS + 0x50000800 + + 0x0 + 0x400 + registers + + + + DCFG + DCFG + OTG_FS device configuration register + (OTG_FS_DCFG) + 0x0 + 0x20 + read-write + 0x02200000 + + + DSPD + Device speed + 0 + 2 + + + NZLSOHSK + Non-zero-length status OUT + handshake + 2 + 1 + + + DAD + Device address + 4 + 7 + + + PFIVL + Periodic frame interval + 11 + 2 + + + + + DCTL + DCTL + OTG_FS device control register + (OTG_FS_DCTL) + 0x4 + 0x20 + 0x00000000 + + + RWUSIG + Remote wakeup signaling + 0 + 1 + read-write + + + SDIS + Soft disconnect + 1 + 1 + read-write + + + GINSTS + Global IN NAK status + 2 + 1 + read-only + + + GONSTS + Global OUT NAK status + 3 + 1 + read-only + + + TCTL + Test control + 4 + 3 + read-write + + + SGINAK + Set global IN NAK + 7 + 1 + read-write + + + CGINAK + Clear global IN NAK + 8 + 1 + read-write + + + SGONAK + Set global OUT NAK + 9 + 1 + read-write + + + CGONAK + Clear global OUT NAK + 10 + 1 + read-write + + + POPRGDNE + Power-on programming done + 11 + 1 + read-write + + + + + DSTS + DSTS + OTG_FS device status register + (OTG_FS_DSTS) + 0x8 + 0x20 + read-only + 0x00000010 + + + SUSPSTS + Suspend status + 0 + 1 + + + ENUMSPD + Enumerated speed + 1 + 2 + + + EERR + Erratic error + 3 + 1 + + + FNSOF + Frame number of the received + SOF + 8 + 14 + + + + + DIEPMSK + DIEPMSK + OTG_FS device IN endpoint common interrupt + mask register (OTG_FS_DIEPMSK) + 0x10 + 0x20 + read-write + 0x00000000 + + + XFRCM + Transfer completed interrupt + mask + 0 + 1 + + + EPDM + Endpoint disabled interrupt + mask + 1 + 1 + + + TOM + Timeout condition mask (Non-isochronous + endpoints) + 3 + 1 + + + ITTXFEMSK + IN token received when TxFIFO empty + mask + 4 + 1 + + + INEPNMM + IN token received with EP mismatch + mask + 5 + 1 + + + INEPNEM + IN endpoint NAK effective + mask + 6 + 1 + + + + + DOEPMSK + DOEPMSK + OTG_FS device OUT endpoint common interrupt + mask register (OTG_FS_DOEPMSK) + 0x14 + 0x20 + read-write + 0x00000000 + + + XFRCM + Transfer completed interrupt + mask + 0 + 1 + + + EPDM + Endpoint disabled interrupt + mask + 1 + 1 + + + STUPM + SETUP phase done mask + 3 + 1 + + + OTEPDM + OUT token received when endpoint + disabled mask + 4 + 1 + + + + + DAINT + DAINT + OTG_FS device all endpoints interrupt + register (OTG_FS_DAINT) + 0x18 + 0x20 + read-only + 0x00000000 + + + IEPINT + IN endpoint interrupt bits + 0 + 16 + + + OEPINT + OUT endpoint interrupt + bits + 16 + 16 + + + + + DAINTMSK + DAINTMSK + OTG_FS all endpoints interrupt mask register + (OTG_FS_DAINTMSK) + 0x1C + 0x20 + read-write + 0x00000000 + + + IEPM + IN EP interrupt mask bits + 0 + 16 + + + OEPM + OUT EP interrupt mask bits + 16 + 16 + + + + + DVBUSDIS + DVBUSDIS + OTG_FS device VBUS discharge time + register + 0x28 + 0x20 + read-write + 0x000017D7 + + + VBUSDT + Device VBUS discharge time + 0 + 16 + + + + + DVBUSPULSE + DVBUSPULSE + OTG_FS device VBUS pulsing time + register + 0x2C + 0x20 + read-write + 0x000005B8 + + + DVBUSP + Device VBUS pulsing time + 0 + 12 + + + + + DIEPEMPMSK + DIEPEMPMSK + OTG_FS device IN endpoint FIFO empty + interrupt mask register + 0x34 + 0x20 + read-write + 0x00000000 + + + INEPTXFEM + IN EP Tx FIFO empty interrupt mask + bits + 0 + 16 + + + + + DIEP0 + Device IN endpoint 0 + 0x100 + + CTL + DIEPCTL0 + OTG_FS device control IN endpoint 0 control + register (OTG_FS_DIEPCTL0) + 0x0 + 0x20 + 0x00000000 + + + MPSIZ + Maximum packet size + 0 + 2 + read-write + + + USBAEP + USB active endpoint + 15 + 1 + read-only + + + NAKSTS + NAK status + 17 + 1 + read-only + + + EPTYP + Endpoint type + 18 + 2 + read-only + + + STALL + STALL handshake + 21 + 1 + read-write + + + TXFNUM + TxFIFO number + 22 + 4 + read-write + + + CNAK + Clear NAK + 26 + 1 + write-only + + + SNAK + Set NAK + 27 + 1 + write-only + + + EPDIS + Endpoint disable + 30 + 1 + read-only + + + EPENA + Endpoint enable + 31 + 1 + read-write + + + + + INT + DIEPINT0 + device endpoint-x interrupt + register + 0x8 + 0x20 + 0x00000080 + + + TXFE + TXFE + 7 + 1 + read-only + + + INEPNE + INEPNE + 6 + 1 + read-write + + + ITTXFE + ITTXFE + 4 + 1 + read-write + + + TOC + TOC + 3 + 1 + read-write + + + EPDISD + EPDISD + 1 + 1 + read-write + + + XFRC + XFRC + 0 + 1 + read-write + + + + + TSIZ + DIEPTSIZ0 + device endpoint-0 transfer size + register + 0x10 + 0x20 + read-write + 0x00000000 + + + PKTCNT + Packet count + 19 + 2 + + + XFRSIZ + Transfer size + 0 + 7 + + + + + TXFSTS + DTXFSTS0 + OTG_FS device IN endpoint transmit FIFO + status register + 0x18 + 0x20 + read-only + 0x00000000 + + + INEPTFSAV + IN endpoint TxFIFO space + available + 0 + 16 + + + + + + 3 + 0x20 + 1-3 + DIEP%s + Device IN endpoint X + 0x120 + + CTL + DIEPCTL1 + OTG device endpoint-1 control + register + 0x0 + 0x20 + 0x00000000 + + + EPENA + EPENA + 31 + 1 + read-write + + + EPDIS + EPDIS + 30 + 1 + read-write + + + SODDFRM_SD1PID + SODDFRM/SD1PID + 29 + 1 + write-only + + + SD0PID_SEVNFRM + SD0PID/SEVNFRM + 28 + 1 + write-only + + + SNAK + SNAK + 27 + 1 + write-only + + + CNAK + CNAK + 26 + 1 + write-only + + + TXFNUM + TXFNUM + 22 + 4 + read-write + + + STALL + STALL handshake + 21 + 1 + read-write + + + EPTYP + EPTYP + 18 + 2 + read-write + + + NAKSTS + NAKSTS + 17 + 1 + read-only + + + EONUM_DPID + EONUM/DPID + 16 + 1 + read-only + + + USBAEP + USBAEP + 15 + 1 + read-write + + + MPSIZ + MPSIZ + 0 + 11 + read-write + + + + + INT + DIEPINT1 + device endpoint-1 interrupt + register + 0x8 + 0x20 + 0x00000080 + + + TXFE + TXFE + 7 + 1 + read-only + + + INEPNE + INEPNE + 6 + 1 + read-write + + + ITTXFE + ITTXFE + 4 + 1 + read-write + + + TOC + TOC + 3 + 1 + read-write + + + EPDISD + EPDISD + 1 + 1 + read-write + + + XFRC + XFRC + 0 + 1 + read-write + + + + + TSIZ + DIEPTSIZ1 + device endpoint-1 transfer size + register + 0x10 + 0x20 + read-write + 0x00000000 + + + MCNT + Multi count + 29 + 2 + + + PKTCNT + Packet count + 19 + 10 + + + XFRSIZ + Transfer size + 0 + 19 + + + + + TXFSTS + DTXFSTS1 + OTG_FS device IN endpoint transmit FIFO + status register + 0x18 + 0x20 + read-only + 0x00000000 + + + INEPTFSAV + IN endpoint TxFIFO space + available + 0 + 16 + + + + + + DOEP0 + Device OUT endpoint 0 + 0x300 + + CTL + DOEPCTL0 + device endpoint-0 control + register + 0x0 + 0x20 + 0x00008000 + + + EPENA + EPENA + 31 + 1 + read-write + + + EPDIS + EPDIS + 30 + 1 + read-only + + + SNAK + SNAK + 27 + 1 + write-only + + + CNAK + CNAK + 26 + 1 + write-only + + + STALL + STALL handshake + 21 + 1 + read-write + + + SNPM + SNPM + 20 + 1 + read-write + + + EPTYP + EPTYP + 18 + 2 + read-only + + + NAKSTS + NAKSTS + 17 + 1 + read-only + + + USBAEP + USBAEP + 15 + 1 + read-only + + + MPSIZ + MPSIZ + 0 + 2 + read-only + + + + + INT + DOEPINT0 + device endpoint-0 interrupt + register + 0x8 + 0x20 + read-write + 0x00000080 + + + B2BSTUP + B2BSTUP + 6 + 1 + + + OTEPDIS + OTEPDIS + 4 + 1 + + + STUP + STUP + 3 + 1 + + + EPDISD + EPDISD + 1 + 1 + + + XFRC + XFRC + 0 + 1 + + + + + TSIZ + DOEPTSIZ0 + device OUT endpoint-0 transfer size + register + 0x10 + 0x20 + read-write + 0x00000000 + + + STUPCNT + SETUP packet count + 29 + 2 + + + PKTCNT + Packet count + 19 + 1 + + + XFRSIZ + Transfer size + 0 + 7 + + + + + + 3 + 0x20 + 1-3 + DOEP%s + Device IN endpoint X + 0x320 + + CTL + DOEPCTL1 + device endpoint-1 control + register + 0x0 + 0x20 + 0x00000000 + + + EPENA + EPENA + 31 + 1 + read-write + + + EPDIS + EPDIS + 30 + 1 + read-write + + + SODDFRM + SODDFRM + 29 + 1 + write-only + + + SD0PID_SEVNFRM + SD0PID/SEVNFRM + 28 + 1 + write-only + + + SNAK + SNAK + 27 + 1 + write-only + + + CNAK + CNAK + 26 + 1 + write-only + + + STALL + STALL handshake + 21 + 1 + read-write + + + SNPM + SNPM + 20 + 1 + read-write + + + EPTYP + EPTYP + 18 + 2 + read-write + + + NAKSTS + NAKSTS + 17 + 1 + read-only + + + EONUM_DPID + EONUM/DPID + 16 + 1 + read-only + + + USBAEP + USBAEP + 15 + 1 + read-write + + + MPSIZ + MPSIZ + 0 + 11 + read-write + + + + + INT + DOEPINT1 + device endpoint-1 interrupt + register + 0x8 + 0x20 + read-write + 0x00000080 + + + B2BSTUP + B2BSTUP + 6 + 1 + + + OTEPDIS + OTEPDIS + 4 + 1 + + + STUP + STUP + 3 + 1 + + + EPDISD + EPDISD + 1 + 1 + + + XFRC + XFRC + 0 + 1 + + + + + TSIZ + DOEPTSIZ1 + device OUT endpoint-1 transfer size + register + 0x10 + 0x20 + read-write + 0x00000000 + + + RXDPID_STUPCNT + Received data PID/SETUP packet + count + 29 + 2 + + + PKTCNT + Packet count + 19 + 10 + + + XFRSIZ + Transfer size + 0 + 19 + + + + + + + + OTG_FS_GLOBAL + USB on the go full speed + USB_OTG_FS + 0x50000000 + + 0x0 + 0x400 + registers + + + + GOTGCTL + GOTGCTL + OTG_FS control and status register + (OTG_FS_GOTGCTL) + 0x0 + 0x20 + 0x00000800 + + + SRQSCS + Session request success + 0 + 1 + read-only + + + SRQ + Session request + 1 + 1 + read-write + + + HNGSCS + Host negotiation success + 8 + 1 + read-only + + + HNPRQ + HNP request + 9 + 1 + read-write + + + HSHNPEN + Host set HNP enable + 10 + 1 + read-write + + + DHNPEN + Device HNP enabled + 11 + 1 + read-write + + + CIDSTS + Connector ID status + 16 + 1 + read-only + + + DBCT + Long/short debounce time + 17 + 1 + read-only + + + ASVLD + A-session valid + 18 + 1 + read-only + + + BSVLD + B-session valid + 19 + 1 + read-only + + + + + GOTGINT + GOTGINT + OTG_FS interrupt register + (OTG_FS_GOTGINT) + 0x4 + 0x20 + read-write + 0x00000000 + + + SEDET + Session end detected + 2 + 1 + + + SRSSCHG + Session request success status + change + 8 + 1 + + + HNSSCHG + Host negotiation success status + change + 9 + 1 + + + HNGDET + Host negotiation detected + 17 + 1 + + + ADTOCHG + A-device timeout change + 18 + 1 + + + DBCDNE + Debounce done + 19 + 1 + + + + + GAHBCFG + GAHBCFG + OTG_FS AHB configuration register + (OTG_FS_GAHBCFG) + 0x8 + 0x20 + read-write + 0x00000000 + + + GINT + Global interrupt mask + 0 + 1 + + + TXFELVL + TxFIFO empty level + 7 + 1 + + + PTXFELVL + Periodic TxFIFO empty + level + 8 + 1 + + + + + GUSBCFG + GUSBCFG + OTG_FS USB configuration register + (OTG_FS_GUSBCFG) + 0xC + 0x20 + 0x00000A00 + + + TOCAL + FS timeout calibration + 0 + 3 + read-write + + + PHYSEL + Full Speed serial transceiver + select + 6 + 1 + write-only + + + SRPCAP + SRP-capable + 8 + 1 + read-write + + + HNPCAP + HNP-capable + 9 + 1 + read-write + + + TRDT + USB turnaround time + 10 + 4 + read-write + + + FHMOD + Force host mode + 29 + 1 + read-write + + + FDMOD + Force device mode + 30 + 1 + read-write + + + CTXPKT + Corrupt Tx packet + 31 + 1 + read-write + + + + + GRSTCTL + GRSTCTL + OTG_FS reset register + (OTG_FS_GRSTCTL) + 0x10 + 0x20 + 0x20000000 + + + CSRST + Core soft reset + 0 + 1 + read-write + + + HSRST + HCLK soft reset + 1 + 1 + read-write + + + FCRST + Host frame counter reset + 2 + 1 + read-write + + + RXFFLSH + RxFIFO flush + 4 + 1 + read-write + + + TXFFLSH + TxFIFO flush + 5 + 1 + read-write + + + TXFNUM + TxFIFO number + 6 + 5 + read-write + + + AHBIDL + AHB master idle + 31 + 1 + read-only + + + + + GINTSTS + GINTSTS + OTG_FS core interrupt register + (OTG_FS_GINTSTS) + 0x14 + 0x20 + 0x04000020 + + + CMOD + Current mode of operation + 0 + 1 + read-only + + + MMIS + Mode mismatch interrupt + 1 + 1 + read-write + + + OTGINT + OTG interrupt + 2 + 1 + read-only + + + SOF + Start of frame + 3 + 1 + read-write + + + RXFLVL + RxFIFO non-empty + 4 + 1 + read-only + + + NPTXFE + Non-periodic TxFIFO empty + 5 + 1 + read-only + + + GINAKEFF + Global IN non-periodic NAK + effective + 6 + 1 + read-only + + + GOUTNAKEFF + Global OUT NAK effective + 7 + 1 + read-only + + + ESUSP + Early suspend + 10 + 1 + read-write + + + USBSUSP + USB suspend + 11 + 1 + read-write + + + USBRST + USB reset + 12 + 1 + read-write + + + ENUMDNE + Enumeration done + 13 + 1 + read-write + + + ISOODRP + Isochronous OUT packet dropped + interrupt + 14 + 1 + read-write + + + EOPF + End of periodic frame + interrupt + 15 + 1 + read-write + + + IEPINT + IN endpoint interrupt + 18 + 1 + read-only + + + OEPINT + OUT endpoint interrupt + 19 + 1 + read-only + + + IISOIXFR + Incomplete isochronous IN + transfer + 20 + 1 + read-write + + + IPXFR_INCOMPISOOUT + Incomplete periodic transfer(Host + mode)/Incomplete isochronous OUT transfer(Device + mode) + 21 + 1 + read-write + + + HPRTINT + Host port interrupt + 24 + 1 + read-only + + + HCINT + Host channels interrupt + 25 + 1 + read-only + + + PTXFE + Periodic TxFIFO empty + 26 + 1 + read-only + + + CIDSCHG + Connector ID status change + 28 + 1 + read-write + + + DISCINT + Disconnect detected + interrupt + 29 + 1 + read-write + + + SRQINT + Session request/new session detected + interrupt + 30 + 1 + read-write + + + WKUPINT + Resume/remote wakeup detected + interrupt + 31 + 1 + read-write + + + + + GINTMSK + GINTMSK + OTG_FS interrupt mask register + (OTG_FS_GINTMSK) + 0x18 + 0x20 + 0x00000000 + + + MMISM + Mode mismatch interrupt + mask + 1 + 1 + read-write + + + OTGINT + OTG interrupt mask + 2 + 1 + read-write + + + SOFM + Start of frame mask + 3 + 1 + read-write + + + RXFLVLM + Receive FIFO non-empty + mask + 4 + 1 + read-write + + + NPTXFEM + Non-periodic TxFIFO empty + mask + 5 + 1 + read-write + + + GINAKEFFM + Global non-periodic IN NAK effective + mask + 6 + 1 + read-write + + + GONAKEFFM + Global OUT NAK effective + mask + 7 + 1 + read-write + + + ESUSPM + Early suspend mask + 10 + 1 + read-write + + + USBSUSPM + USB suspend mask + 11 + 1 + read-write + + + USBRST + USB reset mask + 12 + 1 + read-write + + + ENUMDNEM + Enumeration done mask + 13 + 1 + read-write + + + ISOODRPM + Isochronous OUT packet dropped interrupt + mask + 14 + 1 + read-write + + + EOPFM + End of periodic frame interrupt + mask + 15 + 1 + read-write + + + EPMISM + Endpoint mismatch interrupt + mask + 17 + 1 + read-write + + + IEPINT + IN endpoints interrupt + mask + 18 + 1 + read-write + + + OEPINT + OUT endpoints interrupt + mask + 19 + 1 + read-write + + + IISOIXFRM + Incomplete isochronous IN transfer + mask + 20 + 1 + read-write + + + IPXFRM_IISOOXFRM + Incomplete periodic transfer mask(Host + mode)/Incomplete isochronous OUT transfer mask(Device + mode) + 21 + 1 + read-write + + + PRTIM + Host port interrupt mask + 24 + 1 + read-write + + + HCIM + Host channels interrupt + mask + 25 + 1 + read-write + + + PTXFEM + Periodic TxFIFO empty mask + 26 + 1 + read-write + + + CIDSCHGM + Connector ID status change + mask + 28 + 1 + read-write + + + DISCINT + Disconnect detected interrupt + mask + 29 + 1 + read-write + + + SRQIM + Session request/new session detected + interrupt mask + 30 + 1 + read-write + + + WUIM + Resume/remote wakeup detected interrupt + mask + 31 + 1 + read-write + + + + + GRXSTSR_Device + GRXSTSR_Device + OTG_FS Receive status debug read(Device + mode) + 0x1C + 0x20 + read-only + 0x00000000 + + + EPNUM + Endpoint number + 0 + 4 + + + BCNT + Byte count + 4 + 11 + + + DPID + Data PID + 15 + 2 + + + PKTSTS + Packet status + 17 + 4 + + + FRMNUM + Frame number + 21 + 4 + + + + + GRXSTSR_Host + GRXSTSR_Host + OTG status debug read (host mode) + GRXSTSR_Device + 0x1C + 0x20 + read-only + 0x00000000 + + + CHNUM + Channel number + 0 + 4 + + + BCNT + Byte count + 4 + 11 + + + DPID + Data PID + 15 + 2 + + + PKTSTS + Packet status + 17 + 4 + + + + + GRXFSIZ + GRXFSIZ + OTG_FS Receive FIFO size register + (OTG_FS_GRXFSIZ) + 0x24 + 0x20 + read-write + 0x00000200 + + + RXFD + RxFIFO depth + 0 + 16 + + + + + DIEPTXF0 + DIEPTXF0 + OTG_FS non-periodic transmit FIFO size + register (Device mode) + 0x28 + 0x20 + read-write + 0x00000200 + + + TX0FSA + Endpoint 0 transmit RAM start + address + 0 + 16 + + + TX0FD + Endpoint 0 TxFIFO depth + 16 + 16 + + + + + HNPTXFSIZ + HNPTXFSIZ + OTG_FS non-periodic transmit FIFO size + register (Host mode) + DIEPTXF0 + 0x28 + 0x20 + read-write + 0x00000200 + + + NPTXFSA + Non-periodic transmit RAM start + address + 0 + 16 + + + NPTXFD + Non-periodic TxFIFO depth + 16 + 16 + + + + + GNPTXSTS + GNPTXSTS + OTG_FS non-periodic transmit FIFO/queue + status register (OTG_FS_GNPTXSTS) + 0x2C + 0x20 + read-only + 0x00080200 + + + NPTXFSAV + Non-periodic TxFIFO space + available + 0 + 16 + + + NPTQXSAV + Non-periodic transmit request queue + space available + 16 + 8 + + + NPTXQTOP + Top of the non-periodic transmit request + queue + 24 + 7 + + + + + GCCFG + GCCFG + OTG_FS general core configuration register + (OTG_FS_GCCFG) + 0x38 + 0x20 + read-write + 0x00000000 + + + PWRDWN + Power down + 16 + 1 + + + VBUSASEN + Enable the VBUS sensing + device + 18 + 1 + + + VBUSBSEN + Enable the VBUS sensing + device + 19 + 1 + + + SOFOUTEN + SOF output enable + 20 + 1 + + + NOVBUSSENS + Vbus sensing disable option + 21 + 1 + + + + + CID + CID + core ID register + 0x3C + 0x20 + read-write + 0x00001000 + + + PRODUCT_ID + Product ID field + 0 + 32 + + + + + HPTXFSIZ + HPTXFSIZ + OTG_FS Host periodic transmit FIFO size + register (OTG_FS_HPTXFSIZ) + 0x100 + 0x20 + read-write + 0x02000600 + + + PTXSA + Host periodic TxFIFO start + address + 0 + 16 + + + PTXFSIZ + Host periodic TxFIFO depth + 16 + 16 + + + + + 3 + 0x4 + 1-3 + DIEPTXF%s + DIEPTXF1 + OTF_FS device IN endpoint transmit FIFO size register + 0x104 + 0x20 + read-write + 0x02000400 + + + INEPTXSA + IN endpoint FIFO2 transmit RAM start + address + 0 + 16 + + + INEPTXFD + IN endpoint TxFIFO depth + 16 + 16 + + + + + GRXSTSP_Device + OTG status read and pop (device mode) + 0x20 + 0x20 + read-only + 0x00000000 + + + FRMNUM + Frame number + 21 + 4 + + + PKTSTS + Packet status + 17 + 4 + + + DPID + Data PID + 15 + 2 + + + BCNT + Byte count + 4 + 11 + + + EPNUM + Endpoint number + 0 + 4 + + + + + GRXSTSP_Host + OTG status read and pop (host mode) + GRXSTSP_Device + 0x20 + 0x20 + read-only + 0x00000000 + + + PKTSTS + Packet status + 17 + 4 + + + DPID + Data PID + 15 + 2 + + + BCNT + Byte count + 4 + 11 + + + CHNUM + Channel number + 0 + 4 + + + + + + + OTG_FS_HOST + USB on the go full speed + USB_OTG_FS + 0x50000400 + + 0x0 + 0x400 + registers + + + + HCFG + HCFG + OTG_FS host configuration register + (OTG_FS_HCFG) + 0x0 + 0x20 + 0x00000000 + + + FSLSPCS + FS/LS PHY clock select + 0 + 2 + read-write + + + FSLSS + FS- and LS-only support + 2 + 1 + read-write + + + + + HFIR + HFIR + OTG_FS Host frame interval + register + 0x4 + 0x20 + read-write + 0x0000EA60 + + + FRIVL + Frame interval + 0 + 16 + + + + + HFNUM + HFNUM + OTG_FS host frame number/frame time + remaining register (OTG_FS_HFNUM) + 0x8 + 0x20 + read-only + 0x00003FFF + + + FRNUM + Frame number + 0 + 16 + + + FTREM + Frame time remaining + 16 + 16 + + + + + HPTXSTS + HPTXSTS + OTG_FS_Host periodic transmit FIFO/queue + status register (OTG_FS_HPTXSTS) + 0x10 + 0x20 + 0x00080100 + + + PTXFSAVL + Periodic transmit data FIFO space + available + 0 + 16 + read-write + + + PTXQSAV + Periodic transmit request queue space + available + 16 + 8 + read-only + + + PTXQTOP + Top of the periodic transmit request + queue + 24 + 8 + read-only + + + + + HAINT + HAINT + OTG_FS Host all channels interrupt + register + 0x14 + 0x20 + read-only + 0x00000000 + + + HAINT + Channel interrupts + 0 + 16 + + + + + HAINTMSK + HAINTMSK + OTG_FS host all channels interrupt mask + register + 0x18 + 0x20 + read-write + 0x00000000 + + + HAINTM + Channel interrupt mask + 0 + 16 + + + + + HPRT + HPRT + OTG_FS host port control and status register + (OTG_FS_HPRT) + 0x40 + 0x20 + 0x00000000 + + + PCSTS + Port connect status + 0 + 1 + read-only + + + PCDET + Port connect detected + 1 + 1 + read-write + + + PENA + Port enable + 2 + 1 + read-write + + + PENCHNG + Port enable/disable change + 3 + 1 + read-write + + + POCA + Port overcurrent active + 4 + 1 + read-only + + + POCCHNG + Port overcurrent change + 5 + 1 + read-write + + + PRES + Port resume + 6 + 1 + read-write + + + PSUSP + Port suspend + 7 + 1 + read-write + + + PRST + Port reset + 8 + 1 + read-write + + + PLSTS + Port line status + 10 + 2 + read-only + + + PPWR + Port power + 12 + 1 + read-write + + + PTCTL + Port test control + 13 + 4 + read-write + + + PSPD + Port speed + 17 + 2 + read-only + + + + + 8 + 0x20 + 0-7 + HC%s + Host channel + 0x100 + + CHAR + HCCHAR0 + OTG_FS host channel-0 characteristics + register (OTG_FS_HCCHAR0) + 0x0 + 0x20 + read-write + 0x00000000 + + + MPSIZ + Maximum packet size + 0 + 11 + + + EPNUM + Endpoint number + 11 + 4 + + + EPDIR + Endpoint direction + 15 + 1 + + + LSDEV + Low-speed device + 17 + 1 + + + EPTYP + Endpoint type + 18 + 2 + + + MCNT + Multicount + 20 + 2 + + + DAD + Device address + 22 + 7 + + + ODDFRM + Odd frame + 29 + 1 + + + CHDIS + Channel disable + 30 + 1 + + + CHENA + Channel enable + 31 + 1 + + + + + INT + HCINT0 + OTG_FS host channel-0 interrupt register + (OTG_FS_HCINT0) + 0x8 + 0x20 + read-write + 0x00000000 + + + XFRC + Transfer completed + 0 + 1 + + + CHH + Channel halted + 1 + 1 + + + STALL + STALL response received + interrupt + 3 + 1 + + + NAK + NAK response received + interrupt + 4 + 1 + + + ACK + ACK response received/transmitted + interrupt + 5 + 1 + + + TXERR + Transaction error + 7 + 1 + + + BBERR + Babble error + 8 + 1 + + + FRMOR + Frame overrun + 9 + 1 + + + DTERR + Data toggle error + 10 + 1 + + + + + INTMSK + HCINTMSK0 + OTG_FS host channel-0 mask register + (OTG_FS_HCINTMSK0) + 0xC + 0x20 + read-write + 0x00000000 + + + XFRCM + Transfer completed mask + 0 + 1 + + + CHHM + Channel halted mask + 1 + 1 + + + STALLM + STALL response received interrupt + mask + 3 + 1 + + + NAKM + NAK response received interrupt + mask + 4 + 1 + + + ACKM + ACK response received/transmitted + interrupt mask + 5 + 1 + + + NYET + response received interrupt + mask + 6 + 1 + + + TXERRM + Transaction error mask + 7 + 1 + + + BBERRM + Babble error mask + 8 + 1 + + + FRMORM + Frame overrun mask + 9 + 1 + + + DTERRM + Data toggle error mask + 10 + 1 + + + + + TSIZ + HCTSIZ0 + OTG_FS host channel-0 transfer size + register + 0x10 + 0x20 + read-write + 0x00000000 + + + XFRSIZ + Transfer size + 0 + 19 + + + PKTCNT + Packet count + 19 + 10 + + + DPID + Data PID + 29 + 2 + + + + + + + + OTG_FS_PWRCLK + USB on the go full speed + USB_OTG_FS + 0x50000E00 + + 0x0 + 0x400 + registers + + + + PCGCCTL + PCGCCTL + OTG_FS power and clock gating control + register + 0x0 + 0x20 + read-write + 0x00000000 + + + STPPCLK + Stop PHY clock + 0 + 1 + + + GATEHCLK + Gate HCLK + 1 + 1 + + + PHYSUSP + PHY Suspended + 4 + 1 + + + + + + + PWR + Power control + PWR + 0x40007000 + + 0x0 + 0x400 + registers + + + + CR + CR + power control register + 0x0 + 0x20 + read-write + 0x00000000 + + + VOS + Regulator voltage scaling output + selection + 14 + 2 + + + ADCDC1 + ADCDC1 + 13 + 1 + + + FPDS + Flash power down in Stop + mode + 9 + 1 + + + DBP + Disable backup domain write + protection + 8 + 1 + + + PLS + PVD level selection + 5 + 3 + + + PVDE + Power voltage detector + enable + 4 + 1 + + + CSBF + Clear standby flag + 3 + 1 + + + CWUF + Clear wakeup flag + 2 + 1 + + + PDDS + Power down deepsleep + 1 + 1 + + + LPDS + Low-power deep sleep + 0 + 1 + + + + + CSR + CSR + power control/status register + 0x4 + 0x20 + 0x00000000 + + + WUF + Wakeup flag + 0 + 1 + read-only + + + SBF + Standby flag + 1 + 1 + read-only + + + PVDO + PVD output + 2 + 1 + read-only + + + BRR + Backup regulator ready + 3 + 1 + read-only + + + EWUP + Enable WKUP pin + 8 + 1 + read-write + + + BRE + Backup regulator enable + 9 + 1 + read-write + + + VOSRDY + Regulator voltage scaling output + selection ready bit + 14 + 1 + read-write + + + + + + + RCC + Reset and clock control + RCC + 0x40023800 + + 0x0 + 0x400 + registers + + + I2C1_EV + I2C1 event interrupt + 31 + + + I2C1_ER + I2C1 error interrupt + 32 + + + + CR + CR + clock control register + 0x0 + 0x20 + 0x00000083 + + + PLLI2SRDY + PLLI2S clock ready flag + 27 + 1 + read-only + + + + PLLI2SON + PLLI2S enable + 26 + 1 + read-write + + + + PLLRDY + Main PLL (PLL) clock ready + flag + 25 + 1 + read-only + + + + PLLON + Main PLL (PLL) enable + 24 + 1 + read-write + + + + CSSON + Clock security system + enable + 19 + 1 + read-write + + CSSON + read-write + + Off + Clock security system disabled (clock detector OFF) + 0 + + + On + Clock security system enable (clock detector ON if the HSE is ready, OFF if not) + 1 + + + + + HSEBYP + HSE clock bypass + 18 + 1 + read-write + + HSEBYP + read-write + + NotBypassed + HSE crystal oscillator not bypassed + 0 + + + Bypassed + HSE crystal oscillator bypassed with external clock + 1 + + + + + HSERDY + HSE clock ready flag + 17 + 1 + read-only + + + + HSEON + HSE clock enable + 16 + 1 + read-write + + + + HSICAL + Internal high-speed clock + calibration + 8 + 8 + read-only + + + 0 + 255 + + + + + HSITRIM + Internal high-speed clock + trimming + 3 + 5 + read-write + + + 0 + 31 + + + + + HSIRDY + Internal high-speed clock ready + flag + 1 + 1 + read-only + + HSIRDYR + read + + NotReady + Clock not ready + 0 + + + Ready + Clock ready + 1 + + + + + HSION + Internal high-speed clock + enable + 0 + 1 + read-write + + HSION + read-write + + Off + Clock Off + 0 + + + On + Clock On + 1 + + + + + + + PLLCFGR + PLLCFGR + PLL configuration register + 0x4 + 0x20 + read-write + 0x24003010 + + + PLLSRC + Main PLL(PLL) and audio PLL (PLLI2S) + entry clock source + 22 + 1 + + PLLSRC + read-write + + HSI + HSI clock selected as PLL and PLLI2S clock entry + 0 + + + HSE + HSE oscillator clock selected as PLL and PLLI2S clock entry + 1 + + + + + PLLM + Division factor for the main PLL (PLL) + and audio PLL (PLLI2S) input clock + 0 + 6 + + + 2 + 63 + + + + + PLLN + Main PLL (PLL) multiplication factor for + VCO + 6 + 9 + + + 50 + 432 + + + + + PLLP + Main PLL (PLL) division factor for main + system clock + 16 + 2 + + PLLP + read-write + + Div2 + PLLP=2 + 0 + + + Div4 + PLLP=4 + 1 + + + Div6 + PLLP=6 + 2 + + + Div8 + PLLP=8 + 3 + + + + + PLLQ + Main PLL (PLL) division factor for USB + OTG FS, SDIO and random number generator + clocks + 24 + 4 + + + 2 + 15 + + + + + + + CFGR + CFGR + clock configuration register + 0x8 + 0x20 + 0x00000000 + + + MCO2 + Microcontroller clock output + 2 + 30 + 2 + read-write + + MCO2 + read-write + + SYSCLK + System clock (SYSCLK) selected + 0 + + + PLLI2S + PLLI2S clock selected + 1 + + + HSE + HSE oscillator clock selected + 2 + + + PLL + PLL clock selected + 3 + + + + + MCO2PRE + MCO2 prescaler + 27 + 3 + read-write + + + + MCO1PRE + MCO1 prescaler + 24 + 3 + read-write + + MCO1PRE + read-write + + Div1 + No division + 0 + + + Div2 + Division by 2 + 4 + + + Div3 + Division by 3 + 5 + + + Div4 + Division by 4 + 6 + + + Div5 + Division by 5 + 7 + + + + + I2SSRC + I2S clock selection + 23 + 1 + read-write + + I2SSRC + read-write + + PLLI2S + PLLI2S clock used as I2S clock source + 0 + + + CKIN + External clock mapped on the I2S_CKIN pin used as I2S clock source + 1 + + + + + MCO1 + Microcontroller clock output + 1 + 21 + 2 + read-write + + MCO1 + read-write + + HSI + HSI clock selected + 0 + + + LSE + LSE oscillator selected + 1 + + + HSE + HSE oscillator clock selected + 2 + + + PLL + PLL clock selected + 3 + + + + + RTCPRE + HSE division factor for RTC + clock + 16 + 5 + read-write + + + 0 + 31 + + + + + PPRE2 + APB high-speed prescaler + (APB2) + 13 + 3 + read-write + + + + PPRE1 + APB Low speed prescaler + (APB1) + 10 + 3 + read-write + + PPRE1 + read-write + + Div1 + HCLK not divided + 0 + + + Div2 + HCLK divided by 2 + 4 + + + Div4 + HCLK divided by 4 + 5 + + + Div8 + HCLK divided by 8 + 6 + + + Div16 + HCLK divided by 16 + 7 + + + + + HPRE + AHB prescaler + 4 + 4 + read-write + + HPRE + read-write + + Div1 + SYSCLK not divided + 0 + + + Div2 + SYSCLK divided by 2 + 8 + + + Div4 + SYSCLK divided by 4 + 9 + + + Div8 + SYSCLK divided by 8 + 10 + + + Div16 + SYSCLK divided by 16 + 11 + + + Div64 + SYSCLK divided by 64 + 12 + + + Div128 + SYSCLK divided by 128 + 13 + + + Div256 + SYSCLK divided by 256 + 14 + + + Div512 + SYSCLK divided by 512 + 15 + + + + + SW + System clock switch + 0 + 2 + + SW + read-write + + HSI + HSI selected as system clock + 0 + + + HSE + HSE selected as system clock + 1 + + + PLL + PLL selected as system clock + 2 + + + + + SWS + System clock switch status + 2 + 2 + + SWSR + read + + HSI + HSI oscillator used as system clock + 0 + + + HSE + HSE oscillator used as system clock + 1 + + + PLL + PLL used as system clock + 2 + + + + + + + CIR + CIR + clock interrupt register + 0xC + 0x20 + 0x00000000 + + + CSSC + Clock security system interrupt + clear + 23 + 1 + write-only + + CSSCW + write + + Clear + Clear CSSF flag + 1 + + + + + PLLI2SRDYC + PLLI2S ready interrupt + clear + 21 + 1 + write-only + + + + PLLRDYC + Main PLL(PLL) ready interrupt + clear + 20 + 1 + write-only + + + + HSERDYC + HSE ready interrupt clear + 19 + 1 + write-only + + + + HSIRDYC + HSI ready interrupt clear + 18 + 1 + write-only + + + + LSERDYC + LSE ready interrupt clear + 17 + 1 + write-only + + + + LSIRDYC + LSI ready interrupt clear + 16 + 1 + write-only + + LSIRDYCW + write + + Clear + Clear interrupt flag + 1 + + + + + PLLI2SRDYIE + PLLI2S ready interrupt + enable + 13 + 1 + read-write + + + + PLLRDYIE + Main PLL (PLL) ready interrupt + enable + 12 + 1 + read-write + + + + HSERDYIE + HSE ready interrupt enable + 11 + 1 + read-write + + + + HSIRDYIE + HSI ready interrupt enable + 10 + 1 + read-write + + + + LSERDYIE + LSE ready interrupt enable + 9 + 1 + read-write + + + + LSIRDYIE + LSI ready interrupt enable + 8 + 1 + read-write + + LSIRDYIE + read-write + + Disabled + Interrupt disabled + 0 + + + Enabled + Interrupt enabled + 1 + + + + + CSSF + Clock security system interrupt + flag + 7 + 1 + read-only + + CSSFR + read + + NotInterrupted + No clock security interrupt caused by HSE clock failure + 0 + + + Interrupted + Clock security interrupt caused by HSE clock failure + 1 + + + + + PLLI2SRDYF + PLLI2S ready interrupt + flag + 5 + 1 + read-only + + + + PLLRDYF + Main PLL (PLL) ready interrupt + flag + 4 + 1 + read-only + + + + HSERDYF + HSE ready interrupt flag + 3 + 1 + read-only + + + + HSIRDYF + HSI ready interrupt flag + 2 + 1 + read-only + + + + LSERDYF + LSE ready interrupt flag + 1 + 1 + read-only + + + + LSIRDYF + LSI ready interrupt flag + 0 + 1 + read-only + + LSIRDYFR + read + + NotInterrupted + No clock ready interrupt + 0 + + + Interrupted + Clock ready interrupt + 1 + + + + + + + AHB1RSTR + AHB1RSTR + AHB1 peripheral reset register + 0x10 + 0x20 + read-write + 0x00000000 + + + DMA2RST + DMA2 reset + 22 + 1 + + + + DMA1RST + DMA2 reset + 21 + 1 + + + + CRCRST + CRC reset + 12 + 1 + + + + GPIOHRST + IO port H reset + 7 + 1 + + + + GPIOERST + IO port E reset + 4 + 1 + + + + GPIODRST + IO port D reset + 3 + 1 + + + + GPIOCRST + IO port C reset + 2 + 1 + + + + GPIOBRST + IO port B reset + 1 + 1 + + + + GPIOARST + IO port A reset + 0 + 1 + + GPIOARST + read-write + + Reset + Reset the selected module + 1 + + + + + + + AHB2RSTR + AHB2RSTR + AHB2 peripheral reset register + 0x14 + 0x20 + read-write + 0x00000000 + + + OTGFSRST + USB OTG FS module reset + 7 + 1 + + OTGFSRST + read-write + + Reset + Reset the selected module + 1 + + + + + + + APB1RSTR + APB1RSTR + APB1 peripheral reset register + 0x20 + 0x20 + read-write + 0x00000000 + + + PWRRST + Power interface reset + 28 + 1 + + + + I2C3RST + I2C3 reset + 23 + 1 + + + + I2C2RST + I2C 2 reset + 22 + 1 + + + + I2C1RST + I2C 1 reset + 21 + 1 + + + + USART2RST + USART 2 reset + 17 + 1 + + + + SPI3RST + SPI 3 reset + 15 + 1 + + + + SPI2RST + SPI 2 reset + 14 + 1 + + + + WWDGRST + Window watchdog reset + 11 + 1 + + + + TIM5RST + TIM5 reset + 3 + 1 + + + + TIM4RST + TIM4 reset + 2 + 1 + + + + TIM3RST + TIM3 reset + 1 + 1 + + + + TIM2RST + TIM2 reset + 0 + 1 + + TIM2RST + read-write + + Reset + Reset the selected module + 1 + + + + + + + APB2RSTR + APB2RSTR + APB2 peripheral reset register + 0x24 + 0x20 + read-write + 0x00000000 + + + TIM11RST + TIM11 reset + 18 + 1 + + + + TIM10RST + TIM10 reset + 17 + 1 + + + + TIM9RST + TIM9 reset + 16 + 1 + + + + SYSCFGRST + System configuration controller + reset + 14 + 1 + + + + SPI1RST + SPI 1 reset + 12 + 1 + + + + SDIORST + SDIO reset + 11 + 1 + + + + ADCRST + ADC interface reset (common to all + ADCs) + 8 + 1 + + + + USART6RST + USART6 reset + 5 + 1 + + + + USART1RST + USART1 reset + 4 + 1 + + + + TIM1RST + TIM1 reset + 0 + 1 + + TIM1RST + read-write + + Reset + Reset the selected module + 1 + + + + + SPI4RST + SPI4 reset + 13 + 1 + + + + + + AHB1ENR + AHB1ENR + AHB1 peripheral clock register + 0x30 + 0x20 + read-write + 0x00100000 + + + DMA2EN + DMA2 clock enable + 22 + 1 + + + + DMA1EN + DMA1 clock enable + 21 + 1 + + + + CRCEN + CRC clock enable + 12 + 1 + + + + GPIOHEN + IO port H clock enable + 7 + 1 + + + + GPIOEEN + IO port E clock enable + 4 + 1 + + + + GPIODEN + IO port D clock enable + 3 + 1 + + + + GPIOCEN + IO port C clock enable + 2 + 1 + + + + GPIOBEN + IO port B clock enable + 1 + 1 + + + + GPIOAEN + IO port A clock enable + 0 + 1 + + GPIOAEN + read-write + + Disabled + The selected clock is disabled + 0 + + + Enabled + The selected clock is enabled + 1 + + + + + + + AHB2ENR + AHB2ENR + AHB2 peripheral clock enable + register + 0x34 + 0x20 + read-write + 0x00000000 + + + OTGFSEN + USB OTG FS clock enable + 7 + 1 + + OTGFSEN + read-write + + Disabled + The selected clock is disabled + 0 + + + Enabled + The selected clock is enabled + 1 + + + + + + + APB1ENR + APB1ENR + APB1 peripheral clock enable + register + 0x40 + 0x20 + read-write + 0x00000000 + + + PWREN + Power interface clock + enable + 28 + 1 + + + + I2C3EN + I2C3 clock enable + 23 + 1 + + + + I2C2EN + I2C2 clock enable + 22 + 1 + + + + I2C1EN + I2C1 clock enable + 21 + 1 + + + + USART2EN + USART 2 clock enable + 17 + 1 + + + + SPI3EN + SPI3 clock enable + 15 + 1 + + + + SPI2EN + SPI2 clock enable + 14 + 1 + + + + WWDGEN + Window watchdog clock + enable + 11 + 1 + + + + TIM5EN + TIM5 clock enable + 3 + 1 + + + + TIM4EN + TIM4 clock enable + 2 + 1 + + + + TIM3EN + TIM3 clock enable + 1 + 1 + + + + TIM2EN + TIM2 clock enable + 0 + 1 + + TIM2EN + read-write + + Disabled + The selected clock is disabled + 0 + + + Enabled + The selected clock is enabled + 1 + + + + + + + APB2ENR + APB2ENR + APB2 peripheral clock enable + register + 0x44 + 0x20 + read-write + 0x00000000 + + + TIM11EN + TIM11 clock enable + 18 + 1 + + + + TIM10EN + TIM10 clock enable + 17 + 1 + + + + TIM9EN + TIM9 clock enable + 16 + 1 + + + + SYSCFGEN + System configuration controller clock + enable + 14 + 1 + + + + SPI1EN + SPI1 clock enable + 12 + 1 + + + + SDIOEN + SDIO clock enable + 11 + 1 + + + + ADC1EN + ADC1 clock enable + 8 + 1 + + + + USART6EN + USART6 clock enable + 5 + 1 + + + + USART1EN + USART1 clock enable + 4 + 1 + + + + TIM1EN + TIM1 clock enable + 0 + 1 + + TIM1EN + read-write + + Disabled + The selected clock is disabled + 0 + + + Enabled + The selected clock is enabled + 1 + + + + + SPI4EN + SPI4 clock enable + 13 + 1 + + + + + + AHB1LPENR + AHB1LPENR + AHB1 peripheral clock enable in low power + mode register + 0x50 + 0x20 + read-write + 0x7E6791FF + + + DMA2LPEN + DMA2 clock enable during Sleep + mode + 22 + 1 + + + + DMA1LPEN + DMA1 clock enable during Sleep + mode + 21 + 1 + + + + SRAM1LPEN + SRAM 1interface clock enable during + Sleep mode + 16 + 1 + + + + FLITFLPEN + Flash interface clock enable during + Sleep mode + 15 + 1 + + + + CRCLPEN + CRC clock enable during Sleep + mode + 12 + 1 + + + + GPIOHLPEN + IO port H clock enable during Sleep + mode + 7 + 1 + + + + GPIOELPEN + IO port E clock enable during Sleep + mode + 4 + 1 + + + + GPIODLPEN + IO port D clock enable during Sleep + mode + 3 + 1 + + + + GPIOCLPEN + IO port C clock enable during Sleep + mode + 2 + 1 + + + + GPIOBLPEN + IO port B clock enable during Sleep + mode + 1 + 1 + + + + GPIOALPEN + IO port A clock enable during sleep + mode + 0 + 1 + + GPIOALPEN + read-write + + DisabledInSleep + Selected module is disabled during Sleep mode + 0 + + + EnabledInSleep + Selected module is enabled during Sleep mode + 1 + + + + + + + AHB2LPENR + AHB2LPENR + AHB2 peripheral clock enable in low power + mode register + 0x54 + 0x20 + read-write + 0x000000F1 + + + OTGFSLPEN + USB OTG FS clock enable during Sleep + mode + 7 + 1 + + OTGFSLPEN + read-write + + DisabledInSleep + Selected module is disabled during Sleep mode + 0 + + + EnabledInSleep + Selected module is enabled during Sleep mode + 1 + + + + + + + APB1LPENR + APB1LPENR + APB1 peripheral clock enable in low power + mode register + 0x60 + 0x20 + read-write + 0x36FEC9FF + + + PWRLPEN + Power interface clock enable during + Sleep mode + 28 + 1 + + + + I2C3LPEN + I2C3 clock enable during Sleep + mode + 23 + 1 + + + + I2C2LPEN + I2C2 clock enable during Sleep + mode + 22 + 1 + + + + I2C1LPEN + I2C1 clock enable during Sleep + mode + 21 + 1 + + + + USART2LPEN + USART2 clock enable during Sleep + mode + 17 + 1 + + + + SPI3LPEN + SPI3 clock enable during Sleep + mode + 15 + 1 + + + + SPI2LPEN + SPI2 clock enable during Sleep + mode + 14 + 1 + + + + WWDGLPEN + Window watchdog clock enable during + Sleep mode + 11 + 1 + + + + TIM5LPEN + TIM5 clock enable during Sleep + mode + 3 + 1 + + + + TIM4LPEN + TIM4 clock enable during Sleep + mode + 2 + 1 + + + + TIM3LPEN + TIM3 clock enable during Sleep + mode + 1 + 1 + + + + TIM2LPEN + TIM2 clock enable during Sleep + mode + 0 + 1 + + TIM2LPEN + read-write + + DisabledInSleep + Selected module is disabled during Sleep mode + 0 + + + EnabledInSleep + Selected module is enabled during Sleep mode + 1 + + + + + + + APB2LPENR + APB2LPENR + APB2 peripheral clock enabled in low power + mode register + 0x64 + 0x20 + read-write + 0x00075F33 + + + TIM11LPEN + TIM11 clock enable during Sleep + mode + 18 + 1 + + + + TIM10LPEN + TIM10 clock enable during Sleep + mode + 17 + 1 + + + + TIM9LPEN + TIM9 clock enable during sleep + mode + 16 + 1 + + + + SYSCFGLPEN + System configuration controller clock + enable during Sleep mode + 14 + 1 + + + + SPI1LPEN + SPI 1 clock enable during Sleep + mode + 12 + 1 + + + + SDIOLPEN + SDIO clock enable during Sleep + mode + 11 + 1 + + + + ADC1LPEN + ADC1 clock enable during Sleep + mode + 8 + 1 + + + + USART6LPEN + USART6 clock enable during Sleep + mode + 5 + 1 + + + + USART1LPEN + USART1 clock enable during Sleep + mode + 4 + 1 + + + + TIM1LPEN + TIM1 clock enable during Sleep + mode + 0 + 1 + + TIM1LPEN + read-write + + DisabledInSleep + Selected module is disabled during Sleep mode + 0 + + + EnabledInSleep + Selected module is enabled during Sleep mode + 1 + + + + + SPI4LPEN + SPI4 clock enable during Sleep mode + 13 + 1 + + + + + + BDCR + BDCR + Backup domain control register + 0x70 + 0x20 + 0x00000000 + + + BDRST + Backup domain software + reset + 16 + 1 + read-write + + BDRST + read-write + + Disabled + Reset not activated + 0 + + + Enabled + Reset the entire RTC domain + 1 + + + + + RTCEN + RTC clock enable + 15 + 1 + read-write + + RTCEN + read-write + + Disabled + RTC clock disabled + 0 + + + Enabled + RTC clock enabled + 1 + + + + + LSEBYP + External low-speed oscillator + bypass + 2 + 1 + read-write + + LSEBYP + read-write + + NotBypassed + LSE crystal oscillator not bypassed + 0 + + + Bypassed + LSE crystal oscillator bypassed with external clock + 1 + + + + + LSERDY + External low-speed oscillator + ready + 1 + 1 + read-only + + LSERDYR + read + + NotReady + LSE oscillator not ready + 0 + + + Ready + LSE oscillator ready + 1 + + + + + LSEON + External low-speed oscillator + enable + 0 + 1 + read-write + + LSEON + read-write + + Off + LSE oscillator Off + 0 + + + On + LSE oscillator On + 1 + + + + + RTCSEL + RTC clock source selection + 8 + 2 + + RTCSEL + read-write + + NoClock + No clock + 0 + + + LSE + LSE oscillator clock used as RTC clock + 1 + + + LSI + LSI oscillator clock used as RTC clock + 2 + + + HSE + HSE oscillator clock divided by a prescaler used as RTC clock + 3 + + + + + + + CSR + CSR + clock control & status + register + 0x74 + 0x20 + 0x0E000000 + + + LPWRRSTF + Low-power reset flag + 31 + 1 + read-write + + + + WWDGRSTF + Window watchdog reset flag + 30 + 1 + read-write + + + + WDGRSTF + Independent watchdog reset + flag + 29 + 1 + read-write + + + + SFTRSTF + Software reset flag + 28 + 1 + read-write + + + + PORRSTF + POR/PDR reset flag + 27 + 1 + read-write + + + + PADRSTF + PIN reset flag + 26 + 1 + read-write + + + + BORRSTF + BOR reset flag + 25 + 1 + read-write + + BORRSTFR + read + + NoReset + No reset has occured + 0 + + + Reset + A reset has occured + 1 + + + + + RMVF + Remove reset flag + 24 + 1 + read-write + + RMVFW + write + + Clear + Clears the reset flag + 1 + + + + + LSIRDY + Internal low-speed oscillator + ready + 1 + 1 + read-only + + LSIRDYR + read + + NotReady + LSI oscillator not ready + 0 + + + Ready + LSI oscillator ready + 1 + + + + + LSION + Internal low-speed oscillator + enable + 0 + 1 + read-write + + LSION + read-write + + Off + LSI oscillator Off + 0 + + + On + LSI oscillator On + 1 + + + + + + + SSCGR + SSCGR + spread spectrum clock generation + register + 0x80 + 0x20 + read-write + 0x00000000 + + + SSCGEN + Spread spectrum modulation + enable + 31 + 1 + + SSCGEN + read-write + + Disabled + Spread spectrum modulation disabled + 0 + + + Enabled + Spread spectrum modulation enabled + 1 + + + + + SPREADSEL + Spread Select + 30 + 1 + + SPREADSEL + read-write + + Center + Center spread + 0 + + + Down + Down spread + 1 + + + + + INCSTEP + Incrementation step + 13 + 15 + + + 0 + 32767 + + + + + MODPER + Modulation period + 0 + 13 + + + 0 + 8191 + + + + + + + PLLI2SCFGR + PLLI2SCFGR + PLLI2S configuration register + 0x84 + 0x20 + read-write + 0x20003000 + + + PLLI2SR + PLLI2S division factor for I2S + clocks + 28 + 3 + + + 2 + 7 + + + + + PLLI2SN + PLLI2S multiplication factor for + VCO + 6 + 9 + + + 50 + 432 + + + + + + + DCKCFGR + RCC Dedicated Clock Configuration Register + 0x8C + 0x20 + read-write + 0x00000000 + + + TIMPRE + Timers clocks prescalers selection + 24 + 1 + + TIMPRE + read-write + + Mul1Or2 + If the APB prescaler is configured 1, TIMxCLK = PCLKx. Otherwise, TIMxCLK = 2xPCLKx + 0 + + + Mul1Or4 + If the APB prescaler is configured 1, 2 or 4, TIMxCLK = HCLK. Otherwise, TIMxCLK = 4xPCLKx + 1 + + + + + + + + + RTC + Real-time clock + RTC + 0x40002800 + + 0x0 + 0x400 + registers + + + I2C2_EV + I2C2 event interrupt + 33 + + + I2C2_ER + I2C2 error interrupt + 34 + + + + TR + TR + time register + 0x0 + 0x20 + read-write + 0x00000000 + + + PM + AM/PM notation + 22 + 1 + + PM + read-write + + AM + AM or 24-hour format + 0 + + + PM + PM + 1 + + + + + HT + Hour tens in BCD format + 20 + 2 + + + 0 + 3 + + + + + HU + Hour units in BCD format + 16 + 4 + + + 0 + 15 + + + + + MNT + Minute tens in BCD format + 12 + 3 + + + 0 + 7 + + + + + MNU + Minute units in BCD format + 8 + 4 + + + 0 + 15 + + + + + ST + Second tens in BCD format + 4 + 3 + + + 0 + 7 + + + + + SU + Second units in BCD format + 0 + 4 + + + 0 + 15 + + + + + + + DR + DR + date register + 0x4 + 0x20 + read-write + 0x00002101 + + + YT + Year tens in BCD format + 20 + 4 + + + 0 + 15 + + + + + YU + Year units in BCD format + 16 + 4 + + + 0 + 15 + + + + + WDU + Week day units + 13 + 3 + + + 1 + 7 + + + + + MT + Month tens in BCD format + 12 + 1 + + MT + read-write + + Zero + Month tens is 0 + 0 + + + One + Month tens is 1 + 1 + + + + + MU + Month units in BCD format + 8 + 4 + + + 0 + 15 + + + + + DT + Date tens in BCD format + 4 + 2 + + + 0 + 3 + + + + + DU + Date units in BCD format + 0 + 4 + + + 0 + 15 + + + + + + + CR + CR + control register + 0x8 + 0x20 + read-write + 0x00000000 + + + COE + Calibration output enable + 23 + 1 + + COE + read-write + + Disabled + Calibration output disabled + 0 + + + Enabled + Calibration output enabled + 1 + + + + + OSEL + Output selection + 21 + 2 + + OSEL + read-write + + Disabled + Output disabled + 0 + + + AlarmA + Alarm A output enabled + 1 + + + AlarmB + Alarm B output enabled + 2 + + + Wakeup + Wakeup output enabled + 3 + + + + + POL + Output polarity + 20 + 1 + + POL + read-write + + High + The pin is high when ALRAF/ALRBF/WUTF is asserted (depending on OSEL[1:0]) + 0 + + + Low + The pin is low when ALRAF/ALRBF/WUTF is asserted (depending on OSEL[1:0]) + 1 + + + + + COSEL + Calibration Output + selection + 19 + 1 + + COSEL + read-write + + CalFreq_512Hz + Calibration output is 512 Hz (with default prescaler setting) + 0 + + + CalFreq_1Hz + Calibration output is 1 Hz (with default prescaler setting) + 1 + + + + + BKP + Backup + 18 + 1 + + BKP + read-write + + DST_Not_Changed + Daylight Saving Time change has not been performed + 0 + + + DST_Changed + Daylight Saving Time change has been performed + 1 + + + + + SUB1H + Subtract 1 hour (winter time + change) + 17 + 1 + + SUB1HW + write + + Sub1 + Subtracts 1 hour to the current time. This can be used for winter time change outside initialization mode + 1 + + + + + ADD1H + Add 1 hour (summer time + change) + 16 + 1 + + ADD1HW + write + + Add1 + Adds 1 hour to the current time. This can be used for summer time change outside initialization mode + 1 + + + + + TSIE + Time-stamp interrupt + enable + 15 + 1 + + TSIE + read-write + + Disabled + Time-stamp Interrupt disabled + 0 + + + Enabled + Time-stamp Interrupt enabled + 1 + + + + + WUTIE + Wakeup timer interrupt + enable + 14 + 1 + + WUTIE + read-write + + Disabled + Wakeup timer interrupt disabled + 0 + + + Enabled + Wakeup timer interrupt enabled + 1 + + + + + ALRBIE + Alarm B interrupt enable + 13 + 1 + + ALRBIE + read-write + + Disabled + Alarm B Interrupt disabled + 0 + + + Enabled + Alarm B Interrupt enabled + 1 + + + + + ALRAIE + Alarm A interrupt enable + 12 + 1 + + ALRAIE + read-write + + Disabled + Alarm A interrupt disabled + 0 + + + Enabled + Alarm A interrupt enabled + 1 + + + + + TSE + Time stamp enable + 11 + 1 + + TSE + read-write + + Disabled + Timestamp disabled + 0 + + + Enabled + Timestamp enabled + 1 + + + + + WUTE + Wakeup timer enable + 10 + 1 + + WUTE + read-write + + Disabled + Wakeup timer disabled + 0 + + + Enabled + Wakeup timer enabled + 1 + + + + + ALRBE + Alarm B enable + 9 + 1 + + ALRBE + read-write + + Disabled + Alarm B disabled + 0 + + + Enabled + Alarm B enabled + 1 + + + + + ALRAE + Alarm A enable + 8 + 1 + + ALRAE + read-write + + Disabled + Alarm A disabled + 0 + + + Enabled + Alarm A enabled + 1 + + + + + DCE + Coarse digital calibration + enable + 7 + 1 + + + FMT + Hour format + 6 + 1 + + FMT + read-write + + Twenty_Four_Hour + 24 hour/day format + 0 + + + AM_PM + AM/PM hour format + 1 + + + + + BYPSHAD + Bypass the shadow + registers + 5 + 1 + + BYPSHAD + read-write + + ShadowReg + Calendar values (when reading from RTC_SSR, RTC_TR, and RTC_DR) are taken from the shadow registers, which are updated once every two RTCCLK cycles + 0 + + + BypassShadowReg + Calendar values (when reading from RTC_SSR, RTC_TR, and RTC_DR) are taken directly from the calendar counters + 1 + + + + + REFCKON + Reference clock detection enable (50 or + 60 Hz) + 4 + 1 + + REFCKON + read-write + + Disabled + RTC_REFIN detection disabled + 0 + + + Enabled + RTC_REFIN detection enabled + 1 + + + + + TSEDGE + Time-stamp event active + edge + 3 + 1 + + TSEDGE + read-write + + RisingEdge + RTC_TS input rising edge generates a time-stamp event + 0 + + + FallingEdge + RTC_TS input falling edge generates a time-stamp event + 1 + + + + + WUCKSEL + Wakeup clock selection + 0 + 3 + + WUCKSEL + read-write + + Div16 + RTC/16 clock is selected + 0 + + + Div8 + RTC/8 clock is selected + 1 + + + Div4 + RTC/4 clock is selected + 2 + + + Div2 + RTC/2 clock is selected + 3 + + + ClockSpare + ck_spre (usually 1 Hz) clock is selected + 4 + + + ClockSpareWithOffset + ck_spre (usually 1 Hz) clock is selected and 2^16 is added to the WUT counter value + 6 + + + + + + + ISR + ISR + initialization and status + register + 0xC + 0x20 + 0x00000007 + + + ALRAWF + Alarm A write flag + 0 + 1 + read-only + + ALRAWFR + read + + UpdateNotAllowed + Alarm update not allowed + 0 + + + UpdateAllowed + Alarm update allowed + 1 + + + + + ALRBWF + Alarm B write flag + 1 + 1 + read-only + + + + WUTWF + Wakeup timer write flag + 2 + 1 + read-only + + WUTWFR + read + + UpdateNotAllowed + Wakeup timer configuration update not allowed + 0 + + + UpdateAllowed + Wakeup timer configuration update allowed + 1 + + + + + SHPF + Shift operation pending + 3 + 1 + read-write + + SHPFR + read + + NoShiftPending + No shift operation is pending + 0 + + + ShiftPending + A shift operation is pending + 1 + + + + + INITS + Initialization status flag + 4 + 1 + read-only + + INITSR + read + + NotInitalized + Calendar has not been initialized + 0 + + + Initalized + Calendar has been initialized + 1 + + + + + RSF + Registers synchronization + flag + 5 + 1 + read-write + zeroToClear + + RSFR + read + + NotSynced + Calendar shadow registers not yet synchronized + 0 + + + Synced + Calendar shadow registers synchronized + 1 + + + + RSFW + write + + Clear + This flag is cleared by software by writing 0 + 0 + + + + + INITF + Initialization flag + 6 + 1 + read-only + + INITFR + read + + NotAllowed + Calendar registers update is not allowed + 0 + + + Allowed + Calendar registers update is allowed + 1 + + + + + INIT + Initialization mode + 7 + 1 + read-write + + INIT + read-write + + FreeRunningMode + Free running mode + 0 + + + InitMode + Initialization mode used to program time and date register (RTC_TR and RTC_DR), and prescaler register (RTC_PRER). Counters are stopped and start counting from the new value when INIT is reset. + 1 + + + + + ALRAF + Alarm A flag + 8 + 1 + read-write + zeroToClear + + ALRAFR + read + + Match + This flag is set by hardware when the time/date registers (RTC_TR and RTC_DR) match the Alarm A register (RTC_ALRMAR) + 1 + + + + ALRAFW + write + + Clear + This flag is cleared by software by writing 0 + 0 + + + + + ALRBF + Alarm B flag + 9 + 1 + read-write + zeroToClear + + ALRBFR + read + + Match + This flag is set by hardware when the time/date registers (RTC_TR and RTC_DR) match the Alarm B register (RTC_ALRMBR) + 1 + + + + ALRBFW + write + + Clear + This flag is cleared by software by writing 0 + 0 + + + + + WUTF + Wakeup timer flag + 10 + 1 + read-write + zeroToClear + + WUTFR + read + + Zero + This flag is set by hardware when the wakeup auto-reload counter reaches 0 + 1 + + + + WUTFW + write + + Clear + This flag is cleared by software by writing 0 + 0 + + + + + TSF + Time-stamp flag + 11 + 1 + read-write + zeroToClear + + TSFR + read + + TimestampEvent + This flag is set by hardware when a time-stamp event occurs + 1 + + + + TSFW + write + + Clear + This flag is cleared by software by writing 0 + 0 + + + + + TSOVF + Time-stamp overflow flag + 12 + 1 + read-write + zeroToClear + + TSOVFR + read + + Overflow + This flag is set by hardware when a time-stamp event occurs while TSF is already set + 1 + + + + TSOVFW + write + + Clear + This flag is cleared by software by writing 0 + 0 + + + + + TAMP1F + Tamper detection flag + 13 + 1 + read-write + zeroToClear + + TAMP1FR + read + + Tampered + This flag is set by hardware when a tamper detection event is detected on the RTC_TAMPx input + 1 + + + + TAMP1FW + write + + Clear + Flag cleared by software writing 0 + 0 + + + + + TAMP2F + TAMPER2 detection flag + 14 + 1 + read-write + zeroToClear + + read + + + write + + + + RECALPF + Recalibration pending Flag + 16 + 1 + read-only + + RECALPFR + read + + Pending + The RECALPF status flag is automatically set to 1 when software writes to the RTC_CALR register, indicating that the RTC_CALR register is blocked. When the new calibration settings are taken into account, this bit returns to 0 + 1 + + + + + + + PRER + PRER + prescaler register + 0x10 + 0x20 + read-write + 0x007F00FF + + + PREDIV_A + Asynchronous prescaler + factor + 16 + 7 + + + 0 + 127 + + + + + PREDIV_S + Synchronous prescaler + factor + 0 + 15 + + + 0 + 32767 + + + + + + + WUTR + WUTR + wakeup timer register + 0x14 + 0x20 + read-write + 0x0000FFFF + + + WUT + Wakeup auto-reload value + bits + 0 + 16 + + + 0 + 65535 + + + + + + + CALIBR + CALIBR + calibration register + 0x18 + 0x20 + read-write + 0x00000000 + + + DCS + Digital calibration sign + 7 + 1 + + + DC + Digital calibration + 0 + 5 + + + + + 2 + 0x4 + A,B + ALRM%sR + ALRMAR + Alarm register + 0x1C + 0x20 + read-write + 0x00000000 + + + MSK4 + Alarm date mask + 31 + 1 + + + + WDSEL + Week day selection + 30 + 1 + + WDSEL + read-write + + DateUnits + DU[3:0] represents the date units + 0 + + + WeekDay + DU[3:0] represents the week day. DT[1:0] is don’t care. + 1 + + + + + DT + Date tens in BCD format + 28 + 2 + + + 0 + 3 + + + + + DU + Date units or day in BCD format + 24 + 4 + + + 0 + 15 + + + + + MSK3 + Alarm hours mask + 23 + 1 + + + + PM + AM/PM notation + 22 + 1 + + PM + read-write + + AM + AM or 24-hour format + 0 + + + PM + PM + 1 + + + + + HT + Hour tens in BCD format + 20 + 2 + + + 0 + 3 + + + + + HU + Hour units in BCD format + 16 + 4 + + + 0 + 15 + + + + + MSK2 + Alarm minutes mask + 15 + 1 + + + + MNT + Minute tens in BCD format + 12 + 3 + + + 0 + 7 + + + + + MNU + Minute units in BCD format + 8 + 4 + + + 0 + 15 + + + + + MSK1 + Alarm seconds mask + 7 + 1 + + MSK1 + read-write + + Mask + Alarm set if the date/day match + 0 + + + NotMask + Date/day don’t care in Alarm comparison + 1 + + + + + ST + Second tens in BCD format + 4 + 3 + + + 0 + 7 + + + + + SU + Second units in BCD format + 0 + 4 + + + 0 + 15 + + + + + + + WPR + WPR + write protection register + 0x24 + 0x20 + write-only + 0x00000000 + + + KEY + Write protection key + 0 + 8 + + + 0 + 255 + + + + + + + SSR + SSR + sub second register + 0x28 + 0x20 + read-only + 0x00000000 + + + SS + Sub second value + 0 + 16 + + + 0 + 65535 + + + + + + + SHIFTR + SHIFTR + shift control register + 0x2C + 0x20 + write-only + 0x00000000 + + + ADD1S + Add one second + 31 + 1 + + ADD1SW + write + + Add1 + Add one second to the clock/calendar + 1 + + + + + SUBFS + Subtract a fraction of a + second + 0 + 15 + + + 0 + 32767 + + + + + + + TSTR + TSTR + time stamp time register + 0x30 + + + TSDR + TSDR + time stamp date register + 0x34 + + + TSSSR + TSSSR + timestamp sub second register + 0x38 + + + CALR + CALR + calibration register + 0x3C + 0x20 + read-write + 0x00000000 + + + CALP + Increase frequency of RTC by 488.5 + ppm + 15 + 1 + + CALP + read-write + + NoChange + No RTCCLK pulses are added + 0 + + + IncreaseFreq + One RTCCLK pulse is effectively inserted every 2^11 pulses (frequency increased by 488.5 ppm) + 1 + + + + + CALW8 + Use an 8-second calibration cycle + period + 14 + 1 + + CALW8 + read-write + + Eight_Second + When CALW8 is set to ‘1’, the 8-second calibration cycle period is selected + 1 + + + + + CALW16 + Use a 16-second calibration cycle + period + 13 + 1 + + CALW16 + read-write + + Sixteen_Second + When CALW16 is set to ‘1’, the 16-second calibration cycle period is selected.This bit must not be set to ‘1’ if CALW8=1 + 1 + + + + + CALM + Calibration minus + 0 + 9 + + + 0 + 511 + + + + + + + TAFCR + TAFCR + tamper and alternate function configuration + register + 0x40 + 0x20 + read-write + 0x00000000 + + + ALARMOUTTYPE + AFO_ALARM output type + 18 + 1 + + + TSINSEL + TIMESTAMP mapping + 17 + 1 + + + TAMP1INSEL + TAMPER1 mapping + 16 + 1 + + + TAMPPUDIS + TAMPER pull-up disable + 15 + 1 + + + TAMPPRCH + Tamper precharge duration + 13 + 2 + + + TAMPFLT + Tamper filter count + 11 + 2 + + + TAMPFREQ + Tamper sampling frequency + 8 + 3 + + + TAMPTS + Activate timestamp on tamper detection + event + 7 + 1 + + + TAMP2TRG + Active level for tamper 2 + 4 + 1 + + + TAMP2E + Tamper 2 detection enable + 3 + 1 + + + TAMPIE + Tamper interrupt enable + 2 + 1 + + + TAMP1TRG + Active level for tamper 1 + 1 + 1 + + + TAMP1E + Tamper 1 detection enable + 0 + 1 + + + + + 2 + 0x4 + A,B + ALRM%sSSR + ALRMASSR + Alarm sub-second register + 0x44 + 0x20 + read-write + 0x00000000 + + + MASKSS + Mask the most-significant bits starting + at this bit + 24 + 4 + + + 0 + 15 + + + + + SS + Sub seconds value + 0 + 15 + + + 0 + 32767 + + + + + + + 20 + 0x4 + 0-19 + BKP%sR + BKP0R + backup register + 0x50 + 0x20 + read-write + 0x00000000 + + + BKP + BKP + 0 + 32 + + + 0 + 4294967295 + + + + + + + + + SDIO + Secure digital input/output + interface + SDIO + 0x40012C00 + + 0x0 + 0x400 + registers + + + I2C3_EV + I2C3 event interrupt + 72 + + + I2C3_ER + I2C3 error interrupt + 73 + + + + POWER + POWER + power control register + 0x0 + 0x20 + read-write + 0x00000000 + + + PWRCTRL + PWRCTRL + 0 + 2 + + PWRCTRL + read-write + + PowerOff + Power off + 0 + + + PowerOn + Power on + 3 + + + + + + + CLKCR + CLKCR + SDI clock control register + 0x4 + 0x20 + read-write + 0x00000000 + + + HWFC_EN + HW Flow Control enable + 14 + 1 + + HWFC_EN + read-write + + Disabled + HW Flow Control is disabled + 0 + + + Enabled + HW Flow Control is enabled + 1 + + + + + NEGEDGE + SDIO_CK dephasing selection + bit + 13 + 1 + + NEGEDGE + read-write + + Rising + SDIO_CK generated on the rising edge + 0 + + + Falling + SDIO_CK generated on the falling edge + 1 + + + + + WIDBUS + Wide bus mode enable bit + 11 + 2 + + WIDBUS + read-write + + BusWidth1 + 1 lane wide bus + 0 + + + BusWidth4 + 4 lane wide bus + 1 + + + BusWidth8 + 8 lane wide bus + 2 + + + + + BYPASS + Clock divider bypass enable + bit + 10 + 1 + + BYPASS + read-write + + Disabled + SDIOCLK is divided according to the CLKDIV value before driving the SDIO_CK output signal. + 0 + + + Enabled + SDIOCLK directly drives the SDIO_CK output signal + 1 + + + + + PWRSAV + Power saving configuration + bit + 9 + 1 + + PWRSAV + read-write + + Enabled + SDIO_CK clock is always enabled + 0 + + + Disabled + SDIO_CK is only enabled when the bus is active + 1 + + + + + CLKEN + Clock enable bit + 8 + 1 + + CLKEN + read-write + + Disabled + Disable clock + 0 + + + Enabled + Enable clock + 1 + + + + + CLKDIV + Clock divide factor + 0 + 8 + + + 0 + 255 + + + + + + + ARG + ARG + argument register + 0x8 + 0x20 + read-write + 0x00000000 + + + CMDARG + Command argument + 0 + 32 + + + 0 + 4294967295 + + + + + + + CMD + CMD + command register + 0xC + 0x20 + read-write + 0x00000000 + + + CE_ATACMD + CE-ATA command + 14 + 1 + + CE_ATACMD + read-write + + Disabled + CE-ATA command disabled + 0 + + + Enabled + CE-ATA command enabled + 1 + + + + + nIEN + not Interrupt Enable + 13 + 1 + + nIEN + read-write + + Disabled + Interrupts to the CE-ATA not disabled + 0 + + + Enabled + Interrupt to the CE-ATA are disabled + 1 + + + + + ENCMDcompl + Enable CMD completion + 12 + 1 + + ENCMDcompl + read-write + + Disabled + Command complete signal disabled + 0 + + + Enabled + Command complete signal enabled + 1 + + + + + SDIOSuspend + SD I/O suspend command + 11 + 1 + + SDIOSuspend + read-write + + Disabled + Next command is not a SDIO suspend command + 0 + + + Enabled + Next command send is a SDIO suspend command + 1 + + + + + CPSMEN + Command path state machine (CPSM) Enable + bit + 10 + 1 + + CPSMEN + read-write + + Disabled + Command path state machine disabled + 0 + + + Enabled + Command path state machine enabled + 1 + + + + + WAITPEND + CPSM Waits for ends of data transfer + (CmdPend internal signal). + 9 + 1 + + WAITPEND + read-write + + Disabled + Don't wait for data end + 0 + + + Enabled + Wait for end of data transfer signal before sending command + 1 + + + + + WAITINT + CPSM waits for interrupt + request + 8 + 1 + + WAITINT + read-write + + Disabled + Don't wait for interrupt request + 0 + + + Enabled + Wait for interrupt request + 1 + + + + + WAITRESP + Wait for response bits + 6 + 2 + + WAITRESP + read-write + + NoResponse + No response + 0 + + + ShortResponse + Short response + 1 + + + NoResponse2 + No reponse + 2 + + + LongResponse + Long reponse + 3 + + + + + CMDINDEX + Command index + 0 + 6 + + + 0 + 63 + + + + + + + RESPCMD + RESPCMD + command response register + 0x10 + 0x20 + read-only + 0x00000000 + + + RESPCMD + Response command index + 0 + 6 + + + 0 + 63 + + + + + + + RESP1 + RESP1 + response 1..4 register + 0x14 + 0x20 + read-only + 0x00000000 + + + CARDSTATUS1 + Card Status + 0 + 32 + + + 0 + 4294967295 + + + + + + + RESP2 + RESP2 + response 1..4 register + 0x18 + 0x20 + read-only + 0x00000000 + + + CARDSTATUS2 + Card Status + 0 + 32 + + + 0 + 4294967295 + + + + + + + RESP3 + RESP3 + response 1..4 register + 0x1C + 0x20 + read-only + 0x00000000 + + + CARDSTATUS3 + Card Status + 0 + 32 + + + 0 + 4294967295 + + + + + + + RESP4 + RESP4 + response 1..4 register + 0x20 + 0x20 + read-only + 0x00000000 + + + CARDSTATUS4 + Card Status + 0 + 32 + + + 0 + 4294967295 + + + + + + + DTIMER + DTIMER + data timer register + 0x24 + 0x20 + read-write + 0x00000000 + + + DATATIME + Data timeout period + 0 + 32 + + + 0 + 4294967295 + + + + + + + DLEN + DLEN + data length register + 0x28 + 0x20 + read-write + 0x00000000 + + + DATALENGTH + Data length value + 0 + 25 + + + 0 + 33554431 + + + + + + + DCTRL + DCTRL + data control register + 0x2C + 0x20 + read-write + 0x00000000 + + + SDIOEN + SD I/O enable functions + 11 + 1 + + SDIOEN + read-write + + Disabled + SDIO operations disabled + 0 + + + Enabled + SDIO operations enabled + 1 + + + + + RWMOD + Read wait mode + 10 + 1 + + RWMOD + read-write + + D2 + Read wait control stopping using SDIO_D2 + 0 + + + Ck + Read wait control using SDIO_CK + 1 + + + + + RWSTOP + Read wait stop + 9 + 1 + + RWSTOP + read-write + + Disabled + Read wait in progress if RWSTART is enabled + 0 + + + Enabled + Enable for read wait stop if RWSTART is enabled + 1 + + + + + RWSTART + Read wait start + 8 + 1 + + RWSTART + read-write + + Disabled + Don't start read wait operation + 0 + + + Enabled + Read wait operation starts + 1 + + + + + DBLOCKSIZE + Data block size + 4 + 4 + + + 0 + 15 + + + + + DMAEN + DMA enable bit + 3 + 1 + + DMAEN + read-write + + Disabled + Dma disabled + 0 + + + Enabled + Dma enabled + 1 + + + + + DTMODE + Data transfer mode selection 1: Stream + or SDIO multibyte data transfer. + 2 + 1 + + DTMODE + read-write + + BlockMode + Bloack data transfer + 0 + + + StreamMode + Stream or SDIO multibyte data transfer + 1 + + + + + DTDIR + Data transfer direction + selection + 1 + 1 + + DTDIR + read-write + + ControllerToCard + From controller to card + 0 + + + CardToController + From card to controller + 1 + + + + + DTEN + DTEN + 0 + 1 + + DTEN + read-write + + Disabled + Disabled + 0 + + + Enabled + Start transfer + 1 + + + + + + + DCOUNT + DCOUNT + data counter register + 0x30 + 0x20 + read-only + 0x00000000 + + + DATACOUNT + Data count value + 0 + 25 + + + 0 + 33554431 + + + + + + + STA + STA + status register + 0x34 + 0x20 + read-only + 0x00000000 + + + CEATAEND + CE-ATA command completion signal + received for CMD61 + 23 + 1 + + CEATAEND + read + + NotReceived + Completion signal not received + 0 + + + Received + CE-ATA command completion signal received for CMD61 + 1 + + + + + SDIOIT + SDIO interrupt received + 22 + 1 + + SDIOIT + read + + NotReceived + SDIO interrupt not receieved + 0 + + + Received + SDIO interrupt received + 1 + + + + + RXDAVL + Data available in receive + FIFO + 21 + 1 + + RXDAVL + read + + NotAvailable + Data not available in receive FIFO + 0 + + + Available + Data available in receive FIFO + 1 + + + + + TXDAVL + Data available in transmit + FIFO + 20 + 1 + + TXDAVL + read + + NotAvailable + Data not available in transmit FIFO + 0 + + + Available + Data available in transmit FIFO + 1 + + + + + RXFIFOE + Receive FIFO empty + 19 + 1 + + RXFIFOE + read + + NotEmpty + Receive FIFO not empty + 0 + + + Empty + Receive FIFO empty + 1 + + + + + TXFIFOE + Transmit FIFO empty + 18 + 1 + + TXFIFOE + read + + NotEmpty + Transmit FIFO not empty + 0 + + + Empty + Transmit FIFO empty. When HW Flow Control is enabled, TXFIFOE signals becomes activated when the FIFO contains 2 words. + 1 + + + + + RXFIFOF + Receive FIFO full + 17 + 1 + + RXFIFOF + read + + NotFull + Transmit FIFO not full + 0 + + + Full + Receive FIFO full. When HW Flow Control is enabled, RXFIFOF signals becomes activated 2 words before the FIFO is full. + 1 + + + + + TXFIFOF + Transmit FIFO full + 16 + 1 + + TXFIFOF + read + + NotFull + Transmit FIFO not full + 0 + + + Full + Transmit FIFO full + 1 + + + + + RXFIFOHF + Receive FIFO half full: there are at + least 8 words in the FIFO + 15 + 1 + + RXFIFOHF + read + + NotHalfFull + Receive FIFO not half full + 0 + + + HalfFull + Receive FIFO half full. At least 8 words in the FIFO + 1 + + + + + TXFIFOHE + Transmit FIFO half empty: at least 8 + words can be written into the FIFO + 14 + 1 + + TXFIFOHE + read + + NotHalfEmpty + Transmit FIFO not half empty + 0 + + + HalfEmpty + Transmit FIFO half empty. At least 8 words can be written into the FIFO + 1 + + + + + RXACT + Data receive in progress + 13 + 1 + + RXACT + read + + NotInProgress + Data receive not in progress + 0 + + + InProgress + Data receive in progress + 1 + + + + + TXACT + Data transmit in progress + 12 + 1 + + TXACT + read + + NotInProgress + Data transmit is not in progress + 0 + + + InProgress + Data transmit in progress + 1 + + + + + CMDACT + Command transfer in + progress + 11 + 1 + + CMDACT + read + + NotInProgress + Command transfer not in progress + 0 + + + InProgress + Command tranfer in progress + 1 + + + + + DBCKEND + Data block sent/received (CRC check + passed) + 10 + 1 + + DBCKEND + read + + NotTransferred + Data block not sent/received (CRC check failed) + 0 + + + Transferred + Data block sent/received (CRC check passed) + 1 + + + + + STBITERR + Start bit not detected on all data + signals in wide bus mode + 9 + 1 + + STBITERR + read + + Detected + No start bit detected error + 0 + + + NotDetected + Start bit not detected error + 1 + + + + + DATAEND + Data end (data counter, SDIDCOUNT, is + zero) + 8 + 1 + + DATAEND + read + + NotDone + Not done + 0 + + + Done + Data end (DCOUNT, is zero) + 1 + + + + + CMDSENT + Command sent (no response + required) + 7 + 1 + + CMDSENT + read + + NotSent + Command not sent + 0 + + + Sent + Command sent (no response required) + 1 + + + + + CMDREND + Command response received (CRC check + passed) + 6 + 1 + + CMDREND + read + + NotDone + Command not done + 0 + + + Done + Command response received (CRC check passed) + 1 + + + + + RXOVERR + Received FIFO overrun + error + 5 + 1 + + RXOVERR + read + + NoOverrun + No FIFO overrun error + 0 + + + Overrun + Receive FIFO overrun error + 1 + + + + + TXUNDERR + Transmit FIFO underrun + error + 4 + 1 + + TXUNDERR + read + + NoUnderrun + No transmit FIFO underrun error + 0 + + + Underrun + Transmit FIFO underrun error + 1 + + + + + DTIMEOUT + Data timeout + 3 + 1 + + DTIMEOUT + read + + NoTimeout + No data timeout + 0 + + + Timeout + Data timeout + 1 + + + + + CTIMEOUT + Command response timeout + 2 + 1 + + CTIMEOUT + read + + NoTimeout + No Command timeout + 0 + + + Timeout + Command timeout + 1 + + + + + DCRCFAIL + Data block sent/received (CRC check + failed) + 1 + 1 + + DCRCFAIL + read + + NotFailed + No Data block sent/received crc check fail + 0 + + + Failed + Data block sent/received crc failed + 1 + + + + + CCRCFAIL + Command response received (CRC check + failed) + 0 + 1 + + CCRCFAIL + read + + NotFailed + Command response received, crc check passed + 0 + + + Failed + Command response received, crc check failed + 1 + + + + + + + ICR + ICR + interrupt clear register + 0x38 + 0x20 + read-write + 0x00000000 + + + CEATAENDC + CEATAEND flag clear bit + 23 + 1 + + + + SDIOITC + SDIOIT flag clear bit + 22 + 1 + + + + DBCKENDC + DBCKEND flag clear bit + 10 + 1 + + + + STBITERRC + STBITERR flag clear bit + 9 + 1 + + + + DATAENDC + DATAEND flag clear bit + 8 + 1 + + + + CMDSENTC + CMDSENT flag clear bit + 7 + 1 + + + + CMDRENDC + CMDREND flag clear bit + 6 + 1 + + + + RXOVERRC + RXOVERR flag clear bit + 5 + 1 + + + + TXUNDERRC + TXUNDERR flag clear bit + 4 + 1 + + + + DTIMEOUTC + DTIMEOUT flag clear bit + 3 + 1 + + + + CTIMEOUTC + CTIMEOUT flag clear bit + 2 + 1 + + + + DCRCFAILC + DCRCFAIL flag clear bit + 1 + 1 + + + + CCRCFAILC + CCRCFAIL flag clear bit + 0 + 1 + + CCRCFAILCW + write + + Clear + Clear flag + 1 + + + + + + + MASK + MASK + mask register + 0x3C + 0x20 + read-write + 0x00000000 + + + CEATAENDIE + CE-ATA command completion signal + received interrupt enable + 23 + 1 + + + + SDIOITIE + SDIO mode interrupt received interrupt + enable + 22 + 1 + + + + RXDAVLIE + Data available in Rx FIFO interrupt + enable + 21 + 1 + + + + TXDAVLIE + Data available in Tx FIFO interrupt + enable + 20 + 1 + + + + RXFIFOEIE + Rx FIFO empty interrupt + enable + 19 + 1 + + + + TXFIFOEIE + Tx FIFO empty interrupt + enable + 18 + 1 + + + + RXFIFOFIE + Rx FIFO full interrupt + enable + 17 + 1 + + + + TXFIFOFIE + Tx FIFO full interrupt + enable + 16 + 1 + + + + RXFIFOHFIE + Rx FIFO half full interrupt + enable + 15 + 1 + + + + TXFIFOHEIE + Tx FIFO half empty interrupt + enable + 14 + 1 + + + + RXACTIE + Data receive acting interrupt + enable + 13 + 1 + + + + TXACTIE + Data transmit acting interrupt + enable + 12 + 1 + + + + CMDACTIE + Command acting interrupt + enable + 11 + 1 + + + + DBCKENDIE + Data block end interrupt + enable + 10 + 1 + + + + STBITERRIE + Start bit error interrupt + enable + 9 + 1 + + + + DATAENDIE + Data end interrupt enable + 8 + 1 + + + + CMDSENTIE + Command sent interrupt + enable + 7 + 1 + + + + CMDRENDIE + Command response received interrupt + enable + 6 + 1 + + + + RXOVERRIE + Rx FIFO overrun error interrupt + enable + 5 + 1 + + + + TXUNDERRIE + Tx FIFO underrun error interrupt + enable + 4 + 1 + + + + DTIMEOUTIE + Data timeout interrupt + enable + 3 + 1 + + + + CTIMEOUTIE + Command timeout interrupt + enable + 2 + 1 + + + + DCRCFAILIE + Data CRC fail interrupt + enable + 1 + 1 + + + + CCRCFAILIE + Command CRC fail interrupt + enable + 0 + 1 + + CCRCFAILIE + read-write + + Disabled + Interrupt disabled + 0 + + + Enabled + Interrupt enabled + 1 + + + + + + + FIFOCNT + FIFOCNT + FIFO counter register + 0x48 + 0x20 + read-only + 0x00000000 + + + FIFOCOUNT + Remaining number of words to be written + to or read from the FIFO. + 0 + 24 + + + 0 + 16777215 + + + + + + + FIFO + FIFO + data FIFO register + 0x80 + 0x20 + read-write + 0x00000000 + + + FIFOData + Receive and transmit FIFO + data + 0 + 32 + + + 0 + 4294967295 + + + + + + + + + SYSCFG + System configuration controller + SYSCFG + 0x40013800 + + 0x0 + 0x400 + registers + + + + MEMRM + MEMRM + memory remap register + 0x0 + 0x20 + read-write + 0x00000000 + + + MEM_MODE + MEM_MODE + 0 + 2 + + + + + PMC + PMC + peripheral mode configuration + register + 0x4 + 0x20 + read-write + 0x00000000 + + + ADC1DC2 + ADC1DC2 + 16 + 1 + + + + + EXTICR1 + EXTICR1 + external interrupt configuration register + 1 + 0x8 + 0x20 + read-write + 0x00000000 + + + EXTI3 + EXTI x configuration (x = 0 to + 3) + 12 + 4 + + + EXTI2 + EXTI x configuration (x = 0 to + 3) + 8 + 4 + + + EXTI1 + EXTI x configuration (x = 0 to + 3) + 4 + 4 + + + EXTI0 + EXTI x configuration (x = 0 to + 3) + 0 + 4 + + + + + EXTICR2 + EXTICR2 + external interrupt configuration register + 2 + 0xC + 0x20 + read-write + 0x00000000 + + + EXTI7 + EXTI x configuration (x = 4 to + 7) + 12 + 4 + + + EXTI6 + EXTI x configuration (x = 4 to + 7) + 8 + 4 + + + EXTI5 + EXTI x configuration (x = 4 to + 7) + 4 + 4 + + + EXTI4 + EXTI x configuration (x = 4 to + 7) + 0 + 4 + + + + + EXTICR3 + EXTICR3 + external interrupt configuration register + 3 + 0x10 + 0x20 + read-write + 0x00000000 + + + EXTI11 + EXTI x configuration (x = 8 to + 11) + 12 + 4 + + + EXTI10 + EXTI10 + 8 + 4 + + + EXTI9 + EXTI x configuration (x = 8 to + 11) + 4 + 4 + + + EXTI8 + EXTI x configuration (x = 8 to + 11) + 0 + 4 + + + + + EXTICR4 + EXTICR4 + external interrupt configuration register + 4 + 0x14 + 0x20 + read-write + 0x00000000 + + + EXTI15 + EXTI x configuration (x = 12 to + 15) + 12 + 4 + + + EXTI14 + EXTI x configuration (x = 12 to + 15) + 8 + 4 + + + EXTI13 + EXTI x configuration (x = 12 to + 15) + 4 + 4 + + + EXTI12 + EXTI x configuration (x = 12 to + 15) + 0 + 4 + + + + + CMPCR + CMPCR + Compensation cell control + register + 0x20 + 0x20 + read-only + 0x00000000 + + + READY + READY + 8 + 1 + + + CMP_PD + Compensation cell + power-down + 0 + 1 + + + + + + + TIM1 + Advanced-timers + TIM + 0x40010000 + + 0x0 + 0x400 + registers + + + + CR1 + CR1 + control register 1 + 0x0 + 0x20 + read-write + 0x00000000 + + + CKD + Clock division + 8 + 2 + + CKD + read-write + + Div1 + t_DTS = t_CK_INT + 0 + + + Div2 + t_DTS = 2 × t_CK_INT + 1 + + + Div4 + t_DTS = 4 × t_CK_INT + 2 + + + + + ARPE + Auto-reload preload enable + 7 + 1 + + ARPE + read-write + + Disabled + TIMx_APRR register is not buffered + 0 + + + Enabled + TIMx_APRR register is buffered + 1 + + + + + CMS + Center-aligned mode + selection + 5 + 2 + + CMS + read-write + + EdgeAligned + The counter counts up or down depending on the direction bit + 0 + + + CenterAligned1 + The counter counts up and down alternatively. Output compare interrupt flags are set only when the counter is counting down. + 1 + + + CenterAligned2 + The counter counts up and down alternatively. Output compare interrupt flags are set only when the counter is counting up. + 2 + + + CenterAligned3 + The counter counts up and down alternatively. Output compare interrupt flags are set both when the counter is counting up or down. + 3 + + + + + DIR + Direction + 4 + 1 + + DIR + read-write + + Up + Counter used as upcounter + 0 + + + Down + Counter used as downcounter + 1 + + + + + OPM + One-pulse mode + 3 + 1 + + OPM + read-write + + Disabled + Counter is not stopped at update event + 0 + + + Enabled + Counter stops counting at the next update event (clearing the CEN bit) + 1 + + + + + URS + Update request source + 2 + 1 + + URS + read-write + + AnyEvent + Any of counter overflow/underflow, setting UG, or update through slave mode, generates an update interrupt or DMA request + 0 + + + CounterOnly + Only counter overflow/underflow generates an update interrupt or DMA request + 1 + + + + + UDIS + Update disable + 1 + 1 + + UDIS + read-write + + Enabled + Update event enabled + 0 + + + Disabled + Update event disabled + 1 + + + + + CEN + Counter enable + 0 + 1 + + CEN + read-write + + Disabled + Counter disabled + 0 + + + Enabled + Counter enabled + 1 + + + + + + + CR2 + CR2 + control register 2 + 0x4 + 0x20 + read-write + 0x00000000 + + + OIS4 + Output Idle state 4 + 14 + 1 + + + + OIS3N + Output Idle state 3 + 13 + 1 + + + + OIS3 + Output Idle state 3 + 12 + 1 + + + + OIS2N + Output Idle state 2 + 11 + 1 + + + + OIS2 + Output Idle state 2 + 10 + 1 + + + + OIS1N + Output Idle state 1 + 9 + 1 + + OIS1N + read-write + + Reset + OCxN=0 after a dead-time when MOE=0 + 0 + + + Set + OCxN=1 after a dead-time when MOE=0 + 1 + + + + + OIS1 + Output Idle state 1 + 8 + 1 + + OIS1 + read-write + + Reset + OCx=0 (after a dead-time if OCx(N) is implemented) when MOE=0 + 0 + + + Set + OCx=1 (after a dead-time if OCx(N) is implemented) when MOE=0 + 1 + + + + + TI1S + TI1 selection + 7 + 1 + + TI1S + read-write + + Normal + The TIMx_CH1 pin is connected to TI1 input + 0 + + + XOR + The TIMx_CH1, CH2, CH3 pins are connected to TI1 input + 1 + + + + + MMS + Master mode selection + 4 + 3 + + MMS + read-write + + Reset + The UG bit from the TIMx_EGR register is used as trigger output + 0 + + + Enable + The counter enable signal, CNT_EN, is used as trigger output + 1 + + + Update + The update event is selected as trigger output + 2 + + + ComparePulse + The trigger output send a positive pulse when the CC1IF flag it to be set, as soon as a capture or a compare match occurred + 3 + + + CompareOC1 + OC1REF signal is used as trigger output + 4 + + + CompareOC2 + OC2REF signal is used as trigger output + 5 + + + CompareOC3 + OC3REF signal is used as trigger output + 6 + + + CompareOC4 + OC4REF signal is used as trigger output + 7 + + + + + CCDS + Capture/compare DMA + selection + 3 + 1 + + CCDS + read-write + + OnCompare + CCx DMA request sent when CCx event occurs + 0 + + + OnUpdate + CCx DMA request sent when update event occurs + 1 + + + + + CCUS + Capture/compare control update + selection + 2 + 1 + + + CCPC + Capture/compare preloaded + control + 0 + 1 + + + + + SMCR + SMCR + slave mode control register + 0x8 + 0x20 + read-write + 0x00000000 + + + ETP + External trigger polarity + 15 + 1 + + ETP + read-write + + NotInverted + ETR is noninverted, active at high level or rising edge + 0 + + + Inverted + ETR is inverted, active at low level or falling edge + 1 + + + + + ECE + External clock enable + 14 + 1 + + ECE + read-write + + Disabled + External clock mode 2 disabled + 0 + + + Enabled + External clock mode 2 enabled. The counter is clocked by any active edge on the ETRF signal. + 1 + + + + + ETPS + External trigger prescaler + 12 + 2 + + ETPS + read-write + + Div1 + Prescaler OFF + 0 + + + Div2 + ETRP frequency divided by 2 + 1 + + + Div4 + ETRP frequency divided by 4 + 2 + + + Div8 + ETRP frequency divided by 8 + 3 + + + + + ETF + External trigger filter + 8 + 4 + + ETF + read-write + + NoFilter + No filter, sampling is done at fDTS + 0 + + + FCK_INT_N2 + fSAMPLING=fCK_INT, N=2 + 1 + + + FCK_INT_N4 + fSAMPLING=fCK_INT, N=4 + 2 + + + FCK_INT_N8 + fSAMPLING=fCK_INT, N=8 + 3 + + + FDTS_Div2_N6 + fSAMPLING=fDTS/2, N=6 + 4 + + + FDTS_Div2_N8 + fSAMPLING=fDTS/2, N=8 + 5 + + + FDTS_Div4_N6 + fSAMPLING=fDTS/4, N=6 + 6 + + + FDTS_Div4_N8 + fSAMPLING=fDTS/4, N=8 + 7 + + + FDTS_Div8_N6 + fSAMPLING=fDTS/8, N=6 + 8 + + + FDTS_Div8_N8 + fSAMPLING=fDTS/8, N=8 + 9 + + + FDTS_Div16_N5 + fSAMPLING=fDTS/16, N=5 + 10 + + + FDTS_Div16_N6 + fSAMPLING=fDTS/16, N=6 + 11 + + + FDTS_Div16_N8 + fSAMPLING=fDTS/16, N=8 + 12 + + + FDTS_Div32_N5 + fSAMPLING=fDTS/32, N=5 + 13 + + + FDTS_Div32_N6 + fSAMPLING=fDTS/32, N=6 + 14 + + + FDTS_Div32_N8 + fSAMPLING=fDTS/32, N=8 + 15 + + + + + MSM + Master/Slave mode + 7 + 1 + + MSM + read-write + + NoSync + No action + 0 + + + Sync + The effect of an event on the trigger input (TRGI) is delayed to allow a perfect synchronization between the current timer and its slaves (through TRGO). It is useful if we want to synchronize several timers on a single external event. + 1 + + + + + TS + Trigger selection + 4 + 3 + + TS + read-write + + ITR0 + Internal Trigger 0 (ITR0) + 0 + + + ITR1 + Internal Trigger 1 (ITR1) + 1 + + + ITR2 + Internal Trigger 2 (ITR2) + 2 + + + TI1F_ED + TI1 Edge Detector (TI1F_ED) + 4 + + + TI1FP1 + Filtered Timer Input 1 (TI1FP1) + 5 + + + TI2FP2 + Filtered Timer Input 2 (TI2FP2) + 6 + + + ETRF + External Trigger input (ETRF) + 7 + + + + + SMS + Slave mode selection + 0 + 3 + + SMS + read-write + + Disabled + Slave mode disabled - if CEN = ‘1 then the prescaler is clocked directly by the internal clock. + 0 + + + Encoder_Mode_1 + Encoder mode 1 - Counter counts up/down on TI2FP1 edge depending on TI1FP2 level. + 1 + + + Encoder_Mode_2 + Encoder mode 2 - Counter counts up/down on TI1FP2 edge depending on TI2FP1 level. + 2 + + + Encoder_Mode_3 + Encoder mode 3 - Counter counts up/down on both TI1FP1 and TI2FP2 edges depending on the level of the other input. + 3 + + + Reset_Mode + Reset Mode - Rising edge of the selected trigger input (TRGI) reinitializes the counter and generates an update of the registers. + 4 + + + Gated_Mode + Gated Mode - The counter clock is enabled when the trigger input (TRGI) is high. The counter stops (but is not reset) as soon as the trigger becomes low. Both start and stop of the counter are controlled. + 5 + + + Trigger_Mode + Trigger Mode - The counter starts at a rising edge of the trigger TRGI (but it is not reset). Only the start of the counter is controlled. + 6 + + + Ext_Clock_Mode + External Clock Mode 1 - Rising edges of the selected trigger (TRGI) clock the counter. + 7 + + + + + + + DIER + DIER + DMA/Interrupt enable register + 0xC + 0x20 + read-write + 0x00000000 + + + TDE + Trigger DMA request enable + 14 + 1 + + TDE + read-write + + Disabled + Trigger DMA request disabled + 0 + + + Enabled + Trigger DMA request enabled + 1 + + + + + COMDE + COM DMA request enable + 13 + 1 + + + CC4DE + Capture/Compare 4 DMA request + enable + 12 + 1 + + + + CC3DE + Capture/Compare 3 DMA request + enable + 11 + 1 + + + + CC2DE + Capture/Compare 2 DMA request + enable + 10 + 1 + + + + CC1DE + Capture/Compare 1 DMA request + enable + 9 + 1 + + CC1DE + read-write + + Disabled + CCx DMA request disabled + 0 + + + Enabled + CCx DMA request enabled + 1 + + + + + UDE + Update DMA request enable + 8 + 1 + + UDE + read-write + + Disabled + Update DMA request disabled + 0 + + + Enabled + Update DMA request enabled + 1 + + + + + BIE + Break interrupt enable + 7 + 1 + + + TIE + Trigger interrupt enable + 6 + 1 + + TIE + read-write + + Disabled + Trigger interrupt disabled + 0 + + + Enabled + Trigger interrupt enabled + 1 + + + + + COMIE + COM interrupt enable + 5 + 1 + + + CC4IE + Capture/Compare 4 interrupt + enable + 4 + 1 + + + + CC3IE + Capture/Compare 3 interrupt + enable + 3 + 1 + + + + CC2IE + Capture/Compare 2 interrupt + enable + 2 + 1 + + + + CC1IE + Capture/Compare 1 interrupt + enable + 1 + 1 + + CC1IE + read-write + + Disabled + CCx interrupt disabled + 0 + + + Enabled + CCx interrupt enabled + 1 + + + + + UIE + Update interrupt enable + 0 + 1 + + UIE + read-write + + Disabled + Update interrupt disabled + 0 + + + Enabled + Update interrupt enabled + 1 + + + + + + + SR + SR + status register + 0x10 + 0x20 + read-write + 0x00000000 + + + CC4OF + Capture/Compare 4 overcapture + flag + 12 + 1 + zeroToClear + + read + + + write + + + + CC3OF + Capture/Compare 3 overcapture + flag + 11 + 1 + zeroToClear + + read + + + write + + + + CC2OF + Capture/compare 2 overcapture + flag + 10 + 1 + zeroToClear + + read + + + write + + + + CC1OF + Capture/Compare 1 overcapture + flag + 9 + 1 + zeroToClear + + CC1OFR + read + + Overcapture + The counter value has been captured in TIMx_CCRx register while CCxIF flag was already set + 1 + + + + CC1OFW + write + + Clear + Clear flag + 0 + + + + + BIF + Break interrupt flag + 7 + 1 + + + TIF + Trigger interrupt flag + 6 + 1 + zeroToClear + + TIFR + read + + NoTrigger + No trigger event occurred + 0 + + + Trigger + Trigger interrupt pending + 1 + + + + TIFW + write + + Clear + Clear flag + 0 + + + + + COMIF + COM interrupt flag + 5 + 1 + + + CC4IF + Capture/Compare 4 interrupt + flag + 4 + 1 + zeroToClear + + read + + + write + + + + CC3IF + Capture/Compare 3 interrupt + flag + 3 + 1 + zeroToClear + + read + + + write + + + + CC2IF + Capture/Compare 2 interrupt + flag + 2 + 1 + zeroToClear + + read + + + write + + + + CC1IF + Capture/compare 1 interrupt + flag + 1 + 1 + zeroToClear + + CC1IFR + read + + Match + If CC1 is an output: The content of the counter TIMx_CNT matches the content of the TIMx_CCR1 register. If CC1 is an input: The counter value has been captured in TIMx_CCR1 register. + 1 + + + + CC1IFW + write + + Clear + Clear flag + 0 + + + + + UIF + Update interrupt flag + 0 + 1 + zeroToClear + + UIFR + read + + NoUpdateOccurred + No update occurred + 0 + + + UpdatePending + Update interrupt pending + 1 + + + + UIFW + write + + Clear + Clear flag + 0 + + + + + + + EGR + EGR + event generation register + 0x14 + 0x20 + write-only + 0x00000000 + + + BG + Break generation + 7 + 1 + + + TG + Trigger generation + 6 + 1 + + TGW + write + + Trigger + The TIF flag is set in TIMx_SR register. Related interrupt or DMA transfer can occur if enabled. + 1 + + + + + COMG + Capture/Compare control update + generation + 5 + 1 + + + CC4G + Capture/compare 4 + generation + 4 + 1 + + + + CC3G + Capture/compare 3 + generation + 3 + 1 + + + + CC2G + Capture/compare 2 + generation + 2 + 1 + + + + CC1G + Capture/compare 1 + generation + 1 + 1 + + CC1GW + write + + Trigger + If CC1 is an output: CC1IF flag is set, Corresponding interrupt or DMA request is sent if enabled. If CC1 is an input: The current value of the counter is captured in TIMx_CCR1 register. + 1 + + + + + UG + Update generation + 0 + 1 + + UG + write + + Update + Re-initializes the timer counter and generates an update of the registers. + 1 + + + + + + + CCMR1_Output + CCMR1_Output + capture/compare mode register 1 (output + mode) + 0x18 + 0x20 + read-write + 0x00000000 + + + OC2CE + Output Compare 2 clear + enable + 15 + 1 + + + OC2M + Output Compare 2 mode + 12 + 3 + + + + OC2PE + Output Compare 2 preload + enable + 11 + 1 + + OC2PE + read-write + + Disabled + Preload register on CCR2 disabled. New values written to CCR2 are taken into account immediately + 0 + + + Enabled + Preload register on CCR2 enabled. Preload value is loaded into active register on each update event + 1 + + + + + OC2FE + Output Compare 2 fast + enable + 10 + 1 + + + CC2S + Capture/Compare 2 + selection + 8 + 2 + + CC2S + read-write + + Output + CC2 channel is configured as output + 0 + + + + + OC1CE + Output Compare 1 clear + enable + 7 + 1 + + + OC1M + Output Compare 1 mode + 4 + 3 + + OC1M + read-write + + Frozen + The comparison between the output compare register TIMx_CCRy and the counter TIMx_CNT has no effect on the outputs + 0 + + + ActiveOnMatch + Set channel to active level on match. OCyREF signal is forced high when the counter matches the capture/compare register + 1 + + + InactiveOnMatch + Set channel to inactive level on match. OCyREF signal is forced low when the counter matches the capture/compare register + 2 + + + Toggle + OCyREF toggles when TIMx_CNT=TIMx_CCRy + 3 + + + ForceInactive + OCyREF is forced low + 4 + + + ForceActive + OCyREF is forced high + 5 + + + PwmMode1 + In upcounting, channel is active as long as TIMx_CNT<TIMx_CCRy else inactive. In downcounting, channel is inactive as long as TIMx_CNT>TIMx_CCRy else active + 6 + + + PwmMode2 + Inversely to PwmMode1 + 7 + + + + + OC1PE + Output Compare 1 preload + enable + 3 + 1 + + OC1PE + read-write + + Disabled + Preload register on CCR1 disabled. New values written to CCR1 are taken into account immediately + 0 + + + Enabled + Preload register on CCR1 enabled. Preload value is loaded into active register on each update event + 1 + + + + + OC1FE + Output Compare 1 fast + enable + 2 + 1 + + + CC1S + Capture/Compare 1 + selection + 0 + 2 + + CC1S + read-write + + Output + CC1 channel is configured as output + 0 + + + + + + + CCMR1_Input + CCMR1_Input + capture/compare mode register 1 (input + mode) + CCMR1_Output + 0x18 + 0x20 + read-write + 0x00000000 + + + IC2F + Input capture 2 filter + 12 + 4 + + + 0 + 15 + + + + + IC2PSC + Input capture 2 prescaler + 10 + 2 + + + CC2S + Capture/Compare 2 + selection + 8 + 2 + + CC2S + read-write + + TI2 + CC2 channel is configured as input, IC2 is mapped on TI2 + 1 + + + TI1 + CC2 channel is configured as input, IC2 is mapped on TI1 + 2 + + + TRC + CC2 channel is configured as input, IC2 is mapped on TRC + 3 + + + + + IC1F + Input capture 1 filter + 4 + 4 + + IC1F + read-write + + NoFilter + No filter, sampling is done at fDTS + 0 + + + FCK_INT_N2 + fSAMPLING=fCK_INT, N=2 + 1 + + + FCK_INT_N4 + fSAMPLING=fCK_INT, N=4 + 2 + + + FCK_INT_N8 + fSAMPLING=fCK_INT, N=8 + 3 + + + FDTS_Div2_N6 + fSAMPLING=fDTS/2, N=6 + 4 + + + FDTS_Div2_N8 + fSAMPLING=fDTS/2, N=8 + 5 + + + FDTS_Div4_N6 + fSAMPLING=fDTS/4, N=6 + 6 + + + FDTS_Div4_N8 + fSAMPLING=fDTS/4, N=8 + 7 + + + FDTS_Div8_N6 + fSAMPLING=fDTS/8, N=6 + 8 + + + FDTS_Div8_N8 + fSAMPLING=fDTS/8, N=8 + 9 + + + FDTS_Div16_N5 + fSAMPLING=fDTS/16, N=5 + 10 + + + FDTS_Div16_N6 + fSAMPLING=fDTS/16, N=6 + 11 + + + FDTS_Div16_N8 + fSAMPLING=fDTS/16, N=8 + 12 + + + FDTS_Div32_N5 + fSAMPLING=fDTS/32, N=5 + 13 + + + FDTS_Div32_N6 + fSAMPLING=fDTS/32, N=6 + 14 + + + FDTS_Div32_N8 + fSAMPLING=fDTS/32, N=8 + 15 + + + + + IC1PSC + Input capture 1 prescaler + 2 + 2 + + + CC1S + Capture/Compare 1 + selection + 0 + 2 + + CC1S + read-write + + TI1 + CC1 channel is configured as input, IC1 is mapped on TI1 + 1 + + + TI2 + CC1 channel is configured as input, IC1 is mapped on TI2 + 2 + + + TRC + CC1 channel is configured as input, IC1 is mapped on TRC + 3 + + + + + + + CCMR2_Output + CCMR2_Output + capture/compare mode register 2 (output + mode) + 0x1C + 0x20 + read-write + 0x00000000 + + + OC4CE + Output compare 4 clear + enable + 15 + 1 + + + OC4M + Output compare 4 mode + 12 + 3 + + + + OC4PE + Output compare 4 preload + enable + 11 + 1 + + OC4PE + read-write + + Disabled + Preload register on CCR4 disabled. New values written to CCR4 are taken into account immediately + 0 + + + Enabled + Preload register on CCR4 enabled. Preload value is loaded into active register on each update event + 1 + + + + + OC4FE + Output compare 4 fast + enable + 10 + 1 + + + CC4S + Capture/Compare 4 + selection + 8 + 2 + + CC4S + read-write + + Output + CC4 channel is configured as output + 0 + + + + + OC3CE + Output compare 3 clear + enable + 7 + 1 + + + OC3M + Output compare 3 mode + 4 + 3 + + OC3M + read-write + + Frozen + The comparison between the output compare register TIMx_CCRy and the counter TIMx_CNT has no effect on the outputs + 0 + + + ActiveOnMatch + Set channel to active level on match. OCyREF signal is forced high when the counter matches the capture/compare register + 1 + + + InactiveOnMatch + Set channel to inactive level on match. OCyREF signal is forced low when the counter matches the capture/compare register + 2 + + + Toggle + OCyREF toggles when TIMx_CNT=TIMx_CCRy + 3 + + + ForceInactive + OCyREF is forced low + 4 + + + ForceActive + OCyREF is forced high + 5 + + + PwmMode1 + In upcounting, channel is active as long as TIMx_CNT<TIMx_CCRy else inactive. In downcounting, channel is inactive as long as TIMx_CNT>TIMx_CCRy else active + 6 + + + PwmMode2 + Inversely to PwmMode1 + 7 + + + + + OC3PE + Output compare 3 preload + enable + 3 + 1 + + OC3PE + read-write + + Disabled + Preload register on CCR3 disabled. New values written to CCR3 are taken into account immediately + 0 + + + Enabled + Preload register on CCR3 enabled. Preload value is loaded into active register on each update event + 1 + + + + + OC3FE + Output compare 3 fast + enable + 2 + 1 + + + CC3S + Capture/Compare 3 + selection + 0 + 2 + + CC3S + read-write + + Output + CC3 channel is configured as output + 0 + + + + + + + CCMR2_Input + CCMR2_Input + capture/compare mode register 2 (input + mode) + CCMR2_Output + 0x1C + 0x20 + read-write + 0x00000000 + + + IC4F + Input capture 4 filter + 12 + 4 + + + 0 + 15 + + + + + IC4PSC + Input capture 4 prescaler + 10 + 2 + + + 0 + 3 + + + + + CC4S + Capture/Compare 4 + selection + 8 + 2 + + CC4S + read-write + + TI4 + CC4 channel is configured as input, IC4 is mapped on TI4 + 1 + + + TI3 + CC4 channel is configured as input, IC4 is mapped on TI3 + 2 + + + TRC + CC4 channel is configured as input, IC4 is mapped on TRC + 3 + + + + + IC3F + Input capture 3 filter + 4 + 4 + + + 0 + 15 + + + + + IC3PSC + Input capture 3 prescaler + 2 + 2 + + + 0 + 3 + + + + + CC3S + Capture/compare 3 + selection + 0 + 2 + + CC3S + read-write + + TI3 + CC3 channel is configured as input, IC3 is mapped on TI3 + 1 + + + TI4 + CC3 channel is configured as input, IC3 is mapped on TI4 + 2 + + + TRC + CC3 channel is configured as input, IC3 is mapped on TRC + 3 + + + + + + + CCER + CCER + capture/compare enable + register + 0x20 + 0x20 + read-write + 0x00000000 + + + CC4P + Capture/Compare 3 output + Polarity + 13 + 1 + + + CC4E + Capture/Compare 4 output + enable + 12 + 1 + + + CC3NP + Capture/Compare 3 output + Polarity + 11 + 1 + + + CC3NE + Capture/Compare 3 complementary output + enable + 10 + 1 + + + CC3P + Capture/Compare 3 output + Polarity + 9 + 1 + + + CC3E + Capture/Compare 3 output + enable + 8 + 1 + + + CC2NP + Capture/Compare 2 output + Polarity + 7 + 1 + + + CC2NE + Capture/Compare 2 complementary output + enable + 6 + 1 + + + CC2P + Capture/Compare 2 output + Polarity + 5 + 1 + + + CC2E + Capture/Compare 2 output + enable + 4 + 1 + + + CC1NP + Capture/Compare 1 output + Polarity + 3 + 1 + + + CC1NE + Capture/Compare 1 complementary output + enable + 2 + 1 + + + CC1P + Capture/Compare 1 output + Polarity + 1 + 1 + + + CC1E + Capture/Compare 1 output + enable + 0 + 1 + + + + + CNT + CNT + counter + 0x24 + 0x20 + read-write + 0x00000000 + + + CNT + counter value + 0 + 16 + + + 0 + 65535 + + + + + + + PSC + PSC + prescaler + 0x28 + 0x20 + read-write + 0x00000000 + + + PSC + Prescaler value + 0 + 16 + + + 0 + 65535 + + + + + + + ARR + ARR + auto-reload register + 0x2C + 0x20 + read-write + 0x00000000 + + + ARR + Auto-reload value + 0 + 16 + + + 0 + 65535 + + + + + + + 4 + 0x4 + 1-4 + CCR%s + CCR1 + capture/compare register + 0x34 + 0x20 + read-write + 0x00000000 + + + CCR + Capture/Compare value + 0 + 16 + + + 0 + 65535 + + + + + + + DCR + DCR + DMA control register + 0x48 + 0x20 + read-write + 0x00000000 + + + DBL + DMA burst length + 8 + 5 + + + 0 + 18 + + + + + DBA + DMA base address + 0 + 5 + + + 0 + 31 + + + + + + + DMAR + DMAR + DMA address for full transfer + 0x4C + 0x20 + read-write + 0x00000000 + + + DMAB + DMA register for burst + accesses + 0 + 16 + + + + + RCR + RCR + repetition counter register + 0x30 + 0x20 + read-write + 0x00000000 + + + REP + Repetition counter value + 0 + 8 + + + + + BDTR + BDTR + break and dead-time register + 0x44 + 0x20 + read-write + 0x00000000 + + + MOE + Main output enable + 15 + 1 + + MOE + read-write + + DisabledIdle + OC/OCN are disabled or forced idle depending on OSSI + 0 + + + Enabled + OC/OCN are enabled if CCxE/CCxNE are set + 1 + + + + + AOE + Automatic output enable + 14 + 1 + + AOE + read-write + + Manual + MOE can be set only by software + 0 + + + Automatic + MOE can be set by software or automatically at the next update event (if none of the break inputs BRK and BRK2 is active) + 1 + + + + + BKP + Break polarity + 13 + 1 + + BKP + read-write + + ActiveLow + Break input BRKx is active low + 0 + + + ActiveHigh + Break input BRKx is active high + 1 + + + + + BKE + Break enable + 12 + 1 + + BKE + read-write + + Disabled + Break function x disabled + 0 + + + Enabled + Break function x disabled + 1 + + + + + OSSR + Off-state selection for Run + mode + 11 + 1 + + OSSR + read-write + + Disabled + When inactive, OC/OCN outputs are disabled + 0 + + + IdleLevel + When inactive, OC/OCN outputs are enabled with their inactive level + 1 + + + + + OSSI + Off-state selection for Idle + mode + 10 + 1 + + OSSI + read-write + + Disabled + When inactive, OC/OCN outputs are disabled + 0 + + + IdleLevel + When inactive, OC/OCN outputs are forced to idle level + 1 + + + + + LOCK + Lock configuration + 8 + 2 + + LOCK + read-write + + Off + No bit is write protected + 0 + + + Level1 + Any bits except MOE, OSSR, OSSI and LOCK in TIMx_BDTR register, OISx and OISxN bits in TIMx_CR2 register can no longer be written + 1 + + + Level2 + LOCK Level 1 + CC Polarity bits (CCxP/CCxNP bits in TIMx_CCER register, as long as the related channel is configured in output through the CCxS bits) as well as OSSR and OSSI bits can no longer be written + 2 + + + Level3 + LOCK Level 2 + CC Control bits (OCxM and OCxPE bits in TIMx_CCMRx registers, as long as the related channel is configured in output through the CCxS bits) can no longer be written + 3 + + + + + DTG + Dead-time generator setup + 0 + 8 + + + 0 + 255 + + + + + + + + + TIM10 + General-purpose-timers + TIM + 0x40014400 + + 0x0 + 0x400 + registers + + + SPI1 + SPI1 global interrupt + 35 + + + + CR1 + CR1 + control register 1 + 0x0 + 0x20 + read-write + 0x00000000 + + + CKD + Clock division + 8 + 2 + + CKD + read-write + + Div1 + t_DTS = t_CK_INT + 0 + + + Div2 + t_DTS = 2 × t_CK_INT + 1 + + + Div4 + t_DTS = 4 × t_CK_INT + 2 + + + + + ARPE + Auto-reload preload enable + 7 + 1 + + ARPE + read-write + + Disabled + TIMx_APRR register is not buffered + 0 + + + Enabled + TIMx_APRR register is buffered + 1 + + + + + URS + Update request source + 2 + 1 + + URS + read-write + + AnyEvent + Any of counter overflow/underflow, setting UG, or update through slave mode, generates an update interrupt or DMA request + 0 + + + CounterOnly + Only counter overflow/underflow generates an update interrupt or DMA request + 1 + + + + + UDIS + Update disable + 1 + 1 + + UDIS + read-write + + Enabled + Update event enabled + 0 + + + Disabled + Update event disabled + 1 + + + + + CEN + Counter enable + 0 + 1 + + CEN + read-write + + Disabled + Counter disabled + 0 + + + Enabled + Counter enabled + 1 + + + + + OPM + One-pulse mode + 3 + 1 + + OPM + read-write + + Disabled + Counter is not stopped at update event + 0 + + + Enabled + Counter stops counting at the next update event (clearing the CEN bit) + 1 + + + + + + + DIER + DIER + DMA/Interrupt enable register + 0xC + 0x20 + read-write + 0x00000000 + + + CC1IE + Capture/Compare 1 interrupt + enable + 1 + 1 + + + UIE + Update interrupt enable + 0 + 1 + + UIE + read-write + + Disabled + Update interrupt disabled + 0 + + + Enabled + Update interrupt enabled + 1 + + + + + + + SR + SR + status register + 0x10 + 0x20 + read-write + 0x00000000 + + + CC1OF + Capture/Compare 1 overcapture + flag + 9 + 1 + + + CC1IF + Capture/compare 1 interrupt + flag + 1 + 1 + + + UIF + Update interrupt flag + 0 + 1 + zeroToClear + + UIFR + read + + NoUpdateOccurred + No update occurred + 0 + + + UpdatePending + Update interrupt pending + 1 + + + + UIFW + write + + Clear + Clear flag + 0 + + + + + + + EGR + EGR + event generation register + 0x14 + 0x20 + write-only + 0x00000000 + + + CC1G + Capture/compare 1 + generation + 1 + 1 + + + UG + Update generation + 0 + 1 + + UG + write + + Update + Re-initializes the timer counter and generates an update of the registers. + 1 + + + + + + + CCMR1_Output + CCMR1_Output + capture/compare mode register 1 (output + mode) + 0x18 + 0x20 + read-write + 0x00000000 + + + OC1M + Output Compare 1 mode + 4 + 3 + + OC1M + read-write + + Frozen + The comparison between the output compare register TIMx_CCRy and the counter TIMx_CNT has no effect on the outputs + 0 + + + ActiveOnMatch + Set channel to active level on match. OCyREF signal is forced high when the counter matches the capture/compare register + 1 + + + InactiveOnMatch + Set channel to inactive level on match. OCyREF signal is forced low when the counter matches the capture/compare register + 2 + + + Toggle + OCyREF toggles when TIMx_CNT=TIMx_CCRy + 3 + + + ForceInactive + OCyREF is forced low + 4 + + + ForceActive + OCyREF is forced high + 5 + + + PwmMode1 + In upcounting, channel is active as long as TIMx_CNT<TIMx_CCRy else inactive. In downcounting, channel is inactive as long as TIMx_CNT>TIMx_CCRy else active + 6 + + + PwmMode2 + Inversely to PwmMode1 + 7 + + + + + OC1PE + Output Compare 1 preload + enable + 3 + 1 + + + OC1FE + Output Compare 1 fast + enable + 2 + 1 + + + CC1S + Capture/Compare 1 + selection + 0 + 2 + + + + + CCMR1_Input + CCMR1_Input + capture/compare mode register 1 (input + mode) + CCMR1_Output + 0x18 + 0x20 + read-write + 0x00000000 + + + IC1F + Input capture 1 filter + 4 + 4 + + + IC1PSC + Input capture 1 prescaler + 2 + 2 + + + CC1S + Capture/Compare 1 + selection + 0 + 2 + + + + + CCER + CCER + capture/compare enable + register + 0x20 + 0x20 + read-write + 0x00000000 + + + CC1NP + Capture/Compare 1 output + Polarity + 3 + 1 + + + CC1P + Capture/Compare 1 output + Polarity + 1 + 1 + + + CC1E + Capture/Compare 1 output + enable + 0 + 1 + + + + + CNT + CNT + counter + 0x24 + 0x20 + read-write + 0x00000000 + + + CNT + counter value + 0 + 16 + + + + + PSC + PSC + prescaler + 0x28 + 0x20 + read-write + 0x00000000 + + + PSC + Prescaler value + 0 + 16 + + + 0 + 65535 + + + + + + + ARR + ARR + auto-reload register + 0x2C + 0x20 + read-write + 0x00000000 + + + ARR + Auto-reload value + 0 + 16 + + + + + 1 + 0x0 + 1-1 + CCR%s + CCR1 + capture/compare register + 0x34 + 0x20 + read-write + 0x00000000 + + + CCR + Capture/Compare value + 0 + 16 + + + + + + + TIM11 + General-purpose-timers + TIM + 0x40014800 + + 0x0 + 0x400 + registers + + + SPI2 + SPI2 global interrupt + 36 + + + + CR1 + CR1 + control register 1 + 0x0 + 0x20 + read-write + 0x00000000 + + + CKD + Clock division + 8 + 2 + + CKD + read-write + + Div1 + t_DTS = t_CK_INT + 0 + + + Div2 + t_DTS = 2 × t_CK_INT + 1 + + + Div4 + t_DTS = 4 × t_CK_INT + 2 + + + + + ARPE + Auto-reload preload enable + 7 + 1 + + ARPE + read-write + + Disabled + TIMx_APRR register is not buffered + 0 + + + Enabled + TIMx_APRR register is buffered + 1 + + + + + URS + Update request source + 2 + 1 + + URS + read-write + + AnyEvent + Any of counter overflow/underflow, setting UG, or update through slave mode, generates an update interrupt or DMA request + 0 + + + CounterOnly + Only counter overflow/underflow generates an update interrupt or DMA request + 1 + + + + + UDIS + Update disable + 1 + 1 + + UDIS + read-write + + Enabled + Update event enabled + 0 + + + Disabled + Update event disabled + 1 + + + + + CEN + Counter enable + 0 + 1 + + CEN + read-write + + Disabled + Counter disabled + 0 + + + Enabled + Counter enabled + 1 + + + + + OPM + One-pulse mode + 3 + 1 + + OPM + read-write + + Disabled + Counter is not stopped at update event + 0 + + + Enabled + Counter stops counting at the next update event (clearing the CEN bit) + 1 + + + + + + + DIER + DIER + DMA/Interrupt enable register + 0xC + 0x20 + read-write + 0x00000000 + + + CC1IE + Capture/Compare 1 interrupt + enable + 1 + 1 + + + UIE + Update interrupt enable + 0 + 1 + + UIE + read-write + + Disabled + Update interrupt disabled + 0 + + + Enabled + Update interrupt enabled + 1 + + + + + + + SR + SR + status register + 0x10 + 0x20 + read-write + 0x00000000 + + + CC1OF + Capture/Compare 1 overcapture + flag + 9 + 1 + + + CC1IF + Capture/compare 1 interrupt + flag + 1 + 1 + + + UIF + Update interrupt flag + 0 + 1 + zeroToClear + + UIFR + read + + NoUpdateOccurred + No update occurred + 0 + + + UpdatePending + Update interrupt pending + 1 + + + + UIFW + write + + Clear + Clear flag + 0 + + + + + + + EGR + EGR + event generation register + 0x14 + 0x20 + write-only + 0x00000000 + + + CC1G + Capture/compare 1 + generation + 1 + 1 + + + UG + Update generation + 0 + 1 + + UG + write + + Update + Re-initializes the timer counter and generates an update of the registers. + 1 + + + + + + + CCMR1_Output + CCMR1_Output + capture/compare mode register 1 (output + mode) + 0x18 + 0x20 + read-write + 0x00000000 + + + OC1M + Output Compare 1 mode + 4 + 3 + + OC1M + read-write + + Frozen + The comparison between the output compare register TIMx_CCRy and the counter TIMx_CNT has no effect on the outputs + 0 + + + ActiveOnMatch + Set channel to active level on match. OCyREF signal is forced high when the counter matches the capture/compare register + 1 + + + InactiveOnMatch + Set channel to inactive level on match. OCyREF signal is forced low when the counter matches the capture/compare register + 2 + + + Toggle + OCyREF toggles when TIMx_CNT=TIMx_CCRy + 3 + + + ForceInactive + OCyREF is forced low + 4 + + + ForceActive + OCyREF is forced high + 5 + + + PwmMode1 + In upcounting, channel is active as long as TIMx_CNT<TIMx_CCRy else inactive. In downcounting, channel is inactive as long as TIMx_CNT>TIMx_CCRy else active + 6 + + + PwmMode2 + Inversely to PwmMode1 + 7 + + + + + OC1PE + Output Compare 1 preload + enable + 3 + 1 + + + OC1FE + Output Compare 1 fast + enable + 2 + 1 + + + CC1S + Capture/Compare 1 + selection + 0 + 2 + + + + + CCMR1_Input + CCMR1_Input + capture/compare mode register 1 (input + mode) + CCMR1_Output + 0x18 + 0x20 + read-write + 0x00000000 + + + IC1F + Input capture 1 filter + 4 + 4 + + + IC1PSC + Input capture 1 prescaler + 2 + 2 + + + CC1S + Capture/Compare 1 + selection + 0 + 2 + + + + + CCER + CCER + capture/compare enable + register + 0x20 + 0x20 + read-write + 0x00000000 + + + CC1NP + Capture/Compare 1 output + Polarity + 3 + 1 + + + CC1P + Capture/Compare 1 output + Polarity + 1 + 1 + + + CC1E + Capture/Compare 1 output + enable + 0 + 1 + + + + + CNT + CNT + counter + 0x24 + 0x20 + read-write + 0x00000000 + + + CNT + counter value + 0 + 16 + + + + + PSC + PSC + prescaler + 0x28 + 0x20 + read-write + 0x00000000 + + + PSC + Prescaler value + 0 + 16 + + + 0 + 65535 + + + + + + + ARR + ARR + auto-reload register + 0x2C + 0x20 + read-write + 0x00000000 + + + ARR + Auto-reload value + 0 + 16 + + + + + 1 + 0x0 + 1-1 + CCR%s + CCR1 + capture/compare register + 0x34 + 0x20 + read-write + 0x00000000 + + + CCR + Capture/Compare value + 0 + 16 + + + + + OR + OR + option register + 0x50 + 0x20 + read-write + 0x00000000 + + + RMP + Input 1 remapping + capability + 0 + 2 + + + + + + + TIM2 + General purpose timers + TIM + 0x40000000 + + 0x0 + 0x400 + registers + + + SPI3 + SPI3 global interrupt + 51 + + + + CR1 + CR1 + control register 1 + 0x0 + 0x20 + read-write + 0x00000000 + + + CKD + Clock division + 8 + 2 + + CKD + read-write + + Div1 + t_DTS = t_CK_INT + 0 + + + Div2 + t_DTS = 2 × t_CK_INT + 1 + + + Div4 + t_DTS = 4 × t_CK_INT + 2 + + + + + ARPE + Auto-reload preload enable + 7 + 1 + + ARPE + read-write + + Disabled + TIMx_APRR register is not buffered + 0 + + + Enabled + TIMx_APRR register is buffered + 1 + + + + + CMS + Center-aligned mode + selection + 5 + 2 + + CMS + read-write + + EdgeAligned + The counter counts up or down depending on the direction bit + 0 + + + CenterAligned1 + The counter counts up and down alternatively. Output compare interrupt flags are set only when the counter is counting down. + 1 + + + CenterAligned2 + The counter counts up and down alternatively. Output compare interrupt flags are set only when the counter is counting up. + 2 + + + CenterAligned3 + The counter counts up and down alternatively. Output compare interrupt flags are set both when the counter is counting up or down. + 3 + + + + + DIR + Direction + 4 + 1 + + DIR + read-write + + Up + Counter used as upcounter + 0 + + + Down + Counter used as downcounter + 1 + + + + + OPM + One-pulse mode + 3 + 1 + + OPM + read-write + + Disabled + Counter is not stopped at update event + 0 + + + Enabled + Counter stops counting at the next update event (clearing the CEN bit) + 1 + + + + + URS + Update request source + 2 + 1 + + URS + read-write + + AnyEvent + Any of counter overflow/underflow, setting UG, or update through slave mode, generates an update interrupt or DMA request + 0 + + + CounterOnly + Only counter overflow/underflow generates an update interrupt or DMA request + 1 + + + + + UDIS + Update disable + 1 + 1 + + UDIS + read-write + + Enabled + Update event enabled + 0 + + + Disabled + Update event disabled + 1 + + + + + CEN + Counter enable + 0 + 1 + + CEN + read-write + + Disabled + Counter disabled + 0 + + + Enabled + Counter enabled + 1 + + + + + + + CR2 + CR2 + control register 2 + 0x4 + 0x20 + read-write + 0x00000000 + + + TI1S + TI1 selection + 7 + 1 + + TI1S + read-write + + Normal + The TIMx_CH1 pin is connected to TI1 input + 0 + + + XOR + The TIMx_CH1, CH2, CH3 pins are connected to TI1 input + 1 + + + + + MMS + Master mode selection + 4 + 3 + + MMS + read-write + + Reset + The UG bit from the TIMx_EGR register is used as trigger output + 0 + + + Enable + The counter enable signal, CNT_EN, is used as trigger output + 1 + + + Update + The update event is selected as trigger output + 2 + + + ComparePulse + The trigger output send a positive pulse when the CC1IF flag it to be set, as soon as a capture or a compare match occurred + 3 + + + CompareOC1 + OC1REF signal is used as trigger output + 4 + + + CompareOC2 + OC2REF signal is used as trigger output + 5 + + + CompareOC3 + OC3REF signal is used as trigger output + 6 + + + CompareOC4 + OC4REF signal is used as trigger output + 7 + + + + + CCDS + Capture/compare DMA + selection + 3 + 1 + + CCDS + read-write + + OnCompare + CCx DMA request sent when CCx event occurs + 0 + + + OnUpdate + CCx DMA request sent when update event occurs + 1 + + + + + + + SMCR + SMCR + slave mode control register + 0x8 + 0x20 + read-write + 0x00000000 + + + ETP + External trigger polarity + 15 + 1 + + ETP + read-write + + NotInverted + ETR is noninverted, active at high level or rising edge + 0 + + + Inverted + ETR is inverted, active at low level or falling edge + 1 + + + + + ECE + External clock enable + 14 + 1 + + ECE + read-write + + Disabled + External clock mode 2 disabled + 0 + + + Enabled + External clock mode 2 enabled. The counter is clocked by any active edge on the ETRF signal. + 1 + + + + + ETPS + External trigger prescaler + 12 + 2 + + ETPS + read-write + + Div1 + Prescaler OFF + 0 + + + Div2 + ETRP frequency divided by 2 + 1 + + + Div4 + ETRP frequency divided by 4 + 2 + + + Div8 + ETRP frequency divided by 8 + 3 + + + + + ETF + External trigger filter + 8 + 4 + + ETF + read-write + + NoFilter + No filter, sampling is done at fDTS + 0 + + + FCK_INT_N2 + fSAMPLING=fCK_INT, N=2 + 1 + + + FCK_INT_N4 + fSAMPLING=fCK_INT, N=4 + 2 + + + FCK_INT_N8 + fSAMPLING=fCK_INT, N=8 + 3 + + + FDTS_Div2_N6 + fSAMPLING=fDTS/2, N=6 + 4 + + + FDTS_Div2_N8 + fSAMPLING=fDTS/2, N=8 + 5 + + + FDTS_Div4_N6 + fSAMPLING=fDTS/4, N=6 + 6 + + + FDTS_Div4_N8 + fSAMPLING=fDTS/4, N=8 + 7 + + + FDTS_Div8_N6 + fSAMPLING=fDTS/8, N=6 + 8 + + + FDTS_Div8_N8 + fSAMPLING=fDTS/8, N=8 + 9 + + + FDTS_Div16_N5 + fSAMPLING=fDTS/16, N=5 + 10 + + + FDTS_Div16_N6 + fSAMPLING=fDTS/16, N=6 + 11 + + + FDTS_Div16_N8 + fSAMPLING=fDTS/16, N=8 + 12 + + + FDTS_Div32_N5 + fSAMPLING=fDTS/32, N=5 + 13 + + + FDTS_Div32_N6 + fSAMPLING=fDTS/32, N=6 + 14 + + + FDTS_Div32_N8 + fSAMPLING=fDTS/32, N=8 + 15 + + + + + MSM + Master/Slave mode + 7 + 1 + + MSM + read-write + + NoSync + No action + 0 + + + Sync + The effect of an event on the trigger input (TRGI) is delayed to allow a perfect synchronization between the current timer and its slaves (through TRGO). It is useful if we want to synchronize several timers on a single external event. + 1 + + + + + TS + Trigger selection + 4 + 3 + + TS + read-write + + ITR0 + Internal Trigger 0 (ITR0) + 0 + + + ITR1 + Internal Trigger 1 (ITR1) + 1 + + + ITR2 + Internal Trigger 2 (ITR2) + 2 + + + TI1F_ED + TI1 Edge Detector (TI1F_ED) + 4 + + + TI1FP1 + Filtered Timer Input 1 (TI1FP1) + 5 + + + TI2FP2 + Filtered Timer Input 2 (TI2FP2) + 6 + + + ETRF + External Trigger input (ETRF) + 7 + + + + + SMS + Slave mode selection + 0 + 3 + + SMS + read-write + + Disabled + Slave mode disabled - if CEN = ‘1 then the prescaler is clocked directly by the internal clock. + 0 + + + Encoder_Mode_1 + Encoder mode 1 - Counter counts up/down on TI2FP1 edge depending on TI1FP2 level. + 1 + + + Encoder_Mode_2 + Encoder mode 2 - Counter counts up/down on TI1FP2 edge depending on TI2FP1 level. + 2 + + + Encoder_Mode_3 + Encoder mode 3 - Counter counts up/down on both TI1FP1 and TI2FP2 edges depending on the level of the other input. + 3 + + + Reset_Mode + Reset Mode - Rising edge of the selected trigger input (TRGI) reinitializes the counter and generates an update of the registers. + 4 + + + Gated_Mode + Gated Mode - The counter clock is enabled when the trigger input (TRGI) is high. The counter stops (but is not reset) as soon as the trigger becomes low. Both start and stop of the counter are controlled. + 5 + + + Trigger_Mode + Trigger Mode - The counter starts at a rising edge of the trigger TRGI (but it is not reset). Only the start of the counter is controlled. + 6 + + + Ext_Clock_Mode + External Clock Mode 1 - Rising edges of the selected trigger (TRGI) clock the counter. + 7 + + + + + + + DIER + DIER + DMA/Interrupt enable register + 0xC + 0x20 + read-write + 0x00000000 + + + TDE + Trigger DMA request enable + 14 + 1 + + TDE + read-write + + Disabled + Trigger DMA request disabled + 0 + + + Enabled + Trigger DMA request enabled + 1 + + + + + CC4DE + Capture/Compare 4 DMA request + enable + 12 + 1 + + + + CC3DE + Capture/Compare 3 DMA request + enable + 11 + 1 + + + + CC2DE + Capture/Compare 2 DMA request + enable + 10 + 1 + + + + CC1DE + Capture/Compare 1 DMA request + enable + 9 + 1 + + CC1DE + read-write + + Disabled + CCx DMA request disabled + 0 + + + Enabled + CCx DMA request enabled + 1 + + + + + UDE + Update DMA request enable + 8 + 1 + + UDE + read-write + + Disabled + Update DMA request disabled + 0 + + + Enabled + Update DMA request enabled + 1 + + + + + TIE + Trigger interrupt enable + 6 + 1 + + TIE + read-write + + Disabled + Trigger interrupt disabled + 0 + + + Enabled + Trigger interrupt enabled + 1 + + + + + CC4IE + Capture/Compare 4 interrupt + enable + 4 + 1 + + + + CC3IE + Capture/Compare 3 interrupt + enable + 3 + 1 + + + + CC2IE + Capture/Compare 2 interrupt + enable + 2 + 1 + + + + CC1IE + Capture/Compare 1 interrupt + enable + 1 + 1 + + CC1IE + read-write + + Disabled + CCx interrupt disabled + 0 + + + Enabled + CCx interrupt enabled + 1 + + + + + UIE + Update interrupt enable + 0 + 1 + + UIE + read-write + + Disabled + Update interrupt disabled + 0 + + + Enabled + Update interrupt enabled + 1 + + + + + + + SR + SR + status register + 0x10 + 0x20 + read-write + 0x00000000 + + + CC4OF + Capture/Compare 4 overcapture + flag + 12 + 1 + zeroToClear + + read + + + write + + + + CC3OF + Capture/Compare 3 overcapture + flag + 11 + 1 + zeroToClear + + read + + + write + + + + CC2OF + Capture/compare 2 overcapture + flag + 10 + 1 + zeroToClear + + read + + + write + + + + CC1OF + Capture/Compare 1 overcapture + flag + 9 + 1 + zeroToClear + + CC1OFR + read + + Overcapture + The counter value has been captured in TIMx_CCRx register while CCxIF flag was already set + 1 + + + + CC1OFW + write + + Clear + Clear flag + 0 + + + + + TIF + Trigger interrupt flag + 6 + 1 + zeroToClear + + TIFR + read + + NoTrigger + No trigger event occurred + 0 + + + Trigger + Trigger interrupt pending + 1 + + + + TIFW + write + + Clear + Clear flag + 0 + + + + + CC4IF + Capture/Compare 4 interrupt + flag + 4 + 1 + zeroToClear + + read + + + write + + + + CC3IF + Capture/Compare 3 interrupt + flag + 3 + 1 + zeroToClear + + read + + + write + + + + CC2IF + Capture/Compare 2 interrupt + flag + 2 + 1 + zeroToClear + + read + + + write + + + + CC1IF + Capture/compare 1 interrupt + flag + 1 + 1 + zeroToClear + + CC1IFR + read + + Match + If CC1 is an output: The content of the counter TIMx_CNT matches the content of the TIMx_CCR1 register. If CC1 is an input: The counter value has been captured in TIMx_CCR1 register. + 1 + + + + CC1IFW + write + + Clear + Clear flag + 0 + + + + + UIF + Update interrupt flag + 0 + 1 + zeroToClear + + UIFR + read + + NoUpdateOccurred + No update occurred + 0 + + + UpdatePending + Update interrupt pending + 1 + + + + UIFW + write + + Clear + Clear flag + 0 + + + + + + + EGR + EGR + event generation register + 0x14 + 0x20 + write-only + 0x00000000 + + + TG + Trigger generation + 6 + 1 + + TGW + write + + Trigger + The TIF flag is set in TIMx_SR register. Related interrupt or DMA transfer can occur if enabled. + 1 + + + + + CC4G + Capture/compare 4 + generation + 4 + 1 + + + + CC3G + Capture/compare 3 + generation + 3 + 1 + + + + CC2G + Capture/compare 2 + generation + 2 + 1 + + + + CC1G + Capture/compare 1 + generation + 1 + 1 + + CC1GW + write + + Trigger + If CC1 is an output: CC1IF flag is set, Corresponding interrupt or DMA request is sent if enabled. If CC1 is an input: The current value of the counter is captured in TIMx_CCR1 register. + 1 + + + + + UG + Update generation + 0 + 1 + + UG + write + + Update + Re-initializes the timer counter and generates an update of the registers. + 1 + + + + + + + CCMR1_Output + CCMR1_Output + capture/compare mode register 1 (output + mode) + 0x18 + 0x20 + read-write + 0x00000000 + + + OC2CE + OC2CE + 15 + 1 + + + OC2M + OC2M + 12 + 3 + + + + OC2PE + OC2PE + 11 + 1 + + OC2PE + read-write + + Disabled + Preload register on CCR2 disabled. New values written to CCR2 are taken into account immediately + 0 + + + Enabled + Preload register on CCR2 enabled. Preload value is loaded into active register on each update event + 1 + + + + + OC2FE + OC2FE + 10 + 1 + + + CC2S + CC2S + 8 + 2 + + CC2S + read-write + + Output + CC2 channel is configured as output + 0 + + + + + OC1CE + OC1CE + 7 + 1 + + + OC1M + OC1M + 4 + 3 + + OC1M + read-write + + Frozen + The comparison between the output compare register TIMx_CCRy and the counter TIMx_CNT has no effect on the outputs + 0 + + + ActiveOnMatch + Set channel to active level on match. OCyREF signal is forced high when the counter matches the capture/compare register + 1 + + + InactiveOnMatch + Set channel to inactive level on match. OCyREF signal is forced low when the counter matches the capture/compare register + 2 + + + Toggle + OCyREF toggles when TIMx_CNT=TIMx_CCRy + 3 + + + ForceInactive + OCyREF is forced low + 4 + + + ForceActive + OCyREF is forced high + 5 + + + PwmMode1 + In upcounting, channel is active as long as TIMx_CNT<TIMx_CCRy else inactive. In downcounting, channel is inactive as long as TIMx_CNT>TIMx_CCRy else active + 6 + + + PwmMode2 + Inversely to PwmMode1 + 7 + + + + + OC1PE + OC1PE + 3 + 1 + + OC1PE + read-write + + Disabled + Preload register on CCR1 disabled. New values written to CCR1 are taken into account immediately + 0 + + + Enabled + Preload register on CCR1 enabled. Preload value is loaded into active register on each update event + 1 + + + + + OC1FE + OC1FE + 2 + 1 + + + CC1S + CC1S + 0 + 2 + + CC1S + read-write + + Output + CC1 channel is configured as output + 0 + + + + + + + CCMR1_Input + CCMR1_Input + capture/compare mode register 1 (input + mode) + CCMR1_Output + 0x18 + 0x20 + read-write + 0x00000000 + + + IC2F + Input capture 2 filter + 12 + 4 + + + 0 + 15 + + + + + IC2PSC + Input capture 2 prescaler + 10 + 2 + + + CC2S + Capture/Compare 2 + selection + 8 + 2 + + CC2S + read-write + + TI2 + CC2 channel is configured as input, IC2 is mapped on TI2 + 1 + + + TI1 + CC2 channel is configured as input, IC2 is mapped on TI1 + 2 + + + TRC + CC2 channel is configured as input, IC2 is mapped on TRC + 3 + + + + + IC1F + Input capture 1 filter + 4 + 4 + + IC1F + read-write + + NoFilter + No filter, sampling is done at fDTS + 0 + + + FCK_INT_N2 + fSAMPLING=fCK_INT, N=2 + 1 + + + FCK_INT_N4 + fSAMPLING=fCK_INT, N=4 + 2 + + + FCK_INT_N8 + fSAMPLING=fCK_INT, N=8 + 3 + + + FDTS_Div2_N6 + fSAMPLING=fDTS/2, N=6 + 4 + + + FDTS_Div2_N8 + fSAMPLING=fDTS/2, N=8 + 5 + + + FDTS_Div4_N6 + fSAMPLING=fDTS/4, N=6 + 6 + + + FDTS_Div4_N8 + fSAMPLING=fDTS/4, N=8 + 7 + + + FDTS_Div8_N6 + fSAMPLING=fDTS/8, N=6 + 8 + + + FDTS_Div8_N8 + fSAMPLING=fDTS/8, N=8 + 9 + + + FDTS_Div16_N5 + fSAMPLING=fDTS/16, N=5 + 10 + + + FDTS_Div16_N6 + fSAMPLING=fDTS/16, N=6 + 11 + + + FDTS_Div16_N8 + fSAMPLING=fDTS/16, N=8 + 12 + + + FDTS_Div32_N5 + fSAMPLING=fDTS/32, N=5 + 13 + + + FDTS_Div32_N6 + fSAMPLING=fDTS/32, N=6 + 14 + + + FDTS_Div32_N8 + fSAMPLING=fDTS/32, N=8 + 15 + + + + + IC1PSC + Input capture 1 prescaler + 2 + 2 + + + CC1S + Capture/Compare 1 + selection + 0 + 2 + + CC1S + read-write + + TI1 + CC1 channel is configured as input, IC1 is mapped on TI1 + 1 + + + TI2 + CC1 channel is configured as input, IC1 is mapped on TI2 + 2 + + + TRC + CC1 channel is configured as input, IC1 is mapped on TRC + 3 + + + + + + + CCMR2_Output + CCMR2_Output + capture/compare mode register 2 (output + mode) + 0x1C + 0x20 + read-write + 0x00000000 + + + OC4CE + O24CE + 15 + 1 + + + OC4M + OC4M + 12 + 3 + + + + OC4PE + OC4PE + 11 + 1 + + OC4PE + read-write + + Disabled + Preload register on CCR4 disabled. New values written to CCR4 are taken into account immediately + 0 + + + Enabled + Preload register on CCR4 enabled. Preload value is loaded into active register on each update event + 1 + + + + + OC4FE + OC4FE + 10 + 1 + + + CC4S + CC4S + 8 + 2 + + CC4S + read-write + + Output + CC4 channel is configured as output + 0 + + + + + OC3CE + OC3CE + 7 + 1 + + + OC3M + OC3M + 4 + 3 + + OC3M + read-write + + Frozen + The comparison between the output compare register TIMx_CCRy and the counter TIMx_CNT has no effect on the outputs + 0 + + + ActiveOnMatch + Set channel to active level on match. OCyREF signal is forced high when the counter matches the capture/compare register + 1 + + + InactiveOnMatch + Set channel to inactive level on match. OCyREF signal is forced low when the counter matches the capture/compare register + 2 + + + Toggle + OCyREF toggles when TIMx_CNT=TIMx_CCRy + 3 + + + ForceInactive + OCyREF is forced low + 4 + + + ForceActive + OCyREF is forced high + 5 + + + PwmMode1 + In upcounting, channel is active as long as TIMx_CNT<TIMx_CCRy else inactive. In downcounting, channel is inactive as long as TIMx_CNT>TIMx_CCRy else active + 6 + + + PwmMode2 + Inversely to PwmMode1 + 7 + + + + + OC3PE + OC3PE + 3 + 1 + + OC3PE + read-write + + Disabled + Preload register on CCR3 disabled. New values written to CCR3 are taken into account immediately + 0 + + + Enabled + Preload register on CCR3 enabled. Preload value is loaded into active register on each update event + 1 + + + + + OC3FE + OC3FE + 2 + 1 + + + CC3S + CC3S + 0 + 2 + + CC3S + read-write + + Output + CC3 channel is configured as output + 0 + + + + + + + CCMR2_Input + CCMR2_Input + capture/compare mode register 2 (input + mode) + CCMR2_Output + 0x1C + 0x20 + read-write + 0x00000000 + + + IC4F + Input capture 4 filter + 12 + 4 + + + 0 + 15 + + + + + IC4PSC + Input capture 4 prescaler + 10 + 2 + + + 0 + 3 + + + + + CC4S + Capture/Compare 4 + selection + 8 + 2 + + CC4S + read-write + + TI4 + CC4 channel is configured as input, IC4 is mapped on TI4 + 1 + + + TI3 + CC4 channel is configured as input, IC4 is mapped on TI3 + 2 + + + TRC + CC4 channel is configured as input, IC4 is mapped on TRC + 3 + + + + + IC3F + Input capture 3 filter + 4 + 4 + + + 0 + 15 + + + + + IC3PSC + Input capture 3 prescaler + 2 + 2 + + + 0 + 3 + + + + + CC3S + Capture/compare 3 + selection + 0 + 2 + + CC3S + read-write + + TI3 + CC3 channel is configured as input, IC3 is mapped on TI3 + 1 + + + TI4 + CC3 channel is configured as input, IC3 is mapped on TI4 + 2 + + + TRC + CC3 channel is configured as input, IC3 is mapped on TRC + 3 + + + + + + + CCER + CCER + capture/compare enable + register + 0x20 + 0x20 + read-write + 0x00000000 + + + CC4NP + Capture/Compare 4 output + Polarity + 15 + 1 + + + CC4P + Capture/Compare 3 output + Polarity + 13 + 1 + + + CC4E + Capture/Compare 4 output + enable + 12 + 1 + + + CC3NP + Capture/Compare 3 output + Polarity + 11 + 1 + + + CC3P + Capture/Compare 3 output + Polarity + 9 + 1 + + + CC3E + Capture/Compare 3 output + enable + 8 + 1 + + + CC2NP + Capture/Compare 2 output + Polarity + 7 + 1 + + + CC2P + Capture/Compare 2 output + Polarity + 5 + 1 + + + CC2E + Capture/Compare 2 output + enable + 4 + 1 + + + CC1NP + Capture/Compare 1 output + Polarity + 3 + 1 + + + CC1P + Capture/Compare 1 output + Polarity + 1 + 1 + + + CC1E + Capture/Compare 1 output + enable + 0 + 1 + + + + + CNT + CNT + counter + 0x24 + 0x20 + read-write + 0x00000000 + + + CNT + Counter value + 0 + 32 + + + 0 + 4294967295 + + + + + + + PSC + PSC + prescaler + 0x28 + 0x20 + read-write + 0x00000000 + + + PSC + Prescaler value + 0 + 16 + + + 0 + 65535 + + + + + + + ARR + ARR + auto-reload register + 0x2C + 0x20 + read-write + 0x00000000 + + + ARR + Auto-reload value + 0 + 32 + + + 0 + 4294967295 + + + + + + + 4 + 0x4 + 1-4 + CCR%s + CCR1 + capture/compare register + 0x34 + 0x20 + read-write + 0x00000000 + + + CCR + Capture/Compare value + 0 + 32 + + + 0 + 4294967295 + + + + + + + DCR + DCR + DMA control register + 0x48 + 0x20 + read-write + 0x00000000 + + + DBL + DMA burst length + 8 + 5 + + + 0 + 18 + + + + + DBA + DMA base address + 0 + 5 + + + 0 + 31 + + + + + + + DMAR + DMAR + DMA address for full transfer + 0x4C + 0x20 + read-write + 0x00000000 + + + DMAB + DMA register for burst + accesses + 0 + 16 + + + + + OR + OR + TIM5 option register + 0x50 + 0x20 + read-write + 0x00000000 + + + ITR1_RMP + Timer Input 4 remap + 10 + 2 + + + + + + + TIM3 + General purpose timers + TIM + 0x40000400 + + 0x0 + 0x400 + registers + + + SPI4 + SPI4 global interrupt + 84 + + + TIM4 + TIM4 global interrupt + 30 + + + TIM5 + TIM5 global interrupt + 50 + + + + CR1 + CR1 + control register 1 + 0x0 + 0x20 + read-write + 0x00000000 + + + CKD + Clock division + 8 + 2 + + CKD + read-write + + Div1 + t_DTS = t_CK_INT + 0 + + + Div2 + t_DTS = 2 × t_CK_INT + 1 + + + Div4 + t_DTS = 4 × t_CK_INT + 2 + + + + + ARPE + Auto-reload preload enable + 7 + 1 + + ARPE + read-write + + Disabled + TIMx_APRR register is not buffered + 0 + + + Enabled + TIMx_APRR register is buffered + 1 + + + + + CMS + Center-aligned mode + selection + 5 + 2 + + CMS + read-write + + EdgeAligned + The counter counts up or down depending on the direction bit + 0 + + + CenterAligned1 + The counter counts up and down alternatively. Output compare interrupt flags are set only when the counter is counting down. + 1 + + + CenterAligned2 + The counter counts up and down alternatively. Output compare interrupt flags are set only when the counter is counting up. + 2 + + + CenterAligned3 + The counter counts up and down alternatively. Output compare interrupt flags are set both when the counter is counting up or down. + 3 + + + + + DIR + Direction + 4 + 1 + + DIR + read-write + + Up + Counter used as upcounter + 0 + + + Down + Counter used as downcounter + 1 + + + + + OPM + One-pulse mode + 3 + 1 + + OPM + read-write + + Disabled + Counter is not stopped at update event + 0 + + + Enabled + Counter stops counting at the next update event (clearing the CEN bit) + 1 + + + + + URS + Update request source + 2 + 1 + + URS + read-write + + AnyEvent + Any of counter overflow/underflow, setting UG, or update through slave mode, generates an update interrupt or DMA request + 0 + + + CounterOnly + Only counter overflow/underflow generates an update interrupt or DMA request + 1 + + + + + UDIS + Update disable + 1 + 1 + + UDIS + read-write + + Enabled + Update event enabled + 0 + + + Disabled + Update event disabled + 1 + + + + + CEN + Counter enable + 0 + 1 + + CEN + read-write + + Disabled + Counter disabled + 0 + + + Enabled + Counter enabled + 1 + + + + + + + CR2 + CR2 + control register 2 + 0x4 + 0x20 + read-write + 0x00000000 + + + TI1S + TI1 selection + 7 + 1 + + TI1S + read-write + + Normal + The TIMx_CH1 pin is connected to TI1 input + 0 + + + XOR + The TIMx_CH1, CH2, CH3 pins are connected to TI1 input + 1 + + + + + MMS + Master mode selection + 4 + 3 + + MMS + read-write + + Reset + The UG bit from the TIMx_EGR register is used as trigger output + 0 + + + Enable + The counter enable signal, CNT_EN, is used as trigger output + 1 + + + Update + The update event is selected as trigger output + 2 + + + ComparePulse + The trigger output send a positive pulse when the CC1IF flag it to be set, as soon as a capture or a compare match occurred + 3 + + + CompareOC1 + OC1REF signal is used as trigger output + 4 + + + CompareOC2 + OC2REF signal is used as trigger output + 5 + + + CompareOC3 + OC3REF signal is used as trigger output + 6 + + + CompareOC4 + OC4REF signal is used as trigger output + 7 + + + + + CCDS + Capture/compare DMA + selection + 3 + 1 + + CCDS + read-write + + OnCompare + CCx DMA request sent when CCx event occurs + 0 + + + OnUpdate + CCx DMA request sent when update event occurs + 1 + + + + + + + SMCR + SMCR + slave mode control register + 0x8 + 0x20 + read-write + 0x00000000 + + + ETP + External trigger polarity + 15 + 1 + + ETP + read-write + + NotInverted + ETR is noninverted, active at high level or rising edge + 0 + + + Inverted + ETR is inverted, active at low level or falling edge + 1 + + + + + ECE + External clock enable + 14 + 1 + + ECE + read-write + + Disabled + External clock mode 2 disabled + 0 + + + Enabled + External clock mode 2 enabled. The counter is clocked by any active edge on the ETRF signal. + 1 + + + + + ETPS + External trigger prescaler + 12 + 2 + + ETPS + read-write + + Div1 + Prescaler OFF + 0 + + + Div2 + ETRP frequency divided by 2 + 1 + + + Div4 + ETRP frequency divided by 4 + 2 + + + Div8 + ETRP frequency divided by 8 + 3 + + + + + ETF + External trigger filter + 8 + 4 + + ETF + read-write + + NoFilter + No filter, sampling is done at fDTS + 0 + + + FCK_INT_N2 + fSAMPLING=fCK_INT, N=2 + 1 + + + FCK_INT_N4 + fSAMPLING=fCK_INT, N=4 + 2 + + + FCK_INT_N8 + fSAMPLING=fCK_INT, N=8 + 3 + + + FDTS_Div2_N6 + fSAMPLING=fDTS/2, N=6 + 4 + + + FDTS_Div2_N8 + fSAMPLING=fDTS/2, N=8 + 5 + + + FDTS_Div4_N6 + fSAMPLING=fDTS/4, N=6 + 6 + + + FDTS_Div4_N8 + fSAMPLING=fDTS/4, N=8 + 7 + + + FDTS_Div8_N6 + fSAMPLING=fDTS/8, N=6 + 8 + + + FDTS_Div8_N8 + fSAMPLING=fDTS/8, N=8 + 9 + + + FDTS_Div16_N5 + fSAMPLING=fDTS/16, N=5 + 10 + + + FDTS_Div16_N6 + fSAMPLING=fDTS/16, N=6 + 11 + + + FDTS_Div16_N8 + fSAMPLING=fDTS/16, N=8 + 12 + + + FDTS_Div32_N5 + fSAMPLING=fDTS/32, N=5 + 13 + + + FDTS_Div32_N6 + fSAMPLING=fDTS/32, N=6 + 14 + + + FDTS_Div32_N8 + fSAMPLING=fDTS/32, N=8 + 15 + + + + + MSM + Master/Slave mode + 7 + 1 + + MSM + read-write + + NoSync + No action + 0 + + + Sync + The effect of an event on the trigger input (TRGI) is delayed to allow a perfect synchronization between the current timer and its slaves (through TRGO). It is useful if we want to synchronize several timers on a single external event. + 1 + + + + + TS + Trigger selection + 4 + 3 + + TS + read-write + + ITR0 + Internal Trigger 0 (ITR0) + 0 + + + ITR1 + Internal Trigger 1 (ITR1) + 1 + + + ITR2 + Internal Trigger 2 (ITR2) + 2 + + + TI1F_ED + TI1 Edge Detector (TI1F_ED) + 4 + + + TI1FP1 + Filtered Timer Input 1 (TI1FP1) + 5 + + + TI2FP2 + Filtered Timer Input 2 (TI2FP2) + 6 + + + ETRF + External Trigger input (ETRF) + 7 + + + + + SMS + Slave mode selection + 0 + 3 + + SMS + read-write + + Disabled + Slave mode disabled - if CEN = ‘1 then the prescaler is clocked directly by the internal clock. + 0 + + + Encoder_Mode_1 + Encoder mode 1 - Counter counts up/down on TI2FP1 edge depending on TI1FP2 level. + 1 + + + Encoder_Mode_2 + Encoder mode 2 - Counter counts up/down on TI1FP2 edge depending on TI2FP1 level. + 2 + + + Encoder_Mode_3 + Encoder mode 3 - Counter counts up/down on both TI1FP1 and TI2FP2 edges depending on the level of the other input. + 3 + + + Reset_Mode + Reset Mode - Rising edge of the selected trigger input (TRGI) reinitializes the counter and generates an update of the registers. + 4 + + + Gated_Mode + Gated Mode - The counter clock is enabled when the trigger input (TRGI) is high. The counter stops (but is not reset) as soon as the trigger becomes low. Both start and stop of the counter are controlled. + 5 + + + Trigger_Mode + Trigger Mode - The counter starts at a rising edge of the trigger TRGI (but it is not reset). Only the start of the counter is controlled. + 6 + + + Ext_Clock_Mode + External Clock Mode 1 - Rising edges of the selected trigger (TRGI) clock the counter. + 7 + + + + + + + DIER + DIER + DMA/Interrupt enable register + 0xC + 0x20 + read-write + 0x00000000 + + + TDE + Trigger DMA request enable + 14 + 1 + + TDE + read-write + + Disabled + Trigger DMA request disabled + 0 + + + Enabled + Trigger DMA request enabled + 1 + + + + + CC4DE + Capture/Compare 4 DMA request + enable + 12 + 1 + + + + CC3DE + Capture/Compare 3 DMA request + enable + 11 + 1 + + + + CC2DE + Capture/Compare 2 DMA request + enable + 10 + 1 + + + + CC1DE + Capture/Compare 1 DMA request + enable + 9 + 1 + + CC1DE + read-write + + Disabled + CCx DMA request disabled + 0 + + + Enabled + CCx DMA request enabled + 1 + + + + + UDE + Update DMA request enable + 8 + 1 + + UDE + read-write + + Disabled + Update DMA request disabled + 0 + + + Enabled + Update DMA request enabled + 1 + + + + + TIE + Trigger interrupt enable + 6 + 1 + + TIE + read-write + + Disabled + Trigger interrupt disabled + 0 + + + Enabled + Trigger interrupt enabled + 1 + + + + + CC4IE + Capture/Compare 4 interrupt + enable + 4 + 1 + + + + CC3IE + Capture/Compare 3 interrupt + enable + 3 + 1 + + + + CC2IE + Capture/Compare 2 interrupt + enable + 2 + 1 + + + + CC1IE + Capture/Compare 1 interrupt + enable + 1 + 1 + + CC1IE + read-write + + Disabled + CCx interrupt disabled + 0 + + + Enabled + CCx interrupt enabled + 1 + + + + + UIE + Update interrupt enable + 0 + 1 + + UIE + read-write + + Disabled + Update interrupt disabled + 0 + + + Enabled + Update interrupt enabled + 1 + + + + + + + SR + SR + status register + 0x10 + 0x20 + read-write + 0x00000000 + + + CC4OF + Capture/Compare 4 overcapture + flag + 12 + 1 + zeroToClear + + read + + + write + + + + CC3OF + Capture/Compare 3 overcapture + flag + 11 + 1 + zeroToClear + + read + + + write + + + + CC2OF + Capture/compare 2 overcapture + flag + 10 + 1 + zeroToClear + + read + + + write + + + + CC1OF + Capture/Compare 1 overcapture + flag + 9 + 1 + zeroToClear + + CC1OFR + read + + Overcapture + The counter value has been captured in TIMx_CCRx register while CCxIF flag was already set + 1 + + + + CC1OFW + write + + Clear + Clear flag + 0 + + + + + TIF + Trigger interrupt flag + 6 + 1 + zeroToClear + + TIFR + read + + NoTrigger + No trigger event occurred + 0 + + + Trigger + Trigger interrupt pending + 1 + + + + TIFW + write + + Clear + Clear flag + 0 + + + + + CC4IF + Capture/Compare 4 interrupt + flag + 4 + 1 + zeroToClear + + read + + + write + + + + CC3IF + Capture/Compare 3 interrupt + flag + 3 + 1 + zeroToClear + + read + + + write + + + + CC2IF + Capture/Compare 2 interrupt + flag + 2 + 1 + zeroToClear + + read + + + write + + + + CC1IF + Capture/compare 1 interrupt + flag + 1 + 1 + zeroToClear + + CC1IFR + read + + Match + If CC1 is an output: The content of the counter TIMx_CNT matches the content of the TIMx_CCR1 register. If CC1 is an input: The counter value has been captured in TIMx_CCR1 register. + 1 + + + + CC1IFW + write + + Clear + Clear flag + 0 + + + + + UIF + Update interrupt flag + 0 + 1 + zeroToClear + + UIFR + read + + NoUpdateOccurred + No update occurred + 0 + + + UpdatePending + Update interrupt pending + 1 + + + + UIFW + write + + Clear + Clear flag + 0 + + + + + + + EGR + EGR + event generation register + 0x14 + 0x20 + write-only + 0x00000000 + + + TG + Trigger generation + 6 + 1 + + TGW + write + + Trigger + The TIF flag is set in TIMx_SR register. Related interrupt or DMA transfer can occur if enabled. + 1 + + + + + CC4G + Capture/compare 4 + generation + 4 + 1 + + + + CC3G + Capture/compare 3 + generation + 3 + 1 + + + + CC2G + Capture/compare 2 + generation + 2 + 1 + + + + CC1G + Capture/compare 1 + generation + 1 + 1 + + CC1GW + write + + Trigger + If CC1 is an output: CC1IF flag is set, Corresponding interrupt or DMA request is sent if enabled. If CC1 is an input: The current value of the counter is captured in TIMx_CCR1 register. + 1 + + + + + UG + Update generation + 0 + 1 + + UG + write + + Update + Re-initializes the timer counter and generates an update of the registers. + 1 + + + + + + + CCMR1_Output + CCMR1_Output + capture/compare mode register 1 (output + mode) + 0x18 + 0x20 + read-write + 0x00000000 + + + OC2CE + OC2CE + 15 + 1 + + + OC2M + OC2M + 12 + 3 + + + + OC2PE + OC2PE + 11 + 1 + + OC2PE + read-write + + Disabled + Preload register on CCR2 disabled. New values written to CCR2 are taken into account immediately + 0 + + + Enabled + Preload register on CCR2 enabled. Preload value is loaded into active register on each update event + 1 + + + + + OC2FE + OC2FE + 10 + 1 + + + CC2S + CC2S + 8 + 2 + + CC2S + read-write + + Output + CC2 channel is configured as output + 0 + + + + + OC1CE + OC1CE + 7 + 1 + + + OC1M + OC1M + 4 + 3 + + OC1M + read-write + + Frozen + The comparison between the output compare register TIMx_CCRy and the counter TIMx_CNT has no effect on the outputs + 0 + + + ActiveOnMatch + Set channel to active level on match. OCyREF signal is forced high when the counter matches the capture/compare register + 1 + + + InactiveOnMatch + Set channel to inactive level on match. OCyREF signal is forced low when the counter matches the capture/compare register + 2 + + + Toggle + OCyREF toggles when TIMx_CNT=TIMx_CCRy + 3 + + + ForceInactive + OCyREF is forced low + 4 + + + ForceActive + OCyREF is forced high + 5 + + + PwmMode1 + In upcounting, channel is active as long as TIMx_CNT<TIMx_CCRy else inactive. In downcounting, channel is inactive as long as TIMx_CNT>TIMx_CCRy else active + 6 + + + PwmMode2 + Inversely to PwmMode1 + 7 + + + + + OC1PE + OC1PE + 3 + 1 + + OC1PE + read-write + + Disabled + Preload register on CCR1 disabled. New values written to CCR1 are taken into account immediately + 0 + + + Enabled + Preload register on CCR1 enabled. Preload value is loaded into active register on each update event + 1 + + + + + OC1FE + OC1FE + 2 + 1 + + + CC1S + CC1S + 0 + 2 + + CC1S + read-write + + Output + CC1 channel is configured as output + 0 + + + + + + + CCMR1_Input + CCMR1_Input + capture/compare mode register 1 (input + mode) + CCMR1_Output + 0x18 + 0x20 + read-write + 0x00000000 + + + IC2F + Input capture 2 filter + 12 + 4 + + + 0 + 15 + + + + + IC2PSC + Input capture 2 prescaler + 10 + 2 + + + CC2S + Capture/Compare 2 + selection + 8 + 2 + + CC2S + read-write + + TI2 + CC2 channel is configured as input, IC2 is mapped on TI2 + 1 + + + TI1 + CC2 channel is configured as input, IC2 is mapped on TI1 + 2 + + + TRC + CC2 channel is configured as input, IC2 is mapped on TRC + 3 + + + + + IC1F + Input capture 1 filter + 4 + 4 + + IC1F + read-write + + NoFilter + No filter, sampling is done at fDTS + 0 + + + FCK_INT_N2 + fSAMPLING=fCK_INT, N=2 + 1 + + + FCK_INT_N4 + fSAMPLING=fCK_INT, N=4 + 2 + + + FCK_INT_N8 + fSAMPLING=fCK_INT, N=8 + 3 + + + FDTS_Div2_N6 + fSAMPLING=fDTS/2, N=6 + 4 + + + FDTS_Div2_N8 + fSAMPLING=fDTS/2, N=8 + 5 + + + FDTS_Div4_N6 + fSAMPLING=fDTS/4, N=6 + 6 + + + FDTS_Div4_N8 + fSAMPLING=fDTS/4, N=8 + 7 + + + FDTS_Div8_N6 + fSAMPLING=fDTS/8, N=6 + 8 + + + FDTS_Div8_N8 + fSAMPLING=fDTS/8, N=8 + 9 + + + FDTS_Div16_N5 + fSAMPLING=fDTS/16, N=5 + 10 + + + FDTS_Div16_N6 + fSAMPLING=fDTS/16, N=6 + 11 + + + FDTS_Div16_N8 + fSAMPLING=fDTS/16, N=8 + 12 + + + FDTS_Div32_N5 + fSAMPLING=fDTS/32, N=5 + 13 + + + FDTS_Div32_N6 + fSAMPLING=fDTS/32, N=6 + 14 + + + FDTS_Div32_N8 + fSAMPLING=fDTS/32, N=8 + 15 + + + + + IC1PSC + Input capture 1 prescaler + 2 + 2 + + + CC1S + Capture/Compare 1 + selection + 0 + 2 + + CC1S + read-write + + TI1 + CC1 channel is configured as input, IC1 is mapped on TI1 + 1 + + + TI2 + CC1 channel is configured as input, IC1 is mapped on TI2 + 2 + + + TRC + CC1 channel is configured as input, IC1 is mapped on TRC + 3 + + + + + + + CCMR2_Output + CCMR2_Output + capture/compare mode register 2 (output + mode) + 0x1C + 0x20 + read-write + 0x00000000 + + + OC4CE + O24CE + 15 + 1 + + + OC4M + OC4M + 12 + 3 + + + + OC4PE + OC4PE + 11 + 1 + + OC4PE + read-write + + Disabled + Preload register on CCR4 disabled. New values written to CCR4 are taken into account immediately + 0 + + + Enabled + Preload register on CCR4 enabled. Preload value is loaded into active register on each update event + 1 + + + + + OC4FE + OC4FE + 10 + 1 + + + CC4S + CC4S + 8 + 2 + + CC4S + read-write + + Output + CC4 channel is configured as output + 0 + + + + + OC3CE + OC3CE + 7 + 1 + + + OC3M + OC3M + 4 + 3 + + OC3M + read-write + + Frozen + The comparison between the output compare register TIMx_CCRy and the counter TIMx_CNT has no effect on the outputs + 0 + + + ActiveOnMatch + Set channel to active level on match. OCyREF signal is forced high when the counter matches the capture/compare register + 1 + + + InactiveOnMatch + Set channel to inactive level on match. OCyREF signal is forced low when the counter matches the capture/compare register + 2 + + + Toggle + OCyREF toggles when TIMx_CNT=TIMx_CCRy + 3 + + + ForceInactive + OCyREF is forced low + 4 + + + ForceActive + OCyREF is forced high + 5 + + + PwmMode1 + In upcounting, channel is active as long as TIMx_CNT<TIMx_CCRy else inactive. In downcounting, channel is inactive as long as TIMx_CNT>TIMx_CCRy else active + 6 + + + PwmMode2 + Inversely to PwmMode1 + 7 + + + + + OC3PE + OC3PE + 3 + 1 + + OC3PE + read-write + + Disabled + Preload register on CCR3 disabled. New values written to CCR3 are taken into account immediately + 0 + + + Enabled + Preload register on CCR3 enabled. Preload value is loaded into active register on each update event + 1 + + + + + OC3FE + OC3FE + 2 + 1 + + + CC3S + CC3S + 0 + 2 + + CC3S + read-write + + Output + CC3 channel is configured as output + 0 + + + + + + + CCMR2_Input + CCMR2_Input + capture/compare mode register 2 (input + mode) + CCMR2_Output + 0x1C + 0x20 + read-write + 0x00000000 + + + IC4F + Input capture 4 filter + 12 + 4 + + + 0 + 15 + + + + + IC4PSC + Input capture 4 prescaler + 10 + 2 + + + 0 + 3 + + + + + CC4S + Capture/Compare 4 + selection + 8 + 2 + + CC4S + read-write + + TI4 + CC4 channel is configured as input, IC4 is mapped on TI4 + 1 + + + TI3 + CC4 channel is configured as input, IC4 is mapped on TI3 + 2 + + + TRC + CC4 channel is configured as input, IC4 is mapped on TRC + 3 + + + + + IC3F + Input capture 3 filter + 4 + 4 + + + 0 + 15 + + + + + IC3PSC + Input capture 3 prescaler + 2 + 2 + + + 0 + 3 + + + + + CC3S + Capture/compare 3 + selection + 0 + 2 + + CC3S + read-write + + TI3 + CC3 channel is configured as input, IC3 is mapped on TI3 + 1 + + + TI4 + CC3 channel is configured as input, IC3 is mapped on TI4 + 2 + + + TRC + CC3 channel is configured as input, IC3 is mapped on TRC + 3 + + + + + + + CCER + CCER + capture/compare enable + register + 0x20 + 0x20 + read-write + 0x00000000 + + + CC4NP + Capture/Compare 4 output + Polarity + 15 + 1 + + + CC4P + Capture/Compare 3 output + Polarity + 13 + 1 + + + CC4E + Capture/Compare 4 output + enable + 12 + 1 + + + CC3NP + Capture/Compare 3 output + Polarity + 11 + 1 + + + CC3P + Capture/Compare 3 output + Polarity + 9 + 1 + + + CC3E + Capture/Compare 3 output + enable + 8 + 1 + + + CC2NP + Capture/Compare 2 output + Polarity + 7 + 1 + + + CC2P + Capture/Compare 2 output + Polarity + 5 + 1 + + + CC2E + Capture/Compare 2 output + enable + 4 + 1 + + + CC1NP + Capture/Compare 1 output + Polarity + 3 + 1 + + + CC1P + Capture/Compare 1 output + Polarity + 1 + 1 + + + CC1E + Capture/Compare 1 output + enable + 0 + 1 + + + + + CNT + CNT + counter + 0x24 + 0x20 + read-write + 0x00000000 + + + CNT + Counter value + 0 + 16 + + + 0 + 65535 + + + + + + + PSC + PSC + prescaler + 0x28 + 0x20 + read-write + 0x00000000 + + + PSC + Prescaler value + 0 + 16 + + + 0 + 65535 + + + + + + + ARR + ARR + auto-reload register + 0x2C + 0x20 + read-write + 0x00000000 + + + ARR + Auto-reload value + 0 + 16 + + + 0 + 65535 + + + + + + + 4 + 0x4 + 1-4 + CCR%s + CCR1 + capture/compare register + 0x34 + 0x20 + read-write + 0x00000000 + + + CCR + Capture/Compare value + 0 + 16 + + + 0 + 65535 + + + + + + + DCR + DCR + DMA control register + 0x48 + 0x20 + read-write + 0x00000000 + + + DBL + DMA burst length + 8 + 5 + + + 0 + 18 + + + + + DBA + DMA base address + 0 + 5 + + + 0 + 31 + + + + + + + DMAR + DMAR + DMA address for full transfer + 0x4C + 0x20 + read-write + 0x00000000 + + + DMAB + DMA register for burst + accesses + 0 + 16 + + + + + + + TIM4 + TIM + 0x40000800 + + + TIM5 + General-purpose-timers + TIM + 0x40000C00 + + 0x0 + 0x400 + registers + + + + CR1 + CR1 + control register 1 + 0x0 + 0x20 + read-write + 0x00000000 + + + CKD + Clock division + 8 + 2 + + CKD + read-write + + Div1 + t_DTS = t_CK_INT + 0 + + + Div2 + t_DTS = 2 × t_CK_INT + 1 + + + Div4 + t_DTS = 4 × t_CK_INT + 2 + + + + + ARPE + Auto-reload preload enable + 7 + 1 + + ARPE + read-write + + Disabled + TIMx_APRR register is not buffered + 0 + + + Enabled + TIMx_APRR register is buffered + 1 + + + + + CMS + Center-aligned mode + selection + 5 + 2 + + CMS + read-write + + EdgeAligned + The counter counts up or down depending on the direction bit + 0 + + + CenterAligned1 + The counter counts up and down alternatively. Output compare interrupt flags are set only when the counter is counting down. + 1 + + + CenterAligned2 + The counter counts up and down alternatively. Output compare interrupt flags are set only when the counter is counting up. + 2 + + + CenterAligned3 + The counter counts up and down alternatively. Output compare interrupt flags are set both when the counter is counting up or down. + 3 + + + + + DIR + Direction + 4 + 1 + + DIR + read-write + + Up + Counter used as upcounter + 0 + + + Down + Counter used as downcounter + 1 + + + + + OPM + One-pulse mode + 3 + 1 + + OPM + read-write + + Disabled + Counter is not stopped at update event + 0 + + + Enabled + Counter stops counting at the next update event (clearing the CEN bit) + 1 + + + + + URS + Update request source + 2 + 1 + + URS + read-write + + AnyEvent + Any of counter overflow/underflow, setting UG, or update through slave mode, generates an update interrupt or DMA request + 0 + + + CounterOnly + Only counter overflow/underflow generates an update interrupt or DMA request + 1 + + + + + UDIS + Update disable + 1 + 1 + + UDIS + read-write + + Enabled + Update event enabled + 0 + + + Disabled + Update event disabled + 1 + + + + + CEN + Counter enable + 0 + 1 + + CEN + read-write + + Disabled + Counter disabled + 0 + + + Enabled + Counter enabled + 1 + + + + + + + CR2 + CR2 + control register 2 + 0x4 + 0x20 + read-write + 0x00000000 + + + TI1S + TI1 selection + 7 + 1 + + TI1S + read-write + + Normal + The TIMx_CH1 pin is connected to TI1 input + 0 + + + XOR + The TIMx_CH1, CH2, CH3 pins are connected to TI1 input + 1 + + + + + MMS + Master mode selection + 4 + 3 + + MMS + read-write + + Reset + The UG bit from the TIMx_EGR register is used as trigger output + 0 + + + Enable + The counter enable signal, CNT_EN, is used as trigger output + 1 + + + Update + The update event is selected as trigger output + 2 + + + ComparePulse + The trigger output send a positive pulse when the CC1IF flag it to be set, as soon as a capture or a compare match occurred + 3 + + + CompareOC1 + OC1REF signal is used as trigger output + 4 + + + CompareOC2 + OC2REF signal is used as trigger output + 5 + + + CompareOC3 + OC3REF signal is used as trigger output + 6 + + + CompareOC4 + OC4REF signal is used as trigger output + 7 + + + + + CCDS + Capture/compare DMA + selection + 3 + 1 + + CCDS + read-write + + OnCompare + CCx DMA request sent when CCx event occurs + 0 + + + OnUpdate + CCx DMA request sent when update event occurs + 1 + + + + + + + SMCR + SMCR + slave mode control register + 0x8 + 0x20 + read-write + 0x00000000 + + + ETP + External trigger polarity + 15 + 1 + + ETP + read-write + + NotInverted + ETR is noninverted, active at high level or rising edge + 0 + + + Inverted + ETR is inverted, active at low level or falling edge + 1 + + + + + ECE + External clock enable + 14 + 1 + + ECE + read-write + + Disabled + External clock mode 2 disabled + 0 + + + Enabled + External clock mode 2 enabled. The counter is clocked by any active edge on the ETRF signal. + 1 + + + + + ETPS + External trigger prescaler + 12 + 2 + + ETPS + read-write + + Div1 + Prescaler OFF + 0 + + + Div2 + ETRP frequency divided by 2 + 1 + + + Div4 + ETRP frequency divided by 4 + 2 + + + Div8 + ETRP frequency divided by 8 + 3 + + + + + ETF + External trigger filter + 8 + 4 + + ETF + read-write + + NoFilter + No filter, sampling is done at fDTS + 0 + + + FCK_INT_N2 + fSAMPLING=fCK_INT, N=2 + 1 + + + FCK_INT_N4 + fSAMPLING=fCK_INT, N=4 + 2 + + + FCK_INT_N8 + fSAMPLING=fCK_INT, N=8 + 3 + + + FDTS_Div2_N6 + fSAMPLING=fDTS/2, N=6 + 4 + + + FDTS_Div2_N8 + fSAMPLING=fDTS/2, N=8 + 5 + + + FDTS_Div4_N6 + fSAMPLING=fDTS/4, N=6 + 6 + + + FDTS_Div4_N8 + fSAMPLING=fDTS/4, N=8 + 7 + + + FDTS_Div8_N6 + fSAMPLING=fDTS/8, N=6 + 8 + + + FDTS_Div8_N8 + fSAMPLING=fDTS/8, N=8 + 9 + + + FDTS_Div16_N5 + fSAMPLING=fDTS/16, N=5 + 10 + + + FDTS_Div16_N6 + fSAMPLING=fDTS/16, N=6 + 11 + + + FDTS_Div16_N8 + fSAMPLING=fDTS/16, N=8 + 12 + + + FDTS_Div32_N5 + fSAMPLING=fDTS/32, N=5 + 13 + + + FDTS_Div32_N6 + fSAMPLING=fDTS/32, N=6 + 14 + + + FDTS_Div32_N8 + fSAMPLING=fDTS/32, N=8 + 15 + + + + + MSM + Master/Slave mode + 7 + 1 + + MSM + read-write + + NoSync + No action + 0 + + + Sync + The effect of an event on the trigger input (TRGI) is delayed to allow a perfect synchronization between the current timer and its slaves (through TRGO). It is useful if we want to synchronize several timers on a single external event. + 1 + + + + + TS + Trigger selection + 4 + 3 + + TS + read-write + + ITR0 + Internal Trigger 0 (ITR0) + 0 + + + ITR1 + Internal Trigger 1 (ITR1) + 1 + + + ITR2 + Internal Trigger 2 (ITR2) + 2 + + + TI1F_ED + TI1 Edge Detector (TI1F_ED) + 4 + + + TI1FP1 + Filtered Timer Input 1 (TI1FP1) + 5 + + + TI2FP2 + Filtered Timer Input 2 (TI2FP2) + 6 + + + ETRF + External Trigger input (ETRF) + 7 + + + + + SMS + Slave mode selection + 0 + 3 + + SMS + read-write + + Disabled + Slave mode disabled - if CEN = ‘1 then the prescaler is clocked directly by the internal clock. + 0 + + + Encoder_Mode_1 + Encoder mode 1 - Counter counts up/down on TI2FP1 edge depending on TI1FP2 level. + 1 + + + Encoder_Mode_2 + Encoder mode 2 - Counter counts up/down on TI1FP2 edge depending on TI2FP1 level. + 2 + + + Encoder_Mode_3 + Encoder mode 3 - Counter counts up/down on both TI1FP1 and TI2FP2 edges depending on the level of the other input. + 3 + + + Reset_Mode + Reset Mode - Rising edge of the selected trigger input (TRGI) reinitializes the counter and generates an update of the registers. + 4 + + + Gated_Mode + Gated Mode - The counter clock is enabled when the trigger input (TRGI) is high. The counter stops (but is not reset) as soon as the trigger becomes low. Both start and stop of the counter are controlled. + 5 + + + Trigger_Mode + Trigger Mode - The counter starts at a rising edge of the trigger TRGI (but it is not reset). Only the start of the counter is controlled. + 6 + + + Ext_Clock_Mode + External Clock Mode 1 - Rising edges of the selected trigger (TRGI) clock the counter. + 7 + + + + + + + DIER + DIER + DMA/Interrupt enable register + 0xC + 0x20 + read-write + 0x00000000 + + + TDE + Trigger DMA request enable + 14 + 1 + + TDE + read-write + + Disabled + Trigger DMA request disabled + 0 + + + Enabled + Trigger DMA request enabled + 1 + + + + + CC4DE + Capture/Compare 4 DMA request + enable + 12 + 1 + + + + CC3DE + Capture/Compare 3 DMA request + enable + 11 + 1 + + + + CC2DE + Capture/Compare 2 DMA request + enable + 10 + 1 + + + + CC1DE + Capture/Compare 1 DMA request + enable + 9 + 1 + + CC1DE + read-write + + Disabled + CCx DMA request disabled + 0 + + + Enabled + CCx DMA request enabled + 1 + + + + + UDE + Update DMA request enable + 8 + 1 + + UDE + read-write + + Disabled + Update DMA request disabled + 0 + + + Enabled + Update DMA request enabled + 1 + + + + + TIE + Trigger interrupt enable + 6 + 1 + + TIE + read-write + + Disabled + Trigger interrupt disabled + 0 + + + Enabled + Trigger interrupt enabled + 1 + + + + + CC4IE + Capture/Compare 4 interrupt + enable + 4 + 1 + + + + CC3IE + Capture/Compare 3 interrupt + enable + 3 + 1 + + + + CC2IE + Capture/Compare 2 interrupt + enable + 2 + 1 + + + + CC1IE + Capture/Compare 1 interrupt + enable + 1 + 1 + + CC1IE + read-write + + Disabled + CCx interrupt disabled + 0 + + + Enabled + CCx interrupt enabled + 1 + + + + + UIE + Update interrupt enable + 0 + 1 + + UIE + read-write + + Disabled + Update interrupt disabled + 0 + + + Enabled + Update interrupt enabled + 1 + + + + + + + SR + SR + status register + 0x10 + 0x20 + read-write + 0x00000000 + + + CC4OF + Capture/Compare 4 overcapture + flag + 12 + 1 + zeroToClear + + read + + + write + + + + CC3OF + Capture/Compare 3 overcapture + flag + 11 + 1 + zeroToClear + + read + + + write + + + + CC2OF + Capture/compare 2 overcapture + flag + 10 + 1 + zeroToClear + + read + + + write + + + + CC1OF + Capture/Compare 1 overcapture + flag + 9 + 1 + zeroToClear + + CC1OFR + read + + Overcapture + The counter value has been captured in TIMx_CCRx register while CCxIF flag was already set + 1 + + + + CC1OFW + write + + Clear + Clear flag + 0 + + + + + TIF + Trigger interrupt flag + 6 + 1 + zeroToClear + + TIFR + read + + NoTrigger + No trigger event occurred + 0 + + + Trigger + Trigger interrupt pending + 1 + + + + TIFW + write + + Clear + Clear flag + 0 + + + + + CC4IF + Capture/Compare 4 interrupt + flag + 4 + 1 + zeroToClear + + read + + + write + + + + CC3IF + Capture/Compare 3 interrupt + flag + 3 + 1 + zeroToClear + + read + + + write + + + + CC2IF + Capture/Compare 2 interrupt + flag + 2 + 1 + zeroToClear + + read + + + write + + + + CC1IF + Capture/compare 1 interrupt + flag + 1 + 1 + zeroToClear + + CC1IFR + read + + Match + If CC1 is an output: The content of the counter TIMx_CNT matches the content of the TIMx_CCR1 register. If CC1 is an input: The counter value has been captured in TIMx_CCR1 register. + 1 + + + + CC1IFW + write + + Clear + Clear flag + 0 + + + + + UIF + Update interrupt flag + 0 + 1 + zeroToClear + + UIFR + read + + NoUpdateOccurred + No update occurred + 0 + + + UpdatePending + Update interrupt pending + 1 + + + + UIFW + write + + Clear + Clear flag + 0 + + + + + + + EGR + EGR + event generation register + 0x14 + 0x20 + write-only + 0x00000000 + + + TG + Trigger generation + 6 + 1 + + TGW + write + + Trigger + The TIF flag is set in TIMx_SR register. Related interrupt or DMA transfer can occur if enabled. + 1 + + + + + CC4G + Capture/compare 4 + generation + 4 + 1 + + + + CC3G + Capture/compare 3 + generation + 3 + 1 + + + + CC2G + Capture/compare 2 + generation + 2 + 1 + + + + CC1G + Capture/compare 1 + generation + 1 + 1 + + CC1GW + write + + Trigger + If CC1 is an output: CC1IF flag is set, Corresponding interrupt or DMA request is sent if enabled. If CC1 is an input: The current value of the counter is captured in TIMx_CCR1 register. + 1 + + + + + UG + Update generation + 0 + 1 + + UG + write + + Update + Re-initializes the timer counter and generates an update of the registers. + 1 + + + + + + + CCMR1_Output + CCMR1_Output + capture/compare mode register 1 (output + mode) + 0x18 + 0x20 + read-write + 0x00000000 + + + OC2CE + OC2CE + 15 + 1 + + + OC2M + OC2M + 12 + 3 + + + + OC2PE + OC2PE + 11 + 1 + + OC2PE + read-write + + Disabled + Preload register on CCR2 disabled. New values written to CCR2 are taken into account immediately + 0 + + + Enabled + Preload register on CCR2 enabled. Preload value is loaded into active register on each update event + 1 + + + + + OC2FE + OC2FE + 10 + 1 + + + CC2S + CC2S + 8 + 2 + + CC2S + read-write + + Output + CC2 channel is configured as output + 0 + + + + + OC1CE + OC1CE + 7 + 1 + + + OC1M + OC1M + 4 + 3 + + OC1M + read-write + + Frozen + The comparison between the output compare register TIMx_CCRy and the counter TIMx_CNT has no effect on the outputs + 0 + + + ActiveOnMatch + Set channel to active level on match. OCyREF signal is forced high when the counter matches the capture/compare register + 1 + + + InactiveOnMatch + Set channel to inactive level on match. OCyREF signal is forced low when the counter matches the capture/compare register + 2 + + + Toggle + OCyREF toggles when TIMx_CNT=TIMx_CCRy + 3 + + + ForceInactive + OCyREF is forced low + 4 + + + ForceActive + OCyREF is forced high + 5 + + + PwmMode1 + In upcounting, channel is active as long as TIMx_CNT<TIMx_CCRy else inactive. In downcounting, channel is inactive as long as TIMx_CNT>TIMx_CCRy else active + 6 + + + PwmMode2 + Inversely to PwmMode1 + 7 + + + + + OC1PE + OC1PE + 3 + 1 + + OC1PE + read-write + + Disabled + Preload register on CCR1 disabled. New values written to CCR1 are taken into account immediately + 0 + + + Enabled + Preload register on CCR1 enabled. Preload value is loaded into active register on each update event + 1 + + + + + OC1FE + OC1FE + 2 + 1 + + + CC1S + CC1S + 0 + 2 + + CC1S + read-write + + Output + CC1 channel is configured as output + 0 + + + + + + + CCMR1_Input + CCMR1_Input + capture/compare mode register 1 (input + mode) + CCMR1_Output + 0x18 + 0x20 + read-write + 0x00000000 + + + IC2F + Input capture 2 filter + 12 + 4 + + + 0 + 15 + + + + + IC2PSC + Input capture 2 prescaler + 10 + 2 + + + CC2S + Capture/Compare 2 + selection + 8 + 2 + + CC2S + read-write + + TI2 + CC2 channel is configured as input, IC2 is mapped on TI2 + 1 + + + TI1 + CC2 channel is configured as input, IC2 is mapped on TI1 + 2 + + + TRC + CC2 channel is configured as input, IC2 is mapped on TRC + 3 + + + + + IC1F + Input capture 1 filter + 4 + 4 + + IC1F + read-write + + NoFilter + No filter, sampling is done at fDTS + 0 + + + FCK_INT_N2 + fSAMPLING=fCK_INT, N=2 + 1 + + + FCK_INT_N4 + fSAMPLING=fCK_INT, N=4 + 2 + + + FCK_INT_N8 + fSAMPLING=fCK_INT, N=8 + 3 + + + FDTS_Div2_N6 + fSAMPLING=fDTS/2, N=6 + 4 + + + FDTS_Div2_N8 + fSAMPLING=fDTS/2, N=8 + 5 + + + FDTS_Div4_N6 + fSAMPLING=fDTS/4, N=6 + 6 + + + FDTS_Div4_N8 + fSAMPLING=fDTS/4, N=8 + 7 + + + FDTS_Div8_N6 + fSAMPLING=fDTS/8, N=6 + 8 + + + FDTS_Div8_N8 + fSAMPLING=fDTS/8, N=8 + 9 + + + FDTS_Div16_N5 + fSAMPLING=fDTS/16, N=5 + 10 + + + FDTS_Div16_N6 + fSAMPLING=fDTS/16, N=6 + 11 + + + FDTS_Div16_N8 + fSAMPLING=fDTS/16, N=8 + 12 + + + FDTS_Div32_N5 + fSAMPLING=fDTS/32, N=5 + 13 + + + FDTS_Div32_N6 + fSAMPLING=fDTS/32, N=6 + 14 + + + FDTS_Div32_N8 + fSAMPLING=fDTS/32, N=8 + 15 + + + + + IC1PSC + Input capture 1 prescaler + 2 + 2 + + + CC1S + Capture/Compare 1 + selection + 0 + 2 + + CC1S + read-write + + TI1 + CC1 channel is configured as input, IC1 is mapped on TI1 + 1 + + + TI2 + CC1 channel is configured as input, IC1 is mapped on TI2 + 2 + + + TRC + CC1 channel is configured as input, IC1 is mapped on TRC + 3 + + + + + + + CCMR2_Output + CCMR2_Output + capture/compare mode register 2 (output + mode) + 0x1C + 0x20 + read-write + 0x00000000 + + + OC4CE + O24CE + 15 + 1 + + + OC4M + OC4M + 12 + 3 + + + + OC4PE + OC4PE + 11 + 1 + + OC4PE + read-write + + Disabled + Preload register on CCR4 disabled. New values written to CCR4 are taken into account immediately + 0 + + + Enabled + Preload register on CCR4 enabled. Preload value is loaded into active register on each update event + 1 + + + + + OC4FE + OC4FE + 10 + 1 + + + CC4S + CC4S + 8 + 2 + + CC4S + read-write + + Output + CC4 channel is configured as output + 0 + + + + + OC3CE + OC3CE + 7 + 1 + + + OC3M + OC3M + 4 + 3 + + OC3M + read-write + + Frozen + The comparison between the output compare register TIMx_CCRy and the counter TIMx_CNT has no effect on the outputs + 0 + + + ActiveOnMatch + Set channel to active level on match. OCyREF signal is forced high when the counter matches the capture/compare register + 1 + + + InactiveOnMatch + Set channel to inactive level on match. OCyREF signal is forced low when the counter matches the capture/compare register + 2 + + + Toggle + OCyREF toggles when TIMx_CNT=TIMx_CCRy + 3 + + + ForceInactive + OCyREF is forced low + 4 + + + ForceActive + OCyREF is forced high + 5 + + + PwmMode1 + In upcounting, channel is active as long as TIMx_CNT<TIMx_CCRy else inactive. In downcounting, channel is inactive as long as TIMx_CNT>TIMx_CCRy else active + 6 + + + PwmMode2 + Inversely to PwmMode1 + 7 + + + + + OC3PE + OC3PE + 3 + 1 + + OC3PE + read-write + + Disabled + Preload register on CCR3 disabled. New values written to CCR3 are taken into account immediately + 0 + + + Enabled + Preload register on CCR3 enabled. Preload value is loaded into active register on each update event + 1 + + + + + OC3FE + OC3FE + 2 + 1 + + + CC3S + CC3S + 0 + 2 + + CC3S + read-write + + Output + CC3 channel is configured as output + 0 + + + + + + + CCMR2_Input + CCMR2_Input + capture/compare mode register 2 (input + mode) + CCMR2_Output + 0x1C + 0x20 + read-write + 0x00000000 + + + IC4F + Input capture 4 filter + 12 + 4 + + + 0 + 15 + + + + + IC4PSC + Input capture 4 prescaler + 10 + 2 + + + 0 + 3 + + + + + CC4S + Capture/Compare 4 + selection + 8 + 2 + + CC4S + read-write + + TI4 + CC4 channel is configured as input, IC4 is mapped on TI4 + 1 + + + TI3 + CC4 channel is configured as input, IC4 is mapped on TI3 + 2 + + + TRC + CC4 channel is configured as input, IC4 is mapped on TRC + 3 + + + + + IC3F + Input capture 3 filter + 4 + 4 + + + 0 + 15 + + + + + IC3PSC + Input capture 3 prescaler + 2 + 2 + + + 0 + 3 + + + + + CC3S + Capture/compare 3 + selection + 0 + 2 + + CC3S + read-write + + TI3 + CC3 channel is configured as input, IC3 is mapped on TI3 + 1 + + + TI4 + CC3 channel is configured as input, IC3 is mapped on TI4 + 2 + + + TRC + CC3 channel is configured as input, IC3 is mapped on TRC + 3 + + + + + + + CCER + CCER + capture/compare enable + register + 0x20 + 0x20 + read-write + 0x00000000 + + + CC4NP + Capture/Compare 4 output + Polarity + 15 + 1 + + + CC4P + Capture/Compare 3 output + Polarity + 13 + 1 + + + CC4E + Capture/Compare 4 output + enable + 12 + 1 + + + CC3NP + Capture/Compare 3 output + Polarity + 11 + 1 + + + CC3P + Capture/Compare 3 output + Polarity + 9 + 1 + + + CC3E + Capture/Compare 3 output + enable + 8 + 1 + + + CC2NP + Capture/Compare 2 output + Polarity + 7 + 1 + + + CC2P + Capture/Compare 2 output + Polarity + 5 + 1 + + + CC2E + Capture/Compare 2 output + enable + 4 + 1 + + + CC1NP + Capture/Compare 1 output + Polarity + 3 + 1 + + + CC1P + Capture/Compare 1 output + Polarity + 1 + 1 + + + CC1E + Capture/Compare 1 output + enable + 0 + 1 + + + + + CNT + CNT + counter + 0x24 + 0x20 + read-write + 0x00000000 + + + CNT + Counter value + 0 + 32 + + + 0 + 4294967295 + + + + + + + PSC + PSC + prescaler + 0x28 + 0x20 + read-write + 0x00000000 + + + PSC + Prescaler value + 0 + 16 + + + 0 + 65535 + + + + + + + ARR + ARR + auto-reload register + 0x2C + 0x20 + read-write + 0x00000000 + + + ARR + Auto-reload value + 0 + 32 + + + 0 + 4294967295 + + + + + + + 4 + 0x4 + 1-4 + CCR%s + CCR1 + capture/compare register + 0x34 + 0x20 + read-write + 0x00000000 + + + CCR + Capture/Compare value + 0 + 32 + + + 0 + 4294967295 + + + + + + + DCR + DCR + DMA control register + 0x48 + 0x20 + read-write + 0x00000000 + + + DBL + DMA burst length + 8 + 5 + + + 0 + 18 + + + + + DBA + DMA base address + 0 + 5 + + + 0 + 31 + + + + + + + DMAR + DMAR + DMA address for full transfer + 0x4C + 0x20 + read-write + 0x00000000 + + + DMAB + DMA register for burst + accesses + 0 + 16 + + + + + OR + OR + TIM5 option register + 0x50 + 0x20 + read-write + 0x00000000 + + + IT4_RMP + Timer Input 4 remap + 6 + 2 + + + + + + + TIM9 + General purpose timers + TIM + 0x40014000 + + 0x0 + 0x400 + registers + + + + CR1 + CR1 + control register 1 + 0x0 + 0x20 + read-write + 0x00000000 + + + CKD + Clock division + 8 + 2 + + CKD + read-write + + Div1 + t_DTS = t_CK_INT + 0 + + + Div2 + t_DTS = 2 × t_CK_INT + 1 + + + Div4 + t_DTS = 4 × t_CK_INT + 2 + + + + + ARPE + Auto-reload preload enable + 7 + 1 + + ARPE + read-write + + Disabled + TIMx_APRR register is not buffered + 0 + + + Enabled + TIMx_APRR register is buffered + 1 + + + + + OPM + One-pulse mode + 3 + 1 + + OPM + read-write + + Disabled + Counter is not stopped at update event + 0 + + + Enabled + Counter stops counting at the next update event (clearing the CEN bit) + 1 + + + + + URS + Update request source + 2 + 1 + + URS + read-write + + AnyEvent + Any of counter overflow/underflow, setting UG, or update through slave mode, generates an update interrupt or DMA request + 0 + + + CounterOnly + Only counter overflow/underflow generates an update interrupt or DMA request + 1 + + + + + UDIS + Update disable + 1 + 1 + + UDIS + read-write + + Enabled + Update event enabled + 0 + + + Disabled + Update event disabled + 1 + + + + + CEN + Counter enable + 0 + 1 + + CEN + read-write + + Disabled + Counter disabled + 0 + + + Enabled + Counter enabled + 1 + + + + + + + CR2 + CR2 + control register 2 + 0x4 + 0x20 + read-write + 0x00000000 + + + MMS + Master mode selection + 4 + 3 + + + + + SMCR + SMCR + slave mode control register + 0x8 + 0x20 + read-write + 0x00000000 + + + MSM + Master/Slave mode + 7 + 1 + + + TS + Trigger selection + 4 + 3 + + + SMS + Slave mode selection + 0 + 3 + + + + + DIER + DIER + DMA/Interrupt enable register + 0xC + 0x20 + read-write + 0x00000000 + + + TIE + Trigger interrupt enable + 6 + 1 + + + CC2IE + Capture/Compare 2 interrupt + enable + 2 + 1 + + + CC1IE + Capture/Compare 1 interrupt + enable + 1 + 1 + + + UIE + Update interrupt enable + 0 + 1 + + UIE + read-write + + Disabled + Update interrupt disabled + 0 + + + Enabled + Update interrupt enabled + 1 + + + + + + + SR + SR + status register + 0x10 + 0x20 + read-write + 0x00000000 + + + CC2OF + Capture/compare 2 overcapture + flag + 10 + 1 + + + CC1OF + Capture/Compare 1 overcapture + flag + 9 + 1 + + + TIF + Trigger interrupt flag + 6 + 1 + + + CC2IF + Capture/Compare 2 interrupt + flag + 2 + 1 + + + CC1IF + Capture/compare 1 interrupt + flag + 1 + 1 + + + UIF + Update interrupt flag + 0 + 1 + zeroToClear + + UIFR + read + + NoUpdateOccurred + No update occurred + 0 + + + UpdatePending + Update interrupt pending + 1 + + + + UIFW + write + + Clear + Clear flag + 0 + + + + + + + EGR + EGR + event generation register + 0x14 + 0x20 + write-only + 0x00000000 + + + TG + Trigger generation + 6 + 1 + + + CC2G + Capture/compare 2 + generation + 2 + 1 + + + CC1G + Capture/compare 1 + generation + 1 + 1 + + + UG + Update generation + 0 + 1 + + UG + write + + Update + Re-initializes the timer counter and generates an update of the registers. + 1 + + + + + + + CCMR1_Output + CCMR1_Output + capture/compare mode register 1 (output + mode) + 0x18 + 0x20 + read-write + 0x00000000 + + + OC2M + Output Compare 2 mode + 12 + 3 + + + + OC2PE + Output Compare 2 preload + enable + 11 + 1 + + + OC2FE + Output Compare 2 fast + enable + 10 + 1 + + + CC2S + Capture/Compare 2 + selection + 8 + 2 + + + OC1M + Output Compare 1 mode + 4 + 3 + + OC1M + read-write + + Frozen + The comparison between the output compare register TIMx_CCRy and the counter TIMx_CNT has no effect on the outputs + 0 + + + ActiveOnMatch + Set channel to active level on match. OCyREF signal is forced high when the counter matches the capture/compare register + 1 + + + InactiveOnMatch + Set channel to inactive level on match. OCyREF signal is forced low when the counter matches the capture/compare register + 2 + + + Toggle + OCyREF toggles when TIMx_CNT=TIMx_CCRy + 3 + + + ForceInactive + OCyREF is forced low + 4 + + + ForceActive + OCyREF is forced high + 5 + + + PwmMode1 + In upcounting, channel is active as long as TIMx_CNT<TIMx_CCRy else inactive. In downcounting, channel is inactive as long as TIMx_CNT>TIMx_CCRy else active + 6 + + + PwmMode2 + Inversely to PwmMode1 + 7 + + + + + OC1PE + Output Compare 1 preload + enable + 3 + 1 + + + OC1FE + Output Compare 1 fast + enable + 2 + 1 + + + CC1S + Capture/Compare 1 + selection + 0 + 2 + + + + + CCMR1_Input + CCMR1_Input + capture/compare mode register 1 (input + mode) + CCMR1_Output + 0x18 + 0x20 + read-write + 0x00000000 + + + IC2F + Input capture 2 filter + 12 + 3 + + + IC2PSC + Input capture 2 prescaler + 10 + 2 + + + CC2S + Capture/Compare 2 + selection + 8 + 2 + + + IC1F + Input capture 1 filter + 4 + 3 + + + IC1PSC + Input capture 1 prescaler + 2 + 2 + + + CC1S + Capture/Compare 1 + selection + 0 + 2 + + + + + CCER + CCER + capture/compare enable + register + 0x20 + 0x20 + read-write + 0x00000000 + + + CC2NP + Capture/Compare 2 output + Polarity + 7 + 1 + + + CC2P + Capture/Compare 2 output + Polarity + 5 + 1 + + + CC2E + Capture/Compare 2 output + enable + 4 + 1 + + + CC1NP + Capture/Compare 1 output + Polarity + 3 + 1 + + + CC1P + Capture/Compare 1 output + Polarity + 1 + 1 + + + CC1E + Capture/Compare 1 output + enable + 0 + 1 + + + + + CNT + CNT + counter + 0x24 + 0x20 + read-write + 0x00000000 + + + CNT + counter value + 0 + 16 + + + + + PSC + PSC + prescaler + 0x28 + 0x20 + read-write + 0x00000000 + + + PSC + Prescaler value + 0 + 16 + + + 0 + 65535 + + + + + + + ARR + ARR + auto-reload register + 0x2C + 0x20 + read-write + 0x00000000 + + + ARR + Auto-reload value + 0 + 16 + + + + + 2 + 0x4 + 1-2 + CCR%s + CCR1 + capture/compare register + 0x34 + 0x20 + read-write + 0x00000000 + + + CCR + Capture/Compare value + 0 + 16 + + + + + + + USART1 + Universal synchronous asynchronous receiver + transmitter + USART + 0x40011000 + + 0x0 + 0x400 + registers + + + OTG_FS_WKUP + USB On-The-Go FS Wakeup through EXTI line + interrupt + 42 + + + OTG_FS + USB On The Go FS global + interrupt + 67 + + + USART1 + USART1 global interrupt + 37 + + + USART2 + USART2 global interrupt + 38 + + + USART6 + USART6 global interrupt + 71 + + + + SR + SR + Status register + 0x0 + 0x20 + 0x00C00000 + + + CTS + CTS flag + 9 + 1 + read-write + + + LBD + LIN break detection flag + 8 + 1 + read-write + + + TXE + Transmit data register + empty + 7 + 1 + read-only + + + TC + Transmission complete + 6 + 1 + read-write + + + RXNE + Read data register not + empty + 5 + 1 + read-write + + + IDLE + IDLE line detected + 4 + 1 + read-only + + + ORE + Overrun error + 3 + 1 + read-only + + + NF + Noise detected flag + 2 + 1 + read-only + + + FE + Framing error + 1 + 1 + read-only + + + PE + Parity error + 0 + 1 + read-only + + + + + DR + DR + Data register + 0x4 + 0x20 + read-write + 0x00000000 + + + DR + Data value + 0 + 9 + + + 0 + 511 + + + + + + + BRR + BRR + Baud rate register + 0x8 + 0x20 + read-write + 0x00000000 + + + DIV_Mantissa + mantissa of USARTDIV + 4 + 12 + + + 0 + 4095 + + + + + DIV_Fraction + fraction of USARTDIV + 0 + 4 + + + 0 + 15 + + + + + + + CR1 + CR1 + Control register 1 + 0xC + 0x20 + read-write + 0x00000000 + + + OVER8 + Oversampling mode + 15 + 1 + + OVER8 + read-write + + Oversample16 + Oversampling by 16 + 0 + + + Oversample8 + Oversampling by 8 + 1 + + + + + UE + USART enable + 13 + 1 + + UE + read-write + + Disabled + USART prescaler and outputs disabled + 0 + + + Enabled + USART enabled + 1 + + + + + M + Word length + 12 + 1 + + M + read-write + + M8 + 8 data bits + 0 + + + M9 + 9 data bits + 1 + + + + + WAKE + Wakeup method + 11 + 1 + + WAKE + read-write + + IdleLine + USART wakeup on idle line + 0 + + + AddressMark + USART wakeup on address mark + 1 + + + + + PCE + Parity control enable + 10 + 1 + + PCE + read-write + + Disabled + Parity control disabled + 0 + + + Enabled + Parity control enabled + 1 + + + + + PS + Parity selection + 9 + 1 + + PS + read-write + + Even + Even parity + 0 + + + Odd + Odd parity + 1 + + + + + PEIE + PE interrupt enable + 8 + 1 + + PEIE + read-write + + Disabled + PE interrupt disabled + 0 + + + Enabled + PE interrupt enabled + 1 + + + + + TXEIE + TXE interrupt enable + 7 + 1 + + TXEIE + read-write + + Disabled + TXE interrupt disabled + 0 + + + Enabled + TXE interrupt enabled + 1 + + + + + TCIE + Transmission complete interrupt + enable + 6 + 1 + + TCIE + read-write + + Disabled + TC interrupt disabled + 0 + + + Enabled + TC interrupt enabled + 1 + + + + + RXNEIE + RXNE interrupt enable + 5 + 1 + + RXNEIE + read-write + + Disabled + RXNE interrupt disabled + 0 + + + Enabled + RXNE interrupt enabled + 1 + + + + + IDLEIE + IDLE interrupt enable + 4 + 1 + + IDLEIE + read-write + + Disabled + IDLE interrupt disabled + 0 + + + Enabled + IDLE interrupt enabled + 1 + + + + + TE + Transmitter enable + 3 + 1 + + TE + read-write + + Disabled + Transmitter disabled + 0 + + + Enabled + Transmitter enabled + 1 + + + + + RE + Receiver enable + 2 + 1 + + RE + read-write + + Disabled + Receiver disabled + 0 + + + Enabled + Receiver enabled + 1 + + + + + RWU + Receiver wakeup + 1 + 1 + + RWU + read-write + + Active + Receiver in active mode + 0 + + + Mute + Receiver in mute mode + 1 + + + + + SBK + Send break + 0 + 1 + + SBK + read-write + + NoBreak + No break character is transmitted + 0 + + + Break + Break character transmitted + 1 + + + + + + + CR2 + CR2 + Control register 2 + 0x10 + 0x20 + read-write + 0x00000000 + + + LINEN + LIN mode enable + 14 + 1 + + LINEN + read-write + + Disabled + LIN mode disabled + 0 + + + Enabled + LIN mode enabled + 1 + + + + + STOP + STOP bits + 12 + 2 + + STOP + read-write + + Stop1 + 1 stop bit + 0 + + + Stop0p5 + 0.5 stop bits + 1 + + + Stop2 + 2 stop bits + 2 + + + Stop1p5 + 1.5 stop bits + 3 + + + + + CLKEN + Clock enable + 11 + 1 + + CLKEN + read-write + + Disabled + CK pin disabled + 0 + + + Enabled + CK pin enabled + 1 + + + + + CPOL + Clock polarity + 10 + 1 + + CPOL + read-write + + Low + Steady low value on CK pin outside transmission window + 0 + + + High + Steady high value on CK pin outside transmission window + 1 + + + + + CPHA + Clock phase + 9 + 1 + + CPHA + read-write + + First + The first clock transition is the first data capture edge + 0 + + + Second + The second clock transition is the first data capture edge + 1 + + + + + LBCL + Last bit clock pulse + 8 + 1 + + + LBDIE + LIN break detection interrupt + enable + 6 + 1 + + LBDIE + read-write + + Disabled + LIN break detection interrupt disabled + 0 + + + Enabled + LIN break detection interrupt enabled + 1 + + + + + LBDL + lin break detection length + 5 + 1 + + LBDL + read-write + + LBDL10 + 10-bit break detection + 0 + + + LBDL11 + 11-bit break detection + 1 + + + + + ADD + Address of the USART node + 0 + 4 + + + 0 + 15 + + + + + + + CR3 + CR3 + Control register 3 + 0x14 + 0x20 + read-write + 0x00000000 + + + ONEBIT + One sample bit method + enable + 11 + 1 + + ONEBIT + read-write + + Sample3 + Three sample bit method + 0 + + + Sample1 + One sample bit method + 1 + + + + + CTSIE + CTS interrupt enable + 10 + 1 + + CTSIE + read-write + + Disabled + CTS interrupt disabled + 0 + + + Enabled + CTS interrupt enabled + 1 + + + + + CTSE + CTS enable + 9 + 1 + + CTSE + read-write + + Disabled + CTS hardware flow control disabled + 0 + + + Enabled + CTS hardware flow control enabled + 1 + + + + + RTSE + RTS enable + 8 + 1 + + RTSE + read-write + + Disabled + RTS hardware flow control disabled + 0 + + + Enabled + RTS hardware flow control enabled + 1 + + + + + DMAT + DMA enable transmitter + 7 + 1 + + DMAT + read-write + + Disabled + DMA mode is disabled for transmission + 0 + + + Enabled + DMA mode is enabled for transmission + 1 + + + + + DMAR + DMA enable receiver + 6 + 1 + + DMAR + read-write + + Disabled + DMA mode is disabled for reception + 0 + + + Enabled + DMA mode is enabled for reception + 1 + + + + + SCEN + Smartcard mode enable + 5 + 1 + + SCEN + read-write + + Disabled + Smartcard mode disabled + 0 + + + Enabled + Smartcard mode enabled + 1 + + + + + NACK + Smartcard NACK enable + 4 + 1 + + NACK + read-write + + Disabled + NACK transmission in case of parity error is disabled + 0 + + + Enabled + NACK transmission during parity error is enabled + 1 + + + + + HDSEL + Half-duplex selection + 3 + 1 + + HDSEL + read-write + + FullDuplex + Half duplex mode is not selected + 0 + + + HalfDuplex + Half duplex mode is selected + 1 + + + + + IRLP + IrDA low-power + 2 + 1 + + IRLP + read-write + + Normal + Normal mode + 0 + + + LowPower + Low-power mode + 1 + + + + + IREN + IrDA mode enable + 1 + 1 + + IREN + read-write + + Disabled + IrDA disabled + 0 + + + Enabled + IrDA enabled + 1 + + + + + EIE + Error interrupt enable + 0 + 1 + + EIE + read-write + + Disabled + Error interrupt disabled + 0 + + + Enabled + Error interrupt enabled + 1 + + + + + + + GTPR + GTPR + Guard time and prescaler + register + 0x18 + 0x20 + read-write + 0x00000000 + + + GT + Guard time value + 8 + 8 + + + PSC + Prescaler value + 0 + 8 + + + + + + + USART2 + 0x40004400 + + + USART6 + 0x40011400 + + + WWDG + Window watchdog + WWDG + 0x40002C00 + + 0x0 + 0x400 + registers + + + PVD + PVD through EXTI line detection + interrupt + 1 + + + + CR + CR + Control register + 0x0 + 0x20 + read-write + 0x0000007F + + + WDGA + Activation bit + 7 + 1 + + WDGA + read-write + + Disabled + Watchdog disabled + 0 + + + Enabled + Watchdog enabled + 1 + + + + + T + 7-bit counter (MSB to LSB) + 0 + 7 + + + 0 + 127 + + + + + + + CFR + CFR + Configuration register + 0x4 + 0x20 + read-write + 0x0000007F + + + EWI + Early wakeup interrupt + 9 + 1 + + EWIW + write + + Enable + interrupt occurs whenever the counter reaches the value 0x40 + 1 + + + + + W + 7-bit window value + 0 + 7 + + + 0 + 127 + + + + + WDGTB + Timer base + 7 + 2 + + WDGTB + read-write + + Div1 + Counter clock (PCLK1 div 4096) div 1 + 0 + + + Div2 + Counter clock (PCLK1 div 4096) div 2 + 1 + + + Div4 + Counter clock (PCLK1 div 4096) div 4 + 2 + + + Div8 + Counter clock (PCLK1 div 4096) div 8 + 3 + + + + + + + SR + SR + Status register + 0x8 + 0x20 + read-write + 0x00000000 + + + EWIF + Early wakeup interrupt + flag + 0 + 1 + zeroToClear + + EWIFR + read + + Finished + The EWI Interrupt Service Routine has been serviced + 0 + + + Pending + The EWI Interrupt Service Routine has been triggered + 1 + + + + EWIFW + write + + Finished + The EWI Interrupt Service Routine has been serviced + 0 + + + + + + + + + DMA2 + DMA controller + DMA + 0x40026400 + + 0x0 + 0x400 + registers + + + RCC + RCC global interrupt + 5 + + + DMA1_STREAM0 + DMA1_STREAM0 global interrupt + 11 + + + DMA1_STREAM1 + DMA1_STREAM1 global interrupt + 12 + + + DMA1_STREAM2 + DMA1_STREAM2 global interrupt + 13 + + + DMA1_STREAM3 + DMA1_STREAM3 global interrupt + 14 + + + DMA1_STREAM4 + DMA1_STREAM4 global interrupt + 15 + + + DMA1_STREAM5 + DMA1_STREAM5 global interrupt + 16 + + + DMA1_STREAM6 + DMA1_STREAM6 global interrupt + 17 + + + DMA1_STREAM7 + DMA1_STREAM7 global interrupt + 47 + + + DMA2_STREAM0 + DMA2_STREAM0 global interrupt + 56 + + + DMA2_STREAM1 + DMA2_STREAM1 global interrupt + 57 + + + DMA2_STREAM2 + DMA2_STREAM2 global interrupt + 58 + + + DMA2_STREAM3 + DMA2_STREAM3 global interrupt + 59 + + + DMA2_STREAM4 + DMA2_STREAM4 global interrupt + 60 + + + DMA2_STREAM5 + DMA2_STREAM5 global interrupt + 68 + + + DMA2_STREAM6 + DMA2_STREAM6 global interrupt + 69 + + + DMA2_STREAM7 + DMA2_STREAM7 global interrupt + 70 + + + + LISR + LISR + low interrupt status register + 0x0 + 0x20 + read-only + 0x00000000 + + + TCIF3 + Stream x transfer complete interrupt + flag (x = 3..0) + 27 + 1 + + + + HTIF3 + Stream x half transfer interrupt flag + (x=3..0) + 26 + 1 + + + + TEIF3 + Stream x transfer error interrupt flag + (x=3..0) + 25 + 1 + + + + DMEIF3 + Stream x direct mode error interrupt + flag (x=3..0) + 24 + 1 + + + + FEIF3 + Stream x FIFO error interrupt flag + (x=3..0) + 22 + 1 + + + + TCIF2 + Stream x transfer complete interrupt + flag (x = 3..0) + 21 + 1 + + + + HTIF2 + Stream x half transfer interrupt flag + (x=3..0) + 20 + 1 + + + + TEIF2 + Stream x transfer error interrupt flag + (x=3..0) + 19 + 1 + + + + DMEIF2 + Stream x direct mode error interrupt + flag (x=3..0) + 18 + 1 + + + + FEIF2 + Stream x FIFO error interrupt flag + (x=3..0) + 16 + 1 + + + + TCIF1 + Stream x transfer complete interrupt + flag (x = 3..0) + 11 + 1 + + + + HTIF1 + Stream x half transfer interrupt flag + (x=3..0) + 10 + 1 + + + + TEIF1 + Stream x transfer error interrupt flag + (x=3..0) + 9 + 1 + + + + DMEIF1 + Stream x direct mode error interrupt + flag (x=3..0) + 8 + 1 + + + + FEIF1 + Stream x FIFO error interrupt flag + (x=3..0) + 6 + 1 + + + + TCIF0 + Stream x transfer complete interrupt + flag (x = 3..0) + 5 + 1 + + TCIF0 + read + + NotComplete + No transfer complete event on stream x + 0 + + + Complete + A transfer complete event occurred on stream x + 1 + + + + + HTIF0 + Stream x half transfer interrupt flag + (x=3..0) + 4 + 1 + + HTIF0 + read + + NotHalf + No half transfer event on stream x + 0 + + + Half + A half transfer event occurred on stream x + 1 + + + + + TEIF0 + Stream x transfer error interrupt flag + (x=3..0) + 3 + 1 + + TEIF0 + read + + NoError + No transfer error on stream x + 0 + + + Error + A transfer error occurred on stream x + 1 + + + + + DMEIF0 + Stream x direct mode error interrupt + flag (x=3..0) + 2 + 1 + + DMEIF0 + read + + NoError + No Direct Mode error on stream x + 0 + + + Error + A Direct Mode error occurred on stream x + 1 + + + + + FEIF0 + Stream x FIFO error interrupt flag + (x=3..0) + 0 + 1 + + FEIF0 + read + + NoError + No FIFO error event on stream x + 0 + + + Error + A FIFO error event occurred on stream x + 1 + + + + + + + HISR + HISR + high interrupt status register + 0x4 + 0x20 + read-only + 0x00000000 + + + TCIF7 + Stream x transfer complete interrupt + flag (x=7..4) + 27 + 1 + + + + HTIF7 + Stream x half transfer interrupt flag + (x=7..4) + 26 + 1 + + + + TEIF7 + Stream x transfer error interrupt flag + (x=7..4) + 25 + 1 + + + + DMEIF7 + Stream x direct mode error interrupt + flag (x=7..4) + 24 + 1 + + + + FEIF7 + Stream x FIFO error interrupt flag + (x=7..4) + 22 + 1 + + + + TCIF6 + Stream x transfer complete interrupt + flag (x=7..4) + 21 + 1 + + + + HTIF6 + Stream x half transfer interrupt flag + (x=7..4) + 20 + 1 + + + + TEIF6 + Stream x transfer error interrupt flag + (x=7..4) + 19 + 1 + + + + DMEIF6 + Stream x direct mode error interrupt + flag (x=7..4) + 18 + 1 + + + + FEIF6 + Stream x FIFO error interrupt flag + (x=7..4) + 16 + 1 + + + + TCIF5 + Stream x transfer complete interrupt + flag (x=7..4) + 11 + 1 + + + + HTIF5 + Stream x half transfer interrupt flag + (x=7..4) + 10 + 1 + + + + TEIF5 + Stream x transfer error interrupt flag + (x=7..4) + 9 + 1 + + + + DMEIF5 + Stream x direct mode error interrupt + flag (x=7..4) + 8 + 1 + + + + FEIF5 + Stream x FIFO error interrupt flag + (x=7..4) + 6 + 1 + + + + TCIF4 + Stream x transfer complete interrupt + flag (x=7..4) + 5 + 1 + + TCIF4 + read + + NotComplete + No transfer complete event on stream x + 0 + + + Complete + A transfer complete event occurred on stream x + 1 + + + + + HTIF4 + Stream x half transfer interrupt flag + (x=7..4) + 4 + 1 + + HTIF4 + read + + NotHalf + No half transfer event on stream x + 0 + + + Half + A half transfer event occurred on stream x + 1 + + + + + TEIF4 + Stream x transfer error interrupt flag + (x=7..4) + 3 + 1 + + TEIF4 + read + + NoError + No transfer error on stream x + 0 + + + Error + A transfer error occurred on stream x + 1 + + + + + DMEIF4 + Stream x direct mode error interrupt + flag (x=7..4) + 2 + 1 + + DMEIF4 + read + + NoError + No Direct Mode error on stream x + 0 + + + Error + A Direct Mode error occurred on stream x + 1 + + + + + FEIF4 + Stream x FIFO error interrupt flag + (x=7..4) + 0 + 1 + + FEIF4 + read + + NoError + No FIFO error event on stream x + 0 + + + Error + A FIFO error event occurred on stream x + 1 + + + + + + + LIFCR + LIFCR + low interrupt flag clear + register + 0x8 + 0x20 + write-only + 0x00000000 + + + CTCIF3 + Stream x clear transfer complete + interrupt flag (x = 3..0) + 27 + 1 + + + + CHTIF3 + Stream x clear half transfer interrupt + flag (x = 3..0) + 26 + 1 + + + + CTEIF3 + Stream x clear transfer error interrupt + flag (x = 3..0) + 25 + 1 + + + + CDMEIF3 + Stream x clear direct mode error + interrupt flag (x = 3..0) + 24 + 1 + + + + CFEIF3 + Stream x clear FIFO error interrupt flag + (x = 3..0) + 22 + 1 + + + + CTCIF2 + Stream x clear transfer complete + interrupt flag (x = 3..0) + 21 + 1 + + + + CHTIF2 + Stream x clear half transfer interrupt + flag (x = 3..0) + 20 + 1 + + + + CTEIF2 + Stream x clear transfer error interrupt + flag (x = 3..0) + 19 + 1 + + + + CDMEIF2 + Stream x clear direct mode error + interrupt flag (x = 3..0) + 18 + 1 + + + + CFEIF2 + Stream x clear FIFO error interrupt flag + (x = 3..0) + 16 + 1 + + + + CTCIF1 + Stream x clear transfer complete + interrupt flag (x = 3..0) + 11 + 1 + + + + CHTIF1 + Stream x clear half transfer interrupt + flag (x = 3..0) + 10 + 1 + + + + CTEIF1 + Stream x clear transfer error interrupt + flag (x = 3..0) + 9 + 1 + + + + CDMEIF1 + Stream x clear direct mode error + interrupt flag (x = 3..0) + 8 + 1 + + + + CFEIF1 + Stream x clear FIFO error interrupt flag + (x = 3..0) + 6 + 1 + + + + CTCIF0 + Stream x clear transfer complete + interrupt flag (x = 3..0) + 5 + 1 + + CTCIF0 + write + + Clear + Clear the corresponding TCIFx flag + 1 + + + + + CHTIF0 + Stream x clear half transfer interrupt + flag (x = 3..0) + 4 + 1 + + CHTIF0 + write + + Clear + Clear the corresponding HTIFx flag + 1 + + + + + CTEIF0 + Stream x clear transfer error interrupt + flag (x = 3..0) + 3 + 1 + + CTEIF0 + write + + Clear + Clear the corresponding TEIFx flag + 1 + + + + + CDMEIF0 + Stream x clear direct mode error + interrupt flag (x = 3..0) + 2 + 1 + + CDMEIF0 + write + + Clear + Clear the corresponding DMEIFx flag + 1 + + + + + CFEIF0 + Stream x clear FIFO error interrupt flag + (x = 3..0) + 0 + 1 + + CFEIF0 + write + + Clear + Clear the corresponding CFEIFx flag + 1 + + + + + + + HIFCR + HIFCR + high interrupt flag clear + register + 0xC + 0x20 + write-only + 0x00000000 + + + CTCIF7 + Stream x clear transfer complete + interrupt flag (x = 7..4) + 27 + 1 + + + + CHTIF7 + Stream x clear half transfer interrupt + flag (x = 7..4) + 26 + 1 + + + + CTEIF7 + Stream x clear transfer error interrupt + flag (x = 7..4) + 25 + 1 + + + + CDMEIF7 + Stream x clear direct mode error + interrupt flag (x = 7..4) + 24 + 1 + + + + CFEIF7 + Stream x clear FIFO error interrupt flag + (x = 7..4) + 22 + 1 + + + + CTCIF6 + Stream x clear transfer complete + interrupt flag (x = 7..4) + 21 + 1 + + + + CHTIF6 + Stream x clear half transfer interrupt + flag (x = 7..4) + 20 + 1 + + + + CTEIF6 + Stream x clear transfer error interrupt + flag (x = 7..4) + 19 + 1 + + + + CDMEIF6 + Stream x clear direct mode error + interrupt flag (x = 7..4) + 18 + 1 + + + + CFEIF6 + Stream x clear FIFO error interrupt flag + (x = 7..4) + 16 + 1 + + + + CTCIF5 + Stream x clear transfer complete + interrupt flag (x = 7..4) + 11 + 1 + + + + CHTIF5 + Stream x clear half transfer interrupt + flag (x = 7..4) + 10 + 1 + + + + CTEIF5 + Stream x clear transfer error interrupt + flag (x = 7..4) + 9 + 1 + + + + CDMEIF5 + Stream x clear direct mode error + interrupt flag (x = 7..4) + 8 + 1 + + + + CFEIF5 + Stream x clear FIFO error interrupt flag + (x = 7..4) + 6 + 1 + + + + CTCIF4 + Stream x clear transfer complete + interrupt flag (x = 7..4) + 5 + 1 + + CTCIF4 + write + + Clear + Clear the corresponding TCIFx flag + 1 + + + + + CHTIF4 + Stream x clear half transfer interrupt + flag (x = 7..4) + 4 + 1 + + CHTIF4 + write + + Clear + Clear the corresponding HTIFx flag + 1 + + + + + CTEIF4 + Stream x clear transfer error interrupt + flag (x = 7..4) + 3 + 1 + + CTEIF4 + write + + Clear + Clear the corresponding TEIFx flag + 1 + + + + + CDMEIF4 + Stream x clear direct mode error + interrupt flag (x = 7..4) + 2 + 1 + + CDMEIF4 + write + + Clear + Clear the corresponding DMEIFx flag + 1 + + + + + CFEIF4 + Stream x clear FIFO error interrupt flag + (x = 7..4) + 0 + 1 + + CFEIF4 + write + + Clear + Clear the corresponding CFEIFx flag + 1 + + + + + + + 8 + 0x18 + 0-7 + ST%s + Stream cluster: S?CR, S?NDTR, S?M0AR, S?M1AR and S?FCR registers + 0x10 + + CR + S0CR + stream x configuration + register + 0x0 + 0x20 + read-write + 0x00000000 + + + CHSEL + Channel selection + 25 + 3 + + + 0 + 7 + + + + + MBURST + Memory burst transfer + configuration + 23 + 2 + + + + PBURST + Peripheral burst transfer + configuration + 21 + 2 + + PBURST + read-write + + Single + Single transfer + 0 + + + INCR4 + Incremental burst of 4 beats + 1 + + + INCR8 + Incremental burst of 8 beats + 2 + + + INCR16 + Incremental burst of 16 beats + 3 + + + + + CT + Current target (only in double buffer + mode) + 19 + 1 + + CT + read-write + + Memory0 + The current target memory is Memory 0 + 0 + + + Memory1 + The current target memory is Memory 1 + 1 + + + + + DBM + Double buffer mode + 18 + 1 + + DBM + read-write + + Disabled + No buffer switching at the end of transfer + 0 + + + Enabled + Memory target switched at the end of the DMA transfer + 1 + + + + + PL + Priority level + 16 + 2 + + PL + read-write + + Low + Low + 0 + + + Medium + Medium + 1 + + + High + High + 2 + + + VeryHigh + Very high + 3 + + + + + PINCOS + Peripheral increment offset + size + 15 + 1 + + PINCOS + read-write + + PSIZE + The offset size for the peripheral address calculation is linked to the PSIZE + 0 + + + Fixed4 + The offset size for the peripheral address calculation is fixed to 4 (32-bit alignment) + 1 + + + + + MSIZE + Memory data size + 13 + 2 + + + + PSIZE + Peripheral data size + 11 + 2 + + PSIZE + read-write + + Bits8 + Byte (8-bit) + 0 + + + Bits16 + Half-word (16-bit) + 1 + + + Bits32 + Word (32-bit) + 2 + + + + + MINC + Memory increment mode + 10 + 1 + + + + PINC + Peripheral increment mode + 9 + 1 + + PINC + read-write + + Fixed + Address pointer is fixed + 0 + + + Incremented + Address pointer is incremented after each data transfer + 1 + + + + + CIRC + Circular mode + 8 + 1 + + CIRC + read-write + + Disabled + Circular mode disabled + 0 + + + Enabled + Circular mode enabled + 1 + + + + + DIR + Data transfer direction + 6 + 2 + + DIR + read-write + + PeripheralToMemory + Peripheral-to-memory + 0 + + + MemoryToPeripheral + Memory-to-peripheral + 1 + + + MemoryToMemory + Memory-to-memory + 2 + + + + + PFCTRL + Peripheral flow controller + 5 + 1 + + PFCTRL + read-write + + DMA + The DMA is the flow controller + 0 + + + Peripheral + The peripheral is the flow controller + 1 + + + + + TCIE + Transfer complete interrupt + enable + 4 + 1 + + TCIE + read-write + + Disabled + TC interrupt disabled + 0 + + + Enabled + TC interrupt enabled + 1 + + + + + HTIE + Half transfer interrupt + enable + 3 + 1 + + HTIE + read-write + + Disabled + HT interrupt disabled + 0 + + + Enabled + HT interrupt enabled + 1 + + + + + TEIE + Transfer error interrupt + enable + 2 + 1 + + TEIE + read-write + + Disabled + TE interrupt disabled + 0 + + + Enabled + TE interrupt enabled + 1 + + + + + DMEIE + Direct mode error interrupt + enable + 1 + 1 + + DMEIE + read-write + + Disabled + DME interrupt disabled + 0 + + + Enabled + DME interrupt enabled + 1 + + + + + EN + Stream enable / flag stream ready when + read low + 0 + 1 + + EN + read-write + + Disabled + Stream disabled + 0 + + + Enabled + Stream enabled + 1 + + + + + + + NDTR + S0NDTR + stream x number of data + register + 0x4 + 0x20 + read-write + 0x00000000 + + + NDT + Number of data items to + transfer + 0 + 16 + + + 0 + 65535 + + + + + + + PAR + S0PAR + stream x peripheral address + register + 0x8 + 0x20 + read-write + 0x00000000 + + + PA + Peripheral address + 0 + 32 + + + + + M0AR + S0M0AR + stream x memory 0 address + register + 0xC + 0x20 + read-write + 0x00000000 + + + M0A + Memory 0 address + 0 + 32 + + + + + M1AR + S0M1AR + stream x memory 1 address + register + 0x10 + 0x20 + read-write + 0x00000000 + + + M1A + Memory 1 address (used in case of Double + buffer mode) + 0 + 32 + + + + + FCR + S0FCR + stream x FIFO control register + 0x14 + 0x20 + 0x00000021 + + + FEIE + FIFO error interrupt + enable + 7 + 1 + read-write + + FEIE + read-write + + Disabled + FE interrupt disabled + 0 + + + Enabled + FE interrupt enabled + 1 + + + + + FS + FIFO status + 3 + 3 + read-only + + FS + read + + Quarter1 + 0 < fifo_level < 1/4 + 0 + + + Quarter2 + 1/4 <= fifo_level < 1/2 + 1 + + + Quarter3 + 1/2 <= fifo_level < 3/4 + 2 + + + Quarter4 + 3/4 <= fifo_level < full + 3 + + + Empty + FIFO is empty + 4 + + + Full + FIFO is full + 5 + + + + + DMDIS + Direct mode disable + 2 + 1 + read-write + + DMDIS + read-write + + Enabled + Direct mode is enabled + 0 + + + Disabled + Direct mode is disabled + 1 + + + + + FTH + FIFO threshold selection + 0 + 2 + read-write + + FTH + read-write + + Quarter + 1/4 full FIFO + 0 + + + Half + 1/2 full FIFO + 1 + + + ThreeQuarters + 3/4 full FIFO + 2 + + + Full + Full FIFO + 3 + + + + + + + + + + DMA1 + 0x40026000 + + RTC_WKUP + RTC Wakeup interrupt through the EXTI + line + 3 + + + RTC_Alarm + RTC Alarms (A and B) through EXTI line + interrupt + 41 + + + + GPIOH + General-purpose I/Os + GPIO + 0x40021C00 + + 0x0 + 0x400 + registers + + + SDIO + SDIO global interrupt + 49 + + + + MODER + MODER + GPIO port mode register + 0x0 + 0x20 + read-write + 0x00000000 + + + MODER15 + Port x configuration bits (y = + 0..15) + 30 + 2 + + + + MODER14 + Port x configuration bits (y = + 0..15) + 28 + 2 + + + + MODER13 + Port x configuration bits (y = + 0..15) + 26 + 2 + + + + MODER12 + Port x configuration bits (y = + 0..15) + 24 + 2 + + + + MODER11 + Port x configuration bits (y = + 0..15) + 22 + 2 + + + + MODER10 + Port x configuration bits (y = + 0..15) + 20 + 2 + + + + MODER9 + Port x configuration bits (y = + 0..15) + 18 + 2 + + + + MODER8 + Port x configuration bits (y = + 0..15) + 16 + 2 + + + + MODER7 + Port x configuration bits (y = + 0..15) + 14 + 2 + + + + MODER6 + Port x configuration bits (y = + 0..15) + 12 + 2 + + + + MODER5 + Port x configuration bits (y = + 0..15) + 10 + 2 + + + + MODER4 + Port x configuration bits (y = + 0..15) + 8 + 2 + + + + MODER3 + Port x configuration bits (y = + 0..15) + 6 + 2 + + + + MODER2 + Port x configuration bits (y = + 0..15) + 4 + 2 + + + + MODER1 + Port x configuration bits (y = + 0..15) + 2 + 2 + + + + MODER0 + Port x configuration bits (y = + 0..15) + 0 + 2 + + MODER0 + read-write + + Input + Input mode (reset state) + 0 + + + Output + General purpose output mode + 1 + + + Alternate + Alternate function mode + 2 + + + Analog + Analog mode + 3 + + + + + + + OTYPER + OTYPER + GPIO port output type register + 0x4 + 0x20 + read-write + 0x00000000 + + + OT15 + Port x configuration bits (y = + 0..15) + 15 + 1 + + + + OT14 + Port x configuration bits (y = + 0..15) + 14 + 1 + + + + OT13 + Port x configuration bits (y = + 0..15) + 13 + 1 + + + + OT12 + Port x configuration bits (y = + 0..15) + 12 + 1 + + + + OT11 + Port x configuration bits (y = + 0..15) + 11 + 1 + + + + OT10 + Port x configuration bits (y = + 0..15) + 10 + 1 + + + + OT9 + Port x configuration bits (y = + 0..15) + 9 + 1 + + + + OT8 + Port x configuration bits (y = + 0..15) + 8 + 1 + + + + OT7 + Port x configuration bits (y = + 0..15) + 7 + 1 + + + + OT6 + Port x configuration bits (y = + 0..15) + 6 + 1 + + + + OT5 + Port x configuration bits (y = + 0..15) + 5 + 1 + + + + OT4 + Port x configuration bits (y = + 0..15) + 4 + 1 + + + + OT3 + Port x configuration bits (y = + 0..15) + 3 + 1 + + + + OT2 + Port x configuration bits (y = + 0..15) + 2 + 1 + + + + OT1 + Port x configuration bits (y = + 0..15) + 1 + 1 + + + + OT0 + Port x configuration bits (y = + 0..15) + 0 + 1 + + OT0 + read-write + + PushPull + Output push-pull (reset state) + 0 + + + OpenDrain + Output open-drain + 1 + + + + + + + OSPEEDR + OSPEEDR + GPIO port output speed + register + 0x8 + 0x20 + read-write + 0x00000000 + + + OSPEEDR15 + Port x configuration bits (y = + 0..15) + 30 + 2 + + + + OSPEEDR14 + Port x configuration bits (y = + 0..15) + 28 + 2 + + + + OSPEEDR13 + Port x configuration bits (y = + 0..15) + 26 + 2 + + + + OSPEEDR12 + Port x configuration bits (y = + 0..15) + 24 + 2 + + + + OSPEEDR11 + Port x configuration bits (y = + 0..15) + 22 + 2 + + + + OSPEEDR10 + Port x configuration bits (y = + 0..15) + 20 + 2 + + + + OSPEEDR9 + Port x configuration bits (y = + 0..15) + 18 + 2 + + + + OSPEEDR8 + Port x configuration bits (y = + 0..15) + 16 + 2 + + + + OSPEEDR7 + Port x configuration bits (y = + 0..15) + 14 + 2 + + + + OSPEEDR6 + Port x configuration bits (y = + 0..15) + 12 + 2 + + + + OSPEEDR5 + Port x configuration bits (y = + 0..15) + 10 + 2 + + + + OSPEEDR4 + Port x configuration bits (y = + 0..15) + 8 + 2 + + + + OSPEEDR3 + Port x configuration bits (y = + 0..15) + 6 + 2 + + + + OSPEEDR2 + Port x configuration bits (y = + 0..15) + 4 + 2 + + + + OSPEEDR1 + Port x configuration bits (y = + 0..15) + 2 + 2 + + + + OSPEEDR0 + Port x configuration bits (y = + 0..15) + 0 + 2 + + OSPEEDR0 + read-write + + LowSpeed + Low speed + 0 + + + MediumSpeed + Medium speed + 1 + + + HighSpeed + High speed + 2 + + + VeryHighSpeed + Very high speed + 3 + + + + + + + PUPDR + PUPDR + GPIO port pull-up/pull-down + register + 0xC + 0x20 + read-write + 0x00000000 + + + PUPDR15 + Port x configuration bits (y = + 0..15) + 30 + 2 + + + + PUPDR14 + Port x configuration bits (y = + 0..15) + 28 + 2 + + + + PUPDR13 + Port x configuration bits (y = + 0..15) + 26 + 2 + + + + PUPDR12 + Port x configuration bits (y = + 0..15) + 24 + 2 + + + + PUPDR11 + Port x configuration bits (y = + 0..15) + 22 + 2 + + + + PUPDR10 + Port x configuration bits (y = + 0..15) + 20 + 2 + + + + PUPDR9 + Port x configuration bits (y = + 0..15) + 18 + 2 + + + + PUPDR8 + Port x configuration bits (y = + 0..15) + 16 + 2 + + + + PUPDR7 + Port x configuration bits (y = + 0..15) + 14 + 2 + + + + PUPDR6 + Port x configuration bits (y = + 0..15) + 12 + 2 + + + + PUPDR5 + Port x configuration bits (y = + 0..15) + 10 + 2 + + + + PUPDR4 + Port x configuration bits (y = + 0..15) + 8 + 2 + + + + PUPDR3 + Port x configuration bits (y = + 0..15) + 6 + 2 + + + + PUPDR2 + Port x configuration bits (y = + 0..15) + 4 + 2 + + + + PUPDR1 + Port x configuration bits (y = + 0..15) + 2 + 2 + + + + PUPDR0 + Port x configuration bits (y = + 0..15) + 0 + 2 + + PUPDR0 + read-write + + Floating + No pull-up, pull-down + 0 + + + PullUp + Pull-up + 1 + + + PullDown + Pull-down + 2 + + + + + + + IDR + IDR + GPIO port input data register + 0x10 + 0x20 + read-only + 0x00000000 + + + IDR15 + Port input data (y = + 0..15) + 15 + 1 + + + + IDR14 + Port input data (y = + 0..15) + 14 + 1 + + + + IDR13 + Port input data (y = + 0..15) + 13 + 1 + + + + IDR12 + Port input data (y = + 0..15) + 12 + 1 + + + + IDR11 + Port input data (y = + 0..15) + 11 + 1 + + + + IDR10 + Port input data (y = + 0..15) + 10 + 1 + + + + IDR9 + Port input data (y = + 0..15) + 9 + 1 + + + + IDR8 + Port input data (y = + 0..15) + 8 + 1 + + + + IDR7 + Port input data (y = + 0..15) + 7 + 1 + + + + IDR6 + Port input data (y = + 0..15) + 6 + 1 + + + + IDR5 + Port input data (y = + 0..15) + 5 + 1 + + + + IDR4 + Port input data (y = + 0..15) + 4 + 1 + + + + IDR3 + Port input data (y = + 0..15) + 3 + 1 + + + + IDR2 + Port input data (y = + 0..15) + 2 + 1 + + + + IDR1 + Port input data (y = + 0..15) + 1 + 1 + + + + IDR0 + Port input data (y = + 0..15) + 0 + 1 + + IDR0 + read + + Low + Input is logic low + 0 + + + High + Input is logic high + 1 + + + + + + + ODR + ODR + GPIO port output data register + 0x14 + 0x20 + read-write + 0x00000000 + + + ODR15 + Port output data (y = + 0..15) + 15 + 1 + + + + ODR14 + Port output data (y = + 0..15) + 14 + 1 + + + + ODR13 + Port output data (y = + 0..15) + 13 + 1 + + + + ODR12 + Port output data (y = + 0..15) + 12 + 1 + + + + ODR11 + Port output data (y = + 0..15) + 11 + 1 + + + + ODR10 + Port output data (y = + 0..15) + 10 + 1 + + + + ODR9 + Port output data (y = + 0..15) + 9 + 1 + + + + ODR8 + Port output data (y = + 0..15) + 8 + 1 + + + + ODR7 + Port output data (y = + 0..15) + 7 + 1 + + + + ODR6 + Port output data (y = + 0..15) + 6 + 1 + + + + ODR5 + Port output data (y = + 0..15) + 5 + 1 + + + + ODR4 + Port output data (y = + 0..15) + 4 + 1 + + + + ODR3 + Port output data (y = + 0..15) + 3 + 1 + + + + ODR2 + Port output data (y = + 0..15) + 2 + 1 + + + + ODR1 + Port output data (y = + 0..15) + 1 + 1 + + + + ODR0 + Port output data (y = + 0..15) + 0 + 1 + + ODR0 + read-write + + Low + Set output to logic low + 0 + + + High + Set output to logic high + 1 + + + + + + + BSRR + BSRR + GPIO port bit set/reset + register + 0x18 + 0x20 + write-only + 0x00000000 + + + BR15 + Port x reset bit y (y = + 0..15) + 31 + 1 + + + + BR14 + Port x reset bit y (y = + 0..15) + 30 + 1 + + + + BR13 + Port x reset bit y (y = + 0..15) + 29 + 1 + + + + BR12 + Port x reset bit y (y = + 0..15) + 28 + 1 + + + + BR11 + Port x reset bit y (y = + 0..15) + 27 + 1 + + + + BR10 + Port x reset bit y (y = + 0..15) + 26 + 1 + + + + BR9 + Port x reset bit y (y = + 0..15) + 25 + 1 + + + + BR8 + Port x reset bit y (y = + 0..15) + 24 + 1 + + + + BR7 + Port x reset bit y (y = + 0..15) + 23 + 1 + + + + BR6 + Port x reset bit y (y = + 0..15) + 22 + 1 + + + + BR5 + Port x reset bit y (y = + 0..15) + 21 + 1 + + + + BR4 + Port x reset bit y (y = + 0..15) + 20 + 1 + + + + BR3 + Port x reset bit y (y = + 0..15) + 19 + 1 + + + + BR2 + Port x reset bit y (y = + 0..15) + 18 + 1 + + + + BR1 + Port x reset bit y (y = + 0..15) + 17 + 1 + + + + BR0 + Port x set bit y (y= + 0..15) + 16 + 1 + + BR0W + write + + Reset + Resets the corresponding ODRx bit + 1 + + + + + BS15 + Port x set bit y (y= + 0..15) + 15 + 1 + + + + BS14 + Port x set bit y (y= + 0..15) + 14 + 1 + + + + BS13 + Port x set bit y (y= + 0..15) + 13 + 1 + + + + BS12 + Port x set bit y (y= + 0..15) + 12 + 1 + + + + BS11 + Port x set bit y (y= + 0..15) + 11 + 1 + + + + BS10 + Port x set bit y (y= + 0..15) + 10 + 1 + + + + BS9 + Port x set bit y (y= + 0..15) + 9 + 1 + + + + BS8 + Port x set bit y (y= + 0..15) + 8 + 1 + + + + BS7 + Port x set bit y (y= + 0..15) + 7 + 1 + + + + BS6 + Port x set bit y (y= + 0..15) + 6 + 1 + + + + BS5 + Port x set bit y (y= + 0..15) + 5 + 1 + + + + BS4 + Port x set bit y (y= + 0..15) + 4 + 1 + + + + BS3 + Port x set bit y (y= + 0..15) + 3 + 1 + + + + BS2 + Port x set bit y (y= + 0..15) + 2 + 1 + + + + BS1 + Port x set bit y (y= + 0..15) + 1 + 1 + + + + BS0 + Port x set bit y (y= + 0..15) + 0 + 1 + + BS0W + write + + Set + Sets the corresponding ODRx bit + 1 + + + + + + + LCKR + LCKR + GPIO port configuration lock + register + 0x1C + 0x20 + read-write + 0x00000000 + + + LCKK + Port x lock bit y (y= + 0..15) + 16 + 1 + + LCKK + read-write + + NotActive + Port configuration lock key not active + 0 + + + Active + Port configuration lock key active + 1 + + + + + LCK15 + Port x lock bit y (y= + 0..15) + 15 + 1 + + + + LCK14 + Port x lock bit y (y= + 0..15) + 14 + 1 + + + + LCK13 + Port x lock bit y (y= + 0..15) + 13 + 1 + + + + LCK12 + Port x lock bit y (y= + 0..15) + 12 + 1 + + + + LCK11 + Port x lock bit y (y= + 0..15) + 11 + 1 + + + + LCK10 + Port x lock bit y (y= + 0..15) + 10 + 1 + + + + LCK9 + Port x lock bit y (y= + 0..15) + 9 + 1 + + + + LCK8 + Port x lock bit y (y= + 0..15) + 8 + 1 + + + + LCK7 + Port x lock bit y (y= + 0..15) + 7 + 1 + + + + LCK6 + Port x lock bit y (y= + 0..15) + 6 + 1 + + + + LCK5 + Port x lock bit y (y= + 0..15) + 5 + 1 + + + + LCK4 + Port x lock bit y (y= + 0..15) + 4 + 1 + + + + LCK3 + Port x lock bit y (y= + 0..15) + 3 + 1 + + + + LCK2 + Port x lock bit y (y= + 0..15) + 2 + 1 + + + + LCK1 + Port x lock bit y (y= + 0..15) + 1 + 1 + + + + LCK0 + Port x lock bit y (y= + 0..15) + 0 + 1 + + LCK0 + read-write + + Unlocked + Port configuration not locked + 0 + + + Locked + Port configuration locked + 1 + + + + + + + AFRL + AFRL + GPIO alternate function low + register + 0x20 + 0x20 + read-write + 0x00000000 + + + AFRL7 + Alternate function selection for port x + bit y (y = 0..7) + 28 + 4 + + + + AFRL6 + Alternate function selection for port x + bit y (y = 0..7) + 24 + 4 + + + + AFRL5 + Alternate function selection for port x + bit y (y = 0..7) + 20 + 4 + + + + AFRL4 + Alternate function selection for port x + bit y (y = 0..7) + 16 + 4 + + + + AFRL3 + Alternate function selection for port x + bit y (y = 0..7) + 12 + 4 + + + + AFRL2 + Alternate function selection for port x + bit y (y = 0..7) + 8 + 4 + + + + AFRL1 + Alternate function selection for port x + bit y (y = 0..7) + 4 + 4 + + + + AFRL0 + Alternate function selection for port x + bit y (y = 0..7) + 0 + 4 + + AFRL0 + read-write + + AF0 + AF0 + 0 + + + AF1 + AF1 + 1 + + + AF2 + AF2 + 2 + + + AF3 + AF3 + 3 + + + AF4 + AF4 + 4 + + + AF5 + AF5 + 5 + + + AF6 + AF6 + 6 + + + AF7 + AF7 + 7 + + + AF8 + AF8 + 8 + + + AF9 + AF9 + 9 + + + AF10 + AF10 + 10 + + + AF11 + AF11 + 11 + + + AF12 + AF12 + 12 + + + AF13 + AF13 + 13 + + + AF14 + AF14 + 14 + + + AF15 + AF15 + 15 + + + + + + + AFRH + AFRH + GPIO alternate function high + register + 0x24 + 0x20 + read-write + 0x00000000 + + + AFRH15 + Alternate function selection for port x + bit y (y = 8..15) + 28 + 4 + + + + AFRH14 + Alternate function selection for port x + bit y (y = 8..15) + 24 + 4 + + + + AFRH13 + Alternate function selection for port x + bit y (y = 8..15) + 20 + 4 + + + + AFRH12 + Alternate function selection for port x + bit y (y = 8..15) + 16 + 4 + + + + AFRH11 + Alternate function selection for port x + bit y (y = 8..15) + 12 + 4 + + + + AFRH10 + Alternate function selection for port x + bit y (y = 8..15) + 8 + 4 + + + + AFRH9 + Alternate function selection for port x + bit y (y = 8..15) + 4 + 4 + + + + AFRH8 + Alternate function selection for port x + bit y (y = 8..15) + 0 + 4 + + AFRH8 + read-write + + AF0 + AF0 + 0 + + + AF1 + AF1 + 1 + + + AF2 + AF2 + 2 + + + AF3 + AF3 + 3 + + + AF4 + AF4 + 4 + + + AF5 + AF5 + 5 + + + AF6 + AF6 + 6 + + + AF7 + AF7 + 7 + + + AF8 + AF8 + 8 + + + AF9 + AF9 + 9 + + + AF10 + AF10 + 10 + + + AF11 + AF11 + 11 + + + AF12 + AF12 + 12 + + + AF13 + AF13 + 13 + + + AF14 + AF14 + 14 + + + AF15 + AF15 + 15 + + + + + + + + + GPIOE + 0x40021000 + + + GPIOD + 0x40020C00 + + TIM1_BRK_TIM9 + TIM1 Break interrupt and TIM9 global + interrupt + 24 + + + TIM1_UP_TIM10 + TIM1 Update interrupt and TIM10 global + interrupt + 25 + + + TIM1_TRG_COM_TIM11 + TIM1 Trigger and Commutation interrupts and + TIM11 global interrupt + 26 + + + TIM1_CC + TIM1 Capture Compare interrupt + 27 + + + + GPIOC + 0x40020800 + + TIM1_UP_TIM10 + TIM1 Update interrupt and TIM10 global + interrupt + 25 + + + + GPIOB + General-purpose I/Os + GPIO + 0x40020400 + + 0x0 + 0x400 + registers + + + TIM1_TRG_COM_TIM11 + TIM1 Trigger and Commutation interrupts and + TIM11 global interrupt + 26 + + + + MODER + MODER + GPIO port mode register + 0x0 + 0x20 + read-write + 0x00000280 + + + MODER15 + Port x configuration bits (y = + 0..15) + 30 + 2 + + + + MODER14 + Port x configuration bits (y = + 0..15) + 28 + 2 + + + + MODER13 + Port x configuration bits (y = + 0..15) + 26 + 2 + + + + MODER12 + Port x configuration bits (y = + 0..15) + 24 + 2 + + + + MODER11 + Port x configuration bits (y = + 0..15) + 22 + 2 + + + + MODER10 + Port x configuration bits (y = + 0..15) + 20 + 2 + + + + MODER9 + Port x configuration bits (y = + 0..15) + 18 + 2 + + + + MODER8 + Port x configuration bits (y = + 0..15) + 16 + 2 + + + + MODER7 + Port x configuration bits (y = + 0..15) + 14 + 2 + + + + MODER6 + Port x configuration bits (y = + 0..15) + 12 + 2 + + + + MODER5 + Port x configuration bits (y = + 0..15) + 10 + 2 + + + + MODER4 + Port x configuration bits (y = + 0..15) + 8 + 2 + + + + MODER3 + Port x configuration bits (y = + 0..15) + 6 + 2 + + + + MODER2 + Port x configuration bits (y = + 0..15) + 4 + 2 + + + + MODER1 + Port x configuration bits (y = + 0..15) + 2 + 2 + + + + MODER0 + Port x configuration bits (y = + 0..15) + 0 + 2 + + MODER0 + read-write + + Input + Input mode (reset state) + 0 + + + Output + General purpose output mode + 1 + + + Alternate + Alternate function mode + 2 + + + Analog + Analog mode + 3 + + + + + + + OTYPER + OTYPER + GPIO port output type register + 0x4 + 0x20 + read-write + 0x00000000 + + + OT15 + Port x configuration bits (y = + 0..15) + 15 + 1 + + + + OT14 + Port x configuration bits (y = + 0..15) + 14 + 1 + + + + OT13 + Port x configuration bits (y = + 0..15) + 13 + 1 + + + + OT12 + Port x configuration bits (y = + 0..15) + 12 + 1 + + + + OT11 + Port x configuration bits (y = + 0..15) + 11 + 1 + + + + OT10 + Port x configuration bits (y = + 0..15) + 10 + 1 + + + + OT9 + Port x configuration bits (y = + 0..15) + 9 + 1 + + + + OT8 + Port x configuration bits (y = + 0..15) + 8 + 1 + + + + OT7 + Port x configuration bits (y = + 0..15) + 7 + 1 + + + + OT6 + Port x configuration bits (y = + 0..15) + 6 + 1 + + + + OT5 + Port x configuration bits (y = + 0..15) + 5 + 1 + + + + OT4 + Port x configuration bits (y = + 0..15) + 4 + 1 + + + + OT3 + Port x configuration bits (y = + 0..15) + 3 + 1 + + + + OT2 + Port x configuration bits (y = + 0..15) + 2 + 1 + + + + OT1 + Port x configuration bits (y = + 0..15) + 1 + 1 + + + + OT0 + Port x configuration bits (y = + 0..15) + 0 + 1 + + OT0 + read-write + + PushPull + Output push-pull (reset state) + 0 + + + OpenDrain + Output open-drain + 1 + + + + + + + OSPEEDR + OSPEEDR + GPIO port output speed + register + 0x8 + 0x20 + read-write + 0x000000C0 + + + OSPEEDR15 + Port x configuration bits (y = + 0..15) + 30 + 2 + + + + OSPEEDR14 + Port x configuration bits (y = + 0..15) + 28 + 2 + + + + OSPEEDR13 + Port x configuration bits (y = + 0..15) + 26 + 2 + + + + OSPEEDR12 + Port x configuration bits (y = + 0..15) + 24 + 2 + + + + OSPEEDR11 + Port x configuration bits (y = + 0..15) + 22 + 2 + + + + OSPEEDR10 + Port x configuration bits (y = + 0..15) + 20 + 2 + + + + OSPEEDR9 + Port x configuration bits (y = + 0..15) + 18 + 2 + + + + OSPEEDR8 + Port x configuration bits (y = + 0..15) + 16 + 2 + + + + OSPEEDR7 + Port x configuration bits (y = + 0..15) + 14 + 2 + + + + OSPEEDR6 + Port x configuration bits (y = + 0..15) + 12 + 2 + + + + OSPEEDR5 + Port x configuration bits (y = + 0..15) + 10 + 2 + + + + OSPEEDR4 + Port x configuration bits (y = + 0..15) + 8 + 2 + + + + OSPEEDR3 + Port x configuration bits (y = + 0..15) + 6 + 2 + + + + OSPEEDR2 + Port x configuration bits (y = + 0..15) + 4 + 2 + + + + OSPEEDR1 + Port x configuration bits (y = + 0..15) + 2 + 2 + + + + OSPEEDR0 + Port x configuration bits (y = + 0..15) + 0 + 2 + + OSPEEDR0 + read-write + + LowSpeed + Low speed + 0 + + + MediumSpeed + Medium speed + 1 + + + HighSpeed + High speed + 2 + + + VeryHighSpeed + Very high speed + 3 + + + + + + + PUPDR + PUPDR + GPIO port pull-up/pull-down + register + 0xC + 0x20 + read-write + 0x00000100 + + + PUPDR15 + Port x configuration bits (y = + 0..15) + 30 + 2 + + + + PUPDR14 + Port x configuration bits (y = + 0..15) + 28 + 2 + + + + PUPDR13 + Port x configuration bits (y = + 0..15) + 26 + 2 + + + + PUPDR12 + Port x configuration bits (y = + 0..15) + 24 + 2 + + + + PUPDR11 + Port x configuration bits (y = + 0..15) + 22 + 2 + + + + PUPDR10 + Port x configuration bits (y = + 0..15) + 20 + 2 + + + + PUPDR9 + Port x configuration bits (y = + 0..15) + 18 + 2 + + + + PUPDR8 + Port x configuration bits (y = + 0..15) + 16 + 2 + + + + PUPDR7 + Port x configuration bits (y = + 0..15) + 14 + 2 + + + + PUPDR6 + Port x configuration bits (y = + 0..15) + 12 + 2 + + + + PUPDR5 + Port x configuration bits (y = + 0..15) + 10 + 2 + + + + PUPDR4 + Port x configuration bits (y = + 0..15) + 8 + 2 + + + + PUPDR3 + Port x configuration bits (y = + 0..15) + 6 + 2 + + + + PUPDR2 + Port x configuration bits (y = + 0..15) + 4 + 2 + + + + PUPDR1 + Port x configuration bits (y = + 0..15) + 2 + 2 + + + + PUPDR0 + Port x configuration bits (y = + 0..15) + 0 + 2 + + PUPDR0 + read-write + + Floating + No pull-up, pull-down + 0 + + + PullUp + Pull-up + 1 + + + PullDown + Pull-down + 2 + + + + + + + IDR + IDR + GPIO port input data register + 0x10 + 0x20 + read-only + 0x00000000 + + + IDR15 + Port input data (y = + 0..15) + 15 + 1 + + + + IDR14 + Port input data (y = + 0..15) + 14 + 1 + + + + IDR13 + Port input data (y = + 0..15) + 13 + 1 + + + + IDR12 + Port input data (y = + 0..15) + 12 + 1 + + + + IDR11 + Port input data (y = + 0..15) + 11 + 1 + + + + IDR10 + Port input data (y = + 0..15) + 10 + 1 + + + + IDR9 + Port input data (y = + 0..15) + 9 + 1 + + + + IDR8 + Port input data (y = + 0..15) + 8 + 1 + + + + IDR7 + Port input data (y = + 0..15) + 7 + 1 + + + + IDR6 + Port input data (y = + 0..15) + 6 + 1 + + + + IDR5 + Port input data (y = + 0..15) + 5 + 1 + + + + IDR4 + Port input data (y = + 0..15) + 4 + 1 + + + + IDR3 + Port input data (y = + 0..15) + 3 + 1 + + + + IDR2 + Port input data (y = + 0..15) + 2 + 1 + + + + IDR1 + Port input data (y = + 0..15) + 1 + 1 + + + + IDR0 + Port input data (y = + 0..15) + 0 + 1 + + IDR0 + read + + Low + Input is logic low + 0 + + + High + Input is logic high + 1 + + + + + + + ODR + ODR + GPIO port output data register + 0x14 + 0x20 + read-write + 0x00000000 + + + ODR15 + Port output data (y = + 0..15) + 15 + 1 + + + + ODR14 + Port output data (y = + 0..15) + 14 + 1 + + + + ODR13 + Port output data (y = + 0..15) + 13 + 1 + + + + ODR12 + Port output data (y = + 0..15) + 12 + 1 + + + + ODR11 + Port output data (y = + 0..15) + 11 + 1 + + + + ODR10 + Port output data (y = + 0..15) + 10 + 1 + + + + ODR9 + Port output data (y = + 0..15) + 9 + 1 + + + + ODR8 + Port output data (y = + 0..15) + 8 + 1 + + + + ODR7 + Port output data (y = + 0..15) + 7 + 1 + + + + ODR6 + Port output data (y = + 0..15) + 6 + 1 + + + + ODR5 + Port output data (y = + 0..15) + 5 + 1 + + + + ODR4 + Port output data (y = + 0..15) + 4 + 1 + + + + ODR3 + Port output data (y = + 0..15) + 3 + 1 + + + + ODR2 + Port output data (y = + 0..15) + 2 + 1 + + + + ODR1 + Port output data (y = + 0..15) + 1 + 1 + + + + ODR0 + Port output data (y = + 0..15) + 0 + 1 + + ODR0 + read-write + + Low + Set output to logic low + 0 + + + High + Set output to logic high + 1 + + + + + + + BSRR + BSRR + GPIO port bit set/reset + register + 0x18 + 0x20 + write-only + 0x00000000 + + + BR15 + Port x reset bit y (y = + 0..15) + 31 + 1 + + + + BR14 + Port x reset bit y (y = + 0..15) + 30 + 1 + + + + BR13 + Port x reset bit y (y = + 0..15) + 29 + 1 + + + + BR12 + Port x reset bit y (y = + 0..15) + 28 + 1 + + + + BR11 + Port x reset bit y (y = + 0..15) + 27 + 1 + + + + BR10 + Port x reset bit y (y = + 0..15) + 26 + 1 + + + + BR9 + Port x reset bit y (y = + 0..15) + 25 + 1 + + + + BR8 + Port x reset bit y (y = + 0..15) + 24 + 1 + + + + BR7 + Port x reset bit y (y = + 0..15) + 23 + 1 + + + + BR6 + Port x reset bit y (y = + 0..15) + 22 + 1 + + + + BR5 + Port x reset bit y (y = + 0..15) + 21 + 1 + + + + BR4 + Port x reset bit y (y = + 0..15) + 20 + 1 + + + + BR3 + Port x reset bit y (y = + 0..15) + 19 + 1 + + + + BR2 + Port x reset bit y (y = + 0..15) + 18 + 1 + + + + BR1 + Port x reset bit y (y = + 0..15) + 17 + 1 + + + + BR0 + Port x set bit y (y= + 0..15) + 16 + 1 + + BR0W + write + + Reset + Resets the corresponding ODRx bit + 1 + + + + + BS15 + Port x set bit y (y= + 0..15) + 15 + 1 + + + + BS14 + Port x set bit y (y= + 0..15) + 14 + 1 + + + + BS13 + Port x set bit y (y= + 0..15) + 13 + 1 + + + + BS12 + Port x set bit y (y= + 0..15) + 12 + 1 + + + + BS11 + Port x set bit y (y= + 0..15) + 11 + 1 + + + + BS10 + Port x set bit y (y= + 0..15) + 10 + 1 + + + + BS9 + Port x set bit y (y= + 0..15) + 9 + 1 + + + + BS8 + Port x set bit y (y= + 0..15) + 8 + 1 + + + + BS7 + Port x set bit y (y= + 0..15) + 7 + 1 + + + + BS6 + Port x set bit y (y= + 0..15) + 6 + 1 + + + + BS5 + Port x set bit y (y= + 0..15) + 5 + 1 + + + + BS4 + Port x set bit y (y= + 0..15) + 4 + 1 + + + + BS3 + Port x set bit y (y= + 0..15) + 3 + 1 + + + + BS2 + Port x set bit y (y= + 0..15) + 2 + 1 + + + + BS1 + Port x set bit y (y= + 0..15) + 1 + 1 + + + + BS0 + Port x set bit y (y= + 0..15) + 0 + 1 + + BS0W + write + + Set + Sets the corresponding ODRx bit + 1 + + + + + + + LCKR + LCKR + GPIO port configuration lock + register + 0x1C + 0x20 + read-write + 0x00000000 + + + LCKK + Port x lock bit y (y= + 0..15) + 16 + 1 + + LCKK + read-write + + NotActive + Port configuration lock key not active + 0 + + + Active + Port configuration lock key active + 1 + + + + + LCK15 + Port x lock bit y (y= + 0..15) + 15 + 1 + + + + LCK14 + Port x lock bit y (y= + 0..15) + 14 + 1 + + + + LCK13 + Port x lock bit y (y= + 0..15) + 13 + 1 + + + + LCK12 + Port x lock bit y (y= + 0..15) + 12 + 1 + + + + LCK11 + Port x lock bit y (y= + 0..15) + 11 + 1 + + + + LCK10 + Port x lock bit y (y= + 0..15) + 10 + 1 + + + + LCK9 + Port x lock bit y (y= + 0..15) + 9 + 1 + + + + LCK8 + Port x lock bit y (y= + 0..15) + 8 + 1 + + + + LCK7 + Port x lock bit y (y= + 0..15) + 7 + 1 + + + + LCK6 + Port x lock bit y (y= + 0..15) + 6 + 1 + + + + LCK5 + Port x lock bit y (y= + 0..15) + 5 + 1 + + + + LCK4 + Port x lock bit y (y= + 0..15) + 4 + 1 + + + + LCK3 + Port x lock bit y (y= + 0..15) + 3 + 1 + + + + LCK2 + Port x lock bit y (y= + 0..15) + 2 + 1 + + + + LCK1 + Port x lock bit y (y= + 0..15) + 1 + 1 + + + + LCK0 + Port x lock bit y (y= + 0..15) + 0 + 1 + + LCK0 + read-write + + Unlocked + Port configuration not locked + 0 + + + Locked + Port configuration locked + 1 + + + + + + + AFRL + AFRL + GPIO alternate function low + register + 0x20 + 0x20 + read-write + 0x00000000 + + + AFRL7 + Alternate function selection for port x + bit y (y = 0..7) + 28 + 4 + + + + AFRL6 + Alternate function selection for port x + bit y (y = 0..7) + 24 + 4 + + + + AFRL5 + Alternate function selection for port x + bit y (y = 0..7) + 20 + 4 + + + + AFRL4 + Alternate function selection for port x + bit y (y = 0..7) + 16 + 4 + + + + AFRL3 + Alternate function selection for port x + bit y (y = 0..7) + 12 + 4 + + + + AFRL2 + Alternate function selection for port x + bit y (y = 0..7) + 8 + 4 + + + + AFRL1 + Alternate function selection for port x + bit y (y = 0..7) + 4 + 4 + + + + AFRL0 + Alternate function selection for port x + bit y (y = 0..7) + 0 + 4 + + AFRL0 + read-write + + AF0 + AF0 + 0 + + + AF1 + AF1 + 1 + + + AF2 + AF2 + 2 + + + AF3 + AF3 + 3 + + + AF4 + AF4 + 4 + + + AF5 + AF5 + 5 + + + AF6 + AF6 + 6 + + + AF7 + AF7 + 7 + + + AF8 + AF8 + 8 + + + AF9 + AF9 + 9 + + + AF10 + AF10 + 10 + + + AF11 + AF11 + 11 + + + AF12 + AF12 + 12 + + + AF13 + AF13 + 13 + + + AF14 + AF14 + 14 + + + AF15 + AF15 + 15 + + + + + + + AFRH + AFRH + GPIO alternate function high + register + 0x24 + 0x20 + read-write + 0x00000000 + + + AFRH15 + Alternate function selection for port x + bit y (y = 8..15) + 28 + 4 + + + + AFRH14 + Alternate function selection for port x + bit y (y = 8..15) + 24 + 4 + + + + AFRH13 + Alternate function selection for port x + bit y (y = 8..15) + 20 + 4 + + + + AFRH12 + Alternate function selection for port x + bit y (y = 8..15) + 16 + 4 + + + + AFRH11 + Alternate function selection for port x + bit y (y = 8..15) + 12 + 4 + + + + AFRH10 + Alternate function selection for port x + bit y (y = 8..15) + 8 + 4 + + + + AFRH9 + Alternate function selection for port x + bit y (y = 8..15) + 4 + 4 + + + + AFRH8 + Alternate function selection for port x + bit y (y = 8..15) + 0 + 4 + + AFRH8 + read-write + + AF0 + AF0 + 0 + + + AF1 + AF1 + 1 + + + AF2 + AF2 + 2 + + + AF3 + AF3 + 3 + + + AF4 + AF4 + 4 + + + AF5 + AF5 + 5 + + + AF6 + AF6 + 6 + + + AF7 + AF7 + 7 + + + AF8 + AF8 + 8 + + + AF9 + AF9 + 9 + + + AF10 + AF10 + 10 + + + AF11 + AF11 + 11 + + + AF12 + AF12 + 12 + + + AF13 + AF13 + 13 + + + AF14 + AF14 + 14 + + + AF15 + AF15 + 15 + + + + + + + + + GPIOA + General-purpose I/Os + GPIO + 0x40020000 + + 0x0 + 0x400 + registers + + + TIM2 + TIM2 global interrupt + 28 + + + + MODER + MODER + GPIO port mode register + 0x0 + 0x20 + read-write + 0xA8000000 + + + MODER15 + Port x configuration bits (y = + 0..15) + 30 + 2 + + + + MODER14 + Port x configuration bits (y = + 0..15) + 28 + 2 + + + + MODER13 + Port x configuration bits (y = + 0..15) + 26 + 2 + + + + MODER12 + Port x configuration bits (y = + 0..15) + 24 + 2 + + + + MODER11 + Port x configuration bits (y = + 0..15) + 22 + 2 + + + + MODER10 + Port x configuration bits (y = + 0..15) + 20 + 2 + + + + MODER9 + Port x configuration bits (y = + 0..15) + 18 + 2 + + + + MODER8 + Port x configuration bits (y = + 0..15) + 16 + 2 + + + + MODER7 + Port x configuration bits (y = + 0..15) + 14 + 2 + + + + MODER6 + Port x configuration bits (y = + 0..15) + 12 + 2 + + + + MODER5 + Port x configuration bits (y = + 0..15) + 10 + 2 + + + + MODER4 + Port x configuration bits (y = + 0..15) + 8 + 2 + + + + MODER3 + Port x configuration bits (y = + 0..15) + 6 + 2 + + + + MODER2 + Port x configuration bits (y = + 0..15) + 4 + 2 + + + + MODER1 + Port x configuration bits (y = + 0..15) + 2 + 2 + + + + MODER0 + Port x configuration bits (y = + 0..15) + 0 + 2 + + MODER0 + read-write + + Input + Input mode (reset state) + 0 + + + Output + General purpose output mode + 1 + + + Alternate + Alternate function mode + 2 + + + Analog + Analog mode + 3 + + + + + + + OTYPER + OTYPER + GPIO port output type register + 0x4 + 0x20 + read-write + 0x00000000 + + + OT15 + Port x configuration bits (y = + 0..15) + 15 + 1 + + + + OT14 + Port x configuration bits (y = + 0..15) + 14 + 1 + + + + OT13 + Port x configuration bits (y = + 0..15) + 13 + 1 + + + + OT12 + Port x configuration bits (y = + 0..15) + 12 + 1 + + + + OT11 + Port x configuration bits (y = + 0..15) + 11 + 1 + + + + OT10 + Port x configuration bits (y = + 0..15) + 10 + 1 + + + + OT9 + Port x configuration bits (y = + 0..15) + 9 + 1 + + + + OT8 + Port x configuration bits (y = + 0..15) + 8 + 1 + + + + OT7 + Port x configuration bits (y = + 0..15) + 7 + 1 + + + + OT6 + Port x configuration bits (y = + 0..15) + 6 + 1 + + + + OT5 + Port x configuration bits (y = + 0..15) + 5 + 1 + + + + OT4 + Port x configuration bits (y = + 0..15) + 4 + 1 + + + + OT3 + Port x configuration bits (y = + 0..15) + 3 + 1 + + + + OT2 + Port x configuration bits (y = + 0..15) + 2 + 1 + + + + OT1 + Port x configuration bits (y = + 0..15) + 1 + 1 + + + + OT0 + Port x configuration bits (y = + 0..15) + 0 + 1 + + OT0 + read-write + + PushPull + Output push-pull (reset state) + 0 + + + OpenDrain + Output open-drain + 1 + + + + + + + OSPEEDR + OSPEEDR + GPIO port output speed + register + 0x8 + 0x20 + read-write + 0x00000000 + + + OSPEEDR15 + Port x configuration bits (y = + 0..15) + 30 + 2 + + + + OSPEEDR14 + Port x configuration bits (y = + 0..15) + 28 + 2 + + + + OSPEEDR13 + Port x configuration bits (y = + 0..15) + 26 + 2 + + + + OSPEEDR12 + Port x configuration bits (y = + 0..15) + 24 + 2 + + + + OSPEEDR11 + Port x configuration bits (y = + 0..15) + 22 + 2 + + + + OSPEEDR10 + Port x configuration bits (y = + 0..15) + 20 + 2 + + + + OSPEEDR9 + Port x configuration bits (y = + 0..15) + 18 + 2 + + + + OSPEEDR8 + Port x configuration bits (y = + 0..15) + 16 + 2 + + + + OSPEEDR7 + Port x configuration bits (y = + 0..15) + 14 + 2 + + + + OSPEEDR6 + Port x configuration bits (y = + 0..15) + 12 + 2 + + + + OSPEEDR5 + Port x configuration bits (y = + 0..15) + 10 + 2 + + + + OSPEEDR4 + Port x configuration bits (y = + 0..15) + 8 + 2 + + + + OSPEEDR3 + Port x configuration bits (y = + 0..15) + 6 + 2 + + + + OSPEEDR2 + Port x configuration bits (y = + 0..15) + 4 + 2 + + + + OSPEEDR1 + Port x configuration bits (y = + 0..15) + 2 + 2 + + + + OSPEEDR0 + Port x configuration bits (y = + 0..15) + 0 + 2 + + OSPEEDR0 + read-write + + LowSpeed + Low speed + 0 + + + MediumSpeed + Medium speed + 1 + + + HighSpeed + High speed + 2 + + + VeryHighSpeed + Very high speed + 3 + + + + + + + PUPDR + PUPDR + GPIO port pull-up/pull-down + register + 0xC + 0x20 + read-write + 0x64000000 + + + PUPDR15 + Port x configuration bits (y = + 0..15) + 30 + 2 + + + + PUPDR14 + Port x configuration bits (y = + 0..15) + 28 + 2 + + + + PUPDR13 + Port x configuration bits (y = + 0..15) + 26 + 2 + + + + PUPDR12 + Port x configuration bits (y = + 0..15) + 24 + 2 + + + + PUPDR11 + Port x configuration bits (y = + 0..15) + 22 + 2 + + + + PUPDR10 + Port x configuration bits (y = + 0..15) + 20 + 2 + + + + PUPDR9 + Port x configuration bits (y = + 0..15) + 18 + 2 + + + + PUPDR8 + Port x configuration bits (y = + 0..15) + 16 + 2 + + + + PUPDR7 + Port x configuration bits (y = + 0..15) + 14 + 2 + + + + PUPDR6 + Port x configuration bits (y = + 0..15) + 12 + 2 + + + + PUPDR5 + Port x configuration bits (y = + 0..15) + 10 + 2 + + + + PUPDR4 + Port x configuration bits (y = + 0..15) + 8 + 2 + + + + PUPDR3 + Port x configuration bits (y = + 0..15) + 6 + 2 + + + + PUPDR2 + Port x configuration bits (y = + 0..15) + 4 + 2 + + + + PUPDR1 + Port x configuration bits (y = + 0..15) + 2 + 2 + + + + PUPDR0 + Port x configuration bits (y = + 0..15) + 0 + 2 + + PUPDR0 + read-write + + Floating + No pull-up, pull-down + 0 + + + PullUp + Pull-up + 1 + + + PullDown + Pull-down + 2 + + + + + + + IDR + IDR + GPIO port input data register + 0x10 + 0x20 + read-only + 0x00000000 + + + IDR15 + Port input data (y = + 0..15) + 15 + 1 + + + + IDR14 + Port input data (y = + 0..15) + 14 + 1 + + + + IDR13 + Port input data (y = + 0..15) + 13 + 1 + + + + IDR12 + Port input data (y = + 0..15) + 12 + 1 + + + + IDR11 + Port input data (y = + 0..15) + 11 + 1 + + + + IDR10 + Port input data (y = + 0..15) + 10 + 1 + + + + IDR9 + Port input data (y = + 0..15) + 9 + 1 + + + + IDR8 + Port input data (y = + 0..15) + 8 + 1 + + + + IDR7 + Port input data (y = + 0..15) + 7 + 1 + + + + IDR6 + Port input data (y = + 0..15) + 6 + 1 + + + + IDR5 + Port input data (y = + 0..15) + 5 + 1 + + + + IDR4 + Port input data (y = + 0..15) + 4 + 1 + + + + IDR3 + Port input data (y = + 0..15) + 3 + 1 + + + + IDR2 + Port input data (y = + 0..15) + 2 + 1 + + + + IDR1 + Port input data (y = + 0..15) + 1 + 1 + + + + IDR0 + Port input data (y = + 0..15) + 0 + 1 + + IDR0 + read + + Low + Input is logic low + 0 + + + High + Input is logic high + 1 + + + + + + + ODR + ODR + GPIO port output data register + 0x14 + 0x20 + read-write + 0x00000000 + + + ODR15 + Port output data (y = + 0..15) + 15 + 1 + + + + ODR14 + Port output data (y = + 0..15) + 14 + 1 + + + + ODR13 + Port output data (y = + 0..15) + 13 + 1 + + + + ODR12 + Port output data (y = + 0..15) + 12 + 1 + + + + ODR11 + Port output data (y = + 0..15) + 11 + 1 + + + + ODR10 + Port output data (y = + 0..15) + 10 + 1 + + + + ODR9 + Port output data (y = + 0..15) + 9 + 1 + + + + ODR8 + Port output data (y = + 0..15) + 8 + 1 + + + + ODR7 + Port output data (y = + 0..15) + 7 + 1 + + + + ODR6 + Port output data (y = + 0..15) + 6 + 1 + + + + ODR5 + Port output data (y = + 0..15) + 5 + 1 + + + + ODR4 + Port output data (y = + 0..15) + 4 + 1 + + + + ODR3 + Port output data (y = + 0..15) + 3 + 1 + + + + ODR2 + Port output data (y = + 0..15) + 2 + 1 + + + + ODR1 + Port output data (y = + 0..15) + 1 + 1 + + + + ODR0 + Port output data (y = + 0..15) + 0 + 1 + + ODR0 + read-write + + Low + Set output to logic low + 0 + + + High + Set output to logic high + 1 + + + + + + + BSRR + BSRR + GPIO port bit set/reset + register + 0x18 + 0x20 + write-only + 0x00000000 + + + BR15 + Port x reset bit y (y = + 0..15) + 31 + 1 + + + + BR14 + Port x reset bit y (y = + 0..15) + 30 + 1 + + + + BR13 + Port x reset bit y (y = + 0..15) + 29 + 1 + + + + BR12 + Port x reset bit y (y = + 0..15) + 28 + 1 + + + + BR11 + Port x reset bit y (y = + 0..15) + 27 + 1 + + + + BR10 + Port x reset bit y (y = + 0..15) + 26 + 1 + + + + BR9 + Port x reset bit y (y = + 0..15) + 25 + 1 + + + + BR8 + Port x reset bit y (y = + 0..15) + 24 + 1 + + + + BR7 + Port x reset bit y (y = + 0..15) + 23 + 1 + + + + BR6 + Port x reset bit y (y = + 0..15) + 22 + 1 + + + + BR5 + Port x reset bit y (y = + 0..15) + 21 + 1 + + + + BR4 + Port x reset bit y (y = + 0..15) + 20 + 1 + + + + BR3 + Port x reset bit y (y = + 0..15) + 19 + 1 + + + + BR2 + Port x reset bit y (y = + 0..15) + 18 + 1 + + + + BR1 + Port x reset bit y (y = + 0..15) + 17 + 1 + + + + BR0 + Port x set bit y (y= + 0..15) + 16 + 1 + + BR0W + write + + Reset + Resets the corresponding ODRx bit + 1 + + + + + BS15 + Port x set bit y (y= + 0..15) + 15 + 1 + + + + BS14 + Port x set bit y (y= + 0..15) + 14 + 1 + + + + BS13 + Port x set bit y (y= + 0..15) + 13 + 1 + + + + BS12 + Port x set bit y (y= + 0..15) + 12 + 1 + + + + BS11 + Port x set bit y (y= + 0..15) + 11 + 1 + + + + BS10 + Port x set bit y (y= + 0..15) + 10 + 1 + + + + BS9 + Port x set bit y (y= + 0..15) + 9 + 1 + + + + BS8 + Port x set bit y (y= + 0..15) + 8 + 1 + + + + BS7 + Port x set bit y (y= + 0..15) + 7 + 1 + + + + BS6 + Port x set bit y (y= + 0..15) + 6 + 1 + + + + BS5 + Port x set bit y (y= + 0..15) + 5 + 1 + + + + BS4 + Port x set bit y (y= + 0..15) + 4 + 1 + + + + BS3 + Port x set bit y (y= + 0..15) + 3 + 1 + + + + BS2 + Port x set bit y (y= + 0..15) + 2 + 1 + + + + BS1 + Port x set bit y (y= + 0..15) + 1 + 1 + + + + BS0 + Port x set bit y (y= + 0..15) + 0 + 1 + + BS0W + write + + Set + Sets the corresponding ODRx bit + 1 + + + + + + + LCKR + LCKR + GPIO port configuration lock + register + 0x1C + 0x20 + read-write + 0x00000000 + + + LCKK + Port x lock bit y (y= + 0..15) + 16 + 1 + + LCKK + read-write + + NotActive + Port configuration lock key not active + 0 + + + Active + Port configuration lock key active + 1 + + + + + LCK15 + Port x lock bit y (y= + 0..15) + 15 + 1 + + + + LCK14 + Port x lock bit y (y= + 0..15) + 14 + 1 + + + + LCK13 + Port x lock bit y (y= + 0..15) + 13 + 1 + + + + LCK12 + Port x lock bit y (y= + 0..15) + 12 + 1 + + + + LCK11 + Port x lock bit y (y= + 0..15) + 11 + 1 + + + + LCK10 + Port x lock bit y (y= + 0..15) + 10 + 1 + + + + LCK9 + Port x lock bit y (y= + 0..15) + 9 + 1 + + + + LCK8 + Port x lock bit y (y= + 0..15) + 8 + 1 + + + + LCK7 + Port x lock bit y (y= + 0..15) + 7 + 1 + + + + LCK6 + Port x lock bit y (y= + 0..15) + 6 + 1 + + + + LCK5 + Port x lock bit y (y= + 0..15) + 5 + 1 + + + + LCK4 + Port x lock bit y (y= + 0..15) + 4 + 1 + + + + LCK3 + Port x lock bit y (y= + 0..15) + 3 + 1 + + + + LCK2 + Port x lock bit y (y= + 0..15) + 2 + 1 + + + + LCK1 + Port x lock bit y (y= + 0..15) + 1 + 1 + + + + LCK0 + Port x lock bit y (y= + 0..15) + 0 + 1 + + LCK0 + read-write + + Unlocked + Port configuration not locked + 0 + + + Locked + Port configuration locked + 1 + + + + + + + AFRL + AFRL + GPIO alternate function low + register + 0x20 + 0x20 + read-write + 0x00000000 + + + AFRL7 + Alternate function selection for port x + bit y (y = 0..7) + 28 + 4 + + + + AFRL6 + Alternate function selection for port x + bit y (y = 0..7) + 24 + 4 + + + + AFRL5 + Alternate function selection for port x + bit y (y = 0..7) + 20 + 4 + + + + AFRL4 + Alternate function selection for port x + bit y (y = 0..7) + 16 + 4 + + + + AFRL3 + Alternate function selection for port x + bit y (y = 0..7) + 12 + 4 + + + + AFRL2 + Alternate function selection for port x + bit y (y = 0..7) + 8 + 4 + + + + AFRL1 + Alternate function selection for port x + bit y (y = 0..7) + 4 + 4 + + + + AFRL0 + Alternate function selection for port x + bit y (y = 0..7) + 0 + 4 + + AFRL0 + read-write + + AF0 + AF0 + 0 + + + AF1 + AF1 + 1 + + + AF2 + AF2 + 2 + + + AF3 + AF3 + 3 + + + AF4 + AF4 + 4 + + + AF5 + AF5 + 5 + + + AF6 + AF6 + 6 + + + AF7 + AF7 + 7 + + + AF8 + AF8 + 8 + + + AF9 + AF9 + 9 + + + AF10 + AF10 + 10 + + + AF11 + AF11 + 11 + + + AF12 + AF12 + 12 + + + AF13 + AF13 + 13 + + + AF14 + AF14 + 14 + + + AF15 + AF15 + 15 + + + + + + + AFRH + AFRH + GPIO alternate function high + register + 0x24 + 0x20 + read-write + 0x00000000 + + + AFRH15 + Alternate function selection for port x + bit y (y = 8..15) + 28 + 4 + + + + AFRH14 + Alternate function selection for port x + bit y (y = 8..15) + 24 + 4 + + + + AFRH13 + Alternate function selection for port x + bit y (y = 8..15) + 20 + 4 + + + + AFRH12 + Alternate function selection for port x + bit y (y = 8..15) + 16 + 4 + + + + AFRH11 + Alternate function selection for port x + bit y (y = 8..15) + 12 + 4 + + + + AFRH10 + Alternate function selection for port x + bit y (y = 8..15) + 8 + 4 + + + + AFRH9 + Alternate function selection for port x + bit y (y = 8..15) + 4 + 4 + + + + AFRH8 + Alternate function selection for port x + bit y (y = 8..15) + 0 + 4 + + AFRH8 + read-write + + AF0 + AF0 + 0 + + + AF1 + AF1 + 1 + + + AF2 + AF2 + 2 + + + AF3 + AF3 + 3 + + + AF4 + AF4 + 4 + + + AF5 + AF5 + 5 + + + AF6 + AF6 + 6 + + + AF7 + AF7 + 7 + + + AF8 + AF8 + 8 + + + AF9 + AF9 + 9 + + + AF10 + AF10 + 10 + + + AF11 + AF11 + 11 + + + AF12 + AF12 + 12 + + + AF13 + AF13 + 13 + + + AF14 + AF14 + 14 + + + AF15 + AF15 + 15 + + + + + + + + + I2C3 + 0x40005C00 + + TIM3 + TIM3 global interrupt + 29 + + + + I2C2 + 0x40005800 + + I2C3_EV + I2C3 event interrupt + 72 + + + I2C3_ER + I2C3 error interrupt + 73 + + + + I2C1 + Inter-integrated circuit + I2C + 0x40005400 + + 0x0 + 0x400 + registers + + + I2C2_EV + I2C2 event interrupt + 33 + + + I2C2_ER + I2C2 error interrupt + 34 + + + + CR1 + CR1 + Control register 1 + 0x0 + 0x20 + read-write + 0x00000000 + + + SWRST + Software reset + 15 + 1 + + SWRST + read-write + + NotReset + I2C peripheral not under reset + 0 + + + Reset + I2C peripheral under reset + 1 + + + + + ALERT + SMBus alert + 13 + 1 + + ALERT + read-write + + Release + SMBA pin released high + 0 + + + Drive + SMBA pin driven low + 1 + + + + + PEC + Packet error checking + 12 + 1 + + PEC + read-write + + Disabled + No PEC transfer + 0 + + + Enabled + PEC transfer + 1 + + + + + POS + Acknowledge/PEC Position (for data + reception) + 11 + 1 + + POS + read-write + + Current + ACK bit controls the (N)ACK of the current byte being received + 0 + + + Next + ACK bit controls the (N)ACK of the next byte to be received + 1 + + + + + ACK + Acknowledge enable + 10 + 1 + + ACK + read-write + + NAK + No acknowledge returned + 0 + + + ACK + Acknowledge returned after a byte is received + 1 + + + + + STOP + Stop generation + 9 + 1 + + STOP + read-write + + NoStop + No Stop generation + 0 + + + Stop + In master mode: stop generation after current byte/start, in slave mode: release SCL and SDA after current byte + 1 + + + + + START + Start generation + 8 + 1 + + START + read-write + + NoStart + No Start generation + 0 + + + Start + In master mode: repeated start generation, in slave mode: start generation when bus is free + 1 + + + + + NOSTRETCH + Clock stretching disable (Slave + mode) + 7 + 1 + + NOSTRETCH + read-write + + Enabled + Clock stretching enabled + 0 + + + Disabled + Clock stretching disabled + 1 + + + + + ENGC + General call enable + 6 + 1 + + ENGC + read-write + + Disabled + General call disabled + 0 + + + Enabled + General call enabled + 1 + + + + + ENPEC + PEC enable + 5 + 1 + + ENPEC + read-write + + Disabled + PEC calculation disabled + 0 + + + Enabled + PEC calculation enabled + 1 + + + + + ENARP + ARP enable + 4 + 1 + + ENARP + read-write + + Disabled + ARP disabled + 0 + + + Enabled + ARP enabled + 1 + + + + + SMBTYPE + SMBus type + 3 + 1 + + SMBTYPE + read-write + + Device + SMBus Device + 0 + + + Host + SMBus Host + 1 + + + + + SMBUS + SMBus mode + 1 + 1 + + SMBUS + read-write + + I2C + I2C Mode + 0 + + + SMBus + SMBus + 1 + + + + + PE + Peripheral enable + 0 + 1 + + PE + read-write + + Disabled + Peripheral disabled + 0 + + + Enabled + Peripheral enabled + 1 + + + + + + + CR2 + CR2 + Control register 2 + 0x4 + 0x20 + read-write + 0x00000000 + + + LAST + DMA last transfer + 12 + 1 + + LAST + read-write + + NotLast + Next DMA EOT is not the last transfer + 0 + + + Last + Next DMA EOT is the last transfer + 1 + + + + + DMAEN + DMA requests enable + 11 + 1 + + DMAEN + read-write + + Disabled + DMA requests disabled + 0 + + + Enabled + DMA request enabled when TxE=1 or RxNE=1 + 1 + + + + + ITBUFEN + Buffer interrupt enable + 10 + 1 + + ITBUFEN + read-write + + Disabled + TxE=1 or RxNE=1 does not generate any interrupt + 0 + + + Enabled + TxE=1 or RxNE=1 generates Event interrupt + 1 + + + + + ITEVTEN + Event interrupt enable + 9 + 1 + + ITEVTEN + read-write + + Disabled + Event interrupt disabled + 0 + + + Enabled + Event interrupt enabled + 1 + + + + + ITERREN + Error interrupt enable + 8 + 1 + + ITERREN + read-write + + Disabled + Error interrupt disabled + 0 + + + Enabled + Error interrupt enabled + 1 + + + + + FREQ + Peripheral clock frequency + 0 + 6 + + + 2 + 50 + + + + + + + OAR1 + OAR1 + Own address register 1 + 0x8 + 0x20 + read-write + 0x00000000 + + + ADDMODE + Addressing mode (slave + mode) + 15 + 1 + + ADDMODE + read-write + + ADD7 + 7-bit slave address + 0 + + + ADD10 + 10-bit slave address + 1 + + + + + ADD + Interface address + 0 + 10 + + + 0 + 1023 + + + + + + + OAR2 + OAR2 + Own address register 2 + 0xC + 0x20 + read-write + 0x00000000 + + + ADD2 + Interface address + 1 + 7 + + + 0 + 127 + + + + + ENDUAL + Dual addressing mode + enable + 0 + 1 + + ENDUAL + read-write + + Single + Single addressing mode + 0 + + + Dual + Dual addressing mode + 1 + + + + + + + DR + DR + Data register + 0x10 + 0x20 + read-write + 0x00000000 + + + DR + 8-bit data register + 0 + 8 + + + 0 + 255 + + + + + + + SR1 + SR1 + Status register 1 + 0x14 + 0x20 + 0x00000000 + + + SMBALERT + SMBus alert + 15 + 1 + read-write + zeroToClear + + SMBALERTR + read + + NoAlert + No SMBALERT occured + 0 + + + Alert + SMBALERT occurred + 1 + + + + SMBALERTW + write + + Clear + Clear flag + 0 + + + + + TIMEOUT + Timeout or Tlow error + 14 + 1 + read-write + zeroToClear + + TIMEOUTR + read + + NoTimeout + No Timeout error + 0 + + + Timeout + SCL remained LOW for 25 ms + 1 + + + + TIMEOUTW + write + + Clear + Clear flag + 0 + + + + + PECERR + PEC Error in reception + 12 + 1 + read-write + zeroToClear + + PECERRR + read + + NoError + no PEC error: receiver returns ACK after PEC reception (if ACK=1) + 0 + + + Error + PEC error: receiver returns NACK after PEC reception (whatever ACK) + 1 + + + + PECERRW + write + + Clear + Clear flag + 0 + + + + + OVR + Overrun/Underrun + 11 + 1 + read-write + zeroToClear + + OVRR + read + + NoOverrun + No overrun/underrun occured + 0 + + + Overrun + Overrun/underrun occured + 1 + + + + OVRW + write + + Clear + Clear flag + 0 + + + + + AF + Acknowledge failure + 10 + 1 + read-write + zeroToClear + + AFR + read + + NoFailure + No acknowledge failure + 0 + + + Failure + Acknowledge failure + 1 + + + + AFW + write + + Clear + Clear flag + 0 + + + + + ARLO + Arbitration lost (master + mode) + 9 + 1 + read-write + zeroToClear + + ARLOR + read + + NoLost + No Arbitration Lost detected + 0 + + + Lost + Arbitration Lost detected + 1 + + + + ARLOW + write + + Clear + Clear flag + 0 + + + + + BERR + Bus error + 8 + 1 + read-write + zeroToClear + + BERRR + read + + NoError + No misplaced Start or Stop condition + 0 + + + Error + Misplaced Start or Stop condition + 1 + + + + BERRW + write + + Clear + Clear flag + 0 + + + + + TxE + Data register empty + (transmitters) + 7 + 1 + read-only + + TxE + read + + NotEmpty + Data register not empty + 0 + + + Empty + Data register empty + 1 + + + + + RxNE + Data register not empty + (receivers) + 6 + 1 + read-only + + RxNE + read + + Empty + Data register empty + 0 + + + NotEmpty + Data register not empty + 1 + + + + + STOPF + Stop detection (slave + mode) + 4 + 1 + read-only + + STOPF + read + + NoStop + No Stop condition detected + 0 + + + Stop + Stop condition detected + 1 + + + + + ADD10 + 10-bit header sent (Master + mode) + 3 + 1 + read-only + + + BTF + Byte transfer finished + 2 + 1 + read-only + + BTF + read + + NotFinished + Data byte transfer not done + 0 + + + Finished + Data byte transfer successful + 1 + + + + + ADDR + Address sent (master mode)/matched + (slave mode) + 1 + 1 + read-only + + ADDR + read + + NotMatch + Adress mismatched or not received + 0 + + + Match + Received slave address matched with one of the enabled slave addresses + 1 + + + + + SB + Start bit (Master mode) + 0 + 1 + read-only + + SB + read + + NoStart + No Start condition + 0 + + + Start + Start condition generated + 1 + + + + + + + SR2 + SR2 + Status register 2 + 0x18 + 0x20 + read-only + 0x00000000 + + + PEC + acket error checking + register + 8 + 8 + + + DUALF + Dual flag (Slave mode) + 7 + 1 + + + SMBHOST + SMBus host header (Slave + mode) + 6 + 1 + + + SMBDEFAULT + SMBus device default address (Slave + mode) + 5 + 1 + + + GENCALL + General call address (Slave + mode) + 4 + 1 + + + TRA + Transmitter/receiver + 2 + 1 + + + BUSY + Bus busy + 1 + 1 + + + MSL + Master/slave + 0 + 1 + + + + + CCR + CCR + Clock control register + 0x1C + 0x20 + read-write + 0x00000000 + + + F_S + I2C master mode selection + 15 + 1 + + F_S + read-write + + Standard + Standard mode I2C + 0 + + + Fast + Fast mode I2C + 1 + + + + + DUTY + Fast mode duty cycle + 14 + 1 + + DUTY + read-write + + Duty2_1 + Duty cycle t_low/t_high = 2/1 + 0 + + + Duty16_9 + Duty cycle t_low/t_high = 16/9 + 1 + + + + + CCR + Clock control register in Fast/Standard + mode (Master mode) + 0 + 12 + + + 1 + 4095 + + + + + + + TRISE + TRISE + TRISE register + 0x20 + 0x20 + read-write + 0x00000002 + + + TRISE + Maximum rise time in Fast/Standard mode + (Master mode) + 0 + 6 + + + 0 + 63 + + + + + + + FLTR + FLTR register + 0x24 + read-write + 0x00000000 + + + ANOFF + Analog noise filter + 4 + 1 + + ANOFF + read-write + + Enabled + Analog noise filter enabled + 0 + + + Disabled + Analog noise filter disabled + 1 + + + + + DNF + Digital noise filter + 0 + 4 + + DNF + read-write + + NoFilter + Digital filter disabled + 0 + + + Filter1 + Digital filter enabled and filtering capability up to 1 tI2CCLK + 1 + + + Filter2 + Digital filter enabled and filtering capability up to 2 tI2CCLK + 2 + + + Filter3 + Digital filter enabled and filtering capability up to 3 tI2CCLK + 3 + + + Filter4 + Digital filter enabled and filtering capability up to 4 tI2CCLK + 4 + + + Filter5 + Digital filter enabled and filtering capability up to 5 tI2CCLK + 5 + + + Filter6 + Digital filter enabled and filtering capability up to 6 tI2CCLK + 6 + + + Filter7 + Digital filter enabled and filtering capability up to 7 tI2CCLK + 7 + + + Filter8 + Digital filter enabled and filtering capability up to 8 tI2CCLK + 8 + + + Filter9 + Digital filter enabled and filtering capability up to 9 tI2CCLK + 9 + + + Filter10 + Digital filter enabled and filtering capability up to 10 tI2CCLK + 10 + + + Filter11 + Digital filter enabled and filtering capability up to 11 tI2CCLK + 11 + + + Filter12 + Digital filter enabled and filtering capability up to 12 tI2CCLK + 12 + + + Filter13 + Digital filter enabled and filtering capability up to 13 tI2CCLK + 13 + + + Filter14 + Digital filter enabled and filtering capability up to 14 tI2CCLK + 14 + + + Filter15 + Digital filter enabled and filtering capability up to 15 tI2CCLK + 15 + + + + + + + + + I2S2ext + 0x40003400 + + I2C1_EV + I2C1 event interrupt + 31 + + + I2C1_ER + I2C1 error interrupt + 32 + + + + I2S3ext + 0x40004000 + + + SPI1 + Serial peripheral interface + SPI + 0x40013000 + + 0x0 + 0x400 + registers + + + + CR1 + CR1 + control register 1 + 0x0 + 0x20 + read-write + 0x00000000 + + + BIDIMODE + Bidirectional data mode + enable + 15 + 1 + + BIDIMODE + read-write + + Unidirectional + 2-line unidirectional data mode selected + 0 + + + Bidirectional + 1-line bidirectional data mode selected + 1 + + + + + BIDIOE + Output enable in bidirectional + mode + 14 + 1 + + BIDIOE + read-write + + OutputDisabled + Output disabled (receive-only mode) + 0 + + + OutputEnabled + Output enabled (transmit-only mode) + 1 + + + + + CRCEN + Hardware CRC calculation + enable + 13 + 1 + + CRCEN + read-write + + Disabled + CRC calculation disabled + 0 + + + Enabled + CRC calculation enabled + 1 + + + + + CRCNEXT + CRC transfer next + 12 + 1 + + CRCNEXT + read-write + + TxBuffer + Next transmit value is from Tx buffer + 0 + + + CRC + Next transmit value is from Tx CRC register + 1 + + + + + DFF + Data frame format + 11 + 1 + + DFF + read-write + + EightBit + 8-bit data frame format is selected for transmission/reception + 0 + + + SixteenBit + 16-bit data frame format is selected for transmission/reception + 1 + + + + + RXONLY + Receive only + 10 + 1 + + RXONLY + read-write + + FullDuplex + Full duplex (Transmit and receive) + 0 + + + OutputDisabled + Output disabled (Receive-only mode) + 1 + + + + + SSM + Software slave management + 9 + 1 + + SSM + read-write + + Disabled + Software slave management disabled + 0 + + + Enabled + Software slave management enabled + 1 + + + + + SSI + Internal slave select + 8 + 1 + + SSI + read-write + + SlaveSelected + 0 is forced onto the NSS pin and the I/O value of the NSS pin is ignored + 0 + + + SlaveNotSelected + 1 is forced onto the NSS pin and the I/O value of the NSS pin is ignored + 1 + + + + + LSBFIRST + Frame format + 7 + 1 + + LSBFIRST + read-write + + MSBFirst + Data is transmitted/received with the MSB first + 0 + + + LSBFirst + Data is transmitted/received with the LSB first + 1 + + + + + SPE + SPI enable + 6 + 1 + + SPE + read-write + + Disabled + Peripheral disabled + 0 + + + Enabled + Peripheral enabled + 1 + + + + + BR + Baud rate control + 3 + 3 + + BR + read-write + + Div2 + f_PCLK / 2 + 0 + + + Div4 + f_PCLK / 4 + 1 + + + Div8 + f_PCLK / 8 + 2 + + + Div16 + f_PCLK / 16 + 3 + + + Div32 + f_PCLK / 32 + 4 + + + Div64 + f_PCLK / 64 + 5 + + + Div128 + f_PCLK / 128 + 6 + + + Div256 + f_PCLK / 256 + 7 + + + + + MSTR + Master selection + 2 + 1 + + MSTR + read-write + + Slave + Slave configuration + 0 + + + Master + Master configuration + 1 + + + + + CPOL + Clock polarity + 1 + 1 + + CPOL + read-write + + IdleLow + CK to 0 when idle + 0 + + + IdleHigh + CK to 1 when idle + 1 + + + + + CPHA + Clock phase + 0 + 1 + + CPHA + read-write + + FirstEdge + The first clock transition is the first data capture edge + 0 + + + SecondEdge + The second clock transition is the first data capture edge + 1 + + + + + + + CR2 + CR2 + control register 2 + 0x4 + 0x20 + read-write + 0x00000000 + + + TXEIE + Tx buffer empty interrupt + enable + 7 + 1 + + TXEIE + read-write + + Masked + TXE interrupt masked + 0 + + + NotMasked + TXE interrupt not masked + 1 + + + + + RXNEIE + RX buffer not empty interrupt + enable + 6 + 1 + + RXNEIE + read-write + + Masked + RXE interrupt masked + 0 + + + NotMasked + RXE interrupt not masked + 1 + + + + + ERRIE + Error interrupt enable + 5 + 1 + + ERRIE + read-write + + Masked + Error interrupt masked + 0 + + + NotMasked + Error interrupt not masked + 1 + + + + + FRF + Frame format + 4 + 1 + + FRF + read-write + + Motorola + SPI Motorola mode + 0 + + + TI + SPI TI mode + 1 + + + + + SSOE + SS output enable + 2 + 1 + + SSOE + read-write + + Disabled + SS output is disabled in master mode + 0 + + + Enabled + SS output is enabled in master mode + 1 + + + + + TXDMAEN + Tx buffer DMA enable + 1 + 1 + + TXDMAEN + read-write + + Disabled + Tx buffer DMA disabled + 0 + + + Enabled + Tx buffer DMA enabled + 1 + + + + + RXDMAEN + Rx buffer DMA enable + 0 + 1 + + RXDMAEN + read-write + + Disabled + Rx buffer DMA disabled + 0 + + + Enabled + Rx buffer DMA enabled + 1 + + + + + + + SR + SR + status register + 0x8 + 0x20 + 0x00000002 + + + FRE + TI frame format error + 8 + 1 + read-only + + FRER + read + + NoError + No frame format error + 0 + + + Error + A frame format error occurred + 1 + + + + + BSY + Busy flag + 7 + 1 + read-only + + BSYR + read + + NotBusy + SPI not busy + 0 + + + Busy + SPI busy + 1 + + + + + OVR + Overrun flag + 6 + 1 + read-only + + OVRR + read + + NoOverrun + No overrun occurred + 0 + + + Overrun + Overrun occurred + 1 + + + + + MODF + Mode fault + 5 + 1 + read-only + + MODFR + read + + NoFault + No mode fault occurred + 0 + + + Fault + Mode fault occurred + 1 + + + + + CRCERR + CRC error flag + 4 + 1 + read-write + zeroToClear + + CRCERRR + read + + Match + CRC value received matches the SPIx_RXCRCR value + 0 + + + NoMatch + CRC value received does not match the SPIx_RXCRCR value + 1 + + + + CRCERRW + write + + Clear + Clear flag + 0 + + + + + UDR + Underrun flag + 3 + 1 + read-only + + UDRR + read + + NoUnderrun + No underrun occurred + 0 + + + Underrun + Underrun occurred + 1 + + + + + CHSIDE + Channel side + 2 + 1 + read-only + + CHSIDE + read + + Left + Channel left has to be transmitted or has been received + 0 + + + Right + Channel right has to be transmitted or has been received + 1 + + + + + TXE + Transmit buffer empty + 1 + 1 + read-only + + TXE + read + + NotEmpty + Tx buffer not empty + 0 + + + Empty + Tx buffer empty + 1 + + + + + RXNE + Receive buffer not empty + 0 + 1 + read-only + + RXNE + read + + Empty + Rx buffer empty + 0 + + + NotEmpty + Rx buffer not empty + 1 + + + + + + + DR + DR + data register + 0xC + 0x20 + read-write + 0x00000000 + + + DR + Data register + 0 + 16 + + + 0 + 65535 + + + + + + + CRCPR + CRCPR + CRC polynomial register + 0x10 + 0x20 + read-write + 0x00000007 + + + CRCPOLY + CRC polynomial register + 0 + 16 + + + 0 + 65535 + + + + + + + RXCRCR + RXCRCR + RX CRC register + 0x14 + 0x20 + read-only + 0x00000000 + + + RxCRC + Rx CRC register + 0 + 16 + + + 0 + 65535 + + + + + + + TXCRCR + TXCRCR + TX CRC register + 0x18 + 0x20 + read-only + 0x00000000 + + + TxCRC + Tx CRC register + 0 + 16 + + + 0 + 65535 + + + + + + + I2SCFGR + I2SCFGR + I2S configuration register + 0x1C + 0x20 + read-write + 0x00000000 + + + I2SMOD + I2S mode selection + 11 + 1 + + I2SMOD + read-write + + SPIMode + SPI mode is selected + 0 + + + I2SMode + I2S mode is selected + 1 + + + + + I2SE + I2S Enable + 10 + 1 + + I2SE + read-write + + Disabled + I2S peripheral is disabled + 0 + + + Enabled + I2S peripheral is enabled + 1 + + + + + I2SCFG + I2S configuration mode + 8 + 2 + + I2SCFG + read-write + + SlaveTx + Slave - transmit + 0 + + + SlaveRx + Slave - receive + 1 + + + MasterTx + Master - transmit + 2 + + + MasterRx + Master - receive + 3 + + + + + PCMSYNC + PCM frame synchronization + 7 + 1 + + PCMSYNC + read-write + + Short + Short frame synchronisation + 0 + + + Long + Long frame synchronisation + 1 + + + + + I2SSTD + I2S standard selection + 4 + 2 + + I2SSTD + read-write + + Philips + I2S Philips standard + 0 + + + MSB + MSB justified standard + 1 + + + LSB + LSB justified standard + 2 + + + PCM + PCM standard + 3 + + + + + CKPOL + Steady state clock + polarity + 3 + 1 + + CKPOL + read-write + + IdleLow + I2S clock inactive state is low level + 0 + + + IdleHigh + I2S clock inactive state is high level + 1 + + + + + DATLEN + Data length to be + transferred + 1 + 2 + + DATLEN + read-write + + SixteenBit + 16-bit data length + 0 + + + TwentyFourBit + 24-bit data length + 1 + + + ThirtyTwoBit + 32-bit data length + 2 + + + + + CHLEN + Channel length (number of bits per audio + channel) + 0 + 1 + + CHLEN + read-write + + SixteenBit + 16-bit wide + 0 + + + ThirtyTwoBit + 32-bit wide + 1 + + + + + + + I2SPR + I2SPR + I2S prescaler register + 0x20 + 0x20 + read-write + 0x0000000A + + + MCKOE + Master clock output enable + 9 + 1 + + MCKOE + read-write + + Disabled + Master clock output is disabled + 0 + + + Enabled + Master clock output is enabled + 1 + + + + + ODD + Odd factor for the + prescaler + 8 + 1 + + ODD + read-write + + Even + Real divider value is I2SDIV * 2 + 0 + + + Odd + Real divider value is (I2SDIV * 2) + 1 + 1 + + + + + I2SDIV + I2S Linear prescaler + 0 + 8 + + + 2 + 255 + + + + + + + + + SPI2 + 0x40003800 + + SPI1 + SPI1 global interrupt + 35 + + + + SPI3 + 0x40003C00 + + SPI2 + SPI2 global interrupt + 36 + + + + SPI4 + 0x40013400 + + SPI3 + SPI3 global interrupt + 51 + + + + NVIC + Nested Vectored Interrupt + Controller + NVIC + 0xE000E100 + + 0x0 + 0x351 + registers + + + + ISER0 + ISER0 + Interrupt Set-Enable Register + 0x0 + 0x20 + read-write + 0x00000000 + + + SETENA + SETENA + 0 + 32 + + + + + ISER1 + ISER1 + Interrupt Set-Enable Register + 0x4 + 0x20 + read-write + 0x00000000 + + + SETENA + SETENA + 0 + 32 + + + + + ISER2 + ISER2 + Interrupt Set-Enable Register + 0x8 + 0x20 + read-write + 0x00000000 + + + SETENA + SETENA + 0 + 32 + + + + + ICER0 + ICER0 + Interrupt Clear-Enable + Register + 0x80 + 0x20 + read-write + 0x00000000 + + + CLRENA + CLRENA + 0 + 32 + + + + + ICER1 + ICER1 + Interrupt Clear-Enable + Register + 0x84 + 0x20 + read-write + 0x00000000 + + + CLRENA + CLRENA + 0 + 32 + + + + + ICER2 + ICER2 + Interrupt Clear-Enable + Register + 0x88 + 0x20 + read-write + 0x00000000 + + + CLRENA + CLRENA + 0 + 32 + + + + + ISPR0 + ISPR0 + Interrupt Set-Pending Register + 0x100 + 0x20 + read-write + 0x00000000 + + + SETPEND + SETPEND + 0 + 32 + + + + + ISPR1 + ISPR1 + Interrupt Set-Pending Register + 0x104 + 0x20 + read-write + 0x00000000 + + + SETPEND + SETPEND + 0 + 32 + + + + + ISPR2 + ISPR2 + Interrupt Set-Pending Register + 0x108 + 0x20 + read-write + 0x00000000 + + + SETPEND + SETPEND + 0 + 32 + + + + + ICPR0 + ICPR0 + Interrupt Clear-Pending + Register + 0x180 + 0x20 + read-write + 0x00000000 + + + CLRPEND + CLRPEND + 0 + 32 + + + + + ICPR1 + ICPR1 + Interrupt Clear-Pending + Register + 0x184 + 0x20 + read-write + 0x00000000 + + + CLRPEND + CLRPEND + 0 + 32 + + + + + ICPR2 + ICPR2 + Interrupt Clear-Pending + Register + 0x188 + 0x20 + read-write + 0x00000000 + + + CLRPEND + CLRPEND + 0 + 32 + + + + + IABR0 + IABR0 + Interrupt Active Bit Register + 0x200 + 0x20 + read-only + 0x00000000 + + + ACTIVE + ACTIVE + 0 + 32 + + + + + IABR1 + IABR1 + Interrupt Active Bit Register + 0x204 + 0x20 + read-only + 0x00000000 + + + ACTIVE + ACTIVE + 0 + 32 + + + + + IABR2 + IABR2 + Interrupt Active Bit Register + 0x208 + 0x20 + read-only + 0x00000000 + + + ACTIVE + ACTIVE + 0 + 32 + + + + + IPR0 + IPR0 + Interrupt Priority Register + 0x300 + 0x20 + read-write + 0x00000000 + + + IPR_N0 + IPR_N0 + 0 + 8 + + + IPR_N1 + IPR_N1 + 8 + 8 + + + IPR_N2 + IPR_N2 + 16 + 8 + + + IPR_N3 + IPR_N3 + 24 + 8 + + + + + IPR1 + IPR1 + Interrupt Priority Register + 0x304 + 0x20 + read-write + 0x00000000 + + + IPR_N0 + IPR_N0 + 0 + 8 + + + IPR_N1 + IPR_N1 + 8 + 8 + + + IPR_N2 + IPR_N2 + 16 + 8 + + + IPR_N3 + IPR_N3 + 24 + 8 + + + + + IPR2 + IPR2 + Interrupt Priority Register + 0x308 + 0x20 + read-write + 0x00000000 + + + IPR_N0 + IPR_N0 + 0 + 8 + + + IPR_N1 + IPR_N1 + 8 + 8 + + + IPR_N2 + IPR_N2 + 16 + 8 + + + IPR_N3 + IPR_N3 + 24 + 8 + + + + + IPR3 + IPR3 + Interrupt Priority Register + 0x30C + 0x20 + read-write + 0x00000000 + + + IPR_N0 + IPR_N0 + 0 + 8 + + + IPR_N1 + IPR_N1 + 8 + 8 + + + IPR_N2 + IPR_N2 + 16 + 8 + + + IPR_N3 + IPR_N3 + 24 + 8 + + + + + IPR4 + IPR4 + Interrupt Priority Register + 0x310 + 0x20 + read-write + 0x00000000 + + + IPR_N0 + IPR_N0 + 0 + 8 + + + IPR_N1 + IPR_N1 + 8 + 8 + + + IPR_N2 + IPR_N2 + 16 + 8 + + + IPR_N3 + IPR_N3 + 24 + 8 + + + + + IPR5 + IPR5 + Interrupt Priority Register + 0x314 + 0x20 + read-write + 0x00000000 + + + IPR_N0 + IPR_N0 + 0 + 8 + + + IPR_N1 + IPR_N1 + 8 + 8 + + + IPR_N2 + IPR_N2 + 16 + 8 + + + IPR_N3 + IPR_N3 + 24 + 8 + + + + + IPR6 + IPR6 + Interrupt Priority Register + 0x318 + 0x20 + read-write + 0x00000000 + + + IPR_N0 + IPR_N0 + 0 + 8 + + + IPR_N1 + IPR_N1 + 8 + 8 + + + IPR_N2 + IPR_N2 + 16 + 8 + + + IPR_N3 + IPR_N3 + 24 + 8 + + + + + IPR7 + IPR7 + Interrupt Priority Register + 0x31C + 0x20 + read-write + 0x00000000 + + + IPR_N0 + IPR_N0 + 0 + 8 + + + IPR_N1 + IPR_N1 + 8 + 8 + + + IPR_N2 + IPR_N2 + 16 + 8 + + + IPR_N3 + IPR_N3 + 24 + 8 + + + + + IPR8 + IPR8 + Interrupt Priority Register + 0x320 + 0x20 + read-write + 0x00000000 + + + IPR_N0 + IPR_N0 + 0 + 8 + + + IPR_N1 + IPR_N1 + 8 + 8 + + + IPR_N2 + IPR_N2 + 16 + 8 + + + IPR_N3 + IPR_N3 + 24 + 8 + + + + + IPR9 + IPR9 + Interrupt Priority Register + 0x324 + 0x20 + read-write + 0x00000000 + + + IPR_N0 + IPR_N0 + 0 + 8 + + + IPR_N1 + IPR_N1 + 8 + 8 + + + IPR_N2 + IPR_N2 + 16 + 8 + + + IPR_N3 + IPR_N3 + 24 + 8 + + + + + IPR10 + IPR10 + Interrupt Priority Register + 0x328 + 0x20 + read-write + 0x00000000 + + + IPR_N0 + IPR_N0 + 0 + 8 + + + IPR_N1 + IPR_N1 + 8 + 8 + + + IPR_N2 + IPR_N2 + 16 + 8 + + + IPR_N3 + IPR_N3 + 24 + 8 + + + + + IPR11 + IPR11 + Interrupt Priority Register + 0x32C + 0x20 + read-write + 0x00000000 + + + IPR_N0 + IPR_N0 + 0 + 8 + + + IPR_N1 + IPR_N1 + 8 + 8 + + + IPR_N2 + IPR_N2 + 16 + 8 + + + IPR_N3 + IPR_N3 + 24 + 8 + + + + + IPR12 + IPR12 + Interrupt Priority Register + 0x330 + 0x20 + read-write + 0x00000000 + + + IPR_N0 + IPR_N0 + 0 + 8 + + + IPR_N1 + IPR_N1 + 8 + 8 + + + IPR_N2 + IPR_N2 + 16 + 8 + + + IPR_N3 + IPR_N3 + 24 + 8 + + + + + IPR13 + IPR13 + Interrupt Priority Register + 0x334 + 0x20 + read-write + 0x00000000 + + + IPR_N0 + IPR_N0 + 0 + 8 + + + IPR_N1 + IPR_N1 + 8 + 8 + + + IPR_N2 + IPR_N2 + 16 + 8 + + + IPR_N3 + IPR_N3 + 24 + 8 + + + + + IPR14 + IPR14 + Interrupt Priority Register + 0x338 + 0x20 + read-write + 0x00000000 + + + IPR_N0 + IPR_N0 + 0 + 8 + + + IPR_N1 + IPR_N1 + 8 + 8 + + + IPR_N2 + IPR_N2 + 16 + 8 + + + IPR_N3 + IPR_N3 + 24 + 8 + + + + + IPR15 + IPR15 + Interrupt Priority Register + 0x33C + 0x20 + read-write + 0x00000000 + + + IPR_N0 + IPR_N0 + 0 + 8 + + + IPR_N1 + IPR_N1 + 8 + 8 + + + IPR_N2 + IPR_N2 + 16 + 8 + + + IPR_N3 + IPR_N3 + 24 + 8 + + + + + IPR16 + IPR16 + Interrupt Priority Register + 0x340 + 0x20 + read-write + 0x00000000 + + + IPR_N0 + IPR_N0 + 0 + 8 + + + IPR_N1 + IPR_N1 + 8 + 8 + + + IPR_N2 + IPR_N2 + 16 + 8 + + + IPR_N3 + IPR_N3 + 24 + 8 + + + + + IPR17 + IPR17 + Interrupt Priority Register + 0x344 + 0x20 + read-write + 0x00000000 + + + IPR_N0 + IPR_N0 + 0 + 8 + + + IPR_N1 + IPR_N1 + 8 + 8 + + + IPR_N2 + IPR_N2 + 16 + 8 + + + IPR_N3 + IPR_N3 + 24 + 8 + + + + + IPR18 + IPR18 + Interrupt Priority Register + 0x348 + 0x20 + read-write + 0x00000000 + + + IPR_N0 + IPR_N0 + 0 + 8 + + + IPR_N1 + IPR_N1 + 8 + 8 + + + IPR_N2 + IPR_N2 + 16 + 8 + + + IPR_N3 + IPR_N3 + 24 + 8 + + + + + IPR19 + IPR19 + Interrupt Priority Register + 0x34C + 0x20 + read-write + 0x00000000 + + + IPR_N0 + IPR_N0 + 0 + 8 + + + IPR_N1 + IPR_N1 + 8 + 8 + + + IPR_N2 + IPR_N2 + 16 + 8 + + + IPR_N3 + IPR_N3 + 24 + 8 + + + + + + + FPU + Floting point unit + FPU + 0xE000EF34 + + 0x0 + 0xD + registers + + + FPU + Floating point unit interrupt + 81 + + + + FPCCR + FPCCR + Floating-point context control + register + 0x0 + 0x20 + read-write + 0x00000000 + + + LSPACT + LSPACT + 0 + 1 + + + USER + USER + 1 + 1 + + + THREAD + THREAD + 3 + 1 + + + HFRDY + HFRDY + 4 + 1 + + + MMRDY + MMRDY + 5 + 1 + + + BFRDY + BFRDY + 6 + 1 + + + MONRDY + MONRDY + 8 + 1 + + + LSPEN + LSPEN + 30 + 1 + + + ASPEN + ASPEN + 31 + 1 + + + + + FPCAR + FPCAR + Floating-point context address + register + 0x4 + 0x20 + read-write + 0x00000000 + + + ADDRESS + Location of unpopulated + floating-point + 3 + 29 + + + + + FPSCR + FPSCR + Floating-point status control + register + 0x8 + 0x20 + read-write + 0x00000000 + + + IOC + Invalid operation cumulative exception + bit + 0 + 1 + + + DZC + Division by zero cumulative exception + bit. + 1 + 1 + + + OFC + Overflow cumulative exception + bit + 2 + 1 + + + UFC + Underflow cumulative exception + bit + 3 + 1 + + + IXC + Inexact cumulative exception + bit + 4 + 1 + + + IDC + Input denormal cumulative exception + bit. + 7 + 1 + + + RMode + Rounding Mode control + field + 22 + 2 + + + FZ + Flush-to-zero mode control + bit: + 24 + 1 + + + DN + Default NaN mode control + bit + 25 + 1 + + + AHP + Alternative half-precision control + bit + 26 + 1 + + + V + Overflow condition code + flag + 28 + 1 + + + C + Carry condition code flag + 29 + 1 + + + Z + Zero condition code flag + 30 + 1 + + + N + Negative condition code + flag + 31 + 1 + + + + + + + MPU + Memory protection unit + MPU + 0xE000ED90 + + 0x0 + 0x15 + registers + + + + TYPER + TYPER + MPU type register + 0x0 + 0x20 + read-only + 0x00000800 + + + SEPARATE + Separate flag + 0 + 1 + + + DREGION + Number of MPU data regions + 8 + 8 + + + IREGION + Number of MPU instruction + regions + 16 + 8 + + + + + CTRL + CTRL + MPU control register + 0x4 + 0x20 + read-only + 0x00000000 + + + ENABLE + Enables the MPU + 0 + 1 + + + HFNMIENA + Enables the operation of MPU during hard + fault + 1 + 1 + + + PRIVDEFENA + Enable priviliged software access to + default memory map + 2 + 1 + + + + + RNR + RNR + MPU region number register + 0x8 + 0x20 + read-write + 0x00000000 + + + REGION + MPU region + 0 + 8 + + + + + RBAR + RBAR + MPU region base address + register + 0xC + 0x20 + read-write + 0x00000000 + + + REGION + MPU region field + 0 + 4 + + + VALID + MPU region number valid + 4 + 1 + + + ADDR + Region base address field + 5 + 27 + + + + + RASR + RASR + MPU region attribute and size + register + 0x10 + 0x20 + read-write + 0x00000000 + + + ENABLE + Region enable bit. + 0 + 1 + + + SIZE + Size of the MPU protection + region + 1 + 5 + + + SRD + Subregion disable bits + 8 + 8 + + + B + memory attribute + 16 + 1 + + + C + memory attribute + 17 + 1 + + + S + Shareable memory attribute + 18 + 1 + + + TEX + memory attribute + 19 + 3 + + + AP + Access permission + 24 + 3 + + + XN + Instruction access disable + bit + 28 + 1 + + + + + + + STK + SysTick timer + STK + 0xE000E010 + + 0x0 + 0x11 + registers + + + + CTRL + CTRL + SysTick control and status + register + 0x0 + 0x20 + read-write + 0x00000000 + + + ENABLE + Counter enable + 0 + 1 + + + TICKINT + SysTick exception request + enable + 1 + 1 + + + CLKSOURCE + Clock source selection + 2 + 1 + + + COUNTFLAG + COUNTFLAG + 16 + 1 + + + + + LOAD + LOAD + SysTick reload value register + 0x4 + 0x20 + read-write + 0x00000000 + + + RELOAD + RELOAD value + 0 + 24 + + + + + VAL + VAL + SysTick current value register + 0x8 + 0x20 + read-write + 0x00000000 + + + CURRENT + Current counter value + 0 + 24 + + + + + CALIB + CALIB + SysTick calibration value + register + 0xC + 0x20 + read-write + 0x00000000 + + + TENMS + Calibration value + 0 + 24 + + + SKEW + SKEW flag: Indicates whether the TENMS + value is exact + 30 + 1 + + + NOREF + NOREF flag. Reads as zero + 31 + 1 + + + + + + + SCB + System control block + SCB + 0xE000ED00 + + 0x0 + 0x41 + registers + + + + CPUID + CPUID + CPUID base register + 0x0 + 0x20 + read-only + 0x410FC241 + + + Revision + Revision number + 0 + 4 + + + PartNo + Part number of the + processor + 4 + 12 + + + Constant + Reads as 0xF + 16 + 4 + + + Variant + Variant number + 20 + 4 + + + Implementer + Implementer code + 24 + 8 + + + + + ICSR + ICSR + Interrupt control and state + register + 0x4 + 0x20 + read-write + 0x00000000 + + + VECTACTIVE + Active vector + 0 + 9 + + + RETTOBASE + Return to base level + 11 + 1 + + + VECTPENDING + Pending vector + 12 + 7 + + + ISRPENDING + Interrupt pending flag + 22 + 1 + + + PENDSTCLR + SysTick exception clear-pending + bit + 25 + 1 + + + PENDSTSET + SysTick exception set-pending + bit + 26 + 1 + + + PENDSVCLR + PendSV clear-pending bit + 27 + 1 + + + PENDSVSET + PendSV set-pending bit + 28 + 1 + + + NMIPENDSET + NMI set-pending bit. + 31 + 1 + + + + + VTOR + VTOR + Vector table offset register + 0x8 + 0x20 + read-write + 0x00000000 + + + TBLOFF + Vector table base offset + field + 9 + 21 + + + + + AIRCR + AIRCR + Application interrupt and reset control + register + 0xC + 0x20 + read-write + 0x00000000 + + + VECTRESET + VECTRESET + 0 + 1 + + + VECTCLRACTIVE + VECTCLRACTIVE + 1 + 1 + + + SYSRESETREQ + SYSRESETREQ + 2 + 1 + + + PRIGROUP + PRIGROUP + 8 + 3 + + + ENDIANESS + ENDIANESS + 15 + 1 + + + VECTKEYSTAT + Register key + 16 + 16 + + + + + SCR + SCR + System control register + 0x10 + 0x20 + read-write + 0x00000000 + + + SLEEPONEXIT + SLEEPONEXIT + 1 + 1 + + + SLEEPDEEP + SLEEPDEEP + 2 + 1 + + + SEVEONPEND + Send Event on Pending bit + 4 + 1 + + + + + CCR + CCR + Configuration and control + register + 0x14 + 0x20 + read-write + 0x00000000 + + + NONBASETHRDENA + Configures how the processor enters + Thread mode + 0 + 1 + + + USERSETMPEND + USERSETMPEND + 1 + 1 + + + UNALIGN__TRP + UNALIGN_ TRP + 3 + 1 + + + DIV_0_TRP + DIV_0_TRP + 4 + 1 + + + BFHFNMIGN + BFHFNMIGN + 8 + 1 + + + STKALIGN + STKALIGN + 9 + 1 + + + + + SHPR1 + SHPR1 + System handler priority + registers + 0x18 + 0x20 + read-write + 0x00000000 + + + PRI_4 + Priority of system handler + 4 + 0 + 8 + + + PRI_5 + Priority of system handler + 5 + 8 + 8 + + + PRI_6 + Priority of system handler + 6 + 16 + 8 + + + + + SHPR2 + SHPR2 + System handler priority + registers + 0x1C + 0x20 + read-write + 0x00000000 + + + PRI_11 + Priority of system handler + 11 + 24 + 8 + + + + + SHPR3 + SHPR3 + System handler priority + registers + 0x20 + 0x20 + read-write + 0x00000000 + + + PRI_14 + Priority of system handler + 14 + 16 + 8 + + + PRI_15 + Priority of system handler + 15 + 24 + 8 + + + + + SHCRS + SHCRS + System handler control and state + register + 0x24 + 0x20 + read-write + 0x00000000 + + + MEMFAULTACT + Memory management fault exception active + bit + 0 + 1 + + + BUSFAULTACT + Bus fault exception active + bit + 1 + 1 + + + USGFAULTACT + Usage fault exception active + bit + 3 + 1 + + + SVCALLACT + SVC call active bit + 7 + 1 + + + MONITORACT + Debug monitor active bit + 8 + 1 + + + PENDSVACT + PendSV exception active + bit + 10 + 1 + + + SYSTICKACT + SysTick exception active + bit + 11 + 1 + + + USGFAULTPENDED + Usage fault exception pending + bit + 12 + 1 + + + MEMFAULTPENDED + Memory management fault exception + pending bit + 13 + 1 + + + BUSFAULTPENDED + Bus fault exception pending + bit + 14 + 1 + + + SVCALLPENDED + SVC call pending bit + 15 + 1 + + + MEMFAULTENA + Memory management fault enable + bit + 16 + 1 + + + BUSFAULTENA + Bus fault enable bit + 17 + 1 + + + USGFAULTENA + Usage fault enable bit + 18 + 1 + + + + + CFSR_UFSR_BFSR_MMFSR + CFSR_UFSR_BFSR_MMFSR + Configurable fault status + register + 0x28 + 0x20 + read-write + 0x00000000 + + + IACCVIOL + Instruction access violation + flag + 1 + 1 + + + MUNSTKERR + Memory manager fault on unstacking for a + return from exception + 3 + 1 + + + MSTKERR + Memory manager fault on stacking for + exception entry. + 4 + 1 + + + MLSPERR + MLSPERR + 5 + 1 + + + MMARVALID + Memory Management Fault Address Register + (MMAR) valid flag + 7 + 1 + + + IBUSERR + Instruction bus error + 8 + 1 + + + PRECISERR + Precise data bus error + 9 + 1 + + + IMPRECISERR + Imprecise data bus error + 10 + 1 + + + UNSTKERR + Bus fault on unstacking for a return + from exception + 11 + 1 + + + STKERR + Bus fault on stacking for exception + entry + 12 + 1 + + + LSPERR + Bus fault on floating-point lazy state + preservation + 13 + 1 + + + BFARVALID + Bus Fault Address Register (BFAR) valid + flag + 15 + 1 + + + UNDEFINSTR + Undefined instruction usage + fault + 16 + 1 + + + INVSTATE + Invalid state usage fault + 17 + 1 + + + INVPC + Invalid PC load usage + fault + 18 + 1 + + + NOCP + No coprocessor usage + fault. + 19 + 1 + + + UNALIGNED + Unaligned access usage + fault + 24 + 1 + + + DIVBYZERO + Divide by zero usage fault + 25 + 1 + + + + + HFSR + HFSR + Hard fault status register + 0x2C + 0x20 + read-write + 0x00000000 + + + VECTTBL + Vector table hard fault + 1 + 1 + + + FORCED + Forced hard fault + 30 + 1 + + + DEBUG_VT + Reserved for Debug use + 31 + 1 + + + + + MMFAR + MMFAR + Memory management fault address + register + 0x34 + 0x20 + read-write + 0x00000000 + + + MMFAR + Memory management fault + address + 0 + 32 + + + + + BFAR + BFAR + Bus fault address register + 0x38 + 0x20 + read-write + 0x00000000 + + + BFAR + Bus fault address + 0 + 32 + + + + + AFSR + AFSR + Auxiliary fault status + register + 0x3C + 0x20 + read-write + 0x00000000 + + + IMPDEF + Implementation defined + 0 + 32 + + + + + + + NVIC_STIR + Nested vectored interrupt + controller + NVIC + 0xE000EF00 + + 0x0 + 0x5 + registers + + + + STIR + STIR + Software trigger interrupt + register + 0x0 + 0x20 + read-write + 0x00000000 + + + INTID + Software generated interrupt + ID + 0 + 9 + + + + + + + FPU_CPACR + Floating point unit CPACR + FPU + 0xE000ED88 + + 0x0 + 0x5 + registers + + + + CPACR + CPACR + Coprocessor access control + register + 0x0 + 0x20 + read-write + 0x00000000 + + + CP + CP + 20 + 4 + + + + + + + SCB_ACTRL + System control block ACTLR + SCB + 0xE000E008 + + 0x0 + 0x5 + registers + + + + ACTRL + ACTRL + Auxiliary control register + 0x0 + 0x20 + read-write + 0x00000000 + + + DISMCYCINT + DISMCYCINT + 0 + 1 + + + DISDEFWBUF + DISDEFWBUF + 1 + 1 + + + DISFOLD + DISFOLD + 2 + 1 + + + DISFPCA + DISFPCA + 8 + 1 + + + DISOOFP + DISOOFP + 9 + 1 + + + + + + + \ No newline at end of file diff --git a/nodes/embassy/sensors/Cargo.toml b/nodes/embassy/sensors/Cargo.toml new file mode 100644 index 00000000..c0aecf94 --- /dev/null +++ b/nodes/embassy/sensors/Cargo.toml @@ -0,0 +1,28 @@ +[package] +name = "sensors" +version = "0.1.0" +rust-version.workspace = true +edition.workspace = true +license.workspace = true +authors.workspace = true + +[dependencies] +protocol = { workspace = true } +embassy-stm32.workspace = true +embassy-sync.workspace = true +embassy-time.workspace = true +embassy-futures.workspace = true +embassy-embedded-hal.workspace = true + +defmt.workspace = true + +embedded-hal = "1.0.0" +embedded-hal-async = "1.0" + +# sensors +bosch-bme680 = { version = "1.0.2", path = "/home/david/Documents/async-bosch-bme680" } +max44009 = { version = "0.2", git = "https://github.com/dvdsk/max44009-rs" } +sht31 = { version = "0.3.0", git = "https://github.com/dvdsk/SHT31-rs", features = ["postcard"] } +mhzx = { version = "0.3.0", path = "/home/david/tmp/mh-zx-driver", features = ["serde", "postcard"] } +sps30-async = { version = "0.3.0", path = "/home/david/tmp/sps30", features = ["serde", "postcard"] } +nau7802-async = { path = "/home/david/tmp/nau7802-rs", features = ["serde", "postcard", "defmt"] } diff --git a/nodes/embassy/sensors/src/button.rs b/nodes/embassy/sensors/src/button.rs new file mode 100644 index 00000000..6a7ff5d1 --- /dev/null +++ b/nodes/embassy/sensors/src/button.rs @@ -0,0 +1,69 @@ +use embassy_stm32::exti::ExtiInput; +use embassy_time::{Duration, Instant, Timer}; +use protocol::button; + +pub async fn watch_array( + buttons: [(ExtiInput<'static>, F); N], + on_button: impl Fn(B) + Clone, +) where + B: defmt::Format, + F: Fn(protocol::button::Press) -> B + Clone, +{ + embassy_futures::join::join_array(buttons.map(|(input, into_button)| { + let local_into_button = into_button.clone(); + let on_err = move || print_error(&local_into_button); + + let local_into_button = into_button.clone(); + let local_on_button = on_button.clone(); + let on_ok = move |press| { + let on_button = &local_on_button; + let into_button = &local_into_button; + on_button(into_button(press)); + }; + + watch_button(input, on_ok, on_err) + })) + .await; +} + +fn print_error( + into_reading: impl Fn(protocol::button::Press) -> B, +) { + let event_for_printing = into_reading(protocol::button::Press(0)); + let name = event_for_printing; // todo variant trait + defmt::error!("Button pressed too long: {:?}", name); +} + +async fn watch_button( + mut input: ExtiInput<'static>, + on_ok_press: impl Fn(protocol::button::Press), + on_err_press: impl Fn(), +) { + let mut went_high_at: Option = None; + loop { + if let Some(went_high_at) = went_high_at.take() { + input.wait_for_low().await; + let press = went_high_at.elapsed(); + let Ok(press) = press.as_millis().try_into().map(button::Press) + else { + on_err_press(); + continue; + }; + on_ok_press(press); + } else { + input.wait_for_high().await; + Timer::after(Duration::from_millis(20)).await; + if input.is_low() { + continue; + } + Timer::after(Duration::from_millis(20)).await; + if input.is_low() { + continue; + } + Timer::after(Duration::from_millis(10)).await; + if input.is_high() { + went_high_at = Some(Instant::now()); + } + } + } +} diff --git a/nodes/embassy/sensors/src/drivers.rs b/nodes/embassy/sensors/src/drivers.rs new file mode 100644 index 00000000..0bcd8704 --- /dev/null +++ b/nodes/embassy/sensors/src/drivers.rs @@ -0,0 +1,46 @@ +mod driver_impl_bme680; +mod driver_impl_max44009; +mod driver_impl_nau7802; +mod driver_impl_sht31; +mod wrap_mhz; +mod wrap_sps30; + +mod reinit_on_error; +mod i2c_wrapper; + +pub use i2c_wrapper::I2cWrapper; +use reinit_on_error::ReInitOnErrorDriver; + +use embassy_embedded_hal::shared_bus; +use embassy_stm32::i2c::I2c; +use embassy_stm32::i2c::Master; +use embassy_stm32::mode::{Async, Blocking}; +use embassy_stm32::usart::{RingBufferedUartRx, UartTx}; +use embassy_sync::blocking_mutex::raw::NoopRawMutex; +use shared_bus::asynch::i2c::I2cDevice; + +pub type ConcreteSharedI2c<'a> = + I2cDevice<'a, NoopRawMutex, I2c<'static, Async, Master>>; +pub type ConcreteBlockingI2c<'a> = &'a I2cWrapper>; +pub type ConcreteTx<'a> = UartTx<'a, Async>; +pub type ConcreteRx<'a> = RingBufferedUartRx<'a>; + +use bosch_bme680::Bme680; +use embassy_time::Delay; +use max44009::Max44009; +use nau7802_async::Nau7802; +use sht31::mode::SingleShot; +use sht31::SHT31; + +// Driver type aliases/wrapper structs. These auto correct/re-init on error +pub use wrap_mhz::MhzDriver; +pub use wrap_sps30::{Sps30Driver, SPS30_DRIVER_BUF_SIZE, SPS30_UART_BUF_SIZE}; +pub type Nau7802DriverBlocking<'a> = + ReInitOnErrorDriver, Delay>>; +pub type Nau7802Driver<'a> = + ReInitOnErrorDriver, Delay>>; +pub type Max44Driver<'a> = ReInitOnErrorDriver>>; +pub type Bme680Driver<'a> = + ReInitOnErrorDriver, Delay>>; +pub type Sht31Driver<'a> = + ReInitOnErrorDriver>>; diff --git a/nodes/embassy/sensors/src/drivers/driver_impl_bme680.rs b/nodes/embassy/sensors/src/drivers/driver_impl_bme680.rs new file mode 100644 index 00000000..f25d7cc5 --- /dev/null +++ b/nodes/embassy/sensors/src/drivers/driver_impl_bme680.rs @@ -0,0 +1,35 @@ +use bosch_bme680::Bme680; +use embassy_embedded_hal::shared_bus; +use embassy_stm32::i2c::I2c; +use embassy_stm32::i2c::Master; +use embassy_stm32::mode::Async; +use embassy_sync::blocking_mutex::raw::NoopRawMutex; +use embassy_sync::mutex::Mutex; +use embassy_time::Delay; + +use crate::errors::SensorError; +use crate::ReInitableDriver; + +use super::ConcreteSharedI2c; + +impl<'a> ReInitableDriver for Bme680, Delay> { + type Parts = &'a Mutex>; + type Measurement = bosch_bme680::MeasurementData; + + async fn init(parts: Self::Parts) -> Result { + let shared_i2c = shared_bus::asynch::i2c::I2cDevice::new(parts); + Bme680::new( + shared_i2c, + bosch_bme680::DeviceAddress::Secondary, + Delay, + &bosch_bme680::Configuration::default(), + 21, + ) + .await + .map_err(SensorError::Bme680) + } + + async fn measure(&mut self) -> Result { + self.measure().await.map_err(SensorError::Bme680) + } +} diff --git a/nodes/embassy/sensors/src/drivers/driver_impl_max44009.rs b/nodes/embassy/sensors/src/drivers/driver_impl_max44009.rs new file mode 100644 index 00000000..05d33bfd --- /dev/null +++ b/nodes/embassy/sensors/src/drivers/driver_impl_max44009.rs @@ -0,0 +1,32 @@ +use embassy_embedded_hal::shared_bus; +use embassy_stm32::i2c::I2c; +use embassy_stm32::mode::Async; +use embassy_stm32::i2c::Master; +use embassy_sync::blocking_mutex::raw::NoopRawMutex; +use embassy_sync::mutex::Mutex; +use max44009::{Max44009, SlaveAddr}; + +use crate::errors::SensorError; +use crate::ReInitableDriver; + +use super::ConcreteSharedI2c; + +impl<'a> ReInitableDriver for Max44009> { + type Parts = &'a Mutex>; + type Measurement = f32; + + async fn init(parts: Self::Parts) -> Result { + let shared_i2c = shared_bus::asynch::i2c::I2cDevice::new(parts); + // Wrap these two into something returning Ok or Err + // then make it a generic arg, maybe Driverfactory::init + let mut driver = Max44009::new(shared_i2c, SlaveAddr::default()); + driver + .set_measurement_mode(max44009::MeasurementMode::Continuous) + .await + .map_err(SensorError::Max44)?; + Ok(driver) + } + async fn measure(&mut self) -> Result { + self.read_lux().await.map_err(SensorError::Max44) + } +} diff --git a/nodes/embassy/sensors/src/drivers/driver_impl_nau7802.rs b/nodes/embassy/sensors/src/drivers/driver_impl_nau7802.rs new file mode 100644 index 00000000..08db9a65 --- /dev/null +++ b/nodes/embassy/sensors/src/drivers/driver_impl_nau7802.rs @@ -0,0 +1,51 @@ +use embassy_embedded_hal::shared_bus; +use embassy_stm32::i2c::I2c; +use embassy_stm32::i2c::Master; +use embassy_stm32::mode::{Async, Blocking}; +use embassy_sync::blocking_mutex::raw::NoopRawMutex; +use embassy_sync::mutex::Mutex; +use embassy_time::Delay; +use nau7802_async::Nau7802; + +use crate::errors::SensorError; +use crate::ReInitableDriver; + +use super::{ConcreteBlockingI2c, ConcreteSharedI2c, I2cWrapper}; + +impl<'a> ReInitableDriver for Nau7802, Delay> { + type Parts = &'a Mutex>; + type Measurement = u32; + + async fn init(parts: Self::Parts) -> Result { + let shared_i2c = shared_bus::asynch::i2c::I2cDevice::new(parts); + // Wrap these two into something returning Ok or Err + // then make it a generic arg, maybe Driverfactory::init + let driver = Nau7802::new(shared_i2c, Delay) + .await + .map_err(SensorError::Nau7802Left)?; + Ok(driver) + } + + async fn measure(&mut self) -> Result { + self.read().await.map_err(SensorError::Nau7802Left) + } +} + +impl<'a> ReInitableDriver for Nau7802, Delay> { + type Parts = &'a I2cWrapper>; + type Measurement = u32; + + async fn init(parts: Self::Parts) -> Result { + let shared_i2c = parts; + // Wrap these two into something returning Ok or Err + // then make it a generic arg, maybe Driverfactory::init + let driver = Nau7802::new(shared_i2c, Delay) + .await + .map_err(SensorError::Nau7802Left)?; + Ok(driver) + } + + async fn measure(&mut self) -> Result { + self.read().await.map_err(SensorError::Nau7802Left) + } +} diff --git a/nodes/embassy/sensors/src/drivers/driver_impl_sht31.rs b/nodes/embassy/sensors/src/drivers/driver_impl_sht31.rs new file mode 100644 index 00000000..e5b7cd65 --- /dev/null +++ b/nodes/embassy/sensors/src/drivers/driver_impl_sht31.rs @@ -0,0 +1,38 @@ +use embassy_embedded_hal::shared_bus; +use embassy_stm32::i2c::I2c; +use embassy_stm32::mode::Async; +use embassy_stm32::i2c::Master; +use embassy_sync::blocking_mutex::raw::NoopRawMutex; +use embassy_sync::mutex::Mutex; +use embassy_time::{Delay, Timer}; +use sht31::mode::SingleShot; +use sht31::SHT31; + +use crate::errors::SensorError; +use crate::ReInitableDriver; + +use super::ConcreteSharedI2c; + +impl<'a> ReInitableDriver for SHT31> { + type Parts = &'a Mutex>; + type Measurement = sht31::Reading; + + async fn init(parts: Self::Parts) -> Result { + let shared_i2c = shared_bus::asynch::i2c::I2cDevice::new(parts); + Ok(SHT31::new(shared_i2c, Delay) + .with_mode(SingleShot) + .with_unit(sht31::TemperatureUnit::Celsius) + .with_accuracy(sht31::Accuracy::High)) + } + + async fn measure(&mut self) -> Result { + use sht31::mode::Sht31Measure; + use sht31::mode::Sht31Reader; + + Sht31Measure::measure(self) + .await + .map_err(SensorError::Sht31)?; + Timer::after_secs(1).await; + self.read().await.map_err(SensorError::Sht31) + } +} diff --git a/nodes/embassy/sensors/src/drivers/i2c_wrapper.rs b/nodes/embassy/sensors/src/drivers/i2c_wrapper.rs new file mode 100644 index 00000000..a3248fc9 --- /dev/null +++ b/nodes/embassy/sensors/src/drivers/i2c_wrapper.rs @@ -0,0 +1,69 @@ +use embassy_embedded_hal::shared_bus::I2cDeviceError; +use embassy_sync::blocking_mutex::raw::NoopRawMutex; +use embassy_sync::mutex::Mutex; + +pub struct I2cWrapper(pub Mutex); + +/// Make sure the error type is the same as when +/// embassy_embedded_hal::shared_bus async is used. We do so by wrapping +/// underlying errors in [`I2cDevice`]. +/// +/// [`I2cDevice`](embassy_embedded_hal::shared_bus::asynch::i2c::I2cDevice) +impl embedded_hal_async::i2c::ErrorType + for &I2cWrapper +{ + type Error = I2cDeviceError<::Error>; +} + +impl embedded_hal_async::i2c::I2c + for &I2cWrapper +{ + async fn transaction( + &mut self, + address: u8, + operations: &mut [embedded_hal_async::i2c::Operation<'_>], + ) -> Result<(), Self::Error> { + self.0 + .lock() + .await + .transaction(address, operations) + .map_err(I2cDeviceError::I2c) + } + + async fn read( + &mut self, + address: u8, + read: &mut [u8], + ) -> Result<(), Self::Error> { + self.0 + .lock() + .await + .read(address, read) + .map_err(I2cDeviceError::I2c) + } + + async fn write( + &mut self, + address: u8, + write: &[u8], + ) -> Result<(), Self::Error> { + self.0 + .lock() + .await + .write(address, write) + .map_err(I2cDeviceError::I2c) + } + + async fn write_read( + &mut self, + address: u8, + write: &[u8], + read: &mut [u8], + ) -> Result<(), Self::Error> { + self.0 + .lock() + .await + .write_read(address, write, read) + .map_err(I2cDeviceError::I2c) + } +} diff --git a/nodes/embassy/sensors/src/drivers/reinit_on_error.rs b/nodes/embassy/sensors/src/drivers/reinit_on_error.rs new file mode 100644 index 00000000..ef7a00cf --- /dev/null +++ b/nodes/embassy/sensors/src/drivers/reinit_on_error.rs @@ -0,0 +1,105 @@ +use protocol::Device; + +use crate::errors::Error; +use crate::{Driver, ReInitableDriver}; + +pub struct ReInitOnErrorDriver +where + D: ReInitableDriver, +{ + state: State, + parts: D::Parts, + device: Device, +} + +enum State { + Ready { driver: D }, + Uninit, +} + +impl Driver for ReInitOnErrorDriver { + type Measurement = D::Measurement; + type Affector = (); + + #[inline(always)] + async fn try_measure(&mut self) -> Result { + self.try_measure().await + } + + #[inline(always)] + fn device(&self) -> Device { + self.device.clone() + } +} + +impl ReInitOnErrorDriver +where + D: ReInitableDriver, +{ + #[inline(always)] + pub fn new(parts: D::Parts, device: Device) -> Self { + Self { + state: State::Uninit, + parts, + device, + } + } + + #[inline(always)] + pub async fn try_measure(&mut self) -> Result { + let mut owned_self = State::Uninit; + core::mem::swap(&mut owned_self, &mut self.state); + let (mut new_self, res) = advance_state(owned_self, &self.parts).await; + core::mem::swap(&mut new_self, &mut self.state); + res + } +} + +#[inline(always)] +async fn advance_state( + state: State, + parts: &D::Parts, +) -> (State, Result) { + match state { + State::Ready { + mut driver, + // make a trait over driver that has a measure method + } => match driver.measure().await { + Ok(val) => { + let new_state = State::Ready { driver }; + (new_state, Ok(val)) + } + Err(err) => { + let new_state = State::Uninit; + (new_state, Err(Error::Running(err))) + } + }, + State::Uninit => { + match D::init(parts.clone()).await { + Ok(mut driver) => { + // uses driver::measure again, make that return a SensorError + match driver.measure().await { + Ok(val) => { + let new_state = State::Ready { driver }; + (new_state, Ok(val)) + } + Err(err) => { + let new_state = State::Uninit; + let err = Error::Running(err); + (new_state, Err(err)) + } + } + } + Err(err) => { + // drivers might contain blocking code in their + // error path, this makes sure the executor + // will not block on retrying. + embassy_time::Timer::after_millis(250).await; + let new_state = State::Uninit; + let err = Error::Setup(err); + (new_state, Err(err)) + } + } + } + } +} diff --git a/nodes/embassy/sensors/src/drivers/wrap_mhz.rs b/nodes/embassy/sensors/src/drivers/wrap_mhz.rs new file mode 100644 index 00000000..c25ae57d --- /dev/null +++ b/nodes/embassy/sensors/src/drivers/wrap_mhz.rs @@ -0,0 +1,44 @@ +use mhzx::MHZ; +use protocol::Device; + +use crate::errors::SensorError; +use crate::{Driver, Error}; + +use super::{ConcreteRx, ConcreteTx}; + +pub struct MhzDriver<'a> { + driver: MHZ, ConcreteRx<'a>>, + device: protocol::Device, +} + +impl<'a> MhzDriver<'a> { + pub fn new( + uart_tx: ConcreteTx<'a>, + uart_rx: ConcreteRx<'a>, + device: Device, + ) -> Self { + Self { + driver: MHZ::from_tx_rx(uart_tx, uart_rx), + device, + } + } +} + +impl<'a> Driver for MhzDriver<'a> { + type Measurement = mhzx::Measurement; + type Affector = (); + + #[inline(always)] + async fn try_measure(&mut self) -> Result { + self.driver + .read_co2() + .await + .map_err(SensorError::Mhz14) + .map_err(Error::Running) + } + + #[inline(always)] + fn device(&self) -> protocol::Device { + self.device.clone() + } +} diff --git a/nodes/embassy/sensors/src/drivers/wrap_sps30.rs b/nodes/embassy/sensors/src/drivers/wrap_sps30.rs new file mode 100644 index 00000000..09f2f4a9 --- /dev/null +++ b/nodes/embassy/sensors/src/drivers/wrap_sps30.rs @@ -0,0 +1,91 @@ +use embassy_time::Delay; +use sps30_async::Sps30; + +use crate::errors::{Error, SensorError}; +use crate::Driver; + +use super::{ConcreteRx, ConcreteTx}; + +pub const SPS30_UART_BUF_SIZE: usize = 150; +pub const SPS30_DRIVER_BUF_SIZE: usize = 2 * SPS30_UART_BUF_SIZE; + +/// reset the device when an error occurs +pub struct Sps30Driver<'a> { + is_init: bool, + driver: Sps30, ConcreteRx<'a>, Delay>, + device: protocol::Device, +} + +impl<'a> Sps30Driver<'a> { + pub fn init( + tx: ConcreteTx<'a>, + rx: ConcreteRx<'a>, + device: protocol::Device, + ) -> Self { + let driver = Sps30::from_tx_rx_uninit(tx, rx, Delay); + Self { + is_init: false, + driver, + device, + } + } + + async fn measure(&mut self) -> Result { + if self.is_init { + let res = self + .driver + .read_measurement() + .await + .map_err(SensorError::Sps30) + .map_err(Error::Running); + self.is_init = res.is_ok(); + return res; + } + + self.driver + .reset() + .await + .map_err(SensorError::Sps30) + .map_err(Error::Setup)?; + self.driver + .start_measurement() + .await + .map_err(SensorError::Sps30) + .map_err(Error::Setup)?; + + let res = self + .driver + .read_measurement() + .await + .map_err(SensorError::Sps30) + .map_err(Error::Running); + + self.is_init = res.is_ok(); + res + } +} + +impl<'a> Driver for Sps30Driver<'a> { + type Measurement = sps30_async::Measurement; + type Affector = (); + + async fn try_measure(&mut self) -> Result { + self.measure().await + } + + async fn affect(&mut self, _: Self::Affector) -> Result<(), Error> { + self.driver + .start_fan_cleaning() + .await + .map_err(SensorError::Sps30) + .map_err(Error::Running)?; + // Fan cleaning takes 10 seconds, make sure its done before + // allowing the next reading + embassy_time::Timer::after(embassy_time::Duration::from_secs(11)).await; + Ok(()) + } + + fn device(&self) -> protocol::Device { + self.device.clone() + } +} diff --git a/nodes/embassy/sensors/src/errors.rs b/nodes/embassy/sensors/src/errors.rs new file mode 100644 index 00000000..83aa50e6 --- /dev/null +++ b/nodes/embassy/sensors/src/errors.rs @@ -0,0 +1,173 @@ +use embassy_embedded_hal::shared_bus::I2cDeviceError; +use protocol::make_error_string; + +pub type I2cError = I2cDeviceError; +pub type UartError = embassy_stm32::usart::Error; + +#[derive(defmt::Format, PartialEq, Eq, Clone)] +pub struct PressTooLong { + pub button: &'static str, +} + +impl core::fmt::Debug for PressTooLong { + fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { + f.write_fmt(format_args!("Button {}, pressed too long", self.button)) + } +} + +#[derive(defmt::Format, PartialEq, Eq, Clone)] +pub enum SensorError { + Mhz14(mhzx::Error), + Sps30(sps30_async::Error), + Sht31(sht31::SHTError), + Bme680(bosch_bme680::BmeError), + Max44(max44009::Error), + /// Nodes with only one Nau7802 should use left, + /// it is what the driver returns by default + Nau7802Left(nau7802_async::Error), + Nau7802Right(nau7802_async::Error), + Button(PressTooLong), +} + +impl SensorError { + /// ugly hack to allow users of sensors to get a different error for two + /// identical devices by calling into_right on the error the default error + /// is the 'left device'. Works only if there is a right device. Needs + /// the From for protocol::_::_Error to map right devices to right + /// devices + fn into_right(self) -> Self { + match self { + Self::Nau7802Left(e) => Self::Nau7802Right(e), + ref _other => self, + } + } +} + +/// This error type is as small as possible. It is meant for +/// devices to deduplicate errors that happen rapidly and only +/// send such errors every once in a while to the host +#[derive(defmt::Format, PartialEq, Eq, Clone)] +pub enum Error { + Running(SensorError), + Setup(SensorError), + Timeout(protocol::Device), +} + +impl Error { + /// ugly hack to allow users of sensors to get a different error for two + /// identical devices by calling into_right on the error the default error + /// is the 'left device'. Works only if there is a right device. Needs + /// the From for protocol::_::_Error to map right devices to right + /// devices + pub fn into_right(self) -> Self { + match self { + Self::Running(sensor_error) => { + Self::Running(sensor_error.into_right()) + } + Self::Setup(sensor_error) => { + Self::Setup(sensor_error.into_right()) + } + Self::Timeout(ref _device) => self, + } + } +} + +impl From for protocol::small_bedroom::bed::SensorError { + fn from(val: SensorError) -> Self { + use protocol::small_bedroom::bed; + match val { + SensorError::Mhz14(e) => { + bed::SensorError::Mhz14(make_error_string(e)) + } + SensorError::Sps30(e) => { + bed::SensorError::Sps30(make_error_string(e)) + } + SensorError::Sht31(e) => { + bed::SensorError::Sht31(make_error_string(e)) + } + SensorError::Bme680(e) => { + bed::SensorError::Bme680(make_error_string(e)) + } + SensorError::Max44(e) => { + bed::SensorError::Max44(make_error_string(e)) + } + SensorError::Nau7802Left(e) => { + bed::SensorError::Nau7802(make_error_string(e)) + } + SensorError::Button(e) => { + bed::SensorError::Button(make_error_string(e)) + } + SensorError::Nau7802Right(_) => { + unreachable!("Not installed for small_bedroom bed sensor") + } + } + } +} + +impl From for protocol::small_bedroom::bed::Error { + fn from(val: Error) -> Self { + use protocol::small_bedroom::bed; + match val { + Error::Running(e) => bed::Error::Running(e.into()), + Error::Setup(e) => bed::Error::Setup(e.into()), + Error::Timeout(protocol::Device::SmallBedroom( + protocol::small_bedroom::Device::Bed(dev), + )) => bed::Error::Timeout(dev), + Error::Timeout(incorrect_dev) => defmt::unreachable!( + "Should only contain small_bedroom::bed devices, got {} which \ + is not part of small_bedroom::bed::Device", + incorrect_dev + ), + } + } +} + +impl From for protocol::large_bedroom::bed::SensorError { + fn from(val: SensorError) -> Self { + use protocol::large_bedroom::bed; + match val { + SensorError::Mhz14(e) => { + bed::SensorError::Mhz14(make_error_string(e)) + } + SensorError::Sps30(e) => { + bed::SensorError::Sps30(make_error_string(e)) + } + SensorError::Sht31(e) => { + bed::SensorError::Sht31(make_error_string(e)) + } + SensorError::Bme680(e) => { + bed::SensorError::Bme680(make_error_string(e)) + } + SensorError::Max44(e) => { + bed::SensorError::Max44(make_error_string(e)) + } + SensorError::Nau7802Left(e) => { + bed::SensorError::Nau7802Left(make_error_string(e)) + } + SensorError::Nau7802Right(e) => { + bed::SensorError::Nau7802Right(make_error_string(e)) + } + SensorError::Button(e) => { + bed::SensorError::Button(make_error_string(e)) + } + } + } +} + +impl From for protocol::large_bedroom::bed::Error { + fn from(val: Error) -> Self { + use protocol::large_bedroom::bed; + match val { + Error::Running(e) => bed::Error::Running(e.into()), + Error::Setup(e) => bed::Error::Setup(e.into()), + Error::Timeout(protocol::Device::LargeBedroom( + protocol::large_bedroom::Device::Bed(dev), + )) => bed::Error::Timeout(dev), + Error::Timeout(incorrect_dev) => defmt::unreachable!( + "Should only contain small_bedroom::bed devices, got {} which \ + is not part of small_bedroom::bed::Device", + incorrect_dev + ), + } + } +} diff --git a/nodes/embassy/sensors/src/lib.rs b/nodes/embassy/sensors/src/lib.rs new file mode 100644 index 00000000..3ba8b1dc --- /dev/null +++ b/nodes/embassy/sensors/src/lib.rs @@ -0,0 +1,39 @@ +#![no_std] + +mod drivers; +pub mod button; +pub mod pir; +pub mod errors; +pub mod measurements; + +pub use drivers::I2cWrapper; +pub use drivers::{ + Bme680Driver, Max44Driver, MhzDriver, Nau7802Driver, Nau7802DriverBlocking, + Sht31Driver, Sps30Driver, SPS30_DRIVER_BUF_SIZE, SPS30_UART_BUF_SIZE, +}; + +pub use errors::Error; +use errors::SensorError; + +#[allow(async_fn_in_trait)] +pub trait Driver { + type Measurement; + type Affector; + + async fn try_measure(&mut self) -> Result; + /// For example calibrate, run sensor cleaning etc + async fn affect(&mut self, _: Self::Affector) -> Result<(), Error> { + Ok(()) + } + fn device(&self) -> protocol::Device; +} + +/// A driver that can be re-initialized from copy-able parts +#[allow(async_fn_in_trait)] +pub trait ReInitableDriver: Sized { + type Parts: Clone; + type Measurement; + + async fn init(parts: Self::Parts) -> Result; + async fn measure(&mut self) -> Result; +} diff --git a/nodes/embassy/sensors/src/measurements.rs b/nodes/embassy/sensors/src/measurements.rs new file mode 100644 index 00000000..e865c5da --- /dev/null +++ b/nodes/embassy/sensors/src/measurements.rs @@ -0,0 +1,8 @@ +// cannot get to this type through trait yet: +// https://github.com/rust-lang/rust/issues/86935 +// so this is an alternative + +pub use bosch_bme680::MeasurementData as Bme; +pub use sps30_async::Measurement as Sps30; +pub use mhzx::Measurement as Mhz; +pub use sht31::Reading as Sht31; diff --git a/nodes/embassy/sensors/src/pir.rs b/nodes/embassy/sensors/src/pir.rs new file mode 100644 index 00000000..18c722d0 --- /dev/null +++ b/nodes/embassy/sensors/src/pir.rs @@ -0,0 +1,66 @@ +use embassy_stm32::exti::ExtiInput; +use embassy_time::{Timer, Duration}; + +use protocol::pir::Status; + +pub async fn watch_array( + pirs: [(ExtiInput<'static>, F); N], + on_pir: impl Fn(P) + Clone, +) where + P: defmt::Format, + F: Fn(protocol::pir::Status) -> P + Clone, +{ + embassy_futures::join::join_array(pirs.map(|(input, into_pir)| { + let local_into_pir = into_pir.clone(); + let local_on_pir = on_pir.clone(); + let on_ok = move |press| { + let on_pir = &local_on_pir; + let into_pir = &local_into_pir; + on_pir(into_pir(press)); + }; + + watch_pir(input, on_ok) + })) + .await; +} + +async fn watch_pir( + mut input: ExtiInput<'static>, + on_change: impl Fn(protocol::pir::Status), +) { + loop { + input.wait_for_high().await; + Timer::after(Duration::from_millis(25)).await; + if input.is_low() { + continue; + } + Timer::after(Duration::from_millis(25)).await; + if input.is_low() { + continue; + } + Timer::after(Duration::from_millis(25)).await; + if input.is_low() { + continue; + } + // pretty sure at this point this is not some random noise + on_change(Status::Started); + loop { + input.wait_for_low().await; + Timer::after(Duration::from_millis(25)).await; + if input.is_high() { + continue; + } + Timer::after(Duration::from_millis(25)).await; + if input.is_high() { + continue; + } + Timer::after(Duration::from_millis(25)).await; + if input.is_high() { + continue; + } + // pretty sure at this point this is not some random noise + on_change(Status::End); + break; + } + } +} diff --git a/nodes/embassy/setup.sh b/nodes/embassy/setup.sh new file mode 100755 index 00000000..225ea53b --- /dev/null +++ b/nodes/embassy/setup.sh @@ -0,0 +1,53 @@ +#!/usr/bin/env bash +set -e + +# for newer or different prorammers edit idVendor and idProduct (use lsusb to find these) +UDEV_FILE=/etc/udev/rules.d/70-programmer.rules +UDEV_RULE1='# ST-LINK/V2' +UDEV_RULE2='ATTRS{idVendor}=="0483", ATTRS{idProduct}=="3748", TAG+="uaccess"' +UDEV_RULE3='# ST-LINK/V2-1' +UDEV_RULE4='ATTRS{idVendor}=="0483", ATTRS{idProduct}=="374b", TAG+="uaccess"' +UDEV_RULE5='# CMSIS_DAP compatible adapter' +UDEV_RULE6='ATTRS{product}=="*CMSIS-DAP*", MODE="660", GROUP="plugdev", TAG+="uaccess"' +UDEV_RULE5='# CMSIS_DAP compatible misspelled adapter' +UDEV_RULE6='ATTRS{product}=="*CMSIS_DAP*", MODE="660", GROUP="plugdev", TAG+="uaccess"' + + +function install_tools { + echo "installing tools" + rustup override set nightly + rustup target add thumbv7em-none-eabihf + + # # workaround for issue: https://github.com/knurling-rs/probe-run/issues/289 + # sudo apt remove libusb-dev libusb-0.1-4 + + # sudo apt install -y libusb-1.0-0-dev libudev-dev + curl --proto '=https' --tlsv1.2 -LsSf https://github.com/probe-rs/probe-rs/releases/latest/download/probe-rs-tools-installer.sh | sh + cargo install flip-link # linker with stack overflow protection + # rustup component add llvm-tools-preview +} + +# add udev rules if they do not yet exist +function fix_udev_rules { + sudo groupadd dialout || true + sudo usermod -a -G dialout $USER + + if [ ! -f "${UDEV_FILE}" ]; then + echo "${UDEV_RULE1}" | sudo tee -a $UDEV_FILE > /dev/null + echo "${UDEV_RULE2}" | sudo tee -a $UDEV_FILE > /dev/null + echo "${UDEV_RULE3}" | sudo tee -a $UDEV_FILE > /dev/null + echo "${UDEV_RULE4}" | sudo tee -a $UDEV_FILE > /dev/null + echo "${UDEV_RULE5}" | sudo tee -a $UDEV_FILE > /dev/null + echo "${UDEV_RULE6}" | sudo tee -a $UDEV_FILE > /dev/null + sudo udevadm control --reload-rules + sudo udevadm trigger + echo "created udev rules: $UDEV_FILE" + fi +} + +install_tools +echo $(fix_udev_rules) # without the echo $() this does not work.. bash magic... + +printf "\x1b[31mdo please manually check lsub and udev/rules-d for probe rule\x1b[0m\n"; +printf "\x1b[31mdo NOT FORGET to DISCONNECT and RECONNECT the programmer\x1b[0m\n"; +printf "\x1b[31mdo NOT FORGET to RE-LOGIN the shell to reload groups\x1b[0m\n"; diff --git a/nodes/embassy/small-bedroom-bed/.cargo/config.toml b/nodes/embassy/small-bedroom-bed/.cargo/config.toml new file mode 100644 index 00000000..161b3118 --- /dev/null +++ b/nodes/embassy/small-bedroom-bed/.cargo/config.toml @@ -0,0 +1,17 @@ +[target.'cfg(all(target_arch = "arm", target_os = "none"))'] +# replace STM32F103C8 with your chip as listed in `probe-rs chip list` +# runner = "probe-rs run --chip STM32F103C8" +runner = "probe-rs run --chip STM32F401CCUx" +linker = "flip-link" + +[build] +# target = "thumbv7m-none-eabi" for f103 +target = "thumbv7em-none-eabihf" + +[env] +DEFMT_LOG = "debug,sps30_async=warn,bosch_bme680=info" +EMBASSY_EXECUTOR_TASK_ARENA_SIZE="10900" + +# [unstable] +# build-std = ["core"] +# build-std-features = ["panic_immediate_abort"] diff --git a/nodes/embassy/small-bedroom-bed/Cargo.lock b/nodes/embassy/small-bedroom-bed/Cargo.lock new file mode 100644 index 00000000..50cd7987 --- /dev/null +++ b/nodes/embassy/small-bedroom-bed/Cargo.lock @@ -0,0 +1,1274 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 3 + +[[package]] +name = "ahash" +version = "0.8.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e89da841a80418a9b391ebaea17f5c112ffaaa96f621d2c285b5174da76b9011" +dependencies = [ + "cfg-if", + "once_cell", + "version_check", + "zerocopy", +] + +[[package]] +name = "aligned" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "377e4c0ba83e4431b10df45c1d4666f178ea9c552cac93e60c3a88bf32785923" +dependencies = [ + "as-slice", +] + +[[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 = "atomic-polyfill" +version = "1.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8cf2bce30dfe09ef0bfaef228b9d414faaf7e563035494d7fe092dba54b300f4" +dependencies = [ + "critical-section", +] + +[[package]] +name = "autocfg" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0c4b4d0bd25bd0b74681c0ad21497610ce1b7c91b1022cd21c80c6fbdd9476b0" + +[[package]] +name = "bare-metal" +version = "0.2.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5deb64efa5bd81e31fcd1938615a6d98c82eafcbcd787162b6f63b91d6bac5b3" +dependencies = [ + "rustc_version 0.2.3", +] + +[[package]] +name = "bed-sensors" +version = "0.2.0" +dependencies = [ + "bosch-bme680", + "cortex-m", + "cortex-m-rt", + "defmt", + "defmt-rtt", + "embassy-embedded-hal", + "embassy-executor", + "embassy-futures", + "embassy-stm32", + "embassy-sync", + "embassy-time", + "embassy-usb", + "embedded-hal 1.0.0", + "embedded-hal-async", + "embedded-hal-bus", + "embedded-io-async", + "futures", + "heapless 0.8.0", + "max44009", + "mhzx", + "nau7802-async", + "nb 1.1.0", + "panic-probe", + "protocol", + "rand", + "sht31", + "sps30-async", + "static_cell", +] + +[[package]] +name = "bit_field" +version = "0.10.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dc827186963e592360843fb5ba4b973e145841266c1357f7180c43526f2e5b61" + +[[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.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b048fb63fd8b5923fc5aa7b340d8e156aec7ec02f0c78fa8a6ddc2613f6f71de" + +[[package]] +name = "block-device-driver" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "44c051592f59fe68053524b4c4935249b806f72c1f544cfb7abe4f57c3be258e" +dependencies = [ + "aligned", +] + +[[package]] +name = "bosch-bme680" +version = "1.0.2" +dependencies = [ + "bitfield 0.14.0", + "defmt", + "embedded-hal 1.0.0", + "embedded-hal-async", +] + +[[package]] +name = "byteorder" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" + +[[package]] +name = "cfg-if" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" + +[[package]] +name = "cobs" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "67ba02a97a2bd10f4b59b25c7973101c79642302776489e030cd13cdab09ed15" + +[[package]] +name = "cortex-m" +version = "0.7.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8ec610d8f49840a5b376c69663b6369e71f4b34484b9b2eb29fb918d92516cb9" +dependencies = [ + "bare-metal", + "bitfield 0.13.2", + "critical-section", + "embedded-hal 0.2.7", + "volatile-register", +] + +[[package]] +name = "cortex-m-rt" +version = "0.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ee84e813d593101b1723e13ec38b6ab6abbdbaaa4546553f5395ed274079ddb1" +dependencies = [ + "cortex-m-rt-macros", +] + +[[package]] +name = "cortex-m-rt-macros" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f0f6f3e36f203cfedbc78b357fb28730aa2c6dc1ab060ee5c2405e843988d3c7" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "crc" +version = "3.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "69e6e4d7b33a94f0991c26729976b10ebde1d34c3ee82408fb536164fa10d636" +dependencies = [ + "crc-catalog", +] + +[[package]] +name = "crc-catalog" +version = "2.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "19d374276b40fb8bbdee95aef7c7fa6b5316ec764510eb64b8dd0e2ed0d7e7f5" + +[[package]] +name = "critical-section" +version = "1.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f64009896348fc5af4222e9cf7d7d82a95a256c634ebcf61c53e4ea461422242" + +[[package]] +name = "darling" +version = "0.20.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6f63b86c8a8826a49b8c21f08a2d07338eec8d900540f8630dc76284be802989" +dependencies = [ + "darling_core", + "darling_macro", +] + +[[package]] +name = "darling_core" +version = "0.20.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "95133861a8032aaea082871032f5815eb9e98cef03fa916ab4500513994df9e5" +dependencies = [ + "fnv", + "ident_case", + "proc-macro2", + "quote", + "strsim", + "syn 2.0.77", +] + +[[package]] +name = "darling_macro" +version = "0.20.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d336a2a514f6ccccaa3e09b02d41d35330c07ddf03a62165fcec10bb561c7806" +dependencies = [ + "darling_core", + "quote", + "syn 2.0.77", +] + +[[package]] +name = "defmt" +version = "0.3.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a99dd22262668b887121d4672af5a64b238f026099f1a2a1b322066c9ecfe9e0" +dependencies = [ + "bitflags 1.3.2", + "defmt-macros", +] + +[[package]] +name = "defmt-macros" +version = "0.3.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e3a9f309eff1f79b3ebdf252954d90ae440599c26c2c553fe87a2d17195f2dcb" +dependencies = [ + "defmt-parser", + "proc-macro-error", + "proc-macro2", + "quote", + "syn 2.0.77", +] + +[[package]] +name = "defmt-parser" +version = "0.3.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ff4a5fefe330e8d7f31b16a318f9ce81000d8e35e69b93eae154d16d2278f70f" +dependencies = [ + "thiserror", +] + +[[package]] +name = "defmt-rtt" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bab697b3dbbc1750b7c8b821aa6f6e7f2480b47a99bc057a2ed7b170ebef0c51" +dependencies = [ + "critical-section", + "defmt", +] + +[[package]] +name = "document-features" +version = "0.2.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cb6969eaabd2421f8a2775cfd2471a2b634372b4a25d41e3bd647b79912850a0" +dependencies = [ + "litrs", +] + +[[package]] +name = "embassy-embedded-hal" +version = "0.2.0" +source = "git+https://github.com/embassy-rs/embassy?rev=d7780fc#d7780fcf83a8a35d7b09e5df7b62dd8218436715" +dependencies = [ + "defmt", + "embassy-futures", + "embassy-sync", + "embassy-time", + "embedded-hal 0.2.7", + "embedded-hal 1.0.0", + "embedded-hal-async", + "embedded-storage", + "embedded-storage-async", + "nb 1.1.0", +] + +[[package]] +name = "embassy-executor" +version = "0.6.0" +source = "git+https://github.com/embassy-rs/embassy?rev=d7780fc#d7780fcf83a8a35d7b09e5df7b62dd8218436715" +dependencies = [ + "cortex-m", + "critical-section", + "defmt", + "document-features", + "embassy-executor-macros", + "embassy-time-driver", + "embassy-time-queue-driver", +] + +[[package]] +name = "embassy-executor-macros" +version = "0.5.0" +source = "git+https://github.com/embassy-rs/embassy?rev=d7780fc#d7780fcf83a8a35d7b09e5df7b62dd8218436715" +dependencies = [ + "darling", + "proc-macro2", + "quote", + "syn 2.0.77", +] + +[[package]] +name = "embassy-futures" +version = "0.1.1" +source = "git+https://github.com/embassy-rs/embassy?rev=d7780fc#d7780fcf83a8a35d7b09e5df7b62dd8218436715" + +[[package]] +name = "embassy-hal-internal" +version = "0.2.0" +source = "git+https://github.com/embassy-rs/embassy?rev=d7780fc#d7780fcf83a8a35d7b09e5df7b62dd8218436715" +dependencies = [ + "cortex-m", + "critical-section", + "defmt", + "num-traits", +] + +[[package]] +name = "embassy-net-driver" +version = "0.2.0" +source = "git+https://github.com/embassy-rs/embassy?rev=d7780fc#d7780fcf83a8a35d7b09e5df7b62dd8218436715" +dependencies = [ + "defmt", +] + +[[package]] +name = "embassy-net-driver-channel" +version = "0.3.0" +source = "git+https://github.com/embassy-rs/embassy?rev=d7780fc#d7780fcf83a8a35d7b09e5df7b62dd8218436715" +dependencies = [ + "embassy-futures", + "embassy-net-driver", + "embassy-sync", +] + +[[package]] +name = "embassy-stm32" +version = "0.1.0" +source = "git+https://github.com/embassy-rs/embassy?rev=d7780fc#d7780fcf83a8a35d7b09e5df7b62dd8218436715" +dependencies = [ + "aligned", + "bit_field", + "bitflags 2.6.0", + "block-device-driver", + "cfg-if", + "cortex-m", + "cortex-m-rt", + "critical-section", + "defmt", + "document-features", + "embassy-embedded-hal", + "embassy-futures", + "embassy-hal-internal", + "embassy-net-driver", + "embassy-sync", + "embassy-time", + "embassy-time-driver", + "embassy-usb-driver", + "embassy-usb-synopsys-otg", + "embedded-can", + "embedded-hal 0.2.7", + "embedded-hal 1.0.0", + "embedded-hal-async", + "embedded-hal-nb", + "embedded-io", + "embedded-io-async", + "embedded-storage", + "embedded-storage-async", + "futures-util", + "nb 1.1.0", + "proc-macro2", + "quote", + "rand_core", + "sdio-host", + "static_assertions", + "stm32-fmc", + "stm32-metapac", + "vcell", + "volatile-register", +] + +[[package]] +name = "embassy-sync" +version = "0.6.0" +source = "git+https://github.com/embassy-rs/embassy?rev=d7780fc#d7780fcf83a8a35d7b09e5df7b62dd8218436715" +dependencies = [ + "cfg-if", + "critical-section", + "defmt", + "embedded-io-async", + "futures-util", + "heapless 0.8.0", +] + +[[package]] +name = "embassy-time" +version = "0.3.2" +source = "git+https://github.com/embassy-rs/embassy?rev=d7780fc#d7780fcf83a8a35d7b09e5df7b62dd8218436715" +dependencies = [ + "cfg-if", + "critical-section", + "defmt", + "document-features", + "embassy-time-driver", + "embassy-time-queue-driver", + "embedded-hal 0.2.7", + "embedded-hal 1.0.0", + "embedded-hal-async", + "futures-util", + "heapless 0.8.0", +] + +[[package]] +name = "embassy-time-driver" +version = "0.1.0" +source = "git+https://github.com/embassy-rs/embassy?rev=d7780fc#d7780fcf83a8a35d7b09e5df7b62dd8218436715" +dependencies = [ + "document-features", +] + +[[package]] +name = "embassy-time-queue-driver" +version = "0.1.0" +source = "git+https://github.com/embassy-rs/embassy?rev=d7780fc#d7780fcf83a8a35d7b09e5df7b62dd8218436715" + +[[package]] +name = "embassy-usb" +version = "0.3.0" +source = "git+https://github.com/embassy-rs/embassy?rev=d7780fc#d7780fcf83a8a35d7b09e5df7b62dd8218436715" +dependencies = [ + "defmt", + "embassy-futures", + "embassy-net-driver-channel", + "embassy-sync", + "embassy-usb-driver", + "heapless 0.8.0", + "ssmarshal", + "usbd-hid", +] + +[[package]] +name = "embassy-usb-driver" +version = "0.1.0" +source = "git+https://github.com/embassy-rs/embassy?rev=d7780fc#d7780fcf83a8a35d7b09e5df7b62dd8218436715" +dependencies = [ + "defmt", +] + +[[package]] +name = "embassy-usb-synopsys-otg" +version = "0.1.0" +source = "git+https://github.com/embassy-rs/embassy?rev=d7780fc#d7780fcf83a8a35d7b09e5df7b62dd8218436715" +dependencies = [ + "critical-section", + "embassy-sync", + "embassy-usb-driver", +] + +[[package]] +name = "embedded-can" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e9d2e857f87ac832df68fa498d18ddc679175cf3d2e4aa893988e5601baf9438" +dependencies = [ + "nb 1.1.0", +] + +[[package]] +name = "embedded-hal" +version = "0.2.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "35949884794ad573cf46071e41c9b60efb0cb311e3ca01f7af807af1debc66ff" +dependencies = [ + "nb 0.1.3", + "void", +] + +[[package]] +name = "embedded-hal" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "361a90feb7004eca4019fb28352a9465666b24f840f5c3cddf0ff13920590b89" +dependencies = [ + "defmt", +] + +[[package]] +name = "embedded-hal-async" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0c4c685bbef7fe13c3c6dd4da26841ed3980ef33e841cddfa15ce8a8fb3f1884" +dependencies = [ + "defmt", + "embedded-hal 1.0.0", +] + +[[package]] +name = "embedded-hal-bus" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0d3980bf28e8577db59fe2bdb3df868a419469d2cecb363644eea2b6f7797669" +dependencies = [ + "critical-section", + "defmt", + "embedded-hal 1.0.0", + "embedded-hal-async", + "portable-atomic", +] + +[[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" +dependencies = [ + "defmt", +] + +[[package]] +name = "embedded-io-async" +version = "0.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3ff09972d4073aa8c299395be75161d582e7629cd663171d62af73c8d50dba3f" +dependencies = [ + "defmt", + "embedded-io", +] + +[[package]] +name = "embedded-storage" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a21dea9854beb860f3062d10228ce9b976da520a73474aed3171ec276bc0c032" + +[[package]] +name = "embedded-storage-async" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1763775e2323b7d5f0aa6090657f5e21cfa02ede71f5dc40eead06d64dcd15cc" +dependencies = [ + "embedded-storage", +] + +[[package]] +name = "encode_unicode" +version = "0.3.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a357d28ed41a50f9c765dbfe56cbc04a64e53e5fc58ba79fbc34c10ef3df831f" + +[[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.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "645c6916888f6cb6350d2550b80fb63e734897a8498abe35cfb732b6487804b0" +dependencies = [ + "futures-channel", + "futures-core", + "futures-io", + "futures-sink", + "futures-task", + "futures-util", +] + +[[package]] +name = "futures-channel" +version = "0.3.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eac8f7d7865dcb88bd4373ab671c8cf4508703796caa2b1985a9ca867b3fcb78" +dependencies = [ + "futures-core", + "futures-sink", +] + +[[package]] +name = "futures-core" +version = "0.3.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dfc6580bb841c5a68e9ef15c77ccc837b40a7504914d52e47b8b0e9bbda25a1d" + +[[package]] +name = "futures-io" +version = "0.3.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a44623e20b9681a318efdd71c299b6b222ed6f231972bfe2f224ebad6311f0c1" + +[[package]] +name = "futures-macro" +version = "0.3.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "87750cf4b7a4c0625b1529e4c543c2182106e4dedc60a2a6455e00d212c489ac" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.77", +] + +[[package]] +name = "futures-sink" +version = "0.3.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9fb8e00e87438d937621c1c6269e53f536c14d3fbd6a042bb24879e57d474fb5" + +[[package]] +name = "futures-task" +version = "0.3.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "38d84fa142264698cdce1a9f9172cf383a0c82de1bddcf3092901442c4097004" + +[[package]] +name = "futures-util" +version = "0.3.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3d6401deb83407ab3da39eba7e33987a73c3df0c82b4bb5813ee871c19c41d48" +dependencies = [ + "futures-core", + "futures-macro", + "futures-sink", + "futures-task", + "pin-project-lite", + "pin-utils", +] + +[[package]] +name = "hash32" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b0c35f58762feb77d74ebe43bdbc3210f09be9fe6742234d573bacc26ed92b67" +dependencies = [ + "byteorder", +] + +[[package]] +name = "hash32" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "47d60b12902ba28e2730cd37e95b8c9223af2808df9e902d4df49588d1470606" +dependencies = [ + "byteorder", +] + +[[package]] +name = "hashbrown" +version = "0.13.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "43a3c133739dddd0d2990f9a4bdf8eb4b21ef50e4851ca85ab661199821d510e" +dependencies = [ + "ahash", +] + +[[package]] +name = "heapless" +version = "0.7.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cdc6457c0eb62c71aac4bc17216026d8410337c4126773b9c5daba343f17964f" +dependencies = [ + "atomic-polyfill", + "hash32 0.2.1", + "rustc_version 0.4.1", + "serde", + "spin", + "stable_deref_trait", +] + +[[package]] +name = "heapless" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0bfb9eb618601c89945a70e254898da93b13be0388091d42117462b265bb3fad" +dependencies = [ + "defmt", + "hash32 0.3.1", + "serde", + "stable_deref_trait", +] + +[[package]] +name = "heck" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea" + +[[package]] +name = "ident_case" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b9e0384b61958566e926dc50660321d12159025e767c18e043daf26b70104c39" + +[[package]] +name = "litrs" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b4ce301924b7887e9d637144fdade93f9dfff9b60981d4ac161db09720d39aa5" + +[[package]] +name = "lock_api" +version = "0.4.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "07af8b9cdd281b7915f413fa73f29ebd5d55d0d3f0155584dade1ff18cea1b17" +dependencies = [ + "autocfg", + "scopeguard", +] + +[[package]] +name = "log" +version = "0.4.22" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a7a70ba024b9dc04c27ea2f0c0548feb474ec5c54bba33a7f72f873a39d07b24" + +[[package]] +name = "max44009" +version = "0.2.0" +source = "git+https://github.com/dvdsk/max44009-rs#7b7df2e3173476c250fca3eb242f0dd366857599" +dependencies = [ + "defmt", + "embedded-hal-async", +] + +[[package]] +name = "mhzx" +version = "0.3.0" +dependencies = [ + "defmt", + "embedded-io-async", + "heapless 0.8.0", + "postcard", + "serde", +] + +[[package]] +name = "nau7802-async" +version = "0.2.0" +dependencies = [ + "byteorder", + "defmt", + "embedded-hal-async", + "postcard", + "serde", +] + +[[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 = "num-traits" +version = "0.2.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841" +dependencies = [ + "autocfg", +] + +[[package]] +name = "once_cell" +version = "1.19.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3fdb12b2476b595f9358c5161aa467c2438859caa136dec86c26fdd2efe17b92" + +[[package]] +name = "panic-probe" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4047d9235d1423d66cc97da7d07eddb54d4f154d6c13805c6d0793956f4f25b0" +dependencies = [ + "cortex-m", + "defmt", +] + +[[package]] +name = "pin-project-lite" +version = "0.2.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bda66fc9667c18cb2758a2ac84d1167245054bcf85d5d1aaa6923f45801bdd02" + +[[package]] +name = "pin-utils" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" + +[[package]] +name = "portable-atomic" +version = "1.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d30538d42559de6b034bc76fd6dd4c38961b1ee5c6c56e3808c50128fdbc22ce" + +[[package]] +name = "postcard" +version = "1.0.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5f7f0a8d620d71c457dd1d47df76bb18960378da56af4527aaa10f515eee732e" +dependencies = [ + "cobs", + "defmt", + "heapless 0.7.17", + "postcard-derive", + "serde", +] + +[[package]] +name = "postcard-derive" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0239fa9c1d225d4b7eb69925c25c5e082307a141e470573fbbe3a817ce6a7a37" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "proc-macro-error" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "da25490ff9892aab3fcf7c36f08cfb902dd3e71ca0f9f9517bea02a73a5ce38c" +dependencies = [ + "proc-macro-error-attr", + "proc-macro2", + "quote", + "syn 1.0.109", + "version_check", +] + +[[package]] +name = "proc-macro-error-attr" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a1be40180e52ecc98ad80b184934baf3d0d29f979574e439af5a55274b35f869" +dependencies = [ + "proc-macro2", + "quote", + "version_check", +] + +[[package]] +name = "proc-macro2" +version = "1.0.86" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5e719e8df665df0d1c8fbfd238015744736151d4445ec0836b8e628aae103b77" +dependencies = [ + "unicode-ident", +] + +[[package]] +name = "protocol" +version = "0.1.0" +dependencies = [ + "defmt", + "heapless 0.8.0", + "postcard", + "serde", + "strum", +] + +[[package]] +name = "quote" +version = "1.0.37" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b5b9d34b8991d19d98081b46eacdd8eb58c6f2b201139f7c5f643cc155a633af" +dependencies = [ + "proc-macro2", +] + +[[package]] +name = "rand" +version = "0.8.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404" +dependencies = [ + "rand_core", +] + +[[package]] +name = "rand_core" +version = "0.6.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" + +[[package]] +name = "rustc_version" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "138e3e0acb6c9fb258b19b67cb8abd63c00679d2851805ea151465464fe9030a" +dependencies = [ + "semver 0.9.0", +] + +[[package]] +name = "rustc_version" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cfcb3a22ef46e85b45de6ee7e79d063319ebb6594faafcf1c225ea92ab6e9b92" +dependencies = [ + "semver 1.0.23", +] + +[[package]] +name = "rustversion" +version = "1.0.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "955d28af4278de8121b7ebeb796b6a45735dc01436d898801014aced2773a3d6" + +[[package]] +name = "scopeguard" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" + +[[package]] +name = "sdio-host" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f93c025f9cfe4c388c328ece47d11a54a823da3b5ad0370b22d95ad47137f85a" + +[[package]] +name = "semver" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1d7eb9ef2c18661902cc47e535f9bc51b78acd254da71d375c2f6720d9a40403" +dependencies = [ + "semver-parser", +] + +[[package]] +name = "semver" +version = "1.0.23" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "61697e0a1c7e512e84a621326239844a24d8207b4669b41bc18b32ea5cbf988b" + +[[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.210" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c8e3592472072e6e22e0a54d5904d9febf8508f65fb8552499a1abc7d1078c3a" +dependencies = [ + "serde_derive", +] + +[[package]] +name = "serde_derive" +version = "1.0.210" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "243902eda00fad750862fc144cea25caca5e20d615af0a81bee94ca738f1df1f" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.77", +] + +[[package]] +name = "sht31" +version = "0.3.1" +source = "git+https://github.com/dvdsk/SHT31-rs#a7b6bd94fb137e16bf326eff5fb591624369a2cf" +dependencies = [ + "crc", + "defmt", + "embedded-hal-async", + "postcard", +] + +[[package]] +name = "spin" +version = "0.9.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6980e8d7511241f8acf4aebddbb1ff938df5eebe98691418c4468d0b72a96a67" +dependencies = [ + "lock_api", +] + +[[package]] +name = "sps30-async" +version = "0.3.0" +dependencies = [ + "defmt", + "embedded-hal-async", + "embedded-io-async", + "futures", + "heapless 0.8.0", + "postcard", + "serde", +] + +[[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.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a8f112729512f8e442d81f95a8a7ddf2b7c6b8a1a6f509a95864142b30cab2d3" + +[[package]] +name = "static_assertions" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f" + +[[package]] +name = "static_cell" +version = "2.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d89b0684884a883431282db1e4343f34afc2ff6996fe1f4a1664519b66e14c1e" +dependencies = [ + "portable-atomic", +] + +[[package]] +name = "stm32-fmc" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c7f0639399e2307c2446c54d91d4f1596343a1e1d5cab605b9cce11d0ab3858c" +dependencies = [ + "embedded-hal 0.2.7", +] + +[[package]] +name = "stm32-metapac" +version = "15.0.0" +source = "git+https://github.com/embassy-rs/stm32-data-generated?tag=stm32-data-ad00827345b4b758b2453082809d6e3b634b5364#e442835159a7a311410cd4a2879da52c6f57af52" +dependencies = [ + "cortex-m", + "cortex-m-rt", +] + +[[package]] +name = "strsim" +version = "0.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f" + +[[package]] +name = "strum" +version = "0.26.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8fec0f0aef304996cf250b31b5a10dee7980c85da9d759361292b8bca5a18f06" +dependencies = [ + "strum_macros", +] + +[[package]] +name = "strum_macros" +version = "0.26.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4c6bee85a5a24955dc440386795aa378cd9cf82acd5f764469152d2270e581be" +dependencies = [ + "heck", + "proc-macro2", + "quote", + "rustversion", + "syn 2.0.77", +] + +[[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.77" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9f35bcdf61fd8e7be6caf75f429fdca8beb3ed76584befb503b1569faee373ed" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[package]] +name = "thiserror" +version = "1.0.64" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d50af8abc119fb8bb6dbabcfa89656f46f84aa0ac7688088608076ad2b459a84" +dependencies = [ + "thiserror-impl", +] + +[[package]] +name = "thiserror-impl" +version = "1.0.64" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "08904e7672f5eb876eaaf87e0ce17857500934f4981c4a0ab2b4aa98baac7fc3" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.77", +] + +[[package]] +name = "unicode-ident" +version = "1.0.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e91b56cd4cadaeb79bbf1a5645f6b4f8dc5bde8834ad5894a8db35fda9efa1fe" + +[[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", + "log", + "proc-macro2", + "quote", + "serde", + "syn 1.0.109", + "usbd-hid-descriptors", +] + +[[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 = "zerocopy" +version = "0.7.35" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1b9b4fd18abc82b8136838da5d50bae7bdea537c574d8dc1a34ed098d6c166f0" +dependencies = [ + "zerocopy-derive", +] + +[[package]] +name = "zerocopy-derive" +version = "0.7.35" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fa4f8080344d4671fb4e831a13ad1e68092748387dfc4f55e356242fae12ce3e" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.77", +] diff --git a/nodes/embassy/small-bedroom-bed/Cargo.toml b/nodes/embassy/small-bedroom-bed/Cargo.toml new file mode 100644 index 00000000..fac6480d --- /dev/null +++ b/nodes/embassy/small-bedroom-bed/Cargo.toml @@ -0,0 +1,38 @@ +[package] +name = "bed" +version = "0.2.0" +rust-version = "1.78" +edition = "2021" +license = "GPLv3" +authors = ["David Kleingeld & Eva van Houten"] + +[dependencies] +cortex-m.workspace = true +cortex-m-rt.workspace = true + +embassy-stm32.workspace = true +embassy-sync.workspace = true +embassy-executor.workspace = true +embassy-embedded-hal.workspace = true +embassy-time.workspace = true +embassy-futures.workspace = true +embassy-usb.workspace = true + +defmt.workspace = true +defmt-rtt.workspace = true + +embedded-hal.workspace = true +embedded-hal-async.workspace = true +embedded-hal-bus.workspace = true +embedded-io-async.workspace = true + +panic-probe.workspace = true +futures.workspace = true +heapless.workspace = true + +# sensors +sensors.workspace = true + +# encoding +protocol.workspace = true +usb-bridge-client.workspace = true diff --git a/nodes/embassy/small-bedroom-bed/build.rs b/nodes/embassy/small-bedroom-bed/build.rs new file mode 100644 index 00000000..8cd32d7e --- /dev/null +++ b/nodes/embassy/small-bedroom-bed/build.rs @@ -0,0 +1,5 @@ +fn main() { + println!("cargo:rustc-link-arg-bins=--nmagic"); + println!("cargo:rustc-link-arg-bins=-Tlink.x"); + println!("cargo:rustc-link-arg-bins=-Tdefmt.x"); +} diff --git a/nodes/embassy/small-bedroom-bed/output.txt b/nodes/embassy/small-bedroom-bed/output.txt new file mode 100644 index 00000000..48b0ff76 --- /dev/null +++ b/nodes/embassy/small-bedroom-bed/output.txt @@ -0,0 +1,19660 @@ +DEBUG flash: latency=2 +└─ embassy_stm32::rcc::_version::init @ /home/david/Documents/embassy/embassy-stm32/src/fmt.rs:138 +DEBUG rcc: Clocks { hclk1: MaybeHertz(84000000), pclk1: MaybeHertz(42000000), pclk1_tim: MaybeHertz(84000000), pclk2: MaybeHertz(84000000), pclk2_tim: MaybeHertz(84000000), pll1_q: MaybeHertz(0), pllsai1_q: MaybeHertz(0), rtc: MaybeHertz(32000), sys: MaybeHertz(84000000) } +└─ embassy_stm32::rcc::set_freqs @ /home/david/Documents/embassy/embassy-stm32/src/fmt.rs:138 +INFO random seed: 867502111134296087 +└─ bed_sensors::____embassy_main_task::{async_fn#0} @ src/main.rs:90 +DEBUG IPv4: UP +└─ embassy_net::{impl#5}::apply_static_config @ /home/david/Documents/embassy/embassy-net/src/fmt.rs:138 +DEBUG IP address: 192.168.1.7/24 +└─ embassy_net::{impl#5}::apply_static_config @ /home/david/Documents/embassy/embassy-net/src/fmt.rs:138 +DEBUG Default gateway: Some(192.168.1.1) +└─ embassy_net::{impl#5}::apply_static_config @ /home/david/Documents/embassy/embassy-net/src/fmt.rs:138 +DEBUG Configured socket and connecting +└─ bed_sensors::network::send_published::{async_fn#0} @ src/network.rs:84 +WARN warning connection down, resetting if not up soon +└─ bed_sensors::network::send_published::{async_fn#0} @ src/network.rs:95 +INFO initializing sensors +└─ bed_sensors::sensors::init_then_measure::{async_fn#0} @ src/sensors.rs:51 +DEBUG address 192.168.1.43 not in neighbor cache, sending ARP request +└─ smoltcp::iface::interface::{impl#2}::lookup_hardware_addr @ /home/david/.cargo/registry/src/index.crates.io-6f17d22bba15001f/smoltcp-0.11.0/src/macros.rs:18 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG address 192.168.1.43 not in neighbor cache, sending ARP request +└─ smoltcp::iface::interface::{impl#2}::lookup_hardware_addr @ /home/david/.cargo/registry/src/index.crates.io-6f17d22bba15001f/smoltcp-0.11.0/src/macros.rs:18 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +INFO link_up = true +└─ embassy_net::{impl#5}::poll @ /home/david/Documents/embassy/embassy-net/src/fmt.rs:152 +DEBUG address 192.168.1.43 not in neighbor cache, sending ARP request +└─ smoltcp::iface::interface::{impl#2}::lookup_hardware_addr @ /home/david/.cargo/registry/src/index.crates.io-6f17d22bba15001f/smoltcp-0.11.0/src/macros.rs:18 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +INFO (re-)connected +└─ bed_sensors::network::send_published::{async_fn#0} @ src/network.rs:106 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG timeout exceeded +└─ smoltcp::socket::tcp::{impl#9}::dispatch @ /home/david/.cargo/registry/src/index.crates.io-6f17d22bba15001f/smoltcp-0.11.0/src/macros.rs:18 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +WARN write error: ConnectionReset +└─ bed_sensors::network::send_published::{async_fn#0} @ src/network.rs:114 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +INFO (re-)connected +└─ bed_sensors::network::send_published::{async_fn#0} @ src/network.rs:106 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG queueing error: Timeout(Sht31) +└─ bed_sensors::channel::{impl#0}::queue_error @ src/channel.rs:69 +DEBUG queueing error: Timeout(Mhz14) +└─ bed_sensors::channel::{impl#0}::queue_error @ src/channel.rs:69 +DEBUG queueing error: Timeout(Sps30) +└─ bed_sensors::channel::{impl#0}::queue_error @ src/channel.rs:69 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG flash: latency=2 +└─ embassy_stm32::rcc::_version::init @ /home/david/Documents/embassy/embassy-stm32/src/fmt.rs:138 +DEBUG rcc: Clocks { hclk1: MaybeHertz(84000000), pclk1: MaybeHertz(42000000), pclk1_tim: MaybeHertz(84000000), pclk2: MaybeHertz(84000000), pclk2_tim: MaybeHertz(84000000), pll1_q: MaybeHertz(0), pllsai1_q: MaybeHertz(0), rtc: MaybeHertz(32000), sys: MaybeHertz(84000000) } +└─ embassy_stm32::rcc::set_freqs @ /home/david/Documents/embassy/embassy-stm32/src/fmt.rs:138 +INFO random seed: 14599460162574367279 +└─ bed_sensors::____embassy_main_task::{async_fn#0} @ src/main.rs:90 +DEBUG IPv4: UP +└─ embassy_net::{impl#5}::apply_static_config @ /home/david/Documents/embassy/embassy-net/src/fmt.rs:138 +DEBUG IP address: 192.168.1.7/24 +└─ embassy_net::{impl#5}::apply_static_config @ /home/david/Documents/embassy/embassy-net/src/fmt.rs:138 +DEBUG Default gateway: Some(192.168.1.1) +└─ embassy_net::{impl#5}::apply_static_config @ /home/david/Documents/embassy/embassy-net/src/fmt.rs:138 +DEBUG Configured socket and connecting +└─ bed_sensors::network::send_published::{async_fn#0} @ src/network.rs:84 +WARN warning connection down, resetting if not up soon +└─ bed_sensors::network::send_published::{async_fn#0} @ src/network.rs:95 +INFO initializing sensors +└─ bed_sensors::sensors::init_then_measure::{async_fn#0} @ src/sensors.rs:51 +DEBUG address 192.168.1.43 not in neighbor cache, sending ARP request +└─ smoltcp::iface::interface::{impl#2}::lookup_hardware_addr @ /home/david/.cargo/registry/src/index.crates.io-6f17d22bba15001f/smoltcp-0.11.0/src/macros.rs:18 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG address 192.168.1.43 not in neighbor cache, sending ARP request +└─ smoltcp::iface::interface::{impl#2}::lookup_hardware_addr @ /home/david/.cargo/registry/src/index.crates.io-6f17d22bba15001f/smoltcp-0.11.0/src/macros.rs:18 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +INFO link_up = true +└─ embassy_net::{impl#5}::poll @ /home/david/Documents/embassy/embassy-net/src/fmt.rs:152 +DEBUG address 192.168.1.43 not in neighbor cache, sending ARP request +└─ smoltcp::iface::interface::{impl#2}::lookup_hardware_addr @ /home/david/.cargo/registry/src/index.crates.io-6f17d22bba15001f/smoltcp-0.11.0/src/macros.rs:18 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +INFO (re-)connected +└─ bed_sensors::network::send_published::{async_fn#0} @ src/network.rs:106 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG timeout exceeded +└─ smoltcp::socket::tcp::{impl#9}::dispatch @ /home/david/.cargo/registry/src/index.crates.io-6f17d22bba15001f/smoltcp-0.11.0/src/macros.rs:18 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +WARN write error: ConnectionReset +└─ bed_sensors::network::send_published::{async_fn#0} @ src/network.rs:114 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +INFO (re-)connected +└─ bed_sensors::network::send_published::{async_fn#0} @ src/network.rs:106 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG queueing error: Timeout(Sht31) +└─ bed_sensors::channel::{impl#0}::queue_error @ src/channel.rs:69 +DEBUG queueing error: Timeout(Mhz14) +└─ bed_sensors::channel::{impl#0}::queue_error @ src/channel.rs:69 +DEBUG queueing error: Timeout(Sps30) +└─ bed_sensors::channel::{impl#0}::queue_error @ src/channel.rs:69 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG flash: latency=2 +└─ embassy_stm32::rcc::_version::init @ /home/david/Documents/embassy/embassy-stm32/src/fmt.rs:138 +DEBUG rcc: Clocks { hclk1: MaybeHertz(84000000), pclk1: MaybeHertz(42000000), pclk1_tim: MaybeHertz(84000000), pclk2: MaybeHertz(84000000), pclk2_tim: MaybeHertz(84000000), pll1_q: MaybeHertz(0), pllsai1_q: MaybeHertz(0), rtc: MaybeHertz(32000), sys: MaybeHertz(84000000) } +└─ embassy_stm32::rcc::set_freqs @ /home/david/Documents/embassy/embassy-stm32/src/fmt.rs:138 +INFO random seed: 8070402030576215694 +└─ bed_sensors::____embassy_main_task::{async_fn#0} @ src/main.rs:90 +DEBUG IPv4: UP +└─ embassy_net::{impl#5}::apply_static_config @ /home/david/Documents/embassy/embassy-net/src/fmt.rs:138 +DEBUG IP address: 192.168.1.7/24 +└─ embassy_net::{impl#5}::apply_static_config @ /home/david/Documents/embassy/embassy-net/src/fmt.rs:138 +DEBUG Default gateway: Some(192.168.1.1) +└─ embassy_net::{impl#5}::apply_static_config @ /home/david/Documents/embassy/embassy-net/src/fmt.rs:138 +DEBUG Configured socket and connecting +└─ bed_sensors::network::send_published::{async_fn#0} @ src/network.rs:84 +WARN warning connection down, resetting if not up soon +└─ bed_sensors::network::send_published::{async_fn#0} @ src/network.rs:95 +INFO initializing sensors +└─ bed_sensors::sensors::init_then_measure::{async_fn#0} @ src/sensors.rs:51 +DEBUG address 192.168.1.43 not in neighbor cache, sending ARP request +└─ smoltcp::iface::interface::{impl#2}::lookup_hardware_addr @ /home/david/.cargo/registry/src/index.crates.io-6f17d22bba15001f/smoltcp-0.11.0/src/macros.rs:18 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG address 192.168.1.43 not in neighbor cache, sending ARP request +└─ smoltcp::iface::interface::{impl#2}::lookup_hardware_addr @ /home/david/.cargo/registry/src/index.crates.io-6f17d22bba15001f/smoltcp-0.11.0/src/macros.rs:18 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +INFO link_up = true +└─ embassy_net::{impl#5}::poll @ /home/david/Documents/embassy/embassy-net/src/fmt.rs:152 +DEBUG address 192.168.1.43 not in neighbor cache, sending ARP request +└─ smoltcp::iface::interface::{impl#2}::lookup_hardware_addr @ /home/david/.cargo/registry/src/index.crates.io-6f17d22bba15001f/smoltcp-0.11.0/src/macros.rs:18 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +INFO (re-)connected +└─ bed_sensors::network::send_published::{async_fn#0} @ src/network.rs:106 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG timeout exceeded +└─ smoltcp::socket::tcp::{impl#9}::dispatch @ /home/david/.cargo/registry/src/index.crates.io-6f17d22bba15001f/smoltcp-0.11.0/src/macros.rs:18 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +WARN write error: ConnectionReset +└─ bed_sensors::network::send_published::{async_fn#0} @ src/network.rs:114 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +INFO (re-)connected +└─ bed_sensors::network::send_published::{async_fn#0} @ src/network.rs:106 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG queueing error: Timeout(Sht31) +└─ bed_sensors::channel::{impl#0}::queue_error @ src/channel.rs:69 +DEBUG queueing error: Timeout(Mhz14) +└─ bed_sensors::channel::{impl#0}::queue_error @ src/channel.rs:69 +DEBUG queueing error: Timeout(Sps30) +└─ bed_sensors::channel::{impl#0}::queue_error @ src/channel.rs:69 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG timeout exceeded +└─ smoltcp::socket::tcp::{impl#9}::dispatch @ /home/david/.cargo/registry/src/index.crates.io-6f17d22bba15001f/smoltcp-0.11.0/src/macros.rs:18 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG flash: latency=2 +└─ embassy_stm32::rcc::_version::init @ /home/david/Documents/embassy/embassy-stm32/src/fmt.rs:138 +DEBUG rcc: Clocks { hclk1: MaybeHertz(84000000), pclk1: MaybeHertz(42000000), pclk1_tim: MaybeHertz(84000000), pclk2: MaybeHertz(84000000), pclk2_tim: MaybeHertz(84000000), pll1_q: MaybeHertz(0), pllsai1_q: MaybeHertz(0), rtc: MaybeHertz(32000), sys: MaybeHertz(84000000) } +└─ embassy_stm32::rcc::set_freqs @ /home/david/Documents/embassy/embassy-stm32/src/fmt.rs:138 +INFO random seed: 4334505959795280607 +└─ bed_sensors::____embassy_main_task::{async_fn#0} @ src/main.rs:90 +DEBUG IPv4: UP +└─ embassy_net::{impl#5}::apply_static_config @ /home/david/Documents/embassy/embassy-net/src/fmt.rs:138 +DEBUG IP address: 192.168.1.7/24 +└─ embassy_net::{impl#5}::apply_static_config @ /home/david/Documents/embassy/embassy-net/src/fmt.rs:138 +DEBUG Default gateway: Some(192.168.1.1) +└─ embassy_net::{impl#5}::apply_static_config @ /home/david/Documents/embassy/embassy-net/src/fmt.rs:138 +DEBUG Configured socket and connecting +└─ bed_sensors::network::send_published::{async_fn#0} @ src/network.rs:84 +WARN warning connection down, resetting if not up soon +└─ bed_sensors::network::send_published::{async_fn#0} @ src/network.rs:95 +INFO initializing sensors +└─ bed_sensors::sensors::init_then_measure::{async_fn#0} @ src/sensors.rs:51 +DEBUG address 192.168.1.43 not in neighbor cache, sending ARP request +└─ smoltcp::iface::interface::{impl#2}::lookup_hardware_addr @ /home/david/.cargo/registry/src/index.crates.io-6f17d22bba15001f/smoltcp-0.11.0/src/macros.rs:18 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG address 192.168.1.43 not in neighbor cache, sending ARP request +└─ smoltcp::iface::interface::{impl#2}::lookup_hardware_addr @ /home/david/.cargo/registry/src/index.crates.io-6f17d22bba15001f/smoltcp-0.11.0/src/macros.rs:18 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +INFO link_up = true +└─ embassy_net::{impl#5}::poll @ /home/david/Documents/embassy/embassy-net/src/fmt.rs:152 +DEBUG address 192.168.1.43 not in neighbor cache, sending ARP request +└─ smoltcp::iface::interface::{impl#2}::lookup_hardware_addr @ /home/david/.cargo/registry/src/index.crates.io-6f17d22bba15001f/smoltcp-0.11.0/src/macros.rs:18 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +INFO (re-)connected +└─ bed_sensors::network::send_published::{async_fn#0} @ src/network.rs:106 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG timeout exceeded +└─ smoltcp::socket::tcp::{impl#9}::dispatch @ /home/david/.cargo/registry/src/index.crates.io-6f17d22bba15001f/smoltcp-0.11.0/src/macros.rs:18 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +WARN write error: ConnectionReset +└─ bed_sensors::network::send_published::{async_fn#0} @ src/network.rs:114 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +INFO (re-)connected +└─ bed_sensors::network::send_published::{async_fn#0} @ src/network.rs:106 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG queueing error: Timeout(Sht31) +└─ bed_sensors::channel::{impl#0}::queue_error @ src/channel.rs:69 +DEBUG queueing error: Timeout(Mhz14) +└─ bed_sensors::channel::{impl#0}::queue_error @ src/channel.rs:69 +DEBUG queueing error: Timeout(Sps30) +└─ bed_sensors::channel::{impl#0}::queue_error @ src/channel.rs:69 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG timeout exceeded +└─ smoltcp::socket::tcp::{impl#9}::dispatch @ /home/david/.cargo/registry/src/index.crates.io-6f17d22bba15001f/smoltcp-0.11.0/src/macros.rs:18 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG flash: latency=2 +└─ embassy_stm32::rcc::_version::init @ /home/david/Documents/embassy/embassy-stm32/src/fmt.rs:138 +DEBUG rcc: Clocks { hclk1: MaybeHertz(84000000), pclk1: MaybeHertz(42000000), pclk1_tim: MaybeHertz(84000000), pclk2: MaybeHertz(84000000), pclk2_tim: MaybeHertz(84000000), pll1_q: MaybeHertz(0), pllsai1_q: MaybeHertz(0), rtc: MaybeHertz(32000), sys: MaybeHertz(84000000) } +└─ embassy_stm32::rcc::set_freqs @ /home/david/Documents/embassy/embassy-stm32/src/fmt.rs:138 +INFO random seed: 12614019627889602978 +└─ bed_sensors::____embassy_main_task::{async_fn#0} @ src/main.rs:90 +DEBUG IPv4: UP +└─ embassy_net::{impl#5}::apply_static_config @ /home/david/Documents/embassy/embassy-net/src/fmt.rs:138 +DEBUG IP address: 192.168.1.7/24 +└─ embassy_net::{impl#5}::apply_static_config @ /home/david/Documents/embassy/embassy-net/src/fmt.rs:138 +DEBUG Default gateway: Some(192.168.1.1) +└─ embassy_net::{impl#5}::apply_static_config @ /home/david/Documents/embassy/embassy-net/src/fmt.rs:138 +DEBUG Configured socket and connecting +└─ bed_sensors::network::send_published::{async_fn#0} @ src/network.rs:84 +WARN warning connection down, resetting if not up soon +└─ bed_sensors::network::send_published::{async_fn#0} @ src/network.rs:95 +INFO initializing sensors +└─ bed_sensors::sensors::init_then_measure::{async_fn#0} @ src/sensors.rs:51 +DEBUG address 192.168.1.43 not in neighbor cache, sending ARP request +└─ smoltcp::iface::interface::{impl#2}::lookup_hardware_addr @ /home/david/.cargo/registry/src/index.crates.io-6f17d22bba15001f/smoltcp-0.11.0/src/macros.rs:18 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG address 192.168.1.43 not in neighbor cache, sending ARP request +└─ smoltcp::iface::interface::{impl#2}::lookup_hardware_addr @ /home/david/.cargo/registry/src/index.crates.io-6f17d22bba15001f/smoltcp-0.11.0/src/macros.rs:18 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +INFO link_up = true +└─ embassy_net::{impl#5}::poll @ /home/david/Documents/embassy/embassy-net/src/fmt.rs:152 +DEBUG address 192.168.1.43 not in neighbor cache, sending ARP request +└─ smoltcp::iface::interface::{impl#2}::lookup_hardware_addr @ /home/david/.cargo/registry/src/index.crates.io-6f17d22bba15001f/smoltcp-0.11.0/src/macros.rs:18 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +INFO (re-)connected +└─ bed_sensors::network::send_published::{async_fn#0} @ src/network.rs:106 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG timeout exceeded +└─ smoltcp::socket::tcp::{impl#9}::dispatch @ /home/david/.cargo/registry/src/index.crates.io-6f17d22bba15001f/smoltcp-0.11.0/src/macros.rs:18 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +WARN write error: ConnectionReset +└─ bed_sensors::network::send_published::{async_fn#0} @ src/network.rs:114 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +INFO (re-)connected +└─ bed_sensors::network::send_published::{async_fn#0} @ src/network.rs:106 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG queueing error: Timeout(Sht31) +└─ bed_sensors::channel::{impl#0}::queue_error @ src/channel.rs:69 +DEBUG queueing error: Timeout(Mhz14) +└─ bed_sensors::channel::{impl#0}::queue_error @ src/channel.rs:69 +DEBUG queueing error: Timeout(Sps30) +└─ bed_sensors::channel::{impl#0}::queue_error @ src/channel.rs:69 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG flash: latency=2 +└─ embassy_stm32::rcc::_version::init @ /home/david/Documents/embassy/embassy-stm32/src/fmt.rs:138 +DEBUG rcc: Clocks { hclk1: MaybeHertz(84000000), pclk1: MaybeHertz(42000000), pclk1_tim: MaybeHertz(84000000), pclk2: MaybeHertz(84000000), pclk2_tim: MaybeHertz(84000000), pll1_q: MaybeHertz(0), pllsai1_q: MaybeHertz(0), rtc: MaybeHertz(32000), sys: MaybeHertz(84000000) } +└─ embassy_stm32::rcc::set_freqs @ /home/david/Documents/embassy/embassy-stm32/src/fmt.rs:138 +INFO random seed: 13081958469941311299 +└─ bed_sensors::____embassy_main_task::{async_fn#0} @ src/main.rs:90 +DEBUG IPv4: UP +└─ embassy_net::{impl#5}::apply_static_config @ /home/david/Documents/embassy/embassy-net/src/fmt.rs:138 +DEBUG IP address: 192.168.1.7/24 +└─ embassy_net::{impl#5}::apply_static_config @ /home/david/Documents/embassy/embassy-net/src/fmt.rs:138 +DEBUG Default gateway: Some(192.168.1.1) +└─ embassy_net::{impl#5}::apply_static_config @ /home/david/Documents/embassy/embassy-net/src/fmt.rs:138 +DEBUG Configured socket and connecting +└─ bed_sensors::network::send_published::{async_fn#0} @ src/network.rs:84 +WARN warning connection down, resetting if not up soon +└─ bed_sensors::network::send_published::{async_fn#0} @ src/network.rs:95 +INFO initializing sensors +└─ bed_sensors::sensors::init_then_measure::{async_fn#0} @ src/sensors.rs:51 +DEBUG address 192.168.1.43 not in neighbor cache, sending ARP request +└─ smoltcp::iface::interface::{impl#2}::lookup_hardware_addr @ /home/david/.cargo/registry/src/index.crates.io-6f17d22bba15001f/smoltcp-0.11.0/src/macros.rs:18 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG address 192.168.1.43 not in neighbor cache, sending ARP request +└─ smoltcp::iface::interface::{impl#2}::lookup_hardware_addr @ /home/david/.cargo/registry/src/index.crates.io-6f17d22bba15001f/smoltcp-0.11.0/src/macros.rs:18 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +INFO link_up = true +└─ embassy_net::{impl#5}::poll @ /home/david/Documents/embassy/embassy-net/src/fmt.rs:152 +DEBUG address 192.168.1.43 not in neighbor cache, sending ARP request +└─ smoltcp::iface::interface::{impl#2}::lookup_hardware_addr @ /home/david/.cargo/registry/src/index.crates.io-6f17d22bba15001f/smoltcp-0.11.0/src/macros.rs:18 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +INFO (re-)connected +└─ bed_sensors::network::send_published::{async_fn#0} @ src/network.rs:106 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG timeout exceeded +└─ smoltcp::socket::tcp::{impl#9}::dispatch @ /home/david/.cargo/registry/src/index.crates.io-6f17d22bba15001f/smoltcp-0.11.0/src/macros.rs:18 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +WARN write error: ConnectionReset +└─ bed_sensors::network::send_published::{async_fn#0} @ src/network.rs:114 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +INFO (re-)connected +└─ bed_sensors::network::send_published::{async_fn#0} @ src/network.rs:106 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG queueing error: Timeout(Sht31) +└─ bed_sensors::channel::{impl#0}::queue_error @ src/channel.rs:69 +DEBUG queueing error: Timeout(Mhz14) +└─ bed_sensors::channel::{impl#0}::queue_error @ src/channel.rs:69 +DEBUG queueing error: Timeout(Sps30) +└─ bed_sensors::channel::{impl#0}::queue_error @ src/channel.rs:69 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG queueing error: Timeout(Sht31) +└─ bed_sensors::channel::{impl#0}::queue_error @ src/channel.rs:69 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG queueing error: Timeout(Mhz14) +└─ bed_sensors::channel::{impl#0}::queue_error @ src/channel.rs:69 +DEBUG queueing error: Timeout(Sps30) +└─ bed_sensors::channel::{impl#0}::queue_error @ src/channel.rs:69 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG queueing error: Timeout(Sht31) +└─ bed_sensors::channel::{impl#0}::queue_error @ src/channel.rs:69 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG queueing error: Timeout(Mhz14) +└─ bed_sensors::channel::{impl#0}::queue_error @ src/channel.rs:69 +DEBUG queueing error: Timeout(Sps30) +└─ bed_sensors::channel::{impl#0}::queue_error @ src/channel.rs:69 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG queueing error: Timeout(Sht31) +└─ bed_sensors::channel::{impl#0}::queue_error @ src/channel.rs:69 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG queueing error: Timeout(Mhz14) +└─ bed_sensors::channel::{impl#0}::queue_error @ src/channel.rs:69 +DEBUG queueing error: Timeout(Sps30) +└─ bed_sensors::channel::{impl#0}::queue_error @ src/channel.rs:69 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG queueing error: Timeout(Sht31) +└─ bed_sensors::channel::{impl#0}::queue_error @ src/channel.rs:69 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG queueing error: Timeout(Mhz14) +└─ bed_sensors::channel::{impl#0}::queue_error @ src/channel.rs:69 +DEBUG queueing error: Timeout(Sps30) +└─ bed_sensors::channel::{impl#0}::queue_error @ src/channel.rs:69 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG queueing error: Timeout(Sht31) +└─ bed_sensors::channel::{impl#0}::queue_error @ src/channel.rs:69 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG queueing error: Timeout(Mhz14) +└─ bed_sensors::channel::{impl#0}::queue_error @ src/channel.rs:69 +DEBUG queueing error: Timeout(Sps30) +└─ bed_sensors::channel::{impl#0}::queue_error @ src/channel.rs:69 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG queueing error: Timeout(Sht31) +└─ bed_sensors::channel::{impl#0}::queue_error @ src/channel.rs:69 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG queueing error: Timeout(Mhz14) +└─ bed_sensors::channel::{impl#0}::queue_error @ src/channel.rs:69 +DEBUG queueing error: Timeout(Sps30) +└─ bed_sensors::channel::{impl#0}::queue_error @ src/channel.rs:69 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG queueing error: Timeout(Sht31) +└─ bed_sensors::channel::{impl#0}::queue_error @ src/channel.rs:69 +DEBUG queueing error: Timeout(Mhz14) +└─ bed_sensors::channel::{impl#0}::queue_error @ src/channel.rs:69 +DEBUG queueing error: Timeout(Sps30) +└─ bed_sensors::channel::{impl#0}::queue_error @ src/channel.rs:69 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG queueing error: Timeout(Sht31) +└─ bed_sensors::channel::{impl#0}::queue_error @ src/channel.rs:69 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG queueing error: Timeout(Mhz14) +└─ bed_sensors::channel::{impl#0}::queue_error @ src/channel.rs:69 +DEBUG queueing error: Timeout(Sps30) +└─ bed_sensors::channel::{impl#0}::queue_error @ src/channel.rs:69 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG flash: latency=2 +└─ embassy_stm32::rcc::_version::init @ /home/david/Documents/embassy/embassy-stm32/src/fmt.rs:138 +DEBUG rcc: Clocks { hclk1: MaybeHertz(84000000), pclk1: MaybeHertz(42000000), pclk1_tim: MaybeHertz(84000000), pclk2: MaybeHertz(84000000), pclk2_tim: MaybeHertz(84000000), pll1_q: MaybeHertz(0), pllsai1_q: MaybeHertz(0), rtc: MaybeHertz(32000), sys: MaybeHertz(84000000) } +└─ embassy_stm32::rcc::set_freqs @ /home/david/Documents/embassy/embassy-stm32/src/fmt.rs:138 +INFO random seed: 17908139605922323881 +└─ bed_sensors::____embassy_main_task::{async_fn#0} @ src/main.rs:90 +DEBUG IPv4: UP +└─ embassy_net::{impl#5}::apply_static_config @ /home/david/Documents/embassy/embassy-net/src/fmt.rs:138 +DEBUG IP address: 192.168.1.7/24 +└─ embassy_net::{impl#5}::apply_static_config @ /home/david/Documents/embassy/embassy-net/src/fmt.rs:138 +DEBUG Default gateway: Some(192.168.1.1) +└─ embassy_net::{impl#5}::apply_static_config @ /home/david/Documents/embassy/embassy-net/src/fmt.rs:138 +DEBUG Configured socket and connecting +└─ bed_sensors::network::send_published::{async_fn#0} @ src/network.rs:84 +WARN warning connection down, resetting if not up soon +└─ bed_sensors::network::send_published::{async_fn#0} @ src/network.rs:95 +INFO initializing sensors +└─ bed_sensors::sensors::init_then_measure::{async_fn#0} @ src/sensors.rs:51 +DEBUG address 192.168.1.43 not in neighbor cache, sending ARP request +└─ smoltcp::iface::interface::{impl#2}::lookup_hardware_addr @ /home/david/.cargo/registry/src/index.crates.io-6f17d22bba15001f/smoltcp-0.11.0/src/macros.rs:18 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG address 192.168.1.43 not in neighbor cache, sending ARP request +└─ smoltcp::iface::interface::{impl#2}::lookup_hardware_addr @ /home/david/.cargo/registry/src/index.crates.io-6f17d22bba15001f/smoltcp-0.11.0/src/macros.rs:18 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG address 192.168.1.43 not in neighbor cache, sending ARP request +└─ smoltcp::iface::interface::{impl#2}::lookup_hardware_addr @ /home/david/.cargo/registry/src/index.crates.io-6f17d22bba15001f/smoltcp-0.11.0/src/macros.rs:18 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +INFO link_up = true +└─ embassy_net::{impl#5}::poll @ /home/david/Documents/embassy/embassy-net/src/fmt.rs:152 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +INFO (re-)connected +└─ bed_sensors::network::send_published::{async_fn#0} @ src/network.rs:106 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG timeout exceeded +└─ smoltcp::socket::tcp::{impl#9}::dispatch @ /home/david/.cargo/registry/src/index.crates.io-6f17d22bba15001f/smoltcp-0.11.0/src/macros.rs:18 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +WARN write error: ConnectionReset +└─ bed_sensors::network::send_published::{async_fn#0} @ src/network.rs:114 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +INFO (re-)connected +└─ bed_sensors::network::send_published::{async_fn#0} @ src/network.rs:106 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG queueing error: Timeout(Sht31) +└─ bed_sensors::channel::{impl#0}::queue_error @ src/channel.rs:69 +DEBUG queueing error: Timeout(Mhz14) +└─ bed_sensors::channel::{impl#0}::queue_error @ src/channel.rs:69 +DEBUG queueing error: Timeout(Sps30) +└─ bed_sensors::channel::{impl#0}::queue_error @ src/channel.rs:69 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG timeout exceeded +└─ smoltcp::socket::tcp::{impl#9}::dispatch @ /home/david/.cargo/registry/src/index.crates.io-6f17d22bba15001f/smoltcp-0.11.0/src/macros.rs:18 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG flash: latency=2 +└─ embassy_stm32::rcc::_version::init @ /home/david/Documents/embassy/embassy-stm32/src/fmt.rs:138 +DEBUG rcc: Clocks { hclk1: MaybeHertz(84000000), pclk1: MaybeHertz(42000000), pclk1_tim: MaybeHertz(84000000), pclk2: MaybeHertz(84000000), pclk2_tim: MaybeHertz(84000000), pll1_q: MaybeHertz(0), pllsai1_q: MaybeHertz(0), rtc: MaybeHertz(32000), sys: MaybeHertz(84000000) } +└─ embassy_stm32::rcc::set_freqs @ /home/david/Documents/embassy/embassy-stm32/src/fmt.rs:138 +INFO random seed: 2841131338015846188 +└─ bed_sensors::____embassy_main_task::{async_fn#0} @ src/main.rs:90 +DEBUG IPv4: UP +└─ embassy_net::{impl#5}::apply_static_config @ /home/david/Documents/embassy/embassy-net/src/fmt.rs:138 +DEBUG IP address: 192.168.1.7/24 +└─ embassy_net::{impl#5}::apply_static_config @ /home/david/Documents/embassy/embassy-net/src/fmt.rs:138 +DEBUG Default gateway: Some(192.168.1.1) +└─ embassy_net::{impl#5}::apply_static_config @ /home/david/Documents/embassy/embassy-net/src/fmt.rs:138 +DEBUG Configured socket and connecting +└─ bed_sensors::network::send_published::{async_fn#0} @ src/network.rs:84 +WARN warning connection down, resetting if not up soon +└─ bed_sensors::network::send_published::{async_fn#0} @ src/network.rs:95 +INFO initializing sensors +└─ bed_sensors::sensors::init_then_measure::{async_fn#0} @ src/sensors.rs:51 +DEBUG address 192.168.1.43 not in neighbor cache, sending ARP request +└─ smoltcp::iface::interface::{impl#2}::lookup_hardware_addr @ /home/david/.cargo/registry/src/index.crates.io-6f17d22bba15001f/smoltcp-0.11.0/src/macros.rs:18 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG address 192.168.1.43 not in neighbor cache, sending ARP request +└─ smoltcp::iface::interface::{impl#2}::lookup_hardware_addr @ /home/david/.cargo/registry/src/index.crates.io-6f17d22bba15001f/smoltcp-0.11.0/src/macros.rs:18 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +INFO link_up = true +└─ embassy_net::{impl#5}::poll @ /home/david/Documents/embassy/embassy-net/src/fmt.rs:152 +DEBUG address 192.168.1.43 not in neighbor cache, sending ARP request +└─ smoltcp::iface::interface::{impl#2}::lookup_hardware_addr @ /home/david/.cargo/registry/src/index.crates.io-6f17d22bba15001f/smoltcp-0.11.0/src/macros.rs:18 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +INFO (re-)connected +└─ bed_sensors::network::send_published::{async_fn#0} @ src/network.rs:106 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG timeout exceeded +└─ smoltcp::socket::tcp::{impl#9}::dispatch @ /home/david/.cargo/registry/src/index.crates.io-6f17d22bba15001f/smoltcp-0.11.0/src/macros.rs:18 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +WARN write error: ConnectionReset +└─ bed_sensors::network::send_published::{async_fn#0} @ src/network.rs:114 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +INFO (re-)connected +└─ bed_sensors::network::send_published::{async_fn#0} @ src/network.rs:106 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG queueing error: Timeout(Sht31) +└─ bed_sensors::channel::{impl#0}::queue_error @ src/channel.rs:69 +DEBUG queueing error: Timeout(Mhz14) +└─ bed_sensors::channel::{impl#0}::queue_error @ src/channel.rs:69 +DEBUG queueing error: Timeout(Sps30) +└─ bed_sensors::channel::{impl#0}::queue_error @ src/channel.rs:69 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG flash: latency=2 +└─ embassy_stm32::rcc::_version::init @ /home/david/Documents/embassy/embassy-stm32/src/fmt.rs:138 +DEBUG rcc: Clocks { hclk1: MaybeHertz(84000000), pclk1: MaybeHertz(42000000), pclk1_tim: MaybeHertz(84000000), pclk2: MaybeHertz(84000000), pclk2_tim: MaybeHertz(84000000), pll1_q: MaybeHertz(0), pllsai1_q: MaybeHertz(0), rtc: MaybeHertz(32000), sys: MaybeHertz(84000000) } +└─ embassy_stm32::rcc::set_freqs @ /home/david/Documents/embassy/embassy-stm32/src/fmt.rs:138 +INFO random seed: 13356480873848707970 +└─ bed_sensors::____embassy_main_task::{async_fn#0} @ src/main.rs:90 +DEBUG IPv4: UP +└─ embassy_net::{impl#5}::apply_static_config @ /home/david/Documents/embassy/embassy-net/src/fmt.rs:138 +DEBUG IP address: 192.168.1.7/24 +└─ embassy_net::{impl#5}::apply_static_config @ /home/david/Documents/embassy/embassy-net/src/fmt.rs:138 +DEBUG Default gateway: Some(192.168.1.1) +└─ embassy_net::{impl#5}::apply_static_config @ /home/david/Documents/embassy/embassy-net/src/fmt.rs:138 +DEBUG Configured socket and connecting +└─ bed_sensors::network::send_published::{async_fn#0} @ src/network.rs:84 +WARN warning connection down, resetting if not up soon +└─ bed_sensors::network::send_published::{async_fn#0} @ src/network.rs:95 +INFO initializing sensors +└─ bed_sensors::sensors::init_then_measure::{async_fn#0} @ src/sensors.rs:51 +DEBUG address 192.168.1.43 not in neighbor cache, sending ARP request +└─ smoltcp::iface::interface::{impl#2}::lookup_hardware_addr @ /home/david/.cargo/registry/src/index.crates.io-6f17d22bba15001f/smoltcp-0.11.0/src/macros.rs:18 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG address 192.168.1.43 not in neighbor cache, sending ARP request +└─ smoltcp::iface::interface::{impl#2}::lookup_hardware_addr @ /home/david/.cargo/registry/src/index.crates.io-6f17d22bba15001f/smoltcp-0.11.0/src/macros.rs:18 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +INFO link_up = true +└─ embassy_net::{impl#5}::poll @ /home/david/Documents/embassy/embassy-net/src/fmt.rs:152 +DEBUG address 192.168.1.43 not in neighbor cache, sending ARP request +└─ smoltcp::iface::interface::{impl#2}::lookup_hardware_addr @ /home/david/.cargo/registry/src/index.crates.io-6f17d22bba15001f/smoltcp-0.11.0/src/macros.rs:18 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +INFO (re-)connected +└─ bed_sensors::network::send_published::{async_fn#0} @ src/network.rs:106 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG timeout exceeded +└─ smoltcp::socket::tcp::{impl#9}::dispatch @ /home/david/.cargo/registry/src/index.crates.io-6f17d22bba15001f/smoltcp-0.11.0/src/macros.rs:18 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +WARN write error: ConnectionReset +└─ bed_sensors::network::send_published::{async_fn#0} @ src/network.rs:114 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +INFO (re-)connected +└─ bed_sensors::network::send_published::{async_fn#0} @ src/network.rs:106 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG queueing error: Timeout(Sht31) +└─ bed_sensors::channel::{impl#0}::queue_error @ src/channel.rs:69 +DEBUG queueing error: Timeout(Mhz14) +└─ bed_sensors::channel::{impl#0}::queue_error @ src/channel.rs:69 +DEBUG queueing error: Timeout(Sps30) +└─ bed_sensors::channel::{impl#0}::queue_error @ src/channel.rs:69 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG timeout exceeded +└─ smoltcp::socket::tcp::{impl#9}::dispatch @ /home/david/.cargo/registry/src/index.crates.io-6f17d22bba15001f/smoltcp-0.11.0/src/macros.rs:18 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG flash: latency=2 +└─ embassy_stm32::rcc::_version::init @ /home/david/Documents/embassy/embassy-stm32/src/fmt.rs:138 +DEBUG rcc: Clocks { hclk1: MaybeHertz(84000000), pclk1: MaybeHertz(42000000), pclk1_tim: MaybeHertz(84000000), pclk2: MaybeHertz(84000000), pclk2_tim: MaybeHertz(84000000), pll1_q: MaybeHertz(0), pllsai1_q: MaybeHertz(0), rtc: MaybeHertz(32000), sys: MaybeHertz(84000000) } +└─ embassy_stm32::rcc::set_freqs @ /home/david/Documents/embassy/embassy-stm32/src/fmt.rs:138 +INFO random seed: 1656018264575584532 +└─ bed_sensors::____embassy_main_task::{async_fn#0} @ src/main.rs:90 +DEBUG IPv4: UP +└─ embassy_net::{impl#5}::apply_static_config @ /home/david/Documents/embassy/embassy-net/src/fmt.rs:138 +DEBUG IP address: 192.168.1.7/24 +└─ embassy_net::{impl#5}::apply_static_config @ /home/david/Documents/embassy/embassy-net/src/fmt.rs:138 +DEBUG Default gateway: Some(192.168.1.1) +└─ embassy_net::{impl#5}::apply_static_config @ /home/david/Documents/embassy/embassy-net/src/fmt.rs:138 +DEBUG Configured socket and connecting +└─ bed_sensors::network::send_published::{async_fn#0} @ src/network.rs:84 +WARN warning connection down, resetting if not up soon +└─ bed_sensors::network::send_published::{async_fn#0} @ src/network.rs:95 +INFO initializing sensors +└─ bed_sensors::sensors::init_then_measure::{async_fn#0} @ src/sensors.rs:51 +DEBUG address 192.168.1.43 not in neighbor cache, sending ARP request +└─ smoltcp::iface::interface::{impl#2}::lookup_hardware_addr @ /home/david/.cargo/registry/src/index.crates.io-6f17d22bba15001f/smoltcp-0.11.0/src/macros.rs:18 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG address 192.168.1.43 not in neighbor cache, sending ARP request +└─ smoltcp::iface::interface::{impl#2}::lookup_hardware_addr @ /home/david/.cargo/registry/src/index.crates.io-6f17d22bba15001f/smoltcp-0.11.0/src/macros.rs:18 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +INFO link_up = true +└─ embassy_net::{impl#5}::poll @ /home/david/Documents/embassy/embassy-net/src/fmt.rs:152 +DEBUG address 192.168.1.43 not in neighbor cache, sending ARP request +└─ smoltcp::iface::interface::{impl#2}::lookup_hardware_addr @ /home/david/.cargo/registry/src/index.crates.io-6f17d22bba15001f/smoltcp-0.11.0/src/macros.rs:18 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +INFO (re-)connected +└─ bed_sensors::network::send_published::{async_fn#0} @ src/network.rs:106 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG timeout exceeded +└─ smoltcp::socket::tcp::{impl#9}::dispatch @ /home/david/.cargo/registry/src/index.crates.io-6f17d22bba15001f/smoltcp-0.11.0/src/macros.rs:18 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +WARN write error: ConnectionReset +└─ bed_sensors::network::send_published::{async_fn#0} @ src/network.rs:114 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +INFO (re-)connected +└─ bed_sensors::network::send_published::{async_fn#0} @ src/network.rs:106 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG queueing error: Timeout(Sht31) +└─ bed_sensors::channel::{impl#0}::queue_error @ src/channel.rs:69 +DEBUG queueing error: Timeout(Mhz14) +└─ bed_sensors::channel::{impl#0}::queue_error @ src/channel.rs:69 +DEBUG queueing error: Timeout(Sps30) +└─ bed_sensors::channel::{impl#0}::queue_error @ src/channel.rs:69 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG queueing error: Timeout(Sht31) +└─ bed_sensors::channel::{impl#0}::queue_error @ src/channel.rs:69 +DEBUG queueing error: Timeout(Mhz14) +└─ bed_sensors::channel::{impl#0}::queue_error @ src/channel.rs:69 +DEBUG queueing error: Timeout(Sps30) +└─ bed_sensors::channel::{impl#0}::queue_error @ src/channel.rs:69 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG queueing error: Timeout(Sht31) +└─ bed_sensors::channel::{impl#0}::queue_error @ src/channel.rs:69 +DEBUG queueing error: Timeout(Mhz14) +└─ bed_sensors::channel::{impl#0}::queue_error @ src/channel.rs:69 +DEBUG queueing error: Timeout(Sps30) +└─ bed_sensors::channel::{impl#0}::queue_error @ src/channel.rs:69 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG queueing error: Timeout(Sht31) +└─ bed_sensors::channel::{impl#0}::queue_error @ src/channel.rs:69 +DEBUG queueing error: Timeout(Mhz14) +└─ bed_sensors::channel::{impl#0}::queue_error @ src/channel.rs:69 +DEBUG queueing error: Timeout(Sps30) +└─ bed_sensors::channel::{impl#0}::queue_error @ src/channel.rs:69 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG queueing error: Timeout(Sht31) +└─ bed_sensors::channel::{impl#0}::queue_error @ src/channel.rs:69 +DEBUG queueing error: Timeout(Mhz14) +└─ bed_sensors::channel::{impl#0}::queue_error @ src/channel.rs:69 +DEBUG queueing error: Timeout(Sps30) +└─ bed_sensors::channel::{impl#0}::queue_error @ src/channel.rs:69 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG queueing error: Timeout(Sht31) +└─ bed_sensors::channel::{impl#0}::queue_error @ src/channel.rs:69 +DEBUG queueing error: Timeout(Mhz14) +└─ bed_sensors::channel::{impl#0}::queue_error @ src/channel.rs:69 +DEBUG queueing error: Timeout(Sps30) +└─ bed_sensors::channel::{impl#0}::queue_error @ src/channel.rs:69 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG queueing error: Timeout(Sht31) +└─ bed_sensors::channel::{impl#0}::queue_error @ src/channel.rs:69 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG queueing error: Timeout(Mhz14) +└─ bed_sensors::channel::{impl#0}::queue_error @ src/channel.rs:69 +DEBUG queueing error: Timeout(Sps30) +└─ bed_sensors::channel::{impl#0}::queue_error @ src/channel.rs:69 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG queueing error: Timeout(Sht31) +└─ bed_sensors::channel::{impl#0}::queue_error @ src/channel.rs:69 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG queueing error: Timeout(Mhz14) +└─ bed_sensors::channel::{impl#0}::queue_error @ src/channel.rs:69 +DEBUG queueing error: Timeout(Sps30) +└─ bed_sensors::channel::{impl#0}::queue_error @ src/channel.rs:69 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG queueing error: Timeout(Sht31) +└─ bed_sensors::channel::{impl#0}::queue_error @ src/channel.rs:69 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG queueing error: Timeout(Mhz14) +└─ bed_sensors::channel::{impl#0}::queue_error @ src/channel.rs:69 +DEBUG queueing error: Timeout(Sps30) +└─ bed_sensors::channel::{impl#0}::queue_error @ src/channel.rs:69 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG queueing error: Timeout(Sht31) +└─ bed_sensors::channel::{impl#0}::queue_error @ src/channel.rs:69 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG queueing error: Timeout(Mhz14) +└─ bed_sensors::channel::{impl#0}::queue_error @ src/channel.rs:69 +DEBUG queueing error: Timeout(Sps30) +└─ bed_sensors::channel::{impl#0}::queue_error @ src/channel.rs:69 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG queueing error: Timeout(Sht31) +└─ bed_sensors::channel::{impl#0}::queue_error @ src/channel.rs:69 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG queueing error: Timeout(Mhz14) +└─ bed_sensors::channel::{impl#0}::queue_error @ src/channel.rs:69 +DEBUG queueing error: Timeout(Sps30) +└─ bed_sensors::channel::{impl#0}::queue_error @ src/channel.rs:69 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG queueing error: Timeout(Sht31) +└─ bed_sensors::channel::{impl#0}::queue_error @ src/channel.rs:69 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG queueing error: Timeout(Mhz14) +└─ bed_sensors::channel::{impl#0}::queue_error @ src/channel.rs:69 +DEBUG queueing error: Timeout(Sps30) +└─ bed_sensors::channel::{impl#0}::queue_error @ src/channel.rs:69 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG queueing error: Timeout(Sht31) +└─ bed_sensors::channel::{impl#0}::queue_error @ src/channel.rs:69 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG queueing error: Timeout(Mhz14) +└─ bed_sensors::channel::{impl#0}::queue_error @ src/channel.rs:69 +DEBUG queueing error: Timeout(Sps30) +└─ bed_sensors::channel::{impl#0}::queue_error @ src/channel.rs:69 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG queueing error: Timeout(Sht31) +└─ bed_sensors::channel::{impl#0}::queue_error @ src/channel.rs:69 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG queueing error: Timeout(Mhz14) +└─ bed_sensors::channel::{impl#0}::queue_error @ src/channel.rs:69 +DEBUG queueing error: Timeout(Sps30) +└─ bed_sensors::channel::{impl#0}::queue_error @ src/channel.rs:69 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG queueing error: Timeout(Sht31) +└─ bed_sensors::channel::{impl#0}::queue_error @ src/channel.rs:69 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG queueing error: Timeout(Mhz14) +└─ bed_sensors::channel::{impl#0}::queue_error @ src/channel.rs:69 +DEBUG queueing error: Timeout(Sps30) +└─ bed_sensors::channel::{impl#0}::queue_error @ src/channel.rs:69 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG queueing error: Timeout(Sht31) +└─ bed_sensors::channel::{impl#0}::queue_error @ src/channel.rs:69 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG queueing error: Timeout(Mhz14) +└─ bed_sensors::channel::{impl#0}::queue_error @ src/channel.rs:69 +DEBUG queueing error: Timeout(Sps30) +└─ bed_sensors::channel::{impl#0}::queue_error @ src/channel.rs:69 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG queueing error: Timeout(Sht31) +└─ bed_sensors::channel::{impl#0}::queue_error @ src/channel.rs:69 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG queueing error: Timeout(Mhz14) +└─ bed_sensors::channel::{impl#0}::queue_error @ src/channel.rs:69 +DEBUG queueing error: Timeout(Sps30) +└─ bed_sensors::channel::{impl#0}::queue_error @ src/channel.rs:69 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG queueing error: Timeout(Sht31) +└─ bed_sensors::channel::{impl#0}::queue_error @ src/channel.rs:69 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG queueing error: Timeout(Mhz14) +└─ bed_sensors::channel::{impl#0}::queue_error @ src/channel.rs:69 +DEBUG queueing error: Timeout(Sps30) +└─ bed_sensors::channel::{impl#0}::queue_error @ src/channel.rs:69 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG queueing error: Timeout(Sht31) +└─ bed_sensors::channel::{impl#0}::queue_error @ src/channel.rs:69 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG queueing error: Timeout(Mhz14) +└─ bed_sensors::channel::{impl#0}::queue_error @ src/channel.rs:69 +DEBUG queueing error: Timeout(Sps30) +└─ bed_sensors::channel::{impl#0}::queue_error @ src/channel.rs:69 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG queueing error: Timeout(Sht31) +└─ bed_sensors::channel::{impl#0}::queue_error @ src/channel.rs:69 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG queueing error: Timeout(Mhz14) +└─ bed_sensors::channel::{impl#0}::queue_error @ src/channel.rs:69 +DEBUG queueing error: Timeout(Sps30) +└─ bed_sensors::channel::{impl#0}::queue_error @ src/channel.rs:69 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG queueing error: Timeout(Sht31) +└─ bed_sensors::channel::{impl#0}::queue_error @ src/channel.rs:69 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG queueing error: Timeout(Mhz14) +└─ bed_sensors::channel::{impl#0}::queue_error @ src/channel.rs:69 +DEBUG queueing error: Timeout(Sps30) +└─ bed_sensors::channel::{impl#0}::queue_error @ src/channel.rs:69 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG queueing error: Timeout(Sht31) +└─ bed_sensors::channel::{impl#0}::queue_error @ src/channel.rs:69 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG queueing error: Timeout(Mhz14) +└─ bed_sensors::channel::{impl#0}::queue_error @ src/channel.rs:69 +DEBUG queueing error: Timeout(Sps30) +└─ bed_sensors::channel::{impl#0}::queue_error @ src/channel.rs:69 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG queueing error: Timeout(Sht31) +└─ bed_sensors::channel::{impl#0}::queue_error @ src/channel.rs:69 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG queueing error: Timeout(Mhz14) +└─ bed_sensors::channel::{impl#0}::queue_error @ src/channel.rs:69 +DEBUG queueing error: Timeout(Sps30) +└─ bed_sensors::channel::{impl#0}::queue_error @ src/channel.rs:69 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG queueing error: Timeout(Sht31) +└─ bed_sensors::channel::{impl#0}::queue_error @ src/channel.rs:69 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG queueing error: Timeout(Mhz14) +└─ bed_sensors::channel::{impl#0}::queue_error @ src/channel.rs:69 +DEBUG queueing error: Timeout(Sps30) +└─ bed_sensors::channel::{impl#0}::queue_error @ src/channel.rs:69 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG queueing error: Timeout(Sht31) +└─ bed_sensors::channel::{impl#0}::queue_error @ src/channel.rs:69 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG queueing error: Timeout(Mhz14) +└─ bed_sensors::channel::{impl#0}::queue_error @ src/channel.rs:69 +DEBUG queueing error: Timeout(Sps30) +└─ bed_sensors::channel::{impl#0}::queue_error @ src/channel.rs:69 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG queueing error: Timeout(Sht31) +└─ bed_sensors::channel::{impl#0}::queue_error @ src/channel.rs:69 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG queueing error: Timeout(Mhz14) +└─ bed_sensors::channel::{impl#0}::queue_error @ src/channel.rs:69 +DEBUG queueing error: Timeout(Sps30) +└─ bed_sensors::channel::{impl#0}::queue_error @ src/channel.rs:69 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG queueing error: Timeout(Sht31) +└─ bed_sensors::channel::{impl#0}::queue_error @ src/channel.rs:69 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG queueing error: Timeout(Mhz14) +└─ bed_sensors::channel::{impl#0}::queue_error @ src/channel.rs:69 +DEBUG queueing error: Timeout(Sps30) +└─ bed_sensors::channel::{impl#0}::queue_error @ src/channel.rs:69 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG queueing error: Timeout(Sht31) +└─ bed_sensors::channel::{impl#0}::queue_error @ src/channel.rs:69 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG queueing error: Timeout(Mhz14) +└─ bed_sensors::channel::{impl#0}::queue_error @ src/channel.rs:69 +DEBUG queueing error: Timeout(Sps30) +└─ bed_sensors::channel::{impl#0}::queue_error @ src/channel.rs:69 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG can now write +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:84 +DEBUG need to read +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:78 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG tick +└─ embassy_net_wiznet::{impl#1}::run::{async_fn#0} @ /home/david/Documents/embassy/embassy-net-wiznet/src/lib.rs:89 +DEBUG flash: latency=2 +└─ embassy_stm32::rcc::_version::init @ /home/david/Documents/embassy/embassy-stm32/src/fmt.rs:138 +DEBUG rcc: Clocks { hclk1: MaybeHertz(84000000), pclk1: MaybeHertz(42000000), pclk1_tim: MaybeHertz(84000000), pclk2: MaybeHertz(84000000), pclk2_tim: MaybeHertz(84000000), pll1_q: MaybeHertz(0), pllsai1_q: MaybeHertz(0), rtc: MaybeHertz(32000), sys: MaybeHertz(84000000) } +└─ embassy_stm32::rcc::set_freqs @ /home/david/Documents/embassy/embassy-stm32/src/fmt.rs:138 +INFO random seed: 14091470885172412432 +└─ bed_sensors::____embassy_main_task::{async_fn#0} @ src/main.rs:90 +DEBUG IPv4: UP +└─ embassy_net::{impl#5}::apply_static_config @ /home/david/Documents/embassy/embassy-net/src/fmt.rs:138 +DEBUG IP address: 192.168.1.7/24 +└─ embassy_net::{impl#5}::apply_static_config @ /home/david/Documents/embassy/embassy-net/src/fmt.rs:138 +DEBUG Default gateway: Some(192.168.1.1) +└─ embassy_net::{impl#5}::apply_static_config @ /home/david/Documents/embassy/embassy-net/src/fmt.rs:138 +DEBUG Configured socket and connecting +└─ bed_sensors::network::handle::{async_fn#0} @ src/network.rs:78 +INFO initializing sensors +└─ bed_sensors::sensors::init_then_measure::{async_fn#0} @ src/sensors.rs:51 +DEBUG address 192.168.1.43 not in neighbor cache, sending ARP request +└─ smoltcp::iface::interface::{impl#2}::lookup_hardware_addr @ /home/david/.cargo/registry/src/index.crates.io-6f17d22bba15001f/smoltcp-0.11.0/src/macros.rs:18 +DEBUG address 192.168.1.43 not in neighbor cache, sending ARP request +└─ smoltcp::iface::interface::{impl#2}::lookup_hardware_addr @ /home/david/.cargo/registry/src/index.crates.io-6f17d22bba15001f/smoltcp-0.11.0/src/macros.rs:18 +DEBUG address 192.168.1.43 not in neighbor cache, sending ARP request +└─ smoltcp::iface::interface::{impl#2}::lookup_hardware_addr @ /home/david/.cargo/registry/src/index.crates.io-6f17d22bba15001f/smoltcp-0.11.0/src/macros.rs:18 +INFO link_up = true +└─ embassy_net::{impl#5}::poll @ /home/david/Documents/embassy/embassy-net/src/fmt.rs:152 +DEBUG address 192.168.1.43 not in neighbor cache, sending ARP request +└─ smoltcp::iface::interface::{impl#2}::lookup_hardware_addr @ /home/david/.cargo/registry/src/index.crates.io-6f17d22bba15001f/smoltcp-0.11.0/src/macros.rs:18 +INFO (re-)connected +└─ bed_sensors::network::handle::{async_fn#0} @ src/network.rs:85 +INFO link_up = false +└─ embassy_net::{impl#5}::poll @ /home/david/Documents/embassy/embassy-net/src/fmt.rs:152 +DEBUG retransmitting at t+0.899s +└─ smoltcp::socket::tcp::{impl#9}::dispatch @ /home/david/.cargo/registry/src/index.crates.io-6f17d22bba15001f/smoltcp-0.11.0/src/macros.rs:18 +INFO link_up = true +└─ embassy_net::{impl#5}::poll @ /home/david/Documents/embassy/embassy-net/src/fmt.rs:152 +DEBUG retransmitting at t+0.899s +└─ smoltcp::socket::tcp::{impl#9}::dispatch @ /home/david/.cargo/registry/src/index.crates.io-6f17d22bba15001f/smoltcp-0.11.0/src/macros.rs:18 +DEBUG retransmitting at t+0.899s +└─ smoltcp::socket::tcp::{impl#9}::dispatch @ /home/david/.cargo/registry/src/index.crates.io-6f17d22bba15001f/smoltcp-0.11.0/src/macros.rs:18 +DEBUG retransmitting at t+1.102s +└─ smoltcp::socket::tcp::{impl#9}::dispatch @ /home/david/.cargo/registry/src/index.crates.io-6f17d22bba15001f/smoltcp-0.11.0/src/macros.rs:18 +DEBUG retransmitting at t+1.102s +└─ smoltcp::socket::tcp::{impl#9}::dispatch @ /home/david/.cargo/registry/src/index.crates.io-6f17d22bba15001f/smoltcp-0.11.0/src/macros.rs:18 +DEBUG retransmitting at t+1.102s +└─ smoltcp::socket::tcp::{impl#9}::dispatch @ /home/david/.cargo/registry/src/index.crates.io-6f17d22bba15001f/smoltcp-0.11.0/src/macros.rs:18 +DEBUG queueing error: Timeout(Sht31) +└─ bed_sensors::channel::{impl#0}::queue_error @ src/channel.rs:69 +DEBUG queueing error: Timeout(Mhz14) +└─ bed_sensors::channel::{impl#0}::queue_error @ src/channel.rs:69 +DEBUG queueing error: Timeout(Sps30) +└─ bed_sensors::channel::{impl#0}::queue_error @ src/channel.rs:69 +DEBUG retransmitting at t+1.508s +└─ smoltcp::socket::tcp::{impl#9}::dispatch @ /home/david/.cargo/registry/src/index.crates.io-6f17d22bba15001f/smoltcp-0.11.0/src/macros.rs:18 diff --git a/nodes/embassy/small-bedroom-bed/rust-toolchain.toml b/nodes/embassy/small-bedroom-bed/rust-toolchain.toml new file mode 100644 index 00000000..c17f644e --- /dev/null +++ b/nodes/embassy/small-bedroom-bed/rust-toolchain.toml @@ -0,0 +1,6 @@ +[toolchain] +channel = "stable" +components = [ "rust-src", "rustfmt", "llvm-tools" ] +targets = [ + "thumbv7em-none-eabihf", +] diff --git a/nodes/embassy/small-bedroom-bed/src/channel.rs b/nodes/embassy/small-bedroom-bed/src/channel.rs new file mode 100644 index 00000000..89385fca --- /dev/null +++ b/nodes/embassy/small-bedroom-bed/src/channel.rs @@ -0,0 +1,130 @@ +use embassy_futures::select::{self, Either}; +use embassy_sync::blocking_mutex::raw::NoopRawMutex; +use embassy_sync::channel::Channel; +use embassy_sync::mutex::Mutex; +use embassy_sync::priority_channel::{self, PriorityChannel}; +use embassy_time::{Duration, Instant}; +use heapless::HistoryBuffer; +use protocol::small_bedroom::bed::Reading; + +pub struct Queues { + sensor_queue: PriorityChannel, + error_queue: Channel, + recent_errors: Mutex>, + recent_is_since: Instant, +} + +pub enum QueueItem { + Reading(PriorityValue), + Error(sensors::Error), +} + +impl Queues { + pub fn new() -> Self { + Self { + sensor_queue: PriorityChannel::new(), + error_queue: Channel::new(), + recent_errors: Mutex::new(HistoryBuffer::new()), + recent_is_since: Instant::now(), + } + } + + pub async fn clear(&self) { + while self.sensor_queue.try_receive().is_ok() {} + self.recent_errors.lock().await.clear(); + } + + pub async fn receive(&self) -> QueueItem { + if let Ok(val) = self.sensor_queue.try_receive() { + return QueueItem::Reading(val); + } + + let race = select::select(self.sensor_queue.receive(), self.error_queue.receive()); + match race.await { + Either::First(reading) => QueueItem::Reading(reading), + Either::Second(error) => QueueItem::Error(error), + } + } + + pub async fn receive_reading(&self) -> PriorityValue { + self.sensor_queue.receive().await + } + + pub fn next_ready(&self) -> Option { + self.sensor_queue.try_receive().ok() + } + + pub fn queue_error(&self, error: sensors::Error) { + // unwrap safe: is not used in interrupts + let mut recent_errors = defmt::unwrap!(self.recent_errors.try_lock()); + if self.recent_is_since.elapsed() > Duration::from_secs(60 * 5) { + recent_errors.clear(); + } + if recent_errors.contains(&error) { + return; + } + + defmt::debug!("queueing error: {:?}", error); + let Ok(()) = self.error_queue.try_send(error.clone()) else { + return; + }; + recent_errors.write(error); + } + + pub fn send_p0(&self, value: Reading) { + use protocol::small_bedroom::Reading::Bed; + let entry = PriorityValue { + priority: 0, + value: protocol::Reading::SmallBedroom(Bed(value)), + }; + let _ignore_full = self.sensor_queue.try_send(entry); + } + pub fn send_p1(&self, value: Reading) { + use protocol::small_bedroom::Reading::Bed; + let entry = PriorityValue { + priority: 1, + value: protocol::Reading::SmallBedroom(Bed(value)), + }; + let _ignore_full = self.sensor_queue.try_send(entry); + } + + pub fn send_p2(&self, value: Reading) { + use protocol::small_bedroom::Reading::Bed; + let entry = PriorityValue { + priority: 2, + value: protocol::Reading::SmallBedroom(Bed(value)), + }; + let _ignore_full = self.sensor_queue.try_send(entry); + } +} + +/// Higher priority will be send earlier +pub struct PriorityValue { + priority: u8, + pub value: protocol::Reading, +} + +impl PriorityValue { + pub fn low_priority(&self) -> bool { + self.priority < 2 + } +} + +impl Eq for PriorityValue {} +impl PartialEq for PriorityValue { + fn eq(&self, other: &Self) -> bool { + self.priority.eq(&other.priority) + } +} + +impl PartialOrd for PriorityValue { + fn partial_cmp(&self, other: &Self) -> Option { + Some(self.priority.cmp(&other.priority)) + } +} + +impl Ord for PriorityValue { + fn cmp(&self, other: &Self) -> core::cmp::Ordering { + self.priority.cmp(&other.priority) + } +} diff --git a/nodes/embassy/small-bedroom-bed/src/comms.rs b/nodes/embassy/small-bedroom-bed/src/comms.rs new file mode 100644 index 00000000..a2a07972 --- /dev/null +++ b/nodes/embassy/small-bedroom-bed/src/comms.rs @@ -0,0 +1,199 @@ +use defmt::{unwrap, warn}; +use embassy_futures::select::{self, select}; +use embassy_time::{with_timeout, Duration, Instant}; +use heapless::HistoryBuffer; +use protocol::small_bedroom::{self, bed}; +use protocol::{affector, Affector, ErrorReport, SensorMessage}; + +use crate::channel::{PriorityValue, QueueItem, Queues}; +use crate::sensors::slow; +use usb_bridge_client::{NoSpaceInQueue, UsbHandle, UsbReceiver, UsbSender}; + +pub(crate) type SensMsg = SensorMessage<10>; +type IsLowPrio = bool; + +/// send as soon as we find a high priority message +async fn collect_pending( + publish: &Queues, + reading: PriorityValue, +) -> (IsLowPrio, SensorMessage<10>) { + let mut msg = SensMsg::default(); + let mut is_low_priority = reading.low_priority(); + unwrap!(msg.values.push(reading.value)); + + if is_low_priority { + let deadline = Instant::now() + Duration::from_millis(200); + while msg.space_left() { + let until = deadline.saturating_duration_since(Instant::now()); + match with_timeout(until, publish.receive_reading()).await { + Ok(new) if new.low_priority() => { + unwrap!(msg.values.push(new.value)); + } + Ok(new) => { + is_low_priority = false; + unwrap!(msg.values.push(new.value)); + break; + } + Err(_timeout) => break, + } + } + } else { + while msg.space_left() { + let Some(next) = publish.next_ready() else { + break; + }; + unwrap!(msg.values.push(next.value)); + } + } + (is_low_priority, msg) +} + +async fn get_messages<'a>(publish: &Queues, buf: &'a mut [u8]) -> (IsLowPrio, &'a [u8]) { + let next = publish.receive().await; + match next { + QueueItem::Reading(reading) => { + let (is_low_prio, msg) = collect_pending(publish, reading).await; + let encoded_len = msg.encode_slice(&mut buf[1..]).len(); + buf[0] = protocol::Msg::<0>::READINGS; + (is_low_prio, &buf[..=encoded_len]) + } + QueueItem::Error(error) => { + let error = protocol::small_bedroom::Error::Bed(error.into()); + let error = protocol::Error::SmallBedroom(error); + let encoded_len = ErrorReport::new(error).encode_slice(&mut buf[1..]).len(); + buf[0] = protocol::Msg::<0>::ERROR_REPORT; + (true, &buf[..=encoded_len]) + } + } +} + +pub async fn handle( + usb: UsbHandle<'_>, + publish: &Queues, + driver_orderers: &slow::DriverOrderers, +) -> ! { + const MIN_BETWEEN_COMM_ERRS: Duration = Duration::from_secs(30); + let mut last_errors_at: HistoryBuffer<_, 5> = HistoryBuffer::new(); + + loop { + publish.clear().await; + + let (writer, reader) = usb.split(); + match select( + send_messages(writer, publish), + receive_orders(reader, &driver_orderers), + ) + .await + { + select::Either::First(e) => warn!("Error while sending messages: {}", e), + select::Either::Second(e) => warn!("Error receiving orders: {}", e), + }; + + let mut error_after = Instant::now(); + if last_errors_at + .oldest_ordered() + .rev() + .copied() + .all(|error: Instant| { + let is_recent = error_after.duration_since(error) < MIN_BETWEEN_COMM_ERRS; + error_after = error; + is_recent + }) + { + defmt::error!( + "Something is terribly wrong with the connection, \ + 5 errors occured each within 30 seconds of the previous. \ + Resetting entire node" + ); + cortex_m::peripheral::SCB::sys_reset(); + } else { + last_errors_at.write(Instant::now()); + } + } +} + +const AFFECTOR_LIST_MAX_SIZE: usize = protocol::Msg::<5>::max_size(); +pub fn affector_list() -> heapless::Vec { + let mut list = affector::ListMessage::<5>::empty(); + unwrap!( + list.values.push(Affector::SmallBedroom( + protocol::small_bedroom::Affector::Bed(bed::Affector::Sps30FanClean), + )), + "list is long enough" + ); + unwrap!( + list.values.push(Affector::SmallBedroom( + protocol::small_bedroom::Affector::Bed(bed::Affector::MhzZeroPointCalib), + )), + "list is long enough" + ); + unwrap!( + list.values.push(Affector::SmallBedroom( + protocol::small_bedroom::Affector::Bed(bed::Affector::Nau7802Calib), + )), + "list is long enough" + ); + unwrap!( + list.values.push(Affector::SmallBedroom( + protocol::small_bedroom::Affector::Bed(bed::Affector::ResetNode), + )), + "list is long enough" + ); + + let mut buf = heapless::Vec::new(); + defmt::unwrap!(buf.resize_default(AFFECTOR_LIST_MAX_SIZE)); + let encoded_len = list.encode_slice(&mut buf).len(); + buf.truncate(encoded_len); + buf +} + +async fn send_messages(usb: UsbSender<'_>, publish: &Queues) { + let mut buf = [0; protocol::Msg::<5>::max_size()]; + loop { + let (is_low_prio, to_send) = get_messages(publish, &mut buf).await; + while let Err(NoSpaceInQueue) = usb.send(to_send, is_low_prio).await { + if is_low_prio { + defmt::trace!("dropping low priority package because queue is full"); + break; + } else { + usb.wait_till_queue_free().await; + } + } + } +} + +async fn receive_orders(usb: UsbReceiver<'_>, driver_orderers: &slow::DriverOrderers) { + defmt::debug!("ready to receive orders"); + loop { + let mut read = usb.recv().await; + let item = match affector::Affector::decode(&mut read) { + Ok(item) => item, + Err(e) => { + defmt::error!("Could not decode affector: {}", e); + continue; + } + }; + let Affector::SmallBedroom(small_bedroom::Affector::Bed(affector)) = item else { + defmt::error!("Got affector for other node"); + continue; + }; + + defmt::info!("got affector order: {:?}", affector); + match affector { + bed::Affector::Nau7802Calib => { + defmt::warn!("unimplemented affector: {:?}", affector) + } + bed::Affector::MhzZeroPointCalib => { + driver_orderers.mhz.send(()).await; + } + bed::Affector::Sps30FanClean => { + driver_orderers.sps.send(()).await; + } + bed::Affector::ResetNode => { + defmt::info!("resetting node as orderd via affector"); + defmt::flush(); + cortex_m::peripheral::SCB::sys_reset(); + } + } + } +} diff --git a/nodes/embassy/small-bedroom-bed/src/main.rs b/nodes/embassy/small-bedroom-bed/src/main.rs new file mode 100644 index 00000000..37e90401 --- /dev/null +++ b/nodes/embassy/small-bedroom-bed/src/main.rs @@ -0,0 +1,212 @@ +#![no_std] +#![no_main] + +use core::time::Duration; + +use embassy_executor::Spawner; +use embassy_futures::select::{self, Either4}; +use embassy_stm32::exti::ExtiInput; +use embassy_stm32::gpio::Pull; +use embassy_stm32::i2c::{self, I2c}; +use embassy_stm32::peripherals::IWDG; +use embassy_stm32::time::Hertz; +use embassy_stm32::usart::{self, DataBits, Parity, StopBits, Uart}; +use embassy_stm32::wdg::IndependentWatchdog; +use embassy_stm32::{usb, Config}; +use embassy_sync::blocking_mutex::raw::NoopRawMutex; +use embassy_sync::mutex::Mutex; +use embassy_time::Timer; +use futures::pin_mut; +use sensors::fast::ButtonInputs; +use sensors::slow; + +use defmt::{error, trace, unwrap}; +use {defmt_rtt as _, panic_probe as _}; + +mod channel; +mod comms; +mod sensors; +use crate::channel::Queues; + +embassy_stm32::bind_interrupts!(struct Irqs { + I2C1_EV => embassy_stm32::i2c::EventInterruptHandler; + I2C1_ER => embassy_stm32::i2c::ErrorInterruptHandler; + I2C3_EV => embassy_stm32::i2c::EventInterruptHandler; + I2C3_ER => embassy_stm32::i2c::ErrorInterruptHandler; + USART1 => embassy_stm32::usart::InterruptHandler; + USART2 => embassy_stm32::usart::InterruptHandler; + OTG_FS => embassy_stm32::usb::InterruptHandler; +}); + +// 84 Mhz clock stm32f401 +// 48 Mhz clock for usb +fn config() -> Config { + use embassy_stm32::rcc::mux; + use embassy_stm32::rcc::{ + AHBPrescaler, APBPrescaler, Hse, HseMode, Pll, PllMul, PllPDiv, + PllPreDiv, PllQDiv, PllSource, Sysclk, + }; + + let mut config = Config::default(); + config.rcc.hse = Some(Hse { + freq: Hertz(25_000_000), + mode: HseMode::Oscillator, + }); + config.rcc.pll_src = PllSource::HSE; + config.rcc.pll = Some(Pll { + prediv: PllPreDiv::DIV25, + mul: PllMul::MUL336, + divp: Some(PllPDiv::DIV4), // 25mhz / 25 * 336 / 4 = 84Mhz. + divq: Some(PllQDiv::DIV7), // 25mhz / 25 * 336 / 7 = 48Mhz. + divr: None, + }); + config.rcc.ahb_pre = AHBPrescaler::DIV1; + config.rcc.apb1_pre = APBPrescaler::DIV2; + config.rcc.apb2_pre = APBPrescaler::DIV1; + config.rcc.sys = Sysclk::PLL1_P; + config.rcc.mux.clk48sel = mux::Clk48sel::PLL1_Q; + config +} + +#[embassy_executor::main] +async fn main(_spawner: Spawner) { + let p = embassy_stm32::init(config()); + let dog = IndependentWatchdog::new( + p.IWDG, + Duration::from_secs(5).as_micros() as u32, + ); + + let mut usart_config = usart::Config::default(); + usart_config.baudrate = 9600; + usart_config.data_bits = DataBits::DataBits8; + usart_config.stop_bits = StopBits::STOP1; + let usart_mhz = unwrap!(Uart::new( + p.USART1, + p.PB7, + p.PB6, + Irqs, + p.DMA2_CH7, + p.DMA2_CH2, + usart_config, + )); + + let mut usart_config = usart::Config::default(); + usart_config.baudrate = 115_200; // sps30 only works at this baud + usart_config.data_bits = DataBits::DataBits8; + usart_config.stop_bits = StopBits::STOP1; + usart_config.parity = Parity::ParityNone; + let usart_sps30 = unwrap!(Uart::new( + p.USART2, + p.PA3, + p.PA2, + Irqs, + p.DMA1_CH6, + p.DMA1_CH5, + usart_config, + )); + + let i2c_1 = I2c::new( + p.I2C1, + p.PB8, + p.PB9, + Irqs, + p.DMA1_CH7, + p.DMA1_CH0, + Hertz(150_000), + i2c::Config::default(), + ); + let i2c_1: Mutex = Mutex::new(i2c_1); + + let i2c_3 = I2c::new( + p.I2C3, + p.PA8, + p.PB4, + Irqs, + p.DMA1_CH4, + p.DMA1_CH1, + // Extra slow, helps with longer cable runs + Hertz(150_000), + i2c::Config::default(), + ); + let i2c_3: Mutex = Mutex::new(i2c_3); + + let buttons = ButtonInputs { + left: ExtiInput::new(p.PC14, p.EXTI14, Pull::Down), + left_middle: ExtiInput::new(p.PA9, p.EXTI9, Pull::Down), + right_middle: ExtiInput::new(p.PC13, p.EXTI13, Pull::Down), + right: ExtiInput::new(p.PA10, p.EXTI10, Pull::Down), + }; + + let mut usb_driver_config = embassy_stm32::usb::Config::default(); + // Do not enable vbus_detection. This is a safe default that works in all + // boards. However, if your USB device is self-powered (can stay powered on + // if USB is unplugged), you need to enable vbus_detection to comply with + // the USB spec. If you enable it, the board + usb_driver_config.vbus_detection = false; + + let mut ep_out_buffer = [0u8; 256]; + let usb_driver = usb::Driver::new_fs( + p.USB_OTG_FS, + Irqs, + p.PA12, + p.PA11, + &mut ep_out_buffer, + usb_driver_config, + ); + + let affector_list = comms::affector_list(); + let stack_a = usb_bridge_client::StackA::new(); + let mut stack_b = usb_bridge_client::StackB::new(&stack_a, &affector_list); + let (mut usb_bus, usb_handle) = usb_bridge_client::new( + &stack_a, + &mut stack_b, + usb_bridge_client::config!("small-bedroom-bed", "2478437"), + usb_driver, + ); + + let driver_orderers = slow::DriverOrderers::new(); + let publish = Queues::new(); + let handle_network = comms::handle(usb_handle, &publish, &driver_orderers); + pin_mut!(handle_network); + + let init_then_measure = sensors::init_then_measure( + &publish, + &driver_orderers, + i2c_1, + i2c_3, + usart_mhz, + usart_sps30, + buttons, + ); + + let res = select::select4( + &mut handle_network, + init_then_measure, + usb_bus.run(), + keep_dog_happy(dog), + ) + .await; + + let unrecoverable_err = match res { + Either4::First(_) + | Either4::Second(Ok(())) + | Either4::Third(()) + | Either4::Fourth(_) => { + defmt::unreachable!() + } + Either4::Second(Err(err)) => err, + }; + + // at this point no other errors have occurred + error!("unrecoverable error, resetting: {}", unrecoverable_err); + publish.queue_error(unrecoverable_err); + handle_network.await; // if this takes too long the dog will get us +} + +async fn keep_dog_happy(mut dog: IndependentWatchdog<'_, IWDG>) -> ! { + loop { + Timer::after_secs(1).await; + trace!("petting dog"); + dog.pet(); + } +} diff --git a/nodes/embassy/small-bedroom-bed/src/sensors.rs b/nodes/embassy/small-bedroom-bed/src/sensors.rs new file mode 100644 index 00000000..85d5d80d --- /dev/null +++ b/nodes/embassy/small-bedroom-bed/src/sensors.rs @@ -0,0 +1,60 @@ +use defmt::info; +use embassy_futures::join; +use embassy_stm32::i2c::I2c; +use embassy_stm32::mode::Async; +use embassy_stm32::usart::Uart; +use embassy_sync::blocking_mutex::raw::NoopRawMutex; +use embassy_sync::mutex::Mutex; +use fast::ButtonInputs; +use protocol::small_bedroom::bed::Device; + +use crate::channel::Queues; +use sensors::{Error, SPS30_UART_BUF_SIZE}; +pub mod fast; +pub mod slow; + +use sensors::{ + Bme680Driver, Max44Driver, Nau7802Driver, Sht31Driver, Sps30Driver, MhzDriver +}; + +fn local_dev(dev: protocol::small_bedroom::bed::Device) -> protocol::Device { + protocol::Device::SmallBedroom(protocol::small_bedroom::Device::Bed(dev)) +} + +pub async fn init_then_measure( + publish: &Queues, + orderers: &slow::DriverOrderers, + i2c_1: Mutex>, + i2c_3: Mutex>, + usart_mhz: Uart<'static, Async>, + usart_sps: Uart<'static, Async>, + buttons: ButtonInputs, +) -> Result<(), Error> { + info!("initializing sensors"); + let bme = Bme680Driver::new(&i2c_3, local_dev(Device::Bme680)); + let max44009 = Max44Driver::new(&i2c_1, local_dev(Device::Max44)); + let sht = Sht31Driver::new(&i2c_1, local_dev(Device::Sht31)); + let nau = Nau7802Driver::new(&i2c_3, local_dev(Device::Nau7802)); + + let (tx, rx) = usart_mhz.split(); + let mut usart_buf = [0u8; 9 * 10]; // 9 byte messages + let rx = rx.into_ring_buffered(&mut usart_buf); + let mhz = MhzDriver::new(tx, rx, local_dev(Device::Mhz14)); + + let (tx, rx) = usart_sps.split(); + let mut usart_buf = [0u8; SPS30_UART_BUF_SIZE]; + let rx = rx.into_ring_buffered(&mut usart_buf); + let sps30 = Sps30Driver::init(tx, rx, local_dev(Device::Sps30)); + + let sensors_fast = fast::read(max44009, nau, buttons, publish); + let drivers = slow::Drivers { + sht, + bme, + mhz, + sps: sps30, + }; + let sensors_slow = slow::read(drivers, orderers, publish); + join::join(sensors_fast, sensors_slow).await; + + defmt::unreachable!(); +} diff --git a/nodes/embassy/small-bedroom-bed/src/sensors/fast.rs b/nodes/embassy/small-bedroom-bed/src/sensors/fast.rs new file mode 100644 index 00000000..fcc0c012 --- /dev/null +++ b/nodes/embassy/small-bedroom-bed/src/sensors/fast.rs @@ -0,0 +1,164 @@ +use embassy_futures::join::join4; +use embassy_futures::{join, yield_now}; +use embassy_stm32::exti::ExtiInput; +use embassy_time::{Duration, Instant, Timer}; + +use protocol::small_bedroom::{bed::Button, bed::Reading}; + +use crate::channel::Queues; +use sensors::{Max44Driver, Nau7802Driver}; + +fn sig_lux_diff(old: f32, new: f32) -> bool { + let diff = old - new; + // we do not have f32::abs on embedded + diff > old / 20.0 || -diff > old / 20.0 +} + +fn sig_weight_diff(old: u32, new: u32) -> bool { + let diff = new.abs_diff(old); + diff > 2000 +} + +async fn report_lux(mut max44: Max44Driver<'_>, publish: &Queues) { + const MAX_INTERVAL: Duration = Duration::from_secs(5); + + let mut prev_lux = f32::MAX; + let mut last_lux = Instant::now(); + + loop { + Timer::after_millis(50).await; + let lux = match max44.try_measure().await { + Ok(lux) => lux, + Err(err) if last_lux.elapsed() > MAX_INTERVAL => { + publish.queue_error(err); + continue; + } + Err(_) => continue, + }; + + if sig_lux_diff(prev_lux, lux) { + publish.send_p2(Reading::Brightness(lux)); + } else if last_lux.elapsed() > MAX_INTERVAL { + publish.send_p1(Reading::Brightness(lux)); + } else { + yield_now().await; + continue; + }; + + prev_lux = lux; + last_lux = Instant::now(); + } +} + +trait Nau { + async fn try_measure(&mut self) -> Result; +} + +impl Nau for Nau7802Driver<'_> { + async fn try_measure(&mut self) -> Result { + Nau7802Driver::try_measure(self).await + } +} + +async fn report_weight( + mut nau: impl Nau, + wrap: impl Fn(u32) -> Reading, + publish: &Queues, +) { + const MAX_INTERVAL: Duration = Duration::from_secs(5); + + let mut prev_weight = u32::MAX; + let mut reported_at = Instant::now(); + + loop { + Timer::after_millis(100).await; + let weight = match nau.try_measure().await { + Ok(lux) => lux, + Err(err) if reported_at.elapsed() > MAX_INTERVAL => { + publish.queue_error(err); + continue; + } + Err(_) => continue, + }; + + if sig_weight_diff(prev_weight, weight) { + publish.send_p2(wrap(weight)); + } else if reported_at.elapsed() > MAX_INTERVAL { + publish.send_p1(wrap(weight)); + } else { + yield_now().await; + continue; + }; + + prev_weight = weight; + reported_at = Instant::now(); + } +} + +async fn watch_button( + mut input: ExtiInput<'static>, + event: impl Fn(protocol::button::Press) -> Button, + channel: &Queues, +) { + use sensors::{errors::PressTooLong, errors::SensorError, Error}; + + let mut went_high_at: Option = None; + loop { + if let Some(went_high_at) = went_high_at.take() { + input.wait_for_low().await; + let press = went_high_at.elapsed(); + let Ok(press) = press.as_millis().try_into() else { + let event_for_printing = (event)(protocol::button::Press(0)); + let name = event_for_printing.variant_name(); + channel.queue_error(Error::Running(SensorError::Button( + PressTooLong { button: name }, + ))); + continue; + }; + let event = (event)(protocol::button::Press(press)); + channel.send_p2(Reading::Button(event)); + } else { + input.wait_for_high().await; + Timer::after(Duration::from_millis(20)).await; + if input.is_low() { + continue; + } + Timer::after(Duration::from_millis(20)).await; + if input.is_low() { + continue; + } + Timer::after(Duration::from_millis(10)).await; + if input.is_high() { + went_high_at = Some(Instant::now()); + } + } + } +} + +pub struct ButtonInputs { + pub left: ExtiInput<'static>, + pub left_middle: ExtiInput<'static>, + pub right_middle: ExtiInput<'static>, + pub right: ExtiInput<'static>, +} + +pub(crate) async fn read( + max44: Max44Driver<'_>, + nau: Nau7802Driver<'_>, + inputs: ButtonInputs, + publish: &Queues, +) { + use protocol::small_bedroom::bed::Button; + + let watch_buttons = join4( + watch_button(inputs.left, Button::Left, publish), + watch_button(inputs.left_middle, Button::LeftMiddle, publish), + watch_button(inputs.right_middle, Button::RightMiddle, publish), + watch_button(inputs.right, Button::Right, publish), + ); + + let watch_lux = report_lux(max44, publish); + let report_weight = report_weight(nau, Reading::Weight, publish); + + join::join3(report_weight, watch_lux, watch_buttons).await; +} diff --git a/nodes/embassy/small-bedroom-bed/src/sensors/slow.rs b/nodes/embassy/small-bedroom-bed/src/sensors/slow.rs new file mode 100644 index 00000000..f1d1a973 --- /dev/null +++ b/nodes/embassy/small-bedroom-bed/src/sensors/slow.rs @@ -0,0 +1,205 @@ +use defmt::unwrap; +use embassy_futures::join::join5; +use embassy_futures::select; +use embassy_sync::blocking_mutex::raw::NoopRawMutex; +use embassy_sync::channel::Channel; +use embassy_time::Timer; +use embassy_time::{with_timeout, Duration}; + +use protocol::small_bedroom::bed::Reading; + +use crate::channel::Queues; +use sensors::measurements; +use sensors::{Bme680Driver, Driver, Sht31Driver, Sps30Driver}; +use sensors::{Error, MhzDriver}; + +type Signal = embassy_sync::signal::Signal; + +/// Measure when signal is received or control the device's +/// affector when it is ordered +#[inline(always)] +async fn measure_and_control( + mut driver: D, + order: &Channel, + send: F, + signal: &Signal, +) where + D: Driver, + F: Fn(Result) -> (), +{ + let timeout = Duration::from_secs(15); + loop { + match select::select(signal.wait(), order.receive()).await { + select::Either::First(_) => { + let try_measure = Driver::try_measure(&mut driver); + let res = match with_timeout(timeout, try_measure).await { + Ok(res) => res, + Err(_) => Err(Error::Timeout(driver.device())), + }; + send(res); + } + select::Either::Second(order) => { + let affect = Driver::affect(&mut driver, order); + let res = match with_timeout(timeout, affect).await { + Ok(Ok(_)) => continue, + Ok(Err(e)) => Err(e), + Err(_) => Err(Error::Timeout(driver.device())), + }; + send(res); + } + } + } +} + +async fn order_measurements_every_period(signals: &[Signal]) { + loop { + for signal in signals { + signal.signal(()); + } + Timer::after_secs(5).await; + } +} + +pub(crate) struct Drivers<'a> { + pub sht: Sht31Driver<'a>, + pub bme: Bme680Driver<'a>, + pub mhz: MhzDriver<'a>, + pub sps: Sps30Driver<'a>, +} + +pub(crate) struct DriverOrderers { + pub sht: Channel, + pub bme: Channel, + pub mhz: Channel, + pub sps: Channel, +} +impl DriverOrderers { + pub(crate) fn new() -> Self { + Self { + sht: Channel::new(), + bme: Channel::new(), + mhz: Channel::new(), + sps: Channel::new(), + } + } +} + +#[inline(always)] +pub async fn read( + drivers: Drivers<'_>, + orderers: &DriverOrderers, + publish: &'_ Queues, +) { + let signals = [const { Signal::new() }; 4]; + + join5( + order_measurements_every_period(&signals), + measure_and_control( + drivers.sht, + &orderers.sht, + |res| publish_sht_result(res, &publish), + &signals[0], + ), + measure_and_control( + drivers.bme, + &orderers.bme, + |res| publish_bme_result(res, &publish), + &signals[1], + ), + measure_and_control( + drivers.mhz, + &orderers.mhz, + |res| publish_mhz_result(res, &publish), + &signals[2], + ), + measure_and_control( + drivers.sps, + &orderers.sps, + |res| publish_sps_result(res, &publish), + &signals[3], + ), + ) + .await; +} + +fn publish_sps_result( + sps_res: Result, + publish: &Queues, +) { + match sps_res { + Ok(measurements::Sps30 { + mass_pm1_0, + mass_pm2_5, + mass_pm4_0, + mass_pm10, + number_pm0_5, + number_pm1_0, + number_pm2_5, + number_pm4_0, + number_pm10, + typical_particle_size, + .. + }) => { + publish.send_p0(Reading::MassPm1_0(mass_pm1_0)); + publish.send_p0(Reading::MassPm2_5(mass_pm2_5)); + publish.send_p0(Reading::MassPm4_0(mass_pm4_0)); + publish.send_p0(Reading::MassPm10(mass_pm10)); + publish.send_p0(Reading::NumberPm0_5(number_pm0_5)); + publish.send_p0(Reading::NumberPm1_0(number_pm1_0)); + publish.send_p0(Reading::NumberPm2_5(number_pm2_5)); + publish.send_p0(Reading::NumberPm4_0(number_pm4_0)); + publish.send_p0(Reading::NumberPm10(number_pm10)); + publish + .send_p0(Reading::TypicalParticleSize(typical_particle_size)); + } + Err(err) => publish.queue_error(err), + } +} + +fn publish_mhz_result( + mhz_res: Result, + publish: &Queues, +) { + match mhz_res { + Ok(measurements::Mhz { co2, .. }) => { + publish.send_p0(Reading::Co2(co2)); + } + Err(err) => { + publish.queue_error(err); + } + } +} + +fn publish_sht_result( + sht_res: Result, + publish: &Queues, +) { + match sht_res { + Ok(measurements::Sht31 { + temperature, + humidity, + }) => { + publish.send_p0(Reading::Temperature(temperature)); + publish.send_p0(Reading::Humidity(humidity)); + } + Err(err) => publish.queue_error(err), + } +} + +fn publish_bme_result( + bme_res: Result, + publish: &Queues, +) { + match bme_res { + Ok(measurements::Bme { + pressure, + gas_resistance, + .. + }) => { + let gas_resistance = unwrap!(gas_resistance); // sensor is on + publish.send_p0(Reading::GassResistance(gas_resistance)); + publish.send_p0(Reading::Pressure(pressure)); + } + Err(err) => publish.queue_error(err), + } +} diff --git a/nodes/embassy/small-bedroom-bed/stm32f401.svd b/nodes/embassy/small-bedroom-bed/stm32f401.svd new file mode 100644 index 00000000..b9353d01 --- /dev/null +++ b/nodes/embassy/small-bedroom-bed/stm32f401.svd @@ -0,0 +1,35196 @@ + + + STM32F401 + 1.1 + STM32F401 + + CM4 + r1p0 + little + false + false + 4 + false + + 8 + 32 + 0x20 + 0x00000000 + 0xFFFFFFFF + + + ADC_Common + ADC common registers + ADC_Common + 0x40012300 + + 0x0 + 0x9 + registers + + + FPU + FPU interrupt + 81 + + + + CCR + CCR + ADC common control register + 0x4 + 0x20 + read-write + 0x00000000 + + + TSVREFE + Temperature sensor and VREFINT + enable + 23 + 1 + + TSVREFE + read-write + + Disabled + Temperature sensor and V_REFINT channel disabled + 0 + + + Enabled + Temperature sensor and V_REFINT channel enabled + 1 + + + + + VBATE + VBAT enable + 22 + 1 + + VBATE + read-write + + Disabled + V_BAT channel disabled + 0 + + + Enabled + V_BAT channel enabled + 1 + + + + + ADCPRE + ADC prescaler + 16 + 2 + + ADCPRE + read-write + + Div2 + PCLK2 divided by 2 + 0 + + + Div4 + PCLK2 divided by 4 + 1 + + + Div6 + PCLK2 divided by 6 + 2 + + + Div8 + PCLK2 divided by 8 + 3 + + + + + + + + + ADC1 + Analog-to-digital converter + ADC + 0x40012000 + + 0x0 + 0x51 + registers + + + ADC + ADC1 global interrupt + 18 + + + + SR + SR + status register + 0x0 + 0x20 + read-write + 0x00000000 + + + OVR + Overrun + 5 + 1 + zeroToClear + + OVRR + read + + NoOverrun + No overrun occurred + 0 + + + Overrun + Overrun occurred + 1 + + + + OVRW + write + + Clear + Clear flag + 0 + + + + + STRT + Regular channel start flag + 4 + 1 + zeroToClear + + STRTR + read + + NotStarted + No regular channel conversion started + 0 + + + Started + Regular channel conversion has started + 1 + + + + STRTW + write + + Clear + Clear flag + 0 + + + + + JSTRT + Injected channel start + flag + 3 + 1 + zeroToClear + + JSTRTR + read + + NotStarted + No injected channel conversion started + 0 + + + Started + Injected channel conversion has started + 1 + + + + JSTRTW + write + + Clear + Clear flag + 0 + + + + + JEOC + Injected channel end of + conversion + 2 + 1 + zeroToClear + + JEOCR + read + + NotComplete + Conversion is not complete + 0 + + + Complete + Conversion complete + 1 + + + + JEOCW + write + + Clear + Clear flag + 0 + + + + + EOC + Regular channel end of + conversion + 1 + 1 + zeroToClear + + EOCR + read + + NotComplete + Conversion is not complete + 0 + + + Complete + Conversion complete + 1 + + + + EOCW + write + + Clear + Clear flag + 0 + + + + + AWD + Analog watchdog flag + 0 + 1 + zeroToClear + + AWDR + read + + NoEvent + No analog watchdog event occurred + 0 + + + Event + Analog watchdog event occurred + 1 + + + + AWDW + write + + Clear + Clear flag + 0 + + + + + + + CR1 + CR1 + control register 1 + 0x4 + 0x20 + read-write + 0x00000000 + + + OVRIE + Overrun interrupt enable + 26 + 1 + + OVRIE + read-write + + Disabled + Overrun interrupt disabled + 0 + + + Enabled + Overrun interrupt enabled + 1 + + + + + RES + Resolution + 24 + 2 + + RES + read-write + + TwelveBit + 12-bit (15 ADCCLK cycles) + 0 + + + TenBit + 10-bit (13 ADCCLK cycles) + 1 + + + EightBit + 8-bit (11 ADCCLK cycles) + 2 + + + SixBit + 6-bit (9 ADCCLK cycles) + 3 + + + + + AWDEN + Analog watchdog enable on regular + channels + 23 + 1 + + AWDEN + read-write + + Disabled + Analog watchdog disabled on regular channels + 0 + + + Enabled + Analog watchdog enabled on regular channels + 1 + + + + + JAWDEN + Analog watchdog enable on injected + channels + 22 + 1 + + JAWDEN + read-write + + Disabled + Analog watchdog disabled on injected channels + 0 + + + Enabled + Analog watchdog enabled on injected channels + 1 + + + + + DISCNUM + Discontinuous mode channel + count + 13 + 3 + + + 0 + 7 + + + + + JDISCEN + Discontinuous mode on injected + channels + 12 + 1 + + JDISCEN + read-write + + Disabled + Discontinuous mode on injected channels disabled + 0 + + + Enabled + Discontinuous mode on injected channels enabled + 1 + + + + + DISCEN + Discontinuous mode on regular + channels + 11 + 1 + + DISCEN + read-write + + Disabled + Discontinuous mode on regular channels disabled + 0 + + + Enabled + Discontinuous mode on regular channels enabled + 1 + + + + + JAUTO + Automatic injected group + conversion + 10 + 1 + + JAUTO + read-write + + Disabled + Automatic injected group conversion disabled + 0 + + + Enabled + Automatic injected group conversion enabled + 1 + + + + + AWDSGL + Enable the watchdog on a single channel + in scan mode + 9 + 1 + + AWDSGL + read-write + + AllChannels + Analog watchdog enabled on all channels + 0 + + + SingleChannel + Analog watchdog enabled on a single channel + 1 + + + + + SCAN + Scan mode + 8 + 1 + + SCAN + read-write + + Disabled + Scan mode disabled + 0 + + + Enabled + Scan mode enabled + 1 + + + + + JEOCIE + Interrupt enable for injected + channels + 7 + 1 + + JEOCIE + read-write + + Disabled + JEOC interrupt disabled + 0 + + + Enabled + JEOC interrupt enabled + 1 + + + + + AWDIE + Analog watchdog interrupt + enable + 6 + 1 + + AWDIE + read-write + + Disabled + Analogue watchdog interrupt disabled + 0 + + + Enabled + Analogue watchdog interrupt enabled + 1 + + + + + EOCIE + Interrupt enable for EOC + 5 + 1 + + EOCIE + read-write + + Disabled + EOC interrupt disabled + 0 + + + Enabled + EOC interrupt enabled + 1 + + + + + AWDCH + Analog watchdog channel select + bits + 0 + 5 + + + 0 + 18 + + + + + + + CR2 + CR2 + control register 2 + 0x8 + 0x20 + read-write + 0x00000000 + + + SWSTART + Start conversion of regular + channels + 30 + 1 + + SWSTARTW + write + + Start + Starts conversion of regular channels + 1 + + + + + EXTEN + External trigger enable for regular + channels + 28 + 2 + + EXTEN + read-write + + Disabled + Trigger detection disabled + 0 + + + RisingEdge + Trigger detection on the rising edge + 1 + + + FallingEdge + Trigger detection on the falling edge + 2 + + + BothEdges + Trigger detection on both the rising and falling edges + 3 + + + + + EXTSEL + External event select for regular + group + 24 + 4 + + EXTSEL + read-write + + TIM1CC1 + Timer 1 CC1 event + 0 + + + TIM1CC2 + Timer 1 CC2 event + 1 + + + TIM1CC3 + Timer 1 CC3 event + 2 + + + TIM2CC2 + Timer 2 CC2 event + 3 + + + TIM2CC3 + Timer 2 CC3 event + 4 + + + TIM2CC4 + Timer 2 CC4 event + 5 + + + TIM2TRGO + Timer 2 TRGO event + 6 + + + TIM3CC1 + Timer 3 CC1 event + 7 + + + TIM3TRGO + Timer 3 TRGO event + 8 + + + TIM4CC4 + Timer 4 CC4 event + 9 + + + TIM5CC1 + Timer 5 CC1 event + 10 + + + TIM5CC2 + Timer 5 CC2 event + 11 + + + TIM5CC3 + Timer 5 CC3 event + 12 + + + EXTI11 + EXTI line 11 + 15 + + + + + JSWSTART + Start conversion of injected + channels + 22 + 1 + + JSWSTARTW + write + + Start + Starts conversion of injected channels + 1 + + + + + JEXTEN + External trigger enable for injected + channels + 20 + 2 + + JEXTEN + read-write + + Disabled + Trigger detection disabled + 0 + + + RisingEdge + Trigger detection on the rising edge + 1 + + + FallingEdge + Trigger detection on the falling edge + 2 + + + BothEdges + Trigger detection on both the rising and falling edges + 3 + + + + + JEXTSEL + External event select for injected + group + 16 + 4 + + JEXTSEL + read-write + + TIM1CC4 + Timer 1 CC4 event + 0 + + + TIM1TRGO + Timer 1 TRGO event + 1 + + + TIM2CC1 + Timer 2 CC1 event + 2 + + + TIM2TRGO + Timer 2 TRGO event + 3 + + + TIM3CC2 + Timer 3 CC2 event + 4 + + + TIM3CC4 + Timer 3 CC4 event + 5 + + + TIM4CC1 + Timer 4 CC1 event + 6 + + + TIM4CC2 + Timer 4 CC2 event + 7 + + + TIM4CC3 + Timer 4 CC3 event + 8 + + + TIM4TRGO + Timer 4 TRGO event + 9 + + + TIM5CC4 + Timer 5 CC4 event + 10 + + + TIM5TRGO + Timer 5 TRGO event + 11 + + + EXTI15 + EXTI line 15 + 15 + + + + + ALIGN + Data alignment + 11 + 1 + + ALIGN + read-write + + Right + Right alignment + 0 + + + Left + Left alignment + 1 + + + + + EOCS + End of conversion + selection + 10 + 1 + + EOCS + read-write + + EachSequence + The EOC bit is set at the end of each sequence of regular conversions + 0 + + + EachConversion + The EOC bit is set at the end of each regular conversion + 1 + + + + + DDS + DMA disable selection (for single ADC + mode) + 9 + 1 + + DDS + read-write + + Single + No new DMA request is issued after the last transfer + 0 + + + Continuous + DMA requests are issued as long as data are converted and DMA=1 + 1 + + + + + DMA + Direct memory access mode (for single + ADC mode) + 8 + 1 + + DMA + read-write + + Disabled + DMA mode disabled + 0 + + + Enabled + DMA mode enabled + 1 + + + + + CONT + Continuous conversion + 1 + 1 + + CONT + read-write + + Single + Single conversion mode + 0 + + + Continuous + Continuous conversion mode + 1 + + + + + ADON + A/D Converter ON / OFF + 0 + 1 + + ADON + read-write + + Disabled + Disable ADC conversion and go to power down mode + 0 + + + Enabled + Enable ADC + 1 + + + + + + + SMPR1 + SMPR1 + sample time register 1 + 0xC + 0x20 + read-write + 0x00000000 + + + SMP18 + Channel 18 sampling time selection + 24 + 3 + + + + SMP17 + Channel 17 sampling time selection + 21 + 3 + + + + SMP16 + Channel 16 sampling time selection + 18 + 3 + + + + SMP15 + Channel 15 sampling time selection + 15 + 3 + + + + SMP14 + Channel 14 sampling time selection + 12 + 3 + + + + SMP13 + Channel 13 sampling time selection + 9 + 3 + + + + SMP12 + Channel 12 sampling time selection + 6 + 3 + + + + SMP11 + Channel 11 sampling time selection + 3 + 3 + + + + SMP10 + Channel 10 sampling time selection + 0 + 3 + + SMP10 + read-write + + Cycles3 + 3 cycles + 0 + + + Cycles15 + 15 cycles + 1 + + + Cycles28 + 28 cycles + 2 + + + Cycles56 + 56 cycles + 3 + + + Cycles84 + 84 cycles + 4 + + + Cycles112 + 112 cycles + 5 + + + Cycles144 + 144 cycles + 6 + + + Cycles480 + 480 cycles + 7 + + + + + + + SMPR2 + SMPR2 + sample time register 2 + 0x10 + 0x20 + read-write + 0x00000000 + + + SMP9 + Channel 9 sampling time selection + 27 + 3 + + + + SMP8 + Channel 8 sampling time selection + 24 + 3 + + + + SMP7 + Channel 7 sampling time selection + 21 + 3 + + + + SMP6 + Channel 6 sampling time selection + 18 + 3 + + + + SMP5 + Channel 5 sampling time selection + 15 + 3 + + + + SMP4 + Channel 4 sampling time selection + 12 + 3 + + + + SMP3 + Channel 3 sampling time selection + 9 + 3 + + + + SMP2 + Channel 2 sampling time selection + 6 + 3 + + + + SMP1 + Channel 1 sampling time selection + 3 + 3 + + + + SMP0 + Channel 0 sampling time selection + 0 + 3 + + SMP0 + read-write + + Cycles3 + 3 cycles + 0 + + + Cycles15 + 15 cycles + 1 + + + Cycles28 + 28 cycles + 2 + + + Cycles56 + 56 cycles + 3 + + + Cycles84 + 84 cycles + 4 + + + Cycles112 + 112 cycles + 5 + + + Cycles144 + 144 cycles + 6 + + + Cycles480 + 480 cycles + 7 + + + + + + + 4 + 0x4 + 1-4 + JOFR%s + JOFR1 + injected channel data offset register + x + 0x14 + 0x20 + read-write + 0x00000000 + + + JOFFSET + Data offset for injected channel + x + 0 + 12 + + + 0 + 4095 + + + + + + + HTR + HTR + watchdog higher threshold + register + 0x24 + 0x20 + read-write + 0x00000FFF + + + HT + Analog watchdog higher + threshold + 0 + 12 + + + 0 + 4095 + + + + + + + LTR + LTR + watchdog lower threshold + register + 0x28 + 0x20 + read-write + 0x00000000 + + + LT + Analog watchdog lower + threshold + 0 + 12 + + + 0 + 4095 + + + + + + + SQR1 + SQR1 + regular sequence register 1 + 0x2C + 0x20 + read-write + 0x00000000 + + + L + Regular channel sequence + length + 20 + 4 + + + 0 + 15 + + + + + SQ16 + 16th conversion in regular + sequence + 15 + 5 + + + 0 + 18 + + + + + SQ15 + 15th conversion in regular + sequence + 10 + 5 + + + 0 + 18 + + + + + SQ14 + 14th conversion in regular + sequence + 5 + 5 + + + 0 + 18 + + + + + SQ13 + 13th conversion in regular + sequence + 0 + 5 + + + 0 + 18 + + + + + + + SQR2 + SQR2 + regular sequence register 2 + 0x30 + 0x20 + read-write + 0x00000000 + + + SQ12 + 12th conversion in regular + sequence + 25 + 5 + + + 0 + 18 + + + + + SQ11 + 11th conversion in regular + sequence + 20 + 5 + + + 0 + 18 + + + + + SQ10 + 10th conversion in regular + sequence + 15 + 5 + + + 0 + 18 + + + + + SQ9 + 9th conversion in regular + sequence + 10 + 5 + + + 0 + 18 + + + + + SQ8 + 8th conversion in regular + sequence + 5 + 5 + + + 0 + 18 + + + + + SQ7 + 7th conversion in regular + sequence + 0 + 5 + + + 0 + 18 + + + + + + + SQR3 + SQR3 + regular sequence register 3 + 0x34 + 0x20 + read-write + 0x00000000 + + + SQ6 + 6th conversion in regular + sequence + 25 + 5 + + + 0 + 18 + + + + + SQ5 + 5th conversion in regular + sequence + 20 + 5 + + + 0 + 18 + + + + + SQ4 + 4th conversion in regular + sequence + 15 + 5 + + + 0 + 18 + + + + + SQ3 + 3rd conversion in regular + sequence + 10 + 5 + + + 0 + 18 + + + + + SQ2 + 2nd conversion in regular + sequence + 5 + 5 + + + 0 + 18 + + + + + SQ1 + 1st conversion in regular + sequence + 0 + 5 + + + 0 + 18 + + + + + + + JSQR + JSQR + injected sequence register + 0x38 + 0x20 + read-write + 0x00000000 + + + JL + Injected sequence length + 20 + 2 + + + 0 + 3 + + + + + JSQ4 + 4th conversion in injected + sequence + 15 + 5 + + + 0 + 18 + + + + + JSQ3 + 3rd conversion in injected + sequence + 10 + 5 + + + 0 + 18 + + + + + JSQ2 + 2nd conversion in injected + sequence + 5 + 5 + + + 0 + 18 + + + + + JSQ1 + 1st conversion in injected + sequence + 0 + 5 + + + 0 + 18 + + + + + + + 4 + 0x4 + 1-4 + JDR%s + JDR1 + injected data register x + 0x3C + 0x20 + read-only + 0x00000000 + + + JDATA + Injected data + 0 + 16 + + + + + DR + DR + regular data register + 0x4C + 0x20 + read-only + 0x00000000 + + + DATA + Regular data + 0 + 16 + + + + + + + CRC + Cryptographic processor + CRC + 0x40023000 + + 0x0 + 0x400 + registers + + + + DR + DR + Data register + 0x0 + 0x20 + read-write + 0xFFFFFFFF + + + DR + Data Register + 0 + 32 + + + 0 + 4294967295 + + + + + + + IDR + IDR + Independent Data register + 0x4 + 0x20 + read-write + 0x00000000 + + + IDR + Independent Data register + 0 + 8 + + + 0 + 255 + + + + + + + CR + CR + Control register + 0x8 + 0x20 + write-only + 0x00000000 + + + RESET + Control regidter + 0 + 1 + + RESETW + write + + Reset + Resets the CRC calculation unit and sets the data register to 0xFFFF FFFF + 1 + + + + + + + + + DBGMCU + Debug support + DBG + 0xE0042000 + + 0x0 + 0x400 + registers + + + + IDCODE + IDCODE + IDCODE + 0x0 + 0x20 + read-only + 0x10006411 + + + DEV_ID + DEV_ID + 0 + 12 + + + REV_ID + REV_ID + 16 + 16 + + + + + CR + CR + Control Register + 0x4 + 0x20 + read-write + 0x00000000 + + + DBG_SLEEP + DBG_SLEEP + 0 + 1 + + + DBG_STOP + DBG_STOP + 1 + 1 + + + DBG_STANDBY + DBG_STANDBY + 2 + 1 + + + TRACE_IOEN + TRACE_IOEN + 5 + 1 + + + TRACE_MODE + TRACE_MODE + 6 + 2 + + + + + APB1_FZ + APB1_FZ + Debug MCU APB1 Freeze registe + 0x8 + 0x20 + read-write + 0x00000000 + + + DBG_TIM2_STOP + DBG_TIM2_STOP + 0 + 1 + + + DBG_TIM3_STOP + DBG_TIM3 _STOP + 1 + 1 + + + DBG_TIM4_STOP + DBG_TIM4_STOP + 2 + 1 + + + DBG_TIM5_STOP + DBG_TIM5_STOP + 3 + 1 + + + DBG_RTC_Stop + RTC stopped when Core is + halted + 10 + 1 + + + DBG_WWDG_STOP + DBG_WWDG_STOP + 11 + 1 + + + DBG_IWDG_STOP + DBG_IWDEG_STOP + 12 + 1 + + + DBG_I2C1_SMBUS_TIMEOUT + DBG_J2C1_SMBUS_TIMEOUT + 21 + 1 + + + DBG_I2C2_SMBUS_TIMEOUT + DBG_J2C2_SMBUS_TIMEOUT + 22 + 1 + + + DBG_I2C3SMBUS_TIMEOUT + DBG_J2C3SMBUS_TIMEOUT + 23 + 1 + + + + + APB2_FZ + APB2_FZ + Debug MCU APB2 Freeze registe + 0xC + 0x20 + read-write + 0x00000000 + + + DBG_TIM1_STOP + TIM1 counter stopped when core is + halted + 0 + 1 + + + DBG_TIM9_STOP + TIM9 counter stopped when core is + halted + 16 + 1 + + + DBG_TIM10_STOP + TIM10 counter stopped when core is + halted + 17 + 1 + + + DBG_TIM11_STOP + TIM11 counter stopped when core is + halted + 18 + 1 + + + + + + + EXTI + External interrupt/event + controller + EXTI + 0x40013C00 + + 0x0 + 0x400 + registers + + + TAMP_STAMP + Tamper and TimeStamp interrupts through the + EXTI line + 2 + + + EXTI0 + EXTI Line0 interrupt + 6 + + + EXTI1 + EXTI Line1 interrupt + 7 + + + EXTI2 + EXTI Line2 interrupt + 8 + + + EXTI3 + EXTI Line3 interrupt + 9 + + + EXTI4 + EXTI Line4 interrupt + 10 + + + EXTI9_5 + EXTI Line[9:5] interrupts + 23 + + + EXTI15_10 + EXTI Line[15:10] interrupts + 40 + + + + IMR + IMR + Interrupt mask register + (EXTI_IMR) + 0x0 + 0x20 + read-write + 0x00000000 + + + MR0 + Interrupt Mask on line 0 + 0 + 1 + + MR0 + read-write + + Masked + Interrupt request line is masked + 0 + + + Unmasked + Interrupt request line is unmasked + 1 + + + + + MR1 + Interrupt Mask on line 1 + 1 + 1 + + + + MR2 + Interrupt Mask on line 2 + 2 + 1 + + + + MR3 + Interrupt Mask on line 3 + 3 + 1 + + + + MR4 + Interrupt Mask on line 4 + 4 + 1 + + + + MR5 + Interrupt Mask on line 5 + 5 + 1 + + + + MR6 + Interrupt Mask on line 6 + 6 + 1 + + + + MR7 + Interrupt Mask on line 7 + 7 + 1 + + + + MR8 + Interrupt Mask on line 8 + 8 + 1 + + + + MR9 + Interrupt Mask on line 9 + 9 + 1 + + + + MR10 + Interrupt Mask on line 10 + 10 + 1 + + + + MR11 + Interrupt Mask on line 11 + 11 + 1 + + + + MR12 + Interrupt Mask on line 12 + 12 + 1 + + + + MR13 + Interrupt Mask on line 13 + 13 + 1 + + + + MR14 + Interrupt Mask on line 14 + 14 + 1 + + + + MR15 + Interrupt Mask on line 15 + 15 + 1 + + + + MR16 + Interrupt Mask on line 16 + 16 + 1 + + + + MR17 + Interrupt Mask on line 17 + 17 + 1 + + + + MR18 + Interrupt Mask on line 18 + 18 + 1 + + + + MR19 + Interrupt Mask on line 19 + 19 + 1 + + + + MR20 + Interrupt Mask on line 20 + 20 + 1 + + + + MR21 + Interrupt Mask on line 21 + 21 + 1 + + + + MR22 + Interrupt Mask on line 22 + 22 + 1 + + + + + + EMR + EMR + Event mask register (EXTI_EMR) + 0x4 + 0x20 + read-write + 0x00000000 + + + MR0 + Event Mask on line 0 + 0 + 1 + + MR0 + read-write + + Masked + Interrupt request line is masked + 0 + + + Unmasked + Interrupt request line is unmasked + 1 + + + + + MR1 + Event Mask on line 1 + 1 + 1 + + + + MR2 + Event Mask on line 2 + 2 + 1 + + + + MR3 + Event Mask on line 3 + 3 + 1 + + + + MR4 + Event Mask on line 4 + 4 + 1 + + + + MR5 + Event Mask on line 5 + 5 + 1 + + + + MR6 + Event Mask on line 6 + 6 + 1 + + + + MR7 + Event Mask on line 7 + 7 + 1 + + + + MR8 + Event Mask on line 8 + 8 + 1 + + + + MR9 + Event Mask on line 9 + 9 + 1 + + + + MR10 + Event Mask on line 10 + 10 + 1 + + + + MR11 + Event Mask on line 11 + 11 + 1 + + + + MR12 + Event Mask on line 12 + 12 + 1 + + + + MR13 + Event Mask on line 13 + 13 + 1 + + + + MR14 + Event Mask on line 14 + 14 + 1 + + + + MR15 + Event Mask on line 15 + 15 + 1 + + + + MR16 + Event Mask on line 16 + 16 + 1 + + + + MR17 + Event Mask on line 17 + 17 + 1 + + + + MR18 + Event Mask on line 18 + 18 + 1 + + + + MR19 + Event Mask on line 19 + 19 + 1 + + + + MR20 + Event Mask on line 20 + 20 + 1 + + + + MR21 + Event Mask on line 21 + 21 + 1 + + + + MR22 + Event Mask on line 22 + 22 + 1 + + + + + + RTSR + RTSR + Rising Trigger selection register + (EXTI_RTSR) + 0x8 + 0x20 + read-write + 0x00000000 + + + TR0 + Rising trigger event configuration of + line 0 + 0 + 1 + + TR0 + read-write + + Disabled + Rising edge trigger is disabled + 0 + + + Enabled + Rising edge trigger is enabled + 1 + + + + + TR1 + Rising trigger event configuration of + line 1 + 1 + 1 + + + + TR2 + Rising trigger event configuration of + line 2 + 2 + 1 + + + + TR3 + Rising trigger event configuration of + line 3 + 3 + 1 + + + + TR4 + Rising trigger event configuration of + line 4 + 4 + 1 + + + + TR5 + Rising trigger event configuration of + line 5 + 5 + 1 + + + + TR6 + Rising trigger event configuration of + line 6 + 6 + 1 + + + + TR7 + Rising trigger event configuration of + line 7 + 7 + 1 + + + + TR8 + Rising trigger event configuration of + line 8 + 8 + 1 + + + + TR9 + Rising trigger event configuration of + line 9 + 9 + 1 + + + + TR10 + Rising trigger event configuration of + line 10 + 10 + 1 + + + + TR11 + Rising trigger event configuration of + line 11 + 11 + 1 + + + + TR12 + Rising trigger event configuration of + line 12 + 12 + 1 + + + + TR13 + Rising trigger event configuration of + line 13 + 13 + 1 + + + + TR14 + Rising trigger event configuration of + line 14 + 14 + 1 + + + + TR15 + Rising trigger event configuration of + line 15 + 15 + 1 + + + + TR16 + Rising trigger event configuration of + line 16 + 16 + 1 + + + + TR17 + Rising trigger event configuration of + line 17 + 17 + 1 + + + + TR18 + Rising trigger event configuration of + line 18 + 18 + 1 + + + + TR19 + Rising trigger event configuration of + line 19 + 19 + 1 + + + + TR20 + Rising trigger event configuration of + line 20 + 20 + 1 + + + + TR21 + Rising trigger event configuration of + line 21 + 21 + 1 + + + + TR22 + Rising trigger event configuration of + line 22 + 22 + 1 + + + + + + FTSR + FTSR + Falling Trigger selection register + (EXTI_FTSR) + 0xC + 0x20 + read-write + 0x00000000 + + + TR0 + Falling trigger event configuration of + line 0 + 0 + 1 + + TR0 + read-write + + Disabled + Falling edge trigger is disabled + 0 + + + Enabled + Falling edge trigger is enabled + 1 + + + + + TR1 + Falling trigger event configuration of + line 1 + 1 + 1 + + + + TR2 + Falling trigger event configuration of + line 2 + 2 + 1 + + + + TR3 + Falling trigger event configuration of + line 3 + 3 + 1 + + + + TR4 + Falling trigger event configuration of + line 4 + 4 + 1 + + + + TR5 + Falling trigger event configuration of + line 5 + 5 + 1 + + + + TR6 + Falling trigger event configuration of + line 6 + 6 + 1 + + + + TR7 + Falling trigger event configuration of + line 7 + 7 + 1 + + + + TR8 + Falling trigger event configuration of + line 8 + 8 + 1 + + + + TR9 + Falling trigger event configuration of + line 9 + 9 + 1 + + + + TR10 + Falling trigger event configuration of + line 10 + 10 + 1 + + + + TR11 + Falling trigger event configuration of + line 11 + 11 + 1 + + + + TR12 + Falling trigger event configuration of + line 12 + 12 + 1 + + + + TR13 + Falling trigger event configuration of + line 13 + 13 + 1 + + + + TR14 + Falling trigger event configuration of + line 14 + 14 + 1 + + + + TR15 + Falling trigger event configuration of + line 15 + 15 + 1 + + + + TR16 + Falling trigger event configuration of + line 16 + 16 + 1 + + + + TR17 + Falling trigger event configuration of + line 17 + 17 + 1 + + + + TR18 + Falling trigger event configuration of + line 18 + 18 + 1 + + + + TR19 + Falling trigger event configuration of + line 19 + 19 + 1 + + + + TR20 + Falling trigger event configuration of + line 20 + 20 + 1 + + + + TR21 + Falling trigger event configuration of + line 21 + 21 + 1 + + + + TR22 + Falling trigger event configuration of + line 22 + 22 + 1 + + + + + + SWIER + SWIER + Software interrupt event register + (EXTI_SWIER) + 0x10 + 0x20 + read-write + 0x00000000 + + + SWIER0 + Software Interrupt on line + 0 + 0 + 1 + + SWIER0W + write + + Pend + Generates an interrupt request + 1 + + + + + SWIER1 + Software Interrupt on line + 1 + 1 + 1 + + + + SWIER2 + Software Interrupt on line + 2 + 2 + 1 + + + + SWIER3 + Software Interrupt on line + 3 + 3 + 1 + + + + SWIER4 + Software Interrupt on line + 4 + 4 + 1 + + + + SWIER5 + Software Interrupt on line + 5 + 5 + 1 + + + + SWIER6 + Software Interrupt on line + 6 + 6 + 1 + + + + SWIER7 + Software Interrupt on line + 7 + 7 + 1 + + + + SWIER8 + Software Interrupt on line + 8 + 8 + 1 + + + + SWIER9 + Software Interrupt on line + 9 + 9 + 1 + + + + SWIER10 + Software Interrupt on line + 10 + 10 + 1 + + + + SWIER11 + Software Interrupt on line + 11 + 11 + 1 + + + + SWIER12 + Software Interrupt on line + 12 + 12 + 1 + + + + SWIER13 + Software Interrupt on line + 13 + 13 + 1 + + + + SWIER14 + Software Interrupt on line + 14 + 14 + 1 + + + + SWIER15 + Software Interrupt on line + 15 + 15 + 1 + + + + SWIER16 + Software Interrupt on line + 16 + 16 + 1 + + + + SWIER17 + Software Interrupt on line + 17 + 17 + 1 + + + + SWIER18 + Software Interrupt on line + 18 + 18 + 1 + + + + SWIER19 + Software Interrupt on line + 19 + 19 + 1 + + + + SWIER20 + Software Interrupt on line + 20 + 20 + 1 + + + + SWIER21 + Software Interrupt on line + 21 + 21 + 1 + + + + SWIER22 + Software Interrupt on line + 22 + 22 + 1 + + + + + + PR + PR + Pending register (EXTI_PR) + 0x14 + 0x20 + read-write + 0x00000000 + + + PR0 + Pending bit 0 + 0 + 1 + oneToClear + + PR0R + read + + NotPending + No trigger request occurred + 0 + + + Pending + Selected trigger request occurred + 1 + + + + PR0W + write + + Clear + Clears pending bit + 1 + + + + + PR1 + Pending bit 1 + 1 + 1 + oneToClear + + read + + + write + + + + PR2 + Pending bit 2 + 2 + 1 + oneToClear + + read + + + write + + + + PR3 + Pending bit 3 + 3 + 1 + oneToClear + + read + + + write + + + + PR4 + Pending bit 4 + 4 + 1 + oneToClear + + read + + + write + + + + PR5 + Pending bit 5 + 5 + 1 + oneToClear + + read + + + write + + + + PR6 + Pending bit 6 + 6 + 1 + oneToClear + + read + + + write + + + + PR7 + Pending bit 7 + 7 + 1 + oneToClear + + read + + + write + + + + PR8 + Pending bit 8 + 8 + 1 + oneToClear + + read + + + write + + + + PR9 + Pending bit 9 + 9 + 1 + oneToClear + + read + + + write + + + + PR10 + Pending bit 10 + 10 + 1 + oneToClear + + read + + + write + + + + PR11 + Pending bit 11 + 11 + 1 + oneToClear + + read + + + write + + + + PR12 + Pending bit 12 + 12 + 1 + oneToClear + + read + + + write + + + + PR13 + Pending bit 13 + 13 + 1 + oneToClear + + read + + + write + + + + PR14 + Pending bit 14 + 14 + 1 + oneToClear + + read + + + write + + + + PR15 + Pending bit 15 + 15 + 1 + oneToClear + + read + + + write + + + + PR16 + Pending bit 16 + 16 + 1 + oneToClear + + read + + + write + + + + PR17 + Pending bit 17 + 17 + 1 + oneToClear + + read + + + write + + + + PR18 + Pending bit 18 + 18 + 1 + oneToClear + + read + + + write + + + + PR19 + Pending bit 19 + 19 + 1 + oneToClear + + read + + + write + + + + PR20 + Pending bit 20 + 20 + 1 + oneToClear + + read + + + write + + + + PR21 + Pending bit 21 + 21 + 1 + oneToClear + + read + + + write + + + + PR22 + Pending bit 22 + 22 + 1 + oneToClear + + read + + + write + + + + + + + + FLASH + FLASH + FLASH + 0x40023C00 + + 0x0 + 0x400 + registers + + + FLASH + FLASH global interrupt + 4 + + + + ACR + ACR + Flash access control register + 0x0 + 0x20 + 0x00000000 + + + LATENCY + Latency + 0 + 4 + read-write + + LATENCY + read-write + + WS0 + 0 wait states + 0 + + + WS1 + 1 wait states + 1 + + + WS2 + 2 wait states + 2 + + + WS3 + 3 wait states + 3 + + + WS4 + 4 wait states + 4 + + + WS5 + 5 wait states + 5 + + + WS6 + 6 wait states + 6 + + + WS7 + 7 wait states + 7 + + + WS8 + 8 wait states + 8 + + + WS9 + 9 wait states + 9 + + + WS10 + 10 wait states + 10 + + + WS11 + 11 wait states + 11 + + + WS12 + 12 wait states + 12 + + + WS13 + 13 wait states + 13 + + + WS14 + 14 wait states + 14 + + + WS15 + 15 wait states + 15 + + + + + PRFTEN + Prefetch enable + 8 + 1 + read-write + + PRFTEN + read-write + + Disabled + Prefetch is disabled + 0 + + + Enabled + Prefetch is enabled + 1 + + + + + ICEN + Instruction cache enable + 9 + 1 + read-write + + ICEN + read-write + + Disabled + Instruction cache is disabled + 0 + + + Enabled + Instruction cache is enabled + 1 + + + + + DCEN + Data cache enable + 10 + 1 + read-write + + DCEN + read-write + + Disabled + Data cache is disabled + 0 + + + Enabled + Data cache is enabled + 1 + + + + + ICRST + Instruction cache reset + 11 + 1 + write-only + + ICRST + write + + NotReset + Instruction cache is not reset + 0 + + + Reset + Instruction cache is reset + 1 + + + + + DCRST + Data cache reset + 12 + 1 + read-write + + DCRST + read-write + + NotReset + Data cache is not reset + 0 + + + Reset + Data cache is reset + 1 + + + + + + + KEYR + KEYR + Flash key register + 0x4 + 0x20 + write-only + 0x00000000 + + + KEY + FPEC key + 0 + 32 + + + 0 + 4294967295 + + + + + + + OPTKEYR + OPTKEYR + Flash option key register + 0x8 + 0x20 + write-only + 0x00000000 + + + OPTKEY + Option byte key + 0 + 32 + + + 0 + 4294967295 + + + + + + + SR + SR + Status register + 0xC + 0x20 + 0x00000000 + + + EOP + End of operation + 0 + 1 + read-write + oneToClear + + EOPW + write + + Clear + Clear error flag + 1 + + + + + OPERR + Operation error + 1 + 1 + read-write + oneToClear + + OPERRW + write + + Clear + Clear error flag + 1 + + + + + WRPERR + Write protection error + 4 + 1 + read-write + oneToClear + + WRPERRW + write + + Clear + Clear error flag + 1 + + + + + PGAERR + Programming alignment + error + 5 + 1 + read-write + oneToClear + + PGAERRW + write + + Clear + Clear error flag + 1 + + + + + PGPERR + Programming parallelism + error + 6 + 1 + read-write + oneToClear + + PGPERRW + write + + Clear + Clear error flag + 1 + + + + + PGSERR + Programming sequence error + 7 + 1 + read-write + oneToClear + + PGSERRW + write + + Clear + Clear error flag + 1 + + + + + BSY + Busy + 16 + 1 + read-only + + BSYR + read + + NotBusy + no Flash memory operation ongoing + 0 + + + Busy + Flash memory operation ongoing + 1 + + + + + + + CR + CR + Control register + 0x10 + 0x20 + read-write + 0x80000000 + + + PG + Programming + 0 + 1 + + PG + read-write + + Program + Flash programming activated + 1 + + + + + SER + Sector Erase + 1 + 1 + + SER + read-write + + SectorErase + Erase activated for selected sector + 1 + + + + + MER + Mass Erase + 2 + 1 + + MER + read-write + + MassErase + Erase activated for all user sectors + 1 + + + + + SNB + Sector number + 3 + 4 + + + 0 + 11 + + + + + PSIZE + Program size + 8 + 2 + + PSIZE + read-write + + PSIZE8 + Program x8 + 0 + + + PSIZE16 + Program x16 + 1 + + + PSIZE32 + Program x32 + 2 + + + PSIZE64 + Program x64 + 3 + + + + + STRT + Start + 16 + 1 + + STRT + read-write + + Start + Trigger an erase operation + 1 + + + + + EOPIE + End of operation interrupt + enable + 24 + 1 + + EOPIE + read-write + + Disabled + End of operation interrupt disabled + 0 + + + Enabled + End of operation interrupt enabled + 1 + + + + + ERRIE + Error interrupt enable + 25 + 1 + + ERRIE + read-write + + Disabled + Error interrupt generation disabled + 0 + + + Enabled + Error interrupt generation enabled + 1 + + + + + LOCK + Lock + 31 + 1 + + LOCK + read-write + + Unlocked + FLASH_CR register is unlocked + 0 + + + Locked + FLASH_CR register is locked + 1 + + + + + + + OPTCR + OPTCR + Flash option control register + 0x14 + 0x20 + read-write + 0x00000014 + + + OPTLOCK + Option lock + 0 + 1 + + + OPTSTRT + Option start + 1 + 1 + + + BOR_LEV + BOR reset Level + 2 + 2 + + + WDG_SW + WDG_SW User option bytes + 5 + 1 + + + nRST_STOP + nRST_STOP User option + bytes + 6 + 1 + + + nRST_STDBY + nRST_STDBY User option + bytes + 7 + 1 + + + RDP + Read protect + 8 + 8 + + + nWRP + Not write protect + 16 + 12 + + + + + + + IWDG + Independent watchdog + IWDG + 0x40003000 + + 0x0 + 0x400 + registers + + + + KR + KR + Key register + 0x0 + 0x20 + write-only + 0x00000000 + + + KEY + Key value + 0 + 16 + + KEY + write + + Enable + Enable access to PR, RLR and WINR registers (0x5555) + 21845 + + + Reset + Reset the watchdog value (0xAAAA) + 43690 + + + Start + Start the watchdog (0xCCCC) + 52428 + + + + + + + PR + PR + Prescaler register + 0x4 + 0x20 + read-write + 0x00000000 + + + PR + Prescaler divider + 0 + 3 + + PR + read-write + + DivideBy4 + Divider /4 + 0 + + + DivideBy8 + Divider /8 + 1 + + + DivideBy16 + Divider /16 + 2 + + + DivideBy32 + Divider /32 + 3 + + + DivideBy64 + Divider /64 + 4 + + + DivideBy128 + Divider /128 + 5 + + + DivideBy256 + Divider /256 + 6 + + + DivideBy256bis + Divider /256 + 7 + + + + + + + RLR + RLR + Reload register + 0x8 + 0x20 + read-write + 0x00000FFF + + + RL + Watchdog counter reload + value + 0 + 12 + + + 0 + 4095 + + + + + + + SR + SR + Status register + 0xC + 0x20 + read-only + 0x00000000 + + + RVU + Watchdog counter reload value + update + 1 + 1 + + + PVU + Watchdog prescaler value + update + 0 + 1 + + + + + + + OTG_FS_DEVICE + USB on the go full speed + USB_OTG_FS + 0x50000800 + + 0x0 + 0x400 + registers + + + + DCFG + DCFG + OTG_FS device configuration register + (OTG_FS_DCFG) + 0x0 + 0x20 + read-write + 0x02200000 + + + DSPD + Device speed + 0 + 2 + + + NZLSOHSK + Non-zero-length status OUT + handshake + 2 + 1 + + + DAD + Device address + 4 + 7 + + + PFIVL + Periodic frame interval + 11 + 2 + + + + + DCTL + DCTL + OTG_FS device control register + (OTG_FS_DCTL) + 0x4 + 0x20 + 0x00000000 + + + RWUSIG + Remote wakeup signaling + 0 + 1 + read-write + + + SDIS + Soft disconnect + 1 + 1 + read-write + + + GINSTS + Global IN NAK status + 2 + 1 + read-only + + + GONSTS + Global OUT NAK status + 3 + 1 + read-only + + + TCTL + Test control + 4 + 3 + read-write + + + SGINAK + Set global IN NAK + 7 + 1 + read-write + + + CGINAK + Clear global IN NAK + 8 + 1 + read-write + + + SGONAK + Set global OUT NAK + 9 + 1 + read-write + + + CGONAK + Clear global OUT NAK + 10 + 1 + read-write + + + POPRGDNE + Power-on programming done + 11 + 1 + read-write + + + + + DSTS + DSTS + OTG_FS device status register + (OTG_FS_DSTS) + 0x8 + 0x20 + read-only + 0x00000010 + + + SUSPSTS + Suspend status + 0 + 1 + + + ENUMSPD + Enumerated speed + 1 + 2 + + + EERR + Erratic error + 3 + 1 + + + FNSOF + Frame number of the received + SOF + 8 + 14 + + + + + DIEPMSK + DIEPMSK + OTG_FS device IN endpoint common interrupt + mask register (OTG_FS_DIEPMSK) + 0x10 + 0x20 + read-write + 0x00000000 + + + XFRCM + Transfer completed interrupt + mask + 0 + 1 + + + EPDM + Endpoint disabled interrupt + mask + 1 + 1 + + + TOM + Timeout condition mask (Non-isochronous + endpoints) + 3 + 1 + + + ITTXFEMSK + IN token received when TxFIFO empty + mask + 4 + 1 + + + INEPNMM + IN token received with EP mismatch + mask + 5 + 1 + + + INEPNEM + IN endpoint NAK effective + mask + 6 + 1 + + + + + DOEPMSK + DOEPMSK + OTG_FS device OUT endpoint common interrupt + mask register (OTG_FS_DOEPMSK) + 0x14 + 0x20 + read-write + 0x00000000 + + + XFRCM + Transfer completed interrupt + mask + 0 + 1 + + + EPDM + Endpoint disabled interrupt + mask + 1 + 1 + + + STUPM + SETUP phase done mask + 3 + 1 + + + OTEPDM + OUT token received when endpoint + disabled mask + 4 + 1 + + + + + DAINT + DAINT + OTG_FS device all endpoints interrupt + register (OTG_FS_DAINT) + 0x18 + 0x20 + read-only + 0x00000000 + + + IEPINT + IN endpoint interrupt bits + 0 + 16 + + + OEPINT + OUT endpoint interrupt + bits + 16 + 16 + + + + + DAINTMSK + DAINTMSK + OTG_FS all endpoints interrupt mask register + (OTG_FS_DAINTMSK) + 0x1C + 0x20 + read-write + 0x00000000 + + + IEPM + IN EP interrupt mask bits + 0 + 16 + + + OEPM + OUT EP interrupt mask bits + 16 + 16 + + + + + DVBUSDIS + DVBUSDIS + OTG_FS device VBUS discharge time + register + 0x28 + 0x20 + read-write + 0x000017D7 + + + VBUSDT + Device VBUS discharge time + 0 + 16 + + + + + DVBUSPULSE + DVBUSPULSE + OTG_FS device VBUS pulsing time + register + 0x2C + 0x20 + read-write + 0x000005B8 + + + DVBUSP + Device VBUS pulsing time + 0 + 12 + + + + + DIEPEMPMSK + DIEPEMPMSK + OTG_FS device IN endpoint FIFO empty + interrupt mask register + 0x34 + 0x20 + read-write + 0x00000000 + + + INEPTXFEM + IN EP Tx FIFO empty interrupt mask + bits + 0 + 16 + + + + + DIEP0 + Device IN endpoint 0 + 0x100 + + CTL + DIEPCTL0 + OTG_FS device control IN endpoint 0 control + register (OTG_FS_DIEPCTL0) + 0x0 + 0x20 + 0x00000000 + + + MPSIZ + Maximum packet size + 0 + 2 + read-write + + + USBAEP + USB active endpoint + 15 + 1 + read-only + + + NAKSTS + NAK status + 17 + 1 + read-only + + + EPTYP + Endpoint type + 18 + 2 + read-only + + + STALL + STALL handshake + 21 + 1 + read-write + + + TXFNUM + TxFIFO number + 22 + 4 + read-write + + + CNAK + Clear NAK + 26 + 1 + write-only + + + SNAK + Set NAK + 27 + 1 + write-only + + + EPDIS + Endpoint disable + 30 + 1 + read-only + + + EPENA + Endpoint enable + 31 + 1 + read-write + + + + + INT + DIEPINT0 + device endpoint-x interrupt + register + 0x8 + 0x20 + 0x00000080 + + + TXFE + TXFE + 7 + 1 + read-only + + + INEPNE + INEPNE + 6 + 1 + read-write + + + ITTXFE + ITTXFE + 4 + 1 + read-write + + + TOC + TOC + 3 + 1 + read-write + + + EPDISD + EPDISD + 1 + 1 + read-write + + + XFRC + XFRC + 0 + 1 + read-write + + + + + TSIZ + DIEPTSIZ0 + device endpoint-0 transfer size + register + 0x10 + 0x20 + read-write + 0x00000000 + + + PKTCNT + Packet count + 19 + 2 + + + XFRSIZ + Transfer size + 0 + 7 + + + + + TXFSTS + DTXFSTS0 + OTG_FS device IN endpoint transmit FIFO + status register + 0x18 + 0x20 + read-only + 0x00000000 + + + INEPTFSAV + IN endpoint TxFIFO space + available + 0 + 16 + + + + + + 3 + 0x20 + 1-3 + DIEP%s + Device IN endpoint X + 0x120 + + CTL + DIEPCTL1 + OTG device endpoint-1 control + register + 0x0 + 0x20 + 0x00000000 + + + EPENA + EPENA + 31 + 1 + read-write + + + EPDIS + EPDIS + 30 + 1 + read-write + + + SODDFRM_SD1PID + SODDFRM/SD1PID + 29 + 1 + write-only + + + SD0PID_SEVNFRM + SD0PID/SEVNFRM + 28 + 1 + write-only + + + SNAK + SNAK + 27 + 1 + write-only + + + CNAK + CNAK + 26 + 1 + write-only + + + TXFNUM + TXFNUM + 22 + 4 + read-write + + + STALL + STALL handshake + 21 + 1 + read-write + + + EPTYP + EPTYP + 18 + 2 + read-write + + + NAKSTS + NAKSTS + 17 + 1 + read-only + + + EONUM_DPID + EONUM/DPID + 16 + 1 + read-only + + + USBAEP + USBAEP + 15 + 1 + read-write + + + MPSIZ + MPSIZ + 0 + 11 + read-write + + + + + INT + DIEPINT1 + device endpoint-1 interrupt + register + 0x8 + 0x20 + 0x00000080 + + + TXFE + TXFE + 7 + 1 + read-only + + + INEPNE + INEPNE + 6 + 1 + read-write + + + ITTXFE + ITTXFE + 4 + 1 + read-write + + + TOC + TOC + 3 + 1 + read-write + + + EPDISD + EPDISD + 1 + 1 + read-write + + + XFRC + XFRC + 0 + 1 + read-write + + + + + TSIZ + DIEPTSIZ1 + device endpoint-1 transfer size + register + 0x10 + 0x20 + read-write + 0x00000000 + + + MCNT + Multi count + 29 + 2 + + + PKTCNT + Packet count + 19 + 10 + + + XFRSIZ + Transfer size + 0 + 19 + + + + + TXFSTS + DTXFSTS1 + OTG_FS device IN endpoint transmit FIFO + status register + 0x18 + 0x20 + read-only + 0x00000000 + + + INEPTFSAV + IN endpoint TxFIFO space + available + 0 + 16 + + + + + + DOEP0 + Device OUT endpoint 0 + 0x300 + + CTL + DOEPCTL0 + device endpoint-0 control + register + 0x0 + 0x20 + 0x00008000 + + + EPENA + EPENA + 31 + 1 + read-write + + + EPDIS + EPDIS + 30 + 1 + read-only + + + SNAK + SNAK + 27 + 1 + write-only + + + CNAK + CNAK + 26 + 1 + write-only + + + STALL + STALL handshake + 21 + 1 + read-write + + + SNPM + SNPM + 20 + 1 + read-write + + + EPTYP + EPTYP + 18 + 2 + read-only + + + NAKSTS + NAKSTS + 17 + 1 + read-only + + + USBAEP + USBAEP + 15 + 1 + read-only + + + MPSIZ + MPSIZ + 0 + 2 + read-only + + + + + INT + DOEPINT0 + device endpoint-0 interrupt + register + 0x8 + 0x20 + read-write + 0x00000080 + + + B2BSTUP + B2BSTUP + 6 + 1 + + + OTEPDIS + OTEPDIS + 4 + 1 + + + STUP + STUP + 3 + 1 + + + EPDISD + EPDISD + 1 + 1 + + + XFRC + XFRC + 0 + 1 + + + + + TSIZ + DOEPTSIZ0 + device OUT endpoint-0 transfer size + register + 0x10 + 0x20 + read-write + 0x00000000 + + + STUPCNT + SETUP packet count + 29 + 2 + + + PKTCNT + Packet count + 19 + 1 + + + XFRSIZ + Transfer size + 0 + 7 + + + + + + 3 + 0x20 + 1-3 + DOEP%s + Device IN endpoint X + 0x320 + + CTL + DOEPCTL1 + device endpoint-1 control + register + 0x0 + 0x20 + 0x00000000 + + + EPENA + EPENA + 31 + 1 + read-write + + + EPDIS + EPDIS + 30 + 1 + read-write + + + SODDFRM + SODDFRM + 29 + 1 + write-only + + + SD0PID_SEVNFRM + SD0PID/SEVNFRM + 28 + 1 + write-only + + + SNAK + SNAK + 27 + 1 + write-only + + + CNAK + CNAK + 26 + 1 + write-only + + + STALL + STALL handshake + 21 + 1 + read-write + + + SNPM + SNPM + 20 + 1 + read-write + + + EPTYP + EPTYP + 18 + 2 + read-write + + + NAKSTS + NAKSTS + 17 + 1 + read-only + + + EONUM_DPID + EONUM/DPID + 16 + 1 + read-only + + + USBAEP + USBAEP + 15 + 1 + read-write + + + MPSIZ + MPSIZ + 0 + 11 + read-write + + + + + INT + DOEPINT1 + device endpoint-1 interrupt + register + 0x8 + 0x20 + read-write + 0x00000080 + + + B2BSTUP + B2BSTUP + 6 + 1 + + + OTEPDIS + OTEPDIS + 4 + 1 + + + STUP + STUP + 3 + 1 + + + EPDISD + EPDISD + 1 + 1 + + + XFRC + XFRC + 0 + 1 + + + + + TSIZ + DOEPTSIZ1 + device OUT endpoint-1 transfer size + register + 0x10 + 0x20 + read-write + 0x00000000 + + + RXDPID_STUPCNT + Received data PID/SETUP packet + count + 29 + 2 + + + PKTCNT + Packet count + 19 + 10 + + + XFRSIZ + Transfer size + 0 + 19 + + + + + + + + OTG_FS_GLOBAL + USB on the go full speed + USB_OTG_FS + 0x50000000 + + 0x0 + 0x400 + registers + + + + GOTGCTL + GOTGCTL + OTG_FS control and status register + (OTG_FS_GOTGCTL) + 0x0 + 0x20 + 0x00000800 + + + SRQSCS + Session request success + 0 + 1 + read-only + + + SRQ + Session request + 1 + 1 + read-write + + + HNGSCS + Host negotiation success + 8 + 1 + read-only + + + HNPRQ + HNP request + 9 + 1 + read-write + + + HSHNPEN + Host set HNP enable + 10 + 1 + read-write + + + DHNPEN + Device HNP enabled + 11 + 1 + read-write + + + CIDSTS + Connector ID status + 16 + 1 + read-only + + + DBCT + Long/short debounce time + 17 + 1 + read-only + + + ASVLD + A-session valid + 18 + 1 + read-only + + + BSVLD + B-session valid + 19 + 1 + read-only + + + + + GOTGINT + GOTGINT + OTG_FS interrupt register + (OTG_FS_GOTGINT) + 0x4 + 0x20 + read-write + 0x00000000 + + + SEDET + Session end detected + 2 + 1 + + + SRSSCHG + Session request success status + change + 8 + 1 + + + HNSSCHG + Host negotiation success status + change + 9 + 1 + + + HNGDET + Host negotiation detected + 17 + 1 + + + ADTOCHG + A-device timeout change + 18 + 1 + + + DBCDNE + Debounce done + 19 + 1 + + + + + GAHBCFG + GAHBCFG + OTG_FS AHB configuration register + (OTG_FS_GAHBCFG) + 0x8 + 0x20 + read-write + 0x00000000 + + + GINT + Global interrupt mask + 0 + 1 + + + TXFELVL + TxFIFO empty level + 7 + 1 + + + PTXFELVL + Periodic TxFIFO empty + level + 8 + 1 + + + + + GUSBCFG + GUSBCFG + OTG_FS USB configuration register + (OTG_FS_GUSBCFG) + 0xC + 0x20 + 0x00000A00 + + + TOCAL + FS timeout calibration + 0 + 3 + read-write + + + PHYSEL + Full Speed serial transceiver + select + 6 + 1 + write-only + + + SRPCAP + SRP-capable + 8 + 1 + read-write + + + HNPCAP + HNP-capable + 9 + 1 + read-write + + + TRDT + USB turnaround time + 10 + 4 + read-write + + + FHMOD + Force host mode + 29 + 1 + read-write + + + FDMOD + Force device mode + 30 + 1 + read-write + + + CTXPKT + Corrupt Tx packet + 31 + 1 + read-write + + + + + GRSTCTL + GRSTCTL + OTG_FS reset register + (OTG_FS_GRSTCTL) + 0x10 + 0x20 + 0x20000000 + + + CSRST + Core soft reset + 0 + 1 + read-write + + + HSRST + HCLK soft reset + 1 + 1 + read-write + + + FCRST + Host frame counter reset + 2 + 1 + read-write + + + RXFFLSH + RxFIFO flush + 4 + 1 + read-write + + + TXFFLSH + TxFIFO flush + 5 + 1 + read-write + + + TXFNUM + TxFIFO number + 6 + 5 + read-write + + + AHBIDL + AHB master idle + 31 + 1 + read-only + + + + + GINTSTS + GINTSTS + OTG_FS core interrupt register + (OTG_FS_GINTSTS) + 0x14 + 0x20 + 0x04000020 + + + CMOD + Current mode of operation + 0 + 1 + read-only + + + MMIS + Mode mismatch interrupt + 1 + 1 + read-write + + + OTGINT + OTG interrupt + 2 + 1 + read-only + + + SOF + Start of frame + 3 + 1 + read-write + + + RXFLVL + RxFIFO non-empty + 4 + 1 + read-only + + + NPTXFE + Non-periodic TxFIFO empty + 5 + 1 + read-only + + + GINAKEFF + Global IN non-periodic NAK + effective + 6 + 1 + read-only + + + GOUTNAKEFF + Global OUT NAK effective + 7 + 1 + read-only + + + ESUSP + Early suspend + 10 + 1 + read-write + + + USBSUSP + USB suspend + 11 + 1 + read-write + + + USBRST + USB reset + 12 + 1 + read-write + + + ENUMDNE + Enumeration done + 13 + 1 + read-write + + + ISOODRP + Isochronous OUT packet dropped + interrupt + 14 + 1 + read-write + + + EOPF + End of periodic frame + interrupt + 15 + 1 + read-write + + + IEPINT + IN endpoint interrupt + 18 + 1 + read-only + + + OEPINT + OUT endpoint interrupt + 19 + 1 + read-only + + + IISOIXFR + Incomplete isochronous IN + transfer + 20 + 1 + read-write + + + IPXFR_INCOMPISOOUT + Incomplete periodic transfer(Host + mode)/Incomplete isochronous OUT transfer(Device + mode) + 21 + 1 + read-write + + + HPRTINT + Host port interrupt + 24 + 1 + read-only + + + HCINT + Host channels interrupt + 25 + 1 + read-only + + + PTXFE + Periodic TxFIFO empty + 26 + 1 + read-only + + + CIDSCHG + Connector ID status change + 28 + 1 + read-write + + + DISCINT + Disconnect detected + interrupt + 29 + 1 + read-write + + + SRQINT + Session request/new session detected + interrupt + 30 + 1 + read-write + + + WKUPINT + Resume/remote wakeup detected + interrupt + 31 + 1 + read-write + + + + + GINTMSK + GINTMSK + OTG_FS interrupt mask register + (OTG_FS_GINTMSK) + 0x18 + 0x20 + 0x00000000 + + + MMISM + Mode mismatch interrupt + mask + 1 + 1 + read-write + + + OTGINT + OTG interrupt mask + 2 + 1 + read-write + + + SOFM + Start of frame mask + 3 + 1 + read-write + + + RXFLVLM + Receive FIFO non-empty + mask + 4 + 1 + read-write + + + NPTXFEM + Non-periodic TxFIFO empty + mask + 5 + 1 + read-write + + + GINAKEFFM + Global non-periodic IN NAK effective + mask + 6 + 1 + read-write + + + GONAKEFFM + Global OUT NAK effective + mask + 7 + 1 + read-write + + + ESUSPM + Early suspend mask + 10 + 1 + read-write + + + USBSUSPM + USB suspend mask + 11 + 1 + read-write + + + USBRST + USB reset mask + 12 + 1 + read-write + + + ENUMDNEM + Enumeration done mask + 13 + 1 + read-write + + + ISOODRPM + Isochronous OUT packet dropped interrupt + mask + 14 + 1 + read-write + + + EOPFM + End of periodic frame interrupt + mask + 15 + 1 + read-write + + + EPMISM + Endpoint mismatch interrupt + mask + 17 + 1 + read-write + + + IEPINT + IN endpoints interrupt + mask + 18 + 1 + read-write + + + OEPINT + OUT endpoints interrupt + mask + 19 + 1 + read-write + + + IISOIXFRM + Incomplete isochronous IN transfer + mask + 20 + 1 + read-write + + + IPXFRM_IISOOXFRM + Incomplete periodic transfer mask(Host + mode)/Incomplete isochronous OUT transfer mask(Device + mode) + 21 + 1 + read-write + + + PRTIM + Host port interrupt mask + 24 + 1 + read-write + + + HCIM + Host channels interrupt + mask + 25 + 1 + read-write + + + PTXFEM + Periodic TxFIFO empty mask + 26 + 1 + read-write + + + CIDSCHGM + Connector ID status change + mask + 28 + 1 + read-write + + + DISCINT + Disconnect detected interrupt + mask + 29 + 1 + read-write + + + SRQIM + Session request/new session detected + interrupt mask + 30 + 1 + read-write + + + WUIM + Resume/remote wakeup detected interrupt + mask + 31 + 1 + read-write + + + + + GRXSTSR_Device + GRXSTSR_Device + OTG_FS Receive status debug read(Device + mode) + 0x1C + 0x20 + read-only + 0x00000000 + + + EPNUM + Endpoint number + 0 + 4 + + + BCNT + Byte count + 4 + 11 + + + DPID + Data PID + 15 + 2 + + + PKTSTS + Packet status + 17 + 4 + + + FRMNUM + Frame number + 21 + 4 + + + + + GRXSTSR_Host + GRXSTSR_Host + OTG status debug read (host mode) + GRXSTSR_Device + 0x1C + 0x20 + read-only + 0x00000000 + + + CHNUM + Channel number + 0 + 4 + + + BCNT + Byte count + 4 + 11 + + + DPID + Data PID + 15 + 2 + + + PKTSTS + Packet status + 17 + 4 + + + + + GRXFSIZ + GRXFSIZ + OTG_FS Receive FIFO size register + (OTG_FS_GRXFSIZ) + 0x24 + 0x20 + read-write + 0x00000200 + + + RXFD + RxFIFO depth + 0 + 16 + + + + + DIEPTXF0 + DIEPTXF0 + OTG_FS non-periodic transmit FIFO size + register (Device mode) + 0x28 + 0x20 + read-write + 0x00000200 + + + TX0FSA + Endpoint 0 transmit RAM start + address + 0 + 16 + + + TX0FD + Endpoint 0 TxFIFO depth + 16 + 16 + + + + + HNPTXFSIZ + HNPTXFSIZ + OTG_FS non-periodic transmit FIFO size + register (Host mode) + DIEPTXF0 + 0x28 + 0x20 + read-write + 0x00000200 + + + NPTXFSA + Non-periodic transmit RAM start + address + 0 + 16 + + + NPTXFD + Non-periodic TxFIFO depth + 16 + 16 + + + + + GNPTXSTS + GNPTXSTS + OTG_FS non-periodic transmit FIFO/queue + status register (OTG_FS_GNPTXSTS) + 0x2C + 0x20 + read-only + 0x00080200 + + + NPTXFSAV + Non-periodic TxFIFO space + available + 0 + 16 + + + NPTQXSAV + Non-periodic transmit request queue + space available + 16 + 8 + + + NPTXQTOP + Top of the non-periodic transmit request + queue + 24 + 7 + + + + + GCCFG + GCCFG + OTG_FS general core configuration register + (OTG_FS_GCCFG) + 0x38 + 0x20 + read-write + 0x00000000 + + + PWRDWN + Power down + 16 + 1 + + + VBUSASEN + Enable the VBUS sensing + device + 18 + 1 + + + VBUSBSEN + Enable the VBUS sensing + device + 19 + 1 + + + SOFOUTEN + SOF output enable + 20 + 1 + + + NOVBUSSENS + Vbus sensing disable option + 21 + 1 + + + + + CID + CID + core ID register + 0x3C + 0x20 + read-write + 0x00001000 + + + PRODUCT_ID + Product ID field + 0 + 32 + + + + + HPTXFSIZ + HPTXFSIZ + OTG_FS Host periodic transmit FIFO size + register (OTG_FS_HPTXFSIZ) + 0x100 + 0x20 + read-write + 0x02000600 + + + PTXSA + Host periodic TxFIFO start + address + 0 + 16 + + + PTXFSIZ + Host periodic TxFIFO depth + 16 + 16 + + + + + 3 + 0x4 + 1-3 + DIEPTXF%s + DIEPTXF1 + OTF_FS device IN endpoint transmit FIFO size register + 0x104 + 0x20 + read-write + 0x02000400 + + + INEPTXSA + IN endpoint FIFO2 transmit RAM start + address + 0 + 16 + + + INEPTXFD + IN endpoint TxFIFO depth + 16 + 16 + + + + + GRXSTSP_Device + OTG status read and pop (device mode) + 0x20 + 0x20 + read-only + 0x00000000 + + + FRMNUM + Frame number + 21 + 4 + + + PKTSTS + Packet status + 17 + 4 + + + DPID + Data PID + 15 + 2 + + + BCNT + Byte count + 4 + 11 + + + EPNUM + Endpoint number + 0 + 4 + + + + + GRXSTSP_Host + OTG status read and pop (host mode) + GRXSTSP_Device + 0x20 + 0x20 + read-only + 0x00000000 + + + PKTSTS + Packet status + 17 + 4 + + + DPID + Data PID + 15 + 2 + + + BCNT + Byte count + 4 + 11 + + + CHNUM + Channel number + 0 + 4 + + + + + + + OTG_FS_HOST + USB on the go full speed + USB_OTG_FS + 0x50000400 + + 0x0 + 0x400 + registers + + + + HCFG + HCFG + OTG_FS host configuration register + (OTG_FS_HCFG) + 0x0 + 0x20 + 0x00000000 + + + FSLSPCS + FS/LS PHY clock select + 0 + 2 + read-write + + + FSLSS + FS- and LS-only support + 2 + 1 + read-write + + + + + HFIR + HFIR + OTG_FS Host frame interval + register + 0x4 + 0x20 + read-write + 0x0000EA60 + + + FRIVL + Frame interval + 0 + 16 + + + + + HFNUM + HFNUM + OTG_FS host frame number/frame time + remaining register (OTG_FS_HFNUM) + 0x8 + 0x20 + read-only + 0x00003FFF + + + FRNUM + Frame number + 0 + 16 + + + FTREM + Frame time remaining + 16 + 16 + + + + + HPTXSTS + HPTXSTS + OTG_FS_Host periodic transmit FIFO/queue + status register (OTG_FS_HPTXSTS) + 0x10 + 0x20 + 0x00080100 + + + PTXFSAVL + Periodic transmit data FIFO space + available + 0 + 16 + read-write + + + PTXQSAV + Periodic transmit request queue space + available + 16 + 8 + read-only + + + PTXQTOP + Top of the periodic transmit request + queue + 24 + 8 + read-only + + + + + HAINT + HAINT + OTG_FS Host all channels interrupt + register + 0x14 + 0x20 + read-only + 0x00000000 + + + HAINT + Channel interrupts + 0 + 16 + + + + + HAINTMSK + HAINTMSK + OTG_FS host all channels interrupt mask + register + 0x18 + 0x20 + read-write + 0x00000000 + + + HAINTM + Channel interrupt mask + 0 + 16 + + + + + HPRT + HPRT + OTG_FS host port control and status register + (OTG_FS_HPRT) + 0x40 + 0x20 + 0x00000000 + + + PCSTS + Port connect status + 0 + 1 + read-only + + + PCDET + Port connect detected + 1 + 1 + read-write + + + PENA + Port enable + 2 + 1 + read-write + + + PENCHNG + Port enable/disable change + 3 + 1 + read-write + + + POCA + Port overcurrent active + 4 + 1 + read-only + + + POCCHNG + Port overcurrent change + 5 + 1 + read-write + + + PRES + Port resume + 6 + 1 + read-write + + + PSUSP + Port suspend + 7 + 1 + read-write + + + PRST + Port reset + 8 + 1 + read-write + + + PLSTS + Port line status + 10 + 2 + read-only + + + PPWR + Port power + 12 + 1 + read-write + + + PTCTL + Port test control + 13 + 4 + read-write + + + PSPD + Port speed + 17 + 2 + read-only + + + + + 8 + 0x20 + 0-7 + HC%s + Host channel + 0x100 + + CHAR + HCCHAR0 + OTG_FS host channel-0 characteristics + register (OTG_FS_HCCHAR0) + 0x0 + 0x20 + read-write + 0x00000000 + + + MPSIZ + Maximum packet size + 0 + 11 + + + EPNUM + Endpoint number + 11 + 4 + + + EPDIR + Endpoint direction + 15 + 1 + + + LSDEV + Low-speed device + 17 + 1 + + + EPTYP + Endpoint type + 18 + 2 + + + MCNT + Multicount + 20 + 2 + + + DAD + Device address + 22 + 7 + + + ODDFRM + Odd frame + 29 + 1 + + + CHDIS + Channel disable + 30 + 1 + + + CHENA + Channel enable + 31 + 1 + + + + + INT + HCINT0 + OTG_FS host channel-0 interrupt register + (OTG_FS_HCINT0) + 0x8 + 0x20 + read-write + 0x00000000 + + + XFRC + Transfer completed + 0 + 1 + + + CHH + Channel halted + 1 + 1 + + + STALL + STALL response received + interrupt + 3 + 1 + + + NAK + NAK response received + interrupt + 4 + 1 + + + ACK + ACK response received/transmitted + interrupt + 5 + 1 + + + TXERR + Transaction error + 7 + 1 + + + BBERR + Babble error + 8 + 1 + + + FRMOR + Frame overrun + 9 + 1 + + + DTERR + Data toggle error + 10 + 1 + + + + + INTMSK + HCINTMSK0 + OTG_FS host channel-0 mask register + (OTG_FS_HCINTMSK0) + 0xC + 0x20 + read-write + 0x00000000 + + + XFRCM + Transfer completed mask + 0 + 1 + + + CHHM + Channel halted mask + 1 + 1 + + + STALLM + STALL response received interrupt + mask + 3 + 1 + + + NAKM + NAK response received interrupt + mask + 4 + 1 + + + ACKM + ACK response received/transmitted + interrupt mask + 5 + 1 + + + NYET + response received interrupt + mask + 6 + 1 + + + TXERRM + Transaction error mask + 7 + 1 + + + BBERRM + Babble error mask + 8 + 1 + + + FRMORM + Frame overrun mask + 9 + 1 + + + DTERRM + Data toggle error mask + 10 + 1 + + + + + TSIZ + HCTSIZ0 + OTG_FS host channel-0 transfer size + register + 0x10 + 0x20 + read-write + 0x00000000 + + + XFRSIZ + Transfer size + 0 + 19 + + + PKTCNT + Packet count + 19 + 10 + + + DPID + Data PID + 29 + 2 + + + + + + + + OTG_FS_PWRCLK + USB on the go full speed + USB_OTG_FS + 0x50000E00 + + 0x0 + 0x400 + registers + + + + PCGCCTL + PCGCCTL + OTG_FS power and clock gating control + register + 0x0 + 0x20 + read-write + 0x00000000 + + + STPPCLK + Stop PHY clock + 0 + 1 + + + GATEHCLK + Gate HCLK + 1 + 1 + + + PHYSUSP + PHY Suspended + 4 + 1 + + + + + + + PWR + Power control + PWR + 0x40007000 + + 0x0 + 0x400 + registers + + + + CR + CR + power control register + 0x0 + 0x20 + read-write + 0x00000000 + + + VOS + Regulator voltage scaling output + selection + 14 + 2 + + + ADCDC1 + ADCDC1 + 13 + 1 + + + FPDS + Flash power down in Stop + mode + 9 + 1 + + + DBP + Disable backup domain write + protection + 8 + 1 + + + PLS + PVD level selection + 5 + 3 + + + PVDE + Power voltage detector + enable + 4 + 1 + + + CSBF + Clear standby flag + 3 + 1 + + + CWUF + Clear wakeup flag + 2 + 1 + + + PDDS + Power down deepsleep + 1 + 1 + + + LPDS + Low-power deep sleep + 0 + 1 + + + + + CSR + CSR + power control/status register + 0x4 + 0x20 + 0x00000000 + + + WUF + Wakeup flag + 0 + 1 + read-only + + + SBF + Standby flag + 1 + 1 + read-only + + + PVDO + PVD output + 2 + 1 + read-only + + + BRR + Backup regulator ready + 3 + 1 + read-only + + + EWUP + Enable WKUP pin + 8 + 1 + read-write + + + BRE + Backup regulator enable + 9 + 1 + read-write + + + VOSRDY + Regulator voltage scaling output + selection ready bit + 14 + 1 + read-write + + + + + + + RCC + Reset and clock control + RCC + 0x40023800 + + 0x0 + 0x400 + registers + + + I2C1_EV + I2C1 event interrupt + 31 + + + I2C1_ER + I2C1 error interrupt + 32 + + + + CR + CR + clock control register + 0x0 + 0x20 + 0x00000083 + + + PLLI2SRDY + PLLI2S clock ready flag + 27 + 1 + read-only + + + + PLLI2SON + PLLI2S enable + 26 + 1 + read-write + + + + PLLRDY + Main PLL (PLL) clock ready + flag + 25 + 1 + read-only + + + + PLLON + Main PLL (PLL) enable + 24 + 1 + read-write + + + + CSSON + Clock security system + enable + 19 + 1 + read-write + + CSSON + read-write + + Off + Clock security system disabled (clock detector OFF) + 0 + + + On + Clock security system enable (clock detector ON if the HSE is ready, OFF if not) + 1 + + + + + HSEBYP + HSE clock bypass + 18 + 1 + read-write + + HSEBYP + read-write + + NotBypassed + HSE crystal oscillator not bypassed + 0 + + + Bypassed + HSE crystal oscillator bypassed with external clock + 1 + + + + + HSERDY + HSE clock ready flag + 17 + 1 + read-only + + + + HSEON + HSE clock enable + 16 + 1 + read-write + + + + HSICAL + Internal high-speed clock + calibration + 8 + 8 + read-only + + + 0 + 255 + + + + + HSITRIM + Internal high-speed clock + trimming + 3 + 5 + read-write + + + 0 + 31 + + + + + HSIRDY + Internal high-speed clock ready + flag + 1 + 1 + read-only + + HSIRDYR + read + + NotReady + Clock not ready + 0 + + + Ready + Clock ready + 1 + + + + + HSION + Internal high-speed clock + enable + 0 + 1 + read-write + + HSION + read-write + + Off + Clock Off + 0 + + + On + Clock On + 1 + + + + + + + PLLCFGR + PLLCFGR + PLL configuration register + 0x4 + 0x20 + read-write + 0x24003010 + + + PLLSRC + Main PLL(PLL) and audio PLL (PLLI2S) + entry clock source + 22 + 1 + + PLLSRC + read-write + + HSI + HSI clock selected as PLL and PLLI2S clock entry + 0 + + + HSE + HSE oscillator clock selected as PLL and PLLI2S clock entry + 1 + + + + + PLLM + Division factor for the main PLL (PLL) + and audio PLL (PLLI2S) input clock + 0 + 6 + + + 2 + 63 + + + + + PLLN + Main PLL (PLL) multiplication factor for + VCO + 6 + 9 + + + 50 + 432 + + + + + PLLP + Main PLL (PLL) division factor for main + system clock + 16 + 2 + + PLLP + read-write + + Div2 + PLLP=2 + 0 + + + Div4 + PLLP=4 + 1 + + + Div6 + PLLP=6 + 2 + + + Div8 + PLLP=8 + 3 + + + + + PLLQ + Main PLL (PLL) division factor for USB + OTG FS, SDIO and random number generator + clocks + 24 + 4 + + + 2 + 15 + + + + + + + CFGR + CFGR + clock configuration register + 0x8 + 0x20 + 0x00000000 + + + MCO2 + Microcontroller clock output + 2 + 30 + 2 + read-write + + MCO2 + read-write + + SYSCLK + System clock (SYSCLK) selected + 0 + + + PLLI2S + PLLI2S clock selected + 1 + + + HSE + HSE oscillator clock selected + 2 + + + PLL + PLL clock selected + 3 + + + + + MCO2PRE + MCO2 prescaler + 27 + 3 + read-write + + + + MCO1PRE + MCO1 prescaler + 24 + 3 + read-write + + MCO1PRE + read-write + + Div1 + No division + 0 + + + Div2 + Division by 2 + 4 + + + Div3 + Division by 3 + 5 + + + Div4 + Division by 4 + 6 + + + Div5 + Division by 5 + 7 + + + + + I2SSRC + I2S clock selection + 23 + 1 + read-write + + I2SSRC + read-write + + PLLI2S + PLLI2S clock used as I2S clock source + 0 + + + CKIN + External clock mapped on the I2S_CKIN pin used as I2S clock source + 1 + + + + + MCO1 + Microcontroller clock output + 1 + 21 + 2 + read-write + + MCO1 + read-write + + HSI + HSI clock selected + 0 + + + LSE + LSE oscillator selected + 1 + + + HSE + HSE oscillator clock selected + 2 + + + PLL + PLL clock selected + 3 + + + + + RTCPRE + HSE division factor for RTC + clock + 16 + 5 + read-write + + + 0 + 31 + + + + + PPRE2 + APB high-speed prescaler + (APB2) + 13 + 3 + read-write + + + + PPRE1 + APB Low speed prescaler + (APB1) + 10 + 3 + read-write + + PPRE1 + read-write + + Div1 + HCLK not divided + 0 + + + Div2 + HCLK divided by 2 + 4 + + + Div4 + HCLK divided by 4 + 5 + + + Div8 + HCLK divided by 8 + 6 + + + Div16 + HCLK divided by 16 + 7 + + + + + HPRE + AHB prescaler + 4 + 4 + read-write + + HPRE + read-write + + Div1 + SYSCLK not divided + 0 + + + Div2 + SYSCLK divided by 2 + 8 + + + Div4 + SYSCLK divided by 4 + 9 + + + Div8 + SYSCLK divided by 8 + 10 + + + Div16 + SYSCLK divided by 16 + 11 + + + Div64 + SYSCLK divided by 64 + 12 + + + Div128 + SYSCLK divided by 128 + 13 + + + Div256 + SYSCLK divided by 256 + 14 + + + Div512 + SYSCLK divided by 512 + 15 + + + + + SW + System clock switch + 0 + 2 + + SW + read-write + + HSI + HSI selected as system clock + 0 + + + HSE + HSE selected as system clock + 1 + + + PLL + PLL selected as system clock + 2 + + + + + SWS + System clock switch status + 2 + 2 + + SWSR + read + + HSI + HSI oscillator used as system clock + 0 + + + HSE + HSE oscillator used as system clock + 1 + + + PLL + PLL used as system clock + 2 + + + + + + + CIR + CIR + clock interrupt register + 0xC + 0x20 + 0x00000000 + + + CSSC + Clock security system interrupt + clear + 23 + 1 + write-only + + CSSCW + write + + Clear + Clear CSSF flag + 1 + + + + + PLLI2SRDYC + PLLI2S ready interrupt + clear + 21 + 1 + write-only + + + + PLLRDYC + Main PLL(PLL) ready interrupt + clear + 20 + 1 + write-only + + + + HSERDYC + HSE ready interrupt clear + 19 + 1 + write-only + + + + HSIRDYC + HSI ready interrupt clear + 18 + 1 + write-only + + + + LSERDYC + LSE ready interrupt clear + 17 + 1 + write-only + + + + LSIRDYC + LSI ready interrupt clear + 16 + 1 + write-only + + LSIRDYCW + write + + Clear + Clear interrupt flag + 1 + + + + + PLLI2SRDYIE + PLLI2S ready interrupt + enable + 13 + 1 + read-write + + + + PLLRDYIE + Main PLL (PLL) ready interrupt + enable + 12 + 1 + read-write + + + + HSERDYIE + HSE ready interrupt enable + 11 + 1 + read-write + + + + HSIRDYIE + HSI ready interrupt enable + 10 + 1 + read-write + + + + LSERDYIE + LSE ready interrupt enable + 9 + 1 + read-write + + + + LSIRDYIE + LSI ready interrupt enable + 8 + 1 + read-write + + LSIRDYIE + read-write + + Disabled + Interrupt disabled + 0 + + + Enabled + Interrupt enabled + 1 + + + + + CSSF + Clock security system interrupt + flag + 7 + 1 + read-only + + CSSFR + read + + NotInterrupted + No clock security interrupt caused by HSE clock failure + 0 + + + Interrupted + Clock security interrupt caused by HSE clock failure + 1 + + + + + PLLI2SRDYF + PLLI2S ready interrupt + flag + 5 + 1 + read-only + + + + PLLRDYF + Main PLL (PLL) ready interrupt + flag + 4 + 1 + read-only + + + + HSERDYF + HSE ready interrupt flag + 3 + 1 + read-only + + + + HSIRDYF + HSI ready interrupt flag + 2 + 1 + read-only + + + + LSERDYF + LSE ready interrupt flag + 1 + 1 + read-only + + + + LSIRDYF + LSI ready interrupt flag + 0 + 1 + read-only + + LSIRDYFR + read + + NotInterrupted + No clock ready interrupt + 0 + + + Interrupted + Clock ready interrupt + 1 + + + + + + + AHB1RSTR + AHB1RSTR + AHB1 peripheral reset register + 0x10 + 0x20 + read-write + 0x00000000 + + + DMA2RST + DMA2 reset + 22 + 1 + + + + DMA1RST + DMA2 reset + 21 + 1 + + + + CRCRST + CRC reset + 12 + 1 + + + + GPIOHRST + IO port H reset + 7 + 1 + + + + GPIOERST + IO port E reset + 4 + 1 + + + + GPIODRST + IO port D reset + 3 + 1 + + + + GPIOCRST + IO port C reset + 2 + 1 + + + + GPIOBRST + IO port B reset + 1 + 1 + + + + GPIOARST + IO port A reset + 0 + 1 + + GPIOARST + read-write + + Reset + Reset the selected module + 1 + + + + + + + AHB2RSTR + AHB2RSTR + AHB2 peripheral reset register + 0x14 + 0x20 + read-write + 0x00000000 + + + OTGFSRST + USB OTG FS module reset + 7 + 1 + + OTGFSRST + read-write + + Reset + Reset the selected module + 1 + + + + + + + APB1RSTR + APB1RSTR + APB1 peripheral reset register + 0x20 + 0x20 + read-write + 0x00000000 + + + PWRRST + Power interface reset + 28 + 1 + + + + I2C3RST + I2C3 reset + 23 + 1 + + + + I2C2RST + I2C 2 reset + 22 + 1 + + + + I2C1RST + I2C 1 reset + 21 + 1 + + + + USART2RST + USART 2 reset + 17 + 1 + + + + SPI3RST + SPI 3 reset + 15 + 1 + + + + SPI2RST + SPI 2 reset + 14 + 1 + + + + WWDGRST + Window watchdog reset + 11 + 1 + + + + TIM5RST + TIM5 reset + 3 + 1 + + + + TIM4RST + TIM4 reset + 2 + 1 + + + + TIM3RST + TIM3 reset + 1 + 1 + + + + TIM2RST + TIM2 reset + 0 + 1 + + TIM2RST + read-write + + Reset + Reset the selected module + 1 + + + + + + + APB2RSTR + APB2RSTR + APB2 peripheral reset register + 0x24 + 0x20 + read-write + 0x00000000 + + + TIM11RST + TIM11 reset + 18 + 1 + + + + TIM10RST + TIM10 reset + 17 + 1 + + + + TIM9RST + TIM9 reset + 16 + 1 + + + + SYSCFGRST + System configuration controller + reset + 14 + 1 + + + + SPI1RST + SPI 1 reset + 12 + 1 + + + + SDIORST + SDIO reset + 11 + 1 + + + + ADCRST + ADC interface reset (common to all + ADCs) + 8 + 1 + + + + USART6RST + USART6 reset + 5 + 1 + + + + USART1RST + USART1 reset + 4 + 1 + + + + TIM1RST + TIM1 reset + 0 + 1 + + TIM1RST + read-write + + Reset + Reset the selected module + 1 + + + + + SPI4RST + SPI4 reset + 13 + 1 + + + + + + AHB1ENR + AHB1ENR + AHB1 peripheral clock register + 0x30 + 0x20 + read-write + 0x00100000 + + + DMA2EN + DMA2 clock enable + 22 + 1 + + + + DMA1EN + DMA1 clock enable + 21 + 1 + + + + CRCEN + CRC clock enable + 12 + 1 + + + + GPIOHEN + IO port H clock enable + 7 + 1 + + + + GPIOEEN + IO port E clock enable + 4 + 1 + + + + GPIODEN + IO port D clock enable + 3 + 1 + + + + GPIOCEN + IO port C clock enable + 2 + 1 + + + + GPIOBEN + IO port B clock enable + 1 + 1 + + + + GPIOAEN + IO port A clock enable + 0 + 1 + + GPIOAEN + read-write + + Disabled + The selected clock is disabled + 0 + + + Enabled + The selected clock is enabled + 1 + + + + + + + AHB2ENR + AHB2ENR + AHB2 peripheral clock enable + register + 0x34 + 0x20 + read-write + 0x00000000 + + + OTGFSEN + USB OTG FS clock enable + 7 + 1 + + OTGFSEN + read-write + + Disabled + The selected clock is disabled + 0 + + + Enabled + The selected clock is enabled + 1 + + + + + + + APB1ENR + APB1ENR + APB1 peripheral clock enable + register + 0x40 + 0x20 + read-write + 0x00000000 + + + PWREN + Power interface clock + enable + 28 + 1 + + + + I2C3EN + I2C3 clock enable + 23 + 1 + + + + I2C2EN + I2C2 clock enable + 22 + 1 + + + + I2C1EN + I2C1 clock enable + 21 + 1 + + + + USART2EN + USART 2 clock enable + 17 + 1 + + + + SPI3EN + SPI3 clock enable + 15 + 1 + + + + SPI2EN + SPI2 clock enable + 14 + 1 + + + + WWDGEN + Window watchdog clock + enable + 11 + 1 + + + + TIM5EN + TIM5 clock enable + 3 + 1 + + + + TIM4EN + TIM4 clock enable + 2 + 1 + + + + TIM3EN + TIM3 clock enable + 1 + 1 + + + + TIM2EN + TIM2 clock enable + 0 + 1 + + TIM2EN + read-write + + Disabled + The selected clock is disabled + 0 + + + Enabled + The selected clock is enabled + 1 + + + + + + + APB2ENR + APB2ENR + APB2 peripheral clock enable + register + 0x44 + 0x20 + read-write + 0x00000000 + + + TIM11EN + TIM11 clock enable + 18 + 1 + + + + TIM10EN + TIM10 clock enable + 17 + 1 + + + + TIM9EN + TIM9 clock enable + 16 + 1 + + + + SYSCFGEN + System configuration controller clock + enable + 14 + 1 + + + + SPI1EN + SPI1 clock enable + 12 + 1 + + + + SDIOEN + SDIO clock enable + 11 + 1 + + + + ADC1EN + ADC1 clock enable + 8 + 1 + + + + USART6EN + USART6 clock enable + 5 + 1 + + + + USART1EN + USART1 clock enable + 4 + 1 + + + + TIM1EN + TIM1 clock enable + 0 + 1 + + TIM1EN + read-write + + Disabled + The selected clock is disabled + 0 + + + Enabled + The selected clock is enabled + 1 + + + + + SPI4EN + SPI4 clock enable + 13 + 1 + + + + + + AHB1LPENR + AHB1LPENR + AHB1 peripheral clock enable in low power + mode register + 0x50 + 0x20 + read-write + 0x7E6791FF + + + DMA2LPEN + DMA2 clock enable during Sleep + mode + 22 + 1 + + + + DMA1LPEN + DMA1 clock enable during Sleep + mode + 21 + 1 + + + + SRAM1LPEN + SRAM 1interface clock enable during + Sleep mode + 16 + 1 + + + + FLITFLPEN + Flash interface clock enable during + Sleep mode + 15 + 1 + + + + CRCLPEN + CRC clock enable during Sleep + mode + 12 + 1 + + + + GPIOHLPEN + IO port H clock enable during Sleep + mode + 7 + 1 + + + + GPIOELPEN + IO port E clock enable during Sleep + mode + 4 + 1 + + + + GPIODLPEN + IO port D clock enable during Sleep + mode + 3 + 1 + + + + GPIOCLPEN + IO port C clock enable during Sleep + mode + 2 + 1 + + + + GPIOBLPEN + IO port B clock enable during Sleep + mode + 1 + 1 + + + + GPIOALPEN + IO port A clock enable during sleep + mode + 0 + 1 + + GPIOALPEN + read-write + + DisabledInSleep + Selected module is disabled during Sleep mode + 0 + + + EnabledInSleep + Selected module is enabled during Sleep mode + 1 + + + + + + + AHB2LPENR + AHB2LPENR + AHB2 peripheral clock enable in low power + mode register + 0x54 + 0x20 + read-write + 0x000000F1 + + + OTGFSLPEN + USB OTG FS clock enable during Sleep + mode + 7 + 1 + + OTGFSLPEN + read-write + + DisabledInSleep + Selected module is disabled during Sleep mode + 0 + + + EnabledInSleep + Selected module is enabled during Sleep mode + 1 + + + + + + + APB1LPENR + APB1LPENR + APB1 peripheral clock enable in low power + mode register + 0x60 + 0x20 + read-write + 0x36FEC9FF + + + PWRLPEN + Power interface clock enable during + Sleep mode + 28 + 1 + + + + I2C3LPEN + I2C3 clock enable during Sleep + mode + 23 + 1 + + + + I2C2LPEN + I2C2 clock enable during Sleep + mode + 22 + 1 + + + + I2C1LPEN + I2C1 clock enable during Sleep + mode + 21 + 1 + + + + USART2LPEN + USART2 clock enable during Sleep + mode + 17 + 1 + + + + SPI3LPEN + SPI3 clock enable during Sleep + mode + 15 + 1 + + + + SPI2LPEN + SPI2 clock enable during Sleep + mode + 14 + 1 + + + + WWDGLPEN + Window watchdog clock enable during + Sleep mode + 11 + 1 + + + + TIM5LPEN + TIM5 clock enable during Sleep + mode + 3 + 1 + + + + TIM4LPEN + TIM4 clock enable during Sleep + mode + 2 + 1 + + + + TIM3LPEN + TIM3 clock enable during Sleep + mode + 1 + 1 + + + + TIM2LPEN + TIM2 clock enable during Sleep + mode + 0 + 1 + + TIM2LPEN + read-write + + DisabledInSleep + Selected module is disabled during Sleep mode + 0 + + + EnabledInSleep + Selected module is enabled during Sleep mode + 1 + + + + + + + APB2LPENR + APB2LPENR + APB2 peripheral clock enabled in low power + mode register + 0x64 + 0x20 + read-write + 0x00075F33 + + + TIM11LPEN + TIM11 clock enable during Sleep + mode + 18 + 1 + + + + TIM10LPEN + TIM10 clock enable during Sleep + mode + 17 + 1 + + + + TIM9LPEN + TIM9 clock enable during sleep + mode + 16 + 1 + + + + SYSCFGLPEN + System configuration controller clock + enable during Sleep mode + 14 + 1 + + + + SPI1LPEN + SPI 1 clock enable during Sleep + mode + 12 + 1 + + + + SDIOLPEN + SDIO clock enable during Sleep + mode + 11 + 1 + + + + ADC1LPEN + ADC1 clock enable during Sleep + mode + 8 + 1 + + + + USART6LPEN + USART6 clock enable during Sleep + mode + 5 + 1 + + + + USART1LPEN + USART1 clock enable during Sleep + mode + 4 + 1 + + + + TIM1LPEN + TIM1 clock enable during Sleep + mode + 0 + 1 + + TIM1LPEN + read-write + + DisabledInSleep + Selected module is disabled during Sleep mode + 0 + + + EnabledInSleep + Selected module is enabled during Sleep mode + 1 + + + + + SPI4LPEN + SPI4 clock enable during Sleep mode + 13 + 1 + + + + + + BDCR + BDCR + Backup domain control register + 0x70 + 0x20 + 0x00000000 + + + BDRST + Backup domain software + reset + 16 + 1 + read-write + + BDRST + read-write + + Disabled + Reset not activated + 0 + + + Enabled + Reset the entire RTC domain + 1 + + + + + RTCEN + RTC clock enable + 15 + 1 + read-write + + RTCEN + read-write + + Disabled + RTC clock disabled + 0 + + + Enabled + RTC clock enabled + 1 + + + + + LSEBYP + External low-speed oscillator + bypass + 2 + 1 + read-write + + LSEBYP + read-write + + NotBypassed + LSE crystal oscillator not bypassed + 0 + + + Bypassed + LSE crystal oscillator bypassed with external clock + 1 + + + + + LSERDY + External low-speed oscillator + ready + 1 + 1 + read-only + + LSERDYR + read + + NotReady + LSE oscillator not ready + 0 + + + Ready + LSE oscillator ready + 1 + + + + + LSEON + External low-speed oscillator + enable + 0 + 1 + read-write + + LSEON + read-write + + Off + LSE oscillator Off + 0 + + + On + LSE oscillator On + 1 + + + + + RTCSEL + RTC clock source selection + 8 + 2 + + RTCSEL + read-write + + NoClock + No clock + 0 + + + LSE + LSE oscillator clock used as RTC clock + 1 + + + LSI + LSI oscillator clock used as RTC clock + 2 + + + HSE + HSE oscillator clock divided by a prescaler used as RTC clock + 3 + + + + + + + CSR + CSR + clock control & status + register + 0x74 + 0x20 + 0x0E000000 + + + LPWRRSTF + Low-power reset flag + 31 + 1 + read-write + + + + WWDGRSTF + Window watchdog reset flag + 30 + 1 + read-write + + + + WDGRSTF + Independent watchdog reset + flag + 29 + 1 + read-write + + + + SFTRSTF + Software reset flag + 28 + 1 + read-write + + + + PORRSTF + POR/PDR reset flag + 27 + 1 + read-write + + + + PADRSTF + PIN reset flag + 26 + 1 + read-write + + + + BORRSTF + BOR reset flag + 25 + 1 + read-write + + BORRSTFR + read + + NoReset + No reset has occured + 0 + + + Reset + A reset has occured + 1 + + + + + RMVF + Remove reset flag + 24 + 1 + read-write + + RMVFW + write + + Clear + Clears the reset flag + 1 + + + + + LSIRDY + Internal low-speed oscillator + ready + 1 + 1 + read-only + + LSIRDYR + read + + NotReady + LSI oscillator not ready + 0 + + + Ready + LSI oscillator ready + 1 + + + + + LSION + Internal low-speed oscillator + enable + 0 + 1 + read-write + + LSION + read-write + + Off + LSI oscillator Off + 0 + + + On + LSI oscillator On + 1 + + + + + + + SSCGR + SSCGR + spread spectrum clock generation + register + 0x80 + 0x20 + read-write + 0x00000000 + + + SSCGEN + Spread spectrum modulation + enable + 31 + 1 + + SSCGEN + read-write + + Disabled + Spread spectrum modulation disabled + 0 + + + Enabled + Spread spectrum modulation enabled + 1 + + + + + SPREADSEL + Spread Select + 30 + 1 + + SPREADSEL + read-write + + Center + Center spread + 0 + + + Down + Down spread + 1 + + + + + INCSTEP + Incrementation step + 13 + 15 + + + 0 + 32767 + + + + + MODPER + Modulation period + 0 + 13 + + + 0 + 8191 + + + + + + + PLLI2SCFGR + PLLI2SCFGR + PLLI2S configuration register + 0x84 + 0x20 + read-write + 0x20003000 + + + PLLI2SR + PLLI2S division factor for I2S + clocks + 28 + 3 + + + 2 + 7 + + + + + PLLI2SN + PLLI2S multiplication factor for + VCO + 6 + 9 + + + 50 + 432 + + + + + + + DCKCFGR + RCC Dedicated Clock Configuration Register + 0x8C + 0x20 + read-write + 0x00000000 + + + TIMPRE + Timers clocks prescalers selection + 24 + 1 + + TIMPRE + read-write + + Mul1Or2 + If the APB prescaler is configured 1, TIMxCLK = PCLKx. Otherwise, TIMxCLK = 2xPCLKx + 0 + + + Mul1Or4 + If the APB prescaler is configured 1, 2 or 4, TIMxCLK = HCLK. Otherwise, TIMxCLK = 4xPCLKx + 1 + + + + + + + + + RTC + Real-time clock + RTC + 0x40002800 + + 0x0 + 0x400 + registers + + + I2C2_EV + I2C2 event interrupt + 33 + + + I2C2_ER + I2C2 error interrupt + 34 + + + + TR + TR + time register + 0x0 + 0x20 + read-write + 0x00000000 + + + PM + AM/PM notation + 22 + 1 + + PM + read-write + + AM + AM or 24-hour format + 0 + + + PM + PM + 1 + + + + + HT + Hour tens in BCD format + 20 + 2 + + + 0 + 3 + + + + + HU + Hour units in BCD format + 16 + 4 + + + 0 + 15 + + + + + MNT + Minute tens in BCD format + 12 + 3 + + + 0 + 7 + + + + + MNU + Minute units in BCD format + 8 + 4 + + + 0 + 15 + + + + + ST + Second tens in BCD format + 4 + 3 + + + 0 + 7 + + + + + SU + Second units in BCD format + 0 + 4 + + + 0 + 15 + + + + + + + DR + DR + date register + 0x4 + 0x20 + read-write + 0x00002101 + + + YT + Year tens in BCD format + 20 + 4 + + + 0 + 15 + + + + + YU + Year units in BCD format + 16 + 4 + + + 0 + 15 + + + + + WDU + Week day units + 13 + 3 + + + 1 + 7 + + + + + MT + Month tens in BCD format + 12 + 1 + + MT + read-write + + Zero + Month tens is 0 + 0 + + + One + Month tens is 1 + 1 + + + + + MU + Month units in BCD format + 8 + 4 + + + 0 + 15 + + + + + DT + Date tens in BCD format + 4 + 2 + + + 0 + 3 + + + + + DU + Date units in BCD format + 0 + 4 + + + 0 + 15 + + + + + + + CR + CR + control register + 0x8 + 0x20 + read-write + 0x00000000 + + + COE + Calibration output enable + 23 + 1 + + COE + read-write + + Disabled + Calibration output disabled + 0 + + + Enabled + Calibration output enabled + 1 + + + + + OSEL + Output selection + 21 + 2 + + OSEL + read-write + + Disabled + Output disabled + 0 + + + AlarmA + Alarm A output enabled + 1 + + + AlarmB + Alarm B output enabled + 2 + + + Wakeup + Wakeup output enabled + 3 + + + + + POL + Output polarity + 20 + 1 + + POL + read-write + + High + The pin is high when ALRAF/ALRBF/WUTF is asserted (depending on OSEL[1:0]) + 0 + + + Low + The pin is low when ALRAF/ALRBF/WUTF is asserted (depending on OSEL[1:0]) + 1 + + + + + COSEL + Calibration Output + selection + 19 + 1 + + COSEL + read-write + + CalFreq_512Hz + Calibration output is 512 Hz (with default prescaler setting) + 0 + + + CalFreq_1Hz + Calibration output is 1 Hz (with default prescaler setting) + 1 + + + + + BKP + Backup + 18 + 1 + + BKP + read-write + + DST_Not_Changed + Daylight Saving Time change has not been performed + 0 + + + DST_Changed + Daylight Saving Time change has been performed + 1 + + + + + SUB1H + Subtract 1 hour (winter time + change) + 17 + 1 + + SUB1HW + write + + Sub1 + Subtracts 1 hour to the current time. This can be used for winter time change outside initialization mode + 1 + + + + + ADD1H + Add 1 hour (summer time + change) + 16 + 1 + + ADD1HW + write + + Add1 + Adds 1 hour to the current time. This can be used for summer time change outside initialization mode + 1 + + + + + TSIE + Time-stamp interrupt + enable + 15 + 1 + + TSIE + read-write + + Disabled + Time-stamp Interrupt disabled + 0 + + + Enabled + Time-stamp Interrupt enabled + 1 + + + + + WUTIE + Wakeup timer interrupt + enable + 14 + 1 + + WUTIE + read-write + + Disabled + Wakeup timer interrupt disabled + 0 + + + Enabled + Wakeup timer interrupt enabled + 1 + + + + + ALRBIE + Alarm B interrupt enable + 13 + 1 + + ALRBIE + read-write + + Disabled + Alarm B Interrupt disabled + 0 + + + Enabled + Alarm B Interrupt enabled + 1 + + + + + ALRAIE + Alarm A interrupt enable + 12 + 1 + + ALRAIE + read-write + + Disabled + Alarm A interrupt disabled + 0 + + + Enabled + Alarm A interrupt enabled + 1 + + + + + TSE + Time stamp enable + 11 + 1 + + TSE + read-write + + Disabled + Timestamp disabled + 0 + + + Enabled + Timestamp enabled + 1 + + + + + WUTE + Wakeup timer enable + 10 + 1 + + WUTE + read-write + + Disabled + Wakeup timer disabled + 0 + + + Enabled + Wakeup timer enabled + 1 + + + + + ALRBE + Alarm B enable + 9 + 1 + + ALRBE + read-write + + Disabled + Alarm B disabled + 0 + + + Enabled + Alarm B enabled + 1 + + + + + ALRAE + Alarm A enable + 8 + 1 + + ALRAE + read-write + + Disabled + Alarm A disabled + 0 + + + Enabled + Alarm A enabled + 1 + + + + + DCE + Coarse digital calibration + enable + 7 + 1 + + + FMT + Hour format + 6 + 1 + + FMT + read-write + + Twenty_Four_Hour + 24 hour/day format + 0 + + + AM_PM + AM/PM hour format + 1 + + + + + BYPSHAD + Bypass the shadow + registers + 5 + 1 + + BYPSHAD + read-write + + ShadowReg + Calendar values (when reading from RTC_SSR, RTC_TR, and RTC_DR) are taken from the shadow registers, which are updated once every two RTCCLK cycles + 0 + + + BypassShadowReg + Calendar values (when reading from RTC_SSR, RTC_TR, and RTC_DR) are taken directly from the calendar counters + 1 + + + + + REFCKON + Reference clock detection enable (50 or + 60 Hz) + 4 + 1 + + REFCKON + read-write + + Disabled + RTC_REFIN detection disabled + 0 + + + Enabled + RTC_REFIN detection enabled + 1 + + + + + TSEDGE + Time-stamp event active + edge + 3 + 1 + + TSEDGE + read-write + + RisingEdge + RTC_TS input rising edge generates a time-stamp event + 0 + + + FallingEdge + RTC_TS input falling edge generates a time-stamp event + 1 + + + + + WUCKSEL + Wakeup clock selection + 0 + 3 + + WUCKSEL + read-write + + Div16 + RTC/16 clock is selected + 0 + + + Div8 + RTC/8 clock is selected + 1 + + + Div4 + RTC/4 clock is selected + 2 + + + Div2 + RTC/2 clock is selected + 3 + + + ClockSpare + ck_spre (usually 1 Hz) clock is selected + 4 + + + ClockSpareWithOffset + ck_spre (usually 1 Hz) clock is selected and 2^16 is added to the WUT counter value + 6 + + + + + + + ISR + ISR + initialization and status + register + 0xC + 0x20 + 0x00000007 + + + ALRAWF + Alarm A write flag + 0 + 1 + read-only + + ALRAWFR + read + + UpdateNotAllowed + Alarm update not allowed + 0 + + + UpdateAllowed + Alarm update allowed + 1 + + + + + ALRBWF + Alarm B write flag + 1 + 1 + read-only + + + + WUTWF + Wakeup timer write flag + 2 + 1 + read-only + + WUTWFR + read + + UpdateNotAllowed + Wakeup timer configuration update not allowed + 0 + + + UpdateAllowed + Wakeup timer configuration update allowed + 1 + + + + + SHPF + Shift operation pending + 3 + 1 + read-write + + SHPFR + read + + NoShiftPending + No shift operation is pending + 0 + + + ShiftPending + A shift operation is pending + 1 + + + + + INITS + Initialization status flag + 4 + 1 + read-only + + INITSR + read + + NotInitalized + Calendar has not been initialized + 0 + + + Initalized + Calendar has been initialized + 1 + + + + + RSF + Registers synchronization + flag + 5 + 1 + read-write + zeroToClear + + RSFR + read + + NotSynced + Calendar shadow registers not yet synchronized + 0 + + + Synced + Calendar shadow registers synchronized + 1 + + + + RSFW + write + + Clear + This flag is cleared by software by writing 0 + 0 + + + + + INITF + Initialization flag + 6 + 1 + read-only + + INITFR + read + + NotAllowed + Calendar registers update is not allowed + 0 + + + Allowed + Calendar registers update is allowed + 1 + + + + + INIT + Initialization mode + 7 + 1 + read-write + + INIT + read-write + + FreeRunningMode + Free running mode + 0 + + + InitMode + Initialization mode used to program time and date register (RTC_TR and RTC_DR), and prescaler register (RTC_PRER). Counters are stopped and start counting from the new value when INIT is reset. + 1 + + + + + ALRAF + Alarm A flag + 8 + 1 + read-write + zeroToClear + + ALRAFR + read + + Match + This flag is set by hardware when the time/date registers (RTC_TR and RTC_DR) match the Alarm A register (RTC_ALRMAR) + 1 + + + + ALRAFW + write + + Clear + This flag is cleared by software by writing 0 + 0 + + + + + ALRBF + Alarm B flag + 9 + 1 + read-write + zeroToClear + + ALRBFR + read + + Match + This flag is set by hardware when the time/date registers (RTC_TR and RTC_DR) match the Alarm B register (RTC_ALRMBR) + 1 + + + + ALRBFW + write + + Clear + This flag is cleared by software by writing 0 + 0 + + + + + WUTF + Wakeup timer flag + 10 + 1 + read-write + zeroToClear + + WUTFR + read + + Zero + This flag is set by hardware when the wakeup auto-reload counter reaches 0 + 1 + + + + WUTFW + write + + Clear + This flag is cleared by software by writing 0 + 0 + + + + + TSF + Time-stamp flag + 11 + 1 + read-write + zeroToClear + + TSFR + read + + TimestampEvent + This flag is set by hardware when a time-stamp event occurs + 1 + + + + TSFW + write + + Clear + This flag is cleared by software by writing 0 + 0 + + + + + TSOVF + Time-stamp overflow flag + 12 + 1 + read-write + zeroToClear + + TSOVFR + read + + Overflow + This flag is set by hardware when a time-stamp event occurs while TSF is already set + 1 + + + + TSOVFW + write + + Clear + This flag is cleared by software by writing 0 + 0 + + + + + TAMP1F + Tamper detection flag + 13 + 1 + read-write + zeroToClear + + TAMP1FR + read + + Tampered + This flag is set by hardware when a tamper detection event is detected on the RTC_TAMPx input + 1 + + + + TAMP1FW + write + + Clear + Flag cleared by software writing 0 + 0 + + + + + TAMP2F + TAMPER2 detection flag + 14 + 1 + read-write + zeroToClear + + read + + + write + + + + RECALPF + Recalibration pending Flag + 16 + 1 + read-only + + RECALPFR + read + + Pending + The RECALPF status flag is automatically set to 1 when software writes to the RTC_CALR register, indicating that the RTC_CALR register is blocked. When the new calibration settings are taken into account, this bit returns to 0 + 1 + + + + + + + PRER + PRER + prescaler register + 0x10 + 0x20 + read-write + 0x007F00FF + + + PREDIV_A + Asynchronous prescaler + factor + 16 + 7 + + + 0 + 127 + + + + + PREDIV_S + Synchronous prescaler + factor + 0 + 15 + + + 0 + 32767 + + + + + + + WUTR + WUTR + wakeup timer register + 0x14 + 0x20 + read-write + 0x0000FFFF + + + WUT + Wakeup auto-reload value + bits + 0 + 16 + + + 0 + 65535 + + + + + + + CALIBR + CALIBR + calibration register + 0x18 + 0x20 + read-write + 0x00000000 + + + DCS + Digital calibration sign + 7 + 1 + + + DC + Digital calibration + 0 + 5 + + + + + 2 + 0x4 + A,B + ALRM%sR + ALRMAR + Alarm register + 0x1C + 0x20 + read-write + 0x00000000 + + + MSK4 + Alarm date mask + 31 + 1 + + + + WDSEL + Week day selection + 30 + 1 + + WDSEL + read-write + + DateUnits + DU[3:0] represents the date units + 0 + + + WeekDay + DU[3:0] represents the week day. DT[1:0] is don’t care. + 1 + + + + + DT + Date tens in BCD format + 28 + 2 + + + 0 + 3 + + + + + DU + Date units or day in BCD format + 24 + 4 + + + 0 + 15 + + + + + MSK3 + Alarm hours mask + 23 + 1 + + + + PM + AM/PM notation + 22 + 1 + + PM + read-write + + AM + AM or 24-hour format + 0 + + + PM + PM + 1 + + + + + HT + Hour tens in BCD format + 20 + 2 + + + 0 + 3 + + + + + HU + Hour units in BCD format + 16 + 4 + + + 0 + 15 + + + + + MSK2 + Alarm minutes mask + 15 + 1 + + + + MNT + Minute tens in BCD format + 12 + 3 + + + 0 + 7 + + + + + MNU + Minute units in BCD format + 8 + 4 + + + 0 + 15 + + + + + MSK1 + Alarm seconds mask + 7 + 1 + + MSK1 + read-write + + Mask + Alarm set if the date/day match + 0 + + + NotMask + Date/day don’t care in Alarm comparison + 1 + + + + + ST + Second tens in BCD format + 4 + 3 + + + 0 + 7 + + + + + SU + Second units in BCD format + 0 + 4 + + + 0 + 15 + + + + + + + WPR + WPR + write protection register + 0x24 + 0x20 + write-only + 0x00000000 + + + KEY + Write protection key + 0 + 8 + + + 0 + 255 + + + + + + + SSR + SSR + sub second register + 0x28 + 0x20 + read-only + 0x00000000 + + + SS + Sub second value + 0 + 16 + + + 0 + 65535 + + + + + + + SHIFTR + SHIFTR + shift control register + 0x2C + 0x20 + write-only + 0x00000000 + + + ADD1S + Add one second + 31 + 1 + + ADD1SW + write + + Add1 + Add one second to the clock/calendar + 1 + + + + + SUBFS + Subtract a fraction of a + second + 0 + 15 + + + 0 + 32767 + + + + + + + TSTR + TSTR + time stamp time register + 0x30 + + + TSDR + TSDR + time stamp date register + 0x34 + + + TSSSR + TSSSR + timestamp sub second register + 0x38 + + + CALR + CALR + calibration register + 0x3C + 0x20 + read-write + 0x00000000 + + + CALP + Increase frequency of RTC by 488.5 + ppm + 15 + 1 + + CALP + read-write + + NoChange + No RTCCLK pulses are added + 0 + + + IncreaseFreq + One RTCCLK pulse is effectively inserted every 2^11 pulses (frequency increased by 488.5 ppm) + 1 + + + + + CALW8 + Use an 8-second calibration cycle + period + 14 + 1 + + CALW8 + read-write + + Eight_Second + When CALW8 is set to ‘1’, the 8-second calibration cycle period is selected + 1 + + + + + CALW16 + Use a 16-second calibration cycle + period + 13 + 1 + + CALW16 + read-write + + Sixteen_Second + When CALW16 is set to ‘1’, the 16-second calibration cycle period is selected.This bit must not be set to ‘1’ if CALW8=1 + 1 + + + + + CALM + Calibration minus + 0 + 9 + + + 0 + 511 + + + + + + + TAFCR + TAFCR + tamper and alternate function configuration + register + 0x40 + 0x20 + read-write + 0x00000000 + + + ALARMOUTTYPE + AFO_ALARM output type + 18 + 1 + + + TSINSEL + TIMESTAMP mapping + 17 + 1 + + + TAMP1INSEL + TAMPER1 mapping + 16 + 1 + + + TAMPPUDIS + TAMPER pull-up disable + 15 + 1 + + + TAMPPRCH + Tamper precharge duration + 13 + 2 + + + TAMPFLT + Tamper filter count + 11 + 2 + + + TAMPFREQ + Tamper sampling frequency + 8 + 3 + + + TAMPTS + Activate timestamp on tamper detection + event + 7 + 1 + + + TAMP2TRG + Active level for tamper 2 + 4 + 1 + + + TAMP2E + Tamper 2 detection enable + 3 + 1 + + + TAMPIE + Tamper interrupt enable + 2 + 1 + + + TAMP1TRG + Active level for tamper 1 + 1 + 1 + + + TAMP1E + Tamper 1 detection enable + 0 + 1 + + + + + 2 + 0x4 + A,B + ALRM%sSSR + ALRMASSR + Alarm sub-second register + 0x44 + 0x20 + read-write + 0x00000000 + + + MASKSS + Mask the most-significant bits starting + at this bit + 24 + 4 + + + 0 + 15 + + + + + SS + Sub seconds value + 0 + 15 + + + 0 + 32767 + + + + + + + 20 + 0x4 + 0-19 + BKP%sR + BKP0R + backup register + 0x50 + 0x20 + read-write + 0x00000000 + + + BKP + BKP + 0 + 32 + + + 0 + 4294967295 + + + + + + + + + SDIO + Secure digital input/output + interface + SDIO + 0x40012C00 + + 0x0 + 0x400 + registers + + + I2C3_EV + I2C3 event interrupt + 72 + + + I2C3_ER + I2C3 error interrupt + 73 + + + + POWER + POWER + power control register + 0x0 + 0x20 + read-write + 0x00000000 + + + PWRCTRL + PWRCTRL + 0 + 2 + + PWRCTRL + read-write + + PowerOff + Power off + 0 + + + PowerOn + Power on + 3 + + + + + + + CLKCR + CLKCR + SDI clock control register + 0x4 + 0x20 + read-write + 0x00000000 + + + HWFC_EN + HW Flow Control enable + 14 + 1 + + HWFC_EN + read-write + + Disabled + HW Flow Control is disabled + 0 + + + Enabled + HW Flow Control is enabled + 1 + + + + + NEGEDGE + SDIO_CK dephasing selection + bit + 13 + 1 + + NEGEDGE + read-write + + Rising + SDIO_CK generated on the rising edge + 0 + + + Falling + SDIO_CK generated on the falling edge + 1 + + + + + WIDBUS + Wide bus mode enable bit + 11 + 2 + + WIDBUS + read-write + + BusWidth1 + 1 lane wide bus + 0 + + + BusWidth4 + 4 lane wide bus + 1 + + + BusWidth8 + 8 lane wide bus + 2 + + + + + BYPASS + Clock divider bypass enable + bit + 10 + 1 + + BYPASS + read-write + + Disabled + SDIOCLK is divided according to the CLKDIV value before driving the SDIO_CK output signal. + 0 + + + Enabled + SDIOCLK directly drives the SDIO_CK output signal + 1 + + + + + PWRSAV + Power saving configuration + bit + 9 + 1 + + PWRSAV + read-write + + Enabled + SDIO_CK clock is always enabled + 0 + + + Disabled + SDIO_CK is only enabled when the bus is active + 1 + + + + + CLKEN + Clock enable bit + 8 + 1 + + CLKEN + read-write + + Disabled + Disable clock + 0 + + + Enabled + Enable clock + 1 + + + + + CLKDIV + Clock divide factor + 0 + 8 + + + 0 + 255 + + + + + + + ARG + ARG + argument register + 0x8 + 0x20 + read-write + 0x00000000 + + + CMDARG + Command argument + 0 + 32 + + + 0 + 4294967295 + + + + + + + CMD + CMD + command register + 0xC + 0x20 + read-write + 0x00000000 + + + CE_ATACMD + CE-ATA command + 14 + 1 + + CE_ATACMD + read-write + + Disabled + CE-ATA command disabled + 0 + + + Enabled + CE-ATA command enabled + 1 + + + + + nIEN + not Interrupt Enable + 13 + 1 + + nIEN + read-write + + Disabled + Interrupts to the CE-ATA not disabled + 0 + + + Enabled + Interrupt to the CE-ATA are disabled + 1 + + + + + ENCMDcompl + Enable CMD completion + 12 + 1 + + ENCMDcompl + read-write + + Disabled + Command complete signal disabled + 0 + + + Enabled + Command complete signal enabled + 1 + + + + + SDIOSuspend + SD I/O suspend command + 11 + 1 + + SDIOSuspend + read-write + + Disabled + Next command is not a SDIO suspend command + 0 + + + Enabled + Next command send is a SDIO suspend command + 1 + + + + + CPSMEN + Command path state machine (CPSM) Enable + bit + 10 + 1 + + CPSMEN + read-write + + Disabled + Command path state machine disabled + 0 + + + Enabled + Command path state machine enabled + 1 + + + + + WAITPEND + CPSM Waits for ends of data transfer + (CmdPend internal signal). + 9 + 1 + + WAITPEND + read-write + + Disabled + Don't wait for data end + 0 + + + Enabled + Wait for end of data transfer signal before sending command + 1 + + + + + WAITINT + CPSM waits for interrupt + request + 8 + 1 + + WAITINT + read-write + + Disabled + Don't wait for interrupt request + 0 + + + Enabled + Wait for interrupt request + 1 + + + + + WAITRESP + Wait for response bits + 6 + 2 + + WAITRESP + read-write + + NoResponse + No response + 0 + + + ShortResponse + Short response + 1 + + + NoResponse2 + No reponse + 2 + + + LongResponse + Long reponse + 3 + + + + + CMDINDEX + Command index + 0 + 6 + + + 0 + 63 + + + + + + + RESPCMD + RESPCMD + command response register + 0x10 + 0x20 + read-only + 0x00000000 + + + RESPCMD + Response command index + 0 + 6 + + + 0 + 63 + + + + + + + RESP1 + RESP1 + response 1..4 register + 0x14 + 0x20 + read-only + 0x00000000 + + + CARDSTATUS1 + Card Status + 0 + 32 + + + 0 + 4294967295 + + + + + + + RESP2 + RESP2 + response 1..4 register + 0x18 + 0x20 + read-only + 0x00000000 + + + CARDSTATUS2 + Card Status + 0 + 32 + + + 0 + 4294967295 + + + + + + + RESP3 + RESP3 + response 1..4 register + 0x1C + 0x20 + read-only + 0x00000000 + + + CARDSTATUS3 + Card Status + 0 + 32 + + + 0 + 4294967295 + + + + + + + RESP4 + RESP4 + response 1..4 register + 0x20 + 0x20 + read-only + 0x00000000 + + + CARDSTATUS4 + Card Status + 0 + 32 + + + 0 + 4294967295 + + + + + + + DTIMER + DTIMER + data timer register + 0x24 + 0x20 + read-write + 0x00000000 + + + DATATIME + Data timeout period + 0 + 32 + + + 0 + 4294967295 + + + + + + + DLEN + DLEN + data length register + 0x28 + 0x20 + read-write + 0x00000000 + + + DATALENGTH + Data length value + 0 + 25 + + + 0 + 33554431 + + + + + + + DCTRL + DCTRL + data control register + 0x2C + 0x20 + read-write + 0x00000000 + + + SDIOEN + SD I/O enable functions + 11 + 1 + + SDIOEN + read-write + + Disabled + SDIO operations disabled + 0 + + + Enabled + SDIO operations enabled + 1 + + + + + RWMOD + Read wait mode + 10 + 1 + + RWMOD + read-write + + D2 + Read wait control stopping using SDIO_D2 + 0 + + + Ck + Read wait control using SDIO_CK + 1 + + + + + RWSTOP + Read wait stop + 9 + 1 + + RWSTOP + read-write + + Disabled + Read wait in progress if RWSTART is enabled + 0 + + + Enabled + Enable for read wait stop if RWSTART is enabled + 1 + + + + + RWSTART + Read wait start + 8 + 1 + + RWSTART + read-write + + Disabled + Don't start read wait operation + 0 + + + Enabled + Read wait operation starts + 1 + + + + + DBLOCKSIZE + Data block size + 4 + 4 + + + 0 + 15 + + + + + DMAEN + DMA enable bit + 3 + 1 + + DMAEN + read-write + + Disabled + Dma disabled + 0 + + + Enabled + Dma enabled + 1 + + + + + DTMODE + Data transfer mode selection 1: Stream + or SDIO multibyte data transfer. + 2 + 1 + + DTMODE + read-write + + BlockMode + Bloack data transfer + 0 + + + StreamMode + Stream or SDIO multibyte data transfer + 1 + + + + + DTDIR + Data transfer direction + selection + 1 + 1 + + DTDIR + read-write + + ControllerToCard + From controller to card + 0 + + + CardToController + From card to controller + 1 + + + + + DTEN + DTEN + 0 + 1 + + DTEN + read-write + + Disabled + Disabled + 0 + + + Enabled + Start transfer + 1 + + + + + + + DCOUNT + DCOUNT + data counter register + 0x30 + 0x20 + read-only + 0x00000000 + + + DATACOUNT + Data count value + 0 + 25 + + + 0 + 33554431 + + + + + + + STA + STA + status register + 0x34 + 0x20 + read-only + 0x00000000 + + + CEATAEND + CE-ATA command completion signal + received for CMD61 + 23 + 1 + + CEATAEND + read + + NotReceived + Completion signal not received + 0 + + + Received + CE-ATA command completion signal received for CMD61 + 1 + + + + + SDIOIT + SDIO interrupt received + 22 + 1 + + SDIOIT + read + + NotReceived + SDIO interrupt not receieved + 0 + + + Received + SDIO interrupt received + 1 + + + + + RXDAVL + Data available in receive + FIFO + 21 + 1 + + RXDAVL + read + + NotAvailable + Data not available in receive FIFO + 0 + + + Available + Data available in receive FIFO + 1 + + + + + TXDAVL + Data available in transmit + FIFO + 20 + 1 + + TXDAVL + read + + NotAvailable + Data not available in transmit FIFO + 0 + + + Available + Data available in transmit FIFO + 1 + + + + + RXFIFOE + Receive FIFO empty + 19 + 1 + + RXFIFOE + read + + NotEmpty + Receive FIFO not empty + 0 + + + Empty + Receive FIFO empty + 1 + + + + + TXFIFOE + Transmit FIFO empty + 18 + 1 + + TXFIFOE + read + + NotEmpty + Transmit FIFO not empty + 0 + + + Empty + Transmit FIFO empty. When HW Flow Control is enabled, TXFIFOE signals becomes activated when the FIFO contains 2 words. + 1 + + + + + RXFIFOF + Receive FIFO full + 17 + 1 + + RXFIFOF + read + + NotFull + Transmit FIFO not full + 0 + + + Full + Receive FIFO full. When HW Flow Control is enabled, RXFIFOF signals becomes activated 2 words before the FIFO is full. + 1 + + + + + TXFIFOF + Transmit FIFO full + 16 + 1 + + TXFIFOF + read + + NotFull + Transmit FIFO not full + 0 + + + Full + Transmit FIFO full + 1 + + + + + RXFIFOHF + Receive FIFO half full: there are at + least 8 words in the FIFO + 15 + 1 + + RXFIFOHF + read + + NotHalfFull + Receive FIFO not half full + 0 + + + HalfFull + Receive FIFO half full. At least 8 words in the FIFO + 1 + + + + + TXFIFOHE + Transmit FIFO half empty: at least 8 + words can be written into the FIFO + 14 + 1 + + TXFIFOHE + read + + NotHalfEmpty + Transmit FIFO not half empty + 0 + + + HalfEmpty + Transmit FIFO half empty. At least 8 words can be written into the FIFO + 1 + + + + + RXACT + Data receive in progress + 13 + 1 + + RXACT + read + + NotInProgress + Data receive not in progress + 0 + + + InProgress + Data receive in progress + 1 + + + + + TXACT + Data transmit in progress + 12 + 1 + + TXACT + read + + NotInProgress + Data transmit is not in progress + 0 + + + InProgress + Data transmit in progress + 1 + + + + + CMDACT + Command transfer in + progress + 11 + 1 + + CMDACT + read + + NotInProgress + Command transfer not in progress + 0 + + + InProgress + Command tranfer in progress + 1 + + + + + DBCKEND + Data block sent/received (CRC check + passed) + 10 + 1 + + DBCKEND + read + + NotTransferred + Data block not sent/received (CRC check failed) + 0 + + + Transferred + Data block sent/received (CRC check passed) + 1 + + + + + STBITERR + Start bit not detected on all data + signals in wide bus mode + 9 + 1 + + STBITERR + read + + Detected + No start bit detected error + 0 + + + NotDetected + Start bit not detected error + 1 + + + + + DATAEND + Data end (data counter, SDIDCOUNT, is + zero) + 8 + 1 + + DATAEND + read + + NotDone + Not done + 0 + + + Done + Data end (DCOUNT, is zero) + 1 + + + + + CMDSENT + Command sent (no response + required) + 7 + 1 + + CMDSENT + read + + NotSent + Command not sent + 0 + + + Sent + Command sent (no response required) + 1 + + + + + CMDREND + Command response received (CRC check + passed) + 6 + 1 + + CMDREND + read + + NotDone + Command not done + 0 + + + Done + Command response received (CRC check passed) + 1 + + + + + RXOVERR + Received FIFO overrun + error + 5 + 1 + + RXOVERR + read + + NoOverrun + No FIFO overrun error + 0 + + + Overrun + Receive FIFO overrun error + 1 + + + + + TXUNDERR + Transmit FIFO underrun + error + 4 + 1 + + TXUNDERR + read + + NoUnderrun + No transmit FIFO underrun error + 0 + + + Underrun + Transmit FIFO underrun error + 1 + + + + + DTIMEOUT + Data timeout + 3 + 1 + + DTIMEOUT + read + + NoTimeout + No data timeout + 0 + + + Timeout + Data timeout + 1 + + + + + CTIMEOUT + Command response timeout + 2 + 1 + + CTIMEOUT + read + + NoTimeout + No Command timeout + 0 + + + Timeout + Command timeout + 1 + + + + + DCRCFAIL + Data block sent/received (CRC check + failed) + 1 + 1 + + DCRCFAIL + read + + NotFailed + No Data block sent/received crc check fail + 0 + + + Failed + Data block sent/received crc failed + 1 + + + + + CCRCFAIL + Command response received (CRC check + failed) + 0 + 1 + + CCRCFAIL + read + + NotFailed + Command response received, crc check passed + 0 + + + Failed + Command response received, crc check failed + 1 + + + + + + + ICR + ICR + interrupt clear register + 0x38 + 0x20 + read-write + 0x00000000 + + + CEATAENDC + CEATAEND flag clear bit + 23 + 1 + + + + SDIOITC + SDIOIT flag clear bit + 22 + 1 + + + + DBCKENDC + DBCKEND flag clear bit + 10 + 1 + + + + STBITERRC + STBITERR flag clear bit + 9 + 1 + + + + DATAENDC + DATAEND flag clear bit + 8 + 1 + + + + CMDSENTC + CMDSENT flag clear bit + 7 + 1 + + + + CMDRENDC + CMDREND flag clear bit + 6 + 1 + + + + RXOVERRC + RXOVERR flag clear bit + 5 + 1 + + + + TXUNDERRC + TXUNDERR flag clear bit + 4 + 1 + + + + DTIMEOUTC + DTIMEOUT flag clear bit + 3 + 1 + + + + CTIMEOUTC + CTIMEOUT flag clear bit + 2 + 1 + + + + DCRCFAILC + DCRCFAIL flag clear bit + 1 + 1 + + + + CCRCFAILC + CCRCFAIL flag clear bit + 0 + 1 + + CCRCFAILCW + write + + Clear + Clear flag + 1 + + + + + + + MASK + MASK + mask register + 0x3C + 0x20 + read-write + 0x00000000 + + + CEATAENDIE + CE-ATA command completion signal + received interrupt enable + 23 + 1 + + + + SDIOITIE + SDIO mode interrupt received interrupt + enable + 22 + 1 + + + + RXDAVLIE + Data available in Rx FIFO interrupt + enable + 21 + 1 + + + + TXDAVLIE + Data available in Tx FIFO interrupt + enable + 20 + 1 + + + + RXFIFOEIE + Rx FIFO empty interrupt + enable + 19 + 1 + + + + TXFIFOEIE + Tx FIFO empty interrupt + enable + 18 + 1 + + + + RXFIFOFIE + Rx FIFO full interrupt + enable + 17 + 1 + + + + TXFIFOFIE + Tx FIFO full interrupt + enable + 16 + 1 + + + + RXFIFOHFIE + Rx FIFO half full interrupt + enable + 15 + 1 + + + + TXFIFOHEIE + Tx FIFO half empty interrupt + enable + 14 + 1 + + + + RXACTIE + Data receive acting interrupt + enable + 13 + 1 + + + + TXACTIE + Data transmit acting interrupt + enable + 12 + 1 + + + + CMDACTIE + Command acting interrupt + enable + 11 + 1 + + + + DBCKENDIE + Data block end interrupt + enable + 10 + 1 + + + + STBITERRIE + Start bit error interrupt + enable + 9 + 1 + + + + DATAENDIE + Data end interrupt enable + 8 + 1 + + + + CMDSENTIE + Command sent interrupt + enable + 7 + 1 + + + + CMDRENDIE + Command response received interrupt + enable + 6 + 1 + + + + RXOVERRIE + Rx FIFO overrun error interrupt + enable + 5 + 1 + + + + TXUNDERRIE + Tx FIFO underrun error interrupt + enable + 4 + 1 + + + + DTIMEOUTIE + Data timeout interrupt + enable + 3 + 1 + + + + CTIMEOUTIE + Command timeout interrupt + enable + 2 + 1 + + + + DCRCFAILIE + Data CRC fail interrupt + enable + 1 + 1 + + + + CCRCFAILIE + Command CRC fail interrupt + enable + 0 + 1 + + CCRCFAILIE + read-write + + Disabled + Interrupt disabled + 0 + + + Enabled + Interrupt enabled + 1 + + + + + + + FIFOCNT + FIFOCNT + FIFO counter register + 0x48 + 0x20 + read-only + 0x00000000 + + + FIFOCOUNT + Remaining number of words to be written + to or read from the FIFO. + 0 + 24 + + + 0 + 16777215 + + + + + + + FIFO + FIFO + data FIFO register + 0x80 + 0x20 + read-write + 0x00000000 + + + FIFOData + Receive and transmit FIFO + data + 0 + 32 + + + 0 + 4294967295 + + + + + + + + + SYSCFG + System configuration controller + SYSCFG + 0x40013800 + + 0x0 + 0x400 + registers + + + + MEMRM + MEMRM + memory remap register + 0x0 + 0x20 + read-write + 0x00000000 + + + MEM_MODE + MEM_MODE + 0 + 2 + + + + + PMC + PMC + peripheral mode configuration + register + 0x4 + 0x20 + read-write + 0x00000000 + + + ADC1DC2 + ADC1DC2 + 16 + 1 + + + + + EXTICR1 + EXTICR1 + external interrupt configuration register + 1 + 0x8 + 0x20 + read-write + 0x00000000 + + + EXTI3 + EXTI x configuration (x = 0 to + 3) + 12 + 4 + + + EXTI2 + EXTI x configuration (x = 0 to + 3) + 8 + 4 + + + EXTI1 + EXTI x configuration (x = 0 to + 3) + 4 + 4 + + + EXTI0 + EXTI x configuration (x = 0 to + 3) + 0 + 4 + + + + + EXTICR2 + EXTICR2 + external interrupt configuration register + 2 + 0xC + 0x20 + read-write + 0x00000000 + + + EXTI7 + EXTI x configuration (x = 4 to + 7) + 12 + 4 + + + EXTI6 + EXTI x configuration (x = 4 to + 7) + 8 + 4 + + + EXTI5 + EXTI x configuration (x = 4 to + 7) + 4 + 4 + + + EXTI4 + EXTI x configuration (x = 4 to + 7) + 0 + 4 + + + + + EXTICR3 + EXTICR3 + external interrupt configuration register + 3 + 0x10 + 0x20 + read-write + 0x00000000 + + + EXTI11 + EXTI x configuration (x = 8 to + 11) + 12 + 4 + + + EXTI10 + EXTI10 + 8 + 4 + + + EXTI9 + EXTI x configuration (x = 8 to + 11) + 4 + 4 + + + EXTI8 + EXTI x configuration (x = 8 to + 11) + 0 + 4 + + + + + EXTICR4 + EXTICR4 + external interrupt configuration register + 4 + 0x14 + 0x20 + read-write + 0x00000000 + + + EXTI15 + EXTI x configuration (x = 12 to + 15) + 12 + 4 + + + EXTI14 + EXTI x configuration (x = 12 to + 15) + 8 + 4 + + + EXTI13 + EXTI x configuration (x = 12 to + 15) + 4 + 4 + + + EXTI12 + EXTI x configuration (x = 12 to + 15) + 0 + 4 + + + + + CMPCR + CMPCR + Compensation cell control + register + 0x20 + 0x20 + read-only + 0x00000000 + + + READY + READY + 8 + 1 + + + CMP_PD + Compensation cell + power-down + 0 + 1 + + + + + + + TIM1 + Advanced-timers + TIM + 0x40010000 + + 0x0 + 0x400 + registers + + + + CR1 + CR1 + control register 1 + 0x0 + 0x20 + read-write + 0x00000000 + + + CKD + Clock division + 8 + 2 + + CKD + read-write + + Div1 + t_DTS = t_CK_INT + 0 + + + Div2 + t_DTS = 2 × t_CK_INT + 1 + + + Div4 + t_DTS = 4 × t_CK_INT + 2 + + + + + ARPE + Auto-reload preload enable + 7 + 1 + + ARPE + read-write + + Disabled + TIMx_APRR register is not buffered + 0 + + + Enabled + TIMx_APRR register is buffered + 1 + + + + + CMS + Center-aligned mode + selection + 5 + 2 + + CMS + read-write + + EdgeAligned + The counter counts up or down depending on the direction bit + 0 + + + CenterAligned1 + The counter counts up and down alternatively. Output compare interrupt flags are set only when the counter is counting down. + 1 + + + CenterAligned2 + The counter counts up and down alternatively. Output compare interrupt flags are set only when the counter is counting up. + 2 + + + CenterAligned3 + The counter counts up and down alternatively. Output compare interrupt flags are set both when the counter is counting up or down. + 3 + + + + + DIR + Direction + 4 + 1 + + DIR + read-write + + Up + Counter used as upcounter + 0 + + + Down + Counter used as downcounter + 1 + + + + + OPM + One-pulse mode + 3 + 1 + + OPM + read-write + + Disabled + Counter is not stopped at update event + 0 + + + Enabled + Counter stops counting at the next update event (clearing the CEN bit) + 1 + + + + + URS + Update request source + 2 + 1 + + URS + read-write + + AnyEvent + Any of counter overflow/underflow, setting UG, or update through slave mode, generates an update interrupt or DMA request + 0 + + + CounterOnly + Only counter overflow/underflow generates an update interrupt or DMA request + 1 + + + + + UDIS + Update disable + 1 + 1 + + UDIS + read-write + + Enabled + Update event enabled + 0 + + + Disabled + Update event disabled + 1 + + + + + CEN + Counter enable + 0 + 1 + + CEN + read-write + + Disabled + Counter disabled + 0 + + + Enabled + Counter enabled + 1 + + + + + + + CR2 + CR2 + control register 2 + 0x4 + 0x20 + read-write + 0x00000000 + + + OIS4 + Output Idle state 4 + 14 + 1 + + + + OIS3N + Output Idle state 3 + 13 + 1 + + + + OIS3 + Output Idle state 3 + 12 + 1 + + + + OIS2N + Output Idle state 2 + 11 + 1 + + + + OIS2 + Output Idle state 2 + 10 + 1 + + + + OIS1N + Output Idle state 1 + 9 + 1 + + OIS1N + read-write + + Reset + OCxN=0 after a dead-time when MOE=0 + 0 + + + Set + OCxN=1 after a dead-time when MOE=0 + 1 + + + + + OIS1 + Output Idle state 1 + 8 + 1 + + OIS1 + read-write + + Reset + OCx=0 (after a dead-time if OCx(N) is implemented) when MOE=0 + 0 + + + Set + OCx=1 (after a dead-time if OCx(N) is implemented) when MOE=0 + 1 + + + + + TI1S + TI1 selection + 7 + 1 + + TI1S + read-write + + Normal + The TIMx_CH1 pin is connected to TI1 input + 0 + + + XOR + The TIMx_CH1, CH2, CH3 pins are connected to TI1 input + 1 + + + + + MMS + Master mode selection + 4 + 3 + + MMS + read-write + + Reset + The UG bit from the TIMx_EGR register is used as trigger output + 0 + + + Enable + The counter enable signal, CNT_EN, is used as trigger output + 1 + + + Update + The update event is selected as trigger output + 2 + + + ComparePulse + The trigger output send a positive pulse when the CC1IF flag it to be set, as soon as a capture or a compare match occurred + 3 + + + CompareOC1 + OC1REF signal is used as trigger output + 4 + + + CompareOC2 + OC2REF signal is used as trigger output + 5 + + + CompareOC3 + OC3REF signal is used as trigger output + 6 + + + CompareOC4 + OC4REF signal is used as trigger output + 7 + + + + + CCDS + Capture/compare DMA + selection + 3 + 1 + + CCDS + read-write + + OnCompare + CCx DMA request sent when CCx event occurs + 0 + + + OnUpdate + CCx DMA request sent when update event occurs + 1 + + + + + CCUS + Capture/compare control update + selection + 2 + 1 + + + CCPC + Capture/compare preloaded + control + 0 + 1 + + + + + SMCR + SMCR + slave mode control register + 0x8 + 0x20 + read-write + 0x00000000 + + + ETP + External trigger polarity + 15 + 1 + + ETP + read-write + + NotInverted + ETR is noninverted, active at high level or rising edge + 0 + + + Inverted + ETR is inverted, active at low level or falling edge + 1 + + + + + ECE + External clock enable + 14 + 1 + + ECE + read-write + + Disabled + External clock mode 2 disabled + 0 + + + Enabled + External clock mode 2 enabled. The counter is clocked by any active edge on the ETRF signal. + 1 + + + + + ETPS + External trigger prescaler + 12 + 2 + + ETPS + read-write + + Div1 + Prescaler OFF + 0 + + + Div2 + ETRP frequency divided by 2 + 1 + + + Div4 + ETRP frequency divided by 4 + 2 + + + Div8 + ETRP frequency divided by 8 + 3 + + + + + ETF + External trigger filter + 8 + 4 + + ETF + read-write + + NoFilter + No filter, sampling is done at fDTS + 0 + + + FCK_INT_N2 + fSAMPLING=fCK_INT, N=2 + 1 + + + FCK_INT_N4 + fSAMPLING=fCK_INT, N=4 + 2 + + + FCK_INT_N8 + fSAMPLING=fCK_INT, N=8 + 3 + + + FDTS_Div2_N6 + fSAMPLING=fDTS/2, N=6 + 4 + + + FDTS_Div2_N8 + fSAMPLING=fDTS/2, N=8 + 5 + + + FDTS_Div4_N6 + fSAMPLING=fDTS/4, N=6 + 6 + + + FDTS_Div4_N8 + fSAMPLING=fDTS/4, N=8 + 7 + + + FDTS_Div8_N6 + fSAMPLING=fDTS/8, N=6 + 8 + + + FDTS_Div8_N8 + fSAMPLING=fDTS/8, N=8 + 9 + + + FDTS_Div16_N5 + fSAMPLING=fDTS/16, N=5 + 10 + + + FDTS_Div16_N6 + fSAMPLING=fDTS/16, N=6 + 11 + + + FDTS_Div16_N8 + fSAMPLING=fDTS/16, N=8 + 12 + + + FDTS_Div32_N5 + fSAMPLING=fDTS/32, N=5 + 13 + + + FDTS_Div32_N6 + fSAMPLING=fDTS/32, N=6 + 14 + + + FDTS_Div32_N8 + fSAMPLING=fDTS/32, N=8 + 15 + + + + + MSM + Master/Slave mode + 7 + 1 + + MSM + read-write + + NoSync + No action + 0 + + + Sync + The effect of an event on the trigger input (TRGI) is delayed to allow a perfect synchronization between the current timer and its slaves (through TRGO). It is useful if we want to synchronize several timers on a single external event. + 1 + + + + + TS + Trigger selection + 4 + 3 + + TS + read-write + + ITR0 + Internal Trigger 0 (ITR0) + 0 + + + ITR1 + Internal Trigger 1 (ITR1) + 1 + + + ITR2 + Internal Trigger 2 (ITR2) + 2 + + + TI1F_ED + TI1 Edge Detector (TI1F_ED) + 4 + + + TI1FP1 + Filtered Timer Input 1 (TI1FP1) + 5 + + + TI2FP2 + Filtered Timer Input 2 (TI2FP2) + 6 + + + ETRF + External Trigger input (ETRF) + 7 + + + + + SMS + Slave mode selection + 0 + 3 + + SMS + read-write + + Disabled + Slave mode disabled - if CEN = ‘1 then the prescaler is clocked directly by the internal clock. + 0 + + + Encoder_Mode_1 + Encoder mode 1 - Counter counts up/down on TI2FP1 edge depending on TI1FP2 level. + 1 + + + Encoder_Mode_2 + Encoder mode 2 - Counter counts up/down on TI1FP2 edge depending on TI2FP1 level. + 2 + + + Encoder_Mode_3 + Encoder mode 3 - Counter counts up/down on both TI1FP1 and TI2FP2 edges depending on the level of the other input. + 3 + + + Reset_Mode + Reset Mode - Rising edge of the selected trigger input (TRGI) reinitializes the counter and generates an update of the registers. + 4 + + + Gated_Mode + Gated Mode - The counter clock is enabled when the trigger input (TRGI) is high. The counter stops (but is not reset) as soon as the trigger becomes low. Both start and stop of the counter are controlled. + 5 + + + Trigger_Mode + Trigger Mode - The counter starts at a rising edge of the trigger TRGI (but it is not reset). Only the start of the counter is controlled. + 6 + + + Ext_Clock_Mode + External Clock Mode 1 - Rising edges of the selected trigger (TRGI) clock the counter. + 7 + + + + + + + DIER + DIER + DMA/Interrupt enable register + 0xC + 0x20 + read-write + 0x00000000 + + + TDE + Trigger DMA request enable + 14 + 1 + + TDE + read-write + + Disabled + Trigger DMA request disabled + 0 + + + Enabled + Trigger DMA request enabled + 1 + + + + + COMDE + COM DMA request enable + 13 + 1 + + + CC4DE + Capture/Compare 4 DMA request + enable + 12 + 1 + + + + CC3DE + Capture/Compare 3 DMA request + enable + 11 + 1 + + + + CC2DE + Capture/Compare 2 DMA request + enable + 10 + 1 + + + + CC1DE + Capture/Compare 1 DMA request + enable + 9 + 1 + + CC1DE + read-write + + Disabled + CCx DMA request disabled + 0 + + + Enabled + CCx DMA request enabled + 1 + + + + + UDE + Update DMA request enable + 8 + 1 + + UDE + read-write + + Disabled + Update DMA request disabled + 0 + + + Enabled + Update DMA request enabled + 1 + + + + + BIE + Break interrupt enable + 7 + 1 + + + TIE + Trigger interrupt enable + 6 + 1 + + TIE + read-write + + Disabled + Trigger interrupt disabled + 0 + + + Enabled + Trigger interrupt enabled + 1 + + + + + COMIE + COM interrupt enable + 5 + 1 + + + CC4IE + Capture/Compare 4 interrupt + enable + 4 + 1 + + + + CC3IE + Capture/Compare 3 interrupt + enable + 3 + 1 + + + + CC2IE + Capture/Compare 2 interrupt + enable + 2 + 1 + + + + CC1IE + Capture/Compare 1 interrupt + enable + 1 + 1 + + CC1IE + read-write + + Disabled + CCx interrupt disabled + 0 + + + Enabled + CCx interrupt enabled + 1 + + + + + UIE + Update interrupt enable + 0 + 1 + + UIE + read-write + + Disabled + Update interrupt disabled + 0 + + + Enabled + Update interrupt enabled + 1 + + + + + + + SR + SR + status register + 0x10 + 0x20 + read-write + 0x00000000 + + + CC4OF + Capture/Compare 4 overcapture + flag + 12 + 1 + zeroToClear + + read + + + write + + + + CC3OF + Capture/Compare 3 overcapture + flag + 11 + 1 + zeroToClear + + read + + + write + + + + CC2OF + Capture/compare 2 overcapture + flag + 10 + 1 + zeroToClear + + read + + + write + + + + CC1OF + Capture/Compare 1 overcapture + flag + 9 + 1 + zeroToClear + + CC1OFR + read + + Overcapture + The counter value has been captured in TIMx_CCRx register while CCxIF flag was already set + 1 + + + + CC1OFW + write + + Clear + Clear flag + 0 + + + + + BIF + Break interrupt flag + 7 + 1 + + + TIF + Trigger interrupt flag + 6 + 1 + zeroToClear + + TIFR + read + + NoTrigger + No trigger event occurred + 0 + + + Trigger + Trigger interrupt pending + 1 + + + + TIFW + write + + Clear + Clear flag + 0 + + + + + COMIF + COM interrupt flag + 5 + 1 + + + CC4IF + Capture/Compare 4 interrupt + flag + 4 + 1 + zeroToClear + + read + + + write + + + + CC3IF + Capture/Compare 3 interrupt + flag + 3 + 1 + zeroToClear + + read + + + write + + + + CC2IF + Capture/Compare 2 interrupt + flag + 2 + 1 + zeroToClear + + read + + + write + + + + CC1IF + Capture/compare 1 interrupt + flag + 1 + 1 + zeroToClear + + CC1IFR + read + + Match + If CC1 is an output: The content of the counter TIMx_CNT matches the content of the TIMx_CCR1 register. If CC1 is an input: The counter value has been captured in TIMx_CCR1 register. + 1 + + + + CC1IFW + write + + Clear + Clear flag + 0 + + + + + UIF + Update interrupt flag + 0 + 1 + zeroToClear + + UIFR + read + + NoUpdateOccurred + No update occurred + 0 + + + UpdatePending + Update interrupt pending + 1 + + + + UIFW + write + + Clear + Clear flag + 0 + + + + + + + EGR + EGR + event generation register + 0x14 + 0x20 + write-only + 0x00000000 + + + BG + Break generation + 7 + 1 + + + TG + Trigger generation + 6 + 1 + + TGW + write + + Trigger + The TIF flag is set in TIMx_SR register. Related interrupt or DMA transfer can occur if enabled. + 1 + + + + + COMG + Capture/Compare control update + generation + 5 + 1 + + + CC4G + Capture/compare 4 + generation + 4 + 1 + + + + CC3G + Capture/compare 3 + generation + 3 + 1 + + + + CC2G + Capture/compare 2 + generation + 2 + 1 + + + + CC1G + Capture/compare 1 + generation + 1 + 1 + + CC1GW + write + + Trigger + If CC1 is an output: CC1IF flag is set, Corresponding interrupt or DMA request is sent if enabled. If CC1 is an input: The current value of the counter is captured in TIMx_CCR1 register. + 1 + + + + + UG + Update generation + 0 + 1 + + UG + write + + Update + Re-initializes the timer counter and generates an update of the registers. + 1 + + + + + + + CCMR1_Output + CCMR1_Output + capture/compare mode register 1 (output + mode) + 0x18 + 0x20 + read-write + 0x00000000 + + + OC2CE + Output Compare 2 clear + enable + 15 + 1 + + + OC2M + Output Compare 2 mode + 12 + 3 + + + + OC2PE + Output Compare 2 preload + enable + 11 + 1 + + OC2PE + read-write + + Disabled + Preload register on CCR2 disabled. New values written to CCR2 are taken into account immediately + 0 + + + Enabled + Preload register on CCR2 enabled. Preload value is loaded into active register on each update event + 1 + + + + + OC2FE + Output Compare 2 fast + enable + 10 + 1 + + + CC2S + Capture/Compare 2 + selection + 8 + 2 + + CC2S + read-write + + Output + CC2 channel is configured as output + 0 + + + + + OC1CE + Output Compare 1 clear + enable + 7 + 1 + + + OC1M + Output Compare 1 mode + 4 + 3 + + OC1M + read-write + + Frozen + The comparison between the output compare register TIMx_CCRy and the counter TIMx_CNT has no effect on the outputs + 0 + + + ActiveOnMatch + Set channel to active level on match. OCyREF signal is forced high when the counter matches the capture/compare register + 1 + + + InactiveOnMatch + Set channel to inactive level on match. OCyREF signal is forced low when the counter matches the capture/compare register + 2 + + + Toggle + OCyREF toggles when TIMx_CNT=TIMx_CCRy + 3 + + + ForceInactive + OCyREF is forced low + 4 + + + ForceActive + OCyREF is forced high + 5 + + + PwmMode1 + In upcounting, channel is active as long as TIMx_CNT<TIMx_CCRy else inactive. In downcounting, channel is inactive as long as TIMx_CNT>TIMx_CCRy else active + 6 + + + PwmMode2 + Inversely to PwmMode1 + 7 + + + + + OC1PE + Output Compare 1 preload + enable + 3 + 1 + + OC1PE + read-write + + Disabled + Preload register on CCR1 disabled. New values written to CCR1 are taken into account immediately + 0 + + + Enabled + Preload register on CCR1 enabled. Preload value is loaded into active register on each update event + 1 + + + + + OC1FE + Output Compare 1 fast + enable + 2 + 1 + + + CC1S + Capture/Compare 1 + selection + 0 + 2 + + CC1S + read-write + + Output + CC1 channel is configured as output + 0 + + + + + + + CCMR1_Input + CCMR1_Input + capture/compare mode register 1 (input + mode) + CCMR1_Output + 0x18 + 0x20 + read-write + 0x00000000 + + + IC2F + Input capture 2 filter + 12 + 4 + + + 0 + 15 + + + + + IC2PSC + Input capture 2 prescaler + 10 + 2 + + + CC2S + Capture/Compare 2 + selection + 8 + 2 + + CC2S + read-write + + TI2 + CC2 channel is configured as input, IC2 is mapped on TI2 + 1 + + + TI1 + CC2 channel is configured as input, IC2 is mapped on TI1 + 2 + + + TRC + CC2 channel is configured as input, IC2 is mapped on TRC + 3 + + + + + IC1F + Input capture 1 filter + 4 + 4 + + IC1F + read-write + + NoFilter + No filter, sampling is done at fDTS + 0 + + + FCK_INT_N2 + fSAMPLING=fCK_INT, N=2 + 1 + + + FCK_INT_N4 + fSAMPLING=fCK_INT, N=4 + 2 + + + FCK_INT_N8 + fSAMPLING=fCK_INT, N=8 + 3 + + + FDTS_Div2_N6 + fSAMPLING=fDTS/2, N=6 + 4 + + + FDTS_Div2_N8 + fSAMPLING=fDTS/2, N=8 + 5 + + + FDTS_Div4_N6 + fSAMPLING=fDTS/4, N=6 + 6 + + + FDTS_Div4_N8 + fSAMPLING=fDTS/4, N=8 + 7 + + + FDTS_Div8_N6 + fSAMPLING=fDTS/8, N=6 + 8 + + + FDTS_Div8_N8 + fSAMPLING=fDTS/8, N=8 + 9 + + + FDTS_Div16_N5 + fSAMPLING=fDTS/16, N=5 + 10 + + + FDTS_Div16_N6 + fSAMPLING=fDTS/16, N=6 + 11 + + + FDTS_Div16_N8 + fSAMPLING=fDTS/16, N=8 + 12 + + + FDTS_Div32_N5 + fSAMPLING=fDTS/32, N=5 + 13 + + + FDTS_Div32_N6 + fSAMPLING=fDTS/32, N=6 + 14 + + + FDTS_Div32_N8 + fSAMPLING=fDTS/32, N=8 + 15 + + + + + IC1PSC + Input capture 1 prescaler + 2 + 2 + + + CC1S + Capture/Compare 1 + selection + 0 + 2 + + CC1S + read-write + + TI1 + CC1 channel is configured as input, IC1 is mapped on TI1 + 1 + + + TI2 + CC1 channel is configured as input, IC1 is mapped on TI2 + 2 + + + TRC + CC1 channel is configured as input, IC1 is mapped on TRC + 3 + + + + + + + CCMR2_Output + CCMR2_Output + capture/compare mode register 2 (output + mode) + 0x1C + 0x20 + read-write + 0x00000000 + + + OC4CE + Output compare 4 clear + enable + 15 + 1 + + + OC4M + Output compare 4 mode + 12 + 3 + + + + OC4PE + Output compare 4 preload + enable + 11 + 1 + + OC4PE + read-write + + Disabled + Preload register on CCR4 disabled. New values written to CCR4 are taken into account immediately + 0 + + + Enabled + Preload register on CCR4 enabled. Preload value is loaded into active register on each update event + 1 + + + + + OC4FE + Output compare 4 fast + enable + 10 + 1 + + + CC4S + Capture/Compare 4 + selection + 8 + 2 + + CC4S + read-write + + Output + CC4 channel is configured as output + 0 + + + + + OC3CE + Output compare 3 clear + enable + 7 + 1 + + + OC3M + Output compare 3 mode + 4 + 3 + + OC3M + read-write + + Frozen + The comparison between the output compare register TIMx_CCRy and the counter TIMx_CNT has no effect on the outputs + 0 + + + ActiveOnMatch + Set channel to active level on match. OCyREF signal is forced high when the counter matches the capture/compare register + 1 + + + InactiveOnMatch + Set channel to inactive level on match. OCyREF signal is forced low when the counter matches the capture/compare register + 2 + + + Toggle + OCyREF toggles when TIMx_CNT=TIMx_CCRy + 3 + + + ForceInactive + OCyREF is forced low + 4 + + + ForceActive + OCyREF is forced high + 5 + + + PwmMode1 + In upcounting, channel is active as long as TIMx_CNT<TIMx_CCRy else inactive. In downcounting, channel is inactive as long as TIMx_CNT>TIMx_CCRy else active + 6 + + + PwmMode2 + Inversely to PwmMode1 + 7 + + + + + OC3PE + Output compare 3 preload + enable + 3 + 1 + + OC3PE + read-write + + Disabled + Preload register on CCR3 disabled. New values written to CCR3 are taken into account immediately + 0 + + + Enabled + Preload register on CCR3 enabled. Preload value is loaded into active register on each update event + 1 + + + + + OC3FE + Output compare 3 fast + enable + 2 + 1 + + + CC3S + Capture/Compare 3 + selection + 0 + 2 + + CC3S + read-write + + Output + CC3 channel is configured as output + 0 + + + + + + + CCMR2_Input + CCMR2_Input + capture/compare mode register 2 (input + mode) + CCMR2_Output + 0x1C + 0x20 + read-write + 0x00000000 + + + IC4F + Input capture 4 filter + 12 + 4 + + + 0 + 15 + + + + + IC4PSC + Input capture 4 prescaler + 10 + 2 + + + 0 + 3 + + + + + CC4S + Capture/Compare 4 + selection + 8 + 2 + + CC4S + read-write + + TI4 + CC4 channel is configured as input, IC4 is mapped on TI4 + 1 + + + TI3 + CC4 channel is configured as input, IC4 is mapped on TI3 + 2 + + + TRC + CC4 channel is configured as input, IC4 is mapped on TRC + 3 + + + + + IC3F + Input capture 3 filter + 4 + 4 + + + 0 + 15 + + + + + IC3PSC + Input capture 3 prescaler + 2 + 2 + + + 0 + 3 + + + + + CC3S + Capture/compare 3 + selection + 0 + 2 + + CC3S + read-write + + TI3 + CC3 channel is configured as input, IC3 is mapped on TI3 + 1 + + + TI4 + CC3 channel is configured as input, IC3 is mapped on TI4 + 2 + + + TRC + CC3 channel is configured as input, IC3 is mapped on TRC + 3 + + + + + + + CCER + CCER + capture/compare enable + register + 0x20 + 0x20 + read-write + 0x00000000 + + + CC4P + Capture/Compare 3 output + Polarity + 13 + 1 + + + CC4E + Capture/Compare 4 output + enable + 12 + 1 + + + CC3NP + Capture/Compare 3 output + Polarity + 11 + 1 + + + CC3NE + Capture/Compare 3 complementary output + enable + 10 + 1 + + + CC3P + Capture/Compare 3 output + Polarity + 9 + 1 + + + CC3E + Capture/Compare 3 output + enable + 8 + 1 + + + CC2NP + Capture/Compare 2 output + Polarity + 7 + 1 + + + CC2NE + Capture/Compare 2 complementary output + enable + 6 + 1 + + + CC2P + Capture/Compare 2 output + Polarity + 5 + 1 + + + CC2E + Capture/Compare 2 output + enable + 4 + 1 + + + CC1NP + Capture/Compare 1 output + Polarity + 3 + 1 + + + CC1NE + Capture/Compare 1 complementary output + enable + 2 + 1 + + + CC1P + Capture/Compare 1 output + Polarity + 1 + 1 + + + CC1E + Capture/Compare 1 output + enable + 0 + 1 + + + + + CNT + CNT + counter + 0x24 + 0x20 + read-write + 0x00000000 + + + CNT + counter value + 0 + 16 + + + 0 + 65535 + + + + + + + PSC + PSC + prescaler + 0x28 + 0x20 + read-write + 0x00000000 + + + PSC + Prescaler value + 0 + 16 + + + 0 + 65535 + + + + + + + ARR + ARR + auto-reload register + 0x2C + 0x20 + read-write + 0x00000000 + + + ARR + Auto-reload value + 0 + 16 + + + 0 + 65535 + + + + + + + 4 + 0x4 + 1-4 + CCR%s + CCR1 + capture/compare register + 0x34 + 0x20 + read-write + 0x00000000 + + + CCR + Capture/Compare value + 0 + 16 + + + 0 + 65535 + + + + + + + DCR + DCR + DMA control register + 0x48 + 0x20 + read-write + 0x00000000 + + + DBL + DMA burst length + 8 + 5 + + + 0 + 18 + + + + + DBA + DMA base address + 0 + 5 + + + 0 + 31 + + + + + + + DMAR + DMAR + DMA address for full transfer + 0x4C + 0x20 + read-write + 0x00000000 + + + DMAB + DMA register for burst + accesses + 0 + 16 + + + + + RCR + RCR + repetition counter register + 0x30 + 0x20 + read-write + 0x00000000 + + + REP + Repetition counter value + 0 + 8 + + + + + BDTR + BDTR + break and dead-time register + 0x44 + 0x20 + read-write + 0x00000000 + + + MOE + Main output enable + 15 + 1 + + MOE + read-write + + DisabledIdle + OC/OCN are disabled or forced idle depending on OSSI + 0 + + + Enabled + OC/OCN are enabled if CCxE/CCxNE are set + 1 + + + + + AOE + Automatic output enable + 14 + 1 + + AOE + read-write + + Manual + MOE can be set only by software + 0 + + + Automatic + MOE can be set by software or automatically at the next update event (if none of the break inputs BRK and BRK2 is active) + 1 + + + + + BKP + Break polarity + 13 + 1 + + BKP + read-write + + ActiveLow + Break input BRKx is active low + 0 + + + ActiveHigh + Break input BRKx is active high + 1 + + + + + BKE + Break enable + 12 + 1 + + BKE + read-write + + Disabled + Break function x disabled + 0 + + + Enabled + Break function x disabled + 1 + + + + + OSSR + Off-state selection for Run + mode + 11 + 1 + + OSSR + read-write + + Disabled + When inactive, OC/OCN outputs are disabled + 0 + + + IdleLevel + When inactive, OC/OCN outputs are enabled with their inactive level + 1 + + + + + OSSI + Off-state selection for Idle + mode + 10 + 1 + + OSSI + read-write + + Disabled + When inactive, OC/OCN outputs are disabled + 0 + + + IdleLevel + When inactive, OC/OCN outputs are forced to idle level + 1 + + + + + LOCK + Lock configuration + 8 + 2 + + LOCK + read-write + + Off + No bit is write protected + 0 + + + Level1 + Any bits except MOE, OSSR, OSSI and LOCK in TIMx_BDTR register, OISx and OISxN bits in TIMx_CR2 register can no longer be written + 1 + + + Level2 + LOCK Level 1 + CC Polarity bits (CCxP/CCxNP bits in TIMx_CCER register, as long as the related channel is configured in output through the CCxS bits) as well as OSSR and OSSI bits can no longer be written + 2 + + + Level3 + LOCK Level 2 + CC Control bits (OCxM and OCxPE bits in TIMx_CCMRx registers, as long as the related channel is configured in output through the CCxS bits) can no longer be written + 3 + + + + + DTG + Dead-time generator setup + 0 + 8 + + + 0 + 255 + + + + + + + + + TIM10 + General-purpose-timers + TIM + 0x40014400 + + 0x0 + 0x400 + registers + + + SPI1 + SPI1 global interrupt + 35 + + + + CR1 + CR1 + control register 1 + 0x0 + 0x20 + read-write + 0x00000000 + + + CKD + Clock division + 8 + 2 + + CKD + read-write + + Div1 + t_DTS = t_CK_INT + 0 + + + Div2 + t_DTS = 2 × t_CK_INT + 1 + + + Div4 + t_DTS = 4 × t_CK_INT + 2 + + + + + ARPE + Auto-reload preload enable + 7 + 1 + + ARPE + read-write + + Disabled + TIMx_APRR register is not buffered + 0 + + + Enabled + TIMx_APRR register is buffered + 1 + + + + + URS + Update request source + 2 + 1 + + URS + read-write + + AnyEvent + Any of counter overflow/underflow, setting UG, or update through slave mode, generates an update interrupt or DMA request + 0 + + + CounterOnly + Only counter overflow/underflow generates an update interrupt or DMA request + 1 + + + + + UDIS + Update disable + 1 + 1 + + UDIS + read-write + + Enabled + Update event enabled + 0 + + + Disabled + Update event disabled + 1 + + + + + CEN + Counter enable + 0 + 1 + + CEN + read-write + + Disabled + Counter disabled + 0 + + + Enabled + Counter enabled + 1 + + + + + OPM + One-pulse mode + 3 + 1 + + OPM + read-write + + Disabled + Counter is not stopped at update event + 0 + + + Enabled + Counter stops counting at the next update event (clearing the CEN bit) + 1 + + + + + + + DIER + DIER + DMA/Interrupt enable register + 0xC + 0x20 + read-write + 0x00000000 + + + CC1IE + Capture/Compare 1 interrupt + enable + 1 + 1 + + + UIE + Update interrupt enable + 0 + 1 + + UIE + read-write + + Disabled + Update interrupt disabled + 0 + + + Enabled + Update interrupt enabled + 1 + + + + + + + SR + SR + status register + 0x10 + 0x20 + read-write + 0x00000000 + + + CC1OF + Capture/Compare 1 overcapture + flag + 9 + 1 + + + CC1IF + Capture/compare 1 interrupt + flag + 1 + 1 + + + UIF + Update interrupt flag + 0 + 1 + zeroToClear + + UIFR + read + + NoUpdateOccurred + No update occurred + 0 + + + UpdatePending + Update interrupt pending + 1 + + + + UIFW + write + + Clear + Clear flag + 0 + + + + + + + EGR + EGR + event generation register + 0x14 + 0x20 + write-only + 0x00000000 + + + CC1G + Capture/compare 1 + generation + 1 + 1 + + + UG + Update generation + 0 + 1 + + UG + write + + Update + Re-initializes the timer counter and generates an update of the registers. + 1 + + + + + + + CCMR1_Output + CCMR1_Output + capture/compare mode register 1 (output + mode) + 0x18 + 0x20 + read-write + 0x00000000 + + + OC1M + Output Compare 1 mode + 4 + 3 + + OC1M + read-write + + Frozen + The comparison between the output compare register TIMx_CCRy and the counter TIMx_CNT has no effect on the outputs + 0 + + + ActiveOnMatch + Set channel to active level on match. OCyREF signal is forced high when the counter matches the capture/compare register + 1 + + + InactiveOnMatch + Set channel to inactive level on match. OCyREF signal is forced low when the counter matches the capture/compare register + 2 + + + Toggle + OCyREF toggles when TIMx_CNT=TIMx_CCRy + 3 + + + ForceInactive + OCyREF is forced low + 4 + + + ForceActive + OCyREF is forced high + 5 + + + PwmMode1 + In upcounting, channel is active as long as TIMx_CNT<TIMx_CCRy else inactive. In downcounting, channel is inactive as long as TIMx_CNT>TIMx_CCRy else active + 6 + + + PwmMode2 + Inversely to PwmMode1 + 7 + + + + + OC1PE + Output Compare 1 preload + enable + 3 + 1 + + + OC1FE + Output Compare 1 fast + enable + 2 + 1 + + + CC1S + Capture/Compare 1 + selection + 0 + 2 + + + + + CCMR1_Input + CCMR1_Input + capture/compare mode register 1 (input + mode) + CCMR1_Output + 0x18 + 0x20 + read-write + 0x00000000 + + + IC1F + Input capture 1 filter + 4 + 4 + + + IC1PSC + Input capture 1 prescaler + 2 + 2 + + + CC1S + Capture/Compare 1 + selection + 0 + 2 + + + + + CCER + CCER + capture/compare enable + register + 0x20 + 0x20 + read-write + 0x00000000 + + + CC1NP + Capture/Compare 1 output + Polarity + 3 + 1 + + + CC1P + Capture/Compare 1 output + Polarity + 1 + 1 + + + CC1E + Capture/Compare 1 output + enable + 0 + 1 + + + + + CNT + CNT + counter + 0x24 + 0x20 + read-write + 0x00000000 + + + CNT + counter value + 0 + 16 + + + + + PSC + PSC + prescaler + 0x28 + 0x20 + read-write + 0x00000000 + + + PSC + Prescaler value + 0 + 16 + + + 0 + 65535 + + + + + + + ARR + ARR + auto-reload register + 0x2C + 0x20 + read-write + 0x00000000 + + + ARR + Auto-reload value + 0 + 16 + + + + + 1 + 0x0 + 1-1 + CCR%s + CCR1 + capture/compare register + 0x34 + 0x20 + read-write + 0x00000000 + + + CCR + Capture/Compare value + 0 + 16 + + + + + + + TIM11 + General-purpose-timers + TIM + 0x40014800 + + 0x0 + 0x400 + registers + + + SPI2 + SPI2 global interrupt + 36 + + + + CR1 + CR1 + control register 1 + 0x0 + 0x20 + read-write + 0x00000000 + + + CKD + Clock division + 8 + 2 + + CKD + read-write + + Div1 + t_DTS = t_CK_INT + 0 + + + Div2 + t_DTS = 2 × t_CK_INT + 1 + + + Div4 + t_DTS = 4 × t_CK_INT + 2 + + + + + ARPE + Auto-reload preload enable + 7 + 1 + + ARPE + read-write + + Disabled + TIMx_APRR register is not buffered + 0 + + + Enabled + TIMx_APRR register is buffered + 1 + + + + + URS + Update request source + 2 + 1 + + URS + read-write + + AnyEvent + Any of counter overflow/underflow, setting UG, or update through slave mode, generates an update interrupt or DMA request + 0 + + + CounterOnly + Only counter overflow/underflow generates an update interrupt or DMA request + 1 + + + + + UDIS + Update disable + 1 + 1 + + UDIS + read-write + + Enabled + Update event enabled + 0 + + + Disabled + Update event disabled + 1 + + + + + CEN + Counter enable + 0 + 1 + + CEN + read-write + + Disabled + Counter disabled + 0 + + + Enabled + Counter enabled + 1 + + + + + OPM + One-pulse mode + 3 + 1 + + OPM + read-write + + Disabled + Counter is not stopped at update event + 0 + + + Enabled + Counter stops counting at the next update event (clearing the CEN bit) + 1 + + + + + + + DIER + DIER + DMA/Interrupt enable register + 0xC + 0x20 + read-write + 0x00000000 + + + CC1IE + Capture/Compare 1 interrupt + enable + 1 + 1 + + + UIE + Update interrupt enable + 0 + 1 + + UIE + read-write + + Disabled + Update interrupt disabled + 0 + + + Enabled + Update interrupt enabled + 1 + + + + + + + SR + SR + status register + 0x10 + 0x20 + read-write + 0x00000000 + + + CC1OF + Capture/Compare 1 overcapture + flag + 9 + 1 + + + CC1IF + Capture/compare 1 interrupt + flag + 1 + 1 + + + UIF + Update interrupt flag + 0 + 1 + zeroToClear + + UIFR + read + + NoUpdateOccurred + No update occurred + 0 + + + UpdatePending + Update interrupt pending + 1 + + + + UIFW + write + + Clear + Clear flag + 0 + + + + + + + EGR + EGR + event generation register + 0x14 + 0x20 + write-only + 0x00000000 + + + CC1G + Capture/compare 1 + generation + 1 + 1 + + + UG + Update generation + 0 + 1 + + UG + write + + Update + Re-initializes the timer counter and generates an update of the registers. + 1 + + + + + + + CCMR1_Output + CCMR1_Output + capture/compare mode register 1 (output + mode) + 0x18 + 0x20 + read-write + 0x00000000 + + + OC1M + Output Compare 1 mode + 4 + 3 + + OC1M + read-write + + Frozen + The comparison between the output compare register TIMx_CCRy and the counter TIMx_CNT has no effect on the outputs + 0 + + + ActiveOnMatch + Set channel to active level on match. OCyREF signal is forced high when the counter matches the capture/compare register + 1 + + + InactiveOnMatch + Set channel to inactive level on match. OCyREF signal is forced low when the counter matches the capture/compare register + 2 + + + Toggle + OCyREF toggles when TIMx_CNT=TIMx_CCRy + 3 + + + ForceInactive + OCyREF is forced low + 4 + + + ForceActive + OCyREF is forced high + 5 + + + PwmMode1 + In upcounting, channel is active as long as TIMx_CNT<TIMx_CCRy else inactive. In downcounting, channel is inactive as long as TIMx_CNT>TIMx_CCRy else active + 6 + + + PwmMode2 + Inversely to PwmMode1 + 7 + + + + + OC1PE + Output Compare 1 preload + enable + 3 + 1 + + + OC1FE + Output Compare 1 fast + enable + 2 + 1 + + + CC1S + Capture/Compare 1 + selection + 0 + 2 + + + + + CCMR1_Input + CCMR1_Input + capture/compare mode register 1 (input + mode) + CCMR1_Output + 0x18 + 0x20 + read-write + 0x00000000 + + + IC1F + Input capture 1 filter + 4 + 4 + + + IC1PSC + Input capture 1 prescaler + 2 + 2 + + + CC1S + Capture/Compare 1 + selection + 0 + 2 + + + + + CCER + CCER + capture/compare enable + register + 0x20 + 0x20 + read-write + 0x00000000 + + + CC1NP + Capture/Compare 1 output + Polarity + 3 + 1 + + + CC1P + Capture/Compare 1 output + Polarity + 1 + 1 + + + CC1E + Capture/Compare 1 output + enable + 0 + 1 + + + + + CNT + CNT + counter + 0x24 + 0x20 + read-write + 0x00000000 + + + CNT + counter value + 0 + 16 + + + + + PSC + PSC + prescaler + 0x28 + 0x20 + read-write + 0x00000000 + + + PSC + Prescaler value + 0 + 16 + + + 0 + 65535 + + + + + + + ARR + ARR + auto-reload register + 0x2C + 0x20 + read-write + 0x00000000 + + + ARR + Auto-reload value + 0 + 16 + + + + + 1 + 0x0 + 1-1 + CCR%s + CCR1 + capture/compare register + 0x34 + 0x20 + read-write + 0x00000000 + + + CCR + Capture/Compare value + 0 + 16 + + + + + OR + OR + option register + 0x50 + 0x20 + read-write + 0x00000000 + + + RMP + Input 1 remapping + capability + 0 + 2 + + + + + + + TIM2 + General purpose timers + TIM + 0x40000000 + + 0x0 + 0x400 + registers + + + SPI3 + SPI3 global interrupt + 51 + + + + CR1 + CR1 + control register 1 + 0x0 + 0x20 + read-write + 0x00000000 + + + CKD + Clock division + 8 + 2 + + CKD + read-write + + Div1 + t_DTS = t_CK_INT + 0 + + + Div2 + t_DTS = 2 × t_CK_INT + 1 + + + Div4 + t_DTS = 4 × t_CK_INT + 2 + + + + + ARPE + Auto-reload preload enable + 7 + 1 + + ARPE + read-write + + Disabled + TIMx_APRR register is not buffered + 0 + + + Enabled + TIMx_APRR register is buffered + 1 + + + + + CMS + Center-aligned mode + selection + 5 + 2 + + CMS + read-write + + EdgeAligned + The counter counts up or down depending on the direction bit + 0 + + + CenterAligned1 + The counter counts up and down alternatively. Output compare interrupt flags are set only when the counter is counting down. + 1 + + + CenterAligned2 + The counter counts up and down alternatively. Output compare interrupt flags are set only when the counter is counting up. + 2 + + + CenterAligned3 + The counter counts up and down alternatively. Output compare interrupt flags are set both when the counter is counting up or down. + 3 + + + + + DIR + Direction + 4 + 1 + + DIR + read-write + + Up + Counter used as upcounter + 0 + + + Down + Counter used as downcounter + 1 + + + + + OPM + One-pulse mode + 3 + 1 + + OPM + read-write + + Disabled + Counter is not stopped at update event + 0 + + + Enabled + Counter stops counting at the next update event (clearing the CEN bit) + 1 + + + + + URS + Update request source + 2 + 1 + + URS + read-write + + AnyEvent + Any of counter overflow/underflow, setting UG, or update through slave mode, generates an update interrupt or DMA request + 0 + + + CounterOnly + Only counter overflow/underflow generates an update interrupt or DMA request + 1 + + + + + UDIS + Update disable + 1 + 1 + + UDIS + read-write + + Enabled + Update event enabled + 0 + + + Disabled + Update event disabled + 1 + + + + + CEN + Counter enable + 0 + 1 + + CEN + read-write + + Disabled + Counter disabled + 0 + + + Enabled + Counter enabled + 1 + + + + + + + CR2 + CR2 + control register 2 + 0x4 + 0x20 + read-write + 0x00000000 + + + TI1S + TI1 selection + 7 + 1 + + TI1S + read-write + + Normal + The TIMx_CH1 pin is connected to TI1 input + 0 + + + XOR + The TIMx_CH1, CH2, CH3 pins are connected to TI1 input + 1 + + + + + MMS + Master mode selection + 4 + 3 + + MMS + read-write + + Reset + The UG bit from the TIMx_EGR register is used as trigger output + 0 + + + Enable + The counter enable signal, CNT_EN, is used as trigger output + 1 + + + Update + The update event is selected as trigger output + 2 + + + ComparePulse + The trigger output send a positive pulse when the CC1IF flag it to be set, as soon as a capture or a compare match occurred + 3 + + + CompareOC1 + OC1REF signal is used as trigger output + 4 + + + CompareOC2 + OC2REF signal is used as trigger output + 5 + + + CompareOC3 + OC3REF signal is used as trigger output + 6 + + + CompareOC4 + OC4REF signal is used as trigger output + 7 + + + + + CCDS + Capture/compare DMA + selection + 3 + 1 + + CCDS + read-write + + OnCompare + CCx DMA request sent when CCx event occurs + 0 + + + OnUpdate + CCx DMA request sent when update event occurs + 1 + + + + + + + SMCR + SMCR + slave mode control register + 0x8 + 0x20 + read-write + 0x00000000 + + + ETP + External trigger polarity + 15 + 1 + + ETP + read-write + + NotInverted + ETR is noninverted, active at high level or rising edge + 0 + + + Inverted + ETR is inverted, active at low level or falling edge + 1 + + + + + ECE + External clock enable + 14 + 1 + + ECE + read-write + + Disabled + External clock mode 2 disabled + 0 + + + Enabled + External clock mode 2 enabled. The counter is clocked by any active edge on the ETRF signal. + 1 + + + + + ETPS + External trigger prescaler + 12 + 2 + + ETPS + read-write + + Div1 + Prescaler OFF + 0 + + + Div2 + ETRP frequency divided by 2 + 1 + + + Div4 + ETRP frequency divided by 4 + 2 + + + Div8 + ETRP frequency divided by 8 + 3 + + + + + ETF + External trigger filter + 8 + 4 + + ETF + read-write + + NoFilter + No filter, sampling is done at fDTS + 0 + + + FCK_INT_N2 + fSAMPLING=fCK_INT, N=2 + 1 + + + FCK_INT_N4 + fSAMPLING=fCK_INT, N=4 + 2 + + + FCK_INT_N8 + fSAMPLING=fCK_INT, N=8 + 3 + + + FDTS_Div2_N6 + fSAMPLING=fDTS/2, N=6 + 4 + + + FDTS_Div2_N8 + fSAMPLING=fDTS/2, N=8 + 5 + + + FDTS_Div4_N6 + fSAMPLING=fDTS/4, N=6 + 6 + + + FDTS_Div4_N8 + fSAMPLING=fDTS/4, N=8 + 7 + + + FDTS_Div8_N6 + fSAMPLING=fDTS/8, N=6 + 8 + + + FDTS_Div8_N8 + fSAMPLING=fDTS/8, N=8 + 9 + + + FDTS_Div16_N5 + fSAMPLING=fDTS/16, N=5 + 10 + + + FDTS_Div16_N6 + fSAMPLING=fDTS/16, N=6 + 11 + + + FDTS_Div16_N8 + fSAMPLING=fDTS/16, N=8 + 12 + + + FDTS_Div32_N5 + fSAMPLING=fDTS/32, N=5 + 13 + + + FDTS_Div32_N6 + fSAMPLING=fDTS/32, N=6 + 14 + + + FDTS_Div32_N8 + fSAMPLING=fDTS/32, N=8 + 15 + + + + + MSM + Master/Slave mode + 7 + 1 + + MSM + read-write + + NoSync + No action + 0 + + + Sync + The effect of an event on the trigger input (TRGI) is delayed to allow a perfect synchronization between the current timer and its slaves (through TRGO). It is useful if we want to synchronize several timers on a single external event. + 1 + + + + + TS + Trigger selection + 4 + 3 + + TS + read-write + + ITR0 + Internal Trigger 0 (ITR0) + 0 + + + ITR1 + Internal Trigger 1 (ITR1) + 1 + + + ITR2 + Internal Trigger 2 (ITR2) + 2 + + + TI1F_ED + TI1 Edge Detector (TI1F_ED) + 4 + + + TI1FP1 + Filtered Timer Input 1 (TI1FP1) + 5 + + + TI2FP2 + Filtered Timer Input 2 (TI2FP2) + 6 + + + ETRF + External Trigger input (ETRF) + 7 + + + + + SMS + Slave mode selection + 0 + 3 + + SMS + read-write + + Disabled + Slave mode disabled - if CEN = ‘1 then the prescaler is clocked directly by the internal clock. + 0 + + + Encoder_Mode_1 + Encoder mode 1 - Counter counts up/down on TI2FP1 edge depending on TI1FP2 level. + 1 + + + Encoder_Mode_2 + Encoder mode 2 - Counter counts up/down on TI1FP2 edge depending on TI2FP1 level. + 2 + + + Encoder_Mode_3 + Encoder mode 3 - Counter counts up/down on both TI1FP1 and TI2FP2 edges depending on the level of the other input. + 3 + + + Reset_Mode + Reset Mode - Rising edge of the selected trigger input (TRGI) reinitializes the counter and generates an update of the registers. + 4 + + + Gated_Mode + Gated Mode - The counter clock is enabled when the trigger input (TRGI) is high. The counter stops (but is not reset) as soon as the trigger becomes low. Both start and stop of the counter are controlled. + 5 + + + Trigger_Mode + Trigger Mode - The counter starts at a rising edge of the trigger TRGI (but it is not reset). Only the start of the counter is controlled. + 6 + + + Ext_Clock_Mode + External Clock Mode 1 - Rising edges of the selected trigger (TRGI) clock the counter. + 7 + + + + + + + DIER + DIER + DMA/Interrupt enable register + 0xC + 0x20 + read-write + 0x00000000 + + + TDE + Trigger DMA request enable + 14 + 1 + + TDE + read-write + + Disabled + Trigger DMA request disabled + 0 + + + Enabled + Trigger DMA request enabled + 1 + + + + + CC4DE + Capture/Compare 4 DMA request + enable + 12 + 1 + + + + CC3DE + Capture/Compare 3 DMA request + enable + 11 + 1 + + + + CC2DE + Capture/Compare 2 DMA request + enable + 10 + 1 + + + + CC1DE + Capture/Compare 1 DMA request + enable + 9 + 1 + + CC1DE + read-write + + Disabled + CCx DMA request disabled + 0 + + + Enabled + CCx DMA request enabled + 1 + + + + + UDE + Update DMA request enable + 8 + 1 + + UDE + read-write + + Disabled + Update DMA request disabled + 0 + + + Enabled + Update DMA request enabled + 1 + + + + + TIE + Trigger interrupt enable + 6 + 1 + + TIE + read-write + + Disabled + Trigger interrupt disabled + 0 + + + Enabled + Trigger interrupt enabled + 1 + + + + + CC4IE + Capture/Compare 4 interrupt + enable + 4 + 1 + + + + CC3IE + Capture/Compare 3 interrupt + enable + 3 + 1 + + + + CC2IE + Capture/Compare 2 interrupt + enable + 2 + 1 + + + + CC1IE + Capture/Compare 1 interrupt + enable + 1 + 1 + + CC1IE + read-write + + Disabled + CCx interrupt disabled + 0 + + + Enabled + CCx interrupt enabled + 1 + + + + + UIE + Update interrupt enable + 0 + 1 + + UIE + read-write + + Disabled + Update interrupt disabled + 0 + + + Enabled + Update interrupt enabled + 1 + + + + + + + SR + SR + status register + 0x10 + 0x20 + read-write + 0x00000000 + + + CC4OF + Capture/Compare 4 overcapture + flag + 12 + 1 + zeroToClear + + read + + + write + + + + CC3OF + Capture/Compare 3 overcapture + flag + 11 + 1 + zeroToClear + + read + + + write + + + + CC2OF + Capture/compare 2 overcapture + flag + 10 + 1 + zeroToClear + + read + + + write + + + + CC1OF + Capture/Compare 1 overcapture + flag + 9 + 1 + zeroToClear + + CC1OFR + read + + Overcapture + The counter value has been captured in TIMx_CCRx register while CCxIF flag was already set + 1 + + + + CC1OFW + write + + Clear + Clear flag + 0 + + + + + TIF + Trigger interrupt flag + 6 + 1 + zeroToClear + + TIFR + read + + NoTrigger + No trigger event occurred + 0 + + + Trigger + Trigger interrupt pending + 1 + + + + TIFW + write + + Clear + Clear flag + 0 + + + + + CC4IF + Capture/Compare 4 interrupt + flag + 4 + 1 + zeroToClear + + read + + + write + + + + CC3IF + Capture/Compare 3 interrupt + flag + 3 + 1 + zeroToClear + + read + + + write + + + + CC2IF + Capture/Compare 2 interrupt + flag + 2 + 1 + zeroToClear + + read + + + write + + + + CC1IF + Capture/compare 1 interrupt + flag + 1 + 1 + zeroToClear + + CC1IFR + read + + Match + If CC1 is an output: The content of the counter TIMx_CNT matches the content of the TIMx_CCR1 register. If CC1 is an input: The counter value has been captured in TIMx_CCR1 register. + 1 + + + + CC1IFW + write + + Clear + Clear flag + 0 + + + + + UIF + Update interrupt flag + 0 + 1 + zeroToClear + + UIFR + read + + NoUpdateOccurred + No update occurred + 0 + + + UpdatePending + Update interrupt pending + 1 + + + + UIFW + write + + Clear + Clear flag + 0 + + + + + + + EGR + EGR + event generation register + 0x14 + 0x20 + write-only + 0x00000000 + + + TG + Trigger generation + 6 + 1 + + TGW + write + + Trigger + The TIF flag is set in TIMx_SR register. Related interrupt or DMA transfer can occur if enabled. + 1 + + + + + CC4G + Capture/compare 4 + generation + 4 + 1 + + + + CC3G + Capture/compare 3 + generation + 3 + 1 + + + + CC2G + Capture/compare 2 + generation + 2 + 1 + + + + CC1G + Capture/compare 1 + generation + 1 + 1 + + CC1GW + write + + Trigger + If CC1 is an output: CC1IF flag is set, Corresponding interrupt or DMA request is sent if enabled. If CC1 is an input: The current value of the counter is captured in TIMx_CCR1 register. + 1 + + + + + UG + Update generation + 0 + 1 + + UG + write + + Update + Re-initializes the timer counter and generates an update of the registers. + 1 + + + + + + + CCMR1_Output + CCMR1_Output + capture/compare mode register 1 (output + mode) + 0x18 + 0x20 + read-write + 0x00000000 + + + OC2CE + OC2CE + 15 + 1 + + + OC2M + OC2M + 12 + 3 + + + + OC2PE + OC2PE + 11 + 1 + + OC2PE + read-write + + Disabled + Preload register on CCR2 disabled. New values written to CCR2 are taken into account immediately + 0 + + + Enabled + Preload register on CCR2 enabled. Preload value is loaded into active register on each update event + 1 + + + + + OC2FE + OC2FE + 10 + 1 + + + CC2S + CC2S + 8 + 2 + + CC2S + read-write + + Output + CC2 channel is configured as output + 0 + + + + + OC1CE + OC1CE + 7 + 1 + + + OC1M + OC1M + 4 + 3 + + OC1M + read-write + + Frozen + The comparison between the output compare register TIMx_CCRy and the counter TIMx_CNT has no effect on the outputs + 0 + + + ActiveOnMatch + Set channel to active level on match. OCyREF signal is forced high when the counter matches the capture/compare register + 1 + + + InactiveOnMatch + Set channel to inactive level on match. OCyREF signal is forced low when the counter matches the capture/compare register + 2 + + + Toggle + OCyREF toggles when TIMx_CNT=TIMx_CCRy + 3 + + + ForceInactive + OCyREF is forced low + 4 + + + ForceActive + OCyREF is forced high + 5 + + + PwmMode1 + In upcounting, channel is active as long as TIMx_CNT<TIMx_CCRy else inactive. In downcounting, channel is inactive as long as TIMx_CNT>TIMx_CCRy else active + 6 + + + PwmMode2 + Inversely to PwmMode1 + 7 + + + + + OC1PE + OC1PE + 3 + 1 + + OC1PE + read-write + + Disabled + Preload register on CCR1 disabled. New values written to CCR1 are taken into account immediately + 0 + + + Enabled + Preload register on CCR1 enabled. Preload value is loaded into active register on each update event + 1 + + + + + OC1FE + OC1FE + 2 + 1 + + + CC1S + CC1S + 0 + 2 + + CC1S + read-write + + Output + CC1 channel is configured as output + 0 + + + + + + + CCMR1_Input + CCMR1_Input + capture/compare mode register 1 (input + mode) + CCMR1_Output + 0x18 + 0x20 + read-write + 0x00000000 + + + IC2F + Input capture 2 filter + 12 + 4 + + + 0 + 15 + + + + + IC2PSC + Input capture 2 prescaler + 10 + 2 + + + CC2S + Capture/Compare 2 + selection + 8 + 2 + + CC2S + read-write + + TI2 + CC2 channel is configured as input, IC2 is mapped on TI2 + 1 + + + TI1 + CC2 channel is configured as input, IC2 is mapped on TI1 + 2 + + + TRC + CC2 channel is configured as input, IC2 is mapped on TRC + 3 + + + + + IC1F + Input capture 1 filter + 4 + 4 + + IC1F + read-write + + NoFilter + No filter, sampling is done at fDTS + 0 + + + FCK_INT_N2 + fSAMPLING=fCK_INT, N=2 + 1 + + + FCK_INT_N4 + fSAMPLING=fCK_INT, N=4 + 2 + + + FCK_INT_N8 + fSAMPLING=fCK_INT, N=8 + 3 + + + FDTS_Div2_N6 + fSAMPLING=fDTS/2, N=6 + 4 + + + FDTS_Div2_N8 + fSAMPLING=fDTS/2, N=8 + 5 + + + FDTS_Div4_N6 + fSAMPLING=fDTS/4, N=6 + 6 + + + FDTS_Div4_N8 + fSAMPLING=fDTS/4, N=8 + 7 + + + FDTS_Div8_N6 + fSAMPLING=fDTS/8, N=6 + 8 + + + FDTS_Div8_N8 + fSAMPLING=fDTS/8, N=8 + 9 + + + FDTS_Div16_N5 + fSAMPLING=fDTS/16, N=5 + 10 + + + FDTS_Div16_N6 + fSAMPLING=fDTS/16, N=6 + 11 + + + FDTS_Div16_N8 + fSAMPLING=fDTS/16, N=8 + 12 + + + FDTS_Div32_N5 + fSAMPLING=fDTS/32, N=5 + 13 + + + FDTS_Div32_N6 + fSAMPLING=fDTS/32, N=6 + 14 + + + FDTS_Div32_N8 + fSAMPLING=fDTS/32, N=8 + 15 + + + + + IC1PSC + Input capture 1 prescaler + 2 + 2 + + + CC1S + Capture/Compare 1 + selection + 0 + 2 + + CC1S + read-write + + TI1 + CC1 channel is configured as input, IC1 is mapped on TI1 + 1 + + + TI2 + CC1 channel is configured as input, IC1 is mapped on TI2 + 2 + + + TRC + CC1 channel is configured as input, IC1 is mapped on TRC + 3 + + + + + + + CCMR2_Output + CCMR2_Output + capture/compare mode register 2 (output + mode) + 0x1C + 0x20 + read-write + 0x00000000 + + + OC4CE + O24CE + 15 + 1 + + + OC4M + OC4M + 12 + 3 + + + + OC4PE + OC4PE + 11 + 1 + + OC4PE + read-write + + Disabled + Preload register on CCR4 disabled. New values written to CCR4 are taken into account immediately + 0 + + + Enabled + Preload register on CCR4 enabled. Preload value is loaded into active register on each update event + 1 + + + + + OC4FE + OC4FE + 10 + 1 + + + CC4S + CC4S + 8 + 2 + + CC4S + read-write + + Output + CC4 channel is configured as output + 0 + + + + + OC3CE + OC3CE + 7 + 1 + + + OC3M + OC3M + 4 + 3 + + OC3M + read-write + + Frozen + The comparison between the output compare register TIMx_CCRy and the counter TIMx_CNT has no effect on the outputs + 0 + + + ActiveOnMatch + Set channel to active level on match. OCyREF signal is forced high when the counter matches the capture/compare register + 1 + + + InactiveOnMatch + Set channel to inactive level on match. OCyREF signal is forced low when the counter matches the capture/compare register + 2 + + + Toggle + OCyREF toggles when TIMx_CNT=TIMx_CCRy + 3 + + + ForceInactive + OCyREF is forced low + 4 + + + ForceActive + OCyREF is forced high + 5 + + + PwmMode1 + In upcounting, channel is active as long as TIMx_CNT<TIMx_CCRy else inactive. In downcounting, channel is inactive as long as TIMx_CNT>TIMx_CCRy else active + 6 + + + PwmMode2 + Inversely to PwmMode1 + 7 + + + + + OC3PE + OC3PE + 3 + 1 + + OC3PE + read-write + + Disabled + Preload register on CCR3 disabled. New values written to CCR3 are taken into account immediately + 0 + + + Enabled + Preload register on CCR3 enabled. Preload value is loaded into active register on each update event + 1 + + + + + OC3FE + OC3FE + 2 + 1 + + + CC3S + CC3S + 0 + 2 + + CC3S + read-write + + Output + CC3 channel is configured as output + 0 + + + + + + + CCMR2_Input + CCMR2_Input + capture/compare mode register 2 (input + mode) + CCMR2_Output + 0x1C + 0x20 + read-write + 0x00000000 + + + IC4F + Input capture 4 filter + 12 + 4 + + + 0 + 15 + + + + + IC4PSC + Input capture 4 prescaler + 10 + 2 + + + 0 + 3 + + + + + CC4S + Capture/Compare 4 + selection + 8 + 2 + + CC4S + read-write + + TI4 + CC4 channel is configured as input, IC4 is mapped on TI4 + 1 + + + TI3 + CC4 channel is configured as input, IC4 is mapped on TI3 + 2 + + + TRC + CC4 channel is configured as input, IC4 is mapped on TRC + 3 + + + + + IC3F + Input capture 3 filter + 4 + 4 + + + 0 + 15 + + + + + IC3PSC + Input capture 3 prescaler + 2 + 2 + + + 0 + 3 + + + + + CC3S + Capture/compare 3 + selection + 0 + 2 + + CC3S + read-write + + TI3 + CC3 channel is configured as input, IC3 is mapped on TI3 + 1 + + + TI4 + CC3 channel is configured as input, IC3 is mapped on TI4 + 2 + + + TRC + CC3 channel is configured as input, IC3 is mapped on TRC + 3 + + + + + + + CCER + CCER + capture/compare enable + register + 0x20 + 0x20 + read-write + 0x00000000 + + + CC4NP + Capture/Compare 4 output + Polarity + 15 + 1 + + + CC4P + Capture/Compare 3 output + Polarity + 13 + 1 + + + CC4E + Capture/Compare 4 output + enable + 12 + 1 + + + CC3NP + Capture/Compare 3 output + Polarity + 11 + 1 + + + CC3P + Capture/Compare 3 output + Polarity + 9 + 1 + + + CC3E + Capture/Compare 3 output + enable + 8 + 1 + + + CC2NP + Capture/Compare 2 output + Polarity + 7 + 1 + + + CC2P + Capture/Compare 2 output + Polarity + 5 + 1 + + + CC2E + Capture/Compare 2 output + enable + 4 + 1 + + + CC1NP + Capture/Compare 1 output + Polarity + 3 + 1 + + + CC1P + Capture/Compare 1 output + Polarity + 1 + 1 + + + CC1E + Capture/Compare 1 output + enable + 0 + 1 + + + + + CNT + CNT + counter + 0x24 + 0x20 + read-write + 0x00000000 + + + CNT + Counter value + 0 + 32 + + + 0 + 4294967295 + + + + + + + PSC + PSC + prescaler + 0x28 + 0x20 + read-write + 0x00000000 + + + PSC + Prescaler value + 0 + 16 + + + 0 + 65535 + + + + + + + ARR + ARR + auto-reload register + 0x2C + 0x20 + read-write + 0x00000000 + + + ARR + Auto-reload value + 0 + 32 + + + 0 + 4294967295 + + + + + + + 4 + 0x4 + 1-4 + CCR%s + CCR1 + capture/compare register + 0x34 + 0x20 + read-write + 0x00000000 + + + CCR + Capture/Compare value + 0 + 32 + + + 0 + 4294967295 + + + + + + + DCR + DCR + DMA control register + 0x48 + 0x20 + read-write + 0x00000000 + + + DBL + DMA burst length + 8 + 5 + + + 0 + 18 + + + + + DBA + DMA base address + 0 + 5 + + + 0 + 31 + + + + + + + DMAR + DMAR + DMA address for full transfer + 0x4C + 0x20 + read-write + 0x00000000 + + + DMAB + DMA register for burst + accesses + 0 + 16 + + + + + OR + OR + TIM5 option register + 0x50 + 0x20 + read-write + 0x00000000 + + + ITR1_RMP + Timer Input 4 remap + 10 + 2 + + + + + + + TIM3 + General purpose timers + TIM + 0x40000400 + + 0x0 + 0x400 + registers + + + SPI4 + SPI4 global interrupt + 84 + + + TIM4 + TIM4 global interrupt + 30 + + + TIM5 + TIM5 global interrupt + 50 + + + + CR1 + CR1 + control register 1 + 0x0 + 0x20 + read-write + 0x00000000 + + + CKD + Clock division + 8 + 2 + + CKD + read-write + + Div1 + t_DTS = t_CK_INT + 0 + + + Div2 + t_DTS = 2 × t_CK_INT + 1 + + + Div4 + t_DTS = 4 × t_CK_INT + 2 + + + + + ARPE + Auto-reload preload enable + 7 + 1 + + ARPE + read-write + + Disabled + TIMx_APRR register is not buffered + 0 + + + Enabled + TIMx_APRR register is buffered + 1 + + + + + CMS + Center-aligned mode + selection + 5 + 2 + + CMS + read-write + + EdgeAligned + The counter counts up or down depending on the direction bit + 0 + + + CenterAligned1 + The counter counts up and down alternatively. Output compare interrupt flags are set only when the counter is counting down. + 1 + + + CenterAligned2 + The counter counts up and down alternatively. Output compare interrupt flags are set only when the counter is counting up. + 2 + + + CenterAligned3 + The counter counts up and down alternatively. Output compare interrupt flags are set both when the counter is counting up or down. + 3 + + + + + DIR + Direction + 4 + 1 + + DIR + read-write + + Up + Counter used as upcounter + 0 + + + Down + Counter used as downcounter + 1 + + + + + OPM + One-pulse mode + 3 + 1 + + OPM + read-write + + Disabled + Counter is not stopped at update event + 0 + + + Enabled + Counter stops counting at the next update event (clearing the CEN bit) + 1 + + + + + URS + Update request source + 2 + 1 + + URS + read-write + + AnyEvent + Any of counter overflow/underflow, setting UG, or update through slave mode, generates an update interrupt or DMA request + 0 + + + CounterOnly + Only counter overflow/underflow generates an update interrupt or DMA request + 1 + + + + + UDIS + Update disable + 1 + 1 + + UDIS + read-write + + Enabled + Update event enabled + 0 + + + Disabled + Update event disabled + 1 + + + + + CEN + Counter enable + 0 + 1 + + CEN + read-write + + Disabled + Counter disabled + 0 + + + Enabled + Counter enabled + 1 + + + + + + + CR2 + CR2 + control register 2 + 0x4 + 0x20 + read-write + 0x00000000 + + + TI1S + TI1 selection + 7 + 1 + + TI1S + read-write + + Normal + The TIMx_CH1 pin is connected to TI1 input + 0 + + + XOR + The TIMx_CH1, CH2, CH3 pins are connected to TI1 input + 1 + + + + + MMS + Master mode selection + 4 + 3 + + MMS + read-write + + Reset + The UG bit from the TIMx_EGR register is used as trigger output + 0 + + + Enable + The counter enable signal, CNT_EN, is used as trigger output + 1 + + + Update + The update event is selected as trigger output + 2 + + + ComparePulse + The trigger output send a positive pulse when the CC1IF flag it to be set, as soon as a capture or a compare match occurred + 3 + + + CompareOC1 + OC1REF signal is used as trigger output + 4 + + + CompareOC2 + OC2REF signal is used as trigger output + 5 + + + CompareOC3 + OC3REF signal is used as trigger output + 6 + + + CompareOC4 + OC4REF signal is used as trigger output + 7 + + + + + CCDS + Capture/compare DMA + selection + 3 + 1 + + CCDS + read-write + + OnCompare + CCx DMA request sent when CCx event occurs + 0 + + + OnUpdate + CCx DMA request sent when update event occurs + 1 + + + + + + + SMCR + SMCR + slave mode control register + 0x8 + 0x20 + read-write + 0x00000000 + + + ETP + External trigger polarity + 15 + 1 + + ETP + read-write + + NotInverted + ETR is noninverted, active at high level or rising edge + 0 + + + Inverted + ETR is inverted, active at low level or falling edge + 1 + + + + + ECE + External clock enable + 14 + 1 + + ECE + read-write + + Disabled + External clock mode 2 disabled + 0 + + + Enabled + External clock mode 2 enabled. The counter is clocked by any active edge on the ETRF signal. + 1 + + + + + ETPS + External trigger prescaler + 12 + 2 + + ETPS + read-write + + Div1 + Prescaler OFF + 0 + + + Div2 + ETRP frequency divided by 2 + 1 + + + Div4 + ETRP frequency divided by 4 + 2 + + + Div8 + ETRP frequency divided by 8 + 3 + + + + + ETF + External trigger filter + 8 + 4 + + ETF + read-write + + NoFilter + No filter, sampling is done at fDTS + 0 + + + FCK_INT_N2 + fSAMPLING=fCK_INT, N=2 + 1 + + + FCK_INT_N4 + fSAMPLING=fCK_INT, N=4 + 2 + + + FCK_INT_N8 + fSAMPLING=fCK_INT, N=8 + 3 + + + FDTS_Div2_N6 + fSAMPLING=fDTS/2, N=6 + 4 + + + FDTS_Div2_N8 + fSAMPLING=fDTS/2, N=8 + 5 + + + FDTS_Div4_N6 + fSAMPLING=fDTS/4, N=6 + 6 + + + FDTS_Div4_N8 + fSAMPLING=fDTS/4, N=8 + 7 + + + FDTS_Div8_N6 + fSAMPLING=fDTS/8, N=6 + 8 + + + FDTS_Div8_N8 + fSAMPLING=fDTS/8, N=8 + 9 + + + FDTS_Div16_N5 + fSAMPLING=fDTS/16, N=5 + 10 + + + FDTS_Div16_N6 + fSAMPLING=fDTS/16, N=6 + 11 + + + FDTS_Div16_N8 + fSAMPLING=fDTS/16, N=8 + 12 + + + FDTS_Div32_N5 + fSAMPLING=fDTS/32, N=5 + 13 + + + FDTS_Div32_N6 + fSAMPLING=fDTS/32, N=6 + 14 + + + FDTS_Div32_N8 + fSAMPLING=fDTS/32, N=8 + 15 + + + + + MSM + Master/Slave mode + 7 + 1 + + MSM + read-write + + NoSync + No action + 0 + + + Sync + The effect of an event on the trigger input (TRGI) is delayed to allow a perfect synchronization between the current timer and its slaves (through TRGO). It is useful if we want to synchronize several timers on a single external event. + 1 + + + + + TS + Trigger selection + 4 + 3 + + TS + read-write + + ITR0 + Internal Trigger 0 (ITR0) + 0 + + + ITR1 + Internal Trigger 1 (ITR1) + 1 + + + ITR2 + Internal Trigger 2 (ITR2) + 2 + + + TI1F_ED + TI1 Edge Detector (TI1F_ED) + 4 + + + TI1FP1 + Filtered Timer Input 1 (TI1FP1) + 5 + + + TI2FP2 + Filtered Timer Input 2 (TI2FP2) + 6 + + + ETRF + External Trigger input (ETRF) + 7 + + + + + SMS + Slave mode selection + 0 + 3 + + SMS + read-write + + Disabled + Slave mode disabled - if CEN = ‘1 then the prescaler is clocked directly by the internal clock. + 0 + + + Encoder_Mode_1 + Encoder mode 1 - Counter counts up/down on TI2FP1 edge depending on TI1FP2 level. + 1 + + + Encoder_Mode_2 + Encoder mode 2 - Counter counts up/down on TI1FP2 edge depending on TI2FP1 level. + 2 + + + Encoder_Mode_3 + Encoder mode 3 - Counter counts up/down on both TI1FP1 and TI2FP2 edges depending on the level of the other input. + 3 + + + Reset_Mode + Reset Mode - Rising edge of the selected trigger input (TRGI) reinitializes the counter and generates an update of the registers. + 4 + + + Gated_Mode + Gated Mode - The counter clock is enabled when the trigger input (TRGI) is high. The counter stops (but is not reset) as soon as the trigger becomes low. Both start and stop of the counter are controlled. + 5 + + + Trigger_Mode + Trigger Mode - The counter starts at a rising edge of the trigger TRGI (but it is not reset). Only the start of the counter is controlled. + 6 + + + Ext_Clock_Mode + External Clock Mode 1 - Rising edges of the selected trigger (TRGI) clock the counter. + 7 + + + + + + + DIER + DIER + DMA/Interrupt enable register + 0xC + 0x20 + read-write + 0x00000000 + + + TDE + Trigger DMA request enable + 14 + 1 + + TDE + read-write + + Disabled + Trigger DMA request disabled + 0 + + + Enabled + Trigger DMA request enabled + 1 + + + + + CC4DE + Capture/Compare 4 DMA request + enable + 12 + 1 + + + + CC3DE + Capture/Compare 3 DMA request + enable + 11 + 1 + + + + CC2DE + Capture/Compare 2 DMA request + enable + 10 + 1 + + + + CC1DE + Capture/Compare 1 DMA request + enable + 9 + 1 + + CC1DE + read-write + + Disabled + CCx DMA request disabled + 0 + + + Enabled + CCx DMA request enabled + 1 + + + + + UDE + Update DMA request enable + 8 + 1 + + UDE + read-write + + Disabled + Update DMA request disabled + 0 + + + Enabled + Update DMA request enabled + 1 + + + + + TIE + Trigger interrupt enable + 6 + 1 + + TIE + read-write + + Disabled + Trigger interrupt disabled + 0 + + + Enabled + Trigger interrupt enabled + 1 + + + + + CC4IE + Capture/Compare 4 interrupt + enable + 4 + 1 + + + + CC3IE + Capture/Compare 3 interrupt + enable + 3 + 1 + + + + CC2IE + Capture/Compare 2 interrupt + enable + 2 + 1 + + + + CC1IE + Capture/Compare 1 interrupt + enable + 1 + 1 + + CC1IE + read-write + + Disabled + CCx interrupt disabled + 0 + + + Enabled + CCx interrupt enabled + 1 + + + + + UIE + Update interrupt enable + 0 + 1 + + UIE + read-write + + Disabled + Update interrupt disabled + 0 + + + Enabled + Update interrupt enabled + 1 + + + + + + + SR + SR + status register + 0x10 + 0x20 + read-write + 0x00000000 + + + CC4OF + Capture/Compare 4 overcapture + flag + 12 + 1 + zeroToClear + + read + + + write + + + + CC3OF + Capture/Compare 3 overcapture + flag + 11 + 1 + zeroToClear + + read + + + write + + + + CC2OF + Capture/compare 2 overcapture + flag + 10 + 1 + zeroToClear + + read + + + write + + + + CC1OF + Capture/Compare 1 overcapture + flag + 9 + 1 + zeroToClear + + CC1OFR + read + + Overcapture + The counter value has been captured in TIMx_CCRx register while CCxIF flag was already set + 1 + + + + CC1OFW + write + + Clear + Clear flag + 0 + + + + + TIF + Trigger interrupt flag + 6 + 1 + zeroToClear + + TIFR + read + + NoTrigger + No trigger event occurred + 0 + + + Trigger + Trigger interrupt pending + 1 + + + + TIFW + write + + Clear + Clear flag + 0 + + + + + CC4IF + Capture/Compare 4 interrupt + flag + 4 + 1 + zeroToClear + + read + + + write + + + + CC3IF + Capture/Compare 3 interrupt + flag + 3 + 1 + zeroToClear + + read + + + write + + + + CC2IF + Capture/Compare 2 interrupt + flag + 2 + 1 + zeroToClear + + read + + + write + + + + CC1IF + Capture/compare 1 interrupt + flag + 1 + 1 + zeroToClear + + CC1IFR + read + + Match + If CC1 is an output: The content of the counter TIMx_CNT matches the content of the TIMx_CCR1 register. If CC1 is an input: The counter value has been captured in TIMx_CCR1 register. + 1 + + + + CC1IFW + write + + Clear + Clear flag + 0 + + + + + UIF + Update interrupt flag + 0 + 1 + zeroToClear + + UIFR + read + + NoUpdateOccurred + No update occurred + 0 + + + UpdatePending + Update interrupt pending + 1 + + + + UIFW + write + + Clear + Clear flag + 0 + + + + + + + EGR + EGR + event generation register + 0x14 + 0x20 + write-only + 0x00000000 + + + TG + Trigger generation + 6 + 1 + + TGW + write + + Trigger + The TIF flag is set in TIMx_SR register. Related interrupt or DMA transfer can occur if enabled. + 1 + + + + + CC4G + Capture/compare 4 + generation + 4 + 1 + + + + CC3G + Capture/compare 3 + generation + 3 + 1 + + + + CC2G + Capture/compare 2 + generation + 2 + 1 + + + + CC1G + Capture/compare 1 + generation + 1 + 1 + + CC1GW + write + + Trigger + If CC1 is an output: CC1IF flag is set, Corresponding interrupt or DMA request is sent if enabled. If CC1 is an input: The current value of the counter is captured in TIMx_CCR1 register. + 1 + + + + + UG + Update generation + 0 + 1 + + UG + write + + Update + Re-initializes the timer counter and generates an update of the registers. + 1 + + + + + + + CCMR1_Output + CCMR1_Output + capture/compare mode register 1 (output + mode) + 0x18 + 0x20 + read-write + 0x00000000 + + + OC2CE + OC2CE + 15 + 1 + + + OC2M + OC2M + 12 + 3 + + + + OC2PE + OC2PE + 11 + 1 + + OC2PE + read-write + + Disabled + Preload register on CCR2 disabled. New values written to CCR2 are taken into account immediately + 0 + + + Enabled + Preload register on CCR2 enabled. Preload value is loaded into active register on each update event + 1 + + + + + OC2FE + OC2FE + 10 + 1 + + + CC2S + CC2S + 8 + 2 + + CC2S + read-write + + Output + CC2 channel is configured as output + 0 + + + + + OC1CE + OC1CE + 7 + 1 + + + OC1M + OC1M + 4 + 3 + + OC1M + read-write + + Frozen + The comparison between the output compare register TIMx_CCRy and the counter TIMx_CNT has no effect on the outputs + 0 + + + ActiveOnMatch + Set channel to active level on match. OCyREF signal is forced high when the counter matches the capture/compare register + 1 + + + InactiveOnMatch + Set channel to inactive level on match. OCyREF signal is forced low when the counter matches the capture/compare register + 2 + + + Toggle + OCyREF toggles when TIMx_CNT=TIMx_CCRy + 3 + + + ForceInactive + OCyREF is forced low + 4 + + + ForceActive + OCyREF is forced high + 5 + + + PwmMode1 + In upcounting, channel is active as long as TIMx_CNT<TIMx_CCRy else inactive. In downcounting, channel is inactive as long as TIMx_CNT>TIMx_CCRy else active + 6 + + + PwmMode2 + Inversely to PwmMode1 + 7 + + + + + OC1PE + OC1PE + 3 + 1 + + OC1PE + read-write + + Disabled + Preload register on CCR1 disabled. New values written to CCR1 are taken into account immediately + 0 + + + Enabled + Preload register on CCR1 enabled. Preload value is loaded into active register on each update event + 1 + + + + + OC1FE + OC1FE + 2 + 1 + + + CC1S + CC1S + 0 + 2 + + CC1S + read-write + + Output + CC1 channel is configured as output + 0 + + + + + + + CCMR1_Input + CCMR1_Input + capture/compare mode register 1 (input + mode) + CCMR1_Output + 0x18 + 0x20 + read-write + 0x00000000 + + + IC2F + Input capture 2 filter + 12 + 4 + + + 0 + 15 + + + + + IC2PSC + Input capture 2 prescaler + 10 + 2 + + + CC2S + Capture/Compare 2 + selection + 8 + 2 + + CC2S + read-write + + TI2 + CC2 channel is configured as input, IC2 is mapped on TI2 + 1 + + + TI1 + CC2 channel is configured as input, IC2 is mapped on TI1 + 2 + + + TRC + CC2 channel is configured as input, IC2 is mapped on TRC + 3 + + + + + IC1F + Input capture 1 filter + 4 + 4 + + IC1F + read-write + + NoFilter + No filter, sampling is done at fDTS + 0 + + + FCK_INT_N2 + fSAMPLING=fCK_INT, N=2 + 1 + + + FCK_INT_N4 + fSAMPLING=fCK_INT, N=4 + 2 + + + FCK_INT_N8 + fSAMPLING=fCK_INT, N=8 + 3 + + + FDTS_Div2_N6 + fSAMPLING=fDTS/2, N=6 + 4 + + + FDTS_Div2_N8 + fSAMPLING=fDTS/2, N=8 + 5 + + + FDTS_Div4_N6 + fSAMPLING=fDTS/4, N=6 + 6 + + + FDTS_Div4_N8 + fSAMPLING=fDTS/4, N=8 + 7 + + + FDTS_Div8_N6 + fSAMPLING=fDTS/8, N=6 + 8 + + + FDTS_Div8_N8 + fSAMPLING=fDTS/8, N=8 + 9 + + + FDTS_Div16_N5 + fSAMPLING=fDTS/16, N=5 + 10 + + + FDTS_Div16_N6 + fSAMPLING=fDTS/16, N=6 + 11 + + + FDTS_Div16_N8 + fSAMPLING=fDTS/16, N=8 + 12 + + + FDTS_Div32_N5 + fSAMPLING=fDTS/32, N=5 + 13 + + + FDTS_Div32_N6 + fSAMPLING=fDTS/32, N=6 + 14 + + + FDTS_Div32_N8 + fSAMPLING=fDTS/32, N=8 + 15 + + + + + IC1PSC + Input capture 1 prescaler + 2 + 2 + + + CC1S + Capture/Compare 1 + selection + 0 + 2 + + CC1S + read-write + + TI1 + CC1 channel is configured as input, IC1 is mapped on TI1 + 1 + + + TI2 + CC1 channel is configured as input, IC1 is mapped on TI2 + 2 + + + TRC + CC1 channel is configured as input, IC1 is mapped on TRC + 3 + + + + + + + CCMR2_Output + CCMR2_Output + capture/compare mode register 2 (output + mode) + 0x1C + 0x20 + read-write + 0x00000000 + + + OC4CE + O24CE + 15 + 1 + + + OC4M + OC4M + 12 + 3 + + + + OC4PE + OC4PE + 11 + 1 + + OC4PE + read-write + + Disabled + Preload register on CCR4 disabled. New values written to CCR4 are taken into account immediately + 0 + + + Enabled + Preload register on CCR4 enabled. Preload value is loaded into active register on each update event + 1 + + + + + OC4FE + OC4FE + 10 + 1 + + + CC4S + CC4S + 8 + 2 + + CC4S + read-write + + Output + CC4 channel is configured as output + 0 + + + + + OC3CE + OC3CE + 7 + 1 + + + OC3M + OC3M + 4 + 3 + + OC3M + read-write + + Frozen + The comparison between the output compare register TIMx_CCRy and the counter TIMx_CNT has no effect on the outputs + 0 + + + ActiveOnMatch + Set channel to active level on match. OCyREF signal is forced high when the counter matches the capture/compare register + 1 + + + InactiveOnMatch + Set channel to inactive level on match. OCyREF signal is forced low when the counter matches the capture/compare register + 2 + + + Toggle + OCyREF toggles when TIMx_CNT=TIMx_CCRy + 3 + + + ForceInactive + OCyREF is forced low + 4 + + + ForceActive + OCyREF is forced high + 5 + + + PwmMode1 + In upcounting, channel is active as long as TIMx_CNT<TIMx_CCRy else inactive. In downcounting, channel is inactive as long as TIMx_CNT>TIMx_CCRy else active + 6 + + + PwmMode2 + Inversely to PwmMode1 + 7 + + + + + OC3PE + OC3PE + 3 + 1 + + OC3PE + read-write + + Disabled + Preload register on CCR3 disabled. New values written to CCR3 are taken into account immediately + 0 + + + Enabled + Preload register on CCR3 enabled. Preload value is loaded into active register on each update event + 1 + + + + + OC3FE + OC3FE + 2 + 1 + + + CC3S + CC3S + 0 + 2 + + CC3S + read-write + + Output + CC3 channel is configured as output + 0 + + + + + + + CCMR2_Input + CCMR2_Input + capture/compare mode register 2 (input + mode) + CCMR2_Output + 0x1C + 0x20 + read-write + 0x00000000 + + + IC4F + Input capture 4 filter + 12 + 4 + + + 0 + 15 + + + + + IC4PSC + Input capture 4 prescaler + 10 + 2 + + + 0 + 3 + + + + + CC4S + Capture/Compare 4 + selection + 8 + 2 + + CC4S + read-write + + TI4 + CC4 channel is configured as input, IC4 is mapped on TI4 + 1 + + + TI3 + CC4 channel is configured as input, IC4 is mapped on TI3 + 2 + + + TRC + CC4 channel is configured as input, IC4 is mapped on TRC + 3 + + + + + IC3F + Input capture 3 filter + 4 + 4 + + + 0 + 15 + + + + + IC3PSC + Input capture 3 prescaler + 2 + 2 + + + 0 + 3 + + + + + CC3S + Capture/compare 3 + selection + 0 + 2 + + CC3S + read-write + + TI3 + CC3 channel is configured as input, IC3 is mapped on TI3 + 1 + + + TI4 + CC3 channel is configured as input, IC3 is mapped on TI4 + 2 + + + TRC + CC3 channel is configured as input, IC3 is mapped on TRC + 3 + + + + + + + CCER + CCER + capture/compare enable + register + 0x20 + 0x20 + read-write + 0x00000000 + + + CC4NP + Capture/Compare 4 output + Polarity + 15 + 1 + + + CC4P + Capture/Compare 3 output + Polarity + 13 + 1 + + + CC4E + Capture/Compare 4 output + enable + 12 + 1 + + + CC3NP + Capture/Compare 3 output + Polarity + 11 + 1 + + + CC3P + Capture/Compare 3 output + Polarity + 9 + 1 + + + CC3E + Capture/Compare 3 output + enable + 8 + 1 + + + CC2NP + Capture/Compare 2 output + Polarity + 7 + 1 + + + CC2P + Capture/Compare 2 output + Polarity + 5 + 1 + + + CC2E + Capture/Compare 2 output + enable + 4 + 1 + + + CC1NP + Capture/Compare 1 output + Polarity + 3 + 1 + + + CC1P + Capture/Compare 1 output + Polarity + 1 + 1 + + + CC1E + Capture/Compare 1 output + enable + 0 + 1 + + + + + CNT + CNT + counter + 0x24 + 0x20 + read-write + 0x00000000 + + + CNT + Counter value + 0 + 16 + + + 0 + 65535 + + + + + + + PSC + PSC + prescaler + 0x28 + 0x20 + read-write + 0x00000000 + + + PSC + Prescaler value + 0 + 16 + + + 0 + 65535 + + + + + + + ARR + ARR + auto-reload register + 0x2C + 0x20 + read-write + 0x00000000 + + + ARR + Auto-reload value + 0 + 16 + + + 0 + 65535 + + + + + + + 4 + 0x4 + 1-4 + CCR%s + CCR1 + capture/compare register + 0x34 + 0x20 + read-write + 0x00000000 + + + CCR + Capture/Compare value + 0 + 16 + + + 0 + 65535 + + + + + + + DCR + DCR + DMA control register + 0x48 + 0x20 + read-write + 0x00000000 + + + DBL + DMA burst length + 8 + 5 + + + 0 + 18 + + + + + DBA + DMA base address + 0 + 5 + + + 0 + 31 + + + + + + + DMAR + DMAR + DMA address for full transfer + 0x4C + 0x20 + read-write + 0x00000000 + + + DMAB + DMA register for burst + accesses + 0 + 16 + + + + + + + TIM4 + TIM + 0x40000800 + + + TIM5 + General-purpose-timers + TIM + 0x40000C00 + + 0x0 + 0x400 + registers + + + + CR1 + CR1 + control register 1 + 0x0 + 0x20 + read-write + 0x00000000 + + + CKD + Clock division + 8 + 2 + + CKD + read-write + + Div1 + t_DTS = t_CK_INT + 0 + + + Div2 + t_DTS = 2 × t_CK_INT + 1 + + + Div4 + t_DTS = 4 × t_CK_INT + 2 + + + + + ARPE + Auto-reload preload enable + 7 + 1 + + ARPE + read-write + + Disabled + TIMx_APRR register is not buffered + 0 + + + Enabled + TIMx_APRR register is buffered + 1 + + + + + CMS + Center-aligned mode + selection + 5 + 2 + + CMS + read-write + + EdgeAligned + The counter counts up or down depending on the direction bit + 0 + + + CenterAligned1 + The counter counts up and down alternatively. Output compare interrupt flags are set only when the counter is counting down. + 1 + + + CenterAligned2 + The counter counts up and down alternatively. Output compare interrupt flags are set only when the counter is counting up. + 2 + + + CenterAligned3 + The counter counts up and down alternatively. Output compare interrupt flags are set both when the counter is counting up or down. + 3 + + + + + DIR + Direction + 4 + 1 + + DIR + read-write + + Up + Counter used as upcounter + 0 + + + Down + Counter used as downcounter + 1 + + + + + OPM + One-pulse mode + 3 + 1 + + OPM + read-write + + Disabled + Counter is not stopped at update event + 0 + + + Enabled + Counter stops counting at the next update event (clearing the CEN bit) + 1 + + + + + URS + Update request source + 2 + 1 + + URS + read-write + + AnyEvent + Any of counter overflow/underflow, setting UG, or update through slave mode, generates an update interrupt or DMA request + 0 + + + CounterOnly + Only counter overflow/underflow generates an update interrupt or DMA request + 1 + + + + + UDIS + Update disable + 1 + 1 + + UDIS + read-write + + Enabled + Update event enabled + 0 + + + Disabled + Update event disabled + 1 + + + + + CEN + Counter enable + 0 + 1 + + CEN + read-write + + Disabled + Counter disabled + 0 + + + Enabled + Counter enabled + 1 + + + + + + + CR2 + CR2 + control register 2 + 0x4 + 0x20 + read-write + 0x00000000 + + + TI1S + TI1 selection + 7 + 1 + + TI1S + read-write + + Normal + The TIMx_CH1 pin is connected to TI1 input + 0 + + + XOR + The TIMx_CH1, CH2, CH3 pins are connected to TI1 input + 1 + + + + + MMS + Master mode selection + 4 + 3 + + MMS + read-write + + Reset + The UG bit from the TIMx_EGR register is used as trigger output + 0 + + + Enable + The counter enable signal, CNT_EN, is used as trigger output + 1 + + + Update + The update event is selected as trigger output + 2 + + + ComparePulse + The trigger output send a positive pulse when the CC1IF flag it to be set, as soon as a capture or a compare match occurred + 3 + + + CompareOC1 + OC1REF signal is used as trigger output + 4 + + + CompareOC2 + OC2REF signal is used as trigger output + 5 + + + CompareOC3 + OC3REF signal is used as trigger output + 6 + + + CompareOC4 + OC4REF signal is used as trigger output + 7 + + + + + CCDS + Capture/compare DMA + selection + 3 + 1 + + CCDS + read-write + + OnCompare + CCx DMA request sent when CCx event occurs + 0 + + + OnUpdate + CCx DMA request sent when update event occurs + 1 + + + + + + + SMCR + SMCR + slave mode control register + 0x8 + 0x20 + read-write + 0x00000000 + + + ETP + External trigger polarity + 15 + 1 + + ETP + read-write + + NotInverted + ETR is noninverted, active at high level or rising edge + 0 + + + Inverted + ETR is inverted, active at low level or falling edge + 1 + + + + + ECE + External clock enable + 14 + 1 + + ECE + read-write + + Disabled + External clock mode 2 disabled + 0 + + + Enabled + External clock mode 2 enabled. The counter is clocked by any active edge on the ETRF signal. + 1 + + + + + ETPS + External trigger prescaler + 12 + 2 + + ETPS + read-write + + Div1 + Prescaler OFF + 0 + + + Div2 + ETRP frequency divided by 2 + 1 + + + Div4 + ETRP frequency divided by 4 + 2 + + + Div8 + ETRP frequency divided by 8 + 3 + + + + + ETF + External trigger filter + 8 + 4 + + ETF + read-write + + NoFilter + No filter, sampling is done at fDTS + 0 + + + FCK_INT_N2 + fSAMPLING=fCK_INT, N=2 + 1 + + + FCK_INT_N4 + fSAMPLING=fCK_INT, N=4 + 2 + + + FCK_INT_N8 + fSAMPLING=fCK_INT, N=8 + 3 + + + FDTS_Div2_N6 + fSAMPLING=fDTS/2, N=6 + 4 + + + FDTS_Div2_N8 + fSAMPLING=fDTS/2, N=8 + 5 + + + FDTS_Div4_N6 + fSAMPLING=fDTS/4, N=6 + 6 + + + FDTS_Div4_N8 + fSAMPLING=fDTS/4, N=8 + 7 + + + FDTS_Div8_N6 + fSAMPLING=fDTS/8, N=6 + 8 + + + FDTS_Div8_N8 + fSAMPLING=fDTS/8, N=8 + 9 + + + FDTS_Div16_N5 + fSAMPLING=fDTS/16, N=5 + 10 + + + FDTS_Div16_N6 + fSAMPLING=fDTS/16, N=6 + 11 + + + FDTS_Div16_N8 + fSAMPLING=fDTS/16, N=8 + 12 + + + FDTS_Div32_N5 + fSAMPLING=fDTS/32, N=5 + 13 + + + FDTS_Div32_N6 + fSAMPLING=fDTS/32, N=6 + 14 + + + FDTS_Div32_N8 + fSAMPLING=fDTS/32, N=8 + 15 + + + + + MSM + Master/Slave mode + 7 + 1 + + MSM + read-write + + NoSync + No action + 0 + + + Sync + The effect of an event on the trigger input (TRGI) is delayed to allow a perfect synchronization between the current timer and its slaves (through TRGO). It is useful if we want to synchronize several timers on a single external event. + 1 + + + + + TS + Trigger selection + 4 + 3 + + TS + read-write + + ITR0 + Internal Trigger 0 (ITR0) + 0 + + + ITR1 + Internal Trigger 1 (ITR1) + 1 + + + ITR2 + Internal Trigger 2 (ITR2) + 2 + + + TI1F_ED + TI1 Edge Detector (TI1F_ED) + 4 + + + TI1FP1 + Filtered Timer Input 1 (TI1FP1) + 5 + + + TI2FP2 + Filtered Timer Input 2 (TI2FP2) + 6 + + + ETRF + External Trigger input (ETRF) + 7 + + + + + SMS + Slave mode selection + 0 + 3 + + SMS + read-write + + Disabled + Slave mode disabled - if CEN = ‘1 then the prescaler is clocked directly by the internal clock. + 0 + + + Encoder_Mode_1 + Encoder mode 1 - Counter counts up/down on TI2FP1 edge depending on TI1FP2 level. + 1 + + + Encoder_Mode_2 + Encoder mode 2 - Counter counts up/down on TI1FP2 edge depending on TI2FP1 level. + 2 + + + Encoder_Mode_3 + Encoder mode 3 - Counter counts up/down on both TI1FP1 and TI2FP2 edges depending on the level of the other input. + 3 + + + Reset_Mode + Reset Mode - Rising edge of the selected trigger input (TRGI) reinitializes the counter and generates an update of the registers. + 4 + + + Gated_Mode + Gated Mode - The counter clock is enabled when the trigger input (TRGI) is high. The counter stops (but is not reset) as soon as the trigger becomes low. Both start and stop of the counter are controlled. + 5 + + + Trigger_Mode + Trigger Mode - The counter starts at a rising edge of the trigger TRGI (but it is not reset). Only the start of the counter is controlled. + 6 + + + Ext_Clock_Mode + External Clock Mode 1 - Rising edges of the selected trigger (TRGI) clock the counter. + 7 + + + + + + + DIER + DIER + DMA/Interrupt enable register + 0xC + 0x20 + read-write + 0x00000000 + + + TDE + Trigger DMA request enable + 14 + 1 + + TDE + read-write + + Disabled + Trigger DMA request disabled + 0 + + + Enabled + Trigger DMA request enabled + 1 + + + + + CC4DE + Capture/Compare 4 DMA request + enable + 12 + 1 + + + + CC3DE + Capture/Compare 3 DMA request + enable + 11 + 1 + + + + CC2DE + Capture/Compare 2 DMA request + enable + 10 + 1 + + + + CC1DE + Capture/Compare 1 DMA request + enable + 9 + 1 + + CC1DE + read-write + + Disabled + CCx DMA request disabled + 0 + + + Enabled + CCx DMA request enabled + 1 + + + + + UDE + Update DMA request enable + 8 + 1 + + UDE + read-write + + Disabled + Update DMA request disabled + 0 + + + Enabled + Update DMA request enabled + 1 + + + + + TIE + Trigger interrupt enable + 6 + 1 + + TIE + read-write + + Disabled + Trigger interrupt disabled + 0 + + + Enabled + Trigger interrupt enabled + 1 + + + + + CC4IE + Capture/Compare 4 interrupt + enable + 4 + 1 + + + + CC3IE + Capture/Compare 3 interrupt + enable + 3 + 1 + + + + CC2IE + Capture/Compare 2 interrupt + enable + 2 + 1 + + + + CC1IE + Capture/Compare 1 interrupt + enable + 1 + 1 + + CC1IE + read-write + + Disabled + CCx interrupt disabled + 0 + + + Enabled + CCx interrupt enabled + 1 + + + + + UIE + Update interrupt enable + 0 + 1 + + UIE + read-write + + Disabled + Update interrupt disabled + 0 + + + Enabled + Update interrupt enabled + 1 + + + + + + + SR + SR + status register + 0x10 + 0x20 + read-write + 0x00000000 + + + CC4OF + Capture/Compare 4 overcapture + flag + 12 + 1 + zeroToClear + + read + + + write + + + + CC3OF + Capture/Compare 3 overcapture + flag + 11 + 1 + zeroToClear + + read + + + write + + + + CC2OF + Capture/compare 2 overcapture + flag + 10 + 1 + zeroToClear + + read + + + write + + + + CC1OF + Capture/Compare 1 overcapture + flag + 9 + 1 + zeroToClear + + CC1OFR + read + + Overcapture + The counter value has been captured in TIMx_CCRx register while CCxIF flag was already set + 1 + + + + CC1OFW + write + + Clear + Clear flag + 0 + + + + + TIF + Trigger interrupt flag + 6 + 1 + zeroToClear + + TIFR + read + + NoTrigger + No trigger event occurred + 0 + + + Trigger + Trigger interrupt pending + 1 + + + + TIFW + write + + Clear + Clear flag + 0 + + + + + CC4IF + Capture/Compare 4 interrupt + flag + 4 + 1 + zeroToClear + + read + + + write + + + + CC3IF + Capture/Compare 3 interrupt + flag + 3 + 1 + zeroToClear + + read + + + write + + + + CC2IF + Capture/Compare 2 interrupt + flag + 2 + 1 + zeroToClear + + read + + + write + + + + CC1IF + Capture/compare 1 interrupt + flag + 1 + 1 + zeroToClear + + CC1IFR + read + + Match + If CC1 is an output: The content of the counter TIMx_CNT matches the content of the TIMx_CCR1 register. If CC1 is an input: The counter value has been captured in TIMx_CCR1 register. + 1 + + + + CC1IFW + write + + Clear + Clear flag + 0 + + + + + UIF + Update interrupt flag + 0 + 1 + zeroToClear + + UIFR + read + + NoUpdateOccurred + No update occurred + 0 + + + UpdatePending + Update interrupt pending + 1 + + + + UIFW + write + + Clear + Clear flag + 0 + + + + + + + EGR + EGR + event generation register + 0x14 + 0x20 + write-only + 0x00000000 + + + TG + Trigger generation + 6 + 1 + + TGW + write + + Trigger + The TIF flag is set in TIMx_SR register. Related interrupt or DMA transfer can occur if enabled. + 1 + + + + + CC4G + Capture/compare 4 + generation + 4 + 1 + + + + CC3G + Capture/compare 3 + generation + 3 + 1 + + + + CC2G + Capture/compare 2 + generation + 2 + 1 + + + + CC1G + Capture/compare 1 + generation + 1 + 1 + + CC1GW + write + + Trigger + If CC1 is an output: CC1IF flag is set, Corresponding interrupt or DMA request is sent if enabled. If CC1 is an input: The current value of the counter is captured in TIMx_CCR1 register. + 1 + + + + + UG + Update generation + 0 + 1 + + UG + write + + Update + Re-initializes the timer counter and generates an update of the registers. + 1 + + + + + + + CCMR1_Output + CCMR1_Output + capture/compare mode register 1 (output + mode) + 0x18 + 0x20 + read-write + 0x00000000 + + + OC2CE + OC2CE + 15 + 1 + + + OC2M + OC2M + 12 + 3 + + + + OC2PE + OC2PE + 11 + 1 + + OC2PE + read-write + + Disabled + Preload register on CCR2 disabled. New values written to CCR2 are taken into account immediately + 0 + + + Enabled + Preload register on CCR2 enabled. Preload value is loaded into active register on each update event + 1 + + + + + OC2FE + OC2FE + 10 + 1 + + + CC2S + CC2S + 8 + 2 + + CC2S + read-write + + Output + CC2 channel is configured as output + 0 + + + + + OC1CE + OC1CE + 7 + 1 + + + OC1M + OC1M + 4 + 3 + + OC1M + read-write + + Frozen + The comparison between the output compare register TIMx_CCRy and the counter TIMx_CNT has no effect on the outputs + 0 + + + ActiveOnMatch + Set channel to active level on match. OCyREF signal is forced high when the counter matches the capture/compare register + 1 + + + InactiveOnMatch + Set channel to inactive level on match. OCyREF signal is forced low when the counter matches the capture/compare register + 2 + + + Toggle + OCyREF toggles when TIMx_CNT=TIMx_CCRy + 3 + + + ForceInactive + OCyREF is forced low + 4 + + + ForceActive + OCyREF is forced high + 5 + + + PwmMode1 + In upcounting, channel is active as long as TIMx_CNT<TIMx_CCRy else inactive. In downcounting, channel is inactive as long as TIMx_CNT>TIMx_CCRy else active + 6 + + + PwmMode2 + Inversely to PwmMode1 + 7 + + + + + OC1PE + OC1PE + 3 + 1 + + OC1PE + read-write + + Disabled + Preload register on CCR1 disabled. New values written to CCR1 are taken into account immediately + 0 + + + Enabled + Preload register on CCR1 enabled. Preload value is loaded into active register on each update event + 1 + + + + + OC1FE + OC1FE + 2 + 1 + + + CC1S + CC1S + 0 + 2 + + CC1S + read-write + + Output + CC1 channel is configured as output + 0 + + + + + + + CCMR1_Input + CCMR1_Input + capture/compare mode register 1 (input + mode) + CCMR1_Output + 0x18 + 0x20 + read-write + 0x00000000 + + + IC2F + Input capture 2 filter + 12 + 4 + + + 0 + 15 + + + + + IC2PSC + Input capture 2 prescaler + 10 + 2 + + + CC2S + Capture/Compare 2 + selection + 8 + 2 + + CC2S + read-write + + TI2 + CC2 channel is configured as input, IC2 is mapped on TI2 + 1 + + + TI1 + CC2 channel is configured as input, IC2 is mapped on TI1 + 2 + + + TRC + CC2 channel is configured as input, IC2 is mapped on TRC + 3 + + + + + IC1F + Input capture 1 filter + 4 + 4 + + IC1F + read-write + + NoFilter + No filter, sampling is done at fDTS + 0 + + + FCK_INT_N2 + fSAMPLING=fCK_INT, N=2 + 1 + + + FCK_INT_N4 + fSAMPLING=fCK_INT, N=4 + 2 + + + FCK_INT_N8 + fSAMPLING=fCK_INT, N=8 + 3 + + + FDTS_Div2_N6 + fSAMPLING=fDTS/2, N=6 + 4 + + + FDTS_Div2_N8 + fSAMPLING=fDTS/2, N=8 + 5 + + + FDTS_Div4_N6 + fSAMPLING=fDTS/4, N=6 + 6 + + + FDTS_Div4_N8 + fSAMPLING=fDTS/4, N=8 + 7 + + + FDTS_Div8_N6 + fSAMPLING=fDTS/8, N=6 + 8 + + + FDTS_Div8_N8 + fSAMPLING=fDTS/8, N=8 + 9 + + + FDTS_Div16_N5 + fSAMPLING=fDTS/16, N=5 + 10 + + + FDTS_Div16_N6 + fSAMPLING=fDTS/16, N=6 + 11 + + + FDTS_Div16_N8 + fSAMPLING=fDTS/16, N=8 + 12 + + + FDTS_Div32_N5 + fSAMPLING=fDTS/32, N=5 + 13 + + + FDTS_Div32_N6 + fSAMPLING=fDTS/32, N=6 + 14 + + + FDTS_Div32_N8 + fSAMPLING=fDTS/32, N=8 + 15 + + + + + IC1PSC + Input capture 1 prescaler + 2 + 2 + + + CC1S + Capture/Compare 1 + selection + 0 + 2 + + CC1S + read-write + + TI1 + CC1 channel is configured as input, IC1 is mapped on TI1 + 1 + + + TI2 + CC1 channel is configured as input, IC1 is mapped on TI2 + 2 + + + TRC + CC1 channel is configured as input, IC1 is mapped on TRC + 3 + + + + + + + CCMR2_Output + CCMR2_Output + capture/compare mode register 2 (output + mode) + 0x1C + 0x20 + read-write + 0x00000000 + + + OC4CE + O24CE + 15 + 1 + + + OC4M + OC4M + 12 + 3 + + + + OC4PE + OC4PE + 11 + 1 + + OC4PE + read-write + + Disabled + Preload register on CCR4 disabled. New values written to CCR4 are taken into account immediately + 0 + + + Enabled + Preload register on CCR4 enabled. Preload value is loaded into active register on each update event + 1 + + + + + OC4FE + OC4FE + 10 + 1 + + + CC4S + CC4S + 8 + 2 + + CC4S + read-write + + Output + CC4 channel is configured as output + 0 + + + + + OC3CE + OC3CE + 7 + 1 + + + OC3M + OC3M + 4 + 3 + + OC3M + read-write + + Frozen + The comparison between the output compare register TIMx_CCRy and the counter TIMx_CNT has no effect on the outputs + 0 + + + ActiveOnMatch + Set channel to active level on match. OCyREF signal is forced high when the counter matches the capture/compare register + 1 + + + InactiveOnMatch + Set channel to inactive level on match. OCyREF signal is forced low when the counter matches the capture/compare register + 2 + + + Toggle + OCyREF toggles when TIMx_CNT=TIMx_CCRy + 3 + + + ForceInactive + OCyREF is forced low + 4 + + + ForceActive + OCyREF is forced high + 5 + + + PwmMode1 + In upcounting, channel is active as long as TIMx_CNT<TIMx_CCRy else inactive. In downcounting, channel is inactive as long as TIMx_CNT>TIMx_CCRy else active + 6 + + + PwmMode2 + Inversely to PwmMode1 + 7 + + + + + OC3PE + OC3PE + 3 + 1 + + OC3PE + read-write + + Disabled + Preload register on CCR3 disabled. New values written to CCR3 are taken into account immediately + 0 + + + Enabled + Preload register on CCR3 enabled. Preload value is loaded into active register on each update event + 1 + + + + + OC3FE + OC3FE + 2 + 1 + + + CC3S + CC3S + 0 + 2 + + CC3S + read-write + + Output + CC3 channel is configured as output + 0 + + + + + + + CCMR2_Input + CCMR2_Input + capture/compare mode register 2 (input + mode) + CCMR2_Output + 0x1C + 0x20 + read-write + 0x00000000 + + + IC4F + Input capture 4 filter + 12 + 4 + + + 0 + 15 + + + + + IC4PSC + Input capture 4 prescaler + 10 + 2 + + + 0 + 3 + + + + + CC4S + Capture/Compare 4 + selection + 8 + 2 + + CC4S + read-write + + TI4 + CC4 channel is configured as input, IC4 is mapped on TI4 + 1 + + + TI3 + CC4 channel is configured as input, IC4 is mapped on TI3 + 2 + + + TRC + CC4 channel is configured as input, IC4 is mapped on TRC + 3 + + + + + IC3F + Input capture 3 filter + 4 + 4 + + + 0 + 15 + + + + + IC3PSC + Input capture 3 prescaler + 2 + 2 + + + 0 + 3 + + + + + CC3S + Capture/compare 3 + selection + 0 + 2 + + CC3S + read-write + + TI3 + CC3 channel is configured as input, IC3 is mapped on TI3 + 1 + + + TI4 + CC3 channel is configured as input, IC3 is mapped on TI4 + 2 + + + TRC + CC3 channel is configured as input, IC3 is mapped on TRC + 3 + + + + + + + CCER + CCER + capture/compare enable + register + 0x20 + 0x20 + read-write + 0x00000000 + + + CC4NP + Capture/Compare 4 output + Polarity + 15 + 1 + + + CC4P + Capture/Compare 3 output + Polarity + 13 + 1 + + + CC4E + Capture/Compare 4 output + enable + 12 + 1 + + + CC3NP + Capture/Compare 3 output + Polarity + 11 + 1 + + + CC3P + Capture/Compare 3 output + Polarity + 9 + 1 + + + CC3E + Capture/Compare 3 output + enable + 8 + 1 + + + CC2NP + Capture/Compare 2 output + Polarity + 7 + 1 + + + CC2P + Capture/Compare 2 output + Polarity + 5 + 1 + + + CC2E + Capture/Compare 2 output + enable + 4 + 1 + + + CC1NP + Capture/Compare 1 output + Polarity + 3 + 1 + + + CC1P + Capture/Compare 1 output + Polarity + 1 + 1 + + + CC1E + Capture/Compare 1 output + enable + 0 + 1 + + + + + CNT + CNT + counter + 0x24 + 0x20 + read-write + 0x00000000 + + + CNT + Counter value + 0 + 32 + + + 0 + 4294967295 + + + + + + + PSC + PSC + prescaler + 0x28 + 0x20 + read-write + 0x00000000 + + + PSC + Prescaler value + 0 + 16 + + + 0 + 65535 + + + + + + + ARR + ARR + auto-reload register + 0x2C + 0x20 + read-write + 0x00000000 + + + ARR + Auto-reload value + 0 + 32 + + + 0 + 4294967295 + + + + + + + 4 + 0x4 + 1-4 + CCR%s + CCR1 + capture/compare register + 0x34 + 0x20 + read-write + 0x00000000 + + + CCR + Capture/Compare value + 0 + 32 + + + 0 + 4294967295 + + + + + + + DCR + DCR + DMA control register + 0x48 + 0x20 + read-write + 0x00000000 + + + DBL + DMA burst length + 8 + 5 + + + 0 + 18 + + + + + DBA + DMA base address + 0 + 5 + + + 0 + 31 + + + + + + + DMAR + DMAR + DMA address for full transfer + 0x4C + 0x20 + read-write + 0x00000000 + + + DMAB + DMA register for burst + accesses + 0 + 16 + + + + + OR + OR + TIM5 option register + 0x50 + 0x20 + read-write + 0x00000000 + + + IT4_RMP + Timer Input 4 remap + 6 + 2 + + + + + + + TIM9 + General purpose timers + TIM + 0x40014000 + + 0x0 + 0x400 + registers + + + + CR1 + CR1 + control register 1 + 0x0 + 0x20 + read-write + 0x00000000 + + + CKD + Clock division + 8 + 2 + + CKD + read-write + + Div1 + t_DTS = t_CK_INT + 0 + + + Div2 + t_DTS = 2 × t_CK_INT + 1 + + + Div4 + t_DTS = 4 × t_CK_INT + 2 + + + + + ARPE + Auto-reload preload enable + 7 + 1 + + ARPE + read-write + + Disabled + TIMx_APRR register is not buffered + 0 + + + Enabled + TIMx_APRR register is buffered + 1 + + + + + OPM + One-pulse mode + 3 + 1 + + OPM + read-write + + Disabled + Counter is not stopped at update event + 0 + + + Enabled + Counter stops counting at the next update event (clearing the CEN bit) + 1 + + + + + URS + Update request source + 2 + 1 + + URS + read-write + + AnyEvent + Any of counter overflow/underflow, setting UG, or update through slave mode, generates an update interrupt or DMA request + 0 + + + CounterOnly + Only counter overflow/underflow generates an update interrupt or DMA request + 1 + + + + + UDIS + Update disable + 1 + 1 + + UDIS + read-write + + Enabled + Update event enabled + 0 + + + Disabled + Update event disabled + 1 + + + + + CEN + Counter enable + 0 + 1 + + CEN + read-write + + Disabled + Counter disabled + 0 + + + Enabled + Counter enabled + 1 + + + + + + + CR2 + CR2 + control register 2 + 0x4 + 0x20 + read-write + 0x00000000 + + + MMS + Master mode selection + 4 + 3 + + + + + SMCR + SMCR + slave mode control register + 0x8 + 0x20 + read-write + 0x00000000 + + + MSM + Master/Slave mode + 7 + 1 + + + TS + Trigger selection + 4 + 3 + + + SMS + Slave mode selection + 0 + 3 + + + + + DIER + DIER + DMA/Interrupt enable register + 0xC + 0x20 + read-write + 0x00000000 + + + TIE + Trigger interrupt enable + 6 + 1 + + + CC2IE + Capture/Compare 2 interrupt + enable + 2 + 1 + + + CC1IE + Capture/Compare 1 interrupt + enable + 1 + 1 + + + UIE + Update interrupt enable + 0 + 1 + + UIE + read-write + + Disabled + Update interrupt disabled + 0 + + + Enabled + Update interrupt enabled + 1 + + + + + + + SR + SR + status register + 0x10 + 0x20 + read-write + 0x00000000 + + + CC2OF + Capture/compare 2 overcapture + flag + 10 + 1 + + + CC1OF + Capture/Compare 1 overcapture + flag + 9 + 1 + + + TIF + Trigger interrupt flag + 6 + 1 + + + CC2IF + Capture/Compare 2 interrupt + flag + 2 + 1 + + + CC1IF + Capture/compare 1 interrupt + flag + 1 + 1 + + + UIF + Update interrupt flag + 0 + 1 + zeroToClear + + UIFR + read + + NoUpdateOccurred + No update occurred + 0 + + + UpdatePending + Update interrupt pending + 1 + + + + UIFW + write + + Clear + Clear flag + 0 + + + + + + + EGR + EGR + event generation register + 0x14 + 0x20 + write-only + 0x00000000 + + + TG + Trigger generation + 6 + 1 + + + CC2G + Capture/compare 2 + generation + 2 + 1 + + + CC1G + Capture/compare 1 + generation + 1 + 1 + + + UG + Update generation + 0 + 1 + + UG + write + + Update + Re-initializes the timer counter and generates an update of the registers. + 1 + + + + + + + CCMR1_Output + CCMR1_Output + capture/compare mode register 1 (output + mode) + 0x18 + 0x20 + read-write + 0x00000000 + + + OC2M + Output Compare 2 mode + 12 + 3 + + + + OC2PE + Output Compare 2 preload + enable + 11 + 1 + + + OC2FE + Output Compare 2 fast + enable + 10 + 1 + + + CC2S + Capture/Compare 2 + selection + 8 + 2 + + + OC1M + Output Compare 1 mode + 4 + 3 + + OC1M + read-write + + Frozen + The comparison between the output compare register TIMx_CCRy and the counter TIMx_CNT has no effect on the outputs + 0 + + + ActiveOnMatch + Set channel to active level on match. OCyREF signal is forced high when the counter matches the capture/compare register + 1 + + + InactiveOnMatch + Set channel to inactive level on match. OCyREF signal is forced low when the counter matches the capture/compare register + 2 + + + Toggle + OCyREF toggles when TIMx_CNT=TIMx_CCRy + 3 + + + ForceInactive + OCyREF is forced low + 4 + + + ForceActive + OCyREF is forced high + 5 + + + PwmMode1 + In upcounting, channel is active as long as TIMx_CNT<TIMx_CCRy else inactive. In downcounting, channel is inactive as long as TIMx_CNT>TIMx_CCRy else active + 6 + + + PwmMode2 + Inversely to PwmMode1 + 7 + + + + + OC1PE + Output Compare 1 preload + enable + 3 + 1 + + + OC1FE + Output Compare 1 fast + enable + 2 + 1 + + + CC1S + Capture/Compare 1 + selection + 0 + 2 + + + + + CCMR1_Input + CCMR1_Input + capture/compare mode register 1 (input + mode) + CCMR1_Output + 0x18 + 0x20 + read-write + 0x00000000 + + + IC2F + Input capture 2 filter + 12 + 3 + + + IC2PSC + Input capture 2 prescaler + 10 + 2 + + + CC2S + Capture/Compare 2 + selection + 8 + 2 + + + IC1F + Input capture 1 filter + 4 + 3 + + + IC1PSC + Input capture 1 prescaler + 2 + 2 + + + CC1S + Capture/Compare 1 + selection + 0 + 2 + + + + + CCER + CCER + capture/compare enable + register + 0x20 + 0x20 + read-write + 0x00000000 + + + CC2NP + Capture/Compare 2 output + Polarity + 7 + 1 + + + CC2P + Capture/Compare 2 output + Polarity + 5 + 1 + + + CC2E + Capture/Compare 2 output + enable + 4 + 1 + + + CC1NP + Capture/Compare 1 output + Polarity + 3 + 1 + + + CC1P + Capture/Compare 1 output + Polarity + 1 + 1 + + + CC1E + Capture/Compare 1 output + enable + 0 + 1 + + + + + CNT + CNT + counter + 0x24 + 0x20 + read-write + 0x00000000 + + + CNT + counter value + 0 + 16 + + + + + PSC + PSC + prescaler + 0x28 + 0x20 + read-write + 0x00000000 + + + PSC + Prescaler value + 0 + 16 + + + 0 + 65535 + + + + + + + ARR + ARR + auto-reload register + 0x2C + 0x20 + read-write + 0x00000000 + + + ARR + Auto-reload value + 0 + 16 + + + + + 2 + 0x4 + 1-2 + CCR%s + CCR1 + capture/compare register + 0x34 + 0x20 + read-write + 0x00000000 + + + CCR + Capture/Compare value + 0 + 16 + + + + + + + USART1 + Universal synchronous asynchronous receiver + transmitter + USART + 0x40011000 + + 0x0 + 0x400 + registers + + + OTG_FS_WKUP + USB On-The-Go FS Wakeup through EXTI line + interrupt + 42 + + + OTG_FS + USB On The Go FS global + interrupt + 67 + + + USART1 + USART1 global interrupt + 37 + + + USART2 + USART2 global interrupt + 38 + + + USART6 + USART6 global interrupt + 71 + + + + SR + SR + Status register + 0x0 + 0x20 + 0x00C00000 + + + CTS + CTS flag + 9 + 1 + read-write + + + LBD + LIN break detection flag + 8 + 1 + read-write + + + TXE + Transmit data register + empty + 7 + 1 + read-only + + + TC + Transmission complete + 6 + 1 + read-write + + + RXNE + Read data register not + empty + 5 + 1 + read-write + + + IDLE + IDLE line detected + 4 + 1 + read-only + + + ORE + Overrun error + 3 + 1 + read-only + + + NF + Noise detected flag + 2 + 1 + read-only + + + FE + Framing error + 1 + 1 + read-only + + + PE + Parity error + 0 + 1 + read-only + + + + + DR + DR + Data register + 0x4 + 0x20 + read-write + 0x00000000 + + + DR + Data value + 0 + 9 + + + 0 + 511 + + + + + + + BRR + BRR + Baud rate register + 0x8 + 0x20 + read-write + 0x00000000 + + + DIV_Mantissa + mantissa of USARTDIV + 4 + 12 + + + 0 + 4095 + + + + + DIV_Fraction + fraction of USARTDIV + 0 + 4 + + + 0 + 15 + + + + + + + CR1 + CR1 + Control register 1 + 0xC + 0x20 + read-write + 0x00000000 + + + OVER8 + Oversampling mode + 15 + 1 + + OVER8 + read-write + + Oversample16 + Oversampling by 16 + 0 + + + Oversample8 + Oversampling by 8 + 1 + + + + + UE + USART enable + 13 + 1 + + UE + read-write + + Disabled + USART prescaler and outputs disabled + 0 + + + Enabled + USART enabled + 1 + + + + + M + Word length + 12 + 1 + + M + read-write + + M8 + 8 data bits + 0 + + + M9 + 9 data bits + 1 + + + + + WAKE + Wakeup method + 11 + 1 + + WAKE + read-write + + IdleLine + USART wakeup on idle line + 0 + + + AddressMark + USART wakeup on address mark + 1 + + + + + PCE + Parity control enable + 10 + 1 + + PCE + read-write + + Disabled + Parity control disabled + 0 + + + Enabled + Parity control enabled + 1 + + + + + PS + Parity selection + 9 + 1 + + PS + read-write + + Even + Even parity + 0 + + + Odd + Odd parity + 1 + + + + + PEIE + PE interrupt enable + 8 + 1 + + PEIE + read-write + + Disabled + PE interrupt disabled + 0 + + + Enabled + PE interrupt enabled + 1 + + + + + TXEIE + TXE interrupt enable + 7 + 1 + + TXEIE + read-write + + Disabled + TXE interrupt disabled + 0 + + + Enabled + TXE interrupt enabled + 1 + + + + + TCIE + Transmission complete interrupt + enable + 6 + 1 + + TCIE + read-write + + Disabled + TC interrupt disabled + 0 + + + Enabled + TC interrupt enabled + 1 + + + + + RXNEIE + RXNE interrupt enable + 5 + 1 + + RXNEIE + read-write + + Disabled + RXNE interrupt disabled + 0 + + + Enabled + RXNE interrupt enabled + 1 + + + + + IDLEIE + IDLE interrupt enable + 4 + 1 + + IDLEIE + read-write + + Disabled + IDLE interrupt disabled + 0 + + + Enabled + IDLE interrupt enabled + 1 + + + + + TE + Transmitter enable + 3 + 1 + + TE + read-write + + Disabled + Transmitter disabled + 0 + + + Enabled + Transmitter enabled + 1 + + + + + RE + Receiver enable + 2 + 1 + + RE + read-write + + Disabled + Receiver disabled + 0 + + + Enabled + Receiver enabled + 1 + + + + + RWU + Receiver wakeup + 1 + 1 + + RWU + read-write + + Active + Receiver in active mode + 0 + + + Mute + Receiver in mute mode + 1 + + + + + SBK + Send break + 0 + 1 + + SBK + read-write + + NoBreak + No break character is transmitted + 0 + + + Break + Break character transmitted + 1 + + + + + + + CR2 + CR2 + Control register 2 + 0x10 + 0x20 + read-write + 0x00000000 + + + LINEN + LIN mode enable + 14 + 1 + + LINEN + read-write + + Disabled + LIN mode disabled + 0 + + + Enabled + LIN mode enabled + 1 + + + + + STOP + STOP bits + 12 + 2 + + STOP + read-write + + Stop1 + 1 stop bit + 0 + + + Stop0p5 + 0.5 stop bits + 1 + + + Stop2 + 2 stop bits + 2 + + + Stop1p5 + 1.5 stop bits + 3 + + + + + CLKEN + Clock enable + 11 + 1 + + CLKEN + read-write + + Disabled + CK pin disabled + 0 + + + Enabled + CK pin enabled + 1 + + + + + CPOL + Clock polarity + 10 + 1 + + CPOL + read-write + + Low + Steady low value on CK pin outside transmission window + 0 + + + High + Steady high value on CK pin outside transmission window + 1 + + + + + CPHA + Clock phase + 9 + 1 + + CPHA + read-write + + First + The first clock transition is the first data capture edge + 0 + + + Second + The second clock transition is the first data capture edge + 1 + + + + + LBCL + Last bit clock pulse + 8 + 1 + + + LBDIE + LIN break detection interrupt + enable + 6 + 1 + + LBDIE + read-write + + Disabled + LIN break detection interrupt disabled + 0 + + + Enabled + LIN break detection interrupt enabled + 1 + + + + + LBDL + lin break detection length + 5 + 1 + + LBDL + read-write + + LBDL10 + 10-bit break detection + 0 + + + LBDL11 + 11-bit break detection + 1 + + + + + ADD + Address of the USART node + 0 + 4 + + + 0 + 15 + + + + + + + CR3 + CR3 + Control register 3 + 0x14 + 0x20 + read-write + 0x00000000 + + + ONEBIT + One sample bit method + enable + 11 + 1 + + ONEBIT + read-write + + Sample3 + Three sample bit method + 0 + + + Sample1 + One sample bit method + 1 + + + + + CTSIE + CTS interrupt enable + 10 + 1 + + CTSIE + read-write + + Disabled + CTS interrupt disabled + 0 + + + Enabled + CTS interrupt enabled + 1 + + + + + CTSE + CTS enable + 9 + 1 + + CTSE + read-write + + Disabled + CTS hardware flow control disabled + 0 + + + Enabled + CTS hardware flow control enabled + 1 + + + + + RTSE + RTS enable + 8 + 1 + + RTSE + read-write + + Disabled + RTS hardware flow control disabled + 0 + + + Enabled + RTS hardware flow control enabled + 1 + + + + + DMAT + DMA enable transmitter + 7 + 1 + + DMAT + read-write + + Disabled + DMA mode is disabled for transmission + 0 + + + Enabled + DMA mode is enabled for transmission + 1 + + + + + DMAR + DMA enable receiver + 6 + 1 + + DMAR + read-write + + Disabled + DMA mode is disabled for reception + 0 + + + Enabled + DMA mode is enabled for reception + 1 + + + + + SCEN + Smartcard mode enable + 5 + 1 + + SCEN + read-write + + Disabled + Smartcard mode disabled + 0 + + + Enabled + Smartcard mode enabled + 1 + + + + + NACK + Smartcard NACK enable + 4 + 1 + + NACK + read-write + + Disabled + NACK transmission in case of parity error is disabled + 0 + + + Enabled + NACK transmission during parity error is enabled + 1 + + + + + HDSEL + Half-duplex selection + 3 + 1 + + HDSEL + read-write + + FullDuplex + Half duplex mode is not selected + 0 + + + HalfDuplex + Half duplex mode is selected + 1 + + + + + IRLP + IrDA low-power + 2 + 1 + + IRLP + read-write + + Normal + Normal mode + 0 + + + LowPower + Low-power mode + 1 + + + + + IREN + IrDA mode enable + 1 + 1 + + IREN + read-write + + Disabled + IrDA disabled + 0 + + + Enabled + IrDA enabled + 1 + + + + + EIE + Error interrupt enable + 0 + 1 + + EIE + read-write + + Disabled + Error interrupt disabled + 0 + + + Enabled + Error interrupt enabled + 1 + + + + + + + GTPR + GTPR + Guard time and prescaler + register + 0x18 + 0x20 + read-write + 0x00000000 + + + GT + Guard time value + 8 + 8 + + + PSC + Prescaler value + 0 + 8 + + + + + + + USART2 + 0x40004400 + + + USART6 + 0x40011400 + + + WWDG + Window watchdog + WWDG + 0x40002C00 + + 0x0 + 0x400 + registers + + + PVD + PVD through EXTI line detection + interrupt + 1 + + + + CR + CR + Control register + 0x0 + 0x20 + read-write + 0x0000007F + + + WDGA + Activation bit + 7 + 1 + + WDGA + read-write + + Disabled + Watchdog disabled + 0 + + + Enabled + Watchdog enabled + 1 + + + + + T + 7-bit counter (MSB to LSB) + 0 + 7 + + + 0 + 127 + + + + + + + CFR + CFR + Configuration register + 0x4 + 0x20 + read-write + 0x0000007F + + + EWI + Early wakeup interrupt + 9 + 1 + + EWIW + write + + Enable + interrupt occurs whenever the counter reaches the value 0x40 + 1 + + + + + W + 7-bit window value + 0 + 7 + + + 0 + 127 + + + + + WDGTB + Timer base + 7 + 2 + + WDGTB + read-write + + Div1 + Counter clock (PCLK1 div 4096) div 1 + 0 + + + Div2 + Counter clock (PCLK1 div 4096) div 2 + 1 + + + Div4 + Counter clock (PCLK1 div 4096) div 4 + 2 + + + Div8 + Counter clock (PCLK1 div 4096) div 8 + 3 + + + + + + + SR + SR + Status register + 0x8 + 0x20 + read-write + 0x00000000 + + + EWIF + Early wakeup interrupt + flag + 0 + 1 + zeroToClear + + EWIFR + read + + Finished + The EWI Interrupt Service Routine has been serviced + 0 + + + Pending + The EWI Interrupt Service Routine has been triggered + 1 + + + + EWIFW + write + + Finished + The EWI Interrupt Service Routine has been serviced + 0 + + + + + + + + + DMA2 + DMA controller + DMA + 0x40026400 + + 0x0 + 0x400 + registers + + + RCC + RCC global interrupt + 5 + + + DMA1_STREAM0 + DMA1_STREAM0 global interrupt + 11 + + + DMA1_STREAM1 + DMA1_STREAM1 global interrupt + 12 + + + DMA1_STREAM2 + DMA1_STREAM2 global interrupt + 13 + + + DMA1_STREAM3 + DMA1_STREAM3 global interrupt + 14 + + + DMA1_STREAM4 + DMA1_STREAM4 global interrupt + 15 + + + DMA1_STREAM5 + DMA1_STREAM5 global interrupt + 16 + + + DMA1_STREAM6 + DMA1_STREAM6 global interrupt + 17 + + + DMA1_STREAM7 + DMA1_STREAM7 global interrupt + 47 + + + DMA2_STREAM0 + DMA2_STREAM0 global interrupt + 56 + + + DMA2_STREAM1 + DMA2_STREAM1 global interrupt + 57 + + + DMA2_STREAM2 + DMA2_STREAM2 global interrupt + 58 + + + DMA2_STREAM3 + DMA2_STREAM3 global interrupt + 59 + + + DMA2_STREAM4 + DMA2_STREAM4 global interrupt + 60 + + + DMA2_STREAM5 + DMA2_STREAM5 global interrupt + 68 + + + DMA2_STREAM6 + DMA2_STREAM6 global interrupt + 69 + + + DMA2_STREAM7 + DMA2_STREAM7 global interrupt + 70 + + + + LISR + LISR + low interrupt status register + 0x0 + 0x20 + read-only + 0x00000000 + + + TCIF3 + Stream x transfer complete interrupt + flag (x = 3..0) + 27 + 1 + + + + HTIF3 + Stream x half transfer interrupt flag + (x=3..0) + 26 + 1 + + + + TEIF3 + Stream x transfer error interrupt flag + (x=3..0) + 25 + 1 + + + + DMEIF3 + Stream x direct mode error interrupt + flag (x=3..0) + 24 + 1 + + + + FEIF3 + Stream x FIFO error interrupt flag + (x=3..0) + 22 + 1 + + + + TCIF2 + Stream x transfer complete interrupt + flag (x = 3..0) + 21 + 1 + + + + HTIF2 + Stream x half transfer interrupt flag + (x=3..0) + 20 + 1 + + + + TEIF2 + Stream x transfer error interrupt flag + (x=3..0) + 19 + 1 + + + + DMEIF2 + Stream x direct mode error interrupt + flag (x=3..0) + 18 + 1 + + + + FEIF2 + Stream x FIFO error interrupt flag + (x=3..0) + 16 + 1 + + + + TCIF1 + Stream x transfer complete interrupt + flag (x = 3..0) + 11 + 1 + + + + HTIF1 + Stream x half transfer interrupt flag + (x=3..0) + 10 + 1 + + + + TEIF1 + Stream x transfer error interrupt flag + (x=3..0) + 9 + 1 + + + + DMEIF1 + Stream x direct mode error interrupt + flag (x=3..0) + 8 + 1 + + + + FEIF1 + Stream x FIFO error interrupt flag + (x=3..0) + 6 + 1 + + + + TCIF0 + Stream x transfer complete interrupt + flag (x = 3..0) + 5 + 1 + + TCIF0 + read + + NotComplete + No transfer complete event on stream x + 0 + + + Complete + A transfer complete event occurred on stream x + 1 + + + + + HTIF0 + Stream x half transfer interrupt flag + (x=3..0) + 4 + 1 + + HTIF0 + read + + NotHalf + No half transfer event on stream x + 0 + + + Half + A half transfer event occurred on stream x + 1 + + + + + TEIF0 + Stream x transfer error interrupt flag + (x=3..0) + 3 + 1 + + TEIF0 + read + + NoError + No transfer error on stream x + 0 + + + Error + A transfer error occurred on stream x + 1 + + + + + DMEIF0 + Stream x direct mode error interrupt + flag (x=3..0) + 2 + 1 + + DMEIF0 + read + + NoError + No Direct Mode error on stream x + 0 + + + Error + A Direct Mode error occurred on stream x + 1 + + + + + FEIF0 + Stream x FIFO error interrupt flag + (x=3..0) + 0 + 1 + + FEIF0 + read + + NoError + No FIFO error event on stream x + 0 + + + Error + A FIFO error event occurred on stream x + 1 + + + + + + + HISR + HISR + high interrupt status register + 0x4 + 0x20 + read-only + 0x00000000 + + + TCIF7 + Stream x transfer complete interrupt + flag (x=7..4) + 27 + 1 + + + + HTIF7 + Stream x half transfer interrupt flag + (x=7..4) + 26 + 1 + + + + TEIF7 + Stream x transfer error interrupt flag + (x=7..4) + 25 + 1 + + + + DMEIF7 + Stream x direct mode error interrupt + flag (x=7..4) + 24 + 1 + + + + FEIF7 + Stream x FIFO error interrupt flag + (x=7..4) + 22 + 1 + + + + TCIF6 + Stream x transfer complete interrupt + flag (x=7..4) + 21 + 1 + + + + HTIF6 + Stream x half transfer interrupt flag + (x=7..4) + 20 + 1 + + + + TEIF6 + Stream x transfer error interrupt flag + (x=7..4) + 19 + 1 + + + + DMEIF6 + Stream x direct mode error interrupt + flag (x=7..4) + 18 + 1 + + + + FEIF6 + Stream x FIFO error interrupt flag + (x=7..4) + 16 + 1 + + + + TCIF5 + Stream x transfer complete interrupt + flag (x=7..4) + 11 + 1 + + + + HTIF5 + Stream x half transfer interrupt flag + (x=7..4) + 10 + 1 + + + + TEIF5 + Stream x transfer error interrupt flag + (x=7..4) + 9 + 1 + + + + DMEIF5 + Stream x direct mode error interrupt + flag (x=7..4) + 8 + 1 + + + + FEIF5 + Stream x FIFO error interrupt flag + (x=7..4) + 6 + 1 + + + + TCIF4 + Stream x transfer complete interrupt + flag (x=7..4) + 5 + 1 + + TCIF4 + read + + NotComplete + No transfer complete event on stream x + 0 + + + Complete + A transfer complete event occurred on stream x + 1 + + + + + HTIF4 + Stream x half transfer interrupt flag + (x=7..4) + 4 + 1 + + HTIF4 + read + + NotHalf + No half transfer event on stream x + 0 + + + Half + A half transfer event occurred on stream x + 1 + + + + + TEIF4 + Stream x transfer error interrupt flag + (x=7..4) + 3 + 1 + + TEIF4 + read + + NoError + No transfer error on stream x + 0 + + + Error + A transfer error occurred on stream x + 1 + + + + + DMEIF4 + Stream x direct mode error interrupt + flag (x=7..4) + 2 + 1 + + DMEIF4 + read + + NoError + No Direct Mode error on stream x + 0 + + + Error + A Direct Mode error occurred on stream x + 1 + + + + + FEIF4 + Stream x FIFO error interrupt flag + (x=7..4) + 0 + 1 + + FEIF4 + read + + NoError + No FIFO error event on stream x + 0 + + + Error + A FIFO error event occurred on stream x + 1 + + + + + + + LIFCR + LIFCR + low interrupt flag clear + register + 0x8 + 0x20 + write-only + 0x00000000 + + + CTCIF3 + Stream x clear transfer complete + interrupt flag (x = 3..0) + 27 + 1 + + + + CHTIF3 + Stream x clear half transfer interrupt + flag (x = 3..0) + 26 + 1 + + + + CTEIF3 + Stream x clear transfer error interrupt + flag (x = 3..0) + 25 + 1 + + + + CDMEIF3 + Stream x clear direct mode error + interrupt flag (x = 3..0) + 24 + 1 + + + + CFEIF3 + Stream x clear FIFO error interrupt flag + (x = 3..0) + 22 + 1 + + + + CTCIF2 + Stream x clear transfer complete + interrupt flag (x = 3..0) + 21 + 1 + + + + CHTIF2 + Stream x clear half transfer interrupt + flag (x = 3..0) + 20 + 1 + + + + CTEIF2 + Stream x clear transfer error interrupt + flag (x = 3..0) + 19 + 1 + + + + CDMEIF2 + Stream x clear direct mode error + interrupt flag (x = 3..0) + 18 + 1 + + + + CFEIF2 + Stream x clear FIFO error interrupt flag + (x = 3..0) + 16 + 1 + + + + CTCIF1 + Stream x clear transfer complete + interrupt flag (x = 3..0) + 11 + 1 + + + + CHTIF1 + Stream x clear half transfer interrupt + flag (x = 3..0) + 10 + 1 + + + + CTEIF1 + Stream x clear transfer error interrupt + flag (x = 3..0) + 9 + 1 + + + + CDMEIF1 + Stream x clear direct mode error + interrupt flag (x = 3..0) + 8 + 1 + + + + CFEIF1 + Stream x clear FIFO error interrupt flag + (x = 3..0) + 6 + 1 + + + + CTCIF0 + Stream x clear transfer complete + interrupt flag (x = 3..0) + 5 + 1 + + CTCIF0 + write + + Clear + Clear the corresponding TCIFx flag + 1 + + + + + CHTIF0 + Stream x clear half transfer interrupt + flag (x = 3..0) + 4 + 1 + + CHTIF0 + write + + Clear + Clear the corresponding HTIFx flag + 1 + + + + + CTEIF0 + Stream x clear transfer error interrupt + flag (x = 3..0) + 3 + 1 + + CTEIF0 + write + + Clear + Clear the corresponding TEIFx flag + 1 + + + + + CDMEIF0 + Stream x clear direct mode error + interrupt flag (x = 3..0) + 2 + 1 + + CDMEIF0 + write + + Clear + Clear the corresponding DMEIFx flag + 1 + + + + + CFEIF0 + Stream x clear FIFO error interrupt flag + (x = 3..0) + 0 + 1 + + CFEIF0 + write + + Clear + Clear the corresponding CFEIFx flag + 1 + + + + + + + HIFCR + HIFCR + high interrupt flag clear + register + 0xC + 0x20 + write-only + 0x00000000 + + + CTCIF7 + Stream x clear transfer complete + interrupt flag (x = 7..4) + 27 + 1 + + + + CHTIF7 + Stream x clear half transfer interrupt + flag (x = 7..4) + 26 + 1 + + + + CTEIF7 + Stream x clear transfer error interrupt + flag (x = 7..4) + 25 + 1 + + + + CDMEIF7 + Stream x clear direct mode error + interrupt flag (x = 7..4) + 24 + 1 + + + + CFEIF7 + Stream x clear FIFO error interrupt flag + (x = 7..4) + 22 + 1 + + + + CTCIF6 + Stream x clear transfer complete + interrupt flag (x = 7..4) + 21 + 1 + + + + CHTIF6 + Stream x clear half transfer interrupt + flag (x = 7..4) + 20 + 1 + + + + CTEIF6 + Stream x clear transfer error interrupt + flag (x = 7..4) + 19 + 1 + + + + CDMEIF6 + Stream x clear direct mode error + interrupt flag (x = 7..4) + 18 + 1 + + + + CFEIF6 + Stream x clear FIFO error interrupt flag + (x = 7..4) + 16 + 1 + + + + CTCIF5 + Stream x clear transfer complete + interrupt flag (x = 7..4) + 11 + 1 + + + + CHTIF5 + Stream x clear half transfer interrupt + flag (x = 7..4) + 10 + 1 + + + + CTEIF5 + Stream x clear transfer error interrupt + flag (x = 7..4) + 9 + 1 + + + + CDMEIF5 + Stream x clear direct mode error + interrupt flag (x = 7..4) + 8 + 1 + + + + CFEIF5 + Stream x clear FIFO error interrupt flag + (x = 7..4) + 6 + 1 + + + + CTCIF4 + Stream x clear transfer complete + interrupt flag (x = 7..4) + 5 + 1 + + CTCIF4 + write + + Clear + Clear the corresponding TCIFx flag + 1 + + + + + CHTIF4 + Stream x clear half transfer interrupt + flag (x = 7..4) + 4 + 1 + + CHTIF4 + write + + Clear + Clear the corresponding HTIFx flag + 1 + + + + + CTEIF4 + Stream x clear transfer error interrupt + flag (x = 7..4) + 3 + 1 + + CTEIF4 + write + + Clear + Clear the corresponding TEIFx flag + 1 + + + + + CDMEIF4 + Stream x clear direct mode error + interrupt flag (x = 7..4) + 2 + 1 + + CDMEIF4 + write + + Clear + Clear the corresponding DMEIFx flag + 1 + + + + + CFEIF4 + Stream x clear FIFO error interrupt flag + (x = 7..4) + 0 + 1 + + CFEIF4 + write + + Clear + Clear the corresponding CFEIFx flag + 1 + + + + + + + 8 + 0x18 + 0-7 + ST%s + Stream cluster: S?CR, S?NDTR, S?M0AR, S?M1AR and S?FCR registers + 0x10 + + CR + S0CR + stream x configuration + register + 0x0 + 0x20 + read-write + 0x00000000 + + + CHSEL + Channel selection + 25 + 3 + + + 0 + 7 + + + + + MBURST + Memory burst transfer + configuration + 23 + 2 + + + + PBURST + Peripheral burst transfer + configuration + 21 + 2 + + PBURST + read-write + + Single + Single transfer + 0 + + + INCR4 + Incremental burst of 4 beats + 1 + + + INCR8 + Incremental burst of 8 beats + 2 + + + INCR16 + Incremental burst of 16 beats + 3 + + + + + CT + Current target (only in double buffer + mode) + 19 + 1 + + CT + read-write + + Memory0 + The current target memory is Memory 0 + 0 + + + Memory1 + The current target memory is Memory 1 + 1 + + + + + DBM + Double buffer mode + 18 + 1 + + DBM + read-write + + Disabled + No buffer switching at the end of transfer + 0 + + + Enabled + Memory target switched at the end of the DMA transfer + 1 + + + + + PL + Priority level + 16 + 2 + + PL + read-write + + Low + Low + 0 + + + Medium + Medium + 1 + + + High + High + 2 + + + VeryHigh + Very high + 3 + + + + + PINCOS + Peripheral increment offset + size + 15 + 1 + + PINCOS + read-write + + PSIZE + The offset size for the peripheral address calculation is linked to the PSIZE + 0 + + + Fixed4 + The offset size for the peripheral address calculation is fixed to 4 (32-bit alignment) + 1 + + + + + MSIZE + Memory data size + 13 + 2 + + + + PSIZE + Peripheral data size + 11 + 2 + + PSIZE + read-write + + Bits8 + Byte (8-bit) + 0 + + + Bits16 + Half-word (16-bit) + 1 + + + Bits32 + Word (32-bit) + 2 + + + + + MINC + Memory increment mode + 10 + 1 + + + + PINC + Peripheral increment mode + 9 + 1 + + PINC + read-write + + Fixed + Address pointer is fixed + 0 + + + Incremented + Address pointer is incremented after each data transfer + 1 + + + + + CIRC + Circular mode + 8 + 1 + + CIRC + read-write + + Disabled + Circular mode disabled + 0 + + + Enabled + Circular mode enabled + 1 + + + + + DIR + Data transfer direction + 6 + 2 + + DIR + read-write + + PeripheralToMemory + Peripheral-to-memory + 0 + + + MemoryToPeripheral + Memory-to-peripheral + 1 + + + MemoryToMemory + Memory-to-memory + 2 + + + + + PFCTRL + Peripheral flow controller + 5 + 1 + + PFCTRL + read-write + + DMA + The DMA is the flow controller + 0 + + + Peripheral + The peripheral is the flow controller + 1 + + + + + TCIE + Transfer complete interrupt + enable + 4 + 1 + + TCIE + read-write + + Disabled + TC interrupt disabled + 0 + + + Enabled + TC interrupt enabled + 1 + + + + + HTIE + Half transfer interrupt + enable + 3 + 1 + + HTIE + read-write + + Disabled + HT interrupt disabled + 0 + + + Enabled + HT interrupt enabled + 1 + + + + + TEIE + Transfer error interrupt + enable + 2 + 1 + + TEIE + read-write + + Disabled + TE interrupt disabled + 0 + + + Enabled + TE interrupt enabled + 1 + + + + + DMEIE + Direct mode error interrupt + enable + 1 + 1 + + DMEIE + read-write + + Disabled + DME interrupt disabled + 0 + + + Enabled + DME interrupt enabled + 1 + + + + + EN + Stream enable / flag stream ready when + read low + 0 + 1 + + EN + read-write + + Disabled + Stream disabled + 0 + + + Enabled + Stream enabled + 1 + + + + + + + NDTR + S0NDTR + stream x number of data + register + 0x4 + 0x20 + read-write + 0x00000000 + + + NDT + Number of data items to + transfer + 0 + 16 + + + 0 + 65535 + + + + + + + PAR + S0PAR + stream x peripheral address + register + 0x8 + 0x20 + read-write + 0x00000000 + + + PA + Peripheral address + 0 + 32 + + + + + M0AR + S0M0AR + stream x memory 0 address + register + 0xC + 0x20 + read-write + 0x00000000 + + + M0A + Memory 0 address + 0 + 32 + + + + + M1AR + S0M1AR + stream x memory 1 address + register + 0x10 + 0x20 + read-write + 0x00000000 + + + M1A + Memory 1 address (used in case of Double + buffer mode) + 0 + 32 + + + + + FCR + S0FCR + stream x FIFO control register + 0x14 + 0x20 + 0x00000021 + + + FEIE + FIFO error interrupt + enable + 7 + 1 + read-write + + FEIE + read-write + + Disabled + FE interrupt disabled + 0 + + + Enabled + FE interrupt enabled + 1 + + + + + FS + FIFO status + 3 + 3 + read-only + + FS + read + + Quarter1 + 0 < fifo_level < 1/4 + 0 + + + Quarter2 + 1/4 <= fifo_level < 1/2 + 1 + + + Quarter3 + 1/2 <= fifo_level < 3/4 + 2 + + + Quarter4 + 3/4 <= fifo_level < full + 3 + + + Empty + FIFO is empty + 4 + + + Full + FIFO is full + 5 + + + + + DMDIS + Direct mode disable + 2 + 1 + read-write + + DMDIS + read-write + + Enabled + Direct mode is enabled + 0 + + + Disabled + Direct mode is disabled + 1 + + + + + FTH + FIFO threshold selection + 0 + 2 + read-write + + FTH + read-write + + Quarter + 1/4 full FIFO + 0 + + + Half + 1/2 full FIFO + 1 + + + ThreeQuarters + 3/4 full FIFO + 2 + + + Full + Full FIFO + 3 + + + + + + + + + + DMA1 + 0x40026000 + + RTC_WKUP + RTC Wakeup interrupt through the EXTI + line + 3 + + + RTC_Alarm + RTC Alarms (A and B) through EXTI line + interrupt + 41 + + + + GPIOH + General-purpose I/Os + GPIO + 0x40021C00 + + 0x0 + 0x400 + registers + + + SDIO + SDIO global interrupt + 49 + + + + MODER + MODER + GPIO port mode register + 0x0 + 0x20 + read-write + 0x00000000 + + + MODER15 + Port x configuration bits (y = + 0..15) + 30 + 2 + + + + MODER14 + Port x configuration bits (y = + 0..15) + 28 + 2 + + + + MODER13 + Port x configuration bits (y = + 0..15) + 26 + 2 + + + + MODER12 + Port x configuration bits (y = + 0..15) + 24 + 2 + + + + MODER11 + Port x configuration bits (y = + 0..15) + 22 + 2 + + + + MODER10 + Port x configuration bits (y = + 0..15) + 20 + 2 + + + + MODER9 + Port x configuration bits (y = + 0..15) + 18 + 2 + + + + MODER8 + Port x configuration bits (y = + 0..15) + 16 + 2 + + + + MODER7 + Port x configuration bits (y = + 0..15) + 14 + 2 + + + + MODER6 + Port x configuration bits (y = + 0..15) + 12 + 2 + + + + MODER5 + Port x configuration bits (y = + 0..15) + 10 + 2 + + + + MODER4 + Port x configuration bits (y = + 0..15) + 8 + 2 + + + + MODER3 + Port x configuration bits (y = + 0..15) + 6 + 2 + + + + MODER2 + Port x configuration bits (y = + 0..15) + 4 + 2 + + + + MODER1 + Port x configuration bits (y = + 0..15) + 2 + 2 + + + + MODER0 + Port x configuration bits (y = + 0..15) + 0 + 2 + + MODER0 + read-write + + Input + Input mode (reset state) + 0 + + + Output + General purpose output mode + 1 + + + Alternate + Alternate function mode + 2 + + + Analog + Analog mode + 3 + + + + + + + OTYPER + OTYPER + GPIO port output type register + 0x4 + 0x20 + read-write + 0x00000000 + + + OT15 + Port x configuration bits (y = + 0..15) + 15 + 1 + + + + OT14 + Port x configuration bits (y = + 0..15) + 14 + 1 + + + + OT13 + Port x configuration bits (y = + 0..15) + 13 + 1 + + + + OT12 + Port x configuration bits (y = + 0..15) + 12 + 1 + + + + OT11 + Port x configuration bits (y = + 0..15) + 11 + 1 + + + + OT10 + Port x configuration bits (y = + 0..15) + 10 + 1 + + + + OT9 + Port x configuration bits (y = + 0..15) + 9 + 1 + + + + OT8 + Port x configuration bits (y = + 0..15) + 8 + 1 + + + + OT7 + Port x configuration bits (y = + 0..15) + 7 + 1 + + + + OT6 + Port x configuration bits (y = + 0..15) + 6 + 1 + + + + OT5 + Port x configuration bits (y = + 0..15) + 5 + 1 + + + + OT4 + Port x configuration bits (y = + 0..15) + 4 + 1 + + + + OT3 + Port x configuration bits (y = + 0..15) + 3 + 1 + + + + OT2 + Port x configuration bits (y = + 0..15) + 2 + 1 + + + + OT1 + Port x configuration bits (y = + 0..15) + 1 + 1 + + + + OT0 + Port x configuration bits (y = + 0..15) + 0 + 1 + + OT0 + read-write + + PushPull + Output push-pull (reset state) + 0 + + + OpenDrain + Output open-drain + 1 + + + + + + + OSPEEDR + OSPEEDR + GPIO port output speed + register + 0x8 + 0x20 + read-write + 0x00000000 + + + OSPEEDR15 + Port x configuration bits (y = + 0..15) + 30 + 2 + + + + OSPEEDR14 + Port x configuration bits (y = + 0..15) + 28 + 2 + + + + OSPEEDR13 + Port x configuration bits (y = + 0..15) + 26 + 2 + + + + OSPEEDR12 + Port x configuration bits (y = + 0..15) + 24 + 2 + + + + OSPEEDR11 + Port x configuration bits (y = + 0..15) + 22 + 2 + + + + OSPEEDR10 + Port x configuration bits (y = + 0..15) + 20 + 2 + + + + OSPEEDR9 + Port x configuration bits (y = + 0..15) + 18 + 2 + + + + OSPEEDR8 + Port x configuration bits (y = + 0..15) + 16 + 2 + + + + OSPEEDR7 + Port x configuration bits (y = + 0..15) + 14 + 2 + + + + OSPEEDR6 + Port x configuration bits (y = + 0..15) + 12 + 2 + + + + OSPEEDR5 + Port x configuration bits (y = + 0..15) + 10 + 2 + + + + OSPEEDR4 + Port x configuration bits (y = + 0..15) + 8 + 2 + + + + OSPEEDR3 + Port x configuration bits (y = + 0..15) + 6 + 2 + + + + OSPEEDR2 + Port x configuration bits (y = + 0..15) + 4 + 2 + + + + OSPEEDR1 + Port x configuration bits (y = + 0..15) + 2 + 2 + + + + OSPEEDR0 + Port x configuration bits (y = + 0..15) + 0 + 2 + + OSPEEDR0 + read-write + + LowSpeed + Low speed + 0 + + + MediumSpeed + Medium speed + 1 + + + HighSpeed + High speed + 2 + + + VeryHighSpeed + Very high speed + 3 + + + + + + + PUPDR + PUPDR + GPIO port pull-up/pull-down + register + 0xC + 0x20 + read-write + 0x00000000 + + + PUPDR15 + Port x configuration bits (y = + 0..15) + 30 + 2 + + + + PUPDR14 + Port x configuration bits (y = + 0..15) + 28 + 2 + + + + PUPDR13 + Port x configuration bits (y = + 0..15) + 26 + 2 + + + + PUPDR12 + Port x configuration bits (y = + 0..15) + 24 + 2 + + + + PUPDR11 + Port x configuration bits (y = + 0..15) + 22 + 2 + + + + PUPDR10 + Port x configuration bits (y = + 0..15) + 20 + 2 + + + + PUPDR9 + Port x configuration bits (y = + 0..15) + 18 + 2 + + + + PUPDR8 + Port x configuration bits (y = + 0..15) + 16 + 2 + + + + PUPDR7 + Port x configuration bits (y = + 0..15) + 14 + 2 + + + + PUPDR6 + Port x configuration bits (y = + 0..15) + 12 + 2 + + + + PUPDR5 + Port x configuration bits (y = + 0..15) + 10 + 2 + + + + PUPDR4 + Port x configuration bits (y = + 0..15) + 8 + 2 + + + + PUPDR3 + Port x configuration bits (y = + 0..15) + 6 + 2 + + + + PUPDR2 + Port x configuration bits (y = + 0..15) + 4 + 2 + + + + PUPDR1 + Port x configuration bits (y = + 0..15) + 2 + 2 + + + + PUPDR0 + Port x configuration bits (y = + 0..15) + 0 + 2 + + PUPDR0 + read-write + + Floating + No pull-up, pull-down + 0 + + + PullUp + Pull-up + 1 + + + PullDown + Pull-down + 2 + + + + + + + IDR + IDR + GPIO port input data register + 0x10 + 0x20 + read-only + 0x00000000 + + + IDR15 + Port input data (y = + 0..15) + 15 + 1 + + + + IDR14 + Port input data (y = + 0..15) + 14 + 1 + + + + IDR13 + Port input data (y = + 0..15) + 13 + 1 + + + + IDR12 + Port input data (y = + 0..15) + 12 + 1 + + + + IDR11 + Port input data (y = + 0..15) + 11 + 1 + + + + IDR10 + Port input data (y = + 0..15) + 10 + 1 + + + + IDR9 + Port input data (y = + 0..15) + 9 + 1 + + + + IDR8 + Port input data (y = + 0..15) + 8 + 1 + + + + IDR7 + Port input data (y = + 0..15) + 7 + 1 + + + + IDR6 + Port input data (y = + 0..15) + 6 + 1 + + + + IDR5 + Port input data (y = + 0..15) + 5 + 1 + + + + IDR4 + Port input data (y = + 0..15) + 4 + 1 + + + + IDR3 + Port input data (y = + 0..15) + 3 + 1 + + + + IDR2 + Port input data (y = + 0..15) + 2 + 1 + + + + IDR1 + Port input data (y = + 0..15) + 1 + 1 + + + + IDR0 + Port input data (y = + 0..15) + 0 + 1 + + IDR0 + read + + Low + Input is logic low + 0 + + + High + Input is logic high + 1 + + + + + + + ODR + ODR + GPIO port output data register + 0x14 + 0x20 + read-write + 0x00000000 + + + ODR15 + Port output data (y = + 0..15) + 15 + 1 + + + + ODR14 + Port output data (y = + 0..15) + 14 + 1 + + + + ODR13 + Port output data (y = + 0..15) + 13 + 1 + + + + ODR12 + Port output data (y = + 0..15) + 12 + 1 + + + + ODR11 + Port output data (y = + 0..15) + 11 + 1 + + + + ODR10 + Port output data (y = + 0..15) + 10 + 1 + + + + ODR9 + Port output data (y = + 0..15) + 9 + 1 + + + + ODR8 + Port output data (y = + 0..15) + 8 + 1 + + + + ODR7 + Port output data (y = + 0..15) + 7 + 1 + + + + ODR6 + Port output data (y = + 0..15) + 6 + 1 + + + + ODR5 + Port output data (y = + 0..15) + 5 + 1 + + + + ODR4 + Port output data (y = + 0..15) + 4 + 1 + + + + ODR3 + Port output data (y = + 0..15) + 3 + 1 + + + + ODR2 + Port output data (y = + 0..15) + 2 + 1 + + + + ODR1 + Port output data (y = + 0..15) + 1 + 1 + + + + ODR0 + Port output data (y = + 0..15) + 0 + 1 + + ODR0 + read-write + + Low + Set output to logic low + 0 + + + High + Set output to logic high + 1 + + + + + + + BSRR + BSRR + GPIO port bit set/reset + register + 0x18 + 0x20 + write-only + 0x00000000 + + + BR15 + Port x reset bit y (y = + 0..15) + 31 + 1 + + + + BR14 + Port x reset bit y (y = + 0..15) + 30 + 1 + + + + BR13 + Port x reset bit y (y = + 0..15) + 29 + 1 + + + + BR12 + Port x reset bit y (y = + 0..15) + 28 + 1 + + + + BR11 + Port x reset bit y (y = + 0..15) + 27 + 1 + + + + BR10 + Port x reset bit y (y = + 0..15) + 26 + 1 + + + + BR9 + Port x reset bit y (y = + 0..15) + 25 + 1 + + + + BR8 + Port x reset bit y (y = + 0..15) + 24 + 1 + + + + BR7 + Port x reset bit y (y = + 0..15) + 23 + 1 + + + + BR6 + Port x reset bit y (y = + 0..15) + 22 + 1 + + + + BR5 + Port x reset bit y (y = + 0..15) + 21 + 1 + + + + BR4 + Port x reset bit y (y = + 0..15) + 20 + 1 + + + + BR3 + Port x reset bit y (y = + 0..15) + 19 + 1 + + + + BR2 + Port x reset bit y (y = + 0..15) + 18 + 1 + + + + BR1 + Port x reset bit y (y = + 0..15) + 17 + 1 + + + + BR0 + Port x set bit y (y= + 0..15) + 16 + 1 + + BR0W + write + + Reset + Resets the corresponding ODRx bit + 1 + + + + + BS15 + Port x set bit y (y= + 0..15) + 15 + 1 + + + + BS14 + Port x set bit y (y= + 0..15) + 14 + 1 + + + + BS13 + Port x set bit y (y= + 0..15) + 13 + 1 + + + + BS12 + Port x set bit y (y= + 0..15) + 12 + 1 + + + + BS11 + Port x set bit y (y= + 0..15) + 11 + 1 + + + + BS10 + Port x set bit y (y= + 0..15) + 10 + 1 + + + + BS9 + Port x set bit y (y= + 0..15) + 9 + 1 + + + + BS8 + Port x set bit y (y= + 0..15) + 8 + 1 + + + + BS7 + Port x set bit y (y= + 0..15) + 7 + 1 + + + + BS6 + Port x set bit y (y= + 0..15) + 6 + 1 + + + + BS5 + Port x set bit y (y= + 0..15) + 5 + 1 + + + + BS4 + Port x set bit y (y= + 0..15) + 4 + 1 + + + + BS3 + Port x set bit y (y= + 0..15) + 3 + 1 + + + + BS2 + Port x set bit y (y= + 0..15) + 2 + 1 + + + + BS1 + Port x set bit y (y= + 0..15) + 1 + 1 + + + + BS0 + Port x set bit y (y= + 0..15) + 0 + 1 + + BS0W + write + + Set + Sets the corresponding ODRx bit + 1 + + + + + + + LCKR + LCKR + GPIO port configuration lock + register + 0x1C + 0x20 + read-write + 0x00000000 + + + LCKK + Port x lock bit y (y= + 0..15) + 16 + 1 + + LCKK + read-write + + NotActive + Port configuration lock key not active + 0 + + + Active + Port configuration lock key active + 1 + + + + + LCK15 + Port x lock bit y (y= + 0..15) + 15 + 1 + + + + LCK14 + Port x lock bit y (y= + 0..15) + 14 + 1 + + + + LCK13 + Port x lock bit y (y= + 0..15) + 13 + 1 + + + + LCK12 + Port x lock bit y (y= + 0..15) + 12 + 1 + + + + LCK11 + Port x lock bit y (y= + 0..15) + 11 + 1 + + + + LCK10 + Port x lock bit y (y= + 0..15) + 10 + 1 + + + + LCK9 + Port x lock bit y (y= + 0..15) + 9 + 1 + + + + LCK8 + Port x lock bit y (y= + 0..15) + 8 + 1 + + + + LCK7 + Port x lock bit y (y= + 0..15) + 7 + 1 + + + + LCK6 + Port x lock bit y (y= + 0..15) + 6 + 1 + + + + LCK5 + Port x lock bit y (y= + 0..15) + 5 + 1 + + + + LCK4 + Port x lock bit y (y= + 0..15) + 4 + 1 + + + + LCK3 + Port x lock bit y (y= + 0..15) + 3 + 1 + + + + LCK2 + Port x lock bit y (y= + 0..15) + 2 + 1 + + + + LCK1 + Port x lock bit y (y= + 0..15) + 1 + 1 + + + + LCK0 + Port x lock bit y (y= + 0..15) + 0 + 1 + + LCK0 + read-write + + Unlocked + Port configuration not locked + 0 + + + Locked + Port configuration locked + 1 + + + + + + + AFRL + AFRL + GPIO alternate function low + register + 0x20 + 0x20 + read-write + 0x00000000 + + + AFRL7 + Alternate function selection for port x + bit y (y = 0..7) + 28 + 4 + + + + AFRL6 + Alternate function selection for port x + bit y (y = 0..7) + 24 + 4 + + + + AFRL5 + Alternate function selection for port x + bit y (y = 0..7) + 20 + 4 + + + + AFRL4 + Alternate function selection for port x + bit y (y = 0..7) + 16 + 4 + + + + AFRL3 + Alternate function selection for port x + bit y (y = 0..7) + 12 + 4 + + + + AFRL2 + Alternate function selection for port x + bit y (y = 0..7) + 8 + 4 + + + + AFRL1 + Alternate function selection for port x + bit y (y = 0..7) + 4 + 4 + + + + AFRL0 + Alternate function selection for port x + bit y (y = 0..7) + 0 + 4 + + AFRL0 + read-write + + AF0 + AF0 + 0 + + + AF1 + AF1 + 1 + + + AF2 + AF2 + 2 + + + AF3 + AF3 + 3 + + + AF4 + AF4 + 4 + + + AF5 + AF5 + 5 + + + AF6 + AF6 + 6 + + + AF7 + AF7 + 7 + + + AF8 + AF8 + 8 + + + AF9 + AF9 + 9 + + + AF10 + AF10 + 10 + + + AF11 + AF11 + 11 + + + AF12 + AF12 + 12 + + + AF13 + AF13 + 13 + + + AF14 + AF14 + 14 + + + AF15 + AF15 + 15 + + + + + + + AFRH + AFRH + GPIO alternate function high + register + 0x24 + 0x20 + read-write + 0x00000000 + + + AFRH15 + Alternate function selection for port x + bit y (y = 8..15) + 28 + 4 + + + + AFRH14 + Alternate function selection for port x + bit y (y = 8..15) + 24 + 4 + + + + AFRH13 + Alternate function selection for port x + bit y (y = 8..15) + 20 + 4 + + + + AFRH12 + Alternate function selection for port x + bit y (y = 8..15) + 16 + 4 + + + + AFRH11 + Alternate function selection for port x + bit y (y = 8..15) + 12 + 4 + + + + AFRH10 + Alternate function selection for port x + bit y (y = 8..15) + 8 + 4 + + + + AFRH9 + Alternate function selection for port x + bit y (y = 8..15) + 4 + 4 + + + + AFRH8 + Alternate function selection for port x + bit y (y = 8..15) + 0 + 4 + + AFRH8 + read-write + + AF0 + AF0 + 0 + + + AF1 + AF1 + 1 + + + AF2 + AF2 + 2 + + + AF3 + AF3 + 3 + + + AF4 + AF4 + 4 + + + AF5 + AF5 + 5 + + + AF6 + AF6 + 6 + + + AF7 + AF7 + 7 + + + AF8 + AF8 + 8 + + + AF9 + AF9 + 9 + + + AF10 + AF10 + 10 + + + AF11 + AF11 + 11 + + + AF12 + AF12 + 12 + + + AF13 + AF13 + 13 + + + AF14 + AF14 + 14 + + + AF15 + AF15 + 15 + + + + + + + + + GPIOE + 0x40021000 + + + GPIOD + 0x40020C00 + + TIM1_BRK_TIM9 + TIM1 Break interrupt and TIM9 global + interrupt + 24 + + + TIM1_UP_TIM10 + TIM1 Update interrupt and TIM10 global + interrupt + 25 + + + TIM1_TRG_COM_TIM11 + TIM1 Trigger and Commutation interrupts and + TIM11 global interrupt + 26 + + + TIM1_CC + TIM1 Capture Compare interrupt + 27 + + + + GPIOC + 0x40020800 + + TIM1_UP_TIM10 + TIM1 Update interrupt and TIM10 global + interrupt + 25 + + + + GPIOB + General-purpose I/Os + GPIO + 0x40020400 + + 0x0 + 0x400 + registers + + + TIM1_TRG_COM_TIM11 + TIM1 Trigger and Commutation interrupts and + TIM11 global interrupt + 26 + + + + MODER + MODER + GPIO port mode register + 0x0 + 0x20 + read-write + 0x00000280 + + + MODER15 + Port x configuration bits (y = + 0..15) + 30 + 2 + + + + MODER14 + Port x configuration bits (y = + 0..15) + 28 + 2 + + + + MODER13 + Port x configuration bits (y = + 0..15) + 26 + 2 + + + + MODER12 + Port x configuration bits (y = + 0..15) + 24 + 2 + + + + MODER11 + Port x configuration bits (y = + 0..15) + 22 + 2 + + + + MODER10 + Port x configuration bits (y = + 0..15) + 20 + 2 + + + + MODER9 + Port x configuration bits (y = + 0..15) + 18 + 2 + + + + MODER8 + Port x configuration bits (y = + 0..15) + 16 + 2 + + + + MODER7 + Port x configuration bits (y = + 0..15) + 14 + 2 + + + + MODER6 + Port x configuration bits (y = + 0..15) + 12 + 2 + + + + MODER5 + Port x configuration bits (y = + 0..15) + 10 + 2 + + + + MODER4 + Port x configuration bits (y = + 0..15) + 8 + 2 + + + + MODER3 + Port x configuration bits (y = + 0..15) + 6 + 2 + + + + MODER2 + Port x configuration bits (y = + 0..15) + 4 + 2 + + + + MODER1 + Port x configuration bits (y = + 0..15) + 2 + 2 + + + + MODER0 + Port x configuration bits (y = + 0..15) + 0 + 2 + + MODER0 + read-write + + Input + Input mode (reset state) + 0 + + + Output + General purpose output mode + 1 + + + Alternate + Alternate function mode + 2 + + + Analog + Analog mode + 3 + + + + + + + OTYPER + OTYPER + GPIO port output type register + 0x4 + 0x20 + read-write + 0x00000000 + + + OT15 + Port x configuration bits (y = + 0..15) + 15 + 1 + + + + OT14 + Port x configuration bits (y = + 0..15) + 14 + 1 + + + + OT13 + Port x configuration bits (y = + 0..15) + 13 + 1 + + + + OT12 + Port x configuration bits (y = + 0..15) + 12 + 1 + + + + OT11 + Port x configuration bits (y = + 0..15) + 11 + 1 + + + + OT10 + Port x configuration bits (y = + 0..15) + 10 + 1 + + + + OT9 + Port x configuration bits (y = + 0..15) + 9 + 1 + + + + OT8 + Port x configuration bits (y = + 0..15) + 8 + 1 + + + + OT7 + Port x configuration bits (y = + 0..15) + 7 + 1 + + + + OT6 + Port x configuration bits (y = + 0..15) + 6 + 1 + + + + OT5 + Port x configuration bits (y = + 0..15) + 5 + 1 + + + + OT4 + Port x configuration bits (y = + 0..15) + 4 + 1 + + + + OT3 + Port x configuration bits (y = + 0..15) + 3 + 1 + + + + OT2 + Port x configuration bits (y = + 0..15) + 2 + 1 + + + + OT1 + Port x configuration bits (y = + 0..15) + 1 + 1 + + + + OT0 + Port x configuration bits (y = + 0..15) + 0 + 1 + + OT0 + read-write + + PushPull + Output push-pull (reset state) + 0 + + + OpenDrain + Output open-drain + 1 + + + + + + + OSPEEDR + OSPEEDR + GPIO port output speed + register + 0x8 + 0x20 + read-write + 0x000000C0 + + + OSPEEDR15 + Port x configuration bits (y = + 0..15) + 30 + 2 + + + + OSPEEDR14 + Port x configuration bits (y = + 0..15) + 28 + 2 + + + + OSPEEDR13 + Port x configuration bits (y = + 0..15) + 26 + 2 + + + + OSPEEDR12 + Port x configuration bits (y = + 0..15) + 24 + 2 + + + + OSPEEDR11 + Port x configuration bits (y = + 0..15) + 22 + 2 + + + + OSPEEDR10 + Port x configuration bits (y = + 0..15) + 20 + 2 + + + + OSPEEDR9 + Port x configuration bits (y = + 0..15) + 18 + 2 + + + + OSPEEDR8 + Port x configuration bits (y = + 0..15) + 16 + 2 + + + + OSPEEDR7 + Port x configuration bits (y = + 0..15) + 14 + 2 + + + + OSPEEDR6 + Port x configuration bits (y = + 0..15) + 12 + 2 + + + + OSPEEDR5 + Port x configuration bits (y = + 0..15) + 10 + 2 + + + + OSPEEDR4 + Port x configuration bits (y = + 0..15) + 8 + 2 + + + + OSPEEDR3 + Port x configuration bits (y = + 0..15) + 6 + 2 + + + + OSPEEDR2 + Port x configuration bits (y = + 0..15) + 4 + 2 + + + + OSPEEDR1 + Port x configuration bits (y = + 0..15) + 2 + 2 + + + + OSPEEDR0 + Port x configuration bits (y = + 0..15) + 0 + 2 + + OSPEEDR0 + read-write + + LowSpeed + Low speed + 0 + + + MediumSpeed + Medium speed + 1 + + + HighSpeed + High speed + 2 + + + VeryHighSpeed + Very high speed + 3 + + + + + + + PUPDR + PUPDR + GPIO port pull-up/pull-down + register + 0xC + 0x20 + read-write + 0x00000100 + + + PUPDR15 + Port x configuration bits (y = + 0..15) + 30 + 2 + + + + PUPDR14 + Port x configuration bits (y = + 0..15) + 28 + 2 + + + + PUPDR13 + Port x configuration bits (y = + 0..15) + 26 + 2 + + + + PUPDR12 + Port x configuration bits (y = + 0..15) + 24 + 2 + + + + PUPDR11 + Port x configuration bits (y = + 0..15) + 22 + 2 + + + + PUPDR10 + Port x configuration bits (y = + 0..15) + 20 + 2 + + + + PUPDR9 + Port x configuration bits (y = + 0..15) + 18 + 2 + + + + PUPDR8 + Port x configuration bits (y = + 0..15) + 16 + 2 + + + + PUPDR7 + Port x configuration bits (y = + 0..15) + 14 + 2 + + + + PUPDR6 + Port x configuration bits (y = + 0..15) + 12 + 2 + + + + PUPDR5 + Port x configuration bits (y = + 0..15) + 10 + 2 + + + + PUPDR4 + Port x configuration bits (y = + 0..15) + 8 + 2 + + + + PUPDR3 + Port x configuration bits (y = + 0..15) + 6 + 2 + + + + PUPDR2 + Port x configuration bits (y = + 0..15) + 4 + 2 + + + + PUPDR1 + Port x configuration bits (y = + 0..15) + 2 + 2 + + + + PUPDR0 + Port x configuration bits (y = + 0..15) + 0 + 2 + + PUPDR0 + read-write + + Floating + No pull-up, pull-down + 0 + + + PullUp + Pull-up + 1 + + + PullDown + Pull-down + 2 + + + + + + + IDR + IDR + GPIO port input data register + 0x10 + 0x20 + read-only + 0x00000000 + + + IDR15 + Port input data (y = + 0..15) + 15 + 1 + + + + IDR14 + Port input data (y = + 0..15) + 14 + 1 + + + + IDR13 + Port input data (y = + 0..15) + 13 + 1 + + + + IDR12 + Port input data (y = + 0..15) + 12 + 1 + + + + IDR11 + Port input data (y = + 0..15) + 11 + 1 + + + + IDR10 + Port input data (y = + 0..15) + 10 + 1 + + + + IDR9 + Port input data (y = + 0..15) + 9 + 1 + + + + IDR8 + Port input data (y = + 0..15) + 8 + 1 + + + + IDR7 + Port input data (y = + 0..15) + 7 + 1 + + + + IDR6 + Port input data (y = + 0..15) + 6 + 1 + + + + IDR5 + Port input data (y = + 0..15) + 5 + 1 + + + + IDR4 + Port input data (y = + 0..15) + 4 + 1 + + + + IDR3 + Port input data (y = + 0..15) + 3 + 1 + + + + IDR2 + Port input data (y = + 0..15) + 2 + 1 + + + + IDR1 + Port input data (y = + 0..15) + 1 + 1 + + + + IDR0 + Port input data (y = + 0..15) + 0 + 1 + + IDR0 + read + + Low + Input is logic low + 0 + + + High + Input is logic high + 1 + + + + + + + ODR + ODR + GPIO port output data register + 0x14 + 0x20 + read-write + 0x00000000 + + + ODR15 + Port output data (y = + 0..15) + 15 + 1 + + + + ODR14 + Port output data (y = + 0..15) + 14 + 1 + + + + ODR13 + Port output data (y = + 0..15) + 13 + 1 + + + + ODR12 + Port output data (y = + 0..15) + 12 + 1 + + + + ODR11 + Port output data (y = + 0..15) + 11 + 1 + + + + ODR10 + Port output data (y = + 0..15) + 10 + 1 + + + + ODR9 + Port output data (y = + 0..15) + 9 + 1 + + + + ODR8 + Port output data (y = + 0..15) + 8 + 1 + + + + ODR7 + Port output data (y = + 0..15) + 7 + 1 + + + + ODR6 + Port output data (y = + 0..15) + 6 + 1 + + + + ODR5 + Port output data (y = + 0..15) + 5 + 1 + + + + ODR4 + Port output data (y = + 0..15) + 4 + 1 + + + + ODR3 + Port output data (y = + 0..15) + 3 + 1 + + + + ODR2 + Port output data (y = + 0..15) + 2 + 1 + + + + ODR1 + Port output data (y = + 0..15) + 1 + 1 + + + + ODR0 + Port output data (y = + 0..15) + 0 + 1 + + ODR0 + read-write + + Low + Set output to logic low + 0 + + + High + Set output to logic high + 1 + + + + + + + BSRR + BSRR + GPIO port bit set/reset + register + 0x18 + 0x20 + write-only + 0x00000000 + + + BR15 + Port x reset bit y (y = + 0..15) + 31 + 1 + + + + BR14 + Port x reset bit y (y = + 0..15) + 30 + 1 + + + + BR13 + Port x reset bit y (y = + 0..15) + 29 + 1 + + + + BR12 + Port x reset bit y (y = + 0..15) + 28 + 1 + + + + BR11 + Port x reset bit y (y = + 0..15) + 27 + 1 + + + + BR10 + Port x reset bit y (y = + 0..15) + 26 + 1 + + + + BR9 + Port x reset bit y (y = + 0..15) + 25 + 1 + + + + BR8 + Port x reset bit y (y = + 0..15) + 24 + 1 + + + + BR7 + Port x reset bit y (y = + 0..15) + 23 + 1 + + + + BR6 + Port x reset bit y (y = + 0..15) + 22 + 1 + + + + BR5 + Port x reset bit y (y = + 0..15) + 21 + 1 + + + + BR4 + Port x reset bit y (y = + 0..15) + 20 + 1 + + + + BR3 + Port x reset bit y (y = + 0..15) + 19 + 1 + + + + BR2 + Port x reset bit y (y = + 0..15) + 18 + 1 + + + + BR1 + Port x reset bit y (y = + 0..15) + 17 + 1 + + + + BR0 + Port x set bit y (y= + 0..15) + 16 + 1 + + BR0W + write + + Reset + Resets the corresponding ODRx bit + 1 + + + + + BS15 + Port x set bit y (y= + 0..15) + 15 + 1 + + + + BS14 + Port x set bit y (y= + 0..15) + 14 + 1 + + + + BS13 + Port x set bit y (y= + 0..15) + 13 + 1 + + + + BS12 + Port x set bit y (y= + 0..15) + 12 + 1 + + + + BS11 + Port x set bit y (y= + 0..15) + 11 + 1 + + + + BS10 + Port x set bit y (y= + 0..15) + 10 + 1 + + + + BS9 + Port x set bit y (y= + 0..15) + 9 + 1 + + + + BS8 + Port x set bit y (y= + 0..15) + 8 + 1 + + + + BS7 + Port x set bit y (y= + 0..15) + 7 + 1 + + + + BS6 + Port x set bit y (y= + 0..15) + 6 + 1 + + + + BS5 + Port x set bit y (y= + 0..15) + 5 + 1 + + + + BS4 + Port x set bit y (y= + 0..15) + 4 + 1 + + + + BS3 + Port x set bit y (y= + 0..15) + 3 + 1 + + + + BS2 + Port x set bit y (y= + 0..15) + 2 + 1 + + + + BS1 + Port x set bit y (y= + 0..15) + 1 + 1 + + + + BS0 + Port x set bit y (y= + 0..15) + 0 + 1 + + BS0W + write + + Set + Sets the corresponding ODRx bit + 1 + + + + + + + LCKR + LCKR + GPIO port configuration lock + register + 0x1C + 0x20 + read-write + 0x00000000 + + + LCKK + Port x lock bit y (y= + 0..15) + 16 + 1 + + LCKK + read-write + + NotActive + Port configuration lock key not active + 0 + + + Active + Port configuration lock key active + 1 + + + + + LCK15 + Port x lock bit y (y= + 0..15) + 15 + 1 + + + + LCK14 + Port x lock bit y (y= + 0..15) + 14 + 1 + + + + LCK13 + Port x lock bit y (y= + 0..15) + 13 + 1 + + + + LCK12 + Port x lock bit y (y= + 0..15) + 12 + 1 + + + + LCK11 + Port x lock bit y (y= + 0..15) + 11 + 1 + + + + LCK10 + Port x lock bit y (y= + 0..15) + 10 + 1 + + + + LCK9 + Port x lock bit y (y= + 0..15) + 9 + 1 + + + + LCK8 + Port x lock bit y (y= + 0..15) + 8 + 1 + + + + LCK7 + Port x lock bit y (y= + 0..15) + 7 + 1 + + + + LCK6 + Port x lock bit y (y= + 0..15) + 6 + 1 + + + + LCK5 + Port x lock bit y (y= + 0..15) + 5 + 1 + + + + LCK4 + Port x lock bit y (y= + 0..15) + 4 + 1 + + + + LCK3 + Port x lock bit y (y= + 0..15) + 3 + 1 + + + + LCK2 + Port x lock bit y (y= + 0..15) + 2 + 1 + + + + LCK1 + Port x lock bit y (y= + 0..15) + 1 + 1 + + + + LCK0 + Port x lock bit y (y= + 0..15) + 0 + 1 + + LCK0 + read-write + + Unlocked + Port configuration not locked + 0 + + + Locked + Port configuration locked + 1 + + + + + + + AFRL + AFRL + GPIO alternate function low + register + 0x20 + 0x20 + read-write + 0x00000000 + + + AFRL7 + Alternate function selection for port x + bit y (y = 0..7) + 28 + 4 + + + + AFRL6 + Alternate function selection for port x + bit y (y = 0..7) + 24 + 4 + + + + AFRL5 + Alternate function selection for port x + bit y (y = 0..7) + 20 + 4 + + + + AFRL4 + Alternate function selection for port x + bit y (y = 0..7) + 16 + 4 + + + + AFRL3 + Alternate function selection for port x + bit y (y = 0..7) + 12 + 4 + + + + AFRL2 + Alternate function selection for port x + bit y (y = 0..7) + 8 + 4 + + + + AFRL1 + Alternate function selection for port x + bit y (y = 0..7) + 4 + 4 + + + + AFRL0 + Alternate function selection for port x + bit y (y = 0..7) + 0 + 4 + + AFRL0 + read-write + + AF0 + AF0 + 0 + + + AF1 + AF1 + 1 + + + AF2 + AF2 + 2 + + + AF3 + AF3 + 3 + + + AF4 + AF4 + 4 + + + AF5 + AF5 + 5 + + + AF6 + AF6 + 6 + + + AF7 + AF7 + 7 + + + AF8 + AF8 + 8 + + + AF9 + AF9 + 9 + + + AF10 + AF10 + 10 + + + AF11 + AF11 + 11 + + + AF12 + AF12 + 12 + + + AF13 + AF13 + 13 + + + AF14 + AF14 + 14 + + + AF15 + AF15 + 15 + + + + + + + AFRH + AFRH + GPIO alternate function high + register + 0x24 + 0x20 + read-write + 0x00000000 + + + AFRH15 + Alternate function selection for port x + bit y (y = 8..15) + 28 + 4 + + + + AFRH14 + Alternate function selection for port x + bit y (y = 8..15) + 24 + 4 + + + + AFRH13 + Alternate function selection for port x + bit y (y = 8..15) + 20 + 4 + + + + AFRH12 + Alternate function selection for port x + bit y (y = 8..15) + 16 + 4 + + + + AFRH11 + Alternate function selection for port x + bit y (y = 8..15) + 12 + 4 + + + + AFRH10 + Alternate function selection for port x + bit y (y = 8..15) + 8 + 4 + + + + AFRH9 + Alternate function selection for port x + bit y (y = 8..15) + 4 + 4 + + + + AFRH8 + Alternate function selection for port x + bit y (y = 8..15) + 0 + 4 + + AFRH8 + read-write + + AF0 + AF0 + 0 + + + AF1 + AF1 + 1 + + + AF2 + AF2 + 2 + + + AF3 + AF3 + 3 + + + AF4 + AF4 + 4 + + + AF5 + AF5 + 5 + + + AF6 + AF6 + 6 + + + AF7 + AF7 + 7 + + + AF8 + AF8 + 8 + + + AF9 + AF9 + 9 + + + AF10 + AF10 + 10 + + + AF11 + AF11 + 11 + + + AF12 + AF12 + 12 + + + AF13 + AF13 + 13 + + + AF14 + AF14 + 14 + + + AF15 + AF15 + 15 + + + + + + + + + GPIOA + General-purpose I/Os + GPIO + 0x40020000 + + 0x0 + 0x400 + registers + + + TIM2 + TIM2 global interrupt + 28 + + + + MODER + MODER + GPIO port mode register + 0x0 + 0x20 + read-write + 0xA8000000 + + + MODER15 + Port x configuration bits (y = + 0..15) + 30 + 2 + + + + MODER14 + Port x configuration bits (y = + 0..15) + 28 + 2 + + + + MODER13 + Port x configuration bits (y = + 0..15) + 26 + 2 + + + + MODER12 + Port x configuration bits (y = + 0..15) + 24 + 2 + + + + MODER11 + Port x configuration bits (y = + 0..15) + 22 + 2 + + + + MODER10 + Port x configuration bits (y = + 0..15) + 20 + 2 + + + + MODER9 + Port x configuration bits (y = + 0..15) + 18 + 2 + + + + MODER8 + Port x configuration bits (y = + 0..15) + 16 + 2 + + + + MODER7 + Port x configuration bits (y = + 0..15) + 14 + 2 + + + + MODER6 + Port x configuration bits (y = + 0..15) + 12 + 2 + + + + MODER5 + Port x configuration bits (y = + 0..15) + 10 + 2 + + + + MODER4 + Port x configuration bits (y = + 0..15) + 8 + 2 + + + + MODER3 + Port x configuration bits (y = + 0..15) + 6 + 2 + + + + MODER2 + Port x configuration bits (y = + 0..15) + 4 + 2 + + + + MODER1 + Port x configuration bits (y = + 0..15) + 2 + 2 + + + + MODER0 + Port x configuration bits (y = + 0..15) + 0 + 2 + + MODER0 + read-write + + Input + Input mode (reset state) + 0 + + + Output + General purpose output mode + 1 + + + Alternate + Alternate function mode + 2 + + + Analog + Analog mode + 3 + + + + + + + OTYPER + OTYPER + GPIO port output type register + 0x4 + 0x20 + read-write + 0x00000000 + + + OT15 + Port x configuration bits (y = + 0..15) + 15 + 1 + + + + OT14 + Port x configuration bits (y = + 0..15) + 14 + 1 + + + + OT13 + Port x configuration bits (y = + 0..15) + 13 + 1 + + + + OT12 + Port x configuration bits (y = + 0..15) + 12 + 1 + + + + OT11 + Port x configuration bits (y = + 0..15) + 11 + 1 + + + + OT10 + Port x configuration bits (y = + 0..15) + 10 + 1 + + + + OT9 + Port x configuration bits (y = + 0..15) + 9 + 1 + + + + OT8 + Port x configuration bits (y = + 0..15) + 8 + 1 + + + + OT7 + Port x configuration bits (y = + 0..15) + 7 + 1 + + + + OT6 + Port x configuration bits (y = + 0..15) + 6 + 1 + + + + OT5 + Port x configuration bits (y = + 0..15) + 5 + 1 + + + + OT4 + Port x configuration bits (y = + 0..15) + 4 + 1 + + + + OT3 + Port x configuration bits (y = + 0..15) + 3 + 1 + + + + OT2 + Port x configuration bits (y = + 0..15) + 2 + 1 + + + + OT1 + Port x configuration bits (y = + 0..15) + 1 + 1 + + + + OT0 + Port x configuration bits (y = + 0..15) + 0 + 1 + + OT0 + read-write + + PushPull + Output push-pull (reset state) + 0 + + + OpenDrain + Output open-drain + 1 + + + + + + + OSPEEDR + OSPEEDR + GPIO port output speed + register + 0x8 + 0x20 + read-write + 0x00000000 + + + OSPEEDR15 + Port x configuration bits (y = + 0..15) + 30 + 2 + + + + OSPEEDR14 + Port x configuration bits (y = + 0..15) + 28 + 2 + + + + OSPEEDR13 + Port x configuration bits (y = + 0..15) + 26 + 2 + + + + OSPEEDR12 + Port x configuration bits (y = + 0..15) + 24 + 2 + + + + OSPEEDR11 + Port x configuration bits (y = + 0..15) + 22 + 2 + + + + OSPEEDR10 + Port x configuration bits (y = + 0..15) + 20 + 2 + + + + OSPEEDR9 + Port x configuration bits (y = + 0..15) + 18 + 2 + + + + OSPEEDR8 + Port x configuration bits (y = + 0..15) + 16 + 2 + + + + OSPEEDR7 + Port x configuration bits (y = + 0..15) + 14 + 2 + + + + OSPEEDR6 + Port x configuration bits (y = + 0..15) + 12 + 2 + + + + OSPEEDR5 + Port x configuration bits (y = + 0..15) + 10 + 2 + + + + OSPEEDR4 + Port x configuration bits (y = + 0..15) + 8 + 2 + + + + OSPEEDR3 + Port x configuration bits (y = + 0..15) + 6 + 2 + + + + OSPEEDR2 + Port x configuration bits (y = + 0..15) + 4 + 2 + + + + OSPEEDR1 + Port x configuration bits (y = + 0..15) + 2 + 2 + + + + OSPEEDR0 + Port x configuration bits (y = + 0..15) + 0 + 2 + + OSPEEDR0 + read-write + + LowSpeed + Low speed + 0 + + + MediumSpeed + Medium speed + 1 + + + HighSpeed + High speed + 2 + + + VeryHighSpeed + Very high speed + 3 + + + + + + + PUPDR + PUPDR + GPIO port pull-up/pull-down + register + 0xC + 0x20 + read-write + 0x64000000 + + + PUPDR15 + Port x configuration bits (y = + 0..15) + 30 + 2 + + + + PUPDR14 + Port x configuration bits (y = + 0..15) + 28 + 2 + + + + PUPDR13 + Port x configuration bits (y = + 0..15) + 26 + 2 + + + + PUPDR12 + Port x configuration bits (y = + 0..15) + 24 + 2 + + + + PUPDR11 + Port x configuration bits (y = + 0..15) + 22 + 2 + + + + PUPDR10 + Port x configuration bits (y = + 0..15) + 20 + 2 + + + + PUPDR9 + Port x configuration bits (y = + 0..15) + 18 + 2 + + + + PUPDR8 + Port x configuration bits (y = + 0..15) + 16 + 2 + + + + PUPDR7 + Port x configuration bits (y = + 0..15) + 14 + 2 + + + + PUPDR6 + Port x configuration bits (y = + 0..15) + 12 + 2 + + + + PUPDR5 + Port x configuration bits (y = + 0..15) + 10 + 2 + + + + PUPDR4 + Port x configuration bits (y = + 0..15) + 8 + 2 + + + + PUPDR3 + Port x configuration bits (y = + 0..15) + 6 + 2 + + + + PUPDR2 + Port x configuration bits (y = + 0..15) + 4 + 2 + + + + PUPDR1 + Port x configuration bits (y = + 0..15) + 2 + 2 + + + + PUPDR0 + Port x configuration bits (y = + 0..15) + 0 + 2 + + PUPDR0 + read-write + + Floating + No pull-up, pull-down + 0 + + + PullUp + Pull-up + 1 + + + PullDown + Pull-down + 2 + + + + + + + IDR + IDR + GPIO port input data register + 0x10 + 0x20 + read-only + 0x00000000 + + + IDR15 + Port input data (y = + 0..15) + 15 + 1 + + + + IDR14 + Port input data (y = + 0..15) + 14 + 1 + + + + IDR13 + Port input data (y = + 0..15) + 13 + 1 + + + + IDR12 + Port input data (y = + 0..15) + 12 + 1 + + + + IDR11 + Port input data (y = + 0..15) + 11 + 1 + + + + IDR10 + Port input data (y = + 0..15) + 10 + 1 + + + + IDR9 + Port input data (y = + 0..15) + 9 + 1 + + + + IDR8 + Port input data (y = + 0..15) + 8 + 1 + + + + IDR7 + Port input data (y = + 0..15) + 7 + 1 + + + + IDR6 + Port input data (y = + 0..15) + 6 + 1 + + + + IDR5 + Port input data (y = + 0..15) + 5 + 1 + + + + IDR4 + Port input data (y = + 0..15) + 4 + 1 + + + + IDR3 + Port input data (y = + 0..15) + 3 + 1 + + + + IDR2 + Port input data (y = + 0..15) + 2 + 1 + + + + IDR1 + Port input data (y = + 0..15) + 1 + 1 + + + + IDR0 + Port input data (y = + 0..15) + 0 + 1 + + IDR0 + read + + Low + Input is logic low + 0 + + + High + Input is logic high + 1 + + + + + + + ODR + ODR + GPIO port output data register + 0x14 + 0x20 + read-write + 0x00000000 + + + ODR15 + Port output data (y = + 0..15) + 15 + 1 + + + + ODR14 + Port output data (y = + 0..15) + 14 + 1 + + + + ODR13 + Port output data (y = + 0..15) + 13 + 1 + + + + ODR12 + Port output data (y = + 0..15) + 12 + 1 + + + + ODR11 + Port output data (y = + 0..15) + 11 + 1 + + + + ODR10 + Port output data (y = + 0..15) + 10 + 1 + + + + ODR9 + Port output data (y = + 0..15) + 9 + 1 + + + + ODR8 + Port output data (y = + 0..15) + 8 + 1 + + + + ODR7 + Port output data (y = + 0..15) + 7 + 1 + + + + ODR6 + Port output data (y = + 0..15) + 6 + 1 + + + + ODR5 + Port output data (y = + 0..15) + 5 + 1 + + + + ODR4 + Port output data (y = + 0..15) + 4 + 1 + + + + ODR3 + Port output data (y = + 0..15) + 3 + 1 + + + + ODR2 + Port output data (y = + 0..15) + 2 + 1 + + + + ODR1 + Port output data (y = + 0..15) + 1 + 1 + + + + ODR0 + Port output data (y = + 0..15) + 0 + 1 + + ODR0 + read-write + + Low + Set output to logic low + 0 + + + High + Set output to logic high + 1 + + + + + + + BSRR + BSRR + GPIO port bit set/reset + register + 0x18 + 0x20 + write-only + 0x00000000 + + + BR15 + Port x reset bit y (y = + 0..15) + 31 + 1 + + + + BR14 + Port x reset bit y (y = + 0..15) + 30 + 1 + + + + BR13 + Port x reset bit y (y = + 0..15) + 29 + 1 + + + + BR12 + Port x reset bit y (y = + 0..15) + 28 + 1 + + + + BR11 + Port x reset bit y (y = + 0..15) + 27 + 1 + + + + BR10 + Port x reset bit y (y = + 0..15) + 26 + 1 + + + + BR9 + Port x reset bit y (y = + 0..15) + 25 + 1 + + + + BR8 + Port x reset bit y (y = + 0..15) + 24 + 1 + + + + BR7 + Port x reset bit y (y = + 0..15) + 23 + 1 + + + + BR6 + Port x reset bit y (y = + 0..15) + 22 + 1 + + + + BR5 + Port x reset bit y (y = + 0..15) + 21 + 1 + + + + BR4 + Port x reset bit y (y = + 0..15) + 20 + 1 + + + + BR3 + Port x reset bit y (y = + 0..15) + 19 + 1 + + + + BR2 + Port x reset bit y (y = + 0..15) + 18 + 1 + + + + BR1 + Port x reset bit y (y = + 0..15) + 17 + 1 + + + + BR0 + Port x set bit y (y= + 0..15) + 16 + 1 + + BR0W + write + + Reset + Resets the corresponding ODRx bit + 1 + + + + + BS15 + Port x set bit y (y= + 0..15) + 15 + 1 + + + + BS14 + Port x set bit y (y= + 0..15) + 14 + 1 + + + + BS13 + Port x set bit y (y= + 0..15) + 13 + 1 + + + + BS12 + Port x set bit y (y= + 0..15) + 12 + 1 + + + + BS11 + Port x set bit y (y= + 0..15) + 11 + 1 + + + + BS10 + Port x set bit y (y= + 0..15) + 10 + 1 + + + + BS9 + Port x set bit y (y= + 0..15) + 9 + 1 + + + + BS8 + Port x set bit y (y= + 0..15) + 8 + 1 + + + + BS7 + Port x set bit y (y= + 0..15) + 7 + 1 + + + + BS6 + Port x set bit y (y= + 0..15) + 6 + 1 + + + + BS5 + Port x set bit y (y= + 0..15) + 5 + 1 + + + + BS4 + Port x set bit y (y= + 0..15) + 4 + 1 + + + + BS3 + Port x set bit y (y= + 0..15) + 3 + 1 + + + + BS2 + Port x set bit y (y= + 0..15) + 2 + 1 + + + + BS1 + Port x set bit y (y= + 0..15) + 1 + 1 + + + + BS0 + Port x set bit y (y= + 0..15) + 0 + 1 + + BS0W + write + + Set + Sets the corresponding ODRx bit + 1 + + + + + + + LCKR + LCKR + GPIO port configuration lock + register + 0x1C + 0x20 + read-write + 0x00000000 + + + LCKK + Port x lock bit y (y= + 0..15) + 16 + 1 + + LCKK + read-write + + NotActive + Port configuration lock key not active + 0 + + + Active + Port configuration lock key active + 1 + + + + + LCK15 + Port x lock bit y (y= + 0..15) + 15 + 1 + + + + LCK14 + Port x lock bit y (y= + 0..15) + 14 + 1 + + + + LCK13 + Port x lock bit y (y= + 0..15) + 13 + 1 + + + + LCK12 + Port x lock bit y (y= + 0..15) + 12 + 1 + + + + LCK11 + Port x lock bit y (y= + 0..15) + 11 + 1 + + + + LCK10 + Port x lock bit y (y= + 0..15) + 10 + 1 + + + + LCK9 + Port x lock bit y (y= + 0..15) + 9 + 1 + + + + LCK8 + Port x lock bit y (y= + 0..15) + 8 + 1 + + + + LCK7 + Port x lock bit y (y= + 0..15) + 7 + 1 + + + + LCK6 + Port x lock bit y (y= + 0..15) + 6 + 1 + + + + LCK5 + Port x lock bit y (y= + 0..15) + 5 + 1 + + + + LCK4 + Port x lock bit y (y= + 0..15) + 4 + 1 + + + + LCK3 + Port x lock bit y (y= + 0..15) + 3 + 1 + + + + LCK2 + Port x lock bit y (y= + 0..15) + 2 + 1 + + + + LCK1 + Port x lock bit y (y= + 0..15) + 1 + 1 + + + + LCK0 + Port x lock bit y (y= + 0..15) + 0 + 1 + + LCK0 + read-write + + Unlocked + Port configuration not locked + 0 + + + Locked + Port configuration locked + 1 + + + + + + + AFRL + AFRL + GPIO alternate function low + register + 0x20 + 0x20 + read-write + 0x00000000 + + + AFRL7 + Alternate function selection for port x + bit y (y = 0..7) + 28 + 4 + + + + AFRL6 + Alternate function selection for port x + bit y (y = 0..7) + 24 + 4 + + + + AFRL5 + Alternate function selection for port x + bit y (y = 0..7) + 20 + 4 + + + + AFRL4 + Alternate function selection for port x + bit y (y = 0..7) + 16 + 4 + + + + AFRL3 + Alternate function selection for port x + bit y (y = 0..7) + 12 + 4 + + + + AFRL2 + Alternate function selection for port x + bit y (y = 0..7) + 8 + 4 + + + + AFRL1 + Alternate function selection for port x + bit y (y = 0..7) + 4 + 4 + + + + AFRL0 + Alternate function selection for port x + bit y (y = 0..7) + 0 + 4 + + AFRL0 + read-write + + AF0 + AF0 + 0 + + + AF1 + AF1 + 1 + + + AF2 + AF2 + 2 + + + AF3 + AF3 + 3 + + + AF4 + AF4 + 4 + + + AF5 + AF5 + 5 + + + AF6 + AF6 + 6 + + + AF7 + AF7 + 7 + + + AF8 + AF8 + 8 + + + AF9 + AF9 + 9 + + + AF10 + AF10 + 10 + + + AF11 + AF11 + 11 + + + AF12 + AF12 + 12 + + + AF13 + AF13 + 13 + + + AF14 + AF14 + 14 + + + AF15 + AF15 + 15 + + + + + + + AFRH + AFRH + GPIO alternate function high + register + 0x24 + 0x20 + read-write + 0x00000000 + + + AFRH15 + Alternate function selection for port x + bit y (y = 8..15) + 28 + 4 + + + + AFRH14 + Alternate function selection for port x + bit y (y = 8..15) + 24 + 4 + + + + AFRH13 + Alternate function selection for port x + bit y (y = 8..15) + 20 + 4 + + + + AFRH12 + Alternate function selection for port x + bit y (y = 8..15) + 16 + 4 + + + + AFRH11 + Alternate function selection for port x + bit y (y = 8..15) + 12 + 4 + + + + AFRH10 + Alternate function selection for port x + bit y (y = 8..15) + 8 + 4 + + + + AFRH9 + Alternate function selection for port x + bit y (y = 8..15) + 4 + 4 + + + + AFRH8 + Alternate function selection for port x + bit y (y = 8..15) + 0 + 4 + + AFRH8 + read-write + + AF0 + AF0 + 0 + + + AF1 + AF1 + 1 + + + AF2 + AF2 + 2 + + + AF3 + AF3 + 3 + + + AF4 + AF4 + 4 + + + AF5 + AF5 + 5 + + + AF6 + AF6 + 6 + + + AF7 + AF7 + 7 + + + AF8 + AF8 + 8 + + + AF9 + AF9 + 9 + + + AF10 + AF10 + 10 + + + AF11 + AF11 + 11 + + + AF12 + AF12 + 12 + + + AF13 + AF13 + 13 + + + AF14 + AF14 + 14 + + + AF15 + AF15 + 15 + + + + + + + + + I2C3 + 0x40005C00 + + TIM3 + TIM3 global interrupt + 29 + + + + I2C2 + 0x40005800 + + I2C3_EV + I2C3 event interrupt + 72 + + + I2C3_ER + I2C3 error interrupt + 73 + + + + I2C1 + Inter-integrated circuit + I2C + 0x40005400 + + 0x0 + 0x400 + registers + + + I2C2_EV + I2C2 event interrupt + 33 + + + I2C2_ER + I2C2 error interrupt + 34 + + + + CR1 + CR1 + Control register 1 + 0x0 + 0x20 + read-write + 0x00000000 + + + SWRST + Software reset + 15 + 1 + + SWRST + read-write + + NotReset + I2C peripheral not under reset + 0 + + + Reset + I2C peripheral under reset + 1 + + + + + ALERT + SMBus alert + 13 + 1 + + ALERT + read-write + + Release + SMBA pin released high + 0 + + + Drive + SMBA pin driven low + 1 + + + + + PEC + Packet error checking + 12 + 1 + + PEC + read-write + + Disabled + No PEC transfer + 0 + + + Enabled + PEC transfer + 1 + + + + + POS + Acknowledge/PEC Position (for data + reception) + 11 + 1 + + POS + read-write + + Current + ACK bit controls the (N)ACK of the current byte being received + 0 + + + Next + ACK bit controls the (N)ACK of the next byte to be received + 1 + + + + + ACK + Acknowledge enable + 10 + 1 + + ACK + read-write + + NAK + No acknowledge returned + 0 + + + ACK + Acknowledge returned after a byte is received + 1 + + + + + STOP + Stop generation + 9 + 1 + + STOP + read-write + + NoStop + No Stop generation + 0 + + + Stop + In master mode: stop generation after current byte/start, in slave mode: release SCL and SDA after current byte + 1 + + + + + START + Start generation + 8 + 1 + + START + read-write + + NoStart + No Start generation + 0 + + + Start + In master mode: repeated start generation, in slave mode: start generation when bus is free + 1 + + + + + NOSTRETCH + Clock stretching disable (Slave + mode) + 7 + 1 + + NOSTRETCH + read-write + + Enabled + Clock stretching enabled + 0 + + + Disabled + Clock stretching disabled + 1 + + + + + ENGC + General call enable + 6 + 1 + + ENGC + read-write + + Disabled + General call disabled + 0 + + + Enabled + General call enabled + 1 + + + + + ENPEC + PEC enable + 5 + 1 + + ENPEC + read-write + + Disabled + PEC calculation disabled + 0 + + + Enabled + PEC calculation enabled + 1 + + + + + ENARP + ARP enable + 4 + 1 + + ENARP + read-write + + Disabled + ARP disabled + 0 + + + Enabled + ARP enabled + 1 + + + + + SMBTYPE + SMBus type + 3 + 1 + + SMBTYPE + read-write + + Device + SMBus Device + 0 + + + Host + SMBus Host + 1 + + + + + SMBUS + SMBus mode + 1 + 1 + + SMBUS + read-write + + I2C + I2C Mode + 0 + + + SMBus + SMBus + 1 + + + + + PE + Peripheral enable + 0 + 1 + + PE + read-write + + Disabled + Peripheral disabled + 0 + + + Enabled + Peripheral enabled + 1 + + + + + + + CR2 + CR2 + Control register 2 + 0x4 + 0x20 + read-write + 0x00000000 + + + LAST + DMA last transfer + 12 + 1 + + LAST + read-write + + NotLast + Next DMA EOT is not the last transfer + 0 + + + Last + Next DMA EOT is the last transfer + 1 + + + + + DMAEN + DMA requests enable + 11 + 1 + + DMAEN + read-write + + Disabled + DMA requests disabled + 0 + + + Enabled + DMA request enabled when TxE=1 or RxNE=1 + 1 + + + + + ITBUFEN + Buffer interrupt enable + 10 + 1 + + ITBUFEN + read-write + + Disabled + TxE=1 or RxNE=1 does not generate any interrupt + 0 + + + Enabled + TxE=1 or RxNE=1 generates Event interrupt + 1 + + + + + ITEVTEN + Event interrupt enable + 9 + 1 + + ITEVTEN + read-write + + Disabled + Event interrupt disabled + 0 + + + Enabled + Event interrupt enabled + 1 + + + + + ITERREN + Error interrupt enable + 8 + 1 + + ITERREN + read-write + + Disabled + Error interrupt disabled + 0 + + + Enabled + Error interrupt enabled + 1 + + + + + FREQ + Peripheral clock frequency + 0 + 6 + + + 2 + 50 + + + + + + + OAR1 + OAR1 + Own address register 1 + 0x8 + 0x20 + read-write + 0x00000000 + + + ADDMODE + Addressing mode (slave + mode) + 15 + 1 + + ADDMODE + read-write + + ADD7 + 7-bit slave address + 0 + + + ADD10 + 10-bit slave address + 1 + + + + + ADD + Interface address + 0 + 10 + + + 0 + 1023 + + + + + + + OAR2 + OAR2 + Own address register 2 + 0xC + 0x20 + read-write + 0x00000000 + + + ADD2 + Interface address + 1 + 7 + + + 0 + 127 + + + + + ENDUAL + Dual addressing mode + enable + 0 + 1 + + ENDUAL + read-write + + Single + Single addressing mode + 0 + + + Dual + Dual addressing mode + 1 + + + + + + + DR + DR + Data register + 0x10 + 0x20 + read-write + 0x00000000 + + + DR + 8-bit data register + 0 + 8 + + + 0 + 255 + + + + + + + SR1 + SR1 + Status register 1 + 0x14 + 0x20 + 0x00000000 + + + SMBALERT + SMBus alert + 15 + 1 + read-write + zeroToClear + + SMBALERTR + read + + NoAlert + No SMBALERT occured + 0 + + + Alert + SMBALERT occurred + 1 + + + + SMBALERTW + write + + Clear + Clear flag + 0 + + + + + TIMEOUT + Timeout or Tlow error + 14 + 1 + read-write + zeroToClear + + TIMEOUTR + read + + NoTimeout + No Timeout error + 0 + + + Timeout + SCL remained LOW for 25 ms + 1 + + + + TIMEOUTW + write + + Clear + Clear flag + 0 + + + + + PECERR + PEC Error in reception + 12 + 1 + read-write + zeroToClear + + PECERRR + read + + NoError + no PEC error: receiver returns ACK after PEC reception (if ACK=1) + 0 + + + Error + PEC error: receiver returns NACK after PEC reception (whatever ACK) + 1 + + + + PECERRW + write + + Clear + Clear flag + 0 + + + + + OVR + Overrun/Underrun + 11 + 1 + read-write + zeroToClear + + OVRR + read + + NoOverrun + No overrun/underrun occured + 0 + + + Overrun + Overrun/underrun occured + 1 + + + + OVRW + write + + Clear + Clear flag + 0 + + + + + AF + Acknowledge failure + 10 + 1 + read-write + zeroToClear + + AFR + read + + NoFailure + No acknowledge failure + 0 + + + Failure + Acknowledge failure + 1 + + + + AFW + write + + Clear + Clear flag + 0 + + + + + ARLO + Arbitration lost (master + mode) + 9 + 1 + read-write + zeroToClear + + ARLOR + read + + NoLost + No Arbitration Lost detected + 0 + + + Lost + Arbitration Lost detected + 1 + + + + ARLOW + write + + Clear + Clear flag + 0 + + + + + BERR + Bus error + 8 + 1 + read-write + zeroToClear + + BERRR + read + + NoError + No misplaced Start or Stop condition + 0 + + + Error + Misplaced Start or Stop condition + 1 + + + + BERRW + write + + Clear + Clear flag + 0 + + + + + TxE + Data register empty + (transmitters) + 7 + 1 + read-only + + TxE + read + + NotEmpty + Data register not empty + 0 + + + Empty + Data register empty + 1 + + + + + RxNE + Data register not empty + (receivers) + 6 + 1 + read-only + + RxNE + read + + Empty + Data register empty + 0 + + + NotEmpty + Data register not empty + 1 + + + + + STOPF + Stop detection (slave + mode) + 4 + 1 + read-only + + STOPF + read + + NoStop + No Stop condition detected + 0 + + + Stop + Stop condition detected + 1 + + + + + ADD10 + 10-bit header sent (Master + mode) + 3 + 1 + read-only + + + BTF + Byte transfer finished + 2 + 1 + read-only + + BTF + read + + NotFinished + Data byte transfer not done + 0 + + + Finished + Data byte transfer successful + 1 + + + + + ADDR + Address sent (master mode)/matched + (slave mode) + 1 + 1 + read-only + + ADDR + read + + NotMatch + Adress mismatched or not received + 0 + + + Match + Received slave address matched with one of the enabled slave addresses + 1 + + + + + SB + Start bit (Master mode) + 0 + 1 + read-only + + SB + read + + NoStart + No Start condition + 0 + + + Start + Start condition generated + 1 + + + + + + + SR2 + SR2 + Status register 2 + 0x18 + 0x20 + read-only + 0x00000000 + + + PEC + acket error checking + register + 8 + 8 + + + DUALF + Dual flag (Slave mode) + 7 + 1 + + + SMBHOST + SMBus host header (Slave + mode) + 6 + 1 + + + SMBDEFAULT + SMBus device default address (Slave + mode) + 5 + 1 + + + GENCALL + General call address (Slave + mode) + 4 + 1 + + + TRA + Transmitter/receiver + 2 + 1 + + + BUSY + Bus busy + 1 + 1 + + + MSL + Master/slave + 0 + 1 + + + + + CCR + CCR + Clock control register + 0x1C + 0x20 + read-write + 0x00000000 + + + F_S + I2C master mode selection + 15 + 1 + + F_S + read-write + + Standard + Standard mode I2C + 0 + + + Fast + Fast mode I2C + 1 + + + + + DUTY + Fast mode duty cycle + 14 + 1 + + DUTY + read-write + + Duty2_1 + Duty cycle t_low/t_high = 2/1 + 0 + + + Duty16_9 + Duty cycle t_low/t_high = 16/9 + 1 + + + + + CCR + Clock control register in Fast/Standard + mode (Master mode) + 0 + 12 + + + 1 + 4095 + + + + + + + TRISE + TRISE + TRISE register + 0x20 + 0x20 + read-write + 0x00000002 + + + TRISE + Maximum rise time in Fast/Standard mode + (Master mode) + 0 + 6 + + + 0 + 63 + + + + + + + FLTR + FLTR register + 0x24 + read-write + 0x00000000 + + + ANOFF + Analog noise filter + 4 + 1 + + ANOFF + read-write + + Enabled + Analog noise filter enabled + 0 + + + Disabled + Analog noise filter disabled + 1 + + + + + DNF + Digital noise filter + 0 + 4 + + DNF + read-write + + NoFilter + Digital filter disabled + 0 + + + Filter1 + Digital filter enabled and filtering capability up to 1 tI2CCLK + 1 + + + Filter2 + Digital filter enabled and filtering capability up to 2 tI2CCLK + 2 + + + Filter3 + Digital filter enabled and filtering capability up to 3 tI2CCLK + 3 + + + Filter4 + Digital filter enabled and filtering capability up to 4 tI2CCLK + 4 + + + Filter5 + Digital filter enabled and filtering capability up to 5 tI2CCLK + 5 + + + Filter6 + Digital filter enabled and filtering capability up to 6 tI2CCLK + 6 + + + Filter7 + Digital filter enabled and filtering capability up to 7 tI2CCLK + 7 + + + Filter8 + Digital filter enabled and filtering capability up to 8 tI2CCLK + 8 + + + Filter9 + Digital filter enabled and filtering capability up to 9 tI2CCLK + 9 + + + Filter10 + Digital filter enabled and filtering capability up to 10 tI2CCLK + 10 + + + Filter11 + Digital filter enabled and filtering capability up to 11 tI2CCLK + 11 + + + Filter12 + Digital filter enabled and filtering capability up to 12 tI2CCLK + 12 + + + Filter13 + Digital filter enabled and filtering capability up to 13 tI2CCLK + 13 + + + Filter14 + Digital filter enabled and filtering capability up to 14 tI2CCLK + 14 + + + Filter15 + Digital filter enabled and filtering capability up to 15 tI2CCLK + 15 + + + + + + + + + I2S2ext + 0x40003400 + + I2C1_EV + I2C1 event interrupt + 31 + + + I2C1_ER + I2C1 error interrupt + 32 + + + + I2S3ext + 0x40004000 + + + SPI1 + Serial peripheral interface + SPI + 0x40013000 + + 0x0 + 0x400 + registers + + + + CR1 + CR1 + control register 1 + 0x0 + 0x20 + read-write + 0x00000000 + + + BIDIMODE + Bidirectional data mode + enable + 15 + 1 + + BIDIMODE + read-write + + Unidirectional + 2-line unidirectional data mode selected + 0 + + + Bidirectional + 1-line bidirectional data mode selected + 1 + + + + + BIDIOE + Output enable in bidirectional + mode + 14 + 1 + + BIDIOE + read-write + + OutputDisabled + Output disabled (receive-only mode) + 0 + + + OutputEnabled + Output enabled (transmit-only mode) + 1 + + + + + CRCEN + Hardware CRC calculation + enable + 13 + 1 + + CRCEN + read-write + + Disabled + CRC calculation disabled + 0 + + + Enabled + CRC calculation enabled + 1 + + + + + CRCNEXT + CRC transfer next + 12 + 1 + + CRCNEXT + read-write + + TxBuffer + Next transmit value is from Tx buffer + 0 + + + CRC + Next transmit value is from Tx CRC register + 1 + + + + + DFF + Data frame format + 11 + 1 + + DFF + read-write + + EightBit + 8-bit data frame format is selected for transmission/reception + 0 + + + SixteenBit + 16-bit data frame format is selected for transmission/reception + 1 + + + + + RXONLY + Receive only + 10 + 1 + + RXONLY + read-write + + FullDuplex + Full duplex (Transmit and receive) + 0 + + + OutputDisabled + Output disabled (Receive-only mode) + 1 + + + + + SSM + Software slave management + 9 + 1 + + SSM + read-write + + Disabled + Software slave management disabled + 0 + + + Enabled + Software slave management enabled + 1 + + + + + SSI + Internal slave select + 8 + 1 + + SSI + read-write + + SlaveSelected + 0 is forced onto the NSS pin and the I/O value of the NSS pin is ignored + 0 + + + SlaveNotSelected + 1 is forced onto the NSS pin and the I/O value of the NSS pin is ignored + 1 + + + + + LSBFIRST + Frame format + 7 + 1 + + LSBFIRST + read-write + + MSBFirst + Data is transmitted/received with the MSB first + 0 + + + LSBFirst + Data is transmitted/received with the LSB first + 1 + + + + + SPE + SPI enable + 6 + 1 + + SPE + read-write + + Disabled + Peripheral disabled + 0 + + + Enabled + Peripheral enabled + 1 + + + + + BR + Baud rate control + 3 + 3 + + BR + read-write + + Div2 + f_PCLK / 2 + 0 + + + Div4 + f_PCLK / 4 + 1 + + + Div8 + f_PCLK / 8 + 2 + + + Div16 + f_PCLK / 16 + 3 + + + Div32 + f_PCLK / 32 + 4 + + + Div64 + f_PCLK / 64 + 5 + + + Div128 + f_PCLK / 128 + 6 + + + Div256 + f_PCLK / 256 + 7 + + + + + MSTR + Master selection + 2 + 1 + + MSTR + read-write + + Slave + Slave configuration + 0 + + + Master + Master configuration + 1 + + + + + CPOL + Clock polarity + 1 + 1 + + CPOL + read-write + + IdleLow + CK to 0 when idle + 0 + + + IdleHigh + CK to 1 when idle + 1 + + + + + CPHA + Clock phase + 0 + 1 + + CPHA + read-write + + FirstEdge + The first clock transition is the first data capture edge + 0 + + + SecondEdge + The second clock transition is the first data capture edge + 1 + + + + + + + CR2 + CR2 + control register 2 + 0x4 + 0x20 + read-write + 0x00000000 + + + TXEIE + Tx buffer empty interrupt + enable + 7 + 1 + + TXEIE + read-write + + Masked + TXE interrupt masked + 0 + + + NotMasked + TXE interrupt not masked + 1 + + + + + RXNEIE + RX buffer not empty interrupt + enable + 6 + 1 + + RXNEIE + read-write + + Masked + RXE interrupt masked + 0 + + + NotMasked + RXE interrupt not masked + 1 + + + + + ERRIE + Error interrupt enable + 5 + 1 + + ERRIE + read-write + + Masked + Error interrupt masked + 0 + + + NotMasked + Error interrupt not masked + 1 + + + + + FRF + Frame format + 4 + 1 + + FRF + read-write + + Motorola + SPI Motorola mode + 0 + + + TI + SPI TI mode + 1 + + + + + SSOE + SS output enable + 2 + 1 + + SSOE + read-write + + Disabled + SS output is disabled in master mode + 0 + + + Enabled + SS output is enabled in master mode + 1 + + + + + TXDMAEN + Tx buffer DMA enable + 1 + 1 + + TXDMAEN + read-write + + Disabled + Tx buffer DMA disabled + 0 + + + Enabled + Tx buffer DMA enabled + 1 + + + + + RXDMAEN + Rx buffer DMA enable + 0 + 1 + + RXDMAEN + read-write + + Disabled + Rx buffer DMA disabled + 0 + + + Enabled + Rx buffer DMA enabled + 1 + + + + + + + SR + SR + status register + 0x8 + 0x20 + 0x00000002 + + + FRE + TI frame format error + 8 + 1 + read-only + + FRER + read + + NoError + No frame format error + 0 + + + Error + A frame format error occurred + 1 + + + + + BSY + Busy flag + 7 + 1 + read-only + + BSYR + read + + NotBusy + SPI not busy + 0 + + + Busy + SPI busy + 1 + + + + + OVR + Overrun flag + 6 + 1 + read-only + + OVRR + read + + NoOverrun + No overrun occurred + 0 + + + Overrun + Overrun occurred + 1 + + + + + MODF + Mode fault + 5 + 1 + read-only + + MODFR + read + + NoFault + No mode fault occurred + 0 + + + Fault + Mode fault occurred + 1 + + + + + CRCERR + CRC error flag + 4 + 1 + read-write + zeroToClear + + CRCERRR + read + + Match + CRC value received matches the SPIx_RXCRCR value + 0 + + + NoMatch + CRC value received does not match the SPIx_RXCRCR value + 1 + + + + CRCERRW + write + + Clear + Clear flag + 0 + + + + + UDR + Underrun flag + 3 + 1 + read-only + + UDRR + read + + NoUnderrun + No underrun occurred + 0 + + + Underrun + Underrun occurred + 1 + + + + + CHSIDE + Channel side + 2 + 1 + read-only + + CHSIDE + read + + Left + Channel left has to be transmitted or has been received + 0 + + + Right + Channel right has to be transmitted or has been received + 1 + + + + + TXE + Transmit buffer empty + 1 + 1 + read-only + + TXE + read + + NotEmpty + Tx buffer not empty + 0 + + + Empty + Tx buffer empty + 1 + + + + + RXNE + Receive buffer not empty + 0 + 1 + read-only + + RXNE + read + + Empty + Rx buffer empty + 0 + + + NotEmpty + Rx buffer not empty + 1 + + + + + + + DR + DR + data register + 0xC + 0x20 + read-write + 0x00000000 + + + DR + Data register + 0 + 16 + + + 0 + 65535 + + + + + + + CRCPR + CRCPR + CRC polynomial register + 0x10 + 0x20 + read-write + 0x00000007 + + + CRCPOLY + CRC polynomial register + 0 + 16 + + + 0 + 65535 + + + + + + + RXCRCR + RXCRCR + RX CRC register + 0x14 + 0x20 + read-only + 0x00000000 + + + RxCRC + Rx CRC register + 0 + 16 + + + 0 + 65535 + + + + + + + TXCRCR + TXCRCR + TX CRC register + 0x18 + 0x20 + read-only + 0x00000000 + + + TxCRC + Tx CRC register + 0 + 16 + + + 0 + 65535 + + + + + + + I2SCFGR + I2SCFGR + I2S configuration register + 0x1C + 0x20 + read-write + 0x00000000 + + + I2SMOD + I2S mode selection + 11 + 1 + + I2SMOD + read-write + + SPIMode + SPI mode is selected + 0 + + + I2SMode + I2S mode is selected + 1 + + + + + I2SE + I2S Enable + 10 + 1 + + I2SE + read-write + + Disabled + I2S peripheral is disabled + 0 + + + Enabled + I2S peripheral is enabled + 1 + + + + + I2SCFG + I2S configuration mode + 8 + 2 + + I2SCFG + read-write + + SlaveTx + Slave - transmit + 0 + + + SlaveRx + Slave - receive + 1 + + + MasterTx + Master - transmit + 2 + + + MasterRx + Master - receive + 3 + + + + + PCMSYNC + PCM frame synchronization + 7 + 1 + + PCMSYNC + read-write + + Short + Short frame synchronisation + 0 + + + Long + Long frame synchronisation + 1 + + + + + I2SSTD + I2S standard selection + 4 + 2 + + I2SSTD + read-write + + Philips + I2S Philips standard + 0 + + + MSB + MSB justified standard + 1 + + + LSB + LSB justified standard + 2 + + + PCM + PCM standard + 3 + + + + + CKPOL + Steady state clock + polarity + 3 + 1 + + CKPOL + read-write + + IdleLow + I2S clock inactive state is low level + 0 + + + IdleHigh + I2S clock inactive state is high level + 1 + + + + + DATLEN + Data length to be + transferred + 1 + 2 + + DATLEN + read-write + + SixteenBit + 16-bit data length + 0 + + + TwentyFourBit + 24-bit data length + 1 + + + ThirtyTwoBit + 32-bit data length + 2 + + + + + CHLEN + Channel length (number of bits per audio + channel) + 0 + 1 + + CHLEN + read-write + + SixteenBit + 16-bit wide + 0 + + + ThirtyTwoBit + 32-bit wide + 1 + + + + + + + I2SPR + I2SPR + I2S prescaler register + 0x20 + 0x20 + read-write + 0x0000000A + + + MCKOE + Master clock output enable + 9 + 1 + + MCKOE + read-write + + Disabled + Master clock output is disabled + 0 + + + Enabled + Master clock output is enabled + 1 + + + + + ODD + Odd factor for the + prescaler + 8 + 1 + + ODD + read-write + + Even + Real divider value is I2SDIV * 2 + 0 + + + Odd + Real divider value is (I2SDIV * 2) + 1 + 1 + + + + + I2SDIV + I2S Linear prescaler + 0 + 8 + + + 2 + 255 + + + + + + + + + SPI2 + 0x40003800 + + SPI1 + SPI1 global interrupt + 35 + + + + SPI3 + 0x40003C00 + + SPI2 + SPI2 global interrupt + 36 + + + + SPI4 + 0x40013400 + + SPI3 + SPI3 global interrupt + 51 + + + + NVIC + Nested Vectored Interrupt + Controller + NVIC + 0xE000E100 + + 0x0 + 0x351 + registers + + + + ISER0 + ISER0 + Interrupt Set-Enable Register + 0x0 + 0x20 + read-write + 0x00000000 + + + SETENA + SETENA + 0 + 32 + + + + + ISER1 + ISER1 + Interrupt Set-Enable Register + 0x4 + 0x20 + read-write + 0x00000000 + + + SETENA + SETENA + 0 + 32 + + + + + ISER2 + ISER2 + Interrupt Set-Enable Register + 0x8 + 0x20 + read-write + 0x00000000 + + + SETENA + SETENA + 0 + 32 + + + + + ICER0 + ICER0 + Interrupt Clear-Enable + Register + 0x80 + 0x20 + read-write + 0x00000000 + + + CLRENA + CLRENA + 0 + 32 + + + + + ICER1 + ICER1 + Interrupt Clear-Enable + Register + 0x84 + 0x20 + read-write + 0x00000000 + + + CLRENA + CLRENA + 0 + 32 + + + + + ICER2 + ICER2 + Interrupt Clear-Enable + Register + 0x88 + 0x20 + read-write + 0x00000000 + + + CLRENA + CLRENA + 0 + 32 + + + + + ISPR0 + ISPR0 + Interrupt Set-Pending Register + 0x100 + 0x20 + read-write + 0x00000000 + + + SETPEND + SETPEND + 0 + 32 + + + + + ISPR1 + ISPR1 + Interrupt Set-Pending Register + 0x104 + 0x20 + read-write + 0x00000000 + + + SETPEND + SETPEND + 0 + 32 + + + + + ISPR2 + ISPR2 + Interrupt Set-Pending Register + 0x108 + 0x20 + read-write + 0x00000000 + + + SETPEND + SETPEND + 0 + 32 + + + + + ICPR0 + ICPR0 + Interrupt Clear-Pending + Register + 0x180 + 0x20 + read-write + 0x00000000 + + + CLRPEND + CLRPEND + 0 + 32 + + + + + ICPR1 + ICPR1 + Interrupt Clear-Pending + Register + 0x184 + 0x20 + read-write + 0x00000000 + + + CLRPEND + CLRPEND + 0 + 32 + + + + + ICPR2 + ICPR2 + Interrupt Clear-Pending + Register + 0x188 + 0x20 + read-write + 0x00000000 + + + CLRPEND + CLRPEND + 0 + 32 + + + + + IABR0 + IABR0 + Interrupt Active Bit Register + 0x200 + 0x20 + read-only + 0x00000000 + + + ACTIVE + ACTIVE + 0 + 32 + + + + + IABR1 + IABR1 + Interrupt Active Bit Register + 0x204 + 0x20 + read-only + 0x00000000 + + + ACTIVE + ACTIVE + 0 + 32 + + + + + IABR2 + IABR2 + Interrupt Active Bit Register + 0x208 + 0x20 + read-only + 0x00000000 + + + ACTIVE + ACTIVE + 0 + 32 + + + + + IPR0 + IPR0 + Interrupt Priority Register + 0x300 + 0x20 + read-write + 0x00000000 + + + IPR_N0 + IPR_N0 + 0 + 8 + + + IPR_N1 + IPR_N1 + 8 + 8 + + + IPR_N2 + IPR_N2 + 16 + 8 + + + IPR_N3 + IPR_N3 + 24 + 8 + + + + + IPR1 + IPR1 + Interrupt Priority Register + 0x304 + 0x20 + read-write + 0x00000000 + + + IPR_N0 + IPR_N0 + 0 + 8 + + + IPR_N1 + IPR_N1 + 8 + 8 + + + IPR_N2 + IPR_N2 + 16 + 8 + + + IPR_N3 + IPR_N3 + 24 + 8 + + + + + IPR2 + IPR2 + Interrupt Priority Register + 0x308 + 0x20 + read-write + 0x00000000 + + + IPR_N0 + IPR_N0 + 0 + 8 + + + IPR_N1 + IPR_N1 + 8 + 8 + + + IPR_N2 + IPR_N2 + 16 + 8 + + + IPR_N3 + IPR_N3 + 24 + 8 + + + + + IPR3 + IPR3 + Interrupt Priority Register + 0x30C + 0x20 + read-write + 0x00000000 + + + IPR_N0 + IPR_N0 + 0 + 8 + + + IPR_N1 + IPR_N1 + 8 + 8 + + + IPR_N2 + IPR_N2 + 16 + 8 + + + IPR_N3 + IPR_N3 + 24 + 8 + + + + + IPR4 + IPR4 + Interrupt Priority Register + 0x310 + 0x20 + read-write + 0x00000000 + + + IPR_N0 + IPR_N0 + 0 + 8 + + + IPR_N1 + IPR_N1 + 8 + 8 + + + IPR_N2 + IPR_N2 + 16 + 8 + + + IPR_N3 + IPR_N3 + 24 + 8 + + + + + IPR5 + IPR5 + Interrupt Priority Register + 0x314 + 0x20 + read-write + 0x00000000 + + + IPR_N0 + IPR_N0 + 0 + 8 + + + IPR_N1 + IPR_N1 + 8 + 8 + + + IPR_N2 + IPR_N2 + 16 + 8 + + + IPR_N3 + IPR_N3 + 24 + 8 + + + + + IPR6 + IPR6 + Interrupt Priority Register + 0x318 + 0x20 + read-write + 0x00000000 + + + IPR_N0 + IPR_N0 + 0 + 8 + + + IPR_N1 + IPR_N1 + 8 + 8 + + + IPR_N2 + IPR_N2 + 16 + 8 + + + IPR_N3 + IPR_N3 + 24 + 8 + + + + + IPR7 + IPR7 + Interrupt Priority Register + 0x31C + 0x20 + read-write + 0x00000000 + + + IPR_N0 + IPR_N0 + 0 + 8 + + + IPR_N1 + IPR_N1 + 8 + 8 + + + IPR_N2 + IPR_N2 + 16 + 8 + + + IPR_N3 + IPR_N3 + 24 + 8 + + + + + IPR8 + IPR8 + Interrupt Priority Register + 0x320 + 0x20 + read-write + 0x00000000 + + + IPR_N0 + IPR_N0 + 0 + 8 + + + IPR_N1 + IPR_N1 + 8 + 8 + + + IPR_N2 + IPR_N2 + 16 + 8 + + + IPR_N3 + IPR_N3 + 24 + 8 + + + + + IPR9 + IPR9 + Interrupt Priority Register + 0x324 + 0x20 + read-write + 0x00000000 + + + IPR_N0 + IPR_N0 + 0 + 8 + + + IPR_N1 + IPR_N1 + 8 + 8 + + + IPR_N2 + IPR_N2 + 16 + 8 + + + IPR_N3 + IPR_N3 + 24 + 8 + + + + + IPR10 + IPR10 + Interrupt Priority Register + 0x328 + 0x20 + read-write + 0x00000000 + + + IPR_N0 + IPR_N0 + 0 + 8 + + + IPR_N1 + IPR_N1 + 8 + 8 + + + IPR_N2 + IPR_N2 + 16 + 8 + + + IPR_N3 + IPR_N3 + 24 + 8 + + + + + IPR11 + IPR11 + Interrupt Priority Register + 0x32C + 0x20 + read-write + 0x00000000 + + + IPR_N0 + IPR_N0 + 0 + 8 + + + IPR_N1 + IPR_N1 + 8 + 8 + + + IPR_N2 + IPR_N2 + 16 + 8 + + + IPR_N3 + IPR_N3 + 24 + 8 + + + + + IPR12 + IPR12 + Interrupt Priority Register + 0x330 + 0x20 + read-write + 0x00000000 + + + IPR_N0 + IPR_N0 + 0 + 8 + + + IPR_N1 + IPR_N1 + 8 + 8 + + + IPR_N2 + IPR_N2 + 16 + 8 + + + IPR_N3 + IPR_N3 + 24 + 8 + + + + + IPR13 + IPR13 + Interrupt Priority Register + 0x334 + 0x20 + read-write + 0x00000000 + + + IPR_N0 + IPR_N0 + 0 + 8 + + + IPR_N1 + IPR_N1 + 8 + 8 + + + IPR_N2 + IPR_N2 + 16 + 8 + + + IPR_N3 + IPR_N3 + 24 + 8 + + + + + IPR14 + IPR14 + Interrupt Priority Register + 0x338 + 0x20 + read-write + 0x00000000 + + + IPR_N0 + IPR_N0 + 0 + 8 + + + IPR_N1 + IPR_N1 + 8 + 8 + + + IPR_N2 + IPR_N2 + 16 + 8 + + + IPR_N3 + IPR_N3 + 24 + 8 + + + + + IPR15 + IPR15 + Interrupt Priority Register + 0x33C + 0x20 + read-write + 0x00000000 + + + IPR_N0 + IPR_N0 + 0 + 8 + + + IPR_N1 + IPR_N1 + 8 + 8 + + + IPR_N2 + IPR_N2 + 16 + 8 + + + IPR_N3 + IPR_N3 + 24 + 8 + + + + + IPR16 + IPR16 + Interrupt Priority Register + 0x340 + 0x20 + read-write + 0x00000000 + + + IPR_N0 + IPR_N0 + 0 + 8 + + + IPR_N1 + IPR_N1 + 8 + 8 + + + IPR_N2 + IPR_N2 + 16 + 8 + + + IPR_N3 + IPR_N3 + 24 + 8 + + + + + IPR17 + IPR17 + Interrupt Priority Register + 0x344 + 0x20 + read-write + 0x00000000 + + + IPR_N0 + IPR_N0 + 0 + 8 + + + IPR_N1 + IPR_N1 + 8 + 8 + + + IPR_N2 + IPR_N2 + 16 + 8 + + + IPR_N3 + IPR_N3 + 24 + 8 + + + + + IPR18 + IPR18 + Interrupt Priority Register + 0x348 + 0x20 + read-write + 0x00000000 + + + IPR_N0 + IPR_N0 + 0 + 8 + + + IPR_N1 + IPR_N1 + 8 + 8 + + + IPR_N2 + IPR_N2 + 16 + 8 + + + IPR_N3 + IPR_N3 + 24 + 8 + + + + + IPR19 + IPR19 + Interrupt Priority Register + 0x34C + 0x20 + read-write + 0x00000000 + + + IPR_N0 + IPR_N0 + 0 + 8 + + + IPR_N1 + IPR_N1 + 8 + 8 + + + IPR_N2 + IPR_N2 + 16 + 8 + + + IPR_N3 + IPR_N3 + 24 + 8 + + + + + + + FPU + Floting point unit + FPU + 0xE000EF34 + + 0x0 + 0xD + registers + + + FPU + Floating point unit interrupt + 81 + + + + FPCCR + FPCCR + Floating-point context control + register + 0x0 + 0x20 + read-write + 0x00000000 + + + LSPACT + LSPACT + 0 + 1 + + + USER + USER + 1 + 1 + + + THREAD + THREAD + 3 + 1 + + + HFRDY + HFRDY + 4 + 1 + + + MMRDY + MMRDY + 5 + 1 + + + BFRDY + BFRDY + 6 + 1 + + + MONRDY + MONRDY + 8 + 1 + + + LSPEN + LSPEN + 30 + 1 + + + ASPEN + ASPEN + 31 + 1 + + + + + FPCAR + FPCAR + Floating-point context address + register + 0x4 + 0x20 + read-write + 0x00000000 + + + ADDRESS + Location of unpopulated + floating-point + 3 + 29 + + + + + FPSCR + FPSCR + Floating-point status control + register + 0x8 + 0x20 + read-write + 0x00000000 + + + IOC + Invalid operation cumulative exception + bit + 0 + 1 + + + DZC + Division by zero cumulative exception + bit. + 1 + 1 + + + OFC + Overflow cumulative exception + bit + 2 + 1 + + + UFC + Underflow cumulative exception + bit + 3 + 1 + + + IXC + Inexact cumulative exception + bit + 4 + 1 + + + IDC + Input denormal cumulative exception + bit. + 7 + 1 + + + RMode + Rounding Mode control + field + 22 + 2 + + + FZ + Flush-to-zero mode control + bit: + 24 + 1 + + + DN + Default NaN mode control + bit + 25 + 1 + + + AHP + Alternative half-precision control + bit + 26 + 1 + + + V + Overflow condition code + flag + 28 + 1 + + + C + Carry condition code flag + 29 + 1 + + + Z + Zero condition code flag + 30 + 1 + + + N + Negative condition code + flag + 31 + 1 + + + + + + + MPU + Memory protection unit + MPU + 0xE000ED90 + + 0x0 + 0x15 + registers + + + + TYPER + TYPER + MPU type register + 0x0 + 0x20 + read-only + 0x00000800 + + + SEPARATE + Separate flag + 0 + 1 + + + DREGION + Number of MPU data regions + 8 + 8 + + + IREGION + Number of MPU instruction + regions + 16 + 8 + + + + + CTRL + CTRL + MPU control register + 0x4 + 0x20 + read-only + 0x00000000 + + + ENABLE + Enables the MPU + 0 + 1 + + + HFNMIENA + Enables the operation of MPU during hard + fault + 1 + 1 + + + PRIVDEFENA + Enable priviliged software access to + default memory map + 2 + 1 + + + + + RNR + RNR + MPU region number register + 0x8 + 0x20 + read-write + 0x00000000 + + + REGION + MPU region + 0 + 8 + + + + + RBAR + RBAR + MPU region base address + register + 0xC + 0x20 + read-write + 0x00000000 + + + REGION + MPU region field + 0 + 4 + + + VALID + MPU region number valid + 4 + 1 + + + ADDR + Region base address field + 5 + 27 + + + + + RASR + RASR + MPU region attribute and size + register + 0x10 + 0x20 + read-write + 0x00000000 + + + ENABLE + Region enable bit. + 0 + 1 + + + SIZE + Size of the MPU protection + region + 1 + 5 + + + SRD + Subregion disable bits + 8 + 8 + + + B + memory attribute + 16 + 1 + + + C + memory attribute + 17 + 1 + + + S + Shareable memory attribute + 18 + 1 + + + TEX + memory attribute + 19 + 3 + + + AP + Access permission + 24 + 3 + + + XN + Instruction access disable + bit + 28 + 1 + + + + + + + STK + SysTick timer + STK + 0xE000E010 + + 0x0 + 0x11 + registers + + + + CTRL + CTRL + SysTick control and status + register + 0x0 + 0x20 + read-write + 0x00000000 + + + ENABLE + Counter enable + 0 + 1 + + + TICKINT + SysTick exception request + enable + 1 + 1 + + + CLKSOURCE + Clock source selection + 2 + 1 + + + COUNTFLAG + COUNTFLAG + 16 + 1 + + + + + LOAD + LOAD + SysTick reload value register + 0x4 + 0x20 + read-write + 0x00000000 + + + RELOAD + RELOAD value + 0 + 24 + + + + + VAL + VAL + SysTick current value register + 0x8 + 0x20 + read-write + 0x00000000 + + + CURRENT + Current counter value + 0 + 24 + + + + + CALIB + CALIB + SysTick calibration value + register + 0xC + 0x20 + read-write + 0x00000000 + + + TENMS + Calibration value + 0 + 24 + + + SKEW + SKEW flag: Indicates whether the TENMS + value is exact + 30 + 1 + + + NOREF + NOREF flag. Reads as zero + 31 + 1 + + + + + + + SCB + System control block + SCB + 0xE000ED00 + + 0x0 + 0x41 + registers + + + + CPUID + CPUID + CPUID base register + 0x0 + 0x20 + read-only + 0x410FC241 + + + Revision + Revision number + 0 + 4 + + + PartNo + Part number of the + processor + 4 + 12 + + + Constant + Reads as 0xF + 16 + 4 + + + Variant + Variant number + 20 + 4 + + + Implementer + Implementer code + 24 + 8 + + + + + ICSR + ICSR + Interrupt control and state + register + 0x4 + 0x20 + read-write + 0x00000000 + + + VECTACTIVE + Active vector + 0 + 9 + + + RETTOBASE + Return to base level + 11 + 1 + + + VECTPENDING + Pending vector + 12 + 7 + + + ISRPENDING + Interrupt pending flag + 22 + 1 + + + PENDSTCLR + SysTick exception clear-pending + bit + 25 + 1 + + + PENDSTSET + SysTick exception set-pending + bit + 26 + 1 + + + PENDSVCLR + PendSV clear-pending bit + 27 + 1 + + + PENDSVSET + PendSV set-pending bit + 28 + 1 + + + NMIPENDSET + NMI set-pending bit. + 31 + 1 + + + + + VTOR + VTOR + Vector table offset register + 0x8 + 0x20 + read-write + 0x00000000 + + + TBLOFF + Vector table base offset + field + 9 + 21 + + + + + AIRCR + AIRCR + Application interrupt and reset control + register + 0xC + 0x20 + read-write + 0x00000000 + + + VECTRESET + VECTRESET + 0 + 1 + + + VECTCLRACTIVE + VECTCLRACTIVE + 1 + 1 + + + SYSRESETREQ + SYSRESETREQ + 2 + 1 + + + PRIGROUP + PRIGROUP + 8 + 3 + + + ENDIANESS + ENDIANESS + 15 + 1 + + + VECTKEYSTAT + Register key + 16 + 16 + + + + + SCR + SCR + System control register + 0x10 + 0x20 + read-write + 0x00000000 + + + SLEEPONEXIT + SLEEPONEXIT + 1 + 1 + + + SLEEPDEEP + SLEEPDEEP + 2 + 1 + + + SEVEONPEND + Send Event on Pending bit + 4 + 1 + + + + + CCR + CCR + Configuration and control + register + 0x14 + 0x20 + read-write + 0x00000000 + + + NONBASETHRDENA + Configures how the processor enters + Thread mode + 0 + 1 + + + USERSETMPEND + USERSETMPEND + 1 + 1 + + + UNALIGN__TRP + UNALIGN_ TRP + 3 + 1 + + + DIV_0_TRP + DIV_0_TRP + 4 + 1 + + + BFHFNMIGN + BFHFNMIGN + 8 + 1 + + + STKALIGN + STKALIGN + 9 + 1 + + + + + SHPR1 + SHPR1 + System handler priority + registers + 0x18 + 0x20 + read-write + 0x00000000 + + + PRI_4 + Priority of system handler + 4 + 0 + 8 + + + PRI_5 + Priority of system handler + 5 + 8 + 8 + + + PRI_6 + Priority of system handler + 6 + 16 + 8 + + + + + SHPR2 + SHPR2 + System handler priority + registers + 0x1C + 0x20 + read-write + 0x00000000 + + + PRI_11 + Priority of system handler + 11 + 24 + 8 + + + + + SHPR3 + SHPR3 + System handler priority + registers + 0x20 + 0x20 + read-write + 0x00000000 + + + PRI_14 + Priority of system handler + 14 + 16 + 8 + + + PRI_15 + Priority of system handler + 15 + 24 + 8 + + + + + SHCRS + SHCRS + System handler control and state + register + 0x24 + 0x20 + read-write + 0x00000000 + + + MEMFAULTACT + Memory management fault exception active + bit + 0 + 1 + + + BUSFAULTACT + Bus fault exception active + bit + 1 + 1 + + + USGFAULTACT + Usage fault exception active + bit + 3 + 1 + + + SVCALLACT + SVC call active bit + 7 + 1 + + + MONITORACT + Debug monitor active bit + 8 + 1 + + + PENDSVACT + PendSV exception active + bit + 10 + 1 + + + SYSTICKACT + SysTick exception active + bit + 11 + 1 + + + USGFAULTPENDED + Usage fault exception pending + bit + 12 + 1 + + + MEMFAULTPENDED + Memory management fault exception + pending bit + 13 + 1 + + + BUSFAULTPENDED + Bus fault exception pending + bit + 14 + 1 + + + SVCALLPENDED + SVC call pending bit + 15 + 1 + + + MEMFAULTENA + Memory management fault enable + bit + 16 + 1 + + + BUSFAULTENA + Bus fault enable bit + 17 + 1 + + + USGFAULTENA + Usage fault enable bit + 18 + 1 + + + + + CFSR_UFSR_BFSR_MMFSR + CFSR_UFSR_BFSR_MMFSR + Configurable fault status + register + 0x28 + 0x20 + read-write + 0x00000000 + + + IACCVIOL + Instruction access violation + flag + 1 + 1 + + + MUNSTKERR + Memory manager fault on unstacking for a + return from exception + 3 + 1 + + + MSTKERR + Memory manager fault on stacking for + exception entry. + 4 + 1 + + + MLSPERR + MLSPERR + 5 + 1 + + + MMARVALID + Memory Management Fault Address Register + (MMAR) valid flag + 7 + 1 + + + IBUSERR + Instruction bus error + 8 + 1 + + + PRECISERR + Precise data bus error + 9 + 1 + + + IMPRECISERR + Imprecise data bus error + 10 + 1 + + + UNSTKERR + Bus fault on unstacking for a return + from exception + 11 + 1 + + + STKERR + Bus fault on stacking for exception + entry + 12 + 1 + + + LSPERR + Bus fault on floating-point lazy state + preservation + 13 + 1 + + + BFARVALID + Bus Fault Address Register (BFAR) valid + flag + 15 + 1 + + + UNDEFINSTR + Undefined instruction usage + fault + 16 + 1 + + + INVSTATE + Invalid state usage fault + 17 + 1 + + + INVPC + Invalid PC load usage + fault + 18 + 1 + + + NOCP + No coprocessor usage + fault. + 19 + 1 + + + UNALIGNED + Unaligned access usage + fault + 24 + 1 + + + DIVBYZERO + Divide by zero usage fault + 25 + 1 + + + + + HFSR + HFSR + Hard fault status register + 0x2C + 0x20 + read-write + 0x00000000 + + + VECTTBL + Vector table hard fault + 1 + 1 + + + FORCED + Forced hard fault + 30 + 1 + + + DEBUG_VT + Reserved for Debug use + 31 + 1 + + + + + MMFAR + MMFAR + Memory management fault address + register + 0x34 + 0x20 + read-write + 0x00000000 + + + MMFAR + Memory management fault + address + 0 + 32 + + + + + BFAR + BFAR + Bus fault address register + 0x38 + 0x20 + read-write + 0x00000000 + + + BFAR + Bus fault address + 0 + 32 + + + + + AFSR + AFSR + Auxiliary fault status + register + 0x3C + 0x20 + read-write + 0x00000000 + + + IMPDEF + Implementation defined + 0 + 32 + + + + + + + NVIC_STIR + Nested vectored interrupt + controller + NVIC + 0xE000EF00 + + 0x0 + 0x5 + registers + + + + STIR + STIR + Software trigger interrupt + register + 0x0 + 0x20 + read-write + 0x00000000 + + + INTID + Software generated interrupt + ID + 0 + 9 + + + + + + + FPU_CPACR + Floating point unit CPACR + FPU + 0xE000ED88 + + 0x0 + 0x5 + registers + + + + CPACR + CPACR + Coprocessor access control + register + 0x0 + 0x20 + read-write + 0x00000000 + + + CP + CP + 20 + 4 + + + + + + + SCB_ACTRL + System control block ACTLR + SCB + 0xE000E008 + + 0x0 + 0x5 + registers + + + + ACTRL + ACTRL + Auxiliary control register + 0x0 + 0x20 + read-write + 0x00000000 + + + DISMCYCINT + DISMCYCINT + 0 + 1 + + + DISDEFWBUF + DISDEFWBUF + 1 + 1 + + + DISFOLD + DISFOLD + 2 + 1 + + + DISFPCA + DISFPCA + 8 + 1 + + + DISOOFP + DISOOFP + 9 + 1 + + + + + + + \ No newline at end of file diff --git a/nodes/embassy/small-bedroom-button-panel/.cargo/config.toml b/nodes/embassy/small-bedroom-button-panel/.cargo/config.toml new file mode 100644 index 00000000..f00aaa5f --- /dev/null +++ b/nodes/embassy/small-bedroom-button-panel/.cargo/config.toml @@ -0,0 +1,18 @@ +[target.'cfg(all(target_arch = "arm", target_os = "none"))'] +# replace STM32F103C8 with your chip as listed in `probe-rs chip list` +# runner = "probe-rs run --chip STM32F103C8" +runner = "probe-rs run --chip STM32F401CCUx" +# runner = "probe-rs run --chip STM32F401CCUx --host ws://192.168.1.43:3000 --token secret_token_redacted --probe c251:f001:202108120001" +linker = "flip-link" + +[build] +# target = "thumbv7m-none-eabi" for f103 +target = "thumbv7em-none-eabihf" + +[env] +DEFMT_LOG = "debug,sps30_async=warn,bosch_bme680=info" +EMBASSY_EXECUTOR_TASK_ARENA_SIZE="10900" + +# [unstable] +# build-std = ["core"] +# build-std-features = ["panic_immediate_abort"] diff --git a/nodes/embassy/small-bedroom-button-panel/Cargo.toml b/nodes/embassy/small-bedroom-button-panel/Cargo.toml new file mode 100644 index 00000000..fe5eb8bc --- /dev/null +++ b/nodes/embassy/small-bedroom-button-panel/Cargo.toml @@ -0,0 +1,36 @@ +[package] +name = "small-bedroom-button-panel" +version = "0.2.0" +rust-version = "1.85" +edition = "2024" +license = "GPLv3" +authors = ["David Kleingeld & Eva van Houten"] + +[dependencies] +cortex-m.workspace = true +cortex-m-rt.workspace = true + +embassy-stm32.workspace = true +embassy-sync.workspace = true +embassy-executor.workspace = true +embassy-embedded-hal.workspace = true +embassy-time.workspace = true +embassy-futures.workspace = true +embassy-usb.workspace = true + +defmt.workspace = true +defmt-rtt.workspace = true + +embedded-hal.workspace = true +embedded-hal-async.workspace = true +embedded-hal-bus.workspace = true +embedded-io-async.workspace = true + +panic-probe.workspace = true +futures.workspace = true +heapless.workspace = true + +# encoding +protocol = { workspace = true } + +usb-bridge-client.workspace = true diff --git a/nodes/embassy/small-bedroom-button-panel/build.rs b/nodes/embassy/small-bedroom-button-panel/build.rs new file mode 100644 index 00000000..8cd32d7e --- /dev/null +++ b/nodes/embassy/small-bedroom-button-panel/build.rs @@ -0,0 +1,5 @@ +fn main() { + println!("cargo:rustc-link-arg-bins=--nmagic"); + println!("cargo:rustc-link-arg-bins=-Tlink.x"); + println!("cargo:rustc-link-arg-bins=-Tdefmt.x"); +} diff --git a/nodes/embassy/small-bedroom-button-panel/rust-toolchain.toml b/nodes/embassy/small-bedroom-button-panel/rust-toolchain.toml new file mode 100644 index 00000000..c17f644e --- /dev/null +++ b/nodes/embassy/small-bedroom-button-panel/rust-toolchain.toml @@ -0,0 +1,6 @@ +[toolchain] +channel = "stable" +components = [ "rust-src", "rustfmt", "llvm-tools" ] +targets = [ + "thumbv7em-none-eabihf", +] diff --git a/nodes/embassy/small-bedroom-button-panel/src/buttons.rs b/nodes/embassy/small-bedroom-button-panel/src/buttons.rs new file mode 100644 index 00000000..84d1599f --- /dev/null +++ b/nodes/embassy/small-bedroom-button-panel/src/buttons.rs @@ -0,0 +1,71 @@ +use embassy_futures::join; +use embassy_stm32::exti::ExtiInput; +use fast::watch_button; + +pub mod fast; + +pub struct Inputs { + pub bottom_left: ExtiInput<'static>, + pub bottom_middle: ExtiInput<'static>, + pub bottom_right: ExtiInput<'static>, + pub top_left: ExtiInput<'static>, + pub top_middle: ExtiInput<'static>, + pub top_right: ExtiInput<'static>, +} + +macro_rules! on_ok { + ($pos:ident) => { + |press| { + crate::PUBLISH.send(protocol::Reading::SmallBedroom( + protocol::small_bedroom::Reading::ButtonPanel( + protocol::small_bedroom::ButtonPanel::$pos(press), + ), + )) + } + }; +} + +macro_rules! on_err { + ($pos:ident) => { + || { + let event_for_printing = + (protocol::small_bedroom::ButtonPanel::$pos)( + protocol::button::Press(0), + ); + let name = event_for_printing.variant_name(); + defmt::error!("Button pressed too long: {}", name); + } + }; +} + +pub async fn init_then_measure(inputs: Inputs) { + join::join( + join::join3( + watch_button( + inputs.bottom_left, + on_ok!(BottomLeft), + on_err!(BottomLeft), + ), + watch_button( + inputs.bottom_middle, + on_ok!(BottomMiddle), + on_err!(BottomMiddle), + ), + watch_button( + inputs.bottom_right, + on_ok!(BottomRight), + on_err!(BottomRight), + ), + ), + join::join3( + watch_button(inputs.top_left, on_ok!(TopLeft), on_err!(TopLeft)), + watch_button( + inputs.top_middle, + on_ok!(TopMiddle), + on_err!(TopMiddle), + ), + watch_button(inputs.top_right, on_ok!(TopRight), on_err!(TopRight)), + ), + ) + .await; +} diff --git a/nodes/embassy/small-bedroom-button-panel/src/buttons/fast.rs b/nodes/embassy/small-bedroom-button-panel/src/buttons/fast.rs new file mode 100644 index 00000000..1abd6918 --- /dev/null +++ b/nodes/embassy/small-bedroom-button-panel/src/buttons/fast.rs @@ -0,0 +1,38 @@ +use embassy_stm32::exti::ExtiInput; +use embassy_time::{Duration, Instant, Timer}; + +use protocol::button; + +pub async fn watch_button( + mut input: ExtiInput<'static>, + on_ok_press: impl AsyncFn(protocol::button::Press), + on_err_press: impl Fn(), +) { + let mut went_high_at: Option = None; + loop { + if let Some(went_high_at) = went_high_at.take() { + input.wait_for_low().await; + let press = went_high_at.elapsed(); + let Ok(press) = press.as_millis().try_into().map(button::Press) + else { + on_err_press(); + continue; + }; + on_ok_press(press).await; + } else { + input.wait_for_high().await; + Timer::after(Duration::from_millis(20)).await; + if input.is_low() { + continue; + } + Timer::after(Duration::from_millis(20)).await; + if input.is_low() { + continue; + } + Timer::after(Duration::from_millis(10)).await; + if input.is_high() { + went_high_at = Some(Instant::now()); + } + } + } +} diff --git a/nodes/embassy/small-bedroom-button-panel/src/comms.rs b/nodes/embassy/small-bedroom-button-panel/src/comms.rs new file mode 100644 index 00000000..64de4ef0 --- /dev/null +++ b/nodes/embassy/small-bedroom-button-panel/src/comms.rs @@ -0,0 +1,67 @@ +use defmt::warn; +use embassy_time::{Duration, Instant}; +use heapless::HistoryBuffer; +use protocol::{SensorMessage, affector}; +use usb_bridge_client::{NoSpaceInQueue, UsbHandle, UsbSender}; + +pub async fn handle(usb: UsbHandle<'_>) -> ! { + const MIN_BETWEEN_COMM_ERRS: Duration = Duration::from_secs(30); + let mut last_errors_at: HistoryBuffer<_, 5> = HistoryBuffer::new(); + + loop { + crate::PUBLISH.clear(); + + let (writer, _) = usb.split(); + send_messages(writer).await; + warn!("Error while sending messages"); + + let mut error_after = Instant::now(); + if last_errors_at.oldest_ordered().rev().copied().all( + |error: Instant| { + let is_recent = + error_after.duration_since(error) < MIN_BETWEEN_COMM_ERRS; + error_after = error; + is_recent + }, + ) { + defmt::error!( + "Something is terribly wrong with the connection, \ + 5 errors occured each within 30 seconds of the previous. \ + Resetting entire node" + ); + cortex_m::peripheral::SCB::sys_reset(); + } else { + last_errors_at.write(Instant::now()); + } + } +} + +const AFFECTOR_LIST_MAX_SIZE: usize = protocol::Msg::<5>::max_size(); +pub fn affector_list() -> heapless::Vec { + let list = affector::ListMessage::<5>::empty(); + let mut buf = heapless::Vec::new(); + defmt::unwrap!(buf.resize_default(AFFECTOR_LIST_MAX_SIZE)); + let encoded_len = list.encode_slice(&mut buf).len(); + buf.truncate(encoded_len); + buf +} + +async fn collect_msg() -> SensorMessage<10> { + let mut msg = SensorMessage::<10>::default(); + let reading = crate::PUBLISH.receive().await; + defmt::unwrap!(msg.values.push(reading)); + msg +} + +async fn send_messages(usb: UsbSender<'_>) { + let mut buf = [0; protocol::Msg::<5>::max_size()]; + loop { + let msg = collect_msg().await; + let encoded_len = msg.encode_slice(&mut buf[1..]).len(); + buf[0] = protocol::Msg::<0>::READINGS; + let to_send = &buf[..=encoded_len]; + while let Err(NoSpaceInQueue) = usb.send(to_send, true).await { + usb.wait_till_queue_free().await; + } + } +} diff --git a/nodes/embassy/small-bedroom-button-panel/src/main.rs b/nodes/embassy/small-bedroom-button-panel/src/main.rs new file mode 100644 index 00000000..49f4bf1d --- /dev/null +++ b/nodes/embassy/small-bedroom-button-panel/src/main.rs @@ -0,0 +1,143 @@ +#![no_std] +#![no_main] + +use core::time::Duration; + +use embassy_executor::Spawner; +use embassy_futures::join; +use embassy_stm32::exti::ExtiInput; +use embassy_stm32::gpio::Pull; +use embassy_stm32::peripherals::IWDG; +use embassy_stm32::time::Hertz; +use embassy_stm32::wdg::IndependentWatchdog; +use embassy_stm32::{Config, usb}; +use embassy_sync::blocking_mutex::raw::ThreadModeRawMutex; +use embassy_sync::channel::Channel; +use embassy_time::Timer; +use futures::pin_mut; + +use defmt::trace; +use {defmt_rtt as _, panic_probe as _}; + +mod buttons; +mod comms; + +embassy_stm32::bind_interrupts!(struct Irqs { + OTG_FS => embassy_stm32::usb::InterruptHandler; +}); + +static PUBLISH: Channel = + Channel::new(); + +// 84 Mhz clock stm32f401 +// 48 Mhz clock for usb +fn config() -> Config { + use embassy_stm32::rcc::mux; + use embassy_stm32::rcc::{ + AHBPrescaler, APBPrescaler, Hse, HseMode, Pll, PllMul, PllPDiv, + PllPreDiv, PllQDiv, PllSource, Sysclk, + }; + + let mut config = Config::default(); + config.rcc.hse = Some(Hse { + freq: Hertz(25_000_000), + mode: HseMode::Oscillator, + }); + config.rcc.pll_src = PllSource::HSE; + config.rcc.pll = Some(Pll { + prediv: PllPreDiv::DIV25, + mul: PllMul::MUL336, + divp: Some(PllPDiv::DIV4), // 25mhz / 25 * 336 / 4 = 84Mhz. + divq: Some(PllQDiv::DIV7), // 25mhz / 25 * 336 / 7 = 48Mhz. + divr: None, + }); + config.rcc.ahb_pre = AHBPrescaler::DIV1; + config.rcc.apb1_pre = APBPrescaler::DIV2; + config.rcc.apb2_pre = APBPrescaler::DIV1; + config.rcc.sys = Sysclk::PLL1_P; + config.rcc.mux.clk48sel = mux::Clk48sel::PLL1_Q; + config +} + +#[embassy_executor::main] +async fn main(_spawner: Spawner) { + let p = embassy_stm32::init(config()); + let dog = IndependentWatchdog::new( + p.IWDG, + Duration::from_secs(5).as_micros() as u32, + ); + + let buttons = buttons::Inputs { + bottom_left: ExtiInput::new(p.PC15, p.EXTI15, Pull::Down), + bottom_middle: ExtiInput::new(p.PB0, p.EXTI0, Pull::Down), + bottom_right: ExtiInput::new(p.PC14, p.EXTI14, Pull::Down), + top_left: ExtiInput::new(p.PB12, p.EXTI12, Pull::Down), + top_middle: ExtiInput::new(p.PB13, p.EXTI13, Pull::Down), + top_right: ExtiInput::new(p.PB1, p.EXTI1, Pull::Down), + }; + + let mut usb_driver_config = embassy_stm32::usb::Config::default(); + // Do not enable vbus_detection. This is a safe default that works in all + // boards. However, if your USB device is self-powered (can stay powered on + // if USB is unplugged), you need to enable vbus_detection to comply with + // the USB spec. If you enable it, the board + usb_driver_config.vbus_detection = false; + + let mut ep_out_buffer = [0u8; 256]; + let usb_driver = usb::Driver::new_fs( + p.USB_OTG_FS, + Irqs, + p.PA12, + p.PA11, + &mut ep_out_buffer, + usb_driver_config, + ); + + let affector_list = comms::affector_list(); + let stack_a = usb_bridge_client::StackA::new(); + let mut stack_b = usb_bridge_client::StackB::new(&stack_a, &affector_list); + let (mut usb_bus, usb_handle) = usb_bridge_client::new( + &stack_a, + &mut stack_b, + usb_bridge_client::config!("small-bedroom-panel", "87244"), + usb_driver, + ); + + let handle_network = comms::handle(usb_handle); + pin_mut!(handle_network); + + let init_then_measure = buttons::init_then_measure(buttons); + + join::join4( + &mut handle_network, + init_then_measure, + usb_bus.run(), + keep_dog_happy(dog), + ) + .await; +} + +pub fn usb_config() -> embassy_usb::Config<'static> { + // Create embassy-usb Config + let mut config = embassy_usb::Config::new(0x16c0, 0x27DD); + config.manufacturer = Some("Vid"); + config.product = Some("Sensor node"); + config.serial_number = Some("2478437"); + + // Required for windows compatibility. + // https://developer.nordicsemi.com/nRF_Connect_SDK/doc/1.9.1/kconfig/CONFIG_CDC_ACM_IAD.html#help + config.device_class = 0xEF; + config.device_sub_class = 0x02; + config.device_protocol = 0x01; + config.composite_with_iads = true; + + config +} + +async fn keep_dog_happy(mut dog: IndependentWatchdog<'_, IWDG>) -> ! { + loop { + Timer::after_secs(1).await; + trace!("petting dog"); + dog.pet(); + } +} diff --git a/nodes/embassy/small-bedroom-button-panel/src/usb_wrapper.rs b/nodes/embassy/small-bedroom-button-panel/src/usb_wrapper.rs new file mode 100644 index 00000000..e69de29b diff --git a/nodes/embassy/small-bedroom-button-panel/stm32f401.svd b/nodes/embassy/small-bedroom-button-panel/stm32f401.svd new file mode 100644 index 00000000..b9353d01 --- /dev/null +++ b/nodes/embassy/small-bedroom-button-panel/stm32f401.svd @@ -0,0 +1,35196 @@ + + + STM32F401 + 1.1 + STM32F401 + + CM4 + r1p0 + little + false + false + 4 + false + + 8 + 32 + 0x20 + 0x00000000 + 0xFFFFFFFF + + + ADC_Common + ADC common registers + ADC_Common + 0x40012300 + + 0x0 + 0x9 + registers + + + FPU + FPU interrupt + 81 + + + + CCR + CCR + ADC common control register + 0x4 + 0x20 + read-write + 0x00000000 + + + TSVREFE + Temperature sensor and VREFINT + enable + 23 + 1 + + TSVREFE + read-write + + Disabled + Temperature sensor and V_REFINT channel disabled + 0 + + + Enabled + Temperature sensor and V_REFINT channel enabled + 1 + + + + + VBATE + VBAT enable + 22 + 1 + + VBATE + read-write + + Disabled + V_BAT channel disabled + 0 + + + Enabled + V_BAT channel enabled + 1 + + + + + ADCPRE + ADC prescaler + 16 + 2 + + ADCPRE + read-write + + Div2 + PCLK2 divided by 2 + 0 + + + Div4 + PCLK2 divided by 4 + 1 + + + Div6 + PCLK2 divided by 6 + 2 + + + Div8 + PCLK2 divided by 8 + 3 + + + + + + + + + ADC1 + Analog-to-digital converter + ADC + 0x40012000 + + 0x0 + 0x51 + registers + + + ADC + ADC1 global interrupt + 18 + + + + SR + SR + status register + 0x0 + 0x20 + read-write + 0x00000000 + + + OVR + Overrun + 5 + 1 + zeroToClear + + OVRR + read + + NoOverrun + No overrun occurred + 0 + + + Overrun + Overrun occurred + 1 + + + + OVRW + write + + Clear + Clear flag + 0 + + + + + STRT + Regular channel start flag + 4 + 1 + zeroToClear + + STRTR + read + + NotStarted + No regular channel conversion started + 0 + + + Started + Regular channel conversion has started + 1 + + + + STRTW + write + + Clear + Clear flag + 0 + + + + + JSTRT + Injected channel start + flag + 3 + 1 + zeroToClear + + JSTRTR + read + + NotStarted + No injected channel conversion started + 0 + + + Started + Injected channel conversion has started + 1 + + + + JSTRTW + write + + Clear + Clear flag + 0 + + + + + JEOC + Injected channel end of + conversion + 2 + 1 + zeroToClear + + JEOCR + read + + NotComplete + Conversion is not complete + 0 + + + Complete + Conversion complete + 1 + + + + JEOCW + write + + Clear + Clear flag + 0 + + + + + EOC + Regular channel end of + conversion + 1 + 1 + zeroToClear + + EOCR + read + + NotComplete + Conversion is not complete + 0 + + + Complete + Conversion complete + 1 + + + + EOCW + write + + Clear + Clear flag + 0 + + + + + AWD + Analog watchdog flag + 0 + 1 + zeroToClear + + AWDR + read + + NoEvent + No analog watchdog event occurred + 0 + + + Event + Analog watchdog event occurred + 1 + + + + AWDW + write + + Clear + Clear flag + 0 + + + + + + + CR1 + CR1 + control register 1 + 0x4 + 0x20 + read-write + 0x00000000 + + + OVRIE + Overrun interrupt enable + 26 + 1 + + OVRIE + read-write + + Disabled + Overrun interrupt disabled + 0 + + + Enabled + Overrun interrupt enabled + 1 + + + + + RES + Resolution + 24 + 2 + + RES + read-write + + TwelveBit + 12-bit (15 ADCCLK cycles) + 0 + + + TenBit + 10-bit (13 ADCCLK cycles) + 1 + + + EightBit + 8-bit (11 ADCCLK cycles) + 2 + + + SixBit + 6-bit (9 ADCCLK cycles) + 3 + + + + + AWDEN + Analog watchdog enable on regular + channels + 23 + 1 + + AWDEN + read-write + + Disabled + Analog watchdog disabled on regular channels + 0 + + + Enabled + Analog watchdog enabled on regular channels + 1 + + + + + JAWDEN + Analog watchdog enable on injected + channels + 22 + 1 + + JAWDEN + read-write + + Disabled + Analog watchdog disabled on injected channels + 0 + + + Enabled + Analog watchdog enabled on injected channels + 1 + + + + + DISCNUM + Discontinuous mode channel + count + 13 + 3 + + + 0 + 7 + + + + + JDISCEN + Discontinuous mode on injected + channels + 12 + 1 + + JDISCEN + read-write + + Disabled + Discontinuous mode on injected channels disabled + 0 + + + Enabled + Discontinuous mode on injected channels enabled + 1 + + + + + DISCEN + Discontinuous mode on regular + channels + 11 + 1 + + DISCEN + read-write + + Disabled + Discontinuous mode on regular channels disabled + 0 + + + Enabled + Discontinuous mode on regular channels enabled + 1 + + + + + JAUTO + Automatic injected group + conversion + 10 + 1 + + JAUTO + read-write + + Disabled + Automatic injected group conversion disabled + 0 + + + Enabled + Automatic injected group conversion enabled + 1 + + + + + AWDSGL + Enable the watchdog on a single channel + in scan mode + 9 + 1 + + AWDSGL + read-write + + AllChannels + Analog watchdog enabled on all channels + 0 + + + SingleChannel + Analog watchdog enabled on a single channel + 1 + + + + + SCAN + Scan mode + 8 + 1 + + SCAN + read-write + + Disabled + Scan mode disabled + 0 + + + Enabled + Scan mode enabled + 1 + + + + + JEOCIE + Interrupt enable for injected + channels + 7 + 1 + + JEOCIE + read-write + + Disabled + JEOC interrupt disabled + 0 + + + Enabled + JEOC interrupt enabled + 1 + + + + + AWDIE + Analog watchdog interrupt + enable + 6 + 1 + + AWDIE + read-write + + Disabled + Analogue watchdog interrupt disabled + 0 + + + Enabled + Analogue watchdog interrupt enabled + 1 + + + + + EOCIE + Interrupt enable for EOC + 5 + 1 + + EOCIE + read-write + + Disabled + EOC interrupt disabled + 0 + + + Enabled + EOC interrupt enabled + 1 + + + + + AWDCH + Analog watchdog channel select + bits + 0 + 5 + + + 0 + 18 + + + + + + + CR2 + CR2 + control register 2 + 0x8 + 0x20 + read-write + 0x00000000 + + + SWSTART + Start conversion of regular + channels + 30 + 1 + + SWSTARTW + write + + Start + Starts conversion of regular channels + 1 + + + + + EXTEN + External trigger enable for regular + channels + 28 + 2 + + EXTEN + read-write + + Disabled + Trigger detection disabled + 0 + + + RisingEdge + Trigger detection on the rising edge + 1 + + + FallingEdge + Trigger detection on the falling edge + 2 + + + BothEdges + Trigger detection on both the rising and falling edges + 3 + + + + + EXTSEL + External event select for regular + group + 24 + 4 + + EXTSEL + read-write + + TIM1CC1 + Timer 1 CC1 event + 0 + + + TIM1CC2 + Timer 1 CC2 event + 1 + + + TIM1CC3 + Timer 1 CC3 event + 2 + + + TIM2CC2 + Timer 2 CC2 event + 3 + + + TIM2CC3 + Timer 2 CC3 event + 4 + + + TIM2CC4 + Timer 2 CC4 event + 5 + + + TIM2TRGO + Timer 2 TRGO event + 6 + + + TIM3CC1 + Timer 3 CC1 event + 7 + + + TIM3TRGO + Timer 3 TRGO event + 8 + + + TIM4CC4 + Timer 4 CC4 event + 9 + + + TIM5CC1 + Timer 5 CC1 event + 10 + + + TIM5CC2 + Timer 5 CC2 event + 11 + + + TIM5CC3 + Timer 5 CC3 event + 12 + + + EXTI11 + EXTI line 11 + 15 + + + + + JSWSTART + Start conversion of injected + channels + 22 + 1 + + JSWSTARTW + write + + Start + Starts conversion of injected channels + 1 + + + + + JEXTEN + External trigger enable for injected + channels + 20 + 2 + + JEXTEN + read-write + + Disabled + Trigger detection disabled + 0 + + + RisingEdge + Trigger detection on the rising edge + 1 + + + FallingEdge + Trigger detection on the falling edge + 2 + + + BothEdges + Trigger detection on both the rising and falling edges + 3 + + + + + JEXTSEL + External event select for injected + group + 16 + 4 + + JEXTSEL + read-write + + TIM1CC4 + Timer 1 CC4 event + 0 + + + TIM1TRGO + Timer 1 TRGO event + 1 + + + TIM2CC1 + Timer 2 CC1 event + 2 + + + TIM2TRGO + Timer 2 TRGO event + 3 + + + TIM3CC2 + Timer 3 CC2 event + 4 + + + TIM3CC4 + Timer 3 CC4 event + 5 + + + TIM4CC1 + Timer 4 CC1 event + 6 + + + TIM4CC2 + Timer 4 CC2 event + 7 + + + TIM4CC3 + Timer 4 CC3 event + 8 + + + TIM4TRGO + Timer 4 TRGO event + 9 + + + TIM5CC4 + Timer 5 CC4 event + 10 + + + TIM5TRGO + Timer 5 TRGO event + 11 + + + EXTI15 + EXTI line 15 + 15 + + + + + ALIGN + Data alignment + 11 + 1 + + ALIGN + read-write + + Right + Right alignment + 0 + + + Left + Left alignment + 1 + + + + + EOCS + End of conversion + selection + 10 + 1 + + EOCS + read-write + + EachSequence + The EOC bit is set at the end of each sequence of regular conversions + 0 + + + EachConversion + The EOC bit is set at the end of each regular conversion + 1 + + + + + DDS + DMA disable selection (for single ADC + mode) + 9 + 1 + + DDS + read-write + + Single + No new DMA request is issued after the last transfer + 0 + + + Continuous + DMA requests are issued as long as data are converted and DMA=1 + 1 + + + + + DMA + Direct memory access mode (for single + ADC mode) + 8 + 1 + + DMA + read-write + + Disabled + DMA mode disabled + 0 + + + Enabled + DMA mode enabled + 1 + + + + + CONT + Continuous conversion + 1 + 1 + + CONT + read-write + + Single + Single conversion mode + 0 + + + Continuous + Continuous conversion mode + 1 + + + + + ADON + A/D Converter ON / OFF + 0 + 1 + + ADON + read-write + + Disabled + Disable ADC conversion and go to power down mode + 0 + + + Enabled + Enable ADC + 1 + + + + + + + SMPR1 + SMPR1 + sample time register 1 + 0xC + 0x20 + read-write + 0x00000000 + + + SMP18 + Channel 18 sampling time selection + 24 + 3 + + + + SMP17 + Channel 17 sampling time selection + 21 + 3 + + + + SMP16 + Channel 16 sampling time selection + 18 + 3 + + + + SMP15 + Channel 15 sampling time selection + 15 + 3 + + + + SMP14 + Channel 14 sampling time selection + 12 + 3 + + + + SMP13 + Channel 13 sampling time selection + 9 + 3 + + + + SMP12 + Channel 12 sampling time selection + 6 + 3 + + + + SMP11 + Channel 11 sampling time selection + 3 + 3 + + + + SMP10 + Channel 10 sampling time selection + 0 + 3 + + SMP10 + read-write + + Cycles3 + 3 cycles + 0 + + + Cycles15 + 15 cycles + 1 + + + Cycles28 + 28 cycles + 2 + + + Cycles56 + 56 cycles + 3 + + + Cycles84 + 84 cycles + 4 + + + Cycles112 + 112 cycles + 5 + + + Cycles144 + 144 cycles + 6 + + + Cycles480 + 480 cycles + 7 + + + + + + + SMPR2 + SMPR2 + sample time register 2 + 0x10 + 0x20 + read-write + 0x00000000 + + + SMP9 + Channel 9 sampling time selection + 27 + 3 + + + + SMP8 + Channel 8 sampling time selection + 24 + 3 + + + + SMP7 + Channel 7 sampling time selection + 21 + 3 + + + + SMP6 + Channel 6 sampling time selection + 18 + 3 + + + + SMP5 + Channel 5 sampling time selection + 15 + 3 + + + + SMP4 + Channel 4 sampling time selection + 12 + 3 + + + + SMP3 + Channel 3 sampling time selection + 9 + 3 + + + + SMP2 + Channel 2 sampling time selection + 6 + 3 + + + + SMP1 + Channel 1 sampling time selection + 3 + 3 + + + + SMP0 + Channel 0 sampling time selection + 0 + 3 + + SMP0 + read-write + + Cycles3 + 3 cycles + 0 + + + Cycles15 + 15 cycles + 1 + + + Cycles28 + 28 cycles + 2 + + + Cycles56 + 56 cycles + 3 + + + Cycles84 + 84 cycles + 4 + + + Cycles112 + 112 cycles + 5 + + + Cycles144 + 144 cycles + 6 + + + Cycles480 + 480 cycles + 7 + + + + + + + 4 + 0x4 + 1-4 + JOFR%s + JOFR1 + injected channel data offset register + x + 0x14 + 0x20 + read-write + 0x00000000 + + + JOFFSET + Data offset for injected channel + x + 0 + 12 + + + 0 + 4095 + + + + + + + HTR + HTR + watchdog higher threshold + register + 0x24 + 0x20 + read-write + 0x00000FFF + + + HT + Analog watchdog higher + threshold + 0 + 12 + + + 0 + 4095 + + + + + + + LTR + LTR + watchdog lower threshold + register + 0x28 + 0x20 + read-write + 0x00000000 + + + LT + Analog watchdog lower + threshold + 0 + 12 + + + 0 + 4095 + + + + + + + SQR1 + SQR1 + regular sequence register 1 + 0x2C + 0x20 + read-write + 0x00000000 + + + L + Regular channel sequence + length + 20 + 4 + + + 0 + 15 + + + + + SQ16 + 16th conversion in regular + sequence + 15 + 5 + + + 0 + 18 + + + + + SQ15 + 15th conversion in regular + sequence + 10 + 5 + + + 0 + 18 + + + + + SQ14 + 14th conversion in regular + sequence + 5 + 5 + + + 0 + 18 + + + + + SQ13 + 13th conversion in regular + sequence + 0 + 5 + + + 0 + 18 + + + + + + + SQR2 + SQR2 + regular sequence register 2 + 0x30 + 0x20 + read-write + 0x00000000 + + + SQ12 + 12th conversion in regular + sequence + 25 + 5 + + + 0 + 18 + + + + + SQ11 + 11th conversion in regular + sequence + 20 + 5 + + + 0 + 18 + + + + + SQ10 + 10th conversion in regular + sequence + 15 + 5 + + + 0 + 18 + + + + + SQ9 + 9th conversion in regular + sequence + 10 + 5 + + + 0 + 18 + + + + + SQ8 + 8th conversion in regular + sequence + 5 + 5 + + + 0 + 18 + + + + + SQ7 + 7th conversion in regular + sequence + 0 + 5 + + + 0 + 18 + + + + + + + SQR3 + SQR3 + regular sequence register 3 + 0x34 + 0x20 + read-write + 0x00000000 + + + SQ6 + 6th conversion in regular + sequence + 25 + 5 + + + 0 + 18 + + + + + SQ5 + 5th conversion in regular + sequence + 20 + 5 + + + 0 + 18 + + + + + SQ4 + 4th conversion in regular + sequence + 15 + 5 + + + 0 + 18 + + + + + SQ3 + 3rd conversion in regular + sequence + 10 + 5 + + + 0 + 18 + + + + + SQ2 + 2nd conversion in regular + sequence + 5 + 5 + + + 0 + 18 + + + + + SQ1 + 1st conversion in regular + sequence + 0 + 5 + + + 0 + 18 + + + + + + + JSQR + JSQR + injected sequence register + 0x38 + 0x20 + read-write + 0x00000000 + + + JL + Injected sequence length + 20 + 2 + + + 0 + 3 + + + + + JSQ4 + 4th conversion in injected + sequence + 15 + 5 + + + 0 + 18 + + + + + JSQ3 + 3rd conversion in injected + sequence + 10 + 5 + + + 0 + 18 + + + + + JSQ2 + 2nd conversion in injected + sequence + 5 + 5 + + + 0 + 18 + + + + + JSQ1 + 1st conversion in injected + sequence + 0 + 5 + + + 0 + 18 + + + + + + + 4 + 0x4 + 1-4 + JDR%s + JDR1 + injected data register x + 0x3C + 0x20 + read-only + 0x00000000 + + + JDATA + Injected data + 0 + 16 + + + + + DR + DR + regular data register + 0x4C + 0x20 + read-only + 0x00000000 + + + DATA + Regular data + 0 + 16 + + + + + + + CRC + Cryptographic processor + CRC + 0x40023000 + + 0x0 + 0x400 + registers + + + + DR + DR + Data register + 0x0 + 0x20 + read-write + 0xFFFFFFFF + + + DR + Data Register + 0 + 32 + + + 0 + 4294967295 + + + + + + + IDR + IDR + Independent Data register + 0x4 + 0x20 + read-write + 0x00000000 + + + IDR + Independent Data register + 0 + 8 + + + 0 + 255 + + + + + + + CR + CR + Control register + 0x8 + 0x20 + write-only + 0x00000000 + + + RESET + Control regidter + 0 + 1 + + RESETW + write + + Reset + Resets the CRC calculation unit and sets the data register to 0xFFFF FFFF + 1 + + + + + + + + + DBGMCU + Debug support + DBG + 0xE0042000 + + 0x0 + 0x400 + registers + + + + IDCODE + IDCODE + IDCODE + 0x0 + 0x20 + read-only + 0x10006411 + + + DEV_ID + DEV_ID + 0 + 12 + + + REV_ID + REV_ID + 16 + 16 + + + + + CR + CR + Control Register + 0x4 + 0x20 + read-write + 0x00000000 + + + DBG_SLEEP + DBG_SLEEP + 0 + 1 + + + DBG_STOP + DBG_STOP + 1 + 1 + + + DBG_STANDBY + DBG_STANDBY + 2 + 1 + + + TRACE_IOEN + TRACE_IOEN + 5 + 1 + + + TRACE_MODE + TRACE_MODE + 6 + 2 + + + + + APB1_FZ + APB1_FZ + Debug MCU APB1 Freeze registe + 0x8 + 0x20 + read-write + 0x00000000 + + + DBG_TIM2_STOP + DBG_TIM2_STOP + 0 + 1 + + + DBG_TIM3_STOP + DBG_TIM3 _STOP + 1 + 1 + + + DBG_TIM4_STOP + DBG_TIM4_STOP + 2 + 1 + + + DBG_TIM5_STOP + DBG_TIM5_STOP + 3 + 1 + + + DBG_RTC_Stop + RTC stopped when Core is + halted + 10 + 1 + + + DBG_WWDG_STOP + DBG_WWDG_STOP + 11 + 1 + + + DBG_IWDG_STOP + DBG_IWDEG_STOP + 12 + 1 + + + DBG_I2C1_SMBUS_TIMEOUT + DBG_J2C1_SMBUS_TIMEOUT + 21 + 1 + + + DBG_I2C2_SMBUS_TIMEOUT + DBG_J2C2_SMBUS_TIMEOUT + 22 + 1 + + + DBG_I2C3SMBUS_TIMEOUT + DBG_J2C3SMBUS_TIMEOUT + 23 + 1 + + + + + APB2_FZ + APB2_FZ + Debug MCU APB2 Freeze registe + 0xC + 0x20 + read-write + 0x00000000 + + + DBG_TIM1_STOP + TIM1 counter stopped when core is + halted + 0 + 1 + + + DBG_TIM9_STOP + TIM9 counter stopped when core is + halted + 16 + 1 + + + DBG_TIM10_STOP + TIM10 counter stopped when core is + halted + 17 + 1 + + + DBG_TIM11_STOP + TIM11 counter stopped when core is + halted + 18 + 1 + + + + + + + EXTI + External interrupt/event + controller + EXTI + 0x40013C00 + + 0x0 + 0x400 + registers + + + TAMP_STAMP + Tamper and TimeStamp interrupts through the + EXTI line + 2 + + + EXTI0 + EXTI Line0 interrupt + 6 + + + EXTI1 + EXTI Line1 interrupt + 7 + + + EXTI2 + EXTI Line2 interrupt + 8 + + + EXTI3 + EXTI Line3 interrupt + 9 + + + EXTI4 + EXTI Line4 interrupt + 10 + + + EXTI9_5 + EXTI Line[9:5] interrupts + 23 + + + EXTI15_10 + EXTI Line[15:10] interrupts + 40 + + + + IMR + IMR + Interrupt mask register + (EXTI_IMR) + 0x0 + 0x20 + read-write + 0x00000000 + + + MR0 + Interrupt Mask on line 0 + 0 + 1 + + MR0 + read-write + + Masked + Interrupt request line is masked + 0 + + + Unmasked + Interrupt request line is unmasked + 1 + + + + + MR1 + Interrupt Mask on line 1 + 1 + 1 + + + + MR2 + Interrupt Mask on line 2 + 2 + 1 + + + + MR3 + Interrupt Mask on line 3 + 3 + 1 + + + + MR4 + Interrupt Mask on line 4 + 4 + 1 + + + + MR5 + Interrupt Mask on line 5 + 5 + 1 + + + + MR6 + Interrupt Mask on line 6 + 6 + 1 + + + + MR7 + Interrupt Mask on line 7 + 7 + 1 + + + + MR8 + Interrupt Mask on line 8 + 8 + 1 + + + + MR9 + Interrupt Mask on line 9 + 9 + 1 + + + + MR10 + Interrupt Mask on line 10 + 10 + 1 + + + + MR11 + Interrupt Mask on line 11 + 11 + 1 + + + + MR12 + Interrupt Mask on line 12 + 12 + 1 + + + + MR13 + Interrupt Mask on line 13 + 13 + 1 + + + + MR14 + Interrupt Mask on line 14 + 14 + 1 + + + + MR15 + Interrupt Mask on line 15 + 15 + 1 + + + + MR16 + Interrupt Mask on line 16 + 16 + 1 + + + + MR17 + Interrupt Mask on line 17 + 17 + 1 + + + + MR18 + Interrupt Mask on line 18 + 18 + 1 + + + + MR19 + Interrupt Mask on line 19 + 19 + 1 + + + + MR20 + Interrupt Mask on line 20 + 20 + 1 + + + + MR21 + Interrupt Mask on line 21 + 21 + 1 + + + + MR22 + Interrupt Mask on line 22 + 22 + 1 + + + + + + EMR + EMR + Event mask register (EXTI_EMR) + 0x4 + 0x20 + read-write + 0x00000000 + + + MR0 + Event Mask on line 0 + 0 + 1 + + MR0 + read-write + + Masked + Interrupt request line is masked + 0 + + + Unmasked + Interrupt request line is unmasked + 1 + + + + + MR1 + Event Mask on line 1 + 1 + 1 + + + + MR2 + Event Mask on line 2 + 2 + 1 + + + + MR3 + Event Mask on line 3 + 3 + 1 + + + + MR4 + Event Mask on line 4 + 4 + 1 + + + + MR5 + Event Mask on line 5 + 5 + 1 + + + + MR6 + Event Mask on line 6 + 6 + 1 + + + + MR7 + Event Mask on line 7 + 7 + 1 + + + + MR8 + Event Mask on line 8 + 8 + 1 + + + + MR9 + Event Mask on line 9 + 9 + 1 + + + + MR10 + Event Mask on line 10 + 10 + 1 + + + + MR11 + Event Mask on line 11 + 11 + 1 + + + + MR12 + Event Mask on line 12 + 12 + 1 + + + + MR13 + Event Mask on line 13 + 13 + 1 + + + + MR14 + Event Mask on line 14 + 14 + 1 + + + + MR15 + Event Mask on line 15 + 15 + 1 + + + + MR16 + Event Mask on line 16 + 16 + 1 + + + + MR17 + Event Mask on line 17 + 17 + 1 + + + + MR18 + Event Mask on line 18 + 18 + 1 + + + + MR19 + Event Mask on line 19 + 19 + 1 + + + + MR20 + Event Mask on line 20 + 20 + 1 + + + + MR21 + Event Mask on line 21 + 21 + 1 + + + + MR22 + Event Mask on line 22 + 22 + 1 + + + + + + RTSR + RTSR + Rising Trigger selection register + (EXTI_RTSR) + 0x8 + 0x20 + read-write + 0x00000000 + + + TR0 + Rising trigger event configuration of + line 0 + 0 + 1 + + TR0 + read-write + + Disabled + Rising edge trigger is disabled + 0 + + + Enabled + Rising edge trigger is enabled + 1 + + + + + TR1 + Rising trigger event configuration of + line 1 + 1 + 1 + + + + TR2 + Rising trigger event configuration of + line 2 + 2 + 1 + + + + TR3 + Rising trigger event configuration of + line 3 + 3 + 1 + + + + TR4 + Rising trigger event configuration of + line 4 + 4 + 1 + + + + TR5 + Rising trigger event configuration of + line 5 + 5 + 1 + + + + TR6 + Rising trigger event configuration of + line 6 + 6 + 1 + + + + TR7 + Rising trigger event configuration of + line 7 + 7 + 1 + + + + TR8 + Rising trigger event configuration of + line 8 + 8 + 1 + + + + TR9 + Rising trigger event configuration of + line 9 + 9 + 1 + + + + TR10 + Rising trigger event configuration of + line 10 + 10 + 1 + + + + TR11 + Rising trigger event configuration of + line 11 + 11 + 1 + + + + TR12 + Rising trigger event configuration of + line 12 + 12 + 1 + + + + TR13 + Rising trigger event configuration of + line 13 + 13 + 1 + + + + TR14 + Rising trigger event configuration of + line 14 + 14 + 1 + + + + TR15 + Rising trigger event configuration of + line 15 + 15 + 1 + + + + TR16 + Rising trigger event configuration of + line 16 + 16 + 1 + + + + TR17 + Rising trigger event configuration of + line 17 + 17 + 1 + + + + TR18 + Rising trigger event configuration of + line 18 + 18 + 1 + + + + TR19 + Rising trigger event configuration of + line 19 + 19 + 1 + + + + TR20 + Rising trigger event configuration of + line 20 + 20 + 1 + + + + TR21 + Rising trigger event configuration of + line 21 + 21 + 1 + + + + TR22 + Rising trigger event configuration of + line 22 + 22 + 1 + + + + + + FTSR + FTSR + Falling Trigger selection register + (EXTI_FTSR) + 0xC + 0x20 + read-write + 0x00000000 + + + TR0 + Falling trigger event configuration of + line 0 + 0 + 1 + + TR0 + read-write + + Disabled + Falling edge trigger is disabled + 0 + + + Enabled + Falling edge trigger is enabled + 1 + + + + + TR1 + Falling trigger event configuration of + line 1 + 1 + 1 + + + + TR2 + Falling trigger event configuration of + line 2 + 2 + 1 + + + + TR3 + Falling trigger event configuration of + line 3 + 3 + 1 + + + + TR4 + Falling trigger event configuration of + line 4 + 4 + 1 + + + + TR5 + Falling trigger event configuration of + line 5 + 5 + 1 + + + + TR6 + Falling trigger event configuration of + line 6 + 6 + 1 + + + + TR7 + Falling trigger event configuration of + line 7 + 7 + 1 + + + + TR8 + Falling trigger event configuration of + line 8 + 8 + 1 + + + + TR9 + Falling trigger event configuration of + line 9 + 9 + 1 + + + + TR10 + Falling trigger event configuration of + line 10 + 10 + 1 + + + + TR11 + Falling trigger event configuration of + line 11 + 11 + 1 + + + + TR12 + Falling trigger event configuration of + line 12 + 12 + 1 + + + + TR13 + Falling trigger event configuration of + line 13 + 13 + 1 + + + + TR14 + Falling trigger event configuration of + line 14 + 14 + 1 + + + + TR15 + Falling trigger event configuration of + line 15 + 15 + 1 + + + + TR16 + Falling trigger event configuration of + line 16 + 16 + 1 + + + + TR17 + Falling trigger event configuration of + line 17 + 17 + 1 + + + + TR18 + Falling trigger event configuration of + line 18 + 18 + 1 + + + + TR19 + Falling trigger event configuration of + line 19 + 19 + 1 + + + + TR20 + Falling trigger event configuration of + line 20 + 20 + 1 + + + + TR21 + Falling trigger event configuration of + line 21 + 21 + 1 + + + + TR22 + Falling trigger event configuration of + line 22 + 22 + 1 + + + + + + SWIER + SWIER + Software interrupt event register + (EXTI_SWIER) + 0x10 + 0x20 + read-write + 0x00000000 + + + SWIER0 + Software Interrupt on line + 0 + 0 + 1 + + SWIER0W + write + + Pend + Generates an interrupt request + 1 + + + + + SWIER1 + Software Interrupt on line + 1 + 1 + 1 + + + + SWIER2 + Software Interrupt on line + 2 + 2 + 1 + + + + SWIER3 + Software Interrupt on line + 3 + 3 + 1 + + + + SWIER4 + Software Interrupt on line + 4 + 4 + 1 + + + + SWIER5 + Software Interrupt on line + 5 + 5 + 1 + + + + SWIER6 + Software Interrupt on line + 6 + 6 + 1 + + + + SWIER7 + Software Interrupt on line + 7 + 7 + 1 + + + + SWIER8 + Software Interrupt on line + 8 + 8 + 1 + + + + SWIER9 + Software Interrupt on line + 9 + 9 + 1 + + + + SWIER10 + Software Interrupt on line + 10 + 10 + 1 + + + + SWIER11 + Software Interrupt on line + 11 + 11 + 1 + + + + SWIER12 + Software Interrupt on line + 12 + 12 + 1 + + + + SWIER13 + Software Interrupt on line + 13 + 13 + 1 + + + + SWIER14 + Software Interrupt on line + 14 + 14 + 1 + + + + SWIER15 + Software Interrupt on line + 15 + 15 + 1 + + + + SWIER16 + Software Interrupt on line + 16 + 16 + 1 + + + + SWIER17 + Software Interrupt on line + 17 + 17 + 1 + + + + SWIER18 + Software Interrupt on line + 18 + 18 + 1 + + + + SWIER19 + Software Interrupt on line + 19 + 19 + 1 + + + + SWIER20 + Software Interrupt on line + 20 + 20 + 1 + + + + SWIER21 + Software Interrupt on line + 21 + 21 + 1 + + + + SWIER22 + Software Interrupt on line + 22 + 22 + 1 + + + + + + PR + PR + Pending register (EXTI_PR) + 0x14 + 0x20 + read-write + 0x00000000 + + + PR0 + Pending bit 0 + 0 + 1 + oneToClear + + PR0R + read + + NotPending + No trigger request occurred + 0 + + + Pending + Selected trigger request occurred + 1 + + + + PR0W + write + + Clear + Clears pending bit + 1 + + + + + PR1 + Pending bit 1 + 1 + 1 + oneToClear + + read + + + write + + + + PR2 + Pending bit 2 + 2 + 1 + oneToClear + + read + + + write + + + + PR3 + Pending bit 3 + 3 + 1 + oneToClear + + read + + + write + + + + PR4 + Pending bit 4 + 4 + 1 + oneToClear + + read + + + write + + + + PR5 + Pending bit 5 + 5 + 1 + oneToClear + + read + + + write + + + + PR6 + Pending bit 6 + 6 + 1 + oneToClear + + read + + + write + + + + PR7 + Pending bit 7 + 7 + 1 + oneToClear + + read + + + write + + + + PR8 + Pending bit 8 + 8 + 1 + oneToClear + + read + + + write + + + + PR9 + Pending bit 9 + 9 + 1 + oneToClear + + read + + + write + + + + PR10 + Pending bit 10 + 10 + 1 + oneToClear + + read + + + write + + + + PR11 + Pending bit 11 + 11 + 1 + oneToClear + + read + + + write + + + + PR12 + Pending bit 12 + 12 + 1 + oneToClear + + read + + + write + + + + PR13 + Pending bit 13 + 13 + 1 + oneToClear + + read + + + write + + + + PR14 + Pending bit 14 + 14 + 1 + oneToClear + + read + + + write + + + + PR15 + Pending bit 15 + 15 + 1 + oneToClear + + read + + + write + + + + PR16 + Pending bit 16 + 16 + 1 + oneToClear + + read + + + write + + + + PR17 + Pending bit 17 + 17 + 1 + oneToClear + + read + + + write + + + + PR18 + Pending bit 18 + 18 + 1 + oneToClear + + read + + + write + + + + PR19 + Pending bit 19 + 19 + 1 + oneToClear + + read + + + write + + + + PR20 + Pending bit 20 + 20 + 1 + oneToClear + + read + + + write + + + + PR21 + Pending bit 21 + 21 + 1 + oneToClear + + read + + + write + + + + PR22 + Pending bit 22 + 22 + 1 + oneToClear + + read + + + write + + + + + + + + FLASH + FLASH + FLASH + 0x40023C00 + + 0x0 + 0x400 + registers + + + FLASH + FLASH global interrupt + 4 + + + + ACR + ACR + Flash access control register + 0x0 + 0x20 + 0x00000000 + + + LATENCY + Latency + 0 + 4 + read-write + + LATENCY + read-write + + WS0 + 0 wait states + 0 + + + WS1 + 1 wait states + 1 + + + WS2 + 2 wait states + 2 + + + WS3 + 3 wait states + 3 + + + WS4 + 4 wait states + 4 + + + WS5 + 5 wait states + 5 + + + WS6 + 6 wait states + 6 + + + WS7 + 7 wait states + 7 + + + WS8 + 8 wait states + 8 + + + WS9 + 9 wait states + 9 + + + WS10 + 10 wait states + 10 + + + WS11 + 11 wait states + 11 + + + WS12 + 12 wait states + 12 + + + WS13 + 13 wait states + 13 + + + WS14 + 14 wait states + 14 + + + WS15 + 15 wait states + 15 + + + + + PRFTEN + Prefetch enable + 8 + 1 + read-write + + PRFTEN + read-write + + Disabled + Prefetch is disabled + 0 + + + Enabled + Prefetch is enabled + 1 + + + + + ICEN + Instruction cache enable + 9 + 1 + read-write + + ICEN + read-write + + Disabled + Instruction cache is disabled + 0 + + + Enabled + Instruction cache is enabled + 1 + + + + + DCEN + Data cache enable + 10 + 1 + read-write + + DCEN + read-write + + Disabled + Data cache is disabled + 0 + + + Enabled + Data cache is enabled + 1 + + + + + ICRST + Instruction cache reset + 11 + 1 + write-only + + ICRST + write + + NotReset + Instruction cache is not reset + 0 + + + Reset + Instruction cache is reset + 1 + + + + + DCRST + Data cache reset + 12 + 1 + read-write + + DCRST + read-write + + NotReset + Data cache is not reset + 0 + + + Reset + Data cache is reset + 1 + + + + + + + KEYR + KEYR + Flash key register + 0x4 + 0x20 + write-only + 0x00000000 + + + KEY + FPEC key + 0 + 32 + + + 0 + 4294967295 + + + + + + + OPTKEYR + OPTKEYR + Flash option key register + 0x8 + 0x20 + write-only + 0x00000000 + + + OPTKEY + Option byte key + 0 + 32 + + + 0 + 4294967295 + + + + + + + SR + SR + Status register + 0xC + 0x20 + 0x00000000 + + + EOP + End of operation + 0 + 1 + read-write + oneToClear + + EOPW + write + + Clear + Clear error flag + 1 + + + + + OPERR + Operation error + 1 + 1 + read-write + oneToClear + + OPERRW + write + + Clear + Clear error flag + 1 + + + + + WRPERR + Write protection error + 4 + 1 + read-write + oneToClear + + WRPERRW + write + + Clear + Clear error flag + 1 + + + + + PGAERR + Programming alignment + error + 5 + 1 + read-write + oneToClear + + PGAERRW + write + + Clear + Clear error flag + 1 + + + + + PGPERR + Programming parallelism + error + 6 + 1 + read-write + oneToClear + + PGPERRW + write + + Clear + Clear error flag + 1 + + + + + PGSERR + Programming sequence error + 7 + 1 + read-write + oneToClear + + PGSERRW + write + + Clear + Clear error flag + 1 + + + + + BSY + Busy + 16 + 1 + read-only + + BSYR + read + + NotBusy + no Flash memory operation ongoing + 0 + + + Busy + Flash memory operation ongoing + 1 + + + + + + + CR + CR + Control register + 0x10 + 0x20 + read-write + 0x80000000 + + + PG + Programming + 0 + 1 + + PG + read-write + + Program + Flash programming activated + 1 + + + + + SER + Sector Erase + 1 + 1 + + SER + read-write + + SectorErase + Erase activated for selected sector + 1 + + + + + MER + Mass Erase + 2 + 1 + + MER + read-write + + MassErase + Erase activated for all user sectors + 1 + + + + + SNB + Sector number + 3 + 4 + + + 0 + 11 + + + + + PSIZE + Program size + 8 + 2 + + PSIZE + read-write + + PSIZE8 + Program x8 + 0 + + + PSIZE16 + Program x16 + 1 + + + PSIZE32 + Program x32 + 2 + + + PSIZE64 + Program x64 + 3 + + + + + STRT + Start + 16 + 1 + + STRT + read-write + + Start + Trigger an erase operation + 1 + + + + + EOPIE + End of operation interrupt + enable + 24 + 1 + + EOPIE + read-write + + Disabled + End of operation interrupt disabled + 0 + + + Enabled + End of operation interrupt enabled + 1 + + + + + ERRIE + Error interrupt enable + 25 + 1 + + ERRIE + read-write + + Disabled + Error interrupt generation disabled + 0 + + + Enabled + Error interrupt generation enabled + 1 + + + + + LOCK + Lock + 31 + 1 + + LOCK + read-write + + Unlocked + FLASH_CR register is unlocked + 0 + + + Locked + FLASH_CR register is locked + 1 + + + + + + + OPTCR + OPTCR + Flash option control register + 0x14 + 0x20 + read-write + 0x00000014 + + + OPTLOCK + Option lock + 0 + 1 + + + OPTSTRT + Option start + 1 + 1 + + + BOR_LEV + BOR reset Level + 2 + 2 + + + WDG_SW + WDG_SW User option bytes + 5 + 1 + + + nRST_STOP + nRST_STOP User option + bytes + 6 + 1 + + + nRST_STDBY + nRST_STDBY User option + bytes + 7 + 1 + + + RDP + Read protect + 8 + 8 + + + nWRP + Not write protect + 16 + 12 + + + + + + + IWDG + Independent watchdog + IWDG + 0x40003000 + + 0x0 + 0x400 + registers + + + + KR + KR + Key register + 0x0 + 0x20 + write-only + 0x00000000 + + + KEY + Key value + 0 + 16 + + KEY + write + + Enable + Enable access to PR, RLR and WINR registers (0x5555) + 21845 + + + Reset + Reset the watchdog value (0xAAAA) + 43690 + + + Start + Start the watchdog (0xCCCC) + 52428 + + + + + + + PR + PR + Prescaler register + 0x4 + 0x20 + read-write + 0x00000000 + + + PR + Prescaler divider + 0 + 3 + + PR + read-write + + DivideBy4 + Divider /4 + 0 + + + DivideBy8 + Divider /8 + 1 + + + DivideBy16 + Divider /16 + 2 + + + DivideBy32 + Divider /32 + 3 + + + DivideBy64 + Divider /64 + 4 + + + DivideBy128 + Divider /128 + 5 + + + DivideBy256 + Divider /256 + 6 + + + DivideBy256bis + Divider /256 + 7 + + + + + + + RLR + RLR + Reload register + 0x8 + 0x20 + read-write + 0x00000FFF + + + RL + Watchdog counter reload + value + 0 + 12 + + + 0 + 4095 + + + + + + + SR + SR + Status register + 0xC + 0x20 + read-only + 0x00000000 + + + RVU + Watchdog counter reload value + update + 1 + 1 + + + PVU + Watchdog prescaler value + update + 0 + 1 + + + + + + + OTG_FS_DEVICE + USB on the go full speed + USB_OTG_FS + 0x50000800 + + 0x0 + 0x400 + registers + + + + DCFG + DCFG + OTG_FS device configuration register + (OTG_FS_DCFG) + 0x0 + 0x20 + read-write + 0x02200000 + + + DSPD + Device speed + 0 + 2 + + + NZLSOHSK + Non-zero-length status OUT + handshake + 2 + 1 + + + DAD + Device address + 4 + 7 + + + PFIVL + Periodic frame interval + 11 + 2 + + + + + DCTL + DCTL + OTG_FS device control register + (OTG_FS_DCTL) + 0x4 + 0x20 + 0x00000000 + + + RWUSIG + Remote wakeup signaling + 0 + 1 + read-write + + + SDIS + Soft disconnect + 1 + 1 + read-write + + + GINSTS + Global IN NAK status + 2 + 1 + read-only + + + GONSTS + Global OUT NAK status + 3 + 1 + read-only + + + TCTL + Test control + 4 + 3 + read-write + + + SGINAK + Set global IN NAK + 7 + 1 + read-write + + + CGINAK + Clear global IN NAK + 8 + 1 + read-write + + + SGONAK + Set global OUT NAK + 9 + 1 + read-write + + + CGONAK + Clear global OUT NAK + 10 + 1 + read-write + + + POPRGDNE + Power-on programming done + 11 + 1 + read-write + + + + + DSTS + DSTS + OTG_FS device status register + (OTG_FS_DSTS) + 0x8 + 0x20 + read-only + 0x00000010 + + + SUSPSTS + Suspend status + 0 + 1 + + + ENUMSPD + Enumerated speed + 1 + 2 + + + EERR + Erratic error + 3 + 1 + + + FNSOF + Frame number of the received + SOF + 8 + 14 + + + + + DIEPMSK + DIEPMSK + OTG_FS device IN endpoint common interrupt + mask register (OTG_FS_DIEPMSK) + 0x10 + 0x20 + read-write + 0x00000000 + + + XFRCM + Transfer completed interrupt + mask + 0 + 1 + + + EPDM + Endpoint disabled interrupt + mask + 1 + 1 + + + TOM + Timeout condition mask (Non-isochronous + endpoints) + 3 + 1 + + + ITTXFEMSK + IN token received when TxFIFO empty + mask + 4 + 1 + + + INEPNMM + IN token received with EP mismatch + mask + 5 + 1 + + + INEPNEM + IN endpoint NAK effective + mask + 6 + 1 + + + + + DOEPMSK + DOEPMSK + OTG_FS device OUT endpoint common interrupt + mask register (OTG_FS_DOEPMSK) + 0x14 + 0x20 + read-write + 0x00000000 + + + XFRCM + Transfer completed interrupt + mask + 0 + 1 + + + EPDM + Endpoint disabled interrupt + mask + 1 + 1 + + + STUPM + SETUP phase done mask + 3 + 1 + + + OTEPDM + OUT token received when endpoint + disabled mask + 4 + 1 + + + + + DAINT + DAINT + OTG_FS device all endpoints interrupt + register (OTG_FS_DAINT) + 0x18 + 0x20 + read-only + 0x00000000 + + + IEPINT + IN endpoint interrupt bits + 0 + 16 + + + OEPINT + OUT endpoint interrupt + bits + 16 + 16 + + + + + DAINTMSK + DAINTMSK + OTG_FS all endpoints interrupt mask register + (OTG_FS_DAINTMSK) + 0x1C + 0x20 + read-write + 0x00000000 + + + IEPM + IN EP interrupt mask bits + 0 + 16 + + + OEPM + OUT EP interrupt mask bits + 16 + 16 + + + + + DVBUSDIS + DVBUSDIS + OTG_FS device VBUS discharge time + register + 0x28 + 0x20 + read-write + 0x000017D7 + + + VBUSDT + Device VBUS discharge time + 0 + 16 + + + + + DVBUSPULSE + DVBUSPULSE + OTG_FS device VBUS pulsing time + register + 0x2C + 0x20 + read-write + 0x000005B8 + + + DVBUSP + Device VBUS pulsing time + 0 + 12 + + + + + DIEPEMPMSK + DIEPEMPMSK + OTG_FS device IN endpoint FIFO empty + interrupt mask register + 0x34 + 0x20 + read-write + 0x00000000 + + + INEPTXFEM + IN EP Tx FIFO empty interrupt mask + bits + 0 + 16 + + + + + DIEP0 + Device IN endpoint 0 + 0x100 + + CTL + DIEPCTL0 + OTG_FS device control IN endpoint 0 control + register (OTG_FS_DIEPCTL0) + 0x0 + 0x20 + 0x00000000 + + + MPSIZ + Maximum packet size + 0 + 2 + read-write + + + USBAEP + USB active endpoint + 15 + 1 + read-only + + + NAKSTS + NAK status + 17 + 1 + read-only + + + EPTYP + Endpoint type + 18 + 2 + read-only + + + STALL + STALL handshake + 21 + 1 + read-write + + + TXFNUM + TxFIFO number + 22 + 4 + read-write + + + CNAK + Clear NAK + 26 + 1 + write-only + + + SNAK + Set NAK + 27 + 1 + write-only + + + EPDIS + Endpoint disable + 30 + 1 + read-only + + + EPENA + Endpoint enable + 31 + 1 + read-write + + + + + INT + DIEPINT0 + device endpoint-x interrupt + register + 0x8 + 0x20 + 0x00000080 + + + TXFE + TXFE + 7 + 1 + read-only + + + INEPNE + INEPNE + 6 + 1 + read-write + + + ITTXFE + ITTXFE + 4 + 1 + read-write + + + TOC + TOC + 3 + 1 + read-write + + + EPDISD + EPDISD + 1 + 1 + read-write + + + XFRC + XFRC + 0 + 1 + read-write + + + + + TSIZ + DIEPTSIZ0 + device endpoint-0 transfer size + register + 0x10 + 0x20 + read-write + 0x00000000 + + + PKTCNT + Packet count + 19 + 2 + + + XFRSIZ + Transfer size + 0 + 7 + + + + + TXFSTS + DTXFSTS0 + OTG_FS device IN endpoint transmit FIFO + status register + 0x18 + 0x20 + read-only + 0x00000000 + + + INEPTFSAV + IN endpoint TxFIFO space + available + 0 + 16 + + + + + + 3 + 0x20 + 1-3 + DIEP%s + Device IN endpoint X + 0x120 + + CTL + DIEPCTL1 + OTG device endpoint-1 control + register + 0x0 + 0x20 + 0x00000000 + + + EPENA + EPENA + 31 + 1 + read-write + + + EPDIS + EPDIS + 30 + 1 + read-write + + + SODDFRM_SD1PID + SODDFRM/SD1PID + 29 + 1 + write-only + + + SD0PID_SEVNFRM + SD0PID/SEVNFRM + 28 + 1 + write-only + + + SNAK + SNAK + 27 + 1 + write-only + + + CNAK + CNAK + 26 + 1 + write-only + + + TXFNUM + TXFNUM + 22 + 4 + read-write + + + STALL + STALL handshake + 21 + 1 + read-write + + + EPTYP + EPTYP + 18 + 2 + read-write + + + NAKSTS + NAKSTS + 17 + 1 + read-only + + + EONUM_DPID + EONUM/DPID + 16 + 1 + read-only + + + USBAEP + USBAEP + 15 + 1 + read-write + + + MPSIZ + MPSIZ + 0 + 11 + read-write + + + + + INT + DIEPINT1 + device endpoint-1 interrupt + register + 0x8 + 0x20 + 0x00000080 + + + TXFE + TXFE + 7 + 1 + read-only + + + INEPNE + INEPNE + 6 + 1 + read-write + + + ITTXFE + ITTXFE + 4 + 1 + read-write + + + TOC + TOC + 3 + 1 + read-write + + + EPDISD + EPDISD + 1 + 1 + read-write + + + XFRC + XFRC + 0 + 1 + read-write + + + + + TSIZ + DIEPTSIZ1 + device endpoint-1 transfer size + register + 0x10 + 0x20 + read-write + 0x00000000 + + + MCNT + Multi count + 29 + 2 + + + PKTCNT + Packet count + 19 + 10 + + + XFRSIZ + Transfer size + 0 + 19 + + + + + TXFSTS + DTXFSTS1 + OTG_FS device IN endpoint transmit FIFO + status register + 0x18 + 0x20 + read-only + 0x00000000 + + + INEPTFSAV + IN endpoint TxFIFO space + available + 0 + 16 + + + + + + DOEP0 + Device OUT endpoint 0 + 0x300 + + CTL + DOEPCTL0 + device endpoint-0 control + register + 0x0 + 0x20 + 0x00008000 + + + EPENA + EPENA + 31 + 1 + read-write + + + EPDIS + EPDIS + 30 + 1 + read-only + + + SNAK + SNAK + 27 + 1 + write-only + + + CNAK + CNAK + 26 + 1 + write-only + + + STALL + STALL handshake + 21 + 1 + read-write + + + SNPM + SNPM + 20 + 1 + read-write + + + EPTYP + EPTYP + 18 + 2 + read-only + + + NAKSTS + NAKSTS + 17 + 1 + read-only + + + USBAEP + USBAEP + 15 + 1 + read-only + + + MPSIZ + MPSIZ + 0 + 2 + read-only + + + + + INT + DOEPINT0 + device endpoint-0 interrupt + register + 0x8 + 0x20 + read-write + 0x00000080 + + + B2BSTUP + B2BSTUP + 6 + 1 + + + OTEPDIS + OTEPDIS + 4 + 1 + + + STUP + STUP + 3 + 1 + + + EPDISD + EPDISD + 1 + 1 + + + XFRC + XFRC + 0 + 1 + + + + + TSIZ + DOEPTSIZ0 + device OUT endpoint-0 transfer size + register + 0x10 + 0x20 + read-write + 0x00000000 + + + STUPCNT + SETUP packet count + 29 + 2 + + + PKTCNT + Packet count + 19 + 1 + + + XFRSIZ + Transfer size + 0 + 7 + + + + + + 3 + 0x20 + 1-3 + DOEP%s + Device IN endpoint X + 0x320 + + CTL + DOEPCTL1 + device endpoint-1 control + register + 0x0 + 0x20 + 0x00000000 + + + EPENA + EPENA + 31 + 1 + read-write + + + EPDIS + EPDIS + 30 + 1 + read-write + + + SODDFRM + SODDFRM + 29 + 1 + write-only + + + SD0PID_SEVNFRM + SD0PID/SEVNFRM + 28 + 1 + write-only + + + SNAK + SNAK + 27 + 1 + write-only + + + CNAK + CNAK + 26 + 1 + write-only + + + STALL + STALL handshake + 21 + 1 + read-write + + + SNPM + SNPM + 20 + 1 + read-write + + + EPTYP + EPTYP + 18 + 2 + read-write + + + NAKSTS + NAKSTS + 17 + 1 + read-only + + + EONUM_DPID + EONUM/DPID + 16 + 1 + read-only + + + USBAEP + USBAEP + 15 + 1 + read-write + + + MPSIZ + MPSIZ + 0 + 11 + read-write + + + + + INT + DOEPINT1 + device endpoint-1 interrupt + register + 0x8 + 0x20 + read-write + 0x00000080 + + + B2BSTUP + B2BSTUP + 6 + 1 + + + OTEPDIS + OTEPDIS + 4 + 1 + + + STUP + STUP + 3 + 1 + + + EPDISD + EPDISD + 1 + 1 + + + XFRC + XFRC + 0 + 1 + + + + + TSIZ + DOEPTSIZ1 + device OUT endpoint-1 transfer size + register + 0x10 + 0x20 + read-write + 0x00000000 + + + RXDPID_STUPCNT + Received data PID/SETUP packet + count + 29 + 2 + + + PKTCNT + Packet count + 19 + 10 + + + XFRSIZ + Transfer size + 0 + 19 + + + + + + + + OTG_FS_GLOBAL + USB on the go full speed + USB_OTG_FS + 0x50000000 + + 0x0 + 0x400 + registers + + + + GOTGCTL + GOTGCTL + OTG_FS control and status register + (OTG_FS_GOTGCTL) + 0x0 + 0x20 + 0x00000800 + + + SRQSCS + Session request success + 0 + 1 + read-only + + + SRQ + Session request + 1 + 1 + read-write + + + HNGSCS + Host negotiation success + 8 + 1 + read-only + + + HNPRQ + HNP request + 9 + 1 + read-write + + + HSHNPEN + Host set HNP enable + 10 + 1 + read-write + + + DHNPEN + Device HNP enabled + 11 + 1 + read-write + + + CIDSTS + Connector ID status + 16 + 1 + read-only + + + DBCT + Long/short debounce time + 17 + 1 + read-only + + + ASVLD + A-session valid + 18 + 1 + read-only + + + BSVLD + B-session valid + 19 + 1 + read-only + + + + + GOTGINT + GOTGINT + OTG_FS interrupt register + (OTG_FS_GOTGINT) + 0x4 + 0x20 + read-write + 0x00000000 + + + SEDET + Session end detected + 2 + 1 + + + SRSSCHG + Session request success status + change + 8 + 1 + + + HNSSCHG + Host negotiation success status + change + 9 + 1 + + + HNGDET + Host negotiation detected + 17 + 1 + + + ADTOCHG + A-device timeout change + 18 + 1 + + + DBCDNE + Debounce done + 19 + 1 + + + + + GAHBCFG + GAHBCFG + OTG_FS AHB configuration register + (OTG_FS_GAHBCFG) + 0x8 + 0x20 + read-write + 0x00000000 + + + GINT + Global interrupt mask + 0 + 1 + + + TXFELVL + TxFIFO empty level + 7 + 1 + + + PTXFELVL + Periodic TxFIFO empty + level + 8 + 1 + + + + + GUSBCFG + GUSBCFG + OTG_FS USB configuration register + (OTG_FS_GUSBCFG) + 0xC + 0x20 + 0x00000A00 + + + TOCAL + FS timeout calibration + 0 + 3 + read-write + + + PHYSEL + Full Speed serial transceiver + select + 6 + 1 + write-only + + + SRPCAP + SRP-capable + 8 + 1 + read-write + + + HNPCAP + HNP-capable + 9 + 1 + read-write + + + TRDT + USB turnaround time + 10 + 4 + read-write + + + FHMOD + Force host mode + 29 + 1 + read-write + + + FDMOD + Force device mode + 30 + 1 + read-write + + + CTXPKT + Corrupt Tx packet + 31 + 1 + read-write + + + + + GRSTCTL + GRSTCTL + OTG_FS reset register + (OTG_FS_GRSTCTL) + 0x10 + 0x20 + 0x20000000 + + + CSRST + Core soft reset + 0 + 1 + read-write + + + HSRST + HCLK soft reset + 1 + 1 + read-write + + + FCRST + Host frame counter reset + 2 + 1 + read-write + + + RXFFLSH + RxFIFO flush + 4 + 1 + read-write + + + TXFFLSH + TxFIFO flush + 5 + 1 + read-write + + + TXFNUM + TxFIFO number + 6 + 5 + read-write + + + AHBIDL + AHB master idle + 31 + 1 + read-only + + + + + GINTSTS + GINTSTS + OTG_FS core interrupt register + (OTG_FS_GINTSTS) + 0x14 + 0x20 + 0x04000020 + + + CMOD + Current mode of operation + 0 + 1 + read-only + + + MMIS + Mode mismatch interrupt + 1 + 1 + read-write + + + OTGINT + OTG interrupt + 2 + 1 + read-only + + + SOF + Start of frame + 3 + 1 + read-write + + + RXFLVL + RxFIFO non-empty + 4 + 1 + read-only + + + NPTXFE + Non-periodic TxFIFO empty + 5 + 1 + read-only + + + GINAKEFF + Global IN non-periodic NAK + effective + 6 + 1 + read-only + + + GOUTNAKEFF + Global OUT NAK effective + 7 + 1 + read-only + + + ESUSP + Early suspend + 10 + 1 + read-write + + + USBSUSP + USB suspend + 11 + 1 + read-write + + + USBRST + USB reset + 12 + 1 + read-write + + + ENUMDNE + Enumeration done + 13 + 1 + read-write + + + ISOODRP + Isochronous OUT packet dropped + interrupt + 14 + 1 + read-write + + + EOPF + End of periodic frame + interrupt + 15 + 1 + read-write + + + IEPINT + IN endpoint interrupt + 18 + 1 + read-only + + + OEPINT + OUT endpoint interrupt + 19 + 1 + read-only + + + IISOIXFR + Incomplete isochronous IN + transfer + 20 + 1 + read-write + + + IPXFR_INCOMPISOOUT + Incomplete periodic transfer(Host + mode)/Incomplete isochronous OUT transfer(Device + mode) + 21 + 1 + read-write + + + HPRTINT + Host port interrupt + 24 + 1 + read-only + + + HCINT + Host channels interrupt + 25 + 1 + read-only + + + PTXFE + Periodic TxFIFO empty + 26 + 1 + read-only + + + CIDSCHG + Connector ID status change + 28 + 1 + read-write + + + DISCINT + Disconnect detected + interrupt + 29 + 1 + read-write + + + SRQINT + Session request/new session detected + interrupt + 30 + 1 + read-write + + + WKUPINT + Resume/remote wakeup detected + interrupt + 31 + 1 + read-write + + + + + GINTMSK + GINTMSK + OTG_FS interrupt mask register + (OTG_FS_GINTMSK) + 0x18 + 0x20 + 0x00000000 + + + MMISM + Mode mismatch interrupt + mask + 1 + 1 + read-write + + + OTGINT + OTG interrupt mask + 2 + 1 + read-write + + + SOFM + Start of frame mask + 3 + 1 + read-write + + + RXFLVLM + Receive FIFO non-empty + mask + 4 + 1 + read-write + + + NPTXFEM + Non-periodic TxFIFO empty + mask + 5 + 1 + read-write + + + GINAKEFFM + Global non-periodic IN NAK effective + mask + 6 + 1 + read-write + + + GONAKEFFM + Global OUT NAK effective + mask + 7 + 1 + read-write + + + ESUSPM + Early suspend mask + 10 + 1 + read-write + + + USBSUSPM + USB suspend mask + 11 + 1 + read-write + + + USBRST + USB reset mask + 12 + 1 + read-write + + + ENUMDNEM + Enumeration done mask + 13 + 1 + read-write + + + ISOODRPM + Isochronous OUT packet dropped interrupt + mask + 14 + 1 + read-write + + + EOPFM + End of periodic frame interrupt + mask + 15 + 1 + read-write + + + EPMISM + Endpoint mismatch interrupt + mask + 17 + 1 + read-write + + + IEPINT + IN endpoints interrupt + mask + 18 + 1 + read-write + + + OEPINT + OUT endpoints interrupt + mask + 19 + 1 + read-write + + + IISOIXFRM + Incomplete isochronous IN transfer + mask + 20 + 1 + read-write + + + IPXFRM_IISOOXFRM + Incomplete periodic transfer mask(Host + mode)/Incomplete isochronous OUT transfer mask(Device + mode) + 21 + 1 + read-write + + + PRTIM + Host port interrupt mask + 24 + 1 + read-write + + + HCIM + Host channels interrupt + mask + 25 + 1 + read-write + + + PTXFEM + Periodic TxFIFO empty mask + 26 + 1 + read-write + + + CIDSCHGM + Connector ID status change + mask + 28 + 1 + read-write + + + DISCINT + Disconnect detected interrupt + mask + 29 + 1 + read-write + + + SRQIM + Session request/new session detected + interrupt mask + 30 + 1 + read-write + + + WUIM + Resume/remote wakeup detected interrupt + mask + 31 + 1 + read-write + + + + + GRXSTSR_Device + GRXSTSR_Device + OTG_FS Receive status debug read(Device + mode) + 0x1C + 0x20 + read-only + 0x00000000 + + + EPNUM + Endpoint number + 0 + 4 + + + BCNT + Byte count + 4 + 11 + + + DPID + Data PID + 15 + 2 + + + PKTSTS + Packet status + 17 + 4 + + + FRMNUM + Frame number + 21 + 4 + + + + + GRXSTSR_Host + GRXSTSR_Host + OTG status debug read (host mode) + GRXSTSR_Device + 0x1C + 0x20 + read-only + 0x00000000 + + + CHNUM + Channel number + 0 + 4 + + + BCNT + Byte count + 4 + 11 + + + DPID + Data PID + 15 + 2 + + + PKTSTS + Packet status + 17 + 4 + + + + + GRXFSIZ + GRXFSIZ + OTG_FS Receive FIFO size register + (OTG_FS_GRXFSIZ) + 0x24 + 0x20 + read-write + 0x00000200 + + + RXFD + RxFIFO depth + 0 + 16 + + + + + DIEPTXF0 + DIEPTXF0 + OTG_FS non-periodic transmit FIFO size + register (Device mode) + 0x28 + 0x20 + read-write + 0x00000200 + + + TX0FSA + Endpoint 0 transmit RAM start + address + 0 + 16 + + + TX0FD + Endpoint 0 TxFIFO depth + 16 + 16 + + + + + HNPTXFSIZ + HNPTXFSIZ + OTG_FS non-periodic transmit FIFO size + register (Host mode) + DIEPTXF0 + 0x28 + 0x20 + read-write + 0x00000200 + + + NPTXFSA + Non-periodic transmit RAM start + address + 0 + 16 + + + NPTXFD + Non-periodic TxFIFO depth + 16 + 16 + + + + + GNPTXSTS + GNPTXSTS + OTG_FS non-periodic transmit FIFO/queue + status register (OTG_FS_GNPTXSTS) + 0x2C + 0x20 + read-only + 0x00080200 + + + NPTXFSAV + Non-periodic TxFIFO space + available + 0 + 16 + + + NPTQXSAV + Non-periodic transmit request queue + space available + 16 + 8 + + + NPTXQTOP + Top of the non-periodic transmit request + queue + 24 + 7 + + + + + GCCFG + GCCFG + OTG_FS general core configuration register + (OTG_FS_GCCFG) + 0x38 + 0x20 + read-write + 0x00000000 + + + PWRDWN + Power down + 16 + 1 + + + VBUSASEN + Enable the VBUS sensing + device + 18 + 1 + + + VBUSBSEN + Enable the VBUS sensing + device + 19 + 1 + + + SOFOUTEN + SOF output enable + 20 + 1 + + + NOVBUSSENS + Vbus sensing disable option + 21 + 1 + + + + + CID + CID + core ID register + 0x3C + 0x20 + read-write + 0x00001000 + + + PRODUCT_ID + Product ID field + 0 + 32 + + + + + HPTXFSIZ + HPTXFSIZ + OTG_FS Host periodic transmit FIFO size + register (OTG_FS_HPTXFSIZ) + 0x100 + 0x20 + read-write + 0x02000600 + + + PTXSA + Host periodic TxFIFO start + address + 0 + 16 + + + PTXFSIZ + Host periodic TxFIFO depth + 16 + 16 + + + + + 3 + 0x4 + 1-3 + DIEPTXF%s + DIEPTXF1 + OTF_FS device IN endpoint transmit FIFO size register + 0x104 + 0x20 + read-write + 0x02000400 + + + INEPTXSA + IN endpoint FIFO2 transmit RAM start + address + 0 + 16 + + + INEPTXFD + IN endpoint TxFIFO depth + 16 + 16 + + + + + GRXSTSP_Device + OTG status read and pop (device mode) + 0x20 + 0x20 + read-only + 0x00000000 + + + FRMNUM + Frame number + 21 + 4 + + + PKTSTS + Packet status + 17 + 4 + + + DPID + Data PID + 15 + 2 + + + BCNT + Byte count + 4 + 11 + + + EPNUM + Endpoint number + 0 + 4 + + + + + GRXSTSP_Host + OTG status read and pop (host mode) + GRXSTSP_Device + 0x20 + 0x20 + read-only + 0x00000000 + + + PKTSTS + Packet status + 17 + 4 + + + DPID + Data PID + 15 + 2 + + + BCNT + Byte count + 4 + 11 + + + CHNUM + Channel number + 0 + 4 + + + + + + + OTG_FS_HOST + USB on the go full speed + USB_OTG_FS + 0x50000400 + + 0x0 + 0x400 + registers + + + + HCFG + HCFG + OTG_FS host configuration register + (OTG_FS_HCFG) + 0x0 + 0x20 + 0x00000000 + + + FSLSPCS + FS/LS PHY clock select + 0 + 2 + read-write + + + FSLSS + FS- and LS-only support + 2 + 1 + read-write + + + + + HFIR + HFIR + OTG_FS Host frame interval + register + 0x4 + 0x20 + read-write + 0x0000EA60 + + + FRIVL + Frame interval + 0 + 16 + + + + + HFNUM + HFNUM + OTG_FS host frame number/frame time + remaining register (OTG_FS_HFNUM) + 0x8 + 0x20 + read-only + 0x00003FFF + + + FRNUM + Frame number + 0 + 16 + + + FTREM + Frame time remaining + 16 + 16 + + + + + HPTXSTS + HPTXSTS + OTG_FS_Host periodic transmit FIFO/queue + status register (OTG_FS_HPTXSTS) + 0x10 + 0x20 + 0x00080100 + + + PTXFSAVL + Periodic transmit data FIFO space + available + 0 + 16 + read-write + + + PTXQSAV + Periodic transmit request queue space + available + 16 + 8 + read-only + + + PTXQTOP + Top of the periodic transmit request + queue + 24 + 8 + read-only + + + + + HAINT + HAINT + OTG_FS Host all channels interrupt + register + 0x14 + 0x20 + read-only + 0x00000000 + + + HAINT + Channel interrupts + 0 + 16 + + + + + HAINTMSK + HAINTMSK + OTG_FS host all channels interrupt mask + register + 0x18 + 0x20 + read-write + 0x00000000 + + + HAINTM + Channel interrupt mask + 0 + 16 + + + + + HPRT + HPRT + OTG_FS host port control and status register + (OTG_FS_HPRT) + 0x40 + 0x20 + 0x00000000 + + + PCSTS + Port connect status + 0 + 1 + read-only + + + PCDET + Port connect detected + 1 + 1 + read-write + + + PENA + Port enable + 2 + 1 + read-write + + + PENCHNG + Port enable/disable change + 3 + 1 + read-write + + + POCA + Port overcurrent active + 4 + 1 + read-only + + + POCCHNG + Port overcurrent change + 5 + 1 + read-write + + + PRES + Port resume + 6 + 1 + read-write + + + PSUSP + Port suspend + 7 + 1 + read-write + + + PRST + Port reset + 8 + 1 + read-write + + + PLSTS + Port line status + 10 + 2 + read-only + + + PPWR + Port power + 12 + 1 + read-write + + + PTCTL + Port test control + 13 + 4 + read-write + + + PSPD + Port speed + 17 + 2 + read-only + + + + + 8 + 0x20 + 0-7 + HC%s + Host channel + 0x100 + + CHAR + HCCHAR0 + OTG_FS host channel-0 characteristics + register (OTG_FS_HCCHAR0) + 0x0 + 0x20 + read-write + 0x00000000 + + + MPSIZ + Maximum packet size + 0 + 11 + + + EPNUM + Endpoint number + 11 + 4 + + + EPDIR + Endpoint direction + 15 + 1 + + + LSDEV + Low-speed device + 17 + 1 + + + EPTYP + Endpoint type + 18 + 2 + + + MCNT + Multicount + 20 + 2 + + + DAD + Device address + 22 + 7 + + + ODDFRM + Odd frame + 29 + 1 + + + CHDIS + Channel disable + 30 + 1 + + + CHENA + Channel enable + 31 + 1 + + + + + INT + HCINT0 + OTG_FS host channel-0 interrupt register + (OTG_FS_HCINT0) + 0x8 + 0x20 + read-write + 0x00000000 + + + XFRC + Transfer completed + 0 + 1 + + + CHH + Channel halted + 1 + 1 + + + STALL + STALL response received + interrupt + 3 + 1 + + + NAK + NAK response received + interrupt + 4 + 1 + + + ACK + ACK response received/transmitted + interrupt + 5 + 1 + + + TXERR + Transaction error + 7 + 1 + + + BBERR + Babble error + 8 + 1 + + + FRMOR + Frame overrun + 9 + 1 + + + DTERR + Data toggle error + 10 + 1 + + + + + INTMSK + HCINTMSK0 + OTG_FS host channel-0 mask register + (OTG_FS_HCINTMSK0) + 0xC + 0x20 + read-write + 0x00000000 + + + XFRCM + Transfer completed mask + 0 + 1 + + + CHHM + Channel halted mask + 1 + 1 + + + STALLM + STALL response received interrupt + mask + 3 + 1 + + + NAKM + NAK response received interrupt + mask + 4 + 1 + + + ACKM + ACK response received/transmitted + interrupt mask + 5 + 1 + + + NYET + response received interrupt + mask + 6 + 1 + + + TXERRM + Transaction error mask + 7 + 1 + + + BBERRM + Babble error mask + 8 + 1 + + + FRMORM + Frame overrun mask + 9 + 1 + + + DTERRM + Data toggle error mask + 10 + 1 + + + + + TSIZ + HCTSIZ0 + OTG_FS host channel-0 transfer size + register + 0x10 + 0x20 + read-write + 0x00000000 + + + XFRSIZ + Transfer size + 0 + 19 + + + PKTCNT + Packet count + 19 + 10 + + + DPID + Data PID + 29 + 2 + + + + + + + + OTG_FS_PWRCLK + USB on the go full speed + USB_OTG_FS + 0x50000E00 + + 0x0 + 0x400 + registers + + + + PCGCCTL + PCGCCTL + OTG_FS power and clock gating control + register + 0x0 + 0x20 + read-write + 0x00000000 + + + STPPCLK + Stop PHY clock + 0 + 1 + + + GATEHCLK + Gate HCLK + 1 + 1 + + + PHYSUSP + PHY Suspended + 4 + 1 + + + + + + + PWR + Power control + PWR + 0x40007000 + + 0x0 + 0x400 + registers + + + + CR + CR + power control register + 0x0 + 0x20 + read-write + 0x00000000 + + + VOS + Regulator voltage scaling output + selection + 14 + 2 + + + ADCDC1 + ADCDC1 + 13 + 1 + + + FPDS + Flash power down in Stop + mode + 9 + 1 + + + DBP + Disable backup domain write + protection + 8 + 1 + + + PLS + PVD level selection + 5 + 3 + + + PVDE + Power voltage detector + enable + 4 + 1 + + + CSBF + Clear standby flag + 3 + 1 + + + CWUF + Clear wakeup flag + 2 + 1 + + + PDDS + Power down deepsleep + 1 + 1 + + + LPDS + Low-power deep sleep + 0 + 1 + + + + + CSR + CSR + power control/status register + 0x4 + 0x20 + 0x00000000 + + + WUF + Wakeup flag + 0 + 1 + read-only + + + SBF + Standby flag + 1 + 1 + read-only + + + PVDO + PVD output + 2 + 1 + read-only + + + BRR + Backup regulator ready + 3 + 1 + read-only + + + EWUP + Enable WKUP pin + 8 + 1 + read-write + + + BRE + Backup regulator enable + 9 + 1 + read-write + + + VOSRDY + Regulator voltage scaling output + selection ready bit + 14 + 1 + read-write + + + + + + + RCC + Reset and clock control + RCC + 0x40023800 + + 0x0 + 0x400 + registers + + + I2C1_EV + I2C1 event interrupt + 31 + + + I2C1_ER + I2C1 error interrupt + 32 + + + + CR + CR + clock control register + 0x0 + 0x20 + 0x00000083 + + + PLLI2SRDY + PLLI2S clock ready flag + 27 + 1 + read-only + + + + PLLI2SON + PLLI2S enable + 26 + 1 + read-write + + + + PLLRDY + Main PLL (PLL) clock ready + flag + 25 + 1 + read-only + + + + PLLON + Main PLL (PLL) enable + 24 + 1 + read-write + + + + CSSON + Clock security system + enable + 19 + 1 + read-write + + CSSON + read-write + + Off + Clock security system disabled (clock detector OFF) + 0 + + + On + Clock security system enable (clock detector ON if the HSE is ready, OFF if not) + 1 + + + + + HSEBYP + HSE clock bypass + 18 + 1 + read-write + + HSEBYP + read-write + + NotBypassed + HSE crystal oscillator not bypassed + 0 + + + Bypassed + HSE crystal oscillator bypassed with external clock + 1 + + + + + HSERDY + HSE clock ready flag + 17 + 1 + read-only + + + + HSEON + HSE clock enable + 16 + 1 + read-write + + + + HSICAL + Internal high-speed clock + calibration + 8 + 8 + read-only + + + 0 + 255 + + + + + HSITRIM + Internal high-speed clock + trimming + 3 + 5 + read-write + + + 0 + 31 + + + + + HSIRDY + Internal high-speed clock ready + flag + 1 + 1 + read-only + + HSIRDYR + read + + NotReady + Clock not ready + 0 + + + Ready + Clock ready + 1 + + + + + HSION + Internal high-speed clock + enable + 0 + 1 + read-write + + HSION + read-write + + Off + Clock Off + 0 + + + On + Clock On + 1 + + + + + + + PLLCFGR + PLLCFGR + PLL configuration register + 0x4 + 0x20 + read-write + 0x24003010 + + + PLLSRC + Main PLL(PLL) and audio PLL (PLLI2S) + entry clock source + 22 + 1 + + PLLSRC + read-write + + HSI + HSI clock selected as PLL and PLLI2S clock entry + 0 + + + HSE + HSE oscillator clock selected as PLL and PLLI2S clock entry + 1 + + + + + PLLM + Division factor for the main PLL (PLL) + and audio PLL (PLLI2S) input clock + 0 + 6 + + + 2 + 63 + + + + + PLLN + Main PLL (PLL) multiplication factor for + VCO + 6 + 9 + + + 50 + 432 + + + + + PLLP + Main PLL (PLL) division factor for main + system clock + 16 + 2 + + PLLP + read-write + + Div2 + PLLP=2 + 0 + + + Div4 + PLLP=4 + 1 + + + Div6 + PLLP=6 + 2 + + + Div8 + PLLP=8 + 3 + + + + + PLLQ + Main PLL (PLL) division factor for USB + OTG FS, SDIO and random number generator + clocks + 24 + 4 + + + 2 + 15 + + + + + + + CFGR + CFGR + clock configuration register + 0x8 + 0x20 + 0x00000000 + + + MCO2 + Microcontroller clock output + 2 + 30 + 2 + read-write + + MCO2 + read-write + + SYSCLK + System clock (SYSCLK) selected + 0 + + + PLLI2S + PLLI2S clock selected + 1 + + + HSE + HSE oscillator clock selected + 2 + + + PLL + PLL clock selected + 3 + + + + + MCO2PRE + MCO2 prescaler + 27 + 3 + read-write + + + + MCO1PRE + MCO1 prescaler + 24 + 3 + read-write + + MCO1PRE + read-write + + Div1 + No division + 0 + + + Div2 + Division by 2 + 4 + + + Div3 + Division by 3 + 5 + + + Div4 + Division by 4 + 6 + + + Div5 + Division by 5 + 7 + + + + + I2SSRC + I2S clock selection + 23 + 1 + read-write + + I2SSRC + read-write + + PLLI2S + PLLI2S clock used as I2S clock source + 0 + + + CKIN + External clock mapped on the I2S_CKIN pin used as I2S clock source + 1 + + + + + MCO1 + Microcontroller clock output + 1 + 21 + 2 + read-write + + MCO1 + read-write + + HSI + HSI clock selected + 0 + + + LSE + LSE oscillator selected + 1 + + + HSE + HSE oscillator clock selected + 2 + + + PLL + PLL clock selected + 3 + + + + + RTCPRE + HSE division factor for RTC + clock + 16 + 5 + read-write + + + 0 + 31 + + + + + PPRE2 + APB high-speed prescaler + (APB2) + 13 + 3 + read-write + + + + PPRE1 + APB Low speed prescaler + (APB1) + 10 + 3 + read-write + + PPRE1 + read-write + + Div1 + HCLK not divided + 0 + + + Div2 + HCLK divided by 2 + 4 + + + Div4 + HCLK divided by 4 + 5 + + + Div8 + HCLK divided by 8 + 6 + + + Div16 + HCLK divided by 16 + 7 + + + + + HPRE + AHB prescaler + 4 + 4 + read-write + + HPRE + read-write + + Div1 + SYSCLK not divided + 0 + + + Div2 + SYSCLK divided by 2 + 8 + + + Div4 + SYSCLK divided by 4 + 9 + + + Div8 + SYSCLK divided by 8 + 10 + + + Div16 + SYSCLK divided by 16 + 11 + + + Div64 + SYSCLK divided by 64 + 12 + + + Div128 + SYSCLK divided by 128 + 13 + + + Div256 + SYSCLK divided by 256 + 14 + + + Div512 + SYSCLK divided by 512 + 15 + + + + + SW + System clock switch + 0 + 2 + + SW + read-write + + HSI + HSI selected as system clock + 0 + + + HSE + HSE selected as system clock + 1 + + + PLL + PLL selected as system clock + 2 + + + + + SWS + System clock switch status + 2 + 2 + + SWSR + read + + HSI + HSI oscillator used as system clock + 0 + + + HSE + HSE oscillator used as system clock + 1 + + + PLL + PLL used as system clock + 2 + + + + + + + CIR + CIR + clock interrupt register + 0xC + 0x20 + 0x00000000 + + + CSSC + Clock security system interrupt + clear + 23 + 1 + write-only + + CSSCW + write + + Clear + Clear CSSF flag + 1 + + + + + PLLI2SRDYC + PLLI2S ready interrupt + clear + 21 + 1 + write-only + + + + PLLRDYC + Main PLL(PLL) ready interrupt + clear + 20 + 1 + write-only + + + + HSERDYC + HSE ready interrupt clear + 19 + 1 + write-only + + + + HSIRDYC + HSI ready interrupt clear + 18 + 1 + write-only + + + + LSERDYC + LSE ready interrupt clear + 17 + 1 + write-only + + + + LSIRDYC + LSI ready interrupt clear + 16 + 1 + write-only + + LSIRDYCW + write + + Clear + Clear interrupt flag + 1 + + + + + PLLI2SRDYIE + PLLI2S ready interrupt + enable + 13 + 1 + read-write + + + + PLLRDYIE + Main PLL (PLL) ready interrupt + enable + 12 + 1 + read-write + + + + HSERDYIE + HSE ready interrupt enable + 11 + 1 + read-write + + + + HSIRDYIE + HSI ready interrupt enable + 10 + 1 + read-write + + + + LSERDYIE + LSE ready interrupt enable + 9 + 1 + read-write + + + + LSIRDYIE + LSI ready interrupt enable + 8 + 1 + read-write + + LSIRDYIE + read-write + + Disabled + Interrupt disabled + 0 + + + Enabled + Interrupt enabled + 1 + + + + + CSSF + Clock security system interrupt + flag + 7 + 1 + read-only + + CSSFR + read + + NotInterrupted + No clock security interrupt caused by HSE clock failure + 0 + + + Interrupted + Clock security interrupt caused by HSE clock failure + 1 + + + + + PLLI2SRDYF + PLLI2S ready interrupt + flag + 5 + 1 + read-only + + + + PLLRDYF + Main PLL (PLL) ready interrupt + flag + 4 + 1 + read-only + + + + HSERDYF + HSE ready interrupt flag + 3 + 1 + read-only + + + + HSIRDYF + HSI ready interrupt flag + 2 + 1 + read-only + + + + LSERDYF + LSE ready interrupt flag + 1 + 1 + read-only + + + + LSIRDYF + LSI ready interrupt flag + 0 + 1 + read-only + + LSIRDYFR + read + + NotInterrupted + No clock ready interrupt + 0 + + + Interrupted + Clock ready interrupt + 1 + + + + + + + AHB1RSTR + AHB1RSTR + AHB1 peripheral reset register + 0x10 + 0x20 + read-write + 0x00000000 + + + DMA2RST + DMA2 reset + 22 + 1 + + + + DMA1RST + DMA2 reset + 21 + 1 + + + + CRCRST + CRC reset + 12 + 1 + + + + GPIOHRST + IO port H reset + 7 + 1 + + + + GPIOERST + IO port E reset + 4 + 1 + + + + GPIODRST + IO port D reset + 3 + 1 + + + + GPIOCRST + IO port C reset + 2 + 1 + + + + GPIOBRST + IO port B reset + 1 + 1 + + + + GPIOARST + IO port A reset + 0 + 1 + + GPIOARST + read-write + + Reset + Reset the selected module + 1 + + + + + + + AHB2RSTR + AHB2RSTR + AHB2 peripheral reset register + 0x14 + 0x20 + read-write + 0x00000000 + + + OTGFSRST + USB OTG FS module reset + 7 + 1 + + OTGFSRST + read-write + + Reset + Reset the selected module + 1 + + + + + + + APB1RSTR + APB1RSTR + APB1 peripheral reset register + 0x20 + 0x20 + read-write + 0x00000000 + + + PWRRST + Power interface reset + 28 + 1 + + + + I2C3RST + I2C3 reset + 23 + 1 + + + + I2C2RST + I2C 2 reset + 22 + 1 + + + + I2C1RST + I2C 1 reset + 21 + 1 + + + + USART2RST + USART 2 reset + 17 + 1 + + + + SPI3RST + SPI 3 reset + 15 + 1 + + + + SPI2RST + SPI 2 reset + 14 + 1 + + + + WWDGRST + Window watchdog reset + 11 + 1 + + + + TIM5RST + TIM5 reset + 3 + 1 + + + + TIM4RST + TIM4 reset + 2 + 1 + + + + TIM3RST + TIM3 reset + 1 + 1 + + + + TIM2RST + TIM2 reset + 0 + 1 + + TIM2RST + read-write + + Reset + Reset the selected module + 1 + + + + + + + APB2RSTR + APB2RSTR + APB2 peripheral reset register + 0x24 + 0x20 + read-write + 0x00000000 + + + TIM11RST + TIM11 reset + 18 + 1 + + + + TIM10RST + TIM10 reset + 17 + 1 + + + + TIM9RST + TIM9 reset + 16 + 1 + + + + SYSCFGRST + System configuration controller + reset + 14 + 1 + + + + SPI1RST + SPI 1 reset + 12 + 1 + + + + SDIORST + SDIO reset + 11 + 1 + + + + ADCRST + ADC interface reset (common to all + ADCs) + 8 + 1 + + + + USART6RST + USART6 reset + 5 + 1 + + + + USART1RST + USART1 reset + 4 + 1 + + + + TIM1RST + TIM1 reset + 0 + 1 + + TIM1RST + read-write + + Reset + Reset the selected module + 1 + + + + + SPI4RST + SPI4 reset + 13 + 1 + + + + + + AHB1ENR + AHB1ENR + AHB1 peripheral clock register + 0x30 + 0x20 + read-write + 0x00100000 + + + DMA2EN + DMA2 clock enable + 22 + 1 + + + + DMA1EN + DMA1 clock enable + 21 + 1 + + + + CRCEN + CRC clock enable + 12 + 1 + + + + GPIOHEN + IO port H clock enable + 7 + 1 + + + + GPIOEEN + IO port E clock enable + 4 + 1 + + + + GPIODEN + IO port D clock enable + 3 + 1 + + + + GPIOCEN + IO port C clock enable + 2 + 1 + + + + GPIOBEN + IO port B clock enable + 1 + 1 + + + + GPIOAEN + IO port A clock enable + 0 + 1 + + GPIOAEN + read-write + + Disabled + The selected clock is disabled + 0 + + + Enabled + The selected clock is enabled + 1 + + + + + + + AHB2ENR + AHB2ENR + AHB2 peripheral clock enable + register + 0x34 + 0x20 + read-write + 0x00000000 + + + OTGFSEN + USB OTG FS clock enable + 7 + 1 + + OTGFSEN + read-write + + Disabled + The selected clock is disabled + 0 + + + Enabled + The selected clock is enabled + 1 + + + + + + + APB1ENR + APB1ENR + APB1 peripheral clock enable + register + 0x40 + 0x20 + read-write + 0x00000000 + + + PWREN + Power interface clock + enable + 28 + 1 + + + + I2C3EN + I2C3 clock enable + 23 + 1 + + + + I2C2EN + I2C2 clock enable + 22 + 1 + + + + I2C1EN + I2C1 clock enable + 21 + 1 + + + + USART2EN + USART 2 clock enable + 17 + 1 + + + + SPI3EN + SPI3 clock enable + 15 + 1 + + + + SPI2EN + SPI2 clock enable + 14 + 1 + + + + WWDGEN + Window watchdog clock + enable + 11 + 1 + + + + TIM5EN + TIM5 clock enable + 3 + 1 + + + + TIM4EN + TIM4 clock enable + 2 + 1 + + + + TIM3EN + TIM3 clock enable + 1 + 1 + + + + TIM2EN + TIM2 clock enable + 0 + 1 + + TIM2EN + read-write + + Disabled + The selected clock is disabled + 0 + + + Enabled + The selected clock is enabled + 1 + + + + + + + APB2ENR + APB2ENR + APB2 peripheral clock enable + register + 0x44 + 0x20 + read-write + 0x00000000 + + + TIM11EN + TIM11 clock enable + 18 + 1 + + + + TIM10EN + TIM10 clock enable + 17 + 1 + + + + TIM9EN + TIM9 clock enable + 16 + 1 + + + + SYSCFGEN + System configuration controller clock + enable + 14 + 1 + + + + SPI1EN + SPI1 clock enable + 12 + 1 + + + + SDIOEN + SDIO clock enable + 11 + 1 + + + + ADC1EN + ADC1 clock enable + 8 + 1 + + + + USART6EN + USART6 clock enable + 5 + 1 + + + + USART1EN + USART1 clock enable + 4 + 1 + + + + TIM1EN + TIM1 clock enable + 0 + 1 + + TIM1EN + read-write + + Disabled + The selected clock is disabled + 0 + + + Enabled + The selected clock is enabled + 1 + + + + + SPI4EN + SPI4 clock enable + 13 + 1 + + + + + + AHB1LPENR + AHB1LPENR + AHB1 peripheral clock enable in low power + mode register + 0x50 + 0x20 + read-write + 0x7E6791FF + + + DMA2LPEN + DMA2 clock enable during Sleep + mode + 22 + 1 + + + + DMA1LPEN + DMA1 clock enable during Sleep + mode + 21 + 1 + + + + SRAM1LPEN + SRAM 1interface clock enable during + Sleep mode + 16 + 1 + + + + FLITFLPEN + Flash interface clock enable during + Sleep mode + 15 + 1 + + + + CRCLPEN + CRC clock enable during Sleep + mode + 12 + 1 + + + + GPIOHLPEN + IO port H clock enable during Sleep + mode + 7 + 1 + + + + GPIOELPEN + IO port E clock enable during Sleep + mode + 4 + 1 + + + + GPIODLPEN + IO port D clock enable during Sleep + mode + 3 + 1 + + + + GPIOCLPEN + IO port C clock enable during Sleep + mode + 2 + 1 + + + + GPIOBLPEN + IO port B clock enable during Sleep + mode + 1 + 1 + + + + GPIOALPEN + IO port A clock enable during sleep + mode + 0 + 1 + + GPIOALPEN + read-write + + DisabledInSleep + Selected module is disabled during Sleep mode + 0 + + + EnabledInSleep + Selected module is enabled during Sleep mode + 1 + + + + + + + AHB2LPENR + AHB2LPENR + AHB2 peripheral clock enable in low power + mode register + 0x54 + 0x20 + read-write + 0x000000F1 + + + OTGFSLPEN + USB OTG FS clock enable during Sleep + mode + 7 + 1 + + OTGFSLPEN + read-write + + DisabledInSleep + Selected module is disabled during Sleep mode + 0 + + + EnabledInSleep + Selected module is enabled during Sleep mode + 1 + + + + + + + APB1LPENR + APB1LPENR + APB1 peripheral clock enable in low power + mode register + 0x60 + 0x20 + read-write + 0x36FEC9FF + + + PWRLPEN + Power interface clock enable during + Sleep mode + 28 + 1 + + + + I2C3LPEN + I2C3 clock enable during Sleep + mode + 23 + 1 + + + + I2C2LPEN + I2C2 clock enable during Sleep + mode + 22 + 1 + + + + I2C1LPEN + I2C1 clock enable during Sleep + mode + 21 + 1 + + + + USART2LPEN + USART2 clock enable during Sleep + mode + 17 + 1 + + + + SPI3LPEN + SPI3 clock enable during Sleep + mode + 15 + 1 + + + + SPI2LPEN + SPI2 clock enable during Sleep + mode + 14 + 1 + + + + WWDGLPEN + Window watchdog clock enable during + Sleep mode + 11 + 1 + + + + TIM5LPEN + TIM5 clock enable during Sleep + mode + 3 + 1 + + + + TIM4LPEN + TIM4 clock enable during Sleep + mode + 2 + 1 + + + + TIM3LPEN + TIM3 clock enable during Sleep + mode + 1 + 1 + + + + TIM2LPEN + TIM2 clock enable during Sleep + mode + 0 + 1 + + TIM2LPEN + read-write + + DisabledInSleep + Selected module is disabled during Sleep mode + 0 + + + EnabledInSleep + Selected module is enabled during Sleep mode + 1 + + + + + + + APB2LPENR + APB2LPENR + APB2 peripheral clock enabled in low power + mode register + 0x64 + 0x20 + read-write + 0x00075F33 + + + TIM11LPEN + TIM11 clock enable during Sleep + mode + 18 + 1 + + + + TIM10LPEN + TIM10 clock enable during Sleep + mode + 17 + 1 + + + + TIM9LPEN + TIM9 clock enable during sleep + mode + 16 + 1 + + + + SYSCFGLPEN + System configuration controller clock + enable during Sleep mode + 14 + 1 + + + + SPI1LPEN + SPI 1 clock enable during Sleep + mode + 12 + 1 + + + + SDIOLPEN + SDIO clock enable during Sleep + mode + 11 + 1 + + + + ADC1LPEN + ADC1 clock enable during Sleep + mode + 8 + 1 + + + + USART6LPEN + USART6 clock enable during Sleep + mode + 5 + 1 + + + + USART1LPEN + USART1 clock enable during Sleep + mode + 4 + 1 + + + + TIM1LPEN + TIM1 clock enable during Sleep + mode + 0 + 1 + + TIM1LPEN + read-write + + DisabledInSleep + Selected module is disabled during Sleep mode + 0 + + + EnabledInSleep + Selected module is enabled during Sleep mode + 1 + + + + + SPI4LPEN + SPI4 clock enable during Sleep mode + 13 + 1 + + + + + + BDCR + BDCR + Backup domain control register + 0x70 + 0x20 + 0x00000000 + + + BDRST + Backup domain software + reset + 16 + 1 + read-write + + BDRST + read-write + + Disabled + Reset not activated + 0 + + + Enabled + Reset the entire RTC domain + 1 + + + + + RTCEN + RTC clock enable + 15 + 1 + read-write + + RTCEN + read-write + + Disabled + RTC clock disabled + 0 + + + Enabled + RTC clock enabled + 1 + + + + + LSEBYP + External low-speed oscillator + bypass + 2 + 1 + read-write + + LSEBYP + read-write + + NotBypassed + LSE crystal oscillator not bypassed + 0 + + + Bypassed + LSE crystal oscillator bypassed with external clock + 1 + + + + + LSERDY + External low-speed oscillator + ready + 1 + 1 + read-only + + LSERDYR + read + + NotReady + LSE oscillator not ready + 0 + + + Ready + LSE oscillator ready + 1 + + + + + LSEON + External low-speed oscillator + enable + 0 + 1 + read-write + + LSEON + read-write + + Off + LSE oscillator Off + 0 + + + On + LSE oscillator On + 1 + + + + + RTCSEL + RTC clock source selection + 8 + 2 + + RTCSEL + read-write + + NoClock + No clock + 0 + + + LSE + LSE oscillator clock used as RTC clock + 1 + + + LSI + LSI oscillator clock used as RTC clock + 2 + + + HSE + HSE oscillator clock divided by a prescaler used as RTC clock + 3 + + + + + + + CSR + CSR + clock control & status + register + 0x74 + 0x20 + 0x0E000000 + + + LPWRRSTF + Low-power reset flag + 31 + 1 + read-write + + + + WWDGRSTF + Window watchdog reset flag + 30 + 1 + read-write + + + + WDGRSTF + Independent watchdog reset + flag + 29 + 1 + read-write + + + + SFTRSTF + Software reset flag + 28 + 1 + read-write + + + + PORRSTF + POR/PDR reset flag + 27 + 1 + read-write + + + + PADRSTF + PIN reset flag + 26 + 1 + read-write + + + + BORRSTF + BOR reset flag + 25 + 1 + read-write + + BORRSTFR + read + + NoReset + No reset has occured + 0 + + + Reset + A reset has occured + 1 + + + + + RMVF + Remove reset flag + 24 + 1 + read-write + + RMVFW + write + + Clear + Clears the reset flag + 1 + + + + + LSIRDY + Internal low-speed oscillator + ready + 1 + 1 + read-only + + LSIRDYR + read + + NotReady + LSI oscillator not ready + 0 + + + Ready + LSI oscillator ready + 1 + + + + + LSION + Internal low-speed oscillator + enable + 0 + 1 + read-write + + LSION + read-write + + Off + LSI oscillator Off + 0 + + + On + LSI oscillator On + 1 + + + + + + + SSCGR + SSCGR + spread spectrum clock generation + register + 0x80 + 0x20 + read-write + 0x00000000 + + + SSCGEN + Spread spectrum modulation + enable + 31 + 1 + + SSCGEN + read-write + + Disabled + Spread spectrum modulation disabled + 0 + + + Enabled + Spread spectrum modulation enabled + 1 + + + + + SPREADSEL + Spread Select + 30 + 1 + + SPREADSEL + read-write + + Center + Center spread + 0 + + + Down + Down spread + 1 + + + + + INCSTEP + Incrementation step + 13 + 15 + + + 0 + 32767 + + + + + MODPER + Modulation period + 0 + 13 + + + 0 + 8191 + + + + + + + PLLI2SCFGR + PLLI2SCFGR + PLLI2S configuration register + 0x84 + 0x20 + read-write + 0x20003000 + + + PLLI2SR + PLLI2S division factor for I2S + clocks + 28 + 3 + + + 2 + 7 + + + + + PLLI2SN + PLLI2S multiplication factor for + VCO + 6 + 9 + + + 50 + 432 + + + + + + + DCKCFGR + RCC Dedicated Clock Configuration Register + 0x8C + 0x20 + read-write + 0x00000000 + + + TIMPRE + Timers clocks prescalers selection + 24 + 1 + + TIMPRE + read-write + + Mul1Or2 + If the APB prescaler is configured 1, TIMxCLK = PCLKx. Otherwise, TIMxCLK = 2xPCLKx + 0 + + + Mul1Or4 + If the APB prescaler is configured 1, 2 or 4, TIMxCLK = HCLK. Otherwise, TIMxCLK = 4xPCLKx + 1 + + + + + + + + + RTC + Real-time clock + RTC + 0x40002800 + + 0x0 + 0x400 + registers + + + I2C2_EV + I2C2 event interrupt + 33 + + + I2C2_ER + I2C2 error interrupt + 34 + + + + TR + TR + time register + 0x0 + 0x20 + read-write + 0x00000000 + + + PM + AM/PM notation + 22 + 1 + + PM + read-write + + AM + AM or 24-hour format + 0 + + + PM + PM + 1 + + + + + HT + Hour tens in BCD format + 20 + 2 + + + 0 + 3 + + + + + HU + Hour units in BCD format + 16 + 4 + + + 0 + 15 + + + + + MNT + Minute tens in BCD format + 12 + 3 + + + 0 + 7 + + + + + MNU + Minute units in BCD format + 8 + 4 + + + 0 + 15 + + + + + ST + Second tens in BCD format + 4 + 3 + + + 0 + 7 + + + + + SU + Second units in BCD format + 0 + 4 + + + 0 + 15 + + + + + + + DR + DR + date register + 0x4 + 0x20 + read-write + 0x00002101 + + + YT + Year tens in BCD format + 20 + 4 + + + 0 + 15 + + + + + YU + Year units in BCD format + 16 + 4 + + + 0 + 15 + + + + + WDU + Week day units + 13 + 3 + + + 1 + 7 + + + + + MT + Month tens in BCD format + 12 + 1 + + MT + read-write + + Zero + Month tens is 0 + 0 + + + One + Month tens is 1 + 1 + + + + + MU + Month units in BCD format + 8 + 4 + + + 0 + 15 + + + + + DT + Date tens in BCD format + 4 + 2 + + + 0 + 3 + + + + + DU + Date units in BCD format + 0 + 4 + + + 0 + 15 + + + + + + + CR + CR + control register + 0x8 + 0x20 + read-write + 0x00000000 + + + COE + Calibration output enable + 23 + 1 + + COE + read-write + + Disabled + Calibration output disabled + 0 + + + Enabled + Calibration output enabled + 1 + + + + + OSEL + Output selection + 21 + 2 + + OSEL + read-write + + Disabled + Output disabled + 0 + + + AlarmA + Alarm A output enabled + 1 + + + AlarmB + Alarm B output enabled + 2 + + + Wakeup + Wakeup output enabled + 3 + + + + + POL + Output polarity + 20 + 1 + + POL + read-write + + High + The pin is high when ALRAF/ALRBF/WUTF is asserted (depending on OSEL[1:0]) + 0 + + + Low + The pin is low when ALRAF/ALRBF/WUTF is asserted (depending on OSEL[1:0]) + 1 + + + + + COSEL + Calibration Output + selection + 19 + 1 + + COSEL + read-write + + CalFreq_512Hz + Calibration output is 512 Hz (with default prescaler setting) + 0 + + + CalFreq_1Hz + Calibration output is 1 Hz (with default prescaler setting) + 1 + + + + + BKP + Backup + 18 + 1 + + BKP + read-write + + DST_Not_Changed + Daylight Saving Time change has not been performed + 0 + + + DST_Changed + Daylight Saving Time change has been performed + 1 + + + + + SUB1H + Subtract 1 hour (winter time + change) + 17 + 1 + + SUB1HW + write + + Sub1 + Subtracts 1 hour to the current time. This can be used for winter time change outside initialization mode + 1 + + + + + ADD1H + Add 1 hour (summer time + change) + 16 + 1 + + ADD1HW + write + + Add1 + Adds 1 hour to the current time. This can be used for summer time change outside initialization mode + 1 + + + + + TSIE + Time-stamp interrupt + enable + 15 + 1 + + TSIE + read-write + + Disabled + Time-stamp Interrupt disabled + 0 + + + Enabled + Time-stamp Interrupt enabled + 1 + + + + + WUTIE + Wakeup timer interrupt + enable + 14 + 1 + + WUTIE + read-write + + Disabled + Wakeup timer interrupt disabled + 0 + + + Enabled + Wakeup timer interrupt enabled + 1 + + + + + ALRBIE + Alarm B interrupt enable + 13 + 1 + + ALRBIE + read-write + + Disabled + Alarm B Interrupt disabled + 0 + + + Enabled + Alarm B Interrupt enabled + 1 + + + + + ALRAIE + Alarm A interrupt enable + 12 + 1 + + ALRAIE + read-write + + Disabled + Alarm A interrupt disabled + 0 + + + Enabled + Alarm A interrupt enabled + 1 + + + + + TSE + Time stamp enable + 11 + 1 + + TSE + read-write + + Disabled + Timestamp disabled + 0 + + + Enabled + Timestamp enabled + 1 + + + + + WUTE + Wakeup timer enable + 10 + 1 + + WUTE + read-write + + Disabled + Wakeup timer disabled + 0 + + + Enabled + Wakeup timer enabled + 1 + + + + + ALRBE + Alarm B enable + 9 + 1 + + ALRBE + read-write + + Disabled + Alarm B disabled + 0 + + + Enabled + Alarm B enabled + 1 + + + + + ALRAE + Alarm A enable + 8 + 1 + + ALRAE + read-write + + Disabled + Alarm A disabled + 0 + + + Enabled + Alarm A enabled + 1 + + + + + DCE + Coarse digital calibration + enable + 7 + 1 + + + FMT + Hour format + 6 + 1 + + FMT + read-write + + Twenty_Four_Hour + 24 hour/day format + 0 + + + AM_PM + AM/PM hour format + 1 + + + + + BYPSHAD + Bypass the shadow + registers + 5 + 1 + + BYPSHAD + read-write + + ShadowReg + Calendar values (when reading from RTC_SSR, RTC_TR, and RTC_DR) are taken from the shadow registers, which are updated once every two RTCCLK cycles + 0 + + + BypassShadowReg + Calendar values (when reading from RTC_SSR, RTC_TR, and RTC_DR) are taken directly from the calendar counters + 1 + + + + + REFCKON + Reference clock detection enable (50 or + 60 Hz) + 4 + 1 + + REFCKON + read-write + + Disabled + RTC_REFIN detection disabled + 0 + + + Enabled + RTC_REFIN detection enabled + 1 + + + + + TSEDGE + Time-stamp event active + edge + 3 + 1 + + TSEDGE + read-write + + RisingEdge + RTC_TS input rising edge generates a time-stamp event + 0 + + + FallingEdge + RTC_TS input falling edge generates a time-stamp event + 1 + + + + + WUCKSEL + Wakeup clock selection + 0 + 3 + + WUCKSEL + read-write + + Div16 + RTC/16 clock is selected + 0 + + + Div8 + RTC/8 clock is selected + 1 + + + Div4 + RTC/4 clock is selected + 2 + + + Div2 + RTC/2 clock is selected + 3 + + + ClockSpare + ck_spre (usually 1 Hz) clock is selected + 4 + + + ClockSpareWithOffset + ck_spre (usually 1 Hz) clock is selected and 2^16 is added to the WUT counter value + 6 + + + + + + + ISR + ISR + initialization and status + register + 0xC + 0x20 + 0x00000007 + + + ALRAWF + Alarm A write flag + 0 + 1 + read-only + + ALRAWFR + read + + UpdateNotAllowed + Alarm update not allowed + 0 + + + UpdateAllowed + Alarm update allowed + 1 + + + + + ALRBWF + Alarm B write flag + 1 + 1 + read-only + + + + WUTWF + Wakeup timer write flag + 2 + 1 + read-only + + WUTWFR + read + + UpdateNotAllowed + Wakeup timer configuration update not allowed + 0 + + + UpdateAllowed + Wakeup timer configuration update allowed + 1 + + + + + SHPF + Shift operation pending + 3 + 1 + read-write + + SHPFR + read + + NoShiftPending + No shift operation is pending + 0 + + + ShiftPending + A shift operation is pending + 1 + + + + + INITS + Initialization status flag + 4 + 1 + read-only + + INITSR + read + + NotInitalized + Calendar has not been initialized + 0 + + + Initalized + Calendar has been initialized + 1 + + + + + RSF + Registers synchronization + flag + 5 + 1 + read-write + zeroToClear + + RSFR + read + + NotSynced + Calendar shadow registers not yet synchronized + 0 + + + Synced + Calendar shadow registers synchronized + 1 + + + + RSFW + write + + Clear + This flag is cleared by software by writing 0 + 0 + + + + + INITF + Initialization flag + 6 + 1 + read-only + + INITFR + read + + NotAllowed + Calendar registers update is not allowed + 0 + + + Allowed + Calendar registers update is allowed + 1 + + + + + INIT + Initialization mode + 7 + 1 + read-write + + INIT + read-write + + FreeRunningMode + Free running mode + 0 + + + InitMode + Initialization mode used to program time and date register (RTC_TR and RTC_DR), and prescaler register (RTC_PRER). Counters are stopped and start counting from the new value when INIT is reset. + 1 + + + + + ALRAF + Alarm A flag + 8 + 1 + read-write + zeroToClear + + ALRAFR + read + + Match + This flag is set by hardware when the time/date registers (RTC_TR and RTC_DR) match the Alarm A register (RTC_ALRMAR) + 1 + + + + ALRAFW + write + + Clear + This flag is cleared by software by writing 0 + 0 + + + + + ALRBF + Alarm B flag + 9 + 1 + read-write + zeroToClear + + ALRBFR + read + + Match + This flag is set by hardware when the time/date registers (RTC_TR and RTC_DR) match the Alarm B register (RTC_ALRMBR) + 1 + + + + ALRBFW + write + + Clear + This flag is cleared by software by writing 0 + 0 + + + + + WUTF + Wakeup timer flag + 10 + 1 + read-write + zeroToClear + + WUTFR + read + + Zero + This flag is set by hardware when the wakeup auto-reload counter reaches 0 + 1 + + + + WUTFW + write + + Clear + This flag is cleared by software by writing 0 + 0 + + + + + TSF + Time-stamp flag + 11 + 1 + read-write + zeroToClear + + TSFR + read + + TimestampEvent + This flag is set by hardware when a time-stamp event occurs + 1 + + + + TSFW + write + + Clear + This flag is cleared by software by writing 0 + 0 + + + + + TSOVF + Time-stamp overflow flag + 12 + 1 + read-write + zeroToClear + + TSOVFR + read + + Overflow + This flag is set by hardware when a time-stamp event occurs while TSF is already set + 1 + + + + TSOVFW + write + + Clear + This flag is cleared by software by writing 0 + 0 + + + + + TAMP1F + Tamper detection flag + 13 + 1 + read-write + zeroToClear + + TAMP1FR + read + + Tampered + This flag is set by hardware when a tamper detection event is detected on the RTC_TAMPx input + 1 + + + + TAMP1FW + write + + Clear + Flag cleared by software writing 0 + 0 + + + + + TAMP2F + TAMPER2 detection flag + 14 + 1 + read-write + zeroToClear + + read + + + write + + + + RECALPF + Recalibration pending Flag + 16 + 1 + read-only + + RECALPFR + read + + Pending + The RECALPF status flag is automatically set to 1 when software writes to the RTC_CALR register, indicating that the RTC_CALR register is blocked. When the new calibration settings are taken into account, this bit returns to 0 + 1 + + + + + + + PRER + PRER + prescaler register + 0x10 + 0x20 + read-write + 0x007F00FF + + + PREDIV_A + Asynchronous prescaler + factor + 16 + 7 + + + 0 + 127 + + + + + PREDIV_S + Synchronous prescaler + factor + 0 + 15 + + + 0 + 32767 + + + + + + + WUTR + WUTR + wakeup timer register + 0x14 + 0x20 + read-write + 0x0000FFFF + + + WUT + Wakeup auto-reload value + bits + 0 + 16 + + + 0 + 65535 + + + + + + + CALIBR + CALIBR + calibration register + 0x18 + 0x20 + read-write + 0x00000000 + + + DCS + Digital calibration sign + 7 + 1 + + + DC + Digital calibration + 0 + 5 + + + + + 2 + 0x4 + A,B + ALRM%sR + ALRMAR + Alarm register + 0x1C + 0x20 + read-write + 0x00000000 + + + MSK4 + Alarm date mask + 31 + 1 + + + + WDSEL + Week day selection + 30 + 1 + + WDSEL + read-write + + DateUnits + DU[3:0] represents the date units + 0 + + + WeekDay + DU[3:0] represents the week day. DT[1:0] is don’t care. + 1 + + + + + DT + Date tens in BCD format + 28 + 2 + + + 0 + 3 + + + + + DU + Date units or day in BCD format + 24 + 4 + + + 0 + 15 + + + + + MSK3 + Alarm hours mask + 23 + 1 + + + + PM + AM/PM notation + 22 + 1 + + PM + read-write + + AM + AM or 24-hour format + 0 + + + PM + PM + 1 + + + + + HT + Hour tens in BCD format + 20 + 2 + + + 0 + 3 + + + + + HU + Hour units in BCD format + 16 + 4 + + + 0 + 15 + + + + + MSK2 + Alarm minutes mask + 15 + 1 + + + + MNT + Minute tens in BCD format + 12 + 3 + + + 0 + 7 + + + + + MNU + Minute units in BCD format + 8 + 4 + + + 0 + 15 + + + + + MSK1 + Alarm seconds mask + 7 + 1 + + MSK1 + read-write + + Mask + Alarm set if the date/day match + 0 + + + NotMask + Date/day don’t care in Alarm comparison + 1 + + + + + ST + Second tens in BCD format + 4 + 3 + + + 0 + 7 + + + + + SU + Second units in BCD format + 0 + 4 + + + 0 + 15 + + + + + + + WPR + WPR + write protection register + 0x24 + 0x20 + write-only + 0x00000000 + + + KEY + Write protection key + 0 + 8 + + + 0 + 255 + + + + + + + SSR + SSR + sub second register + 0x28 + 0x20 + read-only + 0x00000000 + + + SS + Sub second value + 0 + 16 + + + 0 + 65535 + + + + + + + SHIFTR + SHIFTR + shift control register + 0x2C + 0x20 + write-only + 0x00000000 + + + ADD1S + Add one second + 31 + 1 + + ADD1SW + write + + Add1 + Add one second to the clock/calendar + 1 + + + + + SUBFS + Subtract a fraction of a + second + 0 + 15 + + + 0 + 32767 + + + + + + + TSTR + TSTR + time stamp time register + 0x30 + + + TSDR + TSDR + time stamp date register + 0x34 + + + TSSSR + TSSSR + timestamp sub second register + 0x38 + + + CALR + CALR + calibration register + 0x3C + 0x20 + read-write + 0x00000000 + + + CALP + Increase frequency of RTC by 488.5 + ppm + 15 + 1 + + CALP + read-write + + NoChange + No RTCCLK pulses are added + 0 + + + IncreaseFreq + One RTCCLK pulse is effectively inserted every 2^11 pulses (frequency increased by 488.5 ppm) + 1 + + + + + CALW8 + Use an 8-second calibration cycle + period + 14 + 1 + + CALW8 + read-write + + Eight_Second + When CALW8 is set to ‘1’, the 8-second calibration cycle period is selected + 1 + + + + + CALW16 + Use a 16-second calibration cycle + period + 13 + 1 + + CALW16 + read-write + + Sixteen_Second + When CALW16 is set to ‘1’, the 16-second calibration cycle period is selected.This bit must not be set to ‘1’ if CALW8=1 + 1 + + + + + CALM + Calibration minus + 0 + 9 + + + 0 + 511 + + + + + + + TAFCR + TAFCR + tamper and alternate function configuration + register + 0x40 + 0x20 + read-write + 0x00000000 + + + ALARMOUTTYPE + AFO_ALARM output type + 18 + 1 + + + TSINSEL + TIMESTAMP mapping + 17 + 1 + + + TAMP1INSEL + TAMPER1 mapping + 16 + 1 + + + TAMPPUDIS + TAMPER pull-up disable + 15 + 1 + + + TAMPPRCH + Tamper precharge duration + 13 + 2 + + + TAMPFLT + Tamper filter count + 11 + 2 + + + TAMPFREQ + Tamper sampling frequency + 8 + 3 + + + TAMPTS + Activate timestamp on tamper detection + event + 7 + 1 + + + TAMP2TRG + Active level for tamper 2 + 4 + 1 + + + TAMP2E + Tamper 2 detection enable + 3 + 1 + + + TAMPIE + Tamper interrupt enable + 2 + 1 + + + TAMP1TRG + Active level for tamper 1 + 1 + 1 + + + TAMP1E + Tamper 1 detection enable + 0 + 1 + + + + + 2 + 0x4 + A,B + ALRM%sSSR + ALRMASSR + Alarm sub-second register + 0x44 + 0x20 + read-write + 0x00000000 + + + MASKSS + Mask the most-significant bits starting + at this bit + 24 + 4 + + + 0 + 15 + + + + + SS + Sub seconds value + 0 + 15 + + + 0 + 32767 + + + + + + + 20 + 0x4 + 0-19 + BKP%sR + BKP0R + backup register + 0x50 + 0x20 + read-write + 0x00000000 + + + BKP + BKP + 0 + 32 + + + 0 + 4294967295 + + + + + + + + + SDIO + Secure digital input/output + interface + SDIO + 0x40012C00 + + 0x0 + 0x400 + registers + + + I2C3_EV + I2C3 event interrupt + 72 + + + I2C3_ER + I2C3 error interrupt + 73 + + + + POWER + POWER + power control register + 0x0 + 0x20 + read-write + 0x00000000 + + + PWRCTRL + PWRCTRL + 0 + 2 + + PWRCTRL + read-write + + PowerOff + Power off + 0 + + + PowerOn + Power on + 3 + + + + + + + CLKCR + CLKCR + SDI clock control register + 0x4 + 0x20 + read-write + 0x00000000 + + + HWFC_EN + HW Flow Control enable + 14 + 1 + + HWFC_EN + read-write + + Disabled + HW Flow Control is disabled + 0 + + + Enabled + HW Flow Control is enabled + 1 + + + + + NEGEDGE + SDIO_CK dephasing selection + bit + 13 + 1 + + NEGEDGE + read-write + + Rising + SDIO_CK generated on the rising edge + 0 + + + Falling + SDIO_CK generated on the falling edge + 1 + + + + + WIDBUS + Wide bus mode enable bit + 11 + 2 + + WIDBUS + read-write + + BusWidth1 + 1 lane wide bus + 0 + + + BusWidth4 + 4 lane wide bus + 1 + + + BusWidth8 + 8 lane wide bus + 2 + + + + + BYPASS + Clock divider bypass enable + bit + 10 + 1 + + BYPASS + read-write + + Disabled + SDIOCLK is divided according to the CLKDIV value before driving the SDIO_CK output signal. + 0 + + + Enabled + SDIOCLK directly drives the SDIO_CK output signal + 1 + + + + + PWRSAV + Power saving configuration + bit + 9 + 1 + + PWRSAV + read-write + + Enabled + SDIO_CK clock is always enabled + 0 + + + Disabled + SDIO_CK is only enabled when the bus is active + 1 + + + + + CLKEN + Clock enable bit + 8 + 1 + + CLKEN + read-write + + Disabled + Disable clock + 0 + + + Enabled + Enable clock + 1 + + + + + CLKDIV + Clock divide factor + 0 + 8 + + + 0 + 255 + + + + + + + ARG + ARG + argument register + 0x8 + 0x20 + read-write + 0x00000000 + + + CMDARG + Command argument + 0 + 32 + + + 0 + 4294967295 + + + + + + + CMD + CMD + command register + 0xC + 0x20 + read-write + 0x00000000 + + + CE_ATACMD + CE-ATA command + 14 + 1 + + CE_ATACMD + read-write + + Disabled + CE-ATA command disabled + 0 + + + Enabled + CE-ATA command enabled + 1 + + + + + nIEN + not Interrupt Enable + 13 + 1 + + nIEN + read-write + + Disabled + Interrupts to the CE-ATA not disabled + 0 + + + Enabled + Interrupt to the CE-ATA are disabled + 1 + + + + + ENCMDcompl + Enable CMD completion + 12 + 1 + + ENCMDcompl + read-write + + Disabled + Command complete signal disabled + 0 + + + Enabled + Command complete signal enabled + 1 + + + + + SDIOSuspend + SD I/O suspend command + 11 + 1 + + SDIOSuspend + read-write + + Disabled + Next command is not a SDIO suspend command + 0 + + + Enabled + Next command send is a SDIO suspend command + 1 + + + + + CPSMEN + Command path state machine (CPSM) Enable + bit + 10 + 1 + + CPSMEN + read-write + + Disabled + Command path state machine disabled + 0 + + + Enabled + Command path state machine enabled + 1 + + + + + WAITPEND + CPSM Waits for ends of data transfer + (CmdPend internal signal). + 9 + 1 + + WAITPEND + read-write + + Disabled + Don't wait for data end + 0 + + + Enabled + Wait for end of data transfer signal before sending command + 1 + + + + + WAITINT + CPSM waits for interrupt + request + 8 + 1 + + WAITINT + read-write + + Disabled + Don't wait for interrupt request + 0 + + + Enabled + Wait for interrupt request + 1 + + + + + WAITRESP + Wait for response bits + 6 + 2 + + WAITRESP + read-write + + NoResponse + No response + 0 + + + ShortResponse + Short response + 1 + + + NoResponse2 + No reponse + 2 + + + LongResponse + Long reponse + 3 + + + + + CMDINDEX + Command index + 0 + 6 + + + 0 + 63 + + + + + + + RESPCMD + RESPCMD + command response register + 0x10 + 0x20 + read-only + 0x00000000 + + + RESPCMD + Response command index + 0 + 6 + + + 0 + 63 + + + + + + + RESP1 + RESP1 + response 1..4 register + 0x14 + 0x20 + read-only + 0x00000000 + + + CARDSTATUS1 + Card Status + 0 + 32 + + + 0 + 4294967295 + + + + + + + RESP2 + RESP2 + response 1..4 register + 0x18 + 0x20 + read-only + 0x00000000 + + + CARDSTATUS2 + Card Status + 0 + 32 + + + 0 + 4294967295 + + + + + + + RESP3 + RESP3 + response 1..4 register + 0x1C + 0x20 + read-only + 0x00000000 + + + CARDSTATUS3 + Card Status + 0 + 32 + + + 0 + 4294967295 + + + + + + + RESP4 + RESP4 + response 1..4 register + 0x20 + 0x20 + read-only + 0x00000000 + + + CARDSTATUS4 + Card Status + 0 + 32 + + + 0 + 4294967295 + + + + + + + DTIMER + DTIMER + data timer register + 0x24 + 0x20 + read-write + 0x00000000 + + + DATATIME + Data timeout period + 0 + 32 + + + 0 + 4294967295 + + + + + + + DLEN + DLEN + data length register + 0x28 + 0x20 + read-write + 0x00000000 + + + DATALENGTH + Data length value + 0 + 25 + + + 0 + 33554431 + + + + + + + DCTRL + DCTRL + data control register + 0x2C + 0x20 + read-write + 0x00000000 + + + SDIOEN + SD I/O enable functions + 11 + 1 + + SDIOEN + read-write + + Disabled + SDIO operations disabled + 0 + + + Enabled + SDIO operations enabled + 1 + + + + + RWMOD + Read wait mode + 10 + 1 + + RWMOD + read-write + + D2 + Read wait control stopping using SDIO_D2 + 0 + + + Ck + Read wait control using SDIO_CK + 1 + + + + + RWSTOP + Read wait stop + 9 + 1 + + RWSTOP + read-write + + Disabled + Read wait in progress if RWSTART is enabled + 0 + + + Enabled + Enable for read wait stop if RWSTART is enabled + 1 + + + + + RWSTART + Read wait start + 8 + 1 + + RWSTART + read-write + + Disabled + Don't start read wait operation + 0 + + + Enabled + Read wait operation starts + 1 + + + + + DBLOCKSIZE + Data block size + 4 + 4 + + + 0 + 15 + + + + + DMAEN + DMA enable bit + 3 + 1 + + DMAEN + read-write + + Disabled + Dma disabled + 0 + + + Enabled + Dma enabled + 1 + + + + + DTMODE + Data transfer mode selection 1: Stream + or SDIO multibyte data transfer. + 2 + 1 + + DTMODE + read-write + + BlockMode + Bloack data transfer + 0 + + + StreamMode + Stream or SDIO multibyte data transfer + 1 + + + + + DTDIR + Data transfer direction + selection + 1 + 1 + + DTDIR + read-write + + ControllerToCard + From controller to card + 0 + + + CardToController + From card to controller + 1 + + + + + DTEN + DTEN + 0 + 1 + + DTEN + read-write + + Disabled + Disabled + 0 + + + Enabled + Start transfer + 1 + + + + + + + DCOUNT + DCOUNT + data counter register + 0x30 + 0x20 + read-only + 0x00000000 + + + DATACOUNT + Data count value + 0 + 25 + + + 0 + 33554431 + + + + + + + STA + STA + status register + 0x34 + 0x20 + read-only + 0x00000000 + + + CEATAEND + CE-ATA command completion signal + received for CMD61 + 23 + 1 + + CEATAEND + read + + NotReceived + Completion signal not received + 0 + + + Received + CE-ATA command completion signal received for CMD61 + 1 + + + + + SDIOIT + SDIO interrupt received + 22 + 1 + + SDIOIT + read + + NotReceived + SDIO interrupt not receieved + 0 + + + Received + SDIO interrupt received + 1 + + + + + RXDAVL + Data available in receive + FIFO + 21 + 1 + + RXDAVL + read + + NotAvailable + Data not available in receive FIFO + 0 + + + Available + Data available in receive FIFO + 1 + + + + + TXDAVL + Data available in transmit + FIFO + 20 + 1 + + TXDAVL + read + + NotAvailable + Data not available in transmit FIFO + 0 + + + Available + Data available in transmit FIFO + 1 + + + + + RXFIFOE + Receive FIFO empty + 19 + 1 + + RXFIFOE + read + + NotEmpty + Receive FIFO not empty + 0 + + + Empty + Receive FIFO empty + 1 + + + + + TXFIFOE + Transmit FIFO empty + 18 + 1 + + TXFIFOE + read + + NotEmpty + Transmit FIFO not empty + 0 + + + Empty + Transmit FIFO empty. When HW Flow Control is enabled, TXFIFOE signals becomes activated when the FIFO contains 2 words. + 1 + + + + + RXFIFOF + Receive FIFO full + 17 + 1 + + RXFIFOF + read + + NotFull + Transmit FIFO not full + 0 + + + Full + Receive FIFO full. When HW Flow Control is enabled, RXFIFOF signals becomes activated 2 words before the FIFO is full. + 1 + + + + + TXFIFOF + Transmit FIFO full + 16 + 1 + + TXFIFOF + read + + NotFull + Transmit FIFO not full + 0 + + + Full + Transmit FIFO full + 1 + + + + + RXFIFOHF + Receive FIFO half full: there are at + least 8 words in the FIFO + 15 + 1 + + RXFIFOHF + read + + NotHalfFull + Receive FIFO not half full + 0 + + + HalfFull + Receive FIFO half full. At least 8 words in the FIFO + 1 + + + + + TXFIFOHE + Transmit FIFO half empty: at least 8 + words can be written into the FIFO + 14 + 1 + + TXFIFOHE + read + + NotHalfEmpty + Transmit FIFO not half empty + 0 + + + HalfEmpty + Transmit FIFO half empty. At least 8 words can be written into the FIFO + 1 + + + + + RXACT + Data receive in progress + 13 + 1 + + RXACT + read + + NotInProgress + Data receive not in progress + 0 + + + InProgress + Data receive in progress + 1 + + + + + TXACT + Data transmit in progress + 12 + 1 + + TXACT + read + + NotInProgress + Data transmit is not in progress + 0 + + + InProgress + Data transmit in progress + 1 + + + + + CMDACT + Command transfer in + progress + 11 + 1 + + CMDACT + read + + NotInProgress + Command transfer not in progress + 0 + + + InProgress + Command tranfer in progress + 1 + + + + + DBCKEND + Data block sent/received (CRC check + passed) + 10 + 1 + + DBCKEND + read + + NotTransferred + Data block not sent/received (CRC check failed) + 0 + + + Transferred + Data block sent/received (CRC check passed) + 1 + + + + + STBITERR + Start bit not detected on all data + signals in wide bus mode + 9 + 1 + + STBITERR + read + + Detected + No start bit detected error + 0 + + + NotDetected + Start bit not detected error + 1 + + + + + DATAEND + Data end (data counter, SDIDCOUNT, is + zero) + 8 + 1 + + DATAEND + read + + NotDone + Not done + 0 + + + Done + Data end (DCOUNT, is zero) + 1 + + + + + CMDSENT + Command sent (no response + required) + 7 + 1 + + CMDSENT + read + + NotSent + Command not sent + 0 + + + Sent + Command sent (no response required) + 1 + + + + + CMDREND + Command response received (CRC check + passed) + 6 + 1 + + CMDREND + read + + NotDone + Command not done + 0 + + + Done + Command response received (CRC check passed) + 1 + + + + + RXOVERR + Received FIFO overrun + error + 5 + 1 + + RXOVERR + read + + NoOverrun + No FIFO overrun error + 0 + + + Overrun + Receive FIFO overrun error + 1 + + + + + TXUNDERR + Transmit FIFO underrun + error + 4 + 1 + + TXUNDERR + read + + NoUnderrun + No transmit FIFO underrun error + 0 + + + Underrun + Transmit FIFO underrun error + 1 + + + + + DTIMEOUT + Data timeout + 3 + 1 + + DTIMEOUT + read + + NoTimeout + No data timeout + 0 + + + Timeout + Data timeout + 1 + + + + + CTIMEOUT + Command response timeout + 2 + 1 + + CTIMEOUT + read + + NoTimeout + No Command timeout + 0 + + + Timeout + Command timeout + 1 + + + + + DCRCFAIL + Data block sent/received (CRC check + failed) + 1 + 1 + + DCRCFAIL + read + + NotFailed + No Data block sent/received crc check fail + 0 + + + Failed + Data block sent/received crc failed + 1 + + + + + CCRCFAIL + Command response received (CRC check + failed) + 0 + 1 + + CCRCFAIL + read + + NotFailed + Command response received, crc check passed + 0 + + + Failed + Command response received, crc check failed + 1 + + + + + + + ICR + ICR + interrupt clear register + 0x38 + 0x20 + read-write + 0x00000000 + + + CEATAENDC + CEATAEND flag clear bit + 23 + 1 + + + + SDIOITC + SDIOIT flag clear bit + 22 + 1 + + + + DBCKENDC + DBCKEND flag clear bit + 10 + 1 + + + + STBITERRC + STBITERR flag clear bit + 9 + 1 + + + + DATAENDC + DATAEND flag clear bit + 8 + 1 + + + + CMDSENTC + CMDSENT flag clear bit + 7 + 1 + + + + CMDRENDC + CMDREND flag clear bit + 6 + 1 + + + + RXOVERRC + RXOVERR flag clear bit + 5 + 1 + + + + TXUNDERRC + TXUNDERR flag clear bit + 4 + 1 + + + + DTIMEOUTC + DTIMEOUT flag clear bit + 3 + 1 + + + + CTIMEOUTC + CTIMEOUT flag clear bit + 2 + 1 + + + + DCRCFAILC + DCRCFAIL flag clear bit + 1 + 1 + + + + CCRCFAILC + CCRCFAIL flag clear bit + 0 + 1 + + CCRCFAILCW + write + + Clear + Clear flag + 1 + + + + + + + MASK + MASK + mask register + 0x3C + 0x20 + read-write + 0x00000000 + + + CEATAENDIE + CE-ATA command completion signal + received interrupt enable + 23 + 1 + + + + SDIOITIE + SDIO mode interrupt received interrupt + enable + 22 + 1 + + + + RXDAVLIE + Data available in Rx FIFO interrupt + enable + 21 + 1 + + + + TXDAVLIE + Data available in Tx FIFO interrupt + enable + 20 + 1 + + + + RXFIFOEIE + Rx FIFO empty interrupt + enable + 19 + 1 + + + + TXFIFOEIE + Tx FIFO empty interrupt + enable + 18 + 1 + + + + RXFIFOFIE + Rx FIFO full interrupt + enable + 17 + 1 + + + + TXFIFOFIE + Tx FIFO full interrupt + enable + 16 + 1 + + + + RXFIFOHFIE + Rx FIFO half full interrupt + enable + 15 + 1 + + + + TXFIFOHEIE + Tx FIFO half empty interrupt + enable + 14 + 1 + + + + RXACTIE + Data receive acting interrupt + enable + 13 + 1 + + + + TXACTIE + Data transmit acting interrupt + enable + 12 + 1 + + + + CMDACTIE + Command acting interrupt + enable + 11 + 1 + + + + DBCKENDIE + Data block end interrupt + enable + 10 + 1 + + + + STBITERRIE + Start bit error interrupt + enable + 9 + 1 + + + + DATAENDIE + Data end interrupt enable + 8 + 1 + + + + CMDSENTIE + Command sent interrupt + enable + 7 + 1 + + + + CMDRENDIE + Command response received interrupt + enable + 6 + 1 + + + + RXOVERRIE + Rx FIFO overrun error interrupt + enable + 5 + 1 + + + + TXUNDERRIE + Tx FIFO underrun error interrupt + enable + 4 + 1 + + + + DTIMEOUTIE + Data timeout interrupt + enable + 3 + 1 + + + + CTIMEOUTIE + Command timeout interrupt + enable + 2 + 1 + + + + DCRCFAILIE + Data CRC fail interrupt + enable + 1 + 1 + + + + CCRCFAILIE + Command CRC fail interrupt + enable + 0 + 1 + + CCRCFAILIE + read-write + + Disabled + Interrupt disabled + 0 + + + Enabled + Interrupt enabled + 1 + + + + + + + FIFOCNT + FIFOCNT + FIFO counter register + 0x48 + 0x20 + read-only + 0x00000000 + + + FIFOCOUNT + Remaining number of words to be written + to or read from the FIFO. + 0 + 24 + + + 0 + 16777215 + + + + + + + FIFO + FIFO + data FIFO register + 0x80 + 0x20 + read-write + 0x00000000 + + + FIFOData + Receive and transmit FIFO + data + 0 + 32 + + + 0 + 4294967295 + + + + + + + + + SYSCFG + System configuration controller + SYSCFG + 0x40013800 + + 0x0 + 0x400 + registers + + + + MEMRM + MEMRM + memory remap register + 0x0 + 0x20 + read-write + 0x00000000 + + + MEM_MODE + MEM_MODE + 0 + 2 + + + + + PMC + PMC + peripheral mode configuration + register + 0x4 + 0x20 + read-write + 0x00000000 + + + ADC1DC2 + ADC1DC2 + 16 + 1 + + + + + EXTICR1 + EXTICR1 + external interrupt configuration register + 1 + 0x8 + 0x20 + read-write + 0x00000000 + + + EXTI3 + EXTI x configuration (x = 0 to + 3) + 12 + 4 + + + EXTI2 + EXTI x configuration (x = 0 to + 3) + 8 + 4 + + + EXTI1 + EXTI x configuration (x = 0 to + 3) + 4 + 4 + + + EXTI0 + EXTI x configuration (x = 0 to + 3) + 0 + 4 + + + + + EXTICR2 + EXTICR2 + external interrupt configuration register + 2 + 0xC + 0x20 + read-write + 0x00000000 + + + EXTI7 + EXTI x configuration (x = 4 to + 7) + 12 + 4 + + + EXTI6 + EXTI x configuration (x = 4 to + 7) + 8 + 4 + + + EXTI5 + EXTI x configuration (x = 4 to + 7) + 4 + 4 + + + EXTI4 + EXTI x configuration (x = 4 to + 7) + 0 + 4 + + + + + EXTICR3 + EXTICR3 + external interrupt configuration register + 3 + 0x10 + 0x20 + read-write + 0x00000000 + + + EXTI11 + EXTI x configuration (x = 8 to + 11) + 12 + 4 + + + EXTI10 + EXTI10 + 8 + 4 + + + EXTI9 + EXTI x configuration (x = 8 to + 11) + 4 + 4 + + + EXTI8 + EXTI x configuration (x = 8 to + 11) + 0 + 4 + + + + + EXTICR4 + EXTICR4 + external interrupt configuration register + 4 + 0x14 + 0x20 + read-write + 0x00000000 + + + EXTI15 + EXTI x configuration (x = 12 to + 15) + 12 + 4 + + + EXTI14 + EXTI x configuration (x = 12 to + 15) + 8 + 4 + + + EXTI13 + EXTI x configuration (x = 12 to + 15) + 4 + 4 + + + EXTI12 + EXTI x configuration (x = 12 to + 15) + 0 + 4 + + + + + CMPCR + CMPCR + Compensation cell control + register + 0x20 + 0x20 + read-only + 0x00000000 + + + READY + READY + 8 + 1 + + + CMP_PD + Compensation cell + power-down + 0 + 1 + + + + + + + TIM1 + Advanced-timers + TIM + 0x40010000 + + 0x0 + 0x400 + registers + + + + CR1 + CR1 + control register 1 + 0x0 + 0x20 + read-write + 0x00000000 + + + CKD + Clock division + 8 + 2 + + CKD + read-write + + Div1 + t_DTS = t_CK_INT + 0 + + + Div2 + t_DTS = 2 × t_CK_INT + 1 + + + Div4 + t_DTS = 4 × t_CK_INT + 2 + + + + + ARPE + Auto-reload preload enable + 7 + 1 + + ARPE + read-write + + Disabled + TIMx_APRR register is not buffered + 0 + + + Enabled + TIMx_APRR register is buffered + 1 + + + + + CMS + Center-aligned mode + selection + 5 + 2 + + CMS + read-write + + EdgeAligned + The counter counts up or down depending on the direction bit + 0 + + + CenterAligned1 + The counter counts up and down alternatively. Output compare interrupt flags are set only when the counter is counting down. + 1 + + + CenterAligned2 + The counter counts up and down alternatively. Output compare interrupt flags are set only when the counter is counting up. + 2 + + + CenterAligned3 + The counter counts up and down alternatively. Output compare interrupt flags are set both when the counter is counting up or down. + 3 + + + + + DIR + Direction + 4 + 1 + + DIR + read-write + + Up + Counter used as upcounter + 0 + + + Down + Counter used as downcounter + 1 + + + + + OPM + One-pulse mode + 3 + 1 + + OPM + read-write + + Disabled + Counter is not stopped at update event + 0 + + + Enabled + Counter stops counting at the next update event (clearing the CEN bit) + 1 + + + + + URS + Update request source + 2 + 1 + + URS + read-write + + AnyEvent + Any of counter overflow/underflow, setting UG, or update through slave mode, generates an update interrupt or DMA request + 0 + + + CounterOnly + Only counter overflow/underflow generates an update interrupt or DMA request + 1 + + + + + UDIS + Update disable + 1 + 1 + + UDIS + read-write + + Enabled + Update event enabled + 0 + + + Disabled + Update event disabled + 1 + + + + + CEN + Counter enable + 0 + 1 + + CEN + read-write + + Disabled + Counter disabled + 0 + + + Enabled + Counter enabled + 1 + + + + + + + CR2 + CR2 + control register 2 + 0x4 + 0x20 + read-write + 0x00000000 + + + OIS4 + Output Idle state 4 + 14 + 1 + + + + OIS3N + Output Idle state 3 + 13 + 1 + + + + OIS3 + Output Idle state 3 + 12 + 1 + + + + OIS2N + Output Idle state 2 + 11 + 1 + + + + OIS2 + Output Idle state 2 + 10 + 1 + + + + OIS1N + Output Idle state 1 + 9 + 1 + + OIS1N + read-write + + Reset + OCxN=0 after a dead-time when MOE=0 + 0 + + + Set + OCxN=1 after a dead-time when MOE=0 + 1 + + + + + OIS1 + Output Idle state 1 + 8 + 1 + + OIS1 + read-write + + Reset + OCx=0 (after a dead-time if OCx(N) is implemented) when MOE=0 + 0 + + + Set + OCx=1 (after a dead-time if OCx(N) is implemented) when MOE=0 + 1 + + + + + TI1S + TI1 selection + 7 + 1 + + TI1S + read-write + + Normal + The TIMx_CH1 pin is connected to TI1 input + 0 + + + XOR + The TIMx_CH1, CH2, CH3 pins are connected to TI1 input + 1 + + + + + MMS + Master mode selection + 4 + 3 + + MMS + read-write + + Reset + The UG bit from the TIMx_EGR register is used as trigger output + 0 + + + Enable + The counter enable signal, CNT_EN, is used as trigger output + 1 + + + Update + The update event is selected as trigger output + 2 + + + ComparePulse + The trigger output send a positive pulse when the CC1IF flag it to be set, as soon as a capture or a compare match occurred + 3 + + + CompareOC1 + OC1REF signal is used as trigger output + 4 + + + CompareOC2 + OC2REF signal is used as trigger output + 5 + + + CompareOC3 + OC3REF signal is used as trigger output + 6 + + + CompareOC4 + OC4REF signal is used as trigger output + 7 + + + + + CCDS + Capture/compare DMA + selection + 3 + 1 + + CCDS + read-write + + OnCompare + CCx DMA request sent when CCx event occurs + 0 + + + OnUpdate + CCx DMA request sent when update event occurs + 1 + + + + + CCUS + Capture/compare control update + selection + 2 + 1 + + + CCPC + Capture/compare preloaded + control + 0 + 1 + + + + + SMCR + SMCR + slave mode control register + 0x8 + 0x20 + read-write + 0x00000000 + + + ETP + External trigger polarity + 15 + 1 + + ETP + read-write + + NotInverted + ETR is noninverted, active at high level or rising edge + 0 + + + Inverted + ETR is inverted, active at low level or falling edge + 1 + + + + + ECE + External clock enable + 14 + 1 + + ECE + read-write + + Disabled + External clock mode 2 disabled + 0 + + + Enabled + External clock mode 2 enabled. The counter is clocked by any active edge on the ETRF signal. + 1 + + + + + ETPS + External trigger prescaler + 12 + 2 + + ETPS + read-write + + Div1 + Prescaler OFF + 0 + + + Div2 + ETRP frequency divided by 2 + 1 + + + Div4 + ETRP frequency divided by 4 + 2 + + + Div8 + ETRP frequency divided by 8 + 3 + + + + + ETF + External trigger filter + 8 + 4 + + ETF + read-write + + NoFilter + No filter, sampling is done at fDTS + 0 + + + FCK_INT_N2 + fSAMPLING=fCK_INT, N=2 + 1 + + + FCK_INT_N4 + fSAMPLING=fCK_INT, N=4 + 2 + + + FCK_INT_N8 + fSAMPLING=fCK_INT, N=8 + 3 + + + FDTS_Div2_N6 + fSAMPLING=fDTS/2, N=6 + 4 + + + FDTS_Div2_N8 + fSAMPLING=fDTS/2, N=8 + 5 + + + FDTS_Div4_N6 + fSAMPLING=fDTS/4, N=6 + 6 + + + FDTS_Div4_N8 + fSAMPLING=fDTS/4, N=8 + 7 + + + FDTS_Div8_N6 + fSAMPLING=fDTS/8, N=6 + 8 + + + FDTS_Div8_N8 + fSAMPLING=fDTS/8, N=8 + 9 + + + FDTS_Div16_N5 + fSAMPLING=fDTS/16, N=5 + 10 + + + FDTS_Div16_N6 + fSAMPLING=fDTS/16, N=6 + 11 + + + FDTS_Div16_N8 + fSAMPLING=fDTS/16, N=8 + 12 + + + FDTS_Div32_N5 + fSAMPLING=fDTS/32, N=5 + 13 + + + FDTS_Div32_N6 + fSAMPLING=fDTS/32, N=6 + 14 + + + FDTS_Div32_N8 + fSAMPLING=fDTS/32, N=8 + 15 + + + + + MSM + Master/Slave mode + 7 + 1 + + MSM + read-write + + NoSync + No action + 0 + + + Sync + The effect of an event on the trigger input (TRGI) is delayed to allow a perfect synchronization between the current timer and its slaves (through TRGO). It is useful if we want to synchronize several timers on a single external event. + 1 + + + + + TS + Trigger selection + 4 + 3 + + TS + read-write + + ITR0 + Internal Trigger 0 (ITR0) + 0 + + + ITR1 + Internal Trigger 1 (ITR1) + 1 + + + ITR2 + Internal Trigger 2 (ITR2) + 2 + + + TI1F_ED + TI1 Edge Detector (TI1F_ED) + 4 + + + TI1FP1 + Filtered Timer Input 1 (TI1FP1) + 5 + + + TI2FP2 + Filtered Timer Input 2 (TI2FP2) + 6 + + + ETRF + External Trigger input (ETRF) + 7 + + + + + SMS + Slave mode selection + 0 + 3 + + SMS + read-write + + Disabled + Slave mode disabled - if CEN = ‘1 then the prescaler is clocked directly by the internal clock. + 0 + + + Encoder_Mode_1 + Encoder mode 1 - Counter counts up/down on TI2FP1 edge depending on TI1FP2 level. + 1 + + + Encoder_Mode_2 + Encoder mode 2 - Counter counts up/down on TI1FP2 edge depending on TI2FP1 level. + 2 + + + Encoder_Mode_3 + Encoder mode 3 - Counter counts up/down on both TI1FP1 and TI2FP2 edges depending on the level of the other input. + 3 + + + Reset_Mode + Reset Mode - Rising edge of the selected trigger input (TRGI) reinitializes the counter and generates an update of the registers. + 4 + + + Gated_Mode + Gated Mode - The counter clock is enabled when the trigger input (TRGI) is high. The counter stops (but is not reset) as soon as the trigger becomes low. Both start and stop of the counter are controlled. + 5 + + + Trigger_Mode + Trigger Mode - The counter starts at a rising edge of the trigger TRGI (but it is not reset). Only the start of the counter is controlled. + 6 + + + Ext_Clock_Mode + External Clock Mode 1 - Rising edges of the selected trigger (TRGI) clock the counter. + 7 + + + + + + + DIER + DIER + DMA/Interrupt enable register + 0xC + 0x20 + read-write + 0x00000000 + + + TDE + Trigger DMA request enable + 14 + 1 + + TDE + read-write + + Disabled + Trigger DMA request disabled + 0 + + + Enabled + Trigger DMA request enabled + 1 + + + + + COMDE + COM DMA request enable + 13 + 1 + + + CC4DE + Capture/Compare 4 DMA request + enable + 12 + 1 + + + + CC3DE + Capture/Compare 3 DMA request + enable + 11 + 1 + + + + CC2DE + Capture/Compare 2 DMA request + enable + 10 + 1 + + + + CC1DE + Capture/Compare 1 DMA request + enable + 9 + 1 + + CC1DE + read-write + + Disabled + CCx DMA request disabled + 0 + + + Enabled + CCx DMA request enabled + 1 + + + + + UDE + Update DMA request enable + 8 + 1 + + UDE + read-write + + Disabled + Update DMA request disabled + 0 + + + Enabled + Update DMA request enabled + 1 + + + + + BIE + Break interrupt enable + 7 + 1 + + + TIE + Trigger interrupt enable + 6 + 1 + + TIE + read-write + + Disabled + Trigger interrupt disabled + 0 + + + Enabled + Trigger interrupt enabled + 1 + + + + + COMIE + COM interrupt enable + 5 + 1 + + + CC4IE + Capture/Compare 4 interrupt + enable + 4 + 1 + + + + CC3IE + Capture/Compare 3 interrupt + enable + 3 + 1 + + + + CC2IE + Capture/Compare 2 interrupt + enable + 2 + 1 + + + + CC1IE + Capture/Compare 1 interrupt + enable + 1 + 1 + + CC1IE + read-write + + Disabled + CCx interrupt disabled + 0 + + + Enabled + CCx interrupt enabled + 1 + + + + + UIE + Update interrupt enable + 0 + 1 + + UIE + read-write + + Disabled + Update interrupt disabled + 0 + + + Enabled + Update interrupt enabled + 1 + + + + + + + SR + SR + status register + 0x10 + 0x20 + read-write + 0x00000000 + + + CC4OF + Capture/Compare 4 overcapture + flag + 12 + 1 + zeroToClear + + read + + + write + + + + CC3OF + Capture/Compare 3 overcapture + flag + 11 + 1 + zeroToClear + + read + + + write + + + + CC2OF + Capture/compare 2 overcapture + flag + 10 + 1 + zeroToClear + + read + + + write + + + + CC1OF + Capture/Compare 1 overcapture + flag + 9 + 1 + zeroToClear + + CC1OFR + read + + Overcapture + The counter value has been captured in TIMx_CCRx register while CCxIF flag was already set + 1 + + + + CC1OFW + write + + Clear + Clear flag + 0 + + + + + BIF + Break interrupt flag + 7 + 1 + + + TIF + Trigger interrupt flag + 6 + 1 + zeroToClear + + TIFR + read + + NoTrigger + No trigger event occurred + 0 + + + Trigger + Trigger interrupt pending + 1 + + + + TIFW + write + + Clear + Clear flag + 0 + + + + + COMIF + COM interrupt flag + 5 + 1 + + + CC4IF + Capture/Compare 4 interrupt + flag + 4 + 1 + zeroToClear + + read + + + write + + + + CC3IF + Capture/Compare 3 interrupt + flag + 3 + 1 + zeroToClear + + read + + + write + + + + CC2IF + Capture/Compare 2 interrupt + flag + 2 + 1 + zeroToClear + + read + + + write + + + + CC1IF + Capture/compare 1 interrupt + flag + 1 + 1 + zeroToClear + + CC1IFR + read + + Match + If CC1 is an output: The content of the counter TIMx_CNT matches the content of the TIMx_CCR1 register. If CC1 is an input: The counter value has been captured in TIMx_CCR1 register. + 1 + + + + CC1IFW + write + + Clear + Clear flag + 0 + + + + + UIF + Update interrupt flag + 0 + 1 + zeroToClear + + UIFR + read + + NoUpdateOccurred + No update occurred + 0 + + + UpdatePending + Update interrupt pending + 1 + + + + UIFW + write + + Clear + Clear flag + 0 + + + + + + + EGR + EGR + event generation register + 0x14 + 0x20 + write-only + 0x00000000 + + + BG + Break generation + 7 + 1 + + + TG + Trigger generation + 6 + 1 + + TGW + write + + Trigger + The TIF flag is set in TIMx_SR register. Related interrupt or DMA transfer can occur if enabled. + 1 + + + + + COMG + Capture/Compare control update + generation + 5 + 1 + + + CC4G + Capture/compare 4 + generation + 4 + 1 + + + + CC3G + Capture/compare 3 + generation + 3 + 1 + + + + CC2G + Capture/compare 2 + generation + 2 + 1 + + + + CC1G + Capture/compare 1 + generation + 1 + 1 + + CC1GW + write + + Trigger + If CC1 is an output: CC1IF flag is set, Corresponding interrupt or DMA request is sent if enabled. If CC1 is an input: The current value of the counter is captured in TIMx_CCR1 register. + 1 + + + + + UG + Update generation + 0 + 1 + + UG + write + + Update + Re-initializes the timer counter and generates an update of the registers. + 1 + + + + + + + CCMR1_Output + CCMR1_Output + capture/compare mode register 1 (output + mode) + 0x18 + 0x20 + read-write + 0x00000000 + + + OC2CE + Output Compare 2 clear + enable + 15 + 1 + + + OC2M + Output Compare 2 mode + 12 + 3 + + + + OC2PE + Output Compare 2 preload + enable + 11 + 1 + + OC2PE + read-write + + Disabled + Preload register on CCR2 disabled. New values written to CCR2 are taken into account immediately + 0 + + + Enabled + Preload register on CCR2 enabled. Preload value is loaded into active register on each update event + 1 + + + + + OC2FE + Output Compare 2 fast + enable + 10 + 1 + + + CC2S + Capture/Compare 2 + selection + 8 + 2 + + CC2S + read-write + + Output + CC2 channel is configured as output + 0 + + + + + OC1CE + Output Compare 1 clear + enable + 7 + 1 + + + OC1M + Output Compare 1 mode + 4 + 3 + + OC1M + read-write + + Frozen + The comparison between the output compare register TIMx_CCRy and the counter TIMx_CNT has no effect on the outputs + 0 + + + ActiveOnMatch + Set channel to active level on match. OCyREF signal is forced high when the counter matches the capture/compare register + 1 + + + InactiveOnMatch + Set channel to inactive level on match. OCyREF signal is forced low when the counter matches the capture/compare register + 2 + + + Toggle + OCyREF toggles when TIMx_CNT=TIMx_CCRy + 3 + + + ForceInactive + OCyREF is forced low + 4 + + + ForceActive + OCyREF is forced high + 5 + + + PwmMode1 + In upcounting, channel is active as long as TIMx_CNT<TIMx_CCRy else inactive. In downcounting, channel is inactive as long as TIMx_CNT>TIMx_CCRy else active + 6 + + + PwmMode2 + Inversely to PwmMode1 + 7 + + + + + OC1PE + Output Compare 1 preload + enable + 3 + 1 + + OC1PE + read-write + + Disabled + Preload register on CCR1 disabled. New values written to CCR1 are taken into account immediately + 0 + + + Enabled + Preload register on CCR1 enabled. Preload value is loaded into active register on each update event + 1 + + + + + OC1FE + Output Compare 1 fast + enable + 2 + 1 + + + CC1S + Capture/Compare 1 + selection + 0 + 2 + + CC1S + read-write + + Output + CC1 channel is configured as output + 0 + + + + + + + CCMR1_Input + CCMR1_Input + capture/compare mode register 1 (input + mode) + CCMR1_Output + 0x18 + 0x20 + read-write + 0x00000000 + + + IC2F + Input capture 2 filter + 12 + 4 + + + 0 + 15 + + + + + IC2PSC + Input capture 2 prescaler + 10 + 2 + + + CC2S + Capture/Compare 2 + selection + 8 + 2 + + CC2S + read-write + + TI2 + CC2 channel is configured as input, IC2 is mapped on TI2 + 1 + + + TI1 + CC2 channel is configured as input, IC2 is mapped on TI1 + 2 + + + TRC + CC2 channel is configured as input, IC2 is mapped on TRC + 3 + + + + + IC1F + Input capture 1 filter + 4 + 4 + + IC1F + read-write + + NoFilter + No filter, sampling is done at fDTS + 0 + + + FCK_INT_N2 + fSAMPLING=fCK_INT, N=2 + 1 + + + FCK_INT_N4 + fSAMPLING=fCK_INT, N=4 + 2 + + + FCK_INT_N8 + fSAMPLING=fCK_INT, N=8 + 3 + + + FDTS_Div2_N6 + fSAMPLING=fDTS/2, N=6 + 4 + + + FDTS_Div2_N8 + fSAMPLING=fDTS/2, N=8 + 5 + + + FDTS_Div4_N6 + fSAMPLING=fDTS/4, N=6 + 6 + + + FDTS_Div4_N8 + fSAMPLING=fDTS/4, N=8 + 7 + + + FDTS_Div8_N6 + fSAMPLING=fDTS/8, N=6 + 8 + + + FDTS_Div8_N8 + fSAMPLING=fDTS/8, N=8 + 9 + + + FDTS_Div16_N5 + fSAMPLING=fDTS/16, N=5 + 10 + + + FDTS_Div16_N6 + fSAMPLING=fDTS/16, N=6 + 11 + + + FDTS_Div16_N8 + fSAMPLING=fDTS/16, N=8 + 12 + + + FDTS_Div32_N5 + fSAMPLING=fDTS/32, N=5 + 13 + + + FDTS_Div32_N6 + fSAMPLING=fDTS/32, N=6 + 14 + + + FDTS_Div32_N8 + fSAMPLING=fDTS/32, N=8 + 15 + + + + + IC1PSC + Input capture 1 prescaler + 2 + 2 + + + CC1S + Capture/Compare 1 + selection + 0 + 2 + + CC1S + read-write + + TI1 + CC1 channel is configured as input, IC1 is mapped on TI1 + 1 + + + TI2 + CC1 channel is configured as input, IC1 is mapped on TI2 + 2 + + + TRC + CC1 channel is configured as input, IC1 is mapped on TRC + 3 + + + + + + + CCMR2_Output + CCMR2_Output + capture/compare mode register 2 (output + mode) + 0x1C + 0x20 + read-write + 0x00000000 + + + OC4CE + Output compare 4 clear + enable + 15 + 1 + + + OC4M + Output compare 4 mode + 12 + 3 + + + + OC4PE + Output compare 4 preload + enable + 11 + 1 + + OC4PE + read-write + + Disabled + Preload register on CCR4 disabled. New values written to CCR4 are taken into account immediately + 0 + + + Enabled + Preload register on CCR4 enabled. Preload value is loaded into active register on each update event + 1 + + + + + OC4FE + Output compare 4 fast + enable + 10 + 1 + + + CC4S + Capture/Compare 4 + selection + 8 + 2 + + CC4S + read-write + + Output + CC4 channel is configured as output + 0 + + + + + OC3CE + Output compare 3 clear + enable + 7 + 1 + + + OC3M + Output compare 3 mode + 4 + 3 + + OC3M + read-write + + Frozen + The comparison between the output compare register TIMx_CCRy and the counter TIMx_CNT has no effect on the outputs + 0 + + + ActiveOnMatch + Set channel to active level on match. OCyREF signal is forced high when the counter matches the capture/compare register + 1 + + + InactiveOnMatch + Set channel to inactive level on match. OCyREF signal is forced low when the counter matches the capture/compare register + 2 + + + Toggle + OCyREF toggles when TIMx_CNT=TIMx_CCRy + 3 + + + ForceInactive + OCyREF is forced low + 4 + + + ForceActive + OCyREF is forced high + 5 + + + PwmMode1 + In upcounting, channel is active as long as TIMx_CNT<TIMx_CCRy else inactive. In downcounting, channel is inactive as long as TIMx_CNT>TIMx_CCRy else active + 6 + + + PwmMode2 + Inversely to PwmMode1 + 7 + + + + + OC3PE + Output compare 3 preload + enable + 3 + 1 + + OC3PE + read-write + + Disabled + Preload register on CCR3 disabled. New values written to CCR3 are taken into account immediately + 0 + + + Enabled + Preload register on CCR3 enabled. Preload value is loaded into active register on each update event + 1 + + + + + OC3FE + Output compare 3 fast + enable + 2 + 1 + + + CC3S + Capture/Compare 3 + selection + 0 + 2 + + CC3S + read-write + + Output + CC3 channel is configured as output + 0 + + + + + + + CCMR2_Input + CCMR2_Input + capture/compare mode register 2 (input + mode) + CCMR2_Output + 0x1C + 0x20 + read-write + 0x00000000 + + + IC4F + Input capture 4 filter + 12 + 4 + + + 0 + 15 + + + + + IC4PSC + Input capture 4 prescaler + 10 + 2 + + + 0 + 3 + + + + + CC4S + Capture/Compare 4 + selection + 8 + 2 + + CC4S + read-write + + TI4 + CC4 channel is configured as input, IC4 is mapped on TI4 + 1 + + + TI3 + CC4 channel is configured as input, IC4 is mapped on TI3 + 2 + + + TRC + CC4 channel is configured as input, IC4 is mapped on TRC + 3 + + + + + IC3F + Input capture 3 filter + 4 + 4 + + + 0 + 15 + + + + + IC3PSC + Input capture 3 prescaler + 2 + 2 + + + 0 + 3 + + + + + CC3S + Capture/compare 3 + selection + 0 + 2 + + CC3S + read-write + + TI3 + CC3 channel is configured as input, IC3 is mapped on TI3 + 1 + + + TI4 + CC3 channel is configured as input, IC3 is mapped on TI4 + 2 + + + TRC + CC3 channel is configured as input, IC3 is mapped on TRC + 3 + + + + + + + CCER + CCER + capture/compare enable + register + 0x20 + 0x20 + read-write + 0x00000000 + + + CC4P + Capture/Compare 3 output + Polarity + 13 + 1 + + + CC4E + Capture/Compare 4 output + enable + 12 + 1 + + + CC3NP + Capture/Compare 3 output + Polarity + 11 + 1 + + + CC3NE + Capture/Compare 3 complementary output + enable + 10 + 1 + + + CC3P + Capture/Compare 3 output + Polarity + 9 + 1 + + + CC3E + Capture/Compare 3 output + enable + 8 + 1 + + + CC2NP + Capture/Compare 2 output + Polarity + 7 + 1 + + + CC2NE + Capture/Compare 2 complementary output + enable + 6 + 1 + + + CC2P + Capture/Compare 2 output + Polarity + 5 + 1 + + + CC2E + Capture/Compare 2 output + enable + 4 + 1 + + + CC1NP + Capture/Compare 1 output + Polarity + 3 + 1 + + + CC1NE + Capture/Compare 1 complementary output + enable + 2 + 1 + + + CC1P + Capture/Compare 1 output + Polarity + 1 + 1 + + + CC1E + Capture/Compare 1 output + enable + 0 + 1 + + + + + CNT + CNT + counter + 0x24 + 0x20 + read-write + 0x00000000 + + + CNT + counter value + 0 + 16 + + + 0 + 65535 + + + + + + + PSC + PSC + prescaler + 0x28 + 0x20 + read-write + 0x00000000 + + + PSC + Prescaler value + 0 + 16 + + + 0 + 65535 + + + + + + + ARR + ARR + auto-reload register + 0x2C + 0x20 + read-write + 0x00000000 + + + ARR + Auto-reload value + 0 + 16 + + + 0 + 65535 + + + + + + + 4 + 0x4 + 1-4 + CCR%s + CCR1 + capture/compare register + 0x34 + 0x20 + read-write + 0x00000000 + + + CCR + Capture/Compare value + 0 + 16 + + + 0 + 65535 + + + + + + + DCR + DCR + DMA control register + 0x48 + 0x20 + read-write + 0x00000000 + + + DBL + DMA burst length + 8 + 5 + + + 0 + 18 + + + + + DBA + DMA base address + 0 + 5 + + + 0 + 31 + + + + + + + DMAR + DMAR + DMA address for full transfer + 0x4C + 0x20 + read-write + 0x00000000 + + + DMAB + DMA register for burst + accesses + 0 + 16 + + + + + RCR + RCR + repetition counter register + 0x30 + 0x20 + read-write + 0x00000000 + + + REP + Repetition counter value + 0 + 8 + + + + + BDTR + BDTR + break and dead-time register + 0x44 + 0x20 + read-write + 0x00000000 + + + MOE + Main output enable + 15 + 1 + + MOE + read-write + + DisabledIdle + OC/OCN are disabled or forced idle depending on OSSI + 0 + + + Enabled + OC/OCN are enabled if CCxE/CCxNE are set + 1 + + + + + AOE + Automatic output enable + 14 + 1 + + AOE + read-write + + Manual + MOE can be set only by software + 0 + + + Automatic + MOE can be set by software or automatically at the next update event (if none of the break inputs BRK and BRK2 is active) + 1 + + + + + BKP + Break polarity + 13 + 1 + + BKP + read-write + + ActiveLow + Break input BRKx is active low + 0 + + + ActiveHigh + Break input BRKx is active high + 1 + + + + + BKE + Break enable + 12 + 1 + + BKE + read-write + + Disabled + Break function x disabled + 0 + + + Enabled + Break function x disabled + 1 + + + + + OSSR + Off-state selection for Run + mode + 11 + 1 + + OSSR + read-write + + Disabled + When inactive, OC/OCN outputs are disabled + 0 + + + IdleLevel + When inactive, OC/OCN outputs are enabled with their inactive level + 1 + + + + + OSSI + Off-state selection for Idle + mode + 10 + 1 + + OSSI + read-write + + Disabled + When inactive, OC/OCN outputs are disabled + 0 + + + IdleLevel + When inactive, OC/OCN outputs are forced to idle level + 1 + + + + + LOCK + Lock configuration + 8 + 2 + + LOCK + read-write + + Off + No bit is write protected + 0 + + + Level1 + Any bits except MOE, OSSR, OSSI and LOCK in TIMx_BDTR register, OISx and OISxN bits in TIMx_CR2 register can no longer be written + 1 + + + Level2 + LOCK Level 1 + CC Polarity bits (CCxP/CCxNP bits in TIMx_CCER register, as long as the related channel is configured in output through the CCxS bits) as well as OSSR and OSSI bits can no longer be written + 2 + + + Level3 + LOCK Level 2 + CC Control bits (OCxM and OCxPE bits in TIMx_CCMRx registers, as long as the related channel is configured in output through the CCxS bits) can no longer be written + 3 + + + + + DTG + Dead-time generator setup + 0 + 8 + + + 0 + 255 + + + + + + + + + TIM10 + General-purpose-timers + TIM + 0x40014400 + + 0x0 + 0x400 + registers + + + SPI1 + SPI1 global interrupt + 35 + + + + CR1 + CR1 + control register 1 + 0x0 + 0x20 + read-write + 0x00000000 + + + CKD + Clock division + 8 + 2 + + CKD + read-write + + Div1 + t_DTS = t_CK_INT + 0 + + + Div2 + t_DTS = 2 × t_CK_INT + 1 + + + Div4 + t_DTS = 4 × t_CK_INT + 2 + + + + + ARPE + Auto-reload preload enable + 7 + 1 + + ARPE + read-write + + Disabled + TIMx_APRR register is not buffered + 0 + + + Enabled + TIMx_APRR register is buffered + 1 + + + + + URS + Update request source + 2 + 1 + + URS + read-write + + AnyEvent + Any of counter overflow/underflow, setting UG, or update through slave mode, generates an update interrupt or DMA request + 0 + + + CounterOnly + Only counter overflow/underflow generates an update interrupt or DMA request + 1 + + + + + UDIS + Update disable + 1 + 1 + + UDIS + read-write + + Enabled + Update event enabled + 0 + + + Disabled + Update event disabled + 1 + + + + + CEN + Counter enable + 0 + 1 + + CEN + read-write + + Disabled + Counter disabled + 0 + + + Enabled + Counter enabled + 1 + + + + + OPM + One-pulse mode + 3 + 1 + + OPM + read-write + + Disabled + Counter is not stopped at update event + 0 + + + Enabled + Counter stops counting at the next update event (clearing the CEN bit) + 1 + + + + + + + DIER + DIER + DMA/Interrupt enable register + 0xC + 0x20 + read-write + 0x00000000 + + + CC1IE + Capture/Compare 1 interrupt + enable + 1 + 1 + + + UIE + Update interrupt enable + 0 + 1 + + UIE + read-write + + Disabled + Update interrupt disabled + 0 + + + Enabled + Update interrupt enabled + 1 + + + + + + + SR + SR + status register + 0x10 + 0x20 + read-write + 0x00000000 + + + CC1OF + Capture/Compare 1 overcapture + flag + 9 + 1 + + + CC1IF + Capture/compare 1 interrupt + flag + 1 + 1 + + + UIF + Update interrupt flag + 0 + 1 + zeroToClear + + UIFR + read + + NoUpdateOccurred + No update occurred + 0 + + + UpdatePending + Update interrupt pending + 1 + + + + UIFW + write + + Clear + Clear flag + 0 + + + + + + + EGR + EGR + event generation register + 0x14 + 0x20 + write-only + 0x00000000 + + + CC1G + Capture/compare 1 + generation + 1 + 1 + + + UG + Update generation + 0 + 1 + + UG + write + + Update + Re-initializes the timer counter and generates an update of the registers. + 1 + + + + + + + CCMR1_Output + CCMR1_Output + capture/compare mode register 1 (output + mode) + 0x18 + 0x20 + read-write + 0x00000000 + + + OC1M + Output Compare 1 mode + 4 + 3 + + OC1M + read-write + + Frozen + The comparison between the output compare register TIMx_CCRy and the counter TIMx_CNT has no effect on the outputs + 0 + + + ActiveOnMatch + Set channel to active level on match. OCyREF signal is forced high when the counter matches the capture/compare register + 1 + + + InactiveOnMatch + Set channel to inactive level on match. OCyREF signal is forced low when the counter matches the capture/compare register + 2 + + + Toggle + OCyREF toggles when TIMx_CNT=TIMx_CCRy + 3 + + + ForceInactive + OCyREF is forced low + 4 + + + ForceActive + OCyREF is forced high + 5 + + + PwmMode1 + In upcounting, channel is active as long as TIMx_CNT<TIMx_CCRy else inactive. In downcounting, channel is inactive as long as TIMx_CNT>TIMx_CCRy else active + 6 + + + PwmMode2 + Inversely to PwmMode1 + 7 + + + + + OC1PE + Output Compare 1 preload + enable + 3 + 1 + + + OC1FE + Output Compare 1 fast + enable + 2 + 1 + + + CC1S + Capture/Compare 1 + selection + 0 + 2 + + + + + CCMR1_Input + CCMR1_Input + capture/compare mode register 1 (input + mode) + CCMR1_Output + 0x18 + 0x20 + read-write + 0x00000000 + + + IC1F + Input capture 1 filter + 4 + 4 + + + IC1PSC + Input capture 1 prescaler + 2 + 2 + + + CC1S + Capture/Compare 1 + selection + 0 + 2 + + + + + CCER + CCER + capture/compare enable + register + 0x20 + 0x20 + read-write + 0x00000000 + + + CC1NP + Capture/Compare 1 output + Polarity + 3 + 1 + + + CC1P + Capture/Compare 1 output + Polarity + 1 + 1 + + + CC1E + Capture/Compare 1 output + enable + 0 + 1 + + + + + CNT + CNT + counter + 0x24 + 0x20 + read-write + 0x00000000 + + + CNT + counter value + 0 + 16 + + + + + PSC + PSC + prescaler + 0x28 + 0x20 + read-write + 0x00000000 + + + PSC + Prescaler value + 0 + 16 + + + 0 + 65535 + + + + + + + ARR + ARR + auto-reload register + 0x2C + 0x20 + read-write + 0x00000000 + + + ARR + Auto-reload value + 0 + 16 + + + + + 1 + 0x0 + 1-1 + CCR%s + CCR1 + capture/compare register + 0x34 + 0x20 + read-write + 0x00000000 + + + CCR + Capture/Compare value + 0 + 16 + + + + + + + TIM11 + General-purpose-timers + TIM + 0x40014800 + + 0x0 + 0x400 + registers + + + SPI2 + SPI2 global interrupt + 36 + + + + CR1 + CR1 + control register 1 + 0x0 + 0x20 + read-write + 0x00000000 + + + CKD + Clock division + 8 + 2 + + CKD + read-write + + Div1 + t_DTS = t_CK_INT + 0 + + + Div2 + t_DTS = 2 × t_CK_INT + 1 + + + Div4 + t_DTS = 4 × t_CK_INT + 2 + + + + + ARPE + Auto-reload preload enable + 7 + 1 + + ARPE + read-write + + Disabled + TIMx_APRR register is not buffered + 0 + + + Enabled + TIMx_APRR register is buffered + 1 + + + + + URS + Update request source + 2 + 1 + + URS + read-write + + AnyEvent + Any of counter overflow/underflow, setting UG, or update through slave mode, generates an update interrupt or DMA request + 0 + + + CounterOnly + Only counter overflow/underflow generates an update interrupt or DMA request + 1 + + + + + UDIS + Update disable + 1 + 1 + + UDIS + read-write + + Enabled + Update event enabled + 0 + + + Disabled + Update event disabled + 1 + + + + + CEN + Counter enable + 0 + 1 + + CEN + read-write + + Disabled + Counter disabled + 0 + + + Enabled + Counter enabled + 1 + + + + + OPM + One-pulse mode + 3 + 1 + + OPM + read-write + + Disabled + Counter is not stopped at update event + 0 + + + Enabled + Counter stops counting at the next update event (clearing the CEN bit) + 1 + + + + + + + DIER + DIER + DMA/Interrupt enable register + 0xC + 0x20 + read-write + 0x00000000 + + + CC1IE + Capture/Compare 1 interrupt + enable + 1 + 1 + + + UIE + Update interrupt enable + 0 + 1 + + UIE + read-write + + Disabled + Update interrupt disabled + 0 + + + Enabled + Update interrupt enabled + 1 + + + + + + + SR + SR + status register + 0x10 + 0x20 + read-write + 0x00000000 + + + CC1OF + Capture/Compare 1 overcapture + flag + 9 + 1 + + + CC1IF + Capture/compare 1 interrupt + flag + 1 + 1 + + + UIF + Update interrupt flag + 0 + 1 + zeroToClear + + UIFR + read + + NoUpdateOccurred + No update occurred + 0 + + + UpdatePending + Update interrupt pending + 1 + + + + UIFW + write + + Clear + Clear flag + 0 + + + + + + + EGR + EGR + event generation register + 0x14 + 0x20 + write-only + 0x00000000 + + + CC1G + Capture/compare 1 + generation + 1 + 1 + + + UG + Update generation + 0 + 1 + + UG + write + + Update + Re-initializes the timer counter and generates an update of the registers. + 1 + + + + + + + CCMR1_Output + CCMR1_Output + capture/compare mode register 1 (output + mode) + 0x18 + 0x20 + read-write + 0x00000000 + + + OC1M + Output Compare 1 mode + 4 + 3 + + OC1M + read-write + + Frozen + The comparison between the output compare register TIMx_CCRy and the counter TIMx_CNT has no effect on the outputs + 0 + + + ActiveOnMatch + Set channel to active level on match. OCyREF signal is forced high when the counter matches the capture/compare register + 1 + + + InactiveOnMatch + Set channel to inactive level on match. OCyREF signal is forced low when the counter matches the capture/compare register + 2 + + + Toggle + OCyREF toggles when TIMx_CNT=TIMx_CCRy + 3 + + + ForceInactive + OCyREF is forced low + 4 + + + ForceActive + OCyREF is forced high + 5 + + + PwmMode1 + In upcounting, channel is active as long as TIMx_CNT<TIMx_CCRy else inactive. In downcounting, channel is inactive as long as TIMx_CNT>TIMx_CCRy else active + 6 + + + PwmMode2 + Inversely to PwmMode1 + 7 + + + + + OC1PE + Output Compare 1 preload + enable + 3 + 1 + + + OC1FE + Output Compare 1 fast + enable + 2 + 1 + + + CC1S + Capture/Compare 1 + selection + 0 + 2 + + + + + CCMR1_Input + CCMR1_Input + capture/compare mode register 1 (input + mode) + CCMR1_Output + 0x18 + 0x20 + read-write + 0x00000000 + + + IC1F + Input capture 1 filter + 4 + 4 + + + IC1PSC + Input capture 1 prescaler + 2 + 2 + + + CC1S + Capture/Compare 1 + selection + 0 + 2 + + + + + CCER + CCER + capture/compare enable + register + 0x20 + 0x20 + read-write + 0x00000000 + + + CC1NP + Capture/Compare 1 output + Polarity + 3 + 1 + + + CC1P + Capture/Compare 1 output + Polarity + 1 + 1 + + + CC1E + Capture/Compare 1 output + enable + 0 + 1 + + + + + CNT + CNT + counter + 0x24 + 0x20 + read-write + 0x00000000 + + + CNT + counter value + 0 + 16 + + + + + PSC + PSC + prescaler + 0x28 + 0x20 + read-write + 0x00000000 + + + PSC + Prescaler value + 0 + 16 + + + 0 + 65535 + + + + + + + ARR + ARR + auto-reload register + 0x2C + 0x20 + read-write + 0x00000000 + + + ARR + Auto-reload value + 0 + 16 + + + + + 1 + 0x0 + 1-1 + CCR%s + CCR1 + capture/compare register + 0x34 + 0x20 + read-write + 0x00000000 + + + CCR + Capture/Compare value + 0 + 16 + + + + + OR + OR + option register + 0x50 + 0x20 + read-write + 0x00000000 + + + RMP + Input 1 remapping + capability + 0 + 2 + + + + + + + TIM2 + General purpose timers + TIM + 0x40000000 + + 0x0 + 0x400 + registers + + + SPI3 + SPI3 global interrupt + 51 + + + + CR1 + CR1 + control register 1 + 0x0 + 0x20 + read-write + 0x00000000 + + + CKD + Clock division + 8 + 2 + + CKD + read-write + + Div1 + t_DTS = t_CK_INT + 0 + + + Div2 + t_DTS = 2 × t_CK_INT + 1 + + + Div4 + t_DTS = 4 × t_CK_INT + 2 + + + + + ARPE + Auto-reload preload enable + 7 + 1 + + ARPE + read-write + + Disabled + TIMx_APRR register is not buffered + 0 + + + Enabled + TIMx_APRR register is buffered + 1 + + + + + CMS + Center-aligned mode + selection + 5 + 2 + + CMS + read-write + + EdgeAligned + The counter counts up or down depending on the direction bit + 0 + + + CenterAligned1 + The counter counts up and down alternatively. Output compare interrupt flags are set only when the counter is counting down. + 1 + + + CenterAligned2 + The counter counts up and down alternatively. Output compare interrupt flags are set only when the counter is counting up. + 2 + + + CenterAligned3 + The counter counts up and down alternatively. Output compare interrupt flags are set both when the counter is counting up or down. + 3 + + + + + DIR + Direction + 4 + 1 + + DIR + read-write + + Up + Counter used as upcounter + 0 + + + Down + Counter used as downcounter + 1 + + + + + OPM + One-pulse mode + 3 + 1 + + OPM + read-write + + Disabled + Counter is not stopped at update event + 0 + + + Enabled + Counter stops counting at the next update event (clearing the CEN bit) + 1 + + + + + URS + Update request source + 2 + 1 + + URS + read-write + + AnyEvent + Any of counter overflow/underflow, setting UG, or update through slave mode, generates an update interrupt or DMA request + 0 + + + CounterOnly + Only counter overflow/underflow generates an update interrupt or DMA request + 1 + + + + + UDIS + Update disable + 1 + 1 + + UDIS + read-write + + Enabled + Update event enabled + 0 + + + Disabled + Update event disabled + 1 + + + + + CEN + Counter enable + 0 + 1 + + CEN + read-write + + Disabled + Counter disabled + 0 + + + Enabled + Counter enabled + 1 + + + + + + + CR2 + CR2 + control register 2 + 0x4 + 0x20 + read-write + 0x00000000 + + + TI1S + TI1 selection + 7 + 1 + + TI1S + read-write + + Normal + The TIMx_CH1 pin is connected to TI1 input + 0 + + + XOR + The TIMx_CH1, CH2, CH3 pins are connected to TI1 input + 1 + + + + + MMS + Master mode selection + 4 + 3 + + MMS + read-write + + Reset + The UG bit from the TIMx_EGR register is used as trigger output + 0 + + + Enable + The counter enable signal, CNT_EN, is used as trigger output + 1 + + + Update + The update event is selected as trigger output + 2 + + + ComparePulse + The trigger output send a positive pulse when the CC1IF flag it to be set, as soon as a capture or a compare match occurred + 3 + + + CompareOC1 + OC1REF signal is used as trigger output + 4 + + + CompareOC2 + OC2REF signal is used as trigger output + 5 + + + CompareOC3 + OC3REF signal is used as trigger output + 6 + + + CompareOC4 + OC4REF signal is used as trigger output + 7 + + + + + CCDS + Capture/compare DMA + selection + 3 + 1 + + CCDS + read-write + + OnCompare + CCx DMA request sent when CCx event occurs + 0 + + + OnUpdate + CCx DMA request sent when update event occurs + 1 + + + + + + + SMCR + SMCR + slave mode control register + 0x8 + 0x20 + read-write + 0x00000000 + + + ETP + External trigger polarity + 15 + 1 + + ETP + read-write + + NotInverted + ETR is noninverted, active at high level or rising edge + 0 + + + Inverted + ETR is inverted, active at low level or falling edge + 1 + + + + + ECE + External clock enable + 14 + 1 + + ECE + read-write + + Disabled + External clock mode 2 disabled + 0 + + + Enabled + External clock mode 2 enabled. The counter is clocked by any active edge on the ETRF signal. + 1 + + + + + ETPS + External trigger prescaler + 12 + 2 + + ETPS + read-write + + Div1 + Prescaler OFF + 0 + + + Div2 + ETRP frequency divided by 2 + 1 + + + Div4 + ETRP frequency divided by 4 + 2 + + + Div8 + ETRP frequency divided by 8 + 3 + + + + + ETF + External trigger filter + 8 + 4 + + ETF + read-write + + NoFilter + No filter, sampling is done at fDTS + 0 + + + FCK_INT_N2 + fSAMPLING=fCK_INT, N=2 + 1 + + + FCK_INT_N4 + fSAMPLING=fCK_INT, N=4 + 2 + + + FCK_INT_N8 + fSAMPLING=fCK_INT, N=8 + 3 + + + FDTS_Div2_N6 + fSAMPLING=fDTS/2, N=6 + 4 + + + FDTS_Div2_N8 + fSAMPLING=fDTS/2, N=8 + 5 + + + FDTS_Div4_N6 + fSAMPLING=fDTS/4, N=6 + 6 + + + FDTS_Div4_N8 + fSAMPLING=fDTS/4, N=8 + 7 + + + FDTS_Div8_N6 + fSAMPLING=fDTS/8, N=6 + 8 + + + FDTS_Div8_N8 + fSAMPLING=fDTS/8, N=8 + 9 + + + FDTS_Div16_N5 + fSAMPLING=fDTS/16, N=5 + 10 + + + FDTS_Div16_N6 + fSAMPLING=fDTS/16, N=6 + 11 + + + FDTS_Div16_N8 + fSAMPLING=fDTS/16, N=8 + 12 + + + FDTS_Div32_N5 + fSAMPLING=fDTS/32, N=5 + 13 + + + FDTS_Div32_N6 + fSAMPLING=fDTS/32, N=6 + 14 + + + FDTS_Div32_N8 + fSAMPLING=fDTS/32, N=8 + 15 + + + + + MSM + Master/Slave mode + 7 + 1 + + MSM + read-write + + NoSync + No action + 0 + + + Sync + The effect of an event on the trigger input (TRGI) is delayed to allow a perfect synchronization between the current timer and its slaves (through TRGO). It is useful if we want to synchronize several timers on a single external event. + 1 + + + + + TS + Trigger selection + 4 + 3 + + TS + read-write + + ITR0 + Internal Trigger 0 (ITR0) + 0 + + + ITR1 + Internal Trigger 1 (ITR1) + 1 + + + ITR2 + Internal Trigger 2 (ITR2) + 2 + + + TI1F_ED + TI1 Edge Detector (TI1F_ED) + 4 + + + TI1FP1 + Filtered Timer Input 1 (TI1FP1) + 5 + + + TI2FP2 + Filtered Timer Input 2 (TI2FP2) + 6 + + + ETRF + External Trigger input (ETRF) + 7 + + + + + SMS + Slave mode selection + 0 + 3 + + SMS + read-write + + Disabled + Slave mode disabled - if CEN = ‘1 then the prescaler is clocked directly by the internal clock. + 0 + + + Encoder_Mode_1 + Encoder mode 1 - Counter counts up/down on TI2FP1 edge depending on TI1FP2 level. + 1 + + + Encoder_Mode_2 + Encoder mode 2 - Counter counts up/down on TI1FP2 edge depending on TI2FP1 level. + 2 + + + Encoder_Mode_3 + Encoder mode 3 - Counter counts up/down on both TI1FP1 and TI2FP2 edges depending on the level of the other input. + 3 + + + Reset_Mode + Reset Mode - Rising edge of the selected trigger input (TRGI) reinitializes the counter and generates an update of the registers. + 4 + + + Gated_Mode + Gated Mode - The counter clock is enabled when the trigger input (TRGI) is high. The counter stops (but is not reset) as soon as the trigger becomes low. Both start and stop of the counter are controlled. + 5 + + + Trigger_Mode + Trigger Mode - The counter starts at a rising edge of the trigger TRGI (but it is not reset). Only the start of the counter is controlled. + 6 + + + Ext_Clock_Mode + External Clock Mode 1 - Rising edges of the selected trigger (TRGI) clock the counter. + 7 + + + + + + + DIER + DIER + DMA/Interrupt enable register + 0xC + 0x20 + read-write + 0x00000000 + + + TDE + Trigger DMA request enable + 14 + 1 + + TDE + read-write + + Disabled + Trigger DMA request disabled + 0 + + + Enabled + Trigger DMA request enabled + 1 + + + + + CC4DE + Capture/Compare 4 DMA request + enable + 12 + 1 + + + + CC3DE + Capture/Compare 3 DMA request + enable + 11 + 1 + + + + CC2DE + Capture/Compare 2 DMA request + enable + 10 + 1 + + + + CC1DE + Capture/Compare 1 DMA request + enable + 9 + 1 + + CC1DE + read-write + + Disabled + CCx DMA request disabled + 0 + + + Enabled + CCx DMA request enabled + 1 + + + + + UDE + Update DMA request enable + 8 + 1 + + UDE + read-write + + Disabled + Update DMA request disabled + 0 + + + Enabled + Update DMA request enabled + 1 + + + + + TIE + Trigger interrupt enable + 6 + 1 + + TIE + read-write + + Disabled + Trigger interrupt disabled + 0 + + + Enabled + Trigger interrupt enabled + 1 + + + + + CC4IE + Capture/Compare 4 interrupt + enable + 4 + 1 + + + + CC3IE + Capture/Compare 3 interrupt + enable + 3 + 1 + + + + CC2IE + Capture/Compare 2 interrupt + enable + 2 + 1 + + + + CC1IE + Capture/Compare 1 interrupt + enable + 1 + 1 + + CC1IE + read-write + + Disabled + CCx interrupt disabled + 0 + + + Enabled + CCx interrupt enabled + 1 + + + + + UIE + Update interrupt enable + 0 + 1 + + UIE + read-write + + Disabled + Update interrupt disabled + 0 + + + Enabled + Update interrupt enabled + 1 + + + + + + + SR + SR + status register + 0x10 + 0x20 + read-write + 0x00000000 + + + CC4OF + Capture/Compare 4 overcapture + flag + 12 + 1 + zeroToClear + + read + + + write + + + + CC3OF + Capture/Compare 3 overcapture + flag + 11 + 1 + zeroToClear + + read + + + write + + + + CC2OF + Capture/compare 2 overcapture + flag + 10 + 1 + zeroToClear + + read + + + write + + + + CC1OF + Capture/Compare 1 overcapture + flag + 9 + 1 + zeroToClear + + CC1OFR + read + + Overcapture + The counter value has been captured in TIMx_CCRx register while CCxIF flag was already set + 1 + + + + CC1OFW + write + + Clear + Clear flag + 0 + + + + + TIF + Trigger interrupt flag + 6 + 1 + zeroToClear + + TIFR + read + + NoTrigger + No trigger event occurred + 0 + + + Trigger + Trigger interrupt pending + 1 + + + + TIFW + write + + Clear + Clear flag + 0 + + + + + CC4IF + Capture/Compare 4 interrupt + flag + 4 + 1 + zeroToClear + + read + + + write + + + + CC3IF + Capture/Compare 3 interrupt + flag + 3 + 1 + zeroToClear + + read + + + write + + + + CC2IF + Capture/Compare 2 interrupt + flag + 2 + 1 + zeroToClear + + read + + + write + + + + CC1IF + Capture/compare 1 interrupt + flag + 1 + 1 + zeroToClear + + CC1IFR + read + + Match + If CC1 is an output: The content of the counter TIMx_CNT matches the content of the TIMx_CCR1 register. If CC1 is an input: The counter value has been captured in TIMx_CCR1 register. + 1 + + + + CC1IFW + write + + Clear + Clear flag + 0 + + + + + UIF + Update interrupt flag + 0 + 1 + zeroToClear + + UIFR + read + + NoUpdateOccurred + No update occurred + 0 + + + UpdatePending + Update interrupt pending + 1 + + + + UIFW + write + + Clear + Clear flag + 0 + + + + + + + EGR + EGR + event generation register + 0x14 + 0x20 + write-only + 0x00000000 + + + TG + Trigger generation + 6 + 1 + + TGW + write + + Trigger + The TIF flag is set in TIMx_SR register. Related interrupt or DMA transfer can occur if enabled. + 1 + + + + + CC4G + Capture/compare 4 + generation + 4 + 1 + + + + CC3G + Capture/compare 3 + generation + 3 + 1 + + + + CC2G + Capture/compare 2 + generation + 2 + 1 + + + + CC1G + Capture/compare 1 + generation + 1 + 1 + + CC1GW + write + + Trigger + If CC1 is an output: CC1IF flag is set, Corresponding interrupt or DMA request is sent if enabled. If CC1 is an input: The current value of the counter is captured in TIMx_CCR1 register. + 1 + + + + + UG + Update generation + 0 + 1 + + UG + write + + Update + Re-initializes the timer counter and generates an update of the registers. + 1 + + + + + + + CCMR1_Output + CCMR1_Output + capture/compare mode register 1 (output + mode) + 0x18 + 0x20 + read-write + 0x00000000 + + + OC2CE + OC2CE + 15 + 1 + + + OC2M + OC2M + 12 + 3 + + + + OC2PE + OC2PE + 11 + 1 + + OC2PE + read-write + + Disabled + Preload register on CCR2 disabled. New values written to CCR2 are taken into account immediately + 0 + + + Enabled + Preload register on CCR2 enabled. Preload value is loaded into active register on each update event + 1 + + + + + OC2FE + OC2FE + 10 + 1 + + + CC2S + CC2S + 8 + 2 + + CC2S + read-write + + Output + CC2 channel is configured as output + 0 + + + + + OC1CE + OC1CE + 7 + 1 + + + OC1M + OC1M + 4 + 3 + + OC1M + read-write + + Frozen + The comparison between the output compare register TIMx_CCRy and the counter TIMx_CNT has no effect on the outputs + 0 + + + ActiveOnMatch + Set channel to active level on match. OCyREF signal is forced high when the counter matches the capture/compare register + 1 + + + InactiveOnMatch + Set channel to inactive level on match. OCyREF signal is forced low when the counter matches the capture/compare register + 2 + + + Toggle + OCyREF toggles when TIMx_CNT=TIMx_CCRy + 3 + + + ForceInactive + OCyREF is forced low + 4 + + + ForceActive + OCyREF is forced high + 5 + + + PwmMode1 + In upcounting, channel is active as long as TIMx_CNT<TIMx_CCRy else inactive. In downcounting, channel is inactive as long as TIMx_CNT>TIMx_CCRy else active + 6 + + + PwmMode2 + Inversely to PwmMode1 + 7 + + + + + OC1PE + OC1PE + 3 + 1 + + OC1PE + read-write + + Disabled + Preload register on CCR1 disabled. New values written to CCR1 are taken into account immediately + 0 + + + Enabled + Preload register on CCR1 enabled. Preload value is loaded into active register on each update event + 1 + + + + + OC1FE + OC1FE + 2 + 1 + + + CC1S + CC1S + 0 + 2 + + CC1S + read-write + + Output + CC1 channel is configured as output + 0 + + + + + + + CCMR1_Input + CCMR1_Input + capture/compare mode register 1 (input + mode) + CCMR1_Output + 0x18 + 0x20 + read-write + 0x00000000 + + + IC2F + Input capture 2 filter + 12 + 4 + + + 0 + 15 + + + + + IC2PSC + Input capture 2 prescaler + 10 + 2 + + + CC2S + Capture/Compare 2 + selection + 8 + 2 + + CC2S + read-write + + TI2 + CC2 channel is configured as input, IC2 is mapped on TI2 + 1 + + + TI1 + CC2 channel is configured as input, IC2 is mapped on TI1 + 2 + + + TRC + CC2 channel is configured as input, IC2 is mapped on TRC + 3 + + + + + IC1F + Input capture 1 filter + 4 + 4 + + IC1F + read-write + + NoFilter + No filter, sampling is done at fDTS + 0 + + + FCK_INT_N2 + fSAMPLING=fCK_INT, N=2 + 1 + + + FCK_INT_N4 + fSAMPLING=fCK_INT, N=4 + 2 + + + FCK_INT_N8 + fSAMPLING=fCK_INT, N=8 + 3 + + + FDTS_Div2_N6 + fSAMPLING=fDTS/2, N=6 + 4 + + + FDTS_Div2_N8 + fSAMPLING=fDTS/2, N=8 + 5 + + + FDTS_Div4_N6 + fSAMPLING=fDTS/4, N=6 + 6 + + + FDTS_Div4_N8 + fSAMPLING=fDTS/4, N=8 + 7 + + + FDTS_Div8_N6 + fSAMPLING=fDTS/8, N=6 + 8 + + + FDTS_Div8_N8 + fSAMPLING=fDTS/8, N=8 + 9 + + + FDTS_Div16_N5 + fSAMPLING=fDTS/16, N=5 + 10 + + + FDTS_Div16_N6 + fSAMPLING=fDTS/16, N=6 + 11 + + + FDTS_Div16_N8 + fSAMPLING=fDTS/16, N=8 + 12 + + + FDTS_Div32_N5 + fSAMPLING=fDTS/32, N=5 + 13 + + + FDTS_Div32_N6 + fSAMPLING=fDTS/32, N=6 + 14 + + + FDTS_Div32_N8 + fSAMPLING=fDTS/32, N=8 + 15 + + + + + IC1PSC + Input capture 1 prescaler + 2 + 2 + + + CC1S + Capture/Compare 1 + selection + 0 + 2 + + CC1S + read-write + + TI1 + CC1 channel is configured as input, IC1 is mapped on TI1 + 1 + + + TI2 + CC1 channel is configured as input, IC1 is mapped on TI2 + 2 + + + TRC + CC1 channel is configured as input, IC1 is mapped on TRC + 3 + + + + + + + CCMR2_Output + CCMR2_Output + capture/compare mode register 2 (output + mode) + 0x1C + 0x20 + read-write + 0x00000000 + + + OC4CE + O24CE + 15 + 1 + + + OC4M + OC4M + 12 + 3 + + + + OC4PE + OC4PE + 11 + 1 + + OC4PE + read-write + + Disabled + Preload register on CCR4 disabled. New values written to CCR4 are taken into account immediately + 0 + + + Enabled + Preload register on CCR4 enabled. Preload value is loaded into active register on each update event + 1 + + + + + OC4FE + OC4FE + 10 + 1 + + + CC4S + CC4S + 8 + 2 + + CC4S + read-write + + Output + CC4 channel is configured as output + 0 + + + + + OC3CE + OC3CE + 7 + 1 + + + OC3M + OC3M + 4 + 3 + + OC3M + read-write + + Frozen + The comparison between the output compare register TIMx_CCRy and the counter TIMx_CNT has no effect on the outputs + 0 + + + ActiveOnMatch + Set channel to active level on match. OCyREF signal is forced high when the counter matches the capture/compare register + 1 + + + InactiveOnMatch + Set channel to inactive level on match. OCyREF signal is forced low when the counter matches the capture/compare register + 2 + + + Toggle + OCyREF toggles when TIMx_CNT=TIMx_CCRy + 3 + + + ForceInactive + OCyREF is forced low + 4 + + + ForceActive + OCyREF is forced high + 5 + + + PwmMode1 + In upcounting, channel is active as long as TIMx_CNT<TIMx_CCRy else inactive. In downcounting, channel is inactive as long as TIMx_CNT>TIMx_CCRy else active + 6 + + + PwmMode2 + Inversely to PwmMode1 + 7 + + + + + OC3PE + OC3PE + 3 + 1 + + OC3PE + read-write + + Disabled + Preload register on CCR3 disabled. New values written to CCR3 are taken into account immediately + 0 + + + Enabled + Preload register on CCR3 enabled. Preload value is loaded into active register on each update event + 1 + + + + + OC3FE + OC3FE + 2 + 1 + + + CC3S + CC3S + 0 + 2 + + CC3S + read-write + + Output + CC3 channel is configured as output + 0 + + + + + + + CCMR2_Input + CCMR2_Input + capture/compare mode register 2 (input + mode) + CCMR2_Output + 0x1C + 0x20 + read-write + 0x00000000 + + + IC4F + Input capture 4 filter + 12 + 4 + + + 0 + 15 + + + + + IC4PSC + Input capture 4 prescaler + 10 + 2 + + + 0 + 3 + + + + + CC4S + Capture/Compare 4 + selection + 8 + 2 + + CC4S + read-write + + TI4 + CC4 channel is configured as input, IC4 is mapped on TI4 + 1 + + + TI3 + CC4 channel is configured as input, IC4 is mapped on TI3 + 2 + + + TRC + CC4 channel is configured as input, IC4 is mapped on TRC + 3 + + + + + IC3F + Input capture 3 filter + 4 + 4 + + + 0 + 15 + + + + + IC3PSC + Input capture 3 prescaler + 2 + 2 + + + 0 + 3 + + + + + CC3S + Capture/compare 3 + selection + 0 + 2 + + CC3S + read-write + + TI3 + CC3 channel is configured as input, IC3 is mapped on TI3 + 1 + + + TI4 + CC3 channel is configured as input, IC3 is mapped on TI4 + 2 + + + TRC + CC3 channel is configured as input, IC3 is mapped on TRC + 3 + + + + + + + CCER + CCER + capture/compare enable + register + 0x20 + 0x20 + read-write + 0x00000000 + + + CC4NP + Capture/Compare 4 output + Polarity + 15 + 1 + + + CC4P + Capture/Compare 3 output + Polarity + 13 + 1 + + + CC4E + Capture/Compare 4 output + enable + 12 + 1 + + + CC3NP + Capture/Compare 3 output + Polarity + 11 + 1 + + + CC3P + Capture/Compare 3 output + Polarity + 9 + 1 + + + CC3E + Capture/Compare 3 output + enable + 8 + 1 + + + CC2NP + Capture/Compare 2 output + Polarity + 7 + 1 + + + CC2P + Capture/Compare 2 output + Polarity + 5 + 1 + + + CC2E + Capture/Compare 2 output + enable + 4 + 1 + + + CC1NP + Capture/Compare 1 output + Polarity + 3 + 1 + + + CC1P + Capture/Compare 1 output + Polarity + 1 + 1 + + + CC1E + Capture/Compare 1 output + enable + 0 + 1 + + + + + CNT + CNT + counter + 0x24 + 0x20 + read-write + 0x00000000 + + + CNT + Counter value + 0 + 32 + + + 0 + 4294967295 + + + + + + + PSC + PSC + prescaler + 0x28 + 0x20 + read-write + 0x00000000 + + + PSC + Prescaler value + 0 + 16 + + + 0 + 65535 + + + + + + + ARR + ARR + auto-reload register + 0x2C + 0x20 + read-write + 0x00000000 + + + ARR + Auto-reload value + 0 + 32 + + + 0 + 4294967295 + + + + + + + 4 + 0x4 + 1-4 + CCR%s + CCR1 + capture/compare register + 0x34 + 0x20 + read-write + 0x00000000 + + + CCR + Capture/Compare value + 0 + 32 + + + 0 + 4294967295 + + + + + + + DCR + DCR + DMA control register + 0x48 + 0x20 + read-write + 0x00000000 + + + DBL + DMA burst length + 8 + 5 + + + 0 + 18 + + + + + DBA + DMA base address + 0 + 5 + + + 0 + 31 + + + + + + + DMAR + DMAR + DMA address for full transfer + 0x4C + 0x20 + read-write + 0x00000000 + + + DMAB + DMA register for burst + accesses + 0 + 16 + + + + + OR + OR + TIM5 option register + 0x50 + 0x20 + read-write + 0x00000000 + + + ITR1_RMP + Timer Input 4 remap + 10 + 2 + + + + + + + TIM3 + General purpose timers + TIM + 0x40000400 + + 0x0 + 0x400 + registers + + + SPI4 + SPI4 global interrupt + 84 + + + TIM4 + TIM4 global interrupt + 30 + + + TIM5 + TIM5 global interrupt + 50 + + + + CR1 + CR1 + control register 1 + 0x0 + 0x20 + read-write + 0x00000000 + + + CKD + Clock division + 8 + 2 + + CKD + read-write + + Div1 + t_DTS = t_CK_INT + 0 + + + Div2 + t_DTS = 2 × t_CK_INT + 1 + + + Div4 + t_DTS = 4 × t_CK_INT + 2 + + + + + ARPE + Auto-reload preload enable + 7 + 1 + + ARPE + read-write + + Disabled + TIMx_APRR register is not buffered + 0 + + + Enabled + TIMx_APRR register is buffered + 1 + + + + + CMS + Center-aligned mode + selection + 5 + 2 + + CMS + read-write + + EdgeAligned + The counter counts up or down depending on the direction bit + 0 + + + CenterAligned1 + The counter counts up and down alternatively. Output compare interrupt flags are set only when the counter is counting down. + 1 + + + CenterAligned2 + The counter counts up and down alternatively. Output compare interrupt flags are set only when the counter is counting up. + 2 + + + CenterAligned3 + The counter counts up and down alternatively. Output compare interrupt flags are set both when the counter is counting up or down. + 3 + + + + + DIR + Direction + 4 + 1 + + DIR + read-write + + Up + Counter used as upcounter + 0 + + + Down + Counter used as downcounter + 1 + + + + + OPM + One-pulse mode + 3 + 1 + + OPM + read-write + + Disabled + Counter is not stopped at update event + 0 + + + Enabled + Counter stops counting at the next update event (clearing the CEN bit) + 1 + + + + + URS + Update request source + 2 + 1 + + URS + read-write + + AnyEvent + Any of counter overflow/underflow, setting UG, or update through slave mode, generates an update interrupt or DMA request + 0 + + + CounterOnly + Only counter overflow/underflow generates an update interrupt or DMA request + 1 + + + + + UDIS + Update disable + 1 + 1 + + UDIS + read-write + + Enabled + Update event enabled + 0 + + + Disabled + Update event disabled + 1 + + + + + CEN + Counter enable + 0 + 1 + + CEN + read-write + + Disabled + Counter disabled + 0 + + + Enabled + Counter enabled + 1 + + + + + + + CR2 + CR2 + control register 2 + 0x4 + 0x20 + read-write + 0x00000000 + + + TI1S + TI1 selection + 7 + 1 + + TI1S + read-write + + Normal + The TIMx_CH1 pin is connected to TI1 input + 0 + + + XOR + The TIMx_CH1, CH2, CH3 pins are connected to TI1 input + 1 + + + + + MMS + Master mode selection + 4 + 3 + + MMS + read-write + + Reset + The UG bit from the TIMx_EGR register is used as trigger output + 0 + + + Enable + The counter enable signal, CNT_EN, is used as trigger output + 1 + + + Update + The update event is selected as trigger output + 2 + + + ComparePulse + The trigger output send a positive pulse when the CC1IF flag it to be set, as soon as a capture or a compare match occurred + 3 + + + CompareOC1 + OC1REF signal is used as trigger output + 4 + + + CompareOC2 + OC2REF signal is used as trigger output + 5 + + + CompareOC3 + OC3REF signal is used as trigger output + 6 + + + CompareOC4 + OC4REF signal is used as trigger output + 7 + + + + + CCDS + Capture/compare DMA + selection + 3 + 1 + + CCDS + read-write + + OnCompare + CCx DMA request sent when CCx event occurs + 0 + + + OnUpdate + CCx DMA request sent when update event occurs + 1 + + + + + + + SMCR + SMCR + slave mode control register + 0x8 + 0x20 + read-write + 0x00000000 + + + ETP + External trigger polarity + 15 + 1 + + ETP + read-write + + NotInverted + ETR is noninverted, active at high level or rising edge + 0 + + + Inverted + ETR is inverted, active at low level or falling edge + 1 + + + + + ECE + External clock enable + 14 + 1 + + ECE + read-write + + Disabled + External clock mode 2 disabled + 0 + + + Enabled + External clock mode 2 enabled. The counter is clocked by any active edge on the ETRF signal. + 1 + + + + + ETPS + External trigger prescaler + 12 + 2 + + ETPS + read-write + + Div1 + Prescaler OFF + 0 + + + Div2 + ETRP frequency divided by 2 + 1 + + + Div4 + ETRP frequency divided by 4 + 2 + + + Div8 + ETRP frequency divided by 8 + 3 + + + + + ETF + External trigger filter + 8 + 4 + + ETF + read-write + + NoFilter + No filter, sampling is done at fDTS + 0 + + + FCK_INT_N2 + fSAMPLING=fCK_INT, N=2 + 1 + + + FCK_INT_N4 + fSAMPLING=fCK_INT, N=4 + 2 + + + FCK_INT_N8 + fSAMPLING=fCK_INT, N=8 + 3 + + + FDTS_Div2_N6 + fSAMPLING=fDTS/2, N=6 + 4 + + + FDTS_Div2_N8 + fSAMPLING=fDTS/2, N=8 + 5 + + + FDTS_Div4_N6 + fSAMPLING=fDTS/4, N=6 + 6 + + + FDTS_Div4_N8 + fSAMPLING=fDTS/4, N=8 + 7 + + + FDTS_Div8_N6 + fSAMPLING=fDTS/8, N=6 + 8 + + + FDTS_Div8_N8 + fSAMPLING=fDTS/8, N=8 + 9 + + + FDTS_Div16_N5 + fSAMPLING=fDTS/16, N=5 + 10 + + + FDTS_Div16_N6 + fSAMPLING=fDTS/16, N=6 + 11 + + + FDTS_Div16_N8 + fSAMPLING=fDTS/16, N=8 + 12 + + + FDTS_Div32_N5 + fSAMPLING=fDTS/32, N=5 + 13 + + + FDTS_Div32_N6 + fSAMPLING=fDTS/32, N=6 + 14 + + + FDTS_Div32_N8 + fSAMPLING=fDTS/32, N=8 + 15 + + + + + MSM + Master/Slave mode + 7 + 1 + + MSM + read-write + + NoSync + No action + 0 + + + Sync + The effect of an event on the trigger input (TRGI) is delayed to allow a perfect synchronization between the current timer and its slaves (through TRGO). It is useful if we want to synchronize several timers on a single external event. + 1 + + + + + TS + Trigger selection + 4 + 3 + + TS + read-write + + ITR0 + Internal Trigger 0 (ITR0) + 0 + + + ITR1 + Internal Trigger 1 (ITR1) + 1 + + + ITR2 + Internal Trigger 2 (ITR2) + 2 + + + TI1F_ED + TI1 Edge Detector (TI1F_ED) + 4 + + + TI1FP1 + Filtered Timer Input 1 (TI1FP1) + 5 + + + TI2FP2 + Filtered Timer Input 2 (TI2FP2) + 6 + + + ETRF + External Trigger input (ETRF) + 7 + + + + + SMS + Slave mode selection + 0 + 3 + + SMS + read-write + + Disabled + Slave mode disabled - if CEN = ‘1 then the prescaler is clocked directly by the internal clock. + 0 + + + Encoder_Mode_1 + Encoder mode 1 - Counter counts up/down on TI2FP1 edge depending on TI1FP2 level. + 1 + + + Encoder_Mode_2 + Encoder mode 2 - Counter counts up/down on TI1FP2 edge depending on TI2FP1 level. + 2 + + + Encoder_Mode_3 + Encoder mode 3 - Counter counts up/down on both TI1FP1 and TI2FP2 edges depending on the level of the other input. + 3 + + + Reset_Mode + Reset Mode - Rising edge of the selected trigger input (TRGI) reinitializes the counter and generates an update of the registers. + 4 + + + Gated_Mode + Gated Mode - The counter clock is enabled when the trigger input (TRGI) is high. The counter stops (but is not reset) as soon as the trigger becomes low. Both start and stop of the counter are controlled. + 5 + + + Trigger_Mode + Trigger Mode - The counter starts at a rising edge of the trigger TRGI (but it is not reset). Only the start of the counter is controlled. + 6 + + + Ext_Clock_Mode + External Clock Mode 1 - Rising edges of the selected trigger (TRGI) clock the counter. + 7 + + + + + + + DIER + DIER + DMA/Interrupt enable register + 0xC + 0x20 + read-write + 0x00000000 + + + TDE + Trigger DMA request enable + 14 + 1 + + TDE + read-write + + Disabled + Trigger DMA request disabled + 0 + + + Enabled + Trigger DMA request enabled + 1 + + + + + CC4DE + Capture/Compare 4 DMA request + enable + 12 + 1 + + + + CC3DE + Capture/Compare 3 DMA request + enable + 11 + 1 + + + + CC2DE + Capture/Compare 2 DMA request + enable + 10 + 1 + + + + CC1DE + Capture/Compare 1 DMA request + enable + 9 + 1 + + CC1DE + read-write + + Disabled + CCx DMA request disabled + 0 + + + Enabled + CCx DMA request enabled + 1 + + + + + UDE + Update DMA request enable + 8 + 1 + + UDE + read-write + + Disabled + Update DMA request disabled + 0 + + + Enabled + Update DMA request enabled + 1 + + + + + TIE + Trigger interrupt enable + 6 + 1 + + TIE + read-write + + Disabled + Trigger interrupt disabled + 0 + + + Enabled + Trigger interrupt enabled + 1 + + + + + CC4IE + Capture/Compare 4 interrupt + enable + 4 + 1 + + + + CC3IE + Capture/Compare 3 interrupt + enable + 3 + 1 + + + + CC2IE + Capture/Compare 2 interrupt + enable + 2 + 1 + + + + CC1IE + Capture/Compare 1 interrupt + enable + 1 + 1 + + CC1IE + read-write + + Disabled + CCx interrupt disabled + 0 + + + Enabled + CCx interrupt enabled + 1 + + + + + UIE + Update interrupt enable + 0 + 1 + + UIE + read-write + + Disabled + Update interrupt disabled + 0 + + + Enabled + Update interrupt enabled + 1 + + + + + + + SR + SR + status register + 0x10 + 0x20 + read-write + 0x00000000 + + + CC4OF + Capture/Compare 4 overcapture + flag + 12 + 1 + zeroToClear + + read + + + write + + + + CC3OF + Capture/Compare 3 overcapture + flag + 11 + 1 + zeroToClear + + read + + + write + + + + CC2OF + Capture/compare 2 overcapture + flag + 10 + 1 + zeroToClear + + read + + + write + + + + CC1OF + Capture/Compare 1 overcapture + flag + 9 + 1 + zeroToClear + + CC1OFR + read + + Overcapture + The counter value has been captured in TIMx_CCRx register while CCxIF flag was already set + 1 + + + + CC1OFW + write + + Clear + Clear flag + 0 + + + + + TIF + Trigger interrupt flag + 6 + 1 + zeroToClear + + TIFR + read + + NoTrigger + No trigger event occurred + 0 + + + Trigger + Trigger interrupt pending + 1 + + + + TIFW + write + + Clear + Clear flag + 0 + + + + + CC4IF + Capture/Compare 4 interrupt + flag + 4 + 1 + zeroToClear + + read + + + write + + + + CC3IF + Capture/Compare 3 interrupt + flag + 3 + 1 + zeroToClear + + read + + + write + + + + CC2IF + Capture/Compare 2 interrupt + flag + 2 + 1 + zeroToClear + + read + + + write + + + + CC1IF + Capture/compare 1 interrupt + flag + 1 + 1 + zeroToClear + + CC1IFR + read + + Match + If CC1 is an output: The content of the counter TIMx_CNT matches the content of the TIMx_CCR1 register. If CC1 is an input: The counter value has been captured in TIMx_CCR1 register. + 1 + + + + CC1IFW + write + + Clear + Clear flag + 0 + + + + + UIF + Update interrupt flag + 0 + 1 + zeroToClear + + UIFR + read + + NoUpdateOccurred + No update occurred + 0 + + + UpdatePending + Update interrupt pending + 1 + + + + UIFW + write + + Clear + Clear flag + 0 + + + + + + + EGR + EGR + event generation register + 0x14 + 0x20 + write-only + 0x00000000 + + + TG + Trigger generation + 6 + 1 + + TGW + write + + Trigger + The TIF flag is set in TIMx_SR register. Related interrupt or DMA transfer can occur if enabled. + 1 + + + + + CC4G + Capture/compare 4 + generation + 4 + 1 + + + + CC3G + Capture/compare 3 + generation + 3 + 1 + + + + CC2G + Capture/compare 2 + generation + 2 + 1 + + + + CC1G + Capture/compare 1 + generation + 1 + 1 + + CC1GW + write + + Trigger + If CC1 is an output: CC1IF flag is set, Corresponding interrupt or DMA request is sent if enabled. If CC1 is an input: The current value of the counter is captured in TIMx_CCR1 register. + 1 + + + + + UG + Update generation + 0 + 1 + + UG + write + + Update + Re-initializes the timer counter and generates an update of the registers. + 1 + + + + + + + CCMR1_Output + CCMR1_Output + capture/compare mode register 1 (output + mode) + 0x18 + 0x20 + read-write + 0x00000000 + + + OC2CE + OC2CE + 15 + 1 + + + OC2M + OC2M + 12 + 3 + + + + OC2PE + OC2PE + 11 + 1 + + OC2PE + read-write + + Disabled + Preload register on CCR2 disabled. New values written to CCR2 are taken into account immediately + 0 + + + Enabled + Preload register on CCR2 enabled. Preload value is loaded into active register on each update event + 1 + + + + + OC2FE + OC2FE + 10 + 1 + + + CC2S + CC2S + 8 + 2 + + CC2S + read-write + + Output + CC2 channel is configured as output + 0 + + + + + OC1CE + OC1CE + 7 + 1 + + + OC1M + OC1M + 4 + 3 + + OC1M + read-write + + Frozen + The comparison between the output compare register TIMx_CCRy and the counter TIMx_CNT has no effect on the outputs + 0 + + + ActiveOnMatch + Set channel to active level on match. OCyREF signal is forced high when the counter matches the capture/compare register + 1 + + + InactiveOnMatch + Set channel to inactive level on match. OCyREF signal is forced low when the counter matches the capture/compare register + 2 + + + Toggle + OCyREF toggles when TIMx_CNT=TIMx_CCRy + 3 + + + ForceInactive + OCyREF is forced low + 4 + + + ForceActive + OCyREF is forced high + 5 + + + PwmMode1 + In upcounting, channel is active as long as TIMx_CNT<TIMx_CCRy else inactive. In downcounting, channel is inactive as long as TIMx_CNT>TIMx_CCRy else active + 6 + + + PwmMode2 + Inversely to PwmMode1 + 7 + + + + + OC1PE + OC1PE + 3 + 1 + + OC1PE + read-write + + Disabled + Preload register on CCR1 disabled. New values written to CCR1 are taken into account immediately + 0 + + + Enabled + Preload register on CCR1 enabled. Preload value is loaded into active register on each update event + 1 + + + + + OC1FE + OC1FE + 2 + 1 + + + CC1S + CC1S + 0 + 2 + + CC1S + read-write + + Output + CC1 channel is configured as output + 0 + + + + + + + CCMR1_Input + CCMR1_Input + capture/compare mode register 1 (input + mode) + CCMR1_Output + 0x18 + 0x20 + read-write + 0x00000000 + + + IC2F + Input capture 2 filter + 12 + 4 + + + 0 + 15 + + + + + IC2PSC + Input capture 2 prescaler + 10 + 2 + + + CC2S + Capture/Compare 2 + selection + 8 + 2 + + CC2S + read-write + + TI2 + CC2 channel is configured as input, IC2 is mapped on TI2 + 1 + + + TI1 + CC2 channel is configured as input, IC2 is mapped on TI1 + 2 + + + TRC + CC2 channel is configured as input, IC2 is mapped on TRC + 3 + + + + + IC1F + Input capture 1 filter + 4 + 4 + + IC1F + read-write + + NoFilter + No filter, sampling is done at fDTS + 0 + + + FCK_INT_N2 + fSAMPLING=fCK_INT, N=2 + 1 + + + FCK_INT_N4 + fSAMPLING=fCK_INT, N=4 + 2 + + + FCK_INT_N8 + fSAMPLING=fCK_INT, N=8 + 3 + + + FDTS_Div2_N6 + fSAMPLING=fDTS/2, N=6 + 4 + + + FDTS_Div2_N8 + fSAMPLING=fDTS/2, N=8 + 5 + + + FDTS_Div4_N6 + fSAMPLING=fDTS/4, N=6 + 6 + + + FDTS_Div4_N8 + fSAMPLING=fDTS/4, N=8 + 7 + + + FDTS_Div8_N6 + fSAMPLING=fDTS/8, N=6 + 8 + + + FDTS_Div8_N8 + fSAMPLING=fDTS/8, N=8 + 9 + + + FDTS_Div16_N5 + fSAMPLING=fDTS/16, N=5 + 10 + + + FDTS_Div16_N6 + fSAMPLING=fDTS/16, N=6 + 11 + + + FDTS_Div16_N8 + fSAMPLING=fDTS/16, N=8 + 12 + + + FDTS_Div32_N5 + fSAMPLING=fDTS/32, N=5 + 13 + + + FDTS_Div32_N6 + fSAMPLING=fDTS/32, N=6 + 14 + + + FDTS_Div32_N8 + fSAMPLING=fDTS/32, N=8 + 15 + + + + + IC1PSC + Input capture 1 prescaler + 2 + 2 + + + CC1S + Capture/Compare 1 + selection + 0 + 2 + + CC1S + read-write + + TI1 + CC1 channel is configured as input, IC1 is mapped on TI1 + 1 + + + TI2 + CC1 channel is configured as input, IC1 is mapped on TI2 + 2 + + + TRC + CC1 channel is configured as input, IC1 is mapped on TRC + 3 + + + + + + + CCMR2_Output + CCMR2_Output + capture/compare mode register 2 (output + mode) + 0x1C + 0x20 + read-write + 0x00000000 + + + OC4CE + O24CE + 15 + 1 + + + OC4M + OC4M + 12 + 3 + + + + OC4PE + OC4PE + 11 + 1 + + OC4PE + read-write + + Disabled + Preload register on CCR4 disabled. New values written to CCR4 are taken into account immediately + 0 + + + Enabled + Preload register on CCR4 enabled. Preload value is loaded into active register on each update event + 1 + + + + + OC4FE + OC4FE + 10 + 1 + + + CC4S + CC4S + 8 + 2 + + CC4S + read-write + + Output + CC4 channel is configured as output + 0 + + + + + OC3CE + OC3CE + 7 + 1 + + + OC3M + OC3M + 4 + 3 + + OC3M + read-write + + Frozen + The comparison between the output compare register TIMx_CCRy and the counter TIMx_CNT has no effect on the outputs + 0 + + + ActiveOnMatch + Set channel to active level on match. OCyREF signal is forced high when the counter matches the capture/compare register + 1 + + + InactiveOnMatch + Set channel to inactive level on match. OCyREF signal is forced low when the counter matches the capture/compare register + 2 + + + Toggle + OCyREF toggles when TIMx_CNT=TIMx_CCRy + 3 + + + ForceInactive + OCyREF is forced low + 4 + + + ForceActive + OCyREF is forced high + 5 + + + PwmMode1 + In upcounting, channel is active as long as TIMx_CNT<TIMx_CCRy else inactive. In downcounting, channel is inactive as long as TIMx_CNT>TIMx_CCRy else active + 6 + + + PwmMode2 + Inversely to PwmMode1 + 7 + + + + + OC3PE + OC3PE + 3 + 1 + + OC3PE + read-write + + Disabled + Preload register on CCR3 disabled. New values written to CCR3 are taken into account immediately + 0 + + + Enabled + Preload register on CCR3 enabled. Preload value is loaded into active register on each update event + 1 + + + + + OC3FE + OC3FE + 2 + 1 + + + CC3S + CC3S + 0 + 2 + + CC3S + read-write + + Output + CC3 channel is configured as output + 0 + + + + + + + CCMR2_Input + CCMR2_Input + capture/compare mode register 2 (input + mode) + CCMR2_Output + 0x1C + 0x20 + read-write + 0x00000000 + + + IC4F + Input capture 4 filter + 12 + 4 + + + 0 + 15 + + + + + IC4PSC + Input capture 4 prescaler + 10 + 2 + + + 0 + 3 + + + + + CC4S + Capture/Compare 4 + selection + 8 + 2 + + CC4S + read-write + + TI4 + CC4 channel is configured as input, IC4 is mapped on TI4 + 1 + + + TI3 + CC4 channel is configured as input, IC4 is mapped on TI3 + 2 + + + TRC + CC4 channel is configured as input, IC4 is mapped on TRC + 3 + + + + + IC3F + Input capture 3 filter + 4 + 4 + + + 0 + 15 + + + + + IC3PSC + Input capture 3 prescaler + 2 + 2 + + + 0 + 3 + + + + + CC3S + Capture/compare 3 + selection + 0 + 2 + + CC3S + read-write + + TI3 + CC3 channel is configured as input, IC3 is mapped on TI3 + 1 + + + TI4 + CC3 channel is configured as input, IC3 is mapped on TI4 + 2 + + + TRC + CC3 channel is configured as input, IC3 is mapped on TRC + 3 + + + + + + + CCER + CCER + capture/compare enable + register + 0x20 + 0x20 + read-write + 0x00000000 + + + CC4NP + Capture/Compare 4 output + Polarity + 15 + 1 + + + CC4P + Capture/Compare 3 output + Polarity + 13 + 1 + + + CC4E + Capture/Compare 4 output + enable + 12 + 1 + + + CC3NP + Capture/Compare 3 output + Polarity + 11 + 1 + + + CC3P + Capture/Compare 3 output + Polarity + 9 + 1 + + + CC3E + Capture/Compare 3 output + enable + 8 + 1 + + + CC2NP + Capture/Compare 2 output + Polarity + 7 + 1 + + + CC2P + Capture/Compare 2 output + Polarity + 5 + 1 + + + CC2E + Capture/Compare 2 output + enable + 4 + 1 + + + CC1NP + Capture/Compare 1 output + Polarity + 3 + 1 + + + CC1P + Capture/Compare 1 output + Polarity + 1 + 1 + + + CC1E + Capture/Compare 1 output + enable + 0 + 1 + + + + + CNT + CNT + counter + 0x24 + 0x20 + read-write + 0x00000000 + + + CNT + Counter value + 0 + 16 + + + 0 + 65535 + + + + + + + PSC + PSC + prescaler + 0x28 + 0x20 + read-write + 0x00000000 + + + PSC + Prescaler value + 0 + 16 + + + 0 + 65535 + + + + + + + ARR + ARR + auto-reload register + 0x2C + 0x20 + read-write + 0x00000000 + + + ARR + Auto-reload value + 0 + 16 + + + 0 + 65535 + + + + + + + 4 + 0x4 + 1-4 + CCR%s + CCR1 + capture/compare register + 0x34 + 0x20 + read-write + 0x00000000 + + + CCR + Capture/Compare value + 0 + 16 + + + 0 + 65535 + + + + + + + DCR + DCR + DMA control register + 0x48 + 0x20 + read-write + 0x00000000 + + + DBL + DMA burst length + 8 + 5 + + + 0 + 18 + + + + + DBA + DMA base address + 0 + 5 + + + 0 + 31 + + + + + + + DMAR + DMAR + DMA address for full transfer + 0x4C + 0x20 + read-write + 0x00000000 + + + DMAB + DMA register for burst + accesses + 0 + 16 + + + + + + + TIM4 + TIM + 0x40000800 + + + TIM5 + General-purpose-timers + TIM + 0x40000C00 + + 0x0 + 0x400 + registers + + + + CR1 + CR1 + control register 1 + 0x0 + 0x20 + read-write + 0x00000000 + + + CKD + Clock division + 8 + 2 + + CKD + read-write + + Div1 + t_DTS = t_CK_INT + 0 + + + Div2 + t_DTS = 2 × t_CK_INT + 1 + + + Div4 + t_DTS = 4 × t_CK_INT + 2 + + + + + ARPE + Auto-reload preload enable + 7 + 1 + + ARPE + read-write + + Disabled + TIMx_APRR register is not buffered + 0 + + + Enabled + TIMx_APRR register is buffered + 1 + + + + + CMS + Center-aligned mode + selection + 5 + 2 + + CMS + read-write + + EdgeAligned + The counter counts up or down depending on the direction bit + 0 + + + CenterAligned1 + The counter counts up and down alternatively. Output compare interrupt flags are set only when the counter is counting down. + 1 + + + CenterAligned2 + The counter counts up and down alternatively. Output compare interrupt flags are set only when the counter is counting up. + 2 + + + CenterAligned3 + The counter counts up and down alternatively. Output compare interrupt flags are set both when the counter is counting up or down. + 3 + + + + + DIR + Direction + 4 + 1 + + DIR + read-write + + Up + Counter used as upcounter + 0 + + + Down + Counter used as downcounter + 1 + + + + + OPM + One-pulse mode + 3 + 1 + + OPM + read-write + + Disabled + Counter is not stopped at update event + 0 + + + Enabled + Counter stops counting at the next update event (clearing the CEN bit) + 1 + + + + + URS + Update request source + 2 + 1 + + URS + read-write + + AnyEvent + Any of counter overflow/underflow, setting UG, or update through slave mode, generates an update interrupt or DMA request + 0 + + + CounterOnly + Only counter overflow/underflow generates an update interrupt or DMA request + 1 + + + + + UDIS + Update disable + 1 + 1 + + UDIS + read-write + + Enabled + Update event enabled + 0 + + + Disabled + Update event disabled + 1 + + + + + CEN + Counter enable + 0 + 1 + + CEN + read-write + + Disabled + Counter disabled + 0 + + + Enabled + Counter enabled + 1 + + + + + + + CR2 + CR2 + control register 2 + 0x4 + 0x20 + read-write + 0x00000000 + + + TI1S + TI1 selection + 7 + 1 + + TI1S + read-write + + Normal + The TIMx_CH1 pin is connected to TI1 input + 0 + + + XOR + The TIMx_CH1, CH2, CH3 pins are connected to TI1 input + 1 + + + + + MMS + Master mode selection + 4 + 3 + + MMS + read-write + + Reset + The UG bit from the TIMx_EGR register is used as trigger output + 0 + + + Enable + The counter enable signal, CNT_EN, is used as trigger output + 1 + + + Update + The update event is selected as trigger output + 2 + + + ComparePulse + The trigger output send a positive pulse when the CC1IF flag it to be set, as soon as a capture or a compare match occurred + 3 + + + CompareOC1 + OC1REF signal is used as trigger output + 4 + + + CompareOC2 + OC2REF signal is used as trigger output + 5 + + + CompareOC3 + OC3REF signal is used as trigger output + 6 + + + CompareOC4 + OC4REF signal is used as trigger output + 7 + + + + + CCDS + Capture/compare DMA + selection + 3 + 1 + + CCDS + read-write + + OnCompare + CCx DMA request sent when CCx event occurs + 0 + + + OnUpdate + CCx DMA request sent when update event occurs + 1 + + + + + + + SMCR + SMCR + slave mode control register + 0x8 + 0x20 + read-write + 0x00000000 + + + ETP + External trigger polarity + 15 + 1 + + ETP + read-write + + NotInverted + ETR is noninverted, active at high level or rising edge + 0 + + + Inverted + ETR is inverted, active at low level or falling edge + 1 + + + + + ECE + External clock enable + 14 + 1 + + ECE + read-write + + Disabled + External clock mode 2 disabled + 0 + + + Enabled + External clock mode 2 enabled. The counter is clocked by any active edge on the ETRF signal. + 1 + + + + + ETPS + External trigger prescaler + 12 + 2 + + ETPS + read-write + + Div1 + Prescaler OFF + 0 + + + Div2 + ETRP frequency divided by 2 + 1 + + + Div4 + ETRP frequency divided by 4 + 2 + + + Div8 + ETRP frequency divided by 8 + 3 + + + + + ETF + External trigger filter + 8 + 4 + + ETF + read-write + + NoFilter + No filter, sampling is done at fDTS + 0 + + + FCK_INT_N2 + fSAMPLING=fCK_INT, N=2 + 1 + + + FCK_INT_N4 + fSAMPLING=fCK_INT, N=4 + 2 + + + FCK_INT_N8 + fSAMPLING=fCK_INT, N=8 + 3 + + + FDTS_Div2_N6 + fSAMPLING=fDTS/2, N=6 + 4 + + + FDTS_Div2_N8 + fSAMPLING=fDTS/2, N=8 + 5 + + + FDTS_Div4_N6 + fSAMPLING=fDTS/4, N=6 + 6 + + + FDTS_Div4_N8 + fSAMPLING=fDTS/4, N=8 + 7 + + + FDTS_Div8_N6 + fSAMPLING=fDTS/8, N=6 + 8 + + + FDTS_Div8_N8 + fSAMPLING=fDTS/8, N=8 + 9 + + + FDTS_Div16_N5 + fSAMPLING=fDTS/16, N=5 + 10 + + + FDTS_Div16_N6 + fSAMPLING=fDTS/16, N=6 + 11 + + + FDTS_Div16_N8 + fSAMPLING=fDTS/16, N=8 + 12 + + + FDTS_Div32_N5 + fSAMPLING=fDTS/32, N=5 + 13 + + + FDTS_Div32_N6 + fSAMPLING=fDTS/32, N=6 + 14 + + + FDTS_Div32_N8 + fSAMPLING=fDTS/32, N=8 + 15 + + + + + MSM + Master/Slave mode + 7 + 1 + + MSM + read-write + + NoSync + No action + 0 + + + Sync + The effect of an event on the trigger input (TRGI) is delayed to allow a perfect synchronization between the current timer and its slaves (through TRGO). It is useful if we want to synchronize several timers on a single external event. + 1 + + + + + TS + Trigger selection + 4 + 3 + + TS + read-write + + ITR0 + Internal Trigger 0 (ITR0) + 0 + + + ITR1 + Internal Trigger 1 (ITR1) + 1 + + + ITR2 + Internal Trigger 2 (ITR2) + 2 + + + TI1F_ED + TI1 Edge Detector (TI1F_ED) + 4 + + + TI1FP1 + Filtered Timer Input 1 (TI1FP1) + 5 + + + TI2FP2 + Filtered Timer Input 2 (TI2FP2) + 6 + + + ETRF + External Trigger input (ETRF) + 7 + + + + + SMS + Slave mode selection + 0 + 3 + + SMS + read-write + + Disabled + Slave mode disabled - if CEN = ‘1 then the prescaler is clocked directly by the internal clock. + 0 + + + Encoder_Mode_1 + Encoder mode 1 - Counter counts up/down on TI2FP1 edge depending on TI1FP2 level. + 1 + + + Encoder_Mode_2 + Encoder mode 2 - Counter counts up/down on TI1FP2 edge depending on TI2FP1 level. + 2 + + + Encoder_Mode_3 + Encoder mode 3 - Counter counts up/down on both TI1FP1 and TI2FP2 edges depending on the level of the other input. + 3 + + + Reset_Mode + Reset Mode - Rising edge of the selected trigger input (TRGI) reinitializes the counter and generates an update of the registers. + 4 + + + Gated_Mode + Gated Mode - The counter clock is enabled when the trigger input (TRGI) is high. The counter stops (but is not reset) as soon as the trigger becomes low. Both start and stop of the counter are controlled. + 5 + + + Trigger_Mode + Trigger Mode - The counter starts at a rising edge of the trigger TRGI (but it is not reset). Only the start of the counter is controlled. + 6 + + + Ext_Clock_Mode + External Clock Mode 1 - Rising edges of the selected trigger (TRGI) clock the counter. + 7 + + + + + + + DIER + DIER + DMA/Interrupt enable register + 0xC + 0x20 + read-write + 0x00000000 + + + TDE + Trigger DMA request enable + 14 + 1 + + TDE + read-write + + Disabled + Trigger DMA request disabled + 0 + + + Enabled + Trigger DMA request enabled + 1 + + + + + CC4DE + Capture/Compare 4 DMA request + enable + 12 + 1 + + + + CC3DE + Capture/Compare 3 DMA request + enable + 11 + 1 + + + + CC2DE + Capture/Compare 2 DMA request + enable + 10 + 1 + + + + CC1DE + Capture/Compare 1 DMA request + enable + 9 + 1 + + CC1DE + read-write + + Disabled + CCx DMA request disabled + 0 + + + Enabled + CCx DMA request enabled + 1 + + + + + UDE + Update DMA request enable + 8 + 1 + + UDE + read-write + + Disabled + Update DMA request disabled + 0 + + + Enabled + Update DMA request enabled + 1 + + + + + TIE + Trigger interrupt enable + 6 + 1 + + TIE + read-write + + Disabled + Trigger interrupt disabled + 0 + + + Enabled + Trigger interrupt enabled + 1 + + + + + CC4IE + Capture/Compare 4 interrupt + enable + 4 + 1 + + + + CC3IE + Capture/Compare 3 interrupt + enable + 3 + 1 + + + + CC2IE + Capture/Compare 2 interrupt + enable + 2 + 1 + + + + CC1IE + Capture/Compare 1 interrupt + enable + 1 + 1 + + CC1IE + read-write + + Disabled + CCx interrupt disabled + 0 + + + Enabled + CCx interrupt enabled + 1 + + + + + UIE + Update interrupt enable + 0 + 1 + + UIE + read-write + + Disabled + Update interrupt disabled + 0 + + + Enabled + Update interrupt enabled + 1 + + + + + + + SR + SR + status register + 0x10 + 0x20 + read-write + 0x00000000 + + + CC4OF + Capture/Compare 4 overcapture + flag + 12 + 1 + zeroToClear + + read + + + write + + + + CC3OF + Capture/Compare 3 overcapture + flag + 11 + 1 + zeroToClear + + read + + + write + + + + CC2OF + Capture/compare 2 overcapture + flag + 10 + 1 + zeroToClear + + read + + + write + + + + CC1OF + Capture/Compare 1 overcapture + flag + 9 + 1 + zeroToClear + + CC1OFR + read + + Overcapture + The counter value has been captured in TIMx_CCRx register while CCxIF flag was already set + 1 + + + + CC1OFW + write + + Clear + Clear flag + 0 + + + + + TIF + Trigger interrupt flag + 6 + 1 + zeroToClear + + TIFR + read + + NoTrigger + No trigger event occurred + 0 + + + Trigger + Trigger interrupt pending + 1 + + + + TIFW + write + + Clear + Clear flag + 0 + + + + + CC4IF + Capture/Compare 4 interrupt + flag + 4 + 1 + zeroToClear + + read + + + write + + + + CC3IF + Capture/Compare 3 interrupt + flag + 3 + 1 + zeroToClear + + read + + + write + + + + CC2IF + Capture/Compare 2 interrupt + flag + 2 + 1 + zeroToClear + + read + + + write + + + + CC1IF + Capture/compare 1 interrupt + flag + 1 + 1 + zeroToClear + + CC1IFR + read + + Match + If CC1 is an output: The content of the counter TIMx_CNT matches the content of the TIMx_CCR1 register. If CC1 is an input: The counter value has been captured in TIMx_CCR1 register. + 1 + + + + CC1IFW + write + + Clear + Clear flag + 0 + + + + + UIF + Update interrupt flag + 0 + 1 + zeroToClear + + UIFR + read + + NoUpdateOccurred + No update occurred + 0 + + + UpdatePending + Update interrupt pending + 1 + + + + UIFW + write + + Clear + Clear flag + 0 + + + + + + + EGR + EGR + event generation register + 0x14 + 0x20 + write-only + 0x00000000 + + + TG + Trigger generation + 6 + 1 + + TGW + write + + Trigger + The TIF flag is set in TIMx_SR register. Related interrupt or DMA transfer can occur if enabled. + 1 + + + + + CC4G + Capture/compare 4 + generation + 4 + 1 + + + + CC3G + Capture/compare 3 + generation + 3 + 1 + + + + CC2G + Capture/compare 2 + generation + 2 + 1 + + + + CC1G + Capture/compare 1 + generation + 1 + 1 + + CC1GW + write + + Trigger + If CC1 is an output: CC1IF flag is set, Corresponding interrupt or DMA request is sent if enabled. If CC1 is an input: The current value of the counter is captured in TIMx_CCR1 register. + 1 + + + + + UG + Update generation + 0 + 1 + + UG + write + + Update + Re-initializes the timer counter and generates an update of the registers. + 1 + + + + + + + CCMR1_Output + CCMR1_Output + capture/compare mode register 1 (output + mode) + 0x18 + 0x20 + read-write + 0x00000000 + + + OC2CE + OC2CE + 15 + 1 + + + OC2M + OC2M + 12 + 3 + + + + OC2PE + OC2PE + 11 + 1 + + OC2PE + read-write + + Disabled + Preload register on CCR2 disabled. New values written to CCR2 are taken into account immediately + 0 + + + Enabled + Preload register on CCR2 enabled. Preload value is loaded into active register on each update event + 1 + + + + + OC2FE + OC2FE + 10 + 1 + + + CC2S + CC2S + 8 + 2 + + CC2S + read-write + + Output + CC2 channel is configured as output + 0 + + + + + OC1CE + OC1CE + 7 + 1 + + + OC1M + OC1M + 4 + 3 + + OC1M + read-write + + Frozen + The comparison between the output compare register TIMx_CCRy and the counter TIMx_CNT has no effect on the outputs + 0 + + + ActiveOnMatch + Set channel to active level on match. OCyREF signal is forced high when the counter matches the capture/compare register + 1 + + + InactiveOnMatch + Set channel to inactive level on match. OCyREF signal is forced low when the counter matches the capture/compare register + 2 + + + Toggle + OCyREF toggles when TIMx_CNT=TIMx_CCRy + 3 + + + ForceInactive + OCyREF is forced low + 4 + + + ForceActive + OCyREF is forced high + 5 + + + PwmMode1 + In upcounting, channel is active as long as TIMx_CNT<TIMx_CCRy else inactive. In downcounting, channel is inactive as long as TIMx_CNT>TIMx_CCRy else active + 6 + + + PwmMode2 + Inversely to PwmMode1 + 7 + + + + + OC1PE + OC1PE + 3 + 1 + + OC1PE + read-write + + Disabled + Preload register on CCR1 disabled. New values written to CCR1 are taken into account immediately + 0 + + + Enabled + Preload register on CCR1 enabled. Preload value is loaded into active register on each update event + 1 + + + + + OC1FE + OC1FE + 2 + 1 + + + CC1S + CC1S + 0 + 2 + + CC1S + read-write + + Output + CC1 channel is configured as output + 0 + + + + + + + CCMR1_Input + CCMR1_Input + capture/compare mode register 1 (input + mode) + CCMR1_Output + 0x18 + 0x20 + read-write + 0x00000000 + + + IC2F + Input capture 2 filter + 12 + 4 + + + 0 + 15 + + + + + IC2PSC + Input capture 2 prescaler + 10 + 2 + + + CC2S + Capture/Compare 2 + selection + 8 + 2 + + CC2S + read-write + + TI2 + CC2 channel is configured as input, IC2 is mapped on TI2 + 1 + + + TI1 + CC2 channel is configured as input, IC2 is mapped on TI1 + 2 + + + TRC + CC2 channel is configured as input, IC2 is mapped on TRC + 3 + + + + + IC1F + Input capture 1 filter + 4 + 4 + + IC1F + read-write + + NoFilter + No filter, sampling is done at fDTS + 0 + + + FCK_INT_N2 + fSAMPLING=fCK_INT, N=2 + 1 + + + FCK_INT_N4 + fSAMPLING=fCK_INT, N=4 + 2 + + + FCK_INT_N8 + fSAMPLING=fCK_INT, N=8 + 3 + + + FDTS_Div2_N6 + fSAMPLING=fDTS/2, N=6 + 4 + + + FDTS_Div2_N8 + fSAMPLING=fDTS/2, N=8 + 5 + + + FDTS_Div4_N6 + fSAMPLING=fDTS/4, N=6 + 6 + + + FDTS_Div4_N8 + fSAMPLING=fDTS/4, N=8 + 7 + + + FDTS_Div8_N6 + fSAMPLING=fDTS/8, N=6 + 8 + + + FDTS_Div8_N8 + fSAMPLING=fDTS/8, N=8 + 9 + + + FDTS_Div16_N5 + fSAMPLING=fDTS/16, N=5 + 10 + + + FDTS_Div16_N6 + fSAMPLING=fDTS/16, N=6 + 11 + + + FDTS_Div16_N8 + fSAMPLING=fDTS/16, N=8 + 12 + + + FDTS_Div32_N5 + fSAMPLING=fDTS/32, N=5 + 13 + + + FDTS_Div32_N6 + fSAMPLING=fDTS/32, N=6 + 14 + + + FDTS_Div32_N8 + fSAMPLING=fDTS/32, N=8 + 15 + + + + + IC1PSC + Input capture 1 prescaler + 2 + 2 + + + CC1S + Capture/Compare 1 + selection + 0 + 2 + + CC1S + read-write + + TI1 + CC1 channel is configured as input, IC1 is mapped on TI1 + 1 + + + TI2 + CC1 channel is configured as input, IC1 is mapped on TI2 + 2 + + + TRC + CC1 channel is configured as input, IC1 is mapped on TRC + 3 + + + + + + + CCMR2_Output + CCMR2_Output + capture/compare mode register 2 (output + mode) + 0x1C + 0x20 + read-write + 0x00000000 + + + OC4CE + O24CE + 15 + 1 + + + OC4M + OC4M + 12 + 3 + + + + OC4PE + OC4PE + 11 + 1 + + OC4PE + read-write + + Disabled + Preload register on CCR4 disabled. New values written to CCR4 are taken into account immediately + 0 + + + Enabled + Preload register on CCR4 enabled. Preload value is loaded into active register on each update event + 1 + + + + + OC4FE + OC4FE + 10 + 1 + + + CC4S + CC4S + 8 + 2 + + CC4S + read-write + + Output + CC4 channel is configured as output + 0 + + + + + OC3CE + OC3CE + 7 + 1 + + + OC3M + OC3M + 4 + 3 + + OC3M + read-write + + Frozen + The comparison between the output compare register TIMx_CCRy and the counter TIMx_CNT has no effect on the outputs + 0 + + + ActiveOnMatch + Set channel to active level on match. OCyREF signal is forced high when the counter matches the capture/compare register + 1 + + + InactiveOnMatch + Set channel to inactive level on match. OCyREF signal is forced low when the counter matches the capture/compare register + 2 + + + Toggle + OCyREF toggles when TIMx_CNT=TIMx_CCRy + 3 + + + ForceInactive + OCyREF is forced low + 4 + + + ForceActive + OCyREF is forced high + 5 + + + PwmMode1 + In upcounting, channel is active as long as TIMx_CNT<TIMx_CCRy else inactive. In downcounting, channel is inactive as long as TIMx_CNT>TIMx_CCRy else active + 6 + + + PwmMode2 + Inversely to PwmMode1 + 7 + + + + + OC3PE + OC3PE + 3 + 1 + + OC3PE + read-write + + Disabled + Preload register on CCR3 disabled. New values written to CCR3 are taken into account immediately + 0 + + + Enabled + Preload register on CCR3 enabled. Preload value is loaded into active register on each update event + 1 + + + + + OC3FE + OC3FE + 2 + 1 + + + CC3S + CC3S + 0 + 2 + + CC3S + read-write + + Output + CC3 channel is configured as output + 0 + + + + + + + CCMR2_Input + CCMR2_Input + capture/compare mode register 2 (input + mode) + CCMR2_Output + 0x1C + 0x20 + read-write + 0x00000000 + + + IC4F + Input capture 4 filter + 12 + 4 + + + 0 + 15 + + + + + IC4PSC + Input capture 4 prescaler + 10 + 2 + + + 0 + 3 + + + + + CC4S + Capture/Compare 4 + selection + 8 + 2 + + CC4S + read-write + + TI4 + CC4 channel is configured as input, IC4 is mapped on TI4 + 1 + + + TI3 + CC4 channel is configured as input, IC4 is mapped on TI3 + 2 + + + TRC + CC4 channel is configured as input, IC4 is mapped on TRC + 3 + + + + + IC3F + Input capture 3 filter + 4 + 4 + + + 0 + 15 + + + + + IC3PSC + Input capture 3 prescaler + 2 + 2 + + + 0 + 3 + + + + + CC3S + Capture/compare 3 + selection + 0 + 2 + + CC3S + read-write + + TI3 + CC3 channel is configured as input, IC3 is mapped on TI3 + 1 + + + TI4 + CC3 channel is configured as input, IC3 is mapped on TI4 + 2 + + + TRC + CC3 channel is configured as input, IC3 is mapped on TRC + 3 + + + + + + + CCER + CCER + capture/compare enable + register + 0x20 + 0x20 + read-write + 0x00000000 + + + CC4NP + Capture/Compare 4 output + Polarity + 15 + 1 + + + CC4P + Capture/Compare 3 output + Polarity + 13 + 1 + + + CC4E + Capture/Compare 4 output + enable + 12 + 1 + + + CC3NP + Capture/Compare 3 output + Polarity + 11 + 1 + + + CC3P + Capture/Compare 3 output + Polarity + 9 + 1 + + + CC3E + Capture/Compare 3 output + enable + 8 + 1 + + + CC2NP + Capture/Compare 2 output + Polarity + 7 + 1 + + + CC2P + Capture/Compare 2 output + Polarity + 5 + 1 + + + CC2E + Capture/Compare 2 output + enable + 4 + 1 + + + CC1NP + Capture/Compare 1 output + Polarity + 3 + 1 + + + CC1P + Capture/Compare 1 output + Polarity + 1 + 1 + + + CC1E + Capture/Compare 1 output + enable + 0 + 1 + + + + + CNT + CNT + counter + 0x24 + 0x20 + read-write + 0x00000000 + + + CNT + Counter value + 0 + 32 + + + 0 + 4294967295 + + + + + + + PSC + PSC + prescaler + 0x28 + 0x20 + read-write + 0x00000000 + + + PSC + Prescaler value + 0 + 16 + + + 0 + 65535 + + + + + + + ARR + ARR + auto-reload register + 0x2C + 0x20 + read-write + 0x00000000 + + + ARR + Auto-reload value + 0 + 32 + + + 0 + 4294967295 + + + + + + + 4 + 0x4 + 1-4 + CCR%s + CCR1 + capture/compare register + 0x34 + 0x20 + read-write + 0x00000000 + + + CCR + Capture/Compare value + 0 + 32 + + + 0 + 4294967295 + + + + + + + DCR + DCR + DMA control register + 0x48 + 0x20 + read-write + 0x00000000 + + + DBL + DMA burst length + 8 + 5 + + + 0 + 18 + + + + + DBA + DMA base address + 0 + 5 + + + 0 + 31 + + + + + + + DMAR + DMAR + DMA address for full transfer + 0x4C + 0x20 + read-write + 0x00000000 + + + DMAB + DMA register for burst + accesses + 0 + 16 + + + + + OR + OR + TIM5 option register + 0x50 + 0x20 + read-write + 0x00000000 + + + IT4_RMP + Timer Input 4 remap + 6 + 2 + + + + + + + TIM9 + General purpose timers + TIM + 0x40014000 + + 0x0 + 0x400 + registers + + + + CR1 + CR1 + control register 1 + 0x0 + 0x20 + read-write + 0x00000000 + + + CKD + Clock division + 8 + 2 + + CKD + read-write + + Div1 + t_DTS = t_CK_INT + 0 + + + Div2 + t_DTS = 2 × t_CK_INT + 1 + + + Div4 + t_DTS = 4 × t_CK_INT + 2 + + + + + ARPE + Auto-reload preload enable + 7 + 1 + + ARPE + read-write + + Disabled + TIMx_APRR register is not buffered + 0 + + + Enabled + TIMx_APRR register is buffered + 1 + + + + + OPM + One-pulse mode + 3 + 1 + + OPM + read-write + + Disabled + Counter is not stopped at update event + 0 + + + Enabled + Counter stops counting at the next update event (clearing the CEN bit) + 1 + + + + + URS + Update request source + 2 + 1 + + URS + read-write + + AnyEvent + Any of counter overflow/underflow, setting UG, or update through slave mode, generates an update interrupt or DMA request + 0 + + + CounterOnly + Only counter overflow/underflow generates an update interrupt or DMA request + 1 + + + + + UDIS + Update disable + 1 + 1 + + UDIS + read-write + + Enabled + Update event enabled + 0 + + + Disabled + Update event disabled + 1 + + + + + CEN + Counter enable + 0 + 1 + + CEN + read-write + + Disabled + Counter disabled + 0 + + + Enabled + Counter enabled + 1 + + + + + + + CR2 + CR2 + control register 2 + 0x4 + 0x20 + read-write + 0x00000000 + + + MMS + Master mode selection + 4 + 3 + + + + + SMCR + SMCR + slave mode control register + 0x8 + 0x20 + read-write + 0x00000000 + + + MSM + Master/Slave mode + 7 + 1 + + + TS + Trigger selection + 4 + 3 + + + SMS + Slave mode selection + 0 + 3 + + + + + DIER + DIER + DMA/Interrupt enable register + 0xC + 0x20 + read-write + 0x00000000 + + + TIE + Trigger interrupt enable + 6 + 1 + + + CC2IE + Capture/Compare 2 interrupt + enable + 2 + 1 + + + CC1IE + Capture/Compare 1 interrupt + enable + 1 + 1 + + + UIE + Update interrupt enable + 0 + 1 + + UIE + read-write + + Disabled + Update interrupt disabled + 0 + + + Enabled + Update interrupt enabled + 1 + + + + + + + SR + SR + status register + 0x10 + 0x20 + read-write + 0x00000000 + + + CC2OF + Capture/compare 2 overcapture + flag + 10 + 1 + + + CC1OF + Capture/Compare 1 overcapture + flag + 9 + 1 + + + TIF + Trigger interrupt flag + 6 + 1 + + + CC2IF + Capture/Compare 2 interrupt + flag + 2 + 1 + + + CC1IF + Capture/compare 1 interrupt + flag + 1 + 1 + + + UIF + Update interrupt flag + 0 + 1 + zeroToClear + + UIFR + read + + NoUpdateOccurred + No update occurred + 0 + + + UpdatePending + Update interrupt pending + 1 + + + + UIFW + write + + Clear + Clear flag + 0 + + + + + + + EGR + EGR + event generation register + 0x14 + 0x20 + write-only + 0x00000000 + + + TG + Trigger generation + 6 + 1 + + + CC2G + Capture/compare 2 + generation + 2 + 1 + + + CC1G + Capture/compare 1 + generation + 1 + 1 + + + UG + Update generation + 0 + 1 + + UG + write + + Update + Re-initializes the timer counter and generates an update of the registers. + 1 + + + + + + + CCMR1_Output + CCMR1_Output + capture/compare mode register 1 (output + mode) + 0x18 + 0x20 + read-write + 0x00000000 + + + OC2M + Output Compare 2 mode + 12 + 3 + + + + OC2PE + Output Compare 2 preload + enable + 11 + 1 + + + OC2FE + Output Compare 2 fast + enable + 10 + 1 + + + CC2S + Capture/Compare 2 + selection + 8 + 2 + + + OC1M + Output Compare 1 mode + 4 + 3 + + OC1M + read-write + + Frozen + The comparison between the output compare register TIMx_CCRy and the counter TIMx_CNT has no effect on the outputs + 0 + + + ActiveOnMatch + Set channel to active level on match. OCyREF signal is forced high when the counter matches the capture/compare register + 1 + + + InactiveOnMatch + Set channel to inactive level on match. OCyREF signal is forced low when the counter matches the capture/compare register + 2 + + + Toggle + OCyREF toggles when TIMx_CNT=TIMx_CCRy + 3 + + + ForceInactive + OCyREF is forced low + 4 + + + ForceActive + OCyREF is forced high + 5 + + + PwmMode1 + In upcounting, channel is active as long as TIMx_CNT<TIMx_CCRy else inactive. In downcounting, channel is inactive as long as TIMx_CNT>TIMx_CCRy else active + 6 + + + PwmMode2 + Inversely to PwmMode1 + 7 + + + + + OC1PE + Output Compare 1 preload + enable + 3 + 1 + + + OC1FE + Output Compare 1 fast + enable + 2 + 1 + + + CC1S + Capture/Compare 1 + selection + 0 + 2 + + + + + CCMR1_Input + CCMR1_Input + capture/compare mode register 1 (input + mode) + CCMR1_Output + 0x18 + 0x20 + read-write + 0x00000000 + + + IC2F + Input capture 2 filter + 12 + 3 + + + IC2PSC + Input capture 2 prescaler + 10 + 2 + + + CC2S + Capture/Compare 2 + selection + 8 + 2 + + + IC1F + Input capture 1 filter + 4 + 3 + + + IC1PSC + Input capture 1 prescaler + 2 + 2 + + + CC1S + Capture/Compare 1 + selection + 0 + 2 + + + + + CCER + CCER + capture/compare enable + register + 0x20 + 0x20 + read-write + 0x00000000 + + + CC2NP + Capture/Compare 2 output + Polarity + 7 + 1 + + + CC2P + Capture/Compare 2 output + Polarity + 5 + 1 + + + CC2E + Capture/Compare 2 output + enable + 4 + 1 + + + CC1NP + Capture/Compare 1 output + Polarity + 3 + 1 + + + CC1P + Capture/Compare 1 output + Polarity + 1 + 1 + + + CC1E + Capture/Compare 1 output + enable + 0 + 1 + + + + + CNT + CNT + counter + 0x24 + 0x20 + read-write + 0x00000000 + + + CNT + counter value + 0 + 16 + + + + + PSC + PSC + prescaler + 0x28 + 0x20 + read-write + 0x00000000 + + + PSC + Prescaler value + 0 + 16 + + + 0 + 65535 + + + + + + + ARR + ARR + auto-reload register + 0x2C + 0x20 + read-write + 0x00000000 + + + ARR + Auto-reload value + 0 + 16 + + + + + 2 + 0x4 + 1-2 + CCR%s + CCR1 + capture/compare register + 0x34 + 0x20 + read-write + 0x00000000 + + + CCR + Capture/Compare value + 0 + 16 + + + + + + + USART1 + Universal synchronous asynchronous receiver + transmitter + USART + 0x40011000 + + 0x0 + 0x400 + registers + + + OTG_FS_WKUP + USB On-The-Go FS Wakeup through EXTI line + interrupt + 42 + + + OTG_FS + USB On The Go FS global + interrupt + 67 + + + USART1 + USART1 global interrupt + 37 + + + USART2 + USART2 global interrupt + 38 + + + USART6 + USART6 global interrupt + 71 + + + + SR + SR + Status register + 0x0 + 0x20 + 0x00C00000 + + + CTS + CTS flag + 9 + 1 + read-write + + + LBD + LIN break detection flag + 8 + 1 + read-write + + + TXE + Transmit data register + empty + 7 + 1 + read-only + + + TC + Transmission complete + 6 + 1 + read-write + + + RXNE + Read data register not + empty + 5 + 1 + read-write + + + IDLE + IDLE line detected + 4 + 1 + read-only + + + ORE + Overrun error + 3 + 1 + read-only + + + NF + Noise detected flag + 2 + 1 + read-only + + + FE + Framing error + 1 + 1 + read-only + + + PE + Parity error + 0 + 1 + read-only + + + + + DR + DR + Data register + 0x4 + 0x20 + read-write + 0x00000000 + + + DR + Data value + 0 + 9 + + + 0 + 511 + + + + + + + BRR + BRR + Baud rate register + 0x8 + 0x20 + read-write + 0x00000000 + + + DIV_Mantissa + mantissa of USARTDIV + 4 + 12 + + + 0 + 4095 + + + + + DIV_Fraction + fraction of USARTDIV + 0 + 4 + + + 0 + 15 + + + + + + + CR1 + CR1 + Control register 1 + 0xC + 0x20 + read-write + 0x00000000 + + + OVER8 + Oversampling mode + 15 + 1 + + OVER8 + read-write + + Oversample16 + Oversampling by 16 + 0 + + + Oversample8 + Oversampling by 8 + 1 + + + + + UE + USART enable + 13 + 1 + + UE + read-write + + Disabled + USART prescaler and outputs disabled + 0 + + + Enabled + USART enabled + 1 + + + + + M + Word length + 12 + 1 + + M + read-write + + M8 + 8 data bits + 0 + + + M9 + 9 data bits + 1 + + + + + WAKE + Wakeup method + 11 + 1 + + WAKE + read-write + + IdleLine + USART wakeup on idle line + 0 + + + AddressMark + USART wakeup on address mark + 1 + + + + + PCE + Parity control enable + 10 + 1 + + PCE + read-write + + Disabled + Parity control disabled + 0 + + + Enabled + Parity control enabled + 1 + + + + + PS + Parity selection + 9 + 1 + + PS + read-write + + Even + Even parity + 0 + + + Odd + Odd parity + 1 + + + + + PEIE + PE interrupt enable + 8 + 1 + + PEIE + read-write + + Disabled + PE interrupt disabled + 0 + + + Enabled + PE interrupt enabled + 1 + + + + + TXEIE + TXE interrupt enable + 7 + 1 + + TXEIE + read-write + + Disabled + TXE interrupt disabled + 0 + + + Enabled + TXE interrupt enabled + 1 + + + + + TCIE + Transmission complete interrupt + enable + 6 + 1 + + TCIE + read-write + + Disabled + TC interrupt disabled + 0 + + + Enabled + TC interrupt enabled + 1 + + + + + RXNEIE + RXNE interrupt enable + 5 + 1 + + RXNEIE + read-write + + Disabled + RXNE interrupt disabled + 0 + + + Enabled + RXNE interrupt enabled + 1 + + + + + IDLEIE + IDLE interrupt enable + 4 + 1 + + IDLEIE + read-write + + Disabled + IDLE interrupt disabled + 0 + + + Enabled + IDLE interrupt enabled + 1 + + + + + TE + Transmitter enable + 3 + 1 + + TE + read-write + + Disabled + Transmitter disabled + 0 + + + Enabled + Transmitter enabled + 1 + + + + + RE + Receiver enable + 2 + 1 + + RE + read-write + + Disabled + Receiver disabled + 0 + + + Enabled + Receiver enabled + 1 + + + + + RWU + Receiver wakeup + 1 + 1 + + RWU + read-write + + Active + Receiver in active mode + 0 + + + Mute + Receiver in mute mode + 1 + + + + + SBK + Send break + 0 + 1 + + SBK + read-write + + NoBreak + No break character is transmitted + 0 + + + Break + Break character transmitted + 1 + + + + + + + CR2 + CR2 + Control register 2 + 0x10 + 0x20 + read-write + 0x00000000 + + + LINEN + LIN mode enable + 14 + 1 + + LINEN + read-write + + Disabled + LIN mode disabled + 0 + + + Enabled + LIN mode enabled + 1 + + + + + STOP + STOP bits + 12 + 2 + + STOP + read-write + + Stop1 + 1 stop bit + 0 + + + Stop0p5 + 0.5 stop bits + 1 + + + Stop2 + 2 stop bits + 2 + + + Stop1p5 + 1.5 stop bits + 3 + + + + + CLKEN + Clock enable + 11 + 1 + + CLKEN + read-write + + Disabled + CK pin disabled + 0 + + + Enabled + CK pin enabled + 1 + + + + + CPOL + Clock polarity + 10 + 1 + + CPOL + read-write + + Low + Steady low value on CK pin outside transmission window + 0 + + + High + Steady high value on CK pin outside transmission window + 1 + + + + + CPHA + Clock phase + 9 + 1 + + CPHA + read-write + + First + The first clock transition is the first data capture edge + 0 + + + Second + The second clock transition is the first data capture edge + 1 + + + + + LBCL + Last bit clock pulse + 8 + 1 + + + LBDIE + LIN break detection interrupt + enable + 6 + 1 + + LBDIE + read-write + + Disabled + LIN break detection interrupt disabled + 0 + + + Enabled + LIN break detection interrupt enabled + 1 + + + + + LBDL + lin break detection length + 5 + 1 + + LBDL + read-write + + LBDL10 + 10-bit break detection + 0 + + + LBDL11 + 11-bit break detection + 1 + + + + + ADD + Address of the USART node + 0 + 4 + + + 0 + 15 + + + + + + + CR3 + CR3 + Control register 3 + 0x14 + 0x20 + read-write + 0x00000000 + + + ONEBIT + One sample bit method + enable + 11 + 1 + + ONEBIT + read-write + + Sample3 + Three sample bit method + 0 + + + Sample1 + One sample bit method + 1 + + + + + CTSIE + CTS interrupt enable + 10 + 1 + + CTSIE + read-write + + Disabled + CTS interrupt disabled + 0 + + + Enabled + CTS interrupt enabled + 1 + + + + + CTSE + CTS enable + 9 + 1 + + CTSE + read-write + + Disabled + CTS hardware flow control disabled + 0 + + + Enabled + CTS hardware flow control enabled + 1 + + + + + RTSE + RTS enable + 8 + 1 + + RTSE + read-write + + Disabled + RTS hardware flow control disabled + 0 + + + Enabled + RTS hardware flow control enabled + 1 + + + + + DMAT + DMA enable transmitter + 7 + 1 + + DMAT + read-write + + Disabled + DMA mode is disabled for transmission + 0 + + + Enabled + DMA mode is enabled for transmission + 1 + + + + + DMAR + DMA enable receiver + 6 + 1 + + DMAR + read-write + + Disabled + DMA mode is disabled for reception + 0 + + + Enabled + DMA mode is enabled for reception + 1 + + + + + SCEN + Smartcard mode enable + 5 + 1 + + SCEN + read-write + + Disabled + Smartcard mode disabled + 0 + + + Enabled + Smartcard mode enabled + 1 + + + + + NACK + Smartcard NACK enable + 4 + 1 + + NACK + read-write + + Disabled + NACK transmission in case of parity error is disabled + 0 + + + Enabled + NACK transmission during parity error is enabled + 1 + + + + + HDSEL + Half-duplex selection + 3 + 1 + + HDSEL + read-write + + FullDuplex + Half duplex mode is not selected + 0 + + + HalfDuplex + Half duplex mode is selected + 1 + + + + + IRLP + IrDA low-power + 2 + 1 + + IRLP + read-write + + Normal + Normal mode + 0 + + + LowPower + Low-power mode + 1 + + + + + IREN + IrDA mode enable + 1 + 1 + + IREN + read-write + + Disabled + IrDA disabled + 0 + + + Enabled + IrDA enabled + 1 + + + + + EIE + Error interrupt enable + 0 + 1 + + EIE + read-write + + Disabled + Error interrupt disabled + 0 + + + Enabled + Error interrupt enabled + 1 + + + + + + + GTPR + GTPR + Guard time and prescaler + register + 0x18 + 0x20 + read-write + 0x00000000 + + + GT + Guard time value + 8 + 8 + + + PSC + Prescaler value + 0 + 8 + + + + + + + USART2 + 0x40004400 + + + USART6 + 0x40011400 + + + WWDG + Window watchdog + WWDG + 0x40002C00 + + 0x0 + 0x400 + registers + + + PVD + PVD through EXTI line detection + interrupt + 1 + + + + CR + CR + Control register + 0x0 + 0x20 + read-write + 0x0000007F + + + WDGA + Activation bit + 7 + 1 + + WDGA + read-write + + Disabled + Watchdog disabled + 0 + + + Enabled + Watchdog enabled + 1 + + + + + T + 7-bit counter (MSB to LSB) + 0 + 7 + + + 0 + 127 + + + + + + + CFR + CFR + Configuration register + 0x4 + 0x20 + read-write + 0x0000007F + + + EWI + Early wakeup interrupt + 9 + 1 + + EWIW + write + + Enable + interrupt occurs whenever the counter reaches the value 0x40 + 1 + + + + + W + 7-bit window value + 0 + 7 + + + 0 + 127 + + + + + WDGTB + Timer base + 7 + 2 + + WDGTB + read-write + + Div1 + Counter clock (PCLK1 div 4096) div 1 + 0 + + + Div2 + Counter clock (PCLK1 div 4096) div 2 + 1 + + + Div4 + Counter clock (PCLK1 div 4096) div 4 + 2 + + + Div8 + Counter clock (PCLK1 div 4096) div 8 + 3 + + + + + + + SR + SR + Status register + 0x8 + 0x20 + read-write + 0x00000000 + + + EWIF + Early wakeup interrupt + flag + 0 + 1 + zeroToClear + + EWIFR + read + + Finished + The EWI Interrupt Service Routine has been serviced + 0 + + + Pending + The EWI Interrupt Service Routine has been triggered + 1 + + + + EWIFW + write + + Finished + The EWI Interrupt Service Routine has been serviced + 0 + + + + + + + + + DMA2 + DMA controller + DMA + 0x40026400 + + 0x0 + 0x400 + registers + + + RCC + RCC global interrupt + 5 + + + DMA1_STREAM0 + DMA1_STREAM0 global interrupt + 11 + + + DMA1_STREAM1 + DMA1_STREAM1 global interrupt + 12 + + + DMA1_STREAM2 + DMA1_STREAM2 global interrupt + 13 + + + DMA1_STREAM3 + DMA1_STREAM3 global interrupt + 14 + + + DMA1_STREAM4 + DMA1_STREAM4 global interrupt + 15 + + + DMA1_STREAM5 + DMA1_STREAM5 global interrupt + 16 + + + DMA1_STREAM6 + DMA1_STREAM6 global interrupt + 17 + + + DMA1_STREAM7 + DMA1_STREAM7 global interrupt + 47 + + + DMA2_STREAM0 + DMA2_STREAM0 global interrupt + 56 + + + DMA2_STREAM1 + DMA2_STREAM1 global interrupt + 57 + + + DMA2_STREAM2 + DMA2_STREAM2 global interrupt + 58 + + + DMA2_STREAM3 + DMA2_STREAM3 global interrupt + 59 + + + DMA2_STREAM4 + DMA2_STREAM4 global interrupt + 60 + + + DMA2_STREAM5 + DMA2_STREAM5 global interrupt + 68 + + + DMA2_STREAM6 + DMA2_STREAM6 global interrupt + 69 + + + DMA2_STREAM7 + DMA2_STREAM7 global interrupt + 70 + + + + LISR + LISR + low interrupt status register + 0x0 + 0x20 + read-only + 0x00000000 + + + TCIF3 + Stream x transfer complete interrupt + flag (x = 3..0) + 27 + 1 + + + + HTIF3 + Stream x half transfer interrupt flag + (x=3..0) + 26 + 1 + + + + TEIF3 + Stream x transfer error interrupt flag + (x=3..0) + 25 + 1 + + + + DMEIF3 + Stream x direct mode error interrupt + flag (x=3..0) + 24 + 1 + + + + FEIF3 + Stream x FIFO error interrupt flag + (x=3..0) + 22 + 1 + + + + TCIF2 + Stream x transfer complete interrupt + flag (x = 3..0) + 21 + 1 + + + + HTIF2 + Stream x half transfer interrupt flag + (x=3..0) + 20 + 1 + + + + TEIF2 + Stream x transfer error interrupt flag + (x=3..0) + 19 + 1 + + + + DMEIF2 + Stream x direct mode error interrupt + flag (x=3..0) + 18 + 1 + + + + FEIF2 + Stream x FIFO error interrupt flag + (x=3..0) + 16 + 1 + + + + TCIF1 + Stream x transfer complete interrupt + flag (x = 3..0) + 11 + 1 + + + + HTIF1 + Stream x half transfer interrupt flag + (x=3..0) + 10 + 1 + + + + TEIF1 + Stream x transfer error interrupt flag + (x=3..0) + 9 + 1 + + + + DMEIF1 + Stream x direct mode error interrupt + flag (x=3..0) + 8 + 1 + + + + FEIF1 + Stream x FIFO error interrupt flag + (x=3..0) + 6 + 1 + + + + TCIF0 + Stream x transfer complete interrupt + flag (x = 3..0) + 5 + 1 + + TCIF0 + read + + NotComplete + No transfer complete event on stream x + 0 + + + Complete + A transfer complete event occurred on stream x + 1 + + + + + HTIF0 + Stream x half transfer interrupt flag + (x=3..0) + 4 + 1 + + HTIF0 + read + + NotHalf + No half transfer event on stream x + 0 + + + Half + A half transfer event occurred on stream x + 1 + + + + + TEIF0 + Stream x transfer error interrupt flag + (x=3..0) + 3 + 1 + + TEIF0 + read + + NoError + No transfer error on stream x + 0 + + + Error + A transfer error occurred on stream x + 1 + + + + + DMEIF0 + Stream x direct mode error interrupt + flag (x=3..0) + 2 + 1 + + DMEIF0 + read + + NoError + No Direct Mode error on stream x + 0 + + + Error + A Direct Mode error occurred on stream x + 1 + + + + + FEIF0 + Stream x FIFO error interrupt flag + (x=3..0) + 0 + 1 + + FEIF0 + read + + NoError + No FIFO error event on stream x + 0 + + + Error + A FIFO error event occurred on stream x + 1 + + + + + + + HISR + HISR + high interrupt status register + 0x4 + 0x20 + read-only + 0x00000000 + + + TCIF7 + Stream x transfer complete interrupt + flag (x=7..4) + 27 + 1 + + + + HTIF7 + Stream x half transfer interrupt flag + (x=7..4) + 26 + 1 + + + + TEIF7 + Stream x transfer error interrupt flag + (x=7..4) + 25 + 1 + + + + DMEIF7 + Stream x direct mode error interrupt + flag (x=7..4) + 24 + 1 + + + + FEIF7 + Stream x FIFO error interrupt flag + (x=7..4) + 22 + 1 + + + + TCIF6 + Stream x transfer complete interrupt + flag (x=7..4) + 21 + 1 + + + + HTIF6 + Stream x half transfer interrupt flag + (x=7..4) + 20 + 1 + + + + TEIF6 + Stream x transfer error interrupt flag + (x=7..4) + 19 + 1 + + + + DMEIF6 + Stream x direct mode error interrupt + flag (x=7..4) + 18 + 1 + + + + FEIF6 + Stream x FIFO error interrupt flag + (x=7..4) + 16 + 1 + + + + TCIF5 + Stream x transfer complete interrupt + flag (x=7..4) + 11 + 1 + + + + HTIF5 + Stream x half transfer interrupt flag + (x=7..4) + 10 + 1 + + + + TEIF5 + Stream x transfer error interrupt flag + (x=7..4) + 9 + 1 + + + + DMEIF5 + Stream x direct mode error interrupt + flag (x=7..4) + 8 + 1 + + + + FEIF5 + Stream x FIFO error interrupt flag + (x=7..4) + 6 + 1 + + + + TCIF4 + Stream x transfer complete interrupt + flag (x=7..4) + 5 + 1 + + TCIF4 + read + + NotComplete + No transfer complete event on stream x + 0 + + + Complete + A transfer complete event occurred on stream x + 1 + + + + + HTIF4 + Stream x half transfer interrupt flag + (x=7..4) + 4 + 1 + + HTIF4 + read + + NotHalf + No half transfer event on stream x + 0 + + + Half + A half transfer event occurred on stream x + 1 + + + + + TEIF4 + Stream x transfer error interrupt flag + (x=7..4) + 3 + 1 + + TEIF4 + read + + NoError + No transfer error on stream x + 0 + + + Error + A transfer error occurred on stream x + 1 + + + + + DMEIF4 + Stream x direct mode error interrupt + flag (x=7..4) + 2 + 1 + + DMEIF4 + read + + NoError + No Direct Mode error on stream x + 0 + + + Error + A Direct Mode error occurred on stream x + 1 + + + + + FEIF4 + Stream x FIFO error interrupt flag + (x=7..4) + 0 + 1 + + FEIF4 + read + + NoError + No FIFO error event on stream x + 0 + + + Error + A FIFO error event occurred on stream x + 1 + + + + + + + LIFCR + LIFCR + low interrupt flag clear + register + 0x8 + 0x20 + write-only + 0x00000000 + + + CTCIF3 + Stream x clear transfer complete + interrupt flag (x = 3..0) + 27 + 1 + + + + CHTIF3 + Stream x clear half transfer interrupt + flag (x = 3..0) + 26 + 1 + + + + CTEIF3 + Stream x clear transfer error interrupt + flag (x = 3..0) + 25 + 1 + + + + CDMEIF3 + Stream x clear direct mode error + interrupt flag (x = 3..0) + 24 + 1 + + + + CFEIF3 + Stream x clear FIFO error interrupt flag + (x = 3..0) + 22 + 1 + + + + CTCIF2 + Stream x clear transfer complete + interrupt flag (x = 3..0) + 21 + 1 + + + + CHTIF2 + Stream x clear half transfer interrupt + flag (x = 3..0) + 20 + 1 + + + + CTEIF2 + Stream x clear transfer error interrupt + flag (x = 3..0) + 19 + 1 + + + + CDMEIF2 + Stream x clear direct mode error + interrupt flag (x = 3..0) + 18 + 1 + + + + CFEIF2 + Stream x clear FIFO error interrupt flag + (x = 3..0) + 16 + 1 + + + + CTCIF1 + Stream x clear transfer complete + interrupt flag (x = 3..0) + 11 + 1 + + + + CHTIF1 + Stream x clear half transfer interrupt + flag (x = 3..0) + 10 + 1 + + + + CTEIF1 + Stream x clear transfer error interrupt + flag (x = 3..0) + 9 + 1 + + + + CDMEIF1 + Stream x clear direct mode error + interrupt flag (x = 3..0) + 8 + 1 + + + + CFEIF1 + Stream x clear FIFO error interrupt flag + (x = 3..0) + 6 + 1 + + + + CTCIF0 + Stream x clear transfer complete + interrupt flag (x = 3..0) + 5 + 1 + + CTCIF0 + write + + Clear + Clear the corresponding TCIFx flag + 1 + + + + + CHTIF0 + Stream x clear half transfer interrupt + flag (x = 3..0) + 4 + 1 + + CHTIF0 + write + + Clear + Clear the corresponding HTIFx flag + 1 + + + + + CTEIF0 + Stream x clear transfer error interrupt + flag (x = 3..0) + 3 + 1 + + CTEIF0 + write + + Clear + Clear the corresponding TEIFx flag + 1 + + + + + CDMEIF0 + Stream x clear direct mode error + interrupt flag (x = 3..0) + 2 + 1 + + CDMEIF0 + write + + Clear + Clear the corresponding DMEIFx flag + 1 + + + + + CFEIF0 + Stream x clear FIFO error interrupt flag + (x = 3..0) + 0 + 1 + + CFEIF0 + write + + Clear + Clear the corresponding CFEIFx flag + 1 + + + + + + + HIFCR + HIFCR + high interrupt flag clear + register + 0xC + 0x20 + write-only + 0x00000000 + + + CTCIF7 + Stream x clear transfer complete + interrupt flag (x = 7..4) + 27 + 1 + + + + CHTIF7 + Stream x clear half transfer interrupt + flag (x = 7..4) + 26 + 1 + + + + CTEIF7 + Stream x clear transfer error interrupt + flag (x = 7..4) + 25 + 1 + + + + CDMEIF7 + Stream x clear direct mode error + interrupt flag (x = 7..4) + 24 + 1 + + + + CFEIF7 + Stream x clear FIFO error interrupt flag + (x = 7..4) + 22 + 1 + + + + CTCIF6 + Stream x clear transfer complete + interrupt flag (x = 7..4) + 21 + 1 + + + + CHTIF6 + Stream x clear half transfer interrupt + flag (x = 7..4) + 20 + 1 + + + + CTEIF6 + Stream x clear transfer error interrupt + flag (x = 7..4) + 19 + 1 + + + + CDMEIF6 + Stream x clear direct mode error + interrupt flag (x = 7..4) + 18 + 1 + + + + CFEIF6 + Stream x clear FIFO error interrupt flag + (x = 7..4) + 16 + 1 + + + + CTCIF5 + Stream x clear transfer complete + interrupt flag (x = 7..4) + 11 + 1 + + + + CHTIF5 + Stream x clear half transfer interrupt + flag (x = 7..4) + 10 + 1 + + + + CTEIF5 + Stream x clear transfer error interrupt + flag (x = 7..4) + 9 + 1 + + + + CDMEIF5 + Stream x clear direct mode error + interrupt flag (x = 7..4) + 8 + 1 + + + + CFEIF5 + Stream x clear FIFO error interrupt flag + (x = 7..4) + 6 + 1 + + + + CTCIF4 + Stream x clear transfer complete + interrupt flag (x = 7..4) + 5 + 1 + + CTCIF4 + write + + Clear + Clear the corresponding TCIFx flag + 1 + + + + + CHTIF4 + Stream x clear half transfer interrupt + flag (x = 7..4) + 4 + 1 + + CHTIF4 + write + + Clear + Clear the corresponding HTIFx flag + 1 + + + + + CTEIF4 + Stream x clear transfer error interrupt + flag (x = 7..4) + 3 + 1 + + CTEIF4 + write + + Clear + Clear the corresponding TEIFx flag + 1 + + + + + CDMEIF4 + Stream x clear direct mode error + interrupt flag (x = 7..4) + 2 + 1 + + CDMEIF4 + write + + Clear + Clear the corresponding DMEIFx flag + 1 + + + + + CFEIF4 + Stream x clear FIFO error interrupt flag + (x = 7..4) + 0 + 1 + + CFEIF4 + write + + Clear + Clear the corresponding CFEIFx flag + 1 + + + + + + + 8 + 0x18 + 0-7 + ST%s + Stream cluster: S?CR, S?NDTR, S?M0AR, S?M1AR and S?FCR registers + 0x10 + + CR + S0CR + stream x configuration + register + 0x0 + 0x20 + read-write + 0x00000000 + + + CHSEL + Channel selection + 25 + 3 + + + 0 + 7 + + + + + MBURST + Memory burst transfer + configuration + 23 + 2 + + + + PBURST + Peripheral burst transfer + configuration + 21 + 2 + + PBURST + read-write + + Single + Single transfer + 0 + + + INCR4 + Incremental burst of 4 beats + 1 + + + INCR8 + Incremental burst of 8 beats + 2 + + + INCR16 + Incremental burst of 16 beats + 3 + + + + + CT + Current target (only in double buffer + mode) + 19 + 1 + + CT + read-write + + Memory0 + The current target memory is Memory 0 + 0 + + + Memory1 + The current target memory is Memory 1 + 1 + + + + + DBM + Double buffer mode + 18 + 1 + + DBM + read-write + + Disabled + No buffer switching at the end of transfer + 0 + + + Enabled + Memory target switched at the end of the DMA transfer + 1 + + + + + PL + Priority level + 16 + 2 + + PL + read-write + + Low + Low + 0 + + + Medium + Medium + 1 + + + High + High + 2 + + + VeryHigh + Very high + 3 + + + + + PINCOS + Peripheral increment offset + size + 15 + 1 + + PINCOS + read-write + + PSIZE + The offset size for the peripheral address calculation is linked to the PSIZE + 0 + + + Fixed4 + The offset size for the peripheral address calculation is fixed to 4 (32-bit alignment) + 1 + + + + + MSIZE + Memory data size + 13 + 2 + + + + PSIZE + Peripheral data size + 11 + 2 + + PSIZE + read-write + + Bits8 + Byte (8-bit) + 0 + + + Bits16 + Half-word (16-bit) + 1 + + + Bits32 + Word (32-bit) + 2 + + + + + MINC + Memory increment mode + 10 + 1 + + + + PINC + Peripheral increment mode + 9 + 1 + + PINC + read-write + + Fixed + Address pointer is fixed + 0 + + + Incremented + Address pointer is incremented after each data transfer + 1 + + + + + CIRC + Circular mode + 8 + 1 + + CIRC + read-write + + Disabled + Circular mode disabled + 0 + + + Enabled + Circular mode enabled + 1 + + + + + DIR + Data transfer direction + 6 + 2 + + DIR + read-write + + PeripheralToMemory + Peripheral-to-memory + 0 + + + MemoryToPeripheral + Memory-to-peripheral + 1 + + + MemoryToMemory + Memory-to-memory + 2 + + + + + PFCTRL + Peripheral flow controller + 5 + 1 + + PFCTRL + read-write + + DMA + The DMA is the flow controller + 0 + + + Peripheral + The peripheral is the flow controller + 1 + + + + + TCIE + Transfer complete interrupt + enable + 4 + 1 + + TCIE + read-write + + Disabled + TC interrupt disabled + 0 + + + Enabled + TC interrupt enabled + 1 + + + + + HTIE + Half transfer interrupt + enable + 3 + 1 + + HTIE + read-write + + Disabled + HT interrupt disabled + 0 + + + Enabled + HT interrupt enabled + 1 + + + + + TEIE + Transfer error interrupt + enable + 2 + 1 + + TEIE + read-write + + Disabled + TE interrupt disabled + 0 + + + Enabled + TE interrupt enabled + 1 + + + + + DMEIE + Direct mode error interrupt + enable + 1 + 1 + + DMEIE + read-write + + Disabled + DME interrupt disabled + 0 + + + Enabled + DME interrupt enabled + 1 + + + + + EN + Stream enable / flag stream ready when + read low + 0 + 1 + + EN + read-write + + Disabled + Stream disabled + 0 + + + Enabled + Stream enabled + 1 + + + + + + + NDTR + S0NDTR + stream x number of data + register + 0x4 + 0x20 + read-write + 0x00000000 + + + NDT + Number of data items to + transfer + 0 + 16 + + + 0 + 65535 + + + + + + + PAR + S0PAR + stream x peripheral address + register + 0x8 + 0x20 + read-write + 0x00000000 + + + PA + Peripheral address + 0 + 32 + + + + + M0AR + S0M0AR + stream x memory 0 address + register + 0xC + 0x20 + read-write + 0x00000000 + + + M0A + Memory 0 address + 0 + 32 + + + + + M1AR + S0M1AR + stream x memory 1 address + register + 0x10 + 0x20 + read-write + 0x00000000 + + + M1A + Memory 1 address (used in case of Double + buffer mode) + 0 + 32 + + + + + FCR + S0FCR + stream x FIFO control register + 0x14 + 0x20 + 0x00000021 + + + FEIE + FIFO error interrupt + enable + 7 + 1 + read-write + + FEIE + read-write + + Disabled + FE interrupt disabled + 0 + + + Enabled + FE interrupt enabled + 1 + + + + + FS + FIFO status + 3 + 3 + read-only + + FS + read + + Quarter1 + 0 < fifo_level < 1/4 + 0 + + + Quarter2 + 1/4 <= fifo_level < 1/2 + 1 + + + Quarter3 + 1/2 <= fifo_level < 3/4 + 2 + + + Quarter4 + 3/4 <= fifo_level < full + 3 + + + Empty + FIFO is empty + 4 + + + Full + FIFO is full + 5 + + + + + DMDIS + Direct mode disable + 2 + 1 + read-write + + DMDIS + read-write + + Enabled + Direct mode is enabled + 0 + + + Disabled + Direct mode is disabled + 1 + + + + + FTH + FIFO threshold selection + 0 + 2 + read-write + + FTH + read-write + + Quarter + 1/4 full FIFO + 0 + + + Half + 1/2 full FIFO + 1 + + + ThreeQuarters + 3/4 full FIFO + 2 + + + Full + Full FIFO + 3 + + + + + + + + + + DMA1 + 0x40026000 + + RTC_WKUP + RTC Wakeup interrupt through the EXTI + line + 3 + + + RTC_Alarm + RTC Alarms (A and B) through EXTI line + interrupt + 41 + + + + GPIOH + General-purpose I/Os + GPIO + 0x40021C00 + + 0x0 + 0x400 + registers + + + SDIO + SDIO global interrupt + 49 + + + + MODER + MODER + GPIO port mode register + 0x0 + 0x20 + read-write + 0x00000000 + + + MODER15 + Port x configuration bits (y = + 0..15) + 30 + 2 + + + + MODER14 + Port x configuration bits (y = + 0..15) + 28 + 2 + + + + MODER13 + Port x configuration bits (y = + 0..15) + 26 + 2 + + + + MODER12 + Port x configuration bits (y = + 0..15) + 24 + 2 + + + + MODER11 + Port x configuration bits (y = + 0..15) + 22 + 2 + + + + MODER10 + Port x configuration bits (y = + 0..15) + 20 + 2 + + + + MODER9 + Port x configuration bits (y = + 0..15) + 18 + 2 + + + + MODER8 + Port x configuration bits (y = + 0..15) + 16 + 2 + + + + MODER7 + Port x configuration bits (y = + 0..15) + 14 + 2 + + + + MODER6 + Port x configuration bits (y = + 0..15) + 12 + 2 + + + + MODER5 + Port x configuration bits (y = + 0..15) + 10 + 2 + + + + MODER4 + Port x configuration bits (y = + 0..15) + 8 + 2 + + + + MODER3 + Port x configuration bits (y = + 0..15) + 6 + 2 + + + + MODER2 + Port x configuration bits (y = + 0..15) + 4 + 2 + + + + MODER1 + Port x configuration bits (y = + 0..15) + 2 + 2 + + + + MODER0 + Port x configuration bits (y = + 0..15) + 0 + 2 + + MODER0 + read-write + + Input + Input mode (reset state) + 0 + + + Output + General purpose output mode + 1 + + + Alternate + Alternate function mode + 2 + + + Analog + Analog mode + 3 + + + + + + + OTYPER + OTYPER + GPIO port output type register + 0x4 + 0x20 + read-write + 0x00000000 + + + OT15 + Port x configuration bits (y = + 0..15) + 15 + 1 + + + + OT14 + Port x configuration bits (y = + 0..15) + 14 + 1 + + + + OT13 + Port x configuration bits (y = + 0..15) + 13 + 1 + + + + OT12 + Port x configuration bits (y = + 0..15) + 12 + 1 + + + + OT11 + Port x configuration bits (y = + 0..15) + 11 + 1 + + + + OT10 + Port x configuration bits (y = + 0..15) + 10 + 1 + + + + OT9 + Port x configuration bits (y = + 0..15) + 9 + 1 + + + + OT8 + Port x configuration bits (y = + 0..15) + 8 + 1 + + + + OT7 + Port x configuration bits (y = + 0..15) + 7 + 1 + + + + OT6 + Port x configuration bits (y = + 0..15) + 6 + 1 + + + + OT5 + Port x configuration bits (y = + 0..15) + 5 + 1 + + + + OT4 + Port x configuration bits (y = + 0..15) + 4 + 1 + + + + OT3 + Port x configuration bits (y = + 0..15) + 3 + 1 + + + + OT2 + Port x configuration bits (y = + 0..15) + 2 + 1 + + + + OT1 + Port x configuration bits (y = + 0..15) + 1 + 1 + + + + OT0 + Port x configuration bits (y = + 0..15) + 0 + 1 + + OT0 + read-write + + PushPull + Output push-pull (reset state) + 0 + + + OpenDrain + Output open-drain + 1 + + + + + + + OSPEEDR + OSPEEDR + GPIO port output speed + register + 0x8 + 0x20 + read-write + 0x00000000 + + + OSPEEDR15 + Port x configuration bits (y = + 0..15) + 30 + 2 + + + + OSPEEDR14 + Port x configuration bits (y = + 0..15) + 28 + 2 + + + + OSPEEDR13 + Port x configuration bits (y = + 0..15) + 26 + 2 + + + + OSPEEDR12 + Port x configuration bits (y = + 0..15) + 24 + 2 + + + + OSPEEDR11 + Port x configuration bits (y = + 0..15) + 22 + 2 + + + + OSPEEDR10 + Port x configuration bits (y = + 0..15) + 20 + 2 + + + + OSPEEDR9 + Port x configuration bits (y = + 0..15) + 18 + 2 + + + + OSPEEDR8 + Port x configuration bits (y = + 0..15) + 16 + 2 + + + + OSPEEDR7 + Port x configuration bits (y = + 0..15) + 14 + 2 + + + + OSPEEDR6 + Port x configuration bits (y = + 0..15) + 12 + 2 + + + + OSPEEDR5 + Port x configuration bits (y = + 0..15) + 10 + 2 + + + + OSPEEDR4 + Port x configuration bits (y = + 0..15) + 8 + 2 + + + + OSPEEDR3 + Port x configuration bits (y = + 0..15) + 6 + 2 + + + + OSPEEDR2 + Port x configuration bits (y = + 0..15) + 4 + 2 + + + + OSPEEDR1 + Port x configuration bits (y = + 0..15) + 2 + 2 + + + + OSPEEDR0 + Port x configuration bits (y = + 0..15) + 0 + 2 + + OSPEEDR0 + read-write + + LowSpeed + Low speed + 0 + + + MediumSpeed + Medium speed + 1 + + + HighSpeed + High speed + 2 + + + VeryHighSpeed + Very high speed + 3 + + + + + + + PUPDR + PUPDR + GPIO port pull-up/pull-down + register + 0xC + 0x20 + read-write + 0x00000000 + + + PUPDR15 + Port x configuration bits (y = + 0..15) + 30 + 2 + + + + PUPDR14 + Port x configuration bits (y = + 0..15) + 28 + 2 + + + + PUPDR13 + Port x configuration bits (y = + 0..15) + 26 + 2 + + + + PUPDR12 + Port x configuration bits (y = + 0..15) + 24 + 2 + + + + PUPDR11 + Port x configuration bits (y = + 0..15) + 22 + 2 + + + + PUPDR10 + Port x configuration bits (y = + 0..15) + 20 + 2 + + + + PUPDR9 + Port x configuration bits (y = + 0..15) + 18 + 2 + + + + PUPDR8 + Port x configuration bits (y = + 0..15) + 16 + 2 + + + + PUPDR7 + Port x configuration bits (y = + 0..15) + 14 + 2 + + + + PUPDR6 + Port x configuration bits (y = + 0..15) + 12 + 2 + + + + PUPDR5 + Port x configuration bits (y = + 0..15) + 10 + 2 + + + + PUPDR4 + Port x configuration bits (y = + 0..15) + 8 + 2 + + + + PUPDR3 + Port x configuration bits (y = + 0..15) + 6 + 2 + + + + PUPDR2 + Port x configuration bits (y = + 0..15) + 4 + 2 + + + + PUPDR1 + Port x configuration bits (y = + 0..15) + 2 + 2 + + + + PUPDR0 + Port x configuration bits (y = + 0..15) + 0 + 2 + + PUPDR0 + read-write + + Floating + No pull-up, pull-down + 0 + + + PullUp + Pull-up + 1 + + + PullDown + Pull-down + 2 + + + + + + + IDR + IDR + GPIO port input data register + 0x10 + 0x20 + read-only + 0x00000000 + + + IDR15 + Port input data (y = + 0..15) + 15 + 1 + + + + IDR14 + Port input data (y = + 0..15) + 14 + 1 + + + + IDR13 + Port input data (y = + 0..15) + 13 + 1 + + + + IDR12 + Port input data (y = + 0..15) + 12 + 1 + + + + IDR11 + Port input data (y = + 0..15) + 11 + 1 + + + + IDR10 + Port input data (y = + 0..15) + 10 + 1 + + + + IDR9 + Port input data (y = + 0..15) + 9 + 1 + + + + IDR8 + Port input data (y = + 0..15) + 8 + 1 + + + + IDR7 + Port input data (y = + 0..15) + 7 + 1 + + + + IDR6 + Port input data (y = + 0..15) + 6 + 1 + + + + IDR5 + Port input data (y = + 0..15) + 5 + 1 + + + + IDR4 + Port input data (y = + 0..15) + 4 + 1 + + + + IDR3 + Port input data (y = + 0..15) + 3 + 1 + + + + IDR2 + Port input data (y = + 0..15) + 2 + 1 + + + + IDR1 + Port input data (y = + 0..15) + 1 + 1 + + + + IDR0 + Port input data (y = + 0..15) + 0 + 1 + + IDR0 + read + + Low + Input is logic low + 0 + + + High + Input is logic high + 1 + + + + + + + ODR + ODR + GPIO port output data register + 0x14 + 0x20 + read-write + 0x00000000 + + + ODR15 + Port output data (y = + 0..15) + 15 + 1 + + + + ODR14 + Port output data (y = + 0..15) + 14 + 1 + + + + ODR13 + Port output data (y = + 0..15) + 13 + 1 + + + + ODR12 + Port output data (y = + 0..15) + 12 + 1 + + + + ODR11 + Port output data (y = + 0..15) + 11 + 1 + + + + ODR10 + Port output data (y = + 0..15) + 10 + 1 + + + + ODR9 + Port output data (y = + 0..15) + 9 + 1 + + + + ODR8 + Port output data (y = + 0..15) + 8 + 1 + + + + ODR7 + Port output data (y = + 0..15) + 7 + 1 + + + + ODR6 + Port output data (y = + 0..15) + 6 + 1 + + + + ODR5 + Port output data (y = + 0..15) + 5 + 1 + + + + ODR4 + Port output data (y = + 0..15) + 4 + 1 + + + + ODR3 + Port output data (y = + 0..15) + 3 + 1 + + + + ODR2 + Port output data (y = + 0..15) + 2 + 1 + + + + ODR1 + Port output data (y = + 0..15) + 1 + 1 + + + + ODR0 + Port output data (y = + 0..15) + 0 + 1 + + ODR0 + read-write + + Low + Set output to logic low + 0 + + + High + Set output to logic high + 1 + + + + + + + BSRR + BSRR + GPIO port bit set/reset + register + 0x18 + 0x20 + write-only + 0x00000000 + + + BR15 + Port x reset bit y (y = + 0..15) + 31 + 1 + + + + BR14 + Port x reset bit y (y = + 0..15) + 30 + 1 + + + + BR13 + Port x reset bit y (y = + 0..15) + 29 + 1 + + + + BR12 + Port x reset bit y (y = + 0..15) + 28 + 1 + + + + BR11 + Port x reset bit y (y = + 0..15) + 27 + 1 + + + + BR10 + Port x reset bit y (y = + 0..15) + 26 + 1 + + + + BR9 + Port x reset bit y (y = + 0..15) + 25 + 1 + + + + BR8 + Port x reset bit y (y = + 0..15) + 24 + 1 + + + + BR7 + Port x reset bit y (y = + 0..15) + 23 + 1 + + + + BR6 + Port x reset bit y (y = + 0..15) + 22 + 1 + + + + BR5 + Port x reset bit y (y = + 0..15) + 21 + 1 + + + + BR4 + Port x reset bit y (y = + 0..15) + 20 + 1 + + + + BR3 + Port x reset bit y (y = + 0..15) + 19 + 1 + + + + BR2 + Port x reset bit y (y = + 0..15) + 18 + 1 + + + + BR1 + Port x reset bit y (y = + 0..15) + 17 + 1 + + + + BR0 + Port x set bit y (y= + 0..15) + 16 + 1 + + BR0W + write + + Reset + Resets the corresponding ODRx bit + 1 + + + + + BS15 + Port x set bit y (y= + 0..15) + 15 + 1 + + + + BS14 + Port x set bit y (y= + 0..15) + 14 + 1 + + + + BS13 + Port x set bit y (y= + 0..15) + 13 + 1 + + + + BS12 + Port x set bit y (y= + 0..15) + 12 + 1 + + + + BS11 + Port x set bit y (y= + 0..15) + 11 + 1 + + + + BS10 + Port x set bit y (y= + 0..15) + 10 + 1 + + + + BS9 + Port x set bit y (y= + 0..15) + 9 + 1 + + + + BS8 + Port x set bit y (y= + 0..15) + 8 + 1 + + + + BS7 + Port x set bit y (y= + 0..15) + 7 + 1 + + + + BS6 + Port x set bit y (y= + 0..15) + 6 + 1 + + + + BS5 + Port x set bit y (y= + 0..15) + 5 + 1 + + + + BS4 + Port x set bit y (y= + 0..15) + 4 + 1 + + + + BS3 + Port x set bit y (y= + 0..15) + 3 + 1 + + + + BS2 + Port x set bit y (y= + 0..15) + 2 + 1 + + + + BS1 + Port x set bit y (y= + 0..15) + 1 + 1 + + + + BS0 + Port x set bit y (y= + 0..15) + 0 + 1 + + BS0W + write + + Set + Sets the corresponding ODRx bit + 1 + + + + + + + LCKR + LCKR + GPIO port configuration lock + register + 0x1C + 0x20 + read-write + 0x00000000 + + + LCKK + Port x lock bit y (y= + 0..15) + 16 + 1 + + LCKK + read-write + + NotActive + Port configuration lock key not active + 0 + + + Active + Port configuration lock key active + 1 + + + + + LCK15 + Port x lock bit y (y= + 0..15) + 15 + 1 + + + + LCK14 + Port x lock bit y (y= + 0..15) + 14 + 1 + + + + LCK13 + Port x lock bit y (y= + 0..15) + 13 + 1 + + + + LCK12 + Port x lock bit y (y= + 0..15) + 12 + 1 + + + + LCK11 + Port x lock bit y (y= + 0..15) + 11 + 1 + + + + LCK10 + Port x lock bit y (y= + 0..15) + 10 + 1 + + + + LCK9 + Port x lock bit y (y= + 0..15) + 9 + 1 + + + + LCK8 + Port x lock bit y (y= + 0..15) + 8 + 1 + + + + LCK7 + Port x lock bit y (y= + 0..15) + 7 + 1 + + + + LCK6 + Port x lock bit y (y= + 0..15) + 6 + 1 + + + + LCK5 + Port x lock bit y (y= + 0..15) + 5 + 1 + + + + LCK4 + Port x lock bit y (y= + 0..15) + 4 + 1 + + + + LCK3 + Port x lock bit y (y= + 0..15) + 3 + 1 + + + + LCK2 + Port x lock bit y (y= + 0..15) + 2 + 1 + + + + LCK1 + Port x lock bit y (y= + 0..15) + 1 + 1 + + + + LCK0 + Port x lock bit y (y= + 0..15) + 0 + 1 + + LCK0 + read-write + + Unlocked + Port configuration not locked + 0 + + + Locked + Port configuration locked + 1 + + + + + + + AFRL + AFRL + GPIO alternate function low + register + 0x20 + 0x20 + read-write + 0x00000000 + + + AFRL7 + Alternate function selection for port x + bit y (y = 0..7) + 28 + 4 + + + + AFRL6 + Alternate function selection for port x + bit y (y = 0..7) + 24 + 4 + + + + AFRL5 + Alternate function selection for port x + bit y (y = 0..7) + 20 + 4 + + + + AFRL4 + Alternate function selection for port x + bit y (y = 0..7) + 16 + 4 + + + + AFRL3 + Alternate function selection for port x + bit y (y = 0..7) + 12 + 4 + + + + AFRL2 + Alternate function selection for port x + bit y (y = 0..7) + 8 + 4 + + + + AFRL1 + Alternate function selection for port x + bit y (y = 0..7) + 4 + 4 + + + + AFRL0 + Alternate function selection for port x + bit y (y = 0..7) + 0 + 4 + + AFRL0 + read-write + + AF0 + AF0 + 0 + + + AF1 + AF1 + 1 + + + AF2 + AF2 + 2 + + + AF3 + AF3 + 3 + + + AF4 + AF4 + 4 + + + AF5 + AF5 + 5 + + + AF6 + AF6 + 6 + + + AF7 + AF7 + 7 + + + AF8 + AF8 + 8 + + + AF9 + AF9 + 9 + + + AF10 + AF10 + 10 + + + AF11 + AF11 + 11 + + + AF12 + AF12 + 12 + + + AF13 + AF13 + 13 + + + AF14 + AF14 + 14 + + + AF15 + AF15 + 15 + + + + + + + AFRH + AFRH + GPIO alternate function high + register + 0x24 + 0x20 + read-write + 0x00000000 + + + AFRH15 + Alternate function selection for port x + bit y (y = 8..15) + 28 + 4 + + + + AFRH14 + Alternate function selection for port x + bit y (y = 8..15) + 24 + 4 + + + + AFRH13 + Alternate function selection for port x + bit y (y = 8..15) + 20 + 4 + + + + AFRH12 + Alternate function selection for port x + bit y (y = 8..15) + 16 + 4 + + + + AFRH11 + Alternate function selection for port x + bit y (y = 8..15) + 12 + 4 + + + + AFRH10 + Alternate function selection for port x + bit y (y = 8..15) + 8 + 4 + + + + AFRH9 + Alternate function selection for port x + bit y (y = 8..15) + 4 + 4 + + + + AFRH8 + Alternate function selection for port x + bit y (y = 8..15) + 0 + 4 + + AFRH8 + read-write + + AF0 + AF0 + 0 + + + AF1 + AF1 + 1 + + + AF2 + AF2 + 2 + + + AF3 + AF3 + 3 + + + AF4 + AF4 + 4 + + + AF5 + AF5 + 5 + + + AF6 + AF6 + 6 + + + AF7 + AF7 + 7 + + + AF8 + AF8 + 8 + + + AF9 + AF9 + 9 + + + AF10 + AF10 + 10 + + + AF11 + AF11 + 11 + + + AF12 + AF12 + 12 + + + AF13 + AF13 + 13 + + + AF14 + AF14 + 14 + + + AF15 + AF15 + 15 + + + + + + + + + GPIOE + 0x40021000 + + + GPIOD + 0x40020C00 + + TIM1_BRK_TIM9 + TIM1 Break interrupt and TIM9 global + interrupt + 24 + + + TIM1_UP_TIM10 + TIM1 Update interrupt and TIM10 global + interrupt + 25 + + + TIM1_TRG_COM_TIM11 + TIM1 Trigger and Commutation interrupts and + TIM11 global interrupt + 26 + + + TIM1_CC + TIM1 Capture Compare interrupt + 27 + + + + GPIOC + 0x40020800 + + TIM1_UP_TIM10 + TIM1 Update interrupt and TIM10 global + interrupt + 25 + + + + GPIOB + General-purpose I/Os + GPIO + 0x40020400 + + 0x0 + 0x400 + registers + + + TIM1_TRG_COM_TIM11 + TIM1 Trigger and Commutation interrupts and + TIM11 global interrupt + 26 + + + + MODER + MODER + GPIO port mode register + 0x0 + 0x20 + read-write + 0x00000280 + + + MODER15 + Port x configuration bits (y = + 0..15) + 30 + 2 + + + + MODER14 + Port x configuration bits (y = + 0..15) + 28 + 2 + + + + MODER13 + Port x configuration bits (y = + 0..15) + 26 + 2 + + + + MODER12 + Port x configuration bits (y = + 0..15) + 24 + 2 + + + + MODER11 + Port x configuration bits (y = + 0..15) + 22 + 2 + + + + MODER10 + Port x configuration bits (y = + 0..15) + 20 + 2 + + + + MODER9 + Port x configuration bits (y = + 0..15) + 18 + 2 + + + + MODER8 + Port x configuration bits (y = + 0..15) + 16 + 2 + + + + MODER7 + Port x configuration bits (y = + 0..15) + 14 + 2 + + + + MODER6 + Port x configuration bits (y = + 0..15) + 12 + 2 + + + + MODER5 + Port x configuration bits (y = + 0..15) + 10 + 2 + + + + MODER4 + Port x configuration bits (y = + 0..15) + 8 + 2 + + + + MODER3 + Port x configuration bits (y = + 0..15) + 6 + 2 + + + + MODER2 + Port x configuration bits (y = + 0..15) + 4 + 2 + + + + MODER1 + Port x configuration bits (y = + 0..15) + 2 + 2 + + + + MODER0 + Port x configuration bits (y = + 0..15) + 0 + 2 + + MODER0 + read-write + + Input + Input mode (reset state) + 0 + + + Output + General purpose output mode + 1 + + + Alternate + Alternate function mode + 2 + + + Analog + Analog mode + 3 + + + + + + + OTYPER + OTYPER + GPIO port output type register + 0x4 + 0x20 + read-write + 0x00000000 + + + OT15 + Port x configuration bits (y = + 0..15) + 15 + 1 + + + + OT14 + Port x configuration bits (y = + 0..15) + 14 + 1 + + + + OT13 + Port x configuration bits (y = + 0..15) + 13 + 1 + + + + OT12 + Port x configuration bits (y = + 0..15) + 12 + 1 + + + + OT11 + Port x configuration bits (y = + 0..15) + 11 + 1 + + + + OT10 + Port x configuration bits (y = + 0..15) + 10 + 1 + + + + OT9 + Port x configuration bits (y = + 0..15) + 9 + 1 + + + + OT8 + Port x configuration bits (y = + 0..15) + 8 + 1 + + + + OT7 + Port x configuration bits (y = + 0..15) + 7 + 1 + + + + OT6 + Port x configuration bits (y = + 0..15) + 6 + 1 + + + + OT5 + Port x configuration bits (y = + 0..15) + 5 + 1 + + + + OT4 + Port x configuration bits (y = + 0..15) + 4 + 1 + + + + OT3 + Port x configuration bits (y = + 0..15) + 3 + 1 + + + + OT2 + Port x configuration bits (y = + 0..15) + 2 + 1 + + + + OT1 + Port x configuration bits (y = + 0..15) + 1 + 1 + + + + OT0 + Port x configuration bits (y = + 0..15) + 0 + 1 + + OT0 + read-write + + PushPull + Output push-pull (reset state) + 0 + + + OpenDrain + Output open-drain + 1 + + + + + + + OSPEEDR + OSPEEDR + GPIO port output speed + register + 0x8 + 0x20 + read-write + 0x000000C0 + + + OSPEEDR15 + Port x configuration bits (y = + 0..15) + 30 + 2 + + + + OSPEEDR14 + Port x configuration bits (y = + 0..15) + 28 + 2 + + + + OSPEEDR13 + Port x configuration bits (y = + 0..15) + 26 + 2 + + + + OSPEEDR12 + Port x configuration bits (y = + 0..15) + 24 + 2 + + + + OSPEEDR11 + Port x configuration bits (y = + 0..15) + 22 + 2 + + + + OSPEEDR10 + Port x configuration bits (y = + 0..15) + 20 + 2 + + + + OSPEEDR9 + Port x configuration bits (y = + 0..15) + 18 + 2 + + + + OSPEEDR8 + Port x configuration bits (y = + 0..15) + 16 + 2 + + + + OSPEEDR7 + Port x configuration bits (y = + 0..15) + 14 + 2 + + + + OSPEEDR6 + Port x configuration bits (y = + 0..15) + 12 + 2 + + + + OSPEEDR5 + Port x configuration bits (y = + 0..15) + 10 + 2 + + + + OSPEEDR4 + Port x configuration bits (y = + 0..15) + 8 + 2 + + + + OSPEEDR3 + Port x configuration bits (y = + 0..15) + 6 + 2 + + + + OSPEEDR2 + Port x configuration bits (y = + 0..15) + 4 + 2 + + + + OSPEEDR1 + Port x configuration bits (y = + 0..15) + 2 + 2 + + + + OSPEEDR0 + Port x configuration bits (y = + 0..15) + 0 + 2 + + OSPEEDR0 + read-write + + LowSpeed + Low speed + 0 + + + MediumSpeed + Medium speed + 1 + + + HighSpeed + High speed + 2 + + + VeryHighSpeed + Very high speed + 3 + + + + + + + PUPDR + PUPDR + GPIO port pull-up/pull-down + register + 0xC + 0x20 + read-write + 0x00000100 + + + PUPDR15 + Port x configuration bits (y = + 0..15) + 30 + 2 + + + + PUPDR14 + Port x configuration bits (y = + 0..15) + 28 + 2 + + + + PUPDR13 + Port x configuration bits (y = + 0..15) + 26 + 2 + + + + PUPDR12 + Port x configuration bits (y = + 0..15) + 24 + 2 + + + + PUPDR11 + Port x configuration bits (y = + 0..15) + 22 + 2 + + + + PUPDR10 + Port x configuration bits (y = + 0..15) + 20 + 2 + + + + PUPDR9 + Port x configuration bits (y = + 0..15) + 18 + 2 + + + + PUPDR8 + Port x configuration bits (y = + 0..15) + 16 + 2 + + + + PUPDR7 + Port x configuration bits (y = + 0..15) + 14 + 2 + + + + PUPDR6 + Port x configuration bits (y = + 0..15) + 12 + 2 + + + + PUPDR5 + Port x configuration bits (y = + 0..15) + 10 + 2 + + + + PUPDR4 + Port x configuration bits (y = + 0..15) + 8 + 2 + + + + PUPDR3 + Port x configuration bits (y = + 0..15) + 6 + 2 + + + + PUPDR2 + Port x configuration bits (y = + 0..15) + 4 + 2 + + + + PUPDR1 + Port x configuration bits (y = + 0..15) + 2 + 2 + + + + PUPDR0 + Port x configuration bits (y = + 0..15) + 0 + 2 + + PUPDR0 + read-write + + Floating + No pull-up, pull-down + 0 + + + PullUp + Pull-up + 1 + + + PullDown + Pull-down + 2 + + + + + + + IDR + IDR + GPIO port input data register + 0x10 + 0x20 + read-only + 0x00000000 + + + IDR15 + Port input data (y = + 0..15) + 15 + 1 + + + + IDR14 + Port input data (y = + 0..15) + 14 + 1 + + + + IDR13 + Port input data (y = + 0..15) + 13 + 1 + + + + IDR12 + Port input data (y = + 0..15) + 12 + 1 + + + + IDR11 + Port input data (y = + 0..15) + 11 + 1 + + + + IDR10 + Port input data (y = + 0..15) + 10 + 1 + + + + IDR9 + Port input data (y = + 0..15) + 9 + 1 + + + + IDR8 + Port input data (y = + 0..15) + 8 + 1 + + + + IDR7 + Port input data (y = + 0..15) + 7 + 1 + + + + IDR6 + Port input data (y = + 0..15) + 6 + 1 + + + + IDR5 + Port input data (y = + 0..15) + 5 + 1 + + + + IDR4 + Port input data (y = + 0..15) + 4 + 1 + + + + IDR3 + Port input data (y = + 0..15) + 3 + 1 + + + + IDR2 + Port input data (y = + 0..15) + 2 + 1 + + + + IDR1 + Port input data (y = + 0..15) + 1 + 1 + + + + IDR0 + Port input data (y = + 0..15) + 0 + 1 + + IDR0 + read + + Low + Input is logic low + 0 + + + High + Input is logic high + 1 + + + + + + + ODR + ODR + GPIO port output data register + 0x14 + 0x20 + read-write + 0x00000000 + + + ODR15 + Port output data (y = + 0..15) + 15 + 1 + + + + ODR14 + Port output data (y = + 0..15) + 14 + 1 + + + + ODR13 + Port output data (y = + 0..15) + 13 + 1 + + + + ODR12 + Port output data (y = + 0..15) + 12 + 1 + + + + ODR11 + Port output data (y = + 0..15) + 11 + 1 + + + + ODR10 + Port output data (y = + 0..15) + 10 + 1 + + + + ODR9 + Port output data (y = + 0..15) + 9 + 1 + + + + ODR8 + Port output data (y = + 0..15) + 8 + 1 + + + + ODR7 + Port output data (y = + 0..15) + 7 + 1 + + + + ODR6 + Port output data (y = + 0..15) + 6 + 1 + + + + ODR5 + Port output data (y = + 0..15) + 5 + 1 + + + + ODR4 + Port output data (y = + 0..15) + 4 + 1 + + + + ODR3 + Port output data (y = + 0..15) + 3 + 1 + + + + ODR2 + Port output data (y = + 0..15) + 2 + 1 + + + + ODR1 + Port output data (y = + 0..15) + 1 + 1 + + + + ODR0 + Port output data (y = + 0..15) + 0 + 1 + + ODR0 + read-write + + Low + Set output to logic low + 0 + + + High + Set output to logic high + 1 + + + + + + + BSRR + BSRR + GPIO port bit set/reset + register + 0x18 + 0x20 + write-only + 0x00000000 + + + BR15 + Port x reset bit y (y = + 0..15) + 31 + 1 + + + + BR14 + Port x reset bit y (y = + 0..15) + 30 + 1 + + + + BR13 + Port x reset bit y (y = + 0..15) + 29 + 1 + + + + BR12 + Port x reset bit y (y = + 0..15) + 28 + 1 + + + + BR11 + Port x reset bit y (y = + 0..15) + 27 + 1 + + + + BR10 + Port x reset bit y (y = + 0..15) + 26 + 1 + + + + BR9 + Port x reset bit y (y = + 0..15) + 25 + 1 + + + + BR8 + Port x reset bit y (y = + 0..15) + 24 + 1 + + + + BR7 + Port x reset bit y (y = + 0..15) + 23 + 1 + + + + BR6 + Port x reset bit y (y = + 0..15) + 22 + 1 + + + + BR5 + Port x reset bit y (y = + 0..15) + 21 + 1 + + + + BR4 + Port x reset bit y (y = + 0..15) + 20 + 1 + + + + BR3 + Port x reset bit y (y = + 0..15) + 19 + 1 + + + + BR2 + Port x reset bit y (y = + 0..15) + 18 + 1 + + + + BR1 + Port x reset bit y (y = + 0..15) + 17 + 1 + + + + BR0 + Port x set bit y (y= + 0..15) + 16 + 1 + + BR0W + write + + Reset + Resets the corresponding ODRx bit + 1 + + + + + BS15 + Port x set bit y (y= + 0..15) + 15 + 1 + + + + BS14 + Port x set bit y (y= + 0..15) + 14 + 1 + + + + BS13 + Port x set bit y (y= + 0..15) + 13 + 1 + + + + BS12 + Port x set bit y (y= + 0..15) + 12 + 1 + + + + BS11 + Port x set bit y (y= + 0..15) + 11 + 1 + + + + BS10 + Port x set bit y (y= + 0..15) + 10 + 1 + + + + BS9 + Port x set bit y (y= + 0..15) + 9 + 1 + + + + BS8 + Port x set bit y (y= + 0..15) + 8 + 1 + + + + BS7 + Port x set bit y (y= + 0..15) + 7 + 1 + + + + BS6 + Port x set bit y (y= + 0..15) + 6 + 1 + + + + BS5 + Port x set bit y (y= + 0..15) + 5 + 1 + + + + BS4 + Port x set bit y (y= + 0..15) + 4 + 1 + + + + BS3 + Port x set bit y (y= + 0..15) + 3 + 1 + + + + BS2 + Port x set bit y (y= + 0..15) + 2 + 1 + + + + BS1 + Port x set bit y (y= + 0..15) + 1 + 1 + + + + BS0 + Port x set bit y (y= + 0..15) + 0 + 1 + + BS0W + write + + Set + Sets the corresponding ODRx bit + 1 + + + + + + + LCKR + LCKR + GPIO port configuration lock + register + 0x1C + 0x20 + read-write + 0x00000000 + + + LCKK + Port x lock bit y (y= + 0..15) + 16 + 1 + + LCKK + read-write + + NotActive + Port configuration lock key not active + 0 + + + Active + Port configuration lock key active + 1 + + + + + LCK15 + Port x lock bit y (y= + 0..15) + 15 + 1 + + + + LCK14 + Port x lock bit y (y= + 0..15) + 14 + 1 + + + + LCK13 + Port x lock bit y (y= + 0..15) + 13 + 1 + + + + LCK12 + Port x lock bit y (y= + 0..15) + 12 + 1 + + + + LCK11 + Port x lock bit y (y= + 0..15) + 11 + 1 + + + + LCK10 + Port x lock bit y (y= + 0..15) + 10 + 1 + + + + LCK9 + Port x lock bit y (y= + 0..15) + 9 + 1 + + + + LCK8 + Port x lock bit y (y= + 0..15) + 8 + 1 + + + + LCK7 + Port x lock bit y (y= + 0..15) + 7 + 1 + + + + LCK6 + Port x lock bit y (y= + 0..15) + 6 + 1 + + + + LCK5 + Port x lock bit y (y= + 0..15) + 5 + 1 + + + + LCK4 + Port x lock bit y (y= + 0..15) + 4 + 1 + + + + LCK3 + Port x lock bit y (y= + 0..15) + 3 + 1 + + + + LCK2 + Port x lock bit y (y= + 0..15) + 2 + 1 + + + + LCK1 + Port x lock bit y (y= + 0..15) + 1 + 1 + + + + LCK0 + Port x lock bit y (y= + 0..15) + 0 + 1 + + LCK0 + read-write + + Unlocked + Port configuration not locked + 0 + + + Locked + Port configuration locked + 1 + + + + + + + AFRL + AFRL + GPIO alternate function low + register + 0x20 + 0x20 + read-write + 0x00000000 + + + AFRL7 + Alternate function selection for port x + bit y (y = 0..7) + 28 + 4 + + + + AFRL6 + Alternate function selection for port x + bit y (y = 0..7) + 24 + 4 + + + + AFRL5 + Alternate function selection for port x + bit y (y = 0..7) + 20 + 4 + + + + AFRL4 + Alternate function selection for port x + bit y (y = 0..7) + 16 + 4 + + + + AFRL3 + Alternate function selection for port x + bit y (y = 0..7) + 12 + 4 + + + + AFRL2 + Alternate function selection for port x + bit y (y = 0..7) + 8 + 4 + + + + AFRL1 + Alternate function selection for port x + bit y (y = 0..7) + 4 + 4 + + + + AFRL0 + Alternate function selection for port x + bit y (y = 0..7) + 0 + 4 + + AFRL0 + read-write + + AF0 + AF0 + 0 + + + AF1 + AF1 + 1 + + + AF2 + AF2 + 2 + + + AF3 + AF3 + 3 + + + AF4 + AF4 + 4 + + + AF5 + AF5 + 5 + + + AF6 + AF6 + 6 + + + AF7 + AF7 + 7 + + + AF8 + AF8 + 8 + + + AF9 + AF9 + 9 + + + AF10 + AF10 + 10 + + + AF11 + AF11 + 11 + + + AF12 + AF12 + 12 + + + AF13 + AF13 + 13 + + + AF14 + AF14 + 14 + + + AF15 + AF15 + 15 + + + + + + + AFRH + AFRH + GPIO alternate function high + register + 0x24 + 0x20 + read-write + 0x00000000 + + + AFRH15 + Alternate function selection for port x + bit y (y = 8..15) + 28 + 4 + + + + AFRH14 + Alternate function selection for port x + bit y (y = 8..15) + 24 + 4 + + + + AFRH13 + Alternate function selection for port x + bit y (y = 8..15) + 20 + 4 + + + + AFRH12 + Alternate function selection for port x + bit y (y = 8..15) + 16 + 4 + + + + AFRH11 + Alternate function selection for port x + bit y (y = 8..15) + 12 + 4 + + + + AFRH10 + Alternate function selection for port x + bit y (y = 8..15) + 8 + 4 + + + + AFRH9 + Alternate function selection for port x + bit y (y = 8..15) + 4 + 4 + + + + AFRH8 + Alternate function selection for port x + bit y (y = 8..15) + 0 + 4 + + AFRH8 + read-write + + AF0 + AF0 + 0 + + + AF1 + AF1 + 1 + + + AF2 + AF2 + 2 + + + AF3 + AF3 + 3 + + + AF4 + AF4 + 4 + + + AF5 + AF5 + 5 + + + AF6 + AF6 + 6 + + + AF7 + AF7 + 7 + + + AF8 + AF8 + 8 + + + AF9 + AF9 + 9 + + + AF10 + AF10 + 10 + + + AF11 + AF11 + 11 + + + AF12 + AF12 + 12 + + + AF13 + AF13 + 13 + + + AF14 + AF14 + 14 + + + AF15 + AF15 + 15 + + + + + + + + + GPIOA + General-purpose I/Os + GPIO + 0x40020000 + + 0x0 + 0x400 + registers + + + TIM2 + TIM2 global interrupt + 28 + + + + MODER + MODER + GPIO port mode register + 0x0 + 0x20 + read-write + 0xA8000000 + + + MODER15 + Port x configuration bits (y = + 0..15) + 30 + 2 + + + + MODER14 + Port x configuration bits (y = + 0..15) + 28 + 2 + + + + MODER13 + Port x configuration bits (y = + 0..15) + 26 + 2 + + + + MODER12 + Port x configuration bits (y = + 0..15) + 24 + 2 + + + + MODER11 + Port x configuration bits (y = + 0..15) + 22 + 2 + + + + MODER10 + Port x configuration bits (y = + 0..15) + 20 + 2 + + + + MODER9 + Port x configuration bits (y = + 0..15) + 18 + 2 + + + + MODER8 + Port x configuration bits (y = + 0..15) + 16 + 2 + + + + MODER7 + Port x configuration bits (y = + 0..15) + 14 + 2 + + + + MODER6 + Port x configuration bits (y = + 0..15) + 12 + 2 + + + + MODER5 + Port x configuration bits (y = + 0..15) + 10 + 2 + + + + MODER4 + Port x configuration bits (y = + 0..15) + 8 + 2 + + + + MODER3 + Port x configuration bits (y = + 0..15) + 6 + 2 + + + + MODER2 + Port x configuration bits (y = + 0..15) + 4 + 2 + + + + MODER1 + Port x configuration bits (y = + 0..15) + 2 + 2 + + + + MODER0 + Port x configuration bits (y = + 0..15) + 0 + 2 + + MODER0 + read-write + + Input + Input mode (reset state) + 0 + + + Output + General purpose output mode + 1 + + + Alternate + Alternate function mode + 2 + + + Analog + Analog mode + 3 + + + + + + + OTYPER + OTYPER + GPIO port output type register + 0x4 + 0x20 + read-write + 0x00000000 + + + OT15 + Port x configuration bits (y = + 0..15) + 15 + 1 + + + + OT14 + Port x configuration bits (y = + 0..15) + 14 + 1 + + + + OT13 + Port x configuration bits (y = + 0..15) + 13 + 1 + + + + OT12 + Port x configuration bits (y = + 0..15) + 12 + 1 + + + + OT11 + Port x configuration bits (y = + 0..15) + 11 + 1 + + + + OT10 + Port x configuration bits (y = + 0..15) + 10 + 1 + + + + OT9 + Port x configuration bits (y = + 0..15) + 9 + 1 + + + + OT8 + Port x configuration bits (y = + 0..15) + 8 + 1 + + + + OT7 + Port x configuration bits (y = + 0..15) + 7 + 1 + + + + OT6 + Port x configuration bits (y = + 0..15) + 6 + 1 + + + + OT5 + Port x configuration bits (y = + 0..15) + 5 + 1 + + + + OT4 + Port x configuration bits (y = + 0..15) + 4 + 1 + + + + OT3 + Port x configuration bits (y = + 0..15) + 3 + 1 + + + + OT2 + Port x configuration bits (y = + 0..15) + 2 + 1 + + + + OT1 + Port x configuration bits (y = + 0..15) + 1 + 1 + + + + OT0 + Port x configuration bits (y = + 0..15) + 0 + 1 + + OT0 + read-write + + PushPull + Output push-pull (reset state) + 0 + + + OpenDrain + Output open-drain + 1 + + + + + + + OSPEEDR + OSPEEDR + GPIO port output speed + register + 0x8 + 0x20 + read-write + 0x00000000 + + + OSPEEDR15 + Port x configuration bits (y = + 0..15) + 30 + 2 + + + + OSPEEDR14 + Port x configuration bits (y = + 0..15) + 28 + 2 + + + + OSPEEDR13 + Port x configuration bits (y = + 0..15) + 26 + 2 + + + + OSPEEDR12 + Port x configuration bits (y = + 0..15) + 24 + 2 + + + + OSPEEDR11 + Port x configuration bits (y = + 0..15) + 22 + 2 + + + + OSPEEDR10 + Port x configuration bits (y = + 0..15) + 20 + 2 + + + + OSPEEDR9 + Port x configuration bits (y = + 0..15) + 18 + 2 + + + + OSPEEDR8 + Port x configuration bits (y = + 0..15) + 16 + 2 + + + + OSPEEDR7 + Port x configuration bits (y = + 0..15) + 14 + 2 + + + + OSPEEDR6 + Port x configuration bits (y = + 0..15) + 12 + 2 + + + + OSPEEDR5 + Port x configuration bits (y = + 0..15) + 10 + 2 + + + + OSPEEDR4 + Port x configuration bits (y = + 0..15) + 8 + 2 + + + + OSPEEDR3 + Port x configuration bits (y = + 0..15) + 6 + 2 + + + + OSPEEDR2 + Port x configuration bits (y = + 0..15) + 4 + 2 + + + + OSPEEDR1 + Port x configuration bits (y = + 0..15) + 2 + 2 + + + + OSPEEDR0 + Port x configuration bits (y = + 0..15) + 0 + 2 + + OSPEEDR0 + read-write + + LowSpeed + Low speed + 0 + + + MediumSpeed + Medium speed + 1 + + + HighSpeed + High speed + 2 + + + VeryHighSpeed + Very high speed + 3 + + + + + + + PUPDR + PUPDR + GPIO port pull-up/pull-down + register + 0xC + 0x20 + read-write + 0x64000000 + + + PUPDR15 + Port x configuration bits (y = + 0..15) + 30 + 2 + + + + PUPDR14 + Port x configuration bits (y = + 0..15) + 28 + 2 + + + + PUPDR13 + Port x configuration bits (y = + 0..15) + 26 + 2 + + + + PUPDR12 + Port x configuration bits (y = + 0..15) + 24 + 2 + + + + PUPDR11 + Port x configuration bits (y = + 0..15) + 22 + 2 + + + + PUPDR10 + Port x configuration bits (y = + 0..15) + 20 + 2 + + + + PUPDR9 + Port x configuration bits (y = + 0..15) + 18 + 2 + + + + PUPDR8 + Port x configuration bits (y = + 0..15) + 16 + 2 + + + + PUPDR7 + Port x configuration bits (y = + 0..15) + 14 + 2 + + + + PUPDR6 + Port x configuration bits (y = + 0..15) + 12 + 2 + + + + PUPDR5 + Port x configuration bits (y = + 0..15) + 10 + 2 + + + + PUPDR4 + Port x configuration bits (y = + 0..15) + 8 + 2 + + + + PUPDR3 + Port x configuration bits (y = + 0..15) + 6 + 2 + + + + PUPDR2 + Port x configuration bits (y = + 0..15) + 4 + 2 + + + + PUPDR1 + Port x configuration bits (y = + 0..15) + 2 + 2 + + + + PUPDR0 + Port x configuration bits (y = + 0..15) + 0 + 2 + + PUPDR0 + read-write + + Floating + No pull-up, pull-down + 0 + + + PullUp + Pull-up + 1 + + + PullDown + Pull-down + 2 + + + + + + + IDR + IDR + GPIO port input data register + 0x10 + 0x20 + read-only + 0x00000000 + + + IDR15 + Port input data (y = + 0..15) + 15 + 1 + + + + IDR14 + Port input data (y = + 0..15) + 14 + 1 + + + + IDR13 + Port input data (y = + 0..15) + 13 + 1 + + + + IDR12 + Port input data (y = + 0..15) + 12 + 1 + + + + IDR11 + Port input data (y = + 0..15) + 11 + 1 + + + + IDR10 + Port input data (y = + 0..15) + 10 + 1 + + + + IDR9 + Port input data (y = + 0..15) + 9 + 1 + + + + IDR8 + Port input data (y = + 0..15) + 8 + 1 + + + + IDR7 + Port input data (y = + 0..15) + 7 + 1 + + + + IDR6 + Port input data (y = + 0..15) + 6 + 1 + + + + IDR5 + Port input data (y = + 0..15) + 5 + 1 + + + + IDR4 + Port input data (y = + 0..15) + 4 + 1 + + + + IDR3 + Port input data (y = + 0..15) + 3 + 1 + + + + IDR2 + Port input data (y = + 0..15) + 2 + 1 + + + + IDR1 + Port input data (y = + 0..15) + 1 + 1 + + + + IDR0 + Port input data (y = + 0..15) + 0 + 1 + + IDR0 + read + + Low + Input is logic low + 0 + + + High + Input is logic high + 1 + + + + + + + ODR + ODR + GPIO port output data register + 0x14 + 0x20 + read-write + 0x00000000 + + + ODR15 + Port output data (y = + 0..15) + 15 + 1 + + + + ODR14 + Port output data (y = + 0..15) + 14 + 1 + + + + ODR13 + Port output data (y = + 0..15) + 13 + 1 + + + + ODR12 + Port output data (y = + 0..15) + 12 + 1 + + + + ODR11 + Port output data (y = + 0..15) + 11 + 1 + + + + ODR10 + Port output data (y = + 0..15) + 10 + 1 + + + + ODR9 + Port output data (y = + 0..15) + 9 + 1 + + + + ODR8 + Port output data (y = + 0..15) + 8 + 1 + + + + ODR7 + Port output data (y = + 0..15) + 7 + 1 + + + + ODR6 + Port output data (y = + 0..15) + 6 + 1 + + + + ODR5 + Port output data (y = + 0..15) + 5 + 1 + + + + ODR4 + Port output data (y = + 0..15) + 4 + 1 + + + + ODR3 + Port output data (y = + 0..15) + 3 + 1 + + + + ODR2 + Port output data (y = + 0..15) + 2 + 1 + + + + ODR1 + Port output data (y = + 0..15) + 1 + 1 + + + + ODR0 + Port output data (y = + 0..15) + 0 + 1 + + ODR0 + read-write + + Low + Set output to logic low + 0 + + + High + Set output to logic high + 1 + + + + + + + BSRR + BSRR + GPIO port bit set/reset + register + 0x18 + 0x20 + write-only + 0x00000000 + + + BR15 + Port x reset bit y (y = + 0..15) + 31 + 1 + + + + BR14 + Port x reset bit y (y = + 0..15) + 30 + 1 + + + + BR13 + Port x reset bit y (y = + 0..15) + 29 + 1 + + + + BR12 + Port x reset bit y (y = + 0..15) + 28 + 1 + + + + BR11 + Port x reset bit y (y = + 0..15) + 27 + 1 + + + + BR10 + Port x reset bit y (y = + 0..15) + 26 + 1 + + + + BR9 + Port x reset bit y (y = + 0..15) + 25 + 1 + + + + BR8 + Port x reset bit y (y = + 0..15) + 24 + 1 + + + + BR7 + Port x reset bit y (y = + 0..15) + 23 + 1 + + + + BR6 + Port x reset bit y (y = + 0..15) + 22 + 1 + + + + BR5 + Port x reset bit y (y = + 0..15) + 21 + 1 + + + + BR4 + Port x reset bit y (y = + 0..15) + 20 + 1 + + + + BR3 + Port x reset bit y (y = + 0..15) + 19 + 1 + + + + BR2 + Port x reset bit y (y = + 0..15) + 18 + 1 + + + + BR1 + Port x reset bit y (y = + 0..15) + 17 + 1 + + + + BR0 + Port x set bit y (y= + 0..15) + 16 + 1 + + BR0W + write + + Reset + Resets the corresponding ODRx bit + 1 + + + + + BS15 + Port x set bit y (y= + 0..15) + 15 + 1 + + + + BS14 + Port x set bit y (y= + 0..15) + 14 + 1 + + + + BS13 + Port x set bit y (y= + 0..15) + 13 + 1 + + + + BS12 + Port x set bit y (y= + 0..15) + 12 + 1 + + + + BS11 + Port x set bit y (y= + 0..15) + 11 + 1 + + + + BS10 + Port x set bit y (y= + 0..15) + 10 + 1 + + + + BS9 + Port x set bit y (y= + 0..15) + 9 + 1 + + + + BS8 + Port x set bit y (y= + 0..15) + 8 + 1 + + + + BS7 + Port x set bit y (y= + 0..15) + 7 + 1 + + + + BS6 + Port x set bit y (y= + 0..15) + 6 + 1 + + + + BS5 + Port x set bit y (y= + 0..15) + 5 + 1 + + + + BS4 + Port x set bit y (y= + 0..15) + 4 + 1 + + + + BS3 + Port x set bit y (y= + 0..15) + 3 + 1 + + + + BS2 + Port x set bit y (y= + 0..15) + 2 + 1 + + + + BS1 + Port x set bit y (y= + 0..15) + 1 + 1 + + + + BS0 + Port x set bit y (y= + 0..15) + 0 + 1 + + BS0W + write + + Set + Sets the corresponding ODRx bit + 1 + + + + + + + LCKR + LCKR + GPIO port configuration lock + register + 0x1C + 0x20 + read-write + 0x00000000 + + + LCKK + Port x lock bit y (y= + 0..15) + 16 + 1 + + LCKK + read-write + + NotActive + Port configuration lock key not active + 0 + + + Active + Port configuration lock key active + 1 + + + + + LCK15 + Port x lock bit y (y= + 0..15) + 15 + 1 + + + + LCK14 + Port x lock bit y (y= + 0..15) + 14 + 1 + + + + LCK13 + Port x lock bit y (y= + 0..15) + 13 + 1 + + + + LCK12 + Port x lock bit y (y= + 0..15) + 12 + 1 + + + + LCK11 + Port x lock bit y (y= + 0..15) + 11 + 1 + + + + LCK10 + Port x lock bit y (y= + 0..15) + 10 + 1 + + + + LCK9 + Port x lock bit y (y= + 0..15) + 9 + 1 + + + + LCK8 + Port x lock bit y (y= + 0..15) + 8 + 1 + + + + LCK7 + Port x lock bit y (y= + 0..15) + 7 + 1 + + + + LCK6 + Port x lock bit y (y= + 0..15) + 6 + 1 + + + + LCK5 + Port x lock bit y (y= + 0..15) + 5 + 1 + + + + LCK4 + Port x lock bit y (y= + 0..15) + 4 + 1 + + + + LCK3 + Port x lock bit y (y= + 0..15) + 3 + 1 + + + + LCK2 + Port x lock bit y (y= + 0..15) + 2 + 1 + + + + LCK1 + Port x lock bit y (y= + 0..15) + 1 + 1 + + + + LCK0 + Port x lock bit y (y= + 0..15) + 0 + 1 + + LCK0 + read-write + + Unlocked + Port configuration not locked + 0 + + + Locked + Port configuration locked + 1 + + + + + + + AFRL + AFRL + GPIO alternate function low + register + 0x20 + 0x20 + read-write + 0x00000000 + + + AFRL7 + Alternate function selection for port x + bit y (y = 0..7) + 28 + 4 + + + + AFRL6 + Alternate function selection for port x + bit y (y = 0..7) + 24 + 4 + + + + AFRL5 + Alternate function selection for port x + bit y (y = 0..7) + 20 + 4 + + + + AFRL4 + Alternate function selection for port x + bit y (y = 0..7) + 16 + 4 + + + + AFRL3 + Alternate function selection for port x + bit y (y = 0..7) + 12 + 4 + + + + AFRL2 + Alternate function selection for port x + bit y (y = 0..7) + 8 + 4 + + + + AFRL1 + Alternate function selection for port x + bit y (y = 0..7) + 4 + 4 + + + + AFRL0 + Alternate function selection for port x + bit y (y = 0..7) + 0 + 4 + + AFRL0 + read-write + + AF0 + AF0 + 0 + + + AF1 + AF1 + 1 + + + AF2 + AF2 + 2 + + + AF3 + AF3 + 3 + + + AF4 + AF4 + 4 + + + AF5 + AF5 + 5 + + + AF6 + AF6 + 6 + + + AF7 + AF7 + 7 + + + AF8 + AF8 + 8 + + + AF9 + AF9 + 9 + + + AF10 + AF10 + 10 + + + AF11 + AF11 + 11 + + + AF12 + AF12 + 12 + + + AF13 + AF13 + 13 + + + AF14 + AF14 + 14 + + + AF15 + AF15 + 15 + + + + + + + AFRH + AFRH + GPIO alternate function high + register + 0x24 + 0x20 + read-write + 0x00000000 + + + AFRH15 + Alternate function selection for port x + bit y (y = 8..15) + 28 + 4 + + + + AFRH14 + Alternate function selection for port x + bit y (y = 8..15) + 24 + 4 + + + + AFRH13 + Alternate function selection for port x + bit y (y = 8..15) + 20 + 4 + + + + AFRH12 + Alternate function selection for port x + bit y (y = 8..15) + 16 + 4 + + + + AFRH11 + Alternate function selection for port x + bit y (y = 8..15) + 12 + 4 + + + + AFRH10 + Alternate function selection for port x + bit y (y = 8..15) + 8 + 4 + + + + AFRH9 + Alternate function selection for port x + bit y (y = 8..15) + 4 + 4 + + + + AFRH8 + Alternate function selection for port x + bit y (y = 8..15) + 0 + 4 + + AFRH8 + read-write + + AF0 + AF0 + 0 + + + AF1 + AF1 + 1 + + + AF2 + AF2 + 2 + + + AF3 + AF3 + 3 + + + AF4 + AF4 + 4 + + + AF5 + AF5 + 5 + + + AF6 + AF6 + 6 + + + AF7 + AF7 + 7 + + + AF8 + AF8 + 8 + + + AF9 + AF9 + 9 + + + AF10 + AF10 + 10 + + + AF11 + AF11 + 11 + + + AF12 + AF12 + 12 + + + AF13 + AF13 + 13 + + + AF14 + AF14 + 14 + + + AF15 + AF15 + 15 + + + + + + + + + I2C3 + 0x40005C00 + + TIM3 + TIM3 global interrupt + 29 + + + + I2C2 + 0x40005800 + + I2C3_EV + I2C3 event interrupt + 72 + + + I2C3_ER + I2C3 error interrupt + 73 + + + + I2C1 + Inter-integrated circuit + I2C + 0x40005400 + + 0x0 + 0x400 + registers + + + I2C2_EV + I2C2 event interrupt + 33 + + + I2C2_ER + I2C2 error interrupt + 34 + + + + CR1 + CR1 + Control register 1 + 0x0 + 0x20 + read-write + 0x00000000 + + + SWRST + Software reset + 15 + 1 + + SWRST + read-write + + NotReset + I2C peripheral not under reset + 0 + + + Reset + I2C peripheral under reset + 1 + + + + + ALERT + SMBus alert + 13 + 1 + + ALERT + read-write + + Release + SMBA pin released high + 0 + + + Drive + SMBA pin driven low + 1 + + + + + PEC + Packet error checking + 12 + 1 + + PEC + read-write + + Disabled + No PEC transfer + 0 + + + Enabled + PEC transfer + 1 + + + + + POS + Acknowledge/PEC Position (for data + reception) + 11 + 1 + + POS + read-write + + Current + ACK bit controls the (N)ACK of the current byte being received + 0 + + + Next + ACK bit controls the (N)ACK of the next byte to be received + 1 + + + + + ACK + Acknowledge enable + 10 + 1 + + ACK + read-write + + NAK + No acknowledge returned + 0 + + + ACK + Acknowledge returned after a byte is received + 1 + + + + + STOP + Stop generation + 9 + 1 + + STOP + read-write + + NoStop + No Stop generation + 0 + + + Stop + In master mode: stop generation after current byte/start, in slave mode: release SCL and SDA after current byte + 1 + + + + + START + Start generation + 8 + 1 + + START + read-write + + NoStart + No Start generation + 0 + + + Start + In master mode: repeated start generation, in slave mode: start generation when bus is free + 1 + + + + + NOSTRETCH + Clock stretching disable (Slave + mode) + 7 + 1 + + NOSTRETCH + read-write + + Enabled + Clock stretching enabled + 0 + + + Disabled + Clock stretching disabled + 1 + + + + + ENGC + General call enable + 6 + 1 + + ENGC + read-write + + Disabled + General call disabled + 0 + + + Enabled + General call enabled + 1 + + + + + ENPEC + PEC enable + 5 + 1 + + ENPEC + read-write + + Disabled + PEC calculation disabled + 0 + + + Enabled + PEC calculation enabled + 1 + + + + + ENARP + ARP enable + 4 + 1 + + ENARP + read-write + + Disabled + ARP disabled + 0 + + + Enabled + ARP enabled + 1 + + + + + SMBTYPE + SMBus type + 3 + 1 + + SMBTYPE + read-write + + Device + SMBus Device + 0 + + + Host + SMBus Host + 1 + + + + + SMBUS + SMBus mode + 1 + 1 + + SMBUS + read-write + + I2C + I2C Mode + 0 + + + SMBus + SMBus + 1 + + + + + PE + Peripheral enable + 0 + 1 + + PE + read-write + + Disabled + Peripheral disabled + 0 + + + Enabled + Peripheral enabled + 1 + + + + + + + CR2 + CR2 + Control register 2 + 0x4 + 0x20 + read-write + 0x00000000 + + + LAST + DMA last transfer + 12 + 1 + + LAST + read-write + + NotLast + Next DMA EOT is not the last transfer + 0 + + + Last + Next DMA EOT is the last transfer + 1 + + + + + DMAEN + DMA requests enable + 11 + 1 + + DMAEN + read-write + + Disabled + DMA requests disabled + 0 + + + Enabled + DMA request enabled when TxE=1 or RxNE=1 + 1 + + + + + ITBUFEN + Buffer interrupt enable + 10 + 1 + + ITBUFEN + read-write + + Disabled + TxE=1 or RxNE=1 does not generate any interrupt + 0 + + + Enabled + TxE=1 or RxNE=1 generates Event interrupt + 1 + + + + + ITEVTEN + Event interrupt enable + 9 + 1 + + ITEVTEN + read-write + + Disabled + Event interrupt disabled + 0 + + + Enabled + Event interrupt enabled + 1 + + + + + ITERREN + Error interrupt enable + 8 + 1 + + ITERREN + read-write + + Disabled + Error interrupt disabled + 0 + + + Enabled + Error interrupt enabled + 1 + + + + + FREQ + Peripheral clock frequency + 0 + 6 + + + 2 + 50 + + + + + + + OAR1 + OAR1 + Own address register 1 + 0x8 + 0x20 + read-write + 0x00000000 + + + ADDMODE + Addressing mode (slave + mode) + 15 + 1 + + ADDMODE + read-write + + ADD7 + 7-bit slave address + 0 + + + ADD10 + 10-bit slave address + 1 + + + + + ADD + Interface address + 0 + 10 + + + 0 + 1023 + + + + + + + OAR2 + OAR2 + Own address register 2 + 0xC + 0x20 + read-write + 0x00000000 + + + ADD2 + Interface address + 1 + 7 + + + 0 + 127 + + + + + ENDUAL + Dual addressing mode + enable + 0 + 1 + + ENDUAL + read-write + + Single + Single addressing mode + 0 + + + Dual + Dual addressing mode + 1 + + + + + + + DR + DR + Data register + 0x10 + 0x20 + read-write + 0x00000000 + + + DR + 8-bit data register + 0 + 8 + + + 0 + 255 + + + + + + + SR1 + SR1 + Status register 1 + 0x14 + 0x20 + 0x00000000 + + + SMBALERT + SMBus alert + 15 + 1 + read-write + zeroToClear + + SMBALERTR + read + + NoAlert + No SMBALERT occured + 0 + + + Alert + SMBALERT occurred + 1 + + + + SMBALERTW + write + + Clear + Clear flag + 0 + + + + + TIMEOUT + Timeout or Tlow error + 14 + 1 + read-write + zeroToClear + + TIMEOUTR + read + + NoTimeout + No Timeout error + 0 + + + Timeout + SCL remained LOW for 25 ms + 1 + + + + TIMEOUTW + write + + Clear + Clear flag + 0 + + + + + PECERR + PEC Error in reception + 12 + 1 + read-write + zeroToClear + + PECERRR + read + + NoError + no PEC error: receiver returns ACK after PEC reception (if ACK=1) + 0 + + + Error + PEC error: receiver returns NACK after PEC reception (whatever ACK) + 1 + + + + PECERRW + write + + Clear + Clear flag + 0 + + + + + OVR + Overrun/Underrun + 11 + 1 + read-write + zeroToClear + + OVRR + read + + NoOverrun + No overrun/underrun occured + 0 + + + Overrun + Overrun/underrun occured + 1 + + + + OVRW + write + + Clear + Clear flag + 0 + + + + + AF + Acknowledge failure + 10 + 1 + read-write + zeroToClear + + AFR + read + + NoFailure + No acknowledge failure + 0 + + + Failure + Acknowledge failure + 1 + + + + AFW + write + + Clear + Clear flag + 0 + + + + + ARLO + Arbitration lost (master + mode) + 9 + 1 + read-write + zeroToClear + + ARLOR + read + + NoLost + No Arbitration Lost detected + 0 + + + Lost + Arbitration Lost detected + 1 + + + + ARLOW + write + + Clear + Clear flag + 0 + + + + + BERR + Bus error + 8 + 1 + read-write + zeroToClear + + BERRR + read + + NoError + No misplaced Start or Stop condition + 0 + + + Error + Misplaced Start or Stop condition + 1 + + + + BERRW + write + + Clear + Clear flag + 0 + + + + + TxE + Data register empty + (transmitters) + 7 + 1 + read-only + + TxE + read + + NotEmpty + Data register not empty + 0 + + + Empty + Data register empty + 1 + + + + + RxNE + Data register not empty + (receivers) + 6 + 1 + read-only + + RxNE + read + + Empty + Data register empty + 0 + + + NotEmpty + Data register not empty + 1 + + + + + STOPF + Stop detection (slave + mode) + 4 + 1 + read-only + + STOPF + read + + NoStop + No Stop condition detected + 0 + + + Stop + Stop condition detected + 1 + + + + + ADD10 + 10-bit header sent (Master + mode) + 3 + 1 + read-only + + + BTF + Byte transfer finished + 2 + 1 + read-only + + BTF + read + + NotFinished + Data byte transfer not done + 0 + + + Finished + Data byte transfer successful + 1 + + + + + ADDR + Address sent (master mode)/matched + (slave mode) + 1 + 1 + read-only + + ADDR + read + + NotMatch + Adress mismatched or not received + 0 + + + Match + Received slave address matched with one of the enabled slave addresses + 1 + + + + + SB + Start bit (Master mode) + 0 + 1 + read-only + + SB + read + + NoStart + No Start condition + 0 + + + Start + Start condition generated + 1 + + + + + + + SR2 + SR2 + Status register 2 + 0x18 + 0x20 + read-only + 0x00000000 + + + PEC + acket error checking + register + 8 + 8 + + + DUALF + Dual flag (Slave mode) + 7 + 1 + + + SMBHOST + SMBus host header (Slave + mode) + 6 + 1 + + + SMBDEFAULT + SMBus device default address (Slave + mode) + 5 + 1 + + + GENCALL + General call address (Slave + mode) + 4 + 1 + + + TRA + Transmitter/receiver + 2 + 1 + + + BUSY + Bus busy + 1 + 1 + + + MSL + Master/slave + 0 + 1 + + + + + CCR + CCR + Clock control register + 0x1C + 0x20 + read-write + 0x00000000 + + + F_S + I2C master mode selection + 15 + 1 + + F_S + read-write + + Standard + Standard mode I2C + 0 + + + Fast + Fast mode I2C + 1 + + + + + DUTY + Fast mode duty cycle + 14 + 1 + + DUTY + read-write + + Duty2_1 + Duty cycle t_low/t_high = 2/1 + 0 + + + Duty16_9 + Duty cycle t_low/t_high = 16/9 + 1 + + + + + CCR + Clock control register in Fast/Standard + mode (Master mode) + 0 + 12 + + + 1 + 4095 + + + + + + + TRISE + TRISE + TRISE register + 0x20 + 0x20 + read-write + 0x00000002 + + + TRISE + Maximum rise time in Fast/Standard mode + (Master mode) + 0 + 6 + + + 0 + 63 + + + + + + + FLTR + FLTR register + 0x24 + read-write + 0x00000000 + + + ANOFF + Analog noise filter + 4 + 1 + + ANOFF + read-write + + Enabled + Analog noise filter enabled + 0 + + + Disabled + Analog noise filter disabled + 1 + + + + + DNF + Digital noise filter + 0 + 4 + + DNF + read-write + + NoFilter + Digital filter disabled + 0 + + + Filter1 + Digital filter enabled and filtering capability up to 1 tI2CCLK + 1 + + + Filter2 + Digital filter enabled and filtering capability up to 2 tI2CCLK + 2 + + + Filter3 + Digital filter enabled and filtering capability up to 3 tI2CCLK + 3 + + + Filter4 + Digital filter enabled and filtering capability up to 4 tI2CCLK + 4 + + + Filter5 + Digital filter enabled and filtering capability up to 5 tI2CCLK + 5 + + + Filter6 + Digital filter enabled and filtering capability up to 6 tI2CCLK + 6 + + + Filter7 + Digital filter enabled and filtering capability up to 7 tI2CCLK + 7 + + + Filter8 + Digital filter enabled and filtering capability up to 8 tI2CCLK + 8 + + + Filter9 + Digital filter enabled and filtering capability up to 9 tI2CCLK + 9 + + + Filter10 + Digital filter enabled and filtering capability up to 10 tI2CCLK + 10 + + + Filter11 + Digital filter enabled and filtering capability up to 11 tI2CCLK + 11 + + + Filter12 + Digital filter enabled and filtering capability up to 12 tI2CCLK + 12 + + + Filter13 + Digital filter enabled and filtering capability up to 13 tI2CCLK + 13 + + + Filter14 + Digital filter enabled and filtering capability up to 14 tI2CCLK + 14 + + + Filter15 + Digital filter enabled and filtering capability up to 15 tI2CCLK + 15 + + + + + + + + + I2S2ext + 0x40003400 + + I2C1_EV + I2C1 event interrupt + 31 + + + I2C1_ER + I2C1 error interrupt + 32 + + + + I2S3ext + 0x40004000 + + + SPI1 + Serial peripheral interface + SPI + 0x40013000 + + 0x0 + 0x400 + registers + + + + CR1 + CR1 + control register 1 + 0x0 + 0x20 + read-write + 0x00000000 + + + BIDIMODE + Bidirectional data mode + enable + 15 + 1 + + BIDIMODE + read-write + + Unidirectional + 2-line unidirectional data mode selected + 0 + + + Bidirectional + 1-line bidirectional data mode selected + 1 + + + + + BIDIOE + Output enable in bidirectional + mode + 14 + 1 + + BIDIOE + read-write + + OutputDisabled + Output disabled (receive-only mode) + 0 + + + OutputEnabled + Output enabled (transmit-only mode) + 1 + + + + + CRCEN + Hardware CRC calculation + enable + 13 + 1 + + CRCEN + read-write + + Disabled + CRC calculation disabled + 0 + + + Enabled + CRC calculation enabled + 1 + + + + + CRCNEXT + CRC transfer next + 12 + 1 + + CRCNEXT + read-write + + TxBuffer + Next transmit value is from Tx buffer + 0 + + + CRC + Next transmit value is from Tx CRC register + 1 + + + + + DFF + Data frame format + 11 + 1 + + DFF + read-write + + EightBit + 8-bit data frame format is selected for transmission/reception + 0 + + + SixteenBit + 16-bit data frame format is selected for transmission/reception + 1 + + + + + RXONLY + Receive only + 10 + 1 + + RXONLY + read-write + + FullDuplex + Full duplex (Transmit and receive) + 0 + + + OutputDisabled + Output disabled (Receive-only mode) + 1 + + + + + SSM + Software slave management + 9 + 1 + + SSM + read-write + + Disabled + Software slave management disabled + 0 + + + Enabled + Software slave management enabled + 1 + + + + + SSI + Internal slave select + 8 + 1 + + SSI + read-write + + SlaveSelected + 0 is forced onto the NSS pin and the I/O value of the NSS pin is ignored + 0 + + + SlaveNotSelected + 1 is forced onto the NSS pin and the I/O value of the NSS pin is ignored + 1 + + + + + LSBFIRST + Frame format + 7 + 1 + + LSBFIRST + read-write + + MSBFirst + Data is transmitted/received with the MSB first + 0 + + + LSBFirst + Data is transmitted/received with the LSB first + 1 + + + + + SPE + SPI enable + 6 + 1 + + SPE + read-write + + Disabled + Peripheral disabled + 0 + + + Enabled + Peripheral enabled + 1 + + + + + BR + Baud rate control + 3 + 3 + + BR + read-write + + Div2 + f_PCLK / 2 + 0 + + + Div4 + f_PCLK / 4 + 1 + + + Div8 + f_PCLK / 8 + 2 + + + Div16 + f_PCLK / 16 + 3 + + + Div32 + f_PCLK / 32 + 4 + + + Div64 + f_PCLK / 64 + 5 + + + Div128 + f_PCLK / 128 + 6 + + + Div256 + f_PCLK / 256 + 7 + + + + + MSTR + Master selection + 2 + 1 + + MSTR + read-write + + Slave + Slave configuration + 0 + + + Master + Master configuration + 1 + + + + + CPOL + Clock polarity + 1 + 1 + + CPOL + read-write + + IdleLow + CK to 0 when idle + 0 + + + IdleHigh + CK to 1 when idle + 1 + + + + + CPHA + Clock phase + 0 + 1 + + CPHA + read-write + + FirstEdge + The first clock transition is the first data capture edge + 0 + + + SecondEdge + The second clock transition is the first data capture edge + 1 + + + + + + + CR2 + CR2 + control register 2 + 0x4 + 0x20 + read-write + 0x00000000 + + + TXEIE + Tx buffer empty interrupt + enable + 7 + 1 + + TXEIE + read-write + + Masked + TXE interrupt masked + 0 + + + NotMasked + TXE interrupt not masked + 1 + + + + + RXNEIE + RX buffer not empty interrupt + enable + 6 + 1 + + RXNEIE + read-write + + Masked + RXE interrupt masked + 0 + + + NotMasked + RXE interrupt not masked + 1 + + + + + ERRIE + Error interrupt enable + 5 + 1 + + ERRIE + read-write + + Masked + Error interrupt masked + 0 + + + NotMasked + Error interrupt not masked + 1 + + + + + FRF + Frame format + 4 + 1 + + FRF + read-write + + Motorola + SPI Motorola mode + 0 + + + TI + SPI TI mode + 1 + + + + + SSOE + SS output enable + 2 + 1 + + SSOE + read-write + + Disabled + SS output is disabled in master mode + 0 + + + Enabled + SS output is enabled in master mode + 1 + + + + + TXDMAEN + Tx buffer DMA enable + 1 + 1 + + TXDMAEN + read-write + + Disabled + Tx buffer DMA disabled + 0 + + + Enabled + Tx buffer DMA enabled + 1 + + + + + RXDMAEN + Rx buffer DMA enable + 0 + 1 + + RXDMAEN + read-write + + Disabled + Rx buffer DMA disabled + 0 + + + Enabled + Rx buffer DMA enabled + 1 + + + + + + + SR + SR + status register + 0x8 + 0x20 + 0x00000002 + + + FRE + TI frame format error + 8 + 1 + read-only + + FRER + read + + NoError + No frame format error + 0 + + + Error + A frame format error occurred + 1 + + + + + BSY + Busy flag + 7 + 1 + read-only + + BSYR + read + + NotBusy + SPI not busy + 0 + + + Busy + SPI busy + 1 + + + + + OVR + Overrun flag + 6 + 1 + read-only + + OVRR + read + + NoOverrun + No overrun occurred + 0 + + + Overrun + Overrun occurred + 1 + + + + + MODF + Mode fault + 5 + 1 + read-only + + MODFR + read + + NoFault + No mode fault occurred + 0 + + + Fault + Mode fault occurred + 1 + + + + + CRCERR + CRC error flag + 4 + 1 + read-write + zeroToClear + + CRCERRR + read + + Match + CRC value received matches the SPIx_RXCRCR value + 0 + + + NoMatch + CRC value received does not match the SPIx_RXCRCR value + 1 + + + + CRCERRW + write + + Clear + Clear flag + 0 + + + + + UDR + Underrun flag + 3 + 1 + read-only + + UDRR + read + + NoUnderrun + No underrun occurred + 0 + + + Underrun + Underrun occurred + 1 + + + + + CHSIDE + Channel side + 2 + 1 + read-only + + CHSIDE + read + + Left + Channel left has to be transmitted or has been received + 0 + + + Right + Channel right has to be transmitted or has been received + 1 + + + + + TXE + Transmit buffer empty + 1 + 1 + read-only + + TXE + read + + NotEmpty + Tx buffer not empty + 0 + + + Empty + Tx buffer empty + 1 + + + + + RXNE + Receive buffer not empty + 0 + 1 + read-only + + RXNE + read + + Empty + Rx buffer empty + 0 + + + NotEmpty + Rx buffer not empty + 1 + + + + + + + DR + DR + data register + 0xC + 0x20 + read-write + 0x00000000 + + + DR + Data register + 0 + 16 + + + 0 + 65535 + + + + + + + CRCPR + CRCPR + CRC polynomial register + 0x10 + 0x20 + read-write + 0x00000007 + + + CRCPOLY + CRC polynomial register + 0 + 16 + + + 0 + 65535 + + + + + + + RXCRCR + RXCRCR + RX CRC register + 0x14 + 0x20 + read-only + 0x00000000 + + + RxCRC + Rx CRC register + 0 + 16 + + + 0 + 65535 + + + + + + + TXCRCR + TXCRCR + TX CRC register + 0x18 + 0x20 + read-only + 0x00000000 + + + TxCRC + Tx CRC register + 0 + 16 + + + 0 + 65535 + + + + + + + I2SCFGR + I2SCFGR + I2S configuration register + 0x1C + 0x20 + read-write + 0x00000000 + + + I2SMOD + I2S mode selection + 11 + 1 + + I2SMOD + read-write + + SPIMode + SPI mode is selected + 0 + + + I2SMode + I2S mode is selected + 1 + + + + + I2SE + I2S Enable + 10 + 1 + + I2SE + read-write + + Disabled + I2S peripheral is disabled + 0 + + + Enabled + I2S peripheral is enabled + 1 + + + + + I2SCFG + I2S configuration mode + 8 + 2 + + I2SCFG + read-write + + SlaveTx + Slave - transmit + 0 + + + SlaveRx + Slave - receive + 1 + + + MasterTx + Master - transmit + 2 + + + MasterRx + Master - receive + 3 + + + + + PCMSYNC + PCM frame synchronization + 7 + 1 + + PCMSYNC + read-write + + Short + Short frame synchronisation + 0 + + + Long + Long frame synchronisation + 1 + + + + + I2SSTD + I2S standard selection + 4 + 2 + + I2SSTD + read-write + + Philips + I2S Philips standard + 0 + + + MSB + MSB justified standard + 1 + + + LSB + LSB justified standard + 2 + + + PCM + PCM standard + 3 + + + + + CKPOL + Steady state clock + polarity + 3 + 1 + + CKPOL + read-write + + IdleLow + I2S clock inactive state is low level + 0 + + + IdleHigh + I2S clock inactive state is high level + 1 + + + + + DATLEN + Data length to be + transferred + 1 + 2 + + DATLEN + read-write + + SixteenBit + 16-bit data length + 0 + + + TwentyFourBit + 24-bit data length + 1 + + + ThirtyTwoBit + 32-bit data length + 2 + + + + + CHLEN + Channel length (number of bits per audio + channel) + 0 + 1 + + CHLEN + read-write + + SixteenBit + 16-bit wide + 0 + + + ThirtyTwoBit + 32-bit wide + 1 + + + + + + + I2SPR + I2SPR + I2S prescaler register + 0x20 + 0x20 + read-write + 0x0000000A + + + MCKOE + Master clock output enable + 9 + 1 + + MCKOE + read-write + + Disabled + Master clock output is disabled + 0 + + + Enabled + Master clock output is enabled + 1 + + + + + ODD + Odd factor for the + prescaler + 8 + 1 + + ODD + read-write + + Even + Real divider value is I2SDIV * 2 + 0 + + + Odd + Real divider value is (I2SDIV * 2) + 1 + 1 + + + + + I2SDIV + I2S Linear prescaler + 0 + 8 + + + 2 + 255 + + + + + + + + + SPI2 + 0x40003800 + + SPI1 + SPI1 global interrupt + 35 + + + + SPI3 + 0x40003C00 + + SPI2 + SPI2 global interrupt + 36 + + + + SPI4 + 0x40013400 + + SPI3 + SPI3 global interrupt + 51 + + + + NVIC + Nested Vectored Interrupt + Controller + NVIC + 0xE000E100 + + 0x0 + 0x351 + registers + + + + ISER0 + ISER0 + Interrupt Set-Enable Register + 0x0 + 0x20 + read-write + 0x00000000 + + + SETENA + SETENA + 0 + 32 + + + + + ISER1 + ISER1 + Interrupt Set-Enable Register + 0x4 + 0x20 + read-write + 0x00000000 + + + SETENA + SETENA + 0 + 32 + + + + + ISER2 + ISER2 + Interrupt Set-Enable Register + 0x8 + 0x20 + read-write + 0x00000000 + + + SETENA + SETENA + 0 + 32 + + + + + ICER0 + ICER0 + Interrupt Clear-Enable + Register + 0x80 + 0x20 + read-write + 0x00000000 + + + CLRENA + CLRENA + 0 + 32 + + + + + ICER1 + ICER1 + Interrupt Clear-Enable + Register + 0x84 + 0x20 + read-write + 0x00000000 + + + CLRENA + CLRENA + 0 + 32 + + + + + ICER2 + ICER2 + Interrupt Clear-Enable + Register + 0x88 + 0x20 + read-write + 0x00000000 + + + CLRENA + CLRENA + 0 + 32 + + + + + ISPR0 + ISPR0 + Interrupt Set-Pending Register + 0x100 + 0x20 + read-write + 0x00000000 + + + SETPEND + SETPEND + 0 + 32 + + + + + ISPR1 + ISPR1 + Interrupt Set-Pending Register + 0x104 + 0x20 + read-write + 0x00000000 + + + SETPEND + SETPEND + 0 + 32 + + + + + ISPR2 + ISPR2 + Interrupt Set-Pending Register + 0x108 + 0x20 + read-write + 0x00000000 + + + SETPEND + SETPEND + 0 + 32 + + + + + ICPR0 + ICPR0 + Interrupt Clear-Pending + Register + 0x180 + 0x20 + read-write + 0x00000000 + + + CLRPEND + CLRPEND + 0 + 32 + + + + + ICPR1 + ICPR1 + Interrupt Clear-Pending + Register + 0x184 + 0x20 + read-write + 0x00000000 + + + CLRPEND + CLRPEND + 0 + 32 + + + + + ICPR2 + ICPR2 + Interrupt Clear-Pending + Register + 0x188 + 0x20 + read-write + 0x00000000 + + + CLRPEND + CLRPEND + 0 + 32 + + + + + IABR0 + IABR0 + Interrupt Active Bit Register + 0x200 + 0x20 + read-only + 0x00000000 + + + ACTIVE + ACTIVE + 0 + 32 + + + + + IABR1 + IABR1 + Interrupt Active Bit Register + 0x204 + 0x20 + read-only + 0x00000000 + + + ACTIVE + ACTIVE + 0 + 32 + + + + + IABR2 + IABR2 + Interrupt Active Bit Register + 0x208 + 0x20 + read-only + 0x00000000 + + + ACTIVE + ACTIVE + 0 + 32 + + + + + IPR0 + IPR0 + Interrupt Priority Register + 0x300 + 0x20 + read-write + 0x00000000 + + + IPR_N0 + IPR_N0 + 0 + 8 + + + IPR_N1 + IPR_N1 + 8 + 8 + + + IPR_N2 + IPR_N2 + 16 + 8 + + + IPR_N3 + IPR_N3 + 24 + 8 + + + + + IPR1 + IPR1 + Interrupt Priority Register + 0x304 + 0x20 + read-write + 0x00000000 + + + IPR_N0 + IPR_N0 + 0 + 8 + + + IPR_N1 + IPR_N1 + 8 + 8 + + + IPR_N2 + IPR_N2 + 16 + 8 + + + IPR_N3 + IPR_N3 + 24 + 8 + + + + + IPR2 + IPR2 + Interrupt Priority Register + 0x308 + 0x20 + read-write + 0x00000000 + + + IPR_N0 + IPR_N0 + 0 + 8 + + + IPR_N1 + IPR_N1 + 8 + 8 + + + IPR_N2 + IPR_N2 + 16 + 8 + + + IPR_N3 + IPR_N3 + 24 + 8 + + + + + IPR3 + IPR3 + Interrupt Priority Register + 0x30C + 0x20 + read-write + 0x00000000 + + + IPR_N0 + IPR_N0 + 0 + 8 + + + IPR_N1 + IPR_N1 + 8 + 8 + + + IPR_N2 + IPR_N2 + 16 + 8 + + + IPR_N3 + IPR_N3 + 24 + 8 + + + + + IPR4 + IPR4 + Interrupt Priority Register + 0x310 + 0x20 + read-write + 0x00000000 + + + IPR_N0 + IPR_N0 + 0 + 8 + + + IPR_N1 + IPR_N1 + 8 + 8 + + + IPR_N2 + IPR_N2 + 16 + 8 + + + IPR_N3 + IPR_N3 + 24 + 8 + + + + + IPR5 + IPR5 + Interrupt Priority Register + 0x314 + 0x20 + read-write + 0x00000000 + + + IPR_N0 + IPR_N0 + 0 + 8 + + + IPR_N1 + IPR_N1 + 8 + 8 + + + IPR_N2 + IPR_N2 + 16 + 8 + + + IPR_N3 + IPR_N3 + 24 + 8 + + + + + IPR6 + IPR6 + Interrupt Priority Register + 0x318 + 0x20 + read-write + 0x00000000 + + + IPR_N0 + IPR_N0 + 0 + 8 + + + IPR_N1 + IPR_N1 + 8 + 8 + + + IPR_N2 + IPR_N2 + 16 + 8 + + + IPR_N3 + IPR_N3 + 24 + 8 + + + + + IPR7 + IPR7 + Interrupt Priority Register + 0x31C + 0x20 + read-write + 0x00000000 + + + IPR_N0 + IPR_N0 + 0 + 8 + + + IPR_N1 + IPR_N1 + 8 + 8 + + + IPR_N2 + IPR_N2 + 16 + 8 + + + IPR_N3 + IPR_N3 + 24 + 8 + + + + + IPR8 + IPR8 + Interrupt Priority Register + 0x320 + 0x20 + read-write + 0x00000000 + + + IPR_N0 + IPR_N0 + 0 + 8 + + + IPR_N1 + IPR_N1 + 8 + 8 + + + IPR_N2 + IPR_N2 + 16 + 8 + + + IPR_N3 + IPR_N3 + 24 + 8 + + + + + IPR9 + IPR9 + Interrupt Priority Register + 0x324 + 0x20 + read-write + 0x00000000 + + + IPR_N0 + IPR_N0 + 0 + 8 + + + IPR_N1 + IPR_N1 + 8 + 8 + + + IPR_N2 + IPR_N2 + 16 + 8 + + + IPR_N3 + IPR_N3 + 24 + 8 + + + + + IPR10 + IPR10 + Interrupt Priority Register + 0x328 + 0x20 + read-write + 0x00000000 + + + IPR_N0 + IPR_N0 + 0 + 8 + + + IPR_N1 + IPR_N1 + 8 + 8 + + + IPR_N2 + IPR_N2 + 16 + 8 + + + IPR_N3 + IPR_N3 + 24 + 8 + + + + + IPR11 + IPR11 + Interrupt Priority Register + 0x32C + 0x20 + read-write + 0x00000000 + + + IPR_N0 + IPR_N0 + 0 + 8 + + + IPR_N1 + IPR_N1 + 8 + 8 + + + IPR_N2 + IPR_N2 + 16 + 8 + + + IPR_N3 + IPR_N3 + 24 + 8 + + + + + IPR12 + IPR12 + Interrupt Priority Register + 0x330 + 0x20 + read-write + 0x00000000 + + + IPR_N0 + IPR_N0 + 0 + 8 + + + IPR_N1 + IPR_N1 + 8 + 8 + + + IPR_N2 + IPR_N2 + 16 + 8 + + + IPR_N3 + IPR_N3 + 24 + 8 + + + + + IPR13 + IPR13 + Interrupt Priority Register + 0x334 + 0x20 + read-write + 0x00000000 + + + IPR_N0 + IPR_N0 + 0 + 8 + + + IPR_N1 + IPR_N1 + 8 + 8 + + + IPR_N2 + IPR_N2 + 16 + 8 + + + IPR_N3 + IPR_N3 + 24 + 8 + + + + + IPR14 + IPR14 + Interrupt Priority Register + 0x338 + 0x20 + read-write + 0x00000000 + + + IPR_N0 + IPR_N0 + 0 + 8 + + + IPR_N1 + IPR_N1 + 8 + 8 + + + IPR_N2 + IPR_N2 + 16 + 8 + + + IPR_N3 + IPR_N3 + 24 + 8 + + + + + IPR15 + IPR15 + Interrupt Priority Register + 0x33C + 0x20 + read-write + 0x00000000 + + + IPR_N0 + IPR_N0 + 0 + 8 + + + IPR_N1 + IPR_N1 + 8 + 8 + + + IPR_N2 + IPR_N2 + 16 + 8 + + + IPR_N3 + IPR_N3 + 24 + 8 + + + + + IPR16 + IPR16 + Interrupt Priority Register + 0x340 + 0x20 + read-write + 0x00000000 + + + IPR_N0 + IPR_N0 + 0 + 8 + + + IPR_N1 + IPR_N1 + 8 + 8 + + + IPR_N2 + IPR_N2 + 16 + 8 + + + IPR_N3 + IPR_N3 + 24 + 8 + + + + + IPR17 + IPR17 + Interrupt Priority Register + 0x344 + 0x20 + read-write + 0x00000000 + + + IPR_N0 + IPR_N0 + 0 + 8 + + + IPR_N1 + IPR_N1 + 8 + 8 + + + IPR_N2 + IPR_N2 + 16 + 8 + + + IPR_N3 + IPR_N3 + 24 + 8 + + + + + IPR18 + IPR18 + Interrupt Priority Register + 0x348 + 0x20 + read-write + 0x00000000 + + + IPR_N0 + IPR_N0 + 0 + 8 + + + IPR_N1 + IPR_N1 + 8 + 8 + + + IPR_N2 + IPR_N2 + 16 + 8 + + + IPR_N3 + IPR_N3 + 24 + 8 + + + + + IPR19 + IPR19 + Interrupt Priority Register + 0x34C + 0x20 + read-write + 0x00000000 + + + IPR_N0 + IPR_N0 + 0 + 8 + + + IPR_N1 + IPR_N1 + 8 + 8 + + + IPR_N2 + IPR_N2 + 16 + 8 + + + IPR_N3 + IPR_N3 + 24 + 8 + + + + + + + FPU + Floting point unit + FPU + 0xE000EF34 + + 0x0 + 0xD + registers + + + FPU + Floating point unit interrupt + 81 + + + + FPCCR + FPCCR + Floating-point context control + register + 0x0 + 0x20 + read-write + 0x00000000 + + + LSPACT + LSPACT + 0 + 1 + + + USER + USER + 1 + 1 + + + THREAD + THREAD + 3 + 1 + + + HFRDY + HFRDY + 4 + 1 + + + MMRDY + MMRDY + 5 + 1 + + + BFRDY + BFRDY + 6 + 1 + + + MONRDY + MONRDY + 8 + 1 + + + LSPEN + LSPEN + 30 + 1 + + + ASPEN + ASPEN + 31 + 1 + + + + + FPCAR + FPCAR + Floating-point context address + register + 0x4 + 0x20 + read-write + 0x00000000 + + + ADDRESS + Location of unpopulated + floating-point + 3 + 29 + + + + + FPSCR + FPSCR + Floating-point status control + register + 0x8 + 0x20 + read-write + 0x00000000 + + + IOC + Invalid operation cumulative exception + bit + 0 + 1 + + + DZC + Division by zero cumulative exception + bit. + 1 + 1 + + + OFC + Overflow cumulative exception + bit + 2 + 1 + + + UFC + Underflow cumulative exception + bit + 3 + 1 + + + IXC + Inexact cumulative exception + bit + 4 + 1 + + + IDC + Input denormal cumulative exception + bit. + 7 + 1 + + + RMode + Rounding Mode control + field + 22 + 2 + + + FZ + Flush-to-zero mode control + bit: + 24 + 1 + + + DN + Default NaN mode control + bit + 25 + 1 + + + AHP + Alternative half-precision control + bit + 26 + 1 + + + V + Overflow condition code + flag + 28 + 1 + + + C + Carry condition code flag + 29 + 1 + + + Z + Zero condition code flag + 30 + 1 + + + N + Negative condition code + flag + 31 + 1 + + + + + + + MPU + Memory protection unit + MPU + 0xE000ED90 + + 0x0 + 0x15 + registers + + + + TYPER + TYPER + MPU type register + 0x0 + 0x20 + read-only + 0x00000800 + + + SEPARATE + Separate flag + 0 + 1 + + + DREGION + Number of MPU data regions + 8 + 8 + + + IREGION + Number of MPU instruction + regions + 16 + 8 + + + + + CTRL + CTRL + MPU control register + 0x4 + 0x20 + read-only + 0x00000000 + + + ENABLE + Enables the MPU + 0 + 1 + + + HFNMIENA + Enables the operation of MPU during hard + fault + 1 + 1 + + + PRIVDEFENA + Enable priviliged software access to + default memory map + 2 + 1 + + + + + RNR + RNR + MPU region number register + 0x8 + 0x20 + read-write + 0x00000000 + + + REGION + MPU region + 0 + 8 + + + + + RBAR + RBAR + MPU region base address + register + 0xC + 0x20 + read-write + 0x00000000 + + + REGION + MPU region field + 0 + 4 + + + VALID + MPU region number valid + 4 + 1 + + + ADDR + Region base address field + 5 + 27 + + + + + RASR + RASR + MPU region attribute and size + register + 0x10 + 0x20 + read-write + 0x00000000 + + + ENABLE + Region enable bit. + 0 + 1 + + + SIZE + Size of the MPU protection + region + 1 + 5 + + + SRD + Subregion disable bits + 8 + 8 + + + B + memory attribute + 16 + 1 + + + C + memory attribute + 17 + 1 + + + S + Shareable memory attribute + 18 + 1 + + + TEX + memory attribute + 19 + 3 + + + AP + Access permission + 24 + 3 + + + XN + Instruction access disable + bit + 28 + 1 + + + + + + + STK + SysTick timer + STK + 0xE000E010 + + 0x0 + 0x11 + registers + + + + CTRL + CTRL + SysTick control and status + register + 0x0 + 0x20 + read-write + 0x00000000 + + + ENABLE + Counter enable + 0 + 1 + + + TICKINT + SysTick exception request + enable + 1 + 1 + + + CLKSOURCE + Clock source selection + 2 + 1 + + + COUNTFLAG + COUNTFLAG + 16 + 1 + + + + + LOAD + LOAD + SysTick reload value register + 0x4 + 0x20 + read-write + 0x00000000 + + + RELOAD + RELOAD value + 0 + 24 + + + + + VAL + VAL + SysTick current value register + 0x8 + 0x20 + read-write + 0x00000000 + + + CURRENT + Current counter value + 0 + 24 + + + + + CALIB + CALIB + SysTick calibration value + register + 0xC + 0x20 + read-write + 0x00000000 + + + TENMS + Calibration value + 0 + 24 + + + SKEW + SKEW flag: Indicates whether the TENMS + value is exact + 30 + 1 + + + NOREF + NOREF flag. Reads as zero + 31 + 1 + + + + + + + SCB + System control block + SCB + 0xE000ED00 + + 0x0 + 0x41 + registers + + + + CPUID + CPUID + CPUID base register + 0x0 + 0x20 + read-only + 0x410FC241 + + + Revision + Revision number + 0 + 4 + + + PartNo + Part number of the + processor + 4 + 12 + + + Constant + Reads as 0xF + 16 + 4 + + + Variant + Variant number + 20 + 4 + + + Implementer + Implementer code + 24 + 8 + + + + + ICSR + ICSR + Interrupt control and state + register + 0x4 + 0x20 + read-write + 0x00000000 + + + VECTACTIVE + Active vector + 0 + 9 + + + RETTOBASE + Return to base level + 11 + 1 + + + VECTPENDING + Pending vector + 12 + 7 + + + ISRPENDING + Interrupt pending flag + 22 + 1 + + + PENDSTCLR + SysTick exception clear-pending + bit + 25 + 1 + + + PENDSTSET + SysTick exception set-pending + bit + 26 + 1 + + + PENDSVCLR + PendSV clear-pending bit + 27 + 1 + + + PENDSVSET + PendSV set-pending bit + 28 + 1 + + + NMIPENDSET + NMI set-pending bit. + 31 + 1 + + + + + VTOR + VTOR + Vector table offset register + 0x8 + 0x20 + read-write + 0x00000000 + + + TBLOFF + Vector table base offset + field + 9 + 21 + + + + + AIRCR + AIRCR + Application interrupt and reset control + register + 0xC + 0x20 + read-write + 0x00000000 + + + VECTRESET + VECTRESET + 0 + 1 + + + VECTCLRACTIVE + VECTCLRACTIVE + 1 + 1 + + + SYSRESETREQ + SYSRESETREQ + 2 + 1 + + + PRIGROUP + PRIGROUP + 8 + 3 + + + ENDIANESS + ENDIANESS + 15 + 1 + + + VECTKEYSTAT + Register key + 16 + 16 + + + + + SCR + SCR + System control register + 0x10 + 0x20 + read-write + 0x00000000 + + + SLEEPONEXIT + SLEEPONEXIT + 1 + 1 + + + SLEEPDEEP + SLEEPDEEP + 2 + 1 + + + SEVEONPEND + Send Event on Pending bit + 4 + 1 + + + + + CCR + CCR + Configuration and control + register + 0x14 + 0x20 + read-write + 0x00000000 + + + NONBASETHRDENA + Configures how the processor enters + Thread mode + 0 + 1 + + + USERSETMPEND + USERSETMPEND + 1 + 1 + + + UNALIGN__TRP + UNALIGN_ TRP + 3 + 1 + + + DIV_0_TRP + DIV_0_TRP + 4 + 1 + + + BFHFNMIGN + BFHFNMIGN + 8 + 1 + + + STKALIGN + STKALIGN + 9 + 1 + + + + + SHPR1 + SHPR1 + System handler priority + registers + 0x18 + 0x20 + read-write + 0x00000000 + + + PRI_4 + Priority of system handler + 4 + 0 + 8 + + + PRI_5 + Priority of system handler + 5 + 8 + 8 + + + PRI_6 + Priority of system handler + 6 + 16 + 8 + + + + + SHPR2 + SHPR2 + System handler priority + registers + 0x1C + 0x20 + read-write + 0x00000000 + + + PRI_11 + Priority of system handler + 11 + 24 + 8 + + + + + SHPR3 + SHPR3 + System handler priority + registers + 0x20 + 0x20 + read-write + 0x00000000 + + + PRI_14 + Priority of system handler + 14 + 16 + 8 + + + PRI_15 + Priority of system handler + 15 + 24 + 8 + + + + + SHCRS + SHCRS + System handler control and state + register + 0x24 + 0x20 + read-write + 0x00000000 + + + MEMFAULTACT + Memory management fault exception active + bit + 0 + 1 + + + BUSFAULTACT + Bus fault exception active + bit + 1 + 1 + + + USGFAULTACT + Usage fault exception active + bit + 3 + 1 + + + SVCALLACT + SVC call active bit + 7 + 1 + + + MONITORACT + Debug monitor active bit + 8 + 1 + + + PENDSVACT + PendSV exception active + bit + 10 + 1 + + + SYSTICKACT + SysTick exception active + bit + 11 + 1 + + + USGFAULTPENDED + Usage fault exception pending + bit + 12 + 1 + + + MEMFAULTPENDED + Memory management fault exception + pending bit + 13 + 1 + + + BUSFAULTPENDED + Bus fault exception pending + bit + 14 + 1 + + + SVCALLPENDED + SVC call pending bit + 15 + 1 + + + MEMFAULTENA + Memory management fault enable + bit + 16 + 1 + + + BUSFAULTENA + Bus fault enable bit + 17 + 1 + + + USGFAULTENA + Usage fault enable bit + 18 + 1 + + + + + CFSR_UFSR_BFSR_MMFSR + CFSR_UFSR_BFSR_MMFSR + Configurable fault status + register + 0x28 + 0x20 + read-write + 0x00000000 + + + IACCVIOL + Instruction access violation + flag + 1 + 1 + + + MUNSTKERR + Memory manager fault on unstacking for a + return from exception + 3 + 1 + + + MSTKERR + Memory manager fault on stacking for + exception entry. + 4 + 1 + + + MLSPERR + MLSPERR + 5 + 1 + + + MMARVALID + Memory Management Fault Address Register + (MMAR) valid flag + 7 + 1 + + + IBUSERR + Instruction bus error + 8 + 1 + + + PRECISERR + Precise data bus error + 9 + 1 + + + IMPRECISERR + Imprecise data bus error + 10 + 1 + + + UNSTKERR + Bus fault on unstacking for a return + from exception + 11 + 1 + + + STKERR + Bus fault on stacking for exception + entry + 12 + 1 + + + LSPERR + Bus fault on floating-point lazy state + preservation + 13 + 1 + + + BFARVALID + Bus Fault Address Register (BFAR) valid + flag + 15 + 1 + + + UNDEFINSTR + Undefined instruction usage + fault + 16 + 1 + + + INVSTATE + Invalid state usage fault + 17 + 1 + + + INVPC + Invalid PC load usage + fault + 18 + 1 + + + NOCP + No coprocessor usage + fault. + 19 + 1 + + + UNALIGNED + Unaligned access usage + fault + 24 + 1 + + + DIVBYZERO + Divide by zero usage fault + 25 + 1 + + + + + HFSR + HFSR + Hard fault status register + 0x2C + 0x20 + read-write + 0x00000000 + + + VECTTBL + Vector table hard fault + 1 + 1 + + + FORCED + Forced hard fault + 30 + 1 + + + DEBUG_VT + Reserved for Debug use + 31 + 1 + + + + + MMFAR + MMFAR + Memory management fault address + register + 0x34 + 0x20 + read-write + 0x00000000 + + + MMFAR + Memory management fault + address + 0 + 32 + + + + + BFAR + BFAR + Bus fault address register + 0x38 + 0x20 + read-write + 0x00000000 + + + BFAR + Bus fault address + 0 + 32 + + + + + AFSR + AFSR + Auxiliary fault status + register + 0x3C + 0x20 + read-write + 0x00000000 + + + IMPDEF + Implementation defined + 0 + 32 + + + + + + + NVIC_STIR + Nested vectored interrupt + controller + NVIC + 0xE000EF00 + + 0x0 + 0x5 + registers + + + + STIR + STIR + Software trigger interrupt + register + 0x0 + 0x20 + read-write + 0x00000000 + + + INTID + Software generated interrupt + ID + 0 + 9 + + + + + + + FPU_CPACR + Floating point unit CPACR + FPU + 0xE000ED88 + + 0x0 + 0x5 + registers + + + + CPACR + CPACR + Coprocessor access control + register + 0x0 + 0x20 + read-write + 0x00000000 + + + CP + CP + 20 + 4 + + + + + + + SCB_ACTRL + System control block ACTLR + SCB + 0xE000E008 + + 0x0 + 0x5 + registers + + + + ACTRL + ACTRL + Auxiliary control register + 0x0 + 0x20 + read-write + 0x00000000 + + + DISMCYCINT + DISMCYCINT + 0 + 1 + + + DISDEFWBUF + DISDEFWBUF + 1 + 1 + + + DISFOLD + DISFOLD + 2 + 1 + + + DISFPCA + DISFPCA + 8 + 1 + + + DISOOFP + DISOOFP + 9 + 1 + + + + + + + \ No newline at end of file diff --git a/nodes/embassy/test-wiznet/.cargo/config.toml b/nodes/embassy/test-wiznet/.cargo/config.toml new file mode 100644 index 00000000..b0f2a66e --- /dev/null +++ b/nodes/embassy/test-wiznet/.cargo/config.toml @@ -0,0 +1,18 @@ +[target.'cfg(all(target_arch = "arm", target_os = "none"))'] +# replace STM32F103C8 with your chip as listed in `probe-rs chip list` +# runner = "probe-rs run --chip STM32F103C8" +# runner = "probe-rs run --chip STM32F401CCUx --host ws://192.168.1.43:3000 --token secret_token_redacted --probe c251:f001:202108120001" +runner = "probe-rs run --chip STM32F401CCUx" +linker = "flip-link" + +[build] +# target = "thumbv7m-none-eabi" for f103 +target = "thumbv7em-none-eabihf" + +[env] +DEFMT_LOG = "debug,sps30_async=warn,bosch_bme680=info" +EMBASSY_EXECUTOR_TASK_ARENA_SIZE="10900" + +# [unstable] +# build-std = ["core"] +# build-std-features = ["panic_immediate_abort"] diff --git a/nodes/embassy/test-wiznet/Cargo.lock b/nodes/embassy/test-wiznet/Cargo.lock new file mode 100644 index 00000000..50cd7987 --- /dev/null +++ b/nodes/embassy/test-wiznet/Cargo.lock @@ -0,0 +1,1274 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 3 + +[[package]] +name = "ahash" +version = "0.8.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e89da841a80418a9b391ebaea17f5c112ffaaa96f621d2c285b5174da76b9011" +dependencies = [ + "cfg-if", + "once_cell", + "version_check", + "zerocopy", +] + +[[package]] +name = "aligned" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "377e4c0ba83e4431b10df45c1d4666f178ea9c552cac93e60c3a88bf32785923" +dependencies = [ + "as-slice", +] + +[[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 = "atomic-polyfill" +version = "1.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8cf2bce30dfe09ef0bfaef228b9d414faaf7e563035494d7fe092dba54b300f4" +dependencies = [ + "critical-section", +] + +[[package]] +name = "autocfg" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0c4b4d0bd25bd0b74681c0ad21497610ce1b7c91b1022cd21c80c6fbdd9476b0" + +[[package]] +name = "bare-metal" +version = "0.2.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5deb64efa5bd81e31fcd1938615a6d98c82eafcbcd787162b6f63b91d6bac5b3" +dependencies = [ + "rustc_version 0.2.3", +] + +[[package]] +name = "bed-sensors" +version = "0.2.0" +dependencies = [ + "bosch-bme680", + "cortex-m", + "cortex-m-rt", + "defmt", + "defmt-rtt", + "embassy-embedded-hal", + "embassy-executor", + "embassy-futures", + "embassy-stm32", + "embassy-sync", + "embassy-time", + "embassy-usb", + "embedded-hal 1.0.0", + "embedded-hal-async", + "embedded-hal-bus", + "embedded-io-async", + "futures", + "heapless 0.8.0", + "max44009", + "mhzx", + "nau7802-async", + "nb 1.1.0", + "panic-probe", + "protocol", + "rand", + "sht31", + "sps30-async", + "static_cell", +] + +[[package]] +name = "bit_field" +version = "0.10.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dc827186963e592360843fb5ba4b973e145841266c1357f7180c43526f2e5b61" + +[[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.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b048fb63fd8b5923fc5aa7b340d8e156aec7ec02f0c78fa8a6ddc2613f6f71de" + +[[package]] +name = "block-device-driver" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "44c051592f59fe68053524b4c4935249b806f72c1f544cfb7abe4f57c3be258e" +dependencies = [ + "aligned", +] + +[[package]] +name = "bosch-bme680" +version = "1.0.2" +dependencies = [ + "bitfield 0.14.0", + "defmt", + "embedded-hal 1.0.0", + "embedded-hal-async", +] + +[[package]] +name = "byteorder" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" + +[[package]] +name = "cfg-if" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" + +[[package]] +name = "cobs" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "67ba02a97a2bd10f4b59b25c7973101c79642302776489e030cd13cdab09ed15" + +[[package]] +name = "cortex-m" +version = "0.7.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8ec610d8f49840a5b376c69663b6369e71f4b34484b9b2eb29fb918d92516cb9" +dependencies = [ + "bare-metal", + "bitfield 0.13.2", + "critical-section", + "embedded-hal 0.2.7", + "volatile-register", +] + +[[package]] +name = "cortex-m-rt" +version = "0.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ee84e813d593101b1723e13ec38b6ab6abbdbaaa4546553f5395ed274079ddb1" +dependencies = [ + "cortex-m-rt-macros", +] + +[[package]] +name = "cortex-m-rt-macros" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f0f6f3e36f203cfedbc78b357fb28730aa2c6dc1ab060ee5c2405e843988d3c7" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "crc" +version = "3.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "69e6e4d7b33a94f0991c26729976b10ebde1d34c3ee82408fb536164fa10d636" +dependencies = [ + "crc-catalog", +] + +[[package]] +name = "crc-catalog" +version = "2.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "19d374276b40fb8bbdee95aef7c7fa6b5316ec764510eb64b8dd0e2ed0d7e7f5" + +[[package]] +name = "critical-section" +version = "1.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f64009896348fc5af4222e9cf7d7d82a95a256c634ebcf61c53e4ea461422242" + +[[package]] +name = "darling" +version = "0.20.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6f63b86c8a8826a49b8c21f08a2d07338eec8d900540f8630dc76284be802989" +dependencies = [ + "darling_core", + "darling_macro", +] + +[[package]] +name = "darling_core" +version = "0.20.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "95133861a8032aaea082871032f5815eb9e98cef03fa916ab4500513994df9e5" +dependencies = [ + "fnv", + "ident_case", + "proc-macro2", + "quote", + "strsim", + "syn 2.0.77", +] + +[[package]] +name = "darling_macro" +version = "0.20.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d336a2a514f6ccccaa3e09b02d41d35330c07ddf03a62165fcec10bb561c7806" +dependencies = [ + "darling_core", + "quote", + "syn 2.0.77", +] + +[[package]] +name = "defmt" +version = "0.3.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a99dd22262668b887121d4672af5a64b238f026099f1a2a1b322066c9ecfe9e0" +dependencies = [ + "bitflags 1.3.2", + "defmt-macros", +] + +[[package]] +name = "defmt-macros" +version = "0.3.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e3a9f309eff1f79b3ebdf252954d90ae440599c26c2c553fe87a2d17195f2dcb" +dependencies = [ + "defmt-parser", + "proc-macro-error", + "proc-macro2", + "quote", + "syn 2.0.77", +] + +[[package]] +name = "defmt-parser" +version = "0.3.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ff4a5fefe330e8d7f31b16a318f9ce81000d8e35e69b93eae154d16d2278f70f" +dependencies = [ + "thiserror", +] + +[[package]] +name = "defmt-rtt" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bab697b3dbbc1750b7c8b821aa6f6e7f2480b47a99bc057a2ed7b170ebef0c51" +dependencies = [ + "critical-section", + "defmt", +] + +[[package]] +name = "document-features" +version = "0.2.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cb6969eaabd2421f8a2775cfd2471a2b634372b4a25d41e3bd647b79912850a0" +dependencies = [ + "litrs", +] + +[[package]] +name = "embassy-embedded-hal" +version = "0.2.0" +source = "git+https://github.com/embassy-rs/embassy?rev=d7780fc#d7780fcf83a8a35d7b09e5df7b62dd8218436715" +dependencies = [ + "defmt", + "embassy-futures", + "embassy-sync", + "embassy-time", + "embedded-hal 0.2.7", + "embedded-hal 1.0.0", + "embedded-hal-async", + "embedded-storage", + "embedded-storage-async", + "nb 1.1.0", +] + +[[package]] +name = "embassy-executor" +version = "0.6.0" +source = "git+https://github.com/embassy-rs/embassy?rev=d7780fc#d7780fcf83a8a35d7b09e5df7b62dd8218436715" +dependencies = [ + "cortex-m", + "critical-section", + "defmt", + "document-features", + "embassy-executor-macros", + "embassy-time-driver", + "embassy-time-queue-driver", +] + +[[package]] +name = "embassy-executor-macros" +version = "0.5.0" +source = "git+https://github.com/embassy-rs/embassy?rev=d7780fc#d7780fcf83a8a35d7b09e5df7b62dd8218436715" +dependencies = [ + "darling", + "proc-macro2", + "quote", + "syn 2.0.77", +] + +[[package]] +name = "embassy-futures" +version = "0.1.1" +source = "git+https://github.com/embassy-rs/embassy?rev=d7780fc#d7780fcf83a8a35d7b09e5df7b62dd8218436715" + +[[package]] +name = "embassy-hal-internal" +version = "0.2.0" +source = "git+https://github.com/embassy-rs/embassy?rev=d7780fc#d7780fcf83a8a35d7b09e5df7b62dd8218436715" +dependencies = [ + "cortex-m", + "critical-section", + "defmt", + "num-traits", +] + +[[package]] +name = "embassy-net-driver" +version = "0.2.0" +source = "git+https://github.com/embassy-rs/embassy?rev=d7780fc#d7780fcf83a8a35d7b09e5df7b62dd8218436715" +dependencies = [ + "defmt", +] + +[[package]] +name = "embassy-net-driver-channel" +version = "0.3.0" +source = "git+https://github.com/embassy-rs/embassy?rev=d7780fc#d7780fcf83a8a35d7b09e5df7b62dd8218436715" +dependencies = [ + "embassy-futures", + "embassy-net-driver", + "embassy-sync", +] + +[[package]] +name = "embassy-stm32" +version = "0.1.0" +source = "git+https://github.com/embassy-rs/embassy?rev=d7780fc#d7780fcf83a8a35d7b09e5df7b62dd8218436715" +dependencies = [ + "aligned", + "bit_field", + "bitflags 2.6.0", + "block-device-driver", + "cfg-if", + "cortex-m", + "cortex-m-rt", + "critical-section", + "defmt", + "document-features", + "embassy-embedded-hal", + "embassy-futures", + "embassy-hal-internal", + "embassy-net-driver", + "embassy-sync", + "embassy-time", + "embassy-time-driver", + "embassy-usb-driver", + "embassy-usb-synopsys-otg", + "embedded-can", + "embedded-hal 0.2.7", + "embedded-hal 1.0.0", + "embedded-hal-async", + "embedded-hal-nb", + "embedded-io", + "embedded-io-async", + "embedded-storage", + "embedded-storage-async", + "futures-util", + "nb 1.1.0", + "proc-macro2", + "quote", + "rand_core", + "sdio-host", + "static_assertions", + "stm32-fmc", + "stm32-metapac", + "vcell", + "volatile-register", +] + +[[package]] +name = "embassy-sync" +version = "0.6.0" +source = "git+https://github.com/embassy-rs/embassy?rev=d7780fc#d7780fcf83a8a35d7b09e5df7b62dd8218436715" +dependencies = [ + "cfg-if", + "critical-section", + "defmt", + "embedded-io-async", + "futures-util", + "heapless 0.8.0", +] + +[[package]] +name = "embassy-time" +version = "0.3.2" +source = "git+https://github.com/embassy-rs/embassy?rev=d7780fc#d7780fcf83a8a35d7b09e5df7b62dd8218436715" +dependencies = [ + "cfg-if", + "critical-section", + "defmt", + "document-features", + "embassy-time-driver", + "embassy-time-queue-driver", + "embedded-hal 0.2.7", + "embedded-hal 1.0.0", + "embedded-hal-async", + "futures-util", + "heapless 0.8.0", +] + +[[package]] +name = "embassy-time-driver" +version = "0.1.0" +source = "git+https://github.com/embassy-rs/embassy?rev=d7780fc#d7780fcf83a8a35d7b09e5df7b62dd8218436715" +dependencies = [ + "document-features", +] + +[[package]] +name = "embassy-time-queue-driver" +version = "0.1.0" +source = "git+https://github.com/embassy-rs/embassy?rev=d7780fc#d7780fcf83a8a35d7b09e5df7b62dd8218436715" + +[[package]] +name = "embassy-usb" +version = "0.3.0" +source = "git+https://github.com/embassy-rs/embassy?rev=d7780fc#d7780fcf83a8a35d7b09e5df7b62dd8218436715" +dependencies = [ + "defmt", + "embassy-futures", + "embassy-net-driver-channel", + "embassy-sync", + "embassy-usb-driver", + "heapless 0.8.0", + "ssmarshal", + "usbd-hid", +] + +[[package]] +name = "embassy-usb-driver" +version = "0.1.0" +source = "git+https://github.com/embassy-rs/embassy?rev=d7780fc#d7780fcf83a8a35d7b09e5df7b62dd8218436715" +dependencies = [ + "defmt", +] + +[[package]] +name = "embassy-usb-synopsys-otg" +version = "0.1.0" +source = "git+https://github.com/embassy-rs/embassy?rev=d7780fc#d7780fcf83a8a35d7b09e5df7b62dd8218436715" +dependencies = [ + "critical-section", + "embassy-sync", + "embassy-usb-driver", +] + +[[package]] +name = "embedded-can" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e9d2e857f87ac832df68fa498d18ddc679175cf3d2e4aa893988e5601baf9438" +dependencies = [ + "nb 1.1.0", +] + +[[package]] +name = "embedded-hal" +version = "0.2.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "35949884794ad573cf46071e41c9b60efb0cb311e3ca01f7af807af1debc66ff" +dependencies = [ + "nb 0.1.3", + "void", +] + +[[package]] +name = "embedded-hal" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "361a90feb7004eca4019fb28352a9465666b24f840f5c3cddf0ff13920590b89" +dependencies = [ + "defmt", +] + +[[package]] +name = "embedded-hal-async" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0c4c685bbef7fe13c3c6dd4da26841ed3980ef33e841cddfa15ce8a8fb3f1884" +dependencies = [ + "defmt", + "embedded-hal 1.0.0", +] + +[[package]] +name = "embedded-hal-bus" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0d3980bf28e8577db59fe2bdb3df868a419469d2cecb363644eea2b6f7797669" +dependencies = [ + "critical-section", + "defmt", + "embedded-hal 1.0.0", + "embedded-hal-async", + "portable-atomic", +] + +[[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" +dependencies = [ + "defmt", +] + +[[package]] +name = "embedded-io-async" +version = "0.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3ff09972d4073aa8c299395be75161d582e7629cd663171d62af73c8d50dba3f" +dependencies = [ + "defmt", + "embedded-io", +] + +[[package]] +name = "embedded-storage" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a21dea9854beb860f3062d10228ce9b976da520a73474aed3171ec276bc0c032" + +[[package]] +name = "embedded-storage-async" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1763775e2323b7d5f0aa6090657f5e21cfa02ede71f5dc40eead06d64dcd15cc" +dependencies = [ + "embedded-storage", +] + +[[package]] +name = "encode_unicode" +version = "0.3.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a357d28ed41a50f9c765dbfe56cbc04a64e53e5fc58ba79fbc34c10ef3df831f" + +[[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.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "645c6916888f6cb6350d2550b80fb63e734897a8498abe35cfb732b6487804b0" +dependencies = [ + "futures-channel", + "futures-core", + "futures-io", + "futures-sink", + "futures-task", + "futures-util", +] + +[[package]] +name = "futures-channel" +version = "0.3.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eac8f7d7865dcb88bd4373ab671c8cf4508703796caa2b1985a9ca867b3fcb78" +dependencies = [ + "futures-core", + "futures-sink", +] + +[[package]] +name = "futures-core" +version = "0.3.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dfc6580bb841c5a68e9ef15c77ccc837b40a7504914d52e47b8b0e9bbda25a1d" + +[[package]] +name = "futures-io" +version = "0.3.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a44623e20b9681a318efdd71c299b6b222ed6f231972bfe2f224ebad6311f0c1" + +[[package]] +name = "futures-macro" +version = "0.3.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "87750cf4b7a4c0625b1529e4c543c2182106e4dedc60a2a6455e00d212c489ac" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.77", +] + +[[package]] +name = "futures-sink" +version = "0.3.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9fb8e00e87438d937621c1c6269e53f536c14d3fbd6a042bb24879e57d474fb5" + +[[package]] +name = "futures-task" +version = "0.3.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "38d84fa142264698cdce1a9f9172cf383a0c82de1bddcf3092901442c4097004" + +[[package]] +name = "futures-util" +version = "0.3.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3d6401deb83407ab3da39eba7e33987a73c3df0c82b4bb5813ee871c19c41d48" +dependencies = [ + "futures-core", + "futures-macro", + "futures-sink", + "futures-task", + "pin-project-lite", + "pin-utils", +] + +[[package]] +name = "hash32" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b0c35f58762feb77d74ebe43bdbc3210f09be9fe6742234d573bacc26ed92b67" +dependencies = [ + "byteorder", +] + +[[package]] +name = "hash32" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "47d60b12902ba28e2730cd37e95b8c9223af2808df9e902d4df49588d1470606" +dependencies = [ + "byteorder", +] + +[[package]] +name = "hashbrown" +version = "0.13.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "43a3c133739dddd0d2990f9a4bdf8eb4b21ef50e4851ca85ab661199821d510e" +dependencies = [ + "ahash", +] + +[[package]] +name = "heapless" +version = "0.7.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cdc6457c0eb62c71aac4bc17216026d8410337c4126773b9c5daba343f17964f" +dependencies = [ + "atomic-polyfill", + "hash32 0.2.1", + "rustc_version 0.4.1", + "serde", + "spin", + "stable_deref_trait", +] + +[[package]] +name = "heapless" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0bfb9eb618601c89945a70e254898da93b13be0388091d42117462b265bb3fad" +dependencies = [ + "defmt", + "hash32 0.3.1", + "serde", + "stable_deref_trait", +] + +[[package]] +name = "heck" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea" + +[[package]] +name = "ident_case" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b9e0384b61958566e926dc50660321d12159025e767c18e043daf26b70104c39" + +[[package]] +name = "litrs" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b4ce301924b7887e9d637144fdade93f9dfff9b60981d4ac161db09720d39aa5" + +[[package]] +name = "lock_api" +version = "0.4.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "07af8b9cdd281b7915f413fa73f29ebd5d55d0d3f0155584dade1ff18cea1b17" +dependencies = [ + "autocfg", + "scopeguard", +] + +[[package]] +name = "log" +version = "0.4.22" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a7a70ba024b9dc04c27ea2f0c0548feb474ec5c54bba33a7f72f873a39d07b24" + +[[package]] +name = "max44009" +version = "0.2.0" +source = "git+https://github.com/dvdsk/max44009-rs#7b7df2e3173476c250fca3eb242f0dd366857599" +dependencies = [ + "defmt", + "embedded-hal-async", +] + +[[package]] +name = "mhzx" +version = "0.3.0" +dependencies = [ + "defmt", + "embedded-io-async", + "heapless 0.8.0", + "postcard", + "serde", +] + +[[package]] +name = "nau7802-async" +version = "0.2.0" +dependencies = [ + "byteorder", + "defmt", + "embedded-hal-async", + "postcard", + "serde", +] + +[[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 = "num-traits" +version = "0.2.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841" +dependencies = [ + "autocfg", +] + +[[package]] +name = "once_cell" +version = "1.19.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3fdb12b2476b595f9358c5161aa467c2438859caa136dec86c26fdd2efe17b92" + +[[package]] +name = "panic-probe" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4047d9235d1423d66cc97da7d07eddb54d4f154d6c13805c6d0793956f4f25b0" +dependencies = [ + "cortex-m", + "defmt", +] + +[[package]] +name = "pin-project-lite" +version = "0.2.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bda66fc9667c18cb2758a2ac84d1167245054bcf85d5d1aaa6923f45801bdd02" + +[[package]] +name = "pin-utils" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" + +[[package]] +name = "portable-atomic" +version = "1.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d30538d42559de6b034bc76fd6dd4c38961b1ee5c6c56e3808c50128fdbc22ce" + +[[package]] +name = "postcard" +version = "1.0.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5f7f0a8d620d71c457dd1d47df76bb18960378da56af4527aaa10f515eee732e" +dependencies = [ + "cobs", + "defmt", + "heapless 0.7.17", + "postcard-derive", + "serde", +] + +[[package]] +name = "postcard-derive" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0239fa9c1d225d4b7eb69925c25c5e082307a141e470573fbbe3a817ce6a7a37" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "proc-macro-error" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "da25490ff9892aab3fcf7c36f08cfb902dd3e71ca0f9f9517bea02a73a5ce38c" +dependencies = [ + "proc-macro-error-attr", + "proc-macro2", + "quote", + "syn 1.0.109", + "version_check", +] + +[[package]] +name = "proc-macro-error-attr" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a1be40180e52ecc98ad80b184934baf3d0d29f979574e439af5a55274b35f869" +dependencies = [ + "proc-macro2", + "quote", + "version_check", +] + +[[package]] +name = "proc-macro2" +version = "1.0.86" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5e719e8df665df0d1c8fbfd238015744736151d4445ec0836b8e628aae103b77" +dependencies = [ + "unicode-ident", +] + +[[package]] +name = "protocol" +version = "0.1.0" +dependencies = [ + "defmt", + "heapless 0.8.0", + "postcard", + "serde", + "strum", +] + +[[package]] +name = "quote" +version = "1.0.37" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b5b9d34b8991d19d98081b46eacdd8eb58c6f2b201139f7c5f643cc155a633af" +dependencies = [ + "proc-macro2", +] + +[[package]] +name = "rand" +version = "0.8.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404" +dependencies = [ + "rand_core", +] + +[[package]] +name = "rand_core" +version = "0.6.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" + +[[package]] +name = "rustc_version" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "138e3e0acb6c9fb258b19b67cb8abd63c00679d2851805ea151465464fe9030a" +dependencies = [ + "semver 0.9.0", +] + +[[package]] +name = "rustc_version" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cfcb3a22ef46e85b45de6ee7e79d063319ebb6594faafcf1c225ea92ab6e9b92" +dependencies = [ + "semver 1.0.23", +] + +[[package]] +name = "rustversion" +version = "1.0.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "955d28af4278de8121b7ebeb796b6a45735dc01436d898801014aced2773a3d6" + +[[package]] +name = "scopeguard" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" + +[[package]] +name = "sdio-host" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f93c025f9cfe4c388c328ece47d11a54a823da3b5ad0370b22d95ad47137f85a" + +[[package]] +name = "semver" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1d7eb9ef2c18661902cc47e535f9bc51b78acd254da71d375c2f6720d9a40403" +dependencies = [ + "semver-parser", +] + +[[package]] +name = "semver" +version = "1.0.23" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "61697e0a1c7e512e84a621326239844a24d8207b4669b41bc18b32ea5cbf988b" + +[[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.210" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c8e3592472072e6e22e0a54d5904d9febf8508f65fb8552499a1abc7d1078c3a" +dependencies = [ + "serde_derive", +] + +[[package]] +name = "serde_derive" +version = "1.0.210" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "243902eda00fad750862fc144cea25caca5e20d615af0a81bee94ca738f1df1f" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.77", +] + +[[package]] +name = "sht31" +version = "0.3.1" +source = "git+https://github.com/dvdsk/SHT31-rs#a7b6bd94fb137e16bf326eff5fb591624369a2cf" +dependencies = [ + "crc", + "defmt", + "embedded-hal-async", + "postcard", +] + +[[package]] +name = "spin" +version = "0.9.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6980e8d7511241f8acf4aebddbb1ff938df5eebe98691418c4468d0b72a96a67" +dependencies = [ + "lock_api", +] + +[[package]] +name = "sps30-async" +version = "0.3.0" +dependencies = [ + "defmt", + "embedded-hal-async", + "embedded-io-async", + "futures", + "heapless 0.8.0", + "postcard", + "serde", +] + +[[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.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a8f112729512f8e442d81f95a8a7ddf2b7c6b8a1a6f509a95864142b30cab2d3" + +[[package]] +name = "static_assertions" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f" + +[[package]] +name = "static_cell" +version = "2.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d89b0684884a883431282db1e4343f34afc2ff6996fe1f4a1664519b66e14c1e" +dependencies = [ + "portable-atomic", +] + +[[package]] +name = "stm32-fmc" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c7f0639399e2307c2446c54d91d4f1596343a1e1d5cab605b9cce11d0ab3858c" +dependencies = [ + "embedded-hal 0.2.7", +] + +[[package]] +name = "stm32-metapac" +version = "15.0.0" +source = "git+https://github.com/embassy-rs/stm32-data-generated?tag=stm32-data-ad00827345b4b758b2453082809d6e3b634b5364#e442835159a7a311410cd4a2879da52c6f57af52" +dependencies = [ + "cortex-m", + "cortex-m-rt", +] + +[[package]] +name = "strsim" +version = "0.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f" + +[[package]] +name = "strum" +version = "0.26.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8fec0f0aef304996cf250b31b5a10dee7980c85da9d759361292b8bca5a18f06" +dependencies = [ + "strum_macros", +] + +[[package]] +name = "strum_macros" +version = "0.26.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4c6bee85a5a24955dc440386795aa378cd9cf82acd5f764469152d2270e581be" +dependencies = [ + "heck", + "proc-macro2", + "quote", + "rustversion", + "syn 2.0.77", +] + +[[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.77" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9f35bcdf61fd8e7be6caf75f429fdca8beb3ed76584befb503b1569faee373ed" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[package]] +name = "thiserror" +version = "1.0.64" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d50af8abc119fb8bb6dbabcfa89656f46f84aa0ac7688088608076ad2b459a84" +dependencies = [ + "thiserror-impl", +] + +[[package]] +name = "thiserror-impl" +version = "1.0.64" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "08904e7672f5eb876eaaf87e0ce17857500934f4981c4a0ab2b4aa98baac7fc3" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.77", +] + +[[package]] +name = "unicode-ident" +version = "1.0.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e91b56cd4cadaeb79bbf1a5645f6b4f8dc5bde8834ad5894a8db35fda9efa1fe" + +[[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", + "log", + "proc-macro2", + "quote", + "serde", + "syn 1.0.109", + "usbd-hid-descriptors", +] + +[[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 = "zerocopy" +version = "0.7.35" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1b9b4fd18abc82b8136838da5d50bae7bdea537c574d8dc1a34ed098d6c166f0" +dependencies = [ + "zerocopy-derive", +] + +[[package]] +name = "zerocopy-derive" +version = "0.7.35" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fa4f8080344d4671fb4e831a13ad1e68092748387dfc4f55e356242fae12ce3e" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.77", +] diff --git a/nodes/embassy/test-wiznet/Cargo.toml b/nodes/embassy/test-wiznet/Cargo.toml new file mode 100644 index 00000000..d46b5c24 --- /dev/null +++ b/nodes/embassy/test-wiznet/Cargo.toml @@ -0,0 +1,28 @@ +[package] +name = "test-wiznet" +version = "0.2.0" +rust-version.workspace = true +edition.workspace = true +license = "GPLv3" +authors = ["David Kleingeld & Eva van Houten"] + +[dependencies] +cortex-m.workspace = true +cortex-m-rt.workspace = true + +embassy-stm32.workspace = true +embassy-executor.workspace = true +embassy-net.workspace = true +embassy-net-wiznet.workspace = true +embassy-time.workspace = true + +defmt.workspace = true +defmt-rtt.workspace = true + +embedded-hal-bus.workspace = true +embedded-io-async.workspace = true + +panic-probe.workspace = true +static_cell = "2.0.0" +rand = { version = "0.8.5", default-features = false, features = ["small_rng"] } +heapless = { version = "0.8", default-features = false } diff --git a/nodes/embassy/test-wiznet/build.rs b/nodes/embassy/test-wiznet/build.rs new file mode 100644 index 00000000..8cd32d7e --- /dev/null +++ b/nodes/embassy/test-wiznet/build.rs @@ -0,0 +1,5 @@ +fn main() { + println!("cargo:rustc-link-arg-bins=--nmagic"); + println!("cargo:rustc-link-arg-bins=-Tlink.x"); + println!("cargo:rustc-link-arg-bins=-Tdefmt.x"); +} diff --git a/nodes/embassy/test-wiznet/rust-toolchain.toml b/nodes/embassy/test-wiznet/rust-toolchain.toml new file mode 100644 index 00000000..c17f644e --- /dev/null +++ b/nodes/embassy/test-wiznet/rust-toolchain.toml @@ -0,0 +1,6 @@ +[toolchain] +channel = "stable" +components = [ "rust-src", "rustfmt", "llvm-tools" ] +targets = [ + "thumbv7em-none-eabihf", +] diff --git a/nodes/embassy/test-wiznet/src/main.rs b/nodes/embassy/test-wiznet/src/main.rs new file mode 100644 index 00000000..0e46455b --- /dev/null +++ b/nodes/embassy/test-wiznet/src/main.rs @@ -0,0 +1,134 @@ +#![no_std] +#![no_main] + +use embassy_executor::Spawner; +use embassy_net::{Ipv4Address, Ipv4Cidr, StackResources}; +use embassy_net_wiznet::{chip::W5500, Device, Runner, State}; +use embassy_stm32::exti::ExtiInput; +use embassy_stm32::gpio::{Level, Output, Pull, Speed}; +use embassy_stm32::mode::Async; +use embassy_stm32::peripherals::IWDG; +use embassy_stm32::spi::{Config as SpiConfig, Spi}; +use embassy_stm32::time::Hertz; +use embassy_stm32::wdg::IndependentWatchdog; +use embassy_stm32::Config; +use embassy_time::{Delay, Timer}; +use embedded_hal_bus::spi::ExclusiveDevice; +use heapless::Vec; +use static_cell::StaticCell; + +use defmt::{trace, unwrap}; +use {defmt_rtt as _, panic_probe as _}; + +mod network; +mod rng; + +type EthernetSPI = ExclusiveDevice, Output<'static>, Delay>; +#[embassy_executor::task] +async fn ethernet_task( + runner: Runner< + 'static, + W5500, + EthernetSPI, + ExtiInput<'static>, + Output<'static>, + >, +) -> ! { + runner.run().await +} + +#[embassy_executor::task] +async fn net_task( + mut runner: embassy_net::Runner<'static, Device<'static>>, +) -> ! { + runner.run().await +} + +// 84 Mhz clock stm32f401 +fn config() -> Config { + use embassy_stm32::rcc::{ + AHBPrescaler, APBPrescaler, Hse, HseMode, Pll, PllMul, PllPDiv, + PllPreDiv, PllSource, Sysclk, + }; + + let mut config = Config::default(); + config.rcc.hse = Some(Hse { + freq: Hertz(25_000_000), + mode: HseMode::Oscillator, + }); + config.rcc.pll_src = PllSource::HSE; + config.rcc.pll = Some(Pll { + prediv: PllPreDiv::DIV25, + mul: PllMul::MUL336, + divp: Some(PllPDiv::DIV4), + divq: None, + divr: None, + }); + config.rcc.ahb_pre = AHBPrescaler::DIV1; + config.rcc.apb1_pre = APBPrescaler::DIV2; + config.rcc.apb2_pre = APBPrescaler::DIV1; + config.rcc.sys = Sysclk::PLL1_P; + config +} + +#[embassy_executor::main] +async fn main(spawner: Spawner) { + let p = embassy_stm32::init(config()); + let mut dog = IndependentWatchdog::new( + p.IWDG, 10_000_000, // microseconds + ); + dog.unleash(); + let seed = rng::generate_seed_blocking(p.ADC1).await; + defmt::info!("random seed: {}", seed); + + let mut spi_cfg = SpiConfig::default(); + spi_cfg.frequency = Hertz(5_000_000); // Up to 50m works + let (miso, mosi, clk) = (p.PA6, p.PA7, p.PA5); + let spi = + Spi::new(p.SPI1, clk, mosi, miso, p.DMA2_CH3, p.DMA2_CH0, spi_cfg); + let cs = Output::new(p.PA4, Level::High, Speed::VeryHigh); + let spi = unwrap!(ExclusiveDevice::new(spi, cs, Delay)); + + let w5500_int = ExtiInput::new(p.PB0, p.EXTI0, Pull::Up); + let w5500_reset = Output::new(p.PB1, Level::High, Speed::Medium); + + let mac_addr = [0x02, 234, 3, 4, 82, 231]; + static STATE: StaticCell> = StaticCell::new(); + let state = STATE.init(State::<3, 2>::new()); + let (device, runner) = unwrap!( + embassy_net_wiznet::new(mac_addr, state, spi, w5500_int, w5500_reset) + .await + ); + unwrap!(spawner.spawn(ethernet_task(runner))); + + // Init network stack + static RESOURCES: StaticCell> = StaticCell::new(); + let config = + embassy_net::Config::ipv4_static(embassy_net::StaticConfigV4 { + address: Ipv4Cidr::new(Ipv4Address::new(192, 168, 1, 7), 24), + gateway: Some(Ipv4Address::new(192, 168, 1, 1)), + dns_servers: Vec::new(), + }); + let (stack, runner) = embassy_net::new( + device, + config, + RESOURCES.init(StackResources::new()), + seed, + ); + + // Launch network task + unwrap!(spawner.spawn(net_task(runner))); + + let handle_network = network::handle(stack); + spawner.must_spawn(handle_network); + + keep_dog_happy(dog).await; +} + +async fn keep_dog_happy(mut dog: IndependentWatchdog<'_, IWDG>) { + loop { + Timer::after_secs(8).await; + trace!("petting dog"); + dog.pet(); + } +} diff --git a/nodes/embassy/test-wiznet/src/network.rs b/nodes/embassy/test-wiznet/src/network.rs new file mode 100644 index 00000000..419a18e9 --- /dev/null +++ b/nodes/embassy/test-wiznet/src/network.rs @@ -0,0 +1,60 @@ +use defmt::{debug, info, warn}; +use embassy_executor::task; +use embassy_net::tcp::TcpSocket; +use embassy_net::{Ipv4Address, Stack}; +use embassy_time::{Duration, Timer}; + +use embedded_io_async::Write; +use embedded_io_async::Read; + +#[task] +pub async fn handle( + stack: Stack<'static>, +) { + 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(5))); + socket.set_keep_alive(Some(Duration::from_secs(1))); + let host_addr = Ipv4Address::new(192, 168, 1, 43); + let host_port = 6969; + + let mut sequential_errors = 0; + + debug!("Configured socket and connecting"); + loop { + debug!("socket state: {:?}", socket.state()); + if let Err(e) = socket.connect((host_addr, host_port)).await { + if sequential_errors > 3 { + defmt::info!("failing to reconnect, resetting node"); + defmt::flush(); + Timer::after_secs(1).await; + cortex_m::peripheral::SCB::sys_reset(); + } + warn!("connect error: {}", e); + sequential_errors += 1; + Timer::after_secs(5).await; + continue; + } + + info!("(re-)connected"); + sequential_errors = 0; + // Prevent out-dated data from being send + + let mut buf = [0u8; 100]; + loop { + let Ok(_) = socket.read_exact(&mut buf).await else { + break + }; + let Ok(_) = socket.write_all(&buf).await else { + break + }; + } + + // Or the socket will hang for a while waiting to close this makes sure + // we can reconnect instantly + socket.abort(); + Timer::after_secs(60).await; // Experiment: does this help? + } +} diff --git a/nodes/embassy/test-wiznet/src/rng.rs b/nodes/embassy/test-wiznet/src/rng.rs new file mode 100644 index 00000000..f489557d --- /dev/null +++ b/nodes/embassy/test-wiznet/src/rng.rs @@ -0,0 +1,31 @@ +use embassy_stm32::peripherals::ADC1; +use embassy_time::Timer; +use rand::{RngCore, SeedableRng}; + +use embassy_stm32::adc::{Adc, Temperature, VrefInt}; +/// #Warning +/// Should only be called before async tasks are spawned. This takes a lot of +/// time to run and will disturb any async task running. +pub async fn generate_seed_blocking(adc: embassy_stm32::Peri<'_, ADC1>) -> u64 { + let mut adc = Adc::new(adc); + + let mut vrefint = adc.enable_vrefint(); + let mut temp = adc.enable_temperature(); + + // Startup delay can be combined to the maximum of either + Timer::after_micros(Temperature::start_time_us().max(VrefInt::start_time_us()) as u64).await; + + let mut seed = [0u8; 16]; + let mut bytes = seed.chunks_exact_mut(2); + while let Some([byte1, byte2]) = bytes.next() { + let sample = adc.blocking_read(&mut temp); + let most_noisy_byte = (sample & 0b0000_0000_1111_1111) as u8; + *byte1 = most_noisy_byte; + let sample = adc.blocking_read(&mut vrefint); + let most_noisy_byte = (sample & 0b0000_0000_1111_1111) as u8; + *byte2 = most_noisy_byte; + } + + let mut rng = rand::rngs::SmallRng::from_seed(seed); + rng.next_u64() +} diff --git a/nodes/embassy/usb-bridge-client/Cargo.toml b/nodes/embassy/usb-bridge-client/Cargo.toml new file mode 100644 index 00000000..1e3a1b71 --- /dev/null +++ b/nodes/embassy/usb-bridge-client/Cargo.toml @@ -0,0 +1,15 @@ +[package] +name = "usb-bridge-client" +version = "0.1.0" +rust-version.workspace = true +edition.workspace = true +license.workspace = true +authors.workspace = true + +[dependencies] +embassy-sync.workspace = true +embassy-usb.workspace = true +defmt.workspace = true +heapless.workspace = true + +protocol.workspace = true diff --git a/nodes/embassy/usb-bridge-client/src/lib.rs b/nodes/embassy/usb-bridge-client/src/lib.rs new file mode 100644 index 00000000..5624dfda --- /dev/null +++ b/nodes/embassy/usb-bridge-client/src/lib.rs @@ -0,0 +1,348 @@ +#![no_std] + +use embassy_sync::blocking_mutex::raw::NoopRawMutex; +use embassy_sync::channel::Channel; +use embassy_sync::mutex::Mutex; +use embassy_sync::signal::Signal; +use embassy_usb::control::{InResponse, OutResponse, Recipient, RequestType}; +use embassy_usb::types::InterfaceNumber; +use embassy_usb::UsbDevice; +use protocol::{affector, usb}; + +const MAX_RECV_ITEM_SIZE: usize = 1 + affector::Affector::ENCODED_SIZE; + +pub(crate) type RecvItem = heapless::Vec; +type SendQueue = + Mutex>; + +pub struct UsbControlHandler<'a> { + pub if_num: Option, + affector_list: &'a [u8], + send_queue: &'a SendQueue, + ready_to_send: &'a Signal, + receive_queue: &'a Channel, +} + +impl embassy_usb::Handler for UsbControlHandler<'_> { + fn control_out( + &mut self, + req: embassy_usb::control::Request, + data: &[u8], + ) -> Option { + // Log the request before filtering to help with debugging. + defmt::info!("Got control_out, request={}, buf={:a}", req, data); + + // Only handle Vendor request types to an Interface. + if req.request_type != RequestType::Vendor { + return None; + } + + if req.recipient != Recipient::Interface { + return None; + } + + // Ignore requests to other interfaces. + if req.index != defmt::unwrap!(self.if_num).0 as u16 { + return None; + } + + // Accept affector orders only. + if req.request == usb::AFFECTOR_ORDER + && data.len() <= MAX_RECV_ITEM_SIZE + { + let data = + heapless::Vec::from_slice(data).expect("checked length above"); + if self.receive_queue.try_send(data).is_err() { + Some(OutResponse::Rejected) + } else { + Some(OutResponse::Accepted) + } + } else { + Some(OutResponse::Rejected) + } + } + + fn control_in<'a>( + &'a mut self, + req: embassy_usb::control::Request, + buf: &'a mut [u8], + ) -> Option> { + // Only handle Vendor request types to an Interface. + if req.request_type != RequestType::Vendor { + return None; + } + + if req.recipient != Recipient::Interface { + return None; + } + + // Ignore requests to other interfaces. + if req.index != defmt::unwrap!(self.if_num).0 as u16 { + return None; + } + + if buf.len() != usb::SEND_BUFFER_SIZE { + defmt::warn!( + "Send buffer is incorrect size ({}), should be: {}. \ + recompile either usb-bridge or this", + buf.len(), + usb::SEND_BUFFER_SIZE + ); + return Some(InResponse::Rejected); + } + + if req.request == usb::GET_AFFECTOR_LIST { + self.send_affector_list(buf); + Some(InResponse::Accepted(buf)) + } else if req.request == usb::GET_QUEUED_MESSAGES { + self.send_queued(buf)?; + Some(InResponse::Accepted(buf)) + } else { + Some(InResponse::Rejected) + } + } +} + +impl UsbControlHandler<'_> { + fn send_affector_list(&mut self, buf: &mut [u8]) { + buf[0] = protocol::Msg::<5>::AFFECTOR_LIST; + buf[1..1 + self.affector_list.len()] + .copy_from_slice(self.affector_list); + buf[1 + self.affector_list.len()..].fill(0); + } + + fn send_queued(&mut self, buf: &mut [u8]) -> Option<()> { + let Ok(mut send_queue) = self.send_queue.try_lock() else { + return None; + }; + + for byte in buf.iter_mut() { + if let Some(to_send) = send_queue.pop_front() { + *byte = to_send; + } else { + *byte = 0; // end of encoded data + } + } + self.ready_to_send.signal(()); + Some(()) + } +} + +pub struct UsbHandle<'a> { + send_queue: &'a SendQueue, + ready_to_send: &'a Signal, + receive_queue: + &'a Channel, 2>, +} + +impl<'a> UsbHandle<'a> { + pub fn split(&self) -> (UsbSender<'a>, UsbReceiver<'a>) { + ( + UsbSender { + send_queue: self.send_queue, + ready_to_send: self.ready_to_send, + }, + UsbReceiver { + receive_queue: self.receive_queue, + }, + ) + } +} + +pub struct UsbSender<'a> { + send_queue: &'a SendQueue, + ready_to_send: &'a Signal, +} + +pub struct NoSpaceInQueue; + +impl UsbSender<'_> { + pub async fn send( + &self, + to_send: &[u8], + is_low_prio: bool, + ) -> Result<(), NoSpaceInQueue> { + const RESERVED_FOR_HIGH_PRIO: usize = 32; + + let mut queue = self.send_queue.lock().await; + let free = queue.capacity() - queue.len(); + if free < 1 + to_send.len() { + return Err(NoSpaceInQueue); + } + + let left_over = free - 1 - to_send.len(); + if left_over < RESERVED_FOR_HIGH_PRIO && is_low_prio { + return Err(NoSpaceInQueue); + } + + defmt::unwrap!( + queue.push_back(defmt::unwrap!( + to_send.len().try_into(), + "send only supports buffers up to and including u8::MAX long" + ),), + "just checked that queue has capacity" + ); + + for byte in to_send { + defmt::unwrap!(queue.push_back(*byte)) + } + Ok(()) + } + + pub async fn wait_till_queue_free(&self) { + let wait_for_ready = self.ready_to_send.wait(); + if !self.send_queue.lock().await.is_full() { + return; + } + + wait_for_ready.await + } +} + +#[allow(dead_code)] +pub struct UsbReceiver<'a> { + receive_queue: + &'a Channel, 2>, +} +#[allow(dead_code)] +impl UsbReceiver<'_> { + pub async fn recv(&self) -> RecvItem { + self.receive_queue.receive().await + } +} + +/// Given a node name and a *random* serial returns a usb config +#[macro_export] +macro_rules! config { + ($node_name:literal, $serial:literal) => { + { + let mut config = embassy_usb::Config::new(0xc0de, 0xcafe); + config.manufacturer = Some("Vid"); + config.product = Some(concat!("sensor node ", $node_name)); + // Random, host driver finds device using this + config.serial_number = Some($serial); + // Required for windows compatibility. + // https://developer.nordicsemi.com/nRF_Connect_SDK/doc/1.9.1/kconfig/CONFIG_CDC_ACM_IAD.html#help + config.device_class = 0xEF; + config.device_sub_class = 0x02; + config.device_protocol = 0x01; + config.composite_with_iads = true; + config + } + }; +} + +pub struct StackA { + send_queue: SendQueue, + ready_to_send: Signal, + receive_queue: + Channel, 2>, +} + +impl StackA { + pub fn new() -> Self { + Self { + send_queue: Mutex::new(heapless::Deque::new()), + receive_queue: Channel::new(), + ready_to_send: Signal::new(), + } + } +} + +pub struct StackB<'a> { + config_descriptor: [u8; 256], + bos_descriptor: [u8; 256], + msos_descriptor: [u8; 256], + control_buf: [u8; usb::SEND_BUFFER_SIZE], + handler: UsbControlHandler<'a>, +} + +impl<'a> StackB<'a> { + pub fn new(stack_a: &'a StackA, affector_list: &'a [u8]) -> Self { + Self { + config_descriptor: [0u8; 256], + bos_descriptor: [0u8; 256], + msos_descriptor: [0u8; 256], + control_buf: [0u8; usb::SEND_BUFFER_SIZE], + + handler: UsbControlHandler { + if_num: None, + send_queue: &stack_a.send_queue, + receive_queue: &stack_a.receive_queue, + ready_to_send: &stack_a.ready_to_send, + affector_list, + }, + } + } +} + +pub struct Usb<'a, D: embassy_usb::driver::Driver<'a>>(UsbDevice<'a, D>); + +impl<'a, D: embassy_usb::driver::Driver<'a>> Usb<'a, D> { + pub async fn run(&mut self) { + self.0.run().await + } +} + +pub fn new<'a, D: embassy_usb::driver::Driver<'a>>( + stack_a: &'a StackA, + stack_b: &'a mut StackB<'a>, + config: embassy_usb::Config<'static>, + driver: D, +) -> (Usb<'a, D>, UsbHandle<'a>) { + use embassy_usb::msos::{self, windows_version}; + + let StackB { + config_descriptor, + bos_descriptor, + msos_descriptor, + control_buf, + handler, + } = stack_b; + + let mut builder = embassy_usb::Builder::new( + driver, + config, + config_descriptor, + bos_descriptor, + msos_descriptor, + control_buf, + ); + + // Add the Microsoft OS Descriptor (MSOS/MOD) descriptor. + // We tell Windows that this entire device is compatible with the "WINUSB" feature. + // This causes it to use the built-in WInUSB driver automatically, which in turn + // can be used by libusb/rusb software without needing a custom driver or INF file. + // In principle you might want to call msos_feature() just on a specific function, + // if your device also has other functions that still use standard class drivers. + builder.msos_descriptor(windows_version::WIN8_1, 0); + builder + .msos_feature(msos::CompatibleIdFeatureDescriptor::new("WINUSB", "")); + + // Randomly generated UUID because Windows requires you provide one to use WinUSB. + // In principle WinUSB-using software could find this device (or a specific interface + // on it) by its GUID instead of using the VID/PID, but in practice that seems unhelpful. + const DEVICE_INTERFACE_GUIDS: &[&str] = + &["{DAC2087C-63FA-458D-A55D-827C0762DEC7}"]; + + builder.msos_feature(msos::RegistryPropertyFeatureDescriptor::new( + "DeviceInterfaceGUIDs", + msos::PropertyData::RegMultiSz(DEVICE_INTERFACE_GUIDS), + )); + + let mut function = builder.function(0xFF, 0, 0); + let mut interface = function.interface(); + let _alternate = interface.alt_setting(0xFF, 0, 0, None); + handler.if_num = Some(interface.interface_number()); + drop(function); + builder.handler(handler); + + ( + Usb(builder.build()), + UsbHandle { + send_queue: &stack_a.send_queue, + receive_queue: &stack_a.receive_queue, + ready_to_send: &stack_a.ready_to_send, + }, + ) +} diff --git a/nodes/esp32/airbox/.cargo/config.toml b/nodes/esp32/airbox/.cargo/config.toml new file mode 100644 index 00000000..0c352f5c --- /dev/null +++ b/nodes/esp32/airbox/.cargo/config.toml @@ -0,0 +1,19 @@ +[target.riscv32imac-unknown-none-elf] +# runner = "espflash flash --monitor --chip esp32c3 --log-format defmt" +runner = "espflash flash --monitor --chip esp32c6 --log-format defmt" + +[env] +DEFMT_LOG="info" +ESP_WIFI_COUNTRY_CODE = "NL" + +[build] +rustflags = [ + # Required to obtain backtraces (e.g. when using the "esp-backtrace" crate.) + # NOTE: May negatively impact performance of produced code + "-C", "force-frame-pointers", +] + +target = "riscv32imac-unknown-none-elf" + +[unstable] +build-std = ["alloc", "core"] diff --git a/nodes/esp32/airbox/.gitignore b/nodes/esp32/airbox/.gitignore new file mode 100644 index 00000000..6e771f81 --- /dev/null +++ b/nodes/esp32/airbox/.gitignore @@ -0,0 +1,17 @@ +# Generated by Cargo +# will have compiled files and executables +debug/ +target/ + +# These are backup files generated by rustfmt +**/*.rs.bk + +# MSVC Windows builds of rustc generate these, which store debugging information +*.pdb + +# RustRover +# JetBrains specific template is maintained in a separate JetBrains.gitignore that can +# be found at https://github.com/github/gitignore/blob/main/Global/JetBrains.gitignore +# and can be added to the global gitignore or merged into this file. For a more nuclear +# option (not recommended) you can uncomment the following to ignore the entire idea folder. +#.idea/ diff --git a/nodes/esp32/airbox/Cargo.lock b/nodes/esp32/airbox/Cargo.lock new file mode 100644 index 00000000..e57bbad6 --- /dev/null +++ b/nodes/esp32/airbox/Cargo.lock @@ -0,0 +1,1632 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 4 + +[[package]] +name = "airbox" +version = "0.1.0" +dependencies = [ + "bme280-rs", + "critical-section", + "defmt", + "embassy-executor", + "embassy-futures", + "embassy-net", + "embassy-sync", + "embassy-time", + "embedded-io", + "embedded-io-async", + "esp-alloc", + "esp-backtrace", + "esp-hal", + "esp-hal-embassy", + "esp-println", + "esp-wifi", + "heapless 0.8.0", + "protocol", + "smoltcp", + "static_cell", + "toml-cfg", +] + +[[package]] +name = "anyhow" +version = "1.0.97" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dcfed56ad506cb2c684a14971b8861fdc3baaaae314b9e5f9bb532cbe3ba7a4f" + +[[package]] +name = "atomic-polyfill" +version = "1.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8cf2bce30dfe09ef0bfaef228b9d414faaf7e563035494d7fe092dba54b300f4" +dependencies = [ + "critical-section", +] + +[[package]] +name = "autocfg" +version = "1.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ace50bade8e6234aa140d9a2f552bbee1db4d353f69b8217bc503490fc1a9f26" + +[[package]] +name = "basic-toml" +version = "0.1.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ba62675e8242a4c4e806d12f11d136e626e6c8361d6b829310732241652a178a" +dependencies = [ + "serde", +] + +[[package]] +name = "bitfield" +version = "0.18.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4c7e6caee68becd795bfd65f1a026e4d00d8f0c2bc9be5eb568e1015f9ce3c34" +dependencies = [ + "bitfield-macros", +] + +[[package]] +name = "bitfield-macros" +version = "0.18.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "331afbb18ce7b644c0b428726d369c5dd37ca0b815d72a459fcc2896c3c8ad32" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.100", +] + +[[package]] +name = "bitflags" +version = "1.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" + +[[package]] +name = "bitflags" +version = "2.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c8214115b7bf84099f1309324e63141d4c5d7cc26862f97a0a857dbefe165bd" + +[[package]] +name = "bme280-rs" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "97b9c5f8cda3fc2c518da006efb17147d2814349adf209911141168838ea5b54" +dependencies = [ + "embedded-hal 1.0.0", + "embedded-hal-async", + "log", +] + +[[package]] +name = "bt-hci" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f377753756ec12e76b52d2dd657437be0448cc9736402ffadd0b8b8b9602c8a1" +dependencies = [ + "defmt", + "embassy-sync", + "embedded-io", + "embedded-io-async", + "futures-intrusive", + "heapless 0.8.0", +] + +[[package]] +name = "bytemuck" +version = "1.22.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b6b1fc10dbac614ebc03540c9dbd60e83887fda27794998c6528f1782047d540" + +[[package]] +name = "byteorder" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" + +[[package]] +name = "cfg-if" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" + +[[package]] +name = "chrono" +version = "0.4.40" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1a7964611d71df112cb1730f2ee67324fcf4d0fc6606acbbe9bfe06df124637c" +dependencies = [ + "num-traits", +] + +[[package]] +name = "cobs" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "67ba02a97a2bd10f4b59b25c7973101c79642302776489e030cd13cdab09ed15" + +[[package]] +name = "critical-section" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "790eea4361631c5e7d22598ecd5723ff611904e3344ce8720784c93e3d83d40b" + +[[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.100", +] + +[[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.100", +] + +[[package]] +name = "defmt" +version = "0.3.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "86f6162c53f659f65d00619fe31f14556a6e9f8752ccc4a41bd177ffcf3d6130" +dependencies = [ + "bitflags 1.3.2", + "defmt-macros", +] + +[[package]] +name = "defmt-macros" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9d135dd939bad62d7490b0002602d35b358dce5fd9233a709d3c1ef467d4bde6" +dependencies = [ + "defmt-parser", + "proc-macro-error2", + "proc-macro2", + "quote", + "syn 2.0.100", +] + +[[package]] +name = "defmt-parser" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3983b127f13995e68c1e29071e5d115cd96f215ccb5e6812e3728cd6f92653b3" +dependencies = [ + "thiserror", +] + +[[package]] +name = "delegate" +version = "0.13.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b9b6483c2bbed26f97861cf57651d4f2b731964a28cd2257f934a4b452480d21" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.100", +] + +[[package]] +name = "document-features" +version = "0.2.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "95249b50c6c185bee49034bcb378a49dc2b5dff0be90ff6616d31d64febab05d" +dependencies = [ + "litrs", +] + +[[package]] +name = "embassy-embedded-hal" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "41fea5ef5bed4d3468dfd44f5c9fa4cda8f54c86d4fb4ae683eacf9d39e2ea12" +dependencies = [ + "embassy-futures", + "embassy-sync", + "embassy-time", + "embedded-hal 0.2.7", + "embedded-hal 1.0.0", + "embedded-hal-async", + "embedded-storage", + "embedded-storage-async", + "nb 1.1.0", +] + +[[package]] +name = "embassy-executor" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "90327bcc66333a507f89ecc4e2d911b265c45f5c9bc241f98eee076752d35ac6" +dependencies = [ + "critical-section", + "defmt", + "document-features", + "embassy-executor-macros", +] + +[[package]] +name = "embassy-executor-macros" +version = "0.6.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3577b1e9446f61381179a330fc5324b01d511624c55f25e3c66c9e3c626dbecf" +dependencies = [ + "darling", + "proc-macro2", + "quote", + "syn 2.0.100", +] + +[[package]] +name = "embassy-futures" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1f878075b9794c1e4ac788c95b728f26aa6366d32eeb10c7051389f898f7d067" +dependencies = [ + "defmt", +] + +[[package]] +name = "embassy-net" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ed041cc19a603d657124fddefdcbe5ef8bd60e77d972793ebb57de93394f5949" +dependencies = [ + "defmt", + "document-features", + "embassy-net-driver", + "embassy-sync", + "embassy-time", + "embedded-io-async", + "embedded-nal-async", + "heapless 0.8.0", + "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", +] + +[[package]] +name = "embassy-sync" +version = "0.6.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8d2c8cdff05a7a51ba0087489ea44b0b1d97a296ca6b1d6d1a33ea7423d34049" +dependencies = [ + "cfg-if", + "critical-section", + "defmt", + "embedded-io-async", + "futures-sink", + "futures-util", + "heapless 0.8.0", +] + +[[package]] +name = "embassy-time" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f820157f198ada183ad62e0a66f554c610cdcd1a9f27d4b316358103ced7a1f8" +dependencies = [ + "cfg-if", + "critical-section", + "document-features", + "embassy-time-driver", + "embassy-time-queue-utils", + "embedded-hal 0.2.7", + "embedded-hal 1.0.0", + "embedded-hal-async", + "futures-util", +] + +[[package]] +name = "embassy-time-driver" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8d45f5d833b6d98bd2aab0c2de70b18bfaa10faf661a1578fd8e5dfb15eb7eba" +dependencies = [ + "document-features", +] + +[[package]] +name = "embassy-time-queue-utils" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dc55c748d16908a65b166d09ce976575fb8852cf60ccd06174092b41064d8f83" +dependencies = [ + "embassy-executor", + "heapless 0.8.0", +] + +[[package]] +name = "embedded-can" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e9d2e857f87ac832df68fa498d18ddc679175cf3d2e4aa893988e5601baf9438" +dependencies = [ + "nb 1.1.0", +] + +[[package]] +name = "embedded-hal" +version = "0.2.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "35949884794ad573cf46071e41c9b60efb0cb311e3ca01f7af807af1debc66ff" +dependencies = [ + "nb 0.1.3", + "void", +] + +[[package]] +name = "embedded-hal" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "361a90feb7004eca4019fb28352a9465666b24f840f5c3cddf0ff13920590b89" +dependencies = [ + "defmt", +] + +[[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-io" +version = "0.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "edd0f118536f44f5ccd48bcb8b111bdc3de888b58c74639dfb034a357d0f206d" +dependencies = [ + "defmt", +] + +[[package]] +name = "embedded-io-async" +version = "0.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3ff09972d4073aa8c299395be75161d582e7629cd663171d62af73c8d50dba3f" +dependencies = [ + "defmt", + "embedded-io", +] + +[[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.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "76959917cd2b86f40a98c28dd5624eddd1fa69d746241c8257eac428d83cb211" +dependencies = [ + "embedded-io-async", + "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 = "enum-as-inner" +version = "0.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a1e6a265c649f3f5979b601d26f1d05ada116434c87741c9493cb56218f76cbc" +dependencies = [ + "heck 0.5.0", + "proc-macro2", + "quote", + "syn 2.0.100", +] + +[[package]] +name = "enumset" +version = "1.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d07a4b049558765cef5f0c1a273c3fc57084d768b44d2f98127aef4cceb17293" +dependencies = [ + "enumset_derive", +] + +[[package]] +name = "enumset_derive" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "59c3b24c345d8c314966bdc1832f6c2635bfcce8e7cf363bd115987bba2ee242" +dependencies = [ + "darling", + "proc-macro2", + "quote", + "syn 2.0.100", +] + +[[package]] +name = "equivalent" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "877a4ace8713b0bcf2a4e7eec82529c029f1d0619886d18145fea96c3ffe5c0f" + +[[package]] +name = "esp-alloc" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a78132d362cbf62ce22a1466eb9e98424f6b2d1e476e7a3cb46ca9063c5833f7" +dependencies = [ + "cfg-if", + "critical-section", + "document-features", + "enumset", + "linked_list_allocator", +] + +[[package]] +name = "esp-backtrace" +version = "0.15.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e4cd70abe47945c9116972781b5c05277ad855a5f5569fe2afd3e2e61a103cc0" +dependencies = [ + "defmt", + "esp-build", + "esp-println", +] + +[[package]] +name = "esp-build" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8aa1c8f9954c9506699cf1ca10a2adcc226ff10b6ae3cb9e875cf2c6a0b9a372" +dependencies = [ + "quote", + "syn 2.0.100", + "termcolor", +] + +[[package]] +name = "esp-config" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "158dba334d3a2acd8d93873c0ae723ca1037cc78eefe5d6b4c5919b0ca28e38e" +dependencies = [ + "document-features", +] + +[[package]] +name = "esp-hal" +version = "1.0.0-beta.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e9efaa9c1324ca20a22086aba2ce47a9bdc5bd65969af8b0cd5e879603b57bef" +dependencies = [ + "basic-toml", + "bitfield", + "bitflags 2.9.0", + "bytemuck", + "cfg-if", + "chrono", + "critical-section", + "defmt", + "delegate", + "document-features", + "embassy-embedded-hal", + "embassy-futures", + "embassy-sync", + "embedded-can", + "embedded-hal 1.0.0", + "embedded-hal-async", + "embedded-io", + "embedded-io-async", + "enumset", + "esp-build", + "esp-config", + "esp-hal-procmacros", + "esp-metadata", + "esp-riscv-rt", + "esp32", + "esp32c2", + "esp32c3", + "esp32c6", + "esp32h2", + "esp32s2", + "esp32s3", + "fugit", + "instability", + "nb 1.1.0", + "paste", + "portable-atomic", + "rand_core", + "riscv", + "serde", + "strum 0.27.1", + "ufmt-write", + "void", + "xtensa-lx", + "xtensa-lx-rt", +] + +[[package]] +name = "esp-hal-embassy" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b27f41110117a9bf2be385b42535c686b301c8ce3b5ea0a07567e200a63a2239" +dependencies = [ + "critical-section", + "document-features", + "embassy-executor", + "embassy-sync", + "embassy-time", + "embassy-time-driver", + "embassy-time-queue-utils", + "esp-build", + "esp-config", + "esp-hal", + "esp-hal-procmacros", + "esp-metadata", + "portable-atomic", + "static_cell", +] + +[[package]] +name = "esp-hal-procmacros" +version = "0.17.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1bd340a20a7d546570af58fd9e2aae17466a42572680d8e70d35fc7c475c4ed8" +dependencies = [ + "darling", + "document-features", + "litrs", + "object", + "proc-macro-crate", + "proc-macro-error2", + "proc-macro2", + "quote", + "syn 2.0.100", +] + +[[package]] +name = "esp-metadata" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "30b4bffc22b7b1222c9467f0cb90eb49dcb63de810ecb3300e4b3bbc4ac2423e" +dependencies = [ + "anyhow", + "basic-toml", + "serde", + "strum 0.26.3", +] + +[[package]] +name = "esp-println" +version = "0.13.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "960703930f9f3c899ddedd122ea27a09d6a612c22323157e524af5b18876448e" +dependencies = [ + "critical-section", + "defmt", + "esp-build", + "log", + "portable-atomic", +] + +[[package]] +name = "esp-riscv-rt" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ec69987b3d7c48b65f8fb829220832a101478d766c518ae836720d040608d5dd" +dependencies = [ + "document-features", + "riscv", + "riscv-rt-macros", +] + +[[package]] +name = "esp-wifi" +version = "0.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cd7d7ea0e2c374343a375758861e13cf618db619436bcb386dfe5529ef31e9d5" +dependencies = [ + "bt-hci", + "cfg-if", + "critical-section", + "defmt", + "document-features", + "embassy-net-driver", + "embassy-sync", + "embedded-io", + "embedded-io-async", + "enumset", + "esp-alloc", + "esp-build", + "esp-config", + "esp-hal", + "esp-metadata", + "esp-wifi-sys", + "heapless 0.8.0", + "libm", + "num-derive", + "num-traits", + "portable-atomic", + "portable_atomic_enum", + "rand_core", + "smoltcp", +] + +[[package]] +name = "esp-wifi-sys" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c6b5438361891c431970194a733415006fb3d00b6eb70b3dcb66fd58f04d9b39" +dependencies = [ + "anyhow", + "defmt", +] + +[[package]] +name = "esp32" +version = "0.36.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3d9b774d7a2c96550a5c25016c2abd33370ebac60e534484b7bca344ecb8a3d6" +dependencies = [ + "critical-section", + "defmt", + "vcell", +] + +[[package]] +name = "esp32c2" +version = "0.25.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6f7037cfa7c93574b0891062f980a75ae97e9d6c93dcaff3e060b37cf1281c59" +dependencies = [ + "critical-section", + "defmt", + "vcell", +] + +[[package]] +name = "esp32c3" +version = "0.28.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "df1bbcfa3ab2979171263db80804dabc38bdd45450c7eb775ee3f81d552cf0ba" +dependencies = [ + "critical-section", + "defmt", + "vcell", +] + +[[package]] +name = "esp32c6" +version = "0.19.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9ff2a4e1d1b0cb2517af20766004b8e8fb4612043f0b0569703cc90d1880ede4" +dependencies = [ + "critical-section", + "defmt", + "vcell", +] + +[[package]] +name = "esp32h2" +version = "0.15.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eee7512ae8da61338545804a76c5bc9816a9122abbf2f23d1195e3d45fab79af" +dependencies = [ + "critical-section", + "defmt", + "vcell", +] + +[[package]] +name = "esp32s2" +version = "0.27.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a22733ee6f4bb08e3113df6651b2c350f37c44314017476e354ec951a55465e9" +dependencies = [ + "critical-section", + "defmt", + "vcell", +] + +[[package]] +name = "esp32s3" +version = "0.31.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4c6d20f119410092abfbc65e46f9362015a7110023528f0dbe855cab80c38ca8" +dependencies = [ + "critical-section", + "defmt", + "vcell", +] + +[[package]] +name = "fnv" +version = "1.0.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" + +[[package]] +name = "fugit" +version = "0.3.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "17186ad64927d5ac8f02c1e77ccefa08ccd9eaa314d5a4772278aa204a22f7e7" +dependencies = [ + "defmt", + "gcd", +] + +[[package]] +name = "futures-core" +version = "0.3.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "05f29059c0c2090612e8d742178b0580d2dc940c837851ad723096f87af6663e" + +[[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-sink" +version = "0.3.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e575fab7d1e0dcb8d0c7bcf9a63ee213816ab51902e6d244a95819acacf1d4f7" + +[[package]] +name = "futures-task" +version = "0.3.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f90f7dce0722e95104fcb095585910c0977252f286e354b5e3bd38902cd99988" + +[[package]] +name = "futures-util" +version = "0.3.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9fa08315bb612088cc391249efdc3bc77536f16c91f6cf495e6fbe85b20a4a81" +dependencies = [ + "futures-core", + "futures-task", + "pin-project-lite", + "pin-utils", +] + +[[package]] +name = "gcd" +version = "2.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1d758ba1b47b00caf47f24925c0074ecb20d6dfcffe7f6d53395c0465674841a" + +[[package]] +name = "hash32" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b0c35f58762feb77d74ebe43bdbc3210f09be9fe6742234d573bacc26ed92b67" +dependencies = [ + "byteorder", +] + +[[package]] +name = "hash32" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "47d60b12902ba28e2730cd37e95b8c9223af2808df9e902d4df49588d1470606" +dependencies = [ + "byteorder", +] + +[[package]] +name = "hashbrown" +version = "0.15.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bf151400ff0baff5465007dd2f3e717f3fe502074ca563069ce3a6629d07b289" + +[[package]] +name = "heapless" +version = "0.7.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cdc6457c0eb62c71aac4bc17216026d8410337c4126773b9c5daba343f17964f" +dependencies = [ + "atomic-polyfill", + "hash32 0.2.1", + "rustc_version", + "serde", + "spin", + "stable_deref_trait", +] + +[[package]] +name = "heapless" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0bfb9eb618601c89945a70e254898da93b13be0388091d42117462b265bb3fad" +dependencies = [ + "defmt", + "hash32 0.3.1", + "portable-atomic", + "serde", + "stable_deref_trait", +] + +[[package]] +name = "heck" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "95505c38b4572b2d910cecb0281560f54b440a19336cbbcb27bf6ce6adc6f5a8" + +[[package]] +name = "heck" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea" + +[[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.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3954d50fe15b02142bf25d3b8bdadb634ec3948f103d04ffe3031bc8fe9d7058" +dependencies = [ + "equivalent", + "hashbrown", +] + +[[package]] +name = "indoc" +version = "2.0.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f4c7245a08504955605670dbf141fceab975f15ca21570696aebe9d2e71576bd" + +[[package]] +name = "instability" +version = "0.3.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0bf9fed6d91cfb734e7476a06bde8300a1b94e217e1b523b6f0cd1a01998c71d" +dependencies = [ + "darling", + "indoc", + "proc-macro2", + "quote", + "syn 2.0.100", +] + +[[package]] +name = "libm" +version = "0.2.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8355be11b20d696c8f18f6cc018c4e372165b1fa8126cef092399c9951984ffa" + +[[package]] +name = "linked_list_allocator" +version = "0.10.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9afa463f5405ee81cdb9cc2baf37e08ec7e4c8209442b5d72c04cfb2cd6e6286" + +[[package]] +name = "litrs" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b4ce301924b7887e9d637144fdade93f9dfff9b60981d4ac161db09720d39aa5" +dependencies = [ + "proc-macro2", +] + +[[package]] +name = "lock_api" +version = "0.4.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "07af8b9cdd281b7915f413fa73f29ebd5d55d0d3f0155584dade1ff18cea1b17" +dependencies = [ + "autocfg", + "scopeguard", +] + +[[package]] +name = "log" +version = "0.4.27" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "13dc2df351e3202783a1fe0d44375f7295ffb4049267b0f3018346dc122a1d94" + +[[package]] +name = "managed" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0ca88d725a0a943b096803bd34e73a4437208b6077654cc4ecb2947a5f91618d" + +[[package]] +name = "memchr" +version = "2.7.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "78ca9ab1a0babb1e7d5695e3530886289c18cf2f87ec19a575a0abdce112e3a3" + +[[package]] +name = "minijinja" +version = "2.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6e36f1329330bb1614c94b78632b9ce45dd7d761f3304a1bed07b2990a7c5097" +dependencies = [ + "serde", +] + +[[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 = "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.100", +] + +[[package]] +name = "num-traits" +version = "0.2.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841" +dependencies = [ + "autocfg", +] + +[[package]] +name = "object" +version = "0.36.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "62948e14d923ea95ea2c7c86c71013138b66525b86bdc08d2dcc262bdb497b87" +dependencies = [ + "memchr", +] + +[[package]] +name = "paste" +version = "1.0.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "57c0d7b74b563b49d38dae00a0c37d4d6de9b432382b2892f0574ddcae73fd0a" + +[[package]] +name = "pin-project-lite" +version = "0.2.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3b3cff922bd51709b605d9ead9aa71031d81447142d828eb4a6eba76fe619f9b" + +[[package]] +name = "pin-utils" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" + +[[package]] +name = "portable-atomic" +version = "1.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "350e9b48cbc6b0e028b0473b114454c6316e57336ee184ceab6e53f72c178b3e" + +[[package]] +name = "portable_atomic_enum" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "30d48f60c43e0120bb2bb48589a16d4bed2f4b911be41e299f2d0fc0e0e20885" +dependencies = [ + "portable-atomic", + "portable_atomic_enum_macros", +] + +[[package]] +name = "portable_atomic_enum_macros" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a33fa6ec7f2047f572d49317cca19c87195de99c6e5b6ee492da701cfe02b053" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.100", +] + +[[package]] +name = "postcard" +version = "1.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "170a2601f67cc9dba8edd8c4870b15f71a6a2dc196daec8c83f72b59dff628a8" +dependencies = [ + "cobs", + "defmt", + "heapless 0.7.17", + "postcard-derive", + "serde", +] + +[[package]] +name = "postcard-derive" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0239fa9c1d225d4b7eb69925c25c5e082307a141e470573fbbe3a817ce6a7a37" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "proc-macro-crate" +version = "3.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "edce586971a4dfaa28950c6f18ed55e0406c1ab88bbce2c6f6293a7aaba73d35" +dependencies = [ + "toml_edit", +] + +[[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.100", +] + +[[package]] +name = "proc-macro2" +version = "1.0.94" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a31971752e70b8b2686d7e46ec17fb38dad4051d94024c88df49b667caea9c84" +dependencies = [ + "unicode-ident", +] + +[[package]] +name = "protocol" +version = "0.1.0" +dependencies = [ + "defmt", + "heapless 0.8.0", + "postcard", + "serde", + "strum 0.27.1", +] + +[[package]] +name = "quote" +version = "1.0.40" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1885c039570dc00dcb4ff087a89e185fd56bae234ddc7f056a945bf36467248d" +dependencies = [ + "proc-macro2", +] + +[[package]] +name = "r0" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bd7a31eed1591dcbc95d92ad7161908e72f4677f8fabf2a32ca49b4237cbf211" + +[[package]] +name = "rand_core" +version = "0.6.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" + +[[package]] +name = "riscv" +version = "0.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5ea8ff73d3720bdd0a97925f0bf79ad2744b6da8ff36be3840c48ac81191d7a7" +dependencies = [ + "critical-section", + "embedded-hal 1.0.0", + "paste", + "riscv-macros", + "riscv-pac", +] + +[[package]] +name = "riscv-macros" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f265be5d634272320a7de94cea15c22a3bfdd4eb42eb43edc528415f066a1f25" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.100", +] + +[[package]] +name = "riscv-pac" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8188909339ccc0c68cfb5a04648313f09621e8b87dc03095454f1a11f6c5d436" + +[[package]] +name = "riscv-rt-macros" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fc71814687c45ba4cd1e47a54e03a2dbc62ca3667098fbae9cc6b423956758fa" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.100", +] + +[[package]] +name = "rustc_version" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cfcb3a22ef46e85b45de6ee7e79d063319ebb6594faafcf1c225ea92ab6e9b92" +dependencies = [ + "semver", +] + +[[package]] +name = "rustversion" +version = "1.0.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eded382c5f5f786b989652c49544c4877d9f015cc22e145a5ea8ea66c2921cd2" + +[[package]] +name = "scopeguard" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" + +[[package]] +name = "semver" +version = "1.0.26" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "56e6fa9c48d24d85fb3de5ad847117517440f6beceb7798af16b4a87d616b8d0" + +[[package]] +name = "serde" +version = "1.0.219" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5f0e2c6ed6606019b4e29e69dbaba95b11854410e5347d525002456dbbb786b6" +dependencies = [ + "serde_derive", +] + +[[package]] +name = "serde_derive" +version = "1.0.219" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5b0276cf7f2c73365f7157c8123c21cd9a50fbbd844757af28ca1f5925fc2a00" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.100", +] + +[[package]] +name = "serde_spanned" +version = "0.6.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "87607cb1398ed59d48732e575a4c28a7a8ebf2454b964fe3f224f2afc07909e1" +dependencies = [ + "serde", +] + +[[package]] +name = "smoltcp" +version = "0.12.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dad095989c1533c1c266d9b1e8d70a1329dd3723c3edac6d03bbd67e7bf6f4bb" +dependencies = [ + "bitflags 1.3.2", + "byteorder", + "cfg-if", + "defmt", + "heapless 0.8.0", + "managed", +] + +[[package]] +name = "spin" +version = "0.9.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6980e8d7511241f8acf4aebddbb1ff938df5eebe98691418c4468d0b72a96a67" +dependencies = [ + "lock_api", +] + +[[package]] +name = "stable_deref_trait" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a8f112729512f8e442d81f95a8a7ddf2b7c6b8a1a6f509a95864142b30cab2d3" + +[[package]] +name = "static_cell" +version = "2.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d89b0684884a883431282db1e4343f34afc2ff6996fe1f4a1664519b66e14c1e" +dependencies = [ + "portable-atomic", +] + +[[package]] +name = "strsim" +version = "0.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f" + +[[package]] +name = "strum" +version = "0.26.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8fec0f0aef304996cf250b31b5a10dee7980c85da9d759361292b8bca5a18f06" +dependencies = [ + "strum_macros 0.26.4", +] + +[[package]] +name = "strum" +version = "0.27.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f64def088c51c9510a8579e3c5d67c65349dcf755e5479ad3d010aa6454e2c32" +dependencies = [ + "strum_macros 0.27.1", +] + +[[package]] +name = "strum_macros" +version = "0.26.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4c6bee85a5a24955dc440386795aa378cd9cf82acd5f764469152d2270e581be" +dependencies = [ + "heck 0.5.0", + "proc-macro2", + "quote", + "rustversion", + "syn 2.0.100", +] + +[[package]] +name = "strum_macros" +version = "0.27.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c77a8c5abcaf0f9ce05d62342b7d298c346515365c36b673df4ebe3ced01fde8" +dependencies = [ + "heck 0.5.0", + "proc-macro2", + "quote", + "rustversion", + "syn 2.0.100", +] + +[[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.100" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b09a44accad81e1ba1cd74a32461ba89dee89095ba17b32f5d03683b1b1fc2a0" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[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.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "567b8a2dae586314f7be2a752ec7474332959c6460e02bde30d702a66d488708" +dependencies = [ + "thiserror-impl", +] + +[[package]] +name = "thiserror-impl" +version = "2.0.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7f7cf42b4507d8ea322120659672cf1b9dbb93f8f2d4ecfd6e51350ff5b17a1d" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.100", +] + +[[package]] +name = "toml" +version = "0.8.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cd87a5cdd6ffab733b2f74bc4fd7ee5fff6634124999ac278c35fc78c6120148" +dependencies = [ + "serde", + "serde_spanned", + "toml_datetime", + "toml_edit", +] + +[[package]] +name = "toml-cfg" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "68c587298ddd135c156e92e8c3eae69614d6eecea8e2d8a09daab011e5e6a21d" +dependencies = [ + "heck 0.4.1", + "proc-macro2", + "quote", + "serde", + "syn 2.0.100", + "toml", +] + +[[package]] +name = "toml_datetime" +version = "0.6.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0dd7358ecb8fc2f8d014bf86f6f638ce72ba252a2c3a2572f2a795f1d23efb41" +dependencies = [ + "serde", +] + +[[package]] +name = "toml_edit" +version = "0.22.24" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "17b4795ff5edd201c7cd6dca065ae59972ce77d1b80fa0a84d94950ece7d1474" +dependencies = [ + "indexmap", + "serde", + "serde_spanned", + "toml_datetime", + "winnow", +] + +[[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.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5a5f39404a5da50712a4c1eecf25e90dd62b613502b7e925fd4e4d19b5c96512" + +[[package]] +name = "vcell" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "77439c1b53d2303b20d9459b1ade71a83c716e3f9c34f3228c00e6f185d6c002" + +[[package]] +name = "void" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6a02e4885ed3bc0f2de90ea6dd45ebcbb66dacffe03547fadbb0eeae2770887d" + +[[package]] +name = "winapi-util" +version = "0.1.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cf221c93e13a30d793f7645a0e7762c55d169dbb0a49671918a2319d289b10bb" +dependencies = [ + "windows-sys", +] + +[[package]] +name = "windows-sys" +version = "0.59.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e38bc4d79ed67fd075bcc251a1c39b32a1776bbe92e5bef1f0bf1f8c531853b" +dependencies = [ + "windows-targets", +] + +[[package]] +name = "windows-targets" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973" +dependencies = [ + "windows_aarch64_gnullvm", + "windows_aarch64_msvc", + "windows_i686_gnu", + "windows_i686_gnullvm", + "windows_i686_msvc", + "windows_x86_64_gnu", + "windows_x86_64_gnullvm", + "windows_x86_64_msvc", +] + +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3" + +[[package]] +name = "windows_aarch64_msvc" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469" + +[[package]] +name = "windows_i686_gnu" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b" + +[[package]] +name = "windows_i686_gnullvm" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66" + +[[package]] +name = "windows_i686_msvc" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66" + +[[package]] +name = "windows_x86_64_gnu" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78" + +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d" + +[[package]] +name = "windows_x86_64_msvc" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" + +[[package]] +name = "winnow" +version = "0.7.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0e97b544156e9bebe1a0ffbc03484fc1ffe3100cbce3ffb17eac35f7cdd7ab36" +dependencies = [ + "memchr", +] + +[[package]] +name = "xtensa-lx" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "51cbb46c78cfd284c9378070ab90bae9d14d38b3766cb853a97c0a137f736d5b" +dependencies = [ + "critical-section", + "document-features", +] + +[[package]] +name = "xtensa-lx-rt" +version = "0.18.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "689c2ef159d9cd4fc9503603e9999968a84a30db9bde0f0f880d0cceea0190a9" +dependencies = [ + "anyhow", + "document-features", + "enum-as-inner", + "minijinja", + "r0", + "serde", + "strum 0.26.3", + "toml", + "xtensa-lx", + "xtensa-lx-rt-proc-macros", +] + +[[package]] +name = "xtensa-lx-rt-proc-macros" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "11277b1e4cbb7ffe44678c668518b249c843c81df249b8f096701757bc50d7ee" +dependencies = [ + "darling", + "proc-macro2", + "quote", + "syn 2.0.100", +] diff --git a/nodes/esp32/airbox/Cargo.toml b/nodes/esp32/airbox/Cargo.toml new file mode 100644 index 00000000..46d22d6c --- /dev/null +++ b/nodes/esp32/airbox/Cargo.toml @@ -0,0 +1,78 @@ +[package] +edition = "2024" +name = "airbox" +version = "0.1.0" + +[dependencies] +defmt = "0.3.10" +embassy-net = { version = "0.6.0", features = [ + "dhcpv4", + "medium-ethernet", + "tcp", + "udp", + "defmt", +] } +embedded-io = "0.6.1" +embedded-io-async = "0.6.1" +esp-alloc = "0.7.0" +esp-backtrace = { version = "0.15.1", features = [ + "defmt", + "esp32c6", + "exception-handler", + "panic-handler", +] } +esp-hal = { version = "1.0.0-beta.0", features = [ + "defmt", + "esp32c6", + "unstable", +] } +esp-println = { version = "0.13.0", features = ["defmt-espflash", "esp32c6", "critical-section"] } +smoltcp = { version = "0.12.0", default-features = false, features = [ + "medium-ethernet", + "multicast", + "proto-dhcpv4", + "proto-dns", + "proto-ipv4", + "socket-dns", + "socket-icmp", + "socket-raw", + "socket-tcp", + "socket-udp", +] } +# for more networking protocol support see https://crates.io/crates/edge-net +critical-section = "1.2.0" +embassy-executor = { version = "0.7.0", features = [ + "defmt", + "task-arena-size-20480", +] } +embassy-time = { version = "0.4.0", features = ["generic-queue-8"] } +embassy-sync = { version = "0.6.2" } +embassy-futures = { version = "0.1.1" } +esp-hal-embassy = { version = "0.7.0", features = ["esp32c6"] } +esp-wifi = { version = "0.13.0", features = [ + "builtin-scheduler", + "defmt", + "esp-alloc", + "esp32c6", + "wifi", +] } +heapless = { version = "0.8.0", default-features = false } +static_cell = { version = "2.1.0", features = ["nightly"] } + +toml-cfg = "0.2" +protocol = { path = "../../../crates/protocol" } +bme280-rs = { version = "0.3.0", features = ["async"] } + +[profile.dev] +# Rust debug is too slow. +# For debug builds always builds with some optimization +opt-level = "s" + +[profile.release] +codegen-units = 1 # LLVM can perform better optimizations using a single thread +debug = 2 +debug-assertions = false +incremental = false +lto = 'fat' +opt-level = 's' +overflow-checks = false diff --git a/nodes/esp32/airbox/build.rs b/nodes/esp32/airbox/build.rs new file mode 100644 index 00000000..e0ec8f61 --- /dev/null +++ b/nodes/esp32/airbox/build.rs @@ -0,0 +1,41 @@ +fn main() { + linker_be_nice(); + println!("cargo:rustc-link-arg=-Tdefmt.x"); + // make sure linkall.x is the last linker script (otherwise might cause problems with flip-link) + println!("cargo:rustc-link-arg=-Tlinkall.x"); +} + +fn linker_be_nice() { + let args: Vec = std::env::args().collect(); + if args.len() > 1 { + let kind = &args[1]; + let what = &args[2]; + + match kind.as_str() { + "undefined-symbol" => match what.as_str() { + "_defmt_timestamp" => { + eprintln!(); + eprintln!("💡 `defmt` not found - make sure `defmt.x` is added as a linker script and you have included `use defmt_rtt as _;`"); + eprintln!(); + } + "_stack_start" => { + eprintln!(); + eprintln!("💡 Is the linker script `linkall.x` missing?"); + eprintln!(); + } + _ => (), + }, + // we don't have anything helpful for "missing-lib" yet + _ => { + std::process::exit(1); + } + } + + std::process::exit(0); + } + + println!( + "cargo:rustc-link-arg=--error-handling-script={}", + std::env::current_exe().unwrap().display() + ); +} diff --git a/nodes/esp32/airbox/rust-toolchain.toml b/nodes/esp32/airbox/rust-toolchain.toml new file mode 100644 index 00000000..30c6884b --- /dev/null +++ b/nodes/esp32/airbox/rust-toolchain.toml @@ -0,0 +1,4 @@ +[toolchain] +channel = "stable" +components = ["rust-src"] +targets = ["riscv32imc-unknown-none-elf"] diff --git a/nodes/esp32/airbox/src/fans.rs b/nodes/esp32/airbox/src/fans.rs new file mode 100644 index 00000000..bbfd9892 --- /dev/null +++ b/nodes/esp32/airbox/src/fans.rs @@ -0,0 +1,111 @@ +use embassy_sync::blocking_mutex::raw::NoopRawMutex; +use embassy_sync::mutex::Mutex; +use embassy_time::Instant; +use esp_hal::gpio::GpioPin; +use esp_hal::ledc::channel::{self, Channel, ChannelIFace, Number}; +use esp_hal::ledc::timer::{Timer, TimerIFace}; +use esp_hal::ledc::{LSGlobalClkSource, Ledc, LowSpeed, timer}; +use esp_hal::peripherals::LEDC; +use esp_hal::time::Rate; +use protocol::large_bedroom::airbox::{DeviceError, Error}; +use protocol::make_error_string; + +use crate::wrap_error; + +/// stack allocated parts of Fans +pub struct FanStack { + control: Ledc<'static>, + timer: Timer<'static, LowSpeed>, +} + +pub struct Fans<'a> { + fan_channel: Channel<'a, LowSpeed>, + transition: Mutex, +} + +struct Transition { + transition_started: Instant, + power_pre_transition: u8, + power_target: u8, +} + +impl Transition { + fn fade_time(&self, target: u8) -> u16 { + const RATE: u16 = 2000 / 100; + let target_change = target as i8 - self.current_power() as i8; + let target_change = target_change.abs() as u16; + target_change * RATE + } + fn current_power(&self) -> u8 { + let target_change = + self.power_target as i8 - self.power_pre_transition as i8; + let progress = + self.transition_started.elapsed().as_millis() as f32 / 1000.0; + let progress = if progress > 1.0 { 1.0 } else { progress }; + + let curr = self.power_pre_transition as i8 + + (progress * target_change as f32) as i8; + curr as u8 + } + fn store_new_to(&mut self, target: u8) { + self.power_pre_transition = self.current_power(); + self.power_target = target; + self.transition_started = Instant::now(); + } +} + +impl FanStack { + pub fn new(led_controller: LEDC) -> Self { + let mut control = Ledc::new(led_controller); + control.set_global_slow_clock(LSGlobalClkSource::APBClk); + let mut timer = control.timer(timer::Number::Timer0); + defmt::unwrap!(timer.configure(timer::config::Config { + duty: timer::config::Duty::Duty10Bit, + clock_source: timer::LSClockSource::APBClk, + frequency: Rate::from_khz(24), + })); + FanStack { control, timer } + } +} + +impl<'a> Fans<'a> { + pub fn new(stack: &'a FanStack, pwm_pin: GpioPin<3>) -> Self { + let mut fan_channel = stack.control.channel(Number::Channel0, pwm_pin); + defmt::unwrap!(fan_channel.configure(channel::config::Config { + timer: &stack.timer, + duty_pct: 10, + pin_config: channel::config::PinConfig::PushPull, + })); + let transition = Mutex::new(Transition { + transition_started: Instant::now(), + power_pre_transition: 0, + power_target: 0, + }); + Self { + fan_channel, + transition, + } + } + + pub async fn current_power(&self) -> u8 { + self.transition.lock().await.current_power() + } + + pub async fn fade_time(&self, target: u8) -> u16 { + self.transition.lock().await.fade_time(target) + } + + pub async fn set_power(&self, target: u8) -> Result<(), protocol::Error> { + if let Err(e) = self.fan_channel.start_duty_fade( + self.current_power().await, + target, + self.fade_time(target).await, + ) { + return Err(wrap_error(Error::Running(DeviceError::Pwm( + make_error_string(e), + )))); + } + self.transition.lock().await.store_new_to(target); + Ok(()) + } +} diff --git a/nodes/esp32/airbox/src/main.rs b/nodes/esp32/airbox/src/main.rs new file mode 100644 index 00000000..59bb0533 --- /dev/null +++ b/nodes/esp32/airbox/src/main.rs @@ -0,0 +1,111 @@ +#![no_std] +#![no_main] + +use core::net::Ipv4Addr; + +use embassy_futures::join::join3; +use embassy_net::{Ipv4Cidr, StackResources}; +use esp_hal::clock::CpuClock; +use esp_hal::rng::Rng; +use esp_hal::timer::systimer::SystemTimer; +use esp_hal::timer::timg::TimerGroup; + +use esp_println as _; + +use embassy_executor::Spawner; + +use esp_backtrace as _; +use esp_wifi::EspWifiController; + +use embassy_sync::blocking_mutex::raw::NoopRawMutex; +use embassy_sync::channel::Channel; +use protocol::large_bedroom::airbox::Error; + +extern crate alloc; + +mod fans; +mod network; +mod sensor; + +#[toml_cfg::toml_config] +pub struct Config { + #[default("")] + wifi_ssid: &'static str, + #[default("")] + wifi_psk: &'static str, +} + +// When you are okay with using a nightly compiler it's better to use https://docs.rs/static_cell/2.1.0/static_cell/macro.make_static.html +macro_rules! mk_static { + ($t:ty,$val:expr) => {{ + static STATIC_CELL: static_cell::StaticCell<$t> = + static_cell::StaticCell::new(); + #[deny(unused_attributes)] + let x = STATIC_CELL.uninit().write(($val)); + x + }}; +} + +type Queue = + Channel, 20>; + +#[esp_hal_embassy::main] +async fn main(spawner: Spawner) { + defmt::warn!("started"); + let config = esp_hal::Config::default().with_cpu_clock(CpuClock::default()); + let peripherals = esp_hal::init(config); + + esp_alloc::heap_allocator!(size: 72 * 1024); + + let timg0 = TimerGroup::new(peripherals.TIMG0); + let mut rng = Rng::new(peripherals.RNG); + + let esp_wifi_ctrl = &*mk_static!( + EspWifiController<'static>, + esp_wifi::init(timg0.timer0, rng, peripherals.RADIO_CLK).unwrap() + ); + + let (controller, interfaces) = + esp_wifi::wifi::new(esp_wifi_ctrl, peripherals.WIFI).unwrap(); + let wifi_interface = interfaces.sta; + + let systimer = SystemTimer::new(peripherals.SYSTIMER); + esp_hal_embassy::init(systimer.alarm0); + + let config = + embassy_net::Config::ipv4_static(embassy_net::StaticConfigV4 { + address: Ipv4Cidr::new(Ipv4Addr::new(192, 168, 1, 8), 24), + gateway: Some(Ipv4Addr::new(192, 168, 1, 1)), + dns_servers: heapless::Vec::new(), + }); + + let seed = ((rng.random() as u64) << 32) | rng.random() as u64; + + // Init network stack + let (stack, runner) = embassy_net::new( + wifi_interface, + config, + mk_static!(StackResources<3>, StackResources::<3>::new()), + seed, + ); + + spawner.spawn(network::connection(controller)).ok(); + spawner.spawn(network::net_task(runner)).ok(); + + let queue = Channel::new(); + let fan_stack = fans::FanStack::new(peripherals.LEDC); + let fans = fans::Fans::new(&fan_stack, peripherals.GPIO3); + + network::handle(&stack, &queue, &fans).await; + + // join3( + // network::handle(&stack, &queue, &fans), + // sensor::button(peripherals.GPIO10, &queue, &fans), + // sensor::measure(peripherals.I2C0, &queue), + // ) + // .await; +} + +fn wrap_error(error: Error) -> protocol::Error { + protocol::Error::LargeBedroom(protocol::large_bedroom::Error::Airbox(error)) +} diff --git a/nodes/esp32/airbox/src/network.rs b/nodes/esp32/airbox/src/network.rs new file mode 100644 index 00000000..282f05fa --- /dev/null +++ b/nodes/esp32/airbox/src/network.rs @@ -0,0 +1,228 @@ +use defmt::{debug, info, unwrap, warn}; +use embassy_futures::select::{self, select}; +use embassy_net::tcp::{TcpReader, TcpSocket, TcpWriter}; +use embassy_net::{Ipv4Address, Runner}; +use embassy_time::{Duration, Timer}; +use embedded_io_async::Write; +use esp_wifi::wifi::{ + ClientConfiguration, Configuration, WifiController, WifiDevice, WifiEvent, + WifiState, +}; +use protocol::affector::DeserializeError; +use protocol::large_bedroom::airbox; +use protocol::{Affector, ErrorReport, affector}; + +use crate::fans::Fans; +use crate::{CONFIG, Queue}; +type SensMsg = protocol::SensorMessage<10>; + +const fn max(a: usize, b: usize) -> usize { + [a, b][(a < b) as usize] +} + +pub async fn handle( + stack: &embassy_net::Stack<'_>, + publish: &Queue, + fans: &Fans<'_>, +) { + let mut rx_buffer = [0; 1024]; + let mut tx_buffer = + [0; max(SensMsg::ENCODED_SIZE, protocol::ErrorReport::ENCODED_SIZE) + * 2]; + + let mut socket = TcpSocket::new(*stack, &mut rx_buffer, &mut tx_buffer); + socket.set_timeout(Some(Duration::from_secs(5))); + socket.set_keep_alive(Some(Duration::from_secs(1))); + let host_addr = Ipv4Address::new(192, 168, 1, 43); + let host_port = 1234; + + debug!("Configured socket and connecting"); + loop { + info!("ip: {}", stack.config_v4().map(|config| config.address)); + debug!("socket state: {:?}", socket.state()); + if let Err(e) = socket.connect((host_addr, host_port)).await { + warn!("connect error: {}", e); + Timer::after_secs(5).await; + continue; + } + + info!("(re-)connected"); + // Prevent out-dated data from being send + publish.clear(); + + let (reader, writer) = socket.split(); + match select( + send_messages(writer, publish), + receive_orders(reader, fans, publish), + ) + .await + { + select::Either::First(e) => { + warn!("Error while sending messages: {}", e) + } + select::Either::Second(e) => warn!("Error receiving orders: {}", e), + }; + // Or the socket will hang for a while waiting to close this makes sure + // we can reconnect instantly + socket.abort(); + Timer::after_secs(60).await; // Experiment: does this help? + } +} + +async fn send_messages( + mut tcp: TcpWriter<'_>, + publish: &Queue, +) -> embassy_net::tcp::Error { + let mut buf = [0; 1 + max( + max(SensMsg::ENCODED_SIZE, ErrorReport::ENCODED_SIZE), + affector::ListMessage::<5>::ENCODED_SIZE, + )]; + let encoded_len = affector_list().encode_slice(&mut buf[1..]).len(); + buf[0] = protocol::Msg::<5>::AFFECTOR_LIST; + let to_send = &buf[..=encoded_len]; + if let Err(e) = tcp.write_all(to_send).await { + return e; + } + if let Err(e) = tcp.flush().await { + return e; + } + + loop { + let to_send = match publish.receive().await { + Ok(reading) => { + let mut msg = SensMsg::default(); + defmt::unwrap!(msg.values.push(reading)); + let encoded_len = msg.encode_slice(&mut buf[1..]).len(); + buf[0] = protocol::Msg::<0>::READINGS; + &buf[..=encoded_len] + } + Err(error) => { + let encoded_len = + ErrorReport::new(error).encode_slice(&mut buf[1..]).len(); + buf[0] = protocol::Msg::<0>::ERROR_REPORT; + &buf[..=encoded_len] + } + }; + + if let Err(e) = tcp.write_all(to_send).await { + return e; + } + if let Err(e) = tcp.flush().await { + return e; + } + } +} + +#[derive(defmt::Format)] +enum ReadError { + ConnectionClosed, + TcpError(embassy_net::tcp::Error), + Deserialize(DeserializeError), +} + +async fn receive_orders( + mut tcp: TcpReader<'_>, + fans: &Fans<'_>, + publish: &Queue, +) -> ReadError { + defmt::debug!("ready to receive orders"); + let mut decoder = protocol::affector::Decoder::default(); + let mut buf = [0u8; 100]; + loop { + let res = tcp.read(&mut buf).await; + let n_read = match res { + Ok(0) => return ReadError::ConnectionClosed, + Ok(n_read) => n_read, + Err(e) => return ReadError::TcpError(e), + }; + let mut read = &buf[..n_read]; + + loop { + let (item, remaining) = match decoder.feed(read) { + Ok(Some((item, remaining))) => (item, remaining), + Ok(None) => break, + Err(e) => return ReadError::Deserialize(e), + }; + + read = remaining; + + let protocol::Affector::LargeBedroom( + protocol::large_bedroom::Affector::Airbox(affector), + ) = item + else { + defmt::error!("Got affector for other node"); + continue; + }; + + defmt::info!("got affector order: {:?}", affector); + match affector { + protocol::large_bedroom::airbox::Affector::FanPower { + power, + } => { + if let Err(e) = fans.set_power(power).await { + defmt::error!("could not set fan power: {}", e); + let _ignore_err = publish.try_send(Err(e)); + } + } + protocol::large_bedroom::airbox::Affector::ResetNode => todo!(), + } + } + } +} + +#[embassy_executor::task] +pub async fn net_task(mut runner: Runner<'static, WifiDevice<'static>>) { + runner.run().await +} + +#[embassy_executor::task] +pub async fn connection(mut controller: WifiController<'static>) { + defmt::info!("start connection task"); + loop { + if esp_wifi::wifi::wifi_state() == WifiState::StaConnected { + // Wait until we're no longer connected + controller.wait_for_event(WifiEvent::StaDisconnected).await; + Timer::after(Duration::from_millis(5000)).await + } + if !matches!(controller.is_started(), Ok(true)) { + let client_config = Configuration::Client(ClientConfiguration { + // The constant `CONFIG` is auto-generated by `toml_config`. + ssid: CONFIG.wifi_ssid.try_into().unwrap(), + password: CONFIG.wifi_psk.try_into().unwrap(), + ..Default::default() + }); + controller.set_configuration(&client_config).unwrap(); + defmt::info!("Starting wifi"); + controller.start_async().await.unwrap(); + defmt::info!("Wifi started!"); + } + defmt::info!("About to connect..."); + defmt::info!("{}, {}", CONFIG.wifi_ssid, CONFIG.wifi_psk); + + match controller.connect_async().await { + Ok(()) => { + defmt::info!("Wifi connected!") + } + Err(e) => { + defmt::info!("Failed to connect to wifi: {}", e); + let scan_res = controller.scan_n_async::<12>().await; + defmt::info!("Scan results: {}", scan_res); + Timer::after(Duration::from_millis(5000)).await + } + } + } +} + +fn affector_list() -> affector::ListMessage<2> { + let mut list = affector::ListMessage::<2>::empty(); + unwrap!(list.values.push(Affector::LargeBedroom( + protocol::large_bedroom::Affector::Airbox(airbox::Affector::FanPower { + power: 0, + }), + ))); + unwrap!(list.values.push(Affector::LargeBedroom( + protocol::large_bedroom::Affector::Airbox(airbox::Affector::ResetNode) + ))); + + list +} diff --git a/nodes/esp32/airbox/src/sensor.rs b/nodes/esp32/airbox/src/sensor.rs new file mode 100644 index 00000000..120f241b --- /dev/null +++ b/nodes/esp32/airbox/src/sensor.rs @@ -0,0 +1,141 @@ +use bme280_rs::{AsyncBme280, Sample}; +use embassy_time::{Delay, Duration, TimeoutError, Timer, WithTimeout}; +use esp_hal::gpio::{GpioPin, Input, InputConfig, Pull}; +use esp_hal::i2c::master::{Config, I2c}; +use esp_hal::peripherals::I2C0; +use esp_hal::time::Rate; +use protocol::button::Press; +use protocol::large_bedroom::airbox::{Device, DeviceError, Error, Reading}; +use protocol::{large_bedroom, make_error_string}; + +use crate::fans::Fans; +use crate::{Queue, wrap_error}; + +fn wrap_reading(reading: Reading) -> protocol::Reading { + protocol::Reading::LargeBedroom(large_bedroom::Reading::Airbox(reading)) +} + +fn next_fan_power(current: u8) -> u8 { + let next = match current { + ..15 => 20, + 15..35 => 40, + 35..55 => 60, + 55..75 => 80, + 75..95 => 100, + 95.. => 0, + }; + defmt::info!("current: {}, next_power: {}", current, next); + next +} + +pub async fn button(pin: GpioPin<10>, queue: &Queue, fans: &Fans<'_>) { + let mut input = Input::new(pin, InputConfig::default().with_pull(Pull::Up)); + + loop { + // TODO measure press time, deduplicate with bed_lb & bed_sb + input.wait_for_low().await; + Timer::after_millis(50).await; + if input.is_high() { + continue + } + + let _ignore_err = + queue.try_send(Ok(wrap_reading(Reading::Button(Press(1))))); + + let next = next_fan_power(fans.current_power().await); + if let Err(e) = fans.set_power(next).await { + defmt::error!("error setting fan power: {}", e); + let _ignore_err = queue.try_send(Err(e)); + } + + Timer::after_millis(500).await; + } +} + +pub async fn measure(i2c: I2C0, queue: &Queue) { + defmt::info!("HOI"); + let i2c = match I2c::new( + i2c, + Config::default().with_frequency(Rate::from_khz(4)), + ) { + Ok(i2c) => i2c, + Err(e) => { + defmt::error!("Could not start i2c"); + let report = + Error::Setup(DeviceError::BmeError(make_error_string(e))); + let _ignore_err = queue.try_send(Err(wrap_error(report))); + return; + } + } + .into_async(); + + let mut i2c = Some(i2c); + loop { + let mut bme = AsyncBme280::new(defmt::unwrap!(i2c.take()), Delay); + match bme.init().with_timeout(Duration::from_millis(200)).await { + Ok(Ok(())) => (), + Ok(Err(e)) => { + defmt::error!("Could not init bme280: {}", e); + let report = + Error::Setup(DeviceError::BmeError(make_error_string(e))); + let _ignore_err = queue.try_send(Err(wrap_error(report))); + i2c = Some(bme.release()); + continue; + } + Err(TimeoutError) => { + defmt::error!("Could not init bme280, timeout"); + let report = Error::SetupTimedOut(Device::Bme280); + let _ignore_err = queue.try_send(Err(wrap_error(report))); + i2c = Some(bme.release()); + continue; + } + } + + read_every_5_seconds_until_error(queue, &mut bme).await; + i2c = Some(bme.release()); + Timer::after_secs(5).await; + } +} + +async fn read_every_5_seconds_until_error( + queue: &Queue, + bme: &mut AsyncBme280, Delay>, +) { + loop { + defmt::info!("loop start"); + match bme + .read_sample() + .with_timeout(Duration::from_millis(200)) + .await + { + Ok(Ok(Sample { + pressure: Some(p), + temperature: Some(t), + .. + })) => { + defmt::info!("pressure: {}, temperature: {}", p, t); + let _ignore_err = + queue.try_send(Ok(wrap_reading(Reading::Temperature(t)))); + let _ignore_err = + queue.try_send(Ok(wrap_reading(Reading::Pressure(p)))); + } + Ok(Ok(_)) => { + defmt::unreachable!("pressure and temperature are enabled") + } + Ok(Err(e)) => { + defmt::error!("Could not read bme280"); + let report = + Error::Running(DeviceError::BmeError(make_error_string(e))); + let _ignore_err = queue.try_send(Err(wrap_error(report))); + return; + } + Err(TimeoutError) => { + defmt::error!("Could not read bme280, timeout"); + let report = Error::Timeout(Device::Bme280); + let _ignore_err = queue.try_send(Err(wrap_error(report))); + return; + } + } + Timer::after_secs(5).await; + } +} diff --git a/nodes/esp32/airbox/template.yaml b/nodes/esp32/airbox/template.yaml new file mode 100644 index 00000000..990c8aa1 --- /dev/null +++ b/nodes/esp32/airbox/template.yaml @@ -0,0 +1,149 @@ +options: + - !Option + name: unstable-hal + display_name: Enable unstable HAL features. + help: "This configuration enables unstable esp-hal features. + These come with no stability guarantees, and could be changed or removed at any time." + + - !Option + name: alloc + display_name: Enable allocations via the esp-alloc crate. + help: esp-alloc comes with no stability guarantees at this time. + + - !Option + name: wifi + display_name: Enable Wi-Fi via the esp-wifi crate. + help: esp-wifi comes with no stability guarantees at this time. + requires: + - alloc + - unstable-hal + chips: + - esp32 + - esp32c2 + - esp32c3 + - esp32c6 + - esp32s2 + - esp32s3 + + - !Option + name: ble + display_name: Enable BLE via the esp-wifi crate. + help: esp-wifi comes with no stability guarantees at this time. + requires: + - alloc + - unstable-hal + chips: + - esp32 + - esp32c2 + - esp32c3 + - esp32c6 + - esp32h2 + - esp32s3 + + - !Option + name: embassy + display_name: Add embassy framework support. + help: esp-hal-embassy comes with no stability guarantees at this time. + requires: + - unstable-hal + + - !Option + name: probe-rs + display_name: Use probe-rs to flash and monitor instead of espflash. + help: probe-rs is a debugger that connects to the chips over JTAG. It can be used to flash and + monitor, and it can also be used to interactively debug an application, or run tests on the + hardware. Semihosting or RTT-based technologies like defmt-rtt require probe-rs. + chips: + - esp32c6 + - esp32h2 + - esp32s3 + + - !Option + name: probe-rs + display_name: Use probe-rs to flash and monitor instead of espflash. + help: probe-rs is a debugger that connects to the chips over JTAG. It can be used to flash and + monitor, and it can also be used to interactively debug an application, or run tests on the + hardware. Semihosting or RTT-based technologies like defmt-rtt require probe-rs. + + probe-rs requires a debug probe like esp-prog, and will not work with USB-UART adapters that + often come on development boards. + chips: + - esp32 + - esp32s2 + - esp32c2 + - esp32c3 + + - !Category + name: flashing-probe-rs + display_name: Flashing, logging and debugging (probe-rs) + requires: + - probe-rs + options: + - !Option + name: defmt + display_name: Use defmt to print messages. + selection_group: log-frontend + - !Option + name: panic-rtt-target + display_name: Use panic-rtt-target as the panic handler. + selection_group: panic-handler + requires: + - probe-rs + + - !Category + name: flashing-espflash + display_name: Flashing, logging and debugging (espflash) + requires: + - "!probe-rs" + options: + - !Option + name: log + display_name: Use the log crate to print messages. + selection_group: log-frontend + requires: + - "!probe-rs" + - !Option + name: defmt + display_name: Use defmt to print messages. + selection_group: log-frontend + - !Option + name: esp-backtrace + display_name: Use esp-backtrace as the panic handler. + selection_group: panic-handler + requires: + - "!probe-rs" + + - !Category + name: optional + display_name: Options + options: + - !Option + name: wokwi + display_name: Add support for Wokwi simulation using VS Code Wokwi extension. + chips: + - esp32 + - esp32c3 + - esp32c6 + - esp32h2 + - esp32s2 + - esp32s3 + + - !Option + name: dev-container + display_name: Add support for VS Code Dev Containers and GitHub Codespaces. + + - !Option + name: ci + display_name: Add GitHub Actions support with some basic checks. + + - !Category + name: editor + display_name: Optional editor config files for rust-analyzer + options: + - !Option + name: helix + display_name: Add rust-analyzer settings for Helix Editor + + - !Option + name: vscode + display_name: Add rust-analyzer settings for Visual Studio Code diff --git a/rust-toolchain.toml b/rust-toolchain.toml new file mode 100644 index 00000000..b3d725d7 --- /dev/null +++ b/rust-toolchain.toml @@ -0,0 +1,10 @@ +[toolchain] +channel = "1.91" +components = [ + "rustc", + "cargo", + "clippy", + "rustfmt", + "rust-analyzer", + "rust-src", +] diff --git a/rustfmt.toml b/rustfmt.toml new file mode 100644 index 00000000..df99c691 --- /dev/null +++ b/rustfmt.toml @@ -0,0 +1 @@ +max_width = 80 diff --git a/src/controller/commands.rs b/src/controller/commands.rs deleted file mode 100644 index f8aa2111..00000000 --- a/src/controller/commands.rs +++ /dev/null @@ -1,50 +0,0 @@ -use super::{ActiveState, Modifications, System}; -use crate::controller::states::*; -use crate::controller::states::RoomState; - -#[derive(Copy, Clone)] -pub enum TargetState { - Normal, - LightLoop, -} - -#[derive(Copy, Clone)] -pub enum Command { - LampsToggle, - LampsDim, - LampsDimmest, - LampsEvening, - LampsNight, - LampsDay, - LampsOff, - LampsOn, - - ChangeState(TargetState), -} - -pub fn handle_cmd(cmd: Command, state: ActiveState, mods: &mut Modifications, sys: &mut System) -> ActiveState { - println!("handled a command"); - match cmd { - Command::ChangeState(target_state) => { - return handle_changestate_cmd(target_state, mods, sys) - } - //Command::PauseMpd => {unimplemented!(); state}, - - Command::LampsToggle => {sys.lights.toggle().unwrap(); mods.lighting = true}, - Command::LampsDim => {sys.lights.set_all_to(50,500).unwrap(); mods.lighting = true}, - Command::LampsDimmest => {sys.lights.set_all_to(1,500).unwrap(); mods.lighting = true}, - Command::LampsEvening => {sys.lights.set_all_to(254,320).unwrap(); mods.lighting = true}, - Command::LampsNight => {sys.lights.set_all_to(220,500).unwrap(); mods.lighting = true}, - Command::LampsDay => {sys.lights.set_all_to(254,240).unwrap(); mods.lighting = true}, - Command::LampsOff => {unimplemented!(); mods.lighting = true}, - Command::LampsOn => {unimplemented!(); mods.lighting = true}, - } - state -} - -fn handle_changestate_cmd(target_state: TargetState, mods: &mut Modifications, sys: &mut System) -> ActiveState { - match target_state { - TargetState::Normal => ActiveState::Normal(Normal::enter(mods, sys)), - TargetState::LightLoop => ActiveState::LightLoop(LightLoop::enter(mods, sys)), - } -} diff --git a/src/controller/mod.rs b/src/controller/mod.rs deleted file mode 100644 index c6a7bece..00000000 --- a/src/controller/mod.rs +++ /dev/null @@ -1,97 +0,0 @@ -use std::sync::mpsc; -use std::time::{Duration, Instant}; -use std::thread; - -mod system; -use system::lamps::Lighting; - -mod states; -use states::{ActiveState, RoomState}; -mod commands; -use commands::{handle_cmd}; -pub use commands::{Command, TargetState}; - -pub enum Event { - Update, - Alarm, - Test, - Command(Command), - Stop, -} - -pub struct Modifications { //change name to: alteration, deviation, overrides or something else? - lighting: bool - //Mpd, - //Desk, - //Alarm, -} - -impl Default for Modifications { - fn default() -> Self { - Modifications {lighting: false} - } -} - -pub struct System { - update_period: Duration, - next_update: Instant, - - lights: Lighting, - //mpd - //etc -} - -fn saturating_duration_till(target: std::time::Instant) -> std::time::Duration{ - let now = Instant::now(); - if now < target { - target - now - } else { - Duration::from_secs(0) - } -} - -pub fn start(rx: mpsc::Receiver) -> Result<(),()>{ - - let mut system = System { - update_period: Duration::from_secs(5), - next_update: Instant::now()+Duration::from_secs(5), - - lights: Lighting::init()?, - //mpd init? - }; - - thread::spawn(move || { - let mut mods = Modifications::default(); - // TODO guess best init state from statefile or lamps+mpd+time - - let mut state = ActiveState::Normal(states::Normal::enter(&mut mods, &mut system)); //initial state - - loop { - - //wait for next update or an incoming event - let start_recv = Instant::now(); - let time_till_update = saturating_duration_till(system.next_update); - let event = if let Ok(event) = rx.recv_timeout(time_till_update){ - event - } else { - system.next_update = Instant::now()+system.update_period; - Event::Update - }; - - state = match (event, state) { - //specific test code for normal state - (Event::Test, ActiveState::Normal(state)) => {dbg!("a test happend while in normal state"); ActiveState::Normal(state)}, - - //general code that is the same for all functions, unless specific handlers exist above - (Event::Command(cmd), state) => {handle_cmd(cmd, state, &mut mods, &mut system)}, - (Event::Update, state) => {state.update(&mut mods, &mut system)}, - (Event::Alarm, state) => {dbg!("ALARM ALARM"); state}, - (Event::Test, state) => {dbg!("a test happend"); state}, - - (Event::Stop, _) => break, - }; - } - }); - Ok(()) -} - diff --git a/src/controller/states/lightloop.rs b/src/controller/states/lightloop.rs deleted file mode 100644 index 51ef0c8f..00000000 --- a/src/controller/states/lightloop.rs +++ /dev/null @@ -1,38 +0,0 @@ -use super::super::{Modifications, System}; -use super::{RoomState, ActiveState}; -use super::normal; - -use std::time::{Duration, Instant}; - -#[derive(Default, Clone, Copy)] -pub struct LightLoop { - counter: u8, -} - -impl RoomState for LightLoop { - fn update(mut self, mods: &mut Modifications, sys: &mut System) -> ActiveState { - dbg!("updating lightloop state"); - if (self.counter == 0){ - ActiveState::Normal(normal::Normal::enter(mods, sys)) - } else { - dbg!(self.counter); - sys.lights.set_all_to(self.counter, 200); - self.counter -= 1; - ActiveState::LightLoop(self) - } - } - fn enter(mods: &mut Modifications, sys: &mut System) -> Self { - dbg!("making everything rdy for the lightloop state"); - - sys.lights.set_all_to(0, 200); - mods.lighting = false; - - sys.update_period = Duration::from_millis(500); - sys.next_update = Instant::now()+sys.update_period; - - Self {counter: 100, } - } -} - - - diff --git a/src/controller/states/mod.rs b/src/controller/states/mod.rs deleted file mode 100644 index 80c4aab1..00000000 --- a/src/controller/states/mod.rs +++ /dev/null @@ -1,28 +0,0 @@ -use super::{System, Modifications}; - -mod normal; -mod lightloop; - -pub use normal::Normal; -pub use lightloop::LightLoop; - - -#[derive(Copy, Clone)] -pub enum ActiveState { - Normal(normal::Normal), - LightLoop(lightloop::LightLoop) -} - -impl ActiveState { - pub fn update(self, mods: &mut Modifications, system: &mut System) -> ActiveState { - match self { - ActiveState::Normal(state) => state.update(mods, system), - ActiveState::LightLoop(state) => state.update(mods, system), - } - } -} - -pub trait RoomState { - fn enter(mods: &mut Modifications, system: &mut System) -> Self; - fn update(self, mods: &mut Modifications, system: &mut System) -> ActiveState; -} \ No newline at end of file diff --git a/src/controller/states/normal.rs b/src/controller/states/normal.rs deleted file mode 100644 index cd2b75b6..00000000 --- a/src/controller/states/normal.rs +++ /dev/null @@ -1,21 +0,0 @@ -use super::super::{Modifications, System}; -use super::{RoomState, ActiveState}; - -use std::time::{Duration, Instant}; - -#[derive(Default, Clone, Copy)] -pub struct Normal {} - -impl RoomState for Normal { - fn update(self, mods: &mut Modifications, sys: &mut System) -> ActiveState { - //dbg!("updating normal state"); - ActiveState::Normal(self) - } - fn enter(mods: &mut Modifications, sys: &mut System) -> Self { - dbg!("making everything rdy for the normal state"); - sys.update_period = Duration::from_secs(5); - sys.next_update = Instant::now()+sys.update_period; - - Self::default() - } -} diff --git a/src/controller/system/lamps/mod.rs b/src/controller/system/lamps/mod.rs deleted file mode 100644 index 2ac7bb68..00000000 --- a/src/controller/system/lamps/mod.rs +++ /dev/null @@ -1,191 +0,0 @@ -extern crate philipshue; -extern crate serde_yaml; - -use philipshue::bridge; -use philipshue::bridge::Bridge; -use philipshue::hue::LightCommand; -use philipshue::errors::{HueError, HueErrorKind, BridgeError::{LinkButtonNotPressed, DeviceIsUnreachable}}; - -use std::thread; -use std::time::Duration; -use std::fs::File; -use std::path::Path; -use std::collections::{HashMap, BTreeMap}; - -fn register(ip: &str) -> Result{ - for _ in 0..5 {//try 5 times to connect - match bridge::register_user(ip, "homeAutomationSys") { - Ok(recieved_login) => { - println!("Success, linked to brige"); - info!("User registered: {}, on IP: {}", &recieved_login, ip); - return Ok(recieved_login); - } - Err(HueError(HueErrorKind::BridgeError { error: LinkButtonNotPressed, .. }, _)) => { - println!("Please, press the link on the bridge. Retrying in 5 seconds"); - thread::sleep(Duration::from_secs(5)); - } - Err(e) => { - println!("Unexpected error occured: {}", e); - return Err(()); - } - } - } - return Err(()); -} - -fn find_bridge_ip() -> Result { - let mut discovered = bridge::discover().unwrap(); - if discovered.len() == 0 { - error!("No bridge found!"); - return Err(()); - } else if discovered.len() > 1 { - error!("Found multiple hue bridges: {:?}, continueing with first one in list", discovered); - } - - Ok(discovered.pop().unwrap().into_ip()) -} - -fn saved_bridge_info() -> Result<(String, String),()> { - let path = Path::new("hueBridgeLogin"); - match File::open(&path){ - Err(e) => error!("find ip and login file, error: {}", e), - Ok(f) => { - match serde_yaml::from_reader(f){ - Ok((ip, login))=> return Ok((ip, login)), - Err(_) => error!("could not read ip and login from file"), - } - }, - } - Err(()) -} - -fn update_saved_bridge_info(bridge_ip: &str, login: &str) -> Result<(), ()> { - let path = Path::new("hueBridgeLogin"); - match File::create(&path){ - Ok(f) => if let Err(e) = serde_yaml::to_writer(f,&(bridge_ip, login)){ - error!("could not write ip and login from file, error: {}", e); - } else { return Ok(()) }, - Err(e) => { - error!("cant open ip and login file, error: {}", e); - }, - } - Err(()) -} - -fn get_bridge_and_status() -> Result<(Bridge, BTreeMap),()> { - - if let Ok((mut ip, mut login)) = saved_bridge_info(){ - let mut update_ip_or_login = false; - loop { - let bridge = Bridge::new(&ip, &login); - match bridge.get_all_lights(){ - Ok(lights_info) => { - if update_ip_or_login { - if update_saved_bridge_info(&ip, &login).is_err() { - error!("Could not save new bridge ip and login, next run will fail without user intervention") - } - } - return Ok((bridge, lights_info)); - }, - //cant find bridge on given ip - Err(HueError(HueErrorKind::BridgeError{error: DeviceIsUnreachable, ..}, _)) => { - ip = find_bridge_ip().map_err(|_| ())?; - update_ip_or_login = true; - }, - //cant register as button was not pressed in time - Err(HueError(HueErrorKind::BridgeError{error: LinkButtonNotPressed, ..}, _)) => { - login = register(&ip).map_err(|_| ())?; - update_ip_or_login = true; - }, - Err(e) => { - error!("Unexpected error occured: {:?}", e); - return Err(()); - }, - } - } - } else { - let ip = find_bridge_ip().map_err(|_| ())?; - let login = register(&ip).map_err(|_| ())?; - if update_saved_bridge_info(&ip, &login).is_err() { - error!("Could not save new bridge ip and login, next run will fail without user intervention") - }; - - let bridge = Bridge::new(&ip, &login); - let lights_info = bridge.get_all_lights().map_err(|_| ())?; - return Ok((bridge, lights_info)); - } -} - -//adaptation from philipshue LightState that adds some -//values and removes unused -struct Lamp { - pub on: bool, - pub bri: u8, - pub hue: Option, - pub sat: Option, - pub xy: Option<(f32, f32)>, - pub ct: Option, - pub reachable: bool, -} - -pub struct Lighting { - bridge: Bridge, - //local cache of current state (used for toggle) - lamps: HashMap, -} - -impl From<&philipshue::hue::LightState> for Lamp{ - fn from(state: &philipshue::hue::LightState) -> Self { - Lamp{ - on: state.on, - bri: state.bri, - hue: state.hue, - sat: state.sat, - xy: state.xy, - ct: state.ct, - reachable: state.reachable, - } - } -} - -impl Lighting { - - pub fn init() -> Result { - let (bridge, lights_info) = get_bridge_and_status()?; - let lamps: HashMap = lights_info.iter().map(|(id,light)| (*id, Lamp::from(&light.state))).collect(); - - Ok(Self {bridge, lamps}) - } - - //how to deal with errors? - pub fn toggle(&mut self) -> Result<(),()>{ - let numb_on: u8 = self.lamps.values().map(|lamp| lamp.on as u8).sum(); - let numb_off = self.lamps.len() as u8 - numb_on; - - //group ID 0 is a special group containing all lights known to the bridge - if numb_on > numb_off { - let command = LightCommand::off(LightCommand::default() ); - self.bridge.set_group_state(0, &command).map_err(|_| ())?; - self.lamps.values_mut().for_each(|lamp| lamp.on = false); - } else { - let command = LightCommand::on(LightCommand::default() ); - self.bridge.set_group_state(0, &command).map_err(|_| ())?; - self.lamps.values_mut().for_each(|lamp| lamp.on = true); - } - - Ok(()) - } - - //how to deal with errors? - pub fn set_all_to(&mut self, bri: u8, ct: u16) -> Result<(),()>{ - let command = LightCommand::default(); - let command = command.on(); - let command = command.with_bri(bri); - let command = command.with_ct(ct); - self.bridge.set_group_state(0, &command).map_err(|_| ())?; - self.lamps.values_mut().for_each(|lamp| {lamp.bri =bri; lamp.ct =Some(ct); lamp.on =true}); - - Ok(()) - } - -} diff --git a/src/controller/system/mod.rs b/src/controller/system/mod.rs deleted file mode 100644 index 14789e7e..00000000 --- a/src/controller/system/mod.rs +++ /dev/null @@ -1 +0,0 @@ -pub mod lamps; \ No newline at end of file diff --git a/src/input/alarms.rs b/src/input/alarms.rs deleted file mode 100644 index 7435e4e4..00000000 --- a/src/input/alarms.rs +++ /dev/null @@ -1,140 +0,0 @@ -use std::collections::BTreeSet; -use std::path::Path; - -use std::sync::{Arc, Mutex, mpsc}; -use std::thread; - -use chrono::{DateTime, Utc}; -use serde::{Serialize, Deserialize}; -use std::fs::File; -use serde_yaml; - -use crate::controller::Event; -use crate::errors::Error; - -//TODO, move alarms to input? then backup waker/trigger/speaker/alarm moves to arduino - -struct AlarmList { - memory: BTreeSet>, - file: File, -} - -enum WakerMessage { - RemoveAlarm(DateTime), - AddAlarm(DateTime), -} - -#[derive(Debug)] -struct Alarms { - waker_tx: mpsc::Sender, - waker_thread: thread::JoinHandle<()>, -} - -fn waker(mut alarm_list: AlarmList, event_tx: mpsc::Sender, waker_rx: mpsc::Receiver) { - - loop { - if let Some(current_alarm) = alarm_list.get_next_alarm() { - loop { //we have an alarm time, keep waiting until is should go off, handle instructions in the mean time - let now = Utc::now(); - let timeout = (now - current_alarm).to_std().unwrap(); - - //do we sound the an alarm or should we add or remove one? - match waker_rx.recv_timeout(timeout) { - Ok(message) => match message {//the alarm should not go off - WakerMessage::RemoveAlarm(at_time) => alarm_list.remove_alarm(&at_time), - WakerMessage::AddAlarm(at_time) => alarm_list.add_alarm(at_time), - }, - Err(error) => match error {//should the alarm go off or should we stop? - mpsc::RecvTimeoutError::Timeout => { - event_tx.send(Event::Alarm); //set - alarm_list.remove_alarm(¤t_alarm); - break; //get next alarm - } - //we should stop, end the thread by returning - mpsc::RecvTimeoutError::Disconnected => return, - } - } - } - } else { - //we have no alarm to wait on, wait for instructions - loop { - match waker_rx.recv() { - Ok(message) => match message { - WakerMessage::RemoveAlarm(at_time) => alarm_list.remove_alarm(&at_time), - //should not only add the alarm but go back and start waiting on it - WakerMessage::AddAlarm(at_time) => { alarm_list.add_alarm(at_time); break }, - } - Err(_) => return //cant have timed out thus program should exit - } - } - } - - } -} - -impl Alarms { - - fn setup_alarms(event_tx: mpsc::Sender) -> Result { - let mut alarm_list = AlarmList::load()?; - - let (waker_tx, waker_rx) = mpsc::channel(); - let waker_thread = thread::spawn(move || { waker(alarm_list, event_tx, waker_rx)}); - - Ok(Self {waker_tx, waker_thread}) - } - - fn add_alarm(&mut self, at_time: DateTime){ - self.waker_tx.send(WakerMessage::AddAlarm(at_time)); - } - fn remove_alarm(&mut self, at_time: DateTime){ - self.waker_tx.send(WakerMessage::RemoveAlarm(at_time)); - } -} - -impl AlarmList { - - fn load() -> Result { - let path = Path::new("alarms.yaml"); - - let mut file; - let memory; - if path.exists() { - file = File::open(path)?; - memory = serde_yaml::from_reader(&mut file)? - } else { - file = File::create(path)?; - memory = BTreeSet::new(); - } - Ok(Self {memory, file }) - } - - fn add_alarm(&mut self, at_time: DateTime) { - self.memory.insert(at_time); - self.file.set_len(0); //truncate file - serde_yaml::to_writer(&mut self.file, &self.memory); - } - fn remove_alarm(&mut self, at_time: &DateTime) { - self.memory.remove(at_time); - self.file.set_len(0); //truncate file - serde_yaml::to_writer(&mut self.file, &self.memory); - } - - /// calculate time to the earliest alarm, remove it from the list if the current time is later - /// then the alarm - fn get_next_alarm(&mut self) -> Option> { - let now = Utc::now(); - - loop { - let next_alarm = self.memory.iter().cloned().next(); - if let Some(alarm) = next_alarm { - if alarm > now { - return Some(alarm.clone()); - } else { - self.remove_alarm(&alarm); - } - } else { - return None; - } - } - } -} \ No newline at end of file diff --git a/src/input/attached_sensors/bme280.rs b/src/input/attached_sensors/bme280.rs deleted file mode 100644 index ca3744b8..00000000 --- a/src/input/attached_sensors/bme280.rs +++ /dev/null @@ -1,24 +0,0 @@ -extern crate linux_embedded_hal as hal; -extern crate bme280; - -use hal::{Delay, I2cdev}; -use bme280::BME280; - -pub fn init() -> BME280 { - // using Linux I2C Bus #1 in this example - let i2c_bus = I2cdev::new("/dev/i2c-1").unwrap(); - // initialize the BME280 using the primary I2C address 0x77 - let mut bme280 = BME280::new_primary(i2c_bus, Delay); - // initialize the sensor - bme280.init().unwrap(); - bme280 -} - -pub fn measure_and_record(bme: &mut BME280 ) -> (f32, f32, f32) { - // measure temperature, pressure, and humidity - dbg!(""); - let measurements = bme.measure().unwrap(); - - (measurements.humidity, measurements.temperature, measurements.pressure) -} - diff --git a/src/input/attached_sensors/buttons.rs b/src/input/attached_sensors/buttons.rs deleted file mode 100644 index 83dd2ad9..00000000 --- a/src/input/attached_sensors/buttons.rs +++ /dev/null @@ -1,58 +0,0 @@ -extern crate sysfs_gpio; -extern crate futures; -extern crate tokio; - -use futures::{Future, lazy, Stream}; -use sysfs_gpio::{Direction, Edge, Pin}; -use std::sync::mpsc::Sender; -use std::thread; -use std::time::{Duration, Instant}; - -use crate::controller::{Command, Event}; - -// when pressing 22, 24 is often activated -// 23 works perfectly -// 24 also works perfectly - -fn stream(mut pin_numb_command_pairs: Vec<(u64, Command)>, tx: Sender) -> sysfs_gpio::Result<()> { - // NOTE: this currently runs forever and as such if - // the app is stopped (Ctrl-C), no cleanup will happen - // and the GPIO will be left exported. Not much - // can be done about this as Rust signal handling isn't - // really present at the moment. Revisit later. - let task = lazy(move || { - for (pin_numb, command) in pin_numb_command_pairs.drain(..) { - let mut last_press = Instant::now(); - let pin = Pin::new(pin_numb); - pin.export().unwrap(); - pin.set_direction(Direction::In).unwrap(); - pin.set_edge(Edge::RisingEdge).unwrap(); - let tx = tx.clone(); - tokio::spawn(pin.get_value_stream().unwrap() - .for_each(move |val| { //TODO refactor - if val == 1 { - if last_press.elapsed() > Duration::from_millis(50) { - last_press = Instant::now(); - dbg!(pin_numb); - dbg!(val); - tx.send(Event::Command(command.clone())); - } - } - Ok(()) - }) - .map_err(|_| ())); - } - Ok(()) - }); - tokio::run(task); - Ok(()) -} - -pub fn start(tx: Sender) { - thread::spawn(move || { - let pin_numb_command_pairs = vec!((22, Command::LampsDim), - (23, Command::LampsDimmest), - (24, Command::LampsToggle)); //BCM pin number - stream(pin_numb_command_pairs, tx).unwrap(); - }); -} diff --git a/src/input/attached_sensors/mod.rs b/src/input/attached_sensors/mod.rs deleted file mode 100644 index 0e67cdc8..00000000 --- a/src/input/attached_sensors/mod.rs +++ /dev/null @@ -1,119 +0,0 @@ -extern crate dataserver; -extern crate chrono; -extern crate smallvec; -extern crate bytes; - -use bytes::Bytes; -use dataserver::{httpserver, httpserver::timeseries_interface, httpserver::DataRouterHandle}; -use timeseries_interface::specifications::{MetaDataSpec, FieldSpec, FieldLength, FieldResolution}; -use self::chrono::{Utc}; - -mod buttons; -mod bme280; - -use std::thread; -use std::time::{Duration}; -use std::sync::{RwLock, Arc}; - -use std::sync::mpsc::Sender; -use crate::controller::{Command, Event}; - -const LOCAL_SENSING_ID: timeseries_interface::DatasetId = 0; -//TODO mechanisme for shutdown -pub fn start_monitoring(tx: Sender, data_router_handle: DataRouterHandle, dataset_handle: Arc>) { - - buttons::start(tx.clone()); - - //load the requird dataset - let data = dataset_handle.read().unwrap(); - let dataset = data.sets.get(&LOCAL_SENSING_ID).expect("dataset for local sensors is missing"); - let fields = dataset.metadata.fields.clone(); - drop(data); - - //init all sensors - let mut bme = bme280::init(); - - thread::spawn(move || {//TODO figure out shutdown behaviour - - loop { - //get all measurements - let (humidity, temperature, pressure) = bme280::measure_and_record(&mut bme); - - //init new slow measurements - //TODO - let now = Utc::now(); - - //process data into events and send off as event - //TODO - - //encode all data - //dbg!(fields); - let mut line: Vec = vec!(0;64); - - dbg!(&humidity); - dbg!(&temperature); - dbg!(&pressure); - - fields[0].encode::(humidity, &mut line); - fields[1].encode::(temperature, &mut line); - fields[2].encode::(pressure, &mut line); - //store data and send to active web_clients - dataserver::httpserver::signal_newdata(&data_router_handle, LOCAL_SENSING_ID, line.clone(), now.timestamp() ); - let mut data = dataset_handle.write().unwrap(); - let set = data.sets.get_mut(&LOCAL_SENSING_ID).unwrap(); - set.timeseries.append(now, &line).unwrap(); - //dbg!(&line); - drop(data); - - //sleep until 5 seconds are completed - thread::sleep(Duration::from_secs(5)); - } - }); -} - -fn make_local_sensing_spec() -> MetaDataSpec { - let humidity_desk = FieldSpec::BitLength( FieldLength { - name: String::from("humidity below desk"), - min_value: 0.0f32, - max_value: 100f32, - numb_of_bits: 10u8, //bits (max 32 bit variables) - }); - let temperature_desk = FieldSpec::Resolution( FieldResolution { - name: String::from("temperature below desk"), - min_value: -20f32, - max_value: 60f32, - resolution: 0.05f32, //bits (max 32 bit variables) - }); - let pressure_desk = FieldSpec::Resolution( FieldResolution { - name: String::from("pressure below desk"), - min_value: 100_000f32-50_000f32, - max_value: 100_000f32+50_000f32, - resolution: 0.1f32, - }); - - MetaDataSpec { - name: String::from("home automation sensors"), - description: String::from("Data from homeautomation sensors"), - fields: vec!(humidity_desk, temperature_desk, pressure_desk), - } -} - -pub fn check_local_sensing_dataset(data: &Arc>) -> Result<(),()>{ - let mut data = data.write().unwrap(); - if let Some(dataset) = data.sets.get(&LOCAL_SENSING_ID){ - //check if name is right - if dataset.metadata.name == "home automation sensors" { - info!("loaded home automation data set"); - Ok(()) - } else { - error!("No existing home automation dataset, cant create one without overwriting, dataset id already taken by dataset: {}",dataset.metadata.name); - Err(()) - } - } else { - //TODO write specification that we can use - let spec = make_local_sensing_spec(); - data.add_specific_set(spec); - info!("created home automation dataset"); - Ok(()) - } -} diff --git a/src/input/mod.rs b/src/input/mod.rs deleted file mode 100644 index 17d7caff..00000000 --- a/src/input/mod.rs +++ /dev/null @@ -1,3 +0,0 @@ -pub mod web_api; -pub mod attached_sensors; -pub mod alarms; \ No newline at end of file diff --git a/src/input/web_api/command_logins.rs b/src/input/web_api/command_logins.rs deleted file mode 100644 index 0e0445f1..00000000 --- a/src/input/web_api/command_logins.rs +++ /dev/null @@ -1,9 +0,0 @@ -pub struct CompileTimeLogin { - pub username: &'static str, - pub password: &'static str, -} - -pub const LIST: [CompileTimeLogin; 2] = [ - CompileTimeLogin {username: "eva", password: "superbabje"}, - CompileTimeLogin {username: "david", password: "12481632"}, -]; diff --git a/src/input/web_api/mod.rs b/src/input/web_api/mod.rs deleted file mode 100644 index fc88b242..00000000 --- a/src/input/web_api/mod.rs +++ /dev/null @@ -1,102 +0,0 @@ -extern crate actix_web_httpauth; -use actix_web::FromRequest; -use actix_web_httpauth::extractors::basic::{BasicAuth, Config}; -use actix_web_httpauth::headers::www_authenticate::basic::Basic; -use actix_web_httpauth::headers::www_authenticate::{WWWAuthenticate}; -use actix_web::http::StatusCode; - -use crate::ServerState; -use crate::actix_web::{HttpResponse, HttpRequest}; -use crate::controller::{Command, TargetState, Event}; - - -mod command_logins; - -fn authenticated(req: &HttpRequest) -> bool { - let mut config = Config::default(); - config.realm("Restricted area"); - - if let Ok(auth) = BasicAuth::from_request(&req, &config){ - let username = auth.username(); - if let Some(password) = auth.password(){ - command_logins::LIST.into_iter() - .filter(|x| x.username==username) - .filter(|x| x.password==password) - .next().is_some() - } else {false } - } else {false } -} - -fn make_auth_error(req: &HttpRequest) -> HttpResponse { - let challenge = Basic {realm: Some("Restricted area".to_string()),}; - req.build_response(StatusCode::UNAUTHORIZED) - .set(WWWAuthenticate(challenge)) - .finish() -} - -///////////////////// lamp commands /////////////////////////////// - -pub fn toggle(req: &HttpRequest) -> HttpResponse { - if authenticated(req) { - req.state().controller_addr.send(Event::Command(Command::LampsToggle)).unwrap(); - HttpResponse::Ok().finish() - } else { - make_auth_error(req) - } -} - -pub fn dim(req: &HttpRequest) -> HttpResponse { - if authenticated(req) { - req.state().controller_addr.send(Event::Command(Command::LampsDim)).unwrap(); - HttpResponse::Ok().finish() - } else { - make_auth_error(req) - } -} - -pub fn dimmest(req: &HttpRequest) -> HttpResponse { - if authenticated(req) { - req.state().controller_addr.send(Event::Command(Command::LampsDimmest)).unwrap(); - HttpResponse::Ok().finish() - } else { - make_auth_error(req) - } -} - -pub fn normal(req: &HttpRequest) -> HttpResponse { - if authenticated(req) { - req.state().controller_addr.send(Event::Command(Command::LampsDay)).unwrap(); - HttpResponse::Ok().finish() - } else { - make_auth_error(req) - } -} - -pub fn evening(req: &HttpRequest) -> HttpResponse { - if authenticated(req) { - req.state().controller_addr.send(Event::Command(Command::LampsEvening)).unwrap(); - HttpResponse::Ok().finish() - } else { - make_auth_error(req) - } -} - -pub fn night(req: &HttpRequest) -> HttpResponse { - if authenticated(req) { - req.state().controller_addr.send(Event::Command(Command::LampsNight)).unwrap(); - HttpResponse::Ok().finish() - } else { - make_auth_error(req) - } -} - -//////////////////////// go to state commands ///////////////////////////////// - -pub fn lightloop(req: &HttpRequest) -> HttpResponse { - if authenticated(req) { - req.state().controller_addr.send(Event::Command(Command::ChangeState(TargetState::LightLoop))).unwrap(); - HttpResponse::Ok().finish() - } else { - make_auth_error(req) - } -} \ No newline at end of file diff --git a/src/main.rs b/src/main.rs deleted file mode 100644 index 8e34d4bb..00000000 --- a/src/main.rs +++ /dev/null @@ -1,172 +0,0 @@ -extern crate dataserver; -extern crate actix_web; -#[macro_use] -extern crate log; - -use crate::actix_web::actix::Arbiter; -use crate::actix_web::{server,App,http::Method}; -use crate::actix_web::middleware::identity::{CookieIdentityPolicy, IdentityService}; - -use std::sync::mpsc; -use std::sync::atomic::{AtomicUsize}; -use std::thread; - -use dataserver::{certificate_manager, httpserver}; -use dataserver::helper; -use dataserver::httpserver::{secure_database::PasswordDatabase, timeseries_interface, ServerHandle, DataRouterHandle, CheckLogin}; -use dataserver::httpserver::{ws_index, index, logout, newdata, plot_data, list_data, login_get_and_check, login_page, serve_file}; -use dataserver::httpserver::{InnerState, DataServerState}; - -use std::sync::{Arc, RwLock}; -use std::io::stdin; -use std::collections::HashMap; - -mod controller; -use controller::Event; - -mod input; -use input::web_api; - -pub struct ServerState { - controller_addr: mpsc::Sender, - dataserver_state: DataServerState, -} - -impl InnerState for ServerState { - fn inner_state(&self) -> &DataServerState { - &self.dataserver_state - } -} - -const FORCE_CERT_REGEN: bool = false; - -pub fn start(signed_cert: &str, private_key: &str, - data: Arc>, - passw_db: Arc>, - sessions: Arc>>, - controller_tx: mpsc::Sender) -> (DataRouterHandle, ServerHandle) { - - let tls_config = httpserver::make_tls_config(signed_cert, private_key); - let cookie_key = httpserver::make_random_cookie_key(); - - let free_session_ids = Arc::new(AtomicUsize::new(0)); - let free_ws_session_ids = Arc::new(AtomicUsize::new(0)); - - let (tx, rx) = mpsc::channel(); - thread::spawn(move || { - // Start data server actor in separate thread - let sys = actix::System::new("http-server"); - let data_server = Arbiter::start(|_| httpserver::websocket_data_router::DataServer::default()); - let data_server_clone = data_server.clone(); - - let web_server = server::new(move || { - // data the webservers functions have access to - let dataserver_state = DataServerState { - passw_db: passw_db.clone(), - websocket_addr: data_server_clone.clone(), - data: data.clone(), - sessions: sessions.clone(), - free_session_ids: free_session_ids.clone(), - free_ws_session_ids: free_ws_session_ids.clone(), - }; - let state = ServerState { - controller_addr: controller_tx.clone(), - dataserver_state, - }; - - App::with_state(state) - .middleware(IdentityService::new( - CookieIdentityPolicy::new(&cookie_key[..]) - .domain("deviousd.duckdns.org") - .name("auth-cookie") - .path("/") - .secure(true), - )) - .middleware(CheckLogin{ - public_roots: vec!(String::from("/commands")), - ..CheckLogin::default() - }) - // homeautomation actions activated by https calls - .resource(r"/commands/lamps/toggle", |r| r.method(Method::GET).f(web_api::toggle)) - .resource(r"/commands/lamps/evening", |r| r.method(Method::GET).f(web_api::evening)) - .resource(r"/commands/lamps/night", |r| r.method(Method::GET).f(web_api::night)) - .resource(r"/commands/lamps/day", |r| r.method(Method::GET).f(web_api::normal)) - .resource(r"/commands/lamps/dimmest", |r| r.method(Method::GET).f(web_api::dimmest)) - .resource(r"/commands/lamps/dim", |r| r.method(Method::GET).f(web_api::dim)) - // websocket route - // note some browsers need already existing http connection to - // this server for the upgrade to wss to work - .resource("/", |r| r.f(index)) - .resource("/ws/", |r| r.method(Method::GET).f(ws_index)) - .resource("/logout", |r| r.f(logout)) - .resource(r"/newdata", |r| r.method(Method::POST).f(newdata)) - .resource("/plot", |r| r.f(plot_data)) - .resource(r"/list_data.html", |r| r.method(Method::GET).f(list_data)) - - //login route, every uri starting "/login" will be forwarded to the adress - //after "/login" once the client has been authenticated - .resource(r"/login/{tail:.*}", |r| { - r.method(Method::POST).with(login_get_and_check); - r.method(Method::GET).f(login_page); - }) - //for all other urls we try to resolve to static files in the "web" dir - .resource(r"/{tail:.*}", |r| r.f(serve_file)) - }) - .bind_rustls("0.0.0.0:8080", tls_config).unwrap() - //.bind("0.0.0.0:8080").unwrap() //without tcp use with debugging (note: https -> http, wss -> ws) - .shutdown_timeout(5) // shut down 5 seconds after getting the signal to shut down - .start(); - - let _ = tx.send((data_server, web_server)); - let _ = sys.run(); - }); - - let (data_handle, web_handle) = rx.recv().unwrap(); - (data_handle, web_handle) -} - -fn main() { - //https://www.deviousd.duckdns.org:8080/index.html - //only do if certs need update - if FORCE_CERT_REGEN { - //generate_and_sign_keys - if let Err(error) = certificate_manager::generate_and_sign_keys( - "deviousd.duckdns.org", - "keys/cert.key", - "keys/cert.cert", - "keys/user.key", - ) { - println!("could not auto generate certificate, error: {:?}", error) - } - } - - helper::setup_logging(2).expect("could not set up debugging"); - - let passw_db = Arc::new(RwLock::new(PasswordDatabase::load("").unwrap())); - let dataset_handle = Arc::new(RwLock::new(timeseries_interface::init("data").unwrap())); - let sessions = Arc::new(RwLock::new(HashMap::new())); - let (controller_tx, controller_rx) = mpsc::channel(); - - let (data_router_handle, web_handle) = //starts webserver - start("keys/cert.key", "keys/cert.cert", dataset_handle.clone(), passw_db.clone(), sessions.clone(), controller_tx.clone()); - - controller::start(controller_rx).unwrap(); - input::attached_sensors::start_monitoring(controller_tx.clone(), data_router_handle, dataset_handle.clone()); - - println!("press: t to send test data, n: to add a new user, q to quit, a to add new dataset"); - loop { - let mut input = String::new(); - stdin().read_line(&mut input).unwrap(); - match input.as_str() { - "t\n" => helper::send_test_data(dataset_handle.clone()), - //"x\n" => httpserver::signal_newdata(data_handle.clone(),0), - "n\n" => helper::add_user(& passw_db), - "a\n" => helper::add_dataset(&passw_db, &dataset_handle), - "q\n" => break, - _ => println!("unhandled"), - }; - } - println!("shutting down"); - httpserver::stop(web_handle); - controller_tx.send(Event::Stop); -}