работает слейв и мастер
This commit is contained in:
751
Core/Src/app_entry.c
Normal file
751
Core/Src/app_entry.c
Normal file
@@ -0,0 +1,751 @@
|
||||
/* USER CODE BEGIN Header */
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file app_entry.c
|
||||
* @author MCD Application Team
|
||||
* @brief Entry point of the application
|
||||
******************************************************************************
|
||||
* @attention
|
||||
*
|
||||
* Copyright (c) 2019-2023 STMicroelectronics.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This software is licensed under terms that can be found in the LICENSE file
|
||||
* in the root directory of this software component.
|
||||
* If no LICENSE file comes with this software, it is provided AS-IS.
|
||||
*
|
||||
******************************************************************************
|
||||
*/
|
||||
/* USER CODE END Header */
|
||||
|
||||
/* Includes ------------------------------------------------------------------*/
|
||||
#include "app_common.h"
|
||||
#include "main.h"
|
||||
#include "app_entry.h"
|
||||
#include "app_zigbee.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 "otp.h"
|
||||
|
||||
/* Private includes -----------------------------------------------------------*/
|
||||
/* USER CODE BEGIN Includes */
|
||||
#include "hardware.h"
|
||||
#include "zigbee_app.h"
|
||||
|
||||
/* USER CODE END Includes */
|
||||
|
||||
/* Private typedef -----------------------------------------------------------*/
|
||||
extern RTC_HandleTypeDef hrtc;
|
||||
/* USER CODE BEGIN PTD */
|
||||
|
||||
/* 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];
|
||||
extern uint8_t g_ot_notification_allowed;
|
||||
|
||||
/* 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 /* CFG_DEBUG_TRACE != 0 */
|
||||
|
||||
/* USER CODE BEGIN GFP */
|
||||
|
||||
/* USER CODE END GFP */
|
||||
|
||||
/* Private functions prototypes-----------------------------------------------*/
|
||||
static void Config_HSE(void);
|
||||
static void Reset_Device(void);
|
||||
#if (CFG_HW_RESET_BY_FW == 1)
|
||||
static void Reset_IPCC(void);
|
||||
static void Reset_BackupDomain(void);
|
||||
#endif /* CFG_HW_RESET_BY_FW == 1*/
|
||||
static void System_Init(void);
|
||||
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);
|
||||
#if (CFG_HW_LPUART1_ENABLED == 1)
|
||||
extern void MX_LPUART1_UART_Init(void);
|
||||
#endif /* CFG_HW_LPUART1_ENABLED == 1 */
|
||||
#if (CFG_HW_USART1_ENABLED == 1)
|
||||
extern void MX_USART1_UART_Init(void);
|
||||
#endif /* CFG_HW_USART1_ENABLED == 1 */
|
||||
static void Init_Rtc(void);
|
||||
|
||||
/* USER CODE BEGIN PFP */
|
||||
static void Led_Init(void);
|
||||
static void Button_Init(void);
|
||||
|
||||
/* Section specific to button management using UART */
|
||||
static void RxUART_Init(void);
|
||||
static void RxCpltCallback(void);
|
||||
static void UartCmdExecute(void);
|
||||
|
||||
#define C_SIZE_CMD_STRING 256U
|
||||
#define RX_BUFFER_SIZE 8U
|
||||
|
||||
static uint8_t aRxBuffer[RX_BUFFER_SIZE];
|
||||
static uint8_t CommandString[C_SIZE_CMD_STRING];
|
||||
static uint16_t indexReceiveChar = 0;
|
||||
EXTI_HandleTypeDef exti_handle;
|
||||
|
||||
/* USER CODE END PFP */
|
||||
|
||||
/* Functions Definition ------------------------------------------------------*/
|
||||
void MX_APPE_Config(void)
|
||||
{
|
||||
/**
|
||||
* 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);
|
||||
|
||||
/**
|
||||
* Reset some configurations so that the system behave in the same way
|
||||
* when either out of nReset or Power On
|
||||
*/
|
||||
Reset_Device();
|
||||
|
||||
/* Configure HSE Tuning */
|
||||
Config_HSE();
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
void MX_APPE_Init(void)
|
||||
{
|
||||
System_Init(); /**< System initialization */
|
||||
|
||||
SystemPower_Config(); /**< Configure the system Power Mode */
|
||||
|
||||
HW_TS_Init(hw_ts_InitMode_Full, &hrtc); /**< Initialize the TimerServer */
|
||||
|
||||
/* USER CODE BEGIN APPE_Init_1 */
|
||||
Init_Debug();
|
||||
|
||||
Led_Init();
|
||||
Button_Init();
|
||||
RxUART_Init();
|
||||
|
||||
/* USER CODE END APPE_Init_1 */
|
||||
appe_Tl_Init(); /* Initialize all transport layers */
|
||||
|
||||
/**
|
||||
* From now, the application is waiting for the ready event (VS_HCI_C2_Ready)
|
||||
* received on the system channel before starting the Stack
|
||||
* This system event is received with APPE_SysUserEvtRx()
|
||||
*/
|
||||
/* USER CODE BEGIN APPE_Init_2 */
|
||||
Hardware_Init();
|
||||
ZigbeeApp_Init();
|
||||
|
||||
/* USER CODE END APPE_Init_2 */
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
void Init_Smps(void)
|
||||
{
|
||||
#if (CFG_USE_SMPS != 0)
|
||||
/**
|
||||
* Configure and enable SMPS
|
||||
*
|
||||
* The SMPS configuration is not yet supported by CubeMx
|
||||
* when SMPS output voltage is set to 1.4V, the RF output power is limited to 3.7dBm
|
||||
* the SMPS output voltage shall be increased for higher RF output power
|
||||
*/
|
||||
LL_PWR_SMPS_SetStartupCurrent(LL_PWR_SMPS_STARTUP_CURRENT_80MA);
|
||||
LL_PWR_SMPS_SetOutputVoltageLevel(LL_PWR_SMPS_OUTPUT_VOLTAGE_1V40);
|
||||
LL_PWR_SMPS_Enable();
|
||||
#endif /* CFG_USE_SMPS != 0 */
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
void Init_Exti(void)
|
||||
{
|
||||
/* Enable IPCC(36), HSEM(38) wakeup interrupts on CPU1 */
|
||||
LL_EXTI_EnableIT_32_63(LL_EXTI_LINE_36 | LL_EXTI_LINE_38);
|
||||
|
||||
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 *************************************/
|
||||
LL_EXTI_EnableIT_32_63(LL_EXTI_LINE_48);
|
||||
LL_C2_EXTI_EnableIT_32_63(LL_EXTI_LINE_48);
|
||||
|
||||
#else
|
||||
|
||||
GPIO_InitTypeDef gpio_config = {0};
|
||||
|
||||
gpio_config.Pull = GPIO_NOPULL;
|
||||
gpio_config.Mode = GPIO_MODE_ANALOG;
|
||||
|
||||
gpio_config.Pin = GPIO_PIN_15 | GPIO_PIN_14 | GPIO_PIN_13;
|
||||
__HAL_RCC_GPIOA_CLK_ENABLE();
|
||||
HAL_GPIO_Init(GPIOA, &gpio_config);
|
||||
__HAL_RCC_GPIOA_CLK_DISABLE();
|
||||
|
||||
gpio_config.Pin = GPIO_PIN_4 | GPIO_PIN_3;
|
||||
__HAL_RCC_GPIOB_CLK_ENABLE();
|
||||
HAL_GPIO_Init(GPIOB, &gpio_config);
|
||||
__HAL_RCC_GPIOB_CLK_DISABLE();
|
||||
|
||||
HAL_DBGMCU_DisableDBGSleepMode();
|
||||
HAL_DBGMCU_DisableDBGStopMode();
|
||||
HAL_DBGMCU_DisableDBGStandbyMode();
|
||||
|
||||
#endif /* (CFG_DEBUGGER_SUPPORTED == 1) */
|
||||
|
||||
#if (CFG_DEBUG_TRACE != 0)
|
||||
DbgTraceInit();
|
||||
#endif /* CFG_DEBUG_TRACE != 0 */
|
||||
|
||||
return;
|
||||
}
|
||||
static void Reset_Device(void)
|
||||
{
|
||||
#if (CFG_HW_RESET_BY_FW == 1)
|
||||
Reset_BackupDomain();
|
||||
|
||||
Reset_IPCC();
|
||||
#endif /* CFG_HW_RESET_BY_FW == 1 */
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
#if (CFG_HW_RESET_BY_FW == 1)
|
||||
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 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;
|
||||
}
|
||||
#endif /* CFG_HW_RESET_BY_FW == 1 */
|
||||
|
||||
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 System_Init(void)
|
||||
{
|
||||
Init_Smps();
|
||||
|
||||
Init_Exti();
|
||||
|
||||
Init_Rtc();
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
static void Init_Rtc(void)
|
||||
{
|
||||
/* 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);
|
||||
|
||||
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)
|
||||
{
|
||||
/* 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();
|
||||
/* Initialize the CPU2 reset value before starting CPU2 with C2BOOT */
|
||||
LL_C2_PWR_SetPowerMode(LL_PWR_MODE_SHUTDOWN);
|
||||
|
||||
/* Disable Stop & Off Modes until Initialisation is complete */
|
||||
UTIL_LPM_SetOffMode(1 << CFG_LPM_APP, UTIL_LPM_DISABLE);
|
||||
UTIL_LPM_SetStopMode(1 << CFG_LPM_APP, UTIL_LPM_DISABLE);
|
||||
|
||||
#if (CFG_USB_INTERFACE_ENABLE != 0)
|
||||
/**
|
||||
* Enable USB power
|
||||
*/
|
||||
HAL_PWREx_EnableVddUSB();
|
||||
#endif /* CFG_USB_INTERFACE_ENABLE != 0 */
|
||||
|
||||
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 */
|
||||
memset(&tl_mm_config, 0, sizeof(TL_MM_Config_t));
|
||||
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);
|
||||
|
||||
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:
|
||||
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_ZIGBEE_UNKNOWN_CMD:
|
||||
APP_DBG("** ERR_ZIGBEE : UNKNOWN_CMD \n");
|
||||
break;
|
||||
default:
|
||||
APP_DBG("** ERR_ZIGBEE : ErroCode=%d \n",ErrorCode);
|
||||
break;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
static void APPE_SysEvtReadyProcessing(void)
|
||||
{
|
||||
/* Traces channel initialization */
|
||||
TL_TRACES_Init();
|
||||
|
||||
APP_ZIGBEE_Init();
|
||||
return;
|
||||
}
|
||||
|
||||
/* USER CODE BEGIN FD_LOCAL_FUNCTIONS */
|
||||
static void Led_Init( void )
|
||||
{
|
||||
#if (CFG_LED_SUPPORTED == 1U)
|
||||
/* Leds Initialization */
|
||||
BSP_LED_Init(LED_BLUE);
|
||||
BSP_LED_Init(LED_GREEN);
|
||||
BSP_LED_Init(LED_RED);
|
||||
#endif /* (CFG_LED_SUPPORTED == 1U) */
|
||||
|
||||
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 /* (CFG_BUTTON_SUPPORTED == 1U) */
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
/* USER CODE END FD_LOCAL_FUNCTIONS */
|
||||
|
||||
/*************************************************************
|
||||
*
|
||||
* 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) || defined (__ARMCC_VERSION)
|
||||
__force_stores();
|
||||
#endif /*__ARMCC_VERSION */
|
||||
|
||||
__WFI();
|
||||
}
|
||||
}
|
||||
|
||||
void MX_APPE_Process(void)
|
||||
{
|
||||
/* USER CODE BEGIN MX_APPE_Process_1 */
|
||||
|
||||
/* USER CODE END MX_APPE_Process_1 */
|
||||
UTIL_SEQ_Run(UTIL_SEQ_DEFAULT);
|
||||
/* USER CODE BEGIN MX_APPE_Process_2 */
|
||||
ZigbeeApp_Process();
|
||||
|
||||
/* USER CODE END MX_APPE_Process_2 */
|
||||
}
|
||||
|
||||
void UTIL_SEQ_Idle(void)
|
||||
{
|
||||
#if (CFG_LPM_SUPPORTED == 1)
|
||||
UTIL_LPM_EnterLowPower();
|
||||
#endif /* CFG_LPM_SUPPORTED == 1 */
|
||||
return;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief This function is called by the scheduler each time an event
|
||||
* is pending.
|
||||
*
|
||||
* @param evt_waited_bm : Event pending.
|
||||
* @retval None
|
||||
*/
|
||||
void UTIL_SEQ_EvtIdle(UTIL_SEQ_bm_t task_id_bm, UTIL_SEQ_bm_t evt_waited_bm)
|
||||
{
|
||||
/* Check the notification condition */
|
||||
if (g_ot_notification_allowed) {
|
||||
UTIL_SEQ_Run(1U << CFG_TASK_NOTIFY_FROM_M0_TO_M4);
|
||||
}
|
||||
switch(evt_waited_bm)
|
||||
{
|
||||
case EVENT_ACK_FROM_M0_EVT:
|
||||
/**
|
||||
* Run only the task CFG_TASK_REQUEST_FROM_M0_TO_M4 to process
|
||||
* direct requests from the M0 (e.g. ZbMalloc), but no stack notifications
|
||||
* until we're done the request to the M0.
|
||||
*/
|
||||
UTIL_SEQ_Run((1U << CFG_TASK_REQUEST_FROM_M0_TO_M4));
|
||||
break;
|
||||
case EVENT_SYNCHRO_BYPASS_IDLE:
|
||||
UTIL_SEQ_SetEvt(EVENT_SYNCHRO_BYPASS_IDLE);
|
||||
/* Process notifications and requests from the M0 */
|
||||
UTIL_SEQ_Run((1U << CFG_TASK_NOTIFY_FROM_M0_TO_M4) | (1U << CFG_TASK_REQUEST_FROM_M0_TO_M4));
|
||||
break;
|
||||
default :
|
||||
/* default case */
|
||||
UTIL_SEQ_Run(UTIL_SEQ_DEFAULT);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
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 != 0 */
|
||||
/* Release buffer */
|
||||
TL_MM_EvtDone(hcievt);
|
||||
}
|
||||
/**
|
||||
* @brief Initialisation of the trace mechanism
|
||||
* @param None
|
||||
* @retval None
|
||||
*/
|
||||
#if (CFG_DEBUG_TRACE != 0)
|
||||
void DbgOutputInit(void)
|
||||
{
|
||||
#ifdef CFG_DEBUG_TRACE_UART
|
||||
MX_USART1_UART_Init();
|
||||
return;
|
||||
#endif /* CFG_DEBUG_TRACE_UART */
|
||||
}
|
||||
|
||||
/**
|
||||
* @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 /* CFG_DEBUG_TRACE != 0 */
|
||||
|
||||
/* USER CODE BEGIN FD_WRAP_FUNCTIONS */
|
||||
/**
|
||||
* @brief This function manage the Push button action
|
||||
* @param GPIO_Pin : GPIO pin which has been activated
|
||||
* @retval None
|
||||
*/
|
||||
void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin)
|
||||
{
|
||||
switch (GPIO_Pin)
|
||||
{
|
||||
case BUTTON_SW1_PIN:
|
||||
break;
|
||||
|
||||
case BUTTON_SW2_PIN:
|
||||
break;
|
||||
|
||||
case BUTTON_SW3_PIN:
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void RxUART_Init(void)
|
||||
{
|
||||
HW_UART_Receive_IT(CFG_DEBUG_TRACE_UART, aRxBuffer, 1U, RxCpltCallback);
|
||||
}
|
||||
|
||||
static void RxCpltCallback(void)
|
||||
{
|
||||
/* Filling buffer and wait for '\r' char */
|
||||
if (indexReceiveChar < C_SIZE_CMD_STRING)
|
||||
{
|
||||
if (aRxBuffer[0] == '\r')
|
||||
{
|
||||
APP_DBG("received %s", CommandString);
|
||||
|
||||
UartCmdExecute();
|
||||
|
||||
/* Clear receive buffer and character counter*/
|
||||
indexReceiveChar = 0;
|
||||
memset(CommandString, 0, C_SIZE_CMD_STRING);
|
||||
}
|
||||
else
|
||||
{
|
||||
CommandString[indexReceiveChar++] = aRxBuffer[0];
|
||||
}
|
||||
}
|
||||
|
||||
/* Once a character has been sent, put back the device in reception mode */
|
||||
HW_UART_Receive_IT(CFG_DEBUG_TRACE_UART, aRxBuffer, 1U, RxCpltCallback);
|
||||
}
|
||||
|
||||
static void UartCmdExecute(void)
|
||||
{
|
||||
/* Parse received CommandString */
|
||||
if(strcmp((char const*)CommandString, "SW1") == 0)
|
||||
{
|
||||
APP_DBG("SW1 OK");
|
||||
exti_handle.Line = EXTI_LINE_4;
|
||||
HAL_EXTI_GenerateSWI(&exti_handle);
|
||||
}
|
||||
else if (strcmp((char const*)CommandString, "SW2") == 0)
|
||||
{
|
||||
APP_DBG("SW2 OK");
|
||||
exti_handle.Line = EXTI_LINE_0;
|
||||
HAL_EXTI_GenerateSWI(&exti_handle);
|
||||
}
|
||||
else if (strcmp((char const*)CommandString, "SW3") == 0)
|
||||
{
|
||||
APP_DBG("SW3 OK");
|
||||
exti_handle.Line = EXTI_LINE_1;
|
||||
HAL_EXTI_GenerateSWI(&exti_handle);
|
||||
}
|
||||
else if (strcmp((char const*)CommandString, "RST") == 0)
|
||||
{
|
||||
APP_DBG("RESET CMD RECEIVED");
|
||||
HAL_NVIC_SystemReset();
|
||||
}
|
||||
else
|
||||
{
|
||||
APP_DBG("NOT RECOGNIZED COMMAND : %s", CommandString);
|
||||
}
|
||||
}
|
||||
/* USER CODE END FD_WRAP_FUNCTIONS */
|
||||
888
Core/Src/hw_timerserver.c
Normal file
888
Core/Src/hw_timerserver.c
Normal file
@@ -0,0 +1,888 @@
|
||||
/* USER CODE BEGIN Header */
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file hw_timerserver.c
|
||||
* @author MCD Application Team
|
||||
* @brief Hardware timerserver source file for STM32WPAN Middleware.
|
||||
******************************************************************************
|
||||
* @attention
|
||||
*
|
||||
* Copyright (c) 2021 STMicroelectronics.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This software is licensed under terms that can be found in the LICENSE file
|
||||
* in the root directory of this software component.
|
||||
* If no LICENSE file comes with this software, it is provided AS-IS.
|
||||
*
|
||||
******************************************************************************
|
||||
*/
|
||||
/* USER CODE END Header */
|
||||
|
||||
/* 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
|
||||
*/
|
||||
|
||||
static volatile TimerContext_t aTimerContext[CFG_HW_TS_MAX_NBR_CONCURRENT_TIMER];
|
||||
static volatile uint8_t CurrentRunningTimerID;
|
||||
static volatile uint8_t PreviousRunningTimerID;
|
||||
static volatile uint32_t SSRValueOnLastSetup;
|
||||
static volatile WakeupTimerLimitation_Status_t WakeupTimerLimitation;
|
||||
|
||||
/**
|
||||
* END of Section TIMERSERVER_CONTEXT
|
||||
*/
|
||||
|
||||
static uint8_t WakeupTimerDivider;
|
||||
static uint8_t AsynchPrescalerUserConfig;
|
||||
static uint16_t SynchPrescalerUserConfig;
|
||||
static volatile uint16_t MaxWakeupTimerSetup;
|
||||
|
||||
/* Global variables ----------------------------------------------------------*/
|
||||
extern RTC_HandleTypeDef hrtc;
|
||||
|
||||
/* 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(&hrtc);
|
||||
*/
|
||||
|
||||
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(&hrtc, 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(&hrtc, 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(&hrtc); /**< 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(&hrtc, RTC_FLAG_WUTWF) == SET);
|
||||
}
|
||||
__HAL_RTC_WAKEUPTIMER_DISABLE(&hrtc); /**< 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( &hrtc );
|
||||
|
||||
/**
|
||||
* 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(&hrtc);
|
||||
|
||||
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( &hrtc );
|
||||
}
|
||||
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( &hrtc );
|
||||
}
|
||||
|
||||
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(&hrtc, 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(&hrtc, 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( &hrtc );
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
void HW_TS_Init(HW_TS_InitMode_t TimerInitMode, RTC_HandleTypeDef *phrtc)
|
||||
{
|
||||
uint8_t loop;
|
||||
uint32_t localmaxwakeuptimersetup;
|
||||
|
||||
/* Disable the write protection for RTC registers */
|
||||
__HAL_RTC_WRITEPROTECTION_DISABLE( &hrtc );
|
||||
|
||||
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(&hrtc); /**< Disable the Wakeup Timer */
|
||||
__HAL_RTC_WAKEUPTIMER_CLEAR_FLAG(&hrtc, 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(&hrtc, RTC_IT_WUT); /**< Enable interrupt in RTC module */
|
||||
}
|
||||
else
|
||||
{
|
||||
if(__HAL_RTC_WAKEUPTIMER_GET_FLAG(&hrtc, 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( &hrtc );
|
||||
|
||||
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( &hrtc );
|
||||
|
||||
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(&hrtc, RTC_FLAG_WUTWF) == SET);
|
||||
}
|
||||
__HAL_RTC_WAKEUPTIMER_DISABLE(&hrtc); /**< Disable the Wakeup Timer */
|
||||
|
||||
while(__HAL_RTC_WAKEUPTIMER_GET_FLAG(&hrtc, 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(&hrtc, 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( &hrtc );
|
||||
|
||||
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( &hrtc );
|
||||
|
||||
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( &hrtc );
|
||||
|
||||
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;
|
||||
}
|
||||
317
Core/Src/hw_uart.c
Normal file
317
Core/Src/hw_uart.c
Normal file
@@ -0,0 +1,317 @@
|
||||
/* USER CODE BEGIN Header */
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file Src/hw_uart.c
|
||||
* @author MCD Application Team
|
||||
* @brief HW UART source file for STM32WPAN Middleware.
|
||||
******************************************************************************
|
||||
* @attention
|
||||
*
|
||||
* Copyright (c) 2019-2023 STMicroelectronics.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This software is licensed under terms that can be found in the LICENSE file
|
||||
* in the root directory of this software component.
|
||||
* If no LICENSE file comes with this software, it is provided AS-IS.
|
||||
*
|
||||
******************************************************************************
|
||||
*/
|
||||
/* USER CODE END Header */
|
||||
|
||||
/* Includes ------------------------------------------------------------------*/
|
||||
#include "app_common.h"
|
||||
#include "hw_conf.h"
|
||||
#if (CFG_HW_LPUART1_ENABLED == 1)
|
||||
extern UART_HandleTypeDef hlpuart1;
|
||||
#endif
|
||||
#if (CFG_HW_USART1_ENABLED == 1)
|
||||
extern UART_HandleTypeDef huart1;
|
||||
#endif
|
||||
|
||||
/* Macros --------------------------------------------------------------------*/
|
||||
#define HW_UART_RX_IT(__HANDLE__, __USART_BASE__) \
|
||||
do{ \
|
||||
HW_##__HANDLE__##RxCb = cb; \
|
||||
(__HANDLE__).Instance = (__USART_BASE__); \
|
||||
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_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)
|
||||
#if (CFG_HW_USART1_DMA_TX_SUPPORTED == 1)
|
||||
DMA_HandleTypeDef HW_hdma_huart1_tx ={0};
|
||||
#endif
|
||||
void (*HW_huart1RxCb)(void);
|
||||
void (*HW_huart1TxCb)(void);
|
||||
#endif
|
||||
|
||||
#if (CFG_HW_LPUART1_ENABLED == 1)
|
||||
#if (CFG_HW_LPUART1_DMA_TX_SUPPORTED == 1)
|
||||
DMA_HandleTypeDef HW_hdma_hlpuart1_tx ={0};
|
||||
#endif
|
||||
void (*HW_hlpuart1RxCb)(void);
|
||||
void (*HW_hlpuart1TxCb)(void);
|
||||
#endif
|
||||
|
||||
void HW_UART_Receive_IT(hw_uart_id_t hw_uart_id, uint8_t *p_data, uint16_t size, void (*cb)(void))
|
||||
{
|
||||
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;
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
void HW_UART_Transmit_IT(hw_uart_id_t hw_uart_id, uint8_t *p_data, uint16_t size, void (*cb)(void))
|
||||
{
|
||||
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;
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
465
Core/Src/main.c
Normal file
465
Core/Src/main.c
Normal file
@@ -0,0 +1,465 @@
|
||||
/* USER CODE BEGIN Header */
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file : main.c
|
||||
* @brief : Main program body
|
||||
******************************************************************************
|
||||
* @attention
|
||||
*
|
||||
* Copyright (c) 2020-2023 STMicroelectronics.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This software is licensed under terms that can be found in the LICENSE file
|
||||
* in the root directory of this software component.
|
||||
* If no LICENSE file comes with this software, it is provided AS-IS.
|
||||
*
|
||||
******************************************************************************
|
||||
*/
|
||||
/* USER CODE END Header */
|
||||
/* Includes ------------------------------------------------------------------*/
|
||||
#include "main.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 ---------------------------------------------------------*/
|
||||
IPCC_HandleTypeDef hipcc;
|
||||
|
||||
UART_HandleTypeDef hlpuart1;
|
||||
UART_HandleTypeDef huart1;
|
||||
DMA_HandleTypeDef hdma_lpuart1_tx;
|
||||
DMA_HandleTypeDef hdma_usart1_tx;
|
||||
|
||||
RTC_HandleTypeDef hrtc;
|
||||
|
||||
/* USER CODE BEGIN PV */
|
||||
|
||||
/* USER CODE END PV */
|
||||
|
||||
/* Private function prototypes -----------------------------------------------*/
|
||||
void SystemClock_Config(void);
|
||||
void PeriphCommonClock_Config(void);
|
||||
static void MX_GPIO_Init(void);
|
||||
static void MX_DMA_Init(void);
|
||||
static void MX_RTC_Init(void);
|
||||
static void MX_IPCC_Init(void);
|
||||
static void MX_RF_Init(void);
|
||||
/* USER CODE BEGIN PFP */
|
||||
|
||||
/* 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 */
|
||||
|
||||
/* USER CODE END 1 */
|
||||
|
||||
/* MCU Configuration--------------------------------------------------------*/
|
||||
|
||||
/* Reset of all peripherals, Initializes the Flash interface and the Systick. */
|
||||
HAL_Init();
|
||||
/* Config code for STM32_WPAN (HSE Tuning must be done before system clock configuration) */
|
||||
MX_APPE_Config();
|
||||
|
||||
/* USER CODE BEGIN Init */
|
||||
|
||||
/* USER CODE END Init */
|
||||
|
||||
/* Configure the system clock */
|
||||
SystemClock_Config();
|
||||
|
||||
/* Configure the peripherals common clocks */
|
||||
PeriphCommonClock_Config();
|
||||
|
||||
/* IPCC initialisation */
|
||||
MX_IPCC_Init();
|
||||
|
||||
/* USER CODE BEGIN SysInit */
|
||||
|
||||
/* USER CODE END SysInit */
|
||||
|
||||
/* Initialize all configured peripherals */
|
||||
MX_GPIO_Init();
|
||||
MX_DMA_Init();
|
||||
MX_RTC_Init();
|
||||
MX_RF_Init();
|
||||
/* USER CODE BEGIN 2 */
|
||||
|
||||
/* USER CODE END 2 */
|
||||
|
||||
/* Init code for STM32_WPAN */
|
||||
MX_APPE_Init();
|
||||
|
||||
/* Infinite loop */
|
||||
/* USER CODE BEGIN WHILE */
|
||||
while (1)
|
||||
{
|
||||
/* USER CODE END WHILE */
|
||||
MX_APPE_Process();
|
||||
|
||||
/* USER CODE BEGIN 3 */
|
||||
}
|
||||
/* USER CODE END 3 */
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief System Clock Configuration
|
||||
* @retval None
|
||||
*/
|
||||
void SystemClock_Config(void)
|
||||
{
|
||||
RCC_OscInitTypeDef RCC_OscInitStruct = {0};
|
||||
RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};
|
||||
|
||||
/** Configure LSE Drive Capability
|
||||
*/
|
||||
HAL_PWR_EnableBkUpAccess();
|
||||
__HAL_RCC_LSEDRIVE_CONFIG(RCC_LSEDRIVE_LOW);
|
||||
|
||||
/** Configure the main internal regulator output voltage
|
||||
*/
|
||||
__HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE1);
|
||||
|
||||
/** Initializes the RCC Oscillators according to the specified parameters
|
||||
* in the RCC_OscInitTypeDef structure.
|
||||
*/
|
||||
RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI|RCC_OSCILLATORTYPE_HSE
|
||||
|RCC_OSCILLATORTYPE_LSE;
|
||||
RCC_OscInitStruct.HSEState = RCC_HSE_ON;
|
||||
RCC_OscInitStruct.LSEState = RCC_LSE_ON;
|
||||
RCC_OscInitStruct.HSIState = RCC_HSI_ON;
|
||||
RCC_OscInitStruct.HSICalibrationValue = RCC_HSICALIBRATION_DEFAULT;
|
||||
RCC_OscInitStruct.PLL.PLLState = RCC_PLL_NONE;
|
||||
if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
|
||||
{
|
||||
Error_Handler();
|
||||
}
|
||||
|
||||
/** Configure the SYSCLKSource, HCLK, PCLK1 and PCLK2 clocks dividers
|
||||
*/
|
||||
RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK4|RCC_CLOCKTYPE_HCLK2
|
||||
|RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK
|
||||
|RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2;
|
||||
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();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Peripherals Common Clock Configuration
|
||||
* @retval None
|
||||
*/
|
||||
void PeriphCommonClock_Config(void)
|
||||
{
|
||||
RCC_PeriphCLKInitTypeDef PeriphClkInitStruct = {0};
|
||||
|
||||
/** Initializes the peripherals clock
|
||||
*/
|
||||
PeriphClkInitStruct.PeriphClockSelection = RCC_PERIPHCLK_SMPS|RCC_PERIPHCLK_RFWAKEUP;
|
||||
PeriphClkInitStruct.RFWakeUpClockSelection = RCC_RFWKPCLKSOURCE_LSE;
|
||||
PeriphClkInitStruct.SmpsClockSelection = RCC_SMPSCLKSOURCE_HSE;
|
||||
PeriphClkInitStruct.SmpsDivSelection = RCC_SMPSCLKDIV_RANGE0;
|
||||
|
||||
if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInitStruct) != HAL_OK)
|
||||
{
|
||||
Error_Handler();
|
||||
}
|
||||
/* USER CODE BEGIN Smps */
|
||||
|
||||
/* USER CODE END Smps */
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief IPCC Initialization Function
|
||||
* @param None
|
||||
* @retval None
|
||||
*/
|
||||
static void MX_IPCC_Init(void)
|
||||
{
|
||||
|
||||
/* USER CODE BEGIN IPCC_Init 0 */
|
||||
|
||||
/* USER CODE END IPCC_Init 0 */
|
||||
|
||||
/* USER CODE BEGIN IPCC_Init 1 */
|
||||
|
||||
/* USER CODE END IPCC_Init 1 */
|
||||
hipcc.Instance = IPCC;
|
||||
if (HAL_IPCC_Init(&hipcc) != HAL_OK)
|
||||
{
|
||||
Error_Handler();
|
||||
}
|
||||
/* USER CODE BEGIN IPCC_Init 2 */
|
||||
|
||||
/* USER CODE END IPCC_Init 2 */
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief LPUART1 Initialization Function
|
||||
* @param None
|
||||
* @retval None
|
||||
*/
|
||||
void MX_LPUART1_UART_Init(void)
|
||||
{
|
||||
|
||||
/* USER CODE BEGIN LPUART1_Init 0 */
|
||||
|
||||
/* USER CODE END LPUART1_Init 0 */
|
||||
|
||||
/* USER CODE BEGIN LPUART1_Init 1 */
|
||||
|
||||
/* USER CODE END LPUART1_Init 1 */
|
||||
hlpuart1.Instance = LPUART1;
|
||||
hlpuart1.Init.BaudRate = 115200;
|
||||
hlpuart1.Init.WordLength = UART_WORDLENGTH_8B;
|
||||
hlpuart1.Init.StopBits = UART_STOPBITS_1;
|
||||
hlpuart1.Init.Parity = UART_PARITY_NONE;
|
||||
hlpuart1.Init.Mode = UART_MODE_TX_RX;
|
||||
hlpuart1.Init.HwFlowCtl = UART_HWCONTROL_NONE;
|
||||
hlpuart1.Init.OneBitSampling = UART_ONE_BIT_SAMPLE_DISABLE;
|
||||
hlpuart1.Init.ClockPrescaler = UART_PRESCALER_DIV1;
|
||||
hlpuart1.AdvancedInit.AdvFeatureInit = UART_ADVFEATURE_NO_INIT;
|
||||
hlpuart1.FifoMode = UART_FIFOMODE_DISABLE;
|
||||
if (HAL_UART_Init(&hlpuart1) != HAL_OK)
|
||||
{
|
||||
Error_Handler();
|
||||
}
|
||||
if (HAL_UARTEx_SetTxFifoThreshold(&hlpuart1, UART_TXFIFO_THRESHOLD_1_8) != HAL_OK)
|
||||
{
|
||||
Error_Handler();
|
||||
}
|
||||
if (HAL_UARTEx_SetRxFifoThreshold(&hlpuart1, UART_RXFIFO_THRESHOLD_1_8) != HAL_OK)
|
||||
{
|
||||
Error_Handler();
|
||||
}
|
||||
if (HAL_UARTEx_DisableFifoMode(&hlpuart1) != HAL_OK)
|
||||
{
|
||||
Error_Handler();
|
||||
}
|
||||
/* USER CODE BEGIN LPUART1_Init 2 */
|
||||
|
||||
/* USER CODE END LPUART1_Init 2 */
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief USART1 Initialization Function
|
||||
* @param None
|
||||
* @retval None
|
||||
*/
|
||||
void MX_USART1_UART_Init(void)
|
||||
{
|
||||
|
||||
/* USER CODE BEGIN USART1_Init 0 */
|
||||
|
||||
/* USER CODE END USART1_Init 0 */
|
||||
|
||||
/* USER CODE BEGIN USART1_Init 1 */
|
||||
|
||||
/* USER CODE END USART1_Init 1 */
|
||||
huart1.Instance = USART1;
|
||||
huart1.Init.BaudRate = 115200;
|
||||
huart1.Init.WordLength = UART_WORDLENGTH_8B;
|
||||
huart1.Init.StopBits = UART_STOPBITS_1;
|
||||
huart1.Init.Parity = UART_PARITY_NONE;
|
||||
huart1.Init.Mode = UART_MODE_TX_RX;
|
||||
huart1.Init.HwFlowCtl = UART_HWCONTROL_NONE;
|
||||
huart1.Init.OverSampling = UART_OVERSAMPLING_8;
|
||||
huart1.Init.OneBitSampling = UART_ONE_BIT_SAMPLE_DISABLE;
|
||||
huart1.Init.ClockPrescaler = UART_PRESCALER_DIV1;
|
||||
huart1.AdvancedInit.AdvFeatureInit = UART_ADVFEATURE_NO_INIT;
|
||||
if (HAL_UART_Init(&huart1) != HAL_OK)
|
||||
{
|
||||
Error_Handler();
|
||||
}
|
||||
if (HAL_UARTEx_SetTxFifoThreshold(&huart1, UART_TXFIFO_THRESHOLD_1_8) != HAL_OK)
|
||||
{
|
||||
Error_Handler();
|
||||
}
|
||||
if (HAL_UARTEx_SetRxFifoThreshold(&huart1, UART_RXFIFO_THRESHOLD_1_8) != HAL_OK)
|
||||
{
|
||||
Error_Handler();
|
||||
}
|
||||
if (HAL_UARTEx_DisableFifoMode(&huart1) != HAL_OK)
|
||||
{
|
||||
Error_Handler();
|
||||
}
|
||||
/* USER CODE BEGIN USART1_Init 2 */
|
||||
|
||||
/* USER CODE END USART1_Init 2 */
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief RF Initialization Function
|
||||
* @param None
|
||||
* @retval None
|
||||
*/
|
||||
static void MX_RF_Init(void)
|
||||
{
|
||||
|
||||
/* USER CODE BEGIN RF_Init 0 */
|
||||
|
||||
/* USER CODE END RF_Init 0 */
|
||||
|
||||
/* USER CODE BEGIN RF_Init 1 */
|
||||
|
||||
/* USER CODE END RF_Init 1 */
|
||||
/* USER CODE BEGIN RF_Init 2 */
|
||||
|
||||
/* USER CODE END RF_Init 2 */
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @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();
|
||||
}
|
||||
|
||||
/** Enable the WakeUp
|
||||
*/
|
||||
if (HAL_RTCEx_SetWakeUpTimer_IT(&hrtc, 0, RTC_WAKEUPCLOCK_RTCCLK_DIV16) != HAL_OK)
|
||||
{
|
||||
Error_Handler();
|
||||
}
|
||||
/* USER CODE BEGIN RTC_Init 2 */
|
||||
|
||||
/* USER CODE END RTC_Init 2 */
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* 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_Channel1_IRQn interrupt configuration */
|
||||
HAL_NVIC_SetPriority(DMA1_Channel1_IRQn, 0, 0);
|
||||
HAL_NVIC_EnableIRQ(DMA1_Channel1_IRQn);
|
||||
/* DMA1_Channel2_IRQn interrupt configuration */
|
||||
HAL_NVIC_SetPriority(DMA1_Channel2_IRQn, 0, 0);
|
||||
HAL_NVIC_EnableIRQ(DMA1_Channel2_IRQn);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief GPIO Initialization Function
|
||||
* @param None
|
||||
* @retval None
|
||||
*/
|
||||
static void MX_GPIO_Init(void)
|
||||
{
|
||||
/* USER CODE BEGIN MX_GPIO_Init_1 */
|
||||
/* USER CODE END MX_GPIO_Init_1 */
|
||||
|
||||
/* GPIO Ports Clock Enable */
|
||||
__HAL_RCC_GPIOC_CLK_ENABLE();
|
||||
__HAL_RCC_GPIOA_CLK_ENABLE();
|
||||
__HAL_RCC_GPIOB_CLK_ENABLE();
|
||||
|
||||
/* USER CODE BEGIN MX_GPIO_Init_2 */
|
||||
/* USER CODE END MX_GPIO_Init_2 */
|
||||
}
|
||||
|
||||
/* USER CODE BEGIN 4 */
|
||||
|
||||
/* USER CODE END 4 */
|
||||
|
||||
/**
|
||||
* @brief This function is executed in case of error occurrence.
|
||||
* @retval None
|
||||
*/
|
||||
void Error_Handler(void)
|
||||
{
|
||||
/* USER CODE BEGIN Error_Handler_Debug */
|
||||
/* User can add his own implementation to report the HAL error return state */
|
||||
__disable_irq();
|
||||
while (1)
|
||||
{
|
||||
}
|
||||
/* USER CODE END Error_Handler_Debug */
|
||||
}
|
||||
|
||||
#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 6 */
|
||||
/* User can add his own implementation to report the file name and line number,
|
||||
ex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */
|
||||
/* USER CODE END 6 */
|
||||
}
|
||||
#endif /* USE_FULL_ASSERT */
|
||||
353
Core/Src/stm32_lpm_if.c
Normal file
353
Core/Src/stm32_lpm_if.c
Normal file
@@ -0,0 +1,353 @@
|
||||
/* USER CODE BEGIN Header */
|
||||
/**
|
||||
***************************************************************************************
|
||||
* @file stm32_lpm_if.c
|
||||
* @author MCD Application Team
|
||||
* @brief Low layer function to enter/exit low power modes (stop, sleep).
|
||||
***************************************************************************************
|
||||
* @attention
|
||||
*
|
||||
* Copyright (c) 2019-2023 STMicroelectronics.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This software is licensed under terms that can be found in the LICENSE file
|
||||
* in the root directory of this software component.
|
||||
* If no LICENSE file comes with this software, it is provided AS-IS.
|
||||
*
|
||||
******************************************************************************
|
||||
*/
|
||||
/* USER CODE END Header */
|
||||
|
||||
/* 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 -----------------------------------------------*/
|
||||
static void Switch_On_HSI(void);
|
||||
static void EnterLowPower(void);
|
||||
static void ExitLowPower(void);
|
||||
/* USER CODE BEGIN Private_Function_Prototypes */
|
||||
|
||||
/* 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 */
|
||||
|
||||
/* Functions Definition ------------------------------------------------------*/
|
||||
/**
|
||||
* @brief Enters Low Power Off Mode
|
||||
* @param none
|
||||
* @retval none
|
||||
*/
|
||||
void PWR_EnterOffMode(void)
|
||||
{
|
||||
/* USER CODE BEGIN PWR_EnterOffMode_1 */
|
||||
|
||||
/* USER CODE END PWR_EnterOffMode_1 */
|
||||
/**
|
||||
* 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();
|
||||
|
||||
EnterLowPower();
|
||||
|
||||
/************************************************************************************
|
||||
* 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) || defined (__ARMCC_VERSION)
|
||||
__force_stores();
|
||||
#endif
|
||||
|
||||
__WFI();
|
||||
|
||||
/* USER CODE BEGIN PWR_EnterOffMode_2 */
|
||||
|
||||
/* USER CODE END PWR_EnterOffMode_2 */
|
||||
return;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Exits Low Power Off Mode
|
||||
* @param none
|
||||
* @retval none
|
||||
*/
|
||||
void PWR_ExitOffMode(void)
|
||||
{
|
||||
/* USER CODE BEGIN PWR_ExitOffMode_1 */
|
||||
|
||||
/* USER CODE END PWR_ExitOffMode_1 */
|
||||
HAL_ResumeTick();
|
||||
/* USER CODE BEGIN PWR_ExitOffMode_2 */
|
||||
|
||||
/* USER CODE END PWR_ExitOffMode_2 */
|
||||
return;
|
||||
}
|
||||
|
||||
/**
|
||||
* @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_1 */
|
||||
|
||||
/* USER CODE END PWR_EnterStopMode_1 */
|
||||
/**
|
||||
* 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
|
||||
*/
|
||||
EnterLowPower();
|
||||
|
||||
/************************************************************************************
|
||||
* ENTER STOP MODE
|
||||
***********************************************************************************/
|
||||
LL_PWR_SetPowerMode(LL_PWR_MODE_STOP2);
|
||||
|
||||
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) || defined (__ARMCC_VERSION)
|
||||
__force_stores();
|
||||
#endif
|
||||
|
||||
__WFI();
|
||||
|
||||
/* USER CODE BEGIN PWR_EnterStopMode_2 */
|
||||
|
||||
/* USER CODE END PWR_EnterStopMode_2 */
|
||||
return;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Exits Low Power Stop Mode
|
||||
* @note Enable the pll at 32MHz
|
||||
* @param none
|
||||
* @retval none
|
||||
*/
|
||||
void PWR_ExitStopMode(void)
|
||||
{
|
||||
/* USER CODE BEGIN PWR_ExitStopMode_1 */
|
||||
|
||||
/* USER CODE END PWR_ExitStopMode_1 */
|
||||
/**
|
||||
* This function is called from CRITICAL SECTION
|
||||
*/
|
||||
ExitLowPower();
|
||||
|
||||
HAL_ResumeTick();
|
||||
/* USER CODE BEGIN PWR_ExitStopMode_2 */
|
||||
|
||||
/* USER CODE END PWR_ExitStopMode_2 */
|
||||
return;
|
||||
}
|
||||
|
||||
/**
|
||||
* @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_1 */
|
||||
|
||||
/* USER CODE END PWR_EnterSleepMode_1 */
|
||||
|
||||
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) || defined (__ARMCC_VERSION)
|
||||
__force_stores();
|
||||
#endif
|
||||
|
||||
__WFI();
|
||||
/* USER CODE BEGIN PWR_EnterSleepMode_2 */
|
||||
|
||||
/* USER CODE END PWR_EnterSleepMode_2 */
|
||||
return;
|
||||
}
|
||||
|
||||
/**
|
||||
* @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_1 */
|
||||
|
||||
/* USER CODE END PWR_ExitSleepMode_1 */
|
||||
HAL_ResumeTick();
|
||||
/* USER CODE BEGIN PWR_ExitSleepMode_2 */
|
||||
|
||||
/* USER CODE END PWR_ExitSleepMode_2 */
|
||||
return;
|
||||
}
|
||||
|
||||
/*************************************************************
|
||||
*
|
||||
* LOCAL FUNCTIONS
|
||||
*
|
||||
*************************************************************/
|
||||
/**
|
||||
* @brief Setup the system to enter either stop or off mode
|
||||
* @param none
|
||||
* @retval none
|
||||
*/
|
||||
static void EnterLowPower(void)
|
||||
{
|
||||
/**
|
||||
* 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() || LL_PWR_IsActiveFlag_C2SB())
|
||||
{
|
||||
/* Release ENTRY_STOP_MODE semaphore */
|
||||
LL_HSEM_ReleaseLock(HSEM, CFG_HW_ENTRY_STOP_MODE_SEMID, 0);
|
||||
|
||||
Switch_On_HSI();
|
||||
__HAL_FLASH_SET_LATENCY(FLASH_LATENCY_0);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Switch_On_HSI();
|
||||
__HAL_FLASH_SET_LATENCY(FLASH_LATENCY_0);
|
||||
}
|
||||
|
||||
/* Release RCC semaphore */
|
||||
LL_HSEM_ReleaseLock(HSEM, CFG_HW_RCC_SEMID, 0);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Restore the system to exit stop mode
|
||||
* @param none
|
||||
* @retval none
|
||||
*/
|
||||
static void ExitLowPower(void)
|
||||
{
|
||||
/* 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));
|
||||
|
||||
if(LL_RCC_GetSysClkSource() == LL_RCC_SYS_CLKSOURCE_STATUS_HSI)
|
||||
{
|
||||
/* Restore the clock configuration of the application in this user section */
|
||||
/* USER CODE BEGIN ExitLowPower_1 */
|
||||
LL_RCC_HSE_Enable( );
|
||||
__HAL_FLASH_SET_LATENCY(FLASH_LATENCY_1);
|
||||
while(__HAL_FLASH_GET_LATENCY() != FLASH_LATENCY_1);
|
||||
while(!LL_RCC_HSE_IsReady( ));
|
||||
LL_RCC_SetSysClkSource(LL_RCC_SYS_CLKSOURCE_HSE);
|
||||
while (LL_RCC_GetSysClkSource( ) != LL_RCC_SYS_CLKSOURCE_STATUS_HSE);
|
||||
|
||||
/* USER CODE END ExitLowPower_1 */
|
||||
}
|
||||
else
|
||||
{
|
||||
/* If the application is not running on HSE restore the clock configuration in this user section */
|
||||
/* USER CODE BEGIN ExitLowPower_2 */
|
||||
|
||||
/* USER CODE END ExitLowPower_2 */
|
||||
}
|
||||
|
||||
/* Release RCC semaphore */
|
||||
LL_HSEM_ReleaseLock(HSEM, CFG_HW_RCC_SEMID, 0);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
/**
|
||||
* @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);
|
||||
return;
|
||||
}
|
||||
|
||||
/* USER CODE BEGIN Private_Functions */
|
||||
|
||||
/* USER CODE END Private_Functions */
|
||||
|
||||
427
Core/Src/stm32wbxx_hal_msp.c
Normal file
427
Core/Src/stm32wbxx_hal_msp.c
Normal file
@@ -0,0 +1,427 @@
|
||||
/* USER CODE BEGIN Header */
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file stm32wbxx_hal_msp.c
|
||||
* @brief This file provides code for the MSP Initialization
|
||||
* and de-Initialization codes.
|
||||
******************************************************************************
|
||||
* @attention
|
||||
*
|
||||
* Copyright (c) 2019-2023 STMicroelectronics.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This software is licensed under terms that can be found in the LICENSE file
|
||||
* in the root directory of this software component.
|
||||
* If no LICENSE file comes with this software, it is provided AS-IS.
|
||||
*
|
||||
******************************************************************************
|
||||
*/
|
||||
/* USER CODE END Header */
|
||||
|
||||
/* Includes ------------------------------------------------------------------*/
|
||||
#include "main.h"
|
||||
|
||||
/* USER CODE BEGIN Includes */
|
||||
|
||||
/* USER CODE END Includes */
|
||||
extern DMA_HandleTypeDef hdma_lpuart1_tx;
|
||||
|
||||
extern DMA_HandleTypeDef hdma_usart1_tx;
|
||||
|
||||
/* Private typedef -----------------------------------------------------------*/
|
||||
/* USER CODE BEGIN TD */
|
||||
|
||||
/* USER CODE END TD */
|
||||
|
||||
/* Private define ------------------------------------------------------------*/
|
||||
/* USER CODE BEGIN Define */
|
||||
|
||||
/* USER CODE END Define */
|
||||
|
||||
/* Private macro -------------------------------------------------------------*/
|
||||
/* USER CODE BEGIN Macro */
|
||||
|
||||
/* USER CODE END Macro */
|
||||
|
||||
/* Private variables ---------------------------------------------------------*/
|
||||
/* USER CODE BEGIN PV */
|
||||
|
||||
/* USER CODE END PV */
|
||||
|
||||
/* Private function prototypes -----------------------------------------------*/
|
||||
/* USER CODE BEGIN PFP */
|
||||
|
||||
/* USER CODE END PFP */
|
||||
|
||||
/* External functions --------------------------------------------------------*/
|
||||
/* USER CODE BEGIN ExternalFunctions */
|
||||
|
||||
/* USER CODE END ExternalFunctions */
|
||||
|
||||
/* USER CODE BEGIN 0 */
|
||||
|
||||
/* USER CODE END 0 */
|
||||
/**
|
||||
* Initializes the Global MSP.
|
||||
*/
|
||||
void HAL_MspInit(void)
|
||||
{
|
||||
/* USER CODE BEGIN MspInit 0 */
|
||||
|
||||
/* USER CODE END MspInit 0 */
|
||||
|
||||
__HAL_RCC_HSEM_CLK_ENABLE();
|
||||
|
||||
/* System interrupt init*/
|
||||
|
||||
/* Peripheral interrupt init */
|
||||
/* PVD_PVM_IRQn interrupt configuration */
|
||||
HAL_NVIC_SetPriority(PVD_PVM_IRQn, 0, 0);
|
||||
HAL_NVIC_EnableIRQ(PVD_PVM_IRQn);
|
||||
/* FLASH_IRQn interrupt configuration */
|
||||
HAL_NVIC_SetPriority(FLASH_IRQn, 0, 0);
|
||||
HAL_NVIC_EnableIRQ(FLASH_IRQn);
|
||||
/* RCC_IRQn interrupt configuration */
|
||||
HAL_NVIC_SetPriority(RCC_IRQn, 0, 0);
|
||||
HAL_NVIC_EnableIRQ(RCC_IRQn);
|
||||
/* C2SEV_PWR_C2H_IRQn interrupt configuration */
|
||||
HAL_NVIC_SetPriority(C2SEV_PWR_C2H_IRQn, 0, 0);
|
||||
HAL_NVIC_EnableIRQ(C2SEV_PWR_C2H_IRQn);
|
||||
/* PWR_SOTF_BLEACT_802ACT_RFPHASE_IRQn interrupt configuration */
|
||||
HAL_NVIC_SetPriority(PWR_SOTF_BLEACT_802ACT_RFPHASE_IRQn, 0, 0);
|
||||
HAL_NVIC_EnableIRQ(PWR_SOTF_BLEACT_802ACT_RFPHASE_IRQn);
|
||||
/* HSEM_IRQn interrupt configuration */
|
||||
HAL_NVIC_SetPriority(HSEM_IRQn, 0, 0);
|
||||
HAL_NVIC_EnableIRQ(HSEM_IRQn);
|
||||
/* FPU_IRQn interrupt configuration */
|
||||
HAL_NVIC_SetPriority(FPU_IRQn, 0, 0);
|
||||
HAL_NVIC_EnableIRQ(FPU_IRQn);
|
||||
|
||||
/* USER CODE BEGIN MspInit 1 */
|
||||
|
||||
/* USER CODE END MspInit 1 */
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief IPCC MSP Initialization
|
||||
* This function configures the hardware resources used in this example
|
||||
* @param hipcc: IPCC handle pointer
|
||||
* @retval None
|
||||
*/
|
||||
void HAL_IPCC_MspInit(IPCC_HandleTypeDef* hipcc)
|
||||
{
|
||||
if(hipcc->Instance==IPCC)
|
||||
{
|
||||
/* USER CODE BEGIN IPCC_MspInit 0 */
|
||||
|
||||
/* USER CODE END IPCC_MspInit 0 */
|
||||
/* Peripheral clock enable */
|
||||
__HAL_RCC_IPCC_CLK_ENABLE();
|
||||
/* IPCC interrupt Init */
|
||||
HAL_NVIC_SetPriority(IPCC_C1_RX_IRQn, 0, 0);
|
||||
HAL_NVIC_EnableIRQ(IPCC_C1_RX_IRQn);
|
||||
HAL_NVIC_SetPriority(IPCC_C1_TX_IRQn, 0, 0);
|
||||
HAL_NVIC_EnableIRQ(IPCC_C1_TX_IRQn);
|
||||
/* USER CODE BEGIN IPCC_MspInit 1 */
|
||||
|
||||
/* USER CODE END IPCC_MspInit 1 */
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief IPCC MSP De-Initialization
|
||||
* This function freeze the hardware resources used in this example
|
||||
* @param hipcc: IPCC handle pointer
|
||||
* @retval None
|
||||
*/
|
||||
void HAL_IPCC_MspDeInit(IPCC_HandleTypeDef* hipcc)
|
||||
{
|
||||
if(hipcc->Instance==IPCC)
|
||||
{
|
||||
/* USER CODE BEGIN IPCC_MspDeInit 0 */
|
||||
|
||||
/* USER CODE END IPCC_MspDeInit 0 */
|
||||
/* Peripheral clock disable */
|
||||
__HAL_RCC_IPCC_CLK_DISABLE();
|
||||
|
||||
/* IPCC interrupt DeInit */
|
||||
HAL_NVIC_DisableIRQ(IPCC_C1_RX_IRQn);
|
||||
HAL_NVIC_DisableIRQ(IPCC_C1_TX_IRQn);
|
||||
/* USER CODE BEGIN IPCC_MspDeInit 1 */
|
||||
|
||||
/* USER CODE END IPCC_MspDeInit 1 */
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @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)
|
||||
{
|
||||
GPIO_InitTypeDef GPIO_InitStruct = {0};
|
||||
RCC_PeriphCLKInitTypeDef PeriphClkInitStruct = {0};
|
||||
if(huart->Instance==LPUART1)
|
||||
{
|
||||
/* USER CODE BEGIN LPUART1_MspInit 0 */
|
||||
|
||||
/* USER CODE END LPUART1_MspInit 0 */
|
||||
|
||||
/** Initializes the peripherals clock
|
||||
*/
|
||||
PeriphClkInitStruct.PeriphClockSelection = RCC_PERIPHCLK_LPUART1;
|
||||
PeriphClkInitStruct.Lpuart1ClockSelection = RCC_LPUART1CLKSOURCE_PCLK1;
|
||||
if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInitStruct) != HAL_OK)
|
||||
{
|
||||
Error_Handler();
|
||||
}
|
||||
|
||||
/* Peripheral clock enable */
|
||||
__HAL_RCC_LPUART1_CLK_ENABLE();
|
||||
|
||||
__HAL_RCC_GPIOA_CLK_ENABLE();
|
||||
/**LPUART1 GPIO Configuration
|
||||
PA2 ------> LPUART1_TX
|
||||
PA3 ------> LPUART1_RX
|
||||
*/
|
||||
GPIO_InitStruct.Pin = GPIO_PIN_2|GPIO_PIN_3;
|
||||
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
|
||||
GPIO_InitStruct.Pull = GPIO_NOPULL;
|
||||
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
|
||||
GPIO_InitStruct.Alternate = GPIO_AF8_LPUART1;
|
||||
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
|
||||
|
||||
/* LPUART1 DMA Init */
|
||||
/* LPUART1_TX Init */
|
||||
hdma_lpuart1_tx.Instance = DMA1_Channel1;
|
||||
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();
|
||||
}
|
||||
|
||||
__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 */
|
||||
}
|
||||
else if(huart->Instance==USART1)
|
||||
{
|
||||
/* USER CODE BEGIN USART1_MspInit 0 */
|
||||
|
||||
/* USER CODE END USART1_MspInit 0 */
|
||||
|
||||
/** Initializes the peripherals clock
|
||||
*/
|
||||
PeriphClkInitStruct.PeriphClockSelection = RCC_PERIPHCLK_USART1;
|
||||
PeriphClkInitStruct.Usart1ClockSelection = RCC_USART1CLKSOURCE_PCLK2;
|
||||
if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInitStruct) != HAL_OK)
|
||||
{
|
||||
Error_Handler();
|
||||
}
|
||||
|
||||
/* Peripheral clock enable */
|
||||
__HAL_RCC_USART1_CLK_ENABLE();
|
||||
|
||||
__HAL_RCC_GPIOA_CLK_ENABLE();
|
||||
__HAL_RCC_GPIOB_CLK_ENABLE();
|
||||
/**USART1 GPIO Configuration
|
||||
PA11 ------> USART1_CTS
|
||||
PB6 ------> USART1_TX
|
||||
PB7 ------> USART1_RX
|
||||
*/
|
||||
GPIO_InitStruct.Pin = GPIO_PIN_11;
|
||||
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
|
||||
GPIO_InitStruct.Pull = GPIO_NOPULL;
|
||||
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
|
||||
GPIO_InitStruct.Alternate = GPIO_AF7_USART1;
|
||||
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
|
||||
|
||||
GPIO_InitStruct.Pin = GPIO_PIN_6|GPIO_PIN_7;
|
||||
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
|
||||
GPIO_InitStruct.Pull = GPIO_NOPULL;
|
||||
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
|
||||
GPIO_InitStruct.Alternate = GPIO_AF7_USART1;
|
||||
HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
|
||||
|
||||
/* USART1 DMA Init */
|
||||
/* USART1_TX Init */
|
||||
hdma_usart1_tx.Instance = DMA1_Channel2;
|
||||
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 */
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @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(huart->Instance==LPUART1)
|
||||
{
|
||||
/* USER CODE BEGIN LPUART1_MspDeInit 0 */
|
||||
|
||||
/* USER CODE END LPUART1_MspDeInit 0 */
|
||||
/* Peripheral clock disable */
|
||||
__HAL_RCC_LPUART1_CLK_DISABLE();
|
||||
|
||||
/**LPUART1 GPIO Configuration
|
||||
PA2 ------> LPUART1_TX
|
||||
PA3 ------> LPUART1_RX
|
||||
*/
|
||||
HAL_GPIO_DeInit(GPIOA, GPIO_PIN_2|GPIO_PIN_3);
|
||||
|
||||
/* 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 */
|
||||
}
|
||||
else if(huart->Instance==USART1)
|
||||
{
|
||||
/* USER CODE BEGIN USART1_MspDeInit 0 */
|
||||
|
||||
/* USER CODE END USART1_MspDeInit 0 */
|
||||
/* Peripheral clock disable */
|
||||
__HAL_RCC_USART1_CLK_DISABLE();
|
||||
|
||||
/**USART1 GPIO Configuration
|
||||
PA11 ------> USART1_CTS
|
||||
PB6 ------> USART1_TX
|
||||
PB7 ------> USART1_RX
|
||||
*/
|
||||
HAL_GPIO_DeInit(GPIOA, GPIO_PIN_11);
|
||||
|
||||
HAL_GPIO_DeInit(GPIOB, GPIO_PIN_6|GPIO_PIN_7);
|
||||
|
||||
/* 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 */
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @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)
|
||||
{
|
||||
RCC_PeriphCLKInitTypeDef PeriphClkInitStruct = {0};
|
||||
if(hrtc->Instance==RTC)
|
||||
{
|
||||
/* USER CODE BEGIN RTC_MspInit 0 */
|
||||
/* Enable access to the RTC registers */
|
||||
HAL_PWR_EnableBkUpAccess();
|
||||
|
||||
/*
|
||||
* 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();
|
||||
|
||||
/* Select LSE as RTC Input */
|
||||
__HAL_RCC_RTC_CONFIG(RCC_RTCCLKSOURCE_LSE);
|
||||
|
||||
/* USER CODE END RTC_MspInit 0 */
|
||||
|
||||
/** Initializes the peripherals clock
|
||||
*/
|
||||
PeriphClkInitStruct.PeriphClockSelection = RCC_PERIPHCLK_RTC;
|
||||
PeriphClkInitStruct.RTCClockSelection = RCC_RTCCLKSOURCE_LSE;
|
||||
if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInitStruct) != HAL_OK)
|
||||
{
|
||||
Error_Handler();
|
||||
}
|
||||
|
||||
/* Peripheral clock enable */
|
||||
__HAL_RCC_RTC_ENABLE();
|
||||
__HAL_RCC_RTCAPB_CLK_ENABLE();
|
||||
/* RTC interrupt Init */
|
||||
HAL_NVIC_SetPriority(RTC_WKUP_IRQn, 0, 0);
|
||||
HAL_NVIC_EnableIRQ(RTC_WKUP_IRQn);
|
||||
/* USER CODE BEGIN RTC_MspInit 1 */
|
||||
|
||||
MODIFY_REG(RTC->CR, RTC_CR_WUCKSEL, CFG_RTC_WUCKSEL_DIVIDER);
|
||||
/* 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();
|
||||
|
||||
/* RTC interrupt DeInit */
|
||||
HAL_NVIC_DisableIRQ(RTC_WKUP_IRQn);
|
||||
/* USER CODE BEGIN RTC_MspDeInit 1 */
|
||||
|
||||
/* USER CODE END RTC_MspDeInit 1 */
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/* USER CODE BEGIN 1 */
|
||||
|
||||
/* USER CODE END 1 */
|
||||
431
Core/Src/stm32wbxx_it.c
Normal file
431
Core/Src/stm32wbxx_it.c
Normal file
@@ -0,0 +1,431 @@
|
||||
/* USER CODE BEGIN Header */
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file stm32wbxx_it.c
|
||||
* @brief Interrupt Service Routines.
|
||||
******************************************************************************
|
||||
* @attention
|
||||
*
|
||||
* Copyright (c) 2020-2023 STMicroelectronics.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This software is licensed under terms that can be found in the LICENSE file
|
||||
* in the root directory of this software component.
|
||||
* If no LICENSE file comes with this software, it is provided AS-IS.
|
||||
*
|
||||
******************************************************************************
|
||||
*/
|
||||
/* USER CODE END Header */
|
||||
|
||||
/* Includes ------------------------------------------------------------------*/
|
||||
#include "main.h"
|
||||
#include "stm32wbxx_it.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 --------------------------------------------------------*/
|
||||
extern IPCC_HandleTypeDef hipcc;
|
||||
extern DMA_HandleTypeDef hdma_lpuart1_tx;
|
||||
extern DMA_HandleTypeDef hdma_usart1_tx;
|
||||
extern UART_HandleTypeDef hlpuart1;
|
||||
extern UART_HandleTypeDef huart1;
|
||||
extern RTC_HandleTypeDef hrtc;
|
||||
/* 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 */
|
||||
while (1)
|
||||
{
|
||||
}
|
||||
/* USER CODE END NonMaskableInt_IRQn 1 */
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief This function handles Hard fault interrupt.
|
||||
*/
|
||||
void HardFault_Handler(void)
|
||||
{
|
||||
/* USER CODE BEGIN HardFault_IRQn 0 */
|
||||
|
||||
/* 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 PVD/PVM0/PVM2 interrupts through EXTI lines 16/31/33.
|
||||
*/
|
||||
void PVD_PVM_IRQHandler(void)
|
||||
{
|
||||
/* USER CODE BEGIN PVD_PVM_IRQn 0 */
|
||||
|
||||
/* USER CODE END PVD_PVM_IRQn 0 */
|
||||
HAL_PWREx_PVD_PVM_IRQHandler();
|
||||
/* USER CODE BEGIN PVD_PVM_IRQn 1 */
|
||||
|
||||
/* USER CODE END PVD_PVM_IRQn 1 */
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief This function handles RTC wake-up interrupt through EXTI line 19.
|
||||
*/
|
||||
void RTC_WKUP_IRQHandler(void)
|
||||
{
|
||||
/* USER CODE BEGIN RTC_WKUP_IRQn 0 */
|
||||
|
||||
/* USER CODE END RTC_WKUP_IRQn 0 */
|
||||
HAL_RTCEx_WakeUpTimerIRQHandler(&hrtc);
|
||||
/* USER CODE BEGIN RTC_WKUP_IRQn 1 */
|
||||
|
||||
/* USER CODE END RTC_WKUP_IRQn 1 */
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief This function handles Flash global interrupt.
|
||||
*/
|
||||
void FLASH_IRQHandler(void)
|
||||
{
|
||||
/* USER CODE BEGIN FLASH_IRQn 0 */
|
||||
|
||||
/* USER CODE END FLASH_IRQn 0 */
|
||||
HAL_FLASH_IRQHandler();
|
||||
/* USER CODE BEGIN FLASH_IRQn 1 */
|
||||
|
||||
/* USER CODE END FLASH_IRQn 1 */
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief This function handles RCC global interrupt.
|
||||
*/
|
||||
void RCC_IRQHandler(void)
|
||||
{
|
||||
/* USER CODE BEGIN RCC_IRQn 0 */
|
||||
|
||||
/* USER CODE END RCC_IRQn 0 */
|
||||
/* USER CODE BEGIN RCC_IRQn 1 */
|
||||
|
||||
/* USER CODE END RCC_IRQn 1 */
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief This function handles DMA1 channel1 global interrupt.
|
||||
*/
|
||||
void DMA1_Channel1_IRQHandler(void)
|
||||
{
|
||||
/* USER CODE BEGIN DMA1_Channel1_IRQn 0 */
|
||||
|
||||
/* USER CODE END DMA1_Channel1_IRQn 0 */
|
||||
HAL_DMA_IRQHandler(&hdma_lpuart1_tx);
|
||||
/* USER CODE BEGIN DMA1_Channel1_IRQn 1 */
|
||||
|
||||
/* USER CODE END DMA1_Channel1_IRQn 1 */
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief This function handles DMA1 channel2 global interrupt.
|
||||
*/
|
||||
void DMA1_Channel2_IRQHandler(void)
|
||||
{
|
||||
/* USER CODE BEGIN DMA1_Channel2_IRQn 0 */
|
||||
|
||||
/* USER CODE END DMA1_Channel2_IRQn 0 */
|
||||
HAL_DMA_IRQHandler(&hdma_usart1_tx);
|
||||
/* USER CODE BEGIN DMA1_Channel2_IRQn 1 */
|
||||
|
||||
/* USER CODE END DMA1_Channel2_IRQn 1 */
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief This function handles CPU2 SEV interrupt through EXTI line 40 and PWR CPU2 HOLD wake-up interrupt.
|
||||
*/
|
||||
void C2SEV_PWR_C2H_IRQHandler(void)
|
||||
{
|
||||
/* USER CODE BEGIN C2SEV_PWR_C2H_IRQn 0 */
|
||||
|
||||
/* USER CODE END C2SEV_PWR_C2H_IRQn 0 */
|
||||
/* USER CODE BEGIN C2SEV_PWR_C2H_IRQn 1 */
|
||||
|
||||
/* USER CODE END C2SEV_PWR_C2H_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 */
|
||||
HAL_UART_IRQHandler(&huart1);
|
||||
/* 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 */
|
||||
HAL_UART_IRQHandler(&hlpuart1);
|
||||
/* USER CODE BEGIN LPUART1_IRQn 1 */
|
||||
|
||||
/* USER CODE END LPUART1_IRQn 1 */
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief This function handles PWR switching on the fly, end of BLE activity, end of 802.15.4 activity, end of critical radio phase interrupt.
|
||||
*/
|
||||
void PWR_SOTF_BLEACT_802ACT_RFPHASE_IRQHandler(void)
|
||||
{
|
||||
/* USER CODE BEGIN PWR_SOTF_BLEACT_802ACT_RFPHASE_IRQn 0 */
|
||||
|
||||
/* USER CODE END PWR_SOTF_BLEACT_802ACT_RFPHASE_IRQn 0 */
|
||||
/* USER CODE BEGIN PWR_SOTF_BLEACT_802ACT_RFPHASE_IRQn 1 */
|
||||
|
||||
/* USER CODE END PWR_SOTF_BLEACT_802ACT_RFPHASE_IRQn 1 */
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief This function handles IPCC RX occupied interrupt.
|
||||
*/
|
||||
void IPCC_C1_RX_IRQHandler(void)
|
||||
{
|
||||
/* USER CODE BEGIN IPCC_C1_RX_IRQn 0 */
|
||||
|
||||
/* USER CODE END IPCC_C1_RX_IRQn 0 */
|
||||
HAL_IPCC_RX_IRQHandler(&hipcc);
|
||||
/* USER CODE BEGIN IPCC_C1_RX_IRQn 1 */
|
||||
|
||||
/* USER CODE END IPCC_C1_RX_IRQn 1 */
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief This function handles IPCC TX free interrupt.
|
||||
*/
|
||||
void IPCC_C1_TX_IRQHandler(void)
|
||||
{
|
||||
/* USER CODE BEGIN IPCC_C1_TX_IRQn 0 */
|
||||
|
||||
/* USER CODE END IPCC_C1_TX_IRQn 0 */
|
||||
HAL_IPCC_TX_IRQHandler(&hipcc);
|
||||
/* USER CODE BEGIN IPCC_C1_TX_IRQn 1 */
|
||||
|
||||
/* USER CODE END IPCC_C1_TX_IRQn 1 */
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief This function handles HSEM global interrupt.
|
||||
*/
|
||||
void HSEM_IRQHandler(void)
|
||||
{
|
||||
/* USER CODE BEGIN HSEM_IRQn 0 */
|
||||
|
||||
/* USER CODE END HSEM_IRQn 0 */
|
||||
HAL_HSEM_IRQHandler();
|
||||
/* USER CODE BEGIN HSEM_IRQn 1 */
|
||||
|
||||
/* USER CODE END HSEM_IRQn 1 */
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief This function handles FPU global interrupt.
|
||||
*/
|
||||
void FPU_IRQHandler(void)
|
||||
{
|
||||
/* USER CODE BEGIN FPU_IRQn 0 */
|
||||
|
||||
/* USER CODE END FPU_IRQn 0 */
|
||||
/* USER CODE BEGIN FPU_IRQn 1 */
|
||||
|
||||
/* USER CODE END FPU_IRQn 1 */
|
||||
}
|
||||
|
||||
/* USER CODE BEGIN 1 */
|
||||
|
||||
|
||||
/**
|
||||
* @brief This function handles External External line 4 interrupt request.
|
||||
* @param None
|
||||
* @retval None
|
||||
*/
|
||||
void EXTI4_IRQHandler(void)
|
||||
{
|
||||
HAL_GPIO_EXTI_IRQHandler(BUTTON_SW1_PIN);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief This function handles External External line 0 interrupt request.
|
||||
* @param None
|
||||
* @retval None
|
||||
*/
|
||||
void EXTI0_IRQHandler(void)
|
||||
{
|
||||
HAL_GPIO_EXTI_IRQHandler(BUTTON_SW2_PIN);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief This function handles External External line 1 interrupt request.
|
||||
* @param None
|
||||
* @retval None
|
||||
*/
|
||||
void EXTI1_IRQHandler(void)
|
||||
{
|
||||
HAL_GPIO_EXTI_IRQHandler(BUTTON_SW3_PIN);
|
||||
}
|
||||
|
||||
/* USER CODE END 1 */
|
||||
203
Core/Src/stm_logging.c
Normal file
203
Core/Src/stm_logging.c
Normal file
@@ -0,0 +1,203 @@
|
||||
/* USER CODE BEGIN Header */
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file stm_logging.c
|
||||
* @author MCD Application Team
|
||||
* @brief This file contains all the defines and functions used
|
||||
* for logging on Application examples.
|
||||
******************************************************************************
|
||||
* @attention
|
||||
*
|
||||
* Copyright (c) 2019-2023 STMicroelectronics.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This software is licensed under terms that can be found in the LICENSE file
|
||||
* in the root directory of this software component.
|
||||
* If no LICENSE file comes with this software, it is provided AS-IS.
|
||||
*
|
||||
******************************************************************************
|
||||
*/
|
||||
/* 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[input] 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_ZIGBEE_API:
|
||||
strcpy(logRegionString, "[M4 ZIGBEE 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[input] 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[input] 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,
|
||||
HAL_GetTick());
|
||||
}
|
||||
#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 */
|
||||
}
|
||||
366
Core/Src/system_stm32wbxx.c
Normal file
366
Core/Src/system_stm32wbxx.c
Normal file
@@ -0,0 +1,366 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* @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
|
||||
*
|
||||
* Copyright (c) 2020-2021 STMicroelectronics.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This software is licensed under terms that can be found in the LICENSE file
|
||||
* in the root directory of this software component.
|
||||
* If no LICENSE file comes with this software, it is provided AS-IS.
|
||||
*
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
/** @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
|
||||
* @{
|
||||
*/
|
||||
|
||||
/* Note: Following vector table addresses must be defined in line with linker
|
||||
configuration. */
|
||||
/*!< Uncomment the following line if you need to relocate CPU1 CM4 and/or CPU2
|
||||
CM0+ vector table anywhere in Sram or Flash. Else vector table will be kept
|
||||
at address 0x00 which correspond to automatic remap of boot address selected */
|
||||
/* #define USER_VECT_TAB_ADDRESS */
|
||||
#if defined(USER_VECT_TAB_ADDRESS)
|
||||
/*!< Uncomment this line for user vector table remap in Sram else user remap
|
||||
will be done in Flash. */
|
||||
/* #define VECT_TAB_SRAM */
|
||||
#if defined(VECT_TAB_SRAM)
|
||||
#define VECT_TAB_BASE_ADDRESS SRAM1_BASE /*!< Vector Table base address field.
|
||||
This value must be a multiple of 0x200. */
|
||||
#define VECT_TAB_OFFSET 0x00000000U /*!< Vector Table base offset field.
|
||||
This value must be a multiple of 0x200. */
|
||||
#else
|
||||
#define VECT_TAB_BASE_ADDRESS FLASH_BASE /*!< Vector Table base address field.
|
||||
This value must be a multiple of 0x200. */
|
||||
#define VECT_TAB_OFFSET 0x00000000U /*!< Vector Table base offset field.
|
||||
This value must be a multiple of 0x200. */
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/** @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 */
|
||||
|
||||
#if defined(STM32WB55xx) || defined(STM32WB5Mxx) || defined(STM32WB35xx) || defined (STM32WB15xx)
|
||||
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}};
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/** @addtogroup STM32WBxx_System_Private_FunctionPrototypes
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/** @addtogroup STM32WBxx_System_Private_Functions
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief Setup the microcontroller system.
|
||||
* @param None
|
||||
* @retval None
|
||||
*/
|
||||
void SystemInit(void)
|
||||
{
|
||||
#if defined(USER_VECT_TAB_ADDRESS)
|
||||
/* Configure the Vector Table location add offset address ------------------*/
|
||||
SCB->VTOR = VECT_TAB_BASE_ADDRESS | VECT_TAB_OFFSET;
|
||||
#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) || defined(STM32WB5Mxx)
|
||||
/* 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;
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
Reference in New Issue
Block a user