Skip to content

Commit 3ee909b

Browse files
committed
fix: core was not recognized and 1-step lock did not work
1 parent 443ffd8 commit 3ee909b

File tree

1 file changed

+122
-28
lines changed

1 file changed

+122
-28
lines changed

embassy-stm32/src/hsem/mod.rs

Lines changed: 122 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,11 @@
11
//! Hardware Semaphore (HSEM)
22
33
use embassy_hal_internal::PeripheralType;
4+
use stm32_metapac::hsem::regs::Rlr;
45

56
use crate::pac;
67
use crate::rcc::RccPeripheral;
7-
// TODO: This code works for all HSEM implemenations except for the STM32WBA52/4/5xx MCUs.
8+
// TODO: This code works for all HSEM implementations except for the STM32WBA52/4/5xx MCUs.
89
// Those MCUs have a different HSEM implementation (Secure semaphore lock support,
910
// Privileged / unprivileged semaphore lock support, Semaphore lock protection via semaphore attribute),
1011
// which is not yet supported by this code.
@@ -17,47 +18,135 @@ pub enum HsemError {
1718
LockFailed,
1819
}
1920

21+
/// HSEM identifier
22+
/// Copied from `hw_conf.h` of the STM32WB55 WPAN stack
23+
#[cfg(any(stm32wb))]
24+
#[derive(Debug, PartialEq, Eq, Clone, Copy, Hash)]
25+
#[repr(u8)]
26+
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
27+
pub enum HsemIdStm32Wb {
28+
/// Semaphore to lock the RNG access
29+
Rng = 0,
30+
/// Semaphore to lock the PKA access
31+
Pka = 1,
32+
/// Semaphore to lock the FLASH access
33+
Flash = 2,
34+
/// Semaphore to lock the RCC access
35+
Rcc = 3,
36+
/// Semaphore to synchronize the entry stop mode
37+
EntryStopMode = 4,
38+
/// Semaphore to lock the Clk48 access
39+
Clk48Config = 5,
40+
/// Semaphore to sync blockwise flash access CPU1
41+
BlockFlashRequestByCpu1 = 6,
42+
/// Semaphore to sync blockwise flash access CPU2
43+
BlockFlashRequestByCpu2 = 7,
44+
/// Semaphore to lock the BLE NVM access
45+
BleNvmSram = 8,
46+
/// Semaphore to lock the Thread NVM access
47+
ThreadNvmSram = 9,
48+
}
49+
50+
#[cfg(any(stm32wb))]
51+
impl From<HsemIdStm32Wb> for u8 {
52+
fn from(id: HsemIdStm32Wb) -> Self {
53+
id as u8
54+
}
55+
}
56+
2057
/// CPU core.
2158
/// The enum values are identical to the bus master IDs / core Ids defined for each
2259
/// chip family (i.e. stm32h747 see rm0399 table 95)
2360
#[derive(Debug, PartialEq, Eq, Clone, Copy, Hash)]
2461
#[repr(u8)]
2562
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
2663
pub enum CoreId {
64+
/// Main processor
65+
Core0,
66+
/// Coprocessor
67+
Core1,
68+
}
69+
70+
/// The core ID used in the HSEM_RLRx register.
71+
#[derive(Debug, PartialEq, Eq, Clone, Copy, Hash)]
72+
#[repr(u8)]
73+
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
74+
pub enum RlrCoreId {
75+
/// Main processor (Cortex M4) core ID
76+
#[cfg(any(stm32wb, stm32wl))]
77+
Core0 = 0x4,
78+
79+
/// Main processor (Cortex M7) core ID
2780
#[cfg(any(stm32h745, stm32h747, stm32h755, stm32h757))]
28-
/// Cortex-M7, core 1.
2981
Core0 = 0x3,
3082

83+
/// Coprocessor (Cortex M0) core ID
84+
#[cfg(any(stm32wb, stm32wl))]
85+
Core1 = 0x8,
86+
87+
/// Coprocessor (Cortex M4) core ID
3188
#[cfg(any(stm32h745, stm32h747, stm32h755, stm32h757))]
32-
/// Cortex-M4, core 2.
3389
Core1 = 0x1,
90+
}
3491

35-
#[cfg(not(any(stm32h745, stm32h747, stm32h755, stm32h757)))]
36-
/// Cortex-M4, core 1
37-
Core0 = 0x4,
92+
impl TryFrom<u8> for RlrCoreId {
93+
type Error = ();
3894

39-
#[cfg(any(stm32wb, stm32wl))]
40-
/// Cortex-M0+, core 2.
41-
Core1 = 0x8,
95+
fn try_from(value: u8) -> Result<Self, Self::Error> {
96+
#[cfg(any(stm32wb, stm32wl))]
97+
match value {
98+
0x4 => Ok(RlrCoreId::Core0),
99+
0x8 => Ok(RlrCoreId::Core1),
100+
_ => Err(()),
101+
}
102+
103+
#[cfg(any(stm32h745, stm32h747, stm32h755, stm32h757))]
104+
match value {
105+
0x3 => Ok(RlrCoreId::Core0),
106+
0x1 => Ok(RlrCoreId::Core1),
107+
_ => Err(()),
108+
}
109+
}
42110
}
43111

