
#include "norflash.h"

#include "trigger.h"
#include "shell.h"
#include "delay.h"

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

// 常量定义
//----------------------------------------------

// serial Norflash 配置命令 (标准/双路/四路SPI指令)，基本指令，

//											// 实现
#define	SNF_WT_ENABLE			0x06		// *		// 写使能
#define	SNF_VSR_WR_ENABLE		0x50		// 			// 易失存储器SR写使能
#define	SNF_WT_DISABLE			0x04		// *		// 写保护

#define	SNF_RD_STREG1			0x05		// *		// 读状态寄存器1(S7--S0)
#define	SNF_RD_STREG2			0x35		// *		// 读状态寄存器2(S15--S8)
#define	SNF_WT_STREG12			0x01		// *		// 写状态寄存器1和2(S7--S0  S15--S8)

#define SNF_READ_DATA			0x03		// *		// 读数据  (3字节地址+至少1字节数据)
#define	SNF_FAST_READ			0x0B		// *		// 读数据[快速读指令] (3字节地址+1字节虚字+至少1字节数据)

#define	SNF_PAGE_PROGRAM		0x02		// *		// 页写数据[最多可以写128个字(256个字节)数据,且不可以跨页] （3个字节的地址+2字节数据个数）
#define	SNF_4K_ERASE			0x20		// *		// 扇区擦除(4KB) (3字节地址)
#define	SNF_32K_ERASE			0x52		// *		// 块擦除(32KB) (3字节地址)
#define	SNF_64K_ERASE			0xD8		// *		// 块擦除(64KB) (3字节地址)


#define	SNF_CHIP_ERASE			0xC7		// *		// 片擦除 或 0x60


#define	SNF_EP_SUSPEND			0x75		//			// 擦除或写入挂起
#define	SNF_EP_RESUME			0x7A		//			// 擦除或写入恢复(从挂起中）
#define	SNF_POWER_DOWN			0xB9		//			// 掉电

#define SNF_WKUP_DEVICE_ID		0xAB		//			// 上电和读取设备ID (3字节虚字+1字节设备ID)
#define	SNF_MANU_DEVICE_ID		0x90		// *		// 读取制造商ID和设备ID (2字节虚字+00H+1字节制造ID+1字节设备ID)
#define	SNF_JEDEC_ID			0x9F		// *		// 芯片 JEDEC ID （固态技术协会）(1字节制造ID+2字节设备ID(存储器类型+存储器容量))
#define SNF_UNIQUE_ID			0x4B		// *		// 独特ID (4字节虚字+8字节UID)
#define	SNF_RD_SFDP				0x5A		//			// 读SFDP寄存器(3字节地址+1字节虚字+至少1字节数据)

#define	SNF_ERASE_SECURITY		0x44		//			// 擦除 保密 寄存器(3字节地址) 三组保密寄存器地址  0x0010xx 0x0020xx  0x0030xx
#define	SNF_PROGRAM_SECURITY	0x42		//			// 编程 保密 寄存器(3字节地址+至少1字节数据)
#define	SNF_READ_SECURITY		0x48		//			// 读取 保密 寄存器(3字节地址+至少1字节数据)

#define	SNF_RESET_DEVICE		0x66		//			// 允许复位
#define	SNF_ENABLE_RESET		0x99		//			// 复位芯片

/*
#define	SNF_BLOCK_LOCK			0x7E		//			// 全部锁定
#define	SNF_BLOCK_UNLOCK		0x98		//			// 全部解锁
#define	SNF_ENTER_QPI			0x38		//			// 进入QPI模式

#define	SNF_INDV_BLOCK_LOCK		0x36		//			// 单独锁定
#define	SNF_INDV_BLOCK_UNLOCK	0x39		//			// 单独解锁
#define	SNF_READ_BLOCK_LOCK		0x3D		//			// 读取锁定
*/

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

#define DUMMY_BYTE          0xFF

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

int SNFWaitNotBusyMs(u32 timeout);
int SNFWaitNotBusy10Us(u32 timeout);

u8 SNFReadStatusReg1(void);
u8 SNFReadStatusReg2(void);
void SNFWriteStatusReg1And2(u8 reg1, u8 reg2);

void ShowSNFInfo(void);
void SNFlashTest(char * para1, char * para2);	// NorFlash 测试

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

