全部博文(436)
分类:
2011-04-18 23:48:16
// 涉及到得函数
/********************************************************
函数名称: amWrite()
函数功能: 读取缓冲区数据根据给定的长度写入指定地址.
入口参数: flashAddr 数据目标地址(flash).
buffer 数据源地址.
length 要写入的字节数.
返 回 值: NULL 写失败.
flashPtr flash的下一个地址.
备 注: 由于am29lv160db按半字(16bit)操作,所以
如果要多次调用这个函数来写入一个文件,则应
每次读取偶数个字节,以保证连续性.
*********************************************************/
u16 *amWrite(u16 *flashAddr, u8 *buffer, int length)//定义两个指针,第一个指向数据目标地址,另一个指向数据源地址。同时定义一个整形length
{
u32 i, j;//定义i,j32
u32 cLength;//定义cLength
u16 *flashPtr;//定义一个指针指向flash的下一个地址
u16 *gBuffer;//
int count=0, lastpercent=-1, percent;//给count赋初值0,lastpercent为1,定义percent为int整形。
flashPtr = flashAddr;//将flashAddr的地址赋予给flashPtr
cLength = (length + 1)/2; //计算半字长度.
gBuffer = (u16 *)buffer;
//erase the sector first
amErase_region((u16 *)flashPtr,(u32)length);
SerialOutputString("\n");
int_disable();
while (cLength > 0)
{
*((u16 *)(AM_START_ADDR + AM_ADDR_UNLOCK1)) = AM_DATA_UNLOCK1; //解锁.
barrier();
*((u16 *)(AM_START_ADDR + AM_ADDR_UNLOCK2)) = AM_DATA_UNLOCK2;//解锁
barrier();
*((u16 *)(AM_START_ADDR + AM_ADDR_UNLOCK1)) = AM_SETUP_WRITE;
barrier();
*flashPtr = *gBuffer; //写入数据.
barrier();
count+=2;
percent=count*100/length;
if(percent!=lastpercent){//如果percent不等于lastpercent
SerialOutputString("Writing data to flash ");//输出字符
SerialOutputDec(percent);
SerialOutputString("%\r");
lastpercent=percent;//将percent的值赋给lastpercent。
}
i=0x100;//给i赋值
while(i--){//i自动减1
if(*flashPtr == *gBuffer)break;若gBuffer指向的内容等于flashPtr的值则退出。
barrier();//调用函数
for(j = 0; j < 400; j++);// j从0开始加,但是不能大于400
}
if(!i){
SerialOutputString("Writing data to flash failed\n");
break;
}
cLength--;//cLength减1
flashPtr++;//flashPtr加1
gBuffer++;//gBuffer加1
}
int_enable();
SerialOutputString("\nverify writing data ...\n");//输出字符
flashPtr = flashAddr;//将flashAddr地址赋给flashPtr
gBuffer = (u16 *)buffer; //将buffer指向的值赋予gBuffer
cLength = length/2;//将半字长度赋予cLength
for(i=0; i
{
if(*flashPtr++ != *gBuffer++)//flashPtr的地址自动加1,若不等于gBuffer自动加1的值,则进入函数。
{
SerialOutputString("verify writing data failed at 0x");//输出字符
SerialOutputHex((u32)flashPtr);
SerialOutputString("\n");//输出字符串
return NULL;
}
}
if(length%2)
{
if((*flashPtr++ & 0x00ff) != (*gBuffer++ & 0x00ff))/*奇数长度的最后一个字节.*/
{
//printf("Error: write failed in SST39vf160 at 0x%x on verification.\n", (int)flashPtr);
return NULL;
}
}
SerialOutputString("verify write data ok\n");//输出字符传
return (u16 *)flashPtr;//返回到flashPtr指向的地址。
}
/********************************************************
函数名称: nore()
函数功能: 擦除由memaddr地址起的nwords个flash单元
入口参数: argc 输入参数个数
argv[] 参数数组
返 回 值: 0 擦除成功
-1 缺少参数
备 注: (无)
*********************************************************/
static int nore(int argc, char *argv[]) //程序入口
{
u8 *memaddr;
u32 nwords;
if(argc >2){
strtou32(argv[1], &memaddr); // 这里的&memaddr不知道是写错了,还是需要从u8 **memaddr转换到u32 value,
// 没弄清楚:-(
// 总之是将第二个参数argv[1]转换为数值memaddr
strtou32(argv[2], &nwords); // 将第三个参数argv[2]转换为数值nwords,这是需要擦除的字节数,由用户指定
}
else return -1;
SerialOutputString("erase nor flash region ");
SerialOutputHex( memaddr);
SerialOutputString(" \n");
amErase_region((u16 *)memaddr,nwords);// 擦除由memaddr地址起的nwords个flash扇区
return 0;
}
static char norehelp[] = "nore address length (bytes)\n"
"nor flash erase region \n";
__commandlist(nore, "nore", norehelp);// 以名字为__command_nore的commandlist_t数据结构的形式存入名为.commandlist的段中
// 涉及到得函数
// 1
/********************************************************
函数名称: amErase_region()
函数功能: .
入口参数: start 目标地址(flash).
nwords 要擦除的字节数.
返 回 值: -1 擦除失败.
备 注: 由于am29lv160db按半字(16bit)操作,所以
如果要多次调用这个函数来写入一个文件,则应
每次读取偶数个字节,以保证连续性.
*********************************************************/
int amErase_region(u16 *start, u32 nwords)
{
u16 *cur;
u16 *end;
int rv;
u16 *MAX_ADDR = 0x200000;
cur = start ;
end = start + (nwords+1)/2;
SerialOutputString("erasing dirty block \n"); //擦出不好的语句块
int_disable();
while(cur < end) {
if(cur >= MAX_ADDR)return 0;
rv = amSectorErase(cur); //擦除指定的flash扇区.
if(rv < 0) { //擦除未成功
SerialOutputString("\nflash erase error at 0x");
SerialOutputHex((u32 )cur);
SerialOutputString("\n"); //输出一系列东西
return rv; //返回-1
}
/*
flash sector :
8K*1 + 4K*2 + 16K*1 +32K*31 (data width=16bit)
16K*1 + 8K*2 + 32K*1 +64K*31 (data width=8bit)
*/
//擦除成功
if(cur < 0x4000 )cur += 0x2000; //根据目标地址的大小,分别增加不同的地址
else if(cur >= 0x4000 && cur < 0x8000 )cur += 0x1000;
else if(cur >= 0x8000 && cur < 0x10000 )cur += 0x4000;
else if(cur >= 0x10000 && cur < 0x200000)cur += 0x8000;
}
int_enable();
SerialOutputString("\n");
return 0;
}
V
V
/********************************************************
函数名称: amSectorErase()
函数功能: 擦除指定的flash扇区.
入口参数: 扇区地址.
返 回 值: OK 擦除完全正确.
ERROR 有单元不能正确擦除.
备 注:
*********************************************************/
int amSectorErase(u16 *pSector)
{
int i,j;
u16 *flashPtr = pSector;
SerialOutputString("Erase flash sector 0x"); //选择要擦出的扇区(16进制)
SerialOutputHex((u32)pSector); //将16位的pSector强制转化成32位的
SerialOutputString("\r");
int_disable();
*((u16 *)(AM_START_ADDR + AM_ADDR_UNLOCK1)) = AM_DATA_UNLOCK1; //连续解锁.
barrier();
*((u16 *)(AM_START_ADDR + AM_ADDR_UNLOCK2)) = AM_DATA_UNLOCK2;
barrier();
*((u16 *)(AM_START_ADDR + AM_ADDR_UNLOCK1)) = AM_SETUP_ERASE;
barrier();
*((u16 *)(AM_START_ADDR + AM_ADDR_UNLOCK1)) = AM_DATA_UNLOCK1;
barrier();
*((u16 *)(AM_START_ADDR + AM_ADDR_UNLOCK2)) = AM_DATA_UNLOCK2;
barrier();
*flashPtr = AM_SECTOR_ERASE; //写入擦除命令.
barrier();
i=0xffff;
while(i--){//verify the data writed
if(*(flashPtr) == 0xffff)break;//如果擦除的地址已经到尾部则返回
barrier();
for(j=0;j<400;j++);
}
int_enable();
if(!i){
SerialOutputString("flash erase sector failed\n");
//如果当前指针不为空,即擦除不成功,返回error
return ERROR;
}
/*
if(check_toggle((u16 *)flashPtr, 0xffff, 0x20000) != OK)
{
SerialOutputString("flash erase sector failed\n");
//如果输入需删除的扇区数大于了设定的数则返回error
return ERROR;
//printf("warning: Chip Erase time out!\n");
}
*/
return OK;//否者返回成功
}
/********************************************************
函数名称: sece()
函数功能: 擦除指定的flash扇区
入口参数: argc 输入参数个数
argv[] 参数数组
返 回 值: 0 擦除成功
-1 缺少参数
备 注: (无)
*********************************************************/
static int sece(int argc, char *argv[])
{
u8 *memaddr;
if(argc >1){ //如果argc(输入参数个数)>1
strtou32(argv[1], &memaddr);
}
else return -1; //如果argc(输入参数个数)>1 ,缺少参数擦除失败
SerialOutputString("erase nor flash region "); //连续输出字符串“删除flash扇区”
SerialOutputHex( memaddr); //连续输出十六进制的"memaddr"
SerialOutputString(" \n"); //回车
amSectorErase((u16 *)memaddr); // 擦除由memaddr地址起的整个flash扇区
return 0; //删除成功
}
static char secehelp[] = "sece address \n"
"nor flash erase region \n";
__commandlist(sece, "sece", secehelp);// 以名字为__command_sece的commandlist_t数据结构的形式存入名为.commandlist的段中
//涉及到的函数
/********************************************************
函数名称: amSectorErase()
函数功能: 擦除指定的flash扇区.
入口参数: 扇区地址.
返 回 值: OK 擦除完全正确.
ERROR 有单元不能正确擦除.
备 注:
*********************************************************/
int amSectorErase(u16 *pSector)
{
int i,j;
u16 *flashPtr = pSector;
SerialOutputString("Erase flash sector 0x"); //删除flash扇区0x
SerialOutputHex((u32)pSector);
SerialOutputString("\r"); //回车
int_disable();
*((u16 *)(AM_START_ADDR + AM_ADDR_UNLOCK1)) = AM_DATA_UNLOCK1; //连续解锁.
barrier();
*((u16 *)(AM_START_ADDR + AM_ADDR_UNLOCK2)) = AM_DATA_UNLOCK2;
barrier();
*((u16 *)(AM_START_ADDR + AM_ADDR_UNLOCK1)) = AM_SETUP_ERASE;
barrier();
*((u16 *)(AM_START_ADDR + AM_ADDR_UNLOCK1)) = AM_DATA_UNLOCK1;
barrier();
*((u16 *)(AM_START_ADDR + AM_ADDR_UNLOCK2)) = AM_DATA_UNLOCK2;
barrier();
*flashPtr = AM_SECTOR_ERASE; //写入擦除命令.
barrier();
i=0xffff;
while(i--){//verify the data writed
if(*(flashPtr) == 0xffff)break;
barrier();
for(j=0;j<400;j++);
}
int_enable();
if(!i){
SerialOutputString("flash erase sector failed\n");
return ERROR;
}
/*
if(check_toggle((u16 *)flashPtr, 0xffff, 0x20000) != OK)
{
SerialOutputString("flash erase sector failed\n");
return ERROR;
//printf("warning: Chip Erase time out!\n");
}
*/
return OK;
}
/********************************************************
函数名称: norw()
函数功能: 读取buf中nwords长度的数据到以memaddr开始的内存区
入口参数: argc 输入参数个数
argv[] 参数数组
返 回 值: 0 擦除成功
-1 缺少参数
备 注: (无)
*********************************************************/
static int norw(int argc, char *argv[])
{
u8 *memaddr,*buf;
u32 nwords;
if(argc >3){
strtou32(argv[1], &memaddr);
strtou32(argv[2], &buf);
strtou32(argv[3], &nwords);
}
else return -1;// 若缺少参数则返回-1,失败
SerialOutputString("erase nor flash region ");
SerialOutputHex( memaddr);
SerialOutputString(" \n");
amWrite((u16 *)memaddr,buf,nwords); // 读取buf中nwords长度的数据到以memaddr开始的内存区,这些参数由用户指定
return 0;
}
static char norwhelp[] = "norw address buffer length\n"
"nor flash write\n";
__commandlist(norw, "norw", norwhelp);// 以名字为__command_norw的commandlist_t数据结构的形式存入名为.commandlist的段中