1. 程式人生 > >SpiFlash同步/非同步讀寫微控制器裸機例項

SpiFlash同步/非同步讀寫微控制器裸機例項

 微控制器裸機開發中會經常遇到外設速度過慢,長時間讀忙等待,但CPU又不能長時間阻塞的問題。
這種問題可以通過實現一個狀態機來非同步處理。

非同步狀態機程式碼結構示例:

enum
{
	eIDLE = 0,
	eSTART,
	eWAIT,
	eSUCCESS
};

static uint8_t stage = 0;
//啟動非同步處理	
void DoSomethingRequest()
{
	if(stage != eIDLE)
	{
		printf("AsyncMachine is busy!!!,return\n");
		return;
	}
	SomethingReq = TRUE;
}
//非同步處理任務
void AsyncMachine()
{
	
	switch(stage)
	{
		case eIDLE:
			if(SomethingReq)
			{
				stage = eSTART;
				printf("A task will be start\n");
			}
			break;
		case eSTART: 
			do_something();
			stage = eWAIT;
			printf("do something\n");
			break;
		case eWAIT: 
			if(something_state() == OK)
			{
				stage = eSUCCESS;
			}
			printf("Wait...\n");
			break;
		case eSUCCESS: 
			stage = eIDLE;
			printf("task exec success\n");
			break;
	}
}

通過把阻塞的任務單獨分離出來,交給一個狀態機子任務來處理。則應用程式只需要呼叫一個處理請求而無需原地死等,狀態機處理完成後,可以非同步回撥來通知應用程式任務已完成。

下面附上SPI FLASH 同步/非同步讀寫例項。

//SPI狀態機狀態
typedef enum 
{
	eFLASH_STATE_IDLE = 0,
	eFLASH_STATE_WRITE = 1, 
	eFLASH_STATE_READ = 2,
	eFLASH_STATE_BUSY = 3,
	eFLASH_STATE_ERASE_CHIP = 4,
	eFLASH_STATE_ERASE = 5,
}FlashState_e;
//SPI裝置結構體
typedef struct SpiDevice_s {
	SPI_TypeDef *spiHandle;//SPI物理屬性
	uint8_t *pTxBuffer;//非同步傳送快取
	uint32_t uTxDstAddr;//非同步傳送目地地址
	uint16_t wTxLen;//非同步傳送長度
	uint16_t wTxOffset; //非同步當前快取已傳送偏移 
	uint8_t *pRxBuffer;
	uint32_t uRxSrcAddr;
	uint16_t wRxLen;
	uint16_t wRxOffset; 
	void (*pWriteAsyncNotifyCallback)(); //非同步寫完成回撥通知
	void (*pEraseChipAsyncNotifyCallback)();//異不擦除回撥通知
	struct {
		FlashState_e eStage;//當前狀態機狀態
		//BOOL bTxBusy:1;   //傳送忙
		BOOL bTxReq:1;     //傳送請求
		BOOL bTxCompleted:1;//傳送完成
		//BOOL bRxBusy:1;  //讀忙
		BOOL bRxReq:1;    //讀請求
		BOOL bEraseChipReq:1;//擦整片請求
		BOOL bEraseSectorReq:1;//擦扇區請求
		BOOL bEraseSuccess:1; //擦成功
	}tState;
	void (*Init)(void);
	uint8_t (*EraseChip)(void);//同步擦
	void (*Read)(uint8_t* pBuffer,uint32_t uReadAddr,uint16_t wNumByteToRead);//同步讀
	uint32_t (*WriteByte)(uint8_t Byte, uint32_t uWriteAddr);//同步寫位元組
	uint32_t (*Write)(uint8_t* pBuffer,uint32_t uWriteAddr, uint16_t wNumByteToWrite);//同步寫
	BOOL (*WriteAsync)(uint8_t* pBuffer,uint32_t uWriteAddr, uint16_t wNumByteToWrite);//非同步寫
	BOOL (*EraseChipAsync)(void);//非同步整片擦
	BOOL (*EraseAsync)(uint32_t uAddr, uint16_t wlen);//奶步擦
	void (*WriteAsyncNotifyCallbackRegister)(void* pfn);//非同步寫完成回撥註冊
	void (*EraseChipAsyncNotifyCallbackRegister)(void *pfn);//非同步擦完成回撥註冊
}SpiDevice_t;
例項化
SpiDevice_t g_tSpiDevice = 
{
	SPI2,
	g_aTxBuffer,
	0,0,0,
	g_aRxBuffer,
	0,0,0,
	0,0,
	{0,0},
	Spi_Init,
	SPI_Flash_Erase_Chip,	//ͬ²½ÕûƬ²Á
	SPI_Flash_Read,				//ͬ²½¶Á
	SPI_Flash_WriteByte,	//ͬ²½Ð´×Ö½Ú
	SPI_Flash_Write,			//ͬ²½Ð´
	SPI_FlashWriteAsync,	//Ò첽д
	SPI_FlashEraseChipAsync,	//Òì²½ÕûƬ²Á³ý
	SPI_FlashEraseAsync,
	SPI_WriteAsyncNotifyCallbackRegister,//д״̬Ò첽֪ͨ»Øµ÷
	SPI_EraseChipAsyncNotifyCallbackRegister,//²Á³ý״̬Ò첽֪ͨ»Øµ÷
};
//SPI同步操作
/*****************
²Á³ýÒ»¸öÉÈÇø
0~511
******************/
unsigned char SPI_Flash_Erase_Sector(unsigned int Dst_Addr)  
{  
	  unsigned char cnt=0; 
	
    SPI_FLASH_Write_Enable();                  //SET WEL           
    while((SPI_Flash_Read_SR()&0x2)!=0x2) 
		{
			cnt ++;
			if(cnt >200)
				return FALSE;
		}   
    SPI_CS_LOW();                            
    SPI_Flash_ReadWrite_Byte(SECTOR_ERASE);      
    SPI_Flash_ReadWrite_Byte((unsigned char)((Dst_Addr)>>16));   
    SPI_Flash_ReadWrite_Byte((unsigned char)((Dst_Addr)>>8));  
    SPI_Flash_ReadWrite_Byte((unsigned char)Dst_Addr); 
    SPI_CS_HIGH();                                         
    SPI_Flash_Wait_Busy();  
		return TRUE;
} 

