diff --git a/lib/sw_services/xilisf/data/xilisf.mld b/lib/sw_services/xilisf/data/xilisf.mld
new file mode 100755
index 00000000..325d341e
--- /dev/null
+++ b/lib/sw_services/xilisf/data/xilisf.mld
@@ -0,0 +1,58 @@
+###############################################################################
+#
+# Copyright (C) 2012 - 2015 Xilinx, Inc. All rights reserved.
+#
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to deal
+# in the Software without restriction, including without limitation the rights
+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+# copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included in
+# all copies or substantial portions of the Software.
+#
+# Use of the Software is limited solely to applications:
+# (a) running on a Xilinx device, or
+# (b) that interact with a Xilinx device through a bus or interconnect.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+# XILINX BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+# WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
+# OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+# SOFTWARE.
+#
+# Except as contained in this notice, the name of the Xilinx shall not be used
+# in advertising or otherwise to promote the sale, use or other dealings in
+# this Software without prior written authorization from Xilinx.
+#
+###############################################################################
+#
+# Modification History
+#
+# Ver Who Date Changes
+# ----- ---- -------- -----------------------------------------------
+# 2.04a sdm 08/01/11 Added new parameter for Numonyx quad flash devices.
+# 3.00a srt 06/20/12 Updated to support interfaces SPI PS and QSPI PS.
+# Added support to SST flash.
+# 3.00a srt 02/06/13 Changed the serial flash family options to include
+# Spansion flash (CR 696379).
+# 5.1 sb 12/23/14 Added Micron to the serial flash family options.
+#
+##############################################################################
+
+OPTION psf_version = 2.1;
+
+BEGIN LIBRARY xilisf
+ OPTION drc = isf_drc;
+ OPTION copyfiles = all;
+ OPTION REQUIRES_OS = (standalone xilkernel);
+ OPTION APP_LINKER_FLAGS = "-Wl,--start-group,-lxilisf,-lxil,-lgcc,-lc,--end-group";
+ OPTION desc = "Xilinx In-system and Serial Flash Library";
+ OPTION VERSION = 5.3;
+ OPTION NAME = xilisf;
+ PARAM name = serial_flash_family, desc = "Indicates the Serial Flash family type. Enter 1 for ATMEL. 2 for INTEL. 3 for STM (M25PXX). 4 for Winbond. 5 for Spansion / Micron. 6 for SST Flash", type = int, default = 1;
+ PARAM name = serial_flash_interface, desc = "Indicates the Serial Flash Interface. Enter 1 for AXI SPI. 2 for PS SPI. 3 for PS QSPI.", type = int, default = 1;
+END LIBRARY
diff --git a/lib/sw_services/xilisf/data/xilisf.tcl b/lib/sw_services/xilisf/data/xilisf.tcl
new file mode 100755
index 00000000..7e2d1f13
--- /dev/null
+++ b/lib/sw_services/xilisf/data/xilisf.tcl
@@ -0,0 +1,191 @@
+###############################################################################
+#
+# Copyright (C) 2012 - 2015 Xilinx, Inc. All rights reserved.
+#
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to deal
+# in the Software without restriction, including without limitation the rights
+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+# copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included in
+# all copies or substantial portions of the Software.
+#
+# Use of the Software is limited solely to applications:
+# (a) running on a Xilinx device, or
+# (b) that interact with a Xilinx device through a bus or interconnect.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+# XILINX BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+# WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
+# OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+# SOFTWARE.
+#
+# Except as contained in this notice, the name of the Xilinx shall not be used
+# in advertising or otherwise to promote the sale, use or other dealings in
+# this Software without prior written authorization from Xilinx.
+#
+###############################################################################
+#
+# Modification History
+#
+# Ver Who Date Changes
+# ----- ---- -------- -----------------------------------------------
+# 2.01a sdm 06/17/10 Updated to support axi_spi
+# 2.02a sdm 09/24/10 updated to use Tcl commands instead of unix commands
+# 2.03a sdm 04/17/11 Updated to support axi_quad_spi
+# 2.04a sdm 08/01/11 Added new parameter for Numonyx quad flash devices.
+# 3.00a srt 06/20/12 Updated to support interfaces SPI PS and QSPI PS.
+# Added support to SST flash.
+# 3.02a srt 05/13/13 Removed compiler errors when not selecting proper
+# interface for Zynq. (CR 716451)
+#
+##############################################################################
+
+#---------------------------------------------
+# ISF_drc - check system configuration and make sure
+# all components to run ISF are available.
+#---------------------------------------------
+
+proc isf_drc {libhandle} {
+ puts "Running DRC for XilIsf library... \n"
+
+ # find the list of xps or opb spi cores
+ set sw_processor [hsi::get_sw_processor]
+ set processor [hsi::get_cells [common::get_property HW_INSTANCE $sw_processor]]
+
+ set spi_periphs_list [get_spi_periphs $processor]
+
+ if { [llength $spi_periphs_list] == 0 } {
+ set cpuname [common::get_property NAME $processor]
+ error "ERROR: No SPI core is addressable from processor $cpuname. \
+ XilIsf library requires a SPI Core \n"
+ return
+ }
+}
+
+proc get_spi_periphs {processor} {
+ set periphs_list [::hsi::utils::get_proc_slave_periphs $processor]
+ set spi_periphs_list {}
+
+ global spi_periphs_name_list
+ set spi_periphs_name_list {}
+
+ foreach periph $periphs_list {
+ set periphname [common::get_property IP_NAME $periph]
+ if {$periphname == "xps_spi"
+ || $periphname == "opb_spi"
+ || $periphname == "xps_insystem_flash"
+ || $periphname == "axi_spi"
+ || $periphname == "axi_quad_spi"
+ || $periphname == "ps7_spi"
+ || $periphname == "ps7_qspi"} {
+ lappend spi_periphs_list $periph
+ lappend spi_periphs_name_list $periphname
+ }
+ }
+
+ return $spi_periphs_list
+}
+
+#--------
+# Check the following h/w requirements for XilIsf:
+#--------
+proc isf_hw_drc {libhandle spi_list} {
+}
+
+
+# SPI hw requirements
+proc isf_spi_hw_drc {libhandle spi} {
+
+}
+
+
+proc generate {libhandle} {
+
+}
+
+
+#-------
+# post_generate: called after generate called on all libraries
+#-------
+proc post_generate {libhandle} {
+ xgen_opts_file $libhandle
+
+}
+
+#-------
+# execs_generate: called after BSP's, libraries and drivers have been compiled
+# This procedure builds the libisf.a library
+#-------
+proc execs_generate {libhandle} {
+
+}
+
+
+proc xgen_opts_file {libhandle} {
+
+ # Open xparameters.h file
+ set file_handle [::hsi::utils::open_include_file "xparameters.h"]
+
+ # -----------------------------
+ # Generate Flash options
+ # -----------------------------
+ puts $file_handle "/* Xilinx EDK In-system and Serial Flash Library (XilIsf) User Settings */"
+ set serial_flash_family [common::get_property CONFIG.serial_flash_family $libhandle]
+ puts $file_handle "\#define XPAR_XISF_FLASH_FAMILY $serial_flash_family"
+
+ set serial_flash_interface [common::get_property CONFIG.serial_flash_interface $libhandle]
+ set ifaceselect 0
+ set ps7qspi 0
+ global spi_periphs_name_list
+ foreach periph $spi_periphs_name_list {
+ if {$periph == "axi_spi" || $periph == "axi_quad_spi"
+ || $periph == "opb_spi"
+ || $periph == "xps_insystem_flash"
+ || $periph == "xps_spi"} {
+ if {$serial_flash_interface == 1} {
+ puts $file_handle "\#define XPAR_XISF_INTERFACE_AXISPI 1"
+ set ifaceselect 1
+ }
+ } elseif {$periph == "ps7_spi" &&
+ $serial_flash_interface == 2} {
+ puts $file_handle "\#define XPAR_XISF_INTERFACE_PSSPI 1"
+ set ifaceselect 1
+ } elseif {$periph == "ps7_qspi" &&
+ $serial_flash_interface == 3} {
+ puts $file_handle "\#define XPAR_XISF_INTERFACE_PSQSPI 1"
+ set ifaceselect 1
+ } elseif {$periph == "ps7_qspi"} {
+ set ps7qspi 1
+ }
+ }
+
+ if {$ps7qspi == 1 && $ifaceselect == 0} {
+ puts "WARN: Improper Flash Interface from BSP Settings!!!! Defaulting on 'ps7_qspi' interface"
+ puts $file_handle "\#define XPAR_XISF_INTERFACE_PSQSPI 1"
+ }
+
+ puts $file_handle ""
+ close $file_handle
+
+ # Copy the include files to the include directory
+ set srcdir [file join src include]
+ set dstdir [file join .. .. include]
+
+ # Create dstdir if it does not exist
+ if { ! [file exists $dstdir] } {
+ file mkdir $dstdir
+ }
+
+ # Get list of files in the srcdir
+ set sources [glob -join $srcdir *.h]
+
+ # Copy each of the files in the list to dstdir
+ foreach source $sources {
+ file copy -force $source $dstdir
+ }
+}
diff --git a/lib/sw_services/xilisf/examples/xilisf_atmel_buffer_rdwr_example.c b/lib/sw_services/xilisf/examples/xilisf_atmel_buffer_rdwr_example.c
new file mode 100644
index 00000000..1f66d4d0
--- /dev/null
+++ b/lib/sw_services/xilisf/examples/xilisf_atmel_buffer_rdwr_example.c
@@ -0,0 +1,556 @@
+/******************************************************************************
+*
+* Copyright (C) 2012 - 2014 Xilinx, Inc. All rights reserved.
+*
+* Permission is hereby granted, free of charge, to any person obtaining a copy
+* of this software and associated documentation files (the "Software"), to deal
+* in the Software without restriction, including without limitation the rights
+* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+* copies of the Software, and to permit persons to whom the Software is
+* furnished to do so, subject to the following conditions:
+*
+* The above copyright notice and this permission notice shall be included in
+* all copies or substantial portions of the Software.
+*
+* Use of the Software is limited solely to applications:
+* (a) running on a Xilinx device, or
+* (b) that interact with a Xilinx device through a bus or interconnect.
+*
+* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+* XILINX BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
+* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+* SOFTWARE.
+*
+* Except as contained in this notice, the name of the Xilinx shall not be used
+* in advertising or otherwise to promote the sale, use or other dealings in
+* this Software without prior written authorization from Xilinx.
+*
+******************************************************************************/
+/*****************************************************************************/
+/**
+* @file xilisf_atmel_buffer_rdwr_example.c
+*
+*
+* This file contains a design example using the Xilinx In-system and Serial
+* Flash Library (XilIsf). This example shows the Buffer Write, Buffer to Page
+* Program with Built-in Erase, Page to Buffer Transfer and Buffer Read features.
+*
+* This example
+* - Writes to a SRAM page buffer using Buffer Write feature
+* - Erase a Page and data is transferred to this page from the SRAM page buffer
+* using the Buffer to Page Program with Built-in Erase feature.
+* - Transfers the data to a SRAM Page using Page to Buffer Transfer feature.
+* - Reads back the Buffer that is written using the Buffer Read feature and
+* compares the data.
+*
+* The example works for AT45DB011D/AT45DB021D/AT45DB041D/AT45DB081D Serial Flash
+* devices. The bytes per page (ISF_PAGE_SIZE) in these devices is 264 for
+* Default addressing mode and 256 in Power-of-2 addressing mode.
+*
+* For AT45DB161D/AT45DB321D the Bytes Per Page (ISF_PAGE_SIZE) is 528 for
+* Default addressing mode and 512 in Power-Of-2 addressing mode.
+*
+* For AT45DB642D the Bytes Per Page (ISF_PAGE_SIZE) is 1056 for Default
+* addressing mode and 1024 in Power-Of-2 addressing mode.
+*
+* The ISF_PAGE_SIZE should be defined by the user according to the Device used.
+*
+* For further details of each device refer to the Spartan-3AN Serial Flash User
+* Guide and data sheets of Atmel AT45XXXD .
+*
+* This example has been tested with the In-system Flash Memory available on the
+* Spartan-3AN on a Xilinx Spartan-3AN Starter Kit board.
+*
+* @note
+*
+* None.
+*
+*
+* MODIFICATION HISTORY:
+*
+* Ver Who Date Changes
+* ----- ------- -------- ---------------------------------------------------
+* 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.
+*
+*
+******************************************************************************/
+
+/***************************** Include Files *********************************/
+
+#include "xil_types.h"
+#include "xparameters.h" /* EDK generated parameters */
+#include "xintc.h" /* Interrupt controller device driver */
+#include /* Serial Flash Library header file */
+#include "xil_exception.h"
+
+/************************** Constant Definitions *****************************/
+
+/*
+ * The following constants map to the XPAR parameters created in the
+ * xparameters.h file. They are defined here such that a user can easily
+ * change all the needed parameters in one place.
+ */
+#define SPI_DEVICE_ID XPAR_SPI_0_DEVICE_ID
+#define INTC_DEVICE_ID XPAR_INTC_0_DEVICE_ID
+#define SPI_INTR_ID XPAR_INTC_0_SPI_0_VEC_ID
+
+/*
+ * The following constant defines the slave select signal that is used to
+ * to select the Serial Flash device on the SPI bus, this signal is typically
+ * connected to the chip select of the device.
+ */
+#define ISF_SPI_SELECT 0x01
+
+/*
+ * Page size of the Serial Flash.
+ */
+#define ISF_PAGE_SIZE 264
+
+/*
+ * Address of the page to perform Erase, Write and Read operations.
+ */
+#define TEST_ADDRESS 0xA3600
+
+#define ISF_TEST_BYTE 0x28 /* Test Byte offset value written to Serial
+ Flash */
+
+/**************************** Type Definitions *******************************/
+
+/***************** Macros (Inline Functions) Definitions *********************/
+
+/************************** Function Prototypes ******************************/
+
+static int IsfWaitForFlashNotBusy();
+
+static int SetupInterruptSystem(XSpi *SpiPtr);
+
+void SpiHandler(void *CallBackRef, u32 StatusEvent, u16 ByteCount);
+
+/************************** Variable Definitions *****************************/
+
+/*
+ * The instances to support the device drivers are global such that the
+ * are initialized to zero each time the program runs.
+ */
+static XIsf Isf;
+static XIntc InterruptController;
+static XSpi Spi;
+
+/*
+ * The following variables are shared between non-interrupt processing and
+ * interrupt processing such that they must be global.
+ */
+volatile static int TransferInProgress; /* State of Spi Transfer */
+static int ErrorCount; /* Errors occurred during Spi transfers */
+
+/*
+ * The user needs to allocate a buffer to be used by the In-system and Serial
+ * Flash Library to perform any read/write operations on the Serial Flash
+ * device.
+ * User applications must pass the address of this memory to the Library in
+ * Serial Flash Initialization function, for the Library to work.
+ * For Write operations:
+ * - The size of this buffer should be equal to the Number of bytes to be
+ * written to the Serial Flash + XISF_CMD_MAX_EXTRA_BYTES.
+ * - The size of this buffer should be large enough for usage across all the
+ * applications that use a common instance of the Serial Flash.
+ * - A minimum of one byte and a maximum of ISF_PAGE_SIZE bytes can be written
+ * to the Serial Flash, through a single Write operation.
+ * The size of this buffer should be equal to XISF_CMD_MAX_EXTRA_BYTES, if the
+ * application only reads from the Serial Flash (no write operations).
+ */
+u8 IsfWriteBuffer[ISF_PAGE_SIZE + XISF_CMD_SEND_EXTRA_BYTES];
+
+/*
+ * Buffers used during read and write transactions.
+ */
+u8 ReadBuffer[ISF_PAGE_SIZE + XISF_CMD_SEND_EXTRA_BYTES] ; /* Read Buffer */
+u8 WriteBuffer[ISF_PAGE_SIZE]; /* Write buffer */
+
+/*****************************************************************************/
+/**
+*
+* Main function to execute the Atmel Serial Flash Buffer Read/Write example.
+*
+* @param None
+*
+* @return XST_SUCCESS if successful else XST_FAILURE.
+*
+* @note None
+*
+******************************************************************************/
+int main(void)
+{
+ int Status;
+ u16 Index;
+ XIsf_BufferWriteParam BufferWriteParam;
+ XIsf_BufferToFlashWriteParam BufferToFlashWriteParam;
+ XIsf_FlashToBufTransferParam FlashToBufTransferParam;
+ XIsf_BufferReadParam BufferReadParam;
+
+ /*
+ * Initialize the SPI driver so that it's ready to use,
+ * specify the device ID that is generated in xparameters.h.
+ */
+ Status = XSpi_Initialize(&Spi, SPI_DEVICE_ID);
+ if(Status != XST_SUCCESS) {
+ return XST_FAILURE;
+ }
+
+ /*
+ * Connect the SPI driver to the interrupt subsystem such that
+ * interrupts can occur. This function is application specific.
+ */
+ Status = SetupInterruptSystem(&Spi);
+ if(Status != XST_SUCCESS) {
+ return XST_FAILURE;
+ }
+
+ /*
+ * Setup the handler for the SPI that will be called from the interrupt
+ * context when an SPI status occurs, specify a pointer to the SPI
+ * driver instance as the callback reference so the handler is able to
+ * access the instance data.
+ */
+ XIsf_SetStatusHandler(&Isf, &Spi, (XSpi_StatusHandler)SpiHandler);
+
+ /*
+ * Start the SPI driver so that interrupts and the device are enabled.
+ */
+ Status = XSpi_Start(&Spi);
+ if(Status != XST_SUCCESS) {
+ return XST_FAILURE;
+ }
+
+ /*
+ * Initialize the In-system and Serial Flash Library.
+ */
+ Status = XIsf_Initialize(&Isf, &Spi, ISF_SPI_SELECT, IsfWriteBuffer);
+ if(Status != XST_SUCCESS) {
+ 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.
+ * - Byte offset within SRAM page buffer where the data is to be written
+ * - The number of bytes to be written.
+ * - The Write Buffer with the data to be written.
+ */
+ BufferWriteParam.BufferNum = XISF_PAGE_BUFFER1;
+ BufferWriteParam.ByteOffset = 0;
+ BufferWriteParam.NumBytes = ISF_PAGE_SIZE;
+ BufferWriteParam.WritePtr = WriteBuffer;
+
+ /*
+ * Prepare the write buffer. Fill in the data need to be written into
+ * Serial Flash.
+ */
+ for(Index = 0; Index < ISF_PAGE_SIZE; Index++) {
+ BufferWriteParam.WritePtr[Index] = Index + ISF_TEST_BYTE;
+ }
+
+ /*
+ * Write to SRAM Page buffer.
+ */
+ TransferInProgress = TRUE;
+ Status = XIsf_Write(&Isf, XISF_BUFFER_WRITE, (void*) &BufferWriteParam);
+ if(Status != XST_SUCCESS) {
+ return XST_FAILURE;
+ }
+
+ /*
+ * Wait till the Transfer is complete and check for any errors.
+ */
+ while(TransferInProgress);
+ if(ErrorCount != 0) {
+ return XST_FAILURE;
+ }
+
+
+ /*
+ * Set the
+ * - SRAM page buffer number from where the data is to be written.
+ * - Page Address in the Serial Flash where the data is to be written.
+ */
+ BufferToFlashWriteParam.BufferNum = XISF_PAGE_BUFFER1;
+ BufferToFlashWriteParam.Address = TEST_ADDRESS;
+
+ /*
+ * Perform Erase then Write to Serial Flash from the SRAM page buffer.
+ */
+ TransferInProgress = TRUE;
+ Status = XIsf_Write(&Isf, XISF_BUF_TO_PAGE_WRITE_WITH_ERASE,
+ (void*) &BufferToFlashWriteParam);
+ if(Status != XST_SUCCESS) {
+ return XST_FAILURE;
+ }
+
+ /*
+ * Wait till the Transfer is complete and check for any errors.
+ */
+ while(TransferInProgress);
+ if(ErrorCount != 0) {
+ return XST_FAILURE;
+ }
+
+ /*
+ * Wait till the Serial Flash is ready to accept next command.
+ */
+ Status = IsfWaitForFlashNotBusy();
+ if(Status != XST_SUCCESS) {
+ return XST_FAILURE;
+ }
+
+ /*
+ * Set the
+ * - SRAM page buffer number to which the data is to be read.
+ * - Set the Page Address from where the data is to be transferred.
+ */
+ FlashToBufTransferParam.BufferNum = XISF_PAGE_BUFFER1;
+ FlashToBufTransferParam.Address = TEST_ADDRESS;
+
+ /*
+ * Transfer data from the Serial Flash to the SRAM page buffer.
+ */
+ TransferInProgress = TRUE;
+ Status = XIsf_Read(&Isf, XISF_PAGE_TO_BUF_TRANS,
+ (void*) &FlashToBufTransferParam);
+ if(Status != XST_SUCCESS) {
+ return XST_FAILURE;
+ }
+
+ /*
+ * Wait till the Transfer is complete and check for any errors.
+ */
+ while(TransferInProgress);
+ if(ErrorCount != 0) {
+ return XST_FAILURE;
+ }
+
+ /*
+ * Wait till the Serial Flash is ready to accept next command.
+ */
+ Status = IsfWaitForFlashNotBusy();
+ if(Status != XST_SUCCESS) {
+ return XST_FAILURE;
+ }
+
+ /*
+ * Set the
+ * - SRAM page buffer number where the data is to be read.
+ * - Byte offset within SRAM page buffer where the data is to be read.
+ * - The number of bytes to be read.
+ * - The Read Buffer to which with the data is to be read.
+ */
+ BufferReadParam.BufferNum = XISF_PAGE_BUFFER1;
+ BufferReadParam.ByteOffset = 0;
+ BufferReadParam.NumBytes = ISF_PAGE_SIZE;
+ BufferReadParam.ReadPtr = ReadBuffer;
+
+ /*
+ * Read data from SRAM page buffer.
+ */
+ TransferInProgress = TRUE;
+ Status = XIsf_Read(&Isf, XISF_BUFFER_READ, (void*) &BufferReadParam);
+ if(Status != XST_SUCCESS) {
+ return XST_FAILURE;
+ }
+
+ /*
+ * Wait till the Transfer is complete and check for any errors.
+ */
+ while(TransferInProgress);
+ if(ErrorCount != 0) {
+ return XST_FAILURE;
+ }
+
+ /*
+ * Compare the data read against the data written.
+ */
+ for(Index = 0; Index < ISF_PAGE_SIZE; Index++) {
+ if(ReadBuffer[Index + XISF_CMD_SEND_EXTRA_BYTES] !=
+ (u8)(Index + ISF_TEST_BYTE)) {
+ return XST_FAILURE;
+ }
+ }
+
+ return XST_SUCCESS;
+}
+
+/*****************************************************************************/
+/**
+*
+* This function waits till the Atmel Serial Flash is ready to accept next
+* command.
+*
+* @param None
+*
+* @return XST_SUCCESS if successful else XST_FAILURE.
+*
+* @note None.
+*
+******************************************************************************/
+static int IsfWaitForFlashNotBusy()
+{
+ 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 complete and check for any errors.
+ */
+ while(TransferInProgress);
+ if(ErrorCount != 0) {
+ return XST_FAILURE;
+ }
+
+ /*
+ * Check if the Serial Flash is ready to accept the next
+ * command. If so break.
+ */
+ StatusReg = ReadBuffer[1];
+ if(StatusReg & XISF_SR_IS_READY_MASK) {
+ break;
+ }
+ }
+
+ return XST_SUCCESS;
+}
+
+/*****************************************************************************/
+/**
+*
+* This function is the handler which performs processing for the SPI 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 SPI data
+* completes or an error occurs.
+*
+* This handler provides an example of how to handle SPI interrupts and
+* is application specific.
+*
+* @param CallBackRef is the upper layer callback reference passed back
+* when the callback function is invoked.
+* @param StatusEvent is the event that just occurred.
+* @param ByteCount is the number of bytes transferred up until the event
+* occurred.
+*
+* @return None.
+*
+* @note None.
+*
+******************************************************************************/
+void SpiHandler(void *CallBackRef, u32 StatusEvent, u16 ByteCount)
+{
+ /*
+ * Indicate the transfer on the SPI bus is no longer in progress
+ * regardless of the status event.
+ */
+ TransferInProgress = FALSE;
+
+ /*
+ * If the event was not transfer done, then track it as an error.
+ */
+ if (StatusEvent != XST_SPI_TRANSFER_DONE) {
+ ErrorCount++;
+ }
+}
+
+/*****************************************************************************/
+/**
+*
+* This function setups the interrupt system such that interrupts can occur
+* for the Spi device. This function is application specific since the actual
+* system may or may not have an interrupt controller. The Spi device could be
+* directly connected to a processor without an interrupt controller. The
+* user should modify this function to fit the application.
+*
+* @param SpiPtr is a pointer to the instance of the Spi device.
+*
+* @return XST_SUCCESS if successful, otherwise XST_FAILURE.
+*
+* @note None
+*
+******************************************************************************/
+static int SetupInterruptSystem(XSpi *SpiPtr)
+{
+
+ int Status;
+
+ /*
+ * Initialize the interrupt controller driver so that it's ready to use,
+ * specify the device ID that is generated in xparameters.h
+ */
+ Status = XIntc_Initialize(&InterruptController, INTC_DEVICE_ID);
+ if(Status != XST_SUCCESS) {
+ return XST_FAILURE;
+ }
+
+ /*
+ * Connect a device driver handler that will be called when an interrupt
+ * for the device occurs, the device driver handler performs the
+ * specific interrupt processing for the device
+ */
+ Status = XIntc_Connect(&InterruptController,
+ SPI_INTR_ID,
+ (XInterruptHandler)XSpi_InterruptHandler,
+ (void *)SpiPtr);
+ if(Status != XST_SUCCESS) {
+ return XST_FAILURE;
+ }
+
+ /*
+ * Start the interrupt controller such that interrupts are enabled for
+ * all devices that cause interrupts, specify real mode so that the SPI
+ * can cause interrupts through the interrupt controller.
+ */
+ Status = XIntc_Start(&InterruptController, XIN_REAL_MODE);
+ if(Status != XST_SUCCESS) {
+ return XST_FAILURE;
+ }
+
+ /*
+ * Enable the interrupt for the SPI.
+ */
+ XIntc_Enable(&InterruptController, SPI_INTR_ID);
+
+ /*
+ * Initialize the exception table.
+ */
+ Xil_ExceptionInit();
+
+ /*
+ * Register the interrupt controller handler with the exception table.
+ */
+ Xil_ExceptionRegisterHandler(XIL_EXCEPTION_ID_INT,
+ (Xil_ExceptionHandler)XIntc_InterruptHandler,
+ &InterruptController);
+
+ /*
+ * Enable non-critical exceptions.
+ */
+ Xil_ExceptionEnable();
+
+ return XST_SUCCESS;
+}
diff --git a/lib/sw_services/xilisf/examples/xilisf_atmel_rdwr_polled_example.c b/lib/sw_services/xilisf/examples/xilisf_atmel_rdwr_polled_example.c
new file mode 100644
index 00000000..ec3d08a7
--- /dev/null
+++ b/lib/sw_services/xilisf/examples/xilisf_atmel_rdwr_polled_example.c
@@ -0,0 +1,331 @@
+/******************************************************************************
+*
+* Copyright (C) 2012 - 2014 Xilinx, Inc. All rights reserved.
+*
+* Permission is hereby granted, free of charge, to any person obtaining a copy
+* of this software and associated documentation files (the "Software"), to deal
+* in the Software without restriction, including without limitation the rights
+* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+* copies of the Software, and to permit persons to whom the Software is
+* furnished to do so, subject to the following conditions:
+*
+* The above copyright notice and this permission notice shall be included in
+* all copies or substantial portions of the Software.
+*
+* Use of the Software is limited solely to applications:
+* (a) running on a Xilinx device, or
+* (b) that interact with a Xilinx device through a bus or interconnect.
+*
+* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+* XILINX BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
+* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+* SOFTWARE.
+*
+* Except as contained in this notice, the name of the Xilinx shall not be used
+* in advertising or otherwise to promote the sale, use or other dealings in
+* this Software without prior written authorization from Xilinx.
+*
+******************************************************************************/
+/*****************************************************************************/
+/**
+* @file xilisf_atmel_rdwr_polled_example.c
+*
+* This file contains a design example using the In-system and Serial Flash
+* Library (XilIsf) with the Spi driver in polled mode of operation. This example
+* shows the Erase, Read and Write features.
+*
+* This example
+* - Erases a Page
+* - Writes to the erased Page
+* - Reads back the Page that is written and compares the data
+*
+* The example works for AT45DB011D/AT45DB021D/AT45DB041D/AT45DB081D Serial Flash
+* devices. The bytes per page (ISF_PAGE_SIZE) in these devices is
+* 264 for Default addressing mode and 256 in Power-of-2 addressing mode.
+*
+* For AT45DB161D/AT45DB321D devices the Bytes Per Page (ISF_PAGE_SIZE) is
+* 528 for Default addressing mode and 512 in Power-Of-2 addressing mode.
+*
+* For AT45DB642D device the Bytes Per Page (ISF_PAGE_SIZE) is 1056 for Default
+* addressing mode and 1024 in Power-Of-2 addressing mode.
+*
+* The ISF_PAGE_SIZE should be defined by the user according to the Device used.
+*
+* For further details of each device refer to the Spartan-3AN Serial Flash User
+* Guide and data sheets of Atmel AT45XXXD .
+*
+* This example has been tested with the In-System Flash Memory available on the
+* Spartan-3AN on a Xilinx Spartan-3AN Starter Kit board.
+*
+* @note
+*
+* None.
+*
+*
+* MODIFICATION HISTORY:
+*
+* Ver Who Date Changes
+* ----- --- -------- ---------------------------------------------------
+* 1.00a sdm 04/02/08 First release
+* 2.00a ktn 11/22/09 The Spi Driver APIs have changed. Replaced the call
+* to XSpi_mIntrGlobalDisable with XSpi_IntrGlobalDisable.
+*
+*
+******************************************************************************/
+
+/***************************** Include Files *********************************/
+
+#include "xparameters.h" /* EDK generated parameters */
+#include "xilisf.h" /* Serial Flash Library header file */
+
+/************************** Constant Definitions *****************************/
+
+/*
+ * The following constants map to the XPAR parameters created in the
+ * xparameters.h file. They are defined here such that a user can easily
+ * change all the needed parameters in one place.
+ */
+#define SPI_DEVICE_ID XPAR_SPI_0_DEVICE_ID
+
+/*
+ * The following constant defines the slave select signal that is used to
+ * select the Serial Flash device on the SPI bus, this signal is typically
+ * connected to the chip select of the device.
+ */
+#define ISF_SPI_SELECT 0x01
+
+/*
+ * Page size of the Serial Flash.
+ */
+#define ISF_PAGE_SIZE 264
+
+/*
+ * Address within the page of the Serial Flash to perform Erase, Write and Read
+ * operations.
+ */
+#define TEST_ADDRESS 0xA2400
+#define ISF_TEST_BYTE 0x20 /* Test Byte offset value written */
+
+/**************************** Type Definitions *******************************/
+
+/***************** Macros (Inline Functions) Definitions *********************/
+
+/************************** Function Prototypes ******************************/
+
+static int IsfWaitForFlashNotBusy();
+
+/************************** Variable Definitions *****************************/
+
+/*
+ * The instances to support the device drivers are global such that they
+ * are initialized to zero each time the program runs.
+ */
+static XIsf Isf;
+static XSpi Spi;
+
+/*
+ * The user needs to allocate a buffer to be used by the In-system and Serial
+ * Flash Library to perform any read/write operations on the Serial Flash
+ * device.
+ * User applications must pass the address of this memory to the Library in
+ * Serial Flash Initialization function, for the Library to work.
+ * For Write operations:
+ * - The size of this buffer should be equal to the Number of bytes to be
+ * written to the Serial Flash + XISF_CMD_MAX_EXTRA_BYTES.
+ * - The size of this buffer should be large enough for usage across all the
+ * applications that use a common instance of the Serial Flash.
+ * - A minimum of one byte and a maximum of ISF_PAGE_SIZE bytes can be written
+ * to the Serial Flash, through a single Write operation.
+ * The size of this buffer should be equal to XISF_CMD_MAX_EXTRA_BYTES, if the
+ * application only reads from the Serial Flash (no write operations).
+ */
+u8 IsfWriteBuffer[ISF_PAGE_SIZE + XISF_CMD_SEND_EXTRA_BYTES];
+
+/*
+ * Buffers used during read and write transactions.
+ */
+u8 ReadBuffer[ISF_PAGE_SIZE + XISF_CMD_SEND_EXTRA_BYTES] ; /* Read Buffer */
+u8 WriteBuffer[ISF_PAGE_SIZE]; /* Write buffer */
+
+/*****************************************************************************/
+/**
+*
+* Main function to execute the Atmel Serial Flash Read/Write polled example.
+*
+* @param None.
+*
+* @return XST_SUCCESS if successful else XST_FAILURE.
+*
+* @note None.
+*
+******************************************************************************/
+int main(void)
+{
+ int Status;
+ u16 Index;
+ XIsf_WriteParam WriteParam;
+ XIsf_ReadParam ReadParam;
+ u32 Address;
+
+ /*
+ * Initialize the SPI driver so that it's ready to use,
+ * specify the device ID that is generated in xparameters.h.
+ */
+ Status = XSpi_Initialize(&Spi, SPI_DEVICE_ID);
+ if(Status != XST_SUCCESS) {
+ return XST_FAILURE;
+ }
+
+ /*
+ * Start the SPI driver so that the device is enabled.
+ */
+ Status = XSpi_Start(&Spi);
+ if(Status != XST_SUCCESS) {
+ return XST_FAILURE;
+ }
+
+ /*
+ * Disable Global interrupt to use the Spi driver in polled mode
+ * operation.
+ */
+ XSpi_IntrGlobalDisable(&Spi);
+
+ /*
+ * Initialize the In-system and Serial Flash Library.
+ */
+ Status = XIsf_Initialize(&Isf, &Spi, ISF_SPI_SELECT, IsfWriteBuffer);
+ if(Status != XST_SUCCESS) {
+ return XST_FAILURE;
+ }
+
+ /*
+ * Specify the address in the Serial Flash for the Erase/Write/Read
+ * operations.
+ */
+ Address = TEST_ADDRESS;
+
+ /*
+ * Perform the Page Erase operation.
+ */
+ Status = XIsf_Erase(&Isf, XISF_PAGE_ERASE, Address);
+ if(Status != XST_SUCCESS) {
+ return XST_FAILURE;
+ }
+
+ /*
+ * Wait till the Serial Flash is ready.
+ */
+ Status = IsfWaitForFlashNotBusy();
+ if(Status != XST_SUCCESS) {
+ return XST_FAILURE;
+ }
+
+ /*
+ * Set the
+ * - Address within the Serial Flash where the data is to be written.
+ * - The number of bytes to be written to the Serial Flash.
+ * - Write Buffer which contains the data to be written to the Serial
+ * Flash.
+ */
+ WriteParam.Address = Address;
+ WriteParam.NumBytes = ISF_PAGE_SIZE;
+ WriteParam.WritePtr = WriteBuffer;
+
+ /*
+ * Prepare the write buffer. Fill in the data need to be written into
+ * Serial Flash.
+ */
+ for(Index = 0; Index < ISF_PAGE_SIZE; Index++) {
+ WriteParam.WritePtr[Index] = Index + ISF_TEST_BYTE;
+ }
+
+ /*
+ * Perform the Write operation.
+ */
+ Status = XIsf_Write(&Isf, XISF_WRITE, (void*) &WriteParam);
+ if(Status != XST_SUCCESS) {
+ return XST_FAILURE;
+ }
+
+ /*
+ * Wait till the Serial Flash is ready.
+ */
+ Status = IsfWaitForFlashNotBusy();
+ if(Status != XST_SUCCESS) {
+ return XST_FAILURE;
+ }
+
+ /*
+ * 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.
+ * - Read Buffer to which the data is to be read.
+ */
+ ReadParam.Address = Address;
+ ReadParam.NumBytes = ISF_PAGE_SIZE;
+ ReadParam.ReadPtr = ReadBuffer;
+
+ /*
+ * Perform the Read operation.
+ */
+ Status = XIsf_Read(&Isf, XISF_READ, (void*) &ReadParam);
+ if(Status != XST_SUCCESS) {
+ return XST_FAILURE;
+ }
+
+ /*
+ * Compare the Data Read with the Data Written to the Serial Flash.
+ */
+ for(Index = 0; Index < ISF_PAGE_SIZE; Index++) {
+ if(ReadParam.ReadPtr[Index + XISF_CMD_SEND_EXTRA_BYTES] !=
+ (u8)(Index + ISF_TEST_BYTE)) {
+ return XST_FAILURE;
+ }
+ }
+
+ return XST_SUCCESS;
+}
+
+/*****************************************************************************/
+/**
+*
+* This function waits till the Serial Flash is ready to accept next command.
+*
+* @param None
+*
+* @return XST_SUCCESS if successful else XST_FAILURE.
+*
+* @note None.
+*
+******************************************************************************/
+static int IsfWaitForFlashNotBusy()
+{
+ int Status;
+ u8 StatusReg;
+ u8 ReadBuffer[2];
+
+ while(1) {
+
+ /*
+ * Get the Status Register.
+ */
+ Status = XIsf_GetStatus(&Isf, ReadBuffer);
+ if(Status != XST_SUCCESS) {
+ return XST_FAILURE;
+ }
+
+ /*
+ * Check if the Serial Flash is ready to accept the next
+ * command. If so break.
+ */
+ StatusReg = ReadBuffer[BYTE2];
+ if(StatusReg & XISF_SR_IS_READY_MASK) {
+ break;
+ }
+ }
+
+ return XST_SUCCESS;
+}
diff --git a/lib/sw_services/xilisf/examples/xilisf_atmel_read_write_example.c b/lib/sw_services/xilisf/examples/xilisf_atmel_read_write_example.c
new file mode 100644
index 00000000..29460fa6
--- /dev/null
+++ b/lib/sw_services/xilisf/examples/xilisf_atmel_read_write_example.c
@@ -0,0 +1,515 @@
+/******************************************************************************
+*
+* Copyright (C) 2012 - 2014 Xilinx, Inc. All rights reserved.
+*
+* Permission is hereby granted, free of charge, to any person obtaining a copy
+* of this software and associated documentation files (the "Software"), to deal
+* in the Software without restriction, including without limitation the rights
+* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+* copies of the Software, and to permit persons to whom the Software is
+* furnished to do so, subject to the following conditions:
+*
+* The above copyright notice and this permission notice shall be included in
+* all copies or substantial portions of the Software.
+*
+* Use of the Software is limited solely to applications:
+* (a) running on a Xilinx device, or
+* (b) that interact with a Xilinx device through a bus or interconnect.
+*
+* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+* XILINX BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
+* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+* SOFTWARE.
+*
+* Except as contained in this notice, the name of the Xilinx shall not be used
+* in advertising or otherwise to promote the sale, use or other dealings in
+* this Software without prior written authorization from Xilinx.
+*
+******************************************************************************/
+/*****************************************************************************/
+/**
+* @file xilisf_atmel_read_write_example.c
+*
+* This file contains a design example using the In-system and Serial Flash
+* Library (XilIsf). This example shows the Erase, Read and Write features.
+*
+* This example
+* - Erases a Page
+* - Writes to the erased Page
+* - Reads back the Page that is written and compares the data.
+*
+* The example works for AT45DB011D/AT45DB021D/AT45DB041D/AT45DB081D Serial Flash
+* devices. The bytes per page (ISF_PAGE_SIZE) in these devices is
+* 264 for Default addressing mode and 256 in Power-of-2 addressing mode.
+*
+* For AT45DB161D/AT45DB321D devices the Bytes Per Page (ISF_PAGE_SIZE) is
+* 528 for Default addressing mode and 512 in Power-Of-2 addressing mode.
+*
+* For AT45DB642D device the Bytes Per Page (ISF_PAGE_SIZE) is 1056 for Default
+* addressing mode and 1024 in Power-Of-2 addressing mode.
+*
+* The ISF_PAGE_SIZE should be defined by the user according to the Device used.
+*
+* For further details of each device refer to the Spartan-3AN Serial Flash User
+* Guide and data sheets of Atmel AT45XXXD .
+*
+* This example has been tested with the In-System Flash Memory available on the
+* Spartan-3AN on a Xilinx Spartan-3AN Starter Kit board.
+*
+* @note
+*
+* None.
+*
+*
+* MODIFICATION HISTORY:
+*
+* Ver Who Date Changes
+* ----- ------- -------- ---------------------------------------------------
+* 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.
+*
+*
+******************************************************************************/
+
+/***************************** Include Files *********************************/
+
+#include "xparameters.h" /* EDK generated parameters */
+#include "xintc.h" /* Interrupt controller device driver */
+#include /* Serial Flash Library header file */
+#include "xil_exception.h"
+
+/************************** Constant Definitions *****************************/
+
+/*
+ * The following constants map to the XPAR parameters created in the
+ * xparameters.h file. They are defined here such that a user can easily
+ * change all the needed parameters in one place.
+ */
+#define SPI_DEVICE_ID XPAR_SPI_0_DEVICE_ID
+#define INTC_DEVICE_ID XPAR_INTC_0_DEVICE_ID
+#define SPI_INTR_ID XPAR_INTC_0_SPI_0_VEC_ID
+
+/*
+ * The following constant defines the slave select signal that is used to
+ * select the Serial Flash device on the SPI bus, this signal is typically
+ * connected to the chip select of the device.
+ */
+#define ISF_SPI_SELECT 0x01
+
+/*
+ * Page size of the Serial Flash.
+ */
+#define ISF_PAGE_SIZE 264
+
+/*
+ * Address within the page of the Serial Flash to perform Erase, Write and Read
+ * operations.
+ */
+#define TEST_ADDRESS 0xA2400
+#define ISF_TEST_BYTE 0x30 /* Test Byte offset value written */
+
+/**************************** Type Definitions *******************************/
+
+/***************** Macros (Inline Functions) Definitions *********************/
+
+/************************** Function Prototypes ******************************/
+
+static int IsfWaitForFlashNotBusy();
+
+static int SetupInterruptSystem(XSpi *SpiPtr);
+
+void SpiHandler(void *CallBackRef, u32 StatusEvent, u16 ByteCount);
+
+/************************** Variable Definitions *****************************/
+
+/*
+ * The instances to support the device drivers are global such that they
+ * are initialized to zero each time the program runs.
+ */
+static XIsf Isf;
+static XIntc InterruptController;
+static XSpi Spi;
+
+/*
+ * The following variables are shared between non-interrupt processing and
+ * interrupt processing such that they must be global.
+ */
+volatile static int TransferInProgress; /* State of Spi Transfer */
+static int ErrorCount; /* Errors occurred during Spi transfers */
+
+/*
+ * The user needs to allocate a buffer to be used by the In-system and Serial
+ * Flash Library to perform any read/write operations on the Serial Flash
+ * device.
+ * User applications must pass the address of this memory to the Library in
+ * Serial Flash Initialization function, for the Library to work.
+ * For Write operations:
+ * - The size of this buffer should be equal to the Number of bytes to be
+ * written to the Serial Flash + XISF_CMD_MAX_EXTRA_BYTES.
+ * - The size of this buffer should be large enough for usage across all the
+ * applications that use a common instance of the Serial Flash.
+ * - A minimum of one byte and a maximum of ISF_PAGE_SIZE bytes can be written
+ * to the Serial Flash, through a single Write operation.
+ * The size of this buffer should be equal to XISF_CMD_MAX_EXTRA_BYTES, if the
+ * application only reads from the Serial Flash (no write operations).
+ */
+u8 IsfWriteBuffer[ISF_PAGE_SIZE + XISF_CMD_SEND_EXTRA_BYTES];
+
+/*
+ * Buffers used during read and write transactions.
+ */
+u8 ReadBuffer[ISF_PAGE_SIZE + XISF_CMD_SEND_EXTRA_BYTES] ; /* Read Buffer */
+u8 WriteBuffer[ISF_PAGE_SIZE]; /* Write buffer */
+
+/*****************************************************************************/
+/**
+*
+* Main function to execute the Atmel Serial Flash Read/Write example.
+*
+* @param None.
+*
+* @return XST_SUCCESS if successful else XST_FAILURE.
+*
+* @note None.
+*
+******************************************************************************/
+int main(void)
+{
+ int Status;
+ u16 Index;
+ XIsf_WriteParam WriteParam;
+ XIsf_ReadParam ReadParam;
+ u32 Address;
+
+ /*
+ * Initialize the SPI driver so that it's ready to use,
+ * specify the device ID that is generated in xparameters.h.
+ */
+ Status = XSpi_Initialize(&Spi, SPI_DEVICE_ID);
+ if(Status != XST_SUCCESS) {
+ return XST_FAILURE;
+ }
+
+ /*
+ * Connect the SPI driver to the interrupt subsystem such that
+ * interrupts can occur. This function is application specific.
+ */
+ Status = SetupInterruptSystem(&Spi);
+ if(Status != XST_SUCCESS) {
+ return XST_FAILURE;
+ }
+
+ /*
+ * Setup the handler for the SPI that will be called from the interrupt
+ * context when an SPI status occurs, specify a pointer to the SPI
+ * driver instance as the callback reference so the handler is able to
+ * access the instance data.
+ */
+ XIsf_SetStatusHandler(&Isf, &Spi, (XSpi_StatusHandler)SpiHandler);
+
+ /*
+ * Start the SPI driver so that interrupts and the device are enabled.
+ */
+ Status = XSpi_Start(&Spi);
+ if(Status != XST_SUCCESS) {
+ return XST_FAILURE;
+ }
+
+ /*
+ * Initialize the In-system and Serial Flash Library.
+ */
+ Status = XIsf_Initialize(&Isf, &Spi, ISF_SPI_SELECT, IsfWriteBuffer);
+ if(Status != XST_SUCCESS) {
+ 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.
+ */
+ Address = TEST_ADDRESS;
+
+ /*
+ * Perform the Page Erase operation.
+ */
+ TransferInProgress = TRUE;
+ Status = XIsf_Erase(&Isf, XISF_PAGE_ERASE, Address);
+ if(Status != XST_SUCCESS) {
+ return XST_FAILURE;
+ }
+
+ /*
+ * Wait till the Transfer is complete and check for any errors.
+ */
+ while(TransferInProgress);
+ if(ErrorCount != 0) {
+ return XST_FAILURE;
+ }
+
+ /*
+ * Wait till the Serial Flash is ready.
+ */
+ Status = IsfWaitForFlashNotBusy();
+ if(Status != XST_SUCCESS) {
+ return XST_FAILURE;
+ }
+
+ /*
+ * Set the
+ * - Address within the Serial Flash where the data is to be written.
+ * - The number of bytes to be written to the Serial Flash.
+ * - Write Buffer which contains the data to be written to the Serial
+ * Flash.
+ */
+ WriteParam.Address = Address;
+ WriteParam.NumBytes = ISF_PAGE_SIZE;
+ WriteParam.WritePtr = WriteBuffer;
+
+ /*
+ * Prepare the write buffer. Fill in the data need to be written into
+ * Serial Flash.
+ */
+ for(Index = 0; Index < ISF_PAGE_SIZE; Index++) {
+ WriteParam.WritePtr[Index] = Index + ISF_TEST_BYTE;
+ }
+
+ /*
+ * Perform the Write operation.
+ */
+ TransferInProgress = TRUE;
+ Status = XIsf_Write(&Isf, XISF_WRITE, (void*) &WriteParam);
+ if(Status != XST_SUCCESS) {
+ return XST_FAILURE;
+ }
+
+ /*
+ * Wait till the Transfer is complete and check for any errors.
+ */
+ while(TransferInProgress);
+ if(ErrorCount != 0) {
+ return XST_FAILURE;
+ }
+
+ /*
+ * Wait till the Serial Flash is ready.
+ */
+ Status = IsfWaitForFlashNotBusy();
+ if(Status != XST_SUCCESS) {
+ return XST_FAILURE;
+ }
+
+ /*
+ * 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.
+ * - Read Buffer to which the data is to be read.
+ */
+ ReadParam.Address = Address;
+ ReadParam.NumBytes = ISF_PAGE_SIZE;
+ ReadParam.ReadPtr = ReadBuffer;
+
+ /*
+ * Perform the Read operation.
+ */
+ TransferInProgress = TRUE;
+ Status = XIsf_Read(&Isf, XISF_READ, (void*) &ReadParam);
+ if(Status != XST_SUCCESS) {
+ return XST_FAILURE;
+ }
+
+ /*
+ * Wait till the Transfer is complete and check for any errors.
+ */
+ while(TransferInProgress);
+ if(ErrorCount != 0) {
+ return XST_FAILURE;
+ }
+
+ /*
+ * Compare the Data Read with the Data Written to the Serial Flash.
+ */
+ for(Index = 0; Index < ISF_PAGE_SIZE; Index++) {
+ if(ReadParam.ReadPtr[Index + XISF_CMD_SEND_EXTRA_BYTES] !=
+ (u8)(Index + ISF_TEST_BYTE)) {
+ return XST_FAILURE;
+ }
+ }
+
+ return XST_SUCCESS;
+}
+
+/*****************************************************************************/
+/**
+*
+* This function waits till the Serial Flash is ready to accept next command.
+*
+* @param None
+*
+* @return XST_SUCCESS if successful else XST_FAILURE.
+*
+* @note None.
+*
+******************************************************************************/
+static int IsfWaitForFlashNotBusy()
+{
+ int Status;
+ u8 StatusReg;
+ u8 ReadBuffer[2];
+
+ 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 complete and check for any errors.
+ */
+ while(TransferInProgress);
+ if(ErrorCount != 0) {
+ return XST_FAILURE;
+ }
+
+ /*
+ * Check if the Serial Flash is ready to accept the next
+ * command. If so break.
+ */
+ StatusReg = ReadBuffer[BYTE2];
+ if(StatusReg & XISF_SR_IS_READY_MASK) {
+ break;
+ }
+ }
+
+ return XST_SUCCESS;
+}
+
+/*****************************************************************************/
+/**
+*
+* This function is the handler which performs processing for the SPI 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 SPI data
+* completes or an error occurs.
+*
+* This handler provides an example of how to handle SPI interrupts and
+* is application specific.
+*
+* @param CallBackRef is the upper layer callback reference passed back
+* when the callback function is invoked.
+* @param StatusEvent is the event that just occurred.
+* @param ByteCount is the number of bytes transferred up until the event
+* occurred.
+*
+* @return None.
+*
+* @note None.
+*
+******************************************************************************/
+void SpiHandler(void *CallBackRef, u32 StatusEvent, u16 ByteCount)
+{
+ /*
+ * Indicate the transfer on the SPI bus is no longer in progress
+ * regardless of the status event.
+ */
+ TransferInProgress = FALSE;
+
+ /*
+ * If the event was not transfer done, then track it as an error.
+ */
+ if (StatusEvent != XST_SPI_TRANSFER_DONE) {
+ ErrorCount++;
+ }
+}
+
+/*****************************************************************************/
+/**
+*
+* This function setups the interrupt system such that interrupts can occur
+* for the Spi device. This function is application specific since the actual
+* system may or may not have an interrupt controller. The Spi device could be
+* directly connected to a processor without an interrupt controller. The
+* user should modify this function to fit the application.
+*
+* @param SpiPtr is a pointer to the instance of the Spi device.
+*
+* @return XST_SUCCESS if successful, otherwise XST_FAILURE.
+*
+* @note None
+*
+******************************************************************************/
+static int SetupInterruptSystem(XSpi *SpiPtr)
+{
+
+ int Status;
+
+ /*
+ * Initialize the interrupt controller driver so that it's ready to use
+ * specify the device ID that is generated in xparameters.h.
+ */
+ Status = XIntc_Initialize(&InterruptController, INTC_DEVICE_ID);
+ if(Status != XST_SUCCESS) {
+ return XST_FAILURE;
+ }
+
+ /*
+ * Connect a device driver handler that will be called when an interrupt
+ * for the device occurs, the device driver handler performs the
+ * specific interrupt processing for the device.
+ */
+ Status = XIntc_Connect(&InterruptController,
+ SPI_INTR_ID,
+ (XInterruptHandler)XSpi_InterruptHandler,
+ (void *)SpiPtr);
+ if(Status != XST_SUCCESS) {
+ return XST_FAILURE;
+ }
+
+ /*
+ * Start the interrupt controller such that interrupts are enabled for
+ * all devices that cause interrupts, specify real mode so that the SPI
+ * can cause interrupts through the interrupt controller.
+ */
+ Status = XIntc_Start(&InterruptController, XIN_REAL_MODE);
+ if(Status != XST_SUCCESS) {
+ return XST_FAILURE;
+ }
+
+ /*
+ * Enable the interrupt for the SPI.
+ */
+ XIntc_Enable(&InterruptController, SPI_INTR_ID);
+
+ /*
+ * Initialize the exception table.
+ */
+ Xil_ExceptionInit();
+
+ /*
+ * Register the interrupt controller handler with the exception table.
+ */
+ Xil_ExceptionRegisterHandler(XIL_EXCEPTION_ID_INT,
+ (Xil_ExceptionHandler)XIntc_InterruptHandler,
+ &InterruptController);
+
+ /*
+ * Enable non-critical exceptions.
+ */
+ Xil_ExceptionEnable();
+
+ return XST_SUCCESS;
+}
diff --git a/lib/sw_services/xilisf/examples/xilisf_atmel_spr_example.c b/lib/sw_services/xilisf/examples/xilisf_atmel_spr_example.c
new file mode 100644
index 00000000..76238d59
--- /dev/null
+++ b/lib/sw_services/xilisf/examples/xilisf_atmel_spr_example.c
@@ -0,0 +1,786 @@
+/******************************************************************************
+*
+* Copyright (C) 2012 - 2014 Xilinx, Inc. All rights reserved.
+*
+* Permission is hereby granted, free of charge, to any person obtaining a copy
+* of this software and associated documentation files (the "Software"), to deal
+* in the Software without restriction, including without limitation the rights
+* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+* copies of the Software, and to permit persons to whom the Software is
+* furnished to do so, subject to the following conditions:
+*
+* The above copyright notice and this permission notice shall be included in
+* all copies or substantial portions of the Software.
+*
+* Use of the Software is limited solely to applications:
+* (a) running on a Xilinx device, or
+* (b) that interact with a Xilinx device through a bus or interconnect.
+*
+* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+* XILINX BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
+* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+* SOFTWARE.
+*
+* Except as contained in this notice, the name of the Xilinx shall not be used
+* in advertising or otherwise to promote the sale, use or other dealings in
+* this Software without prior written authorization from Xilinx.
+*
+******************************************************************************/
+/*****************************************************************************/
+/**
+* @file xilisf_atmel_spr_example.c
+*
+*
+* This file contains a design example using the In-system and Serial Flash
+* Library (XilIsf). This example shows all the features related to Sector
+* Protection.
+*
+* This example
+* - Writes to the Sector Protection Register
+* - Reads the Sector Protection Register and compares with the data that was
+* written
+* - Erases the Sector Protection Register
+* - Erases a Page and writes the data to the Page
+* - Enables the Sector Protection so that all the sectors are Write protected
+* - Erases a Page (This should not happen as the Sectors are Write protected
+* - Reads back the Page that is written and compares the data.
+*
+* The example works for AT45DB011D/AT45DB021D/AT45DB041D/AT45DB081D Serial Flash
+* devices. The bytes per page (ISF_PAGE_SIZE) in these devices is
+* 264 for Default addressing mode and 256 in Power-of-2 addressing mode.
+*
+* For AT45DB161D/AT45DB321D devices the Bytes Per Page (ISF_PAGE_SIZE) is
+* 528 for Default addressing mode and 512 in Power-Of-2 addressing mode.
+*
+* For AT45DB642D device the Bytes Per Page (ISF_PAGE_SIZE) is 1056 for Default
+* addressing mode and 1024 in Power-Of-2 addressing mode.
+*
+* The ISF_PAGE_SIZE should be defined by the user according to the Device used.
+*
+* For further details of each device refer to the Spartan-3AN Serial Flash User
+* Guide and data sheets of Atmel AT45XXXD .
+*
+* This example has been tested with the In-System Flash Memory available on the
+* Spartan-3AN on a Xilinx Spartan-3AN Starter Kit board.
+*
+* @note
+*
+* None.
+*
+*
+* MODIFICATION HISTORY:
+*
+* Ver Who Date Changes
+* ----- ------- -------- -----------------------------------------------------
+* 1.00a mta/ksu 03/20/08 First release
+* 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.
+*
+******************************************************************************/
+
+/***************************** Include Files *********************************/
+
+#include "xparameters.h" /* EDK generated parameters */
+#include "xintc.h" /* Interrupt controller device driver */
+#include /* Serial Flash Library header file */
+#include "xil_exception.h"
+
+/************************** Constant Definitions *****************************/
+
+/*
+ * The following constants map to the XPAR parameters created in the
+ * xparameters.h file. They are defined here such that a user can easily
+ * change all the needed parameters in one place.
+ */
+#define SPI_DEVICE_ID XPAR_SPI_0_DEVICE_ID
+#define INTC_DEVICE_ID XPAR_INTC_0_DEVICE_ID
+#define SPI_INTR_ID XPAR_INTC_0_SPI_0_VEC_ID
+
+/*
+ * The following constant defines the slave select signal that is used to
+ * select the Serial Flash device on the SPI bus, this signal is typically
+ * connected to the chip select of the device.
+ */
+#define ISF_SPI_SELECT 0x01
+
+/*
+ * Page size of the Serial Flash.
+ */
+#define ISF_PAGE_SIZE 264
+
+/*
+ * Address within the page of the Serial Flash to perform Erase, Write and Read
+ * operations.
+ */
+#define TEST_ADDRESS 0xA2400
+#define ISF_TEST_BYTE 0x36 /* Test Byte offset value */
+
+/**************************** Type Definitions *******************************/
+
+/***************** Macros (Inline Functions) Definitions *********************/
+
+/************************** Function Prototypes ******************************/
+
+static int IsfWaitForFlashNotBusy();
+
+static int SetupInterruptSystem(XSpi *SpiPtr);
+
+void SpiHandler(void *CallBackRef, u32 StatusEvent, u16 ByteCount);
+
+/************************** Variable Definitions *****************************/
+
+/*
+ * The instances to support the device drivers are global such that they
+ * are initialized to zero each time the program runs.
+ */
+static XIsf Isf;
+static XIntc InterruptController;
+static XSpi Spi;
+
+/*
+ * The following variables are shared between non-interrupt processing and
+ * interrupt processing such that they must be global.
+ */
+volatile static int TransferInProgress; /* State of Spi Transfer */
+static int ErrorCount; /* Errors occurred during Spi transfers */
+
+/*
+ * The user needs to allocate a buffer to be used by the In-system and Serial
+ * Flash Library to perform any read/write operations on the Serial Flash
+ * device.
+ * User applications must pass the address of this memory to the Library in
+ * Serial Flash Initialization function, for the Library to work.
+ * For Write operations:
+ * - The size of this buffer should be equal to the Number of bytes to be
+ * written to the Serial Flash + XISF_CMD_MAX_EXTRA_BYTES.
+ * - The size of this buffer should be large enough for usage across all the
+ * applications that use a common instance of the Serial Flash.
+ * - A minimum of one byte and a maximum of ISF_PAGE_SIZE bytes can be written
+ * to the Serial Flash, through a single Write operation.
+ * The size of this buffer should be equal to XISF_CMD_MAX_EXTRA_BYTES, if the
+ * application only reads from the Serial Flash (no write operations).
+ */
+u8 IsfWriteBuffer[ISF_PAGE_SIZE + XISF_CMD_SEND_EXTRA_BYTES];
+
+/*
+ * Buffers used during read and write transactions.
+ */
+u8 ReadBuffer[ISF_PAGE_SIZE + XISF_CMD_SEND_EXTRA_BYTES] ; /* Read Buffer. */
+u8 WriteBuffer[ISF_PAGE_SIZE]; /* Write buffer. */
+
+/*****************************************************************************/
+/**
+*
+* Main function to execute the Atmel Serial Flash SPR example.
+*
+* @param None
+*
+* @return XST_SUCCESS if successful else XST_FAILURE.
+*
+* @note None
+*
+******************************************************************************/
+int main(void)
+{
+ int Status;
+ u16 Index;
+ XIsf_WriteParam WriteParam;
+ XIsf_ReadParam ReadParam;
+
+ /*
+ * Initialize the SPI driver so that it's ready to use,
+ * specify the device ID that is generated in xparameters.h.
+ */
+ Status = XSpi_Initialize(&Spi, SPI_DEVICE_ID);
+ if(Status != XST_SUCCESS) {
+ return XST_FAILURE;
+ }
+
+ /*
+ * Connect the SPI driver to the interrupt subsystem such that
+ * interrupts can occur. This function is application specific.
+ */
+ Status = SetupInterruptSystem(&Spi);
+ if(Status != XST_SUCCESS) {
+ return XST_FAILURE;
+ }
+
+ /*
+ * Setup the handler for the SPI that will be called from the interrupt
+ * context when an SPI status occurs, specify a pointer to the SPI
+ * driver instance as the callback reference so the handler is able to
+ * access the instance data.
+ */
+ XIsf_SetStatusHandler(&Isf, &Spi, (XSpi_StatusHandler)SpiHandler);
+
+ /*
+ * Start the SPI driver so that interrupts and the device are enabled.
+ */
+ Status = XSpi_Start(&Spi);
+ if(Status != XST_SUCCESS) {
+ return XST_FAILURE;
+ }
+
+ /*
+ * Initialize the In-system and Serial Flash Library.
+ */
+ Status = XIsf_Initialize(&Isf, &Spi, ISF_SPI_SELECT, IsfWriteBuffer);
+ if(Status != XST_SUCCESS) {
+ return XST_FAILURE;
+ }
+
+ /*
+ * Set The transfer Mode to Interrupt
+ */
+ XIsf_SetTransferMode(&Isf,XISF_INTERRUPT_MODE);
+
+ /*
+ * Perform the SPR erase operation.
+ */
+ TransferInProgress = TRUE;
+ Status = XIsf_SectorProtect(&Isf, XISF_SPR_ERASE, NULL);
+ if(Status != XST_SUCCESS) {
+ return XST_FAILURE;
+ }
+
+ /*
+ * Wait till the Transfer is complete and check for any errors.
+ */
+ while(TransferInProgress);
+ if(ErrorCount != 0) {
+ return XST_FAILURE;
+ }
+
+ /*
+ * Wait till the Serial Flash is ready.
+ */
+ Status = IsfWaitForFlashNotBusy();
+ if(Status != XST_SUCCESS) {
+ return XST_FAILURE;
+ }
+
+ /*
+ * Perform the SPR read operation.
+ */
+ TransferInProgress = TRUE;
+ Status = XIsf_SectorProtect(&Isf, XISF_SPR_READ, ReadBuffer);
+ if(Status != XST_SUCCESS) {
+ return XST_FAILURE;
+ }
+
+ /*
+ * Wait till the Transfer is complete and check for any errors.
+ */
+ while(TransferInProgress);
+ if(ErrorCount != 0) {
+ return XST_FAILURE;
+ }
+
+ /*
+ * Compare the values read back from the SPR with the values written
+ * during SPR erase operation. Return if error.
+ */
+ for(Index = 0; Index < Isf.NumOfSectors; Index++) {
+ if((ReadBuffer[Index + XISF_CMD_SEND_EXTRA_BYTES] & 0xFF) !=
+ 0xFF) {
+ return XST_FAILURE;
+ }
+ }
+
+ /*
+ * Prepare the values to be written to the Sector Protect Register
+ * (SPR).
+ */
+ for(Index = 0; Index < Isf.NumOfSectors; Index++) {
+ WriteBuffer[Index] = 0x00;
+ }
+
+ /*
+ * Perform the SPR write operation.
+ */
+ TransferInProgress = TRUE;
+ Status = XIsf_SectorProtect(&Isf, XISF_SPR_WRITE, WriteBuffer);
+ if(Status != XST_SUCCESS) {
+ return XST_FAILURE;
+ }
+
+ /*
+ * Wait till the Transfer is complete and check for any errors.
+ */
+ while(TransferInProgress);
+ if(ErrorCount != 0) {
+ return XST_FAILURE;
+ }
+
+ /*
+ * Wait till the Serial Flash is ready.
+ */
+ Status = IsfWaitForFlashNotBusy();
+ if(Status != XST_SUCCESS) {
+ return XST_FAILURE;
+ }
+
+ /*
+ * Perform the SPR read operation.
+ */
+ TransferInProgress = TRUE;
+ Status = XIsf_SectorProtect(&Isf, XISF_SPR_READ, ReadBuffer);
+ if(Status != XST_SUCCESS) {
+ return XST_FAILURE;
+ }
+
+ /*
+ * Wait till the Transfer is complete and check for any errors.
+ */
+ while(TransferInProgress);
+ if(ErrorCount != 0) {
+ return XST_FAILURE;
+ }
+
+ /*
+ * Compare the values read back from the SPR with the values written
+ * during SPR write operation. Return if error.
+ */
+ for(Index = 0; Index < Isf.NumOfSectors; Index++) {
+ if(ReadBuffer[Index + XISF_CMD_SEND_EXTRA_BYTES] != 0x00) {
+ return XST_FAILURE;
+ }
+ }
+
+ /*
+ * Perform the SPR erase operation.
+ */
+ TransferInProgress = TRUE;
+ Status = XIsf_SectorProtect(&Isf, XISF_SPR_ERASE, NULL);
+ if(Status != XST_SUCCESS) {
+ return XST_FAILURE;
+ }
+
+ /*
+ * Wait till the Transfer is complete and check for any errors.
+ */
+ while(TransferInProgress);
+ if(ErrorCount != 0) {
+ ErrorCount = 0;
+ return XST_FAILURE;
+ }
+
+ /*
+ * Wait till the Serial Flash is ready.
+ */
+ Status = IsfWaitForFlashNotBusy();
+ if(Status != XST_SUCCESS) {
+ return XST_FAILURE;
+ }
+
+ /*
+ * Perform the SPR read operation.
+ */
+ TransferInProgress = TRUE;
+ Status = XIsf_SectorProtect(&Isf, XISF_SPR_READ, ReadBuffer);
+ if(Status != XST_SUCCESS) {
+ return XST_FAILURE;
+ }
+
+ /*
+ * Wait till the Transfer is complete and check for any errors.
+ */
+ while(TransferInProgress);
+ if(ErrorCount != 0) {
+ return XST_FAILURE;
+ }
+
+ /*
+ * Check if the values read from the SPR, are all 0xFF after performing
+ * the SPR erase operation.
+ */
+ for(Index = XISF_CMD_SEND_EXTRA_BYTES; Index < (Isf.NumOfSectors +
+ XISF_CMD_SEND_EXTRA_BYTES); Index++) {
+ if(ReadBuffer[Index] != 0xFF) {
+ return XST_FAILURE;
+ }
+ }
+
+ /*
+ * Perform the SP disable operation.
+ */
+ TransferInProgress = TRUE;
+ Status = XIsf_SectorProtect(&Isf, XISF_SP_DISABLE, NULL);
+ if(Status != XST_SUCCESS) {
+ return XST_FAILURE;
+ }
+
+ /*
+ * Wait till the Transfer is complete and check for any errors.
+ */
+ while(TransferInProgress);
+ if(ErrorCount != 0) {
+ return XST_FAILURE;
+ }
+
+ /*
+ * Wait till the Serial Flash is ready.
+ */
+ Status = IsfWaitForFlashNotBusy();
+ if(Status != XST_SUCCESS) {
+ return XST_FAILURE;
+ }
+
+ /*
+ * Perform the Page Erase operation.
+ */
+ TransferInProgress = TRUE;
+ Status = XIsf_Erase(&Isf, XISF_PAGE_ERASE, TEST_ADDRESS);
+ if(Status != XST_SUCCESS) {
+ return XST_FAILURE;
+ }
+
+ /*
+ * Wait till the Transfer is complete and check for any errors.
+ */
+ while(TransferInProgress);
+ if(ErrorCount != 0) {
+ return XST_FAILURE;
+ }
+
+ /*
+ * Wait till the Serial Flash is ready.
+ */
+ Status = IsfWaitForFlashNotBusy();
+ if(Status != XST_SUCCESS) {
+ return XST_FAILURE;
+ }
+
+ /*
+ * Set the
+ * - Address within the Serial Flash where the data is to be written.
+ * - The number of bytes to be written to the Serial Flash.
+ * - Write Buffer which contains the data to be written to the Serial
+ * Flash.
+ */
+ WriteParam.Address = TEST_ADDRESS;
+ WriteParam.NumBytes = ISF_PAGE_SIZE;
+ WriteParam.WritePtr = WriteBuffer;
+
+ /*
+ * Prepare the write buffer. Fill in the data need to be written into
+ * Serial Flash.
+ */
+ for(Index = 0; Index < ISF_PAGE_SIZE; Index++) {
+ WriteParam.WritePtr[Index] = Index + ISF_TEST_BYTE;
+ }
+
+ /*
+ * Perform the Write operation.
+ */
+ TransferInProgress = TRUE;
+ Status = XIsf_Write(&Isf, XISF_WRITE, (void*) &WriteParam);
+ if(Status != XST_SUCCESS) {
+ return XST_FAILURE;
+ }
+
+ /*
+ * Wait till the Transfer is complete and check for any errors.
+ */
+ while(TransferInProgress);
+ if(ErrorCount != 0) {
+ return XST_FAILURE;
+ }
+
+ /*
+ * Wait till the Serial Flash is ready.
+ */
+ Status = IsfWaitForFlashNotBusy();
+ if(Status != XST_SUCCESS) {
+ return XST_FAILURE;
+ }
+
+ /*
+ * Perform the SP enable operation. This should enable protection for
+ * all sectors since a SP erase operation has been performed earlier.
+ */
+ TransferInProgress = TRUE;
+ Status = XIsf_SectorProtect(&Isf, XISF_SP_ENABLE, NULL);
+ if(Status != XST_SUCCESS) {
+ return XST_FAILURE;
+ }
+
+ /*
+ * Wait till the Transfer is complete and check for any errors.
+ */
+ while(TransferInProgress);
+ if(ErrorCount != 0) {
+ return XST_FAILURE;
+ }
+
+ /*
+ * Wait till the Serial Flash is ready.
+ */
+ Status = IsfWaitForFlashNotBusy();
+ if(Status != XST_SUCCESS) {
+ return XST_FAILURE;
+ }
+
+ /*
+ * Perform the Page Erase operation. The Page Erase operation should not
+ * work since SP is enabled.
+ */
+ TransferInProgress = TRUE;
+ Status = XIsf_Erase(&Isf, XISF_PAGE_ERASE, TEST_ADDRESS);
+ if(Status != XST_SUCCESS) {
+ return XST_FAILURE;
+ }
+
+ /*
+ * Wait till the Transfer is complete and check for any errors.
+ */
+ while(TransferInProgress);
+ if(ErrorCount != 0) {
+ return XST_FAILURE;
+ }
+
+ /*
+ * Wait till the Serial Flash is ready.
+ */
+ Status = IsfWaitForFlashNotBusy();
+ if(Status != XST_SUCCESS) {
+ return XST_FAILURE;
+ }
+
+ /*
+ * Perform the SP disable operation.
+ */
+ TransferInProgress = TRUE;
+ Status = XIsf_SectorProtect(&Isf, XISF_SP_DISABLE, NULL);
+ if(Status != XST_SUCCESS) {
+ return XST_FAILURE;
+ }
+
+ /*
+ * Wait till the Transfer is complete and check for any errors.
+ */
+ while(TransferInProgress);
+ if(ErrorCount != 0) {
+ return XST_FAILURE;
+ }
+
+ /*
+ * Wait till the Serial Flash is ready.
+ */
+ Status = IsfWaitForFlashNotBusy();
+ if(Status != XST_SUCCESS) {
+ return XST_FAILURE;
+ }
+
+ /*
+ * 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.
+ * - Read Buffer to which the data is to be read.
+ */
+ ReadParam.Address = TEST_ADDRESS;
+ ReadParam.NumBytes = ISF_PAGE_SIZE;
+ ReadParam.ReadPtr = ReadBuffer;
+
+ /*
+ * Perform the read operation. The values read should be same as the
+ * values written earlier.
+ */
+ TransferInProgress = TRUE;
+ Status = XIsf_Read(&Isf, XISF_READ, (void*) &ReadParam);
+ if(Status != XST_SUCCESS) {
+ return XST_FAILURE;
+ }
+
+ /*
+ * Wait till the Transfer is complete and check for any errors.
+ */
+ while(TransferInProgress);
+ if(ErrorCount != 0) {
+ return XST_FAILURE;
+ }
+
+ /*
+ * Compare the data read against the data written.
+ */
+ for(Index = 0; Index < ISF_PAGE_SIZE; Index++) {
+ if(ReadParam.ReadPtr[Index + XISF_CMD_SEND_EXTRA_BYTES] !=
+ (u8)(Index + ISF_TEST_BYTE)) {
+ return XST_FAILURE;
+ }
+ }
+
+ return XST_SUCCESS;
+}
+
+/*****************************************************************************/
+/**
+*
+* This function waits till the Serial Flash is ready to accept next command.
+*
+* @param None
+*
+* @return XST_SUCCESS if successful else XST_FAILURE.
+*
+* @note None.
+*
+******************************************************************************/
+static int IsfWaitForFlashNotBusy()
+{
+ int Status;
+ u8 StatusReg;
+ u8 ReadBuffer[2];
+
+ 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 complete and check for any errors.
+ */
+ while(TransferInProgress);
+ if(ErrorCount != 0) {
+ return XST_FAILURE;
+ }
+
+ /*
+ * Check if the Serial Flash is ready to accept the next
+ * command. If so break.
+ */
+ StatusReg = ReadBuffer[BYTE2];
+ if(StatusReg & XISF_SR_IS_READY_MASK) {
+ break;
+ }
+ }
+
+ return XST_SUCCESS;
+}
+
+/*****************************************************************************/
+/**
+*
+* This function is the handler which performs processing for the SPI 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 SPI data
+* completes or an error occurs.
+*
+* This handler provides an example of how to handle SPI interrupts and
+* is application specific.
+*
+* @param CallBackRef is the upper layer callback reference passed back
+* when the callback function is invoked.
+* @param StatusEvent is the event that just occurred.
+* @param ByteCount is the number of bytes transferred up until the event
+* occurred.
+*
+* @return None.
+*
+* @note None.
+*
+******************************************************************************/
+void SpiHandler(void *CallBackRef, u32 StatusEvent, u16 ByteCount)
+{
+ /*
+ * Indicate the transfer on the SPI bus is no longer in progress
+ * regardless of the status event.
+ */
+ TransferInProgress = FALSE;
+
+ /*
+ * If the event was not transfer done, then track it as an error.
+ */
+ if (StatusEvent != XST_SPI_TRANSFER_DONE) {
+ ErrorCount++;
+ }
+}
+
+/*****************************************************************************/
+/**
+*
+* This function setups the interrupt system such that interrupts can occur
+* for the Spi device. This function is application specific since the actual
+* system may or may not have an interrupt controller. The Spi device could be
+* directly connected to a processor without an interrupt controller. The
+* user should modify this function to fit the application.
+*
+* @param SpiPtr is a pointer to the instance of the Spi device.
+*
+* @return XST_SUCCESS if successful, otherwise XST_FAILURE.
+*
+* @note None
+*
+******************************************************************************/
+static int SetupInterruptSystem(XSpi *SpiPtr)
+{
+
+ int Status;
+
+ /*
+ * Initialize the interrupt controller driver so that it's ready to use
+ * specify the device ID that is generated in xparameters.h
+ */
+ Status = XIntc_Initialize(&InterruptController, INTC_DEVICE_ID);
+ if(Status != XST_SUCCESS) {
+ return XST_FAILURE;
+ }
+
+ /*
+ * Connect a device driver handler that will be called when an interrupt
+ * for the device occurs, the device driver handler performs the
+ * specific interrupt processing for the device
+ */
+ Status = XIntc_Connect(&InterruptController,
+ SPI_INTR_ID,
+ (XInterruptHandler)XSpi_InterruptHandler,
+ (void *)SpiPtr);
+ if(Status != XST_SUCCESS) {
+ return XST_FAILURE;
+ }
+
+ /*
+ * Start the interrupt controller such that interrupts are enabled for
+ * all devices that cause interrupts, specific real mode so that the SPI
+ * can cause interrupts thru the interrupt controller.
+ */
+ Status = XIntc_Start(&InterruptController, XIN_REAL_MODE);
+ if(Status != XST_SUCCESS) {
+ return XST_FAILURE;
+ }
+
+ /*
+ * Enable the interrupt for the SPI.
+ */
+ XIntc_Enable(&InterruptController, SPI_INTR_ID);
+
+ /*
+ * Initialize the exception table.
+ */
+ Xil_ExceptionInit();
+
+ /*
+ * Register the interrupt controller handler with the exception table.
+ */
+ Xil_ExceptionRegisterHandler(XIL_EXCEPTION_ID_INT,
+ (Xil_ExceptionHandler)XIntc_InterruptHandler,
+ &InterruptController);
+
+ /*
+ * Enable non-critical exceptions.
+ */
+ Xil_ExceptionEnable();
+
+ return XST_SUCCESS;
+}
diff --git a/lib/sw_services/xilisf/examples/xilisf_intel_otp_rdwr_example.c b/lib/sw_services/xilisf/examples/xilisf_intel_otp_rdwr_example.c
new file mode 100644
index 00000000..e737cf8b
--- /dev/null
+++ b/lib/sw_services/xilisf/examples/xilisf_intel_otp_rdwr_example.c
@@ -0,0 +1,511 @@
+/******************************************************************************
+*
+* Copyright (C) 2012 - 2014 Xilinx, Inc. All rights reserved.
+*
+* Permission is hereby granted, free of charge, to any person obtaining a copy
+* of this software and associated documentation files (the "Software"), to deal
+* in the Software without restriction, including without limitation the rights
+* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+* copies of the Software, and to permit persons to whom the Software is
+* furnished to do so, subject to the following conditions:
+*
+* The above copyright notice and this permission notice shall be included in
+* all copies or substantial portions of the Software.
+*
+* Use of the Software is limited solely to applications:
+* (a) running on a Xilinx device, or
+* (b) that interact with a Xilinx device through a bus or interconnect.
+*
+* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+* XILINX BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
+* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+* SOFTWARE.
+*
+* Except as contained in this notice, the name of the Xilinx shall not be used
+* in advertising or otherwise to promote the sale, use or other dealings in
+* this Software without prior written authorization from Xilinx.
+*
+******************************************************************************/
+/******************************************************************************
+*
+* @file xilisf_intel_otp_rdwr_example.c
+*
+* This file contains a design example using the Xilinx In-system and Serial
+* Flash Library (XilIsf). This example shows the One-Time Programmable (OTP)
+* Read/Write features.
+*
+* This example
+* - Writes a Byte to OTP region
+* - Reads back the Byte written to the OTP region and compares the data
+*
+* This example has been tested with Intel (Numonyx) Serial Flash Memory (S33)
+* on a S3A-DSP starter kit. For further details about the S33 Flash device refer
+* to the Intel (Numonyx) Serial Flash Memory (S33) Data sheets.
+*
+*
+* @note
+*
+*
+* None.
+*
+*
+* MODIFICATION HISTORY:
+*
+* Ver Who Date Changes
+* ----- ---- -------- -----------------------------------------------
+* 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.
+*
+*
+******************************************************************************/
+
+/***************************** Include Files *********************************/
+
+#include "xparameters.h" /* EDK generated parameters */
+#include "xintc.h" /* Interrupt controller device driver */
+#include /* Serial Flash Library header file */
+#include "xil_exception.h"
+
+/************************** Constant Definitions *****************************/
+
+
+/*
+ * The following constants map to the XPAR parameters created in the
+ * xparameters.h file. They are defined here such that a user can easily
+ * change all the needed parameters in one place.
+ */
+#define SPI_DEVICE_ID XPAR_SPI_0_DEVICE_ID
+#define INTC_DEVICE_ID XPAR_INTC_0_DEVICE_ID
+#define SPI_INTR_ID XPAR_INTC_0_SPI_0_VEC_ID
+
+/*
+ * The following constant defines the slave select signal that is used to
+ * to select the Flash device on the SPI bus, this signal is typically
+ * connected to the chip select of the device.
+ */
+#define ISF_SPI_SELECT 0x01
+
+/*
+ * Number of bytes to be written to the OTP area of the Serial Flash.
+ */
+#define ISF_OTP_WRITE_SIZE 256
+
+/*
+ * Address of the page to perform Erase, Write and Read operations.
+ */
+#define ISF_OTP_TEST_ADDRESS 0x0225;
+#define ISF_TEST_BYTE 0x30 /* Test Byte offset value written */
+
+/**************************** Type Definitions *******************************/
+
+/***************** Macros (Inline Functions) Definitions *********************/
+
+/************************** Function Prototypes ******************************/
+
+static int IsfWaitForFlashNotBusy(void);
+void SpiHandler(void *CallBackRef, u32 StatusEvent, u16 ByteCount);
+static int SetupInterruptSystem(XSpi *SpiPtr);
+
+/************************** 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.
+ */
+static XIsf Isf;
+static XIntc InterruptController;
+static XSpi Spi;
+
+/*
+ * The following variables are shared between non-interrupt processing and
+ * interrupt processing such that they must be global.
+ */
+volatile static int TransferInProgress; /* State of Spi Transfer */
+static int ErrorCount; /* Errors occurred during Spi transfers */
+
+/*
+ * The user needs to allocate a buffer to be used by the In-system and Serial
+ * Flash Library to perform any read/write operations on the Serial Flash
+ * device.
+ * User applications must pass the address of this memory to the Library in
+ * Serial Flash Initialization function, for the Library to work.
+ * For Write operations:
+ * - The size of this buffer should be equal to the Number of bytes to be
+ * written to the Serial Flash + XISF_CMD_MAX_EXTRA_BYTES.
+ * - The size of this buffer should be large enough for usage across all the
+ * applications that use a common instance of the Serial Flash.
+ * - A minimum of one byte and a maximum of ISF_PAGE_SIZE bytes can be written
+ * to the Serial Flash, through a single Write operation.
+ * The size of this buffer should be equal to XISF_CMD_MAX_EXTRA_BYTES, if the
+ * application only reads from the Serial Flash (no write operations).
+ */
+u8 IsfWriteBuffer[ISF_OTP_WRITE_SIZE + XISF_OTP_RDWR_EXTRA_BYTES];
+
+/*
+ * Buffers used during read and write transactions.
+ */
+u8 ReadBuffer[ISF_OTP_WRITE_SIZE + XISF_OTP_RDWR_EXTRA_BYTES]; /* Read Buffer */
+u8 WriteBuffer[ISF_OTP_WRITE_SIZE]; /* Write Buffer */
+
+/************************** Function Definitions ******************************/
+
+/*****************************************************************************/
+/**
+*
+* Main function to execute the Intel OTP Read/Write Flash example.
+*
+* @param None
+*
+* @return XST_SUCCESS if successful else XST_FAILURE.
+*
+* @note None
+*
+******************************************************************************/
+int main()
+{
+ int Status;
+ u32 Address;
+ XIsf_WriteParam WriteParam;
+ XIsf_ReadParam ReadParam;
+
+
+ /*
+ * Initialize the SPI driver so that it's ready to use,
+ * specify the device ID that is generated in xparameters.h.
+ */
+ Status = XSpi_Initialize(&Spi, SPI_DEVICE_ID);
+ if(Status != XST_SUCCESS) {
+ return XST_FAILURE;
+ }
+
+ /*
+ * Connect the SPI driver to the interrupt subsystem such that
+ * interrupts can occur. This function is application specific.
+ */
+ Status = SetupInterruptSystem(&Spi);
+ if(Status != XST_SUCCESS) {
+ return XST_FAILURE;
+ }
+
+ /*
+ * Setup the handler for the SPI that will be called from the interrupt
+ * context when an SPI status occurs, specify a pointer to the SPI
+ * driver instance as the callback reference so the handler is able to
+ * access the instance data.
+ */
+ XIsf_SetStatusHandler(&Isf, &Spi, (XSpi_StatusHandler)SpiHandler);
+
+ /*
+ * Start the SPI driver so that interrupts and the device are enabled.
+ */
+ XSpi_Start(&Spi);
+
+ /*
+ * Initialize the In-system and Serial Flash Library.
+ */
+ Status = XIsf_Initialize(&Isf, &Spi, ISF_SPI_SELECT, IsfWriteBuffer);
+ if(Status != XST_SUCCESS) {
+ 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.
+ */
+ Address = ISF_OTP_TEST_ADDRESS;
+
+ /*
+ * 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 for any errors.
+ */
+ while(TransferInProgress);
+ if(ErrorCount != 0) {
+ return XST_FAILURE;
+ }
+
+ /*
+ * Wait till the Flash is not Busy.
+ */
+ Status = IsfWaitForFlashNotBusy();
+ if(Status != XST_SUCCESS) {
+ return XST_FAILURE;
+ }
+
+ /*
+ * Set the
+ * - Address within the OTP region of the Serial Flash where the data is
+ * to be written.
+ * - The number of bytes to be written to the Serial Flash, this is
+ * always 1 as only 1 byte can be written.
+ * - Write Buffer which contains the data to be written to the OTP
+ * region of the Serial Flash.
+ */
+ WriteParam.Address = Address;
+ WriteParam.NumBytes = ISF_OTP_WRITE_SIZE;
+ WriteParam.WritePtr = WriteBuffer;
+
+ /*
+ * Prepare the write buffer. Fill in the data need to be written into
+ * the OTP region of the Serial Flash.
+ */
+ WriteParam.WritePtr[BYTE1] = ISF_TEST_BYTE;
+
+ /*
+ * Perform the OTP Write operation.
+ */
+ TransferInProgress = TRUE;
+ Status = XIsf_Write(&Isf, XISF_OTP_WRITE, (void*) &WriteParam);
+ if(Status != XST_SUCCESS) {
+ return XST_FAILURE;
+ }
+
+ /*
+ * Wait till the Transfer is complete and check for any errors.
+ */
+ while(TransferInProgress);
+ if(ErrorCount != 0) {
+ return XST_FAILURE;
+ }
+
+ /*
+ * Wait till the Flash is not Busy.
+ */
+ Status = IsfWaitForFlashNotBusy();
+ if(Status != XST_SUCCESS) {
+ return XST_FAILURE;
+ }
+
+ /*
+ * Set the
+ * - Address in the OTP region of the Serial Flash where the data is to
+ * be read from.
+ * - Number of bytes to be read from the Serial Flash.
+ * - Read Buffer to which the data is to be read.
+ */
+ ReadParam.Address = Address;
+ ReadParam.NumBytes = ISF_OTP_WRITE_SIZE;
+ ReadParam.ReadPtr = ReadBuffer;
+
+ /*
+ * Perform the OTP read operation.
+ */
+ TransferInProgress = TRUE;
+ Status = XIsf_Read(&Isf, XISF_OTP_READ, (void*) &ReadParam);
+ if(Status != XST_SUCCESS) {
+ return XST_FAILURE;
+ }
+
+ /*
+ * Wait till the Transfer is complete and check for any errors.
+ */
+ while(TransferInProgress);
+ if(ErrorCount != 0) {
+ return XST_FAILURE;
+ }
+
+ /*
+ * Compare the data read against the data Written.
+ */
+ if(ReadBuffer[BYTE1 + XISF_OTP_RDWR_EXTRA_BYTES] !=
+ (u8)(ISF_TEST_BYTE)) {
+ return XST_FAILURE;
+ }
+
+ return XST_SUCCESS;
+}
+
+/*****************************************************************************/
+/**
+*
+* This function waits till the Intel serial Flash is ready to accept the 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 complete and check for any errors.
+ */
+ while(TransferInProgress);
+ 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) {
+
+ /*
+ * If there were errors return XST_FAILURE.
+ */
+ if (StatusReg & (XISF_SR_PROG_FAIL_MASK |
+ XISF_SR_ERASE_FAIL_MASK)) {
+ return XST_FAILURE;
+ }
+ break;
+ }
+ }
+
+ return XST_SUCCESS;
+}
+
+/*****************************************************************************/
+/**
+*
+* This function is the handler which performs processing for the SPI 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 SPI data
+* completes or an error occurs.
+*
+* This handler provides an example of how to handle SPI interrupts and
+* is application specific.
+*
+* @param CallBackRef is the upper layer callback reference passed back
+* when the callback function is invoked.
+* @param StatusEvent is the event that just occurred.
+* @param ByteCount is the number of bytes transferred up until the event
+* occurred.
+*
+* @return None.
+*
+* @note None.
+*
+******************************************************************************/
+void SpiHandler(void *CallBackRef, u32 StatusEvent, u16 ByteCount)
+{
+ /*
+ * Indicate the transfer on the SPI bus is no longer in progress
+ * regardless of the status event.
+ */
+ TransferInProgress = FALSE;
+
+ /*
+ * If the event was not transfer done, then track it as an error.
+ */
+ if (StatusEvent != XST_SPI_TRANSFER_DONE) {
+ ErrorCount++;
+ }
+}
+
+/*****************************************************************************/
+/**
+*
+* This function setups the interrupt system such that interrupts can occur
+* for the Spi device. This function is application specific since the actual
+* system may or may not have an interrupt controller. The Spi device could be
+* directly connected to a processor without an interrupt controller. The
+* user should modify this function to fit the application.
+*
+* @param SpiPtr is a pointer to the instance of the Spi device.
+*
+* @return XST_SUCCESS if successful, otherwise XST_FAILURE.
+*
+* @note None
+*
+******************************************************************************/
+static int SetupInterruptSystem(XSpi *SpiPtr)
+{
+
+ int Status;
+
+ /*
+ * Initialize the interrupt controller driver so that
+ * it's ready to use, specify the device ID that is generated in
+ * xparameters.h
+ */
+ Status = XIntc_Initialize(&InterruptController, INTC_DEVICE_ID);
+ if(Status != XST_SUCCESS) {
+ return XST_FAILURE;
+ }
+
+ /*
+ * Connect a device driver handler that will be called when an interrupt
+ * for the device occurs, the device driver handler performs the
+ * specific interrupt processing for the device
+ */
+ Status = XIntc_Connect(&InterruptController,
+ SPI_INTR_ID,
+ (XInterruptHandler)XSpi_InterruptHandler,
+ (void *)SpiPtr);
+ if(Status != XST_SUCCESS) {
+ return XST_FAILURE;
+ }
+
+ /*
+ * Start the interrupt controller such that interrupts are enabled for
+ * all devices that cause interrupts, specify real mode so that
+ * the SPI can cause interrupts through the interrupt controller.
+ */
+ Status = XIntc_Start(&InterruptController, XIN_REAL_MODE);
+ if(Status != XST_SUCCESS) {
+ return XST_FAILURE;
+ }
+
+ /*
+ * Enable the interrupt for the SPI.
+ */
+ XIntc_Enable(&InterruptController, SPI_INTR_ID);
+
+
+ /*
+ * Initialize the exception table.
+ */
+ Xil_ExceptionInit();
+
+ /*
+ * Register the interrupt controller handler with the exception table.
+ */
+ Xil_ExceptionRegisterHandler(XIL_EXCEPTION_ID_INT,
+ (Xil_ExceptionHandler)XIntc_InterruptHandler,
+ &InterruptController);
+
+ /*
+ * Enable non-critical exceptions.
+ */
+ Xil_ExceptionEnable();
+
+ return XST_SUCCESS;
+}
diff --git a/lib/sw_services/xilisf/examples/xilisf_intel_rdwr_polled_example.c b/lib/sw_services/xilisf/examples/xilisf_intel_rdwr_polled_example.c
new file mode 100644
index 00000000..55428f54
--- /dev/null
+++ b/lib/sw_services/xilisf/examples/xilisf_intel_rdwr_polled_example.c
@@ -0,0 +1,425 @@
+/******************************************************************************
+*
+* Copyright (C) 2012 - 2014 Xilinx, Inc. All rights reserved.
+*
+* Permission is hereby granted, free of charge, to any person obtaining a copy
+* of this software and associated documentation files (the "Software"), to deal
+* in the Software without restriction, including without limitation the rights
+* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+* copies of the Software, and to permit persons to whom the Software is
+* furnished to do so, subject to the following conditions:
+*
+* The above copyright notice and this permission notice shall be included in
+* all copies or substantial portions of the Software.
+*
+* Use of the Software is limited solely to applications:
+* (a) running on a Xilinx device, or
+* (b) that interact with a Xilinx device through a bus or interconnect.
+*
+* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+* XILINX BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
+* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+* SOFTWARE.
+*
+* Except as contained in this notice, the name of the Xilinx shall not be used
+* in advertising or otherwise to promote the sale, use or other dealings in
+* this Software without prior written authorization from Xilinx.
+*
+******************************************************************************/
+/******************************************************************************
+*
+* @file xilisf_intel_rdwr_polled_example.c
+*
+* This file contains a design example using the Xilinx In-system and Serial
+* Flash Library (XilIsf) with the Spi driver in polled mode of operation.
+* This example shows the Sector Protection Register Read, Sector Protection
+* Register Write, Sector Erase, Read and Write features.
+*
+* This example
+* - Disables the Sector Protection for all the Sectors
+* - Erases a Sector
+* - Writes to a Page within the Erased Sector
+* - Reads back the Page that is written and compares the data.
+*
+* This example has been tested with Intel (Numonyx) Serial Flash Memory (S33)
+* on a S3A-DSP starter kit. For further details about the S33 Flash device refer
+* to the Intel (Numonyx) Serial Flash Memory (S33) Data sheets.
+*
+* @note
+*
+* None.
+*
+*
+* MODIFICATION HISTORY:
+*
+* Ver Who Date Changes
+* ----- --- -------- -----------------------------------------------
+* 1.00a sdm 04/02/08 First release
+* 2.00a ktn 11/22/09 The Spi Driver APIs have changed. Replaced the call
+* to XSpi_mIntrGlobalDisable with XSpi_IntrGlobalDisable.
+*
+*
+******************************************************************************/
+
+/***************************** Include Files *********************************/
+
+#include "xparameters.h" /* EDK generated parameters */
+#include "xilisf.h" /* Serial Flash Library header file */
+
+
+/************************** Constant Definitions *****************************/
+
+/*
+ * The following constants map to the XPAR parameters created in the
+ * xparameters.h file. They are defined here such that a user can easily
+ * change all the needed parameters in one place.
+ */
+#define SPI_DEVICE_ID XPAR_SPI_0_DEVICE_ID
+
+/*
+ * The following constant defines the slave select signal that is used to
+ * to select the Flash device on the SPI bus, this signal is typically
+ * connected to the chip select of the device.
+ */
+#define ISF_SPI_SELECT 0x01
+
+/*
+ * Number of bytes per page in the flash device.
+ */
+#define ISF_PAGE_SIZE 256
+
+/*
+ * Address of the page to perform Erase, Write and Read operations.
+ */
+#define ISF_TEST_ADDRESS 0x010000;
+#define ISF_TEST_BYTE 0x20 /* Test Byte offset value written */
+
+/**************************** Type Definitions *******************************/
+
+/***************** Macros (Inline Functions) Definitions *********************/
+
+/************************** Function Prototypes ******************************/
+
+static int IsfWaitForFlashNotBusy(void);
+
+/************************** 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.
+ */
+static XIsf Isf;
+static XSpi Spi;
+
+/*
+ * The user needs to allocate a buffer to be used by the In-system and Serial
+ * Flash Library to perform any read/write operations on the Serial Flash
+ * device.
+ * User applications must pass the address of this memory to the Library in
+ * Serial Flash Initialization function, for the Library to work.
+ * For Write operations:
+ * - The size of this buffer should be equal to the Number of bytes to be
+ * written to the Serial Flash + XISF_CMD_MAX_EXTRA_BYTES.
+ * - The size of this buffer should be large enough for usage across all the
+ * applications that use a common instance of the Serial Flash.
+ * - A minimum of one byte and a maximum of ISF_PAGE_SIZE bytes can be written
+ * to the Serial Flash, through a single Write operation.
+ * The size of this buffer should be equal to XISF_CMD_MAX_EXTRA_BYTES, if the
+ * application only reads from the Serial Flash (no write operations).
+ */
+u8 IsfWriteBuffer[ISF_PAGE_SIZE + XISF_CMD_SEND_EXTRA_BYTES];
+
+/*
+ * Buffers used during read and write transactions.
+ */
+u8 ReadBuffer[ISF_PAGE_SIZE + XISF_CMD_SEND_EXTRA_BYTES]; /* Read Buffer */
+u8 WriteBuffer[ISF_PAGE_SIZE]; /* Write buffer */
+
+/************************** Function Definitions ******************************/
+
+/*****************************************************************************/
+/**
+*
+* Main function to execute the Intel Serial Flash Read/Write polled example.
+*
+* @param None
+*
+* @return XST_SUCCESS if successful else XST_FAILURE.
+*
+* @note None
+*
+******************************************************************************/
+int main()
+{
+ int Status;
+ u32 Index;
+ u32 Address;
+ XIsf_WriteParam WriteParam;
+ XIsf_ReadParam ReadParam;
+
+ /*
+ * Initialize the SPI driver so that it's ready to use,
+ * specify the device ID that is generated in xparameters.h.
+ */
+ Status = XSpi_Initialize(&Spi, SPI_DEVICE_ID);
+ if(Status != XST_SUCCESS) {
+ return XST_FAILURE;
+ }
+
+ /*
+ * Start the SPI driver so that device is enabled.
+ */
+ XSpi_Start(&Spi);
+
+ /*
+ * Disable Global interrupt to use the Spi driver in polled mode
+ * operation.
+ */
+ XSpi_IntrGlobalDisable(&Spi);
+
+ /*
+ * Initialize the In-system and Serial Flash Library.
+ */
+ Status = XIsf_Initialize(&Isf, &Spi, ISF_SPI_SELECT, IsfWriteBuffer);
+ if(Status != XST_SUCCESS) {
+ return XST_FAILURE;
+ }
+
+ /*
+ * The following code Disables the Sector Protection for all the Blocks
+ * in the Intel Serial Flash.
+ */
+
+ /*
+ * Perform the Write Enable operation.
+ */
+ Status = XIsf_WriteEnable(&Isf, XISF_WRITE_ENABLE);
+ if(Status != XST_SUCCESS) {
+ return XST_FAILURE;
+ }
+
+ /*
+ * Wait till the Flash is Not Busy.
+ */
+ Status = IsfWaitForFlashNotBusy();
+ if(Status != XST_SUCCESS) {
+ return XST_FAILURE;
+ }
+
+ /*
+ * Read the Sector Protection Register.
+ */
+ Status = XIsf_SectorProtect(&Isf, XISF_SPR_READ, ReadBuffer);
+ if(Status != XST_SUCCESS) {
+ return XST_FAILURE;
+ }
+
+ /*
+ * Wait till the Flash is not Busy.
+ */
+ Status = IsfWaitForFlashNotBusy();
+ if(Status != XST_SUCCESS) {
+ return XST_FAILURE;
+ }
+
+
+ /*
+ * Clear all the Block protection bits in the Sector Protection
+ * Register.
+ */
+ WriteBuffer[BYTE1] = ReadBuffer[BYTE2] &
+ (~(XISF_SR_BLOCK_PROTECT_MASK));
+ Status = XIsf_SectorProtect(&Isf, XISF_SPR_WRITE, WriteBuffer);
+ if(Status != XST_SUCCESS) {
+ return XST_FAILURE;
+ }
+
+
+ /*
+ * Specify the address in the Serial Flash for the Erase/Write/Read
+ * operations.
+ */
+ Address = ISF_TEST_ADDRESS;
+
+
+ /*
+ * The following code Erases a Sector in the Intel Serial Flash.
+ */
+
+
+ /*
+ * Perform the Write Enable operation.
+ */
+ Status = XIsf_WriteEnable(&Isf, XISF_WRITE_ENABLE);
+ if(Status != XST_SUCCESS) {
+ return XST_FAILURE;
+ }
+
+ /*
+ * Wait till the Flash is not Busy.
+ */
+ Status = IsfWaitForFlashNotBusy();
+ if(Status != XST_SUCCESS) {
+ return XST_FAILURE;
+ }
+
+ /*
+ * Perform the Sector Erase operation.
+ */
+ Status = XIsf_Erase(&Isf, XISF_SECTOR_ERASE, Address);
+ if(Status != XST_SUCCESS) {
+ return XST_FAILURE;
+ }
+
+ /*
+ * Wait till the Flash is not Busy.
+ */
+ Status = IsfWaitForFlashNotBusy();
+ if(Status != XST_SUCCESS) {
+ return XST_FAILURE;
+ }
+
+
+ /*
+ * The following code Writes data to a Page in the Intel Serial Flash.
+ */
+
+ /*
+ * Perform the Write Enable operation.
+ */
+ Status = XIsf_WriteEnable(&Isf, XISF_WRITE_ENABLE);
+ if(Status != XST_SUCCESS) {
+ return XST_FAILURE;
+ }
+
+ /*
+ * Wait till the Flash is not Busy.
+ */
+ Status = IsfWaitForFlashNotBusy();
+ if(Status != XST_SUCCESS) {
+ return XST_FAILURE;
+ }
+
+
+ /*
+ * - Set the address within the Serial Flash where the data is to be
+ * written.
+ * - Set the number of bytes to be written to the Serial Flash.
+ * - Write Buffer which contains the data to be written to the Serial
+ * Flash.
+ */
+ WriteParam.Address = Address;
+ WriteParam.NumBytes = ISF_PAGE_SIZE;
+ WriteParam.WritePtr = WriteBuffer;
+
+ /*
+ * Prepare the write buffer. Fill in the data need to be written into
+ * Serial Flash.
+ */
+ for(Index = 0; Index < ISF_PAGE_SIZE; Index++) {
+ WriteParam.WritePtr[Index] = Index + ISF_TEST_BYTE;
+ }
+
+ /*
+ * Perform the Write operation.
+ */
+ Status = XIsf_Write(&Isf, XISF_WRITE, (void*) &WriteParam);
+ if(Status != XST_SUCCESS) {
+ return XST_FAILURE;
+ }
+
+ /*
+ * Wait till the Flash is not Busy.
+ */
+ Status = IsfWaitForFlashNotBusy();
+ if(Status != XST_SUCCESS) {
+ return XST_FAILURE;
+ }
+
+ /*
+ * The following code Reads data from a Page in the Intel Serial Flash.
+ */
+
+ /*
+ * 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.
+ * - Read Buffer to which the data is to be read.
+ */
+ ReadParam.Address = Address;
+ ReadParam.NumBytes = ISF_PAGE_SIZE;
+ ReadParam.ReadPtr = ReadBuffer;
+
+ /*
+ * Perform the read operation.
+ */
+ Status = XIsf_Read(&Isf, XISF_READ, (void*) &ReadParam);
+ if(Status != XST_SUCCESS) {
+ return XST_FAILURE;
+ }
+
+ /*
+ * Compare the data read against the data Written.
+ */
+ for(Index = 0; Index < ISF_PAGE_SIZE; Index++) {
+ if(ReadBuffer[Index + XISF_CMD_SEND_EXTRA_BYTES] !=
+ (u8)(Index + ISF_TEST_BYTE)) {
+ return XST_FAILURE;
+ }
+ }
+
+ return XST_SUCCESS;
+}
+
+/*****************************************************************************/
+/**
+*
+* This function waits till the Intel 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.
+ */
+ StatusReg = ReadBuffer[BYTE2];
+ if((StatusReg & XISF_SR_IS_READY_MASK) == 0) {
+
+ /*
+ * If there were errors return XST_FAILURE.
+ */
+ if (StatusReg & (XISF_SR_PROG_FAIL_MASK |
+ XISF_SR_ERASE_FAIL_MASK)) {
+ return XST_FAILURE;
+ }
+ break;
+ }
+ }
+
+ return XST_SUCCESS;
+}
diff --git a/lib/sw_services/xilisf/examples/xilisf_intel_read_write_example.c b/lib/sw_services/xilisf/examples/xilisf_intel_read_write_example.c
new file mode 100644
index 00000000..0445cb11
--- /dev/null
+++ b/lib/sw_services/xilisf/examples/xilisf_intel_read_write_example.c
@@ -0,0 +1,655 @@
+/******************************************************************************
+*
+* Copyright (C) 2012 - 2014 Xilinx, Inc. All rights reserved.
+*
+* Permission is hereby granted, free of charge, to any person obtaining a copy
+* of this software and associated documentation files (the "Software"), to deal
+* in the Software without restriction, including without limitation the rights
+* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+* copies of the Software, and to permit persons to whom the Software is
+* furnished to do so, subject to the following conditions:
+*
+* The above copyright notice and this permission notice shall be included in
+* all copies or substantial portions of the Software.
+*
+* Use of the Software is limited solely to applications:
+* (a) running on a Xilinx device, or
+* (b) that interact with a Xilinx device through a bus or interconnect.
+*
+* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+* XILINX BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
+* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+* SOFTWARE.
+*
+* Except as contained in this notice, the name of the Xilinx shall not be used
+* in advertising or otherwise to promote the sale, use or other dealings in
+* this Software without prior written authorization from Xilinx.
+*
+******************************************************************************/
+/******************************************************************************
+*
+* @file xilisf_intel_read_write_example.c
+*
+* This file contains a design example using the Xilinx In-system and Serial
+* Flash Library (XilIsf). This example shows the Sector Protection Register
+* Read, Sector Protection Register Write, Sector Erase, Read and Write features.
+*
+* This example
+* - Disables the Sector Protection for all the Sectors
+* - Erases a Sector
+* - Writes to a Page within the Erased Sector
+* - Reads back the Page that is written and compares the data.
+*
+* This example has been tested with Intel (Numonyx) Serial Flash Memory (S33)
+* on a S3A-DSP starter kit. For further details about the S33 Flash device refer
+* to the Intel (Numonyx) Serial Flash Memory (S33) Data sheets.
+*
+* @note
+*
+* None.
+*
+*
+* MODIFICATION HISTORY:
+*
+* Ver Who Date Changes
+* ----- ---- -------- -----------------------------------------------
+* 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.
+*
+*
+******************************************************************************/
+
+/***************************** Include Files *********************************/
+
+#include "xparameters.h" /* EDK generated parameters */
+#include "xintc.h" /* Interrupt controller device driver */
+#include /* Serial Flash Library header file */
+#include "xil_exception.h"
+
+/************************** Constant Definitions *****************************/
+
+/*
+ * The following constants map to the XPAR parameters created in the
+ * xparameters.h file. They are defined here such that a user can easily
+ * change all the needed parameters in one place.
+ */
+#define SPI_DEVICE_ID XPAR_SPI_0_DEVICE_ID
+#define INTC_DEVICE_ID XPAR_INTC_0_DEVICE_ID
+#define SPI_INTR_ID XPAR_INTC_0_SPI_0_VEC_ID
+
+/*
+ * The following constant defines the slave select signal that is used to
+ * to select the Flash device on the SPI bus, this signal is typically
+ * connected to the chip select of the device.
+ */
+#define ISF_SPI_SELECT 0x01
+
+/*
+ * Number of bytes per page in the flash device.
+ */
+#define ISF_PAGE_SIZE 256
+
+/*
+ * Address of the page to perform Erase, Write and Read operations.
+ */
+#define ISF_TEST_ADDRESS 0x010000;
+#define ISF_TEST_BYTE 0x20 /* Test Byte offset value written */
+
+/**************************** Type Definitions *******************************/
+
+/***************** Macros (Inline Functions) Definitions *********************/
+
+/************************** Function Prototypes ******************************/
+
+static int IsfWaitForFlashNotBusy(void);
+void SpiHandler(void *CallBackRef, u32 StatusEvent, u16 ByteCount);
+static int SetupInterruptSystem(XSpi *SpiPtr);
+
+/************************** 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.
+ */
+static XIsf Isf;
+static XIntc InterruptController;
+static XSpi Spi;
+
+/*
+ * The following variables are shared between non-interrupt processing and
+ * interrupt processing such that they must be global.
+ */
+volatile static int TransferInProgress; /* State of Spi Transfer */
+static int ErrorCount; /* Errors occurred during Spi transfers */
+
+/*
+ * The user needs to allocate a buffer to be used by the In-system and Serial
+ * Flash Library to perform any read/write operations on the Serial Flash
+ * device.
+ * User applications must pass the address of this memory to the Library in
+ * Serial Flash Initialization function, for the Library to work.
+ * For Write operations:
+ * - The size of this buffer should be equal to the Number of bytes to be
+ * written to the Serial Flash + XISF_CMD_MAX_EXTRA_BYTES.
+ * - The size of this buffer should be large enough for usage across all the
+ * applications that use a common instance of the Serial Flash.
+ * - A minimum of one byte and a maximum of ISF_PAGE_SIZE bytes can be written
+ * to the Serial Flash, through a single Write operation.
+ * The size of this buffer should be equal to XISF_CMD_MAX_EXTRA_BYTES, if the
+ * application only reads from the Serial Flash (no write operations).
+ */
+u8 IsfWriteBuffer[ISF_PAGE_SIZE + XISF_CMD_SEND_EXTRA_BYTES];
+
+/*
+ * Buffers used during read and write transactions.
+ */
+u8 ReadBuffer[ISF_PAGE_SIZE + XISF_CMD_SEND_EXTRA_BYTES]; /* Read Buffer */
+u8 WriteBuffer[ISF_PAGE_SIZE]; /* Write buffer */
+
+/************************** Function Definitions ******************************/
+
+/*****************************************************************************/
+/**
+*
+* Main function to execute the Intel Serial Flash Read/Write example.
+*
+* @param None
+*
+* @return XST_SUCCESS if successful else XST_FAILURE.
+*
+* @note None
+*
+******************************************************************************/
+int main()
+{
+ int Status;
+ u32 Index;
+ u32 Address;
+ XIsf_WriteParam WriteParam;
+ XIsf_ReadParam ReadParam;
+
+ /*
+ * Initialize the SPI driver so that it's ready to use,
+ * specify the device ID that is generated in xparameters.h.
+ */
+ Status = XSpi_Initialize(&Spi, SPI_DEVICE_ID);
+ if(Status != XST_SUCCESS) {
+ return XST_FAILURE;
+ }
+
+ /*
+ * Connect the SPI driver to the interrupt subsystem such that
+ * interrupts can occur. This function is application specific.
+ */
+ Status = SetupInterruptSystem(&Spi);
+ if(Status != XST_SUCCESS) {
+ return XST_FAILURE;
+ }
+
+ /*
+ * Setup the handler for the SPI that will be called from the interrupt
+ * context when an SPI status occurs, specify a pointer to the SPI
+ * driver instance as the callback reference so the handler is able to
+ * access the instance data.
+ */
+ XIsf_SetStatusHandler(&Isf, &Spi, (XSpi_StatusHandler)SpiHandler);
+
+ /*
+ * Start the SPI driver so that interrupts and the device are enabled.
+ */
+ XSpi_Start(&Spi);
+
+ /*
+ * Initialize the In-system and Serial Flash Library.
+ */
+ Status = XIsf_Initialize(&Isf, &Spi, ISF_SPI_SELECT, IsfWriteBuffer);
+ if(Status != XST_SUCCESS) {
+ 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
+ * in the Intel Serial Flash.
+ */
+
+ /*
+ * 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 for errors.
+ */
+ while(TransferInProgress);
+ if(ErrorCount != 0) {
+ return XST_FAILURE;
+ }
+
+ /*
+ * Wait till the Flash is Not Busy.
+ */
+ Status = IsfWaitForFlashNotBusy();
+ if(Status != XST_SUCCESS) {
+ return XST_FAILURE;
+ }
+
+ /*
+ * Read the Sector Protection Register.
+ */
+ TransferInProgress = TRUE;
+ Status = XIsf_SectorProtect(&Isf, XISF_SPR_READ, ReadBuffer);
+ if(Status != XST_SUCCESS) {
+ return XST_FAILURE;
+ }
+
+ /*
+ * Wait till the Transfer is complete and check for errors.
+ */
+ while(TransferInProgress);
+ if(ErrorCount != 0) {
+ return XST_FAILURE;
+ }
+
+ /*
+ * Clear all the Block protection bits in the Sector Protection
+ * Register.
+ */
+ WriteBuffer[BYTE1] = ReadBuffer[BYTE2] &
+ (~(XISF_SR_BLOCK_PROTECT_MASK));
+ TransferInProgress = TRUE;
+ Status = XIsf_SectorProtect(&Isf, XISF_SPR_WRITE, WriteBuffer);
+ if(Status != XST_SUCCESS) {
+ return XST_FAILURE;
+ }
+
+ /*
+ * Wait till the Transfer is complete and check for errors.
+ */
+ while(TransferInProgress);
+ if(ErrorCount != 0) {
+ return XST_FAILURE;
+ }
+
+ /*
+ * Wait till the Flash is not Busy.
+ */
+ Status = IsfWaitForFlashNotBusy();
+ if(Status != XST_SUCCESS) {
+ return XST_FAILURE;
+ }
+
+
+ /*
+ * Specify the address in the Serial Flash for the Erase/Write/Read
+ * operations.
+ */
+ Address = ISF_TEST_ADDRESS;
+
+
+ /*
+ * The following code Erases a Sector in the Intel Serial Flash.
+ */
+
+
+ /*
+ * 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 for errors.
+ */
+ while(TransferInProgress);
+ if(ErrorCount != 0) {
+ return XST_FAILURE;
+ }
+
+ /*
+ * Wait till the Flash is not Busy.
+ */
+ Status = IsfWaitForFlashNotBusy();
+ if(Status != XST_SUCCESS) {
+ return XST_FAILURE;
+ }
+
+ /*
+ * Perform the Sector Erase operation.
+ */
+ TransferInProgress = TRUE;
+ Status = XIsf_Erase(&Isf, XISF_SECTOR_ERASE, Address);
+ if(Status != XST_SUCCESS) {
+ return XST_FAILURE;
+ }
+
+ /*
+ * Wait till the Transfer is complete and check for errors.
+ */
+ while(TransferInProgress);
+ if(ErrorCount != 0) {
+ return XST_FAILURE;
+ }
+
+ /*
+ * Wait till the Flash is not Busy.
+ */
+ Status = IsfWaitForFlashNotBusy();
+ if(Status != XST_SUCCESS) {
+ return XST_FAILURE;
+ }
+
+
+ /*
+ * The following code Writes data to a Page in the Intel Serial Flash.
+ */
+
+ /*
+ * 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 for errors.
+ */
+ while(TransferInProgress);
+ if(ErrorCount != 0) {
+ return XST_FAILURE;
+ }
+
+ /*
+ * Wait till the Flash is not Busy.
+ */
+ Status = IsfWaitForFlashNotBusy();
+ if(Status != XST_SUCCESS) {
+ return XST_FAILURE;
+ }
+
+
+ /*
+ * - Set the address within the Serial Flash where the data is to be
+ * written.
+ * - Set the number of bytes to be written to the Serial Flash.
+ * - Write Buffer which contains the data to be written to the Serial
+ * Flash.
+ */
+ WriteParam.Address = Address;
+ WriteParam.NumBytes = ISF_PAGE_SIZE;
+ WriteParam.WritePtr = WriteBuffer;
+
+ /*
+ * Prepare the write buffer. Fill in the data need to be written into
+ * Serial Flash.
+ */
+ for(Index = 0; Index < ISF_PAGE_SIZE; Index++) {
+ WriteParam.WritePtr[Index] = Index + ISF_TEST_BYTE;
+ }
+
+ /*
+ * Perform the Write operation.
+ */
+ TransferInProgress = TRUE;
+ Status = XIsf_Write(&Isf, XISF_WRITE, (void*) &WriteParam);
+ if(Status != XST_SUCCESS) {
+ return XST_FAILURE;
+ }
+
+ /*
+ * Wait till the Transfer is complete and check for errors.
+ */
+ while(TransferInProgress);
+ if(ErrorCount != 0) {
+ return XST_FAILURE;
+ }
+
+ /*
+ * Wait till the Flash is not Busy.
+ */
+ Status = IsfWaitForFlashNotBusy();
+ if(Status != XST_SUCCESS) {
+ return XST_FAILURE;
+ }
+
+ /*
+ * The following code Reads data from a Page in the Intel Serial Flash.
+ */
+
+ /*
+ * 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.
+ * - Read Buffer to which the data is to be read.
+ */
+ ReadParam.Address = Address;
+ ReadParam.NumBytes = ISF_PAGE_SIZE;
+ ReadParam.ReadPtr = ReadBuffer;
+
+ /*
+ * Perform the read operation.
+ */
+ TransferInProgress = TRUE;
+ Status = XIsf_Read(&Isf, XISF_READ, (void*) &ReadParam);
+ if(Status != XST_SUCCESS) {
+ return XST_FAILURE;
+ }
+
+ /*
+ * Wait till the Transfer is complete and check for errors.
+ */
+ while(TransferInProgress);
+ if(ErrorCount != 0) {
+ return XST_FAILURE;
+ }
+
+ /*
+ * Compare the data read against the data Written.
+ */
+ for(Index = 0; Index < ISF_PAGE_SIZE; Index++) {
+ if(ReadBuffer[Index + XISF_CMD_SEND_EXTRA_BYTES] !=
+ (u8)(Index + ISF_TEST_BYTE)) {
+ return XST_FAILURE;
+ }
+ }
+
+ return XST_SUCCESS;
+}
+
+/*****************************************************************************/
+/**
+*
+* This function waits till the Intel 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.
+ */
+ StatusReg = ReadBuffer[BYTE2];
+ if((StatusReg & XISF_SR_IS_READY_MASK) == 0) {
+
+ /*
+ * If there were errors return XST_FAILURE.
+ */
+ if (StatusReg & (XISF_SR_PROG_FAIL_MASK |
+ XISF_SR_ERASE_FAIL_MASK)) {
+ return XST_FAILURE;
+ }
+ break;
+ }
+ }
+
+ return XST_SUCCESS;
+}
+
+/*****************************************************************************/
+/**
+*
+* This function is the handler which performs processing for the SPI 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 SPI data
+* completes or an error occurs.
+*
+* This handler provides an example of how to handle SPI interrupts and
+* is application specific.
+*
+* @param CallBackRef is the upper layer callback reference passed back
+* when the callback function is invoked.
+* @param StatusEvent is the event that just occurred.
+* @param ByteCount is the number of bytes transferred up until the event
+* occurred.
+*
+* @return None.
+*
+* @note None.
+*
+******************************************************************************/
+void SpiHandler(void *CallBackRef, u32 StatusEvent, u16 ByteCount)
+{
+ /*
+ * Indicate the transfer on the SPI bus is no longer in progress
+ * regardless of the status event.
+ */
+ TransferInProgress = FALSE;
+
+ /*
+ * If the event was not transfer done, then track it as an error.
+ */
+ if (StatusEvent != XST_SPI_TRANSFER_DONE) {
+ ErrorCount++;
+ }
+}
+
+/*****************************************************************************/
+/**
+*
+* This function setups the interrupt system such that interrupts can occur
+* for the Spi device. This function is application specific since the actual
+* system may or may not have an interrupt controller. The Spi device could be
+* directly connected to a processor without an interrupt controller. The
+* user should modify this function to fit the application.
+*
+* @param SpiPtr is a pointer to the instance of the Spi device.
+*
+* @return XST_SUCCESS if successful, otherwise XST_FAILURE.
+*
+* @note None
+*
+******************************************************************************/
+static int SetupInterruptSystem(XSpi *SpiPtr)
+{
+
+ int Status;
+
+ /*
+ * Initialize the interrupt controller driver so that it's ready to use,
+ * specify the device ID that is generated in xparameters.h
+ */
+ Status = XIntc_Initialize(&InterruptController, INTC_DEVICE_ID);
+ if(Status != XST_SUCCESS) {
+ return XST_FAILURE;
+ }
+
+ /*
+ * Connect a device driver handler that will be called when an interrupt
+ * for the device occurs, the device driver handler performs the
+ * specific interrupt processing for the device
+ */
+ Status = XIntc_Connect(&InterruptController,
+ SPI_INTR_ID,
+ (XInterruptHandler)XSpi_InterruptHandler,
+ (void *)SpiPtr);
+ if(Status != XST_SUCCESS) {
+ return XST_FAILURE;
+ }
+
+ /*
+ * Start the interrupt controller such that interrupts are enabled for
+ * all devices that cause interrupts, specify real mode so that
+ * the SPI can cause interrupts through the interrupt controller.
+ */
+ Status = XIntc_Start(&InterruptController, XIN_REAL_MODE);
+ if(Status != XST_SUCCESS) {
+ return XST_FAILURE;
+ }
+
+ /*
+ * Enable the interrupt for the SPI.
+ */
+ XIntc_Enable(&InterruptController, SPI_INTR_ID);
+
+
+ /*
+ * Initialize the exception table.
+ */
+ Xil_ExceptionInit();
+
+ /*
+ * Register the interrupt controller handler with the exception table.
+ */
+ Xil_ExceptionRegisterHandler(XIL_EXCEPTION_ID_INT,
+ (Xil_ExceptionHandler)XIntc_InterruptHandler,
+ &InterruptController);
+
+ /*
+ * Enable non-critical exceptions.
+ */
+ Xil_ExceptionEnable();
+
+ return XST_SUCCESS;
+}
diff --git a/lib/sw_services/xilisf/examples/xilisf_intel_spr_example.c b/lib/sw_services/xilisf/examples/xilisf_intel_spr_example.c
new file mode 100644
index 00000000..31c791c3
--- /dev/null
+++ b/lib/sw_services/xilisf/examples/xilisf_intel_spr_example.c
@@ -0,0 +1,925 @@
+/******************************************************************************
+*
+* Copyright (C) 2012 - 2014 Xilinx, Inc. All rights reserved.
+*
+* Permission is hereby granted, free of charge, to any person obtaining a copy
+* of this software and associated documentation files (the "Software"), to deal
+* in the Software without restriction, including without limitation the rights
+* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+* copies of the Software, and to permit persons to whom the Software is
+* furnished to do so, subject to the following conditions:
+*
+* The above copyright notice and this permission notice shall be included in
+* all copies or substantial portions of the Software.
+*
+* Use of the Software is limited solely to applications:
+* (a) running on a Xilinx device, or
+* (b) that interact with a Xilinx device through a bus or interconnect.
+*
+* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+* XILINX BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
+* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+* SOFTWARE.
+*
+* Except as contained in this notice, the name of the Xilinx shall not be used
+* in advertising or otherwise to promote the sale, use or other dealings in
+* this Software without prior written authorization from Xilinx.
+*
+******************************************************************************/
+/******************************************************************************
+*
+* @file xilisf_intel_spr_example.c
+*
+* This file contains a design example using the Xilinx In-system and Serial
+* Flash Library (XilIsf). This example shows the usage of Sector Erase, Sector
+* Protection, Read and Write features.
+
+* This example
+* - Disables the Sector Protection for all the Sectors
+* - Erases a Sector
+* - Writes to a Page within the erased Sector
+* - Enables the Sector Protection so that all the sectors are Write protected
+* - Erases the Sector (This should not happen as the Sectors are Write protected
+* - Reads the Status Register and checks if the Erase Fail Flag is set
+* - Clears the Status Register Fail Flags
+* - Reads back the Page that is written and compares the data.
+*
+* This example has been tested with Intel (Numonyx) Serial Flash Memory (S33)
+* on a S3A-DSP starter kit. For further details about the S33 Flash device refer
+* to the Intel (Numonyx) Serial Flash Memory (S33) Data sheets.
+*
+* @note
+*
+* None.
+*
+*
+* MODIFICATION HISTORY:
+*
+* Ver Who Date Changes
+* ----- ---- -------- -----------------------------------------------
+* 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.
+*
+*
+******************************************************************************/
+
+/***************************** Include Files *********************************/
+
+#include "xparameters.h" /* EDK generated parameters */
+#include "xintc.h" /* Interrupt controller device driver */
+#include "xspi.h" /* SPI device driver */
+#include /* Serial Flash Library header file */
+#include "xil_exception.h"
+
+/************************** Constant Definitions *****************************/
+
+
+/*
+ * The following constants map to the XPAR parameters created in the
+ * xparameters.h file. They are defined here such that a user can easily
+ * change all the needed parameters in one place.
+ */
+#define SPI_DEVICE_ID XPAR_SPI_0_DEVICE_ID
+#define INTC_DEVICE_ID XPAR_INTC_0_DEVICE_ID
+#define SPI_INTR_ID XPAR_INTC_0_SPI_0_VEC_ID
+
+/*
+ * The following constant defines the slave select signal that is used to
+ * to select the Serial Flash device on the SPI bus, this signal is typically
+ * connected to the chip select of the device.
+ */
+#define ISF_SPI_SELECT 0x01
+
+/*
+ * Number of bytes per page in the Serial Flash.
+ */
+#define ISF_PAGE_SIZE 256
+
+/*
+ * Address of the page to perform Erase, Write and Read operations.
+ */
+#define ISF_TEST_ADDRESS 0x010000;
+#define ISF_TEST_BYTE 0x20 /* Test Byte offset value written */
+
+/**************************** Type Definitions *******************************/
+
+/***************** Macros (Inline Functions) Definitions *********************/
+
+/************************** Function Prototypes ******************************/
+
+static int IsfWaitForFlashNotBusy(void);
+void SpiHandler(void *CallBackRef, u32 StatusEvent, u16 ByteCount);
+static int SetupInterruptSystem(XSpi *SpiPtr);
+
+/************************** 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.
+ */
+static XIsf Isf;
+static XIntc InterruptController;
+static XSpi Spi;
+
+/*
+ * The following variables are shared between non-interrupt processing and
+ * interrupt processing such that they must be global.
+ */
+volatile static int TransferInProgress;
+
+/*
+ * The following variable tracks any errors that occur during interrupt
+ * processing.
+ */
+static int ErrorCount;
+
+/*
+ * The user needs to allocate a buffer to be used by the In-system and Serial
+ * Flash Library to perform any read/write operations on the Serial Flash
+ * device.
+ * User applications must pass the address of this memory to the Library in
+ * Serial Flash Initialization function, for the Library to work.
+ * For Write operations:
+ * - The size of this buffer should be equal to the Number of bytes to be
+ * written to the Serial Flash + XISF_CMD_MAX_EXTRA_BYTES.
+ * - The size of this buffer should be large enough for usage across all the
+ * applications that use a common instance of the Serial Flash.
+ * - A minimum of one byte and a maximum of ISF_PAGE_SIZE bytes can be written
+ * to the Serial Flash, through a single Write operation.
+ * The size of this buffer should be equal to XISF_CMD_MAX_EXTRA_BYTES, if the
+ * application only reads from the Serial Flash (no write operations).
+ */
+u8 IsfWriteBuffer[ISF_PAGE_SIZE + XISF_CMD_SEND_EXTRA_BYTES];
+
+/*
+ * Buffers used during read and write transactions.
+ */
+u8 ReadBuffer[ISF_PAGE_SIZE + XISF_CMD_SEND_EXTRA_BYTES];
+u8 WriteBuffer[ISF_PAGE_SIZE];
+
+/************************** Function Definitions ******************************/
+
+/*****************************************************************************/
+/**
+*
+* Main function to execute the Intel Serial Flash SPR example.
+*
+* @param None
+*
+* @return XST_SUCCESS if successful else XST_FAILURE.
+*
+* @note None
+*
+******************************************************************************/
+int main()
+{
+ int Status;
+ u32 Index;
+ u32 Address;
+ u8 StatusReg;
+ XIsf_WriteParam WriteParam;
+ XIsf_ReadParam ReadParam;
+
+
+ /*
+ * Initialize the SPI driver so that it's ready to use,
+ * specify the device ID that is generated in xparameters.h.
+ */
+ Status = XSpi_Initialize(&Spi, SPI_DEVICE_ID);
+ if(Status != XST_SUCCESS) {
+ return XST_FAILURE;
+ }
+
+ /*
+ * Connect the SPI driver to the interrupt subsystem such that
+ * interrupts can occur. This function is application specific.
+ */
+ Status = SetupInterruptSystem(&Spi);
+ if(Status != XST_SUCCESS) {
+ return XST_FAILURE;
+ }
+
+ /*
+ * Setup the handler for the SPI that will be called from the interrupt
+ * context when an SPI status occurs, specify a pointer to the SPI
+ * driver instance as the callback reference so the handler is able to
+ * access the instance data.
+ */
+ XIsf_SetStatusHandler(&Isf, &Spi, (XSpi_StatusHandler)SpiHandler);
+
+ /*
+ * Start the SPI driver so that interrupts and the device are enabled.
+ */
+ XSpi_Start(&Spi);
+
+ /*
+ * Initialize the Serial Flash Library.
+ */
+ Status = XIsf_Initialize(&Isf, &Spi, ISF_SPI_SELECT, IsfWriteBuffer);
+ if(Status != XST_SUCCESS) {
+ return XST_FAILURE;
+ }
+
+ /*
+ * Set The transfer Mode to Interrupt
+ */
+ XIsf_SetTransferMode(&Isf,XISF_INTERRUPT_MODE);
+
+ /*
+ * 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;
+ }
+
+ /*
+ * Read the sector protection register.
+ */
+ TransferInProgress = TRUE;
+ Status = XIsf_SectorProtect(&Isf, XISF_SPR_READ, ReadBuffer);
+ 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;
+ }
+
+ /*
+ * Clear all the block protection bits in the sector protection register
+ * value read above.
+ */
+ WriteBuffer[BYTE1] = ReadBuffer[BYTE2] &
+ (~(XISF_SR_BLOCK_PROTECT_MASK));
+
+ /*
+ * Write this value to the sector protection register to disable the
+ * sector protection.
+ */
+ TransferInProgress = TRUE;
+ Status = XIsf_SectorProtect(&Isf, XISF_SPR_WRITE, WriteBuffer);
+ 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;
+ }
+
+ /*
+ * Specify the address in the Serial Flash for the Erase/Write/Read
+ * operations.
+ */
+ Address = ISF_TEST_ADDRESS;
+
+ /*
+ * 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;
+ }
+
+ /*
+ * Perform the Sector Erase operation.
+ */
+ TransferInProgress = TRUE;
+ Status = XIsf_Erase(&Isf, XISF_SECTOR_ERASE, Address);
+ 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;
+ }
+
+ /*
+ * 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;
+ }
+
+ /*
+ * - Set the address within the Serial Flash where the data is to be
+ * written.
+ * - Set the number of bytes to be written to the Serial Flash.
+ * - Write Buffer which contains the data to be written to the Serial
+ * Flash.
+ */
+ WriteParam.Address = Address;
+ WriteParam.NumBytes = ISF_PAGE_SIZE;
+ WriteParam.WritePtr = WriteBuffer;
+
+ /*
+ * Prepare the write buffer. Fill in the data need to be written into
+ * Serial Flash.
+ */
+ for(Index = 0; Index < ISF_PAGE_SIZE; Index++) {
+ WriteParam.WritePtr[Index] = Index + ISF_TEST_BYTE;
+ }
+
+ /*
+ * Perform the Write operation.
+ */
+ TransferInProgress = TRUE;
+ Status = XIsf_Write(&Isf, XISF_WRITE, (void*) &WriteParam);
+ 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;
+ }
+
+ /*
+ * 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;
+ }
+
+ /*
+ * Read the sector protection register.
+ */
+ TransferInProgress = TRUE;
+ Status = XIsf_SectorProtect(&Isf, XISF_SPR_READ, ReadBuffer);
+ 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;
+ }
+
+ /*
+ * Set all the block protection bits in the sector protection register
+ * value read above and write it back to the sector protection register.
+ */
+ WriteBuffer[BYTE1] = ReadBuffer[BYTE2] |
+ (XISF_SR_BLOCK_PROTECT_MASK);
+
+ /*
+ * Enable the sector protection.
+ */
+ TransferInProgress = TRUE;
+ Status = XIsf_SectorProtect(&Isf, XISF_SPR_WRITE, WriteBuffer);
+ 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;
+ }
+
+ /*
+ * 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;
+ }
+
+ /*
+ * Perform the Sector Erase operation. This should not work as writes to
+ * the Serial Flash are disabled.
+ */
+ TransferInProgress = TRUE;
+ Status = XIsf_Erase(&Isf, XISF_SECTOR_ERASE, Address);
+ 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;
+ }
+
+ /*
+ * Read 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 erase fail flag is set in the status register. This flag
+ * should be set as a sector erase operation was attempted when sector
+ * protection was enabled.
+ */
+ StatusReg = ReadBuffer[BYTE2];
+ if((StatusReg & XISF_SR_ERASE_FAIL_MASK) == 0) {
+ return XST_FAILURE;
+ }
+ /*
+ * Clear the status register fail flags in the Serial Flash status
+ * register.
+ */
+ TransferInProgress = TRUE;
+ Status = XIsf_Ioctl(&Isf, XISF_IOCTL_CLEAR_SR_FAIL_FLAGS);
+ 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;
+ }
+
+ /*
+ * Read 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 erase fail flag is clear in the status register. This
+ * flag should be clear as a 'Clear SR Fail Flags' command has been
+ * executed.
+ */
+ StatusReg = ReadBuffer[BYTE2];
+ if((StatusReg & XISF_SR_ERASE_FAIL_MASK) != 0) {
+ return XST_FAILURE;
+ }
+
+ /*
+ * Read the sector protection register.
+ */
+ TransferInProgress = TRUE;
+ Status = XIsf_SectorProtect(&Isf, XISF_SPR_READ, ReadBuffer);
+ 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;
+ }
+
+ /*
+ * Clear all the block protection bits in the sector protection register
+ * value read above and write it back to the sector protection register
+ * to disable sector protection for all sectors.
+ */
+ WriteBuffer[BYTE1] = ReadBuffer[BYTE2] &
+ ~(XISF_SR_BLOCK_PROTECT_MASK);
+
+ /*
+ * Disable the sector protection.
+ */
+ TransferInProgress = TRUE;
+ Status = XIsf_SectorProtect(&Isf, XISF_SPR_WRITE, WriteBuffer);
+ 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;
+ }
+
+ /*
+ * The following code Reads data from a Page in the Intel Serial Flash.
+ */
+
+ /*
+ * 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.
+ * - Read Buffer to which the data is to be read.
+ */
+ ReadParam.Address = Address;
+ ReadParam.NumBytes = ISF_PAGE_SIZE;
+ ReadParam.ReadPtr = ReadBuffer;
+
+ /*
+ * Perform the read operation.
+ */
+ TransferInProgress = TRUE;
+ Status = XIsf_Read(&Isf, XISF_READ, (void*) &ReadParam);
+ 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;
+ }
+
+ /*
+ * Compare the data read against the data Written.
+ */
+ for(Index = 0; Index < ISF_PAGE_SIZE; Index++) {
+ if(ReadBuffer[Index + XISF_CMD_SEND_EXTRA_BYTES] !=
+ (u8)(Index + ISF_TEST_BYTE)) {
+ return XST_FAILURE;
+ }
+ }
+
+ 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 SPI 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 SPI data
+* completes or an error occurs.
+*
+* This handler provides an example of how to handle SPI interrupts and
+* is application specific.
+*
+* @param CallBackRef is the upper layer callback reference passed back
+* when the callback function is invoked.
+* @param StatusEvent is the event that just occurred.
+* @param ByteCount is the number of bytes transferred up until the event
+* occurred.
+*
+* @return None.
+*
+* @note None.
+*
+******************************************************************************/
+void SpiHandler(void *CallBackRef, u32 StatusEvent, u16 ByteCount)
+{
+ /*
+ * Indicate the transfer on the SPI bus is no longer in progress
+ * regardless of the status event.
+ */
+ TransferInProgress = FALSE;
+
+ /*
+ * If the event was not transfer done, then track it as an error.
+ */
+ if (StatusEvent != XST_SPI_TRANSFER_DONE) {
+ ErrorCount++;
+ }
+}
+
+/*****************************************************************************/
+/**
+*
+* This function setups the interrupt system such that interrupts can occur
+* for the Spi device. This function is application specific since the actual
+* system may or may not have an interrupt controller. The Spi device could be
+* directly connected to a processor without an interrupt controller. The
+* user should modify this function to fit the application.
+*
+* @param SpiPtr is a pointer to the instance of the Spi device.
+*
+* @return XST_SUCCESS if successful, otherwise XST_FAILURE.
+*
+* @note None
+*
+******************************************************************************/
+static int SetupInterruptSystem(XSpi *SpiPtr)
+{
+
+ int Status;
+
+ /*
+ * Initialize the interrupt controller driver so that
+ * it's ready to use, specify the device ID that is generated in
+ * xparameters.h
+ */
+ Status = XIntc_Initialize(&InterruptController, INTC_DEVICE_ID);
+ if(Status != XST_SUCCESS) {
+ return XST_FAILURE;
+ }
+
+ /*
+ * Connect a device driver handler that will be called when an interrupt
+ * for the device occurs, the device driver handler performs the
+ * specific interrupt processing for the device
+ */
+ Status = XIntc_Connect(&InterruptController,
+ SPI_INTR_ID,
+ (XInterruptHandler)XSpi_InterruptHandler,
+ (void *)SpiPtr);
+ if(Status != XST_SUCCESS) {
+ return XST_FAILURE;
+ }
+
+ /*
+ * Start the interrupt controller such that interrupts are enabled for
+ * all devices that cause interrupts, specific real mode so that
+ * the SPI can cause interrupts thru the interrupt controller.
+ */
+ Status = XIntc_Start(&InterruptController, XIN_REAL_MODE);
+ if(Status != XST_SUCCESS) {
+ return XST_FAILURE;
+ }
+
+ /*
+ * Enable the interrupt for the SPI.
+ */
+ XIntc_Enable(&InterruptController, SPI_INTR_ID);
+
+
+ /*
+ * Initialize the exception table.
+ */
+ Xil_ExceptionInit();
+
+ /*
+ * Register the interrupt controller handler with the exception table.
+ */
+ Xil_ExceptionRegisterHandler(XIL_EXCEPTION_ID_INT,
+ (Xil_ExceptionHandler)XIntc_InterruptHandler,
+ &InterruptController);
+
+ /*
+ * Enable non-critical exceptions.
+ */
+ Xil_ExceptionEnable();
+ return XST_SUCCESS;
+}
diff --git a/lib/sw_services/xilisf/examples/xilisf_qspips_stm_intr_example.c b/lib/sw_services/xilisf/examples/xilisf_qspips_stm_intr_example.c
new file mode 100644
index 00000000..bc3dbfd6
--- /dev/null
+++ b/lib/sw_services/xilisf/examples/xilisf_qspips_stm_intr_example.c
@@ -0,0 +1,864 @@
+/******************************************************************************
+*
+* Copyright (C) 2012 - 2014 Xilinx, Inc. All rights reserved.
+*
+* Permission is hereby granted, free of charge, to any person obtaining a copy
+* of this software and associated documentation files (the "Software"), to deal
+* in the Software without restriction, including without limitation the rights
+* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+* copies of the Software, and to permit persons to whom the Software is
+* furnished to do so, subject to the following conditions:
+*
+* The above copyright notice and this permission notice shall be included in
+* all copies or substantial portions of the Software.
+*
+* Use of the Software is limited solely to applications:
+* (a) running on a Xilinx device, or
+* (b) that interact with a Xilinx device through a bus or interconnect.
+*
+* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+* XILINX BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
+* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+* SOFTWARE.
+*
+* Except as contained in this notice, the name of the Xilinx shall not be used
+* in advertising or otherwise to promote the sale, use or other dealings in
+* this Software without prior written authorization from Xilinx.
+*
+******************************************************************************/
+/*****************************************************************************/
+/**
+*
+* @file xilisf_qspips_flash_intr_example.c
+*
+*
+* This file contains a design example using the XILISF Library in
+* interrupt mode with a serial FLASH device. This examples performs
+* some transfers in Auto mode and Manual start mode, to illustrate the modes
+* available.
+* The hardware which this example runs on, must have a serial FLASH (Numonyx
+* N25Q, Winbond W25Q, or Spansion S25FL) for it to run. This example has been
+* tested with the Numonyx Serial Flash (N25Q128).
+*
+* @note
+*
+* None.
+*
+*
+* MODIFICATION HISTORY:
+*
+* Ver Who Date Changes
+* ----- --- -------- -----------------------------------------------
+* 1.00 srt 06/20/12 First release
+* 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.
+*
+*
+*
+******************************************************************************/
+
+/***************************** Include Files *********************************/
+
+#include "xparameters.h" /**< EDK generated parameters */
+#include "xscugic.h" /**< Interrupt controller device driver */
+#include "xil_exception.h"
+#include "xil_printf.h"
+#include /**< 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
+ * change all the needed parameters in one place.
+ */
+#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 */
+
+/**
+ * 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 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 /**< Number of Pages for
+ Read/Write Operation */
+
+/**
+ * Flash address to which data is to be written.
+ */
+#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 /**< 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 /**< 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 *********************/
+
+/************************** Function Prototypes ******************************/
+
+static int QspiSetupIntrSystem(XScuGic *IntcInstancePtr,
+ XQspiPs *QspiInstancePtr, u16 QspiIntrId);
+
+static void QspiDisableIntrSystem(XScuGic *IntcInstancePtr, u16 QspiIntrId);
+
+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 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.
+ */
+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]; /**< 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.
+*
+* @return XST_SUCCESS if successful, otherwise XST_FAILURE.
+*
+* @note None
+*
+******************************************************************************/
+int main(void)
+{
+ int Status;
+
+ xil_printf("QSPI FLASH Interrupt Example Test \r\n");
+
+ /*
+ * Run the Qspi Interrupt example.
+ */
+ Status = QspiFlashIntrExample(&IntcInstance, &QspiInstance,
+ QSPI_DEVICE_ID, QSPI_INTR_ID);
+ if (Status != XST_SUCCESS) {
+ xil_printf("QSPI FLASH Interrupt Example Test Failed\r\n");
+ return XST_FAILURE;
+ }
+
+ xil_printf("Successfully ran QSPI FLASH Interrupt Example Test\r\n");
+ return XST_SUCCESS;
+}
+
+
+/****************************************************************************/
+/**
+* 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 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.
+*
+* @note
+*
+* This function calls other functions which contain loops that may be infinite
+* if interrupts are not working such that it may not return. If the device
+* slave select is not correct and the device is not responding on bus it will
+* read a status of 0xFF for the status register as the bus is pulled up.
+*
+*****************************************************************************/
+int QspiFlashIntrExample(XScuGic *IntcInstancePtr, XQspiPs *QspiInstancePtr,
+ u16 QspiDeviceId, u16 QspiIntrId)
+{
+ int Status;
+ u8 *BufferPtr;
+ u8 UniqueValue;
+ int Count;
+ int Page;
+ 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;
+ }
+
+ Status = XQspiPs_CfgInitialize(QspiInstancePtr, ConfigPtr,
+ ConfigPtr->BaseAddress);
+ if (Status != XST_SUCCESS) {
+ return XST_FAILURE;
+ }
+
+
+ /*
+ * Set the QSPI options
+ */
+ Options = XQSPIPS_FORCE_SSELECT_OPTION |
+ XQSPIPS_MANUAL_START_OPTION |
+ XQSPIPS_HOLD_B_DRIVE_OPTION;
+ Status = XIsf_SetSpiConfiguration(&Isf, QspiInstancePtr,
+ Options, XISF_SPI_PRESCALER);
+ if (Status != XST_SUCCESS) {
+ return XST_FAILURE;
+ }
+
+
+ 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);
+
+
+
+ XIsf_SetTransferMode(&Isf, XISF_INTERRUPT_MODE);
+
+ /*
+ * Connect the Qspi device to the interrupt subsystem such that
+ * interrupts can occur. This function is application specific
+ */
+ Status = QspiSetupIntrSystem(IntcInstancePtr, QspiInstancePtr,
+ QspiIntrId);
+ if (Status != XST_SUCCESS) {
+ return XST_FAILURE;
+ }
+
+ /*
+ * Setup the handler for the QSPI that will be called from the
+ * interrupt context when an QSPI status occurs, specify a pointer to
+ * the QSPI driver instance as the callback reference so the handler is
+ * able to access the instance data
+ */
+ 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
+ */
+ for (UniqueValue = UNIQUE_VALUE, Count = 0; Count < PAGE_SIZE;
+ Count++, UniqueValue++) {
+ WriteBuffer[Count] = (u8)(UniqueValue + Test);
+ }
+ memset(ReadBuffer, 0x00, sizeof(ReadBuffer));
+
+ 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);
+ }
+
+ /*
+ * Read the contents of the FLASH from TEST_ADDRESS, using Normal Read
+ * command
+ */
+ FlashRead(&Isf, TEST_ADDRESS, MAX_DATA, XISF_READ);
+
+ /*
+ * 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 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;
+ }
+ }
+
+ QspiDisableIntrSystem(IntcInstancePtr, QspiIntrId);
+
+ 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
+* completes or an error occurs.
+*
+* This handler provides an example of how to handle QSPI interrupts but is
+* application specific.
+*
+* @param CallBackRef is a reference passed to the handler.
+* @param StatusEvent is the status of the QSPI .
+* @param ByteCount is the number of bytes transferred.
+*
+* @return None
+*
+* @note None.
+*
+******************************************************************************/
+void XilIsf_Handler(void *CallBackRef, u32 StatusEvent, unsigned int ByteCount)
+{
+ /*
+ * Indicate the transfer on the QSPI bus is no longer in progress
+ * regardless of the status event
+ */
+ TransferInProgress = FALSE;
+
+ /*
+ * If the event was not transfer done, then track it as an error
+ */
+ if (StatusEvent != XST_SPI_TRANSFER_DONE) {
+ ErrorCount++;
+ }
+}
+
+/*****************************************************************************/
+/**
+*
+* 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
+* buffer must be in the same page of the device with page boundaries being on
+* 256 byte boundaries.
+*
+* @param InstancePtr is a pointer to the XIsf component to use.
+* @param Address contains the address to write data to in the FLASH.
+* @param ByteCount contains the number of bytes to write.
+* @param Command is the command used to write data to the flash.
+*
+* @return None.
+*
+* @note None.
+*
+******************************************************************************/
+int FlashWrite(XIsf *InstancePtr, u32 Address, u32 ByteCount, u8 Command)
+{
+ XIsf_WriteParam WriteParam;
+
+ int Status;
+
+ WriteParam.Address = Address;
+ WriteParam.NumBytes = ByteCount;
+ WriteParam.WritePtr = WriteBuffer;
+ /*
+ * Perform the Write operation.
+ */
+ TransferInProgress = TRUE;
+ Status = XIsf_Write(&Isf, Command, (void*) &WriteParam);
+ 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;
+ }
+
+ return XST_SUCCESS;
+}
+
+/*****************************************************************************/
+/**
+* This function reads from the serial FLASH connected to the
+* QSPI interface.
+*
+* @param InstancePtr is a pointer to the XIsf component to use.
+* @param Address contains the address to read data from in the FLASH.
+* @param ByteCount contains the number of bytes to read.
+* @param Command is the command used to read data from the flash.
+*
+* @return None.
+*
+* @note None.
+*
+******************************************************************************/
+int FlashRead(XIsf *InstancePtr, u32 Address, u32 ByteCount, u8 Command)
+{
+ XIsf_ReadParam ReadParam;
+ int Status;
+
+ /*
+ * 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.
+ * - 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.
+ */
+ TransferInProgress = TRUE;
+ Status = XIsf_Read(&Isf, Command, (void*) &ReadParam);
+ 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;
+ }
+ 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.
+* @param ByteCount contains the total size to be erased.
+*
+* @return None.
+*
+* @note None.
+*
+******************************************************************************/
+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 == (NumSectors * SectorSize)) {
+
+ /*
+ * Perform the Bulk Erase operation.
+ */
+
+ TransferInProgress = TRUE;
+ Status = XIsf_Erase(InstancePtr, XISF_BULK_ERASE, Address);
+ 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;
+ }
+
+ }
+
+ /*
+ * 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 < NumSect; Sector++) {
+
+ /*
+ * Perform the Bulk Erase operation.
+ */
+ TransferInProgress = TRUE;
+ Status = XIsf_Erase(InstancePtr, XISF_SECTOR_ERASE, Address);
+ 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;
+ }
+
+ Address += SectorSize;
+ }
+ return XST_SUCCESS;
+}
+
+
+/*****************************************************************************/
+/**
+*
+* This function setups the interrupt system for an Qspi device.
+*
+* @param IntcInstancePtr is a pointer to the instance of the Intc device.
+* @param QspiInstancePtr is a pointer to the instance of the Qspi device.
+* @param QspiIntrId is the interrupt Id for an QSPI device.
+*
+* @return XST_SUCCESS if successful, otherwise XST_FAILURE.
+*
+* @note None.
+*
+******************************************************************************/
+static int QspiSetupIntrSystem(XScuGic *IntcInstancePtr,
+ XQspiPs *QspiInstancePtr, u16 QspiIntrId)
+{
+ int Status;
+
+ XScuGic_Config *IntcConfig; /* Instance of the interrupt controller */
+
+ Xil_ExceptionInit();
+
+ /*
+ * Initialize the interrupt controller driver so that it is ready to
+ * use.
+ */
+ IntcConfig = XScuGic_LookupConfig(INTC_DEVICE_ID);
+ if (NULL == IntcConfig) {
+ return XST_FAILURE;
+ }
+
+ Status = XScuGic_CfgInitialize(IntcInstancePtr, IntcConfig,
+ IntcConfig->CpuBaseAddress);
+ if (Status != XST_SUCCESS) {
+ return XST_FAILURE;
+ }
+
+ /*
+ * Connect the interrupt controller interrupt handler to the hardware
+ * interrupt handling logic in the processor.
+ */
+ Xil_ExceptionRegisterHandler(XIL_EXCEPTION_ID_INT,
+ (Xil_ExceptionHandler)XScuGic_InterruptHandler,
+ IntcInstancePtr);
+
+ /*
+ * Connect the device driver handler that will be called when an
+ * interrupt for the device occurs, the handler defined above performs
+ * the specific interrupt processing for the device.
+ */
+ Status = XScuGic_Connect(IntcInstancePtr, QspiIntrId,
+ (Xil_ExceptionHandler)XQspiPs_InterruptHandler,
+ (void *)QspiInstancePtr);
+ if (Status != XST_SUCCESS) {
+ return Status;
+ }
+
+ /*
+ * Enable the interrupt for the Qspi device.
+ */
+ XScuGic_Enable(IntcInstancePtr, QspiIntrId);
+
+ /*
+ * Enable interrupts in the Processor.
+ */
+ Xil_ExceptionEnable();
+
+ return XST_SUCCESS;
+}
+
+/*****************************************************************************/
+/**
+*
+* This function disables the interrupts that occur for the Qspi device.
+*
+* @param IntcInstancePtr is the pointer to an INTC instance.
+* @param QspiIntrId is the interrupt Id for an QSPI device.
+*
+* @return None.
+*
+* @note None.
+*
+******************************************************************************/
+static void QspiDisableIntrSystem(XScuGic *IntcInstancePtr, u16 QspiIntrId)
+{
+ /*
+ * Disable the interrupt for the QSPI device.
+ */
+ XScuGic_Disable(IntcInstancePtr, QspiIntrId);
+
+ /*
+ * Disconnect and disable the interrupt for the Qspi device.
+ */
+ 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;
+}
diff --git a/lib/sw_services/xilisf/examples/xilisf_qspips_stm_polled_example.c b/lib/sw_services/xilisf/examples/xilisf_qspips_stm_polled_example.c
new file mode 100644
index 00000000..12ceaf88
--- /dev/null
+++ b/lib/sw_services/xilisf/examples/xilisf_qspips_stm_polled_example.c
@@ -0,0 +1,727 @@
+/******************************************************************************
+*
+* Copyright (C) 2012 - 2014 Xilinx, Inc. All rights reserved.
+*
+* Permission is hereby granted, free of charge, to any person obtaining a copy
+* of this software and associated documentation files (the "Software"), to deal
+* in the Software without restriction, including without limitation the rights
+* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+* copies of the Software, and to permit persons to whom the Software is
+* furnished to do so, subject to the following conditions:
+*
+* The above copyright notice and this permission notice shall be included in
+* all copies or substantial portions of the Software.
+*
+* Use of the Software is limited solely to applications:
+* (a) running on a Xilinx device, or
+* (b) that interact with a Xilinx device through a bus or interconnect.
+*
+* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+* XILINX BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
+* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+* SOFTWARE.
+*
+* Except as contained in this notice, the name of the Xilinx shall not be used
+* in advertising or otherwise to promote the sale, use or other dealings in
+* this Software without prior written authorization from Xilinx.
+*
+******************************************************************************/
+/*****************************************************************************/
+/**
+*
+* @file xilisf_qspips_flash_polled_example.c
+*
+*
+* This file contains a design example using the XILISF Library in
+* interrupt mode with a serial FLASH device. This examples performs
+* some transfers in Auto mode and Manual start mode, to illustrate the modes
+* available.
+* The hardware which this example runs on, must have a serial FLASH (Numonyx
+* N25Q, Winbond W25Q, or Spansion S25FL) for it to run. This example has been
+* tested with the Numonyx Serial Flash (N25Q128).
+*
+* @note
+*
+* None.
+*
+*
+* MODIFICATION HISTORY:
+*
+* Ver Who Date Changes
+* ----- --- -------- -----------------------------------------------
+* 1.00 srt 06/20/12 First release
+* 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.
+*
+*
+******************************************************************************/
+
+/***************************** Include Files *********************************/
+
+#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 */
+
+/************************** 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
+ * change all the needed parameters in one place.
+ */
+#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 */
+
+/**
+ * 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 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 32 /**< Number of Pages for r/w Operation */
+
+/**
+ * Flash address to which data is ot be written.
+ */
+#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 /**< 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 /**< 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 *********************/
+
+/************************** 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 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.
+ */
+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_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]; /**< 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.
+*
+* @return XST_SUCCESS if successful, otherwise XST_FAILURE.
+*
+* @note None
+*
+******************************************************************************/
+int main(void)
+{
+ int Status;
+
+ xil_printf("QSPI FLASH Polling Example Test \r\n");
+
+ /*
+ * Run the Qspi Interrupt example.
+ */
+ Status = QspiFlashPollExample(&IntcInstance, &QspiInstance,
+ QSPI_DEVICE_ID, QSPI_INTR_ID);
+ if (Status != XST_SUCCESS) {
+ xil_printf("QSPI FLASH Polling Example Test Failed\r\n");
+ return XST_FAILURE;
+ }
+
+ xil_printf("Successfully ran QSPI FLASH Polling Example Test\r\n");
+ return XST_SUCCESS;
+}
+
+
+/****************************************************************************/
+/**
+* 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.
+*
+* @return XST_SUCCESS if successful else XST_FAILURE.
+*
+* @note
+*
+* This function calls other functions which contain loops that may be infinite
+* if interrupts are not working such that it may not return. If the device
+* slave select is not correct and the device is not responding on bus it will
+* read a status of 0xFF for the status register as the bus is pulled up.
+*
+*****************************************************************************/
+int QspiFlashPollExample(XScuGic *IntcInstancePtr, XQspiPs *QspiInstancePtr,
+ u16 QspiDeviceId, u16 QspiIntrId)
+{
+ u8 *BufferPtr;
+ u8 UniqueValue;
+ int Count;
+ int Page;
+ 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;
+ }
+
+ Status = XQspiPs_CfgInitialize(QspiInstancePtr, ConfigPtr,
+ ConfigPtr->BaseAddress);
+ if (Status != XST_SUCCESS) {
+ return XST_FAILURE;
+ }
+
+ /*
+ * Set the QSPI options
+ */
+ Options = XQSPIPS_FORCE_SSELECT_OPTION |
+ XQSPIPS_MANUAL_START_OPTION |
+ XQSPIPS_HOLD_B_DRIVE_OPTION;
+ XIsf_SetSpiConfiguration(&Isf, QspiInstancePtr, Options,
+ XISF_SPI_PRESCALER);
+
+ 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);
+
+ /*
+ * 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
+ */
+ for (UniqueValue = UNIQUE_VALUE, Count = 0; Count < PAGE_SIZE;
+ Count++, UniqueValue++) {
+ WriteBuffer[Count] = (u8)(UniqueValue + Test_Polled);
+ }
+ memset(ReadBuffer, 0x00, sizeof(ReadBuffer));
+
+
+ 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++) {
+ 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
+ */
+ 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;
+ for (UniqueValue = UNIQUE_VALUE, Count = 0; Count < MAX_DATA;
+ 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;
+ }
+ }
+
+ 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
+* buffer must be in the same page of the device with page boundaries being on
+* 256 byte boundaries.
+*
+* @param InstancePtr is a pointer to the XIsf component to use.
+* @param Address contains the address to write data to in the FLASH.
+* @param ByteCount contains the number of bytes to write.
+* @param Command is the command used to write data to the flash.
+*
+* @return None.
+*
+* @note None.
+*
+******************************************************************************/
+int FlashWrite(XIsf *InstancePtr, u32 Address, u32 ByteCount,
+ u8 Command)
+{
+ XIsf_WriteParam WriteParam;
+
+ int Status;
+
+ WriteParam.Address = Address;
+ WriteParam.NumBytes = ByteCount;
+ WriteParam.WritePtr = WriteBuffer;
+
+ /*
+ * Perform the Write operation.
+ */
+ Status = XIsf_Write(&Isf, Command, (void*) &WriteParam);
+ if(Status != XST_SUCCESS) {
+ return XST_FAILURE;
+ }
+
+ return XST_SUCCESS;
+}
+
+/*****************************************************************************/
+/**
+* This function reads from the serial FLASH connected to the
+* QSPI interface.
+*
+* @param InstancePtr is a pointer to the XIsf component to use.
+* @param Address contains the address to read data from in the FLASH.
+* @param ByteCount contains the number of bytes to read.
+* @param Command is the command used to read data from the flash.
+*
+* @return None.
+*
+* @note None.
+*
+******************************************************************************/
+int FlashRead(XIsf *InstancePtr, u32 Address, u32 ByteCount, u8 Command)
+{
+ XIsf_ReadParam ReadParam;
+ int Status;
+
+ /*
+ * Set the
+ * - Address in the Serial Flash where the data is to be read from.
+ * - 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.
+ */
+ Status = XIsf_Read(&Isf, Command, (void*) &ReadParam);
+ if(Status != XST_SUCCESS) {
+ return XST_FAILURE;
+ }
+
+ 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.
+* @param ByteCount contains the total size to be erased.
+*
+* @return None.
+*
+* @note None.
+*
+******************************************************************************/
+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 == (NumSectors * SectorSize)) {
+
+#ifdef XPAR_XQSPIPS_0_DEVICE_ID
+ if(ConfigPtr->ConnectionMode ==
+ XQSPIPS_CONNECTION_MODE_STACKED){
+
+ /*
+ * 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 < NumSect; Sector++) {
+
+ /*
+ * Perform the Sector Erase operation.
+ */
+ Status = XIsf_Erase(InstancePtr, XISF_SECTOR_ERASE, Address);
+ if(Status != XST_SUCCESS) {
+ return XST_FAILURE;
+ }
+
+ Address += SectorSize;
+ }
+ return XST_SUCCESS;
+}
+
+/*****************************************************************************/
+/**
+*
+* 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;
+}
diff --git a/lib/sw_services/xilisf/examples/xilisf_spips_sst_intr_example.c b/lib/sw_services/xilisf/examples/xilisf_spips_sst_intr_example.c
new file mode 100644
index 00000000..e8a096e5
--- /dev/null
+++ b/lib/sw_services/xilisf/examples/xilisf_spips_sst_intr_example.c
@@ -0,0 +1,717 @@
+/******************************************************************************
+*
+* Copyright (C) 2012 - 2014 Xilinx, Inc. All rights reserved.
+*
+* Permission is hereby granted, free of charge, to any person obtaining a copy
+* of this software and associated documentation files (the "Software"), to deal
+* in the Software without restriction, including without limitation the rights
+* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+* copies of the Software, and to permit persons to whom the Software is
+* furnished to do so, subject to the following conditions:
+*
+* The above copyright notice and this permission notice shall be included in
+* all copies or substantial portions of the Software.
+*
+* Use of the Software is limited solely to applications:
+* (a) running on a Xilinx device, or
+* (b) that interact with a Xilinx device through a bus or interconnect.
+*
+* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+* XILINX BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
+* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+* SOFTWARE.
+*
+* Except as contained in this notice, the name of the Xilinx shall not be used
+* in advertising or otherwise to promote the sale, use or other dealings in
+* this Software without prior written authorization from Xilinx.
+*
+******************************************************************************/
+/*****************************************************************************/
+/**
+*
+* @file xilisf_spips_flash_intr_example.c
+*
+*
+* This file contains a design example using the XILISF Library in
+* interrupt mode with a serial FLASH device. This examples performs
+* some transfers in Auto mode and Manual start mode, to illustrate the modes
+* available.
+* The hardware which this example runs on, must have a serial FLASH (Numonyx
+* N25Q, Winbond W25Q, SST or Spansion S25FL) for it to run. This example has
+* been tested with the SST Flash.
+*
+* @note
+*
+* None.
+*
+*
+* MODIFICATION HISTORY:
+*
+* Ver Who Date Changes
+* ----- --- -------- -----------------------------------------------
+* 1.00 srt 06/20/12 First release
+* 3.01 srt 03/03/13 Modified the flash write, erase and read logic.
+* Ensured flash blocks are unprotected befor a flash erase
+* 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.
+*
+*
+******************************************************************************/
+
+/***************************** Include Files *********************************/
+
+#include "xparameters.h" /* EDK generated parameters */
+#include "xscugic.h" /* Interrupt controller device driver */
+#include "xil_exception.h"
+#include "xil_printf.h"
+#include
+
+/************************** Constant Definitions *****************************/
+
+/*
+ * The following constants map to the XPAR parameters created in the
+ * xparameters.h file. They are defined here such that a user can easily
+ * change all the needed parameters in one place.
+ */
+#define SPI_DEVICE_ID XPAR_XSPIPS_0_DEVICE_ID
+#define INTC_DEVICE_ID XPAR_SCUGIC_SINGLE_DEVICE_ID
+#define SPI_INTR_ID XPAR_XSPIPS_1_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 SPI 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_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 0x1000
+#define NUM_SECTORS 0x100
+
+/*
+ * Flash address to which data is to be written.
+ */
+#define TEST_ADDRESS 0x00
+#define UNIQUE_VALUE 0x05
+
+/*
+ * 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 SECTOR_SIZE * NUM_SECTORS
+
+/*
+ * The following constant defines the slave select signal that is used to
+ * to select the FLASH device on the SPI bus, this signal is typically
+ * connected to the chip select of the device
+ */
+#define FLASH_SPI_SELECT 0x01
+
+/**************************** Type Definitions *******************************/
+
+/***************** Macros (Inline Functions) Definitions *********************/
+
+/************************** Function Prototypes ******************************/
+
+static int SpiSetupIntrSystem(XScuGic *IntcInstancePtr,
+ XSpiPs *SpiInstancePtr, u16 SpiIntrId);
+
+static void SpiDisableIntrSystem(XScuGic *IntcInstancePtr, u16 SpiIntrId);
+
+void SpiHandler(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 SpiFlashIntrExample(XScuGic *IntcInstancePtr, XSpiPs *SpiInstancePtr,
+ u16 SpiDeviceId, u16 SpiIntrId);
+
+/************************** 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.
+ */
+static XScuGic IntcInstance;
+static XSpiPs SpiInstance;
+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 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[MAX_DATA + DATA_OFFSET];
+u8 IsfWriteBuffer[XISF_CMD_SEND_EXTRA_BYTES + 1];
+
+/*****************************************************************************/
+/**
+*
+* Main function to call the SPI Flash example.
+*
+* @param None
+*
+* @return XST_SUCCESS if successful, otherwise XST_FAILURE.
+*
+* @note None
+*
+******************************************************************************/
+int main(void)
+{
+ int Status;
+
+ xil_printf("SPI FLASH Interrupt Example Test \r\n");
+
+ /*
+ * Run the Spi Interrupt example.
+ */
+ Status = SpiFlashIntrExample(&IntcInstance, &SpiInstance,
+ SPI_DEVICE_ID, SPI_INTR_ID);
+ if (Status != XST_SUCCESS) {
+ xil_printf("SPI FLASH Interrupt Example Test Failed\r\n");
+ return XST_FAILURE;
+ }
+
+ xil_printf("Successfully ran SPI FLASH Interrupt Example Test\r\n");
+ return XST_SUCCESS;
+}
+
+/*****************************************************************************
+*
+* The purpose of this function is to illustrate how to use the XSpiPs
+* 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
+*
+* This function calls other functions which contain loops that may be infinite
+* if interrupts are not working such that it may not return. If the device
+* slave select is not correct and the device is not responding on bus it will
+* read a status of 0xFF for the status register as the bus is pulled up.
+*
+*****************************************************************************/
+int SpiFlashIntrExample(XScuGic *IntcInstancePtr, XSpiPs *SpiInstancePtr,
+ u16 SpiDeviceId, u16 SpiIntrId)
+{
+ int Status;
+ u8 *BufferPtr;
+ u8 UniqueValue;
+ u32 Count;
+ XSpiPs_Config *ConfigPtr; /* Pointer to Configuration ROM data */
+ u32 TempAddress;
+
+ /*
+ * Lookup the device configuration in the temporary CROM table. Use this
+ * configuration info down below when initializing this component.
+ */
+ ConfigPtr = XSpiPs_LookupConfig(SpiDeviceId);
+ if (ConfigPtr == NULL) {
+ return XST_DEVICE_NOT_FOUND;
+ }
+
+ XSpiPs_CfgInitialize(SpiInstancePtr, ConfigPtr,
+ ConfigPtr->BaseAddress);
+
+ /* Initialize the XILISF Library */
+ XIsf_Initialize(&Isf, SpiInstancePtr, FLASH_SPI_SELECT,
+ IsfWriteBuffer);
+
+ XIsf_SetTransferMode(&Isf, XISF_INTERRUPT_MODE);
+
+ /*
+ * Connect the Spi device to the interrupt subsystem such that
+ * interrupts can occur. This function is application specific
+ */
+ Status = SpiSetupIntrSystem(IntcInstancePtr, SpiInstancePtr,
+ SpiIntrId);
+ if (Status != XST_SUCCESS) {
+ return XST_FAILURE;
+ }
+
+ /*
+ * Setup the handler for the SPI that will be called from the
+ * interrupt context when an SPI status occurs, specify a pointer to
+ * the SPI driver instance as the callback reference so the handler is
+ * able to access the instance data
+ */
+ XIsf_SetStatusHandler(&Isf, SpiInstancePtr,
+ (XSpiPs_StatusHandler) SpiHandler);
+
+
+ memset(WriteBuffer, 0x00, sizeof(WriteBuffer));
+ memset(ReadBuffer, 0x00, sizeof(ReadBuffer));
+
+ /* Unprotect Sectors */
+ FlashWrite(&Isf, 0, 0, XISF_WRITE_STATUS_REG);
+
+ FlashErase(&Isf, TEST_ADDRESS, MAX_DATA);
+
+ /*
+ * 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
+ */
+ TempAddress = TEST_ADDRESS;
+ for (UniqueValue = UNIQUE_VALUE, Count = 0; Count < MAX_DATA;
+ Count++, UniqueValue++, TempAddress++) {
+ WriteBuffer[0] = (u8)(UniqueValue);
+ FlashWrite(&Isf, TempAddress, 1, XISF_WRITE);
+ }
+
+ /*
+ * Read the contents of the FLASH from TEST_ADDRESS, using Normal Read
+ * command
+ */
+ FlashRead(&Isf, TEST_ADDRESS, MAX_DATA, XISF_READ);
+
+ /*
+ * 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];
+
+ for (UniqueValue = UNIQUE_VALUE, Count = 0; Count < MAX_DATA;
+ Count++, UniqueValue++) {
+ if (BufferPtr[Count] != (u8)(UniqueValue)) {
+ return XST_FAILURE;
+ }
+ }
+
+ SpiDisableIntrSystem(IntcInstancePtr, SpiIntrId);
+ 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 SPI 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 SPI data
+* completes or an error occurs.
+*
+* This handler provides an example of how to handle SPI interrupts but is
+* application specific.
+*
+* @param CallBackRef is a reference passed to the handler.
+* @param StatusEvent is the status of the SPI .
+* @param ByteCount is the number of bytes transferred.
+*
+* @return None
+*
+* @note None.
+*
+******************************************************************************/
+void SpiHandler(void *CallBackRef, u32 StatusEvent, unsigned int ByteCount)
+{
+ /*
+ * Indicate the transfer on the SPI bus is no longer in progress
+ * regardless of the status event
+ */
+ TransferInProgress = FALSE;
+
+ /*
+ * If the event was not transfer done, then track it as an error
+ */
+ if (StatusEvent != XST_SPI_TRANSFER_DONE) {
+ ErrorCount++;
+ }
+}
+
+/******************************************************************************
+*
+*
+* This function writes to the serial FLASH connected to the SPI interface.
+*
+* @param InstancePtr is a pointer to the XIsf component to use.
+* @param Address contains the address to write data to in the FLASH.
+* @param ByteCount contains the number of bytes to write.
+* @param Command is the command used to write data to the flash. SPI
+* device supports Byte Program command to write data to the
+* flash.
+*
+* @return None.
+*
+* @note None.
+*
+******************************************************************************/
+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;
+ /*
+ * Perform the Write operation.
+ */
+ TransferInProgress = TRUE;
+ Status = XIsf_Write(&Isf, Command, (void*) &WriteParam);
+ 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;
+ }
+ return XST_SUCCESS;
+}
+
+/******************************************************************************
+*
+* This function reads from the serial FLASH connected to the
+* SPI interface.
+*
+* @param InstancePtr is a pointer to the XIsf component to use.
+* @param Address contains the address to read data from in the FLASH.
+* @param ByteCount contains the number of bytes to read.
+* @param Command is the command used to read data from the flash. SPI
+* device supports one of the Read, Fast Read, Dual Read and Fast
+* Read commands to read data from the flash.
+*
+* @return None.
+*
+* @note None.
+*
+******************************************************************************/
+int FlashRead(XIsf *InstancePtr, u32 Address, u32 ByteCount, u8 Command)
+{
+ XIsf_ReadParam ReadParam;
+ int Status;
+
+ /*
+ * 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.
+ * - Read Buffer to which the data is to be read.
+ */
+ ReadParam.Address = Address;
+ ReadParam.NumBytes = ByteCount;
+ ReadParam.ReadPtr = ReadBuffer;
+
+ /*
+ * Perform the Read operation.
+ */
+ TransferInProgress = TRUE;
+ Status = XIsf_Read(&Isf, Command, (void*) &ReadParam);
+ 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;
+ }
+ return XST_SUCCESS;
+}
+
+/******************************************************************************
+*
+*
+* This function erases the sectors in the serial FLASH connected to the SPI
+* 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.
+* @param ByteCount contains the total size to be erased.
+*
+* @return None.
+*
+* @note None.
+*
+******************************************************************************/
+int FlashErase(XIsf *InstancePtr, u32 Address, u32 ByteCount)
+{
+ int Status;
+ int Sector;
+
+ /*
+ * 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);
+
+ /*
+ * Perform the Sector Erase operation.
+ */
+ TransferInProgress = TRUE;
+ Status = XIsf_Erase(InstancePtr, XISF_SECTOR_ERASE, Address);
+ 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 += 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;
+ }
+ return XST_SUCCESS;
+}
+
+/*****************************************************************************/
+/**
+*
+* This function setups the interrupt system for an Spi device.
+*
+* @param IntcInstancePtr is a pointer to the instance of the Intc device.
+* @param SpiInstancePtr is a pointer to the instance of the Spi device.
+* @param SpiIntrId is the interrupt Id for an SPI device.
+*
+* @return XST_SUCCESS if successful, otherwise XST_FAILURE.
+*
+* @note None.
+*
+******************************************************************************/
+static int SpiSetupIntrSystem(XScuGic *IntcInstancePtr,
+ XSpiPs *SpiInstancePtr, u16 SpiIntrId)
+{
+ int Status;
+
+ XScuGic_Config *IntcConfig; /* Instance of the interrupt controller */
+
+ Xil_ExceptionInit();
+
+ /*
+ * Initialize the interrupt controller driver so that it is ready to
+ * use.
+ */
+ IntcConfig = XScuGic_LookupConfig(INTC_DEVICE_ID);
+ if (NULL == IntcConfig) {
+ return XST_FAILURE;
+ }
+
+ Status = XScuGic_CfgInitialize(IntcInstancePtr, IntcConfig,
+ IntcConfig->CpuBaseAddress);
+ if (Status != XST_SUCCESS) {
+ return XST_FAILURE;
+ }
+
+ /*
+ * Connect the interrupt controller interrupt handler to the hardware
+ * interrupt handling logic in the processor.
+ */
+ Xil_ExceptionRegisterHandler(XIL_EXCEPTION_ID_INT,
+ (Xil_ExceptionHandler)XScuGic_InterruptHandler,
+ IntcInstancePtr);
+
+ /*
+ * Connect the device driver handler that will be called when an
+ * interrupt for the device occurs, the handler defined above performs
+ * the specific interrupt processing for the device.
+ */
+ Status = XScuGic_Connect(IntcInstancePtr, SpiIntrId,
+ (Xil_ExceptionHandler)XSpiPs_InterruptHandler,
+ (void *)SpiInstancePtr);
+ if (Status != XST_SUCCESS) {
+ return Status;
+ }
+
+ /*
+ * Enable the interrupt for the Spi device.
+ */
+ XScuGic_Enable(IntcInstancePtr, SpiIntrId);
+
+ /*
+ * Enable interrupts in the Processor.
+ */
+ Xil_ExceptionEnable();
+
+ return XST_SUCCESS;
+}
+
+/*****************************************************************************/
+/**
+*
+* This function disables the interrupts that occur for the Spi device.
+*
+* @param IntcInstancePtr is the pointer to an INTC instance.
+* @param SpiIntrId is the interrupt Id for an SPI device.
+*
+* @return None.
+*
+* @note None.
+*
+******************************************************************************/
+static void SpiDisableIntrSystem(XScuGic *IntcInstancePtr, u16 SpiIntrId)
+{
+ /*
+ * Disable the interrupt for the SPI device.
+ */
+ XScuGic_Disable(IntcInstancePtr, SpiIntrId);
+
+ /*
+ * Disconnect and disable the interrupt for the Spi device.
+ */
+ XScuGic_Disconnect(IntcInstancePtr, SpiIntrId);
+}
diff --git a/lib/sw_services/xilisf/examples/xilisf_spips_sst_polled_example.c b/lib/sw_services/xilisf/examples/xilisf_spips_sst_polled_example.c
new file mode 100644
index 00000000..fcbb5cd3
--- /dev/null
+++ b/lib/sw_services/xilisf/examples/xilisf_spips_sst_polled_example.c
@@ -0,0 +1,480 @@
+/******************************************************************************
+*
+* Copyright (C) 2012 - 2014 Xilinx, Inc. All rights reserved.
+*
+* Permission is hereby granted, free of charge, to any person obtaining a copy
+* of this software and associated documentation files (the "Software"), to deal
+* in the Software without restriction, including without limitation the rights
+* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+* copies of the Software, and to permit persons to whom the Software is
+* furnished to do so, subject to the following conditions:
+*
+* The above copyright notice and this permission notice shall be included in
+* all copies or substantial portions of the Software.
+*
+* Use of the Software is limited solely to applications:
+* (a) running on a Xilinx device, or
+* (b) that interact with a Xilinx device through a bus or interconnect.
+*
+* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+* XILINX BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
+* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+* SOFTWARE.
+*
+* Except as contained in this notice, the name of the Xilinx shall not be used
+* in advertising or otherwise to promote the sale, use or other dealings in
+* this Software without prior written authorization from Xilinx.
+*
+******************************************************************************/
+/*****************************************************************************/
+/**
+*
+* @file xilisf_spips_flash_polled_example.c
+*
+* This file contains a design example using the XILISF Library in
+* interrupt mode with a serial FLASH device. This examples performs
+* some transfers in Auto mode and Manual start mode, to illustrate the modes
+* available.
+* The hardware which this example runs on, must have a serial FLASH (Numonyx
+* N25Q, Winbond W25Q, SST or Spansion S25FL) for it to run. This example has
+* been tested with the SST Flash.
+*
+* @note
+*
+* None.
+*
+*
+* MODIFICATION HISTORY:
+*
+* Ver Who Date Changes
+* ----- --- -------- -----------------------------------------------
+* 1.00 srt 06/20/12 First release
+* 3.01 srt 03/03/13 Modified the flash write, erase and read logic.
+* Ensured flash blocks are unprotected befor a flash erase
+* or write operation. (CR 703816)
+* 3.02 srt 04/26/13 Modified Erase function to perform Write Enable operation
+* for each sector erase.
+*
+*
+*
+******************************************************************************/
+
+/***************************** Include Files *********************************/
+
+#include "xparameters.h" /* EDK generated parameters */
+#include "xscugic.h" /* Interrupt controller device driver */
+#include "xil_exception.h"
+#include "xil_printf.h"
+#include
+
+/************************** Constant Definitions *****************************/
+
+/*
+ * The following constants map to the XPAR parameters created in the
+ * xparameters.h file. They are defined here such that a user can easily
+ * change all the needed parameters in one place.
+ */
+#define SPI_DEVICE_ID XPAR_XSPIPS_0_DEVICE_ID
+
+/*
+ * 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 SPI 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_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 0x1000
+#define NUM_SECTORS 0x100
+
+/*
+ * Flash address to which data is to be written.
+ */
+#define TEST_ADDRESS 0x00
+#define UNIQUE_VALUE 0x05
+/*
+ * 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 SECTOR_SIZE * NUM_SECTORS
+
+/*
+ * The following constant defines the slave select signal that is used to
+ * to select the FLASH device on the SPI bus, this signal is typically
+ * connected to the chip select of the device
+ */
+#define FLASH_SPI_SELECT 0x01
+
+/**************************** Type Definitions *******************************/
+
+/***************** Macros (Inline Functions) Definitions *********************/
+
+/************************** 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 SpiFlashPolledExample(XSpiPs *SpiInstancePtr, u16 SpiDeviceId);
+
+/************************** 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.
+ */
+static XSpiPs SpiInstance;
+static XIsf Isf;
+
+/*
+ * 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[MAX_DATA + DATA_OFFSET];
+u8 IsfWriteBuffer[XISF_CMD_SEND_EXTRA_BYTES + 1];
+
+/*****************************************************************************/
+/**
+*
+* Main function to call the SPI Flash example.
+*
+* @param None
+*
+* @return XST_SUCCESS if successful, otherwise XST_FAILURE.
+*
+* @note None
+*
+******************************************************************************/
+int main(void)
+{
+ int Status;
+
+ xil_printf("SPI FLASH Polled Example Test \r\n");
+
+ /*
+ * Run the Spi Interrupt example.
+ */
+ Status = SpiFlashPolledExample(&SpiInstance,SPI_DEVICE_ID);
+ if (Status != XST_SUCCESS) {
+ xil_printf("SPI FLASH Polled Example Test Failed\r\n");
+ return XST_FAILURE;
+ }
+
+ xil_printf("Successfully ran SPI FLASH Polled Example Test\r\n");
+ return XST_SUCCESS;
+}
+
+/*****************************************************************************
+*
+* The purpose of this function is to illustrate how to use the XSpiPs
+* 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
+*
+* This function calls other functions which contain loops that may be infinite
+* if interrupts are not working such that it may not return. If the device
+* slave select is not correct and the device is not responding on bus it will
+* read a status of 0xFF for the status register as the bus is pulled up.
+*
+*****************************************************************************/
+void FlashWriteSPI(XIsf *InstancePtr, u32 Address, u32 ByteCount, u8 Command);
+int SpiFlashPolledExample(XSpiPs *SpiInstancePtr,
+ u16 SpiDeviceId)
+{
+ u8 *BufferPtr;
+ u8 UniqueValue;
+ u32 Count;
+ XSpiPs_Config *ConfigPtr; /* Pointer to Configuration ROM data */
+ u32 TempAddress;
+
+ /*
+ * Lookup the device configuration in the temporary CROM table. Use this
+ * configuration info down below when initializing this component.
+ */
+ ConfigPtr = XSpiPs_LookupConfig(SpiDeviceId);
+ if (ConfigPtr == NULL) {
+ return XST_DEVICE_NOT_FOUND;
+ }
+
+ XSpiPs_CfgInitialize(SpiInstancePtr, ConfigPtr,
+ ConfigPtr->BaseAddress);
+
+ /* Initialize the XILISF Library */
+ XIsf_Initialize(&Isf, SpiInstancePtr, FLASH_SPI_SELECT,
+ IsfWriteBuffer);
+
+ memset(WriteBuffer, 0x00, sizeof(WriteBuffer));
+ memset(ReadBuffer, 0x00, sizeof(ReadBuffer));
+
+ /* Unprotect Sectors */
+ FlashWrite(&Isf, 0, 0, XISF_WRITE_STATUS_REG);
+
+ FlashErase(&Isf, TEST_ADDRESS, MAX_DATA);
+
+ /*
+ * 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
+ */
+ TempAddress = TEST_ADDRESS;
+ for (UniqueValue = UNIQUE_VALUE, Count = 0; Count < MAX_DATA;
+ Count++, UniqueValue++, TempAddress++) {
+ WriteBuffer[0] = (u8)(UniqueValue);
+ FlashWrite(&Isf, TempAddress, 1, XISF_WRITE);
+ }
+
+ /*
+ * Read the contents of the FLASH from TEST_ADDRESS, using Normal Read
+ * command
+ */
+ FlashRead(&Isf, TEST_ADDRESS, MAX_DATA, XISF_READ);
+
+ /*
+ * 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];
+
+ for (UniqueValue = UNIQUE_VALUE, Count = 0; Count < MAX_DATA;
+ Count++, UniqueValue++) {
+ if (BufferPtr[Count] != (u8)(UniqueValue)) {
+ return XST_FAILURE;
+ }
+ }
+
+ return XST_SUCCESS;
+}
+
+/*****************************************************************************/
+/**
+*
+* This function waits till the 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 SPI interface.
+*
+* @param InstancePtr is a pointer to the XIsf component to use.
+* @param Address contains the address to write data to in the FLASH.
+* @param ByteCount contains the number of bytes to write.
+* @param Command is the command used to write data to the flash.
+*
+* @return None.
+*
+* @note None.
+*
+******************************************************************************/
+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;
+
+ /*
+ * Perform the Write operation.
+ */
+ Status = XIsf_Write(&Isf, Command, (void*) &WriteParam);
+ if(Status != XST_SUCCESS) {
+ 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
+* SPI interface.
+*
+* @param InstancePtr is a pointer to the XIsf component to use.
+* @param Address contains the address to read data from in the FLASH.
+* @param ByteCount contains the number of bytes to read.
+* @param Command is the command used to read data from the flash.
+*
+* @return None.
+*
+* @note None.
+*
+******************************************************************************/
+int FlashRead(XIsf *InstancePtr, u32 Address, u32 ByteCount, u8 Command)
+{
+ XIsf_ReadParam ReadParam;
+ int Status;
+
+ /*
+ * 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.
+ * - Read Buffer to which the data is to be read.
+ */
+ ReadParam.Address = Address;
+ ReadParam.NumBytes = ByteCount;
+ ReadParam.ReadPtr = ReadBuffer;
+
+ /*
+ * Perform the Read operation.
+ */
+ Status = XIsf_Read(&Isf, Command, (void*) &ReadParam);
+ if(Status != XST_SUCCESS) {
+ return XST_FAILURE;
+ }
+
+ return XST_SUCCESS;
+}
+
+/******************************************************************************
+*
+*
+* This function erases the sectors in the serial FLASH connected to the
+* SPI 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.
+* @param ByteCount contains the total size to be erased.
+*
+* @return None.
+*
+* @note None.
+*
+******************************************************************************/
+int FlashErase(XIsf *InstancePtr, u32 Address, u32 ByteCount)
+{
+ int Status;
+ int Sector;
+
+ /*
+ * 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);
+
+ /*
+ * Perform the Sector Erase operation.
+ */
+ Status = XIsf_Erase(InstancePtr, XISF_SECTOR_ERASE, Address);
+ if(Status != XST_SUCCESS) {
+ 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 InstancePtr is a pointer to the XIsf component to use.
+*
+* @return XST_SUCCESS if successful else XST_FAILURE.
+*
+*
+******************************************************************************/
+int WriteEnable(XIsf *InstancePtr)
+{
+ int Status;
+
+ /*
+ * Perform the Write Enable operation.
+ */
+ Status = XIsf_WriteEnable(&Isf, XISF_WRITE_ENABLE);
+ if(Status != XST_SUCCESS) {
+ return XST_FAILURE;
+ }
+
+ /*
+ * Wait till the Flash is not Busy.
+ */
+ Status = IsfWaitForFlashNotBusy();
+ if(Status != XST_SUCCESS) {
+ return XST_FAILURE;
+ }
+ return XST_SUCCESS;
+}
diff --git a/lib/sw_services/xilisf/examples/xilisf_stm_quad_flash_example.c b/lib/sw_services/xilisf/examples/xilisf_stm_quad_flash_example.c
new file mode 100644
index 00000000..a965153b
--- /dev/null
+++ b/lib/sw_services/xilisf/examples/xilisf_stm_quad_flash_example.c
@@ -0,0 +1,972 @@
+/******************************************************************************
+*
+* Copyright (C) 2012 - 2014 Xilinx, Inc. All rights reserved.
+*
+* Permission is hereby granted, free of charge, to any person obtaining a copy
+* of this software and associated documentation files (the "Software"), to deal
+* in the Software without restriction, including without limitation the rights
+* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+* copies of the Software, and to permit persons to whom the Software is
+* furnished to do so, subject to the following conditions:
+*
+* The above copyright notice and this permission notice shall be included in
+* all copies or substantial portions of the Software.
+*
+* Use of the Software is limited solely to applications:
+* (a) running on a Xilinx device, or
+* (b) that interact with a Xilinx device through a bus or interconnect.
+*
+* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+* XILINX BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
+* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+* SOFTWARE.
+*
+* Except as contained in this notice, the name of the Xilinx shall not be used
+* in advertising or otherwise to promote the sale, use or other dealings in
+* this Software without prior written authorization from Xilinx.
+*
+******************************************************************************/
+/******************************************************************************
+*
+* @file xilisf_stm_quad_flash_example.c
+*
+* This file contains a design example using the In-system and Serial Flash
+* Library (XilIsf) for Reading/Writing to a STM (Numonyx) N25QXX Quad Serial
+* Flash Device. This example shows the Erase, Dual/Quad Read and Dual/Quad
+* Write features.
+*
+* This example
+* - Erases a Sector
+* - Writes to a Page within the Erased Sector
+* - Reads back the Page that is written and compares the data
+*
+* This example has been tested with a Numonyx Serial Flash Memory (N25Q128) on
+* a Xilinx KC705 board. For further details about the Flash device refer the
+* Numonyx Serial Flash Memory (N25Q128) data sheet.
+*
+* @note
+*
+* None.
+*
+*
+* MODIFICATION HISTORY:
+*
+* Ver Who Date Changes
+* ----- ---- -------- -----------------------------------------------
+* 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.
+*
+*
+******************************************************************************/
+
+/***************************** Include Files *********************************/
+
+#include "xparameters.h" /* EDK generated parameters */
+#include "xintc.h" /* Interrupt controller device driver */
+#include /* Serial Flash Library header file */
+#include "xil_exception.h"
+
+/************************** Constant Definitions *****************************/
+
+
+/*
+ * The following constants map to the XPAR parameters created in the
+ * xparameters.h file. They are defined here such that a user can easily
+ * change all the needed parameters in one place.
+ */
+#define SPI_DEVICE_ID XPAR_SPI_0_DEVICE_ID
+#define INTC_DEVICE_ID XPAR_INTC_0_DEVICE_ID
+#define SPI_INTR_ID XPAR_INTC_0_SPI_0_VEC_ID
+
+/*
+ * The following constant defines the slave select signal that is used to
+ * to select the Flash device on the SPI bus, this signal is typically
+ * connected to the chip select of the device.
+ */
+#define ISF_SPI_SELECT 0x01
+
+/*
+ * Number of bytes per page in the flash device.
+ */
+#define ISF_PAGE_SIZE 256
+
+/*
+ * Address of the page to perform Erase, Write and Read operations.
+ */
+#define ISF_TEST_ADDRESS 0x010000;
+#define ISF_TEST_BYTE 0x03 /* Test Byte value written */
+
+/*
+ * The following definitions specify the number of dummy bytes associated with
+ * various Read commands and the number of dummy bytes to ignore in the data
+ * read from the flash, through those Read commands. This is apart from the
+ * dummy bytes returned in response to the command and address transmitted.
+ */
+/*
+ * After transmitting Dual Read command and address on DIO0, the quad spi
+ * device configures DIO0 and DIO1 in input mode and receives data on both
+ * DIO0 and DIO1 for 8 dummy clock cycles. So we end up with 16 dummy bits
+ * in DRR. The same logic applies for Dual IO Read (8 dummy clock cycles =
+ * 16 dummy bits), Quad Read command (8 dummy clock cycles = 32 dummy bits)
+ * and Quad IO Read command (10 dummy clock cycles = 40 dummy bits)
+ */
+/*
+ * The number of dummy cycles is configurable in the flash device. Please refer
+ * to the flash datasheet for more details.
+ */
+#define DUAL_READ_DUMMY_BYTES 2
+#define DUAL_IO_READ_DUMMY_BYTES 2
+#define QUAD_READ_DUMMY_BYTES 4
+#define QUAD_IO_READ_DUMMY_BYTES 5
+
+/**************************** Type Definitions *******************************/
+
+/***************** Macros (Inline Functions) Definitions *********************/
+
+/************************** Function Prototypes ******************************/
+
+static int IsfWaitForFlashNotBusy(void);
+void SpiHandler(void *CallBackRef, u32 StatusEvent, u16 ByteCount);
+static int SetupInterruptSystem(XSpi *SpiPtr);
+
+/************************** 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.
+ */
+static XIsf Isf;
+static XIntc InterruptController;
+static XSpi Spi;
+
+/*
+ * The following variables are shared between non-interrupt processing and
+ * interrupt processing such that they must be global.
+ */
+volatile static int TransferInProgress; /* State of Spi Transfer */
+static int ErrorCount; /* Errors occurred during Spi transfers */
+
+/*
+ * The user needs to allocate a buffer to be used by the In-system and Serial
+ * Flash Library to perform any read/write operations on the Serial Flash
+ * device.
+ * User applications must pass the address of this memory to the Library in
+ * Serial Flash Initialization function, for the Library to work.
+ * For Write operations:
+ * - The size of this buffer should be equal to the Number of bytes to be
+ * written to the Serial Flash + XISF_CMD_MAX_EXTRA_BYTES.
+ * - The size of this buffer should be large enough for usage across all the
+ * applications that use a common instance of the Serial Flash.
+ * - A minimum of one byte and a maximum of ISF_PAGE_SIZE bytes can be written
+ * to the Serial Flash, through a single Write operation.
+ * The size of this buffer should be equal to XISF_CMD_MAX_EXTRA_BYTES, if the
+ * application only reads from the Serial Flash (no write operations).
+ */
+u8 IsfWriteBuffer[ISF_PAGE_SIZE + XISF_CMD_SEND_EXTRA_BYTES];
+
+/*
+ * Buffers used during Read/Write transactions.
+ */
+u8 ReadBuffer[ISF_PAGE_SIZE + XISF_CMD_SEND_EXTRA_BYTES + 5]; /* Read Buffer */
+u8 WriteBuffer[ISF_PAGE_SIZE]; /* Write buffer */
+
+/************************** Function Definitions ******************************/
+
+/*****************************************************************************/
+/**
+*
+* Main function to execute the Numonyx Quad Serial Flash Read/Write example.
+*
+* @param None
+*
+* @return XST_SUCCESS if successful else XST_FAILURE.
+*
+* @note None
+*
+******************************************************************************/
+int main()
+{
+ int Status;
+ u32 Index;
+ u32 Address;
+ XIsf_WriteParam WriteParam;
+ XIsf_ReadParam ReadParam;
+
+ /*
+ * Initialize the SPI driver so that it's ready to use,
+ * specify the device ID that is generated in xparameters.h.
+ */
+ Status = XSpi_Initialize(&Spi, SPI_DEVICE_ID);
+ if(Status != XST_SUCCESS) {
+ return XST_FAILURE;
+ }
+
+ /*
+ * Connect the SPI driver to the interrupt subsystem such that
+ * interrupts can occur. This function is application specific.
+ */
+ Status = SetupInterruptSystem(&Spi);
+ if(Status != XST_SUCCESS) {
+ return XST_FAILURE;
+ }
+
+ /*
+ * Setup the handler for the SPI that will be called from the interrupt
+ * context when an SPI status occurs, specify a pointer to the SPI
+ * driver instance as the callback reference so the handler is able to
+ * access the instance data.
+ */
+ XIsf_SetStatusHandler(&Isf, &Spi, (XSpi_StatusHandler)SpiHandler);
+
+ /*
+ * Start the SPI driver so that interrupts and the device are enabled.
+ */
+ XSpi_Start(&Spi);
+
+ /*
+ * Set the QSPI options
+ */
+ Status = XIsf_SetSpiConfiguration(&Isf, &Spi,
+ XSP_MASTER_OPTION | XSP_MANUAL_SSELECT_OPTION,
+ XISF_SPI_PRESCALER);
+ if(Status != XST_SUCCESS) {
+ return XST_FAILURE;
+ }
+
+ /*
+ * Initialize the Serial Flash Library.
+ */
+ Status = XIsf_Initialize(&Isf, &Spi, ISF_SPI_SELECT, IsfWriteBuffer);
+ if(Status != XST_SUCCESS) {
+ 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.
+ */
+ Address = ISF_TEST_ADDRESS;
+
+ /*
+ * The following code Erases a Sector in the Numonyx Serial Flash.
+ */
+
+ /*
+ * 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 for errors.
+ */
+ while(TransferInProgress);
+ if(ErrorCount != 0) {
+ return XST_FAILURE;
+ }
+
+ /*
+ * Wait till the Flash is not Busy.
+ */
+ Status = IsfWaitForFlashNotBusy();
+ if(Status != XST_SUCCESS) {
+ return XST_FAILURE;
+ }
+
+ /*
+ * Perform the Sector Erase operation.
+ */
+ TransferInProgress = TRUE;
+ Status = XIsf_Erase(&Isf, XISF_SECTOR_ERASE, Address);
+ if(Status != XST_SUCCESS) {
+ return XST_FAILURE;
+ }
+
+ /*
+ * Wait till the Transfer is complete and check for errors.
+ */
+ while(TransferInProgress);
+ if(ErrorCount != 0) {
+ return XST_FAILURE;
+ }
+
+ /*
+ * Wait till the Flash is not Busy.
+ */
+ Status = IsfWaitForFlashNotBusy();
+ if(Status != XST_SUCCESS) {
+ return XST_FAILURE;
+ }
+
+ /*
+ * 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 for errors.
+ */
+ while(TransferInProgress);
+ if(ErrorCount != 0) {
+ return XST_FAILURE;
+ }
+
+ /*
+ * Wait till the Flash is not Busy.
+ */
+ Status = IsfWaitForFlashNotBusy();
+ if(Status != XST_SUCCESS) {
+ return XST_FAILURE;
+ }
+
+ /*
+ * Set the
+ * - Address within the Serial Flash where the data is to be written.
+ * - Number of bytes to be written to the Serial Flash.
+ * - Write Buffer which contains the data to be written to the Serial
+ * Flash.
+ */
+ WriteParam.Address = Address;
+ WriteParam.NumBytes = ISF_PAGE_SIZE;
+ WriteParam.WritePtr = WriteBuffer;
+
+ /*
+ * Prepare the write buffer. Fill in the data need to be written into
+ * Serial Flash.
+ */
+ for(Index = 0; Index < ISF_PAGE_SIZE; Index++) {
+ WriteParam.WritePtr[Index] = Index + ISF_TEST_BYTE;
+ }
+
+ /*
+ * Perform the Write operation.
+ */
+ TransferInProgress = TRUE;
+ Status = XIsf_Write(&Isf, XISF_DUAL_IP_PAGE_WRITE, (void*) &WriteParam);
+ if(Status != XST_SUCCESS) {
+ return XST_FAILURE;
+ }
+
+ /*
+ * Wait till the Transfer is complete and check for errors.
+ */
+ while(TransferInProgress);
+ if(ErrorCount != 0) {
+ return XST_FAILURE;
+ }
+
+ /*
+ * Wait till the Flash is not Busy.
+ */
+ Status = IsfWaitForFlashNotBusy();
+ if(Status != XST_SUCCESS) {
+ return XST_FAILURE;
+ }
+
+ /*
+ * Read from the flash using Dual Output Fast Read 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.
+ * - Read Buffer to which the data is to be read.
+ * - Number of dummy bytes for the read command.
+ */
+ ReadParam.Address = Address;
+ ReadParam.NumBytes = ISF_PAGE_SIZE;
+ ReadParam.ReadPtr = ReadBuffer;
+ ReadParam.NumDummyBytes = DUAL_READ_DUMMY_BYTES;
+
+ /*
+ * Clear the read Buffer.
+ */
+ for(Index = 0; Index < ISF_PAGE_SIZE + XISF_CMD_SEND_EXTRA_BYTES +
+ DUAL_READ_DUMMY_BYTES; Index++) {
+ ReadBuffer[Index] = 0x0;
+ }
+
+ /*
+ * Perform the read operation.
+ */
+ TransferInProgress = TRUE;
+ Status = XIsf_Read(&Isf, XISF_DUAL_OP_FAST_READ, (void*) &ReadParam);
+ if(Status != XST_SUCCESS) {
+ return XST_FAILURE;
+ }
+
+ /*
+ * Wait till the Transfer is complete and check for errors.
+ */
+ while(TransferInProgress);
+ if(ErrorCount != 0) {
+ return XST_FAILURE;
+ }
+
+ /*
+ * Compare the data read against the data Written.
+ */
+ for(Index = 0; Index < ISF_PAGE_SIZE; Index++) {
+ if(ReadBuffer[Index + XISF_CMD_SEND_EXTRA_BYTES +
+ DUAL_READ_DUMMY_BYTES] !=
+ (u8)(Index + ISF_TEST_BYTE)) {
+ return XST_FAILURE;
+ }
+ }
+
+ /*
+ * 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 for errors.
+ */
+ while(TransferInProgress);
+ if(ErrorCount != 0) {
+ return XST_FAILURE;
+ }
+
+ /*
+ * Wait till the Flash is not Busy.
+ */
+ Status = IsfWaitForFlashNotBusy();
+ if(Status != XST_SUCCESS) {
+ return XST_FAILURE;
+ }
+
+ /*
+ * Move to the next page in the flash.
+ */
+ Address += ISF_PAGE_SIZE;
+
+ /*
+ * Set the
+ * - Address within the Serial Flash where the data is to be written.
+ * - Number of bytes to be written to the Serial Flash.
+ * - Write Buffer which contains the data to be written to the Serial
+ * Flash.
+ */
+ WriteParam.Address = Address;
+ WriteParam.NumBytes = ISF_PAGE_SIZE;
+ WriteParam.WritePtr = WriteBuffer;
+
+ /*
+ * Prepare the write buffer. Fill in the data need to be written into
+ * Serial Flash.
+ */
+ for(Index = 0; Index < ISF_PAGE_SIZE; Index++) {
+ WriteParam.WritePtr[Index] = Index + ISF_TEST_BYTE;
+ }
+
+ /*
+ * Perform the Write operation.
+ */
+ TransferInProgress = TRUE;
+ Status = XIsf_Write(&Isf, XISF_DUAL_IP_EXT_PAGE_WRITE, (void*) &WriteParam);
+ if(Status != XST_SUCCESS) {
+ return XST_FAILURE;
+ }
+
+ /*
+ * Wait till the Transfer is complete and check for errors.
+ */
+ while(TransferInProgress);
+ if(ErrorCount != 0) {
+ return XST_FAILURE;
+ }
+
+ /*
+ * Wait till the Flash is not Busy.
+ */
+ Status = IsfWaitForFlashNotBusy();
+ if(Status != XST_SUCCESS) {
+ return XST_FAILURE;
+ }
+
+ /*
+ * Read from the flash using Dual Input/Output Fast Read 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.
+ * - Read Buffer to which the data is to be read.
+ * - Number of dummy bytes for the read command.
+ */
+ ReadParam.Address = Address;
+ ReadParam.NumBytes = ISF_PAGE_SIZE;
+ ReadParam.ReadPtr = ReadBuffer;
+ ReadParam.NumDummyBytes = DUAL_IO_READ_DUMMY_BYTES;
+
+ /*
+ * Clear the read Buffer.
+ */
+ for(Index = 0; Index < ISF_PAGE_SIZE + XISF_CMD_SEND_EXTRA_BYTES +
+ DUAL_IO_READ_DUMMY_BYTES; Index++) {
+ ReadBuffer[Index] = 0x0;
+ }
+
+ /*
+ * Perform the read operation.
+ */
+ TransferInProgress = TRUE;
+ Status = XIsf_Read(&Isf, XISF_DUAL_IO_FAST_READ, (void*) &ReadParam);
+ if(Status != XST_SUCCESS) {
+ return XST_FAILURE;
+ }
+
+ /*
+ * Wait till the Transfer is complete and check for errors.
+ */
+ while(TransferInProgress);
+ if(ErrorCount != 0) {
+ return XST_FAILURE;
+ }
+
+ /*
+ * Compare the data read against the data Written.
+ */
+ for(Index = 0; Index < ISF_PAGE_SIZE; Index++) {
+ if(ReadBuffer[Index + XISF_CMD_SEND_EXTRA_BYTES +
+ DUAL_IO_READ_DUMMY_BYTES] !=
+ (u8)(Index + ISF_TEST_BYTE)) {
+ return XST_FAILURE;
+ }
+ }
+
+ /*
+ * 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 for errors.
+ */
+ while(TransferInProgress);
+ if(ErrorCount != 0) {
+ return XST_FAILURE;
+ }
+
+ /*
+ * Wait till the Flash is not Busy.
+ */
+ Status = IsfWaitForFlashNotBusy();
+ if(Status != XST_SUCCESS) {
+ return XST_FAILURE;
+ }
+
+ /*
+ * Move to the next page in the flash.
+ */
+ Address += ISF_PAGE_SIZE;
+
+ /*
+ * Set the
+ * - Address within the Serial Flash where the data is to be written.
+ * - Number of bytes to be written to the Serial Flash.
+ * - Write Buffer which contains the data to be written to the Serial
+ * Flash.
+ */
+ WriteParam.Address = Address;
+ WriteParam.NumBytes = ISF_PAGE_SIZE;
+ WriteParam.WritePtr = WriteBuffer;
+
+ /*
+ * Prepare the write buffer. Fill in the data need to be written into
+ * Serial Flash.
+ */
+ for(Index = 0; Index < ISF_PAGE_SIZE; Index++) {
+ WriteParam.WritePtr[Index] = Index + ISF_TEST_BYTE;
+ }
+
+ /*
+ * Perform the Write operation.
+ */
+ TransferInProgress = TRUE;
+ Status = XIsf_Write(&Isf, XISF_QUAD_IP_PAGE_WRITE, (void*) &WriteParam);
+ if(Status != XST_SUCCESS) {
+ return XST_FAILURE;
+ }
+
+ /*
+ * Wait till the Transfer is complete and check for errors.
+ */
+ while(TransferInProgress);
+ if(ErrorCount != 0) {
+ return XST_FAILURE;
+ }
+
+ /*
+ * Wait till the Flash is not Busy.
+ */
+ Status = IsfWaitForFlashNotBusy();
+ if(Status != XST_SUCCESS) {
+ return XST_FAILURE;
+ }
+
+ /*
+ * Read from the flash using Quad Output Fast Read 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.
+ * - Read Buffer to which the data is to be read.
+ * - Number of dummy bytes for the read command.
+ */
+ ReadParam.Address = Address;
+ ReadParam.NumBytes = ISF_PAGE_SIZE;
+ ReadParam.ReadPtr = ReadBuffer;
+ ReadParam.NumDummyBytes = QUAD_READ_DUMMY_BYTES;
+
+ /*
+ * Clear the read Buffer.
+ */
+ for(Index = 0; Index < ISF_PAGE_SIZE + XISF_CMD_SEND_EXTRA_BYTES +
+ QUAD_READ_DUMMY_BYTES; Index++) {
+ ReadBuffer[Index] = 0x0;
+ }
+
+ /*
+ * Perform the read operation.
+ */
+ TransferInProgress = TRUE;
+ Status = XIsf_Read(&Isf, XISF_QUAD_OP_FAST_READ, (void*) &ReadParam);
+ if(Status != XST_SUCCESS) {
+ return XST_FAILURE;
+ }
+
+ /*
+ * Wait till the Transfer is complete and check for errors.
+ */
+ while(TransferInProgress);
+ if(ErrorCount != 0) {
+ return XST_FAILURE;
+ }
+
+ /*
+ * Compare the data read against the data Written.
+ */
+ for(Index = 0; Index < ISF_PAGE_SIZE; Index++) {
+ if(ReadBuffer[Index + XISF_CMD_SEND_EXTRA_BYTES +
+ QUAD_READ_DUMMY_BYTES] !=
+ (u8)(Index + ISF_TEST_BYTE)) {
+ return XST_FAILURE;
+ }
+ }
+
+ /*
+ * 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 for errors.
+ */
+ while(TransferInProgress);
+ if(ErrorCount != 0) {
+ return XST_FAILURE;
+ }
+
+ /*
+ * Wait till the Flash is not Busy.
+ */
+ Status = IsfWaitForFlashNotBusy();
+ if(Status != XST_SUCCESS) {
+ return XST_FAILURE;
+ }
+
+ /*
+ * Move to the next page in the flash.
+ */
+ Address += ISF_PAGE_SIZE;
+
+ /*
+ * Set the
+ * - Address within the Serial Flash where the data is to be written.
+ * - Number of bytes to be written to the Serial Flash.
+ * - Write Buffer which contains the data to be written to the Serial
+ * Flash.
+ */
+ WriteParam.Address = Address;
+ WriteParam.NumBytes = ISF_PAGE_SIZE;
+ WriteParam.WritePtr = WriteBuffer;
+
+ /*
+ * Prepare the write buffer. Fill in the data need to be written into
+ * Serial Flash.
+ */
+ for(Index = 0; Index < ISF_PAGE_SIZE; Index++) {
+ WriteParam.WritePtr[Index] = Index + ISF_TEST_BYTE;
+ }
+
+ /*
+ * Perform the Write operation.
+ */
+ TransferInProgress = TRUE;
+ Status = XIsf_Write(&Isf, XISF_QUAD_IP_EXT_PAGE_WRITE,
+ (void*) &WriteParam);
+ if(Status != XST_SUCCESS) {
+ return XST_FAILURE;
+ }
+
+ /*
+ * Wait till the Transfer is complete and check for errors.
+ */
+ while(TransferInProgress);
+ if(ErrorCount != 0) {
+ return XST_FAILURE;
+ }
+
+ /*
+ * Wait till the Flash is not Busy.
+ */
+ Status = IsfWaitForFlashNotBusy();
+ if(Status != XST_SUCCESS) {
+ return XST_FAILURE;
+ }
+
+ /*
+ * Read from the flash using Quad Input/Output Fast Read 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.
+ * - Read Buffer to which the data is to be read.
+ * - Number of dummy bytes for the read command.
+ */
+ ReadParam.Address = Address;
+ ReadParam.NumBytes = ISF_PAGE_SIZE;
+ ReadParam.ReadPtr = ReadBuffer;
+ ReadParam.NumDummyBytes = QUAD_IO_READ_DUMMY_BYTES;
+
+ /*
+ * Clear the read Buffer.
+ */
+ for(Index = 0; Index < ISF_PAGE_SIZE + XISF_CMD_SEND_EXTRA_BYTES +
+ QUAD_IO_READ_DUMMY_BYTES; Index++) {
+ ReadBuffer[Index] = 0x0;
+ }
+
+ /*
+ * Perform the read operation.
+ */
+ TransferInProgress = TRUE;
+ Status = XIsf_Read(&Isf, XISF_QUAD_IO_FAST_READ, (void*) &ReadParam);
+ if(Status != XST_SUCCESS) {
+ return XST_FAILURE;
+ }
+
+ /*
+ * Wait till the Transfer is complete and check for errors.
+ */
+ while(TransferInProgress);
+ if(ErrorCount != 0) {
+ return XST_FAILURE;
+ }
+
+ /*
+ * Compare the data read against the data written.
+ */
+ for(Index = 0; Index < ISF_PAGE_SIZE; Index++) {
+ if(ReadBuffer[Index + XISF_CMD_SEND_EXTRA_BYTES +
+ QUAD_IO_READ_DUMMY_BYTES] !=
+ (u8)(Index + ISF_TEST_BYTE)) {
+ return XST_FAILURE;
+ }
+ }
+
+ return XST_SUCCESS;
+}
+
+/*****************************************************************************/
+/**
+*
+* This function waits till the Numonyx 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 Serial Flash is ready to accept next command.
+*
+******************************************************************************/
+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 complete and check for errors.
+ */
+ while(TransferInProgress);
+ if(ErrorCount != 0) {
+ return XST_FAILURE;
+ }
+
+ /*
+ * Check if the Serial 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 SPI 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 SPI data
+* completes or an error occurs.
+*
+* This handler provides an example of how to handle SPI interrupts and
+* is application specific.
+*
+* @param CallBackRef is the upper layer callback reference passed back
+* when the callback function is invoked.
+* @param StatusEvent is the event that just occurred.
+* @param ByteCount is the number of bytes transferred up until the event
+* occurred.
+*
+* @return None.
+*
+* @note None.
+*
+******************************************************************************/
+void SpiHandler(void *CallBackRef, u32 StatusEvent, u16 ByteCount)
+{
+ /*
+ * Indicate the transfer on the SPI bus is no longer in progress
+ * regardless of the status event.
+ */
+ TransferInProgress = FALSE;
+
+ /*
+ * If the event was not transfer done, then track it as an error.
+ */
+ if (StatusEvent != XST_SPI_TRANSFER_DONE) {
+ ErrorCount++;
+ }
+}
+
+/*****************************************************************************/
+/**
+*
+* This function setups the interrupt system such that interrupts can occur
+* for the Spi device. This function is application specific since the actual
+* system may or may not have an interrupt controller. The Spi device could be
+* directly connected to a processor without an interrupt controller. The
+* user should modify this function to fit the application.
+*
+* @param SpiPtr is a pointer to the instance of the Spi device.
+*
+* @return XST_SUCCESS if successful, otherwise XST_FAILURE.
+*
+* @note None
+*
+******************************************************************************/
+static int SetupInterruptSystem(XSpi *SpiPtr)
+{
+
+ int Status;
+
+ /*
+ * Initialize the interrupt controller driver so that
+ * it's ready to use, specify the device ID that is generated in
+ * xparameters.h
+ */
+ Status = XIntc_Initialize(&InterruptController, INTC_DEVICE_ID);
+ if(Status != XST_SUCCESS) {
+ return XST_FAILURE;
+ }
+
+ /*
+ * Connect a device driver handler that will be called when an interrupt
+ * for the device occurs, the device driver handler performs the
+ * specific interrupt processing for the device
+ */
+ Status = XIntc_Connect(&InterruptController,
+ SPI_INTR_ID,
+ (XInterruptHandler)XSpi_InterruptHandler,
+ (void *)SpiPtr);
+ if(Status != XST_SUCCESS) {
+ return XST_FAILURE;
+ }
+
+ /*
+ * Start the interrupt controller such that interrupts are enabled for
+ * all devices that cause interrupts, specify real mode so that
+ * the SPI can cause interrupts through the interrupt controller.
+ */
+ Status = XIntc_Start(&InterruptController, XIN_REAL_MODE);
+ if(Status != XST_SUCCESS) {
+ return XST_FAILURE;
+ }
+
+ /*
+ * Enable the interrupt for the SPI.
+ */
+ XIntc_Enable(&InterruptController, SPI_INTR_ID);
+
+ /*
+ * Initialize the exception table.
+ */
+ Xil_ExceptionInit();
+
+ /*
+ * Register the interrupt controller handler with the exception table.
+ */
+ Xil_ExceptionRegisterHandler(XIL_EXCEPTION_ID_INT,
+ (Xil_ExceptionHandler)XIntc_InterruptHandler,
+ &InterruptController);
+
+ /*
+ * Enable non-critical exceptions.
+ */
+ Xil_ExceptionEnable();
+
+ return XST_SUCCESS;
+}
diff --git a/lib/sw_services/xilisf/examples/xilisf_stm_rdwr_polled_example.c b/lib/sw_services/xilisf/examples/xilisf_stm_rdwr_polled_example.c
new file mode 100644
index 00000000..f3cb252e
--- /dev/null
+++ b/lib/sw_services/xilisf/examples/xilisf_stm_rdwr_polled_example.c
@@ -0,0 +1,383 @@
+/******************************************************************************
+*
+* Copyright (C) 2012 - 2015 Xilinx, Inc. All rights reserved.
+*
+* Permission is hereby granted, free of charge, to any person obtaining a copy
+* of this software and associated documentation files (the "Software"), to deal
+* in the Software without restriction, including without limitation the rights
+* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+* copies of the Software, and to permit persons to whom the Software is
+* furnished to do so, subject to the following conditions:
+*
+* The above copyright notice and this permission notice shall be included in
+* all copies or substantial portions of the Software.
+*
+* Use of the Software is limited solely to applications:
+* (a) running on a Xilinx device, or
+* (b) that interact with a Xilinx device through a bus or interconnect.
+*
+* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+* XILINX BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
+* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+* SOFTWARE.
+*
+* Except as contained in this notice, the name of the Xilinx shall not be used
+* in advertising or otherwise to promote the sale, use or other dealings in
+* this Software without prior written authorization from Xilinx.
+*
+******************************************************************************/
+/******************************************************************************
+*
+* @file xilisf_stm_rdwr_polled_example.c
+*
+* This file contains a design example using the In-system and Serial Flash
+* Library (XilIsf) for Reading/Writing to a STM (Numonyx) M25P16 Serial Flash
+* Device with the Spi driver in polled mode of operation. This example shows
+* the Erase, Read and Write features.
+*
+* This example
+* - Erases a Sector
+* - Writes to a Page within the Erased Sector
+* - Reads back the Page that is written and compares the data.
+*
+* This example has been tested with a STM (Numonyx) M25P16 device on a Xilinx
+* Spartan-3A Starter Kit board and AC701 board with a Micron flash N25Q256A
+* (32MB, supporting 4 Byte addressing mode).
+*
+*
+* @note
+*
+* None.
+*
+*
+* MODIFICATION HISTORY:
+*
+* Ver Who Date Changes
+* ----- --- -------- -----------------------------------------------
+* 1.00a sdm 04/02/08 First release
+* 2.00a ktn 11/22/09 The Spi Driver APIs have changed. Replaced the call
+* to XSpi_mIntrGlobalDisable with XSpi_IntrGlobalDisable.
+* 5.2 asa 05/12/15 Added support for Micron N25Q256A flash part which
+* supports 4 byte addressing.
+*
+*
+******************************************************************************/
+
+/***************************** Include Files *********************************/
+
+#include "xparameters.h" /* EDK generated parameters */
+#include "xilisf.h" /* Serial Flash Library header file */
+
+/************************** Constant Definitions *****************************/
+
+
+/*
+ * The following constants map to the XPAR parameters created in the
+ * xparameters.h file. They are defined here such that a user can easily
+ * change all the needed parameters in one place.
+ */
+#define SPI_DEVICE_ID XPAR_SPI_0_DEVICE_ID
+
+/*
+ * The following constant defines the slave select signal that is used to
+ * to select the Flash device on the SPI bus, this signal is typically
+ * connected to the chip select of the device.
+ */
+#define ISF_SPI_SELECT 0x01
+
+/*
+ * Number of bytes per page in the flash device.
+ */
+#define ISF_PAGE_SIZE 256
+
+/*
+ * Address of the page to perform Erase, Write and Read operations.
+ */
+#define ISF_TEST_ADDRESS 0x010000;
+#define ISF_TEST_BYTE 0x36 /* Test Byte offset value written */
+
+/**************************** Type Definitions *******************************/
+
+/***************** Macros (Inline Functions) Definitions *********************/
+
+/************************** Function Prototypes ******************************/
+
+static int IsfWaitForFlashNotBusy(void);
+
+/************************** 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.
+ */
+static XIsf Isf;
+static XSpi Spi;
+
+/*
+ * The user needs to allocate a buffer to be used by the In-system and Serial
+ * Flash Library to perform any read/write operations on the Serial Flash
+ * device.
+ * User applications must pass the address of this memory to the Library in
+ * Serial Flash Initialization function, for the Library to work.
+ * For Write operations:
+ * - The size of this buffer should be equal to the Number of bytes to be
+ * written to the Serial Flash + XISF_CMD_MAX_EXTRA_BYTES.
+ * - The size of this buffer should be large enough for usage across all the
+ * applications that use a common instance of the Serial Flash.
+ * - A minimum of one byte and a maximum of ISF_PAGE_SIZE bytes can be written
+ * to the Serial Flash, through a single Write operation.
+ * The size of this buffer should be equal to XISF_CMD_MAX_EXTRA_BYTES, if the
+ * application only reads from the Serial Flash (no write operations).
+ * For 4 byte addressing mode support, to account for the extra address bye
+ * the buffer size is incremented by 1.
+ */
+u8 IsfWriteBuffer[ISF_PAGE_SIZE + XISF_CMD_SEND_EXTRA_BYTES + 1];
+
+/*
+ * Buffers used during Read/Write transactions.
+ */
+u8 ReadBuffer[ISF_PAGE_SIZE + XISF_CMD_SEND_EXTRA_BYTES + 1]; /* Read Buffer */
+u8 WriteBuffer[ISF_PAGE_SIZE]; /* Write buffer */
+
+/************************** Function Definitions ******************************/
+
+/*****************************************************************************/
+/**
+*
+* Main function to execute the STM Serial Flash Read/Write polled example.
+*
+* @param None
+*
+* @return XST_SUCCESS if successful else XST_FAILURE.
+*
+* @note None
+*
+******************************************************************************/
+int main()
+{
+ int Status;
+ u32 Index;
+ u32 Address;
+ XIsf_WriteParam WriteParam;
+ XIsf_ReadParam ReadParam;
+
+
+ /*
+ * Initialize the SPI driver so that it's ready to use,
+ * specify the device ID that is generated in xparameters.h.
+ */
+ Status = XSpi_Initialize(&Spi, SPI_DEVICE_ID);
+ if(Status != XST_SUCCESS) {
+ return XST_FAILURE;
+ }
+
+ /*
+ * Start the SPI driver so that the device is enabled.
+ */
+ XSpi_Start(&Spi);
+
+ /*
+ * Disable Global interrupt to use the Spi driver in polled mode
+ * operation.
+ */
+ XSpi_IntrGlobalDisable(&Spi);
+
+ Status = XIsf_Initialize(&Isf, &Spi, ISF_SPI_SELECT, IsfWriteBuffer);
+ if(Status != XST_SUCCESS) {
+ return XST_FAILURE;
+ }
+
+ /*
+ * Specify the address in the Serial Flash for the Erase/Write/Read
+ * operations.
+ */
+ Address = ISF_TEST_ADDRESS;
+
+ /*
+ * Check is the flash part is micron in which case, switch to 4 byte
+ * addressing mode.
+ */
+ if (Isf.ManufacturerID == XISF_MANUFACTURER_ID_MICRON) {
+ Status = XIsf_WriteEnable(&Isf, XISF_WRITE_ENABLE);
+ if(Status != XST_SUCCESS) {
+ return XST_FAILURE;
+ }
+
+ Status = IsfWaitForFlashNotBusy();
+ if(Status != XST_SUCCESS) {
+ return XST_FAILURE;
+ }
+
+ XIsf_MicronFlashEnter4BAddMode(&Isf);
+
+ Status = IsfWaitForFlashNotBusy();
+ if(Status != XST_SUCCESS) {
+ return XST_FAILURE;
+ }
+ }
+
+ Status = XIsf_WriteEnable(&Isf, XISF_WRITE_ENABLE);
+ if(Status != XST_SUCCESS) {
+ return XST_FAILURE;
+ }
+
+ Status = IsfWaitForFlashNotBusy();
+ if(Status != XST_SUCCESS) {
+ return XST_FAILURE;
+ }
+
+ Status = XIsf_Erase(&Isf, XISF_SECTOR_ERASE, Address);
+ if(Status != XST_SUCCESS) {
+ return XST_FAILURE;
+ }
+
+ Status = IsfWaitForFlashNotBusy();
+ if(Status != XST_SUCCESS) {
+ return XST_FAILURE;
+ }
+
+ Status = XIsf_WriteEnable(&Isf, XISF_WRITE_ENABLE);
+ if(Status != XST_SUCCESS) {
+ return XST_FAILURE;
+ }
+
+ Status = IsfWaitForFlashNotBusy();
+ if(Status != XST_SUCCESS) {
+ return XST_FAILURE;
+ }
+
+ /*
+ * Set the
+ * - Address within the Serial Flash where the data is to be written.
+ * - Number of bytes to be written to the Serial Flash.
+ * - Write Buffer which contains the data to be written to the Serial
+ * Flash.
+ */
+ WriteParam.Address = Address;
+ WriteParam.NumBytes = ISF_PAGE_SIZE;
+ WriteParam.WritePtr = WriteBuffer;
+
+ /*
+ * Prepare the write buffer. Fill in the data need to be written into
+ * Serial Flash.
+ */
+ for(Index = 0; Index < ISF_PAGE_SIZE; Index++) {
+ WriteParam.WritePtr[Index] = Index + ISF_TEST_BYTE;
+ }
+
+ Status = XIsf_Write(&Isf, XISF_WRITE, (void*) &WriteParam);
+ if(Status != XST_SUCCESS) {
+ return XST_FAILURE;
+ }
+
+ Status = IsfWaitForFlashNotBusy();
+ if(Status != XST_SUCCESS) {
+ return XST_FAILURE;
+ }
+
+ /*
+ * 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.
+ * - Read Buffer to which the data is to be read.
+ */
+ ReadParam.Address = Address;
+ ReadParam.NumBytes = ISF_PAGE_SIZE;
+ ReadParam.ReadPtr = ReadBuffer;
+
+ Status = XIsf_Read(&Isf, XISF_READ, (void*) &ReadParam);
+ if(Status != XST_SUCCESS) {
+ return XST_FAILURE;
+ }
+
+ /*
+ * Compare the data read against the data Written. For Micron flash
+ * which supports 4 Byte mode, comparison should take care of the extra
+ * address byte.
+ */
+ if (Isf.ManufacturerID == XISF_MANUFACTURER_ID_MICRON) {
+ for(Index = 0; Index < ISF_PAGE_SIZE; Index++) {
+ if(ReadBuffer[Index + XISF_CMD_SEND_EXTRA_BYTES_4BYTE_MODE] !=
+ (u8)(Index + ISF_TEST_BYTE)) {
+ return XST_FAILURE;
+ }
+ }
+ } else {
+ for(Index = 0; Index < ISF_PAGE_SIZE; Index++) {
+ if(ReadBuffer[Index + XISF_CMD_SEND_EXTRA_BYTES] !=
+ (u8)(Index + ISF_TEST_BYTE)) {
+ return XST_FAILURE;
+ }
+ }
+ }
+
+ /*
+ * For micron flash part supporting 4 byte ddressing mode, exit from
+ * 4 Byte mode.
+ */
+ if (Isf.ManufacturerID == XISF_MANUFACTURER_ID_MICRON) {
+ Status = XIsf_WriteEnable(&Isf, XISF_WRITE_ENABLE);
+ if(Status != XST_SUCCESS) {
+ return XST_FAILURE;
+ }
+
+ Status = IsfWaitForFlashNotBusy();
+ if(Status != XST_SUCCESS) {
+ return XST_FAILURE;
+ }
+
+ XIsf_MicronFlashExit4BAddMode(&Isf);
+
+ Status = IsfWaitForFlashNotBusy();
+ if(Status != XST_SUCCESS) {
+ return XST_FAILURE;
+ }
+ }
+
+ 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 Serial Flash is ready to accept next command.
+*
+******************************************************************************/
+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 Serial 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;
+}
diff --git a/lib/sw_services/xilisf/examples/xilisf_stm_read_write_example.c b/lib/sw_services/xilisf/examples/xilisf_stm_read_write_example.c
new file mode 100644
index 00000000..84d8e0ba
--- /dev/null
+++ b/lib/sw_services/xilisf/examples/xilisf_stm_read_write_example.c
@@ -0,0 +1,585 @@
+/******************************************************************************
+*
+* Copyright (C) 2012 - 2015 Xilinx, Inc. All rights reserved.
+*
+* Permission is hereby granted, free of charge, to any person obtaining a copy
+* of this software and associated documentation files (the "Software"), to deal
+* in the Software without restriction, including without limitation the rights
+* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+* copies of the Software, and to permit persons to whom the Software is
+* furnished to do so, subject to the following conditions:
+*
+* The above copyright notice and this permission notice shall be included in
+* all copies or substantial portions of the Software.
+*
+* Use of the Software is limited solely to applications:
+* (a) running on a Xilinx device, or
+* (b) that interact with a Xilinx device through a bus or interconnect.
+*
+* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+* XILINX BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
+* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+* SOFTWARE.
+*
+* Except as contained in this notice, the name of the Xilinx shall not be used
+* in advertising or otherwise to promote the sale, use or other dealings in
+* this Software without prior written authorization from Xilinx.
+*
+******************************************************************************/
+/******************************************************************************
+*
+* @file xilisf_stm_read_write_example.c
+*
+* This file contains a design example using the In-system and Serial Flash
+* Library (XilIsf) for Reading/Writing to a STM (Numonyx) M25P16 Serial Flash
+* Device. This example shows the Erase, Read and Write features.
+*
+* This example
+* - Erases a Sector
+* - Writes to a Page within the Erased Sector
+* - Reads back the Page that is written and compares the data
+*
+* This example has been tested with a STM (Numonyx) M25P16 device on Xilinx
+* Spartan-3A Starter Kit board.
+*
+*
+* @note
+*
+* None.
+*
+*
+* MODIFICATION HISTORY:
+*
+* Ver Who Date Changes
+* ----- ---- -------- -----------------------------------------------
+* 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.
+* 5.2 asa 05/12/15 Added support for Micron N25Q256A flash.
+*
+*
+*
+******************************************************************************/
+
+/***************************** Include Files *********************************/
+
+#include "xparameters.h" /* EDK generated parameters */
+#include "xintc.h" /* Interrupt controller device driver */
+#include /* Serial Flash Library header file */
+#include "xil_exception.h"
+
+/************************** Constant Definitions *****************************/
+
+
+/*
+ * The following constants map to the XPAR parameters created in the
+ * xparameters.h file. They are defined here such that a user can easily
+ * change all the needed parameters in one place.
+ */
+#define SPI_DEVICE_ID XPAR_SPI_0_DEVICE_ID
+#define INTC_DEVICE_ID XPAR_INTC_0_DEVICE_ID
+#define SPI_INTR_ID XPAR_INTC_0_SPI_0_VEC_ID
+
+/*
+ * The following constant defines the slave select signal that is used to
+ * to select the Flash device on the SPI bus, this signal is typically
+ * connected to the chip select of the device.
+ */
+#define ISF_SPI_SELECT 0x01
+
+/*
+ * Number of bytes per page in the flash device.
+ */
+#define ISF_PAGE_SIZE 256
+
+/*
+ * Address of the page to perform Erase, Write and Read operations.
+ */
+#define ISF_TEST_ADDRESS 0x010000;
+#define ISF_TEST_BYTE 0x05 /* Test Byte offset value written */
+
+/**************************** Type Definitions *******************************/
+
+/***************** Macros (Inline Functions) Definitions *********************/
+
+/************************** Function Prototypes ******************************/
+
+static int IsfWaitForFlashNotBusy(void);
+void SpiHandler(void *CallBackRef, u32 StatusEvent, u16 ByteCount);
+static int SetupInterruptSystem(XSpi *SpiPtr);
+
+/************************** 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.
+ */
+static XIsf Isf;
+static XIntc InterruptController;
+static XSpi Spi;
+
+/*
+ * The following variables are shared between non-interrupt processing and
+ * interrupt processing such that they must be global.
+ */
+volatile static int TransferInProgress; /* State of Spi Transfer */
+static int ErrorCount; /* Errors occurred during Spi transfers */
+
+/*
+ * The user needs to allocate a buffer to be used by the In-system and Serial
+ * Flash Library to perform any read/write operations on the Serial Flash
+ * device.
+ * User applications must pass the address of this memory to the Library in
+ * Serial Flash Initialization function, for the Library to work.
+ * For Write operations:
+ * - The size of this buffer should be equal to the Number of bytes to be
+ * written to the Serial Flash + XISF_CMD_MAX_EXTRA_BYTES.
+ * - The size of this buffer should be large enough for usage across all the
+ * applications that use a common instance of the Serial Flash.
+ * - A minimum of one byte and a maximum of ISF_PAGE_SIZE bytes can be written
+ * to the Serial Flash, through a single Write operation.
+ * The size of this buffer should be equal to XISF_CMD_MAX_EXTRA_BYTES, if the
+ * application only reads from the Serial Flash (no write operations).
+ */
+u8 IsfWriteBuffer[ISF_PAGE_SIZE + XISF_CMD_SEND_EXTRA_BYTES + 1];
+
+/*
+ * Buffers used during Read/Write transactions.
+ */
+u8 ReadBuffer[ISF_PAGE_SIZE + XISF_CMD_SEND_EXTRA_BYTES + 1]; /* Read Buffer */
+u8 WriteBuffer[ISF_PAGE_SIZE]; /* Write buffer */
+
+/************************** Function Definitions ******************************/
+
+/*****************************************************************************/
+/**
+*
+* Main function to execute the STM Serial Flash Read/Write example.
+*
+* @param None
+*
+* @return XST_SUCCESS if successful else XST_FAILURE.
+*
+* @note None
+*
+******************************************************************************/
+int main()
+{
+ int Status;
+ u32 Index;
+ u32 Address;
+ XIsf_WriteParam WriteParam;
+ XIsf_ReadParam ReadParam;
+
+ /*
+ * Initialize the SPI driver so that it's ready to use,
+ * specify the device ID that is generated in xparameters.h.
+ */
+ Status = XSpi_Initialize(&Spi, SPI_DEVICE_ID);
+ if(Status != XST_SUCCESS) {
+ return XST_FAILURE;
+ }
+
+ /*
+ * Connect the SPI driver to the interrupt subsystem such that
+ * interrupts can occur. This function is application specific.
+ */
+ Status = SetupInterruptSystem(&Spi);
+ if(Status != XST_SUCCESS) {
+ return XST_FAILURE;
+ }
+
+ /*
+ * Setup the handler for the SPI that will be called from the interrupt
+ * context when an SPI status occurs, specify a pointer to the SPI
+ * driver instance as the callback reference so the handler is able to
+ * access the instance data.
+ */
+ XIsf_SetStatusHandler(&Isf, &Spi, (XSpi_StatusHandler)SpiHandler);
+
+ /*
+ * Start the SPI driver so that interrupts and the device are enabled.
+ */
+ XSpi_Start(&Spi);
+
+ /*
+ * Initialize the Serial Flash Library.
+ */
+ Status = XIsf_Initialize(&Isf, &Spi, ISF_SPI_SELECT, IsfWriteBuffer);
+ if(Status != XST_SUCCESS) {
+ 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.
+ */
+ Address = ISF_TEST_ADDRESS;
+
+ TransferInProgress = TRUE;
+ Status = XIsf_WriteEnable(&Isf, XISF_WRITE_ENABLE);
+ if(Status != XST_SUCCESS) {
+ return XST_FAILURE;
+ }
+
+ while(TransferInProgress);
+ if(ErrorCount != 0) {
+ return XST_FAILURE;
+ }
+
+ Status = IsfWaitForFlashNotBusy();
+ if(Status != XST_SUCCESS) {
+ return XST_FAILURE;
+ }
+
+ /*
+ * Check is the flash part is micron in which case, switch to 4 byte
+ * addressing mode.
+ */
+ if (Isf.ManufacturerID == XISF_MANUFACTURER_ID_MICRON) {
+ TransferInProgress = TRUE;
+ Status = XIsf_WriteEnable(&Isf, XISF_WRITE_ENABLE);
+ if(Status != XST_SUCCESS) {
+ return XST_FAILURE;
+ }
+
+ while(TransferInProgress);
+ if(ErrorCount != 0) {
+ return XST_FAILURE;
+ }
+
+ Status = IsfWaitForFlashNotBusy();
+ if(Status != XST_SUCCESS) {
+ return XST_FAILURE;
+ }
+
+ TransferInProgress = TRUE;
+ XIsf_MicronFlashEnter4BAddMode(&Isf);
+
+ while(TransferInProgress);
+ if(ErrorCount != 0) {
+ return XST_FAILURE;
+ }
+
+ Status = IsfWaitForFlashNotBusy();
+ if(Status != XST_SUCCESS) {
+ return XST_FAILURE;
+ }
+ }
+
+ TransferInProgress = TRUE;
+ Status = XIsf_Erase(&Isf, XISF_SECTOR_ERASE, Address);
+ if(Status != XST_SUCCESS) {
+ return XST_FAILURE;
+ }
+
+ while(TransferInProgress);
+ if(ErrorCount != 0) {
+ return XST_FAILURE;
+ }
+
+ Status = IsfWaitForFlashNotBusy();
+ if(Status != XST_SUCCESS) {
+ return XST_FAILURE;
+ }
+
+ TransferInProgress = TRUE;
+ Status = XIsf_WriteEnable(&Isf, XISF_WRITE_ENABLE);
+ if(Status != XST_SUCCESS) {
+ return XST_FAILURE;
+ }
+
+ while(TransferInProgress);
+ if(ErrorCount != 0) {
+ return XST_FAILURE;
+ }
+
+ Status = IsfWaitForFlashNotBusy();
+ if(Status != XST_SUCCESS) {
+ return XST_FAILURE;
+ }
+
+ /*
+ * Set the
+ * - Address within the Serial Flash where the data is to be written.
+ * - Number of bytes to be written to the Serial Flash.
+ * - Write Buffer which contains the data to be written to the Serial
+ * Flash.
+ */
+ WriteParam.Address = Address;
+ WriteParam.NumBytes = ISF_PAGE_SIZE;
+ WriteParam.WritePtr = WriteBuffer;
+
+ /*
+ * Prepare the write buffer. Fill in the data need to be written into
+ * Serial Flash.
+ */
+ for(Index = 0; Index < ISF_PAGE_SIZE; Index++) {
+ WriteParam.WritePtr[Index] = Index + ISF_TEST_BYTE;
+ }
+
+ TransferInProgress = TRUE;
+ Status = XIsf_Write(&Isf, XISF_WRITE, (void*) &WriteParam);
+ if(Status != XST_SUCCESS) {
+ return XST_FAILURE;
+ }
+
+ while(TransferInProgress);
+ if(ErrorCount != 0) {
+ return XST_FAILURE;
+ }
+
+ Status = IsfWaitForFlashNotBusy();
+ if(Status != XST_SUCCESS) {
+ return XST_FAILURE;
+ }
+
+ /*
+ * 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.
+ * - Read Buffer to which the data is to be read.
+ */
+ ReadParam.Address = Address;
+ ReadParam.NumBytes = ISF_PAGE_SIZE;
+ ReadParam.ReadPtr = ReadBuffer;
+
+ TransferInProgress = TRUE;
+ Status = XIsf_Read(&Isf, XISF_READ, (void*) &ReadParam);
+ if(Status != XST_SUCCESS) {
+ return XST_FAILURE;
+ }
+
+ while(TransferInProgress);
+ if(ErrorCount != 0) {
+ return XST_FAILURE;
+ }
+
+ /*
+ * Compare the data read against the data Written.
+ */
+ if (Isf.ManufacturerID == XISF_MANUFACTURER_ID_MICRON) {
+ for(Index = 0; Index < ISF_PAGE_SIZE; Index++) {
+ if(ReadBuffer[Index + XISF_CMD_SEND_EXTRA_BYTES_4BYTE_MODE] !=
+ (u8)(Index + ISF_TEST_BYTE)) {
+ return XST_FAILURE;
+ }
+ }
+ } else {
+ for(Index = 0; Index < ISF_PAGE_SIZE; Index++) {
+ if(ReadBuffer[Index + XISF_CMD_SEND_EXTRA_BYTES] !=
+ (u8)(Index + ISF_TEST_BYTE)) {
+ return XST_FAILURE;
+ }
+ }
+ }
+
+ if (Isf.ManufacturerID == XISF_MANUFACTURER_ID_MICRON) {
+ TransferInProgress = TRUE;
+ Status = XIsf_WriteEnable(&Isf, XISF_WRITE_ENABLE);
+ if(Status != XST_SUCCESS) {
+ return XST_FAILURE;
+ }
+
+ while(TransferInProgress);
+ if(ErrorCount != 0) {
+ return XST_FAILURE;
+ }
+
+ Status = IsfWaitForFlashNotBusy();
+ if(Status != XST_SUCCESS) {
+ return XST_FAILURE;
+ }
+
+ TransferInProgress = TRUE;
+ XIsf_MicronFlashExit4BAddMode(&Isf);
+
+ while(TransferInProgress);
+ if(ErrorCount != 0) {
+ return XST_FAILURE;
+ }
+
+ Status = IsfWaitForFlashNotBusy();
+ if(Status != XST_SUCCESS) {
+ return XST_FAILURE;
+ }
+
+ 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 Serial Flash is ready to accept next command.
+*
+******************************************************************************/
+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 complete and check for errors.
+ */
+ while(TransferInProgress);
+ if(ErrorCount != 0) {
+ return XST_FAILURE;
+ }
+
+ /*
+ * Check if the Serial 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 SPI 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 SPI data
+* completes or an error occurs.
+*
+* This handler provides an example of how to handle SPI interrupts and
+* is application specific.
+*
+* @param CallBackRef is the upper layer callback reference passed back
+* when the callback function is invoked.
+* @param StatusEvent is the event that just occurred.
+* @param ByteCount is the number of bytes transferred up until the event
+* occurred.
+*
+* @return None.
+*
+* @note None.
+*
+******************************************************************************/
+void SpiHandler(void *CallBackRef, u32 StatusEvent, u16 ByteCount)
+{
+ /*
+ * Indicate the transfer on the SPI bus is no longer in progress
+ * regardless of the status event.
+ */
+ TransferInProgress = FALSE;
+
+ /*
+ * If the event was not transfer done, then track it as an error.
+ */
+ if (StatusEvent != XST_SPI_TRANSFER_DONE) {
+ ErrorCount++;
+ }
+}
+
+/*****************************************************************************/
+/**
+*
+* This function setups the interrupt system such that interrupts can occur
+* for the Spi device. This function is application specific since the actual
+* system may or may not have an interrupt controller. The Spi device could be
+* directly connected to a processor without an interrupt controller. The
+* user should modify this function to fit the application.
+*
+* @param SpiPtr is a pointer to the instance of the Spi device.
+*
+* @return XST_SUCCESS if successful, otherwise XST_FAILURE.
+*
+* @note None
+*
+******************************************************************************/
+static int SetupInterruptSystem(XSpi *SpiPtr)
+{
+
+ int Status;
+
+ /*
+ * Initialize the interrupt controller driver so that
+ * it's ready to use, specify the device ID that is generated in
+ * xparameters.h
+ */
+ Status = XIntc_Initialize(&InterruptController, INTC_DEVICE_ID);
+ if(Status != XST_SUCCESS) {
+ return XST_FAILURE;
+ }
+
+ /*
+ * Connect a device driver handler that will be called when an interrupt
+ * for the device occurs, the device driver handler performs the
+ * specific interrupt processing for the device
+ */
+ Status = XIntc_Connect(&InterruptController,
+ SPI_INTR_ID,
+ (XInterruptHandler)XSpi_InterruptHandler,
+ (void *)SpiPtr);
+ if(Status != XST_SUCCESS) {
+ return XST_FAILURE;
+ }
+
+ /*
+ * Start the interrupt controller such that interrupts are enabled for
+ * all devices that cause interrupts, specify real mode so that
+ * the SPI can cause interrupts through the interrupt controller.
+ */
+ Status = XIntc_Start(&InterruptController, XIN_REAL_MODE);
+ if(Status != XST_SUCCESS) {
+ return XST_FAILURE;
+ }
+
+ /*
+ * Enable the interrupt for the SPI.
+ */
+ XIntc_Enable(&InterruptController, SPI_INTR_ID);
+
+ /*
+ * Initialize the exception table.
+ */
+ Xil_ExceptionInit();
+
+ /*
+ * Register the interrupt controller handler with the exception table.
+ */
+ Xil_ExceptionRegisterHandler(XIL_EXCEPTION_ID_INT,
+ (Xil_ExceptionHandler)XIntc_InterruptHandler,
+ &InterruptController);
+
+ /*
+ * Enable non-critical exceptions.
+ */
+ Xil_ExceptionEnable();
+
+ return XST_SUCCESS;
+}
diff --git a/lib/sw_services/xilisf/examples/xilisf_stm_spr_example.c b/lib/sw_services/xilisf/examples/xilisf_stm_spr_example.c
new file mode 100644
index 00000000..a14624af
--- /dev/null
+++ b/lib/sw_services/xilisf/examples/xilisf_stm_spr_example.c
@@ -0,0 +1,754 @@
+/******************************************************************************
+*
+* Copyright (C) 2012 - 2014 Xilinx, Inc. All rights reserved.
+*
+* Permission is hereby granted, free of charge, to any person obtaining a copy
+* of this software and associated documentation files (the "Software"), to deal
+* in the Software without restriction, including without limitation the rights
+* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+* copies of the Software, and to permit persons to whom the Software is
+* furnished to do so, subject to the following conditions:
+*
+* The above copyright notice and this permission notice shall be included in
+* all copies or substantial portions of the Software.
+*
+* Use of the Software is limited solely to applications:
+* (a) running on a Xilinx device, or
+* (b) that interact with a Xilinx device through a bus or interconnect.
+*
+* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+* XILINX BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
+* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+* SOFTWARE.
+*
+* Except as contained in this notice, the name of the Xilinx shall not be used
+* in advertising or otherwise to promote the sale, use or other dealings in
+* this Software without prior written authorization from Xilinx.
+*
+******************************************************************************/
+/******************************************************************************
+*
+* @file xilisf_stm_spr_example.c
+*
+* This file contains a design example using the Xilinx In-system and Serial
+* Flash Library (XilIsf). This example shows the usage of Sector Erase, Sector
+* Protection, Read and Write features.
+
+* This example
+* - Erases a Sector
+* - Writes to a Page within the erased Sector
+* - Enables the Sector Protection so that all the sectors are Write protected
+* - Erases a Page (This should not happen as the Sectors are Write protected
+* - Reads back the Page that is written and compares the data.
+*
+* This example has been tested with a STM (Numonyx) Serial Flash Memory
+* (M25P16) on a Xilinx Spartan-3A Starter Kit board. For further details about
+* the Flash device refer to the STM (Numonyx) Serial Flash Memory (M25P16)
+* data sheet.
+*
+* @note
+*
+* None.
+*
+*
+* MODIFICATION HISTORY:
+*
+* Ver Who Date Changes
+* ----- ---- -------- -----------------------------------------------
+* 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.
+*
+*
+******************************************************************************/
+
+/***************************** Include Files *********************************/
+
+#include "xparameters.h" /* EDK generated parameters */
+#include "xintc.h" /* Interrupt controller device driver */
+#include "xspi.h" /* SPI device driver */
+#include /* Serial Flash Library header file */
+#include "xil_exception.h"
+
+/************************** Constant Definitions *****************************/
+
+
+/*
+ * The following constants map to the XPAR parameters created in the
+ * xparameters.h file. They are defined here such that a user can easily
+ * change all the needed parameters in one place.
+ */
+#define SPI_DEVICE_ID XPAR_SPI_0_DEVICE_ID
+#define INTC_DEVICE_ID XPAR_INTC_0_DEVICE_ID
+#define SPI_INTR_ID XPAR_INTC_0_SPI_0_VEC_ID
+
+/*
+ * The following constant defines the slave select signal that is used to
+ * to select the Serial Flash on the SPI bus, this signal is typically
+ * connected to the chip select of the device.
+ */
+#define ISF_SPI_SELECT 0x01
+
+/*
+ * Number of bytes per page in the Serial Flash.
+ */
+#define ISF_PAGE_SIZE 256
+
+/*
+ * Address of the page to perform Erase, Write and Read operations.
+ */
+#define ISF_TEST_ADDRESS 0x010000;
+#define ISF_TEST_BYTE 0x15 /* Test Byte offset value written */
+
+/**************************** Type Definitions *******************************/
+
+/***************** Macros (Inline Functions) Definitions *********************/
+
+/************************** Function Prototypes ******************************/
+
+static int IsfWaitForFlashNotBusy(void);
+void SpiHandler(void *CallBackRef, u32 StatusEvent, u16 ByteCount);
+static int SetupInterruptSystem(XSpi *SpiPtr);
+
+/************************** 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.
+ */
+static XIsf Isf;
+static XIntc InterruptController;
+static XSpi Spi;
+
+/*
+ * The following variables are shared between non-interrupt processing and
+ * interrupt processing such that they must be global.
+ */
+volatile static int TransferInProgress;
+
+/*
+ * The following variable tracks any errors that occur during interrupt
+ * processing.
+ */
+static int ErrorCount;
+
+/*
+ * The user needs to allocate a buffer to be used by the In-system and Serial
+ * Flash Library to perform any read/write operations on the Serial Flash
+ * device.
+ * User applications must pass the address of this memory to the Library in
+ * Serial Flash Initialization function, for the Library to work.
+ * For Write operations:
+ * - The size of this buffer should be equal to the Number of bytes to be
+ * written to the Serial Flash + XISF_CMD_MAX_EXTRA_BYTES.
+ * - The size of this buffer should be large enough for usage across all the
+ * applications that use a common instance of the Serial Flash.
+ * - A minimum of one byte and a maximum of ISF_PAGE_SIZE bytes can be written
+ * to the Serial Flash, through a single Write operation.
+ * The size of this buffer should be equal to XISF_CMD_MAX_EXTRA_BYTES, if the
+ * application only reads from the Serial Flash (no write operations).
+ */
+u8 IsfWriteBuffer[ISF_PAGE_SIZE + XISF_CMD_SEND_EXTRA_BYTES];
+
+/*
+ * Buffers used during read and write transactions.
+ */
+u8 ReadBuffer[ISF_PAGE_SIZE + XISF_CMD_SEND_EXTRA_BYTES];
+u8 WriteBuffer[ISF_PAGE_SIZE];
+
+/************************** Function Definitions ******************************/
+
+/*****************************************************************************/
+/**
+*
+* Main function to execute the STM Serial Flash SPR example.
+*
+* @param None
+*
+* @return XST_SUCCESS if successful else XST_FAILURE.
+*
+* @note None
+*
+******************************************************************************/
+int main()
+{
+ int Status;
+ u32 Index;
+ u32 Address;
+ XIsf_WriteParam WriteParam;
+ XIsf_ReadParam ReadParam;
+
+
+ /*
+ * Initialize the SPI driver so that it's ready to use,
+ * specify the device ID that is generated in xparameters.h.
+ */
+ Status = XSpi_Initialize(&Spi, SPI_DEVICE_ID);
+ if(Status != XST_SUCCESS) {
+ return XST_FAILURE;
+ }
+
+ /*
+ * Connect the SPI driver to the interrupt subsystem such that
+ * interrupts can occur. This function is application specific.
+ */
+ Status = SetupInterruptSystem(&Spi);
+ if(Status != XST_SUCCESS) {
+ return XST_FAILURE;
+ }
+
+ /*
+ * Setup the handler for the SPI that will be called from the interrupt
+ * context when an SPI status occurs, specify a pointer to the SPI
+ * driver instance as the callback reference so the handler is able to
+ * access the instance data.
+ */
+ XIsf_SetStatusHandler(&Isf, &Spi, (XSpi_StatusHandler)SpiHandler);
+
+ /*
+ * Start the SPI driver so that interrupts and the device are enabled.
+ */
+ XSpi_Start(&Spi);
+
+ /*
+ * Initialize the Serial Flash Library.
+ */
+ Status = XIsf_Initialize(&Isf, &Spi, ISF_SPI_SELECT, IsfWriteBuffer);
+ if(Status != XST_SUCCESS) {
+ 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.
+ */
+ Address = ISF_TEST_ADDRESS;
+
+ /*
+ * 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;
+ }
+
+ /*
+ * Perform the Sector Erase operation.
+ */
+ TransferInProgress = TRUE;
+ Status = XIsf_Erase(&Isf, XISF_SECTOR_ERASE, Address);
+ 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;
+ }
+
+ /*
+ * 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;
+ }
+
+ /*
+ * Set the
+ * - Address within the Serial Flash where the data is to be written.
+ * - Number of bytes to be written to the Serial Flash.
+ * - Write Buffer which contains the data to be written to the Serial
+ * Flash.
+ */
+ WriteParam.Address = Address;
+ WriteParam.NumBytes = ISF_PAGE_SIZE;
+ WriteParam.WritePtr = WriteBuffer;
+
+ /*
+ * Prepare the write buffer. Fill in the data that needs to be written
+ * to the Serial Flash.
+ */
+ for(Index = 0; Index < ISF_PAGE_SIZE; Index++) {
+ WriteParam.WritePtr[Index] = Index + ISF_TEST_BYTE;
+ }
+
+ /*
+ * Perform the Write operation.
+ */
+ TransferInProgress = TRUE;
+ Status = XIsf_Write(&Isf, XISF_WRITE, (void*) &WriteParam);
+ 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;
+ }
+
+ /*
+ * 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;
+ }
+
+ /*
+ * Read the sector protection register.
+ */
+ TransferInProgress = TRUE;
+ Status = XIsf_SectorProtect(&Isf, XISF_SPR_READ, ReadBuffer);
+ 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;
+ }
+
+ /*
+ * Set all the block protection bits in the sector protection register
+ * value read above and write it back to the sector protection register
+ * to disable protection for all sectors.
+ */
+ WriteBuffer[BYTE1] = ReadBuffer[BYTE2] |
+ (XISF_SR_BLOCK_PROTECT_MASK);
+
+ /*
+ * Enable the sector protection.
+ */
+ TransferInProgress = TRUE;
+ Status = XIsf_SectorProtect(&Isf, XISF_SPR_WRITE, WriteBuffer);
+ 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;
+ }
+
+ /*
+ * 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;
+ }
+
+ /*
+ * Perform the Sector Erase operation. This should not work as sector
+ * protection is enabled for all the sectors.
+ */
+ TransferInProgress = TRUE;
+ Status = XIsf_Erase(&Isf, XISF_SECTOR_ERASE, Address);
+ 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;
+ }
+
+ /*
+ * Read the sector protection register.
+ */
+ TransferInProgress = TRUE;
+ Status = XIsf_SectorProtect(&Isf, XISF_SPR_READ, ReadBuffer);
+ 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;
+ }
+
+ /*
+ * Clear all the block protection bits in the sector protection register
+ * value read above and write it back to the sector protection register
+ * to disable protection for all sectors.
+ */
+ WriteBuffer[BYTE1] = ReadBuffer[BYTE2] &
+ ~(XISF_SR_BLOCK_PROTECT_MASK);
+
+ /*
+ * Disable the sector protection.
+ */
+ TransferInProgress = TRUE;
+ Status = XIsf_SectorProtect(&Isf, XISF_SPR_WRITE, WriteBuffer);
+ 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;
+ }
+
+ /*
+ * 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.
+ * - Read Buffer to which the data is to be read.
+ */
+ ReadParam.Address = Address;
+ ReadParam.NumBytes = ISF_PAGE_SIZE;
+ ReadParam.ReadPtr = ReadBuffer;
+
+ /*
+ * Perform the Read operation.
+ */
+ TransferInProgress = TRUE;
+ Status = XIsf_Read(&Isf, XISF_READ, (void*) &ReadParam);
+ 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;
+ }
+
+ /*
+ * Compare the data read against the data written.
+ */
+ for(Index = 0; Index < ISF_PAGE_SIZE; Index++) {
+ if(ReadBuffer[Index + XISF_CMD_SEND_EXTRA_BYTES] !=
+ (u8)(Index + ISF_TEST_BYTE)) {
+ return XST_FAILURE;
+ }
+ }
+
+ 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 SPI 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 SPI data
+* completes or an error occurs.
+*
+* This handler provides an example of how to handle SPI interrupts and
+* is application specific.
+*
+* @param CallBackRef is the upper layer callback reference passed back
+* when the callback function is invoked.
+* @param StatusEvent is the event that just occurred.
+* @param ByteCount is the number of bytes transferred up until the event
+* occurred.
+*
+* @return None.
+*
+* @note None.
+*
+******************************************************************************/
+void SpiHandler(void *CallBackRef, u32 StatusEvent, u16 ByteCount)
+{
+ /*
+ * Indicate the transfer on the SPI bus is no longer in progress
+ * regardless of the status event.
+ */
+ TransferInProgress = FALSE;
+
+ /*
+ * If the event was not transfer done, then track it as an error.
+ */
+ if (StatusEvent != XST_SPI_TRANSFER_DONE) {
+ ErrorCount++;
+ }
+}
+
+/*****************************************************************************/
+/**
+*
+* This function setups the interrupt system such that interrupts can occur
+* for the Spi device. This function is application specific since the actual
+* system may or may not have an interrupt controller. The Spi device could be
+* directly connected to a processor without an interrupt controller. The
+* user should modify this function to fit the application.
+*
+* @param SpiPtr is a pointer to the instance of the Spi device.
+*
+* @return XST_SUCCESS if successful, otherwise XST_FAILURE.
+*
+* @note None
+*
+******************************************************************************/
+static int SetupInterruptSystem(XSpi *SpiPtr)
+{
+
+ int Status;
+
+ /*
+ * Initialize the interrupt controller driver so that
+ * it's ready to use, specify the device ID that is generated in
+ * xparameters.h
+ */
+ Status = XIntc_Initialize(&InterruptController, INTC_DEVICE_ID);
+ if(Status != XST_SUCCESS) {
+ return XST_FAILURE;
+ }
+
+ /*
+ * Connect a device driver handler that will be called when an interrupt
+ * for the device occurs, the device driver handler performs the
+ * specific interrupt processing for the device
+ */
+ Status = XIntc_Connect(&InterruptController,
+ SPI_INTR_ID,
+ (XInterruptHandler)XSpi_InterruptHandler,
+ (void *)SpiPtr);
+ if(Status != XST_SUCCESS) {
+ return XST_FAILURE;
+ }
+
+ /*
+ * Start the interrupt controller such that interrupts are enabled for
+ * all devices that cause interrupts, specific real mode so that
+ * the SPI can cause interrupts thru the interrupt controller.
+ */
+ Status = XIntc_Start(&InterruptController, XIN_REAL_MODE);
+ if(Status != XST_SUCCESS) {
+ return XST_FAILURE;
+ }
+
+ /*
+ * Enable the interrupt for the SPI.
+ */
+ XIntc_Enable(&InterruptController, SPI_INTR_ID);
+
+
+ /*
+ * Initialize the exception table
+ */
+ Xil_ExceptionInit();
+
+ /*
+ * Register the interrupt controller handler with the exception table
+ */
+ Xil_ExceptionRegisterHandler(XIL_EXCEPTION_ID_INT,
+ (Xil_ExceptionHandler)XIntc_InterruptHandler,
+ &InterruptController);
+
+ /*
+ * Enable non-critical exceptions
+ */
+ Xil_ExceptionEnable();
+
+ return XST_SUCCESS;
+}
diff --git a/lib/sw_services/xilisf/examples/xilisf_winbond_quad_flash_example.c b/lib/sw_services/xilisf/examples/xilisf_winbond_quad_flash_example.c
new file mode 100644
index 00000000..a4bad9e6
--- /dev/null
+++ b/lib/sw_services/xilisf/examples/xilisf_winbond_quad_flash_example.c
@@ -0,0 +1,849 @@
+/******************************************************************************
+*
+* Copyright (C) 2012 - 2014 Xilinx, Inc. All rights reserved.
+*
+* Permission is hereby granted, free of charge, to any person obtaining a copy
+* of this software and associated documentation files (the "Software"), to deal
+* in the Software without restriction, including without limitation the rights
+* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+* copies of the Software, and to permit persons to whom the Software is
+* furnished to do so, subject to the following conditions:
+*
+* The above copyright notice and this permission notice shall be included in
+* all copies or substantial portions of the Software.
+*
+* Use of the Software is limited solely to applications:
+* (a) running on a Xilinx device, or
+* (b) that interact with a Xilinx device through a bus or interconnect.
+*
+* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+* XILINX BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
+* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+* SOFTWARE.
+*
+* Except as contained in this notice, the name of the Xilinx shall not be used
+* in advertising or otherwise to promote the sale, use or other dealings in
+* this Software without prior written authorization from Xilinx.
+*
+******************************************************************************/
+/******************************************************************************
+*
+* @file xilisf_winbond_quad_flash_example.c
+*
+* This file contains a design example using the In-system and Serial Flash
+* Library (XilIsf) for Reading/Writing to a Winbond W25QXX Quad Serial Flash
+* Device. This example shows the Erase, Dual/Quad Read and Quad Write
+* features.
+*
+* This example
+* - Erases a Sector
+* - Writes to a Page within the Erased Sector
+* - Reads back the Page that is written and compares the data
+*
+* This example has been tested with a Winbond Serial Flash Memory (W25Q64) on
+* a Xilinx SP605 board. For further details about the Flash device refer the
+* Winbond Serial Flash Memory (W25Q64) data sheet.
+*
+* @note
+*
+* None.
+*
+*
+* MODIFICATION HISTORY:
+*
+* 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.
+*
+*
+******************************************************************************/
+
+/***************************** Include Files *********************************/
+
+#include "xparameters.h" /* EDK generated parameters */
+#include "xintc.h" /* Interrupt controller device driver */
+#include /* Serial Flash Library header file */
+#include "xil_exception.h"
+
+/************************** Constant Definitions *****************************/
+
+
+/*
+ * The following constants map to the XPAR parameters created in the
+ * xparameters.h file. They are defined here such that a user can easily
+ * change all the needed parameters in one place.
+ */
+#define SPI_DEVICE_ID XPAR_SPI_0_DEVICE_ID
+#define INTC_DEVICE_ID XPAR_INTC_0_DEVICE_ID
+#define SPI_INTR_ID XPAR_INTC_0_SPI_0_VEC_ID
+
+/*
+ * The following constant defines the slave select signal that is used to
+ * to select the Flash device on the SPI bus, this signal is typically
+ * connected to the chip select of the device.
+ */
+#define ISF_SPI_SELECT 0x01
+
+/*
+ * Number of bytes per page in the flash device.
+ */
+#define ISF_PAGE_SIZE 256
+
+/*
+ * Address of the page to perform Erase, Write and Read operations.
+ */
+#define ISF_TEST_ADDRESS 0x010000;
+#define ISF_TEST_BYTE 0x03 /* Test Byte value written */
+
+/*
+ * The following definitions specify the number of dummy bytes to ignore in the
+ * data read from the flash, through various Read commands. This is apart from
+ * the dummy bytes returned in reponse to the command and address transmitted.
+ */
+/*
+ * After transmitting Dual Read command and address on DIO0, the quad spi device
+ * configures DIO0 and DIO1 in input mode and receives data on both DIO0 and
+ * DIO1 for 8 dummy clock cycles. So we end up with 16 dummy bits in DRR. The
+ * same logic applies Quad read command, so we end up with 4 dummy bytes in that
+ * case.
+ */
+/*
+ * Please refer to the flash datasheet for more details about the number of dummy
+ * cycles associated with each command.
+ */
+#define DUAL_READ_DUMMY_BYTES 2
+#define QUAD_READ_DUMMY_BYTES 4
+
+#define DUAL_IO_READ_DUMMY_BYTES 1
+#define QUAD_IO_READ_DUMMY_BYTES 3
+
+/**************************** Type Definitions *******************************/
+
+/***************** Macros (Inline Functions) Definitions *********************/
+
+/************************** Function Prototypes ******************************/
+
+static int IsfWaitForFlashNotBusy(void);
+static int SpiFlashQuadEnable(void);
+void SpiHandler(void *CallBackRef, u32 StatusEvent, u16 ByteCount);
+static int SetupInterruptSystem(XSpi *SpiPtr);
+
+/************************** 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.
+ */
+static XIsf Isf;
+static XIntc InterruptController;
+static XSpi Spi;
+
+/*
+ * The following variables are shared between non-interrupt processing and
+ * interrupt processing such that they must be global.
+ */
+volatile static int TransferInProgress; /* State of Spi Transfer */
+static int ErrorCount; /* Errors occurred during Spi transfers */
+
+/*
+ * The user needs to allocate a buffer to be used by the In-system and Serial
+ * Flash Library to perform any read/write operations on the Serial Flash
+ * device.
+ * User applications must pass the address of this memory to the Library in
+ * Serial Flash Initialization function, for the Library to work.
+ * For Write operations:
+ * - The size of this buffer should be equal to the Number of bytes to be
+ * written to the Serial Flash + XISF_CMD_MAX_EXTRA_BYTES.
+ * - The size of this buffer should be large enough for usage across all the
+ * applications that use a common instance of the Serial Flash.
+ * - A minimum of one byte and a maximum of ISF_PAGE_SIZE bytes can be written
+ * to the Serial Flash, through a single Write operation.
+ * The size of this buffer should be equal to XISF_CMD_MAX_EXTRA_BYTES, if the
+ * application only reads from the Serial Flash (no write operations).
+ */
+u8 IsfWriteBuffer[ISF_PAGE_SIZE + XISF_CMD_SEND_EXTRA_BYTES];
+
+/*
+ * Buffers used during Read/Write transactions.
+ */
+u8 ReadBuffer[ISF_PAGE_SIZE + XISF_CMD_SEND_EXTRA_BYTES + 4]; /* Read Buffer */
+u8 WriteBuffer[ISF_PAGE_SIZE]; /* Write buffer */
+
+/************************** Function Definitions ******************************/
+
+/*****************************************************************************/
+/**
+*
+* Main function to execute the Winbond Quad Serial Flash Read/Write example.
+*
+* @param None
+*
+* @return XST_SUCCESS if successful else XST_FAILURE.
+*
+* @note None
+*
+******************************************************************************/
+int main()
+{
+ int Status;
+ u32 Index;
+ u32 Address;
+ XIsf_WriteParam WriteParam;
+ XIsf_ReadParam ReadParam;
+
+ /*
+ * Initialize the SPI driver so that it's ready to use,
+ * specify the device ID that is generated in xparameters.h.
+ */
+ Status = XSpi_Initialize(&Spi, SPI_DEVICE_ID);
+ if(Status != XST_SUCCESS) {
+ return XST_FAILURE;
+ }
+
+ /*
+ * Connect the SPI driver to the interrupt subsystem such that
+ * interrupts can occur. This function is application specific.
+ */
+ Status = SetupInterruptSystem(&Spi);
+ if(Status != XST_SUCCESS) {
+ return XST_FAILURE;
+ }
+
+ /*
+ * Setup the handler for the SPI that will be called from the interrupt
+ * context when an SPI status occurs, specify a pointer to the SPI
+ * driver instance as the callback reference so the handler is able to
+ * access the instance data.
+ */
+ XIsf_SetStatusHandler(&Isf, &Spi, (XSpi_StatusHandler)SpiHandler);
+
+ /*
+ * Start the SPI driver so that interrupts and the device are enabled.
+ */
+ XSpi_Start(&Spi);
+
+ /*
+ * Initialize the Serial Flash Library.
+ */
+ Status = XIsf_Initialize(&Isf, &Spi, ISF_SPI_SELECT, IsfWriteBuffer);
+ if(Status != XST_SUCCESS) {
+ 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.
+ */
+ Address = ISF_TEST_ADDRESS;
+
+ /*
+ * The following code Erases a Sector in the Winbond Serial Flash.
+ */
+
+ /*
+ * 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 for errors.
+ */
+ while(TransferInProgress);
+ if(ErrorCount != 0) {
+ return XST_FAILURE;
+ }
+
+ /*
+ * Wait till the Flash is not Busy.
+ */
+ Status = IsfWaitForFlashNotBusy();
+ if(Status != XST_SUCCESS) {
+ return XST_FAILURE;
+ }
+
+ /*
+ * Perform the Sector Erase operation.
+ */
+ TransferInProgress = TRUE;
+ Status = XIsf_Erase(&Isf, XISF_SECTOR_ERASE, Address);
+ if(Status != XST_SUCCESS) {
+ return XST_FAILURE;
+ }
+
+ /*
+ * Wait till the Transfer is complete and check for errors.
+ */
+ while(TransferInProgress);
+ if(ErrorCount != 0) {
+ return XST_FAILURE;
+ }
+
+ /*
+ * Wait till the Flash is not Busy.
+ */
+ Status = IsfWaitForFlashNotBusy();
+ if(Status != XST_SUCCESS) {
+ return XST_FAILURE;
+ }
+
+ /*
+ * Set the Quad Enable (QE) bit in the flash device, so that Quad
+ * operations can be perfomed on the flash.
+ */
+ Status = SpiFlashQuadEnable();
+ if (Status != XST_SUCCESS) {
+ return XST_FAILURE;
+ }
+
+ /*
+ * 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 for errors.
+ */
+ while(TransferInProgress);
+ if(ErrorCount != 0) {
+ return XST_FAILURE;
+ }
+
+ /*
+ * Wait till the Flash is not Busy.
+ */
+ Status = IsfWaitForFlashNotBusy();
+ if(Status != XST_SUCCESS) {
+ return XST_FAILURE;
+ }
+
+ /*
+ * Set the
+ * - Address within the Serial Flash where the data is to be written.
+ * - Number of bytes to be written to the Serial Flash.
+ * - Write Buffer which contains the data to be written to the Serial
+ * Flash.
+ */
+ WriteParam.Address = Address;
+ WriteParam.NumBytes = ISF_PAGE_SIZE;
+ WriteParam.WritePtr = WriteBuffer;
+
+ /*
+ * Prepare the write buffer. Fill in the data need to be written into
+ * Serial Flash.
+ */
+ for(Index = 0; Index < ISF_PAGE_SIZE; Index++) {
+ WriteParam.WritePtr[Index] = Index + ISF_TEST_BYTE;
+ }
+
+ /*
+ * Perform the Write operation.
+ */
+ TransferInProgress = TRUE;
+ Status = XIsf_Write(&Isf, XISF_QUAD_IP_PAGE_WRITE, (void*) &WriteParam);
+ if(Status != XST_SUCCESS) {
+ return XST_FAILURE;
+ }
+
+ /*
+ * Wait till the Transfer is complete and check for errors.
+ */
+ while(TransferInProgress);
+ if(ErrorCount != 0) {
+ return XST_FAILURE;
+ }
+
+ /*
+ * Wait till the Flash is not Busy.
+ */
+ Status = IsfWaitForFlashNotBusy();
+ if(Status != XST_SUCCESS) {
+ return XST_FAILURE;
+ }
+
+ /*
+ * Read from the flash using Dual Output Fast Read 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.
+ * - Read Buffer to which the data is to be read.
+ * - Number of dummy bytes for the read command.
+ */
+ ReadParam.Address = Address;
+ ReadParam.NumBytes = ISF_PAGE_SIZE;
+ ReadParam.ReadPtr = ReadBuffer;
+ ReadParam.NumDummyBytes = DUAL_READ_DUMMY_BYTES;
+
+ /*
+ * Clear the read Buffer.
+ */
+ for(Index = 0; Index < ISF_PAGE_SIZE + XISF_CMD_SEND_EXTRA_BYTES +
+ DUAL_READ_DUMMY_BYTES; Index++) {
+ ReadBuffer[Index] = 0x0;
+ }
+
+ /*
+ * Perform the read operation.
+ */
+ TransferInProgress = TRUE;
+ Status = XIsf_Read(&Isf, XISF_DUAL_OP_FAST_READ, (void*) &ReadParam);
+ if(Status != XST_SUCCESS) {
+ return XST_FAILURE;
+ }
+
+ /*
+ * Wait till the Transfer is complete and check for errors.
+ */
+ while(TransferInProgress);
+ if(ErrorCount != 0) {
+ return XST_FAILURE;
+ }
+
+ /*
+ * Compare the data read against the data Written.
+ */
+ for(Index = 0; Index < ISF_PAGE_SIZE; Index++) {
+ if(ReadBuffer[Index + XISF_CMD_SEND_EXTRA_BYTES +
+ DUAL_READ_DUMMY_BYTES] !=
+ (u8)(Index + ISF_TEST_BYTE)) {
+ return XST_FAILURE;
+ }
+ }
+
+ /*
+ * Enable High Performance Mode so that data can be read from the flash
+ * using DIO and QIO read commands.
+ */
+ TransferInProgress = TRUE;
+ Status = XIsf_Ioctl(&Isf, XISF_IOCTL_ENABLE_HI_PERF_MODE);
+ 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;
+ }
+
+ /*
+ * Read from the flash using Dual Input/Output Fast Read 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.
+ * - Read Buffer to which the data is to be read.
+ * - Number of dummy bytes for the read command.
+ */
+ ReadParam.Address = Address;
+ ReadParam.NumBytes = ISF_PAGE_SIZE;
+ ReadParam.ReadPtr = ReadBuffer;
+ ReadParam.NumDummyBytes = DUAL_IO_READ_DUMMY_BYTES;
+
+ /*
+ * Clear the read Buffer.
+ */
+ for(Index = 0; Index < ISF_PAGE_SIZE + XISF_CMD_SEND_EXTRA_BYTES +
+ DUAL_IO_READ_DUMMY_BYTES; Index++) {
+ ReadBuffer[Index] = 0x0;
+ }
+
+ /*
+ * Perform the read operation.
+ */
+ TransferInProgress = TRUE;
+ Status = XIsf_Read(&Isf, XISF_DUAL_IO_FAST_READ, (void*) &ReadParam);
+ if(Status != XST_SUCCESS) {
+ return XST_FAILURE;
+ }
+
+ /*
+ * Wait till the Transfer is complete and check for errors.
+ */
+ while(TransferInProgress);
+ if(ErrorCount != 0) {
+ return XST_FAILURE;
+ }
+
+ /*
+ * Compare the data read against the data Written.
+ */
+ for(Index = 0; Index < ISF_PAGE_SIZE; Index++) {
+ if(ReadBuffer[Index + XISF_CMD_SEND_EXTRA_BYTES +
+ DUAL_IO_READ_DUMMY_BYTES] !=
+ (u8)(Index + ISF_TEST_BYTE)) {
+ return XST_FAILURE;
+ }
+ }
+
+ /*
+ * Read from the flash using Quad Output Fast Read 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.
+ * - Read Buffer to which the data is to be read.
+ * - Number of dummy bytes for the read command.
+ */
+ ReadParam.Address = Address;
+ ReadParam.NumBytes = ISF_PAGE_SIZE;
+ ReadParam.ReadPtr = ReadBuffer;
+ ReadParam.NumDummyBytes = QUAD_READ_DUMMY_BYTES;
+
+ /*
+ * Clear the read Buffer.
+ */
+ for(Index = 0; Index < ISF_PAGE_SIZE + XISF_CMD_SEND_EXTRA_BYTES +
+ QUAD_READ_DUMMY_BYTES; Index++) {
+ ReadBuffer[Index] = 0x0;
+ }
+
+ /*
+ * Perform the read operation.
+ */
+ TransferInProgress = TRUE;
+ Status = XIsf_Read(&Isf, XISF_QUAD_OP_FAST_READ, (void*) &ReadParam);
+ if(Status != XST_SUCCESS) {
+ return XST_FAILURE;
+ }
+
+ /*
+ * Wait till the Transfer is complete and check for errors.
+ */
+ while(TransferInProgress);
+ if(ErrorCount != 0) {
+ return XST_FAILURE;
+ }
+
+ /*
+ * Compare the data read against the data Written.
+ */
+ for(Index = 0; Index < ISF_PAGE_SIZE; Index++) {
+ if(ReadBuffer[Index + XISF_CMD_SEND_EXTRA_BYTES +
+ QUAD_READ_DUMMY_BYTES] !=
+ (u8)(Index + ISF_TEST_BYTE)) {
+ return XST_FAILURE;
+ }
+ }
+
+ /*
+ * Read from the flash using Quad Input/Output Fast Read 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.
+ * - Read Buffer to which the data is to be read.
+ * - Number of dummy bytes for the read command.
+ */
+ ReadParam.Address = Address;
+ ReadParam.NumBytes = ISF_PAGE_SIZE;
+ ReadParam.ReadPtr = ReadBuffer;
+ ReadParam.NumDummyBytes = QUAD_IO_READ_DUMMY_BYTES;
+
+ /*
+ * Clear the read Buffer.
+ */
+ for(Index = 0; Index < ISF_PAGE_SIZE + XISF_CMD_SEND_EXTRA_BYTES +
+ QUAD_IO_READ_DUMMY_BYTES; Index++) {
+ ReadBuffer[Index] = 0x0;
+ }
+
+ /*
+ * Perform the read operation.
+ */
+ TransferInProgress = TRUE;
+ Status = XIsf_Read(&Isf, XISF_QUAD_IO_FAST_READ, (void*) &ReadParam);
+ if(Status != XST_SUCCESS) {
+ return XST_FAILURE;
+ }
+
+ /*
+ * Wait till the Transfer is complete and check for errors.
+ */
+ while(TransferInProgress);
+ if(ErrorCount != 0) {
+ return XST_FAILURE;
+ }
+
+ /*
+ * Compare the data read against the data written.
+ */
+ for(Index = 0; Index < ISF_PAGE_SIZE; Index++) {
+ if(ReadBuffer[Index + XISF_CMD_SEND_EXTRA_BYTES +
+ QUAD_IO_READ_DUMMY_BYTES] !=
+ (u8)(Index + ISF_TEST_BYTE)) {
+ return XST_FAILURE;
+ }
+ }
+
+ return XST_SUCCESS;
+}
+
+/*****************************************************************************/
+/**
+*
+* This function waits till the Winbond 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 Serial Flash is ready to accept next command.
+*
+******************************************************************************/
+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 complete and check for errors.
+ */
+ while(TransferInProgress);
+ if(ErrorCount != 0) {
+ return XST_FAILURE;
+ }
+
+ /*
+ * Check if the Serial 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 sets the QuadEnable bit in Winbond flash.
+*
+* @param None
+*
+* @return XST_SUCCESS if successful else XST_FAILURE.
+*
+* @note None.
+*
+******************************************************************************/
+static int SpiFlashQuadEnable(void)
+{
+ 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 for errors.
+ */
+ while(TransferInProgress);
+ if(ErrorCount != 0) {
+ return XST_FAILURE;
+ }
+
+ /*
+ * Wait till the Flash is not Busy.
+ */
+ Status = IsfWaitForFlashNotBusy();
+ if(Status != XST_SUCCESS) {
+ return XST_FAILURE;
+ }
+
+ /*
+ * Prepare the WriteBuffer.
+ */
+ WriteBuffer[BYTE1] = 0x00;
+ WriteBuffer[BYTE2] = 0x02; /* QE = 1 */
+
+ /*
+ * Perform the Write operation.
+ */
+ TransferInProgress = TRUE;
+ Status = XIsf_Write(&Isf, XISF_WRITE_STATUS_REG2, (void*) WriteBuffer);
+ if(Status != XST_SUCCESS) {
+ return XST_FAILURE;
+ }
+
+ /*
+ * Wait till the Transfer is complete and check for errors.
+ */
+ 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 is the handler which performs processing for the SPI 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 SPI data
+* completes or an error occurs.
+*
+* This handler provides an example of how to handle SPI interrupts and
+* is application specific.
+*
+* @param CallBackRef is the upper layer callback reference passed back
+* when the callback function is invoked.
+* @param StatusEvent is the event that just occurred.
+* @param ByteCount is the number of bytes transferred up until the event
+* occurred.
+*
+* @return None.
+*
+* @note None.
+*
+******************************************************************************/
+void SpiHandler(void *CallBackRef, u32 StatusEvent, u16 ByteCount)
+{
+ /*
+ * Indicate the transfer on the SPI bus is no longer in progress
+ * regardless of the status event.
+ */
+ TransferInProgress = FALSE;
+
+ /*
+ * If the event was not transfer done, then track it as an error.
+ */
+ if (StatusEvent != XST_SPI_TRANSFER_DONE) {
+ ErrorCount++;
+ }
+}
+
+/*****************************************************************************/
+/**
+*
+* This function setups the interrupt system such that interrupts can occur
+* for the Spi device. This function is application specific since the actual
+* system may or may not have an interrupt controller. The Spi device could be
+* directly connected to a processor without an interrupt controller. The
+* user should modify this function to fit the application.
+*
+* @param SpiPtr is a pointer to the instance of the Spi device.
+*
+* @return XST_SUCCESS if successful, otherwise XST_FAILURE.
+*
+* @note None
+*
+******************************************************************************/
+static int SetupInterruptSystem(XSpi *SpiPtr)
+{
+
+ int Status;
+
+ /*
+ * Initialize the interrupt controller driver so that
+ * it's ready to use, specify the device ID that is generated in
+ * xparameters.h
+ */
+ Status = XIntc_Initialize(&InterruptController, INTC_DEVICE_ID);
+ if(Status != XST_SUCCESS) {
+ return XST_FAILURE;
+ }
+
+ /*
+ * Connect a device driver handler that will be called when an interrupt
+ * for the device occurs, the device driver handler performs the
+ * specific interrupt processing for the device
+ */
+ Status = XIntc_Connect(&InterruptController,
+ SPI_INTR_ID,
+ (XInterruptHandler)XSpi_InterruptHandler,
+ (void *)SpiPtr);
+ if(Status != XST_SUCCESS) {
+ return XST_FAILURE;
+ }
+
+ /*
+ * Start the interrupt controller such that interrupts are enabled for
+ * all devices that cause interrupts, specify real mode so that
+ * the SPI can cause interrupts through the interrupt controller.
+ */
+ Status = XIntc_Start(&InterruptController, XIN_REAL_MODE);
+ if(Status != XST_SUCCESS) {
+ return XST_FAILURE;
+ }
+
+ /*
+ * Enable the interrupt for the SPI.
+ */
+ XIntc_Enable(&InterruptController, SPI_INTR_ID);
+
+ /*
+ * Initialize the exception table.
+ */
+ Xil_ExceptionInit();
+
+ /*
+ * Register the interrupt controller handler with the exception table.
+ */
+ Xil_ExceptionRegisterHandler(XIL_EXCEPTION_ID_INT,
+ (Xil_ExceptionHandler)XIntc_InterruptHandler,
+ &InterruptController);
+
+ /*
+ * Enable non-critical exceptions.
+ */
+ Xil_ExceptionEnable();
+
+ return XST_SUCCESS;
+}
diff --git a/lib/sw_services/xilisf/examples/xilisf_winbond_rdwr_polled_example.c b/lib/sw_services/xilisf/examples/xilisf_winbond_rdwr_polled_example.c
new file mode 100644
index 00000000..6448f8e0
--- /dev/null
+++ b/lib/sw_services/xilisf/examples/xilisf_winbond_rdwr_polled_example.c
@@ -0,0 +1,355 @@
+/******************************************************************************
+*
+* Copyright (C) 2012 - 2014 Xilinx, Inc. All rights reserved.
+*
+* Permission is hereby granted, free of charge, to any person obtaining a copy
+* of this software and associated documentation files (the "Software"), to deal
+* in the Software without restriction, including without limitation the rights
+* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+* copies of the Software, and to permit persons to whom the Software is
+* furnished to do so, subject to the following conditions:
+*
+* The above copyright notice and this permission notice shall be included in
+* all copies or substantial portions of the Software.
+*
+* Use of the Software is limited solely to applications:
+* (a) running on a Xilinx device, or
+* (b) that interact with a Xilinx device through a bus or interconnect.
+*
+* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+* XILINX BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
+* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+* SOFTWARE.
+*
+* Except as contained in this notice, the name of the Xilinx shall not be used
+* in advertising or otherwise to promote the sale, use or other dealings in
+* this Software without prior written authorization from Xilinx.
+*
+******************************************************************************/
+/******************************************************************************
+*
+* @file xilisf_winbond_rdwr_polled_example.c
+*
+* This file contains a design example using the In-system and Serial Flash
+* Library (XilIsf) for Reading/Writing to a Winbond W25QXX/W25XX Serial Flash
+* Device with the Spi driver in polled mode of operation. This example shows
+* the Erase, Read and Write features.
+*
+* This example
+* - Erases a Sector
+* - Writes to a Page within the Erased Sector
+* - Reads back the Page that is written and compares the data
+*
+* This example has been tested with a Winbond Serial Flash Memory (W25Q64) on
+* a Xilinx SP605 board. For further details about the Flash device refer the
+* Winbond Serial Flash Memory (W25Q64) data sheet.
+*
+* @note
+*
+* None.
+*
+*
+* MODIFICATION HISTORY:
+*
+* Ver Who Date Changes
+* ----- --- -------- -----------------------------------------------
+* 2.01a sdm 03/17/10 First release
+*
+*
+*
+******************************************************************************/
+
+/***************************** Include Files *********************************/
+
+#include "xparameters.h" /* EDK generated parameters */
+#include "xilisf.h" /* Serial Flash Library header file */
+
+/************************** Constant Definitions *****************************/
+
+
+/*
+ * The following constants map to the XPAR parameters created in the
+ * xparameters.h file. They are defined here such that a user can easily
+ * change all the needed parameters in one place.
+ */
+#define SPI_DEVICE_ID XPAR_SPI_0_DEVICE_ID
+
+/*
+ * The following constant defines the slave select signal that is used to
+ * to select the Flash device on the SPI bus, this signal is typically
+ * connected to the chip select of the device.
+ */
+#define ISF_SPI_SELECT 0x01
+
+/*
+ * Number of bytes per page in the flash device.
+ */
+#define ISF_PAGE_SIZE 256
+
+/*
+ * Address of the page to perform Erase, Write and Read operations.
+ */
+#define ISF_TEST_ADDRESS 0x010000;
+#define ISF_TEST_BYTE 0x36 /* Test Byte offset value written */
+
+/**************************** Type Definitions *******************************/
+
+/***************** Macros (Inline Functions) Definitions *********************/
+
+/************************** Function Prototypes ******************************/
+
+static int IsfWaitForFlashNotBusy(void);
+
+/************************** 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.
+ */
+static XIsf Isf;
+static XSpi Spi;
+
+/*
+ * The user needs to allocate a buffer to be used by the In-system and Serial
+ * Flash Library to perform any read/write operations on the Serial Flash
+ * device.
+ * User applications must pass the address of this memory to the Library in
+ * Serial Flash Initialization function, for the Library to work.
+ * For Write operations:
+ * - The size of this buffer should be equal to the Number of bytes to be
+ * written to the Serial Flash + XISF_CMD_MAX_EXTRA_BYTES.
+ * - The size of this buffer should be large enough for usage across all the
+ * applications that use a common instance of the Serial Flash.
+ * - A minimum of one byte and a maximum of ISF_PAGE_SIZE bytes can be written
+ * to the Serial Flash, through a single Write operation.
+ * The size of this buffer should be equal to XISF_CMD_MAX_EXTRA_BYTES, if the
+ * application only reads from the Serial Flash (no write operations).
+ */
+u8 IsfWriteBuffer[ISF_PAGE_SIZE + XISF_CMD_SEND_EXTRA_BYTES];
+
+/*
+ * Buffers used during Read/Write transactions.
+ */
+u8 ReadBuffer[ISF_PAGE_SIZE + XISF_CMD_SEND_EXTRA_BYTES]; /* Read Buffer */
+u8 WriteBuffer[ISF_PAGE_SIZE]; /* Write buffer */
+
+/************************** Function Definitions ******************************/
+
+/*****************************************************************************/
+/**
+*
+* Main function to execute the Winbond Serial Flash Read/Write polled example.
+*
+* @param None
+*
+* @return XST_SUCCESS if successful else XST_FAILURE.
+*
+* @note None
+*
+******************************************************************************/
+int main()
+{
+ int Status;
+ u32 Index;
+ u32 Address;
+ XIsf_WriteParam WriteParam;
+ XIsf_ReadParam ReadParam;
+
+
+ /*
+ * Initialize the SPI driver so that it's ready to use,
+ * specify the device ID that is generated in xparameters.h.
+ */
+ Status = XSpi_Initialize(&Spi, SPI_DEVICE_ID);
+ if(Status != XST_SUCCESS) {
+ return XST_FAILURE;
+ }
+
+ /*
+ * Start the SPI driver so that the device is enabled.
+ */
+ XSpi_Start(&Spi);
+
+ /*
+ * Disable Global interrupt to use the Spi driver in polled mode
+ * operation.
+ */
+ XSpi_IntrGlobalDisable(&Spi);
+
+ /*
+ * Initialize the Serial Flash Library.
+ */
+ Status = XIsf_Initialize(&Isf, &Spi, ISF_SPI_SELECT, IsfWriteBuffer);
+ if(Status != XST_SUCCESS) {
+ return XST_FAILURE;
+ }
+
+ /*
+ * Specify the address in the Serial Flash for the Erase/Write/Read
+ * operations.
+ */
+ Address = ISF_TEST_ADDRESS;
+
+ /*
+ * The following code Erases a Sector in the Winbond Serial Flash.
+ */
+
+ /*
+ * Perform the Write Enable operation.
+ */
+ Status = XIsf_WriteEnable(&Isf, XISF_WRITE_ENABLE);
+ if(Status != XST_SUCCESS) {
+ return XST_FAILURE;
+ }
+
+ /*
+ * Wait till the Flash is not Busy.
+ */
+ Status = IsfWaitForFlashNotBusy();
+ if(Status != XST_SUCCESS) {
+ return XST_FAILURE;
+ }
+
+ /*
+ * Perform the Sector Erase operation.
+ */
+ Status = XIsf_Erase(&Isf, XISF_SECTOR_ERASE, Address);
+ if(Status != XST_SUCCESS) {
+ return XST_FAILURE;
+ }
+
+ /*
+ * Wait till the Flash is not Busy.
+ */
+ Status = IsfWaitForFlashNotBusy();
+ if(Status != XST_SUCCESS) {
+ return XST_FAILURE;
+ }
+
+ /*
+ * Perform the Write Enable operation.
+ */
+ Status = XIsf_WriteEnable(&Isf, XISF_WRITE_ENABLE);
+ if(Status != XST_SUCCESS) {
+ return XST_FAILURE;
+ }
+
+ /*
+ * Wait till the Flash is not Busy.
+ */
+ Status = IsfWaitForFlashNotBusy();
+ if(Status != XST_SUCCESS) {
+ return XST_FAILURE;
+ }
+
+ /*
+ * Set the
+ * - Address within the Serial Flash where the data is to be written.
+ * - Number of bytes to be written to the Serial Flash.
+ * - Write Buffer which contains the data to be written to the Serial
+ * Flash.
+ */
+ WriteParam.Address = Address;
+ WriteParam.NumBytes = ISF_PAGE_SIZE;
+ WriteParam.WritePtr = WriteBuffer;
+
+ /*
+ * Prepare the write buffer. Fill in the data need to be written into
+ * Serial Flash.
+ */
+ for(Index = 0; Index < ISF_PAGE_SIZE; Index++) {
+ WriteParam.WritePtr[Index] = Index + ISF_TEST_BYTE;
+ }
+
+ /*
+ * Perform the Write operation.
+ */
+ Status = XIsf_Write(&Isf, XISF_WRITE, (void*) &WriteParam);
+ if(Status != XST_SUCCESS) {
+ return XST_FAILURE;
+ }
+
+ /*
+ * Wait till the Flash is not Busy.
+ */
+ Status = IsfWaitForFlashNotBusy();
+ if(Status != XST_SUCCESS) {
+ return XST_FAILURE;
+ }
+
+ /*
+ * 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.
+ * - Read Buffer to which the data is to be read.
+ */
+ ReadParam.Address = Address;
+ ReadParam.NumBytes = ISF_PAGE_SIZE;
+ ReadParam.ReadPtr = ReadBuffer;
+
+ /*
+ * Perform the read operation.
+ */
+ Status = XIsf_Read(&Isf, XISF_READ, (void*) &ReadParam);
+ if(Status != XST_SUCCESS) {
+ return XST_FAILURE;
+ }
+
+ /*
+ * Compare the data read against the data Written.
+ */
+ for(Index = 0; Index < ISF_PAGE_SIZE; Index++) {
+ if(ReadBuffer[Index + XISF_CMD_SEND_EXTRA_BYTES] !=
+ (u8)(Index + ISF_TEST_BYTE)) {
+ return XST_FAILURE;
+ }
+ }
+
+ return XST_SUCCESS;
+}
+
+/*****************************************************************************/
+/**
+*
+* This function waits till the Winbond 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 Serial Flash is ready to accept next command.
+*
+******************************************************************************/
+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 Serial 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;
+}
diff --git a/lib/sw_services/xilisf/examples/xilisf_winbond_read_write_example.c b/lib/sw_services/xilisf/examples/xilisf_winbond_read_write_example.c
new file mode 100644
index 00000000..88c3f389
--- /dev/null
+++ b/lib/sw_services/xilisf/examples/xilisf_winbond_read_write_example.c
@@ -0,0 +1,555 @@
+/******************************************************************************
+*
+* Copyright (C) 2012 - 2014 Xilinx, Inc. All rights reserved.
+*
+* Permission is hereby granted, free of charge, to any person obtaining a copy
+* of this software and associated documentation files (the "Software"), to deal
+* in the Software without restriction, including without limitation the rights
+* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+* copies of the Software, and to permit persons to whom the Software is
+* furnished to do so, subject to the following conditions:
+*
+* The above copyright notice and this permission notice shall be included in
+* all copies or substantial portions of the Software.
+*
+* Use of the Software is limited solely to applications:
+* (a) running on a Xilinx device, or
+* (b) that interact with a Xilinx device through a bus or interconnect.
+*
+* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+* XILINX BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
+* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+* SOFTWARE.
+*
+* Except as contained in this notice, the name of the Xilinx shall not be used
+* in advertising or otherwise to promote the sale, use or other dealings in
+* this Software without prior written authorization from Xilinx.
+*
+******************************************************************************/
+/******************************************************************************
+*
+* @file xilisf_winbond_read_write_example.c
+*
+* This file contains a design example using the In-system and Serial Flash
+* Library (XilIsf) for Reading/Writing to a Winbond W25QXX/W25XX Serial Flash
+* Device. This example shows the Erase, Read and Write features.
+*
+* This example
+* - Erases a Sector
+* - Writes to a Page within the Erased Sector
+* - Reads back the Page that is written and compares the data
+*
+* This example has been tested with a Winbond Serial Flash Memory (W25Q64) on
+* a Xilinx SP605 board. For further details about the Flash device refer the
+* Winbond Serial Flash Memory (W25Q64) data sheet.
+*
+* @note
+*
+* None.
+*
+*
+* MODIFICATION HISTORY:
+*
+* 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.
+*
+*
+******************************************************************************/
+
+/***************************** Include Files *********************************/
+
+#include "xparameters.h" /* EDK generated parameters */
+#include "xintc.h" /* Interrupt controller device driver */
+#include /* Serial Flash Library header file */
+#include "xil_exception.h"
+
+/************************** Constant Definitions *****************************/
+
+
+/*
+ * The following constants map to the XPAR parameters created in the
+ * xparameters.h file. They are defined here such that a user can easily
+ * change all the needed parameters in one place.
+ */
+#define SPI_DEVICE_ID XPAR_SPI_0_DEVICE_ID
+#define INTC_DEVICE_ID XPAR_INTC_0_DEVICE_ID
+#define SPI_INTR_ID XPAR_INTC_0_SPI_0_VEC_ID
+
+/*
+ * The following constant defines the slave select signal that is used to
+ * to select the Flash device on the SPI bus, this signal is typically
+ * connected to the chip select of the device.
+ */
+#define ISF_SPI_SELECT 0x01
+
+/*
+ * Number of bytes per page in the flash device.
+ */
+#define ISF_PAGE_SIZE 256
+
+/*
+ * Address of the page to perform Erase, Write and Read operations.
+ */
+#define ISF_TEST_ADDRESS 0x010000;
+#define ISF_TEST_BYTE 0x05 /* Test Byte offset value written */
+
+/**************************** Type Definitions *******************************/
+
+/***************** Macros (Inline Functions) Definitions *********************/
+
+/************************** Function Prototypes ******************************/
+
+static int IsfWaitForFlashNotBusy(void);
+void SpiHandler(void *CallBackRef, u32 StatusEvent, u16 ByteCount);
+static int SetupInterruptSystem(XSpi *SpiPtr);
+
+/************************** 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.
+ */
+static XIsf Isf;
+static XIntc InterruptController;
+static XSpi Spi;
+
+/*
+ * The following variables are shared between non-interrupt processing and
+ * interrupt processing such that they must be global.
+ */
+volatile static int TransferInProgress; /* State of Spi Transfer */
+static int ErrorCount; /* Errors occurred during Spi transfers */
+
+/*
+ * The user needs to allocate a buffer to be used by the In-system and Serial
+ * Flash Library to perform any read/write operations on the Serial Flash
+ * device.
+ * User applications must pass the address of this memory to the Library in
+ * Serial Flash Initialization function, for the Library to work.
+ * For Write operations:
+ * - The size of this buffer should be equal to the Number of bytes to be
+ * written to the Serial Flash + XISF_CMD_MAX_EXTRA_BYTES.
+ * - The size of this buffer should be large enough for usage across all the
+ * applications that use a common instance of the Serial Flash.
+ * - A minimum of one byte and a maximum of ISF_PAGE_SIZE bytes can be written
+ * to the Serial Flash, through a single Write operation.
+ * The size of this buffer should be equal to XISF_CMD_MAX_EXTRA_BYTES, if the
+ * application only reads from the Serial Flash (no write operations).
+ */
+u8 IsfWriteBuffer[ISF_PAGE_SIZE + XISF_CMD_SEND_EXTRA_BYTES];
+
+/*
+ * Buffers used during Read/Write transactions.
+ */
+u8 ReadBuffer[ISF_PAGE_SIZE + XISF_CMD_SEND_EXTRA_BYTES]; /* Read Buffer */
+u8 WriteBuffer[ISF_PAGE_SIZE]; /* Write buffer */
+
+/************************** Function Definitions ******************************/
+
+/*****************************************************************************/
+/**
+*
+* Main function to execute the Winbond Serial Flash Read/Write example.
+*
+* @param None
+*
+* @return XST_SUCCESS if successful else XST_FAILURE.
+*
+* @note None
+*
+******************************************************************************/
+int main()
+{
+ int Status;
+ u32 Index;
+ u32 Address;
+ XIsf_WriteParam WriteParam;
+ XIsf_ReadParam ReadParam;
+
+ /*
+ * Initialize the SPI driver so that it's ready to use,
+ * specify the device ID that is generated in xparameters.h.
+ */
+ Status = XSpi_Initialize(&Spi, SPI_DEVICE_ID);
+ if(Status != XST_SUCCESS) {
+ return XST_FAILURE;
+ }
+
+ /*
+ * Connect the SPI driver to the interrupt subsystem such that
+ * interrupts can occur. This function is application specific.
+ */
+ Status = SetupInterruptSystem(&Spi);
+ if(Status != XST_SUCCESS) {
+ return XST_FAILURE;
+ }
+
+ /*
+ * Setup the handler for the SPI that will be called from the interrupt
+ * context when an SPI status occurs, specify a pointer to the SPI
+ * driver instance as the callback reference so the handler is able to
+ * access the instance data.
+ */
+ XIsf_SetStatusHandler(&Isf, &Spi, (XSpi_StatusHandler)SpiHandler);
+
+ /*
+ * Start the SPI driver so that interrupts and the device are enabled.
+ */
+ XSpi_Start(&Spi);
+
+ /*
+ * Initialize the Serial Flash Library.
+ */
+ Status = XIsf_Initialize(&Isf, &Spi, ISF_SPI_SELECT, IsfWriteBuffer);
+ if(Status != XST_SUCCESS) {
+ 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.
+ */
+ Address = ISF_TEST_ADDRESS;
+
+ /*
+ * The following code Erases a Sector in the Winbond Serial Flash.
+ */
+
+ /*
+ * 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 for errors.
+ */
+ while(TransferInProgress);
+ if(ErrorCount != 0) {
+ return XST_FAILURE;
+ }
+
+ /*
+ * Wait till the Flash is not Busy.
+ */
+ Status = IsfWaitForFlashNotBusy();
+ if(Status != XST_SUCCESS) {
+ return XST_FAILURE;
+ }
+
+ /*
+ * Perform the Sector Erase operation.
+ */
+ TransferInProgress = TRUE;
+ Status = XIsf_Erase(&Isf, XISF_SECTOR_ERASE, Address);
+ if(Status != XST_SUCCESS) {
+ return XST_FAILURE;
+ }
+
+ /*
+ * Wait till the Transfer is complete and check for errors.
+ */
+ while(TransferInProgress);
+ if(ErrorCount != 0) {
+ return XST_FAILURE;
+ }
+
+ /*
+ * Wait till the Flash is not Busy.
+ */
+ Status = IsfWaitForFlashNotBusy();
+ if(Status != XST_SUCCESS) {
+ return XST_FAILURE;
+ }
+
+ /*
+ * 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 for errors.
+ */
+ while(TransferInProgress);
+ if(ErrorCount != 0) {
+ return XST_FAILURE;
+ }
+
+ /*
+ * Wait till the Flash is not Busy.
+ */
+ Status = IsfWaitForFlashNotBusy();
+ if(Status != XST_SUCCESS) {
+ return XST_FAILURE;
+ }
+
+ /*
+ * Set the
+ * - Address within the Serial Flash where the data is to be written.
+ * - Number of bytes to be written to the Serial Flash.
+ * - Write Buffer which contains the data to be written to the Serial
+ * Flash.
+ */
+ WriteParam.Address = Address;
+ WriteParam.NumBytes = ISF_PAGE_SIZE;
+ WriteParam.WritePtr = WriteBuffer;
+
+ /*
+ * Prepare the write buffer. Fill in the data need to be written into
+ * Serial Flash.
+ */
+ for(Index = 0; Index < ISF_PAGE_SIZE; Index++) {
+ WriteParam.WritePtr[Index] = Index + ISF_TEST_BYTE;
+ }
+
+ /*
+ * Perform the Write operation.
+ */
+ TransferInProgress = TRUE;
+ Status = XIsf_Write(&Isf, XISF_WRITE, (void*) &WriteParam);
+ if(Status != XST_SUCCESS) {
+ return XST_FAILURE;
+ }
+
+ /*
+ * Wait till the Transfer is complete and check for errors.
+ */
+ while(TransferInProgress);
+ if(ErrorCount != 0) {
+ return XST_FAILURE;
+ }
+
+ /*
+ * Wait till the Flash is not Busy.
+ */
+ Status = IsfWaitForFlashNotBusy();
+ if(Status != XST_SUCCESS) {
+ return XST_FAILURE;
+ }
+
+ /*
+ * 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.
+ * - Read Buffer to which the data is to be read.
+ */
+ ReadParam.Address = Address;
+ ReadParam.NumBytes = ISF_PAGE_SIZE;
+ ReadParam.ReadPtr = ReadBuffer;
+
+ /*
+ * Perform the read operation.
+ */
+ TransferInProgress = TRUE;
+ Status = XIsf_Read(&Isf, XISF_READ, (void*) &ReadParam);
+ if(Status != XST_SUCCESS) {
+ return XST_FAILURE;
+ }
+
+ /*
+ * Wait till the Transfer is complete and check for errors.
+ */
+ while(TransferInProgress);
+ if(ErrorCount != 0) {
+ return XST_FAILURE;
+ }
+
+ /*
+ * Compare the data read against the data Written.
+ */
+ for(Index = 0; Index < ISF_PAGE_SIZE; Index++) {
+ if(ReadBuffer[Index + XISF_CMD_SEND_EXTRA_BYTES] !=
+ (u8)(Index + ISF_TEST_BYTE)) {
+ return XST_FAILURE;
+ }
+ }
+
+ return XST_SUCCESS;
+}
+
+/*****************************************************************************/
+/**
+*
+* This function waits till the Winbond 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 Serial Flash is ready to accept next command.
+*
+******************************************************************************/
+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 complete and check for errors.
+ */
+ while(TransferInProgress);
+ if(ErrorCount != 0) {
+ return XST_FAILURE;
+ }
+
+ /*
+ * Check if the Serial 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 SPI 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 SPI data
+* completes or an error occurs.
+*
+* This handler provides an example of how to handle SPI interrupts and
+* is application specific.
+*
+* @param CallBackRef is the upper layer callback reference passed back
+* when the callback function is invoked.
+* @param StatusEvent is the event that just occurred.
+* @param ByteCount is the number of bytes transferred up until the event
+* occurred.
+*
+* @return None.
+*
+* @note None.
+*
+******************************************************************************/
+void SpiHandler(void *CallBackRef, u32 StatusEvent, u16 ByteCount)
+{
+ /*
+ * Indicate the transfer on the SPI bus is no longer in progress
+ * regardless of the status event.
+ */
+ TransferInProgress = FALSE;
+
+ /*
+ * If the event was not transfer done, then track it as an error.
+ */
+ if (StatusEvent != XST_SPI_TRANSFER_DONE) {
+ ErrorCount++;
+ }
+}
+
+/*****************************************************************************/
+/**
+*
+* This function setups the interrupt system such that interrupts can occur
+* for the Spi device. This function is application specific since the actual
+* system may or may not have an interrupt controller. The Spi device could be
+* directly connected to a processor without an interrupt controller. The
+* user should modify this function to fit the application.
+*
+* @param SpiPtr is a pointer to the instance of the Spi device.
+*
+* @return XST_SUCCESS if successful, otherwise XST_FAILURE.
+*
+* @note None
+*
+******************************************************************************/
+static int SetupInterruptSystem(XSpi *SpiPtr)
+{
+
+ int Status;
+
+ /*
+ * Initialize the interrupt controller driver so that
+ * it's ready to use, specify the device ID that is generated in
+ * xparameters.h
+ */
+ Status = XIntc_Initialize(&InterruptController, INTC_DEVICE_ID);
+ if(Status != XST_SUCCESS) {
+ return XST_FAILURE;
+ }
+
+ /*
+ * Connect a device driver handler that will be called when an interrupt
+ * for the device occurs, the device driver handler performs the
+ * specific interrupt processing for the device
+ */
+ Status = XIntc_Connect(&InterruptController,
+ SPI_INTR_ID,
+ (XInterruptHandler)XSpi_InterruptHandler,
+ (void *)SpiPtr);
+ if(Status != XST_SUCCESS) {
+ return XST_FAILURE;
+ }
+
+ /*
+ * Start the interrupt controller such that interrupts are enabled for
+ * all devices that cause interrupts, specify real mode so that
+ * the SPI can cause interrupts through the interrupt controller.
+ */
+ Status = XIntc_Start(&InterruptController, XIN_REAL_MODE);
+ if(Status != XST_SUCCESS) {
+ return XST_FAILURE;
+ }
+
+ /*
+ * Enable the interrupt for the SPI.
+ */
+ XIntc_Enable(&InterruptController, SPI_INTR_ID);
+
+ /*
+ * Initialize the exception table.
+ */
+ Xil_ExceptionInit();
+
+ /*
+ * Register the interrupt controller handler with the exception table.
+ */
+ Xil_ExceptionRegisterHandler(XIL_EXCEPTION_ID_INT,
+ (Xil_ExceptionHandler)XIntc_InterruptHandler,
+ &InterruptController);
+
+ /*
+ * Enable non-critical exceptions.
+ */
+ Xil_ExceptionEnable();
+
+ return XST_SUCCESS;
+}
diff --git a/lib/sw_services/xilisf/examples/xilisf_winbond_spr_example.c b/lib/sw_services/xilisf/examples/xilisf_winbond_spr_example.c
new file mode 100644
index 00000000..54617004
--- /dev/null
+++ b/lib/sw_services/xilisf/examples/xilisf_winbond_spr_example.c
@@ -0,0 +1,754 @@
+/******************************************************************************
+*
+* Copyright (C) 2012 - 2014 Xilinx, Inc. All rights reserved.
+*
+* Permission is hereby granted, free of charge, to any person obtaining a copy
+* of this software and associated documentation files (the "Software"), to deal
+* in the Software without restriction, including without limitation the rights
+* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+* copies of the Software, and to permit persons to whom the Software is
+* furnished to do so, subject to the following conditions:
+*
+* The above copyright notice and this permission notice shall be included in
+* all copies or substantial portions of the Software.
+*
+* Use of the Software is limited solely to applications:
+* (a) running on a Xilinx device, or
+* (b) that interact with a Xilinx device through a bus or interconnect.
+*
+* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+* XILINX BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
+* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+* SOFTWARE.
+*
+* Except as contained in this notice, the name of the Xilinx shall not be used
+* in advertising or otherwise to promote the sale, use or other dealings in
+* this Software without prior written authorization from Xilinx.
+*
+******************************************************************************/
+/******************************************************************************
+*
+* @file xilisf_winbond_spr_example.c
+*
+* This file contains a design example using the Xilinx In-system and Serial
+* Flash Library (XilIsf). This example shows the usage of Sector Erase, Sector
+* Protection, Read and Write features on a Winbond W25QXX/W25XX Serial Flash
+* Device.
+
+* This example
+* - Erases a Sector
+* - Writes to a Page within the erased Sector
+* - Enables the Sector Protection so that all the sectors are Write protected
+* - Erases a Page (This should not happen as the Sectors are Write protected
+* - Reads back the Page that is written and compares the data
+*
+* This example has been tested with a Winbond Serial Flash Memory (W25Q64) on
+* a Xilinx SP605 board. For further details about the Flash device refer the
+* Winbond Serial Flash Memory (W25Q64) data sheet.
+*
+* @note
+*
+* None.
+*
+*
+* MODIFICATION HISTORY:
+*
+* 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.
+*
+*
+******************************************************************************/
+
+/***************************** Include Files *********************************/
+
+#include "xparameters.h" /* EDK generated parameters */
+#include "xintc.h" /* Interrupt controller device driver */
+#include "xspi.h" /* SPI device driver */
+#include /* Serial Flash Library header file */
+#include "xil_exception.h"
+
+/************************** Constant Definitions *****************************/
+
+
+/*
+ * The following constants map to the XPAR parameters created in the
+ * xparameters.h file. They are defined here such that a user can easily
+ * change all the needed parameters in one place.
+ */
+#define SPI_DEVICE_ID XPAR_SPI_0_DEVICE_ID
+#define INTC_DEVICE_ID XPAR_INTC_0_DEVICE_ID
+#define SPI_INTR_ID XPAR_INTC_0_SPI_0_VEC_ID
+
+/*
+ * The following constant defines the slave select signal that is used to
+ * to select the Serial Flash on the SPI bus, this signal is typically
+ * connected to the chip select of the device.
+ */
+#define ISF_SPI_SELECT 0x01
+
+/*
+ * Number of bytes per page in the Serial Flash.
+ */
+#define ISF_PAGE_SIZE 256
+
+/*
+ * Address of the page to perform Erase, Write and Read operations.
+ */
+#define ISF_TEST_ADDRESS 0x010000;
+#define ISF_TEST_BYTE 0x15 /* Test Byte offset value written */
+
+/**************************** Type Definitions *******************************/
+
+/***************** Macros (Inline Functions) Definitions *********************/
+
+/************************** Function Prototypes ******************************/
+
+static int IsfWaitForFlashNotBusy(void);
+void SpiHandler(void *CallBackRef, u32 StatusEvent, u16 ByteCount);
+static int SetupInterruptSystem(XSpi *SpiPtr);
+
+/************************** 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.
+ */
+static XIsf Isf;
+static XIntc InterruptController;
+static XSpi Spi;
+
+/*
+ * The following variables are shared between non-interrupt processing and
+ * interrupt processing such that they must be global.
+ */
+volatile static int TransferInProgress;
+
+/*
+ * The following variable tracks any errors that occur during interrupt
+ * processing.
+ */
+static int ErrorCount;
+
+/*
+ * The user needs to allocate a buffer to be used by the In-system and Serial
+ * Flash Library to perform any read/write operations on the Serial Flash
+ * device.
+ * User applications must pass the address of this memory to the Library in
+ * Serial Flash Initialization function, for the Library to work.
+ * For Write operations:
+ * - The size of this buffer should be equal to the Number of bytes to be
+ * written to the Serial Flash + XISF_CMD_MAX_EXTRA_BYTES.
+ * - The size of this buffer should be large enough for usage across all the
+ * applications that use a common instance of the Serial Flash.
+ * - A minimum of one byte and a maximum of ISF_PAGE_SIZE bytes can be written
+ * to the Serial Flash, through a single Write operation.
+ * The size of this buffer should be equal to XISF_CMD_MAX_EXTRA_BYTES, if the
+ * application only reads from the Serial Flash (no write operations).
+ */
+u8 IsfWriteBuffer[ISF_PAGE_SIZE + XISF_CMD_SEND_EXTRA_BYTES];
+
+/*
+ * Buffers used during read and write transactions.
+ */
+u8 ReadBuffer[ISF_PAGE_SIZE + XISF_CMD_SEND_EXTRA_BYTES];
+u8 WriteBuffer[ISF_PAGE_SIZE];
+
+/************************** Function Definitions ******************************/
+
+/*****************************************************************************/
+/**
+*
+* Main function to execute the Winbond Serial Flash SPR example.
+*
+* @param None
+*
+* @return XST_SUCCESS if successful else XST_FAILURE.
+*
+* @note None
+*
+******************************************************************************/
+int main()
+{
+ int Status;
+ u32 Index;
+ u32 Address;
+ XIsf_WriteParam WriteParam;
+ XIsf_ReadParam ReadParam;
+
+
+ /*
+ * Initialize the SPI driver so that it's ready to use,
+ * specify the device ID that is generated in xparameters.h.
+ */
+ Status = XSpi_Initialize(&Spi, SPI_DEVICE_ID);
+ if(Status != XST_SUCCESS) {
+ return XST_FAILURE;
+ }
+
+ /*
+ * Connect the SPI driver to the interrupt subsystem such that
+ * interrupts can occur. This function is application specific.
+ */
+ Status = SetupInterruptSystem(&Spi);
+ if(Status != XST_SUCCESS) {
+ return XST_FAILURE;
+ }
+
+ /*
+ * Setup the handler for the SPI that will be called from the interrupt
+ * context when an SPI status occurs, specify a pointer to the SPI
+ * driver instance as the callback reference so the handler is able to
+ * access the instance data.
+ */
+ XIsf_SetStatusHandler(&Isf, &Spi, (XSpi_StatusHandler)SpiHandler);
+
+ /*
+ * Start the SPI driver so that interrupts and the device are enabled.
+ */
+ XSpi_Start(&Spi);
+
+ /*
+ * Initialize the Serial Flash Library.
+ */
+ Status = XIsf_Initialize(&Isf, &Spi, ISF_SPI_SELECT, IsfWriteBuffer);
+ if(Status != XST_SUCCESS) {
+ 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.
+ */
+ Address = ISF_TEST_ADDRESS;
+
+ /*
+ * 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;
+ }
+
+ /*
+ * Perform the Sector Erase operation.
+ */
+ TransferInProgress = TRUE;
+ Status = XIsf_Erase(&Isf, XISF_SECTOR_ERASE, Address);
+ 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;
+ }
+
+ /*
+ * 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;
+ }
+
+ /*
+ * Set the
+ * - Address within the Serial Flash where the data is to be written.
+ * - Number of bytes to be written to the Serial Flash.
+ * - Write Buffer which contains the data to be written to the Serial
+ * Flash.
+ */
+ WriteParam.Address = Address;
+ WriteParam.NumBytes = ISF_PAGE_SIZE;
+ WriteParam.WritePtr = WriteBuffer;
+
+ /*
+ * Prepare the write buffer. Fill in the data that needs to be written
+ * to the Serial Flash.
+ */
+ for(Index = 0; Index < ISF_PAGE_SIZE; Index++) {
+ WriteParam.WritePtr[Index] = Index + ISF_TEST_BYTE;
+ }
+
+ /*
+ * Perform the Write operation.
+ */
+ TransferInProgress = TRUE;
+ Status = XIsf_Write(&Isf, XISF_WRITE, (void*) &WriteParam);
+ 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;
+ }
+
+ /*
+ * 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;
+ }
+
+ /*
+ * Read the sector protection register.
+ */
+ TransferInProgress = TRUE;
+ Status = XIsf_SectorProtect(&Isf, XISF_SPR_READ, ReadBuffer);
+ 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;
+ }
+
+ /*
+ * Set all the block protection bits in the sector protection register
+ * value read above and write it back to the sector protection register
+ * to disable protection for all sectors.
+ */
+ WriteBuffer[BYTE1] = ReadBuffer[BYTE2] |
+ (XISF_SR_BLOCK_PROTECT_MASK);
+
+ /*
+ * Enable the sector protection.
+ */
+ TransferInProgress = TRUE;
+ Status = XIsf_SectorProtect(&Isf, XISF_SPR_WRITE, WriteBuffer);
+ 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;
+ }
+
+ /*
+ * 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;
+ }
+
+ /*
+ * Perform the Sector Erase operation. This should not work as sector
+ * protection is enabled for all the sectors.
+ */
+ TransferInProgress = TRUE;
+ Status = XIsf_Erase(&Isf, XISF_SECTOR_ERASE, Address);
+ 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;
+ }
+
+ /*
+ * Read the sector protection register.
+ */
+ TransferInProgress = TRUE;
+ Status = XIsf_SectorProtect(&Isf, XISF_SPR_READ, ReadBuffer);
+ 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;
+ }
+
+ /*
+ * Clear all the block protection bits in the sector protection register
+ * value read above and write it back to the sector protection register
+ * to disable protection for all sectors.
+ */
+ WriteBuffer[BYTE1] = ReadBuffer[BYTE2] &
+ ~(XISF_SR_BLOCK_PROTECT_MASK);
+
+ /*
+ * Disable the sector protection.
+ */
+ TransferInProgress = TRUE;
+ Status = XIsf_SectorProtect(&Isf, XISF_SPR_WRITE, WriteBuffer);
+ 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;
+ }
+
+ /*
+ * 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.
+ * - Read Buffer to which the data is to be read.
+ */
+ ReadParam.Address = Address;
+ ReadParam.NumBytes = ISF_PAGE_SIZE;
+ ReadParam.ReadPtr = ReadBuffer;
+
+ /*
+ * Perform the Read operation.
+ */
+ TransferInProgress = TRUE;
+ Status = XIsf_Read(&Isf, XISF_READ, (void*) &ReadParam);
+ 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;
+ }
+
+ /*
+ * Compare the data read against the data written.
+ */
+ for(Index = 0; Index < ISF_PAGE_SIZE; Index++) {
+ if(ReadBuffer[Index + XISF_CMD_SEND_EXTRA_BYTES] !=
+ (u8)(Index + ISF_TEST_BYTE)) {
+ return XST_FAILURE;
+ }
+ }
+
+ return XST_SUCCESS;
+}
+
+/*****************************************************************************/
+/**
+*
+* This function waits till the Winbond Serial Flash is ready to accept the 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 SPI 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 SPI data
+* completes or an error occurs.
+*
+* This handler provides an example of how to handle SPI interrupts and
+* is application specific.
+*
+* @param CallBackRef is the upper layer callback reference passed back
+* when the callback function is invoked.
+* @param StatusEvent is the event that just occurred.
+* @param ByteCount is the number of bytes transferred up until the event
+* occurred.
+*
+* @return None.
+*
+* @note None.
+*
+******************************************************************************/
+void SpiHandler(void *CallBackRef, u32 StatusEvent, u16 ByteCount)
+{
+ /*
+ * Indicate the transfer on the SPI bus is no longer in progress
+ * regardless of the status event.
+ */
+ TransferInProgress = FALSE;
+
+ /*
+ * If the event was not transfer done, then track it as an error.
+ */
+ if (StatusEvent != XST_SPI_TRANSFER_DONE) {
+ ErrorCount++;
+ }
+}
+
+/*****************************************************************************/
+/**
+*
+* This function setups the interrupt system such that interrupts can occur
+* for the Spi device. This function is application specific since the actual
+* system may or may not have an interrupt controller. The Spi device could be
+* directly connected to a processor without an interrupt controller. The
+* user should modify this function to fit the application.
+*
+* @param SpiPtr is a pointer to the instance of the Spi device.
+*
+* @return XST_SUCCESS if successful, otherwise XST_FAILURE.
+*
+* @note None
+*
+******************************************************************************/
+static int SetupInterruptSystem(XSpi *SpiPtr)
+{
+
+ int Status;
+
+ /*
+ * Initialize the interrupt controller driver so that
+ * it's ready to use, specify the device ID that is generated in
+ * xparameters.h.
+ */
+ Status = XIntc_Initialize(&InterruptController, INTC_DEVICE_ID);
+ if(Status != XST_SUCCESS) {
+ return XST_FAILURE;
+ }
+
+ /*
+ * Connect a device driver handler that will be called when an interrupt
+ * for the device occurs, the device driver handler performs the
+ * specific interrupt processing for the device.
+ */
+ Status = XIntc_Connect(&InterruptController,
+ SPI_INTR_ID,
+ (XInterruptHandler)XSpi_InterruptHandler,
+ (void *)SpiPtr);
+ if(Status != XST_SUCCESS) {
+ return XST_FAILURE;
+ }
+
+ /*
+ * Start the interrupt controller such that interrupts are enabled for
+ * all devices that cause interrupts, specific real mode so that
+ * the SPI can cause interrupts thru the interrupt controller.
+ */
+ Status = XIntc_Start(&InterruptController, XIN_REAL_MODE);
+ if(Status != XST_SUCCESS) {
+ return XST_FAILURE;
+ }
+
+ /*
+ * Enable the interrupt for the SPI.
+ */
+ XIntc_Enable(&InterruptController, SPI_INTR_ID);
+
+
+ /*
+ * Initialize the exception table.
+ */
+ Xil_ExceptionInit();
+
+ /*
+ * Register the interrupt controller handler with the exception table.
+ */
+ Xil_ExceptionRegisterHandler(XIL_EXCEPTION_ID_INT,
+ (Xil_ExceptionHandler)XIntc_InterruptHandler,
+ &InterruptController);
+
+ /*
+ * Enable non-critical exceptions.
+ */
+ Xil_ExceptionEnable();
+
+ return XST_SUCCESS;
+}
diff --git a/lib/sw_services/xilisf/src/Makefile b/lib/sw_services/xilisf/src/Makefile
new file mode 100644
index 00000000..373cce17
--- /dev/null
+++ b/lib/sw_services/xilisf/src/Makefile
@@ -0,0 +1,89 @@
+###############################################################################
+#
+# Copyright (C) 2012 - 2015 Xilinx, Inc. All rights reserved.
+#
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to deal
+# in the Software without restriction, including without limitation the rights
+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+# copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included in
+# all copies or substantial portions of the Software.
+#
+# Use of the Software is limited solely to applications:
+# (a) running on a Xilinx device, or
+# (b) that interact with a Xilinx device through a bus or interconnect.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+# XILINX BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+# WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
+# OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+# SOFTWARE.
+#
+# Except as contained in this notice, the name of the Xilinx shall not be used
+# in advertising or otherwise to promote the sale, use or other dealings in
+# this Software without prior written authorization from Xilinx.
+#
+###############################################################################
+
+COMPILER=
+ARCHIVER=
+CP=cp
+COMPILER_FLAGS=
+EXTRA_COMPILER_FLAGS=
+
+RELEASEDIR=../../../lib
+INCLUDEDIR=../../../include
+INCLUDES=-I${INCLUDEDIR}
+ISF_DIR = .
+
+LIB_SRCS = $(ISF_DIR)/xilisf.c \
+ $(ISF_DIR)/xilisf_read.c \
+ $(ISF_DIR)/xilisf_erase.c \
+ $(ISF_DIR)/xilisf_write.c \
+ $(ISF_DIR)/xilisf_spr.c
+
+# create ISF_SRCS based on configured options
+
+ISF_SRCS = $(LIB_SRCS)
+
+ISF_OBJS = $(ISF_SRCS:%.c=%.o)
+
+
+EXPORT_INCLUDE_FILES = $(ISF_DIR)/include/xilisf.h \
+ $(ISF_DIR)/include/xilisf_atmel.h \
+ $(ISF_DIR)/include/xilisf_intelstm.h
+
+
+libs: libxilisf.a
+ cp libxilisf.a $(RELEASEDIR)
+ make clean
+
+include:
+ @for i in $(EXPORT_INCLUDE_FILES); do \
+ echo ${CP} -r $$i ${INCLUDEDIR}; \
+ ${CP} -r $$i ${INCLUDEDIR}; \
+ done
+
+clean:
+ rm -rf obj/*.o
+ rmdir obj
+ rm libxilisf.a
+
+
+libxilisf.a: obj_dir print_msg_isf_base $(ISF_OBJS)
+ @echo "Creating archive $@"
+ $(ARCHIVER) rc $@ obj/*.o
+
+obj_dir:
+ mkdir obj
+
+print_msg_isf_base:
+ @echo "Compiling XilIsf Library"
+
+.c.o:
+ $(COMPILER) $(COMPILER_FLAGS) $(EXTRA_COMPILER_FLAGS) $(INCLUDES) -c $< -o obj/$(@F)
diff --git a/lib/sw_services/xilisf/src/include/xilisf.h b/lib/sw_services/xilisf/src/include/xilisf.h
new file mode 100644
index 00000000..0a6d4e58
--- /dev/null
+++ b/lib/sw_services/xilisf/src/include/xilisf.h
@@ -0,0 +1,1045 @@
+/******************************************************************************
+*
+* Copyright (C) 2012 - 2015 Xilinx, Inc. All rights reserved.
+*
+* Permission is hereby granted, free of charge, to any person obtaining a copy
+* of this software and associated documentation files (the "Software"), to deal
+* in the Software without restriction, including without limitation the rights
+* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+* copies of the Software, and to permit persons to whom the Software is
+* furnished to do so, subject to the following conditions:
+*
+* The above copyright notice and this permission notice shall be included in
+* all copies or substantial portions of the Software.
+*
+* Use of the Software is limited solely to applications:
+* (a) running on a Xilinx device, or
+* (b) that interact with a Xilinx device through a bus or interconnect.
+*
+* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+* XILINX BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
+* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+* SOFTWARE.
+*
+* Except as contained in this notice, the name of the Xilinx shall not be used
+* in advertising or otherwise to promote the sale, use or other dealings in
+* this Software without prior written authorization from Xilinx.
+*
+******************************************************************************/
+/*****************************************************************************/
+/**
+*
+* @file xilisf.h
+*
+* The Xilinx In-system and Serial Flash (XilIsf) Library supports the Xilinx
+* In-system Flash and, external Serial Flash Memories from Atmel (AT45XXXD),
+* Intel (S33), ST Microelectronics (STM) (M25PXX), Winbond (W25QXX/W25XX),
+* Numonyx (N25QXX) devices. Intel (S33) and STM (M25PXX) Serial Flash devices
+* are now a part of Serial Flash devices provided by Numonyx.
+*
+* This library also supports the Spansion (S25FLXX) devices, but this family
+* hasn't been tested. The support for this family of devices is limited to the
+* common commands supported by the other flash families
+*
+* The following instructions are not supported in WinBond (W25QXX/W25XX) -
+* Block Erase 32KB, Erase Suspend/Resume, Mode Bit Reset, Read Unique ID,
+* and Read Manufacturer/Device ID.
+*
+* The following instructions are not supported in Numonyx (N25QXX)- Erase
+* Suspend/Resume, Read/Write Volatile/Non-volatile configuration register.
+*
+* Library Description
+*
+* 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 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.
+*
+* The library supports interrupt driven mode and polled mode based on the
+* mode in which the Spi driver is configured by the user.
+*
+* - Polled Mode of operation: All the APIs are blocking in this mode.
+* - Interrupt mode of operation: It is the application's responsibility to
+* acknowledge the associated Interrupt Controller's interrupts.
+* The transfer is initiated and the control is given back to the user
+* application. The user application has to keep track of whether the initiated
+* operation is completed successfully.
+*
+* This library can support multiple instances of Serial Flash at a time,
+* provided they are of the same device family (either Atmel, Intel, STM or
+* Spansion) as the device family is selected at compile time.
+*
+* Device Operation
+*
+* The Serial Flash operates as a slave device on the SPI bus, with Xilinx SPI
+* core operating as the Master. The library uses XSpi driver for communicating
+* with the Serial Flash.
+*
+* Device Geometry
+*
+* - Atmel (AT45XXXD)/Xilinx ISF:
+* The Atmel Serial Flash is divided into Sectors. Each Sector consists of
+* multiple Blocks. Each Block contains multiple Pages. Each Page contains
+* multiple Bytes. The Number of Sectors, Blocks Per Sector, Pages Per Block and
+* Bytes Per Page vary for different devices within this family.
+* There are two addressing modes supported by the Atmel Serial Flash:
+* - Default-Addressing Mode.
+* - Power-Of-2 Addressing mode.
+*
+* In Default Addressing mode the Atmel Serial Flash contains approximately 3%
+* more Addressing memory than the Power-Of-2 addressing mode. The addressing
+* mode of the Atmel Serial Flash can be known by reading the Device Status
+* Register The ISF in the Xilinx devices is in Default-Addressing mode by
+* default.
+*
+* The following Atmel flash memories are supported by this library.
+* AT45DB011D AT45DB021D AT45DB041D
+* AT45DB081D AT45DB161D AT45DB321D
+* AT45DB642D
+*
+* - Intel (Numonyx) (S33) and STM (Numonyx)(M25PXX):
+* The Intel and STM Serial Flash is divided into Sectors. Each Sector consists
+* of multiple pages. Each Page contains 256 Bytes. The Number of Sectors
+* and Pages Per Sectors vary for different devices within this family.
+*
+* The following Intel and STM flash memories are supported by this library.
+* S3316MBIT S3332MBIT S3364MBIT
+*
+* M25P05_A M25P10_A M25P20
+* M25P40 M25P80 M25P16
+* M25P32 M25P64 M25P128
+*
+* - Winbond W25QXX/W25XX:
+* The Winbond W25QXX/W25XX Serial Flash is divided into Blocks of 64 KB and
+* the blocks are divided into sectors. Each Sector consists of multiple pages.
+* Each Page contains 256 Bytes. The Number of Blocks and Sectors vary for
+* different devices within this family.
+* The following instructions are not supported - Block Erase 32KB, Erase
+* Suspend/Resume, Mode Bit Reset, Read Unique ID, and Read Manufacturer/Device
+* ID.
+*
+* The following Winbond flash memories are supported by this library.
+* W25Q80 W25Q16 W25Q32
+* W25Q64 W25Q128 W25X10
+* W25X20 W25X40 W25X80
+* W25X16 W25X32 W25X64
+*
+* - Numonyx N25QXX
+* The Numonyx N25QXX Serial Flash is divided into sectors of 64 KB and
+* the sectors are divided into sub-sectors. Each Sector consists of multiple
+* pages. Each Page contains 256 Bytes. The Number of Blocks vary for different
+* devices within this family.
+* The following instructions are not supported - Erase Suspend/Resume,
+* Read/Write Volatile/Non-volatile configuration register.
+*
+* The following Numonyx flash memories are supported by this library.
+* N25Q32 N25Q64 N25Q128 N25Q256A
+*
+* - Spansion S25FL
+* The Spansion S25FL Serial Flash is divided into sectors of 64 KB and
+* in devices like S25FL128/129, the sectors are divided into sub-sectors.
+* Each Sector consists of multiple pages. Each Page contains 256 Bytes. The
+* Number of Blocks vary for different devices within this family.
+*
+* The following Spansion flash memories are supported by this library.
+* S25FL004 S25FL008 S25FL016
+* S25FL032 S25FL064 S25FL128/129
+*
+* - Silicon Storage Technology (SST) SST25WF080
+* The SST25WF080 Serial Flash is divided into sectors of 4KB. This flash
+* doesn't support Page Write commands. Supports only Byte-Write Command.
+*
+* Support for new parts can be easily added, when they are available from
+* vendors.
+*
+* Library Initialization
+*
+* The function call XIsf_Initialize() should be called by the application
+* before using any other function in the library. This function will fetch the
+* Manufacturer code and Device code and determine the geometry of the Serial
+* Flash used.
+*
+* Write Operations
+*
+* The XIsf_Write() API is used to write data to the Serial Flash. A maximum
+* of a Page of data can be written using this API. Once the user initiates a
+* write operation, the Serial Flash takes time to complete the write operation
+* internally. The user has to read the Status Register (XIsf_GetStatus) to
+* know if the Serial Flash is still busy with a previously initiated operation
+* before initiating a new one.
+*
+* Using the XIsf_Write() API the user can perform several different types of
+* write operations as mentioned below:
+*
+* - Normal Write:
+* Write data to the specified locations in the Serial Flash.
+* This operation is supported in Atmel, Intel, STM, Winbond and Spansion
+* Serial Flash.
+*
+* - Dual Input Fast Program:
+* This operation is similar to the Normal Write operation, except that
+* the data is transmitted on two lines (DQ0 and DQ1) instead of one.
+* This operation is supported in Numonyx (N25QXX) Quad Serial Flash.
+*
+* - Dual Input Extended Fast Program:
+* This operation is similar to the Dual Input Fast Program, except that
+* the address is transmitted on two lines (DQ0 and DQ1) instead of one.
+* This operation is supported in Numonyx (N25QXX) Quad Serial Flash.
+*
+* - Quad Input Fast Program:
+* This operation is similar to the Dual Input Fast Program, except that
+* the data is transmitted on four lines (DQ0 - DQ3) instead of two.
+* This operation is supported in Numonyx (N25QXX), Winbond (W25QXX) and
+* Spansion (S25FL129) Quad Serial Flash.
+*
+* - Quad Input Extended Fast Program:
+* This operation is similar to the Quad Input Fast Program, except that
+* the address is transmitted on four lines (DQ0 - DQ3) instead of one.
+* This operation is supported in Numonyx (N25QXX) Quad Serial Flash.
+*
+* - Auto Page Write:
+* Auto rewrite the contents of the page.
+* This operation is supported only for Atmel Serial Flash.
+*
+* - Buffer Write:
+* Write data to the internal SRAM buffer of the Serial Flash.
+* This operation is supported only for Atmel Serial Flash.
+*
+* - Buffer To Memory Write With Erase:
+* Write data from the specified SRAM buffer to a page in the Serial Flash
+* after erasing the page.
+* This operation is supported only for Atmel Serial Flash.
+*
+* - Buffer To Memory Write Without Erase:
+* Write data from the specified SRAM buffer to a Page in the Serial Flash
+* without erasing the page.
+* This operation is supported only for Atmel Serial Flash.
+*
+* - Write Status Register:
+* Write to the Status Register of the Serial Flash.
+* This operation is supported only for Intel, STM, Winbond and Spansion
+* Serial Flash.
+*
+* - Write 2 byte Status Register:
+* Write to the 16-bit Status Register of the Serial Flash.
+* This operation is supported only for Winbond Serial Flash.
+*
+* - One Time Programmable Area Write:
+* Write one byte of data in to One Time Programmable area.
+* This operation is supported only for Intel Serial Flash.
+*
+* For Intel, STM (Numonyx), Winbond and Spansion Serial Flash devices, the user
+* application must call the XIsf_WriteEnable() API by passing XISF_WRITE_ENABLE
+* as an argument before calling the Isf_Write() API.
+*
+*
+* Read Operations
+*
+* The XIsf_Read() API can be used to read a minimum of one byte and a maximum of
+* an entire array of the Serial Flash depending on the type of read operation.
+*
+* Using the XIsf_Read() API the user can perform several different types of read
+* operations as mentioned below:
+*
+* - Normal Read:
+* Read data from the specified locations in the Serial Flash .
+* This operation is supported for Atmel, Intel, STM, Winbond and Spansion
+* Serial Flash.
+*
+* - Fast Read:
+* Read a large block of contiguous data from the specified locations of
+* the Serial Flash at a higher speed than the Normal Read.
+* This operation is supported for Atmel, Intel, STM, Winbond and Spansion
+* Serial Flash.
+*
+* - Dual Output Fast Read:
+* This operation is similar to the Fast Read, except that the data is
+* transmitted on two lines (DQ0 and DQ1) instead of one.
+* This operation is supported in Numonyx (N25QXX), Winbond (W25QXX) and
+* Spansion (S25FL129) Quad Serial Flash.
+*
+* - Dual Input/Output Fast Read:
+* This operation is similar to the Dual Output Fast Read, except that
+* the address is transmitted on two lines (DQ0 and DQ1) instead of one.
+* This operation is supported in Numonyx (N25QXX), Winbond (W25QXX) and
+* Spansion (S25FL129) Quad Serial Flash.
+*
+* - Quad Output Fast Read:
+* This operation is similar to the Dual Output Fast Read, except that
+* the data is transmitted on four lines (DQ0 - DQ3) instead of two.
+* This operation is supported in Numonyx (N25QXX), Winbond (W25QXX) and
+* Spansion (S25FL129) Quad Serial Flash.
+*
+* - Quad Input/Output Fast Read:
+* This operation is similar to the Quad Output Fast Program, except that
+* the address is transmitted on four lines (DQ0 - DQ3) instead of one.
+* This operation is supported in Numonyx (N25QXX), Winbond (W25QXX) and
+* Spansion (S25FL129) Quad Serial Flash.
+*
+* - Memory To Buffer Transfer:
+* Transfer a page of data from the Serial Flash to the specified
+* internal SRAM buffer of the Serial Flash.
+* This operation is supported only in Atmel Serial Flash.
+*
+* - Buffer Read:
+* Read data from the specified SRAM internal buffer of the Serial Flash.
+* This operation is supported only in Atmel Serial Flash.
+*
+* - Fast Buffer Read:
+* 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.
+*
+* - One Time Programmable Area Read:
+* Read One Time Programmable area.
+* This operation is supported only for Intel Serial Flash.
+*
+* Erase Operations
+*
+* 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 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
+* operations as mentioned below :
+*
+* - Page Erase:
+* Erase one Page of the Serial Flash.
+* This operation is supported only for Atmel Serial Flash.
+*
+* - Block Erase:
+* Erase one Block of the Serial Flash.
+* This operation is supported for Atmel, Intel, Winbond Serial Flash.
+*
+* - Sector Erase:
+* Erase one Sector of the Serial Flash.
+* This operation is supported for Atmel, Intel, STM, Spansion and Winbond
+* Serial Flash.
+*
+* - Bulk Erase:
+* Erase an entire Serial Flash.
+* This operation is supported for Intel, STM, Winbond and Spansion Serial
+* Flash.
+*
+* For Intel, STM, Winbond and Spansion Serial Flash the user application must
+* call the XIsf_WriteEnable() API by passing XISF_WRITE_ENABLE as an argument
+* before calling the XIsf_Erase() API.
+*
+* Sector Protection Operations
+*
+* 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.
+*
+* Using the XIsf_SectorProtect() API the user can perform five different type of
+* operations as given below:
+*
+* - Sector Protect Register Read:
+* Read Sector Protect Register/Bits in to the buffer provided by user.
+* This operation is supported for Atmel, Intel, STM, Winbond and Spansion
+* Serial Flash.
+*
+* - Sector Protect Register Write:
+* Write data to the Sector Protect Register/Bits.
+* This operation is supported for Atmel, Intel, STM, Winbond and Spansion
+* Serial Flash.
+*
+* - Sector Protect Register Erase:
+* Erase the Sector Protect Register.
+* This operation is supported only for Atmel Serial Flash.
+*
+* - Sector Protect Enable:
+* Enable Sector Protect mode of Serial Flash.
+* This operation is supported only for Atmel Serial Flash.
+*
+* - Sector Protect Disable:
+* Disable Sector Protect mode of Serial Flash.
+* This operation is supported only for Atmel Serial Flash.
+*
+* For Intel, STM, Winbond and Spansion Serial Flash the user application must
+* call the XIsf_WriteEnable() API by passing XISF_WRITE_ENABLE as an argument
+* before calling the XIsf_SectorProtect() API for Sector Protect Register
+* Write operation.
+*
+* Device Control Operations
+*
+* The XIsf_Ioctl() API can be used to perform control operations on the
+* Intel, STM, Winbond and Spansion Serial Flash.
+*
+* Using the XIsf_Ioctl() API the user can perform several different types of
+* operations as given below:
+*
+* - Release From Deep Power-Down Mode:
+* This operation releases the Serial Flash from Deep Power-Down Mode.
+* This operation is supported for Intel, STM, Winbond and Spansion Serial
+* Flash.
+*
+* - Enter to Deep Power-Down Mode:
+* This operation puts the Serial Flash in to Deep Power-Down Mode.
+* In this mode all commands except the release from Deep Power-Down Mode
+* command will be ignored.
+* This operation is supported for Intel, STM, Winbond and Spansion Serial
+* Flash.
+*
+* - Clear Status Register Fail Flag:
+* This operation clears all the fail flags in the Status Register
+* of the Serial Flash.
+* This operation is only supported for Intel Serial Flash.
+*
+* - High Performance Mode:
+* This instruction must be executed before the dual/quad I/O instructions
+* in Winbond Flash. This instruction is supported only in Winbond (W25QXX)
+* Serial Flash.
+*
+* Serial Flash Information Read
+*
+* XIsf_GetDeviceInfo() API is used to read the Joint Electron Device
+* Engineering Council (JEDEC) compatible device information.
+* This JEDEC information consists of Manufacturer ID, Vendor-Specific Device
+* family identifier, Vendor-Specific device identifier for the specified family,
+* number of bits stored per memory cell, product version and number of
+* additional Extended Device Information bytes.
+*
+* Read the Spartan-3AN In-system Flash User Guide and the data sheets of
+* Atmel-AT45XXXD/STM-M25PXX/Intel-S33/Winbond-W25QXX/W25XX/Spansion-S25FLXX for
+* more information.
+*
+* XIsf_GetStatus() API is used to read the Status Register of the Serial Flash.
+* Winbond devices have a Status Register 2 which can be read using the
+* XIsf_GetStatusReg2() API.
+*
+* Write Enable/Disable Operations
+*
+* 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 Serial Flash.
+* Writing to the Serial Flash is disabled by calling XIsf_WriteEnable
+* (XISF_WRITE_DISABLE) API.
+*
+* @note
+*
+* This library is intended to be RTOS and processor independent. It works with
+* physical addresses only. Any needs for dynamic memory management, threads,
+* mutual exclusion, virtual memory or cache control must be satisfied by the
+* layer above this driver.
+*
+* This library supports the Spansion (S25FLXX) devices, but this family hasn't
+* been tested. The support for this family of devices is limited to the common
+* commands supported by the other flash families.
+*
+*
+*
+* MODIFICATION HISTORY:
+*
+* 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
+* 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
+* flash memories
+* 3.00a srt 06/20/12 Updated to support interfaces SPI PS and QSPI PS.
+* New API:
+* XIsf_RegisterInterface()
+* XIsf_SetSpiConfiguration()
+* XIsf_SetOperatingMode()
+* Changed API:
+* XIsf_Initialize()
+* XIsf_Transfer()
+* Added support to SST flash.
+* 3.01a srt 02/06/13 Updated for changes made in QSPIPS driver (CR 698107).
+* APIs changed:
+* XQspiPs_PolledTransfer()
+* XQspiPs_Transfer()
+* XQspiPs_SetSlaveSelect().
+* Modified the examples xilisf_spips_sst_intr_example.c
+* and xilisf_spips_sst_polled_example.c to correct
+* the flash write, erase and read logic. (CR 703816)
+* 3.02a srt 04/25/13 - Added Bulk Erase command support for SST and
+* Spansion flashes (CR 703816 & 711003).
+* - Modified SECTOR and BLOCK Erase commands for
+* SST flash and updated spips examples.
+* (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)
+* 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()
+* 5.1 sb 12/23/14 Added check for flash interface for Winbond, Spansion
+* and Micron flash family for PSQSPI.
+* 5.2 asa 5/12/15 Added support for Micron N25Q256A (>16MB) flash devices.
+* This meant adding necessary support for 4 byte addressing mode.
+* APIs were added to enter and exit from 4 byte mode. Changes were
+* made in read, erase and write APIs to support 4 byte mode.
+* These were done to fix CR#858950.
+*
+*
+*
+******************************************************************************/
+#ifndef XILISF_H /* prevent circular inclusions */
+#define XILISF_H /* by using protection macros */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/***************************** Include Files *********************************/
+
+#include "xparameters.h"
+
+#ifdef XPAR_XISF_INTERFACE_AXISPI
+#include "xspi.h"
+#elif XPAR_XISF_INTERFACE_PSSPI
+#include "xspips.h"
+#elif XPAR_XISF_INTERFACE_PSQSPI
+#include "xqspips.h"
+#endif
+
+/**
+ * The following definitions specify the type of Serial Flash family.
+ * Based on the Serial Flash family selected, some part of the code is included
+ * or excluded in the In-system and Serial Flash Library.
+ */
+#define ATMEL 1 /**< Atmel family device */
+#define INTEL 2 /**< Intel family device */
+#define STM 3 /**< STM family device */
+#define WINBOND 4 /**< Winbond family device */
+#define SPANSION 5 /**< Spansion family device */
+#define SST 6 /**< SST family device */
+
+#if (XPAR_XISF_FLASH_FAMILY == ATMEL)
+#include "xilisf_atmel.h"
+#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))
+#include "xilisf_intelstm.h"
+#endif
+
+/************************** Constant Definitions *****************************/
+
+/**
+ * The following definitions specify the Manufacturer Code for the different
+ * families of Serial Flash supported by this library.
+ */
+#define XISF_MANUFACTURER_ID_ATMEL 0x1F /**< Atmel device */
+#define XISF_MANUFACTURER_ID_INTEL 0x89 /**< Intel device */
+#define XISF_MANUFACTURER_ID_STM 0x20 /**< STM device */
+#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
+ */
+#ifdef XPAR_XISF_INTERFACE_AXISPI
+#define XISF_SPI_OPTIONS (XSP_MASTER_OPTION | \
+ XSP_MANUAL_SSELECT_OPTION | \
+ XSP_CLK_PHASE_1_OPTION | \
+ XSP_CLK_ACTIVE_LOW_OPTION)
+#elif XPAR_XISF_INTERFACE_PSQSPI
+#define XISF_SPI_OPTIONS (XQSPIPS_MANUAL_START_OPTION | \
+ XQSPIPS_FORCE_SSELECT_OPTION)
+#elif XPAR_XISF_INTERFACE_PSSPI
+#define XISF_SPI_OPTIONS (XSPIPS_MASTER_OPTION | \
+ XSPIPS_FORCE_SSELECT_OPTION)
+#endif
+
+/*
+ * PS SPI/QSPI PreScaler Settings
+ */
+#ifdef XPAR_XISF_INTERFACE_PSQSPI
+#define XISF_SPI_PRESCALER XQSPIPS_CLK_PRESCALE_4
+#elif XPAR_XISF_INTERFACE_PSSPI
+#define XISF_SPI_PRESCALER XSPIPS_CLK_PRESCALE_8
+#elif XPAR_XISF_INTERFACE_AXISPI
+#define XISF_SPI_PRESCALER 0
+#endif
+
+/**
+ * The following definitions determines the type of Write operation to be
+ * performed on the Serial Flash.
+ */
+typedef enum {
+ XISF_WRITE, /**< Normal write operation */
+ XISF_AUTO_PAGE_WRITE, /**< Auto rewrite the contents
+ * of the page */
+ XISF_BUFFER_WRITE, /**< Write data to the internal
+ * SRAM buffer of Flash */
+ XISF_BUF_TO_PAGE_WRITE_WITH_ERASE, /**< Erase the specified Page
+ * then Write data to Flash
+ * from the internal SRAM
+ * buffer */
+ XISF_BUF_TO_PAGE_WRITE_WITHOUT_ERASE, /**< Write data to the Flash
+ * from the internal SRAM
+ * buffer */
+ XISF_WRITE_STATUS_REG, /**< Write to the Status
+ * Register */
+ XISF_OTP_WRITE, /**< Write one byte of data in
+ * to the One Time
+ * Programmable area */
+ XISF_WRITE_STATUS_REG2, /**< Write to the 2 byte Status
+ * Register in W25QXX flash */
+
+#if ((XPAR_XISF_FLASH_FAMILY == WINBOND) || (XPAR_XISF_FLASH_FAMILY == STM) || \
+ (XPAR_XISF_FLASH_FAMILY == SPANSION))
+ XISF_QUAD_IP_PAGE_WRITE, /**< Quad input fast page write
+ */
+#endif /*((XPAR_XISF_FLASH_FAMILY == WINBOND) ||
+ (XPAR_XISF_FLASH_FAMILY == STM) ||
+ (XPAR_XISF_FLASH_FAMILY == SPANSION))*/
+
+#if (XPAR_XISF_FLASH_FAMILY == STM)
+ XISF_DUAL_IP_PAGE_WRITE, /**< Dual input fast page write
+ */
+ XISF_DUAL_IP_EXT_PAGE_WRITE, /**< Dual input extended fast
+ * page write */
+ XISF_QUAD_IP_EXT_PAGE_WRITE, /**< Dual input extended fast
+ * page write */
+#endif /* (XPAR_XISF_FLASH_FAMILY == STM) */
+} XIsf_WriteOperation;
+
+/**
+ * The following definitions determines the type of Read operations to be
+ * performed on the Serial Flash.
+ */
+typedef enum {
+ XISF_READ, /**< Normal Read operation */
+ XISF_FAST_READ, /**< Fast Read operation */
+ XISF_PAGE_TO_BUF_TRANS, /**< Transfer data from Flash memory to
+ * internal SRAM buffer of Flash */
+ XISF_BUFFER_READ, /**< Read data from SRAM internal buffer of
+ * the Flash */
+ 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))
+ XISF_DUAL_OP_FAST_READ, /**< Dual output fast read */
+ XISF_DUAL_IO_FAST_READ, /**< Dual input/output fast read */
+ XISF_QUAD_OP_FAST_READ, /**< Quad output fast read */
+ XISF_QUAD_IO_FAST_READ, /**< Quad input/output fast read */
+#endif /*((XPAR_XISF_FLASH_FAMILY == WINBOND) ||
+ (XPAR_XISF_FLASH_FAMILY == STM)) ||
+ (XPAR_XISF_FLASH_FAMILY == SPANSION)*/
+} XIsf_ReadOperation;
+
+/**
+ * The following definitions determines the type of Erase operation to be
+ * performed on the Serial Flash.
+ */
+typedef enum {
+ XISF_PAGE_ERASE, /**< Page Erase operation */
+ XISF_BLOCK_ERASE, /**< Block Erase operation */
+ XISF_SECTOR_ERASE, /**< Sector Erase operation */
+ XISF_BULK_ERASE /**< Erase an entire Flash */
+} XIsf_EraseOperation;
+
+/**
+ * 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 */
+ XISF_SPR_WRITE, /**< Sector protect register write */
+ XISF_SPR_ERASE, /**< Sector protect register erase */
+ XISF_SP_ENABLE, /**< Sector protect enable */
+ XISF_SP_DISABLE /**< Sector protect disable */
+} XIsf_SpOperation;
+
+/**
+ * The following definitions determines the type of control operations to be
+ * performed on the Serial Flash.
+ */
+typedef enum {
+ XISF_IOCTL_RELEASE_DPD, /**< Release from Deep Power-down */
+ XISF_IOCTL_ENTER_DPD, /**< Enter in to Deep Power-down mode */
+ XISF_IOCTL_CLEAR_SR_FAIL_FLAGS, /**< Clear Status Register Fail Flags */
+ XISF_IOCTL_ENABLE_HI_PERF_MODE /**< Enable high performance mode
+ * (availabe in Winbond quad flash
+ * (W25Q)) */
+} XIsf_IoctlOperation;
+
+/**************************** Type Definitions *******************************/
+
+#ifdef XPAR_XISF_INTERFACE_AXISPI
+typedef XSpi XIsf_Iface;
+#elif XPAR_XISF_INTERFACE_PSSPI
+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
+ * Flash.
+ */
+typedef struct {
+ u8 IsReady; /**< Is Device is ready for operation */
+
+ u16 BytesPerPage; /**< Number of Bytes per Page */
+ u16 PagesPerBlock; /**< This is Number of Pages per block,
+ for Atmel and it is Number of
+ Pages per sector for
+ Intel/STM/Winbond/Spansion */
+ u16 BlocksPerSector; /**< Number of Blocks per Sector, this is valid
+ * for ATMEL devices */
+ u16 NumOfSectors; /**< Number of Sectors in Serial Flash */
+ u8 AddrMode; /**< Type of addressing in Atmel Serial Flash
+ * 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 */
+#endif
+ u32 ManufacturerID; /**< Serial Flash Manufacturer ID */
+ XIsf_Iface *SpiInstPtr; /**< SPI Device Instance pointer */
+ u32 SpiSlaveSelect; /**< SPI Slave select for the Serial Flash */
+ u8 *WriteBufPtr; /**< Pointer to Write Buffer */
+
+ u16 ByteMask; /**< Mask used for Address translation in Atmel
+ * devices */
+ u8 RegDone; /**< Registration Done flag */
+ u8 IntrMode; /**< Operating Mode flag Interrupt/Polling */
+ u8 FourByteAddrMode; /**< In four byte address mode flag */
+ int (*XIsf_Iface_SetOptions)
+ (XIsf_Iface *InstancePtr, u32 Options);
+#ifndef XPAR_XISF_INTERFACE_PSQSPI
+ int (*XIsf_Iface_SetSlaveSelect)
+ (XIsf_Iface *InstancePtr, u8 SlaveMask);
+#else
+ int (*XIsf_Iface_SetSlaveSelect)
+ (XIsf_Iface *InstancePtr);
+#endif
+ int (*XIsf_Iface_Start)
+ (XIsf_Iface *InstancePtr);
+ int (*XIsf_Iface_Transfer)
+ (XIsf_Iface *InstancePtr, u8 *SendBufPtr,
+ u8 *RecvBufPtr, unsigned int ByteCount);
+ int (*XIsf_Iface_PolledTransfer)
+ (XIsf_Iface *InstancePtr, u8 *SendBufPtr,
+ u8 *RecvBufPtr, unsigned ByteCount);
+ int (*XIsf_Iface_SetClkPrescaler)
+ (XIsf_Iface *InstancePtr, u8 PreScaler);
+ XIsf_StatusHandler StatusHandler;
+} XIsf;
+
+/**
+ * The following structure definition specifies the operational parameters to be
+ * passed to the XIsf_Write API while performing Normal write (XISF_WRITE) and
+ * OTP write (XISF_OTP_WRITE) operations.
+ */
+typedef struct {
+ u32 Address; /**< Address in the Serial Flash */
+ u8 *WritePtr; /**< Pointer to the data to be written to the
+ * Serial Flash */
+ u32 NumBytes; /**< Number of bytes to be written to the Serial
+ * Flash */
+} XIsf_WriteParam;
+
+
+/**
+ * The following structure definition specifies the operational parameters to be
+ * passed to the XIsf_Read API while performing Normal Read (XISF_READ),
+ * Fast Read (XISF_FAST_READ) and OTP Read (XISF_OTP_READ) operations .
+ */
+typedef struct {
+ u32 Address; /**< Start address in the Serial Flash */
+ u8 *ReadPtr; /**< Read buffer pointer where data needs to be
+ * stored */
+ u32 NumBytes; /**< Number of bytes to read */
+ int NumDummyBytes; /**< Number of dummy bytes associated with the
+ * fast read command. Valid only for dual o/p
+ * fast read, dual i/o fast read, quad o/p
+ * 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).
+ */
+typedef struct {
+ u8 BufferNum; /**< SRAM buffer number of Serial Flash */
+ u8 *WritePtr; /**< Pointer to the data to be written into the
+ * Serial Flash SRAM Buffer */
+ u32 ByteOffset; /**< Byte offset in the buffer from which the
+ * data is written */
+ u32 NumBytes; /**< Number of bytes to be written into the
+ * 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
+ * to a Page in the Atmel Serial Flash using XISF_BUF_TO_PAGE_WRITE_WITH_ERASE /
+ * XISF_BUF_TO_PAGE_WRITE_WITHOUT_ERASE commands in Atmel Serial Flash.
+ */
+typedef struct {
+ u8 BufferNum; /**< SRAM buffer number of Serial Flash */
+ u32 Address; /**< Starting address in the Serial Flash */
+} XIsf_BufferToFlashWriteParam;
+
+/**
+ * The following structure definition specifies the operational parameters to be
+ * passed to the XIsf_Read API while performing Page to Buffer Transfer
+ * operation (XISF_PAGE_TO_BUF_TRANS) in Atmel Serial Flash.
+ */
+typedef struct {
+ u8 BufferNum; /**< SRAM buffer number of Serial Flash */
+ u32 Address; /**< Start address in the Serial Flash */
+} XIsf_FlashToBufTransferParam;
+
+/**
+ * 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.
+ */
+typedef struct {
+ u8 BufferNum; /**< SRAM buffer number of Serial Flash */
+ u8 *ReadPtr; /**< Read buffer pointer where data read from
+ * the SRAM buffer is stored */
+ u32 ByteOffset; /**< Byte offset in the SRAM buffer from where
+ * the first byte is read */
+ u32 NumBytes; /**< Number of bytes to be read from the
+ * buffer */
+} XIsf_BufferReadParam;
+
+
+/************************** Variable Definitions *****************************/
+
+/***************** Macros (Inline Functions) Definitions *********************/
+
+/*****************************************************************************/
+/**
+*
+* This API sets the interrupt/polling mode of transfer.
+*
+* @param InstancePtr is a pointer to the XIsf instance.
+* @param Mode is the value to be set.
+*
+* @note By default, the xilisf library is designed to operate in
+* polling mode. User needs to call this API to set in interrupt
+* mode, if operating in Interrupt Mode.
+******************************************************************************/
+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 ******************************/
+
+/*
+ * Initialization Function.
+ */
+int XIsf_Initialize(XIsf *InstancePtr, XIsf_Iface *SpiInstPtr, u8 SlaveSelect,
+ u8 *WritePtr);
+
+/*
+ * Function to read the Status Registers.
+ */
+int XIsf_GetStatus(XIsf *InstancePtr, u8 *ReadPtr);
+
+#if (XPAR_XISF_FLASH_FAMILY == WINBOND)
+int XIsf_GetStatusReg2(XIsf *InstancePtr, u8 *ReadPtr);
+#endif
+
+
+/*
+ * Function to read the Serial Flash information.
+ */
+int XIsf_GetDeviceInfo(XIsf *InstancePtr, u8 *ReadPtr);
+
+/*
+ * Function for Writing to the Serial Flash.
+ */
+int XIsf_Write(XIsf *InstancePtr, XIsf_WriteOperation Operation,
+ void *OpParamPtr);
+
+/*
+ * Function for Reading from the Serial Flash.
+ */
+int XIsf_Read(XIsf *InstancePtr, XIsf_ReadOperation Operation,
+ void *OpParamPtr);
+
+/*
+ * Function for Erasing the Serial Flash.
+ */
+int XIsf_Erase(XIsf *InstancePtr, XIsf_EraseOperation Operation, u32 Address);
+
+#if (((XPAR_XISF_FLASH_FAMILY == INTEL) || (XPAR_XISF_FLASH_FAMILY == STM) \
+ || (XPAR_XISF_FLASH_FAMILY == SST) || \
+ (XPAR_XISF_FLASH_FAMILY == WINBOND) || \
+ (XPAR_XISF_FLASH_FAMILY == SPANSION)) && \
+ (!defined(XPAR_XISF_INTERFACE_PSQSPI)))
+/*
+ * Function for entering into 4 byte mode for Micron flash.
+ */
+int XIsf_MicronFlashEnter4BAddMode(XIsf *InstancePtr);
+
+/*
+ * Function for exiting from 4 byte mode for Micron flash.
+ */
+int XIsf_MicronFlashExit4BAddMode(XIsf *InstancePtr);
+#endif
+/*
+ * Function related to Sector protection.
+ */
+int XIsf_SectorProtect(XIsf *InstancePtr, XIsf_SpOperation Operation,
+ u8 *BufferPtr);
+
+/*
+ * Function to perform different control operations.
+ */
+int XIsf_Ioctl(XIsf *InstancePtr, XIsf_IoctlOperation Operation);
+
+/*
+ * Function for Enabling/Disabling Write to Intel, STM, Winbond and Spansion
+ * Serial Flash.
+ */
+int XIsf_WriteEnable(XIsf *InstancePtr, u8 WriteEnable);
+
+/*
+ * Function for Registering Interfaces SPI, PSQSPI, PSSPI
+ */
+void XIsf_RegisterInterface(XIsf *InstancePtr);
+
+/*
+ * Function for setting SPI/PSQSPI/PSSPI Configuration
+ */
+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 *XIfaceInstancePtr,
+ XIsf_StatusHandler XilIsf_Handler);
+
+/*
+ *Interrupt Handler of XilISF Lib
+ */
+void XIsf_IfaceHandler(void *CallBackRef, u32 StatusEvent,
+ unsigned int ByteCount);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* end of protection macro */
diff --git a/lib/sw_services/xilisf/src/include/xilisf_atmel.h b/lib/sw_services/xilisf/src/include/xilisf_atmel.h
new file mode 100644
index 00000000..a242aff1
--- /dev/null
+++ b/lib/sw_services/xilisf/src/include/xilisf_atmel.h
@@ -0,0 +1,268 @@
+/******************************************************************************
+*
+* Copyright (C) 2012 - 2015 Xilinx, Inc. All rights reserved.
+*
+* Permission is hereby granted, free of charge, to any person obtaining a copy
+* of this software and associated documentation files (the "Software"), to deal
+* in the Software without restriction, including without limitation the rights
+* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+* copies of the Software, and to permit persons to whom the Software is
+* furnished to do so, subject to the following conditions:
+*
+* The above copyright notice and this permission notice shall be included in
+* all copies or substantial portions of the Software.
+*
+* Use of the Software is limited solely to applications:
+* (a) running on a Xilinx device, or
+* (b) that interact with a Xilinx device through a bus or interconnect.
+*
+* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+* XILINX BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
+* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+* SOFTWARE.
+*
+* Except as contained in this notice, the name of the Xilinx shall not be used
+* in advertising or otherwise to promote the sale, use or other dealings in
+* this Software without prior written authorization from Xilinx.
+*
+******************************************************************************/
+/*****************************************************************************/
+/**
+*
+* @file xilisf_atmel.h
+*
+* This file contains the definitions to be used when accessing the Atmel
+* AT45XXXD Serial Flash.
+* If any new definitions are added to this file, check if they need to be
+* added to the xilisf_intelstm.h file too.
+*
+* @note None
+*
+*
+*
+* MODIFICATION HISTORY:
+*
+* Ver Who Date Changes
+* ----- ------- -------- -----------------------------------------------
+* 1.00a ksu/sdm 03/03/08 First release
+*
+*
+*
+******************************************************************************/
+#ifndef XILISF_ATMEL_H /* prevent circular inclusions */
+#define XILISF_ATMEL_H /* by using protection macros */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/***************************** Include Files *********************************/
+
+
+/************************** Constant Definitions *****************************/
+
+/**
+ * The following definitions specify the Device Id for the different Atmel
+ * AT45XXXD Serial Flash Devices.
+ */
+#define XISF_ATMEL_DEV_AT45DB011D 0x22 /**< Device ID of AT45DB011D */
+#define XISF_ATMEL_DEV_AT45DB021D 0x23 /**< Device ID of AT45DB027D */
+#define XISF_ATMEL_DEV_AT45DB041D 0x24 /**< Device ID of AT45DB041D */
+#define XISF_ATMEL_DEV_AT45DB081D 0x25 /**< Device ID of AT45DB081D */
+#define XISF_ATMEL_DEV_AT45DB161D 0x26 /**< Device ID of AT45DB161D */
+#define XISF_ATMEL_DEV_AT45DB321D 0x27 /**< Device ID of AT45DB321D */
+#define XISF_ATMEL_DEV_AT45DB642D 0x28 /**< Device ID of AT45DB642D */
+
+
+/**
+ * Definitions of Atmel Serial Flash Device geometry.
+ */
+#define XISF_BYTES256_PER_PAGE 256 /**< 256 Bytes per Page */
+#define XISF_BYTES264_PER_PAGE 264 /**< 264 Bytes per Page */
+#define XISF_BYTES512_PER_PAGE 512 /**< 512 Bytes per Page */
+#define XISF_BYTES528_PER_PAGE 528 /**< 528 Bytes per Page */
+#define XISF_BYTES1024_PER_PAGE 1024 /**< 1024 Bytes per Page */
+#define XISF_BYTES1056_PER_PAGE 1056 /**< 1056 Bytes per Page */
+#define XISF_PAGES8_PER_BLOCK 8 /**< Pages per Block */
+#define XISF_BLOCKS16_PER_SECTOR 16 /**< 16 Blocks per Sector */
+#define XISF_BLOCKS32_PER_SECTOR 32 /**< 32 Blocks per Sector */
+#define XISF_NUM_OF_SECTORS4 4 /**< 4 Sectors */
+#define XISF_NUM_OF_SECTORS8 8 /**< 8 Sectors */
+#define XISF_NUM_OF_SECTORS16 16 /**< 16 Sectors */
+#define XISF_NUM_OF_SECTORS32 32 /**< 32 Sectors */
+#define XISF_NUM_OF_SECTORS64 64 /**< 64 Sectors */
+
+/**
+ * Definitions of Bit masks used for calculating device address from a
+ * linear address in the case of Default Addressing mode .
+ */
+#define XISF_BYTES256_PER_PAGE_MASK 0x0FF /**< Byte mask for devices with
+ * 256 or less bytes per page
+ */
+#define XISF_BYTES512_PER_PAGE_MASK 0x1FF /**< Byte mask for devices with
+ * more than 256 bytes per
+ * page */
+#define XISF_BYTES1024_PER_PAGE_MASK 0x3FF /**< Byte mask for devices with
+ * more than 512 bytes per
+ * page */
+#define XISF_BYTES2048_PER_PAGE_MASK 0x7FF /**< Byte mask for devices with
+ * more than 1024 bytes per
+ * page */
+
+/**
+ * Definitions of Read commands.
+ */
+#define XISF_CMD_RANDOM_READ 0x03 /**< Random Read command */
+#define XISF_CMD_FAST_READ 0x0B /**< Fast Read command */
+#define XISF_CMD_ISFINFO_READ 0x9F /**< Device Info command */
+#define XISF_CMD_PAGETOBUF1_TRANS 0x53 /**< Transfer contents of a Page
+ * to the Buffer 1 command */
+#define XISF_CMD_PAGETOBUF2_TRANS 0x55 /**< Transfer contents of a Page
+ * to the Buffer 2 command */
+#define XISF_CMD_BUF1_READ 0xD1 /**< Buffer 1 Read command */
+#define XISF_CMD_BUF2_READ 0xD3 /**< Buffer 2 Read command */
+#define XISF_CMD_FAST_BUF1_READ 0xD4 /**< Fast Buffer 1 Read Cmd */
+#define XISF_CMD_FAST_BUF2_READ 0xD6 /**< Fast Buffer 2 Read Cmd */
+#define XISF_CMD_STATUSREG_READ 0xD7 /**< Status Greg Read Cmd */
+
+/**
+ * Definitions of Write commands.
+ */
+#define XISF_CMD_PAGEPROG_WRITE 0x82 /**< Page Program command */
+#define XISF_CMD_AUTOPAGE_WRITE 0x58 /**< Auto write command */
+#define XISF_CMD_BUFFER1_WRITE 0x84 /**< Buffer1 write command */
+#define XISF_CMD_BUFFER2_WRITE 0x87 /**< Buffer2 write command */
+#define XISF_CMD_ERASE_BUF1TOPAGE_WRITE 0x83 /**< Erase page first then write
+ * buffer 1 to the page
+ * command */
+#define XISF_CMD_ERASE_BUF2TOPAGE_WRITE 0x86 /**< Erase page first then write
+ * buffer2 to the page
+ * command */
+#define XISF_CMD_BUF1TOPAGE_WRITE 0x88 /**< Write buffer1 to the page
+ * command without Erase */
+#define XISF_CMD_BUF2TOPAGE_WRITE 0x89 /**< Write buffer2 to the page
+ * command without Erase */
+
+/**
+ * Definitions of Erase commands.
+ */
+#define XISF_CMD_PAGE_ERASE 0x81 /**< Page Erase command */
+#define XISF_CMD_BLOCK_ERASE 0x50 /**< Block erase command */
+#define XISF_CMD_SECTOR_ERASE 0x7C /**< Sector Erase command */
+
+/**
+ * Definitions of commands used for
+ * - Erasing SPR
+ * - Programming SPR
+ * - Enabling/Disabling SPR.
+ */
+#define XISF_CMD_SPR_BYTE1 0x3D /**< SPR command byte1 */
+#define XISF_CMD_SPR_BYTE2 0x2A /**< SPR command byte2 */
+#define XISF_CMD_SPR_BYTE3 0x7F /**< SPR command byte3 */
+#define XISF_CMD_SPR_BYTE4_ERASE 0xCF /**< SPR erase command */
+#define XISF_CMD_SPR_BYTE4_PROGRAM 0xFC /**< SPR program command */
+#define XISF_CMD_SPR_BYTE4_ENABLE 0xA9 /**< SPR enable command */
+#define XISF_CMD_SPR_BYTE4_DISABLE 0x9A /**< SPR disable command */
+
+/**
+ * Definitions of command used for reading SPR.
+ */
+#define XISF_CMD_SPR_READ 0x32 /**< SPR read command */
+
+/**
+ * The following definitions specify the buffer number of Atmel Serial Flash.
+ */
+#define XISF_PAGE_BUFFER1 1 /**< Buffer 1 */
+#define XISF_PAGE_BUFFER2 2 /**< Buffer 2 */
+
+
+/**
+ * The following definitions specify the Status Register bit definitions of
+ * Atmel Serial Flash.
+ */
+#define XISF_SR_ADDR_MODE_MASK 0x01 /**< Address mode mask */
+#define XISF_SR_COMPARE_MASK 0x40 /**< Compare mask */
+#define XISF_SR_IS_READY_MASK 0x80 /**< Ready mask */
+#define XISF_SR_DEVID_MASK 0x2C /**< Device ID mask */
+#define XISF_SR_DEVID_SHIFT_MASK 0x02 /**< Device ID shift mask */
+
+/**
+ * The following definitions determine the addressing mode of the Atmel Serial
+ * Flash.
+ */
+#define XISF_POWEROFTWO_ADDRESS 0x01 /**< Pow-Of-2 address mask */
+#define XISF_DEFAULT_ADDRESS 0x00 /**< Default address mask */
+
+/**
+ * This definitions specify the extra bytes in each of the Write command, Read
+ * command, Erase command, commands operating on SPR, auto page write, page to
+ * buffer and buffer to page transfer commands. This count includes
+ * Command byte, address bytes and any don't care bytes needed.
+ */
+#define XISF_CMD_SEND_EXTRA_BYTES 4 /**< Command extra bytes */
+
+/**
+ * This definition specifies the extra bytes in each of the Write/Read/Erase
+ * commands, commands operating on SPR, auto page write, page to
+ * buffer and buffer to page transfer commands in 4 bytes addressing mode.
+ * This count includes Command byte, Address bytes and any
+ * don't care bytes needed.
+ */
+#define XISF_CMD_SEND_EXTRA_BYTES_4BYTE_MODE 5 /**< Command extra bytes */
+
+/**
+ * This definitions specify the extra bytes in Fast read Fast buffer read
+ * commands. This count includes Command byte, address bytes and any don't care
+ * bytes needed.
+ */
+#define XISF_CMD_FAST_READ_EXTRA_BYTES 5 /**< Fast read and Fast buffer
+ * read extra bytes */
+
+/**
+ * The following definitions specify the total bytes in some of the commands.
+ * This count includes Command byte and any don't care bytes needed.
+ */
+#define XISF_STATUS_RDWR_BYTES 2 /**< Status Read/Write bytes
+ * count */
+#define XISF_INFO_READ_BYTES 5 /**< Flash Info Read bytes
+ * count */
+#define XISF_INFO_EXTRA_BYTES 1 /**< Flash Info Read Extra
+ * bytes */
+#define XISF_CMD_MAX_EXTRA_BYTES 5 /**< Max extra bytes for
+ * all commands */
+#define XISF_DUMMYBYTE 0xFF /**< Dummy byte to fill */
+
+
+/**
+ * Address Shift Masks.
+ */
+#define XISF_ADDR_SHIFT16 16 /**< 16 bit Shift */
+#define XISF_ADDR_SHIFT8 8 /**< 8 bit Shift */
+
+
+/**
+ * Byte Positions.
+ */
+#define BYTE1 0 /**< Byte 1 position */
+#define BYTE2 1 /**< Byte 2 position */
+#define BYTE3 2 /**< Byte 3 position */
+#define BYTE4 3 /**< Byte 4 position */
+#define BYTE5 4 /**< Byte 5 position */
+
+
+/**************************** Type Definitions *******************************/
+
+/************************** Variable Definitions *****************************/
+
+/***************** Macros (Inline Functions) Definitions *********************/
+
+/************************** Function Prototypes ******************************/
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* end of protection macro */
diff --git a/lib/sw_services/xilisf/src/include/xilisf_intelstm.h b/lib/sw_services/xilisf/src/include/xilisf_intelstm.h
new file mode 100644
index 00000000..429853b7
--- /dev/null
+++ b/lib/sw_services/xilisf/src/include/xilisf_intelstm.h
@@ -0,0 +1,365 @@
+/******************************************************************************
+*
+* Copyright (C) 2012 - 2015 Xilinx, Inc. All rights reserved.
+*
+* Permission is hereby granted, free of charge, to any person obtaining a copy
+* of this software and associated documentation files (the "Software"), to deal
+* in the Software without restriction, including without limitation the rights
+* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+* copies of the Software, and to permit persons to whom the Software is
+* furnished to do so, subject to the following conditions:
+*
+* The above copyright notice and this permission notice shall be included in
+* all copies or substantial portions of the Software.
+*
+* Use of the Software is limited solely to applications:
+* (a) running on a Xilinx device, or
+* (b) that interact with a Xilinx device through a bus or interconnect.
+*
+* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+* XILINX BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
+* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+* SOFTWARE.
+*
+* Except as contained in this notice, the name of the Xilinx shall not be used
+* in advertising or otherwise to promote the sale, use or other dealings in
+* this Software without prior written authorization from Xilinx.
+*
+******************************************************************************/
+/*****************************************************************************/
+/**
+*
+* @file xilisf_intelstm.h
+*
+* This file contains the definitions to be used when accessing the Intel, STM,
+* Winbond and Spansion Serial Flash.
+* If any new definitions are added to this file, check if they need to be
+* added to the xilisf_atmel.h file too.
+*
+* @note None
+*
+*
+*
+* MODIFICATION HISTORY:
+*
+* Ver Who Date Changes
+* ----- ------- -------- -----------------------------------------------
+* 1.00a ksu/sdm 03/03/08 First release
+* 2.01a sdm 01/04/10 Added Support for Winbond W25QXX/W25XX devices
+* 2.04a sdm 08/17/10 Updated to support Numonyx (N25QXX) and Spansion
+* flash memories
+* 3.00a srt 06/20/12 Updated to support interfaces SPI PS and QSPI PS.
+* Added support to SST flash on SPI PS interface.
+* 3.02a srt 04/26/13 Modified SECTOR and BLOCK Erase commands for
+* SST flash (CR 703816).
+* 5.2 asa 05/12/15 Added macros for 4 byte commands.
+*
+*
+******************************************************************************/
+#ifndef XILISF_INTELSTM_H /* prevent circular inclusions */
+#define XILISF_INTELSTM_H /* by using protection macros */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/***************************** Include Files *********************************/
+
+/************************** Constant Definitions *****************************/
+
+/**
+ * The following definitions specify the Device Id for the different
+ * Intel (Numonyx) S33 Serial Flash devices.
+ */
+#define XISF_INTEL_DEV_S3316MBIT 0x11 /**< Device ID for 16Mbit */
+#define XISF_INTEL_DEV_S3332MBIT 0x12 /**< Device ID for 32Mbit */
+#define XISF_INTEL_DEV_S3364MBIT 0x13 /**< Device ID for 64Mbit */
+
+/**
+ * The following definitions specify the Device Id for the different
+ * STM (Numonyx) M25PXX Serial Flash devices.
+ */
+#define XISF_STM_DEV_M25P05_A 0x2010 /**< Device ID for M25P05-A */
+#define XISF_STM_DEV_M25P10_A 0x2011 /**< Device ID for M25P10-A */
+#define XISF_STM_DEV_M25P20 0x2012 /**< Device ID for M25P20 */
+#define XISF_STM_DEV_M25P40 0x2013 /**< Device ID for M25P40 */
+#define XISF_STM_DEV_M25P80 0x2014 /**< Device ID for M25P80 */
+#define XISF_STM_DEV_M25P16 0x2015 /**< Device ID for M25P16 */
+#define XISF_STM_DEV_M25P32 0x2016 /**< Device ID for M25P32 */
+#define XISF_STM_DEV_M25P64 0x2017 /**< Device ID for M25P64 */
+#define XISF_STM_DEV_M25P128 0x2018 /**< Device ID for M25P128 */
+
+/**
+ * The following definitions specify the Device Id (memory type/capacity)
+ * for the different Winbond W25QX/W25XX Serial Flash devices.
+ */
+#define XISF_WB_DEV_W25Q80 0x4014 /**< Device ID for W25Q80 */
+#define XISF_WB_DEV_W25Q16 0x4015 /**< Device ID for W25Q16 */
+#define XISF_WB_DEV_W25Q32 0x4016 /**< Device ID for W25Q32 */
+#define XISF_WB_DEV_W25Q64 0x4017 /**< Device ID for W25Q64 */
+#define XISF_WB_DEV_W25Q128 0x4018 /**< Device ID for W25Q128 */
+#define XISF_WB_DEV_W25X10 0x3011 /**< Device ID for W25X10 */
+#define XISF_WB_DEV_W25X20 0x3012 /**< Device ID for W25X20 */
+#define XISF_WB_DEV_W25X40 0x3013 /**< Device ID for W25X40 */
+#define XISF_WB_DEV_W25X80 0x3014 /**< Device ID for W25X80 */
+#define XISF_WB_DEV_W25X16 0x3015 /**< Device ID for W25X16 */
+#define XISF_WB_DEV_W25X32 0x3016 /**< Device ID for W25X32 */
+#define XISF_WB_DEV_W25X64 0x3017 /**< Device ID for W25X64 */
+
+/**
+ * The following definitions specify the Device Id (memory type/capacity)
+ * for the different STM (Numonyx) N25QXX Serial Flash devices.
+ */
+#define XISF_NM_DEV_N25Q32 0xBA16 /**< Device ID for N25Q32 */
+#define XISF_NM_DEV_N25Q64 0xBA17 /**< Device ID for N25Q64 */
+#define XISF_NM_DEV_N25Q128 0xBA18 /**< Device ID for N25Q128 */
+#define XISF_MIC_DEV_N25Q128 0xBB18 /**< Device ID for N25Q128 */
+#define XISF_MIC_DEV_N25Q256_3V0 0xBA19
+#define XISF_MIC_DEV_N25Q256_1V8 0xBB19
+
+/**
+ * The following definitions specify the Device Id for the different
+ * Spansion S25FLXX Serial Flash devices.
+ */
+#define XISF_SPANSION_DEV_S25FL004 0x0212 /**< Device ID for S25FL004 */
+#define XISF_SPANSION_DEV_S25FL008 0x0213 /**< Device ID for S25FL008 */
+#define XISF_SPANSION_DEV_S25FL016 0x0214 /**< Device ID for S25FL016 */
+#define XISF_SPANSION_DEV_S25FL032 0x0215 /**< Device ID for S25FL032 */
+#define XISF_SPANSION_DEV_S25FL064 0x0216 /**< Device ID for S25FL064 */
+#define XISF_SPANSION_DEV_S25FL128 0x2018 /**< Device ID for S25FL128
+ * and S25FL129 */
+
+/**
+ * The following definitions specify the Device Id for the different
+ * SST Serial Flash device.
+ */
+#define XISF_SST_DEV_SST25WF080 0x2505 /**< Device ID for SST25WF080 */
+
+/**
+ * Definitions for Intel, STM, Winbond and Spansion Serial Flash Device
+ * geometry.
+ */
+#define XISF_BYTES256_PER_PAGE 256 /**< 256 Bytes per Page */
+#define XISF_PAGES16_PER_SECTOR 16 /**< 16 Pages per Sector */
+#define XISF_PAGES128_PER_SECTOR 128 /**< 128 Pages per Sector */
+#define XISF_PAGES256_PER_SECTOR 256 /**< 256 Pages per Sector */
+#define XISF_PAGES1024_PER_SECTOR 1024 /**< 1024 Pages per Sector */
+#define XISF_NUM_OF_SECTORS2 2 /**< 2 Sectors */
+#define XISF_NUM_OF_SECTORS4 4 /**< 4 Sectors */
+#define XISF_NUM_OF_SECTORS8 8 /**< 8 Sector */
+#define XISF_NUM_OF_SECTORS16 16 /**< 16 Sectors */
+#define XISF_NUM_OF_SECTORS32 32 /**< 32 Sectors */
+#define XISF_NUM_OF_SECTORS64 64 /**< 64 Sectors */
+#define XISF_NUM_OF_SECTORS128 128 /**< 128 Sectors */
+#define XISF_NUM_OF_SECTORS256 256 /**< 256 Sectors */
+#define XISF_NUM_OF_SECTORS512 512 /**< 512 Sectors */
+#define XISF_NUM_OF_SECTORS1024 1024 /**< 1024 Sectors */
+#define XISF_NUM_OF_SECTORS2048 2048 /**< 2048 Sectors */
+#define XISF_NUM_OF_SECTORS4096 4096 /**< 4096 Sectors */
+
+/**
+ * Definitions of Read commands.
+ */
+#define XISF_CMD_RANDOM_READ 0x03 /**< Random Read command */
+#define XISF_CMD_RANDOM_READ_4BYTE 0x13 /**< Random 4 byte Read command */
+#define XISF_CMD_FAST_READ 0x0B /**< Fast Read command */
+#define XISF_CMD_FAST_READ_4BYTE 0x0C /**< 4 byte Fast Read command */
+#define XISF_CMD_ISFINFO_READ 0x9F /**< Device Info command */
+#define XISF_CMD_STATUSREG_READ 0x05 /**< Status Reg Read command */
+#define XISF_CMD_STATUSREG2_READ 0x35 /**< Status Reg2 Read command */
+#define XISF_CMD_DUAL_OP_FAST_READ 0x3B /**< Dual output fast read */
+#define XISF_CMD_DUAL_OP_FAST_READ_4B 0x3C /**< 4 byte Dual output fast read */
+#define XISF_CMD_DUAL_IO_FAST_READ 0xBB /**< Dual i/o fast read */
+#define XISF_CMD_DUAL_IO_FAST_READ_4B 0xBC /**< 4 byte Dual i/o fast read */
+#define XISF_CMD_QUAD_OP_FAST_READ 0x6B /**< Quad output fast read */
+#define XISF_CMD_QUAD_OP_FAST_READ_4B 0x6C /**< 4 byte Quad output fast read */
+#define XISF_CMD_QUAD_IO_FAST_READ 0xEB /**< Quad i/o fast read */
+#define XISF_CMD_QUAD_IO_FAST_READ_4B 0xEC /**< 4 byte Quad i/o fast read */
+
+/**
+ * Definitions of Write commands.
+ */
+#define XISF_CMD_PAGEPROG_WRITE 0x02 /**< Page Program command */
+#define XISF_CMD_PAGEPROG_WRITE_4BYTE 0x12 /**< 4 byte Page Program command */
+#define XISF_CMD_STATUSREG_WRITE 0x01 /**< Status Reg Write Command */
+#define XISF_CMD_DUAL_IP_PAGE_WRITE 0xA2 /**< Dual input fast page write
+ */
+#define XISF_CMD_DUAL_IP_EXT_PAGE_WRITE 0xD2 /**< Dual input extended fast
+ * page write */
+#define XISF_CMD_QUAD_IP_PAGE_WRITE 0x32 /**< Quad input fast page write
+ */
+#define XISF_CMD_QUAD_IP_EXT_PAGE_WRITE 0x12 /**< Dual input extended fast
+ * page write */
+
+/**
+ * Definitions of Erase commands.
+ */
+#define XISF_CMD_BULK_ERASE 0xC7 /**< Bulk Erase command */
+
+
+#if ((XPAR_XISF_FLASH_FAMILY == INTEL) || (XPAR_XISF_FLASH_FAMILY == STM) || \
+ (XPAR_XISF_FLASH_FAMILY == SPANSION))
+#define XISF_CMD_SECTOR_ERASE 0xD8 /**< Sector Erase command */
+#define XISF_CMD_SUB_SECTOR_ERASE 0x20 /**< Sub-sector Erase command.
+ * only for N25QXX */
+#define XISF_CMD_4BYTE_SECTOR_ERASE 0xDC
+#endif /* ((XPAR_XISF_FLASH_FAMILY==INTEL)||(XPAR_XISF_FLASH_FAMILY == STM) ||
+ (XPAR_XISF_FLASH_FAMILY == SPANSION)) */
+
+#if ((XPAR_XISF_FLASH_FAMILY == WINBOND) || (XPAR_XISF_FLASH_FAMILY == SST))
+#define XISF_CMD_BLOCK_ERASE 0xD8 /**< Block Erase command */
+#define XISF_CMD_SECTOR_ERASE 0x20 /**< Sector Erase command */
+#endif
+
+/**
+ * Definitions of commands used for
+ * - Write Enable/Disable.
+ * - Deep Power Down mode Enter/Release.
+ * - Switch to 4 byte addressing
+ */
+#define XISF_CMD_ENABLE_WRITE 0x06 /**< Write enable command */
+#define XISF_CMD_DISABLE_WRITE 0x04 /**< Write disable command */
+#define XISF_CMD_DEEP_POWER_DOWN 0xB9 /**< Enter DPD mode command */
+#define XISF_CMD_RELEASE_FROM_DPD 0xAB /**< Release DPD mode command */
+
+#define XISF_CMD_ENABLE_HPM 0xA3 /**< Enable high performance
+ * mode */
+
+#if (XPAR_XISF_FLASH_FAMILY == SPANSION)
+#define XISF_CMD_ENTER_4BYTE_ADDR_MODE 0xB7
+#define XISF_CMD_EXIT_4BYTE_ADDR_MODE 0xE9
+#endif
+#if (XPAR_XISF_FLASH_FAMILY == INTEL)
+/**
+ * Definitions of commands which are only supported in Intel Serial Flash.
+ */
+#define XISF_CMD_OTP_READ 0x4B /**< OTP data read command */
+#define XISF_CMD_OTP_WRITE 0x42 /**< OTP write command */
+#define XISF_CMD_PARAM_BLOCK_ERASE 0x40 /**< Parameter Block Erase
+ * command */
+#define XISF_CMD_CLEAR_SRFAIL_FLAGS 0x30 /**< Clear SR fail bits Cmd */
+#define XISF_OTP_RDWR_EXTRA_BYTES 0x05 /**< OTP Read/Write
+ * extra bytes */
+#endif /* INTEL */
+
+
+/**
+ * The following definitions specify the Status Register bit definitions of
+ * Intel, STM, Winbond and Spansion Serial Flash.
+ */
+#define XISF_SR_IS_READY_MASK 0x01 /**< Ready mask */
+#define XISF_SR_WRITE_ENABLE_MASK 0x02 /**< Write Enable latch mask */
+#define XISF_SR_BLOCK_PROTECT_MASK 0x1C /**< Block Protect mask */
+#define XISF_SR_WRITE_PROTECT_MASK 0x80 /**< Status Reg write
+ * protect mask */
+#define XISF_SR_BLOCK_PROTECT_SHIFT 2 /**< Block protect bits shift */
+
+#if (XPAR_XISF_FLASH_FAMILY == INTEL)
+#define XISF_SR_PROG_FAIL_MASK 0x40 /**< Program Fail bit mask */
+#define XISF_SR_ERASE_FAIL_MASK 0x20 /**< Erase Fail bit mask */
+#endif /* (XPAR_XISF_FLASH_FAMILY == INTEL) */
+
+#if (XPAR_XISF_FLASH_FAMILY == WINBOND)
+#define XISF_SR_TB_PROTECT_MASK 0x20 /**< Top/Bottom Write Protect */
+#define XISF_SR_SECTOR_PROTECT_MASK 0x40 /**< Sector Protect mask */
+#endif /* (XPAR_XISF_FLASH_FAMILY == WINBOND) */
+
+
+/**
+ * The definition specifies the total bytes in Bulk Erase commands.
+ * This count includes Command byte and any don't care bytes needed.
+ */
+#define XISF_BULK_ERASE_BYTES 0x01 /**< Bulk erase extra bytes */
+
+/**
+ * The following definitions specify the Write Enable and Disable operation
+ * arguments to be passed to the XIsf_WriteEnable API.
+ */
+#define XISF_WRITE_ENABLE 1 /**< Write enable */
+#define XISF_WRITE_DISABLE 0 /**< Write disable */
+
+/**
+ * This definition specifies the extra bytes in each of the Write Enable/Disable
+ * commands. This count includes Command byte, address bytes and any don't care
+ * bytes needed.
+ */
+#define XISF_CMD_WRITE_ENABLE_DISABLE_BYTES 1 /**< Write enable/disable
+ * command extra bytes */
+
+/**
+ * This definition specifies the extra bytes in 4 byte addr mode enter and exit
+ * commands. This count refers to the Command byte.
+ */
+#define XISF_CMD_4BYTE_ADDR_ENTER_EXIT_BYTES 1 /**< Four byte addr mode
+ * command extra bytes */
+/**
+ * This definition specifies the extra bytes in each of the Write/Read/Erase
+ * commands, commands operating on SPR, auto page write, page to
+ * buffer and buffer to page transfer commands. This count includes
+ * Command byte, Address bytes and any don't care bytes needed.
+ */
+#define XISF_CMD_SEND_EXTRA_BYTES 4 /**< Command extra bytes */
+
+/**
+ * This definition specifies the extra bytes in each of the Write/Read/Erase
+ * commands, commands operating on SPR, auto page write, page to
+ * buffer and buffer to page transfer commands in 4 bytes addressing mode.
+ * This count includes Command byte, Address bytes and any
+ * don't care bytes needed.
+ */
+#define XISF_CMD_SEND_EXTRA_BYTES_4BYTE_MODE 5 /**< Command extra bytes */
+
+/**
+ * This definition specifies the extra bytes in Fast Read and Fast Buffer Read
+ * commands. This count includes Command byte, address bytes and any don't care
+ * bytes needed.
+ */
+#define XISF_CMD_FAST_READ_EXTRA_BYTES 5 /**< Fast read and Fast buffer
+ * read extra bytes */
+
+/**
+ * The following definitions specify the total bytes in some of the commands.
+ * This count includes Command byte and any don't care bytes needed.
+ */
+#define XISF_STATUS_RDWR_BYTES 2 /**< Status Read/Write bytes
+ * count */
+#define XISF_INFO_READ_BYTES 5 /**< Serial Flash Info read
+ * bytes count */
+#define XISF_INFO_EXTRA_BYTES 1 /**< Serial Flash Info extra
+ * bytes */
+#define XISF_IOCTL_BYTES 1 /**< Serial Flash IOCTL bytes */
+#define XISF_HPM_BYTES 4 /**< Serial Flash HPM bytes */
+#define XISF_CMD_MAX_EXTRA_BYTES 5 /**< Max extra bytes for
+ * all commands */
+#define XISF_DUMMYBYTE 0xFF /**< Dummy byte to fill */
+
+/**
+ * Address Shift Masks.
+ */
+#define XISF_ADDR_SHIFT24 24 /**< 24 bit Shift */
+#define XISF_ADDR_SHIFT16 16 /**< 16 bit Shift */
+#define XISF_ADDR_SHIFT8 8 /**< 8 bit Shift */
+
+/**
+ * Byte Positions.
+ */
+#define BYTE1 0 /**< Byte 1 position */
+#define BYTE2 1 /**< Byte 2 position */
+#define BYTE3 2 /**< Byte 3 position */
+#define BYTE4 3 /**< Byte 4 position */
+#define BYTE5 4 /**< Byte 5 position */
+
+/**************************** Type Definitions *******************************/
+
+/***************** Macros (Inline Functions) Definitions *********************/
+
+/************************** Function Prototypes ******************************/
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* end of protection macro */
diff --git a/lib/sw_services/xilisf/src/xilisf.c b/lib/sw_services/xilisf/src/xilisf.c
new file mode 100644
index 00000000..62ff99c2
--- /dev/null
+++ b/lib/sw_services/xilisf/src/xilisf.c
@@ -0,0 +1,1956 @@
+/******************************************************************************
+*
+* Copyright (C) 2012 - 2015 Xilinx, Inc. All rights reserved.
+*
+* Permission is hereby granted, free of charge, to any person obtaining a copy
+* of this software and associated documentation files (the "Software"), to deal
+* in the Software without restriction, including without limitation the rights
+* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+* copies of the Software, and to permit persons to whom the Software is
+* furnished to do so, subject to the following conditions:
+*
+* The above copyright notice and this permission notice shall be included in
+* all copies or substantial portions of the Software.
+*
+* Use of the Software is limited solely to applications:
+* (a) running on a Xilinx device, or
+* (b) that interact with a Xilinx device through a bus or interconnect.
+*
+* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+* XILINX BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
+* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+* SOFTWARE.
+*
+* Except as contained in this notice, the name of the Xilinx shall not be used
+* in advertising or otherwise to promote the sale, use or other dealings in
+* this Software without prior written authorization from Xilinx.
+*
+******************************************************************************/
+/*****************************************************************************/
+/**
+*
+* @file xilisf.c
+*
+* This file contains the library functions to initialize, control and read the
+* device information of the Serial Flash devices. Refer xilisf.h for detailed
+* description.
+*
+*
+*
+* MODIFICATION HISTORY:
+*
+* Ver Who Date Changes
+* ----- ------- -------- -----------------------------------------------
+* 1.00a ksu/sdm 03/03/08 First release
+* 1.00a sdm 07/02/08 Changed the initialization so that the SPI
+* Master works in Spi Mode 3 as the In-System Flash
+* works only in Spi Mode 3
+* 2.00a ktn 11/27/09 Updated to use HAL processor APIs/definitions
+* 2.01a sdm 01/04/10 Added Support for Winbond W25QXX/W25XX devices
+* The parameter PagesPerBlock in the struct
+* IntelStmDeviceGeometry has been renamed to
+* PagesPerSector.
+* 2.03a sdm 04/17/10 Updated to support Winbond memory W25Q128.
+* 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:
+* XIsf_RegisterInterface()
+* XIsf_SetSpiConfiguration()
+* XIsf_SetTransferMode()
+* Changed API:
+* XIsf_Initialize()
+* XIsf_Transfer()
+* Added support to SST flash.
+* 3.01a srt 02/06/13 Updated for changes made in QSPIPS driver
+* (CR 698107).
+* 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:
+* SpaMicWinFlashInitialize()
+* GetRealAddr()
+* SendBankSelect()
+* XIsf_SetStatusHandler()
+* void XIsf_IfaceHandler()
+* Changed API:
+* - XIsf_Initialize()
+* Added Call back to lib interrupt handler
+* after XIsf_Transfer Call
+* - XIsf_Transfer()
+* - XIsf_GetStatus()
+* - XIsf_GetStatusReg2()
+* - XIsf_GetDeviceInfo()
+* - XIsf_WriteEnable()
+* - XIsf_Ioctl()
+* 5.1 sb 12/23/14 Added check for flash interface for Winbond, Spansion
+* and Micron flash family for PSQSPI.
+* 5.2 asa 05/12/15 Added APIs to support 4 byte addressing for Micron flash.
+* 2 APIs were added, one to enter into 4 byte mode and the other
+* to exit from the same.
+*
+*
+*
+******************************************************************************/
+
+/***************************** Include Files *********************************/
+
+#include "include/xilisf.h"
+
+/************************** Constant Definitions *****************************/
+
+/**************************** Type Definitions *******************************/
+
+#if (XPAR_XISF_FLASH_FAMILY == ATMEL)
+/**
+ * The following structure specifies the geometry of the Atmel Serial Flash.
+ */
+typedef struct {
+ u8 DeviceCode; /**< Device code */
+ u16 BytesPerPageDefaultMode; /**< Bytes per Page in Default mode */
+ u16 BytesPerPagePowerOf2Mode; /**< Bytes per Page in PowerOf2 mode */
+ u8 PagesPerBlock; /**< Number of Pages per Block */
+ u8 BlocksPerSector; /**< Number of Blocks per Sector */
+ u8 NumOfSectors; /**< Number of Sectors in the device */
+} AtmelDeviceGeometry;
+#endif /* (XPAR_XISF_FLASH_FAMILY == ATMEL) */
+
+#if (((XPAR_XISF_FLASH_FAMILY == INTEL) || (XPAR_XISF_FLASH_FAMILY == STM) \
+ || (XPAR_XISF_FLASH_FAMILY == SST) || \
+ (XPAR_XISF_FLASH_FAMILY == WINBOND) || \
+ (XPAR_XISF_FLASH_FAMILY == SPANSION)) && \
+ (!defined(XPAR_XISF_INTERFACE_PSQSPI))) \
+/**
+ * The following structure specifies the geometry of the Intel/STM Serial Flash.
+ */
+typedef struct {
+ u8 ManufacturerID; /**< Manufacturer code */
+ u16 DeviceCode; /**< Device code */
+ u16 BytesPerPage; /**< Bytes per Page */
+ u16 PagesPerSector; /**< Number of Pages per Sector */
+ u16 NumOfSectors; /**< Number of Sectors in the device */
+} IntelStmDeviceGeometry;
+#endif /* (((XPAR_XISF_FLASH_FAMILY == INTEL) ||
+ (XPAR_XISF_FLASH_FAMILY == STM) || \
+ (XPAR_XISF_FLASH_FAMILY == SST) || \
+ (XPAR_XISF_FLASH_FAMILY == WINBOND) || \
+ (XPAR_XISF_FLASH_FAMILY == SPANSION)) && \
+ (!defined(XPAR_XISF_INTERFACE_PSQSPI)))*/
+
+#if (((XPAR_XISF_FLASH_FAMILY == WINBOND) || \
+ (XPAR_XISF_FLASH_FAMILY == SPANSION)) && \
+ defined(XPAR_XISF_INTERFACE_PSQSPI))
+/**
+ * The following structure specifies the geometry of the Spansion/Micron
+ * Serial Flash.
+ */
+typedef struct {
+ u32 SectSize; /**< Individual sector size or
+ * combined sector size in case of parallel
+ * config*/
+ u32 NumSect; /**< Total no. of sectors in one/two
+ * flash devices */
+ u32 PageSize; /**< Individual page size or
+ * combined page size in case of parallel
+ * config*/
+ u32 NumPage; /**< Total no. of pages in one/two flash
+ * devices */
+ u32 FlashDeviceSize; /**< This is the size of one flash device
+ * NOT the combination of both devices,
+ * if present */
+ u8 ManufacturerID; /**< Manufacturer ID - used to identify make */
+ u8 DeviceIDMemSize; /**< Byte of device ID indicating the memory
+ * size */
+ u32 SectMask; /**< Mask to get sector start address */
+ u8 NumDie; /**< No. of die forming a single flash */
+} SpaMicWinDeviceGeometry;
+
+#endif /* (((XPAR_XISF_FLASH_FAMILY == WINBOND) || \
+ (XPAR_XISF_FLASH_FAMILY == SPANSION)) && \
+ defined(XPAR_XISF_INTERFACE_PSQSPI)) */
+
+
+/***************** Macros (Inline Functions) Definitions *********************/
+
+/************************** Function Prototypes ******************************/
+
+int XIsf_Transfer(XIsf *InstancePtr, u8 *WritePtr, u8* ReadPtr,u32 ByteCount);
+
+u32 GetRealAddr(XIsf_Iface *QspiPtr, u32 Address);
+
+#ifdef XPAR_XISF_INTERFACE_PSQSPI
+int SendBankSelect(XIsf *InstancePtr, u32 BankSel);
+#endif
+
+#if (XPAR_XISF_FLASH_FAMILY == ATMEL)
+static int AtmelFlashInitialize(XIsf *InstancePtr, u8 *ReadBuf);
+#endif /* (XPAR_XISF_FLASH_FAMILY == ATMEL) */
+
+#if (((XPAR_XISF_FLASH_FAMILY == SPANSION)) && \
+ (!defined(XPAR_XISF_INTERFACE_PSQSPI)))
+static int IntelStmFlashInitialize(XIsf *InstancePtr, u8 *ReadBuf);
+#endif /* (((XPAR_XISF_FLASH_FAMILY == INTEL) || \
+ (XPAR_XISF_FLASH_FAMILY == STM) || \
+ (XPAR_XISF_FLASH_FAMILY == SST) || \
+ (XPAR_XISF_FLASH_FAMILY == WINBOND) || \
+ (XPAR_XISF_FLASH_FAMILY == SPANSION)) && \
+ (!defined(XPAR_XISF_INTERFACE_PSQSPI))) */
+
+#if (((XPAR_XISF_FLASH_FAMILY == WINBOND) || \
+ (XPAR_XISF_FLASH_FAMILY == SPANSION)) && \
+ defined(XPAR_XISF_INTERFACE_PSQSPI))
+static int SpaMicWinFlashInitialize(XIsf *InstancePtr, u8 *BufferPtr);
+
+#endif /* (((XPAR_XISF_FLASH_FAMILY == WINBOND) || \
+ (XPAR_XISF_FLASH_FAMILY == SPANSION)) && \
+ defined(XPAR_XISF_INTERFACE_PSQSPI)) */
+
+/************************** Variable Definitions *****************************/
+
+#if (XPAR_XISF_FLASH_FAMILY == ATMEL)
+static const AtmelDeviceGeometry AtmelDevices[] = {
+
+ {XISF_ATMEL_DEV_AT45DB011D, XISF_BYTES264_PER_PAGE,
+ XISF_BYTES256_PER_PAGE, XISF_PAGES8_PER_BLOCK,
+ XISF_BLOCKS16_PER_SECTOR, XISF_NUM_OF_SECTORS4},
+
+ {XISF_ATMEL_DEV_AT45DB021D, XISF_BYTES264_PER_PAGE,
+ XISF_BYTES256_PER_PAGE, XISF_PAGES8_PER_BLOCK,
+ XISF_BLOCKS16_PER_SECTOR, XISF_NUM_OF_SECTORS8},
+
+ {XISF_ATMEL_DEV_AT45DB041D, XISF_BYTES264_PER_PAGE,
+ XISF_BYTES256_PER_PAGE, XISF_PAGES8_PER_BLOCK,
+ XISF_BLOCKS32_PER_SECTOR, XISF_NUM_OF_SECTORS8},
+
+ {XISF_ATMEL_DEV_AT45DB081D, XISF_BYTES264_PER_PAGE,
+ XISF_BYTES256_PER_PAGE, XISF_PAGES8_PER_BLOCK,
+ XISF_BLOCKS32_PER_SECTOR, XISF_NUM_OF_SECTORS16},
+
+ {XISF_ATMEL_DEV_AT45DB161D, XISF_BYTES528_PER_PAGE,
+ XISF_BYTES512_PER_PAGE, XISF_PAGES8_PER_BLOCK,
+ XISF_BLOCKS32_PER_SECTOR, XISF_NUM_OF_SECTORS16},
+
+ {XISF_ATMEL_DEV_AT45DB321D, XISF_BYTES528_PER_PAGE,
+ XISF_BYTES512_PER_PAGE, XISF_PAGES8_PER_BLOCK,
+ XISF_BLOCKS16_PER_SECTOR, XISF_NUM_OF_SECTORS64},
+
+ {XISF_ATMEL_DEV_AT45DB642D, XISF_BYTES1056_PER_PAGE,
+ XISF_BYTES1024_PER_PAGE, XISF_PAGES8_PER_BLOCK,
+ XISF_BLOCKS32_PER_SECTOR, XISF_NUM_OF_SECTORS32}
+};
+#endif /* (XPAR_XISF_FLASH_FAMILY == ATMEL) */
+
+#if (((XPAR_XISF_FLASH_FAMILY == INTEL) || (XPAR_XISF_FLASH_FAMILY == STM) \
+ || (XPAR_XISF_FLASH_FAMILY == SST) || \
+ (XPAR_XISF_FLASH_FAMILY == WINBOND) || \
+ (XPAR_XISF_FLASH_FAMILY == SPANSION)) && \
+ (!defined(XPAR_XISF_INTERFACE_PSQSPI)))
+static const IntelStmDeviceGeometry IntelStmDevices[] = {
+ {XISF_MANUFACTURER_ID_INTEL, XISF_INTEL_DEV_S3316MBIT,
+ XISF_BYTES256_PER_PAGE, XISF_PAGES256_PER_SECTOR,
+ XISF_NUM_OF_SECTORS32},
+
+ {XISF_MANUFACTURER_ID_INTEL, XISF_INTEL_DEV_S3332MBIT,
+ XISF_BYTES256_PER_PAGE, XISF_PAGES256_PER_SECTOR,
+ XISF_NUM_OF_SECTORS64},
+
+ {XISF_MANUFACTURER_ID_INTEL, XISF_INTEL_DEV_S3364MBIT,
+ XISF_BYTES256_PER_PAGE, XISF_PAGES256_PER_SECTOR,
+ XISF_NUM_OF_SECTORS128},
+
+ {XISF_MANUFACTURER_ID_STM, XISF_STM_DEV_M25P05_A,
+ XISF_BYTES256_PER_PAGE, XISF_PAGES128_PER_SECTOR,
+ XISF_NUM_OF_SECTORS2},
+
+ {XISF_MANUFACTURER_ID_STM, XISF_STM_DEV_M25P10_A,
+ XISF_BYTES256_PER_PAGE, XISF_PAGES256_PER_SECTOR,
+ XISF_NUM_OF_SECTORS2},
+
+ {XISF_MANUFACTURER_ID_STM, XISF_STM_DEV_M25P20,
+ XISF_BYTES256_PER_PAGE, XISF_PAGES256_PER_SECTOR,
+ XISF_NUM_OF_SECTORS4},
+
+ {XISF_MANUFACTURER_ID_STM, XISF_STM_DEV_M25P40,
+ XISF_BYTES256_PER_PAGE, XISF_PAGES256_PER_SECTOR,
+ XISF_NUM_OF_SECTORS8},
+
+ {XISF_MANUFACTURER_ID_STM, XISF_STM_DEV_M25P80,
+ XISF_BYTES256_PER_PAGE, XISF_PAGES256_PER_SECTOR,
+ XISF_NUM_OF_SECTORS16},
+
+ {XISF_MANUFACTURER_ID_STM, XISF_STM_DEV_M25P16,
+ XISF_BYTES256_PER_PAGE, XISF_PAGES256_PER_SECTOR,
+ XISF_NUM_OF_SECTORS32},
+
+ {XISF_MANUFACTURER_ID_STM, XISF_STM_DEV_M25P32,
+ XISF_BYTES256_PER_PAGE, XISF_PAGES256_PER_SECTOR,
+ XISF_NUM_OF_SECTORS64},
+
+ {XISF_MANUFACTURER_ID_STM, XISF_STM_DEV_M25P64,
+ XISF_BYTES256_PER_PAGE, XISF_PAGES256_PER_SECTOR,
+ XISF_NUM_OF_SECTORS128},
+
+ {XISF_MANUFACTURER_ID_STM, XISF_STM_DEV_M25P128,
+ XISF_BYTES256_PER_PAGE, XISF_PAGES1024_PER_SECTOR,
+ XISF_NUM_OF_SECTORS64},
+
+ {XISF_MANUFACTURER_ID_WINBOND, XISF_WB_DEV_W25Q80,
+ XISF_BYTES256_PER_PAGE, XISF_PAGES16_PER_SECTOR,
+ XISF_NUM_OF_SECTORS256},
+
+ {XISF_MANUFACTURER_ID_WINBOND, XISF_WB_DEV_W25Q16,
+ XISF_BYTES256_PER_PAGE, XISF_PAGES16_PER_SECTOR,
+ XISF_NUM_OF_SECTORS512},
+
+ {XISF_MANUFACTURER_ID_WINBOND, XISF_WB_DEV_W25Q32,
+ XISF_BYTES256_PER_PAGE, XISF_PAGES16_PER_SECTOR,
+ XISF_NUM_OF_SECTORS1024},
+
+ {XISF_MANUFACTURER_ID_WINBOND, XISF_WB_DEV_W25Q64,
+ XISF_BYTES256_PER_PAGE, XISF_PAGES16_PER_SECTOR,
+ XISF_NUM_OF_SECTORS2048},
+
+ {XISF_MANUFACTURER_ID_WINBOND, XISF_WB_DEV_W25Q128,
+ XISF_BYTES256_PER_PAGE, XISF_PAGES16_PER_SECTOR,
+ XISF_NUM_OF_SECTORS4096},
+
+ {XISF_MANUFACTURER_ID_WINBOND, XISF_WB_DEV_W25X10,
+ XISF_BYTES256_PER_PAGE, XISF_PAGES16_PER_SECTOR,
+ XISF_NUM_OF_SECTORS32},
+
+ {XISF_MANUFACTURER_ID_WINBOND, XISF_WB_DEV_W25X20,
+ XISF_BYTES256_PER_PAGE, XISF_PAGES16_PER_SECTOR,
+ XISF_NUM_OF_SECTORS64},
+
+ {XISF_MANUFACTURER_ID_WINBOND, XISF_WB_DEV_W25X40,
+ XISF_BYTES256_PER_PAGE, XISF_PAGES16_PER_SECTOR,
+ XISF_NUM_OF_SECTORS128},
+
+ {XISF_MANUFACTURER_ID_WINBOND, XISF_WB_DEV_W25X80,
+ XISF_BYTES256_PER_PAGE, XISF_PAGES16_PER_SECTOR,
+ XISF_NUM_OF_SECTORS256},
+
+ {XISF_MANUFACTURER_ID_WINBOND, XISF_WB_DEV_W25X16,
+ XISF_BYTES256_PER_PAGE, XISF_PAGES16_PER_SECTOR,
+ XISF_NUM_OF_SECTORS512},
+
+ {XISF_MANUFACTURER_ID_WINBOND, XISF_WB_DEV_W25X32,
+ XISF_BYTES256_PER_PAGE, XISF_PAGES16_PER_SECTOR,
+ XISF_NUM_OF_SECTORS1024},
+
+ {XISF_MANUFACTURER_ID_WINBOND, XISF_WB_DEV_W25X64,
+ XISF_BYTES256_PER_PAGE, XISF_PAGES16_PER_SECTOR,
+ XISF_NUM_OF_SECTORS2048},
+
+ {XISF_MANUFACTURER_ID_STM, XISF_NM_DEV_N25Q32,
+ XISF_BYTES256_PER_PAGE, XISF_PAGES256_PER_SECTOR,
+ XISF_NUM_OF_SECTORS64},
+
+ {XISF_MANUFACTURER_ID_STM, XISF_NM_DEV_N25Q64,
+ XISF_BYTES256_PER_PAGE, XISF_PAGES256_PER_SECTOR,
+ XISF_NUM_OF_SECTORS128},
+
+ {XISF_MANUFACTURER_ID_STM, XISF_NM_DEV_N25Q128,
+ XISF_BYTES256_PER_PAGE, XISF_PAGES256_PER_SECTOR,
+ XISF_NUM_OF_SECTORS256},
+
+ {XISF_MANUFACTURER_ID_STM, XISF_MIC_DEV_N25Q128,
+ XISF_BYTES256_PER_PAGE, XISF_PAGES256_PER_SECTOR,
+ XISF_NUM_OF_SECTORS256},
+
+ {XISF_MANUFACTURER_ID_SPANSION, XISF_SPANSION_DEV_S25FL004,
+ XISF_BYTES256_PER_PAGE, XISF_PAGES256_PER_SECTOR,
+ XISF_NUM_OF_SECTORS8},
+
+ {XISF_MANUFACTURER_ID_SPANSION, XISF_SPANSION_DEV_S25FL008,
+ XISF_BYTES256_PER_PAGE, XISF_PAGES256_PER_SECTOR,
+ XISF_NUM_OF_SECTORS16},
+
+ {XISF_MANUFACTURER_ID_SPANSION, XISF_SPANSION_DEV_S25FL016,
+ XISF_BYTES256_PER_PAGE, XISF_PAGES256_PER_SECTOR,
+ XISF_NUM_OF_SECTORS32},
+
+ {XISF_MANUFACTURER_ID_SPANSION, XISF_SPANSION_DEV_S25FL032,
+ XISF_BYTES256_PER_PAGE, XISF_PAGES256_PER_SECTOR,
+ XISF_NUM_OF_SECTORS64},
+
+ {XISF_MANUFACTURER_ID_SPANSION, XISF_SPANSION_DEV_S25FL064,
+ XISF_BYTES256_PER_PAGE, XISF_PAGES256_PER_SECTOR,
+ XISF_NUM_OF_SECTORS128},
+
+ {XISF_MANUFACTURER_ID_SPANSION, XISF_SPANSION_DEV_S25FL128,
+ XISF_BYTES256_PER_PAGE, XISF_PAGES256_PER_SECTOR,
+ XISF_NUM_OF_SECTORS256},
+
+ {XISF_MANUFACTURER_ID_SST, XISF_SST_DEV_SST25WF080,
+ XISF_BYTES256_PER_PAGE, XISF_PAGES256_PER_SECTOR,
+ XISF_NUM_OF_SECTORS256},
+
+ {XISF_MANUFACTURER_ID_MICRON, XISF_MIC_DEV_N25Q256_3V0,
+ XISF_BYTES256_PER_PAGE, XISF_PAGES256_PER_SECTOR,
+ XISF_NUM_OF_SECTORS512},
+
+};
+#endif /* (((XPAR_XISF_FLASH_FAMILY==INTEL) || (XPAR_XISF_FLASH_FAMILY==STM) \
+ || (XPAR_XISF_FLASH_FAMILY == SST) || \
+ (XPAR_XISF_FLASH_FAMILY == WINBOND) || \
+ (XPAR_XISF_FLASH_FAMILY == SPANSION)) && \
+ (!defined(XPAR_XISF_INTERFACE_PSQSPI)))*/
+
+#if (((XPAR_XISF_FLASH_FAMILY == WINBOND) || \
+ (XPAR_XISF_FLASH_FAMILY == SPANSION)) && \
+ defined(XPAR_XISF_INTERFACE_PSQSPI))
+static const SpaMicWinDeviceGeometry SpaMicWinDevices[] = {
+ {0x10000, 0x100, 256, 0x10000, 0x1000000,
+ XISF_MANUFACTURER_ID_SPANSION, XISF_SPANSION_ID_BYTE2_128,
+ 0xFFFF0000, 1},
+ {0x10000, 0x200, 256, 0x20000, 0x1000000,
+ XISF_MANUFACTURER_ID_SPANSION, XISF_SPANSION_ID_BYTE2_128,
+ 0xFFFF0000, 1},
+ {0x20000, 0x100, 512, 0x10000, 0x1000000,
+ XISF_MANUFACTURER_ID_SPANSION, XISF_SPANSION_ID_BYTE2_128,
+ 0xFFFE0000, 1},
+ {0x10000, 0x200, 256, 0x20000, 0x2000000,
+ XISF_MANUFACTURER_ID_SPANSION, XISF_SPANSION_ID_BYTE2_256,
+ 0xFFFF0000, 1},
+ {0x10000, 0x400, 256, 0x40000, 0x2000000,
+ XISF_MANUFACTURER_ID_SPANSION, XISF_SPANSION_ID_BYTE2_256,
+ 0xFFFF0000, 1},
+ {0x20000, 0x200, 512, 0x20000, 0x2000000,
+ XISF_MANUFACTURER_ID_SPANSION, XISF_SPANSION_ID_BYTE2_256,
+ 0xFFFE0000, 1},
+ {0x40000, 0x100, 512, 0x20000, 0x4000000,
+ XISF_MANUFACTURER_ID_SPANSION, XISF_SPANSION_ID_BYTE2_512,
+ 0xFFFC0000, 1},
+ {0x40000, 0x200, 512, 0x40000, 0x4000000,
+ XISF_MANUFACTURER_ID_SPANSION, XISF_SPANSION_ID_BYTE2_512,
+ 0xFFFC0000, 1},
+ {0x80000, 0x100, 1024, 0x20000, 0x4000000,
+ XISF_MANUFACTURER_ID_SPANSION, XISF_SPANSION_ID_BYTE2_512,
+ 0xFFF80000, 1},
+ /* Spansion 1Gbit is handled as 512Mbit stacked */
+ /* Micron */
+ {0x10000, 0x100, 256, 0x10000, 0x1000000,
+ XISF_MANUFACTURER_ID_MICRON, XISF_MICRON_ID_BYTE2_128,
+ 0xFFFF0000, 1},
+ {0x10000, 0x200, 256, 0x20000, 0x1000000,
+ XISF_MANUFACTURER_ID_MICRON, XISF_MICRON_ID_BYTE2_128,
+ 0xFFFF0000, 1},
+ {0x20000, 0x100, 512, 0x10000, 0x1000000,
+ XISF_MANUFACTURER_ID_MICRON, XISF_MICRON_ID_BYTE2_128,
+ 0xFFFE0000, 1},
+ {0x10000, 0x200, 256, 0x20000, 0x2000000,
+ XISF_MANUFACTURER_ID_MICRON, XISF_MICRON_ID_BYTE2_256,
+ 0xFFFF0000, 1},
+ {0x10000, 0x400, 256, 0x40000, 0x2000000,
+ XISF_MANUFACTURER_ID_MICRON, XISF_MICRON_ID_BYTE2_256,
+ 0xFFFF0000, 1},
+ {0x20000, 0x200, 512, 0x20000, 0x2000000,
+ XISF_MANUFACTURER_ID_MICRON, XISF_MICRON_ID_BYTE2_256,
+ 0xFFFE0000, 1},
+ {0x10000, 0x400, 256, 0x40000, 0x4000000,
+ XISF_MANUFACTURER_ID_MICRON, XISF_MICRON_ID_BYTE2_512,
+ 0xFFFF0000, 2},
+ {0x10000, 0x800, 256, 0x80000, 0x4000000,
+ XISF_MANUFACTURER_ID_MICRON, XISF_MICRON_ID_BYTE2_512,
+ 0xFFFF0000, 2},
+ {0x20000, 0x400, 512, 0x40000, 0x4000000,
+ XISF_MANUFACTURER_ID_MICRON, XISF_MICRON_ID_BYTE2_512,
+ 0xFFFE0000, 2},
+ {0x10000, 0x800, 256, 0x80000, 0x8000000,
+ XISF_MANUFACTURER_ID_MICRON, XISF_MICRON_ID_BYTE2_1G,
+ 0xFFFF0000, 4},
+ {0x10000, 0x1000, 256, 0x100000, 0x8000000,
+ XISF_MANUFACTURER_ID_MICRON, XISF_MICRON_ID_BYTE2_1G,
+ 0xFFFF0000, 4},
+ {0x20000, 0x800, 512, 0x80000, 0x8000000,
+ XISF_MANUFACTURER_ID_MICRON, XISF_MICRON_ID_BYTE2_1G,
+ 0xFFFE0000, 4},
+ /* Winbond */
+ {0x10000, 0x100, 256, 0x10000, 0x1000000,
+ XISF_MANUFACTURER_ID_WINBOND, XISF_WINBOND_ID_BYTE2_128,
+ 0xFFFF0000, 1},
+ {0x10000, 0x200, 256, 0x20000, 0x1000000,
+ XISF_MANUFACTURER_ID_WINBOND, XISF_WINBOND_ID_BYTE2_128,
+ 0xFFFF0000, 1},
+ {0x20000, 0x100, 512, 0x10000, 0x1000000,
+ XISF_MANUFACTURER_ID_WINBOND, XISF_WINBOND_ID_BYTE2_128,
+ 0xFFFE0000, 1}
+};
+#endif /* (((XPAR_XISF_FLASH_FAMILY == WINBOND) || \
+ (XPAR_XISF_FLASH_FAMILY == SPANSION)) && \
+ defined(XPAR_XISF_INTERFACE_PSQSPI)) */
+
+/*
+ * The following variables are shared between non-interrupt processing and
+ * interrupt processing such that they must be global.
+ */
+volatile unsigned int XIsf_TransferInProgress;
+u32 XIsf_StatusEventInfo;
+unsigned int XIsf_ByteCountInfo;
+static u32 XIsf_FCTIndex;
+/************************** Function Definitions *****************************/
+
+/*****************************************************************************/
+/**
+*
+* The geometry of the underlying Serial Flash is determined by reading the
+* Joint Electron Device Engineering Council (JEDEC) Device Information and
+* the Status Register of the Serial Flash.
+* This API when called initializes the SPI interface with default settings.
+* With custom settings, user should call XIsf_SetSpiConfiguration() and then
+* call this API.
+*
+* @param InstancePtr is a pointer to the XIsf instance.
+* @param SpiInstPtr is a pointer to XIsf_Iface instance to be worked on.
+* @param SlaveSelect is a 32-bit mask with a 1 in the bit position of
+* slave being selected. Only one slave can be selected at a time.
+* @param WritePtr is a pointer to the buffer allocated by the user to be
+* used by the In-system and Serial Flash Library to perform any
+* read/write operations on the Serial Flash device.
+* User applications must pass the address of this buffer for the
+* Library to work.
+* - Write operations :
+* - The size of this buffer should be equal to the Number
+* of bytes to be written to the Serial Flash +
+* XISF_CMD_MAX_EXTRA_BYTES.
+* - The size of this buffer should be large enough for
+* usage across all the applications that use a common
+* instance of the Serial Flash.
+* - A minimum of one byte and a maximum of ISF_PAGE_SIZE
+* bytes can be written to the Serial Flash, through a
+* single Write operation.
+* - Read operations :
+* - The size of this buffer should be equal to
+* XISF_CMD_MAX_EXTRA_BYTES, if the application only reads
+* from the Serial Flash (no write operations).
+*
+* @return - XST_SUCCESS if successful.
+* - XST_DEVICE_IS_STOPPED if the device must be started before
+* transferring data.
+* - XST_FAILURE, otherwise.
+*
+* @note - The XIsf_Initialize() API is a blocking call (for both
+* polled and interrupt modes of the Spi driver). It reads the
+* JEDEC information of the device and waits till the transfer is
+* complete before checking if the information is valid.
+* - This library can support multiple instances of Serial Flash
+* at a time, provided they are of the same device family (either
+* Atmel, Intel or STM, Winbond or Spansion) as the device family
+* is selected at compile time.
+*
+******************************************************************************/
+int XIsf_Initialize(XIsf *InstancePtr, XIsf_Iface *SpiInstPtr, u8 SlaveSelect,
+ u8 *WritePtr)
+{
+ int Status;
+ u8 ReadBuf[XISF_INFO_READ_BYTES + XISF_INFO_EXTRA_BYTES] = {0};
+
+ if (InstancePtr == NULL) {
+ return (int)(XST_FAILURE);
+ }
+
+ if (SpiInstPtr == NULL) {
+ return (int)(XST_FAILURE);
+ }
+
+ if (WritePtr == NULL) {
+ return (int)(XST_FAILURE);
+ }
+
+ InstancePtr->IsReady = FALSE;
+ InstancePtr->SpiSlaveSelect = SlaveSelect;
+ InstancePtr->WriteBufPtr = WritePtr;
+
+#ifdef XPAR_XISF_INTERFACE_AXISPI
+ if (SpiInstPtr->IsStarted != XIL_COMPONENT_IS_STARTED) {
+ return XST_DEVICE_IS_STOPPED;
+ }
+#endif
+
+ if ((!InstancePtr->RegDone) != 0) {
+ (void)XIsf_SetSpiConfiguration(InstancePtr, SpiInstPtr,
+ XISF_SPI_OPTIONS, XISF_SPI_PRESCALER);
+ }
+
+ /*
+ * Get the JEDEC Device Info.
+ * The IsReady is temporarily made TRUE and
+ * transfer is set in polling mode to fetch the JEDEC Info.
+ */
+ XIsf_SetTransferMode(InstancePtr, XISF_POLLING_MODE);
+ InstancePtr->IsReady = TRUE;
+ Status = XIsf_GetDeviceInfo(InstancePtr, ReadBuf);
+ InstancePtr->IsReady = FALSE;
+ if (Status != (int)(XST_SUCCESS)) {
+ return (int)(XST_FAILURE);
+ }
+
+#ifdef XPAR_XISF_INTERFACE_AXISPI
+ /*
+ * Wait until the transfer is complete.
+ */
+ do {
+ Status =
+ InstancePtr->XIsf_Iface_SetSlaveSelect(InstancePtr->SpiInstPtr,
+ InstancePtr->SpiSlaveSelect);
+ } while(Status == XST_DEVICE_BUSY);
+
+ if (Status != (int)(XST_SUCCESS)) {
+ return (int)(XST_FAILURE);
+ }
+
+#endif
+
+#if (XPAR_XISF_FLASH_FAMILY == ATMEL)
+ /*
+ * Check for Atmel Serial Flash.
+ */
+ Status = AtmelFlashInitialize(InstancePtr, ReadBuf);
+
+#endif /* (XPAR_XISF_FLASH_FAMILY == ATMEL) */
+
+#if (((XPAR_XISF_FLASH_FAMILY == INTEL) || (XPAR_XISF_FLASH_FAMILY == STM) \
+ || (XPAR_XISF_FLASH_FAMILY == SST) || \
+ (XPAR_XISF_FLASH_FAMILY == WINBOND) || \
+ (XPAR_XISF_FLASH_FAMILY == SPANSION)) && \
+ (!defined(XPAR_XISF_INTERFACE_PSQSPI)))
+
+ /*
+ * Check for Intel/STM/Winbond/Spansion Serial Flash.
+ */
+ Status = IntelStmFlashInitialize(InstancePtr, ReadBuf);
+
+#endif /* (((XPAR_XISF_FLASH_FAMILY==INTEL) || (XPAR_XISF_FLASH_FAMILY==STM) \
+ || (XPAR_XISF_FLASH_FAMILY == SST) || \
+ (XPAR_XISF_FLASH_FAMILY == WINBOND) || \
+ (XPAR_XISF_FLASH_FAMILY == SPANSION)) && \
+ (!defined(XPAR_XISF_INTERFACE_PSQSPI)))*/
+#if (((XPAR_XISF_FLASH_FAMILY == WINBOND) || \
+ (XPAR_XISF_FLASH_FAMILY == SPANSION)) && \
+ defined(XPAR_XISF_INTERFACE_PSQSPI))
+
+ Status = SpaMicWinFlashInitialize(InstancePtr, ReadBuf);
+
+#endif /*(((XPAR_XISF_FLASH_FAMILY == WINBOND) || \
+ (XPAR_XISF_FLASH_FAMILY == SPANSION)) && \
+ defined(XPAR_XISF_INTERFACE_PSQSPI)) */
+
+ return Status;
+}
+
+
+/*****************************************************************************/
+/**
+*
+* This API sets the configuration of SPI. This will set the options and
+* clock prescaler (if applicable).
+*
+* @param InstancePtr is a pointer to the XIsf instance.
+* @param SpiInstPtr is a pointer to XIsf_Iface instance to be worked on.
+* @param Options contains specified options to be set.
+* @param PreScaler is the value of the clock prescaler to set.
+*
+* @return XST_SUCCESS if successful else XST_FAILURE.
+*
+* @note This API can be called before calling XIsf_Initialize()
+* to initialize the SPI interface in other than default options
+* mode. PreScaler is only applicable to PS SPI/QSPI.
+*
+******************************************************************************/
+int XIsf_SetSpiConfiguration(XIsf *InstancePtr, XIsf_Iface *SpiInstPtr,
+ u32 Options, u8 PreScaler)
+{
+ int Status;
+
+ if ((!InstancePtr->RegDone) != 0) {
+ XIsf_RegisterInterface(InstancePtr);
+ InstancePtr->SpiInstPtr = SpiInstPtr;
+ InstancePtr->RegDone = TRUE;
+ }
+
+ Status = InstancePtr->XIsf_Iface_SetOptions(InstancePtr->SpiInstPtr,
+ Options);
+ if (Status != (int)(XST_SUCCESS)){
+ return (int)(XST_FAILURE);
+ }
+
+ if ((InstancePtr->XIsf_Iface_SetClkPrescaler) != NULL) {
+ Status = InstancePtr->XIsf_Iface_SetClkPrescaler(
+ InstancePtr->SpiInstPtr, PreScaler);
+ if (Status != (int)(XST_SUCCESS)){
+ return (int)(XST_FAILURE);
+ }
+ }
+
+ return (int)(XST_SUCCESS);
+}
+
+
+/*****************************************************************************/
+/**
+*
+* This API reads the Serial Flash Status Register.
+*
+* @param InstancePtr is a pointer to the XIsf instance.
+* @param ReadPtr is a pointer to the memory where the Status Register
+* content is copied.
+*
+* @return XST_SUCCESS if successful else XST_FAILURE.
+*
+* @note The contents of the Status Register is stored at second byte
+* pointed by the ReadPtr.
+*
+******************************************************************************/
+int XIsf_GetStatus(XIsf *InstancePtr, u8 *ReadPtr)
+{
+ int Status;
+ u8 Mode;
+
+ if (InstancePtr == NULL) {
+ return (int)(XST_FAILURE);
+ }
+
+ if (InstancePtr->IsReady != TRUE) {
+ return (int)(XST_FAILURE);
+ }
+
+ if (ReadPtr == NULL) {
+ return (int)(XST_FAILURE);
+ }
+
+ /*
+ * Prepare the Write Buffer.
+ */
+ InstancePtr->WriteBufPtr[BYTE1] = XISF_CMD_STATUSREG_READ;
+ InstancePtr->WriteBufPtr[BYTE2] = XISF_DUMMYBYTE;
+
+ /*
+ * Initiate the Transfer.
+ */
+ Status = XIsf_Transfer(InstancePtr, InstancePtr->WriteBufPtr, ReadPtr,
+ XISF_STATUS_RDWR_BYTES);
+ /*
+ * Get the Transfer Mode
+ */
+ Mode = XIsf_GetTransferMode(InstancePtr);
+
+ if(Mode == XISF_INTERRUPT_MODE){
+ InstancePtr->StatusHandler(InstancePtr,
+ XIsf_StatusEventInfo, XIsf_ByteCountInfo);
+ }
+
+ if (Status != (int)(XST_SUCCESS)) {
+ return (int)(XST_FAILURE);
+ }
+
+ return (int)(XST_SUCCESS);
+}
+
+/*****************************************************************************/
+/**
+*
+* This API reads the Serial Flash Status Register 2.
+*
+* @param InstancePtr is a pointer to the XIsf instance.
+* @param ReadPtr is a pointer to the memory where the Status Register
+* content is copied.
+*
+* @return XST_SUCCESS if successful else XST_FAILURE.
+*
+* @note The contents of the Status Register 2 is stored at the second
+* byte pointed by the ReadPtr.
+* This operation is available only in Winbond Serial Flash.
+*
+******************************************************************************/
+#if (XPAR_XISF_FLASH_FAMILY == WINBOND)
+int XIsf_GetStatusReg2(XIsf *InstancePtr, u8 *ReadPtr)
+{
+ int Status;
+ u8 Mode;
+
+ if (InstancePtr == NULL) {
+ return (int)(XST_FAILURE);
+ }
+
+ if (InstancePtr->IsReady != TRUE) {
+ return (int)(XST_FAILURE);
+ }
+
+ if (ReadPtr == NULL) {
+ return (int)(XST_FAILURE);
+ }
+
+ /*
+ * Prepare the Write Buffer.
+ */
+ InstancePtr->WriteBufPtr[BYTE1] = XISF_CMD_STATUSREG2_READ;
+ InstancePtr->WriteBufPtr[BYTE2] = XISF_DUMMYBYTE;
+
+ /*
+ * Initiate the Transfer.
+ */
+ Status = XIsf_Transfer(InstancePtr, InstancePtr->WriteBufPtr, ReadPtr,
+ XISF_STATUS_RDWR_BYTES);
+ /*
+ * Get the Transfer Mode
+ */
+ Mode = XIsf_GetTransferMode(InstancePtr);
+
+ if(Mode == XISF_INTERRUPT_MODE){
+ InstancePtr->StatusHandler(InstancePtr,
+ XIsf_StatusEventInfo, XIsf_ByteCountInfo);
+ }
+
+ if (Status != (int)(XST_SUCCESS)) {
+ return (int)(XST_FAILURE);
+ }
+
+ return (int)(XST_SUCCESS);
+}
+#endif
+
+/*****************************************************************************/
+/**
+*
+* This API reads the Joint Electron Device Engineering Council (JEDEC)
+* information of the Serial Flash.
+*
+* @param InstancePtr is a pointer to the XIsf instance.
+* @param ReadPtr is a pointer to the buffer where the Device information
+* is copied.
+*
+* @return XST_SUCCESS if successful else XST_FAILURE.
+*
+* @note The Device information is stored at the second byte pointed
+* by the ReadPtr.
+*
+******************************************************************************/
+int XIsf_GetDeviceInfo(XIsf *InstancePtr, u8 *ReadPtr)
+{
+ int Status;
+ u8 Mode;
+
+ if (InstancePtr == NULL) {
+ return (int)(XST_FAILURE);
+ }
+
+ if (InstancePtr->IsReady != TRUE) {
+ return (int)(XST_FAILURE);
+ }
+
+ if (ReadPtr == NULL) {
+ return (int)(XST_FAILURE);
+ }
+
+ /*
+ * Prepare the Write Buffer.
+ */
+ InstancePtr->WriteBufPtr[BYTE1] = XISF_CMD_ISFINFO_READ;
+ InstancePtr->WriteBufPtr[BYTE2] = XISF_DUMMYBYTE;
+ InstancePtr->WriteBufPtr[BYTE3] = XISF_DUMMYBYTE;
+ InstancePtr->WriteBufPtr[BYTE4] = XISF_DUMMYBYTE;
+ InstancePtr->WriteBufPtr[BYTE5] = XISF_DUMMYBYTE;
+
+ /*
+ * Initiate the Transfer.
+ */
+ Status = XIsf_Transfer(InstancePtr, InstancePtr->WriteBufPtr,
+ ReadPtr, XISF_INFO_READ_BYTES);
+ /*
+ * Get the Transfer Mode
+ */
+ Mode = XIsf_GetTransferMode(InstancePtr);
+
+ if(Mode == XISF_INTERRUPT_MODE){
+ InstancePtr->StatusHandler(InstancePtr,
+ XIsf_StatusEventInfo, XIsf_ByteCountInfo);
+ }
+
+ if (Status != (int)(XST_SUCCESS)) {
+ return (int)(XST_FAILURE);
+ }
+
+ return Status;
+}
+
+/*****************************************************************************/
+/**
+*
+* This API Enables/Disables writes to the Intel, STM, Winbond and Spansion
+* Serial Flash.
+*
+* @param InstancePtr is a pointer to the XIsf instance.
+* @param WriteEnable specifies whether to Enable (XISF_CMD_ENABLE_WRITE)
+* or Disable (XISF_CMD_DISABLE_WRITE) the writes to the
+* Serial Flash.
+*
+* @return XST_SUCCESS if successful else XST_FAILURE.
+*
+* @note This API works only for Intel, STM, Winbond and Spansion Serial
+* Flash. If this API is called for Atmel Flash, XST_FAILURE is
+* returned.
+*
+******************************************************************************/
+int XIsf_WriteEnable(XIsf *InstancePtr, u8 WriteEnable)
+{
+ int Status = (int)(XST_FAILURE);
+ u8 Mode;
+ u8 WriteEnableBuf[1] = {0};
+ u8 * NULLPtr = NULL;
+#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))
+
+ if (InstancePtr == NULL) {
+ return (int)(XST_FAILURE);
+ }
+
+ if (InstancePtr->IsReady != TRUE) {
+ return (int)(XST_FAILURE);
+ }
+
+ if (WriteEnable == XISF_WRITE_ENABLE) {
+
+ WriteEnableBuf[BYTE1] = XISF_CMD_ENABLE_WRITE;
+
+ } else if (WriteEnable == XISF_WRITE_DISABLE) {
+
+ WriteEnableBuf[BYTE1] = XISF_CMD_DISABLE_WRITE;
+ } else {
+
+ return Status;
+ }
+
+ Xil_AssertNonvoid(NULLPtr == NULL);
+
+ /*
+ * Initiate the Transfer.
+ */
+ Status = XIsf_Transfer(InstancePtr, WriteEnableBuf, NULLPtr,
+ XISF_CMD_WRITE_ENABLE_DISABLE_BYTES);
+
+ /*
+ * Get the Transfer Mode
+ */
+ Mode = XIsf_GetTransferMode(InstancePtr);
+
+ if(Mode == XISF_INTERRUPT_MODE){
+ InstancePtr->StatusHandler(InstancePtr,
+ XIsf_StatusEventInfo, XIsf_ByteCountInfo);
+ }
+
+
+#endif /* ((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)) */
+
+ return Status;
+}
+
+/*****************************************************************************/
+/**
+*
+* This API configures and controls the Intel, STM, Winbond and Spansion Serial
+* Flash.
+*
+* @param InstancePtr is a pointer to the XIsf instance.
+* @param Operation is the type of Control operation to be performed
+* on the Serial Flash.
+* The different control operations are
+ - XISF_RELEASE_DPD: Release from Deep Power Down (DPD) Mode
+ - XISF_ENTER_DPD: Enter DPD Mode
+ - XISF_CLEAR_SR_FAIL_FLAGS: Clear Status Register Fail Flags
+*
+* @return XST_SUCCESS if successful else XST_FAILURE.
+*
+* @note
+* - Atmel Serial Flash does not support any of these operations.
+* - Intel Serial Flash support Enter/Release from DPD Mode and
+* Clear Status Register Fail Flags.
+* - STM, Winbond and Spansion Serial Flash support Enter/Release
+* from DPD Mode.
+* - Winbond (W25QXX) Serial Flash support Enable High Performance
+* mode.
+*
+******************************************************************************/
+int XIsf_Ioctl(XIsf *InstancePtr, XIsf_IoctlOperation Operation)
+{
+ int Status;
+ u8 Mode;
+ u8* NULLPtr = NULL;
+
+#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))
+ u8 NumBytes;
+
+ if (InstancePtr == NULL) {
+ return (int)(XST_FAILURE);
+ }
+
+ if (InstancePtr->IsReady != TRUE) {
+ return (int)(XST_FAILURE);
+ }
+
+ switch (Operation) {
+ case XISF_IOCTL_RELEASE_DPD:
+ InstancePtr->WriteBufPtr[BYTE1] =
+ XISF_CMD_RELEASE_FROM_DPD;
+ NumBytes = XISF_IOCTL_BYTES;
+ break;
+
+ case XISF_IOCTL_ENTER_DPD:
+ InstancePtr->WriteBufPtr[BYTE1] =
+ XISF_CMD_DEEP_POWER_DOWN;
+ NumBytes = XISF_IOCTL_BYTES;
+ break;
+
+#if (XPAR_XISF_FLASH_FAMILY == INTEL)
+ case XISF_IOCTL_CLEAR_SR_FAIL_FLAGS:
+ InstancePtr->WriteBufPtr[BYTE1] =
+ XISF_CMD_CLEAR_SRFAIL_FLAGS;
+ NumBytes = XISF_IOCTL_BYTES;
+ break;
+#endif /* (XPAR_XISF_FLASH_FAMILY == INTEL) */
+
+#if (XPAR_XISF_FLASH_FAMILY == WINBOND)
+ case XISF_IOCTL_ENABLE_HI_PERF_MODE:
+ InstancePtr->WriteBufPtr[BYTE1] =
+ XISF_CMD_ENABLE_HPM;
+ NumBytes = XISF_HPM_BYTES;
+ break;
+#endif /* (XPAR_XISF_FLASH_FAMILY == WINBOND) */
+
+ default:
+ return (int)(XST_FAILURE);
+ }
+
+ Xil_AssertNonvoid(NULLPtr == NULL);
+
+ /*
+ * Initiate the Transfer.
+ */
+ Status = XIsf_Transfer(InstancePtr, InstancePtr->WriteBufPtr, NULLPtr,
+ NumBytes);
+ /*
+ * Get the Transfer Mode
+ */
+ Mode = XIsf_GetTransferMode(InstancePtr);
+
+ if(Mode == XISF_INTERRUPT_MODE){
+ InstancePtr->StatusHandler(InstancePtr,
+ XIsf_StatusEventInfo, XIsf_ByteCountInfo);
+ }
+
+#else
+ Status = (int)(XST_FAILURE);
+
+#endif/* ((XPAR_XISF_FLASH_FAMILY==INTEL) || (XPAR_XISF_FLASH_FAMILY==STM) \
+ (XPAR_XISF_FLASH_FAMILY == WINBOND) ||
+ (XPAR_XISF_FLASH_FAMILY == SPANSION)) */
+
+ return Status;
+}
+
+/*****************************************************************************/
+/*
+*
+* This function performs the SPI transfer.
+*
+* @param InstancePtr is a pointer to the XIsf instance.
+* @param WritePtr is a pointer to the memory which contains the data to
+* be transferred to the Serial Flash .
+* @param ReadPtr is a pointer to the memory where the data read from the
+* Serial Flash is stored.
+* @param ByteCount is the number of bytes to be read from/written to the
+* Serial Flash.
+*
+* @return XST_SUCCESS if successful else XST_FAILURE.
+*
+* @note This function is internal to the In-system and Serial Flash
+* Library. It works with both interrupt mode and polled mode SPI
+* transfers. In polled mode for AXI SPI, the user has to disable
+* the Global Interrupts in the user application, after the Spi
+* is Initialized and Spi driver is started
+*
+******************************************************************************/
+int XIsf_Transfer(XIsf *InstancePtr, u8 *WritePtr, u8* ReadPtr, u32 ByteCount)
+{
+ int Status;
+
+ /*
+ * Select the Serial Flash as a slave.
+ */
+#ifndef XPAR_XISF_INTERFACE_PSQSPI
+ Status = InstancePtr->XIsf_Iface_SetSlaveSelect(
+ InstancePtr->SpiInstPtr,InstancePtr->SpiSlaveSelect);
+#else
+ Status = InstancePtr->XIsf_Iface_SetSlaveSelect(
+ InstancePtr->SpiInstPtr);
+#endif
+ if (Status != (int)(XST_SUCCESS)) {
+ return (int)(XST_FAILURE);
+ }
+
+ /*
+ * Start the transfer.
+ */
+#ifdef XPAR_XISF_INTERFACE_AXISPI
+ if (InstancePtr->IntrMode == XISF_INTERRUPT_MODE) {
+ XIsf_TransferInProgress = TRUE;
+ }
+ Status = InstancePtr->XIsf_Iface_Transfer(InstancePtr->SpiInstPtr,
+ WritePtr, ReadPtr, ByteCount);
+ if (Status != (int)(XST_SUCCESS)) {
+ return (int)(XST_FAILURE);
+ }
+
+ if (InstancePtr->IntrMode == XISF_INTERRUPT_MODE) {
+ while (XIsf_TransferInProgress != 0){
+ /*NOP*/
+ }
+ }
+
+ return (int)(XST_SUCCESS);
+#endif
+
+ if (InstancePtr->IntrMode == XISF_INTERRUPT_MODE) {
+#if defined(XPAR_XISF_INTERFACE_PSQSPI) || defined(XPAR_XISF_INTERFACE_PSSPI)
+ XIsf_TransferInProgress = TRUE;
+#endif
+ Status = InstancePtr->XIsf_Iface_Transfer(
+ InstancePtr->SpiInstPtr,
+ WritePtr, ReadPtr, ByteCount);
+#if defined(XPAR_XISF_INTERFACE_PSQSPI) || defined(XPAR_XISF_INTERFACE_PSSPI)
+ while (XIsf_TransferInProgress != 0){
+ /*NOP*/
+ }
+
+#endif
+ } else {
+ Status = InstancePtr->XIsf_Iface_PolledTransfer(
+ InstancePtr->SpiInstPtr,
+ WritePtr, ReadPtr, ByteCount);
+ }
+
+ if (Status != (int)(XST_SUCCESS)) {
+ return (int)(XST_FAILURE);
+ }
+
+ return (int)(XST_SUCCESS);
+}
+
+
+/*****************************************************************************/
+/*
+*
+* This function registers the interface SPI/SPI PS/QSPI PS.
+*
+* @param InstancePtr is a pointer to the XIsf instance.
+*
+* @return None
+*
+*
+******************************************************************************/
+void XIsf_RegisterInterface(XIsf *InstancePtr)
+{
+#ifdef XPAR_XISF_INTERFACE_AXISPI
+ InstancePtr->XIsf_Iface_SetOptions = XSpi_SetOptions;
+ InstancePtr->XIsf_Iface_SetSlaveSelect = XSpi_SetSlaveSelect;
+ InstancePtr->XIsf_Iface_Transfer = XSpi_Transfer;
+ InstancePtr->XIsf_Iface_Start = XSpi_Start;
+#elif XPAR_XISF_INTERFACE_PSSPI
+ InstancePtr->XIsf_Iface_SetOptions = XSpiPs_SetOptions;
+ InstancePtr->XIsf_Iface_SetSlaveSelect = XSpiPs_SetSlaveSelect;
+ InstancePtr->XIsf_Iface_Transfer = XSpiPs_Transfer;
+ InstancePtr->XIsf_Iface_PolledTransfer = XSpiPs_PolledTransfer;
+ InstancePtr->XIsf_Iface_SetClkPrescaler = XSpiPs_SetClkPrescaler;
+#elif XPAR_XISF_INTERFACE_PSQSPI
+ InstancePtr->XIsf_Iface_SetOptions = XQspiPs_SetOptions;
+ InstancePtr->XIsf_Iface_SetSlaveSelect = XQspiPs_SetSlaveSelect;
+ InstancePtr->XIsf_Iface_Transfer = XQspiPs_Transfer;
+ InstancePtr->XIsf_Iface_PolledTransfer = XQspiPs_PolledTransfer;
+ InstancePtr->XIsf_Iface_SetClkPrescaler = XQspiPs_SetClkPrescaler;
+#endif
+}
+
+
+#if (XPAR_XISF_FLASH_FAMILY == ATMEL)
+/*****************************************************************************/
+/**
+*
+* This function initializes the instance structure with the device geometry of
+* the Atmel Serial Flash if it is an Atmel device.
+*
+* @param InstancePtr is a pointer to the XIsf instance.
+* @param BufferPtr is a pointer to the memory where the device info of
+* the Serial Flash is present.
+*
+* @return - XST_SUCCESS if device information matches the JEDEC
+* information of the Atmel Serial Flash.
+* - XST_FAILURE if device information doesn't match with Atmel
+* Serial Flash.
+*
+* @note None
+*
+******************************************************************************/
+static int AtmelFlashInitialize(XIsf *InstancePtr, u8 *BufferPtr)
+{
+ int Status;
+ u32 Index;
+ u8 StatusRegister;
+ u8 NumOfDevices;
+ u8 ManufacturerID;
+
+ ManufacturerID = BufferPtr[BYTE2];
+ if (ManufacturerID == XISF_MANUFACTURER_ID_ATMEL) {
+
+ /*
+ * For Atmel Serial Flash the device code is the 3rd byte of
+ * JEDEC info.
+ */
+ InstancePtr->DeviceCode = BufferPtr[BYTE3];
+
+ /*
+ * Get the Status Register contents.
+ * The IsReady is temporarily made TRUE to fetch the Status
+ * Register contents.
+ */
+ InstancePtr->IsReady = TRUE;
+ Status = XIsf_GetStatus(InstancePtr, BufferPtr);
+ InstancePtr->IsReady = FALSE;
+ if (Status != (int)(XST_SUCCESS)) {
+ return (int)(XST_FAILURE);
+ }
+
+ /*
+ * Wait until the transfer is complete.
+ */
+ do {
+#ifndef XPAR_XISF_INTERFACE_PSQSPI
+ Status = InstancePtr->XIsf_Iface_SetSlaveSelect(
+ InstancePtr->SpiInstPtr,
+ InstancePtr->SpiSlaveSelect);
+#else
+ Status = InstancePtr->XIsf_Iface_SetSlaveSelect(
+ InstancePtr->SpiInstPtr);
+#endif
+ } while(Status == XST_DEVICE_BUSY);
+
+ if (Status != (int)(XST_SUCCESS)) {
+ return (int)(XST_FAILURE);
+ }
+
+ StatusRegister = BufferPtr[BYTE2];
+
+ /*
+ * Get the Address mode from the Status Register of Serial
+ * Flash.
+ */
+ InstancePtr->AddrMode = StatusRegister &
+ XISF_SR_ADDR_MODE_MASK;
+
+ /*
+ * Update the Serial Flash instance structure with device
+ * geometry.
+ */
+ NumOfDevices = sizeof(AtmelDevices) /
+ sizeof(AtmelDeviceGeometry);
+
+ for(Index = 0; Index < NumOfDevices; Index++) {
+ if (InstancePtr->DeviceCode == AtmelDevices[Index].
+ DeviceCode) {
+ /*
+ * Default address mode device.
+ */
+ if (InstancePtr->AddrMode ==
+ XISF_DEFAULT_ADDRESS) {
+ InstancePtr->BytesPerPage =
+ AtmelDevices [Index].
+ BytesPerPageDefaultMode;
+ } else {
+ /*
+ * Power of 2 address mode device.
+ */
+ InstancePtr->BytesPerPage =
+ AtmelDevices [Index].
+ BytesPerPagePowerOf2Mode;
+ }
+
+ InstancePtr->PagesPerBlock =
+ AtmelDevices[Index].PagesPerBlock;
+
+ InstancePtr->BlocksPerSector =
+ AtmelDevices[Index].BlocksPerSector;
+
+ InstancePtr->NumOfSectors =
+ AtmelDevices[Index].NumOfSectors;
+
+ if (InstancePtr->BytesPerPage >
+ XISF_BYTES1024_PER_PAGE ) {
+ InstancePtr->ByteMask =
+ XISF_BYTES2048_PER_PAGE_MASK;
+ }
+ else if (InstancePtr->BytesPerPage >
+ XISF_BYTES512_PER_PAGE ) {
+ InstancePtr->ByteMask =
+ XISF_BYTES1024_PER_PAGE_MASK;
+ }
+ else if (InstancePtr->BytesPerPage >
+ XISF_BYTES256_PER_PAGE ) {
+ InstancePtr->ByteMask =
+ XISF_BYTES512_PER_PAGE_MASK;
+ }
+ else {
+ InstancePtr->ByteMask =
+ XISF_BYTES256_PER_PAGE_MASK;
+ }
+
+ InstancePtr->IsReady = TRUE;
+ }
+ }
+ }
+
+ /*
+ * If the device is not supported, return Failure.
+ */
+ if (InstancePtr->IsReady != TRUE) {
+ return (int)(XST_FAILURE);
+ }
+
+ return (int)(XST_SUCCESS);
+}
+#endif /* (XPAR_XISF_FLASH_FAMILY == ATMEL) */
+
+#if (((XPAR_XISF_FLASH_FAMILY == SPANSION)) && \
+ (!defined(XPAR_XISF_INTERFACE_PSQSPI)))
+/*****************************************************************************/
+/**
+*
+* This function enters the Micron flash device into 4 bytes addressing mode.
+* As per the Micron spec, before issuing the command to enter into 4 byte addr
+* mode, a write enable command is issued.
+*
+* @param InstancePtr is a pointer to the XIsf instance.
+*
+* @return - XST_SUCCESS
+* - XST_FAILURE
+*
+* @note Applicable only for Micron flash devices
+*
+******************************************************************************/
+int XIsf_MicronFlashEnter4BAddMode(XIsf *InstancePtr)
+{
+ int Status;
+ u8* NULLPtr = NULL;
+ u8 Mode;
+
+ if (InstancePtr == NULL) {
+ return (int)(XST_FAILURE);
+ }
+
+ if (InstancePtr->IsReady != TRUE) {
+ return (int)(XST_FAILURE);
+ }
+
+ if (InstancePtr->FourByteAddrMode == TRUE) {
+ return (int)(XST_SUCCESS);
+ }
+
+ InstancePtr->WriteBufPtr[BYTE1] = XISF_CMD_ENTER_4BYTE_ADDR_MODE;
+
+ Status = XIsf_Transfer(InstancePtr, InstancePtr->WriteBufPtr,
+ NULLPtr, XISF_CMD_4BYTE_ADDR_ENTER_EXIT_BYTES);
+
+ Mode = XIsf_GetTransferMode(InstancePtr);
+
+ if(Mode == XISF_INTERRUPT_MODE){
+ InstancePtr->StatusHandler(InstancePtr,
+ XIsf_StatusEventInfo, XIsf_ByteCountInfo);
+ }
+
+ if (Status != (int)(XST_SUCCESS)) {
+ return (int)(XST_FAILURE);
+ }
+
+ InstancePtr->FourByteAddrMode = TRUE;
+ return Status;
+}
+
+/*****************************************************************************/
+/**
+*
+* This function exits the Micron flash device from 4 bytes addressing mode.
+* As per the Micron spec, before issuing this command a write enable command is
+* first issued.
+*
+* @param InstancePtr is a pointer to the XIsf instance.
+*
+* @return - XST_SUCCESS
+* - XST_FAILURE
+*
+* @note Applicable only for Micron flash devices
+*
+******************************************************************************/
+int XIsf_MicronFlashExit4BAddMode(XIsf *InstancePtr)
+{
+ int Status;
+ u8* NULLPtr = NULL;
+ u8 Mode;
+
+ if (InstancePtr == NULL) {
+ return (int)(XST_FAILURE);
+ }
+
+ if (InstancePtr->IsReady != TRUE) {
+ return (int)(XST_FAILURE);
+ }
+
+ if (InstancePtr->FourByteAddrMode == FALSE) {
+ return (int)(XST_SUCCESS);
+ }
+
+ InstancePtr->WriteBufPtr[BYTE1] = XISF_CMD_EXIT_4BYTE_ADDR_MODE;
+
+ Status = XIsf_Transfer(InstancePtr, InstancePtr->WriteBufPtr,
+ NULLPtr, XISF_CMD_4BYTE_ADDR_ENTER_EXIT_BYTES);
+
+ Mode = XIsf_GetTransferMode(InstancePtr);
+
+ if(Mode == XISF_INTERRUPT_MODE){
+ InstancePtr->StatusHandler(InstancePtr,
+ XIsf_StatusEventInfo, XIsf_ByteCountInfo);
+ }
+
+ if (Status != (int)(XST_SUCCESS)) {
+ return (int)(XST_FAILURE);
+ }
+ InstancePtr->FourByteAddrMode = FALSE;
+ return Status;
+}
+
+/*****************************************************************************/
+/**
+*
+* This function initializes the instance structure with the device geometry of
+* the Intel/Stm/Winbond Serial Flash if it is an Intel/Stm/Winbond device.
+*
+* @param InstancePtr is a pointer to the XIsf instance.
+* @param BufferPtr is a pointer to the memory where the device info of
+* the Serial Flash is present.
+*
+* @return - XST_SUCCESS if device information matches the JEDEC
+* information of Intel or Stm or Winbond Serial Flash.
+* - XST_FAILURE if device information doesn't match with Intel
+* or Stm or Winbond Serial Flash.
+*
+* @note None
+*
+******************************************************************************/
+static int IntelStmFlashInitialize(XIsf *InstancePtr, u8 *BufferPtr)
+{
+ u32 Index;
+ u8 NumOfDevices;
+ u8 ManufacturerID;
+
+ ManufacturerID = BufferPtr[BYTE2];
+
+#if (XPAR_XISF_FLASH_FAMILY == INTEL)
+ /*
+ * For Intel the device code is the 4th byte of the JEDEC info.
+ */
+ InstancePtr->DeviceCode = BufferPtr[BYTE4];
+#else
+ /*
+ * For STM/Winbond/Spansion Serial Flash the device code is 3rd/4th
+ * byte of the JEDEC info. The Third Byte is Memory Type and the 4th
+ * byte represents the capacity.
+ */
+ InstancePtr->DeviceCode = (BufferPtr[BYTE3] << 8) | BufferPtr[BYTE4];
+#endif
+
+ /*
+ * Check for Intel/STM/Winbond/Spansion Serial Flash.
+ */
+ NumOfDevices = sizeof(IntelStmDevices) /
+ sizeof(IntelStmDeviceGeometry);
+
+ for(Index = 0; Index < NumOfDevices; Index++) {
+ if ((InstancePtr->DeviceCode ==
+ IntelStmDevices[Index].DeviceCode) &&
+ (ManufacturerID ==
+ IntelStmDevices[Index].ManufacturerID)) {
+ InstancePtr->ManufacturerID = IntelStmDevices[Index].ManufacturerID;
+ InstancePtr->BytesPerPage =
+ IntelStmDevices[Index].BytesPerPage;
+
+ /*
+ * This is number of pages per Sector.
+ */
+ InstancePtr->PagesPerBlock =
+ IntelStmDevices[Index].PagesPerSector;
+
+ InstancePtr->BlocksPerSector = 0;
+
+ InstancePtr->NumOfSectors =
+ IntelStmDevices[Index].NumOfSectors;
+
+ InstancePtr->IsReady = TRUE;
+ }
+ }
+
+ /*
+ * If the device is not supported, return Failure.
+ */
+ if (InstancePtr->IsReady != TRUE) {
+ return (int)(XST_FAILURE);
+ }
+
+ return (int)(XST_SUCCESS);
+}
+#endif /* (((XPAR_XISF_FLASH_FAMILY==INTEL) || (XPAR_XISF_FLASH_FAMILY==STM) \
+ || (XPAR_XISF_FLASH_FAMILY == SST) || \
+ (XPAR_XISF_FLASH_FAMILY == WINBOND) || \
+ (XPAR_XISF_FLASH_FAMILY == SPANSION)) && \
+ (!defined(XPAR_XISF_INTERFACE_PSQSPI)))*/
+
+#if (((XPAR_XISF_FLASH_FAMILY == WINBOND) || \
+ (XPAR_XISF_FLASH_FAMILY == SPANSION)) && \
+ defined(XPAR_XISF_INTERFACE_PSQSPI))
+/*****************************************************************************/
+/**
+*
+* This function initializes the instance structure with the device geometry of
+* the Spansion/Micron/Winbond Serial Flash if it is an Spansion/Micron/Winbond
+* device.
+*
+* @param InstancePtr is a pointer to the XIsf instance.
+* @param BufferPtr is a pointer to the memory where the device info of
+* the Serial Flash is present.
+*
+* @return - XST_SUCCESS if device information matches the JEDEC
+* information of Intel or Stm or Winbond Serial Flash.
+* - XST_FAILURE if the device information doesn't match with
+* Intel or Stm or Winbond Serial Flash.
+*
+* @note None
+*
+******************************************************************************/
+static int SpaMicWinFlashInitialize(XIsf *InstancePtr, u8 *BufferPtr)
+{
+ u32 Index;
+ u8 NumOfDevices;
+ u8 ManufacturerID;
+ unsigned int StartIndex;
+ u32 FlashMake;
+ u8 * WriteBfrPtr = InstancePtr->WriteBufPtr;
+ int Status;
+
+ /*
+ * Read ID in Auto mode.
+ */
+ WriteBfrPtr[BYTE1] = READ_ID;
+ WriteBfrPtr[BYTE2] = 0x23U; /* 3 dummy bytes */
+ WriteBfrPtr[BYTE3] = 0x08U;
+ WriteBfrPtr[BYTE4] = 0x09U;
+
+ Status = XIsf_Transfer(InstancePtr, WriteBfrPtr, BufferPtr,
+ RD_ID_SIZE);
+ if (Status != (int)(XST_SUCCESS)) {
+ return (int)(XST_FAILURE);
+ }
+
+ /*
+ * Deduce flash make
+ */
+ if(BufferPtr[1] == XISF_MANUFACTURER_ID_MICRON) {
+ FlashMake = XISF_MANUFACTURER_ID_MICRON;
+ StartIndex = MICRON_INDEX_START;
+ }
+ else if(BufferPtr[1] == XISF_MANUFACTURER_ID_SPANSION) {
+ FlashMake = XISF_MANUFACTURER_ID_SPANSION;
+ StartIndex = SPANSION_INDEX_START;
+ }
+ else if(BufferPtr[1] == XISF_MANUFACTURER_ID_WINBOND) {
+ FlashMake = XISF_MANUFACTURER_ID_WINBOND;
+ StartIndex = WINBOND_INDEX_START;
+ }
+ else{
+ FlashMake = 0;
+ StartIndex = 0;
+ }
+ /*
+ * If valid flash ID, then check connection mode & size and
+ * assign corresponding index in the Flash configuration table
+ */
+ if(((FlashMake == XISF_MANUFACTURER_ID_MICRON) ||
+ (FlashMake == XISF_MANUFACTURER_ID_SPANSION)||
+ (FlashMake == XISF_MANUFACTURER_ID_WINBOND)) &&
+ (BufferPtr[3] == XISF_MICRON_ID_BYTE2_128)) {
+ switch(InstancePtr->SpiInstPtr->Config.ConnectionMode)
+ {
+ case XISF_QSPIPS_CONNECTION_MODE_SINGLE:
+ XIsf_FCTIndex =
+ (u32)FLASH_CFG_TBL_SINGLE_128_SP +
+ (u32)StartIndex;
+ break;
+ case XISF_QSPIPS_CONNECTION_MODE_PARALLEL:
+ XIsf_FCTIndex =
+ (u32)FLASH_CFG_TBL_PARALLEL_128_SP +
+ (u32)StartIndex;
+ break;
+ case XISF_QSPIPS_CONNECTION_MODE_STACKED:
+ XIsf_FCTIndex =
+ (u32)FLASH_CFG_TBL_STACKED_128_SP +
+ (u32)StartIndex;
+ break;
+ default:
+ XIsf_FCTIndex = 0;
+ break;
+ }
+ }
+
+ /*
+ * 256 and 512Mbit supported only for Micron and Spansion,
+ * not Winbond
+ */
+ if(((FlashMake == XISF_MANUFACTURER_ID_MICRON) ||
+ (FlashMake == XISF_MANUFACTURER_ID_SPANSION)) &&
+ (BufferPtr[3] == XISF_MICRON_ID_BYTE2_256)) {
+ switch(InstancePtr->SpiInstPtr->Config.ConnectionMode)
+ {
+ case XISF_QSPIPS_CONNECTION_MODE_SINGLE:
+ XIsf_FCTIndex = FLASH_CFG_TBL_SINGLE_256_SP +
+ StartIndex;
+ break;
+ case XISF_QSPIPS_CONNECTION_MODE_PARALLEL:
+ XIsf_FCTIndex = FLASH_CFG_TBL_PARALLEL_256_SP +
+ StartIndex;
+ break;
+ case XISF_QSPIPS_CONNECTION_MODE_STACKED:
+ XIsf_FCTIndex = FLASH_CFG_TBL_STACKED_256_SP +
+ StartIndex;
+ break;
+ default:
+ XIsf_FCTIndex = 0;
+ break;
+ }
+ }
+
+ if(((FlashMake == XISF_MANUFACTURER_ID_MICRON) ||
+ (FlashMake == XISF_MANUFACTURER_ID_SPANSION)) &&
+ (BufferPtr[3] == XISF_MICRON_ID_BYTE2_512)) {
+
+ switch(InstancePtr->SpiInstPtr->Config.ConnectionMode)
+ {
+ case XISF_QSPIPS_CONNECTION_MODE_SINGLE:
+ XIsf_FCTIndex = FLASH_CFG_TBL_SINGLE_512_SP +
+ StartIndex;
+ break;
+ case XISF_QSPIPS_CONNECTION_MODE_PARALLEL:
+ XIsf_FCTIndex = FLASH_CFG_TBL_PARALLEL_512_SP +
+ StartIndex;
+ break;
+ case XISF_QSPIPS_CONNECTION_MODE_STACKED:
+ XIsf_FCTIndex = FLASH_CFG_TBL_STACKED_512_SP +
+ StartIndex;
+ break;
+ default:
+ XIsf_FCTIndex = 0;
+ break;
+ }
+ }
+
+ /*
+ * 1Gbit Single connection supported for Spansion.
+ * The ConnectionMode will indicate stacked as this part has 2 SS
+ * The device ID will indicate 512Mbit.
+ * This configuration is handled as the above 512Mbit stacked
+ * configuration.
+ */
+ /* 1Gbit single, parallel and stacked supported for Micron */
+ if((FlashMake == XISF_MANUFACTURER_ID_MICRON) &&
+ (BufferPtr[3] == XISF_MICRON_ID_BYTE2_1G)) {
+
+ switch(InstancePtr->SpiInstPtr->Config.ConnectionMode)
+ {
+ case XISF_QSPIPS_CONNECTION_MODE_SINGLE:
+ XIsf_FCTIndex = FLASH_CFG_TBL_SINGLE_1GB_MC;
+ break;
+ case XISF_QSPIPS_CONNECTION_MODE_PARALLEL:
+ XIsf_FCTIndex = FLASH_CFG_TBL_PARALLEL_1GB_MC;
+ break;
+ case XISF_QSPIPS_CONNECTION_MODE_STACKED:
+ XIsf_FCTIndex = FLASH_CFG_TBL_STACKED_1GB_MC;
+ break;
+ default:
+ XIsf_FCTIndex = 0;
+ break;
+ }
+ }
+
+ /*
+ * Populate the InstancePtr members with the appropriate values
+ * based on the XIsf_FCTIndex
+ */
+ InstancePtr->BytesPerPage =
+ (u16)(SpaMicWinDevices[XIsf_FCTIndex].PageSize);
+ InstancePtr->NumDie = SpaMicWinDevices[XIsf_FCTIndex].NumDie;
+ InstancePtr->DeviceIDMemSize =
+ SpaMicWinDevices[XIsf_FCTIndex].DeviceIDMemSize;
+ InstancePtr->ManufacturerID = FlashMake;
+ InstancePtr->SectorSize = SpaMicWinDevices[XIsf_FCTIndex].SectSize;
+ InstancePtr->NumSectors = SpaMicWinDevices[XIsf_FCTIndex].NumSect;
+ InstancePtr->IsReady = TRUE;
+
+ return (int)(XST_SUCCESS);
+}
+#endif /* (((XPAR_XISF_FLASH_FAMILY == WINBOND) || \
+ (XPAR_XISF_FLASH_FAMILY == SPANSION)) && \
+ defined(XPAR_XISF_INTERFACE_PSQSPI))*/
+
+/*****************************************************************************/
+/**
+* This functions translates the address based on the type of interconnection.
+* In case of stacked, this function asserts the corresponding slave select.
+*
+* @param QspiPtr is a pointer to XIsf_Iface instance to be worked on.
+* @param Address which is to be accessed (for erase, write or read)
+*
+* @return RealAddr is the translated address - for single it is unchanged
+* for stacked, the lower flash size is subtracted
+* for parallel the address is divided by 2.
+*
+* @note None.
+*
+******************************************************************************/
+u32 GetRealAddr(XIsf_Iface *QspiPtr, u32 Address)
+{
+ u32 LqspiCr;
+ u32 RealAddr = {0};
+#ifdef XPAR_XISF_INTERFACE_PSQSPI
+ switch(QspiPtr->Config.ConnectionMode) {
+ case XISF_QSPIPS_CONNECTION_MODE_SINGLE:
+ RealAddr = Address;
+ break;
+ case XISF_QSPIPS_CONNECTION_MODE_STACKED:
+ /*
+ * Get the current LQSPI Config reg value
+ */
+ LqspiCr = XQspiPs_GetLqspiConfigReg(QspiPtr);
+
+ /* Select lower or upper Flash based on sector address */
+ if(Address &
+ SpaMicWinDevices[XIsf_FCTIndex].FlashDeviceSize) {
+ /*
+ * Set selection to U_PAGE
+ */
+ XQspiPs_SetLqspiConfigReg(QspiPtr,
+ LqspiCr | XQSPIPS_LQSPI_CR_U_PAGE_MASK);
+
+ /*
+ * Subtract first flash size when accessing second
+ * flash.
+ */
+ RealAddr = Address &
+ (~SpaMicWinDevices[XIsf_FCTIndex].FlashDeviceSize);
+
+ }
+ else{
+ /*
+ * Set selection to L_PAGE
+ */
+ XQspiPs_SetLqspiConfigReg(QspiPtr,
+ LqspiCr & (~XQSPIPS_LQSPI_CR_U_PAGE_MASK));
+
+ RealAddr = Address;
+ }
+
+ /*
+ * Assert the Flash chip select.
+ */
+ (void)XQspiPs_SetSlaveSelect(QspiPtr);
+ break;
+ case XISF_QSPIPS_CONNECTION_MODE_PARALLEL:
+ /*
+ * The effective address in each flash is the actual
+ * address / 2
+ */
+ RealAddr = Address / 2;
+ break;
+ default:
+ /* RealAddr wont be assigned in this case */
+ break;
+
+ }
+#else
+ RealAddr = Address;
+#endif
+ return(RealAddr);
+}
+
+#ifdef XPAR_XISF_INTERFACE_PSQSPI
+/*****************************************************************************/
+/**
+* This functions selects the current bank
+*
+* @param InstancePtr is a pointer to the QSPI driver component to use.
+* @param BankSel is the bank to be selected in the flash device(s).
+*
+* @return XST_SUCCESS if bank selected, otherwise XST_FAILURE.
+*
+* @note None.
+*
+******************************************************************************/
+int SendBankSelect(XIsf *InstancePtr, u32 BankSel)
+{
+ #define EXTADD_REG_WR 0xC5U
+ #define EXTADD_REG_RD 0xC8U
+ #define BANK_REG_WR 0x17U
+ #define BANK_SEL_SIZE 2U /**< BRWR or EARWR command +
+ * 1 byte bank value */
+ u8 WriteBuffer[5] = {0};
+ u8* NULLPtr= NULL;
+ u8 WriteEnableCmdBuf = { WRITE_ENABLE_CMD };
+ u32 FlashMake = InstancePtr->ManufacturerID;
+ int Status;
+ /*
+ * Bank select commands for Micron and Spansion are different
+ */
+ if(FlashMake == XISF_MANUFACTURER_ID_MICRON) {
+
+ Xil_AssertNonvoid(NULLPtr == NULL);
+
+ /*
+ * For Micron command WREN should be sent first
+ * except for some specific feature set
+ */
+ Status = XIsf_Transfer(InstancePtr,
+ &WriteEnableCmdBuf, NULLPtr,
+ (u32)sizeof(WriteEnableCmdBuf));
+
+ if(Status != (int)XST_SUCCESS){
+ return (int)XST_FAILURE;
+ }
+
+ WriteBuffer[BYTE1] = EXTADD_REG_WR;
+ WriteBuffer[BYTE2] = (u8)BankSel;
+
+ Xil_AssertNonvoid(NULLPtr == NULL);
+
+ /*
+ * Send the Extended address register write command
+ * written, no receive buffer required
+ */
+ Status = XIsf_Transfer(InstancePtr, WriteBuffer, NULLPtr,
+ BANK_SEL_SIZE);
+
+ if(Status != (int)XST_SUCCESS){
+ return (int)XST_FAILURE;
+ }
+ }
+ if(FlashMake == XISF_MANUFACTURER_ID_SPANSION) {
+ WriteBuffer[BYTE1] = BANK_REG_WR;
+ WriteBuffer[BYTE2] = (u8)BankSel;
+
+ Xil_AssertNonvoid(NULLPtr == NULL);
+
+ /*
+ * Send the Extended address register write command
+ * written, no receive buffer required
+ */
+ Status = XIsf_Transfer(InstancePtr, WriteBuffer, NULLPtr,
+ BANK_SEL_SIZE);
+
+ if(Status != (int)XST_SUCCESS){
+ return (int)XST_FAILURE;
+ }
+ }
+
+ /* Winbond can be added here */
+
+ return (int)(XST_SUCCESS);
+}
+#endif
+
+/******************************************************************************
+*
+* This function is to set the Status Handler when an interrupt is registered
+*
+* @param InstancePtr is a pointer to the XIsf Instance.
+* @param QspiInstancePtr is a pointer to the XIsf_Iface instance
+* to be worked on.
+* @param XilIsf_Handler is the status handler for the application.
+*
+* @return None
+*
+* @note None.
+*
+******************************************************************************/
+void XIsf_SetStatusHandler(XIsf *InstancePtr, XIsf_Iface *XIfaceInstancePtr,
+ XIsf_StatusHandler XilIsf_Handler)
+{
+ Xil_AssertVoid(InstancePtr != NULL);
+ Xil_AssertVoid(XIfaceInstancePtr != NULL);
+ Xil_AssertVoid(XilIsf_Handler != NULL);
+
+ /*
+ * Setup the handler for the QSPI that will be called from the
+ * interrupt context when an QSPI status occurs, specify a pointer to
+ * the QSPI driver instance as the callback reference so the handler
+ * is able to access the instance data
+ */
+#ifdef XPAR_XISF_INTERFACE_PSQSPI
+ XQspiPs_SetStatusHandler(XIfaceInstancePtr, XIfaceInstancePtr,
+ (XQspiPs_StatusHandler) XIsf_IfaceHandler);
+#elif XPAR_XISF_INTERFACE_PSSPI
+ XSpiPs_SetStatusHandler(XIfaceInstancePtr, XIfaceInstancePtr,
+ (XSpiPs_StatusHandler) XIsf_IfaceHandler);
+#elif XPAR_XISF_INTERFACE_AXISPI
+ XSpi_SetStatusHandler(XIfaceInstancePtr, XIfaceInstancePtr,
+ (XSpi_StatusHandler) XIsf_IfaceHandler);
+#endif
+
+ InstancePtr->StatusHandler = XilIsf_Handler;
+}
+
+
+
+/******************************************************************************
+*
+* 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
+* completes or an error occurs.
+*
+* This handler provides an example of how to handle QSPI interrupts but is
+* application specific.
+*
+* @param CallBackRef is a reference passed to the handler.
+* @param StatusEvent is the status of the QSPI .
+* @param ByteCount is the number of bytes transferred.
+*
+* @return None
+*
+* @note None.
+*
+******************************************************************************/
+void XIsf_IfaceHandler(void *CallBackRef, u32 StatusEvent,
+ unsigned int ByteCount)
+{
+
+ Xil_AssertVoid(CallBackRef != NULL);
+
+ XIsf_TransferInProgress = FALSE;
+
+ XIsf_StatusEventInfo = StatusEvent;
+
+ XIsf_ByteCountInfo = ByteCount;
+
+}
diff --git a/lib/sw_services/xilisf/src/xilisf_erase.c b/lib/sw_services/xilisf/src/xilisf_erase.c
new file mode 100644
index 00000000..c2e09970
--- /dev/null
+++ b/lib/sw_services/xilisf/src/xilisf_erase.c
@@ -0,0 +1,597 @@
+/******************************************************************************
+*
+* Copyright (C) 2012 - 2015 Xilinx, Inc. All rights reserved.
+*
+* Permission is hereby granted, free of charge, to any person obtaining a copy
+* of this software and associated documentation files (the "Software"), to deal
+* in the Software without restriction, including without limitation the rights
+* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+* copies of the Software, and to permit persons to whom the Software is
+* furnished to do so, subject to the following conditions:
+*
+* The above copyright notice and this permission notice shall be included in
+* all copies or substantial portions of the Software.
+*
+* Use of the Software is limited solely to applications:
+* (a) running on a Xilinx device, or
+* (b) that interact with a Xilinx device through a bus or interconnect.
+*
+* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+* XILINX BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
+* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+* SOFTWARE.
+*
+* Except as contained in this notice, the name of the Xilinx shall not be used
+* in advertising or otherwise to promote the sale, use or other dealings in
+* this Software without prior written authorization from Xilinx.
+*
+******************************************************************************/
+/*****************************************************************************/
+/**
+*
+* @file xilisf_erase.c
+*
+* This file contains the library functions to Erase the Serial Flash.
+* Refer xilisf.h for a detailed description.
+*
+*
+*
+* MODIFICATION HISTORY:
+*
+* Ver Who Date Changes
+* ----- ------- -------- -----------------------------------------------
+* 1.00a ksu/sdm 03/03/08 First release
+* 2.01a sdm 01/04/10 Added Support for Winbond W25QXX/W25XX devices
+* 2.04a sdm 08/17/10 Updated to support Numonyx (N25QXX) and Spansion
+* flash memories
+* 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()
+* 5.2 asa 05/12/15 Added support for Micron (N25Q256A) flash part
+* which supports 4 byte addressing.
+*
+*
+******************************************************************************/
+
+/***************************** Include Files *********************************/
+
+#include "include/xilisf.h"
+
+/************************** Constant Definitions *****************************/
+#define SIXTEENMB 0x1000000 /**< Sixteen MB */
+/**************************** Type Definitions *******************************/
+
+/***************** Macros (Inline Functions) Definitions *********************/
+
+/************************** Function Prototypes ******************************/
+
+extern int XIsf_Transfer(XIsf *InstancePtr, u8 *WritePtr, u8* ReadPtr,
+ u32 ByteCount);
+extern u32 GetRealAddr(XIsf_Iface *QspiPtr, u32 Address);
+#ifdef XPAR_XISF_INTERFACE_PSQSPI
+extern int SendBankSelect(XIsf *InstancePtr, u32 BankSel);
+#endif
+static int 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 ******************************/
+
+
+/*****************************************************************************/
+/**
+*
+* This API erases the contents of the specified memory in the Serial Flash.
+*
+* @param InstancePtr is a pointer to the XIsf instance.
+* @param Operation is the type of Erase operation to be performed on the
+* Serial Flash.
+* The different operations are
+* - XISF_PAGE_ERASE: Page Erase
+* - XISF_BLOCK_ERASE: Block Erase
+* - XISF_SECTOR_ERASE: Sector Erase
+ - XISF_BULK_ERASE: Bulk Erase
+* @param Address is the address of the Page/Block/Sector to be erased.
+* The address can be either Page address, Block address or Sector
+* address based on the Erase operation to be performed.
+*
+* @return XST_SUCCESS if successful else XST_FAILURE.
+*
+* @note
+* - 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 XIsf_Erase()
+* API.
+* - 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
+* operations.
+*
+******************************************************************************/
+int XIsf_Erase(XIsf *InstancePtr, XIsf_EraseOperation Operation, u32 Address)
+{
+ int Status = (int)(XST_FAILURE);
+ u8 Mode;
+
+ if (InstancePtr == NULL) {
+ return (int)(XST_FAILURE);
+ }
+
+ if (InstancePtr->IsReady != TRUE) {
+ return (int)(XST_FAILURE);
+ }
+
+ switch (Operation) {
+
+ case XISF_PAGE_ERASE:
+ Status = PageErase(InstancePtr, Address);
+ break;
+
+ case XISF_BLOCK_ERASE:
+ Status = BlockErase(InstancePtr, Address);
+ break;
+
+ case XISF_SECTOR_ERASE:
+ Status = SectorErase(InstancePtr, Address);
+ break;
+
+ case XISF_BULK_ERASE:
+ Status = BulkErase(InstancePtr);
+ break;
+
+ default:
+ break;
+ }
+
+
+ /*
+ * Get the Transfer Mode
+ */
+ Mode = XIsf_GetTransferMode(InstancePtr);
+
+ if(Mode == XISF_INTERRUPT_MODE){
+ InstancePtr->StatusHandler(InstancePtr,
+ XIsf_StatusEventInfo, XIsf_ByteCountInfo);
+ }
+
+ return Status;
+}
+
+
+/*****************************************************************************/
+/**
+*
+* This function 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 Page to be erased. This can be any
+* address in the Page to be erased. The Byte address values in
+* this address are ignored.
+*
+* @return XST_SUCCESS if successful else XST_FAILURE.
+*
+* @note
+* - The erased bytes will read as 0xFF.
+* - This operation is only supported for Atmel Serial Flash.
+*
+******************************************************************************/
+static int PageErase(XIsf *InstancePtr, u32 Address)
+{
+ 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;
+ InstancePtr->WriteBufPtr[BYTE2] = (u8) (Address >> XISF_ADDR_SHIFT16);
+ InstancePtr->WriteBufPtr[BYTE3] = (u8) (Address >> XISF_ADDR_SHIFT8);
+ InstancePtr->WriteBufPtr[BYTE4] = (u8) XISF_DUMMYBYTE;
+
+ /*
+ * Initiate the Transfer.
+ */
+ Status = XIsf_Transfer(InstancePtr, InstancePtr->WriteBufPtr,
+ NULL, XISF_CMD_SEND_EXTRA_BYTES);
+ if (Status != (int)(XST_SUCCESS)) {
+ return (int)(XST_FAILURE);
+ }
+#endif /* (XPAR_XISF_FLASH_FAMILY == ATMEL) */
+
+ return Status;
+}
+
+/*****************************************************************************/
+/**
+*
+* This function erases the contents of the specified Block in the Serial Flash.
+*
+* @param InstancePtr is a pointer to the XIsf instance.
+* @param Address is the address of the Block to be erased. This can be
+* any address in the Block to be erased. The Page/Byte address
+* values in this address are ignored.
+*
+* @return XST_SUCCESS if successful else XST_FAILURE.
+*
+* @note
+* - The erased bytes will read as 0xFF.
+* - This operation is supported for Atmel, Intel, Winbond,
+* Numonyx (N25QXX), and Spansion Serial Flash.
+*
+******************************************************************************/
+static int BlockErase(XIsf *InstancePtr, u32 Address)
+{
+ int Status = (int)(XST_FAILURE);
+
+ 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;
+
+#else
+ InstancePtr->WriteBufPtr[BYTE1] = XISF_CMD_PARAM_BLOCK_ERASE;
+
+#endif /* (XPAR_XISF_FLASH_FAMILY == ATMEL) */
+
+ InstancePtr->WriteBufPtr[BYTE2] = (u8) (Address >> XISF_ADDR_SHIFT16);
+ InstancePtr->WriteBufPtr[BYTE3] = (u8) (Address >> XISF_ADDR_SHIFT8);
+ InstancePtr->WriteBufPtr[BYTE4] = (u8) XISF_DUMMYBYTE;
+
+ /*
+ * Initiate the Transfer.
+ */
+ Status = XIsf_Transfer(InstancePtr, InstancePtr->WriteBufPtr,
+ NULL, XISF_CMD_SEND_EXTRA_BYTES);
+ if (Status != (int)(XST_SUCCESS)) {
+ return (int)(XST_FAILURE);
+ }
+#endif /* ((XPAR_XISF_FLASH_FAMILY==ATMEL)||(XPAR_XISF_FLASH_FAMILY==INTEL)) */
+
+ return Status;
+}
+
+/*****************************************************************************/
+/**
+*
+* 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
+* any address in the Sector to be erased.
+* The Block/Page/Byte address values in this address are ignored.
+*
+* @return XST_SUCCESS if successful else XST_FAILURE.
+*
+* @note
+* - The erased bytes will read as 0xFF.
+* - This operation is supported for Atmel, Intel, STM, Winbond
+* and Spansion Serial Flash.
+*
+******************************************************************************/
+static int SectorErase(XIsf *InstancePtr, u32 Address)
+{
+ 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
+
+ Xil_AssertNonvoid(NULLPtr == NULL);
+
+ /*
+ * 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
+#if ((XPAR_XISF_FLASH_FAMILY == SPANSION) && \
+ (!defined(XPAR_XISF_INTERFACE_PSQSPI)))
+ if (InstancePtr->FourByteAddrMode == TRUE) {
+ InstancePtr->WriteBufPtr[BYTE1] = XISF_CMD_SECTOR_ERASE;
+ InstancePtr->WriteBufPtr[BYTE2] = (u8) (RealAddr >> XISF_ADDR_SHIFT24);
+ InstancePtr->WriteBufPtr[BYTE3] = (u8) (RealAddr >> XISF_ADDR_SHIFT16);
+ InstancePtr->WriteBufPtr[BYTE4] = (u8) (RealAddr >> XISF_ADDR_SHIFT8);
+ InstancePtr->WriteBufPtr[BYTE5] = (u8) (RealAddr);
+ } else {
+#endif
+ InstancePtr->WriteBufPtr[BYTE1] = XISF_CMD_SECTOR_ERASE;
+ InstancePtr->WriteBufPtr[BYTE2] = (u8) (RealAddr >> XISF_ADDR_SHIFT16);
+ InstancePtr->WriteBufPtr[BYTE3] = (u8) (RealAddr >> XISF_ADDR_SHIFT8);
+ InstancePtr->WriteBufPtr[BYTE4] = (u8) (RealAddr);
+#if ((XPAR_XISF_FLASH_FAMILY == SPANSION) && \
+ (!defined(XPAR_XISF_INTERFACE_PSQSPI)))
+ }
+#endif
+
+#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
+ if (InstancePtr->FourByteAddrMode == TRUE) {
+ Status = XIsf_Transfer(InstancePtr, InstancePtr->WriteBufPtr,
+ NULLPtr, XISF_CMD_SEND_EXTRA_BYTES_4BYTE_MODE);
+ } else {
+ Status = XIsf_Transfer(InstancePtr, InstancePtr->WriteBufPtr,
+ NULLPtr, XISF_CMD_SEND_EXTRA_BYTES);
+ }
+ if (Status != (int)XST_SUCCESS) {
+ return (int)XST_FAILURE;
+ }
+
+#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;
+}
+
+/*****************************************************************************/
+/**
+*
+* This function erases the content of an entire Serial Flash.
+*
+* @param InstancePtr is a pointer to the XIsf instance.
+*
+* @return XST_SUCCESS if successful else XST_FAILURE.
+*
+* @note
+* - The erased bytes will read as 0xFF.
+* - This operation is supported for Intel, STM, Winbond,
+* Spansion and SST Serial Flashes.
+*
+******************************************************************************/
+static int BulkErase(XIsf *InstancePtr)
+{
+ 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))
+
+#ifdef XPAR_XISF_INTERFACE_PSQSPI
+ /*
+ * If the number of die is greater than 1 call die erase
+ */
+ 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) ||
+ (XPAR_XISF_FLASH_FAMILY == SPANSION)) */
+
+ 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
diff --git a/lib/sw_services/xilisf/src/xilisf_read.c b/lib/sw_services/xilisf/src/xilisf_read.c
new file mode 100644
index 00000000..ae999aee
--- /dev/null
+++ b/lib/sw_services/xilisf/src/xilisf_read.c
@@ -0,0 +1,978 @@
+/******************************************************************************
+*
+* Copyright (C) 2012 - 2015 Xilinx, Inc. All rights reserved.
+*
+* Permission is hereby granted, free of charge, to any person obtaining a copy
+* of this software and associated documentation files (the "Software"), to deal
+* in the Software without restriction, including without limitation the rights
+* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+* copies of the Software, and to permit persons to whom the Software is
+* furnished to do so, subject to the following conditions:
+*
+* The above copyright notice and this permission notice shall be included in
+* all copies or substantial portions of the Software.
+*
+* Use of the Software is limited solely to applications:
+* (a) running on a Xilinx device, or
+* (b) that interact with a Xilinx device through a bus or interconnect.
+*
+* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+* XILINX BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
+* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+* SOFTWARE.
+*
+* Except as contained in this notice, the name of the Xilinx shall not be used
+* in advertising or otherwise to promote the sale, use or other dealings in
+* this Software without prior written authorization from Xilinx.
+*
+******************************************************************************/
+/*****************************************************************************/
+/**
+*
+* @file xilisf_read.c
+*
+* This file contains the library functions to read data from the Serial Flash
+* devices. Refer xilisf.h for detailed description.
+*
+*
+*
+* MODIFICATION HISTORY:
+*
+* Ver Who Date Changes
+* ----- ------- -------- -----------------------------------------------
+* 1.00a ksu/sdm 03/03/08 First release
+* 2.01a sdm 01/04/10 Added Support for Winbond W25QXX/W25XX devices
+* 2.04a sdm 08/17/10 Updated to support Numonyx (N25QXX) and Spansion
+* flash memories
+* 5.0 sb 08/05/14 Updated support for > 128 MB flash for PSQSPI
+* interface.
+* Changed API:
+* ReadData()
+* FastReadData()
+*
+* 5.2 asa 05/12/15 Added support for Micron (N25Q256A) flash part
+* which supports 4 byte addressing.
+*
+*
+******************************************************************************/
+
+/***************************** Include Files *********************************/
+
+#include "include/xilisf.h"
+
+/************************** Constant Definitions *****************************/
+
+#define FAST_READ_NUM_DUMMY_BYTES 1
+#define SIXTEENMB 0x1000000 /**< Sixteen MB */
+#define BANKMASK 0xF000000 /**< Bank mask */
+
+/**************************** Type Definitions *******************************/
+
+/***************** Macros (Inline Functions) Definitions *********************/
+
+/************************** Function Prototypes ******************************/
+
+extern int XIsf_Transfer(XIsf *InstancePtr, u8 *WritePtr, u8* ReadPtr,
+ u32 ByteCount);
+extern u32 GetRealAddr(XIsf_Iface *QspiPtr, u32 Address);
+
+#ifdef XPAR_XISF_INTERFACE_PSQSPI
+extern int SendBankSelect(XIsf *InstancePtr, u32 BankSel);
+#endif
+
+static int ReadData(XIsf *InstancePtr, u32 Address, u8 *ReadPtr,
+ u32 ByteCount);
+static int FastReadData(XIsf *InstancePtr, u8 Command, u32 Address,
+ u8 *ReadPtr,
+ u32 ByteCount, int NumDummyBytes);
+static int FlashToBufTransfer(XIsf *InstancePtr, u8 BufferNum, u32 Address);
+static int BufferRead(XIsf *InstancePtr, u8 BufferNum, u8 *ReadPtr,
+ u32 ByteOffset, u32 NumBytes);
+static int FastBufferRead(XIsf *InstancePtr, u8 BufferNum, u8 *ReadPtr,
+ u32 ByteOffset, u32 NumBytes);
+static int ReadOTPData(XIsf *InstancePtr, u32 Address, u8 *ReadPtr,
+ u32 ByteCount);
+
+/************************** Variable Definitions *****************************/
+extern u32 XIsf_StatusEventInfo;
+extern unsigned int XIsf_ByteCountInfo;
+/************************** Function Definitions ******************************/
+
+/*****************************************************************************/
+/**
+*
+* This API reads the data from the Serial Flash.
+*
+* @param InstancePtr is a pointer to the XIsf instance.
+* @param Operation is the type of the read operation to be performed on
+* the Serial Flash.
+* The different operations are
+ - XISF_READ: Normal Read
+* - XISF_FAST_READ: Fast Read
+* - XISF_PAGE_TO_BUF_TRANS: Page to Buffer Transfer
+* - XISF_BUFFER_READ: Buffer Read
+* - XISF_FAST_BUFFER_READ: Fast Buffer Read
+* - XISF_OTP_READ: One Time Programmable Area (OTP) Read
+* - XISF_DUAL_OP_FAST_READ: Dual Output Fast Read
+* - XISF_DUAL_IO_FAST_READ: Dual Input/Output Fast Read
+* - XISF_QUAD_OP_FAST_READ: Quad Output Fast Read
+* - XISF_QUAD_IO_FAST_READ: Quad Input/Output Fast Read
+* @param OpParamPtr is the pointer to structure variable which contains
+* operational parameter of specified Operation. This parameter
+* type is dependant on the type of Operation to be performed.
+*
+* - Normal Read (XISF_READ), Fast Read (XISF_FAST_READ),
+* One Time Programmable Area Read(XISF_OTP_READ), Dual Output
+* Fast Read (XISF_CMD_DUAL_OP_FAST_READ), Dual Input/Output
+* Fast Read (XISF_CMD_DUAL_IO_FAST_READ), Quad Output Fast Read
+* (XISF_CMD_QUAD_OP_FAST_READ) and Quad Input/Output Fast Read
+* (XISF_CMD_QUAD_IO_FAST_READ):
+* The OpParamPtr must be of type struct XIsf_ReadParam.
+* OpParamPtr->Address is start address in the Serial Flash.
+* OpParamPtr->ReadPtr is a pointer to the memory where the data
+* read from the Serial Flash is stored.
+* OpParamPtr->NumBytes is number of bytes to read.
+* OpParamPtr->NumDummyBytes is the number of dummy bytes to be
+* transmitted for the Read command. This parameter is only used
+* in case of Dual and Quad reads.
+* Normal Read and Fast Read operations are supported for Atmel,
+* Intel, STM, Winbond and Spansion Serial Flash.
+* Dual and quad reads are supported for Winbond (W25QXX), Numonyx
+* (N25QXX) and Spansion (S25FL129) quad flash.
+* OTP Read operation is only supported in Intel Serial Flash.
+*
+* - Page To Buffer Transfer (XISF_PAGE_TO_BUF_TRANS):
+* The OpParamPtr must be of type struct
+* XIsf_FlashToBufTransferParam .
+* OpParamPtr->BufferNum specifies the internal SRAM Buffer of
+* the Serial Flash. The valid values are XISF_PAGE_BUFFER1
+* or XISF_PAGE_BUFFER2. XISF_PAGE_BUFFER2 is not valid in case
+* of AT45DB011D Flash as it contains a single buffer.
+* OpParamPtr->Address is start address in the Serial Flash.
+* This operation is only supported in Atmel Serial Flash.
+*
+* - Buffer Read (XISF_BUFFER_READ) and Fast Buffer Read
+* (XISF_FAST_BUFFER_READ):
+* The OpParamPtr must be of type struct XIsf_BufferReadParam.
+* OpParamPtr->BufferNum specifies the internal SRAM Buffer of
+* the Serial Flash. The valid values are XISF_PAGE_BUFFER1
+* or XISF_PAGE_BUFFER2. XISF_PAGE_BUFFER2 is not valid in case of
+* AT45DB011D Flash as it contains a single buffer.
+* OpParamPtr->ReadPtr is pointer to the memory where data read
+* from the SRAM buffer is to be stored.
+* OpParamPtr->ByteOffset is byte offset in the SRAM buffer from
+* where the first byte is read.
+* OpParamPtr->NumBytes is the number of bytes to be read from the
+* Buffer.
+* These operations are supported only in Atmel Serial Flash.
+*
+* @return XST_SUCCESS if successful else XST_FAILURE.
+*
+* @note
+* - Application must fill the structure elements of the third
+* argument and pass its pointer by type casting it with void
+* pointer.
+* - The valid data is available from the fourth location pointed
+* to by the ReadPtr for Normal Read and Buffer Read operations.
+* - The valid data is available from fifth location pointed to
+* by the ReadPtr for Fast Read, Fast Buffer Read and OTP Read
+* operations.
+* - The valid data is available from the (4 + NumDummyBytes)th
+* location pointed to by ReadPtr for Dual/Quad Read operations.
+*
+******************************************************************************/
+int XIsf_Read(XIsf *InstancePtr, XIsf_ReadOperation Operation,
+ void *OpParamPtr)
+{
+ int Status = (int)(XST_FAILURE);
+ u8 Mode;
+ XIsf_ReadParam *ReadParamPtr;
+ XIsf_FlashToBufTransferParam *FlashToBufTransferParamPtr;
+ XIsf_BufferReadParam *BufferReadParamPtr;
+
+ if (InstancePtr == NULL) {
+ return (int)(XST_FAILURE);
+ }
+
+ if (InstancePtr->IsReady != TRUE) {
+ return (int)(XST_FAILURE);
+ }
+
+ if (NULL == OpParamPtr) {
+ return (int)(XST_FAILURE);
+ }
+
+ switch (Operation) {
+ case XISF_READ:
+ ReadParamPtr = (XIsf_ReadParam*) OpParamPtr;
+ Status = ReadData(InstancePtr,
+ ReadParamPtr->Address,
+ ReadParamPtr->ReadPtr,
+ ReadParamPtr->NumBytes);
+ break;
+
+ case XISF_FAST_READ:
+ ReadParamPtr = (XIsf_ReadParam*)(void *) OpParamPtr;
+ Xil_AssertNonvoid(ReadParamPtr != NULL);
+ Status = FastReadData(InstancePtr,
+ XISF_CMD_FAST_READ,
+ ReadParamPtr->Address,
+ ReadParamPtr->ReadPtr,
+ ReadParamPtr->NumBytes,
+ ReadParamPtr->NumDummyBytes);
+ break;
+
+ case XISF_PAGE_TO_BUF_TRANS:
+ FlashToBufTransferParamPtr =
+ (XIsf_FlashToBufTransferParam*)(void *) OpParamPtr;
+ Xil_AssertNonvoid(FlashToBufTransferParamPtr != NULL);
+ Status = FlashToBufTransfer(InstancePtr,
+ FlashToBufTransferParamPtr->BufferNum,
+ FlashToBufTransferParamPtr->Address);
+ break;
+
+ case XISF_BUFFER_READ:
+ BufferReadParamPtr =
+ (XIsf_BufferReadParam*)(void *) OpParamPtr;
+ Xil_AssertNonvoid(BufferReadParamPtr != NULL);
+ Status = BufferRead(InstancePtr,
+ BufferReadParamPtr->BufferNum,
+ BufferReadParamPtr->ReadPtr,
+ BufferReadParamPtr->ByteOffset,
+ BufferReadParamPtr->NumBytes);
+ break;
+
+ case XISF_FAST_BUFFER_READ:
+ BufferReadParamPtr =
+ (XIsf_BufferReadParam*)(void *) OpParamPtr;
+ Xil_AssertNonvoid(BufferReadParamPtr != NULL);
+ Status = FastBufferRead(InstancePtr,
+ BufferReadParamPtr->BufferNum,
+ BufferReadParamPtr->ReadPtr,
+ BufferReadParamPtr->ByteOffset,
+ BufferReadParamPtr->NumBytes);
+ break;
+
+ case XISF_OTP_READ:
+ ReadParamPtr = (XIsf_ReadParam*)(void *) OpParamPtr;
+ Xil_AssertNonvoid(ReadParamPtr != NULL);
+ Status = ReadOTPData(InstancePtr,
+ ReadParamPtr->Address,
+ ReadParamPtr->ReadPtr,
+ ReadParamPtr->NumBytes);
+ break;
+
+#if ((XPAR_XISF_FLASH_FAMILY == WINBOND) || (XPAR_XISF_FLASH_FAMILY == STM) \
+ || (XPAR_XISF_FLASH_FAMILY == SPANSION))
+ case XISF_DUAL_OP_FAST_READ:
+ ReadParamPtr = (XIsf_ReadParam*)(void *) OpParamPtr;
+ Xil_AssertNonvoid(ReadParamPtr != NULL);
+ Status = FastReadData(InstancePtr,
+ XISF_CMD_DUAL_OP_FAST_READ,
+ ReadParamPtr->Address,
+ ReadParamPtr->ReadPtr,
+ ReadParamPtr->NumBytes,
+ ReadParamPtr->NumDummyBytes);
+ break;
+
+ case XISF_DUAL_IO_FAST_READ:
+ ReadParamPtr = (XIsf_ReadParam*)(void *) OpParamPtr;
+ Xil_AssertNonvoid(ReadParamPtr != NULL);
+ Status = FastReadData(InstancePtr,
+ XISF_CMD_DUAL_IO_FAST_READ,
+ ReadParamPtr->Address,
+ ReadParamPtr->ReadPtr,
+ ReadParamPtr->NumBytes,
+ ReadParamPtr->NumDummyBytes);
+ break;
+
+ case XISF_QUAD_OP_FAST_READ:
+ ReadParamPtr = (XIsf_ReadParam*)(void *) OpParamPtr;
+ Xil_AssertNonvoid(ReadParamPtr != NULL);
+ Status = FastReadData(InstancePtr,
+ XISF_CMD_QUAD_OP_FAST_READ,
+ ReadParamPtr->Address,
+ ReadParamPtr->ReadPtr,
+ ReadParamPtr->NumBytes,
+ ReadParamPtr->NumDummyBytes);
+ break;
+
+ case XISF_QUAD_IO_FAST_READ:
+ ReadParamPtr = (XIsf_ReadParam*)(void *) OpParamPtr;
+ Xil_AssertNonvoid(ReadParamPtr != NULL);
+ Status = FastReadData(InstancePtr,
+ XISF_CMD_QUAD_IO_FAST_READ,
+ ReadParamPtr->Address,
+ ReadParamPtr->ReadPtr,
+ ReadParamPtr->NumBytes,
+ ReadParamPtr->NumDummyBytes);
+ break;
+#endif /*((XPAR_XISF_FLASH_FAMILY == WINBOND) ||
+ (XPAR_XISF_FLASH_FAMILY == STM) ||
+ (XPAR_XISF_FLASH_FAMILY == SPANSION))*/
+
+ default:
+ break;
+ }
+
+ /*
+ * Get the Transfer Mode
+ */
+ Mode = XIsf_GetTransferMode(InstancePtr);
+
+ if(Mode == XISF_INTERRUPT_MODE){
+ InstancePtr->StatusHandler(InstancePtr,
+ XIsf_StatusEventInfo, XIsf_ByteCountInfo);
+ }
+
+ return Status;
+}
+
+/*****************************************************************************/
+/**
+*
+* This function reads data from the Serial Flash.
+*
+* @param InstancePtr is a pointer to the XIsf instance.
+* @param Address is the starting address in the Serial Flash from where
+* the data is to be read.
+* @param ReadPtr is a pointer to the memory where the data read from
+* the Serial Flash is stored.
+* @param ByteCount is the number of bytes to be read from the Serial
+* Flash.
+*
+* @return XST_SUCCESS if successful else XST_FAILURE.
+*
+* @note
+* - This operation is supported for Atmel, Intel, STM, Winbond
+* and Spansion Serial Flash.
+* - Minimum of one byte and a maximum of an entire Serial Flash
+* Array can be read.
+* - The valid data is available from the fourth location pointed
+* to by the ReadPtr.
+*
+******************************************************************************/
+static int ReadData(XIsf *InstancePtr, u32 Address, u8 *ReadPtr, u32 ByteCount)
+{
+ u8 Mode;
+ u32 BankSel;
+ u32 RealAddr;
+ int Status;
+ u32 RealByteCnt;
+ u32 BufferIndex;
+ u8 ShiftSize;
+ u32 TotalByteCnt = ByteCount;
+ u32 LocalByteCnt = ByteCount;
+ u32 LocalAddress = Address;
+ u8 WriteBuffer[10] = {0};
+ if (LocalByteCnt <= 0 ) {
+ return (int)XST_FAILURE;
+ }
+
+ if (ReadPtr == NULL) {
+ return (int)XST_FAILURE;
+ }
+
+ while(((s32)(LocalByteCnt)) > 0) {
+
+ /*
+ * Translate address based on type of connection
+ * If stacked assert the slave select based on address
+ */
+ RealAddr = GetRealAddr(InstancePtr->SpiInstPtr, LocalAddress);
+
+#ifdef XPAR_XISF_INTERFACE_PSQSPI
+ if(InstancePtr->DeviceIDMemSize > 0x18U) {
+
+ /*
+ * Get the Transfer Mode
+ */
+ Mode = XIsf_GetTransferMode(InstancePtr);
+
+ /*
+ * Seting the transfer mode to Polled Mode before
+ * performing the Bank Select operation.
+ */
+ XIsf_SetTransferMode(InstancePtr, XISF_POLLING_MODE);
+
+ BankSel = RealAddr/SIXTEENMB;
+
+ (void)SendBankSelect(InstancePtr, BankSel);
+
+ /*
+ * Restoring the transfer mode back
+ */
+ XIsf_SetTransferMode(InstancePtr, Mode);
+ }
+
+ /*
+ * If data to be read spans beyond the current bank, then
+ * calculate RealByteCnt in current bank. Else
+ * RealByteCnt is the same as ByteCount
+ */
+ if((RealAddr & BANKMASK) != ((RealAddr+LocalByteCnt) & BANKMASK)) {
+ RealByteCnt = ((RealAddr & BANKMASK) + SIXTEENMB) - RealAddr;
+ }
+ else {
+#endif
+ RealByteCnt = LocalByteCnt;
+
+#ifdef XPAR_XISF_INTERFACE_PSQSPI
+ }
+#endif
+#if ((XPAR_XISF_FLASH_FAMILY == SPANSION) && \
+ (!defined(XPAR_XISF_INTERFACE_PSQSPI)))
+ if (InstancePtr->FourByteAddrMode == TRUE) {
+ WriteBuffer[BYTE1] = XISF_CMD_RANDOM_READ_4BYTE;
+ WriteBuffer[BYTE2] = (u8) (RealAddr >> XISF_ADDR_SHIFT24);
+ WriteBuffer[BYTE3] = (u8) (RealAddr >> XISF_ADDR_SHIFT16);
+ WriteBuffer[BYTE4] = (u8) (RealAddr >> XISF_ADDR_SHIFT8);
+ WriteBuffer[BYTE5] = (u8) (RealAddr);
+ } else {
+#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);
+#if ((XPAR_XISF_FLASH_FAMILY == SPANSION) && \
+ (!defined(XPAR_XISF_INTERFACE_PSQSPI)))
+ }
+#endif
+ if (InstancePtr->FourByteAddrMode == TRUE) {
+ Status = XIsf_Transfer(InstancePtr, WriteBuffer,
+ &(ReadPtr[TotalByteCnt - LocalByteCnt]),
+ RealByteCnt + XISF_CMD_SEND_EXTRA_BYTES_4BYTE_MODE);
+ } else {
+ Status = XIsf_Transfer(InstancePtr, WriteBuffer,
+ &(ReadPtr[TotalByteCnt - LocalByteCnt]),
+ RealByteCnt + XISF_CMD_SEND_EXTRA_BYTES);
+ }
+ if (Status != (int)(XST_SUCCESS)) {
+ return (int)XST_FAILURE;
+ }
+
+#ifdef XPAR_XISF_INTERFACE_PSQSPI
+ /*
+ * To discard the first 4 dummy bytes, shift the data in read buffer
+ */
+ ShiftSize = XISF_CMD_SEND_EXTRA_BYTES;
+ BufferIndex = (TotalByteCnt - LocalByteCnt);
+ for(;
+ BufferIndex < ((TotalByteCnt - LocalByteCnt) + RealByteCnt);
+ BufferIndex++) {
+ ReadPtr[BufferIndex] = ReadPtr[BufferIndex + ShiftSize];
+ }
+
+ /*
+ * Increase address to next bank
+ */
+ LocalAddress = (LocalAddress & BANKMASK) + SIXTEENMB;
+#endif
+ /*
+ * Decrease byte count by bytes already read.
+ */
+ LocalByteCnt = LocalByteCnt - RealByteCnt;
+
+ }
+
+ return (int)XST_SUCCESS;
+}
+
+/*****************************************************************************/
+/**
+*
+* This function reads data from the Serial Flash at a higher speed than normal
+* Read operation.
+*
+* @param InstancePtr is a pointer to the XIsf instance.
+* @param Command is the fast read command used to read data from the
+* flash. It could be one of XISF_CMD_DUAL/QUAD_*_FAST_READ or
+* XISF_CMD_FAST_READ.
+* @param Address is the starting address in the Serial Flash from where
+* the data is to be read.
+* @param ReadPtr is a pointer to the memory where the data read from
+* the Serial Flash is stored.
+* @param ByteCount is the number of bytes to be read from the Serial
+* Flash.
+* @param NumDummyBytes is the number of dummy bytes associated with the
+* fast read commands.
+*
+* @return XST_SUCCESS if successful else XST_FAILURE.
+*
+* @note
+* - XISF_CMD_FAST_READ operation is supported for Atmel, Intel,
+* STM, Winbond and Spansion Serial Flash.
+* - XISF_CMD_DUAL/QUAD_*_FAST_READ operations are supported on
+* Winbond (W25QXX), Numonyx (N25QXX) and Spansion (S25FL129)
+* quad flash devices.
+* - Minimum of one byte and a maximum of an entire Serial Flash
+* Array can be read.
+* - The valid data is available from the (4 + NumDummyBytes)th
+* location pointed to by the ReadPtr.
+*
+******************************************************************************/
+static int FastReadData(XIsf *InstancePtr, u8 Command, u32 Address,
+ u8 *ReadPtr, u32 ByteCount, int NumDummyBytes)
+{
+ u8 Mode;
+ int Index;
+ int Status;
+ u32 BankSel;
+ u32 RealAddr;
+ u32 RealByteCnt;
+ u32 BufferIndex;
+ u8 ShiftSize;
+ u32 TotalByteCnt = ByteCount;
+ u32 LocalByteCnt = ByteCount;
+ u32 LocalAddress = Address;
+ u8 WriteBuffer[5]= {0};
+
+ if (LocalByteCnt <= 0 ) {
+ return (int)XST_FAILURE;
+ }
+
+ if (ReadPtr == NULL) {
+ return (int)(XST_FAILURE);
+ }
+
+ if (NumDummyBytes <= 0) {
+ return (int)(XST_FAILURE);
+ }
+
+ while(((s32)(LocalByteCnt)) > 0) {
+
+ /*
+ * Translate address based on type of connection
+ * If stacked assert the slave select based on address
+ */
+ RealAddr = GetRealAddr(InstancePtr->SpiInstPtr, LocalAddress);
+
+#ifdef XPAR_XISF_INTERFACE_PSQSPI
+ if(InstancePtr->DeviceIDMemSize > 0x18U) {
+ /*
+ * Get the Transfer Mode
+ */
+ Mode = XIsf_GetTransferMode(InstancePtr);
+
+ /*
+ * Seting the transfer mode to Polled Mode before
+ * performing the Bank Select operation.
+ */
+ XIsf_SetTransferMode(InstancePtr, XISF_POLLING_MODE);
+
+ BankSel = RealAddr/SIXTEENMB;
+
+ (void)SendBankSelect(InstancePtr, BankSel);
+
+ /*
+ * Restoring the transfer mode back
+ */
+ XIsf_SetTransferMode(InstancePtr, Mode);
+ }
+
+ /*
+ * If data to be read spans beyond the current bank, then
+ * calculate RealByteCnt in current bank. Else
+ * RealByteCnt is the same as ByteCount
+ */
+ if((RealAddr & BANKMASK) != ((RealAddr+LocalByteCnt) & BANKMASK)) {
+ RealByteCnt = ((RealAddr & BANKMASK) + SIXTEENMB) - RealAddr;
+ }
+ else {
+#endif
+ RealByteCnt = LocalByteCnt;
+
+#ifdef XPAR_XISF_INTERFACE_PSQSPI
+ }
+#endif
+#if ((XPAR_XISF_FLASH_FAMILY == SPANSION) && \
+ (!defined(XPAR_XISF_INTERFACE_PSQSPI)))
+ if (InstancePtr->FourByteAddrMode == TRUE) {
+ WriteBuffer[BYTE1] = Command;
+ WriteBuffer[BYTE2] = (u8) (RealAddr >> XISF_ADDR_SHIFT24);
+ WriteBuffer[BYTE3] = (u8) (RealAddr >> XISF_ADDR_SHIFT16);
+ WriteBuffer[BYTE4] = (u8) (RealAddr >> XISF_ADDR_SHIFT8);
+ WriteBuffer[BYTE5] = (u8) RealAddr;
+
+ for (Index = 0; Index < NumDummyBytes; Index++) {
+ WriteBuffer[Index + BYTE5 + 1] = (u8) (XISF_DUMMYBYTE);
+ }
+ } else {
+#endif
+ WriteBuffer[BYTE1] = Command;
+ WriteBuffer[BYTE2] = (u8) (RealAddr >> XISF_ADDR_SHIFT16);
+ WriteBuffer[BYTE3] = (u8) (RealAddr >> XISF_ADDR_SHIFT8);
+ WriteBuffer[BYTE4] = (u8) RealAddr;
+
+ for (Index = 0; Index < NumDummyBytes; Index++) {
+ WriteBuffer[Index + BYTE5] = (u8) (XISF_DUMMYBYTE);
+ }
+#if ((XPAR_XISF_FLASH_FAMILY == SPANSION) && \
+ (!defined(XPAR_XISF_INTERFACE_PSQSPI)))
+ }
+#endif
+ RealByteCnt += NumDummyBytes;
+ if (InstancePtr->FourByteAddrMode == TRUE) {
+ Status = (int)XIsf_Transfer(InstancePtr, WriteBuffer,
+ &(ReadPtr[TotalByteCnt - LocalByteCnt]),
+ RealByteCnt + XISF_CMD_SEND_EXTRA_BYTES_4BYTE_MODE);
+ } else {
+ Status = (int)XIsf_Transfer(InstancePtr, WriteBuffer,
+ &(ReadPtr[TotalByteCnt - LocalByteCnt]),
+ RealByteCnt + XISF_CMD_SEND_EXTRA_BYTES);
+ }
+ if (Status != (int)(XST_SUCCESS)) {
+ return (int)(XST_FAILURE);
+ }
+
+#ifdef XPAR_XISF_INTERFACE_PSQSPI
+ /*
+ * To discard the first 5 dummy bytes, shift the data in read buffer
+ */
+ ShiftSize = XISF_CMD_SEND_EXTRA_BYTES + (u8)NumDummyBytes;
+ BufferIndex = (TotalByteCnt - LocalByteCnt);
+ for(;
+ BufferIndex < ((TotalByteCnt - LocalByteCnt) + RealByteCnt);
+ BufferIndex++) {
+ ReadPtr[BufferIndex] = ReadPtr[BufferIndex + ShiftSize];
+ }
+
+ /*
+ * Increase address to next bank
+ */
+ LocalAddress = (LocalAddress & BANKMASK) + SIXTEENMB;
+#endif
+ /*
+ * Decrease byte count by bytes already read.
+ */
+ LocalByteCnt = LocalByteCnt - (RealByteCnt - NumDummyBytes);
+ }
+
+ return (int)XST_SUCCESS;
+}
+
+/*****************************************************************************/
+/**
+*
+* This function copies the data from the Serial Flash to the specified SRAM
+* buffer.
+*
+* @param InstancePtr is a pointer to the XIsf instance.
+* @param BufferNum specifies the internal SRAM Buffer to which the data
+* from Serial Flash is to be transferred. The valid values are
+* XISF_PAGE_BUFFER1 or XISF_PAGE_BUFFER2. XISF_PAGE_BUFFER2 is
+* not valid in the case of AT45DB011D Flash as it contains a
+* single buffer.
+* @param Address specifies any address within the Page of the Serial
+* Flash from where the Page of data is to be copied.
+* Byte address in this Address is ignored as an entire Page of
+* data is transferred/copied.
+*
+* @return XST_SUCCESS if successful else XST_FAILURE.
+*
+* @note
+* - This operation is only supported in Atmel Serial Flash.
+* - This function reads one complete Page from the Serial Flash.
+* - Read the Spartan-3AN In-system Flash User Guide/Atmel
+* AT45XXXD Data sheets for more information.
+*
+******************************************************************************/
+static int FlashToBufTransfer(XIsf *InstancePtr, u8 BufferNum, u32 Address)
+{
+ int Status = (int)(XST_FAILURE);
+
+ Xil_AssertNonvoid(InstancePtr != NULL);
+ Xil_AssertNonvoid(Address != 0);
+ Xil_AssertNonvoid(BufferNum != 0);
+
+#if (XPAR_XISF_FLASH_FAMILY == ATMEL)
+ /*
+ * Check whether the buffer number is valid or not.
+ */
+ if ((BufferNum == XISF_PAGE_BUFFER1) ||
+ (BufferNum == XISF_PAGE_BUFFER2)) {
+ if ((InstancePtr->DeviceCode == XISF_ATMEL_DEV_AT45DB011D) &&
+ (BufferNum != XISF_PAGE_BUFFER1)) {
+ return (int)(XST_FAILURE);
+ }
+ } else {
+ return (int)(XST_FAILURE);
+ }
+
+ if (BufferNum == XISF_PAGE_BUFFER1) {
+ /*
+ * Page to Buffer 1 Transfer.
+ */
+ InstancePtr->WriteBufPtr[BYTE1] =
+ XISF_CMD_PAGETOBUF1_TRANS;
+ } else {
+ /*
+ * Page to Buffer 2 Transfer.
+ */
+ InstancePtr->WriteBufPtr[BYTE1] =
+ XISF_CMD_PAGETOBUF2_TRANS;
+ }
+
+ InstancePtr->WriteBufPtr[BYTE2] = (u8)(Address >> XISF_ADDR_SHIFT16);
+ InstancePtr->WriteBufPtr[BYTE3] = (u8)(Address >> XISF_ADDR_SHIFT8);
+ InstancePtr->WriteBufPtr[BYTE4] = (u8)(XISF_DUMMYBYTE);
+
+ /*
+ * Initiate the Transfer.
+ */
+ Status = XIsf_Transfer(InstancePtr, InstancePtr->WriteBufPtr, NULL,
+ XISF_CMD_SEND_EXTRA_BYTES);
+ if (Status != (int)(XST_SUCCESS)) {
+ return (int)(XST_FAILURE);
+ }
+#endif /* (XPAR_XISF_FLASH_FAMILY == ATMEL) */
+
+ return Status;
+
+}
+
+/*****************************************************************************/
+/**
+*
+* This function reads the data available in the SRAM buffer of Serial Flash.
+*
+* @param InstancePtr is a pointer to the XIsf instance.
+* @param BufferNum specifies the internal SRAM Buffer from which data
+* is to be read. The valid values are XISF_PAGE_BUFFER1 or
+* XISF_PAGE_BUFFER2. XISF_PAGE_BUFFER2 is not valid in case of
+* AT45DB011D Flash as it contains a single buffer.
+* @param ReadPtr is a pointer to the memory where the data read from the
+* SRAM buffer is stored.
+* @param ByteOffset is the byte offset in the buffer from where the
+* first byte is read.
+* @param NumBytes is the number of bytes to be read from the Buffer.
+*
+* @return XST_SUCCESS if successful else XST_FAILURE.
+*
+* @note
+* - This operation is only supported in Atmel Serial Flash.
+* - This function reads a Minimum of one Byte and a Maximum of an
+* entire SRAM buffer (1 Page) from the Serial Flash.
+* - The valid data is available from the fourth location pointed
+* to by the ReadPtr.
+* - Read the Spartan-3AN In-system Flash User Guide/Atmel
+* AT45XXXD Data sheets for more information.
+*
+******************************************************************************/
+static int BufferRead(XIsf *InstancePtr, u8 BufferNum, u8 *ReadPtr,
+ u32 ByteOffset, u32 NumBytes)
+{
+ int Status = (int)(XST_FAILURE);
+
+ Xil_AssertNonvoid(InstancePtr != NULL);
+ Xil_AssertNonvoid(BufferNum != 0);
+ Xil_AssertNonvoid(ReadPtr != NULL);
+ Xil_AssertNonvoid(ByteOffset != 0);
+ Xil_AssertNonvoid(NumBytes != 0);
+
+#if (XPAR_XISF_FLASH_FAMILY == ATMEL)
+
+ /*
+ * Check if the buffer number is valid or not.
+ */
+ if ((BufferNum == XISF_PAGE_BUFFER1) ||
+ (BufferNum == XISF_PAGE_BUFFER2)) {
+ if ((InstancePtr->DeviceCode == XISF_ATMEL_DEV_AT45DB011D) &&
+ (BufferNum != XISF_PAGE_BUFFER1)) {
+ return (int)(XST_FAILURE);
+ }
+ } else {
+ return (int)(XST_FAILURE);
+ }
+
+ if (ReadPtr == NULL) {
+ return (int)(XST_FAILURE);
+ }
+
+ if (ByteOffset > InstancePtr->BytesPerPage){
+ return (int)(XST_FAILURE);
+ }
+
+ if ((NumBytes <= 0) || (NumBytes > InstancePtr->BytesPerPage)) {
+ return (int)(XST_FAILURE);
+ }
+
+ if (BufferNum == XISF_PAGE_BUFFER1) {
+ ReadPtr[BYTE1] = XISF_CMD_BUF1_READ; /* Buffer 1 Read. */
+ } else {
+ ReadPtr[BYTE1] = XISF_CMD_BUF2_READ; /* Buffer 2 Read.*/
+ }
+ ReadPtr[BYTE2] = (u8) (0x00);
+ ReadPtr[BYTE3] = (u8) (ByteOffset >> XISF_ADDR_SHIFT8);
+ ReadPtr[BYTE4] = (u8) ByteOffset;
+
+ /*
+ * Initiate the Transfer.
+ */
+ Status = XIsf_Transfer(InstancePtr, ReadPtr, ReadPtr,
+ NumBytes + XISF_CMD_SEND_EXTRA_BYTES);
+ if (Status != (int)(XST_SUCCESS)) {
+ return (int)(XST_FAILURE);
+ }
+#endif /* (XPAR_XISF_FLASH_FAMILY == ATMEL) */
+
+ return Status;
+
+}
+/*****************************************************************************/
+/**
+*
+* This function reads the data from the internal SRAM page buffer of the Serial
+* Flash memory at higher speed than normal Buffer Read operation.
+*
+* @param InstancePtr is a pointer to the XIsf instance.
+* @param BufferNum specifies the internal SRAM Buffer from which data
+* is to be read. The valid values are XISF_PAGE_BUFFER1 or
+* XISF_PAGE_BUFFER2. XISF_PAGE_BUFFER2 is not valid in case of
+* AT45DB011D Flash as it contains a single buffer.
+* @param ReadPtr is a pointer to the memory where the data read from the
+* SRAM buffer is stored.
+* @param ByteOffset is the byte offset in the buffer from where the
+* first byte is read.
+* @param NumBytes is the number of bytes to be read from the Buffer.
+*
+* @return XST_SUCCESS if successful else XST_FAILURE.
+*
+* @note
+* - This operation is only supported in Atmel Serial Flash.
+* - This function reads a Minimum of one Byte and a Maximum of an
+* entire SRAM buffer (1 Page) from the Serial Flash.
+* - The valid data is available from the fifth location pointed
+* to by the ReadPtr.
+* - Read the Spartan-3AN In-system Flash User Guide/Atmel
+* AT45XXXD Data sheets for more information.
+*
+******************************************************************************/
+static int FastBufferRead(XIsf *InstancePtr, u8 BufferNum, u8 *ReadPtr,
+ u32 ByteOffset, u32 NumBytes)
+{
+ int Status = (int)(XST_FAILURE);
+
+ Xil_AssertNonvoid(InstancePtr != NULL);
+ Xil_AssertNonvoid(BufferNum != 0);
+ Xil_AssertNonvoid(ReadPtr != NULL);
+ Xil_AssertNonvoid(ByteOffset != 0);
+ Xil_AssertNonvoid(NumBytes != 0);
+
+#if (XPAR_XISF_FLASH_FAMILY == ATMEL)
+ /*
+ * Check if the buffer number is valid or not.
+ */
+ if ((BufferNum == XISF_PAGE_BUFFER1) ||
+ (BufferNum == XISF_PAGE_BUFFER2)) {
+ if ((InstancePtr->DeviceCode == XISF_ATMEL_DEV_AT45DB011D) &&
+ (BufferNum != XISF_PAGE_BUFFER1)) {
+ return (int)(XST_FAILURE);
+ }
+ } else {
+ return (int)(XST_FAILURE);
+ }
+
+ if (ReadPtr == NULL) {
+ return (int)(XST_FAILURE);
+ }
+
+ if (ByteOffset > InstancePtr->BytesPerPage){
+ return (int)(XST_FAILURE);
+ }
+
+ if ((NumBytes <= 0) || (NumBytes > InstancePtr->BytesPerPage)) {
+ return (int)(XST_FAILURE);
+ }
+
+ if (BufferNum == XISF_PAGE_BUFFER1) {
+ /*
+ * Buffer 1 Fast Read.
+ */
+ ReadPtr[BYTE1] = XISF_CMD_FAST_BUF1_READ;
+ } else {
+ /*
+ * Buffer 2 Fast Read.
+ */
+ ReadPtr[BYTE1] = XISF_CMD_FAST_BUF2_READ;
+ }
+
+ ReadPtr[BYTE2] = (u8) (0x00);
+ ReadPtr[BYTE3] = (u8) (ByteOffset >> XISF_ADDR_SHIFT8);
+ ReadPtr[BYTE4] = (u8) ByteOffset;
+ ReadPtr[BYTE5] = (u8) (XISF_DUMMYBYTE);
+
+ /*
+ * Initiate the Transfer.
+ */
+ Status = XIsf_Transfer(InstancePtr, ReadPtr, ReadPtr,
+ NumBytes + XISF_CMD_FAST_READ_EXTRA_BYTES);
+ if (Status != (int)(XST_SUCCESS)) {
+ return (int)(XST_FAILURE);
+ }
+#endif /* (XPAR_XISF_FLASH_FAMILY == ATMEL) */
+
+ return Status;
+}
+
+/*****************************************************************************/
+/**
+*
+* This function reads the data from OTP area of the Serial Flash.
+*
+* @param InstancePtr is a pointer to the XIsf instance.
+* @param Address is the starting address in OTP area of the Serial Flash
+* from which the data is to be read.
+* @param ReadPtr is a pointer to the memory where the data read from the
+* Serial Flash is stored.
+* @param ByteCount is the number of bytes to be read from the Serial
+* Flash.
+*
+* @return XST_SUCCESS if successful else XST_FAILURE.
+*
+* @note
+* - This operation is only supported for Intel Serial Flash.
+* - Minimum of one byte and a maximum of an entire Serial Flash
+* array can be read.
+******************************************************************************/
+static int ReadOTPData(XIsf *InstancePtr, u32 Address, u8 *ReadPtr,
+ u32 ByteCount)
+{
+ int Status = (int)(XST_FAILURE);
+
+ Xil_AssertNonvoid(InstancePtr != NULL);
+ Xil_AssertNonvoid(Address != 0);
+ Xil_AssertNonvoid(ReadPtr != NULL);
+ Xil_AssertNonvoid(ByteCount != 0);
+
+#if (XPAR_XISF_FLASH_FAMILY == INTEL)
+ if (ByteCount <= 0 ) {
+ return (int)(XST_FAILURE);
+ }
+
+ if (ReadPtr == NULL) {
+ return (int)(XST_FAILURE);
+ }
+
+ ReadPtr[BYTE1] = XISF_CMD_OTP_READ;
+ ReadPtr[BYTE2] = (u8) (Address >> XISF_ADDR_SHIFT16);
+ ReadPtr[BYTE3] = (u8) (Address >> XISF_ADDR_SHIFT8);
+ ReadPtr[BYTE4] = (u8) Address;
+ ReadPtr[BYTE5] = (u8) (XISF_DUMMYBYTE);
+
+
+ /*
+ * Initiate the Transfer.
+ */
+ Status = XIsf_Transfer(InstancePtr, ReadPtr, ReadPtr,
+ ByteCount + XISF_OTP_RDWR_EXTRA_BYTES);
+ if (Status != (int)(XST_SUCCESS)) {
+ return (int)(XST_FAILURE);
+ }
+#endif /* (XPAR_XISF_FLASH_FAMILY == INTEL) */
+
+ return Status;
+}
diff --git a/lib/sw_services/xilisf/src/xilisf_spr.c b/lib/sw_services/xilisf/src/xilisf_spr.c
new file mode 100644
index 00000000..50c173db
--- /dev/null
+++ b/lib/sw_services/xilisf/src/xilisf_spr.c
@@ -0,0 +1,411 @@
+/******************************************************************************
+*
+* Copyright (C) 2012 - 2015 Xilinx, Inc. All rights reserved.
+*
+* Permission is hereby granted, free of charge, to any person obtaining a copy
+* of this software and associated documentation files (the "Software"), to deal
+* in the Software without restriction, including without limitation the rights
+* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+* copies of the Software, and to permit persons to whom the Software is
+* furnished to do so, subject to the following conditions:
+*
+* The above copyright notice and this permission notice shall be included in
+* all copies or substantial portions of the Software.
+*
+* Use of the Software is limited solely to applications:
+* (a) running on a Xilinx device, or
+* (b) that interact with a Xilinx device through a bus or interconnect.
+*
+* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+* XILINX BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
+* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+* SOFTWARE.
+*
+* Except as contained in this notice, the name of the Xilinx shall not be used
+* in advertising or otherwise to promote the sale, use or other dealings in
+* this Software without prior written authorization from Xilinx.
+*
+******************************************************************************/
+/*****************************************************************************/
+/**
+*
+* @file xilisf_spr.c
+*
+* This file contains the library functions to operate on Sector Protection
+* feature of the Serial Flash. Refer xilisf.h for a detailed description.
+*
+*
+*
+* MODIFICATION HISTORY:
+*
+* Ver Who Date Changes
+* ----- ------- -------- -----------------------------------------------
+* 1.00a ksu/sdm 03/03/08 First release
+* 2.01a sdm 01/04/10 Added Support for Winbond W25QXX/W25XX devices
+* 2.04a sdm 08/17/10 Updated to support Numonyx (N25QXX) and Spansion
+* flash memories
+* 5.0 sb 08/05/14 Added Call back to lib interrupt handler
+* after XIsf_Transfer Calls.
+* Changed API:
+* - XIsf_SectorProtect()
+*
+*
+*
+******************************************************************************/
+
+/***************************** Include Files *********************************/
+
+#include "include/xilisf.h"
+
+/************************** Constant Definitions *****************************/
+
+/**************************** Type Definitions *******************************/
+
+/***************** Macros (Inline Functions) Definitions *********************/
+
+/************************** Function Prototypes ******************************/
+
+extern int XIsf_Transfer(XIsf *InstancePtr, u8 *WritePtr, u8* ReadPtr,
+ u32 ByteCount);
+extern int XIsf_GetStatus(XIsf *InstancePtr, u8 *ReadPtr);
+static int SprRead(XIsf *InstancePtr, u8 *ReadPtr);
+static int SprProgram(XIsf *InstancePtr, u8 *BufferPtr);
+
+static int SprErase(XIsf *InstancePtr);
+static int SpEnable(XIsf *InstancePtr);
+static int SpDisable(XIsf *InstancePtr);
+
+/************************** Variable Definitions *****************************/
+extern u32 XIsf_StatusEventInfo;
+extern unsigned int XIsf_ByteCountInfo;
+/************************** Function Definitions ******************************/
+
+
+/*****************************************************************************/
+/**
+*
+* This API is used for performing Sector Protect related operations.
+*
+* @param InstancePtr is a pointer to the XIsf instance.
+* @param Operation is the type of Sector Protect operation to be
+* performed on the Serial Flash.
+* The different operations are
+* - XISF_SPR_READ: Read Sector Protection Register
+* - XISF_SPR_WRITE: Write Sector Protection Register
+* - XISF_SPR_ERASE: Erase Sector Protection Register
+* - XISF_SP_ENABLE: Enable Sector Protection
+* - XISF_SP_DISABLE: Disable Sector Protection
+* @param BufferPtr is a pointer to the memory where the SPR content is
+* read to/written from. This argument can be NULL if the
+* Operation is SprErase, SpEnable and SpDisable.
+*
+* @return XST_SUCCESS if successful else XST_FAILURE.
+*
+* @note
+* - The SPR content is stored at the fourth location pointed
+* by the BufferPtr when performing XISF_SPR_READ operation.
+* - For Intel, STM, Winbond and Spansion Serial Flash, the user
+* application must call the XIsf_WriteEnable() API by passing
+* XISF_WRITE_ENABLE as an argument, before calling the
+* XIsf_SectorProtect() API, for Sector Protect Register Write
+* (XISF_SPR_WRITE) operation.
+* - Atmel Flash supports all these Sector Protect operations.
+* - Intel, STM, Winbond and Spansion Flash support only Sector
+* Protect Read and Sector Protect Write operations.
+*
+******************************************************************************/
+int XIsf_SectorProtect(XIsf *InstancePtr, XIsf_SpOperation Operation,
+ u8 *BufferPtr)
+{
+ int Status = (int)(XST_FAILURE);
+ u8 Mode;
+
+ switch (Operation) {
+ case XISF_SPR_READ:
+ Status = SprRead(InstancePtr, BufferPtr);
+ break;
+
+ case XISF_SPR_WRITE:
+ Status = SprProgram(InstancePtr, BufferPtr);
+ break;
+
+ case XISF_SPR_ERASE:
+ Status = SprErase(InstancePtr);
+ break;
+
+ case XISF_SP_ENABLE:
+ Status = SpEnable(InstancePtr);
+ break;
+
+ case XISF_SP_DISABLE:
+ Status = SpDisable(InstancePtr);
+ 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;
+}
+
+/*****************************************************************************/
+/**
+*
+* This function reads the content of the Sector Protection Register(SPR).
+*
+* @param InstancePtr is a pointer to the XIsf instance.
+* @param ReadPtr is a pointer to the memory where the SPR content is
+* copied.
+*
+* @return XST_SUCCESS if successful else XST_FAILURE.
+*
+* @note
+* - 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 second location
+* for STM/Intel/Winbond/Spansion Serial Flash.
+*
+******************************************************************************/
+static int SprRead(XIsf *InstancePtr, u8 *ReadPtr)
+{
+ int Status;
+
+ Xil_AssertNonvoid(InstancePtr != NULL);
+
+
+ if (ReadPtr == NULL) {
+ return (int)(XST_FAILURE);
+ }
+
+#if (XPAR_XISF_FLASH_FAMILY == ATMEL)
+ u32 Index;
+
+ /*
+ * Prepare the Write Buffer.
+ */
+ InstancePtr->WriteBufPtr[BYTE1] = XISF_CMD_SPR_READ;
+
+ for(Index = 1; Index < (InstancePtr->NumOfSectors +
+ XISF_CMD_SEND_EXTRA_BYTES); Index++) {
+ InstancePtr->WriteBufPtr[Index] = XISF_DUMMYBYTE;
+ }
+
+ /*
+ * Initiate the Transfer.
+ */
+ Status = XIsf_Transfer(InstancePtr, InstancePtr->WriteBufPtr, ReadPtr,
+ InstancePtr->NumOfSectors +
+ XISF_CMD_SEND_EXTRA_BYTES);
+
+#else
+
+ Status = XIsf_GetStatus(InstancePtr, ReadPtr);
+
+#endif /* (XPAR_XISF_FLASH_FAMILY == ATMEL) */
+
+ if (Status != (int)(XST_SUCCESS)) {
+ return (int)(XST_FAILURE);
+ }
+
+ return (int)(XST_SUCCESS);
+}
+
+/*****************************************************************************/
+/**
+*
+* This function writes to the Sector Protection Register(SPR).
+*
+* @param InstancePtr is a pointer to the XIsf instance.
+* @param BufferPtr is the pointer to the data to be written to SPR.
+*
+* @return XST_SUCCESS if successful else XST_FAILURE.
+*
+* @note This operation is supported for Atmel, Intel, STM, Winbond and
+* Spansion Serial Flash.
+*
+******************************************************************************/
+static int SprProgram(XIsf *InstancePtr, u8 *BufferPtr)
+{
+ int Status;
+
+ Xil_AssertNonvoid(InstancePtr != NULL);
+
+ if (BufferPtr == NULL) {
+ return (int)(XST_FAILURE);
+ }
+
+#if (XPAR_XISF_FLASH_FAMILY == ATMEL)
+ u32 Index;
+
+ /*
+ * Prepare the Write Buffer.
+ */
+ InstancePtr->WriteBufPtr[BYTE1] = XISF_CMD_SPR_BYTE1;
+ InstancePtr->WriteBufPtr[BYTE2] = XISF_CMD_SPR_BYTE2;
+ InstancePtr->WriteBufPtr[BYTE3] = XISF_CMD_SPR_BYTE3;
+ InstancePtr->WriteBufPtr[BYTE4] = XISF_CMD_SPR_BYTE4_PROGRAM;
+
+ for(Index = 4; Index < (InstancePtr->NumOfSectors +
+ XISF_CMD_SEND_EXTRA_BYTES); Index++) {
+ InstancePtr->WriteBufPtr[Index] = *BufferPtr++;
+ }
+
+ /*
+ * Initiate the Transfer.
+ */
+ Status = XIsf_Transfer(InstancePtr, InstancePtr->WriteBufPtr, NULL,
+ InstancePtr->NumOfSectors +
+ XISF_CMD_SEND_EXTRA_BYTES);
+#else
+
+ Status = XIsf_Write(InstancePtr, XISF_WRITE_STATUS_REG,
+ (void*) BufferPtr);
+
+#endif /* (XPAR_XISF_FLASH_FAMILY == ATMEL) */
+
+ if (Status != (int)(XST_SUCCESS)) {
+ return (int)(XST_FAILURE);
+ }
+
+ return (int)(XST_SUCCESS);
+}
+
+/*****************************************************************************/
+/**
+*
+* This function erases the content of the Sector Protection Register(SPR).
+*
+* @param InstancePtr is a pointer to the XIsf instance.
+*
+* @return XST_SUCCESS if successful else XST_FAILURE.
+*
+* @note This operation is only supported for Atmel Serial Flash.
+*
+******************************************************************************/
+static int SprErase(XIsf *InstancePtr)
+{
+ int Status = (int)(XST_FAILURE);
+
+ Xil_AssertNonvoid(InstancePtr != NULL);
+
+#if (XPAR_XISF_FLASH_FAMILY == ATMEL)
+ /*
+ * Prepare the Write Buffer.
+ */
+ InstancePtr->WriteBufPtr[BYTE1] = XISF_CMD_SPR_BYTE1;
+ InstancePtr->WriteBufPtr[BYTE2] = XISF_CMD_SPR_BYTE2;
+ InstancePtr->WriteBufPtr[BYTE3] = XISF_CMD_SPR_BYTE3;
+ InstancePtr->WriteBufPtr[BYTE4] = XISF_CMD_SPR_BYTE4_ERASE;
+
+ /*
+ * Initiate the Transfer.
+ */
+ Status = XIsf_Transfer(InstancePtr, InstancePtr->WriteBufPtr, NULL,
+ XISF_CMD_SEND_EXTRA_BYTES);
+
+ if (Status != (int)(XST_SUCCESS)) {
+ return (int)(XST_FAILURE);
+ }
+#endif /* (XPAR_XISF_FLASH_FAMILY == ATMEL) */
+
+ return Status;
+}
+
+/*****************************************************************************/
+/**
+*
+* This function enables Sector Protection. Sectors specified for protection in
+* the Sector Protection Register are protected by using this operation.
+*
+* @param InstancePtr is a pointer to the XIsf instance.
+*
+* @return XST_SUCCESS if successful else XST_FAILURE.
+*
+* @note This operation is only supported for Atmel Serial Flash.
+*
+******************************************************************************/
+static int SpEnable(XIsf *InstancePtr)
+{
+ int Status = (int)(XST_FAILURE);
+
+ Xil_AssertNonvoid(InstancePtr != NULL);
+
+
+#if (XPAR_XISF_FLASH_FAMILY == ATMEL)
+ /*
+ * Prepare the Write Buffer.
+ */
+ InstancePtr->WriteBufPtr[BYTE1] = XISF_CMD_SPR_BYTE1;
+ InstancePtr->WriteBufPtr[BYTE2] = XISF_CMD_SPR_BYTE2;
+ InstancePtr->WriteBufPtr[BYTE3] = XISF_CMD_SPR_BYTE3;
+ InstancePtr->WriteBufPtr[BYTE4] = XISF_CMD_SPR_BYTE4_ENABLE;
+
+ /*
+ * Initiate the Transfer.
+ */
+ Status = XIsf_Transfer(InstancePtr, InstancePtr->WriteBufPtr, NULL,
+ XISF_CMD_SEND_EXTRA_BYTES);
+
+ if (Status != (int)(XST_SUCCESS)) {
+ return (int)(XST_FAILURE);
+ }
+#endif /* (XPAR_XISF_FLASH_FAMILY == ATMEL) */
+
+ return Status;
+}
+
+/*****************************************************************************/
+/**
+*
+* This function Disables Sector Protection.
+*
+* @param InstancePtr is a pointer to the XIsf instance.
+*
+* @return XST_SUCCESS if successful else XST_FAILURE.
+*
+* @note This operation is only supported for Atmel Serial Flash.
+*
+******************************************************************************/
+static int SpDisable(XIsf *InstancePtr)
+{
+ int Status = (int)(XST_FAILURE);
+
+ Xil_AssertNonvoid(InstancePtr != NULL);
+
+#if (XPAR_XISF_FLASH_FAMILY == ATMEL)
+ /*
+ * Prepare the Write Buffer.
+ */
+ InstancePtr->WriteBufPtr[BYTE1] = XISF_CMD_SPR_BYTE1;
+ InstancePtr->WriteBufPtr[BYTE2] = XISF_CMD_SPR_BYTE2;
+ InstancePtr->WriteBufPtr[BYTE3] = XISF_CMD_SPR_BYTE3;
+ InstancePtr->WriteBufPtr[BYTE4] = XISF_CMD_SPR_BYTE4_DISABLE;
+
+ /*
+ * Initiate the Transfer.
+ */
+ Status = XIsf_Transfer(InstancePtr, InstancePtr->WriteBufPtr, NULL,
+ XISF_CMD_SEND_EXTRA_BYTES);
+
+ if (Status != (int)(XST_SUCCESS)) {
+ return (int)(XST_FAILURE);
+ }
+#endif /* (XPAR_XISF_FLASH_FAMILY == ATMEL) */
+
+ return Status;
+}
diff --git a/lib/sw_services/xilisf/src/xilisf_write.c b/lib/sw_services/xilisf/src/xilisf_write.c
new file mode 100644
index 00000000..74105155
--- /dev/null
+++ b/lib/sw_services/xilisf/src/xilisf_write.c
@@ -0,0 +1,975 @@
+/******************************************************************************
+*
+* Copyright (C) 2012 - 2015 Xilinx, Inc. All rights reserved.
+*
+* Permission is hereby granted, free of charge, to any person obtaining a copy
+* of this software and associated documentation files (the "Software"), to deal
+* in the Software without restriction, including without limitation the rights
+* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+* copies of the Software, and to permit persons to whom the Software is
+* furnished to do so, subject to the following conditions:
+*
+* The above copyright notice and this permission notice shall be included in
+* all copies or substantial portions of the Software.
+*
+* Use of the Software is limited solely to applications:
+* (a) running on a Xilinx device, or
+* (b) that interact with a Xilinx device through a bus or interconnect.
+*
+* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+* XILINX BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
+* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+* SOFTWARE.
+*
+* Except as contained in this notice, the name of the Xilinx shall not be used
+* in advertising or otherwise to promote the sale, use or other dealings in
+* this Software without prior written authorization from Xilinx.
+*
+******************************************************************************/
+/*****************************************************************************/
+/**
+*
+* @file xilisf_write.c
+*
+* This file contains the library functions to write to the Serial Flash
+* devices. Refer xilisf.h for detailed description.
+*
+*
+*
+* MODIFICATION HISTORY:
+*
+* Ver Who Date Changes
+* ----- ------- -------- -----------------------------------------------
+* 1.00a ksu/sdm 03/03/08 First release
+* 2.01a sdm 01/04/10 Added Support for Winbond W25QXX/W25XX devices
+* 2.04a sdm 08/17/10 Updated to support Numonyx (N25QXX) and Spansion
+* flash memories
+* 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()
+* 5.2 asa 05/12/15 Added support for Micron (N25Q256A) flash part
+* which supports 4 byte addressing.
+*
+*
+******************************************************************************/
+
+/***************************** Include Files *********************************/
+
+#include "include/xilisf.h"
+
+/************************** Constant Definitions *****************************/
+#define SIXTEENMB 0x1000000 /**< Sixteen MB */
+
+/**************************** Type Definitions *******************************/
+
+/***************** Macros (Inline Functions) Definitions *********************/
+
+/************************** Function Prototypes ******************************/
+
+extern int XIsf_Transfer(XIsf *InstancePtr, u8 *WritePtr, u8* ReadPtr,
+ u32 ByteCount);
+extern u32 GetRealAddr(XIsf_Iface *QspiPtr, u32 Address);
+
+#ifdef XPAR_XISF_INTERFACE_PSQSPI
+extern int SendBankSelect(XIsf *InstancePtr, u32 BankSel);
+#endif
+static int WriteData(XIsf *InstancePtr, u8 Command, u32 Address,
+ const u8 *BufferPtr, u32 ByteCount);
+static int AutoPageWrite(XIsf *InstancePtr, u32 Address);
+static int BufferWrite(XIsf *InstancePtr, u8 BufferNum, const u8 *WritePtr,
+ u32 ByteOffset, u32 NumBytes);
+static int BufferToFlashWriteWithErase(XIsf *InstancePtr, u8 BufferNum,
+ u32 Address);
+static int BufferToFlashWriteWithoutErase(XIsf *InstancePtr, u8 BufferNum,
+ u32 Address);
+static int WriteSR(XIsf *InstancePtr, u8 SRData);
+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 ******************************/
+
+
+/*****************************************************************************/
+/**
+*
+* This API writes the data to the Serial Flash.
+*
+* @param InstancePtr is a pointer to the XIsf instance.
+* @param Operation is the type of write operation to be performed on the
+* Serial Flash.
+* The different operations are
+* - XISF_WRITE: Normal Write
+* - XISF_DUAL_IP_PAGE_WRITE: Dual Input Fast Program
+* - XISF_DUAL_IP_EXT_PAGE_WRITE: Dual Input Extended Fast Program
+* - XISF_QUAD_IP_PAGE_WRITE: Quad Input Fast Program
+* - XISF_QUAD_IP_EXT_PAGE_WRITE: Quad Input Extended Fast Program
+* - XISF_AUTO_PAGE_WRITE: Auto Page Write
+* - XISF_BUFFER_WRITE: Buffer Write
+* - XISF_BUF_TO_PAGE_WRITE_WITH_ERASE: Buffer to Page Transfer
+* with Erase
+* - XISF_BUF_TO_PAGE_WRITE_WITHOUT_ERASE: Buffer to Page Transfer
+* without Erase
+* - XISF_WRITE_STATUS_REG: Status Register Write
+* - XISF_WRITE_STATUS_REG2: 2 byte Status Register Write
+* - XISF_OTP_WRITE: OTP Write.
+*
+* @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).
+*
+* - Normal Write (XISF_WRITE), Dual Input Fast Program
+* (XISF_DUAL_IP_PAGE_WRITE), Dual Input Extended Fast Program
+* (XISF_DUAL_IP_EXT_PAGE_WRITE), Quad Input Fast Program
+* (XISF_QUAD_IP_PAGE_WRITE), Quad Input Extended Fast Program
+* (XISF_QUAD_IP_EXT_PAGE_WRITE):
+* The OpParamPtr must be of type struct XIsf_WriteParam.
+* 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
+* 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.
+* This operation is only supported for Atmel Serial Flash.
+*
+* - Buffer Write (XISF_BUFFER_WRITE):
+* The OpParamPtr must be of type struct
+* 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 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 number of bytes to be written to the
+* Buffer.
+* This operation is supported only for Atmel Serial Flash.
+*
+* - Buffer To Memory Write With Erase
+* (XISF_BUF_TO_PAGE_WRITE_WITH_ERASE)/
+* Buffer To Memory Write Without Erase
+* (XISF_BUF_TO_PAGE_WRITE_WITHOUT_ERASE):
+* The OpParamPtr must be of type struct
+* 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 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.
+* These operations are only supported for Atmel Serial Flash.
+*
+* - Write Status Register (XISF_WRITE_STATUS_REG):
+* The OpParamPtr must be of type of 8 bit unsigned integer
+* variable. This is the value to be written to the Status
+* Register.
+* This operation is only supported for Intel, STM Winbond and
+* Spansion Serial Flash.
+*
+* - Write Status Register2 (XISF_WRITE_STATUS_REG2):
+* The OpParamPtr must be of type (u8 *) and should point to two
+* 8 bit unsigned integer values. This is the value to be written
+* to the 16 bit Status Register.
+* This operation is only supported in Winbond (W25Q) Serial Flash.
+*
+* - One Time Programmable Area Write (XISF_OTP_WRITE):
+* The OpParamPtr must be of type struct XIsf_WriteParam.
+* OpParamPtr->Address is the address in the SRAM Buffer of the
+* 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.
+* This operation is only supported for Intel Serial Flash.
+*
+* @return XST_SUCCESS if successful else XST_FAILURE.
+*
+* @note
+* - Application must fill the structure elements of the third
+* argument and pass its pointer by type casting it with void
+* pointer.
+* - For Intel, STM, Winbond and Spansion Serial Flash, the user
+* application must call the XIsf_WriteEnable() API by passing
+* XISF_WRITE_ENABLE as an argument, before calling the
+* XIsf_Write() API.
+*
+******************************************************************************/
+int XIsf_Write(XIsf *InstancePtr, XIsf_WriteOperation Operation,
+ void *OpParamPtr)
+{
+ int Status = (int)XST_FAILURE;
+ u8 Mode;
+ XIsf_WriteParam *WriteParamPtr;
+ XIsf_BufferWriteParam *BufferWriteParamPtr;
+ XIsf_BufferToFlashWriteParam *BufferToFlashWriteParamPtr;
+
+ if (InstancePtr == NULL) {
+ return (int)XST_FAILURE;
+ }
+
+ if (InstancePtr->IsReady != TRUE) {
+ return (int)XST_FAILURE;
+ }
+
+ if (NULL == OpParamPtr) {
+ return (int)XST_FAILURE;
+ }
+
+ switch (Operation) {
+ case XISF_WRITE:
+ WriteParamPtr = (XIsf_WriteParam*)(void *) OpParamPtr;
+ Xil_AssertNonvoid(WriteParamPtr != NULL);
+ Status = WriteData(InstancePtr,
+ XISF_CMD_PAGEPROG_WRITE,
+ WriteParamPtr->Address,
+ WriteParamPtr->WritePtr,
+ WriteParamPtr->NumBytes);
+ break;
+
+ case XISF_AUTO_PAGE_WRITE:
+ Status = AutoPageWrite(InstancePtr,
+ *((u32*)(void *) OpParamPtr));
+ break;
+
+ case XISF_BUFFER_WRITE:
+ BufferWriteParamPtr = (XIsf_BufferWriteParam*)
+ (void *) OpParamPtr;
+ Xil_AssertNonvoid(BufferWriteParamPtr != NULL);
+ Status = BufferWrite(InstancePtr,
+ BufferWriteParamPtr->BufferNum,
+ BufferWriteParamPtr->WritePtr,
+ BufferWriteParamPtr->ByteOffset,
+ BufferWriteParamPtr->NumBytes);
+ break;
+
+ case XISF_BUF_TO_PAGE_WRITE_WITH_ERASE:
+ BufferToFlashWriteParamPtr =
+ (XIsf_BufferToFlashWriteParam*)(void *) OpParamPtr;
+ Xil_AssertNonvoid(BufferToFlashWriteParamPtr != NULL);
+ Status = BufferToFlashWriteWithErase(InstancePtr,
+ BufferToFlashWriteParamPtr->BufferNum,
+ BufferToFlashWriteParamPtr->Address);
+ break;
+
+ case XISF_BUF_TO_PAGE_WRITE_WITHOUT_ERASE:
+ BufferToFlashWriteParamPtr =
+ (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*)(void *) OpParamPtr));
+ break;
+
+ case XISF_OTP_WRITE:
+ WriteParamPtr = (XIsf_WriteParam*)(void *) OpParamPtr;
+ Xil_AssertNonvoid(WriteParamPtr != NULL);
+ if (1 == WriteParamPtr->NumBytes) {
+ Status = WriteOTPData(InstancePtr,
+ WriteParamPtr->Address,
+ WriteParamPtr->WritePtr);
+ }
+ break;
+
+ case XISF_WRITE_STATUS_REG2:
+ Status = WriteSR2(InstancePtr,
+ (u8*)(void *) OpParamPtr);
+ break;
+
+#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*)(void *) OpParamPtr;
+ Xil_AssertNonvoid(WriteParamPtr != NULL);
+ Status = WriteData(InstancePtr,
+ XISF_CMD_QUAD_IP_PAGE_WRITE,
+ WriteParamPtr->Address,
+ WriteParamPtr->WritePtr,
+ WriteParamPtr->NumBytes);
+ break;
+
+#endif /*((XPAR_XISF_FLASH_FAMILY == WINBOND) ||
+ (XPAR_XISF_FLASH_FAMILY == STM) ||
+ (XPAR_XISF_FLASH_FAMILY == SPANSION))*/
+
+#if (XPAR_XISF_FLASH_FAMILY == STM)
+ case XISF_DUAL_IP_PAGE_WRITE:
+ WriteParamPtr = (XIsf_WriteParam*)(void *) OpParamPtr;
+ Xil_AssertNonvoid(WriteParamPtr != NULL);
+ Status = WriteData(InstancePtr,
+ XISF_CMD_DUAL_IP_PAGE_WRITE,
+ WriteParamPtr->Address,
+ WriteParamPtr->WritePtr,
+ WriteParamPtr->NumBytes);
+ break;
+
+ case XISF_DUAL_IP_EXT_PAGE_WRITE:
+ WriteParamPtr = (XIsf_WriteParam*)(void *) OpParamPtr;
+ Xil_AssertNonvoid(WriteParamPtr != NULL);
+ Status = WriteData(InstancePtr,
+ XISF_CMD_DUAL_IP_EXT_PAGE_WRITE,
+ WriteParamPtr->Address,
+ WriteParamPtr->WritePtr,
+ WriteParamPtr->NumBytes);
+ break;
+
+ case XISF_QUAD_IP_EXT_PAGE_WRITE:
+ WriteParamPtr = (XIsf_WriteParam*)(void *) OpParamPtr;
+ Xil_AssertNonvoid(WriteParamPtr != NULL);
+ Status = WriteData(InstancePtr,
+ XISF_CMD_QUAD_IP_EXT_PAGE_WRITE,
+ WriteParamPtr->Address,
+ WriteParamPtr->WritePtr,
+ WriteParamPtr->NumBytes);
+ break;
+#endif /* (XPAR_XISF_FLASH_FAMILY == STM) */
+
+ default:
+ break;
+ }
+
+ 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 Serial
+* Flash.
+*
+* @param InstancePtr is a pointer to the XIsf instance.
+* @param Address is the address in the Serial Flash memory, where the
+* data is to be written.
+* @param BufferPtr is a pointer to the data to be written to Serial
+* Flash.
+* @param ByteCount is the number of bytes to be written.
+*
+* @return XST_SUCCESS if successful else XST_FAILURE.
+*
+* @note
+* - A minimum of one byte and a maximum of one Page can be
+* written using this function.
+* - This operation is supported for Atmel, Intel, STM, Winbond
+* and Spansion Serial Flash.
+*
+******************************************************************************/
+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 (int)XST_FAILURE;
+ }
+
+ if (LocalBufPtr == NULL) {
+ return (int)XST_FAILURE;
+ }
+
+ /*
+ * 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
+ /*
+ * 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
+#if ((XPAR_XISF_FLASH_FAMILY == SPANSION) && \
+ (!defined(XPAR_XISF_INTERFACE_PSQSPI)))
+ if (InstancePtr->FourByteAddrMode == TRUE) {
+ InstancePtr->WriteBufPtr[BYTE1] = Command;
+ InstancePtr->WriteBufPtr[BYTE2] = (u8) (RealAddr >> XISF_ADDR_SHIFT24);
+ InstancePtr->WriteBufPtr[BYTE3] = (u8) (RealAddr >> XISF_ADDR_SHIFT16);
+ InstancePtr->WriteBufPtr[BYTE4] = (u8) (RealAddr >> XISF_ADDR_SHIFT8);
+ InstancePtr->WriteBufPtr[BYTE5] = (u8) (RealAddr);
+ for(Index = 5U; Index < (ByteCount + XISF_CMD_SEND_EXTRA_BYTES_4BYTE_MODE);
+ Index++) {
+ InstancePtr->WriteBufPtr[Index] = *LocalBufPtr;
+ LocalBufPtr += 1;
+ }
+ } else {
+#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;
+ }
+#if ((XPAR_XISF_FLASH_FAMILY == SPANSION) && \
+ (!defined(XPAR_XISF_INTERFACE_PSQSPI)))
+ }
+#endif
+
+#ifdef XPAR_XISF_INTERFACE_PSQSPI
+ /*
+ * Enable write before transfer
+ */
+ Status = XIsf_WriteEnable(InstancePtr, XISF_WRITE_ENABLE);
+#endif
+ if (InstancePtr->FourByteAddrMode == TRUE) {
+ Status = XIsf_Transfer(InstancePtr, InstancePtr->WriteBufPtr, NULLPtr,
+ (ByteCount + XISF_CMD_SEND_EXTRA_BYTES_4BYTE_MODE));
+ } else {
+ 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;
+}
+
+/*****************************************************************************/
+/**
+*
+* This function Auto rewrites the contents of a Page in the Serial Flash.
+*
+* @param InstancePtr is a pointer to the XIsf instance.
+* @param Address is the address of the page to be refreshed.
+*
+* @return XST_SUCCESS if successful else XST_FAILURE.
+*
+* @note This operation is only supported for Atmel Serial Flash.
+*
+******************************************************************************/
+static int AutoPageWrite(XIsf *InstancePtr, u32 Address)
+{
+ 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;
+ InstancePtr->WriteBufPtr[BYTE2] = (u8) (Address >> XISF_ADDR_SHIFT16);
+ InstancePtr->WriteBufPtr[BYTE3] = (u8) (Address >> XISF_ADDR_SHIFT8);
+ InstancePtr->WriteBufPtr[BYTE4] = (XISF_DUMMYBYTE);
+
+ /*
+ * Initiate the Transfer.
+ */
+ Status = XIsf_Transfer(InstancePtr, InstancePtr->WriteBufPtr, NULL,
+ XISF_CMD_SEND_EXTRA_BYTES);
+ if (Status != (int)XST_SUCCESS) {
+ return (int)XST_FAILURE;
+ }
+#endif /* (XPAR_XISF_FLASH_FAMILY == ATMEL) */
+
+ return Status;
+}
+
+/*****************************************************************************/
+/**
+*
+* This function writes data to the specified SRAM buffer of the Serial Flash.
+*
+* @param InstancePtr is a pointer to the XIsf instance.
+* @param BufferNum specifies the internal SRAM Buffer of the Serial
+* Flash. The valid values are XISF_PAGE_BUFFER1 or
+* XISF_PAGE_BUFFER2. XISF_PAGE_BUFFER2 is not valid in case of
+* Atmel AT45DB011D Serial Flash as it contains a single buffer.
+* @param WritePtr is the pointer to the data to be written to the
+* Serial Flash SRAM Buffer.
+* @param ByteOffset is the byte offset in the buffer from where the
+* data is to be written.
+* @param NumBytes is the number of bytes to be written to the Buffer.
+*
+* @return XST_SUCCESS if successful else XST_FAILURE.
+*
+* @note
+* - A minimum of one byte and a maximum of one SRAM buffer can be
+* written using this function.
+* - This operation is only supported for Atmel Serial Flash.
+*
+******************************************************************************/
+static int BufferWrite(XIsf *InstancePtr, u8 BufferNum, const u8 *WritePtr,
+ u32 ByteOffset, u32 NumBytes)
+{
+ 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;
+
+ /*
+ * Check buffer number is valid or not.
+ */
+ if ((BufferNum == XISF_PAGE_BUFFER1) ||
+ (BufferNum == XISF_PAGE_BUFFER2)) {
+ if ((InstancePtr->DeviceCode == XISF_ATMEL_DEV_AT45DB011D) &&
+ (BufferNum != XISF_PAGE_BUFFER1)) {
+ return (int)XST_FAILURE;
+ }
+ }
+ else{
+ return (int)XST_FAILURE;
+ }
+
+ if (WritePtr == NULL) {
+ return (int)XST_FAILURE;
+ }
+
+ if (ByteOffset > InstancePtr->BytesPerPage) {
+ return (int)XST_FAILURE;
+ }
+
+ if ((NumBytes <= 0) || (NumBytes > InstancePtr->BytesPerPage)) {
+ return (int)XST_FAILURE;
+ }
+
+
+ if (BufferNum == XISF_PAGE_BUFFER1) {
+ InstancePtr->WriteBufPtr[BYTE1] = XISF_CMD_BUFFER1_WRITE;
+ }
+ else{
+ InstancePtr->WriteBufPtr[BYTE1] = XISF_CMD_BUFFER2_WRITE;
+ }
+ InstancePtr->WriteBufPtr[BYTE2] = (u8) (0x00);
+ InstancePtr->WriteBufPtr[BYTE3] = (u8) (ByteOffset >> XISF_ADDR_SHIFT8);
+ InstancePtr->WriteBufPtr[BYTE4] = (u8) ByteOffset;
+
+
+ for(Index = 4; Index < NumBytes + XISF_CMD_SEND_EXTRA_BYTES; Index++) {
+ InstancePtr->WriteBufPtr[Index] = *WritePtr++;
+ }
+
+ /*
+ * Initiate the Transfer.
+ */
+ Status = XIsf_Transfer(InstancePtr, InstancePtr->WriteBufPtr, NULL,
+ (NumBytes + XISF_CMD_SEND_EXTRA_BYTES));
+ if (Status != (int)XST_SUCCESS) {
+ return (int)XST_FAILURE;
+ }
+#endif /* (XPAR_XISF_FLASH_FAMILY == ATMEL) */
+
+ return Status;
+}
+
+/*****************************************************************************/
+/**
+*
+* This function first erases a page and then writes data from the specified
+* internal SRAM buffer to the specified locations in the Serial Flash.
+*
+* @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
+* 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
+* ignored as an entire Page is transferred using this API.
+*
+* @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.
+* - This operation is only supported for Atmel Serial Flash.
+*
+******************************************************************************/
+static int BufferToFlashWriteWithErase(XIsf *InstancePtr, u8 BufferNum,
+ u32 Address)
+{
+ int Status = (int)XST_FAILURE;
+
+ Xil_AssertNonvoid(InstancePtr != NULL);
+ Xil_AssertNonvoid(BufferNum != 0);
+ Xil_AssertNonvoid(Address != 0);
+
+#if (XPAR_XISF_FLASH_FAMILY == ATMEL)
+ /*
+ * Check whether the buffer number is valid or not.
+ */
+ if ((BufferNum == XISF_PAGE_BUFFER1) ||
+ (BufferNum == XISF_PAGE_BUFFER2)) {
+ if ((InstancePtr->DeviceCode == XISF_ATMEL_DEV_AT45DB011D) &&
+ (BufferNum != XISF_PAGE_BUFFER1)) {
+ return (int)XST_FAILURE;
+ }
+ }
+ else {
+ return (int)XST_FAILURE;
+ }
+
+ if (BufferNum == XISF_PAGE_BUFFER1) {
+ /*
+ * Buffer 1 to Page Program With Erase.
+ */
+ InstancePtr->WriteBufPtr[BYTE1] =
+ XISF_CMD_ERASE_BUF1TOPAGE_WRITE;
+ } else {
+ /*
+ * Buffer 2 to Page Program With Erase.
+ */
+ InstancePtr->WriteBufPtr[BYTE1] =
+ XISF_CMD_ERASE_BUF2TOPAGE_WRITE;
+ }
+ InstancePtr->WriteBufPtr[BYTE2] = (u8) (Address >> XISF_ADDR_SHIFT16);
+ InstancePtr->WriteBufPtr[BYTE3] = (u8) (Address >> XISF_ADDR_SHIFT8);
+ InstancePtr->WriteBufPtr[BYTE4] = (u8) (XISF_DUMMYBYTE);
+
+ /*
+ * Initiate the Transfer.
+ */
+ Status = XIsf_Transfer(InstancePtr, InstancePtr->WriteBufPtr, NULL,
+ XISF_CMD_SEND_EXTRA_BYTES);
+ if (Status != (int)XST_SUCCESS) {
+ return (int)XST_FAILURE;
+ }
+#endif /* (XPAR_XISF_FLASH_FAMILY == ATMEL) */
+
+ return Status;
+}
+
+/*****************************************************************************/
+/**
+*
+* This function writes data from the specified internal SRAM buffer to the
+* specified locations in the Serial Flash.
+*
+* @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
+* 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
+* ignored as an entire page of data is transferred using this
+* operation.
+*
+* @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.
+* - This operation is only supported for Atmel Serial Flash.
+*
+******************************************************************************/
+static int BufferToFlashWriteWithoutErase(XIsf *InstancePtr, u8 BufferNum,
+ u32 Address)
+{
+ int Status = (int)XST_FAILURE;
+
+ Xil_AssertNonvoid(InstancePtr != NULL);
+ Xil_AssertNonvoid(BufferNum != 0);
+ Xil_AssertNonvoid(Address != 0);
+
+#if (XPAR_XISF_FLASH_FAMILY == ATMEL)
+ /*
+ * Check whether the buffer number is valid or not.
+ */
+ if ((BufferNum == XISF_PAGE_BUFFER1) ||
+ (BufferNum == XISF_PAGE_BUFFER2)) {
+ if ((InstancePtr->DeviceCode == XISF_ATMEL_DEV_AT45DB011D) &&
+ (XISF_PAGE_BUFFER1 != 1)) {
+ return (int)XST_FAILURE;
+ }
+ }
+ else {
+ return (int)XST_FAILURE;
+ }
+
+ if (BufferNum == XISF_PAGE_BUFFER1) {
+ /*
+ * Buffer 1 to Page Program Without Erase.
+ */
+ InstancePtr->WriteBufPtr[BYTE1] = XISF_CMD_BUF1TOPAGE_WRITE;
+ }
+ else {
+ /*
+ * Buffer 2 to Page Program Without Erase.
+ */
+ InstancePtr->WriteBufPtr[BYTE1] = XISF_CMD_BUF2TOPAGE_WRITE;
+ }
+
+ InstancePtr->WriteBufPtr[BYTE2] = (u8) (Address >> XISF_ADDR_SHIFT16);
+ InstancePtr->WriteBufPtr[BYTE3] = (u8) (Address >> XISF_ADDR_SHIFT8);
+ InstancePtr->WriteBufPtr[BYTE4] = (u8) (XISF_DUMMYBYTE);
+
+ /*
+ * Initiate the Transfer.
+ */
+ Status = XIsf_Transfer(InstancePtr, InstancePtr->WriteBufPtr, NULL,
+ XISF_CMD_SEND_EXTRA_BYTES);
+ if (Status != (int)XST_SUCCESS) {
+ return (int)XST_FAILURE;
+ }
+#endif /* (XPAR_XISF_FLASH_FAMILY == ATMEL) */
+
+ return Status;
+}
+
+/*****************************************************************************/
+/**
+*
+* This function writes data to the Status Register of the Serial Flash.
+*
+* @param InstancePtr is a pointer to the XIsf instance.
+* @param SRData is the value to be written to the Status Register
+* of the Serial Flash.
+*
+* @return XST_SUCCESS if successful else XST_FAILURE.
+*
+* @note This operation is only supported in Intel, STM, Winbond and
+* Spansion Serial Flash. This is the write of Status Register 1
+* for Winbond devices, write of Status Register 2 is handled by
+* WriteSR2.
+*
+******************************************************************************/
+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))
+ /*
+ * Prepare the Write Buffer.
+ */
+ InstancePtr->WriteBufPtr[BYTE1] = XISF_CMD_STATUSREG_WRITE;
+ InstancePtr->WriteBufPtr[BYTE2] = SRData;
+
+ /*
+ * Initiate the Transfer.
+ */
+ Status = XIsf_Transfer(InstancePtr, InstancePtr->WriteBufPtr, NULL,
+ XISF_STATUS_RDWR_BYTES);
+ 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) ||
+ (XPAR_XISF_FLASH_FAMILY == SPANSION)) */
+
+ return Status;
+}
+
+/*****************************************************************************/
+/**
+*
+* 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).
+*
+* @param InstancePtr is a pointer to the XIsf instance.
+* @param SRData is of type (u8*) and points to the 16 bit value to be
+* written to the Status Register of the Serial Flash.
+*
+* @return XST_SUCCESS if successful else XST_FAILURE.
+*
+* @note This operation is only supported in Winbond (W25QXX) Serial
+* Flash.
+*
+******************************************************************************/
+static int WriteSR2(XIsf *InstancePtr, u8 *SRData)
+{
+ int Status = (int)XST_FAILURE;
+
+ Xil_AssertNonvoid(InstancePtr != NULL);
+ Xil_AssertNonvoid(SRData != NULL);
+
+#if (XPAR_XISF_FLASH_FAMILY == WINBOND)
+ /*
+ * Prepare the Write Buffer.
+ */
+ InstancePtr->WriteBufPtr[BYTE1] = XISF_CMD_STATUSREG_WRITE;
+ InstancePtr->WriteBufPtr[BYTE2] = *SRData++;
+ InstancePtr->WriteBufPtr[BYTE3] = *SRData;
+
+ /*
+ * Initiate the Transfer.
+ */
+ Status = XIsf_Transfer(InstancePtr, InstancePtr->WriteBufPtr, NULL,
+ XISF_STATUS_RDWR_BYTES + 1);
+ if (Status != (int)XST_SUCCESS) {
+ return (int)XST_FAILURE;
+ }
+#endif /* (XPAR_XISF_FLASH_FAMILY == WINBOND) */
+
+ return Status;
+}
+
+/*****************************************************************************/
+/**
+*
+* 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 data.
+* @param BufferPtr is the pointer to the data to be written into OTP
+* region of Serial Flash.
+*
+* @return XST_SUCCESS if successful else XST_FAILURE.
+*
+* @note
+* - A minimum of one byte and a maximum of one byte can be
+* written using this function.
+* - This operation is supported only for Intel Serial Flash.
+*
+******************************************************************************/
+static int WriteOTPData(XIsf *InstancePtr, u32 Address, const u8 *BufferPtr)
+{
+ 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 (int)XST_FAILURE;
+ }
+
+ InstancePtr->WriteBufPtr[BYTE1] = XISF_CMD_OTP_WRITE;
+ InstancePtr->WriteBufPtr[BYTE2] = (u8) (Address >> XISF_ADDR_SHIFT16);
+ InstancePtr->WriteBufPtr[BYTE3] = (u8) (Address >> XISF_ADDR_SHIFT8);
+ InstancePtr->WriteBufPtr[BYTE4] = (u8) Address;
+ InstancePtr->WriteBufPtr[BYTE5] = *BufferPtr;
+
+ /*
+ * Initiate the Transfer.
+ */
+ Status = XIsf_Transfer(InstancePtr, InstancePtr->WriteBufPtr, NULL,
+ XISF_OTP_RDWR_EXTRA_BYTES);
+ if (Status != (int)XST_SUCCESS) {
+ return (int)XST_FAILURE;
+ }
+#endif /* (XPAR_XISF_FLASH_FAMILY == INTEL) */
+
+ return Status;
+}