Sst25vf080b

来源:互联网 发布:2016年网络主播招聘 编辑:程序博客网 时间:2024/05/20 16:44
#include "DataType.h"


#define  SSTERASE_4K (4*1024)
#define  SSTERASE_32K (32*1024)
#define  SSTERASE_64K (64*1024)


#define  SSTERASE_SIZE SSTERASE_4K


//这块数据也用于不写flash时的共享内存
INT8U   DataBackUp[SSTERASE_SIZE]; //备份未写数据
/******************************************************************************
;
******************************************************************************/
#define SST25_WRITE_DEL 0x1000//write data max delay procss


#define WRITE       0x02  //Write to Memory instruction
#define WRSR       0x01  //Write Status Register instruction
#define WREN       0x06  //Write enable instruction
#define WRDI 0x04//Write disable instruction
#define EWSR 0x50//enable write status register
#define WRAAI 0xAD//auto address inerement programming


#define ERASE4KB 0x20//erase 4k byte of memory array
#define ERASE32KB 0x52//erase 32k byte block memory array
#define ERASE64KB 0xDB//erase 64k byte block memory array
#define BE         0xC7  //Bulk Erase instruction


#define READ       0x03  //Read from Memory instruction
#define HIGHREAD 0x0B//higne speed read memory instruction
#define RDSR       0x05  //Read Status Register instruction
#define RDID       0x9F  //Read identification




static const INT8U SST25_DIVEC_TBL[] = { //sst25vf0805 drv process
0xBF,0x8E,0xBF,0x8E
};
/******************************************************************************
;
******************************************************************************/
static void SST25_WriteEnable(void);
static void SST25_WriteDisable(void);
static BOOL SST25_WaitForWriteEnd(void);
static void SST25_CmdReadWrite(INT16U ccLen,INT8U *pCmd,INT16U crLen,INT8U* pBuf);
static void SST25_Delay(void);
void SST25_Initial(void);
INT8U SST25_ReadStatusRegister(void);
BOOL SST25_WriteStatusRegister(INT8U cSta);
BOOL SST25_Erase(INT32U lAdr);


extern void TIMER3_10msStop(void);
extern void TIMER3_10msStart(void);
/******************************************************************************
; Function Description
; Enter Parameter : void
; Return Parameter : void
******************************************************************************/
extern void SPIDRV_Initial(void);
void SST25_Initial(void)
{
GPIO_BitSet(GPIO_FLASH_CE,IOHILO_HI);
SPIDRV_Initial();
return;
}


/******************************************************************************
; Function Description
; Enter Parameter : void
; Return Parameter : void
******************************************************************************/
BOOL SST25_Test(void)
{
#if 1
INT8U buf[4];


buf[0] = 0x90;
buf[1] = 0x00;
buf[2] = 0x00;
buf[3] = 0x00;
SST25_CmdReadWrite(0x04,buf,0x04,buf);
return MEM_Cmp(0x04,(char*)buf,(char*)(SST25_DIVEC_TBL));
#else
return TRUE;
#endif
}




/******************************************************************************
; Function Description
; Enter Parameter : void
; Return Parameter : void
******************************************************************************/
BOOL SST25DRV_ReadData(INT32U lAddr,INT16U iLen,INT8U* pBuf)
{
INT8U buf[5];

buf[0] = READ;//cmd proces hi 0x0B
buf[1] = (INT8U)(lAddr >> 0x10);
buf[2] = (INT8U)(lAddr >> 0x08);
buf[3] = (INT8U)(lAddr >> 0x00);
SST25_CmdReadWrite(0x04,buf,iLen,pBuf);
return TRUE;
}


