/** * * This function does a minimal test on the Spi device and driver as a * design example. The purpose of this function is to illustrate how to use * the XSpi component using the interrupt mode. * * This function sends data and expects to receive the same data. * * * @param IntcInstancePtr is a pointer to the instance of the INTC * component. * @param SpiInstancePtr is a pointer to the instance of Spi component. * @param SpiDeviceId is the Device ID of the Spi Device and is the * XPAR_<SPI_instance>_DEVICE_ID value from xparameters.h. * @param SpiIntrId is the interrupt Id and is typically * XPAR_<INTC_instance>_<SPI_instance>_VEC_ID value from * xparameters.h . * * @return XST_SUCCESS if successful, otherwise XST_FAILURE. * * @note * * This function contains an infinite loop such that if interrupts are not * working it may never return. * ******************************************************************************/ int SpiIntrExample(XIntc *IntcInstancePtr, XSpi *SpiInstancePtr, u16 SpiDeviceId, u16 SpiIntrId) { int Status; u32 Count; u8 Test; XSpi_Config *ConfigPtr; /* Pointer to Configuration data */ /* * Initialize the SPI driver so that it is ready to use. */ ConfigPtr = XSpi_LookupConfig(SpiDeviceId); if (ConfigPtr == NULL) { return XST_DEVICE_NOT_FOUND; } Status = XSpi_CfgInitialize(SpiInstancePtr, ConfigPtr, ConfigPtr->BaseAddress); if (Status != XST_SUCCESS) { return XST_FAILURE; } /* * Perform a self-test to ensure that the hardware was built correctly. */ Status = XSpi_SelfTest(SpiInstancePtr); if (Status != XST_SUCCESS) { return XST_FAILURE; } /* * Run loopback test only in case of standard SPI mode. */ if (SpiInstancePtr->SpiMode != XSP_STANDARD_MODE) { return XST_SUCCESS; } /* * 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. */ XSpi_SetStatusHandler(SpiInstancePtr, SpiInstancePtr, (XSpi_StatusHandler) SpiIntrHandler); /* * Set the Spi device as a master and in loopback mode. */ Status = XSpi_SetOptions(SpiInstancePtr, XSP_MASTER_OPTION | XSP_LOOPBACK_OPTION); if (Status != XST_SUCCESS) { return XST_FAILURE; } /* * Start the SPI driver so that interrupts and the device are enabled. */ XSpi_Start(SpiInstancePtr); /* * Initialize the write buffer with pattern to write, initialize 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. */ Test = 0x10; for (Count = 0; Count < BUFFER_SIZE; Count++) { WriteBuffer[Count] = (u8)(Count + Test); ReadBuffer[Count] = 0; } /* * Transmit the data. */ TransferInProgress = TRUE; XSpi_Transfer(SpiInstancePtr, WriteBuffer, ReadBuffer, BUFFER_SIZE); /* * Wait for the transmission to be complete. */ while (TransferInProgress); /* * Disable the Spi interrupt. */ SpiDisableIntrSystem(IntcInstancePtr, SpiIntrId); /* * Compare the data received with the data that was transmitted. */ for (Count = 0; Count < BUFFER_SIZE; Count++) { if (WriteBuffer[Count] != ReadBuffer[Count]) { return XST_FAILURE; } } return XST_SUCCESS; }
/***************************************************************************** * * The purpose of this function is to illustrate how to use the XSpiPs * device driver in interrupt mode. This function writes and reads data * from a serial FLASH. * * @param None. * * @return XST_SUCCESS if successful else XST_FAILURE. * * @note * * This function calls other functions which contain loops that may be infinite * if interrupts are not working such that it may not return. If the device * slave select is not correct and the device is not responding on bus it will * read a status of 0xFF for the status register as the bus is pulled up. * *****************************************************************************/ int SpiFlashIntrExample(XScuGic *IntcInstancePtr, XSpiPs *SpiInstancePtr, u16 SpiDeviceId, u16 SpiIntrId) { int Status; u8 *BufferPtr; u8 UniqueValue; u32 Count; XSpiPs_Config *ConfigPtr; /* Pointer to Configuration ROM data */ u32 TempAddress; 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; }
/***************************************************************************** * * The purpose of this function is to illustrate how to use the XSpiPs * device driver in interrupt mode . This test writes and reads data from a * serial EEPROM. * This part must be present in the hardware to use this example. * * @param IntcInstancePtr is a pointer to the GIC driver to use. * @param SpiInstancePtr is a pointer to the SPI driver to use. * @param SpiDeviceId is the DeviceId of the Spi device. * @param SpiIntrId is the Spi Interrupt Id. * * @return XST_SUCCESS if successful else XST_FAILURE. * * @note * * This function calls 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 SpiPsEepromIntrExample(XScuGic *IntcInstancePtr, XSpiPs *SpiInstancePtr, u16 SpiDeviceId, u16 SpiIntrId) { int Status; u8 *BufferPtr; u8 UniqueValue; int Count; int Page; XSpiPs_Config *SpiConfig; /* * Initialize the SPI driver so that it's ready to use */ SpiConfig = XSpiPs_LookupConfig(SpiDeviceId); if (NULL == SpiConfig) { return XST_FAILURE; } Status = XSpiPs_CfgInitialize(SpiInstancePtr, SpiConfig, SpiConfig->BaseAddress); if (Status != XST_SUCCESS) { return XST_FAILURE; } /* * Perform a self-test to check hardware build */ Status = XSpiPs_SelfTest(SpiInstancePtr); if (Status != XST_SUCCESS) { return XST_FAILURE; } /* * 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 */ XSpiPs_SetStatusHandler(SpiInstancePtr, SpiInstancePtr, (XSpiPs_StatusHandler) SpiHandler); /* * Set the Spi device as a master. External loopback is required. */ XSpiPs_SetOptions(SpiInstancePtr, XSPIPS_MASTER_OPTION | XSPIPS_FORCE_SSELECT_OPTION); XSpiPs_SetClkPrescaler(SpiInstancePtr, XSPIPS_CLK_PRESCALE_64); /* * Initialize the write buffer for a pattern to write to the EEPROM * 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 = 13, Count = 0; Count < MAX_DATA; Count++, UniqueValue++) { WriteBuffer[WRITE_DATA_OFFSET + Count] = (u8)(UniqueValue + Test); ReadBuffer[READ_DATA_OFFSET + Count] = 0xA5; } /* * Assert the EEPROM chip select */ XSpiPs_SetSlaveSelect(SpiInstancePtr, EEPROM_SPI_SELECT); /* * Write the data in the write buffer to the serial EEPROM a page at a * time */ for (Page = 0; Page < PAGE_COUNT; Page++) { EepromWrite(SpiInstancePtr, Page * PAGE_SIZE, PAGE_SIZE, &WriteBuffer[Page * PAGE_SIZE]); } /* * Read the contents of the entire EEPROM from address 0, since this * function reads the entire EEPROM it will take some amount of time to * complete */ EepromRead(SpiInstancePtr, 0, MAX_DATA, ReadBuffer); /* * 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[READ_DATA_OFFSET]; for (UniqueValue = 13, Count = 0; Count < MAX_DATA; Count++, UniqueValue++) { if (BufferPtr[Count] != (u8)(UniqueValue + Test)) { return XST_FAILURE; } } SpiDisableIntrSystem(IntcInstancePtr, SpiIntrId); return XST_SUCCESS; }