From 69dcb051e0033f8d2c906c3f62dba3989f12da78 Mon Sep 17 00:00:00 2001 From: Wouter Geraedts Date: Tue, 9 Apr 2024 15:01:27 +0200 Subject: [PATCH] Added esp32c6 support and example --- examples/esp32c6/.cargo/config.toml | 15 + examples/esp32c6/Cargo.lock | 917 ++++++++++++++++++++ examples/esp32c6/Cargo.toml | 24 + examples/esp32c6/README.md | 33 + examples/esp32c6/examples/sw_and_hw.rs | 66 ++ examples/esp32c6/rust-toolchain.toml | 4 + rtic-macros/Cargo.toml | 1 + rtic-macros/src/codegen/bindings.rs | 7 + rtic-macros/src/codegen/bindings/esp32c6.rs | 249 ++++++ rtic-macros/src/lib.rs | 2 + rtic-macros/src/syntax/backend.rs | 7 + rtic-macros/src/syntax/backend/esp32c6.rs | 16 + rtic/Cargo.toml | 2 + rtic/build.rs | 3 + rtic/src/export.rs | 5 + rtic/src/export/riscv_esp32c6.rs | 161 ++++ xtask/src/argument_parsing.rs | 14 +- 17 files changed, 1524 insertions(+), 2 deletions(-) create mode 100644 examples/esp32c6/.cargo/config.toml create mode 100644 examples/esp32c6/Cargo.lock create mode 100644 examples/esp32c6/Cargo.toml create mode 100644 examples/esp32c6/README.md create mode 100644 examples/esp32c6/examples/sw_and_hw.rs create mode 100644 examples/esp32c6/rust-toolchain.toml create mode 100644 rtic-macros/src/codegen/bindings/esp32c6.rs create mode 100644 rtic-macros/src/syntax/backend/esp32c6.rs create mode 100644 rtic/src/export/riscv_esp32c6.rs diff --git a/examples/esp32c6/.cargo/config.toml b/examples/esp32c6/.cargo/config.toml new file mode 100644 index 0000000000..ba9bb54049 --- /dev/null +++ b/examples/esp32c6/.cargo/config.toml @@ -0,0 +1,15 @@ +[target.riscv32imac-unknown-none-elf] +runner = "espflash flash --monitor" + +[build] +rustflags = [ + "-C", "link-arg=-Tlinkall.x", + # Required to obtain backtraces (e.g. when using the "esp-backtrace" crate.) + # NOTE: May negatively impact performance of produced code + "-C", "force-frame-pointers", +] + +target = "riscv32imac-unknown-none-elf" + +[unstable] +build-std = ["core"] diff --git a/examples/esp32c6/Cargo.lock b/examples/esp32c6/Cargo.lock new file mode 100644 index 0000000000..395d50fda9 --- /dev/null +++ b/examples/esp32c6/Cargo.lock @@ -0,0 +1,917 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 3 + +[[package]] +name = "adler" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe" + +[[package]] +name = "aho-corasick" +version = "1.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e60d3430d3a69478ad0993f19238d2df97c507009a52b3c10addcd7f6bcb916" +dependencies = [ + "memchr", +] + +[[package]] +name = "anyhow" +version = "1.0.81" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0952808a6c2afd1aa8947271f3a60f1a6763c7b912d210184c5149b5cf147247" + +[[package]] +name = "atomic-polyfill" +version = "1.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8cf2bce30dfe09ef0bfaef228b9d414faaf7e563035494d7fe092dba54b300f4" +dependencies = [ + "critical-section", +] + +[[package]] +name = "autocfg" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" + +[[package]] +name = "bare-metal" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f8fe8f5a8a398345e52358e18ff07cc17a568fbca5c6f73873d3a62056309603" + +[[package]] +name = "basic-toml" +version = "0.1.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "823388e228f614e9558c6804262db37960ec8821856535f5c3f59913140558f8" +dependencies = [ + "serde", +] + +[[package]] +name = "bitfield" +version = "0.14.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2d7e60934ceec538daadb9d8432424ed043a904d8e0243f3c6446bce549a46ac" + +[[package]] +name = "bitflags" +version = "2.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cf4b9d6a944f767f8e5e0db018570623c85f3d925ac718db4e06d0187adb21c1" + +[[package]] +name = "byteorder" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" + +[[package]] +name = "cfg-if" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" + +[[package]] +name = "core-isa-parser" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "23ec98e54b735872e54b2335c2e5a5c7fa7d9c3bfd45500f75280f84089a0083" +dependencies = [ + "anyhow", + "enum-as-inner", + "regex", + "strum 0.24.1", + "strum_macros 0.24.3", +] + +[[package]] +name = "crc32fast" +version = "1.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b3855a8a784b474f333699ef2bbca9db2c4a1f6d9088a90a2d25b1eb53111eaa" +dependencies = [ + "cfg-if", +] + +[[package]] +name = "critical-section" +version = "1.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7059fff8937831a9ae6f0fe4d658ffabf58f2ca96aa9dec1c889f936f705f216" + +[[package]] +name = "darling" +version = "0.20.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "54e36fcd13ed84ffdfda6f5be89b31287cbb80c439841fe69e04841435464391" +dependencies = [ + "darling_core", + "darling_macro", +] + +[[package]] +name = "darling_core" +version = "0.20.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9c2cf1c23a687a1feeb728783b993c4e1ad83d99f351801977dd809b48d0a70f" +dependencies = [ + "fnv", + "ident_case", + "proc-macro2", + "quote", + "strsim", + "syn 2.0.53", +] + +[[package]] +name = "darling_macro" +version = "0.20.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a668eda54683121533a393014d8692171709ff57a7d61f187b6e782719f8933f" +dependencies = [ + "darling_core", + "quote", + "syn 2.0.53", +] + +[[package]] +name = "derive_more" +version = "0.99.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4fb810d30a7c1953f91334de7244731fc3f3c10d7fe163338a35b9f640960321" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "document-features" +version = "0.2.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ef5282ad69563b5fc40319526ba27e0e7363d552a896f0297d54f767717f9b95" +dependencies = [ + "litrs", +] + +[[package]] +name = "embedded-dma" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "994f7e5b5cb23521c22304927195f236813053eb9c065dd2226a32ba64695446" +dependencies = [ + "stable_deref_trait", +] + +[[package]] +name = "embedded-hal" +version = "0.2.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "35949884794ad573cf46071e41c9b60efb0cb311e3ca01f7af807af1debc66ff" +dependencies = [ + "nb 0.1.3", + "void", +] + +[[package]] +name = "embedded-hal" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "361a90feb7004eca4019fb28352a9465666b24f840f5c3cddf0ff13920590b89" + +[[package]] +name = "enum-as-inner" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "21cdad81446a7f7dc43f6a77409efeb9733d2fa65553efef6018ef257c959b73" +dependencies = [ + "heck", + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "enumset" +version = "1.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "226c0da7462c13fb57e5cc9e0dc8f0635e7d27f276a3a7fd30054647f669007d" +dependencies = [ + "enumset_derive", +] + +[[package]] +name = "enumset_derive" +version = "0.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e08b6c6ab82d70f08844964ba10c7babb716de2ecaeab9be5717918a5177d3af" +dependencies = [ + "darling", + "proc-macro2", + "quote", + "syn 2.0.53", +] + +[[package]] +name = "equivalent" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5" + +[[package]] +name = "esp-backtrace" +version = "0.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dda6c53c50ed96cce44e8565bd7659f8884d55bac3262184c3a77f748553e3ff" +dependencies = [ + "esp-println", +] + +[[package]] +name = "esp-hal" +version = "0.16.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cc3e9b3333d2ae42f5c9b4890e162cb756fb1b067ab5f642b89fc9f29be424fa" +dependencies = [ + "basic-toml", + "bitfield", + "bitflags", + "cfg-if", + "critical-section", + "document-features", + "embedded-dma", + "embedded-hal 0.2.7", + "enumset", + "esp-hal-procmacros", + "esp-riscv-rt", + "esp32", + "esp32c2", + "esp32c3", + "esp32c6", + "esp32h2", + "esp32p4", + "esp32s2", + "esp32s3", + "fugit", + "nb 1.1.0", + "paste", + "portable-atomic", + "rand_core", + "riscv", + "serde", + "strum 0.26.2", + "void", + "xtensa-lx-rt", +] + +[[package]] +name = "esp-hal-procmacros" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "05084ecf8446fe60e0aff6c3873c96dca56dc383a449324ca555edbb80ae60c0" +dependencies = [ + "darling", + "document-features", + "litrs", + "object", + "proc-macro-crate", + "proc-macro-error", + "proc-macro2", + "quote", + "syn 2.0.53", +] + +[[package]] +name = "esp-println" +version = "0.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e98f0f58453dd2ce08d99228fc8757fad39d05dfd26643665d1093b8844f42cc" + +[[package]] +name = "esp-riscv-rt" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e599762d31156fa2322db4d5a0784c13b6122b79c1fa7bed70953de2f7d731f1" +dependencies = [ + "document-features", + "riscv", + "riscv-rt-macros", +] + +[[package]] +name = "esp32" +version = "0.29.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "343ac30c4537d3f8526490db4264091a9785a55bcdfc22fc34482751a501d8d2" +dependencies = [ + "critical-section", + "vcell", + "xtensa-lx", +] + +[[package]] +name = "esp32-c6" +version = "0.1.0" +dependencies = [ + "esp-backtrace", + "esp-hal", + "esp-println", + "esp32c6", + "rtic", +] + +[[package]] +name = "esp32c2" +version = "0.18.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "55e30c9147b7a1f388887dfd2fe7da4d6159a0248603674af5f3a5282a46cd11" +dependencies = [ + "critical-section", + "vcell", +] + +[[package]] +name = "esp32c3" +version = "0.21.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4a7ee710c1e4f16b5e840cdfec3f4e7642b7517a877c5c4b7e1cafa9a14117c5" +dependencies = [ + "critical-section", + "vcell", +] + +[[package]] +name = "esp32c6" +version = "0.12.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ff0275425ea3a7675b7b5903163a93b65e8ce5b9c8a7749ed397279ed2ade3e3" +dependencies = [ + "critical-section", + "vcell", +] + +[[package]] +name = "esp32h2" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e606c8e60d3e68afda997fa9fcc8d8fe1d2e3c172505bb03eb9ab79b4bca4d6a" +dependencies = [ + "critical-section", + "vcell", +] + +[[package]] +name = "esp32p4" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c03c0bc7973e6805e3c3c3c979e9418ba30380d8c16989a477440dbce8cf1965" +dependencies = [ + "critical-section", + "vcell", +] + +[[package]] +name = "esp32s2" +version = "0.20.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0fbcb8e9a4097fbf1c455fc776ad46a4bb7861d5bad3c3cd4549b666ad906ce4" +dependencies = [ + "critical-section", + "vcell", + "xtensa-lx", +] + +[[package]] +name = "esp32s3" +version = "0.24.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "044e216560a33aa5d6c98163c8ae4278845ec3bae7b9cab520da0697be4f23a6" +dependencies = [ + "critical-section", + "vcell", + "xtensa-lx", +] + +[[package]] +name = "flate2" +version = "1.0.28" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "46303f565772937ffe1d394a4fac6f411c6013172fadde9dcdb1e147a086940e" +dependencies = [ + "crc32fast", + "miniz_oxide", +] + +[[package]] +name = "fnv" +version = "1.0.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" + +[[package]] +name = "fugit" +version = "0.3.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "17186ad64927d5ac8f02c1e77ccefa08ccd9eaa314d5a4772278aa204a22f7e7" +dependencies = [ + "gcd", +] + +[[package]] +name = "gcd" +version = "2.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1d758ba1b47b00caf47f24925c0074ecb20d6dfcffe7f6d53395c0465674841a" + +[[package]] +name = "hashbrown" +version = "0.14.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "290f1a1d9242c78d09ce40a5e87e7554ee637af1351968159f4952f028f75604" + +[[package]] +name = "heck" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "95505c38b4572b2d910cecb0281560f54b440a19336cbbcb27bf6ce6adc6f5a8" + +[[package]] +name = "ident_case" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b9e0384b61958566e926dc50660321d12159025e767c18e043daf26b70104c39" + +[[package]] +name = "indexmap" +version = "2.2.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7b0b929d511467233429c45a44ac1dcaa21ba0f5ba11e4879e6ed28ddb4f9df4" +dependencies = [ + "equivalent", + "hashbrown", +] + +[[package]] +name = "litrs" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b4ce301924b7887e9d637144fdade93f9dfff9b60981d4ac161db09720d39aa5" +dependencies = [ + "proc-macro2", +] + +[[package]] +name = "lock_api" +version = "0.4.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3c168f8615b12bc01f9c17e2eb0cc07dcae1940121185446edc3744920e8ef45" +dependencies = [ + "autocfg", + "scopeguard", +] + +[[package]] +name = "memchr" +version = "2.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "523dc4f511e55ab87b694dc30d0f820d60906ef06413f93d4d7a1385599cc149" + +[[package]] +name = "minijinja" +version = "1.0.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fe5b00f90b3542f74bb9aaaccd2627920c16367787de103883461365580e5481" +dependencies = [ + "serde", +] + +[[package]] +name = "miniz_oxide" +version = "0.7.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9d811f3e15f28568be3407c8e7fdb6514c1cda3cb30683f15b6a1a1dc4ea14a7" +dependencies = [ + "adler", +] + +[[package]] +name = "mutex-trait" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b4bb1638d419e12f8b1c43d9e639abd0d1424285bdea2f76aa231e233c63cd3a" + +[[package]] +name = "nb" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "801d31da0513b6ec5214e9bf433a77966320625a37860f910be265be6e18d06f" +dependencies = [ + "nb 1.1.0", +] + +[[package]] +name = "nb" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8d5439c4ad607c3c23abf66de8c8bf57ba8adcd1f129e699851a6e43935d339d" + +[[package]] +name = "object" +version = "0.33.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d8dd6c0cdf9429bce006e1362bfce61fa1bfd8c898a643ed8d2b471934701d3d" +dependencies = [ + "flate2", + "memchr", + "ruzstd", +] + +[[package]] +name = "paste" +version = "1.0.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "de3145af08024dea9fa9914f381a17b8fc6034dfb00f3a84013f7ff43f29ed4c" + +[[package]] +name = "portable-atomic" +version = "1.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7170ef9988bc169ba16dd36a7fa041e5c4cbeb6a35b76d4c03daded371eae7c0" + +[[package]] +name = "proc-macro-crate" +version = "3.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6d37c51ca738a55da99dc0c4a34860fd675453b8b36209178c2249bb13651284" +dependencies = [ + "toml_edit", +] + +[[package]] +name = "proc-macro-error" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "da25490ff9892aab3fcf7c36f08cfb902dd3e71ca0f9f9517bea02a73a5ce38c" +dependencies = [ + "proc-macro-error-attr", + "proc-macro2", + "quote", + "syn 1.0.109", + "version_check", +] + +[[package]] +name = "proc-macro-error-attr" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a1be40180e52ecc98ad80b184934baf3d0d29f979574e439af5a55274b35f869" +dependencies = [ + "proc-macro2", + "quote", + "version_check", +] + +[[package]] +name = "proc-macro2" +version = "1.0.79" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e835ff2298f5721608eb1a980ecaee1aef2c132bf95ecc026a11b7bf3c01c02e" +dependencies = [ + "unicode-ident", +] + +[[package]] +name = "quote" +version = "1.0.35" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "291ec9ab5efd934aaf503a6466c5d5251535d108ee747472c3977cc5acc868ef" +dependencies = [ + "proc-macro2", +] + +[[package]] +name = "r0" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bd7a31eed1591dcbc95d92ad7161908e72f4677f8fabf2a32ca49b4237cbf211" + +[[package]] +name = "rand_core" +version = "0.6.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" + +[[package]] +name = "regex" +version = "1.10.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b62dbe01f0b06f9d8dc7d49e05a0785f153b00b2c227856282f671e0318c9b15" +dependencies = [ + "aho-corasick", + "memchr", + "regex-automata", + "regex-syntax", +] + +[[package]] +name = "regex-automata" +version = "0.4.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "86b83b8b9847f9bf95ef68afb0b8e6cdb80f498442f5179a29fad448fcc1eaea" +dependencies = [ + "aho-corasick", + "memchr", + "regex-syntax", +] + +[[package]] +name = "regex-syntax" +version = "0.8.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c08c74e62047bb2de4ff487b251e4a92e24f48745648451635cec7d591162d9f" + +[[package]] +name = "riscv" +version = "0.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2f5c1b8bf41ea746266cdee443d1d1e9125c86ce1447e1a2615abd34330d33a9" +dependencies = [ + "critical-section", + "embedded-hal 1.0.0", +] + +[[package]] +name = "riscv-rt-macros" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a8d100d466dbb76681ef6a9386f3da9abc570d57394e86da0ba5af8c4408486d" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "rtic" +version = "2.1.1" +dependencies = [ + "atomic-polyfill", + "bare-metal", + "critical-section", + "esp32c6", + "riscv", + "rtic-core", + "rtic-macros", +] + +[[package]] +name = "rtic-core" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d9369355b04d06a3780ec0f51ea2d225624db777acbc60abd8ca4832da5c1a42" + +[[package]] +name = "rtic-macros" +version = "2.1.0" +dependencies = [ + "indexmap", + "proc-macro-error", + "proc-macro2", + "quote", + "syn 2.0.53", +] + +[[package]] +name = "rustversion" +version = "1.0.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7ffc183a10b4478d04cbbbfc96d0873219d962dd5accaff2ffbd4ceb7df837f4" + +[[package]] +name = "ruzstd" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5174a470eeb535a721ae9fdd6e291c2411a906b96592182d05217591d5c5cf7b" +dependencies = [ + "byteorder", + "derive_more", + "twox-hash", +] + +[[package]] +name = "scopeguard" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" + +[[package]] +name = "serde" +version = "1.0.197" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3fb1c873e1b9b056a4dc4c0c198b24c3ffa059243875552b2bd0933b1aee4ce2" +dependencies = [ + "serde_derive", +] + +[[package]] +name = "serde_derive" +version = "1.0.197" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7eb0b34b42edc17f6b7cac84a52a1c5f0e1bb2227e997ca9011ea3dd34e8610b" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.53", +] + +[[package]] +name = "spin" +version = "0.9.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6980e8d7511241f8acf4aebddbb1ff938df5eebe98691418c4468d0b72a96a67" +dependencies = [ + "lock_api", +] + +[[package]] +name = "stable_deref_trait" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a8f112729512f8e442d81f95a8a7ddf2b7c6b8a1a6f509a95864142b30cab2d3" + +[[package]] +name = "static_assertions" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f" + +[[package]] +name = "strsim" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623" + +[[package]] +name = "strum" +version = "0.24.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "063e6045c0e62079840579a7e47a355ae92f60eb74daaf156fb1e84ba164e63f" + +[[package]] +name = "strum" +version = "0.26.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5d8cec3501a5194c432b2b7976db6b7d10ec95c253208b45f83f7136aa985e29" +dependencies = [ + "strum_macros 0.26.2", +] + +[[package]] +name = "strum_macros" +version = "0.24.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e385be0d24f186b4ce2f9982191e7101bb737312ad61c1f2f984f34bcf85d59" +dependencies = [ + "heck", + "proc-macro2", + "quote", + "rustversion", + "syn 1.0.109", +] + +[[package]] +name = "strum_macros" +version = "0.26.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c6cf59daf282c0a494ba14fd21610a0325f9f90ec9d1231dea26bcb1d696c946" +dependencies = [ + "heck", + "proc-macro2", + "quote", + "rustversion", + "syn 2.0.53", +] + +[[package]] +name = "syn" +version = "1.0.109" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[package]] +name = "syn" +version = "2.0.53" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7383cd0e49fff4b6b90ca5670bfd3e9d6a733b3f90c686605aa7eec8c4996032" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[package]] +name = "toml_datetime" +version = "0.6.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3550f4e9685620ac18a50ed434eb3aec30db8ba93b0287467bca5826ea25baf1" + +[[package]] +name = "toml_edit" +version = "0.21.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6a8534fd7f78b5405e860340ad6575217ce99f38d4d5c8f2442cb5ecb50090e1" +dependencies = [ + "indexmap", + "toml_datetime", + "winnow", +] + +[[package]] +name = "twox-hash" +version = "1.6.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "97fee6b57c6a41524a810daee9286c02d7752c4253064d0b05472833a438f675" +dependencies = [ + "cfg-if", + "static_assertions", +] + +[[package]] +name = "unicode-ident" +version = "1.0.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" + +[[package]] +name = "vcell" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "77439c1b53d2303b20d9459b1ade71a83c716e3f9c34f3228c00e6f185d6c002" + +[[package]] +name = "version_check" +version = "0.9.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" + +[[package]] +name = "void" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6a02e4885ed3bc0f2de90ea6dd45ebcbb66dacffe03547fadbb0eeae2770887d" + +[[package]] +name = "winnow" +version = "0.5.40" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f593a95398737aeed53e489c785df13f3618e41dbcd6718c6addbf1395aa6876" +dependencies = [ + "memchr", +] + +[[package]] +name = "xtensa-lx" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e758f94e1a1f71758f94052a2766dcb12604998eb372b8b2e30576e3ab1ba1e6" +dependencies = [ + "bare-metal", + "mutex-trait", + "spin", +] + +[[package]] +name = "xtensa-lx-rt" +version = "0.16.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "904102108b780c9a5e3275c5f3c63dc348ec43ae5da5237868515498b447d51a" +dependencies = [ + "bare-metal", + "core-isa-parser", + "minijinja", + "r0", + "xtensa-lx-rt-proc-macros", +] + +[[package]] +name = "xtensa-lx-rt-proc-macros" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "082cdede098bbec9af15b0e74085e5f3d16f2923597de7aed7b8112003af2da7" +dependencies = [ + "darling", + "proc-macro2", + "quote", + "syn 2.0.53", +] diff --git a/examples/esp32c6/Cargo.toml b/examples/esp32c6/Cargo.toml new file mode 100644 index 0000000000..b53aaeebd9 --- /dev/null +++ b/examples/esp32c6/Cargo.toml @@ -0,0 +1,24 @@ +[package] +name = "esp32-c6" +version = "0.1.0" +edition = "2021" +license = "MIT OR Apache-2.0" + +[workspace] + +[dependencies] +rtic = {path = "../../rtic/"} +esp-hal = { version = "0.16.1", features = ["esp32c6", "direct-vectoring", "interrupt-preemption"] } +esp-backtrace = { version = "0.11.0", features = [ + "esp32c6", + "panic-handler", + "exception-handler", + "println", +] } + +esp32c6 = {version = "0.12.0", features = ["critical-section"]} +esp-println = { version = "0.9.0", default-features=false, features = ["esp32c6", "uart"] } + +[features] +test-critical-section = [] +riscv-esp32c6-backend = ["rtic/riscv-esp32c6-backend"] diff --git a/examples/esp32c6/README.md b/examples/esp32c6/README.md new file mode 100644 index 0000000000..ac57914161 --- /dev/null +++ b/examples/esp32c6/README.md @@ -0,0 +1,33 @@ +### ESP32-C3 RTIC template +This crate showcases a simple RTIC application for the ESP32-C6. + +## Prerequisites + +# Nightly Rust +The ESP32-C6 HAL requires a nightly build of Rust. +Following the example of the (Espressif no_std book)[https://docs.esp-rs.org/no_std-training/02_2_software.html], we use this specific build: +```rustup toolchain install nightly-2023-11-14 --component rust-src --target riscv32imac-unknown-none-elf``` + +# Espressif toolchain + +This crate uses the most convenient option in ``cargo-espflash`` and ``espflash`` +```cargo install cargo-espflash espflash``` + +## Running the crate + +```cargo run --example sw_and_hw --features=riscv-esp32c6-backend (--release)``` + +should do the trick. + +# Expected behavior +The program +- Prints ``init`` +- Enters a high prio task +- During the execution of the high prio task, the button should be non-functional +- Pends a low prio task +- Exits the high prio task +- Enters the low prio task +- During the execution of the low prio task, the button should be functional. +- Exits the low prio task +- Prints ``idle`` + diff --git a/examples/esp32c6/examples/sw_and_hw.rs b/examples/esp32c6/examples/sw_and_hw.rs new file mode 100644 index 0000000000..c5343bc173 --- /dev/null +++ b/examples/esp32c6/examples/sw_and_hw.rs @@ -0,0 +1,66 @@ +#![no_main] +#![no_std] + +#[rtic::app(device = esp32c6, dispatchers=[FROM_CPU_INTR0, FROM_CPU_INTR1])] +mod app { + use esp_backtrace as _; + use esp_hal::{ + gpio::{Event, Gpio9, Input, PullUp, IO}, + peripherals::Peripherals, + prelude::*, + }; + use esp_println::println; + #[shared] + struct Shared {} + + #[local] + struct Local { + button: Gpio9>, + } + + // do nothing in init + #[init] + fn init(_: init::Context) -> (Shared, Local) { + println!("init"); + let peripherals = Peripherals::take(); + let io = IO::new(peripherals.GPIO, peripherals.IO_MUX); + let mut button = io.pins.gpio9.into_pull_up_input(); + button.listen(Event::FallingEdge); + foo::spawn().unwrap(); + (Shared {}, Local { button }) + } + + #[idle()] + fn idle(_: idle::Context) -> ! { + println!("idle"); + loop {} + } + + #[task(priority = 5)] + async fn foo(_: foo::Context) { + bar::spawn().unwrap(); //enqueue low prio task + println!("Inside high prio task, press button now!"); + let mut x = 0; + while x < 5000000 { + x += 1; //burn cycles + esp_hal::riscv::asm::nop(); + } + println!("Leaving high prio task."); + } + #[task(priority = 2)] + async fn bar(_: bar::Context) { + println!("Inside low prio task, press button now!"); + let mut x = 0; + while x < 5000000 { + x += 1; //burn cycles + esp_hal::riscv::asm::nop(); + } + println!("Leaving low prio task."); + } + + #[task(binds=GPIO, local=[button], priority = 3)] + fn gpio_handler(cx: gpio_handler::Context) { + cx.local.button.clear_interrupt(); + println!("button"); + } +} diff --git a/examples/esp32c6/rust-toolchain.toml b/examples/esp32c6/rust-toolchain.toml new file mode 100644 index 0000000000..446d6fe524 --- /dev/null +++ b/examples/esp32c6/rust-toolchain.toml @@ -0,0 +1,4 @@ +[toolchain] +channel = "nightly-2023-11-14" +components = ["rust-src"] +targets = ["riscv32imc-unknown-none-elf"] diff --git a/rtic-macros/Cargo.toml b/rtic-macros/Cargo.toml index 443ed0d072..3a6dc82899 100644 --- a/rtic-macros/Cargo.toml +++ b/rtic-macros/Cargo.toml @@ -34,6 +34,7 @@ default = [] cortex-m-source-masking = [] cortex-m-basepri = [] riscv-esp32c3 = [] +riscv-esp32c6 = [] # riscv-clic = [] # riscv-ch32 = [] riscv-slic = [] diff --git a/rtic-macros/src/codegen/bindings.rs b/rtic-macros/src/codegen/bindings.rs index 501ccdff98..c45b99ed9d 100644 --- a/rtic-macros/src/codegen/bindings.rs +++ b/rtic-macros/src/codegen/bindings.rs @@ -3,6 +3,7 @@ feature = "cortex-m-basepri", feature = "test-template", feature = "riscv-esp32c3", + feature = "riscv-esp32c6", feature = "riscv-slic", )))] compile_error!("No backend selected"); @@ -25,6 +26,12 @@ pub use esp32c3::*; #[cfg(feature = "riscv-esp32c3")] mod esp32c3; +#[cfg(feature = "riscv-esp32c6")] +pub use esp32c6::*; + +#[cfg(feature = "riscv-esp32c6")] +mod esp32c6; + #[cfg(feature = "riscv-slic")] pub use riscv_slic::*; diff --git a/rtic-macros/src/codegen/bindings/esp32c6.rs b/rtic-macros/src/codegen/bindings/esp32c6.rs new file mode 100644 index 0000000000..28984db8ec --- /dev/null +++ b/rtic-macros/src/codegen/bindings/esp32c6.rs @@ -0,0 +1,249 @@ +#[cfg(feature = "riscv-esp32c6")] +pub use esp32c6::*; + +#[cfg(feature = "riscv-esp32c6")] +mod esp32c6 { + use crate::{ + analyze::Analysis as CodegenAnalysis, + codegen::util, + syntax::{analyze::Analysis as SyntaxAnalysis, ast::App}, + }; + use proc_macro2::{Span, TokenStream as TokenStream2}; + use quote::quote; + use std::collections::HashSet; + use syn::{parse, Attribute, Ident}; + + #[allow(clippy::too_many_arguments)] + pub fn impl_mutex( + _app: &App, + _analysis: &CodegenAnalysis, + cfgs: &[Attribute], + resources_prefix: bool, + name: &Ident, + ty: &TokenStream2, + ceiling: u8, + ptr: &TokenStream2, + ) -> TokenStream2 { + let path = if resources_prefix { + quote!(shared_resources::#name) + } else { + quote!(#name) + }; + quote!( + #(#cfgs)* + impl<'a> rtic::Mutex for #path<'a> { + type T = #ty; + + #[inline(always)] + fn lock(&mut self, f: impl FnOnce(&mut #ty) -> RTIC_INTERNAL_R) -> RTIC_INTERNAL_R { + /// Priority ceiling + const CEILING: u8 = #ceiling; + unsafe { + rtic::export::lock( + #ptr, + CEILING, + f, + ) + } + } + } + ) + } + + pub fn interrupt_ident() -> Ident { + let span = Span::call_site(); + Ident::new("Interrupt", span) + } + + pub fn interrupt_mod(app: &App) -> TokenStream2 { + let device = &app.args.device; + let interrupt = interrupt_ident(); + quote!(#device::#interrupt) + } + + pub fn extra_assertions(_: &App, _: &SyntaxAnalysis) -> Vec { + vec![] + } + + pub fn pre_init_preprocessing(_app: &mut App, _analysis: &SyntaxAnalysis) -> parse::Result<()> { + Ok(()) + } + + pub fn pre_init_checks(app: &App, _: &SyntaxAnalysis) -> Vec { + let mut stmts = vec![]; + // check that all dispatchers exists in the `Interrupt` enumeration regardless of whether + // they are used or not + let rt_err = util::rt_err_ident(); + + for name in app.args.dispatchers.keys() { + stmts.push(quote!(let _ = #rt_err::Interrupt::#name;)); + } + stmts + } + pub fn pre_init_enable_interrupts(app: &App, analysis: &CodegenAnalysis) -> Vec { + let mut stmts = vec![]; + let mut curr_cpu_id: u8 = 1; //cpu interrupt id 0 is reserved + let rt_err = util::rt_err_ident(); + let max_prio: usize = 15; //unfortunately this is not part of pac, but we know that max prio is 15. + let interrupt_ids = analysis.interrupts.iter().map(|(p, (id, _))| (p, id)); + // Unmask interrupts and set their priorities + for (&priority, name) in interrupt_ids.chain( + app.hardware_tasks + .values() + .filter_map(|task| Some((&task.args.priority, &task.args.binds))), + ) { + let es = format!( + "Maximum priority used by interrupt vector '{name}' is more than supported by hardware" + ); + // Compile time assert that this priority is supported by the device + stmts.push(quote!( + const _: () = if (#max_prio) <= #priority as usize { ::core::panic!(#es); }; + )); + stmts.push(quote!( + rtic::export::enable( + #rt_err::Interrupt::#name, + #priority, + #curr_cpu_id, + ); + )); + curr_cpu_id += 1; + } + stmts + } + + pub fn architecture_specific_analysis( + app: &App, + _analysis: &SyntaxAnalysis, + ) -> parse::Result<()> { + //check if the dispatchers are supported + for name in app.args.dispatchers.keys() { + let name_s = name.to_string(); + match &*name_s { + "FROM_CPU_INTR0" | "FROM_CPU_INTR1" | "FROM_CPU_INTR2" | "FROM_CPU_INTR3" => {} + + _ => { + return Err(parse::Error::new( + name.span(), + "Only FROM_CPU_INTRX are supported as dispatchers", + )); + } + } + } + + // Check that there are enough external interrupts to dispatch the software tasks and the timer + // queue handler + let mut first = None; + let priorities = app + .software_tasks + .iter() + .map(|(name, task)| { + first = Some(name); + task.args.priority + }) + .filter(|prio| *prio > 0) + .collect::>(); + + let need = priorities.len(); + let given = app.args.dispatchers.len(); + if need > given { + let s = { + format!( + "not enough interrupts to dispatch \ + all software tasks (need: {need}; given: {given})" + ) + }; + + // If not enough tasks and first still is None, may cause + // "custom attribute panicked" due to unwrap on None + return Err(parse::Error::new(first.unwrap().span(), s)); + } + Ok(()) + } + + pub fn interrupt_entry(_app: &App, _analysis: &CodegenAnalysis) -> Vec { + vec![] + } + + pub fn interrupt_exit(_app: &App, _analysis: &CodegenAnalysis) -> Vec { + vec![] + } + + pub fn check_stack_overflow_before_init( + _app: &App, + _analysis: &CodegenAnalysis, + ) -> Vec { + vec![quote!( + // Check for stack overflow using symbols from `risc-v-rt`. + extern "C" { + pub static _stack_start: u32; + pub static _bss_end: u32; + } + + let stack_start = &_stack_start as *const _ as u32; + let ebss = &_bss_end as *const _ as u32; + + if stack_start > ebss { + // No flip-link usage, check the SP for overflow. + if rtic::export::read_sp() <= ebss { + panic!("Stack overflow after allocating executors"); + } + } + )] + } + + pub fn async_entry( + _app: &App, + _analysis: &CodegenAnalysis, + dispatcher_name: Ident, + ) -> Vec { + let mut stmts = vec![]; + stmts.push(quote!( + rtic::export::unpend(rtic::export::Interrupt::#dispatcher_name); //simulate cortex-m behavior by unpending the interrupt on entry. + )); + stmts + } + + pub fn async_prio_limit(app: &App, analysis: &CodegenAnalysis) -> Vec { + let max = if let Some(max) = analysis.max_async_prio { + quote!(#max) + } else { + // No limit + let device = &app.args.device; + quote!(1 << #device::NVIC_PRIO_BITS) + }; + + vec![quote!( + /// Holds the maximum priority level for use by async HAL drivers. + #[no_mangle] + static RTIC_ASYNC_MAX_LOGICAL_PRIO: u8 = #max; + )] + } + pub fn handler_config( + app: &App, + analysis: &CodegenAnalysis, + dispatcher_name: Ident, + ) -> Vec { + let mut stmts = vec![]; + let mut curr_cpu_id = 1; + //let mut ret = ""; + let interrupt_ids = analysis.interrupts.iter().map(|(p, (id, _))| (p, id)); + for (_, name) in interrupt_ids.chain( + app.hardware_tasks + .values() + .filter_map(|task| Some((&task.args.priority, &task.args.binds))), + ) { + if *name == dispatcher_name { + let ret = &("cpu_int_".to_owned() + &curr_cpu_id.to_string() + "_handler"); + stmts.push(quote!(#[export_name = #ret])); + } + curr_cpu_id += 1; + } + + stmts + } + +pub fn extra_modules(_app: &App, _analysis: &SyntaxAnalysis) -> Vec { + vec![] +} +} + diff --git a/rtic-macros/src/lib.rs b/rtic-macros/src/lib.rs index c464ab0481..b59d6242d9 100644 --- a/rtic-macros/src/lib.rs +++ b/rtic-macros/src/lib.rs @@ -15,6 +15,7 @@ macro_rules! with_backend { feature = "cortex-m-basepri", feature = "test-template", feature = "riscv-esp32c3", + feature = "riscv-esp32c6", feature = "riscv-slic", ))] $($tokens)* @@ -118,6 +119,7 @@ with_backend! { feature = "cortex-m-basepri", feature = "test-template", feature = "riscv-esp32c3", + feature = "riscv-esp32c6", feature = "riscv-slic", )))] compile_error!("Cannot compile. No backend feature selected."); diff --git a/rtic-macros/src/syntax/backend.rs b/rtic-macros/src/syntax/backend.rs index 460ef560bf..2d8d930b07 100644 --- a/rtic-macros/src/syntax/backend.rs +++ b/rtic-macros/src/syntax/backend.rs @@ -3,6 +3,7 @@ feature = "cortex-m-basepri", feature = "test-template", feature = "riscv-esp32c3", + feature = "riscv-esp32c6", feature = "riscv-slic", )))] compile_error!("No backend selected"); @@ -16,6 +17,9 @@ pub use template::*; #[cfg(feature = "riscv-esp32c3")] pub use esp32c3::*; +#[cfg(feature = "riscv-esp32c6")] +pub use esp32c6::*; + #[cfg(feature = "riscv-slic")] pub use riscv_slic::*; @@ -28,5 +32,8 @@ mod template; #[cfg(feature = "riscv-esp32c3")] mod esp32c3; +#[cfg(feature = "riscv-esp32c6")] +mod esp32c6; + #[cfg(feature = "riscv-slic")] mod riscv_slic; diff --git a/rtic-macros/src/syntax/backend/esp32c6.rs b/rtic-macros/src/syntax/backend/esp32c6.rs new file mode 100644 index 0000000000..611df89e2c --- /dev/null +++ b/rtic-macros/src/syntax/backend/esp32c6.rs @@ -0,0 +1,16 @@ +use syn::{ + parse::{Parse, ParseStream}, + Error, Result, +}; + +#[derive(Debug)] +pub struct BackendArgs(); + +impl Parse for BackendArgs { + fn parse(input: ParseStream) -> Result { + Err(Error::new( + input.span(), + "esp32c6 backend does not accept any arguments", + )) + } +} diff --git a/rtic/Cargo.toml b/rtic/Cargo.toml index 9a67dd12c0..b5be423053 100644 --- a/rtic/Cargo.toml +++ b/rtic/Cargo.toml @@ -27,6 +27,7 @@ name = "rtic" [dependencies] riscv-slic = { git = "https://github.com/romancardenas/riscv-slic.git", rev = "2a91edb", optional = true } esp32c3 = { version = "0.21.0", optional = true } +esp32c6 = { version = "0.12.0", optional = true } riscv = { version = "0.11.0", optional = true } cortex-m = { version = "0.7.0", optional = true } bare-metal = "1.0.0" @@ -62,6 +63,7 @@ thumbv8main-backend = ["cortex-m", "rtic-macros/cortex-m-basepri"] # riscv-clic-backend = ["rtic-macros/riscv-clic"] # riscv-ch32-backend = ["rtic-macros/riscv-ch32"] riscv-esp32c3-backend = ["esp32c3", "riscv", "rtic-macros/riscv-esp32c3"] +riscv-esp32c6-backend = ["esp32c6", "riscv", "rtic-macros/riscv-esp32c6"] riscv-clint-backend = [ "riscv", "riscv-slic/clint-backend", diff --git a/rtic/build.rs b/rtic/build.rs index 8c87b568c1..314b2e9d8c 100644 --- a/rtic/build.rs +++ b/rtic/build.rs @@ -27,6 +27,9 @@ fn main() { "riscv-esp32c3-backend" => { println!("cargo:rustc-cfg=feature=\"riscv-esp32c3\""); } + "riscv-esp32c6-backend" => { + println!("cargo:rustc-cfg=feature=\"riscv-esp32c6\""); + } "riscv-clint-backend" => { println!("cargo:rustc-cfg=feature=\"riscv-slic\""); } diff --git a/rtic/src/export.rs b/rtic/src/export.rs index 4fd8e7870a..00cc2f6c34 100644 --- a/rtic/src/export.rs +++ b/rtic/src/export.rs @@ -36,6 +36,11 @@ mod riscv_esp32c3; #[cfg(feature = "riscv-esp32c3")] pub use riscv_esp32c3::*; +#[cfg(feature = "riscv-esp32c6")] +mod riscv_esp32c6; +#[cfg(feature = "riscv-esp32c6")] +pub use riscv_esp32c6::*; + #[cfg(feature = "riscv-slic")] mod slic; #[cfg(feature = "riscv-slic")] diff --git a/rtic/src/export/riscv_esp32c6.rs b/rtic/src/export/riscv_esp32c6.rs new file mode 100644 index 0000000000..b59b779b88 --- /dev/null +++ b/rtic/src/export/riscv_esp32c6.rs @@ -0,0 +1,161 @@ +use esp32c6::INTPRI; //priority threshold control +pub use esp32c6::{Interrupt, Peripherals}; +pub use riscv::interrupt; +pub use riscv::register::mcause; //low level interrupt enable/disable + +#[cfg(all(feature = "riscv-esp32c6", not(feature = "riscv-esp32c6-backend")))] +compile_error!("Building for the esp32c6, but 'riscv-esp32c6-backend not selected'"); + +#[inline(always)] +pub fn run(priority: u8, f: F) +where + F: FnOnce(), +{ + if priority == 1 { + //if priority is 1, priority thresh should be 1 + f(); + unsafe { + (*INTPRI::ptr()) + .cpu_int_thresh() + .write(|w| w.cpu_int_thresh().bits(1)); + } + } else { + //read current thresh + let initial = unsafe { + (*INTPRI::ptr()) + .cpu_int_thresh() + .read() + .cpu_int_thresh() + .bits() + }; + f(); + //write back old thresh + unsafe { + (*INTPRI::ptr()) + .cpu_int_thresh() + .write(|w| w.cpu_int_thresh().bits(initial)); + } + } +} + +/// Lock implementation using threshold and global Critical Section (CS) +/// +/// # Safety +/// +/// The system ceiling is raised from current to ceiling +/// by either +/// - raising the threshold to the ceiling value, or +/// - disable all interrupts in case we want to +/// mask interrupts with maximum priority +/// +/// Dereferencing a raw pointer inside CS +/// +/// The priority.set/priority.get can safely be outside the CS +/// as being a context local cell (not affected by preemptions). +/// It is merely used in order to omit masking in case current +/// priority is current priority >= ceiling. +#[inline(always)] +pub unsafe fn lock(ptr: *mut T, ceiling: u8, f: impl FnOnce(&mut T) -> R) -> R { + if ceiling == (15) { + //turn off interrupts completely, were at max prio + let r = critical_section::with(|_| f(&mut *ptr)); + r + } else { + let current = unsafe { + (*INTPRI::ptr()) + .cpu_int_thresh() + .read() + .cpu_int_thresh() + .bits() + }; + + unsafe { + (*INTPRI::ptr()) + .cpu_int_thresh() + .write(|w| w.cpu_int_thresh().bits(ceiling + 1)) + } //esp32c6 lets interrupts with prio equal to threshold through so we up it by one + let r = f(&mut *ptr); + unsafe { + (*INTPRI::ptr()) + .cpu_int_thresh() + .write(|w| w.cpu_int_thresh().bits(current)) + } + r + } +} + +/// Sets the given software interrupt as pending +#[inline(always)] +pub fn pend(int: Interrupt) { + unsafe { + let peripherals = Peripherals::steal(); + match int { + Interrupt::FROM_CPU_INTR0 => peripherals + .INTPRI + .cpu_intr_from_cpu_0() + .write(|w| w.cpu_intr_from_cpu_0().bit(true)), + Interrupt::FROM_CPU_INTR1 => peripherals + .INTPRI + .cpu_intr_from_cpu_1() + .write(|w| w.cpu_intr_from_cpu_1().bit(true)), + Interrupt::FROM_CPU_INTR2 => peripherals + .INTPRI + .cpu_intr_from_cpu_2() + .write(|w| w.cpu_intr_from_cpu_2().bit(true)), + Interrupt::FROM_CPU_INTR3 => peripherals + .INTPRI + .cpu_intr_from_cpu_3() + .write(|w| w.cpu_intr_from_cpu_3().bit(true)), + _ => panic!("Unsupported software interrupt"), //should never happen, checked at compile time + } + } +} + +// Sets the given software interrupt as not pending +pub fn unpend(int: Interrupt) { + unsafe { + let peripherals = Peripherals::steal(); + match int { + Interrupt::FROM_CPU_INTR0 => peripherals + .INTPRI + .cpu_intr_from_cpu_0() + .write(|w| w.cpu_intr_from_cpu_0().bit(false)), + Interrupt::FROM_CPU_INTR1 => peripherals + .INTPRI + .cpu_intr_from_cpu_1() + .write(|w| w.cpu_intr_from_cpu_1().bit(false)), + Interrupt::FROM_CPU_INTR2 => peripherals + .INTPRI + .cpu_intr_from_cpu_2() + .write(|w| w.cpu_intr_from_cpu_2().bit(false)), + Interrupt::FROM_CPU_INTR3 => peripherals + .INTPRI + .cpu_intr_from_cpu_3() + .write(|w| w.cpu_intr_from_cpu_3().bit(false)), + _ => panic!("Unsupported software interrupt"), + } + } +} + +pub fn enable(int: Interrupt, prio: u8, cpu_int_id: u8) { + const INTERRUPT_MAP_BASE: u32 = 0x60010000; + let interrupt_number = int as isize; + let cpu_interrupt_number = cpu_int_id as isize; + + unsafe { + let intr_map_base = INTERRUPT_MAP_BASE as *mut u32; + intr_map_base + .offset(interrupt_number) + .write_volatile(cpu_interrupt_number as u32); + //map peripheral interrupt to CPU interrupt + (*INTPRI::ptr()) + .cpu_int_enable() + .modify(|r, w| w.bits((1 << cpu_interrupt_number) | r.bits())); //enable the CPU interupt. + let intr = INTPRI::ptr(); + let intr_prio_base = (*intr).cpu_int_pri_0().as_ptr(); + + intr_prio_base + .offset(cpu_interrupt_number) + .write_volatile(prio as u32); + } +} diff --git a/xtask/src/argument_parsing.rs b/xtask/src/argument_parsing.rs index f72be77710..9a0fd72e7c 100644 --- a/xtask/src/argument_parsing.rs +++ b/xtask/src/argument_parsing.rs @@ -154,6 +154,7 @@ pub enum Backends { Thumbv8Base, Thumbv8Main, RiscvEsp32C3, + RiscvEsp32C6, Riscv32ImcClint, // not working yet (issues with portable-atomic features...) Riscv32ImacClint, } @@ -167,7 +168,7 @@ impl Backends { Backends::Thumbv8Base => ARMV8MBASE, Backends::Thumbv8Main => ARMV8MMAIN, Backends::Riscv32ImcClint | Backends::RiscvEsp32C3 => RISCV32IMC, - Backends::Riscv32ImacClint => RISCV32IMAC, + Backends::Riscv32ImacClint | Backends::RiscvEsp32C6 => RISCV32IMAC, } } @@ -179,6 +180,7 @@ impl Backends { Backends::Thumbv8Base => "thumbv8base-backend", Backends::Thumbv8Main => "thumbv8main-backend", Backends::RiscvEsp32C3 => "riscv-esp32c3-backend", + Backends::RiscvEsp32C6 => "riscv-esp32c6-backend", Backends::Riscv32ImcClint | Backends::Riscv32ImacClint => "riscv-clint-backend", } } @@ -188,6 +190,7 @@ impl Backends { Backends::Thumbv6 | Backends::Thumbv8Base => "cortex-m-source-masking", Backends::Thumbv7 | Backends::Thumbv8Main => "cortex-m-basepri", Backends::RiscvEsp32C3 => "riscv-esp32c3", + Backends::RiscvEsp32C6 => "riscv-esp32c6", Backends::Riscv32ImcClint | Backends::Riscv32ImacClint => "riscv-clint", } } @@ -203,6 +206,7 @@ pub enum BuildOrCheck { #[derive(clap::ValueEnum, Copy, Clone, Default, Debug)] pub enum Platforms { Esp32C3, + Esp32C6, Hifive1, #[default] Lm3s6965, @@ -217,6 +221,7 @@ impl Platforms { pub fn name(&self) -> String { let name = match self { Platforms::Esp32C3 => "esp32c3", + Platforms::Esp32C6 => "esp32c6", Platforms::Hifive1 => "hifive1", Platforms::Lm3s6965 => "lm3s6965", Platforms::Nrf52840 => "nrf52840", @@ -232,7 +237,7 @@ impl Platforms { pub fn rust_flags(&self) -> Vec { let c = "-C".to_string(); match self { - Platforms::Esp32C3 => vec![c, "link-arg=-Tlinkall.x".to_string()], + Platforms::Esp32C3 | Platforms::Esp32C6 => vec![c, "link-arg=-Tlinkall.x".to_string()], Platforms::Hifive1 => vec![c, "link-arg=-Thifive1-link.x".to_string()], Platforms::Lm3s6965 => vec![c, "link-arg=-Tlink.x".to_string()], Platforms::Nrf52840 => vec![ @@ -271,6 +276,7 @@ impl Platforms { pub fn default_backend(&self) -> Backends { match self { Platforms::Esp32C3 => Backends::RiscvEsp32C3, + Platforms::Esp32C6 => Backends::RiscvEsp32C6, Platforms::Hifive1 => Backends::Riscv32ImcClint, Platforms::Lm3s6965 => Backends::Thumbv7, Platforms::Nrf52840 => unimplemented!(), @@ -290,6 +296,10 @@ impl Platforms { RISCV32IMC => Ok(None), _ => Err(()), }, + Platforms::Esp32C6 => match backend.to_target() { + RISCV32IMAC => Ok(None), + _ => Err(()), + }, Platforms::Hifive1 => match backend.to_target() { RISCV32IMC | RISCV32IMAC => Ok(None), _ => Err(()),