This library allows any user to use their Mbed project with a transient energy source( e.g. windturbine, solar power).

Dependencies:   mbed

Fork of Hibernus by Bogdan Lazarescu

This library allows any user to use their Mbed project with a transient energy source( e.g. windturbine, solar power). You can do this by simply import the "hibernus.h" header file, and call the "Hibernus()" method at the beginning of you main program. In case of a power loss the state of your programm will be saved to the nonvolatile memory and it will be resumed from the same point as soon as there is enough power for the board to run properly. If the power drops down, the internal capacitance of the system is used to save a snapshot of your program into the flash memory, and the board goes in a low power mode (sleep or deepsleep). In order to detect a power loss, the library uses an analog comparator which can be internal (eg Freescale KL 05Z has an internal comparator which can be used ), or external (on LPC11U24 there is no internal comparator) via a GPIO interrupt. For more details see the code comments and the attached example main.cpp file.

This library use "IAP" library, in order to write the required data to the flash nonvolatile memory.

The library can be easily adapted to work with other boards, from different manufactures, which have support for Mbed. In order to adapt this library and use it on your board, the write to flash methods have to be changed. Some changes listed below are required because of the platform dependent parameters of each board. All required changes have to be applied to the "config.h" and "config.cpp" files.

  • The "erase_flags_memory()", "copyRamToFlash()", "restore_flags()", "setFlag()" and " isFlagSet()" methods have to be modified in order to use the right Flash IAP of your board.
  • The wake up and hibernate interrupts have to be modified in order to be trigghered when the voltage drops down or rise. If you use an internal comparator, it should trigger and interrupt whenever the power drops(e.g see CMP0_IRQHandler() method writtend for KL05Z at https://developer.mbed.org/users/BogdanL/code/Hibernus-KL05Z/ ) . At that time a snapshot have to be saved and the board sent to sleep. Another interrupt have to be triggered when the power comes back(see "LLW_IRQHandler()" at https://developer.mbed.org/users/BogdanL/code/Hibernus-KL05Z ) . This have to wake up the board and resume de computation. In you use an external comparator two GPIO interrupts are used. One of them (for LPC11U24 see "FLEX_INT1_IRQHandler()" ) is used to save the snapshot when the power drops down, and the other one (for LPC11U24 see "FLEX_INT0_IRQHandler()" ) is used to wake up the board.
  • For each board, the right Sleep mode have to be chosen. Also the interrups and the comparator have to be properly set, in order to be triggered as desired. For a good example see "configure_VR_gpio_interrupt()" and "configure_VH_gpio_interrupt()" that are used to set up the Restore and Hibernate interrupts on LPC11U24 board, that uses an external comparator.
  • In the "config.h" file, the two arrays, "REG_Addresses_4B[]" and "REG_Addresses_4B[]" have to be populated with the addresses of the 1 Byte and 4Bytes peripheral registers that are used by your project. Different boards have different modules that use different peripheral registers. The addresses of the registers can be found in the Reference Manual of each board, and will be used in order to save and later restore the content of the registers. Also the number of used registers, "No_Of_4B_Peripheral_Reg", No_Of_1B_Peripheral_Reg, have to be updated with the correct number of used registers.
  • At the top of "config.h" header file, specific board parameters have to be fixed: RAM start address(RAM_1_Address), Flash start address(FLASH_Start), RAM size(RAM_Size), Flash size(flash_Size) and the flash sector size(sector_Size).
Committer:
BogdanL
Date:
Fri Sep 08 18:01:22 2017 +0000
Revision:
0:f9a13d4b41f3
First Version of Hibernus Library;

Who changed what in which revision?

UserRevisionLine numberNew contents of line
BogdanL 0:f9a13d4b41f3 1 /** Hibernus Library
BogdanL 0:f9a13d4b41f3 2 * University of Southampton 2017
BogdanL 0:f9a13d4b41f3 3 *
BogdanL 0:f9a13d4b41f3 4 * Open-source liberary that enable any of your Mbed project work with transient enegy sources.
BogdanL 0:f9a13d4b41f3 5 * In order to use this library include the "hibernus.h" header file, and use the "Hibernus()" method at the beginning of you main funtion.
BogdanL 0:f9a13d4b41f3 6 * For more details and example see the "main.cpp" exampe file, and the attached documnetation
BogdanL 0:f9a13d4b41f3 7 *
BogdanL 0:f9a13d4b41f3 8 *
BogdanL 0:f9a13d4b41f3 9 * Released under the MIT License: http://mbed.org/license/mit
BogdanL 0:f9a13d4b41f3 10 */
BogdanL 0:f9a13d4b41f3 11 #include "hibernus.h"
BogdanL 0:f9a13d4b41f3 12 #include "mbed.h"
BogdanL 0:f9a13d4b41f3 13 #include "config.h"
BogdanL 0:f9a13d4b41f3 14 #ifdef LPC11U24
BogdanL 0:f9a13d4b41f3 15 #include "Driver_LPC11U24.h"
BogdanL 0:f9a13d4b41f3 16 #endif
BogdanL 0:f9a13d4b41f3 17 #ifdef KL05Z
BogdanL 0:f9a13d4b41f3 18 #include "Driver_KL05Z.h"
BogdanL 0:f9a13d4b41f3 19 #endif
BogdanL 0:f9a13d4b41f3 20
BogdanL 0:f9a13d4b41f3 21 //11 variables stored at fixed addresses at the beginning of the RAM
BogdanL 0:f9a13d4b41f3 22 #if SaveFlagsInFlash == 0
BogdanL 0:f9a13d4b41f3 23 volatile unsigned int FLAG_1 __attribute__((at(RAM_Start+Fixed_Add_Vars_Offset)));// = Flash_Flags_Sector_Start;
BogdanL 0:f9a13d4b41f3 24 volatile unsigned int FLAG_2 __attribute__((at(RAM_Start+Fixed_Add_Vars_Offset+ 0x4)));// = Flash_Flags_Sector_Start + 0x4;
BogdanL 0:f9a13d4b41f3 25 volatile unsigned int FLAG_3 __attribute__((at(RAM_Start+Fixed_Add_Vars_Offset+ 0x8)));// = Flash_Flags_Sector_Start + 0x8;
BogdanL 0:f9a13d4b41f3 26 volatile unsigned int FLAG_4 __attribute__((at(RAM_Start+Fixed_Add_Vars_Offset+ 0xC)));// = Flash_Flags_Sector_Start + 0xC;
BogdanL 0:f9a13d4b41f3 27 #else
BogdanL 0:f9a13d4b41f3 28 volatile unsigned int FLAG_1 __attribute__((at(RAM_Start+Fixed_Add_Vars_Offset))) = Flash_Flags_Sector_Start;
BogdanL 0:f9a13d4b41f3 29 volatile unsigned int FLAG_2 __attribute__((at(RAM_Start+Fixed_Add_Vars_Offset+ 0x4))) = Flash_Flags_Sector_Start + 0x4;
BogdanL 0:f9a13d4b41f3 30 volatile unsigned int FLAG_3 __attribute__((at(RAM_Start+Fixed_Add_Vars_Offset+ 0x8))) = Flash_Flags_Sector_Start + 0x8;
BogdanL 0:f9a13d4b41f3 31 volatile unsigned int FLAG_4 __attribute__((at(RAM_Start+Fixed_Add_Vars_Offset+ 0xC))) = Flash_Flags_Sector_Start + 0xC;
BogdanL 0:f9a13d4b41f3 32 #endif
BogdanL 0:f9a13d4b41f3 33
BogdanL 0:f9a13d4b41f3 34 volatile unsigned int CoreReg_SP __attribute__((at(RAM_Start+Fixed_Add_Vars_Offset+0x10)));
BogdanL 0:f9a13d4b41f3 35 volatile unsigned int CoreReg_LR __attribute__((at(RAM_Start+Fixed_Add_Vars_Offset+0x14)));
BogdanL 0:f9a13d4b41f3 36 volatile unsigned int CoreReg_PC __attribute__((at(RAM_Start+Fixed_Add_Vars_Offset+0x18)));
BogdanL 0:f9a13d4b41f3 37
BogdanL 0:f9a13d4b41f3 38 volatile unsigned int n __attribute__((at(RAM_Start+Fixed_Add_Vars_Offset+0x1C))); // Variable used for counting in loops (4 bytes) stored at RAM address (RamStart+0x54)
BogdanL 0:f9a13d4b41f3 39 volatile unsigned char i __attribute__((at(RAM_Start+Fixed_Add_Vars_Offset+0x20))); // Variable used for counting in loops (1 byte) stored at RAM address (RamStart+0x58)
BogdanL 0:f9a13d4b41f3 40
BogdanL 0:f9a13d4b41f3 41 volatile unsigned int *FLASH_ptr_4B __attribute__((at(RAM_Start+Fixed_Add_Vars_Offset+0x24))); // Pointer that points to flash (4 bytes) stored at RAM address (RamStart+0x5C)
BogdanL 0:f9a13d4b41f3 42 volatile unsigned int *RAM_ptr __attribute__((at(RAM_Start+Fixed_Add_Vars_Offset+0x28))); // Pointer that points to RAM (4 bytes) stored at RAM address (RamStart+0x60)
BogdanL 0:f9a13d4b41f3 43 // Arrays used to store the contents of the peripheral registers
BogdanL 0:f9a13d4b41f3 44 volatile unsigned int dum __attribute__((at(RAM_Start+Fixed_Add_Vars_Offset+0x2C))) = 0x1234FFFF;
BogdanL 0:f9a13d4b41f3 45 volatile unsigned int REG_Array_4B[No_Of_4B_Peripheral_Reg] __attribute__((at(RAM_Start+Fixed_Add_Vars_Offset+0x30)));;
BogdanL 0:f9a13d4b41f3 46 volatile unsigned char REG_Array_1B[No_Of_1B_Peripheral_Reg] __attribute__((at(RAM_Start+Fixed_Add_Vars_Offset+0x30+4*No_Of_4B_Peripheral_Reg)));;
BogdanL 0:f9a13d4b41f3 47
BogdanL 0:f9a13d4b41f3 48 volatile unsigned int dummyread; // Variable used for serialization
BogdanL 0:f9a13d4b41f3 49
BogdanL 0:f9a13d4b41f3 50 void Hibernus(){
BogdanL 0:f9a13d4b41f3 51 //pc1.printf("flags %x %x ",((unsigned int*)(RAM_Start +Fixed_Add_Vars_Offset+ Fixed_Add_Vars_Size))+(int)((RAM_Size-Fixed_Add_Vars_Offset-Fixed_Add_Vars_Size)/4),&dum);
BogdanL 0:f9a13d4b41f3 52 #if SaveFlagsInFlash == 0
BogdanL 0:f9a13d4b41f3 53 restore_flags();
BogdanL 0:f9a13d4b41f3 54 #endif
BogdanL 0:f9a13d4b41f3 55
BogdanL 0:f9a13d4b41f3 56 if( isFlagSet(&FLAG_2) && isFlagSet(&FLAG_3) && isFlagSet(&FLAG_4)) // Enter this only after complete shut down
BogdanL 0:f9a13d4b41f3 57 {
BogdanL 0:f9a13d4b41f3 58 erase_flags_memory();
BogdanL 0:f9a13d4b41f3 59 setFlag(&FLAG_1);
BogdanL 0:f9a13d4b41f3 60 setFlag(&FLAG_4);
BogdanL 0:f9a13d4b41f3 61 }
BogdanL 0:f9a13d4b41f3 62
BogdanL 0:f9a13d4b41f3 63 if(isFlagSet(&FLAG_1)||isFlagSet(&FLAG_2)||isFlagSet(&FLAG_3)||isFlagSet(&FLAG_4))
BogdanL 0:f9a13d4b41f3 64 {
BogdanL 0:f9a13d4b41f3 65 __enable_irq(); // Enable interrupts
BogdanL 0:f9a13d4b41f3 66 Enter_LLS(); // Enter LLS mode
BogdanL 0:f9a13d4b41f3 67 }
BogdanL 0:f9a13d4b41f3 68
BogdanL 0:f9a13d4b41f3 69 if(!isFlagSet(&FLAG_1)) // If *FLAG_1 is not already set (first time waking up)
BogdanL 0:f9a13d4b41f3 70 {
BogdanL 0:f9a13d4b41f3 71 erase_flags_memory();
BogdanL 0:f9a13d4b41f3 72 setFlag(&FLAG_2);
BogdanL 0:f9a13d4b41f3 73
BogdanL 0:f9a13d4b41f3 74 #if HasInternalComparator == 1
BogdanL 0:f9a13d4b41f3 75 configure_VH_comparator_interrupt();
BogdanL 0:f9a13d4b41f3 76 #else
BogdanL 0:f9a13d4b41f3 77 configure_VH_gpio_interrupt();
BogdanL 0:f9a13d4b41f3 78 #endif
BogdanL 0:f9a13d4b41f3 79 __enable_irq(); // Enable interrupts
BogdanL 0:f9a13d4b41f3 80 }
BogdanL 0:f9a13d4b41f3 81 else{
BogdanL 0:f9a13d4b41f3 82 if(isFlagSet(&FLAG_4))
BogdanL 0:f9a13d4b41f3 83 {
BogdanL 0:f9a13d4b41f3 84 #if HasInternalComparator == 1
BogdanL 0:f9a13d4b41f3 85 configure_VH_comparator_interrupt();
BogdanL 0:f9a13d4b41f3 86 #else
BogdanL 0:f9a13d4b41f3 87 configure_VH_gpio_interrupt();
BogdanL 0:f9a13d4b41f3 88 #endif
BogdanL 0:f9a13d4b41f3 89
BogdanL 0:f9a13d4b41f3 90 erase_flags_memory();
BogdanL 0:f9a13d4b41f3 91 setFlag(&FLAG_2);
BogdanL 0:f9a13d4b41f3 92 restore();
BogdanL 0:f9a13d4b41f3 93 }
BogdanL 0:f9a13d4b41f3 94 }
BogdanL 0:f9a13d4b41f3 95 }
BogdanL 0:f9a13d4b41f3 96
BogdanL 0:f9a13d4b41f3 97 void Save_RAM_Regs(){
BogdanL 0:f9a13d4b41f3 98 //Copy the peripheral registers to RAM
BogdanL 0:f9a13d4b41f3 99 for(n=0; n<No_Of_4B_Peripheral_Reg;n++){
BogdanL 0:f9a13d4b41f3 100 REG_Array_4B[n] = *(unsigned int*)REG_Addresses_4B[n];
BogdanL 0:f9a13d4b41f3 101 }
BogdanL 0:f9a13d4b41f3 102 for(n=0; n<No_Of_1B_Peripheral_Reg;n++){
BogdanL 0:f9a13d4b41f3 103 REG_Array_1B[n] = *(unsigned int*)REG_Addresses_1B[n];
BogdanL 0:f9a13d4b41f3 104 }
BogdanL 0:f9a13d4b41f3 105
BogdanL 0:f9a13d4b41f3 106 //copy all the ram to flash
BogdanL 0:f9a13d4b41f3 107 copyRamToFlash();
BogdanL 0:f9a13d4b41f3 108 }
BogdanL 0:f9a13d4b41f3 109
BogdanL 0:f9a13d4b41f3 110 void Restore_Regs(){
BogdanL 0:f9a13d4b41f3 111 //Restore peripheral registers from RAM, After the ram content was copied back from flash, after a restore
BogdanL 0:f9a13d4b41f3 112 for(n=0; n<No_Of_4B_Peripheral_Reg; n++){
BogdanL 0:f9a13d4b41f3 113 *(unsigned int*) REG_Addresses_4B[n] = REG_Array_4B[n];
BogdanL 0:f9a13d4b41f3 114 }
BogdanL 0:f9a13d4b41f3 115
BogdanL 0:f9a13d4b41f3 116 for(i=0; i<No_Of_1B_Peripheral_Reg; i++){
BogdanL 0:f9a13d4b41f3 117 *(unsigned char*) REG_Addresses_1B[i] = REG_Array_1B[i];
BogdanL 0:f9a13d4b41f3 118 }
BogdanL 0:f9a13d4b41f3 119 }
BogdanL 0:f9a13d4b41f3 120
BogdanL 0:f9a13d4b41f3 121 void hibernate(volatile unsigned int Rsp, volatile unsigned int Rlr, volatile unsigned int Rpc){
BogdanL 0:f9a13d4b41f3 122
BogdanL 0:f9a13d4b41f3 123 if(isFlagSet(&FLAG_2)&& isFlagSet(&FLAG_3) && isFlagSet(&FLAG_4)) // Enter this only after complete shut down
BogdanL 0:f9a13d4b41f3 124 {
BogdanL 0:f9a13d4b41f3 125 erase_flags_memory(); // Erase flash sector used to save the flags
BogdanL 0:f9a13d4b41f3 126 setFlag(&FLAG_1);
BogdanL 0:f9a13d4b41f3 127 setFlag(&FLAG_4);
BogdanL 0:f9a13d4b41f3 128 }
BogdanL 0:f9a13d4b41f3 129
BogdanL 0:f9a13d4b41f3 130 if(isFlagSet(&FLAG_2))
BogdanL 0:f9a13d4b41f3 131 {
BogdanL 0:f9a13d4b41f3 132 // Hibernate procedure
BogdanL 0:f9a13d4b41f3 133 __disable_irq(); // Disable interrupts
BogdanL 0:f9a13d4b41f3 134
BogdanL 0:f9a13d4b41f3 135 //save the core registers
BogdanL 0:f9a13d4b41f3 136 CoreReg_SP = Rsp; // 40 for hibernate function 38 otherwsie
BogdanL 0:f9a13d4b41f3 137 CoreReg_LR = Rlr; // 34 for hibernate function 2C otherwise
BogdanL 0:f9a13d4b41f3 138 CoreReg_PC = Rpc; // 38 for hibernate function 30 otherwise
BogdanL 0:f9a13d4b41f3 139
BogdanL 0:f9a13d4b41f3 140
BogdanL 0:f9a13d4b41f3 141 #if HasInternalComparator == 1
BogdanL 0:f9a13d4b41f3 142 Save_RAM_Regs();
BogdanL 0:f9a13d4b41f3 143
BogdanL 0:f9a13d4b41f3 144 setFlag(&FLAG_3);
BogdanL 0:f9a13d4b41f3 145 setFlag(&FLAG_4);
BogdanL 0:f9a13d4b41f3 146
BogdanL 0:f9a13d4b41f3 147 Comparator_Setup();
BogdanL 0:f9a13d4b41f3 148 configure_VH_comparator_interrupt();
BogdanL 0:f9a13d4b41f3 149 #else
BogdanL 0:f9a13d4b41f3 150 setFlag(getFlag_3());
BogdanL 0:f9a13d4b41f3 151 setFlag(getFlag_4());
BogdanL 0:f9a13d4b41f3 152
BogdanL 0:f9a13d4b41f3 153 Save_RAM_Regs();
BogdanL 0:f9a13d4b41f3 154 configure_VH_gpio_interrupt();
BogdanL 0:f9a13d4b41f3 155 #endif
BogdanL 0:f9a13d4b41f3 156
BogdanL 0:f9a13d4b41f3 157 __enable_irq(); // Enable interrupts
BogdanL 0:f9a13d4b41f3 158
BogdanL 0:f9a13d4b41f3 159 Enter_LLS(); // Enter LLS mode
BogdanL 0:f9a13d4b41f3 160 }
BogdanL 0:f9a13d4b41f3 161 }
BogdanL 0:f9a13d4b41f3 162
BogdanL 0:f9a13d4b41f3 163 void restore(){
BogdanL 0:f9a13d4b41f3 164 // Restore procedure
BogdanL 0:f9a13d4b41f3 165 __disable_irq(); // Disable interrupts
BogdanL 0:f9a13d4b41f3 166
BogdanL 0:f9a13d4b41f3 167 erase_flags_memory();
BogdanL 0:f9a13d4b41f3 168 setFlag(&FLAG_2);
BogdanL 0:f9a13d4b41f3 169
BogdanL 0:f9a13d4b41f3 170 //Restore peripheral registers
BogdanL 0:f9a13d4b41f3 171 Restore_Regs();
BogdanL 0:f9a13d4b41f3 172
BogdanL 0:f9a13d4b41f3 173 //Restore RAM
BogdanL 0:f9a13d4b41f3 174 FLASH_ptr_4B = (unsigned int*) (flash_ramSection_start);
BogdanL 0:f9a13d4b41f3 175 RAM_ptr = (unsigned int*) (RAM_Start);
BogdanL 0:f9a13d4b41f3 176
BogdanL 0:f9a13d4b41f3 177 //Copy RAM until where the pointers and loop variables are stored
BogdanL 0:f9a13d4b41f3 178 //divide it by 4 because the copy is done word by word but byte by byte
BogdanL 0:f9a13d4b41f3 179 for(n=0; n<(Fixed_Add_Vars_Offset/4); n++){
BogdanL 0:f9a13d4b41f3 180 *(RAM_ptr + n) = *(FLASH_ptr_4B + n);
BogdanL 0:f9a13d4b41f3 181 }
BogdanL 0:f9a13d4b41f3 182
BogdanL 0:f9a13d4b41f3 183 //skip the Core reg and fixed address variables
BogdanL 0:f9a13d4b41f3 184 FLASH_ptr_4B = (unsigned int*)(flash_ramSection_start +Fixed_Add_Vars_Offset+ Fixed_Add_Vars_Size);
BogdanL 0:f9a13d4b41f3 185 RAM_ptr = (unsigned int*)(RAM_Start +Fixed_Add_Vars_Offset+ Fixed_Add_Vars_Size);
BogdanL 0:f9a13d4b41f3 186
BogdanL 0:f9a13d4b41f3 187 //copy the rest of the RAM
BogdanL 0:f9a13d4b41f3 188 //(RAM_Size-Fixed_Add_Vars_Offset-Fixed_Add_Vars_Size) is the siz eof the rest of the ram that have to be copied
BogdanL 0:f9a13d4b41f3 189 //divide it by 4 because the copy is done word by word but byte by byte
BogdanL 0:f9a13d4b41f3 190 for(n=1; n<(RAM_Size-Fixed_Add_Vars_Offset-Fixed_Add_Vars_Size)/4; n++){
BogdanL 0:f9a13d4b41f3 191 *(RAM_ptr + n) = *(FLASH_ptr_4B + n);
BogdanL 0:f9a13d4b41f3 192 }
BogdanL 0:f9a13d4b41f3 193
BogdanL 0:f9a13d4b41f3 194 //copy the 3 core registers from flash o ram
BogdanL 0:f9a13d4b41f3 195 CoreReg_SP=*(unsigned int*)(flash_ramSection_start+Fixed_Add_Vars_Offset+0x10);
BogdanL 0:f9a13d4b41f3 196 CoreReg_LR=*(unsigned int*)(flash_ramSection_start+Fixed_Add_Vars_Offset+0x14);
BogdanL 0:f9a13d4b41f3 197 CoreReg_PC=*(unsigned int*)(flash_ramSection_start+Fixed_Add_Vars_Offset+0x18);
BogdanL 0:f9a13d4b41f3 198
BogdanL 0:f9a13d4b41f3 199 #if SaveFlagsInFlash == 1 //if the flags are stored in their own flash sector, their default value(the flags address in their flash sector) have to be restored
BogdanL 0:f9a13d4b41f3 200 //otherwise, their value has to be unchanged, there is no need for restore
BogdanL 0:f9a13d4b41f3 201 FLAG_1 =*(unsigned int*)(flash_ramSection_start+Fixed_Add_Vars_Offset);
BogdanL 0:f9a13d4b41f3 202 FLAG_2 =*(unsigned int*)(flash_ramSection_start+Fixed_Add_Vars_Offset +0x4);
BogdanL 0:f9a13d4b41f3 203 FLAG_3 =*(unsigned int*)(flash_ramSection_start+Fixed_Add_Vars_Offset +0x8);
BogdanL 0:f9a13d4b41f3 204 FLAG_4 =*(unsigned int*)(flash_ramSection_start+Fixed_Add_Vars_Offset +0xC);
BogdanL 0:f9a13d4b41f3 205 #else
BogdanL 0:f9a13d4b41f3 206 configure_VH_gpio_interrupt();
BogdanL 0:f9a13d4b41f3 207 #endif
BogdanL 0:f9a13d4b41f3 208
BogdanL 0:f9a13d4b41f3 209 __enable_irq(); // Enable interrupts
BogdanL 0:f9a13d4b41f3 210
BogdanL 0:f9a13d4b41f3 211 asm_restore(); // Restore the SP
BogdanL 0:f9a13d4b41f3 212 _LR = CoreReg_LR; // Restore the LR
BogdanL 0:f9a13d4b41f3 213 _PC = CoreReg_PC; // Restore the PC
BogdanL 0:f9a13d4b41f3 214 }
BogdanL 0:f9a13d4b41f3 215
BogdanL 0:f9a13d4b41f3 216 //use to check if you recover from a sleep without power loss
BogdanL 0:f9a13d4b41f3 217 //is so, don't restore, and just set the VH interrupt
BogdanL 0:f9a13d4b41f3 218 void recovery_no_power_loss(){
BogdanL 0:f9a13d4b41f3 219
BogdanL 0:f9a13d4b41f3 220 if(isFlagSet(getFlag_3())){ // Enter after hibernation with no power loss
BogdanL 0:f9a13d4b41f3 221 #if HasInternalComparator == 1
BogdanL 0:f9a13d4b41f3 222 configure_VH_comparator_interrupt();
BogdanL 0:f9a13d4b41f3 223 #else
BogdanL 0:f9a13d4b41f3 224 configure_VH_gpio_interrupt();
BogdanL 0:f9a13d4b41f3 225 #endif
BogdanL 0:f9a13d4b41f3 226
BogdanL 0:f9a13d4b41f3 227 erase_flags_memory(); // Erase flash sector used to save the flags
BogdanL 0:f9a13d4b41f3 228 setFlag(getFlag_2());
BogdanL 0:f9a13d4b41f3 229
BogdanL 0:f9a13d4b41f3 230 __enable_irq(); // Enable interrupts
BogdanL 0:f9a13d4b41f3 231 }
BogdanL 0:f9a13d4b41f3 232 }
BogdanL 0:f9a13d4b41f3 233 extern "C" volatile unsigned int* getFlag_1(){
BogdanL 0:f9a13d4b41f3 234 return &FLAG_1;
BogdanL 0:f9a13d4b41f3 235 }
BogdanL 0:f9a13d4b41f3 236
BogdanL 0:f9a13d4b41f3 237 extern "C" volatile unsigned int* getFlag_2(){
BogdanL 0:f9a13d4b41f3 238 return &FLAG_2;
BogdanL 0:f9a13d4b41f3 239 }
BogdanL 0:f9a13d4b41f3 240
BogdanL 0:f9a13d4b41f3 241 extern "C" volatile unsigned int* getFlag_3(){
BogdanL 0:f9a13d4b41f3 242 return &FLAG_3;
BogdanL 0:f9a13d4b41f3 243 }
BogdanL 0:f9a13d4b41f3 244
BogdanL 0:f9a13d4b41f3 245 extern "C" volatile unsigned int* getFlag_4(){
BogdanL 0:f9a13d4b41f3 246 return &FLAG_4;
BogdanL 0:f9a13d4b41f3 247 }
BogdanL 0:f9a13d4b41f3 248
BogdanL 0:f9a13d4b41f3 249