/*64K Flash¿Õ¼ä²Á³ý*/
unsigned char SPI_Flash_Erase_64k(unsigned int Dst_Addr)  
{  
	  unsigned char cnt=0;
	
    SPI_FLASH_Write_Enable();                  //SET WEL           
    while((SPI_Flash_Read_SR()&0x2)!=0x2) 
		{
			cnt ++;
			if(cnt >200)
				return FALSE;
		} 
    SPI_CS_LOW();                            
    SPI_Flash_ReadWrite_Byte(BLOCK_ERASE_64K);      
    SPI_Flash_ReadWrite_Byte((unsigned char)((Dst_Addr)>>16));   
    SPI_Flash_ReadWrite_Byte((unsigned char)((Dst_Addr)>>8));  
    SPI_Flash_ReadWrite_Byte((unsigned char)Dst_Addr); 
    SPI_CS_HIGH();                                         
    SPI_Flash_Wait_Busy(); 
		return TRUE;
} 

/*²Á³ýоƬ*/
unsigned char SPI_Flash_Erase_Chip(void)  
{   
		unsigned char cnt=0;     
		
    SPI_FLASH_Write_Enable();                  //SET WEL
    while((SPI_Flash_Read_SR()&0x2)!=0x2) 
		{
			cnt ++;
			if(cnt >200)
				return FALSE;
		}
    SPI_CS_LOW();                             
    SPI_Flash_ReadWrite_Byte(CHIP_ERASE);        
    SPI_CS_HIGH();                                         
    SPI_Flash_Wait_Busy();  
		return TRUE;
}  

/*Ö¸¶¨µØÖ·¶ÁÈ¡Ö¸¶¨³¤¶ÈÊý¾Ý*/
void SPI_Flash_Read(unsigned char* pBuffer,unsigned int ReadAddr,unsigned short int NumByteToRead)  
{
    unsigned short int index; 
	
    SPI_CS_LOW();                            
    SPI_Flash_ReadWrite_Byte(READ_DATA);         
    /*¸³ÖµµØÖ·*/
    SPI_Flash_ReadWrite_Byte((unsigned char)((ReadAddr)>>16));   
    SPI_Flash_ReadWrite_Byte((unsigned char)((ReadAddr)>>8));  
    SPI_Flash_ReadWrite_Byte((unsigned char)ReadAddr);
          
    for(index=0;index<NumByteToRead;index++)
    {
			pBuffer[index]=SPI_Flash_ReadWrite_Byte(DUMMY); 
    }
    SPI_CS_HIGH();                                        
} 


uint32_t SPI_Flash_WriteByte(unsigned char Byte,unsigned int WriteAddr)
{
		unsigned char cnt=0;
	
		SPI_FLASH_Write_Enable();                  //SET WEL           
    while((SPI_Flash_Read_SR()&0x2)!=0x2) 
		{
			cnt ++;
			if(cnt >200)
				return FALSE;   /*·µ»Øдʧ°Ü*/
		} 
		SPI_CS_LOW();                            
    SPI_Flash_ReadWrite_Byte(PAGE_PRG);      
    SPI_Flash_ReadWrite_Byte((unsigned char)((WriteAddr)>>16));   
    SPI_Flash_ReadWrite_Byte((unsigned char)((WriteAddr)>>8));  
    SPI_Flash_ReadWrite_Byte((unsigned char)WriteAddr);
		SPI_Flash_ReadWrite_Byte(Byte);
		SPI_CS_HIGH();                                         
    SPI_Flash_Wait_Busy();
		return TRUE;
		
}

