L14-Click 1.0
STM32WLE5CC LoRaWAN Sensor Platform
Loading...
Searching...
No Matches
stm32_lpm_if.c
Go to the documentation of this file.
1/* USER CODE BEGIN Header */
2/**
3 ******************************************************************************
4 * @file stm32_lpm_if.c
5 * @author MCD Application Team
6 * @brief Low layer function to enter/exit low power modes (stop, sleep)
7 ******************************************************************************
8 * @attention
9 *
10 * Copyright (c) 2026 STMicroelectronics.
11 * All rights reserved.
12 *
13 * This software is licensed under terms that can be found in the LICENSE file
14 * in the root directory of this software component.
15 * If no LICENSE file comes with this software, it is provided AS-IS.
16 *
17 ******************************************************************************
18 */
19/* USER CODE END Header */
20
21/* Includes ------------------------------------------------------------------*/
22#include "platform.h"
23#include "stm32_lpm.h"
24#include "stm32_lpm_if.h"
25#include "usart_if.h"
26
27/* USER CODE BEGIN Includes */
28#include "spi.h"
29#include "rtc.h"
30#include "adc.h"
31#include "lora_app.h"
32#include "timer_if.h"
33#include "mymems.h"
34#include "radio.h"
35#include "mysensors_base.h"
36#include "utils/utils.h"
37/* USER CODE END Includes */
38
39/* External variables ---------------------------------------------------------*/
40/* USER CODE BEGIN EV */
41
42/* USER CODE END EV */
43
44/* Private typedef -----------------------------------------------------------*/
45/**
46 * @brief Power driver callbacks handler
47 */
54
55/* USER CODE BEGIN PTD */
56
57/* USER CODE END PTD */
58
59/* Private define ------------------------------------------------------------*/
60/* USER CODE BEGIN PD */
61
62/* USER CODE END PD */
63
64/* Private macro -------------------------------------------------------------*/
65/* USER CODE BEGIN PM */
66
67/* USER CODE END PM */
68
69/* Private variables ---------------------------------------------------------*/
70/* USER CODE BEGIN PV */
71
72/* USER CODE END PV */
73
74/* Private function prototypes -----------------------------------------------*/
75/* USER CODE BEGIN PFP */
76
77/* USER CODE END PFP */
78
79/* Exported functions --------------------------------------------------------*/
80
82{
83 /* USER CODE BEGIN EnterOffMode_1 */
84 // no, the LoRa radio has problem with this mode
85 /* Deinitialize/suspend peripherals as needed */
86 //setBackUpRegister(RTC_BKP_STANDBY, RTC_BKP_STANDBY_SIGN); // indicator of restart after
87 Radio.Sleep();
88 while (HAL_GPIO_ReadPin(GPIOA, GPIO_PIN_12) == GPIO_PIN_SET)
89 ;
90
91 //MX_I2C2_DeInit(); // if applicable
93 // Stop UART DMA/IT if used; optional: HAL_UART_DeInit(&huart1);
94 // ADC deinit
95 HAL_ADC_Stop_IT(&hadc);
96 HAL_ADC_DeInit(&hadc);
97
98 /* Clear all wake flags before entering Standby to avoid immediate wake-up */
99 HAL_RTCEx_DeactivateWakeUpTimer(&hrtc);
100 __HAL_PWR_CLEAR_FLAG(PWR_FLAG_WU); /* Clear WUF1/2/3 */
101 __HAL_PWR_CLEAR_FLAG(PWR_FLAG_WRFBUSY); /* Clear radio busy wake flag, if set */
102 __HAL_RTC_WAKEUPTIMER_CLEAR_FLAG(&hrtc, RTC_FLAG_WUTF);
103
104 /* Disable wake-up pins unless you intentionally use them */
105 HAL_PWR_EnableWakeUpPin(PWR_WAKEUP_PIN1_HIGH);
106// HAL_PWR_DisableWakeUpPin(PWR_WAKEUP_PIN1);
107 HAL_PWR_DisableWakeUpPin(PWR_WAKEUP_PIN2);
108 HAL_PWR_DisableWakeUpPin(PWR_WAKEUP_PIN3);
109
110#if kokot
111 /* Deactivate any RTC Alarm and clear its flag (Alarm A) */
112 __HAL_RTC_ALARM_CLEAR_FLAG(&hrtc, RTC_FLAG_ALRAF);
113 HAL_RTC_DeactivateAlarm(&hrtc, RTC_ALARM_A);
114 HAL_RTCEx_DeactivateWakeUpTimer(&hrtc);
115
116
117 /* Optional: ensure radio busy IRQ does not wake us during Standby */
118 //HAL_PWREx_SetRadioBusyTrigger(PWR_RADIO_IRQ_TRIGGER_NONE); // if available
119 CLEAR_BIT(PWR->CR3, PWR_CR3_EWRFBUSY | PWR_CR3_EWRFIRQ);
120#if 1
121 GPIO_InitTypeDef GPIO_InitStruct =
122 { 0 };
123#if 0
124 GPIO_InitStruct.Pin = GPIO_PIN_12;
125 GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
126 GPIO_InitStruct.Pull = GPIO_NOPULL;
127 HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
128
129 while (HAL_GPIO_ReadPin(GPIOA, GPIO_PIN_12) == GPIO_PIN_SET)
130 {
131 // Wait for radio to finish entering sleep mode
132 }
133#endif
134 /* 7. THE LEAKAGE KILLER: Set all GPIOs to ANALOG */
135 /* This includes your I2C pins, RF Switch pins, and UART pins */
136 // --- PORT A ---
137 // Keep PA0 (Radio Reset) and PA4 (Radio NSS) if necessary,
138 // // PA0 - NFC_INT - exclude
139 // though for STANDBY, the most important is to NOT trigger a pin reset.
140 GPIO_InitStruct.Pin = GPIO_PIN_All & ~(GPIO_PIN_0 | GPIO_PIN_4 | NFC_INT_Pin);
141 HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
142
143 // --- PORT B ---
144 // PB8 is your RF Switch. Setting to Analog is fine,
145 // but ensure it's not needed for a specific wakeup.
146 // PB3/PB4 (Debug)
147 // PB12 (Internal Radio CS/Busy related)
148 // PB13/14/15 (Internal SPI)
149 // PB5-PB8 (Commonly used for RF Switch or Sensors)
150
151 // Try this instead of the "All" approach for Port B
152 GPIO_InitStruct.Pin = (
153 GPIO_PIN_0 |
154 GPIO_PIN_1 |
155 GPIO_PIN_2 |
156 GPIO_PIN_6 |
157 GPIO_PIN_8 |
158 GPIO_PIN_9 |
159 GPIO_PIN_10 |
160 GPIO_PIN_11 |
161 GPIO_PIN_12 |
162 GPIO_PIN_13 |
163 GPIO_PIN_14 |
164 GPIO_PIN_15 |
165 0 );// & ~(NFC_INT_Pin);
166
167 GPIO_InitStruct.Mode = GPIO_MODE_ANALOG;
168 GPIO_InitStruct.Pull = GPIO_NOPULL;
169 HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
170
171 // --- PORT C ---
172 // PC13 is your other RF Switch.
173 GPIO_InitStruct.Pin = GPIO_PIN_All & ~(GPIO_PIN_14 | GPIO_PIN_15); //LSE crystal
174 HAL_GPIO_Init(GPIOC, &GPIO_InitStruct);
175#endif
176 // --- CRITICAL: Keep Radio NSS High ---
177 // This prevents the radio from waking up and causing a system crash
178 HAL_GPIO_WritePin(GPIOA, GPIO_PIN_4, GPIO_PIN_SET);
179#endif
180
181 // PA10 - NFC_LPD_Enb, PB12 - Bat_Mon_enb, PB2 - 3V3_Enb
182 GPIO_InitTypeDef GPIO_InitStruct = {};
183 GPIO_InitStruct.Mode = GPIO_MODE_ANALOG;
184 GPIO_InitStruct.Pull = GPIO_NOPULL;
185
186 GPIO_InitStruct.Pin = GPIO_PIN_10 | GPIO_PIN_11 | GPIO_PIN_12 | GPIO_PIN_15; // NFC_LPD_Enb - PA10, SDA, SCL, ADC_BAT
187 HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
188
189 GPIO_InitStruct.Pin = GPIO_PIN_12 | GPIO_PIN_2; // Bat_Mon_enb, 3V3_Enb
190 HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
191
192 /* Enter Standby mode: after WFI, the device will restart from reset on wake */
193 /* Suspend SysTick */
194 HAL_SuspendTick();
195
196 /* Ensure the system knows to use the lowest power regulator state */
197 //HAL_PWR_DisablePVD();
198#ifndef DEBUG
199 // !!! this is important !!!
200 HAL_DBGMCU_DisableDBGStandbyMode();
201#endif
202
203 // this not working - problem of wakeUptimer???
204 // 1. Disable the Wakeup Timer temporarily to modify settings if needed
205 //HAL_RTCEx_DeactivateWakeUpTimer(&hrtc);
206
207 // 2. Re-configure your 30-second period
208// HAL_RTCEx_SetWakeUpTimer_IT(&hrtc, 0xEA60*4, RTC_WAKEUPCLOCK_RTCCLK_DIV16, 0);
209
210// if (HAL_RTCEx_SetWakeUpTimer_IT(&hrtc, 60000*10, RTC_WAKEUPCLOCK_RTCCLK_DIV16, 0) != HAL_OK)
211// {
212// Error_Handler();
213// }
214
215 // 3. CLEAR THE FLAGS RIGHT HERE
216// __HAL_PWR_CLEAR_FLAG(PWR_FLAG_WU);
217// __HAL_RTC_WAKEUPTIMER_CLEAR_FLAG(&hrtc, RTC_FLAG_WUTF);
218
219// */
220
221 // Now proceed to clear flags and enter Standby
222 __HAL_PWR_CLEAR_FLAG(PWR_FLAG_WRFBUSY);
223 __HAL_PWR_CLEAR_FLAG(PWR_FLAG_WU);
224 HAL_PWR_EnterSTANDBYMode();
225
226 /* USER CODE END EnterOffMode_1 */
227}
228
230{
231 /* USER CODE BEGIN ExitOffMode_1 */
232 //Error_Handler(); // never reach
234 /* USER CODE END ExitOffMode_1 */
235}
236
238{
239 /* USER CODE BEGIN EnterStopMode_1 */
240
241 // Deinitialize peripherals before entering stop mode
242 //MX_I2C2_DeInit(); // MT 10.1.2026 is in SensorOFF
243 writeLog("PWR_EnterStopMode");
244 sensorsBase_StartTimerToOff(); // start timer for check to go into off mode
245
247
248 /* USER CODE END EnterStopMode_1 */
249 HAL_SuspendTick();
250 /* Clear Status Flag before entering STOP/STANDBY Mode */
251 LL_PWR_ClearFlag_C1STOP_C1STB();
252
253 /* USER CODE BEGIN EnterStopMode_2 */
254 /* 2. EXTI Maintenance */
255 // Clear any existing pending interrupt on Line 0 so we don't wake up instantly
256 __HAL_GPIO_EXTI_CLEAR_IT(GPIO_PIN_0);
257 LL_EXTI_EnableIT_0_31(LL_EXTI_LINE_0);
258 HAL_GPIO_WritePin(NFC_LPD_Enb_GPIO_Port, NFC_LPD_Enb_Pin, GPIO_PIN_SET); // enter to low power mode
259
260 /* USER CODE END EnterStopMode_2 */
261 HAL_PWREx_EnterSTOP2Mode(PWR_STOPENTRY_WFI);
262 /* USER CODE BEGIN EnterStopMode_3 */
263
264 /* USER CODE END EnterStopMode_3 */
265}
266
268{
269 /* USER CODE BEGIN ExitStopMode_1 */
271 /* USER CODE END ExitStopMode_1 */
272 /* Resume sysTick : work around for debugger problem in dual core */
273 HAL_ResumeTick();
274 /*Not retained periph:
275 ADC interface
276 DAC interface USARTx, TIMx, i2Cx, SPIx
277 SRAM ctrls, DMAx, DMAMux, AES, RNG, HSEM */
278
279 /* Resume not retained USARTx and DMA */
280 vcom_Resume();
281 /* USER CODE BEGIN ExitStopMode_2 */
282 // After wakeup from stop mode, reconfigure system clock
283 MX_SPI1_Init();
284 uart_Start();
285 writeLog("PWR_ExitStopMode");
286 sensorsBase_StopTimerToOff(); // stop timer for check to go into off mode
287 HAL_GPIO_WritePin(NFC_LPD_Enb_GPIO_Port, NFC_LPD_Enb_Pin, GPIO_PIN_RESET); // exit to low power mode
288
289 /* USER CODE END ExitStopMode_2 */
290}
291
293{
294 /* USER CODE BEGIN EnterSleepMode_1 */
295 writeLog("PWR_EnterSleepMode");
296
297 /* USER CODE END EnterSleepMode_1 */
298 /* Suspend sysTick */
299 HAL_SuspendTick();
300 /* USER CODE BEGIN EnterSleepMode_2 */
301
302 /* USER CODE END EnterSleepMode_2 */
303 HAL_PWR_EnterSLEEPMode(PWR_MAINREGULATOR_ON, PWR_SLEEPENTRY_WFI);
304 /* USER CODE BEGIN EnterSleepMode_3 */
305
306 /* USER CODE END EnterSleepMode_3 */
307}
308
310{
311 /* USER CODE BEGIN ExitSleepMode_1 */
312
313 /* USER CODE END ExitSleepMode_1 */
314 /* Resume sysTick */
315 HAL_ResumeTick();
316
317 /* USER CODE BEGIN ExitSleepMode_2 */
318 writeLog("PWR_ExitSleepMode");
319
320 /* USER CODE END ExitSleepMode_2 */
321}
322
323/* USER CODE BEGIN EF */
324
325/* USER CODE END EF */
326
327/* Private Functions Definition -----------------------------------------------*/
328/* USER CODE BEGIN PrFD */
329
330/* USER CODE END PrFD */
This file contains all the function prototypes for the adc.c file.
ADC_HandleTypeDef hadc
Definition adc.c:27
Header of application of the LRWAN Middleware.
void uart_Start()
start of UART reading
Definition main.c:150
void writeLog(const char *format,...)
Format and send a log message over UART (printf-style). Available only when WRITELOG is defined; comp...
Definition main.c:105
#define NFC_INT_Pin
Definition main.h:146
void SystemClock_Config(void)
Re-configure all system clocks after waking from STOP or OFF mode. Called automatically during the st...
Definition main.c:537
#define NFC_LPD_Enb_GPIO_Port
Definition main.h:158
#define NFC_LPD_Enb_Pin
Definition main.h:157
void sensorsBase_StartTimerToOff()
start timer to off the function is called from PWR_EnterStopMode - timer is started
void sensorsBase_StopTimerToOff()
stop timer to off the function is called from PWR_ExitStopMode - the timer value is checked and the P...
Header for General HW instances configuration.
This file contains all the function prototypes for the rtc.c file.
RTC_HandleTypeDef hrtc
Definition rtc.c:27
This file contains all the function prototypes for the spi.c file.
void MX_SPI1_DeInit(void)
Deinitialise SPI1 peripheral to reduce current consumption in low-power mode. Call before entering ST...
Definition spi.c:130
void MX_SPI1_Init(void)
Definition spi.c:30
void PWR_ExitStopMode(void)
Exits Low Power Stop Mode.
void PWR_EnterOffMode(void)
Accumulates the total time spent in STOP or SLEEP mode (in ms or ticks). Incremented each time PWR_Ex...
void PWR_EnterSleepMode(void)
Enters Low Power Sleep Mode.
void PWR_EnterStopMode(void)
Enters Low Power Stop Mode.
void PWR_ExitSleepMode(void)
Exits Low Power Sleep Mode.
const struct UTIL_LPM_Driver_s UTIL_PowerDriver
Power driver callbacks handler.
void PWR_ExitOffMode(void)
Exits Low Power Off Mode.
Header for Low Power Manager interface configuration.
void PWR_ExitStopMode(void)
Exits Low Power Stop Mode.
void PWR_EnterOffMode(void)
Accumulates the total time spent in STOP or SLEEP mode (in ms or ticks). Incremented each time PWR_Ex...
void PWR_EnterSleepMode(void)
Enters Low Power Sleep Mode.
void PWR_EnterStopMode(void)
Enters Low Power Stop Mode.
void PWR_ExitSleepMode(void)
Exits Low Power Sleep Mode.
void PWR_ExitOffMode(void)
Exits Low Power Off Mode.
configuration of the timer_if.c instances
Header for USART interface configuration.
void vcom_Resume(void)
Resume the UART and associated DMA (used by LPM).
Definition usart_if.c:217
void systemRestart()
the calling of system restart with disabling of interrupts
Definition utils.c:135