#include "iospiflash.h"
/*******************************************
//
This was a IOSPI (Simulater by IO)
//
Lib for Driver Flash W25Q64BV
//
*******************************************/
Sbit ioflashspi_cs= p1^0;
Sbit Ioflashspi_din = p1^3;
Sbit ioflashspi_dout = p1^4;
Sbit ioflashspi_clk = p1^5;
/*******************************************
//
IOSPI Base FUNC
Data shifting at the--rising edge--of the CLK
CLK need a Hold Time Mydelay (3)
//
Shift
Write U8
Read U8
//
1
Time Series requires:
The w25q64b Flash support the Stantdard SPI, but the SPI Mode 0 or 3.
SPI Mode 0 required that:
When free:
The CLK need be low-0 and while The/cs is high (when free);
When the Execute an instruction:
Fall The/cs that Enable the Flash.
0-1-0-1 The CLK,
When the rasing edge of CLK, the DOUT (0,1) is send to the FLASH.
When a whole instruction completed.
Need to! Pull up the/cs than over an instruction.
SPI Mode 3 required that:
...../cs/clk the reverse.
2
Other IO need!
/hold---Like a enable pin.
When/hold is low,the FLASH and can not be excute any instructions.
//
*******************************************/
U8 Iospi_flash_shift (U8 Data)
{
U8 Dataread = 0xFF;
U8 i = 0;
for (i = 0; i < 8; i++)
{
IOFLASHSPI_CLK = 0; Fall Edge chage The out data bit
Ioflashspi_dout = ((Data & 0x80) = = 0x80)? 1:0;
Data <<= 1;
Dataread <<= 1;
Mydelay (5);
IOFLASHSPI_CLK = 1; Rising Edge
The rising edge out the data bit and the data bit
Mydelay (5);
if (ioflashspi_din==1)//get bit
Dataread + = 1;
}
return dataread;
}
Rising edge of CLK
//!!!!! The CLK should be keep 0,while there are not excuting any instructions!
void Iospi_flash_u8_write (U8 Data)
{
U8 i = 0;
for (i = 0; i < 8; i++)
{
IOFLASHSPI_CLK = 0;
Ioflashspi_dout = (Data & 0x80);
Data <<= 1;
Mydelay (5);
IOFLASHSPI_CLK = 1; Rising Edge
Mydelay (5);
}
IOFLASHSPI_CLK = 0;
}
U8 Iospi_flash_u8_read (void)
{
U8 Data = 0xFF;
U8 i = 0;
for (i = 0; i < 8; i++)
{
IOFLASHSPI_CLK = 0;
Data <<= 1;
Mydelay (5); Hold Time
IOFLASHSPI_CLK = 1; Rising Edge
Mydelay (5);
if (ioflashspi_din==1)//get bits
Data + = 1;
}
IOFLASHSPI_CLK = 0;
return Data;
}
//-----------------------------------
//
Iospi FLASH FUNC
//
//-----------------------------------
void Iospi_flash_cmd (U8 CMD)
{
Iospi_flash_u8_write (CMD);
}
U8 iospi_flash_rdsr (void)
{
U8 readstatus = 0;
Iospi_flash_cs_enable
Iospi_flash_cmd (CMD_RDSR);//time series need to be learn
Readstatus = Iospi_flash_u8_read ();
Iospi_flash_cs_disable//cs over the instruction
return readstatus;
}
U32 Iospi_flash_rdjcid ()
{
U8 i = 0;
U32 jcid = 0x00000000;
U8 *pdata = &JCID;
Iospi_flash_cs_enable
Iospi_flash_cmd (CMD_RDJCID);//time series need to be learn
for (i = 0; i < 3; i++)
{
* (pdata++) = Iospi_flash_u8_read ();
}
Iospi_flash_cs_disable//cs over the instruction
return jcid;
}
void Iospi_flash_waitfree (void)
{
while ((IOSPI_FLASH_RDSR () & 0x01) ==0x01)//check the busy = 0;
{
Mydelay (30);
}
}
//---------------------------------------------------------
//
4K byte Erase pages
//
//---------------------------------------------------------
void Iospi_flash_sectorerase (U32 Addr)
{
u8* paddr = &Addr;
Iospi_flash_waitfree ();
Iospi_flash_cs_enable
Iospi_flash_cmd (Cmd_enablewrite);
Iospi_flash_cs_disable
Mydelay (5);
Iospi_flash_cs_enable
Iospi_flash_cmd (cmd_secerase);
Iospi_flash_u8_write (*paddr++);
Iospi_flash_u8_write (*paddr++);
Iospi_flash_u8_write (*PADDR);
Iospi_flash_cs_disable
}
void Iospi_flash_blockerase (u8* Addr);
//-----------------------------------------------------------------
//
Page programe
The data to is programe must less than 256bytes,
Otherwise the page would be a wrap by the bytes lengther than the bytes;
//
//-----------------------------------------------------------------
void Iospi_flash_write (U32 Addr, char* Data, U16 length)
{
U16 i = 0;
U8 PData = 0x00;
u8* paddr = &Addr;
if (length > 256)
return;
Iospi_flash_waitfree ();
Iospi_flash_cs_enable
Iospi_flash_cmd (Cmd_enablewrite);
Iospi_flash_cs_disable
Mydelay (5);
Iospi_flash_cs_enable
Iospi_flash_cmd (Cmd_pagewrite);
Iospi_flash_u8_write (*paddr++);
Iospi_flash_u8_write (*paddr++);
Iospi_flash_u8_write (*PADDR);
for (i = 0; i < length; i++)
{
Iospi_flash_u8_write (* (data+i));
}
Iospi_flash_cs_disable
}
//-----------------------------------------------------
//
Standard Flash Read.
Can Read bytes Once at the most.
//
//-----------------------------------------------------
void Iospi_flash_read (U32 Addr, char* Data, U16 length)
{
U16 i = 0;
u8* paddr = &Addr;
Iospi_flash_waitfree ();
Iospi_flash_cs_enable
Iospi_flash_cmd (Cmd_read);
Iospi_flash_u8_write (*paddr++);
Iospi_flash_u8_write (*paddr++);
Iospi_flash_u8_write (*PADDR);
for (i = 0; i < length; i++)
{
* (data+i) = Iospi_flash_u8_read ();
}
Iospi_flash_cs_disable
}
void Iospi_flash_fastread (U32 Addr, char* Data, U16 length)
{
U16 i = 0;
u8* paddr = &Addr;
if (length > 256)
return;
Iospi_flash_waitfree ();
Iospi_flash_cs_enable
Iospi_flash_cmd (Cmd_fastread);
Iospi_flash_u8_write (*paddr++);
Iospi_flash_u8_write (*paddr++);
Iospi_flash_u8_write (*PADDR);
Iospi_flash_u8_write (0x00);
for (i = 0; i < length; i++)
{
* (data+i) = Iospi_flash_u8_read ();
}
Iospi_flash_cs_disable
}
===========================================================================================================
===========================================================================================================
===========================================================================================================
#ifndef __iospiflash_h
#define __iospiflash_h
#include "Common.h"
/**************************************************************
//
W25q64bvsfig FLASH
//
//
*************************************************************/
#define CMD_RDSR0X05
#define CMD_ENABLEWRITE0X06
#define CMD_DISABLEWRITE0X04
#define CMD_WDSR0X01
#define CMD_READ0X03
#define CMD_FASTREAD0X0B
#define CMD_PAGEWRITE0X02
#define Cmd_secerase0x20
#define CMD_BLOCKERASE0X52
#define CMD_RDJCID0X9F
#define Iospi_flash_cs_enable {ioflashspi_cs = 0;}
#define IOSPI_FLASH_CS_DISABLE{IOFLASHSPI_CS = 1;}
U8 Iospi_flash_shift (U8 Data);
void Iospi_flash_u8_write (U8 Data);
U8 iospi_flash_u8_read (void);
void Iospi_flash_cmd (U8 CMD);
U8 iospi_flash_rdsr (void);
void Iospi_flash_waitfree (void);
void Iospi_flash_sectorerase (U32 Addr);
void Iospi_flash_blockerase (U2 Addr);
void Iospi_flash_write (U32 Addr, char* Data, U16 length);
void Iospi_flash_read (U32 Addr, char* Data, U16 length);
void Iospi_flash_fastread (U32 Addr, char* Data, U16 length);
U32 iospi_flash_rdjcid (void);
#endif
IO SPI flash w25q64b io analog SPI timing, using FLASH peripherals! w25q64b