uint32_t SPI_Flash_Write(unsigned char* pBuffer,unsigned int WriteAddr,unsigned short int NumByteToWrite)
{
	unsigned short int pageoffset=PAGE_SIZE-(WriteAddr%PAGE_SIZE);  /*¼ÆËã¸ÃÒ³Öл¹ÓжàÉÙÊ£Óà¿Õ¼ä*/
	unsigned char cnt=0;
	unsigned short int index;
	unsigned int pagenum =WriteAddr/PAGE_SIZE;  /*±¾´ÎдÈëµÄÒ³Êý*/
	unsigned int Addr;
	
	if(pageoffset >= NumByteToWrite)  //Ê£Óà¿Õ¼ä´óÓÚҪдµÄÊýÁ¿
	{
    SPI_FLASH_Write_Enable();                  //SET WEL           
    while((SPI_Flash_Read_SR()&0x2)!=0x2) 
		{
			cnt ++;
			if(cnt >200)
				return FALSE;   /*·µ»Øдʧ°Ü*/
		} 
		SPI_CS_LOW();                            
    SPI_Flash_ReadWrite_Byte(PAGE_PRG);      
    SPI_Flash_ReadWrite_Byte((unsigned char)((WriteAddr)>>16));   
    SPI_Flash_ReadWrite_Byte((unsigned char)((WriteAddr)>>8));  
    SPI_Flash_ReadWrite_Byte((unsigned char)WriteAddr); 
		for(index=0; index<NumByteToWrite;index++)
		{
			SPI_Flash_ReadWrite_Byte(*(pBuffer+index)); 
		}
    SPI_CS_HIGH();                                         
    SPI_Flash_Wait_Busy(); 
		return TRUE;
	}
	else
	{
		/*ÏȽ«¸ÃÒ³ÌîÂú*/
		SPI_FLASH_Write_Enable();                  //SET WEL           
    while((SPI_Flash_Read_SR()&0x2)!=0x2) 
		{
			cnt ++;
			if(cnt >200)
				return FALSE;   /*·µ»Øдʧ°Ü*/
		} 
		SPI_CS_LOW();                            
    SPI_Flash_ReadWrite_Byte(PAGE_PRG);      
    SPI_Flash_ReadWrite_Byte((unsigned char)((WriteAddr)>>16));   
    SPI_Flash_ReadWrite_Byte((unsigned char)((WriteAddr)>>8));  
    SPI_Flash_ReadWrite_Byte((unsigned char)WriteAddr); 
		for(index=0; index<pageoffset;index++)
		{
			SPI_Flash_ReadWrite_Byte(*(pBuffer+index)); 
		}
    SPI_CS_HIGH();                                         
    SPI_Flash_Wait_Busy(); 
		
		NumByteToWrite -=pageoffset;  /*³¤¶È¼õȥдÈëÊý¾Ý*/
		pagenum++;
		Addr = pagenum*PAGE_SIZE;  //»ñÈ¡ÏÂÒ»Ò³µÄÆðʼµØÖ·
		
		while(NumByteToWrite >0)
		{
			if(NumByteToWrite > PAGE_SIZE)  //ÈÔÈ»´óÓÚÒ»Ò³
			{
				SPI_FLASH_Write_Enable();                  //SET WEL           
				while((SPI_Flash_Read_SR()&0x2)!=0x2) 
				{
					cnt ++;
					if(cnt >200)
					return FALSE;   /*·µ»Øдʧ°Ü*/
				} 
				SPI_CS_LOW();                            
				SPI_Flash_ReadWrite_Byte(PAGE_PRG);      
				SPI_Flash_ReadWrite_Byte((unsigned char)((Addr)>>16));   
				SPI_Flash_ReadWrite_Byte((unsigned char)((Addr)>>8));  
				SPI_Flash_ReadWrite_Byte((unsigned char)Addr); 
				for(index=0; index<PAGE_SIZE;index++)
				{
					SPI_Flash_ReadWrite_Byte(*(pBuffer+index+pageoffset)); 
				}
				SPI_CS_HIGH();                                         
				SPI_Flash_Wait_Busy();
				NumByteToWrite -=PAGE_SIZE;
				pageoffset +=PAGE_SIZE;
				pagenum++;
		    Addr = pagenum*PAGE_SIZE;  //»ñÈ¡ÏÂÒ»Ò³µÄÆðʼµØÖ·
			}
			else
			{
				SPI_FLASH_Write_Enable();                  //SET WEL           
				while((SPI_Flash_Read_SR()&0x2)!=0x2) 
				{
					cnt ++;
					if(cnt >200)
					return FALSE;   /*·µ»Øдʧ°Ü*/
				} 
				SPI_CS_LOW();                            
				SPI_Flash_ReadWrite_Byte(PAGE_PRG);      
				SPI_Flash_ReadWrite_Byte((unsigned char)((Addr)>>16));   
				SPI_Flash_ReadWrite_Byte((unsigned char)((Addr)>>8));  
				SPI_Flash_ReadWrite_Byte((unsigned char)Addr); 
				for(index=0; index<NumByteToWrite;index++)
				{
					SPI_Flash_ReadWrite_Byte(*(pBuffer+index+pageoffset)); 
				}
				SPI_CS_HIGH();                                         
				SPI_Flash_Wait_Busy();
				NumByteToWrite =0;
			}
		}
		return TRUE;
	}
}
/***********************************************************************************************
 *SPI非同步操作
 *************************************************************************************************/

