diff options
| author | Jean-Christophe PLAGNIOL-VILLARD <plagnioj@jcrosoft.com> | 2007-11-24 21:26:56 +0100 | 
|---|---|---|
| committer | Jean-Christophe PLAGNIOL-VILLARD <plagnioj@jcrosoft.com> | 2007-11-25 23:28:52 +0100 | 
| commit | 59829cc189378c142c13d2aa8d9a897d8bef3961 (patch) | |
| tree | 9db7b0647e82c7d3edbd33caa89a71eb4e123d0c /drivers/mtd/at45.c | |
| parent | 318c0b90431f2648552e5ade78833f42652ce859 (diff) | |
| download | olio-uboot-2014.01-59829cc189378c142c13d2aa8d9a897d8bef3961.tar.xz olio-uboot-2014.01-59829cc189378c142c13d2aa8d9a897d8bef3961.zip | |
drivers/mtd : move mtd drivers to drivers/mtd
Signed-off-by: Jean-Christophe PLAGNIOL-VILLARD <plagnioj@jcrosoft.com>
Diffstat (limited to 'drivers/mtd/at45.c')
| -rw-r--r-- | drivers/mtd/at45.c | 562 | 
1 files changed, 562 insertions, 0 deletions
| diff --git a/drivers/mtd/at45.c b/drivers/mtd/at45.c new file mode 100644 index 000000000..dac987a43 --- /dev/null +++ b/drivers/mtd/at45.c @@ -0,0 +1,562 @@ +/* Driver for ATMEL DataFlash support + * Author : Hamid Ikdoumi (Atmel) + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + */ + +#include <config.h> +#include <common.h> + +#ifdef CONFIG_HAS_DATAFLASH +#include <dataflash.h> + +/* + * spi.c API + */ +extern unsigned int AT91F_SpiWrite(AT91PS_DataflashDesc pDesc); +extern void AT91F_SpiEnable(int cs); + +#define AT91C_TIMEOUT_WRDY			200000 + +/*----------------------------------------------------------------------*/ +/* \fn    AT91F_DataFlashSendCommand					*/ +/* \brief Generic function to send a command to the dataflash		*/ +/*----------------------------------------------------------------------*/ +AT91S_DataFlashStatus AT91F_DataFlashSendCommand(AT91PS_DataFlash pDataFlash, +						 unsigned char OpCode, +						 unsigned int CmdSize, +						 unsigned int DataflashAddress) +{ +	unsigned int adr; + +	if ((pDataFlash->pDataFlashDesc->state) != IDLE) +		return DATAFLASH_BUSY; + +	/* process the address to obtain page address and byte address */ +	adr = ((DataflashAddress / (pDataFlash->pDevice->pages_size)) << +		pDataFlash->pDevice->page_offset) + +			(DataflashAddress % (pDataFlash->pDevice->pages_size)); + +	/* fill the command buffer */ +	pDataFlash->pDataFlashDesc->command[0] = OpCode; +	if (pDataFlash->pDevice->pages_number >= 16384) { +		pDataFlash->pDataFlashDesc->command[1] = +			(unsigned char)((adr & 0x0F000000) >> 24); +		pDataFlash->pDataFlashDesc->command[2] = +			(unsigned char)((adr & 0x00FF0000) >> 16); +		pDataFlash->pDataFlashDesc->command[3] = +			(unsigned char)((adr & 0x0000FF00) >> 8); +		pDataFlash->pDataFlashDesc->command[4] = +			(unsigned char)(adr & 0x000000FF); +	} else { +		pDataFlash->pDataFlashDesc->command[1] = +			(unsigned char)((adr & 0x00FF0000) >> 16); +		pDataFlash->pDataFlashDesc->command[2] = +			(unsigned char)((adr & 0x0000FF00) >> 8); +		pDataFlash->pDataFlashDesc->command[3] = +			(unsigned char)(adr & 0x000000FF); +		pDataFlash->pDataFlashDesc->command[4] = 0; +	} +	pDataFlash->pDataFlashDesc->command[5] = 0; +	pDataFlash->pDataFlashDesc->command[6] = 0; +	pDataFlash->pDataFlashDesc->command[7] = 0; + +	/* Initialize the SpiData structure for the spi write fuction */ +	pDataFlash->pDataFlashDesc->tx_cmd_pt = +		pDataFlash->pDataFlashDesc->command; +	pDataFlash->pDataFlashDesc->tx_cmd_size = CmdSize; +	pDataFlash->pDataFlashDesc->rx_cmd_pt = +		pDataFlash->pDataFlashDesc->command; +	pDataFlash->pDataFlashDesc->rx_cmd_size = CmdSize; + +	/* send the command and read the data */ +	return AT91F_SpiWrite(pDataFlash->pDataFlashDesc); +} + +/*----------------------------------------------------------------------*/ +/* \fn    AT91F_DataFlashGetStatus					*/ +/* \brief Read the status register of the dataflash			*/ +/*----------------------------------------------------------------------*/ +AT91S_DataFlashStatus AT91F_DataFlashGetStatus(AT91PS_DataflashDesc pDesc) +{ +	AT91S_DataFlashStatus status; + +	/* if a transfert is in progress ==> return 0 */ +	if ((pDesc->state) != IDLE) +		return DATAFLASH_BUSY; + +	/* first send the read status command (D7H) */ +	pDesc->command[0] = DB_STATUS; +	pDesc->command[1] = 0; + +	pDesc->DataFlash_state = GET_STATUS; +	pDesc->tx_data_size = 0;	/* Transmit the command */ +	/* and receive response */ +	pDesc->tx_cmd_pt = pDesc->command; +	pDesc->rx_cmd_pt = pDesc->command; +	pDesc->rx_cmd_size = 2; +	pDesc->tx_cmd_size = 2; +	status = AT91F_SpiWrite(pDesc); + +	pDesc->DataFlash_state = *((unsigned char *)(pDesc->rx_cmd_pt) + 1); + +	return status; +} + +/*----------------------------------------------------------------------*/ +/* \fn    AT91F_DataFlashWaitReady					*/ +/* \brief wait for dataflash ready (bit7 of the status register == 1)	*/ +/*----------------------------------------------------------------------*/ +AT91S_DataFlashStatus AT91F_DataFlashWaitReady(AT91PS_DataflashDesc +						pDataFlashDesc, +						unsigned int timeout) +{ +	pDataFlashDesc->DataFlash_state = IDLE; + +	do { +		AT91F_DataFlashGetStatus(pDataFlashDesc); +		timeout--; +	} while (((pDataFlashDesc->DataFlash_state & 0x80) != 0x80) && +		 (timeout > 0)); + +	if ((pDataFlashDesc->DataFlash_state & 0x80) != 0x80) +		return DATAFLASH_ERROR; + +	return DATAFLASH_OK; +} + +/*--------------------------------------------------------------------------*/ +/* Function Name       : AT91F_DataFlashContinuousRead 			    */ +/* Object              : Continuous stream Read 			    */ +/* Input Parameters    : DataFlash Service				    */ +/*						: <src> = dataflash address */ +/*                     : <*dataBuffer> = data buffer pointer		    */ +/*                     : <sizeToRead> = data buffer size		    */ +/* Return value		: State of the dataflash			    */ +/*--------------------------------------------------------------------------*/ +AT91S_DataFlashStatus AT91F_DataFlashContinuousRead( +				AT91PS_DataFlash pDataFlash, +				int src, +				unsigned char *dataBuffer, +				int sizeToRead) +{ +	AT91S_DataFlashStatus status; +	/* Test the size to read in the device */ +	if ((src + sizeToRead) > +			(pDataFlash->pDevice->pages_size * +				(pDataFlash->pDevice->pages_number))) +		return DATAFLASH_MEMORY_OVERFLOW; + +	pDataFlash->pDataFlashDesc->rx_data_pt = dataBuffer; +	pDataFlash->pDataFlashDesc->rx_data_size = sizeToRead; +	pDataFlash->pDataFlashDesc->tx_data_pt = dataBuffer; +	pDataFlash->pDataFlashDesc->tx_data_size = sizeToRead; + +	status = AT91F_DataFlashSendCommand( +			pDataFlash, DB_CONTINUOUS_ARRAY_READ, 8, src); +	/* Send the command to the dataflash */ +	return (status); +} + +/*---------------------------------------------------------------------------*/ +/* Function Name       : AT91F_DataFlashPagePgmBuf			     */ +/* Object              : Main memory page program thru buffer 1 or buffer 2  */ +/* Input Parameters    : DataFlash Service				     */ +/*						: <*src> = Source buffer     */ +/*                     : <dest> = dataflash destination address		     */ +/*                     : <SizeToWrite> = data buffer size		     */ +/* Return value		: State of the dataflash			     */ +/*---------------------------------------------------------------------------*/ +AT91S_DataFlashStatus AT91F_DataFlashPagePgmBuf(AT91PS_DataFlash pDataFlash, +						unsigned char *src, +						unsigned int dest, +						unsigned int SizeToWrite) +{ +	int cmdsize; +	pDataFlash->pDataFlashDesc->tx_data_pt = src; +	pDataFlash->pDataFlashDesc->tx_data_size = SizeToWrite; +	pDataFlash->pDataFlashDesc->rx_data_pt = src; +	pDataFlash->pDataFlashDesc->rx_data_size = SizeToWrite; + +	cmdsize = 4; +	/* Send the command to the dataflash */ +	if (pDataFlash->pDevice->pages_number >= 16384) +		cmdsize = 5; +	return (AT91F_DataFlashSendCommand( +			pDataFlash, DB_PAGE_PGM_BUF1, cmdsize, dest)); +} + +/*---------------------------------------------------------------------------*/ +/* Function Name       : AT91F_MainMemoryToBufferTransfert		     */ +/* Object              : Read a page in the SRAM Buffer 1 or 2		     */ +/* Input Parameters    : DataFlash Service				     */ +/*                     : Page concerned					     */ +/*                     : 						     */ +/* Return value		: State of the dataflash			     */ +/*---------------------------------------------------------------------------*/ +AT91S_DataFlashStatus AT91F_MainMemoryToBufferTransfert( +					AT91PS_DataFlash +					pDataFlash, +					unsigned char +					BufferCommand, +					unsigned int page) +{ +	int cmdsize; +	/* Test if the buffer command is legal */ +	if ((BufferCommand != DB_PAGE_2_BUF1_TRF) && +			(BufferCommand != DB_PAGE_2_BUF2_TRF)) { +		return DATAFLASH_BAD_COMMAND; +	} + +	/* no data to transmit or receive */ +	pDataFlash->pDataFlashDesc->tx_data_size = 0; +	cmdsize = 4; +	if (pDataFlash->pDevice->pages_number >= 16384) +		cmdsize = 5; +	return (AT91F_DataFlashSendCommand( +			pDataFlash, BufferCommand, cmdsize, +			page * pDataFlash->pDevice->pages_size)); +} + +/*-------------------------------------------------------------------------- */ +/* Function Name       : AT91F_DataFlashWriteBuffer			     */ +/* Object              : Write data to the internal sram buffer 1 or 2	     */ +/* Input Parameters    : DataFlash Service				     */ +/*			: <BufferCommand> = command to write buffer1 or 2    */ +/*                     : <*dataBuffer> = data buffer to write		     */ +/*                     : <bufferAddress> = address in the internal buffer    */ +/*                     : <SizeToWrite> = data buffer size		     */ +/* Return value		: State of the dataflash			     */ +/*---------------------------------------------------------------------------*/ +AT91S_DataFlashStatus AT91F_DataFlashWriteBuffer( +					AT91PS_DataFlash pDataFlash, +					unsigned char BufferCommand, +					unsigned char *dataBuffer, +					unsigned int bufferAddress, +					int SizeToWrite) +{ +	int cmdsize; +	/* Test if the buffer command is legal */ +	if ((BufferCommand != DB_BUF1_WRITE) && +			(BufferCommand != DB_BUF2_WRITE)) { +		return DATAFLASH_BAD_COMMAND; +	} + +	/* buffer address must be lower than page size */ +	if (bufferAddress > pDataFlash->pDevice->pages_size) +		return DATAFLASH_BAD_ADDRESS; + +	if ((pDataFlash->pDataFlashDesc->state) != IDLE) +		return DATAFLASH_BUSY; + +	/* Send first Write Command */ +	pDataFlash->pDataFlashDesc->command[0] = BufferCommand; +	pDataFlash->pDataFlashDesc->command[1] = 0; +	if (pDataFlash->pDevice->pages_number >= 16384) { +		pDataFlash->pDataFlashDesc->command[2] = 0; +		pDataFlash->pDataFlashDesc->command[3] = +			(unsigned char)(((unsigned int)(bufferAddress & +							pDataFlash->pDevice-> +							byte_mask)) >> 8); +		pDataFlash->pDataFlashDesc->command[4] = +			(unsigned char)((unsigned int)bufferAddress & 0x00FF); +		cmdsize = 5; +	} else { +		pDataFlash->pDataFlashDesc->command[2] = +			(unsigned char)(((unsigned int)(bufferAddress & +							pDataFlash->pDevice-> +							byte_mask)) >> 8); +		pDataFlash->pDataFlashDesc->command[3] = +			(unsigned char)((unsigned int)bufferAddress & 0x00FF); +		pDataFlash->pDataFlashDesc->command[4] = 0; +		cmdsize = 4; +	} + +	pDataFlash->pDataFlashDesc->tx_cmd_pt = +		pDataFlash->pDataFlashDesc->command; +	pDataFlash->pDataFlashDesc->tx_cmd_size = cmdsize; +	pDataFlash->pDataFlashDesc->rx_cmd_pt = +		pDataFlash->pDataFlashDesc->command; +	pDataFlash->pDataFlashDesc->rx_cmd_size = cmdsize; + +	pDataFlash->pDataFlashDesc->rx_data_pt = dataBuffer; +	pDataFlash->pDataFlashDesc->tx_data_pt = dataBuffer; +	pDataFlash->pDataFlashDesc->rx_data_size = SizeToWrite; +	pDataFlash->pDataFlashDesc->tx_data_size = SizeToWrite; + +	return AT91F_SpiWrite(pDataFlash->pDataFlashDesc); +} + +/*---------------------------------------------------------------------------*/ +/* Function Name       : AT91F_PageErase                                     */ +/* Object              : Erase a page 					     */ +/* Input Parameters    : DataFlash Service				     */ +/*                     : Page concerned					     */ +/*                     : 						     */ +/* Return value		: State of the dataflash			     */ +/*---------------------------------------------------------------------------*/ +AT91S_DataFlashStatus AT91F_PageErase( +					AT91PS_DataFlash pDataFlash, +					unsigned int page) +{ +	int cmdsize; +	/* Test if the buffer command is legal */ +	/* no data to transmit or receive */ +	pDataFlash->pDataFlashDesc->tx_data_size = 0; + +	cmdsize = 4; +	if (pDataFlash->pDevice->pages_number >= 16384) +		cmdsize = 5; +	return (AT91F_DataFlashSendCommand(pDataFlash, +				DB_PAGE_ERASE, cmdsize, +				page * pDataFlash->pDevice->pages_size)); +} + +/*---------------------------------------------------------------------------*/ +/* Function Name       : AT91F_BlockErase                                    */ +/* Object              : Erase a Block 					     */ +/* Input Parameters    : DataFlash Service				     */ +/*                     : Page concerned					     */ +/*                     : 						     */ +/* Return value		: State of the dataflash			     */ +/*---------------------------------------------------------------------------*/ +AT91S_DataFlashStatus AT91F_BlockErase( +				AT91PS_DataFlash pDataFlash, +				unsigned int block) +{ +	int cmdsize; +	/* Test if the buffer command is legal */ +	/* no data to transmit or receive */ +	pDataFlash->pDataFlashDesc->tx_data_size = 0; +	cmdsize = 4; +	if (pDataFlash->pDevice->pages_number >= 16384) +		cmdsize = 5; +	return (AT91F_DataFlashSendCommand(pDataFlash, DB_BLOCK_ERASE, cmdsize, +					block * 8 * +					pDataFlash->pDevice->pages_size)); +} + +/*---------------------------------------------------------------------------*/ +/* Function Name       : AT91F_WriteBufferToMain			     */ +/* Object              : Write buffer to the main memory		     */ +/* Input Parameters    : DataFlash Service				     */ +/*		: <BufferCommand> = command to send to buffer1 or buffer2    */ +/*                     : <dest> = main memory address			     */ +/* Return value		: State of the dataflash			     */ +/*---------------------------------------------------------------------------*/ +AT91S_DataFlashStatus AT91F_WriteBufferToMain(AT91PS_DataFlash pDataFlash, +					unsigned char BufferCommand, +					unsigned int dest) +{ +	int cmdsize; +	/* Test if the buffer command is correct */ +	if ((BufferCommand != DB_BUF1_PAGE_PGM) && +			(BufferCommand != DB_BUF1_PAGE_ERASE_PGM) && +			(BufferCommand != DB_BUF2_PAGE_PGM) && +			(BufferCommand != DB_BUF2_PAGE_ERASE_PGM)) +		return DATAFLASH_BAD_COMMAND; + +	/* no data to transmit or receive */ +	pDataFlash->pDataFlashDesc->tx_data_size = 0; + +	cmdsize = 4; +	if (pDataFlash->pDevice->pages_number >= 16384) +		cmdsize = 5; +	/* Send the command to the dataflash */ +	return (AT91F_DataFlashSendCommand(pDataFlash, BufferCommand, +						cmdsize, dest)); +} + +/*---------------------------------------------------------------------------*/ +/* Function Name       : AT91F_PartialPageWrite				     */ +/* Object              : Erase partielly a page				     */ +/* Input Parameters    : <page> = page number				     */ +/*			: <AdrInpage> = adr to begin the fading		     */ +/*                     : <length> = Number of bytes to erase		     */ +/*---------------------------------------------------------------------------*/ +AT91S_DataFlashStatus AT91F_PartialPageWrite(AT91PS_DataFlash pDataFlash, +					unsigned char *src, +					unsigned int dest, +					unsigned int size) +{ +	unsigned int page; +	unsigned int AdrInPage; + +	page = dest / (pDataFlash->pDevice->pages_size); +	AdrInPage = dest % (pDataFlash->pDevice->pages_size); + +	/* Read the contents of the page in the Sram Buffer */ +	AT91F_MainMemoryToBufferTransfert(pDataFlash, DB_PAGE_2_BUF1_TRF, page); +	AT91F_DataFlashWaitReady(pDataFlash->pDataFlashDesc, +				 AT91C_TIMEOUT_WRDY); +	/*Update the SRAM buffer */ +	AT91F_DataFlashWriteBuffer(pDataFlash, DB_BUF1_WRITE, src, +					AdrInPage, size); + +	AT91F_DataFlashWaitReady(pDataFlash->pDataFlashDesc, +					AT91C_TIMEOUT_WRDY); + +	/* Erase page if a 128 Mbits device */ +	if (pDataFlash->pDevice->pages_number >= 16384) { +		AT91F_PageErase(pDataFlash, page); +		/* Rewrite the modified Sram Buffer in the main memory */ +		AT91F_DataFlashWaitReady(pDataFlash->pDataFlashDesc, +					 AT91C_TIMEOUT_WRDY); +	} + +	/* Rewrite the modified Sram Buffer in the main memory */ +	return (AT91F_WriteBufferToMain(pDataFlash, DB_BUF1_PAGE_ERASE_PGM, +					(page * +					 pDataFlash->pDevice->pages_size))); +} + +/*---------------------------------------------------------------------------*/ +/* Function Name       : AT91F_DataFlashWrite				     */ +/* Object              :						     */ +/* Input Parameters    : <*src> = Source buffer				     */ +/*                     : <dest> = dataflash adress			     */ +/*                     : <size> = data buffer size			     */ +/*---------------------------------------------------------------------------*/ +AT91S_DataFlashStatus AT91F_DataFlashWrite(AT91PS_DataFlash pDataFlash, +						unsigned char *src, +						int dest, int size) +{ +	unsigned int length; +	unsigned int page; +	unsigned int status; + +	AT91F_SpiEnable(pDataFlash->pDevice->cs); + +	if ((dest + size) > (pDataFlash->pDevice->pages_size * +			(pDataFlash->pDevice->pages_number))) +		return DATAFLASH_MEMORY_OVERFLOW; + +	/* If destination does not fit a page start address */ +	if ((dest % ((unsigned int)(pDataFlash->pDevice->pages_size))) != 0) { +		length = +			pDataFlash->pDevice->pages_size - +			(dest % ((unsigned int)(pDataFlash->pDevice->pages_size))); + +		if (size < length) +			length = size; + +		if (!AT91F_PartialPageWrite(pDataFlash, src, dest, length)) +			return DATAFLASH_ERROR; + +		AT91F_DataFlashWaitReady(pDataFlash->pDataFlashDesc, +					 AT91C_TIMEOUT_WRDY); + +		/* Update size, source and destination pointers */ +		size -= length; +		dest += length; +		src += length; +	} + +	while ((size - pDataFlash->pDevice->pages_size) >= 0) { +		/* program dataflash page */ +		page = (unsigned int)dest / (pDataFlash->pDevice->pages_size); + +		status = AT91F_DataFlashWriteBuffer(pDataFlash, +					DB_BUF1_WRITE, src, 0, +					pDataFlash->pDevice-> +					pages_size); +		AT91F_DataFlashWaitReady(pDataFlash->pDataFlashDesc, +					 AT91C_TIMEOUT_WRDY); + +		status = AT91F_PageErase(pDataFlash, page); +		AT91F_DataFlashWaitReady(pDataFlash->pDataFlashDesc, +					 AT91C_TIMEOUT_WRDY); +		if (!status) +			return DATAFLASH_ERROR; + +		status = AT91F_WriteBufferToMain(pDataFlash, +					 DB_BUF1_PAGE_PGM, dest); +		if (!status) +			return DATAFLASH_ERROR; + +		AT91F_DataFlashWaitReady(pDataFlash->pDataFlashDesc, +					 AT91C_TIMEOUT_WRDY); + +		/* Update size, source and destination pointers */ +		size -= pDataFlash->pDevice->pages_size; +		dest += pDataFlash->pDevice->pages_size; +		src += pDataFlash->pDevice->pages_size; +	} + +	/* If still some bytes to read */ +	if (size > 0) { +		/* program dataflash page */ +		if (!AT91F_PartialPageWrite(pDataFlash, src, dest, size)) +			return DATAFLASH_ERROR; + +		AT91F_DataFlashWaitReady(pDataFlash->pDataFlashDesc, +					 AT91C_TIMEOUT_WRDY); +	} +	return DATAFLASH_OK; +} + +/*---------------------------------------------------------------------------*/ +/* Function Name       : AT91F_DataFlashRead 				     */ +/* Object              : Read a block in dataflash			     */ +/* Input Parameters    : 						     */ +/* Return value		: 						     */ +/*---------------------------------------------------------------------------*/ +int AT91F_DataFlashRead(AT91PS_DataFlash pDataFlash, +			unsigned long addr, unsigned long size, char *buffer) +{ +	unsigned long SizeToRead; + +	AT91F_SpiEnable(pDataFlash->pDevice->cs); + +	if (AT91F_DataFlashWaitReady(pDataFlash->pDataFlashDesc, +					AT91C_TIMEOUT_WRDY) != DATAFLASH_OK) +		return -1; + +	while (size) { +		SizeToRead = (size < 0x8000) ? size : 0x8000; + +		if (AT91F_DataFlashWaitReady(pDataFlash->pDataFlashDesc, +					AT91C_TIMEOUT_WRDY) != +						DATAFLASH_OK) +			return -1; + +		if (AT91F_DataFlashContinuousRead(pDataFlash, addr, +						(uchar *) buffer, +						SizeToRead) != DATAFLASH_OK) +			return -1; + +		size -= SizeToRead; +		addr += SizeToRead; +		buffer += SizeToRead; +	} + +	return DATAFLASH_OK; +} + +/*---------------------------------------------------------------------------*/ +/* Function Name       : AT91F_DataflashProbe 				     */ +/* Object              : 						     */ +/* Input Parameters    : 						     */ +/* Return value	       : Dataflash status register			     */ +/*---------------------------------------------------------------------------*/ +int AT91F_DataflashProbe(int cs, AT91PS_DataflashDesc pDesc) +{ +	AT91F_SpiEnable(cs); +	AT91F_DataFlashGetStatus(pDesc); +	return ((pDesc->command[1] == 0xFF) ? 0 : pDesc->command[1] & 0x3C); +} +#endif |