📄 sst36vf1601c_x16mode.cpp
字号:
/*
Device Driver in generic C language for SST36VF1601C working at x16 WORD Mode
Jerry Deng,
Silicon Storage Technology, Inc.
Revision 1.0, Feb 2004
This code is for customer's reference ONLY and is provided AS IS, SST MAKES NO
WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION ANY WARRANTY OF
MERCHANTABILITY OR FITNESS FOR PARTICULAR PURPOSE. IN NO EVENT SHALL SST BE
LIABLE FOR ANY INCIDENTAL OR CONSEQUENTIAL DAMAGES WITH RESPECT TO THE USE OF
THIS CODE AND/OR SST PRODUCTS.
SST36VF1601C datasheet should be reviewed in conjunction with this code to
completely understand the operation of this device.
SST36VF1601C supports bottom boot block (Block 0) protection, 4 sectors in Block 0 are
protected from being erased/programmed when WP# is low and unprotected when WP# is high.
It's assumed that Byte# pin is always held stable high(Vih or VDD) during the
execution of this code so that the device is working at x16 Word Mode. Otherwise,
If Byte# is low(Vil or ground), the device is working at x8 Byte Mode, please
reference to another device driver specially designed for SST36VF1601C at x8 Byte Mode.
During execution of this code, it's also assumed that RST# signal on device is held in
logic high state, otherwise the device will be put into reset state (read mode)
after Try(20us Max) once RST# changes from high to low.
*/
#define AddrsShift 2
// define 2 if it's true that A1 of system address bus has been shifted to A0 of device address, A2 to A1, etc.
// otherwise, change it to look like:
// #define AddrsShift 1
#define Bank2 0xC0000 // starting Word Address of Bank 2
#define DefaultBaseAddress 0x0 // default device base address for SST36VF1601C
#define ChipEraseTime 714286 // maximum timeout of read cycles for chip-erase, 50ms/70ns
#define BlockEraseTime 357143 // maximum timeout of read cycles for sector-erase, 25ms/70ns
#define SectorEraseTime 357143 // maximum timeout of read cycles for sector-erase, 25ms/70ns
#define WordProgramTime 143 // maximum timeout of read cycles for WORD-program, 10us/70ns
#ifndef TRUE
#define TRUE 1
#endif
#ifndef FALSE
#define FALSE 0
#endif
#ifndef BYTE
typedef unsigned char BYTE;
#endif
#ifndef WORD
typedef unsigned short WORD;
#endif
#ifndef U32
typedef unsigned long U32;
#endif
U32 BaseAddrs=DefaultBaseAddress;
// In some cases, system will assign a device base address for flash only at run time.
// This is the reason that we define BaseAddrs as a variable rather than a CONSTANT.
// The C code in this document contains the following routines in order:
// Name Function
U32 ReadID_FromBank1(void); // Check manufacturer ID and device ID from Bank 1
U32 ReadID_FromBank2(void); // Check manufacturer ID and device ID from Bank 1
void QueryCFI_FromBank1(WORD *); // Read CFI information from Bank 1
void QueryCFI_FromBank2(WORD *); // Read CFI information from Bank 2
void Query_SecID(WORD *, WORD *); // Read both SST SecID and User SecID information
BYTE Program_One_Word(WORD, U32); // Program one WORD into device
BYTE Erase_One_Sector(U32); // Erase one sector(2KWORD)
BYTE Erase_One_Block(U32); // Erase one block (32KWORD)
BYTE Erase_Entire_Chip(void); // Erase the whole chip
BYTE SecID_Lock_Status(void); // Check User SecID lock status
BYTE User_SecID_Word_Program(WORD *, U32, BYTE); // Program n WORDs into User SecID segment
BYTE User_SecID_Lock_Out(void); // Lock out User SecID segment
void Erase_Suspend(void); // Temporarily suspend one sector-erase or block-erase
BYTE Erase_Resume(U32); // Resume suspended sector-erase or block-erase
BYTE Check_ToggleDQ6(U32, U32); // Wait until DQ6 stops toggling
BYTE Check_DataPollingDQ7(U32, WORD, U32); // Wait until DQ7 outputs true data
void Delay_150_Nanoseconds(void); // delay 150ns
void Delay_1_Microsecond(void); // delay 1us
void Delay_20_Microseconds(void); // delay 20us
/************************************************************************/
/* PROCEDURE: ReadID_FromBank1 */
/* */
/* This procedure reads ID from Bank 1 of SST36VF1601C. */
/* */
/* Input: None */
/* */
/* Output: 00BF734Bh for SST36VF1601C. */
/* Any other value indicates non SST36VF1601C. */
/* High word is vendor ID, low word is device ID. */
/************************************************************************/
U32 ReadID_FromBank1(void)
{
U32 ReturnStatus=0;
// Issue Software ID Entry command to SST36VF1601C
*(WORD *) (BaseAddrs + 0x5555*AddrsShift) = 0xAA; // 1st write data 0xAA to device addr 5555H for A14 to A0
*(WORD *) (BaseAddrs + 0x2AAA*AddrsShift) = 0x55; // 2nd write data 0x55 to device addr 2AAAH for A14 to A0
*(WORD *) (BaseAddrs + 0x5555*AddrsShift) = 0x90; // 3rd write data 0x90 to device addr 5555H for A14 to A0
Delay_150_Nanoseconds(); // delay Tida (max. 150ns) for SST36VF1601C
ReturnStatus = *(WORD *) (BaseAddrs + 0*AddrsShift);
ReturnStatus = (ReturnStatus << 16) | *(WORD *) (BaseAddrs + 1*AddrsShift);
// Before exit Software ID mode, all subsequent read with address within Bank 2 will return data in Bank 2
// array, rather than IDs.
// For example, next read will return data at address 180000h and 180001h, not vendor ID.
// WORD ReadBank2;
// ReadBank2 = *(WORD *) (BaseAddrs + (0 + Bank2)*AddrsShift); // read data at address 180000h in Bank 2
// ReadBank2 = *(WORD *) (BaseAddrs + (1 + Bank2)*AddrsShift); // read data at address 180001h in Bank 2
// Issue Software ID Exit command to put SST36VF1601C into normal read mode.
// Two Exit commands ( 3 cycles Exit and shorter 1 cycle Exit command) are equivalent.
*(WORD *) (BaseAddrs + 0x5555*AddrsShift) = 0xAA; // 1st write data 0xAA to device addr 5555H for A14 to A0
*(WORD *) (BaseAddrs + 0x2AAA*AddrsShift) = 0x55; // 2nd write data 0x55 to device addr 2AAAH for A14 to A0
*(WORD *) (BaseAddrs + 0x5555*AddrsShift) = 0xF0; // 3rd write data 0xF0 to device addr 5555H for A14 to A0
Delay_150_Nanoseconds(); // then delay Tida (max. 150ns) for SST36VF1601C
return ReturnStatus;
}
/************************************************************************/
/* PROCEDURE: ReadID_FromBank2 */
/* */
/* This procedure reads ID from Bank 2 of SST36VF1601C. */
/* */
/* Input: None */
/* */
/* Output: 00BF734Bh for SST36VF1601C. */
/* Any other value indicates non SST36VF1601C. */
/* High word is vendor ID, low word is device ID. */
/************************************************************************/
U32 ReadID_FromBank2(void)
{
U32 ReturnStatus=0;
// Issue Software ID Entry command to SST36VF1601C
*(WORD *) (BaseAddrs + 0x5555*AddrsShift) = 0xAA; // 1st write data 0xAA to device addr 5555H for A14 to A0
*(WORD *) (BaseAddrs + 0x2AAA*AddrsShift) = 0x55; // 2nd write data 0x55 to device addr 2AAAH for A14 to A0
*(WORD *) (BaseAddrs + (0x5555 + Bank2)*AddrsShift) = 0x90; // 3rd write data 0x90 to device addr 5555H for A14 to A0
Delay_150_Nanoseconds(); // delay Tida (max. 150ns) for SST36VF1601C
ReturnStatus = *(WORD *) (BaseAddrs + (0 + Bank2)*AddrsShift);
ReturnStatus = (ReturnStatus << 16) | *(WORD *) (BaseAddrs + (1 + Bank2)*AddrsShift);
// Before exit Software ID mode, all subsequent read with address within Bank 1 will return data in Bank 1
// array, rather than IDs.
// For example, next read will return data at address 000000h and 000001h, not vendor ID.
// WORD ReadBank1;
// ReadBank1 = *(WORD *) (BaseAddrs + 0*AddrsShift); // read data at address 000000h in Bank 1
// ReadBank1 = *(WORD *) (BaseAddrs + 1*AddrsShift); // read data at address 000001h in Bank 1
// Issue Software ID Exit command to put SST36VF1601C into normal read mode.
// *(WORD *) (BaseAddrs + 0x5555*AddrsShift) = 0xAA; // 1st write data 0xAA to device addr 5555H for A14 to A0
// *(WORD *) (BaseAddrs + 0x2AAA*AddrsShift) = 0x55; // 2nd write data 0x55 to device addr 2AAAH for A14 to A0
*(WORD *) (BaseAddrs + 0x5555*AddrsShift) = 0xF0; // 3rd write data 0xF0 to device addr 5555H for A14 to A0
Delay_150_Nanoseconds(); // then delay Tida (max. 150ns) for SST36VF1601C
return ReturnStatus;
}
/************************************************************************/
/* PROCEDURE: QueryCFI_FromBank1 */
/* */
/* This procedure queries CFI information from Bank 1. */
/* */
/* Input: *CFI A pointer to store CFI data string (total 37 words). */
/* */
/* Output: The pointer points to CFI data string. */
/************************************************************************/
void QueryCFI_FromBank1(WORD *CFI)
{
// Issue the CFI Query Entry command to SST36VF1601C
*(WORD *) (BaseAddrs + 0x5555*AddrsShift) = 0xAA; // 1st write data 0xAA to device addr 5555H for A14 to A0
*(WORD *) (BaseAddrs + 0x2AAA*AddrsShift) = 0x55; // 2nd write data 0x55 to device addr 2AAAH for A14 to A0
*(WORD *) (BaseAddrs + 0x5555*AddrsShift) = 0x98; // 3rd write data 0x98 to device addr 5555H for A14 to A0
Delay_150_Nanoseconds( ); // delay Tida (150ns)
// retrieve all CFI data string from EVEN ADDRESS between 0010H and 0034H.
for (BYTE i=0x10; i<=0x34; CFI++, i++)
*CFI = *(WORD *) (BaseAddrs + i*AddrsShift); // save CFI data into user-defined pointer.
// Before exit CFI Query mode, all subsequent read with address within Bank 2 will return
// data in Bank 2 array, rather than CFI string.
// For example, next read will return data at address 180020h and 180022h, not CFI string.
// WORD ReadBank2;
// ReadBank2 = *(WORD *) (BaseAddrs + (0x20 + Bank2)*AddrsShift); // read data at address 180020h in Bank 2 array
// ReadBank2 = *(WORD *) (BaseAddrs + (0x22 + Bank2)*AddrsShift); // read data at address 180022h in Bank 2 array
// Issue CFI Exit command to return SST36VF1601C to read mode.
// *(WORD *) (BaseAddrs + 0x5555*AddrsShift) = 0xAA; // 1st write data 0xAA to device addr 5555H for A14 to A0
// *(WORD *) (BaseAddrs + 0x2AAA*AddrsShift) = 0x55; // 2nd write data 0x55 to device addr 2AAAH for A14 to A0
*(WORD *) (BaseAddrs + 0x5555*AddrsShift) = 0xF0; // 3rd write data 0xF0 to device addr 5555H for A14 to A0
Delay_150_Nanoseconds( ); // insert delay time = Tida
}
/************************************************************************/
/* PROCEDURE: QueryCFI_FromBank2 */
/* */
/* This procedure queries CFI information from Bank 2. */
/* */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -