Can't get INT6 on MOD5272 to trigger

Discussion to talk about software related topics only.
Post Reply
User avatar
tod
Posts: 587
Joined: Sat Apr 26, 2008 8:27 am
Location: Southern California
Contact:

Can't get INT6 on MOD5272 to trigger

Post by tod »

For the first time I need to use INT6 on the MOD5272. I'm using interrupts 1,3 and 5 with no problem. I set INT6 to level 6 and set up the vector table but I don't get any interrupts. (I'm toggling the input line so even if the rising/falling polarity is off I should get one).

Reading the manual it says on Table 17-3
"Configure pin M3. If this pin is programmed to function as INT6, it is not available as a GPIO."
and later
"INT6 is always available on pin M3. It can be enabled by programming the appropriate bits in interrupt
control register 4, see Section 7.2.2.4, “Interrupt Control Register 4 (ICR4), and the programmable
interrupt transition register described in Section 7.2.4, “Programmable Interrupt Transition Register
(PITR)."

So I think I'm doing all this but I can't get an interrupt. I'm wondering if since INT6 is on a pin that's shared if there is something special I need to do for INT6 that I don't have to do for the other interrupts.

Also I've always been unclear on the hex value passed to the interrupt routine, I thought 0x21 represent priority 1, through 0x26 for priority 6. Are there rules on these values and how you set up other things in the interrupt?

Here are snippets of the code I'm using for INT6 - these were cut and pasted from various places.

Code: Select all

//CONSTANTS FOR IRQ6
const unsigned long RISING_EDGE_BIT_INT6 = 0x00000020L; //Bit 5 of 31
//IRQ 6 is on icr4 and it is one BYTE down from the msb. make it level 6 by writing 1110 (0E)
const unsigned long DISABLE_IRQ6 = 0x00800000L;
const unsigned long ENABLE_IRQ6 = 0x00E00000L; // put irq 6 at priority 6 (write 1110 in the correct nibble)
const unsigned long IRQ6_MASK = 0x00F00000L;
const int IRQ6_OFFSET = 91;


    INTERRUPT(ext_trig_isr, 0x2600 )
    {
        Interrupts::DisableInterrupt6();
        OSSemPost(&Interrupts::m_pendExtTrig);
    }

   void Interrupts::Init()
   {
     ...
        OSSemInit(&m_pendExtTrig, 0);
        vector_base.table[IRQ6_OFFSET] = reinterpret_cast<unsigned long>(ext_trig_isr);
        SetExtTrigEdge(extTrigIsRising);
        EnableInterrupt6();
   ...
    }

     void Interrupts::EnableInterrupt6()
    {
        sim.icr4 = ((sim.icr4 & ~IRQ6_MASK) | ENABLE_IRQ6);
     }

    void Interrupts::SetExtTrigEdge(bool isRising)
    {
        if (isRising) sim.pitr |= RISING_EDGE_BIT_INT6;
        else sim.pitr &= (~RISING_EDGE_BIT_INT6);
    }
Ridgeglider
Posts: 513
Joined: Sat Apr 26, 2008 7:14 am

Re: Can't get INT6 on MOD5272 to trigger

Post by Ridgeglider »

Tod here is my understanding. That said, if other situations are any indicator, you know way more about this...

Code: Select all

INTERRUPT (EportFlag1_ISR, 0x2600) {
     sim.eport.epfr = 0x40; // clear the IRQ flag bit, bit 6
     // now do your ISR code below
     // YOUR code here
}
The 0x2600 would set the SR register. 0x2600 means that all IRQs below level 7 (yes 7) will be blocked when the ISR runs. Note that you could use 0x2700 here but it would have the same effect of blocking all IRQs below level 7 while this ISR runs. The value "6" in the "0x2600" MUST not be LOWER than the LEVEL of the interrupt specified in the Setintc() function call. Note that IRQs 1-7 are so called EXTERNAL IRQs and have no flexibility with respect to having programmable level or priority. In this case then IRQ6 will always be a Level 6 IRQ, and, because it is an external IRQ, it will also have the odd fixed prio described as "mid" at "3-4". (On the 5270, see the Freescale Ref Manual Table 13-1 for details.)

Next, set up the interrupt controller using the Setintc() function.

Code: Select all

Setintc( (long) &EportFlag6_ISR,
     6,     // Entry point in the vector table. This must be 6 for IRQ6.

     6,     // LEVEL, in this case, because the IRQ is an external IRQ, 
            // I think you can enter any value 1-6 but the level
            //  will be forced to 6, the IRQ number. In the case of the internal IRQs
            // (#8-63) this value can be programmed from 1-6. That wallows you to adjust 
            // the importance of the internal interrupts. Not possible for #1-7 though. 

     1 );  // PRIO. Once again, I think you can enter any value here,
            // and , because we're configuring an EXTERNAL
            // IRQ, the PRIO will be forced to that odd "3-4" value. For
            // internal IRQs (eg #8-63) this PRIO value could be programmed as 0-7.
Maybe this helps?
User avatar
tod
Posts: 587
Joined: Sat Apr 26, 2008 8:27 am
Location: Southern California
Contact:

Re: Can't get INT6 on MOD5272 to trigger

Post by tod »

Thanks for the response. I wasn't aware of the Setintc() function, so it did remind me that I should check the NetBurnerRuntimeLibraries manual, which did include the explanation you provided about the masking purpose of the 0x2600. I don't think that should be affecting me adversely as the sequence of these four interrupts is very synchronous.

Unfortunately SetIntc() doesn't appear to apply to the 5272, but even though I have the libs for a 5270 I still don't see which include file contains this function. Where does this thing live? (Mostly curious for future projects that use a MOD that does support it). I seem some sample code where a manual forward reference is created for it. Does it live in some .a or .o file only? It seems to be a bit special.

The manual also talks about other higher level functions I was unaware of SeetPinIrq(), EnableIrq(), and DisableIrq(), unfortunately my excitement was short-lived as these functions only support the IRQs I already having working the old-fashioned way namely 1, 3 and 5. They seem to explicitly exclude INT6. More evidence that makes me think there must be something special about INT6, and something I'm missing. Sure would have been nice if this manual had mentioned why INT6 was excluded and how we were supposed to use it.

As near as I can tell from the parameters to SetIntc() it serves (at least partially) the same function as setting up the correct value in the vector_base_table array and setting the Enable flag. Since I'm setting vector_base_table by hand and setting the pitr and Enabling the interrupt that's all I'm aware of that I have to do. When I specify the Enable mask I do specify a value of 6 so I would think that would be compatible with the 0x2600.
Ridgeglider
Posts: 513
Joined: Sat Apr 26, 2008 7:14 am

Re: Can't get INT6 on MOD5272 to trigger

Post by Ridgeglider »

Hi Tod:
Let me once again say that I'm unfamiliar w/ the 5272, so everything I said may not apply. However, I've used the the Setintc() function on the 5270, '34, '82, and (I think the 5213) so just assumed it was also available on '72. (The function is a bit different on the '82 because the interrupt controllers is different there too).