typedef struct
{
	int inited;
	// SPI 读写函数
	void (*spicson)(void);
	void (*spicsoff)(void);
	u8 	 (*spird)(void);
	void (*spiwr)(u8 wb);

}SNFCtrl;

SNFCtrl g_snfCtrl;

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

// NorFlash 初始化
int SNFlashInit(void (*spicson)(void), void (*spicsoff)(void), u8 (*spird)(void), void (*spiwr)(u8 wb))
{
	memset(&g_snfCtrl, 0, sizeof(SNFCtrl));

	g_snfCtrl.spicson = spicson;
	g_snfCtrl.spicsoff = spicsoff;
	g_snfCtrl.spird = spird;
	g_snfCtrl.spiwr = spiwr;

	if (g_snfCtrl.spicson == NULL ||
		g_snfCtrl.spicsoff == NULL ||
		g_snfCtrl.spird == NULL ||
		g_snfCtrl.spiwr == NULL ||
		0	)
	{
		printf("SNFlashInit para error\r\n");
		return -1;
	}

	g_snfCtrl.inited = 1;

	SNFWirteEnable();

	SNFWriteStatusReg1And2(0, 0);

	SNFWaitNotBusyMs(100);

	SNFWirteDisable();

#if (0)
	ShowSNFInfo();
	AddShellCmd("NORFLASH", "test nor flash", SNFlashTest);
#endif

	return 0;
}

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

// 写使能开
// 设置状态寄存器中得WEL 位 为1
// 必须在执行 擦除，编程写状态寄存器等指令之前将WEL位置1
void SNFWirteEnable(void)
{
	if (g_snfCtrl.inited == 0)
	{
		return;
	}
	g_snfCtrl.spicson();

	g_snfCtrl.spiwr(SNF_WT_ENABLE);

	g_snfCtrl.spicsoff();
}

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

// 写使能关（可关闭非易失寄存器的写使能）
// 设置状态寄存器中得WEL 位 为0
// 必须在执行 擦除，编程写状态寄存器等指令之前将WEL位置1
void SNFWirteDisable(void)
{
	if (g_snfCtrl.inited == 0)
	{
		return;
	}
	g_snfCtrl.spicson();

	g_snfCtrl.spiwr(SNF_WT_DISABLE);

	g_snfCtrl.spicsoff();
}

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

// 读状态寄存器1
// 可在任意时候读取（数据可以连续读取）
// SRP0 SEC  TB  PB2  PB1  PB0   WEL  BUSY

u8 SNFReadStatusReg1(void)
{
	u8 dat;
	if (g_snfCtrl.inited == 0)
	{
		return 0;
	}
	g_snfCtrl.spicson();

	g_snfCtrl.spiwr(SNF_RD_STREG1);

	dat = g_snfCtrl.spird();	//

	g_snfCtrl.spicsoff();

	return dat;
}

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

// 读状态寄存器2
// 可在任意时候读取（数据可以连续读取）
// SUS  CMP  LB3  LB2  LB1  (R)  QE  SRP1
u8 SNFReadStatusReg2(void)
{
	u8 dat;
	if (g_snfCtrl.inited == 0)
	{
		return 0;
	}

	g_snfCtrl.spicson();

	g_snfCtrl.spiwr(SNF_RD_STREG2);

	dat = g_snfCtrl.spird();	//

	g_snfCtrl.spicsoff();

	return dat;
}

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

// 写状态寄存器1和2
void SNFWriteStatusReg1And2(u8 reg1, u8 reg2)
{
	if (g_snfCtrl.inited == 0)
	{
		return;
	}

	g_snfCtrl.spicson();

	g_snfCtrl.spiwr(SNF_WT_STREG12);

	g_snfCtrl.spiwr(reg1);

	g_snfCtrl.spiwr(reg2);

	g_snfCtrl.spicsoff();
}

//---------------------------------
// 函数功能: 判断Nor是否处于空闲状态
// 返回值:	0, 空闲
// 		 	1, 忙

int SNFIsdStatusBusy(void)
{
	u8 sta1;
	sta1 = SNFReadStatusReg1();
	sta1 &= 0x01;		// WIP flag

	return sta1;
}

//---------------------------------
// 读数据(50M以下的速度）
// 在整个存储区域内可以连续读取
int SNFlashRdData(u32 addr, u8 * pBuf, int len)
{
	int i;
	if (pBuf == NULL ||
		len <= 0 ||
		g_snfCtrl.inited == 0 ||
		0	)
	{
		return -1;
	}

	g_snfCtrl.spicson();

	g_snfCtrl.spiwr(SNF_READ_DATA);
	g_snfCtrl.spiwr(LOBYTE(HIWORD(addr)));
	g_snfCtrl.spiwr(HIBYTE(LOWORD(addr)));
	g_snfCtrl.spiwr(LOBYTE(LOWORD(addr)));

	for (i = 0; i < len; i++)
	{
		*pBuf++ = g_snfCtrl.spird();
	}

	g_snfCtrl.spicsoff();

	return 0;
}

//---------------------------------
// 快速读取（可达到104M）
// 在整个存储区域内可以连续读取
int SNFFastReadData(u32 addr, u8 * pBuf, int len)
{
	int i;
	if (pBuf == NULL ||
		len <= 0 ||
		g_snfCtrl.inited == 0 ||
		0	)
	{
		return -1;
	}

	g_snfCtrl.spicson();

	g_snfCtrl.spiwr(SNF_FAST_READ);
	g_snfCtrl.spiwr(LOBYTE(HIWORD(addr)));
	g_snfCtrl.spiwr(HIBYTE(LOWORD(addr)));
	g_snfCtrl.spiwr(LOBYTE(LOWORD(addr)));

	g_snfCtrl.spiwr(DUMMY_BYTE);

	for (i = 0; i < len; i++)
	{
		*pBuf++ = g_snfCtrl.spird();
	}

	g_snfCtrl.spicsoff();

	return 0;
}

//---------------------------------
// 判断数据区是否为空
int IsSNFlashEmpty(u32 addr, int len)
{
	u32 i;
	int rslt = 0;
	if (g_snfCtrl.inited == 0)
	{
		return 0;
	}
	g_snfCtrl.spicson();

	g_snfCtrl.spiwr(SNF_READ_DATA);
	g_snfCtrl.spiwr(LOBYTE(HIWORD(addr)));
	g_snfCtrl.spiwr(HIBYTE(LOWORD(addr)));
	g_snfCtrl.spiwr(LOBYTE(LOWORD(addr)));

	for (i = 0; i < len; i++)
	{
		if (g_snfCtrl.spird() != 0xff)
		{
			rslt = 1;
			break;
		}
	}

	g_snfCtrl.spicsoff();

	return rslt;
}

//---------------------------------
// 页内写数据[最多可以写256个字节数据]
// 如果数据超出一页，地址会循环回到一页的起始继续写入
int SNFPageProgram(u32 addr, u8 * pBuf, int len)
{
	int i;
	if (pBuf == NULL ||
		len <= 0 ||
		g_snfCtrl.inited == 0 ||
		0	)
	{
		return -1;
	}

	SNFWirteEnable();
	SNFWaitNotBusy10Us(100);

	g_snfCtrl.spicson();

	g_snfCtrl.spiwr(SNF_PAGE_PROGRAM);

	g_snfCtrl.spiwr(LOBYTE(HIWORD(addr)));

	g_snfCtrl.spiwr(HIBYTE(LOWORD(addr)));

	g_snfCtrl.spiwr(LOBYTE(LOWORD(addr)));

	for (i = 0; i < len; i++)
	{
		g_snfCtrl.spiwr(*pBuf++);
	}

	g_snfCtrl.spicsoff();

	return SNFWaitNotBusy10Us(300);
}

//---------------------------------
// 扇区擦除(4KB)
int SNFlash4kErase(u32 addr, int wait)
{
	int rslt = 1;
	if (g_snfCtrl.inited == 0)
	{
		return rslt;
	}

	SNFWirteEnable();
	SNFWaitNotBusy10Us(100);

	g_snfCtrl.spicson();

	g_snfCtrl.spiwr(SNF_4K_ERASE);

	g_snfCtrl.spiwr(LOBYTE(HIWORD(addr)));

	g_snfCtrl.spiwr(HIBYTE(LOWORD(addr)));

	g_snfCtrl.spiwr(LOBYTE(LOWORD(addr)));

	g_snfCtrl.spicsoff();

	if (wait != 0)
	{
		rslt = SNFWaitNotBusyMs(300);
	}

	return rslt;
}

