/* USER CODE BEGIN Header */ /** ****************************************************************************** * @file sys_app.c * @author MCD Application Team * @brief Initializes HW and SW system entities (not related to the radio) ****************************************************************************** * @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 #include "platform.h" #include "sys_app.h" #include "adc_if.h" #include "stm32_seq.h" #include "stm32_systime.h" #include "stm32_lpm.h" #include "timer_if.h" #include "utilities_def.h" #include "sys_debug.h" #include "sys_sensors.h" /* USER CODE BEGIN Includes */ /* USER CODE END Includes */ /* External variables ---------------------------------------------------------*/ /* USER CODE BEGIN EV */ /* USER CODE END EV */ /* Private typedef -----------------------------------------------------------*/ /* USER CODE BEGIN PTD */ /* USER CODE END PTD */ /* Private define ------------------------------------------------------------*/ #define MAX_TS_SIZE (int) 16 /** * Defines the maximum battery level */ #define LORAWAN_MAX_BAT 254 /* USER CODE BEGIN PD */ /* USER CODE END PD */ /* Private macro -------------------------------------------------------------*/ /* USER CODE BEGIN PM */ /* USER CODE END PM */ /* Private variables ---------------------------------------------------------*/ static uint8_t SYS_TimerInitialisedFlag = 0; /* USER CODE BEGIN PV */ /* USER CODE END PV */ /* Private function prototypes -----------------------------------------------*/ /** * @brief Returns sec and msec based on the systime in use * @param buff to update with timestamp * @param size of updated buffer */ static void TimestampNow(uint8_t *buff, uint16_t *size); /** * @brief it calls UTIL_ADV_TRACE_VSNPRINTF */ static void tiny_snprintf_like(char *buf, uint32_t maxsize, const char *strFormat, ...); /* USER CODE BEGIN PFP */ /* USER CODE END PFP */ /* Exported functions ---------------------------------------------------------*/ void SystemApp_Init(void) { /* USER CODE BEGIN SystemApp_Init_1 */ /* USER CODE END SystemApp_Init_1 */ /* Ensure that MSI is wake-up system clock */ __HAL_RCC_WAKEUPSTOP_CLK_CONFIG(RCC_STOP_WAKEUPCLOCK_MSI); /*Initialize timer and RTC*/ UTIL_TIMER_Init(); SYS_TimerInitialisedFlag = 1; /* Initializes the SW probes pins and the monitor RF pins via Alternate Function */ DBG_Init(); /*Initialize the terminal */ UTIL_ADV_TRACE_Init(); UTIL_ADV_TRACE_RegisterTimeStampFunction(TimestampNow); /* #warning "should be removed when proper obl is done" */ __HAL_FLASH_CLEAR_FLAG(FLASH_FLAG_OPTVERR); /*Set verbose LEVEL*/ UTIL_ADV_TRACE_SetVerboseLevel(VERBOSE_LEVEL); /*Initialize the temperature and Battery measurement services */ SYS_InitMeasurement(); /*Initialize the Sensors */ EnvSensors_Init(); // LED1 Flash 3 times for normal power on LED1_TOGGLE; HAL_Delay(500); LED1_TOGGLE; HAL_Delay(500); LED1_TOGGLE; HAL_Delay(500); LED1_TOGGLE; HAL_Delay(500); LED1_TOGGLE; HAL_Delay(500); LED1_TOGGLE; /*Init low power manager*/ UTIL_LPM_Init(); /* Disable Stand-by mode */ UTIL_LPM_SetOffMode((1 << CFG_LPM_APPLI_Id), UTIL_LPM_DISABLE); #if defined (LOW_POWER_DISABLE) && (LOW_POWER_DISABLE == 1) /* Disable Stop Mode */ UTIL_LPM_SetStopMode((1 << CFG_LPM_APPLI_Id), UTIL_LPM_DISABLE); #elif !defined (LOW_POWER_DISABLE) #error LOW_POWER_DISABLE not defined #endif /* LOW_POWER_DISABLE */ /* USER CODE BEGIN SystemApp_Init_2 */ /* USER CODE END SystemApp_Init_2 */ } /** * @brief redefines __weak function in stm32_seq.c such to enter low power */ void UTIL_SEQ_Idle(void) { /* USER CODE BEGIN UTIL_SEQ_Idle_1 */ /* USER CODE END UTIL_SEQ_Idle_1 */ UTIL_LPM_EnterLowPower(); /* USER CODE BEGIN UTIL_SEQ_Idle_2 */ /* USER CODE END UTIL_SEQ_Idle_2 */ } uint8_t GetBatteryLevel(void) { uint8_t batteryLevel = 0; uint16_t batteryLevelmV; /* USER CODE BEGIN GetBatteryLevel_0 */ /* USER CODE END GetBatteryLevel_0 */ batteryLevelmV = (uint16_t) SYS_GetBatteryLevel(); /* Convert battery level from mV to linear scale: 1 (very low) to 254 (fully charged) */ if (batteryLevelmV > VDD_BAT) { batteryLevel = LORAWAN_MAX_BAT; } else if (batteryLevelmV < VDD_MIN) { batteryLevel = 0; } else { batteryLevel = (((uint32_t)(batteryLevelmV - VDD_MIN) * LORAWAN_MAX_BAT) / (VDD_BAT - VDD_MIN)); } /* USER CODE BEGIN GetBatteryLevel_2 */ /* USER CODE END GetBatteryLevel_2 */ return batteryLevel; /* 1 (very low) to 254 (fully charged) */ } int16_t GetTemperatureLevel(void) { int16_t temperatureLevel = 0; sensor_t sensor_data; EnvSensors_Read(&sensor_data); temperatureLevel = (int16_t)(sensor_data.temperature); /* USER CODE BEGIN GetTemperatureLevel */ /* USER CODE END GetTemperatureLevel */ return temperatureLevel; } void GetUniqueId(uint8_t *id) { /* USER CODE BEGIN GetUniqueId_1 */ /* USER CODE END GetUniqueId_1 */ uint32_t val = 0; val = LL_FLASH_GetUDN(); if (val == 0xFFFFFFFF) /* Normally this should not happen */ { uint32_t ID_1_3_val = HAL_GetUIDw0() + HAL_GetUIDw2(); uint32_t ID_2_val = HAL_GetUIDw1(); id[7] = (ID_1_3_val) >> 24; id[6] = (ID_1_3_val) >> 16; id[5] = (ID_1_3_val) >> 8; id[4] = (ID_1_3_val); id[3] = (ID_2_val) >> 24; id[2] = (ID_2_val) >> 16; id[1] = (ID_2_val) >> 8; id[0] = (ID_2_val); } else /* Typical use case */ { id[7] = val & 0xFF; id[6] = (val >> 8) & 0xFF; id[5] = (val >> 16) & 0xFF; id[4] = (val >> 24) & 0xFF; val = LL_FLASH_GetDeviceID(); id[3] = val & 0xFF; val = LL_FLASH_GetSTCompanyID(); id[2] = val & 0xFF; id[1] = (val >> 8) & 0xFF; id[0] = (val >> 16) & 0xFF; } /* USER CODE BEGIN GetUniqueId_2 */ /* USER CODE END GetUniqueId_2 */ } void GetDevAddr(uint32_t *devAddr) { /* USER CODE BEGIN GetDevAddr_1 */ /* USER CODE END GetDevAddr_1 */ *devAddr = LL_FLASH_GetUDN(); if (*devAddr == 0xFFFFFFFF) { *devAddr = ((HAL_GetUIDw0()) ^ (HAL_GetUIDw1()) ^ (HAL_GetUIDw2())); } /* USER CODE BEGIN GetDevAddr_2 */ /* USER CODE END GetDevAddr_2 */ } /* USER CODE BEGIN EF */ /* USER CODE END EF */ /* Private functions ---------------------------------------------------------*/ static void TimestampNow(uint8_t *buff, uint16_t *size) { /* USER CODE BEGIN TimestampNow_1 */ /* USER CODE END TimestampNow_1 */ SysTime_t curtime = SysTimeGet(); tiny_snprintf_like((char *)buff, MAX_TS_SIZE, "%ds%03d:", curtime.Seconds, curtime.SubSeconds); *size = strlen((char *)buff); /* USER CODE BEGIN TimestampNow_2 */ /* USER CODE END TimestampNow_2 */ } /* Disable StopMode when traces need to be printed */ void UTIL_ADV_TRACE_PreSendHook(void) { /* USER CODE BEGIN UTIL_ADV_TRACE_PreSendHook_1 */ /* USER CODE END UTIL_ADV_TRACE_PreSendHook_1 */ UTIL_LPM_SetStopMode((1 << CFG_LPM_UART_TX_Id), UTIL_LPM_DISABLE); /* USER CODE BEGIN UTIL_ADV_TRACE_PreSendHook_2 */ /* USER CODE END UTIL_ADV_TRACE_PreSendHook_2 */ } /* Re-enable StopMode when traces have been printed */ void UTIL_ADV_TRACE_PostSendHook(void) { /* USER CODE BEGIN UTIL_LPM_SetStopMode_1 */ /* USER CODE END UTIL_LPM_SetStopMode_1 */ UTIL_LPM_SetStopMode((1 << CFG_LPM_UART_TX_Id), UTIL_LPM_ENABLE); /* USER CODE BEGIN UTIL_LPM_SetStopMode_2 */ /* USER CODE END UTIL_LPM_SetStopMode_2 */ } static void tiny_snprintf_like(char *buf, uint32_t maxsize, const char *strFormat, ...) { /* USER CODE BEGIN tiny_snprintf_like_1 */ /* USER CODE END tiny_snprintf_like_1 */ va_list vaArgs; va_start(vaArgs, strFormat); UTIL_ADV_TRACE_VSNPRINTF(buf, maxsize, strFormat, vaArgs); va_end(vaArgs); /* USER CODE BEGIN tiny_snprintf_like_2 */ /* USER CODE END tiny_snprintf_like_2 */ } /* USER CODE BEGIN PrFD */ /* USER CODE END PrFD */ /* HAL overload functions ---------------------------------------------------------*/ /** * @note This function overwrites the __weak one from HAL */ HAL_StatusTypeDef HAL_InitTick(uint32_t TickPriority) { /*Don't enable SysTick if TIMER_IF is based on other counters (e.g. RTC) */ /* USER CODE BEGIN HAL_InitTick_1 */ /* USER CODE END HAL_InitTick_1 */ return HAL_OK; /* USER CODE BEGIN HAL_InitTick_2 */ /* USER CODE END HAL_InitTick_2 */ } /** * @note This function overwrites the __weak one from HAL */ uint32_t HAL_GetTick(void) { uint32_t ret = 0; /* TIMER_IF can be based on other counter the SysTick e.g. RTC */ /* USER CODE BEGIN HAL_GetTick_1 */ /* USER CODE END HAL_GetTick_1 */ if (SYS_TimerInitialisedFlag == 0) { /* TIMER_IF_GetTimerValue should be used only once UTIL_TIMER_Init() is initialized */ /* If HAL_Delay or a TIMEOUT countdown is necessary during initialization phase */ /* please use temporarily another timebase source (SysTick or TIMx), which implies also */ /* to rework the above function HAL_InitTick() and to call HAL_IncTick() on the timebase IRQ */ /* Note: when TIMER_IF is based on RTC, stm32wlxx_hal_rtc.c calls this function before TimeServer is functional */ /* RTC TIMEOUT will not expire, i.e. if RTC has an hw problem it will keep looping in the RTC_Init function */ /* USER CODE BEGIN HAL_GetTick_EarlyCall */ /* USER CODE END HAL_GetTick_EarlyCall */ } else { ret = TIMER_IF_GetTimerValue(); } /* USER CODE BEGIN HAL_GetTick_2 */ /* USER CODE END HAL_GetTick_2 */ return ret; } /** * @note This function overwrites the __weak one from HAL */ void HAL_Delay(__IO uint32_t Delay) { /* TIMER_IF can be based on other counter the SysTick e.g. RTC */ /* USER CODE BEGIN HAL_Delay_1 */ /* USER CODE END HAL_Delay_1 */ TIMER_IF_DelayMs(Delay); /* USER CODE BEGIN HAL_Delay_2 */ /* USER CODE END HAL_Delay_2 */ } /* USER CODE BEGIN Overload_HAL_weaks */ /* USER CODE END Overload_HAL_weaks */