@@ -4,7 +4,7 @@ use embassy_hal_internal::PeripheralType;
4
4
5
5
use crate :: pac;
6
6
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.
8
8
// Those MCUs have a different HSEM implementation (Secure semaphore lock support,
9
9
// Privileged / unprivileged semaphore lock support, Semaphore lock protection via semaphore attribute),
10
10
// which is not yet supported by this code.
@@ -17,47 +17,116 @@ pub enum HsemError {
17
17
LockFailed ,
18
18
}
19
19
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
+
20
56
/// CPU core.
21
57
/// The enum values are identical to the bus master IDs / core Ids defined for each
22
58
/// chip family (i.e. stm32h747 see rm0399 table 95)
23
59
#[ derive( Debug , PartialEq , Eq , Clone , Copy , Hash ) ]
24
60
#[ repr( u8 ) ]
25
61
#[ cfg_attr( feature = "defmt" , derive( defmt:: Format ) ) ]
26
62
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
27
79
#[ cfg( any( stm32h745, stm32h747, stm32h755, stm32h757) ) ]
28
- /// Cortex-M7, core 1.
29
80
Core0 = 0x3 ,
30
81
82
+ /// Coprocessor (Cortex M0) core ID
83
+ #[ cfg( any( stm32wb, stm32wl) ) ]
84
+ Core1 = 0x8 ,
85
+
86
+ /// Coprocessor (Cortex M4) core ID
31
87
#[ cfg( any( stm32h745, stm32h747, stm32h755, stm32h757) ) ]
32
- /// Cortex-M4, core 2.
33
88
Core1 = 0x1 ,
89
+ }
34
90
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
+ }
42
99
}
43
100
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.
46
102
#[ inline( always) ]
47
103
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;
52
114
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 ( ) } ;
55
116
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
+ }
58
124
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 ,
61
130
_ => panic ! ( "Unknown Cortex-M core" ) ,
62
131
}
63
132
}
@@ -67,7 +136,6 @@ pub fn get_current_coreid() -> CoreId {
67
136
fn core_id_to_index ( core : CoreId ) -> usize {
68
137
match core {
69
138
CoreId :: Core0 => 0 ,
70
- #[ cfg( any( stm32h745, stm32h747, stm32h755, stm32h757, stm32wb, stm32wl) ) ]
71
139
CoreId :: Core1 => 1 ,
72
140
}
73
141
}
@@ -89,13 +157,13 @@ impl<'d, T: Instance> HardwareSemaphore<'d, T> {
89
157
pub fn two_step_lock ( & mut self , sem_id : u8 , process_id : u8 ) -> Result < ( ) , HsemError > {
90
158
T :: regs ( ) . r ( sem_id as usize ) . write ( |w| {
91
159
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 ) ;
93
161
w. set_lock ( true ) ;
94
162
} ) ;
95
163
let reg = T :: regs ( ) . r ( sem_id as usize ) . read ( ) ;
96
164
match (
97
165
reg. lock ( ) ,
98
- reg. coreid ( ) == get_current_coreid ( ) as u8 ,
166
+ reg. coreid ( ) == RlrCoreId :: from ( get_current_coreid ( ) ) as u8 ,
99
167
reg. procid ( ) == process_id,
100
168
) {
101
169
( true , true , true ) => Ok ( ( ) ) ,
@@ -108,8 +176,13 @@ impl<'d, T: Instance> HardwareSemaphore<'d, T> {
108
176
/// carried out from the HSEM_RLRx register.
109
177
pub fn one_step_lock ( & mut self , sem_id : u8 ) -> Result < ( ) , HsemError > {
110
178
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 ( ( ) ) ,
113
186
_ => Err ( HsemError :: LockFailed ) ,
114
187
}
115
188
}
@@ -120,7 +193,7 @@ impl<'d, T: Instance> HardwareSemaphore<'d, T> {
120
193
pub fn unlock ( & mut self , sem_id : u8 , process_id : u8 ) {
121
194
T :: regs ( ) . r ( sem_id as usize ) . write ( |w| {
122
195
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 ) ;
124
197
w. set_lock ( false ) ;
125
198
} ) ;
126
199
}
@@ -129,10 +202,10 @@ impl<'d, T: Instance> HardwareSemaphore<'d, T> {
129
202
/// All semaphores locked by a COREID can be unlocked at once by using the HSEM_CR
130
203
/// register. Write COREID and correct KEY value in HSEM_CR. All locked semaphores with a
131
204
/// 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 ) {
133
206
T :: regs ( ) . cr ( ) . write ( |w| {
134
207
w. set_key ( key) ;
135
- w. set_coreid ( core_id) ;
208
+ w. set_coreid ( RlrCoreId :: from ( core_id) as u8 ) ;
136
209
} ) ;
137
210
}
138
211
0 commit comments