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.