/**************************************************************************//** * @brief Button Handler * Shared by GPIO Even and GPIO Odd interrupt handlers *****************************************************************************/ void button_handler() { uint32_t interrupt_source = GPIO_IntGet(); /* Both buttons were pushed - toggle the timer */ if (pb1_is_pushed && pb0_is_pushed) { toggleTimer = true; } if (toggleTimer) { /* Wait for both buttons to be released */ if (!pb1_is_pushed && !pb0_is_pushed) { if (enableTimer) { SegmentLCD_Write("STOP"); time = old_time; SegmentLCD_Number(time); /* Disable RTC */ RTC_Enable(false); } else { SegmentLCD_Write("START"); old_time = time; /* Enable RTC */ RTC_Enable(true); } enableTimer = !enableTimer; toggleTimer = false; return; } } else { /* If only Push Button 0 was pressed - decrease the time */ if (!pb0_is_pushed && interrupt_source & 1 << PB0_PIN) { if (time > 0) time--; SegmentLCD_Number(time); } /* If only Push Button 1 was pressed - increase the time */ else if (!pb1_is_pushed && interrupt_source & 1 << PB1_PIN) { if (time < 9999) time++; SegmentLCD_Number(time); } } }
/**************************************************************************//** * @brief Cap sense values demo *****************************************************************************/ void capSenseValues(void) { char msg[8]; uint8_t channel; switch (subMode) { case(0): snprintf(msg, 7, "Pad 0"); channel = CAPLESENSE_getSegmentChannel(0); break; case(1): snprintf(msg, 7, "Pad 1"); channel = CAPLESENSE_getSegmentChannel(1); break; case(2): snprintf(msg, 7, "Pad 2"); channel = CAPLESENSE_getSegmentChannel(2); break; case(3): snprintf(msg, 7, "Pad 3"); channel = CAPLESENSE_getSegmentChannel(3); break; default: snprintf(msg, 7, "Pad 0"); channel = CAPLESENSE_getSegmentChannel(0); break; } SegmentLCD_Write(msg); SegmentLCD_Number(CAPLESENSE_getNormalizedVal(channel)); }
/****************************************************************************** * @brief Main function * The main file starts a timer and uses PRS to trigger an ADC conversion. * It waits in EM1 until the ADC conversion is complete, then prints the * result on the lcd. *****************************************************************************/ int main(void) { /* Initialize chip */ CHIP_Init(); SegmentLCD_Init(false); /* Enable clocks required */ CMU_ClockEnable(cmuClock_ADC0, true); CMU_ClockEnable(cmuClock_PRS, true); CMU_ClockEnable(cmuClock_TIMER0, true); /* Select TIMER0 as source and TIMER0OF (Timer0 overflow) as signal (rising edge) */ PRS_SourceSignalSet(0, PRS_CH_CTRL_SOURCESEL_TIMER0, PRS_CH_CTRL_SIGSEL_TIMER0OF, prsEdgePos); ADCConfig(); TimerConfig(); /* Stay in this loop forever */ while (1) { /* Enter EM1 and wait for timer triggered adc conversion */ EMU_EnterEM1(); /* Write result to LCD */ SegmentLCD_Number(adcResult); /* Do other stuff */ int i; for (i = 0; i < 10000; i++) ; } }
/**************************************************************************//** * @brief LCD Blink Test *****************************************************************************/ void BlinkTest(void) { SegmentLCD_EnergyMode(0, 1); SegmentLCD_EnergyMode(1, 1); SegmentLCD_EnergyMode(2, 1); SegmentLCD_EnergyMode(3, 1); SegmentLCD_EnergyMode(4, 1); /* 2 minutes to midnight */ SegmentLCD_Number(2358); SegmentLCD_Symbol(LCD_SYMBOL_COL10, 1); SegmentLCD_Symbol(LCD_SYMBOL_GECKO, 1); SegmentLCD_Symbol(LCD_SYMBOL_EFM32, 1); SegmentLCD_Write(" EFM32 "); LCD->BACTRL |= LCD_BACTRL_BLINKEN; while (LCD->SYNCBUSY) ; EM2Sleep(2000); SegmentLCD_EnergyMode(4, 0); EM2Sleep(62); SegmentLCD_EnergyMode(3, 0); EM2Sleep(62); SegmentLCD_EnergyMode(2, 0); EM2Sleep(62); SegmentLCD_EnergyMode(1, 0); EM2Sleep(62); SegmentLCD_EnergyMode(0, 0); LCD->BACTRL &= ~LCD_BACTRL_BLINKEN; while (LCD->SYNCBUSY) ; }
/**************************************************************************//** * @brief LESENSE_IRQHandler * Interrupt Service Routine for LESENSE Interrupt Line *****************************************************************************/ void LESENSE_IRQHandler(void) { /* Read interrupts flags */ uint32_t intFlags = LESENSE_IntGet(); /* Clear interrupts */ LESENSE_IntClear(LESENSE_IFC_DEC | LESENSE_IFC_DECERR); /* Enable clock for LCD. */ CMU_ClockEnable(cmuClock_LCD, true); /* Wait until SYNCBUSY_CTRL flag is cleared. */ LCD_SyncBusyDelay(LCD_SYNCBUSY_CTRL); /* Enable LCD. */ LCD_Enable(true); /* If there is a decoder error stop trap execution in this loop */ if (intFlags & LESENSE_IF_DECERR) { /* DECODER ERROR */ SegmentLCD_Write(LCSENSE_ERROR_STRING); while (1) ; } /* Write PCNT counter number the LCD */ SegmentLCD_Number(PCNT_CounterGet(PCNT0)); /* Disable RTC first to reset counter */ RTC_Enable(false); /* Set compare value */ RTC_CompareSet(0, RTC_COMP_VALUE); /* Enable RTC */ RTC_Enable(true); }
void lcd_write_number(int value) { SegmentLCD_Symbol(LCD_SYMBOL_DP10, 0); SegmentLCD_Symbol(LCD_SYMBOL_DEGC, 0); SegmentLCD_Symbol(LCD_SYMBOL_DEGF, 0); SegmentLCD_Number(value); }
/**************************************************************************//** * @brief LESENSE_IRQHandler * Interrupt Service Routine for LESENSE Interrupt Line *****************************************************************************/ void LESENSE_IRQHandler(void) { /* Clear interrupt flag */ LESENSE_IntClear(LESENSE_IFS_DEC); SegmentLCD_Number(++proximityCounter); }
/**************************************************************************//** * @brief Cap sense values demo *****************************************************************************/ void capSenseBars(void) { int barNum; int sliderPos; const char bars[3] = {'{', '!', '1' }; char msg[8]; sliderPos = CAPLESENSE_getSliderPosition(); SegmentLCD_Number(sliderPos); if (sliderPos == -1) { SegmentLCD_Write("SLIDER"); } else { /* Clear the msg string */ snprintf(msg, 7, " "); /* There are 21 possible "bars" on the display, while there are 48 slider * positions. This maps these 48 into 21 slider positions. */ barNum = (sliderPos * 21) / 48; msg[barNum / 3] = bars[barNum %3]; SegmentLCD_Write(msg); } }
/**************************************************************************//** * @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 LCD Blink Test *****************************************************************************/ void BlinkTest(void) { SegmentLCD_EnergyMode(0, 1); SegmentLCD_EnergyMode(1, 1); SegmentLCD_EnergyMode(2, 1); SegmentLCD_EnergyMode(3, 1); SegmentLCD_EnergyMode(4, 1); /* 2 minutes to midnight */ SegmentLCD_Number(2358); SegmentLCD_Symbol(LCD_SYMBOL_COL10, 1); SegmentLCD_Symbol(LCD_SYMBOL_GECKO, 1); SegmentLCD_Symbol(LCD_SYMBOL_EFM32, 1); SegmentLCD_Write(" EFM32 "); LCD_BlinkEnable(true); LCD_SyncBusyDelay(0xFFFFFFFF) ; EM2Sleep(2000); SegmentLCD_EnergyMode(4, 0); EM2Sleep(62); SegmentLCD_EnergyMode(3, 0); EM2Sleep(62); SegmentLCD_EnergyMode(2, 0); EM2Sleep(62); SegmentLCD_EnergyMode(1, 0); EM2Sleep(62); SegmentLCD_EnergyMode(0, 0); LCD_BlinkEnable(false); LCD_SyncBusyDelay(0xFFFFFFFF); }
// Function used to update the display // No bounds checking. void display_time(const uint16_t set_hours, const uint16_t set_minutes) { display_hours = set_hours; display_minutes = set_minutes; SegmentLCD_Number(display_hours * 100 + display_minutes); }
/**************************************************************************//** * @brief Real Time Counter Interrupt Handler *****************************************************************************/ void RTC_IRQHandler(void) { /* Clear interrupt source */ RTC_IntClear(RTC_IFC_COMP0); time--; SegmentLCD_Number(time); if (time == 0) { SegmentLCD_Write("DONE"); time = old_time; /* Disable RTC */ RTC_Enable(false); enableTimer = false; } SegmentLCD_Number(time); }
/****************************************************************************** * @brief Main function *****************************************************************************/ int main(void) { /* Initialize chip */ CHIP_Init(); /* Enable code view */ setupSWO(); /* Initialize LCD */ SegmentLCD_Init(false); /* Enable the HFPER clock */ CMU_ClockEnable(cmuClock_HFPER, true); /* Configure RTC and GPIO */ rtc_setup(); gpio_setup(); /* Stay in this loop forever */ while (1) { /* Wait for Push Button 1 to be pressed */ while (GPIO_PinInGet(PB0_PORT, PB0_PIN)) ; /* and released, so that we do not exit the while loop below immediately */ while (!GPIO_PinInGet(PB0_PORT, PB0_PIN)) ; /* Reset time */ time = 0; /* Disable LCD */ LCD_Enable(true); /* Update time until Push Button 1 is pressed again */ while (1) { if (RTC_CounterGet() == 0) { SegmentLCD_Number(++time); } if (!GPIO_PinInGet(PB0_PORT, PB0_PIN)) break; } /* Delay while showing the result on the LCD */ for (uint32_t delay = 0; delay < 30; delay++) { /* Wait for the RTC to overflow once */ while (RTC_CounterGet() != 0) ; while (RTC_CounterGet() == 0) ; } /* Disable LCD */ LCD_Enable(false); } }
void lcd_write_temperature(int temperature, bool celcius) { SegmentLCD_Number(temperature); SegmentLCD_Symbol(LCD_SYMBOL_DP10, 1); if (celcius) SegmentLCD_Symbol(LCD_SYMBOL_DEGC, 1); else SegmentLCD_Symbol(LCD_SYMBOL_DEGF, 1); }
/**************************************************************************//** * @brief GPIO Interrupt handler (PB9) * Saves the number to the userpage *****************************************************************************/ void GPIO_ODD_IRQHandler(void) { /* Acknowledge interrupt */ GPIO_IntClear(1 << 9); /* Increase data - Wrap at 10000 */ userData.number = (userData.number + 1) % 10000; /* Update the display */ SegmentLCD_Number(userData.number); }
/**************************************************************************//** * @brief GPIO Interrupt Handler *****************************************************************************/ void GPIO_IRQHandler_2(void) { /* Get the interrupt source, either Push Button 2 (pin B11) or pin D3 */ uint32_t interrupt_source = GPIO_IntGet(); /* Push Button 2 (pin B11) */ if (interrupt_source & (1 << PB1_PIN)) { GPIO_IntClear(1 << PB1_PIN); SegmentLCD_Write("Clear"); time = 0; enableCount = false; SegmentLCD_Number(time); } /* Pin D3 - channel 3 => 2^3 */ if (interrupt_source & (1 << 3)) { /* Operations can be made atomic, i.e. it cannot be interrupted by * interrupts with higher priorities, by disabling iterrupts. Uncomment * __disable_irq(); and __enable_irq(); to see how the update of the time * is delayed by the dummy loop below.*/ /* __disable_irq(); */ /* Toggle enableGecko */ if (enableGecko) enableGecko = false; else enableGecko = true; SegmentLCD_Symbol(LCD_SYMBOL_GECKO, enableGecko); /* This dummy loop is intended to illustrate the different levels of * priority. The timer will continue to update the LCD display, but * interrupts produced by Push Button 1 and 2 will not be served until * after this function has finished. */ for (uint32_t tmp = 0; tmp < 2000000; tmp++) ; GPIO_IntClear(1 << 3); /* Enable interrupts again */ /* __enable_irq(); */ } }
/**************************************************************************//** * @brief Main function *****************************************************************************/ int main(void) { /* Initialize chip */ CHIP_Init(); SegmentLCD_Init(true); initRTC(); initGPIO(); /* Initial LCD content */ SegmentLCD_Number(time); while (1) { /* Go to EM2 */ EMU_EnterEM2(true); /* Wait for interrupts */ } }
/**************************************************************************//** * @brief TIMER0 Interrupt Handler. Writes interrupt count to LCD display *****************************************************************************/ void TIMER0_IRQHandler(void) { /* Clear TIMER0 OF interrupt flag. */ /* Do not need to check other flags since we know this is the only one enabled */ TIMER_IntClear(TIMER0, TIMER_IFC_OF); /* Increment interrupt count and write to LCD */ interruptCount++; SegmentLCD_Number(interruptCount); /* Wait until interrupt has been serviced 5 times */ if (interruptCount >= 5) { /* Clear SLEEPONEXIT to go back to main after ISR */ SCB->SCR &= ~SCB_SCR_SLEEPONEXIT_Msk; /* Stop TIMER0 */ TIMER0->CMD = TIMER_CMD_STOP; } }
/**************************************************************************//** * @brief ScrollText demo *****************************************************************************/ void capSenseScrollText(void) { char msg[10]; int sliderPos; static int oldSliderPos = -2; int offset; sliderPos = CAPLESENSE_getSliderPosition(); if (oldSliderPos != sliderPos) { oldSliderPos = sliderPos; SegmentLCD_Number(sliderPos); if (sliderPos == -1) sliderPos = 0; offset = ((strlen(message) - 7) * sliderPos) / 48; snprintf(msg, 8, "%s", message + offset); SegmentLCD_Write(msg); } }
/**************************************************************************//** * @brief Main function *****************************************************************************/ int main(void) { /* Chip errata */ CHIP_Init(); /* If first word of user data page is non-zero, enable eA Profiler trace */ BSP_TraceProfilerSetup(); /* Initialize LCD controller without boost */ SegmentLCD_Init(false); /* Disable all segments */ SegmentLCD_AllOff(); /* Copy contents of the userpage (flash) into the userData struct */ memcpy((void *) &userData, (void *) USERPAGE, sizeof(UserData_TypeDef)); /* Special case for uninitialized data */ if (userData.number > 10000) userData.number = 0; if (userData.numWrites == 0xFFFFFFFF) userData.numWrites = 0; /* Display the number */ SegmentLCD_Number(userData.number); /* Setup GPIO interrupts. PB0 to increase number, PB1 to save to flash */ gpioSetup(); /* No save has occured yet */ recentlySaved = false; /* Main loop - just scroll informative text describing the current state of * the system */ while (1) { switch (currentError) { case mscReturnInvalidAddr: ScrollText(" ERROR: INVALID ADDRESS "); break; case mscReturnLocked: ScrollText(" ERROR: USER PAGE IS LOCKED "); break; case mscReturnTimeOut: ScrollText(" ERROR: TIMEOUT OCCURED "); break; case mscReturnUnaligned: ScrollText(" ERROR: UNALIGNED ACCESS "); default: if (recentlySaved) { recentlySaved = false; SegmentLCD_Number(userData.numWrites); ScrollText(" SAVE NUMBER "); } else { SegmentLCD_Number(userData.number); ScrollText(" PRESS PB0 TO INCREASE NUMBER. PB1 TO SAVE TO INTERNAL FLASH "); } break; } } }
/**************************************************************************//** * @brief Main function *****************************************************************************/ int main(void) { SYSTEM_ChipRevision_TypeDef revision; char string[8]; int i; uint32_t temp; /* Chip revision alignment and errata fixes */ CHIP_Init(); /* Initialize DVK board register access */ BSP_Init(BSP_INIT_DEFAULT); /* If first word of user data page is non-zero, enable eA Profiler trace */ BSP_TraceProfilerSetup(); CMU_ClockEnable(cmuClock_HFPER, true); CMU_ClockEnable(cmuClock_ADC0, true); CMU_ClockEnable(cmuClock_GPIO, true); /* Initialize LCD controller without boost */ SegmentLCD_Init(false); SegmentLCD_AllOff(); /* Check for revision after revision B. Chips with revision earlier than */ /* Revision C has known problems with the internal temperature sensor. */ /* Display a warning in this case */ SYSTEM_ChipRevisionGet(&revision); if (revision.minor < 2) { SegmentLCD_Write("WARNING"); RTCDRV_Trigger(2000, NULL); EMU_EnterEM2(true); SegmentLCD_Write("REV C+"); RTCDRV_Trigger(2000, NULL); EMU_EnterEM2(true); SegmentLCD_Write("REQUIRD"); RTCDRV_Trigger(2000, NULL); EMU_EnterEM2(true); } /* Enable board control interrupts */ BSP_InterruptDisable(0xffff); BSP_InterruptFlagsClear(0xffff); BSP_InterruptEnable(BC_INTEN_JOYSTICK); temperatureIRQInit(); /* Setup ADC for sampling internal temperature sensor. */ setupSensor(); /* Main loop - just read temperature and update LCD */ while (1) { /* Start one ADC sample */ ADC_Start(ADC0, adcStartSingle); /* Wait in EM1 for ADC to complete */ EMU_EnterEM1(); /* Read sensor value */ temp = ADC_DataSingleGet(ADC0); /* Convert ADC sample to Fahrenheit / Celsius and print string to display */ if (showFahrenheit) { /* Show Fahrenheit on alphanumeric part of display */ i = (int)(convertToFahrenheit(temp) * 10); snprintf(string, 8, "%2d,%1d%%F", (i/10), i%10); /* Show Celsius on numeric part of display */ i = (int)(convertToCelsius(temp) * 10); SegmentLCD_Number(i*10); SegmentLCD_Symbol(LCD_SYMBOL_DP10, 1); } else { /* Show Celsius on alphanumeric part of display */ i = (int)(convertToCelsius(temp) * 10); snprintf(string, 8, "%2d,%1d%%C", (i/10), i%10); /* Show Fahrenheit on numeric part of display */ i = (int)(convertToFahrenheit(temp) * 10); SegmentLCD_Number(i*10); SegmentLCD_Symbol(LCD_SYMBOL_DP10, 1); } SegmentLCD_Write(string); /* Sleep for 2 seconds in EM 2 */ RTCDRV_Trigger(2000, NULL); EMU_EnterEM2(true); } }
/**************************************************************************//** * @brief ACMP_setup * Configures and starts the ACMP *****************************************************************************/ void ACMP_setup(void) { /* Enable necessary clocks */ CMU_ClockEnable(cmuClock_ACMP0, true); CMU_ClockEnable(cmuClock_GPIO, true); /* Configure PC4 as input with pull down for ACMP channel 4 input */ GPIO_PinModeSet(gpioPortC, 4, gpioModeInputPullFilter, 0); /* Analog comparator parameters */ const ACMP_Init_TypeDef acmpInit = { .fullBias = false, /* no full bias current*/ .halfBias = false, /* no half bias current */ .biasProg = 7, /* Biasprog current 1.4 uA */ .interruptOnFallingEdge = false, /* disable interrupt for falling edge */ .interruptOnRisingEdge = false, /* disable interrupt for rising edge */ .warmTime = acmpWarmTime256, /* Warm-up time in clock cycles, should be >140 cycles for >10us warm-up @ 14MHz */ .hysteresisLevel = acmpHysteresisLevel0, /* Hysteresis level 0 - no hysteresis */ .inactiveValue = 0, /* Inactive comparator output value */ .lowPowerReferenceEnabled = false, /* Low power reference mode disabled */ .vddLevel = 32, /* Vdd reference scaling of 32 */ }; /* Init ACMP and set ACMP channel 4 as positive input and scaled Vdd as negative input */ ACMP_Init(ACMP0, &acmpInit); ACMP_ChannelSet(ACMP0, acmpChannelVDD, acmpChannel4); ACMP_Enable(ACMP0); } /**************************************************************************//** * @brief PRS_ScanChannel * Waits for activity on a selected PRS channel and writes on the LCD when activity occurs * * @param[in] timer * Pointer to TIMER peripheral register block. * * @param[in] prsCh * PRS Channel to be monitored * * @param[in] edgeType * Signal edge to be monitored/captured *****************************************************************************/ void PRS_ScanChannel(TIMER_TypeDef *timer, TIMER_PRSSEL_TypeDef prsCh, TIMER_Edge_TypeDef edgeType) { /* enable the clock for the correct timer */ #define TIMER_Clock(T) (T==TIMER0 ? cmuClock_TIMER0 : \ T==TIMER1 ? cmuClock_TIMER1 : 0) /* Enable necessary clocks */ CMU_ClockEnable((CMU_Clock_TypeDef)TIMER_Clock(timer), true); /* Initialize LCD */ SegmentLCD_Init(false); /* Select CC channel parameters */ const TIMER_InitCC_TypeDef timerCCInit = { .eventCtrl = timerEventFalling, /* input capture event control */ .edge = edgeType, /* input capture on falling edge */ .prsSel = prsCh, /* prs channel select channel 5*/ .cufoa = timerOutputActionNone, /* no action on counter underflow */ .cofoa = timerOutputActionNone, /* no action on counter overflow */ .cmoa = timerOutputActionNone, /* no action on counter match */ .mode = timerCCModeCapture, /* CC channel mode capture */ .filter = false, /* no filter */ .prsInput = true, /* CC channel PRS input */ .coist = false, /* comparator output initial state */ .outInvert = false, /* no output invert */ }; /* Initialize TIMER0 CC0 */ TIMER_InitCC(timer, 0, &timerCCInit); /* Select timer parameters */ const TIMER_Init_TypeDef timerInit = { .enable = true, /* start counting when init complete */ .debugRun = false, /* counter not running on debug halt */ .prescale = timerPrescale1024, /* prescaler of 64 */ .clkSel = timerClkSelHFPerClk, /* TIMER0 clocked by the HFPERCLK */ .fallAction = timerInputActionNone, /* stop counter on falling edge */ .riseAction = timerInputActionNone, /* reload and start on rising edge */ .mode = timerModeUp, /* counting up */ .dmaClrAct = false, /* no DMA */ .quadModeX4 = false, /* no quad decoding */ .oneShot = false, /* counting up constinuously */ .sync = false, /* no start/stop/reload by other timers */ }; /* Initialize TIMER0 */ TIMER_Init(timer, &timerInit); /* Poll the Input Capture Valid flag in the Status register The program will hang at this point waiting for activity on this channel */ while(!((TIMER0->STATUS & _TIMER_STATUS_ICV0_MASK )>>16)); } /**************************************************************************//** * @brief Main function * Main is called from __iar_program_start, see assembly startup file *****************************************************************************/ int main(void) { /* Align different chip revisions*/ CHIP_Init(); /* Initialise the ACMP */ ACMP_setup(); /* PRS setup */ /* Enable clock for PRS and select ACMP as source and ACMP0OUT (ACMP0 OUTPUT) as signal for channel 5 */ CMU_ClockEnable(cmuClock_PRS, true); PRS_SourceSignalSet(5, PRS_CH_CTRL_SOURCESEL_ACMP0, PRS_CH_CTRL_SIGSEL_ACMP0OUT, prsEdgeOff); /* Start PRS scan This function will halt the program while there is no PRS activity This function assumes that the PRS has been setup previously */ PRS_ScanChannel(TIMER0, timerPRSSELCh5, timerEdgeFalling); /* Write PRS and channel number on the LCD to acknowledge PRS activity */ SegmentLCD_Write("PRS"); SegmentLCD_Number((int)timerPRSSELCh5); while(1) { /* Enter EM1 while waiting for capture. */ EMU_EnterEM1(); } }
/**************************************************************************//** * @brief Main function *****************************************************************************/ int main(void) { int value, delayCount = 0, hfrcoband = 0; float current, voltage; bool vboost; char buffer[8]; /* Chip errata */ CHIP_Init(); /* If first word of user data page is non-zero, enable eA Profiler trace */ BSP_TraceProfilerSetup(); /* Initialize board support package */ BSP_Init(BSP_INIT_BCC); /* Setup SysTick Timer for 1 msec interrupts */ if (SysTick_Config(SystemCoreClockGet() / 1000)) while (1) ; /* Initialize voltage comparator, to check supply voltage */ VDDCHECK_Init(); /* Check if voltage is below 3V, if so use voltage boost */ if (VDDCHECK_LowVoltage(2.9)) { vboost = true; } else { vboost = false; } /* Disable Voltage Comparator */ VDDCHECK_Disable(); /* Initialize segment LCD */ SegmentLCD_Init(vboost); /* Infinite loop */ while (1) { /* Read and display current */ current = BSP_CurrentGet(); value = (int)(1000 * current); /* Check that we fall within displayable value */ if ((value > 0) && (value < 10000)) { SegmentLCD_Number(value); } else { SegmentLCD_Number(-1); } /* Alternate between voltage and clock frequency */ if (((delayCount / 10) & 1) == 0) { voltage = BSP_VoltageGet(); value = (int)(voltage * 100); SegmentLCD_Symbol(LCD_SYMBOL_DP6, 1); sprintf(buffer, "Volt%3d", value); SegmentLCD_Write(buffer); } else { SegmentLCD_Symbol(LCD_SYMBOL_DP6, 0); sprintf(buffer, "%3u MHz", (int)(SystemCoreClockGet() / 1000000)); SegmentLCD_Write(buffer); } /* After 5 seconds, use another HFRCO band */ if (delayCount % 50 == 0) { switch (hfrcoband) { case 0: CMU_HFRCOBandSet(cmuHFRCOBand_11MHz); break; case 1: CMU_HFRCOBandSet(cmuHFRCOBand_14MHz); break; case 2: CMU_HFRCOBandSet(cmuHFRCOBand_21MHz); break; default: CMU_HFRCOBandSet(cmuHFRCOBand_28MHz); /* Restart iteartion */ hfrcoband = -1; break; } hfrcoband++; /* Recalculate delay tick count and baudrate generation */ if (SysTick_Config(SystemCoreClockGet() / 1000)) while (1) ; BSP_Init(BSP_INIT_BCC); } Delay(100); delayCount++; } }
/****************************************************************************** * @brief Main function * Main is called from _program_start, see assembly startup file *****************************************************************************/ int main(void) { /* Initialize chip */ CHIP_Init(); /* The HFRCO is the default clock source for the HF * branch, but it is explicitly selected here * for comprehension purposes */ CMU_ClockSelectSet(cmuClock_HF, cmuSelect_HFRCO); /* Enable LFXO to clock the LFA clock branch */ CMU_OscillatorEnable(cmuOsc_LFXO, true, true); /* Select LFXO as clock source for the LFA branch */ CMU_ClockSelectSet(cmuClock_LFA, cmuSelect_LFXO); /* Enable clock for LCD module */ CMU_ClockEnable(cmuClock_LCD, true); /* Enable clock for GPIO module */ CMU_ClockEnable(cmuClock_GPIO, true); /* Set PC12 as output so it can be * overriden by the peripheral, in this case the CMU */ GPIO_PinModeSet(gpioPortC, 12, gpioModePushPull, 0); /* Initialize LCD */ SegmentLCD_Init(false); /* Set the tuning to the max value so the HFRCO goes to a frequency above 14Mhz * - the frequency will depend on the chip */ CMU_OscillatorTuningSet(cmuOsc_HFRCO, TUNINGMAX); /* Select Clock Output 0 as High Frequency RC without prescalling (14 Mhz) */ CMU->CTRL = CMU->CTRL | CMU_CTRL_CLKOUTSEL1_LFRCO | CMU_CTRL_CLKOUTSEL0_HFRCO; /* Route the Clock output pin to Location 1 and enable them */ CMU->ROUTE = CMU_ROUTE_LOCATION_LOC1 | CMU_ROUTE_CLKOUT0PEN; /* Write Tuning on the LCD while the function runs */ SegmentLCD_Write("TUNING"); /* Variable for reading the tuning value after the calibration */ uint8_t tuning; /* Run HFRCO calibration for the 14Mhz band * This function takes about 10 seconds to execute because * the HFRCO was purposely untuned to the 14Mhz band upper limit * (TUNING = 0xFF) * The calibration loop inside this function will have to execute * as many times as needed for the HFRCO become calibrated * which usually happens for a TUNING value of 116-122, depending * on the chip */ tuning = calibrateHFRCO(HFCYCLES, UP_COUNTER_TUNED); /* Write the tuning result on the LCD and TUNING FINISHED */ SegmentLCD_Write("DONE"); SegmentLCD_Number(tuning); while (1) ; }
/**************************************************************************//** * @brief Main function *****************************************************************************/ int main(void) { int i = 0; uint16_t temp_humid_sensor; float rel_humidity, dew_point; char buffer_humid[10]; // char buffer_voltage[10]; // char light_level[10]; /* Chip errata */ CHIP_Init(); /* If first word of user data page is non-zero, enable eA Profiler trace */ TRACE_ProfilerSetup(); /* Setup SysTick Timer for 1 msec interrupts */ if (SysTick_Config(CMU_ClockFreqGet(cmuClock_CORE) / 1000)) while (1) ; /* Disable usart0 clock, it is enabled by default in gecko series mcu's. */ CMU_ClockEnable(cmuClock_USART0, false); /* Infinite blink loop with main state machine */ state = RESET; while (1) { // state machine switch(state){ case RESET: // RESET state check for vital HW functions if(1){ // todo all checks i = 0; state = INIT; } else state = RESET; break; case INIT: // INIT state initialize all necessary peripherials if(1){ i = i + 1; /* Enable clocks. */ CMU_ClockEnable(cmuClock_GPIO, true); CMU_ClockEnable(cmuClock_I2C0, true); /* Configure PB9, PB10 pin interrupt on falling edge do not enable yet. */ GPIO_PinModeSet(gpioPortB, 9, gpioModeInput, 0); GPIO_PinModeSet(gpioPortB, 10, gpioModeInput, 0); GPIO_IntConfig(gpioPortB, 9, false, true, true); GPIO_IntConfig(gpioPortB, 10, false, true, true); HumiditySensorInit(); LED_Init(); /* Initialize LED driver */ LED_Set(0); /* Enable LCD without voltage boost */ SegmentLCD_Init(false); /* Init LCD driver */ SegmentLCD_Write("ST: INIT"); Delay(500); SegmentLCD_Number(i); Delay(500); state = IDLE; } else state = INIT; break; case IDLE: if(1){ i = i + 1; SegmentLCD_Write("ST: IDLE"); Delay(500); SegmentLCD_Number(i); Delay(500); // while idle check humidity and temp paramters rel_humidity = ReadHumiditySensor(); dew_point = getDewPoint(); /* Get temperature from humidity sensor, notice that both pressure sensor and */ /* humidity sensor has built in temperature sensors, since dewpoint and pressure */ /* is dependent on the temperature close to the sensor it gives the most accurate */ /* results to use the built in temperature sensor in each device. */ temp_humid_sensor = getTemperatureHumidSensor(); state = RX_STATE; } else state = IDLE; break; case RX_STATE : if(1){ i = i + 1; SegmentLCD_Write("ST: Rx"); Delay(500); SegmentLCD_Number(i); Delay(500); SegmentLCD_Symbol(LCD_SYMBOL_ANT, 1); state = TX_STATE; } else state = RX_STATE; break; case TX_STATE: if(1){ i = i + 1; SegmentLCD_Write("ST: TX"); Delay(500); SegmentLCD_Number(i); Delay(500); SegmentLCD_Symbol(LCD_SYMBOL_ANT, 1); state = ERROR; } else state = TX_STATE; break; case ERROR: if(1){ i = i + 1; SegmentLCD_Write("ST: ERR"); Delay(500); SegmentLCD_Number(i); Delay(500); state = IDLE; } else state = ERROR; break; } LED_Toggle(0); LED_Toggle(1); Delay(1000); } }
/**************************************************************************//** * @brief Software Interrupt Handler *****************************************************************************/ void PendSV_Handler(void) { SegmentLCD_Number(time); }
/**************************************************************************//** * @brief Main function *****************************************************************************/ int main(void) { uint8_t prod_rev; char string[8]; int i; uint32_t temp; uint32_t temp_offset; /* Chip errata */ CHIP_Init(); /* If first word of user data page is non-zero, enable eA Profiler trace */ BSP_TraceProfilerSetup(); /* Enable peripheral clocks */ CMU_ClockEnable(cmuClock_HFPER, true); CMU_ClockEnable(cmuClock_ADC0, true); /* Initialize RTC timer. */ RTCDRV_Init(); RTCDRV_AllocateTimer( &xTimerForWakeUp); /* Initialize LCD controller without boost */ SegmentLCD_Init(false); SegmentLCD_AllOff(); /* This is a work around for Chip Rev.D Errata, Revision 0.6. */ /* Check for product revision 16 and 17 and set the offset */ /* for ADC0_TEMP_0_READ_1V25. */ prod_rev = (DEVINFO->PART & _DEVINFO_PART_PROD_REV_MASK) >> _DEVINFO_PART_PROD_REV_SHIFT; if( (prod_rev == 16) || (prod_rev == 17) ) { temp_offset = 112; } else { temp_offset = 0; } /* Enable board control interrupts */ gpioSetup(); /* Setup ADC for sampling internal temperature sensor. */ setupSensor(); /* Main loop - just read temperature and update LCD */ while (1) { /* Start one ADC sample */ ADC_Start(ADC0, adcStartSingle); /* Wait in EM1 for ADC to complete */ EMU_EnterEM1(); /* Read sensor value */ /* According to rev. D errata ADC0_TEMP_0_READ_1V25 should be decreased */ /* by the offset but it is the same if ADC reading is increased - */ /* reference manual 28.3.4.2. */ temp = ADC_DataSingleGet(ADC0) + temp_offset; /* Convert ADC sample to Fahrenheit / Celsius and print string to display */ if (showFahrenheit) { /* Show Fahrenheit on alphanumeric part of display */ i = (int)(convertToFahrenheit(temp) * 10); snprintf(string, 8, "%2d,%1d%%F", (i/10), abs(i%10)); /* Show Celsius on numeric part of display */ i = (int)(convertToCelsius(temp) * 10); SegmentLCD_Number(i*10); SegmentLCD_Symbol(LCD_SYMBOL_DP10, 1); SegmentLCD_Symbol(LCD_SYMBOL_DEGC, 1); SegmentLCD_Symbol(LCD_SYMBOL_DEGF, 0); } else { /* Show Celsius on alphanumeric part of display */ i = (int)(convertToCelsius(temp) * 10); snprintf(string, 8, "%2d,%1d%%C", (i/10), abs(i%10)); /* Show Fahrenheit on numeric part of display */ i = (int)(convertToFahrenheit(temp) * 10); SegmentLCD_Number(i*10); SegmentLCD_Symbol(LCD_SYMBOL_DP10, 1); SegmentLCD_Symbol(LCD_SYMBOL_DEGC, 0); SegmentLCD_Symbol(LCD_SYMBOL_DEGF, 1); } SegmentLCD_Write(string); /* Sleep for 2 seconds in EM 2 */ RTCDRV_StartTimer( xTimerForWakeUp, rtcdrvTimerTypeOneshot, 2000, NULL, NULL); EMU_EnterEM2(true); } }
/**************************************************************************//** * @brief Main function *****************************************************************************/ int main(void) { const int msDelay = 100; /* Chip errata */ CHIP_Init(); /* If first word of user data page is non-zero, enable eA Profiler trace */ BSP_TraceProfilerSetup(); /* Power down special RAM blocks to reduce current consumption with some nA. */ CMU_ClockEnable(cmuClock_CORELE, true); LESENSE->POWERDOWN = LESENSE_POWERDOWN_RAM; CMU_ClockEnable(cmuClock_CORELE, false); /* 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) { switch (eMode) { case 0: SegmentLCD_Write("EM0 32M"); break; case 1: SegmentLCD_Write("EM1 32M"); break; case 2: SegmentLCD_Write("EM2 32K"); break; case 3: SegmentLCD_Write("EM3"); break; case 4: SegmentLCD_Write("EM4"); break; case 5: SegmentLCD_Write("EM2+RTC"); break; case 6: SegmentLCD_Write("RTC+LCD"); break; case 7: SegmentLCD_Write("EM3+RTC"); break; case 8: SegmentLCD_Write("USER"); break; } SegmentLCD_Number(msCountDown); Delay(msDelay); msCountDown -= msDelay; } /* Disable components, reenable when needed */ SegmentLCD_Disable(); RTC_Enable(false); /* GPIO->ROUTE = 0x00000000; */ /* 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; /* Disable LFB clock select */ 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; CMU->LFCLKSEL = 0x00000000; EMU_EnterEM3(false); break; case 4: /* Go straight down to EM4 */ EMU_EnterEM4(); break; case 5: /* EM2 + RTC - only briefly wake up to reconfigure every 2 seconds */ /* Disable LFB clock select */ CMU->LFCLKSEL &= ~(_CMU_LFCLKSEL_LFB_MASK); RTCDRV_Setup(cmuSelect_LFRCO, cmuClkDiv_32); while (1) { RTCDRV_Trigger(2000, NULL); EMU_EnterEM2(false); } case 6: /* EM2 + RTC + LCD (if battery slips below 3V vboost should be enabled) */ /* Disable LFB clock select */ CMU->LFCLKSEL &= ~(_CMU_LFCLKSEL_LFB_MASK); SegmentLCD_Init(false); RTCDRV_Setup(cmuSelect_LFRCO, cmuClkDiv_32); while (1) { SegmentLCD_Write("Silicon"); /* Sleep in EM2 */ RTCDRV_Trigger(2000, NULL); EMU_EnterEM2(false); SegmentLCD_Write(" Labs"); /* Sleep in EM2 */ RTCDRV_Trigger(2000, NULL); EMU_EnterEM2(false); } case 7: /* EM3 + RTC - only briefly wake up to reconfigure every ~5 seconds */ while (1) { /* Disable LFB clock select */ CMU->LFCLKSEL &= ~(_CMU_LFCLKSEL_LFB_MASK); /* This RTCDRV_Setup will configure LFCLK A as ULFRCO */ RTCDRV_Setup(cmuSelect_ULFRCO, cmuClkDiv_1); RTCDRV_Trigger(5000, NULL); /* Sleep in EM3, wake up on RTC trigger */ EMU_EnterEM3(false); /* SegmentLCD_Init will configure LFCLK A as LFRCO */ SegmentLCD_Init(false); SegmentLCD_Write("ULFRCO"); Delay(1000); SegmentLCD_Disable(); } case 8: default: /* User defined */ break; } return 0; }
/**************************************************************************//** * @brief Main function. *****************************************************************************/ int main( void ) { int i; MPU_RegionInit_TypeDef flashInit = MPU_INIT_FLASH_DEFAULT; MPU_RegionInit_TypeDef sramInit = MPU_INIT_SRAM_DEFAULT; MPU_RegionInit_TypeDef peripheralInit = MPU_INIT_PERIPHERAL_DEFAULT; /* Chip alignment */ CHIP_Init(); /* If first word of user data page is non-zero, enable eA Profiler trace */ BSP_TraceProfilerSetup(); /* Enable LCD without voltage boost */ SegmentLCD_Init( false ); SegmentLCD_AllOff(); SegmentLCD_Symbol(LCD_SYMBOL_GECKO, 1); SegmentLCD_Symbol(LCD_SYMBOL_EFM32, 1); GpioInit(); RTCDRV_Setup( cmuSelect_LFXO, cmuClkDiv_32); ScrollText( " MPU DEMO PRESS Pb0 OR Pb1 " "TO GENERATE MPU EXCEPTIONS " ); MPU_Disable(); /* Flash memory */ MPU_ConfigureRegion( &flashInit ); /* SRAM */ MPU_ConfigureRegion( &sramInit ); /* SRAM, a 4k part with priviledged only access, this regions settings */ /* will override those of the previous region */ sramInit.regionNo = 2; sramInit.baseAddress = RAM_MEM_BASE + 0x2000; sramInit.size = mpuRegionSize4Kb; sramInit.accessPermission = mpuRegionApPRw; MPU_ConfigureRegion( &sramInit ); /* LCD, priviledged only access */ peripheralInit.regionNo = 3; peripheralInit.baseAddress = LCD_BASE; peripheralInit.size = mpuRegionSize128b; peripheralInit.accessPermission = mpuRegionApPRw; MPU_ConfigureRegion( &peripheralInit ); MPU_Enable( MPU_CTRL_PRIVDEFENA ); /* Full access to default memory map */ /* in priviledged state */ i = 0; while ( 1 ) { SegmentLCD_Number( i ); /* Count on numeric diplay */ i = ( i + 1 ) % 101; RTCDRV_Delay( 150 , false); if ( PB0_PUSHED() ) { BullsEye( 1 ); /* Generate an access violation in internal SRAM */ __set_CONTROL( 1 ); /* Enter User (unpriviledged) state */ *(volatile uint32_t *)(RAM_MEM_BASE + 0x2000) = 1; BullsEye( 0 ); } if ( PB1_PUSHED() ) { BullsEye( 1 ); /* Generate an access violation in LCD peripheral */ __set_CONTROL( 1 ); /* Enter User (unpriviledged) state */ BullsEye( 0 ); } } }
/**************************************************************************//** * @brief LCD Test Routine, shows various text and patterns *****************************************************************************/ void Test(void) { int i, numberOfIterations = 0; /* Initialize GPIO */ GPIO_IRQInit(); /* Initialize RTC */ RTCDRV_Setup(cmuSelect_LFRCO, cmuClkDiv_32); /* Loop through funny pattern */ while (1) { SegmentLCD_AllOff(); #if VBOOST_SUPPORT checkVoltage(); #endif if (emMode != DEMO_MODE_NONE) { SegmentLCD_Symbol(LCD_SYMBOL_PAD0, 1); SegmentLCD_Symbol(LCD_SYMBOL_PAD1, 1); } else { for (i = 100; i > 0; i--) { SegmentLCD_Number(i); EM2Sleep(10); } SegmentLCD_NumberOff(); SegmentLCD_Symbol(LCD_SYMBOL_GECKO, 1); SegmentLCD_Symbol(LCD_SYMBOL_EFM32, 1); SegmentLCD_Write(" TINY "); EM2Sleep(500); SegmentLCD_Write(" Gecko "); EM2Sleep(1000); SegmentLCD_AllOn(); EM2Sleep(1000); SegmentLCD_AllOff(); } if (emMode != DEMO_MODE_NONE) { SegmentLCD_Symbol(LCD_SYMBOL_PAD0, 1); SegmentLCD_Symbol(LCD_SYMBOL_PAD1, 1); } else { SegmentLCD_Write("OOOOOOO"); EM2Sleep(62); SegmentLCD_Write("XXXXXXX"); EM2Sleep(62); SegmentLCD_Write("+++++++"); EM2Sleep(62); SegmentLCD_Write("@@@@@@@"); EM2Sleep(62); SegmentLCD_Write("ENERGY "); EM2Sleep(250); SegmentLCD_Write("@@ERGY "); EM2Sleep(62); SegmentLCD_Write(" @@RGY "); EM2Sleep(62); SegmentLCD_Write(" M@@GY "); EM2Sleep(62); SegmentLCD_Write(" MI@@Y "); EM2Sleep(62); SegmentLCD_Write(" MIC@@ "); EM2Sleep(62); SegmentLCD_Write(" MICR@@"); EM2Sleep(62); SegmentLCD_Write(" MICRO@"); EM2Sleep(62); SegmentLCD_Write(" MICRO "); EM2Sleep(250); SegmentLCD_Write("-EFM32-"); EM2Sleep(250); /* Various eye candy */ SegmentLCD_AllOff(); if (emMode != DEMO_MODE_NONE) { SegmentLCD_Symbol(LCD_SYMBOL_PAD0, 1); SegmentLCD_Symbol(LCD_SYMBOL_PAD1, 1); } for (i = 0; i < 8; i++) { SegmentLCD_Number(numberOfIterations + i); SegmentLCD_ARing(i, 1); EM2Sleep(20); } for (i = 0; i < 8; i++) { SegmentLCD_Number(numberOfIterations + i); SegmentLCD_ARing(i, 0); EM2Sleep(100); } for (i = 0; i < 5; i++) { SegmentLCD_Number(numberOfIterations + i); SegmentLCD_Battery(i); SegmentLCD_EnergyMode(i, 1); EM2Sleep(100); SegmentLCD_EnergyMode(i, 0); EM2Sleep(100); } SegmentLCD_Symbol(LCD_SYMBOL_ANT, 1); for (i = 0; i < 4; i++) { SegmentLCD_EnergyMode(i, 1); EM2Sleep(100); } SegmentLCD_Symbol(LCD_SYMBOL_ANT, 0); SegmentLCD_Battery(0); } /* Energy Modes */ SegmentLCD_NumberOff(); SegmentLCD_Symbol(LCD_SYMBOL_GECKO, 1); SegmentLCD_Symbol(LCD_SYMBOL_EFM32, 1); if ((emMode != DEMO_MODE_EM3) && (emMode != DEMO_MODE_EM4)) { ScrollText("Energy Mode demo, Press PB0 for EM3 or PB1 for EM4 "); } SegmentLCD_Write(" EM0 "); SegmentLCD_Number(0); SegmentLCD_EnergyMode(0, 1); SegmentLCD_EnergyMode(1, 1); SegmentLCD_EnergyMode(2, 1); SegmentLCD_EnergyMode(3, 1); SegmentLCD_EnergyMode(4, 1); RTCDRV_Delay(4000, false); SegmentLCD_Write(" EM1 "); SegmentLCD_Number(1111); SegmentLCD_EnergyMode(0, 0); EM1Sleep(4000); SegmentLCD_Write(" EM2 "); SegmentLCD_Number(2222); SegmentLCD_EnergyMode(1, 0); EM2Sleep(4000); /* Check if somebody has pressed one of the buttons */ if (emMode == DEMO_MODE_EM3) { ScrollText("Going down to EM3, press PB0 to wake up "); SegmentLCD_Write(" EM3 "); SegmentLCD_Number(3333); RTCDRV_Delay(1000, false); /* Wake up on GPIO interrupt */ EM3Sleep(); SegmentLCD_Number(0000); SegmentLCD_Write("--EM0--"); RTCDRV_Delay(500, false); SegmentLCD_Symbol(LCD_SYMBOL_PAD0, 0); SegmentLCD_Symbol(LCD_SYMBOL_PAD1, 0); emMode = DEMO_MODE_NONE; } /* Check if somebody's joystick down */ if (emMode == DEMO_MODE_EM4) { ScrollText("Going down to EM4, press reset to restart "); SegmentLCD_Write(" EM4 "); SegmentLCD_Number(4444); RTCDRV_Delay(1000, false); /* Wake up on reset */ EM4Sleep(); } SegmentLCD_EnergyMode(0, 0); SegmentLCD_EnergyMode(1, 0); SegmentLCD_EnergyMode(2, 0); SegmentLCD_EnergyMode(3, 0); SegmentLCD_EnergyMode(4, 0); /* Scrolltext */ ScrollText(stext); /* Blink and animation featurs */ BlinkTest(); numberOfIterations++; } }