#ifndef __FLASH_H
#define __FLASH_H

#include "type.h"

// Flash ID
#define ID_W25Q32						(0xEF15)
#define ID_W25Q64						(0xEF16)
#define ID_W25Q128					(0xEF17)
#define ID_W25Q256					(0xEF18)
#define ID_OTHERBRAND				(0x5E4018L)

#define ID_W25N01GV					(0xEFAA21L)
#define ID_W25N02KV					(0xEFAA22L)
#define ID_W25N04KV					(0xEFAA23L)

// Flash type
#define NOR_FLASH						0
#define NOR_FLASH_W25Q256			1
#define NAND_FLASH					2


#define NORFLASH_PAGESIZE			(256)
#define NORFLASH_SECTORSIZE		(0x1000)
#define NORFLASH_BLCOKSIZE			(0x10000L)

#define NANDFLASH_PAGESIZE			(2048)
#define NANDFLASH_BLOCKSIZE		(0x20000L)


/************************** winbond NorFlash command **********************/
#define W25X_WRITEENABLE			0x06
#define W25X_WRITEDISABLE			0x04
#define W25X_RERADSTATUSREG		0x05
#define W25X_RERADSTATUSREG1		0x15
#define W25X_RERADSTATUSREG2		0x35
#define W25X_WRITESTATUSREG		0x01
#define W25X_WRITESTATUSREG3		0x11
#define W25X_WRITESTATUSREG2		0x31
#define W25X_READDATA				0x03
#define W25X_FASTREADDATA			0x0B
#define W25X_FASTREADDUAL			0x3B
#define W25X_PAGEPROGRAM			0x02
#define W25X_SECTORERASE			0x20
#define W25X_CHIPERASE				0xC7
#define W25X_BLOCKERASE				0xD8
#define W25X_HALFBLOCKERASE		0x52
#define W25X_ENTER4BYTEADDRMODE	0xB7
#define W25X_EXIT4BYTEADDRMODE  	0xE9
#define W25X_POWERDOWN				0xB9
#define W25X_RELEASEPOWERDOWN		0xAB
#define W25X_FASTREADDUALIO		0xBB
#define W25X_MANUFACTUREDEVICEID	0x90
#define W25X_JEDECID					0x9F
#define W25X_DEVICEID				0xAB

#define W25X_WRITEENABLE_VSR		0x50

/************************* winbond NANDFlash command ***********************/
//指令表
#define W25N_DEVICERESET						0xFF
#define W25N_READJEDECID						0x9F
#define W25N_READSTATUSREG						0x05 
#define W25N_READSTATUSREG1					0x0F 
#define W25N_WRITESTATUSREG					0x01 
#define W25N_WRITESTATUSREG1					0x1F 
#define W25N_WRITEENABLE						0x06
#define W25N_WRITEDISABLE						0x04 
#define W25N_BADBLOCKMANAGEMENT				0xA1 
#define W25N_READBBMLOOKUPTABLE				0xA5 
#define W25N_LASTFAILUREPAGEADDRESS 		0xA9 
#define W25N_BLOCKERASE							0xD8
#define W25N_READPROGRAMDATA					0x02 
#define W25N_RANDOMREADPROGRAMDATA			0x84
#define W25N_READPROGRAMDATA_QUAD			0x32 
#define W25N_RANDOMREADPROGRAMDATA_QUAD	0x34
#define W25N_PROGRAMEXECUTE					0x10
#define W25N_READPAGEDATA						0x13 
#define W25N_READDATA							0x03
#define W25N_FASTREAD							0x0B
#define W25N_FASTREAD_4BYTEADDR				0x0C
#define W25N_FASTREAD_DUAL						0x3B
#define W25N_FASTREAD_DUAL_4BYTEADDR		0x3C
#define W25N_FASTREAD_QUAD						0x6B
#define W25N_FASTREAD_QUAD_4BYTEADDR		0x6C
#define W25N_FASTREAD_DUALIO					0xBB
#define W25N_FASTREAD_DUALIO_4BYTEADDR		0xBC
#define W25N_FASTREAD_QUADIO					0xEB
#define W25N_FASTREAD_QUADIO_4BYTEADDR		0xEC

#define W25N_STATUSREGISTE		  				0xA0  
#define W25N_STATUSREGISTE1  					0xB0
#define W25N_STATUSREGISTE2					0xC0

/*************************** MCU SPI interface***************************/

extern u8 Flash_Type;  	//用于判断 是NorFlash(0) 或者 NANDFlash(1)
extern u16 BlockQty;		// Minimum block size
extern u32 Flash_ID;


void SPI1_Clock(u8 prescale);
void FlashPort_Init(void);
void FlashPort_Close(void);

/*************************** winbond NorFlash ***************************/
u32 NORFlash_ReadID(void);
u32 NORFlash_ReadID_9F(void);
u8 Flash_ReadID(void);
void NORFlash_Enter4ByteAddressMode(void);
//-----------------------------------------

/*擦除*/
void NORFlash_EraseChip(void);
void NORFlash_EraseSector(u32 addr);
void NORFlash_EraseBlock(u32 addr);
//-----------------------------------------

//连续读写
u8 NORFlash_ReadByte(u32 addr);
u16 NORFlash_ReadHWord(u32 addr);
u32 NORFlash_ReadWord(u32 addr);
void NORFlash_ReadBytes(u32 addr,u8* buffer,u16 length);


/*读写操作*/
//单页读写
void NORFlash_WriteByte(u32 addr,u8 data);
void NORFlash_WriteHWord(u32 addr,u16 data);
void NORFlash_WriteWord(u32 addr,u32 data);
void NORFlash_WriteBytes(u32 addr,u8 *buffer,u16 length);
bool NORFlash_WritePages(u32 addr,u8* buffer,u16 length, bool check);

//-----------------------------------------


/*************************** winbond NandFlash **************************/

/*读取器件ID*/
u32 NANDFlash_ReadID(void);
//-----------------------------------------  			

/*擦除*/
void NANDFlash_EraseBlock(u16 block);
void NANDFlash_EraseChip(void);
//-----------------------------------------
u8 NANDFlash_ReadByte(u32 addr);
u16 NANDFlash_ReadHWord(u32 addr);
u32 NANDFlash_ReadWord(u32 addr);
void NANDFlash_ReadBytes(u32 addr,u8* buffer,u16 length);
void NANDFlash_ReadPages(u32 pageBegionAddr,u8* buffer,u16 length);

void NANDFlash_WriteByte(u32 addr,u8 data);
void NANDFlash_WriteHWord(u32 addr,u16 data);
void NANDFlash_WriteWord(u32 addr,u32 data);
void NANDFlash_WriteBytes(u32 addr,u8* buffer,u16 length);
//不能写入超过2048 Byte（一页2048个Byte，后面的64 Byte非数据位）
// length should less than 2048 byte (page) 
bool NANDFlash_WritePages(u32 addr,u8* buffer,u16 length, bool check);
 

typedef struct 
{
	u16  LBA ;       //坏块地址
	u16  PBA ;		  //替换地址
}BBM;
void NANDFlash_Read_BBM_LUT(BBM * L );
u8 NANDFlash_Bad_Block_Replace(u16 LBA,u16 PBA);


#endif

