DawidPi
Posts: 8
Joined: Fri May 13, 2016 11:18 am

DMA configuration issue

Mon May 16, 2016 2:12 pm

Hi,

I have an issue with raspberryPi2 connected with setting up a DMA and using it. At the beginning I thought, that it's related to the wrong addressing and question has been asked on this forum already.

Code, where I initialize DMA is posted on stack exchange and I post a link below:

http://raspberrypi.stackexchange.com/qu ... -metal-dma

Could anyone please provide me some information on what am I doing wrong?
For those who does not want to use stackexchange I paste a code and some explanation below:

Code: Select all

typedef struct{
    UINT32 controlStatus;
    UINT32 controlBlockAddr;
    UINT32 transferInformation;
    UINT32 sourceAddr;
    UINT32 destAddr;
    UINT32 transferLength;
    UINT32 stride;
    UINT32 nextControlBlock;
    UINT32 debug;
}DMA_Channel;

typedef struct{
    UINT32 transferInformation;
    UINT32 sourceAddr;
    UINT32 destAddr;
    UINT32 transferLength;
    UINT32 stride;
    UINT32 nextControlBlock;
    UINT32 dummy0;
    UINT32 dummy1;
} DMA_ControlBlock __attribute__ ((aligned(32)));

#define PERIPH_BASE (0x3F000000)
#define DMA_OFFSET  (0x00007000)
#define DMA_DIFF    (0x00000100)
#define DMA_CHAN_0  (*((volatile DMA_Channel*)(PERIPH_BASE + DMA_OFFSET)))
#define DMA_ENABLE  (*((volatile UINT32*)(PERIPH_BASE+DMA_OFFSET+0xff0)))
#define DMA_INT_REG (*((volatile UINT32*)(PERIPH_BASE+DMA_OFFSET+0xfe0)))

DMA_ControlBlock dma_controlBlock;

void testDMA(){
    DMA_INT_REG = 0;
    DMA_ENABLE |= 1<<0;

    unsigned long source[100] = {0x00FF00FF, 0x00FF00FF, 0x00FF00FF, 0x00FF00FF, 0x00FF00FF};
    unsigned long dest[100] = {0,0,0,0, 0};

    DMA_CHAN_0.controlStatus |= 1<<31; // reset
    DMA_CHAN_0.controlStatus |= 1<<1;

    dma_controlBlock.transferInformation = 0;
    dma_controlBlock.transferInformation |= 1<<26; // no wide bursts
    dma_controlBlock.transferInformation |= 1<<8; //src incerement
    dma_controlBlock.transferInformation |= 1<<4; //dst increment
    dma_controlBlock.sourceAddr = (UINT32)(&source) | 0xC0000000;
    dma_controlBlock.destAddr = (UINT32)(&dest)| 0xC0000000;
    dma_controlBlock.nextControlBlock =0;
    dma_controlBlock.stride = 0;
    dma_controlBlock.transferLength = 100;
    dma_controlBlock.dummy0 =0;
    dma_controlBlock.dummy1 =0;

    DMA_CHAN_0.controlStatus |= 1<<29; // disdebug
    DMA_CHAN_0.controlBlockAddr = ((UINT32)&dma_controlBlock) | 0xC0000000;
    DMA_CHAN_0.controlStatus |= 1; //start

    while(DMA_CHAN_0.controlStatus & 1<<0){
        hexstring(DMA_CHAN_0.debug);
        hexstring(DMA_CHAN_0.sourceAddr);
    }

    if(dest[2] == source[2]){
        hexstring(0xFFFFFFFF);
    }
    else
        hexstring(0xAAAAAAAA);

    DMA_CHAN_0.controlStatus |= 1<<1;
    while(1);
}
Here hexstring function is function borrowed from DWelch and it puts hex value via UART, so it's usefull for some debugging purposes. I use mapping of the memory properly in terms, that I or it with 0xC0000000.

I would be grateful for any hints on what is going wrong down there.

Thanks,
Dawid :)

Malcolm Lear
Posts: 1
Joined: Wed Jun 06, 2018 3:44 pm

Re: DMA configuration issue

Thu Jun 07, 2018 10:02 am

Hi Dawid,
I've been trying to get DMA working on the SPI interface, so far without success. Having got the SPI working I moved on to the DMA using your neat code. I modified it somewhat to match the style of my existing code but essentially its the same. I initially jumped before walking and tried getting it the work with the SPI, but then went back to your idea of a basic array to array test. It worked fine ))
Having a quick look again, its seems your code is probable working too, but I think:
dma_controlBlock.sourceAddr = (UINT32)(&source) | 0xC0000000;
dma_controlBlock.destAddr = (UINT32)(&dest)| 0xC0000000;
Should be:
dma_controlBlock.sourceAddr = (UINT32)(&source);
dma_controlBlock.destAddr = (UINT32)(&dest);
Now back to the SPI problem.

juj
Posts: 26
Joined: Sat Nov 18, 2017 10:51 pm

Re: DMA configuration issue

Fri Jun 22, 2018 11:18 am

Hi Malcolm,

I recently implemented support for SPI DMA transfers for the Pi, check out https://github.com/juj/fbcp-ili9341/blob/master/dma.cpp for reference. (There are actually two variants, one geared for power saving, another one for performance) The code there does 4-wire SPI, i.e. it flips the Data/Command bits which complicates things a little.

User avatar
Arjan
Posts: 256
Joined: Sat Sep 08, 2012 1:59 pm

Re: DMA configuration issue

Fri Jun 22, 2018 6:16 pm

There is a good example for bare metal SPI DMA here -> https://github.com/rsta2/circle/blob/ma ... terdma.cpp
http://www.raspberrypi-dmx.org/
Open Source DMX/RDM/MIDI/OSC/Art-Net/sACN solutions

Return to “Bare metal, Assembly language”