44-
/// Get the current core id
45-
/// This code assume that it is only executed on a Cortex-M M0+, M4 or M7 core.
112+
impl From<CoreId> for RlrCoreId {
113+
fn from(core: CoreId) -> Self {
114+
match core {
115+
CoreId::Core0 => RlrCoreId::Core0,
116+
CoreId::Core1 => RlrCoreId::Core1,
117+
}
118+
}
119+
}
120+
121+
/// Get the current core id.
46122
#[inline(always)]
47123
pub fn get_current_coreid() -> CoreId {
48-
let cpuid = unsafe { cortex_m::peripheral::CPUID::PTR.read_volatile().base.read() };
49-
match cpuid & 0x000000F0 {
50-
#[cfg(any(stm32wb, stm32wl))]
51-
0x0 => CoreId::Core1,
124+
const CPUID_PARTNO_MASK: u32 = 0x0000FFF0;
125+
// From the arm developer manual
126+
// https://developer.arm.com/documentation/ddi0439/b/System-Control/Register-descriptions/CPUID-Base-Register--CPUID
127+
#[allow(dead_code)]
128+
const CPUID_PARTNO_CORTEX_M4: u32 = 0x0000C240;
129+
#[allow(dead_code)]
130+
const CPUID_PARTNO_CORTEX_M7: u32 = 0x0000C270;
131+
#[allow(dead_code)]
132+
const CPUID_PARTNO_CORTEX_M0: u32 = 0x0000C600;
133+
// const CPUID_PARTNO_CORTEX_M33: u32 = 0x0000D210;
52134

53-
#[cfg(not(any(stm32h745, stm32h747, stm32h755, stm32h757)))]
54-
0x4 => CoreId::Core0,
135+
let cpuid = unsafe { cortex_m::peripheral::CPUID::PTR.read_volatile().base.read() };
55136

56-
#[cfg(any(stm32h745, stm32h747, stm32h755, stm32h757))]
57-
0x4 => CoreId::Core1,
137+
#[cfg(any(stm32wb, stm32wl))]
138+
// Cortex M4 as main processor and Cortex M0 as coprocessor
139+
match cpuid & CPUID_PARTNO_MASK {
140+
CPUID_PARTNO_CORTEX_M4 => CoreId::Core0,
141+
CPUID_PARTNO_CORTEX_M0 => CoreId::Core1,
142+
_ => panic!("Unknown Cortex-M core"),
143+
}
58144

59-
#[cfg(any(stm32h745, stm32h747, stm32h755, stm32h757))]
60-
0x7 => CoreId::Core0,
145+
#[cfg(any(stm32h745, stm32h747, stm32h755, stm32h757))]
146+
// Cortex M7 as main processor and Cortex M4 as coprocessor
147+
match cpuid & CPUID_PARTNO_MASK {
148+
CPUID_PARTNO_CORTEX_M7 => CoreId::Core0,
149+
CPUID_PARTNO_CORTEX_M4 => CoreId::Core1,
61150
_ => panic!("Unknown Cortex-M core"),
62151
}
63152
}
@@ -89,13 +178,13 @@ impl<'d, T: Instance> HardwareSemaphore<'d, T> {
89178
pub fn two_step_lock(&mut self, sem_id: u8, process_id: u8) -> Result<(), HsemError> {
90179
T::regs().r(sem_id as usize).write(|w| {
91180
w.set_procid(process_id);
92-
w.set_coreid(get_current_coreid() as u8);
181+
w.set_coreid(RlrCoreId::from(get_current_coreid()) as u8);
93182
w.set_lock(true);
94183
});
95184
let reg = T::regs().r(sem_id as usize).read();
96185
match (
97186
reg.lock(),
98-
reg.coreid() == get_current_coreid() as u8,
187+
reg.coreid() == RlrCoreId::from(get_current_coreid()) as u8,
99188
reg.procid() == process_id,
100189
) {
101190
(true, true, true) => Ok(()),
@@ -108,8 +197,13 @@ impl<'d, T: Instance> HardwareSemaphore<'d, T> {
108197
/// carried out from the HSEM_RLRx register.
109198
pub fn one_step_lock(&mut self, sem_id: u8) -> Result<(), HsemError> {
110199
let reg = T::regs().rlr(sem_id as usize).read();
111-
match (reg.lock(), reg.coreid() == get_current_coreid() as u8, reg.procid()) {
112-
(false, true, 0) => Ok(()),
200+
201+
match (
202+
reg.lock(),
203+
reg.coreid() == RlrCoreId::from(get_current_coreid()) as u8,
204+
reg.procid(),
205+
) {
206+
(true, true, 0) => Ok(()),
113207
_ => Err(HsemError::LockFailed),
114208
}
115209
}
@@ -120,7 +214,7 @@ impl<'d, T: Instance> HardwareSemaphore<'d, T> {
120214
pub fn unlock(&mut self, sem_id: u8, process_id: u8) {
121215
T::regs().r(sem_id as usize).write(|w| {
122216
w.set_procid(process_id);
123-
w.set_coreid(get_current_coreid() as u8);
217+
w.set_coreid(RlrCoreId::from(get_current_coreid()) as u8);
124218
w.set_lock(false);
125219
});
126220
}
@@ -129,10 +223,10 @@ impl<'d, T: Instance> HardwareSemaphore<'d, T> {
129223
/// All semaphores locked by a COREID can be unlocked at once by using the HSEM_CR
130224
/// register. Write COREID and correct KEY value in HSEM_CR. All locked semaphores with a
131225
/// matching COREID are unlocked, and may generate an interrupt when enabled.
132-
pub fn unlock_all(&mut self, key: u16, core_id: u8) {
226+
pub fn unlock_all(&mut self, key: u16, core_id: CoreId) {
133227
T::regs().cr().write(|w| {
134228
w.set_key(key);
135-
w.set_coreid(core_id);
229+
w.set_coreid(RlrCoreId::from(core_id) as u8);
136230
});
137231
}
138232

0 commit comments

Comments
 (0)