/*****************************************************************************************                    									       	
º¯ÊýÃû³Æ:SPI_FlashWriteAsync非同步寫請求
º¯ÊýÃèÊö:Ò첽д
ÊäÈë²ÎÊý:                                  
Êä³ö²ÎÊý:                                                        
º¯Êý·µ»Ø: 
******************************************************************************************/
BOOL SPI_FlashWriteAsync(uint8_t* pBuffer,uint32_t uWriteAddr, uint16_t wNumByteToWrite)
{
	if(wNumByteToWrite > FLASH_TX_BUFFER_SIZE)
	{
		return FALSE;
	}
	if(g_tSpiDevice.tState.eStage != eFLASH_STATE_IDLE)
	{
		Debug(eDBUG_LEVEL_ERROR,"[%d]Flash_Write:busy,return\r\n", GetTicks());
		return FALSE;
	}
	memcpy(g_tSpiDevice.pTxBuffer, pBuffer, wNumByteToWrite);
	g_tSpiDevice.wTxLen = wNumByteToWrite;
	g_tSpiDevice.uTxDstAddr = uWriteAddr;
	g_tSpiDevice.wTxOffset = 0;
	g_tSpiDevice.tState.bTxReq = TRUE; //請求標誌
	g_tSpiDevice.tState.bTxCompleted = FALSE;
	//g_tSpiDevice.tState.bTxBusy = TRUE;
	return TRUE;
}
/*****************************************************************************************                    									       	
º¯ÊýÃû³Æ:SPI_FlashWriteAsync
º¯ÊýÃèÊö:Òì²½²ÁÕûƬ
ÊäÈë²ÎÊý:                                  
Êä³ö²ÎÊý:                                                        
º¯Êý·µ»Ø: 
******************************************************************************************/
BOOL SPI_FlashEraseChipAsync(void)
{
	//unsigned char cnt=0;     
	
	if(g_tSpiDevice.tState.eStage != eFLASH_STATE_IDLE)
	{
		Debug(eDBUG_LEVEL_ERROR,"[%d]Flash_earse:busy,return\r\n", GetTicks());
		return FALSE;
	}
	

	g_tSpiDevice.tState.bEraseChipReq = TRUE;
	return TRUE;	
}
/*****************************************************************************************                    									       	
º¯ÊýÃû³Æ:非同步擦除
º¯ÊýÃèÊö:Òì²½²ÁÖ¸¶¨µØÖ·
ÊäÈë²ÎÊý:                                  
Êä³ö²ÎÊý:                                                        
º¯Êý·µ»Ø: 
******************************************************************************************/
BOOL SPI_FlashEraseAsync(uint32_t uAddr, uint16_t wlen)
{
	//unsigned char cnt=0;     
	
	if(g_tSpiDevice.tState.eStage != eFLASH_STATE_IDLE)
	{
		Debug(eDBUG_LEVEL_ERROR,"[%d]Flash_earse:busy,return\r\n", GetTicks());
		return FALSE;
	}
	
	g_tSpiDevice.wTxLen = wlen;
	g_tSpiDevice.uTxDstAddr = uAddr;
	g_tSpiDevice.wTxOffset = 0;
	g_tSpiDevice.tState.bEraseSectorReq = TRUE;
	return TRUE;	
}
//註冊完成通知

void SPI_WriteAsyncNotifyCallbackRegister(void *pfn)
{
	g_tSpiDevice.pWriteAsyncNotifyCallback = (void (*)())pfn;
}
void SPI_EraseChipAsyncNotifyCallbackRegister(void *pfn)
{
	g_tSpiDevice.pEraseChipAsyncNotifyCallback = (void (*)())pfn;
}



