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:
Shakti Bhatnagar 2014-08-07 18:18:06 +05:30 committed by Jagannadha Sutradharudu Teki
parent ee1d5c6b44
commit c2b6e79695
22 changed files with 2627 additions and 825 deletions

View file

@ -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.

View file

@ -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.

View file

@ -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.
*/

View file

@ -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.

View file

@ -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

View file

@ -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.
*/

View file

@ -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;
}

View file

@ -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;
}

View file

@ -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) {

View file

@ -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;
}
}

View file

@ -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.

View file

@ -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.

View file

@ -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.

View file

@ -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.

View file

@ -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.

View file

@ -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.

View file

@ -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

View file

@ -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

View file

@ -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) */

View file

@ -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) */

View file

@ -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) */