Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
hibernus.cpp
00001 /** Hibernus Library 00002 * University of Southampton 2017 00003 * 00004 * Open-source liberary that enable any of your Mbed project work with transient enegy sources. 00005 * In order to use this library include the "hibernus.h" header file, and use the "Hibernus()" method at the beginning of you main funtion. 00006 * For more details and example see the "main.cpp" exampe file, and the attached documnetation 00007 * 00008 * 00009 * Released under the MIT License: http://mbed.org/license/mit 00010 */ 00011 #include "hibernus.h" 00012 #include "mbed.h" 00013 #include "config.h" 00014 #ifdef LPC11U24 00015 #include "Driver_LPC11U24.h" 00016 #endif 00017 #ifdef KL05Z 00018 #include "Driver_KL05Z.h" 00019 #endif 00020 00021 //11 variables stored at fixed addresses at the beginning of the RAM 00022 #if SaveFlagsInFlash == 0 00023 volatile unsigned int FLAG_1 __attribute__((at(RAM_Start+Fixed_Add_Vars_Offset)));// = Flash_Flags_Sector_Start; 00024 volatile unsigned int FLAG_2 __attribute__((at(RAM_Start+Fixed_Add_Vars_Offset+ 0x4)));// = Flash_Flags_Sector_Start + 0x4; 00025 volatile unsigned int FLAG_3 __attribute__((at(RAM_Start+Fixed_Add_Vars_Offset+ 0x8)));// = Flash_Flags_Sector_Start + 0x8; 00026 volatile unsigned int FLAG_4 __attribute__((at(RAM_Start+Fixed_Add_Vars_Offset+ 0xC)));// = Flash_Flags_Sector_Start + 0xC; 00027 #else 00028 volatile unsigned int FLAG_1 __attribute__((at(RAM_Start+Fixed_Add_Vars_Offset))) = Flash_Flags_Sector_Start; 00029 volatile unsigned int FLAG_2 __attribute__((at(RAM_Start+Fixed_Add_Vars_Offset+ 0x4))) = Flash_Flags_Sector_Start + 0x4; 00030 volatile unsigned int FLAG_3 __attribute__((at(RAM_Start+Fixed_Add_Vars_Offset+ 0x8))) = Flash_Flags_Sector_Start + 0x8; 00031 volatile unsigned int FLAG_4 __attribute__((at(RAM_Start+Fixed_Add_Vars_Offset+ 0xC))) = Flash_Flags_Sector_Start + 0xC; 00032 #endif 00033 00034 volatile unsigned int CoreReg_SP __attribute__((at(RAM_Start+Fixed_Add_Vars_Offset+0x10))); 00035 volatile unsigned int CoreReg_LR __attribute__((at(RAM_Start+Fixed_Add_Vars_Offset+0x14))); 00036 volatile unsigned int CoreReg_PC __attribute__((at(RAM_Start+Fixed_Add_Vars_Offset+0x18))); 00037 00038 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) 00039 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) 00040 00041 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) 00042 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) 00043 // Arrays used to store the contents of the peripheral registers 00044 volatile unsigned int dum __attribute__((at(RAM_Start+Fixed_Add_Vars_Offset+0x2C))) = 0x1234FFFF; 00045 volatile unsigned int REG_Array_4B[No_Of_4B_Peripheral_Reg] __attribute__((at(RAM_Start+Fixed_Add_Vars_Offset+0x30)));; 00046 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)));; 00047 00048 volatile unsigned int dummyread; // Variable used for serialization 00049 00050 void Hibernus(){ 00051 //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); 00052 #if SaveFlagsInFlash == 0 00053 restore_flags(); 00054 #endif 00055 00056 if( isFlagSet(&FLAG_2) && isFlagSet(&FLAG_3) && isFlagSet(&FLAG_4)) // Enter this only after complete shut down 00057 { 00058 erase_flags_memory(); 00059 setFlag(&FLAG_1); 00060 setFlag(&FLAG_4); 00061 } 00062 00063 if(isFlagSet(&FLAG_1)||isFlagSet(&FLAG_2)||isFlagSet(&FLAG_3)||isFlagSet(&FLAG_4)) 00064 { 00065 __enable_irq(); // Enable interrupts 00066 Enter_LLS(); // Enter LLS mode 00067 } 00068 00069 if(!isFlagSet(&FLAG_1)) // If *FLAG_1 is not already set (first time waking up) 00070 { 00071 erase_flags_memory(); 00072 setFlag(&FLAG_2); 00073 00074 #if HasInternalComparator == 1 00075 configure_VH_comparator_interrupt(); 00076 #else 00077 configure_VH_gpio_interrupt(); 00078 #endif 00079 __enable_irq(); // Enable interrupts 00080 } 00081 else{ 00082 if(isFlagSet(&FLAG_4)) 00083 { 00084 #if HasInternalComparator == 1 00085 configure_VH_comparator_interrupt(); 00086 #else 00087 configure_VH_gpio_interrupt(); 00088 #endif 00089 00090 erase_flags_memory(); 00091 setFlag(&FLAG_2); 00092 restore(); 00093 } 00094 } 00095 } 00096 00097 void Save_RAM_Regs(){ 00098 //Copy the peripheral registers to RAM 00099 for(n=0; n<No_Of_4B_Peripheral_Reg;n++){ 00100 REG_Array_4B[n] = *(unsigned int*)REG_Addresses_4B[n]; 00101 } 00102 for(n=0; n<No_Of_1B_Peripheral_Reg;n++){ 00103 REG_Array_1B[n] = *(unsigned int*)REG_Addresses_1B[n]; 00104 } 00105 00106 //copy all the ram to flash 00107 copyRamToFlash(); 00108 } 00109 00110 void Restore_Regs(){ 00111 //Restore peripheral registers from RAM, After the ram content was copied back from flash, after a restore 00112 for(n=0; n<No_Of_4B_Peripheral_Reg; n++){ 00113 *(unsigned int*) REG_Addresses_4B[n] = REG_Array_4B[n]; 00114 } 00115 00116 for(i=0; i<No_Of_1B_Peripheral_Reg; i++){ 00117 *(unsigned char*) REG_Addresses_1B[i] = REG_Array_1B[i]; 00118 } 00119 } 00120 00121 void hibernate(volatile unsigned int Rsp, volatile unsigned int Rlr, volatile unsigned int Rpc){ 00122 00123 if(isFlagSet(&FLAG_2)&& isFlagSet(&FLAG_3) && isFlagSet(&FLAG_4)) // Enter this only after complete shut down 00124 { 00125 erase_flags_memory(); // Erase flash sector used to save the flags 00126 setFlag(&FLAG_1); 00127 setFlag(&FLAG_4); 00128 } 00129 00130 if(isFlagSet(&FLAG_2)) 00131 { 00132 // Hibernate procedure 00133 __disable_irq(); // Disable interrupts 00134 00135 //save the core registers 00136 CoreReg_SP = Rsp; // 40 for hibernate function 38 otherwsie 00137 CoreReg_LR = Rlr; // 34 for hibernate function 2C otherwise 00138 CoreReg_PC = Rpc; // 38 for hibernate function 30 otherwise 00139 00140 00141 #if HasInternalComparator == 1 00142 Save_RAM_Regs(); 00143 00144 setFlag(&FLAG_3); 00145 setFlag(&FLAG_4); 00146 00147 Comparator_Setup(); 00148 configure_VH_comparator_interrupt(); 00149 #else 00150 setFlag(getFlag_3()); 00151 setFlag(getFlag_4()); 00152 00153 Save_RAM_Regs(); 00154 configure_VH_gpio_interrupt(); 00155 #endif 00156 00157 __enable_irq(); // Enable interrupts 00158 00159 Enter_LLS(); // Enter LLS mode 00160 } 00161 } 00162 00163 void restore(){ 00164 // Restore procedure 00165 __disable_irq(); // Disable interrupts 00166 00167 erase_flags_memory(); 00168 setFlag(&FLAG_2); 00169 00170 //Restore peripheral registers 00171 Restore_Regs(); 00172 00173 //Restore RAM 00174 FLASH_ptr_4B = (unsigned int*) (flash_ramSection_start); 00175 RAM_ptr = (unsigned int*) (RAM_Start); 00176 00177 //Copy RAM until where the pointers and loop variables are stored 00178 //divide it by 4 because the copy is done word by word but byte by byte 00179 for(n=0; n<(Fixed_Add_Vars_Offset/4); n++){ 00180 *(RAM_ptr + n) = *(FLASH_ptr_4B + n); 00181 } 00182 00183 //skip the Core reg and fixed address variables 00184 FLASH_ptr_4B = (unsigned int*)(flash_ramSection_start +Fixed_Add_Vars_Offset+ Fixed_Add_Vars_Size); 00185 RAM_ptr = (unsigned int*)(RAM_Start +Fixed_Add_Vars_Offset+ Fixed_Add_Vars_Size); 00186 00187 //copy the rest of the RAM 00188 //(RAM_Size-Fixed_Add_Vars_Offset-Fixed_Add_Vars_Size) is the siz eof the rest of the ram that have to be copied 00189 //divide it by 4 because the copy is done word by word but byte by byte 00190 for(n=1; n<(RAM_Size-Fixed_Add_Vars_Offset-Fixed_Add_Vars_Size)/4; n++){ 00191 *(RAM_ptr + n) = *(FLASH_ptr_4B + n); 00192 } 00193 00194 //copy the 3 core registers from flash o ram 00195 CoreReg_SP=*(unsigned int*)(flash_ramSection_start+Fixed_Add_Vars_Offset+0x10); 00196 CoreReg_LR=*(unsigned int*)(flash_ramSection_start+Fixed_Add_Vars_Offset+0x14); 00197 CoreReg_PC=*(unsigned int*)(flash_ramSection_start+Fixed_Add_Vars_Offset+0x18); 00198 00199 #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 00200 //otherwise, their value has to be unchanged, there is no need for restore 00201 FLAG_1 =*(unsigned int*)(flash_ramSection_start+Fixed_Add_Vars_Offset); 00202 FLAG_2 =*(unsigned int*)(flash_ramSection_start+Fixed_Add_Vars_Offset +0x4); 00203 FLAG_3 =*(unsigned int*)(flash_ramSection_start+Fixed_Add_Vars_Offset +0x8); 00204 FLAG_4 =*(unsigned int*)(flash_ramSection_start+Fixed_Add_Vars_Offset +0xC); 00205 #else 00206 configure_VH_gpio_interrupt(); 00207 #endif 00208 00209 __enable_irq(); // Enable interrupts 00210 00211 asm_restore(); // Restore the SP 00212 _LR = CoreReg_LR; // Restore the LR 00213 _PC = CoreReg_PC; // Restore the PC 00214 } 00215 00216 //use to check if you recover from a sleep without power loss 00217 //is so, don't restore, and just set the VH interrupt 00218 void recovery_no_power_loss(){ 00219 00220 if(isFlagSet(getFlag_3())){ // Enter after hibernation with no power loss 00221 #if HasInternalComparator == 1 00222 configure_VH_comparator_interrupt(); 00223 #else 00224 configure_VH_gpio_interrupt(); 00225 #endif 00226 00227 erase_flags_memory(); // Erase flash sector used to save the flags 00228 setFlag(getFlag_2()); 00229 00230 __enable_irq(); // Enable interrupts 00231 } 00232 } 00233 extern "C" volatile unsigned int* getFlag_1(){ 00234 return &FLAG_1; 00235 } 00236 00237 extern "C" volatile unsigned int* getFlag_2(){ 00238 return &FLAG_2; 00239 } 00240 00241 extern "C" volatile unsigned int* getFlag_3(){ 00242 return &FLAG_3; 00243 } 00244 00245 extern "C" volatile unsigned int* getFlag_4(){ 00246 return &FLAG_4; 00247 } 00248 00249
Generated on Wed Jul 27 2022 03:07:51 by
1.7.2