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

📄 at45.c

📁 (1)基于部分u-boot代码自己调试的vxworks BSP (2)实现了nand/nor flash的tffs文件系统 (3)实现了对spi dataflash的访问 (4)实现了对启动参数
💻 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           : at45c.h
 Object              : 

 1.0 10/12/03 HIi    : Creation
----------------------------------------------------------------------------*/
#include "AT91RM9200.h"
#include "lib_AT91RM9200.h"

#define AT91C_SPI_CLK 5000000
#define AT91C_SPI_PCS0_SERIAL_DATAFLASH		0xE     /* Chip Select 0 : NPCS0 %1110 */
#define AT91C_SPI_PCS3_DATAFLASH_CARD		0x7     /* Chip Select 3 : NPCS3 %0111 */


/*----------------------------------------------------------------------------*/
/* \fn    AT91F_SpiInit						      							  */
/* \brief SPI Low level Init												  */
/*----------------------------------------------------------------------------*/
void AT91F_SpiInit(void) {
	/* Configure PIOs */
	AT91C_BASE_PIOA->PIO_ASR = AT91C_PA3_NPCS0 | AT91C_PA4_NPCS1 | AT91C_PA1_MOSI | AT91C_PA5_NPCS2 |
				   AT91C_PA6_NPCS3 | AT91C_PA0_MISO | AT91C_PA2_SPCK;
	AT91C_BASE_PIOA->PIO_PDR = AT91C_PA3_NPCS0 | AT91C_PA4_NPCS1 | AT91C_PA1_MOSI | AT91C_PA5_NPCS2 |
				   AT91C_PA6_NPCS3 | AT91C_PA0_MISO | AT91C_PA2_SPCK;
	/* Enable CLock */
	AT91C_BASE_PMC->PMC_PCER = 1 << AT91C_ID_SPI;

	/* Reset the SPI */
	AT91C_BASE_SPI->SPI_CR = AT91C_SPI_SWRST;

    	/* Configure SPI in Master Mode with No CS selected !!! */
	AT91C_BASE_SPI->SPI_MR = AT91C_SPI_MSTR | AT91C_SPI_MODFDIS | AT91C_SPI_PCS;

	/* Configure CS0 and CS3 */
	*(AT91C_SPI_CSR + 0) = AT91C_SPI_CPOL | (AT91C_SPI_DLYBS & 0x100000) | ((AT91C_MASTER_CLOCK / (2*AT91C_SPI_CLK)) << 8);

	*(AT91C_SPI_CSR + 3) = AT91C_SPI_CPOL | (AT91C_SPI_DLYBS & 0x100000) | ((AT91C_MASTER_CLOCK / (2*AT91C_SPI_CLK)) << 8);

}


/*----------------------------------------------------------------------------*/
/* \fn    AT91F_SpiEnable					      							  */
/* \brief Enable SPI chip select											  */
/*----------------------------------------------------------------------------*/
void AT91F_SpiEnable(int cs) {
	switch(cs) {
	case 0:	/* Configure SPI CS0 for Serial DataFlash AT45DBxx */
		AT91C_BASE_SPI->SPI_MR &= 0xFFF0FFFF;
		AT91C_BASE_SPI->SPI_MR |= ((AT91C_SPI_PCS0_SERIAL_DATAFLASH<<16) & AT91C_SPI_PCS);
		break;
	case 3:	/* Configure SPI CS3 for Serial DataFlash Card */
		/* Set up PIO SDC_TYPE to switch on DataFlash Card and not MMC/SDCard */
		AT91C_BASE_PIOB->PIO_PER = AT91C_PIO_PB7;	/* Set in PIO mode */
		AT91C_BASE_PIOB->PIO_OER = AT91C_PIO_PB7;	/* Configure in output */
		/* Clear Output */
		AT91C_BASE_PIOB->PIO_CODR = AT91C_PIO_PB7;
		/* Configure PCS */
		AT91C_BASE_SPI->SPI_MR &= 0xFFF0FFFF;
		AT91C_BASE_SPI->SPI_MR |= ((AT91C_SPI_PCS3_DATAFLASH_CARD<<16) & AT91C_SPI_PCS);
		break;
	}

	/* SPI_Enable */
	AT91C_BASE_SPI->SPI_CR = AT91C_SPI_SPIEN;
}

/*----------------------------------------------------------------------------*/
/* \fn    AT91F_SpiWrite						                              */
/* \brief Set the PDC registers for a transfert				                  */
/*----------------------------------------------------------------------------*/
unsigned int AT91F_SpiWrite ( AT91PS_DataflashDesc pDesc)
{
   	unsigned int timeout;
	
	pDesc->state = BUSY;

   	AT91C_BASE_SPI->SPI_PTCR = AT91C_PDC_TXTDIS + AT91C_PDC_RXTDIS;

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

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

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

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

     /* arm simple, non interrupt dependent timer */
	timeout = 0;

	AT91C_BASE_SPI->SPI_PTCR = AT91C_PDC_TXTEN + AT91C_PDC_RXTEN;
	while(!(AT91C_BASE_SPI->SPI_SR & AT91C_SPI_RXBUFF));

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

	if (timeout >= AT91C_DATAFLASH_TIMEOUT){
		return AT91C_DATAFLASH_ERROR;
	}

	return AT91C_DATAFLASH_OK;
}


/*----------------------------------------------------------------------*/
/* \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 AT91C_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 ;

	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 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 ;
    	status = AT91F_SpiWrite (pDesc);

	pDesc->DataFlash_state = *( (unsigned char *) (pDesc->rx_cmd_pt) +1);
	return status;
}

#if 0
/*----------------------------------------------------------------------*/
/* fn    AT91F_DataFlashExtID											*/
/* brief Read the extended ID											*/
/*----------------------------------------------------------------------*/
AT91S_DataFlashStatus AT91F_DataFlashExtID(
	AT91PS_DataflashDesc pDesc)
	
{
	AT91S_DataFlashStatus status;

	/* if a transfert is in progress ==> return 0 */
	if( (pDesc->state) != IDLE)
		return AT91C_DATAFLASH_BUSY;

	/* first send the read status command (D7H) */
	pDesc->command[0] = 0x9F;
	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 	= 5 ;
    	pDesc->tx_cmd_size 	= 5 ;
    	status = AT91F_SpiWrite (pDesc);

	pDesc->DataFlash_state = *( (unsigned char *) (pDesc->rx_cmd_pt) +1);

	return status;
}
#endif


/*----------------------------------------------------------------------*/
/* \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 AT91C_DATAFLASH_ERROR;
	
	return AT91C_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 AT91C_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_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;

⌨️ 快捷键说明

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