mirror of
https://github.com/embassy-rs/embassy.git
synced 2026-05-01 02:24:22 +00:00
stm32wl55: abscond with HSEM 3 for reset locking so only one core issues the reset
This commit is contained in:
@@ -80,9 +80,12 @@ impl CoreId {
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(not(all(stm32wb, feature = "low-power")))]
|
||||
#[cfg(all(not(all(stm32wb, feature = "low-power")), not(stm32wl5x)))]
|
||||
const PUB_CHANNELS: usize = 6;
|
||||
|
||||
#[cfg(stm32wl5x)]
|
||||
const PUB_CHANNELS: usize = 5;
|
||||
|
||||
#[cfg(all(stm32wb, feature = "low-power"))]
|
||||
const PUB_CHANNELS: usize = 4;
|
||||
|
||||
@@ -273,7 +276,7 @@ impl<T: Instance> HardwareSemaphore<T> {
|
||||
[
|
||||
HardwareSemaphoreChannel::new(1),
|
||||
HardwareSemaphoreChannel::new(2),
|
||||
#[cfg(not(all(stm32wb, feature = "low-power")))]
|
||||
#[cfg(all(not(all(stm32wb, feature = "low-power")), not(stm32wl5x)))]
|
||||
HardwareSemaphoreChannel::new(3),
|
||||
#[cfg(not(all(stm32wb, feature = "low-power")))]
|
||||
HardwareSemaphoreChannel::new(4),
|
||||
|
||||
@@ -278,7 +278,7 @@ pub struct Ipcc {
|
||||
}
|
||||
|
||||
impl Ipcc {
|
||||
/// Creates a new HardwareSemaphore instance.
|
||||
/// Creates a new Ipcc instance.
|
||||
#[cfg(not(feature = "_core-cm0p"))]
|
||||
pub fn new<'d>(
|
||||
_peripheral: Peri<'d, crate::peripherals::IPCC>,
|
||||
@@ -302,7 +302,7 @@ impl Ipcc {
|
||||
Self { _private: () }
|
||||
}
|
||||
|
||||
/// Creates a new HardwareSemaphore instance.
|
||||
/// Creates a new Ipcc instance.
|
||||
#[cfg(feature = "_core-cm0p")]
|
||||
pub fn new<'d>(
|
||||
_peripheral: Peri<'d, crate::peripherals::IPCC>,
|
||||
|
||||
@@ -222,6 +222,18 @@ impl RccInfo {
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(stm32wl5x)]
|
||||
fn wait_for_lock(&self) -> crate::hsem::HardwareSemaphoreMutex<'_, crate::peripherals::HSEM> {
|
||||
use crate::hsem::HardwareSemaphoreChannel;
|
||||
use crate::peripherals::HSEM;
|
||||
let mut sem = HardwareSemaphoreChannel::<HSEM>::new(3);
|
||||
loop {
|
||||
if let Some(lock) = sem.try_lock(0) {
|
||||
return lock;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: should this be `unsafe`?
|
||||
pub(crate) fn enable_and_reset_with_cs(&self, _cs: CriticalSection) {
|
||||
if self.refcount_idx_or_0xff != 0xff {
|
||||
@@ -253,14 +265,18 @@ impl RccInfo {
|
||||
|
||||
// on stm32wl5x each CPU has its own peripheral enable bits and if the othert CPU has enabled the peripheral we don;t want to reset it
|
||||
// as that would reset the configuration that the other CPU has set up.
|
||||
// TODO: race condition!
|
||||
// we hold a hardware lock to prevent the other CPU from enabling the peripheral while we are resetting it.
|
||||
#[cfg(stm32wl5x)]
|
||||
if unsafe { !self.is_enabled_by_other_core() } {
|
||||
unsafe {
|
||||
let val = reset_ptr.read_volatile();
|
||||
reset_ptr.write_volatile(val | 1u32 << self.reset_bit);
|
||||
{
|
||||
let lock = self.wait_for_lock();
|
||||
if unsafe { !self.is_enabled_by_other_core() } {
|
||||
unsafe {
|
||||
let val = reset_ptr.read_volatile();
|
||||
reset_ptr.write_volatile(val | 1u32 << self.reset_bit);
|
||||
}
|
||||
trace!("rcc: reset 0x{:x}:{}", self.enable_offset, self.enable_bit);
|
||||
}
|
||||
trace!("rcc: reset 0x{:x}:{}", self.enable_offset, self.enable_bit);
|
||||
drop(lock);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -32,7 +32,9 @@ async fn main(_spawner: Spawner) {
|
||||
|
||||
#[cfg(feature = "stm32wb55rg")]
|
||||
let [_channel1, _channel2, mut channel5, _channel6] = hsem.split();
|
||||
#[cfg(not(feature = "stm32wb55rg"))]
|
||||
#[cfg(feature = "stm32wl55jc")]
|
||||
let [_channel1, _channel2, _channel4, mut channel5, _channel6] = hsem.split();
|
||||
#[cfg(not(any(feature = "stm32wb55rg", feature = "stm32wl55jc")))]
|
||||
let [_channel1, _channel2, _channel3, _channel4, mut channel5, _channel6] = hsem.split();
|
||||
|
||||
info!("Locking channel 5");
|
||||
|
||||
Reference in New Issue
Block a user