CS/ECE 5785/6785: Lab 2


(back to: main 5785 page, 5785 lab page)

Creating a Timer

Create a new project for your board in CodeWarrior using the same steps as in Lab 1. Now develop code for a timer based on the Programmable Interrupt Timer 0 (PIT0) module on your ColdFire chip (see Chapter 22 of the reference manual for the MCF5223x).

Your assignment is to develop three functions:
void init_timer (void);
int start_timer (void);
int stop_timer (int);
init_timer() sets PIT0 as a free running timer that counts down at the CPU frequency, resetting to 0xffff after it reaches zero. Read about this in your processor manual. This can be accomplished by writing the correct value to a single configuration register MCF_PIT0_PCSR, using macros found in the CodeWarrior header file MCF52233_PIT.h. Be sure to set the PIT0 prescaler properly so that it counts down at the bus clock frequency.

start_timer() returns an integer value corresponding to the current value of the timer, as found in MCF_PIT0_PCNTR.

stop_timer() takes a timer start value as an argument and compares this value to the current timer value. It returns the number of elapsed cycles since the timer was started. It must operate correctly even if the timer has wrapped around to 0xffff between the call to start_timer() and the call to stop_timer(). In other words, your timer should correctly measure times from 0 to 65535 cycles.

Put these functions in a file timer.c

Using a Timer

Your task is to measure and report the average number of cycles your ColdFire processor requires to: More information: Put all of this code in a file time_ops.c

Timer Interrupts

Starting with your init_timer() function, create a new function init_timer_with_interrupts() that makes PIT0 generate an interrupt when the timer rolls over. Select the prescaler value for PIT0 that makes it flash LED0 (see code below) as close as possible to 1Hz (this just needs to be close, not exact -- you can leave PIT0 as a free-running timer).

Your interrupt handler should look like this:
__declspec(interrupt:0) void handler_pit0_int (void)
{
    MCF_GPIO_PORTTC ^= 0x1;
    MCF_PIT0_PCSR |= MCF_PIT_PCSR_PIF;
}
For this interrupt handler to blink the LED, you will need to have set bit 0 of port TC as GPIO and as an output pin.

You also need to install the interrupt handler by calling this function:
static unsigned char *fnSetIntHandler(int iVectNumber, unsigned char *new_handler)
{
    extern unsigned long __VECTOR_RAM[];
    unsigned char *old_handler;
    
    old_handler = (unsigned char *)__VECTOR_RAM[iVectNumber];
    __VECTOR_RAM[iVectNumber] = (unsigned long)new_handler;
    return old_handler;     
}

Its arguments should be the vector number, 119, and the address of your interrupt handling function.

Also you need to use the following code to tell the interrupt controller to give you interrupts for PIT0:
static void init_interrupt_controller (void)
{
    MCF_INTC0_ICR55 |= MCF_INTC_ICR_IL (0x4) | MCF_INTC_ICR_IP (0x4);
    MCF_INTC0_IMRH &= (~MCF_INTC_IMRH_INT_MASK55);
    MCF_INTC0_IMRL &= (~MCF_INTC_IMRL_MASKALL);
}
After calling all hardware initialization functions, and before entering your program's main loop, you should enable interrupts by calling this function:
void enable_interrupts(void)
{
	asm {
   	    move.l   #0x00002000,d0
	    move.w   d0,SR
    	}
}
Put these functions in a file int_timer.c

Power-On Self Test

Modify your processor's boot code so that it performs some power-on self tests. You should: Put this code in a file self_test.c

Lab report

Handin in the CADE Lab

To hand in file foo:
  handin cs5785 lab2 foo



This page is maintained by John Regehr, mail me if you find a mistake or if any content is unclear.