M5211DEMO interrupts

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

M5211DEMO interrupts

3,614 Views
rwehrli
Contributor I
So far I have been unsuccessful at getting any new interrupt to fire. Does anyone have a very simple example that does little more than write to the vectors.s file and can be forced using the interrupt force register?

I've tried many things, including writing the address of my vector handler to the VBR index in RAM.

I'm guessing that I'm not enabling the interrupt and/or masking it properly.

I will continue to RTFM as time permits.
Labels (1)
0 Kudos
Reply
4 Replies

1,126 Views
mccPaul
Contributor I
Hi,
 
In case the examples I pointed out in my reply to your other post didn't help:
 
Coldfire exception processing is explained in detail in the interrupt controller module chapter of the user guides, but it can be a bit confusing.
 
There are a number of steps that you need to complete to enable, trigger and service interrupts properly.
 
1. You need to define an interrupt service routine - note that you must usually use a pragma or some special declaration style to tell the compiler to generate a function that ends with an RTI instruction rather than an RTS instruction.
 
2. You need to configure the peripheral so that it generates interrupts for the condition you are looking for. This usually involves setting register flags for the peripheral.
 
3. You then unmask the interrupt source in the interrupt controller and set a unique level and priority for that source.
 
4. When the interrupt fires, the interrupt controller module identifies the source of the interrupt and the vector for that source. If the interrupt source is not masked, it will then call the interrupt service routine pointed to by the vector. All interrupts at or below the level of this source are automatically masked, but your ISR can mask higher levels by setting the CPU's status register mask. The interrupt controller uses the priority to decide which interrupt to service first when more than one interrupt is active simultaneously.
 
There is sample code on the resources page for the M5211/13 (something like mcf5213sc.zip) and I have modified the main.c from the example project. You will need the CPU startup and headers from this to make this example build. Link: http://www.freescale.com/webapp/sps/site/prod_summary.jsp?ProdMetaId=ProdMetaId%2FDesign_Tools%2FMCF...;
 
I have not compiled or tested this but if you can't get this working then I give up!
 
Please post back the example if you get it to work so that others can use it.
 
Good luck,
 
Paul.
 
Edit - added link to 5211 resources page

Message Edited by mccp on 2007-05-16 10:11 AM

Message Edited by t.dowe on 2007-05-18 05:51 PM

Message Edited by t.dowe on 2007-05-18 05:56 PM



Message Edited by t.dowe on 2007-05-18 05:56 PM

Message Edited by t.dowe on 2007-05-18 11:04 PM
0 Kudos
Reply

1,126 Views
rwehrli
Contributor I
I finally got it working.  The problem stemmed from the default interrupts that were enabled (for IRQs 4,5,7).
 
I used a level of 3 and a priority of 1 and never saw the interrupt, nor was it ever being set in the IACK register.
 
So, I changed it to L7 P1 and it worked.  Now I need a quick tutorial on interrupt level/priority management
so that I can better understand how these correspond so that I can get the entire system running properly.
 
Does anyone have a cheat-sheet for laying out interrupts in a fairly busy system design?
 
Another "issue" with the provided code is that, by default, the "stationary" for the M5211DEMO board do not
include the function m5xxx_set_handler.  I did find what it was doing in another directory that was installed,
but it was doing the same thing that I was doing in my code, which was assigning the interrupt vector in RAM to
the handler address.
 
When I change my PIT0 level to less than 7, it never runs, however, I am able to get my SW2 Interrupt (IRQ7)
to run.  If I change my PIT0 level to 7, it runs fine, however, if I press the SW2, it kills the PIT0.  The code is
not directly affecting either of these, as I am clearing the MCF_EPORT_EPFR only in the SW2 interrupt
handler, and I'm only modifying the PIF bit in the PIT0 handler.  There is an issue of some sort between the
interrupt levels and how they interact that I am missing.  I'm sure that more RTFM is in order, but I'd be
appreciative if someone could offer some more immediate gratification through an example.  I'll happily post
a completed example once I figure it out for the M5211DEMO board.
 

Take Care.
 
Rob!
0 Kudos
Reply

1,126 Views
mccPaul
Contributor I
Hi
 
When an ISR is called, the interrupt module sets the status register interrupt mask to the level of the interrupt being processed. This means that if a level 4 interrupt is being serviced, then all other interrupt sources at levels 4 and below will be masked.
 
If two sources are requesting an interrupt at the same level during the cycle that the interrupt controller is sampling them, then the one with the higher priority will be run. As the edge port uses the fixed mid-priority (between 3 and 4), your SW2 ISR will be called in preference to your PIT ISR which is at priority 1.
 
That's why your timer stops when you press the switch. When the switch is pressed, there will always be an interrupt source with a higher priority that the PIT ISR (unless you configure the edge port for edge triggered interrupts). If you put the PIT ISR at priority 4 or above it should start working again.
 
It is more difficult to understand why your PIT ISR is never called when it is at level 3. The PIT interrupts are cleared by writing the PIF flag, or by writing the PMR register. The PMR register should only be written when you configure the timer and the PIF flag would be written by your ISR.
 
This all means that once the PIT interrupt has happened it won't be cleared. If your other ISRs at higher levels are constantly requesting then your PIT ISR will never be run, but you should see that the L3IACK register shows your priority 1 PIT interrupt.
 
If the higher level interrupt sources are not constantly asserted (or they aren't being deasserted properly) and you never see priority 1 in L3IACK, it implies that you didn't configure the ISR properly. As you have made it work at level 7, that doesn't really add up.
 
You could try setting it back to level 3, and try reading L3IACK to see if it ever asserts. If it doesn't, you should look for anything that may be resetting the PIT interrupt outside of the PIT ISR.
 
Cheers,
 
Paul.
 
 
 
0 Kudos
Reply

1,126 Views
rwehrli
Contributor I
I happened to figure it out and realized that the
"asm_startmeup" was setting SR to h2700, which was
masking all but the NMIs.

However, does ANYBODY know how to keep this forum
from truncating messages? Or does this only
happen to me? (Truncates them when viewing them)


...this is from the default "stationary" for
the M5211DEMO board choice in CW 6.4

Code:
/*  IMPORTANT

Add to mcf5xxx_vectors.s file

// at the top, below other externs
    .extern _IRQ_PIT0
    .extern _IRQ7_SW2

//vector071: .long asm_exception_handler
vector071: .long _IRQ7_SW2

//vector119: .long asm_exception_handler
vector119: .long _IRQ_PIT0 // 55 + 64

*/


/*
 * File:  main.c
 * Purpose:  sample program
 *
 */
#include "support_common.h"
#include <stdio.h>

#define OSCOPE_MODE 1
#define USE_LEDS 1

static uint16 g_counter = 0;
static uint8 g_sr = 0;

#ifdef USE_LEDS

void leds_display( uint8 value )
{
    MCF_GPIO_PORTTC |= value;
}

void leds_init( void )
{
    MCF_GPIO_DDRTC  = 0x0F; // set to output
    MCF_GPIO_PORTTC = 0x00; // all LEDS off
}

void leds_on( uint8 numLed )
{
    MCF_GPIO_PORTTC |= numLed;
}

void leds_off( uint8 numLed )
{
    MCF_GPIO_PORTTC &= ~numLed;
}

void leds_toggle( uint8 numLed )
{
    MCF_GPIO_PORTTC ^= numLed;
}

#endif

__declspec(interrupt)void IRQ_PIT0( void )
{
#ifdef OSCOPE_MODE   
 MCF_GPIO_SETQS = 0x7F;
    MCF_GPIO_CLRQS = 0x00;
#endif   
    MCF_PIT_PCSR(0) |= MCF_PIT_PCSR_PIF;
}

__declspec(interrupt)void IRQ7_SW2( void )
{
    printf( "IRQ7_SW2 %d\r\n", g_counter++ );
    MCF_EPORT_EPFR |= 0x80;
#ifdef USE_LEDS
    if( g_counter % 2 == 0 )
    {
        leds_toggle(0x0A);
        leds_off( 0x05 );
    }
    else
    {
        leds_toggle(0x05);
        leds_off( 0x0A );
    }
#endif
}

int main(void)
{
#ifdef OSCOPE_MODE

// Set Up The GPIO Pins (connect oscope probe to Pin 19 on J1)

    MCF_GPIO_PORTQS = 0x7F;
    MCF_GPIO_DDRQS  = 0x7F;

#endif

#ifdef USE_LEDS
    leds_init();
#endif

// Set Up The PIT0 IRQ   

    // set the interrupt level IL and the interrupt priority IP
    MCF_INTC_ICR55 = MCF_INTC_ICR_IL(6) | MCF_INTC_ICR_IP(0);

// Set Up the PIT0 Timer
   
    MCF_PIT0_PCSR   = 0;
 MCF_PIT0_PCSR = (uint16)(MCF_PIT_PCSR_PRE(2)); // arbitrary value, 0 is default
    MCF_PIT0_PMR = 0x40; // arbitrary value, 0xFFFF is default

 // Create and enable 'set and forget' timer
 MCF_PIT0_PCSR |= MCF_PIT_PCSR_OVW // overwrite
      |  MCF_PIT_PCSR_PIE // interrupt enable
      |  MCF_PIT_PCSR_PIF // interrupt flag
      |  MCF_PIT_PCSR_RLD // reload (auto)
      |  MCF_PIT_PCSR_DBG // debug bit is set
      |  MCF_PIT_PCSR_EN; // enable timer
   
   
    // Unmask 55 = PIT0 interrupt source
    MCF_INTC_IMRL &= ~(MCF_INTC_IMRL_MASKALL);
    MCF_INTC_IMRH &= ~(MCF_INTC_IMRH_INT_MASK55);

    asm( move.w   #0x2000,   sr ); // enable all priority levels
  
 while( 1 )
 {
        // spin forever
 }
}

 

So much for formatting... oh well, this _should_ work for anyone
with an M5211DEMO board and CW 6.4 using any of the RAM/Flash
target options. "printf" will output to serial port 115.2K/8N1.

Connect an oscilloscope probe to Pin 19 on J1 (needs .100" header
installed first) if you want to "see" the PIT0 interrupt happening.


Take Care.

Rob!
0 Kudos
Reply