Accessing gpio via the DSP

I see a few discussions on this list about accessing the gpio pins using the DSP. Unfortunately I didn’t find any solutions, so I’m trying to figure it myself.

Here is some sample code that reads the push button from the DSP. Here are my notes on trying to get the sample code to work.

When compiling using c6runapp I get an error saying HWI_enableWugen is undefined. If I comment out the offending line, the code compiles and runs, but doesn’t respond to the push button.

Does anyone have a simple example that shows how to access gpio from the DSP?
Can anyone suggest how to fix the code I already have?



Ah.. Wugen. That one can be a bit confusing, It took me half a week to
get that beast working.

The Wugen module acts as a filter between extern events (interrupts and
dma requests) and the DSP. If you want to handle interrupts or DMA
events on the DSP you have to first enable them in the wugen (only
applies to some interrupt sources though).

I have working code that enables DMA-events. It should be easy to change
the code to use the WUGEN_MEVTCL0/WUGEN_MEVTCL1 registers to route the
interrupts into the DSP.

Note that the WUGEN can only manage 64 interrupts but the DSP has more
than this. You have to apply an offset of 45 to the masks to enable an
event. The first 45 events are internal to the DSP and can't be
controlled by the WUGEN.

E.g. if you want to enable event 73 (gpio-1) the event-ID within the DSP
is still 73, but the corresponding bit in the WUGEN is (73-45) = 28.

To enable this event set the bit (1<<28) in the register WUGEN_MEVTCL0.

I haven't tried that with interrupts yet, but chances are good that it
will work.

Good luck.

#define WUGEN_BASE 0x01c21000

#define WUGEN_REVISION 0x0000 // revision register
#define WUGEN_SYSCONFIG 0x0008 // submodule config (clocks ect.)
#define WUGEN_MEVT0 0x0060 // Interrupt Mask Status [0..31]
#define WUGEN_MEVT1 0x0064 // Interrupt Mask Status [32.63]
#define WUGEN_MEVT2 0x0068 // DMA Request Mask Status [0..19]
#define WUGEN_MEVTCL0 0x0070 // Interrupt Mask Low Clear
#define WUGEN_MEVTCL1 0x0074 // Interrupt Mask High Clear
#define WUGEN_MEVTCL2 0x0078 // Dma Request Mask Clear
#define WUGEN_MEVTSET0 0x0080 // Interrupt Mask Low Clear
#define WUGEN_MEVTSET1 0x0084 // Interrupt Mask High Clear
#define WUGEN_MEVTSET2 0x0088 // Dma Request Mask Clear
// there are more registers in WUGEN. (pending masks...)

#define reg32w(b, r, v) (*((volatile unsigned int *)((b)+(r))) = (v))

// exampe code for DMA Wugen control:

void util_wugen_enabledma_event (unsigned evt)
  reg32w (WUGEN_BASE, WUGEN_MEVTCL2, 1<<evt);

void util_wugen_disabledma_event (unsigned evt)
  reg32w (WUGEN_BASE, WUGEN_MEVTSET2, 1<<evt);