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

📄 dataflash.c

📁 AT91BootSAM9261.zip,atmelsam9261微处理器启动初始化源代码
💻 C
📖 第 1 页 / 共 2 页
字号:
//*----------------------------------------------------------------------------
//*         ATMEL Microcontroller Software Support  -  ROUSSET  -
//*----------------------------------------------------------------------------
//* The software is delivered "AS IS" without warranty or condition of any
//* kind, either express, implied or statutory. This includes without
//* limitation any warranty or condition with respect to merchantability or
//* fitness for any particular purpose, or against the infringements of
//* intellectual property rights of others.
//*----------------------------------------------------------------------------
//* File Name           : dataflash.c
//* Object              : High level functions for the dataflash
//*----------------------------------------------------------------------------

#include "main.h"
#include "dataflash.h"

AT91S_DataFlash 		CurrentDataFlash;
unsigned int			SizeToDownload;

extern void AT91F_SpiInit(unsigned int uPCS);
extern void AT91F_Reset_Registers(void);
extern void Remap(void);
extern void AT91F_InitRTT(void);

//*----------------------------------------------------------------------------
//* \fn    AT91F_SpiWrite
//* \brief Set the PDC registers for a transfert
//*----------------------------------------------------------------------------
unsigned int AT91F_SpiWrite ( AT91PS_DataflashDesc pDesc , unsigned int timeout)
{
   	volatile unsigned int tmp = 0;

	pDesc->state = BUSY;

   	AT91C_BASE_SPI0->SPI_PTCR = AT91C_PDC_TXTDIS + AT91C_PDC_RXTDIS;

	// Initialize the Transmit and Receive Pointer
	AT91C_BASE_SPI0->SPI_RPR = (unsigned int)pDesc->rx_cmd_pt ;
	AT91C_BASE_SPI0->SPI_TPR = (unsigned int)pDesc->tx_cmd_pt ;

	// Intialize the Transmit and Receive Counters
	AT91C_BASE_SPI0->SPI_RCR = pDesc->rx_cmd_size;
	AT91C_BASE_SPI0->SPI_TCR = pDesc->tx_cmd_size;

	if ( pDesc->tx_data_size != 0 )
	{
	   	// Initialize the Next Transmit and Next Receive Pointer
	   	AT91C_BASE_SPI0->SPI_RNPR = (unsigned int)pDesc->rx_data_pt ;
		AT91C_BASE_SPI0->SPI_TNPR = (unsigned int)pDesc->tx_data_pt ;

		// Intialize the Next Transmit and Next Receive Counters
		AT91C_BASE_SPI0->SPI_RNCR = pDesc->rx_data_size ;
	 	AT91C_BASE_SPI0->SPI_TNCR = pDesc->tx_data_size ;
   	}

	AT91C_BASE_SPI0->SPI_PTCR = AT91C_PDC_TXTEN + AT91C_PDC_RXTEN;

	// Wait for End of Rx

#ifdef AT91SAM9260
	AT91F_InitRTT();

	do {
		tmp = AT91C_BASE_RTTC->RTTC_RTVR;
	}
	while( !(AT91C_BASE_SPI0->SPI_SR & AT91C_SPI_RXBUFF) && (!tmp) );
#else
	tmp = 0;
	while( !(AT91C_BASE_SPI0->SPI_SR & AT91C_SPI_RXBUFF) && (tmp++ < timeout) );
#endif

   	AT91C_BASE_SPI0->SPI_PTCR = AT91C_PDC_TXTDIS + AT91C_PDC_RXTDIS;
   	pDesc->state = IDLE;

#ifdef AT91SAM9260
	if (tmp)
#else
	if (tmp >= timeout)
#endif
		return AT91C_DATAFLASH_ERROR;

	return AT91C_DATAFLASH_OK;
}


//*----------------------------------------------------------------------
//* \fn    AT91F_DataFlashGetStatus
//* \brief Read the status register of the dataflash
//*----------------------------------------------------------------------
unsigned int AT91F_DataFlashGetStatus(AT91PS_DataflashDesc pDesc)
{
	unsigned int status;

	// if a transfert is in progress ==> return 0 (BUSY)
	if( (pDesc->state) != IDLE)
		return AT91C_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 ;

	// Send Command with TIMEOUT
	status = AT91F_SpiWrite (pDesc,AT91C_DATAFLASH_TIMEOUT);

	// Extract DataFlash Status Register
	pDesc->DataFlash_state = *( (unsigned char *) (pDesc->rx_cmd_pt) +1);

	return status;
}

//*-----------------------------------------------------------------------------
//* Function Name       : AT91F_DataFlashWaitReady
//* \brief
//*-----------------------------------------------------------------------------
unsigned int AT91F_DataFlashWaitReady(AT91PS_DataflashDesc pDataFlashDesc, unsigned int timeout)
{
	volatile unsigned int tmp = 0;

	while( (pDataFlashDesc->state != IDLE) && (tmp++ < timeout) );

	if(pDataFlashDesc->state != IDLE)
		return AT91C_DATAFLASH_ERROR;

	tmp = 0;
	pDataFlashDesc->DataFlash_state = IDLE;
	do
	{
		(volatile unsigned int)AT91F_DataFlashGetStatus(pDataFlashDesc);
		if((pDataFlashDesc->DataFlash_state & 0x80) == 0x80)
			return AT91C_DATAFLASH_OK;
	}
	while(tmp++ < timeout);

	return AT91C_DATAFLASH_ERROR;
}


