Page 1 of 2
(Solved) Interrupt problems - again - Catweasel this time.
Posted: Sun Jun 30, 2013 1:40 pm
by Spirantho
Hi everybody.
I've got to the point in my SID player that I want to use the Catweasel's IRQ.
Calling this:
Code: Select all
gInterruptNumber = tPCIDevice->MapInterrupt();
gInterrupt = (struct Interrupt *)IExec->AllocSysObjectTags( ASOT_INTERRUPT,
ASOINTR_Size, sizeof( struct Interrupt ),
ASOINTR_Code, (APTR)handler,
TAG_END
);
IExec->DebugPrintF("Setting handler to %p.\n", handler );
gInterrupt->is_Code = (void (*)() )handler;
gInterrupt->is_Node.ln_Succ = 0;
gInterrupt->is_Node.ln_Pred = 0;
gInterrupt->is_Node.ln_Name = (char *)"Catweasel SID FIFO Interrupt Handler";
gInterrupt->is_Node.ln_Pri = -1;
gInterrupt->is_Node.ln_Type = NT_EXTINTERRUPT;
tIntSuccess = AddIntServer( gInterruptNumber, gInterrupt );
I think this should work. gInterruptNumber is 66, which I believe is correct for my Sam440ep. "handler" is just a routine that returns 0, so it should have no effect whatsoever. What it actually does, however, is crash my Sam hard, such that C+A+A doesn't work, and I need to hard reset.
If I unmask the interrupts, it runs perfectly. As soon as I allow interrupts to trigger - BOOM.
Can someone please tell me what I'm doing wrong? Surely setting an interrupt handler for the hardware to a function that does nothing should just do.. nothing?
Many thanks for any help - Interrupts have been the scourge of my OS4 experience so far, everything seems nice until I try and use interrupts and then it all goes pear-shaped.
System is a Sam 440ep 600MHz, AOS 4.1u6, Catweasel Mk4.
Re: Interrupt problems - again - Catweasel this time.
Posted: Sun Jun 30, 2013 7:13 pm
by LyleHaze
I am just beginning to understand these myself, so anything I say might be wrong.
Hardware interupts are often shared by different devices. If I understand this correctly,
the very first thing to do in your interrupt code is to check your hardware.
If your hardware did NOT cause the interrupt, return Zero.
If your hardware DID cause the interrupt, handle it, then return Non-Zero.
If you return zero, it moves down the interrupt chain until it finds the correct handler.
Lots more information at the Wiki
http://wiki.amigaos.net/index.php/Exec_Interrupts
Good Luck!
Re: Interrupt problems - again - Catweasel this time.
Posted: Sun Jun 30, 2013 7:24 pm
by Spirantho
Thanks for the pointer!
That - like all the other examples I can find - seems to deal with software interrupts, or at least non-peripheral ones. I need an example which deals with a proper hardware interrupt, though.
From what I understand I'm doing it correctly - calling MapInterrupt (which works fine) and then assigning a handler to that interrupt number... but when the interrupt line actually triggers ,*kaboom* - hard reset required.
I did get the interrupts basically working on the Bt8x8 TV card drivers ages ago, but they'd randomly lock-up the machine solid. This time, though, it just locks the machine up anyway.
I will take a longer look through that webpage, but I'm not sure it contains the answer. Thanks anyway (and if you have success with interrupts, I'd be interested to hear about it!

)
Re: Interrupt problems - again - Catweasel this time.
Posted: Sun Jun 30, 2013 7:36 pm
by LyleHaze
I checked the routines that handle the hardware interrupt for the X1000 hdaudio driver before I replied.
What I described is working there.
This is just slightly cut down:
Code: Select all
uint32 CardInterrupt(struct ExceptionContext *pContext UNUSED, struct ExecBase *sysBase UNUSED, struct CardData *card)
{
//... variables declaration here..//
// 2 other PCI Devices share our Interrupt Nr
intreq = PCI_ReadLong( card, HD_INTSTS ); // HD_INSTS is the interrupt register for hdaudio
if (( intreq & HD_INTCTL_GLOBAL ) == 0 ) // GLOBAL is true if ANY interrupt from the card is active
{ // if it's not for us, return zero
return(0);
}
// if it is for us, return NOT zero, or True, or anything BUT zero, after it is handled
// might be a good idea to handle the interrupt and reset the intreq in hardware first.
Good Luck!
Re: Interrupt problems - again - Catweasel this time.
Posted: Sun Jun 30, 2013 8:00 pm
by Spirantho
Thanks (again) but I'm still not sure.
I have it mapped as int number 66. That's isolated to the card, as far as I can see...? So if I always return 1, it should "work" (i.e. it'll not do anything, as there's no code) but not crash. Equally, if I always return 0, it should "work" (it won't do anything, it'll just fall off the end off the interrupt queue for this interrupt number).
Whatever happens, it definitely shouldn't cause a hard lock-up.
Do you have any idea what might be causing this?
Re: Interrupt problems - again - Catweasel this time.
Posted: Sun Jun 30, 2013 8:22 pm
by LyleHaze
Your return value is used to "steer" the interrupt code correctly.
Your code is supposed to return non-zero if the interrupt was from the catweasel and it has been handled.
If you just return a zero in this case, then two bad things happen:
The system continues to look for the correct interrupt handler, which it will not find.
At the end of that search, the interrupt is still active, so it will repeat the search.
Since interrupt handling is a higher priority than tasks, this would result in a lockup.
Your code is supposed to return a Zero if the interrupt is NOT from the catweasel.
If you return a non-zero in this case, then the search for the "right" interrupt handler ends WITHOUT any code to reset the interrupt, and so the interrupt is still active and the search is repeated.
Since interrupt handling is a higher priority than tasks, this would result in a lockup.
So, if you're not ready to recognize whether the interrupt is really yours AND do whatever it takes to
de-assert the interrupt when it is, then you're going to lock up a lot.
Again, I'm new at this, so I may be wrong. But if you see a hole in my logic please let me know!
Re: Interrupt problems - again - Catweasel this time.
Posted: Sun Jun 30, 2013 8:26 pm
by LyleHaze
I used to wonder what would happen if two "shared" interrupts fired at exactly the same time.
Since the first one would "cancel" the search, how would the second interrupt get serviced?
Now I understand.. the first handler would return non-zero, and the interrupt would STILL be active, because the second one has not been serviced yet.. so it would just run the chain of interrupt handlers again.
Thanks for explaining that for me!

Re: Interrupt problems - again - Catweasel this time.
Posted: Mon Jul 01, 2013 1:07 am
by tonyw
You must "service" the interrupt - that is, cancel the hardware request state. If you don't, the hardware will interrupt again immediately you return from the interrupt, with the lockup that you are seeing.
Otherwise, what Lyle says is gold.
Re: Interrupt problems - again - Catweasel this time.
Posted: Mon Jul 01, 2013 9:21 am
by Spirantho
That worked! Thanks so much!
I've now got the Catweasel filling the SID FIFO stack, playing and only re-filling the stack when it's half-empty (the IRQ). At the moment it's a simple Delay() loop, but next step will be to have the interrupt message the stack-filling routine so it's all nice and OS clean. It's pretty awesome to have the CW SID chip playing happily without any slow-down or eating up CPU time!
I think I may have to re-visit my TV card drivers now, too. I never realised that you
had to service the interrupt, but I suppose it makes sense.
It would be worth putting this clearly in documentation though - I always thought that if you didn't service the interrupt it'll just fall off the bottom of the chain rather than keep trying and cause a hard lock-up (and of course its crashing hard didn't make it easy to debug!).
Thanks again! I just wish I'd known more about interrupts when I did the TV card drivers years ago.
Re: Interrupt problems - again - Catweasel this time.
Posted: Mon Jul 01, 2013 11:02 am
by LyleHaze
Glad you got it working!
I am quite new to a lot of this as well.
I've done a fair bit with microcontroller interrupts, but those are MUCH simpler than what we play with here.
As far as AmigaOS, I am definitely learning more every day.
Spirantho:
If you have a minute to spare, could you add (Solved) to the topic line please?
I guess it doesn't matter much, but I'm always happy to see good news when scanning a list of problems.
Otherwise, what Lyle says is gold.
You are being quite generous.
I am happy if it's just shiny brass.