// 快速读可以达到50MHz
BOOL SST25_ReadHData(INT32U lAddr,INT16U iLen,INT8U* pBuf)
{
INT8U buf[5];

buf[0] = HIGHREAD;//cmd proces hi 0x0B
buf[1] = (INT8U)(lAddr >> 0x10);
buf[2] = (INT8U)(lAddr >> 0x08);
buf[3] = (INT8U)(lAddr >> 0x00);
SST25_CmdReadWrite(0x04,buf,iLen,pBuf);
return TRUE;
}


/******************************************************************************
; Function Description
; Enter Parameter : void
; Return Parameter : void
******************************************************************************/
BOOL SST25_WriteData(INT32U lAdr,INT16U iLen,INT8U* pBuf)
{
  BOOL r;
  INT8U reg;
  BOOL set;
INT8U buf[6];
INT8U n;
INT16U len;
INT32U adr;
INT8U* data;
INT8U*   pTmp;


INT8U sectors;
INT16U offset;


INT32U Adr;
INT16U Length;
INT8U  iTmep =0;
INT16U  iRemainSpace;
sectors = lAdr/4096;
offset  = lAdr % 4096;
iRemainSpace = 4096 - offset;


TIMER3_10msStop();


if(iRemainSpace < iLen)
{
iTmep =1; //跨扇区
}
for(INT8U i =0 ;i<iTmep+1;i++)
{
pTmp= DataBackUp;
memset(DataBackUp,0xFF,4096);
if(i ==0)
{
Adr = (sectors * 4096);
SST25_ReadHData( Adr,4096,pTmp);
MEM_Copy(iLen, (char*)&pTmp[offset], (char*)pBuf);
SST25_Erase(Adr);
}
else
{
Adr = ((sectors +1)* 4096);//跨扇区
SST25_ReadHData( Adr,4096,pTmp);
MEM_Copy(iLen-iRemainSpace, (char*)&pTmp[0], (char*)&pBuf[iRemainSpace]);
SST25_Erase(Adr);
}

Length = 4096;

len = Length;//iLen;//back length value
adr = Adr;//lAdr;
data = pTmp;


set = FALSE;
reg = SST25_ReadStatusRegister();//back register value
SST25_WriteStatusRegister(0x00);//clr write back process
SST25_WriteEnable();//Enable Write
while(Length > 0x00)//check length value process
{
  if (Length < 0x02)//check data if < 0x02 process
{
  if (set == TRUE)//close adi process status
{
SST25_WriteDisable();//close write disable
SST25_WaitForWriteEnd();
SST25_WriteEnable();//Enable Write
}
n = 0x05; //setting send length
buf[0] = WRITE;//write one byte process
buf[1] = (INT8U)(Adr >> 0x10);
buf[2] = (INT8U)(Adr >> 0x08);
buf[3] = (INT8U)(Adr >> 0x00);
buf[4] = *pTmp;
pTmp++;
Length--; //renew data length value
}
else
{
  buf[0] = WRAAI;
if (set == FALSE)//one setting adress process
{
  n = 0x06;//setting send data length
  buf[1] = (INT8U)(Adr >> 0x10);
buf[2] = (INT8U)(Adr >> 0x08);
buf[3] = (INT8U)(Adr >> 0x00);
buf[4] = *pTmp;
pTmp++;
buf[5] = *pTmp;
pTmp++; //modify pointer value
  set = TRUE;
}
else
{
  n = 0x03;//setting send data length
buf[1] = *pTmp;
pTmp++;
buf[2] = *pTmp;
pTmp++; //modify pointer value
}
Length -= 0x02;
Adr += 0x02;
}
SST25_CmdReadWrite(n,buf,0x00,buf);//write flash byte
SST25_WaitForWriteEnd();
}
SST25_WriteDisable();//close write disable
r = SST25_WaitForWriteEnd();//wait write complete
SST25_WriteStatusRegister(reg);//renew status register process
#if 1
if (r == TRUE)//write complete process
{
for( ;len > 0x00; len--)//read data compare process
{
SST25DRV_ReadData(adr,0x01,buf);
if (buf[0] != *data)//check error process
{
r = FALSE;
break;
}
data++; 
adr++;
}
}
#endif
}


TIMER3_10msStart();
return r;
}


