AnsweredAssumed Answered

Problem with DMA on PCIe transactions

Question asked by masasi on Oct 29, 2015
Latest reply on Nov 2, 2015 by lunminliang

Hi,

 

I am trying to use the DMA on the PCIe outbound transactions in order to improve the data transfer speed on a P1012 microprocessor.

I have configured the DMA in direct mode. I create my PCIe output message on a function using a local variable(located in DDR), then I fill the SAR register with a pointer to my local variable and the DAR with the address of my PCIe outbound window. If I write directly on the outbound window without using the DMA, the PCIe communication works fine but when I use the DMA I always get a programming error on my status register.

 

According to the reference manual, the programming error may be caused by a:

- Transfer started with a byte count of zero(which is not my case)

- Stride transfer started with a stride size of zero( disabled)

- Transfer started with a priority of three

-  Illegal type, defined by SATRn[SREADTTYPE] and DATRn[DWRITETTYPE], used for the transfer. (I check all the possible value combinations for SATR and DATR and none of them worked).

 

What does the "Transfer started with a priority of three" means? How can I check that? Does anyone can help find found out what I am doing wrong?


Here is my code:

 

static void dma_sync(void) {

     asm("sync; isync; msync");

}

 

static uint dma_check(void) {

     volatile fsl_dma_t *dma = 0xff721100;

     volatile uint status = dma->sr;

     /* While the channel is busy, spin */

     while (status & 4) status = dma->sr;

      /* clear MR[CS] channel start bit */

     dma->mr &= 1; dma_sync();

     if (status != 0)

          printf ("DMA Error: status = %x\n", status);

     return status;

}

 

void LibInitDMA(void) {

     volatile fsl_dma_t *dma= 0xff721100;

     //Confirm proper initialization

     if((dma->mr&(DMA_MR_CS_MASK||DMA_MR_CC_MASK))||(dma->sr&(DMA_SR_TE_MASK||DMA_SR_CB_MASK)))

     {

          printf("Error configuring DMA...\n");

     }

     dma->satr = 0x00040000;

     dma->datr = 0x00040000;

     dma_sync();

}

void LibSendDMA(int src_add, int dst_addr, int size)

{

     volatile fsl_dma_t *dma= 0xff721100;

     //Poll the channel state to confirm that the DMA channel 0 is idle

     while((dma->sr&DMA_SR_CB_MASK)!=0);

     //Initialize source and destination transfer

     //Initialize SAR0

     dma->sar=src_add;

     //Initialize DAR0

     dma->dar=dst_addr;

     //Set data size to transfer

     dma->bcr=size;

     /* Disable bandwidth control, use direct transfer mode */

     dma->mr = 0xf000004;

     dma_sync();

     /* Start the transfer */

     dma->mr = 0xf000005;

     dma_sync();

     return dma_check();

}

 

Thank you very much for your help

Outcomes