diff options
author | rihab kouki <rihab.kouki@st.com> | 2021-07-23 12:14:42 +0300 |
---|---|---|
committer | rihab kouki <rihab.kouki@st.com> | 2021-07-23 16:12:38 +0300 |
commit | 95f19205e36f1e26409b88e302537cbc8918f7e9 (patch) | |
tree | 300d4ed71cc66e1e68c12ebc51aedb5d5136b6c8 /Projects/NUCLEO-WB15CC/Applications/BLE_LLD/BLE_LLD_Lowpower/Core | |
parent | 2d1f0ea0748169a268228d0f7b6416e5127e6027 (diff) |
Release v1.12.0
Diffstat (limited to 'Projects/NUCLEO-WB15CC/Applications/BLE_LLD/BLE_LLD_Lowpower/Core')
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>© 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>© 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>© 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>© 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>© 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>© 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>© 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>© 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>© 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>© 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>© 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>© 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>© 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>© 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>© 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>© 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>© 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>© 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>© 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>© 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>© 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>© 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>© 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****/ |