# Microchip PIC24's DMA doesn't work as expected

I am trying to configure the DMA in Microchip's PIC24FJ1024, DMA channel will transfer Data, from Source to Destination, every time the program trigger the DMA Channel.

• One Shot Mode

• SRC increments every transfer

• DST address increments every transfer

• DMACNT0 = 2

I have written this simple code to test the DMA

#include "xc.h"
#include <stdio.h>

#pragma config FWDTEN = OFF

int ArraySRC[100];
int ArrayDST[100];

void DMA_Init (void)
{
DMACONbits.DMAEN = 1;//enable dma
DMACONbits.PRSSEL = 1;//channel priority

DMACH0bits.NULLW = 0;//no dummy
DMACH0bits.RELOAD = 0;//don't reload
DMACH0bits.SIZE = 0;//word

DMACH0bits.SAMODE = 1;//SRC address ++
DMACH0bits.DAMODE = 1;//DST address constant

DMACH0bits.TRMODE = 0;//one shot

DMASRC0 = (int) &ArraySRC;
DMADST0 = (int) &ArrayDST;

DMACNT0 = 2;

DMACH0bits.CHEN = 1;//enable channel
}

int main (void)
{
int i;
for(i = 0; i<100; i++)
{
ArraySRC[i] = i+1;
}
DMA_Init ();

//1st trigger
DMACH0bits.CHREQ = 1;//start transaction
while(DMACH0bits.CHREQ);

//2nd trigger
DMACH0bits.CHREQ = 1;
while(DMACH0bits.CHREQ);

while(1);

return 0;
}


What I expected was, was for every trigger DMACH0bits.CHREQ = 1; the DMA updates the SRC, and DST address, and decrements the DMA Counter DMACNT0.

But when I debug it (using the simulator), the debugger reaches the first trigger, updates the SRC, and DST (I can see it in the variable window), but when it reaches the second trigger, the debugger stops at while(DMACH0bits.CHREQ);, and the DMA Counter remains 1, and doesn't decrement.

Any help would be appreciated.

• Is CHEN still 1 after the first transfer? Jun 22, 2017 at 10:24
• I'd recommend having a look at the simulator's documentation. As I recall, DMA support was buggy for some PICs in the past. Jun 22, 2017 at 12:28
• @Majenko sorry for the late reply, no chen becomes a 0, I added a line of code chen = 1 but still, I get the same problem Jun 23, 2017 at 8:37
• @MathieuL. This might be the case because sometimes the debugger won't move beyond the first trigger. I will read about the simulator's documentation for PIC24, as it is a Beta version, and it doesn't support Peripherals. Jun 23, 2017 at 10:06
• I would suggest using real hardware. I never put any trust in a simulator - even one I wrote myself and understand every single detail of how it works. Silicon is never quite the same. Especially when there are erratas to take into account that won't be in the simulator... Especially when dealing with asynchronous things like DMA. Getting that right in a simulator is a real pain in the rear end. Jun 23, 2017 at 10:24

## 1 Answer

It seems like you are trying to handle two independent operations with the same index. I recommend using i for one and j for the other. Also, I don't see where/how you are decrementing the DMA counter? I would recommend removing the second trigger code and use a decrement command instead. This way you will see if the first trigger works properly. After this works properly, you can add the second trigger code.

• I tried to put it in a while loop, as soon as the debugger steps into DMACH0bits.CHREQ = 1 the DMA0CNT becomes a one instead of a 2 (as I set it), and the problem remains the same Jun 23, 2017 at 14:11