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.

Trouble with TM4C123GXL Hibernate

Other Parts Discussed in Thread: EK-TM4C123GXL

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.