Problem with DMA on PCIe transactions

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

Problem with DMA on PCIe transactions

1,306 Views
masasi
Contributor II

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

Labels (1)
0 Kudos
1 Reply

730 Views
lunminliang
NXP Employee
NXP Employee

Hello masasi,

Does it always fail with PCIe outbound address? Or sometimes fail, please clarify.

And when you set the address to DMA register, is it a physical address?

Can you successfully transfer data from DDR to DDR with your DMA code?


Have a great day,
Lunmin

-----------------------------------------------------------------------------------------------------------------------
Note: If this post answers your question, please click the Correct Answer button. Thank you!
-----------------------------------------------------------------------------------------------------------------------

0 Kudos