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(()),