//*----------------------------------------------------------------------
//* \fn    AT91F_DataFlashSendCommand
//* \brief Generic function to send a command to the dataflash
//*----------------------------------------------------------------------
unsigned int AT91F_DataFlashSendCommand(
	AT91PS_DataFlash pDataFlash,
	unsigned char OpCode,
	unsigned int CmdSize,
	unsigned int DataflashAddress)
{
    unsigned int adr;

	if ( (pDataFlash->DataFlashDesc.state) != IDLE)
		return AT91C_DATAFLASH_BUSY;

	/* process the address to obtain page address and byte address */
	adr = ((DataflashAddress / (pDataFlash->Device.pages_size)) << pDataFlash->Device.page_offset) + (DataflashAddress % (pDataFlash->Device.pages_size));

	/* fill the  command  buffer */
	pDataFlash->DataFlashDesc.command[0] = OpCode;
	if (pDataFlash->Device.pages_number >= 16384)
	{
		pDataFlash->DataFlashDesc.command[1] = (unsigned char)((adr & 0x0F000000) >> 24);
		pDataFlash->DataFlashDesc.command[2] = (unsigned char)((adr & 0x00FF0000) >> 16);
		pDataFlash->DataFlashDesc.command[3] = (unsigned char)((adr & 0x0000FF00) >> 8);
		pDataFlash->DataFlashDesc.command[4] = (unsigned char)(adr & 0x000000FF);
	}
	else
	{
		pDataFlash->DataFlashDesc.command[1] = (unsigned char)((adr & 0x00FF0000) >> 16);
		pDataFlash->DataFlashDesc.command[2] = (unsigned char)((adr & 0x0000FF00) >> 8);
		pDataFlash->DataFlashDesc.command[3] = (unsigned char)(adr & 0x000000FF) ;
		pDataFlash->DataFlashDesc.command[4] = 0;
	}
	pDataFlash->DataFlashDesc.command[5] = 0;
	pDataFlash->DataFlashDesc.command[6] = 0;
	pDataFlash->DataFlashDesc.command[7] = 0;

	/* Initialize the SpiData structure for the spi write fuction */
	pDataFlash->DataFlashDesc.tx_cmd_pt   =  pDataFlash->DataFlashDesc.command ;
	pDataFlash->DataFlashDesc.tx_cmd_size =  CmdSize ;
	pDataFlash->DataFlashDesc.rx_cmd_pt   =  pDataFlash->DataFlashDesc.command ;
	pDataFlash->DataFlashDesc.rx_cmd_size =  CmdSize ;

	return AT91F_SpiWrite ( &(pDataFlash->DataFlashDesc) ,AT91C_DATAFLASH_TIMEOUT);
}

//*------------------------------------------------------------------------------
//* Function Name       	: AT91F_DataFlashContinuousRead
//* Object              	: Continuous stream Read
//* Input Parameters 	: DataFlash Structure
//*						: <src> = dataflash address
//*                     	: <*dataBuffer> = data buffer pointer
//*                     	: <sizeToRead> = data buffer size
//* Return value			: State of the dataflash
//*------------------------------------------------------------------------------
unsigned int AT91F_DataFlashContinuousRead (
 	AT91PS_DataFlash pDataFlash,
	unsigned int src,
	unsigned char *dataBuffer,
	unsigned int sizeToRead )
{
	unsigned int status;
	// Test the size to read in the device
	if ( (src + sizeToRead) > (pDataFlash->Device.pages_size * (pDataFlash->Device.pages_number)))
		return AT91C_DATAFLASH_MEMORY_OVERFLOW;

	pDataFlash->DataFlashDesc.rx_data_pt = dataBuffer;
	pDataFlash->DataFlashDesc.rx_data_size = sizeToRead;
	pDataFlash->DataFlashDesc.tx_data_pt = dataBuffer;
	pDataFlash->DataFlashDesc.tx_data_size = sizeToRead;

	// Send the command to the dataflash
	status = AT91F_DataFlashSendCommand (pDataFlash, DB_CONTINUOUS_ARRAY_READ, 8, src);

	return(status);
}

//*------------------------------------------------------------------------------
//* Function Name       AT91F_DataFlashRead
//* \brief				Read a block in dataflash
//*------------------------------------------------------------------------------
int AT91F_DataFlashRead(
	AT91PS_DataFlash pDataFlash,
	unsigned int addr,
	unsigned char *buffer,
	unsigned int size)
{
	unsigned int SizeToRead;

	while (size)
	{
		SizeToRead = (size < AT91C_MAX_PDC_SIZE)? size:AT91C_MAX_PDC_SIZE;

		// wait the dataflash ready status
		if(AT91F_DataFlashWaitReady( &(CurrentDataFlash.DataFlashDesc) ,AT91C_DATAFLASH_TIMEOUT) != AT91C_DATAFLASH_OK)
			return FALSE;

⌨️ 快捷键说明

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