diff --git a/Cargo.lock b/Cargo.lock index 46fcbb0..4892c03 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3,16 +3,19 @@ version = 4 [[package]] -name = "allocator-api2" -version = "0.3.1" +name = "aead" +version = "0.4.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c583acf993cf4245c4acb0a2cc2ab1f9cc097de73411bb6d3647ff6af2b1013d" +checksum = "0b613b8e1e3cf911a086f53f03bf286f52fd7a7258e4fa606f0ef220d39d8877" +dependencies = [ + "generic-array", +] [[package]] -name = "anyhow" -version = "1.0.100" +name = "allocator-api2" +version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a23eb6b1614318a8071c9b2521f36b424b2c83db5eb3a0fead4a6c0809af6e61" +checksum = "c583acf993cf4245c4acb0a2cc2ab1f9cc097de73411bb6d3647ff6af2b1013d" [[package]] name = "autocfg" @@ -89,6 +92,12 @@ version = "3.19.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5dd9dc738b7a8311c7ade152424974d8115f2cdad61e8dab8dac9f2362298510" +[[package]] +name = "byte" +version = "0.2.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "21c7ab3e4ae80853c7f8dcdcd904dfa25c02cc373534b8d165194325a088a7cc" + [[package]] name = "bytemuck" version = "1.24.0" @@ -101,12 +110,33 @@ version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" +[[package]] +name = "ccm" +version = "0.4.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0a9cf981c7e62b6fb02225592ee7ebf221e0b0b5317984a57a1e9d21af20e317" +dependencies = [ + "aead", + "cipher", + "ctr", + "subtle", +] + [[package]] name = "cfg-if" version = "1.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9330f8b2ff13f34540b44e946ef35111825727b38d33286ef986142615121801" +[[package]] +name = "cipher" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7ee52072ec15386f770805afd189a01c8841be8696bed250fa2f13c4c0d6dfb7" +dependencies = [ + "generic-array", +] + [[package]] name = "const-default" version = "1.0.0" @@ -135,12 +165,16 @@ dependencies = [ "bt-hci", "critical-section", "defmt 1.0.1", + "embassy-embedded-hal", "embassy-executor", "embassy-net", + "embassy-sync 0.7.2", "embassy-time", "embedded-hal 1.0.0", + "embedded-hal-async", "embedded-io 0.7.1", "embedded-io-async 0.7.0", + "embedded-sdmmc", "esp-alloc", "esp-backtrace", "esp-bootloader-esp-idf", @@ -164,6 +198,15 @@ dependencies = [ "typenum", ] +[[package]] +name = "ctr" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "049bb91fb4aaf0e3c7efa6cd5ef877dbbbd15b39dad06d9948de4ec8a75761ea" +dependencies = [ + "cipher", +] + [[package]] name = "darling" version = "0.20.11" @@ -328,6 +371,26 @@ dependencies = [ "crypto-common", ] +[[package]] +name = "docsplay" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8547ea80db62c5bb9d7796fcce5e6e07d1136bdc1a02269095061e806758fab4" +dependencies = [ + "docsplay-macros", +] + +[[package]] +name = "docsplay-macros" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "11772ed3eb3db124d826f3abeadf5a791a557f62c19b123e3f07288158a71fdd" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.114", +] + [[package]] name = "document-features" version = "0.2.12" @@ -586,6 +649,19 @@ dependencies = [ "embedded-nal", ] +[[package]] +name = "embedded-sdmmc" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ce3c7f9ea039eeafc4a49597b7bd5ae3a1c8e51b2803a381cb0f29ce90fe1ec6" +dependencies = [ + "byteorder", + "defmt 0.3.100", + "embedded-hal 1.0.0", + "embedded-io 0.6.1", + "heapless 0.8.0", +] + [[package]] name = "embedded-storage" version = "0.3.1" @@ -632,8 +708,7 @@ checksum = "877a4ace8713b0bcf2a4e7eec82529c029f1d0619886d18145fea96c3ffe5c0f" [[package]] name = "esp-alloc" version = "0.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "641e43d6a60244429117ef2fa7a47182120c7561336ea01f6fb08d634f46bae1" +source = "git+https://github.com/esp-rs/esp-hal.git?rev=109324ac4c5f8d0788b01ce7a27ac3045570f696#109324ac4c5f8d0788b01ce7a27ac3045570f696" dependencies = [ "allocator-api2", "cfg-if", @@ -649,8 +724,7 @@ dependencies = [ [[package]] name = "esp-backtrace" version = "0.18.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3318413fb566c7227387f67736cf70cd74d80a11f2bb31c7b95a9eb48d079669" +source = "git+https://github.com/esp-rs/esp-hal.git?rev=109324ac4c5f8d0788b01ce7a27ac3045570f696#109324ac4c5f8d0788b01ce7a27ac3045570f696" dependencies = [ "cfg-if", "defmt 1.0.1", @@ -666,8 +740,7 @@ dependencies = [ [[package]] name = "esp-bootloader-esp-idf" version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "02a56964ab5479ac20c9cf76fa3b0d3f2233b20b5d8554e81ef5d65f63c20567" +source = "git+https://github.com/esp-rs/esp-hal.git?rev=109324ac4c5f8d0788b01ce7a27ac3045570f696#109324ac4c5f8d0788b01ce7a27ac3045570f696" dependencies = [ "cfg-if", "defmt 1.0.1", @@ -684,8 +757,7 @@ dependencies = [ [[package]] name = "esp-config" version = "0.6.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "102871054f8dd98202177b9890cb4b71d0c6fe1f1413b7a379a8e0841fc2473c" +source = "git+https://github.com/esp-rs/esp-hal.git?rev=109324ac4c5f8d0788b01ce7a27ac3045570f696#109324ac4c5f8d0788b01ce7a27ac3045570f696" dependencies = [ "document-features", "esp-metadata-generated", @@ -697,8 +769,7 @@ dependencies = [ [[package]] name = "esp-hal" version = "1.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "54786287c0a61ca0f78cb0c338a39427551d1be229103b4444591796c579e093" +source = "git+https://github.com/esp-rs/esp-hal.git?rev=109324ac4c5f8d0788b01ce7a27ac3045570f696#109324ac4c5f8d0788b01ce7a27ac3045570f696" dependencies = [ "bitfield", "bitflags 2.10.0", @@ -729,6 +800,7 @@ dependencies = [ "esp32", "esp32c2", "esp32c3", + "esp32c5", "esp32c6", "esp32h2", "esp32s2", @@ -750,8 +822,7 @@ dependencies = [ [[package]] name = "esp-hal-procmacros" version = "0.21.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3e025a7a7a0affdb4ff913b5c4494aef96ee03d085bf83c27453ae3a71d50da6" +source = "git+https://github.com/esp-rs/esp-hal.git?rev=109324ac4c5f8d0788b01ce7a27ac3045570f696#109324ac4c5f8d0788b01ce7a27ac3045570f696" dependencies = [ "document-features", "proc-macro-crate", @@ -764,14 +835,12 @@ dependencies = [ [[package]] name = "esp-metadata-generated" version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9a93e39c8ad8d390d248dc7b9f4b59a873f313bf535218b8e2351356972399e3" +source = "git+https://github.com/esp-rs/esp-hal.git?rev=109324ac4c5f8d0788b01ce7a27ac3045570f696#109324ac4c5f8d0788b01ce7a27ac3045570f696" [[package]] name = "esp-phy" version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6b1facf348e1e251517278fc0f5dc134e95e518251f5796cfbb532ca226a29bf" +source = "git+https://github.com/esp-rs/esp-hal.git?rev=109324ac4c5f8d0788b01ce7a27ac3045570f696#109324ac4c5f8d0788b01ce7a27ac3045570f696" dependencies = [ "cfg-if", "defmt 1.0.1", @@ -780,14 +849,13 @@ dependencies = [ "esp-hal", "esp-metadata-generated", "esp-sync", - "esp-wifi-sys", + "esp-wifi-sys-esp32c3", ] [[package]] name = "esp-println" version = "0.16.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5a30e6c9fbcc01c348d46706fef8131c7775ab84c254a3cd65d0cd3f6414d592" +source = "git+https://github.com/esp-rs/esp-hal.git?rev=109324ac4c5f8d0788b01ce7a27ac3045570f696#109324ac4c5f8d0788b01ce7a27ac3045570f696" dependencies = [ "defmt 1.0.1", "document-features", @@ -800,13 +868,14 @@ dependencies = [ [[package]] name = "esp-radio" version = "0.17.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "684c4de2f8907b73c9b891fbda65286a86d34fced4b856f36a7896c211f2f265" +source = "git+https://github.com/esp-rs/esp-hal.git?rev=109324ac4c5f8d0788b01ce7a27ac3045570f696#109324ac4c5f8d0788b01ce7a27ac3045570f696" dependencies = [ "allocator-api2", "bt-hci", "cfg-if", + "critical-section", "defmt 1.0.1", + "docsplay", "document-features", "embassy-net-driver", "embedded-io 0.6.1", @@ -822,8 +891,15 @@ dependencies = [ "esp-phy", "esp-radio-rtos-driver", "esp-sync", - "esp-wifi-sys", + "esp-wifi-sys-esp32", + "esp-wifi-sys-esp32c2", + "esp-wifi-sys-esp32c3", + "esp-wifi-sys-esp32c6", + "esp-wifi-sys-esp32h2", + "esp-wifi-sys-esp32s2", + "esp-wifi-sys-esp32s3", "heapless 0.9.2", + "ieee802154", "instability", "num-derive", "num-traits", @@ -835,14 +911,17 @@ dependencies = [ [[package]] name = "esp-radio-rtos-driver" version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "543bc31d1851afd062357e7810c1a9633f282fd3993583499a841ab497cbca6c" +source = "git+https://github.com/esp-rs/esp-hal.git?rev=109324ac4c5f8d0788b01ce7a27ac3045570f696#109324ac4c5f8d0788b01ce7a27ac3045570f696" +dependencies = [ + "cfg-if", + "esp-sync", + "portable-atomic", +] [[package]] name = "esp-riscv-rt" version = "0.13.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "502744a5b1e7268d27fd2a4e56ad45efe42ead517d6c517a6961540de949b0ee" +source = "git+https://github.com/esp-rs/esp-hal.git?rev=109324ac4c5f8d0788b01ce7a27ac3045570f696#109324ac4c5f8d0788b01ce7a27ac3045570f696" dependencies = [ "defmt 1.0.1", "document-features", @@ -853,8 +932,7 @@ dependencies = [ [[package]] name = "esp-rom-sys" version = "0.1.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cd66cccc6dd2d13e9f33668a57717ab14a6d217180ec112e6be533de93e7ecbf" +source = "git+https://github.com/esp-rs/esp-hal.git?rev=109324ac4c5f8d0788b01ce7a27ac3045570f696#109324ac4c5f8d0788b01ce7a27ac3045570f696" dependencies = [ "cfg-if", "document-features", @@ -864,8 +942,7 @@ dependencies = [ [[package]] name = "esp-rtos" version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "162ec711c8d06e79c67b75d01595539e86b0aac209643af98ca87a12250428b3" +source = "git+https://github.com/esp-rs/esp-hal.git?rev=109324ac4c5f8d0788b01ce7a27ac3045570f696#109324ac4c5f8d0788b01ce7a27ac3045570f696" dependencies = [ "allocator-api2", "cfg-if", @@ -881,15 +958,17 @@ dependencies = [ "esp-hal-procmacros", "esp-metadata-generated", "esp-radio-rtos-driver", + "esp-rom-sys", "esp-sync", "portable-atomic", + "riscv", + "xtensa-lx", ] [[package]] name = "esp-sync" version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d44974639b4e88914f83fe60d2832c00276657d7d857628fdfc966cc7302e8a8" +source = "git+https://github.com/esp-rs/esp-hal.git?rev=109324ac4c5f8d0788b01ce7a27ac3045570f696#109324ac4c5f8d0788b01ce7a27ac3045570f696" dependencies = [ "cfg-if", "defmt 1.0.1", @@ -902,20 +981,72 @@ dependencies = [ ] [[package]] -name = "esp-wifi-sys" -version = "0.8.1" +name = "esp-wifi-sys-esp32" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dfa62cf4d74d2639852bf3502909fc650ecc21a350a8a6369f6263273dd6188c" +dependencies = [ + "defmt 1.0.1", +] + +[[package]] +name = "esp-wifi-sys-esp32c2" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "39f14de1f9211c208e2bbbde0db1c1b84261061673cb49b3bd835409190981a6" +dependencies = [ + "defmt 1.0.1", +] + +[[package]] +name = "esp-wifi-sys-esp32c3" +version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "89b6544f6f0cb86169d1f93ba2101a8d50358a040c5043676ed86b793e09b12c" +checksum = "a2ff0e720a85a1b5dfcb777084e145f8cc1877fa596cf5f448f1536f520d6e24" +dependencies = [ + "defmt 1.0.1", +] + +[[package]] +name = "esp-wifi-sys-esp32c6" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "be3706b97351a35bd47d392e8a8afb7725b56714c3c1d7071038144e2f8d3a83" +dependencies = [ + "defmt 1.0.1", +] + +[[package]] +name = "esp-wifi-sys-esp32h2" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f7c5fb8e69b4c3c6ae6e3dda54758739eb38d8191c2ebb30d511e8b9bd204b25" +dependencies = [ + "defmt 1.0.1", +] + +[[package]] +name = "esp-wifi-sys-esp32s2" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1f456e2e9fadc17dd751ea235cad8ad07ab0033ed4bd00083e6e073f16b86ce3" +dependencies = [ + "defmt 1.0.1", +] + +[[package]] +name = "esp-wifi-sys-esp32s3" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1777e3b1b5e69d3a8ef528db54f63cac11d7991252863f5dc4bf0a727dd81c5b" dependencies = [ - "anyhow", "defmt 1.0.1", ] [[package]] name = "esp32" version = "0.39.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b76170a463d18f888a1ad258031901036fd827a9ef126733053ba5f8739fb0c8" +source = "git+https://github.com/esp-rs/esp-pacs?rev=5d7a479#5d7a47921f25d96ab3ddd4a16bad31543bc9a8be" dependencies = [ "critical-section", "defmt 1.0.1", @@ -925,8 +1056,7 @@ dependencies = [ [[package]] name = "esp32c2" version = "0.28.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e62cf8932966b8d445b6f1832977b468178f0a84effb2e9fda89f60c24d45aa3" +source = "git+https://github.com/esp-rs/esp-pacs?rev=5d7a479#5d7a47921f25d96ab3ddd4a16bad31543bc9a8be" dependencies = [ "critical-section", "defmt 1.0.1", @@ -936,8 +1066,17 @@ dependencies = [ [[package]] name = "esp32c3" version = "0.31.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "356af3771d0d6536c735bf71136594f4d1cbb506abf6e0c51a6639e9bf4e7988" +source = "git+https://github.com/esp-rs/esp-pacs?rev=5d7a479#5d7a47921f25d96ab3ddd4a16bad31543bc9a8be" +dependencies = [ + "critical-section", + "defmt 1.0.1", + "vcell", +] + +[[package]] +name = "esp32c5" +version = "0.1.0" +source = "git+https://github.com/esp-rs/esp-pacs?rev=035a5e4#035a5e47c5adcb40844a0c5007cb5de1d23e9af0" dependencies = [ "critical-section", "defmt 1.0.1", @@ -947,8 +1086,7 @@ dependencies = [ [[package]] name = "esp32c6" version = "0.22.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8f5e511df672d79cd63365c92045135e01ba952b6bddd25b660baff5e1110f6b" +source = "git+https://github.com/esp-rs/esp-pacs?rev=5d7a479#5d7a47921f25d96ab3ddd4a16bad31543bc9a8be" dependencies = [ "critical-section", "defmt 1.0.1", @@ -958,8 +1096,7 @@ dependencies = [ [[package]] name = "esp32h2" version = "0.18.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ed4a50bbd1380931e095e0973b9b12f782a9c481f2edf1f7c42e7eb4ff736d6d" +source = "git+https://github.com/esp-rs/esp-pacs?rev=5d7a479#5d7a47921f25d96ab3ddd4a16bad31543bc9a8be" dependencies = [ "critical-section", "defmt 1.0.1", @@ -969,8 +1106,7 @@ dependencies = [ [[package]] name = "esp32s2" version = "0.30.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "98574d4c577fbe888fe3e6df7fc80d25a05624d9998f7d7de1500ae21fcca78f" +source = "git+https://github.com/esp-rs/esp-pacs?rev=5d7a479#5d7a47921f25d96ab3ddd4a16bad31543bc9a8be" dependencies = [ "critical-section", "defmt 1.0.1", @@ -980,8 +1116,7 @@ dependencies = [ [[package]] name = "esp32s3" version = "0.34.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1810d8ee4845ef87542af981e38eb80ab531d0ef1061e1486014ab7af74c337a" +source = "git+https://github.com/esp-rs/esp-pacs?rev=5d7a479#5d7a47921f25d96ab3ddd4a16bad31543bc9a8be" dependencies = [ "critical-section", "defmt 1.0.1", @@ -1091,6 +1226,15 @@ dependencies = [ "version_check", ] +[[package]] +name = "hash32" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b0c35f58762feb77d74ebe43bdbc3210f09be9fe6742234d573bacc26ed92b67" +dependencies = [ + "byteorder", +] + [[package]] name = "hash32" version = "0.3.1" @@ -1100,6 +1244,17 @@ dependencies = [ "byteorder", ] +[[package]] +name = "hash32-derive" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "59d2aba832b60be25c1b169146b27c64115470981b128ed84c8db18c1b03c6ff" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.109", +] + [[package]] name = "hashbrown" version = "0.16.1" @@ -1113,7 +1268,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0bfb9eb618601c89945a70e254898da93b13be0388091d42117462b265bb3fad" dependencies = [ "defmt 0.3.100", - "hash32", + "hash32 0.3.1", "stable_deref_trait", ] @@ -1124,7 +1279,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2af2455f757db2b292a9b1768c4b70186d443bcb3b316252d6b540aec1cd89ed" dependencies = [ "defmt 1.0.1", - "hash32", + "hash32 0.3.1", "stable_deref_trait", ] @@ -1140,6 +1295,20 @@ version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b9e0384b61958566e926dc50660321d12159025e767c18e043daf26b70104c39" +[[package]] +name = "ieee802154" +version = "0.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4fcb6de62f20180795db19ae2ab338852a66f8576581554fa8a730e437b450a5" +dependencies = [ + "byte", + "ccm", + "cipher", + "defmt 0.3.100", + "hash32 0.2.1", + "hash32-derive", +] + [[package]] name = "indexmap" version = "2.13.0" @@ -1617,6 +1786,12 @@ dependencies = [ "syn 2.0.114", ] +[[package]] +name = "subtle" +version = "2.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6bdef32e8150c2a081110b42772ffe7d7c9032b606bc226c8260fd97e0976601" + [[package]] name = "svgbobdoc" version = "0.3.0" @@ -1889,8 +2064,7 @@ dependencies = [ [[package]] name = "xtensa-lx" version = "0.13.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e012d667b0aa6d2592ace8ef145a98bff3e76cca7a644f4181ecd7a916ed289b" +source = "git+https://github.com/esp-rs/esp-hal.git?rev=109324ac4c5f8d0788b01ce7a27ac3045570f696#109324ac4c5f8d0788b01ce7a27ac3045570f696" dependencies = [ "critical-section", ] @@ -1898,8 +2072,7 @@ dependencies = [ [[package]] name = "xtensa-lx-rt" version = "0.21.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8709f037fb123fe7ff146d2bce86f9dc0dfc53045c016bfd9d703317b6502845" +source = "git+https://github.com/esp-rs/esp-hal.git?rev=109324ac4c5f8d0788b01ce7a27ac3045570f696#109324ac4c5f8d0788b01ce7a27ac3045570f696" dependencies = [ "defmt 1.0.1", "document-features", @@ -1910,8 +2083,7 @@ dependencies = [ [[package]] name = "xtensa-lx-rt-proc-macros" version = "0.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "96fb42cd29c42f8744c74276e9f5bee7b06685bbe5b88df891516d72cb320450" +source = "git+https://github.com/esp-rs/esp-hal.git?rev=109324ac4c5f8d0788b01ce7a27ac3045570f696#109324ac4c5f8d0788b01ce7a27ac3045570f696" dependencies = [ "proc-macro2", "quote", diff --git a/Cargo.toml b/Cargo.toml index f69930a..3ca8fc8 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -9,18 +9,17 @@ name = "crustpoint" path = "./src/main.rs" [dependencies] -esp-hal = { version = "~1.0", features = ["defmt", "esp32c3", "unstable"] } +# Need a prerelease version of esp-hal to get access to GPIO pins 12-17. Other esp crates need to follow that version. Update to stable after 1.0.0 when those GPIO pins are stable. +esp-hal = { version = "1.0.0", features = ["defmt", "esp32c3", "unstable"], git = "https://github.com/esp-rs/esp-hal.git", rev = "109324ac4c5f8d0788b01ce7a27ac3045570f696" } +esp-rtos = { version = "0.2.0", features = ["defmt", "embassy", "esp-alloc", "esp-radio", "esp32c3"], git = "https://github.com/esp-rs/esp-hal.git", rev = "109324ac4c5f8d0788b01ce7a27ac3045570f696" } +esp-alloc = { version = "0.9.0", features = ["defmt"], git = "https://github.com/esp-rs/esp-hal.git", rev = "109324ac4c5f8d0788b01ce7a27ac3045570f696" } +esp-backtrace = { version = "0.18.1", features = ["defmt", "esp32c3", "panic-handler"], git = "https://github.com/esp-rs/esp-hal.git", rev = "109324ac4c5f8d0788b01ce7a27ac3045570f696" } +esp-println = { version = "0.16.1", features = ["defmt-espflash", "esp32c3"], git = "https://github.com/esp-rs/esp-hal.git", rev = "109324ac4c5f8d0788b01ce7a27ac3045570f696" } +esp-bootloader-esp-idf = { version = "0.4.0", features = ["defmt", "esp32c3"], git = "https://github.com/esp-rs/esp-hal.git", rev = "109324ac4c5f8d0788b01ce7a27ac3045570f696" } +esp-radio = { version = "0.17.0", features = ["ble", "coex", "defmt", "esp-alloc", "esp32c3", "smoltcp", "unstable", "wifi"], git = "https://github.com/esp-rs/esp-hal.git", rev = "109324ac4c5f8d0788b01ce7a27ac3045570f696" } -esp-rtos = { version = "0.2.0", features = [ - "defmt", - "embassy", - "esp-alloc", - "esp-radio", - "esp32c3", -] } defmt = "1.0.1" -esp-bootloader-esp-idf = { version = "0.4.0", features = ["defmt", "esp32c3"] } embassy-net = { version = "0.7.1", features = [ "defmt", @@ -30,28 +29,10 @@ embassy-net = { version = "0.7.1", features = [ "udp", ] } embedded-io = { version = "0.7.1", features = ["defmt"] } -embedded-io-async = { version = "0.7.0", features = ["defmt"] } -esp-alloc = { version = "0.9.0", features = ["defmt"] } -esp-backtrace = { version = "0.18.1", features = [ - "defmt", - "esp32c3", - "panic-handler", -] } -esp-println = { version = "0.16.1", features = ["defmt-espflash", "esp32c3"] } -# for more networking protocol support see https://crates.io/crates/edge-net +embedded-io-async = { version = "0.7.0", features = ["defmt"] }# for more networking protocol support see https://crates.io/crates/edge-net bt-hci = "0.6.0" embassy-executor = { version = "0.9.1", features = ["defmt"] } embassy-time = { version = "0.5.0", features = ["defmt"] } -esp-radio = { version = "0.17.0", features = [ - "ble", - "coex", - "defmt", - "esp-alloc", - "esp32c3", - "smoltcp", - "unstable", - "wifi", -] } smoltcp = { version = "0.12.0", default-features = false, features = [ "defmt", "medium-ethernet", @@ -71,6 +52,11 @@ critical-section = "1.2.0" static_cell = "2.1.1" embedded-hal = "1.0.0" thiserror = { version = "2.0.18", default-features = false } +# For SD card +embedded-sdmmc = { version = "0.9.0", features = ["defmt-log"], default-features = false } +embassy-embedded-hal = "0.5.0" +embassy-sync = "0.7.2" +embedded-hal-async = "1.0.0" [profile.dev] diff --git a/src/eink_display/error.rs b/src/eink_display/error.rs index 3b2c3f0..46ec717 100644 --- a/src/eink_display/error.rs +++ b/src/eink_display/error.rs @@ -1,4 +1,5 @@ use embassy_time::TimeoutError; +use embedded_hal::spi::Error; use esp_hal::{dma::DmaBufError, spi}; #[derive(Debug, thiserror::Error, defmt::Format)] @@ -13,30 +14,30 @@ pub(crate) enum CreateError { #[derive(Debug, thiserror::Error)] #[error("Failed to send command")] -pub(crate) struct SendCommandError(pub(super) spi::Error); +pub(crate) struct SendCommandError(#[from] pub(super) E); #[derive(Debug, thiserror::Error)] #[error("Failed to send data")] -pub(crate) struct SendDataError(pub(super) spi::Error); +pub(crate) struct SendDataError(#[from] pub(super) E); #[derive(Debug, thiserror::Error)] -pub(crate) enum SetRamAreaError { +pub(crate) enum SetRamAreaError { #[error("Failed to send command")] - SendCommand(#[from] SendCommandError), + SendCommand(#[from] SendCommandError), #[error("Failed to send data")] - SendData(#[from] SendDataError), + SendData(#[from] SendDataError), } #[derive(Debug, thiserror::Error)] -pub(crate) enum InitializeControllerError { +pub(crate) enum InitializeControllerError { #[error("Failed to send command")] - SendCommand(#[from] SendCommandError), + SendCommand(#[from] SendCommandError), #[error("Failed to send data")] - SendData(#[from] SendDataError), + SendData(#[from] SendDataError), #[error("Timed out waiting for busy")] WaitForBusy(#[from] WaitForBusyTimeoutError), #[error("Failed to set RAM area")] - SetRamArea(#[from] SetRamAreaError), + SetRamArea(#[from] SetRamAreaError), } #[derive(Debug, thiserror::Error, defmt::Format)] @@ -44,41 +45,41 @@ pub(crate) enum InitializeControllerError { pub(crate) struct WaitForBusyTimeoutError(pub(super) TimeoutError); #[derive(Debug, thiserror::Error)] -pub(crate) enum InitializationError { +pub(crate) enum InitializationError { #[error("Failed to create e-ink display driver instance")] Create(#[from] CreateError), #[error("Failed to initialize e-ink display controller")] - InitializeController(#[from] InitializeControllerError), + InitializeController(#[from] InitializeControllerError), } #[derive(Debug, thiserror::Error)] -pub(crate) enum RefreshError { +pub(crate) enum RefreshError { #[error("Failed to send command")] - SendCommand(#[from] SendCommandError), + SendCommand(#[from] SendCommandError), #[error("Failed to send data")] - SendData(#[from] SendDataError), + SendData(#[from] SendDataError), #[error("Failed to wait for busy")] WaitForBusy(#[from] WaitForBusyTimeoutError), } #[derive(Debug, thiserror::Error)] -pub(crate) enum DisplayError { +pub(crate) enum DisplayError { #[error("Failed to set RAM area")] - SetRamArea(#[from] SetRamAreaError), + SetRamArea(#[from] SetRamAreaError), #[error("Failed to send command")] - SendCommand(#[from] SendCommandError), + SendCommand(#[from] SendCommandError), #[error("Failed to send data")] - SendData(#[from] SendDataError), + SendData(#[from] SendDataError), #[error("Failed to refresh display")] - Refresh(#[from] RefreshError), + Refresh(#[from] RefreshError), } #[derive(Debug, thiserror::Error)] -pub(crate) enum EnterDeepSleepError { +pub(crate) enum EnterDeepSleepError { #[error("Failed to send command")] - SendCommand(#[from] SendCommandError), + SendCommand(#[from] SendCommandError), #[error("Failed to send data")] - SendData(#[from] SendDataError), + SendData(#[from] SendDataError), #[error("Failed to wait for busy")] WaitForBusy(#[from] WaitForBusyTimeoutError), } diff --git a/src/eink_display/mod.rs b/src/eink_display/mod.rs index 8468d19..3f989b8 100644 --- a/src/eink_display/mod.rs +++ b/src/eink_display/mod.rs @@ -1,21 +1,9 @@ -use crate::eink_display::error::{ - CreateError, DisplayError, EnterDeepSleepError, InitializationError, InitializeControllerError, - RefreshError, SendCommandError, SendDataError, SetRamAreaError, WaitForBusyTimeoutError, -}; +pub(crate) use crate::eink_display::error::*; + use defmt::info; use embassy_time::{Duration, Timer, with_timeout}; -use esp_hal::{ - Async, - dma::{DmaChannelFor, DmaRxBuf, DmaTxBuf}, - dma_buffers, - gpio::{ - Input, InputConfig, InputPin, Level, Output, OutputConfig, OutputPin, - interconnect::PeripheralOutput, - }, - spi::master::{AnySpi, Config, Instance, Spi, SpiDmaBus}, - time::Rate, -}; - +use embedded_hal_async::spi::SpiDevice; +use esp_hal::gpio::{Input, InputConfig, InputPin, Level, Output, OutputConfig, OutputPin}; mod error; #[derive(Debug, defmt::Format)] @@ -61,8 +49,8 @@ enum ControlMode { BypassRed = 0x40, } -pub(super) struct EinkDisplay<'d> { - spi: SpiDmaBus<'d, Async>, +pub(super) struct EinkDisplay<'d, SPI: SpiDevice> { + spi: SPI, reset: Output<'d>, /// Based on usage this pin is used to select between data and command mode. /// When set to low, the pin is in command mode to send commands. @@ -79,61 +67,27 @@ pub(super) enum RefreshMode { HalfRefresh, } -impl<'d> EinkDisplay<'d> { - const DISPLAY_WIDTH: u16 = 800; - const DISPLAY_HEIGHT: u16 = 480; - const DISPLAY_WIDTH_BYTES: usize = { - // There is no div_exact yet - assert!( - Self::DISPLAY_WIDTH % 8 == 0, - "Display width must be a multiple of 8" - ); +const DISPLAY_WIDTH: u16 = 800; +const DISPLAY_HEIGHT: u16 = 480; +const DISPLAY_WIDTH_BYTES: usize = { + // There is no div_exact yet + assert!( + DISPLAY_WIDTH % 8 == 0, + "Display width must be a multiple of 8" + ); - Self::DISPLAY_WIDTH.strict_div(8) as usize - }; + DISPLAY_WIDTH.strict_div(8) as usize +}; - pub(crate) const BUFFER_SIZE: usize = - Self::DISPLAY_WIDTH_BYTES.strict_mul(Self::DISPLAY_HEIGHT as usize); +pub(crate) const BUFFER_SIZE: usize = DISPLAY_WIDTH_BYTES.strict_mul(DISPLAY_HEIGHT as usize); +impl<'d, SPI: SpiDevice> EinkDisplay<'d, SPI> { fn new( - spi: impl Instance + 'd, - serial_clock: impl PeripheralOutput<'d>, - master_out_slave_in: impl PeripheralOutput<'d>, - chip_select: impl PeripheralOutput<'d>, - direct_memory_access_channel: impl DmaChannelFor>, + spi: SPI, reset: impl OutputPin + 'd, data_command: impl OutputPin + 'd, busy: impl InputPin + 'd, ) -> Result { - // DMA = Direct Memory Access - let (receive_buffer, receive_descriptor, transmit_buffer, transmit_descriptors) = - dma_buffers!(32_000); - let direct_memory_access_receive_buffer = DmaRxBuf::new(receive_descriptor, receive_buffer) - .map_err(CreateError::DmaReceiveBuffer)?; - let direct_memory_access_transmit_buffer = - DmaTxBuf::new(transmit_descriptors, transmit_buffer) - .map_err(CreateError::DmaTransmitBuffer)?; - - // Initialize SPI with custom pins - let spi = Spi::new( - spi, - Config::default() - .with_frequency(Rate::from_mhz(40)) - .with_mode(esp_hal::spi::Mode::_0) - .with_read_bit_order(esp_hal::spi::BitOrder::MsbFirst), // .with_write_bit_order(esp_hal::spi::BitOrder::MsbFirst) - )? - .with_sck(serial_clock) - .with_mosi(master_out_slave_in) - // MISO might be pin 7? https://github.com/juicecultus/ariel-os/blob/a2816b156b632b2633801df45d69c8fe9dde500c/examples/x4-launcher/src/main.rs#L943 - // .with_miso(todo!("Not defined in XteinkX4 screen spec")) - .with_cs(chip_select) - .with_dma(direct_memory_access_channel) - .with_buffers( - direct_memory_access_receive_buffer, - direct_memory_access_transmit_buffer, - ) - .into_async(); - // Set up GPIO pins let reset = Output::new(reset, Level::Low, OutputConfig::default()); let data_command = Output::new(data_command, Level::High, OutputConfig::default()); @@ -142,7 +96,6 @@ impl<'d> EinkDisplay<'d> { InputConfig::default().with_pull(esp_hal::gpio::Pull::Down), ); - info!("Size: {}", Self::BUFFER_SIZE); Ok(Self { spi, reset, @@ -165,26 +118,20 @@ impl<'d> EinkDisplay<'d> { info!("Display reset completed"); } - async fn send_command(&mut self, command: Command) -> Result<(), SendCommandError> { + async fn send_command(&mut self, command: Command) -> Result<(), SendCommandError> { info!("Sending command: {:?}", command); // Set into command mode self.data_command.set_low(); - self.spi - .write_async(&[command as u8]) - .await - .map_err(SendCommandError)?; + self.spi.write(&[command as u8]).await?; info!("Command sent"); Ok(()) } - async fn send_data(&mut self, data: impl AsRef<[u8]>) -> Result<(), SendDataError> { + async fn send_data(&mut self, data: &[u8]) -> Result<(), SendDataError> { info!("Sending data: {:?}", data.as_ref().len()); // Set into data mode self.data_command.set_high(); - self.spi - .write_async(data.as_ref()) - .await - .map_err(SendDataError)?; + self.spi.write(data).await?; info!("Data sent"); Ok(()) } @@ -202,13 +149,13 @@ impl<'d> EinkDisplay<'d> { y: u16, width: u16, height: u16, - ) -> Result<(), SetRamAreaError> { + ) -> Result<(), SetRamAreaError> { // Data entry x increment y decrement??? const DATA_ENTRY_X_INC_Y_DEC: u8 = 0x01; //TODO overflow safety // Reverse Y coordinate (gates are reversed on this display) - let y = Self::DISPLAY_HEIGHT - y - height; + let y = DISPLAY_HEIGHT - y - height; self.send_command(Command::DataEntryMode).await?; self.send_data(&[DATA_ENTRY_X_INC_Y_DEC]).await?; @@ -252,7 +199,7 @@ impl<'d> EinkDisplay<'d> { Ok(()) } - async fn initialize_controller(&mut self) -> Result<(), InitializeControllerError> { + async fn initialize_controller(&mut self) -> Result<(), InitializeControllerError> { info!("Initializing SSD1677 controller"); // Soft reset @@ -277,9 +224,9 @@ impl<'d> EinkDisplay<'d> { // Driver output control: set display height (480) and scan direction self.send_command(Command::DriverOutputControl).await?; //TODO safer casting - self.send_data(&[((Self::DISPLAY_HEIGHT - 1) % 256) as u8]) + self.send_data(&[((DISPLAY_HEIGHT - 1) % 256) as u8]) .await?; - self.send_data(&[((Self::DISPLAY_HEIGHT - 1) / 256) as u8]) + self.send_data(&[((DISPLAY_HEIGHT - 1) / 256) as u8]) .await?; self.send_data(&[0x02]).await?; @@ -288,7 +235,7 @@ impl<'d> EinkDisplay<'d> { self.send_data(&[0x01]).await?; // Set up full screen RAM area - self.set_ram_area(0, 0, Self::DISPLAY_WIDTH, Self::DISPLAY_HEIGHT) + self.set_ram_area(0, 0, DISPLAY_WIDTH, DISPLAY_HEIGHT) .await?; info!("Clearing RAM buffers"); @@ -307,26 +254,13 @@ impl<'d> EinkDisplay<'d> { } pub(super) async fn initialize( - spi: impl Instance + 'd, - serial_clock: impl PeripheralOutput<'d>, - master_out_slave_in: impl PeripheralOutput<'d>, - chip_select: impl PeripheralOutput<'d>, - direct_memory_access_channel: impl DmaChannelFor>, + spi: SPI, reset: impl OutputPin + 'd, data_command: impl OutputPin + 'd, busy: impl InputPin + 'd, - ) -> Result { + ) -> Result> { info!("Initializing e-ink display driver"); - let mut this = Self::new( - spi, - serial_clock, - master_out_slave_in, - chip_select, - direct_memory_access_channel, - reset, - data_command, - busy, - )?; + let mut this = Self::new(spi, reset, data_command, busy)?; this.reset().await; @@ -341,7 +275,7 @@ impl<'d> EinkDisplay<'d> { &mut self, mode: RefreshMode, turn_screen_off: bool, - ) -> Result<(), RefreshError> { + ) -> Result<(), RefreshError> { // Configure Display Update Control 1 self.send_command(Command::DisplayUpdateControl1).await?; // Configure buffer comparison mode @@ -425,15 +359,15 @@ impl<'d> EinkDisplay<'d> { pub(crate) async fn display( &mut self, mut refresh_mode: RefreshMode, - frame_buffer: &[u8; EinkDisplay::BUFFER_SIZE], - ) -> Result<(), DisplayError> { + frame_buffer: &[u8], + ) -> Result<(), DisplayError> { if !self.is_screen_on { // Force half refresh if screen is off refresh_mode = RefreshMode::HalfRefresh; } // Set up full screen RAM area - self.set_ram_area(0, 0, Self::DISPLAY_WIDTH, Self::DISPLAY_HEIGHT) + self.set_ram_area(0, 0, DISPLAY_WIDTH, DISPLAY_HEIGHT) .await?; match refresh_mode { @@ -459,7 +393,7 @@ impl<'d> EinkDisplay<'d> { Ok(()) } - pub(crate) async fn enter_deep_sleep(&mut self) -> Result<(), EnterDeepSleepError> { + pub(crate) async fn enter_deep_sleep(&mut self) -> Result<(), EnterDeepSleepError> { info!("Preparing display to enter deep sleep"); // First, power down the display properly // This shuts down the analog power rails and clock diff --git a/src/main.rs b/src/main.rs index 2c94423..36fbf6a 100644 --- a/src/main.rs +++ b/src/main.rs @@ -8,10 +8,14 @@ #![deny(clippy::large_stack_frames)] mod eink_display; +mod spi; + +use core::error; use defmt::{error, info}; use embassy_executor::Spawner; use embassy_time::{Duration, Timer}; +use embedded_hal_async::spi::SpiDevice; use esp_hal::clock::CpuClock; use esp_hal::timer::timg::TimerGroup; use {esp_backtrace as _, esp_println as _}; @@ -32,14 +36,32 @@ async fn hello_world() { } } -#[allow( - clippy::large_stack_frames, - reason = "it's not unusual to allocate larger buffers etc. in main" -)] -#[esp_rtos::main] -async fn main(_spawner: Spawner) { - // generator version: 1.2.0 +#[derive(Debug, thiserror::Error)] +enum ApplicationError { + #[error("Error setting up SPI")] + SetUpSpi(#[from] spi::SetUpError), + #[error("Error setting up e-ink display")] + SetUpEinkDisplay( + eink_display::InitializationError< + as embedded_hal_async::spi::ErrorType>::Error, + >, + ), + #[error("Error displaying on e-ink display")] + Display( + eink_display::DisplayError< + as embedded_hal_async::spi::ErrorType>::Error, + >, + ), + #[error("Error setting entering display deep sleep")] + EnterDeepSleep( + eink_display::EnterDeepSleepError< + as embedded_hal_async::spi::ErrorType>::Error, + >, + ), +} +/// Just a convenience replacement for main to be able to return errors +async fn run(_spawner: Spawner) -> Result<(), ApplicationError> { let config = esp_hal::Config::default().with_cpu_clock(CpuClock::max()); let peripherals = esp_hal::init(config); @@ -60,8 +82,9 @@ async fn main(_spawner: Spawner) { let serial_clock = peripherals.GPIO8; // SPI Master Out Slave In (MOSI) let master_out_slave_in = peripherals.GPIO10; - // Chip Select (CS) - let chip_select = peripherals.GPIO21; + let master_in_slave_out = peripherals.GPIO7; + // Display Chip Select (CS) + let display_chip_select = peripherals.GPIO21; // Data/Command (DC) let data_command = peripherals.GPIO4; // Reset (RST) @@ -70,42 +93,51 @@ async fn main(_spawner: Spawner) { let busy = peripherals.GPIO6; let direct_memory_access_channel = peripherals.DMA_CH0; - let mut display = EinkDisplay::initialize( + let sd_card_chip_select = peripherals.GPIO12; + + let (display_spi, _sd_card_spi) = spi::set_up_devices( peripherals.SPI2, serial_clock, master_out_slave_in, - chip_select, + master_in_slave_out, direct_memory_access_channel, - reset, - data_command, - busy, - ) - .await - .inspect_err(|_error| error!("Error initializing display")) - .expect("Failed to initialize display"); + display_chip_select, + sd_card_chip_select, + )?; + + info!("Initializing display"); + + let mut display = EinkDisplay::initialize(display_spi, reset, data_command, busy) + .await + .map_err(ApplicationError::SetUpEinkDisplay)?; display .display( eink_display::RefreshMode::Full, - &[0xFF; EinkDisplay::BUFFER_SIZE], + &[0x00; eink_display::BUFFER_SIZE], ) .await - .inspect_err(|error| error!("Error displaying {:?}", defmt::Debug2Format(&error))) - .expect("Failed to display"); + .map_err(ApplicationError::Display)?; display .enter_deep_sleep() .await - .inspect_err(|error| { - error!( - "Error starting deep sleep {:?}", - defmt::Debug2Format(&error) - ) - }) - .expect("Failed to start deep sleep"); - - // Task test + .map_err(ApplicationError::EnterDeepSleep)?; // for inspiration have a look at the examples at https://github.com/esp-rs/esp-hal/tree/esp-hal-v1.0.0/examples - info!("COMPLETED"); + + Ok(()) +} + +#[allow( + clippy::large_stack_frames, + reason = "it's not unusual to allocate larger buffers etc. in main" +)] +#[esp_rtos::main] +async fn main(spawner: Spawner) { + let result = run(spawner).await; + if let Err(error) = result { + error!("Main failed: {:?}", defmt::Debug2Format(&error)); + } + info!("Main completed"); } diff --git a/src/spi.rs b/src/spi.rs new file mode 100644 index 0000000..02d4c62 --- /dev/null +++ b/src/spi.rs @@ -0,0 +1,78 @@ +use embassy_embedded_hal::shared_bus::asynch::spi::SpiDevice; +use embassy_sync::{blocking_mutex::raw::NoopRawMutex, mutex::Mutex}; +use esp_hal::{ + Async, + dma::{DmaBufError, DmaChannelFor, DmaRxBuf, DmaTxBuf}, + dma_buffers, + gpio::{ + Level, Output, OutputConfig, OutputPin, + interconnect::{PeripheralInput, PeripheralOutput}, + }, + spi::master::{AnySpi, Config, ConfigError, Instance, Spi, SpiDmaBus}, + time::Rate, +}; +use static_cell::StaticCell; + +#[derive(Debug, thiserror::Error)] +pub(crate) enum SetUpError { + #[error("Failed to create direct memory access (DMA) receive channel buffer")] + DmaReceiveBuffer(DmaBufError), + #[error("Failed to create direct memory access (DMA) transmit channel buffer")] + DmaTransmitBuffer(DmaBufError), + #[error("Failed to create SPI bus")] + SpiBus(#[from] ConfigError), +} +pub(crate) type Device<'a> = SpiDevice<'a, NoopRawMutex, SpiDmaBus<'a, Async>, Output<'a>>; + +pub(crate) fn set_up_devices( + spi: impl Instance + 'static, + serial_clock: impl PeripheralOutput<'static>, + master_out_slave_in: impl PeripheralOutput<'static>, + master_in_slave_out: impl PeripheralInput<'static>, + direct_memory_access_channel: impl DmaChannelFor>, + display_chip_select: impl OutputPin + 'static, + sd_card_chip_select: impl OutputPin + 'static, +) -> Result<(Device<'static>, Device<'static>), SetUpError> { + let configuration = Config::default() + .with_frequency(Rate::from_mhz(40)) + .with_mode(esp_hal::spi::Mode::_0) + .with_read_bit_order(esp_hal::spi::BitOrder::MsbFirst); + + // DMA = Direct Memory Access + let (receive_buffer, receive_descriptor, transmit_buffer, transmit_descriptors) = + dma_buffers!(32_000); + let direct_memory_access_receive_buffer = + DmaRxBuf::new(receive_descriptor, receive_buffer).map_err(SetUpError::DmaReceiveBuffer)?; + let direct_memory_access_transmit_buffer = DmaTxBuf::new(transmit_descriptors, transmit_buffer) + .map_err(SetUpError::DmaTransmitBuffer)?; + + // Not sure if the embassy wrapper for sharing calls duplicates work the esp_hal SPI is already doing. Hopefully it uses the DMA too but I think it should. + let spi = Spi::new(spi, configuration)? + .with_sck(serial_clock) + .with_mosi(master_out_slave_in) + .with_miso(master_in_slave_out) + // Do not configure chip select (cs) pin as that is different depending on the device + .with_dma(direct_memory_access_channel) + .with_buffers( + direct_memory_access_receive_buffer, + direct_memory_access_transmit_buffer, + ) + .into_async(); + + // Choosing to share the bus using embassy_embedded_hal over embedded_hal_bus to allow for async operations + // Set up SPI bus sharing between devices with embassy + static SPI_BUS: StaticCell>> = StaticCell::new(); + let spi_bus = Mutex::new(spi); + let spi_bus = SPI_BUS.init(spi_bus); + + let display_chip_select = + Output::new(display_chip_select, Level::High, OutputConfig::default()); + + let display_spi = SpiDevice::new(spi_bus, display_chip_select); + + let sd_card_chip_select = + Output::new(sd_card_chip_select, Level::High, OutputConfig::default()); + let sd_card_spi = SpiDevice::new(spi_bus, sd_card_chip_select); + + Ok((display_spi, sd_card_spi)) +}