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.

Tiva Hibernation module hangs on _HibernateWriteComplete()

Other Parts Discussed in Thread: EK-TM4C1294XL

System Details:

  • OS -  Microsoft Windows 7 Professional Version 6.1.7601 Service Pack 1 Build 7601

  • Processor - Intel(R) Core(TM) i7-3770 CPU @ 3.40GHz, 3401 Mhz, 4 Core(s), 8 Logical Processor(s)

  • BIOS Version/Date - Dell Inc. A13, 3/27/2013

CCS Details:

  • Version: 6.1.1.00022
  • TivaWare_C_Series-2.1.0.12573
  • Launchpad: EK-TM4C1294XL

Hello all,

I am trying to get the hibernation module to run in a simple way. I have a timer that is consistently fed and when a certain event occurs, the timer is no longer fed and expires. Once expired I need the device to enter hibernation mode and wake only when the 'Wake' pin is asserted. I don't need any internal clocks running, and the device is powered by VDD. I have an initialization function that I call in main() and the 'enter_hibernation' function is called when the previously mentioned timer expires. Here is what I have:

void sleepInit(void)
{

    // Enable the hibernate module.
    SysCtlPeripheralEnable(SYSCTL_PERIPH_HIBERNATE);

	// Set the VDD3ON bit to allert that the chip is powered by VDD
	HibernateGPIORetentionEnable();

    // Configure Hibernate module clock.
    HibernateEnableExpClk(ui32SysClock);

    HibernateRTCDisable(); 	// We are not using the RTC feature in the hibernation module

    // Configure the module clock source.
    HibernateClockConfig(HIBERNATE_OSC_DISABLE);	// No oscilator used in the hibernate madule




    // Configure GPIO used as Hibernate wake source
   // GPIOPadConfigSet(GPIO_PORTK_BASE, GPIO_PIN_7, GPIO_STRENGTH_2MA,
                    // (GPIO_PIN_TYPE_WAKE_LOW | GPIO_PIN_TYPE_STD_WPU));

}


void Sys_sleep(void)
{

	uint32_t ui32Status;


	// Perform system checks before sleep

	    // Read and clear any status bits that might have been set since
	    // last clearing them.
	   	ui32Status = HibernateIntStatus(0);
	    HibernateIntClear(ui32Status);

	    // Configure Hibernate wake sources.
	    HibernateWakeSet(HIBERNATE_WAKE_PIN);	// Wake on WAKE-PIN assertion

		// Request Hibernation.
		HibernateRequest();

		// Wait for a while for hibernate to activate.  It should never get
		// past this point.
		SysCtlDelay(100);

		// If it ever gets here, store the text, that informs the user on
		// what to do, into the respective widget buffers.
		printf("The controller did not enter hibernate.  \n");

		// Wait here.
		while(1)
		{
		}
}

The problem is with _HibernateWriteComplete() which is called from within a number of the above functions and shown below:

//*****************************************************************************
//
//! \internal
//!
//! Polls until the write complete (WRC) bit in the hibernate control register
//! is set.
//!
//! \param None.
//!
//! The Hibernation module provides an indication when any write is completed.
//! This mechanism is used to pace writes to the module.  This function merely
//! polls this bit and returns as soon as it is set.  At this point, it is safe
//! to perform another write to the module.
//!
//! \return None.
//
//*****************************************************************************
static void
_HibernateWriteComplete(void)
{
    //
    // Spin until the write complete bit is set.
    //
    while(!(HWREG(HIB_CTL) & HIB_CTL_WRC))
    {
    }
}

This function hangs on the while loop at various times. Sometimes it will hang when called from within the initialization function, and sometimes it will hang when it is called form the Sys_sleep function.

I cannot figure out why it is hanging. Please let me know if there is anything you find that would help me.

Thank you,

