📄 obj_svcdataflash.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 : obj_svcdataflash.c
//* Object : Atmel AT45DBxxx DataFlash service.
//*
//* 1.0 14/01/02 HI : Creation
//* 1.2 08/10/02 FB HI : New structure
//*---------------------------------------------------------------------------
#include "services\obj_romboot.h"
#include "services\obj_svcdataflash.h"
#define AT91C_SPI_RXBUFF ((unsigned int) 0x1 << 6)
#define AT91C_SPI_TXBUFE ((unsigned int) 0x1 << 7)
//*-----------------------------------------------------------------------------
//* Function Name : AT91F_SpiWrite
//* Object : set the PDC registers for a transfert
//* Input Parameters : DataFlash Descriptor
//* Output Parameters : none
//* Functions called : none
//*-----------------------------------------------------------------------------
static void AT91F_SpiWrite ( AT91PS_DataflashDesc pDesc )
{
pDesc->state = BUSY;
//* Initialize the Transmit and Receive Pointer
SPI_BASE->SP_RPR = (u_int)pDesc->rx_cmd_pt ;
SPI_BASE->SP_TPR = (u_int)pDesc->tx_cmd_pt ;
//* Intialize the Transmit and Receive Counters
SPI_BASE->SP_RCR = pDesc->rx_cmd_size ;
SPI_BASE->SP_TCR = pDesc->tx_cmd_size ;
if ( pDesc->tx_data_size != 0 )
{
//* Initialize the Next Transmit and Next Receive Pointer
SPI_BASE->SP_RNPR = (u_int)pDesc->rx_data_pt ;
SPI_BASE->SP_TNPR = (u_int)pDesc->tx_data_pt ;
//* Intialize the Next Transmit and Next Receive Counters
SPI_BASE->SP_RNCR = pDesc->rx_data_size ;
SPI_BASE->SP_TNCR = pDesc->tx_data_size ;
}
//* Enable RXBUFF Interrupt
SPI_BASE->SP_IER = AT91C_SPI_RXBUFF;
SPI_BASE->SP_PTCR = PDC_TXTEN + PDC_RXTEN;
}
//*-----------------------------------------------------------------------------
//* Function Name : AT91F_DataFlashHandler
//* Object : SPI Fixed Peripheral C interrupt handler.
//* Input Parameters : DataFlash Service, status parameter
//* Output Parameters : none
//* Functions called : none
//*-----------------------------------------------------------------------------
void AT91F_DataFlashHandler(
AT91PS_SvcDataFlash pSvcDataFlash,
u_int status)
{
AT91PS_DataflashDesc pDesc = (AT91PS_DataflashDesc) &(pSvcDataFlash->DataFlashDesc) ;
//* If End of Receive Transfer interrupt occurred
if (( status & AT91C_SPI_RXBUFF))
{
if( pDesc->state == BUSY)
{
//* Next State
pDesc->state = IDLE;
if (pDesc->DataFlash_state == GET_STATUS)
pDesc->DataFlash_state = *( (u_char *) (pDesc->rx_cmd_pt) +1);
//* Disable the Transmit Interrupt
SPI_BASE->SP_IDR = AT91C_SPI_RXBUFF;
SPI_BASE->SP_PTCR = PDC_TXTDIS + PDC_RXTDIS;
return;
}
}
pDesc->state = ERROR;
SPI_BASE->SP_PTCR = PDC_TXTDIS + PDC_RXTDIS;
SPI_BASE->SP_IDR = status;
}
//*-----------------------------------------------------------------------------
//* Function Name : AT91F_OpenSvcDataFlash
//* Object : Open the DataFlash service
//* Input Parameters : DataFlash Service , APMC Base
//* Output Parameters : The service structure initialized
//* Functions called : none
//*-----------------------------------------------------------------------------
AT91PS_SvcDataFlash AT91F_OpenSvcDataFlash (
const AT91PS_APMC pApmc,
AT91PS_SvcDataFlash pSvcDataFlash)
{
pSvcDataFlash->Handler = AT91F_DataFlashHandler;
pSvcDataFlash->Status = AT91F_DataFlashGetStatus;
pSvcDataFlash->AbortCommand = AT91F_DataFlashAbortCommand;
pSvcDataFlash->PageRead = AT91F_DataFlashPageRead;
pSvcDataFlash->ContinuousRead = AT91F_DataFlashContinuousRead;
pSvcDataFlash->ReadBuffer = AT91F_DataFlashReadBuffer;
pSvcDataFlash->MainMemoryToBufferTransfert = AT91F_MainMemoryToBufferTransfert;
pSvcDataFlash->PagePgmBuf = AT91F_DataFlashPagePgmBuf;
pSvcDataFlash->WriteBuffer = AT91F_DataFlashWriteBuffer;
pSvcDataFlash->WriteBufferToMain = AT91F_WriteBufferToMain;
pSvcDataFlash->PageErase = AT91F_PageErase;
pSvcDataFlash->BlockErase = AT91F_BlockErase;
pSvcDataFlash->MainMemoryToBufferCompare = AT91F_MainMemoryToBufferCompare;
return pSvcDataFlash;
}
//*-----------------------------------------------------------------------------
//* Function Name : AT91F_DataFlashAbortCommand
//* Object : Allows to reset PDC & Interrupts
//* Input Parameters : DataFlash Descriptor
//* Return value : none
//*-----------------------------------------------------------------------------
void AT91F_DataFlashAbortCommand(AT91PS_DataflashDesc pDesc)
{
int status;
status = ( SPI_BASE->SP_SR & SPI_BASE->SP_IMR );
pDesc->state = IDLE;
SPI_BASE->SP_PTCR = PDC_TXTDIS + PDC_RXTDIS;
SPI_BASE->SP_IDR = status;
}
//*-----------------------------------------------------------------------------
//* Function Name : AT91F_DataFlashGetStatus
//* Object : Read the status register of the dataflash
//* Input Parameters : DataFlash Descriptor
//* Return value : State of the dataflash
//*-----------------------------------------------------------------------------
AT91S_SvcDataFlashStatus AT91F_DataFlashGetStatus(AT91PS_DataflashDesc pDesc)
{
//* 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 ;
AT91F_SpiWrite (pDesc);
return DATAFLASH_OK;
}
//*-----------------------------------------------------------------------------
//* Function Name : AT91F_DataFlashSendCommand
//* Object : Generic function to send a command to the dataflash
//* Input Parameters : DataFlash Service
//* : <OpCode> = command operation code
//* : <CmdSize> = size of the command
//* : <DataflashAddress> = address associate to the command
//* Return value : State of the dataflash
//*-----------------------------------------------------------------------------
AT91S_SvcDataFlashStatus AT91F_DataFlashSendCommand (
AT91PS_SvcDataFlash pSvcDataFlash,
u_char OpCode,
u_int CmdSize,
u_int DataflashAddress)
{
u_int adr;
if ( (pSvcDataFlash->DataFlashDesc.state) != IDLE)
return DATAFLASH_BUSY;
//* process the address to obtain page address and byte address
adr = ((DataflashAddress / (pSvcDataFlash->pDevice->pages_size)) << pSvcDataFlash->pDevice->page_offset) + (DataflashAddress % (pSvcDataFlash->pDevice->pages_size));
//* fill the command buffer */
pSvcDataFlash->DataFlashDesc.command[0] = OpCode;
pSvcDataFlash->DataFlashDesc.command[1] = (u_char)((adr & 0x00FF0000) >> 16);
pSvcDataFlash->DataFlashDesc.command[2] = (u_char)((adr & 0x0000FF00) >> 8);
pSvcDataFlash->DataFlashDesc.command[3] = (u_char)(adr & 0x000000FF) ;
pSvcDataFlash->DataFlashDesc.command[4] = 0;
pSvcDataFlash->DataFlashDesc.command[5] = 0;
pSvcDataFlash->DataFlashDesc.command[6] = 0;
pSvcDataFlash->DataFlashDesc.command[7] = 0;
/* Initialize the SpiData structure for the spi write fuction */
pSvcDataFlash->DataFlashDesc.tx_cmd_pt = pSvcDataFlash->DataFlashDesc.command ;
pSvcDataFlash->DataFlashDesc.tx_cmd_size = CmdSize ;
pSvcDataFlash->DataFlashDesc.rx_cmd_pt = pSvcDataFlash->DataFlashDesc.command ;
pSvcDataFlash->DataFlashDesc.rx_cmd_size = CmdSize ;
/* send the command and read the data */
AT91F_SpiWrite (&(pSvcDataFlash->DataFlashDesc));
return DATAFLASH_OK;
}
///////////////////////////////////////////////////////////////////////////////////////////
// Read Functions
///////////////////////////////////////////////////////////////////////////////////////////
//*-----------------------------------------------------------------------------
//* Function Name : AT91F_DataFlashPageRead
//* Object : Main memory page read
//* Input Parameters : DataFlash Service
//* : <src> = dataflash address
//* : <*dataBuffer> = data buffer pointer
//* : <sizeToRead> = Number of bytes to read
//* Return value : State of the dataflash
//*-----------------------------------------------------------------------------
AT91S_SvcDataFlashStatus AT91F_DataFlashPageRead (
AT91PS_SvcDataFlash pSvcDataFlash,
u_int src,
u_char *dataBuffer,
int sizeToRead )
{
pSvcDataFlash->DataFlashDesc.rx_data_pt = dataBuffer ; /* buffer for the read operation*/
pSvcDataFlash->DataFlashDesc.rx_data_size = sizeToRead; /* Number of byte to read */
pSvcDataFlash->DataFlashDesc.tx_data_pt = dataBuffer ;
pSvcDataFlash->DataFlashDesc.tx_data_size = sizeToRead;
/* Send the command to the dataflash */
return (AT91F_DataFlashSendCommand (pSvcDataFlash, DB_PAGE_READ, 8, src));
}
//*-----------------------------------------------------------------------------
//* 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_SvcDataFlashStatus AT91F_DataFlashContinuousRead (
AT91PS_SvcDataFlash pSvcDataFlash,
int src,
u_char *dataBuffer,
int sizeToRead )
{
//* Test the size to read in the device
if ( (src + sizeToRead) > (pSvcDataFlash->pDevice->pages_size * (pSvcDataFlash->pDevice->pages_number)))
return DATAFLASH_MEMORY_OVERFLOW;
pSvcDataFlash->DataFlashDesc.rx_data_pt = dataBuffer;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -