Add init fn. Initializes hw and returns Peripherals.
				
					
				
			This commit is contained in:
		@@ -46,18 +46,17 @@ macro_rules! peripherals {
 | 
				
			|||||||
        impl Peripherals {
 | 
					        impl Peripherals {
 | 
				
			||||||
            ///Returns all the peripherals *once*
 | 
					            ///Returns all the peripherals *once*
 | 
				
			||||||
            #[inline]
 | 
					            #[inline]
 | 
				
			||||||
            pub fn take() -> Option<Self> {
 | 
					            pub(crate) fn take() -> Self {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                #[no_mangle]
 | 
					                #[no_mangle]
 | 
				
			||||||
                static mut _EMBASSY_DEVICE_PERIPHERALS: bool = false;
 | 
					                static mut _EMBASSY_DEVICE_PERIPHERALS: bool = false;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                critical_section::with(|_| {
 | 
					                critical_section::with(|_| unsafe {
 | 
				
			||||||
                    if unsafe { _EMBASSY_DEVICE_PERIPHERALS } {
 | 
					                    if _EMBASSY_DEVICE_PERIPHERALS {
 | 
				
			||||||
                        None
 | 
					                        panic!("init called more than once!")
 | 
				
			||||||
                    } else {
 | 
					 | 
				
			||||||
                        unsafe { _EMBASSY_DEVICE_PERIPHERALS = true };
 | 
					 | 
				
			||||||
                        Some(unsafe { <Self as embassy::util::Steal>::steal() })
 | 
					 | 
				
			||||||
                    }
 | 
					                    }
 | 
				
			||||||
 | 
					                    _EMBASSY_DEVICE_PERIPHERALS = true;
 | 
				
			||||||
 | 
					                    <Self as embassy::util::Steal>::steal()
 | 
				
			||||||
                })
 | 
					                })
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -9,7 +9,7 @@ pub fn generate(embassy_prefix: &ModulePrefix, config: syn::Expr) -> TokenStream
 | 
				
			|||||||
    quote!(
 | 
					    quote!(
 | 
				
			||||||
        use #embassy_nrf_path::{interrupt, peripherals, rtc};
 | 
					        use #embassy_nrf_path::{interrupt, peripherals, rtc};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        unsafe { #embassy_nrf_path::system::configure(#config) };
 | 
					        let p = #embassy_nrf_path::init(#config);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        let mut rtc = rtc::RTC::new(unsafe { <peripherals::RTC1 as #embassy_path::util::Steal>::steal() }, interrupt::take!(RTC1));
 | 
					        let mut rtc = rtc::RTC::new(unsafe { <peripherals::RTC1 as #embassy_path::util::Steal>::steal() }, interrupt::take!(RTC1));
 | 
				
			||||||
        let rtc = unsafe { make_static(&mut rtc) };
 | 
					        let rtc = unsafe { make_static(&mut rtc) };
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -7,6 +7,6 @@ pub fn generate(embassy_prefix: &ModulePrefix, config: syn::Expr) -> TokenStream
 | 
				
			|||||||
    quote!(
 | 
					    quote!(
 | 
				
			||||||
        use #embassy_rp_path::{interrupt, peripherals};
 | 
					        use #embassy_rp_path::{interrupt, peripherals};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        unsafe { #embassy_rp_path::system::configure(#config) };
 | 
					        let p = #embassy_rp_path::init(#config);
 | 
				
			||||||
    )
 | 
					    )
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -315,12 +315,12 @@ pub fn main(args: TokenStream, item: TokenStream) -> TokenStream {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    let args = task_fn.sig.inputs.clone();
 | 
					    let args = task_fn.sig.inputs.clone();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if args.len() != 1 {
 | 
					    if args.len() != 2 {
 | 
				
			||||||
        task_fn
 | 
					        task_fn
 | 
				
			||||||
            .sig
 | 
					            .sig
 | 
				
			||||||
            .span()
 | 
					            .span()
 | 
				
			||||||
            .unwrap()
 | 
					            .unwrap()
 | 
				
			||||||
            .error("main function must have one argument")
 | 
					            .error("main function must have 2 arguments")
 | 
				
			||||||
            .emit();
 | 
					            .emit();
 | 
				
			||||||
        fail = true;
 | 
					        fail = true;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
@@ -364,7 +364,7 @@ pub fn main(args: TokenStream, item: TokenStream) -> TokenStream {
 | 
				
			|||||||
            #chip_setup
 | 
					            #chip_setup
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            executor.run(|spawner| {
 | 
					            executor.run(|spawner| {
 | 
				
			||||||
                spawner.spawn(__embassy_main(spawner)).unwrap();
 | 
					                spawner.spawn(__embassy_main(spawner, p)).unwrap();
 | 
				
			||||||
            })
 | 
					            })
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -17,8 +17,7 @@ use embassy_nrf::Peripherals;
 | 
				
			|||||||
use embedded_hal::digital::v2::OutputPin;
 | 
					use embedded_hal::digital::v2::OutputPin;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#[embassy::main]
 | 
					#[embassy::main]
 | 
				
			||||||
async fn main(spawner: Spawner) {
 | 
					async fn main(spawner: Spawner, p: Peripherals) {
 | 
				
			||||||
    let p = Peripherals::take().unwrap();
 | 
					 | 
				
			||||||
    let mut led = Output::new(p.P0_13, Level::Low, OutputDrive::Standard);
 | 
					    let mut led = Output::new(p.P0_13, Level::Low, OutputDrive::Standard);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    loop {
 | 
					    loop {
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -17,9 +17,7 @@ use example_common::*;
 | 
				
			|||||||
use futures::pin_mut;
 | 
					use futures::pin_mut;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#[embassy::main]
 | 
					#[embassy::main]
 | 
				
			||||||
async fn main(spawner: Spawner) {
 | 
					async fn main(spawner: Spawner, p: Peripherals) {
 | 
				
			||||||
    let p = Peripherals::take().unwrap();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    let mut config = uarte::Config::default();
 | 
					    let mut config = uarte::Config::default();
 | 
				
			||||||
    config.parity = uarte::Parity::EXCLUDED;
 | 
					    config.parity = uarte::Parity::EXCLUDED;
 | 
				
			||||||
    config.baudrate = uarte::Baudrate::BAUD115200;
 | 
					    config.baudrate = uarte::Baudrate::BAUD115200;
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -13,7 +13,7 @@ use core::task::Poll;
 | 
				
			|||||||
use defmt::panic;
 | 
					use defmt::panic;
 | 
				
			||||||
use embassy::executor::Spawner;
 | 
					use embassy::executor::Spawner;
 | 
				
			||||||
use embassy::time::{Duration, Instant, Timer};
 | 
					use embassy::time::{Duration, Instant, Timer};
 | 
				
			||||||
use embassy_nrf::interrupt;
 | 
					use embassy_nrf::{interrupt, Peripherals};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#[embassy::task]
 | 
					#[embassy::task]
 | 
				
			||||||
async fn run1() {
 | 
					async fn run1() {
 | 
				
			||||||
@@ -40,7 +40,7 @@ async fn run3() {
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#[embassy::main]
 | 
					#[embassy::main]
 | 
				
			||||||
async fn main(spawner: Spawner) {
 | 
					async fn main(spawner: Spawner, p: Peripherals) {
 | 
				
			||||||
    unwrap!(spawner.spawn(run1()));
 | 
					    unwrap!(spawner.spawn(run1()));
 | 
				
			||||||
    unwrap!(spawner.spawn(run2()));
 | 
					    unwrap!(spawner.spawn(run2()));
 | 
				
			||||||
    unwrap!(spawner.spawn(run3()));
 | 
					    unwrap!(spawner.spawn(run3()));
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -12,13 +12,11 @@ use example_common::*;
 | 
				
			|||||||
use defmt::panic;
 | 
					use defmt::panic;
 | 
				
			||||||
use embassy::executor::Spawner;
 | 
					use embassy::executor::Spawner;
 | 
				
			||||||
use embassy_nrf::gpio::{Input, Pull};
 | 
					use embassy_nrf::gpio::{Input, Pull};
 | 
				
			||||||
use embassy_nrf::gpiote::{self, InputChannel, InputChannelPolarity};
 | 
					use embassy_nrf::gpiote::{InputChannel, InputChannelPolarity};
 | 
				
			||||||
use embassy_nrf::{interrupt, Peripherals};
 | 
					use embassy_nrf::{interrupt, Peripherals};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#[embassy::main]
 | 
					#[embassy::main]
 | 
				
			||||||
async fn main(spawner: Spawner) {
 | 
					async fn main(spawner: Spawner, p: Peripherals) {
 | 
				
			||||||
    let p = Peripherals::take().unwrap();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    info!("Starting!");
 | 
					    info!("Starting!");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    let ch1 = InputChannel::new(
 | 
					    let ch1 = InputChannel::new(
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -28,9 +28,7 @@ async fn button_task(n: usize, mut pin: PortInput<'static, AnyPin>) {
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#[embassy::main]
 | 
					#[embassy::main]
 | 
				
			||||||
async fn main(spawner: Spawner) {
 | 
					async fn main(spawner: Spawner, p: Peripherals) {
 | 
				
			||||||
    let p = Peripherals::take().unwrap();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    info!("Starting!");
 | 
					    info!("Starting!");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    let btn1 = PortInput::new(Input::new(p.P0_11.degrade(), Pull::Up));
 | 
					    let btn1 = PortInput::new(Input::new(p.P0_11.degrade(), Pull::Up));
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -126,9 +126,8 @@ static EXECUTOR_LOW: Forever<Executor> = Forever::new();
 | 
				
			|||||||
fn main() -> ! {
 | 
					fn main() -> ! {
 | 
				
			||||||
    info!("Hello World!");
 | 
					    info!("Hello World!");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    let p = unwrap!(embassy_nrf::Peripherals::take());
 | 
					    let p = embassy_nrf::init(Default::default());
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    unsafe { embassy_nrf::system::configure(Default::default()) };
 | 
					 | 
				
			||||||
    let rtc = RTC.put(rtc::RTC::new(p.RTC1, interrupt::take!(RTC1)));
 | 
					    let rtc = RTC.put(rtc::RTC::new(p.RTC1, interrupt::take!(RTC1)));
 | 
				
			||||||
    rtc.start();
 | 
					    rtc.start();
 | 
				
			||||||
    unsafe { embassy::time::set_clock(rtc) };
 | 
					    unsafe { embassy::time::set_clock(rtc) };
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -19,9 +19,7 @@ use embassy_nrf::{interrupt, Peripherals};
 | 
				
			|||||||
use gpiote::{OutputChannel, OutputChannelPolarity};
 | 
					use gpiote::{OutputChannel, OutputChannelPolarity};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#[embassy::main]
 | 
					#[embassy::main]
 | 
				
			||||||
async fn main(spawner: Spawner) {
 | 
					async fn main(spawner: Spawner, p: Peripherals) {
 | 
				
			||||||
    let p = Peripherals::take().unwrap();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    info!("Starting!");
 | 
					    info!("Starting!");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    let button1 = InputChannel::new(
 | 
					    let button1 = InputChannel::new(
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -23,9 +23,7 @@ const PAGE_SIZE: usize = 4096;
 | 
				
			|||||||
struct AlignedBuf([u8; 4096]);
 | 
					struct AlignedBuf([u8; 4096]);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#[embassy::main]
 | 
					#[embassy::main]
 | 
				
			||||||
async fn main(spawner: Spawner) {
 | 
					async fn main(spawner: Spawner, p: Peripherals) {
 | 
				
			||||||
    let p = Peripherals::take().unwrap();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    let csn = p.P0_17;
 | 
					    let csn = p.P0_17;
 | 
				
			||||||
    let sck = p.P0_19;
 | 
					    let sck = p.P0_19;
 | 
				
			||||||
    let io0 = p.P0_20;
 | 
					    let io0 = p.P0_20;
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -37,9 +37,8 @@ static EXECUTOR: Forever<Executor> = Forever::new();
 | 
				
			|||||||
fn main() -> ! {
 | 
					fn main() -> ! {
 | 
				
			||||||
    info!("Hello World!");
 | 
					    info!("Hello World!");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    let p = unwrap!(embassy_nrf::Peripherals::take());
 | 
					    let p = embassy_nrf::init(Default::default());
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    unsafe { embassy_nrf::system::configure(Default::default()) };
 | 
					 | 
				
			||||||
    let rtc = RTC.put(rtc::RTC::new(p.RTC1, interrupt::take!(RTC1)));
 | 
					    let rtc = RTC.put(rtc::RTC::new(p.RTC1, interrupt::take!(RTC1)));
 | 
				
			||||||
    rtc.start();
 | 
					    rtc.start();
 | 
				
			||||||
    unsafe { embassy::time::set_clock(rtc) };
 | 
					    unsafe { embassy::time::set_clock(rtc) };
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -19,11 +19,9 @@ use embedded_hal::digital::v2::*;
 | 
				
			|||||||
use example_common::*;
 | 
					use example_common::*;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#[embassy::main]
 | 
					#[embassy::main]
 | 
				
			||||||
async fn main(spawner: Spawner) {
 | 
					async fn main(spawner: Spawner, p: Peripherals) {
 | 
				
			||||||
    info!("running!");
 | 
					    info!("running!");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    let p = unsafe { Peripherals::steal() };
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    let mut config = spim::Config::default();
 | 
					    let mut config = spim::Config::default();
 | 
				
			||||||
    config.frequency = spim::Frequency::M16;
 | 
					    config.frequency = spim::Frequency::M16;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -7,6 +7,7 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
#[path = "../example_common.rs"]
 | 
					#[path = "../example_common.rs"]
 | 
				
			||||||
mod example_common;
 | 
					mod example_common;
 | 
				
			||||||
 | 
					use embassy_nrf::Peripherals;
 | 
				
			||||||
use example_common::*;
 | 
					use example_common::*;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
use defmt::panic;
 | 
					use defmt::panic;
 | 
				
			||||||
@@ -30,7 +31,7 @@ async fn run2() {
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#[embassy::main]
 | 
					#[embassy::main]
 | 
				
			||||||
async fn main(spawner: Spawner) {
 | 
					async fn main(spawner: Spawner, p: Peripherals) {
 | 
				
			||||||
    unwrap!(spawner.spawn(run1()));
 | 
					    unwrap!(spawner.spawn(run1()));
 | 
				
			||||||
    unwrap!(spawner.spawn(run2()));
 | 
					    unwrap!(spawner.spawn(run2()));
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -17,9 +17,7 @@ use embassy_nrf::gpio::NoPin;
 | 
				
			|||||||
use embassy_nrf::{interrupt, uarte, Peripherals};
 | 
					use embassy_nrf::{interrupt, uarte, Peripherals};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#[embassy::main]
 | 
					#[embassy::main]
 | 
				
			||||||
async fn main(spawner: Spawner) {
 | 
					async fn main(spawner: Spawner, p: Peripherals) {
 | 
				
			||||||
    let p = unsafe { Peripherals::steal() };
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    let mut config = uarte::Config::default();
 | 
					    let mut config = uarte::Config::default();
 | 
				
			||||||
    config.parity = uarte::Parity::EXCLUDED;
 | 
					    config.parity = uarte::Parity::EXCLUDED;
 | 
				
			||||||
    config.baudrate = uarte::Baudrate::BAUD115200;
 | 
					    config.baudrate = uarte::Baudrate::BAUD115200;
 | 
				
			||||||
@@ -42,33 +40,5 @@ async fn main(spawner: Spawner) {
 | 
				
			|||||||
        unwrap!(uart.read(&mut buf).await);
 | 
					        unwrap!(uart.read(&mut buf).await);
 | 
				
			||||||
        info!("writing...");
 | 
					        info!("writing...");
 | 
				
			||||||
        unwrap!(uart.write(&buf).await);
 | 
					        unwrap!(uart.write(&buf).await);
 | 
				
			||||||
 | 
					 | 
				
			||||||
        /*
 | 
					 | 
				
			||||||
        // `receive()` doesn't return until the buffer has been completely filled with
 | 
					 | 
				
			||||||
        // incoming data, which in this case is 8 bytes.
 | 
					 | 
				
			||||||
        //
 | 
					 | 
				
			||||||
        // This example shows how to use `select` to run an uart receive concurrently with a
 | 
					 | 
				
			||||||
        // 1 second timer, effectively adding a timeout to the receive operation.
 | 
					 | 
				
			||||||
        let recv_fut = uart.read(&mut buf);
 | 
					 | 
				
			||||||
        let timer_fut = Timer::after(Duration::from_millis(1000));
 | 
					 | 
				
			||||||
        let received_len = match select(recv_fut, timer_fut).await {
 | 
					 | 
				
			||||||
            // recv_fut completed first, so we've received `buf_len` bytes.
 | 
					 | 
				
			||||||
            Either::Left(_) => buf_len,
 | 
					 | 
				
			||||||
            // timer_fut completed first. `select` gives us back the future that didn't complete, which
 | 
					 | 
				
			||||||
            // is `recv_fut` in this case, so we can do further stuff with it.
 | 
					 | 
				
			||||||
            //
 | 
					 | 
				
			||||||
            // The recv_fut would stop the uart read automatically when dropped. However, we want to know how
 | 
					 | 
				
			||||||
            // many bytes have been received, so we have to "gracefully stop" it with `.stop()`.
 | 
					 | 
				
			||||||
            Either::Right((_, recv_fut)) => recv_fut.stop().await,
 | 
					 | 
				
			||||||
        };
 | 
					 | 
				
			||||||
        let received = &mut buf[..received_len];
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        if !received.is_empty() {
 | 
					 | 
				
			||||||
            info!("read done, got {}", received);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            // Echo back received data
 | 
					 | 
				
			||||||
            unwrap!(uart.write(received).await);
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
         */
 | 
					 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -18,9 +18,7 @@ use embassy_nrf::gpio::NoPin;
 | 
				
			|||||||
use embassy_nrf::{interrupt, uarte, Peripherals};
 | 
					use embassy_nrf::{interrupt, uarte, Peripherals};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#[embassy::main]
 | 
					#[embassy::main]
 | 
				
			||||||
async fn main(spawner: Spawner) {
 | 
					async fn main(spawner: Spawner, p: Peripherals) {
 | 
				
			||||||
    let p = unsafe { Peripherals::steal() };
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    let mut config = uarte::Config::default();
 | 
					    let mut config = uarte::Config::default();
 | 
				
			||||||
    config.parity = uarte::Parity::EXCLUDED;
 | 
					    config.parity = uarte::Parity::EXCLUDED;
 | 
				
			||||||
    config.baudrate = uarte::Baudrate::BAUD115200;
 | 
					    config.baudrate = uarte::Baudrate::BAUD115200;
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -35,7 +35,6 @@ pub mod rtc;
 | 
				
			|||||||
#[cfg(not(feature = "nrf52820"))]
 | 
					#[cfg(not(feature = "nrf52820"))]
 | 
				
			||||||
pub mod saadc;
 | 
					pub mod saadc;
 | 
				
			||||||
pub mod spim;
 | 
					pub mod spim;
 | 
				
			||||||
pub mod system;
 | 
					 | 
				
			||||||
pub mod timer;
 | 
					pub mod timer;
 | 
				
			||||||
pub mod twim;
 | 
					pub mod twim;
 | 
				
			||||||
pub mod uarte;
 | 
					pub mod uarte;
 | 
				
			||||||
@@ -73,3 +72,88 @@ pub mod interrupt {
 | 
				
			|||||||
    pub use embassy_extras::interrupt::Priority3 as Priority;
 | 
					    pub use embassy_extras::interrupt::Priority3 as Priority;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
pub use embassy_macros::interrupt;
 | 
					pub use embassy_macros::interrupt;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					pub mod config {
 | 
				
			||||||
 | 
					    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,
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					pub fn init(config: config::Config) -> Peripherals {
 | 
				
			||||||
 | 
					    // Do this first, so that it panics if user is calling `init` a second time
 | 
				
			||||||
 | 
					    // before doing anything important.
 | 
				
			||||||
 | 
					    let peripherals = Peripherals::take();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    let r = unsafe { &*pac::CLOCK::ptr() };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // Start HFCLK.
 | 
				
			||||||
 | 
					    match config.hfclk_source {
 | 
				
			||||||
 | 
					        config::HfclkSource::Internal => {}
 | 
				
			||||||
 | 
					        config::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 {
 | 
				
			||||||
 | 
					        config::LfclkSource::InternalRC => r.lfclksrc.write(|w| w.src().rc()),
 | 
				
			||||||
 | 
					        config::LfclkSource::Synthesized => r.lfclksrc.write(|w| w.src().synth()),
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        config::LfclkSource::ExternalXtal => r.lfclksrc.write(|w| w.src().xtal()),
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        config::LfclkSource::ExternalLowSwing => r.lfclksrc.write(|w| {
 | 
				
			||||||
 | 
					            w.src().xtal();
 | 
				
			||||||
 | 
					            w.external().enabled();
 | 
				
			||||||
 | 
					            w.bypass().disabled();
 | 
				
			||||||
 | 
					            w
 | 
				
			||||||
 | 
					        }),
 | 
				
			||||||
 | 
					        config::LfclkSource::ExternalFullSwing => r.lfclksrc.write(|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 {}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // Init GPIOTE
 | 
				
			||||||
 | 
					    crate::gpiote::init();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    peripherals
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,79 +0,0 @@
 | 
				
			|||||||
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 {}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    // Init GPIOTE
 | 
					 | 
				
			||||||
    crate::gpiote::init();
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
@@ -16,9 +16,7 @@ use embedded_hal::digital::v2::OutputPin;
 | 
				
			|||||||
use gpio::{Level, Output};
 | 
					use gpio::{Level, Output};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#[embassy::main]
 | 
					#[embassy::main]
 | 
				
			||||||
async fn main(_spawner: Spawner) {
 | 
					async fn main(_spawner: Spawner, p: Peripherals) {
 | 
				
			||||||
    let p = unwrap!(Peripherals::take());
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    let mut led = Output::new(p.PIN_25, Level::Low);
 | 
					    let mut led = Output::new(p.PIN_25, Level::Low);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    loop {
 | 
					    loop {
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -16,9 +16,7 @@ use embassy_rp::Peripherals;
 | 
				
			|||||||
use embedded_hal::digital::v2::{InputPin, OutputPin};
 | 
					use embedded_hal::digital::v2::{InputPin, OutputPin};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#[embassy::main]
 | 
					#[embassy::main]
 | 
				
			||||||
async fn main(_spawner: Spawner) {
 | 
					async fn main(_spawner: Spawner, p: Peripherals) {
 | 
				
			||||||
    let p = unwrap!(Peripherals::take());
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    let button = Input::new(p.PIN_28, Pull::Up);
 | 
					    let button = Input::new(p.PIN_28, Pull::Up);
 | 
				
			||||||
    let mut led = Output::new(p.PIN_25, Level::Low);
 | 
					    let mut led = Output::new(p.PIN_25, Level::Low);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -14,9 +14,7 @@ use embassy::executor::Spawner;
 | 
				
			|||||||
use embassy_rp::{uart, Peripherals};
 | 
					use embassy_rp::{uart, Peripherals};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#[embassy::main]
 | 
					#[embassy::main]
 | 
				
			||||||
async fn main(_spanwer: Spawner) {
 | 
					async fn main(_spawner: Spawner, p: Peripherals) {
 | 
				
			||||||
    let p = unwrap!(Peripherals::take());
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    let config = uart::Config::default();
 | 
					    let config = uart::Config::default();
 | 
				
			||||||
    let mut uart = uart::Uart::new(p.UART0, p.PIN_0, p.PIN_1, p.PIN_2, p.PIN_3, config);
 | 
					    let mut uart = uart::Uart::new(p.UART0, p.PIN_0, p.PIN_1, p.PIN_2, p.PIN_3, config);
 | 
				
			||||||
    uart.send("Hello World!\r\n".as_bytes());
 | 
					    uart.send("Hello World!\r\n".as_bytes());
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -15,7 +15,6 @@ pub mod dma;
 | 
				
			|||||||
pub mod gpio;
 | 
					pub mod gpio;
 | 
				
			||||||
pub mod pll;
 | 
					pub mod pll;
 | 
				
			||||||
pub mod resets;
 | 
					pub mod resets;
 | 
				
			||||||
pub mod system;
 | 
					 | 
				
			||||||
pub mod uart;
 | 
					pub mod uart;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
embassy_extras::peripherals! {
 | 
					embassy_extras::peripherals! {
 | 
				
			||||||
@@ -72,3 +71,105 @@ embassy_extras::peripherals! {
 | 
				
			|||||||
    DMA_CH10,
 | 
					    DMA_CH10,
 | 
				
			||||||
    DMA_CH11,
 | 
					    DMA_CH11,
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#[link_section = ".boot2"]
 | 
				
			||||||
 | 
					#[used]
 | 
				
			||||||
 | 
					static BOOT2: [u8; 256] = *include_bytes!("boot2.bin");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					pub mod config {
 | 
				
			||||||
 | 
					    #[non_exhaustive]
 | 
				
			||||||
 | 
					    pub struct Config {}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    impl Default for Config {
 | 
				
			||||||
 | 
					        fn default() -> Self {
 | 
				
			||||||
 | 
					            Self {}
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					pub fn init(config: config::Config) -> Peripherals {
 | 
				
			||||||
 | 
					    // Do this first, so that it panics if user is calling `init` a second time
 | 
				
			||||||
 | 
					    // before doing anything important.
 | 
				
			||||||
 | 
					    let peripherals = Peripherals::take();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // Now reset all the peripherals, except QSPI and XIP (we're using those
 | 
				
			||||||
 | 
					    // to execute from external flash!)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    let resets = resets::Resets::new();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // Reset everything except:
 | 
				
			||||||
 | 
					    // - QSPI (we're using it to run this code!)
 | 
				
			||||||
 | 
					    // - PLLs (it may be suicide if that's what's clocking us)
 | 
				
			||||||
 | 
					    let mut peris = resets::ALL_PERIPHERALS;
 | 
				
			||||||
 | 
					    peris.set_io_qspi(false);
 | 
				
			||||||
 | 
					    peris.set_pads_qspi(false);
 | 
				
			||||||
 | 
					    peris.set_pll_sys(false);
 | 
				
			||||||
 | 
					    peris.set_pll_usb(false);
 | 
				
			||||||
 | 
					    resets.reset(peris);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    let mut peris = resets::ALL_PERIPHERALS;
 | 
				
			||||||
 | 
					    peris.set_adc(false);
 | 
				
			||||||
 | 
					    peris.set_rtc(false);
 | 
				
			||||||
 | 
					    peris.set_spi0(false);
 | 
				
			||||||
 | 
					    peris.set_spi1(false);
 | 
				
			||||||
 | 
					    peris.set_uart0(false);
 | 
				
			||||||
 | 
					    peris.set_uart1(false);
 | 
				
			||||||
 | 
					    peris.set_usbctrl(false);
 | 
				
			||||||
 | 
					    resets.unreset_wait(peris);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    unsafe {
 | 
				
			||||||
 | 
					        // xosc 12 mhz
 | 
				
			||||||
 | 
					        pac::WATCHDOG.tick().write(|w| {
 | 
				
			||||||
 | 
					            w.set_cycles(XOSC_MHZ as u16);
 | 
				
			||||||
 | 
					            w.set_enable(true);
 | 
				
			||||||
 | 
					        });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        pac::CLOCKS
 | 
				
			||||||
 | 
					            .clk_sys_resus_ctrl()
 | 
				
			||||||
 | 
					            .write_value(pac::clocks::regs::ClkSysResusCtrl(0));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        // Enable XOSC
 | 
				
			||||||
 | 
					        // TODO extract to HAL module
 | 
				
			||||||
 | 
					        const XOSC_MHZ: u32 = 12;
 | 
				
			||||||
 | 
					        pac::XOSC
 | 
				
			||||||
 | 
					            .ctrl()
 | 
				
			||||||
 | 
					            .write(|w| w.set_freq_range(pac::xosc::vals::CtrlFreqRange::_1_15MHZ));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        let startup_delay = (((XOSC_MHZ * 1_000_000) / 1000) + 128) / 256;
 | 
				
			||||||
 | 
					        pac::XOSC
 | 
				
			||||||
 | 
					            .startup()
 | 
				
			||||||
 | 
					            .write(|w| w.set_delay(startup_delay as u16));
 | 
				
			||||||
 | 
					        pac::XOSC.ctrl().write(|w| {
 | 
				
			||||||
 | 
					            w.set_freq_range(pac::xosc::vals::CtrlFreqRange::_1_15MHZ);
 | 
				
			||||||
 | 
					            w.set_enable(pac::xosc::vals::CtrlEnable::ENABLE);
 | 
				
			||||||
 | 
					        });
 | 
				
			||||||
 | 
					        while !pac::XOSC.status().read().stable() {}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        // Before we touch PLLs, switch sys and ref cleanly away from their aux sources.
 | 
				
			||||||
 | 
					        pac::CLOCKS
 | 
				
			||||||
 | 
					            .clk_sys_ctrl()
 | 
				
			||||||
 | 
					            .modify(|w| w.set_src(pac::clocks::vals::ClkSysCtrlSrc::CLK_REF));
 | 
				
			||||||
 | 
					        while pac::CLOCKS.clk_sys_selected().read() != 1 {}
 | 
				
			||||||
 | 
					        pac::CLOCKS
 | 
				
			||||||
 | 
					            .clk_ref_ctrl()
 | 
				
			||||||
 | 
					            .modify(|w| w.set_src(pac::clocks::vals::ClkRefCtrlSrc::ROSC_CLKSRC_PH));
 | 
				
			||||||
 | 
					        while pac::CLOCKS.clk_ref_selected().read() != 1 {}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        let mut peris = resets::Peripherals(0);
 | 
				
			||||||
 | 
					        peris.set_pll_sys(true);
 | 
				
			||||||
 | 
					        peris.set_pll_usb(true);
 | 
				
			||||||
 | 
					        resets.reset(peris);
 | 
				
			||||||
 | 
					        resets.unreset_wait(peris);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        pll::PLL::new(pll::PllSys).configure(1, 1500_000_000, 6, 2);
 | 
				
			||||||
 | 
					        pll::PLL::new(pll::PllUsb).configure(1, 480_000_000, 5, 2);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        // Activate peripheral clock and take external oscillator as input
 | 
				
			||||||
 | 
					        pac::CLOCKS.clk_peri_ctrl().write(|w| {
 | 
				
			||||||
 | 
					            w.set_enable(true);
 | 
				
			||||||
 | 
					            w.set_auxsrc(pac::clocks::vals::ClkPeriCtrlAuxsrc::XOSC_CLKSRC);
 | 
				
			||||||
 | 
					        });
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    peripherals
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,94 +0,0 @@
 | 
				
			|||||||
use crate::{pac, pll, resets};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#[link_section = ".boot2"]
 | 
					 | 
				
			||||||
#[used]
 | 
					 | 
				
			||||||
pub static BOOT2: [u8; 256] = *include_bytes!("boot2.bin");
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#[non_exhaustive]
 | 
					 | 
				
			||||||
pub struct Config {}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
impl Default for Config {
 | 
					 | 
				
			||||||
    fn default() -> Self {
 | 
					 | 
				
			||||||
        Self {}
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/// safety: must only call once.
 | 
					 | 
				
			||||||
pub unsafe fn configure(_config: Config) {
 | 
					 | 
				
			||||||
    // Now reset all the peripherals, except QSPI and XIP (we're using those
 | 
					 | 
				
			||||||
    // to execute from external flash!)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    let resets = resets::Resets::new();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    // Reset everything except:
 | 
					 | 
				
			||||||
    // - QSPI (we're using it to run this code!)
 | 
					 | 
				
			||||||
    // - PLLs (it may be suicide if that's what's clocking us)
 | 
					 | 
				
			||||||
    let mut peris = resets::ALL_PERIPHERALS;
 | 
					 | 
				
			||||||
    peris.set_io_qspi(false);
 | 
					 | 
				
			||||||
    peris.set_pads_qspi(false);
 | 
					 | 
				
			||||||
    peris.set_pll_sys(false);
 | 
					 | 
				
			||||||
    peris.set_pll_usb(false);
 | 
					 | 
				
			||||||
    resets.reset(peris);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    let mut peris = resets::ALL_PERIPHERALS;
 | 
					 | 
				
			||||||
    peris.set_adc(false);
 | 
					 | 
				
			||||||
    peris.set_rtc(false);
 | 
					 | 
				
			||||||
    peris.set_spi0(false);
 | 
					 | 
				
			||||||
    peris.set_spi1(false);
 | 
					 | 
				
			||||||
    peris.set_uart0(false);
 | 
					 | 
				
			||||||
    peris.set_uart1(false);
 | 
					 | 
				
			||||||
    peris.set_usbctrl(false);
 | 
					 | 
				
			||||||
    resets.unreset_wait(peris);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    // xosc 12 mhz
 | 
					 | 
				
			||||||
    pac::WATCHDOG.tick().write(|w| {
 | 
					 | 
				
			||||||
        w.set_cycles(XOSC_MHZ as u16);
 | 
					 | 
				
			||||||
        w.set_enable(true);
 | 
					 | 
				
			||||||
    });
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    pac::CLOCKS
 | 
					 | 
				
			||||||
        .clk_sys_resus_ctrl()
 | 
					 | 
				
			||||||
        .write_value(pac::clocks::regs::ClkSysResusCtrl(0));
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    // Enable XOSC
 | 
					 | 
				
			||||||
    // TODO extract to HAL module
 | 
					 | 
				
			||||||
    const XOSC_MHZ: u32 = 12;
 | 
					 | 
				
			||||||
    pac::XOSC
 | 
					 | 
				
			||||||
        .ctrl()
 | 
					 | 
				
			||||||
        .write(|w| w.set_freq_range(pac::xosc::vals::CtrlFreqRange::_1_15MHZ));
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    let startup_delay = (((XOSC_MHZ * 1_000_000) / 1000) + 128) / 256;
 | 
					 | 
				
			||||||
    pac::XOSC
 | 
					 | 
				
			||||||
        .startup()
 | 
					 | 
				
			||||||
        .write(|w| w.set_delay(startup_delay as u16));
 | 
					 | 
				
			||||||
    pac::XOSC.ctrl().write(|w| {
 | 
					 | 
				
			||||||
        w.set_freq_range(pac::xosc::vals::CtrlFreqRange::_1_15MHZ);
 | 
					 | 
				
			||||||
        w.set_enable(pac::xosc::vals::CtrlEnable::ENABLE);
 | 
					 | 
				
			||||||
    });
 | 
					 | 
				
			||||||
    while !pac::XOSC.status().read().stable() {}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    // Before we touch PLLs, switch sys and ref cleanly away from their aux sources.
 | 
					 | 
				
			||||||
    pac::CLOCKS
 | 
					 | 
				
			||||||
        .clk_sys_ctrl()
 | 
					 | 
				
			||||||
        .modify(|w| w.set_src(pac::clocks::vals::ClkSysCtrlSrc::CLK_REF));
 | 
					 | 
				
			||||||
    while pac::CLOCKS.clk_sys_selected().read() != 1 {}
 | 
					 | 
				
			||||||
    pac::CLOCKS
 | 
					 | 
				
			||||||
        .clk_ref_ctrl()
 | 
					 | 
				
			||||||
        .modify(|w| w.set_src(pac::clocks::vals::ClkRefCtrlSrc::ROSC_CLKSRC_PH));
 | 
					 | 
				
			||||||
    while pac::CLOCKS.clk_ref_selected().read() != 1 {}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    let mut peris = resets::Peripherals(0);
 | 
					 | 
				
			||||||
    peris.set_pll_sys(true);
 | 
					 | 
				
			||||||
    peris.set_pll_usb(true);
 | 
					 | 
				
			||||||
    resets.reset(peris);
 | 
					 | 
				
			||||||
    resets.unreset_wait(peris);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    pll::PLL::new(pll::PllSys).configure(1, 1500_000_000, 6, 2);
 | 
					 | 
				
			||||||
    pll::PLL::new(pll::PllUsb).configure(1, 480_000_000, 5, 2);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    // Activate peripheral clock and take external oscillator as input
 | 
					 | 
				
			||||||
    pac::CLOCKS.clk_peri_ctrl().write(|w| {
 | 
					 | 
				
			||||||
        w.set_enable(true);
 | 
					 | 
				
			||||||
        w.set_auxsrc(pac::clocks::vals::ClkPeriCtrlAuxsrc::XOSC_CLKSRC);
 | 
					 | 
				
			||||||
    });
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
		Reference in New Issue
	
	Block a user