Monday, January 7, 2008

blinker3

Blinking the led, part 3.

blinker3-20080106a.tar.gz

This post continues to improve on or at least change a simple example program that blinks the led on a Luminary Micro Stellaris evaluation board. Specifically supported are the LM3S811, LM3S1968, and the LM3S6965 evaluation boards.

part 1, blinker1, was very simple assembler. part 2, blinker 2, was C with some support functions in assembler. Both part 1 and part 2 simply counted for a while between blinks. Part 3 uses the on chip timer to control the rate of the blinks with some precision.

This family of chips has three on board timers, for what I care about here we are going to take one of the timers and make it a 32 bit count down timer that rolls over. Basically you can grab the timer value when you start something, grab the timer value again and subtract it from the start time to get the duration. In this case we continue sampling the timer and subtracting from the start time until we reach a pre-determined timeout. Note, being 32 bit timers and using 32 bit math you dont have to worry about the counter roll over because you are allowed to borrow off the top of the register. Take a 3 or 4 bit counter and work it out on paper...

Because I am using the timer I needed to make sure the system clock was predictable. At one point I was having problems with the system clock between loading with lmiflash and reset/powerup. So I made it predictable by reading the register, preserving the reserved bits and oring on the bits I wanted which were mostly the default bits. For the 811 I did not have to touch the clock, it just worked.

So, the 811 eval board uses a 6mhz clock, so if we count to 6,000,000 then toggle the led that should be once a second. And it is. The 1968 and 6965 are 8mhz based so when compiling for those the timeout is 8,000,000 clock ticks. All of the problems we had with the for loop in blinker2 go away as gcc is not willing to optimize out the GET32 timer reads.