/**************************************************************************//** * @brief Update clock and wait in EM2 for RTC tick. *****************************************************************************/ void clockLoop(void) { LCD_FrameCountInit_TypeDef frameInit; LCD_AnimInit_TypeDef animInit; /* Write Gecko and display, and light up the colon between hours and minutes. */ SegmentLCD_Symbol(LCD_SYMBOL_COL10, 1); SegmentLCD_Write("Wonder"); /* Setup frame counter */ frameInit.enable = true; /* Enable framecounter */ frameInit.top = 15; /* Generate event every 15 frames. */ frameInit.prescale = lcdFCPrescDiv1; /* No prescaling */ LCD_FrameCountInit(&frameInit); /* Animate half ring - by special board design it is possible to achieve */ /* "slide in/slide out" effect */ animInit.enable = true; /* Enable animation after initialization. */ animInit.AReg = 0x00; /* Initial A register value */ animInit.BReg = 0x0F; /* Initial B register value */ animInit.AShift = lcdAnimShiftLeft; /* Shift A register left */ animInit.BShift = lcdAnimShiftLeft; /* Shift B register left */ animInit.animLogic = lcdAnimLogicOr; /* Enable segment if A or B */ animInit.startSeg = 8; /* Initial animation segment */ LCD_AnimInit(&animInit); while (1) { checkVoltage(); SegmentLCD_Number(hours * 100 + minutes); EMU_EnterEM2(true); } }
/**************************************************************************//** * @brief Main function *****************************************************************************/ int main(void) { int msCountDown; const int msDelay = 100; char displayString[8]; LCD_AnimInit_TypeDef anim = { true, 0x00, lcdAnimShiftNone, 0x03, lcdAnimShiftLeft, lcdAnimLogicOr }; LCD_FrameCountInit_TypeDef fc = { true, 2, /* Update each 2nd frame */ lcdFCPrescDiv1, }; /* Chip errata */ CHIP_Init(); /* If first word of user data page is non-zero, enable eA Profiler trace */ BSP_TraceProfilerSetup(); /* Configure push button interrupts */ gpioSetup(); /* Setup SysTick Timer for 1 msec interrupts */ if (SysTick_Config(SystemCoreClockGet() / 1000)) while (1) ; /* Initialize LCD controller */ SegmentLCD_Init(false); /* Run countdown for user to select energy mode */ msCountDown = 4000; /* milliseconds */ while(msCountDown > 0) { if ( eMode >=3 && eMode<=4) { sprintf(displayString, "EM%d", eMode); SegmentLCD_Write(displayString); } switch( eMode ) { case 0: SegmentLCD_Write("EM0 32M"); break; case 1: SegmentLCD_Write("EM1 32M"); break; case 2: SegmentLCD_Write("EM2 32K"); break; case 5: SegmentLCD_Write("EM2+RTC"); break; case 6: SegmentLCD_Write("RTC+LCD"); break; } SegmentLCD_Number(msCountDown); Delay(msDelay); msCountDown -= msDelay; } /* Disable components, reenable when needed */ SegmentLCD_Disable(); RTC_Enable(false); /* Go to energy mode and wait for reset */ switch(eMode) { case 0: /* Disable pin input */ GPIO_PinModeSet(gpioPortB, 10, gpioModeDisabled, 1); /* Disable systick timer */ SysTick->CTRL = 0; /* 32Mhz primes demo - running off HFXO */ CMU_ClockSelectSet(cmuClock_HF, cmuSelect_HFXO); /* Disable HFRCO, LFRCO and all unwanted clocks */ CMU->OSCENCMD = CMU_OSCENCMD_HFRCODIS; CMU->OSCENCMD = CMU_OSCENCMD_LFRCODIS; CMU->HFPERCLKEN0 = 0x00000000; CMU->HFCORECLKEN0 = 0x00000000; CMU->LFACLKEN0 = 0x00000000; CMU->LFBCLKEN0 = 0x00000000; CMU->LFCLKSEL = 0x00000000; /* Supress Conditional Branch Target Prefetch */ MSC->READCTRL = MSC_READCTRL_MODE_WS1SCBTP; { #define PRIM_NUMS 64 uint32_t i, d, n; uint32_t primes[PRIM_NUMS]; /* Find prime numbers forever */ while (1) { primes[0] = 1; for (i = 1; i < PRIM_NUMS;) { for (n = primes[i - 1] + 1; ;n++) { for (d = 2; d <= n; d++) { if (n == d) { primes[i] = n; goto nexti; } if (n%d == 0) break; } } nexti: i++; } } } case 1: /* Disable pin input */ GPIO_PinModeSet(gpioPortB, 10, gpioModeDisabled, 1); /* Disable systick timer */ SysTick->CTRL = 0; CMU_ClockSelectSet(cmuClock_HF, cmuSelect_HFXO); /* Disable HFRCO, LFRCO and all unwanted clocks */ CMU->OSCENCMD = CMU_OSCENCMD_HFRCODIS; CMU->OSCENCMD = CMU_OSCENCMD_LFRCODIS; CMU->HFPERCLKEN0 = 0x00000000; CMU->HFCORECLKEN0 = 0x00000000; CMU->LFACLKEN0 = 0x00000000; CMU->LFBCLKEN0 = 0x00000000; CMU->LFCLKSEL = 0x00000000; EMU_EnterEM1(); break; case 2: /* Enable LFRCO */ CMU->OSCENCMD = CMU_OSCENCMD_LFRCOEN; /* Disable everything else */ CMU->OSCENCMD = CMU_OSCENCMD_LFXODIS; CMU->HFPERCLKEN0 = 0x00000000; CMU->HFCORECLKEN0 = 0x00000000; CMU->LFACLKEN0 = 0x00000000; CMU->LFBCLKEN0 = 0x00000000; CMU->LFCLKSEL = 0x00000000; EMU_EnterEM2(false); break; case 3: /* Disable all clocks */ CMU->OSCENCMD = CMU_OSCENCMD_LFXODIS; CMU->OSCENCMD = CMU_OSCENCMD_LFRCODIS; CMU->HFPERCLKEN0 = 0x00000000; CMU->HFCORECLKEN0 = 0x00000000; CMU->LFACLKEN0 = 0x00000000; CMU->LFBCLKEN0 = 0x00000000; EMU_EnterEM3(false); break; case 4: EMU_EnterEM4(); break; case 5: /* EM2 + RTC - only briefly wake up to reconfigure each second */ CMU->LFCLKSEL = CMU_LFCLKSEL_LFA_LFRCO; while(1) { RTCDRV_Trigger(2000, NULL); EMU_EnterEM2(false); } case 6: default: /* EM2 + RTC + LCD (if battery slips below 3V vboost should be */ /* enabled) */ CMU->LFCLKSEL = CMU_LFCLKSEL_LFA_LFRCO; SegmentLCD_Init(false); /* Animate LCD */ LCD_FrameCountInit(&fc); LCD_AnimInit(&anim); while(1) { SegmentLCD_Write("Energy"); /* Sleep in EM2 */ RTCDRV_Trigger(2000,NULL); EMU_EnterEM2(false); SegmentLCD_Write("Micro"); /* Sleep in EM2 */ RTCDRV_Trigger(2000,NULL); EMU_EnterEM2(false); } } return 0; }