📄 dataflash.c
字号:
//*----------------------------------------------------------------------------
//* 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 + -