/****************************************************************************** * * * This function erases the sectors in the serial FLASH connected to the SPI * interface. * * @param InstancePtr is a pointer to the XIsf component to use. * @param Address contains the address of the first sector which needs to * be erased. * @param ByteCount contains the total size to be erased. * * @return None. * * @note None. * ******************************************************************************/ int FlashErase(XIsf *InstancePtr, u32 Address, u32 ByteCount) { int Status; int Sector; /* * If the erase size is less than the total size of the flash, use * sector erase command */ for (Sector = 0; Sector < ((ByteCount / SECTOR_SIZE) + 1); Sector++) { /* * Write enable instruction has to be executed prior to * any Write operation. */ WriteEnable(InstancePtr); /* * Perform the Sector Erase operation. */ TransferInProgress = TRUE; Status = XIsf_Erase(InstancePtr, XISF_SECTOR_ERASE, Address); if(Status != XST_SUCCESS) { return XST_FAILURE; } /* * Wait till the Transfer is complete and check if there are any errors * in the transaction. */ while(TransferInProgress); if(ErrorCount != 0) { return XST_FAILURE; } /* * Wait till the Flash is not Busy. */ Status = IsfWaitForFlashNotBusy(); if(Status != XST_SUCCESS) { return XST_FAILURE; } Address += SECTOR_SIZE; } return XST_SUCCESS; }
/** * * Main function to execute the Numonyx Quad Serial Flash Read/Write example. * * @param None * * @return XST_SUCCESS if successful else XST_FAILURE. * * @note None * ******************************************************************************/ int main() { int Status; u32 Index; u32 Address; XIsf_WriteParam WriteParam; XIsf_ReadParam ReadParam; /* * Initialize the SPI driver so that it's ready to use, * specify the device ID that is generated in xparameters.h. */ Status = XSpi_Initialize(&Spi, SPI_DEVICE_ID); if(Status != XST_SUCCESS) { return XST_FAILURE; } /* * Connect the SPI driver to the interrupt subsystem such that * interrupts can occur. This function is application specific. */ Status = SetupInterruptSystem(&Spi); if(Status != XST_SUCCESS) { return XST_FAILURE; } /* * Setup the handler for the SPI that will be called from the interrupt * context when an SPI status occurs, specify a pointer to the SPI * driver instance as the callback reference so the handler is able to * access the instance data. */ XIsf_SetStatusHandler(&Isf, &Spi, (XSpi_StatusHandler)SpiHandler); /* * Start the SPI driver so that interrupts and the device are enabled. */ XSpi_Start(&Spi); /* * Set the QSPI options */ Status = XIsf_SetSpiConfiguration(&Isf, &Spi, XSP_MASTER_OPTION | XSP_MANUAL_SSELECT_OPTION, XISF_SPI_PRESCALER); if(Status != XST_SUCCESS) { return XST_FAILURE; } /* * Initialize the Serial Flash Library. */ Status = XIsf_Initialize(&Isf, &Spi, ISF_SPI_SELECT, IsfWriteBuffer); if(Status != XST_SUCCESS) { return XST_FAILURE; } /* * Set The transfer Mode to Interrupt */ XIsf_SetTransferMode(&Isf,XISF_INTERRUPT_MODE); /* * Specify the address in the Serial Flash for the Erase/Write/Read * operations. */ Address = ISF_TEST_ADDRESS; /* * The following code Erases a Sector in the Numonyx Serial Flash. */ /* * Perform the Write Enable operation. */ TransferInProgress = TRUE; Status = XIsf_WriteEnable(&Isf, XISF_WRITE_ENABLE); if(Status != XST_SUCCESS) { return XST_FAILURE; } /* * Wait till the Transfer is complete and check for errors. */ while(TransferInProgress); if(ErrorCount != 0) { return XST_FAILURE; } /* * Wait till the Flash is not Busy. */ Status = IsfWaitForFlashNotBusy(); if(Status != XST_SUCCESS) { return XST_FAILURE; } /* * Perform the Sector Erase operation. */ TransferInProgress = TRUE; Status = XIsf_Erase(&Isf, XISF_SECTOR_ERASE, Address); if(Status != XST_SUCCESS) { return XST_FAILURE; } /* * Wait till the Transfer is complete and check for errors. */ while(TransferInProgress); if(ErrorCount != 0) { return XST_FAILURE; } /* * Wait till the Flash is not Busy. */ Status = IsfWaitForFlashNotBusy(); if(Status != XST_SUCCESS) { return XST_FAILURE; } /* * Perform the Write Enable operation. */ TransferInProgress = TRUE; Status = XIsf_WriteEnable(&Isf, XISF_WRITE_ENABLE); if(Status != XST_SUCCESS) { return XST_FAILURE; } /* * Wait till the Transfer is complete and check for errors. */ while(TransferInProgress); if(ErrorCount != 0) { return XST_FAILURE; } /* * Wait till the Flash is not Busy. */ Status = IsfWaitForFlashNotBusy(); if(Status != XST_SUCCESS) { return XST_FAILURE; } /* * Set the * - Address within the Serial Flash where the data is to be written. * - Number of bytes to be written to the Serial Flash. * - Write Buffer which contains the data to be written to the Serial * Flash. */ WriteParam.Address = Address; WriteParam.NumBytes = ISF_PAGE_SIZE; WriteParam.WritePtr = WriteBuffer; /* * Prepare the write buffer. Fill in the data need to be written into * Serial Flash. */ for(Index = 0; Index < ISF_PAGE_SIZE; Index++) { WriteParam.WritePtr[Index] = Index + ISF_TEST_BYTE; } /* * Perform the Write operation. */ TransferInProgress = TRUE; Status = XIsf_Write(&Isf, XISF_DUAL_IP_PAGE_WRITE, (void*) &WriteParam); if(Status != XST_SUCCESS) { return XST_FAILURE; } /* * Wait till the Transfer is complete and check for errors. */ while(TransferInProgress); if(ErrorCount != 0) { return XST_FAILURE; } /* * Wait till the Flash is not Busy. */ Status = IsfWaitForFlashNotBusy(); if(Status != XST_SUCCESS) { return XST_FAILURE; } /* * Read from the flash using Dual Output Fast Read command. * Set the * - Address in the Serial Flash where the data is to be read from. * - Number of bytes to be read from the Serial Flash. * - Read Buffer to which the data is to be read. * - Number of dummy bytes for the read command. */ ReadParam.Address = Address; ReadParam.NumBytes = ISF_PAGE_SIZE; ReadParam.ReadPtr = ReadBuffer; ReadParam.NumDummyBytes = DUAL_READ_DUMMY_BYTES; /* * Clear the read Buffer. */ for(Index = 0; Index < ISF_PAGE_SIZE + XISF_CMD_SEND_EXTRA_BYTES + DUAL_READ_DUMMY_BYTES; Index++) { ReadBuffer[Index] = 0x0; } /* * Perform the read operation. */ TransferInProgress = TRUE; Status = XIsf_Read(&Isf, XISF_DUAL_OP_FAST_READ, (void*) &ReadParam); if(Status != XST_SUCCESS) { return XST_FAILURE; } /* * Wait till the Transfer is complete and check for errors. */ while(TransferInProgress); if(ErrorCount != 0) { return XST_FAILURE; } /* * Compare the data read against the data Written. */ for(Index = 0; Index < ISF_PAGE_SIZE; Index++) { if(ReadBuffer[Index + XISF_CMD_SEND_EXTRA_BYTES + DUAL_READ_DUMMY_BYTES] != (u8)(Index + ISF_TEST_BYTE)) { return XST_FAILURE; } } /* * Perform the Write Enable operation. */ TransferInProgress = TRUE; Status = XIsf_WriteEnable(&Isf, XISF_WRITE_ENABLE); if(Status != XST_SUCCESS) { return XST_FAILURE; } /* * Wait till the Transfer is complete and check for errors. */ while(TransferInProgress); if(ErrorCount != 0) { return XST_FAILURE; } /* * Wait till the Flash is not Busy. */ Status = IsfWaitForFlashNotBusy(); if(Status != XST_SUCCESS) { return XST_FAILURE; } /* * Move to the next page in the flash. */ Address += ISF_PAGE_SIZE; /* * Set the * - Address within the Serial Flash where the data is to be written. * - Number of bytes to be written to the Serial Flash. * - Write Buffer which contains the data to be written to the Serial * Flash. */ WriteParam.Address = Address; WriteParam.NumBytes = ISF_PAGE_SIZE; WriteParam.WritePtr = WriteBuffer; /* * Prepare the write buffer. Fill in the data need to be written into * Serial Flash. */ for(Index = 0; Index < ISF_PAGE_SIZE; Index++) { WriteParam.WritePtr[Index] = Index + ISF_TEST_BYTE; } /* * Perform the Write operation. */ TransferInProgress = TRUE; Status = XIsf_Write(&Isf, XISF_DUAL_IP_EXT_PAGE_WRITE, (void*) &WriteParam); if(Status != XST_SUCCESS) { return XST_FAILURE; } /* * Wait till the Transfer is complete and check for errors. */ while(TransferInProgress); if(ErrorCount != 0) { return XST_FAILURE; } /* * Wait till the Flash is not Busy. */ Status = IsfWaitForFlashNotBusy(); if(Status != XST_SUCCESS) { return XST_FAILURE; } /* * Read from the flash using Dual Input/Output Fast Read command. * Set the * - Address in the Serial Flash where the data is to be read from. * - Number of bytes to be read from the Serial Flash. * - Read Buffer to which the data is to be read. * - Number of dummy bytes for the read command. */ ReadParam.Address = Address; ReadParam.NumBytes = ISF_PAGE_SIZE; ReadParam.ReadPtr = ReadBuffer; ReadParam.NumDummyBytes = DUAL_IO_READ_DUMMY_BYTES; /* * Clear the read Buffer. */ for(Index = 0; Index < ISF_PAGE_SIZE + XISF_CMD_SEND_EXTRA_BYTES + DUAL_IO_READ_DUMMY_BYTES; Index++) { ReadBuffer[Index] = 0x0; } /* * Perform the read operation. */ TransferInProgress = TRUE; Status = XIsf_Read(&Isf, XISF_DUAL_IO_FAST_READ, (void*) &ReadParam); if(Status != XST_SUCCESS) { return XST_FAILURE; } /* * Wait till the Transfer is complete and check for errors. */ while(TransferInProgress); if(ErrorCount != 0) { return XST_FAILURE; } /* * Compare the data read against the data Written. */ for(Index = 0; Index < ISF_PAGE_SIZE; Index++) { if(ReadBuffer[Index + XISF_CMD_SEND_EXTRA_BYTES + DUAL_IO_READ_DUMMY_BYTES] != (u8)(Index + ISF_TEST_BYTE)) { return XST_FAILURE; } } /* * Perform the Write Enable operation. */ TransferInProgress = TRUE; Status = XIsf_WriteEnable(&Isf, XISF_WRITE_ENABLE); if(Status != XST_SUCCESS) { return XST_FAILURE; } /* * Wait till the Transfer is complete and check for errors. */ while(TransferInProgress); if(ErrorCount != 0) { return XST_FAILURE; } /* * Wait till the Flash is not Busy. */ Status = IsfWaitForFlashNotBusy(); if(Status != XST_SUCCESS) { return XST_FAILURE; } /* * Move to the next page in the flash. */ Address += ISF_PAGE_SIZE; /* * Set the * - Address within the Serial Flash where the data is to be written. * - Number of bytes to be written to the Serial Flash. * - Write Buffer which contains the data to be written to the Serial * Flash. */ WriteParam.Address = Address; WriteParam.NumBytes = ISF_PAGE_SIZE; WriteParam.WritePtr = WriteBuffer; /* * Prepare the write buffer. Fill in the data need to be written into * Serial Flash. */ for(Index = 0; Index < ISF_PAGE_SIZE; Index++) { WriteParam.WritePtr[Index] = Index + ISF_TEST_BYTE; } /* * Perform the Write operation. */ TransferInProgress = TRUE; Status = XIsf_Write(&Isf, XISF_QUAD_IP_PAGE_WRITE, (void*) &WriteParam); if(Status != XST_SUCCESS) { return XST_FAILURE; } /* * Wait till the Transfer is complete and check for errors. */ while(TransferInProgress); if(ErrorCount != 0) { return XST_FAILURE; } /* * Wait till the Flash is not Busy. */ Status = IsfWaitForFlashNotBusy(); if(Status != XST_SUCCESS) { return XST_FAILURE; } /* * Read from the flash using Quad Output Fast Read command. * Set the * - Address in the Serial Flash where the data is to be read from. * - Number of bytes to be read from the Serial Flash. * - Read Buffer to which the data is to be read. * - Number of dummy bytes for the read command. */ ReadParam.Address = Address; ReadParam.NumBytes = ISF_PAGE_SIZE; ReadParam.ReadPtr = ReadBuffer; ReadParam.NumDummyBytes = QUAD_READ_DUMMY_BYTES; /* * Clear the read Buffer. */ for(Index = 0; Index < ISF_PAGE_SIZE + XISF_CMD_SEND_EXTRA_BYTES + QUAD_READ_DUMMY_BYTES; Index++) { ReadBuffer[Index] = 0x0; } /* * Perform the read operation. */ TransferInProgress = TRUE; Status = XIsf_Read(&Isf, XISF_QUAD_OP_FAST_READ, (void*) &ReadParam); if(Status != XST_SUCCESS) { return XST_FAILURE; } /* * Wait till the Transfer is complete and check for errors. */ while(TransferInProgress); if(ErrorCount != 0) { return XST_FAILURE; } /* * Compare the data read against the data Written. */ for(Index = 0; Index < ISF_PAGE_SIZE; Index++) { if(ReadBuffer[Index + XISF_CMD_SEND_EXTRA_BYTES + QUAD_READ_DUMMY_BYTES] != (u8)(Index + ISF_TEST_BYTE)) { return XST_FAILURE; } } /* * Perform the Write Enable operation. */ TransferInProgress = TRUE; Status = XIsf_WriteEnable(&Isf, XISF_WRITE_ENABLE); if(Status != XST_SUCCESS) { return XST_FAILURE; } /* * Wait till the Transfer is complete and check for errors. */ while(TransferInProgress); if(ErrorCount != 0) { return XST_FAILURE; } /* * Wait till the Flash is not Busy. */ Status = IsfWaitForFlashNotBusy(); if(Status != XST_SUCCESS) { return XST_FAILURE; } /* * Move to the next page in the flash. */ Address += ISF_PAGE_SIZE; /* * Set the * - Address within the Serial Flash where the data is to be written. * - Number of bytes to be written to the Serial Flash. * - Write Buffer which contains the data to be written to the Serial * Flash. */ WriteParam.Address = Address; WriteParam.NumBytes = ISF_PAGE_SIZE; WriteParam.WritePtr = WriteBuffer; /* * Prepare the write buffer. Fill in the data need to be written into * Serial Flash. */ for(Index = 0; Index < ISF_PAGE_SIZE; Index++) { WriteParam.WritePtr[Index] = Index + ISF_TEST_BYTE; } /* * Perform the Write operation. */ TransferInProgress = TRUE; Status = XIsf_Write(&Isf, XISF_QUAD_IP_EXT_PAGE_WRITE, (void*) &WriteParam); if(Status != XST_SUCCESS) { return XST_FAILURE; } /* * Wait till the Transfer is complete and check for errors. */ while(TransferInProgress); if(ErrorCount != 0) { return XST_FAILURE; } /* * Wait till the Flash is not Busy. */ Status = IsfWaitForFlashNotBusy(); if(Status != XST_SUCCESS) { return XST_FAILURE; } /* * Read from the flash using Quad Input/Output Fast Read command. * Set the * - Address in the Serial Flash where the data is to be read from. * - Number of bytes to be read from the Serial Flash. * - Read Buffer to which the data is to be read. * - Number of dummy bytes for the read command. */ ReadParam.Address = Address; ReadParam.NumBytes = ISF_PAGE_SIZE; ReadParam.ReadPtr = ReadBuffer; ReadParam.NumDummyBytes = QUAD_IO_READ_DUMMY_BYTES; /* * Clear the read Buffer. */ for(Index = 0; Index < ISF_PAGE_SIZE + XISF_CMD_SEND_EXTRA_BYTES + QUAD_IO_READ_DUMMY_BYTES; Index++) { ReadBuffer[Index] = 0x0; } /* * Perform the read operation. */ TransferInProgress = TRUE; Status = XIsf_Read(&Isf, XISF_QUAD_IO_FAST_READ, (void*) &ReadParam); if(Status != XST_SUCCESS) { return XST_FAILURE; } /* * Wait till the Transfer is complete and check for errors. */ while(TransferInProgress); if(ErrorCount != 0) { return XST_FAILURE; } /* * Compare the data read against the data written. */ for(Index = 0; Index < ISF_PAGE_SIZE; Index++) { if(ReadBuffer[Index + XISF_CMD_SEND_EXTRA_BYTES + QUAD_IO_READ_DUMMY_BYTES] != (u8)(Index + ISF_TEST_BYTE)) { return XST_FAILURE; } } return XST_SUCCESS; }
/** * * Main function to execute the Atmel Serial Flash Read/Write example. * * @param None. * * @return XST_SUCCESS if successful else XST_FAILURE. * * @note None. * ******************************************************************************/ int main(void) { int Status; u16 Index; XIsf_WriteParam WriteParam; XIsf_ReadParam ReadParam; u32 Address; /* * Initialize the SPI driver so that it's ready to use, * specify the device ID that is generated in xparameters.h. */ Status = XSpi_Initialize(&Spi, SPI_DEVICE_ID); if(Status != XST_SUCCESS) { return XST_FAILURE; } /* * Connect the SPI driver to the interrupt subsystem such that * interrupts can occur. This function is application specific. */ Status = SetupInterruptSystem(&Spi); if(Status != XST_SUCCESS) { return XST_FAILURE; } /* * Setup the handler for the SPI that will be called from the interrupt * context when an SPI status occurs, specify a pointer to the SPI * driver instance as the callback reference so the handler is able to * access the instance data. */ XIsf_SetStatusHandler(&Isf, &Spi, (XSpi_StatusHandler)SpiHandler); /* * Start the SPI driver so that interrupts and the device are enabled. */ Status = XSpi_Start(&Spi); if(Status != XST_SUCCESS) { return XST_FAILURE; } /* * Initialize the In-system and Serial Flash Library. */ Status = XIsf_Initialize(&Isf, &Spi, ISF_SPI_SELECT, IsfWriteBuffer); if(Status != XST_SUCCESS) { return XST_FAILURE; } /* * Set The transfer Mode to Interrupt */ XIsf_SetTransferMode(&Isf,XISF_INTERRUPT_MODE); /* * Specify the address in the Serial Flash for the Erase/Write/Read * operations. */ Address = TEST_ADDRESS; /* * Perform the Page Erase operation. */ TransferInProgress = TRUE; Status = XIsf_Erase(&Isf, XISF_PAGE_ERASE, Address); if(Status != XST_SUCCESS) { return XST_FAILURE; } /* * Wait till the Transfer is complete and check for any errors. */ while(TransferInProgress); if(ErrorCount != 0) { return XST_FAILURE; } /* * Wait till the Serial Flash is ready. */ Status = IsfWaitForFlashNotBusy(); if(Status != XST_SUCCESS) { return XST_FAILURE; } /* * Set the * - Address within the Serial Flash where the data is to be written. * - The number of bytes to be written to the Serial Flash. * - Write Buffer which contains the data to be written to the Serial * Flash. */ WriteParam.Address = Address; WriteParam.NumBytes = ISF_PAGE_SIZE; WriteParam.WritePtr = WriteBuffer; /* * Prepare the write buffer. Fill in the data need to be written into * Serial Flash. */ for(Index = 0; Index < ISF_PAGE_SIZE; Index++) { WriteParam.WritePtr[Index] = Index + ISF_TEST_BYTE; } /* * Perform the Write operation. */ TransferInProgress = TRUE; Status = XIsf_Write(&Isf, XISF_WRITE, (void*) &WriteParam); if(Status != XST_SUCCESS) { return XST_FAILURE; } /* * Wait till the Transfer is complete and check for any errors. */ while(TransferInProgress); if(ErrorCount != 0) { return XST_FAILURE; } /* * Wait till the Serial Flash is ready. */ Status = IsfWaitForFlashNotBusy(); if(Status != XST_SUCCESS) { return XST_FAILURE; } /* * Set the * - Address in the Serial Flash where the data is to be read from. * - Number of bytes to be read from the Serial Flash. * - Read Buffer to which the data is to be read. */ ReadParam.Address = Address; ReadParam.NumBytes = ISF_PAGE_SIZE; ReadParam.ReadPtr = ReadBuffer; /* * Perform the Read operation. */ TransferInProgress = TRUE; Status = XIsf_Read(&Isf, XISF_READ, (void*) &ReadParam); if(Status != XST_SUCCESS) { return XST_FAILURE; } /* * Wait till the Transfer is complete and check for any errors. */ while(TransferInProgress); if(ErrorCount != 0) { return XST_FAILURE; } /* * Compare the Data Read with the Data Written to the Serial Flash. */ for(Index = 0; Index < ISF_PAGE_SIZE; Index++) { if(ReadParam.ReadPtr[Index + XISF_CMD_SEND_EXTRA_BYTES] != (u8)(Index + ISF_TEST_BYTE)) { return XST_FAILURE; } } return XST_SUCCESS; }
/** * * Main function to execute the Intel Serial Flash SPR example. * * @param None * * @return XST_SUCCESS if successful else XST_FAILURE. * * @note None * ******************************************************************************/ int main() { int Status; u32 Index; u32 Address; u8 StatusReg; XIsf_WriteParam WriteParam; XIsf_ReadParam ReadParam; /* * Initialize the SPI driver so that it's ready to use, * specify the device ID that is generated in xparameters.h. */ Status = XSpi_Initialize(&Spi, SPI_DEVICE_ID); if(Status != XST_SUCCESS) { return XST_FAILURE; } /* * Connect the SPI driver to the interrupt subsystem such that * interrupts can occur. This function is application specific. */ Status = SetupInterruptSystem(&Spi); if(Status != XST_SUCCESS) { return XST_FAILURE; } /* * Setup the handler for the SPI that will be called from the interrupt * context when an SPI status occurs, specify a pointer to the SPI * driver instance as the callback reference so the handler is able to * access the instance data. */ XIsf_SetStatusHandler(&Isf, &Spi, (XSpi_StatusHandler)SpiHandler); /* * Start the SPI driver so that interrupts and the device are enabled. */ XSpi_Start(&Spi); /* * Initialize the Serial Flash Library. */ Status = XIsf_Initialize(&Isf, &Spi, ISF_SPI_SELECT, IsfWriteBuffer); if(Status != XST_SUCCESS) { return XST_FAILURE; } /* * Set The transfer Mode to Interrupt */ XIsf_SetTransferMode(&Isf,XISF_INTERRUPT_MODE); /* * Perform the Write Enable operation. */ TransferInProgress = TRUE; Status = XIsf_WriteEnable(&Isf, XISF_WRITE_ENABLE); if(Status != XST_SUCCESS) { return XST_FAILURE; } /* * Wait till the Transfer is complete and check if there are any errors * in the transaction. */ while(TransferInProgress); if(ErrorCount != 0) { return XST_FAILURE; } /* * Wait till the Flash is not Busy. */ Status = IsfWaitForFlashNotBusy(); if(Status != XST_SUCCESS) { return XST_FAILURE; } /* * Read the sector protection register. */ TransferInProgress = TRUE; Status = XIsf_SectorProtect(&Isf, XISF_SPR_READ, ReadBuffer); if(Status != XST_SUCCESS) { return XST_FAILURE; } /* * Wait till the Transfer is complete and check if there are any errors * in the transaction. */ while(TransferInProgress); if(ErrorCount != 0) { return XST_FAILURE; } /* * Clear all the block protection bits in the sector protection register * value read above. */ WriteBuffer[BYTE1] = ReadBuffer[BYTE2] & (~(XISF_SR_BLOCK_PROTECT_MASK)); /* * Write this value to the sector protection register to disable the * sector protection. */ TransferInProgress = TRUE; Status = XIsf_SectorProtect(&Isf, XISF_SPR_WRITE, WriteBuffer); if(Status != XST_SUCCESS) { return XST_FAILURE; } /* * Wait till the Transfer is complete and check if there are any errors * in the transaction. */ while(TransferInProgress); if(ErrorCount != 0) { return XST_FAILURE; } /* * Wait till the Flash is not Busy. */ Status = IsfWaitForFlashNotBusy(); if(Status != XST_SUCCESS) { return XST_FAILURE; } /* * Specify the address in the Serial Flash for the Erase/Write/Read * operations. */ Address = ISF_TEST_ADDRESS; /* * Perform the Write Enable operation. */ TransferInProgress = TRUE; Status = XIsf_WriteEnable(&Isf, XISF_WRITE_ENABLE); if(Status != XST_SUCCESS) { return XST_FAILURE; } /* * Wait till the Transfer is complete and check if there are any errors * in the transaction. */ while(TransferInProgress); if(ErrorCount != 0) { return XST_FAILURE; } /* * Wait till the Flash is not Busy. */ Status = IsfWaitForFlashNotBusy(); if(Status != XST_SUCCESS) { return XST_FAILURE; } /* * Perform the Sector Erase operation. */ TransferInProgress = TRUE; Status = XIsf_Erase(&Isf, XISF_SECTOR_ERASE, Address); if(Status != XST_SUCCESS) { return XST_FAILURE; } /* * Wait till the Transfer is complete and check if there are any errors * in the transaction. */ while(TransferInProgress); if(ErrorCount != 0) { return XST_FAILURE; } /* * Wait till the Flash is not Busy. */ Status = IsfWaitForFlashNotBusy(); if(Status != XST_SUCCESS) { return XST_FAILURE; } /* * Perform the Write Enable operation. */ TransferInProgress = TRUE; Status = XIsf_WriteEnable(&Isf, XISF_WRITE_ENABLE); if(Status != XST_SUCCESS) { return XST_FAILURE; } /* * Wait till the Transfer is complete and check if there are any errors * in the transaction. */ while(TransferInProgress); if(ErrorCount != 0) { return XST_FAILURE; } /* * Wait till the Flash is not Busy. */ Status = IsfWaitForFlashNotBusy(); if(Status != XST_SUCCESS) { return XST_FAILURE; } /* * - Set the address within the Serial Flash where the data is to be * written. * - Set the number of bytes to be written to the Serial Flash. * - Write Buffer which contains the data to be written to the Serial * Flash. */ WriteParam.Address = Address; WriteParam.NumBytes = ISF_PAGE_SIZE; WriteParam.WritePtr = WriteBuffer; /* * Prepare the write buffer. Fill in the data need to be written into * Serial Flash. */ for(Index = 0; Index < ISF_PAGE_SIZE; Index++) { WriteParam.WritePtr[Index] = Index + ISF_TEST_BYTE; } /* * Perform the Write operation. */ TransferInProgress = TRUE; Status = XIsf_Write(&Isf, XISF_WRITE, (void*) &WriteParam); if(Status != XST_SUCCESS) { return XST_FAILURE; } /* * Wait till the Transfer is complete and check if there are any errors * in the transaction. */ while(TransferInProgress); if(ErrorCount != 0) { return XST_FAILURE; } /* * Wait till the Flash is not Busy. */ Status = IsfWaitForFlashNotBusy(); if(Status != XST_SUCCESS) { return XST_FAILURE; } /* * Perform the Write Enable operation. */ TransferInProgress = TRUE; Status = XIsf_WriteEnable(&Isf, XISF_WRITE_ENABLE); if(Status != XST_SUCCESS) { return XST_FAILURE; } /* * Wait till the Transfer is complete and check if there are any errors * in the transaction. */ while(TransferInProgress); if(ErrorCount != 0) { return XST_FAILURE; } /* * Wait till the Flash is not Busy. */ Status = IsfWaitForFlashNotBusy(); if(Status != XST_SUCCESS) { return XST_FAILURE; } /* * Read the sector protection register. */ TransferInProgress = TRUE; Status = XIsf_SectorProtect(&Isf, XISF_SPR_READ, ReadBuffer); if(Status != XST_SUCCESS) { return XST_FAILURE; } /* * Wait till the Transfer is complete and check if there are any errors * in the transaction. */ while(TransferInProgress); if(ErrorCount != 0) { return XST_FAILURE; } /* * Set all the block protection bits in the sector protection register * value read above and write it back to the sector protection register. */ WriteBuffer[BYTE1] = ReadBuffer[BYTE2] | (XISF_SR_BLOCK_PROTECT_MASK); /* * Enable the sector protection. */ TransferInProgress = TRUE; Status = XIsf_SectorProtect(&Isf, XISF_SPR_WRITE, WriteBuffer); if(Status != XST_SUCCESS) { return XST_FAILURE; } /* * Wait till the Transfer is complete and check if there are any errors * in the transaction. */ while(TransferInProgress); if(ErrorCount != 0) { return XST_FAILURE; } /* * Wait till the Flash is not Busy. */ Status = IsfWaitForFlashNotBusy(); if(Status != XST_SUCCESS) { return XST_FAILURE; } /* * Perform the Write Enable operation. */ TransferInProgress = TRUE; Status = XIsf_WriteEnable(&Isf, XISF_WRITE_ENABLE); if(Status != XST_SUCCESS) { return XST_FAILURE; } /* * Wait till the Transfer is complete and check if there are any errors * in the transaction. */ while(TransferInProgress); if(ErrorCount != 0) { return XST_FAILURE; } /* * Wait till the Flash is not Busy. */ Status = IsfWaitForFlashNotBusy(); if(Status != XST_SUCCESS) { return XST_FAILURE; } /* * Perform the Sector Erase operation. This should not work as writes to * the Serial Flash are disabled. */ TransferInProgress = TRUE; Status = XIsf_Erase(&Isf, XISF_SECTOR_ERASE, Address); if(Status != XST_SUCCESS) { return XST_FAILURE; } /* * Wait till the Transfer is complete and check if there are any errors * in the transaction. */ while(TransferInProgress); if(ErrorCount != 0) { return XST_FAILURE; } /* * Wait till the Flash is not Busy. */ Status = IsfWaitForFlashNotBusy(); if(Status != XST_SUCCESS) { return XST_FAILURE; } /* * Read the Status Register. */ TransferInProgress = TRUE; Status = XIsf_GetStatus(&Isf, ReadBuffer); if(Status != XST_SUCCESS) { return XST_FAILURE; } /* * Wait till the Transfer is in progress. */ while(TransferInProgress); /* * Check if there are any errors in the transaction. */ if(ErrorCount != 0) { return XST_FAILURE; } /* * Check if the erase fail flag is set in the status register. This flag * should be set as a sector erase operation was attempted when sector * protection was enabled. */ StatusReg = ReadBuffer[BYTE2]; if((StatusReg & XISF_SR_ERASE_FAIL_MASK) == 0) { return XST_FAILURE; } /* * Clear the status register fail flags in the Serial Flash status * register. */ TransferInProgress = TRUE; Status = XIsf_Ioctl(&Isf, XISF_IOCTL_CLEAR_SR_FAIL_FLAGS); if(Status != XST_SUCCESS) { return XST_FAILURE; } /* * Wait till the Transfer is complete and check if there are any errors * in the transaction. */ while(TransferInProgress); if(ErrorCount != 0) { return XST_FAILURE; } /* * Wait till the Flash is not Busy. */ Status = IsfWaitForFlashNotBusy(); if(Status != XST_SUCCESS) { return XST_FAILURE; } /* * Read the Status Register. */ TransferInProgress = TRUE; Status = XIsf_GetStatus(&Isf, ReadBuffer); if(Status != XST_SUCCESS) { return XST_FAILURE; } /* * Wait till the Transfer is in progress. */ while(TransferInProgress); /* * Check if there are any errors in the transaction. */ if(ErrorCount != 0) { return XST_FAILURE; } /* * Check if the erase fail flag is clear in the status register. This * flag should be clear as a 'Clear SR Fail Flags' command has been * executed. */ StatusReg = ReadBuffer[BYTE2]; if((StatusReg & XISF_SR_ERASE_FAIL_MASK) != 0) { return XST_FAILURE; } /* * Read the sector protection register. */ TransferInProgress = TRUE; Status = XIsf_SectorProtect(&Isf, XISF_SPR_READ, ReadBuffer); if(Status != XST_SUCCESS) { return XST_FAILURE; } /* * Wait till the Transfer is complete and check if there are any errors * in the transaction. */ while(TransferInProgress); if(ErrorCount != 0) { return XST_FAILURE; } /* * Clear all the block protection bits in the sector protection register * value read above and write it back to the sector protection register * to disable sector protection for all sectors. */ WriteBuffer[BYTE1] = ReadBuffer[BYTE2] & ~(XISF_SR_BLOCK_PROTECT_MASK); /* * Disable the sector protection. */ TransferInProgress = TRUE; Status = XIsf_SectorProtect(&Isf, XISF_SPR_WRITE, WriteBuffer); if(Status != XST_SUCCESS) { return XST_FAILURE; } /* * Wait till the Transfer is complete and check if there are any errors * in the transaction. */ while(TransferInProgress); if(ErrorCount != 0) { return XST_FAILURE; } /* * Wait till the Flash is not Busy. */ Status = IsfWaitForFlashNotBusy(); if(Status != XST_SUCCESS) { return XST_FAILURE; } /* * The following code Reads data from a Page in the Intel Serial Flash. */ /* * Set the * - Address in the Serial Flash where the data is to be read from. * - Number of bytes to be read from the Serial Flash. * - Read Buffer to which the data is to be read. */ ReadParam.Address = Address; ReadParam.NumBytes = ISF_PAGE_SIZE; ReadParam.ReadPtr = ReadBuffer; /* * Perform the read operation. */ TransferInProgress = TRUE; Status = XIsf_Read(&Isf, XISF_READ, (void*) &ReadParam); if(Status != XST_SUCCESS) { return XST_FAILURE; } /* * Wait till the Transfer is complete and check if there are any errors * in the transaction. */ while(TransferInProgress); if(ErrorCount != 0) { return XST_FAILURE; } /* * Compare the data read against the data Written. */ for(Index = 0; Index < ISF_PAGE_SIZE; Index++) { if(ReadBuffer[Index + XISF_CMD_SEND_EXTRA_BYTES] != (u8)(Index + ISF_TEST_BYTE)) { return XST_FAILURE; } } return XST_SUCCESS; }
/** * * This function erases the sectors in the serial FLASH connected to the * QSPI interface. * * @param InstancePtr is a pointer to the XIsf component to use. * @param Address contains the address of the first sector which needs to * be erased. * @param ByteCount contains the total size to be erased. * * @return None. * * @note None. * ******************************************************************************/ int FlashErase(XIsf *InstancePtr, u32 Address, u32 ByteCount) { int Status; int Sector; u32 LqspiCr; u32 NumSect; u32 SectorSize; u32 NumSectors; u32 Sector_Mask; /* * Get the value of Sector Size and Number of Sectors for the flash */ SectorSize = Isf.SectorSize; NumSectors = Isf.NumSectors; /* Get the sector mask value */ Sector_Mask = SectorMask(SectorSize); /* * If erase size is same as the total size of the flash, use bulk erase * command */ if (ByteCount == (NumSectors * SectorSize)) { #ifdef XPAR_XQSPIPS_0_DEVICE_ID if(ConfigPtr->ConnectionMode == XQSPIPS_CONNECTION_MODE_STACKED){ /* * Get the current LQSPI configuration register value */ LqspiCr = XQspiPs_GetLqspiConfigReg(InstancePtr->SpiInstPtr); /* * Set selection to L_PAGE */ XQspiPs_SetLqspiConfigReg(InstancePtr->SpiInstPtr, LqspiCr & (~XQSPIPS_LQSPI_CR_U_PAGE_MASK)); /* * Assert the Flash chip select. */ XQspiPs_SetSlaveSelect(InstancePtr->SpiInstPtr); } #endif /*XPAR_XQSPIPS_0_DEVICE_ID*/ /* * Call Bulk erase */ Status = XIsf_Erase(InstancePtr, XISF_BULK_ERASE, Address); if(Status != XST_SUCCESS) { return XST_FAILURE; } #ifdef XPAR_XQSPIPS_0_DEVICE_ID /* * If stacked mode, bulk erase second flash */ if(ConfigPtr->ConnectionMode == XQSPIPS_CONNECTION_MODE_STACKED){ /* * Get the current LQSPI configuration register value */ LqspiCr = XQspiPs_GetLqspiConfigReg(InstancePtr->SpiInstPtr); /* * Set selection to U_PAGE */ XQspiPs_SetLqspiConfigReg(InstancePtr->SpiInstPtr, LqspiCr | XQSPIPS_LQSPI_CR_U_PAGE_MASK); /* * Assert the Flash chip select. */ XQspiPs_SetSlaveSelect(InstancePtr->SpiInstPtr); /* * Call Bulk erase */ Status = XIsf_Erase(InstancePtr, XISF_BULK_ERASE, Address); if(Status != XST_SUCCESS) { return XST_FAILURE; } } #endif /*XPAR_XQSPIPS_0_DEVICE_ID*/ return Status; } /* * Calculate no. of sectors to erase based on byte count */ NumSect = ByteCount/SectorSize + 1; /* * If ByteCount to k sectors, * but the address range spans from N to N+k+1 sectors, then * increment no. of sectors to be erased */ if( ((Address + ByteCount) & Sector_Mask) == ((Address + (NumSect * SectorSize)) & Sector_Mask) ) { NumSect++; } /* * If the erase size is less than the total size of the flash, use * sector erase command */ for (Sector = 0; Sector < NumSect; Sector++) { /* * Perform the Sector Erase operation. */ Status = XIsf_Erase(InstancePtr, XISF_SECTOR_ERASE, Address); if(Status != XST_SUCCESS) { return XST_FAILURE; } Address += SectorSize; } return XST_SUCCESS; }