396 lines
12 KiB
C++
396 lines
12 KiB
C++
|
#include "w25qxx.h"
|
|||
|
uint16_t W25QXX_TYPE = 0XFFFF; //Ĭ<><C4AC><EFBFBD><EFBFBD>W25Q128
|
|||
|
|
|||
|
//4KbytesΪһ<CEAA><D2BB>Sector
|
|||
|
//16<31><36><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ϊ1<CEAA><31>Block
|
|||
|
//W25Q128
|
|||
|
//<2F><><EFBFBD><EFBFBD>Ϊ16M<36>ֽ<EFBFBD>,<2C><><EFBFBD><EFBFBD>256<35><36>Block,4096<39><36>Sector
|
|||
|
static void delayus(uint32_t nus){
|
|||
|
volatile uint32_t i;
|
|||
|
while (nus-- > 0){
|
|||
|
i = 26;
|
|||
|
while (i-- > 0);
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
void SPI1S_Init(void){
|
|||
|
// gpio init
|
|||
|
// pinMode(NORFLASH_HOLD_PIN, OUTPUT);
|
|||
|
// pinMode(NORFLASH_WP_PIN, OUTPUT);
|
|||
|
// digitalWrite(NORFLASH_HOLD_PIN, HIGH); //<2F><><EFBFBD><EFBFBD>
|
|||
|
// digitalWrite(NORFLASH_WP_PIN, HIGH); //д<><D0B4><EFBFBD><EFBFBD>
|
|||
|
#ifdef HARDWARE_SPI
|
|||
|
//ʹ<><CAB9>Ӳ<EFBFBD><D3B2>SPI
|
|||
|
SPI.begin(NORFLASH_CLK_PIN, NORFLASH_MISO_PIN, NORFLASH_MOSI_PIN, NORFLASH_CS_PIN);
|
|||
|
SPI.setDataMode(SPI_MODE0);
|
|||
|
SPI.setBitOrder(MSBFIRST);
|
|||
|
SPI.setFrequency(SPI_FREQUENCY);
|
|||
|
// SPI.setFrequency(1000000*20);
|
|||
|
pinMode(NORFLASH_CS_PIN, OUTPUT);
|
|||
|
#endif
|
|||
|
#ifdef SOFTWARE_SPI
|
|||
|
//ʹ<><CAB9><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ģ<EFBFBD><C4A3>SPI
|
|||
|
pinMode(NORFLASH_CLK_PIN, OUTPUT);
|
|||
|
pinMode(NORFLASH_MOSI_PIN, OUTPUT);
|
|||
|
pinMode(NORFLASH_MISO_PIN, INPUT);
|
|||
|
pinMode(NORFLASH_CS_PIN, OUTPUT);
|
|||
|
|
|||
|
digitalWrite(NORFLASH_CS_PIN,HIGH);
|
|||
|
digitalWrite(NORFLASH_CLK_PIN,LOW);
|
|||
|
delay(1);
|
|||
|
#endif
|
|||
|
#ifdef FLASH_TEST_ENABLE
|
|||
|
/* readwrite test */
|
|||
|
int g = 0;
|
|||
|
uint8_t str[1280];
|
|||
|
memset(str, 0, sizeof(str));
|
|||
|
unsigned int j = 0;
|
|||
|
for(int k=0; k < 5; k++)
|
|||
|
{
|
|||
|
for(int i = 0; i < 256; i++)
|
|||
|
{
|
|||
|
str[j] = i;
|
|||
|
j++;
|
|||
|
}
|
|||
|
}
|
|||
|
Serial.println("");
|
|||
|
Serial.println("-----write data-------");
|
|||
|
W25QXX_CS0;
|
|||
|
W25QXX_Erase_Sector(0x00);
|
|||
|
W25QXX_Write(str,0x10,256);
|
|||
|
memset(str, 0, sizeof(str));
|
|||
|
W25QXX_Read(str,0x00,512);
|
|||
|
W25QXX_CS1;
|
|||
|
Serial.println("str:");
|
|||
|
for(int k = 0; k < 512; k++) {
|
|||
|
if(g == 16){
|
|||
|
Serial.println("|");
|
|||
|
if(k % 256 == 0) Serial.println("---------------");
|
|||
|
{
|
|||
|
g = 1;
|
|||
|
}
|
|||
|
}
|
|||
|
else {
|
|||
|
g++;
|
|||
|
}
|
|||
|
Serial.printf("%02X ", str[k]);
|
|||
|
}
|
|||
|
#endif
|
|||
|
}
|
|||
|
|
|||
|
//SPI1 <20><>дһ<D0B4><D2BB><EFBFBD>ֽ<EFBFBD>
|
|||
|
//TxData:Ҫд<D2AA><D0B4><EFBFBD><EFBFBD><EFBFBD>ֽ<EFBFBD>
|
|||
|
//<2F><><EFBFBD><EFBFBD>ֵ:<3A><>ȡ<EFBFBD><C8A1><EFBFBD><EFBFBD><EFBFBD>ֽ<EFBFBD>
|
|||
|
uint8_t SPI1_ReadWriteByte(uint8_t TxData)
|
|||
|
{
|
|||
|
uint8_t Rxdata;
|
|||
|
#ifdef HARDWARE_SPI
|
|||
|
Rxdata = SPI.transfer(TxData);
|
|||
|
return Rxdata;
|
|||
|
#endif
|
|||
|
#ifdef SOFTWARE_SPI
|
|||
|
uint8_t i = 0, Rxdata = 0;
|
|||
|
for(i = 0; i < 8; i++)
|
|||
|
{
|
|||
|
digitalWrite(NORFLASH_CLK_PIN, HIGH);
|
|||
|
digitalWrite(NORFLASH_CLK_PIN, LOW);
|
|||
|
if(digitalRead(NORFLASH_MISO_PIN))
|
|||
|
{
|
|||
|
Rxdata |= 0x80 >> i;
|
|||
|
}
|
|||
|
}
|
|||
|
return Rxdata;
|
|||
|
#endif
|
|||
|
return Rxdata; //<2F><><EFBFBD><EFBFBD><EFBFBD>յ<EFBFBD><D5B5><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|||
|
}
|
|||
|
|
|||
|
//<2F><>ʼ<EFBFBD><CABC>SPI FLASH<53><48>IO<49><4F>
|
|||
|
void W25QXX_Init(void)
|
|||
|
{
|
|||
|
SPI1S_Init(); //<2F><>ʼ<EFBFBD><CABC>SPI
|
|||
|
W25QXX_TYPE = W25QXX_ReadID(); //<2F><>ȡFLASH ID.
|
|||
|
}
|
|||
|
|
|||
|
//<2F><>ȡW25QXX<58><58>״̬<D7B4>Ĵ<EFBFBD><C4B4><EFBFBD><EFBFBD><EFBFBD>W25QXXһ<58><D2BB><EFBFBD><EFBFBD>3<EFBFBD><33>״̬<D7B4>Ĵ<EFBFBD><C4B4><EFBFBD>
|
|||
|
//״̬<D7B4>Ĵ<EFBFBD><C4B4><EFBFBD>1<EFBFBD><31>
|
|||
|
//BIT7 6 5 4 3 2 1 0
|
|||
|
//SPR RV TB BP2 BP1 BP0 WEL BUSY
|
|||
|
//SPR:Ĭ<><C4AC>0,״̬<D7B4>Ĵ<EFBFBD><C4B4><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>λ,<2C><><EFBFBD><EFBFBD>WPʹ<50><CAB9>
|
|||
|
//TB,BP2,BP1,BP0:FLASH<53><48><EFBFBD><EFBFBD>д<EFBFBD><D0B4><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|||
|
//WEL:дʹ<D0B4><CAB9><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|||
|
//BUSY:æ<><C3A6><EFBFBD><EFBFBD>λ(1,æ;0,<2C><><EFBFBD><EFBFBD>)
|
|||
|
//Ĭ<><C4AC>:0x00
|
|||
|
//״̬<D7B4>Ĵ<EFBFBD><C4B4><EFBFBD>2<EFBFBD><32>
|
|||
|
//BIT7 6 5 4 3 2 1 0
|
|||
|
//SUS CMP LB3 LB2 LB1 (R) QE SRP1
|
|||
|
//״̬<D7B4>Ĵ<EFBFBD><C4B4><EFBFBD>3<EFBFBD><33>
|
|||
|
//BIT7 6 5 4 3 2 1 0
|
|||
|
//HOLD/RST DRV1 DRV0 (R) (R) WPS ADP ADS
|
|||
|
//regno:״̬<D7B4>Ĵ<EFBFBD><C4B4><EFBFBD><EFBFBD>ţ<EFBFBD><C5A3><EFBFBD>:1~3
|
|||
|
//<2F><><EFBFBD><EFBFBD>ֵ:״̬<D7B4>Ĵ<EFBFBD><C4B4><EFBFBD>ֵ
|
|||
|
uint8_t W25QXX_ReadSR(uint8_t regno)
|
|||
|
{
|
|||
|
uint8_t byte=0,command=0;
|
|||
|
switch(regno)
|
|||
|
{
|
|||
|
case 1:
|
|||
|
command = W25X_ReadStatusReg1; //<2F><>״̬<D7B4>Ĵ<EFBFBD><C4B4><EFBFBD>1ָ<31><D6B8>
|
|||
|
break;
|
|||
|
case 2:
|
|||
|
command = W25X_ReadStatusReg2; //<2F><>״̬<D7B4>Ĵ<EFBFBD><C4B4><EFBFBD>2ָ<32><D6B8>
|
|||
|
break;
|
|||
|
case 3:
|
|||
|
command = W25X_ReadStatusReg3; //<2F><>״̬<D7B4>Ĵ<EFBFBD><C4B4><EFBFBD>3ָ<33><D6B8>
|
|||
|
break;
|
|||
|
default:
|
|||
|
command = W25X_ReadStatusReg1;
|
|||
|
break;
|
|||
|
}
|
|||
|
W25QXX_CS0; //ʹ<><CAB9><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|||
|
SPI1_ReadWriteByte(command); //<2F><><EFBFBD>Ͷ<EFBFBD>ȡ״̬<D7B4>Ĵ<EFBFBD><C4B4><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|||
|
byte=SPI1_ReadWriteByte(0Xff); //<2F><>ȡһ<C8A1><D2BB><EFBFBD>ֽ<EFBFBD>
|
|||
|
W25QXX_CS1; //ȡ<><C8A1>Ƭѡ
|
|||
|
return byte;
|
|||
|
}
|
|||
|
//дW25QXX״̬<D7B4>Ĵ<EFBFBD><C4B4><EFBFBD>
|
|||
|
void W25QXX_Write_SR(uint8_t regno,uint8_t sr)
|
|||
|
{
|
|||
|
uint8_t command=0;
|
|||
|
switch(regno)
|
|||
|
{
|
|||
|
case 1:
|
|||
|
command=W25X_WriteStatusReg1; //д״̬<D7B4>Ĵ<EFBFBD><C4B4><EFBFBD>1ָ<31><D6B8>
|
|||
|
break;
|
|||
|
case 2:
|
|||
|
command=W25X_WriteStatusReg2; //д״̬<D7B4>Ĵ<EFBFBD><C4B4><EFBFBD>2ָ<32><D6B8>
|
|||
|
break;
|
|||
|
case 3:
|
|||
|
command=W25X_WriteStatusReg3; //д״̬<D7B4>Ĵ<EFBFBD><C4B4><EFBFBD>3ָ<33><D6B8>
|
|||
|
break;
|
|||
|
default:
|
|||
|
command=W25X_WriteStatusReg1;
|
|||
|
break;
|
|||
|
}
|
|||
|
W25QXX_CS0; //ʹ<><CAB9><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|||
|
SPI1_ReadWriteByte(command); //<2F><><EFBFBD><EFBFBD>дȡ״̬<D7B4>Ĵ<EFBFBD><C4B4><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|||
|
SPI1_ReadWriteByte(sr); //д<><D0B4>һ<EFBFBD><D2BB><EFBFBD>ֽ<EFBFBD>
|
|||
|
W25QXX_CS1; //ȡ<><C8A1>Ƭѡ
|
|||
|
}
|
|||
|
//W25QXXдʹ<D0B4><CAB9>
|
|||
|
//<2F><>WEL<45><4C>λ
|
|||
|
void W25QXX_Write_Enable(void)
|
|||
|
{
|
|||
|
W25QXX_CS0; //ʹ<><CAB9><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|||
|
SPI1_ReadWriteByte(W25X_WriteEnable); //<2F><><EFBFBD><EFBFBD>дʹ<D0B4><CAB9>
|
|||
|
W25QXX_CS1; //ȡ<><C8A1>Ƭѡ
|
|||
|
}
|
|||
|
//W25QXXд<58><D0B4>ֹ
|
|||
|
//<2F><>WEL<45><4C><EFBFBD><EFBFBD>
|
|||
|
void W25QXX_Write_Disable(void)
|
|||
|
{
|
|||
|
W25QXX_CS0; //ʹ<><CAB9><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|||
|
SPI1_ReadWriteByte(W25X_WriteDisable); //<2F><><EFBFBD><EFBFBD>д<EFBFBD><D0B4>ָֹ<D6B9><D6B8>
|
|||
|
W25QXX_CS1; //ȡ<><C8A1>Ƭѡ
|
|||
|
}
|
|||
|
|
|||
|
//<2F><>ȡоƬID
|
|||
|
//<2F><><EFBFBD><EFBFBD>ֵ<EFBFBD><D6B5><EFBFBD><EFBFBD>:
|
|||
|
//0XEF13,<2C><>ʾоƬ<D0BE>ͺ<EFBFBD>ΪW25Q80
|
|||
|
//0XEF14,<2C><>ʾоƬ<D0BE>ͺ<EFBFBD>ΪW25Q16
|
|||
|
//0XEF15,<2C><>ʾоƬ<D0BE>ͺ<EFBFBD>ΪW25Q32
|
|||
|
//0XEF16,<2C><>ʾоƬ<D0BE>ͺ<EFBFBD>ΪW25Q64
|
|||
|
//0XEF17,<2C><>ʾоƬ<D0BE>ͺ<EFBFBD>ΪW25Q128
|
|||
|
//0XEF18,<2C><>ʾоƬ<D0BE>ͺ<EFBFBD>ΪW25Q256
|
|||
|
uint16_t W25QXX_ReadID(void)
|
|||
|
{
|
|||
|
uint16_t Temp = 0;
|
|||
|
W25QXX_CS0;
|
|||
|
SPI1_ReadWriteByte(0x90);//<2F><><EFBFBD>Ͷ<EFBFBD>ȡID<49><44><EFBFBD><EFBFBD>
|
|||
|
SPI1_ReadWriteByte(0x00);
|
|||
|
SPI1_ReadWriteByte(0x00);
|
|||
|
SPI1_ReadWriteByte(0x00);
|
|||
|
Temp|=SPI1_ReadWriteByte(0xFF)<<8;
|
|||
|
Temp|=SPI1_ReadWriteByte(0xFF);
|
|||
|
W25QXX_CS1;
|
|||
|
return Temp;
|
|||
|
}
|
|||
|
//<2F><>ȡSPI FLASH
|
|||
|
//<2F><>ָ<EFBFBD><D6B8><EFBFBD><EFBFBD>ַ<EFBFBD><D6B7>ʼ<EFBFBD><CABC>ȡָ<C8A1><D6B8><EFBFBD><EFBFBD><EFBFBD>ȵ<EFBFBD><C8B5><EFBFBD><EFBFBD><EFBFBD>
|
|||
|
//pBuffer:<3A><><EFBFBD>ݴ洢<DDB4><E6B4A2>
|
|||
|
//ReadAddr:<3A><>ʼ<EFBFBD><CABC>ȡ<EFBFBD>ĵ<EFBFBD>ַ(24bit)
|
|||
|
//NumByteToRead:Ҫ<><D2AA>ȡ<EFBFBD><C8A1><EFBFBD>ֽ<EFBFBD><D6BD><EFBFBD>(<28><><EFBFBD><EFBFBD>65535)
|
|||
|
void W25QXX_Read(uint8_t* pBuffer,uint32_t ReadAddr,uint16_t NumByteToRead)
|
|||
|
{
|
|||
|
uint16_t i;
|
|||
|
W25QXX_CS0; //ʹ<><CAB9><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|||
|
SPI1_ReadWriteByte(W25X_ReadData); //<2F><><EFBFBD>Ͷ<EFBFBD>ȡ<EFBFBD><C8A1><EFBFBD><EFBFBD>
|
|||
|
if(W25QXX_TYPE==W25Q256) //<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>W25Q256<35>Ļ<EFBFBD><C4BB><EFBFBD>ַΪ4<CEAA>ֽڵģ<DAB5>Ҫ<EFBFBD><D2AA><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>8λ
|
|||
|
{
|
|||
|
SPI1_ReadWriteByte((uint8_t)((ReadAddr)>>24));
|
|||
|
}
|
|||
|
SPI1_ReadWriteByte((uint8_t)((ReadAddr)>>16)); //<2F><><EFBFBD><EFBFBD>24bit<69><74>ַ
|
|||
|
SPI1_ReadWriteByte((uint8_t)((ReadAddr)>>8));
|
|||
|
SPI1_ReadWriteByte((uint8_t)ReadAddr);
|
|||
|
for(i=0; i<NumByteToRead; i++)
|
|||
|
{
|
|||
|
pBuffer[i]=SPI1_ReadWriteByte(0XFF); //ѭ<><D1AD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|||
|
}
|
|||
|
W25QXX_CS1;
|
|||
|
}
|
|||
|
//SPI<50><49>һҳ(0~65535)<29><>д<EFBFBD><D0B4><EFBFBD><EFBFBD><EFBFBD><EFBFBD>256<35><36><EFBFBD>ֽڵ<D6BD><DAB5><EFBFBD><EFBFBD><EFBFBD>
|
|||
|
//<2F><>ָ<EFBFBD><D6B8><EFBFBD><EFBFBD>ַ<EFBFBD><D6B7>ʼд<CABC><D0B4><EFBFBD><EFBFBD><EFBFBD><EFBFBD>256<35>ֽڵ<D6BD><DAB5><EFBFBD><EFBFBD><EFBFBD>
|
|||
|
//pBuffer:<3A><><EFBFBD>ݴ洢<DDB4><E6B4A2>
|
|||
|
//WriteAddr:<3A><>ʼд<CABC><D0B4><EFBFBD>ĵ<EFBFBD>ַ(24bit)
|
|||
|
//NumByteToWrite:Ҫд<D2AA><D0B4><EFBFBD><EFBFBD><EFBFBD>ֽ<EFBFBD><D6BD><EFBFBD>(<28><><EFBFBD><EFBFBD>256),<2C><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ӧ<EFBFBD>ó<EFBFBD><C3B3><EFBFBD><EFBFBD><EFBFBD>ҳ<EFBFBD><D2B3>ʣ<EFBFBD><CAA3><EFBFBD>ֽ<EFBFBD><D6BD><EFBFBD>!!!
|
|||
|
void W25QXX_Write_Page(uint8_t* pBuffer,uint32_t WriteAddr,uint16_t NumByteToWrite)
|
|||
|
{
|
|||
|
uint16_t i;
|
|||
|
W25QXX_Write_Enable(); //SET WEL
|
|||
|
W25QXX_CS0; //ʹ<><CAB9><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|||
|
SPI1_ReadWriteByte(W25X_PageProgram); //<2F><><EFBFBD><EFBFBD>дҳ<D0B4><D2B3><EFBFBD><EFBFBD>
|
|||
|
if(W25QXX_TYPE==W25Q256) //<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>W25Q256<35>Ļ<EFBFBD><C4BB><EFBFBD>ַΪ4<CEAA>ֽڵģ<DAB5>Ҫ<EFBFBD><D2AA><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>8λ
|
|||
|
{
|
|||
|
SPI1_ReadWriteByte((uint8_t)((WriteAddr)>>24));
|
|||
|
}
|
|||
|
SPI1_ReadWriteByte((uint8_t)((WriteAddr)>>16)); //<2F><><EFBFBD><EFBFBD>24bit<69><74>ַ
|
|||
|
SPI1_ReadWriteByte((uint8_t)((WriteAddr)>>8));
|
|||
|
SPI1_ReadWriteByte((uint8_t)WriteAddr);
|
|||
|
for(i=0; i<NumByteToWrite; i++)SPI1_ReadWriteByte(pBuffer[i]); //ѭ<><D1AD>д<EFBFBD><D0B4>
|
|||
|
W25QXX_CS1; //ȡ<><C8A1>Ƭѡ
|
|||
|
W25QXX_Wait_Busy(); //<2F>ȴ<EFBFBD>д<EFBFBD><D0B4><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|||
|
}
|
|||
|
//<2F><EFBFBD><DEBC><EFBFBD>дSPI FLASH
|
|||
|
//<2F><><EFBFBD><EFBFBD>ȷ<EFBFBD><C8B7><EFBFBD><EFBFBD>д<EFBFBD>ĵ<EFBFBD>ַ<EFBFBD><D6B7>Χ<EFBFBD>ڵ<EFBFBD><DAB5><EFBFBD><EFBFBD><EFBFBD>ȫ<EFBFBD><C8AB>Ϊ0XFF,<2C><><EFBFBD><EFBFBD><EFBFBD>ڷ<EFBFBD>0XFF<46><46>д<EFBFBD><D0B4><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ݽ<EFBFBD>ʧ<EFBFBD><CAA7>!
|
|||
|
//<2F><><EFBFBD><EFBFBD><EFBFBD>Զ<EFBFBD><D4B6><EFBFBD>ҳ<EFBFBD><D2B3><EFBFBD><EFBFBD>
|
|||
|
//<2F><>ָ<EFBFBD><D6B8><EFBFBD><EFBFBD>ַ<EFBFBD><D6B7>ʼд<CABC><D0B4>ָ<EFBFBD><D6B8><EFBFBD><EFBFBD><EFBFBD>ȵ<EFBFBD><C8B5><EFBFBD><EFBFBD><EFBFBD>,<2C><><EFBFBD><EFBFBD>Ҫȷ<D2AA><C8B7><EFBFBD><EFBFBD>ַ<EFBFBD><D6B7>Խ<EFBFBD><D4BD>!
|
|||
|
//pBuffer:<3A><><EFBFBD>ݴ洢<DDB4><E6B4A2>
|
|||
|
//WriteAddr:<3A><>ʼд<CABC><D0B4><EFBFBD>ĵ<EFBFBD>ַ(24bit)
|
|||
|
//NumByteToWrite:Ҫд<D2AA><D0B4><EFBFBD><EFBFBD><EFBFBD>ֽ<EFBFBD><D6BD><EFBFBD>(<28><><EFBFBD><EFBFBD>65535)
|
|||
|
//CHECK OK
|
|||
|
void W25QXX_Write_NoCheck(uint8_t* pBuffer,uint32_t WriteAddr,uint16_t NumByteToWrite)
|
|||
|
{
|
|||
|
uint16_t pageremain;
|
|||
|
pageremain=256-WriteAddr%256; //<2F><>ҳʣ<D2B3><CAA3><EFBFBD><EFBFBD><EFBFBD>ֽ<EFBFBD><D6BD><EFBFBD>
|
|||
|
if(NumByteToWrite<=pageremain)pageremain=NumByteToWrite;//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>256<35><36><EFBFBD>ֽ<EFBFBD>
|
|||
|
while(1)
|
|||
|
{
|
|||
|
W25QXX_Write_Page(pBuffer,WriteAddr,pageremain);
|
|||
|
if(NumByteToWrite==pageremain)break;//д<><D0B4><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|||
|
else //NumByteToWrite>pageremain
|
|||
|
{
|
|||
|
pBuffer+=pageremain;
|
|||
|
WriteAddr+=pageremain;
|
|||
|
|
|||
|
NumByteToWrite-=pageremain; //<2F><>ȥ<EFBFBD>Ѿ<EFBFBD>д<EFBFBD><D0B4><EFBFBD>˵<EFBFBD><CBB5>ֽ<EFBFBD><D6BD><EFBFBD>
|
|||
|
if(NumByteToWrite>256)pageremain=256; //һ<>ο<EFBFBD><CEBF><EFBFBD>д<EFBFBD><D0B4>256<35><36><EFBFBD>ֽ<EFBFBD>
|
|||
|
else pageremain=NumByteToWrite; //<2F><><EFBFBD><EFBFBD>256<35><36><EFBFBD>ֽ<EFBFBD><D6BD><EFBFBD>
|
|||
|
}
|
|||
|
};
|
|||
|
}
|
|||
|
//дSPI FLASH
|
|||
|
//<2F><>ָ<EFBFBD><D6B8><EFBFBD><EFBFBD>ַ<EFBFBD><D6B7>ʼд<CABC><D0B4>ָ<EFBFBD><D6B8><EFBFBD><EFBFBD><EFBFBD>ȵ<EFBFBD><C8B5><EFBFBD><EFBFBD><EFBFBD>
|
|||
|
//<2F>ú<EFBFBD><C3BA><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>!
|
|||
|
//pBuffer:<3A><><EFBFBD>ݴ洢<DDB4><E6B4A2>
|
|||
|
//WriteAddr:<3A><>ʼд<CABC><D0B4><EFBFBD>ĵ<EFBFBD>ַ(24bit)
|
|||
|
//NumByteToWrite:Ҫд<D2AA><D0B4><EFBFBD><EFBFBD><EFBFBD>ֽ<EFBFBD><D6BD><EFBFBD>(<28><><EFBFBD><EFBFBD>65535)
|
|||
|
uint8_t W25QXX_BUFFER[4096];
|
|||
|
void W25QXX_Write(uint8_t* pBuffer,uint32_t WriteAddr,uint32_t NumByteToWrite)
|
|||
|
{
|
|||
|
uint32_t secpos;
|
|||
|
uint16_t secoff;
|
|||
|
uint16_t secremain;
|
|||
|
uint16_t i;
|
|||
|
uint8_t * W25QXX_BUF;
|
|||
|
W25QXX_BUF=W25QXX_BUFFER;
|
|||
|
secpos=WriteAddr/4096;//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ַ
|
|||
|
secoff=WriteAddr%4096;//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ڵ<EFBFBD>ƫ<EFBFBD><C6AB>
|
|||
|
secremain=4096-secoff;//<2F><><EFBFBD><EFBFBD>ʣ<EFBFBD><CAA3><EFBFBD>ռ<EFBFBD><D5BC><EFBFBD>С
|
|||
|
// printf("ad:%X,nb:%X\r\n",WriteAddr,NumByteToWrite);//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|||
|
if(NumByteToWrite <= secremain) secremain = NumByteToWrite; //<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʣ<EFBFBD><CAA3><EFBFBD>ռ<EFBFBD><D5BC><EFBFBD>С
|
|||
|
while(1)
|
|||
|
{
|
|||
|
W25QXX_Read(W25QXX_BUF,secpos*4096,4096);//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|||
|
for(i=0; i<secremain; i++) //У<><D0A3><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|||
|
{
|
|||
|
if(W25QXX_BUF[secoff+i]!=0XFF) break;//<2F><>Ҫ<EFBFBD><D2AA><EFBFBD><EFBFBD>
|
|||
|
}
|
|||
|
if(i<secremain)//<2F><>Ҫ<EFBFBD><D2AA><EFBFBD><EFBFBD>
|
|||
|
{
|
|||
|
W25QXX_Erase_Sector(secpos);//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|||
|
for(i=0; i<secremain; i++) //<2F><><EFBFBD><EFBFBD>
|
|||
|
{
|
|||
|
W25QXX_BUF[i+secoff]=pBuffer[i];
|
|||
|
}
|
|||
|
W25QXX_Write_NoCheck(W25QXX_BUF,secpos*4096,4096);//д<><D0B4><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|||
|
|
|||
|
}
|
|||
|
else W25QXX_Write_NoCheck(pBuffer,WriteAddr,secremain); //д<>Ѿ<EFBFBD><D1BE><EFBFBD><EFBFBD><EFBFBD><EFBFBD>˵<EFBFBD>,ֱ<><D6B1>д<EFBFBD><D0B4><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʣ<EFBFBD><CAA3><EFBFBD><EFBFBD><EFBFBD><EFBFBD>.
|
|||
|
if(NumByteToWrite==secremain) break;//д<><D0B4><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|||
|
else//д<><D0B4>δ<EFBFBD><CEB4><EFBFBD><EFBFBD>
|
|||
|
{
|
|||
|
secpos++;//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ַ<EFBFBD><D6B7>1
|
|||
|
secoff=0;//ƫ<><C6AB>λ<EFBFBD><CEBB>Ϊ0
|
|||
|
|
|||
|
pBuffer+=secremain; //ָ<><D6B8>ƫ<EFBFBD><C6AB>
|
|||
|
WriteAddr+=secremain;//д<><D0B4>ַƫ<D6B7><C6AB>
|
|||
|
NumByteToWrite-=secremain; //<2F>ֽ<EFBFBD><D6BD><EFBFBD><EFBFBD>ݼ<EFBFBD>
|
|||
|
if(NumByteToWrite>4096)secremain=4096; //<2F><>һ<EFBFBD><D2BB><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>д<EFBFBD><D0B4><EFBFBD><EFBFBD>
|
|||
|
else secremain=NumByteToWrite; //<2F><>һ<EFBFBD><D2BB><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>д<EFBFBD><D0B4><EFBFBD><EFBFBD>
|
|||
|
}
|
|||
|
};
|
|||
|
}
|
|||
|
//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>оƬ
|
|||
|
//<2F>ȴ<EFBFBD>ʱ<EFBFBD>䳬<EFBFBD><E4B3AC>...
|
|||
|
void W25QXX_Erase_Chip(void)
|
|||
|
{
|
|||
|
W25QXX_Write_Enable(); //SET WEL
|
|||
|
W25QXX_Wait_Busy();
|
|||
|
W25QXX_CS0; //ʹ<><CAB9><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|||
|
SPI1_ReadWriteByte(W25X_ChipErase); //<2F><><EFBFBD><EFBFBD>Ƭ<EFBFBD><C6AC><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|||
|
W25QXX_CS1; //ȡ<><C8A1>Ƭѡ
|
|||
|
W25QXX_Wait_Busy(); //<2F>ȴ<EFBFBD>оƬ<D0BE><C6AC><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|||
|
}
|
|||
|
//<2F><><EFBFBD><EFBFBD>һ<EFBFBD><D2BB><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|||
|
//Dst_Addr:<3A><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ַ <20><><EFBFBD><EFBFBD>ʵ<EFBFBD><CAB5><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|||
|
//<2F><><EFBFBD><EFBFBD>һ<EFBFBD><D2BB><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʱ<EFBFBD><CAB1>:150ms
|
|||
|
void W25QXX_Erase_Sector(uint32_t Dst_Addr)
|
|||
|
{
|
|||
|
//<2F><><EFBFBD><EFBFBD>falsh<73><68><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>,<2C><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|||
|
//printf("fe:%x\r\n",Dst_Addr);
|
|||
|
Dst_Addr*=4096;
|
|||
|
W25QXX_Write_Enable(); //SET WEL
|
|||
|
W25QXX_Wait_Busy();
|
|||
|
W25QXX_CS0; //ʹ<><CAB9><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|||
|
SPI1_ReadWriteByte(W25X_SectorErase); //<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ָ<EFBFBD><D6B8>
|
|||
|
if(W25QXX_TYPE==W25Q256) //<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>W25Q256<35>Ļ<EFBFBD><C4BB><EFBFBD>ַΪ4<CEAA>ֽڵģ<DAB5>Ҫ<EFBFBD><D2AA><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>8λ
|
|||
|
{
|
|||
|
SPI1_ReadWriteByte((uint8_t)((Dst_Addr)>>24));
|
|||
|
}
|
|||
|
SPI1_ReadWriteByte((uint8_t)((Dst_Addr)>>16)); //<2F><><EFBFBD><EFBFBD>24bit<69><74>ַ
|
|||
|
SPI1_ReadWriteByte((uint8_t)((Dst_Addr)>>8));
|
|||
|
SPI1_ReadWriteByte((uint8_t)Dst_Addr);
|
|||
|
W25QXX_CS1; //ȡ<><C8A1>Ƭѡ
|
|||
|
W25QXX_Wait_Busy(); //<2F>ȴ<EFBFBD><C8B4><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|||
|
}
|
|||
|
//<2F>ȴ<EFBFBD><C8B4><EFBFBD><EFBFBD><EFBFBD>
|
|||
|
void W25QXX_Wait_Busy(void)
|
|||
|
{
|
|||
|
while((W25QXX_ReadSR(1)&0x01)==0x01); // <20>ȴ<EFBFBD>BUSYλ<59><CEBB><EFBFBD><EFBFBD>
|
|||
|
}
|
|||
|
//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ģʽ
|
|||
|
void W25QXX_PowerDown(void)
|
|||
|
{
|
|||
|
W25QXX_CS0; //ʹ<><CAB9><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|||
|
SPI1_ReadWriteByte(W25X_PowerDown); //<2F><><EFBFBD>͵<EFBFBD><CDB5><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|||
|
W25QXX_CS1; //ȡ<><C8A1>Ƭѡ
|
|||
|
delayus(3); //<2F>ȴ<EFBFBD>TPD
|
|||
|
}
|
|||
|
//<2F><><EFBFBD><EFBFBD>
|
|||
|
void W25QXX_WAKEUP(void)
|
|||
|
{
|
|||
|
W25QXX_CS0; //ʹ<><CAB9><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|||
|
SPI1_ReadWriteByte(W25X_ReleasePowerDown); // send W25X_PowerDown command 0xAB
|
|||
|
W25QXX_CS1; //ȡ<><C8A1>Ƭѡ
|
|||
|
delayus(3); //<2F>ȴ<EFBFBD>TRES1
|
|||
|
}
|