Make clocks repr C.

Add shared data.
Modify freq functions to use shared data.
Modify examples to use new init/
This commit is contained in:
Dion Dokter 2024-07-08 16:54:06 +02:00
parent b1ea90a87e
commit 203297b569
11 changed files with 272 additions and 73 deletions

View File

@ -181,6 +181,9 @@ split-pc3 = ["_split-pins-enabled"]
## internal use only ## internal use only
_split-pins-enabled = [] _split-pins-enabled = []
## internal use only
_dual-core = []
#! ## Chip-selection features #! ## Chip-selection features
#! Select your chip by specifying the model as a feature, e.g. `stm32c011d6`. #! Select your chip by specifying the model as a feature, e.g. `stm32c011d6`.
#! Check the `Cargo.toml` for the latest list of supported chips. #! Check the `Cargo.toml` for the latest list of supported chips.
@ -1004,40 +1007,40 @@ stm32h743xg = [ "stm32-metapac/stm32h743xg" ]
stm32h743xi = [ "stm32-metapac/stm32h743xi" ] stm32h743xi = [ "stm32-metapac/stm32h743xi" ]
stm32h743zg = [ "stm32-metapac/stm32h743zg" ] stm32h743zg = [ "stm32-metapac/stm32h743zg" ]
stm32h743zi = [ "stm32-metapac/stm32h743zi" ] stm32h743zi = [ "stm32-metapac/stm32h743zi" ]
stm32h745bg-cm7 = [ "stm32-metapac/stm32h745bg-cm7" ] stm32h745bg-cm7 = [ "stm32-metapac/stm32h745bg-cm7", "_dual-core" ]
stm32h745bg-cm4 = [ "stm32-metapac/stm32h745bg-cm4" ] stm32h745bg-cm4 = [ "stm32-metapac/stm32h745bg-cm4", "_dual-core" ]
stm32h745bi-cm7 = [ "stm32-metapac/stm32h745bi-cm7" ] stm32h745bi-cm7 = [ "stm32-metapac/stm32h745bi-cm7", "_dual-core" ]
stm32h745bi-cm4 = [ "stm32-metapac/stm32h745bi-cm4" ] stm32h745bi-cm4 = [ "stm32-metapac/stm32h745bi-cm4", "_dual-core" ]
stm32h745ig-cm7 = [ "stm32-metapac/stm32h745ig-cm7" ] stm32h745ig-cm7 = [ "stm32-metapac/stm32h745ig-cm7", "_dual-core" ]
stm32h745ig-cm4 = [ "stm32-metapac/stm32h745ig-cm4" ] stm32h745ig-cm4 = [ "stm32-metapac/stm32h745ig-cm4", "_dual-core" ]
stm32h745ii-cm7 = [ "stm32-metapac/stm32h745ii-cm7" ] stm32h745ii-cm7 = [ "stm32-metapac/stm32h745ii-cm7", "_dual-core" ]
stm32h745ii-cm4 = [ "stm32-metapac/stm32h745ii-cm4" ] stm32h745ii-cm4 = [ "stm32-metapac/stm32h745ii-cm4", "_dual-core" ]
stm32h745xg-cm7 = [ "stm32-metapac/stm32h745xg-cm7" ] stm32h745xg-cm7 = [ "stm32-metapac/stm32h745xg-cm7", "_dual-core" ]
stm32h745xg-cm4 = [ "stm32-metapac/stm32h745xg-cm4" ] stm32h745xg-cm4 = [ "stm32-metapac/stm32h745xg-cm4", "_dual-core" ]
stm32h745xi-cm7 = [ "stm32-metapac/stm32h745xi-cm7" ] stm32h745xi-cm7 = [ "stm32-metapac/stm32h745xi-cm7", "_dual-core" ]
stm32h745xi-cm4 = [ "stm32-metapac/stm32h745xi-cm4" ] stm32h745xi-cm4 = [ "stm32-metapac/stm32h745xi-cm4", "_dual-core" ]
stm32h745zg-cm7 = [ "stm32-metapac/stm32h745zg-cm7" ] stm32h745zg-cm7 = [ "stm32-metapac/stm32h745zg-cm7", "_dual-core" ]
stm32h745zg-cm4 = [ "stm32-metapac/stm32h745zg-cm4" ] stm32h745zg-cm4 = [ "stm32-metapac/stm32h745zg-cm4", "_dual-core" ]
stm32h745zi-cm7 = [ "stm32-metapac/stm32h745zi-cm7" ] stm32h745zi-cm7 = [ "stm32-metapac/stm32h745zi-cm7", "_dual-core" ]
stm32h745zi-cm4 = [ "stm32-metapac/stm32h745zi-cm4" ] stm32h745zi-cm4 = [ "stm32-metapac/stm32h745zi-cm4", "_dual-core" ]
stm32h747ag-cm7 = [ "stm32-metapac/stm32h747ag-cm7" ] stm32h747ag-cm7 = [ "stm32-metapac/stm32h747ag-cm7", "_dual-core" ]
stm32h747ag-cm4 = [ "stm32-metapac/stm32h747ag-cm4" ] stm32h747ag-cm4 = [ "stm32-metapac/stm32h747ag-cm4", "_dual-core" ]
stm32h747ai-cm7 = [ "stm32-metapac/stm32h747ai-cm7" ] stm32h747ai-cm7 = [ "stm32-metapac/stm32h747ai-cm7", "_dual-core" ]
stm32h747ai-cm4 = [ "stm32-metapac/stm32h747ai-cm4" ] stm32h747ai-cm4 = [ "stm32-metapac/stm32h747ai-cm4", "_dual-core" ]
stm32h747bg-cm7 = [ "stm32-metapac/stm32h747bg-cm7" ] stm32h747bg-cm7 = [ "stm32-metapac/stm32h747bg-cm7", "_dual-core" ]
stm32h747bg-cm4 = [ "stm32-metapac/stm32h747bg-cm4" ] stm32h747bg-cm4 = [ "stm32-metapac/stm32h747bg-cm4", "_dual-core" ]
stm32h747bi-cm7 = [ "stm32-metapac/stm32h747bi-cm7" ] stm32h747bi-cm7 = [ "stm32-metapac/stm32h747bi-cm7", "_dual-core" ]
stm32h747bi-cm4 = [ "stm32-metapac/stm32h747bi-cm4" ] stm32h747bi-cm4 = [ "stm32-metapac/stm32h747bi-cm4", "_dual-core" ]
stm32h747ig-cm7 = [ "stm32-metapac/stm32h747ig-cm7" ] stm32h747ig-cm7 = [ "stm32-metapac/stm32h747ig-cm7", "_dual-core" ]
stm32h747ig-cm4 = [ "stm32-metapac/stm32h747ig-cm4" ] stm32h747ig-cm4 = [ "stm32-metapac/stm32h747ig-cm4", "_dual-core" ]
stm32h747ii-cm7 = [ "stm32-metapac/stm32h747ii-cm7" ] stm32h747ii-cm7 = [ "stm32-metapac/stm32h747ii-cm7", "_dual-core" ]
stm32h747ii-cm4 = [ "stm32-metapac/stm32h747ii-cm4" ] stm32h747ii-cm4 = [ "stm32-metapac/stm32h747ii-cm4", "_dual-core" ]
stm32h747xg-cm7 = [ "stm32-metapac/stm32h747xg-cm7" ] stm32h747xg-cm7 = [ "stm32-metapac/stm32h747xg-cm7", "_dual-core" ]
stm32h747xg-cm4 = [ "stm32-metapac/stm32h747xg-cm4" ] stm32h747xg-cm4 = [ "stm32-metapac/stm32h747xg-cm4", "_dual-core" ]
stm32h747xi-cm7 = [ "stm32-metapac/stm32h747xi-cm7" ] stm32h747xi-cm7 = [ "stm32-metapac/stm32h747xi-cm7", "_dual-core" ]
stm32h747xi-cm4 = [ "stm32-metapac/stm32h747xi-cm4" ] stm32h747xi-cm4 = [ "stm32-metapac/stm32h747xi-cm4", "_dual-core" ]
stm32h747zi-cm7 = [ "stm32-metapac/stm32h747zi-cm7" ] stm32h747zi-cm7 = [ "stm32-metapac/stm32h747zi-cm7", "_dual-core" ]
stm32h747zi-cm4 = [ "stm32-metapac/stm32h747zi-cm4" ] stm32h747zi-cm4 = [ "stm32-metapac/stm32h747zi-cm4", "_dual-core" ]
stm32h750ib = [ "stm32-metapac/stm32h750ib" ] stm32h750ib = [ "stm32-metapac/stm32h750ib" ]
stm32h750vb = [ "stm32-metapac/stm32h750vb" ] stm32h750vb = [ "stm32-metapac/stm32h750vb" ]
stm32h750xb = [ "stm32-metapac/stm32h750xb" ] stm32h750xb = [ "stm32-metapac/stm32h750xb" ]
@ -1048,24 +1051,24 @@ stm32h753ii = [ "stm32-metapac/stm32h753ii" ]
stm32h753vi = [ "stm32-metapac/stm32h753vi" ] stm32h753vi = [ "stm32-metapac/stm32h753vi" ]
stm32h753xi = [ "stm32-metapac/stm32h753xi" ] stm32h753xi = [ "stm32-metapac/stm32h753xi" ]
stm32h753zi = [ "stm32-metapac/stm32h753zi" ] stm32h753zi = [ "stm32-metapac/stm32h753zi" ]
stm32h755bi-cm7 = [ "stm32-metapac/stm32h755bi-cm7" ] stm32h755bi-cm7 = [ "stm32-metapac/stm32h755bi-cm7", "_dual-core" ]
stm32h755bi-cm4 = [ "stm32-metapac/stm32h755bi-cm4" ] stm32h755bi-cm4 = [ "stm32-metapac/stm32h755bi-cm4", "_dual-core" ]
stm32h755ii-cm7 = [ "stm32-metapac/stm32h755ii-cm7" ] stm32h755ii-cm7 = [ "stm32-metapac/stm32h755ii-cm7", "_dual-core" ]
stm32h755ii-cm4 = [ "stm32-metapac/stm32h755ii-cm4" ] stm32h755ii-cm4 = [ "stm32-metapac/stm32h755ii-cm4", "_dual-core" ]
stm32h755xi-cm7 = [ "stm32-metapac/stm32h755xi-cm7" ] stm32h755xi-cm7 = [ "stm32-metapac/stm32h755xi-cm7", "_dual-core" ]
stm32h755xi-cm4 = [ "stm32-metapac/stm32h755xi-cm4" ] stm32h755xi-cm4 = [ "stm32-metapac/stm32h755xi-cm4", "_dual-core" ]
stm32h755zi-cm7 = [ "stm32-metapac/stm32h755zi-cm7" ] stm32h755zi-cm7 = [ "stm32-metapac/stm32h755zi-cm7", "_dual-core" ]
stm32h755zi-cm4 = [ "stm32-metapac/stm32h755zi-cm4" ] stm32h755zi-cm4 = [ "stm32-metapac/stm32h755zi-cm4", "_dual-core" ]
stm32h757ai-cm7 = [ "stm32-metapac/stm32h757ai-cm7" ] stm32h757ai-cm7 = [ "stm32-metapac/stm32h757ai-cm7", "_dual-core" ]
stm32h757ai-cm4 = [ "stm32-metapac/stm32h757ai-cm4" ] stm32h757ai-cm4 = [ "stm32-metapac/stm32h757ai-cm4", "_dual-core" ]
stm32h757bi-cm7 = [ "stm32-metapac/stm32h757bi-cm7" ] stm32h757bi-cm7 = [ "stm32-metapac/stm32h757bi-cm7", "_dual-core" ]
stm32h757bi-cm4 = [ "stm32-metapac/stm32h757bi-cm4" ] stm32h757bi-cm4 = [ "stm32-metapac/stm32h757bi-cm4", "_dual-core" ]
stm32h757ii-cm7 = [ "stm32-metapac/stm32h757ii-cm7" ] stm32h757ii-cm7 = [ "stm32-metapac/stm32h757ii-cm7", "_dual-core" ]
stm32h757ii-cm4 = [ "stm32-metapac/stm32h757ii-cm4" ] stm32h757ii-cm4 = [ "stm32-metapac/stm32h757ii-cm4", "_dual-core" ]
stm32h757xi-cm7 = [ "stm32-metapac/stm32h757xi-cm7" ] stm32h757xi-cm7 = [ "stm32-metapac/stm32h757xi-cm7", "_dual-core" ]
stm32h757xi-cm4 = [ "stm32-metapac/stm32h757xi-cm4" ] stm32h757xi-cm4 = [ "stm32-metapac/stm32h757xi-cm4", "_dual-core" ]
stm32h757zi-cm7 = [ "stm32-metapac/stm32h757zi-cm7" ] stm32h757zi-cm7 = [ "stm32-metapac/stm32h757zi-cm7", "_dual-core" ]
stm32h757zi-cm4 = [ "stm32-metapac/stm32h757zi-cm4" ] stm32h757zi-cm4 = [ "stm32-metapac/stm32h757zi-cm4", "_dual-core" ]
stm32h7a3ag = [ "stm32-metapac/stm32h7a3ag" ] stm32h7a3ag = [ "stm32-metapac/stm32h7a3ag" ]
stm32h7a3ai = [ "stm32-metapac/stm32h7a3ai" ] stm32h7a3ai = [ "stm32-metapac/stm32h7a3ai" ]
stm32h7a3ig = [ "stm32-metapac/stm32h7a3ig" ] stm32h7a3ig = [ "stm32-metapac/stm32h7a3ig" ]
@ -1598,14 +1601,14 @@ stm32wba55he = [ "stm32-metapac/stm32wba55he" ]
stm32wba55hg = [ "stm32-metapac/stm32wba55hg" ] stm32wba55hg = [ "stm32-metapac/stm32wba55hg" ]
stm32wba55ue = [ "stm32-metapac/stm32wba55ue" ] stm32wba55ue = [ "stm32-metapac/stm32wba55ue" ]
stm32wba55ug = [ "stm32-metapac/stm32wba55ug" ] stm32wba55ug = [ "stm32-metapac/stm32wba55ug" ]
stm32wl54cc-cm4 = [ "stm32-metapac/stm32wl54cc-cm4" ] stm32wl54cc-cm4 = [ "stm32-metapac/stm32wl54cc-cm4", "_dual-core" ]
stm32wl54cc-cm0p = [ "stm32-metapac/stm32wl54cc-cm0p" ] stm32wl54cc-cm0p = [ "stm32-metapac/stm32wl54cc-cm0p", "_dual-core" ]
stm32wl54jc-cm4 = [ "stm32-metapac/stm32wl54jc-cm4" ] stm32wl54jc-cm4 = [ "stm32-metapac/stm32wl54jc-cm4", "_dual-core" ]
stm32wl54jc-cm0p = [ "stm32-metapac/stm32wl54jc-cm0p" ] stm32wl54jc-cm0p = [ "stm32-metapac/stm32wl54jc-cm0p", "_dual-core" ]
stm32wl55cc-cm4 = [ "stm32-metapac/stm32wl55cc-cm4" ] stm32wl55cc-cm4 = [ "stm32-metapac/stm32wl55cc-cm4", "_dual-core" ]
stm32wl55cc-cm0p = [ "stm32-metapac/stm32wl55cc-cm0p" ] stm32wl55cc-cm0p = [ "stm32-metapac/stm32wl55cc-cm0p", "_dual-core" ]
stm32wl55jc-cm4 = [ "stm32-metapac/stm32wl55jc-cm4" ] stm32wl55jc-cm4 = [ "stm32-metapac/stm32wl55jc-cm4", "_dual-core" ]
stm32wl55jc-cm0p = [ "stm32-metapac/stm32wl55jc-cm0p" ] stm32wl55jc-cm0p = [ "stm32-metapac/stm32wl55jc-cm0p", "_dual-core" ]
stm32wle4c8 = [ "stm32-metapac/stm32wle4c8" ] stm32wle4c8 = [ "stm32-metapac/stm32wle4c8" ]
stm32wle4cb = [ "stm32-metapac/stm32wle4cb" ] stm32wle4cb = [ "stm32-metapac/stm32wle4cb" ]
stm32wle4cc = [ "stm32-metapac/stm32wle4cc" ] stm32wle4cc = [ "stm32-metapac/stm32wle4cc" ]

