📄 flashdrive.c
字号:
/*
Software Device Driver
SST39VF3201/SST39VF3202
32 Mbit Multi-Purpose Flash (MPF+)
Jerry Deng, Silicon Storage Technology, Inc.
Revision 2.0, December 2003
ABOUT THE SOFTWARE
This is a software device driver example for SST39VF3201/3202
32 Mbit Multi-Purpose Flash (MPF+). The code is written in generic C language,
extensive comments are included in each routine to describe its function and usage.
SST39VF3201/3202 datasheet should be reviewed in conjunction
with this code to completely understand the operation of this device.
The SST39VF3201 supports bottom boot block protection, and the SST39VF3202
supports top boot block protection. The boot block memory area is protected from
erase/programming when WP# is low and unprotected when WP# is high.
During execution of this code, it's assumed that RST# signal on device is held in
logic high state, otherwise the device will be put into reset state (read mode)
as long as RST# is low.
*/
#include "type.h"
#include <stdio.h>
#include "sst1601.h"
#include "FB.h"
static volatile u16 *flashnext = (volatile u16 *)BaseAddrs;
/************************************************************************/
/* PROCEDURE: Check_SST_39VF320X */
/* */
/* This procedure decides whether a physical hardware device has a */
/* SST39VF3201/3202 32 Mbit MPF+ Device installed or not. */
/* */
/* Input: */
/* None */
/* */
/* Output: */
/* 00BF235Bh for SST39VF3201, */
/* 00BF235Ah for SST39VF3202, */
/* Any other value indicates non SST39VF3201/3202. */
/* high word of returned value is vendor ID, low word is device ID. */
/************************************************************************/
u32 Check_SST_39VF320X(void)
{
u16 Vendor_ID;
u16 Device_ID;
u32 ReturnStatus;
// Issue Software ID Entry command to SST39VF320X
*(u16 *) (BaseAddrs + 0x5555 * AddrsShift) = 0x00AA; // 1st write data 0x00AA to device addr 5555H
*(u16 *) (BaseAddrs + 0x2AAA * AddrsShift) = 0x0055; // 2nd write data 0x0055 to device addr 2AAAH
*(u16 *) (BaseAddrs + 0x5555 * AddrsShift) = 0x0090; // 3rd write data 0x0090 to device addr 5555H
Delay_150_Nano_Seconds(); // delay Tida (max. 150ns) for SST39VF320X
Vendor_ID = *(u16 *) (BaseAddrs + 0); // read vendor ID
Device_ID = *(u16 *) (BaseAddrs + 1 * AddrsShift); // read device ID
ReturnStatus = Vendor_ID * 65536 + Device_ID;
// Issue Software ID Exit command to put SST39VF320X into normal read mode.
*(u16 *) (BaseAddrs + 0x5555 * AddrsShift) = 0x00AA; // 1st write data 0x00AA to device addr 5555H
*(u16 *) (BaseAddrs + 0x2AAA * AddrsShift) = 0x0055; // 2nd write data 0x0055 to device addr 2AAAH
*(u16 *) (BaseAddrs + 0x5555 * AddrsShift) = 0x00F0; // 3rd write data 0x00F0 to device addr 5555H
Delay_150_Nano_Seconds(); // then delay Tida (max. 150ns) for SST39VF320X
return ReturnStatus;
}
/************************************************************************/
/* PROCEDURE: CFI_Query */
/* */
/* This procedure should be used to query for CFI information */
/* */
/* Input: */
/* *CFI a pointer to store CFI data string (total 37 words) */
/* */
/* Output: */
/* The pointer points to CFI data string. */
/************************************************************************/
void CFI_Query(u16 *CFI)
{
u8 i;
// Issue the CFI Query Entry command to SST39VF320X
*(u16 *) (BaseAddrs + 0x5555 * AddrsShift) = 0x00AA; // 1st write data 0x00AA to device addr 5555H
*(u16 *) (BaseAddrs + 0x2AAA * AddrsShift) = 0x0055; // 2nd write data 0x0055 to device addr 2AAAH
*(u16 *) (BaseAddrs + 0x5555 * AddrsShift) = 0x0098; // 3rd write data 0x0098 to device addr 5555H
Delay_150_Nano_Seconds( ); // delay Tida (150ns)
// retrieve all CFI data string from address 0010H--0034H
for(i=0x10; i<=0x34; i++)
{*CFI = *(u16 *)(BaseAddrs + i * AddrsShift); // save CFI data into user-defined pointer
++CFI;
}
// Issue CFI Exit command to return SST39VF320X to read mode.
*(u16 *) (BaseAddrs + 0x5555 * AddrsShift) = 0x00AA; // 1st write data 0x00AA to device addr 5555H
*(u16 *) (BaseAddrs + 0x2AAA * AddrsShift) = 0x0055; // 2nd write data 0x0055 to device addr 2AAAH
*(u16 *) (BaseAddrs + 0x5555 * AddrsShift) = 0x00F0; // 3rd write data 0x00F0 to device addr 5555H
Delay_150_Nano_Seconds( ); // insert delay time = Tida
}
/************************************************************************/
/* PROCEDURE: SecID_Query */
/* */
/* This procedure should be used to query for Security ID information. */
/* */
/* Input: */
/* *SST_SecID pointer to store SST SecID string (8 words) */
/* *User_SecID pointer to store User SecID string (8 words) */
/* */
/* Output: */
/* pointer SST_SecID points to SST security ID */
/* pointer User_SecID points to user security ID */
/************************************************************************/
void SecID_Query(u16 *SST_SecID, u16 *User_SecID)
{
u8 i;
// Issue Query SecID command to SST39VF320X
*(u16 *) (BaseAddrs + 0x5555 * AddrsShift) = 0x00AA; // 1st write data 0x00AA to device addr 5555H
*(u16 *) (BaseAddrs + 0x2AAA * AddrsShift) = 0x0055; // 2nd write data 0x0055 to device addr 2AAAH
*(u16 *) (BaseAddrs + 0x5555 * AddrsShift) = 0x0088; // 3rd write data 0x0088 to device addr 5555H
Delay_150_Nano_Seconds( ); // insert delay time = Tida
// read all Security ID information:
// SST security ID is from address 000000H to 000007H,
// User security ID is from address 000010H to 000017H.
for (i=0; i<=7; i++)
{
*SST_SecID = *(u16 *) (BaseAddrs + i * AddrsShift); // read & save SST security ID
++SST_SecID; // point to next word
*User_SecID = *(u16 *) (BaseAddrs + (i+0x10) * AddrsShift); // read & save user security ID
++User_SecID; // point to next word
}
// Issue Sec ID Exit command to return SST39VF320X to read mode
*(u16 *) (BaseAddrs+0x0) = 0x00F0; // writing F0h into any address
Delay_150_Nano_Seconds( ); // insert delay time = Tida
}
/************************************************************************/
/* PROCEDURE: Erase_One_Sector */
/* */
/* This procedure can be used to erase a total of 2048 words. */
/* */
/* Input: */
/* Dst DESTINATION address of sector to be erased */
/* */
/* Output: */
/* return TRUE: indicates success in sector-erase */
/* return FALSE: indicates timeout in sector-erase */
/************************************************************************/
u8 Erase_One_Sector(u32 Dst)
{
u8 ReturnStatus=TRUE;
*( u16*) (BaseAddrs + 0x5555 * AddrsShift) = 0x00AA; // 1st write data 0x00AA to device addr 5555H
*( u16*) (BaseAddrs + 0x2AAA * AddrsShift) = 0x0055; // 2nd write data 0x0055 to device addr 2AAAH
*( u16*) (BaseAddrs + 0x5555 * AddrsShift) = 0x0080; // 3rd write data 0x0080 to device addr 5555H
*( u16*) (BaseAddrs + 0x5555 * AddrsShift) = 0x00AA; // 4th write data 0x00AA to device addr 5555H
*( u16*) (BaseAddrs + 0x2AAA * AddrsShift) = 0x0055; // 5th write data 0x0055 to device addr 2AAAH
*( u16*) (BaseAddrs + Dst * AddrsShift) = 0x0030; // 6th write data 0x0030 to device sector addr Dst
// ReturnStatus = Check_Toggle_Ready(Dst,SectorEraseTime); // wait TOGGLE bit stops toggling
ReturnStatus = Check_Data_Polling(Dst, 0xFFFF, SectorEraseTime); // wait until DQ7 outputs 1
return ReturnStatus;
}
/************************************************************************/
/* PROCEDURE: Erase_One_Block */
/* */
/* This procedure can be used to erase a total of 32K words. */
/* */
/* Input: */
/* Dst DESTINATION address where the erase operation starts */
/* */
/* Output: */
/* return TRUE: indicates success in block-erase */
/* return FALSE: indicates timeout in block-erase */
/************************************************************************/
u8 Erase_One_Block (u32 Dst)
{
u8 ReturnStatus=TRUE;
*(u16 *) (BaseAddrs + 0x5555 * AddrsShift) = 0x00AA; // 1st write data 0x00AA to device addr 5555H
*(u16 *) (BaseAddrs + 0x2AAA * AddrsShift) = 0x0055; // 2nd write data 0x0055 to device addr 2AAAH
*(u16 *) (BaseAddrs + 0x5555 * AddrsShift) = 0x0080; // 3rd write data 0x0080 to device addr 5555H
*(u16 *) (BaseAddrs + 0x5555 * AddrsShift) = 0x00AA; // 4th write data 0x00AA to device addr 5555H
*(u16 *) (BaseAddrs + 0x2AAA * AddrsShift) = 0x0055; // 5th write data 0x0055 to device addr 2AAAH
*(u16 *) (BaseAddrs + Dst * AddrsShift) = 0x0050; // 6th write data 0x0050 to device sector addr Dst
ReturnStatus = Check_Toggle_Ready(Dst, BlockEraseTime); // wait TOGGLE bit stops toggling
// ReturnStatus = Check_Data_Polling(Dst, 0xFFFF, BlockEraseTime); // wait until DQ7 outputs 1
return ReturnStatus;
}
/************************************************************************/
/* PROCEDURE: Erase_Entire_Chip */
/* */
/* This procedure can be used to erase the entire chip. */
/* */
/* Input: */
/* NONE */
/* */
/* Output: */
/* return TRUE: indicates success in block-erase */
/* return FALSE: indicates timeout in block-erase */
/************************************************************************/
u8 Erase_Entire_Chip(void)
{
u8 ReturnStatus=TRUE;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -