embeddedsw/lib/sw_services/xilisf/src/xilisf_read.c
Shakti Bhatnagar c2b6e79695 xiliisf: Updated xilisf lib
Updated the lib src files as well as the examples
for the major version change v5_0

Signed-off-by: Shakti Bhatnagar <shaktib@xilinx.com>
2014-09-02 11:21:18 +05:30

939 lines
29 KiB
C
Executable file

/******************************************************************************
*
* 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.
*
* <pre>
*
* 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()
* </pre>
*
******************************************************************************/
/***************************** 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;
}