Using timer interrupts on the Tiva C microcontroller with the Energia IDE

I wanted to generate a period timer interrupt on the Tiva C within the Energia environment WITHOUT modifying any of the Energia files. The interrupt vector table can not be modified without tinkering with the Energia system files which would seem to make the task impossible however…..The Energia environment allows you attach an interrupt handler to a port pin and, some port pins can be driven by a timer so, combining these two ideas leads to a working timer interrupt (albeit at the expense of a port pin). Here’s the code:

 
// Try to hack a timer interrupt without rewriting the energia source files
// The plan: Attach an interrupt to an IOPIN that is driven by the timer. 
// Hopefully this will allow us to get a periodic interrupt
// PF1 drives the RED LED.  This can be driven by T0CCP1
#include <inc/tm4c123gh6pm.h>
#define LED RED_LED
// Period of 80000 should yield an interrupt rate of 1kHz
// This divisor will have to be spread across the match register and prescaler
#define PERIOD 80000  
void initTimer(void)
{
  SYSCTL_RCGCTIMER_R |= 1;
  TIMER0_CTL_R &= ~(1 << 8); // disable timer B
  TIMER0_CFG_R  = 4; 
  TIMER0_TBMR_R = 0b1010; // set T1AMS, T0MR=0
  TIMER0_TBILR_R = PERIOD & 0xffff; // set interval (lower 16 bits) 
  TIMER0_TBPR_R = PERIOD >> 16; // set interval (upper bits)
  TIMER0_TBMATCHR_R = 100; //  set match value
  TIMER0_CTL_R |= (1 << 8); // enable timer B
  GPIO_PORTF_AFSEL_R |= (1 << 1); // select alternate function for PF1 
  GPIO_PORTF_PCTL_R |= (7 << 4);
}
int Count = 0;
void ISR(void)
{
  Count++;
}
void setup() {                
  // initialize the digital pin as an output.
  pinMode(LED, OUTPUT); 
    
  Serial.begin(9600);
  initTimer();
  attachInterrupt(LED, ISR, RISING);
}
// the loop routine runs over and over again forever:
void loop() {
  int snapshot; 
  Count=0;
  delay(1000);                 // wait for a second
  snapshot=Count;              // check to see how far the count got in that time (should be 1000 for 1 ms timebase)
  Serial.println(snapshot);    // report it back  
}

 

Good luck!

Using timer interrupts with the Energia/MSP430 IDE.

I was curious whether you could run interrupts within Energia code on the TIMSP430 – guess what? You can. Here’s some code that toggles the Green LED during an interrupt service routine. The RED LED is toggled in the main program loop. The code runs on the MSP430 Launchpad with the MSP430G2553 microcontroller.

#include <msp430.h>
void setup()
{
  // put your setup code here, to run once:
  pinMode(P1_6,OUTPUT); // make the LED pins outputs
  pinMode(P1_0,OUTPUT);
  // Configuration word
  // Bits 15-10: Unused
  // Bits 9-8: Clock source select: set to SMCLK (16MHz)
  // Bits 7-6: Input divider: set to 8
  // Bits 5-4: Mode control: Count up to TACCRO and reset
  // Bit 3: Unused
  // Bits 2: TACLR : set to initially clear timer system
  // Bit 1: Enable interrupts from TA0
  // Bit 0: Interrupt (pending) flag : set to zero (initially)
  TA0CTL=0b0000001011010010; 
  TACCR0=2000; // Set TACCR0 = 2000 to generate a 1ms timebase @ 16MHz with a divisor of 8
  TACCTL0=BIT4; // Enable interrupts when TAR = TACCR0

  
}
void loop()
{
  // put your main code here, to run repeatedly:
  digitalWrite(P1_0,HIGH);
  delay(100);
  digitalWrite(P1_0,LOW);
  delay(100);
}
// The address function that follows this vector statement is placed in the specified location Interrupt Vector table 
#pragma vector=TIMER0_A0_VECTOR
__interrupt  void timerA0ISR(void)
{
// Timer A0 Interrupt service routine
  static int msCount=0;// Count milliseconds to allow a 1 second pulse
  static int state=0;  // Remember LED state for toggling purposes
  msCount++;
  if (msCount >= 1000)
  {
    msCount = 0;
    digitalWrite(P1_6,state); // Write to LED
    state=~state;             // toggle state
  }
  TA0CTL &= ~BIT0;     // Updated Dec 2015. Acknowledge the interrupt
}

An ADC game on the LPC1114

This is a simple game for the LPC1114FN28 (DIP version). The user controls the location of an @ symbol on the display, trying to steer it away from the edges of the ‘tunnel’. The user starts with 16 ‘lives’ and the game ends when the user runs out of lives.

Wiring

The wiring diagram is as shown below.
wiring
The two buttons are used to reset and enter ISP mode. The potentiometer is used to control the @ symbol.

Gameplay

During game play, the screen scrolls vertically. The micro draws a series of dots with a gap in the middle as shown below:

…………………………….     @       ……………………00000010

The gap randomly migrates back and forth with each new line. The number to the right is the remaining lives (in hex)
Sourcecode available from here

PRBS

I have been using a 31 bit prbs function to generate random numbers. I never tested to see if this was of maximum length – guess what – it wasn’t! So after some trial and error I arrived at the following 31 bit prbs function which doesn’t repeat itself until after 2 billion cycles or so and is maximal length


#include <stdio.h>
unsigned prbs()
{
	// This is a verified 31 bit PRBS generator on an i3 running 64 bit Fedora Linux
	static unsigned long shift_register=0xa5a5a5a5;
	unsigned long new_bit=0;
	static int busy=0; // need to prevent re-entrancy here
	if (!busy)
	{
		busy=1;
		new_bit= ((shift_register >> 27) ^ (shift_register >> 30));
		new_bit= ~new_bit;
		new_bit = new_bit & 1;
		shift_register=shift_register << 1;
		shift_register=shift_register | (new_bit);
		shift_register=shift_register & 0x7fffffff;
		busy=0;
	 
	}
	return shift_register; // return 31 LSB's
}
void main()
{
	unsigned first_run;
	unsigned count;
	int value;
	first_run = prbs();
	value=prbs();
	while(value != first_run)
	{
		value=prbs();
		//printf("%d\n",value); // uncomment this to see the values (slows things down a lot)
		count++;
	}
	printf("Count = %d\n",count);
}

The “busy” flag is used in the prbs function in case the routine is called from with an interrupt service routine leading to a danger of re-entrancy.