//***************************************************************************** // // Uses the fColorWheelPos variable to update the color mix shown on the RGB // // This function is called when system has decided it is time to enter // Hibernate. This will prepare the hibernate peripheral, save the system // state and then enter hibernate mode. // //***************************************************************************** void AppHibernateEnter(void) { // // Alert UART command line users that we are going to hibernate // UARTprintf("Entering Hibernate...\n"); // // Prepare Hibernation Module // HibernateGPIORetentionEnable(); HibernateRTCSet(0); HibernateRTCEnable(); HibernateRTCMatchSet(0, 5); HibernateWakeSet(HIBERNATE_WAKE_PIN | HIBERNATE_WAKE_RTC); // // Store state information to battery backed memory // since sizeof returns number of bytes we convert to words and force // a rounding up to next whole word. // HibernateDataSet((uint32_t*)&g_sAppState, sizeof(tAppState)/4+1); // // Disable the LED for 100 milliseconds to let user know we are // ready for hibernate and will hibernate on relase of buttons // RGBDisable(); SysCtlDelay(SysCtlClockGet()/3/10); RGBEnable(); // // Wait for wake button to be released prior to going into hibernate // while(g_sAppState.ui32Buttons & RIGHT_BUTTON) { // //Delay for about 300 clock ticks to allow time for interrupts to //sense that button is released // SysCtlDelay(100); } // // Disable the LED for power savings and go to hibernate mode // RGBDisable(); HibernateRequest(); }
//***************************************************************************** // //! This is the hibernate module handler. //! When the RTC timer expires, an interrupt is generated and the the GPS //! data is parsed and logged. //! //! If the Wake button is pressed, low power mode is disabled. //! A reset/power cycle is required to re-enable low power mode after Wake has //! been pressed. // //***************************************************************************** void lowPowerMode(int delaySeconds) { uint32_t ui32Status; // // Set the RTC to 0 or an initial value. The RTC can be set once when the // system is initialized after the cold startup and then left to run. Or // it can be initialized before every hibernate. // HibernateRTCSet(0); // // Set the match 0 register for 30 seconds from now. // HibernateRTCMatchSet(0, HibernateRTCGet() + delaySeconds); // // Clear any pending status. // ui32Status = HibernateIntStatus(0); HibernateIntClear(ui32Status); // // Save the program state information. The state information is stored in // the pui32NVData[] array. It is not necessary to save the full 16 words // of data, only as much as is actually needed by the program. // HibernateDataSet(&lowPowerOn, 1); // // Configure to wake on RTC match or when wake button is pressed. // HibernateWakeSet(HIBERNATE_WAKE_RTC | HIBERNATE_WAKE_PIN); // // Request hibernation. The following call may return because it takes a // finite amount of time for power to be removed. // HibernateRequest(); // // Spin here to wait for the power to be removed. // for(;;) { } } // End function lowPowerMode
/************************** YOSEMIT XOLALPA ROSALES PROF. VENKI CPE403 TIVAC-LAB06 **************************/ int main(void) { SysCtlClockSet(SYSCTL_SYSDIV_5|SYSCTL_USE_PLL|SYSCTL_XTAL_16MHZ|SYSCTL_OSC_MAIN); SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOF); GPIOPinTypeGPIOOutput(GPIO_PORTF_BASE, GPIO_PIN_1|GPIO_PIN_2|GPIO_PIN_3); GPIOPinWrite(GPIO_PORTF_BASE,GPIO_PIN_1|GPIO_PIN_2|GPIO_PIN_3, 0x08); SysCtlPeripheralEnable(SYSCTL_PERIPH_HIBERNATE); HibernateEnableExpClk(SysCtlClockGet()); HibernateGPIORetentionEnable(); SysCtlDelay(64000000); HibernateRTCSet(0); HibernateRTCEnable(); HibernateRTCMatchSet(0,5); HibernateWakeSet(HIBERNATE_WAKE_PIN | HIBERNATE_WAKE_RTC); GPIOPinWrite(GPIO_PORTF_BASE,GPIO_PIN_3, 0x00); HibernateRequest(); while(1) { } }
//***************************************************************************** // // Run the hibernate example. Use a loop to put the microcontroller into // hibernate mode, and to wake up based on time. Also allow the user to cause // it to hibernate and/or wake up based on button presses. // //***************************************************************************** int main(void) { uint32_t ui32Idx; uint32_t ui32Status = 0; uint32_t ui32HibernateCount = 0; tContext sContext; tRectangle sRect; // // Enable lazy stacking for interrupt handlers. This allows floating-point // instructions to be used within interrupt handlers, but at the expense of // extra stack usage. // ROM_FPULazyStackingEnable(); // // Set the clocking to run directly from the crystal. // ROM_SysCtlClockSet(SYSCTL_SYSDIV_1 | SYSCTL_USE_OSC | SYSCTL_OSC_MAIN | SYSCTL_XTAL_16MHZ); // // Initialize the UART. // ConfigureUART(); // // Initialize the OLED display // CFAL96x64x16Init(); // // Initialize the graphics context. // GrContextInit(&sContext, &g_sCFAL96x64x16); // // Fill the top 24 rows of the screen with blue to create the banner. // sRect.i16XMin = 0; sRect.i16YMin = 0; sRect.i16XMax = GrContextDpyWidthGet(&sContext) - 1; sRect.i16YMax = 9; GrContextForegroundSet(&sContext, ClrDarkBlue); GrRectFill(&sContext, &sRect); // // Change foreground for white text. // GrContextForegroundSet(&sContext, ClrWhite); // // Put the application name in the middle of the banner. // GrContextFontSet(&sContext, g_psFontFixed6x8); GrStringDrawCentered(&sContext, "hibernate", -1, GrContextDpyWidthGet(&sContext) / 2, 4, 0); // // Initialize the buttons driver // ButtonsInit(); // // Set up systick to generate interrupts at 100 Hz. // ROM_SysTickPeriodSet(ROM_SysCtlClockGet() / 100); ROM_SysTickIntEnable(); ROM_SysTickEnable(); // // Enable the Hibernation module. // ROM_SysCtlPeripheralEnable(SYSCTL_PERIPH_HIBERNATE); // // Print wake cause message on display. // GrStringDrawCentered(&sContext, "Wake due to:", -1, GrContextDpyWidthGet(&sContext) / 2, Row(2) + 4, true); // // Check to see if Hibernation module is already active, which could mean // that the processor is waking from a hibernation. // if(HibernateIsActive()) { // // Read the status bits to see what caused the wake. // ui32Status = HibernateIntStatus(0); HibernateIntClear(ui32Status); // // Wake was due to the push button. // if(ui32Status & HIBERNATE_INT_PIN_WAKE) { GrStringDrawCentered(&sContext, "BUTTON", -1, GrContextDpyWidthGet(&sContext) / 2, Row(3) + 4, true); } // // Wake was due to RTC match // else if(ui32Status & HIBERNATE_INT_RTC_MATCH_0) { GrStringDrawCentered(&sContext, "TIMEOUT", -1, GrContextDpyWidthGet(&sContext) / 2, Row(3) + 4, true); } // // Wake is due to neither button nor RTC, so it must have been a hard // reset. // else { GrStringDrawCentered(&sContext, "RESET", -1, GrContextDpyWidthGet(&sContext) / 2, Row(3) + 4, true); } // // If the wake is due to button or RTC, then read the first location // from the battery backed memory, as the hibernation count. // if(ui32Status & (HIBERNATE_INT_PIN_WAKE | HIBERNATE_INT_RTC_MATCH_0)) { HibernateDataGet(&ui32HibernateCount, 1); } } // // Enable the Hibernation module. This should always be called, even if // the module was already enabled, because this function also initializes // some timing parameters. // HibernateEnableExpClk(ROM_SysCtlClockGet()); // // If the wake was not due to button or RTC match, then it was a reset. // if(!(ui32Status & (HIBERNATE_INT_PIN_WAKE | HIBERNATE_INT_RTC_MATCH_0))) { // // Configure the module clock source. // HibernateClockConfig(HIBERNATE_OSC_LOWDRIVE); // // Finish the wake cause message. // GrStringDrawCentered(&sContext, "RESET", -1, GrContextDpyWidthGet(&sContext) / 2, Row(3) + 4, true); // // Wait a couple of seconds in case we need to break in with the // debugger. // SysTickWait(3 * 100); // // Allow time for the crystal to power up. This line is separated from // the above to make it clear this is still needed, even if the above // delay is removed. // SysTickWait(15); } // // Print the count of times that hibernate has occurred. // usnprintf(g_pcBuf, sizeof(g_pcBuf), "Hib count=%4u", ui32HibernateCount); GrStringDrawCentered(&sContext, g_pcBuf, -1, GrContextDpyWidthGet(&sContext) / 2, Row(1) + 4, true); // // Print messages on the screen about hibernation. // GrStringDrawCentered(&sContext, "Select to Hib", -1, GrContextDpyWidthGet(&sContext) / 2, Row(4) + 4, true); GrStringDrawCentered(&sContext, "Wake in 5 s,", -1, GrContextDpyWidthGet(&sContext) / 2, Row(5) + 4, true); GrStringDrawCentered(&sContext, "or press Select", -1, GrContextDpyWidthGet(&sContext) / 2, Row(6) + 4, true); GrStringDrawCentered(&sContext, "for immed. wake.", -1, GrContextDpyWidthGet(&sContext) / 2, Row(7) + 4, true); // // Clear the button pressed flag, in case it was held down at the // beginning. // bSelectPressed = 0; // // Wait for user to press the button. // while(!bSelectPressed) { // // Wait a bit before looping again. // SysTickWait(10); } // // Tell user to release the button. // GrStringDrawCentered(&sContext, " ", -1, GrContextDpyWidthGet(&sContext) / 2, Row(4) + 4, true); GrStringDrawCentered(&sContext, " ", -1, GrContextDpyWidthGet(&sContext) / 2, Row(5) + 4, true); GrStringDrawCentered(&sContext, " ", -1, GrContextDpyWidthGet(&sContext) / 2, Row(6) + 4, true); GrStringDrawCentered(&sContext, " ", -1, GrContextDpyWidthGet(&sContext) / 2, Row(7) + 4, true); GrStringDrawCentered(&sContext, "Release the", -1, GrContextDpyWidthGet(&sContext) / 2, Row(5) + 4, true); GrStringDrawCentered(&sContext, "button.", -1, GrContextDpyWidthGet(&sContext) / 2, Row(6) + 4, true); GrStringDrawCentered(&sContext, " ", -1, GrContextDpyWidthGet(&sContext) / 2, Row(7) + 4, true); // // Wait for user to release the button. // while(bSelectPressed) { } // // If hibernation count is very large, it may be that there was already // a value in the hibernate memory, so reset the count. // ui32HibernateCount = (ui32HibernateCount > 10000) ? 0 : ui32HibernateCount; // // Increment the hibernation count, and store it in the battery backed // memory. // ui32HibernateCount++; HibernateDataSet(&ui32HibernateCount, 1); // // Clear and enable the RTC and set the match registers to 5 seconds in the // future. Set both to same, though they could be set differently, the // first to match will cause a wake. // HibernateRTCSet(0); HibernateRTCEnable(); HibernateRTCMatchSet(0, 5); // // Set wake condition on pin or RTC match. Board will wake when 5 seconds // elapses, or when the button is pressed. // HibernateWakeSet(HIBERNATE_WAKE_PIN | HIBERNATE_WAKE_RTC); // // Request hibernation. // HibernateRequest(); // // Give it time to activate, it should never get past this wait. // SysTickWait(100); // // Should not have got here, something is wrong. Print an error message to // the user. // sRect.i16XMin = 0; sRect.i16XMax = 95; sRect.i16YMin = 0; sRect.i16YMax = 63; GrContextForegroundSet(&sContext, ClrBlack); GrRectFill(&sContext, &sRect); GrContextForegroundSet(&sContext, ClrWhite); ui32Idx = 0; while(g_pcErrorText[ui32Idx]) { GrStringDraw(&sContext, g_pcErrorText[ui32Idx], -1, Col(0), Row(ui32Idx), true); ui32Idx++; } // // Wait for the user to press the button, then restart the app. // bSelectPressed = 0; while(!bSelectPressed) { } // // Reset the processor. // ROM_SysCtlReset(); // // Finished. // while(1) { } }
//***************************************************************************** // // This function is called to start an acquisition running. It determines // which channels are to be logged, enables the ADC sequencers, and computes // the first RTC match value. This will start the acquisition running. // //***************************************************************************** void AcquireStart(tConfigState *psConfig) { uint32_t ui32Idx, pui32RTC[2], ui32SelectedMask; // // Check the parameters // ASSERT(psConfig); if(!psConfig) { return; } // // Update the config state pointer, save the selected item mask // g_psConfigState = psConfig; ui32SelectedMask = psConfig->ui16SelectedMask; // // Get the logging period from the logger configuration. Split the // period into seconds and subseconds pieces and save for later use in // generating RTC match values. // g_pui32MatchPeriod[0] = psConfig->ui32Period >> 8; g_pui32MatchPeriod[1] = (psConfig->ui32Period & 0xFF) << 8; // // Determine how many channels are to be logged // ui32Idx = ui32SelectedMask; g_ui32NumItems = 0; while(ui32Idx) { if(ui32Idx & 1) { g_ui32NumItems++; } ui32Idx >>= 1; } // // Initialize the strip chart manager for a new run. Don't bother with // the strip chart if we are using viewer mode, or sleep-logging. // if((psConfig->ui8Storage != CONFIG_STORAGE_VIEWER) && !psConfig->ui32SleepLogging) { StripChartMgrInit(); StripChartMgrConfigure(ui32SelectedMask); } // // Configure USB for memory stick if USB storage is chosen // if(psConfig->ui8Storage == CONFIG_STORAGE_USB) { USBStickOpenLogFile(0); } else if(psConfig->ui8Storage == CONFIG_STORAGE_FLASH) { // // Flash storage is to be used, prepare the flash storage module. // If already sleep-logging, then pass in the saved flash address // so it does not need to be searched. // if(psConfig->ui32SleepLogging) { FlashStoreOpenLogFile(psConfig->ui32FlashStore); } else { // // Otherwise not sleep logging, so just initialize the flash store, // this will cause it to search for the starting storage address. // FlashStoreOpenLogFile(0); } } // // Enable the ADC sequencers // MAP_ADCSequenceEnable(ADC0_BASE, 0); MAP_ADCSequenceEnable(ADC1_BASE, 0); // // Flush the ADC sequencers to be sure there is no lingering data. // MAP_ADCSequenceDataGet(ADC0_BASE, 0, g_pui32ADCData); MAP_ADCSequenceDataGet(ADC1_BASE, 0, g_pui32ADCData); // // Enable ADC interrupts // MAP_ADCIntClear(ADC0_BASE, 0); MAP_ADCIntClear(ADC1_BASE, 0); MAP_ADCIntEnable(ADC0_BASE, 0); MAP_IntEnable(INT_ADC0SS0); // // If we are not already sleep-logging, then initialize the RTC match. // If we are sleep logging then this does not need to be set up. // if(!psConfig->ui32SleepLogging) { // // Get the current RTC value // do { pui32RTC[0] = HibernateRTCGet(); pui32RTC[1] = HibernateRTCSSGet(); } while(pui32RTC[0] != HibernateRTCGet()); // // Set an initial next match value. Start with the subseconds always // 0 so the first match value will always be an even multiple of the // subsecond match. Add 2 seconds to the current RTC just to be clear // of an imminent rollover. This means that the first match will occur // between 1 and 2 seconds from now. // g_pui32NextMatch[0] = pui32RTC[0] + 2; g_pui32NextMatch[1] = 0; // // Now set the match value // HibernateRTCMatchSet(0, g_pui32NextMatch[0]); HibernateRTCSSMatchSet(0, g_pui32NextMatch[1]); } // // If we are configured to sleep, but not sleeping yet, then enter sleep // logging mode if allowed. // if(psConfig->bSleep && !psConfig->ui32SleepLogging) { // // Allow sleep logging if storing to flash at a period of 1 second // or greater. // if((psConfig->ui8Storage == CONFIG_STORAGE_FLASH) && (psConfig->ui32Period >= 0x100)) { psConfig->ui32SleepLogging = 1; } } // // Enable the RTC interrupts from the hibernate module // HibernateIntClear(HibernateIntStatus(0)); HibernateIntEnable(HIBERNATE_INT_RTC_MATCH_0 | HIBERNATE_INT_PIN_WAKE); MAP_IntEnable(INT_HIBERNATE); // // Logging data should now start running // }
//***************************************************************************** // // This is the handler for the RTC interrupt from the hibernate peripheral. // It occurs on RTC match. This handler will initiate an ADC acquisition, // which will run all of the ADC sequencers. Then it computes the next // match value and sets it in the RTC. // //***************************************************************************** void RTCHandler(void) { uint32_t ui32Status, ui32Seconds; // // Increment RTC interrupt counter // g_pui32RTCInts++; // // Clear the RTC interrupts (this can be slow for hib module) // ui32Status = HibernateIntStatus(1); HibernateIntClear(ui32Status); // // Read and save the current value of the seconds counter. // ui32Seconds = HibernateRTCGet(); // // If we are sleep logging, then there will be no remembered value for // the next match value, which is also used as the time stamp when // data is collected. In this case we will just use the current // RTC seconds. This is safe because if sleep-logging is used, it // is only with periods of whole seconds, 1 second or longer. // if(g_psConfigState->ui32SleepLogging) { g_pui32NextMatch[0] = ui32Seconds; g_pui32NextMatch[1] = 0; } // // If we are logging data to PC and using a period greater than one // second, then use special handling. For PC logging, if no data is // collected, then we must send a keep-alive packet once per second. // if((g_psConfigState->ui8Storage == CONFIG_STORAGE_HOSTPC) && (g_pui32MatchPeriod[0] > 1)) { // // If the current seconds count is less than the match value, that // means we got the interrupt due to one-second keep alive for the // host PC. // if(ui32Seconds < g_pui32NextMatch[0]) { // // Set the next match for one second ahead (next keep-alive) // HibernateRTCMatchSet(0, ui32Seconds + 1); // // Set flag to indicate that a keep alive packet is needed // g_bNeedKeepAlive = true; // // Nothing else to do except wait for next keep alive or match // return; } // // Else, this is a real match so proceed to below to do a normal // acquisition. // } // // Kick off the next ADC acquisition. When these are done they will // cause an ADC interrupt. // MAP_ADCProcessorTrigger(ADC1_BASE, 0); MAP_ADCProcessorTrigger(ADC0_BASE, 0); // // Set the next RTC match. Add the match period to the previous match // value. We are making an assumption here that there is enough time from // when the match interrupt occurred, to this point in the code, that we // are still setting the match time in the future. If the period is too // long, then we could miss a match and never get another RTC interrupt. // g_pui32NextMatch[0] += g_pui32MatchPeriod[0]; g_pui32NextMatch[1] += g_pui32MatchPeriod[1]; if(g_pui32NextMatch[1] > 32767) { // // Handle subseconds rollover // g_pui32NextMatch[1] &= 32767; g_pui32NextMatch[0]++; } // // If logging to host PC at greater than 1 second period, then set the // next RTC wakeup for 1 second from now. This will cause a keep alive // packet to be sent to the PC // if((g_psConfigState->ui8Storage == CONFIG_STORAGE_HOSTPC) && (g_pui32MatchPeriod[0] > 1)) { HibernateRTCMatchSet(0, ui32Seconds + 1); } else { // // Otherwise this is a normal match and the next match should also be a // normal match, so set the next wakeup to the calculated match time. // HibernateRTCMatchSet(0, g_pui32NextMatch[0]); HibernateRTCSSMatchSet(0, g_pui32NextMatch[1]); } // // Toggle the LED on the board so the user can see that the acquisition // is running. // MAP_GPIOPinWrite(GPIO_PORTG_BASE, GPIO_PIN_2, ~MAP_GPIOPinRead(GPIO_PORTG_BASE, GPIO_PIN_2)); // // Now exit the int handler. The ADC will trigger an interrupt when // it is finished, and the RTC is set up for the next match. // }