cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 
berkeratel
Observer
Observer
333 Views
Registered: ‎08-26-2020

DMA stale descriptor error(DMA error)

Hi,

I get Scatter Gather Internal Error and Error IRQ. This is a stale descriptor acc. to PG021. 

I have 3 waveforms at different address which are not adjacent. 

#define MEM_BASE_ADDR 0x00100000
#define DAC1_BASE_ADDR (MEM_BASE_ADDR + 0x00100000)
#define DAC2_BASE_ADDR (MEM_BASE_ADDR + 0x00200000)
#define DAC3_BASE_ADDR (MEM_BASE_ADDR + 0x00300000)

Buffer descriptor address which are have offset 0x40

#define BD_ADDR (MEM_BASE_ADDR + 0x00800000)
#define DESC1_ADDR BD_ADDR
#define DESC2_ADDR BD_ADDR+0x40
#define DESC3_ADDR BD_ADDR+0x80

1) I create BDs on the memory

2) Reset, Set Current BD, Set Start, Set Tail BD

After setting Tail BD pointer, this is not start MM2S transfer. Valid signal doesn't come to stream side. How can i solve it? 

 

 

 

#include <stdio.h>
#include "platform.h"
#include "xil_printf.h"
#include "xaxidma.h"
#include "xparameters.h"
#include "xil_exception.h"
#include "xscugic.h"
//#include "xbasic_types.h"
#include "xil_io.h"
#include "xil_types.h"
#include "sine.h"

#define DMA_BASE_ADDR       0x40400000
#define MEM_BASE_ADDR		0x00100000
#define DAC1_BASE_ADDR		(MEM_BASE_ADDR + 0x00100000)
#define DAC2_BASE_ADDR		(MEM_BASE_ADDR + 0x00200000)
#define DAC3_BASE_ADDR		(MEM_BASE_ADDR + 0x00300000)
#define BD_ADDR				(MEM_BASE_ADDR + 0x00800000)
#define DESC1_ADDR          BD_ADDR
#define DESC2_ADDR          BD_ADDR+0x40
#define DESC3_ADDR          BD_ADDR+0x80


#define DMA_MM2S_IRQID   61

XScuGic 	     Intc_ins;
XScuGic_Config   Intc_cfg;
XAxiDma 		 DMA_ins;
XAxiDma_Config   DMA_cfg;

static volatile u32 DMA_MM2S_Flag=0;

void MM2S_ISR(void *CallbackRef);
void print_DDR_cell_u8(u8 *data,u16 size);


int main()
{
    init_platform();



    XScuGic          *Intc_ins_p = &Intc_ins;
    XScuGic_Config   *Intc_cfg_p = &Intc_cfg;
    Intc_cfg_p = XScuGic_LookupConfig(0);
	XScuGic_CfgInitialize(Intc_ins_p, Intc_cfg_p,Intc_cfg_p->CpuBaseAddress);


	XAxiDma  		*AxiDMA_ins_p = &DMA_ins;
	XAxiDma_Config  *AxiDMA_cfg_p = &DMA_cfg;
    AxiDMA_cfg_p = XAxiDma_LookupConfig(0);
    XAxiDma_CfgInitialize(AxiDMA_ins_p,AxiDMA_cfg_p);


	Xil_ExceptionInit();
	Xil_ExceptionRegisterHandler(XIL_EXCEPTION_ID_IRQ_INT,
				(Xil_ExceptionHandler)XScuGic_InterruptHandler,
				Intc_ins_p);
	XScuGic_Connect(Intc_ins_p, DMA_MM2S_IRQID,
			    (Xil_ExceptionHandler)MM2S_ISR,
				(void *)&DMA_ins);
	XScuGic_Enable(Intc_ins_p,DMA_MM2S_IRQID);
	Xil_ExceptionEnable();

	DMA_MM2S_Flag=0;
	int Index;
	u8 *TxBufferPtr1;
	u8 *TxBufferPtr2;
	u8 *TxBufferPtr3;

	TxBufferPtr1 = (u8 *)DAC1_BASE_ADDR ;
	TxBufferPtr2 = (u8 *)DAC2_BASE_ADDR ;
	TxBufferPtr3 = (u8 *)DAC3_BASE_ADDR ;

	for(Index = 0;Index <100; Index ++)
	{

		TxBufferPtr1[Index] = S11[Index];
		TxBufferPtr2[Index] = Index;
		TxBufferPtr3[Index] = 100-Index;
	}

	Xil_DCacheFlushRange((UINTPTR)TxBufferPtr1, 100);
	Xil_DCacheFlushRange((UINTPTR)TxBufferPtr2, 100);
	Xil_DCacheFlushRange((UINTPTR)TxBufferPtr3, 100);


	//BD1
	Xil_Out32(DESC1_ADDR+0x00,(DESC2_ADDR)<<6);
	//Xil_Out32(BD_ADDR+0x04,0x00000000);
	Xil_Out32(DESC1_ADDR+0x08,DAC1_BASE_ADDR);
	//Xil_Out32(BD_ADDR+0x0C,0x00000000);
	//Xil_Out32(BD_ADDR+0x10,0x00000000);
	//Xil_Out32(BD_ADDR+0x14,0x00000000);
	Xil_Out32(DESC1_ADDR+0x18,0x08000064);//100byte, SOF
	//Xil_Out32(BD_ADDR+0x1C,0x00000000);

	//BD2
	Xil_Out32(DESC2_ADDR+0x00,((DESC3_ADDR)<<6)  );
	//Xil_Out32(BD_ADDR+0x40+0x04,0x00000000);
	Xil_Out32(DESC2_ADDR+0x08,DAC2_BASE_ADDR);
	//Xil_Out32(BD_ADDR+0x40+0x0C,0x00000000);
	//Xil_Out32(BD_ADDR+0x40+0x10,0x00000000);
	//Xil_Out32(BD_ADDR+0x40+0x14,0x00000000);
	Xil_Out32(DESC2_ADDR+0x18,0x00000064);
	//Xil_Out32(BD_ADDR+0x40+0x1C,0x00000000);

	//BD3
	Xil_Out32(DESC3_ADDR+0x00,((DESC1_ADDR)<<6) );
	//Xil_Out32(BD_ADDR+0x80+0x04,0x00000000);
	Xil_Out32(DESC3_ADDR+0x08,DAC3_BASE_ADDR);
	//Xil_Out32(BD_ADDR+0x80+0x0C,0x00000000);
	//Xil_Out32(BD_ADDR+0x80+0x10,0x00000000);
	//Xil_Out32(BD_ADDR+0x80+0x14,0x00000000);
	Xil_Out32(DESC3_ADDR+0x18,0x04000064);//100byte, EOF
	//Xil_Out32(BD_ADDR+0x80+0x1C,0x00000000);


	print("DESCRIPTORS---\n\r");
	xil_printf("DESC1:\n\r");
	xil_printf("NXTDESC:%x\n\r",(Xil_In32(DESC1_ADDR))>>6 );
	xil_printf("BUFADDR:%x\n\r",Xil_In32(DESC1_ADDR+0x08));
	xil_printf("LEN:%d\n\r",(Xil_In32(DESC1_ADDR+0x18))&0x03FFFFFF  );
	xil_printf("SOF:%d\n\r",((Xil_In32(DESC1_ADDR+0x18))&0x08000000)>>27 );
	xil_printf("EOF:%d\n\r",((Xil_In32(DESC1_ADDR+0x18))&0x04000000)>>26 );
	xil_printf("CMPLT:%d\n\r",((Xil_In32(DESC1_ADDR+0x18))&0x80000000)>>31 );
	printf("\n\r");

	xil_printf("DESC2:\n\r");
	xil_printf("NXTDESC:%x\n\r",(Xil_In32(DESC2_ADDR))>>6 );
	xil_printf("BUFADDR:%x\n\r",Xil_In32(DESC2_ADDR+0x08));
	xil_printf("LEN:%d\n\r",(Xil_In32(DESC2_ADDR+0x18))&0x03FFFFFF  );
	xil_printf("SOF:%d\n\r",((Xil_In32(DESC2_ADDR+0x18))&0x08000000)>>27 );
	xil_printf("EOF:%d\n\r",((Xil_In32(DESC2_ADDR+0x18))&0x04000000)>>26 );
	xil_printf("CMPLT:%d\n\r",((Xil_In32(DESC2_ADDR+0x18))&0x80000000)>>31 );
	printf("\n\r");

	xil_printf("DESC3:\n\r");
	xil_printf("NXTDESC:%x\n\r",(Xil_In32(DESC3_ADDR))>>6 );
	xil_printf("BUFADDR:%x\n\r",Xil_In32(DESC3_ADDR+0x08));
	xil_printf("LEN:%d\n\r",(Xil_In32(DESC3_ADDR+0x18))&0x03FFFFFF  );
	xil_printf("SOF:%d\n\r",((Xil_In32(DESC3_ADDR+0x18))&0x08000000)>>27 );
	xil_printf("EOF:%d\n\r",((Xil_In32(DESC3_ADDR+0x18))&0x04000000)>>26 );
	xil_printf("CMPLT:%d\n\r",((Xil_In32(DESC3_ADDR+0x18))&0x80000000)>>31 );
	printf("\n\r");

	//current register
	//RS=1
	//IRQ_EN=1
	//tail register

	u32 MM2S_DMACR = 0;
	u32 MM2S_DMASR = 0;


	print("BEFORE START\n\r");
	MM2S_DMACR =  (Xil_In32(DMA_BASE_ADDR+0));
	MM2S_DMACR = MM2S_DMACR & 0x00000001;
	xil_printf("RS:%d\n\r",MM2S_DMACR);

	MM2S_DMASR =  (Xil_In32(DMA_BASE_ADDR+4));
	MM2S_DMASR = (MM2S_DMASR & 0x00000001);
	xil_printf("Halted:%d\n\r",MM2S_DMASR);

	MM2S_DMASR =  (Xil_In32(DMA_BASE_ADDR+4));
	MM2S_DMASR = (MM2S_DMASR & 0x00000002)>>1;
	xil_printf("Idle:%d\n\r",MM2S_DMASR);

	MM2S_DMASR =  (Xil_In32(DMA_BASE_ADDR+4));
	MM2S_DMASR = (MM2S_DMASR & 0x00000100)>>8;
	xil_printf("DMA error:%d\n\r",MM2S_DMASR);

	MM2S_DMASR =  (Xil_In32(DMA_BASE_ADDR+4));
	MM2S_DMASR = (MM2S_DMASR & 0x00001000)>>12;
	xil_printf("IRQ CMPLTD:%d\n\r",MM2S_DMASR);

	MM2S_DMASR =  (Xil_In32(DMA_BASE_ADDR+4));
	MM2S_DMASR = (MM2S_DMASR & 0x00005000)>>14;
	xil_printf("ERR IRQ CMPLTD:%d\n\r",MM2S_DMASR);


	//RESET DMA IP
	MM2S_DMACR =  (Xil_In32(DMA_BASE_ADDR+0));
	Xil_Out32(DMA_BASE_ADDR+0,MM2S_DMACR|0x00000004);

	MM2S_DMACR =  (Xil_In32(DMA_BASE_ADDR+0));
	Xil_Out32(DMA_BASE_ADDR+0,MM2S_DMACR|0x00000000);


	//CURRENT
	u32 curr_bd_addr=((DESC1_ADDR)<<6);
	Xil_Out32(DMA_BASE_ADDR+8,curr_bd_addr);


	//RS=1
	MM2S_DMACR =  (Xil_In32(DMA_BASE_ADDR+0));
	Xil_Out32(DMA_BASE_ADDR+0,MM2S_DMACR|0x00000001);


	//TAIL
	u32 tail_bd_addr=((DESC3_ADDR)<<6);
	Xil_Out32(DMA_BASE_ADDR+16,tail_bd_addr);

	u32 MM2S_CURDESC  =  (Xil_In32(DMA_BASE_ADDR+0x08))>>6;
	u32 MM2S_TAILDESC =  (Xil_In32(DMA_BASE_ADDR+0x10))>>6;
	xil_printf("MM2S_CURDESC:%x\n\r",MM2S_CURDESC);
	xil_printf("MM2S_TAILDESC:%x\n\r",MM2S_TAILDESC);


	print("AFTER STOP\n\r");

	MM2S_DMACR =  (Xil_In32(DMA_BASE_ADDR+0));
	MM2S_DMACR = MM2S_DMACR & 0x00000001;
	xil_printf("RS:%d\n\r",MM2S_DMACR);

	MM2S_DMASR =  (Xil_In32(DMA_BASE_ADDR+4));
	MM2S_DMASR = (MM2S_DMASR & 0x00000001);
	xil_printf("Halted:%d\n\r",MM2S_DMASR);

	MM2S_DMASR =  (Xil_In32(DMA_BASE_ADDR+4));
	MM2S_DMASR = (MM2S_DMASR & 0x00000002)>>1;
	xil_printf("Idle:%d\n\r",MM2S_DMASR);

	MM2S_DMASR =  (Xil_In32(DMA_BASE_ADDR+4));
	MM2S_DMASR = (MM2S_DMASR & 0x00000100)>>8;
	xil_printf("DMA error:%d\n\r",MM2S_DMASR);

	MM2S_DMASR =  (Xil_In32(DMA_BASE_ADDR+4));
	MM2S_DMASR = (MM2S_DMASR & 0x00001000)>>12;
	xil_printf("IRQ CMPLTD:%d\n\r",MM2S_DMASR);

	MM2S_DMASR =  (Xil_In32(DMA_BASE_ADDR+4));
	MM2S_DMASR = (MM2S_DMASR & 0x00005000)>>14;
	xil_printf("ERR IRQ CMPLTD:%d\n\r",MM2S_DMASR);


	xil_printf("CMPLT:%d\n\r",((Xil_In32(DESC1_ADDR+0x18))&0x80000000)>>31 );
	xil_printf("CMPLT:%d\n\r",((Xil_In32(DESC2_ADDR+0x18))&0x80000000)>>31 );
	xil_printf("CMPLT:%d\n\r",((Xil_In32(DESC3_ADDR+0x18))&0x80000000)>>31 );

    cleanup_platform();
    return 0;
}


