This post is older than 2 years and might not be relevant anymore
More Info: Consider searching for newer posts

Retain 32 bits across a watchdog reset ?

I'm sure the same question has been asked in a few different forms, but hoping for some ideas. . . Is there a way to retain 32 bits of information across a watchdog reset ?

I currently use PPI to clock a 32 bit counter at 1Hz from the RTC, this is nice because it gives me a real time clock time in a 32 bit register that runs in low power mode (why oh why is the rtc timer not 32bit ?!?!?!?! or at least has a 32 bit prescaler)

Anyway, the problem with this is that a watchdog reset clears the peripherals, so I lose the 32 bit count. I could write the value to NVM in the watchdog event handler, as long as the flash memory was erased at program startup otherwise it would take too long, but this doesn't seem like an elegant solution.

I know that the ram is not specifically reset, but may be corrupted, to this is also a possibility I guess.

Any suggestions appreciated! Thanks

  • Also, why on earth would the GPREGRET registers not be 32 bit ?!?!?!

  • Well you could push your 32 bit register to flash between watchdog refresh cycles. Unless your watchdog time is unusually short this shouldn't use much power. Then on reboot you can look for the data and load if available. At worst you will be off by one watchdog cycle. The reality is you would always be off a little on a watchdog reset since the RTC won't be configured on reset.

    As for the RTC timer, a second of 32768 fits nicely in 16 bits so even 24 bits is overkill let alone 32 bits. Don't know if they had a reason for it though.

    According to the spec, ram does not reset under any circumstance. They warn that it could be corrupted depending on the reset reason (eg, brownout). So, you could just write the 32bit word to ram once a second and just make sure to not initialize the variable in C. Sounds silly, but it should work.

  • Yeah, I should have added that we are ultra low power, our devices usually sleep @ less than 2uA to get the lifetime we require from a CR2032. No chance of writing to flash and even having to wake up the high frequency clock every second just to store the timer value make a real difference to our sleep current.

    I have experimented with writing the timer to a .noinit global variable and it looks to be working well in practice. I would have liked to store the timer value to this variable in the watchdog event handler, but it seems I cannot initialize the 32 bit counter to the stored value at startup ? Still trying to think about a simple way around all these catches.

  • Also, because the RTC is 24bit with a 12bit prescaler, you cannot really use it to keep real time for years. At maximum values, it would overflow every 24 days or so if my quick math is correct. This means to do a low power timebase that runs for years, I had to use the PPI to clock a 32 bit counter every second, which then also turns on the HF clock briefly at every event, which causes a extra 100nA or so on average of extra power consumption in sleep mode. This problem could have been avoided by either being able to use the 32k clock for a 32bit timer or by making the RTC 32 bit.

  • The RTC on most microcontrollers is really just a tick, app_timer kind of thing. And, for bluetooth it runs sleep/wake to keep the framing correct. At 20ppm it's not going to keep great time anyway. It might be for that reason that they refer to it as a real time counter and not real time clock.

    There are a lot of good real time clock solutions out there in tiny packages and only draw nanoamps. Plus they have internal registers that will keep time for roughly forever. Interfaces are simple i2c, 1 wire or 2 wire serial. Most are around 1 to 2ppm. Or under 1 minute error annually. This might be a better solution if you have high performance time keeping requirements. Plus at nanoamps these can normally be run from soldered in rechargeable button cells so they even run with power off.

Related