You may be aware of the ydata qualifier which instructs the DSPICC compiler to locate so qualified variables in the ydata data region in RAM. Unfortunately there isn't an equivalent "dma" qualifier which would locate variables in the DMA region of the device. However there are a couple of ways I can think of that one could get the compiler to produce similar results.
1) Use absolute addressing
Firstly one could assign the variables for the DMA region using an absolute address. Consider the following example for a dsPIC33 with 8kB of RAM.
#include
#define DMA_LO 0x2000
#define BUFF_SIZE 256
#define BUFF1_ADDR DMA_LO
#define BUFF2_ADDR (BUFF1_ADDR+BUFF_SIZE)
#define DMA_OFFSET(x) ((int)(x)-DMA_LO)
int buffer1 @BUFF1_ADDR;
int buffer2 @BUFF2_ADDR;
void main (void)
{
DMA0STA = DMA_OFFSET(&buffer1);
DMA1STA = DMA_OFFSET(&buffer2);
while(1);
}
Absolute addressing instructs the compiler to associate the name of the variable with an address. In this case buffer (or rather the symbol _buffer) is equivalent to the address 0x2000 in the data address space. A draw back of this method is that the compiler doesn't allocate any space for such variables. So to ensure that nothing else is linked to this region you'll need to reserve it using the --ram driver option. In this example one might use --ram=default,-2000-27ff. To respect the size of the buffers they should addressed accordingly.
2) Use a new psect
This method takes a little more effort but does have the advantage of allocating space for the variables.
#include
#define DMA_LO 0x2000
#define DMA_OFFSET(x) ((int)(x)-DMA_LO)
asm("psect dma, space=1, size=800h");
#pragma psect nearbss=dma
int buffer[128];
void main (void)
{
DMA0STA = DMA_OFFSET(buffer);
while(1);
}
In this instance with the same device as before we create a new psect, dma equal in size to the DMA region. Before we declare variables for the DMA region we employ a #pragma psect directive. Since the buffer is uninitialised and all variables are by default near it would normally be assigned to the nearbss psect. The #pragma psect directive employed will redirect those objects after it which would normally appear in the nearbss psect (viz. our buffer) to the dma psect. If an alignment for following variables needs to be respected then you could pad out the size of the buffer to the next alignment boundary. To complete this method we finally need to instruct the linker via the driver using the -L option to link the dma psect to the bottom of the DMA region, e.g. -L-pdma=2000h.
--------------------
Andrew Lanham,
Microchip Technology