📄 flash.c
字号:
/***********************************************************************/
/* Copyright Silicon Storage Technology, Inc. (SST), 1994-2001 */
/* Example "C" language Driver of 39VF160 16 Mbit Multi-Purpose Flash */
/* Nelson Wang, Silicon Storage Technology, Inc. */
/* */
/* Revision 1.0, Sept. 12, 2001 */
/* */
/***********************************************************************/
#include "Flash.h"
#define FALSE 0
#define TRUE 1
// 数据线引脚映射
#define FLASH_DATA(n) ( (n) >> 15 & 0x0001 /* D15 -> D0 */ \
| (n) >> 12 & 0x0004 /* D14 -> D2 */ \
| (n) >> 9 & 0x0010 /* D13 -> D4 */ \
| (n) >> 6 & 0x0040 /* D12 -> D6 */ \
| (n) >> 3 & 0x0100 /* D11 -> D8 */ \
| (n) >> 0 & 0x0400 /* D10 -> D10 */ \
| (n) << 3 & 0x1000 /* D9 -> D12 */ \
| (n) << 6 & 0x4000 /* D8 -> D14 */ \
| (n) >> 6 & 0x0002 /* D7 -> D1 */ \
| (n) >> 3 & 0x0008 /* D6 -> D3 */ \
| (n) >> 0 & 0x0020 /* D5 -> D5 */ \
| (n) << 3 & 0x0080 /* D4 -> D7 */ \
| (n) << 6 & 0x0200 /* D3 -> D9 */ \
| (n) << 9 & 0x0800 /* D2 -> D11 */ \
| (n) << 12 & 0x2000 /* D1 -> D13 */ \
| (n) << 15 & 0x8000 /* D0 -> D15 */ )
#define FLASH_ADDR(a) ((volatile WORD *)((a) << 1))
#define FLASH_WRITE(addr, word) (*FLASH_ADDR(addr) = FLASH_DATA(word))
#define SST_ID 0xBF /* SST Manufacturer's ID code */
#define SST_39VF160 0x2782 /* SST 39VF160 device code */
/************************************************************************/
/* PROCEDURE: Check_SST_39VF160 */
/* */
/* This procedure decides whether a physical hardware device has a */
/* SST39VF160 16 Mbit Multi-Purpose Flash installed or not. */
/* */
/* Input: */
/* None */
/* */
/* Output: */
/* return TRUE: indicates a SST39VF160 */
/* return FALSE: indicates not a SST39VF160 */
/************************************************************************/
int Check_SST_39VF160(void)
{
unsigned SST_id1, SST_id2;
int ReturnStatus;
/* Issue the Software Product ID code to 39VF160 */
FLASH_WRITE(0x5555, 0xaaaa);
FLASH_WRITE(0x2aaa, 0x5555);
FLASH_WRITE(0x5555, 0x9090);
// Delay_150_Nano_Seconds();
/* Read the product ID from 39VF160 */
SST_id1 = *FLASH_ADDR(0) & FLASH_DATA(255); /* get first ID word */
SST_id2 = *FLASH_ADDR(1); /* get second ID word */
/* Determine whether there is a SST39VF160 installed or not */
ReturnStatus = SST_id1 == FLASH_DATA(SST_ID)
&& SST_id2 == FLASH_DATA(SST_39VF160);
/* Issue the Soffware Product ID Exit code thus returning the 39VF160 */
/* to the read operating mode */
FLASH_WRITE(0x5555, 0xaaaa);
FLASH_WRITE(0x2aaa, 0x5555);
FLASH_WRITE(0x5555, 0xF0F0);
// Delay_150_Nano_Seconds();
return(ReturnStatus);
}
/************************************************************************/
/* PROCEDURE: Erase_Entire_Chip */
/* */
/* This procedure can be used to erase the entire chip. */
/* */
/* Input: */
/* NONE */
/* */
/* Output: */
/* NONE */
/************************************************************************/
void Erase_Entire_Chip(void)
{
/* Issue the Chip Erase command to 39VF160 */
FLASH_WRITE(0x5555, 0xaaaa);
FLASH_WRITE(0x2aaa, 0x5555);
FLASH_WRITE(0x5555, 0x8080);
FLASH_WRITE(0x5555, 0xaaaa);
FLASH_WRITE(0x2aaa, 0x5555);
FLASH_WRITE(0x5555, 0x1010);
// Delay_100_Milli_Seconds(); /* Delay Tsce time */
Check_Toggle_Ready((WORD *)0); /* wait for TOGGLE bit to get ready */
}
/************************************************************************/
/* PROCEDURE: Erase_One_Sector */
/* */
/* This procedure can be used to erase a total of 2048 words. */
/* */
/* Input: */
/* dst DESTINATION address which the erase operation starts */
/* */
/* Output: */
/* NONE */
/************************************************************************/
void Erase_One_Sector(WORD *dst)
{
/* Issue the Sector Erase command to 39VF160 */
FLASH_WRITE(0x5555, 0xaaaa);
FLASH_WRITE(0x2aaa, 0x5555);
FLASH_WRITE(0x5555, 0x8080);
FLASH_WRITE(0x5555, 0xaaaa);
FLASH_WRITE(0x2aaa, 0x5555);
FLASH_WRITE((unsigned)dst >> 1, 0x3030);
// Delay_25_Milli_Seconds(); /* Delay time = Tse */
Check_Toggle_Ready(dst); /* wait for TOGGLE bit to get ready */
}
/************************************************************************/
/* PROCEDURE: Erase_One_Block */
/* */
/* This procedure can be used to erase a total of 32K words. */
/* */
/* Input: */
/* dst DESTINATION address which the erase operation starts */
/* */
/* Output: */
/* NONE */
/************************************************************************/
void Erase_One_Block(WORD *dst)
{
/* Issue the Sector Erase command to 39VF160 */
FLASH_WRITE(0x5555, 0xaaaa);
FLASH_WRITE(0x2aaa, 0x5555);
FLASH_WRITE(0x5555, 0x8080);
FLASH_WRITE(0x5555, 0xaaaa);
FLASH_WRITE(0x2aaa, 0x5555);
FLASH_WRITE((unsigned)dst >> 1, 0x5050);
// Delay_25_Milli_Seconds(); /* Delay time = Tbe */
Check_Toggle_Ready(dst); /* wait for TOGGLE bit to get ready */
}
/************************************************************************/
/* PROCEDURE: Program_One_Word */
/* */
/* This procedure can be used to program ONE word of date to the */
/* 39VF160. */
/* */
/* NOTE: It is VERY important the sector containing the word to be */
/* programmed was ERASED first. */
/* */
/* Input: */
/* dst DESTINATION address which will be written with the */
/* data passed in from Src */
/* data The WORD which will be written to the 39VF160 */
/* */
/* Output: */
/* None */
/************************************************************************/
void Program_One_Word(WORD *dst, WORD data)
{
FLASH_WRITE(0x5555, 0xaaaa);
FLASH_WRITE(0x2aaa, 0x5555);
FLASH_WRITE(0x5555, 0xa0a0);
*dst = data; /* transfer the word to destination */
Check_Toggle_Ready(dst); /* wait for TOGGLE bit to get ready */
}
/************************************************************************/
/* PROCEDURE: Check_Toggle_Ready */
/* */
/* During the internal program cycle, any consecutive read operation */
/* on DQ6 will produce alternating 0's and 1's (i.e. toggling between */
/* 0 and 1). When the program cycle is completed, DQ6 of the data will */
/* stop toggling. After the DQ6 data bit stops toggling, the device is */
/* ready for next operation. */
/* */
/* Input: */
/* dst must already set-up by the caller */
/* */
/* Output: */
/* None */
/************************************************************************/
void Check_Toggle_Ready(WORD *dst)
{
int Loop = TRUE;
unsigned TimeOut = 0;
int PreData = *(volatile WORD *)dst & FLASH_DATA(0x0040);
while(TimeOut < 0x07FFFFFF && Loop)
{
int CurrData = *(volatile WORD *)dst & FLASH_DATA(0x0040);
if(PreData == CurrData)
Loop = FALSE; /* ready to exit the while loop */
PreData = CurrData;
TimeOut++;
}
}
/************************************************************************/
/* PROCEDURE: Check_Data_Polling */
/* */
/* During the internal program cycle, any attempt to read DQ7 of the */
/* last byte loaded during the page/byte-load cycle will receive the */
/* complement of the true data. Once the program cycle is completed, */
/* DQ7 will show true data. */
/* */
/* Input: */
/* dst must already set-up by the caller */
/* TrueData Data is the original (true) data */
/* */
/* Output: */
/* None */
/************************************************************************/
void Check_Data_Polling(WORD *dst, WORD TrueData)
{
int Loop = TRUE;
unsigned long TimeOut = 0;
TrueData &= FLASH_DATA(0x8080);
while ((TimeOut< 0x07FFFFFF) && (Loop))
{
int CurrData = *(volatile WORD *)dst & FLASH_DATA(0x8080);
if (TrueData == CurrData)
Loop = FALSE; /* ready to exit the while loop */
TimeOut++;
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -