electrlife 发表于 2013-4-12 12:23:59

请问下各位LPC1788的SDRAM都能跑到什么频率?

请问下各位LPC1788的SDRAM都能跑到什么频率?

本人使用LPC1788的SDRAM,芯片是HY57XX,外部的频率只能跑在60HZ,
再高的话,有时会出错!想了解下,各位用LPC1788的,EMC能跑到多少!

难道会和布线有关吗?按说100MHZ的速度应该不需要蛇形等长吧!!

chishangpiao 发表于 2013-4-12 17:23:32

我画过好几次1788的板子了,有几款都是双层的,只要保证工作电压3.3V很稳定,个人认为不需要蛇形走线,不知道楼主是采用什么方法检测SDRAM在>60M出错的?

lanshuitianxia 发表于 2013-4-12 17:55:45

记得芯片手册里面电气特性部分说最高是80M

gnocy 发表于 2013-4-12 19:29:01

目前跑60M,还没有发现问题

electrlife 发表于 2013-4-12 21:15:18

gnocy 发表于 2013-4-12 19:29 static/image/common/back.gif
目前跑60M,还没有发现问题

跑60MHZ,我也是的,没什么问题!下面给下我的SDRAM(H57V256)的代码,各位可以简单测试下,能跑多少频率?
代码是参照其它程序的!


#define NSPERCLK            ((1000 * 1000000) / SystemCoreClock)
#define EMC_NS2CLK(ns)      ((ns + NSPERCLK - 1) / NSPERCLK)

/*********************************************************************
*
*       SDRAM settings
*/
#define SDRAM_SIZE_MB    64
#define SDRAM_SIZE       (SDRAM_SIZE_MB * 1024 * 1024)
#define SDRAM_BASE_ADDR0xA0000000


/*********************************************************************
*
*       _DelayMs()
*
* Function description:
*   Starts a timer and waits for the given delay in ms.
*/
static void _DelayMs(uint32_t ms) {
    LPC_TIM0->TCR = 0x02;// Reset timer
    LPC_TIM0->PR= 0x00;// Set prescaler to zero
    LPC_TIM0->MR0 = ms * (SystemCoreClock / (LPC_SC->PCLKSEL & 0x1F) / 1000 - 1);
    LPC_TIM0->IR= 0xFF;// Reset all interrrupts
    LPC_TIM0->MCR = 0x04;// Stop timer on match
    LPC_TIM0->TCR = 0x01;// Start timer
    //
    // Wait until delay time has elapsed
    //
    while (LPC_TIM0->TCR & 1);
}

/*********************************************************************
*
*       _TestSDRAM()
*
*Function description:
*    Simple SDRAM test for testing timing setup
*
*Return value:
*    1: Error
*    0: O.K.
*/
static int _TestSDRAM(void) {
    volatile uint32_t * pWriteLong;
    volatile uint16_t * pWriteShort;
    uint32_t   Data;
    uint32_t   i;
    uint32_t   j;
   
    pWriteLong= (uint32_t*)SDRAM_BASE_ADDR;
    pWriteShort = (uint16_t*)SDRAM_BASE_ADDR;
    //
    // Fill 16 bit wise
    //
    for (i = 0; i < (SDRAM_SIZE / 0x40000); i++) {
      for (j = 0; j < 0x100; j++) {
            *pWriteShort++ = (i + j);
            *pWriteShort++ = (i + j) + 1;
      }
    }
    //
    // Verifying
    //
    pWriteLong = (uint32_t*)SDRAM_BASE_ADDR;
    for (i = 0; i < (SDRAM_SIZE / 0x40000); i++) {
      for (j = 0; j < 0x100; j++) {
            Data = *pWriteLong++;
            if (Data != (((((i + j) + 1) & 0xFFFF) << 16) | ((i + j) & 0xFFFF))) {
                return 1;// Error
            }
      }
    }
    return 0;// O.K.
}

/*********************************************************************
*
*       _FindDelay()
*
*Function description:
*    Test for min./max. CMDDLY or FBCLKDLY values
*
*Parameter:
*    DelayType: 0 = CMDDLY, 1 = FBCLKDLY
*/
static void _FindDelay(int DelayType) {
    uint32_t Delay;
    uint32_t Min;
    uint32_t Max;
    uint32_t v;
   
    //
    // Init start values
    //
    Delay = 0x00;
    Min   = 0xFF;
    Max   = 0xFF;
    //
    // Test for DLY min./max. values
    //
    while (Delay < 32) {
      //
      // Setup new DLY value to test
      //
      if (DelayType == 0) {
            v               = LPC_SC->EMCDLYCTL & ~0x001Ful;
            LPC_SC->EMCDLYCTL = v | Delay;
      } else {
            v               = LPC_SC->EMCDLYCTL & ~0x1F00ul;
            LPC_SC->EMCDLYCTL = v | (Delay << 8);
      }
      //
      // Test configured DLY value and find out min./max. values that will work
      //
      if (_TestSDRAM() == 0) {
            //
            // Test passed, remember min. DLY value if not done yet
            //
            if (Min == 0xFF) {
                Min = Delay;
            }
      } else {
            //
            // Test failed, if a min. value has been found before, remember the current value for max.
            //
            if (Min != 0xFF) {
                Max = Delay;
            }
      }
      Delay++;
    }
    //
    // Calc DLY value
    //
    if      (Max != 0xFF) {// If we found a min. and max. value we use the average of the min. and max. values to get an optimal DQSIN delay
      Delay = (Min + Max) / 2;
    } else if (Min != 0xFF) {// If we found only a min. value we use the average of the min. value and the longest DLY value to get an optimal DQSIN delay
      Delay = (Min + 0x1F) / 2;
    } else {                   // No working max. and/or min. values found
      while (1);// Fatal error
    }
    //
    // Setup DLY value to work with
    //
    if (DelayType == 0) {
      v               = LPC_SC->EMCDLYCTL & ~0x001Ful;
      LPC_SC->EMCDLYCTL = v | Delay;
    } else {
      v               = LPC_SC->EMCDLYCTL & ~0x1F00ul;
      LPC_SC->EMCDLYCTL = v | (Delay << 8);
    }
}

/*********************************************************************
*
*       _CalibrateOsc()
*
*Function description:
*    Calibrate ring oscillator.
*
*Return value:
*    Current ring oscillator count
*/
static uint32_t _CalibrateOsc(void) {
    uint32_t Cnt;
    uint32_t v;
    uint32_t i;
   
    //
    // Init start values
    //
    Cnt = 0;
    //
    // Calibrate osc.
    //
    for (i = 0; i < 10; i++) {
      LPC_SC->EMCCAL = (1 << 14);   // Start calibration
      v = LPC_SC->EMCCAL;
      while ((v & (1 << 15)) == 0) {// Wait for calibration done
            v = LPC_SC->EMCCAL;
      }
      Cnt += (v & 0xFF);
    }
    return (Cnt / 10);
}

/*********************************************************************
*
*       _AdjustEMCTiming()
*
*Function description:
*    Adjust timings for EMC.
*/
static void _AdjustEMCTiming(uint32_t Delay) {
    uint32_t v;
    uint32_t CmdDly;
    uint32_t FBDelay;
    uint32_t FBClkDly;
   
    FBDelay = _CalibrateOsc();
   
    v = LPC_SC->EMCDLYCTL;
    CmdDly            = ((v &0x001Ful) * Delay / FBDelay) & 0x1F;
    FBClkDly          = ((v &0x1F00ul) * Delay / FBDelay) & 0x1F00;
    LPC_SC->EMCDLYCTL =(v & ~0x1F1Ful) | FBClkDly | CmdDly;
}

