/***************************************************************************** * * The purpose of this function is to illustrate how to use the XSpiPs * device driver in interrupt mode. This function writes and reads data * from a serial FLASH. * * @param None. * * @return XST_SUCCESS if successful else XST_FAILURE. * * @note * * This function calls other functions which contain loops that may be infinite * if interrupts are not working such that it may not return. If the device * slave select is not correct and the device is not responding on bus it will * read a status of 0xFF for the status register as the bus is pulled up. * *****************************************************************************/ int SpiFlashIntrExample(XScuGic *IntcInstancePtr, XSpiPs *SpiInstancePtr, u16 SpiDeviceId, u16 SpiIntrId) { int Status; u8 *BufferPtr; u8 UniqueValue; u32 Count; XSpiPs_Config *ConfigPtr; /* Pointer to Configuration ROM data */ u32 TempAddress; u32 MaxSize = MAX_DATA; u32 ChipSelect = FLASH_SPI_SELECT_1; if (XGetPlatform_Info() == XPLAT_ZYNQ_ULTRA_MP) { MaxSize = 1024 * 10; ChipSelect = FLASH_SPI_SELECT_0; /* Device is on CS 0 */ SpiIntrId = XPAR_XSPIPS_0_INTR; } /* * Lookup the device configuration in the temporary CROM table. Use this * configuration info down below when initializing this component. */ ConfigPtr = XSpiPs_LookupConfig(SpiDeviceId); if (ConfigPtr == NULL) { return XST_DEVICE_NOT_FOUND; } XSpiPs_CfgInitialize(SpiInstancePtr, ConfigPtr, ConfigPtr->BaseAddress); /* Initialize the XILISF Library */ XIsf_Initialize(&Isf, SpiInstancePtr, ChipSelect, IsfWriteBuffer); XIsf_SetTransferMode(&Isf, XISF_INTERRUPT_MODE); /* * Connect the Spi device to the interrupt subsystem such that * interrupts can occur. This function is application specific */ Status = SpiSetupIntrSystem(IntcInstancePtr, SpiInstancePtr, SpiIntrId); if (Status != XST_SUCCESS) { return XST_FAILURE; } /* * Setup the handler for the SPI that will be called from the * interrupt context when an SPI status occurs, specify a pointer to * the SPI driver instance as the callback reference so the handler is * able to access the instance data */ XIsf_SetStatusHandler(&Isf, SpiInstancePtr, (XSpiPs_StatusHandler) SpiHandler); memset(WriteBuffer, 0x00, sizeof(WriteBuffer)); memset(ReadBuffer, 0x00, sizeof(ReadBuffer)); /* Unprotect Sectors */ FlashWrite(&Isf, 0, 0, XISF_WRITE_STATUS_REG); FlashErase(&Isf, TEST_ADDRESS, MaxSize); /* * Initialize the write buffer for a pattern to write to the FLASH * and the read buffer to zero so it can be verified after the read, the * test value that is added to the unique value allows the value to be * changed in a debug environment to guarantee */ TempAddress = TEST_ADDRESS; for (UniqueValue = UNIQUE_VALUE, Count = 0; Count < MaxSize; Count++, UniqueValue++, TempAddress++) { WriteBuffer[0] = (u8)(UniqueValue); FlashWrite(&Isf, TempAddress, 1, XISF_WRITE); } /* * Read the contents of the FLASH from TEST_ADDRESS, using Normal Read * command */ FlashRead(&Isf, TEST_ADDRESS, MaxSize, XISF_READ); /* * Setup a pointer to the start of the data that was read into the read * buffer and verify the data read is the data that was written */ BufferPtr = &ReadBuffer[DATA_OFFSET]; for (UniqueValue = UNIQUE_VALUE, Count = 0; Count < MaxSize; Count++, UniqueValue++) { if (BufferPtr[Count] != (u8)(UniqueValue)) { return XST_FAILURE; } } SpiDisableIntrSystem(IntcInstancePtr, SpiIntrId); return XST_SUCCESS; }
int SpiFlashPolledExample(XSpiPs *SpiInstancePtr, u16 SpiDeviceId) { u8 *BufferPtr; u8 UniqueValue; u32 Count; XSpiPs_Config *ConfigPtr; /* Pointer to Configuration ROM data */ u32 TempAddress; /* * Lookup the device configuration in the temporary CROM table. Use this * configuration info down below when initializing this component. */ ConfigPtr = XSpiPs_LookupConfig(SpiDeviceId); if (ConfigPtr == NULL) { return XST_DEVICE_NOT_FOUND; } XSpiPs_CfgInitialize(SpiInstancePtr, ConfigPtr, ConfigPtr->BaseAddress); /* Initialize the XILISF Library */ XIsf_Initialize(&Isf, SpiInstancePtr, FLASH_SPI_SELECT, IsfWriteBuffer); memset(WriteBuffer, 0x00, sizeof(WriteBuffer)); memset(ReadBuffer, 0x00, sizeof(ReadBuffer)); /* Unprotect Sectors */ FlashWrite(&Isf, 0, 0, XISF_WRITE_STATUS_REG); FlashErase(&Isf, TEST_ADDRESS, MAX_DATA); /* * Initialize the write buffer for a pattern to write to the FLASH * and the read buffer to zero so it can be verified after the read, the * test value that is added to the unique value allows the value to be * changed in a debug environment to guarantee */ TempAddress = TEST_ADDRESS; for (UniqueValue = UNIQUE_VALUE, Count = 0; Count < MAX_DATA; Count++, UniqueValue++, TempAddress++) { WriteBuffer[0] = (u8)(UniqueValue); FlashWrite(&Isf, TempAddress, 1, XISF_WRITE); } /* * Read the contents of the FLASH from TEST_ADDRESS, using Normal Read * command */ FlashRead(&Isf, TEST_ADDRESS, MAX_DATA, XISF_READ); /* * Setup a pointer to the start of the data that was read into the read * buffer and verify the data read is the data that was written */ BufferPtr = &ReadBuffer[DATA_OFFSET]; for (UniqueValue = UNIQUE_VALUE, Count = 0; Count < MAX_DATA; Count++, UniqueValue++) { if (BufferPtr[Count] != (u8)(UniqueValue)) { return XST_FAILURE; } } return XST_SUCCESS; }
/** * * 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 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; }
/** * * 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; }
/** * The purpose of this function is to illustrate how to use the XQspiPs * device driver in interrupt mode. This function writes and reads data * from a serial FLASH. * * @return XST_SUCCESS if successful else XST_FAILURE. * * @note * * This function calls other functions which contain loops that may be infinite * if interrupts are not working such that it may not return. If the device * slave select is not correct and the device is not responding on bus it will * read a status of 0xFF for the status register as the bus is pulled up. * *****************************************************************************/ int QspiFlashPollExample(XScuGic *IntcInstancePtr, XQspiPs *QspiInstancePtr, u16 QspiDeviceId, u16 QspiIntrId) { u8 *BufferPtr; u8 UniqueValue; int Count; int Page; int Status; u32 Options; /* * Lookup the device configuration in the temporary CROM table. Use this * configuration info down below when initializing this component. */ ConfigPtr = XQspiPs_LookupConfig(QspiDeviceId); if (ConfigPtr == NULL) { return XST_DEVICE_NOT_FOUND; } Status = XQspiPs_CfgInitialize(QspiInstancePtr, ConfigPtr, ConfigPtr->BaseAddress); if (Status != XST_SUCCESS) { return XST_FAILURE; } /* * Set the QSPI options */ Options = XQSPIPS_FORCE_SSELECT_OPTION | XQSPIPS_MANUAL_START_OPTION | XQSPIPS_HOLD_B_DRIVE_OPTION; XIsf_SetSpiConfiguration(&Isf, QspiInstancePtr, Options, XISF_SPI_PRESCALER); if(ConfigPtr->ConnectionMode == XQSPIPS_CONNECTION_MODE_STACKED) { /* * Enable two flash memories, Shared bus * (NOT separate bus), L_PAGE selected by default */ XQspiPs_SetLqspiConfigReg(QspiInstancePtr, DUAL_STACK_CONFIG_WRITE); } if(ConfigPtr->ConnectionMode == XQSPIPS_CONNECTION_MODE_PARALLEL) { /* * Enable two flash memories on separate buses */ XQspiPs_SetLqspiConfigReg(QspiInstancePtr, DUAL_QSPI_CONFIG_WRITE); } /* Initialize the XILISF Library */ XIsf_Initialize(&Isf, QspiInstancePtr, FLASH_QSPI_SELECT, IsfWriteBuffer); /* * Initialize the write buffer for a pattern to write to the FLASH * and the read buffer to zero so it can be verified after the read, * the test value that is added to the unique value allows the value * to be changed in a debug environment to guarantee */ for (UniqueValue = UNIQUE_VALUE, Count = 0; Count < PAGE_SIZE; Count++, UniqueValue++) { WriteBuffer[Count] = (u8)(UniqueValue + Test_Polled); } memset(ReadBuffer, 0x00, sizeof(ReadBuffer)); Status = FlashErase(&Isf, TEST_ADDRESS, MAX_DATA); if(Status != XST_SUCCESS){ return XST_FAILURE; } /* * Write the data in the write buffer to the serial FLASH a page at a * time, starting from TEST_ADDRESS */ for (Page = 0; Page < PAGE_COUNT; Page++) { Status = FlashWrite(&Isf, (Page * PAGE_SIZE) + TEST_ADDRESS, PAGE_SIZE, XISF_QUAD_IP_PAGE_WRITE); if(Status != XST_SUCCESS){ return XST_FAILURE; } } /****************************************************** **********************NORMAL READ********************* ******************************************************/ /* * Read the contents of the FLASH from TEST_ADDRESS, using Normal Read * command */ Status = FlashRead(&Isf, TEST_ADDRESS, MAX_DATA, XISF_READ); if(Status != XST_SUCCESS){ return XST_FAILURE; } /* * Setup a pointer to the start of the data that was read into the read * buffer and verify the data read is the data that was written */ BufferPtr = ReadBuffer; for (UniqueValue = UNIQUE_VALUE, Count = 0; Count < MAX_DATA; Count++, UniqueValue++) { if (BufferPtr[Count] != (u8)(UniqueValue + Test_Polled)) { return XST_FAILURE; } } /****************************************************** **********************FAST READ*********************** ******************************************************/ /* * Read the contents of the FLASH from TEST_ADDRESS, using Fast Read * command */ Status = FlashRead(&Isf, TEST_ADDRESS, MAX_DATA, XISF_FAST_READ); if(Status != XST_SUCCESS){ return XST_FAILURE; } /* * Setup a pointer to the start of the data that was read into the read * buffer and verify the data read is the data that was written */ BufferPtr = ReadBuffer; for (UniqueValue = UNIQUE_VALUE, Count = 0; Count < MAX_DATA; Count++, UniqueValue++) { if (BufferPtr[Count] != (u8)(UniqueValue + Test_Polled)) { return XST_FAILURE; } } /****************************************************** ******************DUAL OP FAST READ******************* ******************************************************/ /* * Read the contents of the FLASH from TEST_ADDRESS, using DUAL OP * Fast Read command */ Status = FlashRead(&Isf, TEST_ADDRESS, MAX_DATA, XISF_DUAL_OP_FAST_READ); if(Status != XST_SUCCESS){ return XST_FAILURE; } /* * Setup a pointer to the start of the data that was read into the read * buffer and verify the data read is the data that was written */ BufferPtr = ReadBuffer; for (UniqueValue = UNIQUE_VALUE, Count = 0; Count < MAX_DATA; Count++, UniqueValue++) { if (BufferPtr[Count] != (u8)(UniqueValue + Test_Polled)) { return XST_FAILURE; } } /****************************************************** ******************QUAD IO FAST READ******************* ******************************************************/ /* * Read the contents of the FLASH from TEST_ADDRESS, using QUAD IO * Fast Read command */ Status = FlashRead(&Isf, TEST_ADDRESS, MAX_DATA, XISF_QUAD_OP_FAST_READ); if(Status != XST_SUCCESS){ return XST_FAILURE; } /* * Setup a pointer to the start of the data that was read into the read * buffer and verify the data read is the data that was written */ BufferPtr = ReadBuffer; for (UniqueValue = UNIQUE_VALUE, Count = 0; Count < MAX_DATA; Count++, UniqueValue++) { if (BufferPtr[Count] != (u8)(UniqueValue + Test_Polled)) { return XST_FAILURE; } } return XST_SUCCESS; }