Channel Circular Buffer Mode

Circular buffer mode is used when an application is required to transfer an exact amount of data on a fixed start address. The DMA Controller core self-restarts when a transfer has been completed and starts executing the transfer again with the information provided from the previous transfer. This mode is applicable in direct mode transfer.

Figure 1. Channel Circular Buffer Mode Flow Diagram

Starting from version v6.3, the DMA introduces on how to do a self-restart or circular buffer operation with scatter-gather mode. The following program shows the example on how to program the descriptor list to do the self-restart or circular buffer operation.

Circular Buffer Mode with SG Descriptors Example

void program_circular_descriptor() {
	for (int j=0; j<FRAME_RATE; j=j+1 ) {
       if(j == FRAME_RATE-1) {
    	   descriptors0[j].control = (BUFFER_SIZE*4)-1  | DMASG_DESCRIPTOR_CONTROL_NO_COMPLETION ;
    	   descriptors0[j].from    = 0;
    	   descriptors0[j].to      = (u32)(dbSGM + (j *(BUFFER_SIZE)) );
    	   descriptors0[j].next    = (u32) (descriptors0);
    	   descriptors0[j].status  = 0;
    	   descriptors1[j].control = (BUFFER_SIZE*4)-1  | DMASG_DESCRIPTOR_CONTROL_NO_COMPLETION ;
    	   descriptors1[j].from    = (u32)(sb + (j *(BUFFER_SIZE)));
    	   descriptors1[j].to      = 0;
    	   descriptors1[j].next    = (u32) (descriptors1);
    	   descriptors1[j].status  = 0;
       } else {
        	descriptors0[j].control = (BUFFER_SIZE*4)-1  | DMASG_DESCRIPTOR_CONTROL_NO_COMPLETION ;
        	descriptors0[j].from    = 0;
        	descriptors0[j].to      = (u32)(dbSGM + (j *(BUFFER_SIZE)) );
        	descriptors0[j].next    = (u32) (descriptors0 + (j+1));
        	descriptors0[j].status  = 0;
        	descriptors1[j].control = (BUFFER_SIZE*4)-1  | DMASG_DESCRIPTOR_CONTROL_NO_COMPLETION ;
        	descriptors1[j].from    = (u32)(sb + (j *(BUFFER_SIZE)));
        	descriptors1[j].to      = 0;
        	descriptors1[j].next    = (u32) (descriptors1 + (j+1));
        	descriptors1[j].status  = 0;
       }
	}
}