Skip to content

Commit 98339a6

Browse files
committed
fix: core was not recognized and 1-step lock did not work
1 parent 9d62fba commit 98339a6

File tree

1 file changed

+174
-62
lines changed

1 file changed

+174
-62
lines changed

embassy-stm32/src/hsem/mod.rs

+174-62
Original file line numberDiff line numberDiff line change
@@ -4,71 +4,178 @@ 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.
1111
use crate::Peri;
1212

1313
/// HSEM error.
14-
#[derive(Debug)]
14+
#[derive(Debug, PartialEq, Eq, Clone, Copy, Hash)]
15+
#[repr(u8)]
16+
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
1517
pub enum HsemError {
1618
/// Locking the semaphore failed.
1719
LockFailed,
1820
}
1921

22+
/// HSEM identifier
23+
#[derive(Debug, PartialEq, Eq, Clone, Copy, Hash)]
24+
#[repr(u8)]
25+
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
26+
pub enum SemId {
27+
/// Semaphore 0
28+
Id0 = 0,
29+
/// Semaphore 1
30+
Id1 = 1,
31+
/// Semaphore 2
32+
Id2 = 2,
33+
/// Semaphore 3
34+
Id3 = 3,
35+
/// Semaphore 4
36+
Id4 = 4,
37+
/// Semaphore 5
38+
Id5 = 5,
39+
/// Semaphore 6
40+
Id6 = 6,
41+
/// Semaphore 7
42+
Id7 = 7,
43+
/// Semaphore 8
44+
Id8 = 8,
45+
/// Semaphore 9
46+
Id9 = 9,
47+
/// Semaphore 10
48+
Id10 = 10,
49+
/// Semaphore 11
50+
Id11 = 11,
51+
/// Semaphore 12
52+
Id12 = 12,
53+
/// Semaphore 13
54+
Id13 = 13,
55+
/// Semaphore 14
56+
Id14 = 14,
57+
/// Semaphore 15
58+
Id15 = 15,
59+
/// Semaphore 16
60+
Id16 = 16,
61+
/// Semaphore 17
62+
Id17 = 17,
63+
/// Semaphore 18
64+
Id18 = 18,
65+
/// Semaphore 19
66+
Id19 = 19,
67+
/// Semaphore 20
68+
Id20 = 20,
69+
/// Semaphore 21
70+
Id21 = 21,
71+
/// Semaphore 22
72+
Id22 = 22,
73+
/// Semaphore 23
74+
Id23 = 23,
75+
/// Semaphore 24
76+
Id24 = 24,
77+
/// Semaphore 25
78+
Id25 = 25,
79+
/// Semaphore 26
80+
Id26 = 26,
81+
/// Semaphore 27
82+
Id27 = 27,
83+
/// Semaphore 28
84+
Id28 = 28,
85+
/// Semaphore 29
86+
Id29 = 29,
87+
/// Semaphore 30
88+
Id30 = 30,
89+
/// Semaphore 31
90+
Id31 = 31,
91+
}
92+
93+
impl From<SemId> for usize {
94+
fn from(id: SemId) -> Self {
95+
id as usize
96+
}
97+
}
98+
2099
/// CPU core.
21100
/// The enum values are identical to the bus master IDs / core Ids defined for each
22101
/// chip family (i.e. stm32h747 see rm0399 table 95)
23102
#[derive(Debug, PartialEq, Eq, Clone, Copy, Hash)]
24103
#[repr(u8)]
25104
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
26105
pub enum CoreId {
27-
#[cfg(any(stm32h745, stm32h747, stm32h755, stm32h757))]
28-
/// Cortex-M7, core 1.
29-
Core0 = 0x3,
106+
/// Main processor
107+
Core0 = 0,
108+
/// Coprocessor
109+
Core1,
110+
}
30111

31-
#[cfg(any(stm32h745, stm32h747, stm32h755, stm32h757))]
32-
/// Cortex-M4, core 2.
33-
Core1 = 0x1,
112+
impl From<CoreId> for usize {
113+
fn from(core: CoreId) -> Self {
114+
core as usize
115+
}
116+
}
34117

35-
#[cfg(not(any(stm32h745, stm32h747, stm32h755, stm32h757)))]
36-
/// Cortex-M4, core 1
37-
Core0 = 0x4,
118+
/// The core ID used in the HSEM_RLRx register.
119+
#[derive(Debug, PartialEq, Eq, Clone, Copy, Hash)]
120+
#[repr(u8)]
121+
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
122+
pub enum RlrCoreId {
123+
#[cfg(any(stm32h7a3, stm32h7b3, stm32h7b0))]
124+
/// Cortex-M7, core 1. MASTERID = 1
125+
Core0 = 1,
38126

39-
#[cfg(any(stm32wb, stm32wl))]
40-
/// Cortex-M0+, core 2.
41-
Core1 = 0x8,
42-
}
127+
#[cfg(any(
128+
stm32h723, stm32h725, stm32h730, stm32h733, stm32h735, stm32h742, stm32h743, stm32h745, stm32h747, stm32h750,
129+
stm32h753, stm32h755, stm32h757,
130+
))]
131+
/// Cortex-M7, core 1. MASTERID = 3
132+
Core0 = 3,
43133

44-
/// Get the current core id
45-
/// This code assume that it is only executed on a Cortex-M M0+, M4 or M7 core.
46-
#[inline(always)]
47-
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,
134+
#[cfg(any(stm32wb, stm32wl))]
135+
/// Cortex-M4, core 1
136+
Core0 = 4,
52137

53-
#[cfg(not(any(stm32h745, stm32h747, stm32h755, stm32h757)))]
54-
0x4 => CoreId::Core0,
138+
#[cfg(not(any(stm32wb, stm32wl, stm32h7a3, stm32h7b3, stm32h7b0)))]
139+
/// Cortex-M4, core 2
140+
Core1 = 1,
55141

56-
#[cfg(any(stm32h745, stm32h747, stm32h755, stm32h757))]
57-
0x4 => CoreId::Core1,
142+
#[cfg(any(stm32wb, stm32wl))]
143+
/// Cortex M0+, core 2
144+
Core1 = 8,
145+
}
58146

59-
#[cfg(any(stm32h745, stm32h747, stm32h755, stm32h757))]
60-
0x7 => CoreId::Core0,
61-
_ => panic!("Unknown Cortex-M core"),
147+
impl From<CoreId> for RlrCoreId {
148+
#[rustfmt::skip]
149+
fn from(core: CoreId) -> Self {
150+
match core {
151+
#[cfg(any(
152+
any(
153+
stm32h723, stm32h725, stm32h730, stm32h733, stm32h735, stm32h742, stm32h743, stm32h745, stm32h747, stm32h750,
154+
stm32h753, stm32h755, stm32h757,
155+
),
156+
any(stm32wb, stm32wl))
157+
)]
158+
CoreId::Core0 => RlrCoreId::Core0,
159+
#[cfg(any(
160+
not(any(stm32wb, stm32wl, stm32h7a3, stm32h7b3, stm32h7b0)),
161+
any(stm32wb, stm32wl))
162+
)]
163+
CoreId::Core1 => RlrCoreId::Core1,
164+
}
62165
}
63166
}
64167

65-
/// Translates the core ID to an index into the interrupt registers.
66-
#[inline(always)]
67-
fn core_id_to_index(core: CoreId) -> usize {
68-
match core {
69-
CoreId::Core0 => 0,
70-
#[cfg(any(stm32h745, stm32h747, stm32h755, stm32h757, stm32wb, stm32wl))]
71-
CoreId::Core1 => 1,
168+
impl CoreId {
169+
/// Returns the ID of the current running core.
170+
pub fn get_current() -> Self {
171+
#[cfg(any(
172+
all(stm32wl, not(feature = "_core-cm0p")),
173+
all(not(stm32wl), any(feature = "_core-cm7", not(feature = "_core-cm4"))),
174+
))]
175+
return CoreId::Core0;
176+
177+
#[cfg(any(all(not(stm32wl), feature = "_core-cm4"), all(stm32wl, feature = "_core-cm0p")))]
178+
return CoreId::Core1;
72179
}
73180
}
74181

