/** * sleep * * Put panStamp into Power-down state during "time". * This function uses RTC connected to an external 32.768KHz crystal * in order to exit (interrupt) from the power-down state * * @param time Sleeping time in seconds * @param ACLK source (RTCSRC_XT1 or RTCSRC_VLO) */ void CC430RTC::sleep(uint16_t time, RTCSRC source) { if (time == 0) return; uint32_t ticks = 0xFFFFFFFF; switch(source) { case RTCSRC_XT1: RTC_SET_ACLK_XT1(); // Connect ACLK to 32.768 KHz crystal ticks -= (RTC_32K_CYCLES_1SEC * time); break; case RTCSRC_VLO: RTC_SET_ACLK_VLO(); // Connect ACLK to VLO (Internal 10KHz oscillator) ticks -= (RTC_VLO_CYCLES_1SEC * time); break; default: break; } disableWatchDog(); // Stop WDT RTC_SET_TICKS(ticks); // Initialize 32-bit counter RTC_ISR_ENABLE(); // Enable RTC interrupt RTC_START_32BIT_COUNTER(); // Start RTC counter with 32-bit overflow panstamp.core.setLowPowerMode(); // Enter low-power mode (LPM3) // ZZZZZZZ.... panstamp.core.setNormalMode(); // Exit low-power mode and enable WDT //enableWatchDog(); // Enable WDT again }
// erase flash, make sure pointer is in the segment you wish to erase, otherwise you may erase you program or some data void CCFlashClass::erase(unsigned char *flash) { disableWatchDog(); // Disable WDT FCTL3 = FWKEY; // Clear LOCK FCTL1 = FWKEY+ERASE; //Enable segment erase *flash = 0; // Dummy write, erase Segment FCTL3 = FWKEY+LOCK; // Done, set LOCK enableWatchDog(); // Enable WDT }
/** * setLowPowerMode * * Enter low power mode * * @param lpm4 true if LPM4 has to be entered. Otherwise the MCU will * enter LPM3 */ void CC430CORE::setLowPowerMode(bool lpm4) { // Stop WDT disableWatchDog(); // Keep current port selections portSelection[0] = P1SEL; portSelection[1] = P2SEL; portSelection[2] = P3SEL; // Configure ports as binary I/O's P1SEL = 0; //P2SEL = 0; #ifdef __NRG_VERSION_1_0__ // Current hardware version (1.0) uses P3.6 to detect interrupts from // the on-board accelerometer. For this application, P3.6 is configured // as a timer capture input to simulate pin interrupts. // (P3 does not natively support pin interrupts) // In future hardware revisions, a pin supporting true pin interrupts // should be used instead. P3SEL &= BIT6; P3DIR |= portSelection[2] & ~BIT6; #else P3DIR |= portSelection[2]; #endif // I2C lines remain high to not to sink current through // I2C pull-up resistors P1OUT |= 0x18; // Configure ports working as alternative functions as outputs P1DIR |= portSelection[0]; //P2DIR |= portSelection[1]; // Enter lowest power VCore level and MCLK = 1 MHz _SET_VCORE_1MHZ(0); // Turn off SVSH, SVSM PMMCTL0_H = 0xA5; SVSMHCTL = 0; SVSMLCTL = 0; PMMCTL0_H = 0x00; if (lpm4) { // Enter LPM4 with interrupts __bis_SR_register(LPM4_bits + GIE); } else { // Enter LPM3 with interrupts __bis_SR_register(LPM3_bits + GIE); } }
// save in to flash (at segment boundary) void CCFlashClass::write(unsigned char *flash, unsigned char *src, int len) { disableWatchDog(); // Disable WDT FCTL3 = FWKEY; // Clear LOCK FCTL1 = FWKEY+WRT; // Enable write while(len--) // Copy data *(flash++) = *(src++); FCTL1 = FWKEY; //Done. Clear WRT FCTL3 = FWKEY+LOCK; // Set LOCK enableWatchDog(); // Enable WDT }
void init() { disableWatchDog(); initClocks(); //Copy RAM functions memcpy(&RamfuncsRunStart, &RamfuncsLoadStart, (size_t)&RamfuncsLoadSize); //Setup flash waitstates initFlash(); initPie(); analogInit(); EINT; }
/** * sleepUntil * * Put panStamp into Power-down state until the RTC alarm is triggered * Here the RTC module is used in calendar mode and hexadecimal format * This function uses RTC connected to an external 32.768KHz crystal * in order to exit (interrupt) from the power-down state * * @param day Day of month (1 to 31) * @param dow Day of week (0 to 6) * @param hour Hour (0 to 23) * @param min Minutes day (0 to 59) */ void CC430RTC::sleepUntil(char day, char dow, char hour, char min) { if ((day < 0) && (dow < 0) && (hour < 0) && (min < 0)) return; RTC_SET_ACLK_XT1(); // Connect ACLK to 32.768 KHz crystal disableWatchDog(); // Stop WDT if (day > 0) { RTC_SET_DAY_ALARM(day); RTC_ENABLE_DAY_ALARM(); } else if (dow > 0) { RTC_SET_DOW_ALARM(dow); RTC_ENABLE_DOW_ALARM(); } if (hour > 0) { RTC_SET_HOUR_ALARM(hour); RTC_ENABLE_HOUR_ALARM(); } if (min > 0) { RTC_SET_MIN_ALARM(min); RTC_ENABLE_MIN_ALARM(); } RTC_SET_CALENDAR_MODE(); // RTC set to calendar mode RTC_ENABLE_ALARM(); // Enable RTC alarm RTC_ISR_ENABLE(); // Enable RTC interrupt __bis_SR_register(LPM3_bits + GIE); // Enter LPM3 with interrupts enableWatchDog(); // Enable WDT again }
void initClocks(void) { volatile Uint16 iVol; //Calibrate ADC EALLOW; SysCtrlRegs.PCLKCR0.bit.ADCENCLK = 1; // Enable ADC peripheral clock (*Device_cal)(); SysCtrlRegs.PCLKCR0.bit.ADCENCLK = 0; // Return ADC clock to original state //Select internal oscillator 1 SysCtrlRegs.CLKCTL.bit.INTOSC1OFF = 0; SysCtrlRegs.CLKCTL.bit.OSCCLKSRCSEL=0; // Clk Src = INTOSC1 SysCtrlRegs.CLKCTL.bit.XCLKINOFF=1; // Turn off XCLKIN SysCtrlRegs.CLKCTL.bit.XTALOSCOFF=1; // Turn off XTALOSC SysCtrlRegs.CLKCTL.bit.INTOSC2OFF=1; // Turn off INTOSC2 EDIS; // Make sure the PLL is not running in limp mode if (SysCtrlRegs.PLLSTS.bit.MCLKSTS != 0) { EALLOW; // OSCCLKSRC1 failure detected. PLL running in limp mode. // Re-enable missing clock logic. SysCtrlRegs.PLLSTS.bit.MCLKCLR = 1; EDIS; // Replace this line with a call to an appropriate // SystemShutdown(); function. asm(" ESTOP0"); // Uncomment for debugging purposes } // DIVSEL MUST be 0 before PLLCR can be changed from // 0x0000. It is set to 0 by an external reset XRSn // This puts us in 1/4 if (SysCtrlRegs.PLLSTS.bit.DIVSEL != 0) { EALLOW; SysCtrlRegs.PLLSTS.bit.DIVSEL = 0; EDIS; } EALLOW; // Before setting PLLCR turn off missing clock detect logic SysCtrlRegs.PLLSTS.bit.MCLKOFF = 1; #if F_CPU >= 60000000L SysCtrlRegs.PLLCR.bit.DIV = 0x0C; #elif F_CPU >= 50000000L SysCtrlRegs.PLLCR.bit.DIV = 0x0A; #elif F_CPU >= 40000000L SysCtrlRegs.PLLCR.bit.DIV = 0x08; #elif F_CPU >= 3000000L SysCtrlRegs.PLLCR.bit.DIV = 0x06; #elif F_CPU >= 2000000L SysCtrlRegs.PLLCR.bit.DIV = 0x04; #else #warning No Suitable Frequency found! #endif EDIS; // Uncomment to disable the watchdog disableWatchDog(); while(SysCtrlRegs.PLLSTS.bit.PLLLOCKS != 1) { // Uncomment to service the watchdog // ServiceDog(); } EALLOW; SysCtrlRegs.PLLSTS.bit.MCLKOFF = 0; EDIS; EALLOW; SysCtrlRegs.PLLSTS.bit.DIVSEL = 2; EDIS; }