/*********************************************************************
*
*       _EMC_Init()
*
*Purpose:
*    Initializes external memory controller for SDRAM
*/
void SDRAMInit(void) {
    volatile uint32_t i;
    volatile uint32_t Dummy;
    volatile uint32_t CmdDly;
   
    LPC_SC->PCONP   |= (1 << 11);   // Turn on EMC peripheral clock
    LPC_SC->EMCDLYCTL= 0x00001010;
    LPC_EMC->Control   = 1;// EMC enable
    LPC_EMC->Config    = 0;
    //
    // Port init
    //
    LPC_IOCON->P3_0= 1;// D0
    LPC_IOCON->P3_1= 1;// D1
    LPC_IOCON->P3_2= 1;// D2
    LPC_IOCON->P3_3= 1;// D3
    LPC_IOCON->P3_4= 1;// D4
    LPC_IOCON->P3_5= 1;// D5
    LPC_IOCON->P3_6= 1;// D6
    LPC_IOCON->P3_7= 1;// D7
    LPC_IOCON->P3_8= 1;// D8
    LPC_IOCON->P3_9= 1;// D9
    LPC_IOCON->P3_10 = 1;// D10
    LPC_IOCON->P3_11 = 1;// D11
    LPC_IOCON->P3_12 = 1;// D12
    LPC_IOCON->P3_13 = 1;// D13
    LPC_IOCON->P3_14 = 1;// D14
    LPC_IOCON->P3_15 = 1;// D15
    LPC_IOCON->P3_16 = 1;// D16
    LPC_IOCON->P3_17 = 1;// D17
    LPC_IOCON->P3_18 = 1;// D18
    LPC_IOCON->P3_19 = 1;// D19
    LPC_IOCON->P3_20 = 1;// D20
    LPC_IOCON->P3_21 = 1;// D21
    LPC_IOCON->P3_22 = 1;// D22
    LPC_IOCON->P3_23 = 1;// D23
    LPC_IOCON->P3_24 = 1;// D24
    LPC_IOCON->P3_25 = 1;// D25
    LPC_IOCON->P3_26 = 1;// D26
    LPC_IOCON->P3_27 = 1;// D27
    LPC_IOCON->P3_28 = 1;// D28
    LPC_IOCON->P3_29 = 1;// D29
    LPC_IOCON->P3_30 = 1;// D30
    LPC_IOCON->P3_31 = 1;// D31
   
    LPC_IOCON->P4_0= 1;// A0
    LPC_IOCON->P4_1= 1;// A1
    LPC_IOCON->P4_2= 1;// A2
    LPC_IOCON->P4_3= 1;// A3
    LPC_IOCON->P4_4= 1;// A4
    LPC_IOCON->P4_5= 1;// A5
    LPC_IOCON->P4_6= 1;// A6
    LPC_IOCON->P4_7= 1;// A7
    LPC_IOCON->P4_8= 1;// A8
    LPC_IOCON->P4_9= 1;// A9
    LPC_IOCON->P4_10 = 1;// A10
    LPC_IOCON->P4_11 = 1;// A11
    LPC_IOCON->P4_12 = 1;// A12
    LPC_IOCON->P4_13 = 1;// A13
    LPC_IOCON->P4_14 = 1;// A14
    LPC_IOCON->P4_15 = 1;// A15
    LPC_IOCON->P4_16 = 1;// A16
    LPC_IOCON->P4_17 = 1;// A17
    LPC_IOCON->P4_18 = 1;// A18
    LPC_IOCON->P4_19 = 1;// A19
    LPC_IOCON->P4_20 = 1;// A20
    LPC_IOCON->P4_21 = 1;// A21
    LPC_IOCON->P4_22 = 1;// A22
    LPC_IOCON->P4_23 = 1;// A23
   
    LPC_IOCON->P4_24 = 1;// OE
    LPC_IOCON->P4_25 = 1;// WE
    //LPC_IOCON->P4_26 = 1;// BLS0
    //LPC_IOCON->P4_27 = 1;// BLS1
    //LPC_IOCON->P4_28 = 1;// BLS2
    //LPC_IOCON->P4_29 = 1;// BLS3
    //LPC_IOCON->P4_30 = 1;// CS0
    //LPC_IOCON->P4_31 = 1;// CS1
    //LPC_IOCON->P2_14 = 1;// CS2
    //LPC_IOCON->P2_15 = 1;// CS3
    LPC_IOCON->P2_16 = 1;// CAS
    LPC_IOCON->P2_17 = 1;// RAS
    LPC_IOCON->P2_18 = 1;// CLKOUT0
    //LPC_IOCON->P2_19 = 1;// CLKOUT1
    LPC_IOCON->P2_20 = 1;// DYCS0
    //LPC_IOCON->P2_21 = 1;// DYCS1
    //LPC_IOCON->P2_22 = 1;// DYCS2
    //LPC_IOCON->P2_23 = 1;// DYCS3
   
    LPC_IOCON->P2_24 = 1;// CKEOUT0
    //LPC_IOCON->P2_25 = 1;// CKEOUT1
    //LPC_IOCON->P2_26 = 1;// CKEOUT2
    //LPC_IOCON->P2_27 = 1;// CKEOUT3
    LPC_IOCON->P2_28 = 1;// DQMOUT0
    LPC_IOCON->P2_29 = 1;// DQMOUT1
    LPC_IOCON->P2_30 = 1;// DQMOUT2
    LPC_IOCON->P2_31 = 1;// DQMOUT3
    //
    // Setup EMC config for SDRAM, timings for 60MHz bus
    //
    LPC_EMC->DynamicConfig0    = 0x00004480;// 256MB, 8Mx32, 4 banks, 12 rows, 9 columns, buffers disabled
    LPC_EMC->DynamicReadConfig = 0x00000001;// Command delayed strategy, using EMCCLKDELAY
#if 0
    LPC_EMC->DynamicRasCas0    = 0x00000202;// 2 RAS, 2 CAS latency */
    LPC_EMC->DynamicRP         = 0x00000001;// n + 1 clock cycles
    LPC_EMC->DynamicRAS      = 0x00000003;// n + 1 clock cycles
    LPC_EMC->DynamicSREX       = 0x00000005;// n + 1 clock cycles
    LPC_EMC->DynamicAPR      = 0x00000002;// n + 1 clock cycles
    LPC_EMC->DynamicDAL      = 0x00000003;// n   clock cycles
    LPC_EMC->DynamicWR         = 0x00000001;// n + 1 clock cycles
    LPC_EMC->DynamicRC         = 0x00000004;// n + 1 clock cycles
    LPC_EMC->DynamicRFC      = 0x00000004;// n + 1 clock cycles
    LPC_EMC->DynamicXSR      = 0x00000005;// n + 1 clock cycles
    LPC_EMC->DynamicRRD      = 0x00000001;// n + 1 clock cycles
    LPC_EMC->DynamicMRD      = 0x00000001;// n + 1 clock cycles
#endif
    // -------------------------------------------------------------------------
    // RAS latency (active to read/write delay) (RAS): 3CCLK cycles
    // CAS latency (CAS)                           : 3CCLK cycles
    // -------------------------------------------------------------------------
    /* H57V2562GTR-75C: tCL=3CLK, tRCD=20ns(min), 3 CLK=24ns */
    LPC_EMC->DynamicRasCas0    = 0x00000303;
    LPC_EMC->DynamicRP         = EMC_NS2CLK(20);      /* 20ns,*/
    LPC_EMC->DynamicRAS      = EMC_NS2CLK(50);      /* 42ns to 100K ns,*/
    LPC_EMC->DynamicSREX       = 1 - 1;               /* tSRE, 1clk, */
    LPC_EMC->DynamicAPR      = 2 - 1;               /* Not found!!! Estimated as 2clk, */
    LPC_EMC->DynamicDAL      = EMC_NS2CLK(20) + 2;    /* tDAL = tRP + tDPL = 20ns + 2clk*/
    LPC_EMC->DynamicWR         = 2 - 1;               /* 2CLK,*/
    LPC_EMC->DynamicRC         = EMC_NS2CLK(63);      /* H57V2562GTR-75C tRC=63ns(min)*/
    LPC_EMC->DynamicRFC      = EMC_NS2CLK(63);      /* H57V2562GTR-75C tRFC=tRC */
    LPC_EMC->DynamicXSR      = 0x0000000F;            /* exit self-refresh to active, 不知道,设为最久*/
    LPC_EMC->DynamicRRD      = EMC_NS2CLK(63);      /* 3clk, tRRD=15ns(min) */
    LPC_EMC->DynamicMRD      = 2 - 1;               /* 2clk, tMRD=2clk(min) */

   
    _DelayMs(100);
    LPC_EMC->DynamicControl    = 0x00000183;// Issue NOP command
    _DelayMs(200);
    LPC_EMC->DynamicControl    = 0x00000103;// Issue PALL command
    LPC_EMC->DynamicRefresh    = 0x00000002;// n * 16 clock cycles
    for (i = 0; i < 0x80; i++);               // Wait 128 AHB clock cycles
    LPC_EMC->DynamicRefresh    = 0x0000003A;// n * 16 clock cycles
    //
    // Init SDRAM
    //
    LPC_EMC->DynamicControl = 0x00000083;                           // Issue MODE command
    Dummy = *((volatile uint32_t*)(SDRAM_BASE_ADDR | (0x32 << (2+2+9))));// 4 burst, 3 CAS latency
    LPC_EMC->DynamicControl = 0x00000000;                           // Issue NORMAL command
    LPC_EMC->DynamicConfig0 = 0x00084480;                           // 256MB, 8Mx32, 4 banks, 12 rows, 9 columns, buffers (re-)enabled
    //
    // Auto calibrate timings
    //
    CmdDly = _CalibrateOsc();
    //
    // Find best delay values
    //
    _FindDelay(0);// EMCDLY
    _FindDelay(1);// FBCLKDLY
    _AdjustEMCTiming(CmdDly);
}

