Blink Example using Timer on a Tiva Launchpad

Working with the powerful Tiva Launchpads using Energia is awesome! However… things start to get ugly when trying to achieve things not officially supported by the IDE and its libraries, such is the case when trying to use hardware Timers.

Tiva Launchpad’s micro controller offers several 16-32 bit hardware Timers with interesting capabilities. I won’t dig deeply with the use of timers, but I’ll show how to setup a timer to trigger an interrupt to handle led blinking.

The following code contains what we need to setup Timer 1A (these Timer provide two channels A and B, each one of 16 bits and they can be combined if using channel A on 32 bit mode), trigger an interrupt and perform led blinking every one second. The code has been tested on a Tiva Launchpad TM4C1294XL but it’s compatible with the TM4C123GXL board (they have different micro controllers but they are based on the same technology by Texas Instruments, that makes code recyclable).


#include "wiring_private.h"
#include "inc/hw_ints.h"
#include "driverlib/interrupt.h"
#include "driverlib/rom.h"
#include "driverlib/timer.h"
#include "driverlib/sysctl.h"

#define LED RED_LED

volatile uint8_t state = 0;

void setup(){
  pinMode(LED, OUTPUT);   
  
  configureTimer1A();
}

void loop(){
  
}

void configureTimer1A(){
  ROM_SysCtlPeripheralEnable(SYSCTL_PERIPH_TIMER1); // Enable Timer 1 Clock
  ROM_IntMasterEnable(); // Enable Interrupts
  ROM_TimerConfigure(TIMER1_BASE, TIMER_CFG_PERIODIC); // Configure Timer Operation as Periodic
  
  // Configure Timer Frequency
  // Frequency is given by MasterClock / CustomValue
  // Examples: 120MHz / 120k = 1000 kHz ; 120MHz / 120M = 1 Hz
  ROM_TimerLoadSet(TIMER1_BASE, TIMER_A, 120000000); 
  
  ROM_IntEnable(INT_TIMER1A);  // Enable Timer 1A Interrupt
  ROM_TimerIntEnable(TIMER1_BASE, TIMER_TIMA_TIMEOUT); // Timer 1A Interrupt when Timeout
  ROM_TimerEnable(TIMER1_BASE, TIMER_A); // Start Timer 1A
}

void Timer1AHandler(void){
  //Required to launch next interrupt
  ROM_TimerIntClear(TIMER1_BASE, TIMER_A);
  
  state ^= 0x02; // Toggle led state
  digitalWrite(LED, state); // Blink
}

We’re not done yet. There is one important thing missing… We need the compiler to know that our function ‘Timer1AHandler’ is the function that will handle Timer 1A interrupts. We need to hack a little bit with Energia’s libraries. By default most interrupt handlers are not defined by Energia, the following steps helps us to set up not only a handler for the Timer 1A interrupt but for other timers and components of the micro controller as well.

We need to locate the folder where Energia’s libraries are located. They are on your installation folder. Once on the installation folder we must find the following route: Energia/Java/hardware/lm4f/cores/lm4f/. Energia and Arduino core libraries are found in this folder. We need to open and edit two files: wiring_private.h and startup_gcc.c.

On wiring_private.h we need only to add one line of code between/above/down ToneIntHandler and GPIOIntHandler:


void Timer1AHandler(void); //Custom Timer1A Interrupt Handler

On startup_gcc.c we need to insert one line of code and modify two lines. First, we need to add the function prototype as an attribute (copy and paste the following line where the attributes are found):


__attribute__((weak)) void Timer1AHandler(void) {} //Custom Timer1A Interrupt Handler

Second, we need to modify the default interruption handler for Timer 1A. You’ll need to change two lines of code. You’ll find a section similar to the following inside the array __attribute__ ((section(“.isr_vector”)))
void (* const g_pfnVectors[])(void) = { … };


IntDefaultHandler,                      // Timer 0 subtimer B
IntDefaultHandler,                      // Timer 1 subtimer A
IntDefaultHandler,                      // Timer 1 subtimer B

Change it to become this:


IntDefaultHandler,                      // Timer 0 subtimer B
Timer1AHandler,                      	// Timer 1 subtimer A - Custom Timer 1A Interrupt Handler
IntDefaultHandler,                      // Timer 1 subtimer B

IMPORTANT: You’ll have to make the second step twice! You’ll find a similar part of code which is practically the same, it repeats because of a #ifdef statement. Using the ‘find’ command on a text editor helps.

Setting up the custom interrupt handler was tricky, but it’s really important to understand how to do it. I created a git repository containing the Energia sketch and the two modified files (in the case you got confused on how to modify the files). You can find the repository here.

Advertisements
This entry was posted in Uncategorized. Bookmark the permalink.

2 Responses to Blink Example using Timer on a Tiva Launchpad

  1. Enrique says:

    Thank you. It was very helpful for me. I have made it work without the need of hacking Energia.

    I used the funcion:
    ROM_TimerIntRegister(TIMER0_BASE, TIMER_A, &Timer0IntHandler);

    Hope this helps 🙂

    Like

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 )

Twitter picture

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

Facebook photo

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

Google+ photo

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

Connecting to %s