S7G2 writing to internal data flash during power off

I am just curious to know if there is a way on S7G2 to detect Power OFF condition to write couple of variables to internal data flash, and if there is a way to do that, the next question is would it have enough time to write 8 bytes before quitting.

If there is way then I don't have to worry about designing a super cap board/Circuitry that can hold the charge for 3-5 secs on power OFF.

I have a requirement to keep track some variables every 0.1 changes, and I don't want to write to memory every 0.1 change as I would hit the upper limit of 100,000 erase/write cycles in a couple of months.

Any input on this is much appreciated.




  • Hi Sam,

    Just a couple of thoughts.

    If you are using a battery for the RTC you might be able to get a few bytes from the alarm registers which are non volatile, and you can R/W as often as you wish before the power down occurs.

    Again if you have a battery, you can put on a small spi device, we use 23LCV1024 (128k) and modified the sample driver and put FileX on it.

    I think there is Wear levelling code available for the DataFlash I don't know how much this extends the write cycles .

    As most application use almost no dataflash, you might be able to write your own very inefficient / wasteful memory code to use the 64K memory for your data. A minimum BLOCK size is 64 so you have 1000 of them, you get 100K writes but unlimited reads, so the first 2 blocks give you 992 bits which you set to 1 and goes to 0 when a data block is used. A counter in each of your data blocks counts to 100k so you know when to use the next block. This should give you 100M Read / Writes.

    Best Regards,
  • Hello Sam,

    there is the Low Voltage Detection (LVD) HAL module available in the SSP. It could be used to execute user's code when the VCC crosses the detection threshold.

    Best regards,

  • Thank you Anper and Alan for your inputs. I will try either using battery backed up RTC RAM area (or) detecting low voltage and writing to data flash and see which would work fine for our application.
    Thanks again for your prompt response.
  • You could use external FRAM for close to unlimited write cycles, then you can make the write intervals so small that you may end up without any low voltage detection needed. Some FRAMs have a write protction pin, or internal LV-detection, or you could use one with 2 or more internal banks. With those functions you can protect the contents from beeing corrupted due to writes during falling supply.
    Another approach, in case you have a higher supply voltage from which the 3.3V processor supply is generated: In that case a drop in the, say 5V, can be the used to trigger an interrupt before the 3.3V start to drop. The time left is then only dependend from the bulk capacitor on the 5V. This can be optimized by the use of an DCC for the 3.3V and further by using a switch through or even boost-capable DCC, so you propably wont need a large cap.
    A further enhancement can be made in making all additional current consuming circuits -like interface chips- power-switchable via I/O-Pins.
    When the low-supply interrupt fires, all of this 'soon to be without power anyway' stuff is immediately switched off, leaving more or less only the processor on the supply to do some housekeeping. Of course it can be used to switch off unneccessary processor-internal peripherals as well to further save remainig time.
  • Hello Anper,
    Tried the LVD Module. I guess the module itself works just fine.
    But when I tested a power OFF condition by just unplugging the 5V power source on the DK-S7G2, the processor shuts down instantly. The sink to 0V is fast enough to not trigger the LVD callback interrupt below 2.85V threshold. I just followed the settings and procedure explained in Module Guide.

    I started with the other option of accessing RTC's alarm register to store a sample data 0x55 as shown below:

    *((uint32_t*)0x4004401A)=0x55; //0x4004401A is the address of RTC.RMONAR Month Alarm Register (Page 700 on S7G2 USER MANUAL Rev 1.20)

    Tried to debug the above and monitor in Memory window - not able to see a value 0x55 in that location, its showing 0x00.
    Not sure if this is the right way to use alarm registers for user variables.

    Any help on this is greatly appreciated.

  • Using an "ideal diode" in front of a beefy-enough bulk capacitor could let you monitor incoming 5V side without taking a big diode drop penalty on your processor supply rail. That might be all you need.
  • Thanks for you response. At this point I will not be able to make any hardware changes to fix this, so i am thinking I will have use the RTC registers to save my 8 bytes of application data. Any light on how to use RTC alarm registers for saving application data might be helpful. (All I need is to store 8 bytes of data into battery backedup RTC RAM location)
    I tried the below and I am not able to write to that location.
    *((uint32_t*)0x4004401A)=0x55; //0x4004401A is the address of RTC.RMONAR Month Alarm Register (Page 700 on S7G2 USER MANUAL Rev 1.20)
    Tried to debug the above and monitor in Memory window - not able to see a value 0x55 in that location, its showing 0x00.
    Not sure if this is the right way to use alarm registers for user variables.
  • How can I access the below mentioned VBAT Backup Register Area using Synergy API's for storing application data:





  • Sam,

    I do not think that there are any API that you can use to access the VBATT backup registers.

    But they are easily accessed.

    Below is an example.





    /* HAL-only entry function */

    #include "hal_data.h"

    void hal_entry(void)


       /* TODO: add your own code here */


        * VBATT registers are Write Protected

        * Enable access

        * Refer to section 13 of S7G2 Hardware User's Manual for more info



       /* Zero out VBATT Backup Registers */

       for( uint16_t count=0; count<512;count++ )


           R_SYSTEM->VBTBKRn[count] = 0;


       /* Write some test data */

       for( uint16_t count=0; count<512;count++ )


           R_SYSTEM->VBTBKRn[count] = (uint8_t)count;


       /* Enable Write Protection */