Bogdan Lazarescu / Mbed 2 deprecated Hibernus-KL05Z

Dependencies:   FreescaleIAP mbed

Files at this revision

API Documentation at this revision

Comitter:
BogdanL
Date:
Fri Sep 01 14:37:15 2017 +0000
Commit message:
First version of the Hibernus Library. V1.0

Changed in this revision

FreescaleIAP.lib Show annotated file Show diff for this revision Revisions of this file
asm_restore.s Show annotated file Show diff for this revision Revisions of this file
config.cpp Show annotated file Show diff for this revision Revisions of this file
config.h Show annotated file Show diff for this revision Revisions of this file
hibernus.cpp Show annotated file Show diff for this revision Revisions of this file
hibernus.h Show annotated file Show diff for this revision Revisions of this file
main.cpp Show annotated file Show diff for this revision Revisions of this file
mbed.bld Show annotated file Show diff for this revision Revisions of this file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/FreescaleIAP.lib	Fri Sep 01 14:37:15 2017 +0000
@@ -0,0 +1,1 @@
+http://mbed.org/users/Sissors/code/FreescaleIAP/#ab8a833a25eb
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/asm_restore.s	Fri Sep 01 14:37:15 2017 +0000
@@ -0,0 +1,12 @@
+    AREA asm_func, CODE, READONLY
+; Export my_asm function location so that C compiler can find it and link
+    EXPORT asm_restore
+asm_restore
+
+    LDR    R2,  =0x1FFFFC50  // Use R2 as auxiliary register (address of RAM sector 3)
+    
+    LDR    R1,  [R2]         // Load R1 with value of R13 (SP) stored in RAM
+    MOV    SP,  R1           // Copy value of R1 into R13 (SP)
+    
+    BX     LR
+END
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/config.cpp	Fri Sep 01 14:37:15 2017 +0000
@@ -0,0 +1,151 @@
+/**    Hibernus Library
+ *	   University of Southampton 2017
+ *
+ *		Open-source liberary that enable any of your Mbed project work with transient enegy sources.
+ *		In order to use this library include the "hibernus.h" header file, and use the "Hibernus()" method at the beginning of you main funtion.
+ *		For more details and example see the "main.cpp" exampe file, and the attached documnetation
+ *
+ *
+ *     Released under the MIT License: http://mbed.org/license/mit
+ */
+#include "config.h"
+#include "hibernus.h"
+
+volatile unsigned int dummyread;      // Variable used for serialization
+extern "C" void CMP0_IRQHandler()   //To make sure the compiler sees handler, need to declare it as extern (https://developer.mbed.org/forum/mbed/topic/419/?page=1#comment-2126)
+{
+	
+	CMP0->SCR |= CMP_SCR_CFF_MASK | CMP_SCR_CFR_MASK;   // Clear CMP0 flags
+  dummyread = CMP0->SCR;                              // Read back for serialization
+
+    
+  if(isFlagSet(getFlag_2())&& isFlagSet(getFlag_3()) && isFlagSet(getFlag_4())){  // Enter this only after complete shut down
+		erase_flags_memory(); 													// Erase flash sector used to save the flags 
+		setFlag(getFlag_1());
+		setFlag(getFlag_4());
+   }
+    
+	if(isFlagSet(getFlag_2())){									// Hibernate procedure           
+		__disable_irq();     									// Disable interrupts
+    
+		volatile unsigned int sp1=(_SP+0x28), lr1= *(unsigned int*)(_SP+0x1C), pc1=*(unsigned int*)(_SP+0x20);
+		// Save previous SP value from main // 0x40 for hibernate function 38 otherwsie
+     *getCore_SP() = sp1;                        
+    
+     // Save previous LR value from main// 34 for hibernate function 2C otherwise
+		*getCore_LR() = lr1;
+			
+     // Save previous PC value from main // 38 for hibernate function 30 otherwise
+		*getCore_PC() = pc1;
+    
+    Save_RAM_Regs();
+
+		setFlag(getFlag_3());
+		setFlag(getFlag_4());
+        
+    Comparator_Setup();
+    CMP0->DACCR = 0xDA;               // Enable DAC, Vdd is 6-bit reference, threshold set to P3V3 = +2.37V (V_R)
+    CMP0->SCR = 0x16;                 // Enable all interrupts and clear flags
+    CMP0->CR1 |= CMP_CR1_EN_MASK;     // Enable comparator module
+                                        
+    __enable_irq();     // Enable interrupts
+		
+    Enter_LLS();        // Enter LLS mode
+    }
+}
+
+extern "C" void LLW_IRQHandler(){
+	
+    CMP0->SCR |= CMP_SCR_CFF_MASK | CMP_SCR_CFR_MASK;   // Clear CMP0 flags
+    dummyread = CMP0->SCR;                              // Read back for serialization
+    NVIC_ClearPendingIRQ(CMP0_IRQn);                    // Clear pending CMP0 interrupt so that the CMP_IRQ is not entered
+    
+		if(isFlagSet(getFlag_3())){   // Enter after hibernation with no power loss
+			Comparator_Setup();
+      CMP0->DACCR = 0xDC;               // Enable DAC, Vdd is 6-bit reference, threshold set to P3V3 = +2.21V (V_H)
+      CMP0->SCR = 0x0E;                 // Enable falling edge interrupt and clear flags
+      CMP0->CR1 |= CMP_CR1_EN_MASK;     // Enable comparator module
+        
+			erase_flags_memory();  // Erase flash sector used to save the flags 
+			setFlag(getFlag_2());
+			
+      __enable_irq();     // Enable interrupts
+    }
+}
+void Comparator_Setup(){
+	
+  NVIC_SetPriority(CMP0_IRQn, 1);     // Lower the CMP0 interrupt priority from 0 to 1 (smaller number = higher priority)
+  NVIC_EnableIRQ(CMP0_IRQn);          // Enable CMP0 interrupts in NVIC
+    
+  SIM->SCGC4 |= SIM_SCGC4_CMP_MASK;       // Enable comparator module clock
+  LLWU->ME |= LLWU_ME_WUME1_MASK;         // Enable CMP0 as a LLWU source
+  PMC->REGSC |= PMC_REGSC_BGEN_MASK |     // Allow bangap buffer in low power operation
+                  PMC_REGSC_BGBE_MASK;      // Enable bandgap buffer for +1V reference (CMP0_IN6)
+                  
+  // Comparator in sampled, filtered mode 4B
+  CMP0->CR0 = 0x22;                 // Hysteresis level 2 (20mV) and 2 consecutive filter samples must agree
+  CMP0->CR1 = 0x00;                 // Low-speed compare, non-inverted output, use filtered output and disable comparator output pin PTA2
+  CMP0->FPR = 0x01;                 // Filter sample period = 1 bus clock cycle
+  CMP0->SCR = 0x06;                 // Disable all interrupts and clear flags
+  CMP0->DACCR = 0x40;               // Disable DAC, Vdd is 6-bit reference, threshold set to zero
+  CMP0->MUXCR = 0x3E;               // CMP0_IN7 (DAC) to V+ channel and CMP0_IN6 (+1V bandgap) to V- 3E
+}
+
+void Enter_LLS(){
+	
+	Comparator_Setup();
+  CMP0->DACCR = 0xDA;               // Enable DAC, Vdd is 6-bit reference, threshold set to P3V3 = +2.37V (V_R)
+  CMP0->SCR = 0x16;                 // Enable rising edge interrupt and clear flags
+  CMP0->CR1 |= CMP_CR1_EN_MASK;     // Enable comparator module
+	
+  NVIC_EnableIRQ(LLW_IRQn);               // Enable LLW interrupts in NVIC
+  MCG->C6 &= ~(MCG_C6_CME_MASK);          // DIsable all clock monitors
+  SCB->SCR = 1<<SCB_SCR_SLEEPDEEP_Pos;    // Set the SLEEPDEEP bit for stop mode
+    
+  SMC->PMPROT = SMC_PMPROT_ALLS_MASK;         // Allow LLS power modes
+  SMC->PMCTRL &= ~(SMC_PMCTRL_STOPM_MASK);    // Serialisation
+  SMC->PMCTRL = SMC_PMCTRL_STOPM(0x3);        // Select LLS as desired power mode
+  dummyread = SMC->PMCTRL;                    // Read back for serialisation
+
+  __WFI();    // Stop executing instructions and enter LLS (wait for interrupt)
+}
+
+void configure_VH_comparator_interrupt(){                            
+  Comparator_Setup();
+  CMP0->DACCR = 0xDC;               // Enable DAC, Vdd is 6-bit reference, threshold set to P3V3 = +2.21V (V_H)
+  CMP0->SCR = 0x0E;                 // Enable falling edge interrupt and clear flags
+  CMP0->CR1 |= CMP_CR1_EN_MASK;     // Enable comparator module
+}
+
+void setFlag(volatile unsigned int* add){
+	const unsigned int set = Flag_set;
+	program_flash(*add,(char*)&set,4);			//if the flags are stored in flash, use this line
+}
+
+bool isFlagSet(volatile unsigned int* add){
+	if( *(unsigned int *)(*add) == Flag_set) return true;
+	return false;
+}
+
+void erase_flash_secors_for_RAM(){
+	int i;
+	for(i = 2; i<= 2+ramToFlash_sectors_number; i++)				//start the erase from the 3rd last block, the first 2 are used for flags and peripheral registers
+		erase_sector(flash_end-i*sector_Size);
+}
+
+void erase_flags_memory(){
+	if(!SaveFlagsInFlash) {
+    *getFlag_1() = Flag_erase;
+    *getFlag_2() = Flag_erase;
+    *getFlag_3() = Flag_erase;
+    *getFlag_4() = Flag_erase;
+	}else{
+		erase_sector(Flash_Flags_Sector_Start);
+	}
+}
+
+void copyRamToFlash(){
+	// Erase flash sectors o save the RAM content
+	erase_flash_secors_for_RAM();  
+	program_flash(flash_ramSection_start, (char*) RAM_1_Address, RAM_Size);     // Copy all the RAM to flash
+}
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/config.h	Fri Sep 01 14:37:15 2017 +0000
@@ -0,0 +1,111 @@
+/**    Hibernus Library
+ *	   University of Southampton 2017
+ *
+ *		Open-source liberary that enable any of your Mbed project work with transient enegy sources.
+ *		In order to use this library include the "hibernus.h" header file, and use the "Hibernus()" method at the beginning of you main funtion.
+ *		For more details and example see the "main.cpp" exampe file, and the attached documnetation
+ *
+ *
+ *     Released under the MIT License: http://mbed.org/license/mit
+ */
+#ifndef CONFIG_H_
+#define CONFIG_H_
+#include "mbed.h"
+#include "FreescaleIAP.h"
+
+#define HasInternalComparator 1							//Set on 1 if there is an internal comparator 0 otherwise
+#define SaveFlagsInFlash	1									//set on 1 if there is enough Flash memory available for the flags to have their own flash sector, 0 otherwise
+																						//if there is not enough flash memory, the flags will be saved in RAM memory
+
+// RAM addresses split in 1 KB sectors
+#define RAM_1_Address  0x1FFFFC00
+#define FLASH_Start 0x00000000
+#define RAM_Size 4096
+#define flash_Size flash_size()				//32K flash
+#define sector_Size SECTOR_SIZE				//4K sector size
+#define Flash_Flags_Sector_Start (flash_end -1*sector_Size)
+
+#define No_Of_4B_Peripheral_Reg 19
+#define No_Of_1B_Peripheral_Reg 8
+
+
+const unsigned int REG_Addresses_4B[83] =     // Constant peripheral register addresses which are 4 bytes in size
+    {
+		(unsigned int)&FPTA->PDOR,(unsigned int)&FPTA->PDDR,(unsigned int)&FPTB->PDOR,(unsigned int)&FPTB->PDDR,
+		 //0x4000F000, 0x4000F014, 0x4000F040, 0x4000F054,    // GPIO controller aliased to ox400FF000
+		(unsigned int)&SIM->SOPT1,(unsigned int)&SIM->SOPT1CFG,(unsigned int)&SIM->SOPT2,(unsigned int)&SIM->SOPT4,
+		(unsigned int)&SIM->SOPT5,(unsigned int)&SIM->SOPT7,(unsigned int)&SIM->SCGC4,(unsigned int)&SIM->SCGC5,
+		(unsigned int)&SIM->SCGC6,(unsigned int)&SIM->SCGC7,(unsigned int)&SIM->CLKDIV1,(unsigned int)&SIM->FCFG1,
+		(unsigned int)&SIM->COPC,
+     //0x40047000, 0x40047004, 0x40048004, 0x4004800C, 0x40048010, 0x40048018, 0x40048034, 0x40048038, 0x4004803C, 0x40048040,
+     //0x40048044, 0x4004804C, 0x40048100,    // SIM
+		/*(unsigned int)&PORTA->PCR[0],(unsigned int)&PORTA->PCR[1],(unsigned int)&PORTA->PCR[2],(unsigned int)&PORTA->PCR[3],
+		(unsigned int)&PORTA->PCR[4],(unsigned int)&PORTA->PCR[5],(unsigned int)&PORTA->PCR[6],(unsigned int)&PORTA->PCR[7],
+		(unsigned int)&PORTA->PCR[8],(unsigned int)&PORTA->PCR[9],(unsigned int)&PORTA->PCR[10],(unsigned int)&PORTA->PCR[11],
+		(unsigned int)&PORTA->PCR[12],(unsigned int)&PORTA->PCR[13],(unsigned int)&PORTA->PCR[14],(unsigned int)&PORTA->PCR[15],
+		(unsigned int)&PORTA->PCR[16],(unsigned int)&PORTA->PCR[17],(unsigned int)&PORTA->PCR[18],(unsigned int)&PORTA->PCR[19],
+		(unsigned int)&PORTA->PCR[20],(unsigned int)&PORTA->PCR[21],(unsigned int)&PORTA->PCR[22],(unsigned int)&PORTA->PCR[23],
+		(unsigned int)&PORTA->PCR[24],(unsigned int)&PORTA->PCR[25],(unsigned int)&PORTA->PCR[26],(unsigned int)&PORTA->PCR[27],
+		(unsigned int)&PORTA->PCR[28],(unsigned int)&PORTA->PCR[29],(unsigned int)&PORTA->PCR[30],(unsigned int)&PORTA->PCR[31],
+     //0x40049000, 0x40049004, 0x40049008, 0x4004900C, 0x40049010, 0x40049014, 0x40049018, 0x4004901C, 0x40049020, 0x40049024,
+     //0x40049028, 0x4004902C, 0x40049030, 0x40049034, 0x40049038, 0x4004903C, 0x40049040, 0x40049044, 0x40049048, 0x4004904C,
+     //0x40049050, 0x40049054, 0x40049058, 0x4004905C, 0x40049060, 0x40049064, 0x40049068, 0x4004906C, 0x40049070, 0x40049074,
+     //0x40049078, 0x4004907C,    // Port A multiplexing control
+		(unsigned int)&PORTB->PCR[0],(unsigned int)&PORTB->PCR[1],(unsigned int)&PORTB->PCR[2],(unsigned int)&PORTB->PCR[3],
+		(unsigned int)&PORTB->PCR[4],(unsigned int)&PORTB->PCR[5],(unsigned int)&PORTB->PCR[6],(unsigned int)&PORTB->PCR[7],
+		(unsigned int)&PORTB->PCR[8],(unsigned int)&PORTB->PCR[9],(unsigned int)&PORTB->PCR[10],(unsigned int)&PORTB->PCR[11],
+		(unsigned int)&PORTB->PCR[12],(unsigned int)&PORTB->PCR[13],(unsigned int)&PORTB->PCR[14],(unsigned int)&PORTB->PCR[15],
+		(unsigned int)&PORTB->PCR[16],(unsigned int)&PORTB->PCR[17],(unsigned int)&PORTB->PCR[18],(unsigned int)&PORTB->PCR[19],
+		(unsigned int)&PORTB->PCR[20],(unsigned int)&PORTB->PCR[21],(unsigned int)&PORTB->PCR[22],(unsigned int)&PORTB->PCR[23],
+		(unsigned int)&PORTB->PCR[24],(unsigned int)&PORTB->PCR[25],(unsigned int)&PORTB->PCR[26],(unsigned int)&PORTB->PCR[27],
+		(unsigned int)&PORTB->PCR[28],(unsigned int)&PORTB->PCR[29],(unsigned int)&PORTB->PCR[30],(unsigned int)&PORTB->PCR[31],
+     //0x4004A000, 0x4004A004, 0x4004A008, 0x4004A00C, 0x4004A010, 0x4004A014, 0x4004A018, 0x4004A01C, 0x4004A020, 0x4004A024,
+     //0x4004A028, 0x4004A02C, 0x4004A030, 0x4004A034, 0x4004A038, 0x4004A03C, 0x4004A040, 0x4004A044, 0x4004A048, 0x4004A04C,
+     //0x4004A050, 0x4004A054, 0x4004A058, 0x4004A05C, 0x4004A060, 0x4004A064, 0x4004A068, 0x4004A06C, 0x4004A070, 0x4004A074,
+     //0x4004A078, 0x4004A07C,    // Port B multiplexing control*/
+		(unsigned int)&MCM->PLACR,(unsigned int)&MCM->CPO
+     //0xF000300C, 0xF0003040			// MCM
+		};    
+ 
+const unsigned int REG_Addresses_1B[30] =     // Constant peripheral register addresses which are 1 byte in size
+    {
+		(unsigned int)&MCG->C1,(unsigned int)&MCG->C2,(unsigned int)&MCG->C3,(unsigned int)&MCG->C4,
+		(unsigned int)&MCG->C6,(unsigned int)&MCG->SC,(unsigned int)&MCG->ATCVH,(unsigned int)&MCG->ATCVL,
+			//0x40064000, 0x40064001, 0x40064002, 0x40064003, 0x40064005, 0x40064008, 0x4006400A, 0x4006400B,    // MCG
+    //(unsigned int)&OSC0->CR,
+			//0x40065000,    // Oscillator
+		//(unsigned int)&UART0->BDH,(unsigned int)&UART0->BDL,(unsigned int)&UART0->C1,(unsigned int)&UART0->C2,
+		//(unsigned int)&UART0->S1,(unsigned int)&UART0->S2,(unsigned int)&UART0->C3,(unsigned int)&UART0->D,
+		//(unsigned int)&UART0->MA1,(unsigned int)&UART0->MA2,(unsigned int)&UART0->C4,(unsigned int)&UART0->C5,
+     //0x4006A000, 0x4006A001, 0x4006A002, 0x4006A003, 0x4006A004, 0x4006A005, 0x4006A006, 0x4006A007, 0x4006A008, 0x4006A009,
+     //0x4006A00A, 0x4006A00B,    // UART0
+		//(unsigned int)&PMC->LVDSC1,(unsigned int)&PMC->LVDSC2,(unsigned int)&PMC->REGSC,
+     //0x4007D000, 0x4007D001, 0x4007D002,    // PMC
+		//(unsigned int)&SMC->PMPROT,(unsigned int)&SMC->PMCTRL,(unsigned int)&SMC->STOPCTRL,(unsigned int)&SMC->PMSTAT,
+     //0x4007E000, 0x4007E001, 0x4007E002, 0x4007E003,   // SMC
+		//(unsigned int)&RCM->RPFC,(unsigned int)&RCM->RPFW
+     //0x4007F004, 0x4007F005 // RCM
+		};
+		
+		
+extern "C" void FLEX_INT0_IRQHandler(void);
+extern "C" void FLEX_INT1_IRQHandler(void);
+
+#if HasInternalComparator == 1
+	void configure_VH_comparator_interrupt(void);
+#else
+	void configure_VH_gpio_interrupt(void);
+	void configure_VR_gpio_interrupt(void);
+#endif
+		
+void Comparator_Setup(void);
+
+void erase_flags_memory(void);
+void restore_flags(void);
+void Enter_LLS(void);
+void setFlag(volatile unsigned int*);
+bool isFlagSet(volatile unsigned int*);
+void copyRamToFlash(void);
+
+#endif
+	
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hibernus.cpp	Fri Sep 01 14:37:15 2017 +0000
@@ -0,0 +1,182 @@
+/**    Hibernus Library
+ *	   University of Southampton 2017
+ *
+ *		Open-source liberary that enable any of your Mbed project work with transient enegy sources.
+ *		In order to use this library include the "hibernus.h" header file, and use the "Hibernus()" method at the beginning of you main funtion.
+ *		For more details and example see the "main.cpp" exampe file, and the attached documnetation
+ *
+ *
+ *     Released under the MIT License: http://mbed.org/license/mit
+ */
+ 
+#include "hibernus.h"
+#include "mbed.h"
+#include "config.h"
+
+//11 variables stored at fixed addresses at the beginning of the RAM
+volatile unsigned int FLAG_1 __attribute__((at(RAM_1_Address+Fixed_Add_Vars_Offset))) = Flash_Flags_Sector_Start;
+volatile unsigned int FLAG_2 __attribute__((at(RAM_1_Address+Fixed_Add_Vars_Offset+ 0x4))) = Flash_Flags_Sector_Start + 0x4;
+volatile unsigned int FLAG_3 __attribute__((at(RAM_1_Address+Fixed_Add_Vars_Offset+ 0x8))) = Flash_Flags_Sector_Start + 0x8;
+volatile unsigned int FLAG_4 __attribute__((at(RAM_1_Address+Fixed_Add_Vars_Offset+ 0xC))) = Flash_Flags_Sector_Start + 0xC;
+
+volatile unsigned int CoreReg_SP __attribute__((at(RAM_1_Address+Fixed_Add_Vars_Offset+0x10)));
+volatile unsigned int CoreReg_LR __attribute__((at(RAM_1_Address+Fixed_Add_Vars_Offset+0x14)));
+volatile unsigned int CoreReg_PC __attribute__((at(RAM_1_Address+Fixed_Add_Vars_Offset+0x18)));
+volatile unsigned int  n __attribute__((at(RAM_1_Address+Fixed_Add_Vars_Offset+0x1C)));   // Variable used for counting in loops (4 bytes) stored at RAM address (RamStart+0x54)
+volatile unsigned char i __attribute__((at(RAM_1_Address+Fixed_Add_Vars_Offset+0x20)));   // Variable used for counting in loops (1 byte) stored at RAM address (RamStart+0x58)
+
+volatile unsigned int *FLASH_ptr_4B __attribute__((at(RAM_1_Address+Fixed_Add_Vars_Offset+0x24)));    // Pointer that points to flash (4 bytes) stored at RAM address (RamStart+0x5C)
+volatile unsigned int *RAM_ptr      __attribute__((at(RAM_1_Address+Fixed_Add_Vars_Offset+0x28)));    // Pointer that points to RAM (4 bytes) stored at RAM address (RamStart+0x60)
+
+// Arrays used to store the contents of the peripheral registers
+volatile unsigned int REG_Array_4B[No_Of_4B_Peripheral_Reg] 	__attribute__((at(RAM_1_Address+Fixed_Add_Vars_Offset+0x2C)));;			
+volatile unsigned char REG_Array_1B[No_Of_1B_Peripheral_Reg] __attribute__((at(RAM_1_Address+Fixed_Add_Vars_Offset+0x2C+4*No_Of_4B_Peripheral_Reg)));;
+
+Serial pc1(USBTX, USBRX);
+void Hibernus(){
+	#if SaveFlagsInFlash == 0
+		restore_flags();
+	#endif
+	
+	if( isFlagSet(&FLAG_2) && isFlagSet(&FLAG_3) && isFlagSet(&FLAG_4))  // Enter this only after complete shut down
+  {	
+		erase_flags_memory();	
+		setFlag(&FLAG_1);
+		setFlag(&FLAG_4);
+   }
+		
+	if(isFlagSet(&FLAG_1)||isFlagSet(&FLAG_2)||isFlagSet(&FLAG_3)||isFlagSet(&FLAG_4))
+	{	
+    __enable_irq();     // Enable interrupts
+    Enter_LLS();        // Enter LLS mode
+  }
+		
+	if(!isFlagSet(&FLAG_1)) // If *FLAG_1 is not already set (first time waking up)
+  {
+		erase_flags_memory();
+		setFlag(&FLAG_2);
+			
+		#if HasInternalComparator == 1
+				configure_VH_comparator_interrupt();
+		#else
+				configure_VH_gpio_interrupt();
+		#endif
+    __enable_irq();     // Enable interrupts
+  }
+  else{
+		if(isFlagSet(&FLAG_4))
+		{ 
+		#if HasInternalComparator == 1
+				configure_VH_comparator_interrupt();
+		#else
+				configure_VH_gpio_interrupt();
+		#endif
+			
+			erase_flags_memory();
+			setFlag(&FLAG_2);
+			restore();
+     }
+  }
+}
+
+void Save_RAM_Regs(){  
+	//Copy the peripheral registers to RAM
+	for(n=0; n<No_Of_4B_Peripheral_Reg;n++){
+		REG_Array_4B[n] = *(unsigned int*)REG_Addresses_4B[n];
+	}
+	for(n=0; n<No_Of_1B_Peripheral_Reg;n++){
+		REG_Array_1B[n] = *(unsigned int*)REG_Addresses_1B[n];
+	}
+	
+	//copy all the ram to flash
+	copyRamToFlash();
+}
+
+void Restore_Regs(){ 
+    //Restore peripheral registers from RAM, After the ram content was copied back from flash, after a restore
+    for(n=0; n<No_Of_4B_Peripheral_Reg; n++){
+        *(unsigned int*) REG_Addresses_4B[n] = REG_Array_4B[n];
+    }
+    
+    for(i=0; i<No_Of_1B_Peripheral_Reg; i++){
+        *(unsigned char*) REG_Addresses_1B[i] = REG_Array_1B[i];
+    }
+}
+
+void restore(){
+	// Restore procedure
+	__disable_irq();     // Disable interrupts
+ 
+	erase_flags_memory();
+	setFlag(&FLAG_2); 
+
+	//Restore peripheral registers	
+	Restore_Regs();     
+                
+	//Restore RAM
+  FLASH_ptr_4B = (unsigned int*) (flash_ramSection_start);       
+  RAM_ptr      = (unsigned int*) (RAM_1_Address);
+	
+	//Copy RAM until where the pointers and loop variables are stored
+	//divide it by 4 because the copy is done word by word but byte by byte
+  for(n=0; n<(Fixed_Add_Vars_Offset/4); n++){                                
+		*(RAM_ptr + n) = *(FLASH_ptr_4B + n);
+	}
+	
+	//skip the Core reg and fixed address variables
+	FLASH_ptr_4B = (unsigned int*)(flash_ramSection_start +Fixed_Add_Vars_Offset+ Fixed_Add_Vars_Size);
+	RAM_ptr = (unsigned int*)(RAM_1_Address +Fixed_Add_Vars_Offset+ Fixed_Add_Vars_Size);
+	
+	//copy the rest of the RAM
+	//(RAM_Size-Fixed_Add_Vars_Offset-Fixed_Add_Vars_Size) is the siz eof the rest of the ram that have to be copied
+	//divide it by 4 because the copy is done word by word but byte by byte
+	 for(n=0; n<(RAM_Size-Fixed_Add_Vars_Offset-Fixed_Add_Vars_Size)/4; n++){                                
+		*(RAM_ptr + n) = *(FLASH_ptr_4B + n);
+  }
+	 
+	//copy the 3 core registers from flash o ram
+	CoreReg_SP=*(unsigned int*)(flash_ramSection_start+Fixed_Add_Vars_Offset+0x10);
+	CoreReg_LR=*(unsigned int*)(flash_ramSection_start+Fixed_Add_Vars_Offset+0x14);
+	CoreReg_PC=*(unsigned int*)(flash_ramSection_start+Fixed_Add_Vars_Offset+0x18);
+								
+	//Configure the iterrupt for VH/Hibernate
+	#if HasInternalComparator == 1
+			configure_VH_comparator_interrupt();
+	#else
+			configure_VH_gpio_interrupt();
+	#endif
+		
+	__enable_irq();     // Enable interrupts 
+
+	asm_restore();      	// Restore the value of SP                        
+	_LR = CoreReg_LR;     // Restore the value of LR
+  _PC = CoreReg_PC;     // Restore the value of PC
+}
+
+extern "C" volatile unsigned int* getFlag_1(){
+	return &FLAG_1;
+}
+
+extern "C" volatile unsigned int* getFlag_2(){
+	return &FLAG_2;
+}
+
+extern "C" volatile unsigned int* getFlag_3(){
+	return &FLAG_3;
+}
+
+extern "C" volatile unsigned int* getFlag_4(){
+	return &FLAG_4;
+}
+
+extern "C" volatile unsigned int* getCore_SP(){
+	return &CoreReg_SP;
+}
+
+extern "C" volatile unsigned int* getCore_PC(){
+	return &CoreReg_PC;
+}
+
+extern "C" volatile unsigned int* getCore_LR(){
+	return &CoreReg_LR;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hibernus.h	Fri Sep 01 14:37:15 2017 +0000
@@ -0,0 +1,45 @@
+/**    Hibernus Library
+ *	   University of Southampton 2017
+ *
+ *		Open-source liberary that enable any of your Mbed project work with transient enegy sources.
+ *		In order to use this library include the "hibernus.h" header file, and use the "Hibernus()" method at the beginning of you main funtion.
+ *		For more details and example see the "main.cpp" exampe file, and the attached documnetation
+ *
+ *
+ *     Released under the MIT License: http://mbed.org/license/mit
+ */
+#ifndef HIBERNUS_H_
+#define HIBERNUS_H_
+
+#define Fixed_Add_Vars_Offset 0x40			//the Offset added to the first address of RAM, in order to compute the address of first fixed Add variable
+#define Fixed_Add_Vars_Size 0x2C					//size of the all fixed address variables (0x28 = 44(dec) = 4Bytes*(4 flags+3CoreReg+4LoopVar))
+#define flash_end  (FLASH_Start + flash_Size)
+#define ramToFlash_sectors_number (RAM_Size / sector_Size)		//how many flash sectors do we have to erase, before saving the RAM content to flash
+#define flash_ramSection_start (flash_end - RAM_Size)
+
+// Declare register integers for the SP, LR, and PC
+register volatile unsigned int _SP __asm("r13");
+register volatile unsigned int _LR __asm("r14");
+register volatile unsigned int _PC __asm("r15");
+
+// Value written to non-volatile flags to indicate that they are set or not
+#define Flag_set 0xFFFF0000
+#define Flag_erase  0xFFFFFFFF
+
+// Declare external assembly language function (in a *.s file)
+extern "C" void asm_restore(void);
+extern "C" volatile unsigned int* getFlag_1(void);
+extern "C" volatile unsigned int* getFlag_2(void);
+extern "C" volatile unsigned int* getFlag_3(void);
+extern "C" volatile unsigned int* getFlag_4(void);
+extern "C" volatile unsigned int* getCore_SP(void);
+extern "C" volatile unsigned int* getCore_LR(void);
+extern "C" volatile unsigned int* getCore_PC(void);
+
+void Hibernus(void);
+void Save_RAM_Regs(void);
+void Restore_Regs(void);
+void restore(void);
+void hibernate(void);
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/main.cpp	Fri Sep 01 14:37:15 2017 +0000
@@ -0,0 +1,46 @@
+/**    Hibernus Library
+ *	   University of Southampton 2017
+ *
+ *		Open-source liberary that enable any of your Mbed project work with transient enegy sources.
+ *		In order to use this library include the "hibernus.h" header file, and use the "Hibernus()" method at the beginning of you main funtion.
+ *		For more details and example see the "main.cpp" exampe file, and the attached documnetation
+ *
+ *
+ *     Released under the MIT License: http://mbed.org/license/mit
+ */
+ 
+#include "hibernus.h"
+#include "mbed.h"
+		 
+DigitalOut bit0(PTB11);
+DigitalOut bit1(PTA5);
+DigitalOut bit2(PTA7);
+DigitalOut bit3(PTA6);
+		 
+Serial pc(USBTX, USBRX);
+
+int main()
+{
+	int c;
+	Hibernus();
+    while(1)        // Binary counter
+    {
+			bit0 = 0;	bit1 = 0;	bit2 = 0; bit3 = 0; for(c = 0; c<2000000; c++);    // 0
+			bit0 = 1;	bit1 = 0;	bit2 = 0; bit3 = 0; for(c = 0; c<2000000; c++);    // 1
+			bit0 = 0;	bit1 = 1;	bit2 = 0; bit3 = 0; for(c = 0; c<2000000; c++);    // 2
+			bit0 = 1;	bit1 = 1;	bit2 = 0; bit3 = 0; for(c = 0; c<2000000; c++);    // 3
+			bit0 = 0;	bit1 = 0;	bit2 = 1; bit3 = 0; for(c = 0; c<2000000; c++);    // 4
+			bit0 = 1;	bit1 = 0;	bit2 = 1; bit3 = 0; for(c = 0; c<2000000; c++);    // 5
+			bit0 = 0;	bit1 = 1;	bit2 = 1; bit3 = 0; for(c = 0; c<2000000; c++);    // 6
+			bit0 = 1;	bit1 = 1;	bit2 = 1; bit3 = 0; for(c = 0; c<2000000; c++);    // 7
+			bit0 = 0;	bit1 = 0;	bit2 = 0; bit3 = 1; for(c = 0; c<2000000; c++);    // 8
+			bit0 = 1;	bit1 = 0;	bit2 = 0; bit3 = 1; for(c = 0; c<2000000; c++);    // 9
+			bit0 = 0;	bit1 = 1;	bit2 = 0; bit3 = 1; for(c = 0; c<2000000; c++);    // 10
+			bit0 = 1;	bit1 = 1;	bit2 = 0; bit3 = 1; for(c = 0; c<2000000; c++);    // 11
+			bit0 = 0;	bit1 = 0;	bit2 = 1; bit3 = 1; for(c = 0; c<2000000; c++);    // 12
+			bit0 = 1;	bit1 = 0;	bit2 = 1; bit3 = 1; for(c = 0; c<2000000; c++);    // 13
+			bit0 = 0;	bit1 = 1;	bit2 = 1; bit3 = 1; for(c = 0; c<2000000; c++);    // 14
+			bit0 = 1;	bit1 = 1;	bit2 = 1; bit3 = 1; for(c = 0; c<2000000; c++);    // 15
+    }
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/mbed.bld	Fri Sep 01 14:37:15 2017 +0000
@@ -0,0 +1,1 @@
+http://mbed.org/users/mbed_official/code/mbed/builds/a330f0fddbec
\ No newline at end of file