This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

dm365 dvsdk4里面edma例子的问题



我程序里面需要用到edma,但在看dm365 dvsdk4里面的edma例子时有个地方不明白,请专家指点:

例子是psp里面linuxutil里面的edma例子,edma_test.c里面函数

int edma3_memtomemcpytest_dma(int acnt, int bcnt, int ccnt, int sync_mode,
         int event_queue)
{
 int result = 0;
 unsigned int dma_ch = 0;
 int i;
 int count = 0;
 unsigned int Istestpassed = 0u;
 unsigned int numenabled = 0;
 unsigned int BRCnt = 0;
 int srcbidx = 0;
 int desbidx = 0;
 int srccidx = 0;
 int descidx = 0;
 struct edmacc_param param_set;

 /* Initalize source and destination buffers */
 for (count = 0u; count < (acnt * bcnt * ccnt); count++) {
  dmabufsrc1[count] = 'A' + (count % 26);
  dmabufdest1[count] = 0;
 }

 /* Set B count reload as B count. */
 BRCnt = bcnt;

 /* Setting up the SRC/DES Index */
 srcbidx = acnt;
 desbidx = acnt;

 /* A Sync Transfer Mode */
 srccidx = acnt;
 descidx = acnt;

 dma_ch = edma_alloc_channel(EDMA_CHANNEL_ANY, callback1, NULL,
   event_queue);
 
 printk("edma3_memtomemcpytest_dma::dma_ch is %d\n", dma_ch);

 if (dma_ch < 0) {
  DMA_PRINTK
      ("\nedma3_memtomemcpytest_dma::edma_alloc_channel failed for dma_ch, error:%d\n",
       dma_ch);
  return dma_ch;
 }

 edma_set_src(dma_ch, (unsigned long)(dmaphyssrc1), INCR, W8BIT);

 edma_set_dest(dma_ch, (unsigned long)(dmaphysdest1), INCR, W8BIT);

 edma_set_src_index(dma_ch, srcbidx, srccidx);

 edma_set_dest_index(dma_ch, desbidx, descidx);

/*上面输入参数acnt=512,bcnt=8,ccnt=8,我的问题是

不明白为什么这里srccidx等于acnt,我查edma_set_src_index的函数解释是

 edma_set_src_index - configure DMA source address indexing 

 @slot: parameter RAM slot being configured 

 @src_bidx: byte offset between source arrays in a frame 

 @src_cidx: byte offset between source frames in a block 

src_cidx即块中frame间的字节偏移,我觉得应该是acnt*bcnt才对,怎么会是acnt呢?

是不是因为下面红字处的edma_start在for循环中要运行bcnt * ccnt次,所以这里每次就传512字节,所以src_cidx和src_cidx都设置成了acnt*/

 /* A Sync Transfer Mode */
 edma_set_transfer_params(dma_ch, acnt, bcnt, ccnt, BRCnt, ASYNC);

 /* Enable the Interrupts on Channel 1 */
 edma_read_slot(dma_ch, &param_set);
 param_set.opt |= (1 << ITCINTEN_SHIFT);
 param_set.opt |= (1 << TCINTEN_SHIFT);
 param_set.opt |= EDMA_TCC(EDMA_CHAN_SLOT(dma_ch));
 edma_write_slot(dma_ch, &param_set);

 numenabled = bcnt * ccnt;

 for (i = 0; i < numenabled; i++) {
  irqraised1 = 0;

  /* Now enable the transfer as many times as calculated above. */
  result = edma_start(dma_ch);
  if (result != 0) {
   DMA_PRINTK
       ("edma3_memtomemcpytest_dma: edma_start failed \n");
   break;
  }

  /* Wait for the Completion ISR. */
  while (irqraised1 == 0u) ;

  /* Check the status of the completed transfer */
  if (irqraised1 < 0) {
   /* Some error occured, break from the FOR loop. */
   DMA_PRINTK("edma3_memtomemcpytest_dma: "
       "Event Miss Occured!!!\n");
   break;
  }
 }

 if (0 == result) {
  for (i = 0; i < (acnt * bcnt * ccnt); i++) {
   if (dmabufsrc1[i] != dmabufdest1[i]) {
    DMA_PRINTK
        ("\n edma3_memtomemcpytest_dma: Data write-read matching failed at = %u\n",
         i);
    Istestpassed = 0u;
    result = -1;
    break;
   }
  }
  if (i == (acnt * bcnt * ccnt)) {
   Istestpassed = 1u;
  }

  edma_stop(dma_ch);
  edma_clean_channel(dma_ch);
  edma_free_slot(dma_ch);
  edma_free_channel(dma_ch);
 }

 if (Istestpassed == 1u) {
  DMA_PRINTK
      ("\nedma3_memtomemcpytest_dma: EDMA Data Transfer Successfull \n");
 } else {
  DMA_PRINTK
      ("\nedma3_memtomemcpytest_dma: EDMA Data Transfer Failed \n");
 }

 return result;
}

谢谢专家!期待您的指导!

  • 参见 DM365 data sheet, Chapter "EDMA" section "Functional Description", "Types of EDMA3 transfers",  "A synchronized transfer", 由图可见在A-synchronous transfer中,为了实现frame 的连续传输需要使 cidx = bidx.