打印
[Atmel]

SAMV71读写SDRAM的错误问题

[复制链接]
1553|4
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
sz_user001|  楼主 | 2016-4-28 18:01 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
SAMV71读写SDRAM的错误问题


我自己做的SAMV71板子,配置了512MBit SDRAM (MT48LC32M16A1, 最高133MHz clock)。SDRAM同SAMV71的连接完全参照评估板“SAM_V71_Xplained”,配置程序也是基本照抄例子程序。

硬件连线上的变化是:多连接了A11,A12,BA1这3条线。
软件上配置程序的变化是:COL数目,ROW数目和BANK数目曾为1013,4. 另外刷新周期改为7~7.8us。
除以上不同,我的SDRAM部分的硬件,软件同demo板和例程完全一样。


但是反复折腾了几个星期,SDRAM的读写还是不正确:所有16bit word写入SDRAM后,bit1~15(在全部64M byte空间)完全正确,唯独bit0(在全部64M byte空间)读回来永远为0. 示波器查看了SDRAM的data0,也就是MCU的Pin11(PC00),在连续读写测试中在始终为高,在3.0v~3.3v,(不像其他数据线在0~3.3v间跳动)


硬件接线方面也查了,没有走线,短路问题。


请好心人帮忙分析下!不胜感激!



以下是SDRAM配置(基本同例程一样。)

//this is for 64M byte SDRam
#define PIN_SDRAM_D0_7      {0x000000FF, PIOC, ID_PIOC, PIO_PERIPH_A, PIO_DEFAULT}
#define PIN_SDRAM_D8_13     {0x0000003F, PIOE, ID_PIOE, PIO_PERIPH_A, PIO_DEFAULT}
#define PIN_SDRAM_D14_15    {0x00018000, PIOA, ID_PIOA, PIO_PERIPH_A, PIO_DEFAULT}
#define PIN_SDRAM_A0_9      {0x3FF00000, PIOC, ID_PIOC, PIO_PERIPH_A, PIO_DEFAULT}
#define PIN_SDRAM_SDA10     {0x00002000, PIOD, ID_PIOD, PIO_PERIPH_C, PIO_DEFAULT}
#define PIN_SDRAM_A11       {0x80000000, PIOC, ID_PIOC, PIO_PERIPH_A, PIO_DEFAULT}  //PC31
#define PIN_SDRAM_A12       {0x00040000, PIOA, ID_PIOA, PIO_PERIPH_C, PIO_DEFAULT}  //PA18

#define PIN_SDRAM_CAS       {0x00020000, PIOD, ID_PIOD, PIO_PERIPH_C, PIO_DEFAULT}
#define PIN_SDRAM_RAS       {0x00010000, PIOD, ID_PIOD, PIO_PERIPH_C, PIO_DEFAULT}
#define PIN_SDRAM_SDCKE     {0x00004000, PIOD, ID_PIOD, PIO_PERIPH_C, PIO_DEFAULT}
#define PIN_SDRAM_SDCK      {0x00800000, PIOD, ID_PIOD, PIO_PERIPH_C, PIO_DEFAULT}
#define PIN_SDRAM_SDSC      {0x00008000, PIOC, ID_PIOC, PIO_PERIPH_A, PIO_DEFAULT}
#define PIN_SDRAM_NBS0      {0x00040000, PIOC, ID_PIOC, PIO_PERIPH_A, PIO_DEFAULT}
#define PIN_SDRAM_NBS1      {0x00008000, PIOD, ID_PIOD, PIO_PERIPH_C, PIO_DEFAULT}
#define PIN_SDRAM_SDWE      {0x20000000, PIOD, ID_PIOD, PIO_PERIPH_C, PIO_DEFAULT}
#define PIN_SDRAM_BA0       {0x00100000, PIOA, ID_PIOA, PIO_PERIPH_C, PIO_DEFAULT}
#define PIN_SDRAM_BA1       {0x00000001, PIOA, ID_PIOA, PIO_PERIPH_C, PIO_DEFAULT}

