|
/******************************************************************************
|
* Copyright (C) 2014-2015 HangZhou SiZhu Co.,LTD.
|
*
|
*-----------------------------------------------------------------------------
|
* File: w25x40bv.c
|
* Description: FLASH operation code
|
* Author: Lishoujian (867693272@qq.com)
|
* Date: Jan 8, 2015
|
*****************************************************************************/
|
|
/* ----------------------- Platform includes --------------------------------*/
|
|
#include "w25x40bv.h"
|
#include "spi.h"
|
#include "delay.h"
|
|
|
/******************************************
|
* func: Flash_ReadSR
|
* desc: read 1 byte status data from flash
|
* input: none
|
* output: none
|
* return: 1 byte status data read from flash
|
*****************************************/
|
u8 Flash_ReadSR(void)
|
{
|
u8 byte=0;
|
FLASH_CS_LOW;
|
FLASH_ReadWriteByte(FLASH_RDSR); //send read status register instructon
|
byte=FLASH_ReadWriteByte(0Xff);
|
FLASH_CS_HIGH;
|
return byte;
|
}
|
|
/******************************************
|
* func: FLASH_Write_SR
|
* desc: write 1 byte status data to flash
|
* input:
|
* data - 1 byte state data to fram status register
|
* output: none
|
* return: none
|
*****************************************/
|
void FLASH_Write_SR(u8 sr)
|
{
|
FLASH_Write_Enable();
|
FLASH_CS_LOW;
|
FLASH_ReadWriteByte(FLASH_WRSR); //send write status register instructon
|
FLASH_ReadWriteByte(sr);
|
FLASH_CS_HIGH;
|
}
|
|
/******************************************
|
* func: FLASH_Write_Enable
|
* desc: write enable flash.
|
* input: none
|
* output: none
|
* return: none
|
*****************************************/
|
void FLASH_Write_Enable(void)
|
{
|
FLASH_CS_LOW;
|
FLASH_ReadWriteByte(FLASH_WREN); //send write enable instruction
|
FLASH_CS_HIGH;
|
}
|
|
/******************************************
|
* func: FLASH_Write_Disable
|
* desc: write disable flash
|
* input: none
|
* output: none
|
* return: none
|
*****************************************/
|
void FLASH_Write_Disable(void)
|
{
|
FLASH_CS_LOW;
|
FLASH_ReadWriteByte(FLASH_WRDI); //send write disable instruction
|
FLASH_CS_HIGH;
|
}
|
|
/******************************************
|
* func: Flash_ReadID
|
* desc: read 16bit ID from flash
|
* input: none
|
* output: none
|
* return: ID - 16bit Manufacturer ID/Device ID
|
*****************************************/
|
u16 Flash_ReadID(void)
|
{
|
u16 ID = 0;
|
FLASH_CS_LOW;
|
FLASH_ReadWriteByte(FLASH_RDID);//send
|
FLASH_ReadWriteByte(0x00);
|
FLASH_ReadWriteByte(0x00);
|
FLASH_ReadWriteByte(0x00);
|
ID|=FLASH_ReadWriteByte(0xFF)<<8;
|
ID|=FLASH_ReadWriteByte(0xFF);
|
FLASH_CS_HIGH;
|
return ID;
|
}
|
|
/******************************************
|
* func: Flash_Read
|
* desc: read one or one more data bytes from flash
|
* input: pBuffer-data read from flash
|
ReadAddr-32bit input address,just send the front 24bit
|
NumByteToRead-decide how many bytes to read
|
* output: none
|
* return: none
|
*****************************************/
|
void Flash_Read(uint8* pBuffer,uint32 ReadAddr,uint16 NumByteToRead)
|
{
|
u16 i;
|
FLASH_CS_LOW;
|
FLASH_ReadWriteByte(FLASH_READ); //send read command
|
FLASH_ReadWriteByte((u8)((ReadAddr)>>16)); //send 24bit address
|
FLASH_ReadWriteByte((u8)((ReadAddr)>>8));
|
FLASH_ReadWriteByte((u8)ReadAddr);
|
for(i=0;i<NumByteToRead;i++)
|
{
|
pBuffer[i]=FLASH_ReadWriteByte(0XFF);
|
}
|
FLASH_CS_HIGH;
|
}
|
|
|
|
/******************************************
|
* func: Flash_Write
|
* desc: write data into flash,can write more than 256 bytes,and can executed sector erase operation.
|
* input: pBuffer-data write into flash
|
ReadAddr-32bit input address,just send the front 24bit
|
NumByteToRead-decide how many bytes to write
|
* output: none
|
* return: none
|
*****************************************/
|
/*u8 FLASH_BUF[4096];
|
void Flash_Write(uint8* pBuffer,uint32 WriteAddr,uint16 NumByteToWrite)
|
{
|
u32 secpos;
|
u16 secoff;
|
u16 secremain;
|
u16 i;
|
|
secpos=WriteAddr/4096; //sector address 0~127 for w25x40bv
|
secoff=WriteAddr%4096; //sector offset
|
secremain=4096-secoff; //remaining space of sector
|
|
if(NumByteToWrite<=secremain)secremain=NumByteToWrite;//no more than 4096 bytes
|
while(1)
|
{
|
Flash_Read(FLASH_BUF,secpos*4096,4096); //read all data from sector
|
for(i=0;i<secremain;i++) //check data
|
{
|
if(FLASH_BUF[secoff+i]!=0XFF)break;
|
}
|
if(i<secremain)
|
{
|
Flash_Erase_Sector(secpos); //sector erase
|
for(i=0;i<secremain;i++) //write data
|
{
|
FLASH_BUF[i+secoff]=pBuffer[i];
|
}
|
Flash_Write_NoCheck(FLASH_BUF,secpos*4096,4096); //write data into sector
|
|
}
|
else Flash_Write_NoCheck(pBuffer,WriteAddr,secremain);
|
if(NumByteToWrite==secremain)break; //write finish
|
else //write unfinish
|
{
|
secpos++; //sector address add 1
|
secoff=0; //sector offset 0
|
|
pBuffer+=secremain; //pointer offset
|
WriteAddr+=secremain; //write address offset
|
NumByteToWrite-=secremain; //the number of bytes reduce
|
if(NumByteToWrite>4096)secremain=4096; //write operation can't be finished in next sector
|
else secremain=NumByteToWrite; //write operation can be finished in next sector
|
}
|
};
|
}*/
|
|
/******************************************
|
* func: Flash_Write_NoCheck
|
* desc: write data into flash,can write more than 256 bytes.(we must delete the precious data before write)
|
* input: pBuffer-data write into flash
|
ReadAddr-32bit input address,just send the front 24bit
|
NumByteToRead-decide how many bytes to write
|
* output: none
|
* return: none
|
*****************************************/
|
void Flash_Write_NoCheck(u8* pBuffer,u32 WriteAddr,u16 NumByteToWrite)
|
{
|
u16 pageremain;
|
pageremain=256-WriteAddr%256; //remaining space of page
|
if(NumByteToWrite<=pageremain)pageremain=NumByteToWrite;//no more than 256B
|
while(1)
|
{
|
Flash_Write_Page(pBuffer,WriteAddr,pageremain);
|
if(NumByteToWrite==pageremain)break; //write finish
|
else //NumByteToWrite>pageremain
|
{
|
pBuffer+=pageremain;
|
WriteAddr+=pageremain;
|
|
NumByteToWrite-=pageremain;
|
if(NumByteToWrite>256)pageremain=256; //write operation can't be finished in next page
|
else pageremain=NumByteToWrite; //write operation can be finished in next page
|
}
|
}
|
}
|
|
/******************************************
|
* func: Flash_Write_Page
|
* desc: write data less than 256 bytes into flash.(we must delete the precious data before write)
|
* input: pBuffer-data write into flash
|
ReadAddr-32bit input address,just send the front 24bit
|
NumByteToRead-decide how many bytes to write
|
* output: none
|
* return: none
|
*****************************************/
|
void Flash_Write_Page(u8* pBuffer,u32 WriteAddr,u16 NumByteToWrite)
|
{
|
u16 i;
|
FLASH_Write_Enable(); //write enable
|
FLASH_CS_LOW;
|
FLASH_ReadWriteByte(FLASH_WRITE); //send write command
|
FLASH_ReadWriteByte((u8)((WriteAddr)>>16)); //send 24bit address
|
FLASH_ReadWriteByte((u8)((WriteAddr)>>8));
|
FLASH_ReadWriteByte((u8)WriteAddr);
|
for(i=0;i<NumByteToWrite;i++)
|
FLASH_ReadWriteByte(pBuffer[i]);
|
FLASH_CS_HIGH;
|
Flash_Wait_Busy(); //wait write finish
|
}
|
|
|
/******************************************
|
* func: Flash_Erase_Chip
|
* desc: erase all data.
|
* input: none
|
* output: none
|
* return: none
|
*****************************************/
|
void Flash_Erase_Chip(void)
|
{
|
FLASH_Write_Enable();
|
Flash_Wait_Busy();
|
FLASH_CS_LOW;
|
FLASH_ReadWriteByte(FLASH_ChipErase); //send chip erase instruction
|
FLASH_CS_HIGH;
|
Flash_Wait_Busy(); //wait erase finish
|
}
|
|
|
/******************************************
|
* func: Flash_Erase_Sector
|
* desc: sector erase operation.
|
* input: Dst_Addr - sector address.
|
* output: none
|
* return: none
|
*****************************************/
|
void Flash_Erase_Sector(u32 Dst_Addr)
|
{
|
Dst_Addr*=4096;
|
FLASH_Write_Enable(); //write enable
|
Flash_Wait_Busy();
|
FLASH_CS_LOW;
|
FLASH_ReadWriteByte(FLASH_SectorErase); //send sector erase instruction
|
FLASH_ReadWriteByte((u8)((Dst_Addr)>>16));
|
FLASH_ReadWriteByte((u8)((Dst_Addr)>>8));
|
FLASH_ReadWriteByte((u8)Dst_Addr);
|
FLASH_CS_HIGH;
|
Flash_Wait_Busy();
|
}
|
|
|
/******************************************
|
* func: Flash_Wait_Busy
|
* desc: wait write or erase operation finish.
|
* input: none
|
* output: none
|
* return: none
|
*****************************************/
|
void Flash_Wait_Busy(void)
|
{
|
while ((Flash_ReadSR()&0x01)==0x01); //wait BUSY=0
|
}
|
|
|
/******************************************
|
* func: Flash_PowerDown
|
* desc: take flash into power-down mode.
|
* input: none
|
* output: none
|
* return: none
|
*****************************************/
|
void Flash_PowerDown(void)
|
{
|
FLASH_CS_LOW;
|
FLASH_ReadWriteByte(FLASH_POWERDOWN); //send power-down instruction
|
FLASH_CS_HIGH;
|
delay_us(3); //wait TPD
|
}
|
|
|
/******************************************
|
* func: Flash_WAKEUP
|
* desc: release flash from power-down mode.
|
* input: none
|
* output: none
|
* return: none
|
*****************************************/
|
void Flash_WAKEUP(void)
|
{
|
FLASH_CS_LOW;
|
FLASH_ReadWriteByte(FLASH_WKUP); //send wake up command 0xAB
|
FLASH_CS_HIGH;
|
delay_us(3); //wait TRES1
|
}
|