This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

C6748读写DDR2速度过慢



您好,本人在用DSP6748对DDR2进行读写测试中,发现全地址读写完成用的时间非常长,耗时10分钟。

配置如下:

DDR2controller时钟配置为300MHz,系统晶振25MHz, DDR时钟配置:device_PLL1(23,1,0,1,2)

寄存器配置:

DEVICE_DDRConfig(unsigned int ddr_type, unsigned int freq)

{

   unsigned int j;

   unsigned int tmp_SDCR;

  

   // Enable the Clock to EMIFDDR SDRAM

   PSC1_LPSC_enable(PD0, LPSC_DDR);

 

   // Begin VTP Calibration

   VTPIO_CTL &= ~0x00000040;       // Clear POWERDN

   VTPIO_CTL &= ~0x00000080;       // Clear LOCK

   VTPIO_CTL |= 0x00002000;      // Set CLKRZ in case it was cleared before (VTP looks for CLKRZ edge transition)

   VTPIO_CTL &= ~0x00002000;       // Clear CLKRZ (Use read-modify-write to ensure 1 VTP cycle wait for previous instruction)

   VTPIO_CTL |= 0x00002000;       // Set CLKRZ (Use read-modify-write to ensure 1 VTP cycle wait for previous instruction)

 

   j = 0;

   // Polling READY bit to see when VTP calibration is done

   while((VTPIO_CTL & 0x00008000) == 0) {

     if( j++ > VTP_TIMEOUT ) {

       GEL_TextOut("\tVTP Ready timeout\n","Output",1,1,1);          

       break;

     }

   }

 

   VTPIO_CTL |= 0x00000080;       // Set LOCK bit for static calibration mode

   VTPIO_CTL |= 0x00000040;       // Set POWERDN bit to power down VTP module

   // End VTP Calibration

 

   VTPIO_CTL |= 0x00004000;       // Set IOPWRDN to allow powerdown of input receivers when PWRDNEN is set

 

   // **********************************************************************************************

   // Setting based 1Gb DDR2 Samsung K4T1G164QF-BCF8

   // Config DDR timings

   DRPYC1R     = (0x0               << 8)   | // Reserved

                 (0x1               << 7)   | // EXT_STRBEN

                 (0x1               << 6)   | // PWRDNEN

                 (0x0              << 3)   | // Reserved

                 (0x4               << 0);     // RL

   // DRPYC1R Value = 0x000000C4

 

   if( DDR_DEBUG ) {

     // Configure EMIF with max timings for more slack

     // Try this if memory is not stable

     DRPYC1R |= 0x7; // RL

   }

 

   EMIFDDR_SDCR |= 0x00800000; // Set BOOTUNLOCK

 

   // Settings depending on DDR2

     tmp_SDCR = (0x0               << 25) | // MSDRAMEN

                 (0x1               << 20);   // DDR2EN

     GEL_TextOut("\tUsing DDR2 settings\n","Output",1,1,1);

 

 

   EMIFDDR_SDCR = tmp_SDCR                   | // Settings that change depending on DDR2 or MDDR

                   (EMIFDDR_SDCR & 0xF0000000) | // Reserved

                   (0x0               << 27)   | // DDR2TERM1

                   (0x0               << 26)   | // IBANK_POS

                   (0x0               << 24)   | // DDRDRIVE1

                   (0x0               << 23)   | // BOOTUNLOCK

                   (0x0               << 22)   | // DDR2DDQS

                   (0x0               << 21)   | // DDR2TERM0

                   (0x0               << 19)   | // DDRDLL_DIS

                   (0x0               << 18)   | // DDRDRIVE0

                   (0x1               << 17)   | // DDREN

                   (0x1               << 16)   | // SDRAMEN

                   (0x1               << 15)   | // TIMUNLOCK

                   (0x1               << 14)   | // NM

                   (0x0               << 12)   | // Reserved

                  (0x4               << 9)   | // CL

                   (0x0               << 7)   | // Reserved

                   (0x3               << 4)   | // IBANK

                   (0x0               << 3)   | // Reserved

                   (0x2               << 0);     // PAGESIZE

  

   EMIFDDR_SDCR2   = 0x00000000; // IBANK_POS set to 0 so this register does not apply

 

   if( DDR_DEBUG ) {

     // Configure EMIF with max timings for more slack

     // Try this if memory is not stable

 

     EMIFDDR_SDTIMR1 = (0x7F << 25)             | // tRFC

                       (0x07 << 22)             | // tRP

                       (0x07 << 19)             | // tRCD

                       (0x07 << 16)             | // tWR

                       (0x1F << 11)             | // tRAS

                       (0x1F << 6)             | // tRC

                       (0x07 << 3)             | // tRRD

                       (EMIFDDR_SDTIMR1 & 0x4) | // Reserved

                        (0x03 << 0);               // tWTR

    

     EMIFDDR_SDTIMR2 = (EMIFDDR_SDTIMR2 & 0x80000000)                       | // Reserved

                       (((unsigned int) ((70000 / 3400) - 0.5)) << 27)   | // tRASMAX (original 7812.5)

                       (0x3                                       << 25)   | // tXP

                       (0x0                                       << 23)   | // tODT (Not supported)

                       (0x7F                                      << 16)   | // tXSNR

                       (0xFF                                       << 8)   | // tXSRD

                       (0x07                                       << 5)   | // tRTP (1 Cycle)

                       (0x1F                                      << 0);     // tCKE

 

  

     GEL_TextOut("\tDDR Timings Configured for Debug\n","Output",1,1,1);

   }

   else {

     // Let float -> integer truncate handle minus 1; Safer to round up for timings

     EMIFDDR_SDTIMR1 = (((unsigned int) (127.5 * freq / 1000)) << 25) | // tRFC

                       (((unsigned int) (13.13 * freq / 1000)) << 22) | // tRP

                       (((unsigned int) (13.13 * freq / 1000)) << 19) | // tRCD

                       (((unsigned int) ( 15.0 * freq / 1000)) << 16) | // tWR

                       (((unsigned int) ( 45.0 * freq / 1000)) << 11) | // tRAS

                       (((unsigned int) (58.13 * freq / 1000)) << 6)   | // tRC

                      (((unsigned int) ( 7.5 * freq / 1000)) << 3)   | // tRRD

                       (EMIFDDR_SDTIMR1 & 0x4)                         | // Reserved

                       ((2 - 1)                                 << 0);     // tWTR

  

     EMIFDDR_SDTIMR2 = (EMIFDDR_SDTIMR2 & 0x80000000)                   | // Reserved

                       (((unsigned int) ((70000 / 7800) - 1))   << 27)   | // tRASMAX (original 3400)

                       ((0x3-1)                                 << 25)   | // tXP (Should be 6-1 per MT46H64M16LFBF-6 datasheet, but field only goes up to 0b11)

                       (0x0                                     << 23)   | // tODT (Not supported)

                       (((unsigned int) (137.5 * freq / 1000)) << 16)   | // tXSNR (tXSR for mDDR)

                       ((200-1)                                                     << 8)   | // tXSRD (tXSR for mDDR)

                       ((2 - 1)                                << 5)   | // tRTP

                       ((3 - 1)                                 << 0);     // tCKE

       }

   EMIFDDR_SDCR   &= ~0x00008000; // Clear TIMUNLOCK

 

   // Let float -> integer truncate handle RR round-down; Safer to round down for refresh rate

   EMIFDDR_SDRCR   = (0x1                                 << 31) | // LPMODEN (Required for LPSC SyncReset/Enable)

                     (0x1                                 << 30) | // MCLKSTOPEN (Required for LPSC SyncReset/Enable)

                     (0x0                                 << 24) | // Reserved

                     (0x0                                 << 23) | // SR_PD

                     (0x0                                 << 16) | // Reserved

                     (((unsigned int) (7.8 * freq))         << 0);     // RR (original 7.8125)

 

   // SyncReset the Clock to EMIFDDR SDRAM

   PSC1_LPSC_SyncReset(PD0, LPSC_DDR);

 

   // Enable the Clock to EMIFDDR SDRAM

   PSC1_LPSC_enable(PD0, LPSC_DDR);

 

   // Disable self-refresh

   EMIFDDR_SDRCR &= ~0xC0000000;

      

   // Set PBBPR to a value lower than default to prevent blocking

   EMIFDDR_PBBPR = 0x30;

}

 

DDR2采用IS43/46DR16640C,64Mx16,读写长度为0x7F00000

读写测试程序:

       for (iSDRAMindex = 0; iSDRAMindex < DDR_SIZE; iSDRAMindex++)

       {

           *(pcSDRAMStorrage+iSDRAMindex) = 0x55;//

           if ( *(pcSDRAMStorrage+iSDRAMindex) != 0x55)

           {

               retVal = STW_EFAIL;

               break;

           }

       }

 望予以指导和建议,感激不尽