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;index200)
				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; index200)
				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; index0)
		{
			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; index200)
					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; indexSPI异步操作
 *************************************************************************************************/

/*****************************************************************************************                    									       	
º¯ÊýÃû³Æ: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;
	}
	
}
	

 
  
 
  
 
   
  
 
  
 
  
 
  
 
 

你可能感兴趣的:(arm/裸机)