This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

TM4C123GH6PM: Why can't my TM4C123 lanuchpad get into hibernation?

Part Number: TM4C123GH6PM


Hi all:

One of my ongoing projects requires hibernation, and then wake up through reset pin.  Because the MCU used is TM4C123, I first perform functional verification on the TM4C123 red lanuchpad.

And refer to the reference routine of hibernation in dk-tm4c123g in tivaware. But my program couldn't hibernate. I used LED flicker to indicate if the program was hibernating. The LED kept flickering after the program

was running, so it didn't go into hibernation. My code is as follows. What tips can help me solve this problem? Thank you very much.

void
SysTickWait(uint32_t ui32Ticks)
{
    ui32Ticks += g_ui32SysTickCount;
    while(g_ui32SysTickCount <= ui32Ticks)
    {
    }
}
//*****************************************************************************
//
//! \addtogroup example_list
//! <h1>Blinky (blinky)</h1>
//!
//! A very simple example that blinks the on-board LED using direct register
//! access.
//
//*****************************************************************************
void SysTickHandler(void)
{
    
    //
    // Increment the tick counter.
    //
    g_ui32SysTickCount++;

}

int
main(void)
{
    volatile uint32_t ui32Loop, k;
    
    uint32_t ui32Status = 0;
    uint32_t ui32HibernateCount = 0;
    
    //
    // 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);


    //
    // Enable the GPIO port that is used for the on-board LED.
    //
    SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOF);

    //
    // Check if the peripheral access is enabled.
    //
    while(!SysCtlPeripheralReady(SYSCTL_PERIPH_GPIOF))
    {
    }

    //
    // Enable the GPIO pin for the LED (PF3).  Set the direction as output, and
    // enable the GPIO pin for digital function.
    //
    GPIOPinTypeGPIOOutput(GPIO_PORTF_BASE, GPIO_PIN_3);
    
    
    //
    // 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);

    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)
        {
           
        }

        //
        // Wake was due to RTC match
        //
        else if(ui32Status & HIBERNATE_INT_RTC_MATCH_0)
        {
           
        }

        //
        // Wake is due to neither button nor RTC, so it must have been a hard
        // reset.
        //
        else
        {
            
        }

        
    }

    HibernateEnableExpClk(ROM_SysCtlClockGet());
    
    if(!(ui32Status & (HIBERNATE_INT_PIN_WAKE | HIBERNATE_INT_RTC_MATCH_0)))
    {
        //
        // Configure the module clock source.
        //
        HibernateClockConfig(HIBERNATE_OSC_LOWDRIVE);

        //
        // 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);
    }
    
    ui32HibernateCount = (ui32HibernateCount > 10000) ? 0 : ui32HibernateCount;
    ui32HibernateCount++;
    HibernateDataSet(&ui32HibernateCount, 1);

    //
    // Loop forever.
    //
    while(1)
    {
      // LED flash loop 10 times
      for(k = 0; k < 10; k++)
      {
        //
        // Turn on the LED.
        //
        GPIOPinWrite(GPIO_PORTF_BASE, GPIO_PIN_3, GPIO_PIN_3);

        //
        // Delay for a bit.
        //
        for(ui32Loop = 0; ui32Loop < 200000; ui32Loop++)
        {
        }

        //
        // Turn off the LED.
        //
        GPIOPinWrite(GPIO_PORTF_BASE, GPIO_PIN_3, 0x0);

        //
        // Delay for a bit.
        //
        for(ui32Loop = 0; ui32Loop < 200000; ui32Loop++)
        {
        }
      }
        
        // start hibernate
        HibernateWakeSet(HIBERNATE_WAKE_RESET);

        HibernateRequest();

        SysTickWait(100);
    }
}

  • Hi,

     Several for things for you to try:

    •   See below datasheet. It looks like the HibernateRequest() will not initiate unless you have either a WAKE pin or RTC wakeup configured. Even though you want to use the reset pin to wake up the device, I think you should still enable wake from either RTC or WAKE pin. So I will suggest change to something like below. 

      HibernateWakeSet(HIBERNATE_WAKE_PIN | HIBERNATE_WAKE_RESET | HIBERNATE_WAKE_RTC);

    7.3.9 Initiating Hibernate
    Hibernate mode is initiated when the HIBREQ bit of the HIBCTL register is set. If a wake-up condition
    has not been configured using the PINWEN or RTCWEN bits in the HIBCTL register, the hibernation
    request is ignored. If a Flash memory write operation is in progress when the HIBREQ bit is set, an
    interlock feature holds off the transition into Hibernate mode until the write has completed. In addition,
    if the battery voltage is below the threshold voltage defined by the VBATSEL field in the HIBCTL
    register, the hibernation request is ignored.

    • Did you try the example as is on the DK board? Did it work?
    • Can you add your pin toggling into the TivaWare example and see if the LED will stop?

  • Hi Charles:

    Thanks for your reply.

    I tried your advice. Use "HibernateWakeSet(HIBERNATE_WAKE_PIN | HIBERNATE_WAKE_RESET | HIBERNATE_WAKE_RTC);" instead

    "HibernateWakeSet(HIBERNATE_WAKE_RESET); " , And at the same time enabled RTC .

    "HibernateRTCSet(0); HibernateRTCEnable();HibernateRTCMatchSet(0, 10); "

    But still no effect. Later, I found it necessary to add this function "HibernateGPIORetentionEnable();", To successfully enter hibernation.

    But I don't know why.

    I have no DK board, I only have red EK board. So I can only run the example of DK hibernation on the EK board.

    I add pin toggling into the code and if the LED will stop.(PF3).

    So I am still confused.
  • Hi Alex,
    Glad that you are making good progress. I'm not too sure why HibernateGPIORetentionEnable is needed. How are you connecting the board to the external components? It is possible that without the HibernateGPIORetentionEnable, the board cannot maintain the GPIO pin states. Perhaps one of the floating pins triggers the device to wake up immediately.