📄 sst28f040_zly_driver.c
字号:
#pragma large
#include "w77e58.h"
#include "flash.h"
#include <stdlib.h>
#include <intrins.h>
#include "math.h"
#define FLASH_BASE_ADDR 0x8000
#define FALSE 0
#define TRUE 1
#define ROW_SIZE 256 /* Must be 256 unsigned char xdatas for 28SF040 */
#define SST_ID 0xBF /* SST Manufacturer抯 ID code */
#define SST_28SF040 0x04 /* SST 28SF040 device code */
#define AUTO_PG_ERASE1 0x20
#define AUTO_PG_ERASE2 0xD0
#define AUTO_PGRM 0x10
#define RESET 0xFF
#define READ_ID 0x90
void Enable_Chip_Data_Protection();
void Disable_Chip_Data_Protection();
void Check_Data_Polling (unsigned char *Dst, unsigned char TrueData);
int Check_Toggle_Ready (unsigned char *Dst);
/*****************************************************************************************************/
/* PROCEDURE: Write_28SF040 */
/* */
/* This procedure can be used to write a total of 256 bytes at one write cycle to the */
/* SST抯 28SF040 4 Mbit SuperFlash EEPROM. */
/* */
/* Input: */
/* SRC SOURCE address containing the data which will be */
/* written into the 28SF040. */
/* Dst DESTINATION address which will be written with the */
/* data passed in from ds:si */
/* */
/* Output: */
/* return - 1 : indicates an error in programming the 28SF040 */
/* return - 0 : indicates no error in programming the 28SF040 */
/*****************************************************************************************************/
int Write_28SF040 (unsigned char *Src, unsigned int Dst)
{
unsigned char *SourceBuf;
unsigned char *DestBuf;
int Index;
int Count;
unsigned char SourceByte;
unsigned char ProgrammedByte;
unsigned char Continue;
char tmp1;
char tmp2;
unsigned long TimeOut ;
char Loop;
Loop=TRUE;
TimeOut=0;
/*和本次设计有关,详细情况参考透明modem原理图*/
if(Dst>=0x8000)
{
P1_4 = 1;
;
}
else
{
P1_4 = 0;
Dst=Dst+FLASH_BASE_ADDR;
}
Disable_Chip_Data_Protection();
SourceBuf = Src;
DestBuf = (unsigned char *)Dst;
/************************************************************************************/
/* ERASE OPERATION */
/* */
/************************************************************************************/
*DestBuf = AUTO_PG_ERASE1;
*DestBuf = AUTO_PG_ERASE2;
Check_Toggle_Ready((unsigned char *)Dst);
Count = 0;
Continue = TRUE;
while ((Count < ROW_SIZE) && (Continue))
{
SourceByte = * DestBuf++;
if (SourceByte == 0xFF)
Count++;
else
Continue = FALSE;
}
if (!Continue)
{
Enable_Chip_Data_Protection();
return (FALSE);
}
/**********************************************************************************************************/
/* PROGRAM OPERATION */
/* */
/**********************************************************************************************************/
SourceBuf = Src;
DestBuf = (unsigned char *)Dst;
for (Index = 0; Index < ROW_SIZE; Index++)
{
SourceByte = *SourceBuf++;
if (SourceByte != 0xFF)
{
*DestBuf = AUTO_PGRM;
*DestBuf = SourceByte;
if(FALSE==Check_Toggle_Ready((unsigned char*)Dst))
{
//如果通过检查,数据出错,就通过进一步的读取数据进一步确认
while ((TimeOut< 0x07FFFFFF) && (Loop))
{
tmp1 = *(DestBuf);
tmp2 = *(DestBuf);
if(tmp1==tmp2)
Loop=FALSE;
TimeOut++;
}
if (Loop==FALSE) Continue = TRUE;
else Continue = FALSE;
}
ProgrammedByte = *DestBuf;
//检查写入的数据是否正确
if (SourceByte != ProgrammedByte)
{
Continue = FALSE;
break;
}
}
DestBuf++;
}
P1_4 = 0;
Enable_Chip_Data_Protection();
if (!Continue)
return(FALSE);
else
return(TRUE);
}
void ReadFlash(unsigned int addr, unsigned char * buf, unsigned int len)
{
unsigned int i;
unsigned char xdata * addr1;
if(addr>=0x8000)
{
P1_4 = 1;
addr1 = addr;
}
else
{
P1_4 = 0;
addr1 = FLASH_BASE_ADDR +addr;
}
for( i=0;i<len;i++)
{
buf[i]=*(addr1+i);
}
buf[len]=0;
P1_4 = 0;
}
void Disable_Chip_Data_Protection()
{
unsigned int adds;
unsigned char TempByte;
adds= (0x1823+FLASH_BASE_ADDR);
TempByte = *(unsigned char*)adds; /* set up address to be E000:1823h */
adds= (0x1820+FLASH_BASE_ADDR);
TempByte = *( unsigned char*)adds; /* set up address to be E000:1820h */
adds =(0x1822+FLASH_BASE_ADDR);
TempByte = *( unsigned char *)adds; /* set up address to be E000:1822h */
adds =(0x0418+FLASH_BASE_ADDR);
TempByte = *( unsigned char*)adds; /* set up address to be E000:0418h */
adds =(0x041B+FLASH_BASE_ADDR);
TempByte = *( unsigned char*)adds; /* set up address to be E000:041Bh */
adds = (0x0419+FLASH_BASE_ADDR) ;
TempByte = *( unsigned char*)adds; /* set up address to be E000:0419h */
adds= (0x041A+FLASH_BASE_ADDR) ;
TempByte = *( unsigned char*)adds;
}
void Enable_Chip_Data_Protection()
{
unsigned int adds;
unsigned char TempByte;
adds= (0x1823+FLASH_BASE_ADDR);
TempByte = *(unsigned char*)adds; /* set up address to be E000:1823h */
adds= (0x1820+FLASH_BASE_ADDR);
TempByte = *( unsigned char*)adds; /* set up address to be E000:1820h */
adds =(0x1822+FLASH_BASE_ADDR);
TempByte = *( unsigned char *)adds; /* set up address to be E000:1822h */
adds =(0x0418+FLASH_BASE_ADDR);
TempByte = *( unsigned char*)adds; /* set up address to be E000:0418h */
adds =(0x041B+FLASH_BASE_ADDR);
TempByte = *( unsigned char*)adds; /* set up address to be E000:041Bh */
adds = (0x0419+FLASH_BASE_ADDR) ;
TempByte = *( unsigned char*)adds; /* set up address to be E000:0419h */
adds= (0x040A+FLASH_BASE_ADDR) ;
TempByte = *( unsigned char*)adds;
}
/******************************************************************************************************/
/*PROCEDURE: Check_Toggle_Ready */
/* */
/*During the internal write cycle, any consecutive read operation */
/*on DQ6 will produce alternating 0抯 and 1抯 i.e. toggling between */
/*0 and 1. When the write 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 */
/******************************************************************************************************/
int Check_Toggle_Ready (unsigned char *Dst)
{
unsigned char Loop = TRUE;
unsigned char PreData;
unsigned char CurrData;
unsigned long TimeOut = 0;
PreData = *Dst;
PreData = PreData & 0x40;
while ((TimeOut< 0x07FFFFFF) && (Loop))
{
CurrData = *Dst;
CurrData = CurrData & 0x40;
if (PreData == CurrData)
Loop = FALSE; /* ready to exit the while loop */
PreData = CurrData;
TimeOut++;
}
if(FALSE==Loop)
return FALSE;
else
return TRUE;
}
/********************************************************************************************************/
/* PROCEDURE: Check_Data_Polling */
/* */
/* During the internal write cycle, any attempt to read DQ7 of the byte loaded during */
/* the byte-load cycle will receive the complement of the true data. Once the write */
/* cycle is completed, DQ7 will show true data. */
/* */
/* Input: */
/* Dst must already set-up by the caller */
/* TrueData this is the original (true) data */
/* */
/* Output: */
/* None */
/********************************************************************************************************/
/*
void Check_Data_Polling (unsigned char *Dst, unsigned char TrueData)
{
unsigned char Loop = TRUE;
unsigned char CurrData;
unsigned long TimeOut = 0;
TrueData = TrueData & 0x80;
while ((TimeOut< 0x07FFFFFF) && (Loop))
{
CurrData = *Dst;
CurrData = CurrData & 0x80;
if (TrueData == CurrData)
Loop = FALSE;
TimeOut++;
}
}
*/
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -