Bogdan Lazarescu / Mbed 2 deprecated Hibernus

Dependencies:   mbed

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers Driver_LPC11U24.cpp Source File

Driver_LPC11U24.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 #ifdef LPC11U24
00012 #include "Driver_LPC11U24.h"
00013 #include "hibernus.h"
00014 #include "config.h"
00015 
00016 IAP iap;
00017 Serial pc1(USBTX, USBRX);
00018 
00019 void Enter_LLS(){
00020     configure_VR_gpio_interrupt();
00021     
00022     LPC_PMU->PCON |= 0x1;
00023     LPC_SYSCON->PINTSEL[0] = 0x02;                                              //configure pin P0_2 as interupt source 
00024     LPC_SYSCON->PDRUNCFG &= ~(1<<1);
00025     LPC_SYSCON->STARTERP0 |= (1<<0);                                            //Config chanel as wake up interrupt
00026     LPC_SYSCON->PDAWAKECFG &= ~((1<<0)|(1<<1)|(1<<2)|(1<<5)|(1<<7));    //wake up all needed modules after recovering from deepslep mode
00027     NVIC_SetPriority(FLEX_INT0_IRQn,0);
00028     NVIC_EnableIRQ(FLEX_INT0_IRQn);
00029     NVIC_SetPriority(FLEX_INT0_IRQn,0);
00030     
00031     //Go to deep Sleep mode ---->
00032     SCB->SCR |= SCB_SCR_SLEEPDEEP_Msk;                                      //choose Deep Sleep as power mode
00033     __WFI();                                                                                        // Stop executing instructions and enter Deep Sleep mode
00034 }
00035 
00036 //if there is no internal Coomparator define 2 GPIO interrupts to wake up and sleep
00037 
00038 void configure_VR_gpio_interrupt(){
00039     LPC_GPIO->DIR[0] |= 1<<2;                                       //set pin P0_2 as input //generate interrupt for VR
00040 
00041     LPC_SYSCON->SYSAHBCLKCTRL |= (1<<6);    
00042     LPC_SYSCON->SYSAHBCLKCTRL |= (1<<16);
00043     LPC_IOCON->PIO0_2 = (0x0|(0x2<<3));                 //enable pullup
00044     LPC_SYSCON->SYSAHBCLKCTRL |= (1<<19);           //System enable peripheral clock        
00045     LPC_SYSCON->PINTSEL[0] = 0x2;                               //configure interrupt chanel for the GPIO pin is syscon block
00046 
00047     LPC_GPIO_PIN_INT->ISEL &= ~(1<<0);                  //set the interrupt mode for the pin0 to be Level Sensitive
00048     LPC_GPIO_PIN_INT->IENF |= (1<<0);                       //enable the level sensitive interrupt on pin P0_2
00049         
00050     LPC_SYSCON->STARTERP0 |= (1<<0);                        //config chanel as wake up interrupt is Syscon block
00051         
00052     __enable_irq();
00053     NVIC_EnableIRQ(FLEX_INT0_IRQn);
00054     NVIC_SetPriority(FLEX_INT0_IRQn,0);                 //Set a higher prioroty for wake up interrupt, to be able to interrupt the sleep interrupt
00055 }
00056 
00057 void configure_VH_gpio_interrupt(){
00058     LPC_GPIO->DIR[0] |= 1<<8;                                       //set pin P0_8 as input //generate interrupt for VH
00059     
00060     LPC_SYSCON->SYSAHBCLKCTRL |= (1<<6);    
00061     LPC_SYSCON->SYSAHBCLKCTRL |= (1<<16);
00062     LPC_IOCON->PIO0_8 = (0x0|(0x2<<3));                 //choose first pin function and enable pullup
00063     LPC_SYSCON->SYSAHBCLKCTRL |= (1<<19);           //System enable peripheral clock        
00064     LPC_SYSCON->PINTSEL[1] = (uint32_t)8;               //configure interrupt chanel for the GPIO pin is syscon block
00065     
00066     LPC_GPIO_PIN_INT->ISEL &= ~(1<<1);                  //set the interrupt mode for the pin1 to be Level Sensitive
00067     LPC_GPIO_PIN_INT->IENF |= (1<<1);                       //enable the level sensitive interrupt on pin P0_8
00068     
00069     __enable_irq();
00070     NVIC_EnableIRQ(FLEX_INT1_IRQn);
00071     NVIC_SetPriority(FLEX_INT1_IRQn,2);                 //Set a lower priority for the sleep interrupt, in order to be possible for the wake up interrupt to interrupt it
00072 }
00073 
00074 //the interrupt triggered by the GPIO/INternal Comparator where the snapshot is saved
00075 extern "C" void FLEX_INT1_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)
00076     pc1.printf(" ",isFlagSet(getFlag_1()),isFlagSet(getFlag_2()),isFlagSet(getFlag_3()),isFlagSet(getFlag_4())); 
00077 
00078   hibernate((_SP+0x40),*(unsigned int*)(_SP+0x34),*(unsigned int*)(_SP+0x38));
00079         
00080         //clear interupt status register
00081         LPC_GPIO_PIN_INT->IST |=((1<<0)|(1<<1));
00082         //delete any sleep interupts that came during the sleep
00083         NVIC_ClearPendingIRQ(FLEX_INT1_IRQn);
00084 }
00085 
00086 //ISR for wakeing up the core and seting the interrupt for Hibernate procedure 
00087 extern "C" void FLEX_INT0_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)
00088     NVIC_ClearPendingIRQ(FLEX_INT0_IRQn);
00089     
00090     recovery_no_power_loss();                               //check if you are recovering after no power loss, and if so, configure VH interrupt
00091     
00092     //clear interupt status register
00093     LPC_GPIO_PIN_INT->IST |= (1<<0);
00094 }
00095 
00096 //used to restore the flags values from Flash to RAM
00097 void restore_flags(){
00098     if(!SaveFlagsInFlash){
00099         *getFlag_1() = *(unsigned int*)(flash_ramSection_start+Fixed_Add_Vars_Offset);
00100         *getFlag_2() = *(unsigned int*)(flash_ramSection_start+Fixed_Add_Vars_Offset+0x4);
00101         *getFlag_3() = *(unsigned int*)(flash_ramSection_start+Fixed_Add_Vars_Offset+0x8);
00102         *getFlag_4() = *(unsigned int*)(flash_ramSection_start+Fixed_Add_Vars_Offset+0xC);
00103     }
00104 }
00105 
00106 //mark a flag as "SET"
00107 void setFlag(volatile unsigned int* add){
00108     #if SaveFlagsInFlash == 1
00109         const unsigned int set = Flag_set;
00110         program_flash(*add,(char*)&set,4);          //if the flags are stored in flash, use this line
00111     #else
00112         *add = Flag_set;
00113     #endif
00114     
00115 }
00116 
00117 //check if a flag is SET or CLEAR
00118 bool isFlagSet(volatile unsigned int* add){
00119     #if SaveFlagsInFlash == 1
00120         if( *(unsigned int *)(*add) == Flag_set) return true;
00121         return false;
00122     #else
00123         if(*add == Flag_set ) return true;
00124         return false;
00125     #endif
00126 }
00127 
00128 //Clear the memory area where the flags are saved
00129 void erase_flags_memory(){
00130     #if SaveFlagsInFlash == 0               //if the flags are stored in RAM, their value have to be clanged to the "erased" value ("Flag_erase")
00131     *getFlag_1() = Flag_erase;
00132     *getFlag_2() = Flag_erase;
00133     *getFlag_3() = Flag_erase;
00134     *getFlag_4() = Flag_erase;
00135     #else                                               //if the flags are stored in Flash, their secvtor have to be erased
00136         erase_sector(Flash_Flags_Sector_Start);
00137     #endif
00138 }
00139 
00140 //copy the whole content of RAM into the flash
00141 void copyRamToFlash(){
00142     // Erase flash sectors o save the RAM content
00143     int g3=iap.prepare(6,7);
00144     int g4=iap.erase(6,7);
00145     
00146   // Copy all the RAM to flash
00147   int g0 = iap.prepare(6,7);
00148     int g1=iap.write((char*)RAM_Start,(char*)flash_ramSection_start,RAM_Size/2);
00149             g1+=iap.write((char*)RAM_Start+(RAM_Size/2),(char*)flash_ramSection_start+(RAM_Size/2),(RAM_Size/2));
00150 }
00151 #endif