⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 at45.c

📁 U-boot源码 ARM7启动代码
💻 C
📖 第 1 页 / 共 2 页
字号:
/* 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);

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -