Skip to content

Commit e3034a7

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

File tree

2 files changed

+104
-31
lines changed

2 files changed

+104
-31
lines changed

embassy-stm32/src/hsem/mod.rs

Lines changed: 103 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ use embassy_hal_internal::PeripheralType;
44

55
use crate::pac;
66
use crate::rcc::RccPeripheral;
7-
// TODO: This code works for all HSEM implemenations except for the STM32WBA52/4/5xx MCUs.
7+
// TODO: This code works for all HSEM implementations except for the STM32WBA52/4/5xx MCUs.
88
// Those MCUs have a different HSEM implementation (Secure semaphore lock support,
99
// Privileged / unprivileged semaphore lock support, Semaphore lock protection via semaphore attribute),
1010
// which is not yet supported by this code.
@@ -17,47 +17,116 @@ pub enum HsemError {
1717
LockFailed,
1818
}
1919

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

82+
/// Coprocessor (Cortex M0) core ID
83+
#[cfg(any(stm32wb, stm32wl))]
84+
Core1 = 0x8,
85+
86+
/// Coprocessor (Cortex M4) core ID
3187
#[cfg(any(stm32h745, stm32h747, stm32h755, stm32h757))]
32-
/// Cortex-M4, core 2.
3388
Core1 = 0x1,
89+
}
3490

35-
#[cfg(not(any(stm32h745, stm32h747, stm32h755, stm32h757)))]
36-
/// Cortex-M4, core 1
37-
Core0 = 0x4,
38-
39-
#[cfg(any(stm32wb, stm32wl))]
40-
/// Cortex-M0+, core 2.
41-
Core1 = 0x8,
91+
#[cfg(any(stm32wb, stm32wl, stm32h745, stm32h747, stm32h755, stm32h757))]
92+
impl From<CoreId> for RlrCoreId {
93+
fn from(core: CoreId) -> Self {
94+
match core {
95+
CoreId::Core0 => RlrCoreId::Core0,
96+
CoreId::Core1 => RlrCoreId::Core1,
97+
}
98+
}
4299
}
43100

44-
/// Get the current core id
45-
/// This code assume that it is only executed on a Cortex-M M0+, M4 or M7 core.
101+
/// Get the current core id.
46102
#[inline(always)]
47103
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,
104+
const CPUID_PARTNO_MASK: u32 = 0x0000FFF0;
105+
// From the arm developer manual
106+
// https://developer.arm.com/documentation/ddi0439/b/System-Control/Register-descriptions/CPUID-Base-Register--CPUID
107+
#[allow(dead_code)]
108+
const CPUID_PARTNO_CORTEX_M4: u32 = 0x0000C240;
109+
#[allow(dead_code)]
110+
const CPUID_PARTNO_CORTEX_M7: u32 = 0x0000C270;
111+
#[allow(dead_code)]
112+
const CPUID_PARTNO_CORTEX_M0: u32 = 0x0000C600;
113+
// const CPUID_PARTNO_CORTEX_M33: u32 = 0x0000D210;
52114

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

56-
#[cfg(any(stm32h745, stm32h747, stm32h755, stm32h757))]
57-
0x4 => CoreId::Core1,
117+
#[cfg(any(stm32wb, stm32wl))]
118+
// Cortex M4 as main processor and Cortex M0 as coprocessor
119+
match cpuid & CPUID_PARTNO_MASK {
120+
CPUID_PARTNO_CORTEX_M4 => CoreId::Core0,
121+
CPUID_PARTNO_CORTEX_M0 => CoreId::Core1,
122+
_ => panic!("Unknown Cortex-M core"),
123+
}
58124