tangleon 发表于 2013-4-12 21:18:01

跑过120M,没发现问题

electrlife 发表于 2013-4-12 21:23:11

tangleon 发表于 2013-4-12 21:18 static/image/common/back.gif
跑过120M,没发现问题

LS可以使用以上的测试部分程序,简单测下!
以下部分,测下是不是可以通过!
    //
    // Auto calibrate timings
    //
    CmdDly = _CalibrateOsc();
    //
    // Find best delay values
    //
    _FindDelay(0);// EMCDLY
    _FindDelay(1);// FBCLKDLY
    _AdjustEMCTiming(CmdDly);

tangleon 发表于 2013-4-12 23:26:44

离职了 做不了测试了
当时没用校准
也没用分频什么的
如果有事物,用示波器测下clk可以吗

tangleon 发表于 2013-4-12 23:28:20

//
//HY57V641620FTP-74Bank x 1M x 16bits
//
void SDRAMInit( void )
{
        static u32dwtemp;
        uint32_t mhz, nsPerClk;
        uint16_t wtemp = wtemp;

        EMCInit();
        Delay_ms(100);
        mhz = SystemCoreClock / 1000000;
        if (LPC_SC->EMCCLKSEL)
                mhz >>= 1;
        nsPerClk = 1000 / mhz;
    LPC_EMC->DynamicRP         = EMC_NS2CLK(20, nsPerClk)-1;
    LPC_EMC->DynamicRAS      = EMC_NS2CLK(42, nsPerClk)-1;
    LPC_EMC->DynamicSREX       = EMC_NS2CLK(70, nsPerClk)-1;
    LPC_EMC->DynamicAPR      = 2 - 1;
    LPC_EMC->DynamicDAL      = EMC_NS2CLK(20, nsPerClk) + 2-1;
    LPC_EMC->DynamicWR         = 2 - 1-1;
    LPC_EMC->DynamicRC         = EMC_NS2CLK(63, nsPerClk)-1;
    LPC_EMC->DynamicRFC      = EMC_NS2CLK(63, nsPerClk)-1;
    LPC_EMC->DynamicXSR      = EMC_NS2CLK(70, nsPerClk)-1;
    LPC_EMC->DynamicRRD      = EMC_NS2CLK(15, nsPerClk)-1;
    LPC_EMC->DynamicMRD      = 2 - 1;

    LPC_EMC->DynamicReadConfig = 0x00000001;
    LPC_EMC->DynamicRasCas0    = MDKCFG_RASCAS0VAL;

        LPC_EMC->DynamicConfig0    = 0x00000280;   
        Delay_ms(100);                                                  
        LPC_EMC->DynamicControl    = 0x00000183;
        Delay_ms(200);                                                          
        LPC_EMC->DynamicControl    = 0x00000103;
        LPC_EMC->DynamicRefresh    = 4;

        Delay_ms(200);                
        wtemp = 64000000 / (1 << 12);
        wtemp -= 16;
        wtemp >>= 4;
        wtemp = wtemp * mhz / 1000;
    LPC_EMC->DynamicRefresh    = wtemp;
       
        Delay_ms(200);       
        LPC_EMC->DynamicControl    = 0x00000083;
        dwtemp = *((volatile uint16_t *)(SDRAM_BASE_ADDR | (0x33<<11)));
        Delay_ms(20);
        LPC_EMC->DynamicControl    = 0x00000000;
        LPC_EMC->DynamicConfig0   |= 0x00080000;
        Delay_ms(100);       

Excellence 发表于 2014-10-31 15:36:52

{:lol:}{:lol:}{:lol:}
页: [1]
查看完整版本: 请问下各位LPC1788的SDRAM都能跑到什么频率?