Skip to main content
Associate II
January 28, 2026
Solved

STM32L4 STOP2 System abnormal restart

  • January 28, 2026
  • 10 replies
  • 1713 views

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/02/03 23:18 UPDATE:

Environment:
50 mAh battery + STM32L4 MCU + 32.768 kHz LSE crystal + 4G module + GPS module + solar charging panel

Functionality:

  • The device wakes up once per hour to collect sensor data.
  • Every 8 hours, it uploads the accumulated data to a server via the 4G module.
  • Immediately after completing its tasks, the MCU enters STOP2 low-power mode.
  • Data collection and logging are stored in the internal Flash memory.
  • During the long sleep period, the MCU wakes up every 10 minutes solely to feed an external watchdog timer.

Problem:
The device occasionally resets during these 10-minute wake-up intervals.

Known Information:

  • Our LDO can only supply a peak current of 300 mA.
  • There is approximately 10 µF of capacitance on the 3.3V power rail.
  • The 4G module’s datasheet specifies a peak current requirement of 1 A. During RF transmission, significant voltage droop occurs—oscilloscope measurements show the 3.3V rail dropping as low as 2.4V.
  • The GPS module draws about 100 mA during operation, causing ~100 mV voltage pulses visible on the oscilloscope.
  • The Brown-Out Reset (BOR) threshold is configured at 1.7V.

Current Observations & Issues:

