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>
This commit is contained in:
parent
ee1d5c6b44
commit
c2b6e79695
22 changed files with 2627 additions and 825 deletions
|
@ -75,6 +75,8 @@
|
|||
* ----- ------- -------- ---------------------------------------------------
|
||||
* 1.00a ksu/sdm 03/22/08 First release
|
||||
* 2.00a ktn 11/22/09 Updated to use HAL processor APIs.
|
||||
* 5.0 sb 08/05/14 Registering to Xilisf Interrupt handler
|
||||
* instead of driver handler.
|
||||
*</pre>
|
||||
*
|
||||
******************************************************************************/
|
||||
|
@ -216,7 +218,7 @@ int main(void)
|
|||
* driver instance as the callback reference so the handler is able to
|
||||
* access the instance data.
|
||||
*/
|
||||
XSpi_SetStatusHandler(&Spi, &Spi, (XSpi_StatusHandler)SpiHandler);
|
||||
XIsf_SetStatusHandler(&Isf, &Spi, (XSpi_StatusHandler)SpiHandler);
|
||||
|
||||
/*
|
||||
* Start the SPI driver so that interrupts and the device are enabled.
|
||||
|
@ -234,6 +236,11 @@ int main(void)
|
|||
return XST_FAILURE;
|
||||
}
|
||||
|
||||
/*
|
||||
* Set The transfer Mode to Interrupt
|
||||
*/
|
||||
XIsf_SetTransferMode(&Isf,XISF_INTERRUPT_MODE);
|
||||
|
||||
/*
|
||||
* Set the
|
||||
* - SRAM page buffer number where the data is to be written.
|
||||
|
|
|
@ -70,6 +70,8 @@
|
|||
* ----- ------- -------- ---------------------------------------------------
|
||||
* 1.00a mta/ksu 03/20/08 First release
|
||||
* 2.00a ktn 11/22/09 Updated to use HAL processor APIs.
|
||||
* 5.0 sb 08/05/14 Registering to Xilisf Interrupt handler
|
||||
* instead of driver handler.
|
||||
*</pre>
|
||||
*
|
||||
******************************************************************************/
|
||||
|
@ -208,7 +210,7 @@ int main(void)
|
|||
* driver instance as the callback reference so the handler is able to
|
||||
* access the instance data.
|
||||
*/
|
||||
XSpi_SetStatusHandler(&Spi, &Spi, (XSpi_StatusHandler)SpiHandler);
|
||||
XIsf_SetStatusHandler(&Isf, &Spi, (XSpi_StatusHandler)SpiHandler);
|
||||
|
||||
/*
|
||||
* Start the SPI driver so that interrupts and the device are enabled.
|
||||
|
@ -226,6 +228,11 @@ int main(void)
|
|||
return XST_FAILURE;
|
||||
}
|
||||
|
||||
/*
|
||||
* Set The transfer Mode to Interrupt
|
||||
*/
|
||||
XIsf_SetTransferMode(&Isf,XISF_INTERRUPT_MODE);
|
||||
|
||||
/*
|
||||
* Specify the address in the Serial Flash for the Erase/Write/Read
|
||||
* operations.
|
||||
|
|
|
@ -79,6 +79,8 @@
|
|||
* 1.00a ktn 09/08/09 Updated this example such that every SPR write should
|
||||
* be preceded by an erase as per the atmel datasheet.
|
||||
* 2.00a ktn 11/22/09 Updated to use HAL processor APIs.
|
||||
* 5.0 sb 08/05/14 Registering to Xilisf Interrupt handler
|
||||
* instead of driver handler.
|
||||
*</pre>
|
||||
******************************************************************************/
|
||||
|
||||
|
@ -215,7 +217,7 @@ int main(void)
|
|||
* driver instance as the callback reference so the handler is able to
|
||||
* access the instance data.
|
||||
*/
|
||||
XSpi_SetStatusHandler(&Spi, &Spi, (XSpi_StatusHandler)SpiHandler);
|
||||
XIsf_SetStatusHandler(&Isf, &Spi, (XSpi_StatusHandler)SpiHandler);
|
||||
|
||||
/*
|
||||
* Start the SPI driver so that interrupts and the device are enabled.
|
||||
|
@ -233,6 +235,11 @@ int main(void)
|
|||
return XST_FAILURE;
|
||||
}
|
||||
|
||||
/*
|
||||
* Set The transfer Mode to Interrupt
|
||||
*/
|
||||
XIsf_SetTransferMode(&Isf,XISF_INTERRUPT_MODE);
|
||||
|
||||
/*
|
||||
* Perform the SPR erase operation.
|
||||
*/
|
||||
|
|
|
@ -58,7 +58,8 @@
|
|||
* ----- ---- -------- -----------------------------------------------
|
||||
* 1.00a sdm 03/24/08 First release
|
||||
* 2.00a ktn 11/22/09 Updated to use HAL processor APIs.
|
||||
*
|
||||
* 5.0 sb 08/05/14 Registering to Xilisf Interrupt handler
|
||||
* instead of driver handler.
|
||||
* </pre>
|
||||
*
|
||||
******************************************************************************/
|
||||
|
@ -198,7 +199,7 @@ int main()
|
|||
* driver instance as the callback reference so the handler is able to
|
||||
* access the instance data.
|
||||
*/
|
||||
XSpi_SetStatusHandler(&Spi, &Spi, (XSpi_StatusHandler)SpiHandler);
|
||||
XIsf_SetStatusHandler(&Isf, &Spi, (XSpi_StatusHandler)SpiHandler);
|
||||
|
||||
/*
|
||||
* Start the SPI driver so that interrupts and the device are enabled.
|
||||
|
@ -213,6 +214,11 @@ int main()
|
|||
return XST_FAILURE;
|
||||
}
|
||||
|
||||
/*
|
||||
* Set The transfer Mode to Interrupt
|
||||
*/
|
||||
XIsf_SetTransferMode(&Isf,XISF_INTERRUPT_MODE);
|
||||
|
||||
/*
|
||||
* Specify the address in the OTP region of the Serial Flash for the
|
||||
* Write/Read operations.
|
||||
|
|
|
@ -58,6 +58,8 @@
|
|||
* ----- ---- -------- -----------------------------------------------
|
||||
* 1.00a sdm 03/17/08 First release
|
||||
* 2.00a ktn 11/22/09 Updated to use HAL processor APIs.
|
||||
* 5.0 sb 08/05/14 Registering to Xilisf Interrupt handler
|
||||
* instead of driver handler.
|
||||
*
|
||||
* </pre>
|
||||
******************************************************************************/
|
||||
|
@ -196,7 +198,7 @@ int main()
|
|||
* driver instance as the callback reference so the handler is able to
|
||||
* access the instance data.
|
||||
*/
|
||||
XSpi_SetStatusHandler(&Spi, &Spi, (XSpi_StatusHandler)SpiHandler);
|
||||
XIsf_SetStatusHandler(&Isf, &Spi, (XSpi_StatusHandler)SpiHandler);
|
||||
|
||||
/*
|
||||
* Start the SPI driver so that interrupts and the device are enabled.
|
||||
|
@ -211,6 +213,10 @@ int main()
|
|||
return XST_FAILURE;
|
||||
}
|
||||
|
||||
/*
|
||||
* Set The transfer Mode to Interrupt
|
||||
*/
|
||||
XIsf_SetTransferMode(&Isf,XISF_INTERRUPT_MODE);
|
||||
|
||||
/*
|
||||
* The following code Disables the Sector Protection for all the Blocks
|
||||
|
|
|
@ -62,7 +62,8 @@
|
|||
* ----- ---- -------- -----------------------------------------------
|
||||
* 1.00a sdm 03/17/08 First release
|
||||
* 2.00a ktn 11/22/09 Updated to use HAL processor APIs.
|
||||
*
|
||||
* 5.0 sb 08/05/14 Registering to Xilisf Interrupt handler
|
||||
* instead of driver handler.
|
||||
* </pre>
|
||||
*
|
||||
******************************************************************************/
|
||||
|
@ -210,7 +211,7 @@ int main()
|
|||
* driver instance as the callback reference so the handler is able to
|
||||
* access the instance data.
|
||||
*/
|
||||
XSpi_SetStatusHandler(&Spi, &Spi, (XSpi_StatusHandler)SpiHandler);
|
||||
XIsf_SetStatusHandler(&Isf, &Spi, (XSpi_StatusHandler)SpiHandler);
|
||||
|
||||
/*
|
||||
* Start the SPI driver so that interrupts and the device are enabled.
|
||||
|
@ -225,6 +226,11 @@ int main()
|
|||
return XST_FAILURE;
|
||||
}
|
||||
|
||||
/*
|
||||
* Set The transfer Mode to Interrupt
|
||||
*/
|
||||
XIsf_SetTransferMode(&Isf,XISF_INTERRUPT_MODE);
|
||||
|
||||
/*
|
||||
* Perform the Write Enable operation.
|
||||
*/
|
||||
|
|
|
@ -56,6 +56,7 @@
|
|||
* 1.01 srt 04/26/13 Modified Erase function to perform Write Enable operation
|
||||
* for each sector erase.
|
||||
* 1.01 srt 08/28/13 Fixed the CR 731919, by setting the proper QSPI options.
|
||||
* 5.0 sb 08/05/14 Added support for greater than 128MB flash operations.
|
||||
*
|
||||
*</pre>
|
||||
*
|
||||
|
@ -63,14 +64,17 @@
|
|||
|
||||
/***************************** Include Files *********************************/
|
||||
|
||||
#include "xparameters.h" /* EDK generated parameters */
|
||||
#include "xscugic.h" /* Interrupt controller device driver */
|
||||
#include "xparameters.h" /**< EDK generated parameters */
|
||||
#include "xscugic.h" /**< Interrupt controller device driver */
|
||||
#include "xil_exception.h"
|
||||
#include "xil_printf.h"
|
||||
#include <xilisf.h> /* Serial Flash Library header file */
|
||||
#include <xilisf.h> /**< Serial Flash Library header file */
|
||||
|
||||
/************************** Constant Definitions *****************************/
|
||||
|
||||
/** @name Device ID's
|
||||
*
|
||||
* @{
|
||||
*/
|
||||
/*
|
||||
* The following constants map to the XPAR parameters created in the
|
||||
* xparameters.h file. They are defined here such that a user can easily
|
||||
|
@ -79,57 +83,61 @@
|
|||
#define QSPI_DEVICE_ID XPAR_XQSPIPS_0_DEVICE_ID
|
||||
#define INTC_DEVICE_ID XPAR_SCUGIC_SINGLE_DEVICE_ID
|
||||
#define QSPI_INTR_ID XPAR_XQSPIPS_0_INTR
|
||||
/*@}*/
|
||||
|
||||
/*
|
||||
/**
|
||||
* The following constants define the offsets within a FlashBuffer data
|
||||
* type for each kind of data. Note that the read data offset is not the
|
||||
* same as the write data because the QSPI driver is designed to allow full
|
||||
* duplex transfers such that the number of bytes received is the number
|
||||
* sent and received.
|
||||
*/
|
||||
#define DATA_OFFSET 4 /* Start of Data for Read/Write */
|
||||
#define DUMMY_OFFSET 4 /* Dummy byte offset for fast, dual and quad
|
||||
reads */
|
||||
#define DUMMY_SIZE 1 /* Number of dummy bytes for fast, dual and
|
||||
quad reads */
|
||||
#define DATA_OFFSET 4 /**< Start of Data for Read/Write */
|
||||
#define DUMMY_OFFSET 4 /**< Dummy byte offset for fast, dual
|
||||
and quad reads */
|
||||
#define DUMMY_SIZE 1 /**< Number of dummy bytes for fast,
|
||||
dual and quad reads */
|
||||
|
||||
/*
|
||||
/**
|
||||
* The following constants specify the page size, sector size, and number of
|
||||
* pages and sectors for the FLASH. The page size specifies a max number of
|
||||
* bytes that can be written to the FLASH with a single transfer.
|
||||
*/
|
||||
#define SECTOR_SIZE 0x10000
|
||||
#define NUM_SECTORS 0x100
|
||||
#define NUM_PAGES 0x10000
|
||||
#define PAGE_SIZE 256
|
||||
#define NUM_PAGES 0x10000 /**< Number of Pages in the flash */
|
||||
#define PAGE_SIZE 256 /**< Page Size for Read/Write Operation */
|
||||
|
||||
/*
|
||||
/**
|
||||
* Number of flash pages to be written.
|
||||
*/
|
||||
#define PAGE_COUNT 16
|
||||
#define PAGE_COUNT 16 /**< Number of Pages for
|
||||
Read/Write Operation */
|
||||
|
||||
/*
|
||||
* Flash address to which data is ot be written.
|
||||
/**
|
||||
* Flash address to which data is to be written.
|
||||
*/
|
||||
#define TEST_ADDRESS 0x00090000
|
||||
#define UNIQUE_VALUE 0x05
|
||||
/*
|
||||
#define TEST_ADDRESS 0x00080000 /**< Test Address in the flash */
|
||||
#define UNIQUE_VALUE 0x05 /**< Unique Value for Test */
|
||||
|
||||
/**
|
||||
* The following constants specify the max amount of data and the size of the
|
||||
* the buffer required to hold the data and overhead to transfer the data to
|
||||
* and from the FLASH.
|
||||
*/
|
||||
#define MAX_DATA PAGE_COUNT * PAGE_SIZE
|
||||
#define MAX_DATA PAGE_COUNT * PAGE_SIZE /**< Max Data Calculated by
|
||||
multiplying Page count and Page Size*/
|
||||
|
||||
/*
|
||||
/**
|
||||
* The following constant defines the slave select signal that is used to
|
||||
* to select the FLASH device on the QSPI bus, this signal is typically
|
||||
* connected to the chip select of the device
|
||||
*/
|
||||
#define FLASH_QSPI_SELECT 0x00
|
||||
|
||||
#define INTR_MODE 1
|
||||
|
||||
#define INTR_MODE 1 /**< Interrupt Mode Enable */
|
||||
|
||||
#define FAST_READ_NUM_DUMMY_BYTES 1 /**< Number Dummy Bytes for Fast Read*/
|
||||
#define DUAL_READ_NUM_DUMMY_BYTES 1 /**< Number Dummy Bytes for Dual Read */
|
||||
#define QUAD_READ_NUM_DUMMY_BYTES 1 /**< Number Dummy Bytes for Quad Read */
|
||||
/**************************** Type Definitions *******************************/
|
||||
|
||||
/***************** Macros (Inline Functions) Definitions *********************/
|
||||
|
@ -137,22 +145,22 @@
|
|||
/************************** Function Prototypes ******************************/
|
||||
|
||||
static int QspiSetupIntrSystem(XScuGic *IntcInstancePtr,
|
||||
XQspiPs *QspiInstancePtr, u16 QspiIntrId);
|
||||
XQspiPs *QspiInstancePtr, u16 QspiIntrId);
|
||||
|
||||
static void QspiDisableIntrSystem(XScuGic *IntcInstancePtr, u16 QspiIntrId);
|
||||
|
||||
void QspiHandler(void *CallBackRef, u32 StatusEvent, unsigned int ByteCount);
|
||||
void XilIsf_Handler(void *CallBackRef, u32 StatusEvent, unsigned int ByteCount);
|
||||
|
||||
int FlashErase(XIsf *InstancePtr, u32 Address, u32 ByteCount);
|
||||
int FlashWrite(XIsf *InstancePtr, u32 Address, u32 ByteCount, u8 Command);
|
||||
int FlashRead(XIsf *InstancePtr, u32 Address, u32 ByteCount, u8 Command);
|
||||
int WriteEnable(XIsf *InstancePtr);
|
||||
int QspiFlashIntrExample(XScuGic *IntcInstancePtr, XQspiPs *QspiInstancePtr,
|
||||
u16 QspiDeviceId, u16 QspiIntrId);
|
||||
u32 SectorMask(u32 SectorSize);
|
||||
|
||||
/************************** Variable Definitions *****************************/
|
||||
|
||||
/*
|
||||
/**
|
||||
* The instances to support the device drivers are global such that they
|
||||
* are initialized to zero each time the program runs. They could be local
|
||||
* but should at least be static so they are zeroed.
|
||||
|
@ -161,40 +169,56 @@ static XScuGic IntcInstance;
|
|||
static XQspiPs QspiInstance;
|
||||
static XIsf Isf;
|
||||
|
||||
/*
|
||||
/**
|
||||
* The following variables are shared between non-interrupt processing and
|
||||
* interrupt processing such that they must be global.
|
||||
*/
|
||||
volatile int TransferInProgress;
|
||||
|
||||
/*
|
||||
/**
|
||||
* The following variable tracks any errors that occur during interrupt
|
||||
* processing
|
||||
*/
|
||||
int ErrorCount;
|
||||
|
||||
/*
|
||||
/**
|
||||
* The following variable allows a test value to be added to the values that
|
||||
* are written to the FLASH such that unique values can be generated to
|
||||
* guarantee the writes to the FLASH were successful
|
||||
*/
|
||||
int Test = 5;
|
||||
|
||||
/*
|
||||
/**
|
||||
* The following variables are used to read and write to the eeprom and they
|
||||
* are global to avoid having large buffers on the stack
|
||||
*/
|
||||
u8 ReadBuffer[MAX_DATA + DATA_OFFSET + DUMMY_SIZE];
|
||||
u8 WriteBuffer[PAGE_SIZE + DATA_OFFSET];
|
||||
u8 IsfWriteBuffer[PAGE_SIZE + XISF_CMD_SEND_EXTRA_BYTES];
|
||||
u8 WriteBuffer[PAGE_SIZE + DATA_OFFSET]; /**< Write Buffer */
|
||||
u8 IsfWriteBuffer[PAGE_SIZE + XISF_CMD_SEND_EXTRA_BYTES];/**< IsfWrite Buffer
|
||||
used in XilISF Initialization */
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* The following defines are for dual flash stacked mode interface.
|
||||
*/
|
||||
#define LQSPI_CR_FAST_QUAD_READ 0x0000006B /**< Fast Quad Read output */
|
||||
#define LQSPI_CR_1_DUMMY_BYTE 0x00000100 /**< 1 Dummy Byte between
|
||||
address and return data */
|
||||
|
||||
#define DUAL_STACK_CONFIG_WRITE (XQSPIPS_LQSPI_CR_TWO_MEM_MASK | \
|
||||
LQSPI_CR_1_DUMMY_BYTE | \
|
||||
LQSPI_CR_FAST_QUAD_READ)/**< Fast Quad Read output */
|
||||
|
||||
#define DUAL_QSPI_CONFIG_WRITE (XQSPIPS_LQSPI_CR_TWO_MEM_MASK | \
|
||||
XQSPIPS_LQSPI_CR_SEP_BUS_MASK | \
|
||||
LQSPI_CR_1_DUMMY_BYTE | \
|
||||
LQSPI_CR_FAST_QUAD_READ)/**< Fast Quad Read output */
|
||||
/*****************************************************************************/
|
||||
/**
|
||||
*
|
||||
* Main function to call the QSPI Flash example.
|
||||
*
|
||||
* @param None
|
||||
*
|
||||
* @return XST_SUCCESS if successful, otherwise XST_FAILURE.
|
||||
*
|
||||
* @note None
|
||||
|
@ -210,7 +234,7 @@ int main(void)
|
|||
* Run the Qspi Interrupt example.
|
||||
*/
|
||||
Status = QspiFlashIntrExample(&IntcInstance, &QspiInstance,
|
||||
QSPI_DEVICE_ID, QSPI_INTR_ID);
|
||||
QSPI_DEVICE_ID, QSPI_INTR_ID);
|
||||
if (Status != XST_SUCCESS) {
|
||||
xil_printf("QSPI FLASH Interrupt Example Test Failed\r\n");
|
||||
return XST_FAILURE;
|
||||
|
@ -221,13 +245,16 @@ int main(void)
|
|||
}
|
||||
|
||||
|
||||
/*****************************************************************************
|
||||
*
|
||||
/****************************************************************************/
|
||||
/**
|
||||
* The purpose of this function is to illustrate how to use the XQspiPs
|
||||
* device driver in interrupt mode. This function writes and reads data
|
||||
* from a serial FLASH.
|
||||
*
|
||||
* @param None.
|
||||
* @param IntcInstancePtr is the instance of the interrupt
|
||||
* @param QspiInstancePtr is the Pointer to the qspi driver instance
|
||||
* @param QspiDeviceId is the Device ID of qspi
|
||||
* @param QspiIntrId is the interrupt ID for QSPI driver
|
||||
*
|
||||
* @return XST_SUCCESS if successful else XST_FAILURE.
|
||||
*
|
||||
|
@ -247,25 +274,29 @@ int QspiFlashIntrExample(XScuGic *IntcInstancePtr, XQspiPs *QspiInstancePtr,
|
|||
u8 UniqueValue;
|
||||
int Count;
|
||||
int Page;
|
||||
XQspiPs_Config *ConfigPtr; /* Pointer to Configuration ROM data */
|
||||
u32 Options;
|
||||
XQspiPs_Config *ConfigPtr; /* Pointer to Configuration ROM data */
|
||||
u32 Options;
|
||||
|
||||
/*
|
||||
* Lookup the device configuration in the temporary CROM table. Use this
|
||||
* configuration info down below when initializing this component.
|
||||
*/
|
||||
ConfigPtr = XQspiPs_LookupConfig(QspiDeviceId);
|
||||
if (ConfigPtr == NULL) {
|
||||
return XST_DEVICE_NOT_FOUND;
|
||||
}
|
||||
/*
|
||||
* Lookup the device configuration in the temporary CROM table. Use this
|
||||
* configuration info down below when initializing this component.
|
||||
*/
|
||||
ConfigPtr = XQspiPs_LookupConfig(QspiDeviceId);
|
||||
if (ConfigPtr == NULL) {
|
||||
return XST_DEVICE_NOT_FOUND;
|
||||
}
|
||||
|
||||
XQspiPs_CfgInitialize(QspiInstancePtr, ConfigPtr,
|
||||
ConfigPtr->BaseAddress);
|
||||
Status = XQspiPs_CfgInitialize(QspiInstancePtr, ConfigPtr,
|
||||
ConfigPtr->BaseAddress);
|
||||
if (Status != XST_SUCCESS) {
|
||||
return XST_FAILURE;
|
||||
}
|
||||
|
||||
/*
|
||||
* Set the QSPI options
|
||||
*/
|
||||
Options = XQSPIPS_FORCE_SSELECT_OPTION |
|
||||
|
||||
/*
|
||||
* Set the QSPI options
|
||||
*/
|
||||
Options = XQSPIPS_FORCE_SSELECT_OPTION |
|
||||
XQSPIPS_MANUAL_START_OPTION |
|
||||
XQSPIPS_HOLD_B_DRIVE_OPTION;
|
||||
Status = XIsf_SetSpiConfiguration(&Isf, QspiInstancePtr,
|
||||
|
@ -274,9 +305,30 @@ int QspiFlashIntrExample(XScuGic *IntcInstancePtr, XQspiPs *QspiInstancePtr,
|
|||
return XST_FAILURE;
|
||||
}
|
||||
|
||||
/* Initialize the XILISF Library */
|
||||
|
||||
if(ConfigPtr->ConnectionMode == XQSPIPS_CONNECTION_MODE_STACKED) {
|
||||
/*
|
||||
* Enable two flash memories, Shared bus (NOT separate bus),
|
||||
* L_PAGE selected by default
|
||||
*/
|
||||
XQspiPs_SetLqspiConfigReg(QspiInstancePtr,
|
||||
DUAL_STACK_CONFIG_WRITE);
|
||||
}
|
||||
|
||||
if(ConfigPtr->ConnectionMode == XQSPIPS_CONNECTION_MODE_PARALLEL) {
|
||||
/*
|
||||
* Enable two flash memories on separate buses
|
||||
*/
|
||||
XQspiPs_SetLqspiConfigReg(QspiInstancePtr,
|
||||
DUAL_QSPI_CONFIG_WRITE);
|
||||
}
|
||||
|
||||
|
||||
/* Initialize the XILISF Library */
|
||||
XIsf_Initialize(&Isf, QspiInstancePtr, FLASH_QSPI_SELECT,
|
||||
IsfWriteBuffer);
|
||||
IsfWriteBuffer);
|
||||
|
||||
|
||||
|
||||
XIsf_SetTransferMode(&Isf, XISF_INTERRUPT_MODE);
|
||||
|
||||
|
@ -285,7 +337,7 @@ int QspiFlashIntrExample(XScuGic *IntcInstancePtr, XQspiPs *QspiInstancePtr,
|
|||
* interrupts can occur. This function is application specific
|
||||
*/
|
||||
Status = QspiSetupIntrSystem(IntcInstancePtr, QspiInstancePtr,
|
||||
QspiIntrId);
|
||||
QspiIntrId);
|
||||
if (Status != XST_SUCCESS) {
|
||||
return XST_FAILURE;
|
||||
}
|
||||
|
@ -296,14 +348,14 @@ int QspiFlashIntrExample(XScuGic *IntcInstancePtr, XQspiPs *QspiInstancePtr,
|
|||
* the QSPI driver instance as the callback reference so the handler is
|
||||
* able to access the instance data
|
||||
*/
|
||||
XQspiPs_SetStatusHandler(QspiInstancePtr, QspiInstancePtr,
|
||||
(XQspiPs_StatusHandler) QspiHandler);
|
||||
XIsf_SetStatusHandler(&Isf, QspiInstancePtr,
|
||||
(XQspiPs_StatusHandler) XilIsf_Handler);
|
||||
|
||||
/*
|
||||
* Initialize the write buffer for a pattern to write to the FLASH
|
||||
* and the read buffer to zero so it can be verified after the read, the
|
||||
* test value that is added to the unique value allows the value to be
|
||||
* changed in a debug environment to guarantee
|
||||
* and the read buffer to zero so it can be verified after the read,
|
||||
* the test value that is added to the unique value allows the value
|
||||
* to be changed in a debug environment to guarantee
|
||||
*/
|
||||
for (UniqueValue = UNIQUE_VALUE, Count = 0; Count < PAGE_SIZE;
|
||||
Count++, UniqueValue++) {
|
||||
|
@ -311,7 +363,10 @@ int QspiFlashIntrExample(XScuGic *IntcInstancePtr, XQspiPs *QspiInstancePtr,
|
|||
}
|
||||
memset(ReadBuffer, 0x00, sizeof(ReadBuffer));
|
||||
|
||||
FlashErase(&Isf, TEST_ADDRESS, MAX_DATA);
|
||||
Status = FlashErase(&Isf, TEST_ADDRESS, MAX_DATA);
|
||||
if(Status != XST_SUCCESS){
|
||||
return XST_FAILURE;
|
||||
}
|
||||
|
||||
/*
|
||||
* Write the data in the write buffer to the serial FLASH a page at a
|
||||
|
@ -332,10 +387,85 @@ int QspiFlashIntrExample(XScuGic *IntcInstancePtr, XQspiPs *QspiInstancePtr,
|
|||
* Setup a pointer to the start of the data that was read into the read
|
||||
* buffer and verify the data read is the data that was written
|
||||
*/
|
||||
BufferPtr = &ReadBuffer[DATA_OFFSET];
|
||||
|
||||
BufferPtr = ReadBuffer;
|
||||
|
||||
for (UniqueValue = UNIQUE_VALUE, Count = 0; Count < MAX_DATA;
|
||||
Count++, UniqueValue++) {
|
||||
|
||||
if (BufferPtr[Count] != (u8)(UniqueValue + Test)) {
|
||||
return XST_FAILURE;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Read the contents of the FLASH from TEST_ADDRESS, using Fast Read
|
||||
* command
|
||||
*/
|
||||
|
||||
Status = FlashRead(&Isf, TEST_ADDRESS, MAX_DATA, XISF_FAST_READ);
|
||||
if(Status != XST_SUCCESS){
|
||||
return XST_FAILURE;
|
||||
}
|
||||
|
||||
/*
|
||||
* Setup a pointer to the start of the data that was read into the read
|
||||
* buffer and verify the data read is the data that was written
|
||||
*/
|
||||
|
||||
BufferPtr = ReadBuffer;
|
||||
|
||||
for (UniqueValue = UNIQUE_VALUE, Count = 0; Count < MAX_DATA;
|
||||
Count++, UniqueValue++) {
|
||||
|
||||
if (BufferPtr[Count] != (u8)(UniqueValue + Test)) {
|
||||
return XST_FAILURE;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Read the contents of the FLASH from TEST_ADDRESS, using DUAL IO
|
||||
* Fast Read command
|
||||
*/
|
||||
Status = FlashRead(&Isf, TEST_ADDRESS, MAX_DATA, XISF_DUAL_OP_FAST_READ);
|
||||
if(Status != XST_SUCCESS){
|
||||
return XST_FAILURE;
|
||||
}
|
||||
|
||||
/*
|
||||
* Setup a pointer to the start of the data that was read into the read
|
||||
* buffer and verify the data read is the data that was written
|
||||
*/
|
||||
|
||||
BufferPtr = ReadBuffer;
|
||||
for (UniqueValue = UNIQUE_VALUE, Count = 0; Count < MAX_DATA;
|
||||
Count++, UniqueValue++) {
|
||||
|
||||
if (BufferPtr[Count] != (u8)(UniqueValue + Test)) {
|
||||
return XST_FAILURE;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Read the contents of the FLASH from TEST_ADDRESS, using QUAD OP
|
||||
* Fast Read command
|
||||
*/
|
||||
Status = FlashRead(&Isf, TEST_ADDRESS, MAX_DATA, XISF_QUAD_OP_FAST_READ);
|
||||
if(Status != XST_SUCCESS){
|
||||
return XST_FAILURE;
|
||||
}
|
||||
|
||||
/*
|
||||
* Setup a pointer to the start of the data that was read into the read
|
||||
* buffer and verify the data read is the data that was written
|
||||
*/
|
||||
|
||||
BufferPtr = ReadBuffer;
|
||||
for (UniqueValue = UNIQUE_VALUE, Count = 0; Count < MAX_DATA;
|
||||
Count++, UniqueValue++) {
|
||||
if (BufferPtr[Count] != (u8)(UniqueValue + Test)) {
|
||||
return XST_FAILURE;
|
||||
}
|
||||
|
@ -346,63 +476,8 @@ int QspiFlashIntrExample(XScuGic *IntcInstancePtr, XQspiPs *QspiInstancePtr,
|
|||
return XST_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
/*****************************************************************************/
|
||||
/**
|
||||
*
|
||||
* This function waits till the STM Serial Flash is ready to accept next command.
|
||||
*
|
||||
* @param None.
|
||||
*
|
||||
* @return XST_SUCCESS if successful else XST_FAILURE.
|
||||
*
|
||||
* @note This function reads the status register of the Serial Flash and
|
||||
waits till the WIP bit of the status register becomes 0.
|
||||
*
|
||||
******************************************************************************/
|
||||
int IsfWaitForFlashNotBusy(void)
|
||||
{
|
||||
int Status;
|
||||
u8 StatusReg;
|
||||
|
||||
while(1) {
|
||||
|
||||
/*
|
||||
* Get the Status Register.
|
||||
*/
|
||||
TransferInProgress = TRUE;
|
||||
Status = XIsf_GetStatus(&Isf, ReadBuffer);
|
||||
if(Status != XST_SUCCESS) {
|
||||
return XST_FAILURE;
|
||||
}
|
||||
|
||||
/*
|
||||
* Wait till the Transfer is in progress.
|
||||
*/
|
||||
while(TransferInProgress);
|
||||
|
||||
/*
|
||||
* Check if there are any errors in the transaction.
|
||||
*/
|
||||
if(ErrorCount != 0) {
|
||||
return XST_FAILURE;
|
||||
}
|
||||
|
||||
/*
|
||||
* Check if the flash is ready to accept the next command.
|
||||
* If so break.
|
||||
*/
|
||||
StatusReg = ReadBuffer[BYTE2];
|
||||
if((StatusReg & XISF_SR_IS_READY_MASK) == 0) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return XST_SUCCESS;
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* This function is the handler which performs processing for the QSPI driver.
|
||||
* It is called from an interrupt context such that the amount of processing
|
||||
* performed should be minimized. It is called when a transfer of QSPI data
|
||||
|
@ -420,7 +495,7 @@ int IsfWaitForFlashNotBusy(void)
|
|||
* @note None.
|
||||
*
|
||||
******************************************************************************/
|
||||
void QspiHandler(void *CallBackRef, u32 StatusEvent, unsigned int ByteCount)
|
||||
void XilIsf_Handler(void *CallBackRef, u32 StatusEvent, unsigned int ByteCount)
|
||||
{
|
||||
/*
|
||||
* Indicate the transfer on the QSPI bus is no longer in progress
|
||||
|
@ -436,8 +511,8 @@ void QspiHandler(void *CallBackRef, u32 StatusEvent, unsigned int ByteCount)
|
|||
}
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
/*****************************************************************************/
|
||||
/**
|
||||
*
|
||||
* This function writes to the serial FLASH connected to the QSPI interface.
|
||||
* The FLASH contains a 256 byte write buffer which can be filled and then a
|
||||
|
@ -461,8 +536,6 @@ int FlashWrite(XIsf *InstancePtr, u32 Address, u32 ByteCount, u8 Command)
|
|||
|
||||
int Status;
|
||||
|
||||
WriteEnable(InstancePtr);
|
||||
|
||||
WriteParam.Address = Address;
|
||||
WriteParam.NumBytes = ByteCount;
|
||||
WriteParam.WritePtr = WriteBuffer;
|
||||
|
@ -477,25 +550,18 @@ int FlashWrite(XIsf *InstancePtr, u32 Address, u32 ByteCount, u8 Command)
|
|||
|
||||
/*
|
||||
* Wait till the Transfer is complete and check if there are any errors
|
||||
* in the transaction.
|
||||
* in the transaction.
|
||||
*/
|
||||
while(TransferInProgress);
|
||||
if(ErrorCount != 0) {
|
||||
return XST_FAILURE;
|
||||
}
|
||||
|
||||
/*
|
||||
* Wait till the Flash is not Busy.
|
||||
*/
|
||||
Status = IsfWaitForFlashNotBusy();
|
||||
if(Status != XST_SUCCESS) {
|
||||
return XST_FAILURE;
|
||||
}
|
||||
return XST_SUCCESS;
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
/*****************************************************************************/
|
||||
/**
|
||||
* This function reads from the serial FLASH connected to the
|
||||
* QSPI interface.
|
||||
*
|
||||
|
@ -523,6 +589,15 @@ int FlashRead(XIsf *InstancePtr, u32 Address, u32 ByteCount, u8 Command)
|
|||
ReadParam.Address = Address;
|
||||
ReadParam.NumBytes = ByteCount;
|
||||
ReadParam.ReadPtr = ReadBuffer;
|
||||
if(Command == XISF_FAST_READ){
|
||||
ReadParam.NumDummyBytes = FAST_READ_NUM_DUMMY_BYTES;
|
||||
}
|
||||
else if(Command == XISF_DUAL_OP_FAST_READ){
|
||||
ReadParam.NumDummyBytes = DUAL_READ_NUM_DUMMY_BYTES;
|
||||
}
|
||||
else{
|
||||
ReadParam.NumDummyBytes = QUAD_READ_NUM_DUMMY_BYTES;
|
||||
}
|
||||
|
||||
/*
|
||||
* Perform the Read operation.
|
||||
|
@ -544,15 +619,15 @@ int FlashRead(XIsf *InstancePtr, u32 Address, u32 ByteCount, u8 Command)
|
|||
return XST_SUCCESS;
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
/*****************************************************************************/
|
||||
/**
|
||||
*
|
||||
* This function erases the sectors in the serial FLASH connected to the
|
||||
* QSPI interface.
|
||||
*
|
||||
* @param InstancePtr is a pointer to the XIsf component to use.
|
||||
* @param Address contains the address of the first sector which needs to
|
||||
* be erased.
|
||||
* be erased.
|
||||
* @param ByteCount contains the total size to be erased.
|
||||
*
|
||||
* @return None.
|
||||
|
@ -564,17 +639,27 @@ int FlashErase(XIsf *InstancePtr, u32 Address, u32 ByteCount)
|
|||
{
|
||||
int Status;
|
||||
int Sector;
|
||||
u32 NumSect;
|
||||
u32 SectorSize;
|
||||
u32 NumSectors;
|
||||
u32 Sector_Mask;
|
||||
|
||||
SectorSize = Isf.SectorSize;
|
||||
NumSectors = Isf.NumSectors;
|
||||
|
||||
/* Get the sector mask value */
|
||||
Sector_Mask = SectorMask(SectorSize);
|
||||
|
||||
/*
|
||||
* If erase size is same as the total size of the flash, use bulk erase
|
||||
* command
|
||||
*/
|
||||
if (ByteCount == (NUM_SECTORS * SECTOR_SIZE)) {
|
||||
WriteEnable(InstancePtr);
|
||||
if (ByteCount == (NumSectors * SectorSize)) {
|
||||
|
||||
/*
|
||||
* Perform the Bulk Erase operation.
|
||||
*/
|
||||
|
||||
TransferInProgress = TRUE;
|
||||
Status = XIsf_Erase(InstancePtr, XISF_BULK_ERASE, Address);
|
||||
if(Status != XST_SUCCESS) {
|
||||
|
@ -582,34 +667,38 @@ int FlashErase(XIsf *InstancePtr, u32 Address, u32 ByteCount)
|
|||
}
|
||||
|
||||
/*
|
||||
* Wait till the Transfer is complete and check if there are any errors
|
||||
* in the transaction.
|
||||
* Wait till the Transfer is complete and check if there
|
||||
* are any errors in the transaction.
|
||||
*/
|
||||
while(TransferInProgress);
|
||||
if(ErrorCount != 0) {
|
||||
return XST_FAILURE;
|
||||
}
|
||||
|
||||
/*
|
||||
* Wait till the Flash is not Busy.
|
||||
*/
|
||||
Status = IsfWaitForFlashNotBusy();
|
||||
if(Status != XST_SUCCESS) {
|
||||
return XST_FAILURE;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Calculate no. of sectors to erase based on byte count
|
||||
*/
|
||||
NumSect = ByteCount/SectorSize + 1;
|
||||
|
||||
/*
|
||||
* If ByteCount to k sectors,
|
||||
* but the address range spans from N to N+k+1 sectors, then
|
||||
* increment no. of sectors to be erased
|
||||
*/
|
||||
|
||||
if( ((Address + ByteCount) & Sector_Mask) ==
|
||||
((Address + (NumSect * SectorSize)) &
|
||||
Sector_Mask) ) {
|
||||
NumSect++;
|
||||
}
|
||||
|
||||
/*
|
||||
* If the erase size is less than the total size of the flash, use
|
||||
* sector erase command
|
||||
*/
|
||||
for (Sector = 0; Sector < ((ByteCount / SECTOR_SIZE) + 1); Sector++) {
|
||||
/*
|
||||
* Write enable instruction has to be executed prior to
|
||||
* any Write operation.
|
||||
*/
|
||||
WriteEnable(InstancePtr);
|
||||
for (Sector = 0; Sector < NumSect; Sector++) {
|
||||
|
||||
/*
|
||||
* Perform the Bulk Erase operation.
|
||||
|
@ -621,66 +710,15 @@ int FlashErase(XIsf *InstancePtr, u32 Address, u32 ByteCount)
|
|||
}
|
||||
|
||||
/*
|
||||
* Wait till the Transfer is complete and check if there are any errors
|
||||
* in the transaction.
|
||||
* Wait till the Transfer is complete and check if there
|
||||
* are any errors in the transaction.
|
||||
*/
|
||||
while(TransferInProgress);
|
||||
if(ErrorCount != 0) {
|
||||
return XST_FAILURE;
|
||||
}
|
||||
|
||||
/*
|
||||
* Wait till the Flash is not Busy.
|
||||
*/
|
||||
Status = IsfWaitForFlashNotBusy();
|
||||
if(Status != XST_SUCCESS) {
|
||||
return XST_FAILURE;
|
||||
}
|
||||
|
||||
Address += SECTOR_SIZE;
|
||||
}
|
||||
return XST_SUCCESS;
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
/**
|
||||
*
|
||||
* This function performs the write enable operation.
|
||||
*
|
||||
* @param None.
|
||||
*
|
||||
* @return XST_SUCCESS if successful else XST_FAILURE.
|
||||
*
|
||||
*
|
||||
******************************************************************************/
|
||||
int WriteEnable(XIsf *InstancePtr)
|
||||
{
|
||||
int Status;
|
||||
|
||||
/*
|
||||
* Perform the Write Enable operation.
|
||||
*/
|
||||
TransferInProgress = TRUE;
|
||||
Status = XIsf_WriteEnable(&Isf, XISF_WRITE_ENABLE);
|
||||
if(Status != XST_SUCCESS) {
|
||||
return XST_FAILURE;
|
||||
}
|
||||
|
||||
/*
|
||||
* Wait till the Transfer is complete and check if there are any errors
|
||||
* in the transaction.
|
||||
*/
|
||||
while(TransferInProgress);
|
||||
if(ErrorCount != 0) {
|
||||
return XST_FAILURE;
|
||||
}
|
||||
|
||||
/*
|
||||
* Wait till the Flash is not Busy.
|
||||
*/
|
||||
Status = IsfWaitForFlashNotBusy();
|
||||
if(Status != XST_SUCCESS) {
|
||||
return XST_FAILURE;
|
||||
Address += SectorSize;
|
||||
}
|
||||
return XST_SUCCESS;
|
||||
}
|
||||
|
@ -782,3 +820,45 @@ static void QspiDisableIntrSystem(XScuGic *IntcInstancePtr, u16 QspiIntrId)
|
|||
*/
|
||||
XScuGic_Disconnect(IntcInstancePtr, QspiIntrId);
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
/**
|
||||
*
|
||||
* This function calculates the sector mask based upon the sector size value
|
||||
*
|
||||
*
|
||||
* @param SectorSize is the size of the sector of the flash
|
||||
* available on the board.
|
||||
*
|
||||
* @return will return the sector mask after calculation.
|
||||
*
|
||||
* @note None.
|
||||
*
|
||||
******************************************************************************/
|
||||
u32 SectorMask(u32 SectorSize){
|
||||
|
||||
u32 Mask;
|
||||
|
||||
switch(SectorSize){
|
||||
case 0x10000:
|
||||
Mask = 0xFFFF0000;
|
||||
break;
|
||||
|
||||
case 0x20000:
|
||||
Mask = 0xFFFE0000;
|
||||
break;
|
||||
|
||||
case 0x40000:
|
||||
Mask = 0xFFFC0000;
|
||||
break;
|
||||
|
||||
case 0x80000:
|
||||
Mask = 0xFFF80000;
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return Mask;
|
||||
}
|
||||
|
|
|
@ -56,7 +56,7 @@
|
|||
* 1.01 srt 04/26/13 Modified Erase function to perform Write Enable operation
|
||||
* for each sector erase.
|
||||
* 1.01 srt 08/28/13 Fixed the CR 731919, by setting the proper QSPI options.
|
||||
*
|
||||
* 5.0 sb 08/05/14 Added support for greater than 128MB flash operations.
|
||||
*</pre>
|
||||
*
|
||||
******************************************************************************/
|
||||
|
@ -67,10 +67,13 @@
|
|||
#include "xscugic.h" /* Interrupt controller device driver */
|
||||
#include "xil_exception.h"
|
||||
#include "xil_printf.h"
|
||||
#include <xilisf.h> /* Serial Flash Library header file */
|
||||
#include "xilisf.h" /* Serial Flash Library header file */
|
||||
|
||||
/************************** Constant Definitions *****************************/
|
||||
|
||||
/** @name Device ID's
|
||||
*
|
||||
* @{
|
||||
*/
|
||||
/*
|
||||
* The following constants map to the XPAR parameters created in the
|
||||
* xparameters.h file. They are defined here such that a user can easily
|
||||
|
@ -79,55 +82,62 @@
|
|||
#define QSPI_DEVICE_ID XPAR_XQSPIPS_0_DEVICE_ID
|
||||
#define INTC_DEVICE_ID XPAR_SCUGIC_SINGLE_DEVICE_ID
|
||||
#define QSPI_INTR_ID XPAR_XQSPIPS_0_INTR
|
||||
/*@}*/
|
||||
|
||||
/*
|
||||
/**
|
||||
* The following constants define the offsets within a FlashBuffer data
|
||||
* type for each kind of data. Note that the read data offset is not the
|
||||
* same as the write data because the QSPI driver is designed to allow full
|
||||
* duplex transfers such that the number of bytes received is the number
|
||||
* sent and received.
|
||||
*/
|
||||
#define DATA_OFFSET 4 /* Start of Data for Read/Write */
|
||||
#define DUMMY_OFFSET 4 /* Dummy byte offset for fast, dual and quad
|
||||
reads */
|
||||
#define DUMMY_SIZE 1 /* Number of dummy bytes for fast, dual and
|
||||
quad reads */
|
||||
#define DATA_OFFSET 4 /**< Start of Data for Read/Write */
|
||||
#define DUMMY_OFFSET 4 /**< Dummy byte offset for fast, dual and quad
|
||||
reads */
|
||||
#define DUMMY_SIZE 1 /**< Number of dummy bytes for fast, dual and
|
||||
quad reads */
|
||||
|
||||
/*
|
||||
* The following constants specify the page size, sector size, and number of
|
||||
* pages and sectors for the FLASH. The page size specifies a max number of
|
||||
/**
|
||||
* The following constants specify the page size and number of
|
||||
* pages for the FLASH. The page size specifies a max number of
|
||||
* bytes that can be written to the FLASH with a single transfer.
|
||||
*/
|
||||
#define SECTOR_SIZE 0x10000
|
||||
#define NUM_SECTORS 0x100
|
||||
#define NUM_PAGES 0x10000
|
||||
#define PAGE_SIZE 256
|
||||
#define NUM_PAGES 0x10000 /**< Number of Pages in the flash */
|
||||
#define PAGE_SIZE 256 /**< Page Size for Read/Write Operation */
|
||||
|
||||
/*
|
||||
/**
|
||||
* Number of flash pages to be written.
|
||||
*/
|
||||
#define PAGE_COUNT 16
|
||||
#define PAGE_COUNT 32 /**< Number of Pages for r/w Operation */
|
||||
|
||||
/*
|
||||
/**
|
||||
* Flash address to which data is ot be written.
|
||||
*/
|
||||
#define TEST_ADDRESS 0x00090000
|
||||
#define UNIQUE_VALUE 0x05
|
||||
/*
|
||||
#define TEST_ADDRESS 0x00090000 /**< Test Address in the flash */
|
||||
#define UNIQUE_VALUE 0x08 /**< Unique Value for Test */
|
||||
|
||||
|
||||
/**
|
||||
* The following constants specify the max amount of data and the size of the
|
||||
* the buffer required to hold the data and overhead to transfer the data to
|
||||
* and from the FLASH.
|
||||
*/
|
||||
#define MAX_DATA PAGE_COUNT * PAGE_SIZE
|
||||
#define MAX_DATA PAGE_COUNT * PAGE_SIZE /**< Max Data Calculated by
|
||||
multiplying Page count and Page Size */
|
||||
|
||||
/*
|
||||
/**
|
||||
* The following constant defines the slave select signal that is used to
|
||||
* to select the FLASH device on the QSPI bus, this signal is typically
|
||||
* connected to the chip select of the device
|
||||
*/
|
||||
#define FLASH_QSPI_SELECT 0x00
|
||||
|
||||
#define FLASH_QSPI_SELECT 0x00 /**< Interrupt Mode Enable */
|
||||
|
||||
#define FAST_READ_NUM_DUMMY_BYTES 1 /**< Number Dummy Bytes for
|
||||
Fast Read */
|
||||
#define DUAL_READ_NUM_DUMMY_BYTES 1 /**< Number Dummy Bytes for
|
||||
Dual Read */
|
||||
#define QUAD_READ_NUM_DUMMY_BYTES 1 /**< Number Dummy Bytes for
|
||||
Quad Read */
|
||||
/**************************** Type Definitions *******************************/
|
||||
|
||||
/***************** Macros (Inline Functions) Definitions *********************/
|
||||
|
@ -135,15 +145,17 @@
|
|||
/************************** Function Prototypes ******************************/
|
||||
|
||||
int FlashErase(XIsf *InstancePtr, u32 Address, u32 ByteCount);
|
||||
int FlashWrite(XIsf *InstancePtr, u32 Address, u32 ByteCount, u8 Command);
|
||||
int FlashRead(XIsf *InstancePtr, u32 Address, u32 ByteCount, u8 Command);
|
||||
int WriteEnable(XIsf *InstancePtr);
|
||||
int FlashWrite(XIsf *InstancePtr, u32 Address, u32 ByteCount,
|
||||
u8 Command);
|
||||
int FlashRead(XIsf *InstancePtr, u32 Address, u32 ByteCount,
|
||||
u8 Command);
|
||||
int QspiFlashPollExample(XScuGic *IntcInstancePtr, XQspiPs *QspiInstancePtr,
|
||||
u16 QspiDeviceId, u16 QspiIntrId);
|
||||
static u32 SectorMask(u32 SectorSize);
|
||||
|
||||
/************************** Variable Definitions *****************************/
|
||||
|
||||
/*
|
||||
/**
|
||||
* The instances to support the device drivers are global such that they
|
||||
* are initialized to zero each time the program runs. They could be local
|
||||
* but should at least be static so they are zeroed.
|
||||
|
@ -151,35 +163,50 @@ int QspiFlashPollExample(XScuGic *IntcInstancePtr, XQspiPs *QspiInstancePtr,
|
|||
static XScuGic IntcInstance;
|
||||
static XQspiPs QspiInstance;
|
||||
static XIsf Isf;
|
||||
static XQspiPs_Config *ConfigPtr; /**< Pointer to Configuration ROM data */
|
||||
|
||||
/*
|
||||
/**
|
||||
* The following variables are shared between non-interrupt processing and
|
||||
* interrupt processing such that they must be global.
|
||||
*/
|
||||
volatile int TransferInProgress;
|
||||
|
||||
/*
|
||||
/**
|
||||
* The following variable allows a test value to be added to the values that
|
||||
* are written to the FLASH such that unique values can be generated to
|
||||
* guarantee the writes to the FLASH were successful
|
||||
*/
|
||||
int Test = 5;
|
||||
int Test_Polled = 7;
|
||||
|
||||
/*
|
||||
/**
|
||||
* The following variables are used to read and write to the eeprom and they
|
||||
* are global to avoid having large buffers on the stack
|
||||
*/
|
||||
u8 ReadBuffer[MAX_DATA + DATA_OFFSET + DUMMY_SIZE];
|
||||
u8 WriteBuffer[PAGE_SIZE + DATA_OFFSET];
|
||||
u8 IsfWriteBuffer[PAGE_SIZE + XISF_CMD_SEND_EXTRA_BYTES];
|
||||
u8 WriteBuffer[PAGE_SIZE + DATA_OFFSET]; /**< Write Buffer */
|
||||
u8 IsfWriteBuffer[PAGE_SIZE + XISF_CMD_SEND_EXTRA_BYTES];/**< IsfWrite Buffer
|
||||
used in XilISF Initialization */
|
||||
|
||||
/**
|
||||
* The following defines are for dual flash stacked mode interface.
|
||||
*/
|
||||
#define LQSPI_CR_FAST_QUAD_READ 0x0000006B /**< Fast Quad Read output */
|
||||
#define LQSPI_CR_1_DUMMY_BYTE 0x00000100 /**< 1 Dummy Byte between
|
||||
address and return data */
|
||||
|
||||
#define DUAL_STACK_CONFIG_WRITE (XQSPIPS_LQSPI_CR_TWO_MEM_MASK | \
|
||||
LQSPI_CR_1_DUMMY_BYTE | \
|
||||
LQSPI_CR_FAST_QUAD_READ) /**< Fast Quad Read output */
|
||||
|
||||
#define DUAL_QSPI_CONFIG_WRITE (XQSPIPS_LQSPI_CR_TWO_MEM_MASK | \
|
||||
XQSPIPS_LQSPI_CR_SEP_BUS_MASK | \
|
||||
LQSPI_CR_1_DUMMY_BYTE | \
|
||||
LQSPI_CR_FAST_QUAD_READ) /**< Fast Quad Read output */
|
||||
/*****************************************************************************/
|
||||
/**
|
||||
*
|
||||
* Main function to call the QSPI Flash example.
|
||||
*
|
||||
* @param None
|
||||
*
|
||||
* @return XST_SUCCESS if successful, otherwise XST_FAILURE.
|
||||
*
|
||||
* @note None
|
||||
|
@ -206,14 +233,12 @@ int main(void)
|
|||
}
|
||||
|
||||
|
||||
/*****************************************************************************
|
||||
*
|
||||
/****************************************************************************/
|
||||
/**
|
||||
* The purpose of this function is to illustrate how to use the XQspiPs
|
||||
* device driver in interrupt mode. This function writes and reads data
|
||||
* from a serial FLASH.
|
||||
*
|
||||
* @param None.
|
||||
*
|
||||
* @return XST_SUCCESS if successful else XST_FAILURE.
|
||||
*
|
||||
* @note
|
||||
|
@ -231,22 +256,25 @@ int QspiFlashPollExample(XScuGic *IntcInstancePtr, XQspiPs *QspiInstancePtr,
|
|||
u8 UniqueValue;
|
||||
int Count;
|
||||
int Page;
|
||||
XQspiPs_Config *ConfigPtr; /* Pointer to Configuration ROM data */
|
||||
int Status;
|
||||
u32 Options;
|
||||
|
||||
/*
|
||||
* Lookup the device configuration in the temporary CROM table. Use this
|
||||
* configuration info down below when initializing this component.
|
||||
*/
|
||||
ConfigPtr = XQspiPs_LookupConfig(QspiDeviceId);
|
||||
if (ConfigPtr == NULL) {
|
||||
return XST_DEVICE_NOT_FOUND;
|
||||
}
|
||||
/*
|
||||
* Lookup the device configuration in the temporary CROM table. Use this
|
||||
* configuration info down below when initializing this component.
|
||||
*/
|
||||
ConfigPtr = XQspiPs_LookupConfig(QspiDeviceId);
|
||||
if (ConfigPtr == NULL) {
|
||||
return XST_DEVICE_NOT_FOUND;
|
||||
}
|
||||
|
||||
XQspiPs_CfgInitialize(QspiInstancePtr, ConfigPtr,
|
||||
ConfigPtr->BaseAddress);
|
||||
Status = XQspiPs_CfgInitialize(QspiInstancePtr, ConfigPtr,
|
||||
ConfigPtr->BaseAddress);
|
||||
if (Status != XST_SUCCESS) {
|
||||
return XST_FAILURE;
|
||||
}
|
||||
|
||||
/*
|
||||
/*
|
||||
* Set the QSPI options
|
||||
*/
|
||||
Options = XQSPIPS_FORCE_SSELECT_OPTION |
|
||||
|
@ -255,48 +283,164 @@ int QspiFlashPollExample(XScuGic *IntcInstancePtr, XQspiPs *QspiInstancePtr,
|
|||
XIsf_SetSpiConfiguration(&Isf, QspiInstancePtr, Options,
|
||||
XISF_SPI_PRESCALER);
|
||||
|
||||
/* Initialize the XILISF Library */
|
||||
if(ConfigPtr->ConnectionMode == XQSPIPS_CONNECTION_MODE_STACKED) {
|
||||
/*
|
||||
* Enable two flash memories, Shared bus
|
||||
* (NOT separate bus), L_PAGE selected by default
|
||||
*/
|
||||
XQspiPs_SetLqspiConfigReg(QspiInstancePtr,
|
||||
DUAL_STACK_CONFIG_WRITE);
|
||||
}
|
||||
|
||||
if(ConfigPtr->ConnectionMode == XQSPIPS_CONNECTION_MODE_PARALLEL) {
|
||||
/*
|
||||
* Enable two flash memories on separate buses
|
||||
*/
|
||||
XQspiPs_SetLqspiConfigReg(QspiInstancePtr,
|
||||
DUAL_QSPI_CONFIG_WRITE);
|
||||
}
|
||||
|
||||
/* Initialize the XILISF Library */
|
||||
XIsf_Initialize(&Isf, QspiInstancePtr, FLASH_QSPI_SELECT,
|
||||
IsfWriteBuffer);
|
||||
IsfWriteBuffer);
|
||||
|
||||
/*
|
||||
* Initialize the write buffer for a pattern to write to the FLASH
|
||||
* and the read buffer to zero so it can be verified after the read, the
|
||||
* test value that is added to the unique value allows the value to be
|
||||
* changed in a debug environment to guarantee
|
||||
* and the read buffer to zero so it can be verified after the read,
|
||||
* the test value that is added to the unique value allows the value
|
||||
* to be changed in a debug environment to guarantee
|
||||
*/
|
||||
for (UniqueValue = UNIQUE_VALUE, Count = 0; Count < PAGE_SIZE;
|
||||
Count++, UniqueValue++) {
|
||||
WriteBuffer[Count] = (u8)(UniqueValue + Test);
|
||||
Count++, UniqueValue++) {
|
||||
WriteBuffer[Count] = (u8)(UniqueValue + Test_Polled);
|
||||
}
|
||||
memset(ReadBuffer, 0x00, sizeof(ReadBuffer));
|
||||
|
||||
FlashErase(&Isf, TEST_ADDRESS, MAX_DATA);
|
||||
|
||||
Status = FlashErase(&Isf, TEST_ADDRESS, MAX_DATA);
|
||||
if(Status != XST_SUCCESS){
|
||||
return XST_FAILURE;
|
||||
}
|
||||
|
||||
/*
|
||||
* Write the data in the write buffer to the serial FLASH a page at a
|
||||
* time, starting from TEST_ADDRESS
|
||||
*/
|
||||
|
||||
for (Page = 0; Page < PAGE_COUNT; Page++) {
|
||||
FlashWrite(&Isf, (Page * PAGE_SIZE) + TEST_ADDRESS,
|
||||
PAGE_SIZE, XISF_WRITE);
|
||||
Status = FlashWrite(&Isf,
|
||||
(Page * PAGE_SIZE) + TEST_ADDRESS, PAGE_SIZE,
|
||||
XISF_QUAD_IP_PAGE_WRITE);
|
||||
if(Status != XST_SUCCESS){
|
||||
return XST_FAILURE;
|
||||
}
|
||||
}
|
||||
|
||||
/******************************************************
|
||||
**********************NORMAL READ*********************
|
||||
******************************************************/
|
||||
|
||||
/*
|
||||
* Read the contents of the FLASH from TEST_ADDRESS, using Normal Read
|
||||
* command
|
||||
*/
|
||||
FlashRead(&Isf, TEST_ADDRESS, MAX_DATA, XISF_READ);
|
||||
Status = FlashRead(&Isf, TEST_ADDRESS, MAX_DATA, XISF_READ);
|
||||
if(Status != XST_SUCCESS){
|
||||
return XST_FAILURE;
|
||||
}
|
||||
|
||||
/*
|
||||
* Setup a pointer to the start of the data that was read into the read
|
||||
* buffer and verify the data read is the data that was written
|
||||
*/
|
||||
BufferPtr = ReadBuffer;
|
||||
for (UniqueValue = UNIQUE_VALUE, Count = 0; Count < MAX_DATA;
|
||||
Count++, UniqueValue++) {
|
||||
if (BufferPtr[Count] != (u8)(UniqueValue + Test_Polled)) {
|
||||
return XST_FAILURE;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/******************************************************
|
||||
**********************FAST READ***********************
|
||||
******************************************************/
|
||||
|
||||
/*
|
||||
* Read the contents of the FLASH from TEST_ADDRESS, using Fast Read
|
||||
* command
|
||||
*/
|
||||
Status = FlashRead(&Isf, TEST_ADDRESS, MAX_DATA,
|
||||
XISF_FAST_READ);
|
||||
if(Status != XST_SUCCESS){
|
||||
return XST_FAILURE;
|
||||
}
|
||||
|
||||
/*
|
||||
* Setup a pointer to the start of the data that was read into the read
|
||||
* buffer and verify the data read is the data that was written
|
||||
*/
|
||||
BufferPtr = &ReadBuffer[DATA_OFFSET];
|
||||
|
||||
BufferPtr = ReadBuffer;
|
||||
for (UniqueValue = UNIQUE_VALUE, Count = 0; Count < MAX_DATA;
|
||||
Count++, UniqueValue++) {
|
||||
if (BufferPtr[Count] != (u8)(UniqueValue + Test)) {
|
||||
Count++, UniqueValue++) {
|
||||
if (BufferPtr[Count] != (u8)(UniqueValue + Test_Polled)) {
|
||||
return XST_FAILURE;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/******************************************************
|
||||
******************DUAL OP FAST READ*******************
|
||||
******************************************************/
|
||||
|
||||
/*
|
||||
* Read the contents of the FLASH from TEST_ADDRESS, using DUAL OP
|
||||
* Fast Read command
|
||||
*/
|
||||
Status = FlashRead(&Isf, TEST_ADDRESS, MAX_DATA,
|
||||
XISF_DUAL_OP_FAST_READ);
|
||||
if(Status != XST_SUCCESS){
|
||||
return XST_FAILURE;
|
||||
}
|
||||
|
||||
/*
|
||||
* Setup a pointer to the start of the data that was read into the read
|
||||
* buffer and verify the data read is the data that was written
|
||||
*/
|
||||
|
||||
BufferPtr = ReadBuffer;
|
||||
for (UniqueValue = UNIQUE_VALUE, Count = 0; Count < MAX_DATA;
|
||||
Count++, UniqueValue++) {
|
||||
|
||||
if (BufferPtr[Count] != (u8)(UniqueValue + Test_Polled)) {
|
||||
return XST_FAILURE;
|
||||
}
|
||||
}
|
||||
|
||||
/******************************************************
|
||||
******************QUAD IO FAST READ*******************
|
||||
******************************************************/
|
||||
|
||||
/*
|
||||
* Read the contents of the FLASH from TEST_ADDRESS, using QUAD IO
|
||||
* Fast Read command
|
||||
*/
|
||||
Status = FlashRead(&Isf, TEST_ADDRESS, MAX_DATA,
|
||||
XISF_QUAD_OP_FAST_READ);
|
||||
if(Status != XST_SUCCESS){
|
||||
return XST_FAILURE;
|
||||
}
|
||||
|
||||
/*
|
||||
* Setup a pointer to the start of the data that was read into the read
|
||||
* buffer and verify the data read is the data that was written
|
||||
*/
|
||||
|
||||
BufferPtr = ReadBuffer;
|
||||
for (UniqueValue = UNIQUE_VALUE, Count = 0; Count < MAX_DATA;
|
||||
Count++, UniqueValue++) {
|
||||
if (BufferPtr[Count] != (u8)(UniqueValue + Test_Polled)) {
|
||||
return XST_FAILURE;
|
||||
}
|
||||
}
|
||||
|
@ -305,50 +449,10 @@ int QspiFlashPollExample(XScuGic *IntcInstancePtr, XQspiPs *QspiInstancePtr,
|
|||
}
|
||||
|
||||
|
||||
|
||||
/*****************************************************************************/
|
||||
/**
|
||||
*
|
||||
* This function waits till the STM Serial Flash is ready to accept next command.
|
||||
*
|
||||
* @param None.
|
||||
*
|
||||
* @return XST_SUCCESS if successful else XST_FAILURE.
|
||||
*
|
||||
* @note This function reads the status register of the Serial Flash and
|
||||
waits till the WIP bit of the status register becomes 0.
|
||||
*
|
||||
******************************************************************************/
|
||||
int IsfWaitForFlashNotBusy(void)
|
||||
{
|
||||
int Status;
|
||||
u8 StatusReg;
|
||||
|
||||
while(1) {
|
||||
|
||||
/*
|
||||
* Get the Status Register.
|
||||
*/
|
||||
Status = XIsf_GetStatus(&Isf, ReadBuffer);
|
||||
if(Status != XST_SUCCESS) {
|
||||
return XST_FAILURE;
|
||||
}
|
||||
|
||||
/*
|
||||
* Check if the flash is ready to accept the next command.
|
||||
* If so break.
|
||||
*/
|
||||
StatusReg = ReadBuffer[BYTE2];
|
||||
if((StatusReg & XISF_SR_IS_READY_MASK) == 0) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return XST_SUCCESS;
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
*
|
||||
* This function writes to the serial FLASH connected to the QSPI interface.
|
||||
* The FLASH contains a 256 byte write buffer which can be filled and then a
|
||||
* write is automatically performed by the device. All the data put into the
|
||||
|
@ -365,14 +469,13 @@ int IsfWaitForFlashNotBusy(void)
|
|||
* @note None.
|
||||
*
|
||||
******************************************************************************/
|
||||
int FlashWrite(XIsf *InstancePtr, u32 Address, u32 ByteCount, u8 Command)
|
||||
int FlashWrite(XIsf *InstancePtr, u32 Address, u32 ByteCount,
|
||||
u8 Command)
|
||||
{
|
||||
XIsf_WriteParam WriteParam;
|
||||
|
||||
int Status;
|
||||
|
||||
WriteEnable(InstancePtr);
|
||||
|
||||
WriteParam.Address = Address;
|
||||
WriteParam.NumBytes = ByteCount;
|
||||
WriteParam.WritePtr = WriteBuffer;
|
||||
|
@ -385,18 +488,11 @@ int FlashWrite(XIsf *InstancePtr, u32 Address, u32 ByteCount, u8 Command)
|
|||
return XST_FAILURE;
|
||||
}
|
||||
|
||||
/*
|
||||
* Wait till the Flash is not Busy.
|
||||
*/
|
||||
Status = IsfWaitForFlashNotBusy();
|
||||
if(Status != XST_SUCCESS) {
|
||||
return XST_FAILURE;
|
||||
}
|
||||
return XST_SUCCESS;
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
/*****************************************************************************/
|
||||
/**
|
||||
* This function reads from the serial FLASH connected to the
|
||||
* QSPI interface.
|
||||
*
|
||||
|
@ -418,13 +514,21 @@ int FlashRead(XIsf *InstancePtr, u32 Address, u32 ByteCount, u8 Command)
|
|||
/*
|
||||
* Set the
|
||||
* - Address in the Serial Flash where the data is to be read from.
|
||||
* - Number of bytes to be read from the Serial Flash.
|
||||
* - Number of bytes ReadParam.NumDummyBytesto be read from the Serial Flash.
|
||||
* - Read Buffer to which the data is to be read.
|
||||
*/
|
||||
ReadParam.Address = Address;
|
||||
ReadParam.NumBytes = ByteCount;
|
||||
ReadParam.ReadPtr = ReadBuffer;
|
||||
|
||||
if(Command == XISF_FAST_READ){
|
||||
ReadParam.NumDummyBytes = FAST_READ_NUM_DUMMY_BYTES;
|
||||
}
|
||||
else if(Command == XISF_DUAL_OP_FAST_READ){
|
||||
ReadParam.NumDummyBytes = DUAL_READ_NUM_DUMMY_BYTES;
|
||||
}
|
||||
else{
|
||||
ReadParam.NumDummyBytes = QUAD_READ_NUM_DUMMY_BYTES;
|
||||
}
|
||||
/*
|
||||
* Perform the Read operation.
|
||||
*/
|
||||
|
@ -436,15 +540,15 @@ int FlashRead(XIsf *InstancePtr, u32 Address, u32 ByteCount, u8 Command)
|
|||
return XST_SUCCESS;
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
/*****************************************************************************/
|
||||
/**
|
||||
*
|
||||
* This function erases the sectors in the serial FLASH connected to the
|
||||
* QSPI interface.
|
||||
*
|
||||
* @param InstancePtr is a pointer to the XIsf component to use.
|
||||
* @param Address contains the address of the first sector which needs to
|
||||
* be erased.
|
||||
* be erased.
|
||||
* @param ByteCount contains the total size to be erased.
|
||||
*
|
||||
* @return None.
|
||||
|
@ -456,42 +560,117 @@ int FlashErase(XIsf *InstancePtr, u32 Address, u32 ByteCount)
|
|||
{
|
||||
int Status;
|
||||
int Sector;
|
||||
u32 LqspiCr;
|
||||
u32 NumSect;
|
||||
u32 SectorSize;
|
||||
u32 NumSectors;
|
||||
u32 Sector_Mask;
|
||||
/*
|
||||
* Get the value of Sector Size and Number of Sectors for the flash
|
||||
*/
|
||||
SectorSize = Isf.SectorSize;
|
||||
NumSectors = Isf.NumSectors;
|
||||
|
||||
/* Get the sector mask value */
|
||||
Sector_Mask = SectorMask(SectorSize);
|
||||
|
||||
/*
|
||||
* If erase size is same as the total size of the flash, use bulk erase
|
||||
* command
|
||||
*/
|
||||
if (ByteCount == (NUM_SECTORS * SECTOR_SIZE)) {
|
||||
WriteEnable(InstancePtr);
|
||||
if (ByteCount == (NumSectors * SectorSize)) {
|
||||
|
||||
/*
|
||||
* Perform the Bulk Erase operation.
|
||||
*/
|
||||
Status = XIsf_Erase(InstancePtr, XISF_BULK_ERASE, Address);
|
||||
if(Status != XST_SUCCESS) {
|
||||
return XST_FAILURE;
|
||||
}
|
||||
#ifdef XPAR_XQSPIPS_0_DEVICE_ID
|
||||
if(ConfigPtr->ConnectionMode ==
|
||||
XQSPIPS_CONNECTION_MODE_STACKED){
|
||||
|
||||
/*
|
||||
* Wait till the Flash is not Busy.
|
||||
*/
|
||||
Status = IsfWaitForFlashNotBusy();
|
||||
if(Status != XST_SUCCESS) {
|
||||
return XST_FAILURE;
|
||||
/*
|
||||
* Get the current LQSPI configuration register value
|
||||
*/
|
||||
LqspiCr =
|
||||
XQspiPs_GetLqspiConfigReg(InstancePtr->SpiInstPtr);
|
||||
/*
|
||||
* Set selection to L_PAGE
|
||||
*/
|
||||
XQspiPs_SetLqspiConfigReg(InstancePtr->SpiInstPtr,
|
||||
LqspiCr & (~XQSPIPS_LQSPI_CR_U_PAGE_MASK));
|
||||
|
||||
/*
|
||||
* Assert the Flash chip select.
|
||||
*/
|
||||
XQspiPs_SetSlaveSelect(InstancePtr->SpiInstPtr);
|
||||
}
|
||||
#endif /*XPAR_XQSPIPS_0_DEVICE_ID*/
|
||||
|
||||
/*
|
||||
* Call Bulk erase
|
||||
*/
|
||||
Status = XIsf_Erase(InstancePtr,
|
||||
XISF_BULK_ERASE, Address);
|
||||
if(Status != XST_SUCCESS) {
|
||||
return XST_FAILURE;
|
||||
}
|
||||
|
||||
#ifdef XPAR_XQSPIPS_0_DEVICE_ID
|
||||
/*
|
||||
* If stacked mode, bulk erase second flash
|
||||
*/
|
||||
if(ConfigPtr->ConnectionMode ==
|
||||
XQSPIPS_CONNECTION_MODE_STACKED){
|
||||
|
||||
/*
|
||||
* Get the current LQSPI configuration register value
|
||||
*/
|
||||
LqspiCr =
|
||||
XQspiPs_GetLqspiConfigReg(InstancePtr->SpiInstPtr);
|
||||
/*
|
||||
* Set selection to U_PAGE
|
||||
*/
|
||||
XQspiPs_SetLqspiConfigReg(InstancePtr->SpiInstPtr,
|
||||
LqspiCr | XQSPIPS_LQSPI_CR_U_PAGE_MASK);
|
||||
|
||||
/*
|
||||
* Assert the Flash chip select.
|
||||
*/
|
||||
XQspiPs_SetSlaveSelect(InstancePtr->SpiInstPtr);
|
||||
|
||||
|
||||
/*
|
||||
* Call Bulk erase
|
||||
*/
|
||||
Status = XIsf_Erase(InstancePtr,
|
||||
XISF_BULK_ERASE, Address);
|
||||
if(Status != XST_SUCCESS) {
|
||||
return XST_FAILURE;
|
||||
}
|
||||
}
|
||||
#endif /*XPAR_XQSPIPS_0_DEVICE_ID*/
|
||||
|
||||
return Status;
|
||||
}
|
||||
|
||||
/*
|
||||
* Calculate no. of sectors to erase based on byte count
|
||||
*/
|
||||
NumSect = ByteCount/SectorSize + 1;
|
||||
|
||||
/*
|
||||
* If ByteCount to k sectors,
|
||||
* but the address range spans from N to N+k+1 sectors, then
|
||||
* increment no. of sectors to be erased
|
||||
*/
|
||||
|
||||
if( ((Address + ByteCount) & Sector_Mask) ==
|
||||
((Address + (NumSect * SectorSize)) &
|
||||
Sector_Mask) ) {
|
||||
NumSect++;
|
||||
}
|
||||
|
||||
/*
|
||||
* If the erase size is less than the total size of the flash, use
|
||||
* sector erase command
|
||||
*/
|
||||
for (Sector = 0; Sector < ((ByteCount / SECTOR_SIZE) + 1); Sector++) {
|
||||
/*
|
||||
* Write enable instruction has to be executed prior to
|
||||
* any Write operation.
|
||||
*/
|
||||
WriteEnable(InstancePtr);
|
||||
for (Sector = 0; Sector < NumSect; Sector++) {
|
||||
|
||||
/*
|
||||
* Perform the Sector Erase operation.
|
||||
|
@ -501,15 +680,7 @@ int FlashErase(XIsf *InstancePtr, u32 Address, u32 ByteCount)
|
|||
return XST_FAILURE;
|
||||
}
|
||||
|
||||
/*
|
||||
* Wait till the Flash is not Busy.
|
||||
*/
|
||||
Status = IsfWaitForFlashNotBusy();
|
||||
if(Status != XST_SUCCESS) {
|
||||
return XST_FAILURE;
|
||||
}
|
||||
|
||||
Address += SECTOR_SIZE;
|
||||
Address += SectorSize;
|
||||
}
|
||||
return XST_SUCCESS;
|
||||
}
|
||||
|
@ -517,34 +688,40 @@ int FlashErase(XIsf *InstancePtr, u32 Address, u32 ByteCount)
|
|||
/*****************************************************************************/
|
||||
/**
|
||||
*
|
||||
* This function performs the write enable operation.
|
||||
* This function calculates the sector mask based upon the sector size value
|
||||
*
|
||||
* @param None.
|
||||
*
|
||||
* @return XST_SUCCESS if successful else XST_FAILURE.
|
||||
* @param SectorSize is the size of the sector of the flash
|
||||
* available on the board.
|
||||
*
|
||||
* @return will return the sector mask after calculation.
|
||||
*
|
||||
* @note None.
|
||||
*
|
||||
******************************************************************************/
|
||||
int WriteEnable(XIsf *InstancePtr)
|
||||
{
|
||||
int Status;
|
||||
u32 SectorMask(u32 SectorSize){
|
||||
|
||||
/*
|
||||
* Perform the Write Enable operation.
|
||||
*/
|
||||
Status = XIsf_WriteEnable(&Isf, XISF_WRITE_ENABLE);
|
||||
if(Status != XST_SUCCESS) {
|
||||
return XST_FAILURE;
|
||||
u32 Mask;
|
||||
|
||||
switch(SectorSize){
|
||||
case 0x10000:
|
||||
Mask = 0xFFFF0000;
|
||||
break;
|
||||
|
||||
case 0x20000:
|
||||
Mask = 0xFFFE0000;
|
||||
break;
|
||||
case 0x40000:
|
||||
Mask = 0xFFFC0000;
|
||||
break;
|
||||
|
||||
case 0x80000:
|
||||
Mask = 0xFFF80000;
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
/*
|
||||
* Wait till the Flash is not Busy.
|
||||
*/
|
||||
Status = IsfWaitForFlashNotBusy();
|
||||
if(Status != XST_SUCCESS) {
|
||||
return XST_FAILURE;
|
||||
}
|
||||
return XST_SUCCESS;
|
||||
return Mask;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -58,7 +58,8 @@
|
|||
* or write operation. (CR 703816)
|
||||
* 3.02 srt 04/26/13 Modified Erase function to perform Write Enable operation
|
||||
* for each sector erase.
|
||||
*
|
||||
* 5.0 sb 08/05/14 Registering to Xilisf Interrupt handler
|
||||
* instead of driver handler.
|
||||
*</pre>
|
||||
*
|
||||
******************************************************************************/
|
||||
|
@ -265,7 +266,7 @@ int SpiFlashIntrExample(XScuGic *IntcInstancePtr, XSpiPs *SpiInstancePtr,
|
|||
* the SPI driver instance as the callback reference so the handler is
|
||||
* able to access the instance data
|
||||
*/
|
||||
XSpiPs_SetStatusHandler(SpiInstancePtr, SpiInstancePtr,
|
||||
XIsf_SetStatusHandler(&Isf, SpiInstancePtr,
|
||||
(XSpiPs_StatusHandler) SpiHandler);
|
||||
|
||||
|
||||
|
@ -305,7 +306,6 @@ int SpiFlashIntrExample(XScuGic *IntcInstancePtr, XSpiPs *SpiInstancePtr,
|
|||
for (UniqueValue = UNIQUE_VALUE, Count = 0; Count < MAX_DATA;
|
||||
Count++, UniqueValue++) {
|
||||
if (BufferPtr[Count] != (u8)(UniqueValue)) {
|
||||
xil_printf("Buffer %x Unique %x Count %d\n\r", BufferPtr[Count], UniqueValue, Count);
|
||||
return XST_FAILURE;
|
||||
}
|
||||
}
|
||||
|
@ -443,7 +443,7 @@ int FlashWrite(XIsf *InstancePtr, u32 Address, u32 ByteCount, u8 Command)
|
|||
|
||||
/*
|
||||
* Wait till the Transfer is complete and check if there are any errors
|
||||
* in the transaction.
|
||||
* in the transaction.
|
||||
*/
|
||||
while(TransferInProgress);
|
||||
if(ErrorCount != 0) {
|
||||
|
|
|
@ -257,7 +257,6 @@ int SpiFlashPolledExample(XSpiPs *SpiInstancePtr,
|
|||
for (UniqueValue = UNIQUE_VALUE, Count = 0; Count < MAX_DATA;
|
||||
Count++, UniqueValue++) {
|
||||
if (BufferPtr[Count] != (u8)(UniqueValue)) {
|
||||
xil_printf("Buffer %x Unique %x Count %d\n\r", BufferPtr[Count], UniqueValue, Count);
|
||||
return XST_FAILURE;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -58,7 +58,8 @@
|
|||
* ----- ---- -------- -----------------------------------------------
|
||||
* 2.04a sdm 08/25/11 First release
|
||||
* 3.02a adk 07/08/13 Fixed the CR 721229, by setting the proper QSPI options.
|
||||
*
|
||||
* 5.0 sb 08/05/14 Registering to Xilisf Interrupt handler
|
||||
* instead of driver handler.
|
||||
* </pre>
|
||||
*
|
||||
******************************************************************************/
|
||||
|
@ -221,7 +222,7 @@ int main()
|
|||
* driver instance as the callback reference so the handler is able to
|
||||
* access the instance data.
|
||||
*/
|
||||
XSpi_SetStatusHandler(&Spi, &Spi, (XSpi_StatusHandler)SpiHandler);
|
||||
XIsf_SetStatusHandler(&Isf, &Spi, (XSpi_StatusHandler)SpiHandler);
|
||||
|
||||
/*
|
||||
* Start the SPI driver so that interrupts and the device are enabled.
|
||||
|
@ -246,6 +247,11 @@ int main()
|
|||
return XST_FAILURE;
|
||||
}
|
||||
|
||||
/*
|
||||
* Set The transfer Mode to Interrupt
|
||||
*/
|
||||
XIsf_SetTransferMode(&Isf,XISF_INTERRUPT_MODE);
|
||||
|
||||
/*
|
||||
* Specify the address in the Serial Flash for the Erase/Write/Read
|
||||
* operations.
|
||||
|
|
|
@ -57,6 +57,8 @@
|
|||
* ----- ---- -------- -----------------------------------------------
|
||||
* 1.00a sdm 03/17/08 First release
|
||||
* 2.00a ktn 11/22/09 Updated to use HAL processor APIs.
|
||||
* 5.0 sb 08/05/14 Registering to Xilisf Interrupt handler
|
||||
* instead of driver handler.
|
||||
*
|
||||
* </pre>
|
||||
*
|
||||
|
@ -197,7 +199,7 @@ int main()
|
|||
* driver instance as the callback reference so the handler is able to
|
||||
* access the instance data.
|
||||
*/
|
||||
XSpi_SetStatusHandler(&Spi, &Spi, (XSpi_StatusHandler)SpiHandler);
|
||||
XIsf_SetStatusHandler(&Isf, &Spi, (XSpi_StatusHandler)SpiHandler);
|
||||
|
||||
/*
|
||||
* Start the SPI driver so that interrupts and the device are enabled.
|
||||
|
@ -212,6 +214,11 @@ int main()
|
|||
return XST_FAILURE;
|
||||
}
|
||||
|
||||
/*
|
||||
* Set The transfer Mode to Interrupt
|
||||
*/
|
||||
XIsf_SetTransferMode(&Isf,XISF_INTERRUPT_MODE);
|
||||
|
||||
/*
|
||||
* Specify the address in the Serial Flash for the Erase/Write/Read
|
||||
* operations.
|
||||
|
|
|
@ -60,7 +60,8 @@
|
|||
* ----- ---- -------- -----------------------------------------------
|
||||
* 1.00a sdm 03/17/08 First release
|
||||
* 2.00a ktn 11/22/09 Updated to use HAL processor APIs.
|
||||
*
|
||||
* 5.0 sb 08/05/14 Registering to Xilisf Interrupt handler
|
||||
* instead of driver handler.
|
||||
* </pre>
|
||||
*
|
||||
******************************************************************************/
|
||||
|
@ -207,7 +208,7 @@ int main()
|
|||
* driver instance as the callback reference so the handler is able to
|
||||
* access the instance data.
|
||||
*/
|
||||
XSpi_SetStatusHandler(&Spi, &Spi, (XSpi_StatusHandler)SpiHandler);
|
||||
XIsf_SetStatusHandler(&Isf, &Spi, (XSpi_StatusHandler)SpiHandler);
|
||||
|
||||
/*
|
||||
* Start the SPI driver so that interrupts and the device are enabled.
|
||||
|
@ -222,6 +223,11 @@ int main()
|
|||
return XST_FAILURE;
|
||||
}
|
||||
|
||||
/*
|
||||
* Set The transfer Mode to Interrupt
|
||||
*/
|
||||
XIsf_SetTransferMode(&Isf,XISF_INTERRUPT_MODE);
|
||||
|
||||
/*
|
||||
* Specify the address in the Serial Flash for the Erase/Write/Read
|
||||
* operations.
|
||||
|
|
|
@ -57,7 +57,8 @@
|
|||
* Ver Who Date Changes
|
||||
* ----- ---- -------- -----------------------------------------------
|
||||
* 2.04a sdm 08/25/11 First release
|
||||
*
|
||||
* 5.0 sb 08/05/14 Registering to Xilisf Interrupt handler
|
||||
* instead of driver handler.
|
||||
* </pre>
|
||||
*
|
||||
******************************************************************************/
|
||||
|
@ -220,7 +221,7 @@ int main()
|
|||
* driver instance as the callback reference so the handler is able to
|
||||
* access the instance data.
|
||||
*/
|
||||
XSpi_SetStatusHandler(&Spi, &Spi, (XSpi_StatusHandler)SpiHandler);
|
||||
XIsf_SetStatusHandler(&Isf, &Spi, (XSpi_StatusHandler)SpiHandler);
|
||||
|
||||
/*
|
||||
* Start the SPI driver so that interrupts and the device are enabled.
|
||||
|
@ -235,6 +236,11 @@ int main()
|
|||
return XST_FAILURE;
|
||||
}
|
||||
|
||||
/*
|
||||
* Set The transfer Mode to Interrupt
|
||||
*/
|
||||
XIsf_SetTransferMode(&Isf,XISF_INTERRUPT_MODE);
|
||||
|
||||
/*
|
||||
* Specify the address in the Serial Flash for the Erase/Write/Read
|
||||
* operations.
|
||||
|
|
|
@ -56,7 +56,8 @@
|
|||
* Ver Who Date Changes
|
||||
* ----- ---- -------- -----------------------------------------------
|
||||
* 2.01a sdm 03/17/10 First release
|
||||
*
|
||||
* 5.0 sb 08/05/14 Registering to Xilisf Interrupt handler
|
||||
* instead of driver handler.
|
||||
* </pre>
|
||||
*
|
||||
******************************************************************************/
|
||||
|
@ -196,7 +197,7 @@ int main()
|
|||
* driver instance as the callback reference so the handler is able to
|
||||
* access the instance data.
|
||||
*/
|
||||
XSpi_SetStatusHandler(&Spi, &Spi, (XSpi_StatusHandler)SpiHandler);
|
||||
XIsf_SetStatusHandler(&Isf, &Spi, (XSpi_StatusHandler)SpiHandler);
|
||||
|
||||
/*
|
||||
* Start the SPI driver so that interrupts and the device are enabled.
|
||||
|
@ -211,6 +212,11 @@ int main()
|
|||
return XST_FAILURE;
|
||||
}
|
||||
|
||||
/*
|
||||
* Set The transfer Mode to Interrupt
|
||||
*/
|
||||
XIsf_SetTransferMode(&Isf,XISF_INTERRUPT_MODE);
|
||||
|
||||
/*
|
||||
* Specify the address in the Serial Flash for the Erase/Write/Read
|
||||
* operations.
|
||||
|
|
|
@ -59,7 +59,8 @@
|
|||
* Ver Who Date Changes
|
||||
* ----- ---- -------- -----------------------------------------------
|
||||
* 2.01a sdm 03/17/10 First release
|
||||
*
|
||||
* 5.0 sb 08/05/14 Registering to Xilisf Interrupt handler
|
||||
* instead of driver handler.
|
||||
* </pre>
|
||||
*
|
||||
******************************************************************************/
|
||||
|
@ -206,7 +207,7 @@ int main()
|
|||
* driver instance as the callback reference so the handler is able to
|
||||
* access the instance data.
|
||||
*/
|
||||
XSpi_SetStatusHandler(&Spi, &Spi, (XSpi_StatusHandler)SpiHandler);
|
||||
XIsf_SetStatusHandler(&Isf, &Spi, (XSpi_StatusHandler)SpiHandler);
|
||||
|
||||
/*
|
||||
* Start the SPI driver so that interrupts and the device are enabled.
|
||||
|
@ -221,6 +222,11 @@ int main()
|
|||
return XST_FAILURE;
|
||||
}
|
||||
|
||||
/*
|
||||
* Set The transfer Mode to Interrupt
|
||||
*/
|
||||
XIsf_SetTransferMode(&Isf,XISF_INTERRUPT_MODE);
|
||||
|
||||
/*
|
||||
* Specify the address in the Serial Flash for the Erase/Write/Read
|
||||
* operations.
|
||||
|
|
|
@ -53,11 +53,11 @@
|
|||
*
|
||||
* <b>Library Description</b>
|
||||
*
|
||||
* The library enables higher layer software (e.g. an application) to communicate
|
||||
* with the Serial Flash.
|
||||
* The library enables higher layer software (e.g. an application) to
|
||||
* communicate with the Serial Flash.
|
||||
*
|
||||
* The library allows the user to Write, Read and Erase the Serial Flash.
|
||||
* The user can also protect the data stored in the Serial Flash from unwarranted
|
||||
* The user can also protect the data stored in Serial Flash from unwarranted
|
||||
* modification by enabling the Sector Protection feature. User can also perform
|
||||
* different Control operations on Intel, STM (Numonyx), Winbond and Spansion
|
||||
* Serial Flash devices.
|
||||
|
@ -293,7 +293,7 @@
|
|||
* This operation is supported only in Atmel Serial Flash.
|
||||
*
|
||||
* - Fast Buffer Read:
|
||||
* Read multiple contiguous bytes from the internal SRAM page buffer of the
|
||||
* Read multiple contiguous bytes from the internal SRAM page buffer of
|
||||
* Serial Flash at a higher speed than normal Buffer Read.
|
||||
* This operation is supported only for Atmel Serial Flash.
|
||||
*
|
||||
|
@ -306,7 +306,7 @@
|
|||
* The XIsf_Erase() API can be used to Erase the contents of the Serial Flash.
|
||||
* Once the user initiates an Erase operation, the Serial Flash takes time to
|
||||
* complete the Erase operation internally. The user has to read the Status
|
||||
* Register to know if the Serial Flash is still busy with a previously initiated
|
||||
* Register to know if Serial Flash is still busy with a previously initiated
|
||||
* operation before initiating a new one.
|
||||
*
|
||||
* Using the XIsf_Erase() API the user can perform four different types of Erase
|
||||
|
@ -336,7 +336,7 @@
|
|||
*
|
||||
* <b>Sector Protection Operations</b>
|
||||
*
|
||||
* The XIsf_SectorProtect() API can be used to perform Sector Protection related
|
||||
* The XIsf_SectorProtect() API can be used to perform Sector Protection related
|
||||
* operations. The Serial Flash is divided into Sectors. Each Sector or number of
|
||||
* Sectors can be protected from unwarranted writing/erasing.
|
||||
*
|
||||
|
@ -421,7 +421,7 @@
|
|||
*
|
||||
* For Intel, STM, Winbond and Spansion Serial Flash the user application must
|
||||
* enable the Write to the Serial Flash by calling XIsf_WriteEnable
|
||||
* (XISF_WRITE_ENABLE) API before doing any Write operations to the Serial Flash.
|
||||
* (XISF_WRITE_ENABLE) API before doing any Write operations to Serial Flash.
|
||||
* Writing to the Serial Flash is disabled by calling XIsf_WriteEnable
|
||||
* (XISF_WRITE_DISABLE) API.
|
||||
*
|
||||
|
@ -443,13 +443,13 @@
|
|||
* Ver Who Date Changes
|
||||
* ----- ------- -------- -----------------------------------------------
|
||||
* 1.00a ksu/sdm 03/03/08 First release
|
||||
* 2.00a ktn 11/27/09 Updated to use HAL processor APIs/definitions
|
||||
* 2.01a sdm 01/04/10 Added Support for Winbond W25Q80/16/32 devices
|
||||
* 2.01a sdm 06/17/10 Updated the Tcl to support axi_spi
|
||||
* 2.03a sdm 04/17/10 Updated to support Winbond memory W25Q128 and added
|
||||
* 2.00a ktn 11/27/09 Updated to use HAL processor APIs/definitions
|
||||
* 2.01a sdm 01/04/10 Added Support for Winbond W25Q80/16/32 devices
|
||||
* 2.01a sdm 06/17/10 Updated the Tcl to support axi_spi
|
||||
* 2.03a sdm 04/17/10 Updated to support Winbond memory W25Q128 and added
|
||||
* a list of supported flash memories
|
||||
* Updated the Tcl to support axi_quad_spi
|
||||
* 2.04a sdm 08/17/10 Updated to support Numonyx (N25QXX) and Spansion
|
||||
* 2.04a sdm 08/17/10 Updated to support Numonyx (N25QXX) and Spansion
|
||||
* flash memories
|
||||
* 3.00a srt 06/20/12 Updated to support interfaces SPI PS and QSPI PS.
|
||||
* New API:
|
||||
|
@ -475,8 +475,18 @@
|
|||
* (CR 703816)
|
||||
* - Updated spips and qspips examples to perform
|
||||
* Write enable operation in each sector
|
||||
* - Removed compiler errors when not selecting proper
|
||||
* interface for Zynq. (CR 716451)
|
||||
* - Removed compiler errors when not selecting proper
|
||||
* interface for Zynq. (CR 716451)
|
||||
* 5.0 sb 08/05/14 - Updated for support for > 128 MB flash for PSQSPI
|
||||
* Interface.
|
||||
* - Added Library Handler API which will
|
||||
* register to driver interrupts, based upon the
|
||||
* interface selected.
|
||||
* New API:
|
||||
* GetRealAddr()
|
||||
* SendBankSelect()
|
||||
* XIsf_SetStatusHandler()
|
||||
* XIsf_IfaceHandler()
|
||||
*
|
||||
* </pre>
|
||||
*
|
||||
|
@ -517,8 +527,8 @@ extern "C" {
|
|||
#endif
|
||||
|
||||
#if ((XPAR_XISF_FLASH_FAMILY == INTEL) || (XPAR_XISF_FLASH_FAMILY == STM) || \
|
||||
(XPAR_XISF_FLASH_FAMILY == WINBOND) || (XPAR_XISF_FLASH_FAMILY == SPANSION) \
|
||||
|| (XPAR_XISF_FLASH_FAMILY == SST))
|
||||
(XPAR_XISF_FLASH_FAMILY == WINBOND) || \
|
||||
(XPAR_XISF_FLASH_FAMILY == SPANSION) || (XPAR_XISF_FLASH_FAMILY == SST))
|
||||
#include "xilisf_intelstm.h"
|
||||
#endif
|
||||
|
||||
|
@ -534,13 +544,79 @@ extern "C" {
|
|||
#define XISF_MANUFACTURER_ID_WINBOND 0xEF /**< Winbond device */
|
||||
#define XISF_MANUFACTURER_ID_SPANSION 0x01 /**< Spansion device */
|
||||
#define XISF_MANUFACTURER_ID_SST 0xBF /**< SST device */
|
||||
#define XISF_MANUFACTURER_ID_MICRON 0x20 /**< Micron device */
|
||||
|
||||
#define XISF_SPANSION_ID_BYTE2_128 0x18
|
||||
#define XISF_SPANSION_ID_BYTE2_256 0x19
|
||||
#define XISF_SPANSION_ID_BYTE2_512 0x20
|
||||
/*Micron*/
|
||||
#define XISF_MICRON_ID_BYTE2_128 0x18
|
||||
#define XISF_MICRON_ID_BYTE2_256 0x19
|
||||
#define XISF_MICRON_ID_BYTE2_512 0x20
|
||||
#define XISF_MICRON_ID_BYTE2_1G 0x21
|
||||
/*Winbond*/
|
||||
#define XISF_WINBOND_ID_BYTE2_128 0x18
|
||||
|
||||
|
||||
|
||||
#define READ_STATUS_CMD 0x05
|
||||
#define WRITE_ENABLE_CMD 0x06
|
||||
#define READ_FLAG_STATUS_CMD 0x70
|
||||
|
||||
#define RD_ID_SIZE 4
|
||||
#define DIE_ERASE_SIZE 4
|
||||
#define DIE_ERASE_CMD 0xC4
|
||||
#define READ_ID 0x9F
|
||||
|
||||
/*
|
||||
* QSPI Flash Connection Mode
|
||||
*/
|
||||
#define XISF_QSPIPS_CONNECTION_MODE_SINGLE 0
|
||||
#define XISF_QSPIPS_CONNECTION_MODE_STACKED 1
|
||||
#define XISF_QSPIPS_CONNECTION_MODE_PARALLEL 2
|
||||
|
||||
/*
|
||||
* The index for Flash config table
|
||||
*/
|
||||
/* Spansion*/
|
||||
#define SPANSION_INDEX_START 0
|
||||
#define FLASH_CFG_TBL_SINGLE_128_SP SPANSION_INDEX_START
|
||||
#define FLASH_CFG_TBL_STACKED_128_SP (SPANSION_INDEX_START + 1)
|
||||
#define FLASH_CFG_TBL_PARALLEL_128_SP (SPANSION_INDEX_START + 2)
|
||||
#define FLASH_CFG_TBL_SINGLE_256_SP (SPANSION_INDEX_START + 3)
|
||||
#define FLASH_CFG_TBL_STACKED_256_SP (SPANSION_INDEX_START + 4)
|
||||
#define FLASH_CFG_TBL_PARALLEL_256_SP (SPANSION_INDEX_START + 5)
|
||||
#define FLASH_CFG_TBL_SINGLE_512_SP (SPANSION_INDEX_START + 6)
|
||||
#define FLASH_CFG_TBL_STACKED_512_SP (SPANSION_INDEX_START + 7)
|
||||
#define FLASH_CFG_TBL_PARALLEL_512_SP (SPANSION_INDEX_START + 8)
|
||||
|
||||
/* Micron */
|
||||
#define MICRON_INDEX_START (FLASH_CFG_TBL_PARALLEL_512_SP + 1)
|
||||
#define FLASH_CFG_TBL_SINGLE_128_MC MICRON_INDEX_START
|
||||
#define FLASH_CFG_TBL_STACKED_128_MC (MICRON_INDEX_START + 1)
|
||||
#define FLASH_CFG_TBL_PARALLEL_128_MC (MICRON_INDEX_START + 2)
|
||||
#define FLASH_CFG_TBL_SINGLE_256_MC (MICRON_INDEX_START + 3)
|
||||
#define FLASH_CFG_TBL_STACKED_256_MC (MICRON_INDEX_START + 4)
|
||||
#define FLASH_CFG_TBL_PARALLEL_256_MC (MICRON_INDEX_START + 5)
|
||||
#define FLASH_CFG_TBL_SINGLE_512_MC (MICRON_INDEX_START + 6)
|
||||
#define FLASH_CFG_TBL_STACKED_512_MC (MICRON_INDEX_START + 7)
|
||||
#define FLASH_CFG_TBL_PARALLEL_512_MC (MICRON_INDEX_START + 8)
|
||||
#define FLASH_CFG_TBL_SINGLE_1GB_MC (MICRON_INDEX_START + 9)
|
||||
#define FLASH_CFG_TBL_STACKED_1GB_MC (MICRON_INDEX_START + 10)
|
||||
#define FLASH_CFG_TBL_PARALLEL_1GB_MC (MICRON_INDEX_START + 11)
|
||||
|
||||
/* Winbond */
|
||||
#define WINBOND_INDEX_START (FLASH_CFG_TBL_PARALLEL_1GB_MC + 1)
|
||||
#define FLASH_CFG_TBL_SINGLE_128_WB WINBOND_INDEX_START
|
||||
#define FLASH_CFG_TBL_STACKED_128_WB (WINBOND_INDEX_START + 1)
|
||||
#define FLASH_CFG_TBL_PARALLEL_128_WB (WINBOND_INDEX_START + 2)
|
||||
|
||||
|
||||
/*
|
||||
* Interrupt or Polling mode of Operation Flags
|
||||
*/
|
||||
#define XISF_POLLING_MODE 0
|
||||
#define XISF_INTERRUPT_MODE 1
|
||||
|
||||
/*
|
||||
* SPI Options flags
|
||||
*/
|
||||
|
@ -577,7 +653,7 @@ typedef enum {
|
|||
XISF_AUTO_PAGE_WRITE, /**< Auto rewrite the contents
|
||||
* of the page */
|
||||
XISF_BUFFER_WRITE, /**< Write data to the internal
|
||||
* SRAM buffer of the Flash */
|
||||
* SRAM buffer of Flash */
|
||||
XISF_BUF_TO_PAGE_WRITE_WITH_ERASE, /**< Erase the specified Page
|
||||
* then Write data to Flash
|
||||
* from the internal SRAM
|
||||
|
@ -625,8 +701,8 @@ typedef enum {
|
|||
XISF_FAST_BUFFER_READ, /**< Fast SRAM buffer read operation on Flash */
|
||||
XISF_OTP_READ, /**< Read One Time Programmable area */
|
||||
|
||||
#if ((XPAR_XISF_FLASH_FAMILY == WINBOND) || (XPAR_XISF_FLASH_FAMILY == STM) || \
|
||||
(XPAR_XISF_FLASH_FAMILY == SPANSION))
|
||||
#if ((XPAR_XISF_FLASH_FAMILY == WINBOND) || (XPAR_XISF_FLASH_FAMILY == STM) \
|
||||
|| (XPAR_XISF_FLASH_FAMILY == SPANSION))
|
||||
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 */
|
||||
|
@ -648,8 +724,8 @@ typedef enum {
|
|||
} XIsf_EraseOperation;
|
||||
|
||||
/**
|
||||
* The following definitions determines the type of Sector protection operations
|
||||
* to be performed on the Serial Flash.
|
||||
* The following definitions determines the type of Sector protection
|
||||
* operations to be performed on the Serial Flash.
|
||||
*/
|
||||
typedef enum {
|
||||
XISF_SPR_READ, /**< Sector protect register read */
|
||||
|
@ -681,6 +757,8 @@ typedef XSpiPs XIsf_Iface;
|
|||
#elif XPAR_XISF_INTERFACE_PSQSPI
|
||||
typedef XQspiPs XIsf_Iface;
|
||||
#endif
|
||||
typedef void (*XIsf_StatusHandler) (void *CallBackRef, u32 StatusEvent,
|
||||
unsigned int ByteCount);
|
||||
|
||||
/**
|
||||
* The following definition specifies the instance structure of the Serial
|
||||
|
@ -701,6 +779,14 @@ typedef struct {
|
|||
* 0 - Default/Normal Addressing Mode
|
||||
* 1 - Power-Of-2 Addressing Mode */
|
||||
u16 DeviceCode; /**< The Serial Flash Device Code */
|
||||
#ifdef XPAR_XISF_INTERFACE_PSQSPI
|
||||
u8 DeviceIDMemSize; /**< Byte of device ID indicating the memory
|
||||
* size */
|
||||
u8 NumDie; /**< No. of die forming a single flash */
|
||||
u32 SectorSize; /**< Size of the Sector */
|
||||
u32 NumSectors; /**< No. of sectors */
|
||||
u32 ManufacturerID; /**< Serial Flash Manufacturer ID */
|
||||
#endif
|
||||
XIsf_Iface *SpiInstPtr; /**< SPI Device Instance pointer */
|
||||
u32 SpiSlaveSelect; /**< SPI Slave select for the Serial Flash */
|
||||
u8 *WriteBufPtr; /**< Pointer to Write Buffer */
|
||||
|
@ -722,13 +808,13 @@ typedef struct {
|
|||
(XIsf_Iface *InstancePtr);
|
||||
int (*XIsf_Iface_Transfer)
|
||||
(XIsf_Iface *InstancePtr, u8 *SendBufPtr,
|
||||
u8 *RecvBufPtr, unsigned int ByteCount);
|
||||
u8 *RecvBufPtr, unsigned int ByteCount);
|
||||
int (*XIsf_Iface_PolledTransfer)
|
||||
(XIsf_Iface *InstancePtr, u8 *SendBufPtr,
|
||||
u8 *RecvBufPtr, unsigned ByteCount);
|
||||
u8 *RecvBufPtr, unsigned ByteCount);
|
||||
int (*XIsf_Iface_SetClkPrescaler)
|
||||
(XIsf_Iface *InstancePtr, u8 PreScaler);
|
||||
|
||||
XIsf_StatusHandler StatusHandler;
|
||||
} XIsf;
|
||||
|
||||
/**
|
||||
|
@ -761,12 +847,10 @@ typedef struct {
|
|||
* fast read and quad i/o fast read */
|
||||
} XIsf_ReadParam;
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* The following structure definition specifies the operational parameters to be
|
||||
* passed to the XIsf_Write API while writing data to the internal SRAM buffer
|
||||
* of the Atmel Serial Flash (XISF_BUFFER_WRITE).
|
||||
* The following structure definition specifies the operational parameters to
|
||||
* be passed to the XIsf_Write API while writing data to the internal SRAM
|
||||
* buffer of the Atmel Serial Flash (XISF_BUFFER_WRITE).
|
||||
*/
|
||||
typedef struct {
|
||||
u8 BufferNum; /**< SRAM buffer number of Serial Flash */
|
||||
|
@ -778,7 +862,6 @@ typedef struct {
|
|||
* buffer */
|
||||
} XIsf_BufferWriteParam;
|
||||
|
||||
|
||||
/**
|
||||
* The following structure definition specifies the operational parameters to be
|
||||
* passed to the XIsf_Write API while writing data from the internal SRAM buffer
|
||||
|
@ -801,7 +884,7 @@ typedef struct {
|
|||
} XIsf_FlashToBufTransferParam;
|
||||
|
||||
/**
|
||||
* The following structure definition specifies the operational parameters to be
|
||||
* The following structure definition specifies operational parameters to be
|
||||
* passed to the XIsf_Read API while reading data from the Internal SRAM buffer
|
||||
* of Flash using XISF_BUFFER_READ or XISF_FAST_BUFFER_READ commands in Atmel
|
||||
* Serial Flash.
|
||||
|
@ -838,6 +921,20 @@ static inline void XIsf_SetTransferMode(XIsf *InstancePtr, u8 Mode)
|
|||
InstancePtr->IntrMode = Mode;
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
/**
|
||||
*
|
||||
* This API gets the interrupt/polling mode of transfer.
|
||||
*
|
||||
* @param InstancePtr is a pointer to the XIsf instance.
|
||||
*
|
||||
* @note (shakti)
|
||||
******************************************************************************/
|
||||
static inline u8 XIsf_GetTransferMode(XIsf *InstancePtr)
|
||||
{
|
||||
return(InstancePtr->IntrMode);
|
||||
}
|
||||
|
||||
/************************** Function Prototypes ******************************/
|
||||
|
||||
/*
|
||||
|
@ -855,6 +952,7 @@ int XIsf_GetStatus(XIsf *InstancePtr, u8 *ReadPtr);
|
|||
int XIsf_GetStatusReg2(XIsf *InstancePtr, u8 *ReadPtr);
|
||||
#endif
|
||||
|
||||
|
||||
/*
|
||||
* Function to read the Serial Flash information.
|
||||
*/
|
||||
|
@ -889,7 +987,7 @@ int XIsf_SectorProtect(XIsf *InstancePtr, XIsf_SpOperation Operation,
|
|||
int XIsf_Ioctl(XIsf *InstancePtr, XIsf_IoctlOperation Operation);
|
||||
|
||||
/*
|
||||
* Function for Enabling/Disabling Write to the Intel, STM, Winbond and Spansion
|
||||
* Function for Enabling/Disabling Write to Intel, STM, Winbond and Spansion
|
||||
* Serial Flash.
|
||||
*/
|
||||
int XIsf_WriteEnable(XIsf *InstancePtr, u8 WriteEnable);
|
||||
|
@ -905,6 +1003,18 @@ void XIsf_RegisterInterface(XIsf *InstancePtr);
|
|||
int XIsf_SetSpiConfiguration(XIsf *InstancePtr, XIsf_Iface *SpiInstPtr,
|
||||
u32 Options, u8 PreScaler);
|
||||
|
||||
/*
|
||||
*Interrupt Status Handler of XilIsf Lib
|
||||
*/
|
||||
void XIsf_SetStatusHandler(XIsf *InstancePtr, XIsf_Iface *QspiInstancePtr,
|
||||
XIsf_StatusHandler XilIsf_Handler);
|
||||
|
||||
/*
|
||||
*Interrupt Handler of XilISF Lib
|
||||
*/
|
||||
void XIsf_IfaceHandler(void *CallBackRef, u32 StatusEvent,
|
||||
unsigned int ByteCount);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -49,6 +49,13 @@
|
|||
* flash memories
|
||||
* 3.02a srt 04/25/13 Added Bulk Erase command support for SST and
|
||||
* Spansion flashes.
|
||||
* 5.0 sb 08/05/14 Updated support for > 128 MB flash for PSQSPI
|
||||
* interface.
|
||||
* New API:
|
||||
* DieErase()
|
||||
* Changed API:
|
||||
* SectorErase()
|
||||
* BulkErase()
|
||||
* </pre>
|
||||
*
|
||||
******************************************************************************/
|
||||
|
@ -58,7 +65,7 @@
|
|||
#include "include/xilisf.h"
|
||||
|
||||
/************************** Constant Definitions *****************************/
|
||||
|
||||
#define SIXTEENMB 0x1000000 /**< Sixteen MB */
|
||||
/**************************** Type Definitions *******************************/
|
||||
|
||||
/***************** Macros (Inline Functions) Definitions *********************/
|
||||
|
@ -67,13 +74,21 @@
|
|||
|
||||
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 PageErase(XIsf *InstancePtr, u32 Address);
|
||||
static int BlockErase(XIsf *InstancePtr, u32 Address);
|
||||
static int SectorErase(XIsf *InstancePtr, u32 Address);
|
||||
static int BulkErase(XIsf *InstancePtr);
|
||||
|
||||
#ifdef XPAR_XISF_INTERFACE_PSQSPI
|
||||
static int DieErase(XIsf *InstancePtr);
|
||||
#endif
|
||||
/************************** Variable Definitions *****************************/
|
||||
|
||||
extern u32 XIsf_StatusEventInfo;
|
||||
extern unsigned int XIsf_ByteCountInfo;
|
||||
/************************** Function Definitions ******************************/
|
||||
|
||||
|
||||
|
@ -100,9 +115,10 @@ static int BulkErase(XIsf *InstancePtr);
|
|||
* - The erased bytes will read as 0xFF.
|
||||
* - For Intel, STM, Winbond or Spansion Serial Flash the user
|
||||
* application must call XIsf_WriteEnable() API by passing
|
||||
* XISF_WRITE_ENABLE as an argument before calling the XIsf_Erase()
|
||||
* XISF_WRITE_ENABLE as an argument before calling XIsf_Erase()
|
||||
* API.
|
||||
* - Atmel Serial Flash support Page/Block/Sector Erase operations.
|
||||
* - Atmel Serial Flash support Page/Block/Sector Erase
|
||||
- operations.
|
||||
* - Intel, Winbond, Numonyx (N25QXX) and Spansion Serial Flash
|
||||
* support Sector/Block/Bulk Erase operations.
|
||||
* - STM (M25PXX) Serial Flash support Sector/Bulk Erase
|
||||
|
@ -111,14 +127,15 @@ static int BulkErase(XIsf *InstancePtr);
|
|||
******************************************************************************/
|
||||
int XIsf_Erase(XIsf *InstancePtr, XIsf_EraseOperation Operation, u32 Address)
|
||||
{
|
||||
int Status = XST_FAILURE;
|
||||
int Status = (int)(XST_FAILURE);
|
||||
u8 Mode;
|
||||
|
||||
if (InstancePtr == NULL) {
|
||||
return XST_FAILURE;
|
||||
return (int)(XST_FAILURE);
|
||||
}
|
||||
|
||||
if (InstancePtr->IsReady != TRUE) {
|
||||
return XST_FAILURE;
|
||||
return (int)(XST_FAILURE);
|
||||
}
|
||||
|
||||
switch (Operation) {
|
||||
|
@ -143,6 +160,17 @@ int XIsf_Erase(XIsf *InstancePtr, XIsf_EraseOperation Operation, u32 Address)
|
|||
break;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Get the Transfer Mode
|
||||
*/
|
||||
Mode = XIsf_GetTransferMode(InstancePtr);
|
||||
|
||||
if(Mode == XISF_INTERRUPT_MODE){
|
||||
InstancePtr->StatusHandler(InstancePtr,
|
||||
XIsf_StatusEventInfo, XIsf_ByteCountInfo);
|
||||
}
|
||||
|
||||
return Status;
|
||||
}
|
||||
|
||||
|
@ -153,7 +181,7 @@ int XIsf_Erase(XIsf *InstancePtr, XIsf_EraseOperation Operation, u32 Address)
|
|||
* This function erases the contents of the specified Page in the Serial Flash.
|
||||
*
|
||||
* @param InstancePtr is a pointer to the XIsf instance.
|
||||
* @param Address is the address of the Page to be erased. This can be any
|
||||
* @param Address is the address of Page to be erased. This can be any
|
||||
* address in the Page to be erased. The Byte address values in
|
||||
* this address are ignored.
|
||||
*
|
||||
|
@ -166,7 +194,10 @@ int XIsf_Erase(XIsf *InstancePtr, XIsf_EraseOperation Operation, u32 Address)
|
|||
******************************************************************************/
|
||||
static int PageErase(XIsf *InstancePtr, u32 Address)
|
||||
{
|
||||
int Status = XST_FAILURE;
|
||||
int Status = (int)(XST_FAILURE);
|
||||
|
||||
Xil_AssertNonvoid(InstancePtr != NULL);
|
||||
Xil_AssertNonvoid(Address != 0);
|
||||
|
||||
#if (XPAR_XISF_FLASH_FAMILY == ATMEL)
|
||||
InstancePtr->WriteBufPtr[BYTE1] = XISF_CMD_PAGE_ERASE;
|
||||
|
@ -179,8 +210,8 @@ static int PageErase(XIsf *InstancePtr, u32 Address)
|
|||
*/
|
||||
Status = XIsf_Transfer(InstancePtr, InstancePtr->WriteBufPtr,
|
||||
NULL, XISF_CMD_SEND_EXTRA_BYTES);
|
||||
if (Status != XST_SUCCESS) {
|
||||
return XST_FAILURE;
|
||||
if (Status != (int)(XST_SUCCESS)) {
|
||||
return (int)(XST_FAILURE);
|
||||
}
|
||||
#endif /* (XPAR_XISF_FLASH_FAMILY == ATMEL) */
|
||||
|
||||
|
@ -207,10 +238,13 @@ static int PageErase(XIsf *InstancePtr, u32 Address)
|
|||
******************************************************************************/
|
||||
static int BlockErase(XIsf *InstancePtr, u32 Address)
|
||||
{
|
||||
int Status = XST_FAILURE;
|
||||
int Status = (int)(XST_FAILURE);
|
||||
|
||||
#if ((XPAR_XISF_FLASH_FAMILY == ATMEL) || (XPAR_XISF_FLASH_FAMILY == INTEL) || \
|
||||
(XPAR_XISF_FLASH_FAMILY == WINBOND))
|
||||
Xil_AssertNonvoid(InstancePtr != NULL);
|
||||
Xil_AssertNonvoid(Address != 0);
|
||||
|
||||
#if ((XPAR_XISF_FLASH_FAMILY == ATMEL) || (XPAR_XISF_FLASH_FAMILY == INTEL) \
|
||||
|| (XPAR_XISF_FLASH_FAMILY == WINBOND))
|
||||
|
||||
#if ((XPAR_XISF_FLASH_FAMILY == ATMEL) || (XPAR_XISF_FLASH_FAMILY == WINBOND))
|
||||
InstancePtr->WriteBufPtr[BYTE1] = XISF_CMD_BLOCK_ERASE;
|
||||
|
@ -229,8 +263,8 @@ static int BlockErase(XIsf *InstancePtr, u32 Address)
|
|||
*/
|
||||
Status = XIsf_Transfer(InstancePtr, InstancePtr->WriteBufPtr,
|
||||
NULL, XISF_CMD_SEND_EXTRA_BYTES);
|
||||
if (Status != XST_SUCCESS) {
|
||||
return XST_FAILURE;
|
||||
if (Status != (int)(XST_SUCCESS)) {
|
||||
return (int)(XST_FAILURE);
|
||||
}
|
||||
#endif /* ((XPAR_XISF_FLASH_FAMILY==ATMEL)||(XPAR_XISF_FLASH_FAMILY==INTEL)) */
|
||||
|
||||
|
@ -240,7 +274,7 @@ static int BlockErase(XIsf *InstancePtr, u32 Address)
|
|||
/*****************************************************************************/
|
||||
/**
|
||||
*
|
||||
* This function erases the contents of the specified Sector in the Serial Flash.
|
||||
* This function erases the contents of the specified Sector in Serial Flash.
|
||||
*
|
||||
* @param InstancePtr is a pointer to the XIsf instance.
|
||||
* @param Address is the address of the Sector to be erased. This can be
|
||||
|
@ -251,29 +285,137 @@ static int BlockErase(XIsf *InstancePtr, u32 Address)
|
|||
*
|
||||
* @note
|
||||
* - The erased bytes will read as 0xFF.
|
||||
* - This operation is supported for Atmel, Intel, STM, Winbond and
|
||||
* Spansion Serial Flash.
|
||||
* - This operation is supported for Atmel, Intel, STM, Winbond
|
||||
* and Spansion Serial Flash.
|
||||
*
|
||||
******************************************************************************/
|
||||
static int SectorErase(XIsf *InstancePtr, u32 Address)
|
||||
{
|
||||
int Status;
|
||||
int Status = (int)(XST_FAILURE);
|
||||
u8 Mode;
|
||||
u32 BankSel;
|
||||
u32 RealAddr;
|
||||
u8* NULLPtr = NULL;
|
||||
u8 FlagStatus[2] = {0};
|
||||
u8 FlashStatus[2] = {0};
|
||||
u8 ReadStatusCmdBuf[] = { READ_STATUS_CMD, 0 };
|
||||
u8 ReadFlagSRCmd[] = {READ_FLAG_STATUS_CMD, 0};
|
||||
#ifdef XPAR_XISF_INTERFACE_PSQSPI
|
||||
u32 FlashMake = InstancePtr->ManufacturerID;
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Translate address based on type of connection
|
||||
* If stacked assert the slave select based on address
|
||||
*/
|
||||
RealAddr = GetRealAddr(InstancePtr->SpiInstPtr, Address);
|
||||
|
||||
#ifdef XPAR_XISF_INTERFACE_PSQSPI
|
||||
/*
|
||||
* Initial bank selection
|
||||
*/
|
||||
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);
|
||||
|
||||
/*
|
||||
* Calculate initial bank
|
||||
*/
|
||||
BankSel = RealAddr/SIXTEENMB;
|
||||
/*
|
||||
* Select bank
|
||||
*/
|
||||
Status = SendBankSelect(InstancePtr, BankSel);
|
||||
|
||||
/*
|
||||
* Restoring the transfer mode back
|
||||
*/
|
||||
XIsf_SetTransferMode(InstancePtr, Mode);
|
||||
|
||||
if(Status!=(int)(XST_SUCCESS)){
|
||||
return (int)XST_FAILURE;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
InstancePtr->WriteBufPtr[BYTE1] = XISF_CMD_SECTOR_ERASE;
|
||||
InstancePtr->WriteBufPtr[BYTE2] = (u8) (Address >> XISF_ADDR_SHIFT16);
|
||||
InstancePtr->WriteBufPtr[BYTE3] = (u8) (Address >> XISF_ADDR_SHIFT8);
|
||||
InstancePtr->WriteBufPtr[BYTE4] = (u8) XISF_DUMMYBYTE;
|
||||
InstancePtr->WriteBufPtr[BYTE2] = (u8) (RealAddr >> XISF_ADDR_SHIFT16);
|
||||
InstancePtr->WriteBufPtr[BYTE3] = (u8) (RealAddr >> XISF_ADDR_SHIFT8);
|
||||
InstancePtr->WriteBufPtr[BYTE4] = (u8) (RealAddr);
|
||||
|
||||
#ifdef XPAR_XISF_INTERFACE_PSQSPI
|
||||
/*
|
||||
* Enable write before transfer
|
||||
*/
|
||||
Status = XIsf_WriteEnable(InstancePtr, XISF_WRITE_ENABLE);
|
||||
if (Status != (int)XST_SUCCESS) {
|
||||
return (int)XST_FAILURE;
|
||||
}
|
||||
#endif
|
||||
Xil_AssertNonvoid(NULLPtr == NULL);
|
||||
|
||||
/*
|
||||
* Initiate the Transfer.
|
||||
*/
|
||||
Status = XIsf_Transfer(InstancePtr, InstancePtr->WriteBufPtr,
|
||||
NULL, XISF_CMD_SEND_EXTRA_BYTES);
|
||||
if (Status != XST_SUCCESS) {
|
||||
return XST_FAILURE;
|
||||
NULLPtr, XISF_CMD_SEND_EXTRA_BYTES);
|
||||
|
||||
if (Status != (int)XST_SUCCESS) {
|
||||
return (int)XST_FAILURE;
|
||||
}
|
||||
|
||||
return XST_SUCCESS;
|
||||
#ifdef XPAR_XISF_INTERFACE_PSQSPI
|
||||
if((InstancePtr->NumDie > (u8)1) &&
|
||||
(FlashMake == (u32)XISF_MANUFACTURER_ID_MICRON)) {
|
||||
|
||||
Status = XIsf_Transfer(InstancePtr, ReadFlagSRCmd, FlagStatus,
|
||||
(u32)sizeof(ReadFlagSRCmd));
|
||||
}
|
||||
|
||||
/*
|
||||
* Wait for the sector erase command to the Flash to be completed
|
||||
*/
|
||||
while (1) {
|
||||
/*
|
||||
* Poll the status register of the device to determine
|
||||
* when it completes, by sending a read status command
|
||||
* and receiving the status byte
|
||||
*/
|
||||
Status = XIsf_Transfer(InstancePtr, ReadStatusCmdBuf,
|
||||
FlashStatus,
|
||||
(u32)sizeof(ReadStatusCmdBuf));
|
||||
|
||||
/*
|
||||
* If the status indicates the write is done, then stop
|
||||
* waiting, if a value of 0xFF in the status byte is
|
||||
* read from the device and this loop never exits, the
|
||||
* device slave select is possibly incorrect such that
|
||||
* the device status is not being read
|
||||
*/
|
||||
if ((FlashStatus[1] & 0x01) == 0) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if((InstancePtr->NumDie > (u8)1) &&
|
||||
(FlashMake == (u32)XISF_MANUFACTURER_ID_MICRON)) {
|
||||
|
||||
Status =
|
||||
XIsf_Transfer(InstancePtr, ReadFlagSRCmd, FlagStatus,
|
||||
(u32)sizeof(ReadFlagSRCmd));
|
||||
}
|
||||
#endif
|
||||
|
||||
return Status;
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
|
@ -293,22 +435,43 @@ static int SectorErase(XIsf *InstancePtr, u32 Address)
|
|||
******************************************************************************/
|
||||
static int BulkErase(XIsf *InstancePtr)
|
||||
{
|
||||
int Status = XST_FAILURE;
|
||||
int Status = (int)(XST_FAILURE);
|
||||
u8* NULLPtr = NULL;
|
||||
|
||||
#if ((XPAR_XISF_FLASH_FAMILY == INTEL) || (XPAR_XISF_FLASH_FAMILY == STM) || \
|
||||
(XPAR_XISF_FLASH_FAMILY == WINBOND) || (XPAR_XISF_FLASH_FAMILY == SST) || \
|
||||
(XPAR_XISF_FLASH_FAMILY == SPANSION))
|
||||
InstancePtr->WriteBufPtr[BYTE1] = XISF_CMD_BULK_ERASE;
|
||||
(XPAR_XISF_FLASH_FAMILY == WINBOND) || (XPAR_XISF_FLASH_FAMILY == SST) \
|
||||
|| (XPAR_XISF_FLASH_FAMILY == SPANSION))
|
||||
|
||||
#ifdef XPAR_XISF_INTERFACE_PSQSPI
|
||||
/*
|
||||
* Initiate the Transfer.
|
||||
* If the number of die is greater than 1 call die erase
|
||||
*/
|
||||
Status = XIsf_Transfer(InstancePtr, InstancePtr->WriteBufPtr,
|
||||
NULL, XISF_BULK_ERASE_BYTES);
|
||||
if (Status != XST_SUCCESS) {
|
||||
return XST_FAILURE;
|
||||
if(InstancePtr->NumDie > 1){
|
||||
Status = DieErase(InstancePtr);
|
||||
}
|
||||
|
||||
else{
|
||||
#endif
|
||||
InstancePtr->WriteBufPtr[BYTE1] = XISF_CMD_BULK_ERASE;
|
||||
|
||||
/*
|
||||
* Enable write before transfer
|
||||
*/
|
||||
Status = XIsf_WriteEnable(InstancePtr, XISF_WRITE_ENABLE);
|
||||
if (Status != (int)XST_SUCCESS) {
|
||||
return (int)XST_FAILURE;
|
||||
}
|
||||
|
||||
Xil_AssertNonvoid(NULLPtr == NULL);
|
||||
|
||||
/*
|
||||
* Initiate the Transfer.
|
||||
*/
|
||||
Status = XIsf_Transfer(InstancePtr, InstancePtr->WriteBufPtr,
|
||||
NULLPtr, XISF_BULK_ERASE_BYTES);
|
||||
#ifdef XPAR_XISF_INTERFACE_PSQSPI
|
||||
}
|
||||
#endif
|
||||
#endif /* ((XPAR_XISF_FLASH_FAMILY==INTEL)||(XPAR_XISF_FLASH_FAMILY==STM)) \
|
||||
(XPAR_XISF_FLASH_FAMILY == WINBOND) ||
|
||||
(XPAR_XISF_FLASH_FAMILY == SST) ||
|
||||
|
@ -316,3 +479,105 @@ static int BulkErase(XIsf *InstancePtr)
|
|||
|
||||
return Status;
|
||||
}
|
||||
|
||||
#ifdef XPAR_XISF_INTERFACE_PSQSPI
|
||||
/*****************************************************************************/
|
||||
/**
|
||||
*
|
||||
* This function erases the content of a Die of Serial Flash.
|
||||
*
|
||||
* @param InstancePtr is a pointer to the XIsf instance.
|
||||
*
|
||||
* @return XST_SUCCESS if successful else XST_FAILURE.
|
||||
*
|
||||
* @note
|
||||
* - This operation is supported for Winbond,
|
||||
* Spansion and Micron Serial Flashes.
|
||||
*
|
||||
******************************************************************************/
|
||||
static int DieErase(XIsf *InstancePtr)
|
||||
{
|
||||
int Status = (int)(XST_FAILURE);
|
||||
u8* NULLPtr = NULL;
|
||||
#if ((XPAR_XISF_FLASH_FAMILY == WINBOND) || \
|
||||
(XPAR_XISF_FLASH_FAMILY == SPANSION))
|
||||
|
||||
u8 DieCnt;
|
||||
u8 ReadFlagSRCmd[] = { READ_FLAG_STATUS_CMD, 0 };
|
||||
u8 FlagStatus[2] = {0};
|
||||
|
||||
for(DieCnt = 0; DieCnt < InstancePtr->NumDie; DieCnt++) {
|
||||
/*
|
||||
* Select bank - the lower of the 2 banks in each die
|
||||
* This is specific to Micron flash
|
||||
*/
|
||||
Status = SendBankSelect(InstancePtr, DieCnt*2);
|
||||
|
||||
/*
|
||||
* Setup the write command with the specified address and data
|
||||
* for the Flash
|
||||
*/
|
||||
/*
|
||||
* This ensures 3B address is sent to flash even with address
|
||||
* greater than 128Mb.
|
||||
* The address is the start address of die - MSB bits will be
|
||||
* derived from bank select by the flash
|
||||
*/
|
||||
InstancePtr->WriteBufPtr[BYTE1] = DIE_ERASE_CMD;
|
||||
InstancePtr->WriteBufPtr[BYTE2] = 0x00;
|
||||
InstancePtr->WriteBufPtr[BYTE3] = 0x00;
|
||||
InstancePtr->WriteBufPtr[BYTE4] = 0x00;
|
||||
|
||||
/*
|
||||
* Enable write before transfer
|
||||
*/
|
||||
Status = XIsf_WriteEnable(InstancePtr, XISF_WRITE_ENABLE);
|
||||
if (Status != (int)XST_SUCCESS) {
|
||||
return (int)XST_FAILURE;
|
||||
}
|
||||
|
||||
Xil_AssertNonvoid(NULLPtr == NULL);
|
||||
|
||||
/*
|
||||
* Send the sector erase command and address; no receive buffer
|
||||
* is specified since there is nothing to receive
|
||||
*/
|
||||
Status =
|
||||
XIsf_Transfer(InstancePtr, InstancePtr->WriteBufPtr, NULLPtr,
|
||||
DIE_ERASE_SIZE);
|
||||
|
||||
/*
|
||||
* Wait for the sector erase command to Flash to be completed
|
||||
*/
|
||||
while (1) {
|
||||
|
||||
/*
|
||||
* Poll the status register of the device to determine
|
||||
* when it completes, by sending a read status command
|
||||
* and receiving the status byte
|
||||
*/
|
||||
Status =
|
||||
XIsf_Transfer(InstancePtr, ReadFlagSRCmd, FlagStatus,
|
||||
(u32)sizeof(ReadFlagSRCmd));
|
||||
|
||||
/*
|
||||
* If the status indicates the write is done, then stop
|
||||
* waiting, if a value of 0xFF in the status byte is
|
||||
* read from the device and this loop never exits, the
|
||||
* device slave select is possibly incorrect such that
|
||||
* the device status is not being read
|
||||
*/
|
||||
if ((FlagStatus[1] & (u8)0x80) == (u8)0x80) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#endif /* ((XPAR_XISF_FLASH_FAMILY == WINBOND) || \
|
||||
(XPAR_XISF_FLASH_FAMILY == SPANSION)) */
|
||||
|
||||
return Status;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
|
|
@ -47,7 +47,11 @@
|
|||
* 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>
|
||||
*
|
||||
******************************************************************************/
|
||||
|
@ -59,6 +63,8 @@
|
|||
/************************** Constant Definitions *****************************/
|
||||
|
||||
#define FAST_READ_NUM_DUMMY_BYTES 1
|
||||
#define SIXTEENMB 0x1000000 /**< Sixteen MB */
|
||||
#define BANKMASK 0xF000000 /**< Bank mask */
|
||||
|
||||
/**************************** Type Definitions *******************************/
|
||||
|
||||
|
@ -68,8 +74,16 @@
|
|||
|
||||
extern int XIsf_Transfer(XIsf *InstancePtr, u8 *WritePtr, u8* ReadPtr,
|
||||
u32 ByteCount);
|
||||
static int ReadData(XIsf *InstancePtr, u32 Address, u8 *ReadPtr, u32 ByteCount);
|
||||
static int FastReadData(XIsf *InstancePtr, u8 Command, u32 Address, u8 *ReadPtr,
|
||||
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,
|
||||
|
@ -80,7 +94,8 @@ static int ReadOTPData(XIsf *InstancePtr, u32 Address, u8 *ReadPtr,
|
|||
u32 ByteCount);
|
||||
|
||||
/************************** Variable Definitions *****************************/
|
||||
|
||||
extern u32 XIsf_StatusEventInfo;
|
||||
extern unsigned int XIsf_ByteCountInfo;
|
||||
/************************** Function Definitions ******************************/
|
||||
|
||||
/*****************************************************************************/
|
||||
|
@ -107,9 +122,9 @@ static int ReadOTPData(XIsf *InstancePtr, u32 Address, u8 *ReadPtr,
|
|||
* 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
|
||||
* 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.
|
||||
|
@ -131,7 +146,7 @@ static int ReadOTPData(XIsf *InstancePtr, u32 Address, u8 *ReadPtr,
|
|||
* 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 the case
|
||||
* 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.
|
||||
|
@ -143,7 +158,7 @@ static int ReadOTPData(XIsf *InstancePtr, u32 Address, u8 *ReadPtr,
|
|||
* 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 the data read
|
||||
* 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.
|
||||
|
@ -159,30 +174,32 @@ static int ReadOTPData(XIsf *InstancePtr, u32 Address, u8 *ReadPtr,
|
|||
* 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 the fifth location pointed to
|
||||
* - 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 XIsf_Read(XIsf *InstancePtr, XIsf_ReadOperation Operation,
|
||||
void *OpParamPtr)
|
||||
{
|
||||
int Status = XST_FAILURE;
|
||||
int Status = (int)(XST_FAILURE);
|
||||
u8 Mode;
|
||||
XIsf_ReadParam *ReadParamPtr;
|
||||
XIsf_FlashToBufTransferParam *FlashToBufTransferParamPtr;
|
||||
XIsf_BufferReadParam *BufferReadParamPtr;
|
||||
|
||||
if (InstancePtr == NULL) {
|
||||
return XST_FAILURE;
|
||||
return (int)(XST_FAILURE);
|
||||
}
|
||||
|
||||
if (InstancePtr->IsReady != TRUE) {
|
||||
return XST_FAILURE;
|
||||
return (int)(XST_FAILURE);
|
||||
}
|
||||
|
||||
if (NULL == OpParamPtr) {
|
||||
return XST_FAILURE;
|
||||
return (int)(XST_FAILURE);
|
||||
}
|
||||
|
||||
switch (Operation) {
|
||||
|
@ -195,25 +212,29 @@ int XIsf_Read(XIsf *InstancePtr, XIsf_ReadOperation Operation, void *OpParamPtr)
|
|||
break;
|
||||
|
||||
case XISF_FAST_READ:
|
||||
ReadParamPtr = (XIsf_ReadParam*) OpParamPtr;
|
||||
ReadParamPtr = (XIsf_ReadParam*)(void *) OpParamPtr;
|
||||
Xil_AssertNonvoid(ReadParamPtr != NULL);
|
||||
Status = FastReadData(InstancePtr,
|
||||
XISF_CMD_FAST_READ,
|
||||
ReadParamPtr->Address,
|
||||
ReadParamPtr->ReadPtr,
|
||||
ReadParamPtr->NumBytes,
|
||||
FAST_READ_NUM_DUMMY_BYTES);
|
||||
ReadParamPtr->NumDummyBytes);
|
||||
break;
|
||||
|
||||
case XISF_PAGE_TO_BUF_TRANS:
|
||||
FlashToBufTransferParamPtr =
|
||||
(XIsf_FlashToBufTransferParam*) OpParamPtr;
|
||||
(XIsf_FlashToBufTransferParam*)(void *) OpParamPtr;
|
||||
Xil_AssertNonvoid(FlashToBufTransferParamPtr != NULL);
|
||||
Status = FlashToBufTransfer(InstancePtr,
|
||||
FlashToBufTransferParamPtr->BufferNum,
|
||||
FlashToBufTransferParamPtr->Address);
|
||||
break;
|
||||
|
||||
case XISF_BUFFER_READ:
|
||||
BufferReadParamPtr = (XIsf_BufferReadParam*) OpParamPtr;
|
||||
BufferReadParamPtr =
|
||||
(XIsf_BufferReadParam*)(void *) OpParamPtr;
|
||||
Xil_AssertNonvoid(BufferReadParamPtr != NULL);
|
||||
Status = BufferRead(InstancePtr,
|
||||
BufferReadParamPtr->BufferNum,
|
||||
BufferReadParamPtr->ReadPtr,
|
||||
|
@ -222,7 +243,9 @@ int XIsf_Read(XIsf *InstancePtr, XIsf_ReadOperation Operation, void *OpParamPtr)
|
|||
break;
|
||||
|
||||
case XISF_FAST_BUFFER_READ:
|
||||
BufferReadParamPtr = (XIsf_BufferReadParam*) OpParamPtr;
|
||||
BufferReadParamPtr =
|
||||
(XIsf_BufferReadParam*)(void *) OpParamPtr;
|
||||
Xil_AssertNonvoid(BufferReadParamPtr != NULL);
|
||||
Status = FastBufferRead(InstancePtr,
|
||||
BufferReadParamPtr->BufferNum,
|
||||
BufferReadParamPtr->ReadPtr,
|
||||
|
@ -231,17 +254,19 @@ int XIsf_Read(XIsf *InstancePtr, XIsf_ReadOperation Operation, void *OpParamPtr)
|
|||
break;
|
||||
|
||||
case XISF_OTP_READ:
|
||||
ReadParamPtr = (XIsf_ReadParam*) OpParamPtr;
|
||||
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))
|
||||
#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*) OpParamPtr;
|
||||
ReadParamPtr = (XIsf_ReadParam*)(void *) OpParamPtr;
|
||||
Xil_AssertNonvoid(ReadParamPtr != NULL);
|
||||
Status = FastReadData(InstancePtr,
|
||||
XISF_CMD_DUAL_OP_FAST_READ,
|
||||
ReadParamPtr->Address,
|
||||
|
@ -251,7 +276,8 @@ int XIsf_Read(XIsf *InstancePtr, XIsf_ReadOperation Operation, void *OpParamPtr)
|
|||
break;
|
||||
|
||||
case XISF_DUAL_IO_FAST_READ:
|
||||
ReadParamPtr = (XIsf_ReadParam*) OpParamPtr;
|
||||
ReadParamPtr = (XIsf_ReadParam*)(void *) OpParamPtr;
|
||||
Xil_AssertNonvoid(ReadParamPtr != NULL);
|
||||
Status = FastReadData(InstancePtr,
|
||||
XISF_CMD_DUAL_IO_FAST_READ,
|
||||
ReadParamPtr->Address,
|
||||
|
@ -261,7 +287,8 @@ int XIsf_Read(XIsf *InstancePtr, XIsf_ReadOperation Operation, void *OpParamPtr)
|
|||
break;
|
||||
|
||||
case XISF_QUAD_OP_FAST_READ:
|
||||
ReadParamPtr = (XIsf_ReadParam*) OpParamPtr;
|
||||
ReadParamPtr = (XIsf_ReadParam*)(void *) OpParamPtr;
|
||||
Xil_AssertNonvoid(ReadParamPtr != NULL);
|
||||
Status = FastReadData(InstancePtr,
|
||||
XISF_CMD_QUAD_OP_FAST_READ,
|
||||
ReadParamPtr->Address,
|
||||
|
@ -271,7 +298,8 @@ int XIsf_Read(XIsf *InstancePtr, XIsf_ReadOperation Operation, void *OpParamPtr)
|
|||
break;
|
||||
|
||||
case XISF_QUAD_IO_FAST_READ:
|
||||
ReadParamPtr = (XIsf_ReadParam*) OpParamPtr;
|
||||
ReadParamPtr = (XIsf_ReadParam*)(void *) OpParamPtr;
|
||||
Xil_AssertNonvoid(ReadParamPtr != NULL);
|
||||
Status = FastReadData(InstancePtr,
|
||||
XISF_CMD_QUAD_IO_FAST_READ,
|
||||
ReadParamPtr->Address,
|
||||
|
@ -287,6 +315,16 @@ int XIsf_Read(XIsf *InstancePtr, XIsf_ReadOperation Operation, void *OpParamPtr)
|
|||
break;
|
||||
}
|
||||
|
||||
/*
|
||||
* Get the Transfer Mode
|
||||
*/
|
||||
Mode = XIsf_GetTransferMode(InstancePtr);
|
||||
|
||||
if(Mode == XISF_INTERRUPT_MODE){
|
||||
InstancePtr->StatusHandler(InstancePtr,
|
||||
XIsf_StatusEventInfo, XIsf_ByteCountInfo);
|
||||
}
|
||||
|
||||
return Status;
|
||||
}
|
||||
|
||||
|
@ -316,31 +354,110 @@ int XIsf_Read(XIsf *InstancePtr, XIsf_ReadOperation Operation, void *OpParamPtr)
|
|||
******************************************************************************/
|
||||
static int ReadData(XIsf *InstancePtr, u32 Address, u8 *ReadPtr, u32 ByteCount)
|
||||
{
|
||||
u8 Mode;
|
||||
u32 BankSel;
|
||||
u32 RealAddr;
|
||||
int Status;
|
||||
|
||||
if (ByteCount <= 0 ) {
|
||||
return XST_FAILURE;
|
||||
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 XST_FAILURE;
|
||||
return (int)XST_FAILURE;
|
||||
}
|
||||
|
||||
ReadPtr[BYTE1] = XISF_CMD_RANDOM_READ;
|
||||
ReadPtr[BYTE2] = (u8) (Address >> XISF_ADDR_SHIFT16);
|
||||
ReadPtr[BYTE3] = (u8) (Address >> XISF_ADDR_SHIFT8);
|
||||
ReadPtr[BYTE4] = (u8) Address;
|
||||
while(((s32)(LocalByteCnt)) > 0) {
|
||||
|
||||
/*
|
||||
* Initiate the Transfer.
|
||||
* Translate address based on type of connection
|
||||
* If stacked assert the slave select based on address
|
||||
*/
|
||||
Status = XIsf_Transfer(InstancePtr, ReadPtr, ReadPtr,
|
||||
ByteCount + XISF_CMD_SEND_EXTRA_BYTES);
|
||||
if (Status != XST_SUCCESS) {
|
||||
return XST_FAILURE;
|
||||
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);
|
||||
}
|
||||
|
||||
return XST_SUCCESS;
|
||||
/*
|
||||
* 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;
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
|
@ -376,44 +493,126 @@ static int ReadData(XIsf *InstancePtr, u32 Address, u8 *ReadPtr, u32 ByteCount)
|
|||
* location pointed to by the ReadPtr.
|
||||
*
|
||||
******************************************************************************/
|
||||
static int FastReadData(XIsf *InstancePtr, u8 Command, u32 Address, u8 *ReadPtr,
|
||||
u32 ByteCount, int NumDummyBytes)
|
||||
static int FastReadData(XIsf *InstancePtr, u8 Command, u32 Address,
|
||||
u8 *ReadPtr, u32 ByteCount, int NumDummyBytes)
|
||||
{
|
||||
int Status;
|
||||
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 (ByteCount <= 0 ) {
|
||||
return XST_FAILURE;
|
||||
if (LocalByteCnt <= 0 ) {
|
||||
return (int)XST_FAILURE;
|
||||
}
|
||||
|
||||
if (ReadPtr == NULL) {
|
||||
return XST_FAILURE;
|
||||
return (int)(XST_FAILURE);
|
||||
}
|
||||
|
||||
if (NumDummyBytes <= 0) {
|
||||
return XST_FAILURE;
|
||||
return (int)(XST_FAILURE);
|
||||
}
|
||||
|
||||
ReadPtr[BYTE1] = Command;
|
||||
ReadPtr[BYTE2] = (u8) (Address >> XISF_ADDR_SHIFT16);
|
||||
ReadPtr[BYTE3] = (u8) (Address >> XISF_ADDR_SHIFT8);
|
||||
ReadPtr[BYTE4] = (u8) Address;
|
||||
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++) {
|
||||
ReadPtr[Index + BYTE5] = (u8) (XISF_DUMMYBYTE);
|
||||
WriteBuffer[Index + BYTE5] = (u8) (XISF_DUMMYBYTE);
|
||||
}
|
||||
|
||||
RealByteCnt += NumDummyBytes;
|
||||
|
||||
/*
|
||||
* Initiate the Transfer.
|
||||
*/
|
||||
Status = XIsf_Transfer(InstancePtr, ReadPtr, ReadPtr,
|
||||
ByteCount + NumDummyBytes +
|
||||
XISF_CMD_SEND_EXTRA_BYTES);
|
||||
if (Status != XST_SUCCESS) {
|
||||
return XST_FAILURE;
|
||||
Status = (int)XIsf_Transfer(InstancePtr, WriteBuffer,
|
||||
&(ReadPtr[TotalByteCnt - LocalByteCnt]),
|
||||
RealByteCnt + XISF_CMD_SEND_EXTRA_BYTES);
|
||||
if (Status != (int)(XST_SUCCESS)) {
|
||||
return (int)(XST_FAILURE);
|
||||
}
|
||||
|
||||
return XST_SUCCESS;
|
||||
#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;
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
|
@ -424,10 +623,10 @@ static int FastReadData(XIsf *InstancePtr, u8 Command, u32 Address, u8 *ReadPtr,
|
|||
*
|
||||
* @param InstancePtr is a pointer to the XIsf instance.
|
||||
* @param BufferNum specifies the internal SRAM Buffer to which the data
|
||||
* from the 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.
|
||||
* 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
|
||||
|
@ -444,7 +643,11 @@ static int FastReadData(XIsf *InstancePtr, u8 Command, u32 Address, u8 *ReadPtr,
|
|||
******************************************************************************/
|
||||
static int FlashToBufTransfer(XIsf *InstancePtr, u8 BufferNum, u32 Address)
|
||||
{
|
||||
int Status = XST_FAILURE;
|
||||
int Status = (int)(XST_FAILURE);
|
||||
|
||||
Xil_AssertNonvoid(InstancePtr != NULL);
|
||||
Xil_AssertNonvoid(Address != 0);
|
||||
Xil_AssertNonvoid(BufferNum != 0);
|
||||
|
||||
#if (XPAR_XISF_FLASH_FAMILY == ATMEL)
|
||||
/*
|
||||
|
@ -454,10 +657,10 @@ static int FlashToBufTransfer(XIsf *InstancePtr, u8 BufferNum, u32 Address)
|
|||
(BufferNum == XISF_PAGE_BUFFER2)) {
|
||||
if ((InstancePtr->DeviceCode == XISF_ATMEL_DEV_AT45DB011D) &&
|
||||
(BufferNum != XISF_PAGE_BUFFER1)) {
|
||||
return XST_FAILURE;
|
||||
return (int)(XST_FAILURE);
|
||||
}
|
||||
} else {
|
||||
return XST_FAILURE;
|
||||
return (int)(XST_FAILURE);
|
||||
}
|
||||
|
||||
if (BufferNum == XISF_PAGE_BUFFER1) {
|
||||
|
@ -483,8 +686,8 @@ static int FlashToBufTransfer(XIsf *InstancePtr, u8 BufferNum, u32 Address)
|
|||
*/
|
||||
Status = XIsf_Transfer(InstancePtr, InstancePtr->WriteBufPtr, NULL,
|
||||
XISF_CMD_SEND_EXTRA_BYTES);
|
||||
if (Status != XST_SUCCESS) {
|
||||
return XST_FAILURE;
|
||||
if (Status != (int)(XST_SUCCESS)) {
|
||||
return (int)(XST_FAILURE);
|
||||
}
|
||||
#endif /* (XPAR_XISF_FLASH_FAMILY == ATMEL) */
|
||||
|
||||
|
@ -495,12 +698,12 @@ static int FlashToBufTransfer(XIsf *InstancePtr, u8 BufferNum, u32 Address)
|
|||
/*****************************************************************************/
|
||||
/**
|
||||
*
|
||||
* This function reads the data available in the SRAM buffer of the Serial Flash.
|
||||
* 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 the data
|
||||
* @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 the case of
|
||||
* 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.
|
||||
|
@ -523,7 +726,13 @@ static int FlashToBufTransfer(XIsf *InstancePtr, u8 BufferNum, u32 Address)
|
|||
static int BufferRead(XIsf *InstancePtr, u8 BufferNum, u8 *ReadPtr,
|
||||
u32 ByteOffset, u32 NumBytes)
|
||||
{
|
||||
int Status = XST_FAILURE;
|
||||
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)
|
||||
|
||||
|
@ -534,22 +743,22 @@ static int BufferRead(XIsf *InstancePtr, u8 BufferNum, u8 *ReadPtr,
|
|||
(BufferNum == XISF_PAGE_BUFFER2)) {
|
||||
if ((InstancePtr->DeviceCode == XISF_ATMEL_DEV_AT45DB011D) &&
|
||||
(BufferNum != XISF_PAGE_BUFFER1)) {
|
||||
return XST_FAILURE;
|
||||
return (int)(XST_FAILURE);
|
||||
}
|
||||
} else {
|
||||
return XST_FAILURE;
|
||||
return (int)(XST_FAILURE);
|
||||
}
|
||||
|
||||
if (ReadPtr == NULL) {
|
||||
return XST_FAILURE;
|
||||
return (int)(XST_FAILURE);
|
||||
}
|
||||
|
||||
if (ByteOffset > InstancePtr->BytesPerPage){
|
||||
return XST_FAILURE;
|
||||
return (int)(XST_FAILURE);
|
||||
}
|
||||
|
||||
if ((NumBytes <= 0) || (NumBytes > InstancePtr->BytesPerPage)) {
|
||||
return XST_FAILURE;
|
||||
return (int)(XST_FAILURE);
|
||||
}
|
||||
|
||||
if (BufferNum == XISF_PAGE_BUFFER1) {
|
||||
|
@ -566,8 +775,8 @@ static int BufferRead(XIsf *InstancePtr, u8 BufferNum, u8 *ReadPtr,
|
|||
*/
|
||||
Status = XIsf_Transfer(InstancePtr, ReadPtr, ReadPtr,
|
||||
NumBytes + XISF_CMD_SEND_EXTRA_BYTES);
|
||||
if (Status != XST_SUCCESS) {
|
||||
return XST_FAILURE;
|
||||
if (Status != (int)(XST_SUCCESS)) {
|
||||
return (int)(XST_FAILURE);
|
||||
}
|
||||
#endif /* (XPAR_XISF_FLASH_FAMILY == ATMEL) */
|
||||
|
||||
|
@ -581,9 +790,9 @@ static int BufferRead(XIsf *InstancePtr, u8 BufferNum, u8 *ReadPtr,
|
|||
* 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 the data
|
||||
* @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 the case of
|
||||
* 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.
|
||||
|
@ -606,7 +815,13 @@ static int BufferRead(XIsf *InstancePtr, u8 BufferNum, u8 *ReadPtr,
|
|||
static int FastBufferRead(XIsf *InstancePtr, u8 BufferNum, u8 *ReadPtr,
|
||||
u32 ByteOffset, u32 NumBytes)
|
||||
{
|
||||
int Status = XST_FAILURE;
|
||||
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)
|
||||
/*
|
||||
|
@ -616,22 +831,22 @@ static int FastBufferRead(XIsf *InstancePtr, u8 BufferNum, u8 *ReadPtr,
|
|||
(BufferNum == XISF_PAGE_BUFFER2)) {
|
||||
if ((InstancePtr->DeviceCode == XISF_ATMEL_DEV_AT45DB011D) &&
|
||||
(BufferNum != XISF_PAGE_BUFFER1)) {
|
||||
return XST_FAILURE;
|
||||
return (int)(XST_FAILURE);
|
||||
}
|
||||
} else {
|
||||
return XST_FAILURE;
|
||||
return (int)(XST_FAILURE);
|
||||
}
|
||||
|
||||
if (ReadPtr == NULL) {
|
||||
return XST_FAILURE;
|
||||
return (int)(XST_FAILURE);
|
||||
}
|
||||
|
||||
if (ByteOffset > InstancePtr->BytesPerPage){
|
||||
return XST_FAILURE;
|
||||
return (int)(XST_FAILURE);
|
||||
}
|
||||
|
||||
if ((NumBytes <= 0) || (NumBytes > InstancePtr->BytesPerPage)) {
|
||||
return XST_FAILURE;
|
||||
return (int)(XST_FAILURE);
|
||||
}
|
||||
|
||||
if (BufferNum == XISF_PAGE_BUFFER1) {
|
||||
|
@ -656,8 +871,8 @@ static int FastBufferRead(XIsf *InstancePtr, u8 BufferNum, u8 *ReadPtr,
|
|||
*/
|
||||
Status = XIsf_Transfer(InstancePtr, ReadPtr, ReadPtr,
|
||||
NumBytes + XISF_CMD_FAST_READ_EXTRA_BYTES);
|
||||
if (Status != XST_SUCCESS) {
|
||||
return XST_FAILURE;
|
||||
if (Status != (int)(XST_SUCCESS)) {
|
||||
return (int)(XST_FAILURE);
|
||||
}
|
||||
#endif /* (XPAR_XISF_FLASH_FAMILY == ATMEL) */
|
||||
|
||||
|
@ -687,15 +902,20 @@ static int FastBufferRead(XIsf *InstancePtr, u8 BufferNum, u8 *ReadPtr,
|
|||
static int ReadOTPData(XIsf *InstancePtr, u32 Address, u8 *ReadPtr,
|
||||
u32 ByteCount)
|
||||
{
|
||||
int Status = XST_FAILURE;
|
||||
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 XST_FAILURE;
|
||||
return (int)(XST_FAILURE);
|
||||
}
|
||||
|
||||
if (ReadPtr == NULL) {
|
||||
return XST_FAILURE;
|
||||
return (int)(XST_FAILURE);
|
||||
}
|
||||
|
||||
ReadPtr[BYTE1] = XISF_CMD_OTP_READ;
|
||||
|
@ -710,8 +930,8 @@ static int ReadOTPData(XIsf *InstancePtr, u32 Address, u8 *ReadPtr,
|
|||
*/
|
||||
Status = XIsf_Transfer(InstancePtr, ReadPtr, ReadPtr,
|
||||
ByteCount + XISF_OTP_RDWR_EXTRA_BYTES);
|
||||
if (Status != XST_SUCCESS) {
|
||||
return XST_FAILURE;
|
||||
if (Status != (int)(XST_SUCCESS)) {
|
||||
return (int)(XST_FAILURE);
|
||||
}
|
||||
#endif /* (XPAR_XISF_FLASH_FAMILY == INTEL) */
|
||||
|
||||
|
|
|
@ -47,6 +47,10 @@
|
|||
* 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 Added Call back to lib interrupt handler
|
||||
* after XIsf_Transfer Calls.
|
||||
* Changed API:
|
||||
* - XIsf_SectorProtect()
|
||||
*
|
||||
* </pre>
|
||||
*
|
||||
|
@ -75,7 +79,8 @@ static int SpEnable(XIsf *InstancePtr);
|
|||
static int SpDisable(XIsf *InstancePtr);
|
||||
|
||||
/************************** Variable Definitions *****************************/
|
||||
|
||||
extern u32 XIsf_StatusEventInfo;
|
||||
extern unsigned int XIsf_ByteCountInfo;
|
||||
/************************** Function Definitions ******************************/
|
||||
|
||||
|
||||
|
@ -115,7 +120,8 @@ static int SpDisable(XIsf *InstancePtr);
|
|||
int XIsf_SectorProtect(XIsf *InstancePtr, XIsf_SpOperation Operation,
|
||||
u8 *BufferPtr)
|
||||
{
|
||||
int Status = XST_FAILURE;
|
||||
int Status = (int)(XST_FAILURE);
|
||||
u8 Mode;
|
||||
|
||||
switch (Operation) {
|
||||
case XISF_SPR_READ:
|
||||
|
@ -139,9 +145,20 @@ int XIsf_SectorProtect(XIsf *InstancePtr, XIsf_SpOperation Operation,
|
|||
break;
|
||||
|
||||
default:
|
||||
/* Added Comment for MISRA C */
|
||||
break;
|
||||
}
|
||||
|
||||
/*
|
||||
* Get the Transfer Mode
|
||||
*/
|
||||
Mode = XIsf_GetTransferMode(InstancePtr);
|
||||
|
||||
if(Mode == XISF_INTERRUPT_MODE){
|
||||
InstancePtr->StatusHandler(InstancePtr,
|
||||
XIsf_StatusEventInfo, XIsf_ByteCountInfo);
|
||||
}
|
||||
|
||||
return Status;
|
||||
}
|
||||
|
||||
|
@ -160,7 +177,7 @@ int XIsf_SectorProtect(XIsf *InstancePtr, XIsf_SpOperation Operation,
|
|||
* - This operation is supported for Atmel, Intel, STM, Winbond
|
||||
* and Spansion Serial Flash.
|
||||
* - The SPR content is stored at the fourth location pointed
|
||||
* by the ReadPtr for Atmel Serial Flash and at the second location
|
||||
* by the ReadPtr for Atmel Serial Flash and at second location
|
||||
* for STM/Intel/Winbond/Spansion Serial Flash.
|
||||
*
|
||||
******************************************************************************/
|
||||
|
@ -168,8 +185,11 @@ static int SprRead(XIsf *InstancePtr, u8 *ReadPtr)
|
|||
{
|
||||
int Status;
|
||||
|
||||
Xil_AssertNonvoid(InstancePtr != NULL);
|
||||
|
||||
|
||||
if (ReadPtr == NULL) {
|
||||
return XST_FAILURE;
|
||||
return (int)(XST_FAILURE);
|
||||
}
|
||||
|
||||
#if (XPAR_XISF_FLASH_FAMILY == ATMEL)
|
||||
|
@ -198,11 +218,11 @@ static int SprRead(XIsf *InstancePtr, u8 *ReadPtr)
|
|||
|
||||
#endif /* (XPAR_XISF_FLASH_FAMILY == ATMEL) */
|
||||
|
||||
if (Status != XST_SUCCESS) {
|
||||
return XST_FAILURE;
|
||||
if (Status != (int)(XST_SUCCESS)) {
|
||||
return (int)(XST_FAILURE);
|
||||
}
|
||||
|
||||
return XST_SUCCESS;
|
||||
return (int)(XST_SUCCESS);
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
|
@ -223,8 +243,10 @@ static int SprProgram(XIsf *InstancePtr, u8 *BufferPtr)
|
|||
{
|
||||
int Status;
|
||||
|
||||
Xil_AssertNonvoid(InstancePtr != NULL);
|
||||
|
||||
if (BufferPtr == NULL) {
|
||||
return XST_FAILURE;
|
||||
return (int)(XST_FAILURE);
|
||||
}
|
||||
|
||||
#if (XPAR_XISF_FLASH_FAMILY == ATMEL)
|
||||
|
@ -256,11 +278,11 @@ static int SprProgram(XIsf *InstancePtr, u8 *BufferPtr)
|
|||
|
||||
#endif /* (XPAR_XISF_FLASH_FAMILY == ATMEL) */
|
||||
|
||||
if (Status != XST_SUCCESS) {
|
||||
return XST_FAILURE;
|
||||
if (Status != (int)(XST_SUCCESS)) {
|
||||
return (int)(XST_FAILURE);
|
||||
}
|
||||
|
||||
return XST_SUCCESS;
|
||||
return (int)(XST_SUCCESS);
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
|
@ -277,7 +299,9 @@ static int SprProgram(XIsf *InstancePtr, u8 *BufferPtr)
|
|||
******************************************************************************/
|
||||
static int SprErase(XIsf *InstancePtr)
|
||||
{
|
||||
int Status = XST_FAILURE;
|
||||
int Status = (int)(XST_FAILURE);
|
||||
|
||||
Xil_AssertNonvoid(InstancePtr != NULL);
|
||||
|
||||
#if (XPAR_XISF_FLASH_FAMILY == ATMEL)
|
||||
/*
|
||||
|
@ -293,8 +317,9 @@ static int SprErase(XIsf *InstancePtr)
|
|||
*/
|
||||
Status = XIsf_Transfer(InstancePtr, InstancePtr->WriteBufPtr, NULL,
|
||||
XISF_CMD_SEND_EXTRA_BYTES);
|
||||
if (Status != XST_SUCCESS) {
|
||||
return XST_FAILURE;
|
||||
|
||||
if (Status != (int)(XST_SUCCESS)) {
|
||||
return (int)(XST_FAILURE);
|
||||
}
|
||||
#endif /* (XPAR_XISF_FLASH_FAMILY == ATMEL) */
|
||||
|
||||
|
@ -316,7 +341,10 @@ static int SprErase(XIsf *InstancePtr)
|
|||
******************************************************************************/
|
||||
static int SpEnable(XIsf *InstancePtr)
|
||||
{
|
||||
int Status = XST_FAILURE;
|
||||
int Status = (int)(XST_FAILURE);
|
||||
|
||||
Xil_AssertNonvoid(InstancePtr != NULL);
|
||||
|
||||
|
||||
#if (XPAR_XISF_FLASH_FAMILY == ATMEL)
|
||||
/*
|
||||
|
@ -332,8 +360,9 @@ static int SpEnable(XIsf *InstancePtr)
|
|||
*/
|
||||
Status = XIsf_Transfer(InstancePtr, InstancePtr->WriteBufPtr, NULL,
|
||||
XISF_CMD_SEND_EXTRA_BYTES);
|
||||
if (Status != XST_SUCCESS) {
|
||||
return XST_FAILURE;
|
||||
|
||||
if (Status != (int)(XST_SUCCESS)) {
|
||||
return (int)(XST_FAILURE);
|
||||
}
|
||||
#endif /* (XPAR_XISF_FLASH_FAMILY == ATMEL) */
|
||||
|
||||
|
@ -354,7 +383,9 @@ static int SpEnable(XIsf *InstancePtr)
|
|||
******************************************************************************/
|
||||
static int SpDisable(XIsf *InstancePtr)
|
||||
{
|
||||
int Status = XST_FAILURE;
|
||||
int Status = (int)(XST_FAILURE);
|
||||
|
||||
Xil_AssertNonvoid(InstancePtr != NULL);
|
||||
|
||||
#if (XPAR_XISF_FLASH_FAMILY == ATMEL)
|
||||
/*
|
||||
|
@ -370,8 +401,9 @@ static int SpDisable(XIsf *InstancePtr)
|
|||
*/
|
||||
Status = XIsf_Transfer(InstancePtr, InstancePtr->WriteBufPtr, NULL,
|
||||
XISF_CMD_SEND_EXTRA_BYTES);
|
||||
if (Status != XST_SUCCESS) {
|
||||
return XST_FAILURE;
|
||||
|
||||
if (Status != (int)(XST_SUCCESS)) {
|
||||
return (int)(XST_FAILURE);
|
||||
}
|
||||
#endif /* (XPAR_XISF_FLASH_FAMILY == ATMEL) */
|
||||
|
||||
|
|
|
@ -49,7 +49,11 @@
|
|||
* flash memories
|
||||
* 3.00a srt 06/20/12 Updated to support interfaces SPI PS and QSPI PS.
|
||||
* Added support to SST flash on SPI PS interface.
|
||||
*
|
||||
* 5.0 sb 08/05/14 Updated support for > 128 MB flash for PSQSPI
|
||||
* interface.
|
||||
* Changed API:
|
||||
* WriteData()
|
||||
* XIsf_Write()
|
||||
* </pre>
|
||||
*
|
||||
******************************************************************************/
|
||||
|
@ -59,6 +63,7 @@
|
|||
#include "include/xilisf.h"
|
||||
|
||||
/************************** Constant Definitions *****************************/
|
||||
#define SIXTEENMB 0x1000000 /**< Sixteen MB */
|
||||
|
||||
/**************************** Type Definitions *******************************/
|
||||
|
||||
|
@ -68,6 +73,11 @@
|
|||
|
||||
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 WriteData(XIsf *InstancePtr, u8 Command, u32 Address,
|
||||
const u8 *BufferPtr, u32 ByteCount);
|
||||
static int AutoPageWrite(XIsf *InstancePtr, u32 Address);
|
||||
|
@ -82,7 +92,8 @@ static int WriteSR2(XIsf *InstancePtr, u8 *SRData);
|
|||
static int WriteOTPData(XIsf *InstancePtr, u32 Address, const u8 *BufferPtr);
|
||||
|
||||
/************************** Variable Definitions *****************************/
|
||||
|
||||
extern u32 XIsf_StatusEventInfo;
|
||||
extern unsigned int XIsf_ByteCountInfo;
|
||||
/************************** Function Definitions ******************************/
|
||||
|
||||
|
||||
|
@ -110,7 +121,7 @@ static int WriteOTPData(XIsf *InstancePtr, u32 Address, const u8 *BufferPtr);
|
|||
* - XISF_WRITE_STATUS_REG2: 2 byte Status Register Write
|
||||
* - XISF_OTP_WRITE: OTP Write.
|
||||
*
|
||||
* @param OpParamPtr is the pointer to a structure variable which contains
|
||||
* @param OpParamPtr is pointer to a structure variable which contains
|
||||
* operational parameters of the specified operation.
|
||||
* This parameter type is dependant on value of first argument
|
||||
* (Operation).
|
||||
|
@ -124,15 +135,15 @@ static int WriteOTPData(XIsf *InstancePtr, u32 Address, const u8 *BufferPtr);
|
|||
* OpParamPtr->Address is the start address in the Serial Flash.
|
||||
* OpParamPtr->WritePtr is a pointer to the data to be written to
|
||||
* the Serial Flash.
|
||||
* OpParamPtr->NumBytes is the number of bytes to be written to the
|
||||
* OpParamPtr->NumBytes is the number of bytes to be written to
|
||||
* Serial Flash.
|
||||
* This operation is supported for Atmel, Intel, STM, Winbond and
|
||||
* Spansion Serial Flash.
|
||||
*
|
||||
* - Auto Page Write (XISF_AUTO_PAGE_WRITE):
|
||||
* The OpParamPtr must be of 32 bit unsigned integer variable. This
|
||||
* is the address of page number in the Serial Flash which is to be
|
||||
* refreshed.
|
||||
* The OpParamPtr must be of 32 bit unsigned integer variable.
|
||||
* This is the address of page number in the Serial Flash which is
|
||||
* to be refreshed.
|
||||
* This operation is only supported for Atmel Serial Flash.
|
||||
*
|
||||
* - Buffer Write (XISF_BUFFER_WRITE):
|
||||
|
@ -140,13 +151,13 @@ static int WriteOTPData(XIsf *InstancePtr, u32 Address, const u8 *BufferPtr);
|
|||
* XIsf_BufferToFlashWriteParam.
|
||||
* 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 the case of
|
||||
* XISF_PAGE_BUFFER2. XISF_PAGE_BUFFER2 is not valid in case of
|
||||
* AT45DB011D Flash as it contains a single buffer.
|
||||
* OpParamPtr->WritePtr is a pointer to the data to be written to
|
||||
* the Serial Flash SRAM Buffer.
|
||||
* OpParamPtr->ByteOffset is byte offset in the buffer from where
|
||||
* the data is to be written.
|
||||
* OpParamPtr->NumBytes is the number of bytes to be written to the
|
||||
* OpParamPtr->NumBytes is number of bytes to be written to the
|
||||
* Buffer.
|
||||
* This operation is supported only for Atmel Serial Flash.
|
||||
*
|
||||
|
@ -158,7 +169,7 @@ static int WriteOTPData(XIsf *InstancePtr, u32 Address, const u8 *BufferPtr);
|
|||
* XIsf_BufferToFlashWriteParam.
|
||||
* 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 the case of
|
||||
* XISF_PAGE_BUFFER2. XISF_PAGE_BUFFER2 is not valid in case of
|
||||
* AT45DB011D Flash as it contains a single buffer.
|
||||
* OpParamPtr->Address is starting address in the Serial Flash
|
||||
* memory from where the data is to be written.
|
||||
|
@ -183,8 +194,8 @@ static int WriteOTPData(XIsf *InstancePtr, u32 Address, const u8 *BufferPtr);
|
|||
* Serial Flash to which the data is to be written.
|
||||
* OpParamPtr->WritePtr is a pointer to the data to be written to
|
||||
* the Serial Flash.
|
||||
* OpParamPtr->NumBytes should be set to 1 when performing OTPWrite
|
||||
* operation.
|
||||
* OpParamPtr->NumBytes should be set to 1 when performing
|
||||
* OTPWrite operation.
|
||||
* This operation is only supported for Intel Serial Flash.
|
||||
*
|
||||
* @return XST_SUCCESS if successful else XST_FAILURE.
|
||||
|
@ -202,26 +213,28 @@ static int WriteOTPData(XIsf *InstancePtr, u32 Address, const u8 *BufferPtr);
|
|||
int XIsf_Write(XIsf *InstancePtr, XIsf_WriteOperation Operation,
|
||||
void *OpParamPtr)
|
||||
{
|
||||
int Status = XST_FAILURE;
|
||||
int Status = (int)XST_FAILURE;
|
||||
u8 Mode;
|
||||
XIsf_WriteParam *WriteParamPtr;
|
||||
XIsf_BufferWriteParam *BufferWriteParamPtr;
|
||||
XIsf_BufferToFlashWriteParam *BufferToFlashWriteParamPtr;
|
||||
|
||||
if (InstancePtr == NULL) {
|
||||
return XST_FAILURE;
|
||||
return (int)XST_FAILURE;
|
||||
}
|
||||
|
||||
if (InstancePtr->IsReady != TRUE) {
|
||||
return XST_FAILURE;
|
||||
return (int)XST_FAILURE;
|
||||
}
|
||||
|
||||
if (NULL == OpParamPtr) {
|
||||
return XST_FAILURE;
|
||||
return (int)XST_FAILURE;
|
||||
}
|
||||
|
||||
switch (Operation) {
|
||||
case XISF_WRITE:
|
||||
WriteParamPtr = (XIsf_WriteParam*) OpParamPtr;
|
||||
WriteParamPtr = (XIsf_WriteParam*)(void *) OpParamPtr;
|
||||
Xil_AssertNonvoid(WriteParamPtr != NULL);
|
||||
Status = WriteData(InstancePtr,
|
||||
XISF_CMD_PAGEPROG_WRITE,
|
||||
WriteParamPtr->Address,
|
||||
|
@ -231,12 +244,13 @@ int XIsf_Write(XIsf *InstancePtr, XIsf_WriteOperation Operation,
|
|||
|
||||
case XISF_AUTO_PAGE_WRITE:
|
||||
Status = AutoPageWrite(InstancePtr,
|
||||
*((u32*)OpParamPtr));
|
||||
*((u32*)(void *) OpParamPtr));
|
||||
break;
|
||||
|
||||
case XISF_BUFFER_WRITE:
|
||||
BufferWriteParamPtr = (XIsf_BufferWriteParam*)
|
||||
OpParamPtr;
|
||||
(void *) OpParamPtr;
|
||||
Xil_AssertNonvoid(BufferWriteParamPtr != NULL);
|
||||
Status = BufferWrite(InstancePtr,
|
||||
BufferWriteParamPtr->BufferNum,
|
||||
BufferWriteParamPtr->WritePtr,
|
||||
|
@ -246,7 +260,8 @@ int XIsf_Write(XIsf *InstancePtr, XIsf_WriteOperation Operation,
|
|||
|
||||
case XISF_BUF_TO_PAGE_WRITE_WITH_ERASE:
|
||||
BufferToFlashWriteParamPtr =
|
||||
(XIsf_BufferToFlashWriteParam*) OpParamPtr;
|
||||
(XIsf_BufferToFlashWriteParam*)(void *) OpParamPtr;
|
||||
Xil_AssertNonvoid(BufferToFlashWriteParamPtr != NULL);
|
||||
Status = BufferToFlashWriteWithErase(InstancePtr,
|
||||
BufferToFlashWriteParamPtr->BufferNum,
|
||||
BufferToFlashWriteParamPtr->Address);
|
||||
|
@ -254,18 +269,21 @@ int XIsf_Write(XIsf *InstancePtr, XIsf_WriteOperation Operation,
|
|||
|
||||
case XISF_BUF_TO_PAGE_WRITE_WITHOUT_ERASE:
|
||||
BufferToFlashWriteParamPtr =
|
||||
(XIsf_BufferToFlashWriteParam*) OpParamPtr;
|
||||
(XIsf_BufferToFlashWriteParam*)(void *) OpParamPtr;
|
||||
Xil_AssertNonvoid(BufferToFlashWriteParamPtr != NULL);
|
||||
Status = BufferToFlashWriteWithoutErase(InstancePtr,
|
||||
BufferToFlashWriteParamPtr->BufferNum,
|
||||
BufferToFlashWriteParamPtr->Address);
|
||||
break;
|
||||
|
||||
case XISF_WRITE_STATUS_REG:
|
||||
Status = WriteSR(InstancePtr, *((u8*)OpParamPtr));
|
||||
Status = WriteSR(InstancePtr,
|
||||
*((u8*)(void *) OpParamPtr));
|
||||
break;
|
||||
|
||||
case XISF_OTP_WRITE:
|
||||
WriteParamPtr = (XIsf_WriteParam*) OpParamPtr;
|
||||
WriteParamPtr = (XIsf_WriteParam*)(void *) OpParamPtr;
|
||||
Xil_AssertNonvoid(WriteParamPtr != NULL);
|
||||
if (1 == WriteParamPtr->NumBytes) {
|
||||
Status = WriteOTPData(InstancePtr,
|
||||
WriteParamPtr->Address,
|
||||
|
@ -274,13 +292,15 @@ int XIsf_Write(XIsf *InstancePtr, XIsf_WriteOperation Operation,
|
|||
break;
|
||||
|
||||
case XISF_WRITE_STATUS_REG2:
|
||||
Status = WriteSR2(InstancePtr, (u8*)OpParamPtr);
|
||||
Status = WriteSR2(InstancePtr,
|
||||
(u8*)(void *) OpParamPtr);
|
||||
break;
|
||||
|
||||
#if ((XPAR_XISF_FLASH_FAMILY == WINBOND) || (XPAR_XISF_FLASH_FAMILY == STM) || \
|
||||
(XPAR_XISF_FLASH_FAMILY == SPANSION))
|
||||
#if ((XPAR_XISF_FLASH_FAMILY == WINBOND) || (XPAR_XISF_FLASH_FAMILY == STM) \
|
||||
|| (XPAR_XISF_FLASH_FAMILY == SPANSION))
|
||||
case XISF_QUAD_IP_PAGE_WRITE:
|
||||
WriteParamPtr = (XIsf_WriteParam*) OpParamPtr;
|
||||
WriteParamPtr = (XIsf_WriteParam*)(void *) OpParamPtr;
|
||||
Xil_AssertNonvoid(WriteParamPtr != NULL);
|
||||
Status = WriteData(InstancePtr,
|
||||
XISF_CMD_QUAD_IP_PAGE_WRITE,
|
||||
WriteParamPtr->Address,
|
||||
|
@ -294,7 +314,8 @@ int XIsf_Write(XIsf *InstancePtr, XIsf_WriteOperation Operation,
|
|||
|
||||
#if (XPAR_XISF_FLASH_FAMILY == STM)
|
||||
case XISF_DUAL_IP_PAGE_WRITE:
|
||||
WriteParamPtr = (XIsf_WriteParam*) OpParamPtr;
|
||||
WriteParamPtr = (XIsf_WriteParam*)(void *) OpParamPtr;
|
||||
Xil_AssertNonvoid(WriteParamPtr != NULL);
|
||||
Status = WriteData(InstancePtr,
|
||||
XISF_CMD_DUAL_IP_PAGE_WRITE,
|
||||
WriteParamPtr->Address,
|
||||
|
@ -303,7 +324,8 @@ int XIsf_Write(XIsf *InstancePtr, XIsf_WriteOperation Operation,
|
|||
break;
|
||||
|
||||
case XISF_DUAL_IP_EXT_PAGE_WRITE:
|
||||
WriteParamPtr = (XIsf_WriteParam*) OpParamPtr;
|
||||
WriteParamPtr = (XIsf_WriteParam*)(void *) OpParamPtr;
|
||||
Xil_AssertNonvoid(WriteParamPtr != NULL);
|
||||
Status = WriteData(InstancePtr,
|
||||
XISF_CMD_DUAL_IP_EXT_PAGE_WRITE,
|
||||
WriteParamPtr->Address,
|
||||
|
@ -312,7 +334,8 @@ int XIsf_Write(XIsf *InstancePtr, XIsf_WriteOperation Operation,
|
|||
break;
|
||||
|
||||
case XISF_QUAD_IP_EXT_PAGE_WRITE:
|
||||
WriteParamPtr = (XIsf_WriteParam*) OpParamPtr;
|
||||
WriteParamPtr = (XIsf_WriteParam*)(void *) OpParamPtr;
|
||||
Xil_AssertNonvoid(WriteParamPtr != NULL);
|
||||
Status = WriteData(InstancePtr,
|
||||
XISF_CMD_QUAD_IP_EXT_PAGE_WRITE,
|
||||
WriteParamPtr->Address,
|
||||
|
@ -325,13 +348,23 @@ int XIsf_Write(XIsf *InstancePtr, XIsf_WriteOperation Operation,
|
|||
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 writes the data to the specified address locations in the Serial
|
||||
* This function writes the data to the specified address locations in Serial
|
||||
* Flash.
|
||||
*
|
||||
* @param InstancePtr is a pointer to the XIsf instance.
|
||||
|
@ -353,37 +386,144 @@ int XIsf_Write(XIsf *InstancePtr, XIsf_WriteOperation Operation,
|
|||
static int WriteData(XIsf *InstancePtr, u8 Command, u32 Address,
|
||||
const u8 *BufferPtr, u32 ByteCount)
|
||||
{
|
||||
u8 Mode;
|
||||
u32 Index;
|
||||
u32 BankSel;
|
||||
u32 RealAddr;
|
||||
int Status;
|
||||
u8 FlagStatus[2] = {0};
|
||||
u8 FlashStatus[2] = {0};
|
||||
u8 * NULLPtr = NULL;
|
||||
const u8 * LocalBufPtr = BufferPtr;
|
||||
#ifdef XPAR_XISF_INTERFACE_PSQSPI
|
||||
u32 FlashMake = InstancePtr->ManufacturerID;
|
||||
#endif
|
||||
u8 ReadStatusCmdBuf[] = { READ_STATUS_CMD, 0 };
|
||||
u8 ReadFlagSRCmd[] = {READ_FLAG_STATUS_CMD, 0};
|
||||
|
||||
if ((ByteCount <= 0) || (ByteCount > InstancePtr->BytesPerPage)) {
|
||||
return XST_FAILURE;
|
||||
return (int)XST_FAILURE;
|
||||
}
|
||||
|
||||
if (BufferPtr == NULL) {
|
||||
return XST_FAILURE;
|
||||
}
|
||||
|
||||
InstancePtr->WriteBufPtr[BYTE1] = Command;
|
||||
InstancePtr->WriteBufPtr[BYTE2] = (u8) (Address >> XISF_ADDR_SHIFT16);
|
||||
InstancePtr->WriteBufPtr[BYTE3] = (u8) (Address >> XISF_ADDR_SHIFT8);
|
||||
InstancePtr->WriteBufPtr[BYTE4] = (u8) (Address);
|
||||
|
||||
for(Index = 4; Index < ByteCount + XISF_CMD_SEND_EXTRA_BYTES;
|
||||
Index++) {
|
||||
InstancePtr->WriteBufPtr[Index] = *BufferPtr++;
|
||||
if (LocalBufPtr == NULL) {
|
||||
return (int)XST_FAILURE;
|
||||
}
|
||||
|
||||
/*
|
||||
* Initiate the Transfer.
|
||||
* Translate address based on type of connection
|
||||
* If stacked assert the slave select based on address
|
||||
*/
|
||||
Status = XIsf_Transfer(InstancePtr, InstancePtr->WriteBufPtr, NULL,
|
||||
(ByteCount + XISF_CMD_SEND_EXTRA_BYTES));
|
||||
if (Status != XST_SUCCESS) {
|
||||
return XST_FAILURE;
|
||||
RealAddr = GetRealAddr(InstancePtr->SpiInstPtr, Address);
|
||||
|
||||
#ifdef XPAR_XISF_INTERFACE_PSQSPI
|
||||
/*
|
||||
* 0x18 is the DeviceIDMemSize for different make of
|
||||
* flashes of size 16MB
|
||||
*/
|
||||
if(InstancePtr->DeviceIDMemSize > 0x18) {
|
||||
|
||||
/*
|
||||
* 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);
|
||||
|
||||
/*
|
||||
* Calculate bank
|
||||
*/
|
||||
BankSel = RealAddr/SIXTEENMB;
|
||||
/*
|
||||
* Select bank
|
||||
*/
|
||||
(void)SendBankSelect(InstancePtr, BankSel);
|
||||
|
||||
/*
|
||||
* Restoring the transfer mode back
|
||||
*/
|
||||
XIsf_SetTransferMode(InstancePtr, Mode);
|
||||
}
|
||||
#endif
|
||||
|
||||
InstancePtr->WriteBufPtr[BYTE1] = Command;
|
||||
InstancePtr->WriteBufPtr[BYTE2] = (u8) (RealAddr >> XISF_ADDR_SHIFT16);
|
||||
InstancePtr->WriteBufPtr[BYTE3] = (u8) (RealAddr >> XISF_ADDR_SHIFT8);
|
||||
InstancePtr->WriteBufPtr[BYTE4] = (u8) (RealAddr);
|
||||
|
||||
for(Index = 4U; Index < (ByteCount + XISF_CMD_SEND_EXTRA_BYTES);
|
||||
Index++) {
|
||||
InstancePtr->WriteBufPtr[Index] = *LocalBufPtr;
|
||||
LocalBufPtr += 1;
|
||||
}
|
||||
|
||||
return XST_SUCCESS;
|
||||
#ifdef XPAR_XISF_INTERFACE_PSQSPI
|
||||
/*
|
||||
* Enable write before transfer
|
||||
*/
|
||||
Status = XIsf_WriteEnable(InstancePtr, XISF_WRITE_ENABLE);
|
||||
#endif
|
||||
/*
|
||||
* Initiate the Transfer.
|
||||
*/
|
||||
Status = XIsf_Transfer(InstancePtr, InstancePtr->WriteBufPtr, NULLPtr,
|
||||
(ByteCount + XISF_CMD_SEND_EXTRA_BYTES));
|
||||
if (Status != (int)XST_SUCCESS) {
|
||||
return (int)XST_FAILURE;
|
||||
}
|
||||
|
||||
#ifdef XPAR_XISF_INTERFACE_PSQSPI
|
||||
if((InstancePtr->NumDie > 1) &&
|
||||
(FlashMake == XISF_MANUFACTURER_ID_MICRON)) {
|
||||
Status = XIsf_Transfer(InstancePtr, ReadFlagSRCmd, FlagStatus,
|
||||
(u32)sizeof(ReadFlagSRCmd));
|
||||
if(Status != (int)XST_SUCCESS){
|
||||
return (int)XST_FAILURE;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Wait for the write command to the Flash to be completed, it takes
|
||||
* some time for the data to be written
|
||||
*/
|
||||
while (1) {
|
||||
/*
|
||||
* Poll the status register of the Flash to determine when it
|
||||
* completes, by sending a read status command and receiving
|
||||
* status byte
|
||||
*/
|
||||
Status = XIsf_Transfer(InstancePtr, ReadStatusCmdBuf,
|
||||
FlashStatus, (u32)sizeof(ReadStatusCmdBuf));
|
||||
if(Status != (int)XST_SUCCESS){
|
||||
return (int)XST_FAILURE;
|
||||
}
|
||||
|
||||
/*
|
||||
* If status indicates the write is done, then stop waiting,
|
||||
* if a value of 0xFF in the status byte is read from the
|
||||
* device and this loop never exits, the device slave select is
|
||||
* possibly incorrect such that the device status is not being
|
||||
* read
|
||||
*/
|
||||
if ((FlashStatus[1] & 0x01) == 0) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if((InstancePtr->NumDie > 1) &&
|
||||
(FlashMake == XISF_MANUFACTURER_ID_MICRON)) {
|
||||
Status = XIsf_Transfer(InstancePtr, ReadFlagSRCmd, FlagStatus,
|
||||
(u32)sizeof(ReadFlagSRCmd));
|
||||
if(Status != (int)XST_SUCCESS){
|
||||
return (int)XST_FAILURE;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
return Status;
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
|
@ -401,7 +541,11 @@ static int WriteData(XIsf *InstancePtr, u8 Command, u32 Address,
|
|||
******************************************************************************/
|
||||
static int AutoPageWrite(XIsf *InstancePtr, u32 Address)
|
||||
{
|
||||
int Status = XST_FAILURE;
|
||||
int Status = (int)XST_FAILURE;
|
||||
|
||||
Xil_AssertNonvoid(InstancePtr != NULL);
|
||||
Xil_AssertNonvoid(Address != 0);
|
||||
|
||||
|
||||
#if (XPAR_XISF_FLASH_FAMILY == ATMEL)
|
||||
InstancePtr->WriteBufPtr[BYTE1] = XISF_CMD_AUTOPAGE_WRITE;
|
||||
|
@ -414,8 +558,8 @@ static int AutoPageWrite(XIsf *InstancePtr, u32 Address)
|
|||
*/
|
||||
Status = XIsf_Transfer(InstancePtr, InstancePtr->WriteBufPtr, NULL,
|
||||
XISF_CMD_SEND_EXTRA_BYTES);
|
||||
if (Status != XST_SUCCESS) {
|
||||
return XST_FAILURE;
|
||||
if (Status != (int)XST_SUCCESS) {
|
||||
return (int)XST_FAILURE;
|
||||
}
|
||||
#endif /* (XPAR_XISF_FLASH_FAMILY == ATMEL) */
|
||||
|
||||
|
@ -449,7 +593,13 @@ static int AutoPageWrite(XIsf *InstancePtr, u32 Address)
|
|||
static int BufferWrite(XIsf *InstancePtr, u8 BufferNum, const u8 *WritePtr,
|
||||
u32 ByteOffset, u32 NumBytes)
|
||||
{
|
||||
int Status = XST_FAILURE;
|
||||
int Status = (int)XST_FAILURE;
|
||||
|
||||
Xil_AssertNonvoid(InstancePtr != NULL);
|
||||
Xil_AssertNonvoid(BufferNum != 0);
|
||||
Xil_AssertNonvoid(WritePtr != NULL);
|
||||
Xil_AssertNonvoid(ByteOffset != 0);
|
||||
Xil_AssertNonvoid(NumBytes != 0);
|
||||
|
||||
#if (XPAR_XISF_FLASH_FAMILY == ATMEL)
|
||||
u16 Index;
|
||||
|
@ -461,23 +611,23 @@ static int BufferWrite(XIsf *InstancePtr, u8 BufferNum, const u8 *WritePtr,
|
|||
(BufferNum == XISF_PAGE_BUFFER2)) {
|
||||
if ((InstancePtr->DeviceCode == XISF_ATMEL_DEV_AT45DB011D) &&
|
||||
(BufferNum != XISF_PAGE_BUFFER1)) {
|
||||
return XST_FAILURE;
|
||||
return (int)XST_FAILURE;
|
||||
}
|
||||
}
|
||||
else{
|
||||
return XST_FAILURE;
|
||||
return (int)XST_FAILURE;
|
||||
}
|
||||
|
||||
if (WritePtr == NULL) {
|
||||
return XST_FAILURE;
|
||||
return (int)XST_FAILURE;
|
||||
}
|
||||
|
||||
if (ByteOffset > InstancePtr->BytesPerPage) {
|
||||
return XST_FAILURE;
|
||||
return (int)XST_FAILURE;
|
||||
}
|
||||
|
||||
if ((NumBytes <= 0) || (NumBytes > InstancePtr->BytesPerPage)) {
|
||||
return XST_FAILURE;
|
||||
return (int)XST_FAILURE;
|
||||
}
|
||||
|
||||
|
||||
|
@ -501,8 +651,8 @@ static int BufferWrite(XIsf *InstancePtr, u8 BufferNum, const u8 *WritePtr,
|
|||
*/
|
||||
Status = XIsf_Transfer(InstancePtr, InstancePtr->WriteBufPtr, NULL,
|
||||
(NumBytes + XISF_CMD_SEND_EXTRA_BYTES));
|
||||
if (Status != XST_SUCCESS) {
|
||||
return XST_FAILURE;
|
||||
if (Status != (int)XST_SUCCESS) {
|
||||
return (int)XST_FAILURE;
|
||||
}
|
||||
#endif /* (XPAR_XISF_FLASH_FAMILY == ATMEL) */
|
||||
|
||||
|
@ -518,8 +668,8 @@ static int BufferWrite(XIsf *InstancePtr, u8 BufferNum, const u8 *WritePtr,
|
|||
* @param InstancePtr is a pointer to the XIsf instance.
|
||||
* @param BufferNum specifies the internal SRAM Buffer, from which the
|
||||
* data needs to be written to the Serial Flash. The valid values
|
||||
* are XISF_PAGE_BUFFER1 or XISF_PAGE_BUFFER2. XISF_PAGE_BUFFER2 is
|
||||
* not valid in the case of Atmel AT45DB011D Serial Flash as it
|
||||
* are XISF_PAGE_BUFFER1 or XISF_PAGE_BUFFER2. XISF_PAGE_BUFFER2
|
||||
* is not valid in the case of Atmel AT45DB011D Serial Flash as it
|
||||
* contains a single buffer.
|
||||
* @param Address is the starting address in the Serial Flash where
|
||||
* the data has to be written. Byte address in this address is
|
||||
|
@ -528,15 +678,19 @@ static int BufferWrite(XIsf *InstancePtr, u8 BufferNum, const u8 *WritePtr,
|
|||
* @return XST_SUCCESS if successful else XST_FAILURE.
|
||||
*
|
||||
* @note
|
||||
* - A minimum of one Page and a maximum of one Page can be written
|
||||
* using this function.
|
||||
* - A minimum of one Page and a maximum of one Page can be
|
||||
* written using this function.
|
||||
* - This operation is only supported for Atmel Serial Flash.
|
||||
*
|
||||
******************************************************************************/
|
||||
static int BufferToFlashWriteWithErase(XIsf *InstancePtr, u8 BufferNum,
|
||||
u32 Address)
|
||||
{
|
||||
int Status = XST_FAILURE;
|
||||
int Status = (int)XST_FAILURE;
|
||||
|
||||
Xil_AssertNonvoid(InstancePtr != NULL);
|
||||
Xil_AssertNonvoid(BufferNum != 0);
|
||||
Xil_AssertNonvoid(Address != 0);
|
||||
|
||||
#if (XPAR_XISF_FLASH_FAMILY == ATMEL)
|
||||
/*
|
||||
|
@ -546,11 +700,11 @@ static int BufferToFlashWriteWithErase(XIsf *InstancePtr, u8 BufferNum,
|
|||
(BufferNum == XISF_PAGE_BUFFER2)) {
|
||||
if ((InstancePtr->DeviceCode == XISF_ATMEL_DEV_AT45DB011D) &&
|
||||
(BufferNum != XISF_PAGE_BUFFER1)) {
|
||||
return XST_FAILURE;
|
||||
return (int)XST_FAILURE;
|
||||
}
|
||||
}
|
||||
else {
|
||||
return XST_FAILURE;
|
||||
return (int)XST_FAILURE;
|
||||
}
|
||||
|
||||
if (BufferNum == XISF_PAGE_BUFFER1) {
|
||||
|
@ -575,8 +729,8 @@ static int BufferToFlashWriteWithErase(XIsf *InstancePtr, u8 BufferNum,
|
|||
*/
|
||||
Status = XIsf_Transfer(InstancePtr, InstancePtr->WriteBufPtr, NULL,
|
||||
XISF_CMD_SEND_EXTRA_BYTES);
|
||||
if (Status != XST_SUCCESS) {
|
||||
return XST_FAILURE;
|
||||
if (Status != (int)XST_SUCCESS) {
|
||||
return (int)XST_FAILURE;
|
||||
}
|
||||
#endif /* (XPAR_XISF_FLASH_FAMILY == ATMEL) */
|
||||
|
||||
|
@ -592,8 +746,8 @@ static int BufferToFlashWriteWithErase(XIsf *InstancePtr, u8 BufferNum,
|
|||
* @param InstancePtr is a pointer to the XIsf instance.
|
||||
* @param BufferNum specifies the internal SRAM Buffer, from which the
|
||||
* data needs to be written to the Serial Flash. The valid values
|
||||
* are XISF_PAGE_BUFFER1 or XISF_PAGE_BUFFER2. XISF_PAGE_BUFFER2 is
|
||||
* not valid in the case of Atmel AT45DB011D Serial Flash as it
|
||||
* are XISF_PAGE_BUFFER1 or XISF_PAGE_BUFFER2. XISF_PAGE_BUFFER2
|
||||
* is not valid in the case of Atmel AT45DB011D Serial Flash as it
|
||||
* contains a single buffer.
|
||||
* @param Address is the starting address in the Serial Flash where
|
||||
* data has to be written. Byte address in this address will be
|
||||
|
@ -602,15 +756,19 @@ static int BufferToFlashWriteWithErase(XIsf *InstancePtr, u8 BufferNum,
|
|||
*
|
||||
* @return XST_SUCCESS if successful else XST_FAILURE.
|
||||
*
|
||||
* - A minimum of one Page and a maximum of one Page can be written
|
||||
* using this function.
|
||||
* - A minimum of one Page and a maximum of one Page can be
|
||||
* written using this function.
|
||||
* - This operation is only supported for Atmel Serial Flash.
|
||||
*
|
||||
******************************************************************************/
|
||||
static int BufferToFlashWriteWithoutErase(XIsf *InstancePtr, u8 BufferNum,
|
||||
u32 Address)
|
||||
{
|
||||
int Status = XST_FAILURE;
|
||||
int Status = (int)XST_FAILURE;
|
||||
|
||||
Xil_AssertNonvoid(InstancePtr != NULL);
|
||||
Xil_AssertNonvoid(BufferNum != 0);
|
||||
Xil_AssertNonvoid(Address != 0);
|
||||
|
||||
#if (XPAR_XISF_FLASH_FAMILY == ATMEL)
|
||||
/*
|
||||
|
@ -620,11 +778,11 @@ static int BufferToFlashWriteWithoutErase(XIsf *InstancePtr, u8 BufferNum,
|
|||
(BufferNum == XISF_PAGE_BUFFER2)) {
|
||||
if ((InstancePtr->DeviceCode == XISF_ATMEL_DEV_AT45DB011D) &&
|
||||
(XISF_PAGE_BUFFER1 != 1)) {
|
||||
return XST_FAILURE;
|
||||
return (int)XST_FAILURE;
|
||||
}
|
||||
}
|
||||
else {
|
||||
return XST_FAILURE;
|
||||
return (int)XST_FAILURE;
|
||||
}
|
||||
|
||||
if (BufferNum == XISF_PAGE_BUFFER1) {
|
||||
|
@ -649,8 +807,8 @@ static int BufferToFlashWriteWithoutErase(XIsf *InstancePtr, u8 BufferNum,
|
|||
*/
|
||||
Status = XIsf_Transfer(InstancePtr, InstancePtr->WriteBufPtr, NULL,
|
||||
XISF_CMD_SEND_EXTRA_BYTES);
|
||||
if (Status != XST_SUCCESS) {
|
||||
return XST_FAILURE;
|
||||
if (Status != (int)XST_SUCCESS) {
|
||||
return (int)XST_FAILURE;
|
||||
}
|
||||
#endif /* (XPAR_XISF_FLASH_FAMILY == ATMEL) */
|
||||
|
||||
|
@ -679,8 +837,8 @@ static int WriteSR(XIsf *InstancePtr, u8 SRData)
|
|||
int Status = XST_FAILURE;
|
||||
|
||||
#if ((XPAR_XISF_FLASH_FAMILY == INTEL) || (XPAR_XISF_FLASH_FAMILY == STM) || \
|
||||
(XPAR_XISF_FLASH_FAMILY == WINBOND) || (XPAR_XISF_FLASH_FAMILY == SPANSION) \
|
||||
|| (XPAR_XISF_FLASH_FAMILY == SST))
|
||||
(XPAR_XISF_FLASH_FAMILY == WINBOND) || \
|
||||
(XPAR_XISF_FLASH_FAMILY == SPANSION) || (XPAR_XISF_FLASH_FAMILY == SST))
|
||||
/*
|
||||
* Prepare the Write Buffer.
|
||||
*/
|
||||
|
@ -692,8 +850,8 @@ static int WriteSR(XIsf *InstancePtr, u8 SRData)
|
|||
*/
|
||||
Status = XIsf_Transfer(InstancePtr, InstancePtr->WriteBufPtr, NULL,
|
||||
XISF_STATUS_RDWR_BYTES);
|
||||
if (Status != XST_SUCCESS) {
|
||||
return XST_FAILURE;
|
||||
if (Status != (int)XST_SUCCESS) {
|
||||
return (int)XST_FAILURE;
|
||||
}
|
||||
#endif /* ((XPAR_XISF_FLASH_FAMILY==INTEL) || (XPAR_XISF_FLASH_FAMILY==STM) \\
|
||||
(XPAR_XISF_FLASH_FAMILY == WINBOND) ||
|
||||
|
@ -705,7 +863,7 @@ static int WriteSR(XIsf *InstancePtr, u8 SRData)
|
|||
/*****************************************************************************/
|
||||
/**
|
||||
*
|
||||
* This function writes data to the Status Register of the Serial Flash. This API
|
||||
* This function writes data to Status Register of the Serial Flash. This API
|
||||
* should be used to write to the 16 bit status register in Winbond Quad Flash
|
||||
* (W25QXX).
|
||||
*
|
||||
|
@ -721,7 +879,10 @@ static int WriteSR(XIsf *InstancePtr, u8 SRData)
|
|||
******************************************************************************/
|
||||
static int WriteSR2(XIsf *InstancePtr, u8 *SRData)
|
||||
{
|
||||
int Status = XST_FAILURE;
|
||||
int Status = (int)XST_FAILURE;
|
||||
|
||||
Xil_AssertNonvoid(InstancePtr != NULL);
|
||||
Xil_AssertNonvoid(SRData != NULL);
|
||||
|
||||
#if (XPAR_XISF_FLASH_FAMILY == WINBOND)
|
||||
/*
|
||||
|
@ -736,8 +897,8 @@ static int WriteSR2(XIsf *InstancePtr, u8 *SRData)
|
|||
*/
|
||||
Status = XIsf_Transfer(InstancePtr, InstancePtr->WriteBufPtr, NULL,
|
||||
XISF_STATUS_RDWR_BYTES + 1);
|
||||
if (Status != XST_SUCCESS) {
|
||||
return XST_FAILURE;
|
||||
if (Status != (int)XST_SUCCESS) {
|
||||
return (int)XST_FAILURE;
|
||||
}
|
||||
#endif /* (XPAR_XISF_FLASH_FAMILY == WINBOND) */
|
||||
|
||||
|
@ -750,7 +911,7 @@ static int WriteSR2(XIsf *InstancePtr, u8 *SRData)
|
|||
* This function writes one byte of data to the OTP area in the Serial Flash.
|
||||
*
|
||||
* @param InstancePtr is a pointer to the XIsf instance.
|
||||
* @param Address is the address in the OTP area, where to write the data.
|
||||
* @param Address is the address in the OTP area, where to write data.
|
||||
* @param BufferPtr is the pointer to the data to be written into OTP
|
||||
* region of Serial Flash.
|
||||
*
|
||||
|
@ -764,11 +925,16 @@ static int WriteSR2(XIsf *InstancePtr, u8 *SRData)
|
|||
******************************************************************************/
|
||||
static int WriteOTPData(XIsf *InstancePtr, u32 Address, const u8 *BufferPtr)
|
||||
{
|
||||
int Status = XST_FAILURE;
|
||||
int Status = (int)XST_FAILURE;
|
||||
|
||||
Xil_AssertNonvoid(InstancePtr != NULL);
|
||||
Xil_AssertNonvoid(Address != 0);
|
||||
Xil_AssertNonvoid(BufferPtr != NULL);
|
||||
|
||||
|
||||
#if (XPAR_XISF_FLASH_FAMILY == INTEL)
|
||||
if (BufferPtr == NULL) {
|
||||
return XST_FAILURE;
|
||||
return (int)XST_FAILURE;
|
||||
}
|
||||
|
||||
InstancePtr->WriteBufPtr[BYTE1] = XISF_CMD_OTP_WRITE;
|
||||
|
@ -782,8 +948,8 @@ static int WriteOTPData(XIsf *InstancePtr, u32 Address, const u8 *BufferPtr)
|
|||
*/
|
||||
Status = XIsf_Transfer(InstancePtr, InstancePtr->WriteBufPtr, NULL,
|
||||
XISF_OTP_RDWR_EXTRA_BYTES);
|
||||
if (Status != XST_SUCCESS) {
|
||||
return XST_FAILURE;
|
||||
if (Status != (int)XST_SUCCESS) {
|
||||
return (int)XST_FAILURE;
|
||||
}
|
||||
#endif /* (XPAR_XISF_FLASH_FAMILY == INTEL) */
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue