Example-2

This example shows the code snippet for the setup of the DMA module to transfer data from the user RAM to the UART Transmit buffer. The transfer is triggered by the UART Transmit Interrupt. The data is stored in an array called “TX_DATA” and everytime a byte is sent out from the UART Transmit buffer, the DMA is triggered to load a new byte. User firmware does not need to set the DGO bit in the DMA1CON0 register. Setting the SSTP bit will clear the SIRQEN bit once all the data has been transferred. User firmware can set the SIRQEN bit to arm the DMA module again.


void DMA1_Initialize(void)
 {
     DMA1SSA = &TX_DATA;         //set source start address
     DMA1DSA = &U1TXB;           //set destination start address
     DMA1CON1 = 0x03;            //DMODE = 00 | DSTP = 0 | SMR = 01 | SMODE = 01 | SSTP = 1 
     DMA1SSZ = 0x0017;           //set source size = 23 bytes
     DMA1DSZ = 0x0001;           //set destination size = 1 byte
     DMA1SIRQ = 0x1C;            //set DMA Transfer Trigger Source = U1TX     
     DMA1AIRQ = 0x00;            //set DMA Transfer abort Source    
      
     PIR2bits.DMA1DCNTIF = 0;    //clear Destination Count Interrupt Flag bit     
     PIR2bits.DMA1SCNTIF = 0;    //clear Source Count Interrupt Flag bit
     PIR2bits.DMA1AIF = 0;       //clear abort Interrupt Flag bit
     PIR2bits.DMA1ORIF = 0;      //clear overrun Interrupt Flag bit
     PIE2bits.DMA1DCNTIE = 0;    //disable Destination Count Interrupt 
     PIE2bits.DMA1SCNTIE = 0;    //disable Source Count Interrupt
     PIE2bits.DMA1AIE = 0;       //disable abort Interrupt 
     PIE2bits.DMA1ORIE = 0;      //disable overrun Interrupt 

     asm("BCF INTCON0,7");       //disable Global Interrupts

     asm ("BANKSEL PRLOCK");     //    
     asm ("MOVLW 0x55");         //    
     asm ("MOVWF PRLOCK");       //Arbiter Priority lock
     asm ("MOVLW 0xAA");         //sequence
     asm ("MOVWF PRLOCK");       //     
     asm ("BSF PRLOCK, 0");      //  
     
     asm("BSF INTCON0,7");       //enable Global Interrupts
     DMA1CON0 = 0x80;            //EN = 1 | SIRQEN = 0 | DGO = 0 |xx| AIRQEN = 0 |x| XIP = 0
 }

User firmware can set the SIRQEN bit whenever the DMA transaction needs to start. This can be done with the following line of code.

DMA1CON0bits.SIRQEN = 1;