#![no_std] #![cfg_attr(feature = "nightly", feature(async_fn_in_trait, impl_trait_projections))] // This mod MUST go first, so that the others see its macros. pub(crate) mod fmt; #[cfg(feature = "critical-section-impl")] mod critical_section_impl; mod intrinsics; pub mod adc; pub mod clocks; pub mod dma; pub mod flash; mod float; pub mod gpio; pub mod i2c; pub mod interrupt; pub mod multicore; pub mod pwm; mod reset; pub mod rom_data; pub mod rtc; pub mod spi; #[cfg(feature = "time-driver")] pub mod timer; pub mod uart; #[cfg(feature = "nightly")] pub mod usb; pub mod watchdog; // PIO // TODO: move `pio_instr_util` and `relocate` to inside `pio` pub mod pio; pub mod pio_instr_util; pub mod relocate; // Reexports pub use embassy_cortex_m::executor; pub use embassy_cortex_m::interrupt::_export::interrupt; pub use embassy_hal_common::{into_ref, Peripheral, PeripheralRef}; #[cfg(feature = "unstable-pac")] pub use rp_pac as pac; #[cfg(not(feature = "unstable-pac"))] pub(crate) use rp_pac as pac; embassy_hal_common::peripherals! { PIN_0, PIN_1, PIN_2, PIN_3, PIN_4, PIN_5, PIN_6, PIN_7, PIN_8, PIN_9, PIN_10, PIN_11, PIN_12, PIN_13, PIN_14, PIN_15, PIN_16, PIN_17, PIN_18, PIN_19, PIN_20, PIN_21, PIN_22, PIN_23, PIN_24, PIN_25, PIN_26, PIN_27, PIN_28, PIN_29, PIN_QSPI_SCLK, PIN_QSPI_SS, PIN_QSPI_SD0, PIN_QSPI_SD1, PIN_QSPI_SD2, PIN_QSPI_SD3, UART0, UART1, SPI0, SPI1, I2C0, I2C1, DMA_CH0, DMA_CH1, DMA_CH2, DMA_CH3, DMA_CH4, DMA_CH5, DMA_CH6, DMA_CH7, DMA_CH8, DMA_CH9, DMA_CH10, DMA_CH11, PWM_CH0, PWM_CH1, PWM_CH2, PWM_CH3, PWM_CH4, PWM_CH5, PWM_CH6, PWM_CH7, USB, RTC, FLASH, ADC, CORE1, PIO0, PIO1, WATCHDOG, } macro_rules! select_bootloader { ( $( $feature:literal => $loader:ident, )+ default => $default:ident ) => { $( #[cfg(feature = $feature)] #[link_section = ".boot2"] #[used] static BOOT2: [u8; 256] = rp2040_boot2::$loader; )* #[cfg(not(any( $( feature = $feature),* )))] #[link_section = ".boot2"] #[used] static BOOT2: [u8; 256] = rp2040_boot2::$default; } } select_bootloader! { "boot2-at25sf128a" => BOOT_LOADER_AT25SF128A, "boot2-gd25q64cs" => BOOT_LOADER_GD25Q64CS, "boot2-generic-03h" => BOOT_LOADER_GENERIC_03H, "boot2-is25lp080" => BOOT_LOADER_IS25LP080, "boot2-ram-memcpy" => BOOT_LOADER_RAM_MEMCPY, "boot2-w25q080" => BOOT_LOADER_W25Q080, "boot2-w25x10cl" => BOOT_LOADER_W25X10CL, default => BOOT_LOADER_W25Q080 } pub mod config { use crate::clocks::ClockConfig; #[non_exhaustive] pub struct Config { pub clocks: ClockConfig, } impl Default for Config { fn default() -> Self { Self { clocks: ClockConfig::crystal(12_000_000), } } } impl Config { pub fn new(clocks: ClockConfig) -> Self { Self { clocks } } } } 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(); unsafe { clocks::init(config.clocks); #[cfg(feature = "time-driver")] timer::init(); dma::init(); pio::init(); gpio::init(); } peripherals } /// Extension trait for PAC regs, adding atomic xor/bitset/bitclear writes. trait RegExt { unsafe fn write_xor(&self, f: impl FnOnce(&mut T) -> R) -> R; unsafe fn write_set(&self, f: impl FnOnce(&mut T) -> R) -> R; unsafe fn write_clear(&self, f: impl FnOnce(&mut T) -> R) -> R; } impl RegExt for pac::common::Reg { unsafe fn write_xor(&self, f: impl FnOnce(&mut T) -> R) -> R { let mut val = Default::default(); let res = f(&mut val); let ptr = (self.ptr() as *mut u8).add(0x1000) as *mut T; ptr.write_volatile(val); res } unsafe fn write_set(&self, f: impl FnOnce(&mut T) -> R) -> R { let mut val = Default::default(); let res = f(&mut val); let ptr = (self.ptr() as *mut u8).add(0x2000) as *mut T; ptr.write_volatile(val); res } unsafe fn write_clear(&self, f: impl FnOnce(&mut T) -> R) -> R { let mut val = Default::default(); let res = f(&mut val); let ptr = (self.ptr() as *mut u8).add(0x3000) as *mut T; ptr.write_volatile(val); res } }