#define BOARD_SDRAM_PINS PIN_SDRAM_D0_7, PIN_SDRAM_D8_13 , PIN_SDRAM_D14_15,\
PIN_SDRAM_A0_9, PIN_SDRAM_SDA10, PIN_SDRAM_BA0, PIN_SDRAM_BA1, PIN_SDRAM_A11, PIN_SDRAM_A12,\
PIN_SDRAM_CAS, PIN_SDRAM_RAS, PIN_SDRAM_SDCKE,PIN_SDRAM_SDCK,\
PIN_SDRAM_SDSC,PIN_SDRAM_NBS0 ,PIN_SDRAM_NBS1,PIN_SDRAM_SDWE


void ConfigureSdram(void)
{
   
        volatile uint32_t i;
        volatile uint8_t *pSdram = (uint8_t *) SDRAM_CS_ADDR;

        /* Configure PIO */
        PIO_Configure(pinsSdram, PIO_LISTSIZE(pinsSdram));
        PMC_EnablePeripheral(ID_SDRAMC);
        MATRIX->CCFG_SMCNFCS = CCFG_SMCNFCS_SDRAMEN;

        /* 1. SDRAM features must be set in the configuration register:
        asynchronous timings (TRC, TRAS, etc.), number of columns, rows,
        CAS latency, and the data bus width. */
   
        SDRAMC->SDRAMC_CR =
                SDRAMC_CR_NC_COL10      // 10 column bits
                | SDRAMC_CR_NR_ROW13     // 13 row bits (8K)
                | SDRAMC_CR_CAS_LATENCY3 // CAS Latency 3
                | SDRAMC_CR_NB_BANK4     // 4 banks
                | SDRAMC_CR_DBW          // 16 bit
                | SDRAMC_CR_TWR(2)                                                                //2016April17 --- should be 2
                | SDRAMC_CR_TRC_TRFC(9) // 63ns   min                        //2016April17 --- 66ns min, try 9, at 133MHz
                | SDRAMC_CR_TRP(3)       // Command period (PRE to ACT) 21 ns min        //2016April17 --- 20ns min, try 3, at 133MHz
                | SDRAMC_CR_TRCD(3)      // Active Command to read/Write Command delay time 21ns min  //2016April17 --- 20ns min, try 3, at 133MHz
                | SDRAMC_CR_TRAS(6)      // Command period (ACT to PRE)  42ns min                 //2016April17 --- 44ns min, try 6, at 133MHz
                | SDRAMC_CR_TXSR(10U);   // Exit self-refresh to active time  70ns Min         //2016April17 --- 75ns min, try 10, at 133MHz
   
        /* 2. For mobile SDRAM, temperature-compensated self refresh (TCSR), drive
        strength (DS) and partial array self refresh (PASR) must be set in the
        Low Power Register. */

        /* 3. The SDRAM memory type must be set in the Memory Device Register.*/
        SDRAMC->SDRAMC_MDR = SDRAMC_MDR_MD_SDRAM;

        /* 4. A minimum pause of 200 ¦Ìs is provided to precede any signal toggle.*/
        for (i = 0; i < 300; i++) Delay600Nop_1us();
   
        /* 5. (1)A NOP command is issued to the SDRAM devices. The application must
        set Mode to 1 in the Mode Register and perform a write access to
        any SDRAM address.*/
        SDRAMC->SDRAMC_MR = SDRAMC_MR_MODE_NOP;
        *pSdram = 0;

        for (i = 0; i < 300; i++) Delay600Nop_1us();

        /* 6. An All Banks Precharge command is issued to the SDRAM devices.
        The application must set Mode to 2 in the Mode Register and perform a write
        access to any SDRAM address. */
        SDRAMC->SDRAMC_MR = SDRAMC_MR_MODE_ALLBANKS_PRECHARGE;
        *pSdram = 0;

        for (i = 0; i < 300; i++) Delay600Nop_1us();

        /* 7. Eight auto-refresh (CBR) cycles are provided. The application must
        set the Mode to 4 in the Mode Register and perform a write access to any
        SDRAM location eight times.*/
        for (i = 0; i < 8; i++) {
                SDRAMC->SDRAMC_MR = SDRAMC_MR_MODE_AUTO_REFRESH;
                *pSdram = 0;
        }

        for (i = 0; i < 300; i++) Delay600Nop_1us();

        /*8. A Mode Register set (MRS) cycle is issued to program the parameters of
        the SDRAM devices, in particular CAS latency and burst length. The
        application must set Mode to 3 in the Mode Register and perform a write
        access to the SDRAM. The write address must be chosen so that BA[1:0]
        are set to 0. For example, with a 16-bit 128 MB SDRAM (12 rows, 9 columns,
        4 banks) bank address, the SDRAM write access should be done at the address
        0x70000000.*/
        SDRAMC->SDRAMC_MR = SDRAMC_MR_MODE_LOAD_MODEREG;
        *pSdram = 0;

        for (i = 0; i < 300; i++) Delay600Nop_1us();

        /*9. For mobile SDRAM initialization, an Extended Mode Register set (EMRS)
        cycle is issued to program the SDRAM parameters (TCSR, PASR, DS). The
        application must set Mode to 5 in the Mode Register and perform a write
        access to the SDRAM. The write address must be chosen so that BA[1] or BA[0]
        are set to 1.
        For example, with a 16-bit 128 MB SDRAM, (12 rows, 9 columns, 4 banks) bank
        address the SDRAM write access should be done at the address 0x70800000 or
        0x70400000. */
        //SDRAMC->SDRAMC_MR = SDRAMC_MR_MODE_EXT_LOAD_MODEREG;
        // *((uint8_t *)(pSdram + SDRAM_BA0)) = 0;

        /* 10. The application must go into Normal Mode, setting Mode to 0 in the
        Mode Register and performing a write access at any location in the SDRAM. */
        SDRAMC->SDRAMC_MR = SDRAMC_MR_MODE_NORMAL;
        *pSdram = 0;

        for (i = 0; i < 300; i++) Delay600Nop_1us();

        /* 11. Write the refresh rate into the count field in the SDRAMC Refresh
        Timer register. (Refresh rate = delay between refresh cycles).
        The SDRAM device requires a refresh every 15.625 ¦Ìs or 7.81 ¦Ìs.
        With a 100 MHz frequency, the Refresh Timer Counter Register must be set
        with the value 1562(15.625 ¦Ìs x 100 MHz) or 781(7.81 ¦Ìs x 100 MHz). */
        // For IS42S16100E, 2048 refresh cycle every 32ms, every 15.625 ¦Ìs
        /* ((32 x 10(^-3))/2048) x150 x (10^6) */
        //SDRAMC->SDRAMC_TR = 1562;
        //SDRAMC->SDRAMC_TR = 781;                                        //2016April17 --- should try 7.81us (64ms/8192), 7.81*133 (at 100MHz) = 781
        SDRAMC->SDRAMC_TR = 700;                                        //2016April17 --- should try 7.81us (64ms/8192), 7.81*133 (at 100MHz) = 781
        SDRAMC->SDRAMC_CFR1 |= SDRAMC_CFR1_UNAL;
        /* After initialization, the SDRAM devices are fully functional. */
}

相关帖子

沙发
sz_user001|  楼主 | 2016-4-30 16:13 | 只看该作者
今天把MCU的PC00脚抬起来,发现在运行我的SDRAM测试程序时,PC00根本就不动。

然后,我又另外写了程序,配置PC00和PC01为通用IO口输出,让PC00和PC01输出方波,发现PC01输出正确,PC00依然恒定为高。

难道MCU的PC00引脚坏了????

使用特权

评论回复
板凳
homey123| | 2016-5-3 11:49 | 只看该作者
在XPRO板子上试一下IO输出程序看看是不是好的吧。

使用特权

评论回复
地板
sz_user001|  楼主 | 2016-5-5 17:22 | 只看该作者
在XPRO板子上试一下IO输出程序看看是不是好的吧。  ---------    同样的测试程序,再另外一块板子上就可以让PC00动起来。而在这个板子上,就PC00动不了。MCU坏了??? can't believe it...

使用特权

评论回复
5
wuxingsheji| | 2016-5-6 12:00 | 只看该作者
在XPRO板子上试一下IO输出程序看看是不是好的吧。

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

7

主题

24

帖子

0

粉丝