Hi
When an interrupt occurs in the Coldfire architecture, the interrupt controller module works out the vector number that is associated with the interrupt and then it executes the function that the vector points to. It is common practice to point all unused vectors to a default handler that can be used for debugging or other diagnostics.
If you want to create a handler for a specific interrupt, you would normally change the vector for that interrupt to point to the handler. ISRs are usually written to be as efficient as possible and as the interrupt module has already determined a vector for you, it is not very good practice to duplicate this effort in software with a big switch statement in a generic handler.
If your vector table remains in flash, then you will not be able to change it at run time and you need to set the vector for your interrupt to point at the ISR. This is easily done - just copy the way that the irq_handler does it, you need to add one line and change another in the vectors.s file, assume you are adding my_irq_handler():
In vectors.s add:
extern _my_irq_handler
Change the vector (let's say it is PIT0):
vector77: .long _my_irq_handler
(you need the leading _ because the CodeWarrior compiler decorates all functions with a leading _, but vectors.s is an assembler file.)
Now define your function:
Code:__interrupt__void timer_handler (void){ MCF_PIT0_PMR |= MCF_PIT_PCSR_PIF;} So now your code will compile, but your ISR will not be called. There are two more steps that you need, one is to configure the peripheral to generate interrupts, and the second is to inform the interrupt module that the interrupt is active and to set a level and priority. I think you are missing out the second step.
Here is the source to two functions that I use. The first initialises a PIT and you will see that is calls the second, which enables the interrupt in the interrupt module.
Code:/* FUNCTION: PIT_Timer_Init() * * Initialise and enable a Programmable Interval Timer * * PARAM1: PIT - can be 0, 1, 2 or 3 * * PARAM2: Prescaler value - sets the tick frequency to * (system clock/2) divided by 2^PCSR * * PARAM3: Modulo counter - sets the mumber of ticks per interrupt * * PARAM4: Interrupt handler * * RETURNS: none */voidPIT_Timer_Init(uint8 timer, uint8 PCSR, uint16 PMR, void (*handler)(void)){ // At 64MHz: // PCSR = 5 gives a tick per uS // PMR = 10000 gives an interrupt every 10ms if (timer < 4) { uint8 ipl = MCF5282_INTC_ICR_IL(TIMER_NETWORK_LEVEL) | MCF5282_INTC_ICR_IP(timer); MCF5282_PIT_PCSR(timer) = 0; // Set up interrupt handler mcf5282_interrupt_init(timer + 55, ipl, handler); // Set modulo count // (= number of ticks per interrupt) MCF5282_PIT_PMR(timer) = PMR; // Tick frequency = (system clock/2) divided by 2^PCSR MCF5282_PIT_PCSR(timer) = (uint16)(MCF5282_PIT_PCSR_PRE(PCSR)); // Create and enable 'set and forget' timer MCF5282_PIT_PCSR(timer) |= MCF5282_PIT_PCSR_OVW | MCF5282_PIT_PCSR_PIE | MCF5282_PIT_PCSR_PIF | MCF5282_PIT_PCSR_RLD | MCF5282_PIT_PCSR_EN; }}/* FUNCTION: PIT_Timer_Stop() * * Disable timer interrupts for the specified PIT * * PARAM1: PIT - can be 0, 1, 2 or 3 * * RETURNS: none */voidPIT_Timer_Stop(uint8 timer){ if (timer < 4) MCF5282_PIT_PCSR(timer) &= ~( MCF5282_PIT_PCSR_PIE | MCF5282_PIT_PCSR_EN );} Code:/* FUNCTION: mcf5282_interrupt_init() * * Initialise an interrupt handler for an interrupt source * for INTC0. If the handler is a NULL pointer, then mask * this interrupt. * * PARAM1: Interrupt source (1..62) * * PARAM2: Interrupt level and priority * * PARAM3: Interrupt handler * * RETURNS: none */voidmcf5282_interrupt_init(uint8 source, uint8 ipl, void (*handler)(void)){ // Only for user defined vectors in INTC0 if ((source > 0) && (source < 63)) { // Interrupts should be disabled to avoid vector problems // and to ensure that a spurious interrupt exception can't // be generated. uint8 sysint = asm_set_ipl(7); if (handler) { // Set interrupt priority level MCF5282_INTC0_ICR(source) = (ipl & 0x3F); // Set vector mcf5xxx_set_handler(source+64, (ADDRESS)handler); // Clear mask for this handler if (source < 32) MCF5282_INTC0_IMRL &= ~(MCF5282_INTC_IMRL_INT(source) | MCF5282_INTC_IMRL_MASKALL); else { MCF5282_INTC0_IMRL &= ~(MCF5282_INTC_IMRL_MASKALL); MCF5282_INTC0_IMRH &= ~(MCF5282_INTC_IMRH_INT(source)); } } else { // Set vector mcf5xxx_set_handler(source+64, (ADDRESS)handler); // Set mask for this handler if (source < 32) { MCF5282_INTC0_IMRL |= MCF5282_INTC_IMRL_INT(source); } else { MCF5282_INTC0_IMRH |= MCF5282_INTC_IMRH_INT(source); } } // As you were... asm_set_ipl(sysint); }}/********************************************************************/ You also probably need to read the chapter about the interrupt controller module for your CPU (although they are pretty much the same across the board).
Paul.
Edit>>>
mcf5282_interrupt_init() will also set the vector for you if your vector table is copied to RAM. The other functions called by this code are prety much standard Freescale examples which you will probably find in files in a folder called cpu in your project.
Message Edited by mccp on 2007-03-2311:36 AM