@@ -86,16 +193,16 @@ impl<'d, T: Instance> HardwareSemaphore<'d, T> {
86193
/// Locks the semaphore.
87194
/// The 2-step lock procedure consists in a write to lock the semaphore, followed by a read to
88195
/// check if the lock has been successful, carried out from the HSEM_Rx register.
89-
pub fn two_step_lock(&mut self, sem_id: u8, process_id: u8) -> Result<(), HsemError> {
90-
T::regs().r(sem_id as usize).write(|w| {
196+
pub fn two_step_lock(&mut self, sem_id: SemId, process_id: u8) -> Result<(), HsemError> {
197+
T::regs().r(sem_id.into()).write(|w| {
91198
w.set_procid(process_id);
92-
w.set_coreid(get_current_coreid() as u8);
199+
w.set_coreid(RlrCoreId::from(CoreId::get_current()) as u8);
93200
w.set_lock(true);
94201
});
95-
let reg = T::regs().r(sem_id as usize).read();
202+
let reg = T::regs().r(sem_id.into()).read();
96203
match (
97204
reg.lock(),
98-
reg.coreid() == get_current_coreid() as u8,
205+
reg.coreid() == RlrCoreId::from(CoreId::get_current()) as u8,
99206
reg.procid() == process_id,
100207
) {
101208
(true, true, true) => Ok(()),
@@ -106,21 +213,28 @@ impl<'d, T: Instance> HardwareSemaphore<'d, T> {
106213
/// Locks the semaphore.
107214
/// The 1-step procedure consists in a read to lock and check the semaphore in a single step,
108215
/// carried out from the HSEM_RLRx register.
109-
pub fn one_step_lock(&mut self, sem_id: u8) -> Result<(), HsemError> {
110-
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(()),
216+
pub fn one_step_lock(&mut self, sem_id: SemId) -> Result<(), HsemError> {
217+
let reg = T::regs().rlr(sem_id.into()).read();
218+
219+
match (
220+
reg.lock(),
221+
reg.coreid() == RlrCoreId::from(CoreId::get_current()) as u8,
222+
reg.procid(),
223+
) {
224+
(true, true, 0) => Ok(()),
113225
_ => Err(HsemError::LockFailed),
114226
}
115227
}
116228

117229
/// Unlocks the semaphore.
118230
/// Unlocking a semaphore is a protected process, to prevent accidental clearing by a AHB bus
119231
/// core ID or by a process not having the semaphore lock right.
120-
pub fn unlock(&mut self, sem_id: u8, process_id: u8) {
121-
T::regs().r(sem_id as usize).write(|w| {
232+
pub fn unlock(&mut self, sem_id: SemId, process_id: Option<u8>) {
233+
let process_id = process_id.unwrap_or(0);
234+
235+
T::regs().r(sem_id.into()).write(|w| {
122236
w.set_procid(process_id);
123-
w.set_coreid(get_current_coreid() as u8);
237+
w.set_coreid(RlrCoreId::from(CoreId::get_current()) as u8);
124238
w.set_lock(false);
125239
});
126240
}
@@ -129,16 +243,16 @@ impl<'d, T: Instance> HardwareSemaphore<'d, T> {
129243
/// All semaphores locked by a COREID can be unlocked at once by using the HSEM_CR
130244
/// register. Write COREID and correct KEY value in HSEM_CR. All locked semaphores with a
131245
/// matching COREID are unlocked, and may generate an interrupt when enabled.
132-
pub fn unlock_all(&mut self, key: u16, core_id: u8) {
246+
pub fn unlock_all(&mut self, key: u16, core_id: CoreId) {
133247
T::regs().cr().write(|w| {
134248
w.set_key(key);
135-
w.set_coreid(core_id);
249+
w.set_coreid(RlrCoreId::from(core_id) as u8);
136250
});
137251
}
138252

139253
/// Checks if the semaphore is locked.
140-
pub fn is_semaphore_locked(&self, sem_id: u8) -> bool {
141-
T::regs().r(sem_id as usize).read().lock()
254+
pub fn is_semaphore_locked(&self, sem_id: SemId) -> bool {
255+
T::regs().r(sem_id.into()).read().lock()
142256
}
143257

144258
/// Sets the clear (unlock) key
@@ -152,22 +266,20 @@ impl<'d, T: Instance> HardwareSemaphore<'d, T> {
152266
}
153267

154268
/// Sets the interrupt enable bit for the semaphore.
155-
pub fn enable_interrupt(&mut self, core_id: CoreId, sem_x: usize, enable: bool) {
269+
pub fn enable_interrupt(&mut self, core_id: CoreId, sem_id: SemId, enable: bool) {
156270
T::regs()
157-
.ier(core_id_to_index(core_id))
158-
.modify(|w| w.set_ise(sem_x, enable));
271+
.ier(core_id.into())
272+
.modify(|w| w.set_ise(sem_id.into(), enable));
159273
}
160274

161275
/// Gets the interrupt flag for the semaphore.
162-
pub fn is_interrupt_active(&mut self, core_id: CoreId, sem_x: usize) -> bool {
163-
T::regs().isr(core_id_to_index(core_id)).read().isf(sem_x)
276+
pub fn is_interrupt_active(&mut self, core_id: CoreId, sem_id: SemId) -> bool {
277+
T::regs().isr(core_id.into()).read().isf(sem_id.into())
164278
}
165279

166280
/// Clears the interrupt flag for the semaphore.
167-
pub fn clear_interrupt(&mut self, core_id: CoreId, sem_x: usize) {
168-
T::regs()
169-
.icr(core_id_to_index(core_id))
170-
.write(|w| w.set_isc(sem_x, false));
281+
pub fn clear_interrupt(&mut self, core_id: CoreId, sem_id: SemId) {
282+
T::regs().icr(core_id.into()).write(|w| w.set_isc(sem_id.into(), false));
171283
}
172284
}
173285

0 commit comments

Comments
 (0)