/**********************************************************************************
*注意: 使用地址自动增加写数据时,起始地址只能是偶数
*数据字节0将被编入的起始地址[A23-A1]与A0=0,数据字节1将被编入初始地址[A23-A1]与A0=1
*
**********************************************************************************/
BOOL SST25_WriteData_NoErase(INT32U lAdr,INT16U iLen,INT8U* pBuf)
{
  BOOL r;
  INT8U reg;
  BOOL set;
INT8U buf[6];
INT8U n;
INT16U len;
INT32U adr;
INT8U* data;
len = iLen;//back length value
adr = lAdr;
data = pBuf;
set = FALSE;
TIMER3_10msStop();


while(iLen > 0x00)//check length value process
{
  if (iLen < 0x02 || ( lAdr%2 != 0) )//check data if < 0x02 process
{
  if (set == TRUE)//close adi process status
{
SST25_WriteDisable();//close write disable
SST25_WaitForWriteEnd();
SST25_WriteEnable();//Enable Write
}
else
{
reg = SST25_ReadStatusRegister();//back register value
SST25_WriteStatusRegister(0x00);//clr write back process
SST25_WriteEnable();//Enable Write
}
n = 0x05; //setting send length
buf[0] = WRITE;//write one byte process
buf[1] = (INT8U)(lAdr >> 0x10);
buf[2] = (INT8U)(lAdr >> 0x08);
buf[3] = (INT8U)(lAdr >> 0x00);
buf[4] = *pBuf;
pBuf++;
iLen--;
lAdr++; //renew data length value
}
else
{
  buf[0] = WRAAI;
if (set == FALSE)//one setting adress process
{
reg = SST25_ReadStatusRegister();//back register value
SST25_WriteStatusRegister(0x00);//clr write back process
SST25_WriteEnable();//Enable Write

  n = 0x06;//setting send data length
  buf[1] = (INT8U)(lAdr >> 0x10);
buf[2] = (INT8U)(lAdr >> 0x08);
buf[3] = (INT8U)(lAdr >> 0x00);
buf[4] = *pBuf;
pBuf++;
buf[5] = *pBuf;
pBuf++; //modify pointer value
  set = TRUE;
}
else
{
  n = 0x03;//setting send data length
buf[1] = *pBuf;
pBuf++;
buf[2] = *pBuf;
pBuf++; //modify pointer value
}
iLen -= 0x02;
lAdr += 0x02;
}
SST25_CmdReadWrite(n,buf,0x00,buf);//write flash byte
SST25_WaitForWriteEnd();


}
SST25_WriteDisable();//close write disable
r = SST25_WaitForWriteEnd();//wait write complete
SST25_WriteStatusRegister(reg);//renew status register process




#if 1
if (r == TRUE)//write complete process
{
for( ;len > 0x00; len--)//read data compare process
{
SST25DRV_ReadData(adr,0x01,buf);
if (buf[0] != *data)//check error process
{

r = FALSE;
len=len;
                break;
}
data++; 
adr++;
}
}
#endif


TIMER3_10msStart();


return r;
}


/******************************************************************************
; Function Description
; Enter Parameter : void
; Return Parameter : void
******************************************************************************/
INT8U SST25_ReadStatusRegister(void)
{
INT8U buf[2];


buf[0] = RDSR;//send read status rigister
SST25_CmdReadWrite(0x01,buf,0x01,buf);
return (buf[0]);
}


/******************************************************************************
; Function Description
; Enter Parameter : void
; Return Parameter : void
******************************************************************************/
BOOL SST25_WriteStatusRegister(INT8U cSta)
{
INT8U buf[2];

buf[0] = EWSR;
SST25_CmdReadWrite(0x01,buf,0x00,buf);
buf[0] = WRSR;
buf[1] = cSta;
SST25_CmdReadWrite(0x02,buf,0x00,buf);
return TRUE;
}


