diff options
| author | Dario Nieuwenhuis <[email protected]> | 2021-05-12 01:57:01 +0200 |
|---|---|---|
| committer | Dario Nieuwenhuis <[email protected]> | 2021-05-17 00:57:37 +0200 |
| commit | 0310e4d458b86df31f1765104eb3aa9a6ee09bfc (patch) | |
| tree | aca167ae6e37442cafc932b3c729e37082d23b04 | |
| parent | bfc7f52e6dd7b5ad12fa1f09483fa60f2732ae0c (diff) | |
Add `init` fn. Initializes hw and returns Peripherals.
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; | |||
| 17 | use embedded_hal::digital::v2::OutputPin; | 17 | use embedded_hal::digital::v2::OutputPin; |
| 18 | 18 | ||
| 19 | #[embassy::main] | 19 | #[embassy::main] |
| 20 | async fn main(spawner: Spawner) { | 20 | async 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::*; | |||
| 17 | use futures::pin_mut; | 17 | use futures::pin_mut; |
| 18 | 18 | ||
| 19 | #[embassy::main] | 19 | #[embassy::main] |
| 20 | async fn main(spawner: Spawner) { | 20 | async 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; | |||
| 13 | use defmt::panic; | 13 | use defmt::panic; |
| 14 | use embassy::executor::Spawner; | 14 | use embassy::executor::Spawner; |
| 15 | use embassy::time::{Duration, Instant, Timer}; | 15 | use embassy::time::{Duration, Instant, Timer}; |
| 16 | use embassy_nrf::interrupt; | 16 | use embassy_nrf::{interrupt, Peripherals}; |
| 17 | 17 | ||
| 18 | #[embassy::task] | 18 | #[embassy::task] |
| 19 | async fn run1() { | 19 | async fn run1() { |
| @@ -40,7 +40,7 @@ async fn run3() { | |||
| 40 | } | 40 | } |
| 41 | 41 | ||
| 42 | #[embassy::main] | 42 | #[embassy::main] |
| 43 | async fn main(spawner: Spawner) { | 43 | async 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::*; | |||
| 12 | use defmt::panic; | 12 | use defmt::panic; |
| 13 | use embassy::executor::Spawner; | 13 | use embassy::executor::Spawner; |
| 14 | use embassy_nrf::gpio::{Input, Pull}; | 14 | use embassy_nrf::gpio::{Input, Pull}; |
| 15 | use embassy_nrf::gpiote::{self, InputChannel, InputChannelPolarity}; | 15 | use embassy_nrf::gpiote::{InputChannel, InputChannelPolarity}; |
| 16 | use embassy_nrf::{interrupt, Peripherals}; | 16 | use embassy_nrf::{interrupt, Peripherals}; |
| 17 | 17 | ||
| 18 | #[embassy::main] | 18 | #[embassy::main] |
| 19 | async fn main(spawner: Spawner) { | 19 | async 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] |
| 31 | async fn main(spawner: Spawner) { | 31 | async 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(); | |||
| 126 | fn main() -> ! { | 126 | fn 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}; | |||
| 19 | use gpiote::{OutputChannel, OutputChannelPolarity}; | 19 | use gpiote::{OutputChannel, OutputChannelPolarity}; |
| 20 | 20 | ||
| 21 | #[embassy::main] | 21 | #[embassy::main] |
| 22 | async fn main(spawner: Spawner) { | 22 | async 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; | |||
| 23 | struct AlignedBuf([u8; 4096]); | 23 | struct AlignedBuf([u8; 4096]); |
| 24 | 24 | ||
| 25 | #[embassy::main] | 25 | #[embassy::main] |
| 26 | async fn main(spawner: Spawner) { | 26 | async 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(); | |||
| 37 | fn main() -> ! { | 37 | fn 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::*; | |||
| 19 | use example_common::*; | 19 | use example_common::*; |
| 20 | 20 | ||
| 21 | #[embassy::main] | 21 | #[embassy::main] |
| 22 | async fn main(spawner: Spawner) { | 22 | async 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"] |
| 9 | mod example_common; | 9 | mod example_common; |
| 10 | use embassy_nrf::Peripherals; | ||
| 10 | use example_common::*; | 11 | use example_common::*; |
| 11 | 12 | ||
| 12 | use defmt::panic; | 13 | use defmt::panic; |
| @@ -30,7 +31,7 @@ async fn run2() { | |||
| 30 | } | 31 | } |
| 31 | 32 | ||
| 32 | #[embassy::main] | 33 | #[embassy::main] |
| 33 | async fn main(spawner: Spawner) { | 34 | async 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; | |||
| 17 | use embassy_nrf::{interrupt, uarte, Peripherals}; | 17 | use embassy_nrf::{interrupt, uarte, Peripherals}; |
| 18 | 18 | ||
| 19 | #[embassy::main] | 19 | #[embassy::main] |
| 20 | async fn main(spawner: Spawner) { | 20 | async 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; | |||
| 18 | use embassy_nrf::{interrupt, uarte, Peripherals}; | 18 | use embassy_nrf::{interrupt, uarte, Peripherals}; |
| 19 | 19 | ||
| 20 | #[embassy::main] | 20 | #[embassy::main] |
| 21 | async fn main(spawner: Spawner) { | 21 | async 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"))] |
| 36 | pub mod saadc; | 36 | pub mod saadc; |
| 37 | pub mod spim; | 37 | pub mod spim; |
| 38 | pub mod system; | ||
| 39 | pub mod timer; | 38 | pub mod timer; |
| 40 | pub mod twim; | 39 | pub mod twim; |
| 41 | pub mod uarte; | 40 | pub 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 | } |
| 75 | pub use embassy_macros::interrupt; | 74 | pub use embassy_macros::interrupt; |
| 75 | |||
| 76 | pub 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 | |||
| 109 | pub 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 @@ | |||
| 1 | use crate::pac; | ||
| 2 | |||
| 3 | pub enum HfclkSource { | ||
| 4 | Internal, | ||
| 5 | ExternalXtal, | ||
| 6 | } | ||
| 7 | |||
| 8 | pub enum LfclkSource { | ||
| 9 | InternalRC, | ||
| 10 | Synthesized, | ||
| 11 | ExternalXtal, | ||
| 12 | ExternalLowSwing, | ||
| 13 | ExternalFullSwing, | ||
| 14 | } | ||
| 15 | |||
| 16 | #[non_exhaustive] | ||
| 17 | pub struct Config { | ||
| 18 | pub hfclk_source: HfclkSource, | ||
| 19 | pub lfclk_source: LfclkSource, | ||
| 20 | } | ||
| 21 | |||
| 22 | impl 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. | ||
| 35 | pub 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; | |||
| 16 | use gpio::{Level, Output}; | 16 | use gpio::{Level, Output}; |
| 17 | 17 | ||
| 18 | #[embassy::main] | 18 | #[embassy::main] |
| 19 | async fn main(_spawner: Spawner) { | 19 | async 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; | |||
| 16 | use embedded_hal::digital::v2::{InputPin, OutputPin}; | 16 | use embedded_hal::digital::v2::{InputPin, OutputPin}; |
| 17 | 17 | ||
| 18 | #[embassy::main] | 18 | #[embassy::main] |
| 19 | async fn main(_spawner: Spawner) { | 19 | async 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; | |||
| 14 | use embassy_rp::{uart, Peripherals}; | 14 | use embassy_rp::{uart, Peripherals}; |
| 15 | 15 | ||
| 16 | #[embassy::main] | 16 | #[embassy::main] |
| 17 | async fn main(_spanwer: Spawner) { | 17 | async 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; | |||
| 15 | pub mod gpio; | 15 | pub mod gpio; |
| 16 | pub mod pll; | 16 | pub mod pll; |
| 17 | pub mod resets; | 17 | pub mod resets; |
| 18 | pub mod system; | ||
| 19 | pub mod uart; | 18 | pub mod uart; |
| 20 | 19 | ||
| 21 | embassy_extras::peripherals! { | 20 | embassy_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] | ||
| 77 | static BOOT2: [u8; 256] = *include_bytes!("boot2.bin"); | ||
| 78 | |||
| 79 | pub 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 | |||
| 90 | pub 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 @@ | |||
| 1 | use crate::{pac, pll, resets}; | ||
| 2 | |||
| 3 | #[link_section = ".boot2"] | ||
| 4 | #[used] | ||
| 5 | pub static BOOT2: [u8; 256] = *include_bytes!("boot2.bin"); | ||
| 6 | |||
| 7 | #[non_exhaustive] | ||
| 8 | pub struct Config {} | ||
| 9 | |||
| 10 | impl Default for Config { | ||
| 11 | fn default() -> Self { | ||
| 12 | Self {} | ||
| 13 | } | ||
| 14 | } | ||
| 15 | |||
| 16 | /// safety: must only call once. | ||
| 17 | pub 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 | } | ||
