7.2 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;