真诚与善良是最大的财富
分类: 嵌入式
2010-08-12 11:14:55
我选用的是SST的SST39VF1601每次写操作必须是16位进行
硬件连接如图(TMS320C6713+ SST39VF1601)所示:
注:因为是16bit操作,所以地址要偏移1位(依次类推,32bit操作偏移2位)
volatile Uint16 *FLASH_5555 = (volatile Uint16 *) (0x90000000+(0x5555<<1));
volatile Uint16 *FLASH_2AAA = (volatile Uint16 *) (0x90000000+(0x2AAA<<1));
#define FLASH_UL1 0xAA
#define FLASH_UL2 0x55
#define FLASH_UL3 0x80
#define FLASH_UL4 0xAA
#define FLASH_UL5 0x55
#define FLASH_SECTOR_UL6 0x30
#define FLASH_CHIP_UL6 0x10
#define FLASH_PROGRAM 0xA0
#define SECTOR_SIZE 0x0800 //2Kword,即2k*16bit
#define BLOCK_SIZE 0x8000 //32Kword
#define CHIP_SIZE 0x100000 //1Mword
flash擦除操作命令时序:
注:每个Sector为2Kword,即2^10,则SST39VF1601有2^9=512个Sector
每个Block为32Kword,即2^15,则SST39VF1601有2^5=32个Block
下述程序采用Data# Polling 方式判断flash是否擦除完成,即判断DQ7是否为1
/********************************************************************************\
\* Flash erase function. *\
\********************************************************************************/
Uint32 Flash_Erase(Uint32 addr,Uint16 type)
{
Uint32 i,j;
*FLASH_5555 = FLASH_UL1; //first
*FLASH_2AAA = FLASH_UL2; //second
*FLASH_5555 = FLASH_UL3; //third
*FLASH_5555 = FLASH_UL4;
*FLASH_2AAA = FLASH_UL5;
switch(type)
{
case 0x50: //block erase
*(Uint16 *)addr = type;
while((*(Uint16 *)addr & 0x80) != 0x80);
for(i = 0; i < BLOCK_SIZE; i++)
{
if(*(Uint16 *)(addr + 2*i) != 0xffff)
{
j = 0;
break;
}
}
j = 1;
break;
case 0x30: //sector erase
*(Uint16 *)addr = type;
while((*(Uint16 *)addr & 0x80) != 0x80);
for(i = 0; i < SECTOR_SIZE; i++)
{
if(*(Uint16 *)(addr + 2*i) != 0xffff)
{
j = 0;
break;
}
}
j = 1;
break;
case 0x10: //chip erase
*FLASH_5555 = type;
while((*FLASH_5555 & 0x80) != 0x80);
for(i = 0; i < CHIP_SIZE; i++)
{
if(*(Uint16 *)(addr + 2*i) != 0xffff)
{
j = 0;
break;
}
}
j = 1;
break;
default:
break;
}
return (j);
}
Flash写数据命令时序
/********************************************************************************\
\* Write a single data. *\
\********************************************************************************/
void Flash_Writes(Uint32 addr,Uint16 data)
{
*FLASH_5555 = FLASH_UL1;
*FLASH_2AAA = FLASH_UL2;
*FLASH_5555 = FLASH_PROGRAM;
*(Uint16 *)addr = data;
while(*(Uint16 *)addr != data);
}
/********************************************************************************\
\* Write the certain length data. *\
\********************************************************************************/
void Flash_Writem(Uint32 addr,Uint16 *ptr,Uint32 length)
{
Uint32 i;
for(i = 0; i < length; i++)
{
Flash_Writes(addr+2*i,*(ptr+i));
}
}
/********************************************************************************\
\* Read a single data. *\
\********************************************************************************/
Uint32 Flash_Reads(Uint32 addr)
{
return (*(Uint16 *)addr);
}
/********************************************************************************\
\* Read the certain length data. *\
\********************************************************************************/
void Flash_Readm(Uint32 addr,Uint16 *ptr,Uint32 length)
{
Uint32 i;
for(i = 0; i < length; i++)
{
*(ptr + i) = Flash_Reads(addr+2*i);
}
}
注:因为是以16bit方式读写的,所以每读写一次,地址要加2(依次,以32bit读写时,地址要加4)
网上资料:两片SST39VF1601组成32位
1.我选用的是SST的SST39VF1601.每次写操作必须是16位进行。而我的系统是采用的2片flash组成的可以进行32位数据操作的结构。这就和以往用的8位数据线的单片flash的结构有所不同了。
2.关于一些操作指令:由于要同时对两片flash进行操作,那么操作格式命令要从原来的00AAH改成00AA00AAH等。以下是我定义的一些地址和操作指令(注意用SST的芯片地址要右移两位哦):
#define FLASH_5555 (0x90000000+(0x5555<<2))//32BIT SHOULD MOVE 2
#define FLASH_2AAA (0x90000000+(0x2AAA<<2))
#define FLASH_UL1 0x00AA00AA
#define FLASH_UL2 0x00550055
#define FLASH_UL3 0x00800080
#define FLASH_UL4 0x00AA00AA
#define FLASH_UL5 0x00550055
#define FLASH_PROGRAM 0x00A000A0
#define SECTOR_ERASE 0x00300030
3.flash的擦除操作:在进行写操作之前,必须要先进行flash的擦除操作。擦除操作分为sector erase(扇区擦除),block erase(块擦除),chip erase(芯片擦除)。
4.关于两片flash的写操作:写两片flash的时候。每次都进行32bit的读%