aboutsummaryrefslogtreecommitdiff
path: root/embassy-stm32-wpan
diff options
context:
space:
mode:
Diffstat (limited to 'embassy-stm32-wpan')
-rw-r--r--embassy-stm32-wpan/Cargo.toml2
-rw-r--r--embassy-stm32-wpan/src/wba/linklayer_plat.rs1062
2 files changed, 418 insertions, 646 deletions
diff --git a/embassy-stm32-wpan/Cargo.toml b/embassy-stm32-wpan/Cargo.toml
index 9624c7932..6ae2612dd 100644
--- a/embassy-stm32-wpan/Cargo.toml
+++ b/embassy-stm32-wpan/Cargo.toml
@@ -57,7 +57,7 @@ wb55 = []
57wb55_ble = ["dep:stm32wb-hci"] 57wb55_ble = ["dep:stm32wb-hci"]
58wb55_mac = ["dep:bitflags", "dep:embassy-net-driver", "dep:smoltcp", "smoltcp/medium-ieee802154"] 58wb55_mac = ["dep:bitflags", "dep:embassy-net-driver", "dep:smoltcp", "smoltcp/medium-ieee802154"]
59 59
60wba = [ "dep:stm32-bindings" ] 60wba = [ "dep:stm32-bindings", "dep:embassy-time" ]
61wba_ble = [ "stm32-bindings/wba_wpan_mac" , "stm32-bindings/wba_wpan" ] 61wba_ble = [ "stm32-bindings/wba_wpan_mac" , "stm32-bindings/wba_wpan" ]
62wba_mac = [ "stm32-bindings/wba_wpan_mac", "stm32-bindings/wba_wpan_ble" , "stm32-bindings/lib_wba5_linklayer15_4", "stm32-bindings/lib_wba_mac_lib" , "stm32-bindings/wba_wpan" ] 62wba_mac = [ "stm32-bindings/wba_wpan_mac", "stm32-bindings/wba_wpan_ble" , "stm32-bindings/lib_wba5_linklayer15_4", "stm32-bindings/lib_wba_mac_lib" , "stm32-bindings/wba_wpan" ]
63 63
diff --git a/embassy-stm32-wpan/src/wba/linklayer_plat.rs b/embassy-stm32-wpan/src/wba/linklayer_plat.rs
index c011b3bcb..f53783666 100644
--- a/embassy-stm32-wpan/src/wba/linklayer_plat.rs
+++ b/embassy-stm32-wpan/src/wba/linklayer_plat.rs
@@ -1,645 +1,417 @@
1#[allow(dead_code)] 1#![cfg(feature = "wba")]
2fn test_fn() {} 2#![allow(clippy::missing_safety_doc)]
3 3
4// /* USER CODE BEGIN Header */ 4use core::hint::spin_loop;
5// /** 5use core::ptr;
6// ****************************************************************************** 6use core::sync::atomic::{AtomicBool, AtomicI32, AtomicPtr, AtomicU32, Ordering};
7// * @file linklayer_plat.c 7
8// * @author MCD Application Team 8use cortex_m::asm::{dsb, isb};
9// * @brief Source file for the linklayer plateform adaptation layer 9use cortex_m::interrupt::InterruptNumber;
10// ****************************************************************************** 10use cortex_m::peripheral::NVIC;
11// * @attention 11use cortex_m::register::{basepri, primask};
12// * 12use embassy_stm32::NVIC_PRIO_BITS;
13// * Copyright (c) 2024 STMicroelectronics. 13use embassy_time::{Duration, block_for};
14// * All rights reserved. 14
15// * 15use super::bindings::{link_layer, mac};
16// * This software is licensed under terms that can be found in the LICENSE file 16
17// * in the root directory of this software component. 17// Missing constant from stm32-bindings - RADIO_SW_LOW interrupt number
18// * If no LICENSE file comes with this software, it is provided AS-IS. 18// For STM32WBA, this is typically RADIO_IRQ_BUSY (interrupt 43)
19// * 19const RADIO_SW_LOW_INTR_NUM: u32 = 43;
20// ****************************************************************************** 20
21// */ 21type Callback = unsafe extern "C" fn();
22// /* USER CODE END Header */ 22
23// 23#[derive(Clone, Copy, Debug, Eq, PartialEq)]
24// #include "stm32wbaxx_hal.h" 24#[repr(transparent)]
25// #include "stm32wbaxx_hal_conf.h" 25struct RawInterrupt(u16);
26// #include "stm32wbaxx_ll_rcc.h" 26
27// 27impl RawInterrupt {
28// #include "app_common.h" 28 #[inline(always)]
29// #include "app_conf.h" 29 fn new(irq: u32) -> Self {
30// #include "linklayer_plat.h" 30 debug_assert!(irq <= u16::MAX as u32);
31// #include "scm.h" 31 Self(irq as u16)
32// #include "log_module.h" 32 }
33// #if (USE_TEMPERATURE_BASED_RADIO_CALIBRATION == 1) 33}
34// #include "adc_ctrl.h" 34
35// #endif /* (USE_TEMPERATURE_BASED_RADIO_CALIBRATION == 1) */ 35impl From<u32> for RawInterrupt {
36// 36 #[inline(always)]
37// #if (CFG_LPM_LEVEL != 0) 37 fn from(value: u32) -> Self {
38// #include "stm32_lpm.h" 38 Self::new(value)
39// #include "stm32_lpm_if.h" 39 }
40// #endif /* (CFG_LPM_LEVEL != 0) */ 40}
41// 41
42// /* USER CODE BEGIN Includes */ 42unsafe impl InterruptNumber for RawInterrupt {
43// 43 fn number(self) -> u16 {
44// /* USER CODE END Includes */ 44 self.0
45// 45 }
46// #define max(a,b) ((a) > (b) ? a : b) 46}
47// 47
48// /* 2.4GHz RADIO ISR callbacks */ 48static RADIO_CALLBACK: AtomicPtr<()> = AtomicPtr::new(ptr::null_mut());
49// void (*radio_callback)(void) = NULL; 49static LOW_ISR_CALLBACK: AtomicPtr<()> = AtomicPtr::new(ptr::null_mut());
50// void (*low_isr_callback)(void) = NULL; 50
51// 51static IRQ_COUNTER: AtomicI32 = AtomicI32::new(0);
52// /* RNG handle */ 52static PRIMASK_SNAPSHOT: AtomicU32 = AtomicU32::new(0);
53// extern RNG_HandleTypeDef hrng; 53
54// 54static PRIO_HIGH_ISR_COUNTER: AtomicI32 = AtomicI32::new(0);
55// #if (USE_TEMPERATURE_BASED_RADIO_CALIBRATION == 1) 55static PRIO_LOW_ISR_COUNTER: AtomicI32 = AtomicI32::new(0);
56// /* Link Layer temperature request from background */ 56static PRIO_SYS_ISR_COUNTER: AtomicI32 = AtomicI32::new(0);
57// extern void ll_sys_bg_temperature_measurement(void); 57static LOCAL_BASEPRI_VALUE: AtomicU32 = AtomicU32::new(0);
58// #endif /* (USE_TEMPERATURE_BASED_RADIO_CALIBRATION == 1) */ 58
59// 59static RADIO_SW_LOW_ISR_RUNNING_HIGH_PRIO: AtomicBool = AtomicBool::new(false);
60// /* Radio critical sections */ 60static AHB5_SWITCHED_OFF: AtomicBool = AtomicBool::new(false);
61// static uint32_t primask_bit = 0; 61static RADIO_SLEEP_TIMER_VAL: AtomicU32 = AtomicU32::new(0);
62// volatile int32_t prio_high_isr_counter = 0; 62
63// volatile int32_t prio_low_isr_counter = 0; 63static PRNG_STATE: AtomicU32 = AtomicU32::new(0);
64// volatile int32_t prio_sys_isr_counter = 0; 64static PRNG_INIT: AtomicBool = AtomicBool::new(false);
65// volatile int32_t irq_counter = 0; 65
66// volatile uint32_t local_basepri_value = 0; 66unsafe extern "C" {
67// 67 static SystemCoreClock: u32;
68// /* Radio SW low ISR global variable */ 68}
69// volatile uint8_t radio_sw_low_isr_is_running_high_prio = 0; 69
70// 70#[inline(always)]
71// /* Radio bus clock control variables */ 71fn read_system_core_clock() -> u32 {
72// uint8_t AHB5_SwitchedOff = 0; 72 unsafe { ptr::read_volatile(&SystemCoreClock) }
73// uint32_t radio_sleep_timer_val = 0; 73}
74// 74
75// /** 75#[inline(always)]
76// * @brief Configure the necessary clock sources for the radio. 76fn store_callback(slot: &AtomicPtr<()>, cb: Option<Callback>) {
77// * @param None 77 let ptr = cb.map_or(ptr::null_mut(), |f| f as *mut ());
78// * @retval None 78 slot.store(ptr, Ordering::Release);
79// */ 79}
80// void LINKLAYER_PLAT_ClockInit() 80
81// { 81#[inline(always)]
82// uint32_t linklayer_slp_clk_src = LL_RCC_RADIOSLEEPSOURCE_NONE; 82fn load_callback(slot: &AtomicPtr<()>) -> Option<Callback> {
83// 83 let ptr = slot.load(Ordering::Acquire);
84// /* Get the Link Layer sleep timer clock source */ 84 if ptr.is_null() {
85// linklayer_slp_clk_src = LL_RCC_RADIO_GetSleepTimerClockSource(); 85 None
86// if(linklayer_slp_clk_src == LL_RCC_RADIOSLEEPSOURCE_NONE) 86 } else {
87// { 87 Some(unsafe { core::mem::transmute::<*mut (), Callback>(ptr) })
88// /* If there is no clock source defined, should be selected before */ 88 }
89// assert_param(0); 89}
90// } 90
91// 91#[inline(always)]
92// /* Enable AHB5ENR peripheral clock (bus CLK) */ 92fn priority_shift() -> u8 {
93// __HAL_RCC_RADIO_CLK_ENABLE(); 93 8 - NVIC_PRIO_BITS as u8
94// } 94}
95// 95
96// /** 96fn pack_priority(raw: u32) -> u8 {
97// * @brief Link Layer active waiting loop. 97 let shift = priority_shift();
98// * @param delay: delay in us 98 let priority_bits = NVIC_PRIO_BITS as u32;
99// * @retval None 99 let mask = if priority_bits >= 32 {
100// */ 100 u32::MAX
101// void LINKLAYER_PLAT_DelayUs(uint32_t delay) 101 } else {
102// { 102 (1u32 << priority_bits) - 1
103// static uint8_t lock = 0; 103 };
104// uint32_t t0; 104 let clamped = raw & mask;
105// uint32_t primask_bit; 105 (clamped << u32::from(shift)) as u8
106// 106}
107// /* Enter critical section */ 107
108// primask_bit= __get_PRIMASK(); 108#[inline(always)]
109// __disable_irq(); 109fn counter_release(counter: &AtomicI32) -> bool {
110// 110 counter.fetch_sub(1, Ordering::SeqCst) <= 1
111// if (lock == 0U) 111}
112// { 112
113// /* Initialize counter */ 113#[inline(always)]
114// /* Reset cycle counter to prevent overflow 114fn counter_acquire(counter: &AtomicI32) -> bool {
115// As a us counter, it is assumed than even with re-entrancy, 115 counter.fetch_add(1, Ordering::SeqCst) == 0
116// overflow will never happen before re-initializing this counter */ 116}
117// DWT->CYCCNT = 0U; 117
118// /* Enable DWT by safety but should be useless (as already set) */ 118unsafe fn nvic_enable(irq: u32) {
119// SET_BIT(DCB->DEMCR, DCB_DEMCR_TRCENA_Msk); 119 NVIC::unmask(RawInterrupt::new(irq));
120// /* Enable counter */ 120 dsb();
121// SET_BIT(DWT->CTRL, DWT_CTRL_CYCCNTENA_Msk); 121 isb();
122// } 122}
123// /* Increment 're-entrance' counter */ 123
124// lock++; 124unsafe fn nvic_disable(irq: u32) {
125// /* Get starting time stamp */ 125 NVIC::mask(RawInterrupt::new(irq));
126// t0 = DWT->CYCCNT; 126 dsb();
127// /* Exit critical section */ 127 isb();
128// __set_PRIMASK(primask_bit); 128}
129// 129
130// /* Turn us into cycles */ 130unsafe fn nvic_set_pending(irq: u32) {
131// delay = delay * (SystemCoreClock / 1000000U); 131 NVIC::pend(RawInterrupt::new(irq));
132// delay += t0; 132 dsb();
133// 133 isb();
134// /* Busy waiting loop */ 134}
135// while (DWT->CYCCNT < delay) 135
136// { 136unsafe fn nvic_get_active(irq: u32) -> bool {
137// }; 137 NVIC::is_active(RawInterrupt::new(irq))
138// 138}
139// /* Enter critical section */ 139
140// primask_bit= __get_PRIMASK(); 140unsafe fn nvic_set_priority(irq: u32, priority: u8) {
141// __disable_irq(); 141 // STM32WBA is ARMv8-M, which uses byte-accessible IPR registers
142// if (lock == 1U) 142 let nvic = &*NVIC::PTR;
143// { 143 nvic.ipr[irq as usize].write(priority);
144// /* Disable counter */ 144
145// CLEAR_BIT(DWT->CTRL, DWT_CTRL_CYCCNTENA_Msk); 145 dsb();
146// } 146 isb();
147// /* Decrement 're-entrance' counter */ 147}
148// lock--; 148
149// /* Exit critical section */ 149#[inline(always)]
150// __set_PRIMASK(primask_bit); 150fn set_basepri_max(value: u8) {
151// 151 unsafe {
152// } 152 if basepri::read() < value {
153// 153 basepri::write(value);
154// /** 154 }
155// * @brief Link Layer assertion API 155 }
156// * @param condition: conditional statement to be checked. 156}
157// * @retval None 157
158// */ 158fn prng_next() -> u32 {
159// void LINKLAYER_PLAT_Assert(uint8_t condition) 159 #[inline]
160// { 160 fn xorshift(mut x: u32) -> u32 {
161// assert_param(condition); 161 x ^= x << 13;
162// } 162 x ^= x >> 17;
163// 163 x ^= x << 5;
164// /** 164 x
165// * @brief Enable/disable the Link Layer active clock (baseband clock). 165 }
166// * @param enable: boolean value to enable (1) or disable (0) the clock. 166
167// * @retval None 167 if !PRNG_INIT.load(Ordering::Acquire) {
168// */ 168 let seed = unsafe {
169// void LINKLAYER_PLAT_WaitHclkRdy(void) 169 let timer = link_layer::ll_intf_cmn_get_slptmr_value();
170// { 170 let core_clock = read_system_core_clock();
171// /* Wait on radio bus clock readiness if it has been turned of */ 171 timer ^ core_clock ^ 0x6C8E_9CF5
172// if (AHB5_SwitchedOff == 1) 172 };
173// { 173 PRNG_STATE.store(seed, Ordering::Relaxed);
174// AHB5_SwitchedOff = 0; 174 PRNG_INIT.store(true, Ordering::Release);
175// while (radio_sleep_timer_val == ll_intf_cmn_get_slptmr_value()); 175 }
176// } 176
177// } 177 let mut current = PRNG_STATE.load(Ordering::Relaxed);
178// 178 loop {
179// /** 179 let next = xorshift(current);
180// * @brief Notify the Link Layer platform layer the system will enter in WFI 180 match PRNG_STATE.compare_exchange_weak(current, next, Ordering::AcqRel, Ordering::Relaxed) {
181// * and AHB5 clock may be turned of regarding the 2.4Ghz radio state. 181 Ok(_) => return next,
182// * @param None 182 Err(v) => current = v,
183// * @retval None 183 }
184// */ 184 }
185// void LINKLAYER_PLAT_NotifyWFIEnter(void) 185}
186// { 186
187// /* Check if Radio state will allow the AHB5 clock to be cut */ 187pub unsafe fn run_radio_high_isr() {
188// 188 if let Some(cb) = load_callback(&RADIO_CALLBACK) {
189// /* AHB5 clock will be cut in the following cases: 189 cb();
190// * - 2.4GHz radio is not in ACTIVE mode (in SLEEP or DEEPSLEEP mode). 190 }
191// * - RADIOSMEN and STRADIOCLKON bits are at 0. 191}
192// */ 192
193// if((LL_PWR_GetRadioMode() != LL_PWR_RADIO_ACTIVE_MODE) || 193pub unsafe fn run_radio_sw_low_isr() {
194// ((__HAL_RCC_RADIO_IS_CLK_SLEEP_ENABLED() == 0) && (LL_RCC_RADIO_IsEnabledSleepTimerClock() == 0))) 194 if let Some(cb) = load_callback(&LOW_ISR_CALLBACK) {
195// { 195 cb();
196// AHB5_SwitchedOff = 1; 196 }
197// } 197
198// } 198 if RADIO_SW_LOW_ISR_RUNNING_HIGH_PRIO.swap(false, Ordering::AcqRel) {
199// 199 nvic_set_priority(RADIO_SW_LOW_INTR_NUM, pack_priority(mac::RADIO_SW_LOW_INTR_PRIO));
200// /** 200 }
201// * @brief Notify the Link Layer platform layer the system exited WFI and AHB5 201}
202// * clock may be resynchronized as is may have been turned of during 202
203// * low power mode entry. 203#[unsafe(no_mangle)]
204// * @param None 204pub unsafe extern "C" fn LINKLAYER_PLAT_ClockInit() {
205// * @retval None 205 let _ = link_layer::ll_intf_cmn_get_slptmr_value();
206// */ 206}
207// void LINKLAYER_PLAT_NotifyWFIExit(void) 207
208// { 208#[unsafe(no_mangle)]
209// /* Check if AHB5 clock has been turned of and needs resynchronisation */ 209pub unsafe extern "C" fn LINKLAYER_PLAT_DelayUs(delay: u32) {
210// if (AHB5_SwitchedOff) 210 block_for(Duration::from_micros(u64::from(delay)));
211// { 211}
212// /* Read sleep register as earlier as possible */ 212
213// radio_sleep_timer_val = ll_intf_cmn_get_slptmr_value(); 213#[unsafe(no_mangle)]
214// } 214pub unsafe extern "C" fn LINKLAYER_PLAT_Assert(condition: u8) {
215// } 215 if condition == 0 {
216// 216 panic!("LINKLAYER_PLAT assertion failed");
217// /** 217 }
218// * @brief Active wait on bus clock readiness. 218}
219// * @param None 219
220// * @retval None 220#[unsafe(no_mangle)]
221// */ 221pub unsafe extern "C" fn LINKLAYER_PLAT_WaitHclkRdy() {
222// void LINKLAYER_PLAT_AclkCtrl(uint8_t enable) 222 if AHB5_SWITCHED_OFF.swap(false, Ordering::AcqRel) {
223// { 223 let reference = RADIO_SLEEP_TIMER_VAL.load(Ordering::Acquire);
224// if(enable != 0u) 224 while reference == link_layer::ll_intf_cmn_get_slptmr_value() {
225// { 225 spin_loop();
226// #if (CFG_SCM_SUPPORTED == 1) 226 }
227// /* SCM HSE BEGIN */ 227 }
228// /* Polling on HSE32 activation */ 228}
229// SCM_HSE_WaitUntilReady(); 229
230// /* Enable RADIO baseband clock (active CLK) */ 230#[unsafe(no_mangle)]
231// HAL_RCCEx_EnableRadioBBClock(); 231pub unsafe extern "C" fn LINKLAYER_PLAT_NotifyWFIEnter() {
232// /* SCM HSE END */ 232 AHB5_SWITCHED_OFF.store(true, Ordering::Release);
233// #else 233}
234// /* Enable RADIO baseband clock (active CLK) */ 234
235// HAL_RCCEx_EnableRadioBBClock(); 235#[unsafe(no_mangle)]
236// /* Polling on HSE32 activation */ 236pub unsafe extern "C" fn LINKLAYER_PLAT_NotifyWFIExit() {
237// while ( LL_RCC_HSE_IsReady() == 0); 237 if AHB5_SWITCHED_OFF.load(Ordering::Acquire) {
238// #endif /* CFG_SCM_SUPPORTED */ 238 let value = link_layer::ll_intf_cmn_get_slptmr_value();
239// } 239 RADIO_SLEEP_TIMER_VAL.store(value, Ordering::Release);
240// else 240 }
241// { 241}
242// /* Disable RADIO baseband clock (active CLK) */ 242
243// HAL_RCCEx_DisableRadioBBClock(); 243#[unsafe(no_mangle)]
244// } 244pub unsafe extern "C" fn LINKLAYER_PLAT_AclkCtrl(_enable: u8) {}
245// } 245
246// 246#[unsafe(no_mangle)]
247// /** 247pub unsafe extern "C" fn LINKLAYER_PLAT_GetRNG(ptr_rnd: *mut u8, len: u32) {
248// * @brief Link Layer RNG request. 248 if ptr_rnd.is_null() || len == 0 {
249// * @param ptr_rnd: pointer to the variable that hosts the number. 249 return;
250// * @param len: number of byte of anthropy to get. 250 }
251// * @retval None 251
252// */ 252 for i in 0..len {
253// void LINKLAYER_PLAT_GetRNG(uint8_t *ptr_rnd, uint32_t len) 253 let byte = (prng_next() >> ((i & 3) * 8)) as u8;
254// { 254 ptr::write_volatile(ptr_rnd.add(i as usize), byte);
255// uint32_t nb_remaining_rng = len; 255 }
256// uint32_t generated_rng; 256}
257// 257
258// /* Get the requested RNGs (4 bytes by 4bytes) */ 258#[unsafe(no_mangle)]
259// while(nb_remaining_rng >= 4) 259pub unsafe extern "C" fn LINKLAYER_PLAT_SetupRadioIT(intr_cb: Option<Callback>) {
260// { 260 store_callback(&RADIO_CALLBACK, intr_cb);
261// generated_rng = 0; 261
262// HW_RNG_Get(1, &generated_rng); 262 if intr_cb.is_some() {
263// memcpy((ptr_rnd+(len-nb_remaining_rng)), &generated_rng, 4); 263 nvic_set_priority(mac::RADIO_INTR_NUM, pack_priority(mac::RADIO_INTR_PRIO_HIGH));
264// nb_remaining_rng -=4; 264 nvic_enable(mac::RADIO_INTR_NUM);
265// } 265 } else {
266// 266 nvic_disable(mac::RADIO_INTR_NUM);
267// /* Get the remaining number of RNGs */ 267 }
268// if(nb_remaining_rng>0){ 268}
269// generated_rng = 0; 269
270// HW_RNG_Get(1, &generated_rng); 270#[unsafe(no_mangle)]
271// memcpy((ptr_rnd+(len-nb_remaining_rng)), &generated_rng, nb_remaining_rng); 271pub unsafe extern "C" fn LINKLAYER_PLAT_SetupSwLowIT(intr_cb: Option<Callback>) {
272// } 272 store_callback(&LOW_ISR_CALLBACK, intr_cb);
273// } 273
274// 274 if intr_cb.is_some() {
275// /** 275 nvic_set_priority(RADIO_SW_LOW_INTR_NUM, pack_priority(mac::RADIO_SW_LOW_INTR_PRIO));
276// * @brief Initialize Link Layer radio high priority interrupt. 276 nvic_enable(RADIO_SW_LOW_INTR_NUM);
277// * @param intr_cb: function pointer to assign for the radio high priority ISR routine. 277 } else {
278// * @retval None 278 nvic_disable(RADIO_SW_LOW_INTR_NUM);
279// */ 279 }
280// void LINKLAYER_PLAT_SetupRadioIT(void (*intr_cb)()) 280}
281// { 281
282// radio_callback = intr_cb; 282#[unsafe(no_mangle)]
283// HAL_NVIC_SetPriority((IRQn_Type) RADIO_INTR_NUM, RADIO_INTR_PRIO_HIGH, 0); 283pub unsafe extern "C" fn LINKLAYER_PLAT_TriggerSwLowIT(priority: u8) {
284// HAL_NVIC_EnableIRQ((IRQn_Type) RADIO_INTR_NUM); 284 let active = nvic_get_active(RADIO_SW_LOW_INTR_NUM);
285// } 285
286// 286 if !active {
287// /** 287 let prio = if priority == 0 {
288// * @brief Initialize Link Layer SW low priority interrupt. 288 pack_priority(mac::RADIO_SW_LOW_INTR_PRIO)
289// * @param intr_cb: function pointer to assign for the SW low priority ISR routine. 289 } else {
290// * @retval None 290 pack_priority(mac::RADIO_INTR_PRIO_LOW)
291// */ 291 };
292// void LINKLAYER_PLAT_SetupSwLowIT(void (*intr_cb)()) 292 nvic_set_priority(RADIO_SW_LOW_INTR_NUM, prio);
293// { 293 } else if priority != 0 {
294// low_isr_callback = intr_cb; 294 RADIO_SW_LOW_ISR_RUNNING_HIGH_PRIO.store(true, Ordering::Release);
295// 295 }
296// HAL_NVIC_SetPriority((IRQn_Type) RADIO_SW_LOW_INTR_NUM, RADIO_SW_LOW_INTR_PRIO, 0); 296
297// HAL_NVIC_EnableIRQ((IRQn_Type) RADIO_SW_LOW_INTR_NUM); 297 nvic_set_pending(RADIO_SW_LOW_INTR_NUM);
298// } 298}
299// 299
300// /** 300#[unsafe(no_mangle)]
301// * @brief Trigger the link layer SW low interrupt. 301pub unsafe extern "C" fn LINKLAYER_PLAT_EnableIRQ() {
302// * @param None 302 if counter_release(&IRQ_COUNTER) {
303// * @retval None 303 let snapshot = PRIMASK_SNAPSHOT.swap(0, Ordering::Relaxed);
304// */ 304 if snapshot != 0 {
305// void LINKLAYER_PLAT_TriggerSwLowIT(uint8_t priority) 305 cortex_m::interrupt::disable();
306// { 306 } else {
307// uint8_t low_isr_priority = RADIO_INTR_PRIO_LOW; 307 cortex_m::interrupt::enable();
308// 308 }
309// /* Check if a SW low interrupt as already been raised. 309 }
310// * Nested call far radio low isr are not supported 310}
311// **/ 311
312// 312#[unsafe(no_mangle)]
313// if(NVIC_GetActive(RADIO_SW_LOW_INTR_NUM) == 0) 313pub unsafe extern "C" fn LINKLAYER_PLAT_DisableIRQ() {
314// { 314 if counter_acquire(&IRQ_COUNTER) {
315// /* No nested SW low ISR, default behavior */ 315 let snapshot = if primask::read().is_active() { 1 } else { 0 };
316// 316 PRIMASK_SNAPSHOT.store(snapshot, Ordering::Relaxed);
317// if(priority == 0) 317 }
318// { 318 cortex_m::interrupt::disable();
319// low_isr_priority = RADIO_SW_LOW_INTR_PRIO; 319}
320// } 320
321// 321#[unsafe(no_mangle)]
322// HAL_NVIC_SetPriority((IRQn_Type) RADIO_SW_LOW_INTR_NUM, low_isr_priority, 0); 322pub unsafe extern "C" fn LINKLAYER_PLAT_EnableSpecificIRQ(isr_type: u8) {
323// } 323 if (isr_type & link_layer::LL_HIGH_ISR_ONLY as u8) != 0 {
324// else 324 if counter_release(&PRIO_HIGH_ISR_COUNTER) {
325// { 325 nvic_enable(mac::RADIO_INTR_NUM);
326// /* Nested call detected */ 326 }
327// /* No change for SW radio low interrupt priority for the moment */ 327 }
328// 328
329// if(priority != 0) 329 if (isr_type & link_layer::LL_LOW_ISR_ONLY as u8) != 0 {
330// { 330 if counter_release(&PRIO_LOW_ISR_COUNTER) {
331// /* At the end of current SW radio low ISR, this pending SW low interrupt 331 nvic_enable(RADIO_SW_LOW_INTR_NUM);
332// * will run with RADIO_INTR_PRIO_LOW priority 332 }
333// **/ 333 }
334// radio_sw_low_isr_is_running_high_prio = 1; 334
335// } 335 if (isr_type & link_layer::SYS_LOW_ISR as u8) != 0 {
336// } 336 if counter_release(&PRIO_SYS_ISR_COUNTER) {
337// 337 let stored = LOCAL_BASEPRI_VALUE.load(Ordering::Relaxed) as u8;
338// HAL_NVIC_SetPendingIRQ((IRQn_Type) RADIO_SW_LOW_INTR_NUM); 338 basepri::write(stored);
339// } 339 }
340// 340 }
341// /** 341}
342// * @brief Enable interrupts. 342
343// * @param None 343#[unsafe(no_mangle)]
344// * @retval None 344pub unsafe extern "C" fn LINKLAYER_PLAT_DisableSpecificIRQ(isr_type: u8) {
345// */ 345 if (isr_type & link_layer::LL_HIGH_ISR_ONLY as u8) != 0 {
346// void LINKLAYER_PLAT_EnableIRQ(void) 346 if counter_acquire(&PRIO_HIGH_ISR_COUNTER) {
347// { 347 nvic_disable(mac::RADIO_INTR_NUM);
348// irq_counter = max(0,irq_counter-1); 348 }
349// 349 }
350// if(irq_counter == 0) 350
351// { 351 if (isr_type & link_layer::LL_LOW_ISR_ONLY as u8) != 0 {
352// /* When irq_counter reaches 0, restore primask bit */ 352 if counter_acquire(&PRIO_LOW_ISR_COUNTER) {
353// __set_PRIMASK(primask_bit); 353 nvic_disable(RADIO_SW_LOW_INTR_NUM);
354// } 354 }
355// } 355 }
356// 356
357// /** 357 if (isr_type & link_layer::SYS_LOW_ISR as u8) != 0 {
358// * @brief Disable interrupts. 358 if counter_acquire(&PRIO_SYS_ISR_COUNTER) {
359// * @param None 359 let current = basepri::read();
360// * @retval None 360 LOCAL_BASEPRI_VALUE.store(current.into(), Ordering::Relaxed);
361// */ 361 set_basepri_max(pack_priority(mac::RADIO_INTR_PRIO_LOW));
362// void LINKLAYER_PLAT_DisableIRQ(void) 362 }
363// { 363 }
364// if(irq_counter == 0) 364}
365// { 365
366// /* Save primask bit at first interrupt disablement */ 366#[unsafe(no_mangle)]
367// primask_bit= __get_PRIMASK(); 367pub unsafe extern "C" fn LINKLAYER_PLAT_EnableRadioIT() {
368// } 368 nvic_enable(mac::RADIO_INTR_NUM);
369// __disable_irq(); 369}
370// irq_counter ++; 370
371// } 371#[unsafe(no_mangle)]
372// 372pub unsafe extern "C" fn LINKLAYER_PLAT_DisableRadioIT() {
373// /** 373 nvic_disable(mac::RADIO_INTR_NUM);
374// * @brief Enable specific interrupt group. 374}
375// * @param isr_type: mask for interrupt group to enable. 375
376// * This parameter can be one of the following: 376#[unsafe(no_mangle)]
377// * @arg LL_HIGH_ISR_ONLY: enable link layer high priority ISR. 377pub unsafe extern "C" fn LINKLAYER_PLAT_StartRadioEvt() {
378// * @arg LL_LOW_ISR_ONLY: enable link layer SW low priority ISR. 378 nvic_set_priority(mac::RADIO_INTR_NUM, pack_priority(mac::RADIO_INTR_PRIO_HIGH));
379// * @arg SYS_LOW_ISR: mask interrupts for all the other system ISR with 379 nvic_enable(mac::RADIO_INTR_NUM);
380// * lower priority that link layer SW low interrupt. 380}
381// * @retval None 381
382// */ 382#[unsafe(no_mangle)]
383// void LINKLAYER_PLAT_EnableSpecificIRQ(uint8_t isr_type) 383pub unsafe extern "C" fn LINKLAYER_PLAT_StopRadioEvt() {
384// { 384 nvic_set_priority(mac::RADIO_INTR_NUM, pack_priority(mac::RADIO_INTR_PRIO_LOW));
385// if( (isr_type & LL_HIGH_ISR_ONLY) != 0 ) 385}
386// { 386
387// prio_high_isr_counter--; 387#[unsafe(no_mangle)]
388// if(prio_high_isr_counter == 0) 388pub unsafe extern "C" fn LINKLAYER_PLAT_RCOStartClbr() {}
389// { 389
390// /* When specific counter for link layer high ISR reaches 0, interrupt is enabled */ 390#[unsafe(no_mangle)]
391// HAL_NVIC_EnableIRQ(RADIO_INTR_NUM); 391pub unsafe extern "C" fn LINKLAYER_PLAT_RCOStopClbr() {}
392// /* USER CODE BEGIN LINKLAYER_PLAT_EnableSpecificIRQ_1 */ 392
393// 393#[unsafe(no_mangle)]
394// /* USER CODE END LINKLAYER_PLAT_EnableSpecificIRQ_1 */ 394pub unsafe extern "C" fn LINKLAYER_PLAT_RequestTemperature() {}
395// } 395
396// } 396#[unsafe(no_mangle)]
397// 397pub unsafe extern "C" fn LINKLAYER_PLAT_PhyStartClbr() {}
398// if( (isr_type & LL_LOW_ISR_ONLY) != 0 ) 398
399// { 399#[unsafe(no_mangle)]
400// prio_low_isr_counter--; 400pub unsafe extern "C" fn LINKLAYER_PLAT_PhyStopClbr() {}
401// if(prio_low_isr_counter == 0) 401
402// { 402#[unsafe(no_mangle)]
403// /* When specific counter for link layer SW low ISR reaches 0, interrupt is enabled */ 403pub unsafe extern "C" fn LINKLAYER_PLAT_SCHLDR_TIMING_UPDATE_NOT(_timings: *const link_layer::Evnt_timing_t) {}
404// HAL_NVIC_EnableIRQ(RADIO_SW_LOW_INTR_NUM); 404
405// } 405#[unsafe(no_mangle)]
406// 406pub unsafe extern "C" fn LINKLAYER_PLAT_GetSTCompanyID() -> u32 {
407// } 407 // STMicroelectronics Bluetooth SIG Company Identifier
408// 408 // TODO: Pull in update from latest stm32-generated-data
409// if( (isr_type & SYS_LOW_ISR) != 0 ) 409 0x0030
410// { 410}
411// prio_sys_isr_counter--; 411
412// if(prio_sys_isr_counter == 0) 412#[unsafe(no_mangle)]
413// { 413pub unsafe extern "C" fn LINKLAYER_PLAT_GetUDN() -> u32 {
414// /* Restore basepri value */ 414 // Read the first 32 bits of the STM32 unique 96-bit ID
415// __set_BASEPRI(local_basepri_value); 415 let uid = embassy_stm32::uid::uid();
416// } 416 u32::from_le_bytes([uid[0], uid[1], uid[2], uid[3]])
417// } 417}
418// }
419//
420// /**
421// * @brief Disable specific interrupt group.
422// * @param isr_type: mask for interrupt group to disable.
423// * This parameter can be one of the following:
424// * @arg LL_HIGH_ISR_ONLY: disable link layer high priority ISR.
425// * @arg LL_LOW_ISR_ONLY: disable link layer SW low priority ISR.
426// * @arg SYS_LOW_ISR: unmask interrupts for all the other system ISR with
427// * lower priority that link layer SW low interrupt.
428// * @retval None
429// */
430// void LINKLAYER_PLAT_DisableSpecificIRQ(uint8_t isr_type)
431// {
432// if( (isr_type & LL_HIGH_ISR_ONLY) != 0 )
433// {
434// prio_high_isr_counter++;
435// if(prio_high_isr_counter == 1)
436// {
437// /* USER CODE BEGIN LINKLAYER_PLAT_DisableSpecificIRQ_1 */
438//
439// /* USER CODE END LINKLAYER_PLAT_DisableSpecificIRQ_1 */
440// /* When specific counter for link layer high ISR value is 1, interrupt is disabled */
441// HAL_NVIC_DisableIRQ(RADIO_INTR_NUM);
442// }
443// }
444//
445// if( (isr_type & LL_LOW_ISR_ONLY) != 0 )
446// {
447// prio_low_isr_counter++;
448// if(prio_low_isr_counter == 1)
449// {
450// /* When specific counter for link layer SW low ISR value is 1, interrupt is disabled */
451// HAL_NVIC_DisableIRQ(RADIO_SW_LOW_INTR_NUM);
452// }
453// }
454//
455// if( (isr_type & SYS_LOW_ISR) != 0 )
456// {
457// prio_sys_isr_counter++;
458// if(prio_sys_isr_counter == 1)
459// {
460// /* Save basepri register value */
461// local_basepri_value = __get_BASEPRI();
462//
463// /* Mask all other interrupts with lower priority that link layer SW low ISR */
464// __set_BASEPRI_MAX(RADIO_INTR_PRIO_LOW<<4);
465// }
466// }
467// }
468//
469// /**
470// * @brief Enable link layer high priority ISR only.
471// * @param None
472// * @retval None
473// */
474// void LINKLAYER_PLAT_EnableRadioIT(void)
475// {
476// /* USER CODE BEGIN LINKLAYER_PLAT_EnableRadioIT_1 */
477//
478// /* USER CODE END LINKLAYER_PLAT_EnableRadioIT_1 */
479//
480// HAL_NVIC_EnableIRQ((IRQn_Type) RADIO_INTR_NUM);
481//
482// /* USER CODE BEGIN LINKLAYER_PLAT_EnableRadioIT_2 */
483//
484// /* USER CODE END LINKLAYER_PLAT_EnableRadioIT_2 */
485// }
486//
487// /**
488// * @brief Disable link layer high priority ISR only.
489// * @param None
490// * @retval None
491// */
492// void LINKLAYER_PLAT_DisableRadioIT(void)
493// {
494// /* USER CODE BEGIN LINKLAYER_PLAT_DisableRadioIT_1 */
495//
496// /* USER CODE END LINKLAYER_PLAT_DisableRadioIT_1 */
497//
498// HAL_NVIC_DisableIRQ((IRQn_Type) RADIO_INTR_NUM);
499//
500// /* USER CODE BEGIN LINKLAYER_PLAT_DisableRadioIT_2 */
501//
502// /* USER CODE END LINKLAYER_PLAT_DisableRadioIT_2 */
503// }
504//
505// /**
506// * @brief Link Layer notification for radio activity start.
507// * @param None
508// * @retval None
509// */
510// void LINKLAYER_PLAT_StartRadioEvt(void)
511// {
512// __HAL_RCC_RADIO_CLK_SLEEP_ENABLE();
513// NVIC_SetPriority(RADIO_INTR_NUM, RADIO_INTR_PRIO_HIGH);
514// #if (CFG_SCM_SUPPORTED == 1)
515// scm_notifyradiostate(SCM_RADIO_ACTIVE);
516// #endif /* CFG_SCM_SUPPORTED */
517// }
518//
519// /**
520// * @brief Link Layer notification for radio activity end.
521// * @param None
522// * @retval None
523// */
524// void LINKLAYER_PLAT_StopRadioEvt(void)
525// {
526// __HAL_RCC_RADIO_CLK_SLEEP_DISABLE();
527// NVIC_SetPriority(RADIO_INTR_NUM, RADIO_INTR_PRIO_LOW);
528// #if (CFG_SCM_SUPPORTED == 1)
529// scm_notifyradiostate(SCM_RADIO_NOT_ACTIVE);
530// #endif /* CFG_SCM_SUPPORTED */
531// }
532//
533// /**
534// * @brief Link Layer notification for RCO calibration start.
535// * @param None
536// * @retval None
537// */
538// void LINKLAYER_PLAT_RCOStartClbr(void)
539// {
540// #if (CFG_LPM_LEVEL != 0)
541// PWR_DisableSleepMode();
542// /* Disabling stop mode prevents also from entering in standby */
543// UTIL_LPM_SetStopMode(1U << CFG_LPM_LL_HW_RCO_CLBR, UTIL_LPM_DISABLE);
544// #endif /* (CFG_LPM_LEVEL != 0) */
545// #if (CFG_SCM_SUPPORTED == 1)
546// scm_setsystemclock(SCM_USER_LL_HW_RCO_CLBR, HSE_32MHZ);
547// while (LL_PWR_IsActiveFlag_VOS() == 0);
548// #endif /* (CFG_SCM_SUPPORTED == 1) */
549// }
550//
551// /**
552// * @brief Link Layer notification for RCO calibration end.
553// * @param None
554// * @retval None
555// */
556// void LINKLAYER_PLAT_RCOStopClbr(void)
557// {
558// #if (CFG_LPM_LEVEL != 0)
559// PWR_EnableSleepMode();
560// UTIL_LPM_SetStopMode(1U << CFG_LPM_LL_HW_RCO_CLBR, UTIL_LPM_ENABLE);
561// #endif /* (CFG_LPM_LEVEL != 0) */
562// #if (CFG_SCM_SUPPORTED == 1)
563// scm_setsystemclock(SCM_USER_LL_HW_RCO_CLBR, HSE_16MHZ);
564// #endif /* (CFG_SCM_SUPPORTED == 1) */
565// }
566//
567// /**
568// * @brief Link Layer requests temperature.
569// * @param None
570// * @retval None
571// */
572// void LINKLAYER_PLAT_RequestTemperature(void)
573// {
574// #if (USE_TEMPERATURE_BASED_RADIO_CALIBRATION == 1)
575// ll_sys_bg_temperature_measurement();
576// #endif /* USE_TEMPERATURE_BASED_RADIO_CALIBRATION */
577// }
578//
579// /**
580// * @brief PHY Start calibration.
581// * @param None
582// * @retval None
583// */
584// void LINKLAYER_PLAT_PhyStartClbr(void)
585// {
586// /* USER CODE BEGIN LINKLAYER_PLAT_PhyStartClbr_0 */
587//
588// /* USER CODE END LINKLAYER_PLAT_PhyStartClbr_0 */
589//
590// /* USER CODE BEGIN LINKLAYER_PLAT_PhyStartClbr_1 */
591//
592// /* USER CODE END LINKLAYER_PLAT_PhyStartClbr_1 */
593// }
594//
595// /**
596// * @brief PHY Stop calibration.
597// * @param None
598// * @retval None
599// */
600// void LINKLAYER_PLAT_PhyStopClbr(void)
601// {
602// /* USER CODE BEGIN LINKLAYER_PLAT_PhyStopClbr_0 */
603//
604// /* USER CODE END LINKLAYER_PLAT_PhyStopClbr_0 */
605//
606// /* USER CODE BEGIN LINKLAYER_PLAT_PhyStopClbr_1 */
607//
608// /* USER CODE END LINKLAYER_PLAT_PhyStopClbr_1 */
609// }
610//
611// /**
612// * @brief Notify the upper layer that new Link Layer timings have been applied.
613// * @param evnt_timing[in]: Evnt_timing_t pointer to structure contains drift time , execution time and scheduling time
614// * @retval None.
615// */
616// void LINKLAYER_PLAT_SCHLDR_TIMING_UPDATE_NOT(Evnt_timing_t * p_evnt_timing)
617// {
618// /* USER CODE BEGIN LINKLAYER_PLAT_SCHLDR_TIMING_UPDATE_NOT_0 */
619//
620// /* USER CODE END LINKLAYER_PLAT_SCHLDR_TIMING_UPDATE_NOT_0 */
621// }
622//
623// /**
624// * @brief Get the ST company ID.
625// * @param None
626// * @retval Company ID
627// */
628// uint32_t LINKLAYER_PLAT_GetSTCompanyID(void)
629// {
630// return LL_FLASH_GetSTCompanyID();
631// }
632//
633// /**
634// * @brief Get the Unique Device Number (UDN).
635// * @param None
636// * @retval UDN
637// */
638// uint32_t LINKLAYER_PLAT_GetUDN(void)
639// {
640// return LL_FLASH_GetUDN();
641// }
642//
643// /* USER CODE BEGIN LINKLAYER_PLAT 0 */
644//
645// /* USER CODE END LINKLAYER_PLAT 0 */