Bogdan Lazarescu / Mbed 2 deprecated Hibernus

Dependencies:   mbed

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers Driver_KL05Z.cpp Source File

Driver_KL05Z.cpp

00001 #include "config.h"
00002 #ifdef KL05Z
00003 #include "Driver_KL05Z.h"
00004 #include "hibernus.h"
00005 Serial pr(USBTX, USBRX);
00006 volatile unsigned int dummyread1;      // Variable used for serialization
00007 
00008 //inerrupt triggered by comparator whenever the power drops under the treshold value
00009 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)
00010 {
00011   CMP0->SCR |= CMP_SCR_CFF_MASK | CMP_SCR_CFR_MASK;   // Clear CMP0 flags
00012   dummyread1 = CMP0->SCR;                              // Read back for serialization
00013   
00014     //call hibernate procedure directly with the three parameters (don't store them in a variable and then call the method with them,
00015     //the store procedure changes the stackpointer and the program counter)
00016     // pram1 = StackPointer = SP, param2 = LinkRegister = LR, param3 = ProgramCounter = PC
00017     // call hibernate(param1, param2, param3) then the voltage drops under the low(hibernate) treshold
00018     hibernate((_SP+0x28),*((unsigned int*)(_SP+0x1C)),*((unsigned int*)(_SP+0x20)));
00019     
00020 }
00021 
00022 extern "C" void LLW_IRQHandler(){                   //interrupt triggered to wake up the board from sleep mode
00023     
00024     CMP0->SCR |= CMP_SCR_CFF_MASK | CMP_SCR_CFR_MASK;   // Clear CMP0 flags
00025     dummyread1 = CMP0->SCR;                             // Read back for serialization
00026     NVIC_ClearPendingIRQ(CMP0_IRQn);                    // Clear pending CMP0 interrupt so that the CMP_IRQ is not entered
00027     
00028         recovery_no_power_loss();                               //check if you are recovering after no power loss, and if so, configure VH interrupt
00029 }
00030 
00031 void Comparator_Setup(){
00032     
00033   NVIC_SetPriority(CMP0_IRQn, 1);     // Lower the CMP0 interrupt priority from 0 to 1 (smaller number = higher priority)
00034   NVIC_EnableIRQ(CMP0_IRQn);          // Enable CMP0 interrupts in NVIC
00035     
00036   SIM->SCGC4 |= SIM_SCGC4_CMP_MASK;       // Enable comparator module clock
00037   LLWU->ME |= LLWU_ME_WUME1_MASK;         // Enable CMP0 as a LLWU source
00038   PMC->REGSC |= PMC_REGSC_BGEN_MASK |     // Allow bangap buffer in low power operation
00039                   PMC_REGSC_BGBE_MASK;      // Enable bandgap buffer for +1V reference (CMP0_IN6)
00040                   
00041   // Comparator in sampled, filtered mode 4B
00042   CMP0->CR0 = 0x22;                 // Hysteresis level 2 (20mV) and 2 consecutive filter samples must agree
00043   CMP0->CR1 = 0x00;                 // Low-speed compare, non-inverted output, use filtered output and disable comparator output pin PTA2
00044   CMP0->FPR = 0x01;                 // Filter sample period = 1 bus clock cycle
00045   CMP0->SCR = 0x06;                 // Disable all interrupts and clear flags
00046   CMP0->DACCR = 0x40;               // Disable DAC, Vdd is 6-bit reference, threshold set to zero
00047   CMP0->MUXCR = 0x3E;               // CMP0_IN7 (DAC) to V+ channel and CMP0_IN6 (+1V bandgap) to V- 3E
00048 }
00049 
00050 void Enter_LLS(){
00051     
00052     Comparator_Setup();
00053   CMP0->DACCR = 0xDA;               // Enable DAC, Vdd is 6-bit reference, threshold set to P3V3 = +2.37V (V_R)
00054   CMP0->SCR = 0x16;                 // Enable rising edge interrupt and clear flags
00055   CMP0->CR1 |= CMP_CR1_EN_MASK;     // Enable comparator module
00056     
00057   NVIC_EnableIRQ(LLW_IRQn);               // Enable LLW interrupts in NVIC
00058   MCG->C6 &= ~(MCG_C6_CME_MASK);          // DIsable all clock monitors
00059   SCB->SCR = 1<<SCB_SCR_SLEEPDEEP_Pos;    // Set the SLEEPDEEP bit for stop mode
00060     
00061   SMC->PMPROT = SMC_PMPROT_ALLS_MASK;         // Allow LLS power modes
00062   SMC->PMCTRL &= ~(SMC_PMCTRL_STOPM_MASK);    // Serialisation
00063   SMC->PMCTRL = SMC_PMCTRL_STOPM(0x3);        // Select LLS as desired power mode
00064   dummyread1 = SMC->PMCTRL;                    // Read back for serialisation
00065 
00066   __WFI();    // Stop executing instructions and enter LLS (wait for interrupt)
00067 }
00068 
00069 void configure_VH_comparator_interrupt(){                            
00070   Comparator_Setup();
00071   CMP0->DACCR = 0xDC;               // Enable DAC, Vdd is 6-bit reference, threshold set to P3V3 = +2.21V (V_H)
00072   CMP0->SCR = 0x0E;                 // Enable falling edge interrupt and clear flags
00073   CMP0->CR1 |= CMP_CR1_EN_MASK;     // Enable comparator module
00074 }
00075 
00076 void configure_VR_comparator_interrupt(){
00077     CMP0->DACCR = 0xDA;               // Enable DAC, Vdd is 6-bit reference, threshold set to P3V3 = +2.37V (V_R)
00078   CMP0->SCR = 0x16;                 // Enable all interrupts and clear flags
00079   CMP0->CR1 |= CMP_CR1_EN_MASK;     // Enable comparator module
00080 }
00081 
00082 void setFlag(volatile unsigned int* add){
00083     const unsigned int set = Flag_set;
00084     program_flash(*add,(char*)&set,4);          //if the flags are stored in flash, use this line
00085 }
00086 
00087 bool isFlagSet(volatile unsigned int* add){
00088     if( *(unsigned int *)(*add) == Flag_set) return true;
00089     return false;
00090 }
00091 
00092 void erase_flags_memory(){
00093     if(!SaveFlagsInFlash) {             //if the flags are stored in RAM, their value have to be clanged to the "erased" value ("Flag_erase")
00094     *getFlag_1() = Flag_erase;
00095     *getFlag_2() = Flag_erase;
00096     *getFlag_3() = Flag_erase;
00097     *getFlag_4() = Flag_erase;
00098     }else{                                              //if the flags are stored in Flash, their secvtor have to be erased
00099         erase_sector(Flash_Flags_Sector_Start);
00100     }
00101 }
00102 //erase the flash memory needed to save the whole RAM content
00103 void erase_flash_secors_for_RAM(){
00104     int i;
00105     for(i = 2; i<= 2+ramToFlash_sectors_number; i++)                //start the erase from the second last block, the first is used for flags
00106         erase_sector(flash_end-i*sector_Size);
00107 }
00108 
00109 void copyRamToFlash(){
00110     // Erase flash sectors o save the RAM content
00111     erase_flash_secors_for_RAM();
00112     program_flash(flash_ramSection_start, (char*) RAM_Start, RAM_Size);     // Copy all the RAM to flash
00113 }
00114 #endif