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 Davinci-linux-open-source@linux.davincidsp.com http://linux.davincidsp.com/mailman/listinfo/davinci-linux-open-source