TI中文支持网
TI专业的中文技术问题搜集分享网站

DM642的flash烧写问题

各位大神,能否为小弟解答一个问题?我现在仿照合众达seed642自己做了一块基于DM642的板子,

没有使用cpld,flash用的是Am29LV033C,4M的,22根地址线,DM642只有20根地址线,所以我用

了两个GPIO口来扩充。现在想实现flash的烧写,但手中的例程都是基于cpld的,而且看不太明白,

请大神帮我看看,万分感谢。我是DSP新手,还望诸位见谅~

noaming:

你好,首先CPLD和FLASH并没关系,对FLASH的读写不受CPLD的影响,因为访问FLASH走的EMIF总线。那个例程的CPLD是意在读取存储在FLASH里的程序到CPLD里运行。所以你只用分析\evmdm642\evmdm642\flashburn\FBTC642里面的代码就可以了。至少FLASH低位空间访问是没有问题的。高位需要GPIO来模拟,这时候需要改这部分代码了。

shu wei xiao:

回复 noaming:

首先,谢谢您抽出时间来回复我。我先看看您说的这个代码,有问题我再向您请教。

shu wei xiao:

回复 noaming:

您好,我最近研读了一下有关seed开发板上有关flash烧写的程序,理解了七七八八吧,但是有一个地方我有点不明白,请您帮我看看行吗?

下面是我感到困惑的地方:

