Example #1
0
//*****************************************************************************
//
// 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();


}
Example #2
0
//*****************************************************************************
//
//! 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
Example #3
0
/**************************
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)
	{
	}
}
Example #4
0
//*****************************************************************************
//
// 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.
    //
}