13.4.8.3 Repeated One-Shot Mode

In Repeated One-Shot mode (TRMODE[1:0] = 01), single transfers occur repeatedly as long as triggers are being provided or CHREQ is set. Each time a trigger occurs or CHREQ is set, DMAxCNT is decremented. In this case, however, the channel is not disabled when DMAxCNT reaches 0000h. Instead, the original value of DMAxCNT is reloaded. If RELOADS = 1 and RELOADD = 1, the original values of DMAxSRC and DMAxDST are also reloaded. The entire cycle then starts again on the next trigger. To end the sequence, the channel must be disabled by clearing the CHEN bit in software.

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

Typical Code Sequence for a Repeated One-Shot Transfer

unsigned int SRC[4];
unsigned int DEST[4];
int main()
{
    for (int i=0;i<4;i++)
    {
        SRC[i]=i+1;                         //fill with i+1
        DEST[i]=0;                          //fill with 0
    }
    DMACONbits.ON=1;
    DMACONbits.PRIORITY=1;
    IFS2bits.DMA0IF=0;
    DMALOW=0x4000;
    DMAHIGH=0x7FFF;                         //set lower and upper address limit
    DMA0SRC=(unsigned int)& SRC;            //load the source address
    DMA0DST=(unsigned int)& DEST;           //load destination address
    DMA0CNT=4;
    DMA0CH=0;
    DMA0CHbits.SAMODE=1;                    //Source address increment mode
    DMA0CHbits.DAMODE=1;                    //Destination address increment mode
    DMA0CHbits.TRMODE=1;                    //Transfer mode Repeat One-Shot
    DMA0CHbits.RELOADS=1;                   //Reload Source Address
    DMA0CHbits.RELOADD=1;                   //Reload Destination Address
    DMA0CHbits.SIZE=2;                      //32-Bit transfer per count
    DMA0CHbits.CHEN=1;                      //Channel enable
    while(1)
    {
        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 in half way point
        DMA0CHbits.CHREQ=1;              //Fourth trigger DMACNT=0 and transfer complete
        while(DMA0CHbits.CHREQ);           //DMACNT reloaded to 4, DMA0IF=1
                                           //Since RELOADS=1 and RELOADD=1,
                                           //DMASRC0/DMADST0 are reloaded
        while(!DMA0STATbits.DONE);
        DMA0STATbits.DONE=0;               //Clear DONE and HALIF flag
        DMA0STATbits.HALF=0;
        IFS2bits.DMA0IF=0;
    }
}