• Resolved

Trouble with TM4C123GXL Hibernate

Hello everyone,

I'm having trouble enabling the hibernation module on my TM4C123GXL. This the following code I'm executing:

#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>

#include "inc/hw_ints.h"
#include "inc/hw_memmap.h"
#include "inc/hw_hibernate.h"
#include "inc/hw_types.h"
#include "driverlib/gpio.h"
#include "driverlib/rom.h"
#include "driverlib/interrupt.h"
#include "driverlib/pin_map.h"
#include "driverlib/sysctl.h"
#include "driverlib/systick.h"
#include "driverlib/hibernate.h"

uint32_t g_sysclk;
volatile uint32_t g_ms = 0;
static volatile uint8_t hib_stat_track = 0;

static __interrupt void systick_isr(void) {
	++g_ms;
}

void init_main(void) {

	SysCtlMOSCConfigSet(SYSCTL_MOSC_HIGHFREQ); // xtal > 10 MHz
	SysCtlClockSet(SYSCTL_SYSDIV_5 | SYSCTL_XTAL_16MHZ | SYSCTL_USE_PLL | SYSCTL_OSC_MAIN);
	g_sysclk = 40000000;

	const uint32_t systick_clocks = g_sysclk / 1000;
	SysTickPeriodSet(systick_clocks);
	SysTickIntRegister(systick_isr);
	SysTickIntEnable();
	SysTickEnable();
}

void systick_delay(uint32_t ms_delay) {
	ms_delay += g_ms;
	while(g_ms <= ms_delay) {
	}
}

int main(void) {
	uint32_t hibernation_status = 0;

	init_main();

	SysCtlPeripheralEnable(SYSCTL_PERIPH_HIBERNATE);
	hibernation_status = HibernateIntStatus(0);
	// the following function will return true if the MCU is just
	// waking up from hibernation
	if(HibernateIsActive()) {
		HibernateIntClear(hibernation_status);
		if(hibernation_status & HIBERNATE_INT_RTC_MATCH_0) {
			hib_stat_track=1;
		} else if(hibernation_status & HIBERNATE_INT_RESET_WAKE){
			hib_stat_track=2;
		} else if(hibernation_status & HIBERNATE_INT_LOW_BAT) {
			hib_stat_track=3;
		} else {
			hib_stat_track=4;
		}
	} else {
		hib_stat_track=5;
	}
	// hibernate module should be enabled again even if it was already enabled,
	// because it "also initializes some timing parameters".
	HibernateEnableExpClk(g_sysclk);
	// time to check if the hibernation module needs to have its
	// clock source reconfigured
	if(!(hibernation_status & HIBERNATE_INT_RTC_MATCH_0)) {
		// set the module source
		// "HIBERNATE_OSC_HIGHDRIVE specifies a higher drive strength
		// when a 24-pF filter capacitor is used with a crystal."
		HibernateClockConfig(HIBERNATE_OSC_LOWDRIVE);
		// let the Hibernation Module crystal start up!
		systick_delay(15);
	}

	// enable the RTC
	HibernateRTCEnable();
	// reset the RTC to 0
	HibernateRTCSet(0);
	// set RTC match index 0 to 10 seconds in the future
	HibernateRTCMatchSet(0, 10);
	// tell the module to abort when the battery is low!
	//HibernateLowBatSet(HIBERNATE_LOW_BAT_ABORT | HIBERNATE_LOW_BAT_2_5V);
	// tell the hibernation module to wakeup on a RTC match
	HibernateWakeSet(HIBERNATE_WAKE_RTC);
	// now we're ready to request hibernation!
	HibernateRequest();

	// Errata HIB#03 work-around
	while((HWREG(HIB_CTL)&HIB_CTL_CLK32EN)==HIB_CTL_CLK32EN)
	{}
	// hibernate didnt come into effect, reseting!
	SysCtlReset();

	while(1) {}
}

(here's a pastebin link incase the formatting doesnt come through: http://pastebin.com/U9RquzfD)

The problem seems to occur right after calling the following line:

HibernateEnableExpClk(g_sysclk);

Following the function into the hibernate.c, the following code is called:

void
HibernateEnableExpClk(uint32_t ui32HibClk)
{
    //
    // Turn on the clock enable bit.
    //
    HWREG(HIB_CTL) |= HIB_CTL_CLK32EN;

    //
    // Wait for write complete following register load (above).
    //
    _HibernateWriteComplete();
}

Inspecting the HIB_CTL register it seems that the HIB_CTL_CLK32EN is NOT asserted. This seemingly appears to happen randomly. Sometimes after a few power cycles, the module wakes up with the bit set as expected.

However, when the line called to assert the HIB_CTL_CLK32EN bit is carried out, the HIB_CTL_WRC is de-asserted. The main issue here is that the HibernateEnableExpClk(...) function then NEVER returns, as the _HibernateWriteComplete() seems to get the MCU stuck in an infinite loop (this function simply waits for the assertion of the HIB_CTL_WRC bit which never happens).

The "hib_stat_track" serves simply as a way for me to insert a breakpoint in the code. The "hibernation_status" retains a value of 0 throughout the execution.

I'm using the  EK-TM4C123GXL to test it out on, with nothing but a USB cable connected. Can anyone tell me what I'm doing wrong? I think it's a power issue, but looking at the schematic for the board I cannot really figure out what the real problem appears to be.

  • Hello Tobias,

    The EK-TM4C123 will support the VDD3ON mode of Hibernate, however in the code I do not see the VDD3ON being set in Hibernate Control Register.

    Regards

    Amit

    Regards,

    Amit Ashara

  • In reply to Amit Ashara:

    Amit,

    It actually dawned upon me that VDD3ON was required about an hour after I made my post that this would be required since VBAT line is connected to VDD of the TM4C123G ... But thank you VERY much for confirming this, I'm ecasatic!

    Best support I've ever received on an issue like this, TI's the best!