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.

Dependencies:   FreescaleIAP mbed

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 "FreescaleIAP" library, in order to write the required data to the flash nonvolatile memory. This library works and can be easily used in order to access the flash memory of all Freescale boards that suport Mbed

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 01 14:37:15 2017 +0000
Revision:
0:57ca0bfdc2d8
First version of the Hibernus Library. V1.0

Who changed what in which revision?

UserRevisionLine numberNew contents of line
BogdanL 0:57ca0bfdc2d8 1 /** Hibernus Library
BogdanL 0:57ca0bfdc2d8 2 * University of Southampton 2017
BogdanL 0:57ca0bfdc2d8 3 *
BogdanL 0:57ca0bfdc2d8 4 * Open-source liberary that enable any of your Mbed project work with transient enegy sources.
BogdanL 0:57ca0bfdc2d8 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:57ca0bfdc2d8 6 * For more details and example see the "main.cpp" exampe file, and the attached documnetation
BogdanL 0:57ca0bfdc2d8 7 *
BogdanL 0:57ca0bfdc2d8 8 *
BogdanL 0:57ca0bfdc2d8 9 * Released under the MIT License: http://mbed.org/license/mit
BogdanL 0:57ca0bfdc2d8 10 */
BogdanL 0:57ca0bfdc2d8 11 #ifndef CONFIG_H_
BogdanL 0:57ca0bfdc2d8 12 #define CONFIG_H_
BogdanL 0:57ca0bfdc2d8 13 #include "mbed.h"
BogdanL 0:57ca0bfdc2d8 14 #include "FreescaleIAP.h"
BogdanL 0:57ca0bfdc2d8 15
BogdanL 0:57ca0bfdc2d8 16 #define HasInternalComparator 1 //Set on 1 if there is an internal comparator 0 otherwise
BogdanL 0:57ca0bfdc2d8 17 #define SaveFlagsInFlash 1 //set on 1 if there is enough Flash memory available for the flags to have their own flash sector, 0 otherwise
BogdanL 0:57ca0bfdc2d8 18 //if there is not enough flash memory, the flags will be saved in RAM memory
BogdanL 0:57ca0bfdc2d8 19
BogdanL 0:57ca0bfdc2d8 20 // RAM addresses split in 1 KB sectors
BogdanL 0:57ca0bfdc2d8 21 #define RAM_1_Address 0x1FFFFC00
BogdanL 0:57ca0bfdc2d8 22 #define FLASH_Start 0x00000000
BogdanL 0:57ca0bfdc2d8 23 #define RAM_Size 4096
BogdanL 0:57ca0bfdc2d8 24 #define flash_Size flash_size() //32K flash
BogdanL 0:57ca0bfdc2d8 25 #define sector_Size SECTOR_SIZE //4K sector size
BogdanL 0:57ca0bfdc2d8 26 #define Flash_Flags_Sector_Start (flash_end -1*sector_Size)
BogdanL 0:57ca0bfdc2d8 27
BogdanL 0:57ca0bfdc2d8 28 #define No_Of_4B_Peripheral_Reg 19
BogdanL 0:57ca0bfdc2d8 29 #define No_Of_1B_Peripheral_Reg 8
BogdanL 0:57ca0bfdc2d8 30
BogdanL 0:57ca0bfdc2d8 31
BogdanL 0:57ca0bfdc2d8 32 const unsigned int REG_Addresses_4B[83] = // Constant peripheral register addresses which are 4 bytes in size
BogdanL 0:57ca0bfdc2d8 33 {
BogdanL 0:57ca0bfdc2d8 34 (unsigned int)&FPTA->PDOR,(unsigned int)&FPTA->PDDR,(unsigned int)&FPTB->PDOR,(unsigned int)&FPTB->PDDR,
BogdanL 0:57ca0bfdc2d8 35 //0x4000F000, 0x4000F014, 0x4000F040, 0x4000F054, // GPIO controller aliased to ox400FF000
BogdanL 0:57ca0bfdc2d8 36 (unsigned int)&SIM->SOPT1,(unsigned int)&SIM->SOPT1CFG,(unsigned int)&SIM->SOPT2,(unsigned int)&SIM->SOPT4,
BogdanL 0:57ca0bfdc2d8 37 (unsigned int)&SIM->SOPT5,(unsigned int)&SIM->SOPT7,(unsigned int)&SIM->SCGC4,(unsigned int)&SIM->SCGC5,
BogdanL 0:57ca0bfdc2d8 38 (unsigned int)&SIM->SCGC6,(unsigned int)&SIM->SCGC7,(unsigned int)&SIM->CLKDIV1,(unsigned int)&SIM->FCFG1,
BogdanL 0:57ca0bfdc2d8 39 (unsigned int)&SIM->COPC,
BogdanL 0:57ca0bfdc2d8 40 //0x40047000, 0x40047004, 0x40048004, 0x4004800C, 0x40048010, 0x40048018, 0x40048034, 0x40048038, 0x4004803C, 0x40048040,
BogdanL 0:57ca0bfdc2d8 41 //0x40048044, 0x4004804C, 0x40048100, // SIM
BogdanL 0:57ca0bfdc2d8 42 /*(unsigned int)&PORTA->PCR[0],(unsigned int)&PORTA->PCR[1],(unsigned int)&PORTA->PCR[2],(unsigned int)&PORTA->PCR[3],
BogdanL 0:57ca0bfdc2d8 43 (unsigned int)&PORTA->PCR[4],(unsigned int)&PORTA->PCR[5],(unsigned int)&PORTA->PCR[6],(unsigned int)&PORTA->PCR[7],
BogdanL 0:57ca0bfdc2d8 44 (unsigned int)&PORTA->PCR[8],(unsigned int)&PORTA->PCR[9],(unsigned int)&PORTA->PCR[10],(unsigned int)&PORTA->PCR[11],
BogdanL 0:57ca0bfdc2d8 45 (unsigned int)&PORTA->PCR[12],(unsigned int)&PORTA->PCR[13],(unsigned int)&PORTA->PCR[14],(unsigned int)&PORTA->PCR[15],
BogdanL 0:57ca0bfdc2d8 46 (unsigned int)&PORTA->PCR[16],(unsigned int)&PORTA->PCR[17],(unsigned int)&PORTA->PCR[18],(unsigned int)&PORTA->PCR[19],
BogdanL 0:57ca0bfdc2d8 47 (unsigned int)&PORTA->PCR[20],(unsigned int)&PORTA->PCR[21],(unsigned int)&PORTA->PCR[22],(unsigned int)&PORTA->PCR[23],
BogdanL 0:57ca0bfdc2d8 48 (unsigned int)&PORTA->PCR[24],(unsigned int)&PORTA->PCR[25],(unsigned int)&PORTA->PCR[26],(unsigned int)&PORTA->PCR[27],
BogdanL 0:57ca0bfdc2d8 49 (unsigned int)&PORTA->PCR[28],(unsigned int)&PORTA->PCR[29],(unsigned int)&PORTA->PCR[30],(unsigned int)&PORTA->PCR[31],
BogdanL 0:57ca0bfdc2d8 50 //0x40049000, 0x40049004, 0x40049008, 0x4004900C, 0x40049010, 0x40049014, 0x40049018, 0x4004901C, 0x40049020, 0x40049024,
BogdanL 0:57ca0bfdc2d8 51 //0x40049028, 0x4004902C, 0x40049030, 0x40049034, 0x40049038, 0x4004903C, 0x40049040, 0x40049044, 0x40049048, 0x4004904C,
BogdanL 0:57ca0bfdc2d8 52 //0x40049050, 0x40049054, 0x40049058, 0x4004905C, 0x40049060, 0x40049064, 0x40049068, 0x4004906C, 0x40049070, 0x40049074,
BogdanL 0:57ca0bfdc2d8 53 //0x40049078, 0x4004907C, // Port A multiplexing control
BogdanL 0:57ca0bfdc2d8 54 (unsigned int)&PORTB->PCR[0],(unsigned int)&PORTB->PCR[1],(unsigned int)&PORTB->PCR[2],(unsigned int)&PORTB->PCR[3],
BogdanL 0:57ca0bfdc2d8 55 (unsigned int)&PORTB->PCR[4],(unsigned int)&PORTB->PCR[5],(unsigned int)&PORTB->PCR[6],(unsigned int)&PORTB->PCR[7],
BogdanL 0:57ca0bfdc2d8 56 (unsigned int)&PORTB->PCR[8],(unsigned int)&PORTB->PCR[9],(unsigned int)&PORTB->PCR[10],(unsigned int)&PORTB->PCR[11],
BogdanL 0:57ca0bfdc2d8 57 (unsigned int)&PORTB->PCR[12],(unsigned int)&PORTB->PCR[13],(unsigned int)&PORTB->PCR[14],(unsigned int)&PORTB->PCR[15],
BogdanL 0:57ca0bfdc2d8 58 (unsigned int)&PORTB->PCR[16],(unsigned int)&PORTB->PCR[17],(unsigned int)&PORTB->PCR[18],(unsigned int)&PORTB->PCR[19],
BogdanL 0:57ca0bfdc2d8 59 (unsigned int)&PORTB->PCR[20],(unsigned int)&PORTB->PCR[21],(unsigned int)&PORTB->PCR[22],(unsigned int)&PORTB->PCR[23],
BogdanL 0:57ca0bfdc2d8 60 (unsigned int)&PORTB->PCR[24],(unsigned int)&PORTB->PCR[25],(unsigned int)&PORTB->PCR[26],(unsigned int)&PORTB->PCR[27],
BogdanL 0:57ca0bfdc2d8 61 (unsigned int)&PORTB->PCR[28],(unsigned int)&PORTB->PCR[29],(unsigned int)&PORTB->PCR[30],(unsigned int)&PORTB->PCR[31],
BogdanL 0:57ca0bfdc2d8 62 //0x4004A000, 0x4004A004, 0x4004A008, 0x4004A00C, 0x4004A010, 0x4004A014, 0x4004A018, 0x4004A01C, 0x4004A020, 0x4004A024,
BogdanL 0:57ca0bfdc2d8 63 //0x4004A028, 0x4004A02C, 0x4004A030, 0x4004A034, 0x4004A038, 0x4004A03C, 0x4004A040, 0x4004A044, 0x4004A048, 0x4004A04C,
BogdanL 0:57ca0bfdc2d8 64 //0x4004A050, 0x4004A054, 0x4004A058, 0x4004A05C, 0x4004A060, 0x4004A064, 0x4004A068, 0x4004A06C, 0x4004A070, 0x4004A074,
BogdanL 0:57ca0bfdc2d8 65 //0x4004A078, 0x4004A07C, // Port B multiplexing control*/
BogdanL 0:57ca0bfdc2d8 66 (unsigned int)&MCM->PLACR,(unsigned int)&MCM->CPO
BogdanL 0:57ca0bfdc2d8 67 //0xF000300C, 0xF0003040 // MCM
BogdanL 0:57ca0bfdc2d8 68 };
BogdanL 0:57ca0bfdc2d8 69
BogdanL 0:57ca0bfdc2d8 70 const unsigned int REG_Addresses_1B[30] = // Constant peripheral register addresses which are 1 byte in size
BogdanL 0:57ca0bfdc2d8 71 {
BogdanL 0:57ca0bfdc2d8 72 (unsigned int)&MCG->C1,(unsigned int)&MCG->C2,(unsigned int)&MCG->C3,(unsigned int)&MCG->C4,
BogdanL 0:57ca0bfdc2d8 73 (unsigned int)&MCG->C6,(unsigned int)&MCG->SC,(unsigned int)&MCG->ATCVH,(unsigned int)&MCG->ATCVL,
BogdanL 0:57ca0bfdc2d8 74 //0x40064000, 0x40064001, 0x40064002, 0x40064003, 0x40064005, 0x40064008, 0x4006400A, 0x4006400B, // MCG
BogdanL 0:57ca0bfdc2d8 75 //(unsigned int)&OSC0->CR,
BogdanL 0:57ca0bfdc2d8 76 //0x40065000, // Oscillator
BogdanL 0:57ca0bfdc2d8 77 //(unsigned int)&UART0->BDH,(unsigned int)&UART0->BDL,(unsigned int)&UART0->C1,(unsigned int)&UART0->C2,
BogdanL 0:57ca0bfdc2d8 78 //(unsigned int)&UART0->S1,(unsigned int)&UART0->S2,(unsigned int)&UART0->C3,(unsigned int)&UART0->D,
BogdanL 0:57ca0bfdc2d8 79 //(unsigned int)&UART0->MA1,(unsigned int)&UART0->MA2,(unsigned int)&UART0->C4,(unsigned int)&UART0->C5,
BogdanL 0:57ca0bfdc2d8 80 //0x4006A000, 0x4006A001, 0x4006A002, 0x4006A003, 0x4006A004, 0x4006A005, 0x4006A006, 0x4006A007, 0x4006A008, 0x4006A009,
BogdanL 0:57ca0bfdc2d8 81 //0x4006A00A, 0x4006A00B, // UART0
BogdanL 0:57ca0bfdc2d8 82 //(unsigned int)&PMC->LVDSC1,(unsigned int)&PMC->LVDSC2,(unsigned int)&PMC->REGSC,
BogdanL 0:57ca0bfdc2d8 83 //0x4007D000, 0x4007D001, 0x4007D002, // PMC
BogdanL 0:57ca0bfdc2d8 84 //(unsigned int)&SMC->PMPROT,(unsigned int)&SMC->PMCTRL,(unsigned int)&SMC->STOPCTRL,(unsigned int)&SMC->PMSTAT,
BogdanL 0:57ca0bfdc2d8 85 //0x4007E000, 0x4007E001, 0x4007E002, 0x4007E003, // SMC
BogdanL 0:57ca0bfdc2d8 86 //(unsigned int)&RCM->RPFC,(unsigned int)&RCM->RPFW
BogdanL 0:57ca0bfdc2d8 87 //0x4007F004, 0x4007F005 // RCM
BogdanL 0:57ca0bfdc2d8 88 };
BogdanL 0:57ca0bfdc2d8 89
BogdanL 0:57ca0bfdc2d8 90
BogdanL 0:57ca0bfdc2d8 91 extern "C" void FLEX_INT0_IRQHandler(void);
BogdanL 0:57ca0bfdc2d8 92 extern "C" void FLEX_INT1_IRQHandler(void);
BogdanL 0:57ca0bfdc2d8 93
BogdanL 0:57ca0bfdc2d8 94 #if HasInternalComparator == 1
BogdanL 0:57ca0bfdc2d8 95 void configure_VH_comparator_interrupt(void);
BogdanL 0:57ca0bfdc2d8 96 #else
BogdanL 0:57ca0bfdc2d8 97 void configure_VH_gpio_interrupt(void);
BogdanL 0:57ca0bfdc2d8 98 void configure_VR_gpio_interrupt(void);
BogdanL 0:57ca0bfdc2d8 99 #endif
BogdanL 0:57ca0bfdc2d8 100
BogdanL 0:57ca0bfdc2d8 101 void Comparator_Setup(void);
BogdanL 0:57ca0bfdc2d8 102
BogdanL 0:57ca0bfdc2d8 103 void erase_flags_memory(void);
BogdanL 0:57ca0bfdc2d8 104 void restore_flags(void);
BogdanL 0:57ca0bfdc2d8 105 void Enter_LLS(void);
BogdanL 0:57ca0bfdc2d8 106 void setFlag(volatile unsigned int*);
BogdanL 0:57ca0bfdc2d8 107 bool isFlagSet(volatile unsigned int*);
BogdanL 0:57ca0bfdc2d8 108 void copyRamToFlash(void);
BogdanL 0:57ca0bfdc2d8 109
BogdanL 0:57ca0bfdc2d8 110 #endif
BogdanL 0:57ca0bfdc2d8 111