📄 sst39vf3201.c
字号:
while (length--)
{
*(WORD *) (BaseAddrs + 0x5555 * AddrsShift) = 0x00AA; // 1st write data 0x00AA to device addr 5555H
*(WORD *) (BaseAddrs + 0x2AAA * AddrsShift) = 0x0055; // 2nd write data 0x0055 to device addr 2AAAH
*(WORD *) (BaseAddrs + 0x5555 * AddrsShift) = 0x00A5; // 3rd write data 0x00A5 to device addr 5555H
*(WORD *) (BaseAddrs + Dst * AddrsShift) = *SrcWord; // 4th write data word *SrcWord to destination Dst
++Dst; // point to next address
++SrcWord; // point to next data
// Read the toggle bit to detect end-of-programming for User Sec ID.
// Do Not use Data# Polling for User_SecID_Word_Program!!
ReturnStatus = Check_Toggle_Ready(Dst, WordProgramTime); // wait for TOGGLE bit to get ready
if (!ReturnStatus)
return FALSE; // SecID Word-Program failed!
}
return TRUE;
}
/************************************************************************/
/* PROCEDURE: User_SecID_Lock_Out */
/* */
/* This procedure can be used to Lock Out the User Security ID. */
/* */
/* NOTE: */
/* 2. Data in User SecID segment can't be erased, They are OTP. */
/* 3. User SecID segment can't be unlocked once it's locked. */
/* */
/* Input: None */
/* */
/* Output: */
/* TRUE if successfully locked after programming. */
/* FALSE if timeout error or chip is not locked after programming.*/
/************************************************************************/
BYTE User_SecID_Lock_Out (void)
{
BYTE ReturnStatus=TRUE;
if(SecID_Lock_Status( )) // double check if it's already locked.
return TRUE; // return TRUE if locked.
*(WORD *) (BaseAddrs + 0x5555 * AddrsShift) = 0x00AA; // 1st write data 0x00AA to device addr 5555H
*(WORD *) (BaseAddrs + 0x2AAA * AddrsShift) = 0x0055; // 2nd write data 0x0055 to device addr 2AAAH
*(WORD *) (BaseAddrs + 0x5555 * AddrsShift) = 0x0085; // 3rd write data 0x0085 to device addr 5555H
*(WORD *) (BaseAddrs + 0) = 0x0000; // 4th write data 0x0000 to any address
ReturnStatus = Check_Toggle_Ready(0, WordProgramTime); // wait for TOGGLE bit to get ready
if(ReturnStatus)
if(SecID_Lock_Status( )) // double check if it's really locked.
return TRUE; // return TRUE if locked.
return FALSE; // otherwise, return FALSE.
}
/************************************************************************/
/* PROCEDURE: Erase_Suspend */
/* */
/* This procedure can be used to temporarily suspend a Sector/Block- */
/* Erase operation in SST39VF320X. */
/* */
/* Input: None */
/* */
/* Output: None */
/************************************************************************/
void Erase_Suspend (void)
{
*(WORD *) (BaseAddrs + 0x5555 * AddrsShift) = 0x00B0; // write data 0x00B0 to any address, e.g.5555H
Delay_20_Micro_Seconds(); // The device will be ready to read after 20us.
}
/************************************************************************/
/* PROCEDURE: Erase_Resume */
/* */
/* This procedure can be used to resume a Sector-Erase or Block-Erase */
/* operation that had been suspended in SST39VF320X. */
/* */
/* Input: None */
/* */
/* Output: */
/* TRUE if success */
/* FALSE if timeout error */
/************************************************************************/
BYTE Erase_Resume (void)
{
BYTE ReturnStatus=TRUE;
*(WORD *) (BaseAddrs + 0x5555 * AddrsShift) = 0x0030; // write data 0x0030 to any address, e.g.5555H
ReturnStatus=Check_Toggle_Ready(0, BlockEraseTime); // because BlockEraseTime=SectorEraseTime.
return ReturnStatus; // Don't return to caller until erase is completed!
}
/************************************************************************/
/* PROCEDURE: Check_Toggle_Ready */
/* */
/* During the internal erase/program, any consecutive read operation */
/* on DQ6 will produce alternating 0's and 1's i.e. toggling between */
/* 0 and 1. When the operation is completed, DQ6 will stop toggling. */
/* After 1us bus recovery time, the device is ready for next operation. */
/* */
/* Input: */
/* Dst any valid device address */
/* MaxCycles maximum time allowed for that specific operation */
/* */
/* Output: TRUE for success */
/* FALSE for timeout error */
/************************************************************************/
BYTE Check_Toggle_Ready (DWORD Dst, DWORD MaxCycles)
{
WORD CurrData, PreData;
DWORD TimeOut = 0;
PreData = *(WORD *) (BaseAddrs + Dst * AddrsShift); // read data
PreData = PreData & 0x0040; // get DQ6
while (TimeOut < MaxCycles) // check if time-out
{
CurrData = *(WORD *) (BaseAddrs + Dst * AddrsShift); // read again
CurrData = CurrData & 0x0040; // retrieve bit DQ6
if (PreData == CurrData)
{ Delay_1_Microsecond( ); // delay 1us for bus recovery
return TRUE; // return true if DQ6 stops toggling.
}
PreData = CurrData;
TimeOut++;
}
return FALSE; // timeout error
}
/************************************************************************/
/* PROCEDURE: Check_Data_Polling */
/* */
/* During the internal erase/program, any attempt to read DQ7 of the */
/* last byte loaded will receive the complement of the true data. */
/* Once the program cycle is completed, DQ7 will show true data. */
/* For erase, DQ7 will output 0 during busy of internal operation. */
/* DQ7 will ouput 1 once the internal erase operation is completed. */
/* */
/* Input: */
/* Dst any valid device address */
/* TrueData this is the original (true) data */
/* MaxCycles maximum time allowed for that specific operation */
/* */
/* Output: */
/* TRUE if Success */
/* FALSE if timeout error */
/************************************************************************/
BYTE Check_Data_Polling (DWORD Dst, WORD TrueData, DWORD MaxCycles)
{
WORD CurrData;
DWORD Timeout = 0;
TrueData = TrueData & 0x0080; // keep DQ7 only
while (Timeout < MaxCycles) // compare if timeout
{
CurrData = *(WORD *) (BaseAddrs + Dst * AddrsShift); // read data word.
CurrData = CurrData & 0x0080; // get bit DQ7
if (CurrData == TrueData)
{Delay_1_Microsecond( ); // delay 1us for bus recovery
return TRUE; // return TRUE if DQ7 outputs true data.
}
Timeout++;
}
return FALSE; // otherwise, return FALSE if timeout error.
}
void Delay_150_Nano_Seconds(void) // delay 150ns.
{ int i;
for(i=0; i<10; i++); // change the number according to your system speed.
}
void Delay_1_Microsecond(void) // delay 1us
{ int i;
for(i=0; i<70; i++); // change number 70 according to application system speed.
}
void Delay_20_Micro_Seconds(void) // delay 20us.
{ int i;
for(i=0; i<0x5000; i++); // change the number according to your system speed.
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -