Hello,
I want to use EDMA during booting. So i am testing data transfer from
ARM RAM to DRR2. Copying from DRR to arm goes fine. But during copying
from arm to ddr2, every (29-31)th bytes are broken. Any ideas?
As the base application i use spraai0-application. Here is the patch for it:
diff -uNr uartapp/dm644x.h Quartapp/dm644x.h
--- uartapp/dm644x.h 2006-11-15 13:39:28.000000000 +0300
+++ Quartapp/dm644x.h 2008-01-24 15:33:09.000000000 +0300
@@ -180,6 +180,72 @@
#define DDR_TEST_PATTERN 0xA55AA55Au
#define DDR_RAM_SIZE 0x10000000u
+/*----------------------------------------------------------------------------
+DMA register structure
+------------------------------------------------------------------------------*/
+
+#define DMA_REG_BASE 0x01C00000
/*base for dma registers*/
+
+#define PARAM_SET_BASE (DMA_REG_BASE + 0x4000)
/*base for PaRAM sets*/
+#define PARAM_SET_OFFSET 0x20
/*offset between PaRAM stes*/
+#define PARAM_SET(n) (PARAM_SET_BASE + n * PARAM_SET_OFFSET) /*PaRAM
set n*/
+
+#define DMA_DRAE (0x0340 + DMA_REG_BASE)
/*Region access
enable. low part*/
+#define DMA_DRAE_H (0x0344 + DMA_REG_BASE)
/*Region access
enable*. high part*/
+
+#define DMA_IPR (0x1068 + DMA_REG_BASE)
/*Interrupt pending
register. low part*/
+#define DMA_IPR_H (0x106C + DMA_REG_BASE)
/*Interrupt pending
register. high part*/
+
+#define DMA_EMR (0x0300 + DMA_REG_BASE)
/*Event missed. low part*/
+#define DMA_EMR_H (0x0304 + DMA_REG_BASE)
/*Event missed. high part*/
+
+#define DMA_CCERR (0x0318 + DMA_REG_BASE)
/*Error*/
+
+#define DMA_SER (0x1038 + DMA_REG_BASE)
/*Secondary event. low part*/
+#define DMA_SER_H (0x103C + DMA_REG_BASE)
/*Secondary event. high part*/
+
+#define DMA_SECR (0x1040 + DMA_REG_BASE)
/*Secondary event
clear. low part*/
+#define DMA_SECR_H (0x1044 + DMA_REG_BASE)
/*Secondary event
clear. high part*/
+
+#define DMA_ICR (0x1070 + DMA_REG_BASE)
/*Interrupt clear
register. low pert*/
+#define DMA_ICR_H (0x1074 + DMA_REG_BASE)
/*Interrupt clear
register. high part*/
+
+#define DMA_IESR (0x1060 + DMA_REG_BASE)
/*Interrupt set
enable. low part*/
+#define DMA_IESR_H (0x1064 + DMA_REG_BASE)
/*Interrupt set
enable. high part*/
+
+#define DMA_ESR (0x1010 + DMA_REG_BASE)
/*Event set. low part*/
+#define DMA_ESR_H (0x1014 + DMA_REG_BASE)
/*Event set. high part*/
+
+#define DMA_IPR_0 (0x2068 + DMA_REG_BASE)
/*Interrupt pending
register. low part. region 0*/
+#define DMA_IPR_H_0 (0x206C + DMA_REG_BASE)
/*Interrupt pending
register. high part. region 0*/
+
+#define DMA_ICR_0 (0x2070 + DMA_REG_BASE)
/*Interrupt clear
register. low pert. region 0*/
+#define DMA_ICR_H_0 (0x2074 + DMA_REG_BASE)
/*Interrupt clear
register. high part. region 0*/
+
+#define DMA_IER_0 (0x2050 + DMA_REG_BASE)
/*Interrupt enable.
low part. region 0*/
+#define DMA_IER_H_0 (0x2054 + DMA_REG_BASE)
/*Interrupt enable.
high part. region 0*/
+
+#define DMA_IESR_0 (0x2060 + DMA_REG_BASE)
/*Interrupt set
enable. low part. region 0*/
+#define DMA_IESR_H_0 (0x2064 + DMA_REG_BASE)
/*Interrupt set
enable. high part. region 0*/
+
+#define DMA_ESR_0 (0x2010 + DMA_REG_BASE)
/*Event set. low
part. region 0*/
+#define DMA_ESR_H_0 (0x2014 + DMA_REG_BASE)
/*Event set. high
part. region 0*/
+
+typedef struct _dma_regs_
+{
+ volatile unsigned int OPT;
+ volatile unsigned int SRC;
+ volatile unsigned int BCNT_ACNT;
+ volatile unsigned int DST;
+ volatile unsigned int DSTBIDX_SRCBIDX;
+ volatile unsigned int BCTNRDL_LINK;
+ volatile unsigned int DSTCIDX_SRCCIDX;
+ volatile unsigned int CCNT_Rsvd;
+} dmaRegs;
+
+#define DMA_PARAM_SET_N(n) ((dmaRegs*)PARAM_SET(n))
+
+#define DDR_MEM_BASE 0x80000000u
/* -------------------------------------------------------------------------- *
* AEMIF Register structure - See sprue20a.pdf for more details. *
diff -uNr uartapp/uartapp.c Quartapp/uartapp.c
--- uartapp/uartapp.c 2006-11-15 15:41:08.000000000 +0300
+++ Quartapp/uartapp.c 2008-01-24 15:58:56.000000000 +0300
@@ -66,6 +66,129 @@
return E_PASS;
}
+#define DMA_TO_ARM
+/*#define DMA_FROM_ARM*/
+
+#define SET_REGISTER(rg, vl) (*(unsigned int*)rg) = vl;
+
+unsigned int DMATest(void)
+{
+ const unsigned int value = 0x55AA55AA;
+ const unsigned int startPoint = 0;
+ const unsigned int startPoint2 = 1024;
+ const int size = 512;
+ const int set = 0; /*Number of PaRAM set*/
+
+ unsigned int res = E_PASS;
+ int i = 0, j = 0;
+ volatile unsigned int array[size];
+ volatile unsigned int array2[size];
+
+#ifdef DMA_FROM_ARM
+ for(i = 0; i < size; i++)
+ array[i] = value;
+#else
+ for(i = startPoint2; i < size + startPoint2; i++)
+ DDRMem[i] = value;
+#endif
+#ifdef DMA_TO_ARM
+ for(i = 0; i < size; i++)
+ array2[i] = 0;
+#else
+ for(i = startPoint; i < size + startPoint; i++)
+ DDRMem[i] = 0;
+#endif
+
+ UARTSendData("\r\nStarting DMA test. ");
+#ifdef DMA_TO_ARM
+ UARTSendData("To ARM ");
+#else
+ UARTSendData("To DDR2 ");
+#endif
+#ifdef DMA_FROM_ARM
+ UARTSendData("from ARM");
+#else
+ UARTSendData("from DDR2");
+#endif
+
+ // Enable interrupt
+ SET_REGISTER(DMA_IESR, 1 << set)
+
+ i = 10; while(i > 0){asm (" NOP");i--;}
+
+ // Set PaRAM
+ DMA_PARAM_SET_N(set)->OPT = 0x00100008u;
// Non static,
completion interrupt enabled
+ DMA_PARAM_SET_N(set)->BCNT_ACNT = 0x00010000u | size * 4;
// BCNT =
1; ACNT = size * 4
+ DMA_PARAM_SET_N(set)->BCTNRDL_LINK = 0xFFFFu;
// No link
+ DMA_PARAM_SET_N(set)->CCNT_Rsvd = 0x1u;
// CCNT = 1
+#ifdef DMA_FROM_ARM
+ DMA_PARAM_SET_N(set)->SRC = (unsigned int)array;
// Source
+#else
+ DMA_PARAM_SET_N(set)->SRC = DDR_MEM_BASE + startPoint2 * 4;
// Source
+#endif
+#ifdef DMA_TO_ARM
+ DMA_PARAM_SET_N(set)->DST = (unsigned int)array2;
// Destination
+#else
+ DMA_PARAM_SET_N(set)->DST = DDR_MEM_BASE + startPoint * 4;
// Destination
+#endif
+
+ i = 10; while(i > 0){asm (" NOP");i--;} /*without this it hangs*/
+
+ /* Start transfer*/
+ SET_REGISTER(DMA_ESR, 1 << set)
+
+ UARTSendData("\r\nEnter loop.");
+ while(!(*(unsigned int*)DMA_IPR))
+ {
+ asm (" NOP");
+ }
+
+ UARTSendData("\r\nError status = ");
+ UARTSendInt((*(unsigned int*)DMA_CCERR));
+ UARTSendData("\r\nMissed events = ");
+ UARTSendInt((*(unsigned int*)DMA_EMR));
+ UARTSendData("\r\nMissed events (H) = ");
+ UARTSendInt((*(unsigned int*)DMA_EMR_H));
+
+ UARTSendData("\r\nChecking...");
+#ifdef DMA_TO_ARM
+ for(i = 0; i < size; i++)
+ {
+ if(array2[i] != value)
+ {
+ UARTSendData("\r\nTest failed at ");
+ UARTSendInt((unsigned int)i);
+ UARTSendData(" value = ");
+ UARTSendInt(array2[i]);
+ res = E_FAIL;
+ if(array2[i] == 0)
+ {
+ UARTSendData("\r\nZero");
+ break;
+ }
+ }
+ }
+#else
+ for(i = startPoint, j = 0; i < size + startPoint; i++, j++)
+ {
+ if(DDRMem[i] != value)
+ {
+ UARTSendData("\r\nTest failed at ");
+ UARTSendInt((unsigned int)j);
+ UARTSendData(" value = ");
+ UARTSendInt(DDRMem[i]);
+ res = E_FAIL;
+ if(DDRMem[i] == 0)
+ {
+ UARTSendData("\r\nZero");
+ break;
+ }
+ }
+ }
+#endif
+ return res;
+}
+
void aemif_start()
{
asm (" NOP"); //needed to prevent compiler optimizing away
@@ -89,6 +212,7 @@
UARTSendData("\t1) Print Hello World!.\r\n");
UARTSendData("\t2) Initialize and test DDR RAM.\r\n");
UARTSendData("\t3) Boot out of NOR flash.\r\n");
+ UARTSendData("\t4) Test DMA.\r\n");
UARTSendData("\n\tEnter selection followed by <Enter>: ");
while (UARTRecvData(2,inData) != E_PASS);
@@ -107,6 +231,12 @@
case (3):
aemif_start();
break;
+ case (4):
+ if(DMATest() == E_PASS)
+ UARTSendData("\r\nDMA Test Passed");
+ else
+ UARTSendData("\r\nDMA Test Failed");
+ break;
default:
UARTSendData("\r\nInvalid Selection!\r\n");
break;
diff -uNr uartapp/uartapp.h Quartapp/uartapp.h
--- uartapp/uartapp.h 2006-11-15 15:41:10.000000000 +0300
+++ Quartapp/uartapp.h 2008-01-24 15:31:59.000000000 +0300
@@ -13,6 +13,7 @@
void aemif_start( void ) __attribute__((naked,section(".aemif")));
unsigned int DDRTest(void);
+unsigned int DMATest(void);
int uartapp_main( void );
_______________________________________________
Davinci-linux-open-source mailing list
[email protected]
http://linux.davincidsp.com/mailman/listinfo/davinci-linux-open-source