Other Parts Discussed in Thread: EK-TM4C123GXL
This code just isn't doing what I thought it would.
I'm trying to make it so that on reset, the LED flashes and then it hibernates. After it wakes from hibernation the LED flashes 5 times and hibernates again, this should happen forever. I'm not sure if my hibernation configuration is out of order or if I'm missing something entirely.
#include <stdint.h>
#include "inc/tm4c123gh6pm.h"
#include <stdbool.h>
#include "driverlib/hibernate.h"
#include "driverlib/sysctl.h"
#include "driverlib/rom_map.h"
uint32_t hibStatus;
uint32_t hibData[64];
void hibernateInterrupt(void);
void ledOn(void);
void ledOff(void);
int main(void);
void hibernate(void) {
// Enable the hibernation peripheral
MAP_SysCtlPeripheralEnable(SYSCTL_PERIPH_HIBERNATE);
// Enable clocking to the hibernation module
MAP_HibernateEnableExpClk(MAP_SysCtlClockGet());
// delay here to allow crystal to power up and stabalize
MAP_SysCtlDelay(5000);
// Configure the clock source for Hibernation module, and enable the RTC
// feature.
MAP_HibernateClockConfig(HIBERNATE_OSC_LOWDRIVE);
MAP_HibernateRTCEnable();
// Initialize the RTC
MAP_HibernateRTCSet(0);
// Set the match 0 register for 10 seconds from now
HibernateRTCMatchSet(0, MAP_HibernateRTCGet() + 10);
// Clear any pending status
hibStatus = MAP_HibernateIntStatus(false);
MAP_HibernateIntClear(hibStatus);
// Enable the interrupt sources
MAP_HibernateIntEnable(HIBERNATE_INT_PIN_WAKE | HIBERNATE_INT_LOW_BAT
| HIBERNATE_INT_RTC_MATCH_0);
// Save the program state information (not currently populated)
MAP_HibernateDataSet(hibData, 64);
// Configure to wake on RTC match, low battery or pin wake
MAP_HibernateWakeSet(HIBERNATE_WAKE_PIN | HIBERNATE_WAKE_RTC
| HIBERNATE_WAKE_LOW_BAT);
// Set the function to run on wake
HibernateIntRegister(hibernateInterrupt);
// Request to go into hibernation mode
MAP_HibernateRequest();
// It may take some time for power to be removed
for (;;) {
}
}
void hibernateInterrupt(void) {
// Get the interrupt status
hibStatus = MAP_HibernateIntStatus(true);
// Clear the interrupt
MAP_HibernateIntClear(hibStatus);
uint8_t i;
for (i=0; i<5; i++) {
ledOn();
MAP_SysCtlDelay(1500000);
ledOff();
MAP_SysCtlDelay(1500000);
}
// Process the RTC match 0 and wake pin interrupts
if (hibStatus & (HIBERNATE_INT_RTC_MATCH_0 | HIBERNATE_INT_PIN_WAKE)) {
// RTC match 0 interrupt actions here
}
// Process the low battery interrupt
if (hibStatus & HIBERNATE_INT_LOW_BAT) {
}
hibernate();
}
void configureLED(void) {
volatile uint32_t loop;
// Enable the GPIO port that is used for the on-board LED.
SYSCTL_RCGC2_R = SYSCTL_RCGC2_GPIOF;
// Do a dummy read to insert a few cycles after enabling the peripheral.
loop = SYSCTL_RCGC2_R;
// Enable the GPIO pin for the LED (PF3). Set the direction as output, and
// enable the GPIO pin for digital function.
GPIO_PORTF_DIR_R = 0x08;
GPIO_PORTF_DEN_R = 0x08;
}
void ledOn(void) {
// Turn on the LED.
GPIO_PORTF_DATA_R |= 0x08;
}
void ledOff(void) {
// Turn off the LED.
GPIO_PORTF_DATA_R &= ~(0x08);
}
int main (void) {
configureLED();
ledOn();
MAP_SysCtlDelay(3000000);
ledOff();
hibernate();
}
Looking through the peripheral driver library it wasn't clear to me where execution starts after returning from hibernation. If I don't set `HibernateIntRegister(hibernateInterrupt);` should I expect that main will be run when the interrupt occurs?