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