/****************************************************************************** * * Copyright (C) 2012 - 2014 Xilinx, Inc. All rights reserved. * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * Use of the Software is limited solely to applications: * (a) running on a Xilinx device, or * (b) that interact with a Xilinx device through a bus or interconnect. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * XILINX CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. * * Except as contained in this notice, the name of the Xilinx shall not be used * in advertising or otherwise to promote the sale, use or other dealings in * this Software without prior written authorization from Xilinx. * ******************************************************************************/ /*****************************************************************************/ /** * * @file xilisf_read.c * * This file contains the library functions to read data from the Serial Flash * devices. Refer xilisf.h for detailed description. * *
*
* MODIFICATION HISTORY:
*
* Ver   Who      Date     Changes
* ----- -------  -------- -----------------------------------------------
* 1.00a ksu/sdm  03/03/08 First release
* 2.01a sdm      01/04/10 Added Support for Winbond W25QXX/W25XX devices
* 2.04a sdm      08/17/10 Updated to support Numonyx (N25QXX) and Spansion
*			  flash memories
* 5.0   sb	 08/05/14 Updated support for > 128 MB flash for PSQSPI
*			  interface.
*			  Changed API:
*				ReadData()
*				FastReadData()
* 
* ******************************************************************************/ /***************************** Include Files *********************************/ #include "include/xilisf.h" /************************** Constant Definitions *****************************/ #define FAST_READ_NUM_DUMMY_BYTES 1 #define SIXTEENMB 0x1000000 /**< Sixteen MB */ #define BANKMASK 0xF000000 /**< Bank mask */ /**************************** Type Definitions *******************************/ /***************** Macros (Inline Functions) Definitions *********************/ /************************** Function Prototypes ******************************/ extern int XIsf_Transfer(XIsf *InstancePtr, u8 *WritePtr, u8* ReadPtr, u32 ByteCount); extern u32 GetRealAddr(XIsf_Iface *QspiPtr, u32 Address); #ifdef XPAR_XISF_INTERFACE_PSQSPI extern int SendBankSelect(XIsf *InstancePtr, u32 BankSel); #endif static int ReadData(XIsf *InstancePtr, u32 Address, u8 *ReadPtr, u32 ByteCount); static int FastReadData(XIsf *InstancePtr, u8 Command, u32 Address, u8 *ReadPtr, u32 ByteCount, int NumDummyBytes); static int FlashToBufTransfer(XIsf *InstancePtr, u8 BufferNum, u32 Address); static int BufferRead(XIsf *InstancePtr, u8 BufferNum, u8 *ReadPtr, u32 ByteOffset, u32 NumBytes); static int FastBufferRead(XIsf *InstancePtr, u8 BufferNum, u8 *ReadPtr, u32 ByteOffset, u32 NumBytes); static int ReadOTPData(XIsf *InstancePtr, u32 Address, u8 *ReadPtr, u32 ByteCount); /************************** Variable Definitions *****************************/ extern u32 XIsf_StatusEventInfo; extern unsigned int XIsf_ByteCountInfo; /************************** Function Definitions ******************************/ /*****************************************************************************/ /** * * This API reads the data from the Serial Flash. * * @param InstancePtr is a pointer to the XIsf instance. * @param Operation is the type of the read operation to be performed on * the Serial Flash. * The different operations are - XISF_READ: Normal Read * - XISF_FAST_READ: Fast Read * - XISF_PAGE_TO_BUF_TRANS: Page to Buffer Transfer * - XISF_BUFFER_READ: Buffer Read * - XISF_FAST_BUFFER_READ: Fast Buffer Read * - XISF_OTP_READ: One Time Programmable Area (OTP) Read * - XISF_DUAL_OP_FAST_READ: Dual Output Fast Read * - XISF_DUAL_IO_FAST_READ: Dual Input/Output Fast Read * - XISF_QUAD_OP_FAST_READ: Quad Output Fast Read * - XISF_QUAD_IO_FAST_READ: Quad Input/Output Fast Read * @param OpParamPtr is the pointer to structure variable which contains * operational parameter of specified Operation. This parameter * type is dependant on the type of Operation to be performed. * * - Normal Read (XISF_READ), Fast Read (XISF_FAST_READ), * One Time Programmable Area Read(XISF_OTP_READ), Dual Output * Fast Read (XISF_CMD_DUAL_OP_FAST_READ), Dual Input/Output * Fast Read (XISF_CMD_DUAL_IO_FAST_READ), Quad Output Fast Read * (XISF_CMD_QUAD_OP_FAST_READ) and Quad Input/Output Fast Read * (XISF_CMD_QUAD_IO_FAST_READ): * The OpParamPtr must be of type struct XIsf_ReadParam. * OpParamPtr->Address is start address in the Serial Flash. * OpParamPtr->ReadPtr is a pointer to the memory where the data * read from the Serial Flash is stored. * OpParamPtr->NumBytes is number of bytes to read. * OpParamPtr->NumDummyBytes is the number of dummy bytes to be * transmitted for the Read command. This parameter is only used * in case of Dual and Quad reads. * Normal Read and Fast Read operations are supported for Atmel, * Intel, STM, Winbond and Spansion Serial Flash. * Dual and quad reads are supported for Winbond (W25QXX), Numonyx * (N25QXX) and Spansion (S25FL129) quad flash. * OTP Read operation is only supported in Intel Serial Flash. * * - Page To Buffer Transfer (XISF_PAGE_TO_BUF_TRANS): * The OpParamPtr must be of type struct * XIsf_FlashToBufTransferParam . * OpParamPtr->BufferNum specifies the internal SRAM Buffer of * the Serial Flash. The valid values are XISF_PAGE_BUFFER1 * or XISF_PAGE_BUFFER2. XISF_PAGE_BUFFER2 is not valid in case * of AT45DB011D Flash as it contains a single buffer. * OpParamPtr->Address is start address in the Serial Flash. * This operation is only supported in Atmel Serial Flash. * * - Buffer Read (XISF_BUFFER_READ) and Fast Buffer Read * (XISF_FAST_BUFFER_READ): * The OpParamPtr must be of type struct XIsf_BufferReadParam. * OpParamPtr->BufferNum specifies the internal SRAM Buffer of * the Serial Flash. The valid values are XISF_PAGE_BUFFER1 * or XISF_PAGE_BUFFER2. XISF_PAGE_BUFFER2 is not valid in case of * AT45DB011D Flash as it contains a single buffer. * OpParamPtr->ReadPtr is pointer to the memory where data read * from the SRAM buffer is to be stored. * OpParamPtr->ByteOffset is byte offset in the SRAM buffer from * where the first byte is read. * OpParamPtr->NumBytes is the number of bytes to be read from the * Buffer. * These operations are supported only in Atmel Serial Flash. * * @return XST_SUCCESS if successful else XST_FAILURE. * * @note * - Application must fill the structure elements of the third * argument and pass its pointer by type casting it with void * pointer. * - The valid data is available from the fourth location pointed * to by the ReadPtr for Normal Read and Buffer Read operations. * - The valid data is available from fifth location pointed to * by the ReadPtr for Fast Read, Fast Buffer Read and OTP Read * operations. * - The valid data is available from the (4 + NumDummyBytes)th * location pointed to by ReadPtr for Dual/Quad Read operations. * ******************************************************************************/ int XIsf_Read(XIsf *InstancePtr, XIsf_ReadOperation Operation, void *OpParamPtr) { int Status = (int)(XST_FAILURE); u8 Mode; XIsf_ReadParam *ReadParamPtr; XIsf_FlashToBufTransferParam *FlashToBufTransferParamPtr; XIsf_BufferReadParam *BufferReadParamPtr; if (InstancePtr == NULL) { return (int)(XST_FAILURE); } if (InstancePtr->IsReady != TRUE) { return (int)(XST_FAILURE); } if (NULL == OpParamPtr) { return (int)(XST_FAILURE); } switch (Operation) { case XISF_READ: ReadParamPtr = (XIsf_ReadParam*) OpParamPtr; Status = ReadData(InstancePtr, ReadParamPtr->Address, ReadParamPtr->ReadPtr, ReadParamPtr->NumBytes); break; case XISF_FAST_READ: ReadParamPtr = (XIsf_ReadParam*)(void *) OpParamPtr; Xil_AssertNonvoid(ReadParamPtr != NULL); Status = FastReadData(InstancePtr, XISF_CMD_FAST_READ, ReadParamPtr->Address, ReadParamPtr->ReadPtr, ReadParamPtr->NumBytes, ReadParamPtr->NumDummyBytes); break; case XISF_PAGE_TO_BUF_TRANS: FlashToBufTransferParamPtr = (XIsf_FlashToBufTransferParam*)(void *) OpParamPtr; Xil_AssertNonvoid(FlashToBufTransferParamPtr != NULL); Status = FlashToBufTransfer(InstancePtr, FlashToBufTransferParamPtr->BufferNum, FlashToBufTransferParamPtr->Address); break; case XISF_BUFFER_READ: BufferReadParamPtr = (XIsf_BufferReadParam*)(void *) OpParamPtr; Xil_AssertNonvoid(BufferReadParamPtr != NULL); Status = BufferRead(InstancePtr, BufferReadParamPtr->BufferNum, BufferReadParamPtr->ReadPtr, BufferReadParamPtr->ByteOffset, BufferReadParamPtr->NumBytes); break; case XISF_FAST_BUFFER_READ: BufferReadParamPtr = (XIsf_BufferReadParam*)(void *) OpParamPtr; Xil_AssertNonvoid(BufferReadParamPtr != NULL); Status = FastBufferRead(InstancePtr, BufferReadParamPtr->BufferNum, BufferReadParamPtr->ReadPtr, BufferReadParamPtr->ByteOffset, BufferReadParamPtr->NumBytes); break; case XISF_OTP_READ: ReadParamPtr = (XIsf_ReadParam*)(void *) OpParamPtr; Xil_AssertNonvoid(ReadParamPtr != NULL); Status = ReadOTPData(InstancePtr, ReadParamPtr->Address, ReadParamPtr->ReadPtr, ReadParamPtr->NumBytes); break; #if ((XPAR_XISF_FLASH_FAMILY == WINBOND) || (XPAR_XISF_FLASH_FAMILY == STM) \ || (XPAR_XISF_FLASH_FAMILY == SPANSION)) case XISF_DUAL_OP_FAST_READ: ReadParamPtr = (XIsf_ReadParam*)(void *) OpParamPtr; Xil_AssertNonvoid(ReadParamPtr != NULL); Status = FastReadData(InstancePtr, XISF_CMD_DUAL_OP_FAST_READ, ReadParamPtr->Address, ReadParamPtr->ReadPtr, ReadParamPtr->NumBytes, ReadParamPtr->NumDummyBytes); break; case XISF_DUAL_IO_FAST_READ: ReadParamPtr = (XIsf_ReadParam*)(void *) OpParamPtr; Xil_AssertNonvoid(ReadParamPtr != NULL); Status = FastReadData(InstancePtr, XISF_CMD_DUAL_IO_FAST_READ, ReadParamPtr->Address, ReadParamPtr->ReadPtr, ReadParamPtr->NumBytes, ReadParamPtr->NumDummyBytes); break; case XISF_QUAD_OP_FAST_READ: ReadParamPtr = (XIsf_ReadParam*)(void *) OpParamPtr; Xil_AssertNonvoid(ReadParamPtr != NULL); Status = FastReadData(InstancePtr, XISF_CMD_QUAD_OP_FAST_READ, ReadParamPtr->Address, ReadParamPtr->ReadPtr, ReadParamPtr->NumBytes, ReadParamPtr->NumDummyBytes); break; case XISF_QUAD_IO_FAST_READ: ReadParamPtr = (XIsf_ReadParam*)(void *) OpParamPtr; Xil_AssertNonvoid(ReadParamPtr != NULL); Status = FastReadData(InstancePtr, XISF_CMD_QUAD_IO_FAST_READ, ReadParamPtr->Address, ReadParamPtr->ReadPtr, ReadParamPtr->NumBytes, ReadParamPtr->NumDummyBytes); break; #endif /*((XPAR_XISF_FLASH_FAMILY == WINBOND) || (XPAR_XISF_FLASH_FAMILY == STM) || (XPAR_XISF_FLASH_FAMILY == SPANSION))*/ default: break; } /* * Get the Transfer Mode */ Mode = XIsf_GetTransferMode(InstancePtr); if(Mode == XISF_INTERRUPT_MODE){ InstancePtr->StatusHandler(InstancePtr, XIsf_StatusEventInfo, XIsf_ByteCountInfo); } return Status; } /*****************************************************************************/ /** * * This function reads data from the Serial Flash. * * @param InstancePtr is a pointer to the XIsf instance. * @param Address is the starting address in the Serial Flash from where * the data is to be read. * @param ReadPtr is a pointer to the memory where the data read from * the Serial Flash is stored. * @param ByteCount is the number of bytes to be read from the Serial * Flash. * * @return XST_SUCCESS if successful else XST_FAILURE. * * @note * - This operation is supported for Atmel, Intel, STM, Winbond * and Spansion Serial Flash. * - Minimum of one byte and a maximum of an entire Serial Flash * Array can be read. * - The valid data is available from the fourth location pointed * to by the ReadPtr. * ******************************************************************************/ static int ReadData(XIsf *InstancePtr, u32 Address, u8 *ReadPtr, u32 ByteCount) { u8 Mode; u32 BankSel; u32 RealAddr; int Status; u32 RealByteCnt; u32 BufferIndex; u8 ShiftSize; u32 TotalByteCnt = ByteCount; u32 LocalByteCnt = ByteCount; u32 LocalAddress = Address; u8 WriteBuffer[5] = {0}; if (LocalByteCnt <= 0 ) { return (int)XST_FAILURE; } if (ReadPtr == NULL) { return (int)XST_FAILURE; } while(((s32)(LocalByteCnt)) > 0) { /* * Translate address based on type of connection * If stacked assert the slave select based on address */ RealAddr = GetRealAddr(InstancePtr->SpiInstPtr, LocalAddress); #ifdef XPAR_XISF_INTERFACE_PSQSPI if(InstancePtr->DeviceIDMemSize > 0x18U) { /* * Get the Transfer Mode */ Mode = XIsf_GetTransferMode(InstancePtr); /* * Seting the transfer mode to Polled Mode before * performing the Bank Select operation. */ XIsf_SetTransferMode(InstancePtr, XISF_POLLING_MODE); BankSel = RealAddr/SIXTEENMB; (void)SendBankSelect(InstancePtr, BankSel); /* * Restoring the transfer mode back */ XIsf_SetTransferMode(InstancePtr, Mode); } /* * If data to be read spans beyond the current bank, then * calculate RealByteCnt in current bank. Else * RealByteCnt is the same as ByteCount */ if((RealAddr & BANKMASK) != ((RealAddr+LocalByteCnt) & BANKMASK)) { RealByteCnt = ((RealAddr & BANKMASK) + SIXTEENMB) - RealAddr; } else { #endif RealByteCnt = LocalByteCnt; #ifdef XPAR_XISF_INTERFACE_PSQSPI } #endif WriteBuffer[BYTE1] = XISF_CMD_RANDOM_READ; WriteBuffer[BYTE2] = (u8)((RealAddr & 0xFF0000) >> XISF_ADDR_SHIFT16); WriteBuffer[BYTE3] = (u8)((RealAddr & 0xFF00) >> XISF_ADDR_SHIFT8); WriteBuffer[BYTE4] = (u8)(RealAddr & 0xFF); Status = XIsf_Transfer(InstancePtr, WriteBuffer, &(ReadPtr[TotalByteCnt - LocalByteCnt]), RealByteCnt + XISF_CMD_SEND_EXTRA_BYTES); if (Status != (int)(XST_SUCCESS)) { return (int)XST_FAILURE; } #ifdef XPAR_XISF_INTERFACE_PSQSPI /* * To discard the first 4 dummy bytes, shift the data in read buffer */ ShiftSize = XISF_CMD_SEND_EXTRA_BYTES; BufferIndex = (TotalByteCnt - LocalByteCnt); for(; BufferIndex < ((TotalByteCnt - LocalByteCnt) + RealByteCnt); BufferIndex++) { ReadPtr[BufferIndex] = ReadPtr[BufferIndex + ShiftSize]; } /* * Increase address to next bank */ LocalAddress = (LocalAddress & BANKMASK) + SIXTEENMB; #endif /* * Decrease byte count by bytes already read. */ LocalByteCnt = LocalByteCnt - RealByteCnt; } return (int)XST_SUCCESS; } /*****************************************************************************/ /** * * This function reads data from the Serial Flash at a higher speed than normal * Read operation. * * @param InstancePtr is a pointer to the XIsf instance. * @param Command is the fast read command used to read data from the * flash. It could be one of XISF_CMD_DUAL/QUAD_*_FAST_READ or * XISF_CMD_FAST_READ. * @param Address is the starting address in the Serial Flash from where * the data is to be read. * @param ReadPtr is a pointer to the memory where the data read from * the Serial Flash is stored. * @param ByteCount is the number of bytes to be read from the Serial * Flash. * @param NumDummyBytes is the number of dummy bytes associated with the * fast read commands. * * @return XST_SUCCESS if successful else XST_FAILURE. * * @note * - XISF_CMD_FAST_READ operation is supported for Atmel, Intel, * STM, Winbond and Spansion Serial Flash. * - XISF_CMD_DUAL/QUAD_*_FAST_READ operations are supported on * Winbond (W25QXX), Numonyx (N25QXX) and Spansion (S25FL129) * quad flash devices. * - Minimum of one byte and a maximum of an entire Serial Flash * Array can be read. * - The valid data is available from the (4 + NumDummyBytes)th * location pointed to by the ReadPtr. * ******************************************************************************/ static int FastReadData(XIsf *InstancePtr, u8 Command, u32 Address, u8 *ReadPtr, u32 ByteCount, int NumDummyBytes) { u8 Mode; int Index; int Status; u32 BankSel; u32 RealAddr; u32 RealByteCnt; u32 BufferIndex; u8 ShiftSize; u32 TotalByteCnt = ByteCount; u32 LocalByteCnt = ByteCount; u32 LocalAddress = Address; u8 WriteBuffer[5]= {0}; if (LocalByteCnt <= 0 ) { return (int)XST_FAILURE; } if (ReadPtr == NULL) { return (int)(XST_FAILURE); } if (NumDummyBytes <= 0) { return (int)(XST_FAILURE); } while(((s32)(LocalByteCnt)) > 0) { /* * Translate address based on type of connection * If stacked assert the slave select based on address */ RealAddr = GetRealAddr(InstancePtr->SpiInstPtr, LocalAddress); #ifdef XPAR_XISF_INTERFACE_PSQSPI if(InstancePtr->DeviceIDMemSize > 0x18U) { /* * Get the Transfer Mode */ Mode = XIsf_GetTransferMode(InstancePtr); /* * Seting the transfer mode to Polled Mode before * performing the Bank Select operation. */ XIsf_SetTransferMode(InstancePtr, XISF_POLLING_MODE); BankSel = RealAddr/SIXTEENMB; (void)SendBankSelect(InstancePtr, BankSel); /* * Restoring the transfer mode back */ XIsf_SetTransferMode(InstancePtr, Mode); } /* * If data to be read spans beyond the current bank, then * calculate RealByteCnt in current bank. Else * RealByteCnt is the same as ByteCount */ if((RealAddr & BANKMASK) != ((RealAddr+LocalByteCnt) & BANKMASK)) { RealByteCnt = ((RealAddr & BANKMASK) + SIXTEENMB) - RealAddr; } else { #endif RealByteCnt = LocalByteCnt; #ifdef XPAR_XISF_INTERFACE_PSQSPI } #endif WriteBuffer[BYTE1] = Command; WriteBuffer[BYTE2] = (u8) (RealAddr >> XISF_ADDR_SHIFT16); WriteBuffer[BYTE3] = (u8) (RealAddr >> XISF_ADDR_SHIFT8); WriteBuffer[BYTE4] = (u8) RealAddr; for (Index = 0; Index < NumDummyBytes; Index++) { WriteBuffer[Index + BYTE5] = (u8) (XISF_DUMMYBYTE); } RealByteCnt += NumDummyBytes; /* * Initiate the Transfer. */ Status = (int)XIsf_Transfer(InstancePtr, WriteBuffer, &(ReadPtr[TotalByteCnt - LocalByteCnt]), RealByteCnt + XISF_CMD_SEND_EXTRA_BYTES); if (Status != (int)(XST_SUCCESS)) { return (int)(XST_FAILURE); } #ifdef XPAR_XISF_INTERFACE_PSQSPI /* * To discard the first 5 dummy bytes, shift the data in read buffer */ ShiftSize = XISF_CMD_SEND_EXTRA_BYTES + (u8)NumDummyBytes; BufferIndex = (TotalByteCnt - LocalByteCnt); for(; BufferIndex < ((TotalByteCnt - LocalByteCnt) + RealByteCnt); BufferIndex++) { ReadPtr[BufferIndex] = ReadPtr[BufferIndex + ShiftSize]; } /* * Increase address to next bank */ LocalAddress = (LocalAddress & BANKMASK) + SIXTEENMB; #endif /* * Decrease byte count by bytes already read. */ LocalByteCnt = LocalByteCnt - (RealByteCnt - NumDummyBytes); } return (int)XST_SUCCESS; } /*****************************************************************************/ /** * * This function copies the data from the Serial Flash to the specified SRAM * buffer. * * @param InstancePtr is a pointer to the XIsf instance. * @param BufferNum specifies the internal SRAM Buffer to which the data * from Serial Flash is to be transferred. The valid values are * XISF_PAGE_BUFFER1 or XISF_PAGE_BUFFER2. XISF_PAGE_BUFFER2 is * not valid in the case of AT45DB011D Flash as it contains a * single buffer. * @param Address specifies any address within the Page of the Serial * Flash from where the Page of data is to be copied. * Byte address in this Address is ignored as an entire Page of * data is transferred/copied. * * @return XST_SUCCESS if successful else XST_FAILURE. * * @note * - This operation is only supported in Atmel Serial Flash. * - This function reads one complete Page from the Serial Flash. * - Read the Spartan-3AN In-system Flash User Guide/Atmel * AT45XXXD Data sheets for more information. * ******************************************************************************/ static int FlashToBufTransfer(XIsf *InstancePtr, u8 BufferNum, u32 Address) { int Status = (int)(XST_FAILURE); Xil_AssertNonvoid(InstancePtr != NULL); Xil_AssertNonvoid(Address != 0); Xil_AssertNonvoid(BufferNum != 0); #if (XPAR_XISF_FLASH_FAMILY == ATMEL) /* * Check whether the buffer number is valid or not. */ if ((BufferNum == XISF_PAGE_BUFFER1) || (BufferNum == XISF_PAGE_BUFFER2)) { if ((InstancePtr->DeviceCode == XISF_ATMEL_DEV_AT45DB011D) && (BufferNum != XISF_PAGE_BUFFER1)) { return (int)(XST_FAILURE); } } else { return (int)(XST_FAILURE); } if (BufferNum == XISF_PAGE_BUFFER1) { /* * Page to Buffer 1 Transfer. */ InstancePtr->WriteBufPtr[BYTE1] = XISF_CMD_PAGETOBUF1_TRANS; } else { /* * Page to Buffer 2 Transfer. */ InstancePtr->WriteBufPtr[BYTE1] = XISF_CMD_PAGETOBUF2_TRANS; } InstancePtr->WriteBufPtr[BYTE2] = (u8)(Address >> XISF_ADDR_SHIFT16); InstancePtr->WriteBufPtr[BYTE3] = (u8)(Address >> XISF_ADDR_SHIFT8); InstancePtr->WriteBufPtr[BYTE4] = (u8)(XISF_DUMMYBYTE); /* * Initiate the Transfer. */ Status = XIsf_Transfer(InstancePtr, InstancePtr->WriteBufPtr, NULL, XISF_CMD_SEND_EXTRA_BYTES); if (Status != (int)(XST_SUCCESS)) { return (int)(XST_FAILURE); } #endif /* (XPAR_XISF_FLASH_FAMILY == ATMEL) */ return Status; } /*****************************************************************************/ /** * * This function reads the data available in the SRAM buffer of Serial Flash. * * @param InstancePtr is a pointer to the XIsf instance. * @param BufferNum specifies the internal SRAM Buffer from which data * is to be read. The valid values are XISF_PAGE_BUFFER1 or * XISF_PAGE_BUFFER2. XISF_PAGE_BUFFER2 is not valid in case of * AT45DB011D Flash as it contains a single buffer. * @param ReadPtr is a pointer to the memory where the data read from the * SRAM buffer is stored. * @param ByteOffset is the byte offset in the buffer from where the * first byte is read. * @param NumBytes is the number of bytes to be read from the Buffer. * * @return XST_SUCCESS if successful else XST_FAILURE. * * @note * - This operation is only supported in Atmel Serial Flash. * - This function reads a Minimum of one Byte and a Maximum of an * entire SRAM buffer (1 Page) from the Serial Flash. * - The valid data is available from the fourth location pointed * to by the ReadPtr. * - Read the Spartan-3AN In-system Flash User Guide/Atmel * AT45XXXD Data sheets for more information. * ******************************************************************************/ static int BufferRead(XIsf *InstancePtr, u8 BufferNum, u8 *ReadPtr, u32 ByteOffset, u32 NumBytes) { int Status = (int)(XST_FAILURE); Xil_AssertNonvoid(InstancePtr != NULL); Xil_AssertNonvoid(BufferNum != 0); Xil_AssertNonvoid(ReadPtr != NULL); Xil_AssertNonvoid(ByteOffset != 0); Xil_AssertNonvoid(NumBytes != 0); #if (XPAR_XISF_FLASH_FAMILY == ATMEL) /* * Check if the buffer number is valid or not. */ if ((BufferNum == XISF_PAGE_BUFFER1) || (BufferNum == XISF_PAGE_BUFFER2)) { if ((InstancePtr->DeviceCode == XISF_ATMEL_DEV_AT45DB011D) && (BufferNum != XISF_PAGE_BUFFER1)) { return (int)(XST_FAILURE); } } else { return (int)(XST_FAILURE); } if (ReadPtr == NULL) { return (int)(XST_FAILURE); } if (ByteOffset > InstancePtr->BytesPerPage){ return (int)(XST_FAILURE); } if ((NumBytes <= 0) || (NumBytes > InstancePtr->BytesPerPage)) { return (int)(XST_FAILURE); } if (BufferNum == XISF_PAGE_BUFFER1) { ReadPtr[BYTE1] = XISF_CMD_BUF1_READ; /* Buffer 1 Read. */ } else { ReadPtr[BYTE1] = XISF_CMD_BUF2_READ; /* Buffer 2 Read.*/ } ReadPtr[BYTE2] = (u8) (0x00); ReadPtr[BYTE3] = (u8) (ByteOffset >> XISF_ADDR_SHIFT8); ReadPtr[BYTE4] = (u8) ByteOffset; /* * Initiate the Transfer. */ Status = XIsf_Transfer(InstancePtr, ReadPtr, ReadPtr, NumBytes + XISF_CMD_SEND_EXTRA_BYTES); if (Status != (int)(XST_SUCCESS)) { return (int)(XST_FAILURE); } #endif /* (XPAR_XISF_FLASH_FAMILY == ATMEL) */ return Status; } /*****************************************************************************/ /** * * This function reads the data from the internal SRAM page buffer of the Serial * Flash memory at higher speed than normal Buffer Read operation. * * @param InstancePtr is a pointer to the XIsf instance. * @param BufferNum specifies the internal SRAM Buffer from which data * is to be read. The valid values are XISF_PAGE_BUFFER1 or * XISF_PAGE_BUFFER2. XISF_PAGE_BUFFER2 is not valid in case of * AT45DB011D Flash as it contains a single buffer. * @param ReadPtr is a pointer to the memory where the data read from the * SRAM buffer is stored. * @param ByteOffset is the byte offset in the buffer from where the * first byte is read. * @param NumBytes is the number of bytes to be read from the Buffer. * * @return XST_SUCCESS if successful else XST_FAILURE. * * @note * - This operation is only supported in Atmel Serial Flash. * - This function reads a Minimum of one Byte and a Maximum of an * entire SRAM buffer (1 Page) from the Serial Flash. * - The valid data is available from the fifth location pointed * to by the ReadPtr. * - Read the Spartan-3AN In-system Flash User Guide/Atmel * AT45XXXD Data sheets for more information. * ******************************************************************************/ static int FastBufferRead(XIsf *InstancePtr, u8 BufferNum, u8 *ReadPtr, u32 ByteOffset, u32 NumBytes) { int Status = (int)(XST_FAILURE); Xil_AssertNonvoid(InstancePtr != NULL); Xil_AssertNonvoid(BufferNum != 0); Xil_AssertNonvoid(ReadPtr != NULL); Xil_AssertNonvoid(ByteOffset != 0); Xil_AssertNonvoid(NumBytes != 0); #if (XPAR_XISF_FLASH_FAMILY == ATMEL) /* * Check if the buffer number is valid or not. */ if ((BufferNum == XISF_PAGE_BUFFER1) || (BufferNum == XISF_PAGE_BUFFER2)) { if ((InstancePtr->DeviceCode == XISF_ATMEL_DEV_AT45DB011D) && (BufferNum != XISF_PAGE_BUFFER1)) { return (int)(XST_FAILURE); } } else { return (int)(XST_FAILURE); } if (ReadPtr == NULL) { return (int)(XST_FAILURE); } if (ByteOffset > InstancePtr->BytesPerPage){ return (int)(XST_FAILURE); } if ((NumBytes <= 0) || (NumBytes > InstancePtr->BytesPerPage)) { return (int)(XST_FAILURE); } if (BufferNum == XISF_PAGE_BUFFER1) { /* * Buffer 1 Fast Read. */ ReadPtr[BYTE1] = XISF_CMD_FAST_BUF1_READ; } else { /* * Buffer 2 Fast Read. */ ReadPtr[BYTE1] = XISF_CMD_FAST_BUF2_READ; } ReadPtr[BYTE2] = (u8) (0x00); ReadPtr[BYTE3] = (u8) (ByteOffset >> XISF_ADDR_SHIFT8); ReadPtr[BYTE4] = (u8) ByteOffset; ReadPtr[BYTE5] = (u8) (XISF_DUMMYBYTE); /* * Initiate the Transfer. */ Status = XIsf_Transfer(InstancePtr, ReadPtr, ReadPtr, NumBytes + XISF_CMD_FAST_READ_EXTRA_BYTES); if (Status != (int)(XST_SUCCESS)) { return (int)(XST_FAILURE); } #endif /* (XPAR_XISF_FLASH_FAMILY == ATMEL) */ return Status; } /*****************************************************************************/ /** * * This function reads the data from OTP area of the Serial Flash. * * @param InstancePtr is a pointer to the XIsf instance. * @param Address is the starting address in OTP area of the Serial Flash * from which the data is to be read. * @param ReadPtr is a pointer to the memory where the data read from the * Serial Flash is stored. * @param ByteCount is the number of bytes to be read from the Serial * Flash. * * @return XST_SUCCESS if successful else XST_FAILURE. * * @note * - This operation is only supported for Intel Serial Flash. * - Minimum of one byte and a maximum of an entire Serial Flash * array can be read. ******************************************************************************/ static int ReadOTPData(XIsf *InstancePtr, u32 Address, u8 *ReadPtr, u32 ByteCount) { int Status = (int)(XST_FAILURE); Xil_AssertNonvoid(InstancePtr != NULL); Xil_AssertNonvoid(Address != 0); Xil_AssertNonvoid(ReadPtr != NULL); Xil_AssertNonvoid(ByteCount != 0); #if (XPAR_XISF_FLASH_FAMILY == INTEL) if (ByteCount <= 0 ) { return (int)(XST_FAILURE); } if (ReadPtr == NULL) { return (int)(XST_FAILURE); } ReadPtr[BYTE1] = XISF_CMD_OTP_READ; ReadPtr[BYTE2] = (u8) (Address >> XISF_ADDR_SHIFT16); ReadPtr[BYTE3] = (u8) (Address >> XISF_ADDR_SHIFT8); ReadPtr[BYTE4] = (u8) Address; ReadPtr[BYTE5] = (u8) (XISF_DUMMYBYTE); /* * Initiate the Transfer. */ Status = XIsf_Transfer(InstancePtr, ReadPtr, ReadPtr, ByteCount + XISF_OTP_RDWR_EXTRA_BYTES); if (Status != (int)(XST_SUCCESS)) { return (int)(XST_FAILURE); } #endif /* (XPAR_XISF_FLASH_FAMILY == INTEL) */ return Status; }