uint8_t W25QXX_Buf[4096];
GPIO设置
/*SPI pin set*/
PinCfg.Funcnum = PINSEL_FUNC_3;
PinCfg.Portnum = 0;
PinCfg.Pinmode = PINSEL_PINMODE_TRISTATE;
PinCfg.Pinnum = SPI_SCK;
PINSEL_ConfigPin(&PinCfg);
PinCfg.Pinnum = SPI_MOSI;
PINSEL_ConfigPin(&PinCfg);
PinCfg.Pinnum = SPI_MISO;
PINSEL_ConfigPin(&PinCfg);
PinCfg.Funcnum = PINSEL_FUNC_0;
PinCfg.Portnum = 0;
PinCfg.OpenDrain = PINSEL_PINMODE_NORMAL;
PinCfg.Pinnum = SPI_CS;
PINSEL_ConfigPin(&PinCfg);
GPIO_SetDir(0, (1<<SPI_CS), 1);
GPIO_SetValue(0, (1<<SPI_CS));
void Spi_Initial(void)
{
SPI_CFG_Type spi0;
spi0.CPHA = SPI_CPHA_FIRST;
spi0.CPOL = SPI_CPOL_LO;
spi0.ClockRate = 3125000; //spi_clk = 25000000,25000000/8=3125000,能使用的最高频率
spi0.DataOrder = SPI_DATA_MSB_FIRST;
spi0.Databit = SPI_DATABIT_8;
spi0.Mode = SPI_MASTER_MODE;
SPI_Init(LPC_SPI,&spi0);
}
uint8_t SPIF_POLLING(void)
{
uint8_t n = 0xff;
while (n–)
{
if (LPC_SPI->SPSR & 0x80)
return TRUE;
}
return FALSE;
}
uint8_t SPI_WriteByte(uint8_t TxData)
{
LPC_SPI->SPDR = TxData;
if (!SPIF_POLLING())
return FALSE;
return TRUE;
}
void SPI_ReadByte(uint8_t* rxdata)
{
*rxdata = LPC_SPI->SPDR;
}
uint8_t W25QXX_ReadID(uint16_t* id)
{
uint16_t temp = 0;
uint8_t sta;
uint8_t rxdata;
LPC_GPIO0->FIOCLR=(1<<SPI_CS);
sta = SPI_WriteByte(0x90);
if(sta == FALSE)
{
LPC_GPIO0->FIOSET=(1<<SPI_CS);
return FALSE;
}
sta = SPI_WriteByte(0x00);
if(sta == FALSE)
{
LPC_GPIO0->FIOSET=(1<<SPI_CS);
return FALSE;
}
sta = SPI_WriteByte(0x00);
if(sta == FALSE)
{
LPC_GPIO0->FIOSET=(1<<SPI_CS);
return FALSE;
}
sta = SPI_WriteByte(0x00);
if(sta == FALSE)
{
LPC_GPIO0->FIOSET=(1<<SPI_CS);
return FALSE;
}
sta = SPI_WriteByte(0xff);
if(sta == FALSE)
{
LPC_GPIO0->FIOSET=(1<<SPI_CS);
return FALSE;
}
SPI_ReadByte(&rxdata);
*id = rxdata;
*id <<= 8;
sta = SPI_WriteByte(0xff);
if(sta == FALSE)
{
LPC_GPIO0->FIOSET=(1<<SPI_CS);
return FALSE;
}
SPI_ReadByte(&rxdata);
*id |= rxdata;
LPC_GPIO0->FIOSET=(1<<SPI_CS);
return TRUE;
}
uint8_t W25QXX_Write_Enable(void)
{
uint8_t sta;
LPC_GPIO0->FIOCLR=(1<<SPI_CS);
sta = SPI_WriteByte(0x06);
if(sta == FALSE)
{
LPC_GPIO0->FIOSET=(1<<SPI_CS);
return FALSE;
}
LPC_GPIO0->FIOSET=(1<<SPI_CS);
return TRUE;
}
uint8_t W25QXX_Wait_Busy(void)
{
uint8_t sta;
uint8_t rxdata;
uint16_t cnt=0;
do
{
LPC_GPIO0->FIOCLR=(1<<SPI_CS);
sta = SPI_WriteByte(0x05);
if(sta == FALSE)
{
LPC_GPIO0->FIOSET=(1<<SPI_CS);
return FALSE;
}
sta = SPI_WriteByte(0xFF);
if(sta == FALSE)
{
LPC_GPIO0->FIOSET=(1<<SPI_CS);
return FALSE;
}
SPI_ReadByte(&rxdata);
LPC_GPIO0->FIOSET=(1<<SPI_CS);
cnt++;
}while((rxdata & 0x01) && (cnt < 0x8fff));
if(cnt >= 0x8fff)
return FALSE;
else
return TRUE;
}
uint8_t W25QXX_Erase_Sector(uint32_t SectorAddr)
{
uint8_t sta;
/* sta = W25QXX_Wait_Busy();
if(sta == FALSE)
return FALSE;*/
SectorAddr *= 4096;
sta = W25QXX_Write_Enable();
if(sta == FALSE)
{
LPC_GPIO0->FIOSET=(1<<SPI_CS);
return FALSE;
}
LPC_GPIO0->FIOCLR=(1<<SPI_CS);
sta = SPI_WriteByte(0x20);
if(sta == FALSE)
{
LPC_GPIO0->FIOSET=(1<<SPI_CS);
return FALSE;
}
sta = SPI_WriteByte((uint8_t)(SectorAddr>>16));
if(sta == FALSE)
{
LPC_GPIO0->FIOSET=(1<<SPI_CS);
return FALSE;
}
sta = SPI_WriteByte((uint8_t)(SectorAddr>>8));
if(sta == FALSE)
{
LPC_GPIO0->FIOSET=(1<<SPI_CS);
return FALSE;
}
sta = SPI_WriteByte((uint8_t)SectorAddr);
if(sta == FALSE)
{
LPC_GPIO0->FIOSET=(1<<SPI_CS);
return FALSE;
}
LPC_GPIO0->FIOSET=(1<<SPI_CS);
sta = W25QXX_Wait_Busy();
return sta;
}
uint8_t W25QXX_Read(uint8_t* pBuffer,uint32_t ReadAddr,uint16_t NumByteToRead)
{
uint16_t i;
uint8_t sta;
LPC_GPIO0->FIOCLR=(1<<SPI_CS);
sta = SPI_WriteByte(0x03);
if(sta == FALSE)
{
LPC_GPIO0->FIOSET=(1<<SPI_CS);
return FALSE;
}
sta = SPI_WriteByte((uint8_t)((ReadAddr)>>16));
if(sta == FALSE)
{
LPC_GPIO0->FIOSET=(1<<SPI_CS);
return FALSE;
}
sta = SPI_WriteByte((uint8_t)((ReadAddr)>>8));
if(sta == FALSE)
{
LPC_GPIO0->FIOSET=(1<<SPI_CS);
return FALSE;
}
sta = SPI_WriteByte((uint8_t)ReadAddr);
if(sta == FALSE)
{
LPC_GPIO0->FIOSET=(1<<SPI_CS);
return FALSE;
}
for(i=0;i<NumByteToRead;i++)
{
sta = SPI_WriteByte(0xFF);
if(sta == FALSE)
{
LPC_GPIO0->FIOSET=(1<<SPI_CS);
return FALSE;
}
SPI_ReadByte(&pBuffer[i]);
}
LPC_GPIO0->FIOSET=(1<<SPI_CS);
return TRUE;
}
uint8_t W25QXX_Write_Page(uint8_t* pBuffer,uint32_t WriteAddr,uint16_t NumByteToWrite)
{
uint16_t i;
uint8_t sta;
/* sta = W25QXX_Wait_Busy();
if(sta == FALSE)
return FALSE;*/
sta = W25QXX_Write_Enable();
if(sta == FALSE)
return FALSE;
LPC_GPIO0->FIOCLR=(1<<SPI_CS);
sta = SPI_WriteByte(0x02);
if(sta == FALSE)
{
LPC_GPIO0->FIOSET=(1<<SPI_CS);
return FALSE;
}
sta = SPI_WriteByte((uint8_t)((WriteAddr)>>16));
if(sta == FALSE)
{
LPC_GPIO0->FIOSET=(1<<SPI_CS);
return FALSE;
}
sta = SPI_WriteByte((uint8_t)((WriteAddr)>>8));
if(sta == FALSE)
{
LPC_GPIO0->FIOSET=(1<<SPI_CS);
return FALSE;
}
sta = SPI_WriteByte((uint8_t)WriteAddr);
if(sta == FALSE)
{
LPC_GPIO0->FIOSET=(1<<SPI_CS);
return FALSE;
}
for(i=0;i<NumByteToWrite;i++)
{
sta = SPI_WriteByte(pBuffer[i]);
if(sta == FALSE)
{
LPC_GPIO0->FIOSET=(1<<SPI_CS);
return FALSE;
}
}
LPC_GPIO0->FIOSET=(1<<SPI_CS);
sta = W25QXX_Wait_Busy();
return sta;
}
uint8_t W25QXX_Write_NoCheck(uint8_t* pBuffer,uint32_t WriteAddr,uint16_t NumByteToWrite)
{
uint16_t pageremain;
uint8_t sta;
pageremain=256-WriteAddr%256;
if(NumByteToWrite<=pageremain)pageremain=NumByteToWrite;
while(1)
{
sta = W25QXX_Write_Page(pBuffer,WriteAddr,pageremain);
if(sta == FALSE)
return FALSE;
if(NumByteToWrite==pageremain)break;
else
{
pBuffer+=pageremain;
WriteAddr+=pageremain;
NumByteToWrite-=pageremain;
if(NumByteToWrite>256)pageremain=256;
else pageremain=NumByteToWrite;
}
}
return TRUE;
}
uint8_t W25QXX_Write(uint8_t* pBuffer,uint32_t WriteAddr,uint16_t NumByteToWrite)
{
uint32_t secpos;
uint16_t secoff;
uint16_t secremain;
uint16_t i;
uint8_t * W25QXX_BUF;
uint8_t sta;
W25QXX_BUF=W25QXX_Buf;
secpos=WriteAddr/4096;
secoff=WriteAddr%4096;
secremain=4096-secoff;
if(NumByteToWrite<=secremain)secremain=NumByteToWrite;
while(1)
{
sta = W25QXX_Read(W25QXX_BUF,secpos*4096,4096);
if(sta == FALSE)
return FALSE;
for(i=0;i<secremain;i++)//
{
if(W25QXX_BUF[secoff+i]!=0XFF)break;
}
if(i<secremain)
{
sta = W25QXX_Erase_Sector(secpos);
if(sta == FALSE)
return FALSE;
for(i=0;i<secremain;i++)
{
W25QXX_BUF[i+secoff]=pBuffer[i];
}
sta = W25QXX_Write_NoCheck(W25QXX_BUF,secpos*4096,4096);
if(sta == FALSE)
return FALSE;
}
else
{
sta = W25QXX_Write_NoCheck(pBuffer,WriteAddr,secremain);
if(sta == FALSE)
return FALSE;
}
if(NumByteToWrite==secremain)
break;
else
{
secpos++;
secoff=0;
pBuffer+=secremain;
WriteAddr+=secremain;
NumByteToWrite-=secremain;
if(NumByteToWrite>4096)secremain=4096;
else secremain=NumByteToWrite;
}
}
return TRUE;
}