aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDario Nieuwenhuis <[email protected]>2021-05-12 01:57:01 +0200
committerDario Nieuwenhuis <[email protected]>2021-05-17 00:57:37 +0200
commit0310e4d458b86df31f1765104eb3aa9a6ee09bfc (patch)
treeaca167ae6e37442cafc932b3c729e37082d23b04
parentbfc7f52e6dd7b5ad12fa1f09483fa60f2732ae0c (diff)
Add `init` fn. Initializes hw and returns Peripherals.
-rw-r--r--embassy-extras/src/macros.rs13
-rw-r--r--embassy-macros/src/chip/nrf.rs2
-rw-r--r--embassy-macros/src/chip/rp.rs2
-rw-r--r--embassy-macros/src/lib.rs6
-rw-r--r--embassy-nrf-examples/src/bin/blinky.rs3
-rw-r--r--embassy-nrf-examples/src/bin/buffered_uart.rs4
-rw-r--r--embassy-nrf-examples/src/bin/executor_fairness_test.rs4
-rw-r--r--embassy-nrf-examples/src/bin/gpiote_channel.rs6
-rw-r--r--embassy-nrf-examples/src/bin/gpiote_port.rs4
-rw-r--r--embassy-nrf-examples/src/bin/multiprio.rs3
-rw-r--r--embassy-nrf-examples/src/bin/ppi.rs4
-rw-r--r--embassy-nrf-examples/src/bin/qspi.rs4
-rw-r--r--embassy-nrf-examples/src/bin/raw_spawn.rs3
-rw-r--r--embassy-nrf-examples/src/bin/spim.rs4
-rw-r--r--embassy-nrf-examples/src/bin/timer.rs3
-rw-r--r--embassy-nrf-examples/src/bin/uart.rs32
-rw-r--r--embassy-nrf-examples/src/bin/uart_idle.rs4
-rw-r--r--embassy-nrf/src/lib.rs86
-rw-r--r--embassy-nrf/src/system.rs79
-rw-r--r--embassy-rp-examples/src/bin/blinky.rs4
-rw-r--r--embassy-rp-examples/src/bin/button.rs4
-rw-r--r--embassy-rp-examples/src/bin/uart.rs4
-rw-r--r--embassy-rp/src/lib.rs103
-rw-r--r--embassy-rp/src/system.rs94
24 files changed, 217 insertions, 258 deletions
diff --git a/embassy-extras/src/macros.rs b/embassy-extras/src/macros.rs
index 860c0795a..fba752619 100644
--- a/embassy-extras/src/macros.rs
+++ b/embassy-extras/src/macros.rs
@@ -46,18 +46,17 @@ macro_rules! peripherals {
46 impl Peripherals { 46 impl Peripherals {
47 ///Returns all the peripherals *once* 47 ///Returns all the peripherals *once*
48 #[inline] 48 #[inline]
49 pub fn take() -> Option<Self> { 49 pub(crate) fn take() -> Self {
50 50
51 #[no_mangle] 51 #[no_mangle]
52 static mut _EMBASSY_DEVICE_PERIPHERALS: bool = false; 52 static mut _EMBASSY_DEVICE_PERIPHERALS: bool = false;
53 53
54 critical_section::with(|_| { 54 critical_section::with(|_| unsafe {
55 if unsafe { _EMBASSY_DEVICE_PERIPHERALS } { 55 if _EMBASSY_DEVICE_PERIPHERALS {
56 None 56 panic!("init called more than once!")
57 } else {
58 unsafe { _EMBASSY_DEVICE_PERIPHERALS = true };
59 Some(unsafe { <Self as embassy::util::Steal>::steal() })
60 } 57 }
58 _EMBASSY_DEVICE_PERIPHERALS = true;
59 <Self as embassy::util::Steal>::steal()
61 }) 60 })
62 } 61 }
63 } 62 }
diff --git a/embassy-macros/src/chip/nrf.rs b/embassy-macros/src/chip/nrf.rs
index aba4c004f..503a8ba5a 100644
--- a/embassy-macros/src/chip/nrf.rs
+++ b/embassy-macros/src/chip/nrf.rs
@@ -9,7 +9,7 @@ pub fn generate(embassy_prefix: &ModulePrefix, config: syn::Expr) -> TokenStream
9 quote!( 9 quote!(
10 use #embassy_nrf_path::{interrupt, peripherals, rtc}; 10 use #embassy_nrf_path::{interrupt, peripherals, rtc};
11 11
12 unsafe { #embassy_nrf_path::system::configure(#config) }; 12 let p = #embassy_nrf_path::init(#config);
13 13
14 let mut rtc = rtc::RTC::new(unsafe { <peripherals::RTC1 as #embassy_path::util::Steal>::steal() }, interrupt::take!(RTC1)); 14 let mut rtc = rtc::RTC::new(unsafe { <peripherals::RTC1 as #embassy_path::util::Steal>::steal() }, interrupt::take!(RTC1));
15 let rtc = unsafe { make_static(&mut rtc) }; 15 let rtc = unsafe { make_static(&mut rtc) };
diff --git a/embassy-macros/src/chip/rp.rs b/embassy-macros/src/chip/rp.rs
index 33863de86..04211f8f3 100644
--- a/embassy-macros/src/chip/rp.rs
+++ b/embassy-macros/src/chip/rp.rs
@@ -7,6 +7,6 @@ pub fn generate(embassy_prefix: &ModulePrefix, config: syn::Expr) -> TokenStream
7 quote!( 7 quote!(
8 use #embassy_rp_path::{interrupt, peripherals}; 8 use #embassy_rp_path::{interrupt, peripherals};
9 9
10 unsafe { #embassy_rp_path::system::configure(#config) }; 10 let p = #embassy_rp_path::init(#config);
11 ) 11 )
12} 12}
diff --git a/embassy-macros/src/lib.rs b/embassy-macros/src/lib.rs
index d91549ca7..dc234cd6d 100644
--- a/embassy-macros/src/lib.rs
+++ b/embassy-macros/src/lib.rs
@@ -315,12 +315,12 @@ pub fn main(args: TokenStream, item: TokenStream) -> TokenStream {
315 315
316 let args = task_fn.sig.inputs.clone(); 316 let args = task_fn.sig.inputs.clone();
317 317
318 if args.len() != 1 { 318 if args.len() != 2 {
319 task_fn 319 task_fn
320 .sig 320 .sig
321 .span() 321 .span()
322 .unwrap() 322 .unwrap()
323 .error("main function must have one argument") 323 .error("main function must have 2 arguments")
324 .emit(); 324 .emit();
325 fail = true; 325 fail = true;
326 } 326 }
@@ -364,7 +364,7 @@ pub fn main(args: TokenStream, item: TokenStream) -> TokenStream {
364 #chip_setup 364 #chip_setup
365 365
366 executor.run(|spawner| { 366 executor.run(|spawner| {
367 spawner.spawn(__embassy_main(spawner)).unwrap(); 367 spawner.spawn(__embassy_main(spawner, p)).unwrap();
368 }) 368 })
369 369
370 } 370 }
diff --git a/embassy-nrf-examples/src/bin/blinky.rs b/embassy-nrf-examples/src/bin/blinky.rs
index 4cb09bee7..e6fc854b5 100644
--- a/embassy-nrf-examples/src/bin/blinky.rs
+++ b/embassy-nrf-examples/src/bin/blinky.rs
@@ -17,8 +17,7 @@ use embassy_nrf::Peripherals;
17use embedded_hal::digital::v2::OutputPin; 17use embedded_hal::digital::v2::OutputPin;
18 18
19#[embassy::main] 19#[embassy::main]
20async fn main(spawner: Spawner) { 20async fn main(spawner: Spawner, p: Peripherals) {
21 let p = Peripherals::take().unwrap();
22 let mut led = Output::new(p.P0_13, Level::Low, OutputDrive::Standard); 21 let mut led = Output::new(p.P0_13, Level::Low, OutputDrive::Standard);
23 22
24 loop { 23 loop {
diff --git a/embassy-nrf-examples/src/bin/buffered_uart.rs b/embassy-nrf-examples/src/bin/buffered_uart.rs
index 8f5d9fb2e..b3a621c6b 100644
--- a/embassy-nrf-examples/src/bin/buffered_uart.rs
+++ b/embassy-nrf-examples/src/bin/buffered_uart.rs
@@ -17,9 +17,7 @@ use example_common::*;
17use futures::pin_mut; 17use futures::pin_mut;
18 18
19#[embassy::main] 19#[embassy::main]
20async fn main(spawner: Spawner) { 20async fn main(spawner: Spawner, p: Peripherals) {
21 let p = Peripherals::take().unwrap();
22
23 let mut config = uarte::Config::default(); 21 let mut config = uarte::Config::default();
24 config.parity = uarte::Parity::EXCLUDED; 22 config.parity = uarte::Parity::EXCLUDED;
25 config.baudrate = uarte::Baudrate::BAUD115200; 23 config.baudrate = uarte::Baudrate::BAUD115200;
diff --git a/embassy-nrf-examples/src/bin/executor_fairness_test.rs b/embassy-nrf-examples/src/bin/executor_fairness_test.rs
index 3ea74316e..ca9bcc1e6 100644
--- a/embassy-nrf-examples/src/bin/executor_fairness_test.rs
+++ b/embassy-nrf-examples/src/bin/executor_fairness_test.rs
@@ -13,7 +13,7 @@ use core::task::Poll;
13use defmt::panic; 13use defmt::panic;
14use embassy::executor::Spawner; 14use embassy::executor::Spawner;
15use embassy::time::{Duration, Instant, Timer}; 15use embassy::time::{Duration, Instant, Timer};
16use embassy_nrf::interrupt; 16use embassy_nrf::{interrupt, Peripherals};
17 17
18#[embassy::task] 18#[embassy::task]
19async fn run1() { 19async fn run1() {
@@ -40,7 +40,7 @@ async fn run3() {
40} 40}
41 41
42#[embassy::main] 42#[embassy::main]
43async fn main(spawner: Spawner) { 43async fn main(spawner: Spawner, p: Peripherals) {
44 unwrap!(spawner.spawn(run1())); 44 unwrap!(spawner.spawn(run1()));
45 unwrap!(spawner.spawn(run2())); 45 unwrap!(spawner.spawn(run2()));
46 unwrap!(spawner.spawn(run3())); 46 unwrap!(spawner.spawn(run3()));
diff --git a/embassy-nrf-examples/src/bin/gpiote_channel.rs b/embassy-nrf-examples/src/bin/gpiote_channel.rs
index ee670acd5..d52ed7767 100644
--- a/embassy-nrf-examples/src/bin/gpiote_channel.rs
+++ b/embassy-nrf-examples/src/bin/gpiote_channel.rs
@@ -12,13 +12,11 @@ use example_common::*;
12use defmt::panic; 12use defmt::panic;
13use embassy::executor::Spawner; 13use embassy::executor::Spawner;
14use embassy_nrf::gpio::{Input, Pull}; 14use embassy_nrf::gpio::{Input, Pull};
15use embassy_nrf::gpiote::{self, InputChannel, InputChannelPolarity}; 15use embassy_nrf::gpiote::{InputChannel, InputChannelPolarity};
16use embassy_nrf::{interrupt, Peripherals}; 16use embassy_nrf::{interrupt, Peripherals};
17 17
18#[embassy::main] 18#[embassy::main]
19async fn main(spawner: Spawner) { 19async fn main(spawner: Spawner, p: Peripherals) {
20 let p = Peripherals::take().unwrap();
21
22 info!("Starting!"); 20 info!("Starting!");
23 21
24 let ch1 = InputChannel::new( 22 let ch1 = InputChannel::new(
diff --git a/embassy-nrf-examples/src/bin/gpiote_port.rs b/embassy-nrf-examples/src/bin/gpiote_port.rs
index 717d3398b..4a7951cd3 100644
--- a/embassy-nrf-examples/src/bin/gpiote_port.rs
+++ b/embassy-nrf-examples/src/bin/gpiote_port.rs
@@ -28,9 +28,7 @@ async fn button_task(n: usize, mut pin: PortInput<'static, AnyPin>) {
28} 28}
29 29
30#[embassy::main] 30#[embassy::main]
31async fn main(spawner: Spawner) { 31async fn main(spawner: Spawner, p: Peripherals) {
32 let p = Peripherals::take().unwrap();
33
34 info!("Starting!"); 32 info!("Starting!");
35 33
36 let btn1 = PortInput::new(Input::new(p.P0_11.degrade(), Pull::Up)); 34 let btn1 = PortInput::new(Input::new(p.P0_11.degrade(), Pull::Up));
diff --git a/embassy-nrf-examples/src/bin/multiprio.rs b/embassy-nrf-examples/src/bin/multiprio.rs
index 9ed5c1368..79fa029b3 100644
--- a/embassy-nrf-examples/src/bin/multiprio.rs
+++ b/embassy-nrf-examples/src/bin/multiprio.rs
@@ -126,9 +126,8 @@ static EXECUTOR_LOW: Forever<Executor> = Forever::new();
126fn main() -> ! { 126fn main() -> ! {
127 info!("Hello World!"); 127 info!("Hello World!");
128 128
129 let p = unwrap!(embassy_nrf::Peripherals::take()); 129 let p = embassy_nrf::init(Default::default());
130 130
131 unsafe { embassy_nrf::system::configure(Default::default()) };
132 let rtc = RTC.put(rtc::RTC::new(p.RTC1, interrupt::take!(RTC1))); 131 let rtc = RTC.put(rtc::RTC::new(p.RTC1, interrupt::take!(RTC1)));
133 rtc.start(); 132 rtc.start();
134 unsafe { embassy::time::set_clock(rtc) }; 133 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 3c39e032e..47782ed29 100644
--- a/embassy-nrf-examples/src/bin/ppi.rs
+++ b/embassy-nrf-examples/src/bin/ppi.rs
@@ -19,9 +19,7 @@ use embassy_nrf::{interrupt, Peripherals};
19use gpiote::{OutputChannel, OutputChannelPolarity}; 19use gpiote::{OutputChannel, OutputChannelPolarity};
20 20
21#[embassy::main] 21#[embassy::main]
22async fn main(spawner: Spawner) { 22async fn main(spawner: Spawner, p: Peripherals) {
23 let p = Peripherals::take().unwrap();
24
25 info!("Starting!"); 23 info!("Starting!");
26 24
27 let button1 = InputChannel::new( 25 let button1 = InputChannel::new(
diff --git a/embassy-nrf-examples/src/bin/qspi.rs b/embassy-nrf-examples/src/bin/qspi.rs
index 28cde6e51..3dc027f6f 100644
--- a/embassy-nrf-examples/src/bin/qspi.rs
+++ b/embassy-nrf-examples/src/bin/qspi.rs
@@ -23,9 +23,7 @@ const PAGE_SIZE: usize = 4096;
23struct AlignedBuf([u8; 4096]); 23struct AlignedBuf([u8; 4096]);
24 24
25#[embassy::main] 25#[embassy::main]
26async fn main(spawner: Spawner) { 26async fn main(spawner: Spawner, p: Peripherals) {
27 let p = Peripherals::take().unwrap();
28
29 let csn = p.P0_17; 27 let csn = p.P0_17;
30 let sck = p.P0_19; 28 let sck = p.P0_19;
31 let io0 = p.P0_20; 29 let io0 = p.P0_20;
diff --git a/embassy-nrf-examples/src/bin/raw_spawn.rs b/embassy-nrf-examples/src/bin/raw_spawn.rs
index f8e021d9b..78de7b100 100644
--- a/embassy-nrf-examples/src/bin/raw_spawn.rs
+++ b/embassy-nrf-examples/src/bin/raw_spawn.rs
@@ -37,9 +37,8 @@ static EXECUTOR: Forever<Executor> = Forever::new();
37fn main() -> ! { 37fn main() -> ! {
38 info!("Hello World!"); 38 info!("Hello World!");
39 39
40 let p = unwrap!(embassy_nrf::Peripherals::take()); 40 let p = embassy_nrf::init(Default::default());
41 41
42 unsafe { embassy_nrf::system::configure(Default::default()) };
43 let rtc = RTC.put(rtc::RTC::new(p.RTC1, interrupt::take!(RTC1))); 42 let rtc = RTC.put(rtc::RTC::new(p.RTC1, interrupt::take!(RTC1)));
44 rtc.start(); 43 rtc.start();
45 unsafe { embassy::time::set_clock(rtc) }; 44 unsafe { embassy::time::set_clock(rtc) };
diff --git a/embassy-nrf-examples/src/bin/spim.rs b/embassy-nrf-examples/src/bin/spim.rs
index ccda75765..df921fc86 100644
--- a/embassy-nrf-examples/src/bin/spim.rs
+++ b/embassy-nrf-examples/src/bin/spim.rs
@@ -19,11 +19,9 @@ use embedded_hal::digital::v2::*;
19use example_common::*; 19use example_common::*;
20 20
21#[embassy::main] 21#[embassy::main]
22async fn main(spawner: Spawner) { 22async fn main(spawner: Spawner, p: Peripherals) {
23 info!("running!"); 23 info!("running!");
24 24
25 let p = unsafe { Peripherals::steal() };
26
27 let mut config = spim::Config::default(); 25 let mut config = spim::Config::default();
28 config.frequency = spim::Frequency::M16; 26 config.frequency = spim::Frequency::M16;
29 27
diff --git a/embassy-nrf-examples/src/bin/timer.rs b/embassy-nrf-examples/src/bin/timer.rs
index a2b717bc1..ffbbb7841 100644
--- a/embassy-nrf-examples/src/bin/timer.rs
+++ b/embassy-nrf-examples/src/bin/timer.rs
@@ -7,6 +7,7 @@
7 7
8#[path = "../example_common.rs"] 8#[path = "../example_common.rs"]
9mod example_common; 9mod example_common;
10use embassy_nrf::Peripherals;
10use example_common::*; 11use example_common::*;
11 12
12use defmt::panic; 13use defmt::panic;
@@ -30,7 +31,7 @@ async fn run2() {
30} 31}
31 32
32#[embassy::main] 33#[embassy::main]
33async fn main(spawner: Spawner) { 34async fn main(spawner: Spawner, p: Peripherals) {
34 unwrap!(spawner.spawn(run1())); 35 unwrap!(spawner.spawn(run1()));
35 unwrap!(spawner.spawn(run2())); 36 unwrap!(spawner.spawn(run2()));
36} 37}
diff --git a/embassy-nrf-examples/src/bin/uart.rs b/embassy-nrf-examples/src/bin/uart.rs
index 23fc89312..9a0e65d3e 100644
--- a/embassy-nrf-examples/src/bin/uart.rs
+++ b/embassy-nrf-examples/src/bin/uart.rs
@@ -17,9 +17,7 @@ use embassy_nrf::gpio::NoPin;
17use embassy_nrf::{interrupt, uarte, Peripherals}; 17use embassy_nrf::{interrupt, uarte, Peripherals};
18 18
19#[embassy::main] 19#[embassy::main]
20async fn main(spawner: Spawner) { 20async fn main(spawner: Spawner, p: Peripherals) {
21 let p = unsafe { Peripherals::steal() };
22
23 let mut config = uarte::Config::default(); 21 let mut config = uarte::Config::default();
24 config.parity = uarte::Parity::EXCLUDED; 22 config.parity = uarte::Parity::EXCLUDED;
25 config.baudrate = uarte::Baudrate::BAUD115200; 23 config.baudrate = uarte::Baudrate::BAUD115200;
@@ -42,33 +40,5 @@ async fn main(spawner: Spawner) {
42 unwrap!(uart.read(&mut buf).await); 40 unwrap!(uart.read(&mut buf).await);
43 info!("writing..."); 41 info!("writing...");
44 unwrap!(uart.write(&buf).await); 42 unwrap!(uart.write(&buf).await);
45
46 /*
47 // `receive()` doesn't return until the buffer has been completely filled with
48 // incoming data, which in this case is 8 bytes.
49 //
50 // This example shows how to use `select` to run an uart receive concurrently with a
51 // 1 second timer, effectively adding a timeout to the receive operation.
52 let recv_fut = uart.read(&mut buf);
53 let timer_fut = Timer::after(Duration::from_millis(1000));
54 let received_len = match select(recv_fut, timer_fut).await {
55 // recv_fut completed first, so we've received `buf_len` bytes.
56 Either::Left(_) => buf_len,
57 // timer_fut completed first. `select` gives us back the future that didn't complete, which
58 // is `recv_fut` in this case, so we can do further stuff with it.
59 //
60 // The recv_fut would stop the uart read automatically when dropped. However, we want to know how
61 // many bytes have been received, so we have to "gracefully stop" it with `.stop()`.
62 Either::Right((_, recv_fut)) => recv_fut.stop().await,
63 };
64 let received = &mut buf[..received_len];
65
66 if !received.is_empty() {
67 info!("read done, got {}", received);
68
69 // Echo back received data
70 unwrap!(uart.write(received).await);
71 }
72 */
73 } 43 }
74} 44}
diff --git a/embassy-nrf-examples/src/bin/uart_idle.rs b/embassy-nrf-examples/src/bin/uart_idle.rs
index 54d524ae5..a97c65933 100644
--- a/embassy-nrf-examples/src/bin/uart_idle.rs
+++ b/embassy-nrf-examples/src/bin/uart_idle.rs
@@ -18,9 +18,7 @@ use embassy_nrf::gpio::NoPin;
18use embassy_nrf::{interrupt, uarte, Peripherals}; 18use embassy_nrf::{interrupt, uarte, Peripherals};
19 19
20#[embassy::main] 20#[embassy::main]
21async fn main(spawner: Spawner) { 21async fn main(spawner: Spawner, p: Peripherals) {
22 let p = unsafe { Peripherals::steal() };
23
24 let mut config = uarte::Config::default(); 22 let mut config = uarte::Config::default();
25 config.parity = uarte::Parity::EXCLUDED; 23 config.parity = uarte::Parity::EXCLUDED;
26 config.baudrate = uarte::Baudrate::BAUD115200; 24 config.baudrate = uarte::Baudrate::BAUD115200;
diff --git a/embassy-nrf/src/lib.rs b/embassy-nrf/src/lib.rs
index 4349bf39f..6ab9cbb27 100644
--- a/embassy-nrf/src/lib.rs
+++ b/embassy-nrf/src/lib.rs
@@ -35,7 +35,6 @@ pub mod rtc;
35#[cfg(not(feature = "nrf52820"))] 35#[cfg(not(feature = "nrf52820"))]
36pub mod saadc; 36pub mod saadc;
37pub mod spim; 37pub mod spim;
38pub mod system;
39pub mod timer; 38pub mod timer;
40pub mod twim; 39pub mod twim;
41pub mod uarte; 40pub mod uarte;
@@ -73,3 +72,88 @@ pub mod interrupt {
73 pub use embassy_extras::interrupt::Priority3 as Priority; 72 pub use embassy_extras::interrupt::Priority3 as Priority;
74} 73}
75pub use embassy_macros::interrupt; 74pub use embassy_macros::interrupt;
75
76pub mod config {
77 pub enum HfclkSource {
78 Internal,
79 ExternalXtal,
80 }
81
82 pub enum LfclkSource {
83 InternalRC,
84 Synthesized,
85 ExternalXtal,
86 ExternalLowSwing,
87 ExternalFullSwing,
88 }
89
90 #[non_exhaustive]
91 pub struct Config {
92 pub hfclk_source: HfclkSource,
93 pub lfclk_source: LfclkSource,
94 }
95
96 impl Default for Config {
97 fn default() -> Self {
98 Self {
99 // There are hobby nrf52 boards out there without external XTALs...
100 // Default everything to internal so it Just Works. User can enable external
101 // xtals if they know they have them.
102 hfclk_source: HfclkSource::Internal,
103 lfclk_source: LfclkSource::InternalRC,
104 }
105 }
106 }
107}
108
109pub fn init(config: config::Config) -> Peripherals {
110 // Do this first, so that it panics if user is calling `init` a second time
111 // before doing anything important.
112 let peripherals = Peripherals::take();
113
114 let r = unsafe { &*pac::CLOCK::ptr() };
115
116 // Start HFCLK.
117 match config.hfclk_source {
118 config::HfclkSource::Internal => {}
119 config::HfclkSource::ExternalXtal => {
120 // Datasheet says this is likely to take 0.36ms
121 r.events_hfclkstarted.write(|w| unsafe { w.bits(0) });
122 r.tasks_hfclkstart.write(|w| unsafe { w.bits(1) });
123 while r.events_hfclkstarted.read().bits() == 0 {}
124 }
125 }
126
127 // Configure LFCLK.
128 match config.lfclk_source {
129 config::LfclkSource::InternalRC => r.lfclksrc.write(|w| w.src().rc()),
130 config::LfclkSource::Synthesized => r.lfclksrc.write(|w| w.src().synth()),
131
132 config::LfclkSource::ExternalXtal => r.lfclksrc.write(|w| w.src().xtal()),
133
134 config::LfclkSource::ExternalLowSwing => r.lfclksrc.write(|w| {
135 w.src().xtal();
136 w.external().enabled();
137 w.bypass().disabled();
138 w
139 }),
140 config::LfclkSource::ExternalFullSwing => r.lfclksrc.write(|w| {
141 w.src().xtal();
142 w.external().enabled();
143 w.bypass().enabled();
144 w
145 }),
146 }
147
148 // Start LFCLK.
149 // Datasheet says this could take 100us from synth source
150 // 600us from rc source, 0.25s from an external source.
151 r.events_lfclkstarted.write(|w| unsafe { w.bits(0) });
152 r.tasks_lfclkstart.write(|w| unsafe { w.bits(1) });
153 while r.events_lfclkstarted.read().bits() == 0 {}
154
155 // Init GPIOTE
156 crate::gpiote::init();
157
158 peripherals
159}
diff --git a/embassy-nrf/src/system.rs b/embassy-nrf/src/system.rs
deleted file mode 100644
index e358d2c38..000000000
--- a/embassy-nrf/src/system.rs
+++ /dev/null
@@ -1,79 +0,0 @@
1use crate::pac;
2
3pub enum HfclkSource {
4 Internal,
5 ExternalXtal,
6}
7
8pub enum LfclkSource {
9 InternalRC,
10 Synthesized,
11 ExternalXtal,
12 ExternalLowSwing,
13 ExternalFullSwing,
14}
15
16#[non_exhaustive]
17pub struct Config {
18 pub hfclk_source: HfclkSource,
19 pub lfclk_source: LfclkSource,
20}
21
22impl Default for Config {
23 fn default() -> Self {
24 Self {
25 // There are hobby nrf52 boards out there without external XTALs...
26 // Default everything to internal so it Just Works. User can enable external
27 // xtals if they know they have them.
28 hfclk_source: HfclkSource::Internal,
29 lfclk_source: LfclkSource::InternalRC,
30 }
31 }
32}
33
34/// safety: must only call once.
35pub unsafe fn configure(config: Config) {
36 let r = &*pac::CLOCK::ptr();
37
38 // Start HFCLK.
39 match config.hfclk_source {
40 HfclkSource::Internal => {}
41 HfclkSource::ExternalXtal => {
42 // Datasheet says this is likely to take 0.36ms
43 r.events_hfclkstarted.write(|w| unsafe { w.bits(0) });
44 r.tasks_hfclkstart.write(|w| unsafe { w.bits(1) });
45 while r.events_hfclkstarted.read().bits() == 0 {}
46 }
47 }
48
49 // Configure LFCLK.
50 match config.lfclk_source {
51 LfclkSource::InternalRC => r.lfclksrc.write(|w| w.src().rc()),
52 LfclkSource::Synthesized => r.lfclksrc.write(|w| w.src().synth()),
53
54 LfclkSource::ExternalXtal => r.lfclksrc.write(move |w| w.src().xtal()),
55
56 LfclkSource::ExternalLowSwing => r.lfclksrc.write(move |w| {
57 w.src().xtal();
58 w.external().enabled();
59 w.bypass().disabled();
60 w
61 }),
62 LfclkSource::ExternalFullSwing => r.lfclksrc.write(move |w| {
63 w.src().xtal();
64 w.external().enabled();
65 w.bypass().enabled();
66 w
67 }),
68 }
69
70 // Start LFCLK.
71 // Datasheet says this could take 100us from synth source
72 // 600us from rc source, 0.25s from an external source.
73 r.events_lfclkstarted.write(|w| unsafe { w.bits(0) });
74 r.tasks_lfclkstart.write(|w| unsafe { w.bits(1) });
75 while r.events_lfclkstarted.read().bits() == 0 {}
76
77 // Init GPIOTE
78 crate::gpiote::init();
79}
diff --git a/embassy-rp-examples/src/bin/blinky.rs b/embassy-rp-examples/src/bin/blinky.rs
index 34e3cafc3..e42999912 100644
--- a/embassy-rp-examples/src/bin/blinky.rs
+++ b/embassy-rp-examples/src/bin/blinky.rs
@@ -16,9 +16,7 @@ use embedded_hal::digital::v2::OutputPin;
16use gpio::{Level, Output}; 16use gpio::{Level, Output};
17 17
18#[embassy::main] 18#[embassy::main]
19async fn main(_spawner: Spawner) { 19async fn main(_spawner: Spawner, p: Peripherals) {
20 let p = unwrap!(Peripherals::take());
21
22 let mut led = Output::new(p.PIN_25, Level::Low); 20 let mut led = Output::new(p.PIN_25, Level::Low);
23 21
24 loop { 22 loop {
diff --git a/embassy-rp-examples/src/bin/button.rs b/embassy-rp-examples/src/bin/button.rs
index 77d4c57a9..007d07a36 100644
--- a/embassy-rp-examples/src/bin/button.rs
+++ b/embassy-rp-examples/src/bin/button.rs
@@ -16,9 +16,7 @@ use embassy_rp::Peripherals;
16use embedded_hal::digital::v2::{InputPin, OutputPin}; 16use embedded_hal::digital::v2::{InputPin, OutputPin};
17 17
18#[embassy::main] 18#[embassy::main]
19async fn main(_spawner: Spawner) { 19async fn main(_spawner: Spawner, p: Peripherals) {
20 let p = unwrap!(Peripherals::take());
21
22 let button = Input::new(p.PIN_28, Pull::Up); 20 let button = Input::new(p.PIN_28, Pull::Up);
23 let mut led = Output::new(p.PIN_25, Level::Low); 21 let mut led = Output::new(p.PIN_25, Level::Low);
24 22
diff --git a/embassy-rp-examples/src/bin/uart.rs b/embassy-rp-examples/src/bin/uart.rs
index cd72d5312..82bd4cb6a 100644
--- a/embassy-rp-examples/src/bin/uart.rs
+++ b/embassy-rp-examples/src/bin/uart.rs
@@ -14,9 +14,7 @@ use embassy::executor::Spawner;
14use embassy_rp::{uart, Peripherals}; 14use embassy_rp::{uart, Peripherals};
15 15
16#[embassy::main] 16#[embassy::main]
17async fn main(_spanwer: Spawner) { 17async fn main(_spawner: Spawner, p: Peripherals) {
18 let p = unwrap!(Peripherals::take());
19
20 let config = uart::Config::default(); 18 let config = uart::Config::default();
21 let mut uart = uart::Uart::new(p.UART0, p.PIN_0, p.PIN_1, p.PIN_2, p.PIN_3, config); 19 let mut uart = uart::Uart::new(p.UART0, p.PIN_0, p.PIN_1, p.PIN_2, p.PIN_3, config);
22 uart.send("Hello World!\r\n".as_bytes()); 20 uart.send("Hello World!\r\n".as_bytes());
diff --git a/embassy-rp/src/lib.rs b/embassy-rp/src/lib.rs
index f64464d13..f1a045987 100644
--- a/embassy-rp/src/lib.rs
+++ b/embassy-rp/src/lib.rs
@@ -15,7 +15,6 @@ pub mod dma;
15pub mod gpio; 15pub mod gpio;
16pub mod pll; 16pub mod pll;
17pub mod resets; 17pub mod resets;
18pub mod system;
19pub mod uart; 18pub mod uart;
20 19
21embassy_extras::peripherals! { 20embassy_extras::peripherals! {
@@ -72,3 +71,105 @@ embassy_extras::peripherals! {
72 DMA_CH10, 71 DMA_CH10,
73 DMA_CH11, 72 DMA_CH11,
74} 73}
74
75#[link_section = ".boot2"]
76#[used]
77static BOOT2: [u8; 256] = *include_bytes!("boot2.bin");
78
79pub mod config {
80 #[non_exhaustive]
81 pub struct Config {}
82
83 impl Default for Config {
84 fn default() -> Self {
85 Self {}
86 }
87 }
88}
89
90pub fn init(config: config::Config) -> Peripherals {
91 // Do this first, so that it panics if user is calling `init` a second time
92 // before doing anything important.
93 let peripherals = Peripherals::take();
94
95 // Now reset all the peripherals, except QSPI and XIP (we're using those
96 // to execute from external flash!)
97
98 let resets = resets::Resets::new();
99
100 // Reset everything except:
101 // - QSPI (we're using it to run this code!)
102 // - PLLs (it may be suicide if that's what's clocking us)
103 let mut peris = resets::ALL_PERIPHERALS;
104 peris.set_io_qspi(false);
105 peris.set_pads_qspi(false);
106 peris.set_pll_sys(false);
107 peris.set_pll_usb(false);
108 resets.reset(peris);
109
110 let mut peris = resets::ALL_PERIPHERALS;
111 peris.set_adc(false);
112 peris.set_rtc(false);
113 peris.set_spi0(false);
114 peris.set_spi1(false);
115 peris.set_uart0(false);
116 peris.set_uart1(false);
117 peris.set_usbctrl(false);
118 resets.unreset_wait(peris);
119
120 unsafe {
121 // xosc 12 mhz
122 pac::WATCHDOG.tick().write(|w| {
123 w.set_cycles(XOSC_MHZ as u16);
124 w.set_enable(true);
125 });
126
127 pac::CLOCKS
128 .clk_sys_resus_ctrl()
129 .write_value(pac::clocks::regs::ClkSysResusCtrl(0));
130
131 // Enable XOSC
132 // TODO extract to HAL module
133 const XOSC_MHZ: u32 = 12;
134 pac::XOSC
135 .ctrl()
136 .write(|w| w.set_freq_range(pac::xosc::vals::CtrlFreqRange::_1_15MHZ));
137
138 let startup_delay = (((XOSC_MHZ * 1_000_000) / 1000) + 128) / 256;
139 pac::XOSC
140 .startup()
141 .write(|w| w.set_delay(startup_delay as u16));
142 pac::XOSC.ctrl().write(|w| {
143 w.set_freq_range(pac::xosc::vals::CtrlFreqRange::_1_15MHZ);
144 w.set_enable(pac::xosc::vals::CtrlEnable::ENABLE);
145 });
146 while !pac::XOSC.status().read().stable() {}
147
148 // Before we touch PLLs, switch sys and ref cleanly away from their aux sources.
149 pac::CLOCKS
150 .clk_sys_ctrl()
151 .modify(|w| w.set_src(pac::clocks::vals::ClkSysCtrlSrc::CLK_REF));
152 while pac::CLOCKS.clk_sys_selected().read() != 1 {}
153 pac::CLOCKS
154 .clk_ref_ctrl()
155 .modify(|w| w.set_src(pac::clocks::vals::ClkRefCtrlSrc::ROSC_CLKSRC_PH));
156 while pac::CLOCKS.clk_ref_selected().read() != 1 {}
157
158 let mut peris = resets::Peripherals(0);
159 peris.set_pll_sys(true);
160 peris.set_pll_usb(true);
161 resets.reset(peris);
162 resets.unreset_wait(peris);
163
164 pll::PLL::new(pll::PllSys).configure(1, 1500_000_000, 6, 2);
165 pll::PLL::new(pll::PllUsb).configure(1, 480_000_000, 5, 2);
166
167 // Activate peripheral clock and take external oscillator as input
168 pac::CLOCKS.clk_peri_ctrl().write(|w| {
169 w.set_enable(true);
170 w.set_auxsrc(pac::clocks::vals::ClkPeriCtrlAuxsrc::XOSC_CLKSRC);
171 });
172 }
173
174 peripherals
175}
diff --git a/embassy-rp/src/system.rs b/embassy-rp/src/system.rs
deleted file mode 100644
index ba1396433..000000000
--- a/embassy-rp/src/system.rs
+++ /dev/null
@@ -1,94 +0,0 @@
1use crate::{pac, pll, resets};
2
3#[link_section = ".boot2"]
4#[used]
5pub static BOOT2: [u8; 256] = *include_bytes!("boot2.bin");
6
7#[non_exhaustive]
8pub struct Config {}
9
10impl Default for Config {
11 fn default() -> Self {
12 Self {}
13 }
14}
15
16/// safety: must only call once.
17pub unsafe fn configure(_config: Config) {
18 // Now reset all the peripherals, except QSPI and XIP (we're using those
19 // to execute from external flash!)
20
21 let resets = resets::Resets::new();
22
23 // Reset everything except:
24 // - QSPI (we're using it to run this code!)
25 // - PLLs (it may be suicide if that's what's clocking us)
26 let mut peris = resets::ALL_PERIPHERALS;
27 peris.set_io_qspi(false);
28 peris.set_pads_qspi(false);
29 peris.set_pll_sys(false);
30 peris.set_pll_usb(false);
31 resets.reset(peris);
32
33 let mut peris = resets::ALL_PERIPHERALS;
34 peris.set_adc(false);
35 peris.set_rtc(false);
36 peris.set_spi0(false);
37 peris.set_spi1(false);
38 peris.set_uart0(false);
39 peris.set_uart1(false);
40 peris.set_usbctrl(false);
41 resets.unreset_wait(peris);
42
43 // xosc 12 mhz
44 pac::WATCHDOG.tick().write(|w| {
45 w.set_cycles(XOSC_MHZ as u16);
46 w.set_enable(true);
47 });
48
49 pac::CLOCKS
50 .clk_sys_resus_ctrl()
51 .write_value(pac::clocks::regs::ClkSysResusCtrl(0));
52
53 // Enable XOSC
54 // TODO extract to HAL module
55 const XOSC_MHZ: u32 = 12;
56 pac::XOSC
57 .ctrl()
58 .write(|w| w.set_freq_range(pac::xosc::vals::CtrlFreqRange::_1_15MHZ));
59
60 let startup_delay = (((XOSC_MHZ * 1_000_000) / 1000) + 128) / 256;
61 pac::XOSC
62 .startup()
63 .write(|w| w.set_delay(startup_delay as u16));
64 pac::XOSC.ctrl().write(|w| {
65 w.set_freq_range(pac::xosc::vals::CtrlFreqRange::_1_15MHZ);
66 w.set_enable(pac::xosc::vals::CtrlEnable::ENABLE);
67 });
68 while !pac::XOSC.status().read().stable() {}
69
70 // Before we touch PLLs, switch sys and ref cleanly away from their aux sources.
71 pac::CLOCKS
72 .clk_sys_ctrl()
73 .modify(|w| w.set_src(pac::clocks::vals::ClkSysCtrlSrc::CLK_REF));
74 while pac::CLOCKS.clk_sys_selected().read() != 1 {}
75 pac::CLOCKS
76 .clk_ref_ctrl()
77 .modify(|w| w.set_src(pac::clocks::vals::ClkRefCtrlSrc::ROSC_CLKSRC_PH));
78 while pac::CLOCKS.clk_ref_selected().read() != 1 {}
79
80 let mut peris = resets::Peripherals(0);
81 peris.set_pll_sys(true);
82 peris.set_pll_usb(true);
83 resets.reset(peris);
84 resets.unreset_wait(peris);
85
86 pll::PLL::new(pll::PllSys).configure(1, 1500_000_000, 6, 2);
87 pll::PLL::new(pll::PllUsb).configure(1, 480_000_000, 5, 2);
88
89 // Activate peripheral clock and take external oscillator as input
90 pac::CLOCKS.clk_peri_ctrl().write(|w| {
91 w.set_enable(true);
92 w.set_auxsrc(pac::clocks::vals::ClkPeriCtrlAuxsrc::XOSC_CLKSRC);
93 });
94}