for(page = 0;page<8;page++) { /*取FLASh的首址*/ addr = SEEDDM642_FLASH_BASE; /* Set Flash page*/ SEEDDM642_rset(SEEDDM642_FLASHPAGE, page); /*等待延时*/ SEEDDM642_waitusec(1); /*将数据写入第0页,每页512K*/ limit = 8; for (i = 0; i < limit; i++) { for (j = 0; j < 128; j++) { startaddr = addr; /*每次写入512个字节,以16位的数据为基数*/ for (k = 0; k < 256; k++) { buffer[k] = (addr + i + page) & 0xffff; addr += 2; } SEEDDM642_FLASH_write((Uint32)buffer, startaddr, 512); } }

以上是我摘录了其中一段,我明白seed642开发板个是利用19位地址线来连接flash(AMD29LV033C),

合众达的处理是运用cpld扩展例外三根地址线,将flash分成8页,每页有512k的大小,

我了解到该款flash的扇区大小为64K,因此上面程序中分别套用的两个循环,for (j = 0; j < 128; j++)和for (k = 0; k < 256; k++)

就能解释的通了。

我的问题是buffer[k] = (addr + i + page) & 0xffff;是怎么回事呢?合众达定义的这个数组是个int型说明以16位来进行赋值,

但是这样的问题就在于i和page的作用是什么呢?如当i和page取1时,这个数组取的数又是什么呢?因为这样按位求出的结果

貌似有误,还请大神指教

shu wei xiao:

回复 noaming:

您好,我最近研读了一下有关seed开发板上有关flash烧写的程序,理解了七七八八吧,但是有一个地方我有点不明白,请您帮我看看行吗?

下面是我感到困惑的地方:

for(page = 0;page<8;page++){/*取FLASh的首址*/addr = SEEDDM642_FLASH_BASE;/* Set Flash page*/SEEDDM642_rset(SEEDDM642_FLASHPAGE, page); /*等待延时*/SEEDDM642_waitusec(1);/*将数据写入第0页,每页512K*/limit = 8;for (i = 0; i < limit; i++){for (j = 0; j < 128; j++){startaddr = addr;/*每次写入512个字节,以16位的数据为基数*/for (k = 0; k < 256; k++){buffer[k] = (addr + i + page) & 0xffff;addr += 2;}SEEDDM642_FLASH_write((Uint32)buffer, startaddr, 512);}}

以上是我摘录了其中一段,我明白seed642开发板个是利用19位地址线来连接flash(AMD29LV033C),

合众达的处理是运用cpld扩展例外三根地址线,将flash分成8页,每页有512k的大小,

我了解到该款flash的扇区大小为64K,因此上面程序中分别套用的两个循环,for (j = 0; j < 128; j++)和for (k = 0; k < 256; k++)

就能解释的通了。

我的问题是buffer[k] = (addr + i + page) & 0xffff;是怎么回事呢?合众达定义的这个数组是个int型说明以16位来进行赋值,

但是这样的问题就在于i和page的作用是什么呢?如当i和page取1时,这个数组取的数又是什么呢?因为这样按位求出的结果

貌似有误,还请大神指教

KITCHEN:

你好,我现在也是在调试一个DM642的板子,现在遇见问题了,是不能擦除FLASH,flash的型号是AM29LV033C。我的硬件连接没有问题,请问你知道这个可能是什么原因么?

shu wei xiao:

回复 KITCHEN:

请问你的不能擦除是什么意思?我不是很明白,你可以先看看内存相应位置的数据是否改变,比如0x90000000以后的区域,你的硬件是怎么连接的?用的FPGA选通?还是I/O口模拟啊?

KITCHEN:

回复 shu wei xiao:

使用CPLD选通的。就是说FLASH的扇区擦除指令,dsp是正常发送出去了的。六个周期的指令序列嘛。可是貌似flash貌似没有正确接收到指令。导致flash的扇区内嵌擦除程序不工作。我吧我的程序给你看看。

FLASH型号:Am29LV033C我用一个合纵达提供的flash擦除和烧写的例程的时候,一直会死在擦除和写FLASH的函数的While循环那以下是擦除函数和写函数,麻烦大家看看,一块讨论讨论,我会关注本帖的,谢谢大家void SEEDDM642_FLASH_erase(Uint32 start, Uint32 length){    Int16 i;    Uint8 *pdata;    Uint32 sector_base, end;        /* Calculate extents of range to erase */    end = start + length – 1;        /* Walk through each sector, erase any sectors within range */    sector_base = SEEDDM642_FLASH_BASE;    for (i = 0; i < SEEDDM642_FLASH_SECTORS; i++)    {        if ((start <= sector_base) && (sector_end[i] <= end))        {            /* Start sector erase sequence */            *((Uint8 *)SEEDDM642_FLASH_BASE) = 0xAA;          //  SEEDDM642_wait(1000);            *((Uint8 *)SEEDDM642_FLASH_BASE) = 0x55;                //        SEEDDM642_wait(1000);            *((Uint8 *)SEEDDM642_FLASH_BASE) = 0x80;                        //SEEDDM642_wait(1000);            *((Uint8 *)SEEDDM642_FLASH_BASE) = 0xAA;                //        SEEDDM642_wait(1000);            *((Uint8 *)SEEDDM642_FLASH_BASE) = 0x55;                //        SEEDDM642_wait(1000);           // *((Uint8 *)SEEDDM642_FLASH_BASE) = 0x10;            /* Start erase at sector address */            pdata = (Uint8 *)sector_base;           *pdata = 0x30;            SEEDDM642_wait(1000);            /* Wait for erase to complete */            while (1)            {                if (*pdata & 0xff)//程序死在这个while循环中                {                    break;                }            }                   /* Put back in read mode */                    *((Uint8 *)SEEDDM642_FLASH_BASE) = 0xf0;                            }                /* Advance to next sector */        sector_base = sector_end[i] + 1;    }}烧写函数void SEEDDM642_FLASH_write(Uint32 src, Uint32 dst, Uint32 length){    Uint8 *psrc, *pdst;    Uint32 i;    /* Establish source and destination */    psrc = (Uint8 *)src;    pdst = (Uint8 *)dst;     for (i = 0; i < length; i++)    {        // Program one 8-bit word        *((Uint8 *)SEEDDM642_FLASH_BASE) = 0xaa;        *((Uint8 *)SEEDDM642_FLASH_BASE) = 0x55;        *((Uint8 *)SEEDDM642_FLASH_BASE) = 0xa0;        *pdst = *psrc;                // Wait for operation to complete        while(1)///这个循环也死        {            if (*pdst == *psrc)            {                break;           }       }               //  SEEDDM642_waitusec(10000);        pdst++;        psrc++;    }        /* Put back in read mode */    *((Uint16 *)SEEDDM642_FLASH_BASE) = 0xf0;    }

shu wei xiao:

回复 KITCHEN:

你好,你这个程序就是合众达给的例程吧?有几个问题,你可以参考一下。据我的经验(不一定对哈),分页执行的话,只能每次操作512K的数据,如果大于512K则不行,但是你说的是一直死在那个循环里,这个就有几种解释了,第一,你的flash工作了,但是你没有注意到,这个问题你可以通过查看寄存器是否为FFFFFFFF,即查看是否进行了擦除来验证,如果flash工作了,这个是最理想的情况,那么说明你的CPLD确实配置上有误,可能是分页不对等等。第二,你的flash没有工作,那么可能是你的片子坏了,或者是有其他什么原因导致了你的硬件出错,这两天我也是被这个问题所困,我通过用示波器测量发现,SDRAM的低八位工作不正常,导致flash的八位数据位有误,也是死在那些循环里。

KITCHEN:

回复 shu wei xiao:

是的,是合纵达的例程。我知道分页的,而且我的CPLD的分页是正确的,我觉得是我的flash在我的的DSP发送完6个周期的擦除指令后没有自动调用其内部的擦除程序进行擦除。而我能保证的是我的六个周期的擦除指令时正确的发送了过去的。擦看寄存器的时候寄出去全部是0x00000000.换了几个片子了,感觉也不是片子坏了。

KITCHEN:

回复 KITCHEN:

我的QQ 405211631 有时间的话我们一起聊一聊吧,我最近在用他的EMIF读取FIFO,感觉也遇到了一些问题,你看我们能互相学习一下么?

赞(0)
未经允许不得转载:TI中文支持网 » DM642的flash烧写问题
分享到: 更多 (0)