|
各位大神,能否为小弟解答一个问题?我现在仿照合众达seed642自己做了一块基于DM642的板子, 没有使用cpld,flash用的是Am29LV033C,4M的,22根地址线,DM642只有20根地址线,所以我用 了两个GPIO口来扩充。现在想实现flash的烧写,但手中的例程都是基于cpld的,而且看不太明白, 请大神帮我看看,万分感谢。我是DSP新手,还望诸位见谅~ |
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.
|
各位大神,能否为小弟解答一个问题?我现在仿照合众达seed642自己做了一块基于DM642的板子, 没有使用cpld,flash用的是Am29LV033C,4M的,22根地址线,DM642只有20根地址线,所以我用 了两个GPIO口来扩充。现在想实现flash的烧写,但手中的例程都是基于cpld的,而且看不太明白, 请大神帮我看看,万分感谢。我是DSP新手,还望诸位见谅~ |
您好,我最近研读了一下有关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时,这个数组取的数又是什么呢?因为这样按位求出的结果
貌似有误,还请大神指教
您好,我最近研读了一下有关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时,这个数组取的数又是什么呢?因为这样按位求出的结果
貌似有误,还请大神指教
请问你的不能擦除是什么意思?我不是很明白,你可以先看看内存相应位置的数据是否改变,比如0x90000000以后的区域,你的硬件是怎么连接的?用的FPGA选通?还是I/O口模拟啊?
使用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;
}
你好,你这个程序就是合众达给的例程吧?有几个问题,你可以参考一下。据我的经验(不一定对哈),分页执行的话,只能每次操作512K的数据,如果大于512K则不行,但是你说的是一直死在那个循环里,这个就有几种解释了,第一,你的flash工作了,但是你没有注意到,这个问题你可以通过查看寄存器是否为FFFFFFFF,即查看是否进行了擦除来验证,如果flash工作了,这个是最理想的情况,那么说明你的CPLD确实配置上有误,可能是分页不对等等。第二,你的flash没有工作,那么可能是你的片子坏了,或者是有其他什么原因导致了你的硬件出错,这两天我也是被这个问题所困,我通过用示波器测量发现,SDRAM的低八位工作不正常,导致flash的八位数据位有误,也是死在那些循环里。