Advertisement
manitou

DUE DMA mem2mem

Dec 21st, 2012
103
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 3.83 KB | None | 0 0
  1. /**********************************************************************
  2.  use DMA for memcpy memset
  3.  */
  4.  
  5.  
  6. // mem2mem works on all channels
  7. #define DMAC_MEMCH 0
  8.  
  9. /** Disable DMA Controller. */
  10. static void dmac_disable() {
  11.   DMAC->DMAC_EN &= (~DMAC_EN_ENABLE);
  12. }
  13. /** Enable DMA Controller. */
  14. static void dmac_enable() {
  15.   DMAC->DMAC_EN = DMAC_EN_ENABLE;
  16. }
  17. /** Disable DMA Channel. */
  18. static void dmac_channel_disable(uint32_t ul_num) {
  19.   DMAC->DMAC_CHDR = DMAC_CHDR_DIS0 << ul_num;
  20. }
  21. /** Enable DMA Channel. */
  22. static void dmac_channel_enable(uint32_t ul_num) {
  23.   DMAC->DMAC_CHER = DMAC_CHER_ENA0 << ul_num;
  24. }
  25. /** Poll for transfer complete. */
  26. static bool dmac_channel_transfer_done(uint32_t ul_num) {
  27.   return (DMAC->DMAC_CHSR & (DMAC_CHSR_ENA0 << ul_num)) ? false : true;
  28. }
  29.  
  30.  
  31. void memcpy32(uint32_t *dst, uint32_t *src, uint32_t n) {
  32.   dmac_channel_disable(DMAC_MEMCH);
  33.   DMAC->DMAC_CH_NUM[DMAC_MEMCH].DMAC_SADDR = (uint32_t)src;
  34.   DMAC->DMAC_CH_NUM[DMAC_MEMCH].DMAC_DADDR = (uint32_t)dst;
  35.   DMAC->DMAC_CH_NUM[DMAC_MEMCH].DMAC_DSCR =  0;
  36.   DMAC->DMAC_CH_NUM[DMAC_MEMCH].DMAC_CTRLA = n |
  37.     DMAC_CTRLA_SRC_WIDTH_WORD | DMAC_CTRLA_DST_WIDTH_WORD;
  38.  
  39.   DMAC->DMAC_CH_NUM[DMAC_MEMCH].DMAC_CTRLB =  DMAC_CTRLB_SRC_DSCR |
  40.     DMAC_CTRLB_DST_DSCR | DMAC_CTRLB_FC_MEM2MEM_DMA_FC |
  41.     DMAC_CTRLB_SRC_INCR_INCREMENTING | DMAC_CTRLB_DST_INCR_INCREMENTING;
  42.  
  43.   DMAC->DMAC_CH_NUM[DMAC_MEMCH].DMAC_CFG = DMAC_CFG_SOD | DMAC_CFG_FIFOCFG_ALAP_CFG;
  44.  
  45.   dmac_channel_enable(DMAC_MEMCH);
  46.   while (!dmac_channel_transfer_done(DMAC_MEMCH)) {}
  47.   dmac_channel_disable(DMAC_MEMCH);   // needed?  SOD does this?
  48.  
  49. }
  50.  
  51. void memset32(uint32_t *dst, uint32_t word, uint32_t n) {
  52.   dmac_channel_disable(DMAC_MEMCH);
  53.   DMAC->DMAC_CH_NUM[DMAC_MEMCH].DMAC_SADDR = (uint32_t)&word;
  54.   DMAC->DMAC_CH_NUM[DMAC_MEMCH].DMAC_DADDR = (uint32_t)dst;
  55.   DMAC->DMAC_CH_NUM[DMAC_MEMCH].DMAC_DSCR =  0;
  56.   DMAC->DMAC_CH_NUM[DMAC_MEMCH].DMAC_CTRLA = n |
  57.     DMAC_CTRLA_SRC_WIDTH_WORD | DMAC_CTRLA_DST_WIDTH_WORD;
  58.  
  59.   DMAC->DMAC_CH_NUM[DMAC_MEMCH].DMAC_CTRLB =  DMAC_CTRLB_SRC_DSCR |
  60.     DMAC_CTRLB_DST_DSCR | DMAC_CTRLB_FC_MEM2MEM_DMA_FC |
  61.     DMAC_CTRLB_SRC_INCR_FIXED | DMAC_CTRLB_DST_INCR_INCREMENTING;
  62.  
  63.   DMAC->DMAC_CH_NUM[DMAC_MEMCH].DMAC_CFG = DMAC_CFG_SOD | DMAC_CFG_FIFOCFG_ALAP_CFG;
  64.  
  65.   dmac_channel_enable(DMAC_MEMCH);
  66.   while (!dmac_channel_transfer_done(DMAC_MEMCH)) {}
  67.   dmac_channel_disable(DMAC_MEMCH);   // needed?  SOD does this?
  68. }
  69.  
  70. #define WORDS 1000
  71. uint32_t src[WORDS],dst[WORDS];
  72.  
  73. void setup(){
  74.     Serial.begin(9600);
  75.     pmc_enable_periph_clk(ID_DMAC);
  76.     dmac_disable();
  77.      DMAC->DMAC_GCFG = DMAC_GCFG_ARB_CFG_FIXED;
  78.     dmac_enable();
  79. }
  80.  
  81. void loop(){
  82.     int i,t1,t2;
  83.    
  84.     for (i=0;i<WORDS;i++){
  85.         dst[i]=0;
  86.         src[i]=i;
  87.     }
  88.     memcpy32(dst,src,WORDS);
  89.     Serial.println(dst[3],DEC);
  90.         memset32(dst,45,WORDS);
  91.         Serial.println(dst[3],DEC);
  92.         t1=micros();
  93.         memcpy32(dst,src,WORDS);
  94.         t2 = micros() - t1;
  95.         Serial.print("memcpy32 ");Serial.println(t2,DEC);
  96.         t1=micros();
  97.         for(i=0;i<WORDS;i++) dst[i] = src[i];
  98.         t2 = micros() - t1;
  99.         Serial.print("loop ");Serial.println(t2,DEC);
  100.        
  101.         t1=micros();
  102.         memset32(dst,66,WORDS);
  103.         t2 = micros() - t1;
  104.         Serial.print("memset32 ");Serial.println(t2,DEC);
  105.         t1=micros();
  106.         for(i=0;i<WORDS;i++) dst[i] = 66;
  107.         t2 = micros() - t1;
  108.         Serial.print("loop ");Serial.println(t2,DEC);
  109.        
  110.         dst[3]=99;
  111.         t1=micros();
  112.         memcpy(dst,src,4*WORDS);
  113.         t2 = micros() - t1;
  114.         Serial.print("memcpy ");Serial.println(t2,DEC);
  115.         Serial.println(dst[3],DEC);
  116.         t1=micros();
  117.         memset(dst,66,4*WORDS);
  118.         t2 = micros() - t1;
  119.         Serial.print("memset ");Serial.println(t2,DEC);
  120.         Serial.println(dst[3],HEX);
  121.         Serial.println();
  122.     delay(3000);
  123. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement