對norflash的讀操作比較簡單,系統上電後會自動進入讀模式,而且也不需要額外的命令來實現讀操作,下面的代碼就實現了
NOR Flash的操作。
static unsigned int Read_SST1601(unsigned int addr)
{
return *((volatile unsigned int *)(addr));
}
②.復位操作
norflash不僅能夠實現硬件復位,而且可以實現軟件復位。軟件復位的操作是向任一地址寫入復位命令0xF0。下面的函數實現
了軟件復位:
static void Reset_SST1601(void)
{
*((volatile unsigned int *)0x0) = 0xf0;
}
norflash的擦除操作和寫操作要稍微複雜一些,它們需要4個或6個週期來完成,每一個週期都要把相應的命令寫入norflash
中的某一命令寄存器中。寫操作的過程爲第一個週期是把命令0xAA寫入地址爲0x5555的命令寄存器中,第二個週期是把命令0x55寫
入地址爲0x2AAA命令寄存器中,第三個週期是把命令0xA0再寫入地址爲0x5555命令寄存器中,第四個週期爲真正地把要寫入的數據
寫入到norflash的地址中。下面的函數實現了寫操作,其中該函數的兩個輸入參數分別爲要寫入的數據和地址,爲了方便,我們
事先定義好命令寄存器.【注】參考芯片手冊
#define flash_base 0x00000000
#define CMD_ADDR0 *((volatile unsigned int *)(0x555<<1+flash_base))
#define CMD_ADDR1 *((volatile unsigned int *)(0x2aa<<1+flash_base))
static unsigned char SST1601_Program(unsigned int addr, unsigned int dat)
{
CMD_ADDR0 = 0xaa;
CMD_ADDR1 = 0x55;
CMD_ADDR0 = 0xa0;
*((volatile unsigned int *)(addr)) = dat;
return check_toggle();
}
static unsigned char check_toggle()
{
volatile unsigned int newtoggle,oldtoggle;
oldtoggle = *((volatile unsigned int *)0x0);
while(1)
{
newtoggle = *((volatile unsigned int *)0x0);
if((oldtoggle & 0x40)==(newtoggle & 0x40))
break;
if(newtoggle & 0x20) //DQ5
{
oldtoggle = *((volatile unsigned int *)0x0);
newtoggle = *((volatile unsigned int *)0x0);
if((oldtoggle & 0x40)==(newtoggle & 0x40))
break;
else
return 0; //錯誤
}
oldtoggle = newtoggle;
}
return 1; //正確
}
check_toggle()的原理是連續兩次讀取數據總線上的數據,判斷數據總線上的第6位數值(DQ6)是否翻轉,如果沒有翻轉則正
確,否則還要判斷第5位(DQ5),以確定是否是因爲超時而引起的翻轉。
④.擦除操作
寫操作只能使“1”變爲“0”,而只有擦除才能使“0”變爲“1”。因此在寫之前一定要先擦除。擦除分爲塊擦除和整片擦除。塊擦除
的過程爲第一個週期是把命令0xAA寫入地址爲0x5555的命令寄存器中,第二個週期是把命令0x55寫入地址爲0x2AAA命令寄存器中,
第三個週期是把命令0x80再寫入地址爲0x5555命令寄存器中,第四個週期是把命令0xAA寫入地址爲0x5555的命令寄存器中,第五個
週期是把命令0x55再寫入地址爲0x2AAA命令寄存器中,第六個週期是把命令0x30寫入要擦除塊的首地址內。下面的函數爲塊擦除,
其中輸入參數爲要擦除塊的首地址.【注】參考芯片手冊
unsigned char SST1601_sector_erase(unsigned int section_addr)
{
CMD_ADDR0 = 0xaa;
CMD_ADDR1 = 0x55;
CMD_ADDR0 = 0x80;
CMD_ADDR0 = 0xaa;
CMD_ADDR1 = 0x55;
*((unsigned int *)(section_addr)) = 0x30;
return check_toggle();
}
⑤.讀取芯片ID
對norflash另一個比較常用的操作是讀取芯片的ID。讀取廠商ID的過程爲第一個週期是把命令0xAA寫入地址爲0x555的命令寄存器
中,第二個週期是把命令0x55寫入地址爲0x2AA命令寄存器中,第三個週期是把命令0x90再寫入地址爲0x555命令寄存器中,第四個週期
爲讀取地址爲0x100中的內容,即廠商ID(0x1C)。讀取設備ID的過程的前三個週期與讀取廠商ID相同,第四個週期是讀取地址爲0x01中
的內容,即設備ID(0x2249)。下面的函數爲讀取芯片ID:
unsigned int get_en29lv160ab_id(void)
{
U32 temp=0;
CMD_ADDR0 = 0xaa;
CMD_ADDR1 = 0x55;
CMD_ADDR0 = 0x90;
temp = (*(volatile unsigned short *)(flash_base+ (0x100<<1)))<<16;
temp |= (*(volatile unsigned short *)(flash_base + (1<<1));
return temp;
}