//---------------------------------
// 扇区擦除(32KB)
int SNFlash32kErase(u32 addr, int wait)
{
	int rslt = 1;
	if (g_snfCtrl.inited == 0)
	{
		return rslt;
	}
	g_snfCtrl.spicson();

	g_snfCtrl.spiwr(SNF_32K_ERASE);

	g_snfCtrl.spiwr(LOBYTE(HIWORD(addr)));

	g_snfCtrl.spiwr(HIBYTE(LOWORD(addr)));

	g_snfCtrl.spiwr(LOBYTE(LOWORD(addr)));

	g_snfCtrl.spicsoff();

	if (wait != 0)
	{
		rslt = SNFWaitNotBusyMs(800);
	}

	return rslt;
}

//---------------------------------
// 扇区擦除(64KB)
int SNFlash64kErase(u32 addr, int wait)
{
	int rslt = 1;
	if (g_snfCtrl.inited == 0)
	{
		return rslt;
	}
	g_snfCtrl.spicson();

	g_snfCtrl.spiwr(SNF_64K_ERASE);

	g_snfCtrl.spiwr(LOBYTE(HIWORD(addr)));

	g_snfCtrl.spiwr(HIBYTE(LOWORD(addr)));

	g_snfCtrl.spiwr(LOBYTE(LOWORD(addr)));

	g_snfCtrl.spicsoff();

	if (wait != 0)
	{
		rslt = SNFWaitNotBusyMs(1000);
	}

	return rslt;
}

//---------------------------------
// 正片擦除
int SNFlashChipErase(u32 addr, int wait)
{
	int rslt = 1;
	if (g_snfCtrl.inited == 0)
	{
		return rslt;
	}
	g_snfCtrl.spicson();

	g_snfCtrl.spiwr(SNF_CHIP_ERASE);

	g_snfCtrl.spicsoff();

	if (wait != 0)
	{
		rslt = SNFWaitNotBusyMs(6000);
	}

	return rslt;
}

//---------------------------------
// 读取 制造商 id 和 设备 ID
// manufacturer id + device id

u32 SNFGetManufacDeviceID(void)
{
	u32 mdid;
	u8	mid,did;
	if (g_snfCtrl.inited == 0)
	{
		return 0;
	}
	g_snfCtrl.spicson();
	g_snfCtrl.spiwr(SNF_MANU_DEVICE_ID);
	g_snfCtrl.spiwr(0);
	g_snfCtrl.spiwr(0);
	g_snfCtrl.spiwr(0);

	mid = g_snfCtrl.spird();
	did = g_snfCtrl.spird();

	g_snfCtrl.spicsoff();

	mdid = MAKEDWORDF(did, mid, 0, 0);

//	printf("Nor flash manufacturer id and device id = 0x%x\r\n", mdid);

	return mdid;
}

//---------------------------------
// 读取 JEDEC ID
// manufacturer id + memory type + capacity

u32 SNFGetJedecID(void)
{
	u32 jid;
	u8	id1,id2,id3;
	if (g_snfCtrl.inited == 0)
	{
		return 0;
	}
	g_snfCtrl.spicson();
	g_snfCtrl.spiwr(SNF_JEDEC_ID);
	id3 = g_snfCtrl.spird();
	id2 = g_snfCtrl.spird();
	id1 = g_snfCtrl.spird();
	g_snfCtrl.spicsoff();

	jid = MAKEDWORDF(id1, id2, id3, 0);

//	printf("Nor flash jedec id = 0x%x\r\n", jid);

	return jid;
}

//---------------------------------
// 读取 Unique ID
// 8字节的唯一序列号

u64 SNFGetUniqueID(void)
{
	int i;
	u8 id;
	u64 uid;
	u8 * pId = (u8 *)(&uid);

	if (g_snfCtrl.inited == 0)
	{
		return 0;
	}
	g_snfCtrl.spicson();
	g_snfCtrl.spiwr(SNF_UNIQUE_ID);
	g_snfCtrl.spiwr(DUMMY_BYTE);
	g_snfCtrl.spiwr(DUMMY_BYTE);
	g_snfCtrl.spiwr(DUMMY_BYTE);
	g_snfCtrl.spiwr(DUMMY_BYTE);

	printf("Nor flash Unique id = ");

	for (i = 0; i < 8; i++)
	{
		id = g_snfCtrl.spird();
		*pId++ = id;
		printf("0x%x, ", id);
	}
	printf("\r\n");

	g_snfCtrl.spicsoff();

	return uid;
}