Mitchell

  • Hello Mitchell,

    Did you already refer the "./examples/boards/ek-tm4c1294xl/hibernate"? What are you different from this example?

    Thanks,
    Sai
  • Yes I have looked at that example. Most of my code is based on what that example does. However, there are fundamental differences in the operation of the hibernation module (particularly wake-up sources) that make my code different. As far as I can tell, all of the critical function calls are made in my code. When I run the example project on the launchpad, everything works fine. But my code is still not working.

  • Hello Mitchell,

    When enabling any bit in the Hibernate module, the HibernateEnableExpClk must be called before any configuration. In your code I see that the HibernateGPIORetentionEnable is called before the clock is enabled.

    // Enable the hibernate module.
    SysCtlPeripheralEnable(SYSCTL_PERIPH_HIBERNATE);

    // Set the VDD3ON bit to allert that the chip is powered by VDD
    HibernateGPIORetentionEnable();

    // Configure Hibernate module clock.
    HibernateEnableExpClk(ui32SysClock);

    Also a critical information on Hibernate module, is that one RTC is enabled or pin wakeup is enabled, the hibernate is not affected by the Pin or System Reset. So before running any experiments, make sure all of flash is erased and the board has been power cycled.

    Regards
    Amit
  • Why does the board need to be power cycled for the hibernation module to work?

  • Hello Mitchell,

    The Hibernate module will not respond to a system reset once a valid wakeup source or RTC is enabled. The step mentioned above, will ensure that Hibernate if configured, after flash erased and power cycle, will not be configured again, so that it comes back to vanilla state.

    Regards
    Amit
  • I have changed my code to more closely resemble the code from the example project. Previously, whenever I would power cycle the board before testing, the program would run through the hibernate initialization function just fine, but would always hang on the _HibernateWriteComplete() function when the "go into hibernation" function is called.

    Now that I have changed the code, despite power cycling the board, the program hangs on the very first call to _HibernateWriteComplete()
  • Hello Mitchell,

    Can you please share the CCS project, so that I can reproduce the issue on my side?

    Regards
    Amit
  • Amit,

    I would like to share the project with you, but I have concerns about intellectual property issues. Is there a way to share it with you privately?

  • Hello Mitchell,

    You can make a small project separate than your existing project and send it to me via PM.

    Regards
    Amit
  • Amit,

    It appears we found the core issue on this.  There does need to be an extra line in the initialization of the hibernation module.  We don't have an external 32.768kHz clock on the board so the init had to look like this to prevent the lockup.

    SysCtlPeripheralEnable(SYSCTL_PERIPH_HIBERNATE); // Enable the hibernate module.
    SysCtlDelay(10); // delay for peripheral to enable

    HibernateClockConfig(HIBERNATE_OSC_LFIOSC); // Use external crystal, high drive

    HibernateEnableExpClk(ui32SysClock); // Configure Hibernate module clock

    We need to specify using the internal OSC before enabling the clock, or it stuck waiting for the state machine to run in the hibernation module it appears.

    Regards,

    Doug

  • Hello Doug,

    I don't think I saw a project from Mitchell. Please do make sure that it fails on a EK-TM4C1294XL
    Regards
    Amit
  • Amit,

    So this has progressed further and I'm hitting a block on the WAKE pin to wake up the processor. Here is my init code:

    SysCtlPeripheralEnable(SYSCTL_PERIPH_HIBERNATE); // Enable the hibernate module.
    SysCtlDelay(10); // delay for peripheral to enable
    HibernateClockConfig(HIBERNATE_OSC_HIGHDRIVE); // Use internal crystal
    // HibernateClockConfig(HIBERNATE_OSC_LFIOSC); // Use internal crystal
    HibernateEnableExpClk(ui32SysClock); // Configure Hibernate module clock

    //
    // Check to see if Hibernation module is already active, which could mean
    // that the processor is waking from a hibernation.
    //

    if(HibernateIsActive())
    {
    UARTprintf("Hibernate Peripheral is Enbled\n");
    //
    // Read the status bits to see what caused the wake. Clear the wake
    // source so that the device can be put into hibernation again.
    //
    ui32Status = HibernateIntStatus(0);
    HibernateIntClear(ui32Status);

    //
    // Wake was due to the External Wake pin.
    //
    if(ui32Status & HIBERNATE_INT_PIN_WAKE)
    {
    UARTprintf("SYSTEM WAKE DUE TO WAKE PIN\n"); //Great, now what do we do???
    }
    if(ui32Status & HIBERNATE_INT_RESET_WAKE)
    {
    UARTprintf("SYSTEM WAKE DUE TO RESET\n"); //Great, now what do we do???
    }
    if(ui32Status & HIBERNATE_INT_VDDFAIL)
    {
    UARTprintf("SYSTEM WAKE DUE TO VDD FAIL\n"); //Great, now what do we do???
    }
    }


    And here is the code that gets called to enter hiberation.

    //
    // Read and clear any status bits that might have been set since
    // last clearing them.
    //
    ui32Status = HibernateIntStatus(0);
    HibernateIntClear(ui32Status);

    //
    // Configure Hibernate wake sources.
    //
    HibernateWakeSet(HIBERNATE_WAKE_PIN /*| HIBERNATE_WAKE_RESET*/);
    HibernateIntEnable(HIBERNATE_INT_PIN_WAKE); //<<<--- This has no effect to get a wakeup from WAKE input

    HibernateRTCDisable(); // We are not using the RTC feature in the hibernation module

    //
    // Request Hibernation.
    //
    HibernateRequest();

    The WAKE pin is not waking up the device. The device goes to sleep, the main 25MHz clock shuts down and then when I pull the WAKE signal low, the 25MHz clock starts up. However, no power on reset is ever executed. My startup code never starts.

    I did an experiment and found that if I also enabled reset as a wakeup source, then it would wake from reset, and my initial code would show that hibernate woke up and it was from a reset. Further, If I first pull the WAKE input low, release it, and then yank the reset low, the processor wakes up and both the WAKE and RESET hibernation wake up interrupt bits are set.

    I followed this a bit further with only WAKE set for hibernation wake up. If I put the part to sleep, it ignores reset as a wake up source and the board stays in reset, as expected. If I then pull WAKE low, then pull reset, it will wake up with only the WAKE interrupt bit set.

    I have to be missing something here, I saw the errata on the rev 1 silicon for the WAKE pin not working, but my part was as a date code of August 2015, so that doesn't seem likely. I feel very close to moving this forward, but can't get the expected results from just the WAKE pin.

    I also added the 32kHz clock just to make sure that wasn't' somehow involved, but that has had no effect on these tests.

    I'm close, but what am I missing?

    Regards,
    Doug
  • Hello Doug,

    What are the values of the Hibernate registers before the Wake Pin Only condition code is executed and HibernateRequest has not been executed?

    Also can you please confirm that the Hibernate Wake Pin on the device goes low when the switch is pressed?

    Regards
    Amit
  • HIB CTL: 0x80002150
    HIB IM: 0x00000008
    HIB_RIS: 0x00000010
    HIB_MIS: 0x00000000
    HIB_IC: 0x00000010
    HIB_IO: 0x80000000
    HIB_PP: 0x00000002

    I skipped the clock stuff and all others are zero.

    Yes, the input goes low.
  • Hello Doug,

    The configuration does look fine. Can you confirm that VDD3ON mode is being requested? If yes, then zip the project and attach it to the forum post, so that I can check on my LaunchPad if the same issue persists.

    Regards
    Amit
  • Amit,

    I had not been setting the VDD3ON mode. Adding those lines to enable and disable on startup made no difference. However, in reviewing the datasheet, section 7.3.9, Power Control Using VDD3ON Mode presents a few issues, specifically:

    1) GPIO K[7:4] are not used for wakeup on my design, in fact two are outputs to Ethernet LED indications. The other two are floating. I haven't looked back to see how the internal pull-ups might be set.
    2) More concerning is that apparently the supply rails to the Ethernet resistors R1-R4 (Per Figure 20-13) must be switched off. I have no way to do that, but will try a board mod and remove them for testing.

    Does it seem likely that these couple of issues would prevent the board from waking on the WAKE signal being pulled low.

    In the interim, I have been playing with Sleep modes which are working pretty well, but I'd still like to nail down the Hibernation mode. Appreciate your thoughts, and I'll let you know as I get further in testing this.

    Doug
  • Hello Doug

    If the GPIO Pin wake is not being used then it will not cause any issue. Also since the configuration was VDD3OFF, the GPIO Pin wake feature is not applicable. As long as the VDD/VDDA supply ramp down in hibernate mode, it should be sufficient.

    Regards
    Amit