I'm using ADSP21489. I'm trying to migrate CCES from VDSP++.
Now I have the next problem.
My VDSP++ project use the super-fast interrupt dispatcher (interrupts()) which uses the alternate register set and interrupt nesting is disabled.
I can't understand: What do I need that I get the non-nesting interrupt handler with alternate register set.
I'm stuck. If CCES can't support it I will return back VDSP++
After some investigation, we believe that taking all of the interrupt code from VisualDSP++ 5.0 is just too complicated to port to CCES. Instead, we believe that a simpler solution would be…
1) As the source code says, VDSP saves and changes IMASK in order to provide support for signal(). The signal() function specifies that the handler should only be executed once. In order to…
Kenny, thanks very much for this! It has been very useful to me and I am sure many others.
Kennie's solution works.
Starting with Kennie's code I shaved a few more instruction cycles off of interrupt dispatching. I realize few people are worried about the fastest-possible interrupt, but I wanted to share an outline of it in case it helps anyone else.
(1) Turn off NESTM (no nested interrupts) and compile with -restrict-hardware-loops 3
(2) Use these macros to build IVT:
// XXX - hang for interrupt vectors we do not use. Label the 4 vector instructions for map.xml// INT - save stack and frame pointers (i6 and i7) to SPFP, jump to our custom dispatcher, // do explicit "push sts" [needed for most interrupts], and set to alternate registers.// NB: "push sts" saves ASTATx, ASTATy, MODE1, and masks MODE1 using ~MMASK.// IRQ - like INT macro but without explicit "push sts" [for irq3-0 and core timer interrupts].// NB: Hardware does an implicit "push sts" for irq3-0 and core timer interrupts.#define XXX(irp) .retain_name irp##_ivt; irp##_ivt: JUMP irp##_ivt; nop; nop; nop;#define INT(irp, tgt) .extern tgt; .retain_name irp##_##tgt; irp##_##tgt: \ dm(SPFP) = i6 (LW); JUMP tgt (DB); push sts; bit set mode1 0x04fc; #define IRQ(irp, tgt) .extern tgt; .retain_name irp##_##tgt; irp##_##tgt: \ dm(SPFP) = i6 (LW); JUMP tgt (DB); bit set mode1 0x04fc; nop;
(3) Write dispatchers like this (one is shown for use with INT macro in IVT, another for IRQ):
// These minimal super-fast dispatchers will:// - save the stack and frame pointers// - enable the alternate register set// - set up the alternate stack and frame pointers.// Overhead to enter ISR = 18 CCLK = 5(interrupt sequencer) + 5(ivt) + 8(dispatcher)// Overhead to exit ISR = 4 CCLK
rti_sts: // shared exit for interrupt dispatchers that work with INT macro in ivt rti (db); pop sts; // restore ASTATx, ASTATy, MODE1 (enables primary regs) nop;.rti_sts.end: .type rti_sts,STT_FUNC; .global rti_sts;
PSensorDispatch: .extern _PSensorIsr; //dm(SPFP) = i6 (LW); // done by INT macro (save stack and frame pointers) //push sts; // done by INT macro (save ASTATx,ASTATy,MODE1; modify MODE1) //bit set mode1 0x04fc; // done by INT macro (select alternate registers) //nop; // done by jump delay (mode1 latency) nop; // for silicon anomolies (mode1 latency) i6 = dm(SPFP) (LW); // set alt version stack and frame pointers cjump _PSensorIsr (db); // 2 pipeline stalls (cjump has implicit r2=i6, i6=i7) dm(i7, m7) = r2; dm(i7, m7) = rti_sts-1; // return to rti_sts (executes: rti (db); pop sts; nop).PSensorDispatch.end: .type PSensorDispatch,STT_FUNC; .global PSensorDispatch;
rtcDispatch: .extern _rtcIsr; // unusual dispatcher (via IRQ macro) //push sts; // implicit "push sts" for irq3-0 and core timer //dm(SPFP) = i6 (LW); // done by IRQ macro (save stack and frame pointers) //bit set mode1 0x04fc; // done by IRQ macro (select alternate registers) //nop; // done by IRQ macro (mode1 latency) //nop; // done by jump delay (for silicon anomolies) i6 = dm(SPFP) (LW); // set alt version stack and frame pointers cjump _rtcIsr (db); // 2 pipeline stalls (cjump has implicit r2=i6, i6=i7) dm(i7, m7) = r2; dm(i7, m7) = .ret_rtc-1;.ret_rtc: rti; // implicit "pop sts" done by rti for irq3-0 and core timer.rtcDispatch.end: .type rtcDispatch,STT_FUNC; .global rtcDispatch;