void MM2S_ISR(void *CallbackRef)
{
//	DMA_MM2S_Flag=1;
//	u32 MM2S_DMASR_temp =  (Xil_In32(DMA_BASE_ADDR+4));
//	Xil_Out32(DMA_BASE_ADDR+4,MM2S_DMASR_temp&0x00005000);
//	xil_printf("done IRQ");
}

void print_DDR_cell_u8(u8 *data,u16 size)
{
	int i;
    for(i=0;i<size;i++)
    {
    	xil_printf("%d:%d\r\n",i,data[i]);
    }
}

 

 

 

 

This is print log:

DESCRIPTORS---

DESC1:

NXTDESC:900040

BUFADDR:200000

LEN:100

SOF:1

EOF:0

CMPLT:0


DESC2:

NXTDESC:900080

BUFADDR:300000

LEN:100

SOF:0

EOF:0

CMPLT:0

 

DESC3:

NXTDESC:900000

BUFADDR:400000

LEN:100

SOF:0

EOF:1

CMPLT:0

 

BEFORE START

RS:0

Halted:1

Idle:0

DMA error:0

IRQ CMPLTD:0

ERR IRQ CMPLTD:0

MM2S_CURDESC:900000

MM2S_TAILDESC:900080

AFTER STOP

RS:0

Halted:1

Idle:0

DMA error:1

IRQ CMPLTD:0

ERR IRQ CMPLTD:1

CMPLT:0

CMPLT:0

CMPLT:0

 

Any help would be appreciated. 

 

 

Tags (2)
0 Kudos
0 Replies