📄 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 + -