@@ -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,117 @@ 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
+ #[ cfg( any( stm32wb, stm32wl, stm32h745, stm32h747, stm32h755, stm32h757) ) ]
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
27
80
#[ cfg( any( stm32h745, stm32h747, stm32h755, stm32h757) ) ]
28
- /// Cortex-M7, core 1.
29
81
Core0 = 0x3 ,
30
82
83
+ /// Coprocessor (Cortex M0) core ID
84
+ #[ cfg( any( stm32wb, stm32wl) ) ]
85
+ Core1 = 0x8 ,
86
+
87
+ /// Coprocessor (Cortex M4) core ID
31
88
#[ cfg( any( stm32h745, stm32h747, stm32h755, stm32h757) ) ]
32
- /// Cortex-M4, core 2.
33
89
Core1 = 0x1 ,
90
+ }
34
91
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 ,
92
+ #[ cfg( any( stm32wb, stm32wl, stm32h745, stm32h747, stm32h755, stm32h757) ) ]
93
+ impl From < CoreId > for RlrCoreId {
94
+ fn from ( core : CoreId ) -> Self {
95
+ match core {
96
+ CoreId :: Core0 => RlrCoreId :: Core0 ,
97
+ CoreId :: Core1 => RlrCoreId :: Core1 ,
98
+ }
99
+ }
42
100
}
43
101
44
- /// Get the current core id
45
- /// This code assume that it is only executed on a Cortex-M M0+, M4 or M7 core.
102
+ /// Get the current core id.
46
103
#[ inline( always) ]
47
104
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 ,
105
+ const CPUID_PARTNO_MASK : u32 = 0x0000FFF0 ;
106
+ // From the arm developer manual
107
+ // https://developer.arm.com/documentation/ddi0439/b/System-Control/Register-descriptions/CPUID-Base-Register--CPUID
108
+ #[ allow( dead_code) ]
109
+ const CPUID_PARTNO_CORTEX_M4 : u32 = 0x0000C240 ;
110
+ #[ allow( dead_code) ]
111
+ const CPUID_PARTNO_CORTEX_M7 : u32 = 0x0000C270 ;
112
+ #[ allow( dead_code) ]
113
+ const CPUID_PARTNO_CORTEX_M0 : u32 = 0x0000C600 ;
114
+ // const CPUID_PARTNO_CORTEX_M33: u32 = 0x0000D210;
52
115
53
- #[ cfg( not( any( stm32h745, stm32h747, stm32h755, stm32h757) ) ) ]
54
- 0x4 => CoreId :: Core0 ,
116
+ let cpuid = unsafe { cortex_m:: peripheral:: CPUID :: PTR . read_volatile ( ) . base . read ( ) } ;
55
117
56
- #[ cfg( any( stm32h745, stm32h747, stm32h755, stm32h757) ) ]
57
- 0x4 => CoreId :: Core1 ,
118
+ #[ cfg( any( stm32wb, stm32wl) ) ]
119
+ // Cortex M4 as main processor and Cortex M0 as coprocessor
120
+ match cpuid & CPUID_PARTNO_MASK {
121
+ CPUID_PARTNO_CORTEX_M4 => CoreId :: Core0 ,
122
+ CPUID_PARTNO_CORTEX_M0 => CoreId :: Core1 ,
123
+ _ => panic ! ( "Unknown Cortex-M core" ) ,
124
+ }
58
125
59
- #[ cfg( any( stm32h745, stm32h747, stm32h755, stm32h757) ) ]
60
- 0x7 => CoreId :: Core0 ,
126
+ #[ cfg( any( stm32h745, stm32h747, stm32h755, stm32h757) ) ]
127
+ // Cortex M7 as main processor and Cortex M4 as coprocessor
128
+ match cpuid & CPUID_PARTNO_MASK {
129
+ CPUID_PARTNO_CORTEX_M7 => CoreId :: Core0 ,
130
+ CPUID_PARTNO_CORTEX_M4 => CoreId :: Core1 ,
61
131
_ => panic ! ( "Unknown Cortex-M core" ) ,
62
132
}
63
133
}
@@ -89,13 +159,13 @@ impl<'d, T: Instance> HardwareSemaphore<'d, T> {
89
159
pub fn two_step_lock ( & mut self , sem_id : u8 , process_id : u8 ) -> Result < ( ) , HsemError > {
90
160
T :: regs ( ) . r ( sem_id as usize ) . write ( |w| {
91
161
w. set_procid ( process_id) ;
92
- w. set_coreid ( get_current_coreid ( ) as u8 ) ;
162
+ w. set_coreid ( RlrCoreId :: from ( get_current_coreid ( ) ) as u8 ) ;
93
163
w. set_lock ( true ) ;
94
164
} ) ;
95
165
let reg = T :: regs ( ) . r ( sem_id as usize ) . read ( ) ;
96
166
match (
97
167
reg. lock ( ) ,
98
- reg. coreid ( ) == get_current_coreid ( ) as u8 ,
168
+ reg. coreid ( ) == RlrCoreId :: from ( get_current_coreid ( ) ) as u8 ,
99
169
reg. procid ( ) == process_id,
100
170
) {
101
171
( true , true , true ) => Ok ( ( ) ) ,
@@ -108,8 +178,13 @@ impl<'d, T: Instance> HardwareSemaphore<'d, T> {
108
178
/// carried out from the HSEM_RLRx register.
109
179
pub fn one_step_lock ( & mut self , sem_id : u8 ) -> Result < ( ) , HsemError > {
110
180
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 ( ( ) ) ,
181
+
182
+ match (
183
+ reg. lock ( ) ,
184
+ reg. coreid ( ) == RlrCoreId :: from ( get_current_coreid ( ) ) as u8 ,
185
+ reg. procid ( ) ,
186
+ ) {
187
+ ( true , true , 0 ) => Ok ( ( ) ) ,
113
188
_ => Err ( HsemError :: LockFailed ) ,
114
189
}
115
190
}
@@ -120,7 +195,7 @@ impl<'d, T: Instance> HardwareSemaphore<'d, T> {
120
195
pub fn unlock ( & mut self , sem_id : u8 , process_id : u8 ) {
121
196
T :: regs ( ) . r ( sem_id as usize ) . write ( |w| {
122
197
w. set_procid ( process_id) ;
123
- w. set_coreid ( get_current_coreid ( ) as u8 ) ;
198
+ w. set_coreid ( RlrCoreId :: from ( get_current_coreid ( ) ) as u8 ) ;
124
199
w. set_lock ( false ) ;
125
200
} ) ;
126
201
}
@@ -129,10 +204,10 @@ impl<'d, T: Instance> HardwareSemaphore<'d, T> {
129
204
/// All semaphores locked by a COREID can be unlocked at once by using the HSEM_CR
130
205
/// register. Write COREID and correct KEY value in HSEM_CR. All locked semaphores with a
131
206
/// matching COREID are unlocked, and may generate an interrupt when enabled.
132
- pub fn unlock_all ( & mut self , key : u16 , core_id : u8 ) {
207
+ pub fn unlock_all ( & mut self , key : u16 , core_id : CoreId ) {
133
208
T :: regs ( ) . cr ( ) . write ( |w| {
134
209
w. set_key ( key) ;
135
- w. set_coreid ( core_id) ;
210
+ w. set_coreid ( RlrCoreId :: from ( core_id) as u8 ) ;
136
211
} ) ;
137
212
}
138
213
0 commit comments