Coldfire MCF 5307 IRQ7 Initialization/ISR

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

Coldfire MCF 5307 IRQ7 Initialization/ISR

963 Views
williamcarlisle
Contributor II

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!

Labels (1)
0 Kudos
Reply
2 Replies

662 Views
mjbcswitzerland
Specialist V

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
    }
}

0 Kudos
Reply

662 Views
TomE
Specialist II

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

0 Kudos
Reply