3 Commits
Author SHA1 Message Date
rhetenor 4d9cd05f72 fix wokwi wifi 2026-09-02 20:31:37 +02:00
rhetenor 240e2b081d rewrite wifi crate 2026-09-02 20:11:40 +02:00
rhetenor 0aa1370a2b rework card storage to use nvs 2026-08-31 20:16:42 +02:00
11 changed files with 435 additions and 381 deletions
Generated
+92 -111
View File
@@ -34,9 +34,9 @@ dependencies = [
[[package]] [[package]]
name = "aho-corasick" name = "aho-corasick"
version = "1.1.4" version = "1.1.5"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ddd31a130427c27518df266943a5308ed92d4b226cc639f5a8f1002816174301" checksum = "c982642fa9e8606056828ee9a8505737230110bb1099153c79efe865c59d12ba"
dependencies = [ dependencies = [
"memchr", "memchr",
] ]
@@ -71,12 +71,6 @@ version = "1.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7b7e4c2464d97fe331d41de9d5db0def0a96f4d823b8b32a2efd503578988973" checksum = "7b7e4c2464d97fe331d41de9d5db0def0a96f4d823b8b32a2efd503578988973"
[[package]]
name = "base64"
version = "0.13.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9e1b586273c5702936fe7b7d6896644d8be71e6314cfe09d3167c95f712589e8"
[[package]] [[package]]
name = "base64" name = "base64"
version = "0.23.1" version = "0.23.1"
@@ -148,7 +142,7 @@ checksum = "c0cb6f3d4773a2107b94cbeccaa5b5f0b35a88389b5d522d13d659f64317b22d"
dependencies = [ dependencies = [
"proc-macro2", "proc-macro2",
"quote", "quote",
"syn 3.0.3", "syn 3.0.4",
] ]
[[package]] [[package]]
@@ -250,9 +244,9 @@ dependencies = [
[[package]] [[package]]
name = "cc" name = "cc"
version = "1.4.0" version = "1.4.4"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5add81bb678e6cb321aff7fa0dc7689ad82b112dbc032cea19f91d6b8e3582b9" checksum = "0ad534f4357a5264cce5019c989cf66a4f0dc4e0d1b1d15f8aacec0ff7360273"
dependencies = [ dependencies = [
"find-msvc-tools", "find-msvc-tools",
"shlex", "shlex",
@@ -320,9 +314,9 @@ dependencies = [
[[package]] [[package]]
name = "cordyceps" name = "cordyceps"
version = "0.3.4" version = "0.3.5"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "688d7fbb8092b8de775ef2536f36c8c31f2bc4006ece2e8d8ad2d17d00ce0a2a" checksum = "5b9ab7e0ca1d179628fa0172b2b97203c7fa0cd81be2448bd446fb9559ca9261"
dependencies = [ dependencies = [
"loom", "loom",
"tracing", "tracing",
@@ -336,9 +330,9 @@ checksum = "417bef24afe1460300965a25ff4a24b8b45ad011948302ec221e8a0a81eb2c79"
[[package]] [[package]]
name = "crc32fast" name = "crc32fast"
version = "1.5.0" version = "1.5.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9481c1c90cbf2ac953f07c8d4a58aa3945c425b7185c9154d67a65e4230da511" checksum = "8498c871161e1742aaa9d52551b2d6ebdd4c3d45a3be423e3728f33b955be550"
dependencies = [ dependencies = [
"cfg-if", "cfg-if",
] ]
@@ -347,14 +341,14 @@ dependencies = [
name = "creaturedex" name = "creaturedex"
version = "0.1.0" version = "0.1.0"
dependencies = [ dependencies = [
"base64 0.23.1", "base64",
"binary_serde", "binary_serde",
"ch1115", "ch1115",
"critical-section", "critical-section",
"display-interface-spi", "display-interface-spi",
"embassy-executor", "embassy-executor",
"embassy-futures", "embassy-futures",
"embassy-sync 0.8.0", "embassy-sync 0.7.2",
"embassy-time", "embassy-time",
"embedded-graphics", "embedded-graphics",
"embedded-graphics-core", "embedded-graphics-core",
@@ -475,12 +469,12 @@ dependencies = [
[[package]] [[package]]
name = "darling" name = "darling"
version = "0.23.0" version = "0.24.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "25ae13da2f202d56bd7f91c25fba009e7717a1e4a1cc98a76d844b65ae912e9d" checksum = "ed17f5901b6630b993ca003def43f2f8ef4014fc13b047b57aad617ff32bc2ec"
dependencies = [ dependencies = [
"darling_core 0.23.0", "darling_core 0.24.1",
"darling_macro 0.23.0", "darling_macro 0.24.1",
] ]
[[package]] [[package]]
@@ -512,15 +506,15 @@ dependencies = [
[[package]] [[package]]
name = "darling_core" name = "darling_core"
version = "0.23.0" version = "0.24.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9865a50f7c335f53564bb694ef660825eb8610e0a53d3e11bf1b0d3df31e03b0" checksum = "6837e2cf7485aaae18f86181d2f0e9a7ed297a025e220aeabf63fdebd3a2ddff"
dependencies = [ dependencies = [
"ident_case", "ident_case",
"proc-macro2", "proc-macro2",
"quote", "quote",
"strsim", "strsim",
"syn 2.0.119", "syn 3.0.4",
] ]
[[package]] [[package]]
@@ -547,13 +541,13 @@ dependencies = [
[[package]] [[package]]
name = "darling_macro" name = "darling_macro"
version = "0.23.0" version = "0.24.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ac3984ec7bd6cfa798e62b4a642426a5be0e68f9401cfc2a01e3fa9ea2fcdb8d" checksum = "2ac7135c3ef02b2f7833bbeb1be5ba7f966dcde8a87c6b87f65a778d71a02785"
dependencies = [ dependencies = [
"darling_core 0.23.0", "darling_core 0.24.1",
"quote", "quote",
"syn 2.0.119", "syn 3.0.4",
] ]
[[package]] [[package]]
@@ -571,9 +565,9 @@ dependencies = [
[[package]] [[package]]
name = "data-encoding" name = "data-encoding"
version = "2.11.0" version = "2.11.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a4ae5f15dda3c708c0ade84bfee31ccab44a3da4f88015ed22f63732abe300c8" checksum = "4583a4551df46e2792f82ceeac45e850d2e2d5debba0b91f102385cda5b11f06"
[[package]] [[package]]
name = "data-url" name = "data-url"
@@ -724,9 +718,9 @@ checksum = "466dfce9c2172a4e947b81b556f1f07a86029fbac679e323cfb66c738cc2faea"
[[package]] [[package]]
name = "either" name = "either"
version = "1.17.0" version = "1.18.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9e5e8f6c15a24b9a3ee5efec809ccd006d3b30e8b3bb63c39af737c7f87daa1d" checksum = "252afb9ae5eaa683babdc6a068b3f5726eb19e05070c731f9b2a23a7c3e8ed34"
[[package]] [[package]]
name = "embassy-embedded-hal" name = "embassy-embedded-hal"
@@ -1138,9 +1132,9 @@ dependencies = [
[[package]] [[package]]
name = "esp-hal" name = "esp-hal"
version = "1.1.1" version = "1.1.2"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2bfcf2a0842903717f4663f6a08512c32b0f6b2d7fb7db3c8a6895d2e6d49f72" checksum = "9e2874462a2a0faca8b6318a10b0db87d2b7cd74dded82b3dfd780c07a319038"
dependencies = [ dependencies = [
"bitfield 0.19.5", "bitfield 0.19.5",
"bitflags 2.13.1", "bitflags 2.13.1",
@@ -1237,7 +1231,7 @@ dependencies = [
[[package]] [[package]]
name = "esp-hal-wifimanager" name = "esp-hal-wifimanager"
version = "0.3.1" version = "0.3.1"
source = "git+https://github.com/InvisibleUSA/esp-hal-wifimanager#49050fdf44e9c2e1ec0be02b01301422c737519c" source = "git+https://github.com/rhetenor/esp-hal-wifimanager.git#c35c2b35c9c4b724138f2c62a8aed9adf6365a7f"
dependencies = [ dependencies = [
"embassy-executor", "embassy-executor",
"embassy-futures", "embassy-futures",
@@ -1531,18 +1525,19 @@ checksum = "da7c62ceae207dd37ea5b845da6a0696c799f85e97da1ab5b7910be3c1c80223"
[[package]] [[package]]
name = "find-msvc-tools" name = "find-msvc-tools"
version = "0.1.9" version = "0.1.11"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5baebc0774151f905a1a2cc41989300b1e6fbb29aff0ceffa1064fdd3088d582" checksum = "d45db016d36b838f563236e9193d0ee6ce38f3f68b6c94e914b4929c96bbb890"
[[package]] [[package]]
name = "flate2" name = "flate2"
version = "1.1.9" version = "1.1.10"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "843fba2746e448b37e26a819579957415c8cef339bf08564fe8b7ddbd959573c" checksum = "6e634e2e0ebac1ee034020da1ca582e17ffe4e0f5e985823721e168928136dcb"
dependencies = [ dependencies = [
"crc32fast", "crc32fast",
"miniz_oxide", "miniz_oxide",
"zlib-rs",
] ]
[[package]] [[package]]
@@ -1766,9 +1761,9 @@ dependencies = [
[[package]] [[package]]
name = "indexmap" name = "indexmap"
version = "2.14.0" version = "2.14.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d466e9454f08e4a911e14806c24e16fba1b4c121d1ea474396f396069cf949d9" checksum = "07aa2048142242915a31d35844fb311e0e53fcca590c3a0a40dcf1b841fa09eb"
dependencies = [ dependencies = [
"equivalent", "equivalent",
"hashbrown 0.17.1", "hashbrown 0.17.1",
@@ -1787,15 +1782,15 @@ dependencies = [
[[package]] [[package]]
name = "instability" name = "instability"
version = "0.3.12" version = "0.3.13"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5eb2d60ef19920a3a9193c3e371f726ec1dafc045dac788d0fb3704272458971" checksum = "2bf84e73fa6f27f299dec58e13223cf70db80da872eb921d4f6138342a0eabc8"
dependencies = [ dependencies = [
"darling 0.23.0", "darling 0.24.1",
"indoc", "indoc",
"proc-macro2", "proc-macro2",
"quote", "quote",
"syn 2.0.119", "syn 3.0.4",
] ]
[[package]] [[package]]
@@ -1860,9 +1855,9 @@ dependencies = [
[[package]] [[package]]
name = "js-sys" name = "js-sys"
version = "0.3.103" version = "0.3.104"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "53b44bfcdb3f8d5837a46dae1ca9660a837176eee74a28b229bc626816589102" checksum = "0e0c1080212aad755ea003d18543e8768dd432c48819efd73a7bf1e39b7a5a3a"
dependencies = [ dependencies = [
"cfg-if", "cfg-if",
"futures-util", "futures-util",
@@ -1950,9 +1945,9 @@ dependencies = [
[[package]] [[package]]
name = "log" name = "log"
version = "0.4.33" version = "0.4.34"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0ceec5bc11778974d1bcb055b18002eba7f4b3518b6a0081b3af5f21666da9ad" checksum = "f9f8bd3e56ce4dfc153cf470fffbfa98c7620958b312ca5c3a4b8d5181fd13c6"
[[package]] [[package]]
name = "loom" name = "loom"
@@ -2036,9 +2031,9 @@ dependencies = [
[[package]] [[package]]
name = "miniz_oxide" name = "miniz_oxide"
version = "0.8.9" version = "0.9.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1fa76a2c86f704bdb222d66965fb3d63269ce38518b83cb0575fca855ebb6316" checksum = "b63fbc4a50860e98e7b2aa7804ded1db5cbc3aff9193adaff57a6931bf7c4b4c"
dependencies = [ dependencies = [
"adler2", "adler2",
"simd-adler32", "simd-adler32",
@@ -2097,9 +2092,9 @@ dependencies = [
[[package]] [[package]]
name = "num-integer" name = "num-integer"
version = "0.1.46" version = "0.1.47"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7969661fd2958a5cb096e56c8e1ad0444ac2bbcd0061bd28660485a44879858f" checksum = "7ce2d95d4b3734dc35aa2f45e1aa22cd416814592a4f9d9205e11affd5b8e10b"
dependencies = [ dependencies = [
"num-traits", "num-traits",
] ]
@@ -2169,9 +2164,9 @@ checksum = "1a80800c0488c3a21695ea981a54918fbb37abf04f4d0720c453632255e2ff0e"
[[package]] [[package]]
name = "owo-colors" name = "owo-colors"
version = "4.3.0" version = "4.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d211803b9b6b570f68772237e415a029d5a50c65d382910b879fb19d3271f94d" checksum = "13c45bb4a6ae1280ec0803b1ef9d3455eb50f01efbbe1447ab020f1d54fba9d8"
[[package]] [[package]]
name = "oxc-browserslist" name = "oxc-browserslist"
@@ -2199,7 +2194,7 @@ dependencies = [
"textwrap", "textwrap",
"thiserror", "thiserror",
"unicode-segmentation", "unicode-segmentation",
"unicode-width 0.2.2", "unicode-width",
] ]
[[package]] [[package]]
@@ -2681,9 +2676,9 @@ dependencies = [
[[package]] [[package]]
name = "portable-atomic" name = "portable-atomic"
version = "1.14.0" version = "1.15.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3d20d5497ef88037a52ff98267d066e7f11fcc5e99bbfbd58a42336193aacec3" checksum = "05c8b63e8d9609db387f0324918f81d68fe27748f084ef092fb35954d0539a85"
[[package]] [[package]]
name = "portable-atomic-util" name = "portable-atomic-util"
@@ -2800,9 +2795,9 @@ checksum = "46b71a9d9206e8b46714c74255adcaea8b11e0350c1d8456165073c3f75fc81a"
[[package]] [[package]]
name = "rand" name = "rand"
version = "0.8.7" version = "0.8.8"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "22f6172bdec972074665ed81ed53b71da00bfc44b65a753cfde883ec4c702a1a" checksum = "e058c7de0b26af77780c769414d6257830bb240f3c38477dbc2c16e5f54d6d4c"
dependencies = [ dependencies = [
"rand_core 0.6.4", "rand_core 0.6.4",
] ]
@@ -2865,9 +2860,9 @@ dependencies = [
[[package]] [[package]]
name = "regex-automata" name = "regex-automata"
version = "0.4.16" version = "0.4.18"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8fcfdb36bda0c880c5931cdc7a2bcdc8ba4556847b9d912bca70bc94708711ad" checksum = "ad8553b9b26413251cbf30e620595c7a41b3887f03da04579c0e6b0d6a06b4b2"
dependencies = [ dependencies = [
"aho-corasick", "aho-corasick",
"memchr", "memchr",
@@ -2979,15 +2974,14 @@ dependencies = [
[[package]] [[package]]
name = "rlsf" name = "rlsf"
version = "0.2.2" version = "0.2.3"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1646a59a9734b8b7a0ac51689388a60fe1625d4b956348e9de07591a1478457a" checksum = "07393724337be2ee43a9d86164df4505746874a3fa65913374bc6d6a92314362"
dependencies = [ dependencies = [
"cfg-if", "cfg-if",
"const-default", "const-default",
"libc", "libc",
"rustversion", "rustversion",
"svgbobdoc",
] ]
[[package]] [[package]]
@@ -3074,7 +3068,7 @@ checksum = "e7a5d71263a5a7d47b41f6b3f06ba276f10cc18b0931f1799f710578e2309348"
dependencies = [ dependencies = [
"proc-macro2", "proc-macro2",
"quote", "quote",
"syn 3.0.3", "syn 3.0.4",
] ]
[[package]] [[package]]
@@ -3153,9 +3147,9 @@ checksum = "0c790de23124f9ab44544d7ac05d60440adc586479ce501c1d6d7da3cd8c9cf5"
[[package]] [[package]]
name = "smallvec" name = "smallvec"
version = "1.15.2" version = "1.16.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8ed6a63f02c8539c91a8685a86f4099661ba3da017932f6ebbea6de3f0fa7c90" checksum = "b9be42f50aa861c555654aa3a37f52f4b1074bacf4e48fe0ef7fa584e80f1f0f"
[[package]] [[package]]
name = "smawk" name = "smawk"
@@ -3239,19 +3233,6 @@ dependencies = [
"syn 2.0.119", "syn 2.0.119",
] ]
[[package]]
name = "svgbobdoc"
version = "0.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f2c04b93fc15d79b39c63218f15e3fdffaa4c227830686e3b7c5f41244eb3e50"
dependencies = [
"base64 0.13.1",
"proc-macro2",
"quote",
"syn 1.0.109",
"unicode-width 0.1.14",
]
[[package]] [[package]]
name = "syn" name = "syn"
version = "1.0.109" version = "1.0.109"
@@ -3276,9 +3257,9 @@ dependencies = [
[[package]] [[package]]
name = "syn" name = "syn"
version = "3.0.3" version = "3.0.4"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "53e9bae58849f64dfa4f5d5ae372c8341f7305f82a3868709269343628b659a3" checksum = "e6275cddf4610d1775e6d1fe9469b2e77d0f39fd98fb7450901b821e0c53649f"
dependencies = [ dependencies = [
"proc-macro2", "proc-macro2",
"quote", "quote",
@@ -3308,27 +3289,27 @@ checksum = "c13547615a44dc9c452a8a534638acdf07120d4b6847c8178705da06306a3057"
dependencies = [ dependencies = [
"smawk", "smawk",
"unicode-linebreak", "unicode-linebreak",
"unicode-width 0.2.2", "unicode-width",
] ]
[[package]] [[package]]
name = "thiserror" name = "thiserror"
version = "2.0.19" version = "2.0.20"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "09a43598840e33d5b0331f38c5e30d13bb11c11210a4b58f0d9b18a5a5eefcd9" checksum = "ec86235f5fcc2a73650310756d2ac5b138a5780bbbdfae3eeccec992c435ba4f"
dependencies = [ dependencies = [
"thiserror-impl", "thiserror-impl",
] ]
[[package]] [[package]]
name = "thiserror-impl" name = "thiserror-impl"
version = "2.0.19" version = "2.0.20"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "43cbfe0cf76104d42a574802844187e84a305e531ed54455f11fbde0f10541cd" checksum = "bc04cd3e1236dd4a98afca4569f2deb3f120e5422a4023be2cb683f8486292af"
dependencies = [ dependencies = [
"proc-macro2", "proc-macro2",
"quote", "quote",
"syn 3.0.3", "syn 3.0.4",
] ]
[[package]] [[package]]
@@ -3398,9 +3379,9 @@ dependencies = [
[[package]] [[package]]
name = "toml_parser" name = "toml_parser"
version = "1.1.2+spec-1.1.0" version = "1.1.3+spec-1.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a2abe9b86193656635d2411dc43050282ca48aa31c2451210f4202550afb7526" checksum = "1d38ac1cf9b95face32296c0a3ede1fdc270627c9d9c02a7274dd6d960dc4d56"
dependencies = [ dependencies = [
"winnow", "winnow",
] ]
@@ -3502,12 +3483,6 @@ version = "1.13.3"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c6f5d3c3b1bf09027a88a6bc961fc00497d651009560b5463668dc81b0fa87a8" checksum = "c6f5d3c3b1bf09027a88a6bc961fc00497d651009560b5463668dc81b0fa87a8"
[[package]]
name = "unicode-width"
version = "0.1.14"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7dd6e30e90baa6f72411720665d41d89b9a3d039dc45b8faea1ddd07f617f6af"
[[package]] [[package]]
name = "unicode-width" name = "unicode-width"
version = "0.2.2" version = "0.2.2"
@@ -3532,9 +3507,9 @@ dependencies = [
[[package]] [[package]]
name = "uuid" name = "uuid"
version = "1.24.0" version = "1.26.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bf3923a6f5c4c6382e0b653c4117f48d631ea17f38ed86e2a828e6f7412f5239" checksum = "b5772d71c9be8a8a6ac2117d949c5b224c1b72241bb611d9a3012edcf8af7812"
dependencies = [ dependencies = [
"js-sys", "js-sys",
"wasm-bindgen", "wasm-bindgen",
@@ -3593,9 +3568,9 @@ dependencies = [
[[package]] [[package]]
name = "wasm-bindgen" name = "wasm-bindgen"
version = "0.2.126" version = "0.2.127"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4b067c0c11094aef6b7a801c1e34a26affafdf3d051dba08456b868789aaf9a4" checksum = "1b70935747edd64d89de3efa29d73789b806c15798f8e7dca4d8ac356b50ce70"
dependencies = [ dependencies = [
"cfg-if", "cfg-if",
"once_cell", "once_cell",
@@ -3606,9 +3581,9 @@ dependencies = [
[[package]] [[package]]
name = "wasm-bindgen-macro" name = "wasm-bindgen-macro"
version = "0.2.126" version = "0.2.127"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "167ce5e579f6bcf889c4f7175a8a5a585de84e8ff93976ce393efa5f2837aab1" checksum = "77775f8f3f7217702089053b94958f8f54061a3f663417df76e19cbdcca29bc1"
dependencies = [ dependencies = [
"quote", "quote",
"wasm-bindgen-macro-support", "wasm-bindgen-macro-support",
@@ -3616,9 +3591,9 @@ dependencies = [
[[package]] [[package]]
name = "wasm-bindgen-macro-support" name = "wasm-bindgen-macro-support"
version = "0.2.126" version = "0.2.127"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f3997c7839262f4ef12cf90b818d6340c18e80f263f1a94bf157d0ec4420380e" checksum = "e11d33f857dc2fb11b8bc75aee111aa9cbeb12cd9f25efd3d4c2a3dd4e235284"
dependencies = [ dependencies = [
"bumpalo", "bumpalo",
"proc-macro2", "proc-macro2",
@@ -3629,9 +3604,9 @@ dependencies = [
[[package]] [[package]]
name = "wasm-bindgen-shared" name = "wasm-bindgen-shared"
version = "0.2.126" version = "0.2.127"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "dc1b4cb0cc549fcf58d7dfc081778139b3d283a081644e833e84682ad71cea24" checksum = "7ef64dbcc55df09c7e5a46182d181c2cfa3e925f3da937ea764728b4bbb9dcbf"
dependencies = [ dependencies = [
"unicode-ident", "unicode-ident",
] ]
@@ -3726,24 +3701,30 @@ dependencies = [
[[package]] [[package]]
name = "zerocopy" name = "zerocopy"
version = "0.8.55" version = "0.8.56"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b5a105cd7b140f6eeec8acff2ea38135d3cab283ada58540f629fe51e46696eb" checksum = "556764e583adb45a9f8d413c2a147fa7e8d821e48e12b14fd560b607998b75eb"
dependencies = [ dependencies = [
"zerocopy-derive", "zerocopy-derive",
] ]
[[package]] [[package]]
name = "zerocopy-derive" name = "zerocopy-derive"
version = "0.8.55" version = "0.8.56"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0fe976fb70c78cd64cccfe3a6fc142244e8a77b70959b30faf9d0ac37ee228eb" checksum = "f2ab42fc20575779bd240faa45f94a74256f755c0fa9e89f0ede20d91d0cdfc1"
dependencies = [ dependencies = [
"proc-macro2", "proc-macro2",
"quote", "quote",
"syn 2.0.119", "syn 2.0.119",
] ]
[[package]]
name = "zlib-rs"
version = "0.6.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "34b31d188d9d685a4f9c7b46d6e36631b07058d2cfe190267adce54dc230bf12"
[[package]] [[package]]
name = "zmij" name = "zmij"
version = "1.0.23" version = "1.0.23"
+2 -2
View File
@@ -32,7 +32,7 @@ embassy-executor = { version = "0.10.0", features = ["trace", "metadata-name"] }
embassy-time = { version = "0.5.1", default-features = false } embassy-time = { version = "0.5.1", default-features = false }
embassy-futures = "0.1.2" embassy-futures = "0.1.2"
esp-alloc = "0.10.0" esp-alloc = "0.10.0"
esp-hal-wifimanager = { git = "https://github.com/InvisibleUSA/esp-hal-wifimanager", default-features = false, features = [ esp-hal-wifimanager = { git = "https://github.com/rhetenor/esp-hal-wifimanager.git", default-features = false, features = [
"ap", "ap",
"esp32s3", "esp32s3",
] } ] }
@@ -46,7 +46,7 @@ embedded-graphics-core = "0.4.1"
base64 = { version = "0.23.1", default-features = false, features = ["alloc"] } base64 = { version = "0.23.1", default-features = false, features = ["alloc"] }
pn532 = "0.5.0" pn532 = "0.5.0"
num_enum = { version = "0.7.6", default-features = false } num_enum = { version = "0.7.6", default-features = false }
embassy-sync = "0.8.0" embassy-sync = "0.7.2"
embedded-hal-async = "1.0.0" embedded-hal-async = "1.0.0"
i2c-character-display = "0.5.1" i2c-character-display = "0.5.1"
ch1115 = { version = "0.1.2", features = ["graphics"] } ch1115 = { version = "0.1.2", features = ["graphics"] }
+3 -2
View File
@@ -42,12 +42,13 @@ pub async fn nfc_scanner(
}; };
CARD_DATA.lock().await.replace(card); CARD_DATA.lock().await.replace(card);
log::debug!("saving card to flash");
match peripherals match peripherals
.store .store
.lock() .lock()
.await .await
.card_store .card_store
.save_raw_card(split_data, peripherals.rtc.current_time_us()) .save_raw_card(&split_data, peripherals.rtc.current_time_us())
.await .await
{ {
Ok(()) => {} Ok(()) => {}
@@ -75,6 +76,6 @@ pub async fn nfc_scanner(
} }
} }
} }
embassy_time::Timer::after(embassy_time::Duration::from_millis(1000)).await; embassy_time::Timer::after(embassy_time::Duration::from_millis(10)).await;
} }
} }
+22 -13
View File
@@ -8,6 +8,7 @@
#![deny(clippy::large_stack_frames)] #![deny(clippy::large_stack_frames)]
use alloc::boxed::Box; use alloc::boxed::Box;
use alloc::sync::Arc;
use creaturedex::background_tasks; use creaturedex::background_tasks;
use creaturedex::drivers::i2c_bus::I2cBusPinConfiguration; use creaturedex::drivers::i2c_bus::I2cBusPinConfiguration;
use creaturedex::drivers::nfc_pn532::NfcPn532Driver; use creaturedex::drivers::nfc_pn532::NfcPn532Driver;
@@ -17,14 +18,14 @@ use creaturedex::drivers::spi_bus;
use creaturedex::drivers::tertiary_lcd::{ use creaturedex::drivers::tertiary_lcd::{
BOX, EMPTY, EXAMPLE, HEART, TertiaryDisplay, TertiaryDisplayPinConfiguration, BOX, EMPTY, EXAMPLE, HEART, TertiaryDisplay, TertiaryDisplayPinConfiguration,
}; };
use creaturedex::navigation::navigation::Mutex;
use creaturedex::navigation::inputs::Inputs; use creaturedex::navigation::inputs::Inputs;
use creaturedex::navigation::navigation::Mutex;
use creaturedex::navigation::navigation::{self}; use creaturedex::navigation::navigation::{self};
use creaturedex::navigation::state::NavigationState;
use creaturedex::navigation::outputs::Outputs; use creaturedex::navigation::outputs::Outputs;
use creaturedex::navigation::state::NavigationState;
use creaturedex::network::wifi::setup_wifi;
use creaturedex::peripherals::Peripherals; use creaturedex::peripherals::Peripherals;
use creaturedex::peripherals::storage::cardstore::CardStore; use creaturedex::peripherals::storage::cardstore::CardStore;
use creaturedex::peripherals::storage::flash_store::FlashStore;
use creaturedex::peripherals::storage::store::Store; use creaturedex::peripherals::storage::store::Store;
use embassy_executor::Spawner; use embassy_executor::Spawner;
use embedded_graphics::pixelcolor::BinaryColor; use embedded_graphics::pixelcolor::BinaryColor;
@@ -51,6 +52,9 @@ extern crate alloc;
const HEAP_SIZE: usize = 73744; const HEAP_SIZE: usize = 73744;
const NVS_PARTITION_OFFSET: usize = 0x10000;
const NVS_PARTITION_SIZE: usize = 0xfa000;
// This creates a default app-descriptor required by the esp-idf bootloader. // This creates a default app-descriptor required by the esp-idf bootloader.
// For more information see: <https://docs.espressif.com/projects/esp-idf/en/stable/esp32/api-reference/system/app_image_format.html#application-description> // For more information see: <https://docs.espressif.com/projects/esp-idf/en/stable/esp32/api-reference/system/app_image_format.html#application-description>
esp_bootloader_esp_idf::esp_app_desc!(); esp_bootloader_esp_idf::esp_app_desc!();
@@ -122,20 +126,21 @@ async fn main(spawner: Spawner) {
); );
} }
let flash_store = Box::leak(Box::new( let storage = esp_storage::FlashStorage::new(esp_peripherals.FLASH);
FlashStore::new(esp_peripherals.FLASH).expect("Could not initialize Flash Store"),
let nvs = Arc::new(Mutex::new(
esp_nvs::Nvs::new(NVS_PARTITION_OFFSET, NVS_PARTITION_SIZE, storage)
.expect("failed to create nvs"),
)); ));
let card_store = CardStore::new(flash_store) setup_wifi(esp_peripherals.WIFI, Arc::clone(&nvs), &spawner).await;
let card_store = CardStore::new(nvs)
.await .await
.expect("Could not initialize Card Store"); .expect("Could not initialize Card Store");
let store = Store { let store = Store { card_store };
flash_store,
card_store,
};
let rtc = Rtc::new(esp_peripherals.LPWR); let rtc = Rtc::new(esp_peripherals.LPWR);
//setup_wifi(peripherals.WIFI, peripherals.FLASH, &spawner).await;
let peripherals = Box::leak(Box::new(Peripherals { let peripherals = Box::leak(Box::new(Peripherals {
store: Mutex::new(store), store: Mutex::new(store),
@@ -179,10 +184,14 @@ async fn main(spawner: Spawner) {
let navigation_state = Box::leak(Box::new(Mutex::new(NavigationState::new()))); let navigation_state = Box::leak(Box::new(Mutex::new(NavigationState::new())));
log::info!("Setup complete, entering main loop"); log::info!("Setup complete, entering main loop");
spawner.spawn(navigation::run(inputs, outputs, peripherals, navigation_state).expect("run task failed"));
spawner.spawn( spawner.spawn(
background_tasks::nfc_scanner(nfc_driver, outputs, peripherals, navigation_state).expect("nfc scanner task failed"), navigation::run(inputs, outputs, peripherals, navigation_state).expect("run task failed"),
); );
spawner.spawn(
background_tasks::nfc_scanner(nfc_driver, outputs, peripherals, navigation_state)
.expect("nfc scanner task failed"),
);
core::future::pending::<()>().await core::future::pending::<()>().await
} }
+34
View File
@@ -1,4 +1,6 @@
use base64::prelude::*;
use core::fmt::Display; use core::fmt::Display;
use esp_nvs::Key;
use alloc::{string::String, vec::Vec}; use alloc::{string::String, vec::Vec};
use num_enum::FromPrimitive; use num_enum::FromPrimitive;
@@ -22,6 +24,38 @@ pub struct RawCard {
pub _padding: [u8; 2], pub _padding: [u8; 2],
} }
impl Default for RawCard {
fn default() -> Self {
Self {
event_encoding: Default::default(),
card_type: Default::default(),
card_uuid: Default::default(),
_reserved: Default::default(),
sprite: [0; 722],
packed_card_text: [0; 54],
secret: Default::default(),
_opaque_trailer: [0; 49],
_padding: Default::default(),
}
}
}
impl RawCard {
pub fn get_uuid(&self) -> u32 {
((u16::from_ne_bytes(self.event_encoding) as u32) << 16)
| (u16::from_ne_bytes(self.card_uuid) as u32)
}
pub fn get_nvs_key(&self) -> Key {
let uuid = self.get_uuid();
Self::nvs_key_from_uuid(uuid)
}
pub fn nvs_key_from_uuid(uuid: u32) -> Key {
let base64 = BASE64_STANDARD.encode(uuid.to_ne_bytes());
Key::from_str(&base64)
}
}
static_assertions::const_assert!(RawCard::SERIALIZED_SIZE.is_multiple_of(4)); static_assertions::const_assert!(RawCard::SERIALIZED_SIZE.is_multiple_of(4));
#[derive(Debug, Clone, Eq, PartialEq, FromPrimitive)] #[derive(Debug, Clone, Eq, PartialEq, FromPrimitive)]
+18 -18
View File
@@ -1,12 +1,15 @@
use crate::navigation::navigation::Mutex;
use crate::peripherals::storage::Nvs;
use alloc::sync::Arc;
use embassy_executor::Spawner; use embassy_executor::Spawner;
#[cfg(not(feature = "wokwi"))] #[cfg(not(feature = "wokwi"))]
pub async fn setup_wifi( pub async fn setup_wifi(
wifi: esp_hal::peripherals::WIFI<'static>, wifi: esp_hal::peripherals::WIFI<'static>,
flash: esp_hal::peripherals::FLASH<'static>, nvs: Arc<Mutex<Nvs>>,
spawner: &Spawner, spawner: &Spawner,
) { ) {
let nvs = esp_hal_wifimanager::Nvs::new(0x9000, 0x6000, flash).unwrap(); let espnvs = esp_hal_wifimanager::Nvs::new_from_nvs(nvs, 0, 0);
let mut wm_settings = esp_hal_wifimanager::WmSettings::default(); let mut wm_settings = esp_hal_wifimanager::WmSettings::default();
@@ -19,7 +22,8 @@ pub async fn setup_wifi(
wm_settings.wifi_conn_timeout = 30000; wm_settings.wifi_conn_timeout = 30000;
wm_settings.esp_reset_timeout = Some(300000); // 5min wm_settings.esp_reset_timeout = Some(300000); // 5min
let wifi_res = esp_hal_wifimanager::init_wm(wm_settings, spawner, Some(&nvs), wifi, None).await; let wifi_res =
esp_hal_wifimanager::init_wm(wm_settings, spawner, Some(&espnvs), wifi, None).await;
log::info!("wifi_res: {wifi_res:?}"); log::info!("wifi_res: {wifi_res:?}");
} }
@@ -27,31 +31,27 @@ pub async fn setup_wifi(
#[cfg(feature = "wokwi")] #[cfg(feature = "wokwi")]
pub async fn setup_wifi( pub async fn setup_wifi(
wifi: esp_hal::peripherals::WIFI<'static>, wifi: esp_hal::peripherals::WIFI<'static>,
flash: esp_hal::peripherals::FLASH<'static>, nvs: Arc<Mutex<Nvs>>,
spawner: &Spawner, spawner: &Spawner,
) { ) {
log::info!("Wokwi mode active: pre-seeding WiFi Manager with Wokwi credentials"); log::info!("Wokwi mode active: pre-seeding WiFi Manager with Wokwi credentials");
// Preload connection data so init_wm can connect immediately without AP setup. use esp_nvs::Key;
let nvs = match esp_hal_wifimanager::Nvs::new(0x9000, 0x6000, flash) { const WIFIMANAGER_NAMESPACE: Key = Key::from_str("wifimanager");
Ok(nvs) => nvs, const WIFIMANAGER_NVS_KEY: Key = Key::from_str("WIFI_SETUP");
Err(e) => {
log::error!("Failed to initialize NVS for Wokwi: {e:?}");
return;
}
};
if let Err(e) = nvs if let Err(e) = nvs.lock().await.set(
.set( &WIFIMANAGER_NAMESPACE,
esp_hal_wifimanager::WIFI_NVS_KEY, &WIFIMANAGER_NVS_KEY,
"{\"ssid\":\"Wokwi-GUEST\",\"psk\":\"\",\"data\":{}}", "{\"ssid\":\"Wokwi-GUEST\",\"psk\":\"\",\"data\":{}}",
) ) {
.await
{
log::error!("Failed to store Wokwi WiFi config in NVS: {e:?}"); log::error!("Failed to store Wokwi WiFi config in NVS: {e:?}");
return; return;
} }
// Preload connection data so init_wm can connect immediately without AP setup.
let nvs = esp_hal_wifimanager::Nvs::new_from_nvs(nvs, 0, 0);
let mut wm_settings = esp_hal_wifimanager::WmSettings::default(); let mut wm_settings = esp_hal_wifimanager::WmSettings::default();
// Wokwi simulation uses a default open network called "Wokwi-GUEST" // Wokwi simulation uses a default open network called "Wokwi-GUEST"
+2 -27
View File
@@ -1,32 +1,7 @@
pub struct MemoryRegion { use esp_storage::FlashStorage;
pub offset: u32,
pub size: usize,
}
impl MemoryRegion { pub type Nvs = esp_nvs::Nvs<FlashStorage<'static>>;
pub const fn new(offset: u32, size: usize) -> Self {
assert!(offset.is_multiple_of(4), "Flash requires 4 bytes alignment");
assert!(size.is_multiple_of(4), "Flash requires 4 bytes alignment");
Self { offset, size }
}
pub const fn end(&self) -> usize {
self.offset as usize + self.size
}
}
pub const MAX_FLASH: usize = 16 * 1024 * 1024;
pub const MAGIC_REGION: MemoryRegion = MemoryRegion::new(0, 4);
pub const SETTINGS_REGION: MemoryRegion = MemoryRegion::new(MAGIC_REGION.end() as u32, 1024);
pub const CARDSTORE_REGION: MemoryRegion = MemoryRegion::new(
SETTINGS_REGION.end() as u32,
MAX_FLASH - SETTINGS_REGION.end(),
);
pub mod cardstore; pub mod cardstore;
pub mod flash_store;
pub mod settings; pub mod settings;
pub mod store; pub mod store;
+246 -178
View File
@@ -1,73 +1,25 @@
use alloc::collections::BTreeMap; use crate::card::model::RawCard;
use crate::peripherals::Mutex;
use crate::peripherals::storage::Nvs;
use alloc::sync::Arc;
use alloc::vec::Vec; use alloc::vec::Vec;
use binary_serde::{BinarySerde, DeserializeError, Endianness};
use core::error::Error; use core::error::Error;
use core::fmt::Display; use core::fmt::Display;
use esp_nvs::Key;
use binary_serde::{BinarySerde, DeserializeError, Endianness}; const NVS_NAMESPACE_CARDSTORE: Key = Key::from_str("CARDSTORE");
const NVS_NAMESPACE_CARDSTORE_METADATA: Key = Key::from_str("CSMETA");
const NVS_NAMESPACE_CARDSTORE_CARDS: Key = Key::from_str("CSCARDS");
//use crate::card::model::Nfcraw_card; const NVS_CARDSTORE_INITIALIZED_KEY: Key = Key::from_str("INITIALIZED");
const NVS_CARDSTORE_CARDCOUNT_KEY: Key = Key::from_str("CARDCOUNT");
use crate::card::model::RawCard; const NVS_CARDSTORE_DUMMY_KEY: Key = Key::from_str("DUMMY");
use crate::peripherals::storage::flash_store::{FlashStore, FlashStoreError};
use crate::peripherals::storage::{CARDSTORE_REGION, MemoryRegion};
const MAX_CARDS: usize = 20000;
pub const COUNT_REGION: MemoryRegion = MemoryRegion::new(CARDSTORE_REGION.offset, size_of::<u32>());
const ALLOCATION_TABLE_REGION: MemoryRegion = MemoryRegion::new(
COUNT_REGION.end() as u32,
MAX_CARDS * AllocationTableEntry::SERIALIZED_SIZE,
);
const CARDS_REGION: MemoryRegion = MemoryRegion::new(
ALLOCATION_TABLE_REGION.end() as u32,
CARDSTORE_REGION.size - ALLOCATION_TABLE_REGION.end(),
);
#[derive(Debug, BinarySerde, PartialEq, Eq, Clone)]
#[repr(C)]
pub struct AllocationTableEntry {
uuid: u32,
// this is the numeric offset of the AllocationTableEntry
// as well as the card entry in flash memory
// size_of::<AllocationTableEntry>() * offset
// size_of::<RawCard>() * offset
offset: u32,
creation_date: u64,
last_read_date: u64,
// how often a card has been read by nfc
read_count: u32,
deleted: bool,
reserved: [u64; 4],
_padding: [u8; 3],
}
static_assertions::const_assert!(AllocationTableEntry::SERIALIZED_SIZE.is_multiple_of(4));
impl AllocationTableEntry {
fn new(uuid: u32, offset: u32, timestamp: u64) -> Self {
Self {
uuid,
offset,
creation_date: timestamp,
last_read_date: timestamp,
read_count: 0,
deleted: true,
reserved: Default::default(),
_padding: Default::default(),
}
}
}
#[derive(Debug)] #[derive(Debug)]
pub enum CardStoreError { pub enum CardStoreError {
Store(FlashStoreError), Store(esp_nvs::error::Error),
CorruptedEntry(DeserializeError), CorruptedEntry(DeserializeError),
NoEntry(u32), NoEntry(u32),
} }
@@ -84,8 +36,8 @@ impl Display for CardStoreError {
} }
} }
impl From<FlashStoreError> for CardStoreError { impl From<esp_nvs::error::Error> for CardStoreError {
fn from(error: FlashStoreError) -> CardStoreError { fn from(error: esp_nvs::error::Error) -> CardStoreError {
CardStoreError::Store(error) CardStoreError::Store(error)
} }
} }
@@ -96,140 +48,256 @@ impl From<DeserializeError> for CardStoreError {
} }
} }
#[derive(Debug, BinarySerde, PartialEq, Eq, Clone)]
pub struct CardStoreMetaData {
pub creation_date: u64,
pub last_read_date: u64,
// how often a card has been read by nfc
pub read_count: u32,
}
impl CardStoreMetaData {
fn new(creation_date: u64) -> Self {
Self {
creation_date: creation_date,
last_read_date: creation_date,
read_count: 0,
}
}
}
pub struct CardStore { pub struct CardStore {
store: &'static FlashStore, nvs: Arc<Mutex<Nvs>>,
count: u32,
pub allocation_table: BTreeMap<u32, AllocationTableEntry>,
} }
impl CardStore { impl CardStore {
pub async fn new(store: &'static FlashStore) -> Result<Self, CardStoreError> { pub async fn new(nvs: Arc<Mutex<Nvs>>) -> Result<Self, CardStoreError> {
let mut count_bytes: [u8; COUNT_REGION.size] = [0; COUNT_REGION.size]; if !Self::is_initialized(&nvs).await? {
log::info!("CardStore has not been initialized");
store.read(COUNT_REGION.offset, &mut count_bytes).await?; Self::initialize(&nvs).await?;
let count: u32 = u32::from_ne_bytes(count_bytes);
log::info!("Found {count} cards in flash.");
let mut allocation_table_entries: Vec<u8> =
Vec::with_capacity(AllocationTableEntry::SERIALIZED_SIZE * count as usize);
store
.read(
ALLOCATION_TABLE_REGION.offset,
&mut allocation_table_entries,
)
.await?;
let chunks =
allocation_table_entries.into_chunks::<{ AllocationTableEntry::SERIALIZED_SIZE }>();
let mut allocation_table = BTreeMap::<u32, AllocationTableEntry>::new();
for chunk in chunks {
let allocation_table_entry =
AllocationTableEntry::binary_deserialize(chunk.as_ref(), Endianness::Little)?;
allocation_table.insert(allocation_table_entry.uuid, allocation_table_entry);
} }
Ok(Self { log::info!("CardStore has been initialized");
store, let card_count = nvs
count, .lock()
allocation_table, .await
}) .get::<u32>(&NVS_NAMESPACE_CARDSTORE, &NVS_CARDSTORE_CARDCOUNT_KEY)?;
log::info!("Cards stored in flash: {card_count}");
Ok(Self { nvs })
} }
pub async fn get_card_by_uuid(&self, uuid: u32) -> Result<RawCard, CardStoreError> { async fn is_initialized(nvs: &Mutex<Nvs>) -> Result<bool, CardStoreError> {
let entry = self log::info!("check initialization");
.allocation_table let mut nvs_lock = nvs.lock().await;
.get(&uuid) match nvs_lock.get::<bool>(&NVS_NAMESPACE_CARDSTORE, &NVS_CARDSTORE_INITIALIZED_KEY) {
.ok_or(CardStoreError::NoEntry(uuid))?; Ok(initialized) => {
log::debug!("initialization_check: initialized {initialized:?}");
return Ok(true);
}
Err(esp_nvs::error::Error::NamespaceNotFound) => {
log::debug!("initialization_check: error: namespace not found");
return Ok(false);
}
Err(esp_nvs::error::Error::KeyNotFound) => {
log::debug!("initialization_check: error: key not found");
return Ok(false);
}
Err(error) => return Err(error.into()),
};
}
let mut raw_card: [u8; size_of::<RawCard>()] = [0; size_of::<RawCard>()]; // initializing cardstore with 0 cards, so that all namespaces exist and there
self.store.read(entry.offset, &mut raw_card).await?; // are only keynotfound errors in the future
async fn initialize(nvs: &Mutex<Nvs>) -> Result<(), CardStoreError> {
log::info!("initializing card store");
Ok(RawCard::binary_deserialize( Self::delete_all_cards(nvs).await?;
raw_card.as_ref(),
Endianness::Little, let mut nvs_lock = nvs.lock().await;
)?)
log::debug!("initialization: write card count");
// initialize card count
nvs_lock.set::<u32>(&NVS_NAMESPACE_CARDSTORE, &NVS_CARDSTORE_CARDCOUNT_KEY, 0)?;
// initialize card namespace
let dummy_card = RawCard::default();
let mut carddata_serialized: [u8; RawCard::SERIALIZED_SIZE] = [0; RawCard::SERIALIZED_SIZE];
dummy_card.binary_serialize(&mut carddata_serialized, Endianness::Little);
log::debug!("initialization: write dummy card");
nvs_lock.set::<&[u8]>(
&NVS_NAMESPACE_CARDSTORE_CARDS,
&NVS_CARDSTORE_DUMMY_KEY,
&carddata_serialized,
)?;
// initialize metadata namespace
log::debug!("initialization: write dummy metadata");
let dummy_metadata = CardStoreMetaData::new(0);
let mut metadata_serialized: [u8; CardStoreMetaData::SERIALIZED_SIZE] =
[0; CardStoreMetaData::SERIALIZED_SIZE];
dummy_metadata.binary_serialize(&mut metadata_serialized, Endianness::Little);
nvs_lock.set::<&[u8]>(
&NVS_NAMESPACE_CARDSTORE_METADATA,
&NVS_CARDSTORE_DUMMY_KEY,
&metadata_serialized,
)?;
// set initialized
log::debug!("initialization: write initialized");
nvs_lock.set::<bool>(
&NVS_NAMESPACE_CARDSTORE,
&NVS_CARDSTORE_INITIALIZED_KEY,
true,
)?;
Ok(())
}
async fn delete_all_cards(nvs: &Mutex<Nvs>) -> Result<(), CardStoreError> {
log::info!("delete all cards");
let mut nvs_lock = nvs.lock().await;
let keys = nvs_lock.keys().collect::<Result<Vec<_>, _>>()?;
for (namespace, key) in keys {
if namespace == NVS_NAMESPACE_CARDSTORE || namespace == NVS_NAMESPACE_CARDSTORE_METADATA
{
nvs_lock.delete(&namespace, &key)?;
}
}
Ok(())
}
pub async fn load_card_count(&self) -> Result<u32, CardStoreError> {
log::debug!("load card count");
let mut nvs_lock = self.nvs.lock().await;
let result = nvs_lock.get::<u32>(&NVS_NAMESPACE_CARDSTORE, &NVS_CARDSTORE_CARDCOUNT_KEY)?;
log::debug!("card count: {result}");
Ok(result)
}
pub async fn load_raw_card(&self, uuid: u32) -> Result<Option<RawCard>, CardStoreError> {
log::debug!("load raw card\nuuid: 0x{uuid:x}");
let nvs_key = RawCard::nvs_key_from_uuid(uuid);
let mut nvs_lock = self.nvs.lock().await;
let carddata_binary: Vec<u8> = match nvs_lock.get(&NVS_NAMESPACE_CARDSTORE_CARDS, &nvs_key)
{
Ok(carddata) => carddata,
Err(esp_nvs::error::Error::KeyNotFound) => return Ok(None),
Err(error) => return Err(error.into()),
};
let carddata = RawCard::binary_deserialize(carddata_binary.as_ref(), Endianness::Little)?;
Ok(Some(carddata))
}
async fn write_card(&self, nvs_key: Key, card: &RawCard) -> Result<(), CardStoreError> {
log::debug!("writing card...\nkey: {nvs_key:?}");
let mut carddata_serialized: [u8; RawCard::SERIALIZED_SIZE] = [0; RawCard::SERIALIZED_SIZE];
card.binary_serialize(&mut carddata_serialized, Endianness::Little);
self.nvs.lock().await.set::<&[u8]>(
&NVS_NAMESPACE_CARDSTORE_CARDS,
&nvs_key,
&carddata_serialized,
)?;
Ok(())
}
async fn update_card_metadata(
&self,
nvs_key: Key,
timestamp: u64,
) -> Result<bool, CardStoreError> {
log::debug!("updating card metadata...\nkey: {nvs_key:?}\ntimestamp: {timestamp}");
let mut is_new = false;
// update metadata
let metadata: CardStoreMetaData =
if let Some(mut metadata) = self.load_card_metadata(nvs_key).await? {
log::debug!("found existing card");
metadata.last_read_date = timestamp;
metadata.read_count += 1;
metadata
} else {
log::debug!("new card");
is_new = true;
CardStoreMetaData::new(timestamp)
};
let mut metadata_serialized: [u8; CardStoreMetaData::SERIALIZED_SIZE] =
[0; CardStoreMetaData::SERIALIZED_SIZE];
metadata.binary_serialize(&mut metadata_serialized, Endianness::Little);
self.nvs.lock().await.set::<&[u8]>(
&NVS_NAMESPACE_CARDSTORE_METADATA,
&nvs_key,
&metadata_serialized,
)?;
Ok(is_new)
}
async fn increment_card_count(&self) -> Result<(), CardStoreError> {
log::debug!("incrementing card count");
let card_count: u32 = self.load_card_count().await?;
log::debug!("previous card count: {card_count}");
self.nvs.lock().await.set::<u32>(
&NVS_NAMESPACE_CARDSTORE,
&NVS_CARDSTORE_CARDCOUNT_KEY,
card_count + 1,
)?;
let card_count = self
.nvs
.lock()
.await
.get::<u32>(&NVS_NAMESPACE_CARDSTORE, &NVS_CARDSTORE_CARDCOUNT_KEY)?;
log::info!("Cards stored in flash: {card_count}");
Ok(())
} }
pub async fn save_raw_card( pub async fn save_raw_card(
&mut self, &self,
raw_card: RawCard, card: &RawCard,
timestamp: u64, timestamp: u64,
) -> Result<(), CardStoreError> { ) -> Result<(), CardStoreError> {
let uuid: u32 = (u16::from_ne_bytes(raw_card.event_encoding) as u32) << 16 log::debug!("saving raw card\ntimestamp: {timestamp}");
| (u16::from_ne_bytes(raw_card.card_uuid) as u32); let nvs_key = card.get_nvs_key();
log::info!("Saving card with uuid {:x}", uuid);
// check if we already got the card self.write_card(nvs_key, card).await?;
// if not find the next deleted entry,
// if none create a new one at the end
let (entry, is_new) = match self.allocation_table.get_mut(&uuid) {
Some(entry) => {
log::debug!("old entry");
(entry, false)
}
None => match self
.allocation_table
.values_mut()
.find(|entry| entry.deleted)
{
Some(entry) => {
log::debug!("deleted entry");
(entry, true)
}
None => {
log::debug!("new entry");
let entry = AllocationTableEntry::new(uuid, self.count + 1, timestamp);
self.allocation_table.insert(uuid, entry);
(
self.allocation_table
.get_mut(&uuid)
.expect("entry was just inserted"),
true,
)
}
},
};
// only write card data if it is new. else it is already written in flash let new_card = self.update_card_metadata(nvs_key, timestamp).await?;
if is_new {
log::debug!("writing RawCard to flash"); if new_card {
let mut serialized_card: [u8; RawCard::SERIALIZED_SIZE] = [0; RawCard::SERIALIZED_SIZE]; self.increment_card_count().await?;
raw_card.binary_serialize(&mut serialized_card, Endianness::Little);
self.store
.write_erase(
CARDS_REGION.offset + entry.offset * RawCard::SERIALIZED_SIZE as u32,
&mut serialized_card,
)
.await?;
} else {
entry.last_read_date = timestamp;
entry.read_count += 1;
} }
entry.deleted = false;
log::debug!("writing AllocationTableEntry to flash");
let mut serialized_entry: [u8; AllocationTableEntry::SERIALIZED_SIZE] =
[0; AllocationTableEntry::SERIALIZED_SIZE];
entry.binary_serialize(&mut serialized_entry, Endianness::Little);
self.store
.write_erase(
ALLOCATION_TABLE_REGION.offset
+ entry.offset * AllocationTableEntry::SERIALIZED_SIZE as u32,
&mut serialized_entry,
)
.await?;
self.count += 1;
log::debug!("writing card count to flash");
let mut serialized_count: [u8; 4] = self.count.to_le_bytes();
self.store
.write(COUNT_REGION.offset, serialized_count.as_mut_slice())
.await?;
Ok(()) Ok(())
} }
pub async fn load_card_metadata(
&self,
nvs_key: Key,
) -> Result<Option<CardStoreMetaData>, CardStoreError> {
log::debug!("load card meta data\nkey: {nvs_key:?}");
let mut nvs_lock = self.nvs.lock().await;
let metadata_binary: Vec<u8> =
match nvs_lock.get(&NVS_NAMESPACE_CARDSTORE_METADATA, &nvs_key) {
Ok(metadata) => metadata,
Err(esp_nvs::error::Error::KeyNotFound) => return Ok(None),
Err(error) => return Err(error.into()),
};
let metadata =
CardStoreMetaData::binary_deserialize(metadata_binary.as_ref(), Endianness::Little)?;
Ok(Some(metadata))
}
} }
+8 -6
View File
@@ -25,7 +25,7 @@ impl Display for FlashStoreError {
} }
} }
const FLASH_ADDR: u32 = 0x9000; const FLASH_ADDR: u32 = 0x200000;
const INITIALIZATION_SIZE: usize = 0x1000; const INITIALIZATION_SIZE: usize = 0x1000;
const FLASH_INITIALIZE_MAGIC: u32 = 0xde6de6de; const FLASH_INITIALIZE_MAGIC: u32 = 0xde6de6de;
@@ -74,11 +74,13 @@ impl FlashStore {
bytes.len() bytes.len()
); );
let mut lock = self.storage.lock().await; let mut lock = self.storage.lock().await;
lock.erase( let addr = FLASH_ADDR + offset;
FLASH_ADDR + offset, let to = FLASH_ADDR + offset + bytes.len() as u32;
FLASH_ADDR + offset + bytes.len() as u32, log::debug!("Erasing from 0x{addr:x} to 0x{to:x}");
)?; //lock.erase(addr, to)?;
lock.write(FLASH_ADDR + offset, bytes)?;
log::debug!("Writing bytes...");
lock.write(addr, bytes)?;
Ok(()) Ok(())
} }
-2
View File
@@ -1,7 +1,5 @@
use crate::peripherals::storage::cardstore::CardStore; use crate::peripherals::storage::cardstore::CardStore;
use crate::peripherals::storage::flash_store::FlashStore;
pub struct Store { pub struct Store {
pub flash_store: &'static FlashStore,
pub card_store: CardStore, pub card_store: CardStore,
} }
+7 -21
View File
@@ -4,8 +4,6 @@ use crate::navigation::navigation::Navigable;
use crate::navigation::navigation::NewState; use crate::navigation::navigation::NewState;
use crate::navigation::outputs::Outputs; use crate::navigation::outputs::Outputs;
use crate::peripherals::Peripherals; use crate::peripherals::Peripherals;
use crate::peripherals::storage::MAGIC_REGION;
use crate::peripherals::storage::cardstore::COUNT_REGION;
use crate::views::view::View; use crate::views::view::View;
use alloc::boxed::Box; use alloc::boxed::Box;
use core::error; use core::error;
@@ -39,22 +37,6 @@ impl Navigable for FlashInfoView {
.clear(Rgb565::BLACK) .clear(Rgb565::BLACK)
.map_err(PrimaryDisplayError::from)?; .map_err(PrimaryDisplayError::from)?;
let _style = MonoTextStyle::new(&FONT_10X20, Rgb565::WHITE); let _style = MonoTextStyle::new(&FONT_10X20, Rgb565::WHITE);
let mut magic_bytes: [u8; MAGIC_REGION.size] = [0; MAGIC_REGION.size];
peripherals
.store
.lock()
.await
.flash_store
.read(MAGIC_REGION.offset, &mut magic_bytes)
.await?;
let mut card_count_bytes: [u8; COUNT_REGION.size] = [0; COUNT_REGION.size];
peripherals
.store
.lock()
.await
.flash_store
.read(COUNT_REGION.offset, &mut card_count_bytes)
.await?;
let style = MonoTextStyle::new(&FONT_10X20, Rgb565::WHITE); let style = MonoTextStyle::new(&FONT_10X20, Rgb565::WHITE);
let textbox_style = TextBoxStyleBuilder::new() let textbox_style = TextBoxStyleBuilder::new()
@@ -65,14 +47,18 @@ impl Navigable for FlashInfoView {
let display_area = outputs.primary_display.bounding_box(); let display_area = outputs.primary_display.bounding_box();
let bounds = Rectangle::new(Point::new(0, 30), display_area.size); let bounds = Rectangle::new(Point::new(0, 30), display_area.size);
log::debug!("locking store");
let store = peripherals.store.lock().await;
log::debug!("getting card count");
let card_count = store.card_store.load_card_count().await?;
TextBox::with_textbox_style( TextBox::with_textbox_style(
&format!( &format!(
" "
Flash Init Magic: 0x{:x}\n
Card Count: {}\n Card Count: {}\n
", ",
u32::from_le_bytes(magic_bytes), card_count
u32::from_le_bytes(card_count_bytes)
), ),
bounds, bounds,
style, style,