View File

@ -480,7 +480,7 @@ fn main() {
self.clock_names.insert(name.to_ascii_lowercase()); self.clock_names.insert(name.to_ascii_lowercase());
quote!(unsafe { quote!(unsafe {
unwrap!( unwrap!(
crate::rcc::get_freqs().#clock_name, crate::rcc::get_freqs().#clock_name.to_hertz(),
"peripheral '{}' is configured to use the '{}' clock, which is not running. \ "peripheral '{}' is configured to use the '{}' clock, which is not running. \
Either enable it in 'config.rcc' or change 'config.rcc.mux' to use another clock", Either enable it in 'config.rcc' or change 'config.rcc.mux' to use another clock",
#peripheral, #peripheral,
@ -713,9 +713,10 @@ fn main() {
g.extend(quote! { g.extend(quote! {
#[derive(Clone, Copy, Debug)] #[derive(Clone, Copy, Debug)]
#[cfg_attr(feature = "defmt", derive(defmt::Format))] #[cfg_attr(feature = "defmt", derive(defmt::Format))]
#[repr(C)]
pub struct Clocks { pub struct Clocks {
#( #(
pub #clock_idents: Option<crate::time::Hertz>, pub #clock_idents: crate::time::MaybeHertz,
)* )*
} }
}); });
@ -732,7 +733,7 @@ fn main() {
$($(#[$m])* $k: $v,)* $($(#[$m])* $k: $v,)*
}; };
crate::rcc::set_freqs(crate::rcc::Clocks { crate::rcc::set_freqs(crate::rcc::Clocks {
#( #clock_idents: all.#clock_idents, )* #( #clock_idents: all.#clock_idents.into(), )*
}); });
} }
}; };

View File

@ -273,7 +273,123 @@ impl Default for Config {
/// This returns the peripheral singletons that can be used for creating drivers. /// This returns the peripheral singletons that can be used for creating drivers.
/// ///
/// This should only be called once at startup, otherwise it panics. /// This should only be called once at startup, otherwise it panics.
#[cfg(not(feature = "_dual-core"))]
pub fn init(config: Config) -> Peripherals { pub fn init(config: Config) -> Peripherals {
init_hw(config)
}
#[cfg(feature = "_dual-core")]
mod dual_core {
use rcc::Clocks;
use super::*;
use core::{
mem::MaybeUninit,
sync::atomic::{AtomicUsize, Ordering},
};
/// Object containing data that embassy needs to share between cores.
///
/// It cannot be initialized by the user. The intended use is:
///
/// ```
/// #[link_section = ".ram_d3"]
/// static SHARED_DATA: MaybeUninit<SharedData> = MaybeUninit::uninit();
///
/// init_secondary(&SHARED_DATA);
/// ```
///
/// This static must be placed in the same position for both cores. How and where this is done is left to the user.
pub struct SharedData {
init_flag: AtomicUsize,
clocks: MaybeUninit<Clocks>,
}
const INIT_DONE_FLAG: usize = 0xca11ab1e;
/// Initialize the `embassy-stm32` HAL with the provided configuration.
/// This function does the actual initialization of the hardware, in contrast to [init_secondary] or [try_init_secondary].
/// Any core can do the init, but it's important only one core does it.
///
/// This returns the peripheral singletons that can be used for creating drivers.
///
/// This should only be called once at startup, otherwise it panics.
///
/// The `shared_data` is used to coordinate the init with the second core. Read the [SharedData] docs
/// for more information on its requirements.
pub fn init_primary(config: Config, shared_data: &'static MaybeUninit<SharedData>) -> Peripherals {
let shared_data = unsafe { shared_data.assume_init_ref() };
rcc::set_freqs_ptr(&shared_data.clocks);
let p = init_hw(config);
shared_data.init_flag.store(INIT_DONE_FLAG, Ordering::SeqCst);
p
}
/// Try to initialize the `embassy-stm32` HAL based on the init done by the other core using [init_primary].
///
/// This returns the peripheral singletons that can be used for creating drivers if the other core is done with its init.
/// If the other core is not done yet, this will return `None`.
///
/// This should only be called once at startup, otherwise it may panic.
///
/// The `shared_data` is used to coordinate the init with the second core. Read the [SharedData] docs
/// for more information on its requirements.
pub fn try_init_secondary(shared_data: &'static MaybeUninit<SharedData>) -> Option<Peripherals> {
let shared_data = unsafe { shared_data.assume_init_ref() };
if shared_data
.init_flag
.compare_exchange(INIT_DONE_FLAG, 0, Ordering::SeqCst, Ordering::SeqCst)
.is_err()
{
return None;
}
Some(init_secondary_hw(shared_data))
}
/// Initialize the `embassy-stm32` HAL based on the init done by the other core using [init_primary].
///
/// This returns the peripheral singletons that can be used for creating drivers when the other core is done with its init.
/// If the other core is not done yet, this will spinloop wait on it.
///
/// This should only be called once at startup, otherwise it may panic.
///
/// The `shared_data` is used to coordinate the init with the second core. Read the [SharedData] docs
/// for more information on its requirements.
pub fn init_secondary(shared_data: &'static MaybeUninit<SharedData>) -> Peripherals {
let shared_data = unsafe { shared_data.assume_init_ref() };
while shared_data
.init_flag
.compare_exchange(INIT_DONE_FLAG, 0, Ordering::SeqCst, Ordering::SeqCst)
.is_err()
{}
init_secondary_hw(shared_data)
}
fn init_secondary_hw(shared_data: &'static SharedData) -> Peripherals {
rcc::set_freqs_ptr(&shared_data.clocks);
// We use different timers on the different cores, so we have to still initialize one here
critical_section::with(|cs| {
// must be after rcc init
#[cfg(feature = "_time-driver")]
time_driver::init(cs);
});
Peripherals::take()
}
}
#[cfg(feature = "_dual-core")]
pub use dual_core::*;
fn init_hw(config: Config) -> Peripherals {
critical_section::with(|cs| { critical_section::with(|cs| {
let p = Peripherals::take_with_cs(cs); let p = Peripherals::take_with_cs(cs);

View File

@ -48,11 +48,22 @@ pub(crate) static mut REFCOUNT_STOP1: u32 = 0;
/// May be read without a critical section /// May be read without a critical section
pub(crate) static mut REFCOUNT_STOP2: u32 = 0; pub(crate) static mut REFCOUNT_STOP2: u32 = 0;
#[cfg(not(feature = "_dual-core"))]
/// Frozen clock frequencies /// Frozen clock frequencies
/// ///
/// The existence of this value indicates that the clock configuration can no longer be changed /// The existence of this value indicates that the clock configuration can no longer be changed
static mut CLOCK_FREQS: MaybeUninit<Clocks> = MaybeUninit::uninit(); static mut CLOCK_FREQS: MaybeUninit<Clocks> = MaybeUninit::uninit();
#[cfg(feature = "_dual-core")]
static CLOCK_FREQS_PTR: core::sync::atomic::AtomicPtr<MaybeUninit<Clocks>> =
core::sync::atomic::AtomicPtr::new(core::ptr::null_mut());
#[cfg(feature = "_dual-core")]
pub(crate) fn set_freqs_ptr(freqs: &'static MaybeUninit<Clocks>) {
CLOCK_FREQS_PTR.store(freqs as *const _ as *mut _, core::sync::atomic::Ordering::SeqCst);
}
#[cfg(not(feature = "_dual-core"))]
/// Sets the clock frequencies /// Sets the clock frequencies
/// ///
/// Safety: Sets a mutable global. /// Safety: Sets a mutable global.
@ -61,11 +72,27 @@ pub(crate) unsafe fn set_freqs(freqs: Clocks) {
CLOCK_FREQS = MaybeUninit::new(freqs); CLOCK_FREQS = MaybeUninit::new(freqs);
} }
#[cfg(feature = "_dual-core")]
/// Sets the clock frequencies
///
/// Safety: Sets a mutable global.
pub(crate) unsafe fn set_freqs(freqs: Clocks) {
debug!("rcc: {:?}", freqs);
CLOCK_FREQS_PTR.load(core::sync::atomic::Ordering::SeqCst).write(MaybeUninit::new(freqs));
}
#[cfg(not(feature = "_dual-core"))]
/// Safety: Reads a mutable global. /// Safety: Reads a mutable global.
pub(crate) unsafe fn get_freqs() -> &'static Clocks { pub(crate) unsafe fn get_freqs() -> &'static Clocks {
CLOCK_FREQS.assume_init_ref() CLOCK_FREQS.assume_init_ref()
} }
#[cfg(feature = "_dual-core")]
/// Safety: Reads a mutable global.
pub(crate) unsafe fn get_freqs() -> &'static Clocks {
unwrap!(CLOCK_FREQS_PTR.load(core::sync::atomic::Ordering::SeqCst).as_ref()).assume_init_ref()
}
pub(crate) trait SealedRccPeripheral { pub(crate) trait SealedRccPeripheral {
fn frequency() -> Hertz; fn frequency() -> Hertz;
const RCC_INFO: RccInfo; const RCC_INFO: RccInfo;

View File

@ -168,7 +168,7 @@ impl Rtc {
fn frequency() -> Hertz { fn frequency() -> Hertz {
let freqs = unsafe { crate::rcc::get_freqs() }; let freqs = unsafe { crate::rcc::get_freqs() };
freqs.rtc.unwrap() freqs.rtc.to_hertz().unwrap()
} }
/// Acquire a [`RtcTimeProvider`] instance. /// Acquire a [`RtcTimeProvider`] instance.

View File

@ -87,3 +87,39 @@ impl Div<Hertz> for Hertz {
self.0 / rhs.0 self.0 / rhs.0
} }
} }
#[repr(C)]
#[derive(Eq, PartialEq, Ord, PartialOrd, Clone, Copy, Debug, Default)]
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
/// A variant on [Hertz] that acts as an `Option<Hertz>` that is smaller and repr C.
///
/// An `Option<Hertz>` can be `.into()`'d into this type and back.
/// The only restriction is that that [Hertz] cannot have the value 0 since that's
/// seen as the `None` variant.
pub struct MaybeHertz(u32);
impl MaybeHertz {
/// Same as calling the `.into()` function, but without type inference.
pub fn to_hertz(self) -> Option<Hertz> {
self.into()
}
}
impl From<Option<Hertz>> for MaybeHertz {
fn from(value: Option<Hertz>) -> Self {
match value {
Some(Hertz(0)) => panic!("Hertz cannot be 0"),
Some(Hertz(val)) => Self(val),
None => Self(0),
}
}
}
impl From<MaybeHertz> for Option<Hertz> {
fn from(value: MaybeHertz) -> Self {
match value {
MaybeHertz(0) => None,
MaybeHertz(val) => Some(Hertz(val)),
}
}
}

View File

@ -1,5 +1,5 @@
[target.thumbv7em-none-eabihf] [target.thumbv7em-none-eabihf]
runner = 'probe-rs run --chip STM32H755ZITx' runner = 'probe-rs run --chip STM32H755ZITx --catch-hardfault --always-print-stacktrace'
[build] [build]
target = "thumbv7em-none-eabihf" # Cortex-M4F and Cortex-M7F (with FPU) target = "thumbv7em-none-eabihf" # Cortex-M4F and Cortex-M7F (with FPU)

View File

@ -1,7 +1,7 @@
MEMORY MEMORY
{ {
FLASH : ORIGIN = 0x08100000, LENGTH = 1024K /* BANK_2 */ FLASH : ORIGIN = 0x08100000, LENGTH = 1024K /* BANK_2 */
RAM : ORIGIN = 0x30000000, LENGTH = 128K /* SRAM1 */ RAM : ORIGIN = 0x10000000, LENGTH = 128K /* SRAM1 */
RAM_D3 : ORIGIN = 0x38000000, LENGTH = 64K /* SRAM4 */ RAM_D3 : ORIGIN = 0x38000000, LENGTH = 64K /* SRAM4 */
} }

View File

@ -1,15 +1,23 @@
#![no_std] #![no_std]
#![no_main] #![no_main]
use core::mem::MaybeUninit;
use defmt::*; use defmt::*;
use embassy_executor::Spawner; use embassy_executor::Spawner;
use embassy_stm32::gpio::{Level, Output, Speed}; use embassy_stm32::{
gpio::{Level, Output, Speed},
SharedData,
};
use embassy_time::Timer; use embassy_time::Timer;
use {defmt_rtt as _, panic_probe as _}; use {defmt_rtt as _, panic_probe as _};
#[link_section = ".ram_d3"]
static SHARED_DATA: MaybeUninit<SharedData> = MaybeUninit::uninit();
#[embassy_executor::main] #[embassy_executor::main]
async fn main(_spawner: Spawner) { async fn main(_spawner: Spawner) {
let p = embassy_stm32::init(Default::default()); let p = embassy_stm32::init_secondary(&SHARED_DATA);
info!("Hello World!"); info!("Hello World!");
let mut led = Output::new(p.PE1, Level::High, Speed::Low); let mut led = Output::new(p.PE1, Level::High, Speed::Low);
@ -17,10 +25,10 @@ async fn main(_spawner: Spawner) {
loop { loop {
info!("high"); info!("high");
led.set_high(); led.set_high();
Timer::after_millis(500).await; Timer::after_millis(250).await;
info!("low"); info!("low");
led.set_low(); led.set_low();
Timer::after_millis(500).await; Timer::after_millis(250).await;
} }
} }

View File

@ -1,5 +1,5 @@
[target.thumbv7em-none-eabihf] [target.thumbv7em-none-eabihf]
runner = 'probe-rs run --chip STM32H755ZITx' runner = 'probe-rs run --chip STM32H755ZITx --catch-hardfault --always-print-stacktrace'
[build] [build]
target = "thumbv7em-none-eabihf" # Cortex-M4F and Cortex-M7F (with FPU) target = "thumbv7em-none-eabihf" # Cortex-M4F and Cortex-M7F (with FPU)

View File

@ -1,12 +1,20 @@
#![no_std] #![no_std]
#![no_main] #![no_main]
use core::mem::MaybeUninit;
use defmt::*; use defmt::*;
use embassy_executor::Spawner; use embassy_executor::Spawner;
use embassy_stm32::gpio::{Level, Output, Speed}; use embassy_stm32::{
gpio::{Level, Output, Speed},
SharedData,
};
use embassy_time::Timer; use embassy_time::Timer;
use {defmt_rtt as _, panic_probe as _}; use {defmt_rtt as _, panic_probe as _};
#[link_section = ".ram_d3"]
static SHARED_DATA: MaybeUninit<SharedData> = MaybeUninit::uninit();
#[embassy_executor::main] #[embassy_executor::main]
async fn main(_spawner: Spawner) { async fn main(_spawner: Spawner) {
let mut config = embassy_stm32::Config::default(); let mut config = embassy_stm32::Config::default();
@ -31,7 +39,7 @@ async fn main(_spawner: Spawner) {
config.rcc.voltage_scale = VoltageScale::Scale1; config.rcc.voltage_scale = VoltageScale::Scale1;
config.rcc.supply_config = SupplyConfig::DirectSMPS; config.rcc.supply_config = SupplyConfig::DirectSMPS;
} }
let p = embassy_stm32::init(config); let p = embassy_stm32::init_primary(config, &SHARED_DATA);
info!("Hello World!"); info!("Hello World!");
let mut led = Output::new(p.PB14, Level::High, Speed::Low); let mut led = Output::new(p.PB14, Level::High, Speed::Low);