MOD54415 IRQ Issue / NNDK 2.7.7

Discussion to talk about software related topics only.
Post Reply
DBrunermer
Posts: 67
Joined: Thu Apr 21, 2011 7:06 am
Location: Pittsburgh, PA

MOD54415 IRQ Issue / NNDK 2.7.7

Post by DBrunermer »

I'm trying to configure IRQs 1, 2, and 3 as edgeport irq, positive edge trigger, priority/level not important. I began to think I was using the included functions for this incorrectly, so I decided to just write my own configuration section. Please excuse the long setup to the question.

Code: Select all

	
	// Before I begin configuring the edge ports, I'm going to disable the interrupts in epier
	sim2.eport.epier &= 0x31; // Just disable IRQ1, 2, 3, 6, and 7
	// I'm also going to clear/acknowledge any pending ints
	sim2.eport.epfr = 0xCE; // Clear ints 1,2,3,6,7
	// 30 JAN 2018 EDIT - Adding manual pin control for IRQ1, 2, and 3, IRQ6,7 set to output.
	// I will program IRQ7 and 6 for GPIO, Outputs, off. IRQ1, 2, and 3 to IRQ.
	// In general, 11 = primary, 10 Alt 1, 01 Alt 2, 00 GPIO in par_ registers
	sim1.gpio.par_irq0h &= 0x0F; // Keep IRQ 4 just in case, IRQ7 GPIO
	sim1.gpio.par_irq0h |= 0x03; // Make IRQ 1 the edge port pin
	sim1.gpio.par_irq0l = 0x3C; // Make IRQ2, 3 INTS, IRQ6 GPIO
	// Set IRQ6 and 7 as GPIO outputs, and turn off
	sim1.gpio.pddr_c |= 0x60; // That makes them outputs Recall: IRQ6<->PC.5 ; IRQ7<->PC.6
	// Now to make sure the IRQ123 and inputs, while not changing IRQ4
	sim1.gpio.pddr_c &= 0xF1; // Clear bits 1, 2, and 3 to make inputs. Just in case
	// Keep in mind, as far as PORT ID is concerned, IRQ6 is PORTC.5, IRQ7 is PORTC.6
	sim1.gpio.pclrr_c = 0x6E; // That also turns off IRQ1, 2, and 3, but I don't know that it does anything
	vector_base.table[65] = (long)&FireDoneDummy; // Just so  it doesn't dump, set up some dummy 65=IRQ1
	vector_base.table[66] = (long)&DataDoneDummy; // interrupt handlers 66 = IRQ2
	vector_base.table[67] = (long)&SyncEncDummy; // 67 = IRQ3
That first part was (obviously) just the pin multiplex control. Next I configure the edgeport registers proper:

Code: Select all

	// Clear any pending interrupts
	sim2.eport.epfr = 0x0E;
	// Set direction as input, this time in EPDDR
	sim2.eport.epddr &= 0xF1; // 1,2,3 in
	sim2.eport.epddr |= 0xC0; // 6,7 out
	sim2.eport.epdr &= 0x3F; // Clear 6,7
	// Set Rising Edge Trigger
	sim2.eport.eppar &= 0xFF03; // Clear old setting
	sim2.eport.eppar |= 0x0054; // All 3 to pos edge trig
	// Clear any pending interrupts
	sim2.eport.epfr = 0x0E;
	// Set the levels like the examples
	sim2.intc[0].icrn[1] = 0x01;
	sim2.intc[0].icrn[2] = 0x02;
	sim2.intc[0].icrn[3] = 0x03;
	// Mask off the Data Done IRQ2, as software will poll the flag
	sim2.intc[0].simr = 0x04; // Mask 2
	sim2.intc[0].cimr = 0x02; // Unmask 1
	sim2.intc[0].cimr = 0x08; // Unmask 3
In real operation, IRQ2's flag is actually polled, but that's not germane. My interrupts:

Code: Select all

INTERRUPT( FireDoneDummy, 0x2100)
{
	printf("f");
	sim2.eport.epfr = 0x02; // Clear IRQ 1
	return;
}
INTERRUPT( DataDoneDummy, 0x2200 )
{
	// Clear the register
	printf("d");
	sim2.eport.epfr = 0x04; // Clear IRQ 2
	return;
}
INTERRUPT( SyncEncDummy, 0x2300 )
{
	printf("e");
	sim2.eport.epfr = 0x08; // Clear IRQ3
	return;
}
OK, so that's my setup. Here's what happens. IRQ1 and IRQ3 never get caught, but IRQ2 does. If I set the mask for IRQ2, the interrupt doesn't happen, but the edge port flag does get set. If I clear the mask for IRQ2, the interrupt does fire. With 1 and 3, no matter what I do, I can't get the interrupt to fire. If I cause the interrupt driver to generate a pulse, the correct bit does get set and latched in epfr, but it won't propagate through to an interrupt routine. I've watched it all on my oscilloscope, and it looks good.

And it seems to be independent of level. I could use 0x2100-0x2700 for IRQ1 and 3, and it doesn't help. Likewise, I can assign IRQ2 to anything, and it always works. I'm hoping I'm just being a dunce and missing something obvious.
Thanks for your help, Dan B.
User avatar
TomNB
Posts: 538
Joined: Tue May 10, 2016 8:22 am

Re: MOD54415 IRQ Issue / NNDK 2.7.7

Post by TomNB »

