Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/Flipper-Zero/STM32CubeWB.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorrihab kouki <rihab.kouki@st.com>2021-07-23 12:14:42 +0300
committerrihab kouki <rihab.kouki@st.com>2021-07-23 16:12:38 +0300
commit95f19205e36f1e26409b88e302537cbc8918f7e9 (patch)
tree300d4ed71cc66e1e68c12ebc51aedb5d5136b6c8 /Projects/NUCLEO-WB15CC/Applications/BLE_LLD/BLE_LLD_Lowpower/Core
parent2d1f0ea0748169a268228d0f7b6416e5127e6027 (diff)
Release v1.12.0
Diffstat (limited to 'Projects/NUCLEO-WB15CC/Applications/BLE_LLD/BLE_LLD_Lowpower/Core')
-rw-r--r--Projects/NUCLEO-WB15CC/Applications/BLE_LLD/BLE_LLD_Lowpower/Core/Inc/app_common.h124
-rw-r--r--Projects/NUCLEO-WB15CC/Applications/BLE_LLD/BLE_LLD_Lowpower/Core/Inc/app_conf.h337
-rw-r--r--Projects/NUCLEO-WB15CC/Applications/BLE_LLD/BLE_LLD_Lowpower/Core/Inc/app_entry.h69
-rw-r--r--Projects/NUCLEO-WB15CC/Applications/BLE_LLD/BLE_LLD_Lowpower/Core/Inc/gpio_lld.h179
-rw-r--r--Projects/NUCLEO-WB15CC/Applications/BLE_LLD/BLE_LLD_Lowpower/Core/Inc/hw_conf.h186
-rw-r--r--Projects/NUCLEO-WB15CC/Applications/BLE_LLD/BLE_LLD_Lowpower/Core/Inc/hw_if.h287
-rw-r--r--Projects/NUCLEO-WB15CC/Applications/BLE_LLD/BLE_LLD_Lowpower/Core/Inc/main.h107
-rw-r--r--Projects/NUCLEO-WB15CC/Applications/BLE_LLD/BLE_LLD_Lowpower/Core/Inc/nucleo_wb15cc_conf.h77
-rw-r--r--Projects/NUCLEO-WB15CC/Applications/BLE_LLD/BLE_LLD_Lowpower/Core/Inc/stm32_lpm_if.h79
-rw-r--r--Projects/NUCLEO-WB15CC/Applications/BLE_LLD/BLE_LLD_Lowpower/Core/Inc/stm32wbxx_hal_conf.h353
-rw-r--r--Projects/NUCLEO-WB15CC/Applications/BLE_LLD/BLE_LLD_Lowpower/Core/Inc/stm32wbxx_it.h83
-rw-r--r--Projects/NUCLEO-WB15CC/Applications/BLE_LLD/BLE_LLD_Lowpower/Core/Inc/stm_logging.h63
-rw-r--r--Projects/NUCLEO-WB15CC/Applications/BLE_LLD/BLE_LLD_Lowpower/Core/Inc/utilities_conf.h68
-rw-r--r--Projects/NUCLEO-WB15CC/Applications/BLE_LLD/BLE_LLD_Lowpower/Core/Src/app_entry.c421
-rw-r--r--Projects/NUCLEO-WB15CC/Applications/BLE_LLD/BLE_LLD_Lowpower/Core/Src/gpio_lld.c132
-rw-r--r--Projects/NUCLEO-WB15CC/Applications/BLE_LLD/BLE_LLD_Lowpower/Core/Src/hw_timerserver.c893
-rw-r--r--Projects/NUCLEO-WB15CC/Applications/BLE_LLD/BLE_LLD_Lowpower/Core/Src/hw_uart.c442
-rw-r--r--Projects/NUCLEO-WB15CC/Applications/BLE_LLD/BLE_LLD_Lowpower/Core/Src/main.c607
-rw-r--r--Projects/NUCLEO-WB15CC/Applications/BLE_LLD/BLE_LLD_Lowpower/Core/Src/standby_stm32wb15.c159
-rw-r--r--Projects/NUCLEO-WB15CC/Applications/BLE_LLD/BLE_LLD_Lowpower/Core/Src/stm32_lpm_if.c288
-rw-r--r--Projects/NUCLEO-WB15CC/Applications/BLE_LLD/BLE_LLD_Lowpower/Core/Src/stm32wbxx_hal_msp.c332
-rw-r--r--Projects/NUCLEO-WB15CC/Applications/BLE_LLD/BLE_LLD_Lowpower/Core/Src/stm32wbxx_it.c323
-rw-r--r--Projects/NUCLEO-WB15CC/Applications/BLE_LLD/BLE_LLD_Lowpower/Core/Src/stm_logging.c213
-rw-r--r--Projects/NUCLEO-WB15CC/Applications/BLE_LLD/BLE_LLD_Lowpower/Core/Src/system_stm32wbxx.c355
24 files changed, 6177 insertions, 0 deletions
diff --git a/Projects/NUCLEO-WB15CC/Applications/BLE_LLD/BLE_LLD_Lowpower/Core/Inc/app_common.h b/Projects/NUCLEO-WB15CC/Applications/BLE_LLD/BLE_LLD_Lowpower/Core/Inc/app_common.h
new file mode 100644
index 000000000..5bb0f82f1
--- /dev/null
+++ b/Projects/NUCLEO-WB15CC/Applications/BLE_LLD/BLE_LLD_Lowpower/Core/Inc/app_common.h
@@ -0,0 +1,124 @@
+/* USER CODE BEGIN Header */
+/**
+ ******************************************************************************
+ * File Name : app_common.h
+ * Description : App Common application configuration file for STM32WPAN Middleware.
+ *
+ ******************************************************************************
+ * @attention
+ *
+ * <h2><center>&copy; Copyright (c) 2020 STMicroelectronics.
+ * All rights reserved.</center></h2>
+ *
+ * This software component is licensed by ST under Ultimate Liberty license
+ * SLA0044, the "License"; You may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at:
+ * www.st.com/SLA0044
+ *
+ ******************************************************************************
+ */
+/* USER CODE END Header */
+/* Define to prevent recursive inclusion -------------------------------------*/
+#ifndef APP_COMMON_H
+#define APP_COMMON_H
+
+#ifdef __cplusplus
+extern "C"{
+#endif
+
+#include <stdint.h>
+#include <string.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdarg.h>
+
+#include "main.h"
+#include "app_conf.h"
+
+ /* -------------------------------- *
+ * Basic definitions *
+ * -------------------------------- */
+
+#undef NULL
+#define NULL 0
+
+#undef FALSE
+#define FALSE 0
+
+#undef TRUE
+#define TRUE (!0)
+
+ /* -------------------------------- *
+ * Critical Section definition *
+ * -------------------------------- */
+#define BACKUP_PRIMASK() uint32_t primask_bit= __get_PRIMASK()
+#define DISABLE_IRQ() __disable_irq()
+#define RESTORE_PRIMASK() __set_PRIMASK(primask_bit)
+
+ /* -------------------------------- *
+ * Macro delimiters *
+ * -------------------------------- */
+
+#define M_BEGIN do {
+
+#define M_END } while(0)
+
+ /* -------------------------------- *
+ * Some useful macro definitions *
+ * -------------------------------- */
+
+#ifndef MAX
+#define MAX( x, y ) (((x)>(y))?(x):(y))
+#endif
+
+#ifndef MIN
+#define MIN( x, y ) (((x)<(y))?(x):(y))
+#endif
+
+#define MODINC( a, m ) M_BEGIN (a)++; if ((a)>=(m)) (a)=0; M_END
+
+#define MODDEC( a, m ) M_BEGIN if ((a)==0) (a)=(m); (a)--; M_END
+
+#define MODADD( a, b, m ) M_BEGIN (a)+=(b); if ((a)>=(m)) (a)-=(m); M_END
+
+#define MODSUB( a, b, m ) MODADD( a, (m)-(b), m )
+
+#define PAUSE( t ) M_BEGIN \
+ __IO int _i; \
+ for ( _i = t; _i > 0; _i -- ); \
+ M_END
+
+#define DIVF( x, y ) ((x)/(y))
+
+#define DIVC( x, y ) (((x)+(y)-1)/(y))
+
+#define DIVR( x, y ) (((x)+((y)/2))/(y))
+
+#define SHRR( x, n ) ((((x)>>((n)-1))+1)>>1)
+
+#define BITN( w, n ) (((w)[(n)/32] >> ((n)%32)) & 1)
+
+#define BITNSET( w, n, b ) M_BEGIN (w)[(n)/32] |= ((U32)(b))<<((n)%32); M_END
+
+#define CRITICAL_BEGIN( ) M_BEGIN BACKUP_PRIMASK(); DISABLE_IRQ()
+
+#define CRITICAL_END( ) RESTORE_PRIMASK(); M_END
+
+ /* -------------------------------- *
+ * Compiler *
+ * -------------------------------- */
+#define PLACE_IN_SECTION( __x__ ) __attribute__((section (__x__)))
+
+#ifdef WIN32
+#define ALIGN(n)
+#else
+#define ALIGN(n) __attribute__((aligned(n)))
+#endif
+
+#ifdef __cplusplus
+} /* extern "C" */
+#endif
+
+#endif /*APP_COMMON_H */
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/Projects/NUCLEO-WB15CC/Applications/BLE_LLD/BLE_LLD_Lowpower/Core/Inc/app_conf.h b/Projects/NUCLEO-WB15CC/Applications/BLE_LLD/BLE_LLD_Lowpower/Core/Inc/app_conf.h
new file mode 100644
index 000000000..b21ab05e2
--- /dev/null
+++ b/Projects/NUCLEO-WB15CC/Applications/BLE_LLD/BLE_LLD_Lowpower/Core/Inc/app_conf.h
@@ -0,0 +1,337 @@
+/* USER CODE BEGIN Header */
+/**
+ ******************************************************************************
+ * File Name : app_conf.h
+ * Description : Application configuration file for STM32WPAN Middleware.
+ ******************************************************************************
+ * @attention
+ *
+ * <h2><center>&copy; Copyright (c) 2020 STMicroelectronics.
+ * All rights reserved.</center></h2>
+ *
+ * This software component is licensed by ST under Ultimate Liberty license
+ * SLA0044, the "License"; You may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at:
+ * www.st.com/SLA0044
+ *
+ ******************************************************************************
+ */
+/* USER CODE END Header */
+
+/* Define to prevent recursive inclusion -------------------------------------*/
+#ifndef APP_CONF_H
+#define APP_CONF_H
+
+#include "hw.h"
+#include "hw_conf.h"
+#include "hw_if.h"
+
+/******************************************************************************
+ * Application Config
+ ******************************************************************************/
+#define CFG_HS_STARTUP_TIME 0x0099 /* Start up time of the high speed oscillator in system time units (625/256us) */
+
+#define CFG_BACK2BACK_TIME 200 /* Back to back time (us) */
+
+/******************************************************************************
+ * Transport Layer
+ ******************************************************************************/
+/**
+ * Queue length of M0 traces/log messages
+ * This parameter defines the number of asynchronous events that can be stored in the M0 test FW before
+ * being reported to the M4 which will re-build traces/log messages before to send them to UART.
+ * This parameter is combined with the CFG_TL_MOST_EVENT_PAYLOAD_SIZE to calculate the queue size needed by M0 for traces.
+ */
+#define CFG_TL_EVT_QUEUE_LENGTH 20
+/**
+ * TL_EVENT_FRAME_SIZE is the size of the packets transfered between M0 and M4 through IPCC.
+ * Note 1 : thoose packets are first put in a trace queue (see DBG_TRACE_MSG_QUEUE_SIZE) before beeing sent to UART
+ * Note 2 : Queue size must be higher than a M0 trace buffer max size (see LOG_BUFFER_SIZE_MAX in M0 FW)
+ */
+#define CFG_TL_MOST_EVENT_PAYLOAD_SIZE 255
+
+#define TL_EVENT_FRAME_SIZE ( TL_EVT_HDR_SIZE + CFG_TL_MOST_EVENT_PAYLOAD_SIZE )
+
+/******************************************************************************
+ * UART interfaces
+ ******************************************************************************/
+/**
+ * Select UART interfaces
+ */
+#define CFG_DEBUG_TRACE_UART hw_lpuart1
+#define CFG_UART hw_uart1
+
+/******************************************************************************
+ * USB interface
+ ******************************************************************************/
+
+/**
+ * Enable/Disable USB interface
+ */
+#define CFG_USB_INTERFACE_ENABLE 0
+
+/******************************************************************************
+ * Low Power
+ *
+ * When BLE_LLD_LP is set to 1:
+ * the system is configured in low power mode CFG_LPM_SUPPORTED
+ *
+ * When BLE_LLD_LP is not set, the low power mode is not activated
+ *
+ ******************************************************************************/
+#define CFG_LPM_SUPPORTED 0
+
+#ifdef BLE_LLD_LP
+#undef CFG_LPM_SUPPORTED
+#define CFG_LPM_SUPPORTED 1
+#endif
+
+#define CFG_PWR_MODE_STOP LL_PWR_MODE_STOP1
+
+/******************************************************************************
+ * Timer Server
+ ******************************************************************************/
+/**
+ * CFG_RTC_WUCKSEL_DIVIDER: This sets the RTCCLK divider to the wakeup timer.
+ * The higher is the value, the better is the power consumption and the accuracy of the timerserver
+ * The lower is the value, the finest is the granularity
+ *
+ * CFG_RTC_ASYNCH_PRESCALER: This sets the asynchronous prescaler of the RTC. It should as high as possible ( to ouput
+ * clock as low as possible) but the output clock should be equal or higher frequency compare to the clock feeding
+ * the wakeup timer. A lower clock speed would impact the accuracy of the timer server.
+ *
+ * CFG_RTC_SYNCH_PRESCALER: This sets the synchronous prescaler of the RTC.
+ * When the 1Hz calendar clock is required, it shall be sets according to other settings
+ * When the 1Hz calendar clock is not needed, CFG_RTC_SYNCH_PRESCALER should be set to 0x7FFF (MAX VALUE)
+ *
+ * CFG_RTCCLK_DIVIDER_CONF:
+ * Shall be set to either 0,2,4,8,16
+ * When set to either 2,4,8,16, the 1Hhz calendar is supported
+ * When set to 0, the user sets its own configuration
+ *
+ * The following settings are computed with LSI as input to the RTC
+ */
+#define CFG_RTCCLK_DIVIDER_CONF 0
+
+#if (CFG_RTCCLK_DIVIDER_CONF == 0)
+/**
+ * Custom configuration
+ * It does not support 1Hz calendar
+ * It divides the RTC CLK by 16
+ */
+#define CFG_RTCCLK_DIV (16)
+#define CFG_RTC_WUCKSEL_DIVIDER (0)
+#define CFG_RTC_ASYNCH_PRESCALER (CFG_RTCCLK_DIV - 1)
+#define CFG_RTC_SYNCH_PRESCALER (0x7FFF)
+
+#else
+
+#if (CFG_RTCCLK_DIVIDER_CONF == 2)
+/**
+ * It divides the RTC CLK by 2
+ */
+#define CFG_RTC_WUCKSEL_DIVIDER (3)
+#endif
+
+#if (CFG_RTCCLK_DIVIDER_CONF == 4)
+/**
+ * It divides the RTC CLK by 4
+ */
+#define CFG_RTC_WUCKSEL_DIVIDER (2)
+#endif
+
+#if (CFG_RTCCLK_DIVIDER_CONF == 8)
+/**
+ * It divides the RTC CLK by 8
+ */
+#define CFG_RTC_WUCKSEL_DIVIDER (1)
+#endif
+
+#if (CFG_RTCCLK_DIVIDER_CONF == 16)
+/**
+ * It divides the RTC CLK by 16
+ */
+#define CFG_RTC_WUCKSEL_DIVIDER (0)
+#endif
+
+#define CFG_RTCCLK_DIV CFG_RTCCLK_DIVIDER_CONF
+#define CFG_RTC_ASYNCH_PRESCALER (CFG_RTCCLK_DIV - 1)
+#define CFG_RTC_SYNCH_PRESCALER (DIVR( LSE_VALUE, (CFG_RTC_ASYNCH_PRESCALER+1) ) - 1 )
+
+#endif
+
+/** tick timer value in us */
+#define CFG_TS_TICK_VAL DIVR( (CFG_RTCCLK_DIV * 1000000), LSE_VALUE )
+
+typedef enum
+{
+ CFG_TIM_PROC_ID_ISR,
+} CFG_TimProcID_t;
+
+/******************************************************************************
+ * Debug
+ ******************************************************************************/
+/**
+ * When set, this resets some hw resources to set the device in the same state than the power up
+ * The FW resets only register that may prevent the FW to run properly
+ *
+ * This shall be set to 0 in a final product
+ *
+ */
+#define CFG_HW_RESET_BY_FW 1
+
+/**
+ * keep debugger enabled while in any low power mode when set to 1
+ * should be set to 0 in production
+ */
+#define CFG_DEBUGGER_SUPPORTED 1
+
+#if (CFG_LPM_SUPPORTED == 1)
+#undef CFG_DEBUGGER_SUPPORTED
+#define CFG_DEBUGGER_SUPPORTED 0
+#endif
+
+/*****************************************************************************
+ * Traces
+ * Enable or Disable traces in application
+ * When CFG_DEBUG_TRACE is set, traces are activated
+ *
+ * Note : Refer to utilities_conf.h file in order to details
+ * the level of traces : CFG_DEBUG_TRACE_FULL or CFG_DEBUG_TRACE_LIGHT
+ *****************************************************************************/
+#define CFG_DEBUG_TRACE 1
+
+#if (CFG_LPM_SUPPORTED == 1)
+#undef CFG_DEBUG_TRACE
+#define CFG_DEBUG_TRACE 0
+#endif
+
+/**
+ * When CFG_DEBUG_TRACE_FULL is set to 1, the trace are output with the API name, the file name and the line number
+ * When CFG_DEBUG_TRACE_LIGHT is set to 1, only the debug message is output
+ *
+ * When both are set to 0, no trace are output
+ * When both are set to 1, CFG_DEBUG_TRACE_FULL is selected
+ */
+#define CFG_DEBUG_TRACE_LIGHT 1
+#define CFG_DEBUG_TRACE_FULL 0
+
+#if (( CFG_DEBUG_TRACE != 0 ) && ( CFG_DEBUG_TRACE_LIGHT == 0 ) && (CFG_DEBUG_TRACE_FULL == 0))
+#undef CFG_DEBUG_TRACE_FULL
+#undef CFG_DEBUG_TRACE_LIGHT
+#define CFG_DEBUG_TRACE_FULL 0
+#define CFG_DEBUG_TRACE_LIGHT 1
+#endif
+
+#if ( CFG_DEBUG_TRACE == 0 )
+#undef CFG_DEBUG_TRACE_FULL
+#undef CFG_DEBUG_TRACE_LIGHT
+#define CFG_DEBUG_TRACE_FULL 0
+#define CFG_DEBUG_TRACE_LIGHT 0
+#endif
+
+/**
+ * When not set, the traces is looping on sending the trace over UART
+ */
+#define DBG_TRACE_USE_CIRCULAR_QUEUE 1
+
+/**
+ * max buffer Size to queue data traces and max data trace allowed.
+ * Only Used if DBG_TRACE_USE_CIRCULAR_QUEUE is defined
+ */
+#define DBG_TRACE_MSG_QUEUE_SIZE 4096
+#define MAX_DBG_TRACE_MSG_SIZE 1024
+
+/******************************************************************************
+ * Configure Log level for Application
+ ******************************************************************************/
+#define APPLI_CONFIG_LOG_LEVEL LOG_LEVEL_INFO
+#define APPLI_PRINT_FILE_FUNC_LINE 0
+
+/* USER CODE BEGIN Defines */
+/******************************************************************************
+ * User interaction
+ * When CFG_LED_SUPPORTED is set, LEDS are activated if requested
+ * When CFG_BUTTON_SUPPORTED is set, the push button are activated if requested
+ ******************************************************************************/
+#if (CFG_LPM_SUPPORTED == 1)
+#define CFG_LED_SUPPORTED 0
+#define CFG_BUTTON_SUPPORTED 0
+#else
+#define CFG_LED_SUPPORTED 1
+#define CFG_BUTTON_SUPPORTED 1
+#endif
+
+
+/* USER CODE END Defines */
+
+/******************************************************************************
+ * Scheduler
+ ******************************************************************************/
+ /**
+ * This is the list of task id required by the application
+ * Each Id shall be in the range 0..31
+ */
+
+typedef enum
+{
+ CFG_TASK_CMD_FROM_M0_TO_M4,
+ CFG_TASK_SEND_CLI_TO_M0,
+ CFG_TASK_SEND_TO_M0,
+/* USER CODE BEGIN IdleTask */
+ CFG_TASK_TIMER,
+/* USER CODE END IdleTask */
+ CFG_TASK_SYSTEM_HCI_ASYNCH_EVT,
+ CFG_TASK_PROCESS_UART_RX_BUFFER,
+ CFG_TASK_PROCESS_UART_RX_IT,
+ CFG_TASK_PROCESS_UART_TX_IT,
+ CFG_TASK_NBR /**< Shall be last in the list */
+} CFG_IdleTask_Id_t;
+
+/**
+ * This is the list of priority required by the application
+ * Each Id shall be in the range 0..31
+ */
+typedef enum
+{
+ CFG_SCH_PRIO_0,
+ CFG_SCH_PRIO_1,
+ CFG_PRIO_NBR,
+} CFG_SCH_Prio_Id_t;
+
+/**
+ * This is a bit mapping over 32bits listing all events id supported in the application
+ */
+typedef enum
+{
+ CFG_EVT_SYSTEM_HCI_CMD_EVT_RESP,
+ CFG_EVT_RECEIVE_RSPACKEVT,
+ CFG_EVT_RECEIVE_ENDPACKEVT,
+} CFG_IdleEvt_Id_t;
+
+/******************************************************************************
+ * LOW POWER
+ ******************************************************************************/
+/**
+ * Supported requester to the MCU Low Power Manager - can be increased up to 32
+ * It lits a bit mapping of all user of the Low Power Manager
+ */
+typedef enum
+{
+ CFG_LPM_APP,
+ CFG_LPM_APP_BLE_LLD,
+ /* USER CODE BEGIN CFG_LPM_Id_t */
+
+ /* USER CODE END CFG_LPM_Id_t */
+} CFG_LPM_Id_t;
+
+/******************************************************************************
+ * OTP manager
+ ******************************************************************************/
+#define CFG_OTP_BASE_ADDRESS OTP_AREA_BASE
+
+#define CFG_OTP_END_ADRESS OTP_AREA_END_ADDR
+
+#endif /*APP_CONF_H */
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/Projects/NUCLEO-WB15CC/Applications/BLE_LLD/BLE_LLD_Lowpower/Core/Inc/app_entry.h b/Projects/NUCLEO-WB15CC/Applications/BLE_LLD/BLE_LLD_Lowpower/Core/Inc/app_entry.h
new file mode 100644
index 000000000..77ead2384
--- /dev/null
+++ b/Projects/NUCLEO-WB15CC/Applications/BLE_LLD/BLE_LLD_Lowpower/Core/Inc/app_entry.h
@@ -0,0 +1,69 @@
+/* USER CODE BEGIN Header */
+/**
+ ******************************************************************************
+ * @file app_entry.h
+ * @author MCD Application Team
+ * @brief Interface to the application
+ ******************************************************************************
+ * @attention
+ *
+ * <h2><center>&copy; Copyright (c) 2019 STMicroelectronics.
+ * All rights reserved.</center></h2>
+ *
+ * This software component is licensed by ST under Ultimate Liberty license
+ * SLA0044, the "License"; You may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at:
+ * www.st.com/SLA0044
+ *
+ ******************************************************************************
+ */
+/* USER CODE END Header */
+
+/* Define to prevent recursive inclusion -------------------------------------*/
+#ifndef APP_ENTRY_H
+#define APP_ENTRY_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* Includes ------------------------------------------------------------------*/
+
+/* Private includes ----------------------------------------------------------*/
+/* USER CODE BEGIN Includes */
+
+/* USER CODE END Includes */
+
+ /* Exported types ------------------------------------------------------------*/
+/* USER CODE BEGIN ET */
+
+/* USER CODE END ET */
+
+/* Exported constants --------------------------------------------------------*/
+/* USER CODE BEGIN EC */
+
+/* USER CODE END EC */
+
+/* Exported variables --------------------------------------------------------*/
+/* USER CODE BEGIN EV */
+
+/* USER CODE END EV */
+
+/* Exported macros ------------------------------------------------------------*/
+/* USER CODE BEGIN EM */
+
+/* USER CODE END EM */
+
+/* Exported functions ---------------------------------------------*/
+ void APPE_Init( void );
+/* USER CODE BEGIN EF */
+
+/* USER CODE END EF */
+
+#ifdef __cplusplus
+} /* extern "C" */
+#endif
+
+#endif /*APP_ENTRY_H */
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/Projects/NUCLEO-WB15CC/Applications/BLE_LLD/BLE_LLD_Lowpower/Core/Inc/gpio_lld.h b/Projects/NUCLEO-WB15CC/Applications/BLE_LLD/BLE_LLD_Lowpower/Core/Inc/gpio_lld.h
new file mode 100644
index 000000000..e9ceb78c0
--- /dev/null
+++ b/Projects/NUCLEO-WB15CC/Applications/BLE_LLD/BLE_LLD_Lowpower/Core/Inc/gpio_lld.h
@@ -0,0 +1,179 @@
+/*
+ * gpio_lld.h
+ *
+ */
+
+#ifndef GPIO_LLD_H_
+#define GPIO_LLD_H_
+
+#define GPIO_HARD_FAULT_PIN GPIO_PIN_4
+#define GPIO_HARD_FAULT_PORT GPIOA
+
+// External PA TX/RX pin is fixed by the chip
+#define GPIO_EXT_PA_TX_PIN GPIO_PIN_0
+#define GPIO_EXT_PA_TX_PORT GPIOB
+// External PA enable pin is chosen by user
+#define GPIO_EXT_PA_EN_PIN GPIO_PIN_9
+#define GPIO_EXT_PA_EN_PORT GPIOB
+
+void gpio_lld_phy_init( void );
+void gpio_lld_phy_gpioTx_up(void);
+void gpio_lld_phy_gpioTx_down(void);
+void gpio_lld_phy_gpioHardFault_up(void);
+void gpio_lld_phy_gpioHardFault_down(void);
+void gpio_lld_phy_gpio1_up(void);
+void gpio_lld_phy_gpio1_down(void);
+void gpio_lld_phy_gpio2_up(void);
+void gpio_lld_phy_gpio2_down(void);
+void gpio_lld_phy_deInit(void);
+
+void gpio_lld_mco_init(uint32_t mcoSource, uint32_t mcoDiv);
+void gpio_lld_mco_deInit(void);
+
+void gpio_lld_extPa_init(void);
+void gpio_lld_extPa_deInit(void);
+
+#ifdef USE_SIMU
+void gpio_lld_SimuMaster_init(void);
+void gpio_lld_SimuSlave_init(void);
+#endif
+
+void gpio_lld_lpuart_init(void);
+void gpio_lld_lpuart_deInit(void);
+
+void gpio_lld_usart_init(void);
+void gpio_lld_usart_deInit(void);
+
+#if !defined (USE_SIMU) && !defined(USE_FPGA)
+void gpio_lld_pa2_init(uint8_t mode);
+void gpio_lld_pa2_deInit(void);
+
+void gpio_lld_dtb_init(uint8_t dtbMode);
+void gpio_lld_dtb_deInit(void);
+#endif
+
+void gpio_lld_led1_toggle(void);
+void gpio_lld_led2_toggle(void);
+void gpio_lld_led3_toggle(void);
+
+#ifdef STM32WB15xx
+#define BUTTON_SW1_EXTI_IRQHandler EXTI0_IRQHandler
+#define BUTTON_SW2_EXTI_IRQHandler EXTI4_IRQHandler
+#define BUTTON_SW3_EXTI_IRQHandler EXTI9_5_IRQHandler
+
+/**
+ * @brief USART pins
+ */
+#define USART_CLK_ENABLE() __HAL_RCC_USART1_CLK_ENABLE()
+
+#define USART_TX_AF GPIO_AF7_USART1
+#define USART_TX_GPIO_PORT GPIOA
+#define USART_TX_PIN GPIO_PIN_9
+#define USART_TX_GPIO_CLK_ENABLE() __HAL_RCC_GPIOA_CLK_ENABLE()
+#define USART_TX_GPIO_CLK_DISABLE() __HAL_RCC_GPIOA_CLK_DISABLE()
+
+#define USART_RX_AF GPIO_AF7_USART1
+#define USART_RX_GPIO_PORT GPIOA
+#define USART_RX_PIN GPIO_PIN_10
+#define USART_RX_GPIO_CLK_ENABLE() __HAL_RCC_GPIOA_CLK_ENABLE()
+#define USART_RX_GPIO_CLK_DISABLE() __HAL_RCC_GPIOA_CLK_DISABLE()
+
+/**
+ * @brief LPUART pins
+ */
+#define LPUART_CLK_ENABLE() __HAL_RCC_LPUART1_CLK_ENABLE()
+
+#define LPUART_TX_AF GPIO_AF8_LPUART1
+#define LPUART_TX_GPIO_PORT GPIOA
+#define LPUART_TX_PIN GPIO_PIN_2
+#define LPUART_TX_GPIO_CLK_ENABLE() __HAL_RCC_GPIOA_CLK_ENABLE()
+#define LPUART_TX_GPIO_CLK_DISABLE() __HAL_RCC_GPIOA_CLK_DISABLE()
+
+#define LPUART_RX_AF GPIO_AF8_LPUART1
+#define LPUART_RX_GPIO_PORT GPIOA
+#define LPUART_RX_PIN GPIO_PIN_3
+#define LPUART_RX_GPIO_CLK_ENABLE() __HAL_RCC_GPIOA_CLK_ENABLE()
+#define LPUART_RX_GPIO_CLK_DISABLE() __HAL_RCC_GPIOA_CLK_DISABLE()
+#endif
+
+#ifdef STM32WB35xx
+#define BUTTON_SW1_EXTI_IRQHandler EXTI0_IRQHandler
+#define BUTTON_SW2_EXTI_IRQHandler EXTI4_IRQHandler
+#define BUTTON_SW3_EXTI_IRQHandler EXTI9_5_IRQHandler
+
+/**
+ * @brief USART pins
+ */
+#define USART_CLK_ENABLE() __HAL_RCC_USART1_CLK_ENABLE()
+
+#define USART_TX_AF GPIO_AF7_USART1
+#define USART_TX_GPIO_PORT GPIOB
+#define USART_TX_PIN GPIO_PIN_6
+#define USART_TX_GPIO_CLK_ENABLE() __HAL_RCC_GPIOB_CLK_ENABLE()
+#define USART_TX_GPIO_CLK_DISABLE() __HAL_RCC_GPIOB_CLK_DISABLE()
+
+#define USART_RX_AF GPIO_AF7_USART1
+#define USART_RX_GPIO_PORT GPIOB
+#define USART_RX_PIN GPIO_PIN_7
+#define USART_RX_GPIO_CLK_ENABLE() __HAL_RCC_GPIOB_CLK_ENABLE()
+#define USART_RX_GPIO_CLK_DISABLE() __HAL_RCC_GPIOB_CLK_DISABLE()
+
+/**
+ * @brief LPUART pins
+ */
+#define LPUART_CLK_ENABLE() __HAL_RCC_LPUART1_CLK_ENABLE()
+
+#define LPUART_TX_AF GPIO_AF8_LPUART1
+#define LPUART_TX_GPIO_PORT GPIOB
+#define LPUART_TX_PIN GPIO_PIN_5
+#define LPUART_TX_GPIO_CLK_ENABLE() __HAL_RCC_GPIOB_CLK_ENABLE()
+#define LPUART_TX_GPIO_CLK_DISABLE() __HAL_RCC_GPIOB_CLK_DISABLE()
+
+#define LPUART_RX_AF GPIO_AF8_LPUART1
+#define LPUART_RX_GPIO_PORT GPIOA
+#define LPUART_RX_PIN GPIO_PIN_3
+#define LPUART_RX_GPIO_CLK_ENABLE() __HAL_RCC_GPIOA_CLK_ENABLE()
+#define LPUART_RX_GPIO_CLK_DISABLE() __HAL_RCC_GPIOA_CLK_DISABLE()
+#endif
+
+#ifdef STM32WB55xx
+#define BUTTON_SW1_EXTI_IRQHandler EXTI4_IRQHandler
+#define BUTTON_SW2_EXTI_IRQHandler EXTI0_IRQHandler
+#define BUTTON_SW3_EXTI_IRQHandler EXTI1_IRQHandler
+
+/**
+ * @brief USART pins
+ */
+#define USART_CLK_ENABLE() __HAL_RCC_USART1_CLK_ENABLE()
+
+#define USART_TX_AF GPIO_AF7_USART1
+#define USART_TX_GPIO_PORT GPIOB
+#define USART_TX_PIN GPIO_PIN_6
+#define USART_TX_GPIO_CLK_ENABLE() __HAL_RCC_GPIOB_CLK_ENABLE()
+#define USART_TX_GPIO_CLK_DISABLE() __HAL_RCC_GPIOB_CLK_DISABLE()
+
+#define USART_RX_AF GPIO_AF7_USART1
+#define USART_RX_GPIO_PORT GPIOB
+#define USART_RX_PIN GPIO_PIN_7
+#define USART_RX_GPIO_CLK_ENABLE() __HAL_RCC_GPIOB_CLK_ENABLE()
+#define USART_RX_GPIO_CLK_DISABLE() __HAL_RCC_GPIOB_CLK_DISABLE()
+
+/**
+ * @brief LPUART pins
+ */
+#define LPUART_CLK_ENABLE() __HAL_RCC_LPUART1_CLK_ENABLE()
+
+#define LPUART_TX_AF GPIO_AF8_LPUART1
+#define LPUART_TX_GPIO_PORT GPIOC
+#define LPUART_TX_PIN GPIO_PIN_1
+#define LPUART_TX_GPIO_CLK_ENABLE() __HAL_RCC_GPIOC_CLK_ENABLE()
+#define LPUART_TX_GPIO_CLK_DISABLE() __HAL_RCC_GPIOC_CLK_DISABLE()
+
+#define LPUART_RX_AF GPIO_AF8_LPUART1
+#define LPUART_RX_GPIO_PORT GPIOC
+#define LPUART_RX_PIN GPIO_PIN_0
+#define LPUART_RX_GPIO_CLK_ENABLE() __HAL_RCC_GPIOC_CLK_ENABLE()
+#define LPUART_RX_GPIO_CLK_DISABLE() __HAL_RCC_GPIOC_CLK_DISABLE()
+#endif
+
+#endif /* GPIO_LLD_H_ */
diff --git a/Projects/NUCLEO-WB15CC/Applications/BLE_LLD/BLE_LLD_Lowpower/Core/Inc/hw_conf.h b/Projects/NUCLEO-WB15CC/Applications/BLE_LLD/BLE_LLD_Lowpower/Core/Inc/hw_conf.h
new file mode 100644
index 000000000..cec656da9
--- /dev/null
+++ b/Projects/NUCLEO-WB15CC/Applications/BLE_LLD/BLE_LLD_Lowpower/Core/Inc/hw_conf.h
@@ -0,0 +1,186 @@
+/* USER CODE BEGIN Header */
+/**
+ ******************************************************************************
+ * File Name : hw_conf.h
+ * Description : Hardware configuration file for the application.
+ ******************************************************************************
+ * @attention
+ *
+ * <h2><center>&copy; Copyright (c) 2019 STMicroelectronics.
+ * All rights reserved.</center></h2>
+ *
+ * This software component is licensed by ST under Ultimate Liberty license
+ * SLA0044, the "License"; You may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at:
+ * www.st.com/SLA0044
+ *
+ ******************************************************************************
+ */
+/* USER CODE END Header */
+
+/* Define to prevent recursive inclusion -------------------------------------*/
+#ifndef HW_CONF_H
+#define HW_CONF_H
+
+/******************************************************************************
+ * Semaphores
+ * THIS SHALL NO BE CHANGED AS THESE SEMAPHORES ARE USED AS WELL ON THE CM0+
+ *****************************************************************************/
+/**
+* The CPU2 may be configured to store the Thread persistent data either in internal NVM storage on CPU2 or in
+* SRAM2 buffer provided by the user application. This can be configured with the system command SHCI_C2_Config()
+* When the CPU2 is requested to store persistent data in SRAM2, it can write data in this buffer at any time when needed.
+* In order to read consistent data with the CPU1 from the SRAM2 buffer, the flow should be:
+* + CPU1 takes CFG_HW_THREAD_NVM_SRAM_SEMID semaphore
+* + CPU1 reads all persistent data from SRAM2 (most of the time, the goal is to write these data into an NVM managed by CPU1)
+* + CPU1 releases CFG_HW_THREAD_NVM_SRAM_SEMID semaphore
+* CFG_HW_THREAD_NVM_SRAM_SEMID semaphore makes sure CPU2 does not update the persistent data in SRAM2 at the same time CPU1 is reading them.
+* There is no timing constraint on how long this semaphore can be kept.
+*/
+#define CFG_HW_THREAD_NVM_SRAM_SEMID 9
+
+/**
+* The CPU2 may be configured to store the BLE persistent data either in internal NVM storage on CPU2 or in
+* SRAM2 buffer provided by the user application. This can be configured with the system command SHCI_C2_Config()
+* When the CPU2 is requested to store persistent data in SRAM2, it can write data in this buffer at any time when needed.
+* In order to read consistent data with the CPU1 from the SRAM2 buffer, the flow should be:
+* + CPU1 takes CFG_HW_BLE_NVM_SRAM_SEMID semaphore
+* + CPU1 reads all persistent data from SRAM2 (most of the time, the goal is to write these data into an NVM managed by CPU1)
+* + CPU1 releases CFG_HW_BLE_NVM_SRAM_SEMID semaphore
+* CFG_HW_BLE_NVM_SRAM_SEMID semaphore makes sure CPU2 does not update the persistent data in SRAM2 at the same time CPU1 is reading them.
+* There is no timing constraint on how long this semaphore can be kept.
+*/
+#define CFG_HW_BLE_NVM_SRAM_SEMID 8
+
+/**
+* Index of the semaphore used by CPU2 to prevent the CPU1 to either write or erase data in flash
+* The CPU1 shall not either write or erase in flash when this semaphore is taken by the CPU2
+* When the CPU1 needs to either write or erase in flash, it shall first get the semaphore and release it just
+* after writing a raw (64bits data) or erasing one sector.
+* On v1.4.0 and older CPU2 wireless firmware, this semaphore is unused and CPU2 is using PES bit.
+* By default, CPU2 is using the PES bit to protect its timing. The CPU1 may request the CPU2 to use the semaphore
+* instead of the PES bit by sending the system command SHCI_C2_SetFlashActivityControl()
+*/
+#define CFG_HW_BLOCK_FLASH_REQ_BY_CPU2_SEMID 7
+
+/**
+* Index of the semaphore used by CPU1 to prevent the CPU2 to either write or erase data in flash
+* In order to protect its timing, the CPU1 may get this semaphore to prevent the CPU2 to either
+* write or erase in flash (as this will stall both CPUs)
+* The PES bit shall not be used as this may stall the CPU2 in some cases.
+*/
+#define CFG_HW_BLOCK_FLASH_REQ_BY_CPU1_SEMID 6
+
+/**
+* Index of the semaphore used to manage the CLK48 clock configuration
+* When the USB is required, this semaphore shall be taken before configuring te CLK48 for USB
+* and should be released after the application switch OFF the clock when the USB is not used anymore
+* When using the RNG, it is good enough to use CFG_HW_RNG_SEMID to control CLK48.
+* More details in AN5289
+*/
+#define CFG_HW_CLK48_CONFIG_SEMID 5
+
+/* Index of the semaphore used to manage the entry Stop Mode procedure */
+#define CFG_HW_ENTRY_STOP_MODE_SEMID 4
+
+/* Index of the semaphore used to access the RCC */
+#define CFG_HW_RCC_SEMID 3
+
+/* Index of the semaphore used to access the FLASH */
+#define CFG_HW_FLASH_SEMID 2
+
+/* Index of the semaphore used to access the PKA */
+#define CFG_HW_PKA_SEMID 1
+
+/* Index of the semaphore used to access the RNG */
+#define CFG_HW_RNG_SEMID 0
+
+/******************************************************************************
+ * HW TIMER SERVER
+ *****************************************************************************/
+/**
+ * The user may define the maximum number of virtual timers supported.
+ * It shall not exceed 255
+ */
+#define CFG_HW_TS_MAX_NBR_CONCURRENT_TIMER 6
+
+/**
+ * The user may define the priority in the NVIC of the RTC_WKUP interrupt handler that is used to manage the
+ * wakeup timer.
+ * This setting is the preemptpriority part of the NVIC.
+ */
+#define CFG_HW_TS_NVIC_RTC_WAKEUP_IT_PREEMPTPRIO 3
+
+/**
+ * The user may define the priority in the NVIC of the RTC_WKUP interrupt handler that is used to manage the
+ * wakeup timer.
+ * This setting is the subpriority part of the NVIC. It does not exist on all processors. When it is not supported
+ * on the CPU, the setting is ignored
+ */
+#define CFG_HW_TS_NVIC_RTC_WAKEUP_IT_SUBPRIO 0
+
+/**
+ * Define a critical section in the Timer server
+ * The Timer server does not support the API to be nested
+ * The Application shall either:
+ * a) Ensure this will never happen
+ * b) Define the critical section
+ * The default implementations is masking all interrupts using the PRIMASK bit
+ * The TimerServer driver uses critical sections to avoid context corruption. This is achieved with the macro
+ * TIMER_ENTER_CRITICAL_SECTION and TIMER_EXIT_CRITICAL_SECTION. When CFG_HW_TS_USE_PRIMASK_AS_CRITICAL_SECTION is set
+ * to 1, all STM32 interrupts are masked with the PRIMASK bit of the CortexM CPU. It is possible to use the BASEPRI
+ * register of the CortexM CPU to keep allowed some interrupts with high priority. In that case, the user shall
+ * re-implement TIMER_ENTER_CRITICAL_SECTION and TIMER_EXIT_CRITICAL_SECTION and shall make sure that no TimerServer
+ * API are called when the TIMER critical section is entered
+ */
+#define CFG_HW_TS_USE_PRIMASK_AS_CRITICAL_SECTION 1
+
+/**
+ * This value shall reflect the maximum delay there could be in the application between the time the RTC interrupt
+ * is generated by the Hardware and the time when the RTC interrupt handler is called. This time is measured in
+ * number of RTCCLK ticks.
+ * A relaxed timing would be 10ms
+ * When the value is too short, the timerserver will not be able to count properly and all timeout may be random.
+ * When the value is too long, the device may wake up more often than the most optimal configuration. However, the
+ * impact on power consumption would be marginal (unless the value selected is extremely too long). It is strongly
+ * recommended to select a value large enough to make sure it is not too short to ensure reliability of the system
+ * as this will have marginal impact on low power mode
+ */
+#define CFG_HW_TS_RTC_HANDLER_MAX_DELAY ( 10 * (LSI_VALUE/1000) )
+
+ /**
+ * Interrupt ID in the NVIC of the RTC Wakeup interrupt handler
+ * It shall be type of IRQn_Type
+ */
+#define CFG_HW_TS_RTC_WAKEUP_HANDLER_ID RTC_WKUP_IRQn
+
+
+
+/******************************************************************************
+ * HW UART
+ *****************************************************************************/
+#if (CFG_LPM_SUPPORTED == 0)
+#define CFG_HW_LPUART1_ENABLED 1
+#define CFG_HW_LPUART1_DMA_TX_SUPPORTED 1
+#define CFG_HW_USART1_ENABLED 1
+#define CFG_HW_USART1_DMA_TX_SUPPORTED 1
+
+#else
+#define CFG_HW_LPUART1_ENABLED 0
+#define CFG_HW_LPUART1_DMA_TX_SUPPORTED 0
+#define CFG_HW_USART1_ENABLED 0
+#define CFG_HW_USART1_DMA_TX_SUPPORTED 0
+#endif
+/******************************************************************************
+ * External PA
+ *****************************************************************************/
+
+#if (CFG_LPM_SUPPORTED == 0)
+#define CFG_HW_EXTPA_ENABLED 1
+#else
+#define CFG_HW_EXTPA_ENABLED 0
+#endif
+
+#endif /*HW_CONF_H */
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/Projects/NUCLEO-WB15CC/Applications/BLE_LLD/BLE_LLD_Lowpower/Core/Inc/hw_if.h b/Projects/NUCLEO-WB15CC/Applications/BLE_LLD/BLE_LLD_Lowpower/Core/Inc/hw_if.h
new file mode 100644
index 000000000..3fd93b322
--- /dev/null
+++ b/Projects/NUCLEO-WB15CC/Applications/BLE_LLD/BLE_LLD_Lowpower/Core/Inc/hw_if.h
@@ -0,0 +1,287 @@
+/* USER CODE BEGIN Header */
+/**
+ ******************************************************************************
+ * @file hw_if.h
+ * @author MCD Application Team
+ * @brief Hardware Interface
+ ******************************************************************************
+ * @attention
+ *
+ * <h2><center>&copy; Copyright (c) 2019 STMicroelectronics.
+ * All rights reserved.</center></h2>
+ *
+ * This software component is licensed by ST under Ultimate Liberty license
+ * SLA0044, the "License"; You may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at:
+ * www.st.com/SLA0044
+ *
+ ******************************************************************************
+ */
+/* USER CODE END Header */
+
+/* Define to prevent recursive inclusion -------------------------------------*/
+#ifndef HW_IF_H
+#define HW_IF_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+ /* Includes ------------------------------------------------------------------*/
+#include "stm32wbxx.h"
+#include "stm32wbxx_ll_exti.h"
+#include "stm32wbxx_ll_system.h"
+#include "stm32wbxx_ll_rcc.h"
+#include "stm32wbxx_ll_ipcc.h"
+#include "stm32wbxx_ll_bus.h"
+#include "stm32wbxx_ll_pwr.h"
+#include "stm32wbxx_ll_cortex.h"
+#include "stm32wbxx_ll_utils.h"
+#include "stm32wbxx_ll_hsem.h"
+#include "stm32wbxx_ll_gpio.h"
+#include "stm32wbxx_ll_rtc.h"
+
+#ifdef USE_STM32WBXX_USB_DONGLE
+#include "stm32wbxx_usb_dongle.h"
+#endif
+
+#ifdef USE_STM32WBXX_NUCLEO
+
+#ifdef STM32WB15xx
+#include "nucleo_wb15cc.h"
+#endif
+
+#ifdef STM32WB35xx
+#include "nucleo_wb35ce.h"
+#endif
+
+#ifdef STM32WB55xx
+#include "stm32wbxx_nucleo.h"
+#endif
+
+#endif
+
+#ifdef USE_X_NUCLEO_EPD
+#include "x_nucleo_epd.h"
+#endif
+
+/* Private includes ----------------------------------------------------------*/
+/* USER CODE BEGIN Includes */
+
+/* USER CODE END Includes */
+
+/******************************************************************************
+ * HW UART
+ ******************************************************************************/
+typedef enum
+{
+ hw_uart1,
+ hw_uart2,
+ hw_lpuart1,
+} hw_uart_id_t;
+
+typedef enum
+{
+ hw_uart_ok,
+ hw_uart_error,
+ hw_uart_busy,
+ hw_uart_to,
+} hw_status_t;
+
+#if (CFG_HW_LPUART1_ENABLED == 1)
+extern UART_HandleTypeDef hlpuart1;
+extern DMA_HandleTypeDef hdma_lpuart1_tx;
+#endif
+#if (CFG_HW_USART1_ENABLED == 1)
+extern UART_HandleTypeDef huart1;
+extern DMA_HandleTypeDef hdma_usart1_tx;
+#endif
+
+//void HW_UART_Init(hw_uart_id_t hw_uart_id);
+hw_status_t HW_UART_Receive_IT(hw_uart_id_t hw_uart_id, uint8_t *pData, uint16_t Size, void (*Callback)(void));
+hw_status_t HW_UART_Transmit_IT(hw_uart_id_t hw_uart_id, uint8_t *pData, uint16_t Size, void (*Callback)(void));
+hw_status_t HW_UART_Transmit(hw_uart_id_t hw_uart_id, uint8_t *p_data, uint16_t size, uint32_t timeout);
+hw_status_t HW_UART_Transmit_DMA(hw_uart_id_t hw_uart_id, uint8_t *p_data, uint16_t size, void (*Callback)(void));
+#if 0
+void HW_UART_Interrupt_Handler(hw_uart_id_t hw_uart_id);
+void HW_UART_DMA_Interrupt_Handler(hw_uart_id_t hw_uart_id);
+#endif
+
+#if (CFG_HW_LPUART1_ENABLED == 1)
+void MX_LPUART1_UART_Init(void);
+void MX_LPUART1_UART_DeInit(void);
+#endif
+#if (CFG_HW_USART1_ENABLED == 1)
+void MX_USART1_UART_Init(void);
+void MX_USART1_UART_DeInit(void);
+#endif
+
+ /******************************************************************************
+ * HW TimerServer
+ ******************************************************************************/
+ /* Exported types ------------------------------------------------------------*/
+ /**
+ * This setting is used when standby mode is supported.
+ * hw_ts_InitMode_Limited should be used when the device restarts from Standby Mode. In that case, the Timer Server does
+ * not re-initialized its context. Only the Hardware register which content has been lost is reconfigured
+ * Otherwise, hw_ts_InitMode_Full should be requested (Start from Power ON) and everything is re-initialized.
+ */
+ typedef enum
+ {
+ hw_ts_InitMode_Full,
+ hw_ts_InitMode_Limited,
+ } HW_TS_InitMode_t;
+
+ /**
+ * When a Timer is created as a SingleShot timer, it is not automatically restarted when the timeout occurs. However,
+ * the timer is kept reserved in the list and could be restarted at anytime with HW_TS_Start()
+ *
+ * When a Timer is created as a Repeated timer, it is automatically restarted when the timeout occurs.
+ */
+ typedef enum
+ {
+ hw_ts_SingleShot,
+ hw_ts_Repeated
+ } HW_TS_Mode_t;
+
+ /**
+ * hw_ts_Successful is returned when a Timer has been successfully created with HW_TS_Create(). Otherwise, hw_ts_Failed
+ * is returned. When hw_ts_Failed is returned, that means there are not enough free slots in the list to create a
+ * Timer. In that case, CFG_HW_TS_MAX_NBR_CONCURRENT_TIMER should be increased
+ */
+ typedef enum
+ {
+ hw_ts_Successful,
+ hw_ts_Failed,
+ }HW_TS_ReturnStatus_t;
+
+ typedef void (*HW_TS_pTimerCb_t)(void);
+
+ /**
+ * @brief Initialize the timer server
+ * This API shall be called by the application before any timer is requested to the timer server. It
+ * configures the RTC module to be connected to the LSI input clock.
+ *
+ * @param TimerInitMode: When the device restarts from Standby, it should request hw_ts_InitMode_Limited so that the
+ * Timer context is not re-initialized. Otherwise, hw_ts_InitMode_Full should be requested
+ * @param hrtc: RTC Handle
+ * @retval None
+ */
+ void HW_TS_Init(HW_TS_InitMode_t TimerInitMode, RTC_HandleTypeDef *hrtc);
+
+ /**
+ * @brief Interface to create a virtual timer
+ * The user shall call this API to create a timer. Once created, the timer is reserved to the module until it
+ * has been deleted. When creating a timer, the user shall specify the mode (single shot or repeated), the
+ * callback to be notified when the timer expires and a module ID to identify in the timer interrupt handler
+ * which module is concerned. In return, the user gets a timer ID to handle it.
+ *
+ * @param TimerProcessID: This is an identifier provided by the user and returned in the callback to allow
+ * identification of the requester
+ * @param pTimerId: Timer Id returned to the user to request operation (start, stop, delete)
+ * @param TimerMode: Mode of the virtual timer (Single shot or repeated)
+ * @param pTimerCallBack: Callback when the virtual timer expires
+ * @retval HW_TS_ReturnStatus_t: Return whether the creation is sucessfull or not
+ */
+ HW_TS_ReturnStatus_t HW_TS_Create(uint32_t TimerProcessID, uint8_t *pTimerId, HW_TS_Mode_t TimerMode, HW_TS_pTimerCb_t pTimerCallBack);
+
+ /**
+ * @brief Stop a virtual timer
+ * This API may be used to stop a running timer. A timer which is stopped is move to the pending state.
+ * A pending timer may be restarted at any time with a different timeout value but the mode cannot be changed.
+ * Nothing is done when it is called to stop a timer which has been already stopped
+ *
+ * @param TimerID: Id of the timer to stop
+ * @retval None
+ */
+ void HW_TS_Stop(uint8_t TimerID);
+
+ /**
+ * @brief Start a virtual timer
+ * This API shall be used to start a timer. The timeout value is specified and may be different each time.
+ * When the timer is in the single shot mode, it will move to the pending state when it expires. The user may
+ * restart it at any time with a different timeout value. When the timer is in the repeated mode, it always
+ * stay in the running state. When the timer expires, it will be restarted with the same timeout value.
+ * This API shall not be called on a running timer.
+ *
+ * @param TimerID: The ID Id of the timer to start
+ * @param timeout_ticks: Number of ticks of the virtual timer (Maximum value is (0xFFFFFFFF-0xFFFF = 0xFFFF0000)
+ * @retval None
+ */
+ void HW_TS_Start(uint8_t TimerID, uint32_t timeout_ticks);
+
+ /**
+ * @brief Delete a virtual timer from the list
+ * This API should be used when a timer is not needed anymore by the user. A deleted timer is removed from
+ * the timer list managed by the timer server. It cannot be restarted again. The user has to go with the
+ * creation of a new timer if required and may get a different timer id
+ *
+ * @param TimerID: The ID of the timer to remove from the list
+ * @retval None
+ */
+ void HW_TS_Delete(uint8_t TimerID);
+
+ /**
+ * @brief Schedule the timer list on the timer interrupt handler
+ * This interrupt handler shall be called by the application in the RTC interrupt handler. This handler takes
+ * care of clearing all status flag required in the RTC and EXTI peripherals
+ *
+ * @param None
+ * @retval None
+ */
+ void HW_TS_RTC_Wakeup_Handler(void);
+
+ /**
+ * @brief Return the number of ticks to count before the interrupt
+ * This API returns the number of ticks left to be counted before an interrupt is generated by the
+ * Timer Server. This API may be used by the application for power management optimization. When the system
+ * enters low power mode, the mode selection is a tradeoff between the wakeup time where the CPU is running
+ * and the time while the CPU will be kept in low power mode before next wakeup. The deeper is the
+ * low power mode used, the longer is the wakeup time. The low power mode management considering wakeup time
+ * versus time in low power mode is implementation specific
+ * When the timer is disabled (No timer in the list), it returns 0xFFFF
+ *
+ * @param None
+ * @retval The number of ticks left to count
+ */
+ uint16_t HW_TS_RTC_ReadLeftTicksToCount(void);
+
+ /**
+ * @brief Notify the application that a registered timer has expired
+ * This API shall be implemented by the user application.
+ * This API notifies the application that a timer expires. This API is running in the RTC Wakeup interrupt
+ * context. The application may implement an Operating System to change the context priority where the timer
+ * callback may be handled. This API provides the module ID to identify which module is concerned and to allow
+ * sending the information to the correct task
+ *
+ * @param TimerProcessID: The TimerProcessId associated with the timer when it has been created
+ * @param TimerID: The TimerID of the expired timer
+ * @param pTimerCallBack: The Callback associated with the timer when it has been created
+ * @retval None
+ */
+ void HW_TS_RTC_Int_AppNot(uint32_t TimerProcessID, uint8_t TimerID, HW_TS_pTimerCb_t pTimerCallBack);
+
+ /**
+ * @brief Notify the application that the wakeupcounter has been updated
+ * This API should be implemented by the user application
+ * This API notifies the application that the counter has been updated. This is expected to be used along
+ * with the HW_TS_RTC_ReadLeftTicksToCount () API. It could be that the counter has been updated since the
+ * last call of HW_TS_RTC_ReadLeftTicksToCount () and before entering low power mode. This notification
+ * provides a way to the application to solve that race condition to reevaluate the counter value before
+ * entering low power mode
+ *
+ * @param None
+ * @retval None
+ */
+ void HW_TS_RTC_CountUpdated_AppNot(void);
+
+void MX_UART_Init(hw_uart_id_t uart);
+void MX_UART_Deinit(hw_uart_id_t uart);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /*HW_IF_H */
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/Projects/NUCLEO-WB15CC/Applications/BLE_LLD/BLE_LLD_Lowpower/Core/Inc/main.h b/Projects/NUCLEO-WB15CC/Applications/BLE_LLD/BLE_LLD_Lowpower/Core/Inc/main.h
new file mode 100644
index 000000000..0c024028b
--- /dev/null
+++ b/Projects/NUCLEO-WB15CC/Applications/BLE_LLD/BLE_LLD_Lowpower/Core/Inc/main.h
@@ -0,0 +1,107 @@
+/* USER CODE BEGIN Header */
+/**
+ ******************************************************************************
+ * @file main.h
+ * @author MCD Application Team
+ * @brief Header for main.c module
+ ******************************************************************************
+ * @attention
+ *
+ * <h2><center>&copy; Copyright (c) 2019 STMicroelectronics.
+ * All rights reserved.</center></h2>
+ *
+ * This software component is licensed by ST under Ultimate Liberty license
+ * SLA0044, the "License"; You may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at:
+ * www.st.com/SLA0044
+ *
+ ******************************************************************************
+ */
+/* USER CODE END Header */
+
+/* Define to prevent recursive inclusion -------------------------------------*/
+#ifndef __MAIN_H
+#define __MAIN_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* Includes ------------------------------------------------------------------*/
+
+/* Private includes ----------------------------------------------------------*/
+/* USER CODE BEGIN Includes */
+
+/* USER CODE END Includes */
+
+/* Exported types ------------------------------------------------------------*/
+/* USER CODE BEGIN ET */
+
+/* USER CODE END ET */
+
+/* Exported constants --------------------------------------------------------*/
+/* USER CODE BEGIN EC */
+
+/* USER CODE END EC */
+
+/* Exported macro ------------------------------------------------------------*/
+/* USER CODE BEGIN EM */
+
+/* USER CODE END EM */
+
+/* Exported functions prototypes ---------------------------------------------*/
+void Error_Handler(void);
+void SystemClock_Config_HSE(uint32_t usePLL);
+void SystemClock_Config_MSI(uint32_t usePLL);
+
+/* USER CODE BEGIN EFP */
+
+/* USER CODE END EFP */
+
+/* Private defines -----------------------------------------------------------*/
+/* USER CODE BEGIN Private defines */
+
+
+/*
+ In this example TIM2 input clock (TIM2CLK) is set to APB1 clock (PCLK1),
+ since APB1 prescaler is equal to 1.
+ TIM2CLK = PCLK1
+ PCLK1 = HCLK
+ => TIM2CLK = HCLK = SystemCoreClock
+ To get TIM2 counter clock at 10 KHz, the Prescaler is computed as following:
+ Prescaler = (TIM2CLK / TIM2 counter clock) - 1
+ Prescaler = (SystemCoreClock /10 KHz) - 1
+
+ Note:
+ SystemCoreClock variable holds HCLK frequency and is defined in system_stm32wbxx.c file.
+ Each time the core clock (HCLK) changes, user had to update SystemCoreClock
+ variable value. Otherwise, any configuration based on this variable will be incorrect.
+ This variable is updated in three ways:
+ 1) by calling CMSIS function SystemCoreClockUpdate()
+ 2) by calling HAL API function HAL_RCC_GetSysClockFreq()
+ 3) each time HAL_RCC_ClockConfig() is called to configure the system clock frequency
+ ----------------------------------------------------------------------- */
+
+/* Compute the prescaler value to have TIMx counter clock equal to 10000 Hz */
+
+#define PRESCALER_VALUE (uint32_t)(((SystemCoreClock) / (1000000)) - 1)
+
+ /* Initialize TIMx peripheral as follows:
+ + Period = 10000 - 1
+ + Prescaler = (SystemCoreClock/10000) - 1
+ + ClockDivision = 0
+ + Counter direction = Up
+ */
+
+#define PERIOD_VALUE (1000000 - 1);
+
+
+/* USER CODE END Private defines */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __MAIN_H */
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/Projects/NUCLEO-WB15CC/Applications/BLE_LLD/BLE_LLD_Lowpower/Core/Inc/nucleo_wb15cc_conf.h b/Projects/NUCLEO-WB15CC/Applications/BLE_LLD/BLE_LLD_Lowpower/Core/Inc/nucleo_wb15cc_conf.h
new file mode 100644
index 000000000..45c29d955
--- /dev/null
+++ b/Projects/NUCLEO-WB15CC/Applications/BLE_LLD/BLE_LLD_Lowpower/Core/Inc/nucleo_wb15cc_conf.h
@@ -0,0 +1,77 @@
+/**
+ ******************************************************************************
+ * @file nucleo_wb15cc_conf.h
+ * @author MCD Application Team
+ * @brief NUCLEO-WB15CC board configuration file.
+ ******************************************************************************
+ * @attention
+ *
+ * <h2><center>&copy; Copyright (c) 2020 STMicroelectronics.
+ * All rights reserved.</center></h2>
+ *
+ * This software component is licensed by ST under BSD 3-Clause license,
+ * the "License"; You may not use this file except in compliance with the
+ * License. You may obtain a copy of the License at:
+ * opensource.org/licenses/BSD-3-Clause
+ *
+ ******************************************************************************
+ */
+
+/* Define to prevent recursive inclusion -------------------------------------*/
+#ifndef NUCLEO_WB15CC_CONF_H
+#define NUCLEO_WB15CC_CONF_H
+
+#ifdef __cplusplus
+ extern "C" {
+#endif
+
+/* Includes ------------------------------------------------------------------*/
+#include "stm32wbxx_hal.h"
+
+/** @addtogroup BSP
+ * @{
+ */
+
+/** @addtogroup NUCLEO_WB15CC
+ * @{
+ */
+
+/** @defgroup NUCLEO_WB15CC_CONFIG CONFIG
+ * @{
+ */
+
+/** @defgroup NUCLEO_WB15CC_CONFIG_Exported_Constants Exported Constants
+ * @{
+ */
+/* COM usage define */
+#define USE_BSP_COM_FEATURE 0U
+
+/* COM log define */
+#define USE_COM_LOG 0U
+
+/* IRQ priorities */
+#define BSP_BUTTON_SWx_IT_PRIORITY 15U
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* NUCLEO_WB15CC_CONF_H */
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/Projects/NUCLEO-WB15CC/Applications/BLE_LLD/BLE_LLD_Lowpower/Core/Inc/stm32_lpm_if.h b/Projects/NUCLEO-WB15CC/Applications/BLE_LLD/BLE_LLD_Lowpower/Core/Inc/stm32_lpm_if.h
new file mode 100644
index 000000000..dac7e2cbb
--- /dev/null
+++ b/Projects/NUCLEO-WB15CC/Applications/BLE_LLD/BLE_LLD_Lowpower/Core/Inc/stm32_lpm_if.h
@@ -0,0 +1,79 @@
+/**
+ ******************************************************************************
+ * @file stm32_lpm_if.h
+ * @brief Header for stm32_lpm_if.c module (device specific LP management)
+ ******************************************************************************
+ * @attention
+ *
+ * <h2><center>&copy; Copyright (c) 2019 STMicroelectronics.
+ * All rights reserved.</center></h2>
+ *
+ * This software component is licensed by ST under BSD 3-Clause license,
+ * the "License"; You may not use this file except in compliance with the
+ * License. You may obtain a copy of the License at:
+ * opensource.org/licenses/BSD-3-Clause
+ *
+ ******************************************************************************
+ */
+
+/* Define to prevent recursive inclusion -------------------------------------*/
+#ifndef __STM32_LPM_IF_H
+#define __STM32_LPM_IF_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* Includes ------------------------------------------------------------------*/
+
+/**
+ * @brief Enters Low Power Off Mode
+ * @param none
+ * @retval none
+ */
+void PWR_EnterOffMode( void );
+/**
+ * @brief Exits Low Power Off Mode
+ * @param none
+ * @retval none
+ */
+void PWR_ExitOffMode( void );
+
+/**
+ * @brief Enters Low Power Stop Mode
+ * @note ARM exists the function when waking up
+ * @param none
+ * @retval none
+ */
+void PWR_EnterStopMode( void );
+/**
+ * @brief Exits Low Power Stop Mode
+ * @note Enable the pll at 32MHz
+ * @param none
+ * @retval none
+ */
+void PWR_ExitStopMode( void );
+
+/**
+ * @brief Enters Low Power Sleep Mode
+ * @note ARM exits the function when waking up
+ * @param none
+ * @retval none
+ */
+void PWR_EnterSleepMode( void );
+
+/**
+ * @brief Exits Low Power Sleep Mode
+ * @note ARM exits the function when waking up
+ * @param none
+ * @retval none
+ */
+void PWR_ExitSleepMode( void );
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /*__STM32_LPM_IF_H */
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/Projects/NUCLEO-WB15CC/Applications/BLE_LLD/BLE_LLD_Lowpower/Core/Inc/stm32wbxx_hal_conf.h b/Projects/NUCLEO-WB15CC/Applications/BLE_LLD/BLE_LLD_Lowpower/Core/Inc/stm32wbxx_hal_conf.h
new file mode 100644
index 000000000..365809937
--- /dev/null
+++ b/Projects/NUCLEO-WB15CC/Applications/BLE_LLD/BLE_LLD_Lowpower/Core/Inc/stm32wbxx_hal_conf.h
@@ -0,0 +1,353 @@
+/**
+ ******************************************************************************
+ * @file stm32wbxx_hal_conf.h
+ * @author MCD Application Team
+ * @brief HAL configuration file.
+ ******************************************************************************
+ * @attention
+ *
+ * <h2><center>&copy; Copyright (c) 2019 STMicroelectronics.
+ * All rights reserved.</center></h2>
+ *
+ * This software component is licensed by ST under BSD 3-Clause license,
+ * the "License"; You may not use this file except in compliance with the
+ * License. You may obtain a copy of the License at:
+ * opensource.org/licenses/BSD-3-Clause
+ *
+ ******************************************************************************
+ */
+
+/* Define to prevent recursive inclusion -------------------------------------*/
+#ifndef STM32WBxx_HAL_CONF_H
+#define STM32WBxx_HAL_CONF_H
+
+#ifdef __cplusplus
+ extern "C" {
+#endif
+
+/* Exported types ------------------------------------------------------------*/
+/* Exported constants --------------------------------------------------------*/
+
+/* ########################## Module Selection ############################## */
+/**
+ * @brief This is the list of modules to be used in the HAL driver
+ */
+#define HAL_MODULE_ENABLED
+/*#define HAL_ADC_MODULE_ENABLED */
+/*#define HAL_COMP_MODULE_ENABLED */
+#define HAL_CORTEX_MODULE_ENABLED
+/*#define HAL_CRC_MODULE_ENABLED */
+/*#define HAL_CRYP_MODULE_ENABLED */
+#define HAL_DMA_MODULE_ENABLED
+#define HAL_EXTI_MODULE_ENABLED
+#define HAL_FLASH_MODULE_ENABLED
+#define HAL_GPIO_MODULE_ENABLED
+#define HAL_HSEM_MODULE_ENABLED
+/*#define HAL_I2C_MODULE_ENABLED */
+/*#define HAL_IPCC_MODULE_ENABLED */
+/*#define HAL_IRDA_MODULE_ENABLED */
+/*#define HAL_IWDG_MODULE_ENABLED */
+/*#define HAL_LCD_MODULE_ENABLED */
+/*#define HAL_LPTIM_MODULE_ENABLED */
+/*#define HAL_PCD_MODULE_ENABLED */
+/*#define HAL_PKA_MODULE_ENABLED */
+#define HAL_PWR_MODULE_ENABLED
+/*#define HAL_QSPI_MODULE_ENABLED */
+#define HAL_RCC_MODULE_ENABLED
+/*#define HAL_RNG_MODULE_ENABLED */
+#define HAL_RTC_MODULE_ENABLED
+/*#define HAL_SAI_MODULE_ENABLED */
+/*#define HAL_SMARTCARD_MODULE_ENABLED */
+/*#define HAL_SMBUS_MODULE_ENABLED */
+/*#define HAL_SPI_MODULE_ENABLED */
+#define HAL_TIM_MODULE_ENABLED
+/*#define HAL_TSC_MODULE_ENABLED */
+#define HAL_UART_MODULE_ENABLED
+/*#define HAL_USART_MODULE_ENABLED */
+/*#define HAL_WWDG_MODULE_ENABLED */
+
+#define USE_HAL_ADC_REGISTER_CALLBACKS 0u
+#define USE_HAL_COMP_REGISTER_CALLBACKS 0u
+#define USE_HAL_CRYP_REGISTER_CALLBACKS 0u
+#define USE_HAL_I2C_REGISTER_CALLBACKS 0u
+#define USE_HAL_IRDA_REGISTER_CALLBACKS 0u
+#define USE_HAL_LPTIM_REGISTER_CALLBACKS 0u
+#define USE_HAL_PCD_REGISTER_CALLBACKS 0u
+#define USE_HAL_PKA_REGISTER_CALLBACKS 0u
+#define USE_HAL_QSPI_REGISTER_CALLBACKS 0u
+#define USE_HAL_RNG_REGISTER_CALLBACKS 0u
+#define USE_HAL_RTC_REGISTER_CALLBACKS 0u
+#define USE_HAL_SAI_REGISTER_CALLBACKS 0u
+#define USE_HAL_SMARTCARD_REGISTER_CALLBACKS 0u
+#define USE_HAL_SMBUS_REGISTER_CALLBACKS 0u
+#define USE_HAL_SPI_REGISTER_CALLBACKS 0u
+#define USE_HAL_TIM_REGISTER_CALLBACKS 0u
+#define USE_HAL_TSC_REGISTER_CALLBACKS 0u
+#define USE_HAL_UART_REGISTER_CALLBACKS 0u
+#define USE_HAL_USART_REGISTER_CALLBACKS 0u
+#define USE_HAL_WWDG_REGISTER_CALLBACKS 0u
+
+/* ########################## Oscillator Values adaptation ####################*/
+/**
+ * @brief Adjust the value of External High Speed oscillator (HSE) used in your application.
+ * This value is used by the RCC HAL module to compute the system frequency
+ * (when HSE is used as system clock source, directly or through the PLL).
+ */
+
+#if !defined (HSE_VALUE)
+ #define HSE_VALUE (32000000UL) /*!< Value of the External oscillator in Hz */
+#endif /* HSE_VALUE */
+
+#if !defined (HSE_STARTUP_TIMEOUT)
+ #define HSE_STARTUP_TIMEOUT (100UL) /*!< Time out for HSE start up, in ms */
+#endif /* HSE_STARTUP_TIMEOUT */
+
+/**
+ * @brief Internal Multiple Speed oscillator (MSI) default value.
+ * This value is the default MSI range value after Reset.
+ */
+#if !defined (MSI_VALUE)
+ #define MSI_VALUE (4000000UL) /*!< Value of the Internal oscillator in Hz*/
+#endif /* MSI_VALUE */
+
+/**
+ * @brief Internal High Speed oscillator (HSI) value.
+ * This value is used by the RCC HAL module to compute the system frequency
+ * (when HSI is used as system clock source, directly or through the PLL).
+ */
+#if !defined (HSI_VALUE)
+ #define HSI_VALUE (16000000UL) /*!< Value of the Internal oscillator in Hz*/
+#endif /* HSI_VALUE */
+
+/**
+ * @brief Internal Low Speed oscillator (LSI1) value.
+ */
+#if !defined (LSI1_VALUE)
+ #define LSI1_VALUE (32000UL) /*!< LSI1 Typical Value in Hz*/
+#endif /* LSI1_VALUE */ /*!< Value of the Internal Low Speed oscillator in Hz
+ The real value may vary depending on the variations
+ in voltage and temperature.*/
+/**
+ * @brief Internal Low Speed oscillator (LSI2) value.
+ */
+#if !defined (LSI2_VALUE)
+ #define LSI2_VALUE (32000UL) /*!< LSI2 Typical Value in Hz*/
+#endif /* LSI2_VALUE */ /*!< Value of the Internal Low Speed oscillator in Hz
+ The real value may vary depending on the variations
+ in voltage and temperature.*/
+
+/**
+ * @brief External Low Speed oscillator (LSE) value.
+ * This value is used by the UART, RTC HAL module to compute the system frequency
+ */
+#if !defined (LSE_VALUE)
+ #define LSE_VALUE (32768UL) /*!< Value of the External oscillator in Hz*/
+#endif /* LSE_VALUE */
+
+/**
+ * @brief Internal Multiple Speed oscillator (HSI48) default value.
+ * This value is the default HSI48 range value after Reset.
+ */
+#if !defined (HSI48_VALUE)
+ #define HSI48_VALUE (48000000UL) /*!< Value of the Internal oscillator in Hz*/
+#endif /* HSI48_VALUE */
+
+#if !defined (LSE_STARTUP_TIMEOUT)
+ #define LSE_STARTUP_TIMEOUT (5000UL) /*!< Time out for LSE start up, in ms */
+#endif /* LSE_STARTUP_TIMEOUT */
+
+/**
+ * @brief External clock source for SAI1 peripheral
+ * This value is used by the RCC HAL module to compute the SAI1 & SAI2 clock source
+ * frequency.
+ */
+#if !defined (EXTERNAL_SAI1_CLOCK_VALUE)
+ #define EXTERNAL_SAI1_CLOCK_VALUE (48000UL) /*!< Value of the SAI1 External clock source in Hz*/
+#endif /* EXTERNAL_SAI1_CLOCK_VALUE */
+
+/* Tip: To avoid modifying this file each time you need to use different HSE,
+ === you can define the HSE value in your toolchain compiler preprocessor. */
+
+/* ########################### System Configuration ######################### */
+/**
+ * @brief This is the HAL system configuration section
+ */
+#define VDD_VALUE (3300UL) /*!< Value of VDD in mv */
+#define TICK_INT_PRIORITY ((1UL<<__NVIC_PRIO_BITS) - 1UL) /*!< tick interrupt priority (lowest by default) */
+#define USE_RTOS 0
+#define PREFETCH_ENABLE 0
+#define INSTRUCTION_CACHE_ENABLE 1
+#define DATA_CACHE_ENABLE 1
+
+/* ########################## Assert Selection ############################## */
+/**
+ * @brief Uncomment the line below to expanse the "assert_param" macro in the
+ * HAL drivers code
+ */
+/* #define USE_FULL_ASSERT 1 */
+
+/* ################## SPI peripheral configuration ########################## */
+
+/* CRC FEATURE: Use to activate CRC feature inside HAL SPI Driver
+ * Activated: CRC code is present inside driver
+ * Deactivated: CRC code cleaned from driver
+ */
+
+#define USE_SPI_CRC 1U
+
+/* Includes ------------------------------------------------------------------*/
+/**
+ * @brief Include module's header file
+ */
+#ifdef HAL_DMA_MODULE_ENABLED
+ #include "stm32wbxx_hal_dma.h"
+#endif /* HAL_DMA_MODULE_ENABLED */
+
+#ifdef HAL_ADC_MODULE_ENABLED
+ #include "stm32wbxx_hal_adc.h"
+#endif /* HAL_ADC_MODULE_ENABLED */
+
+#ifdef HAL_COMP_MODULE_ENABLED
+ #include "stm32wbxx_hal_comp.h"
+#endif /* HAL_COMP_MODULE_ENABLED */
+
+#ifdef HAL_CORTEX_MODULE_ENABLED
+ #include "stm32wbxx_hal_cortex.h"
+#endif /* HAL_CORTEX_MODULE_ENABLED */
+
+#ifdef HAL_CRC_MODULE_ENABLED
+ #include "stm32wbxx_hal_crc.h"
+#endif /* HAL_CRC_MODULE_ENABLED */
+
+#ifdef HAL_CRYP_MODULE_ENABLED
+ #include "stm32wbxx_hal_cryp.h"
+#endif /* HAL_CRYP_MODULE_ENABLED */
+
+#ifdef HAL_EXTI_MODULE_ENABLED
+ #include "stm32wbxx_hal_exti.h"
+#endif /* HAL_EXTI_MODULE_ENABLED */
+
+#ifdef HAL_FLASH_MODULE_ENABLED
+ #include "stm32wbxx_hal_flash.h"
+#endif /* HAL_FLASH_MODULE_ENABLED */
+
+#ifdef HAL_GPIO_MODULE_ENABLED
+ #include "stm32wbxx_hal_gpio.h"
+#endif /* HAL_GPIO_MODULE_ENABLED */
+
+#ifdef HAL_HSEM_MODULE_ENABLED
+ #include "stm32wbxx_hal_hsem.h"
+#endif /* HAL_HSEM_MODULE_ENABLED */
+
+#ifdef HAL_I2C_MODULE_ENABLED
+ #include "stm32wbxx_hal_i2c.h"
+#endif /* HAL_I2C_MODULE_ENABLED */
+
+#ifdef HAL_IPCC_MODULE_ENABLED
+ #include "stm32wbxx_hal_ipcc.h"
+#endif /* HAL_IPCC_MODULE_ENABLED */
+
+#ifdef HAL_IRDA_MODULE_ENABLED
+ #include "stm32wbxx_hal_irda.h"
+#endif /* HAL_IRDA_MODULE_ENABLED */
+
+#ifdef HAL_IWDG_MODULE_ENABLED
+ #include "stm32wbxx_hal_iwdg.h"
+#endif /* HAL_IWDG_MODULE_ENABLED */
+
+#ifdef HAL_LCD_MODULE_ENABLED
+ #include "stm32wbxx_hal_lcd.h"
+#endif /* HAL_LCD_MODULE_ENABLED */
+
+#ifdef HAL_LPTIM_MODULE_ENABLED
+ #include "stm32wbxx_hal_lptim.h"
+#endif /* HAL_LPTIM_MODULE_ENABLED */
+
+#ifdef HAL_PCD_MODULE_ENABLED
+ #include "stm32wbxx_hal_pcd.h"
+#endif /* HAL_PCD_MODULE_ENABLED */
+
+#ifdef HAL_PKA_MODULE_ENABLED
+ #include "stm32wbxx_hal_pka.h"
+#endif /* HAL_PKA_MODULE_ENABLED */
+
+#ifdef HAL_PWR_MODULE_ENABLED
+ #include "stm32wbxx_hal_pwr.h"
+#endif /* HAL_PWR_MODULE_ENABLED */
+
+#ifdef HAL_QSPI_MODULE_ENABLED
+ #include "stm32wbxx_hal_qspi.h"
+#endif /* HAL_QSPI_MODULE_ENABLED */
+
+#ifdef HAL_RCC_MODULE_ENABLED
+ #include "stm32wbxx_hal_rcc.h"
+#endif /* HAL_RCC_MODULE_ENABLED */
+
+#ifdef HAL_RNG_MODULE_ENABLED
+ #include "stm32wbxx_hal_rng.h"
+#endif /* HAL_RNG_MODULE_ENABLED */
+
+#ifdef HAL_RTC_MODULE_ENABLED
+ #include "stm32wbxx_hal_rtc.h"
+#endif /* HAL_RTC_MODULE_ENABLED */
+
+#ifdef HAL_SAI_MODULE_ENABLED
+ #include "stm32wbxx_hal_sai.h"
+#endif /* HAL_SAI_MODULE_ENABLED */
+
+#ifdef HAL_SMARTCARD_MODULE_ENABLED
+ #include "stm32wbxx_hal_smartcard.h"
+#endif /* HAL_SMARTCARD_MODULE_ENABLED */
+
+#ifdef HAL_SMBUS_MODULE_ENABLED
+ #include "stm32wbxx_hal_smbus.h"
+#endif /* HAL_SMBUS_MODULE_ENABLED */
+
+#ifdef HAL_SPI_MODULE_ENABLED
+ #include "stm32wbxx_hal_spi.h"
+#endif /* HAL_SPI_MODULE_ENABLED */
+
+#ifdef HAL_TIM_MODULE_ENABLED
+ #include "stm32wbxx_hal_tim.h"
+#endif /* HAL_TIM_MODULE_ENABLED */
+
+#ifdef HAL_TSC_MODULE_ENABLED
+ #include "stm32wbxx_hal_tsc.h"
+#endif /* HAL_TSC_MODULE_ENABLED */
+
+#ifdef HAL_UART_MODULE_ENABLED
+ #include "stm32wbxx_hal_uart.h"
+#endif /* HAL_UART_MODULE_ENABLED */
+
+#ifdef HAL_USART_MODULE_ENABLED
+ #include "stm32wbxx_hal_usart.h"
+#endif /* HAL_USART_MODULE_ENABLED */
+
+#ifdef HAL_WWDG_MODULE_ENABLED
+ #include "stm32wbxx_hal_wwdg.h"
+#endif /* HAL_WWDG_MODULE_ENABLED */
+
+/* Exported macro ------------------------------------------------------------*/
+#ifdef USE_FULL_ASSERT
+/**
+ * @brief The assert_param macro is used for function's parameters check.
+ * @param expr If expr is false, it calls assert_failed function
+ * which reports the name of the source file and the source
+ * line number of the call that failed.
+ * If expr is true, it returns no value.
+ * @retval None
+ */
+ #define assert_param(expr) ((expr) ? (void)0U : assert_failed((uint8_t *)__FILE__, __LINE__))
+/* Exported functions ------------------------------------------------------- */
+ void assert_failed(uint8_t* file, uint32_t line);
+#else
+ #define assert_param(expr) ((void)0U)
+#endif /* USE_FULL_ASSERT */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* STM32WBxx_HAL_CONF_H */
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/Projects/NUCLEO-WB15CC/Applications/BLE_LLD/BLE_LLD_Lowpower/Core/Inc/stm32wbxx_it.h b/Projects/NUCLEO-WB15CC/Applications/BLE_LLD/BLE_LLD_Lowpower/Core/Inc/stm32wbxx_it.h
new file mode 100644
index 000000000..fd3ff7829
--- /dev/null
+++ b/Projects/NUCLEO-WB15CC/Applications/BLE_LLD/BLE_LLD_Lowpower/Core/Inc/stm32wbxx_it.h
@@ -0,0 +1,83 @@
+/* USER CODE BEGIN Header */
+/**
+ ******************************************************************************
+ * @file stm32wbxx_it.h
+ * @brief This file contains the headers of the interrupt handlers.
+ *******************************************************************************
+ * @attention
+ *
+ * <h2><center>&copy; Copyright (c) 2019 STMicroelectronics.
+ * All rights reserved.</center></h2>
+ *
+ * This software component is licensed by ST under Ultimate Liberty license
+ * SLA0044, the "License"; You may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at:
+ * www.st.com/SLA0044
+ *
+ ******************************************************************************
+ */
+/* USER CODE END Header */
+
+/* Define to prevent recursive inclusion -------------------------------------*/
+#ifndef __STM32WBxx_IT_H
+#define __STM32WBxx_IT_H
+
+#ifdef __cplusplus
+ extern "C" {
+#endif
+
+/* Private includes ----------------------------------------------------------*/
+/* USER CODE BEGIN Includes */
+#include "app_common.h"
+#include "gpio_lld.h"
+/* USER CODE END Includes */
+
+/* Exported types ------------------------------------------------------------*/
+/* USER CODE BEGIN ET */
+
+/* USER CODE END ET */
+
+/* Exported constants --------------------------------------------------------*/
+/* USER CODE BEGIN EC */
+
+/* USER CODE END EC */
+
+/* Exported macro ------------------------------------------------------------*/
+/* USER CODE BEGIN EM */
+
+/* USER CODE END EM */
+
+/* Exported functions prototypes ---------------------------------------------*/
+void NMI_Handler(void);
+void HardFault_Handler(void);
+void MemManage_Handler(void);
+void BusFault_Handler(void);
+void UsageFault_Handler(void);
+void SVC_Handler(void);
+void DebugMon_Handler(void);
+void PendSV_Handler(void);
+void SysTick_Handler(void);
+void DMA1_Channel4_IRQHandler(void);
+void DMA1_Channel5_IRQHandler(void);
+void USART1_IRQHandler(void);
+void LPUART1_IRQHandler(void);
+/* USER CODE BEGIN EFP */
+void RTC_WKUP_IRQHandler(void);
+
+void IPCC_C1_TX_IRQHandler(void);
+void IPCC_C1_RX_IRQHandler(void);
+
+void BUTTON_SW1_EXTI_IRQHandler(void);
+void BUTTON_SW2_EXTI_IRQHandler(void);
+void BUTTON_SW3_EXTI_IRQHandler(void);
+void TIM2_IRQHandler(void);
+
+/* USER CODE END EFP */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __STM32WBxx_IT_H */
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/Projects/NUCLEO-WB15CC/Applications/BLE_LLD/BLE_LLD_Lowpower/Core/Inc/stm_logging.h b/Projects/NUCLEO-WB15CC/Applications/BLE_LLD/BLE_LLD_Lowpower/Core/Inc/stm_logging.h
new file mode 100644
index 000000000..119d6e7a0
--- /dev/null
+++ b/Projects/NUCLEO-WB15CC/Applications/BLE_LLD/BLE_LLD_Lowpower/Core/Inc/stm_logging.h
@@ -0,0 +1,63 @@
+/**
+ ******************************************************************************
+ * File Name : stm_logging.h
+ * Description : Application header file for logging
+ ******************************************************************************
+ * @attention
+ *
+ * <h2><center>&copy; Copyright (c) 2021 STMicroelectronics.
+ * All rights reserved.</center></h2>
+ *
+ * This software component is licensed by ST under Ultimate Liberty license
+ * SLA0044, the "License"; You may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at:
+ * www.st.com/SLA0044
+ *
+ ******************************************************************************
+ */
+
+#ifndef STM_LOGGING_H_
+#define STM_LOGGING_H_
+
+#define LOG_LEVEL_NONE 0 /* None */
+#define LOG_LEVEL_CRIT 1U /* Critical */
+#define LOG_LEVEL_WARN 2U /* Warning */
+#define LOG_LEVEL_INFO 3U /* Info */
+#define LOG_LEVEL_DEBG 4U /* Debug */
+
+#define APP_DBG_FULL(level, region, ...) \
+ { \
+ if (APPLI_PRINT_FILE_FUNC_LINE == 1U) \
+ { \
+ printf("\r\n[%s][%s][%d] ", DbgTraceGetFileName(__FILE__),__FUNCTION__,__LINE__); \
+ } \
+ logApplication(level, region, __VA_ARGS__); \
+ }
+
+#define APP_DBG(...) \
+ { \
+ if (APPLI_PRINT_FILE_FUNC_LINE == 1U) \
+ { \
+ printf("\r\n[%s][%s][%d] ", DbgTraceGetFileName(__FILE__),__FUNCTION__,__LINE__); \
+ } \
+ logApplication(LOG_LEVEL_NONE, APPLI_LOG_REGION_GENERAL, __VA_ARGS__); \
+ }
+
+/**
+ * This enumeration represents log regions.
+ *
+ */
+typedef enum
+{
+ APPLI_LOG_REGION_GENERAL = 1U, /* General */
+ APPLI_LOG_REGION_OPENTHREAD_API = 2U, /* OpenThread API */
+ APPLI_LOG_REGION_OT_API_LINK = 3U, /* OpenThread Link API */
+ APPLI_LOG_REGION_OT_API_INSTANCE = 4U, /* OpenThread Instance API */
+ APPLI_LOG_REGION_OT_API_MESSAGE = 5U /* OpenThread Message API */
+} appliLogRegion_t;
+
+typedef uint8_t appliLogLevel_t;
+
+void logApplication(appliLogLevel_t aLogLevel, appliLogRegion_t aLogRegion, const char *aFormat, ...);
+
+#endif /* STM_LOGGING_H_ */
diff --git a/Projects/NUCLEO-WB15CC/Applications/BLE_LLD/BLE_LLD_Lowpower/Core/Inc/utilities_conf.h b/Projects/NUCLEO-WB15CC/Applications/BLE_LLD/BLE_LLD_Lowpower/Core/Inc/utilities_conf.h
new file mode 100644
index 000000000..4dde3509a
--- /dev/null
+++ b/Projects/NUCLEO-WB15CC/Applications/BLE_LLD/BLE_LLD_Lowpower/Core/Inc/utilities_conf.h
@@ -0,0 +1,68 @@
+/* USER CODE BEGIN Header */
+/**
+ ******************************************************************************
+ * File Name : utilities_conf.h
+ * Description : Configuration file for STM32 Utilities.
+ *
+ ******************************************************************************
+ * @attention
+ *
+ * <h2><center>&copy; Copyright (c) 2019 STMicroelectronics.
+ * All rights reserved.</center></h2>
+ *
+ * This software component is licensed by ST under BSD 3-Clause license,
+ * the "License"; You may not use this file except in compliance with the
+ * License. You may obtain a copy of the License at:
+ * opensource.org/licenses/BSD-3-Clause
+ *
+ ******************************************************************************
+ */
+/* USER CODE END Header */
+
+/* Define to prevent recursive inclusion -------------------------------------*/
+#ifndef UTILITIES_CONF_H
+#define UTILITIES_CONF_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include "cmsis_compiler.h"
+#include "string.h"
+
+/******************************************************************************
+ * common
+ ******************************************************************************/
+#define UTILS_ENTER_CRITICAL_SECTION( ) uint32_t primask_bit = __get_PRIMASK( );\
+ __disable_irq( )
+
+#define UTILS_EXIT_CRITICAL_SECTION( ) __set_PRIMASK( primask_bit )
+
+#define UTILS_MEMSET8( dest, value, size ) memset( dest, value, size);
+
+/******************************************************************************
+ * tiny low power manager
+ * (any macro that does not need to be modified can be removed)
+ ******************************************************************************/
+#define UTIL_LPM_INIT_CRITICAL_SECTION( )
+#define UTIL_LPM_ENTER_CRITICAL_SECTION( ) UTILS_ENTER_CRITICAL_SECTION( )
+#define UTIL_LPM_EXIT_CRITICAL_SECTION( ) UTILS_EXIT_CRITICAL_SECTION( )
+
+/******************************************************************************
+ * sequencer
+ * (any macro that does not need to be modified can be removed)
+ ******************************************************************************/
+#define UTIL_SEQ_INIT_CRITICAL_SECTION( )
+#define UTIL_SEQ_ENTER_CRITICAL_SECTION( ) UTILS_ENTER_CRITICAL_SECTION( )
+#define UTIL_SEQ_EXIT_CRITICAL_SECTION( ) UTILS_EXIT_CRITICAL_SECTION( )
+#define UTIL_SEQ_CONF_TASK_NBR (32)
+#define UTIL_SEQ_CONF_PRIO_NBR (2)
+#define UTIL_SEQ_MEMSET8( dest, value, size ) UTILS_MEMSET8( dest, value, size )
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /*UTILITIES_CONF_H */
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/Projects/NUCLEO-WB15CC/Applications/BLE_LLD/BLE_LLD_Lowpower/Core/Src/app_entry.c b/Projects/NUCLEO-WB15CC/Applications/BLE_LLD/BLE_LLD_Lowpower/Core/Src/app_entry.c
new file mode 100644
index 000000000..a377e0f8a
--- /dev/null
+++ b/Projects/NUCLEO-WB15CC/Applications/BLE_LLD/BLE_LLD_Lowpower/Core/Src/app_entry.c
@@ -0,0 +1,421 @@
+/* USER CODE BEGIN Header */
+/**
+ ******************************************************************************
+ * @file app_entry.c
+ * @author MCD Application Team
+ * @brief Entry point of the Application
+ ******************************************************************************
+ * @attention
+ *
+ * <h2><center>&copy; Copyright (c) 2019 STMicroelectronics.
+ * All rights reserved.</center></h2>
+ *
+ * This software component is licensed by ST under Ultimate Liberty license
+ * SLA0044, the "License"; You may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at:
+ * www.st.com/SLA0044
+ *
+ ******************************************************************************
+ */
+/* USER CODE END Header */
+
+/* Includes ------------------------------------------------------------------*/
+#include "app_common.h"
+#include "app_entry.h"
+#include "app_ble_lld.h"
+#include "app_conf.h"
+#include "hw_conf.h"
+#include "stm32_seq.h"
+#include "stm_logging.h"
+#include "shci_tl.h"
+#include "stm32_lpm.h"
+#include "dbg_trace.h"
+#include "shci.h"
+#include "lowpower_app.h"
+
+/* Private includes -----------------------------------------------------------*/
+/* USER CODE BEGIN Includes */
+
+/* USER CODE END Includes */
+
+/* Private typedef -----------------------------------------------------------*/
+/* USER CODE BEGIN PTD */
+extern RTC_HandleTypeDef hrtc;
+
+/* USER CODE END PTD */
+
+/* Private defines -----------------------------------------------------------*/
+/* POOL_SIZE = 2(TL_PacketHeader_t) + 258 (3(TL_EVT_HDR_SIZE) + 255(Payload size)) */
+#define POOL_SIZE (CFG_TL_EVT_QUEUE_LENGTH * 4U * DIVC(( sizeof(TL_PacketHeader_t) + TL_EVENT_FRAME_SIZE ), 4U))
+
+/* USER CODE BEGIN PD */
+
+/* USER CODE END PD */
+
+/* Private macros ------------------------------------------------------------*/
+/* USER CODE BEGIN PM */
+
+/* USER CODE END PM */
+
+/* Private variables ---------------------------------------------------------*/
+PLACE_IN_SECTION("MB_MEM2") ALIGN(4) static uint8_t EvtPool[POOL_SIZE];
+PLACE_IN_SECTION("MB_MEM2") ALIGN(4) static TL_CmdPacket_t SystemCmdBuffer;
+PLACE_IN_SECTION("MB_MEM2") ALIGN(4) static uint8_t SystemSpareEvtBuffer[sizeof(TL_PacketHeader_t) + TL_EVT_HDR_SIZE + 255U];
+
+/* USER CODE BEGIN PV */
+
+/* USER CODE END PV */
+
+/* Global function prototypes -----------------------------------------------*/
+#if(CFG_DEBUG_TRACE != 0)
+size_t DbgTraceWrite(int handle, const unsigned char * buf, size_t bufSize);
+#endif
+
+/* USER CODE BEGIN GFP */
+
+/* USER CODE END GFP */
+
+/* Private functions prototypes-----------------------------------------------*/
+static void SystemPower_Config( void );
+static void Init_Debug( void );
+static void appe_Tl_Init( void );
+static void APPE_SysStatusNot( SHCI_TL_CmdStatus_t status );
+static void APPE_SysUserEvtRx( void * pPayload );
+static void APPE_SysEvtReadyProcessing( void );
+static void APPE_SysEvtError( SCHI_SystemErrCode_t ErrorCode);
+
+/* USER CODE BEGIN PFP */
+static void Led_Init( void );
+static void Button_Init( void );
+/* USER CODE END PFP */
+
+/* Functions Definition ------------------------------------------------------*/
+void APPE_Init( void )
+{
+ /**< Configure the system Power Mode */
+ SystemPower_Config();
+
+ HW_TS_Init(hw_ts_InitMode_Full, &hrtc); /**< Initialize the TimerServer */
+
+/* USER CODE BEGIN APPE_Init_1 */
+ /* initialize debugger module if supported and debug trace if activated */
+ Init_Debug();
+
+ Led_Init();
+ Button_Init();
+
+/* USER CODE END APPE_Init_1 */
+ /* Initialize all transport layers and start CPU2 which will send back a ready event to CPU1 */
+ appe_Tl_Init();
+
+ /**
+ * From now, the application is waiting for the ready event ( sub event : SHCI_SUB_EVT_CODE_READY / payload : WIRELESS_FW_RUNNING)
+ * received on the system channel before starting the LLD test appli using system message SHCI_OPCODE_C2_LLD_TESTS_INIT
+ * This system event is received with APPE_SysUserEvtRx()
+ */
+/* USER CODE BEGIN APPE_Init_2 */
+
+/* USER CODE END APPE_Init_2 */
+ return;
+}
+/* USER CODE BEGIN FD */
+
+/* USER CODE END FD */
+
+/*************************************************************
+ *
+ * LOCAL FUNCTIONS
+ *
+ *************************************************************/
+static void Init_Debug( void )
+{
+#if (CFG_DEBUGGER_SUPPORTED == 1)
+ /**
+ * Keep debugger enabled while in any low power mode
+ */
+ HAL_DBGMCU_EnableDBGSleepMode();
+
+ /* Enable debugger EXTI lines */
+ LL_EXTI_EnableIT_32_63(LL_EXTI_LINE_48);
+ LL_C2_EXTI_EnableIT_32_63(LL_EXTI_LINE_48);
+
+#else
+ /* Disable debugger EXTI lines */
+ LL_EXTI_DisableIT_32_63(LL_EXTI_LINE_48);
+ LL_C2_EXTI_DisableIT_32_63(LL_EXTI_LINE_48);
+
+ /**
+ * Do not keep debugger enabled while in any low power mode
+ */
+ HAL_DBGMCU_DisableDBGSleepMode();
+ HAL_DBGMCU_DisableDBGStopMode();
+ HAL_DBGMCU_DisableDBGStandbyMode();
+#endif /* (CFG_DEBUGGER_SUPPORTED == 1) */
+
+#if(CFG_DEBUG_TRACE != 0)
+ DbgTraceInit();
+#endif
+
+ /* Send a first trace to debug trace port to see that M4 is alive */
+ APP_DBG("++++++++++++++++++++++++++++++++++++++++++++++++++++++++++");
+ APP_DBG("traces init done on M4");
+ APP_DBG("++++++++++++++++++++++++++++++++++++++++++++++++++++++++++");
+
+ return;
+}
+
+/**
+ * @brief Configure the system for power optimization
+ *
+ * @note This API configures the system to be ready for low power mode
+ *
+ * @param None
+ * @retval None
+ */
+static void SystemPower_Config( void )
+{
+ // Disable internal wake-up which is active by default and is for RTC wake-up
+ LL_PWR_DisableInternWU();
+
+ // Before going to stop or standby modes, do the settings so that system clock and IP80215.4 clock
+ // start on HSI automatically
+ LL_RCC_HSI_EnableAutoFromStop();
+
+ /**
+ * Select HSI as system clock source after Wake Up from Stop mode
+ */
+ LL_RCC_SetClkAfterWakeFromStop(LL_RCC_STOP_WAKEUPCLOCK_HSI);
+
+ /* Initialize low power manager */
+ UTIL_LPM_Init( );
+
+ /* Disable low power mode until INIT is complete */
+ UTIL_LPM_SetOffMode(1 << CFG_LPM_APP, UTIL_LPM_DISABLE);
+ UTIL_LPM_SetStopMode(1 << CFG_LPM_APP, UTIL_LPM_DISABLE);
+
+ return;
+}
+
+static void appe_Tl_Init( void )
+{
+ TL_MM_Config_t tl_mm_config;
+ SHCI_TL_HciInitConf_t SHci_Tl_Init_Conf;
+
+ /**< Reference table initialization */
+ TL_Init();
+
+ /**< System channel initialization */
+ UTIL_SEQ_RegTask( 1<< CFG_TASK_SYSTEM_HCI_ASYNCH_EVT, UTIL_SEQ_RFU, shci_user_evt_proc );
+ SHci_Tl_Init_Conf.p_cmdbuffer = (uint8_t*)&SystemCmdBuffer;
+ SHci_Tl_Init_Conf.StatusNotCallBack = APPE_SysStatusNot;
+ shci_init(APPE_SysUserEvtRx, (void*) &SHci_Tl_Init_Conf);
+
+ /**< Memory Manager channel initialization */
+ tl_mm_config.p_BleSpareEvtBuffer = 0;
+ tl_mm_config.p_SystemSpareEvtBuffer = SystemSpareEvtBuffer;
+ tl_mm_config.p_AsynchEvtPool = EvtPool;
+ tl_mm_config.AsynchEvtPoolSize = POOL_SIZE;
+ TL_MM_Init( &tl_mm_config );
+
+ /* Enable transport layer and start CPU2 */
+ TL_Enable();
+
+ return;
+}
+
+static void APPE_SysStatusNot( SHCI_TL_CmdStatus_t status )
+{
+ UNUSED(status);
+ return;
+}
+
+/**
+ * The type of the payload for a system user event is tSHCI_UserEvtRxParam
+ * When the system event is both :
+ * - a ready event (subevtcode = SHCI_SUB_EVT_CODE_READY)
+ * - reported by the FUS (sysevt_ready_rsp == FUS_FW_RUNNING)
+ * The buffer shall not be released
+ * ( eg ((tSHCI_UserEvtRxParam*)pPayload)->status shall be set to SHCI_TL_UserEventFlow_Disable )
+ * When the status is not filled, the buffer is released by default
+ */
+static void APPE_SysUserEvtRx( void * pPayload )
+{
+ TL_AsynchEvt_t *p_sys_event;
+ p_sys_event = (TL_AsynchEvt_t*)(((tSHCI_UserEvtRxParam*)pPayload)->pckt->evtserial.evt.payload);
+
+ switch(p_sys_event->subevtcode)
+ {
+ case SHCI_SUB_EVT_CODE_READY:
+ if (p_sys_event->payload[0] == WIRELESS_FW_RUNNING)
+ APPE_SysEvtReadyProcessing();
+ break;
+
+ case SHCI_SUB_EVT_ERROR_NOTIF:
+ APPE_SysEvtError((SCHI_SystemErrCode_t) (p_sys_event->payload[0]));
+ break;
+
+ default:
+ break;
+ }
+ return;
+}
+
+/**
+ * @brief Notify a system error coming from the M0 firmware
+ * @param ErrorCode : errorCode detected by the M0 firmware
+ *
+ * @retval None
+ */
+static void APPE_SysEvtError( SCHI_SystemErrCode_t ErrorCode)
+{
+ switch(ErrorCode)
+ {
+ case ERR_THREAD_LLD_FATAL_ERROR:
+ APP_DBG("** ERR_LLD_TESTS : LLD_FATAL_ERROR \n");
+ break;
+
+ case ERR_THREAD_UNKNOWN_CMD:
+ APP_DBG("** ERR_LLD_TESTS : UNKNOWN_CMD \n");
+ break;
+
+ default:
+ APP_DBG("** ERR_LLD_TESTS : ErroCode=%d \n",ErrorCode);
+ break;
+ }
+ return;
+}
+
+static void APPE_SysEvtReadyProcessing( void )
+{
+ /* Traces channel initialization */
+ TL_TRACES_Init( );
+
+ /* Application specific init */
+ LOWPOWER_APP_Init();
+
+#if ( CFG_LPM_SUPPORTED == 1)
+ /* Thread stack is initialized, low power mode can be enabled */
+ UTIL_LPM_SetOffMode(1U << CFG_LPM_APP, UTIL_LPM_ENABLE);
+ UTIL_LPM_SetStopMode(1U << CFG_LPM_APP, UTIL_LPM_ENABLE);
+#endif
+
+ return;
+}
+
+/* USER CODE BEGIN FD_LOCAL_FUNCTIONS */
+static void Led_Init( void )
+{
+#if (CFG_LED_SUPPORTED == 1U)
+ /**
+ * Leds Initialization
+ */
+#if (CFG_HW_LPUART1_ENABLED != 1) || ! defined (STM32WB35xx)
+ // On WB35, LED_BLUE share the GPIO PB5 with LPUART
+ BSP_LED_Init(LED_BLUE);
+#endif
+ BSP_LED_Init(LED_GREEN);
+ BSP_LED_Init(LED_RED);
+#endif
+
+ return;
+}
+
+static void Button_Init( void )
+{
+#if (CFG_BUTTON_SUPPORTED == 1U)
+ /**
+ * Button Initialization
+ */
+ BSP_PB_Init(BUTTON_SW1, BUTTON_MODE_EXTI);
+ BSP_PB_Init(BUTTON_SW2, BUTTON_MODE_EXTI);
+ BSP_PB_Init(BUTTON_SW3, BUTTON_MODE_EXTI);
+
+#endif
+
+ return;
+}
+
+/* USER CODE END FD_LOCAL_FUNCTIONS */
+
+/*************************************************************
+ *
+ * WRAP FUNCTIONS
+ *
+ *************************************************************/
+
+void UTIL_SEQ_Idle( void )
+{
+ /* Note that WFI (i.e. SLEEP mode) is required for SF timer tests but STOP or OFF mode will be managed by low-power test itself */
+#if ( CFG_LPM_SUPPORTED == 1)
+ UTIL_LPM_EnterLowPower( );
+#endif
+ return;
+}
+
+void shci_notify_asynch_evt(void* pdata)
+{
+ UNUSED(pdata);
+ UTIL_SEQ_SetTask(1U << CFG_TASK_SYSTEM_HCI_ASYNCH_EVT, CFG_SCH_PRIO_0);
+ return;
+}
+
+void shci_cmd_resp_release(uint32_t flag)
+{
+ UNUSED(flag);
+ UTIL_SEQ_SetEvt(1U << CFG_EVT_SYSTEM_HCI_CMD_EVT_RESP);
+ return;
+}
+
+void shci_cmd_resp_wait(uint32_t timeout)
+{
+ UNUSED(timeout);
+ UTIL_SEQ_WaitEvt(1U << CFG_EVT_SYSTEM_HCI_CMD_EVT_RESP);
+ return;
+}
+
+/* Received trace buffer from M0 */
+void TL_TRACES_EvtReceived( TL_EvtPacket_t * hcievt )
+{
+#if(CFG_DEBUG_TRACE != 0)
+ /* Call write/print function using DMA from dbg_trace */
+ /* - Cast to TL_AsynchEvt_t* to get "real" payload (without Sub Evt code 2bytes),
+ - (-2) to size to remove Sub Evt Code */
+ DbgTraceWrite(1U, (const unsigned char *) ((TL_AsynchEvt_t *)(hcievt->evtserial.evt.payload))->payload, hcievt->evtserial.evt.plen - 2U);
+#endif /* CFG_DEBUG_TRACE */
+ /* Release buffer */
+ TL_MM_EvtDone( hcievt );
+}
+/**
+ * @brief Initialisation of the trace mechanism
+ * @param None
+ * @retval None
+ */
+#if(CFG_DEBUG_TRACE != 0)
+void DbgOutputInit( void )
+{
+/* USER CODE BEGIN DbgOutputInit */
+#ifdef CFG_DEBUG_TRACE_UART
+ MX_UART_Init(CFG_DEBUG_TRACE_UART);
+#endif
+ return;
+}
+
+/**
+ * @brief Management of the traces
+ * @param p_data : data
+ * @param size : size
+ * @param call-back :
+ * @retval None
+ */
+void DbgOutputTraces( uint8_t *p_data, uint16_t size, void (*cb)(void) )
+{
+ HW_UART_Transmit_DMA(CFG_DEBUG_TRACE_UART, p_data, size, cb);
+
+ return;
+}
+#endif
+
+/* USER CODE BEGIN FD_WRAP_FUNCTIONS */
+
+/* USER CODE END FD_WRAP_FUNCTIONS */
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/Projects/NUCLEO-WB15CC/Applications/BLE_LLD/BLE_LLD_Lowpower/Core/Src/gpio_lld.c b/Projects/NUCLEO-WB15CC/Applications/BLE_LLD/BLE_LLD_Lowpower/Core/Src/gpio_lld.c
new file mode 100644
index 000000000..1ccb7b42f
--- /dev/null
+++ b/Projects/NUCLEO-WB15CC/Applications/BLE_LLD/BLE_LLD_Lowpower/Core/Src/gpio_lld.c
@@ -0,0 +1,132 @@
+/**
+ ******************************************************************************
+ * @file gpio_lld.c
+ * @author MCD Application Team
+ * @version $VERSION$
+ * @date $DATE$
+ * @brief This file contains the init of all the GPIOs used by LLD tests.
+ * It is to be used on both M0 and M4.
+ ******************************************************************************
+ * @attention
+ *
+ * <h2><center>&copy; COPYRIGHT(c) 2015 STMicroelectronics</center></h2>
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ * 3. Neither the name of STMicroelectronics nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ ******************************************************************************
+ */
+
+/* Includes ------------------------------------------------------------------*/
+// Be carrefull with the .h included as this file must be compilable on both M0 and M4 environments
+#include "app_conf.h"
+#include "gpio_lld.h"
+
+/* Set PHY GPIO_HARD_FAULT to '1' */
+void gpio_lld_phy_gpioHardFault_up(void) {
+ HAL_GPIO_WritePin(GPIO_HARD_FAULT_PORT, GPIO_HARD_FAULT_PIN, GPIO_PIN_SET);
+}
+
+/* Set PHY GPIO_HARD_FAULT to '0' */
+void gpio_lld_phy_gpioHardFault_down(void) {
+ HAL_GPIO_WritePin(GPIO_HARD_FAULT_PORT, GPIO_HARD_FAULT_PIN, GPIO_PIN_RESET);
+}
+
+/* Initialize GPIOs used by USART */
+void gpio_lld_usart_init(void)
+{
+ GPIO_InitTypeDef gpioinitstruct = {0};
+
+ /*** Configure the GPIOs ***/
+ /* Enable GPIO clock */
+ USART_TX_GPIO_CLK_ENABLE();
+ USART_RX_GPIO_CLK_ENABLE();
+
+ /* Common configuration to Tx and Rx */
+ gpioinitstruct.Mode = GPIO_MODE_AF_PP;
+ gpioinitstruct.Pull = GPIO_NOPULL;
+ gpioinitstruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
+
+ /* Configure USART Tx */
+ gpioinitstruct.Pin = USART_TX_PIN;
+ gpioinitstruct.Alternate = USART_TX_AF;
+ HAL_GPIO_Init(USART_TX_GPIO_PORT, &gpioinitstruct);
+
+ /* Configure USART Rx */
+ gpioinitstruct.Pin = USART_RX_PIN;
+ gpioinitstruct.Alternate = USART_RX_AF;
+ HAL_GPIO_Init(USART_RX_GPIO_PORT, &gpioinitstruct);
+
+ /*** Configure the USART peripheral ***/
+ /* Enable USART clock */
+ USART_CLK_ENABLE();
+}
+
+/* De-initialize GPIOs used by USART */
+void gpio_lld_usart_deInit(void) {
+ HAL_GPIO_DeInit(USART_TX_GPIO_PORT, USART_TX_PIN);
+ HAL_GPIO_DeInit(USART_RX_GPIO_PORT, USART_RX_PIN);
+ /* Do not disable clocks as they could be used by others GPIOs and it seems
+ to not need power in STOP mode */
+}
+
+/* Initialize GPIOs used by LPUART */
+void gpio_lld_lpuart_init(void)
+{
+ GPIO_InitTypeDef gpioinitstruct = {0};
+
+ /*** Configure the GPIOs ***/
+ /* Enable GPIO clock */
+ LPUART_TX_GPIO_CLK_ENABLE();
+ LPUART_RX_GPIO_CLK_ENABLE();
+
+ /* Common configuration to Tx and Rx */
+ gpioinitstruct.Mode = GPIO_MODE_AF_PP;
+ gpioinitstruct.Pull = GPIO_NOPULL;
+ gpioinitstruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
+
+ /* Configure LPUART Tx */
+ gpioinitstruct.Pin = LPUART_TX_PIN;
+ gpioinitstruct.Alternate = LPUART_TX_AF;
+ HAL_GPIO_Init(LPUART_TX_GPIO_PORT, &gpioinitstruct);
+
+ /* Configure LPUART Rx */
+ gpioinitstruct.Pin = LPUART_RX_PIN;
+ gpioinitstruct.Alternate = LPUART_RX_AF;
+ HAL_GPIO_Init(LPUART_RX_GPIO_PORT, &gpioinitstruct);
+
+ /*** Configure the LPUART peripheral ***/
+ /* Enable LPUART clock */
+ LPUART_CLK_ENABLE();
+}
+
+/* De-initialize GPIOs used by LPUART */
+void gpio_lld_lpuart_deInit(void) {
+ HAL_GPIO_DeInit(LPUART_TX_GPIO_PORT, LPUART_TX_PIN);
+ HAL_GPIO_DeInit(LPUART_RX_GPIO_PORT, LPUART_RX_PIN);
+ /* Do not disable clocks as they could be used by others GPIOs and it seems
+ to not need power in STOP mode */
+}
+
+
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/Projects/NUCLEO-WB15CC/Applications/BLE_LLD/BLE_LLD_Lowpower/Core/Src/hw_timerserver.c b/Projects/NUCLEO-WB15CC/Applications/BLE_LLD/BLE_LLD_Lowpower/Core/Src/hw_timerserver.c
new file mode 100644
index 000000000..e0e4fcb5d
--- /dev/null
+++ b/Projects/NUCLEO-WB15CC/Applications/BLE_LLD/BLE_LLD_Lowpower/Core/Src/hw_timerserver.c
@@ -0,0 +1,893 @@
+/**
+ ******************************************************************************
+ * File Name : hw_timerserver.c
+ * Description : Hardware timerserver source file for STM32WPAN Middleware.
+ *
+ ******************************************************************************
+ * @attention
+ *
+ * <h2><center>&copy; Copyright (c) 2020 STMicroelectronics.
+ * All rights reserved.</center></h2>
+ *
+ * This software component is licensed by ST under Ultimate Liberty license
+ * SLA0044, the "License"; You may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at:
+ * www.st.com/SLA0044
+ *
+ ******************************************************************************
+ */
+
+/* Includes ------------------------------------------------------------------*/
+#include "app_common.h"
+#include "hw_conf.h"
+
+/* Private typedef -----------------------------------------------------------*/
+typedef enum
+{
+ TimerID_Free,
+ TimerID_Created,
+ TimerID_Running
+}TimerIDStatus_t;
+
+typedef enum
+{
+ SSR_Read_Requested,
+ SSR_Read_Not_Requested
+}RequestReadSSR_t;
+
+typedef enum
+{
+ WakeupTimerValue_Overpassed,
+ WakeupTimerValue_LargeEnough
+}WakeupTimerLimitation_Status_t;
+
+typedef struct
+{
+ HW_TS_pTimerCb_t pTimerCallBack;
+ uint32_t CounterInit;
+ uint32_t CountLeft;
+ TimerIDStatus_t TimerIDStatus;
+ HW_TS_Mode_t TimerMode;
+ uint32_t TimerProcessID;
+ uint8_t PreviousID;
+ uint8_t NextID;
+}TimerContext_t;
+
+/* Private defines -----------------------------------------------------------*/
+#define SSR_FORBIDDEN_VALUE 0xFFFFFFFF
+#define TIMER_LIST_EMPTY 0xFFFF
+
+/* Private macros ------------------------------------------------------------*/
+/* Private variables ---------------------------------------------------------*/
+
+/**
+ * START of Section TIMERSERVER_CONTEXT
+ */
+
+PLACE_IN_SECTION("TIMERSERVER_CONTEXT") static volatile TimerContext_t aTimerContext[CFG_HW_TS_MAX_NBR_CONCURRENT_TIMER];
+PLACE_IN_SECTION("TIMERSERVER_CONTEXT") static volatile uint8_t CurrentRunningTimerID;
+PLACE_IN_SECTION("TIMERSERVER_CONTEXT") static volatile uint8_t PreviousRunningTimerID;
+PLACE_IN_SECTION("TIMERSERVER_CONTEXT") static volatile uint32_t SSRValueOnLastSetup;
+PLACE_IN_SECTION("TIMERSERVER_CONTEXT") static volatile WakeupTimerLimitation_Status_t WakeupTimerLimitation;
+
+/**
+ * END of Section TIMERSERVER_CONTEXT
+ */
+
+static RTC_HandleTypeDef *phrtc; /**< RTC handle */
+static uint8_t WakeupTimerDivider;
+static uint8_t AsynchPrescalerUserConfig;
+static uint16_t SynchPrescalerUserConfig;
+static volatile uint16_t MaxWakeupTimerSetup;
+
+/* Global variables ----------------------------------------------------------*/
+/* Private function prototypes -----------------------------------------------*/
+static void RestartWakeupCounter(uint16_t Value);
+static uint16_t ReturnTimeElapsed(void);
+static void RescheduleTimerList(void);
+static void UnlinkTimer(uint8_t TimerID, RequestReadSSR_t RequestReadSSR);
+static void LinkTimerBefore(uint8_t TimerID, uint8_t RefTimerID);
+static void LinkTimerAfter(uint8_t TimerID, uint8_t RefTimerID);
+static uint16_t linkTimer(uint8_t TimerID);
+static uint32_t ReadRtcSsrValue(void);
+
+__weak void HW_TS_RTC_CountUpdated_AppNot(void);
+
+/* Functions Definition ------------------------------------------------------*/
+
+/**
+ * @brief Read the RTC_SSR value
+ * As described in the reference manual, the RTC_SSR shall be read twice to ensure
+ * reliability of the value
+ * @param None
+ * @retval SSR value read
+ */
+static uint32_t ReadRtcSsrValue(void)
+{
+ uint32_t first_read;
+ uint32_t second_read;
+
+ first_read = (uint32_t)(READ_BIT(RTC->SSR, RTC_SSR_SS));
+
+ second_read = (uint32_t)(READ_BIT(RTC->SSR, RTC_SSR_SS));
+
+ while(first_read != second_read)
+ {
+ first_read = second_read;
+
+ second_read = (uint32_t)(READ_BIT(RTC->SSR, RTC_SSR_SS));
+ }
+
+ return second_read;
+}
+
+/**
+ * @brief Insert a Timer in the list after the Timer ID specified
+ * @param TimerID: The ID of the Timer
+ * @param RefTimerID: The ID of the Timer to be linked after
+ * @retval None
+ */
+static void LinkTimerAfter(uint8_t TimerID, uint8_t RefTimerID)
+{
+ uint8_t next_id;
+
+ next_id = aTimerContext[RefTimerID].NextID;
+
+ if(next_id != CFG_HW_TS_MAX_NBR_CONCURRENT_TIMER)
+ {
+ aTimerContext[next_id].PreviousID = TimerID;
+ }
+ aTimerContext[TimerID].NextID = next_id;
+ aTimerContext[TimerID].PreviousID = RefTimerID ;
+ aTimerContext[RefTimerID].NextID = TimerID;
+
+ return;
+}
+
+/**
+ * @brief Insert a Timer in the list before the ID specified
+ * @param TimerID: The ID of the Timer
+ * @param RefTimerID: The ID of the Timer to be linked before
+ * @retval None
+ */
+static void LinkTimerBefore(uint8_t TimerID, uint8_t RefTimerID)
+{
+ uint8_t previous_id;
+
+ if(RefTimerID != CurrentRunningTimerID)
+ {
+ previous_id = aTimerContext[RefTimerID].PreviousID;
+
+ aTimerContext[previous_id].NextID = TimerID;
+ aTimerContext[TimerID].NextID = RefTimerID;
+ aTimerContext[TimerID].PreviousID = previous_id ;
+ aTimerContext[RefTimerID].PreviousID = TimerID;
+ }
+ else
+ {
+ aTimerContext[TimerID].NextID = RefTimerID;
+ aTimerContext[RefTimerID].PreviousID = TimerID;
+ }
+
+ return;
+}
+
+/**
+ * @brief Insert a Timer in the list
+ * @param TimerID: The ID of the Timer
+ * @retval None
+ */
+static uint16_t linkTimer(uint8_t TimerID)
+{
+ uint32_t time_left;
+ uint16_t time_elapsed;
+ uint8_t timer_id_lookup;
+ uint8_t next_id;
+
+ if(CurrentRunningTimerID == CFG_HW_TS_MAX_NBR_CONCURRENT_TIMER)
+ {
+ /**
+ * No timer in the list
+ */
+ PreviousRunningTimerID = CurrentRunningTimerID;
+ CurrentRunningTimerID = TimerID;
+ aTimerContext[TimerID].NextID = CFG_HW_TS_MAX_NBR_CONCURRENT_TIMER;
+
+ SSRValueOnLastSetup = SSR_FORBIDDEN_VALUE;
+ time_elapsed = 0;
+ }
+ else
+ {
+ time_elapsed = ReturnTimeElapsed();
+
+ /**
+ * update count of the timer to be linked
+ */
+ aTimerContext[TimerID].CountLeft += time_elapsed;
+ time_left = aTimerContext[TimerID].CountLeft;
+
+ /**
+ * Search for index where the new timer shall be linked
+ */
+ if(aTimerContext[CurrentRunningTimerID].CountLeft <= time_left)
+ {
+ /**
+ * Search for the ID after the first one
+ */
+ timer_id_lookup = CurrentRunningTimerID;
+ next_id = aTimerContext[timer_id_lookup].NextID;
+ while((next_id != CFG_HW_TS_MAX_NBR_CONCURRENT_TIMER) && (aTimerContext[next_id].CountLeft <= time_left))
+ {
+ timer_id_lookup = aTimerContext[timer_id_lookup].NextID;
+ next_id = aTimerContext[timer_id_lookup].NextID;
+ }
+
+ /**
+ * Link after the ID
+ */
+ LinkTimerAfter(TimerID, timer_id_lookup);
+ }
+ else
+ {
+ /**
+ * Link before the first ID
+ */
+ LinkTimerBefore(TimerID, CurrentRunningTimerID);
+ PreviousRunningTimerID = CurrentRunningTimerID;
+ CurrentRunningTimerID = TimerID;
+ }
+ }
+
+ return time_elapsed;
+}
+
+/**
+ * @brief Remove a Timer from the list
+ * @param TimerID: The ID of the Timer
+ * @param RequestReadSSR: Request to read the SSR register or not
+ * @retval None
+ */
+static void UnlinkTimer(uint8_t TimerID, RequestReadSSR_t RequestReadSSR)
+{
+ uint8_t previous_id;
+ uint8_t next_id;
+
+ if(TimerID == CurrentRunningTimerID)
+ {
+ PreviousRunningTimerID = CurrentRunningTimerID;
+ CurrentRunningTimerID = aTimerContext[TimerID].NextID;
+ }
+ else
+ {
+ previous_id = aTimerContext[TimerID].PreviousID;
+ next_id = aTimerContext[TimerID].NextID;
+
+ aTimerContext[previous_id].NextID = aTimerContext[TimerID].NextID;
+ if(next_id != CFG_HW_TS_MAX_NBR_CONCURRENT_TIMER)
+ {
+ aTimerContext[next_id].PreviousID = aTimerContext[TimerID].PreviousID;
+ }
+ }
+
+ /**
+ * Timer is out of the list
+ */
+ aTimerContext[TimerID].TimerIDStatus = TimerID_Created;
+
+ if((CurrentRunningTimerID == CFG_HW_TS_MAX_NBR_CONCURRENT_TIMER) && (RequestReadSSR == SSR_Read_Requested))
+ {
+ SSRValueOnLastSetup = SSR_FORBIDDEN_VALUE;
+ }
+
+ return;
+}
+
+/**
+ * @brief Return the number of ticks counted by the wakeuptimer since it has been started
+ * @note The API is reading the SSR register to get how many ticks have been counted
+ * since the time the timer has been started
+ * @param None
+ * @retval Time expired in Ticks
+ */
+static uint16_t ReturnTimeElapsed(void)
+{
+ uint32_t return_value;
+ uint32_t wrap_counter;
+
+ if(SSRValueOnLastSetup != SSR_FORBIDDEN_VALUE)
+ {
+ return_value = ReadRtcSsrValue(); /**< Read SSR register first */
+
+ if (SSRValueOnLastSetup >= return_value)
+ {
+ return_value = SSRValueOnLastSetup - return_value;
+ }
+ else
+ {
+ wrap_counter = SynchPrescalerUserConfig - return_value;
+ return_value = SSRValueOnLastSetup + wrap_counter;
+ }
+
+ /**
+ * At this stage, ReturnValue holds the number of ticks counted by SSR
+ * Need to translate in number of ticks counted by the Wakeuptimer
+ */
+ return_value = return_value*AsynchPrescalerUserConfig;
+ return_value = return_value >> WakeupTimerDivider;
+ }
+ else
+ {
+ return_value = 0;
+ }
+
+ return (uint16_t)return_value;
+}
+
+/**
+ * @brief Set the wakeup counter
+ * @note The API is writing the counter value so that the value is decreased by one to cope with the fact
+ * the interrupt is generated with 1 extra clock cycle (See RefManuel)
+ * It assumes all condition are met to be allowed to write the wakeup counter
+ * @param Value: Value to be written in the counter
+ * @retval None
+ */
+static void RestartWakeupCounter(uint16_t Value)
+{
+ /**
+ * The wakeuptimer has been disabled in the calling function to reduce the time to poll the WUTWF
+ * FLAG when the new value will have to be written
+ * __HAL_RTC_WAKEUPTIMER_DISABLE(phrtc);
+ */
+
+ if(Value == 0)
+ {
+ SSRValueOnLastSetup = ReadRtcSsrValue();
+
+ /**
+ * Simulate that the Timer expired
+ */
+ HAL_NVIC_SetPendingIRQ(CFG_HW_TS_RTC_WAKEUP_HANDLER_ID);
+ }
+ else
+ {
+ if((Value > 1) ||(WakeupTimerDivider != 1))
+ {
+ Value -= 1;
+ }
+
+ while(__HAL_RTC_WAKEUPTIMER_GET_FLAG(phrtc, RTC_FLAG_WUTWF) == RESET);
+
+ /**
+ * make sure to clear the flags after checking the WUTWF.
+ * It takes 2 RTCCLK between the time the WUTE bit is disabled and the
+ * time the timer is disabled. The WUTWF bit somehow guarantee the system is stable
+ * Otherwise, when the timer is periodic with 1 Tick, it may generate an extra interrupt in between
+ * due to the autoreload feature
+ */
+ __HAL_RTC_WAKEUPTIMER_CLEAR_FLAG(phrtc, RTC_FLAG_WUTF); /**< Clear flag in RTC module */
+ __HAL_RTC_WAKEUPTIMER_EXTI_CLEAR_FLAG(); /**< Clear flag in EXTI module */
+ HAL_NVIC_ClearPendingIRQ(CFG_HW_TS_RTC_WAKEUP_HANDLER_ID); /**< Clear pending bit in NVIC */
+
+ MODIFY_REG(RTC->WUTR, RTC_WUTR_WUT, Value);
+
+ /**
+ * Update the value here after the WUTWF polling that may take some time
+ */
+ SSRValueOnLastSetup = ReadRtcSsrValue();
+
+ __HAL_RTC_WAKEUPTIMER_ENABLE(phrtc); /**< Enable the Wakeup Timer */
+
+ HW_TS_RTC_CountUpdated_AppNot();
+ }
+
+ return ;
+}
+
+/**
+ * @brief Reschedule the list of timer
+ * @note 1) Update the count left for each timer in the list
+ * 2) Setup the wakeuptimer
+ * @param None
+ * @retval None
+ */
+static void RescheduleTimerList(void)
+{
+ uint8_t localTimerID;
+ uint32_t timecountleft;
+ uint16_t wakeup_timer_value;
+ uint16_t time_elapsed;
+
+ /**
+ * The wakeuptimer is disabled now to reduce the time to poll the WUTWF
+ * FLAG when the new value will have to be written
+ */
+ if((READ_BIT(RTC->CR, RTC_CR_WUTE) == (RTC_CR_WUTE)) == SET)
+ {
+ /**
+ * Wait for the flag to be back to 0 when the wakeup timer is enabled
+ */
+ while(__HAL_RTC_WAKEUPTIMER_GET_FLAG(phrtc, RTC_FLAG_WUTWF) == SET);
+ }
+ __HAL_RTC_WAKEUPTIMER_DISABLE(phrtc); /**< Disable the Wakeup Timer */
+
+ localTimerID = CurrentRunningTimerID;
+
+ /**
+ * Calculate what will be the value to write in the wakeuptimer
+ */
+ timecountleft = aTimerContext[localTimerID].CountLeft;
+
+ /**
+ * Read how much has been counted
+ */
+ time_elapsed = ReturnTimeElapsed();
+
+ if(timecountleft < time_elapsed )
+ {
+ /**
+ * There is no tick left to count
+ */
+ wakeup_timer_value = 0;
+ WakeupTimerLimitation = WakeupTimerValue_LargeEnough;
+ }
+ else
+ {
+ if(timecountleft > (time_elapsed + MaxWakeupTimerSetup))
+ {
+ /**
+ * The number of tick left is greater than the Wakeuptimer maximum value
+ */
+ wakeup_timer_value = MaxWakeupTimerSetup;
+
+ WakeupTimerLimitation = WakeupTimerValue_Overpassed;
+ }
+ else
+ {
+ wakeup_timer_value = timecountleft - time_elapsed;
+ WakeupTimerLimitation = WakeupTimerValue_LargeEnough;
+ }
+
+ }
+
+ /**
+ * update ticks left to be counted for each timer
+ */
+ while(localTimerID != CFG_HW_TS_MAX_NBR_CONCURRENT_TIMER)
+ {
+ if (aTimerContext[localTimerID].CountLeft < time_elapsed)
+ {
+ aTimerContext[localTimerID].CountLeft = 0;
+ }
+ else
+ {
+ aTimerContext[localTimerID].CountLeft -= time_elapsed;
+ }
+ localTimerID = aTimerContext[localTimerID].NextID;
+ }
+
+ /**
+ * Write next count
+ */
+ RestartWakeupCounter(wakeup_timer_value);
+
+ return ;
+}
+
+/* Public functions ----------------------------------------------------------*/
+
+/**
+ * For all public interface except that may need write access to the RTC, the RTC
+ * shall be unlock at the beginning and locked at the output
+ * In order to ease maintainability, the unlock is done at the top and the lock at then end
+ * in case some new implementation is coming in the future
+ */
+
+void HW_TS_RTC_Wakeup_Handler(void)
+{
+ HW_TS_pTimerCb_t ptimer_callback;
+ uint32_t timer_process_id;
+ uint8_t local_current_running_timer_id;
+#if (CFG_HW_TS_USE_PRIMASK_AS_CRITICAL_SECTION == 1)
+ uint32_t primask_bit;
+#endif
+
+#if (CFG_HW_TS_USE_PRIMASK_AS_CRITICAL_SECTION == 1)
+ primask_bit = __get_PRIMASK(); /**< backup PRIMASK bit */
+ __disable_irq(); /**< Disable all interrupts by setting PRIMASK bit on Cortex*/
+#endif
+
+/* Disable the write protection for RTC registers */
+ __HAL_RTC_WRITEPROTECTION_DISABLE( phrtc );
+
+ /**
+ * Disable the Wakeup Timer
+ * This may speed up a bit the processing to wait the timer to be disabled
+ * The timer is still counting 2 RTCCLK
+ */
+ __HAL_RTC_WAKEUPTIMER_DISABLE(phrtc);
+
+ local_current_running_timer_id = CurrentRunningTimerID;
+
+ if(aTimerContext[local_current_running_timer_id].TimerIDStatus == TimerID_Running)
+ {
+ ptimer_callback = aTimerContext[local_current_running_timer_id].pTimerCallBack;
+ timer_process_id = aTimerContext[local_current_running_timer_id].TimerProcessID;
+
+ /**
+ * It should be good to check whether the TimeElapsed is greater or not than the tick left to be counted
+ * However, due to the inaccuracy of the reading of the time elapsed, it may return there is 1 tick
+ * to be left whereas the count is over
+ * A more secure implementation has been done with a flag to state whereas the full count has been written
+ * in the wakeuptimer or not
+ */
+ if(WakeupTimerLimitation != WakeupTimerValue_Overpassed)
+ {
+ if(aTimerContext[local_current_running_timer_id].TimerMode == hw_ts_Repeated)
+ {
+ UnlinkTimer(local_current_running_timer_id, SSR_Read_Not_Requested);
+#if (CFG_HW_TS_USE_PRIMASK_AS_CRITICAL_SECTION == 1)
+ __set_PRIMASK(primask_bit); /**< Restore PRIMASK bit*/
+#endif
+ HW_TS_Start(local_current_running_timer_id, aTimerContext[local_current_running_timer_id].CounterInit);
+
+ /* Disable the write protection for RTC registers */
+ __HAL_RTC_WRITEPROTECTION_DISABLE( phrtc );
+ }
+ else
+ {
+#if (CFG_HW_TS_USE_PRIMASK_AS_CRITICAL_SECTION == 1)
+ __set_PRIMASK(primask_bit); /**< Restore PRIMASK bit*/
+#endif
+ HW_TS_Stop(local_current_running_timer_id);
+
+ /* Disable the write protection for RTC registers */
+ __HAL_RTC_WRITEPROTECTION_DISABLE( phrtc );
+ }
+
+ HW_TS_RTC_Int_AppNot(timer_process_id, local_current_running_timer_id, ptimer_callback);
+ }
+ else
+ {
+ RescheduleTimerList();
+#if (CFG_HW_TS_USE_PRIMASK_AS_CRITICAL_SECTION == 1)
+ __set_PRIMASK(primask_bit); /**< Restore PRIMASK bit*/
+#endif
+ }
+ }
+ else
+ {
+ /**
+ * We should never end up in this case
+ * However, if due to any bug in the timer server this is the case, the mistake may not impact the user.
+ * We could just clean the interrupt flag and get out from this unexpected interrupt
+ */
+ while(__HAL_RTC_WAKEUPTIMER_GET_FLAG(phrtc, RTC_FLAG_WUTWF) == RESET);
+
+ /**
+ * make sure to clear the flags after checking the WUTWF.
+ * It takes 2 RTCCLK between the time the WUTE bit is disabled and the
+ * time the timer is disabled. The WUTWF bit somehow guarantee the system is stable
+ * Otherwise, when the timer is periodic with 1 Tick, it may generate an extra interrupt in between
+ * due to the autoreload feature
+ */
+ __HAL_RTC_WAKEUPTIMER_CLEAR_FLAG(phrtc, RTC_FLAG_WUTF); /**< Clear flag in RTC module */
+ __HAL_RTC_WAKEUPTIMER_EXTI_CLEAR_FLAG(); /**< Clear flag in EXTI module */
+
+#if (CFG_HW_TS_USE_PRIMASK_AS_CRITICAL_SECTION == 1)
+ __set_PRIMASK(primask_bit); /**< Restore PRIMASK bit*/
+#endif
+ }
+
+ /* Enable the write protection for RTC registers */
+ __HAL_RTC_WRITEPROTECTION_ENABLE( phrtc );
+
+ return;
+}
+
+void HW_TS_Init(HW_TS_InitMode_t TimerInitMode, RTC_HandleTypeDef *hrtc)
+{
+ uint8_t loop;
+ uint32_t localmaxwakeuptimersetup;
+
+ /**
+ * Get RTC handler
+ */
+ phrtc = hrtc;
+
+ /* Disable the write protection for RTC registers */
+ __HAL_RTC_WRITEPROTECTION_DISABLE( phrtc );
+
+ SET_BIT(RTC->CR, RTC_CR_BYPSHAD);
+
+ /**
+ * Readout the user config
+ */
+ WakeupTimerDivider = (4 - ((uint32_t)(READ_BIT(RTC->CR, RTC_CR_WUCKSEL))));
+
+ AsynchPrescalerUserConfig = (uint8_t)(READ_BIT(RTC->PRER, RTC_PRER_PREDIV_A) >> (uint32_t)POSITION_VAL(RTC_PRER_PREDIV_A)) + 1;
+
+ SynchPrescalerUserConfig = (uint16_t)(READ_BIT(RTC->PRER, RTC_PRER_PREDIV_S)) + 1;
+
+ /**
+ * Margin is taken to avoid wrong calculation when the wrap around is there and some
+ * application interrupts may have delayed the reading
+ */
+ localmaxwakeuptimersetup = ((((SynchPrescalerUserConfig - 1)*AsynchPrescalerUserConfig) - CFG_HW_TS_RTC_HANDLER_MAX_DELAY) >> WakeupTimerDivider);
+
+ if(localmaxwakeuptimersetup >= 0xFFFF)
+ {
+ MaxWakeupTimerSetup = 0xFFFF;
+ }
+ else
+ {
+ MaxWakeupTimerSetup = (uint16_t)localmaxwakeuptimersetup;
+ }
+
+ /**
+ * Configure EXTI module
+ */
+ LL_EXTI_EnableRisingTrig_0_31(RTC_EXTI_LINE_WAKEUPTIMER_EVENT);
+ LL_EXTI_EnableIT_0_31(RTC_EXTI_LINE_WAKEUPTIMER_EVENT);
+
+ if(TimerInitMode == hw_ts_InitMode_Full)
+ {
+ WakeupTimerLimitation = WakeupTimerValue_LargeEnough;
+ SSRValueOnLastSetup = SSR_FORBIDDEN_VALUE;
+
+ /**
+ * Initialize the timer server
+ */
+ for(loop = 0; loop < CFG_HW_TS_MAX_NBR_CONCURRENT_TIMER; loop++)
+ {
+ aTimerContext[loop].TimerIDStatus = TimerID_Free;
+ }
+
+ CurrentRunningTimerID = CFG_HW_TS_MAX_NBR_CONCURRENT_TIMER; /**< Set ID to non valid value */
+
+ __HAL_RTC_WAKEUPTIMER_DISABLE(phrtc); /**< Disable the Wakeup Timer */
+ __HAL_RTC_WAKEUPTIMER_CLEAR_FLAG(phrtc, RTC_FLAG_WUTF); /**< Clear flag in RTC module */
+ __HAL_RTC_WAKEUPTIMER_EXTI_CLEAR_FLAG(); /**< Clear flag in EXTI module */
+ HAL_NVIC_ClearPendingIRQ(CFG_HW_TS_RTC_WAKEUP_HANDLER_ID); /**< Clear pending bit in NVIC */
+ __HAL_RTC_WAKEUPTIMER_ENABLE_IT(phrtc, RTC_IT_WUT); /**< Enable interrupt in RTC module */
+ }
+ else
+ {
+ if(__HAL_RTC_WAKEUPTIMER_GET_FLAG(phrtc, RTC_FLAG_WUTF) != RESET)
+ {
+ /**
+ * Simulate that the Timer expired
+ */
+ HAL_NVIC_SetPendingIRQ(CFG_HW_TS_RTC_WAKEUP_HANDLER_ID);
+ }
+ }
+
+ /* Enable the write protection for RTC registers */
+ __HAL_RTC_WRITEPROTECTION_ENABLE( phrtc );
+
+ HAL_NVIC_SetPriority(CFG_HW_TS_RTC_WAKEUP_HANDLER_ID, CFG_HW_TS_NVIC_RTC_WAKEUP_IT_PREEMPTPRIO, CFG_HW_TS_NVIC_RTC_WAKEUP_IT_SUBPRIO); /**< Set NVIC priority */
+ HAL_NVIC_EnableIRQ(CFG_HW_TS_RTC_WAKEUP_HANDLER_ID); /**< Enable NVIC */
+
+ return;
+}
+
+HW_TS_ReturnStatus_t HW_TS_Create(uint32_t TimerProcessID, uint8_t *pTimerId, HW_TS_Mode_t TimerMode, HW_TS_pTimerCb_t pftimeout_handler)
+{
+ HW_TS_ReturnStatus_t localreturnstatus;
+ uint8_t loop = 0;
+#if (CFG_HW_TS_USE_PRIMASK_AS_CRITICAL_SECTION == 1)
+ uint32_t primask_bit;
+#endif
+
+#if (CFG_HW_TS_USE_PRIMASK_AS_CRITICAL_SECTION == 1)
+ primask_bit = __get_PRIMASK(); /**< backup PRIMASK bit */
+ __disable_irq(); /**< Disable all interrupts by setting PRIMASK bit on Cortex*/
+#endif
+
+ while((loop < CFG_HW_TS_MAX_NBR_CONCURRENT_TIMER) && (aTimerContext[loop].TimerIDStatus != TimerID_Free))
+ {
+ loop++;
+ }
+
+ if(loop != CFG_HW_TS_MAX_NBR_CONCURRENT_TIMER)
+ {
+ aTimerContext[loop].TimerIDStatus = TimerID_Created;
+
+#if (CFG_HW_TS_USE_PRIMASK_AS_CRITICAL_SECTION == 1)
+ __set_PRIMASK(primask_bit); /**< Restore PRIMASK bit*/
+#endif
+
+ aTimerContext[loop].TimerProcessID = TimerProcessID;
+ aTimerContext[loop].TimerMode = TimerMode;
+ aTimerContext[loop].pTimerCallBack = pftimeout_handler;
+ *pTimerId = loop;
+
+ localreturnstatus = hw_ts_Successful;
+ }
+ else
+ {
+#if (CFG_HW_TS_USE_PRIMASK_AS_CRITICAL_SECTION == 1)
+ __set_PRIMASK(primask_bit); /**< Restore PRIMASK bit*/
+#endif
+
+ localreturnstatus = hw_ts_Failed;
+ }
+
+ return(localreturnstatus);
+}
+
+void HW_TS_Delete(uint8_t timer_id)
+{
+ HW_TS_Stop(timer_id);
+
+ aTimerContext[timer_id].TimerIDStatus = TimerID_Free; /**< release ID */
+
+ return;
+}
+
+void HW_TS_Stop(uint8_t timer_id)
+{
+ uint8_t localcurrentrunningtimerid;
+
+#if (CFG_HW_TS_USE_PRIMASK_AS_CRITICAL_SECTION == 1)
+ uint32_t primask_bit;
+#endif
+
+#if (CFG_HW_TS_USE_PRIMASK_AS_CRITICAL_SECTION == 1)
+ primask_bit = __get_PRIMASK(); /**< backup PRIMASK bit */
+ __disable_irq(); /**< Disable all interrupts by setting PRIMASK bit on Cortex*/
+#endif
+
+ HAL_NVIC_DisableIRQ(CFG_HW_TS_RTC_WAKEUP_HANDLER_ID); /**< Disable NVIC */
+
+ /* Disable the write protection for RTC registers */
+ __HAL_RTC_WRITEPROTECTION_DISABLE( phrtc );
+
+ if(aTimerContext[timer_id].TimerIDStatus == TimerID_Running)
+ {
+ UnlinkTimer(timer_id, SSR_Read_Requested);
+ localcurrentrunningtimerid = CurrentRunningTimerID;
+
+ if(localcurrentrunningtimerid == CFG_HW_TS_MAX_NBR_CONCURRENT_TIMER)
+ {
+ /**
+ * List is empty
+ */
+
+ /**
+ * Disable the timer
+ */
+ if((READ_BIT(RTC->CR, RTC_CR_WUTE) == (RTC_CR_WUTE)) == SET)
+ {
+ /**
+ * Wait for the flag to be back to 0 when the wakeup timer is enabled
+ */
+ while(__HAL_RTC_WAKEUPTIMER_GET_FLAG(phrtc, RTC_FLAG_WUTWF) == SET);
+ }
+ __HAL_RTC_WAKEUPTIMER_DISABLE(phrtc); /**< Disable the Wakeup Timer */
+
+ while(__HAL_RTC_WAKEUPTIMER_GET_FLAG(phrtc, RTC_FLAG_WUTWF) == RESET);
+
+ /**
+ * make sure to clear the flags after checking the WUTWF.
+ * It takes 2 RTCCLK between the time the WUTE bit is disabled and the
+ * time the timer is disabled. The WUTWF bit somehow guarantee the system is stable
+ * Otherwise, when the timer is periodic with 1 Tick, it may generate an extra interrupt in between
+ * due to the autoreload feature
+ */
+ __HAL_RTC_WAKEUPTIMER_CLEAR_FLAG(phrtc, RTC_FLAG_WUTF); /**< Clear flag in RTC module */
+ __HAL_RTC_WAKEUPTIMER_EXTI_CLEAR_FLAG(); /**< Clear flag in EXTI module */
+ HAL_NVIC_ClearPendingIRQ(CFG_HW_TS_RTC_WAKEUP_HANDLER_ID); /**< Clear pending bit in NVIC */
+ }
+ else if(PreviousRunningTimerID != localcurrentrunningtimerid)
+ {
+ RescheduleTimerList();
+ }
+ }
+
+ /* Enable the write protection for RTC registers */
+ __HAL_RTC_WRITEPROTECTION_ENABLE( phrtc );
+
+ HAL_NVIC_EnableIRQ(CFG_HW_TS_RTC_WAKEUP_HANDLER_ID); /**< Enable NVIC */
+
+#if (CFG_HW_TS_USE_PRIMASK_AS_CRITICAL_SECTION == 1)
+ __set_PRIMASK(primask_bit); /**< Restore PRIMASK bit*/
+#endif
+
+ return;
+}
+
+void HW_TS_Start(uint8_t timer_id, uint32_t timeout_ticks)
+{
+ uint16_t time_elapsed;
+ uint8_t localcurrentrunningtimerid;
+
+#if (CFG_HW_TS_USE_PRIMASK_AS_CRITICAL_SECTION == 1)
+ uint32_t primask_bit;
+#endif
+
+ if(aTimerContext[timer_id].TimerIDStatus == TimerID_Running)
+ {
+ HW_TS_Stop( timer_id );
+ }
+
+#if (CFG_HW_TS_USE_PRIMASK_AS_CRITICAL_SECTION == 1)
+ primask_bit = __get_PRIMASK(); /**< backup PRIMASK bit */
+ __disable_irq(); /**< Disable all interrupts by setting PRIMASK bit on Cortex*/
+#endif
+
+ HAL_NVIC_DisableIRQ(CFG_HW_TS_RTC_WAKEUP_HANDLER_ID); /**< Disable NVIC */
+
+ /* Disable the write protection for RTC registers */
+ __HAL_RTC_WRITEPROTECTION_DISABLE( phrtc );
+
+ aTimerContext[timer_id].TimerIDStatus = TimerID_Running;
+
+ aTimerContext[timer_id].CountLeft = timeout_ticks;
+ aTimerContext[timer_id].CounterInit = timeout_ticks;
+
+ time_elapsed = linkTimer(timer_id);
+
+ localcurrentrunningtimerid = CurrentRunningTimerID;
+
+ if(PreviousRunningTimerID != localcurrentrunningtimerid)
+ {
+ RescheduleTimerList();
+ }
+ else
+ {
+ aTimerContext[timer_id].CountLeft -= time_elapsed;
+ }
+
+ /* Enable the write protection for RTC registers */
+ __HAL_RTC_WRITEPROTECTION_ENABLE( phrtc );
+
+ HAL_NVIC_EnableIRQ(CFG_HW_TS_RTC_WAKEUP_HANDLER_ID); /**< Enable NVIC */
+
+#if (CFG_HW_TS_USE_PRIMASK_AS_CRITICAL_SECTION == 1)
+ __set_PRIMASK(primask_bit); /**< Restore PRIMASK bit*/
+#endif
+
+ return;
+}
+
+uint16_t HW_TS_RTC_ReadLeftTicksToCount(void)
+{
+ uint32_t primask_bit;
+ uint16_t return_value, auro_reload_value, elapsed_time_value;
+
+ primask_bit = __get_PRIMASK(); /**< backup PRIMASK bit */
+ __disable_irq(); /**< Disable all interrupts by setting PRIMASK bit on Cortex*/
+
+ if((READ_BIT(RTC->CR, RTC_CR_WUTE) == (RTC_CR_WUTE)) == SET)
+ {
+ auro_reload_value = (uint32_t)(READ_BIT(RTC->WUTR, RTC_WUTR_WUT));
+
+ elapsed_time_value = ReturnTimeElapsed();
+
+ if(auro_reload_value > elapsed_time_value)
+ {
+ return_value = auro_reload_value - elapsed_time_value;
+ }
+ else
+ {
+ return_value = 0;
+ }
+ }
+ else
+ {
+ return_value = TIMER_LIST_EMPTY;
+ }
+
+ __set_PRIMASK(primask_bit); /**< Restore PRIMASK bit*/
+
+ return (return_value);
+}
+
+__weak void HW_TS_RTC_Int_AppNot(uint32_t TimerProcessID, uint8_t TimerID, HW_TS_pTimerCb_t pTimerCallBack)
+{
+ pTimerCallBack();
+
+ return;
+}
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/Projects/NUCLEO-WB15CC/Applications/BLE_LLD/BLE_LLD_Lowpower/Core/Src/hw_uart.c b/Projects/NUCLEO-WB15CC/Applications/BLE_LLD/BLE_LLD_Lowpower/Core/Src/hw_uart.c
new file mode 100644
index 000000000..3c842b29a
--- /dev/null
+++ b/Projects/NUCLEO-WB15CC/Applications/BLE_LLD/BLE_LLD_Lowpower/Core/Src/hw_uart.c
@@ -0,0 +1,442 @@
+/**
+ ******************************************************************************
+ * File Name : Src/hw_uart.c
+ * Description : HW UART source file for STM32WPAN Middleware.
+ *
+ ******************************************************************************
+ * @attention
+ *
+ * <h2><center>&copy; Copyright (c) 2019 STMicroelectronics.
+ * All rights reserved.</center></h2>
+ *
+ * This software component is licensed by ST under Ultimate Liberty license
+ * SLA0044, the "License"; You may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at:
+ * www.st.com/SLA0044
+ *
+ ******************************************************************************
+ */
+
+/* Includes ------------------------------------------------------------------*/
+#include "app_common.h"
+
+/* Macros --------------------------------------------------------------------*/
+#define HW_UART_RX_IT(__HANDLE__, __USART_BASE__) \
+ do{ \
+ HW_##__HANDLE__##RxCb = cb; \
+ (__HANDLE__).Instance = (__USART_BASE__); \
+ hal_status = HAL_UART_Receive_IT(&(__HANDLE__), p_data, size); \
+ } while(0)
+
+#define HW_UART_TX_IT(__HANDLE__, __USART_BASE__) \
+ do{ \
+ HW_##__HANDLE__##TxCb = cb; \
+ (__HANDLE__).Instance = (__USART_BASE__); \
+ hal_status = HAL_UART_Transmit_IT(&(__HANDLE__), p_data, size); \
+ } while(0)
+
+#define HW_UART_TX(__HANDLE__, __USART_BASE__) \
+ do{ \
+ (__HANDLE__).Instance = (__USART_BASE__); \
+ hal_status = HAL_UART_Transmit(&(__HANDLE__), p_data, size, timeout); \
+ } while(0)
+
+/* Variables -----------------------------------------------------------------*/
+#if (CFG_HW_USART1_ENABLED == 1)
+UART_HandleTypeDef huart1;
+#if (CFG_HW_USART1_DMA_TX_SUPPORTED == 1)
+DMA_HandleTypeDef hdma_usart1_tx;
+#endif
+void (*HW_huart1RxCb)(void);
+void (*HW_huart1TxCb)(void);
+#endif
+
+#if (CFG_HW_LPUART1_ENABLED == 1)
+UART_HandleTypeDef hlpuart1;
+#if (CFG_HW_LPUART1_DMA_TX_SUPPORTED == 1)
+DMA_HandleTypeDef hdma_lpuart1_tx;
+#endif
+void (*HW_hlpuart1RxCb)(void);
+void (*HW_hlpuart1TxCb)(void);
+#endif
+
+/* Functions Definition ------------------------------------------------------*/
+
+void MX_UART_Init(hw_uart_id_t uart)
+{
+ UART_HandleTypeDef *handle = NULL;
+ USART_TypeDef *instance = NULL;
+ switch(uart){
+ case hw_uart1:
+#if (CFG_HW_USART1_ENABLED != 1)
+ return;
+#endif
+ handle = &huart1;
+ instance = USART1;
+ break;
+ case hw_lpuart1:
+#if (CFG_HW_LPUART1_ENABLED != 1)
+ return;
+#endif
+ handle = &hlpuart1;
+ instance = LPUART1;
+ break;
+ default: Error_Handler();
+ }
+ handle->Instance = instance;
+ handle->Init.BaudRate = 115200;
+ handle->Init.WordLength = UART_WORDLENGTH_8B;
+ handle->Init.StopBits = UART_STOPBITS_1;
+ handle->Init.Parity = UART_PARITY_NONE;
+ handle->Init.Mode = UART_MODE_TX_RX;
+ handle->Init.HwFlowCtl = UART_HWCONTROL_NONE;
+ handle->Init.OverSampling = UART_OVERSAMPLING_16;
+ handle->Init.OneBitSampling = UART_ONE_BIT_SAMPLE_DISABLE;
+ handle->Init.ClockPrescaler = UART_PRESCALER_DIV1;
+ handle->AdvancedInit.AdvFeatureInit = UART_ADVFEATURE_NO_INIT;
+ handle->FifoMode = UART_FIFOMODE_DISABLE;
+ if (HAL_UART_Init(handle) != HAL_OK)
+ {
+ Error_Handler();
+ }
+ if (HAL_UARTEx_SetTxFifoThreshold(handle, UART_TXFIFO_THRESHOLD_1_8) != HAL_OK)
+ {
+ Error_Handler();
+ }
+ if (HAL_UARTEx_SetRxFifoThreshold(handle, UART_RXFIFO_THRESHOLD_1_8) != HAL_OK)
+ {
+ Error_Handler();
+ }
+ if (HAL_UARTEx_DisableFifoMode(handle) != HAL_OK)
+ {
+ Error_Handler();
+ }
+}
+
+void MX_UART_Deinit(hw_uart_id_t uart)
+{
+ UART_HandleTypeDef *handle = NULL;
+ switch(uart){
+ case hw_uart1:
+#if (CFG_HW_USART1_ENABLED != 1)
+ return;
+#endif
+ handle = &huart1;
+ break;
+ case hw_lpuart1:
+#if (CFG_HW_LPUART1_ENABLED != 1)
+ return;
+#endif
+ handle = &hlpuart1;
+ break;
+ default: Error_Handler();
+ }
+ if (HAL_UART_DeInit(handle) != HAL_OK)
+ {
+ Error_Handler();
+ }
+}
+
+hw_status_t HW_UART_Receive_IT(hw_uart_id_t hw_uart_id, uint8_t *p_data, uint16_t size, void (*cb)(void))
+{
+ HAL_StatusTypeDef hal_status = HAL_OK;
+ hw_status_t hw_status = hw_uart_ok;
+
+ switch (hw_uart_id)
+ {
+#if (CFG_HW_USART1_ENABLED == 1)
+ case hw_uart1:
+ HW_UART_RX_IT(huart1, USART1);
+ break;
+#endif
+
+#if (CFG_HW_LPUART1_ENABLED == 1)
+ case hw_lpuart1:
+ HW_UART_RX_IT(hlpuart1, LPUART1);
+ break;
+#endif
+
+ default:
+ break;
+ }
+
+ switch (hal_status)
+ {
+ case HAL_OK:
+ hw_status = hw_uart_ok;
+ break;
+
+ case HAL_ERROR:
+ hw_status = hw_uart_error;
+ break;
+
+ case HAL_BUSY:
+ hw_status = hw_uart_busy;
+ break;
+
+ case HAL_TIMEOUT:
+ hw_status = hw_uart_to;
+ break;
+
+ default:
+ break;
+ }
+
+ return hw_status;
+}
+
+hw_status_t HW_UART_Transmit_IT(hw_uart_id_t hw_uart_id, uint8_t *p_data, uint16_t size, void (*cb)(void))
+{
+ HAL_StatusTypeDef hal_status = HAL_OK;
+ hw_status_t hw_status = hw_uart_ok;
+
+ switch (hw_uart_id)
+ {
+#if (CFG_HW_USART1_ENABLED == 1)
+ case hw_uart1:
+ HW_UART_TX_IT(huart1, USART1);
+ break;
+#endif
+
+#if (CFG_HW_LPUART1_ENABLED == 1)
+ case hw_lpuart1:
+ HW_UART_TX_IT(hlpuart1, LPUART1);
+ break;
+#endif
+
+ default:
+ break;
+ }
+
+ switch (hal_status)
+ {
+ case HAL_OK:
+ hw_status = hw_uart_ok;
+ break;
+
+ case HAL_ERROR:
+ hw_status = hw_uart_error;
+ break;
+
+ case HAL_BUSY:
+ hw_status = hw_uart_busy;
+ break;
+
+ case HAL_TIMEOUT:
+ hw_status = hw_uart_to;
+ break;
+
+ default:
+ break;
+ }
+
+ return hw_status;
+}
+
+hw_status_t HW_UART_Transmit(hw_uart_id_t hw_uart_id, uint8_t *p_data, uint16_t size, uint32_t timeout)
+{
+ HAL_StatusTypeDef hal_status = HAL_OK;
+ hw_status_t hw_status = hw_uart_ok;
+
+ switch (hw_uart_id)
+ {
+#if (CFG_HW_USART1_ENABLED == 1)
+ case hw_uart1:
+ HW_UART_TX(huart1, USART1);
+ break;
+#endif
+
+#if (CFG_HW_LPUART1_ENABLED == 1)
+ case hw_lpuart1:
+ HW_UART_TX(hlpuart1, LPUART1);
+ break;
+#endif
+
+ default:
+ break;
+ }
+
+ switch (hal_status)
+ {
+ case HAL_OK:
+ hw_status = hw_uart_ok;
+ break;
+
+ case HAL_ERROR:
+ hw_status = hw_uart_error;
+ break;
+
+ case HAL_BUSY:
+ hw_status = hw_uart_busy;
+ break;
+
+ case HAL_TIMEOUT:
+ hw_status = hw_uart_to;
+ break;
+
+ default:
+ break;
+ }
+
+ return hw_status;
+}
+
+hw_status_t HW_UART_Transmit_DMA(hw_uart_id_t hw_uart_id, uint8_t *p_data, uint16_t size, void (*cb)(void))
+{
+ HAL_StatusTypeDef hal_status = HAL_OK;
+ hw_status_t hw_status = hw_uart_ok;
+
+ switch (hw_uart_id)
+ {
+#if (CFG_HW_USART1_ENABLED == 1)
+ case hw_uart1:
+ HW_huart1TxCb = cb;
+ huart1.Instance = USART1;
+ hal_status = HAL_UART_Transmit_DMA(&huart1, p_data, size);
+ break;
+#endif
+
+#if (CFG_HW_LPUART1_ENABLED == 1)
+ case hw_lpuart1:
+ HW_hlpuart1TxCb = cb;
+ hlpuart1.Instance = LPUART1;
+ hal_status = HAL_UART_Transmit_DMA(&hlpuart1, p_data, size);
+ break;
+#endif
+
+ default:
+ break;
+ }
+
+ switch (hal_status)
+ {
+ case HAL_OK:
+ hw_status = hw_uart_ok;
+ break;
+
+ case HAL_ERROR:
+ hw_status = hw_uart_error;
+ break;
+
+ case HAL_BUSY:
+ hw_status = hw_uart_busy;
+ break;
+
+ case HAL_TIMEOUT:
+ hw_status = hw_uart_to;
+ break;
+
+ default:
+ break;
+ }
+
+ return hw_status;
+}
+
+#if 0
+void HW_UART_Interrupt_Handler(hw_uart_id_t hw_uart_id)
+{
+ switch (hw_uart_id)
+ {
+#if (CFG_HW_USART1_ENABLED == 1)
+ case hw_uart1:
+ HAL_UART_IRQHandler(&huart1);
+ break;
+#endif
+
+#if (CFG_HW_LPUART1_ENABLED == 1)
+ case hw_lpuart1:
+ HAL_UART_IRQHandler(&hlpuart1);
+ break;
+#endif
+
+ default:
+ break;
+ }
+
+ return;
+}
+
+void HW_UART_DMA_Interrupt_Handler(hw_uart_id_t hw_uart_id)
+{
+ switch (hw_uart_id)
+ {
+#if (CFG_HW_USART1_DMA_TX_SUPPORTED == 1)
+ case hw_uart1:
+ HAL_DMA_IRQHandler(huart1.hdmatx);
+ break;
+#endif
+
+#if (CFG_HW_LPUART1_DMA_TX_SUPPORTED == 1)
+ case hw_lpuart1:
+ HAL_DMA_IRQHandler(hlpuart1.hdmatx);
+ break;
+#endif
+
+ default:
+ break;
+ }
+
+ return;
+}
+#endif
+
+void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
+{
+ switch ((uint32_t)huart->Instance)
+ {
+#if (CFG_HW_USART1_ENABLED == 1)
+ case (uint32_t)USART1:
+ if(HW_huart1RxCb)
+ {
+ HW_huart1RxCb();
+ }
+ break;
+#endif
+
+#if (CFG_HW_LPUART1_ENABLED == 1)
+ case (uint32_t)LPUART1:
+ if(HW_hlpuart1RxCb)
+ {
+ HW_hlpuart1RxCb();
+ }
+ break;
+#endif
+
+ default:
+ break;
+ }
+
+ return;
+}
+
+void HAL_UART_TxCpltCallback(UART_HandleTypeDef *huart)
+{
+ switch ((uint32_t)huart->Instance)
+ {
+#if (CFG_HW_USART1_ENABLED == 1)
+ case (uint32_t)USART1:
+ if(HW_huart1TxCb)
+ {
+ HW_huart1TxCb();
+ }
+ break;
+#endif
+
+#if (CFG_HW_LPUART1_ENABLED == 1)
+ case (uint32_t)LPUART1:
+ if(HW_hlpuart1TxCb)
+ {
+ HW_hlpuart1TxCb();
+ }
+ break;
+#endif
+
+ default:
+ break;
+ }
+
+ return;
+}
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/Projects/NUCLEO-WB15CC/Applications/BLE_LLD/BLE_LLD_Lowpower/Core/Src/main.c b/Projects/NUCLEO-WB15CC/Applications/BLE_LLD/BLE_LLD_Lowpower/Core/Src/main.c
new file mode 100644
index 000000000..b1012309c
--- /dev/null
+++ b/Projects/NUCLEO-WB15CC/Applications/BLE_LLD/BLE_LLD_Lowpower/Core/Src/main.c
@@ -0,0 +1,607 @@
+/* USER CODE BEGIN Header */
+/**
+ ******************************************************************************
+ * @file main.c
+ * @author MCD Application Team
+ * @brief RF LLD tests application
+ *
+ @verbatim
+ ==============================================================================
+ ##### IMPORTANT NOTE #####
+ ==============================================================================
+
+ This application requests having a M0 LLD tests binary
+ flashed on the Wireless Coprocessor.
+ If it is not the case, you need to use STM32CubeProgrammer to load the appropriate
+ binary.
+
+ All available binaries are located under following directory:
+ /Projects/STM32_Copro_Wireless_Binaries
+
+ Refer to UM2237 to learn how to use/install STM32CubeProgrammer.
+ Refer to /Projects/STM32_Copro_Wireless_Binaries/ReleaseNote.html for the
+ detailed procedure to change the Wireless Coprocessor binary.
+
+ @endverbatim
+ ******************************************************************************
+ * @attention
+ *
+ * <h2><center>&copy; Copyright (c) 2019 STMicroelectronics.
+ * All rights reserved.</center></h2>
+ *
+ * This software component is licensed by ST under Ultimate Liberty license
+ * SLA0044, the "License"; You may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at:
+ * www.st.com/SLA0044
+ *
+ ******************************************************************************
+ */
+/* USER CODE END Header */
+/* Includes ------------------------------------------------------------------*/
+#include "app_common.h"
+#include "app_entry.h"
+#include "main.h"
+
+/* Private includes ----------------------------------------------------------*/
+/* USER CODE BEGIN Includes */
+#include "stm32_lpm.h"
+#include "stm32_seq.h"
+#include "dbg_trace.h"
+#include "hw_conf.h"
+#include "otp.h"
+/* USER CODE END Includes */
+
+/* Private typedef -----------------------------------------------------------*/
+/* USER CODE BEGIN PTD */
+
+/* USER CODE END PTD */
+
+/* Private define ------------------------------------------------------------*/
+/* USER CODE BEGIN PD */
+
+/* USER CODE END PD */
+
+/* Private macro -------------------------------------------------------------*/
+/* USER CODE BEGIN PM */
+
+/* USER CODE END PM */
+
+/* Private variables ---------------------------------------------------------*/
+/* USER CODE BEGIN PV */
+RTC_HandleTypeDef hrtc;
+
+/* USER CODE END PV */
+
+/* Private function prototypes -----------------------------------------------*/
+static void MX_DMA_Init(void);
+static void MX_RTC_Init(void);
+
+/* USER CODE BEGIN PFP */
+static void SystemClock_Config(void);
+static void PeriphClock_Config(void);
+static void Reset_Device( void );
+static void Reset_IPCC( void );
+static void Reset_BackupDomain( void );
+static void Init_Exti( void );
+static void Config_HSE(void);
+/* USER CODE END PFP */
+
+/* Private user code ---------------------------------------------------------*/
+
+/* USER CODE BEGIN 0 */
+
+/* USER CODE END 0 */
+
+/**
+ * @brief The application entry point.
+ * @retval int
+ */
+int main(void)
+{
+ /* USER CODE BEGIN 1 */
+
+ /**
+ * The OPTVERR flag is wrongly set at power on
+ * It shall be cleared before using any HAL_FLASH_xxx() api
+ */
+ __HAL_FLASH_CLEAR_FLAG(FLASH_FLAG_OPTVERR);
+
+ /* USER CODE END 1 */
+
+ /* MCU Configuration--------------------------------------------------------*/
+
+ /* Reset of all peripherals, Initializes the Flash interface and the Systick. */
+ HAL_Init();
+
+ /* USER CODE BEGIN Init */
+ Reset_Device();
+ Config_HSE();
+ /* USER CODE END Init */
+
+ /* Configure the system clock on HSE without using PLL and the periph clock needed by this application */
+ SystemClock_Config();
+
+ /* USER CODE BEGIN SysInit */
+ PeriphClock_Config();
+ Init_Exti();
+
+ /* USER CODE END SysInit */
+
+ /* Initialize all configured peripherals */
+ MX_DMA_Init();
+ MX_RTC_Init();
+
+ /* Init code for STM32_WPAN */
+ APPE_Init();
+
+ /* Infinite loop */
+ /* USER CODE BEGIN WHILE */
+ while (1)
+ {
+ UTIL_SEQ_Run( UTIL_SEQ_DEFAULT );
+ /* USER CODE END WHILE */
+
+ /* USER CODE END WHILE */
+ }
+ /* USER CODE BEGIN 3 */
+
+ /* USER CODE END 3 */
+}
+
+/**
+ * @brief System Clock Configuration : API to be called to use HSE (with or without PLL use) as 32Mhz system clock.
+ SystemClock_Config_HSE() must be called once just after boot (to go from default MSI to HSE).
+ Then application user can call both SystemClock_Config_HSE() and SystemClock_Config_MSI() at any time.
+ * @retval None
+ */
+void SystemClock_Config_HSE(uint32_t usePLL)
+{
+ RCC_OscInitTypeDef RCC_OscInitStruct = {0};
+ RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};
+
+ /* First, just set MSI ON (with the 32Mhz range) in case it was OFF, without any update on PLL */
+ RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_MSI;
+ RCC_OscInitStruct.MSIState = RCC_MSI_ON;
+ RCC_OscInitStruct.MSIClockRange = RCC_MSIRANGE_10;
+ RCC_OscInitStruct.MSICalibrationValue = RCC_MSICALIBRATION_DEFAULT;
+ RCC_OscInitStruct.PLL.PLLState = RCC_PLL_NONE;
+ if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
+ {
+ /* Initialization Error */
+ Error_Handler();
+ }
+ /* Select MSI as system clock in order to be able to update HSE and PLL configuration */
+ RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_SYSCLK;
+ RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_MSI;
+ if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_1) != HAL_OK)
+ {
+ /* Initialization Error */
+ Error_Handler();
+ }
+
+ /* Configure HSE and PLL if needed*/
+ RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE;
+ RCC_OscInitStruct.HSEState = RCC_HSE_ON;
+ RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE;
+ if (usePLL == 1)
+ RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
+ else
+ RCC_OscInitStruct.PLL.PLLState = RCC_PLL_OFF;
+ RCC_OscInitStruct.PLL.PLLM = RCC_PLLM_DIV2;
+ RCC_OscInitStruct.PLL.PLLN = 8;
+ RCC_OscInitStruct.PLL.PLLP = RCC_PLLP_DIV4;
+ RCC_OscInitStruct.PLL.PLLQ = RCC_PLLQ_DIV4;
+ RCC_OscInitStruct.PLL.PLLR = RCC_PLLR_DIV4;
+ if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
+ {
+ Error_Handler();
+ }
+
+ /* Configure the system clock source and the dividers according to the fact that system clock source is 32Mhz */
+ RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK4 | RCC_CLOCKTYPE_HCLK2 | RCC_CLOCKTYPE_HCLK |
+ RCC_CLOCKTYPE_SYSCLK | RCC_CLOCKTYPE_PCLK1 | RCC_CLOCKTYPE_PCLK2;
+ if (usePLL == 1)
+ RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
+ else
+ RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_HSE;
+ RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
+ RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV1;
+ RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;
+ RCC_ClkInitStruct.AHBCLK2Divider = RCC_SYSCLK_DIV1;
+ RCC_ClkInitStruct.AHBCLK4Divider = RCC_SYSCLK_DIV1;
+ if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_1) != HAL_OK)
+ {
+ Error_Handler();
+ }
+
+ // Note that function UTILS_SetFlashLatency() could be used to set the correct Flash latency
+ // (with 32Mhz, 2WS are needed if the range is changed to 1V instead of 1.2V)
+
+ /* Disable MSI Oscillator as the MSI is no more needed by the application */
+ RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_MSI;
+ RCC_OscInitStruct.MSIState = RCC_MSI_OFF;
+ RCC_OscInitStruct.PLL.PLLState = RCC_PLL_NONE; /* No update on PLL */
+ if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
+ {
+ /* Initialization Error */
+ Error_Handler();
+ }
+}
+
+/**
+ * @brief System Clock Configuration : API to be called to use MSI (with or without PLL use) as 32Mhz system clock.
+ SystemClock_Config_HSE() must be called once just after boot (to go from default MSI to HSE).
+ Then application user can call both SystemClock_Config_HSE() and SystemClock_Config_MSI() at any time.
+ * @retval None
+ */
+void SystemClock_Config_MSI(uint32_t usePLL)
+{
+ RCC_OscInitTypeDef RCC_OscInitStruct = {0};
+ RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};
+
+ /* First, just set HSE ON (with the 32Mhz range) in case it was OFF, without any update on PLL */
+ RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE;
+ RCC_OscInitStruct.HSEState = RCC_HSE_ON;
+ RCC_OscInitStruct.PLL.PLLState = RCC_PLL_NONE;
+ if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
+ {
+ /* Initialization Error */
+ Error_Handler();
+ }
+ /* Select HSE as system clock in order to be able to update MSI and PLL configuration */
+ RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_SYSCLK;
+ RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_HSE;
+ if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_1) != HAL_OK)
+ {
+ /* Initialization Error */
+ Error_Handler();
+ }
+
+ /* Configure MSI and PLL if needed*/
+ RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_MSI;
+ RCC_OscInitStruct.MSIState = RCC_MSI_ON;
+ RCC_OscInitStruct.MSIClockRange = RCC_MSIRANGE_10;
+ RCC_OscInitStruct.MSICalibrationValue = RCC_MSICALIBRATION_DEFAULT;
+ RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_MSI;
+ if (usePLL == 1)
+ RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
+ else
+ RCC_OscInitStruct.PLL.PLLState = RCC_PLL_OFF;
+ RCC_OscInitStruct.PLL.PLLM = RCC_PLLM_DIV2;
+ RCC_OscInitStruct.PLL.PLLN = 8;
+ RCC_OscInitStruct.PLL.PLLP = RCC_PLLP_DIV4;
+ RCC_OscInitStruct.PLL.PLLQ = RCC_PLLQ_DIV4;
+ RCC_OscInitStruct.PLL.PLLR = RCC_PLLR_DIV4;
+ if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
+ {
+ /* Initialization Error */
+ Error_Handler();
+ }
+
+ /* Configure the system clock source and the dividers according to the fact that system clock source is 32Mhz */
+ RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK4 | RCC_CLOCKTYPE_HCLK2 | RCC_CLOCKTYPE_HCLK |
+ RCC_CLOCKTYPE_SYSCLK | RCC_CLOCKTYPE_PCLK1 | RCC_CLOCKTYPE_PCLK2;
+ if (usePLL == 1)
+ RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
+ else
+ RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_MSI;
+ RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
+ RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV1;
+ RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;
+ RCC_ClkInitStruct.AHBCLK2Divider = RCC_SYSCLK_DIV1;
+ RCC_ClkInitStruct.AHBCLK4Divider = RCC_SYSCLK_DIV1;
+ if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_1) != HAL_OK)
+ {
+ Error_Handler();
+ }
+
+/* HSE cannot be stopped while using RF */
+#if 0
+ /* Disable HSE Oscillator as the HSE is no more needed by the application */
+ RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE;
+ RCC_OscInitStruct.HSEState = RCC_HSE_OFF;
+ RCC_OscInitStruct.PLL.PLLState = RCC_PLL_NONE; /* No update on PLL */
+ if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
+ {
+ /* Initialization Error */
+ Error_Handler();
+ }
+#endif
+}
+
+/*************************************************************
+ *
+ * LOCAL FUNCTIONS
+ *
+ *************************************************************/
+/**
+ * @brief System Clock Configuration : must be called during application start-up
+ * @retval None
+ */
+static void SystemClock_Config(void)
+{
+ RCC_OscInitTypeDef RCC_OscInitStruct = {0};
+
+ /* Configure LSE Drive Capability */
+ __HAL_RCC_LSEDRIVE_CONFIG(RCC_LSEDRIVE_LOW);
+ #ifdef STM32WB15xx
+ #else
+ /* Configure the main internal regulator output voltage */
+ __HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE1);
+ #endif
+
+ /* Assuming that MSI is enabled by default after boot, lets go to HSE without using PLL */
+ SystemClock_Config_HSE(0);
+
+ /* Configure Others clock */
+ #ifdef STM32WB15xx
+ RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI |
+ RCC_OSCILLATORTYPE_LSE | RCC_OSCILLATORTYPE_LSI2;
+ #else
+ RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI | RCC_OSCILLATORTYPE_HSI48 |
+ RCC_OSCILLATORTYPE_LSE | RCC_OSCILLATORTYPE_LSI2;
+ RCC_OscInitStruct.HSI48State = RCC_HSI48_OFF;
+ #endif
+ RCC_OscInitStruct.LSEState = RCC_LSE_ON;
+ RCC_OscInitStruct.HSIState = RCC_HSI_OFF;
+ RCC_OscInitStruct.HSICalibrationValue = RCC_HSICALIBRATION_DEFAULT;
+ RCC_OscInitStruct.LSIState = RCC_LSI_OFF;
+ RCC_OscInitStruct.LSI2CalibrationValue = 0;
+ RCC_OscInitStruct.PLL.PLLState = RCC_PLL_NONE;
+ if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
+ {
+ Error_Handler();
+ }
+}
+
+/**
+ * Enable DMA controller clock
+ */
+static void MX_DMA_Init(void)
+{
+ /* DMA controller clock enable */
+ __HAL_RCC_DMAMUX1_CLK_ENABLE();
+ __HAL_RCC_DMA1_CLK_ENABLE();
+
+ /* DMA interrupt init */
+ /* DMA1_Channel4_IRQn interrupt configuration */
+ HAL_NVIC_SetPriority(DMA1_Channel4_IRQn, 0, 0);
+ HAL_NVIC_EnableIRQ(DMA1_Channel4_IRQn);
+ /* DMA1_Channel5_IRQn interrupt configuration */
+ HAL_NVIC_SetPriority(DMA1_Channel5_IRQn, 0, 0);
+ HAL_NVIC_EnableIRQ(DMA1_Channel5_IRQn);
+}
+
+static void PeriphClock_Config(void)
+{
+ RCC_PeriphCLKInitTypeDef PeriphClkInitStruct = {0};
+
+#if USE_SMPS_ENABLED_BY_DEFAULT
+ PeriphClkInitStruct.PeriphClockSelection = RCC_PERIPHCLK_SMPS | RCC_PERIPHCLK_RFWAKEUP | RCC_PERIPHCLK_USART1 | RCC_PERIPHCLK_LPUART1;
+ PeriphClkInitStruct.Usart1ClockSelection = RCC_USART1CLKSOURCE_PCLK2;
+ PeriphClkInitStruct.Lpuart1ClockSelection = RCC_LPUART1CLKSOURCE_PCLK1;
+ PeriphClkInitStruct.RFWakeUpClockSelection = RCC_RFWKPCLKSOURCE_LSE;
+ PeriphClkInitStruct.SmpsClockSelection = RCC_SMPSCLKSOURCE_HSE;
+ PeriphClkInitStruct.SmpsDivSelection = RCC_SMPSCLKDIV_RANGE1;
+ if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInitStruct) != HAL_OK)
+ {
+ Error_Handler();
+ }
+
+ /* Initialize SMPS here like in BLE applis */
+ LL_PWR_SMPS_SetStartupCurrent(LL_PWR_SMPS_STARTUP_CURRENT_80MA);
+ LL_PWR_SMPS_SetOutputVoltageLevel(LL_PWR_SMPS_OUTPUT_VOLTAGE_1V40);
+ LL_PWR_SMPS_Enable();
+#else
+ PeriphClkInitStruct.PeriphClockSelection = RCC_PERIPHCLK_RFWAKEUP | RCC_PERIPHCLK_USART1 | RCC_PERIPHCLK_LPUART1;
+ PeriphClkInitStruct.Usart1ClockSelection = RCC_USART1CLKSOURCE_PCLK2;
+ PeriphClkInitStruct.Lpuart1ClockSelection = RCC_LPUART1CLKSOURCE_PCLK1;
+ PeriphClkInitStruct.RFWakeUpClockSelection = RCC_RFWKPCLKSOURCE_LSE;
+ if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInitStruct) != HAL_OK)
+ {
+ Error_Handler();
+ }
+#endif
+
+ return;
+}
+
+static void Config_HSE(void)
+{
+ OTP_ID0_t * p_otp;
+
+ /**
+ * Read HSE_Tuning from OTP
+ */
+ p_otp = (OTP_ID0_t *) OTP_Read(0);
+ if (p_otp)
+ {
+ LL_RCC_HSE_SetCapacitorTuning(p_otp->hse_tuning);
+ }
+
+ return;
+}
+
+
+static void Reset_Device( void )
+{
+#if ( CFG_HW_RESET_BY_FW == 1 )
+ Reset_BackupDomain();
+
+ Reset_IPCC();
+#endif
+
+ return;
+}
+
+static void Reset_IPCC( void )
+{
+ LL_AHB3_GRP1_EnableClock(LL_AHB3_GRP1_PERIPH_IPCC);
+
+ LL_C1_IPCC_ClearFlag_CHx(
+ IPCC,
+ LL_IPCC_CHANNEL_1 | LL_IPCC_CHANNEL_2 | LL_IPCC_CHANNEL_3 | LL_IPCC_CHANNEL_4
+ | LL_IPCC_CHANNEL_5 | LL_IPCC_CHANNEL_6);
+
+ LL_C2_IPCC_ClearFlag_CHx(
+ IPCC,
+ LL_IPCC_CHANNEL_1 | LL_IPCC_CHANNEL_2 | LL_IPCC_CHANNEL_3 | LL_IPCC_CHANNEL_4
+ | LL_IPCC_CHANNEL_5 | LL_IPCC_CHANNEL_6);
+
+ LL_C1_IPCC_DisableTransmitChannel(
+ IPCC,
+ LL_IPCC_CHANNEL_1 | LL_IPCC_CHANNEL_2 | LL_IPCC_CHANNEL_3 | LL_IPCC_CHANNEL_4
+ | LL_IPCC_CHANNEL_5 | LL_IPCC_CHANNEL_6);
+
+ LL_C2_IPCC_DisableTransmitChannel(
+ IPCC,
+ LL_IPCC_CHANNEL_1 | LL_IPCC_CHANNEL_2 | LL_IPCC_CHANNEL_3 | LL_IPCC_CHANNEL_4
+ | LL_IPCC_CHANNEL_5 | LL_IPCC_CHANNEL_6);
+
+ LL_C1_IPCC_DisableReceiveChannel(
+ IPCC,
+ LL_IPCC_CHANNEL_1 | LL_IPCC_CHANNEL_2 | LL_IPCC_CHANNEL_3 | LL_IPCC_CHANNEL_4
+ | LL_IPCC_CHANNEL_5 | LL_IPCC_CHANNEL_6);
+
+ LL_C2_IPCC_DisableReceiveChannel(
+ IPCC,
+ LL_IPCC_CHANNEL_1 | LL_IPCC_CHANNEL_2 | LL_IPCC_CHANNEL_3 | LL_IPCC_CHANNEL_4
+ | LL_IPCC_CHANNEL_5 | LL_IPCC_CHANNEL_6);
+
+ return;
+}
+
+static void Reset_BackupDomain( void )
+{
+ if ((LL_RCC_IsActiveFlag_PINRST() != FALSE) && (LL_RCC_IsActiveFlag_SFTRST() == FALSE))
+ {
+ HAL_PWR_EnableBkUpAccess(); /**< Enable access to the RTC registers */
+
+ /**
+ * Write twice the value to flush the APB-AHB bridge
+ * This bit shall be written in the register before writing the next one
+ */
+ HAL_PWR_EnableBkUpAccess();
+
+ __HAL_RCC_BACKUPRESET_FORCE();
+ __HAL_RCC_BACKUPRESET_RELEASE();
+ }
+
+ return;
+}
+
+static void Init_Exti( void )
+{
+ /**< Disable all wakeup interrupt on CPU1 except LPUART(25), IPCC(36), HSEM(38) */
+ LL_EXTI_DisableIT_0_31( (~0) & (~(LL_EXTI_LINE_25)) );
+ LL_EXTI_DisableIT_32_63( (~0) & (~(LL_EXTI_LINE_36 | LL_EXTI_LINE_38)) );
+
+ return;
+}
+
+/**
+ * @brief RTC Initialization Function
+ * @param None
+ * @retval None
+ */
+static void MX_RTC_Init(void)
+{
+
+ /* USER CODE BEGIN RTC_Init 0 */
+
+ /* USER CODE END RTC_Init 0 */
+
+ /* USER CODE BEGIN RTC_Init 1 */
+
+ /* USER CODE END RTC_Init 1 */
+ /** Initialize RTC Only
+ */
+ hrtc.Instance = RTC;
+ hrtc.Init.HourFormat = RTC_HOURFORMAT_24;
+ hrtc.Init.AsynchPrediv = CFG_RTC_ASYNCH_PRESCALER;
+ hrtc.Init.SynchPrediv = CFG_RTC_SYNCH_PRESCALER;
+ hrtc.Init.OutPut = RTC_OUTPUT_DISABLE;
+ hrtc.Init.OutPutPolarity = RTC_OUTPUT_POLARITY_HIGH;
+ hrtc.Init.OutPutType = RTC_OUTPUT_TYPE_OPENDRAIN;
+ hrtc.Init.OutPutRemap = RTC_OUTPUT_REMAP_NONE;
+ if (HAL_RTC_Init(&hrtc) != HAL_OK)
+ {
+ Error_Handler();
+ }
+ /* USER CODE BEGIN RTC_Init 2 */
+ /* Disable RTC registers write protection */
+ LL_RTC_DisableWriteProtection(RTC);
+
+ LL_RTC_WAKEUP_SetClock(RTC, CFG_RTC_WUCKSEL_DIVIDER);
+
+ /* Enable RTC registers write protection */
+ LL_RTC_EnableWriteProtection(RTC);
+ /* USER CODE END RTC_Init 2 */
+
+}
+
+/*************************************************************
+ *
+ * WRAP FUNCTIONS
+ *
+ *************************************************************/
+void HAL_Delay(uint32_t Delay)
+{
+ uint32_t tickstart = HAL_GetTick();
+ uint32_t wait = Delay;
+
+ /* Add a freq to guarantee minimum wait */
+ if (wait < HAL_MAX_DELAY)
+ {
+ wait += HAL_GetTickFreq();
+ }
+
+ while ((HAL_GetTick() - tickstart) < wait)
+ {
+ /************************************************************************************
+ * ENTER SLEEP MODE
+ ***********************************************************************************/
+ LL_LPM_EnableSleep( ); /**< Clear SLEEPDEEP bit of Cortex System Control Register */
+
+ /**
+ * This option is used to ensure that store operations are completed
+ */
+ #if defined ( __CC_ARM)
+ __force_stores();
+ #endif
+
+ __WFI( );
+ }
+}
+/* USER CODE END 4 */
+
+/**
+ * @brief This function is executed in case of error occurrence.
+ * @retval None
+ */
+void Error_Handler(void)
+{
+ BSP_LED_On(LED_BLUE);
+ /* USER CODE BEGIN Error_Handler */
+ /* User can add his own implementation to report the HAL error return state */
+ /* USER CODE END Error_Handler */
+}
+
+#ifdef USE_FULL_ASSERT
+/**
+ * @brief Reports the name of the source file and the source line number
+ * where the assert_param error has occurred.
+ * @param file: pointer to the source file name
+ * @param line: assert_param error line source number
+ * @retval None
+ */
+void assert_failed(uint8_t *file, uint32_t line)
+{
+ /* USER CODE BEGIN assert_failed */
+ /* User can add his own implementation to report the file name and line number,
+ tex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */
+ /* USER CODE END assert_failed */
+}
+#endif /* USE_FULL_ASSERT */
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/Projects/NUCLEO-WB15CC/Applications/BLE_LLD/BLE_LLD_Lowpower/Core/Src/standby_stm32wb15.c b/Projects/NUCLEO-WB15CC/Applications/BLE_LLD/BLE_LLD_Lowpower/Core/Src/standby_stm32wb15.c
new file mode 100644
index 000000000..a0a8b4839
--- /dev/null
+++ b/Projects/NUCLEO-WB15CC/Applications/BLE_LLD/BLE_LLD_Lowpower/Core/Src/standby_stm32wb15.c
@@ -0,0 +1,159 @@
+/* USER CODE BEGIN Header */
+/**
+ ******************************************************************************
+ * File Name : standby_stm32wb15.c
+ * Description : Application configuration file for STM32WPAN Middleware.
+ ******************************************************************************
+ * @attention
+ *
+ * <h2><center>&copy; Copyright (c) 2021 STMicroelectronics.
+ * All rights reserved.</center></h2>
+ *
+ * This software component is licensed by ST under Ultimate Liberty license
+ * SLA0044, the "License"; You may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at:
+ * www.st.com/SLA0044
+ *
+ ******************************************************************************
+ */
+/* USER CODE END Header */
+
+/* Includes ------------------------------------------------------------------*/
+#include "main.h"
+#include "app_entry.h"
+#include "app_common.h"
+#include "app_debug.h"
+
+/* Private includes ----------------------------------------------------------*/
+/* USER CODE BEGIN Includes */
+
+/* USER CODE END Includes */
+
+/* Private typedef -----------------------------------------------------------*/
+/* USER CODE BEGIN PTD */
+
+/* USER CODE END PTD */
+
+/* Private define ------------------------------------------------------------*/
+/* USER CODE BEGIN PD */
+
+/* USER CODE END PD */
+
+/* Private macro -------------------------------------------------------------*/
+/* USER CODE BEGIN PM */
+
+/* USER CODE END PM */
+
+/* Private variables ---------------------------------------------------------*/
+uint32_t backup_MSP;
+uint32_t backup_IPCC_C1MR;
+uint32_t boot_after_standby;
+extern RTC_HandleTypeDef hrtc;
+/* USER CODE BEGIN PV */
+
+/* USER CODE END PV */
+
+/* Private function prototypes -----------------------------------------------*/
+uint32_t standby_boot_mng(void);
+void standby_hw_save(void);
+void standby_hw_restore(void);
+/* USER CODE BEGIN PFP */
+void SystemClock_Config(void); // may be declared in main.h file ???
+/* USER CODE END PFP */
+
+/* Private user code ---------------------------------------------------------*/
+/* USER CODE BEGIN 0 */
+
+/* USER CODE END 0 */
+
+/*******************************************************************************
+ * This part may be updated by the user
+ ******************************************************************************/
+
+ /**
+ * @brief standby_hw_save function, saves hardware context to restore
+ * @param None
+ * @retval None
+ */
+void standby_hw_save(void)
+{
+ backup_IPCC_C1MR = READ_REG(IPCC->C1MR);
+
+ /* USER CODE BEGIN standby_hw_save */
+
+ /* USER CODE END standby_hw_save */
+ return;
+}
+
+ /**
+ * @brief standby_hw_restore function, restore and reconfigure hardware context
+ * @param None
+ * @retval None
+ */
+void standby_hw_restore(void)
+{
+ /* USER CODE BEGIN standby_hw_restore_1 */
+
+ /* USER CODE END standby_hw_restore_1 */
+
+ APPD_Init();
+
+ SystemClock_Config();
+
+ HAL_Init();
+
+ /* In this user section add MX init functions present in main.c , except MX_RTC_Init() */
+ /* USER CODE BEGIN standby_hw_restore_2 */
+
+ Init_Exti();
+ MX_GPIO_Init();
+ MX_DMA_Init();
+ MX_USART1_UART_Init();
+
+ /* USER CODE END standby_hw_restore_2 */
+
+ HW_IPCC_Init();
+ HW_IPCC_Enable();
+ WRITE_REG(IPCC->C1MR, backup_IPCC_C1MR);
+
+ HW_TS_Init(hw_ts_InitMode_Limited, &hrtc);
+
+ LL_PWR_EnableSRAM2Retention();
+
+ /* USER CODE BEGIN standby_hw_restore_3 */
+ APPE_Led_Init();
+ APPE_Button_Init();
+ /* USER CODE END standby_hw_restore_3 */
+
+ return;
+}
+
+/*******************************************************************************
+ * Do not update code from this limit.
+ ******************************************************************************/
+
+ /**
+ * @brief standby_boot_mng function, will restore MCU context if wakeup from standby
+ * @param None
+ * @retval None
+ */
+uint32_t standby_boot_mng(void)
+{
+#if ( CFG_LPM_STANDBY_SUPPORTED != 0 )
+ if( __HAL_PWR_GET_FLAG(PWR_FLAG_SB) != RESET )
+ {
+ __disable_irq( );
+
+ boot_after_standby = 1;
+ __HAL_PWR_CLEAR_FLAG(PWR_FLAG_SB);
+ }else{
+ boot_after_standby = 0;
+ }
+#else
+ boot_after_standby = 0;
+#endif
+
+ return boot_after_standby;
+}
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/Projects/NUCLEO-WB15CC/Applications/BLE_LLD/BLE_LLD_Lowpower/Core/Src/stm32_lpm_if.c b/Projects/NUCLEO-WB15CC/Applications/BLE_LLD/BLE_LLD_Lowpower/Core/Src/stm32_lpm_if.c
new file mode 100644
index 000000000..e4e8fd597
--- /dev/null
+++ b/Projects/NUCLEO-WB15CC/Applications/BLE_LLD/BLE_LLD_Lowpower/Core/Src/stm32_lpm_if.c
@@ -0,0 +1,288 @@
+ /*******************************************************************************
+ * @file stm32_lpm_if.c
+ * @author MCD Application Team
+ * @brief Low layer function to enter/exit low power modes (stop, sleep)
+ ******************************************************************************
+ * @attention
+ *
+ * <h2><center>&copy; Copyright (c) 2019 STMicroelectronics.
+ * All rights reserved.</center></h2>
+ *
+ * This software component is licensed by ST under BSD 3-Clause license,
+ * the "License"; You may not use this file except in compliance with the
+ * License. You may obtain a copy of the License at:
+ * opensource.org/licenses/BSD-3-Clause
+ *
+ ******************************************************************************
+ */
+
+/* Includes ------------------------------------------------------------------*/
+#include "stm32_lpm_if.h"
+#include "stm32_lpm.h"
+#include "app_conf.h"
+/* USER CODE BEGIN include */
+
+/* USER CODE END include */
+
+/* Exported variables --------------------------------------------------------*/
+const struct UTIL_LPM_Driver_s UTIL_PowerDriver =
+{
+ PWR_EnterSleepMode,
+ PWR_ExitSleepMode,
+
+ PWR_EnterStopMode,
+ PWR_ExitStopMode,
+
+ PWR_EnterOffMode,
+ PWR_ExitOffMode,
+};
+
+/* Private function prototypes -----------------------------------------------*/
+/* USER CODE BEGIN Private_Function_Prototypes */
+static void Switch_On_HSI( void );
+
+/* USER CODE END Private_Function_Prototypes */
+/* Private typedef -----------------------------------------------------------*/
+/* USER CODE BEGIN Private_Typedef */
+
+/* USER CODE END Private_Typedef */
+/* Private define ------------------------------------------------------------*/
+/* USER CODE BEGIN Private_Define */
+
+/* USER CODE END Private_Define */
+/* Private macro -------------------------------------------------------------*/
+/* USER CODE BEGIN Private_Macro */
+
+/* USER CODE END Private_Macro */
+/* Private variables ---------------------------------------------------------*/
+/* USER CODE BEGIN Private_Variables */
+
+/* USER CODE END Private_Variables */
+
+/**
+ * @brief Enters Low Power Off Mode
+ * @param none
+ * @retval none
+ */
+void PWR_EnterOffMode( void )
+{
+/* USER CODE BEGIN PWR_EnterOffMode */
+
+ /**
+ * The systick should be disabled for the same reason than when the device enters stop mode because
+ * at this time, the device may enter either OffMode or StopMode.
+ */
+ HAL_SuspendTick();
+
+ /************************************************************************************
+ * ENTER OFF MODE
+ ***********************************************************************************/
+ /*
+ * There is no risk to clear all the WUF here because in the current implementation, this API is called
+ * in critical section. If an interrupt occurs while in that critical section before that point,
+ * the flag is set and will be cleared here but the system will not enter Off Mode
+ * because an interrupt is pending in the NVIC. The ISR will be executed when moving out
+ * of this critical section
+ */
+ LL_PWR_ClearFlag_WU( );
+
+ LL_PWR_SetPowerMode( LL_PWR_MODE_STANDBY );
+
+ LL_LPM_EnableDeepSleep( ); /**< Set SLEEPDEEP bit of Cortex System Control Register */
+
+ /**
+ * This option is used to ensure that store operations are completed
+ */
+#if defined ( __CC_ARM)
+ __force_stores( );
+#endif
+
+ __WFI( );
+/* USER CODE END PWR_EnterOffMode */
+}
+
+/**
+ * @brief Exits Low Power Off Mode
+ * @param none
+ * @retval none
+ */
+void PWR_ExitOffMode( void )
+{
+/* USER CODE BEGIN PWR_ExitOffMode */
+
+ HAL_ResumeTick();
+
+/* USER CODE END PWR_ExitOffMode */
+}
+
+/**
+ * @brief Enters Low Power Stop Mode
+ * @note ARM exists the function when waking up
+ * @param none
+ * @retval none
+ */
+void PWR_EnterStopMode( void )
+{
+/* USER CODE BEGIN PWR_EnterStopMode */
+ /**
+ * When HAL_DBGMCU_EnableDBGStopMode() is called to keep the debugger active in Stop Mode,
+ * the systick shall be disabled otherwise the cpu may crash when moving out from stop mode
+ *
+ * When in production, the HAL_DBGMCU_EnableDBGStopMode() is not called so that the device can reach best power consumption
+ * However, the systick should be disabled anyway to avoid the case when it is about to expire at the same time the device enters
+ * stop mode ( this will abort the Stop Mode entry ).
+ */
+ HAL_SuspendTick();
+
+ /**
+ * This function is called from CRITICAL SECTION
+ */
+ while( LL_HSEM_1StepLock( HSEM, CFG_HW_RCC_SEMID ) );
+
+ if ( ! LL_HSEM_1StepLock( HSEM, CFG_HW_ENTRY_STOP_MODE_SEMID ) )
+ {
+ if( LL_PWR_IsActiveFlag_C2DS( ) )
+ {
+ /* Release ENTRY_STOP_MODE semaphore */
+ LL_HSEM_ReleaseLock( HSEM, CFG_HW_ENTRY_STOP_MODE_SEMID, 0 );
+
+ /**
+ * The switch on HSI before entering Stop Mode is required on Cut2.0
+ * It is useless from Cut2.1
+ */
+ Switch_On_HSI( );
+ }
+ }
+ else
+ {
+ /**
+ * The switch on HSI before entering Stop Mode is required on Cut2.0
+ * It is useless from Cut2.1
+ */
+ Switch_On_HSI( );
+ }
+
+ /* Release RCC semaphore */
+ LL_HSEM_ReleaseLock( HSEM, CFG_HW_RCC_SEMID, 0 );
+
+ /************************************************************************************
+ * ENTER STOP MODE
+ ***********************************************************************************/
+ LL_PWR_SetPowerMode(CFG_PWR_MODE_STOP);
+
+ LL_LPM_EnableDeepSleep( ); /**< Set SLEEPDEEP bit of Cortex System Control Register */
+
+ /**
+ * This option is used to ensure that store operations are completed
+ */
+#if defined ( __CC_ARM)
+ __force_stores( );
+#endif
+
+ __WFI();
+/* USER CODE END PWR_EnterStopMode */
+}
+
+/**
+ * @brief Exits Low Power Stop Mode
+ * @param none
+ * @retval none
+ */
+void PWR_ExitStopMode( void )
+{
+/* USER CODE BEGIN PWR_ExitStopMode */
+ /**
+ * This function is called from CRITICAL SECTION
+ */
+
+ /* Release ENTRY_STOP_MODE semaphore */
+ LL_HSEM_ReleaseLock( HSEM, CFG_HW_ENTRY_STOP_MODE_SEMID, 0 );
+
+ while( LL_HSEM_1StepLock( HSEM, CFG_HW_RCC_SEMID ) );
+// CCO : Taken from MAC project already validated in low-power
+// if(LL_RCC_GetSysClkSource( ) == LL_RCC_SYS_CLKSOURCE_STATUS_HSI)
+ if(LL_RCC_GetSysClkSource( ) != LL_RCC_SYS_CLKSOURCE_STATUS_HSE)
+ {
+ LL_RCC_HSE_Enable( );
+ while(!LL_RCC_HSE_IsReady( ));
+ LL_RCC_SetSysClkSource(LL_RCC_SYS_CLKSOURCE_HSE);
+ while (LL_RCC_GetSysClkSource( ) != LL_RCC_SYS_CLKSOURCE_STATUS_HSE);
+ }
+ else
+ {
+ /**
+ * As long as the current application is fine with HSE as system clock source,
+ * there is nothing to do here
+ */
+ }
+
+ /* Release RCC semaphore */
+ LL_HSEM_ReleaseLock( HSEM, CFG_HW_RCC_SEMID, 0 );
+
+ HAL_ResumeTick();
+
+/* USER CODE END PWR_ExitStopMode */
+}
+
+/**
+ * @brief Enters Low Power Sleep Mode
+ * @note ARM exits the function when waking up
+ * @param none
+ * @retval none
+ */
+void PWR_EnterSleepMode( void )
+{
+/* USER CODE BEGIN PWR_EnterSleepMode */
+
+ HAL_SuspendTick();
+
+ /************************************************************************************
+ * ENTER SLEEP MODE
+ ***********************************************************************************/
+ LL_LPM_EnableSleep( ); /**< Clear SLEEPDEEP bit of Cortex System Control Register */
+
+ /**
+ * This option is used to ensure that store operations are completed
+ */
+#if defined ( __CC_ARM)
+ __force_stores();
+#endif
+
+ __WFI( );
+/* USER CODE END PWR_EnterSleepMode */
+}
+
+/**
+ * @brief Exits Low Power Sleep Mode
+ * @note ARM exits the function when waking up
+ * @param none
+ * @retval none
+ */
+void PWR_ExitSleepMode( void )
+{
+/* USER CODE BEGIN PWR_ExitSleepMode */
+
+ HAL_ResumeTick();
+
+/* USER CODE END PWR_ExitSleepMode */
+}
+
+/* USER CODE BEGIN Private_Functions */
+/**
+ * @brief Switch the system clock on HSI
+ * @param none
+ * @retval none
+ */
+static void Switch_On_HSI( void )
+{
+ LL_RCC_HSI_Enable( );
+ while(!LL_RCC_HSI_IsReady( ));
+ LL_RCC_SetSysClkSource( LL_RCC_SYS_CLKSOURCE_HSI );
+ LL_RCC_SetSMPSClockSource(LL_RCC_SMPS_CLKSOURCE_HSI);
+ while (LL_RCC_GetSysClkSource( ) != LL_RCC_SYS_CLKSOURCE_STATUS_HSI);
+}
+
+/* USER CODE END Private_Functions */
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
+
diff --git a/Projects/NUCLEO-WB15CC/Applications/BLE_LLD/BLE_LLD_Lowpower/Core/Src/stm32wbxx_hal_msp.c b/Projects/NUCLEO-WB15CC/Applications/BLE_LLD/BLE_LLD_Lowpower/Core/Src/stm32wbxx_hal_msp.c
new file mode 100644
index 000000000..c789f48a8
--- /dev/null
+++ b/Projects/NUCLEO-WB15CC/Applications/BLE_LLD/BLE_LLD_Lowpower/Core/Src/stm32wbxx_hal_msp.c
@@ -0,0 +1,332 @@
+/**
+ ******************************************************************************
+ * @file stm32wbxx_hal_msp.c
+ * @author MCD Application Team
+ * @brief This file contains the HAL System and Peripheral (UARTs) MSP initialization
+ * and de-initialization functions.
+ ******************************************************************************
+ * @attention
+ *
+ * <h2><center>&copy; Copyright (c) 2019 STMicroelectronics.
+ * All rights reserved.</center></h2>
+ *
+ * This software component is licensed by ST under BSD 3-Clause license,
+ * the "License"; You may not use this file except in compliance with the
+ * License. You may obtain a copy of the License at:
+ * opensource.org/licenses/BSD-3-Clause
+ *
+ ******************************************************************************
+ */
+
+/* Includes ------------------------------------------------------------------*/
+#include "stm32wbxx_hal.h"
+#include "app_common.h"
+#include "gpio_lld.h"
+
+/** @addtogroup STM32WBxx_HAL_Driver
+ * @{
+ */
+
+/** @defgroup HAL_MSP HAL MSP
+ * @brief HAL MSP module.
+ * @{
+ */
+
+/* Private typedef -----------------------------------------------------------*/
+/* Private define ------------------------------------------------------------*/
+/* Private macro -------------------------------------------------------------*/
+/* Private variables ---------------------------------------------------------*/
+/* Private function prototypes -----------------------------------------------*/
+/* Private functions ---------------------------------------------------------*/
+
+/** @defgroup HAL_MSP_Private_Functions HAL MSP Private Functions
+ * @{
+ */
+
+/**
+ * @brief Initializes the Global MSP.
+ * @note This function is called from HAL_Init() function to perform system
+ * level initialization (GPIOs, clock, DMA, interrupt).
+ * @retval None
+ */
+void HAL_MspInit(void)
+{
+
+}
+
+/**
+ * @brief DeInitializes the Global MSP.
+ * @note This functiona is called from HAL_DeInit() function to perform system
+ * level de-initialization (GPIOs, clock, DMA, interrupt).
+ * @retval None
+ */
+void HAL_MspDeInit(void)
+{
+
+}
+
+/**
+ * @brief UART MSP Initialization
+ * This function configures the hardware resources used in this example
+ * @param huart: UART handle pointer
+ * @retval None
+ */
+void HAL_UART_MspInit(UART_HandleTypeDef* huart)
+{
+ HAL_DMA_MuxSyncConfigTypeDef pSyncConfig;
+
+#if (CFG_HW_LPUART1_ENABLED == 1)
+ if(huart->Instance == LPUART1)
+ {
+ /* USER CODE BEGIN LPUART1_MspInit 0 */
+
+ /* USER CODE END LPUART1_MspInit 0 */
+
+ /* GPIOs configuration */
+ #if(CFG_DEBUG_TRACE != 0)
+ gpio_lld_lpuart_init();
+ #endif
+
+
+ /* LPUART1 DMA Init */
+ /* LPUART1_TX Init */
+ hdma_lpuart1_tx.Instance = DMA1_Channel4;
+ hdma_lpuart1_tx.Init.Request = DMA_REQUEST_LPUART1_TX;
+ hdma_lpuart1_tx.Init.Direction = DMA_MEMORY_TO_PERIPH;
+ hdma_lpuart1_tx.Init.PeriphInc = DMA_PINC_DISABLE;
+ hdma_lpuart1_tx.Init.MemInc = DMA_MINC_ENABLE;
+ hdma_lpuart1_tx.Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE;
+ hdma_lpuart1_tx.Init.MemDataAlignment = DMA_MDATAALIGN_BYTE;
+ hdma_lpuart1_tx.Init.Mode = DMA_NORMAL;
+ hdma_lpuart1_tx.Init.Priority = DMA_PRIORITY_LOW;
+ if (HAL_DMA_Init(&hdma_lpuart1_tx) != HAL_OK)
+ {
+ Error_Handler();
+ }
+
+ pSyncConfig.SyncSignalID = HAL_DMAMUX1_SYNC_DMAMUX1_CH1_EVT;
+ pSyncConfig.SyncPolarity = HAL_DMAMUX_SYNC_NO_EVENT;
+ pSyncConfig.SyncEnable = DISABLE;
+ pSyncConfig.EventEnable = DISABLE;
+ pSyncConfig.RequestNumber = 1;
+ if (HAL_DMAEx_ConfigMuxSync(&hdma_lpuart1_tx, &pSyncConfig) != HAL_OK)
+ {
+ Error_Handler();
+ }
+
+ __HAL_LINKDMA(huart,hdmatx,hdma_lpuart1_tx);
+
+ /* LPUART1 interrupt Init */
+ HAL_NVIC_SetPriority(LPUART1_IRQn, 0, 0);
+ HAL_NVIC_EnableIRQ(LPUART1_IRQn);
+ /* USER CODE BEGIN LPUART1_MspInit 1 */
+
+ /* USER CODE END LPUART1_MspInit 1 */
+ }
+#endif
+#if (CFG_HW_USART1_ENABLED == 1)
+ if(huart->Instance == USART1)
+ {
+ /* USER CODE BEGIN USART1_MspInit 0 */
+
+ /* USER CODE END USART1_MspInit 0 */
+ /* Peripheral clock enable */
+ __HAL_RCC_USART1_CLK_ENABLE();
+
+ /* GPIOs configuration */
+ #if(CFG_DEBUG_TRACE != 0)
+ gpio_lld_usart_init();
+ #endif
+
+
+ /* USART1 DMA Init */
+ /* USART1_TX Init */
+ hdma_usart1_tx.Instance = DMA1_Channel5;
+ hdma_usart1_tx.Init.Request = DMA_REQUEST_USART1_TX;
+ hdma_usart1_tx.Init.Direction = DMA_MEMORY_TO_PERIPH;
+ hdma_usart1_tx.Init.PeriphInc = DMA_PINC_DISABLE;
+ hdma_usart1_tx.Init.MemInc = DMA_MINC_ENABLE;
+ hdma_usart1_tx.Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE;
+ hdma_usart1_tx.Init.MemDataAlignment = DMA_MDATAALIGN_BYTE;
+ hdma_usart1_tx.Init.Mode = DMA_NORMAL;
+ hdma_usart1_tx.Init.Priority = DMA_PRIORITY_LOW;
+ if (HAL_DMA_Init(&hdma_usart1_tx) != HAL_OK)
+ {
+ Error_Handler();
+ }
+
+ __HAL_LINKDMA(huart,hdmatx,hdma_usart1_tx);
+
+ /* USART1 interrupt Init */
+ HAL_NVIC_SetPriority(USART1_IRQn, 0, 0);
+ HAL_NVIC_EnableIRQ(USART1_IRQn);
+ /* USER CODE BEGIN USART1_MspInit 1 */
+
+ /* USER CODE END USART1_MspInit 1 */
+ }
+#endif
+}
+
+/**
+ * @brief UART MSP De-Initialization
+ * This function freeze the hardware resources used in this example
+ * @param huart: UART handle pointer
+ * @retval None
+ */
+void HAL_UART_MspDeInit(UART_HandleTypeDef* huart)
+{
+#if (CFG_HW_LPUART1_ENABLED == 1)
+ if(huart->Instance == LPUART1)
+ {
+ /* USER CODE BEGIN LPUART1_MspDeInit 0 */
+
+ /* USER CODE END LPUART1_MspDeInit 0 */
+ /* Peripheral clock disable */
+ __HAL_RCC_LPUART1_CLK_DISABLE();
+
+ /* De-init GPIOs */
+ gpio_lld_lpuart_deInit();
+
+ /* LPUART1 DMA DeInit */
+ HAL_DMA_DeInit(huart->hdmatx);
+
+ /* LPUART1 interrupt DeInit */
+ HAL_NVIC_DisableIRQ(LPUART1_IRQn);
+ /* USER CODE BEGIN LPUART1_MspDeInit 1 */
+
+ /* USER CODE END LPUART1_MspDeInit 1 */
+ }
+#endif
+#if (CFG_HW_USART1_ENABLED == 1)
+ if(huart->Instance == USART1)
+ {
+ /* USER CODE BEGIN USART1_MspDeInit 0 */
+
+ /* USER CODE END USART1_MspDeInit 0 */
+ /* Peripheral clock disable */
+ __HAL_RCC_USART1_CLK_DISABLE();
+
+ /* De-init GPIOs */
+ gpio_lld_usart_deInit();
+
+
+ /* USART1 DMA DeInit */
+ HAL_DMA_DeInit(huart->hdmatx);
+
+ /* USART1 interrupt DeInit */
+ HAL_NVIC_DisableIRQ(USART1_IRQn);
+ /* USER CODE BEGIN USART1_MspDeInit 1 */
+
+ /* USER CODE END USART1_MspDeInit 1 */
+ }
+#endif
+}
+
+/**
+ * @}
+ */
+/**
+* @brief TIM_Base MSP Initialization
+* This function configures the hardware resources used in this example
+* @param htim_base: TIM_Base handle pointer
+* @retval None
+*/
+void HAL_TIM_Base_MspInit(TIM_HandleTypeDef* htim_base)
+{
+ if(htim_base->Instance==TIM2)
+ {
+ /* USER CODE BEGIN TIM2_MspInit 0 */
+
+ /* USER CODE END TIM2_MspInit 0 */
+ /* Peripheral clock enable */
+ __HAL_RCC_TIM2_CLK_ENABLE();
+ /* TIM2 interrupt Init */
+ HAL_NVIC_SetPriority(TIM2_IRQn, 3, 0);
+ HAL_NVIC_EnableIRQ(TIM2_IRQn);
+ /* USER CODE BEGIN TIM2_MspInit 1 */
+
+ /* USER CODE END TIM2_MspInit 1 */
+ }
+
+}
+
+/**
+* @brief TIM_Base MSP De-Initialization
+* This function freeze the hardware resources used in this example
+* @param htim_base: TIM_Base handle pointer
+* @retval None
+*/
+void HAL_TIM_Base_MspDeInit(TIM_HandleTypeDef* htim_base)
+{
+ if(htim_base->Instance==TIM2)
+ {
+ /* USER CODE BEGIN TIM2_MspDeInit 0 */
+
+ /* USER CODE END TIM2_MspDeInit 0 */
+ /* Peripheral clock disable */
+ __HAL_RCC_TIM2_CLK_DISABLE();
+
+ /* TIM2 interrupt DeInit */
+ HAL_NVIC_DisableIRQ(TIM2_IRQn);
+ /* USER CODE BEGIN TIM2_MspDeInit 1 */
+
+ /* USER CODE END TIM2_MspDeInit 1 */
+ }
+
+}
+
+/**
+* @brief RTC MSP Initialization
+* This function configures the hardware resources used in this example
+* @param hrtc: RTC handle pointer
+* @retval None
+*/
+void HAL_RTC_MspInit(RTC_HandleTypeDef* hrtc)
+{
+ if(hrtc->Instance==RTC)
+ {
+ /* USER CODE BEGIN RTC_MspInit 0 */
+ HAL_PWR_EnableBkUpAccess(); /**< Enable access to the RTC registers */
+
+ /**
+ * Write twice the value to flush the APB-AHB bridge
+ * This bit shall be written in the register before writing the next one
+ */
+ HAL_PWR_EnableBkUpAccess();
+
+ __HAL_RCC_RTC_CONFIG(RCC_RTCCLKSOURCE_LSE); /**< Select LSI as RTC Input */
+ /* USER CODE END RTC_MspInit 0 */
+ /* Peripheral clock enable */
+ __HAL_RCC_RTC_ENABLE();
+ __HAL_RCC_RTCAPB_CLK_ENABLE();
+ /* USER CODE BEGIN RTC_MspInit 1 */
+ HAL_RTCEx_EnableBypassShadow(hrtc);
+ /* USER CODE END RTC_MspInit 1 */
+ }
+
+}
+
+/**
+* @brief RTC MSP De-Initialization
+* This function freeze the hardware resources used in this example
+* @param hrtc: RTC handle pointer
+* @retval None
+*/
+void HAL_RTC_MspDeInit(RTC_HandleTypeDef* hrtc)
+{
+ if(hrtc->Instance==RTC)
+ {
+ /* USER CODE BEGIN RTC_MspDeInit 0 */
+
+ /* USER CODE END RTC_MspDeInit 0 */
+ /* Peripheral clock disable */
+ __HAL_RCC_RTC_DISABLE();
+ __HAL_RCC_RTCAPB_CLK_DISABLE();
+ /* USER CODE BEGIN RTC_MspDeInit 1 */
+
+ /* USER CODE END RTC_MspDeInit 1 */
+ }
+
+}
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/Projects/NUCLEO-WB15CC/Applications/BLE_LLD/BLE_LLD_Lowpower/Core/Src/stm32wbxx_it.c b/Projects/NUCLEO-WB15CC/Applications/BLE_LLD/BLE_LLD_Lowpower/Core/Src/stm32wbxx_it.c
new file mode 100644
index 000000000..09fb8f08f
--- /dev/null
+++ b/Projects/NUCLEO-WB15CC/Applications/BLE_LLD/BLE_LLD_Lowpower/Core/Src/stm32wbxx_it.c
@@ -0,0 +1,323 @@
+/* USER CODE BEGIN Header */
+/**
+ ******************************************************************************
+ * @file stm32wbxx_it.c
+ * @brief Interrupt Service Routines.
+ *******************************************************************************
+ * @attention
+ *
+ * <h2><center>&copy; Copyright (c) 2019 STMicroelectronics.
+ * All rights reserved.</center></h2>
+ *
+ * This software component is licensed by ST under Ultimate Liberty license
+ * SLA0044, the "License"; You may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at:
+ * www.st.com/SLA0044
+ *
+ ******************************************************************************
+ */
+/* USER CODE END Header */
+
+/* Includes ------------------------------------------------------------------*/
+#include "app_common.h"
+#include "stm32wbxx_it.h"
+#include "gpio_lld.h"
+
+/* Private includes ----------------------------------------------------------*/
+/* USER CODE BEGIN Includes */
+
+/* USER CODE END Includes */
+
+/* Private typedef -----------------------------------------------------------*/
+/* USER CODE BEGIN TD */
+
+/* USER CODE END TD */
+
+/* Private define ------------------------------------------------------------*/
+/* USER CODE BEGIN PD */
+
+/* USER CODE END PD */
+
+/* Private macro -------------------------------------------------------------*/
+/* USER CODE BEGIN PM */
+
+/* USER CODE END PM */
+
+/* Private variables ---------------------------------------------------------*/
+/* USER CODE BEGIN PV */
+
+/* USER CODE END PV */
+
+/* Private function prototypes -----------------------------------------------*/
+/* USER CODE BEGIN PFP */
+
+/* USER CODE END PFP */
+
+/* Private user code ---------------------------------------------------------*/
+/* USER CODE BEGIN 0 */
+
+/* USER CODE END 0 */
+
+/* External variables --------------------------------------------------------*/
+/* USER CODE BEGIN EV */
+
+/* USER CODE END EV */
+
+/******************************************************************************/
+/* Cortex Processor Interruption and Exception Handlers */
+/******************************************************************************/
+/**
+ * @brief This function handles Non maskable interrupt.
+ */
+void NMI_Handler(void)
+{
+ /* USER CODE BEGIN NonMaskableInt_IRQn 0 */
+
+ /* USER CODE END NonMaskableInt_IRQn 0 */
+ /* USER CODE BEGIN NonMaskableInt_IRQn 1 */
+
+ /* USER CODE END NonMaskableInt_IRQn 1 */
+}
+
+/**
+ * @brief This function handles Hard fault interrupt.
+ */
+void HardFault_Handler(void)
+{
+ /* USER CODE BEGIN HardFault_IRQn 0 */
+ gpio_lld_phy_gpioHardFault_up();
+
+ /* USER CODE END HardFault_IRQn 0 */
+ while (1)
+ {
+ /* USER CODE BEGIN W1_HardFault_IRQn 0 */
+ /* USER CODE END W1_HardFault_IRQn 0 */
+ }
+}
+
+/**
+ * @brief This function handles Memory management fault.
+ */
+void MemManage_Handler(void)
+{
+ /* USER CODE BEGIN MemoryManagement_IRQn 0 */
+
+ /* USER CODE END MemoryManagement_IRQn 0 */
+ while (1)
+ {
+ /* USER CODE BEGIN W1_MemoryManagement_IRQn 0 */
+ /* USER CODE END W1_MemoryManagement_IRQn 0 */
+ }
+}
+
+/**
+ * @brief This function handles Prefetch fault, memory access fault.
+ */
+void BusFault_Handler(void)
+{
+ /* USER CODE BEGIN BusFault_IRQn 0 */
+
+ /* USER CODE END BusFault_IRQn 0 */
+ while (1)
+ {
+ /* USER CODE BEGIN W1_BusFault_IRQn 0 */
+ /* USER CODE END W1_BusFault_IRQn 0 */
+ }
+}
+
+/**
+ * @brief This function handles Undefined instruction or illegal state.
+ */
+void UsageFault_Handler(void)
+{
+ /* USER CODE BEGIN UsageFault_IRQn 0 */
+
+ /* USER CODE END UsageFault_IRQn 0 */
+ while (1)
+ {
+ /* USER CODE BEGIN W1_UsageFault_IRQn 0 */
+ /* USER CODE END W1_UsageFault_IRQn 0 */
+ }
+}
+
+/**
+ * @brief This function handles System service call via SWI instruction.
+ */
+void SVC_Handler(void)
+{
+ /* USER CODE BEGIN SVCall_IRQn 0 */
+
+ /* USER CODE END SVCall_IRQn 0 */
+ /* USER CODE BEGIN SVCall_IRQn 1 */
+
+ /* USER CODE END SVCall_IRQn 1 */
+}
+
+/**
+ * @brief This function handles Debug monitor.
+ */
+void DebugMon_Handler(void)
+{
+ /* USER CODE BEGIN DebugMonitor_IRQn 0 */
+
+ /* USER CODE END DebugMonitor_IRQn 0 */
+ /* USER CODE BEGIN DebugMonitor_IRQn 1 */
+
+ /* USER CODE END DebugMonitor_IRQn 1 */
+}
+
+/**
+ * @brief This function handles Pendable request for system service.
+ */
+void PendSV_Handler(void)
+{
+ /* USER CODE BEGIN PendSV_IRQn 0 */
+
+ /* USER CODE END PendSV_IRQn 0 */
+ /* USER CODE BEGIN PendSV_IRQn 1 */
+
+ /* USER CODE END PendSV_IRQn 1 */
+}
+
+/**
+ * @brief This function handles System tick timer.
+ */
+void SysTick_Handler(void)
+{
+ /* USER CODE BEGIN SysTick_IRQn 0 */
+
+ /* USER CODE END SysTick_IRQn 0 */
+ HAL_IncTick();
+ /* USER CODE BEGIN SysTick_IRQn 1 */
+
+ /* USER CODE END SysTick_IRQn 1 */
+}
+
+/******************************************************************************/
+/* STM32WBxx Peripheral Interrupt Handlers */
+/* Add here the Interrupt Handlers for the used peripherals. */
+/* For the available peripheral interrupt handler names, */
+/* please refer to the startup file (startup_stm32wbxx.s). */
+/******************************************************************************/
+/**
+ * @brief This function handles DMA1 channel4 global interrupt.
+ */
+void DMA1_Channel4_IRQHandler(void)
+{
+ /* USER CODE BEGIN DMA1_Channel4_IRQn 0 */
+
+ /* USER CODE END DMA1_Channel4_IRQn 0 */
+#if (CFG_HW_LPUART1_ENABLED == 1)
+#if (CFG_HW_LPUART1_DMA_TX_SUPPORTED == 1)
+ HAL_DMA_IRQHandler(&hdma_lpuart1_tx);
+#endif
+#endif
+ /* USER CODE BEGIN DMA1_Channel4_IRQn 1 */
+
+ /* USER CODE END DMA1_Channel4_IRQn 1 */
+}
+
+/**
+ * @brief This function handles DMA2 channel4 global interrupt.
+ */
+void DMA1_Channel5_IRQHandler(void)
+{
+ /* USER CODE BEGIN DMA1_Channel5_IRQn 0 */
+
+ /* USER CODE END DMA1_Channel5_IRQn 0 */
+#if (CFG_HW_USART1_ENABLED == 1)
+#if (CFG_HW_USART1_DMA_TX_SUPPORTED == 1)
+ HAL_DMA_IRQHandler(&hdma_usart1_tx);
+#endif
+#endif
+ /* USER CODE BEGIN DMA1_Channel5_IRQn 1 */
+
+ /* USER CODE END DMA1_Channel5_IRQn 1 */
+}
+
+/**
+ * @brief This function handles USART1 global interrupt.
+ */
+void USART1_IRQHandler(void)
+{
+ /* USER CODE BEGIN USART1_IRQn 0 */
+
+ /* USER CODE END USART1_IRQn 0 */
+#if (CFG_HW_USART1_ENABLED == 1)
+ HAL_UART_IRQHandler(&huart1);
+#endif
+ /* USER CODE BEGIN USART1_IRQn 1 */
+
+ /* USER CODE END USART1_IRQn 1 */
+}
+
+/**
+ * @brief This function handles LPUART1 global interrupt.
+ */
+void LPUART1_IRQHandler(void)
+{
+ /* USER CODE BEGIN LPUART1_IRQn 0 */
+
+ /* USER CODE END LPUART1_IRQn 0 */
+#if (CFG_HW_LPUART1_ENABLED == 1)
+ HAL_UART_IRQHandler(&hlpuart1);
+#endif
+ /* USER CODE BEGIN LPUART1_IRQn 1 */
+
+ /* USER CODE END LPUART1_IRQn 1 */
+}
+
+/* USER CODE BEGIN 1 */
+/**
+ * @brief This function handles External line
+ * interrupt request.
+ * @param None
+ * @retval None
+ */
+void BUTTON_SW1_EXTI_IRQHandler(void)
+{
+ HAL_GPIO_EXTI_IRQHandler(BUTTON_SW1_PIN);
+}
+
+/**
+ * @brief This function handles External line
+ * interrupt request.
+ * @param None
+ * @retval None
+ */
+void BUTTON_SW2_EXTI_IRQHandler(void)
+{
+ HAL_GPIO_EXTI_IRQHandler(BUTTON_SW2_PIN);
+}
+
+/**
+ * @brief This function handles External line
+ * interrupt request.
+ * @param None
+ * @retval None
+ */
+void BUTTON_SW3_EXTI_IRQHandler(void)
+{
+ HAL_GPIO_EXTI_IRQHandler(BUTTON_SW3_PIN);
+}
+
+void RTC_WKUP_IRQHandler(void)
+{
+ HW_TS_RTC_Wakeup_Handler();
+}
+
+void IPCC_C1_TX_IRQHandler(void)
+{
+ HW_IPCC_Tx_Handler();
+
+ return;
+}
+
+void IPCC_C1_RX_IRQHandler(void)
+{
+ HW_IPCC_Rx_Handler();
+ return;
+}
+
+/* USER CODE END 1 */
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/Projects/NUCLEO-WB15CC/Applications/BLE_LLD/BLE_LLD_Lowpower/Core/Src/stm_logging.c b/Projects/NUCLEO-WB15CC/Applications/BLE_LLD/BLE_LLD_Lowpower/Core/Src/stm_logging.c
new file mode 100644
index 000000000..40997ccd7
--- /dev/null
+++ b/Projects/NUCLEO-WB15CC/Applications/BLE_LLD/BLE_LLD_Lowpower/Core/Src/stm_logging.c
@@ -0,0 +1,213 @@
+/* USER CODE BEGIN Header */
+/**
+ ******************************************************************************
+ * File Name : stm_logging.c
+ * Description : This file contains all the defines and functions used
+ * for logging on Application examples.
+ *
+ ******************************************************************************
+ * @attention
+ *
+ * <h2><center>&copy; Copyright (c) 2021 STMicroelectronics.
+ * All rights reserved.</center></h2>
+ *
+ * This software component is licensed by ST under Ultimate Liberty license
+ * SLA0044, the "License"; You may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at:
+ * www.st.com/SLA0044
+ *
+ ******************************************************************************
+ */
+/* USER CODE END Header */
+
+/**
+ * @file
+ * This file implements logging functions to be used in Application examples.
+ *
+ */
+
+#include <ctype.h>
+#include <inttypes.h>
+#include <stdarg.h>
+#include <stdio.h>
+#include <stdint.h>
+#include <string.h>
+
+#include "app_conf.h"
+#include "stm_logging.h"
+
+#define LOG_PARSE_BUFFER_SIZE 256U
+
+#define LOG_TIMESTAMP_ENABLE 0
+#define LOG_REGION_ENABLE 1U
+#define LOG_RTT_COLOR_ENABLE 1U
+
+#if (LOG_RTT_COLOR_ENABLE == 1U)
+#define RTT_COLOR_CODE_DEFAULT "\x1b[0m"
+#define RTT_COLOR_CODE_RED "\x1b[0;91m"
+#define RTT_COLOR_CODE_GREEN "\x1b[0;92m"
+#define RTT_COLOR_CODE_YELLOW "\x1b[0;93m"
+#define RTT_COLOR_CODE_CYAN "\x1b[0;96m"
+
+#else /* LOG_RTT_COLOR_ENABLE == 1 */
+#define RTT_COLOR_CODE_DEFAULT ""
+#define RTT_COLOR_CODE_RED ""
+#define RTT_COLOR_CODE_GREEN ""
+#define RTT_COLOR_CODE_YELLOW ""
+#define RTT_COLOR_CODE_CYAN ""
+#endif /* LOG_RTT_COLOR_ENABLE == 1 */
+
+#if (CFG_DEBUG_TRACE != 0)
+/**
+ * Function for outputting code region string.
+ *
+ * @param[inout] aLogString Pointer to log buffer.
+ * @param[in] aMaxSize Maximum size of log buffer.
+ * @param[in] otLogRegion The region ID.
+ *
+ * @returns String with a log level color value.
+ */
+static inline uint16_t logRegion(char *aLogString, uint16_t aMaxSize,
+ appliLogRegion_t aLogRegion)
+{
+ char logRegionString[30U];
+
+ switch (aLogRegion)
+ {
+ case APPLI_LOG_REGION_GENERAL:
+ strcpy(logRegionString, "[M4 APPLICATION]");
+ break;
+ case APPLI_LOG_REGION_OPENTHREAD_API:
+ strcpy(logRegionString, "[M4 OPENTHREAD API]");
+ break;
+ case APPLI_LOG_REGION_OT_API_LINK:
+ strcpy(logRegionString, "[M4 LINK API]");
+ break;
+ case APPLI_LOG_REGION_OT_API_INSTANCE:
+ strcpy(logRegionString, "[M4 INSTANCE API]");
+ break;
+ case APPLI_LOG_REGION_OT_API_MESSAGE:
+ strcpy(logRegionString, "[M4 MESSAGE API]");
+ break;
+ default:
+ strcpy(logRegionString, "[M4]");
+ break;
+ }
+
+ return snprintf(aLogString, aMaxSize, "%s ", logRegionString);
+}
+#endif /* CFG_DEBUG_TRACE */
+
+#if (LOG_RTT_COLOR_ENABLE == 1U)
+#if (CFG_DEBUG_TRACE != 0)
+/**
+ * Function for getting color of a given level log.
+ *
+ * @param[in] aLogLevel The log level.
+ *
+ * @returns String with a log level color value.
+ */
+static inline const char *levelToString(appliLogLevel_t aLogLevel)
+{
+ switch (aLogLevel)
+ {
+ case LOG_LEVEL_CRIT:
+ return RTT_COLOR_CODE_RED;
+
+ case LOG_LEVEL_WARN:
+ return RTT_COLOR_CODE_YELLOW;
+
+ case LOG_LEVEL_INFO:
+ return RTT_COLOR_CODE_GREEN;
+
+ case LOG_LEVEL_DEBG:
+ default:
+ return RTT_COLOR_CODE_DEFAULT;
+ }
+}
+#endif /* CFG_DEBUG_TRACE */
+
+#if (CFG_DEBUG_TRACE != 0)
+/**
+ * Function for printing log level.
+ *
+ * @param[inout] aLogString Pointer to log buffer.
+ * @param[in] aMaxSize Maximum size of log buffer.
+ * @param[in] aLogLevel Log level.
+ *
+ * @returns Number of bytes successfully written to the log buffer.
+ */
+static inline uint16_t logLevel(char *aLogString, uint16_t aMaxSize,
+ appliLogLevel_t aLogLevel)
+{
+ return snprintf(aLogString, aMaxSize, "%s", levelToString(aLogLevel));
+}
+#endif /* CFG_DEBUG_TRACE */
+#endif /* LOG_RTT_COLOR_ENABLE */
+
+#if (LOG_TIMESTAMP_ENABLE == 1U)
+/**
+ * Function for printing actual timestamp.
+ *
+ * @param[inout] aLogString Pointer to the log buffer.
+ * @param[in] aMaxSize Maximum size of the log buffer.
+ *
+ * @returns Number of bytes successfully written to the log buffer.
+ */
+static inline uint16_t logTimestamp(char *aLogString, uint16_t aMaxSize)
+{
+ return snprintf(aLogString, aMaxSize, "%s[%010ld]", RTT_COLOR_CODE_DEFAULT,
+ otPlatAlarmMilliGetNow());
+}
+#endif /* LOG_TIMESTAMP_ENABLE */
+
+/**
+ * Function for printing application log
+ *
+ * @param[in] aLogLevel Log level.
+ * @param[in] aLogRegion The region ID.
+ * @param[in] aFormat User string format.
+ *
+ * @returns Number of bytes successfully written to the log buffer.
+ */
+void logApplication(appliLogLevel_t aLogLevel, appliLogRegion_t aLogRegion, const char *aFormat, ...)
+{
+#if (CFG_DEBUG_TRACE != 0) /* Since the traces are disabled, there is nothing to print */
+ uint16_t length = 0;
+ char logString[LOG_PARSE_BUFFER_SIZE + 1U];
+
+#if (LOG_TIMESTAMP_ENABLE == 1U)
+ length += logTimestamp(logString, LOG_PARSE_BUFFER_SIZE);
+#endif
+
+#if (LOG_RTT_COLOR_ENABLE == 1U)
+ /* Add level information */
+ length += logLevel(&logString[length], (LOG_PARSE_BUFFER_SIZE - length),
+ aLogLevel);
+#endif
+
+#if (LOG_REGION_ENABLE == 1U)
+ /* Add Region information */
+ length += logRegion(&logString[length], (LOG_PARSE_BUFFER_SIZE - length),
+ aLogRegion);
+#endif
+
+ /* Parse user string */
+ va_list paramList;
+ va_start(paramList, aFormat);
+ length += vsnprintf(&logString[length], (LOG_PARSE_BUFFER_SIZE - length),
+ aFormat, paramList);
+ logString[length++] = '\r';
+ logString[length++] = '\n';
+ logString[length++] = 0;
+ va_end(paramList);
+
+ if (aLogLevel <= APPLI_CONFIG_LOG_LEVEL)
+ {
+ printf("%s", logString);
+ }else
+ {
+ /* Print nothing */
+ }
+#endif /* CFG_DEBUG_TRACE */
+}
diff --git a/Projects/NUCLEO-WB15CC/Applications/BLE_LLD/BLE_LLD_Lowpower/Core/Src/system_stm32wbxx.c b/Projects/NUCLEO-WB15CC/Applications/BLE_LLD/BLE_LLD_Lowpower/Core/Src/system_stm32wbxx.c
new file mode 100644
index 000000000..791008e1d
--- /dev/null
+++ b/Projects/NUCLEO-WB15CC/Applications/BLE_LLD/BLE_LLD_Lowpower/Core/Src/system_stm32wbxx.c
@@ -0,0 +1,355 @@
+/**
+ ******************************************************************************
+ * @file system_stm32wbxx.c
+ * @author MCD Application Team
+ * @brief CMSIS Cortex Device Peripheral Access Layer System Source File
+ *
+ * This file provides two functions and one global variable to be called from
+ * user application:
+ * - SystemInit(): This function is called at startup just after reset and
+ * before branch to main program. This call is made inside
+ * the "startup_stm32wbxx.s" file.
+ *
+ * - SystemCoreClock variable: Contains the core clock (HCLK), it can be used
+ * by the user application to setup the SysTick
+ * timer or configure other parameters.
+ *
+ * - SystemCoreClockUpdate(): Updates the variable SystemCoreClock and must
+ * be called whenever the core clock is changed
+ * during program execution.
+ *
+ * After each device reset the MSI (4 MHz) is used as system clock source.
+ * Then SystemInit() function is called, in "startup_stm32wbxx.s" file, to
+ * configure the system clock before to branch to main program.
+ *
+ * This file configures the system clock as follows:
+ *=============================================================================
+ *-----------------------------------------------------------------------------
+ * System Clock source | MSI
+ *-----------------------------------------------------------------------------
+ * SYSCLK(Hz) | 4000000
+ *-----------------------------------------------------------------------------
+ * HCLK(Hz) | 4000000
+ *-----------------------------------------------------------------------------
+ * AHB Prescaler | 1
+ *-----------------------------------------------------------------------------
+ * APB1 Prescaler | 1
+ *-----------------------------------------------------------------------------
+ * APB2 Prescaler | 1
+ *-----------------------------------------------------------------------------
+ * PLL_M | 1
+ *-----------------------------------------------------------------------------
+ * PLL_N | 8
+ *-----------------------------------------------------------------------------
+ * PLL_P | 7
+ *-----------------------------------------------------------------------------
+ * PLL_Q | 2
+ *-----------------------------------------------------------------------------
+ * PLL_R | 2
+ *-----------------------------------------------------------------------------
+ * PLLSAI1_P | NA
+ *-----------------------------------------------------------------------------
+ * PLLSAI1_Q | NA
+ *-----------------------------------------------------------------------------
+ * PLLSAI1_R | NA
+ *-----------------------------------------------------------------------------
+ * Require 48MHz for USB OTG FS, | Disabled
+ * SDIO and RNG clock |
+ *-----------------------------------------------------------------------------
+ *=============================================================================
+ ******************************************************************************
+ * @attention
+ *
+ * <h2><center>&copy; Copyright (c) 2019 STMicroelectronics.
+ * All rights reserved.</center></h2>
+ *
+ * This software component is licensed by ST under Apache License, Version 2.0,
+ * the "License"; You may not use this file except in compliance with the
+ * License. You may obtain a copy of the License at:
+ * opensource.org/licenses/Apache-2.0
+ *
+ ******************************************************************************
+ */
+
+/** @addtogroup CMSIS
+ * @{
+ */
+
+/** @addtogroup stm32WBxx_system
+ * @{
+ */
+
+/** @addtogroup stm32WBxx_System_Private_Includes
+ * @{
+ */
+
+#include "stm32wbxx.h"
+
+#if !defined (HSE_VALUE)
+ #define HSE_VALUE (32000000UL) /*!< Value of the External oscillator in Hz */
+#endif /* HSE_VALUE */
+
+#if !defined (MSI_VALUE)
+ #define MSI_VALUE (4000000UL) /*!< Value of the Internal oscillator in Hz*/
+#endif /* MSI_VALUE */
+
+#if !defined (HSI_VALUE)
+ #define HSI_VALUE (16000000UL) /*!< Value of the Internal oscillator in Hz*/
+#endif /* HSI_VALUE */
+
+#if !defined (LSI_VALUE)
+ #define LSI_VALUE (32000UL) /*!< Value of LSI in Hz*/
+#endif /* LSI_VALUE */
+
+#if !defined (LSE_VALUE)
+ #define LSE_VALUE (32768UL) /*!< Value of LSE in Hz*/
+#endif /* LSE_VALUE */
+
+/**
+ * @}
+ */
+
+/** @addtogroup STM32WBxx_System_Private_TypesDefinitions
+ * @{
+ */
+
+/**
+ * @}
+ */
+
+/** @addtogroup STM32WBxx_System_Private_Defines
+ * @{
+ */
+
+/*!< Uncomment the following line if you need to relocate your vector Table in
+ Internal SRAM. */
+/* #define VECT_TAB_SRAM */
+#define VECT_TAB_OFFSET 0x0U /*!< Vector Table base offset field.
+ This value must be a multiple of 0x200. */
+
+#define VECT_TAB_BASE_ADDRESS SRAM1_BASE /*!< Vector Table base offset field.
+ This value must be a multiple of 0x200. */
+/**
+ * @}
+ */
+
+/** @addtogroup STM32WBxx_System_Private_Macros
+ * @{
+ */
+
+/**
+ * @}
+ */
+
+/** @addtogroup STM32WBxx_System_Private_Variables
+ * @{
+ */
+ /* The SystemCoreClock variable is updated in three ways:
+ 1) by calling CMSIS function SystemCoreClockUpdate()
+ 2) by calling HAL API function HAL_RCC_GetHCLKFreq()
+ 3) each time HAL_RCC_ClockConfig() is called to configure the system clock frequency
+ Note: If you use this function to configure the system clock; then there
+ is no need to call the 2 first functions listed above, since SystemCoreClock
+ variable is updated automatically.
+ */
+ uint32_t SystemCoreClock = 4000000UL ; /*CPU1: M4 on MSI clock after startup (4MHz)*/
+
+ const uint32_t AHBPrescTable[16UL] = {1UL, 3UL, 5UL, 1UL, 1UL, 6UL, 10UL, 32UL, 2UL, 4UL, 8UL, 16UL, 64UL, 128UL, 256UL, 512UL};
+
+ const uint32_t APBPrescTable[8UL] = {0UL, 0UL, 0UL, 0UL, 1UL, 2UL, 3UL, 4UL};
+
+ const uint32_t MSIRangeTable[16UL] = {100000UL, 200000UL, 400000UL, 800000UL, 1000000UL, 2000000UL, \
+ 4000000UL, 8000000UL, 16000000UL, 24000000UL, 32000000UL, 48000000UL, 0UL, 0UL, 0UL, 0UL}; /* 0UL values are incorrect cases */
+
+ const uint32_t SmpsPrescalerTable[4UL][6UL]={{1UL,3UL,2UL,2UL,1UL,2UL}, \
+ {2UL,6UL,4UL,3UL,2UL,4UL}, \
+ {4UL,12UL,8UL,6UL,4UL,8UL}, \
+ {4UL,12UL,8UL,6UL,4UL,8UL}};
+
+/**
+ * @}
+ */
+
+/** @addtogroup STM32WBxx_System_Private_FunctionPrototypes
+ * @{
+ */
+
+/**
+ * @}
+ */
+
+/** @addtogroup STM32WBxx_System_Private_Functions
+ * @{
+ */
+
+/**
+ * @brief Setup the microcontroller system.
+ * @param None
+ * @retval None
+ */
+void SystemInit(void)
+{
+ /* Configure the Vector Table location add offset address ------------------*/
+#if defined(VECT_TAB_SRAM) && defined(VECT_TAB_BASE_ADDRESS)
+ /* program in SRAMx */
+ SCB->VTOR = VECT_TAB_BASE_ADDRESS | VECT_TAB_OFFSET; /* Vector Table Relocation in Internal SRAMx for CPU1 */
+#else /* program in FLASH */
+ SCB->VTOR = VECT_TAB_OFFSET; /* Vector Table Relocation in Internal FLASH */
+#endif
+
+ /* FPU settings ------------------------------------------------------------*/
+ #if (__FPU_PRESENT == 1) && (__FPU_USED == 1)
+ SCB->CPACR |= ((3UL << (10UL*2UL))|(3UL << (11UL*2UL))); /* set CP10 and CP11 Full Access */
+ #endif
+
+ /* Reset the RCC clock configuration to the default reset state ------------*/
+ /* Set MSION bit */
+ RCC->CR |= RCC_CR_MSION;
+
+ /* Reset CFGR register */
+ RCC->CFGR = 0x00070000U;
+
+ /* Reset PLLSAI1ON, PLLON, HSECSSON, HSEON, HSION, and MSIPLLON bits */
+ RCC->CR &= (uint32_t)0xFAF6FEFBU;
+
+ /*!< Reset LSI1 and LSI2 bits */
+ RCC->CSR &= (uint32_t)0xFFFFFFFAU;
+
+ /*!< Reset HSI48ON bit */
+ RCC->CRRCR &= (uint32_t)0xFFFFFFFEU;
+
+ /* Reset PLLCFGR register */
+ RCC->PLLCFGR = 0x22041000U;
+
+#if defined(STM32WB55xx)
+ /* Reset PLLSAI1CFGR register */
+ RCC->PLLSAI1CFGR = 0x22041000U;
+#endif
+
+ /* Reset HSEBYP bit */
+ RCC->CR &= 0xFFFBFFFFU;
+
+ /* Disable all interrupts */
+ RCC->CIER = 0x00000000;
+}
+
+/**
+ * @brief Update SystemCoreClock variable according to Clock Register Values.
+ * The SystemCoreClock variable contains the core clock (HCLK), it can
+ * be used by the user application to setup the SysTick timer or configure
+ * other parameters.
+ *
+ * @note Each time the core clock (HCLK) changes, this function must be called
+ * to update SystemCoreClock variable value. Otherwise, any configuration
+ * based on this variable will be incorrect.
+ *
+ * @note - The system frequency computed by this function is not the real
+ * frequency in the chip. It is calculated based on the predefined
+ * constant and the selected clock source:
+ *
+ * - If SYSCLK source is MSI, SystemCoreClock will contain the MSI_VALUE(*)
+ *
+ * - If SYSCLK source is HSI, SystemCoreClock will contain the HSI_VALUE(**)
+ *
+ * - If SYSCLK source is HSE, SystemCoreClock will contain the HSE_VALUE(***)
+ *
+ * - If SYSCLK source is PLL, SystemCoreClock will contain the HSE_VALUE(***)
+ * or HSI_VALUE(*) or MSI_VALUE(*) multiplied/divided by the PLL factors.
+ *
+ * (*) MSI_VALUE is a constant defined in stm32wbxx_hal.h file (default value
+ * 4 MHz) but the real value may vary depending on the variations
+ * in voltage and temperature.
+ *
+ * (**) HSI_VALUE is a constant defined in stm32wbxx_hal_conf.h file (default value
+ * 16 MHz) but the real value may vary depending on the variations
+ * in voltage and temperature.
+ *
+ * (***) HSE_VALUE is a constant defined in stm32wbxx_hal_conf.h file (default value
+ * 32 MHz), user has to ensure that HSE_VALUE is same as the real
+ * frequency of the crystal used. Otherwise, this function may
+ * have wrong result.
+ *
+ * - The result of this function could be not correct when using fractional
+ * value for HSE crystal.
+ *
+ * @param None
+ * @retval None
+ */
+void SystemCoreClockUpdate(void)
+{
+ uint32_t tmp, msirange, pllvco, pllr, pllsource , pllm;
+
+ /* Get MSI Range frequency--------------------------------------------------*/
+
+ /*MSI frequency range in Hz*/
+ msirange = MSIRangeTable[(RCC->CR & RCC_CR_MSIRANGE) >> RCC_CR_MSIRANGE_Pos];
+
+ /* Get SYSCLK source -------------------------------------------------------*/
+ switch (RCC->CFGR & RCC_CFGR_SWS)
+ {
+ case 0x00: /* MSI used as system clock source */
+ SystemCoreClock = msirange;
+ break;
+
+ case 0x04: /* HSI used as system clock source */
+ /* HSI used as system clock source */
+ SystemCoreClock = HSI_VALUE;
+ break;
+
+ case 0x08: /* HSE used as system clock source */
+ SystemCoreClock = HSE_VALUE;
+ break;
+
+ case 0x0C: /* PLL used as system clock source */
+ /* PLL_VCO = (HSE_VALUE or HSI_VALUE or MSI_VALUE/ PLLM) * PLLN
+ SYSCLK = PLL_VCO / PLLR
+ */
+ pllsource = (RCC->PLLCFGR & RCC_PLLCFGR_PLLSRC);
+ pllm = ((RCC->PLLCFGR & RCC_PLLCFGR_PLLM) >> RCC_PLLCFGR_PLLM_Pos) + 1UL ;
+
+ if(pllsource == 0x02UL) /* HSI used as PLL clock source */
+ {
+ pllvco = (HSI_VALUE / pllm);
+ }
+ else if(pllsource == 0x03UL) /* HSE used as PLL clock source */
+ {
+ pllvco = (HSE_VALUE / pllm);
+ }
+ else /* MSI used as PLL clock source */
+ {
+ pllvco = (msirange / pllm);
+ }
+
+ pllvco = pllvco * ((RCC->PLLCFGR & RCC_PLLCFGR_PLLN) >> RCC_PLLCFGR_PLLN_Pos);
+ pllr = (((RCC->PLLCFGR & RCC_PLLCFGR_PLLR) >> RCC_PLLCFGR_PLLR_Pos) + 1UL);
+
+ SystemCoreClock = pllvco/pllr;
+ break;
+
+ default:
+ SystemCoreClock = msirange;
+ break;
+ }
+
+ /* Compute HCLK clock frequency --------------------------------------------*/
+ /* Get HCLK1 prescaler */
+ tmp = AHBPrescTable[((RCC->CFGR & RCC_CFGR_HPRE) >> RCC_CFGR_HPRE_Pos)];
+ /* HCLK clock frequency */
+ SystemCoreClock = SystemCoreClock / tmp;
+
+}
+
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/