//---------------------------------
// 连续写数据
int SNFlashWrData(u32 addr, u8 *data, int len)
{
	int rslt;
	u32 pglen;

	pglen = addr % SNF_BYTES_PER_PAGE;
	if (pglen == 0)
	{
		pglen = SNF_BYTES_PER_PAGE;
	}

	do
	{
		rslt = SNFPageProgram(addr, data, pglen);
		if (rslt != 0)
		{
			break;
		}
		addr += pglen;
		data += pglen;
		len -= pglen;
		if (len >= SNF_BYTES_PER_PAGE)
		{
			pglen = SNF_BYTES_PER_PAGE;
		}
		else if (len > 0)
		{
			pglen = len;
		}
		else
		{
			break;
		}
	}while(1);

	return rslt;
}

//---------------------------------
/* 整个扇区
 * 	----------------------		eaddr:扇区首地址(起始地址)	-----
 * |					  |										|
 * |					  |										|
 * |		页1			  |										|
 *  ----------------------										|
 * |					  |										|
 * |					  |										elen:扇区首地址到写入完成的字节数
 * |		页2			  |										|
 *  ----------------------	---- addr:写入起始地址			    |
 * |					  |		 |								|
 * |					  |		 len:写入长度					|
 * |		页3			  |		 |								|
 *  ----------------------	-----							----
 * |					  |
 * |					  |
 * |		页4			  |
 *  ----------------------
 * |					  |
 * |					  |
 * |		页5			  |
 *  ----------------------
 * |					  |
 * |					  |
 * |		页6			  |
 *  ----------------------
 * |					  |
 * |					  |
 * |		页7			  |
 *  ----------------------
 * |					  |
 * |					  |
 * |		页8			  |
 * 	----------------------
 * |					  |
 * |					  |
 * |		页9			  |
 *  ----------------------
 * |					  |
 * |					  |
 * |		页10			  |
 *  ----------------------
 * |					  |
 * |					  |
 * |		页11			  |
 *  ----------------------
 * |					  |
 * |					  |
 * |		页12			  |
 *  ----------------------
 * |					  |
 * |					  |
 * |		页13			  |
 *  ----------------------
 * |					  |
 * |					  |
 * |		页14			  |
 *  ----------------------
 * |					  |
 * |					  |
 * |		页15			  |
 *  ----------------------
 * |					  |
 * |					  |
 * |		页16			  |
 *  ----------------------
 */
// 写数据（自动擦除）
int SNFlashWrDataWithErase(u32 addr, u8 *data, int len)
{
	int i, erflag, rslt;			// erflag:擦除标志 = 1,擦除
	u8 rdata[SNF_BYTES_PER_SEC];	// 存储整个扇区的数据
	u32 eaddr;						// 扇区首地址
	u32 elen, wlen;					// elen:扇区首地址到写入完成的字节数		wlen:写入长度

	eaddr = (addr/SNF_BYTES_PER_SEC) * SNF_BYTES_PER_SEC;	// 取整扇区首地址
	rslt = 0;

	printf("nwe, fad=0x%x, sad=0x%x len=%d, \r\n", addr, eaddr, len);

	while(addr < SNF_TOTAL_BYTES && len > 0)
	{
		erflag = 0;
		SNFlashRdData(eaddr, rdata, SNF_BYTES_PER_SEC);		// 读取一个扇区

		elen = SNF_BYTES_PER_SEC;
		if ((addr-eaddr)+len < elen)
		{
			elen = len+(addr-eaddr);			// 扇区首地址到写入完成的字节数
		}

		wlen = elen-(addr-eaddr);

		// 判断是否需要擦除
		for (i = (addr-eaddr); i < elen; i++)		// 如果不能写入(存在0--1)
		{
			if ((rdata[i] & data[i]) != data[i])	// 与之后，和要写入数据相同，可以不擦除
			{
				erflag = 1;		// 擦除标志
				break;
			}
		}

	//	printf("elen=%d, wlen=%d, bufbeg=%d\r\n", elen, wlen, addr-eaddr);

		if (erflag != 0)
		{
			SNFlash4kErase(eaddr, 1);							// 擦除一个扇区

			memcpy(&(rdata[(addr-eaddr)]), data, wlen);				// 数据写入缓冲区
			rslt = SNFlashWrData(eaddr, rdata, SNF_BYTES_PER_SEC);	// 写入flash

			printf("Erase 4K and wr\r\n");
		}
		else
		{
		//	printf("wr to fls\r\n");
			rslt = SNFlashWrData(addr, data, wlen);				// 写入flash
		}

		if (rslt != 0)
		{
			break;
		}

		len -= wlen;
		data += wlen;
		addr += wlen;						// 地址增加
		eaddr += SNF_BYTES_PER_SEC;
	}

	return rslt;
}


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

// 函数功能: 等待Nor操作完成
// 返回值: 0, 正常
// 		  -1, 超时
int SNFWaitNotBusyMs(u32 timeout)
{
	u32 i;
	int rst = -1;

	for (i = 0; i < timeout; i++)
	{
		if (SNFIsdStatusBusy() == 0)
		{
			rst = 0;
			break;
		}
		DelayMs(1); 			// 此处可替换为其他延时函数
	}

	return rst;
}

//---------------------------------
// 函数功能: 等待Nor操作完成
// 返回值:0 正常
// 		 -1:超时
int SNFWaitNotBusy10Us(u32 timeout)
{
	u32 i;
	int rst = -1;

	for (i = 0; i < timeout; i++)
	{
		if (SNFIsdStatusBusy() == 0)
		{
			rst = 0;
			break;
		}
		DelayUs(10); 			// 此处可替换为其他延时函数
	}

	return rst;
}

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

void ShowSNFInfo(void)
{
	u32 id;

	printf("--------------nor flash info--------------\r\n");

	id = SNFGetManufacDeviceID();	// 读取 制造商 id 和 设备 ID
	printf("manufacturer id = 0x%x\r\n", HIBYTE(LOWORD(id)));
	printf("device id = 0x%x\r\n", LOBYTE(LOWORD(id)));

	id = SNFGetJedecID();	// 读取 jedec id

	printf("manufacturer id = 0x%x\r\n", LOBYTE(HIWORD(id)));
	printf("memory type = 0x%x\r\n", HIBYTE(LOWORD(id)));
	printf("capacity = 0x%x\r\n", LOBYTE(LOWORD(id)));

	SNFGetUniqueID();	// 8字节的唯一序列号

	printf("------------------------------------------\r\n");
}

// NorFlash 测试
void SNFlashTest(char * para1, char * para2)
{
	int p1, p2;

	p1 = p2 = 0;
	if (para1 != NULL && strcmp(para1, "") != 0)
	{
		p1 = atoi(para1);
	}
	if (para2 != NULL && strcmp(para2, "") != 0)
	{
		p2 = atoi(para2);
	}
	if (p1 == p2)
	{
	}
	//--------------------------------
	{
		u8 buff[1024];
		int i;

		if (p1 == 0)
		{// 从地址p2开始读取1K字节数据
			memset(buff, 0, 1024);
			DatFlashRdData(p2, buff, 1024);
			printf("DatFlashRdData addr=0x%x,\r\n", p2);
			for (i = 0; i < 1024; i++)
			{
				if ((i%16) == 0)
				{
					printf("\r\n%d:\t", i+1);
					DelayMs(10);
				}
				printf("%02x ", buff[i]);
			}
			printf("\r\n");
		}
		else if (p1 == 1)
		{// 从地址p2开始写入1K字节数据
			printf("DatFlashWrDataWithErase addr=0x%x,\r\n", p2);

			for (i = 0; i < 1024; i++)
			{
				buff[i] = p2 + i;
			}
			DatFlashWrDataWithErase(p2, buff, 1024);
			printf("done \r\n");
		}
		else if (p1 == 3)
		{// 从地址0x190000开始读取数据
			int circle = p2;
			int count = 0;
			do
			{
				memset(buff, 0, 1024);
				DatFlashRdData(0x190000+count*0x400, buff, 1024);
				printf("DatFlashRdData addr=0x%x,\r\n", 0x190000+count*0x400);
				for (i = 0; i < 1024; i++)
				{
					if ((i%16) == 0)
					{
						printf("\r\n%d:\t", count*1024+i+1);
						DelayMs(10);
					}
					printf("%02x ", buff[i]);
				}
				printf("\r\n");
				circle--;
				count++;
				if (circle <= 0)
				{
					break;
				}
			}while(1);
		}
	}
}