//ÅжÏSPI FLASH æ
static BOOL SPI_FlashBusyCheck(void)
{
	if((SPI_Flash_Read_SR()&0x01)==0x01)
	{
		return TRUE;
	} 
	else 
	{
		return FALSE;
	}
}
//дһҳ
static BOOL __SPI_FlashWritePage(uint32_t uWriteAddr, uint8_t *pData, uint16_t wWriteLen)
{
	uint8_t  cnt;
	uint16_t index;
	SPI_FLASH_Write_Enable();                  //SET WEL           
	while((SPI_Flash_Read_SR()&0x2)!=0x2) 
	{
		cnt ++;
		if(cnt >200)
			return FALSE;   /*·µ»Øдʧ°Ü*/
	} 
	SPI_CS_LOW();                            
	SPI_Flash_ReadWrite_Byte(PAGE_PRG);      
	SPI_Flash_ReadWrite_Byte((unsigned char)((uWriteAddr)>>16));   
	SPI_Flash_ReadWrite_Byte((unsigned char)((uWriteAddr)>>8));  
	SPI_Flash_ReadWrite_Byte((unsigned char)uWriteAddr); 
	for(index=0; index < wWriteLen; index++)
	{
		SPI_Flash_ReadWrite_Byte(*(pData+index)); 
	}
	SPI_CS_HIGH();
	return TRUE;
}
//Ò첽д´¦Àí×ÓÈÎÎñ
static int32_t __SPI_FlashWrite(void)
{
	uint16_t wWriteRemainNum = g_tSpiDevice.wTxLen - g_tSpiDevice.wTxOffset;
	uint8_t *pData = g_tSpiDevice.pTxBuffer + g_tSpiDevice.wTxOffset;
	uint32_t uWriteAddr = g_tSpiDevice.uTxDstAddr + g_tSpiDevice.wTxOffset;
	uint16_t wPageRemain = PAGE_SIZE - (uWriteAddr % PAGE_SIZE);

	//ÅжÏдÍê³É
	if(wWriteRemainNum == 0)
	{
		//дÍê³É
		g_tSpiDevice.tState.bTxCompleted = TRUE;
		//g_tSpiDevice.tState.bRxBusy = FALSE;
		g_tSpiDevice.tState.bTxReq = FALSE;
		g_tSpiDevice.tState.eStage = eFLASH_STATE_IDLE; //дÍê³É ת¿ÕÏÐ
		if(g_tSpiDevice.pWriteAsyncNotifyCallback)
		{
			//TODO Ò첽֪ͨ»Øµ÷ ¹©µ÷ÓÃÕßʵÏÖ
			g_tSpiDevice.pWriteAsyncNotifyCallback();
		}
		return eSUCCESS;
	}		

	
	//СÓÚһҳʣÓà¿Éд×Ö½Ú
	if(wWriteRemainNum <= wPageRemain)
	{
		__SPI_FlashWritePage(uWriteAddr, pData, wWriteRemainNum);
		g_tSpiDevice.wTxOffset += wWriteRemainNum;
		//дÍêÊ£Óà
	}
	else 
	{
		__SPI_FlashWritePage(uWriteAddr, pData, wPageRemain);
		g_tSpiDevice.wTxOffset += wPageRemain;
		//дһÕûÒ³£¬
	}
	//Òì²½¶Áæ
	g_tSpiDevice.tState.eStage = eFLASH_STATE_BUSY;
	return eSUCCESS;
}
//Òì²½¶Áæ×ÓÈÎÎñ
static void __SPI_FlashBusy(void)
{
	//¶Áæ ·Ç×èÈû
	if(SPI_FlashBusyCheck())
	{
		return ;
	}
	//SPIÉϴβÙ×÷ÒÑÍê³É
	//TX process
	if(g_tSpiDevice.tState.bTxReq == TRUE)
	{
		g_tSpiDevice.tState.eStage = eFLASH_STATE_WRITE;
	}
	//RX process
	// TODO ²Á³ýÒÑÍê³É
	if(g_tSpiDevice.tState.bEraseChipReq == TRUE)
	{
		g_tSpiDevice.tState.eStage = eFLASH_STATE_ERASE_CHIP;
	}
	if(g_tSpiDevice.tState.bEraseSectorReq == TRUE)
	{
		g_tSpiDevice.tState.eStage = eFLASH_STATE_ERASE;
	}
}
//Òì²½²Á³ý×ÓÈÎÎñ ÕûƬ
static int32_t __SPI_FlashEraseChip(void)
{
	uint8_t cnt = 0;
	SPI_FLASH_Write_Enable();                  //SET WEL
	if(g_tSpiDevice.tState.bEraseSuccess == TRUE)
	{
		g_tSpiDevice.tState.bEraseSuccess = FALSE;
		g_tSpiDevice.tState.bEraseChipReq = FALSE;
		g_tSpiDevice.tState.eStage = eFLASH_STATE_IDLE;//дÍê³É ת¿ÕÏÐ
		if(g_tSpiDevice.pEraseChipAsyncNotifyCallback)
		{
			////TODO Ò첽֪ͨ»Øµ÷ ¹©µ÷ÓÃÕßʵÏÖ
			g_tSpiDevice.pEraseChipAsyncNotifyCallback();
		}
		return TRUE;
	}
	while((SPI_Flash_Read_SR()&0x2)!=0x2) 
	{
		cnt ++;
		if(cnt >200)
			return FALSE;
	}
	SPI_CS_LOW();                             
	SPI_Flash_ReadWrite_Byte(CHIP_ERASE);        
	SPI_CS_HIGH();                                         
	//SPI_Flash_Wait_Busy(); 
	g_tSpiDevice.tState.eStage = eFLASH_STATE_BUSY;//Òì²½¶Áæ
	return TRUE;
}
//Òì²½²Á³ý×ÓÈÎÎñ 
static int32_t __SPI_FlashErase(void)
{
	uint8_t cnt = 0;	
	//uint32_t uSectorIdxFirst = g_tSpiDevice.uTxDstAddr/SECTOR_SIZE;
	uint32_t uSectorIdxTail = (g_tSpiDevice.uTxDstAddr+g_tSpiDevice.wTxLen)/SECTOR_SIZE;
	uint32_t uCurrentSectorIdx = (g_tSpiDevice.uTxDstAddr + g_tSpiDevice.wTxOffset)/SECTOR_SIZE;
	
	if(uCurrentSectorIdx > uSectorIdxTail)
	{
		g_tSpiDevice.tState.bEraseSectorReq = FALSE;
		g_tSpiDevice.tState.bEraseSuccess = TRUE;
		g_tSpiDevice.tState.eStage = eFLASH_STATE_IDLE;//дÍê³É ת¿ÕÏÐ
		if(g_tSpiDevice.pEraseChipAsyncNotifyCallback)
		{
			////TODO Ò첽֪ͨ»Øµ÷ ¹©µ÷ÓÃÕßʵÏÖ
			g_tSpiDevice.pEraseChipAsyncNotifyCallback();
		}
		return TRUE;
	}
	SPI_FLASH_Write_Enable();                  //SET WEL
	while((SPI_Flash_Read_SR()&0x2)!=0x2) 
	{
		cnt ++;
		if(cnt >200)
			return FALSE;
	}
	SPI_CS_LOW();                            
	SPI_Flash_ReadWrite_Byte(SECTOR_ERASE);      
	SPI_Flash_ReadWrite_Byte((unsigned char)((uCurrentSectorIdx*SECTOR_SIZE)>>16));   
	SPI_Flash_ReadWrite_Byte((unsigned char)((uCurrentSectorIdx*SECTOR_SIZE)>>8));  
	SPI_Flash_ReadWrite_Byte((unsigned char)(uCurrentSectorIdx*SECTOR_SIZE)); 
	SPI_CS_HIGH(); 
	g_tSpiDevice.wTxOffset += SECTOR_SIZE;
	//SPI_Flash_Wait_Busy(); 
	g_tSpiDevice.tState.eStage = eFLASH_STATE_BUSY;//Òì²½¶Áæ
	return TRUE;
}
//¿ÕÏд¦Àí×ÓÈÎÎñ
static void __SPI_FlashIdle(void)
{
	//Æô¶¯¸÷ÏîÈÎÎñ
	if(g_tSpiDevice.tState.bTxReq == TRUE)
	{
		g_tSpiDevice.tState.eStage = eFLASH_STATE_WRITE;
	} 
	else if(g_tSpiDevice.tState.bRxReq == TRUE)
	{
		g_tSpiDevice.tState.eStage = eFLASH_STATE_READ;
	} 
	else if(g_tSpiDevice.tState.bEraseChipReq == TRUE)
	{
		g_tSpiDevice.tState.eStage = eFLASH_STATE_ERASE_CHIP;
	}
	else if(g_tSpiDevice.tState.bEraseSectorReq == TRUE)
	{
		g_tSpiDevice.tState.eStage = eFLASH_STATE_ERASE;
	}
}
//SPIÒì²½²Ù×÷´¦Àí×ÜÈÎÎñ
void SPI_FlashAsyncProcTask(void)
{
	switch(g_tSpiDevice.tState.eStage)
	{
		case eFLASH_STATE_IDLE:
			__SPI_FlashIdle();
			break;
		case eFLASH_STATE_WRITE:
			__SPI_FlashWrite();
			break;
		case eFLASH_STATE_READ:
			//TODO
			break;
		case eFLASH_STATE_BUSY:
			__SPI_FlashBusy();
			break;
		case eFLASH_STATE_ERASE_CHIP:
			__SPI_FlashEraseChip();
			break;
		case eFLASH_STATE_ERASE:
			__SPI_FlashErase();
			break;
		default:
			break;
	}
	
}