Current Analysis:

  1. Power supply IC limitation: Although we haven’t captured the exact 3.3V waveform at the moment of reset, we have observed dips down to 2.4V. It’s reasonable to assume that under real-world outdoor conditions—especially with poor cellular signal requiring higher 4G transmit power—the voltage could drop even further. (See image showing a 2.8V dip: https://community.st.com/t5/stm32-mcus-products/stm32l4-stop2-system-abnormal-restart/m-p/875903/highlight/true#M292050.)
  2. Power cable issue: The current wiring uses approximately AWG16 gauge, which may be too thin, contributing to additional voltage drop.
  3. Flash corruption during write operations: Data logging, Flash writes, and 4G transmission occur simultaneously. Therefore, it’s highly likely that a voltage droop-induced reset happens during a Flash write, potentially corrupting the memory contents.

Current Questions:

  1. Regarding point #3 above: If a reset caused by voltage droop occurs during Flash read/write, will it permanently damage the Flash memory or only partially corrupt its contents?

Next Steps:

  1. Redesign the power circuit: Replace the current LDO with one capable of handling higher peak currents, then conduct further testing.
  2. Use thicker power cables (lower gauge) to reduce resistive losses.
  3. Investigate and resolve the STM32CubeProgrammer read failure—either recover the root cause or implement mitigation strategies (e.g., robust Flash write protocols, power monitoring before writes).
Best answer by daniaoday

daniaoday_0-1770018917890.jpeg

We re-examined the current issue and found that the power supply problem is indeed more significant. However, the original oscilloscope truly couldn't detect any anomalies. Therefore, we borrowed a higher-end oscilloscope, and the test results were excellent! Although we didn't capture the voltage level during the reset event, we did successfully capture waveform dips at certain moments!

The voltage dropped to around 2.8V. Although it didn’t reach the BOR  threshold, this is very likely the root cause of the issue!

 

Therefore, we've decided to redesign the power supply and fabricate a new PCB. We hope the next revision will resolve the issue.
P.S.: But why can't we read the flash memory on the failed devices—has it been locked or physically damaged?

 

10 replies

daniaodayAuthor
Associate II
January 28, 2026

 

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.

daniaodayAuthor
Associate II
January 28, 2026

daniaoday_0-1769696181061.png

This is the latest version.

daniaoday_0-1769697023787.png

this is power . 

daniaodayAuthor
Associate II
January 28, 2026
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
January 28, 2026

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""."
daniaodayAuthor
Associate II
January 28, 2026
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.

TDK
Super User
January 28, 2026

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""."
TDK
Super User
January 28, 2026

> A low level on the NRST pin (external reset) → No external reset signal was captured by the oscilloscope.

> However, actual measurements show that the low-level duration on the nRST pin is less than 1 ms.

I'm having trouble reconciling these two statements. You measured the NRST pin was low less than 1 ms (and presumably more than 0s?) but "no external reset signal" was captured? Isn't that the same thing?

If you have a scope capture of NRST when the reset happens:

Create a new project where IWDG is enabled and let it cause a chip reset. That will trigger the same internal pulse generator on NRST. Capture NRST during this event and compare the two. If they're the same, likely it was an internal reset, not external.

"If you feel a post has answered your question, please click ""Accept as Solution""."
daniaodayAuthor
Associate II
January 28, 2026
A low level on the NRST pin (external reset) → No external reset signal was captured by the oscilloscope.
—> This specifically refers to the absence of the TPL5010’s 320 ms wide reset pulse.
 
I didn’t test using the IWDG; instead, I directly called HAL_NVIC_SystemReset(), and the observed behavior was identical.
The ~1 ms pulse width might be due to the RC time constant: τ = R × C = 10 kΩ × 100 nF (marked as "104") → τ ≈ 1 ms?
TDK
Super User
January 28, 2026

Ahh, okay, so likely an internal reset then.

Floating SWD pins will not cause a reset, nor will they affect system stability.

I'm afraid all the potential reset causes are what you listed above. Given your scenario, I think BOR reset is the most likely, though of course this will not happen if power is sufficient.

"If you feel a post has answered your question, please click ""Accept as Solution""."
MM..1
Chief III
January 29, 2026

@daniaoday wrote:

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.

 

Try little match : your bat in OK state can do 45mA one hour. Every hour your code work time on 80M is how long ??? STOP2 isnt hour when every ten min exist next wakes ... How is complete current your design on run mode and on stop ?  My tip is MCU 8mA + 7mA other =15mA  If run time is one minute every hour , then your design deplete bat after 3x 60 hours around 7days 

 

You dont reply how batery type and voltage used?

TDK
Super User
January 29, 2026

Guys, if the battery was failing or running out, the 3V3 line would be dropping, no? And it wouldn't be recovering after a reset.

"If you feel a post has answered your question, please click ""Accept as Solution""."
Andrew Neil
Super User
January 29, 2026

@TDK wrote:

Guys, if the battery was failing or running out, the 3V3 line would be dropping, no?


I get the impression the 3V3 line has only been verified in the lab ?

But the devices are failing in the field - where the state of the battery (and, thus, 3V3) are unknown ?

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.
TDK
Super User
January 29, 2026

This cleared it up for me. But I could be missing something.

> The oscilloscope captured 3.3V on one channel and nRST on the other, with the nRST channel set to trigger mode. It was found that when the nRST signal had a falling edge, there was no fluctuation on the 3.3V line.

It would always be good to see actual scope plots with this information rather than just text. Sometimes things are left out or misinterpreted.

"If you feel a post has answered your question, please click ""Accept as Solution""."
daniaodayAuthor
Associate II
January 30, 2026
@TDK  @Andrew Neil  @MM..1 

Battery:
Specification for Lithium-ion cell: 65 mAh, 3.7 V.
Failed device issue:
We currently have two pilot customers, each with approximately 20 devices.
  • Scenario 1: The first customer has already deployed the devices on birds. Within three days, about ten devices exhibited anomalies one after another, followed by occasional additional failures in the subsequent days. The failures occurred too rapidly to identify any clear pattern.
  • Scenario 2: According to feedback, the second customer has not yet deployed the devices on birds (they may still be in storage). On a certain day between 4:55 and 7:26, nine devices rebooted. Afterward, they began rebooting every few hours. After some time, the reboots became irregular again.
  • Scenario 3: We conducted our own test with devices placed on a balcony, and two units showed anomalies, named test1 and test2:
    • test1: Tested by colleague J. Confirmed as an internal reset with stable 3.3 V power. A new firmware version with added RCC status logging was reflashed, and the issue did not reoccur within three days—still under monitoring.
    • test2: Tested by colleague K. Also confirmed as an internal reset with stable 3.3 V power. I will now read the MCU’s internal status via J-Link.
All lab-test-related information I’ve shared with you so far is based on testing results from test1 and test2.
In all three scenarios, when anomalies occurred, our platform reported battery voltages between 4.0 V and 4.2 V.
 
Device configuration:
The device currently collects data once per hour and uploads data via the 4G module every 8 hours.
 
Device workflow:
Under normal operation:
Power-on / Reboot → Log reboot event → Collect data once → Upload all historical data to the platform → Enter 1-hour sleep → Upload all historical data → Collect data → Sleep 1 hour (repeat this cycle 8 times) → At the 8-hour mark, upload all historical data → Collect data → Sleep 1 hour (repeat this cycle again) → LOOP.
The “1-hour sleep” is implemented via the device_enter_lowpower function, which internally splits the hour into six 10-minute intervals. The relevant code has already been shared previously.

At the time of reboot, logs from both test1 and test2 indicate that the reset occurred inside the device_enter_lowpower function. Similarly, for Scenario 1 and Scenario 2, reboots observed on the platform also follow this pattern—i.e., the interval between reboots and logged events is always a multiple of 10 minutes.
 
scope plots -->

daniaoday_0-1769737149650.png

 



MM..1
Chief III
January 30, 2026

OK then forget to Vdd issue. Trouble is sw. Check PLL recovery waiting is ok in your sw.

Good practice use only MSI without PLL. 

Check if some code on fail dont have sw reset call in code etc. For example stack fail...

daniaodayAuthor
Associate II
January 30, 2026
PLL? This is an unexpected possibility: the PLL derived from HSI, and the repeated switching between PLL and MSI when entering and exiting Stop mode—could this cause a reset?
I only saw in the reference manual that MSI may exhibit overshoot during clock switching, and that it needs to stabilize before being used. In practice, however, I started using it without waiting for it to stabilize.
 
daniaoday_0-1769774437061.png

 

daniaodayAuthor
Associate II
January 30, 2026
Everyone, latest update:
  • When using J-Link with STM32CubeProgrammer or J-Flash to read a normal device, communication works fine and Flash can be read successfully.
  • However, when attempting to read a faulty device with the same setup, various errors occur.

Additionally, STM32CubeProgrammer occasionally crashes when connecting to the faulty device.

 

daniaoday_0-1769776577540.pngdaniaoday_1-1769776601289.png

daniaoday_3-1769776676800.pngdaniaoday_2-1769776642595.png

 

 

 

daniaoday_4-1769776796537.png

daniaoday_5-1769776821187.png

 

daniaodayAuthor
Associate II
January 30, 2026

Regarding the issue where STM32CubeProgrammer cannot read the Flash, I came across a forum post mentioning that the problem is often due to the chip not being correctly selected. However, in my case, the chip has already been properly recognized.

 

https://community.st.com/t5/stm32cubeprogrammer-mcus/missing-database-files/td-p/81261 

 

daniaoday_6-1769777382889.png

 

daniaoday_7-1769777580852.png

 

SWD communication should be fine.

And the device has already been correctly identified.

 

daniaodayAuthorBest answer
Associate II
February 2, 2026

daniaoday_0-1770018917890.jpeg

We re-examined the current issue and found that the power supply problem is indeed more significant. However, the original oscilloscope truly couldn't detect any anomalies. Therefore, we borrowed a higher-end oscilloscope, and the test results were excellent! Although we didn't capture the voltage level during the reset event, we did successfully capture waveform dips at certain moments!

The voltage dropped to around 2.8V. Although it didn’t reach the BOR  threshold, this is very likely the root cause of the issue!

 

Therefore, we've decided to redesign the power supply and fabricate a new PCB. We hope the next revision will resolve the issue.
P.S.: But why can't we read the flash memory on the failed devices—has it been locked or physically damaged?

 

Andrew Neil
Super User
February 2, 2026

I don't think you've mentioned it but, presumably, your system has some sort of radio link to upload its data?

It is typical of radios to have large current spikes when they transmit - so I guess that's what's happening here?

 


@daniaoday wrote:

the original oscilloscope truly couldn't detect any anomalies.


These things can, indeed, be hard to spot - the pulses can be narrow and infrequent.

 


@daniaoday wrote:

The voltage dropped to around 2.8V. Although it didn’t reach the BOR  threshold


Well, the one you captured didn't.

You need to check what happens in a worst-case scenario - probably when the battery is low, and the solar cell isn't charging.

Again, does your system log the battery state-of-charge?

 

BTW: Please use your scope's screen capture facility - it will be much better that photos of the screen!

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.
daniaodayAuthor
Associate II
February 2, 2026

I don't think you've mentioned it but, presumably, your system has some sort of radio link to upload its data? 

--->  Yes, there is a 4G module.

It is typical of radios to have large current spikes when they transmit - so I guess that's what's happening here?

---> Yes 

Again, does your system log the battery state-of-charge?

---> Yes, but at that time the battery voltage was still quite high. 4.0~4.2V . 

 

These are the monitoring logs from several devices on the platform.

daniaoday_6-1770027282343.png

daniaoday_7-1770027324582.png

daniaoday_8-1770027368910.png

daniaoday_9-1770027409584.png

daniaodayAuthor
Associate II
February 3, 2026

Also 4G comms could cause a lot of RF (and maybe other) noise ...   --->

Yes, and according to the code logic, the 4G communication and Flash write operations are very likely happening concurrently.
------------------------------------------------------------

To make it easier for others to read, I've updated some key information in the body section for everyone's reference.

Andrew Neil
Super User
February 3, 2026

@daniaoday wrote:

Next Steps:

  1. Redesign the power circuit: Replace the current LDO with one capable of handling higher peak currents, then conduct further testing.

So is the same LDO currently powering both microcontroller and 4G module?

Might be better to separate them?

Some cellular modules car run direct off a lithium battery...

Also add some capacitance to keep the microcontroller supply up, separate from the 4G module.

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.
daniaodayAuthor
Associate II
February 3, 2026

Yes, the power supply for the 4G module and the MCU should be separated—most likely, the 4G module will use a dedicated LDO or MOSFET for power delivery.