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