diff --git a/nrf52-code/boards/dk-solution/Cargo.lock b/nrf52-code/boards/dk-solution/Cargo.lock index 8de16adf9..80a73a1f0 100644 --- a/nrf52-code/boards/dk-solution/Cargo.lock +++ b/nrf52-code/boards/dk-solution/Cargo.lock @@ -2,12 +2,6 @@ # It is not intended for manual editing. version = 4 -[[package]] -name = "autocfg" -version = "1.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c08606f8c3cbf4ce6ec8e28fb0014a2c086708fe954eaa885384a6165172e7e8" - [[package]] name = "az" version = "1.2.1" @@ -35,17 +29,11 @@ version = "1.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" -[[package]] -name = "bitflags" -version = "2.10.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "812e12b5285cc515a9c72a5c1d3b6d46a19dac5acfef5265968c166106e31dd3" - [[package]] name = "bytemuck" -version = "1.24.0" +version = "1.23.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1fbdf580320f38b612e485521afda1ee26d10cc9884efaaa750d383e13e3c5f4" +checksum = "9134a6ef01ce4b366b50689c94f82c14bc72bc5d0386829828a2e2752ef7958c" [[package]] name = "byteorder" @@ -53,11 +41,17 @@ 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.4" +version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9330f8b2ff13f34540b44e946ef35111825727b38d33286ef986142615121801" +checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" [[package]] name = "cortex-m" @@ -109,25 +103,23 @@ checksum = "790eea4361631c5e7d22598ecd5723ff611904e3344ce8720784c93e3d83d40b" [[package]] name = "crunchy" -version = "0.2.4" +version = "0.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "460fbee9c2c2f33933d720630a6a0bac33ba7053db5344fac858d4b8952d77d5" +checksum = "43da5946c66ffcc7745f48db692ffbb10a83bfe0afd96235c5c2a4fb23994929" [[package]] name = "defmt" version = "1.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "548d977b6da32fa1d1fda2876453da1e7df63ad0304c8b3dae4dbe7b96f39b78" +source = "git+https://github.com/knurling-rs/defmt/?rev=177c219#177c2195072caa1759ebe92221f4a50204cce46c" dependencies = [ - "bitflags 1.3.2", + "bitflags", "defmt-macros", ] [[package]] name = "defmt-macros" version = "1.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3d4fc12a85bcf441cfe44344c4b72d58493178ce635338a3f3b78943aceb258e" +source = "git+https://github.com/knurling-rs/defmt/?rev=177c219#177c2195072caa1759ebe92221f4a50204cce46c" dependencies = [ "defmt-parser", "proc-macro-error2", @@ -139,17 +131,15 @@ dependencies = [ [[package]] name = "defmt-parser" version = "1.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "10d60334b3b2e7c9d91ef8150abfb6fa4c1c39ebbcf4a81c2e346aad939fee3e" +source = "git+https://github.com/knurling-rs/defmt/?rev=177c219#177c2195072caa1759ebe92221f4a50204cce46c" dependencies = [ "thiserror", ] [[package]] name = "defmt-rtt" -version = "1.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "93d5a25c99d89c40f5676bec8cefe0614f17f0f40e916f98e345dae941807f9e" +version = "1.0.0" +source = "git+https://github.com/knurling-rs/defmt/?rev=177c219#177c2195072caa1759ebe92221f4a50204cce46c" dependencies = [ "critical-section", "defmt", @@ -164,131 +154,18 @@ dependencies = [ "cortex-m-semihosting", "defmt", "defmt-rtt", - "embassy-nrf", - "embassy-time", "embedded-hal 1.0.0", "grounded", - "nb 1.1.0", -] - -[[package]] -name = "document-features" -version = "0.2.12" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d4b8a88685455ed29a21542a33abd9cb6510b6b129abadabdcef0f4c55bc8f61" -dependencies = [ - "litrs", -] - -[[package]] -name = "embassy-embedded-hal" -version = "0.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "554e3e840696f54b4c9afcf28a0f24da431c927f4151040020416e7393d6d0d8" -dependencies = [ - "embassy-futures", - "embassy-hal-internal", - "embassy-sync", - "embedded-hal 0.2.7", - "embedded-hal 1.0.0", - "embedded-hal-async", - "embedded-storage", - "embedded-storage-async", - "nb 1.1.0", -] - -[[package]] -name = "embassy-futures" -version = "0.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dc2d050bdc5c21e0862a89256ed8029ae6c290a93aecefc73084b3002cdebb01" - -[[package]] -name = "embassy-hal-internal" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "95285007a91b619dc9f26ea8f55452aa6c60f7115a4edc05085cd2bd3127cd7a" -dependencies = [ - "cortex-m", - "critical-section", - "num-traits", -] - -[[package]] -name = "embassy-nrf" -version = "0.8.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a8d63429d74ab5786cde7c9dc9a0338ea162a4da95e204ac5345c5ae36831fdb" -dependencies = [ - "bitflags 2.10.0", - "cfg-if", - "cortex-m", - "cortex-m-rt", - "critical-section", - "document-features", - "embassy-embedded-hal", - "embassy-hal-internal", - "embassy-sync", - "embassy-usb-driver", - "embedded-hal 0.2.7", - "embedded-hal 1.0.0", - "embedded-hal-async", - "embedded-io", - "embedded-io-async", - "embedded-storage", - "embedded-storage-async", - "fixed", - "nrf-pac", - "rand_core 0.6.4", - "rand_core 0.9.3", -] - -[[package]] -name = "embassy-sync" -version = "0.7.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "73974a3edbd0bd286759b3d483540f0ebef705919a5f56f4fc7709066f71689b" -dependencies = [ - "cfg-if", - "critical-section", - "embedded-io-async", - "futures-core", - "futures-sink", - "heapless", -] - -[[package]] -name = "embassy-time" -version = "0.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f4fa65b9284d974dad7a23bb72835c4ec85c0b540d86af7fc4098c88cff51d65" -dependencies = [ - "cfg-if", - "critical-section", - "document-features", - "embassy-time-driver", - "embedded-hal 0.2.7", - "embedded-hal 1.0.0", - "embedded-hal-async", - "futures-core", -] - -[[package]] -name = "embassy-time-driver" -version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a0a244c7dc22c8d0289379c8d8830cae06bb93d8f990194d0de5efb3b5ae7ba6" -dependencies = [ - "document-features", + "nrf52840-hal", ] [[package]] -name = "embassy-usb-driver" +name = "embedded-dma" version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "17119855ccc2d1f7470a39756b12068454ae27a3eabb037d940b5c03d9c77b7a" +checksum = "994f7e5b5cb23521c22304927195f236813053eb9c065dd2226a32ba64695446" dependencies = [ - "embedded-io-async", + "stable_deref_trait", ] [[package]] @@ -307,45 +184,18 @@ 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-io-async" -version = "0.6.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3ff09972d4073aa8c299395be75161d582e7629cd663171d62af73c8d50dba3f" -dependencies = [ - "embedded-io", -] - [[package]] name = "embedded-storage" version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a21dea9854beb860f3062d10228ce9b976da520a73474aed3171ec276bc0c032" -[[package]] -name = "embedded-storage-async" -version = "0.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1763775e2323b7d5f0aa6090657f5e21cfa02ede71f5dc40eead06d64dcd15cc" -dependencies = [ - "embedded-storage", -] - [[package]] name = "fixed" version = "1.29.0" @@ -358,18 +208,6 @@ dependencies = [ "typenum", ] -[[package]] -name = "futures-core" -version = "0.3.31" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "05f29059c0c2090612e8d742178b0580d2dc940c837851ad723096f87af6663e" - -[[package]] -name = "futures-sink" -version = "0.3.31" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e575fab7d1e0dcb8d0c7bcf9a63ee213816ab51902e6d244a95819acacf1d4f7" - [[package]] name = "grounded" version = "0.2.0" @@ -381,13 +219,12 @@ dependencies = [ [[package]] name = "half" -version = "2.7.1" +version = "2.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6ea2d84b969582b4b1864a92dc5d27cd2b77b622a8d79306834f1be5ba20d84b" +checksum = "459196ed295495a68f7d7fe1d84f6c4b7ff0e21fe3017b2f283c6fac3ad803c9" dependencies = [ "cfg-if", "crunchy", - "zerocopy", ] [[package]] @@ -409,12 +246,6 @@ dependencies = [ "stable_deref_trait", ] -[[package]] -name = "litrs" -version = "1.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "11d3d7f243d5c5a8b9bb5d6dd2b1602c0cb0b9db1621bafc7ed66e35ff9fe092" - [[package]] name = "nb" version = "0.1.3" @@ -431,29 +262,65 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8d5439c4ad607c3c23abf66de8c8bf57ba8adcd1f129e699851a6e43935d339d" [[package]] -name = "nrf-pac" -version = "0.1.0" +name = "nrf-hal-common" +version = "0.18.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d334027d6703534f2a80de0794ae435c0e029358d28278533d3935e69b221b01" +checksum = "0c134de1f2f0191aed3fc24d3831da8808d1e636b06edf81a5717103095f625d" dependencies = [ + "cast", + "cfg-if", "cortex-m", - "cortex-m-rt", + "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 = "num-traits" -version = "0.2.19" +name = "nrf52840-hal" +version = "0.18.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841" +checksum = "433cfd866da18dfc58376880bdebd092c130444837debc513f44edcd0d6a6558" dependencies = [ - "autocfg", + "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 = "portable-atomic" -version = "1.11.1" +version = "1.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f84267b20a16ea918e43c6a88433c2d54fa145c92a811b5b047ccbe153674483" +checksum = "350e9b48cbc6b0e028b0473b114454c6316e57336ee184ceab6e53f72c178b3e" [[package]] name = "proc-macro-error-attr2" @@ -479,18 +346,18 @@ dependencies = [ [[package]] name = "proc-macro2" -version = "1.0.103" +version = "1.0.95" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5ee95bc4ef87b8d5ba32e8b7714ccc834865276eab0aed5c9958d00ec45f49e8" +checksum = "02b3e5e68a3a1a02aad3ec490a98007cbc13c37cbe84a3cd7b8e406d76e7f778" dependencies = [ "unicode-ident", ] [[package]] name = "quote" -version = "1.0.41" +version = "1.0.40" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ce25767e7b499d1b604768e7cde645d14cc8584231ea6b295e9c9eb22c02e1d1" +checksum = "1885c039570dc00dcb4ff087a89e185fd56bae234ddc7f056a945bf36467248d" dependencies = [ "proc-macro2", ] @@ -501,12 +368,6 @@ version = "0.6.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" -[[package]] -name = "rand_core" -version = "0.9.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "99d9a13982dcf210057a8a78572b2217b667c3beacbf3a0d8b454f6f82837d38" - [[package]] name = "rustc_version" version = "0.2.3" @@ -533,15 +394,15 @@ checksum = "388a1df253eca08550bef6c72392cfe7c30914bf41df5269b68cbd6ff8f570a3" [[package]] name = "stable_deref_trait" -version = "1.2.1" +version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6ce2be8dc25455e1f91df71bfa12ad37d7af1092ae736f3a6cd0e37bc7810596" +checksum = "a8f112729512f8e442d81f95a8a7ddf2b7c6b8a1a6f509a95864142b30cab2d3" [[package]] name = "syn" -version = "2.0.108" +version = "2.0.101" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "da58917d35242480a05c2897064da0a80589a2a0476c9a3f2fdc83b53502e917" +checksum = "8ce2b7fc941b3a24138a0a7cf8e858bfc6a992e7978a068a5c760deb0ed43caf" dependencies = [ "proc-macro2", "quote", @@ -550,18 +411,18 @@ dependencies = [ [[package]] name = "thiserror" -version = "2.0.17" +version = "2.0.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f63587ca0f12b72a0600bcba1d40081f830876000bb46dd2337a3051618f4fc8" +checksum = "567b8a2dae586314f7be2a752ec7474332959c6460e02bde30d702a66d488708" dependencies = [ "thiserror-impl", ] [[package]] name = "thiserror-impl" -version = "2.0.17" +version = "2.0.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3ff15c8ecd7de3849db632e14d18d2571fa09dfc5ed93479bc4485c7a517c913" +checksum = "7f7cf42b4507d8ea322120659672cf1b9dbb93f8f2d4ecfd6e51350ff5b17a1d" dependencies = [ "proc-macro2", "quote", @@ -570,15 +431,25 @@ dependencies = [ [[package]] name = "typenum" -version = "1.19.0" +version = "1.18.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "562d481066bde0658276a35467c4af00bdc6ee726305698a55b86e61d7ad82bb" +checksum = "1dccffe3ce07af9386bfd29e80c0ab1a8205a2fc34e4bcd40364df902cfa8f3f" [[package]] name = "unicode-ident" -version = "1.0.22" +version = "1.0.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9312f7c4f6ff9069b165498234ce8be658059c6728633667c526e27dc2cf1df5" +checksum = "5a5f39404a5da50712a4c1eecf25e90dd62b613502b7e925fd4e4d19b5c96512" + +[[package]] +name = "usb-device" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "98816b1accafbb09085168b90f27e93d790b4bfa19d883466b5e53315b5f06a6" +dependencies = [ + "heapless", + "portable-atomic", +] [[package]] name = "vcell" @@ -600,23 +471,3 @@ checksum = "de437e2a6208b014ab52972a27e59b33fa2920d3e00fe05026167a1c509d19cc" dependencies = [ "vcell", ] - -[[package]] -name = "zerocopy" -version = "0.8.27" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0894878a5fa3edfd6da3f88c4805f4c8558e2b996227a3d864f47fe11e38282c" -dependencies = [ - "zerocopy-derive", -] - -[[package]] -name = "zerocopy-derive" -version = "0.8.27" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "88d2b8d9c68ad2b9e4340d7832716a4d21a22a1154777ad56ea55c51a9cf3831" -dependencies = [ - "proc-macro2", - "quote", - "syn", -] diff --git a/nrf52-code/boards/dk-solution/Cargo.toml b/nrf52-code/boards/dk-solution/Cargo.toml index ea5fa592c..e28a5c28d 100644 --- a/nrf52-code/boards/dk-solution/Cargo.toml +++ b/nrf52-code/boards/dk-solution/Cargo.toml @@ -11,11 +11,9 @@ cortex-m-rt = "0.7.5" cortex-m-semihosting = "0.5.0" defmt = "1" defmt-rtt = "1.1" -embassy-time = "0.5" embedded-hal = "1.0" -nb = "1" grounded = { version = "0.2.0", features = ["cas"] } -hal = { package = "embassy-nrf", version = "0.8", features = ["nrf52840", "unstable-pac"] } +hal = { package = "nrf52840-hal", version = "0.18.0" } [features] advanced = [] diff --git a/nrf52-code/boards/dk-solution/src/lib.rs b/nrf52-code/boards/dk-solution/src/lib.rs index 6cd09bbf0..6ad75ab29 100644 --- a/nrf52-code/boards/dk-solution/src/lib.rs +++ b/nrf52-code/boards/dk-solution/src/lib.rs @@ -1,31 +1,32 @@ //! Board Support Package (BSP) for the nRF52840 Development Kit //! -//! Based on [`embassy-nrf`](https://docs.embassy.dev/embassy-nrf/git/nrf52840/index.html) and -//! [`nrf-pac`](https://github.com/embassy-rs/nrf-pac). -//! //! See -//! -//! This copy contains support for Buttons 1 to 4. #![deny(missing_docs)] #![deny(warnings)] #![no_std] use core::{ - hint::spin_loop, + ops, sync::atomic::{self, AtomicU32, Ordering}, time::Duration, }; +use cortex_m::peripheral::NVIC; use cortex_m_semihosting::debug; -use embedded_hal::delay::DelayNs; +use embedded_hal::digital::{InputPin, OutputPin, StatefulOutputPin}; #[cfg(feature = "advanced")] use grounded::uninit::GroundedArrayCell; -pub use hal; +#[cfg(any(feature = "radio", feature = "usbd"))] +use grounded::uninit::GroundedCell; +#[cfg(feature = "radio")] +pub use hal::ieee802154; pub use hal::pac::{interrupt, Interrupt, NVIC_PRIO_BITS, RTC0}; use hal::{ - gpio::{Input, Level, Output, OutputDrive, Port}, - Peri, + clocks::{self, Clocks}, + gpio::{p0, Input, Level, Output, Pin, Port, PullUp, PushPull}, + rtc::{Rtc, RtcInterrupt}, + timer::OneShot, }; #[cfg(any(feature = "radio", feature = "advanced"))] @@ -34,32 +35,49 @@ use defmt_rtt as _; // global logger #[cfg(feature = "advanced")] mod errata; pub mod peripheral; -#[cfg(feature = "radio")] -pub mod radio; #[cfg(feature = "advanced")] pub mod usbd; +#[cfg(any(feature = "radio", feature = "usbd"))] +struct ClockSyncWrapper { + clocks: Clocks, +} + +#[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 pub leds: Leds, - /// Buttons. + /// Buttons pub buttons: Buttons, /// Timer pub timer: Timer, /// Radio interface #[cfg(feature = "radio")] - pub radio: crate::radio::Radio<'static>, + pub radio: ieee802154::Radio<'static>, /// USBD (Universal Serial Bus Device) peripheral #[cfg(any(feature = "advanced", feature = "usbd"))] - pub usbd: hal::pac::usbd::Usbd, + pub usbd: hal::pac::USBD, /// POWER (Power Supply) peripheral #[cfg(feature = "advanced")] - pub power: hal::pac::power::Power, + pub power: hal::pac::POWER, /// USB control endpoint 0 #[cfg(feature = "advanced")] pub ep0in: usbd::Ep0In, + /// Represents our current clock setup + #[cfg(any(feature = "radio", feature = "usbd"))] + pub clocks: &'static Clocks< + clocks::ExternalOscillator, + clocks::ExternalOscillator, + clocks::LfOscStarted, + >, } /// All LEDs on the board @@ -76,9 +94,7 @@ pub struct Leds { /// A single LED pub struct Led { - port: Port, - pin: u8, - inner: Output<'static>, + inner: Pin>, } impl Led { @@ -86,27 +102,37 @@ impl Led { pub fn on(&mut self) { defmt::trace!( "setting P{}.{} low (LED on)", - if self.port == Port::Port1 { '1' } else { '0' }, - self.pin + if self.inner.port() == Port::Port1 { + '1' + } else { + '0' + }, + self.inner.pin() ); - self.inner.set_low() + // NOTE this operations returns a `Result` but never returns the `Err` variant + let _ = self.inner.set_low(); } /// Turns off the LED pub fn off(&mut self) { defmt::trace!( "setting P{}.{} high (LED off)", - if self.port == Port::Port1 { '1' } else { '0' }, - self.pin + if self.inner.port() == Port::Port1 { + '1' + } else { + '0' + }, + self.inner.pin() ); - self.inner.set_high() + // NOTE this operations returns a `Result` but never returns the `Err` variant + let _ = self.inner.set_high(); } /// Returns `true` if the LED is in the OFF state pub fn is_off(&mut self) -> bool { - self.inner.is_set_high() + self.inner.is_set_high() == Ok(true) } /// Returns `true` if the LED is in the ON state @@ -138,106 +164,79 @@ pub struct Buttons { /// A single Button pub struct Button { - inner: Input<'static>, + inner: Pin>, } impl Button { /// Is the button pressed pub fn is_pressed(&mut self) -> bool { - self.inner.is_low() + self.inner.is_low() == Ok(true) } } /// A timer for creating blocking delays -pub struct Timer(hal::timer::Timer<'static>); - -impl DelayNs for Timer { - fn delay_ns(&mut self, ns: u32) { - if ns == 0 { - return; - } - self.0.stop(); - self.0.clear(); - // Write cycle count in microseconds for 1 MHz timer. - self.0.cc(0).write(ns / 1_000); - self.0.start(); - while !self.reset_if_finished() { - spin_loop(); - } - } +pub struct Timer { + inner: hal::Timer, } impl Timer { - /// Create a new timer instance which can be used for blocking delays. - pub fn new(peri: Peri<'static, T>) -> Self { - let timer = hal::timer::Timer::new(peri); - timer.set_frequency(hal::timer::Frequency::F1MHz); - timer.cc(0).short_compare_clear(); - timer.cc(0).short_compare_stop(); - Self(timer) - } - - /// Start the timer with the given microsecond duration. - pub fn start(&mut self, microseconds: u32) { - self.0.cc(0).clear_events(); - self.0.cc(0).write(microseconds); - self.0.task_clear(); - self.0.task_start(); - } - - /// If the timer has finished, resets it and returns true. - /// - /// Returns false if the timer is still running. - pub fn reset_if_finished(&mut self) -> bool { - if !self.0.cc(0).event_compare().is_triggered() { - // EVENTS_COMPARE has not been triggered yet - return false; - } - - self.0.cc(0).clear_events(); - - true - } - - /// Wait for the specified duration. + /// Blocks program execution for at least the specified `duration` pub fn wait(&mut self, duration: Duration) { defmt::trace!("blocking for {:?} ...", duration); // 1 cycle = 1 microsecond let subsec_micros = duration.subsec_micros(); if subsec_micros != 0 { - self.delay_us(subsec_micros); + self.inner.delay(subsec_micros); } - let mut millis = duration.as_secs() * 1000; - if millis == 0 { - return; + const MICROS_IN_ONE_SEC: u32 = 1_000_000; + // maximum number of seconds that fit in a single `delay` call without overflowing the `u32` + // argument + const MAX_SECS: u32 = u32::MAX / MICROS_IN_ONE_SEC; + let mut secs = duration.as_secs(); + while secs != 0 { + let cycles = if secs > MAX_SECS as u64 { + secs -= MAX_SECS as u64; + MAX_SECS * MICROS_IN_ONE_SEC + } else { + let cycles = secs as u32 * MICROS_IN_ONE_SEC; + secs = 0; + cycles + }; + + self.inner.delay(cycles) } - while millis > u32::MAX as u64 { - self.delay_ms(u32::MAX); - millis -= u32::MAX as u64; - } - self.delay_ms(millis as u32); - defmt::trace!("... DONE"); } } +impl ops::Deref for Timer { + type Target = hal::Timer; + + fn deref(&self) -> &Self::Target { + &self.inner + } +} + +impl ops::DerefMut for Timer { + fn deref_mut(&mut self) -> &mut Self::Target { + &mut self.inner + } +} + #[cfg(feature = "radio")] mod radio_retry { - use embedded_hal::delay::DelayNs as _; - - use crate::radio::{self, Packet}; + use super::ieee802154::Packet; const RETRY_COUNT: u32 = 10; const ADDR_LEN: usize = 6; fn get_id() -> [u8; ADDR_LEN] { - let ficr = hal::pac::FICR; - - let id = ficr.deviceaddr(0).read(); - let id2 = ficr.deviceaddr(1).read(); + let ficr = unsafe { &*hal::pac::FICR::ptr() }; + let id = ficr.deviceaddr[0].read().bits(); + let id2 = ficr.deviceaddr[1].read().bits(); let id = u64::from(id) << 32 | u64::from(id2); defmt::trace!("Device ID: {:#08x}", id); let id_bytes = id.to_be_bytes(); @@ -261,18 +260,21 @@ mod radio_retry { /// address in it), we try again. /// /// If we try too many times, we give up. - pub fn send_recv<'packet>( + pub fn send_recv<'packet, I>( packet: &'packet mut Packet, data_to_send: &[u8], - radio: &mut crate::radio::Radio, - timer: &mut crate::Timer, + radio: &mut hal::ieee802154::Radio, + timer: &mut hal::timer::Timer, microseconds: u32, - ) -> Result<&'packet [u8], crate::radio::Error> { + ) -> Result<&'packet [u8], hal::ieee802154::Error> + where + I: hal::timer::Instance, + { assert!(data_to_send.len() + ADDR_LEN < usize::from(Packet::CAPACITY)); let id_bytes = get_id(); // Short delay before sending, so we don't get into a tight loop and steal all the bandwidth - timer.delay_us(5000); + timer.delay(5000); for i in 0..RETRY_COUNT { packet.set_len(ADDR_LEN as u8 + data_to_send.len() as u8); let source_iter = id_bytes.iter().chain(data_to_send.iter()); @@ -292,20 +294,20 @@ mod radio_retry { return Ok(&packet[ADDR_LEN..]); } else { defmt::warn!("RX Wrong Address try {}", i); - timer.delay_us(10000); + timer.delay(10000); } } - Err(radio::Error::Timeout) => { + Err(hal::ieee802154::Error::Timeout) => { defmt::warn!("RX Timeout try {}", i); - timer.delay_us(10000); + timer.delay(10000); } - Err(radio::Error::Crc(_)) => { + Err(hal::ieee802154::Error::Crc(_)) => { defmt::warn!("RX CRC Error try {}", i); - timer.delay_us(10000); + timer.delay(10000); } } } - Err(radio::Error::Timeout) + Err(hal::ieee802154::Error::Timeout) } } @@ -323,26 +325,47 @@ pub enum Error { /// /// This return an `Err`or if called more than once pub fn init() -> Result { - // probe-rs puts us in blocking mode, so wait for blocking mode as a proxy - // for waiting for probe-rs to connect. - while !defmt_rtt::in_blocking_mode() { - core::hint::spin_loop(); - } + let Some(periph) = hal::pac::Peripherals::take() else { + return Err(Error::DoubleInit); + }; // NOTE: this branch runs at most once #[cfg(feature = "advanced")] static EP0IN_BUF: GroundedArrayCell = GroundedArrayCell::const_init(); + #[cfg(any(feature = "radio", feature = "usbd"))] + // We need the wrapper to make this type Sync, as it contains raw pointers + static CLOCKS: GroundedCell< + ClockSyncWrapper< + clocks::ExternalOscillator, + clocks::ExternalOscillator, + clocks::LfOscStarted, + >, + > = GroundedCell::uninit(); + defmt::debug!("Initializing the board"); + + let clocks = Clocks::new(periph.CLOCK); + let clocks = clocks.enable_ext_hfosc(); + let clocks = clocks.set_lfclk_src_external(clocks::LfOscConfiguration::NoExternalNoBypass); + let clocks = clocks.start_lfclk(); + let _clocks = clocks.enable_ext_hfosc(); + // extend lifetime to `'static` + #[cfg(any(feature = "radio", feature = "usbd"))] + let clocks = unsafe { + let clocks_ptr = CLOCKS.get(); + clocks_ptr.write(ClockSyncWrapper { clocks: _clocks }); + // Now it's initialised, we can take a static reference to the clocks + // object it contains. + let clock_wrapper: &'static ClockSyncWrapper<_, _, _> = &*clocks_ptr; + &clock_wrapper.clocks + }; - let mut config = hal::config::Config::default(); - config.hfclk_source = hal::config::HfclkSource::ExternalXtal; - config.lfclk_source = hal::config::LfclkSource::ExternalXtal; - let periph = hal::init(config); - - // NOTE: this branch runs at most once + defmt::debug!("Clocks configured"); - let mut rtc = hal::rtc::Rtc::new(periph.RTC0, 0).unwrap(); - // NOTE on unmasking the NVIC interrupt: Because this crate defines the `#[interrupt] fn RTC0` - // interrupt handler, RTIC cannot manage that interrupt (trying to do so results in a linker - // error). Thus it is the task of this crate to mask/unmask the interrupt in a safe manner. + let mut rtc = Rtc::new(periph.RTC0, 0).unwrap(); + rtc.enable_interrupt(RtcInterrupt::Overflow, None); + rtc.enable_counter(); + // NOTE(unsafe) because this crate defines the `#[interrupt] fn RTC0` interrupt handler, + // RTIC cannot manage that interrupt (trying to do so results in a linker error). Thus it + // is the task of this crate to mask/unmask the interrupt in a safe manner. // // Because the RTC0 interrupt handler does *not* access static variables through a critical // section (that disables interrupts) this `unmask` operation cannot break critical sections @@ -352,84 +375,71 @@ pub fn init() -> Result { // of the RTC0 peripheral from this function (which can only be called at most once) to the // interrupt handler (where the peripheral is accessed without any synchronization // mechanism) - rtc.enable_interrupt(hal::rtc::Interrupt::Overflow, true); - rtc.enable(); + unsafe { NVIC::unmask(Interrupt::RTC0) }; defmt::debug!("RTC started"); - let led1pin = Led { - port: Port::Port0, - pin: 13, - inner: Output::new(periph.P0_13, Level::High, OutputDrive::Standard), - }; - let led2pin = Led { - port: Port::Port0, - pin: 14, - inner: Output::new(periph.P0_14, Level::High, OutputDrive::Standard), - }; - let led3pin = Led { - port: Port::Port0, - pin: 15, - inner: Output::new(periph.P0_15, Level::High, OutputDrive::Standard), - }; - let led4pin = Led { - port: Port::Port0, - pin: 16, - inner: Output::new(periph.P0_16, Level::High, OutputDrive::Standard), - }; + let pins = p0::Parts::new(periph.P0); - defmt::debug!("I/O pins have been configured for digital output"); + // NOTE LEDs turn on when the pin output level is low + let led1pin = pins.p0_13.degrade().into_push_pull_output(Level::High); + let led2pin = pins.p0_14.degrade().into_push_pull_output(Level::High); + let led3pin = pins.p0_15.degrade().into_push_pull_output(Level::High); + let led4pin = pins.p0_16.degrade().into_push_pull_output(Level::High); // NOTE pin goes low when button is pressed - let button1pin = Button { - inner: Input::new(periph.P0_11, hal::gpio::Pull::Up), - }; - let button2pin = Button { - inner: Input::new(periph.P0_12, hal::gpio::Pull::Up), - }; - let button3pin = Button { - inner: Input::new(periph.P0_24, hal::gpio::Pull::Up), - }; - let button4pin = Button { - inner: Input::new(periph.P0_25, hal::gpio::Pull::Up), - }; + let button1pin = pins.p0_11.degrade().into_pullup_input(); + let button2pin = pins.p0_12.degrade().into_pullup_input(); + let button3pin = pins.p0_24.degrade().into_pullup_input(); + let button4pin = pins.p0_25.degrade().into_pullup_input(); + + defmt::debug!("I/O pins have been configured for digital output"); - let timer = Timer::new(periph.TIMER0); + let timer = hal::Timer::new(periph.TIMER0); #[cfg(feature = "radio")] let radio = { - use hal::radio::TxPower; - - let mut radio = crate::radio::Radio::new(periph.RADIO); + let mut radio = ieee802154::Radio::init(periph.RADIO, clocks); // set TX power to its maximum value - radio.set_transmission_power(TxPower::POS8_DBM); + radio.set_txpower(ieee802154::TxPower::Pos8dBm); defmt::debug!("Radio initialized and configured with TX power set to the maximum value"); 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: led1pin, - _2: led2pin, - _3: led3pin, - _4: led4pin, + _1: Led { inner: led1pin }, + _2: Led { inner: led2pin }, + _3: Led { inner: led3pin }, + _4: Led { inner: led4pin }, }, buttons: Buttons { - _1: button1pin, - _2: button2pin, - _3: button3pin, - _4: button4pin, + _1: Button { inner: button1pin }, + _2: Button { inner: button2pin }, + _3: Button { inner: button3pin }, + _4: Button { inner: button4pin }, }, #[cfg(feature = "radio")] radio, - timer, - #[cfg(feature = "advanced")] - ep0in: unsafe { usbd::Ep0In::new(&EP0IN_BUF) }, + timer: Timer { inner: timer }, #[cfg(any(feature = "advanced", feature = "usbd"))] - usbd: hal::pac::USBD, + usbd: periph.USBD, + #[cfg(feature = "advanced")] + power: periph.POWER, #[cfg(feature = "advanced")] - power: hal::pac::POWER, + ep0in: unsafe { usbd::Ep0In::new(&EP0IN_BUF) }, + #[cfg(any(feature = "radio", feature = "usbd"))] + clocks, }) } @@ -440,9 +450,13 @@ static OVERFLOWS: AtomicU32 = AtomicU32::new(0); #[interrupt] fn RTC0() { OVERFLOWS.fetch_add(1, Ordering::Release); - let rtc = hal::pac::RTC0; - // clear the EVENT register - rtc.events_ovrflw().write_value(0); + // # Safety + // Concurrent access to this field within the RTC is acceptable. + unsafe { + let rtc = hal::pac::Peripherals::steal().RTC0; + // clear the EVENT register + rtc.events_ovrflw.reset(); + } } /// Exits the application successfully when the program is executed through the @@ -498,12 +512,12 @@ pub fn uptime_ticks() -> u64 { // # Safety // Concurrent access to this field within the RTC is acceptable. - let rtc_counter = hal::pac::RTC0.counter(); + let rtc_counter = unsafe { &hal::pac::Peripherals::steal().RTC0.counter }; loop { // NOTE volatile is used to order these load operations among themselves let hi1 = OVERFLOWS.load(Ordering::Acquire); - let low = rtc_counter.read().counter(); + let low = rtc_counter.read().counter().bits(); let hi2 = OVERFLOWS.load(Ordering::Relaxed); if hi1 == hi2 { @@ -555,10 +569,14 @@ pub fn uptime_us() -> u64 { /// Returns the least-significant bits of the device identifier pub fn deviceid0() -> u32 { - hal::pac::FICR.deviceid(0).read() + // NOTE(unsafe) read-only registers, and no other use of the block + let ficr = unsafe { &*hal::pac::FICR::ptr() }; + ficr.deviceid[0].read().deviceid().bits() } /// Returns the most-significant bits of the device identifier pub fn deviceid1() -> u32 { - hal::pac::FICR.deviceid(1).read() + // NOTE(unsafe) read-only registers, and no other use of the block + let ficr = unsafe { &*hal::pac::FICR::ptr() }; + ficr.deviceid[1].read().deviceid().bits() } diff --git a/nrf52-code/boards/dk-solution/src/radio.rs b/nrf52-code/boards/dk-solution/src/radio.rs deleted file mode 100644 index 377ae25a8..000000000 --- a/nrf52-code/boards/dk-solution/src/radio.rs +++ /dev/null @@ -1,832 +0,0 @@ -//! # IEEE 802.15.4 radio driver -//! -//! This driver is a synchronous/blocking one written for a radio training. -//! A lot of its implementation is based on the -//! [nrf52840 HAL](https://github.com/nrf-rs/nrf-hal) -//! -//! [MIT license from the project](https://github.com/nrf-rs/nrf-hal/blob/master/LICENSE-MIT): -//! -//! Copyright (c) 2018 Anthony James Munns -//! -//! Permission is hereby granted, free of charge, to any -//! person obtaining a copy of this software and associated -//! documentation files (the "Software"), to deal in the -//! Software without restriction, including without -//! limitation the rights to use, copy, modify, merge, -//! publish, distribute, sublicense, and/or sell copies of -//! the Software, and to permit persons to whom the Software -//! is furnished to do so, subject to the following -//! conditions: -//! -//! THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF -//! ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED -//! TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A -//! PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT -//! SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY -//! CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -//! OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR -//! IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER -//! DEALINGS IN THE SOFTWARE. - -use core::sync::atomic::{compiler_fence, Ordering}; - -use crate::Peri; -use hal::pac::radio::regs::Shorts; -use hal::pac::radio::vals::{self, Crcstatus, State as RadioState}; -pub use hal::radio::TxPower; - -/// Default (IEEE compliant) Start of Frame Delimiter -pub const DEFAULT_SFD: u8 = 0xA7; - -/// Error -#[derive(Copy, Clone, Debug, PartialEq, defmt::Format)] -pub enum Error { - /// Incorrect CRC - Crc(u16), - /// Timeout - Timeout, -} - -/// IEEE 802.15.4 channels -/// -/// NOTE these are NOT the same as WiFi 2.4 GHz channels -#[derive(Debug, Copy, Clone, PartialEq, Eq, defmt::Format)] -pub enum Channel { - /// 2_405 MHz - _11 = 11, - /// 2_410 MHz - _12 = 12, - /// 2_415 MHz - _13 = 13, - /// 2_420 MHz - _14 = 14, - /// 2_425 MHz - _15 = 15, - /// 2_430 MHz - _16 = 16, - /// 2_435 MHz - _17 = 17, - /// 2_440 MHz - _18 = 18, - /// 2_445 MHz - _19 = 19, - /// 2_450 MHz - _20 = 20, - /// 2_455 MHz - _21 = 21, - /// 2_460 MHz - _22 = 22, - /// 2_465 MHz - _23 = 23, - /// 2_470 MHz - _24 = 24, - /// 2_475 MHz - _25 = 25, - /// 2_480 MHz - _26 = 26, -} - -impl Channel { - /// Frequency offset for the given channel. - pub const fn frequency_offset(&self) -> u32 { - (*self as u32 - 10) * 5 - } -} - -/// Driver state -/// -/// After, or at the start of, any method call the RADIO will be in one of these states -// This is a subset of the STATE_A enum -#[derive(Copy, Clone, PartialEq, Eq, defmt::Format)] -enum State { - Disabled, - RxIdle, - TxIdle, -} - -#[derive(Debug, defmt::Format)] -enum Event { - PhyEnd, -} - -/// Non-blocking receive -pub struct Recv<'a, 'c> { - radio: &'a mut Radio<'c>, -} - -impl<'a, 'c> Recv<'a, 'c> { - fn new(radio: &'a mut Radio<'c>) -> Self { - Self { radio } - } - - /// Check if receive is done - /// - /// This methods returns the `Ok` variant if the CRC included the - /// packet was successfully validated by the hardware. It returns - /// `Err(nb::Error::WouldBlock)` if a packet hasn't been received - /// yet, and `Err(nb::Error::Other)` if the CRC check failed. - pub fn is_done(&self) -> nb::Result { - let regs = self.radio.regs(); - if regs.events_end().read() == 1 { - regs.events_end().write_value(0); - - dma_end_fence(); - - let crc = regs.rxcrc().read().rxcrc() as u16; - - if regs.crcstatus().read().crcstatus() == Crcstatus::CRCOK { - Ok(crc) - } else { - Err(nb::Error::Other(crc)) - } - } else { - Err(nb::Error::WouldBlock) - } - } -} - -impl<'a, 'c> Drop for Recv<'a, 'c> { - fn drop(&mut self) { - self.radio.cancel_recv(); - } -} - -// TODO expose the other variants in `pac::CCAMODE_A` -/// Clear Channel Assessment method -pub enum Cca { - /// Carrier sense - CarrierSense, - /// Energy Detection / Energy Above Threshold - EnergyDetection { - /// Energy measurements above this value mean that the channel is assumed to be busy. - /// Note the measurement range is 0..0xFF - where 0 means that the received power was - /// less than 10 dB above the selected receiver sensitivity. This value is not given in dBm, - /// but can be converted. See the nrf52840 Product Specification Section 6.20.12.4 - /// for details. - ed_threshold: u8, - }, -} - -/// IEEE 802.15.4 radio driver. -pub struct Radio<'d> { - _p: Peri<'d, hal::peripherals::RADIO>, - needs_enable: bool, -} - -impl<'d> Radio<'d> { - /// Create a new IEEE 802.15.4 radio driver. - pub fn new(radio: Peri<'d, hal::peripherals::RADIO>) -> Self { - let r = hal::pac::RADIO; - - // Disable and enable to reset peripheral - r.power().write(|w| w.set_power(false)); - r.power().write(|w| w.set_power(true)); - - // Enable 802.15.4 mode - r.mode() - .write(|w| w.set_mode(vals::Mode::IEEE802154_250KBIT)); - // Configure CRC skip address - r.crccnf().write(|w| { - w.set_len(vals::Len::TWO); - w.set_skipaddr(vals::Skipaddr::IEEE802154); - }); - // Configure CRC polynomial and init - r.crcpoly().write(|w| w.set_crcpoly(0x0001_1021)); - r.crcinit().write(|w| w.set_crcinit(0)); - r.pcnf0().write(|w| { - // 8-bit on air length - w.set_lflen(8); - // Zero bytes S0 field length - w.set_s0len(false); - // Zero bytes S1 field length - w.set_s1len(0); - // Do not include S1 field in RAM if S1 length > 0 - w.set_s1incl(vals::S1incl::AUTOMATIC); - // Zero code Indicator length - w.set_cilen(0); - // 32-bit zero preamble - w.set_plen(vals::Plen::_32BIT_ZERO); - // Include CRC in length - w.set_crcinc(vals::Crcinc::INCLUDE); - }); - r.pcnf1().write(|w| { - // Maximum packet length - w.set_maxlen(Packet::MAX_PSDU_LEN); - // Zero static length - w.set_statlen(0); - // Zero base address length - w.set_balen(0); - // Little-endian - w.set_endian(vals::Endian::LITTLE); - // Disable packet whitening - w.set_whiteen(false); - }); - - // Enable NVIC interrupt - //T::Interrupt::unpend(); - //unsafe { T::Interrupt::enable() }; - - let mut radio = Self { - _p: radio, - needs_enable: false, - }; - - radio.set_sfd(DEFAULT_SFD); - radio.set_transmission_power_raw(0); - radio.set_channel_raw(11); - radio.set_cca(Cca::CarrierSense); - - radio - } - - /// Raw register block access. - #[inline] - pub fn regs(&self) -> hal::pac::radio::Radio { - hal::pac::RADIO - } - - /// Set the channel. - pub fn set_channel(&mut self, channel: Channel) { - self.set_channel_raw(channel as u8); - } - - /// Changes the radio channel using a raw channel ID. - pub fn set_channel_raw(&mut self, channel: u8) { - let r = self.regs(); - if !(11..=26).contains(&channel) { - panic!("Bad 802.15.4 channel"); - } - let frequency_offset = (channel - 10) * 5; - self.needs_enable = true; - r.frequency().write(|w| { - w.set_frequency(frequency_offset); - w.set_map(vals::Map::DEFAULT); - }); - } - - /// Changes the Clear Channel Assessment method - pub fn set_cca(&mut self, cca: Cca) { - let r = self.regs(); - self.needs_enable = true; - match cca { - Cca::CarrierSense => r - .ccactrl() - .write(|w| w.set_ccamode(hal::pac::radio::vals::Ccamode::CARRIER_MODE)), - Cca::EnergyDetection { ed_threshold } => { - // "[ED] is enabled by first configuring the field CCAMODE=EdMode in CCACTRL - // and writing the CCAEDTHRES field to a chosen value." - r.ccactrl().write(|w| { - w.set_ccamode(hal::pac::radio::vals::Ccamode::ED_MODE); - w.set_ccaedthres(ed_threshold); - }); - } - } - } - - /// Changes the Start of Frame Delimiter (SFD) - pub fn set_sfd(&mut self, sfd: u8) { - let r = self.regs(); - r.sfd().write(|w| w.set_sfd(sfd)); - } - - /// Clear interrupts - pub fn clear_all_interrupts(&mut self) { - let r = self.regs(); - r.intenclr().write(|w| w.0 = 0xffff_ffff); - } - - /// Changes the radio transmission power - pub fn set_transmission_power_raw(&mut self, power: i8) { - self.needs_enable = true; - - let tx_power: TxPower = match power { - 8 => TxPower::POS8_DBM, - 7 => TxPower::POS7_DBM, - 6 => TxPower::POS6_DBM, - 5 => TxPower::POS5_DBM, - 4 => TxPower::POS4_DBM, - 3 => TxPower::POS3_DBM, - 2 => TxPower::POS2_DBM, - 0 => TxPower::_0_DBM, - -4 => TxPower::NEG4_DBM, - -8 => TxPower::NEG8_DBM, - -12 => TxPower::NEG12_DBM, - -16 => TxPower::NEG16_DBM, - -20 => TxPower::NEG20_DBM, - -30 => TxPower::NEG30_DBM, - -40 => TxPower::NEG40_DBM, - _ => panic!("Invalid transmission power value"), - }; - - self.set_transmission_power(tx_power); - } - - /// Changes the radio transmission power - pub fn set_transmission_power(&mut self, power: TxPower) { - let r = self.regs(); - self.needs_enable = true; - r.txpower().write(|w| w.set_txpower(power)); - } - - /// Waits until the radio state matches the given `state` - pub fn wait_for_radio_state(&self, state: RadioState) { - while self.regs().state().read().state() != state {} - } - - /// Get the current radio state - fn state(&self) -> State { - match self.regs().state().read().state() { - // final states - RadioState::DISABLED => State::Disabled, - RadioState::TX_IDLE => State::TxIdle, - RadioState::RX_IDLE => State::RxIdle, - - // transitory states - RadioState::TX_DISABLE => { - self.wait_for_state_a(RadioState::DISABLED); - State::Disabled - } - - _ => unreachable!(), - } - } - - fn set_buffer(&mut self, buffer: &[u8]) { - self.regs().packetptr().write_value(buffer.as_ptr() as u32); - } - - /// Sample the received signal power (i.e. the presence of possibly interfering signals) - /// within the bandwidth of the currently used channel for `sample_cycles` iterations. - /// Note that one iteration has a sample time of 128μs, and that each iteration produces the - /// average RSSI value measured during this sample time. - /// - /// Returns the *maximum* measurement recorded during sampling as reported by the hardware (not in dBm!). - /// The result can be used to find a suitable ED threshold for Energy Detection-based CCA mechanisms. - /// - /// For details, see Section 6.20.12.3 Energy detection (ED) of the PS. - /// RSSI samples are averaged over a measurement time of 8 symbol periods (128 μs). - pub fn energy_detection_scan(&mut self, sample_cycles: u32) -> u8 { - let regs = self.regs(); - // Increase the time spent listening - regs.edcnt().write(|w| w.set_edcnt(sample_cycles)); - - // ensure that the shortcut between READY event and START task is disabled before putting - // the radio into recv mode - regs.shorts() - .write_value(hal::pac::radio::regs::Shorts::default()); - self.put_in_rx_mode(); - - // clear related events - regs.events_edend().write_value(0); - - // start energy detection sampling - regs.tasks_edstart().write_value(1); - - loop { - if regs.events_edend().read() == 1 { - // sampling period is over; collect value - regs.events_edend().write_value(0); - - // note that since we have increased EDCNT, the EDSAMPLE register contains the - // maximum recorded value, not the average - let read_lvl = regs.edsample().read().edlvl(); - return read_lvl; - } - } - } - - /// Receives one radio packet and copies its contents into the given `packet` buffer - /// - /// This methods returns the `Ok` variant if the CRC included the packet was successfully - /// validated by the hardware; otherwise it returns the `Err` variant. In either case, `packet` - /// will be updated with the received packet's data - pub fn recv(&mut self, packet: &mut Packet) -> Result { - // Start non-blocking receive - self.recv_non_blocking(packet, |recv| { - // Block untill receive is done - nb::block!(recv.is_done()) - }) - } - - /// Receives one radio packet and copies its contents into the given `packet` buffer - /// - /// This method is non-blocking - pub fn recv_non_blocking<'a, R>( - &'a mut self, - packet: &'a mut Packet, - f: impl FnOnce(&Recv<'a, 'd>) -> R, - ) -> R { - // Start the read - // NOTE(unsafe) - // The packet must live until the transfer is done. Receive is handled inside - // a closure to ensure this - unsafe { - self.start_recv(packet); - } - - let recv = Recv::new(self); - f(&recv) - } - - /// Listens for a packet for no longer than the specified amount of microseconds - /// and copies its contents into the given `packet` buffer - /// - /// If no packet is received within the specified time then the `Timeout` error is returned - /// - /// If a packet is received within the time span then the packet CRC is checked. If the CRC is - /// incorrect then the `Crc` error is returned; otherwise the `Ok` variant is returned. - /// Note that `packet` will contain the packet in any case, even if the CRC check failed. - /// - /// Note that the time it takes to switch the radio to RX mode is included in the timeout count. - /// This transition may take up to a hundred of microseconds; see the section 6.20.15.8 in the - /// Product Specification for more details about timing - pub fn recv_timeout( - &mut self, - packet: &mut Packet, - timer: &mut super::Timer, - microseconds: u32, - ) -> Result { - // Start the timeout timer - timer.start(microseconds); - - // Start non-blocking receive - self.recv_non_blocking(packet, |recv| { - // Check if either receive is done or timeout occured - loop { - match recv.is_done() { - Ok(crc) => break Ok(crc), - Err(err) => match err { - nb::Error::Other(crc) => break Err(Error::Crc(crc)), - nb::Error::WouldBlock => (), - }, - } - - if timer.reset_if_finished() { - // Break loop in case of timeout. Receive is - // cancelled when `recv` is dropped. - break Err(Error::Timeout); - } - } - }) - } - - unsafe fn start_recv(&mut self, packet: &mut Packet) { - let regs = self.regs(); - // NOTE we do NOT check the address of `packet` because the mutable reference ensures it's - // allocated in RAM - - // clear related events - regs.events_phyend().write_value(0); - regs.events_end().write_value(0); - - self.put_in_rx_mode(); - - // NOTE(unsafe) DMA transfer has not yet started - // set up RX buffer - self.set_buffer(packet.buffer.as_mut()); - - // start transfer - dma_start_fence(); - regs.tasks_start().write_value(1); - } - - fn cancel_recv(&mut self) { - let regs = self.regs(); - regs.tasks_stop().write_value(1); - self.wait_for_state_a(RadioState::RX_IDLE); - // DMA transfer may have been in progress so synchronize with its memory operations - dma_end_fence(); - } - - /// Tries to send the given `packet` - /// - /// This method performs Clear Channel Assessment (CCA) first and sends the `packet` only if the - /// channel is observed to be *clear* (no transmission is currently ongoing), otherwise no - /// packet is transmitted and the `Err` variant is returned - /// - /// NOTE this method will *not* modify the `packet` argument. The mutable reference is used to - /// ensure the `packet` buffer is allocated in RAM, which is required by the RADIO peripheral - // NOTE we do NOT check the address of `packet` because the mutable reference ensures it's - // allocated in RAM - #[allow(clippy::result_unit_err)] - pub fn try_send(&mut self, packet: &mut Packet) -> Result<(), ()> { - let regs = self.regs(); - // enable radio to perform cca - self.put_in_rx_mode(); - - // clear related events - regs.events_phyend().write_value(0); - regs.events_end().write_value(0); - - // NOTE(unsafe) DMA transfer has not yet started - regs.packetptr().write_value(packet.buffer.as_ptr() as u32); - - // configure radio to immediately start transmission if the channel is idle - regs.shorts().modify(|w| { - w.set_ccaidle_txen(true); - w.set_end_disable(true); - }); - - // the DMA transfer will start at some point after the following write operation so - // we place the compiler fence here - dma_start_fence(); - // start CCA. In case the channel is clear, the data at packetptr will be sent automatically - regs.tasks_ccastart().write_value(1); - - loop { - if regs.events_phyend().read() == 1 { - // transmission completed - dma_end_fence(); - regs.events_phyend().write_value(0); - regs.shorts().write_value(Shorts::default()); - return Ok(()); - } - - if regs.events_ccabusy().read() == 1 { - // channel is busy - regs.events_ccabusy().write_value(0); - regs.shorts().write_value(Shorts::default()); - return Err(()); - } - } - } - - /// Sends the given `packet` - /// - /// This is utility method that *consecutively* calls the `try_send` method until it succeeds. - /// Note that this approach is *not* IEEE spec compliant -- there must be delay between failed - /// CCA attempts to be spec compliant - /// - /// NOTE this method will *not* modify the `packet` argument. The mutable reference is used to - /// ensure the `packet` buffer is allocated in RAM, which is required by the RADIO peripheral - // NOTE we do NOT check the address of `packet` because the mutable reference ensures it's - // allocated in RAM - pub fn send(&mut self, packet: &mut Packet) { - let regs = self.regs(); - - // enable radio to perform cca - self.put_in_rx_mode(); - - // clear related events - regs.events_phyend().write_value(0); - regs.events_end().write_value(0); - - // immediately start transmission if the channel is idle - regs.shorts().modify(|w| { - w.set_ccaidle_txen(true); - w.set_txready_start(true); - w.set_end_disable(true); - }); - - // the DMA transfer will start at some point after the following write operation so - // we place the compiler fence here - dma_start_fence(); - // NOTE(unsafe) DMA transfer has not yet started - regs.packetptr().write_value(packet.buffer.as_ptr() as u32); - - 'cca: loop { - // start CCA (+ sending if channel is clear) - regs.tasks_ccastart().write_value(1); - - loop { - if regs.events_phyend().read() == 1 { - dma_end_fence(); - // transmission is complete - regs.events_phyend().write_value(0); - break 'cca; - } - - if regs.events_ccabusy().read() == 1 { - // channel is busy; try another CCA - regs.events_ccabusy().write_value(0); - continue 'cca; - } - } - } - - regs.shorts().write_value(Shorts::default()); - } - - /// Sends the specified `packet` without first performing CCA - /// - /// Acknowledgment packets must be sent using this method - /// - /// NOTE this method will *not* modify the `packet` argument. The mutable reference is used to - /// ensure the `packet` buffer is allocated in RAM, which is required by the RADIO peripheral - // NOTE we do NOT check the address of `packet` because the mutable reference ensures it's - // allocated in RAM - pub fn send_no_cca(&mut self, packet: &mut Packet) { - let regs = self.regs(); - self.put_in_tx_mode(); - - // clear related events - regs.events_phyend().write_value(0); - regs.events_end().write_value(0); - - // NOTE(unsafe) DMA transfer has not yet started - regs.packetptr().write_value(packet.buffer.as_ptr() as u32); - - // configure radio to disable transmitter once packet is sent - regs.shorts().modify(|w| w.set_end_disable(true)); - - // start DMA transfer - dma_start_fence(); - regs.tasks_start().write_value(1); - - self.wait_for_event(Event::PhyEnd); - regs.shorts().write_value(Shorts::default()); - } - - /// Moves the radio from any state to the DISABLED state - pub fn disable(&mut self) { - let regs = self.regs(); - // See figure 110 in nRF52840-PS - loop { - match regs.state().read().state() { - RadioState::DISABLED => return, - RadioState::RX_RU - | RadioState::RX_IDLE - | RadioState::TX_RU - | RadioState::TX_IDLE => { - regs.tasks_disable().write_value(1); - - self.wait_for_state_a(RadioState::DISABLED); - return; - } - RadioState::RX_DISABLE | RadioState::TX_DISABLE => { - self.wait_for_state_a(RadioState::DISABLED); - return; - } - RadioState::RX => { - regs.tasks_ccastop().write_value(1); - regs.tasks_stop().write_value(1); - self.wait_for_state_a(RadioState::RX_IDLE); - } - RadioState::TX => { - regs.tasks_stop().write_value(1); - self.wait_for_state_a(RadioState::TX_IDLE); - } - _ => (), - } - } - } - - /// Moves the radio to the RXIDLE state - fn put_in_rx_mode(&mut self) { - let regs = self.regs(); - let state = self.state(); - - let (disable, enable) = match state { - State::Disabled => (false, true), - State::RxIdle => (false, self.needs_enable), - // NOTE to avoid errata 204 (see rev1 v1.4) we do TXIDLE -> DISABLED -> RXIDLE - State::TxIdle => (true, true), - }; - - if disable { - regs.tasks_disable().write_value(1); - self.wait_for_state_a(RadioState::DISABLED); - } - - if enable { - self.needs_enable = false; - regs.tasks_rxen().write_value(1); - self.wait_for_state_a(RadioState::RX_IDLE); - } - } - - /// Moves the radio to the TXIDLE state - fn put_in_tx_mode(&mut self) { - let state = self.state(); - - if state != State::TxIdle || self.needs_enable { - self.needs_enable = false; - self.regs().tasks_rxen().write_value(1); - self.wait_for_state_a(RadioState::TX_IDLE); - } - } - - fn wait_for_event(&self, event: Event) { - match event { - Event::PhyEnd => { - while self.regs().events_phyend().read() == 0 {} - self.regs().events_phyend().write_value(0); - } - } - } - - //use hal::pac::radio::vals::State - /// Waits until the radio state matches the given `state` - fn wait_for_state_a(&self, state: RadioState) { - while self.regs().state().read().state() != state {} - } -} - -/// An IEEE 802.15.4 packet -/// -/// This `Packet` is a PHY layer packet. It's made up of the physical header (PHR) and the PSDU -/// (PHY service data unit). The PSDU of this `Packet` will always include the MAC level CRC, AKA -/// the FCS (Frame Control Sequence) -- the CRC is fully computed in hardware and automatically -/// appended on transmission and verified on reception. -/// -/// The API lets users modify the usable part (not the CRC) of the PSDU via the `deref` and -/// `copy_from_slice` methods. These methods will automatically update the PHR. -/// -/// See figure 119 in the Product Specification of the nRF52840 for more details -pub struct Packet { - buffer: [u8; Self::SIZE], -} - -// See figure 124 in nRF52840-PS -impl Packet { - // for indexing purposes - const PHY_HDR: usize = 0; - const DATA: core::ops::RangeFrom = 1..; - - /// Maximum amount of usable payload (CRC excluded) a single packet can contain, in bytes - pub const CAPACITY: u8 = 125; - const CRC: u8 = 2; // size of the CRC, which is *never* copied to / from RAM - const MAX_PSDU_LEN: u8 = Self::CAPACITY + Self::CRC; - const SIZE: usize = 1 /* PHR */ + Self::MAX_PSDU_LEN as usize; - - /// Returns an empty packet (length = 0) - pub fn new() -> Self { - let mut packet = Self { - buffer: [0; Self::SIZE], - }; - packet.set_len(0); - packet - } - - /// Fills the packet payload with given `src` data - /// - /// # Panics - /// - /// This function panics if `src` is larger than `Self::CAPACITY` - pub fn copy_from_slice(&mut self, src: &[u8]) { - assert!(src.len() <= Self::CAPACITY as usize); - let len = src.len() as u8; - self.buffer[Self::DATA][..len as usize].copy_from_slice(&src[..len.into()]); - self.set_len(len); - } - - /// Returns the size of this packet's payload - #[allow(clippy::len_without_is_empty)] - pub fn len(&self) -> u8 { - self.buffer[Self::PHY_HDR] - Self::CRC - } - - /// Changes the size of the packet's payload - /// - /// # Panics - /// - /// This function panics if `len` is larger than `Self::CAPACITY` - pub fn set_len(&mut self, len: u8) { - assert!(len <= Self::CAPACITY); - self.buffer[Self::PHY_HDR] = len + Self::CRC; - } - - /// Returns the LQI (Link Quality Indicator) of the received packet - /// - /// Note that the LQI is stored in the `Packet`'s internal buffer by the hardware so the value - /// returned by this method is only valid after a `Radio.recv` operation. Operations that - /// modify the `Packet`, like `copy_from_slice` or `set_len`+`deref_mut`, will overwrite the - /// stored LQI value. - /// - /// Also note that the hardware will *not* compute a LQI for packets smaller than 3 bytes so - /// this method will return an invalid value for those packets. - pub fn lqi(&self) -> u8 { - self.buffer[1 /* PHY_HDR */ + self.len() as usize /* data */] - } -} - -impl Default for Packet { - fn default() -> Self { - Self::new() - } -} - -impl core::ops::Deref for Packet { - type Target = [u8]; - - fn deref(&self) -> &[u8] { - &self.buffer[Self::DATA][..self.len() as usize] - } -} - -impl core::ops::DerefMut for Packet { - fn deref_mut(&mut self) -> &mut [u8] { - let len = self.len(); - &mut self.buffer[Self::DATA][..len as usize] - } -} - -/// NOTE must be followed by a volatile write operation -fn dma_start_fence() { - compiler_fence(Ordering::Release); -} - -/// NOTE must be preceded by a volatile read operation -fn dma_end_fence() { - compiler_fence(Ordering::Acquire); -} diff --git a/nrf52-code/boards/dk-solution/src/usbd.rs b/nrf52-code/boards/dk-solution/src/usbd.rs index 0e86e40cd..bb3ccbd99 100644 --- a/nrf52-code/boards/dk-solution/src/usbd.rs +++ b/nrf52-code/boards/dk-solution/src/usbd.rs @@ -3,9 +3,11 @@ use core::sync::atomic::{self, Ordering}; use grounded::uninit::GroundedArrayCell; -use hal::pac::{power::Power, usbd::Usbd}; -use crate::errata; +use crate::{ + errata, + peripheral::{POWER, USBD}, +}; /// Endpoint IN 0 pub struct Ep0In { @@ -29,7 +31,7 @@ impl Ep0In { /// /// - This function panics if the last transfer was not finished by calling the `end` function /// - This function panics if `bytes` is larger than the maximum packet size (64 bytes) - pub fn start(&mut self, bytes: &[u8], usbd: &Usbd) { + pub fn start(&mut self, bytes: &[u8], usbd: &USBD) { let (buffer_ptr, buffer_len) = self.buffer.get_ptr_len(); assert!(!self.busy, "EP0IN: last transfer has not completed"); assert!( @@ -43,9 +45,14 @@ impl Ep0In { } // use a "shortcut" to issue a status stage after the data transfer is complete - usbd.shorts().modify(|w| w.set_ep0datadone_ep0status(true)); - usbd.epin(0).maxcnt().write(|w| w.set_maxcnt(n as u8)); - usbd.epin(0).ptr().write(|w| *w = buffer_ptr as u32); + usbd.shorts + .modify(|_, w| w.ep0datadone_ep0status().set_bit()); + usbd.epin0 + .maxcnt + .write(|w| unsafe { w.maxcnt().bits(n as u8) }); + usbd.epin0 + .ptr + .write(|w| unsafe { w.ptr().bits(buffer_ptr as u32) }); self.busy = true; @@ -53,7 +60,7 @@ impl Ep0In { // start DMA transfer dma_start(); - usbd.tasks_startepin(0).write(|w| *w = 1); + usbd.tasks_startepin[0].write(|w| w.tasks_startepin().set_bit()); } /// Completes a data transfer @@ -64,13 +71,13 @@ impl Ep0In { /// /// This function panics if called before `start` or before the EP0DATADONE event is raised by /// the hardware - pub fn end(&mut self, usbd: &Usbd) { - if usbd.events_ep0datadone().read() == 0 { + pub fn end(&mut self, usbd: &USBD) { + if usbd.events_ep0datadone.read().bits() == 0 { panic!("Ep0In::end called before the EP0DATADONE event was raised"); } else { // DMA transfer complete dma_end(); - usbd.events_ep0datadone().write(|w| *w = 0); + usbd.events_ep0datadone.reset(); self.busy = false; defmt::info!("EP0IN: transfer done"); @@ -102,11 +109,11 @@ fn dma_end() { // NOTE will be called from user code; at that point the high frequency clock source has already // been configured to use to the external crystal // Reference: section 6.35.4 of the nRF52840 Product Specification -pub fn init(power: Power, usbd: &Usbd) { +pub fn init(power: POWER, usbd: &USBD) { let mut once = true; // wait until the USB cable has been connected - while power.events_usbdetected().read() == 0 { + while power.events_usbdetected.read().bits() == 0 { if once { defmt::info!("waiting for USB connection on port J3"); once = false; @@ -114,48 +121,48 @@ pub fn init(power: Power, usbd: &Usbd) { continue; } - power.events_usbdetected().write_value(0); + power.events_usbdetected.reset(); // workaround silicon bug unsafe { errata::e187a() } // enable the USB peripheral - usbd.enable().write(|w| w.set_enable(true)); + usbd.enable.write(|w| w.enable().set_bit()); // wait for the peripheral to signal it has reached the READY state - while !usbd.eventcause().read().ready() { + while usbd.eventcause.read().ready().bit_is_clear() { continue; } - // setting the bit clears the flag - usbd.eventcause().write(|w| w.set_ready(true)); + // write 1 to clear the flag + usbd.eventcause.write(|w| w.ready().clear_bit_by_one()); // if EVENTCAUSE is all zeroes then also clear the USBEVENT register - if usbd.eventcause().read().0 == 0 { - usbd.events_usbevent().write_value(0); + if usbd.eventcause.read().bits() == 0 { + usbd.events_usbevent.reset(); } // complete the silicon bug workaround unsafe { errata::e187b() } // also need to wait for the USB power supply regulator to stabilize - while power.events_usbpwrrdy().read() == 0 { + while power.events_usbpwrrdy.read().bits() == 0 { continue; } - power.events_usbpwrrdy().write_value(0); + power.events_usbpwrrdy.reset(); // before returning unmask the relevant interrupts - usbd.intenset().write(|w| { - w.set_ep0datadone(true); - w.set_ep0setup(true); - w.set_usbreset(true); + usbd.intenset.write(|w| { + w.ep0datadone().set_bit(); + w.ep0setup().set_bit(); + w.usbreset().set_bit() }); // enable the D+ line pull-up - usbd.usbpullup().write(|w| w.set_connect(true)); + usbd.usbpullup.write(|w| w.connect().set_bit()); } /// Stalls endpoint 0 -pub fn ep0stall(usbd: &Usbd) { - usbd.tasks_ep0stall().write_value(1); +pub fn ep0stall(usbd: &USBD) { + usbd.tasks_ep0stall.write(|w| w.tasks_ep0stall().set_bit()); } /// USBD.EVENTS registers mapped to an enum @@ -175,22 +182,22 @@ pub enum Event { /// /// NOTE this function will clear the corresponding the EVENT register (*) so the caller should /// handle the returned event properly. Expect for USBEVENT and EP0DATADONE -pub fn next_event(usbd: &Usbd) -> Option { - if usbd.events_usbreset().read() != 0 { - usbd.events_usbreset().write_value(0); +pub fn next_event(usbd: &USBD) -> Option { + if usbd.events_usbreset.read().bits() != 0 { + usbd.events_usbreset.reset(); return Some(Event::UsbReset); } - if usbd.events_ep0datadone().read() != 0 { + if usbd.events_ep0datadone.read().bits() != 0 { // this will be cleared by the `Ep0In::end` method // usbd.events_ep0datadone.reset(); return Some(Event::UsbEp0DataDone); } - if usbd.events_ep0setup().read() != 0 { - usbd.events_ep0setup().write_value(0); + if usbd.events_ep0setup.read().bits() != 0 { + usbd.events_ep0setup.reset(); return Some(Event::UsbEp0Setup); } @@ -199,28 +206,31 @@ pub fn next_event(usbd: &Usbd) -> Option { } /// Reads the BMREQUESTTYPE register and returns the 8-bit BMREQUESTTYPE component of a setup packet -pub fn bmrequesttype(usbd: &Usbd) -> u8 { +pub fn bmrequesttype(usbd: &USBD) -> u8 { // read the 32-bit register and extract the least significant byte // (the alternative is to read the 3 bitfields of the register and merge them into one byte) - usbd.bmrequesttype().read().0 as u8 + usbd.bmrequesttype.read().bits() as u8 } /// Reads the BREQUEST register and returns the 8-bit BREQUEST component of a setup packet -pub fn brequest(usbd: &Usbd) -> u8 { - usbd.brequest().read().brequest() as u8 +pub fn brequest(usbd: &USBD) -> u8 { + usbd.brequest.read().brequest().bits() } /// Reads the WLENGTHL and WLENGTHH registers and returns the 16-bit WLENGTH component of a setup packet -pub fn wlength(usbd: &Usbd) -> u16 { - u16::from(usbd.wlengthl().read().wlengthl()) | u16::from(usbd.wlengthh().read().wlengthh()) << 8 +pub fn wlength(usbd: &USBD) -> u16 { + u16::from(usbd.wlengthl.read().wlengthl().bits()) + | u16::from(usbd.wlengthh.read().wlengthh().bits()) << 8 } /// Reads the WINDEXL and WINDEXH registers and returns the 16-bit WINDEX component of a setup packet -pub fn windex(usbd: &Usbd) -> u16 { - u16::from(usbd.windexl().read().windexl()) | u16::from(usbd.windexh().read().windexh()) << 8 +pub fn windex(usbd: &USBD) -> u16 { + u16::from(usbd.windexl.read().windexl().bits()) + | u16::from(usbd.windexh.read().windexh().bits()) << 8 } /// Reads the WVALUEL and WVALUEH registers and returns the 16-bit WVALUE component of a setup packet -pub fn wvalue(usbd: &Usbd) -> u16 { - u16::from(usbd.wvaluel().read().wvaluel()) | u16::from(usbd.wvalueh().read().wvalueh()) << 8 +pub fn wvalue(usbd: &USBD) -> u16 { + u16::from(usbd.wvaluel.read().wvaluel().bits()) + | u16::from(usbd.wvalueh.read().wvalueh().bits()) << 8 } diff --git a/nrf52-code/boards/dk/Cargo.lock b/nrf52-code/boards/dk/Cargo.lock index 8de16adf9..80a73a1f0 100644 --- a/nrf52-code/boards/dk/Cargo.lock +++ b/nrf52-code/boards/dk/Cargo.lock @@ -2,12 +2,6 @@ # It is not intended for manual editing. version = 4 -[[package]] -name = "autocfg" -version = "1.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c08606f8c3cbf4ce6ec8e28fb0014a2c086708fe954eaa885384a6165172e7e8" - [[package]] name = "az" version = "1.2.1" @@ -35,17 +29,11 @@ version = "1.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" -[[package]] -name = "bitflags" -version = "2.10.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "812e12b5285cc515a9c72a5c1d3b6d46a19dac5acfef5265968c166106e31dd3" - [[package]] name = "bytemuck" -version = "1.24.0" +version = "1.23.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1fbdf580320f38b612e485521afda1ee26d10cc9884efaaa750d383e13e3c5f4" +checksum = "9134a6ef01ce4b366b50689c94f82c14bc72bc5d0386829828a2e2752ef7958c" [[package]] name = "byteorder" @@ -53,11 +41,17 @@ 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.4" +version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9330f8b2ff13f34540b44e946ef35111825727b38d33286ef986142615121801" +checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" [[package]] name = "cortex-m" @@ -109,25 +103,23 @@ checksum = "790eea4361631c5e7d22598ecd5723ff611904e3344ce8720784c93e3d83d40b" [[package]] name = "crunchy" -version = "0.2.4" +version = "0.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "460fbee9c2c2f33933d720630a6a0bac33ba7053db5344fac858d4b8952d77d5" +checksum = "43da5946c66ffcc7745f48db692ffbb10a83bfe0afd96235c5c2a4fb23994929" [[package]] name = "defmt" version = "1.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "548d977b6da32fa1d1fda2876453da1e7df63ad0304c8b3dae4dbe7b96f39b78" +source = "git+https://github.com/knurling-rs/defmt/?rev=177c219#177c2195072caa1759ebe92221f4a50204cce46c" dependencies = [ - "bitflags 1.3.2", + "bitflags", "defmt-macros", ] [[package]] name = "defmt-macros" version = "1.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3d4fc12a85bcf441cfe44344c4b72d58493178ce635338a3f3b78943aceb258e" +source = "git+https://github.com/knurling-rs/defmt/?rev=177c219#177c2195072caa1759ebe92221f4a50204cce46c" dependencies = [ "defmt-parser", "proc-macro-error2", @@ -139,17 +131,15 @@ dependencies = [ [[package]] name = "defmt-parser" version = "1.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "10d60334b3b2e7c9d91ef8150abfb6fa4c1c39ebbcf4a81c2e346aad939fee3e" +source = "git+https://github.com/knurling-rs/defmt/?rev=177c219#177c2195072caa1759ebe92221f4a50204cce46c" dependencies = [ "thiserror", ] [[package]] name = "defmt-rtt" -version = "1.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "93d5a25c99d89c40f5676bec8cefe0614f17f0f40e916f98e345dae941807f9e" +version = "1.0.0" +source = "git+https://github.com/knurling-rs/defmt/?rev=177c219#177c2195072caa1759ebe92221f4a50204cce46c" dependencies = [ "critical-section", "defmt", @@ -164,131 +154,18 @@ dependencies = [ "cortex-m-semihosting", "defmt", "defmt-rtt", - "embassy-nrf", - "embassy-time", "embedded-hal 1.0.0", "grounded", - "nb 1.1.0", -] - -[[package]] -name = "document-features" -version = "0.2.12" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d4b8a88685455ed29a21542a33abd9cb6510b6b129abadabdcef0f4c55bc8f61" -dependencies = [ - "litrs", -] - -[[package]] -name = "embassy-embedded-hal" -version = "0.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "554e3e840696f54b4c9afcf28a0f24da431c927f4151040020416e7393d6d0d8" -dependencies = [ - "embassy-futures", - "embassy-hal-internal", - "embassy-sync", - "embedded-hal 0.2.7", - "embedded-hal 1.0.0", - "embedded-hal-async", - "embedded-storage", - "embedded-storage-async", - "nb 1.1.0", -] - -[[package]] -name = "embassy-futures" -version = "0.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dc2d050bdc5c21e0862a89256ed8029ae6c290a93aecefc73084b3002cdebb01" - -[[package]] -name = "embassy-hal-internal" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "95285007a91b619dc9f26ea8f55452aa6c60f7115a4edc05085cd2bd3127cd7a" -dependencies = [ - "cortex-m", - "critical-section", - "num-traits", -] - -[[package]] -name = "embassy-nrf" -version = "0.8.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a8d63429d74ab5786cde7c9dc9a0338ea162a4da95e204ac5345c5ae36831fdb" -dependencies = [ - "bitflags 2.10.0", - "cfg-if", - "cortex-m", - "cortex-m-rt", - "critical-section", - "document-features", - "embassy-embedded-hal", - "embassy-hal-internal", - "embassy-sync", - "embassy-usb-driver", - "embedded-hal 0.2.7", - "embedded-hal 1.0.0", - "embedded-hal-async", - "embedded-io", - "embedded-io-async", - "embedded-storage", - "embedded-storage-async", - "fixed", - "nrf-pac", - "rand_core 0.6.4", - "rand_core 0.9.3", -] - -[[package]] -name = "embassy-sync" -version = "0.7.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "73974a3edbd0bd286759b3d483540f0ebef705919a5f56f4fc7709066f71689b" -dependencies = [ - "cfg-if", - "critical-section", - "embedded-io-async", - "futures-core", - "futures-sink", - "heapless", -] - -[[package]] -name = "embassy-time" -version = "0.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f4fa65b9284d974dad7a23bb72835c4ec85c0b540d86af7fc4098c88cff51d65" -dependencies = [ - "cfg-if", - "critical-section", - "document-features", - "embassy-time-driver", - "embedded-hal 0.2.7", - "embedded-hal 1.0.0", - "embedded-hal-async", - "futures-core", -] - -[[package]] -name = "embassy-time-driver" -version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a0a244c7dc22c8d0289379c8d8830cae06bb93d8f990194d0de5efb3b5ae7ba6" -dependencies = [ - "document-features", + "nrf52840-hal", ] [[package]] -name = "embassy-usb-driver" +name = "embedded-dma" version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "17119855ccc2d1f7470a39756b12068454ae27a3eabb037d940b5c03d9c77b7a" +checksum = "994f7e5b5cb23521c22304927195f236813053eb9c065dd2226a32ba64695446" dependencies = [ - "embedded-io-async", + "stable_deref_trait", ] [[package]] @@ -307,45 +184,18 @@ 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-io-async" -version = "0.6.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3ff09972d4073aa8c299395be75161d582e7629cd663171d62af73c8d50dba3f" -dependencies = [ - "embedded-io", -] - [[package]] name = "embedded-storage" version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a21dea9854beb860f3062d10228ce9b976da520a73474aed3171ec276bc0c032" -[[package]] -name = "embedded-storage-async" -version = "0.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1763775e2323b7d5f0aa6090657f5e21cfa02ede71f5dc40eead06d64dcd15cc" -dependencies = [ - "embedded-storage", -] - [[package]] name = "fixed" version = "1.29.0" @@ -358,18 +208,6 @@ dependencies = [ "typenum", ] -[[package]] -name = "futures-core" -version = "0.3.31" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "05f29059c0c2090612e8d742178b0580d2dc940c837851ad723096f87af6663e" - -[[package]] -name = "futures-sink" -version = "0.3.31" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e575fab7d1e0dcb8d0c7bcf9a63ee213816ab51902e6d244a95819acacf1d4f7" - [[package]] name = "grounded" version = "0.2.0" @@ -381,13 +219,12 @@ dependencies = [ [[package]] name = "half" -version = "2.7.1" +version = "2.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6ea2d84b969582b4b1864a92dc5d27cd2b77b622a8d79306834f1be5ba20d84b" +checksum = "459196ed295495a68f7d7fe1d84f6c4b7ff0e21fe3017b2f283c6fac3ad803c9" dependencies = [ "cfg-if", "crunchy", - "zerocopy", ] [[package]] @@ -409,12 +246,6 @@ dependencies = [ "stable_deref_trait", ] -[[package]] -name = "litrs" -version = "1.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "11d3d7f243d5c5a8b9bb5d6dd2b1602c0cb0b9db1621bafc7ed66e35ff9fe092" - [[package]] name = "nb" version = "0.1.3" @@ -431,29 +262,65 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8d5439c4ad607c3c23abf66de8c8bf57ba8adcd1f129e699851a6e43935d339d" [[package]] -name = "nrf-pac" -version = "0.1.0" +name = "nrf-hal-common" +version = "0.18.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d334027d6703534f2a80de0794ae435c0e029358d28278533d3935e69b221b01" +checksum = "0c134de1f2f0191aed3fc24d3831da8808d1e636b06edf81a5717103095f625d" dependencies = [ + "cast", + "cfg-if", "cortex-m", - "cortex-m-rt", + "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 = "num-traits" -version = "0.2.19" +name = "nrf52840-hal" +version = "0.18.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841" +checksum = "433cfd866da18dfc58376880bdebd092c130444837debc513f44edcd0d6a6558" dependencies = [ - "autocfg", + "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 = "portable-atomic" -version = "1.11.1" +version = "1.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f84267b20a16ea918e43c6a88433c2d54fa145c92a811b5b047ccbe153674483" +checksum = "350e9b48cbc6b0e028b0473b114454c6316e57336ee184ceab6e53f72c178b3e" [[package]] name = "proc-macro-error-attr2" @@ -479,18 +346,18 @@ dependencies = [ [[package]] name = "proc-macro2" -version = "1.0.103" +version = "1.0.95" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5ee95bc4ef87b8d5ba32e8b7714ccc834865276eab0aed5c9958d00ec45f49e8" +checksum = "02b3e5e68a3a1a02aad3ec490a98007cbc13c37cbe84a3cd7b8e406d76e7f778" dependencies = [ "unicode-ident", ] [[package]] name = "quote" -version = "1.0.41" +version = "1.0.40" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ce25767e7b499d1b604768e7cde645d14cc8584231ea6b295e9c9eb22c02e1d1" +checksum = "1885c039570dc00dcb4ff087a89e185fd56bae234ddc7f056a945bf36467248d" dependencies = [ "proc-macro2", ] @@ -501,12 +368,6 @@ version = "0.6.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" -[[package]] -name = "rand_core" -version = "0.9.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "99d9a13982dcf210057a8a78572b2217b667c3beacbf3a0d8b454f6f82837d38" - [[package]] name = "rustc_version" version = "0.2.3" @@ -533,15 +394,15 @@ checksum = "388a1df253eca08550bef6c72392cfe7c30914bf41df5269b68cbd6ff8f570a3" [[package]] name = "stable_deref_trait" -version = "1.2.1" +version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6ce2be8dc25455e1f91df71bfa12ad37d7af1092ae736f3a6cd0e37bc7810596" +checksum = "a8f112729512f8e442d81f95a8a7ddf2b7c6b8a1a6f509a95864142b30cab2d3" [[package]] name = "syn" -version = "2.0.108" +version = "2.0.101" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "da58917d35242480a05c2897064da0a80589a2a0476c9a3f2fdc83b53502e917" +checksum = "8ce2b7fc941b3a24138a0a7cf8e858bfc6a992e7978a068a5c760deb0ed43caf" dependencies = [ "proc-macro2", "quote", @@ -550,18 +411,18 @@ dependencies = [ [[package]] name = "thiserror" -version = "2.0.17" +version = "2.0.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f63587ca0f12b72a0600bcba1d40081f830876000bb46dd2337a3051618f4fc8" +checksum = "567b8a2dae586314f7be2a752ec7474332959c6460e02bde30d702a66d488708" dependencies = [ "thiserror-impl", ] [[package]] name = "thiserror-impl" -version = "2.0.17" +version = "2.0.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3ff15c8ecd7de3849db632e14d18d2571fa09dfc5ed93479bc4485c7a517c913" +checksum = "7f7cf42b4507d8ea322120659672cf1b9dbb93f8f2d4ecfd6e51350ff5b17a1d" dependencies = [ "proc-macro2", "quote", @@ -570,15 +431,25 @@ dependencies = [ [[package]] name = "typenum" -version = "1.19.0" +version = "1.18.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "562d481066bde0658276a35467c4af00bdc6ee726305698a55b86e61d7ad82bb" +checksum = "1dccffe3ce07af9386bfd29e80c0ab1a8205a2fc34e4bcd40364df902cfa8f3f" [[package]] name = "unicode-ident" -version = "1.0.22" +version = "1.0.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9312f7c4f6ff9069b165498234ce8be658059c6728633667c526e27dc2cf1df5" +checksum = "5a5f39404a5da50712a4c1eecf25e90dd62b613502b7e925fd4e4d19b5c96512" + +[[package]] +name = "usb-device" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "98816b1accafbb09085168b90f27e93d790b4bfa19d883466b5e53315b5f06a6" +dependencies = [ + "heapless", + "portable-atomic", +] [[package]] name = "vcell" @@ -600,23 +471,3 @@ checksum = "de437e2a6208b014ab52972a27e59b33fa2920d3e00fe05026167a1c509d19cc" dependencies = [ "vcell", ] - -[[package]] -name = "zerocopy" -version = "0.8.27" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0894878a5fa3edfd6da3f88c4805f4c8558e2b996227a3d864f47fe11e38282c" -dependencies = [ - "zerocopy-derive", -] - -[[package]] -name = "zerocopy-derive" -version = "0.8.27" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "88d2b8d9c68ad2b9e4340d7832716a4d21a22a1154777ad56ea55c51a9cf3831" -dependencies = [ - "proc-macro2", - "quote", - "syn", -] diff --git a/nrf52-code/boards/dk/Cargo.toml b/nrf52-code/boards/dk/Cargo.toml index ea5fa592c..e28a5c28d 100644 --- a/nrf52-code/boards/dk/Cargo.toml +++ b/nrf52-code/boards/dk/Cargo.toml @@ -11,11 +11,9 @@ cortex-m-rt = "0.7.5" cortex-m-semihosting = "0.5.0" defmt = "1" defmt-rtt = "1.1" -embassy-time = "0.5" embedded-hal = "1.0" -nb = "1" grounded = { version = "0.2.0", features = ["cas"] } -hal = { package = "embassy-nrf", version = "0.8", features = ["nrf52840", "unstable-pac"] } +hal = { package = "nrf52840-hal", version = "0.18.0" } [features] advanced = [] diff --git a/nrf52-code/boards/dk/src/lib.rs b/nrf52-code/boards/dk/src/lib.rs index 08fda59e2..cea8004c4 100644 --- a/nrf52-code/boards/dk/src/lib.rs +++ b/nrf52-code/boards/dk/src/lib.rs @@ -1,8 +1,5 @@ //! Board Support Package (BSP) for the nRF52840 Development Kit //! -//! Based on [`embassy-nrf`](https://docs.embassy.dev/embassy-nrf/git/nrf52840/index.html) and -//! [`nrf-pac`](https://github.com/embassy-rs/nrf-pac). -//! //! See #![deny(missing_docs)] @@ -10,20 +7,26 @@ #![no_std] use core::{ - hint::spin_loop, + ops, sync::atomic::{self, AtomicU32, Ordering}, time::Duration, }; +use cortex_m::peripheral::NVIC; use cortex_m_semihosting::debug; -use embedded_hal::delay::DelayNs; +use embedded_hal::digital::{OutputPin, StatefulOutputPin}; #[cfg(feature = "advanced")] use grounded::uninit::GroundedArrayCell; -pub use hal; +#[cfg(any(feature = "radio", feature = "usbd"))] +use grounded::uninit::GroundedCell; +#[cfg(feature = "radio")] +pub use hal::ieee802154; pub use hal::pac::{interrupt, Interrupt, NVIC_PRIO_BITS, RTC0}; use hal::{ - gpio::{Level, Output, OutputDrive, Port}, - Peri, + clocks::{self, Clocks}, + gpio::{p0, Level, Output, Pin, Port, PushPull}, + rtc::{Rtc, RtcInterrupt}, + timer::OneShot, }; #[cfg(any(feature = "radio", feature = "advanced"))] @@ -32,11 +35,21 @@ use defmt_rtt as _; // global logger #[cfg(feature = "advanced")] mod errata; pub mod peripheral; -#[cfg(feature = "radio")] -pub mod radio; #[cfg(feature = "advanced")] pub mod usbd; +#[cfg(any(feature = "radio", feature = "usbd"))] +struct ClockSyncWrapper { + clocks: Clocks, +} + +#[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 @@ -46,16 +59,23 @@ pub struct Board { /// Radio interface #[cfg(feature = "radio")] - pub radio: crate::radio::Radio<'static>, + pub radio: ieee802154::Radio<'static>, /// USBD (Universal Serial Bus Device) peripheral #[cfg(any(feature = "advanced", feature = "usbd"))] - pub usbd: hal::pac::usbd::Usbd, + pub usbd: hal::pac::USBD, /// POWER (Power Supply) peripheral #[cfg(feature = "advanced")] - pub power: hal::pac::power::Power, + pub power: hal::pac::POWER, /// USB control endpoint 0 #[cfg(feature = "advanced")] pub ep0in: usbd::Ep0In, + /// Represents our current clock setup + #[cfg(any(feature = "radio", feature = "usbd"))] + pub clocks: &'static Clocks< + clocks::ExternalOscillator, + clocks::ExternalOscillator, + clocks::LfOscStarted, + >, } /// All LEDs on the board @@ -72,9 +92,7 @@ pub struct Leds { /// A single LED pub struct Led { - port: Port, - pin: u8, - inner: Output<'static>, + inner: Pin>, } impl Led { @@ -82,27 +100,37 @@ impl Led { pub fn on(&mut self) { defmt::trace!( "setting P{}.{} low (LED on)", - if self.port == Port::Port1 { '1' } else { '0' }, - self.pin + if self.inner.port() == Port::Port1 { + '1' + } else { + '0' + }, + self.inner.pin() ); - self.inner.set_low() + // NOTE this operations returns a `Result` but never returns the `Err` variant + let _ = self.inner.set_low(); } /// Turns off the LED pub fn off(&mut self) { defmt::trace!( "setting P{}.{} high (LED off)", - if self.port == Port::Port1 { '1' } else { '0' }, - self.pin + if self.inner.port() == Port::Port1 { + '1' + } else { + '0' + }, + self.inner.pin() ); - self.inner.set_high() + // NOTE this operations returns a `Result` but never returns the `Err` variant + let _ = self.inner.set_high(); } /// Returns `true` if the LED is in the OFF state pub fn is_off(&mut self) -> bool { - self.inner.is_set_high() + self.inner.is_set_high() == Ok(true) } /// Returns `true` if the LED is in the ON state @@ -121,95 +149,68 @@ impl Led { } /// A timer for creating blocking delays -pub struct Timer(hal::timer::Timer<'static>); - -impl DelayNs for Timer { - fn delay_ns(&mut self, ns: u32) { - if ns == 0 { - return; - } - self.0.stop(); - self.0.clear(); - // Write cycle count in microseconds for 1 MHz timer. - self.0.cc(0).write(ns / 1_000); - self.0.start(); - while !self.reset_if_finished() { - spin_loop(); - } - } +pub struct Timer { + inner: hal::Timer, } impl Timer { - /// Create a new timer instance which can be used for blocking delays. - pub fn new(peri: Peri<'static, T>) -> Self { - let timer = hal::timer::Timer::new(peri); - timer.set_frequency(hal::timer::Frequency::F1MHz); - timer.cc(0).short_compare_clear(); - timer.cc(0).short_compare_stop(); - Self(timer) - } - - /// Start the timer with the given microsecond duration. - pub fn start(&mut self, microseconds: u32) { - self.0.cc(0).clear_events(); - self.0.cc(0).write(microseconds); - self.0.task_clear(); - self.0.task_start(); - } - - /// If the timer has finished, resets it and returns true. - /// - /// Returns false if the timer is still running. - pub fn reset_if_finished(&mut self) -> bool { - if !self.0.cc(0).event_compare().is_triggered() { - // EVENTS_COMPARE has not been triggered yet - return false; - } - - self.0.cc(0).clear_events(); - - true - } - - /// Wait for the specified duration. + /// Blocks program execution for at least the specified `duration` pub fn wait(&mut self, duration: Duration) { defmt::trace!("blocking for {:?} ...", duration); // 1 cycle = 1 microsecond let subsec_micros = duration.subsec_micros(); if subsec_micros != 0 { - self.delay_us(subsec_micros); + self.inner.delay(subsec_micros); } - let mut millis = duration.as_secs() * 1000; - if millis == 0 { - return; + const MICROS_IN_ONE_SEC: u32 = 1_000_000; + // maximum number of seconds that fit in a single `delay` call without overflowing the `u32` + // argument + const MAX_SECS: u32 = u32::MAX / MICROS_IN_ONE_SEC; + let mut secs = duration.as_secs(); + while secs != 0 { + let cycles = if secs > MAX_SECS as u64 { + secs -= MAX_SECS as u64; + MAX_SECS * MICROS_IN_ONE_SEC + } else { + let cycles = secs as u32 * MICROS_IN_ONE_SEC; + secs = 0; + cycles + }; + + self.inner.delay(cycles) } - while millis > u32::MAX as u64 { - self.delay_ms(u32::MAX); - millis -= u32::MAX as u64; - } - self.delay_ms(millis as u32); - defmt::trace!("... DONE"); } } +impl ops::Deref for Timer { + type Target = hal::Timer; + + fn deref(&self) -> &Self::Target { + &self.inner + } +} + +impl ops::DerefMut for Timer { + fn deref_mut(&mut self) -> &mut Self::Target { + &mut self.inner + } +} + #[cfg(feature = "radio")] mod radio_retry { - use embedded_hal::delay::DelayNs as _; - - use crate::radio::{self, Packet}; + use super::ieee802154::Packet; const RETRY_COUNT: u32 = 10; const ADDR_LEN: usize = 6; fn get_id() -> [u8; ADDR_LEN] { - let ficr = hal::pac::FICR; - - let id = ficr.deviceaddr(0).read(); - let id2 = ficr.deviceaddr(1).read(); + let ficr = unsafe { &*hal::pac::FICR::ptr() }; + let id = ficr.deviceaddr[0].read().bits(); + let id2 = ficr.deviceaddr[1].read().bits(); let id = u64::from(id) << 32 | u64::from(id2); defmt::trace!("Device ID: {:#08x}", id); let id_bytes = id.to_be_bytes(); @@ -233,18 +234,21 @@ mod radio_retry { /// address in it), we try again. /// /// If we try too many times, we give up. - pub fn send_recv<'packet>( + pub fn send_recv<'packet, I>( packet: &'packet mut Packet, data_to_send: &[u8], - radio: &mut crate::radio::Radio, - timer: &mut crate::Timer, + radio: &mut hal::ieee802154::Radio, + timer: &mut hal::timer::Timer, microseconds: u32, - ) -> Result<&'packet [u8], crate::radio::Error> { + ) -> Result<&'packet [u8], hal::ieee802154::Error> + where + I: hal::timer::Instance, + { assert!(data_to_send.len() + ADDR_LEN < usize::from(Packet::CAPACITY)); let id_bytes = get_id(); // Short delay before sending, so we don't get into a tight loop and steal all the bandwidth - timer.delay_us(5000); + timer.delay(5000); for i in 0..RETRY_COUNT { packet.set_len(ADDR_LEN as u8 + data_to_send.len() as u8); let source_iter = id_bytes.iter().chain(data_to_send.iter()); @@ -264,20 +268,20 @@ mod radio_retry { return Ok(&packet[ADDR_LEN..]); } else { defmt::warn!("RX Wrong Address try {}", i); - timer.delay_us(10000); + timer.delay(10000); } } - Err(radio::Error::Timeout) => { + Err(hal::ieee802154::Error::Timeout) => { defmt::warn!("RX Timeout try {}", i); - timer.delay_us(10000); + timer.delay(10000); } - Err(radio::Error::Crc(_)) => { + Err(hal::ieee802154::Error::Crc(_)) => { defmt::warn!("RX CRC Error try {}", i); - timer.delay_us(10000); + timer.delay(10000); } } } - Err(radio::Error::Timeout) + Err(hal::ieee802154::Error::Timeout) } } @@ -300,21 +304,48 @@ pub fn init() -> Result { while !defmt_rtt::in_blocking_mode() { core::hint::spin_loop(); } + + let Some(periph) = hal::pac::Peripherals::take() else { + return Err(Error::DoubleInit); + }; // NOTE: this branch runs at most once #[cfg(feature = "advanced")] static EP0IN_BUF: GroundedArrayCell = GroundedArrayCell::const_init(); + #[cfg(any(feature = "radio", feature = "usbd"))] + // We need the wrapper to make this type Sync, as it contains raw pointers + static CLOCKS: GroundedCell< + ClockSyncWrapper< + clocks::ExternalOscillator, + clocks::ExternalOscillator, + clocks::LfOscStarted, + >, + > = GroundedCell::uninit(); + defmt::debug!("Initializing the board"); + + let clocks = Clocks::new(periph.CLOCK); + let clocks = clocks.enable_ext_hfosc(); + let clocks = clocks.set_lfclk_src_external(clocks::LfOscConfiguration::NoExternalNoBypass); + let clocks = clocks.start_lfclk(); + let _clocks = clocks.enable_ext_hfosc(); + // extend lifetime to `'static` + #[cfg(any(feature = "radio", feature = "usbd"))] + let clocks = unsafe { + let clocks_ptr = CLOCKS.get(); + clocks_ptr.write(ClockSyncWrapper { clocks: _clocks }); + // Now it's initialised, we can take a static reference to the clocks + // object it contains. + let clock_wrapper: &'static ClockSyncWrapper<_, _, _> = &*clocks_ptr; + &clock_wrapper.clocks + }; - let mut config = hal::config::Config::default(); - config.hfclk_source = hal::config::HfclkSource::ExternalXtal; - config.lfclk_source = hal::config::LfclkSource::ExternalXtal; - let periph = hal::init(config); - - // NOTE: this branch runs at most once + defmt::debug!("Clocks configured"); - let mut rtc = hal::rtc::Rtc::new(periph.RTC0, 0).unwrap(); - // NOTE on unmasking the NVIC interrupt: Because this crate defines the `#[interrupt] fn RTC0` - // interrupt handler, RTIC cannot manage that interrupt (trying to do so results in a linker - // error). Thus it is the task of this crate to mask/unmask the interrupt in a safe manner. + let mut rtc = Rtc::new(periph.RTC0, 0).unwrap(); + rtc.enable_interrupt(RtcInterrupt::Overflow, None); + rtc.enable_counter(); + // NOTE(unsafe) because this crate defines the `#[interrupt] fn RTC0` interrupt handler, + // RTIC cannot manage that interrupt (trying to do so results in a linker error). Thus it + // is the task of this crate to mask/unmask the interrupt in a safe manner. // // Because the RTC0 interrupt handler does *not* access static variables through a critical // section (that disables interrupts) this `unmask` operation cannot break critical sections @@ -324,64 +355,59 @@ pub fn init() -> Result { // of the RTC0 peripheral from this function (which can only be called at most once) to the // interrupt handler (where the peripheral is accessed without any synchronization // mechanism) - rtc.enable_interrupt(hal::rtc::Interrupt::Overflow, true); - rtc.enable(); + unsafe { NVIC::unmask(Interrupt::RTC0) }; defmt::debug!("RTC started"); - let led1pin = Led { - port: Port::Port0, - pin: 13, - inner: Output::new(periph.P0_13, Level::High, OutputDrive::Standard), - }; - let led2pin = Led { - port: Port::Port0, - pin: 14, - inner: Output::new(periph.P0_14, Level::High, OutputDrive::Standard), - }; - let led3pin = Led { - port: Port::Port0, - pin: 15, - inner: Output::new(periph.P0_15, Level::High, OutputDrive::Standard), - }; - let led4pin = Led { - port: Port::Port0, - pin: 16, - inner: Output::new(periph.P0_16, Level::High, OutputDrive::Standard), - }; + let pins = p0::Parts::new(periph.P0); + + // NOTE LEDs turn on when the pin output level is low + let led1pin = pins.p0_13.degrade().into_push_pull_output(Level::High); + let led2pin = pins.p0_14.degrade().into_push_pull_output(Level::High); + let led3pin = pins.p0_15.degrade().into_push_pull_output(Level::High); + let led4pin = pins.p0_16.degrade().into_push_pull_output(Level::High); defmt::debug!("I/O pins have been configured for digital output"); - let timer = Timer::new(periph.TIMER0); + let timer = hal::Timer::new(periph.TIMER0); #[cfg(feature = "radio")] let radio = { - use hal::radio::TxPower; - - let mut radio = crate::radio::Radio::new(periph.RADIO); + let mut radio = ieee802154::Radio::init(periph.RADIO, clocks); // set TX power to its maximum value - radio.set_transmission_power(TxPower::POS8_DBM); + radio.set_txpower(ieee802154::TxPower::Pos8dBm); defmt::debug!("Radio initialized and configured with TX power set to the maximum value"); 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: led1pin, - _2: led2pin, - _3: led3pin, - _4: led4pin, + _1: Led { inner: led1pin }, + _2: Led { inner: led2pin }, + _3: Led { inner: led3pin }, + _4: Led { inner: led4pin }, }, #[cfg(feature = "radio")] radio, - timer, - #[cfg(feature = "advanced")] - ep0in: unsafe { usbd::Ep0In::new(&EP0IN_BUF) }, + timer: Timer { inner: timer }, #[cfg(any(feature = "advanced", feature = "usbd"))] - usbd: hal::pac::USBD, + usbd: periph.USBD, #[cfg(feature = "advanced")] - power: hal::pac::POWER, + power: periph.POWER, + #[cfg(feature = "advanced")] + ep0in: unsafe { usbd::Ep0In::new(&EP0IN_BUF) }, + #[cfg(any(feature = "radio", feature = "usbd"))] + clocks, }) } @@ -392,9 +418,13 @@ static OVERFLOWS: AtomicU32 = AtomicU32::new(0); #[interrupt] fn RTC0() { OVERFLOWS.fetch_add(1, Ordering::Release); - let rtc = hal::pac::RTC0; - // clear the EVENT register - rtc.events_ovrflw().write_value(0); + // # Safety + // Concurrent access to this field within the RTC is acceptable. + unsafe { + let rtc = hal::pac::Peripherals::steal().RTC0; + // clear the EVENT register + rtc.events_ovrflw.reset(); + } } /// Exits the application successfully when the program is executed through the @@ -450,12 +480,12 @@ pub fn uptime_ticks() -> u64 { // # Safety // Concurrent access to this field within the RTC is acceptable. - let rtc_counter = hal::pac::RTC0.counter(); + let rtc_counter = unsafe { &hal::pac::Peripherals::steal().RTC0.counter }; loop { // NOTE volatile is used to order these load operations among themselves let hi1 = OVERFLOWS.load(Ordering::Acquire); - let low = rtc_counter.read().counter(); + let low = rtc_counter.read().counter().bits(); let hi2 = OVERFLOWS.load(Ordering::Relaxed); if hi1 == hi2 { @@ -507,10 +537,14 @@ pub fn uptime_us() -> u64 { /// Returns the least-significant bits of the device identifier pub fn deviceid0() -> u32 { - hal::pac::FICR.deviceid(0).read() + // NOTE(unsafe) read-only registers, and no other use of the block + let ficr = unsafe { &*hal::pac::FICR::ptr() }; + ficr.deviceid[0].read().deviceid().bits() } /// Returns the most-significant bits of the device identifier pub fn deviceid1() -> u32 { - hal::pac::FICR.deviceid(1).read() + // NOTE(unsafe) read-only registers, and no other use of the block + let ficr = unsafe { &*hal::pac::FICR::ptr() }; + ficr.deviceid[1].read().deviceid().bits() } diff --git a/nrf52-code/boards/dk/src/radio.rs b/nrf52-code/boards/dk/src/radio.rs deleted file mode 100644 index 377ae25a8..000000000 --- a/nrf52-code/boards/dk/src/radio.rs +++ /dev/null @@ -1,832 +0,0 @@ -//! # IEEE 802.15.4 radio driver -//! -//! This driver is a synchronous/blocking one written for a radio training. -//! A lot of its implementation is based on the -//! [nrf52840 HAL](https://github.com/nrf-rs/nrf-hal) -//! -//! [MIT license from the project](https://github.com/nrf-rs/nrf-hal/blob/master/LICENSE-MIT): -//! -//! Copyright (c) 2018 Anthony James Munns -//! -//! Permission is hereby granted, free of charge, to any -//! person obtaining a copy of this software and associated -//! documentation files (the "Software"), to deal in the -//! Software without restriction, including without -//! limitation the rights to use, copy, modify, merge, -//! publish, distribute, sublicense, and/or sell copies of -//! the Software, and to permit persons to whom the Software -//! is furnished to do so, subject to the following -//! conditions: -//! -//! THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF -//! ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED -//! TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A -//! PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT -//! SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY -//! CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -//! OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR -//! IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER -//! DEALINGS IN THE SOFTWARE. - -use core::sync::atomic::{compiler_fence, Ordering}; - -use crate::Peri; -use hal::pac::radio::regs::Shorts; -use hal::pac::radio::vals::{self, Crcstatus, State as RadioState}; -pub use hal::radio::TxPower; - -/// Default (IEEE compliant) Start of Frame Delimiter -pub const DEFAULT_SFD: u8 = 0xA7; - -/// Error -#[derive(Copy, Clone, Debug, PartialEq, defmt::Format)] -pub enum Error { - /// Incorrect CRC - Crc(u16), - /// Timeout - Timeout, -} - -/// IEEE 802.15.4 channels -/// -/// NOTE these are NOT the same as WiFi 2.4 GHz channels -#[derive(Debug, Copy, Clone, PartialEq, Eq, defmt::Format)] -pub enum Channel { - /// 2_405 MHz - _11 = 11, - /// 2_410 MHz - _12 = 12, - /// 2_415 MHz - _13 = 13, - /// 2_420 MHz - _14 = 14, - /// 2_425 MHz - _15 = 15, - /// 2_430 MHz - _16 = 16, - /// 2_435 MHz - _17 = 17, - /// 2_440 MHz - _18 = 18, - /// 2_445 MHz - _19 = 19, - /// 2_450 MHz - _20 = 20, - /// 2_455 MHz - _21 = 21, - /// 2_460 MHz - _22 = 22, - /// 2_465 MHz - _23 = 23, - /// 2_470 MHz - _24 = 24, - /// 2_475 MHz - _25 = 25, - /// 2_480 MHz - _26 = 26, -} - -impl Channel { - /// Frequency offset for the given channel. - pub const fn frequency_offset(&self) -> u32 { - (*self as u32 - 10) * 5 - } -} - -/// Driver state -/// -/// After, or at the start of, any method call the RADIO will be in one of these states -// This is a subset of the STATE_A enum -#[derive(Copy, Clone, PartialEq, Eq, defmt::Format)] -enum State { - Disabled, - RxIdle, - TxIdle, -} - -#[derive(Debug, defmt::Format)] -enum Event { - PhyEnd, -} - -/// Non-blocking receive -pub struct Recv<'a, 'c> { - radio: &'a mut Radio<'c>, -} - -impl<'a, 'c> Recv<'a, 'c> { - fn new(radio: &'a mut Radio<'c>) -> Self { - Self { radio } - } - - /// Check if receive is done - /// - /// This methods returns the `Ok` variant if the CRC included the - /// packet was successfully validated by the hardware. It returns - /// `Err(nb::Error::WouldBlock)` if a packet hasn't been received - /// yet, and `Err(nb::Error::Other)` if the CRC check failed. - pub fn is_done(&self) -> nb::Result { - let regs = self.radio.regs(); - if regs.events_end().read() == 1 { - regs.events_end().write_value(0); - - dma_end_fence(); - - let crc = regs.rxcrc().read().rxcrc() as u16; - - if regs.crcstatus().read().crcstatus() == Crcstatus::CRCOK { - Ok(crc) - } else { - Err(nb::Error::Other(crc)) - } - } else { - Err(nb::Error::WouldBlock) - } - } -} - -impl<'a, 'c> Drop for Recv<'a, 'c> { - fn drop(&mut self) { - self.radio.cancel_recv(); - } -} - -// TODO expose the other variants in `pac::CCAMODE_A` -/// Clear Channel Assessment method -pub enum Cca { - /// Carrier sense - CarrierSense, - /// Energy Detection / Energy Above Threshold - EnergyDetection { - /// Energy measurements above this value mean that the channel is assumed to be busy. - /// Note the measurement range is 0..0xFF - where 0 means that the received power was - /// less than 10 dB above the selected receiver sensitivity. This value is not given in dBm, - /// but can be converted. See the nrf52840 Product Specification Section 6.20.12.4 - /// for details. - ed_threshold: u8, - }, -} - -/// IEEE 802.15.4 radio driver. -pub struct Radio<'d> { - _p: Peri<'d, hal::peripherals::RADIO>, - needs_enable: bool, -} - -impl<'d> Radio<'d> { - /// Create a new IEEE 802.15.4 radio driver. - pub fn new(radio: Peri<'d, hal::peripherals::RADIO>) -> Self { - let r = hal::pac::RADIO; - - // Disable and enable to reset peripheral - r.power().write(|w| w.set_power(false)); - r.power().write(|w| w.set_power(true)); - - // Enable 802.15.4 mode - r.mode() - .write(|w| w.set_mode(vals::Mode::IEEE802154_250KBIT)); - // Configure CRC skip address - r.crccnf().write(|w| { - w.set_len(vals::Len::TWO); - w.set_skipaddr(vals::Skipaddr::IEEE802154); - }); - // Configure CRC polynomial and init - r.crcpoly().write(|w| w.set_crcpoly(0x0001_1021)); - r.crcinit().write(|w| w.set_crcinit(0)); - r.pcnf0().write(|w| { - // 8-bit on air length - w.set_lflen(8); - // Zero bytes S0 field length - w.set_s0len(false); - // Zero bytes S1 field length - w.set_s1len(0); - // Do not include S1 field in RAM if S1 length > 0 - w.set_s1incl(vals::S1incl::AUTOMATIC); - // Zero code Indicator length - w.set_cilen(0); - // 32-bit zero preamble - w.set_plen(vals::Plen::_32BIT_ZERO); - // Include CRC in length - w.set_crcinc(vals::Crcinc::INCLUDE); - }); - r.pcnf1().write(|w| { - // Maximum packet length - w.set_maxlen(Packet::MAX_PSDU_LEN); - // Zero static length - w.set_statlen(0); - // Zero base address length - w.set_balen(0); - // Little-endian - w.set_endian(vals::Endian::LITTLE); - // Disable packet whitening - w.set_whiteen(false); - }); - - // Enable NVIC interrupt - //T::Interrupt::unpend(); - //unsafe { T::Interrupt::enable() }; - - let mut radio = Self { - _p: radio, - needs_enable: false, - }; - - radio.set_sfd(DEFAULT_SFD); - radio.set_transmission_power_raw(0); - radio.set_channel_raw(11); - radio.set_cca(Cca::CarrierSense); - - radio - } - - /// Raw register block access. - #[inline] - pub fn regs(&self) -> hal::pac::radio::Radio { - hal::pac::RADIO - } - - /// Set the channel. - pub fn set_channel(&mut self, channel: Channel) { - self.set_channel_raw(channel as u8); - } - - /// Changes the radio channel using a raw channel ID. - pub fn set_channel_raw(&mut self, channel: u8) { - let r = self.regs(); - if !(11..=26).contains(&channel) { - panic!("Bad 802.15.4 channel"); - } - let frequency_offset = (channel - 10) * 5; - self.needs_enable = true; - r.frequency().write(|w| { - w.set_frequency(frequency_offset); - w.set_map(vals::Map::DEFAULT); - }); - } - - /// Changes the Clear Channel Assessment method - pub fn set_cca(&mut self, cca: Cca) { - let r = self.regs(); - self.needs_enable = true; - match cca { - Cca::CarrierSense => r - .ccactrl() - .write(|w| w.set_ccamode(hal::pac::radio::vals::Ccamode::CARRIER_MODE)), - Cca::EnergyDetection { ed_threshold } => { - // "[ED] is enabled by first configuring the field CCAMODE=EdMode in CCACTRL - // and writing the CCAEDTHRES field to a chosen value." - r.ccactrl().write(|w| { - w.set_ccamode(hal::pac::radio::vals::Ccamode::ED_MODE); - w.set_ccaedthres(ed_threshold); - }); - } - } - } - - /// Changes the Start of Frame Delimiter (SFD) - pub fn set_sfd(&mut self, sfd: u8) { - let r = self.regs(); - r.sfd().write(|w| w.set_sfd(sfd)); - } - - /// Clear interrupts - pub fn clear_all_interrupts(&mut self) { - let r = self.regs(); - r.intenclr().write(|w| w.0 = 0xffff_ffff); - } - - /// Changes the radio transmission power - pub fn set_transmission_power_raw(&mut self, power: i8) { - self.needs_enable = true; - - let tx_power: TxPower = match power { - 8 => TxPower::POS8_DBM, - 7 => TxPower::POS7_DBM, - 6 => TxPower::POS6_DBM, - 5 => TxPower::POS5_DBM, - 4 => TxPower::POS4_DBM, - 3 => TxPower::POS3_DBM, - 2 => TxPower::POS2_DBM, - 0 => TxPower::_0_DBM, - -4 => TxPower::NEG4_DBM, - -8 => TxPower::NEG8_DBM, - -12 => TxPower::NEG12_DBM, - -16 => TxPower::NEG16_DBM, - -20 => TxPower::NEG20_DBM, - -30 => TxPower::NEG30_DBM, - -40 => TxPower::NEG40_DBM, - _ => panic!("Invalid transmission power value"), - }; - - self.set_transmission_power(tx_power); - } - - /// Changes the radio transmission power - pub fn set_transmission_power(&mut self, power: TxPower) { - let r = self.regs(); - self.needs_enable = true; - r.txpower().write(|w| w.set_txpower(power)); - } - - /// Waits until the radio state matches the given `state` - pub fn wait_for_radio_state(&self, state: RadioState) { - while self.regs().state().read().state() != state {} - } - - /// Get the current radio state - fn state(&self) -> State { - match self.regs().state().read().state() { - // final states - RadioState::DISABLED => State::Disabled, - RadioState::TX_IDLE => State::TxIdle, - RadioState::RX_IDLE => State::RxIdle, - - // transitory states - RadioState::TX_DISABLE => { - self.wait_for_state_a(RadioState::DISABLED); - State::Disabled - } - - _ => unreachable!(), - } - } - - fn set_buffer(&mut self, buffer: &[u8]) { - self.regs().packetptr().write_value(buffer.as_ptr() as u32); - } - - /// Sample the received signal power (i.e. the presence of possibly interfering signals) - /// within the bandwidth of the currently used channel for `sample_cycles` iterations. - /// Note that one iteration has a sample time of 128μs, and that each iteration produces the - /// average RSSI value measured during this sample time. - /// - /// Returns the *maximum* measurement recorded during sampling as reported by the hardware (not in dBm!). - /// The result can be used to find a suitable ED threshold for Energy Detection-based CCA mechanisms. - /// - /// For details, see Section 6.20.12.3 Energy detection (ED) of the PS. - /// RSSI samples are averaged over a measurement time of 8 symbol periods (128 μs). - pub fn energy_detection_scan(&mut self, sample_cycles: u32) -> u8 { - let regs = self.regs(); - // Increase the time spent listening - regs.edcnt().write(|w| w.set_edcnt(sample_cycles)); - - // ensure that the shortcut between READY event and START task is disabled before putting - // the radio into recv mode - regs.shorts() - .write_value(hal::pac::radio::regs::Shorts::default()); - self.put_in_rx_mode(); - - // clear related events - regs.events_edend().write_value(0); - - // start energy detection sampling - regs.tasks_edstart().write_value(1); - - loop { - if regs.events_edend().read() == 1 { - // sampling period is over; collect value - regs.events_edend().write_value(0); - - // note that since we have increased EDCNT, the EDSAMPLE register contains the - // maximum recorded value, not the average - let read_lvl = regs.edsample().read().edlvl(); - return read_lvl; - } - } - } - - /// Receives one radio packet and copies its contents into the given `packet` buffer - /// - /// This methods returns the `Ok` variant if the CRC included the packet was successfully - /// validated by the hardware; otherwise it returns the `Err` variant. In either case, `packet` - /// will be updated with the received packet's data - pub fn recv(&mut self, packet: &mut Packet) -> Result { - // Start non-blocking receive - self.recv_non_blocking(packet, |recv| { - // Block untill receive is done - nb::block!(recv.is_done()) - }) - } - - /// Receives one radio packet and copies its contents into the given `packet` buffer - /// - /// This method is non-blocking - pub fn recv_non_blocking<'a, R>( - &'a mut self, - packet: &'a mut Packet, - f: impl FnOnce(&Recv<'a, 'd>) -> R, - ) -> R { - // Start the read - // NOTE(unsafe) - // The packet must live until the transfer is done. Receive is handled inside - // a closure to ensure this - unsafe { - self.start_recv(packet); - } - - let recv = Recv::new(self); - f(&recv) - } - - /// Listens for a packet for no longer than the specified amount of microseconds - /// and copies its contents into the given `packet` buffer - /// - /// If no packet is received within the specified time then the `Timeout` error is returned - /// - /// If a packet is received within the time span then the packet CRC is checked. If the CRC is - /// incorrect then the `Crc` error is returned; otherwise the `Ok` variant is returned. - /// Note that `packet` will contain the packet in any case, even if the CRC check failed. - /// - /// Note that the time it takes to switch the radio to RX mode is included in the timeout count. - /// This transition may take up to a hundred of microseconds; see the section 6.20.15.8 in the - /// Product Specification for more details about timing - pub fn recv_timeout( - &mut self, - packet: &mut Packet, - timer: &mut super::Timer, - microseconds: u32, - ) -> Result { - // Start the timeout timer - timer.start(microseconds); - - // Start non-blocking receive - self.recv_non_blocking(packet, |recv| { - // Check if either receive is done or timeout occured - loop { - match recv.is_done() { - Ok(crc) => break Ok(crc), - Err(err) => match err { - nb::Error::Other(crc) => break Err(Error::Crc(crc)), - nb::Error::WouldBlock => (), - }, - } - - if timer.reset_if_finished() { - // Break loop in case of timeout. Receive is - // cancelled when `recv` is dropped. - break Err(Error::Timeout); - } - } - }) - } - - unsafe fn start_recv(&mut self, packet: &mut Packet) { - let regs = self.regs(); - // NOTE we do NOT check the address of `packet` because the mutable reference ensures it's - // allocated in RAM - - // clear related events - regs.events_phyend().write_value(0); - regs.events_end().write_value(0); - - self.put_in_rx_mode(); - - // NOTE(unsafe) DMA transfer has not yet started - // set up RX buffer - self.set_buffer(packet.buffer.as_mut()); - - // start transfer - dma_start_fence(); - regs.tasks_start().write_value(1); - } - - fn cancel_recv(&mut self) { - let regs = self.regs(); - regs.tasks_stop().write_value(1); - self.wait_for_state_a(RadioState::RX_IDLE); - // DMA transfer may have been in progress so synchronize with its memory operations - dma_end_fence(); - } - - /// Tries to send the given `packet` - /// - /// This method performs Clear Channel Assessment (CCA) first and sends the `packet` only if the - /// channel is observed to be *clear* (no transmission is currently ongoing), otherwise no - /// packet is transmitted and the `Err` variant is returned - /// - /// NOTE this method will *not* modify the `packet` argument. The mutable reference is used to - /// ensure the `packet` buffer is allocated in RAM, which is required by the RADIO peripheral - // NOTE we do NOT check the address of `packet` because the mutable reference ensures it's - // allocated in RAM - #[allow(clippy::result_unit_err)] - pub fn try_send(&mut self, packet: &mut Packet) -> Result<(), ()> { - let regs = self.regs(); - // enable radio to perform cca - self.put_in_rx_mode(); - - // clear related events - regs.events_phyend().write_value(0); - regs.events_end().write_value(0); - - // NOTE(unsafe) DMA transfer has not yet started - regs.packetptr().write_value(packet.buffer.as_ptr() as u32); - - // configure radio to immediately start transmission if the channel is idle - regs.shorts().modify(|w| { - w.set_ccaidle_txen(true); - w.set_end_disable(true); - }); - - // the DMA transfer will start at some point after the following write operation so - // we place the compiler fence here - dma_start_fence(); - // start CCA. In case the channel is clear, the data at packetptr will be sent automatically - regs.tasks_ccastart().write_value(1); - - loop { - if regs.events_phyend().read() == 1 { - // transmission completed - dma_end_fence(); - regs.events_phyend().write_value(0); - regs.shorts().write_value(Shorts::default()); - return Ok(()); - } - - if regs.events_ccabusy().read() == 1 { - // channel is busy - regs.events_ccabusy().write_value(0); - regs.shorts().write_value(Shorts::default()); - return Err(()); - } - } - } - - /// Sends the given `packet` - /// - /// This is utility method that *consecutively* calls the `try_send` method until it succeeds. - /// Note that this approach is *not* IEEE spec compliant -- there must be delay between failed - /// CCA attempts to be spec compliant - /// - /// NOTE this method will *not* modify the `packet` argument. The mutable reference is used to - /// ensure the `packet` buffer is allocated in RAM, which is required by the RADIO peripheral - // NOTE we do NOT check the address of `packet` because the mutable reference ensures it's - // allocated in RAM - pub fn send(&mut self, packet: &mut Packet) { - let regs = self.regs(); - - // enable radio to perform cca - self.put_in_rx_mode(); - - // clear related events - regs.events_phyend().write_value(0); - regs.events_end().write_value(0); - - // immediately start transmission if the channel is idle - regs.shorts().modify(|w| { - w.set_ccaidle_txen(true); - w.set_txready_start(true); - w.set_end_disable(true); - }); - - // the DMA transfer will start at some point after the following write operation so - // we place the compiler fence here - dma_start_fence(); - // NOTE(unsafe) DMA transfer has not yet started - regs.packetptr().write_value(packet.buffer.as_ptr() as u32); - - 'cca: loop { - // start CCA (+ sending if channel is clear) - regs.tasks_ccastart().write_value(1); - - loop { - if regs.events_phyend().read() == 1 { - dma_end_fence(); - // transmission is complete - regs.events_phyend().write_value(0); - break 'cca; - } - - if regs.events_ccabusy().read() == 1 { - // channel is busy; try another CCA - regs.events_ccabusy().write_value(0); - continue 'cca; - } - } - } - - regs.shorts().write_value(Shorts::default()); - } - - /// Sends the specified `packet` without first performing CCA - /// - /// Acknowledgment packets must be sent using this method - /// - /// NOTE this method will *not* modify the `packet` argument. The mutable reference is used to - /// ensure the `packet` buffer is allocated in RAM, which is required by the RADIO peripheral - // NOTE we do NOT check the address of `packet` because the mutable reference ensures it's - // allocated in RAM - pub fn send_no_cca(&mut self, packet: &mut Packet) { - let regs = self.regs(); - self.put_in_tx_mode(); - - // clear related events - regs.events_phyend().write_value(0); - regs.events_end().write_value(0); - - // NOTE(unsafe) DMA transfer has not yet started - regs.packetptr().write_value(packet.buffer.as_ptr() as u32); - - // configure radio to disable transmitter once packet is sent - regs.shorts().modify(|w| w.set_end_disable(true)); - - // start DMA transfer - dma_start_fence(); - regs.tasks_start().write_value(1); - - self.wait_for_event(Event::PhyEnd); - regs.shorts().write_value(Shorts::default()); - } - - /// Moves the radio from any state to the DISABLED state - pub fn disable(&mut self) { - let regs = self.regs(); - // See figure 110 in nRF52840-PS - loop { - match regs.state().read().state() { - RadioState::DISABLED => return, - RadioState::RX_RU - | RadioState::RX_IDLE - | RadioState::TX_RU - | RadioState::TX_IDLE => { - regs.tasks_disable().write_value(1); - - self.wait_for_state_a(RadioState::DISABLED); - return; - } - RadioState::RX_DISABLE | RadioState::TX_DISABLE => { - self.wait_for_state_a(RadioState::DISABLED); - return; - } - RadioState::RX => { - regs.tasks_ccastop().write_value(1); - regs.tasks_stop().write_value(1); - self.wait_for_state_a(RadioState::RX_IDLE); - } - RadioState::TX => { - regs.tasks_stop().write_value(1); - self.wait_for_state_a(RadioState::TX_IDLE); - } - _ => (), - } - } - } - - /// Moves the radio to the RXIDLE state - fn put_in_rx_mode(&mut self) { - let regs = self.regs(); - let state = self.state(); - - let (disable, enable) = match state { - State::Disabled => (false, true), - State::RxIdle => (false, self.needs_enable), - // NOTE to avoid errata 204 (see rev1 v1.4) we do TXIDLE -> DISABLED -> RXIDLE - State::TxIdle => (true, true), - }; - - if disable { - regs.tasks_disable().write_value(1); - self.wait_for_state_a(RadioState::DISABLED); - } - - if enable { - self.needs_enable = false; - regs.tasks_rxen().write_value(1); - self.wait_for_state_a(RadioState::RX_IDLE); - } - } - - /// Moves the radio to the TXIDLE state - fn put_in_tx_mode(&mut self) { - let state = self.state(); - - if state != State::TxIdle || self.needs_enable { - self.needs_enable = false; - self.regs().tasks_rxen().write_value(1); - self.wait_for_state_a(RadioState::TX_IDLE); - } - } - - fn wait_for_event(&self, event: Event) { - match event { - Event::PhyEnd => { - while self.regs().events_phyend().read() == 0 {} - self.regs().events_phyend().write_value(0); - } - } - } - - //use hal::pac::radio::vals::State - /// Waits until the radio state matches the given `state` - fn wait_for_state_a(&self, state: RadioState) { - while self.regs().state().read().state() != state {} - } -} - -/// An IEEE 802.15.4 packet -/// -/// This `Packet` is a PHY layer packet. It's made up of the physical header (PHR) and the PSDU -/// (PHY service data unit). The PSDU of this `Packet` will always include the MAC level CRC, AKA -/// the FCS (Frame Control Sequence) -- the CRC is fully computed in hardware and automatically -/// appended on transmission and verified on reception. -/// -/// The API lets users modify the usable part (not the CRC) of the PSDU via the `deref` and -/// `copy_from_slice` methods. These methods will automatically update the PHR. -/// -/// See figure 119 in the Product Specification of the nRF52840 for more details -pub struct Packet { - buffer: [u8; Self::SIZE], -} - -// See figure 124 in nRF52840-PS -impl Packet { - // for indexing purposes - const PHY_HDR: usize = 0; - const DATA: core::ops::RangeFrom = 1..; - - /// Maximum amount of usable payload (CRC excluded) a single packet can contain, in bytes - pub const CAPACITY: u8 = 125; - const CRC: u8 = 2; // size of the CRC, which is *never* copied to / from RAM - const MAX_PSDU_LEN: u8 = Self::CAPACITY + Self::CRC; - const SIZE: usize = 1 /* PHR */ + Self::MAX_PSDU_LEN as usize; - - /// Returns an empty packet (length = 0) - pub fn new() -> Self { - let mut packet = Self { - buffer: [0; Self::SIZE], - }; - packet.set_len(0); - packet - } - - /// Fills the packet payload with given `src` data - /// - /// # Panics - /// - /// This function panics if `src` is larger than `Self::CAPACITY` - pub fn copy_from_slice(&mut self, src: &[u8]) { - assert!(src.len() <= Self::CAPACITY as usize); - let len = src.len() as u8; - self.buffer[Self::DATA][..len as usize].copy_from_slice(&src[..len.into()]); - self.set_len(len); - } - - /// Returns the size of this packet's payload - #[allow(clippy::len_without_is_empty)] - pub fn len(&self) -> u8 { - self.buffer[Self::PHY_HDR] - Self::CRC - } - - /// Changes the size of the packet's payload - /// - /// # Panics - /// - /// This function panics if `len` is larger than `Self::CAPACITY` - pub fn set_len(&mut self, len: u8) { - assert!(len <= Self::CAPACITY); - self.buffer[Self::PHY_HDR] = len + Self::CRC; - } - - /// Returns the LQI (Link Quality Indicator) of the received packet - /// - /// Note that the LQI is stored in the `Packet`'s internal buffer by the hardware so the value - /// returned by this method is only valid after a `Radio.recv` operation. Operations that - /// modify the `Packet`, like `copy_from_slice` or `set_len`+`deref_mut`, will overwrite the - /// stored LQI value. - /// - /// Also note that the hardware will *not* compute a LQI for packets smaller than 3 bytes so - /// this method will return an invalid value for those packets. - pub fn lqi(&self) -> u8 { - self.buffer[1 /* PHY_HDR */ + self.len() as usize /* data */] - } -} - -impl Default for Packet { - fn default() -> Self { - Self::new() - } -} - -impl core::ops::Deref for Packet { - type Target = [u8]; - - fn deref(&self) -> &[u8] { - &self.buffer[Self::DATA][..self.len() as usize] - } -} - -impl core::ops::DerefMut for Packet { - fn deref_mut(&mut self) -> &mut [u8] { - let len = self.len(); - &mut self.buffer[Self::DATA][..len as usize] - } -} - -/// NOTE must be followed by a volatile write operation -fn dma_start_fence() { - compiler_fence(Ordering::Release); -} - -/// NOTE must be preceded by a volatile read operation -fn dma_end_fence() { - compiler_fence(Ordering::Acquire); -} diff --git a/nrf52-code/boards/dk/src/usbd.rs b/nrf52-code/boards/dk/src/usbd.rs index 0e86e40cd..bb3ccbd99 100644 --- a/nrf52-code/boards/dk/src/usbd.rs +++ b/nrf52-code/boards/dk/src/usbd.rs @@ -3,9 +3,11 @@ use core::sync::atomic::{self, Ordering}; use grounded::uninit::GroundedArrayCell; -use hal::pac::{power::Power, usbd::Usbd}; -use crate::errata; +use crate::{ + errata, + peripheral::{POWER, USBD}, +}; /// Endpoint IN 0 pub struct Ep0In { @@ -29,7 +31,7 @@ impl Ep0In { /// /// - This function panics if the last transfer was not finished by calling the `end` function /// - This function panics if `bytes` is larger than the maximum packet size (64 bytes) - pub fn start(&mut self, bytes: &[u8], usbd: &Usbd) { + pub fn start(&mut self, bytes: &[u8], usbd: &USBD) { let (buffer_ptr, buffer_len) = self.buffer.get_ptr_len(); assert!(!self.busy, "EP0IN: last transfer has not completed"); assert!( @@ -43,9 +45,14 @@ impl Ep0In { } // use a "shortcut" to issue a status stage after the data transfer is complete - usbd.shorts().modify(|w| w.set_ep0datadone_ep0status(true)); - usbd.epin(0).maxcnt().write(|w| w.set_maxcnt(n as u8)); - usbd.epin(0).ptr().write(|w| *w = buffer_ptr as u32); + usbd.shorts + .modify(|_, w| w.ep0datadone_ep0status().set_bit()); + usbd.epin0 + .maxcnt + .write(|w| unsafe { w.maxcnt().bits(n as u8) }); + usbd.epin0 + .ptr + .write(|w| unsafe { w.ptr().bits(buffer_ptr as u32) }); self.busy = true; @@ -53,7 +60,7 @@ impl Ep0In { // start DMA transfer dma_start(); - usbd.tasks_startepin(0).write(|w| *w = 1); + usbd.tasks_startepin[0].write(|w| w.tasks_startepin().set_bit()); } /// Completes a data transfer @@ -64,13 +71,13 @@ impl Ep0In { /// /// This function panics if called before `start` or before the EP0DATADONE event is raised by /// the hardware - pub fn end(&mut self, usbd: &Usbd) { - if usbd.events_ep0datadone().read() == 0 { + pub fn end(&mut self, usbd: &USBD) { + if usbd.events_ep0datadone.read().bits() == 0 { panic!("Ep0In::end called before the EP0DATADONE event was raised"); } else { // DMA transfer complete dma_end(); - usbd.events_ep0datadone().write(|w| *w = 0); + usbd.events_ep0datadone.reset(); self.busy = false; defmt::info!("EP0IN: transfer done"); @@ -102,11 +109,11 @@ fn dma_end() { // NOTE will be called from user code; at that point the high frequency clock source has already // been configured to use to the external crystal // Reference: section 6.35.4 of the nRF52840 Product Specification -pub fn init(power: Power, usbd: &Usbd) { +pub fn init(power: POWER, usbd: &USBD) { let mut once = true; // wait until the USB cable has been connected - while power.events_usbdetected().read() == 0 { + while power.events_usbdetected.read().bits() == 0 { if once { defmt::info!("waiting for USB connection on port J3"); once = false; @@ -114,48 +121,48 @@ pub fn init(power: Power, usbd: &Usbd) { continue; } - power.events_usbdetected().write_value(0); + power.events_usbdetected.reset(); // workaround silicon bug unsafe { errata::e187a() } // enable the USB peripheral - usbd.enable().write(|w| w.set_enable(true)); + usbd.enable.write(|w| w.enable().set_bit()); // wait for the peripheral to signal it has reached the READY state - while !usbd.eventcause().read().ready() { + while usbd.eventcause.read().ready().bit_is_clear() { continue; } - // setting the bit clears the flag - usbd.eventcause().write(|w| w.set_ready(true)); + // write 1 to clear the flag + usbd.eventcause.write(|w| w.ready().clear_bit_by_one()); // if EVENTCAUSE is all zeroes then also clear the USBEVENT register - if usbd.eventcause().read().0 == 0 { - usbd.events_usbevent().write_value(0); + if usbd.eventcause.read().bits() == 0 { + usbd.events_usbevent.reset(); } // complete the silicon bug workaround unsafe { errata::e187b() } // also need to wait for the USB power supply regulator to stabilize - while power.events_usbpwrrdy().read() == 0 { + while power.events_usbpwrrdy.read().bits() == 0 { continue; } - power.events_usbpwrrdy().write_value(0); + power.events_usbpwrrdy.reset(); // before returning unmask the relevant interrupts - usbd.intenset().write(|w| { - w.set_ep0datadone(true); - w.set_ep0setup(true); - w.set_usbreset(true); + usbd.intenset.write(|w| { + w.ep0datadone().set_bit(); + w.ep0setup().set_bit(); + w.usbreset().set_bit() }); // enable the D+ line pull-up - usbd.usbpullup().write(|w| w.set_connect(true)); + usbd.usbpullup.write(|w| w.connect().set_bit()); } /// Stalls endpoint 0 -pub fn ep0stall(usbd: &Usbd) { - usbd.tasks_ep0stall().write_value(1); +pub fn ep0stall(usbd: &USBD) { + usbd.tasks_ep0stall.write(|w| w.tasks_ep0stall().set_bit()); } /// USBD.EVENTS registers mapped to an enum @@ -175,22 +182,22 @@ pub enum Event { /// /// NOTE this function will clear the corresponding the EVENT register (*) so the caller should /// handle the returned event properly. Expect for USBEVENT and EP0DATADONE -pub fn next_event(usbd: &Usbd) -> Option { - if usbd.events_usbreset().read() != 0 { - usbd.events_usbreset().write_value(0); +pub fn next_event(usbd: &USBD) -> Option { + if usbd.events_usbreset.read().bits() != 0 { + usbd.events_usbreset.reset(); return Some(Event::UsbReset); } - if usbd.events_ep0datadone().read() != 0 { + if usbd.events_ep0datadone.read().bits() != 0 { // this will be cleared by the `Ep0In::end` method // usbd.events_ep0datadone.reset(); return Some(Event::UsbEp0DataDone); } - if usbd.events_ep0setup().read() != 0 { - usbd.events_ep0setup().write_value(0); + if usbd.events_ep0setup.read().bits() != 0 { + usbd.events_ep0setup.reset(); return Some(Event::UsbEp0Setup); } @@ -199,28 +206,31 @@ pub fn next_event(usbd: &Usbd) -> Option { } /// Reads the BMREQUESTTYPE register and returns the 8-bit BMREQUESTTYPE component of a setup packet -pub fn bmrequesttype(usbd: &Usbd) -> u8 { +pub fn bmrequesttype(usbd: &USBD) -> u8 { // read the 32-bit register and extract the least significant byte // (the alternative is to read the 3 bitfields of the register and merge them into one byte) - usbd.bmrequesttype().read().0 as u8 + usbd.bmrequesttype.read().bits() as u8 } /// Reads the BREQUEST register and returns the 8-bit BREQUEST component of a setup packet -pub fn brequest(usbd: &Usbd) -> u8 { - usbd.brequest().read().brequest() as u8 +pub fn brequest(usbd: &USBD) -> u8 { + usbd.brequest.read().brequest().bits() } /// Reads the WLENGTHL and WLENGTHH registers and returns the 16-bit WLENGTH component of a setup packet -pub fn wlength(usbd: &Usbd) -> u16 { - u16::from(usbd.wlengthl().read().wlengthl()) | u16::from(usbd.wlengthh().read().wlengthh()) << 8 +pub fn wlength(usbd: &USBD) -> u16 { + u16::from(usbd.wlengthl.read().wlengthl().bits()) + | u16::from(usbd.wlengthh.read().wlengthh().bits()) << 8 } /// Reads the WINDEXL and WINDEXH registers and returns the 16-bit WINDEX component of a setup packet -pub fn windex(usbd: &Usbd) -> u16 { - u16::from(usbd.windexl().read().windexl()) | u16::from(usbd.windexh().read().windexh()) << 8 +pub fn windex(usbd: &USBD) -> u16 { + u16::from(usbd.windexl.read().windexl().bits()) + | u16::from(usbd.windexh.read().windexh().bits()) << 8 } /// Reads the WVALUEL and WVALUEH registers and returns the 16-bit WVALUE component of a setup packet -pub fn wvalue(usbd: &Usbd) -> u16 { - u16::from(usbd.wvaluel().read().wvaluel()) | u16::from(usbd.wvalueh().read().wvalueh()) << 8 +pub fn wvalue(usbd: &USBD) -> u16 { + u16::from(usbd.wvaluel.read().wvaluel().bits()) + | u16::from(usbd.wvalueh.read().wvalueh().bits()) << 8 } diff --git a/nrf52-code/hal-app/Cargo.lock b/nrf52-code/hal-app/Cargo.lock index e529008f4..8452c67f8 100644 --- a/nrf52-code/hal-app/Cargo.lock +++ b/nrf52-code/hal-app/Cargo.lock @@ -2,12 +2,6 @@ # It is not intended for manual editing. version = 4 -[[package]] -name = "autocfg" -version = "1.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c08606f8c3cbf4ce6ec8e28fb0014a2c086708fe954eaa885384a6165172e7e8" - [[package]] name = "az" version = "1.2.1" @@ -35,12 +29,6 @@ version = "1.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" -[[package]] -name = "bitflags" -version = "2.9.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2261d10cca569e4643e526d8dc2e62e433cc8aba21ab764233731f8d369bf394" - [[package]] name = "bytemuck" version = "1.22.0" @@ -53,6 +41,12 @@ 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" @@ -119,7 +113,7 @@ version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "548d977b6da32fa1d1fda2876453da1e7df63ad0304c8b3dae4dbe7b96f39b78" dependencies = [ - "bitflags 1.3.2", + "bitflags", "defmt-macros", ] @@ -164,131 +158,18 @@ dependencies = [ "cortex-m-semihosting", "defmt", "defmt-rtt", - "embassy-nrf", - "embassy-time", "embedded-hal 1.0.0", "grounded", - "nb 1.1.0", -] - -[[package]] -name = "document-features" -version = "0.2.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "95249b50c6c185bee49034bcb378a49dc2b5dff0be90ff6616d31d64febab05d" -dependencies = [ - "litrs", -] - -[[package]] -name = "embassy-embedded-hal" -version = "0.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "554e3e840696f54b4c9afcf28a0f24da431c927f4151040020416e7393d6d0d8" -dependencies = [ - "embassy-futures", - "embassy-hal-internal", - "embassy-sync", - "embedded-hal 0.2.7", - "embedded-hal 1.0.0", - "embedded-hal-async", - "embedded-storage", - "embedded-storage-async", - "nb 1.1.0", -] - -[[package]] -name = "embassy-futures" -version = "0.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dc2d050bdc5c21e0862a89256ed8029ae6c290a93aecefc73084b3002cdebb01" - -[[package]] -name = "embassy-hal-internal" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "95285007a91b619dc9f26ea8f55452aa6c60f7115a4edc05085cd2bd3127cd7a" -dependencies = [ - "cortex-m", - "critical-section", - "num-traits", -] - -[[package]] -name = "embassy-nrf" -version = "0.8.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a8d63429d74ab5786cde7c9dc9a0338ea162a4da95e204ac5345c5ae36831fdb" -dependencies = [ - "bitflags 2.9.4", - "cfg-if", - "cortex-m", - "cortex-m-rt", - "critical-section", - "document-features", - "embassy-embedded-hal", - "embassy-hal-internal", - "embassy-sync", - "embassy-usb-driver", - "embedded-hal 0.2.7", - "embedded-hal 1.0.0", - "embedded-hal-async", - "embedded-io", - "embedded-io-async", - "embedded-storage", - "embedded-storage-async", - "fixed", - "nrf-pac", - "rand_core 0.6.4", - "rand_core 0.9.3", -] - -[[package]] -name = "embassy-sync" -version = "0.7.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "73974a3edbd0bd286759b3d483540f0ebef705919a5f56f4fc7709066f71689b" -dependencies = [ - "cfg-if", - "critical-section", - "embedded-io-async", - "futures-core", - "futures-sink", - "heapless 0.8.0", -] - -[[package]] -name = "embassy-time" -version = "0.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f4fa65b9284d974dad7a23bb72835c4ec85c0b540d86af7fc4098c88cff51d65" -dependencies = [ - "cfg-if", - "critical-section", - "document-features", - "embassy-time-driver", - "embedded-hal 0.2.7", - "embedded-hal 1.0.0", - "embedded-hal-async", - "futures-core", + "nrf52840-hal", ] [[package]] -name = "embassy-time-driver" -version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a0a244c7dc22c8d0289379c8d8830cae06bb93d8f990194d0de5efb3b5ae7ba6" -dependencies = [ - "document-features", -] - -[[package]] -name = "embassy-usb-driver" +name = "embedded-dma" version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "17119855ccc2d1f7470a39756b12068454ae27a3eabb037d940b5c03d9c77b7a" +checksum = "994f7e5b5cb23521c22304927195f236813053eb9c065dd2226a32ba64695446" dependencies = [ - "embedded-io-async", + "stable_deref_trait", ] [[package]] @@ -307,45 +188,18 @@ 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-io-async" -version = "0.6.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3ff09972d4073aa8c299395be75161d582e7629cd663171d62af73c8d50dba3f" -dependencies = [ - "embedded-io", -] - [[package]] name = "embedded-storage" version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a21dea9854beb860f3062d10228ce9b976da520a73474aed3171ec276bc0c032" -[[package]] -name = "embedded-storage-async" -version = "0.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1763775e2323b7d5f0aa6090657f5e21cfa02ede71f5dc40eead06d64dcd15cc" -dependencies = [ - "embedded-storage", -] - [[package]] name = "fixed" version = "1.29.0" @@ -358,18 +212,6 @@ dependencies = [ "typenum", ] -[[package]] -name = "futures-core" -version = "0.3.31" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "05f29059c0c2090612e8d742178b0580d2dc940c837851ad723096f87af6663e" - -[[package]] -name = "futures-sink" -version = "0.3.31" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e575fab7d1e0dcb8d0c7bcf9a63ee213816ab51902e6d244a95819acacf1d4f7" - [[package]] name = "grounded" version = "0.2.0" @@ -388,7 +230,7 @@ dependencies = [ "defmt", "defmt-rtt", "dk", - "heapless 0.9.1", + "heapless 0.9.2", ] [[package]] @@ -422,20 +264,14 @@ dependencies = [ [[package]] name = "heapless" -version = "0.9.1" +version = "0.9.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b1edcd5a338e64688fbdcb7531a846cfd3476a54784dcb918a0844682bc7ada5" +checksum = "2af2455f757db2b292a9b1768c4b70186d443bcb3b316252d6b540aec1cd89ed" dependencies = [ "hash32", "stable_deref_trait", ] -[[package]] -name = "litrs" -version = "0.4.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f5e54036fe321fd421e10d732f155734c4e4afd610dd556d9a82833ab3ee0bed" - [[package]] name = "nb" version = "0.1.3" @@ -452,22 +288,58 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8d5439c4ad607c3c23abf66de8c8bf57ba8adcd1f129e699851a6e43935d339d" [[package]] -name = "nrf-pac" -version = "0.1.0" +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 = "d334027d6703534f2a80de0794ae435c0e029358d28278533d3935e69b221b01" +checksum = "aedf862f941154442271ae9914777bd1c93f6d2e0dc9db4cafa160e55ffb9085" dependencies = [ "cortex-m", - "cortex-m-rt", + "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 = "num-traits" -version = "0.2.19" +name = "nrf52840-pac" +version = "0.12.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841" +checksum = "30713f36f1be02e5bc9abefa30eae4a1f943d810f199d4923d3ad062d1be1b3d" dependencies = [ - "autocfg", + "cortex-m", + "cortex-m-rt", + "vcell", ] [[package]] @@ -522,12 +394,6 @@ version = "0.6.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" -[[package]] -name = "rand_core" -version = "0.9.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "99d9a13982dcf210057a8a78572b2217b667c3beacbf3a0d8b454f6f82837d38" - [[package]] name = "rustc_version" version = "0.2.3" @@ -601,6 +467,16 @@ version = "1.0.18" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5a5f39404a5da50712a4c1eecf25e90dd62b613502b7e925fd4e4d19b5c96512" +[[package]] +name = "usb-device" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "98816b1accafbb09085168b90f27e93d790b4bfa19d883466b5e53315b5f06a6" +dependencies = [ + "heapless 0.8.0", + "portable-atomic", +] + [[package]] name = "vcell" version = "0.1.3" diff --git a/nrf52-code/hal-app/Cargo.toml b/nrf52-code/hal-app/Cargo.toml index bbaedcd23..7191743ba 100644 --- a/nrf52-code/hal-app/Cargo.toml +++ b/nrf52-code/hal-app/Cargo.toml @@ -9,7 +9,7 @@ description = "Solutions for the nRF52 HAL exercises" [dependencies] cortex-m = {version = "0.7.7", features = ["critical-section-single-core"]} cortex-m-rt = "0.7.5" -dk = { path = "../boards/dk-solution", features = ["radio"] } +dk = { path = "../boards/dk", features = ["radio"] } heapless = "0.9" defmt = "1" defmt-rtt = "1.1" diff --git a/nrf52-code/radio-app/Cargo.lock b/nrf52-code/radio-app/Cargo.lock index f8e9aac44..cf7b433e4 100644 --- a/nrf52-code/radio-app/Cargo.lock +++ b/nrf52-code/radio-app/Cargo.lock @@ -2,12 +2,6 @@ # It is not intended for manual editing. version = 4 -[[package]] -name = "autocfg" -version = "1.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c08606f8c3cbf4ce6ec8e28fb0014a2c086708fe954eaa885384a6165172e7e8" - [[package]] name = "az" version = "1.2.1" @@ -35,12 +29,6 @@ version = "1.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" -[[package]] -name = "bitflags" -version = "2.9.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2261d10cca569e4643e526d8dc2e62e433cc8aba21ab764233731f8d369bf394" - [[package]] name = "bytemuck" version = "1.23.2" @@ -53,6 +41,12 @@ 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.3" @@ -119,7 +113,7 @@ version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "548d977b6da32fa1d1fda2876453da1e7df63ad0304c8b3dae4dbe7b96f39b78" dependencies = [ - "bitflags 1.3.2", + "bitflags", "defmt-macros", ] @@ -164,131 +158,18 @@ dependencies = [ "cortex-m-semihosting", "defmt", "defmt-rtt", - "embassy-nrf", - "embassy-time", "embedded-hal 1.0.0", "grounded", - "nb 1.1.0", -] - -[[package]] -name = "document-features" -version = "0.2.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "95249b50c6c185bee49034bcb378a49dc2b5dff0be90ff6616d31d64febab05d" -dependencies = [ - "litrs", -] - -[[package]] -name = "embassy-embedded-hal" -version = "0.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "554e3e840696f54b4c9afcf28a0f24da431c927f4151040020416e7393d6d0d8" -dependencies = [ - "embassy-futures", - "embassy-hal-internal", - "embassy-sync", - "embedded-hal 0.2.7", - "embedded-hal 1.0.0", - "embedded-hal-async", - "embedded-storage", - "embedded-storage-async", - "nb 1.1.0", -] - -[[package]] -name = "embassy-futures" -version = "0.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dc2d050bdc5c21e0862a89256ed8029ae6c290a93aecefc73084b3002cdebb01" - -[[package]] -name = "embassy-hal-internal" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "95285007a91b619dc9f26ea8f55452aa6c60f7115a4edc05085cd2bd3127cd7a" -dependencies = [ - "cortex-m", - "critical-section", - "num-traits", -] - -[[package]] -name = "embassy-nrf" -version = "0.8.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a8d63429d74ab5786cde7c9dc9a0338ea162a4da95e204ac5345c5ae36831fdb" -dependencies = [ - "bitflags 2.9.4", - "cfg-if", - "cortex-m", - "cortex-m-rt", - "critical-section", - "document-features", - "embassy-embedded-hal", - "embassy-hal-internal", - "embassy-sync", - "embassy-usb-driver", - "embedded-hal 0.2.7", - "embedded-hal 1.0.0", - "embedded-hal-async", - "embedded-io", - "embedded-io-async", - "embedded-storage", - "embedded-storage-async", - "fixed", - "nrf-pac", - "rand_core 0.6.4", - "rand_core 0.9.3", -] - -[[package]] -name = "embassy-sync" -version = "0.7.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "73974a3edbd0bd286759b3d483540f0ebef705919a5f56f4fc7709066f71689b" -dependencies = [ - "cfg-if", - "critical-section", - "embedded-io-async", - "futures-core", - "futures-sink", - "heapless 0.8.0", -] - -[[package]] -name = "embassy-time" -version = "0.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f4fa65b9284d974dad7a23bb72835c4ec85c0b540d86af7fc4098c88cff51d65" -dependencies = [ - "cfg-if", - "critical-section", - "document-features", - "embassy-time-driver", - "embedded-hal 0.2.7", - "embedded-hal 1.0.0", - "embedded-hal-async", - "futures-core", + "nrf52840-hal", ] [[package]] -name = "embassy-time-driver" -version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a0a244c7dc22c8d0289379c8d8830cae06bb93d8f990194d0de5efb3b5ae7ba6" -dependencies = [ - "document-features", -] - -[[package]] -name = "embassy-usb-driver" +name = "embedded-dma" version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "17119855ccc2d1f7470a39756b12068454ae27a3eabb037d940b5c03d9c77b7a" +checksum = "994f7e5b5cb23521c22304927195f236813053eb9c065dd2226a32ba64695446" dependencies = [ - "embedded-io-async", + "stable_deref_trait", ] [[package]] @@ -307,45 +188,18 @@ 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-io-async" -version = "0.6.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3ff09972d4073aa8c299395be75161d582e7629cd663171d62af73c8d50dba3f" -dependencies = [ - "embedded-io", -] - [[package]] name = "embedded-storage" version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a21dea9854beb860f3062d10228ce9b976da520a73474aed3171ec276bc0c032" -[[package]] -name = "embedded-storage-async" -version = "0.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1763775e2323b7d5f0aa6090657f5e21cfa02ede71f5dc40eead06d64dcd15cc" -dependencies = [ - "embedded-storage", -] - [[package]] name = "fixed" version = "1.29.0" @@ -358,18 +212,6 @@ dependencies = [ "typenum", ] -[[package]] -name = "futures-core" -version = "0.3.31" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "05f29059c0c2090612e8d742178b0580d2dc940c837851ad723096f87af6663e" - -[[package]] -name = "futures-sink" -version = "0.3.31" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e575fab7d1e0dcb8d0c7bcf9a63ee213816ab51902e6d244a95819acacf1d4f7" - [[package]] name = "grounded" version = "0.2.0" @@ -418,12 +260,6 @@ dependencies = [ "stable_deref_trait", ] -[[package]] -name = "litrs" -version = "0.4.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f5e54036fe321fd421e10d732f155734c4e4afd610dd556d9a82833ab3ee0bed" - [[package]] name = "nb" version = "0.1.3" @@ -440,22 +276,58 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8d5439c4ad607c3c23abf66de8c8bf57ba8adcd1f129e699851a6e43935d339d" [[package]] -name = "nrf-pac" -version = "0.1.0" +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 = "d334027d6703534f2a80de0794ae435c0e029358d28278533d3935e69b221b01" +checksum = "aedf862f941154442271ae9914777bd1c93f6d2e0dc9db4cafa160e55ffb9085" dependencies = [ "cortex-m", - "cortex-m-rt", + "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 = "num-traits" -version = "0.2.19" +name = "nrf52840-pac" +version = "0.12.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841" +checksum = "30713f36f1be02e5bc9abefa30eae4a1f943d810f199d4923d3ad062d1be1b3d" dependencies = [ - "autocfg", + "cortex-m", + "cortex-m-rt", + "vcell", ] [[package]] @@ -522,12 +394,6 @@ version = "0.6.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" -[[package]] -name = "rand_core" -version = "0.9.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "99d9a13982dcf210057a8a78572b2217b667c3beacbf3a0d8b454f6f82837d38" - [[package]] name = "rustc_version" version = "0.2.3" @@ -597,9 +463,19 @@ checksum = "1dccffe3ce07af9386bfd29e80c0ab1a8205a2fc34e4bcd40364df902cfa8f3f" [[package]] name = "unicode-ident" -version = "1.0.19" +version = "1.0.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5a5f39404a5da50712a4c1eecf25e90dd62b613502b7e925fd4e4d19b5c96512" + +[[package]] +name = "usb-device" +version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f63a545481291138910575129486daeaf8ac54aee4387fe7906919f7830c7d9d" +checksum = "98816b1accafbb09085168b90f27e93d790b4bfa19d883466b5e53315b5f06a6" +dependencies = [ + "heapless 0.8.0", + "portable-atomic", +] [[package]] name = "vcell" diff --git a/nrf52-code/radio-app/src/bin/radio-puzzle-1.rs b/nrf52-code/radio-app/src/bin/radio-puzzle-1.rs index 510492882..a64423bb1 100644 --- a/nrf52-code/radio-app/src/bin/radio-puzzle-1.rs +++ b/nrf52-code/radio-app/src/bin/radio-puzzle-1.rs @@ -3,7 +3,7 @@ #![no_std] use cortex_m_rt::entry; -use dk::radio::{Channel, Packet}; +use dk::ieee802154::{Channel, Packet}; // this imports `src/lib.rs`to retrieve our global logger + panicking-behavior use radio_app as _; diff --git a/nrf52-code/radio-app/src/bin/radio-puzzle-3.rs b/nrf52-code/radio-app/src/bin/radio-puzzle-3.rs index 8644dc649..6e805064b 100644 --- a/nrf52-code/radio-app/src/bin/radio-puzzle-3.rs +++ b/nrf52-code/radio-app/src/bin/radio-puzzle-3.rs @@ -3,7 +3,7 @@ #![no_std] use cortex_m_rt::entry; -use dk::radio::{Channel, Packet}; +use dk::ieee802154::{Channel, Packet}; use heapless::LinearMap; // this imports `src/lib.rs`to retrieve our global logger + panicking-behavior use radio_app as _; diff --git a/nrf52-code/radio-app/src/bin/radio-puzzle-5.rs b/nrf52-code/radio-app/src/bin/radio-puzzle-5.rs index 17d3c7fc3..3e8311657 100644 --- a/nrf52-code/radio-app/src/bin/radio-puzzle-5.rs +++ b/nrf52-code/radio-app/src/bin/radio-puzzle-5.rs @@ -5,7 +5,7 @@ use core::str; use cortex_m_rt::entry; -use dk::radio::{Channel, Packet}; +use dk::ieee802154::{Channel, Packet}; use heapless::Vec; // this imports `src/lib.rs`to retrieve our global logger + panicking-behavior use radio_app as _; diff --git a/nrf52-code/radio-app/src/bin/radio-puzzle-6.rs b/nrf52-code/radio-app/src/bin/radio-puzzle-6.rs index d694657ab..7ff85a554 100644 --- a/nrf52-code/radio-app/src/bin/radio-puzzle-6.rs +++ b/nrf52-code/radio-app/src/bin/radio-puzzle-6.rs @@ -5,7 +5,7 @@ use core::str; use cortex_m_rt::entry; -use dk::radio::{Channel, Packet}; +use dk::ieee802154::{Channel, Packet}; use heapless::{LinearMap, Vec}; // this imports `src/lib.rs`to retrieve our global logger + panicking-behavior use radio_app as _; diff --git a/nrf52-code/radio-app/src/bin/radio-puzzle-7.rs b/nrf52-code/radio-app/src/bin/radio-puzzle-7.rs index b88e0460c..965ea2a63 100644 --- a/nrf52-code/radio-app/src/bin/radio-puzzle-7.rs +++ b/nrf52-code/radio-app/src/bin/radio-puzzle-7.rs @@ -5,7 +5,7 @@ use core::str; use cortex_m_rt::entry; -use dk::radio::{Channel, Packet}; +use dk::ieee802154::{Channel, Packet}; use heapless::{LinearMap, Vec}; // this imports `src/lib.rs`to retrieve our global logger + panicking-behavior use radio_app as _; diff --git a/nrf52-code/radio-app/src/bin/radio-puzzle-solution.rs b/nrf52-code/radio-app/src/bin/radio-puzzle-solution.rs index 2e13c0da1..b0ba2d4ea 100644 --- a/nrf52-code/radio-app/src/bin/radio-puzzle-solution.rs +++ b/nrf52-code/radio-app/src/bin/radio-puzzle-solution.rs @@ -5,7 +5,7 @@ use core::str; use cortex_m_rt::entry; -use dk::radio::{Channel, Packet}; +use dk::ieee802154::{Channel, Packet}; use heapless::{LinearMap, Vec}; // this imports `src/lib.rs`to retrieve our global logger + panicking-behavior use radio_app as _; diff --git a/nrf52-code/radio-app/src/bin/radio-puzzle.rs b/nrf52-code/radio-app/src/bin/radio-puzzle.rs index 938088754..47dd5707b 100644 --- a/nrf52-code/radio-app/src/bin/radio-puzzle.rs +++ b/nrf52-code/radio-app/src/bin/radio-puzzle.rs @@ -5,7 +5,7 @@ use core::str; use cortex_m_rt::entry; -use dk::radio::{Channel, Packet}; +use dk::ieee802154::{Channel, Packet}; // this imports `src/lib.rs`to retrieve our global logger + panicking-behavior use radio_app as _; diff --git a/nrf52-code/radio-app/src/bin/radio-recv.rs b/nrf52-code/radio-app/src/bin/radio-recv.rs index d39cb6354..afa970fbc 100644 --- a/nrf52-code/radio-app/src/bin/radio-recv.rs +++ b/nrf52-code/radio-app/src/bin/radio-recv.rs @@ -5,7 +5,7 @@ use core::str; use cortex_m_rt::entry; -use dk::radio::{Channel, Error, Packet}; +use dk::ieee802154::{Channel, Error, Packet}; // this imports `src/lib.rs`to retrieve our global logger + panicking-behavior use radio_app as _; diff --git a/nrf52-code/radio-app/src/bin/radio-send.rs b/nrf52-code/radio-app/src/bin/radio-send.rs index a59f03572..c24f82126 100644 --- a/nrf52-code/radio-app/src/bin/radio-send.rs +++ b/nrf52-code/radio-app/src/bin/radio-send.rs @@ -5,7 +5,7 @@ use core::str; use cortex_m_rt::entry; -use dk::radio::{Channel, Packet, TxPower}; +use dk::ieee802154::{Channel, Packet, TxPower}; // this imports `src/lib.rs`to retrieve our global logger + panicking-behavior use radio_app as _; @@ -17,7 +17,7 @@ fn main() -> ! { // these are the default settings of the DK's radio // NOTE if you ran `change-channel` then you may need to update the channel here radio.set_channel(Channel::_20); // <- must match the Dongle's listening channel - radio.set_transmission_power(TxPower::POS8_DBM); + radio.set_txpower(TxPower::Pos8dBm); let mut packet = Packet::new(); diff --git a/nrf52-code/usb-app-solutions/Cargo.lock b/nrf52-code/usb-app-solutions/Cargo.lock index 2176f30c2..a5ed963f0 100644 --- a/nrf52-code/usb-app-solutions/Cargo.lock +++ b/nrf52-code/usb-app-solutions/Cargo.lock @@ -2,12 +2,6 @@ # It is not intended for manual editing. version = 4 -[[package]] -name = "autocfg" -version = "1.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c08606f8c3cbf4ce6ec8e28fb0014a2c086708fe954eaa885384a6165172e7e8" - [[package]] name = "az" version = "1.2.1" @@ -41,17 +35,11 @@ version = "1.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" -[[package]] -name = "bitflags" -version = "2.10.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "812e12b5285cc515a9c72a5c1d3b6d46a19dac5acfef5265968c166106e31dd3" - [[package]] name = "bytemuck" -version = "1.24.0" +version = "1.22.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1fbdf580320f38b612e485521afda1ee26d10cc9884efaaa750d383e13e3c5f4" +checksum = "b6b1fc10dbac614ebc03540c9dbd60e83887fda27794998c6528f1782047d540" [[package]] name = "byteorder" @@ -59,11 +47,17 @@ 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.4" +version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9330f8b2ff13f34540b44e946ef35111825727b38d33286ef986142615121801" +checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" [[package]] name = "consts" @@ -119,9 +113,9 @@ checksum = "790eea4361631c5e7d22598ecd5723ff611904e3344ce8720784c93e3d83d40b" [[package]] name = "crunchy" -version = "0.2.4" +version = "0.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "460fbee9c2c2f33933d720630a6a0bac33ba7053db5344fac858d4b8952d77d5" +checksum = "43da5946c66ffcc7745f48db692ffbb10a83bfe0afd96235c5c2a4fb23994929" [[package]] name = "defmt" @@ -129,7 +123,7 @@ version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "548d977b6da32fa1d1fda2876453da1e7df63ad0304c8b3dae4dbe7b96f39b78" dependencies = [ - "bitflags 1.3.2", + "bitflags", "defmt-macros", ] @@ -174,131 +168,18 @@ dependencies = [ "cortex-m-semihosting", "defmt", "defmt-rtt", - "embassy-nrf", - "embassy-time", "embedded-hal 1.0.0", "grounded", - "nb 1.1.0", -] - -[[package]] -name = "document-features" -version = "0.2.12" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d4b8a88685455ed29a21542a33abd9cb6510b6b129abadabdcef0f4c55bc8f61" -dependencies = [ - "litrs", -] - -[[package]] -name = "embassy-embedded-hal" -version = "0.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "554e3e840696f54b4c9afcf28a0f24da431c927f4151040020416e7393d6d0d8" -dependencies = [ - "embassy-futures", - "embassy-hal-internal", - "embassy-sync", - "embedded-hal 0.2.7", - "embedded-hal 1.0.0", - "embedded-hal-async", - "embedded-storage", - "embedded-storage-async", - "nb 1.1.0", -] - -[[package]] -name = "embassy-futures" -version = "0.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dc2d050bdc5c21e0862a89256ed8029ae6c290a93aecefc73084b3002cdebb01" - -[[package]] -name = "embassy-hal-internal" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "95285007a91b619dc9f26ea8f55452aa6c60f7115a4edc05085cd2bd3127cd7a" -dependencies = [ - "cortex-m", - "critical-section", - "num-traits", + "nrf52840-hal", ] [[package]] -name = "embassy-nrf" -version = "0.8.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a8d63429d74ab5786cde7c9dc9a0338ea162a4da95e204ac5345c5ae36831fdb" -dependencies = [ - "bitflags 2.10.0", - "cfg-if", - "cortex-m", - "cortex-m-rt", - "critical-section", - "document-features", - "embassy-embedded-hal", - "embassy-hal-internal", - "embassy-sync", - "embassy-usb-driver", - "embedded-hal 0.2.7", - "embedded-hal 1.0.0", - "embedded-hal-async", - "embedded-io", - "embedded-io-async", - "embedded-storage", - "embedded-storage-async", - "fixed", - "nrf-pac", - "rand_core 0.6.4", - "rand_core 0.9.3", -] - -[[package]] -name = "embassy-sync" -version = "0.7.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "73974a3edbd0bd286759b3d483540f0ebef705919a5f56f4fc7709066f71689b" -dependencies = [ - "cfg-if", - "critical-section", - "embedded-io-async", - "futures-core", - "futures-sink", - "heapless 0.8.0", -] - -[[package]] -name = "embassy-time" -version = "0.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f4fa65b9284d974dad7a23bb72835c4ec85c0b540d86af7fc4098c88cff51d65" -dependencies = [ - "cfg-if", - "critical-section", - "document-features", - "embassy-time-driver", - "embedded-hal 0.2.7", - "embedded-hal 1.0.0", - "embedded-hal-async", - "futures-core", -] - -[[package]] -name = "embassy-time-driver" -version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a0a244c7dc22c8d0289379c8d8830cae06bb93d8f990194d0de5efb3b5ae7ba6" -dependencies = [ - "document-features", -] - -[[package]] -name = "embassy-usb-driver" +name = "embedded-dma" version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "17119855ccc2d1f7470a39756b12068454ae27a3eabb037d940b5c03d9c77b7a" +checksum = "994f7e5b5cb23521c22304927195f236813053eb9c065dd2226a32ba64695446" dependencies = [ - "embedded-io-async", + "stable_deref_trait", ] [[package]] @@ -317,45 +198,18 @@ 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-io-async" -version = "0.6.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3ff09972d4073aa8c299395be75161d582e7629cd663171d62af73c8d50dba3f" -dependencies = [ - "embedded-io", -] - [[package]] name = "embedded-storage" version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a21dea9854beb860f3062d10228ce9b976da520a73474aed3171ec276bc0c032" -[[package]] -name = "embedded-storage-async" -version = "0.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1763775e2323b7d5f0aa6090657f5e21cfa02ede71f5dc40eead06d64dcd15cc" -dependencies = [ - "embedded-storage", -] - [[package]] name = "equivalent" version = "1.0.2" @@ -374,18 +228,6 @@ dependencies = [ "typenum", ] -[[package]] -name = "futures-core" -version = "0.3.31" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "05f29059c0c2090612e8d742178b0580d2dc940c837851ad723096f87af6663e" - -[[package]] -name = "futures-sink" -version = "0.3.31" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e575fab7d1e0dcb8d0c7bcf9a63ee213816ab51902e6d244a95819acacf1d4f7" - [[package]] name = "grounded" version = "0.2.0" @@ -397,13 +239,12 @@ dependencies = [ [[package]] name = "half" -version = "2.7.1" +version = "2.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6ea2d84b969582b4b1864a92dc5d27cd2b77b622a8d79306834f1be5ba20d84b" +checksum = "7db2ff139bba50379da6aa0766b52fdcb62cb5b263009b09ed58ba604e14bbd1" dependencies = [ "cfg-if", "crunchy", - "zerocopy", ] [[package]] @@ -417,9 +258,9 @@ dependencies = [ [[package]] name = "hashbrown" -version = "0.16.0" +version = "0.15.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5419bdc4f6a9207fbeba6d11b604d481addf78ecd10c11ad51e76c2f6482748d" +checksum = "bf151400ff0baff5465007dd2f3e717f3fe502074ca563069ce3a6629d07b289" [[package]] name = "heapless" @@ -444,20 +285,14 @@ dependencies = [ [[package]] name = "indexmap" -version = "2.12.0" +version = "2.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6717a8d2a5a929a1a2eb43a12812498ed141a0bcfb7e8f7844fbdbe4303bba9f" +checksum = "3954d50fe15b02142bf25d3b8bdadb634ec3948f103d04ffe3031bc8fe9d7058" dependencies = [ "equivalent", "hashbrown", ] -[[package]] -name = "litrs" -version = "1.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "11d3d7f243d5c5a8b9bb5d6dd2b1602c0cb0b9db1621bafc7ed66e35ff9fe092" - [[package]] name = "nb" version = "0.1.3" @@ -474,29 +309,65 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8d5439c4ad607c3c23abf66de8c8bf57ba8adcd1f129e699851a6e43935d339d" [[package]] -name = "nrf-pac" -version = "0.1.0" +name = "nrf-hal-common" +version = "0.18.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d334027d6703534f2a80de0794ae435c0e029358d28278533d3935e69b221b01" +checksum = "0c134de1f2f0191aed3fc24d3831da8808d1e636b06edf81a5717103095f625d" dependencies = [ + "cast", + "cfg-if", "cortex-m", - "cortex-m-rt", + "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 = "num-traits" -version = "0.2.19" +name = "nrf-usbd" +version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841" +checksum = "aedf862f941154442271ae9914777bd1c93f6d2e0dc9db4cafa160e55ffb9085" dependencies = [ - "autocfg", + "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 = "portable-atomic" -version = "1.11.1" +version = "1.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f84267b20a16ea918e43c6a88433c2d54fa145c92a811b5b047ccbe153674483" +checksum = "350e9b48cbc6b0e028b0473b114454c6316e57336ee184ceab6e53f72c178b3e" [[package]] name = "proc-macro-error-attr2" @@ -522,18 +393,18 @@ dependencies = [ [[package]] name = "proc-macro2" -version = "1.0.103" +version = "1.0.94" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5ee95bc4ef87b8d5ba32e8b7714ccc834865276eab0aed5c9958d00ec45f49e8" +checksum = "a31971752e70b8b2686d7e46ec17fb38dad4051d94024c88df49b667caea9c84" dependencies = [ "unicode-ident", ] [[package]] name = "quote" -version = "1.0.41" +version = "1.0.40" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ce25767e7b499d1b604768e7cde645d14cc8584231ea6b295e9c9eb22c02e1d1" +checksum = "1885c039570dc00dcb4ff087a89e185fd56bae234ddc7f056a945bf36467248d" dependencies = [ "proc-macro2", ] @@ -544,17 +415,11 @@ version = "0.6.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" -[[package]] -name = "rand_core" -version = "0.9.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "99d9a13982dcf210057a8a78572b2217b667c3beacbf3a0d8b454f6f82837d38" - [[package]] name = "rtic" -version = "2.2.0" +version = "2.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6bc68b1fa2eefbb7ad6747b299b79c8fca92163dfa46f0e279f39109cf272186" +checksum = "401961431a1e491124cdd216a313fada2d395aa2b5bee2867c872fc8af7c1bc1" dependencies = [ "bare-metal 1.0.0", "cortex-m", @@ -572,9 +437,9 @@ checksum = "d9369355b04d06a3780ec0f51ea2d225624db777acbc60abd8ca4832da5c1a42" [[package]] name = "rtic-macros" -version = "2.2.0" +version = "2.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f387b12bd6c01d2c9d4776dddeefaf0ae51b9497c83c0186b1693f6821ff3c4a" +checksum = "ac22ab522d80079b48f46ac66ded4d349e1adf81b52430d6a74faa3a7790ed80" dependencies = [ "indexmap", "proc-macro-error2", @@ -609,15 +474,15 @@ checksum = "388a1df253eca08550bef6c72392cfe7c30914bf41df5269b68cbd6ff8f570a3" [[package]] name = "stable_deref_trait" -version = "1.2.1" +version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6ce2be8dc25455e1f91df71bfa12ad37d7af1092ae736f3a6cd0e37bc7810596" +checksum = "a8f112729512f8e442d81f95a8a7ddf2b7c6b8a1a6f509a95864142b30cab2d3" [[package]] name = "syn" -version = "2.0.109" +version = "2.0.100" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2f17c7e013e88258aa9543dcbe81aca68a667a9ac37cd69c9fbc07858bfe0e2f" +checksum = "b09a44accad81e1ba1cd74a32461ba89dee89095ba17b32f5d03683b1b1fc2a0" dependencies = [ "proc-macro2", "quote", @@ -626,18 +491,18 @@ dependencies = [ [[package]] name = "thiserror" -version = "2.0.17" +version = "2.0.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f63587ca0f12b72a0600bcba1d40081f830876000bb46dd2337a3051618f4fc8" +checksum = "567b8a2dae586314f7be2a752ec7474332959c6460e02bde30d702a66d488708" dependencies = [ "thiserror-impl", ] [[package]] name = "thiserror-impl" -version = "2.0.17" +version = "2.0.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3ff15c8ecd7de3849db632e14d18d2571fa09dfc5ed93479bc4485c7a517c913" +checksum = "7f7cf42b4507d8ea322120659672cf1b9dbb93f8f2d4ecfd6e51350ff5b17a1d" dependencies = [ "proc-macro2", "quote", @@ -646,15 +511,15 @@ dependencies = [ [[package]] name = "typenum" -version = "1.19.0" +version = "1.18.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "562d481066bde0658276a35467c4af00bdc6ee726305698a55b86e61d7ad82bb" +checksum = "1dccffe3ce07af9386bfd29e80c0ab1a8205a2fc34e4bcd40364df902cfa8f3f" [[package]] name = "unicode-ident" -version = "1.0.22" +version = "1.0.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9312f7c4f6ff9069b165498234ce8be658059c6728633667c526e27dc2cf1df5" +checksum = "5a5f39404a5da50712a4c1eecf25e90dd62b613502b7e925fd4e4d19b5c96512" [[package]] name = "usb" @@ -677,6 +542,16 @@ dependencies = [ "usb2", ] +[[package]] +name = "usb-device" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "98816b1accafbb09085168b90f27e93d790b4bfa19d883466b5e53315b5f06a6" +dependencies = [ + "heapless 0.8.0", + "portable-atomic", +] + [[package]] name = "usb2" version = "0.0.1" @@ -703,23 +578,3 @@ checksum = "de437e2a6208b014ab52972a27e59b33fa2920d3e00fe05026167a1c509d19cc" dependencies = [ "vcell", ] - -[[package]] -name = "zerocopy" -version = "0.8.27" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0894878a5fa3edfd6da3f88c4805f4c8558e2b996227a3d864f47fe11e38282c" -dependencies = [ - "zerocopy-derive", -] - -[[package]] -name = "zerocopy-derive" -version = "0.8.27" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "88d2b8d9c68ad2b9e4340d7832716a4d21a22a1154777ad56ea55c51a9cf3831" -dependencies = [ - "proc-macro2", - "quote", - "syn", -] diff --git a/nrf52-code/usb-app-solutions/src/bin/task-state.rs b/nrf52-code/usb-app-solutions/src/bin/task-state.rs index a2d101f85..f748b777a 100644 --- a/nrf52-code/usb-app-solutions/src/bin/task-state.rs +++ b/nrf52-code/usb-app-solutions/src/bin/task-state.rs @@ -7,11 +7,11 @@ use usb_app as _; #[rtic::app(device = dk, peripherals = false)] mod app { use cortex_m::asm; - use dk::hal::pac::power::Power; + use dk::peripheral::POWER; #[local] struct MyLocalResources { - power: Power, + power: POWER, counter: usize, } @@ -24,7 +24,7 @@ mod app { let power = board.power; - power.intenset().write(|w| w.set_usbdetected(true)); + power.intenset.write(|w| w.usbdetected().set_bit()); defmt::println!("USBDETECTED interrupt enabled"); @@ -46,7 +46,7 @@ mod app { } } - #[task(binds = CLOCK_POWER, local = [power, counter])] + #[task(binds = POWER_CLOCK, local = [power, counter])] // ^^^^^^^ we want to access the resource from here fn on_power_event(cx: on_power_event::Context) { defmt::println!("POWER event occurred"); @@ -60,6 +60,6 @@ mod app { ); // clear the interrupt flag; otherwise this task will run again after it returns - cx.local.power.events_usbdetected().write_value(0); + cx.local.power.events_usbdetected.reset(); } } diff --git a/nrf52-code/usb-app-solutions/src/bin/usb-1.rs b/nrf52-code/usb-app-solutions/src/bin/usb-1.rs index 73204d03c..c7eb2e83d 100644 --- a/nrf52-code/usb-app-solutions/src/bin/usb-1.rs +++ b/nrf52-code/usb-app-solutions/src/bin/usb-1.rs @@ -1,20 +1,21 @@ #![no_main] #![no_std] -use dk::hal::pac::usbd::Usbd; -use dk::usbd::{self, Event}; +use dk::{ + peripheral::USBD, + usbd::{self, Event}, +}; // this imports `src/lib.rs`to retrieve our global logger + panicking-behavior use usb_app as _; #[rtic::app(device = dk, peripherals = false)] mod app { - use super::*; #[local] struct MyLocalResources { - usbd: Usbd, + usbd: USBD, } #[shared] @@ -42,7 +43,7 @@ mod app { } /// Handle a USB event (in interrupt context) -fn on_event(_usbd: &Usbd, event: Event) { +fn on_event(_usbd: &USBD, event: Event) { defmt::debug!("USB: {} @ {=u64:tus}", event, dk::uptime_us()); match event { diff --git a/nrf52-code/usb-app-solutions/src/bin/usb-2.rs b/nrf52-code/usb-app-solutions/src/bin/usb-2.rs index 079f1fa72..7ae3fc868 100644 --- a/nrf52-code/usb-app-solutions/src/bin/usb-2.rs +++ b/nrf52-code/usb-app-solutions/src/bin/usb-2.rs @@ -1,8 +1,10 @@ #![no_main] #![no_std] -use dk::hal::pac::usbd::Usbd; -use dk::usbd::{self, Event}; +use dk::{ + peripheral::USBD, + usbd::{self, Event}, +}; use usb::{Descriptor, Request}; @@ -11,12 +13,11 @@ use usb_app as _; #[rtic::app(device = dk, peripherals = false)] mod app { - use super::*; #[local] struct MyLocalResources { - usbd: Usbd, + usbd: USBD, } #[shared] @@ -40,7 +41,7 @@ mod app { } /// Handle a USB event (in interrupt context) -fn on_event(usbd: &Usbd, event: Event) { +fn on_event(usbd: &USBD, event: Event) { defmt::debug!("USB: {} @ {=u64:tus}", event, dk::uptime_us()); match event { @@ -52,22 +53,22 @@ fn on_event(usbd: &Usbd, event: Event) { Event::UsbEp0Setup => { // the BMREQUESTTYPE register contains information about data recipient, transfer type and direction - let bmrequesttype = usbd.bmrequesttype().read().0 as u8; + let bmrequesttype = usbd.bmrequesttype.read().bits() as u8; // the BREQUEST register stores the type of the current request (e.g. SET_ADDRESS, GET_DESCRIPTOR, ...) - let brequest = usbd.brequest().read().brequest() as u8; + let brequest = usbd.brequest.read().brequest().bits(); // wLength denotes the number of bytes to transfer (if any) // composed of a high register (WLENGTHH) and a low register (WLENGTHL) - let wlength = (u16::from(usbd.wlengthh().read().wlengthh()) << 8) - | u16::from(usbd.wlengthl().read().wlengthl()); + let wlength = (u16::from(usbd.wlengthh.read().wlengthh().bits()) << 8) + | u16::from(usbd.wlengthl.read().wlengthl().bits()); // wIndex is a generic index field whose meaning depends on the request type // composed of a high register (WINDEXH) and a low register (WINDEXL) - let windex = (u16::from(usbd.windexh().read().windexh()) << 8) - | u16::from(usbd.windexl().read().windexl()); + let windex = (u16::from(usbd.windexh.read().windexh().bits()) << 8) + | u16::from(usbd.windexl.read().windexl().bits()); // wValue is a generic parameter field meaning depends on the request type (e.g. contains the device // address in SET_ADDRESS requests) // composed of a high register (WVALUEH) and a low register (WVALUEL) - let wvalue = (u16::from(usbd.wvalueh().read().wvalueh()) << 8) - | u16::from(usbd.wvaluel().read().wvaluel()); + let wvalue = (u16::from(usbd.wvalueh.read().wvalueh().bits()) << 8) + | u16::from(usbd.wvaluel.read().wvaluel().bits()); // NOTE the `dk` crate contains helper functions for the above operations // let bmrequesttype = usbd::bmrequesttype(usbd); diff --git a/nrf52-code/usb-app-solutions/src/bin/usb-3.rs b/nrf52-code/usb-app-solutions/src/bin/usb-3.rs index ed14570e0..eccdcf62e 100644 --- a/nrf52-code/usb-app-solutions/src/bin/usb-3.rs +++ b/nrf52-code/usb-app-solutions/src/bin/usb-3.rs @@ -1,8 +1,10 @@ #![no_main] #![no_std] -use dk::hal::pac::usbd::Usbd; -use dk::usbd::{self, Ep0In, Event}; +use dk::{ + peripheral::USBD, + usbd::{self, Ep0In, Event}, +}; use usb::{Descriptor, Request}; @@ -11,12 +13,11 @@ use usb_app as _; #[rtic::app(device = dk, peripherals = false)] mod app { - use super::*; #[local] struct MyLocalResources { - usbd: Usbd, + usbd: USBD, ep0in: Ep0In, } @@ -47,7 +48,7 @@ mod app { } /// Handle a USB event (in interrupt context) -fn on_event(usbd: &Usbd, ep0in: &mut Ep0In, event: Event) { +fn on_event(usbd: &USBD, ep0in: &mut Ep0In, event: Event) { defmt::debug!("USB: {} @ {=u64:tus}", event, dk::uptime_us()); match event { diff --git a/nrf52-code/usb-app-solutions/src/bin/usb-4.rs b/nrf52-code/usb-app-solutions/src/bin/usb-4.rs index c0c632349..4a04c7c1e 100644 --- a/nrf52-code/usb-app-solutions/src/bin/usb-4.rs +++ b/nrf52-code/usb-app-solutions/src/bin/usb-4.rs @@ -3,8 +3,10 @@ use core::num::NonZeroU8; -use dk::hal::pac::usbd::Usbd; -use dk::usbd::{self, Ep0In, Event}; +use dk::{ + peripheral::USBD, + usbd::{self, Ep0In, Event}, +}; use usb2::{GetDescriptor as Descriptor, StandardRequest as Request, State}; @@ -16,12 +18,11 @@ const CONFIG_VAL: u8 = 42; #[rtic::app(device = dk, peripherals = false)] mod app { - use super::*; #[local] struct MyLocalResources { - usbd: Usbd, + usbd: USBD, ep0in: Ep0In, state: State, } @@ -54,7 +55,7 @@ mod app { } /// Handle a USB event (in interrupt context) -fn on_event(usbd: &Usbd, ep0in: &mut Ep0In, state: &mut State, event: Event) { +fn on_event(usbd: &USBD, ep0in: &mut Ep0In, state: &mut State, event: Event) { defmt::debug!("USB: {} @ {=u64:tus}", event, dk::uptime_us()); match event { @@ -78,7 +79,7 @@ fn on_event(usbd: &Usbd, ep0in: &mut Ep0In, state: &mut State, event: Event) { } /// Handle a SETUP request on EP0 -fn ep0setup(usbd: &Usbd, ep0in: &mut Ep0In, state: &mut State) -> Result<(), ()> { +fn ep0setup(usbd: &USBD, ep0in: &mut Ep0In, state: &mut State) -> Result<(), ()> { let bmrequesttype = usbd::bmrequesttype(usbd); let brequest = usbd::brequest(usbd); let wlength = usbd::wlength(usbd); diff --git a/nrf52-code/usb-app-solutions/src/bin/usb-5.rs b/nrf52-code/usb-app-solutions/src/bin/usb-5.rs index 005becc19..1cece83e6 100644 --- a/nrf52-code/usb-app-solutions/src/bin/usb-5.rs +++ b/nrf52-code/usb-app-solutions/src/bin/usb-5.rs @@ -3,8 +3,10 @@ use core::num::NonZeroU8; -use dk::hal::pac::usbd::Usbd; -use dk::usbd::{self, Ep0In, Event}; +use dk::{ + peripheral::USBD, + usbd::{self, Ep0In, Event}, +}; use usb2::{GetDescriptor as Descriptor, StandardRequest as Request, State}; @@ -16,12 +18,11 @@ const CONFIG_VAL: u8 = 42; #[rtic::app(device = dk, peripherals = false)] mod app { - use super::*; #[local] struct MyLocalResources { - usbd: Usbd, + usbd: USBD, ep0in: Ep0In, state: State, } @@ -54,7 +55,7 @@ mod app { } /// Handle a USB event (in interrupt context) -fn on_event(usbd: &Usbd, ep0in: &mut Ep0In, state: &mut State, event: Event) { +fn on_event(usbd: &USBD, ep0in: &mut Ep0In, state: &mut State, event: Event) { defmt::debug!("USB: {} @ {=u64:tus}", event, dk::uptime_us()); match event { @@ -78,7 +79,7 @@ fn on_event(usbd: &Usbd, ep0in: &mut Ep0In, state: &mut State, event: Event) { } /// Handle a SETUP request on EP0 -fn ep0setup(usbd: &Usbd, ep0in: &mut Ep0In, state: &mut State) -> Result<(), ()> { +fn ep0setup(usbd: &USBD, ep0in: &mut Ep0In, state: &mut State) -> Result<(), ()> { let bmrequesttype = usbd::bmrequesttype(usbd); let brequest = usbd::brequest(usbd); let wlength = usbd::wlength(usbd); @@ -237,7 +238,8 @@ fn ep0setup(usbd: &Usbd, ep0in: &mut Ep0In, state: &mut State) -> Result<(), ()> } } - usbd.tasks_ep0status().write_value(1); + usbd.tasks_ep0status + .write(|w| w.tasks_ep0status().set_bit()); } Ok(_) => { // stall anything else diff --git a/nrf52-code/usb-app/Cargo.lock b/nrf52-code/usb-app/Cargo.lock index 9f7b0bf2e..53760b113 100644 --- a/nrf52-code/usb-app/Cargo.lock +++ b/nrf52-code/usb-app/Cargo.lock @@ -2,12 +2,6 @@ # It is not intended for manual editing. version = 4 -[[package]] -name = "autocfg" -version = "1.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c08606f8c3cbf4ce6ec8e28fb0014a2c086708fe954eaa885384a6165172e7e8" - [[package]] name = "az" version = "1.2.1" @@ -41,12 +35,6 @@ version = "1.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" -[[package]] -name = "bitflags" -version = "2.10.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "812e12b5285cc515a9c72a5c1d3b6d46a19dac5acfef5265968c166106e31dd3" - [[package]] name = "bytemuck" version = "1.22.0" @@ -59,6 +47,12 @@ 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" @@ -129,7 +123,7 @@ version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "548d977b6da32fa1d1fda2876453da1e7df63ad0304c8b3dae4dbe7b96f39b78" dependencies = [ - "bitflags 1.3.2", + "bitflags", "defmt-macros", ] @@ -174,131 +168,18 @@ dependencies = [ "cortex-m-semihosting", "defmt", "defmt-rtt", - "embassy-nrf", - "embassy-time", "embedded-hal 1.0.0", "grounded", - "nb 1.1.0", -] - -[[package]] -name = "document-features" -version = "0.2.12" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d4b8a88685455ed29a21542a33abd9cb6510b6b129abadabdcef0f4c55bc8f61" -dependencies = [ - "litrs", -] - -[[package]] -name = "embassy-embedded-hal" -version = "0.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "554e3e840696f54b4c9afcf28a0f24da431c927f4151040020416e7393d6d0d8" -dependencies = [ - "embassy-futures", - "embassy-hal-internal", - "embassy-sync", - "embedded-hal 0.2.7", - "embedded-hal 1.0.0", - "embedded-hal-async", - "embedded-storage", - "embedded-storage-async", - "nb 1.1.0", -] - -[[package]] -name = "embassy-futures" -version = "0.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dc2d050bdc5c21e0862a89256ed8029ae6c290a93aecefc73084b3002cdebb01" - -[[package]] -name = "embassy-hal-internal" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "95285007a91b619dc9f26ea8f55452aa6c60f7115a4edc05085cd2bd3127cd7a" -dependencies = [ - "cortex-m", - "critical-section", - "num-traits", -] - -[[package]] -name = "embassy-nrf" -version = "0.8.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a8d63429d74ab5786cde7c9dc9a0338ea162a4da95e204ac5345c5ae36831fdb" -dependencies = [ - "bitflags 2.10.0", - "cfg-if", - "cortex-m", - "cortex-m-rt", - "critical-section", - "document-features", - "embassy-embedded-hal", - "embassy-hal-internal", - "embassy-sync", - "embassy-usb-driver", - "embedded-hal 0.2.7", - "embedded-hal 1.0.0", - "embedded-hal-async", - "embedded-io", - "embedded-io-async", - "embedded-storage", - "embedded-storage-async", - "fixed", - "nrf-pac", - "rand_core 0.6.4", - "rand_core 0.9.3", -] - -[[package]] -name = "embassy-sync" -version = "0.7.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "73974a3edbd0bd286759b3d483540f0ebef705919a5f56f4fc7709066f71689b" -dependencies = [ - "cfg-if", - "critical-section", - "embedded-io-async", - "futures-core", - "futures-sink", - "heapless 0.8.0", -] - -[[package]] -name = "embassy-time" -version = "0.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f4fa65b9284d974dad7a23bb72835c4ec85c0b540d86af7fc4098c88cff51d65" -dependencies = [ - "cfg-if", - "critical-section", - "document-features", - "embassy-time-driver", - "embedded-hal 0.2.7", - "embedded-hal 1.0.0", - "embedded-hal-async", - "futures-core", -] - -[[package]] -name = "embassy-time-driver" -version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a0a244c7dc22c8d0289379c8d8830cae06bb93d8f990194d0de5efb3b5ae7ba6" -dependencies = [ - "document-features", + "nrf52840-hal", ] [[package]] -name = "embassy-usb-driver" +name = "embedded-dma" version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "17119855ccc2d1f7470a39756b12068454ae27a3eabb037d940b5c03d9c77b7a" +checksum = "994f7e5b5cb23521c22304927195f236813053eb9c065dd2226a32ba64695446" dependencies = [ - "embedded-io-async", + "stable_deref_trait", ] [[package]] @@ -317,45 +198,18 @@ 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-io-async" -version = "0.6.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3ff09972d4073aa8c299395be75161d582e7629cd663171d62af73c8d50dba3f" -dependencies = [ - "embedded-io", -] - [[package]] name = "embedded-storage" version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a21dea9854beb860f3062d10228ce9b976da520a73474aed3171ec276bc0c032" -[[package]] -name = "embedded-storage-async" -version = "0.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1763775e2323b7d5f0aa6090657f5e21cfa02ede71f5dc40eead06d64dcd15cc" -dependencies = [ - "embedded-storage", -] - [[package]] name = "equivalent" version = "1.0.2" @@ -374,18 +228,6 @@ dependencies = [ "typenum", ] -[[package]] -name = "futures-core" -version = "0.3.31" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "05f29059c0c2090612e8d742178b0580d2dc940c837851ad723096f87af6663e" - -[[package]] -name = "futures-sink" -version = "0.3.31" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e575fab7d1e0dcb8d0c7bcf9a63ee213816ab51902e6d244a95819acacf1d4f7" - [[package]] name = "grounded" version = "0.2.0" @@ -451,12 +293,6 @@ dependencies = [ "hashbrown", ] -[[package]] -name = "litrs" -version = "1.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "11d3d7f243d5c5a8b9bb5d6dd2b1602c0cb0b9db1621bafc7ed66e35ff9fe092" - [[package]] name = "nb" version = "0.1.3" @@ -473,22 +309,58 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8d5439c4ad607c3c23abf66de8c8bf57ba8adcd1f129e699851a6e43935d339d" [[package]] -name = "nrf-pac" -version = "0.1.0" +name = "nrf-hal-common" +version = "0.18.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d334027d6703534f2a80de0794ae435c0e029358d28278533d3935e69b221b01" +checksum = "0c134de1f2f0191aed3fc24d3831da8808d1e636b06edf81a5717103095f625d" dependencies = [ + "cast", + "cfg-if", "cortex-m", - "cortex-m-rt", + "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 = "num-traits" -version = "0.2.19" +name = "nrf52840-pac" +version = "0.12.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841" +checksum = "30713f36f1be02e5bc9abefa30eae4a1f943d810f199d4923d3ad062d1be1b3d" dependencies = [ - "autocfg", + "cortex-m", + "cortex-m-rt", + "vcell", ] [[package]] @@ -543,12 +415,6 @@ version = "0.6.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" -[[package]] -name = "rand_core" -version = "0.9.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "99d9a13982dcf210057a8a78572b2217b667c3beacbf3a0d8b454f6f82837d38" - [[package]] name = "rtic" version = "2.1.2" @@ -680,6 +546,16 @@ dependencies = [ "usb2", ] +[[package]] +name = "usb-device" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "98816b1accafbb09085168b90f27e93d790b4bfa19d883466b5e53315b5f06a6" +dependencies = [ + "heapless 0.8.0", + "portable-atomic", +] + [[package]] name = "usb2" version = "0.0.1" diff --git a/nrf52-code/usb-app/src/bin/events.rs b/nrf52-code/usb-app/src/bin/events.rs index dc848dee6..9a977321d 100644 --- a/nrf52-code/usb-app/src/bin/events.rs +++ b/nrf52-code/usb-app/src/bin/events.rs @@ -23,11 +23,11 @@ mod app { // INTENSET is one of POWER's registers // the `write()` method writes a (32-bit) value into the register - power.intenset().write(|w| { + power.intenset.write(|w| { // `w` is a "constructor" with methods to clear/set the bitfields of INTENSET // `w` starts with all bitfields set to their reset value // USBDETECTED is one of INTENSET's 1-bit fields - w.set_usbdetected(true) + w.usbdetected().set_bit() }); defmt::println!("USBDETECTED interrupt enabled"); @@ -36,14 +36,15 @@ mod app { // the `read()` method returns a reader which can then be used to access the register content // in full or only specific bitfields (see below) // (the layout of the USBREGSTATUS register can be found in section 5.3.7.13 of the PS) - let regstatus: u32 = power.usbregstatus().read().0; - // ^^ complete register content + let regstatus: u32 = power.usbregstatus.read().bits(); + // ^^^^ complete register content defmt::println!("USBREGSTATUS: {:b}", regstatus); // read the 1-bit VBUSDETECT field that is part of the USBREGSTATUS register content // to show that its contents reflect our usb connection status // (the USBDETECTED event that will trigger `on_power_event()` is derived from this information) - let vbusdetect: bool = power.usbregstatus().read().vbusdetect(); + let vbusdetect: bool = power.usbregstatus.read().vbusdetect().is_vbus_present(); + // ^^^^^^^^^^ bitfield name defmt::println!("USBREGSTATUS.VBUSDETECT: {}", vbusdetect); (MySharedResources {}, MyLocalResources {}) @@ -59,7 +60,7 @@ mod app { } } - #[task(binds = CLOCK_POWER)] + #[task(binds = POWER_CLOCK)] fn on_power_event(_cx: on_power_event::Context) { defmt::println!("POWER event occurred"); asm::bkpt(); diff --git a/nrf52-code/usb-app/src/bin/task-state.rs b/nrf52-code/usb-app/src/bin/task-state.rs index e1e16c9cc..fe34b2d5b 100644 --- a/nrf52-code/usb-app/src/bin/task-state.rs +++ b/nrf52-code/usb-app/src/bin/task-state.rs @@ -7,11 +7,11 @@ use usb_app as _; #[rtic::app(device = dk, peripherals = false)] mod app { use cortex_m::asm; - use dk::hal::pac::power::Power; + use dk::peripheral::POWER; #[local] struct MyLocalResources { - power: Power, + power: POWER, } #[shared] @@ -23,7 +23,7 @@ mod app { let power = board.power; - power.intenset().write(|w| w.set_usbdetected(true)); + power.intenset.write(|w| w.usbdetected().set_bit()); defmt::println!("USBDETECTED interrupt enabled"); @@ -39,12 +39,12 @@ mod app { } } - #[task(binds = CLOCK_POWER, local = [power])] + #[task(binds = POWER_CLOCK, local = [power])] // ^^^^^^^ resource access list fn on_power_event(cx: on_power_event::Context) { defmt::println!("POWER event occurred"); // clear the interrupt flag; otherwise this task will run again after it returns - cx.local.power.events_usbdetected().write_value(0); + cx.local.power.events_usbdetected.reset(); } } diff --git a/nrf52-code/usb-app/src/bin/usb-1.rs b/nrf52-code/usb-app/src/bin/usb-1.rs index d77311e6a..fc63c4d44 100644 --- a/nrf52-code/usb-app/src/bin/usb-1.rs +++ b/nrf52-code/usb-app/src/bin/usb-1.rs @@ -1,20 +1,21 @@ #![no_main] #![no_std] -use dk::hal::pac::usbd::Usbd; -use dk::usbd::{self, Event}; +use dk::{ + peripheral::USBD, + usbd::{self, Event}, +}; // this imports `src/lib.rs`to retrieve our global logger + panicking-behavior use usb_app as _; #[rtic::app(device = dk, peripherals = false)] mod app { - use super::*; #[local] struct MyLocalResources { - usbd: Usbd, + usbd: USBD, } #[shared] @@ -42,7 +43,7 @@ mod app { } /// Handle a USB event (in interrupt context) -fn on_event(_usbd: &Usbd, event: Event) { +fn on_event(_usbd: &USBD, event: Event) { defmt::debug!("USB: {} @ {=u64:tus}", event, dk::uptime_us()); match event { diff --git a/nrf52-code/usb-app/src/bin/usb-2.rs b/nrf52-code/usb-app/src/bin/usb-2.rs index 54c6344a1..213f0cd74 100644 --- a/nrf52-code/usb-app/src/bin/usb-2.rs +++ b/nrf52-code/usb-app/src/bin/usb-2.rs @@ -1,8 +1,10 @@ #![no_main] #![no_std] -use dk::hal::pac::usbd::Usbd; -use dk::usbd::{self, Event}; +use dk::{ + peripheral::USBD, + usbd::{self, Event}, +}; use usb::{Descriptor, Request}; @@ -11,12 +13,11 @@ use usb_app as _; #[rtic::app(device = dk, peripherals = false)] mod app { - use super::*; #[local] struct MyLocalResources { - usbd: Usbd, + usbd: USBD, } #[shared] @@ -40,7 +41,7 @@ mod app { } /// Handle a USB event (in interrupt context) -fn on_event(_usbd: &Usbd, event: Event) { +fn on_event(_usbd: &USBD, event: Event) { defmt::debug!("USB: {} @ {=u64:tus}", event, dk::uptime_us()); match event { diff --git a/nrf52-code/usb-app/src/bin/usb-3.rs b/nrf52-code/usb-app/src/bin/usb-3.rs index 5d288001c..2de9d2e5f 100644 --- a/nrf52-code/usb-app/src/bin/usb-3.rs +++ b/nrf52-code/usb-app/src/bin/usb-3.rs @@ -1,8 +1,10 @@ #![no_main] #![no_std] -use dk::hal::pac::usbd::Usbd; -use dk::usbd::{self, Ep0In, Event}; +use dk::{ + peripheral::USBD, + usbd::{self, Ep0In, Event}, +}; use usb::{Descriptor, Request}; @@ -11,12 +13,11 @@ use usb_app as _; #[rtic::app(device = dk, peripherals = false)] mod app { - use super::*; #[local] struct MyLocalResources { - usbd: Usbd, + usbd: USBD, ep0in: Ep0In, } @@ -47,7 +48,7 @@ mod app { } /// Handle a USB event (in interrupt context) -fn on_event(usbd: &Usbd, ep0in: &mut Ep0In, event: Event) { +fn on_event(usbd: &USBD, ep0in: &mut Ep0In, event: Event) { defmt::debug!("USB: {} @ {=u64:tus}", event, dk::uptime_us()); match event { diff --git a/nrf52-code/usb-app/src/bin/usb-4.rs b/nrf52-code/usb-app/src/bin/usb-4.rs index b2835868c..a11e6ceed 100644 --- a/nrf52-code/usb-app/src/bin/usb-4.rs +++ b/nrf52-code/usb-app/src/bin/usb-4.rs @@ -1,8 +1,10 @@ #![no_main] #![no_std] -use dk::hal::pac::usbd::Usbd; -use dk::usbd::{self, Ep0In, Event}; +use dk::{ + peripheral::USBD, + usbd::{self, Ep0In, Event}, +}; use usb2::State; @@ -15,12 +17,11 @@ use usb_app as _; #[rtic::app(device = dk, peripherals = false)] mod app { - use super::*; #[local] struct MyLocalResources { - usbd: Usbd, + usbd: USBD, ep0in: Ep0In, state: State, } @@ -53,7 +54,7 @@ mod app { } /// Handle a USB event (in interrupt context) -fn on_event(usbd: &Usbd, ep0in: &mut Ep0In, state: &mut State, event: Event) { +fn on_event(usbd: &USBD, ep0in: &mut Ep0In, state: &mut State, event: Event) { defmt::debug!("USB: {} @ {=u64:tus}", event, dk::uptime_us()); match event { @@ -79,7 +80,7 @@ fn on_event(usbd: &Usbd, ep0in: &mut Ep0In, state: &mut State, event: Event) { } /// Handle a SETUP request on EP0 -fn ep0setup(usbd: &Usbd, ep0in: &mut Ep0In, _state: &mut State) -> Result<(), ()> { +fn ep0setup(usbd: &USBD, ep0in: &mut Ep0In, _state: &mut State) -> Result<(), ()> { let bmrequesttype = usbd::bmrequesttype(usbd); let brequest = usbd::brequest(usbd); let wlength = usbd::wlength(usbd);