diff --git a/embassy-nrf-examples/Cargo.toml b/embassy-nrf-examples/Cargo.toml index 432e8950..2a5b52dd 100644 --- a/embassy-nrf-examples/Cargo.toml +++ b/embassy-nrf-examples/Cargo.toml @@ -28,5 +28,4 @@ cortex-m = { version = "0.7.1", features = ["inline-asm"] } cortex-m-rt = "0.6.13" embedded-hal = { version = "0.2.4" } panic-probe = "0.1.0" -nrf52840-hal = { version = "0.12.1" } futures = { version = "0.3.8", default-features = false, features = ["async-await"] } \ No newline at end of file diff --git a/embassy-nrf-examples/src/bin/buffered_uart.rs b/embassy-nrf-examples/src/bin/buffered_uart.rs index 80b24d2b..c7c82e84 100644 --- a/embassy-nrf-examples/src/bin/buffered_uart.rs +++ b/embassy-nrf-examples/src/bin/buffered_uart.rs @@ -7,20 +7,16 @@ #[path = "../example_common.rs"] mod example_common; -use core::mem; - -use embassy_nrf::gpio::NoPin; -use example_common::*; use cortex_m_rt::entry; use defmt::panic; -use futures::pin_mut; -use nrf52840_hal::clocks; - use embassy::executor::{task, Executor}; use embassy::io::{AsyncBufReadExt, AsyncWriteExt}; use embassy::util::{Forever, Steal}; +use embassy_nrf::gpio::NoPin; use embassy_nrf::{buffered_uarte::BufferedUarte, interrupt, peripherals, rtc, uarte, Peripherals}; +use example_common::*; +use futures::pin_mut; #[task] async fn run() { @@ -85,14 +81,9 @@ fn main() -> ! { let p = unwrap!(embassy_nrf::Peripherals::take()); - clocks::Clocks::new(unsafe { mem::transmute(()) }) - .enable_ext_hfosc() - .set_lfclk_src_external(clocks::LfOscConfiguration::NoExternalNoBypass) - .start_lfclk(); - + unsafe { embassy_nrf::system::configure(Default::default()) }; let rtc = RTC.put(rtc::RTC::new(p.RTC1, interrupt::take!(RTC1))); rtc.start(); - unsafe { embassy::time::set_clock(rtc) }; let alarm = ALARM.put(rtc.alarm0()); diff --git a/embassy-nrf-examples/src/bin/executor_fairness_test.rs b/embassy-nrf-examples/src/bin/executor_fairness_test.rs index cfcfd949..67610ef0 100644 --- a/embassy-nrf-examples/src/bin/executor_fairness_test.rs +++ b/embassy-nrf-examples/src/bin/executor_fairness_test.rs @@ -9,7 +9,6 @@ mod example_common; use example_common::*; -use core::mem; use core::task::Poll; use cortex_m_rt::entry; use defmt::panic; @@ -18,7 +17,6 @@ use embassy::time::{Duration, Instant, Timer}; use embassy::util::Forever; use embassy_nrf::peripherals; use embassy_nrf::{interrupt, rtc}; -use nrf52840_hal::clocks; #[task] async fn run1() { @@ -54,14 +52,9 @@ fn main() -> ! { let p = unwrap!(embassy_nrf::Peripherals::take()); - clocks::Clocks::new(unsafe { mem::transmute(()) }) - .enable_ext_hfosc() - .set_lfclk_src_external(clocks::LfOscConfiguration::NoExternalNoBypass) - .start_lfclk(); - + unsafe { embassy_nrf::system::configure(Default::default()) }; let rtc = RTC.put(rtc::RTC::new(p.RTC1, interrupt::take!(RTC1))); rtc.start(); - unsafe { embassy::time::set_clock(rtc) }; let alarm = ALARM.put(rtc.alarm0()); diff --git a/embassy-nrf-examples/src/bin/multiprio.rs b/embassy-nrf-examples/src/bin/multiprio.rs index 017de3c0..aa2824f6 100644 --- a/embassy-nrf-examples/src/bin/multiprio.rs +++ b/embassy-nrf-examples/src/bin/multiprio.rs @@ -62,14 +62,10 @@ #[path = "../example_common.rs"] mod example_common; -use core::mem; - use example_common::*; use cortex_m_rt::entry; use defmt::panic; -use nrf52840_hal::clocks; - use embassy::executor::{task, Executor, InterruptExecutor}; use embassy::interrupt::InterruptExt; use embassy::time::{Duration, Instant, Timer}; @@ -132,11 +128,7 @@ fn main() -> ! { let p = unwrap!(embassy_nrf::Peripherals::take()); - clocks::Clocks::new(unsafe { mem::transmute(()) }) - .enable_ext_hfosc() - .set_lfclk_src_external(clocks::LfOscConfiguration::NoExternalNoBypass) - .start_lfclk(); - + unsafe { embassy_nrf::system::configure(Default::default()) }; let rtc = RTC.put(rtc::RTC::new(p.RTC1, interrupt::take!(RTC1))); rtc.start(); unsafe { embassy::time::set_clock(rtc) }; diff --git a/embassy-nrf-examples/src/bin/ppi.rs b/embassy-nrf-examples/src/bin/ppi.rs index 87854fa5..382c18f8 100644 --- a/embassy-nrf-examples/src/bin/ppi.rs +++ b/embassy-nrf-examples/src/bin/ppi.rs @@ -20,7 +20,6 @@ use embassy_nrf::gpio::{Input, Level, Output, OutputDrive, Pull}; use embassy_nrf::gpiote::{self, InputChannel, InputChannelPolarity}; use embassy_nrf::ppi::Ppi; use embassy_nrf::{interrupt, Peripherals}; -use futures::future; use gpiote::{OutputChannel, OutputChannelPolarity}; #[task] diff --git a/embassy-nrf-examples/src/bin/raw_spawn.rs b/embassy-nrf-examples/src/bin/raw_spawn.rs index 1dd60403..f8e021d9 100644 --- a/embassy-nrf-examples/src/bin/raw_spawn.rs +++ b/embassy-nrf-examples/src/bin/raw_spawn.rs @@ -3,19 +3,17 @@ #[path = "../example_common.rs"] mod example_common; -use core::mem; - -use embassy::executor::raw::Task; use example_common::*; +use core::mem; use cortex_m_rt::entry; use defmt::panic; +use embassy::executor::raw::Task; use embassy::executor::Executor; use embassy::time::{Duration, Timer}; use embassy::util::Forever; use embassy_nrf::peripherals; use embassy_nrf::{interrupt, rtc}; -use nrf52840_hal::clocks; async fn run1() { loop { @@ -41,14 +39,9 @@ fn main() -> ! { let p = unwrap!(embassy_nrf::Peripherals::take()); - clocks::Clocks::new(unsafe { mem::transmute(()) }) - .enable_ext_hfosc() - .set_lfclk_src_external(clocks::LfOscConfiguration::NoExternalNoBypass) - .start_lfclk(); - + unsafe { embassy_nrf::system::configure(Default::default()) }; let rtc = RTC.put(rtc::RTC::new(p.RTC1, interrupt::take!(RTC1))); rtc.start(); - unsafe { embassy::time::set_clock(rtc) }; let alarm = ALARM.put(rtc.alarm0()); diff --git a/embassy-nrf-examples/src/bin/spim.rs b/embassy-nrf-examples/src/bin/spim.rs index 77058bf2..5e2340ff 100644 --- a/embassy-nrf-examples/src/bin/spim.rs +++ b/embassy-nrf-examples/src/bin/spim.rs @@ -8,8 +8,6 @@ #[path = "../example_common.rs"] mod example_common; -use core::mem; - use cortex_m_rt::entry; use defmt::panic; use embassy::executor::{task, Executor}; @@ -22,7 +20,6 @@ use embassy_traits::spi::FullDuplex; use embedded_hal::digital::v2::*; use example_common::*; use futures::pin_mut; -use nrf52840_hal::clocks; #[task] async fn run() { @@ -98,13 +95,10 @@ fn main() -> ! { let p = unwrap!(embassy_nrf::Peripherals::take()); - clocks::Clocks::new(unsafe { mem::transmute(()) }) - .enable_ext_hfosc() - .set_lfclk_src_external(clocks::LfOscConfiguration::NoExternalNoBypass) - .start_lfclk(); - + unsafe { embassy_nrf::system::configure(Default::default()) }; let rtc = RTC.put(rtc::RTC::new(p.RTC1, interrupt::take!(RTC1))); rtc.start(); + unsafe { embassy::time::set_clock(rtc) }; unsafe { embassy::time::set_clock(rtc) }; diff --git a/embassy-nrf-examples/src/bin/timer.rs b/embassy-nrf-examples/src/bin/timer.rs index 41e5d77a..47d5d677 100644 --- a/embassy-nrf-examples/src/bin/timer.rs +++ b/embassy-nrf-examples/src/bin/timer.rs @@ -7,8 +7,6 @@ #[path = "../example_common.rs"] mod example_common; -use core::mem; - use example_common::*; use cortex_m_rt::entry; @@ -16,9 +14,7 @@ use defmt::panic; use embassy::executor::{task, Executor}; use embassy::time::{Duration, Timer}; use embassy::util::Forever; -use embassy_nrf::peripherals; -use embassy_nrf::{interrupt, rtc}; -use nrf52840_hal::clocks; +use embassy_nrf::{interrupt, peripherals, rtc}; #[task] async fn run1() { @@ -44,16 +40,11 @@ static EXECUTOR: Forever = Forever::new(); fn main() -> ! { info!("Hello World!"); - clocks::Clocks::new(unsafe { mem::transmute(()) }) - .enable_ext_hfosc() - .set_lfclk_src_external(clocks::LfOscConfiguration::NoExternalNoBypass) - .start_lfclk(); - let p = unwrap!(embassy_nrf::Peripherals::take()); + unsafe { embassy_nrf::system::configure(Default::default()) }; let rtc = RTC.put(rtc::RTC::new(p.RTC1, interrupt::take!(RTC1))); rtc.start(); - unsafe { embassy::time::set_clock(rtc) }; let alarm = ALARM.put(rtc.alarm0()); diff --git a/embassy-nrf-examples/src/bin/uart.rs b/embassy-nrf-examples/src/bin/uart.rs index d8644167..9bbcb3d4 100644 --- a/embassy-nrf-examples/src/bin/uart.rs +++ b/embassy-nrf-examples/src/bin/uart.rs @@ -7,9 +7,6 @@ #[path = "../example_common.rs"] mod example_common; -use core::mem; - -use embassy_nrf::gpio::NoPin; use example_common::*; use cortex_m_rt::entry; @@ -17,9 +14,9 @@ use defmt::panic; use embassy::executor::{task, Executor}; use embassy::traits::uart::{Read, Write}; use embassy::util::{Forever, Steal}; +use embassy_nrf::gpio::NoPin; use embassy_nrf::{interrupt, peripherals, rtc, uarte, Peripherals}; use futures::pin_mut; -use nrf52840_hal::clocks; #[task] async fn run() { @@ -88,14 +85,9 @@ fn main() -> ! { let p = unwrap!(embassy_nrf::Peripherals::take()); - clocks::Clocks::new(unsafe { mem::transmute(()) }) - .enable_ext_hfosc() - .set_lfclk_src_external(clocks::LfOscConfiguration::NoExternalNoBypass) - .start_lfclk(); - + unsafe { embassy_nrf::system::configure(Default::default()) }; let rtc = RTC.put(rtc::RTC::new(p.RTC1, interrupt::take!(RTC1))); rtc.start(); - unsafe { embassy::time::set_clock(rtc) }; let alarm = ALARM.put(rtc.alarm0()); diff --git a/embassy-nrf-examples/src/example_common.rs b/embassy-nrf-examples/src/example_common.rs index d16964d4..54d63383 100644 --- a/embassy-nrf-examples/src/example_common.rs +++ b/embassy-nrf-examples/src/example_common.rs @@ -1,7 +1,6 @@ #![macro_use] use defmt_rtt as _; // global logger -use nrf52840_hal as _; use panic_probe as _; pub use defmt::*; diff --git a/embassy-nrf/Cargo.toml b/embassy-nrf/Cargo.toml index 3ab2c60b..8ec5b087 100644 --- a/embassy-nrf/Cargo.toml +++ b/embassy-nrf/Cargo.toml @@ -31,8 +31,8 @@ embedded-hal = { version = "0.2.4" } embedded-dma = { version = "0.1.2" } futures = { version = "0.3.5", default-features = false } -nrf52810-pac = { version = "0.9.0", optional = true } -nrf52811-pac = { version = "0.9.1", optional = true } -nrf52832-pac = { version = "0.9.0", optional = true } -nrf52833-pac = { version = "0.9.0", optional = true } -nrf52840-pac = { version = "0.9.0", optional = true } +nrf52810-pac = { version = "0.9.0", optional = true, features = [ "rt" ]} +nrf52811-pac = { version = "0.9.1", optional = true, features = [ "rt" ]} +nrf52832-pac = { version = "0.9.0", optional = true, features = [ "rt" ]} +nrf52833-pac = { version = "0.9.0", optional = true, features = [ "rt" ]} +nrf52840-pac = { version = "0.9.0", optional = true, features = [ "rt" ]} diff --git a/embassy-nrf/src/lib.rs b/embassy-nrf/src/lib.rs index 042050d2..33d764fb 100644 --- a/embassy-nrf/src/lib.rs +++ b/embassy-nrf/src/lib.rs @@ -92,6 +92,7 @@ pub mod qspi; pub mod rtc; pub mod saadc; pub mod spim; +pub mod system; pub mod timer; pub mod uarte; diff --git a/embassy-nrf/src/system.rs b/embassy-nrf/src/system.rs new file mode 100644 index 00000000..5d36e66f --- /dev/null +++ b/embassy-nrf/src/system.rs @@ -0,0 +1,76 @@ +use crate::pac; + +pub enum HfclkSource { + Internal, + ExternalXtal, +} + +pub enum LfclkSource { + InternalRC, + Synthesized, + ExternalXtal, + ExternalLowSwing, + ExternalFullSwing, +} + +#[non_exhaustive] +pub struct Config { + pub hfclk_source: HfclkSource, + pub lfclk_source: LfclkSource, +} + +impl Default for Config { + fn default() -> Self { + Self { + // There are hobby nrf52 boards out there without external XTALs... + // Default everything to internal so it Just Works. User can enable external + // xtals if they know they have them. + hfclk_source: HfclkSource::Internal, + lfclk_source: LfclkSource::InternalRC, + } + } +} + +/// safety: must only call once. +pub unsafe fn configure(config: Config) { + let r = &*pac::CLOCK::ptr(); + + // Start HFCLK. + match config.hfclk_source { + HfclkSource::Internal => {} + HfclkSource::ExternalXtal => { + // Datasheet says this is likely to take 0.36ms + r.events_hfclkstarted.write(|w| unsafe { w.bits(0) }); + r.tasks_hfclkstart.write(|w| unsafe { w.bits(1) }); + while r.events_hfclkstarted.read().bits() == 0 {} + } + } + + // Configure LFCLK. + match config.lfclk_source { + LfclkSource::InternalRC => r.lfclksrc.write(|w| w.src().rc()), + LfclkSource::Synthesized => r.lfclksrc.write(|w| w.src().synth()), + + LfclkSource::ExternalXtal => r.lfclksrc.write(move |w| w.src().xtal()), + + LfclkSource::ExternalLowSwing => r.lfclksrc.write(move |w| { + w.src().xtal(); + w.external().enabled(); + w.bypass().disabled(); + w + }), + LfclkSource::ExternalFullSwing => r.lfclksrc.write(move |w| { + w.src().xtal(); + w.external().enabled(); + w.bypass().enabled(); + w + }), + } + + // Start LFCLK. + // Datasheet says this could take 100us from synth source + // 600us from rc source, 0.25s from an external source. + r.events_lfclkstarted.write(|w| unsafe { w.bits(0) }); + r.tasks_lfclkstart.write(|w| unsafe { w.bits(1) }); + while r.events_lfclkstarted.read().bits() == 0 {} +}