cancel
Showing results for 
Search instead for 
Did you mean: 

PINRSTF & WWDGRSTF are set in RCC->CSR with no apparent reason

Clonimus74
Senior II

Hi,

Our device sometimes turns on from Standby by itself. The only wakeup sources enabled are a couple of wakeup pins.

I saw the device reset (from standby) by itself, and the PINRSTF flags in RCC->CSR was set. The reset pin has 100nF capacitor to Gnd (it has an internal pullup according to the datasheet), and it is not connected anywhere, there's no option of performing external reset.

On another occasion the WWDGRSTF flag was set, and I do not use the Window Watchdog. My application uses Independent Watchdog, but power off is done by software reset, then the bootloader 'sees' no button is pressed and so it puts the system in Standby, with no watchdog set.

I did some experiments, and when I turn on the device from Standby (by wakeup pin) the PINRSTF flag is set with no apparent reason.

Ideas?

1 ACCEPTED SOLUTION

Accepted Solutions
Clonimus74
Senior II

I found the problem.

Here's what I do in the bootloader:

#pragma location=0x20000004
__no_init volatile uint32_t reset_flags;
#pragma location=0x20000008
__no_init volatile uint32_t power_flags;
 
  reset_flags = RCC->CSR;
  power_flags = PWR->SR1;

In the application I have the same declaration, added the volatile keyword to make sure they will not be optimized.

#pragma location=0x20000004
__no_init volatile uint32_t reset_flags;
#pragma location=0x20000008
__no_init volatile uint32_t power_flags;
 
  parameters->data_6.u32 = (*(uint32_t *)0x20000004);
  parameters->data_7.u32 = (*(uint32_t *)0x20000008);

I use the absolute address and not the variable name since the compiler returned with error when I tried to use the variables, I didn't think of it too much. A mistake.... 🙂

The compiler didn't reserve the locations, even though I used "__no_init" and "#pragma location".​ 

My ADC handle got the 0x20000004 location and overwritten the flags data.

So, right before power off, in the application, I reset the variables so the compiler will "see" they are being used.

Now I see the expected flags.

View solution in original post

3 REPLIES 3

What STM32?

Doesn't the RM diagram the reset circuit. The NRST pin is bidirectional/open-collector, the hardware drives this so it resets the CPU and all your external synchronous logic. This should be an OR gate with half a dozen potential sources including POR, Watchdog, etc

Tips, buy me a coffee, or three.. PayPal Venmo Up vote any posts that you find helpful, it shows what's working..
Clonimus74
Senior II

STM32L476QE

Each reset source has its own independent flag in RCC-CSR register

Clonimus74
Senior II

I found the problem.

Here's what I do in the bootloader:

#pragma location=0x20000004
__no_init volatile uint32_t reset_flags;
#pragma location=0x20000008
__no_init volatile uint32_t power_flags;
 
  reset_flags = RCC->CSR;
  power_flags = PWR->SR1;

In the application I have the same declaration, added the volatile keyword to make sure they will not be optimized.

#pragma location=0x20000004
__no_init volatile uint32_t reset_flags;
#pragma location=0x20000008
__no_init volatile uint32_t power_flags;
 
  parameters->data_6.u32 = (*(uint32_t *)0x20000004);
  parameters->data_7.u32 = (*(uint32_t *)0x20000008);

I use the absolute address and not the variable name since the compiler returned with error when I tried to use the variables, I didn't think of it too much. A mistake.... 🙂

The compiler didn't reserve the locations, even though I used "__no_init" and "#pragma location".​ 

My ADC handle got the 0x20000004 location and overwritten the flags data.

So, right before power off, in the application, I reset the variables so the compiler will "see" they are being used.

Now I see the expected flags.