搜索
bottom↓
回复: 9

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

[复制链接]

出0入0汤圆

发表于 2013-4-12 12:23:59 | 显示全部楼层 |阅读模式
请问下各位LPC1788的SDRAM都能跑到什么频率?

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

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

阿莫论坛20周年了!感谢大家的支持与爱护!!

月入3000的是反美的。收入3万是亲美的。收入30万是移民美国的。收入300万是取得绿卡后回国,教唆那些3000来反美的!

出0入0汤圆

发表于 2013-4-12 17:23:32 | 显示全部楼层
我画过好几次1788的板子了,有几款都是双层的,只要保证工作电压3.3V很稳定,个人认为不需要蛇形走线,不知道楼主是采用什么方法检测SDRAM在>60M出错的?

出0入0汤圆

发表于 2013-4-12 17:55:45 | 显示全部楼层
记得芯片手册里面电气特性部分说最高是80M

出0入0汤圆

发表于 2013-4-12 19:29:01 | 显示全部楼层
目前跑60M,还没有发现问题

出0入0汤圆

 楼主| 发表于 2013-4-12 21:15:18 | 显示全部楼层
gnocy 发表于 2013-4-12 19:29
目前跑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_ADDR  0xA0000000


/*********************************************************************
*
*       _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): 3  CCLK cycles
    // CAS latency (CAS)                             : 3  CCLK 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);
}

出0入0汤圆

发表于 2013-4-12 21:18:01 | 显示全部楼层
跑过120M,没发现问题

出0入0汤圆

 楼主| 发表于 2013-4-12 21:23:11 | 显示全部楼层
tangleon 发表于 2013-4-12 21:18
跑过120M,没发现问题


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

出0入0汤圆

发表于 2013-4-12 23:26:44 | 显示全部楼层
离职了 做不了测试了
当时没用校准
也没用分频什么的
如果有事物,用示波器测下clk可以吗

出0入0汤圆

发表于 2013-4-12 23:28:20 | 显示全部楼层
//
//HY57V641620FTP-7  4Bank x 1M x 16bits
//
void SDRAMInit( void )
{
        static u32  dwtemp;
        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);       

出0入0汤圆

发表于 2014-10-31 15:36:52 | 显示全部楼层
回帖提示: 反政府言论将被立即封锁ID 在按“提交”前,请自问一下:我这样表达会给举报吗,会给自己惹麻烦吗? 另外:尽量不要使用Mark、顶等没有意义的回复。不得大量使用大字体和彩色字。【本论坛不允许直接上传手机拍摄图片,浪费大家下载带宽和论坛服务器空间,请压缩后(图片小于1兆)才上传。压缩方法可以在微信里面发给自己(不要勾选“原图),然后下载,就能得到压缩后的图片】。另外,手机版只能上传图片,要上传附件需要切换到电脑版(不需要使用电脑,手机上切换到电脑版就行,页面底部)。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

手机版|Archiver|amobbs.com 阿莫电子技术论坛 ( 粤ICP备2022115958号, 版权所有:东莞阿莫电子贸易商行 创办于2004年 (公安交互式论坛备案:44190002001997 ) )

GMT+8, 2024-4-26 13:07

© Since 2004 www.amobbs.com, 原www.ourdev.cn, 原www.ouravr.com

快速回复 返回顶部 返回列表