mirror of
https://github.com/embassy-rs/embassy.git
synced 2024-11-22 06:42:32 +00:00
Add init
fn. Initializes hw and returns Peripherals.
This commit is contained in:
parent
bfc7f52e6d
commit
0310e4d458
@ -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);
|
|
||||||
});
|
|
||||||
}
|
|
Loading…
Reference in New Issue
Block a user