/******************************************************************************
; Function Description
; Enter Parameter : void
; Return Parameter : void
******************************************************************************/
BOOL SST25_ChipAllErase(void)
{
INT8U buf[2];
    INT8U reg;
    BOOL r;
    reg = SST25_ReadStatusRegister();
SST25_WriteStatusRegister(0x00);
SST25_WriteEnable();//Send write enable instruction
buf[0] = BE; //erase full memory array 
SST25_CmdReadWrite(0x01,buf,0x00,buf);
     r= SST25_WaitForWriteEnd();
    SST25_WriteStatusRegister(reg);
return r; //Wait the end of Flash writing
}
/******************************************************************************
; Function Description
; Enter Parameter : void
; Return Parameter : void
******************************************************************************/
BOOL SST25_Erase(INT32U lAdr)
{
  INT8U buf[4];
INT8U reg;
    BOOL r;
    reg = SST25_ReadStatusRegister();
SST25_WriteStatusRegister(0x00);
SST25_WriteEnable();//Send write enable instruction
#if (SSTERASE_SIZE==SSTERASE_64K)
buf[0] = ERASE64KB;
#elif (SSTERASE_SIZE==SSTERASE_32K)
buf[0] = ERASE32KB;
#else
buf[0] = ERASE4KB;
#endif
buf[1] = (INT8U)(lAdr >> 0x10);
buf[2] = (INT8U)(lAdr >> 0x08);
buf[3] = (INT8U)(lAdr >> 0x00);
SST25_CmdReadWrite(0x04,buf,0x00,buf);
     r= SST25_WaitForWriteEnd();
    SST25_WriteStatusRegister(reg);
return r; //Wait the end of Flash writing
}


/******************************************************************************
; Function Description
; Enter Parameter : void
; Return Parameter : void
******************************************************************************/
static void SST25_WriteEnable(void)
{
INT8U buf[2];


buf[0] = WREN;// read status value
SST25_CmdReadWrite(0x01,buf,0x00,buf);
return;
}


/******************************************************************************
; Function Description
; Enter Parameter : void
; Return Parameter : void
******************************************************************************/
static void SST25_WriteDisable(void)
{
  INT8U buf[2];


buf[0] = WRDI;
SST25_CmdReadWrite(0x01,buf,0x00,buf);
return;
}


/******************************************************************************
; Function Description
; Enter Parameter : void
; Return Parameter : void
******************************************************************************/
static BOOL SST25_WaitForWriteEnd(void)
{
  INT16U del;
INT8U  Status;
for(del = 0x00; del < SST25_WRITE_DEL; del++)//write delay process
{
  SST25_Delay();
Status = SST25_ReadStatusRegister(); 
  if (((Status & 0x01) == 0x00))//check busy process
{
return TRUE;
}
}
return FALSE;
}


/******************************************************************************
; Function Description
; Enter Parameter : void
; Return Parameter : void
******************************************************************************/
static void SST25_CmdReadWrite(INT16U icLen,INT8U *pCmd,INT16U irLen,INT8U* pBuf)
{
GPIO_BitSet(GPIO_FLASH_CE,IOHILO_LO);
SPIDRV_SendDatas(icLen,pCmd);
if(pCmd[0] == HIGHREAD )
{
SPIDRV_SendByte(0xff);
SPIDRV_ReceiveByte();
}
SPIDRV_ReadDatas(irLen,pBuf);
GPIO_BitSet(GPIO_FLASH_CE,IOHILO_HI);



}


/******************************************************************************
; Function Description
; Enter Parameter : void
; Return Parameter : void
******************************************************************************/
static void SST25_Delay(void)
{
  INT16U i;

for(i = 0x00; i < 128; i++)
{
 ;
}
return;
}



0 0