AnsweredAssumed Answered

Circular DMA Buffer

Question asked by Jensen Kenneth on Nov 22, 2013
Latest reply on Jun 18, 2015 by 鑫 金



I am using flextimer and configured them to trigger DMA when it reach a rising edge in the channel interrupt. I defined a specific size of the DMA buffer, which gives me some problems, as I don't know how many inputs i get.


First question: Is it possible somehow to make a circular DMA buffer? and how?

Second question: If I want to clear the DMA and start all over before the buffer is full, how do I do this in a correct way? Right now I have to initialize the controller again.


I posted my code for initializing the DMA, I hope someone can help me out.

I have a DMA buffer which has 2048 elements of uint16.

I am working on a K60 MCU using uTasker.


Thanks in advance.


// Configure DMA multiplexer and DMA controller

void dma_init(void)







  /* No link channel to channel, number of transactions */

  DMA_TCD0_CITER_ELINKNO = buffer_size; // Current Minor Loop Link, Major Loop Count

  DMA_TCD0_BITER_ELINKNO = buffer_size; // Beginning Minor Loop Link, Major Loop Count


  /* transfer, making only a single minor loop necessary to complete a major loop */

  DMA_TCD0_SADDR = (uint32)(&FTM0_C0V); // Set the Source Address

  DMA_TCD0_SOFF = 0; // Source offset disabled

  DMA_TCD0_SLAST = 0; // Last Source Address Adjustment - No adjust needed


  DMA_TCD0_DADDR = (uint32)dma_buf; // Set the Destination Address

  DMA_TCD0_DOFF = sizeof(uint16); // Destination offset 2 bytes (Increments the address after transaction)

  DMA_TCD0_DLASTSGA = -(sizeof(uint16)*(buffer_size)); // Last Destination Address Adjustment (2 byte * array size)


  DMA_TCD0_NBYTES_MLNO = sizeof(uint16); // Transfer 2 bytes per transaction (16 bit)


  /* Source and Destination Modulo off, source and destination size 1 = 16 bits */



  DMA_ERQ |= DMA_ERQ_ERQ0; // Enable DMA request on channel 0