2026-01-28 7:26 AM
Environment: STM32L4 + 32.768K LSE
Function: Wake up and work once every hour, then enter stop2 mode. During the one-hour sleep, wake up every ten minutes to feed the external watchdog.
Problem: The device resets directly when waking up every ten minutes.
Current known information: The device was tested in the company for over twenty days without any issues (including restarts, freezes, etc.). After the prototypes were given to customers, problems started to occur in about 10 to 20 days. Currently, there are two failed devices. After power cycling, the devices did not return to normal. External reset also did not restore them to normal. Re-flashing the devices allows them to operate normally, and they are currently under continuous pressure testing to see if the issue will recur.
Current debugging progress: When the device restarts, the nRST pin has a low-level time of less than 1ms. The 3.3V power supply pin of the MCU is stable as observed by the oscilloscope. The TP5010_DONE_Pin has a 40ms high-level time during each ten-minute wake-up period (HAL_Delay(1) --> SystemCoreClock configured at 80M, after low-power wake-up, it switches to the default 4M of MSI, reducing by 20 times, plus the HAL_GPIO_WritePin time, which is exactly 40ms), but during the first low-power entry, it has a high-level time of over 20ms (caused by unstable PLL switching to MSI?).
2026-01-28 7:27 AM - last edited on 2026-01-28 7:48 AM by Andrew Neil
void device_enter_lowpower(void)
{
GPIO_InitTypeDef GPIO_InitStruct = {0};
uint32_t sleepTime = 10;
uint32_t sleepTimeAll = 0;
printf("enter lowpower, It will wake up in %d seconds. \n", g_sleepTime); //g_sleepTime == 3600
HAL_ADC_DeInit(&hadc1);
HAL_I2C_DeInit(&hi2c1);
HAL_SPI_DeInit(&hspi1);
HAL_UART_DeInit(&huart1);
HAL_UART_DeInit(&huart2);
// /*Configure GPIO pins : PBPin PBPin PBPin */
GPIO_InitStruct.Pin = SPI_CS_ADXL362_Pin;
GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
GPIO_InitStruct.Pull = GPIO_PULLUP;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
HAL_GPIO_Init(SPI_CS_ADXL362_GPIO_Port, &GPIO_InitStruct);
HAL_GPIO_WritePin(GPIOOUT_4G_VBATEN_GPIO_Port, GPIOOUT_4G_VBATEN_Pin, GPIO_PIN_RESET);
HAL_GPIO_WritePin(GPIOOUT_GPS_EN_GPIO_Port, GPIOOUT_GPS_EN_Pin, GPIO_PIN_RESET);
HAL_GPIO_WritePin(GPIOOUT_4G_RESET_GPIO_Port, GPIOOUT_4G_RESET_Pin, GPIO_PIN_RESET);
do {
if(g_sleepTime - sleepTimeAll < 600) {
sleepTime = g_sleepTime - sleepTimeAll;
} else {
sleepTime = 600; // 600seconds --> 10min
}
sleepTimeAll += sleepTime;
HAL_RTCEx_DeactivateWakeUpTimer(&hrtc);
__HAL_PWR_CLEAR_FLAG(PWR_FLAG_WU);
HAL_RTCEx_SetWakeUpTimer_IT(&hrtc, sleepTime, RTC_WAKEUPCLOCK_CK_SPRE_16BITS);
// HAL_PWR_EnterSTANDBYMode();
HAL_PWREx_EnterSTOP2Mode(PWR_STOPENTRY_WFI);
HAL_GPIO_WritePin(GPIOOUT_TP5010_DONE_GPIO_Port, GPIOOUT_TP5010_DONE_Pin, GPIO_PIN_SET);
HAL_Delay(1);
HAL_GPIO_WritePin(GPIOOUT_TP5010_DONE_GPIO_Port, GPIOOUT_TP5010_DONE_Pin, GPIO_PIN_RESET);
} while(g_sleepTime - sleepTimeAll > 0);
}
void device_exit_lowpower(void)
{
SystemClock_Config();
MX_GPIO_Init();
MX_ADC1_Init();
MX_I2C1_Init();
// MX_LPTIM1_Init();
// MX_LPTIM2_Init();
MX_SPI1_Init();
MX_USART1_UART_Init();
MX_USART2_UART_Init();
MX_RTC_Init();
HAL_UARTEx_ReceiveToIdle_DMA(&huart2, modbus_struct.receive_buffer, RECV_BUFF_MAX_LEN);
HAL_GPIO_WritePin(GPIOOUT_TP5010_DONE_GPIO_Port, GPIOOUT_TP5010_DONE_Pin, GPIO_PIN_SET);
HAL_Delay(1);
HAL_GPIO_WritePin(GPIOOUT_TP5010_DONE_GPIO_Port, GPIOOUT_TP5010_DONE_Pin, GPIO_PIN_RESET);
HAL_GPIO_WritePin(GPIOOUT_GPS_EN_GPIO_Port, GPIOOUT_GPS_EN_Pin, GPIO_PIN_SET);
printf("exit lowpower\n");
}Edited to apply source code formatting - please see How to insert source code for future reference.
2026-01-28 7:28 AM
2026-01-28 7:39 AM
2026-01-28 7:48 AM
Read the flags in RCC_CSR to determine the cause of the reset.
If only PINRSTF is set, the NRST pin is being pulled low externally, probably by the external supervisor.
2026-01-28 7:56 AM
@daniaoday wrote:So, why did the reset occur?
The RCC_CSR will tell you that:
@daniaoday wrote:
Are you sure your watchdog isn't causing the reset?
2026-01-28 7:58 AM - last edited on 2026-01-28 8:01 AM by Andrew Neil
printf("RCC->CR = %x \n", RCC->CR);
printf("RCC->BDCR = %x \n", RCC->BDCR);
printf("RCC->CSR = %x \n", RCC->CSR);
printf("RCC->CIFR = %x \n", RCC->CIFR);
printf("RCC->BDCR = %x \n", RCC->BDCR);
uint8_t rst = 0;
if (__HAL_RCC_GET_FLAG(RCC_FLAG_IWDGRST))
{
rst |= 0x80;
printf("RESET_CAUSE_INDEPENDENT_WATCHDOG_RESET\n");
}
if (__HAL_RCC_GET_FLAG(RCC_FLAG_SFTRST))
{
rst |= 0x40;
printf("RESET_CAUSE_SOFTWARE_RESET\n");
}
if (__HAL_RCC_GET_FLAG(RCC_FLAG_PINRST))
{
rst |= 0x20;
printf("RESET_CAUSE_EXTERNAL_RESET_PIN_RESET\n");
}
if (__HAL_RCC_GET_FLAG(RCC_FLAG_BORRST))
{
rst |= 0x10;
printf("RESET_CAUSE_BROWNOUT_RESET\n");
}
if (__HAL_RCC_GET_FLAG(RCC_FLAG_LPWRRST))
{
rst |= 0x08;
printf(" Low-Power reset flag \n");
}
if (__HAL_RCC_GET_FLAG(RCC_FLAG_FWRST))
{
rst |= 0x04;
printf(" Firewall reset flag \n");
}
if (__HAL_RCC_GET_FLAG(RCC_FLAG_OBLRST))
{
rst |= 0x02;
printf(" Option Byte Loader reset flag \n");
}
__HAL_RCC_CLEAR_RESET_FLAGS();Edited to apply source code formatting - again, please see How to insert source code for future reference.
2026-01-28 8:21 AM
2026-01-28 8:41 AM
What if the problem is not within the code? Code doesn't start behaving differently after 10-20 days, barring rare scenarios like a timer overflow or slowly depleting heap. The code you showed doesn't have either of those. The cause is likely something external to the chip.
2026-01-28 8:46 AM