From d99b9ba22f1f187ee0c6f929e13355d252a973a3 Mon Sep 17 00:00:00 2001 From: Daniel Schaefer Date: Tue, 8 Aug 2023 02:04:04 +0800 Subject: [PATCH] very dirty implementation of basic persistence --save command saves grid and loads it on restart Signed-off-by: Daniel Schaefer --- Cargo.lock | 286 ++++++++++++-------- fl16-inputmodules/Cargo.toml | 14 + fl16-inputmodules/src/control.rs | 9 +- fl16-inputmodules/src/games/game_of_life.rs | 4 +- fl16-inputmodules/src/games/pong.rs | 6 +- fl16-inputmodules/src/games/snake.rs | 4 +- fl16-inputmodules/src/matrix.rs | 73 ++++- fl16-inputmodules/src/patterns.rs | 121 +++++---- inputmodule-control/src/inputmodule.rs | 5 + inputmodule-control/src/ledmatrix.rs | 3 + ledmatrix/Cargo.toml | 3 + ledmatrix/src/main.rs | 115 ++++++++ 12 files changed, 454 insertions(+), 189 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index f84c1b9f..d8d879a0 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -25,9 +25,9 @@ dependencies = [ [[package]] name = "addr2line" -version = "0.19.0" +version = "0.20.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a76fd60b23679b7d19bd066031410fb7e458ccc5e958eb5c325888ce4baedc97" +checksum = "f4fa78e18c64fce05e902adecd7a5eed15a5e0a3439f7b0e169f0252214865e3" dependencies = [ "gimli", ] @@ -58,9 +58,9 @@ dependencies = [ [[package]] name = "alsa" -version = "0.7.0" +version = "0.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8512c9117059663fb5606788fbca3619e2a91dac0e3fe516242eab1fa6be5e44" +checksum = "e2562ad8dcf0f789f65c6fdaad8a8a9708ed6b488e649da28c01656ad66b8b47" dependencies = [ "alsa-sys", "bitflags 1.3.2", @@ -110,15 +110,15 @@ dependencies = [ [[package]] name = "anstyle" -version = "1.0.0" +version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "41ed9a86bf92ae6580e0a31281f65a1b1d867c0cc68d5346e2ae128dddfa6a7d" +checksum = "3a30da5c5f2d5e72842e00bcb57657162cdabef0931f40e2deb9b4140440cecd" [[package]] name = "anstyle-parse" -version = "0.2.0" +version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e765fd216e48e067936442276d1d57399e37bce53c264d6fefbe298080cb57ee" +checksum = "938874ff5980b03a87c5524b3ae5b59cf99b1d6bc836848df7bc5ada9643c333" dependencies = [ "utf8parse", ] @@ -150,9 +150,9 @@ checksum = "fca387cdc0a1f9c7a7c26556d584aa2d07fc529843082e4861003cde4ab914ed" [[package]] name = "arrayvec" -version = "0.7.3" +version = "0.7.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8868f09ff8cea88b079da74ae569d9b8c62a23c68c746240b704ee6f7525c89c" +checksum = "96d30a06541fbafbc7f82ed10c06164cfbd2c401138f6addd8404629c4b16711" [[package]] name = "atomic-polyfill" @@ -220,15 +220,15 @@ dependencies = [ [[package]] name = "backtrace" -version = "0.3.67" +version = "0.3.68" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "233d376d6d185f2a3093e58f283f60f880315b6c60075b01f36b3b85154564ca" +checksum = "4319208da049c43661739c5fade2ba182f09d1dc2299b32298d3a31692b17e12" dependencies = [ "addr2line", "cc", "cfg-if", "libc", - "miniz_oxide 0.6.2", + "miniz_oxide", "object", "rustc-demangle", ] @@ -256,7 +256,7 @@ dependencies = [ "peeking_take_while", "proc-macro2", "quote", - "regex 1.8.4", + "regex 1.9.3", "rustc-hash", "shlex", "syn 1.0.109", @@ -334,11 +334,12 @@ checksum = "981520c98f422fcc584dc1a95c334e6953900b9106bc47a9839b81790009eb21" [[package]] name = "cc" -version = "1.0.79" +version = "1.0.82" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "50d30906286121d95be3d479533b458f87493b30a4b5f79a607db8f5d11aa91f" +checksum = "305fe645edc1442a0fa8b6726ba61d422798d37a52e12eaecf4b022ebbb88f01" dependencies = [ "jobserver", + "libc", ] [[package]] @@ -390,9 +391,9 @@ dependencies = [ [[package]] name = "clap" -version = "4.3.3" +version = "4.3.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ca8f255e4b8027970e78db75e78831229c9815fdbfa67eb1a1b777a62e24b4a0" +checksum = "5fd304a20bff958a57f04c4e96a2e7594cc4490a0e809cbd48bb6437edaa452d" dependencies = [ "clap_builder", "clap_derive", @@ -401,27 +402,26 @@ dependencies = [ [[package]] name = "clap_builder" -version = "4.3.3" +version = "4.3.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "acd4f3c17c83b0ba34ffbc4f8bbd74f079413f747f84a6f89292f138057e36ab" +checksum = "01c6a3f08f1fe5662a35cfe393aec09c4df95f60ee93b7556505260f75eee9e1" dependencies = [ "anstream", "anstyle", - "bitflags 1.3.2", "clap_lex", "strsim", ] [[package]] name = "clap_derive" -version = "4.3.2" +version = "4.3.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b8cd2b2a819ad6eec39e8f1d6b53001af1e5469f8c177579cdaeb313115b825f" +checksum = "54a9bb5758fc5dfe728d1019941681eccaf0cf8a4189b692a0ee2f2ecf90a050" dependencies = [ "heck", "proc-macro2", "quote", - "syn 2.0.18", + "syn 2.0.28", ] [[package]] @@ -439,6 +439,12 @@ dependencies = [ "bitflags 1.3.2", ] +[[package]] +name = "cobs" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "67ba02a97a2bd10f4b59b25c7973101c79642302776489e030cd13cdab09ed15" + [[package]] name = "color-backtrace" version = "0.5.1" @@ -614,9 +620,9 @@ checksum = "f578e8e2c440e7297e008bb5486a3a8a194775224bbc23729b0dbdfaeebf162e" [[package]] name = "defmt" -version = "0.3.4" +version = "0.3.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "956673bd3cb347512bf988d1e8d89ac9a82b64f6eec54d3c01c3529dac019882" +checksum = "a8a2d011b2fee29fb7d659b83c43fce9a2cb4df453e16d441a51448e448f3f98" dependencies = [ "bitflags 1.3.2", "defmt-macros", @@ -624,15 +630,15 @@ dependencies = [ [[package]] name = "defmt-macros" -version = "0.3.5" +version = "0.3.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b4abc4821bd84d3d8f49945ddb24d029be9385ed9b77c99bf2f6296847a6a9f0" +checksum = "54f0216f6c5acb5ae1a47050a6645024e6edafc2ee32d421955eccfef12ef92e" dependencies = [ "defmt-parser", "proc-macro-error", "proc-macro2", "quote", - "syn 1.0.109", + "syn 2.0.28", ] [[package]] @@ -656,9 +662,9 @@ dependencies = [ [[package]] name = "either" -version = "1.8.1" +version = "1.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7fcaabb2fef8c910e7f4c7ce9f67a1283a1715879a7c230ca9d6d1ae31f16d91" +checksum = "a26ae43d7bcc3b814de94796a5e736d4029efb0ee900c12e2d54c993ad1a1e07" [[package]] name = "embedded-dma" @@ -717,15 +723,21 @@ dependencies = [ "humantime", "is-terminal", "log", - "regex 1.8.4", + "regex 1.9.3", "termcolor", ] +[[package]] +name = "equivalent" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5" + [[package]] name = "errno" -version = "0.3.1" +version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4bcfec3a70f97c962c307b2d2c56e358cf1d00b558d74262b5f929ee8cc7e73a" +checksum = "6b30f669a7961ef1631673d2766cc92f52d64f7ef354d4fe0ddfd30ed52f0f4f" dependencies = [ "errno-dragonfly", "libc", @@ -789,9 +801,12 @@ dependencies = [ "num", "num-derive", "num-traits", + "postcard", "rp2040-boot2", + "rp2040-flash", "rp2040-hal", "rp2040-panic-usb-boot", + "serde", "smart-leds", "st7306", "tinybmp", @@ -808,7 +823,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3b9429470923de8e8cbd4d2dc513535400b4b3fef0319fb5c4e1f520a7bef743" dependencies = [ "crc32fast", - "miniz_oxide 0.7.1", + "miniz_oxide", ] [[package]] @@ -864,9 +879,9 @@ dependencies = [ [[package]] name = "gimli" -version = "0.27.2" +version = "0.27.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ad0a93d233ebf96623465aad4046a8d3aa4da22d4f4beba5388838c8a434bbb4" +checksum = "b6c80984affa11d98d1b88b66ac8853f143217b399d3c74116778ff8fdb4ed2e" [[package]] name = "glob" @@ -885,9 +900,9 @@ dependencies = [ [[package]] name = "hashbrown" -version = "0.12.3" +version = "0.14.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888" +checksum = "2c6201b9ff9fd90a5a3bac2e56a830d0caa509576f0e503818ee82c181b3437a" [[package]] name = "heapless" @@ -898,6 +913,7 @@ dependencies = [ "atomic-polyfill", "hash32", "rustc_version 0.4.0", + "serde", "spin", "stable_deref_trait", ] @@ -919,9 +935,9 @@ dependencies = [ [[package]] name = "hermit-abi" -version = "0.3.1" +version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fed44880c466736ef9a5c5b5facefb5ed0785676d0c02d612db14e54f0d84286" +checksum = "443144c8cdadd93ebf52ddb4056d257f5b52c04d3c804e657d19eb73fc33668b" [[package]] name = "humantime" @@ -969,11 +985,11 @@ dependencies = [ [[package]] name = "indexmap" -version = "1.9.3" +version = "2.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bd070e393353796e801d209ad339e89596eb4c8d430d18ede6a1cced8fafbd99" +checksum = "d5477fe2230a79769d8dc68e0eabf5437907c0457a5614a9e8dddb67f65eb65d" dependencies = [ - "autocfg 1.1.0", + "equivalent", "hashbrown", ] @@ -996,7 +1012,7 @@ version = "1.0.11" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "eae7b9aee968036d54dce06cebaefd919e4472e753296daccd6d344e3e2df0c2" dependencies = [ - "hermit-abi 0.3.1", + "hermit-abi 0.3.2", "libc", "windows-sys", ] @@ -1013,7 +1029,7 @@ version = "0.4.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "adcf93614601c8129ddf72e2d5633df827ba6551541c6d8c59520a371475be1f" dependencies = [ - "hermit-abi 0.3.1", + "hermit-abi 0.3.2", "io-lifetimes", "rustix", "windows-sys", @@ -1115,6 +1131,7 @@ dependencies = [ "heapless", "is31fl3741", "rp2040-boot2", + "rp2040-flash", "rp2040-hal", "rp2040-panic-usb-boot", "usb-device", @@ -1124,9 +1141,9 @@ dependencies = [ [[package]] name = "libc" -version = "0.2.146" +version = "0.2.147" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f92be4933c13fd498862a9e02a3055f8a8d9c039ce33db97306fd5a6caa7f29b" +checksum = "b4668fb0ea861c1df094127ac5f1da3409a82116a4ba74fca2e58ef927159bb3" [[package]] name = "libloading" @@ -1180,7 +1197,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c1cc9717a20b1bb222f333e6a92fd32f7d8a18ddc5a3191a11af45dcbf4dcd16" dependencies = [ "autocfg 1.1.0", - "scopeguard 1.1.0", + "scopeguard 1.2.0", ] [[package]] @@ -1231,15 +1248,6 @@ version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a" -[[package]] -name = "miniz_oxide" -version = "0.6.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b275950c28b37e794e8c55d88aeb5e139d0ce23fdbbeda68f8d7174abdf9e8fa" -dependencies = [ - "adler", -] - [[package]] name = "miniz_oxide" version = "0.7.1" @@ -1329,9 +1337,9 @@ dependencies = [ [[package]] name = "num" -version = "0.4.0" +version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "43db66d1170d347f9a065114077f7dccb00c1b9478c89384490a3425279a4606" +checksum = "b05180d69e3da0e530ba2a1dae5110317e49e3b7f3d41be227dc5f92e49ee7af" dependencies = [ "num-complex", "num-integer", @@ -1394,9 +1402,9 @@ dependencies = [ [[package]] name = "num-traits" -version = "0.2.15" +version = "0.2.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "578ede34cf02f8924ab9447f50c28075b4d3e5b269972345e7e0372b38c6cdcd" +checksum = "f30b0abd723be7e2ffca1272140fac1a2f084c77ec3e123c192b66af1ee9e6c2" dependencies = [ "autocfg 1.1.0", ] @@ -1424,9 +1432,9 @@ dependencies = [ [[package]] name = "object" -version = "0.30.4" +version = "0.31.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "03b4680b86d9cfafba8fc491dc9b6df26b68cf40e9e6cd73909194759a63c385" +checksum = "8bda667d9f2b5051b8833f59f3bf748b28ef54f850f4fcb389a252aa383866d1" dependencies = [ "memchr", ] @@ -1511,15 +1519,15 @@ dependencies = [ "cfg-if", "libc", "redox_syscall", - "smallvec 1.10.0", - "windows-targets 0.48.0", + "smallvec 1.11.0", + "windows-targets 0.48.1", ] [[package]] name = "paste" -version = "1.0.12" +version = "1.0.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9f746c4065a8fa3fe23974dd82f15431cc8d40779821001404d10d2e79ca7d79" +checksum = "de3145af08024dea9fa9914f381a17b8fc6034dfb00f3a84013f7ff43f29ed4c" [[package]] name = "peeking_take_while" @@ -1554,7 +1562,18 @@ dependencies = [ "crc32fast", "fdeflate", "flate2", - "miniz_oxide 0.7.1", + "miniz_oxide", +] + +[[package]] +name = "postcard" +version = "1.0.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c9ee729232311d3cd113749948b689627618133b1c5012b77342c1950b25eaeb" +dependencies = [ + "cobs", + "heapless", + "serde", ] [[package]] @@ -1608,18 +1627,18 @@ dependencies = [ [[package]] name = "proc-macro2" -version = "1.0.60" +version = "1.0.66" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dec2b086b7a862cf4de201096214fa870344cf922b2b30c167badb3af3195406" +checksum = "18fb31db3f9bddb2ea821cde30a9f70117e3f119938b5ee630b7403aa6e2ead9" dependencies = [ "unicode-ident", ] [[package]] name = "quote" -version = "1.0.28" +version = "1.0.32" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1b9ab9c7eadfd8df19006f1cf1a4aed13540ed5cbc047010ece5826e10825488" +checksum = "50f3b39ccfb720540debaa0164757101c08ecb8d326b15358ce76a62c7e85965" dependencies = [ "proc-macro2", ] @@ -1799,13 +1818,25 @@ dependencies = [ [[package]] name = "regex" -version = "1.8.4" +version = "1.9.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d0ab3ca65655bb1e41f2a8c8cd662eb4fb035e67c3f78da1d61dffe89d07300f" +checksum = "81bc1d4caf89fac26a70747fe603c130093b53c773888797a6329091246d651a" dependencies = [ "aho-corasick 1.0.2", "memchr", - "regex-syntax 0.7.2", + "regex-automata", + "regex-syntax 0.7.4", +] + +[[package]] +name = "regex-automata" +version = "0.3.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fed1ceff11a1dddaee50c9dc8e4938bd106e9d89ae372f192311e7da498e3b69" +dependencies = [ + "aho-corasick 1.0.2", + "memchr", + "regex-syntax 0.7.4", ] [[package]] @@ -1819,9 +1850,9 @@ dependencies = [ [[package]] name = "regex-syntax" -version = "0.7.2" +version = "0.7.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "436b050e76ed2903236f032a59761c1eb99e1b0aead2c257922771dab1fc8c78" +checksum = "e5ea92a5b6195c6ef2a0295ea818b312502c6fc94dde986c5553242e18fd4ce2" [[package]] name = "rgb" @@ -1841,6 +1872,15 @@ dependencies = [ "crc-any", ] +[[package]] +name = "rp2040-flash" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "181d7e68c6c748bb69b7466e8fc14245023a82d07a304996d368c177ac357f79" +dependencies = [ + "rp2040-hal", +] + [[package]] name = "rp2040-hal" version = "0.8.2" @@ -1924,7 +1964,7 @@ version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bfa0f585226d2e68097d4f95d113b15b83a82e819ab25717ec0590d9584ef366" dependencies = [ - "semver 1.0.17", + "semver 1.0.18", ] [[package]] @@ -1944,9 +1984,9 @@ dependencies = [ [[package]] name = "rustix" -version = "0.37.20" +version = "0.37.23" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b96e891d04aa506a6d1f318d2771bcb1c7dfda84e126660ace067c9b474bb2c0" +checksum = "4d69718bf81c6127a49dc64e44a742e8bb9213c0ff8869a22c308f84c1d4ab06" dependencies = [ "bitflags 1.3.2", "errno", @@ -1973,9 +2013,9 @@ checksum = "94258f53601af11e6a49f722422f6e3425c52b06245a5cf9bc09908b174f5e27" [[package]] name = "scopeguard" -version = "1.1.0" +version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd" +checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" [[package]] name = "semver" @@ -1988,9 +2028,9 @@ dependencies = [ [[package]] name = "semver" -version = "1.0.17" +version = "1.0.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bebd363326d05ec3e2f532ab7660680f3b02130d780c299bca73469d521bc0ed" +checksum = "b0293b4b29daaf487284529cc2f5675b8e57c61f70167ba415a463651fd6a918" [[package]] name = "semver-parser" @@ -2000,15 +2040,29 @@ checksum = "388a1df253eca08550bef6c72392cfe7c30914bf41df5269b68cbd6ff8f570a3" [[package]] name = "serde" -version = "1.0.164" +version = "1.0.183" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9e8c8cf938e98f769bc164923b06dce91cea1751522f46f8466461af04c9027d" +checksum = "32ac8da02677876d532745a130fc9d8e6edfa81a269b107c5b00829b91d8eb3c" +dependencies = [ + "serde_derive", +] + +[[package]] +name = "serde_derive" +version = "1.0.183" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "aafe972d60b0b9bee71a91b92fee2d4fb3c9d7e8f6b179aa99f27203d99a4816" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.28", +] [[package]] name = "serialport" -version = "4.2.1" +version = "4.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "353dc2cbfc67c9a14a89a1292a9d8e819bd51066b083e08c1974ba08e3f48c62" +checksum = "c32634e2bd4311420caa504404a55fad2131292c485c97014cbed89a5899885f" dependencies = [ "CoreFoundation-sys", "IOKit-sys", @@ -2017,8 +2071,8 @@ dependencies = [ "libudev", "mach2", "nix 0.26.2", - "regex 1.8.4", - "scopeguard 1.1.0", + "regex 1.9.3", + "scopeguard 1.2.0", "winapi", ] @@ -2030,9 +2084,9 @@ checksum = "43b2853a4d09f215c24cc5489c992ce46052d359b5109343cbafbf26bc62f8a3" [[package]] name = "simd-adler32" -version = "0.3.5" +version = "0.3.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "238abfbb77c1915110ad968465608b68e869e0772622c9656714e73e5a1a522f" +checksum = "d66dc143e6b11c1eddc06d5c423cfc97062865baf299914ab64caa38182078fe" [[package]] name = "smallvec" @@ -2045,9 +2099,9 @@ dependencies = [ [[package]] name = "smallvec" -version = "1.10.0" +version = "1.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a507befe795404456341dfab10cef66ead4c041f62b8b11bbb92bffe5d0953e0" +checksum = "62bb4feee49fdd9f707ef802e22365a35de4b7b299de4763d44bfea899442ff9" [[package]] name = "smart-leds" @@ -2139,9 +2193,9 @@ dependencies = [ [[package]] name = "syn" -version = "2.0.18" +version = "2.0.28" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "32d41677bcbe24c20c52e7c70b0d8db04134c5d1066bf98662e2871ad200ea3e" +checksum = "04361975b3f5e348b2189d8dc55bc942f278b2d482a6a0365de5bdd62d351567" dependencies = [ "proc-macro2", "quote", @@ -2159,22 +2213,22 @@ dependencies = [ [[package]] name = "thiserror" -version = "1.0.40" +version = "1.0.44" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "978c9a314bd8dc99be594bc3c175faaa9794be04a5a5e153caba6915336cebac" +checksum = "611040a08a0439f8248d1990b111c95baa9c704c805fa1f62104b39655fd7f90" dependencies = [ "thiserror-impl", ] [[package]] name = "thiserror-impl" -version = "1.0.40" +version = "1.0.44" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f9456a42c5b0d803c8cd86e73dd7cc9edd429499f37a3550d286d5e86720569f" +checksum = "090198534930841fab3a5d1bb637cde49e339654e606195f8d9c76eeb081dc96" dependencies = [ "proc-macro2", "quote", - "syn 2.0.18", + "syn 2.0.28", ] [[package]] @@ -2230,15 +2284,15 @@ dependencies = [ [[package]] name = "toml_datetime" -version = "0.6.2" +version = "0.6.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5a76a9312f5ba4c2dec6b9161fdf25d87ad8a09256ccea5a556fef03c706a10f" +checksum = "7cda73e2f1397b1262d6dfdcef8aafae14d1de7748d66822d3bfeeb6d03e5e4b" [[package]] name = "toml_edit" -version = "0.19.10" +version = "0.19.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2380d56e8670370eee6566b0bfd4265f65b3f432e8c6d85623f728d4fa31f739" +checksum = "f8123f27e969974a3dfba720fdb560be359f57b44302d280ba72e76a74480e8a" dependencies = [ "indexmap", "toml_datetime", @@ -2272,9 +2326,9 @@ checksum = "abd2fc5d32b590614af8b0a20d837f32eca055edd0bbead59a9cfe80858be003" [[package]] name = "unicode-ident" -version = "1.0.9" +version = "1.0.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b15811caf2415fb889178633e7724bad2509101cde276048e013b9def5e51fa0" +checksum = "301abaae475aa91687eb82514b328ab47a211a533026cb25fc3e519b86adfc3c" [[package]] name = "usb-device" @@ -2426,7 +2480,7 @@ dependencies = [ "once_cell 1.18.0", "proc-macro2", "quote", - "syn 2.0.18", + "syn 2.0.28", "wasm-bindgen-shared", ] @@ -2460,7 +2514,7 @@ checksum = "54681b18a46765f095758388f2d0cf16eb8d4169b639ab575a8f5693af210c7b" dependencies = [ "proc-macro2", "quote", - "syn 2.0.18", + "syn 2.0.28", "wasm-bindgen-backend", "wasm-bindgen-shared", ] @@ -2533,7 +2587,7 @@ version = "0.48.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e686886bc078bc1b0b600cac0147aadb815089b6e4da64016cbd754b6342700f" dependencies = [ - "windows-targets 0.48.0", + "windows-targets 0.48.1", ] [[package]] @@ -2542,7 +2596,7 @@ version = "0.48.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "677d2418bec65e3338edb076e806bc1ec15693c5d0104683f2efe857f61056a9" dependencies = [ - "windows-targets 0.48.0", + "windows-targets 0.48.1", ] [[package]] @@ -2562,9 +2616,9 @@ dependencies = [ [[package]] name = "windows-targets" -version = "0.48.0" +version = "0.48.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7b1eb6f0cd7c80c79759c929114ef071b87354ce476d9d94271031c0497adfd5" +checksum = "05d4b17490f70499f20b9e791dcf6a299785ce8af4d709018206dc5b4953e95f" dependencies = [ "windows_aarch64_gnullvm 0.48.0", "windows_aarch64_msvc 0.48.0", @@ -2661,9 +2715,9 @@ checksum = "1a515f5799fe4961cb532f983ce2b23082366b898e52ffbce459c86f67c8378a" [[package]] name = "winnow" -version = "0.4.6" +version = "0.5.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "61de7bac303dc551fe038e2b3cef0f571087a47571ea6e79a87692ac99b99699" +checksum = "acaaa1190073b2b101e15083c38ee8ec891b5e05cbee516521e94ec008f61e64" dependencies = [ "memchr", ] diff --git a/fl16-inputmodules/Cargo.toml b/fl16-inputmodules/Cargo.toml index f06404c1..1d06c2bb 100644 --- a/fl16-inputmodules/Cargo.toml +++ b/fl16-inputmodules/Cargo.toml @@ -42,6 +42,20 @@ tinybmp = { workspace = true, optional = true } smart-leds = { workspace = true, optional = true } ws2812-pio = { workspace = true, optional = true } +# Persistent configuration +rp2040-flash = "0.3.1" +#serde = { version = "1.0.183", default-features = false, features = ["derive"]} +serde = { default-features = false, features = [ + "derive", +], version = "1.0" } ##it = "file:///home/zoid/clone/reference/serde", branch = "array-34-100" } +#serde_derive = { default-features = false, features = [ +#], git = "file:///home/zoid/clone/reference/serde", branch = "array-34" } +#serde-big-array = "0.5.1" +#serde_arrays = { version = "0.1.0", default-features = false, git = "https://github.com/jaredwolff/serde_arrays.git", features = [ +# "no-std", +#] } +postcard = "1.0.0" + [features] default = [] ledmatrix = ["is31fl3741"] diff --git a/fl16-inputmodules/src/control.rs b/fl16-inputmodules/src/control.rs index 7aba38bd..13a6355c 100644 --- a/fl16-inputmodules/src/control.rs +++ b/fl16-inputmodules/src/control.rs @@ -41,6 +41,8 @@ use is31fl3741::PwmFreq; #[cfg(feature = "c1minimal")] use smart_leds::{SmartLedsWrite, RGB8}; +use serde::{Deserialize, Serialize}; + #[repr(u8)] #[derive(num_derive::FromPrimitive)] /// All available commands @@ -68,6 +70,7 @@ pub enum CommandVals { SetFps = 0x1A, SetPowerMode = 0x1B, AnimationPeriod = 0x1C, + Save = 0x1D, PwmFreq = 0x1E, Version = 0x20, } @@ -129,7 +132,7 @@ pub enum DisplayMode { } #[cfg(feature = "ledmatrix")] -#[derive(Copy, Clone, num_derive::FromPrimitive)] +#[derive(Copy, Clone, num_derive::FromPrimitive, PartialEq, Eq, Serialize, Deserialize, Debug)] pub enum PwmFreqArg { /// 29kHz P29k = 0x00, @@ -202,6 +205,7 @@ pub enum Command { GetPowerMode, SetAnimationPeriod(u16), GetAnimationPeriod, + Save, #[cfg(feature = "ledmatrix")] SetPwmFreq(PwmFreqArg), GetPwmFreq, @@ -378,6 +382,7 @@ pub fn parse_module_command(count: usize, buf: &[u8]) -> Option { Some(Command::GetAnimationPeriod) } } + Some(CommandVals::Save) => Some(Command::Save), Some(CommandVals::PwmFreq) => { if let Some(freq) = arg { FromPrimitive::from_u8(freq).map(Command::SetPwmFreq) @@ -604,6 +609,8 @@ pub fn handle_command( response[0..2].copy_from_slice(&(period_ms as u16).to_le_bytes()); Some(response) } + // TODO + // Command::Save => None, Command::SetPwmFreq(arg) => { state.pwm_freq = *arg; matrix.device.set_pwm_freq(state.pwm_freq.into()).unwrap(); diff --git a/fl16-inputmodules/src/games/game_of_life.rs b/fl16-inputmodules/src/games/game_of_life.rs index c51d4e15..5f395781 100644 --- a/fl16-inputmodules/src/games/game_of_life.rs +++ b/fl16-inputmodules/src/games/game_of_life.rs @@ -1,13 +1,13 @@ use crate::control::{GameControlArg, GameOfLifeStartParam}; use crate::matrix::{GameState, Grid, LedmatrixState, HEIGHT, WIDTH}; -#[derive(Clone, Copy, num_derive::FromPrimitive)] +#[derive(Clone, Copy, Debug, PartialEq, Eq, num_derive::FromPrimitive)] pub enum Cell { Dead = 0, Alive = 1, } -#[derive(Clone)] +#[derive(Clone, Debug, PartialEq, Eq)] pub struct GameOfLifeState { cells: [[Cell; WIDTH]; HEIGHT], } diff --git a/fl16-inputmodules/src/games/pong.rs b/fl16-inputmodules/src/games/pong.rs index 37a09028..db70d52e 100644 --- a/fl16-inputmodules/src/games/pong.rs +++ b/fl16-inputmodules/src/games/pong.rs @@ -3,7 +3,7 @@ use crate::matrix::{GameState, Grid, LedmatrixState, HEIGHT, WIDTH}; const PADDLE_WIDTH: usize = 5; -#[derive(Clone)] +#[derive(Clone, Debug, PartialEq, Eq)] struct Score { _upper: u8, _lower: u8, @@ -12,14 +12,14 @@ struct Score { type Position = (usize, usize); type Velocity = (i8, i8); -#[derive(Clone)] +#[derive(Clone, Debug, PartialEq, Eq)] struct Ball { pos: Position, // Not a position, more like a directional vector direction: Velocity, } -#[derive(Clone)] +#[derive(Clone, Debug, PartialEq, Eq)] pub struct PongState { // TODO: Properly calculate score and display it _score: Score, diff --git a/fl16-inputmodules/src/games/snake.rs b/fl16-inputmodules/src/games/snake.rs index b985ec65..24380d62 100644 --- a/fl16-inputmodules/src/games/snake.rs +++ b/fl16-inputmodules/src/games/snake.rs @@ -6,7 +6,7 @@ use heapless::Vec; // Wrap around the edges const WRAP_ENABLE: bool = false; -#[derive(Clone, Debug, Copy)] +#[derive(Clone, Copy, Debug, PartialEq, Eq)] pub enum HeadDirection { Up, Down, @@ -16,7 +16,7 @@ pub enum HeadDirection { type Position = (i8, i8); -#[derive(Clone)] +#[derive(Clone, Debug, PartialEq, Eq)] pub struct SnakeState { head: Position, pub direction: HeadDirection, diff --git a/fl16-inputmodules/src/matrix.rs b/fl16-inputmodules/src/matrix.rs index 1bccf4a2..985ccce3 100644 --- a/fl16-inputmodules/src/matrix.rs +++ b/fl16-inputmodules/src/matrix.rs @@ -3,38 +3,101 @@ use crate::games::game_of_life::GameOfLifeState; use crate::games::pong::PongState; use crate::games::snake::SnakeState; +use core::ops::Deref; +use heapless::Vec; +use postcard::{from_bytes, to_vec}; +use serde::{Deserialize, Serialize}; +use rp2040_flash::flash; + pub const WIDTH: usize = 9; pub const HEIGHT: usize = 34; pub const LEDS: usize = WIDTH * HEIGHT; -#[derive(Clone)] -pub struct Grid(pub [[u8; HEIGHT]; WIDTH]); +//#[derive(Clone, Copy, Debug, PartialEq, Eq)] +//pub struct Col( pub [u8; HEIGHT]); +//#[derive(Clone, Debug, PartialEq, Eq, Serialize)] +//pub struct Grid( +// pub [Col; WIDTH], +//); +#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)] +pub struct Grid(pub Vec, WIDTH>); impl Default for Grid { fn default() -> Self { - Grid([[0; HEIGHT]; WIDTH]) + let mut vec: Vec, WIDTH> = Vec::new(); + for _ in 0..WIDTH { + let mut col = Vec::new(); + for _ in 0..HEIGHT { + col.push(0).unwrap(); + } + vec.push(col).unwrap(); + } + Grid(vec) } } +#[derive(Serialize, Deserialize, Debug, PartialEq, Eq)] pub struct LedmatrixState { + pub rev: u16, pub grid: Grid, + #[serde(skip)] pub col_buffer: Grid, pub animate: bool, pub brightness: u8, pub sleeping: SleepState, + #[serde(skip)] pub game: Option, pub animation_period: u64, pub pwm_freq: PwmFreqArg, } +unsafe fn any_as_u8_slice(p: &T) -> &[u8] { + ::core::slice::from_raw_parts( + (p as *const T) as *const u8, + ::core::mem::size_of::(), + ) +} + +impl LedmatrixState { + pub fn save(&self) { + //let foo: Vec()}> = to_vec(&self.grid).unwrap(); + let foo: &[u8] = unsafe {any_as_u8_slice(&self.grid)}; + let mut data: Vec = Vec::new(); + for _ in 0..4096 { + data.push(0); + } + data[0..{core::mem::size_of::()}].copy_from_slice(foo); + let addr = 0xfe000; // 2nd to last 4K sector + cortex_m::interrupt::free(|_cs| { + unsafe {flash::flash_range_erase_and_program(addr, &data, true)}; + }); + } + pub fn restore() -> Grid { + let addr = 0xfe000 + 0x10000000; // 2nd to last 4K sector + unsafe { + //let bytes = *(&*(addr as *const &[u8; 4096])); + //let g: *const Grid = (bytes as *const u8) as *const Grid; + //let g = &*(addr as *const &Grid); + //(*g).clone() + //from_bytes(bytes).unwrap() + } + Grid::default() + } +} + #[allow(clippy::large_enum_variant)] -#[derive(Clone)] +#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)] pub enum SleepState { Awake, Sleeping((Grid, u8)), } +//impl Default for SleepState { +// fn default() -> Self { +// SleepState::Awake +// } +//} #[allow(clippy::large_enum_variant)] -#[derive(Clone)] +#[derive(Clone, Debug, PartialEq, Eq)] pub enum GameState { Snake(SnakeState), Pong(PongState), diff --git a/fl16-inputmodules/src/patterns.rs b/fl16-inputmodules/src/patterns.rs index 5f46b556..55dbedfb 100644 --- a/fl16-inputmodules/src/patterns.rs +++ b/fl16-inputmodules/src/patterns.rs @@ -2,6 +2,7 @@ use rp2040_hal::{ gpio::bank0::{Gpio26, Gpio27}, pac::I2C1, }; +use heapless::Vec; use crate::fl16::LedMatrix; use crate::led_hal as bsp; @@ -51,103 +52,103 @@ pub fn draw_grey_col(grid: &mut Grid, col: u8, levels: &[u8; HEIGHT]) { } pub fn display_sleep() -> Grid { - Grid([ - [ + Grid(Vec::from_slice(&[ + Vec::from_slice(&[ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - ], - [ + ]).unwrap(), + Vec::from_slice(&[ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - ], - [ + ]).unwrap(), + Vec::from_slice(&[ 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, - ], - [ + ]).unwrap(), + Vec::from_slice(&[ 0xFF, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0x00, 0x00, - ], - [ + ]).unwrap(), + Vec::from_slice(&[ 0xFF, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0x00, 0x00, - ], - [ + ]).unwrap(), + Vec::from_slice(&[ 0xFF, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0x00, 0x00, - ], - [ + ]).unwrap(), + Vec::from_slice(&[ 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, - ], - [ + ]).unwrap(), + Vec::from_slice(&[ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - ], - [ + ]).unwrap(), + Vec::from_slice(&[ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - ], - ]) + ]).unwrap(), + ]).unwrap()) } pub fn display_panic() -> Grid { - Grid([ - [ + Grid(Vec::from_slice(&[ + Vec::from_slice(&[ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - ], - [ + ]).unwrap(), + Vec::from_slice(&[ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - ], - [ + ]).unwrap(), + Vec::from_slice(&[ 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xFF, - ], - [ + ]).unwrap(), + Vec::from_slice(&[ 0xFF, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xFF, - ], - [ + ]).unwrap(), + Vec::from_slice(&[ 0xFF, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xFF, - ], - [ + ]).unwrap(), + Vec::from_slice(&[ 0xFF, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xFF, - ], - [ + ]).unwrap(), + Vec::from_slice(&[ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, - ], - [ + ]).unwrap(), + Vec::from_slice(&[ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - ], - [ + ]).unwrap(), + Vec::from_slice(&[ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - ], - ]) + ]).unwrap(), + ]).unwrap()) } pub fn display_lotus() -> Grid { @@ -163,53 +164,53 @@ pub fn display_lotus() -> Grid { } pub fn display_lotus2() -> Grid { - Grid([ - [ + Grid(Vec::from_slice(&[ + Vec::from_slice(&[ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - ], - [ + ]).unwrap(), + Vec::from_slice(&[ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - ], - [ + ]).unwrap(), + Vec::from_slice(&[ 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, - ], - [ + ]).unwrap(), + Vec::from_slice(&[ 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0x00, 0xFF, - ], - [ + ]).unwrap(), + Vec::from_slice(&[ 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0x00, 0xFF, - ], - [ + ]).unwrap(), + Vec::from_slice(&[ 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0x00, 0xFF, - ], - [ + ]).unwrap(), + Vec::from_slice(&[ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0xFF, - ], - [ + ]).unwrap(), + Vec::from_slice(&[ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - ], - [ + ]).unwrap(), + Vec::from_slice(&[ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - ], - ]) + ]).unwrap(), + ]).unwrap()) } pub fn display_letter(pos: usize, grid: &mut Grid, letter: SingleDisplayData) { diff --git a/inputmodule-control/src/inputmodule.rs b/inputmodule-control/src/inputmodule.rs index 6258b94a..29e70ea6 100644 --- a/inputmodule-control/src/inputmodule.rs +++ b/inputmodule-control/src/inputmodule.rs @@ -47,6 +47,7 @@ enum Command { Fps = 0x1A, PowerMode = 0x1B, AnimationPeriod = 0x1C, + Save = 0x1D, PwmFreq = 0x1E, Version = 0x20, } @@ -222,6 +223,10 @@ pub fn serial_commands(args: &crate::ClapCli) { animation_fps_cmd(serialdev, fps); } + if ledmatrix_args.save { + simple_cmd(serialdev, Command::Save, &[]); + } + if let Some(freq) = ledmatrix_args.pwm_freq { pwm_freq_cmd(serialdev, freq); } diff --git a/inputmodule-control/src/ledmatrix.rs b/inputmodule-control/src/ledmatrix.rs index 54317bbb..32daf9f4 100644 --- a/inputmodule-control/src/ledmatrix.rs +++ b/inputmodule-control/src/ledmatrix.rs @@ -126,6 +126,9 @@ pub struct LedMatrixSubcommand { #[arg(long)] pub animation_fps: Option>, + #[arg(long)] + pub save: bool, + /// Set/get PWM Frequency in Hz #[arg(long)] #[clap(value_enum)] diff --git a/ledmatrix/Cargo.toml b/ledmatrix/Cargo.toml index 39711d71..7026babd 100644 --- a/ledmatrix/Cargo.toml +++ b/ledmatrix/Cargo.toml @@ -25,6 +25,9 @@ usbd-serial.workspace = true usbd-hid.workspace = true fugit.workspace = true +# Persistent Configuration +rp2040-flash = "0.3.1" + is31fl3741.workspace = true [dependencies.fl16-inputmodules] diff --git a/ledmatrix/src/main.rs b/ledmatrix/src/main.rs index e632f9b5..bf078f40 100644 --- a/ledmatrix/src/main.rs +++ b/ledmatrix/src/main.rs @@ -7,6 +7,8 @@ use cortex_m::delay::Delay; //use defmt::*; use defmt_rtt as _; use embedded_hal::digital::v2::{InputPin, OutputPin}; +use heapless::Vec; +use rp2040_flash::flash; use rp2040_hal::{ gpio::bank0::Gpio29, @@ -172,6 +174,16 @@ fn main() -> ! { &mut pac.RESETS, ); + let psm = pac.PSM; + + // Reset core1 so it's guaranteed to be running + // ROM code, waiting for the wakeup sequence + psm.frce_off.modify(|_, w| w.proc1().set_bit()); + while !psm.frce_off.read().proc1().bit_is_set() { + cortex_m::asm::nop(); + } + psm.frce_off.modify(|_, w| w.proc1().clear_bit()); + // Set up the USB driver let usb_bus = UsbBusAllocator::new(usb::UsbBus::new( pac.USBCTRL_REGS, @@ -216,6 +228,7 @@ fn main() -> ! { ); let mut state = LedmatrixState { + rev: 0, grid: percentage(0), col_buffer: Grid::default(), animate: false, @@ -321,7 +334,47 @@ fn main() -> ! { Some(p) if p <= 100 && STARTUP_ANIMATION => { state.grid = percentage(p); startup_percentage = Some(p + 5); + + if p == 100 { + let addr = 0xfe000 + 0x10000000; // 2nd to last 4K sector + let ptr = unsafe { addr as *const [u8; 4096] }; + let _ = serial.write(b"Before restoring\n\r"); + unsafe { + let read = ptr.as_ref().unwrap(); + let _ = serial.write(b"After restoring\n\r"); + // TODO: Use checksum instead + if read[0] == 0x32 && read[1] == 0xAC { + state.grid.0[0] = + Vec::from_slice(&read[4 + 34 * 0..4 + 34 * 1]).unwrap(); + state.grid.0[1] = + Vec::from_slice(&read[4 + 34 * 1..4 + 34 * 2]).unwrap(); + state.grid.0[2] = + Vec::from_slice(&read[4 + 34 * 2..4 + 34 * 3]).unwrap(); + state.grid.0[3] = + Vec::from_slice(&read[4 + 34 * 3..4 + 34 * 4]).unwrap(); + state.grid.0[4] = + Vec::from_slice(&read[4 + 34 * 4..4 + 34 * 5]).unwrap(); + state.grid.0[5] = + Vec::from_slice(&read[4 + 34 * 5..4 + 34 * 6]).unwrap(); + state.grid.0[6] = + Vec::from_slice(&read[4 + 34 * 6..4 + 34 * 7]).unwrap(); + state.grid.0[7] = + Vec::from_slice(&read[4 + 34 * 7..4 + 34 * 8]).unwrap(); + state.grid.0[8] = + Vec::from_slice(&read[4 + 34 * 8..4 + 34 * 9]).unwrap(); + let mut text: String<64> = String::new(); + write!( + &mut text, + "Read text '{:?}, {}, {}, {}, {}, {}, {}'\r\n", + read[0], read[1], read[2], read[3], read[4], read[5], read[6] + ) + .unwrap(); + let _ = serial.write(text.as_bytes()); + } + } + } } + _ => {} } @@ -370,6 +423,68 @@ fn main() -> ! { (Some(c @ Command::BootloaderReset), _) => { handle_command(&c, &mut state, &mut matrix, random); } + (Some(Command::Save), _) => { + let jedec_id: u32 = unsafe { + cortex_m::interrupt::free(|_cs| flash::flash_jedec_id(true)) + }; + let mut unique_id = [0u8; 8]; + unsafe { + cortex_m::interrupt::free(|_cs| { + flash::flash_unique_id(&mut unique_id, true) + }) + }; + let mut text: String<64> = String::new(); + write!( + &mut text, + "JEDEC ID {:x?}, Unique ID {:x?}\n\r", + jedec_id, unique_id + ) + .unwrap(); + + let _ = serial.write(text.as_bytes()); + let mut data: [u8; 4096] = [0xFF; 4096]; + data[0] = 0x32; + data[1] = 0xAC; + data[4 + 34 * 0..4 + 34 * 1] + .copy_from_slice(state.grid.0[0].as_slice()); + data[4 + 34 * 1..4 + 34 * 2] + .copy_from_slice(state.grid.0[1].as_slice()); + data[4 + 34 * 2..4 + 34 * 3] + .copy_from_slice(state.grid.0[2].as_slice()); + data[4 + 34 * 3..4 + 34 * 4] + .copy_from_slice(state.grid.0[3].as_slice()); + data[4 + 34 * 4..4 + 34 * 5] + .copy_from_slice(state.grid.0[4].as_slice()); + data[4 + 34 * 5..4 + 34 * 6] + .copy_from_slice(state.grid.0[5].as_slice()); + data[4 + 34 * 6..4 + 34 * 7] + .copy_from_slice(state.grid.0[6].as_slice()); + data[4 + 34 * 7..4 + 34 * 8] + .copy_from_slice(state.grid.0[7].as_slice()); + data[4 + 34 * 8..4 + 34 * 9] + .copy_from_slice(state.grid.0[8].as_slice()); + let _ = serial.write(b"Before saving\n\r"); + core::sync::atomic::compiler_fence( + core::sync::atomic::Ordering::SeqCst, + ); + cortex_m::interrupt::free(|_cs| { + unsafe { + flash::flash_range_erase_and_program(0xfe000, &data, true) + }; + }); + core::sync::atomic::compiler_fence( + core::sync::atomic::Ordering::SeqCst, + ); + let _ = serial.write(b"After saving\n\r"); + let mut text: String<64> = String::new(); + write!( + &mut text, + "Write text '{:?}, {}, {}, {}, {}, {}, {}'\r\n", + data[0], data[1], data[2], data[3], data[4], data[5], data[6] + ) + .unwrap(); + let _ = serial.write(text.as_bytes()); + } (Some(command), _) => { if let Command::Sleep(go_sleeping) = command { sleeping = go_sleeping;