13.4.9.2 Fixed to Block
In Fixed to Block mode, the source address remains unchanged throughout the transfer, but the destination address is incremented or decremented (depending on the DAMODEx setting). This works well for receiving data from the single-word buffer of a serial communication peripheral and filling a block of addresses designated as a buffer.
Code for Fixed to Block Continuous Transfer (Peripheral to Memory) shows sample code for Fixed to Block Addressing. The source address (UART receive) generates an interrupt when the UART buffer has received four bytes; the UART Receive Interrupt Flag (U2RIF) will trigger the transfer.
Code for Fixed to Block Continuous Transfer (Peripheral to Memory)
void UartInit(void);
unsigned char Array2[32];
int main()
{
UartInit();
for (int i = 0; i < 32; i++)
{
Array2[i] = 0; //fill with 0
}
DMACONbits.ON = 1; //Enable DMA
DMAHIGH = 0x5000; //set lower and upper address limit
DMALOW = 0x4000;
DMA0SRC = (uint32_t) &U1RXB;
DMA0DST = (uint32_t) &Array2[0]; // load destination address
DMA0CNT = 4; //When the UART buffer has 4 bytes, do an interrupt and transfer 4 bytes
DMA0CH = 0;
DMA0CHbits.SIZE=0; //One byte transferred at a time
DMA0CHbits.SAMODE = 0; //Source address increment mode: do not increment
DMA0CHbits.DAMODE = 1; //Destination address increment mode: increment 1
DMA0CHbits.TRMODE = 2; //Transfer mode: Continuous
DMA0SELbits.CHSEL = 15; //Trigger DMA channel 0 on UART1 Receive
DMA0CHbits.DONEEN=1; //Enable interrupt on DONE being set
DMA0CHbits.CHEN = 1; //Channel 0 enable
IFS2bits.DMA0IF = 0;
//Wait for the bytes to be transferred (triggered by UART reception)
while (!IFS2bits.DMA0IF); //DONE=1;CHAEN=0,DMA0IF=1 and transfer complete with one trigger
IFS2bits.DMA0IF = 0;
//4 bytes received from UART1 are now be stored in Array2.
//DMA0DST will point at Array2[4], and further bytes can be transferred by enabling the channel again.
while (1);
}
//Enable UART1 for 115200 baud rate using RH1 as UART1 TX and RD1 as UART1 RX.
void UartInit(void)
{
//Enable CLKEN8 to provide clock to UART
CLK8CONbits.ON = 1;
// RP114 - RH1, configure as UART TX
_TRISH1 = 0;
_RP114R = _RPOUT_U1TX;
// RP50 - RD1, configure as UART RX
_TRISD1 = 1;
_U1RXR = 50;
U1CONbits.CLKMOD = 1; //Use fractional baud rate generation
U1CONbits.CLKSEL = 1; //Select CLKGEN8 as clock source
U1CONbits.MODE = 0; //Asynchronous 8-bit UART
//Enable RX and TX functionality
U1CONbits.RXEN = 1;
U1CONbits.TXEN = 1;
//In fractional baud rate mode, UxBRG = Input clock / baud rate, for 8MHz and 115200 baud
U1BRG = (8000000 / 115200);
U1STATbits.RXWM = 3; //Interrupt after 4 transfers
//Lastly, enable UART1
U1CONbits.ON = 1;
_U1RXIF = 0;
}