Have you tried running the ExternalIrq example program? It shows how to run IRQs 1, 2, 3 and 6.
I would avoid ever using a printf in an ISR. Anything in there should complete in the range of microseconds. Many people even avoid function calls of any kind. Instead you could use a flag or counter, then access those variables outside of the ISR.
User avatar
pbreed
Posts: 1080
Joined: Thu Apr 24, 2008 3:58 pm

Re: MOD54415 IRQ Issue / NNDK 2.7.7

Post by pbreed »

printf in IRQ will crash the system.


On the 54415 use the macros in

#include <intcdefs.h>

To make sure your setting the correct intc controller (there are 2)

SETUP_IRQ1_EDGEPORT1_ISR(f,l) SetIntc(0,(long)f,1,l)
SETUP_IRQ2_EDGEPORT2_ISR(f,l) SetIntc(0,(long)f,2,l)
SETUP_IRQ3_EDGEPORT3_ISR(f,l) SetIntc(0,(long)f,3,l)
SETUP_IRQ4_EDGEPORT4_ISR(f,l) SetIntc(0,(long)f,4,l)
SETUP_IRQ5_EDGEPORT5_ISR(f,l) SetIntc(0,(long)f,5,l)
SETUP_IRQ6_EDGEPORT6_ISR(f,l) SetIntc(0,(long)f,6,l)
SETUP_IRQ7_EDGEPORT7_ISR(f,l) SetIntc(0,(long)f,7,l)
DBrunermer
Posts: 67
Joined: Thu Apr 21, 2011 7:06 am
Location: Pittsburgh, PA

Re: MOD54415 IRQ Issue / NNDK 2.7.7

Post by DBrunermer »

Hi Tom, thanks for replying. I just want to mention the real functions don't do that. I have a specialized debug command that tests the IRQs individually, and it's only there so I can see something happened. Originally, the test functions kept all of the interrupts masked, and I just had a tight while() loop with a timeout that tested for the epfr bit being set. That's why I thought everything was going pretty well. I figured if my configurations were wrong, I'd never get the flag, so I'd have to keep trying. When I was getting epfr, I tried unmasking them for the dummy functions, and that's when only the dummy attached to IRQ2 would fire.

The answer to your other question is a little more complicated. When I first started writing this part of the program, what I did was copy and paste the lines from the IRQ Example program in one of the other threads. I think it's the one you're talking about. It was the main.cpp file in MOD54415-ExternalIRQ.zip; it was a post from NB. So I used those calls with my functions, without the IRQ6 stuff of course, and the output. None of that was working, so I decided to dig deeper into the library files to see exactly what NB was doing behind the scenes. I took that code and brought it all out like I have laid out in my post. Again, except where changes made sense for my specific application.

But I must admit somewhere along the way I would find areas of the CPLD that drives these IRQS wouldn't be functioning right either, and I had a bunch of bugs to undo there. Maybe I gave up on the library functions too early. I'll try commenting out my code and doing it like that file again. I'm pretty confident in the CPLD at this point, so yeah, maybe I'll try that again.

Thanks, Dan B.
DBrunermer
Posts: 67
Joined: Thu Apr 21, 2011 7:06 am
Location: Pittsburgh, PA

Re: MOD54415 IRQ Issue / NNDK 2.7.7

Post by DBrunermer »

Thanks, pbreed, I'll try that and get back. - Dan B.
DBrunermer
Posts: 67
Joined: Thu Apr 21, 2011 7:06 am
Location: Pittsburgh, PA

Re: MOD54415 IRQ Issue / NNDK 2.7.7

Post by DBrunermer »

One thing about that example program. Why doesn't EdgeportISR() have to be defined in the INTERRUPT macro? - Dan B.
DBrunermer
Posts: 67
Joined: Thu Apr 21, 2011 7:06 am
Location: Pittsburgh, PA

Re: MOD54415 IRQ Issue / NNDK 2.7.7

Post by DBrunermer »

Ok, this has gotten me closer. I took out all of my init stuff, and replaced it with some simple stuff:

Code: Select all

SetPinIrq( 26, 1, &SyncEncDummy);  // IRQ 3
SetPinIrq( 43, 1, &DataDoneDummy);  // IRQ 2
SetPinIrq( 45, 1, &FireDoneDummy);  // IRQ 1
J2[47].function( PINJ2_47_GPIO );
J2[47] = 0;
And now, for the most part, it all seems ok, so thanks! A quick caveat, though. I found that if I had to call SetPinIrq more than once, it would generate a few spurious interrupts. I suspect that it's because clearing the eppar register during setup allows the epfr flag to be set when the IRQ line is low (which mine is). So I wound up doing an external declare of TheIrqFuncs[], and I just remap directly when I need to. I think I can move on to more complete testing now.

Thanks again, Dan B.
User avatar
TomNB
Posts: 538
Joined: Tue May 10, 2016 8:22 am

Re: MOD54415 IRQ Issue / NNDK 2.7.7

Post by TomNB »

SetPinIRQ is an initialization function that is designed to only be called one time. Why would you need to call it more than once? The example was created to run in the dev board and uses a gpio to trigger the interrupts, so if you use it connected to your cpld you may need to make modifications.
DBrunermer
Posts: 67
Joined: Thu Apr 21, 2011 7:06 am
Location: Pittsburgh, PA

Re: MOD54415 IRQ Issue / NNDK 2.7.7

Post by DBrunermer »

Like I say in my post, there are occasions where I need the handler pointed at one function, like say a diagnostic and testing function, but other cases where I need it tied to a different function that's more application specific, all within one program. But like I say, it's working now, so, cool. Thanks again, Dan B.
Post Reply