13.4.8.2 One-Shot Mode

In One-Shot mode (TRMODE[1:0] = 00), a single transfer (from DMAxSRC to DMAxDST) is performed for each trigger event. By default, the Reset value of DMAxCNT is 0001h. When a single One-Shot transfer occurs, DMAxCNT is decremented to 0000h; this disables the channel and requires the channel to be re-enabled to perform the next transaction. Of course, it is also possible to store a larger value in DMAxCNT and then conduct a defined number of One-Shot transfers.

Typical Code Sequence for a One-Shot Transfer shows a typical code sequence for a One-Shot transfer.

Typical Code Sequence for a One-Shot Transfer

uint8_t SRC[4];
uint8_t DST[4];
int i;

int main()
{
    for (i = 0; i < 4; i++) {
        SRC[i] = i + 1;  //fill with i+1
        DST[i] = 0;      //fill with 0
    }
    
    DMACONbits.ON = 1;
    DMACONbits.PRIORITY = 1;
    DMALOW = 0x4000;
    DMAHIGH = 0x7FFF;                   //set lower and upper address limit
    DMA0SRC = (unsigned int) SRC;       //load the source address
    DMA0DST = (unsigned int) DST;       //load destination address
    DMA0CNT = 4;                        //Four transfers to be done
    DMA0CH = 0;
    DMA0CHbits.SAMODE = 1;              //Source address increment mode
    DMA0CHbits.DAMODE = 1;              //Destination address increment mode
    DMA0CHbits.TRMODE = 0;              //One-Shot Transfer mode
    DMA0CHbits.CHEN = 1;                //Enable channel
    IFS2bits.DMA0IF = 0;
    DMA0CHbits.CHREQ = 1;               //First trigger
    while (DMA0CHbits.CHREQ);
   
    DMA0CHbits.CHREQ = 1;               //Second trigger
    while (DMA0CHbits.CHREQ);
   
    DMA0CHbits.CHREQ = 1;               //Third trigger
    while (DMA0CHbits.CHREQ);           //HALF=1 since DMACNT is at halfway point
    
    DMA0CHbits.CHREQ = 1;               //Fourth trigger DMACNT=0 and transfer complete
    while (DMA0CHbits.CHREQ);
    
    while (!DMA0STATbits.DONE);         //Transfer Complete
    
    //DMA0IF=1 ,DONE=1, CHEN=0;
    IFS2bits.DMA0IF = 0;
    DMA0STATbits.DONE=0;
    DMA0STATbits.HALF=0;
    
    while (1);
}