59-
#[cfg(any(stm32h745, stm32h747, stm32h755, stm32h757))]
60-
0x7 => CoreId::Core0,
125+
#[cfg(any(stm32h745, stm32h747, stm32h755, stm32h757))]
126+
// Cortex M7 as main processor and Cortex M4 as coprocessor
127+
match cpuid & CPUID_PARTNO_MASK {
128+
CPUID_PARTNO_CORTEX_M7 => CoreId::Core0,
129+
CPUID_PARTNO_CORTEX_M4 => CoreId::Core1,
61130
_ => panic!("Unknown Cortex-M core"),
62131
}
63132
}
@@ -67,7 +136,6 @@ pub fn get_current_coreid() -> CoreId {
67136
fn core_id_to_index(core: CoreId) -> usize {
68137
match core {
69138
CoreId::Core0 => 0,
70-
#[cfg(any(stm32h745, stm32h747, stm32h755, stm32h757, stm32wb, stm32wl))]
71139
CoreId::Core1 => 1,
72140
}
73141
}
@@ -89,13 +157,13 @@ impl<'d, T: Instance> HardwareSemaphore<'d, T> {
89157
pub fn two_step_lock(&mut self, sem_id: u8, process_id: u8) -> Result<(), HsemError> {
90158
T::regs().r(sem_id as usize).write(|w| {
91159
w.set_procid(process_id);
92-
w.set_coreid(get_current_coreid() as u8);
160+
w.set_coreid(RlrCoreId::from(get_current_coreid()) as u8);
93161
w.set_lock(true);
94162
});
95163
let reg = T::regs().r(sem_id as usize).read();
96164
match (
97165
reg.lock(),
98-
reg.coreid() == get_current_coreid() as u8,
166+
reg.coreid() == RlrCoreId::from(get_current_coreid()) as u8,
99167
reg.procid() == process_id,
100168
) {
101169
(true, true, true) => Ok(()),
@@ -108,8 +176,13 @@ impl<'d, T: Instance> HardwareSemaphore<'d, T> {
108176
/// carried out from the HSEM_RLRx register.
109177
pub fn one_step_lock(&mut self, sem_id: u8) -> Result<(), HsemError> {
110178
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(()),
179+
180+
match (
181+
reg.lock(),
182+
reg.coreid() == RlrCoreId::from(get_current_coreid()) as u8,
183+
reg.procid(),
184+
) {
185+
(true, true, 0) => Ok(()),
113186
_ => Err(HsemError::LockFailed),
114187
}
115188
}
@@ -120,7 +193,7 @@ impl<'d, T: Instance> HardwareSemaphore<'d, T> {
120193
pub fn unlock(&mut self, sem_id: u8, process_id: u8) {
121194
T::regs().r(sem_id as usize).write(|w| {
122195
w.set_procid(process_id);
123-
w.set_coreid(get_current_coreid() as u8);
196+
w.set_coreid(RlrCoreId::from(get_current_coreid()) as u8);
124197
w.set_lock(false);
125198
});
126199
}
@@ -129,10 +202,10 @@ impl<'d, T: Instance> HardwareSemaphore<'d, T> {
129202
/// All semaphores locked by a COREID can be unlocked at once by using the HSEM_CR
130203
/// register. Write COREID and correct KEY value in HSEM_CR. All locked semaphores with a
131204
/// matching COREID are unlocked, and may generate an interrupt when enabled.
132-
pub fn unlock_all(&mut self, key: u16, core_id: u8) {
205+
pub fn unlock_all(&mut self, key: u16, core_id: CoreId) {
133206
T::regs().cr().write(|w| {
134207
w.set_key(key);
135-
w.set_coreid(core_id);
208+
w.set_coreid(RlrCoreId::from(core_id) as u8);
136209
});
137210
}
138211

embassy-stm32/src/lib.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -81,7 +81,7 @@ pub mod fmc;
8181
pub mod hash;
8282
#[cfg(hrtim)]
8383
pub mod hrtim;
84-
#[cfg(hsem)]
84+
#[cfg(all(hsem, any(stm32wb, stm32wl, stm32h745, stm32h747, stm32h755, stm32h757)))]
8585
pub mod hsem;
8686
#[cfg(hspi)]
8787
pub mod hspi;

0 commit comments

Comments
 (0)