I am currently working to modify firmware on a Coldfire 5307, and we are needing to use the NMI IRQ7(pin68) pin for power failure. This will only be used in last resort situations.
I have endless documentation for setting up everything else imaginable on the 5307, just nothing substantial enough to even get started setting up IRQ7. Any help from someone that has any experience programming IRQ7 on a coldfire 5307 would be greatly appreciated, thanks much!
Hi
I don't know whether this is of any use but I have posted code from the uTasker project which sets up edge port IRQ7 on an M5225x (and similar) Coldfires. It may or may not be relevant to the 5307....
Regards
Mark
Configuring edge port IRQ (including NMI - IRQ7) of M5225x (and similar) Colfires
unsigned short usMask, usValue;
unsigned short *EPPAR = EPPAR0_ADR; // eport 0
POWER_UP(POWER_EPORT); // apply power to edge port module
usMask = (ALT_2_FUNCTION_Q << (2 * ucIRQ_bit));
usValue = (PRIMARY_FUNCTION_Q << (2 * ucIRQ_bit));
PNQPAR &= ~usMask; // set interrupt function on port NQ
PNQPAR |= usValue;
EPDDR0 &= ~(0x01 << ucIRQ_bit); // ensure that the edge port is configured as an input
EPPAR0 &= ~usMask; // clear the interrupt type mask
*EPPAR |= (usValue << 1); // falling edge sensitive
eport_handler[ucIRQ_bit - 1] = ((INTERRUPT_SETUP *)ptrSettings)->int_handler; // set caller's interrupt callback
fnSetIntHandler((IRQ1_VECTOR + (ucIRQ_bit - 1)), (unsigned char *)irq_int_handlers[ucIRQ_bit - 1]); // enter the handler routine
EPFR0 = (0x01 << ucIRQ_bit); // clear pending interrupts
EPIER0 |= (0x01 << ucIRQ_bit); // enable interrupts
IC_IMRL_0 &= ~((IRQ1_PIF_INT_L << (ucIRQ_bit - 1)) | MASK_ALL_INT); // unmask interrupt source
Entereing teh interrupt handler (vectors in RAM)
extern 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;
}
#define IRQ1_PIF_INT_L 0x00000002
NMI interrupt handler:
// IRQ7 has dedicated NMI level and so should not call any driver routines which require protected regions.
// The flag iInterruptLevel is not modified since this routine can also not be interrupted and doesn't need to control the value
// due to the fact that it doesn't call any code with protected region entry/exit requirements (this avoids the risk of
// disturbing lower priority interrupts that may be in a protected region and avoids related counter corruption)
//
static __interrupt__ void _irq7_handler(void)
{
EPFR0 = 0x80; // clear interrupt flag
if (eport_handler[6]) {
(eport_handler[6])(); // call the user handler, if available
}
}
This is pretty simple. As long as you've read every Motorola and Freescale CPU manual since the early 1980's that is - then you know what concepts are operating and what keywords to look for.
With the original 68000 there were 7 interrupt pins on the CPU. A peripheral pulled one of these pins low, and then waited for an interrupt-ack cycle, at which point it had to provide a "Vector" on the bus so the CPU knew which service routine to call.
The next innovation with more integrated chips was to allow internal peripherals to generate interrupt vectors (that you could set or that were preassigned) and allow the external pins to "Autovector".
So search for "Autovector" and find "Table 9-5. AVR Field Descriptions". Set bit 7 to allow IRQ7 to autovector. Set all the bits for all the pins you're using to generate interrupts. "Table 9-6. Autovector Register Bit Assignments" tells you which bits are what interrupts and what vectors they use.
Is that enough?
Make sure you've read "18.7.1 Level 7 Interrupts" for the differences between IRQ7 and all the other ones.
Tom