cancel
Showing results for 
Search instead for 
Did you mean: 

STM32L4 STOP2 System abnormal restart

daniaoday
Associate II

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?).

15 REPLIES 15
daniaoday
Associate II

 

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.

daniaoday_0-1769614121562.png

 

The STM32L4 has three types of reset: system reset, power reset, and backup domain reset.
  • Power reset → 3.3V is OK; Standby and Shutdown modes are not used.
  • System reset could be caused by:
    1. A low level on the NRST pin (external reset) → No external reset signal was captured by the oscilloscope.
    2. Window watchdog event (WWDG reset) → Not enabled.
    3. Independent watchdog event (IWDG reset) → Not enabled.
    4. A firewall event (FIREWALL reset) → Not enabled.
    5. A software reset (SW reset) (see Software reset) → HAL_NVIC_SystemReset() was not called.
    6. Low-power mode security reset (see Low-power mode security reset) → Not enabled.
    7. Option byte loader reset (see Option byte loader reset) → Not enabled.
    8. A Brown-out reset → 3.3V is OK.
  • Backup domain reset could be caused by:
    1. Software reset triggered by setting the BDRST bit in the Backup domain control register (RCC_BDCR) → HAL_RCC_BackupResetCmd() or similar was not called.
    2. VDD or VBAT power-on, if both supplies had previously been powered off → 3.3V is OK.
So, why did the reset occur?
TDK
Super User

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.

If you feel a post has answered your question, please click "Accept as Solution".

@daniaoday wrote:
So, why did the reset occur?

The RCC_CSR will tell you that:

AndrewNeil_0-1769615609406.png

https://www.st.com/resource/en/reference_manual/rm0394-stm32l41xxx42xxx43xxx44xxx45xxx46xxx-advanced-armbased-32bit-mcus-stmicroelectronics.pdf#page=179

 


@daniaoday wrote:
AndrewNeil_1-1769615725849.png
 

Are you sure your watchdog isn't causing the reset?

A complex system that works is invariably found to have evolved from a simple system that worked.
A complex system designed from scratch never works and cannot be patched up to make it work.
In the latest code, I added the following code to identify the reset cause. However, the issue takes too long to reproduce (10–20 days or even longer), so I must identify and resolve the problem from a code perspective. 
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.

In the latest code, I've already added logging of the RCC_CSR register status to identify the reset cause. However, this log is only useful after the issue reproduces—and the reproduction interval is far too long .
It is unlikely that the TPL5010 caused the reset, for the following reasons:
  1. The watchdog timeout configured via external resistors on the TPL5010 is set to 1 hour.
  2. The watchdog is being regularly fed—the feeding signal has been confirmed by oscilloscope measurements.
  3. If the reset were triggered by the TPL5010, the low pulse on the nRST pin should last significantly longer than 1 ms (the TPL5010 datasheet specifies a typical reset pulse width of 320 ms). However, actual measurements show that the low-level duration on the nRST pin is less than 1 ms.

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.

If you feel a post has answered your question, please click "Accept as Solution".
We initially suspected an external issue as well. After conducting a series of tests, we confirmed that both the power supply and the reset circuitry are functioning correctly.
Given that, are there any other external I/O pins that could potentially cause the MCU to reset? For example, could the SWD pins be a factor? The SWD I/Os are left floating—could that affect system stability or trigger a reset?