Here's where I found out about Setintc(). A similar Appnote is on the page for most of the core modules:
http://www.netburner.com/downloads/mod5 ... rrupts.zip
Unfortunately the Setintc() code is buried in c:\nburn\lib\Mod5270.a

However a similar appnote is not on the 5272 page. Instead there is:
http://www.netburner.com/downloads/mod5 ... xample.zip
which DOES NOT mention Setintc.

Looks like I led you astray.
Worth knowing about on the other modules though...
User avatar
Forrest
Posts: 289
Joined: Wed Apr 23, 2008 10:05 am

Re: Can't get INT6 on MOD5272 to trigger

Post by Forrest »

The 5272 does not have the setintc functions, so you have to set up everything manually.

I wrote an example on this for Tod in support and thought it would be good to place here as well.

Code: Select all

/*
 * author Forrest Stanley
 *
 * This example demonstrates how to enable and use IRQ6 as a level 6 interrupt on a MOD5272.
 *
 * Hardware Setup:
 * 	Tie J2[20] to J2[48]. This example toggles the GPIO J2[20] to trigger external interrupts on J2[48]
 *
 */

#include "predef.h"
#include <stdio.h>
#include <ctype.h>
#include <startnet.h>
#include <autoupdate.h>
#include <dhcpclient.h>
#include <NetworkDebug.h>
#include <sim5272.h>
#include <ucos.h>
#include <cfinter.h>
#include <pin_irq.h>
#include <pins.h>


extern "C" {
void UserMain(void * pd);
}

const char * AppName="irq6";

volatile DWORD isr_counter = 0;

INTERRUPT(example_isr,0x2600 ) {
	sim.icr4 |= (0x08 << 20 ); // Clear the IRQ6 Interrupt
	isr_counter++;

}

void UserMain(void * pd) {
    InitializeStack();
    if (EthernetIP == 0) GetDHCPAddress();
    OSChangePrio(MAIN_PRIO);
    EnableAutoUpdate();

    #ifdef _DEBUG
    InitializeNetworkGDB_and_Wait();
    #endif

    // Set IRQ6 to Rising Edge Trigger (Freescale Manual 7.2.4)
    sim.pitr |= ( 0x01 << 5);

    // Set location of Interrupt service routine (Freescale Manual 7.2.6)
    vector_base.table[91] = (unsigned long) &example_isr;

    // Enable IRQ6 and set to interrupt level 6 (Freescale Manual 7.2.2.4)
    sim.icr4 = 0x0E << 20;

    iprintf("Application started\n");
    while (1) {
        OSTimeDly(5);
        J2[20] = 0;
        OSTimeDly(5);
        J2[20] = 1;
        OSTimeDly(5);
        iprintf("Interrupt Count: %d\r",isr_counter);
    }
}

Forrest Stanley
Project Engineer
NetBurner, Inc

NetBurner Learn Articles: http://www.netburner.com/learn
User avatar
tod
Posts: 587
Joined: Sat Apr 26, 2008 8:27 am
Location: Southern California
Contact:

Re: Can't get INT6 on MOD5272 to trigger

Post by tod »

A HUGE thank you to Forrest for this. It turns out the code I posted was fine and indeed was working. My testing methodology was flawed. The interrupt was indeed firing and I was even getting the posted semaphore but in my while loop (which of course I didn't post) I was doing the equivalent of this

bool make_rookie_mistake = true;
while (make_rookie_mistake )
{
bool make_rookie_mistake = false; //oops
HitHeadAgainstWall(); //
}

Ridge - I also appreciate your response, I did download and read up more about the SetIntc() function. Nice to know it's only in the library, another mystery solved. That explains the need for the forward reference and my inability to find the source code.
Ridgeglider
Posts: 513
Joined: Sat Apr 26, 2008 7:14 am

Re: Can't get INT6 on MOD5272 to trigger

Post by Ridgeglider »

Tod: I found SetIntc() source in the platform system directory, eg: C:\nburn\MOD527\system\BSP.c
User avatar
tod
Posts: 587
Joined: Sat Apr 26, 2008 8:27 am
Location: Southern California
Contact:

Re: Can't get INT6 on MOD5272 to trigger

Post by tod »

Ah mystery solved, thanks I think I was searching the general system directory. Looking at the source makes it clear why it only works for the 5270 and not the 5272.
Post Reply