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.rs645
1 files changed, 645 insertions, 0 deletions
diff --git a/embassy-stm32-wpan/src/wba/linklayer_plat.rs b/embassy-stm32-wpan/src/wba/linklayer_plat.rs
new file mode 100644
index 000000000..c011b3bcb
--- /dev/null
+++ b/embassy-stm32-wpan/src/wba/linklayer_plat.rs
@@ -0,0 +1,645 @@
1#[allow(dead_code)]
2fn test_fn() {}
3
4// /* USER CODE BEGIN Header */
5// /**
6// ******************************************************************************
7// * @file linklayer_plat.c
8// * @author MCD Application Team
9// * @brief Source file for the linklayer plateform adaptation layer
10// ******************************************************************************
11// * @attention
12// *
13// * Copyright (c) 2024 STMicroelectronics.
14// * All rights reserved.
15// *
16// * This software is licensed under terms that can be found in the LICENSE file
17// * in the root directory of this software component.
18// * If no LICENSE file comes with this software, it is provided AS-IS.
19// *
20// ******************************************************************************
21// */
22// /* USER CODE END Header */
23//
24// #include "stm32wbaxx_hal.h"
25// #include "stm32wbaxx_hal_conf.h"
26// #include "stm32wbaxx_ll_rcc.h"
27//
28// #include "app_common.h"
29// #include "app_conf.h"
30// #include "linklayer_plat.h"
31// #include "scm.h"
32// #include "log_module.h"
33// #if (USE_TEMPERATURE_BASED_RADIO_CALIBRATION == 1)
34// #include "adc_ctrl.h"
35// #endif /* (USE_TEMPERATURE_BASED_RADIO_CALIBRATION == 1) */
36//
37// #if (CFG_LPM_LEVEL != 0)
38// #include "stm32_lpm.h"
39// #include "stm32_lpm_if.h"
40// #endif /* (CFG_LPM_LEVEL != 0) */
41//
42// /* USER CODE BEGIN Includes */
43//
44// /* USER CODE END Includes */
45//
46// #define max(a,b) ((a) > (b) ? a : b)
47//
48// /* 2.4GHz RADIO ISR callbacks */
49// void (*radio_callback)(void) = NULL;
50// void (*low_isr_callback)(void) = NULL;
51//
52// /* RNG handle */
53// extern RNG_HandleTypeDef hrng;
54//
55// #if (USE_TEMPERATURE_BASED_RADIO_CALIBRATION == 1)
56// /* Link Layer temperature request from background */
57// extern void ll_sys_bg_temperature_measurement(void);
58// #endif /* (USE_TEMPERATURE_BASED_RADIO_CALIBRATION == 1) */
59//
60// /* Radio critical sections */
61// static uint32_t primask_bit = 0;
62// volatile int32_t prio_high_isr_counter = 0;
63// volatile int32_t prio_low_isr_counter = 0;
64// volatile int32_t prio_sys_isr_counter = 0;
65// volatile int32_t irq_counter = 0;
66// volatile uint32_t local_basepri_value = 0;
67//
68// /* Radio SW low ISR global variable */
69// volatile uint8_t radio_sw_low_isr_is_running_high_prio = 0;
70//
71// /* Radio bus clock control variables */
72// uint8_t AHB5_SwitchedOff = 0;
73// uint32_t radio_sleep_timer_val = 0;
74//
75// /**
76// * @brief Configure the necessary clock sources for the radio.
77// * @param None
78// * @retval None
79// */
80// void LINKLAYER_PLAT_ClockInit()
81// {
82// uint32_t linklayer_slp_clk_src = LL_RCC_RADIOSLEEPSOURCE_NONE;
83//
84// /* Get the Link Layer sleep timer clock source */
85// linklayer_slp_clk_src = LL_RCC_RADIO_GetSleepTimerClockSource();
86// if(linklayer_slp_clk_src == LL_RCC_RADIOSLEEPSOURCE_NONE)
87// {
88// /* If there is no clock source defined, should be selected before */
89// assert_param(0);
90// }
91//
92// /* Enable AHB5ENR peripheral clock (bus CLK) */
93// __HAL_RCC_RADIO_CLK_ENABLE();
94// }
95//
96// /**
97// * @brief Link Layer active waiting loop.
98// * @param delay: delay in us
99// * @retval None
100// */
101// void LINKLAYER_PLAT_DelayUs(uint32_t delay)
102// {
103// static uint8_t lock = 0;
104// uint32_t t0;
105// uint32_t primask_bit;
106//
107// /* Enter critical section */
108// primask_bit= __get_PRIMASK();
109// __disable_irq();
110//
111// if (lock == 0U)
112// {
113// /* Initialize counter */
114// /* Reset cycle counter to prevent overflow
115// As a us counter, it is assumed than even with re-entrancy,
116// overflow will never happen before re-initializing this counter */
117// DWT->CYCCNT = 0U;
118// /* Enable DWT by safety but should be useless (as already set) */
119// SET_BIT(DCB->DEMCR, DCB_DEMCR_TRCENA_Msk);
120// /* Enable counter */
121// SET_BIT(DWT->CTRL, DWT_CTRL_CYCCNTENA_Msk);
122// }
123// /* Increment 're-entrance' counter */
124// lock++;
125// /* Get starting time stamp */
126// t0 = DWT->CYCCNT;
127// /* Exit critical section */
128// __set_PRIMASK(primask_bit);
129//
130// /* Turn us into cycles */
131// delay = delay * (SystemCoreClock / 1000000U);
132// delay += t0;
133//
134// /* Busy waiting loop */
135// while (DWT->CYCCNT < delay)
136// {
137// };
138//
139// /* Enter critical section */
140// primask_bit= __get_PRIMASK();
141// __disable_irq();
142// if (lock == 1U)
143// {
144// /* Disable counter */
145// CLEAR_BIT(DWT->CTRL, DWT_CTRL_CYCCNTENA_Msk);
146// }
147// /* Decrement 're-entrance' counter */
148// lock--;
149// /* Exit critical section */
150// __set_PRIMASK(primask_bit);
151//
152// }
153//
154// /**
155// * @brief Link Layer assertion API
156// * @param condition: conditional statement to be checked.
157// * @retval None
158// */
159// void LINKLAYER_PLAT_Assert(uint8_t condition)
160// {
161// assert_param(condition);
162// }
163//
164// /**
165// * @brief Enable/disable the Link Layer active clock (baseband clock).
166// * @param enable: boolean value to enable (1) or disable (0) the clock.
167// * @retval None
168// */
169// void LINKLAYER_PLAT_WaitHclkRdy(void)
170// {
171// /* Wait on radio bus clock readiness if it has been turned of */
172// if (AHB5_SwitchedOff == 1)
173// {
174// AHB5_SwitchedOff = 0;
175// while (radio_sleep_timer_val == ll_intf_cmn_get_slptmr_value());
176// }
177// }
178//
179// /**
180// * @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.
182// * @param None
183// * @retval None
184// */
185// void LINKLAYER_PLAT_NotifyWFIEnter(void)
186// {
187// /* Check if Radio state will allow the AHB5 clock to be cut */
188//
189// /* AHB5 clock will be cut in the following cases:
190// * - 2.4GHz radio is not in ACTIVE mode (in SLEEP or DEEPSLEEP mode).
191// * - RADIOSMEN and STRADIOCLKON bits are at 0.
192// */
193// if((LL_PWR_GetRadioMode() != LL_PWR_RADIO_ACTIVE_MODE) ||
194// ((__HAL_RCC_RADIO_IS_CLK_SLEEP_ENABLED() == 0) && (LL_RCC_RADIO_IsEnabledSleepTimerClock() == 0)))
195// {
196// AHB5_SwitchedOff = 1;
197// }
198// }
199//
200// /**
201// * @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
203// * low power mode entry.
204// * @param None
205// * @retval None
206// */
207// void LINKLAYER_PLAT_NotifyWFIExit(void)
208// {
209// /* Check if AHB5 clock has been turned of and needs resynchronisation */
210// if (AHB5_SwitchedOff)
211// {
212// /* Read sleep register as earlier as possible */
213// radio_sleep_timer_val = ll_intf_cmn_get_slptmr_value();
214// }
215// }
216//
217// /**
218// * @brief Active wait on bus clock readiness.
219// * @param None
220// * @retval None
221// */
222// void LINKLAYER_PLAT_AclkCtrl(uint8_t enable)
223// {
224// if(enable != 0u)
225// {
226// #if (CFG_SCM_SUPPORTED == 1)
227// /* SCM HSE BEGIN */
228// /* Polling on HSE32 activation */
229// SCM_HSE_WaitUntilReady();
230// /* Enable RADIO baseband clock (active CLK) */
231// HAL_RCCEx_EnableRadioBBClock();
232// /* SCM HSE END */
233// #else
234// /* Enable RADIO baseband clock (active CLK) */
235// HAL_RCCEx_EnableRadioBBClock();
236// /* Polling on HSE32 activation */
237// while ( LL_RCC_HSE_IsReady() == 0);
238// #endif /* CFG_SCM_SUPPORTED */
239// }
240// else
241// {
242// /* Disable RADIO baseband clock (active CLK) */
243// HAL_RCCEx_DisableRadioBBClock();
244// }
245// }
246//
247// /**
248// * @brief Link Layer RNG request.
249// * @param ptr_rnd: pointer to the variable that hosts the number.
250// * @param len: number of byte of anthropy to get.
251// * @retval None
252// */
253// void LINKLAYER_PLAT_GetRNG(uint8_t *ptr_rnd, uint32_t len)
254// {
255// uint32_t nb_remaining_rng = len;
256// uint32_t generated_rng;
257//
258// /* Get the requested RNGs (4 bytes by 4bytes) */
259// while(nb_remaining_rng >= 4)
260// {
261// generated_rng = 0;
262// HW_RNG_Get(1, &generated_rng);
263// memcpy((ptr_rnd+(len-nb_remaining_rng)), &generated_rng, 4);
264// nb_remaining_rng -=4;
265// }
266//
267// /* Get the remaining number of RNGs */
268// if(nb_remaining_rng>0){
269// generated_rng = 0;
270// HW_RNG_Get(1, &generated_rng);
271// memcpy((ptr_rnd+(len-nb_remaining_rng)), &generated_rng, nb_remaining_rng);
272// }
273// }
274//
275// /**
276// * @brief Initialize Link Layer radio high priority interrupt.
277// * @param intr_cb: function pointer to assign for the radio high priority ISR routine.
278// * @retval None
279// */
280// void LINKLAYER_PLAT_SetupRadioIT(void (*intr_cb)())
281// {
282// radio_callback = intr_cb;
283// HAL_NVIC_SetPriority((IRQn_Type) RADIO_INTR_NUM, RADIO_INTR_PRIO_HIGH, 0);
284// HAL_NVIC_EnableIRQ((IRQn_Type) RADIO_INTR_NUM);
285// }
286//
287// /**
288// * @brief Initialize Link Layer SW low priority interrupt.
289// * @param intr_cb: function pointer to assign for the SW low priority ISR routine.
290// * @retval None
291// */
292// void LINKLAYER_PLAT_SetupSwLowIT(void (*intr_cb)())
293// {
294// low_isr_callback = intr_cb;
295//
296// HAL_NVIC_SetPriority((IRQn_Type) RADIO_SW_LOW_INTR_NUM, RADIO_SW_LOW_INTR_PRIO, 0);
297// HAL_NVIC_EnableIRQ((IRQn_Type) RADIO_SW_LOW_INTR_NUM);
298// }
299//
300// /**
301// * @brief Trigger the link layer SW low interrupt.
302// * @param None
303// * @retval None
304// */
305// void LINKLAYER_PLAT_TriggerSwLowIT(uint8_t priority)
306// {
307// uint8_t low_isr_priority = RADIO_INTR_PRIO_LOW;
308//
309// /* Check if a SW low interrupt as already been raised.
310// * Nested call far radio low isr are not supported
311// **/
312//
313// if(NVIC_GetActive(RADIO_SW_LOW_INTR_NUM) == 0)
314// {
315// /* No nested SW low ISR, default behavior */
316//
317// if(priority == 0)
318// {
319// low_isr_priority = RADIO_SW_LOW_INTR_PRIO;
320// }
321//
322// HAL_NVIC_SetPriority((IRQn_Type) RADIO_SW_LOW_INTR_NUM, low_isr_priority, 0);
323// }
324// else
325// {
326// /* Nested call detected */
327// /* No change for SW radio low interrupt priority for the moment */
328//
329// if(priority != 0)
330// {
331// /* At the end of current SW radio low ISR, this pending SW low interrupt
332// * will run with RADIO_INTR_PRIO_LOW priority
333// **/
334// radio_sw_low_isr_is_running_high_prio = 1;
335// }
336// }
337//
338// HAL_NVIC_SetPendingIRQ((IRQn_Type) RADIO_SW_LOW_INTR_NUM);
339// }
340//
341// /**
342// * @brief Enable interrupts.
343// * @param None
344// * @retval None
345// */
346// void LINKLAYER_PLAT_EnableIRQ(void)
347// {
348// irq_counter = max(0,irq_counter-1);
349//
350// if(irq_counter == 0)
351// {
352// /* When irq_counter reaches 0, restore primask bit */
353// __set_PRIMASK(primask_bit);
354// }
355// }
356//
357// /**
358// * @brief Disable interrupts.
359// * @param None
360// * @retval None
361// */
362// void LINKLAYER_PLAT_DisableIRQ(void)
363// {
364// if(irq_counter == 0)
365// {
366// /* Save primask bit at first interrupt disablement */
367// primask_bit= __get_PRIMASK();
368// }
369// __disable_irq();
370// irq_counter ++;
371// }
372//
373// /**
374// * @brief Enable specific interrupt group.
375// * @param isr_type: mask for interrupt group to enable.
376// * This parameter can be one of the following:
377// * @arg LL_HIGH_ISR_ONLY: enable link layer high priority ISR.
378// * @arg LL_LOW_ISR_ONLY: enable link layer SW low priority ISR.
379// * @arg SYS_LOW_ISR: mask interrupts for all the other system ISR with
380// * lower priority that link layer SW low interrupt.
381// * @retval None
382// */
383// void LINKLAYER_PLAT_EnableSpecificIRQ(uint8_t isr_type)
384// {
385// if( (isr_type & LL_HIGH_ISR_ONLY) != 0 )
386// {
387// prio_high_isr_counter--;
388// if(prio_high_isr_counter == 0)
389// {
390// /* When specific counter for link layer high ISR reaches 0, interrupt is enabled */
391// HAL_NVIC_EnableIRQ(RADIO_INTR_NUM);
392// /* USER CODE BEGIN LINKLAYER_PLAT_EnableSpecificIRQ_1 */
393//
394// /* USER CODE END LINKLAYER_PLAT_EnableSpecificIRQ_1 */
395// }
396// }
397//
398// if( (isr_type & LL_LOW_ISR_ONLY) != 0 )
399// {
400// prio_low_isr_counter--;
401// if(prio_low_isr_counter == 0)
402// {
403// /* When specific counter for link layer SW low ISR reaches 0, interrupt is enabled */
404// HAL_NVIC_EnableIRQ(RADIO_SW_LOW_INTR_NUM);
405// }
406//
407// }
408//
409// if( (isr_type & SYS_LOW_ISR) != 0 )
410// {
411// prio_sys_isr_counter--;
412// if(prio_sys_isr_counter == 0)
413// {
414// /* Restore basepri value */
415// __set_BASEPRI(local_basepri_value);
416// }
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 */