aboutsummaryrefslogtreecommitdiff
path: root/embassy-stm32-wpan/src/wba/linklayer_plat.rs
diff options
context:
space:
mode:
Diffstat (limited to 'embassy-stm32-wpan/src/wba/linklayer_plat.rs')
-rw-r--r--embassy-stm32-wpan/src/wba/linklayer_plat.rs1118
1 files changed, 693 insertions, 425 deletions
diff --git a/embassy-stm32-wpan/src/wba/linklayer_plat.rs b/embassy-stm32-wpan/src/wba/linklayer_plat.rs
index c011b3bcb..108e84efe 100644
--- a/embassy-stm32-wpan/src/wba/linklayer_plat.rs
+++ b/embassy-stm32-wpan/src/wba/linklayer_plat.rs
@@ -1,6 +1,3 @@
1#[allow(dead_code)]
2fn test_fn() {}
3
4// /* USER CODE BEGIN Header */ 1// /* USER CODE BEGIN Header */
5// /** 2// /**
6// ****************************************************************************** 3// ******************************************************************************
@@ -72,131 +69,352 @@ fn test_fn() {}
72// uint8_t AHB5_SwitchedOff = 0; 69// uint8_t AHB5_SwitchedOff = 0;
73// uint32_t radio_sleep_timer_val = 0; 70// uint32_t radio_sleep_timer_val = 0;
74// 71//
72// /* USER CODE BEGIN LINKLAYER_PLAT 0 */
73//
74// /* USER CODE END LINKLAYER_PLAT 0 */
75#![cfg(feature = "wba")]
76#![allow(clippy::missing_safety_doc)]
77
78use core::hint::spin_loop;
79use core::ptr;
80use core::sync::atomic::{AtomicBool, AtomicI32, AtomicPtr, AtomicU32, Ordering};
81
82use cortex_m::asm::{dsb, isb};
83use cortex_m::interrupt::InterruptNumber;
84use cortex_m::peripheral::NVIC;
85use cortex_m::register::basepri;
86use critical_section;
87#[cfg(feature = "defmt")]
88use defmt::trace;
89use embassy_stm32::NVIC_PRIO_BITS;
90use embassy_time::{Duration, block_for};
91
92use super::bindings::{link_layer, mac};
93
94// Missing constant from stm32-bindings - RADIO_SW_LOW interrupt number
95// For STM32WBA, this is typically RADIO_IRQ_BUSY (interrupt 43)
96const RADIO_SW_LOW_INTR_NUM: u32 = 43;
97
98type Callback = unsafe extern "C" fn();
99
100#[derive(Clone, Copy, Debug, Eq, PartialEq)]
101#[repr(transparent)]
102struct RawInterrupt(u16);
103
104impl RawInterrupt {
105 #[inline(always)]
106 fn new(irq: u32) -> Self {
107 debug_assert!(irq <= u16::MAX as u32);
108 Self(irq as u16)
109 }
110}
111
112impl From<u32> for RawInterrupt {
113 #[inline(always)]
114 fn from(value: u32) -> Self {
115 Self::new(value)
116 }
117}
118
119unsafe impl InterruptNumber for RawInterrupt {
120 fn number(self) -> u16 {
121 self.0
122 }
123}
124
125static RADIO_CALLBACK: AtomicPtr<()> = AtomicPtr::new(ptr::null_mut());
126static LOW_ISR_CALLBACK: AtomicPtr<()> = AtomicPtr::new(ptr::null_mut());
127
128static IRQ_COUNTER: AtomicI32 = AtomicI32::new(0);
129
130static PRIO_HIGH_ISR_COUNTER: AtomicI32 = AtomicI32::new(0);
131static PRIO_LOW_ISR_COUNTER: AtomicI32 = AtomicI32::new(0);
132static PRIO_SYS_ISR_COUNTER: AtomicI32 = AtomicI32::new(0);
133static LOCAL_BASEPRI_VALUE: AtomicU32 = AtomicU32::new(0);
134
135static RADIO_SW_LOW_ISR_RUNNING_HIGH_PRIO: AtomicBool = AtomicBool::new(false);
136static AHB5_SWITCHED_OFF: AtomicBool = AtomicBool::new(false);
137static RADIO_SLEEP_TIMER_VAL: AtomicU32 = AtomicU32::new(0);
138
139static PRNG_STATE: AtomicU32 = AtomicU32::new(0);
140static PRNG_INIT: AtomicBool = AtomicBool::new(false);
141
142// Critical-section restore token for IRQ enable/disable pairing.
143// Only written when the IRQ disable counter transitions 0->1, and consumed when it transitions 1->0.
144static mut CS_RESTORE_STATE: Option<critical_section::RestoreState> = None;
145
146unsafe extern "C" {
147 static SystemCoreClock: u32;
148}
149
150#[inline(always)]
151fn read_system_core_clock() -> u32 {
152 unsafe { ptr::read_volatile(&SystemCoreClock) }
153}
154
155#[inline(always)]
156fn store_callback(slot: &AtomicPtr<()>, cb: Option<Callback>) {
157 let ptr = cb.map_or(ptr::null_mut(), |f| f as *mut ());
158 slot.store(ptr, Ordering::Release);
159}
160
161#[inline(always)]
162fn load_callback(slot: &AtomicPtr<()>) -> Option<Callback> {
163 let ptr = slot.load(Ordering::Acquire);
164 if ptr.is_null() {
165 None
166 } else {
167 Some(unsafe { core::mem::transmute::<*mut (), Callback>(ptr) })
168 }
169}
170
171#[inline(always)]
172fn priority_shift() -> u8 {
173 8 - NVIC_PRIO_BITS as u8
174}
175
176fn pack_priority(raw: u32) -> u8 {
177 let shift = priority_shift();
178 let priority_bits = NVIC_PRIO_BITS as u32;
179 let mask = if priority_bits >= 32 {
180 u32::MAX
181 } else {
182 (1u32 << priority_bits) - 1
183 };
184 let clamped = raw & mask;
185 (clamped << u32::from(shift)) as u8
186}
187
188#[inline(always)]
189fn counter_release(counter: &AtomicI32) -> bool {
190 counter.fetch_sub(1, Ordering::SeqCst) <= 1
191}
192
193#[inline(always)]
194fn counter_acquire(counter: &AtomicI32) -> bool {
195 counter.fetch_add(1, Ordering::SeqCst) == 0
196}
197
198unsafe fn nvic_enable(irq: u32) {
199 NVIC::unmask(RawInterrupt::new(irq));
200 dsb();
201 isb();
202}
203
204unsafe fn nvic_disable(irq: u32) {
205 NVIC::mask(RawInterrupt::new(irq));
206 dsb();
207 isb();
208}
209
210unsafe fn nvic_set_pending(irq: u32) {
211 NVIC::pend(RawInterrupt::new(irq));
212 dsb();
213 isb();
214}
215
216unsafe fn nvic_get_active(irq: u32) -> bool {
217 NVIC::is_active(RawInterrupt::new(irq))
218}
219
220unsafe fn nvic_set_priority(irq: u32, priority: u8) {
221 // STM32WBA is ARMv8-M, which uses byte-accessible IPR registers
222 let nvic = &*NVIC::PTR;
223 nvic.ipr[irq as usize].write(priority);
224
225 dsb();
226 isb();
227}
228
229#[inline(always)]
230fn set_basepri_max(value: u8) {
231 unsafe {
232 if basepri::read() < value {
233 basepri::write(value);
234 }
235 }
236}
237
238fn prng_next() -> u32 {
239 #[inline]
240 fn xorshift(mut x: u32) -> u32 {
241 x ^= x << 13;
242 x ^= x >> 17;
243 x ^= x << 5;
244 x
245 }
246
247 if !PRNG_INIT.load(Ordering::Acquire) {
248 let seed = unsafe {
249 let timer = link_layer::ll_intf_cmn_get_slptmr_value();
250 let core_clock = read_system_core_clock();
251 timer ^ core_clock ^ 0x6C8E_9CF5
252 };
253 PRNG_STATE.store(seed, Ordering::Relaxed);
254 PRNG_INIT.store(true, Ordering::Release);
255 }
256
257 let mut current = PRNG_STATE.load(Ordering::Relaxed);
258 loop {
259 let next = xorshift(current);
260 match PRNG_STATE.compare_exchange_weak(current, next, Ordering::AcqRel, Ordering::Relaxed) {
261 Ok(_) => return next,
262 Err(v) => current = v,
263 }
264 }
265}
266
267pub unsafe fn run_radio_high_isr() {
268 if let Some(cb) = load_callback(&RADIO_CALLBACK) {
269 cb();
270 }
271}
272
273pub unsafe fn run_radio_sw_low_isr() {
274 if let Some(cb) = load_callback(&LOW_ISR_CALLBACK) {
275 cb();
276 }
277
278 if RADIO_SW_LOW_ISR_RUNNING_HIGH_PRIO.swap(false, Ordering::AcqRel) {
279 nvic_set_priority(RADIO_SW_LOW_INTR_NUM, pack_priority(mac::RADIO_SW_LOW_INTR_PRIO));
280 }
281}
282
75// /** 283// /**
76// * @brief Configure the necessary clock sources for the radio. 284// * @brief Configure the necessary clock sources for the radio.
77// * @param None 285// * @param None
78// * @retval None 286// * @retval None
79// */ 287// */
80// void LINKLAYER_PLAT_ClockInit() 288#[unsafe(no_mangle)]
81// { 289pub unsafe extern "C" fn LINKLAYER_PLAT_ClockInit() {
82// uint32_t linklayer_slp_clk_src = LL_RCC_RADIOSLEEPSOURCE_NONE; 290 // uint32_t linklayer_slp_clk_src = LL_RCC_RADIOSLEEPSOURCE_NONE;
83// 291 //
84// /* Get the Link Layer sleep timer clock source */ 292 // /* Get the Link Layer sleep timer clock source */
85// linklayer_slp_clk_src = LL_RCC_RADIO_GetSleepTimerClockSource(); 293 // linklayer_slp_clk_src = LL_RCC_RADIO_GetSleepTimerClockSource();
86// if(linklayer_slp_clk_src == LL_RCC_RADIOSLEEPSOURCE_NONE) 294 // if(linklayer_slp_clk_src == LL_RCC_RADIOSLEEPSOURCE_NONE)
87// { 295 // {
88// /* If there is no clock source defined, should be selected before */ 296 // /* If there is no clock source defined, should be selected before */
89// assert_param(0); 297 // assert_param(0);
90// } 298 // }
91// 299 //
92// /* Enable AHB5ENR peripheral clock (bus CLK) */ 300 // /* Enable AHB5ENR peripheral clock (bus CLK) */
93// __HAL_RCC_RADIO_CLK_ENABLE(); 301 // __HAL_RCC_RADIO_CLK_ENABLE();
94// } 302 trace!("LINKLAYER_PLAT_ClockInit: get_slptmr_value");
95// 303 let _ = link_layer::ll_intf_cmn_get_slptmr_value();
304}
305
96// /** 306// /**
97// * @brief Link Layer active waiting loop. 307// * @brief Link Layer active waiting loop.
98// * @param delay: delay in us 308// * @param delay: delay in us
99// * @retval None 309// * @retval None
100// */ 310// */
101// void LINKLAYER_PLAT_DelayUs(uint32_t delay) 311#[unsafe(no_mangle)]
102// { 312pub unsafe extern "C" fn LINKLAYER_PLAT_DelayUs(delay: u32) {
103// static uint8_t lock = 0; 313 // static uint8_t lock = 0;
104// uint32_t t0; 314 // uint32_t t0;
105// uint32_t primask_bit; 315 // uint32_t primask_bit;
106// 316 //
107// /* Enter critical section */ 317 // /* Enter critical section */
108// primask_bit= __get_PRIMASK(); 318 // primask_bit= __get_PRIMASK();
109// __disable_irq(); 319 // __disable_irq();
110// 320 //
111// if (lock == 0U) 321 // if (lock == 0U)
112// { 322 // {
113// /* Initialize counter */ 323 // /* Initialize counter */
114// /* Reset cycle counter to prevent overflow 324 // /* Reset cycle counter to prevent overflow
115// As a us counter, it is assumed than even with re-entrancy, 325 // As a us counter, it is assumed than even with re-entrancy,
116// overflow will never happen before re-initializing this counter */ 326 // overflow will never happen before re-initializing this counter */
117// DWT->CYCCNT = 0U; 327 // DWT->CYCCNT = 0U;
118// /* Enable DWT by safety but should be useless (as already set) */ 328 // /* Enable DWT by safety but should be useless (as already set) */
119// SET_BIT(DCB->DEMCR, DCB_DEMCR_TRCENA_Msk); 329 // SET_BIT(DCB->DEMCR, DCB_DEMCR_TRCENA_Msk);
120// /* Enable counter */ 330 // /* Enable counter */
121// SET_BIT(DWT->CTRL, DWT_CTRL_CYCCNTENA_Msk); 331 // SET_BIT(DWT->CTRL, DWT_CTRL_CYCCNTENA_Msk);
122// } 332 // }
123// /* Increment 're-entrance' counter */ 333 // /* Increment 're-entrance' counter */
124// lock++; 334 // lock++;
125// /* Get starting time stamp */ 335 // /* Get starting time stamp */
126// t0 = DWT->CYCCNT; 336 // t0 = DWT->CYCCNT;
127// /* Exit critical section */ 337 // /* Exit critical section */
128// __set_PRIMASK(primask_bit); 338 // __set_PRIMASK(primask_bit);
129// 339 //
130// /* Turn us into cycles */ 340 // /* Turn us into cycles */
131// delay = delay * (SystemCoreClock / 1000000U); 341 // delay = delay * (SystemCoreClock / 1000000U);
132// delay += t0; 342 // delay += t0;
133// 343 //
134// /* Busy waiting loop */ 344 // /* Busy waiting loop */
135// while (DWT->CYCCNT < delay) 345 // while (DWT->CYCCNT < delay)
136// { 346 // {
137// }; 347 // };
138// 348 //
139// /* Enter critical section */ 349 // /* Enter critical section */
140// primask_bit= __get_PRIMASK(); 350 // primask_bit= __get_PRIMASK();
141// __disable_irq(); 351 // __disable_irq();
142// if (lock == 1U) 352 // if (lock == 1U)
143// { 353 // {
144// /* Disable counter */ 354 // /* Disable counter */
145// CLEAR_BIT(DWT->CTRL, DWT_CTRL_CYCCNTENA_Msk); 355 // CLEAR_BIT(DWT->CTRL, DWT_CTRL_CYCCNTENA_Msk);
146// } 356 // }
147// /* Decrement 're-entrance' counter */ 357 // /* Decrement 're-entrance' counter */
148// lock--; 358 // lock--;
149// /* Exit critical section */ 359 // /* Exit critical section */
150// __set_PRIMASK(primask_bit); 360 // __set_PRIMASK(primask_bit);
151// 361 //
152// } 362 trace!("LINKLAYER_PLAT_DelayUs: delay={}", delay);
153// 363 block_for(Duration::from_micros(u64::from(delay)));
364}
365
154// /** 366// /**
155// * @brief Link Layer assertion API 367// * @brief Link Layer assertion API
156// * @param condition: conditional statement to be checked. 368// * @param condition: conditional statement to be checked.
157// * @retval None 369// * @retval None
158// */ 370// */
159// void LINKLAYER_PLAT_Assert(uint8_t condition) 371#[unsafe(no_mangle)]
160// { 372pub unsafe extern "C" fn LINKLAYER_PLAT_Assert(condition: u8) {
161// assert_param(condition); 373 if condition == 0 {
162// } 374 panic!("LINKLAYER_PLAT assertion failed");
163// 375 }
376}
377
164// /** 378// /**
165// * @brief Enable/disable the Link Layer active clock (baseband clock). 379// * @brief Enable/disable the Link Layer active clock (baseband clock).
166// * @param enable: boolean value to enable (1) or disable (0) the clock. 380// * @param enable: boolean value to enable (1) or disable (0) the clock.
167// * @retval None 381// * @retval None
168// */ 382// */
169// void LINKLAYER_PLAT_WaitHclkRdy(void) 383#[unsafe(no_mangle)]
170// { 384pub unsafe extern "C" fn LINKLAYER_PLAT_WaitHclkRdy() {
171// /* Wait on radio bus clock readiness if it has been turned of */ 385 trace!("LINKLAYER_PLAT_WaitHclkRdy");
172// if (AHB5_SwitchedOff == 1) 386 if AHB5_SWITCHED_OFF.swap(false, Ordering::AcqRel) {
173// { 387 let reference = RADIO_SLEEP_TIMER_VAL.load(Ordering::Acquire);
174// AHB5_SwitchedOff = 0; 388 trace!("LINKLAYER_PLAT_WaitHclkRdy: reference={}", reference);
175// while (radio_sleep_timer_val == ll_intf_cmn_get_slptmr_value()); 389 while reference == link_layer::ll_intf_cmn_get_slptmr_value() {
176// } 390 spin_loop();
177// } 391 }
178// 392 }
393}
394
179// /** 395// /**
180// * @brief Notify the Link Layer platform layer the system will enter in WFI 396// * @brief Notify the Link Layer platform layer the system will enter in WFI
181// * and AHB5 clock may be turned of regarding the 2.4Ghz radio state. 397// * and AHB5 clock may be turned of regarding the 2.4Ghz radio state.
182// * @param None 398// * @param None
183// * @retval None 399// * @retval None
184// */ 400// */
185// void LINKLAYER_PLAT_NotifyWFIEnter(void) 401#[unsafe(no_mangle)]
186// { 402pub unsafe extern "C" fn LINKLAYER_PLAT_NotifyWFIEnter() {
187// /* Check if Radio state will allow the AHB5 clock to be cut */ 403 // /* Check if Radio state will allow the AHB5 clock to be cut */
188// 404 //
189// /* AHB5 clock will be cut in the following cases: 405 // /* AHB5 clock will be cut in the following cases:
190// * - 2.4GHz radio is not in ACTIVE mode (in SLEEP or DEEPSLEEP mode). 406 // * - 2.4GHz radio is not in ACTIVE mode (in SLEEP or DEEPSLEEP mode).
191// * - RADIOSMEN and STRADIOCLKON bits are at 0. 407 // * - RADIOSMEN and STRADIOCLKON bits are at 0.
192// */ 408 // */
193// if((LL_PWR_GetRadioMode() != LL_PWR_RADIO_ACTIVE_MODE) || 409 // if((LL_PWR_GetRadioMode() != LL_PWR_RADIO_ACTIVE_MODE) ||
194// ((__HAL_RCC_RADIO_IS_CLK_SLEEP_ENABLED() == 0) && (LL_RCC_RADIO_IsEnabledSleepTimerClock() == 0))) 410 // ((__HAL_RCC_RADIO_IS_CLK_SLEEP_ENABLED() == 0) && (LL_RCC_RADIO_IsEnabledSleepTimerClock() == 0)))
195// { 411 // {
196// AHB5_SwitchedOff = 1; 412 // AHB5_SwitchedOff = 1;
197// } 413 // }
198// } 414 trace!("LINKLAYER_PLAT_NotifyWFIEnter");
199// 415 AHB5_SWITCHED_OFF.store(true, Ordering::Release);
416}
417
200// /** 418// /**
201// * @brief Notify the Link Layer platform layer the system exited WFI and AHB5 419// * @brief Notify the Link Layer platform layer the system exited WFI and AHB5
202// * clock may be resynchronized as is may have been turned of during 420// * clock may be resynchronized as is may have been turned of during
@@ -204,172 +422,202 @@ fn test_fn() {}
204// * @param None 422// * @param None
205// * @retval None 423// * @retval None
206// */ 424// */
207// void LINKLAYER_PLAT_NotifyWFIExit(void) 425#[unsafe(no_mangle)]
208// { 426pub unsafe extern "C" fn LINKLAYER_PLAT_NotifyWFIExit() {
209// /* Check if AHB5 clock has been turned of and needs resynchronisation */ 427 trace!("LINKLAYER_PLAT_NotifyWFIExit");
210// if (AHB5_SwitchedOff) 428 // /* Check if AHB5 clock has been turned of and needs resynchronisation */
211// { 429 if AHB5_SWITCHED_OFF.load(Ordering::Acquire) {
212// /* Read sleep register as earlier as possible */ 430 // /* Read sleep register as earlier as possible */
213// radio_sleep_timer_val = ll_intf_cmn_get_slptmr_value(); 431 let value = link_layer::ll_intf_cmn_get_slptmr_value();
214// } 432 RADIO_SLEEP_TIMER_VAL.store(value, Ordering::Release);
215// } 433 }
216// 434}
435
217// /** 436// /**
218// * @brief Active wait on bus clock readiness. 437// * @brief Active wait on bus clock readiness.
219// * @param None 438// * @param None
220// * @retval None 439// * @retval None
221// */ 440// */
222// void LINKLAYER_PLAT_AclkCtrl(uint8_t enable) 441#[unsafe(no_mangle)]
223// { 442pub unsafe extern "C" fn LINKLAYER_PLAT_AclkCtrl(_enable: u8) {
224// if(enable != 0u) 443 trace!("LINKLAYER_PLAT_AclkCtrl: enable={}", _enable);
225// { 444 if _enable != 0 {
226// #if (CFG_SCM_SUPPORTED == 1) 445 // #if (CFG_SCM_SUPPORTED == 1)
227// /* SCM HSE BEGIN */ 446 // /* SCM HSE BEGIN */
228// /* Polling on HSE32 activation */ 447 // /* Polling on HSE32 activation */
229// SCM_HSE_WaitUntilReady(); 448 // SCM_HSE_WaitUntilReady();
230// /* Enable RADIO baseband clock (active CLK) */ 449 // /* Enable RADIO baseband clock (active CLK) */
231// HAL_RCCEx_EnableRadioBBClock(); 450 // HAL_RCCEx_EnableRadioBBClock();
232// /* SCM HSE END */ 451 // /* SCM HSE END */
233// #else 452 // #else
234// /* Enable RADIO baseband clock (active CLK) */ 453 // /* Enable RADIO baseband clock (active CLK) */
235// HAL_RCCEx_EnableRadioBBClock(); 454 // HAL_RCCEx_EnableRadioBBClock();
236// /* Polling on HSE32 activation */ 455 // /* Polling on HSE32 activation */
237// while ( LL_RCC_HSE_IsReady() == 0); 456 // while ( LL_RCC_HSE_IsReady() == 0);
238// #endif /* CFG_SCM_SUPPORTED */ 457 // #endif /* CFG_SCM_SUPPORTED */
239// } 458 // NOTE: Add a proper assertion once a typed `Radio` peripheral exists in embassy-stm32
240// else 459 // that exposes the baseband clock enable status via RCC.
241// { 460 } else {
242// /* Disable RADIO baseband clock (active CLK) */ 461 // /* Disable RADIO baseband clock (active CLK) */
243// HAL_RCCEx_DisableRadioBBClock(); 462 // HAL_RCCEx_DisableRadioBBClock();
244// } 463 }
245// } 464}
246// 465
247// /** 466// /**
248// * @brief Link Layer RNG request. 467// * @brief Link Layer RNG request.
249// * @param ptr_rnd: pointer to the variable that hosts the number. 468// * @param ptr_rnd: pointer to the variable that hosts the number.
250// * @param len: number of byte of anthropy to get. 469// * @param len: number of byte of anthropy to get.
251// * @retval None 470// * @retval None
252// */ 471// */
253// void LINKLAYER_PLAT_GetRNG(uint8_t *ptr_rnd, uint32_t len) 472#[unsafe(no_mangle)]
254// { 473pub unsafe extern "C" fn LINKLAYER_PLAT_GetRNG(ptr_rnd: *mut u8, len: u32) {
255// uint32_t nb_remaining_rng = len; 474 // uint32_t nb_remaining_rng = len;
256// uint32_t generated_rng; 475 // uint32_t generated_rng;
257// 476 //
258// /* Get the requested RNGs (4 bytes by 4bytes) */ 477 // /* Get the requested RNGs (4 bytes by 4bytes) */
259// while(nb_remaining_rng >= 4) 478 // while(nb_remaining_rng >= 4)
260// { 479 // {
261// generated_rng = 0; 480 // generated_rng = 0;
262// HW_RNG_Get(1, &generated_rng); 481 // HW_RNG_Get(1, &generated_rng);
263// memcpy((ptr_rnd+(len-nb_remaining_rng)), &generated_rng, 4); 482 // memcpy((ptr_rnd+(len-nb_remaining_rng)), &generated_rng, 4);
264// nb_remaining_rng -=4; 483 // nb_remaining_rng -=4;
265// } 484 // }
266// 485 //
267// /* Get the remaining number of RNGs */ 486 // /* Get the remaining number of RNGs */
268// if(nb_remaining_rng>0){ 487 // if(nb_remaining_rng>0){
269// generated_rng = 0; 488 // generated_rng = 0;
270// HW_RNG_Get(1, &generated_rng); 489 // HW_RNG_Get(1, &generated_rng);
271// memcpy((ptr_rnd+(len-nb_remaining_rng)), &generated_rng, nb_remaining_rng); 490 // memcpy((ptr_rnd+(len-nb_remaining_rng)), &generated_rng, nb_remaining_rng);
272// } 491 // }
273// } 492 trace!("LINKLAYER_PLAT_GetRNG: ptr_rnd={:?}, len={}", ptr_rnd, len);
274// 493 if ptr_rnd.is_null() || len == 0 {
494 return;
495 }
496
497 for i in 0..len {
498 let byte = (prng_next() >> ((i & 3) * 8)) as u8;
499 ptr::write_volatile(ptr_rnd.add(i as usize), byte);
500 }
501}
502
275// /** 503// /**
276// * @brief Initialize Link Layer radio high priority interrupt. 504// * @brief Initialize Link Layer radio high priority interrupt.
277// * @param intr_cb: function pointer to assign for the radio high priority ISR routine. 505// * @param intr_cb: function pointer to assign for the radio high priority ISR routine.
278// * @retval None 506// * @retval None
279// */ 507// */
280// void LINKLAYER_PLAT_SetupRadioIT(void (*intr_cb)()) 508#[unsafe(no_mangle)]
281// { 509pub unsafe extern "C" fn LINKLAYER_PLAT_SetupRadioIT(intr_cb: Option<Callback>) {
282// radio_callback = intr_cb; 510 trace!("LINKLAYER_PLAT_SetupRadioIT: intr_cb={:?}", intr_cb);
283// HAL_NVIC_SetPriority((IRQn_Type) RADIO_INTR_NUM, RADIO_INTR_PRIO_HIGH, 0); 511 store_callback(&RADIO_CALLBACK, intr_cb);
284// HAL_NVIC_EnableIRQ((IRQn_Type) RADIO_INTR_NUM); 512
285// } 513 if intr_cb.is_some() {
286// 514 nvic_set_priority(mac::RADIO_INTR_NUM, pack_priority(mac::RADIO_INTR_PRIO_HIGH));
515 nvic_enable(mac::RADIO_INTR_NUM);
516 } else {
517 nvic_disable(mac::RADIO_INTR_NUM);
518 }
519}
520
287// /** 521// /**
288// * @brief Initialize Link Layer SW low priority interrupt. 522// * @brief Initialize Link Layer SW low priority interrupt.
289// * @param intr_cb: function pointer to assign for the SW low priority ISR routine. 523// * @param intr_cb: function pointer to assign for the SW low priority ISR routine.
290// * @retval None 524// * @retval None
291// */ 525// */
292// void LINKLAYER_PLAT_SetupSwLowIT(void (*intr_cb)()) 526#[unsafe(no_mangle)]
293// { 527pub unsafe extern "C" fn LINKLAYER_PLAT_SetupSwLowIT(intr_cb: Option<Callback>) {
294// low_isr_callback = intr_cb; 528 trace!("LINKLAYER_PLAT_SetupSwLowIT: intr_cb={:?}", intr_cb);
295// 529 store_callback(&LOW_ISR_CALLBACK, intr_cb);
296// HAL_NVIC_SetPriority((IRQn_Type) RADIO_SW_LOW_INTR_NUM, RADIO_SW_LOW_INTR_PRIO, 0); 530
297// HAL_NVIC_EnableIRQ((IRQn_Type) RADIO_SW_LOW_INTR_NUM); 531 if intr_cb.is_some() {
298// } 532 nvic_set_priority(RADIO_SW_LOW_INTR_NUM, pack_priority(mac::RADIO_SW_LOW_INTR_PRIO));
299// 533 nvic_enable(RADIO_SW_LOW_INTR_NUM);
534 } else {
535 nvic_disable(RADIO_SW_LOW_INTR_NUM);
536 }
537}
538
300// /** 539// /**
301// * @brief Trigger the link layer SW low interrupt. 540// * @brief Trigger the link layer SW low interrupt.
302// * @param None 541// * @param None
303// * @retval None 542// * @retval None
304// */ 543// */
305// void LINKLAYER_PLAT_TriggerSwLowIT(uint8_t priority) 544#[unsafe(no_mangle)]
306// { 545pub unsafe extern "C" fn LINKLAYER_PLAT_TriggerSwLowIT(priority: u8) {
307// uint8_t low_isr_priority = RADIO_INTR_PRIO_LOW; 546 trace!("LINKLAYER_PLAT_TriggerSwLowIT: priority={}", priority);
308// 547 let active = nvic_get_active(RADIO_SW_LOW_INTR_NUM);
309// /* Check if a SW low interrupt as already been raised. 548
310// * Nested call far radio low isr are not supported 549 // /* Check if a SW low interrupt as already been raised.
311// **/ 550 // * Nested call far radio low isr are not supported
312// 551 // **/
313// if(NVIC_GetActive(RADIO_SW_LOW_INTR_NUM) == 0) 552 if !active {
314// { 553 let prio = if priority == 0 {
315// /* No nested SW low ISR, default behavior */ 554 // /* No nested SW low ISR, default behavior */
316// 555 pack_priority(mac::RADIO_SW_LOW_INTR_PRIO)
317// if(priority == 0) 556 } else {
318// { 557 pack_priority(mac::RADIO_INTR_PRIO_LOW)
319// low_isr_priority = RADIO_SW_LOW_INTR_PRIO; 558 };
320// } 559 nvic_set_priority(RADIO_SW_LOW_INTR_NUM, prio);
321// 560 } else if priority != 0 {
322// HAL_NVIC_SetPriority((IRQn_Type) RADIO_SW_LOW_INTR_NUM, low_isr_priority, 0); 561 // /* Nested call detected */
323// } 562 // /* No change for SW radio low interrupt priority for the moment */
324// else 563 //
325// { 564 // if(priority != 0)
326// /* Nested call detected */ 565 // {
327// /* No change for SW radio low interrupt priority for the moment */ 566 // /* At the end of current SW radio low ISR, this pending SW low interrupt
328// 567 // * will run with RADIO_INTR_PRIO_LOW priority
329// if(priority != 0) 568 // **/
330// { 569 // radio_sw_low_isr_is_running_high_prio = 1;
331// /* At the end of current SW radio low ISR, this pending SW low interrupt 570 // }
332// * will run with RADIO_INTR_PRIO_LOW priority 571 RADIO_SW_LOW_ISR_RUNNING_HIGH_PRIO.store(true, Ordering::Release);
333// **/ 572 }
334// radio_sw_low_isr_is_running_high_prio = 1; 573
335// } 574 nvic_set_pending(RADIO_SW_LOW_INTR_NUM);
336// } 575}
337// 576
338// HAL_NVIC_SetPendingIRQ((IRQn_Type) RADIO_SW_LOW_INTR_NUM);
339// }
340//
341// /** 577// /**
342// * @brief Enable interrupts. 578// * @brief Enable interrupts.
343// * @param None 579// * @param None
344// * @retval None 580// * @retval None
345// */ 581// */
346// void LINKLAYER_PLAT_EnableIRQ(void) 582#[unsafe(no_mangle)]
347// { 583pub unsafe extern "C" fn LINKLAYER_PLAT_EnableIRQ() {
348// irq_counter = max(0,irq_counter-1); 584 trace!("LINKLAYER_PLAT_EnableIRQ");
349// 585 // irq_counter = max(0,irq_counter-1);
350// if(irq_counter == 0) 586 //
351// { 587 // if(irq_counter == 0)
352// /* When irq_counter reaches 0, restore primask bit */ 588 // {
353// __set_PRIMASK(primask_bit); 589 // /* When irq_counter reaches 0, restore primask bit */
354// } 590 // __set_PRIMASK(primask_bit);
355// } 591 // }
356// 592 if counter_release(&IRQ_COUNTER) {
593 // When the counter reaches zero, restore prior interrupt state using the captured token.
594 if let Some(token) = CS_RESTORE_STATE.take() {
595 critical_section::release(token);
596 }
597 }
598}
599
357// /** 600// /**
358// * @brief Disable interrupts. 601// * @brief Disable interrupts.
359// * @param None 602// * @param None
360// * @retval None 603// * @retval None
361// */ 604// */
362// void LINKLAYER_PLAT_DisableIRQ(void) 605#[unsafe(no_mangle)]
363// { 606pub unsafe extern "C" fn LINKLAYER_PLAT_DisableIRQ() {
364// if(irq_counter == 0) 607 trace!("LINKLAYER_PLAT_DisableIRQ");
365// { 608 // if(irq_counter == 0)
366// /* Save primask bit at first interrupt disablement */ 609 // {
367// primask_bit= __get_PRIMASK(); 610 // /* Save primask bit at first interrupt disablement */
368// } 611 // primask_bit= __get_PRIMASK();
369// __disable_irq(); 612 // }
370// irq_counter ++; 613 // __disable_irq();
371// } 614 // irq_counter ++;
372// 615 if counter_acquire(&IRQ_COUNTER) {
616 // Capture and disable using critical-section API on first disable.
617 CS_RESTORE_STATE = Some(critical_section::acquire());
618 }
619}
620
373// /** 621// /**
374// * @brief Enable specific interrupt group. 622// * @brief Enable specific interrupt group.
375// * @param isr_type: mask for interrupt group to enable. 623// * @param isr_type: mask for interrupt group to enable.
@@ -380,43 +628,62 @@ fn test_fn() {}
380// * lower priority that link layer SW low interrupt. 628// * lower priority that link layer SW low interrupt.
381// * @retval None 629// * @retval None
382// */ 630// */
383// void LINKLAYER_PLAT_EnableSpecificIRQ(uint8_t isr_type) 631#[unsafe(no_mangle)]
384// { 632pub unsafe extern "C" fn LINKLAYER_PLAT_EnableSpecificIRQ(isr_type: u8) {
385// if( (isr_type & LL_HIGH_ISR_ONLY) != 0 ) 633 trace!("LINKLAYER_PLAT_EnableSpecificIRQ: isr_type={}", isr_type);
386// { 634 // if( (isr_type & LL_HIGH_ISR_ONLY) != 0 )
387// prio_high_isr_counter--; 635 // {
388// if(prio_high_isr_counter == 0) 636 // prio_high_isr_counter--;
389// { 637 // if(prio_high_isr_counter == 0)
390// /* When specific counter for link layer high ISR reaches 0, interrupt is enabled */ 638 // {
391// HAL_NVIC_EnableIRQ(RADIO_INTR_NUM); 639 // /* When specific counter for link layer high ISR reaches 0, interrupt is enabled */
392// /* USER CODE BEGIN LINKLAYER_PLAT_EnableSpecificIRQ_1 */ 640 // HAL_NVIC_EnableIRQ(RADIO_INTR_NUM);
393// 641 // /* USER CODE BEGIN LINKLAYER_PLAT_EnableSpecificIRQ_1 */
394// /* USER CODE END LINKLAYER_PLAT_EnableSpecificIRQ_1 */ 642 //
395// } 643 // /* USER CODE END LINKLAYER_PLAT_EnableSpecificIRQ_1 */
396// } 644 // }
397// 645 // }
398// if( (isr_type & LL_LOW_ISR_ONLY) != 0 ) 646 //
399// { 647 // if( (isr_type & LL_LOW_ISR_ONLY) != 0 )
400// prio_low_isr_counter--; 648 // {
401// if(prio_low_isr_counter == 0) 649 // prio_low_isr_counter--;
402// { 650 // if(prio_low_isr_counter == 0)
403// /* When specific counter for link layer SW low ISR reaches 0, interrupt is enabled */ 651 // {
404// HAL_NVIC_EnableIRQ(RADIO_SW_LOW_INTR_NUM); 652 // /* When specific counter for link layer SW low ISR reaches 0, interrupt is enabled */
405// } 653 // HAL_NVIC_EnableIRQ(RADIO_SW_LOW_INTR_NUM);
406// 654 // }
407// } 655 //
408// 656 // }
409// if( (isr_type & SYS_LOW_ISR) != 0 ) 657 //
410// { 658 // if( (isr_type & SYS_LOW_ISR) != 0 )
411// prio_sys_isr_counter--; 659 // {
412// if(prio_sys_isr_counter == 0) 660 // prio_sys_isr_counter--;
413// { 661 // if(prio_sys_isr_counter == 0)
414// /* Restore basepri value */ 662 // {
415// __set_BASEPRI(local_basepri_value); 663 // /* Restore basepri value */
416// } 664 // __set_BASEPRI(local_basepri_value);
417// } 665 // }
418// } 666 // }
419// 667 if (isr_type & link_layer::LL_HIGH_ISR_ONLY as u8) != 0 {
668 if counter_release(&PRIO_HIGH_ISR_COUNTER) {
669 nvic_enable(mac::RADIO_INTR_NUM);
670 }
671 }
672
673 if (isr_type & link_layer::LL_LOW_ISR_ONLY as u8) != 0 {
674 if counter_release(&PRIO_LOW_ISR_COUNTER) {
675 nvic_enable(RADIO_SW_LOW_INTR_NUM);
676 }
677 }
678
679 if (isr_type & link_layer::SYS_LOW_ISR as u8) != 0 {
680 if counter_release(&PRIO_SYS_ISR_COUNTER) {
681 let stored = LOCAL_BASEPRI_VALUE.load(Ordering::Relaxed) as u8;
682 basepri::write(stored);
683 }
684 }
685}
686
420// /** 687// /**
421// * @brief Disable specific interrupt group. 688// * @brief Disable specific interrupt group.
422// * @param isr_type: mask for interrupt group to disable. 689// * @param isr_type: mask for interrupt group to disable.
@@ -427,219 +694,220 @@ fn test_fn() {}
427// * lower priority that link layer SW low interrupt. 694// * lower priority that link layer SW low interrupt.
428// * @retval None 695// * @retval None
429// */ 696// */
430// void LINKLAYER_PLAT_DisableSpecificIRQ(uint8_t isr_type) 697#[unsafe(no_mangle)]
431// { 698pub unsafe extern "C" fn LINKLAYER_PLAT_DisableSpecificIRQ(isr_type: u8) {
432// if( (isr_type & LL_HIGH_ISR_ONLY) != 0 ) 699 // if( (isr_type & LL_HIGH_ISR_ONLY) != 0 )
433// { 700 // {
434// prio_high_isr_counter++; 701 // prio_high_isr_counter++;
435// if(prio_high_isr_counter == 1) 702 // if(prio_high_isr_counter == 1)
436// { 703 // {
437// /* USER CODE BEGIN LINKLAYER_PLAT_DisableSpecificIRQ_1 */ 704 // /* USER CODE BEGIN LINKLAYER_PLAT_DisableSpecificIRQ_1 */
438// 705 //
439// /* USER CODE END LINKLAYER_PLAT_DisableSpecificIRQ_1 */ 706 // /* USER CODE END LINKLAYER_PLAT_DisableSpecificIRQ_1 */
440// /* When specific counter for link layer high ISR value is 1, interrupt is disabled */ 707 // /* When specific counter for link layer high ISR value is 1, interrupt is disabled */
441// HAL_NVIC_DisableIRQ(RADIO_INTR_NUM); 708 // HAL_NVIC_DisableIRQ(RADIO_INTR_NUM);
442// } 709 // }
443// } 710 // }
444// 711 //
445// if( (isr_type & LL_LOW_ISR_ONLY) != 0 ) 712 // if( (isr_type & LL_LOW_ISR_ONLY) != 0 )
446// { 713 // {
447// prio_low_isr_counter++; 714 // prio_low_isr_counter++;
448// if(prio_low_isr_counter == 1) 715 // if(prio_low_isr_counter == 1)
449// { 716 // {
450// /* When specific counter for link layer SW low ISR value is 1, interrupt is disabled */ 717 // /* When specific counter for link layer SW low ISR value is 1, interrupt is disabled */
451// HAL_NVIC_DisableIRQ(RADIO_SW_LOW_INTR_NUM); 718 // HAL_NVIC_DisableIRQ(RADIO_SW_LOW_INTR_NUM);
452// } 719 // }
453// } 720 // }
454// 721 //
455// if( (isr_type & SYS_LOW_ISR) != 0 ) 722 // if( (isr_type & SYS_LOW_ISR) != 0 )
456// { 723 // {
457// prio_sys_isr_counter++; 724 // prio_sys_isr_counter++;
458// if(prio_sys_isr_counter == 1) 725 // if(prio_sys_isr_counter == 1)
459// { 726 // {
460// /* Save basepri register value */ 727 // /* Save basepri register value */
461// local_basepri_value = __get_BASEPRI(); 728 // local_basepri_value = __get_BASEPRI();
462// 729 //
463// /* Mask all other interrupts with lower priority that link layer SW low ISR */ 730 // /* Mask all other interrupts with lower priority that link layer SW low ISR */
464// __set_BASEPRI_MAX(RADIO_INTR_PRIO_LOW<<4); 731 // __set_BASEPRI_MAX(RADIO_INTR_PRIO_LOW<<4);
465// } 732 // }
466// } 733 // }
467// } 734 trace!("LINKLAYER_PLAT_DisableSpecificIRQ: isr_type={}", isr_type);
468// 735 if (isr_type & link_layer::LL_HIGH_ISR_ONLY as u8) != 0 {
736 if counter_acquire(&PRIO_HIGH_ISR_COUNTER) {
737 nvic_disable(mac::RADIO_INTR_NUM);
738 }
739 }
740
741 if (isr_type & link_layer::LL_LOW_ISR_ONLY as u8) != 0 {
742 if counter_acquire(&PRIO_LOW_ISR_COUNTER) {
743 nvic_disable(RADIO_SW_LOW_INTR_NUM);
744 }
745 }
746
747 if (isr_type & link_layer::SYS_LOW_ISR as u8) != 0 {
748 if counter_acquire(&PRIO_SYS_ISR_COUNTER) {
749 let current = basepri::read();
750 LOCAL_BASEPRI_VALUE.store(current.into(), Ordering::Relaxed);
751 set_basepri_max(pack_priority(mac::RADIO_INTR_PRIO_LOW));
752 }
753 }
754}
755
469// /** 756// /**
470// * @brief Enable link layer high priority ISR only. 757// * @brief Enable link layer high priority ISR only.
471// * @param None 758// * @param None
472// * @retval None 759// * @retval None
473// */ 760// */
474// void LINKLAYER_PLAT_EnableRadioIT(void) 761#[unsafe(no_mangle)]
475// { 762pub unsafe extern "C" fn LINKLAYER_PLAT_EnableRadioIT() {
476// /* USER CODE BEGIN LINKLAYER_PLAT_EnableRadioIT_1 */ 763 trace!("LINKLAYER_PLAT_EnableRadioIT");
477// 764 nvic_enable(mac::RADIO_INTR_NUM);
478// /* USER CODE END LINKLAYER_PLAT_EnableRadioIT_1 */ 765}
479// 766
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// /** 767// /**
488// * @brief Disable link layer high priority ISR only. 768// * @brief Disable link layer high priority ISR only.
489// * @param None 769// * @param None
490// * @retval None 770// * @retval None
491// */ 771// */
492// void LINKLAYER_PLAT_DisableRadioIT(void) 772#[unsafe(no_mangle)]
493// { 773pub unsafe extern "C" fn LINKLAYER_PLAT_DisableRadioIT() {
494// /* USER CODE BEGIN LINKLAYER_PLAT_DisableRadioIT_1 */ 774 trace!("LINKLAYER_PLAT_DisableRadioIT");
495// 775 nvic_disable(mac::RADIO_INTR_NUM);
496// /* USER CODE END LINKLAYER_PLAT_DisableRadioIT_1 */ 776}
497// 777
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// /** 778// /**
506// * @brief Link Layer notification for radio activity start. 779// * @brief Link Layer notification for radio activity start.
507// * @param None 780// * @param None
508// * @retval None 781// * @retval None
509// */ 782// */
510// void LINKLAYER_PLAT_StartRadioEvt(void) 783#[unsafe(no_mangle)]
511// { 784pub unsafe extern "C" fn LINKLAYER_PLAT_StartRadioEvt() {
512// __HAL_RCC_RADIO_CLK_SLEEP_ENABLE(); 785 trace!("LINKLAYER_PLAT_StartRadioEvt");
513// NVIC_SetPriority(RADIO_INTR_NUM, RADIO_INTR_PRIO_HIGH); 786 // __HAL_RCC_RADIO_CLK_SLEEP_ENABLE();
514// #if (CFG_SCM_SUPPORTED == 1) 787 // NVIC_SetPriority(RADIO_INTR_NUM, RADIO_INTR_PRIO_HIGH);
515// scm_notifyradiostate(SCM_RADIO_ACTIVE); 788 // #if (CFG_SCM_SUPPORTED == 1)
516// #endif /* CFG_SCM_SUPPORTED */ 789 // scm_notifyradiostate(SCM_RADIO_ACTIVE);
517// } 790 // #endif /* CFG_SCM_SUPPORTED */
518// 791 nvic_set_priority(mac::RADIO_INTR_NUM, pack_priority(mac::RADIO_INTR_PRIO_HIGH));
792 nvic_enable(mac::RADIO_INTR_NUM);
793}
794
519// /** 795// /**
520// * @brief Link Layer notification for radio activity end. 796// * @brief Link Layer notification for radio activity end.
521// * @param None 797// * @param None
522// * @retval None 798// * @retval None
523// */ 799// */
524// void LINKLAYER_PLAT_StopRadioEvt(void) 800#[unsafe(no_mangle)]
525// { 801pub unsafe extern "C" fn LINKLAYER_PLAT_StopRadioEvt() {
526// __HAL_RCC_RADIO_CLK_SLEEP_DISABLE(); 802 trace!("LINKLAYER_PLAT_StopRadioEvt");
527// NVIC_SetPriority(RADIO_INTR_NUM, RADIO_INTR_PRIO_LOW); 803 // {
528// #if (CFG_SCM_SUPPORTED == 1) 804 // __HAL_RCC_RADIO_CLK_SLEEP_DISABLE();
529// scm_notifyradiostate(SCM_RADIO_NOT_ACTIVE); 805 // NVIC_SetPriority(RADIO_INTR_NUM, RADIO_INTR_PRIO_LOW);
530// #endif /* CFG_SCM_SUPPORTED */ 806 // #if (CFG_SCM_SUPPORTED == 1)
531// } 807 // scm_notifyradiostate(SCM_RADIO_NOT_ACTIVE);
532// 808 // #endif /* CFG_SCM_SUPPORTED */
809 nvic_set_priority(mac::RADIO_INTR_NUM, pack_priority(mac::RADIO_INTR_PRIO_LOW));
810}
811
533// /** 812// /**
534// * @brief Link Layer notification for RCO calibration start. 813// * @brief Link Layer notification for RCO calibration start.
535// * @param None 814// * @param None
536// * @retval None 815// * @retval None
537// */ 816// */
538// void LINKLAYER_PLAT_RCOStartClbr(void) 817#[unsafe(no_mangle)]
539// { 818pub unsafe extern "C" fn LINKLAYER_PLAT_RCOStartClbr() {
540// #if (CFG_LPM_LEVEL != 0) 819 trace!("LINKLAYER_PLAT_RCOStartClbr");
541// PWR_DisableSleepMode(); 820 // #if (CFG_LPM_LEVEL != 0)
542// /* Disabling stop mode prevents also from entering in standby */ 821 // PWR_DisableSleepMode();
543// UTIL_LPM_SetStopMode(1U << CFG_LPM_LL_HW_RCO_CLBR, UTIL_LPM_DISABLE); 822 // /* Disabling stop mode prevents also from entering in standby */
544// #endif /* (CFG_LPM_LEVEL != 0) */ 823 // UTIL_LPM_SetStopMode(1U << CFG_LPM_LL_HW_RCO_CLBR, UTIL_LPM_DISABLE);
545// #if (CFG_SCM_SUPPORTED == 1) 824 // #endif /* (CFG_LPM_LEVEL != 0) */
546// scm_setsystemclock(SCM_USER_LL_HW_RCO_CLBR, HSE_32MHZ); 825 // #if (CFG_SCM_SUPPORTED == 1)
547// while (LL_PWR_IsActiveFlag_VOS() == 0); 826 // scm_setsystemclock(SCM_USER_LL_HW_RCO_CLBR, HSE_32MHZ);
548// #endif /* (CFG_SCM_SUPPORTED == 1) */ 827 // while (LL_PWR_IsActiveFlag_VOS() == 0);
549// } 828 // #endif /* (CFG_SCM_SUPPORTED == 1) */
550// 829}
830
551// /** 831// /**
552// * @brief Link Layer notification for RCO calibration end. 832// * @brief Link Layer notification for RCO calibration end.
553// * @param None 833// * @param None
554// * @retval None 834// * @retval None
555// */ 835// */
556// void LINKLAYER_PLAT_RCOStopClbr(void) 836#[unsafe(no_mangle)]
557// { 837pub unsafe extern "C" fn LINKLAYER_PLAT_RCOStopClbr() {
558// #if (CFG_LPM_LEVEL != 0) 838 trace!("LINKLAYER_PLAT_RCOStopClbr");
559// PWR_EnableSleepMode(); 839 // #if (CFG_LPM_LEVEL != 0)
560// UTIL_LPM_SetStopMode(1U << CFG_LPM_LL_HW_RCO_CLBR, UTIL_LPM_ENABLE); 840 // PWR_EnableSleepMode();
561// #endif /* (CFG_LPM_LEVEL != 0) */ 841 // UTIL_LPM_SetStopMode(1U << CFG_LPM_LL_HW_RCO_CLBR, UTIL_LPM_ENABLE);
562// #if (CFG_SCM_SUPPORTED == 1) 842 // #endif /* (CFG_LPM_LEVEL != 0) */
563// scm_setsystemclock(SCM_USER_LL_HW_RCO_CLBR, HSE_16MHZ); 843 // #if (CFG_SCM_SUPPORTED == 1)
564// #endif /* (CFG_SCM_SUPPORTED == 1) */ 844 // scm_setsystemclock(SCM_USER_LL_HW_RCO_CLBR, HSE_16MHZ);
565// } 845 // #endif /* (CFG_SCM_SUPPORTED == 1) */
566// 846}
847
567// /** 848// /**
568// * @brief Link Layer requests temperature. 849// * @brief Link Layer requests temperature.
569// * @param None 850// * @param None
570// * @retval None 851// * @retval None
571// */ 852// */
572// void LINKLAYER_PLAT_RequestTemperature(void) 853#[unsafe(no_mangle)]
573// { 854pub unsafe extern "C" fn LINKLAYER_PLAT_RequestTemperature() {
574// #if (USE_TEMPERATURE_BASED_RADIO_CALIBRATION == 1) 855 trace!("LINKLAYER_PLAT_RequestTemperature");
575// ll_sys_bg_temperature_measurement(); 856 // #if (USE_TEMPERATURE_BASED_RADIO_CALIBRATION == 1)
576// #endif /* USE_TEMPERATURE_BASED_RADIO_CALIBRATION */ 857 // ll_sys_bg_temperature_measurement();
577// } 858 // #endif /* USE_TEMPERATURE_BASED_RADIO_CALIBRATION */
578// 859}
860
579// /** 861// /**
580// * @brief PHY Start calibration. 862// * @brief PHY Start calibration.
581// * @param None 863// * @param None
582// * @retval None 864// * @retval None
583// */ 865// */
584// void LINKLAYER_PLAT_PhyStartClbr(void) 866#[unsafe(no_mangle)]
585// { 867pub unsafe extern "C" fn LINKLAYER_PLAT_PhyStartClbr() {
586// /* USER CODE BEGIN LINKLAYER_PLAT_PhyStartClbr_0 */ 868 trace!("LINKLAYER_PLAT_PhyStartClbr");
587// 869}
588// /* USER CODE END LINKLAYER_PLAT_PhyStartClbr_0 */ 870
589//
590// /* USER CODE BEGIN LINKLAYER_PLAT_PhyStartClbr_1 */
591//
592// /* USER CODE END LINKLAYER_PLAT_PhyStartClbr_1 */
593// }
594//
595// /** 871// /**
596// * @brief PHY Stop calibration. 872// * @brief PHY Stop calibration.
597// * @param None 873// * @param None
598// * @retval None 874// * @retval None
599// */ 875// */
600// void LINKLAYER_PLAT_PhyStopClbr(void) 876#[unsafe(no_mangle)]
601// { 877pub unsafe extern "C" fn LINKLAYER_PLAT_PhyStopClbr() {
602// /* USER CODE BEGIN LINKLAYER_PLAT_PhyStopClbr_0 */ 878 trace!("LINKLAYER_PLAT_PhyStopClbr");
603// 879}
604// /* USER CODE END LINKLAYER_PLAT_PhyStopClbr_0 */ 880
605//
606// /* USER CODE BEGIN LINKLAYER_PLAT_PhyStopClbr_1 */
607//
608// /* USER CODE END LINKLAYER_PLAT_PhyStopClbr_1 */
609// }
610//
611// /** 881// /**
612// * @brief Notify the upper layer that new Link Layer timings have been applied. 882// * @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 883// * @param evnt_timing[in]: Evnt_timing_t pointer to structure contains drift time , execution time and scheduling time
614// * @retval None. 884// * @retval None.
615// */ 885// */
616// void LINKLAYER_PLAT_SCHLDR_TIMING_UPDATE_NOT(Evnt_timing_t * p_evnt_timing) 886#[unsafe(no_mangle)]
617// { 887pub unsafe extern "C" fn LINKLAYER_PLAT_SCHLDR_TIMING_UPDATE_NOT(_timings: *const link_layer::Evnt_timing_t) {
618// /* USER CODE BEGIN LINKLAYER_PLAT_SCHLDR_TIMING_UPDATE_NOT_0 */ 888 trace!("LINKLAYER_PLAT_SCHLDR_TIMING_UPDATE_NOT: timings={:?}", _timings);
619// 889}
620// /* USER CODE END LINKLAYER_PLAT_SCHLDR_TIMING_UPDATE_NOT_0 */ 890
621// }
622//
623// /** 891// /**
624// * @brief Get the ST company ID. 892// * @brief Get the ST company ID.
625// * @param None 893// * @param None
626// * @retval Company ID 894// * @retval Company ID
627// */ 895// */
628// uint32_t LINKLAYER_PLAT_GetSTCompanyID(void) 896#[unsafe(no_mangle)]
629// { 897pub unsafe extern "C" fn LINKLAYER_PLAT_GetSTCompanyID() -> u32 {
630// return LL_FLASH_GetSTCompanyID(); 898 // STMicroelectronics Bluetooth SIG Company Identifier
631// } 899 // TODO: Pull in update from latest stm32-generated-data
632// 900 0x0030
901}
902
633// /** 903// /**
634// * @brief Get the Unique Device Number (UDN). 904// * @brief Get the Unique Device Number (UDN).
635// * @param None 905// * @param None
636// * @retval UDN 906// * @retval UDN
637// */ 907// */
638// uint32_t LINKLAYER_PLAT_GetUDN(void) 908#[unsafe(no_mangle)]
639// { 909pub unsafe extern "C" fn LINKLAYER_PLAT_GetUDN() -> u32 {
640// return LL_FLASH_GetUDN(); 910 // Read the first 32 bits of the STM32 unique 96-bit ID
641// } 911 let uid = embassy_stm32::uid::uid();
642// 912 u32::from_le_bytes([uid[0], uid[1], uid[2], uid[3]])
643// /* USER CODE BEGIN LINKLAYER_PLAT 0 */ 913}
644//
645// /* USER CODE END LINKLAYER_PLAT 0 */