Stellaris launchpad Hibernation module.

Texas Instruments chips are renowned for their low power operations. In this example I will go through basics of the hibernate module available with Stellaris devices which enables the user to put the device i low power mode. This module becomes trivial in low power consumption demanding applications. They claim that the processor only  consumes around 6 micro amperes of current when it is configured to work in the hibernate module. Within this article I will refer to the datasheet of the device where applicable.

med_ek-lm4f120xl_stellarislaunchpad_tool

It is fairly easy to use the hibernation module in the Stellaris devices through their “Peripheral driver library”. Also the module is very well explained in the datasheet. So I recommend everyone to go through the datasheet and understand the behavior of the module prior to coding. At-least, that is my approach. The hibernate module related information can be found in Chapter 7.

In this example I will use the external wake-up button to signal the processor to come out from the hibernation. If you go through the schematics of the launchpad, which is available at Page no 20 of launchpad user manual you will realize that the SW2 is connected to both the PF_0 and WAKE pin in the processor.

Once the processor is in the hibernation it can retain the GPIO states and some processor states too. When it comes out from the hibernation it acts as a Power ON reset. So you need to specifically handle the hibernate interrupts and carry out necessary configurations if you want to have a better control over the processes. Within this example that part will not be addressed. Please refer to section 7.3.10 in the datasheet for more information.

Moreover, here I will use the SW2 as a GPIO too. In order to configure the PF_0 as a GPIO pin you need to unlock that pin from NMI (non-maskable interrupt) mode. Refer to the section 10.2.4 in the datasheet. Following code will does exactly the same thing,

HWREG(GPIO_PORTF_BASE + GPIO_O_LOCK) = GPIO_LOCK_KEY_DD;
HWREG(GPIO_PORTF_BASE + GPIO_O_CR) |= 0x01;
HWREG(GPIO_PORTF_BASE + GPIO_O_LOCK) = 0;

Hibernation module can be configured using the following API calls,

SysCtlPeripheralEnable(SYSCTL_PERIPH_HIBERNATE);
HibernateEnableExpClk(SysCtlClockGet());
HibernateWakeSet(HIBERNATE_WAKE_PIN);
HibernateGPIORetentionEnable();

The API calls are self explanatory. The processor will be put into the hibernation mode by executing the following API call.

HibernateRequest();

Here it will power off the microprocessor and will wait until a wake up condition occur.

In the following code, the user will first have to press SW1 to start the program. Then the Green LED will keep on blinking. Once both SW1 and SW2 were pressed the processor will go into the hibernation mode. Wake up pin can be accessed through SW2 to come out of hibernation.

Code:


/*
 * Hibernate example
 */

#include "inc/hw_memmap.h"
#include "inc/hw_types.h"
#include "inc/hw_gpio.h"
#include "driverlib/sysctl.h"
#include "driverlib/gpio.h"
#include "driverlib/timer.h"
#include "driverlib/pin_map.h"
#include "driverlib/hibernate.h"

void RedLEDBlink();
void BlueLEDBlink();
void GreenLEDBlink();

int main(void)
{
	unsigned long a;
	// Configuring the clock to have 40 MHz
	SysCtlClockSet(SYSCTL_USE_PLL | SYSCTL_OSC_MAIN | SYSCTL_XTAL_16MHZ | SYSCTL_SYSDIV_5);

	// Configure LEDs
	SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOF);
	GPIOPinTypeGPIOOutput(GPIO_PORTF_BASE,GPIO_PIN_1 | GPIO_PIN_2 | GPIO_PIN_3);
	GPIOPinWrite(GPIO_PORTF_BASE,GPIO_PIN_1 | GPIO_PIN_2 | GPIO_PIN_3 , 0x00);
	RedLEDBlink();

	// Unlock PF_0
	HWREG(GPIO_PORTF_BASE + GPIO_O_LOCK) = GPIO_LOCK_KEY_DD;
	HWREG(GPIO_PORTF_BASE + GPIO_O_CR) |= 0x01;
	HWREG(GPIO_PORTF_BASE + GPIO_O_LOCK) = 0;
	// Configure switches
	GPIOPinTypeGPIOInput(GPIO_PORTF_BASE,GPIO_PIN_0 | GPIO_PIN_4);
	GPIOPadConfigSet(GPIO_PORTF_BASE, GPIO_PIN_0 | GPIO_PIN_4, GPIO_STRENGTH_2MA, GPIO_PIN_TYPE_STD_WPU);

	// Wait until SW1 is pressed
	while(GPIOPinRead(GPIO_PORTF_BASE,GPIO_PIN_4));
	// Wait until SW1 is released
	while(!GPIOPinRead(GPIO_PORTF_BASE,GPIO_PIN_4));
	RedLEDBlink();

	// Configure hibernate module
	SysCtlPeripheralEnable(SYSCTL_PERIPH_HIBERNATE);
	HibernateEnableExpClk(SysCtlClockGet());
	HibernateWakeSet(HIBERNATE_WAKE_PIN);

	while(1){
		GreenLEDBlink();

		// Check whether both SW1 and SW2 are pressed
		if(!GPIOPinRead(GPIO_PORTF_BASE,GPIO_PIN_4 | GPIO_PIN_0))
		{
			// Loop until both SW1 and SW2 are released
			while(GPIOPinRead(GPIO_PORTF_BASE,GPIO_PIN_4 | GPIO_PIN_0) != 0x11);
			BlueLEDBlink();
			HibernateGPIORetentionEnable();
			HibernateRequest();
		}
	}
}

void RedLEDBlink()
{
	GPIOPinWrite(GPIO_PORTF_BASE,GPIO_PIN_1, 0xFF);
	SysCtlDelay(500000);
	GPIOPinWrite(GPIO_PORTF_BASE,GPIO_PIN_1 , 0x00);
	SysCtlDelay(500000);
}

void BlueLEDBlink()
{
	GPIOPinWrite(GPIO_PORTF_BASE,GPIO_PIN_2, 0xFF);
	SysCtlDelay(500000);
	GPIOPinWrite(GPIO_PORTF_BASE,GPIO_PIN_2 , 0x00);
	SysCtlDelay(500000);
}

void GreenLEDBlink()
{
	GPIOPinWrite(GPIO_PORTF_BASE,GPIO_PIN_3, 0xFF);
	SysCtlDelay(500000);
	GPIOPinWrite(GPIO_PORTF_BASE,GPIO_PIN_3 , 0x00);
	SysCtlDelay(500000);
}

In order to make this code work, you need to put all the include paths, linker paths and pre-processor definitions correctly. They can be found in the post related to ‘buttons.h’ in the blog.

Thank you.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s