static XStatus XSpi_CfgInitialize(XSpi * InstancePtr, XSpi_Config * CfgPtr) { XStatus retval; down(&cfg_sem); p_xspi_cfg = CfgPtr; retval = XSpi_Initialize(InstancePtr, 0); up(&cfg_sem); return retval; }
/***************************************************************************//** * @brief spi_init *******************************************************************************/ int32_t spi_init(uint32_t device_id, uint8_t clk_pha, uint8_t clk_pol) { uint32_t base_addr = 0; uint32_t spi_options = 0; #ifdef _XPARAMETERS_PS_H_ spi_config = XSpiPs_LookupConfig(device_id); base_addr = spi_config->BaseAddress; XSpiPs_CfgInitialize(&spi_instance, spi_config, base_addr); spi_options = XSPIPS_MASTER_OPTION | (clk_pol ? XSPIPS_CLK_ACTIVE_LOW_OPTION : 0) | (clk_pha ? XSPIPS_CLK_PHASE_1_OPTION : 0) | (spi_decoded_cs ? XSPIPS_DECODE_SSELECT_OPTION : 0) | XSPIPS_FORCE_SSELECT_OPTION; XSpiPs_SetOptions(&spi_instance, spi_options); XSpiPs_SetClkPrescaler(&spi_instance, XSPIPS_CLK_PRESCALE_32); /* FIXME: Temporary 15.2 Fix */ XSpiPs_CfgInitialize(&spi_instance, spi_config, base_addr); XSpiPs_SetOptions(&spi_instance, spi_options); XSpiPs_SetClkPrescaler(&spi_instance, XSPIPS_CLK_PRESCALE_32); #else XSpi_Initialize(&spi_instance, device_id); XSpi_Stop(&spi_instance); spi_config = XSpi_LookupConfig(device_id); base_addr = spi_config->BaseAddress; XSpi_CfgInitialize(&spi_instance, spi_config, base_addr); spi_options = XSP_MASTER_OPTION | (clk_pol ? XSP_CLK_ACTIVE_LOW_OPTION : 0) | (clk_pha ? XSP_CLK_PHASE_1_OPTION : 0) | XSP_MANUAL_SSELECT_OPTION; XSpi_SetOptions(&spi_instance, spi_options); XSpi_Start(&spi_instance); XSpi_IntrGlobalDisable(&spi_instance); #endif return 0; }
/***************************************************************************//** * @brief spi_init *******************************************************************************/ int32_t spi_init(uint32_t device_id, uint8_t clk_pha, uint8_t clk_pol) { uint32_t base_addr = 0; uint32_t control_val = 0; #ifdef _XPARAMETERS_PS_H_ uint8_t byte = 0; spi_config = XSpiPs_LookupConfig(device_id); base_addr = spi_config->BaseAddress; XSpiPs_CfgInitialize(&spi_instance, spi_config, base_addr); control_val = XSPIPS_CR_SSFORCE_MASK | XSPIPS_CR_SSCTRL_MASK | 4 << XSPIPS_CR_PRESC_SHIFT | (clk_pha ? XSPIPS_CR_CPHA_MASK : 0) | (clk_pol ? XSPIPS_CR_CPOL_MASK : 0) | XSPIPS_CR_MSTREN_MASK; XSpiPs_WriteReg(base_addr, XSPIPS_CR_OFFSET, control_val); for(byte = 0; byte < 128; byte++) { XSpiPs_ReadReg(base_addr, XSPIPS_RXD_OFFSET); } #else XSpi_Initialize(&spi_instance, device_id); XSpi_Stop(&spi_instance); spi_config = XSpi_LookupConfig(device_id); base_addr = spi_config->BaseAddress; XSpi_CfgInitialize(&spi_instance, spi_config, base_addr); control_val = XSP_MASTER_OPTION | XSP_CLK_PHASE_1_OPTION | XSP_MANUAL_SSELECT_OPTION; XSpi_SetOptions(&spi_instance, control_val); XSpi_Start(&spi_instance); XSpi_IntrGlobalDisable(&spi_instance); XSpi_SetSlaveSelect(&spi_instance, 1); #endif return 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; }
DSTATUS disk_initialize (void) { BYTE n, cmd, ty, buf[4]; UINT tmr; #if AXI_SPI /* * Initialize the SPI driver so that it's ready to use, * specify the device ID that is generated in xparameters.h. */ XStatus Status = XSpi_Initialize(&Spi, XPAR_SDCARD_SPI_DEVICE_ID); if(Status != XST_SUCCESS) {\ xil_printf("Failure INIT\r\n"); return XST_FAILURE; } /* * Set the SPI device as a master and in manual slave select mode such * that the slave select signal does not toggle for every byte of a * transfer, this must be done before the slave select is set. */ Status = XSpi_SetOptions(&Spi, XSP_MASTER_OPTION | XSP_MANUAL_SSELECT_OPTION); if(Status != XST_SUCCESS) { xil_printf("Failure Options\r\n"); return XST_FAILURE; } Status = XSpi_SetSlaveSelect(&Spi, 1); if(Status != XST_SUCCESS) { xil_printf("Failure Slave Select\r\n"); return XST_FAILURE; } XSpi_Start(&Spi); XSpi_IntrGlobalDisable(&Spi); DLY_US(1); #else INIT_PORT(); CS_H(); #endif skip_mmc(10); /* Dummy clocks */ ty = 0; if (send_cmd(CMD0, 0) == 1) { /* Enter Idle state */ if (send_cmd(CMD8, 0x1AA) == 1) { /* SDv2 */ for (n = 0; n < 4; n++) buf[n] = rcvr_mmc(); /* Get trailing return value of R7 resp */ if (buf[2] == 0x01 && buf[3] == 0xAA) { /* The card can work at vdd range of 2.7-3.6V */ for (tmr = 1000; tmr; tmr--) { /* Wait for leaving idle state (ACMD41 with HCS bit) */ if (send_cmd(ACMD41, 1UL << 30) == 0) break; DLY_US(1000); } if (tmr && send_cmd(CMD58, 0) == 0) { /* Check CCS bit in the OCR */ for (n = 0; n < 4; n++) buf[n] = rcvr_mmc(); ty = (buf[0] & 0x40) ? CT_SD2 | CT_BLOCK : CT_SD2; /* SDv2 (HC or SC) */ } } } else { /* SDv1 or MMCv3 */ if (send_cmd(ACMD41, 0) <= 1) { ty = CT_SD1; cmd = ACMD41; /* SDv1 */ } else { ty = CT_MMC; cmd = CMD1; /* MMCv3 */ } for (tmr = 1000; tmr; tmr--) { /* Wait for leaving idle state */ if (send_cmd(cmd, 0) == 0) break; DLY_US(1000); } if (!tmr || send_cmd(CMD16, 512) != 0) /* Set R/W block length to 512 */ ty = 0; } } CardType = ty; release_spi(); return ty ? 0 : STA_NOINIT; }