diff --git a/build.sh b/build.sh index c675c148..66339e5e 100755 --- a/build.sh +++ b/build.sh @@ -72,6 +72,10 @@ pushd loopback-fw cargo build --target=thumbv7em-none-eabihf --release cargo fmt --check popd +pushd loopback-fw-rtic +cargo build --target=thumbv7em-none-eabihf --release +cargo fmt --check +popd popd # Only build the templates (they will panic at run-time due to the use of todo!) @@ -105,5 +109,6 @@ cp -r ./.cargo "${OUTPUT_NAME}/" cp -r ./tools "${OUTPUT_NAME}/" cp ./nrf52-code/puzzle-fw/target/thumbv7em-none-eabihf/release/puzzle-fw "${OUTPUT_NAME}/nrf52-code/boards/dongle-fw/puzzle-fw" cp ./nrf52-code/loopback-fw/target/thumbv7em-none-eabihf/release/loopback-fw "${OUTPUT_NAME}/nrf52-code/boards/dongle-fw/loopback-fw" +cp ./nrf52-code/loopback-fw-rtic/target/thumbv7em-none-eabihf/release/loopback-fw-rtic "${OUTPUT_NAME}/nrf52-code/boards/dongle-fw/loopback-fw-rtic" find "${OUTPUT_NAME}" -name target -type d -print0 | xargs -0 rm -rf zip -r "${OUTPUT_NAME}.zip" "${OUTPUT_NAME}" diff --git a/nrf52-code/boards/dk/Cargo.toml b/nrf52-code/boards/dk/Cargo.toml index 4fc4c4d1..e8d19e94 100644 --- a/nrf52-code/boards/dk/Cargo.toml +++ b/nrf52-code/boards/dk/Cargo.toml @@ -18,3 +18,4 @@ hal = { package = "nrf52840-hal", version = "0.18.0" } [features] advanced = [] radio = [] +usbd = [] diff --git a/nrf52-code/boards/dk/src/lib.rs b/nrf52-code/boards/dk/src/lib.rs index 88ac36c8..6c22505a 100644 --- a/nrf52-code/boards/dk/src/lib.rs +++ b/nrf52-code/boards/dk/src/lib.rs @@ -17,7 +17,7 @@ use cortex_m_semihosting::debug; use embedded_hal::digital::{OutputPin, StatefulOutputPin}; #[cfg(feature = "advanced")] use grounded::uninit::GroundedArrayCell; -#[cfg(feature = "radio")] +#[cfg(any(feature = "radio", feature = "usbd"))] use grounded::uninit::GroundedCell; #[cfg(feature = "radio")] pub use hal::ieee802154; @@ -44,14 +44,18 @@ pub mod peripheral; #[cfg(feature = "advanced")] pub mod usbd; -#[cfg(feature = "radio")] +#[cfg(any(feature = "radio", feature = "usbd"))] struct ClockSyncWrapper { clocks: Clocks, } -#[cfg(feature = "radio")] +#[cfg(any(feature = "radio", feature = "usbd"))] unsafe impl Sync for ClockSyncWrapper {} +/// Our USB Device +#[cfg(feature = "usbd")] +pub type UsbDevice = hal::usbd::Usbd>; + /// Components on the board pub struct Board { /// LEDs @@ -71,6 +75,9 @@ pub struct Board { /// USB control endpoint 0 #[cfg(feature = "advanced")] pub ep0in: Ep0In, + /// A configured USB Device + #[cfg(feature = "usbd")] + pub usbd: UsbDevice, } /// All LEDs on the board @@ -300,7 +307,7 @@ pub fn init() -> Result { // NOTE: this branch runs at most once #[cfg(feature = "advanced")] static EP0IN_BUF: GroundedArrayCell = GroundedArrayCell::const_init(); - #[cfg(feature = "radio")] + #[cfg(any(feature = "radio", feature = "usbd"))] // We need the wrapper to make this type Sync, as it contains raw pointers static CLOCKS: GroundedCell< ClockSyncWrapper< @@ -317,7 +324,7 @@ pub fn init() -> Result { let clocks = clocks.start_lfclk(); let _clocks = clocks.enable_ext_hfosc(); // extend lifetime to `'static` - #[cfg(feature = "radio")] + #[cfg(any(feature = "radio", feature = "usbd"))] let clocks = unsafe { let clocks_ptr = CLOCKS.get(); clocks_ptr.write(ClockSyncWrapper { clocks: _clocks }); @@ -370,6 +377,15 @@ pub fn init() -> Result { radio }; + #[cfg(feature = "usbd")] + { + defmt::debug!("Enabling SOF interrupts..."); + periph.USBD.inten.modify(|_r, w| { + w.sof().set_bit(); + w + }); + } + Ok(Board { leds: Leds { _1: Led { inner: led1pin }, @@ -386,6 +402,8 @@ pub fn init() -> Result { power: periph.POWER, #[cfg(feature = "advanced")] ep0in: unsafe { Ep0In::new(&EP0IN_BUF) }, + #[cfg(feature = "usbd")] + usbd: UsbDevice::new(hal::usbd::UsbPeripheral::new(periph.USBD, clocks)), }) } diff --git a/nrf52-code/loopback-fw-rtic/.cargo/config.toml b/nrf52-code/loopback-fw-rtic/.cargo/config.toml new file mode 100644 index 00000000..436cc4fb --- /dev/null +++ b/nrf52-code/loopback-fw-rtic/.cargo/config.toml @@ -0,0 +1,23 @@ +[target.thumbv7em-none-eabihf] +# set custom cargo runner to flash & run on embedded target when we call `cargo run` +# for more information, check out https://github.com/probe-rs +runner = [ + "probe-rs", + "run", + "--chip", + "nRF52840_xxAA", + "--allow-erase-all", + "--log-format", + "{t} {[{L}]%bold} {s} {({c:bold} {fff}:{l:1})%dimmed}" +] +# Or use "{[{L}]%bold} {s} {({c:bold} {fff}:{l:1})%dimmed}" to disable timestamps + +linker = "flip-link" # adds stack overflow protection +rustflags = [ + "-C", "link-arg=-Tlink.x", # use the cortex-m-rt linker script + "-C", "link-arg=-Tdefmt.x", # defmt support +] + +[build] +# cross-compile to this target +target = "thumbv7em-none-eabihf" # = ARM Cortex-M4 with FPU diff --git a/nrf52-code/loopback-fw-rtic/.gitignore b/nrf52-code/loopback-fw-rtic/.gitignore new file mode 100644 index 00000000..eb5a316c --- /dev/null +++ b/nrf52-code/loopback-fw-rtic/.gitignore @@ -0,0 +1 @@ +target diff --git a/nrf52-code/loopback-fw-rtic/Cargo.lock b/nrf52-code/loopback-fw-rtic/Cargo.lock new file mode 100644 index 00000000..881e4ec4 --- /dev/null +++ b/nrf52-code/loopback-fw-rtic/Cargo.lock @@ -0,0 +1,665 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 3 + +[[package]] +name = "az" +version = "1.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7b7e4c2464d97fe331d41de9d5db0def0a96f4d823b8b32a2efd503578988973" + +[[package]] +name = "bare-metal" +version = "0.2.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5deb64efa5bd81e31fcd1938615a6d98c82eafcbcd787162b6f63b91d6bac5b3" +dependencies = [ + "rustc_version", +] + +[[package]] +name = "bare-metal" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f8fe8f5a8a398345e52358e18ff07cc17a568fbca5c6f73873d3a62056309603" + +[[package]] +name = "bitfield" +version = "0.13.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "46afbd2983a5d5a7bd740ccb198caf5b82f45c40c09c0eed36052d91cb92e719" + +[[package]] +name = "bitflags" +version = "1.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" + +[[package]] +name = "bytemuck" +version = "1.20.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8b37c88a63ffd85d15b406896cc343916d7cf57838a847b3a6f2ca5d39a5695a" + +[[package]] +name = "byteorder" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" + +[[package]] +name = "cast" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "37b2a672a2cb129a2e41c10b1224bb368f9f37a2b16b612598138befd7b37eb5" + +[[package]] +name = "cfg-if" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" + +[[package]] +name = "consts" +version = "0.1.0" + +[[package]] +name = "cortex-m" +version = "0.7.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8ec610d8f49840a5b376c69663b6369e71f4b34484b9b2eb29fb918d92516cb9" +dependencies = [ + "bare-metal 0.2.5", + "bitfield", + "critical-section", + "embedded-hal 0.2.7", + "volatile-register", +] + +[[package]] +name = "cortex-m-rt" +version = "0.7.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "801d4dec46b34c299ccf6b036717ae0fce602faa4f4fe816d9013b9a7c9f5ba6" +dependencies = [ + "cortex-m-rt-macros", +] + +[[package]] +name = "cortex-m-rt-macros" +version = "0.7.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e37549a379a9e0e6e576fd208ee60394ccb8be963889eebba3ffe0980364f472" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "cortex-m-semihosting" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c23234600452033cc77e4b761e740e02d2c4168e11dbf36ab14a0f58973592b0" +dependencies = [ + "cortex-m", +] + +[[package]] +name = "critical-section" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "790eea4361631c5e7d22598ecd5723ff611904e3344ce8720784c93e3d83d40b" + +[[package]] +name = "crunchy" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7a81dae078cea95a014a339291cec439d2f232ebe854a9d672b796c6afafa9b7" + +[[package]] +name = "defmt" +version = "0.3.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "86f6162c53f659f65d00619fe31f14556a6e9f8752ccc4a41bd177ffcf3d6130" +dependencies = [ + "bitflags", + "defmt-macros", +] + +[[package]] +name = "defmt-macros" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9d135dd939bad62d7490b0002602d35b358dce5fd9233a709d3c1ef467d4bde6" +dependencies = [ + "defmt-parser", + "proc-macro-error2", + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "defmt-parser" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3983b127f13995e68c1e29071e5d115cd96f215ccb5e6812e3728cd6f92653b3" +dependencies = [ + "thiserror", +] + +[[package]] +name = "defmt-rtt" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bab697b3dbbc1750b7c8b821aa6f6e7f2480b47a99bc057a2ed7b170ebef0c51" +dependencies = [ + "critical-section", + "defmt", +] + +[[package]] +name = "dk" +version = "0.0.0" +dependencies = [ + "cortex-m", + "cortex-m-rt", + "cortex-m-semihosting", + "defmt", + "defmt-rtt", + "embedded-hal 1.0.0", + "grounded", + "nrf52840-hal", +] + +[[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 = "embedded-hal-async" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0c4c685bbef7fe13c3c6dd4da26841ed3980ef33e841cddfa15ce8a8fb3f1884" +dependencies = [ + "embedded-hal 1.0.0", +] + +[[package]] +name = "embedded-io" +version = "0.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "edd0f118536f44f5ccd48bcb8b111bdc3de888b58c74639dfb034a357d0f206d" + +[[package]] +name = "embedded-storage" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a21dea9854beb860f3062d10228ce9b976da520a73474aed3171ec276bc0c032" + +[[package]] +name = "equivalent" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5" + +[[package]] +name = "fixed" +version = "1.28.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "85c6e0b89bf864acd20590dbdbad56f69aeb898abfc9443008fd7bd48b2cc85a" +dependencies = [ + "az", + "bytemuck", + "half", + "typenum", +] + +[[package]] +name = "fugit" +version = "0.3.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "17186ad64927d5ac8f02c1e77ccefa08ccd9eaa314d5a4772278aa204a22f7e7" +dependencies = [ + "gcd", +] + +[[package]] +name = "futures-core" +version = "0.3.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "05f29059c0c2090612e8d742178b0580d2dc940c837851ad723096f87af6663e" + +[[package]] +name = "futures-task" +version = "0.3.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f90f7dce0722e95104fcb095585910c0977252f286e354b5e3bd38902cd99988" + +[[package]] +name = "futures-util" +version = "0.3.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9fa08315bb612088cc391249efdc3bc77536f16c91f6cf495e6fbe85b20a4a81" +dependencies = [ + "futures-core", + "futures-task", + "pin-project-lite", + "pin-utils", +] + +[[package]] +name = "gcd" +version = "2.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1d758ba1b47b00caf47f24925c0074ecb20d6dfcffe7f6d53395c0465674841a" + +[[package]] +name = "grounded" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "917d82402c7eb9755fdd87d52117701dae9e413a6abb309fac2a13af693b6080" +dependencies = [ + "portable-atomic", +] + +[[package]] +name = "half" +version = "2.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6dd08c532ae367adf81c312a4580bc67f1d0fe8bc9c460520283f4c0ff277888" +dependencies = [ + "cfg-if", + "crunchy", +] + +[[package]] +name = "hash32" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "47d60b12902ba28e2730cd37e95b8c9223af2808df9e902d4df49588d1470606" +dependencies = [ + "byteorder", +] + +[[package]] +name = "hashbrown" +version = "0.15.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bf151400ff0baff5465007dd2f3e717f3fe502074ca563069ce3a6629d07b289" + +[[package]] +name = "heapless" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0bfb9eb618601c89945a70e254898da93b13be0388091d42117462b265bb3fad" +dependencies = [ + "hash32", + "stable_deref_trait", +] + +[[package]] +name = "indexmap" +version = "2.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "62f822373a4fe84d4bb149bf54e584a7f4abec90e072ed49cda0edea5b95471f" +dependencies = [ + "equivalent", + "hashbrown", +] + +[[package]] +name = "loopback-fw-rtic" +version = "0.0.0" +dependencies = [ + "consts", + "defmt", + "defmt-rtt", + "dk", + "rtic", + "rtic-monotonics", + "usb-device", + "usbd-serial", +] + +[[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 = "nrf-hal-common" +version = "0.18.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0c134de1f2f0191aed3fc24d3831da8808d1e636b06edf81a5717103095f625d" +dependencies = [ + "cast", + "cfg-if", + "cortex-m", + "embedded-dma", + "embedded-hal 0.2.7", + "embedded-hal 1.0.0", + "embedded-io", + "embedded-storage", + "fixed", + "nb 1.1.0", + "nrf-usbd", + "nrf52840-pac", + "rand_core", + "void", +] + +[[package]] +name = "nrf-usbd" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "aedf862f941154442271ae9914777bd1c93f6d2e0dc9db4cafa160e55ffb9085" +dependencies = [ + "cortex-m", + "critical-section", + "usb-device", + "vcell", +] + +[[package]] +name = "nrf52840-hal" +version = "0.18.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "433cfd866da18dfc58376880bdebd092c130444837debc513f44edcd0d6a6558" +dependencies = [ + "nrf-hal-common", + "nrf52840-pac", +] + +[[package]] +name = "nrf52840-pac" +version = "0.12.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "30713f36f1be02e5bc9abefa30eae4a1f943d810f199d4923d3ad062d1be1b3d" +dependencies = [ + "cortex-m", + "cortex-m-rt", + "vcell", +] + +[[package]] +name = "pin-project-lite" +version = "0.2.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "915a1e146535de9163f3987b8944ed8cf49a18bb0056bcebcdcece385cece4ff" + +[[package]] +name = "pin-utils" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" + +[[package]] +name = "portable-atomic" +version = "1.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "280dc24453071f1b63954171985a0b0d30058d287960968b9b2aca264c8d4ee6" + +[[package]] +name = "proc-macro-error-attr2" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "96de42df36bb9bba5542fe9f1a054b8cc87e172759a1868aa05c1f3acc89dfc5" +dependencies = [ + "proc-macro2", + "quote", +] + +[[package]] +name = "proc-macro-error2" +version = "2.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "11ec05c52be0a07b08061f7dd003e7d7092e0472bc731b4af7bb1ef876109802" +dependencies = [ + "proc-macro-error-attr2", + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "proc-macro2" +version = "1.0.92" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "37d3544b3f2748c54e147655edb5025752e2303145b5aefb3c3ea2c78b973bb0" +dependencies = [ + "unicode-ident", +] + +[[package]] +name = "quote" +version = "1.0.37" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b5b9d34b8991d19d98081b46eacdd8eb58c6f2b201139f7c5f643cc155a633af" +dependencies = [ + "proc-macro2", +] + +[[package]] +name = "rand_core" +version = "0.6.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" + +[[package]] +name = "rtic" +version = "2.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "401961431a1e491124cdd216a313fada2d395aa2b5bee2867c872fc8af7c1bc1" +dependencies = [ + "bare-metal 1.0.0", + "cortex-m", + "critical-section", + "portable-atomic", + "rtic-core", + "rtic-macros", +] + +[[package]] +name = "rtic-common" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0786b50b81ef9d2a944a000f60405bb28bf30cd45da2d182f3fe636b2321f35c" +dependencies = [ + "critical-section", +] + +[[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.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ac22ab522d80079b48f46ac66ded4d349e1adf81b52430d6a74faa3a7790ed80" +dependencies = [ + "indexmap", + "proc-macro-error2", + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "rtic-monotonics" +version = "2.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f1cb90bcfdbbacf3ca37340cdab52ec2de5611c744095ef7889e9c50c233b748" +dependencies = [ + "cfg-if", + "cortex-m", + "fugit", + "portable-atomic", + "rtic-time", +] + +[[package]] +name = "rtic-time" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a7b1d853fa50dc125695414ce4510567a0d420221e455b1568cfa8c9aece9614" +dependencies = [ + "critical-section", + "embedded-hal 1.0.0", + "embedded-hal-async", + "fugit", + "futures-util", + "rtic-common", +] + +[[package]] +name = "rustc_version" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "138e3e0acb6c9fb258b19b67cb8abd63c00679d2851805ea151465464fe9030a" +dependencies = [ + "semver", +] + +[[package]] +name = "semver" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1d7eb9ef2c18661902cc47e535f9bc51b78acd254da71d375c2f6720d9a40403" +dependencies = [ + "semver-parser", +] + +[[package]] +name = "semver-parser" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "388a1df253eca08550bef6c72392cfe7c30914bf41df5269b68cbd6ff8f570a3" + +[[package]] +name = "stable_deref_trait" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a8f112729512f8e442d81f95a8a7ddf2b7c6b8a1a6f509a95864142b30cab2d3" + +[[package]] +name = "syn" +version = "2.0.90" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "919d3b74a5dd0ccd15aeb8f93e7006bd9e14c295087c9896a110f490752bcf31" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[package]] +name = "thiserror" +version = "2.0.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8fec2a1820ebd077e2b90c4df007bebf344cd394098a13c563957d0afc83ea47" +dependencies = [ + "thiserror-impl", +] + +[[package]] +name = "thiserror-impl" +version = "2.0.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d65750cab40f4ff1929fb1ba509e9914eb756131cef4210da8d5d700d26f6312" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "typenum" +version = "1.17.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "42ff0bf0c66b8238c6f3b578df37d0b7848e55df8577b3f74f92a69acceeb825" + +[[package]] +name = "unicode-ident" +version = "1.0.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "adb9e6ca4f869e1180728b7950e35922a7fc6397f7b641499e8f3ef06e50dc83" + +[[package]] +name = "usb-device" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "98816b1accafbb09085168b90f27e93d790b4bfa19d883466b5e53315b5f06a6" +dependencies = [ + "defmt", + "heapless", + "portable-atomic", +] + +[[package]] +name = "usbd-serial" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "065e4eaf93db81d5adac82d9cef8f8da314cb640fa7f89534b972383f1cf80fc" +dependencies = [ + "embedded-hal 0.2.7", + "embedded-io", + "nb 1.1.0", + "usb-device", +] + +[[package]] +name = "vcell" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "77439c1b53d2303b20d9459b1ade71a83c716e3f9c34f3228c00e6f185d6c002" + +[[package]] +name = "void" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6a02e4885ed3bc0f2de90ea6dd45ebcbb66dacffe03547fadbb0eeae2770887d" + +[[package]] +name = "volatile-register" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "de437e2a6208b014ab52972a27e59b33fa2920d3e00fe05026167a1c509d19cc" +dependencies = [ + "vcell", +] diff --git a/nrf52-code/loopback-fw-rtic/Cargo.toml b/nrf52-code/loopback-fw-rtic/Cargo.toml new file mode 100644 index 00000000..eddb7d51 --- /dev/null +++ b/nrf52-code/loopback-fw-rtic/Cargo.toml @@ -0,0 +1,16 @@ +[package] +authors = ["Ferrous Systems"] +edition = "2021" +license = "MIT OR Apache-2.0" +name = "loopback-fw-rtic" +version = "0.0.0" + +[dependencies] +consts = { version = "0.1.0", path = "../consts" } +defmt = "0.3.10" +defmt-rtt = "0.4.1" +dk = { version = "0.0.0", path = "../boards/dk", features = ["usbd"] } +rtic = { version = "2.1.2", features = ["thumbv7-backend"] } +rtic-monotonics = { version = "2.0.3", features = ["cortex-m-systick"] } +usb-device = { version = "0.3.2", features = ["defmt"] } +usbd-serial = "0.2.2" diff --git a/nrf52-code/loopback-fw-rtic/src/main.rs b/nrf52-code/loopback-fw-rtic/src/main.rs new file mode 100644 index 00000000..acd2aaf7 --- /dev/null +++ b/nrf52-code/loopback-fw-rtic/src/main.rs @@ -0,0 +1,113 @@ +//! The Loopback Firmware, written using RTIC +//! +//! Currently this runs on the Developer Kit and not the Dongle, because it's +//! easier to debug. +//! +//! And it doesn't do any radio stuff - just USB Serial. + +#![no_main] +#![no_std] + +use defmt_rtt as _; + +#[rtic::app(device = dk, peripherals = false)] +mod app { + use core::mem::MaybeUninit; + use rtic_monotonics::systick::prelude::*; + + systick_monotonic!(Mono, 100); + + #[local] + struct MyLocalResources {} + + #[shared] + struct MySharedResources { + usb_serial: usbd_serial::SerialPort<'static, dk::UsbDevice>, + usb_device: usb_device::device::UsbDevice<'static, dk::UsbDevice>, + } + + #[init(local = [ + usb_alloc: MaybeUninit> = MaybeUninit::uninit() + ])] + fn init(cx: init::Context) -> (MySharedResources, MyLocalResources) { + let board = dk::init().unwrap(); + Mono::start(cx.core.SYST, 64_000_000); + + defmt::debug!("Building USB allocator..."); + let usb_alloc = cx + .local + .usb_alloc + .write(usb_device::bus::UsbBusAllocator::new(board.usbd)); + + defmt::debug!("Creating usb_serial..."); + let usb_serial = usbd_serial::SerialPort::new(usb_alloc); + + defmt::debug!("Building USB Strings..."); + let strings = usb_device::device::StringDescriptors::new(usb_device::LangID::EN) + .manufacturer("Ferrous Systems") + .product("Test Device"); + + defmt::debug!("Building VID and PID..."); + let vid_pid = + usb_device::device::UsbVidPid(consts::USB_VID_DEMO, consts::USB_PID_DONGLE_LOOPBACK); + + defmt::debug!("Building USB Device..."); + let usb_device = usb_device::device::UsbDeviceBuilder::new(usb_alloc, vid_pid) + .composite_with_iads() + .strings(&[strings]) + .expect("Adding strings") + .max_packet_size_0(64) + .expect("set_packet_size") + .build(); + + defmt::debug!("Spawning task..."); + foo::spawn().ok(); + + defmt::debug!("Building structures..."); + let shared = MySharedResources { + usb_serial, + usb_device, + }; + let local = MyLocalResources {}; + + defmt::debug!("Init Complete!"); + + (shared, local) + } + + #[task(shared = [usb_serial])] + async fn foo(mut cx: foo::Context) { + loop { + defmt::info!("hello from foo"); + let _ = cx.shared.usb_serial.lock(|usb_serial| { + usb_serial.write(b"Boopity boop"); + }); + Mono::delay(1000.millis()).await; + } + } + + /// USB Interrupt Handler + /// + /// USB Device is set to fire this whenever there's a Start of Frame from + /// the USB Host. + #[task(binds = USBD, shared = [usb_serial, usb_device])] + fn usb_isr(cx: usb_isr::Context) { + (cx.shared.usb_serial, cx.shared.usb_device).lock(|usb_serial, usb_device| { + usb_device.poll(&mut [usb_serial]); + }); + } +} + +#[panic_handler] +fn panic(info: &core::panic::PanicInfo) -> ! { + if let Some(location) = info.location() { + defmt::error!("Panic at {}:{}", location.file(), location.line()); + } else { + defmt::error!("Panic at unknown location"); + } + loop { + core::hint::spin_loop(); + } +} + +defmt::timestamp!("{=u64:tus}", dk::uptime_us());