mirror of
https://github.com/embassy-rs/embassy.git
synced 2024-11-21 22:32:29 +00:00
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:
parent
b1ea90a87e
commit
203297b569
@ -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" ]
|
||||||
|
@ -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(), )*
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -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);
|
||||||
|
|
||||||
|
@ -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;
|
||||||
|
@ -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.
|
||||||
|
@ -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)),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -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)
|
||||||
|
@ -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 */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -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)
|
||||||
|
@ -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);
|
||||||
|
Loading…
Reference in New Issue
Block a user