/** * This function initiates an interrupt-driven send in master mode. * * It tries to send the first FIFO-full of data, then lets the interrupt * handler to handle the rest of the data if there is any. * * @param InstancePtr is a pointer to the XIicPs instance. * @param MsgPtr is the pointer to the send buffer. * @param ByteCount is the number of bytes to be sent. * @param SlaveAddr is the address of the slave we are sending to. * * @return None. * * @note This send routine is for interrupt-driven transfer only. * ****************************************************************************/ void XIicPs_MasterSend(XIicPs *InstancePtr, u8 *MsgPtr, s32 ByteCount, u16 SlaveAddr) { u32 BaseAddr; u32 Platform = XGetPlatform_Info(); /* * Assert validates the input arguments. */ Xil_AssertVoid(InstancePtr != NULL); Xil_AssertVoid(MsgPtr != NULL); Xil_AssertVoid(InstancePtr->IsReady == (u32)XIL_COMPONENT_IS_READY); Xil_AssertVoid(XIICPS_ADDR_MASK >= SlaveAddr); BaseAddr = InstancePtr->Config.BaseAddress; InstancePtr->SendBufferPtr = MsgPtr; InstancePtr->SendByteCount = ByteCount; InstancePtr->RecvBufferPtr = NULL; InstancePtr->IsSend = 1; /* * Set repeated start if sending more than FIFO of data. */ if (((InstancePtr->IsRepeatedStart) != 0)|| ((ByteCount > XIICPS_FIFO_DEPTH) != 0U)) { XIicPs_WriteReg(BaseAddr, (u32)XIICPS_CR_OFFSET, XIicPs_ReadReg(BaseAddr, (u32)XIICPS_CR_OFFSET) | (u32)XIICPS_CR_HOLD_MASK); } /* * Setup as a master sending role. */ (void)XIicPs_SetupMaster(InstancePtr, SENDING_ROLE); (void)TransmitFifoFill(InstancePtr); XIicPs_EnableInterrupts(BaseAddr, (u32)XIICPS_IXR_NACK_MASK | (u32)XIICPS_IXR_COMP_MASK | (u32)XIICPS_IXR_ARB_LOST_MASK); /* * Do the address transfer to notify the slave. */ XIicPs_WriteReg(BaseAddr, XIICPS_ADDR_OFFSET, (u32)SlaveAddr); /* Clear the Hold bit in ZYNQ if receive byte count is less than * the FIFO depth to get the completion interrupt properly. */ if ((ByteCount < XIICPS_FIFO_DEPTH) && (Platform == (u32)XPLAT_ZYNQ)) { XIicPs_WriteReg(BaseAddr, XIICPS_CR_OFFSET, XIicPs_ReadReg(BaseAddr, (u32)XIICPS_CR_OFFSET) & (u32)(~XIICPS_CR_HOLD_MASK)); } }
/***************************************************************************** * * 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 interrupt handler for the master mode. It does the protocol handling for * the interrupt-driven transfers. * * Completion events and errors are signaled to upper layer for proper handling. * * <pre> * The interrupts that are handled are: * - DATA * This case is handled only for master receive data. * The master has to request for more data (if there is more data to * receive) and read the data from the FIFO . * * - COMP * If the Master is transmitting data and there is more data to be * sent then the data is written to the FIFO. If there is no more data to * be transmitted then a completion event is signalled to the upper layer * by calling the callback handler. * * If the Master is receiving data then the data is read from the FIFO and * the Master has to request for more data (if there is more data to * receive). If all the data has been received then a completion event * is signalled to the upper layer by calling the callback handler. * It is an error if the amount of received data is more than expected. * * - NAK and SLAVE_RDY * This is signalled to the upper layer by calling the callback handler. * * - All Other interrupts * These interrupts are marked as error. This is signalled to the upper * layer by calling the callback handler. * * </pre> * * @param InstancePtr is a pointer to the XIicPs instance. * * @return None. * * @note None. * ****************************************************************************/ void XIicPs_MasterInterruptHandler(XIicPs *InstancePtr) { u32 IntrStatusReg; u32 StatusEvent = 0U; u32 BaseAddr; u16 SlaveAddr; s32 ByteCnt; s32 IsHold; u32 Platform; /* * Assert validates the input arguments. */ Xil_AssertVoid(InstancePtr != NULL); Xil_AssertVoid(InstancePtr->IsReady == (u32)XIL_COMPONENT_IS_READY); BaseAddr = InstancePtr->Config.BaseAddress; Platform = XGetPlatform_Info(); /* * Read the Interrupt status register. */ IntrStatusReg = XIicPs_ReadReg(BaseAddr, (u32)XIICPS_ISR_OFFSET); /* * Write the status back to clear the interrupts so no events are * missed while processing this interrupt. */ XIicPs_WriteReg(BaseAddr, (u32)XIICPS_ISR_OFFSET, IntrStatusReg); /* * Use the Mask register AND with the Interrupt Status register so * disabled interrupts are not processed. */ IntrStatusReg &= ~(XIicPs_ReadReg(BaseAddr, (u32)XIICPS_IMR_OFFSET)); ByteCnt = InstancePtr->CurrByteCount; IsHold = 0; if ((XIicPs_ReadReg(BaseAddr, (u32)XIICPS_CR_OFFSET) & (u32)XIICPS_CR_HOLD_MASK) != 0U) { IsHold = 1; } /* * Send */ if (((InstancePtr->IsSend) != 0) && ((u32)0U != (IntrStatusReg & (u32)XIICPS_IXR_COMP_MASK))) { if (InstancePtr->SendByteCount > 0) { MasterSendData(InstancePtr); } else { StatusEvent |= XIICPS_EVENT_COMPLETE_SEND; } } /* * Receive */ if (((!(InstancePtr->IsSend))!= 0) && ((0 != (IntrStatusReg & (u32)XIICPS_IXR_DATA_MASK)) || (0 != (IntrStatusReg & (u32)XIICPS_IXR_COMP_MASK)))){ while ((XIicPs_ReadReg(BaseAddr, (u32)XIICPS_SR_OFFSET) & XIICPS_SR_RXDV_MASK) != 0U) { if (((InstancePtr->RecvByteCount < XIICPS_DATA_INTR_DEPTH)!= 0U) && (IsHold != 0) && ((!InstancePtr->IsRepeatedStart)!= 0) && (InstancePtr->UpdateTxSize == 0)) { IsHold = 0; XIicPs_WriteReg(BaseAddr, XIICPS_CR_OFFSET, XIicPs_ReadReg(BaseAddr, XIICPS_CR_OFFSET) & (~XIICPS_CR_HOLD_MASK)); } XIicPs_RecvByte(InstancePtr); ByteCnt--; if (Platform == (u32)XPLAT_ZYNQ) { if ((InstancePtr->UpdateTxSize != 0) && (ByteCnt == (XIICPS_FIFO_DEPTH + 1))) { break; } } } if (Platform == (u32)XPLAT_ZYNQ) { if ((InstancePtr->UpdateTxSize != 0) && (ByteCnt == (XIICPS_FIFO_DEPTH + 1))) { /* wait while fifo is full */ while (XIicPs_ReadReg(BaseAddr, XIICPS_TRANS_SIZE_OFFSET) != (u32)(ByteCnt - XIICPS_FIFO_DEPTH)) { } if ((InstancePtr->RecvByteCount - XIICPS_FIFO_DEPTH) > XIICPS_MAX_TRANSFER_SIZE) { XIicPs_WriteReg(BaseAddr, XIICPS_TRANS_SIZE_OFFSET, XIICPS_MAX_TRANSFER_SIZE); ByteCnt = (s32)XIICPS_MAX_TRANSFER_SIZE + XIICPS_FIFO_DEPTH; } else { XIicPs_WriteReg(BaseAddr, XIICPS_TRANS_SIZE_OFFSET, InstancePtr->RecvByteCount - XIICPS_FIFO_DEPTH); InstancePtr->UpdateTxSize = 0; ByteCnt = InstancePtr->RecvByteCount; } } } else { if ((InstancePtr->RecvByteCount > 0) && (ByteCnt == 0)) { /* * Clear the interrupt status register before use it to * monitor. */ IntrStatusReg = XIicPs_ReadReg(BaseAddr, XIICPS_ISR_OFFSET); XIicPs_WriteReg(BaseAddr, XIICPS_ISR_OFFSET, IntrStatusReg); SlaveAddr = (u16)XIicPs_ReadReg(BaseAddr, (u32)XIICPS_ADDR_OFFSET); XIicPs_WriteReg(BaseAddr, XIICPS_ADDR_OFFSET, SlaveAddr); if ((InstancePtr->RecvByteCount) > XIICPS_MAX_TRANSFER_SIZE) { XIicPs_WriteReg(BaseAddr, XIICPS_TRANS_SIZE_OFFSET, XIICPS_MAX_TRANSFER_SIZE); ByteCnt = (s32)XIICPS_MAX_TRANSFER_SIZE; } else { XIicPs_WriteReg(BaseAddr, XIICPS_TRANS_SIZE_OFFSET, InstancePtr->RecvByteCount); InstancePtr->UpdateTxSize = 0; ByteCnt = InstancePtr->RecvByteCount; } XIicPs_EnableInterrupts(BaseAddr, (u32)XIICPS_IXR_NACK_MASK | (u32)XIICPS_IXR_DATA_MASK | (u32)XIICPS_IXR_RX_OVR_MASK | (u32)XIICPS_IXR_COMP_MASK | (u32)XIICPS_IXR_ARB_LOST_MASK); } } InstancePtr->CurrByteCount = ByteCnt; } if (((!(InstancePtr->IsSend)) != 0) && (0U != (IntrStatusReg & XIICPS_IXR_COMP_MASK))) { /* * If all done, tell the application. */ if (InstancePtr->RecvByteCount == 0){ if ((!(InstancePtr->IsRepeatedStart)) != 0) { XIicPs_WriteReg(BaseAddr, XIICPS_CR_OFFSET, XIicPs_ReadReg(BaseAddr, XIICPS_CR_OFFSET) & (~XIICPS_CR_HOLD_MASK)); } StatusEvent |= XIICPS_EVENT_COMPLETE_RECV; } } /* * Slave ready interrupt, it is only meaningful for master mode. */ if (0U != (IntrStatusReg & XIICPS_IXR_SLV_RDY_MASK)) { StatusEvent |= XIICPS_EVENT_SLAVE_RDY; } if (0U != (IntrStatusReg & XIICPS_IXR_NACK_MASK)) { if ((!(InstancePtr->IsRepeatedStart)) != 0 ) { XIicPs_WriteReg(BaseAddr, XIICPS_CR_OFFSET, XIicPs_ReadReg(BaseAddr, XIICPS_CR_OFFSET) & (~XIICPS_CR_HOLD_MASK)); } StatusEvent |= XIICPS_EVENT_NACK; } /* * Arbitration lost interrupt */ if (0U != (IntrStatusReg & XIICPS_IXR_ARB_LOST_MASK)) { StatusEvent |= XIICPS_EVENT_ARB_LOST; } /* * All other interrupts are treated as error. */ if (0U != (IntrStatusReg & (XIICPS_IXR_NACK_MASK | XIICPS_IXR_RX_UNF_MASK | XIICPS_IXR_TX_OVR_MASK | XIICPS_IXR_RX_OVR_MASK))) { if ((!(InstancePtr->IsRepeatedStart)) != 0) { XIicPs_WriteReg(BaseAddr, XIICPS_CR_OFFSET, XIicPs_ReadReg(BaseAddr, XIICPS_CR_OFFSET) & (~XIICPS_CR_HOLD_MASK)); } StatusEvent |= XIICPS_EVENT_ERROR; } /* * Signal application if there are any events. */ if (StatusEvent != 0U) { InstancePtr->StatusHandler(InstancePtr->CallBackRef, StatusEvent); } }
/** * This function initiates a polled mode receive in master mode. * * It repeatedly sets the transfer size register so the slave can * send data to us. It polls the data register for data to come in. * If slave fails to send us data, it fails with time out. * * @param InstancePtr is a pointer to the XIicPs instance. * @param MsgPtr is the pointer to the receive buffer. * @param ByteCount is the number of bytes to be received. * @param SlaveAddr is the address of the slave we are receiving from. * * @return * - XST_SUCCESS if everything went well. * - XST_FAILURE if timed out. * * @note This receive routine is for polled mode transfer only. * ****************************************************************************/ s32 XIicPs_MasterRecvPolled(XIicPs *InstancePtr, u8 *MsgPtr, s32 ByteCount, u16 SlaveAddr) { u32 IntrStatusReg; u32 Intrs; u32 StatusReg; u32 BaseAddr; s32 BytesToRecv; s32 BytesToRead; s32 TransSize; u32 Status_Rcv; u32 Status; s32 Result; s32 IsHold; s32 UpdateTxSize = 0; s32 ByteCountVar = ByteCount; u32 Platform; /* * Assert validates the input arguments. */ Xil_AssertNonvoid(InstancePtr != NULL); Xil_AssertNonvoid(MsgPtr != NULL); Xil_AssertNonvoid(InstancePtr->IsReady == (u32)XIL_COMPONENT_IS_READY); Xil_AssertNonvoid(XIICPS_ADDR_MASK >= SlaveAddr); BaseAddr = InstancePtr->Config.BaseAddress; InstancePtr->RecvBufferPtr = MsgPtr; InstancePtr->RecvByteCount = ByteCountVar; Platform = XGetPlatform_Info(); if((ByteCountVar > XIICPS_FIFO_DEPTH) || ((InstancePtr->IsRepeatedStart) !=0)) { XIicPs_WriteReg(BaseAddr, XIICPS_CR_OFFSET, XIicPs_ReadReg(BaseAddr, (u32)XIICPS_CR_OFFSET) | (u32)XIICPS_CR_HOLD_MASK); IsHold = 1; } else { IsHold = 0; } (void)XIicPs_SetupMaster(InstancePtr, RECVING_ROLE); /* * Clear the interrupt status register before use it to monitor. */ IntrStatusReg = XIicPs_ReadReg(BaseAddr, XIICPS_ISR_OFFSET); XIicPs_WriteReg(BaseAddr, XIICPS_ISR_OFFSET, IntrStatusReg); XIicPs_WriteReg(BaseAddr, XIICPS_ADDR_OFFSET, SlaveAddr); /* * Set up the transfer size register so the slave knows how much * to send to us. */ if (ByteCountVar > XIICPS_MAX_TRANSFER_SIZE) { XIicPs_WriteReg(BaseAddr, XIICPS_TRANS_SIZE_OFFSET, XIICPS_MAX_TRANSFER_SIZE); ByteCountVar = (s32)XIICPS_MAX_TRANSFER_SIZE; UpdateTxSize = 1; }else { XIicPs_WriteReg(BaseAddr, XIICPS_TRANS_SIZE_OFFSET, ByteCountVar); } /* * Intrs keeps all the error-related interrupts. */ Intrs = (u32)XIICPS_IXR_ARB_LOST_MASK | (u32)XIICPS_IXR_RX_OVR_MASK | (u32)XIICPS_IXR_RX_UNF_MASK | (u32)XIICPS_IXR_NACK_MASK; /* * Poll the interrupt status register to find the errors. */ IntrStatusReg = XIicPs_ReadReg(BaseAddr, XIICPS_ISR_OFFSET); while ((InstancePtr->RecvByteCount > 0) && ((IntrStatusReg & Intrs) == 0U)) { StatusReg = XIicPs_ReadReg(BaseAddr, XIICPS_SR_OFFSET); while ((StatusReg & XIICPS_SR_RXDV_MASK) != 0U) { if (((InstancePtr->RecvByteCount < XIICPS_DATA_INTR_DEPTH) != 0U) && (IsHold != 0) && ((!InstancePtr->IsRepeatedStart) != 0) && (UpdateTxSize == 0)) { IsHold = 0; XIicPs_WriteReg(BaseAddr, XIICPS_CR_OFFSET, XIicPs_ReadReg(BaseAddr, XIICPS_CR_OFFSET) & (~XIICPS_CR_HOLD_MASK)); } XIicPs_RecvByte(InstancePtr); ByteCountVar --; if (Platform == (u32)XPLAT_ZYNQ) { if ((UpdateTxSize != 0) && (ByteCountVar == (XIICPS_FIFO_DEPTH + 1))) { break; } } StatusReg = XIicPs_ReadReg(BaseAddr, XIICPS_SR_OFFSET); } if (Platform == (u32)XPLAT_ZYNQ) { if ((UpdateTxSize != 0) && (ByteCountVar == (XIICPS_FIFO_DEPTH + 1))) { /* wait while fifo is full */ while (XIicPs_ReadReg(BaseAddr, XIICPS_TRANS_SIZE_OFFSET) != (u32)(ByteCountVar - XIICPS_FIFO_DEPTH)) { ; } if ((InstancePtr->RecvByteCount - XIICPS_FIFO_DEPTH) > XIICPS_MAX_TRANSFER_SIZE) { XIicPs_WriteReg(BaseAddr, XIICPS_TRANS_SIZE_OFFSET, XIICPS_MAX_TRANSFER_SIZE); ByteCountVar = (s32)XIICPS_MAX_TRANSFER_SIZE + XIICPS_FIFO_DEPTH; } else { XIicPs_WriteReg(BaseAddr, XIICPS_TRANS_SIZE_OFFSET, InstancePtr->RecvByteCount - XIICPS_FIFO_DEPTH); UpdateTxSize = 0; ByteCountVar = InstancePtr->RecvByteCount; } } } else { if ((InstancePtr->RecvByteCount > 0) && (ByteCountVar == 0)) { /* * Clear the interrupt status register before use it to * monitor. */ IntrStatusReg = XIicPs_ReadReg(BaseAddr, XIICPS_ISR_OFFSET); XIicPs_WriteReg(BaseAddr, XIICPS_ISR_OFFSET, IntrStatusReg); XIicPs_WriteReg(BaseAddr, XIICPS_ADDR_OFFSET, SlaveAddr); if ((InstancePtr->RecvByteCount) > XIICPS_MAX_TRANSFER_SIZE) { XIicPs_WriteReg(BaseAddr, XIICPS_TRANS_SIZE_OFFSET, XIICPS_MAX_TRANSFER_SIZE); ByteCountVar = (s32)XIICPS_MAX_TRANSFER_SIZE; } else { XIicPs_WriteReg(BaseAddr, XIICPS_TRANS_SIZE_OFFSET, InstancePtr->RecvByteCount); UpdateTxSize = 0; ByteCountVar = InstancePtr->RecvByteCount; } } } IntrStatusReg = XIicPs_ReadReg(BaseAddr, XIICPS_ISR_OFFSET); } if ((!(InstancePtr->IsRepeatedStart)) != 0) { XIicPs_WriteReg(BaseAddr, XIICPS_CR_OFFSET, XIicPs_ReadReg(BaseAddr,XIICPS_CR_OFFSET) & (~XIICPS_CR_HOLD_MASK)); } if ((IntrStatusReg & Intrs) != 0x0U) { Result = (s32)XST_FAILURE; } else { Result = (s32)XST_SUCCESS; } return Result; }
/***************************************************************************** * * 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 IntcInstancePtr is a pointer to Interrupt Controller instance. * * @param SpiInstancePtr is a pointer to the SPI driver instance to use. * * @param SpiDeviceId is the Instance Id of SPI in the system. * * @param SpiIntrId is the Interrupt Id for SPI in the system. * * @param None. * * @return * - XST_SUCCESS if successful * - XST_FAILURE if not successful * * @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 SpiPsFlashIntrExample(XScuGic *IntcInstancePtr, XSpiPs *SpiInstancePtr, u16 SpiDeviceId, u16 SpiIntrId) { int Status; u8 *BufferPtr; u8 UniqueValue; u32 Count; u32 MaxSize = MAX_DATA; u32 ChipSelect = FLASH_SPI_SELECT_1; XSpiPs_Config *SpiConfig; 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; } /* * 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 = SpiPsSetupIntrSystem(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) SpiPsHandler); /* * Set the SPI device as a master with manual start and manual * chip select mode options */ XSpiPs_SetOptions(SpiInstancePtr, XSPIPS_MANUAL_START_OPTION | \ XSPIPS_MASTER_OPTION | XSPIPS_FORCE_SSELECT_OPTION); /* * Set the SPI device pre-scalar to divide by 8 */ XSpiPs_SetClkPrescaler(SpiInstancePtr, XSPIPS_CLK_PRESCALE_8); memset(WriteBuffer, 0x00, sizeof(WriteBuffer)); memset(ReadBuffer, 0x00, sizeof(ReadBuffer)); /* * 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 < MaxSize; Count++, UniqueValue++) { WriteBuffer[DATA_OFFSET + Count] = (u8)(UniqueValue); } /* * Assert the flash chip select */ XSpiPs_SetSlaveSelect(SpiInstancePtr, ChipSelect); /* * Read the flash ID */ Status = FlashReadID(SpiInstancePtr); if (Status != XST_SUCCESS) { xil_printf("SPI FLASH Interrupt Example Read ID Failed\r\n"); return XST_FAILURE; } /* * Erase the flash */ FlashErase(SpiInstancePtr); /* * Write the data in the write buffer to TestAddress in serial flash */ FlashWrite(SpiInstancePtr, TestAddress, MaxSize, WRITE_CMD); /* * Read the contents of the flash from TestAddress of size MAX_DATA * using Normal Read command */ FlashRead(SpiInstancePtr, TestAddress, MaxSize, READ_CMD); /* * 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; } } /* * Set the SPI device as a master with auto start and manual * chip select mode options */ XSpiPs_SetOptions(SpiInstancePtr, XSPIPS_MASTER_OPTION | \ XSPIPS_FORCE_SSELECT_OPTION); memset(WriteBuffer, 0x00, sizeof(WriteBuffer)); memset(ReadBuffer, 0x00, sizeof(ReadBuffer)); /* * 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 < MaxSize; Count++, UniqueValue++) { WriteBuffer[DATA_OFFSET + Count] = (u8)(UniqueValue); } /* * Erase the flash */ FlashErase(SpiInstancePtr); /* * Write the data in the write buffer to TestAddress in serial flash */ FlashWrite(SpiInstancePtr, TestAddress, MaxSize, WRITE_CMD); /* * Read the contents of the flash from TestAddress of size MAX_DATA * using Normal Read command */ FlashRead(SpiInstancePtr, TestAddress, MaxSize, READ_CMD); /* * 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; } } SpiPsDisableIntrSystem(IntcInstancePtr, SpiIntrId); return XST_SUCCESS; }
int main() { char buff[4]; init_platform(); int Status; XUartPs_Config *Config; int Index; u32 IntrMask = 0; int BadByteCount = 0; if (XGetPlatform_Info() == XPLAT_ZYNQ_ULTRA_MP) { #ifdef XPAR_XUARTPS_1_DEVICE_ID DeviceId = XPAR_XUARTPS_1_DEVICE_ID; #endif } /* * Initialize the UART driver so that it's ready to use * Look up the configuration in the config table, then initialize it. */ Config = XUartPs_LookupConfig(UART_DEVICE_ID); if (NULL == Config) { return XST_FAILURE; } Status = XUartPs_CfgInitialize(&uart, Config, Config->BaseAddress); if (Status != XST_SUCCESS) { return XST_FAILURE; } /* Check hardware build */ Status = XUartPs_SelfTest(&uart); if (Status != XST_SUCCESS) { return XST_FAILURE; } /* * Connect the UART to the interrupt subsystem such that interrupts * can occur. This function is application specific. */ Status = SetupInterruptSystem(&intc, &uart, UART_INT_IRQ_ID); if (Status != XST_SUCCESS) { return XST_FAILURE; } //force receive interrupt for every byte (char) XUartPs_SetFifoThreshold(&uart, 1); /* * Setup the handlers for the UART that will be called from the * interrupt context when data has been sent and received, specify * a pointer to the UART driver instance as the callback reference * so the handlers are able to access the instance data */ XUartPs_SetHandler(&uart, (XUartPs_Handler)Handler, &uart); /* * Enable the interrupt of the UART so interrupts will occur */ IntrMask = XUARTPS_IXR_TOUT | XUARTPS_IXR_PARITY | XUARTPS_IXR_FRAMING | XUARTPS_IXR_OVER | XUARTPS_IXR_TXEMPTY | XUARTPS_IXR_RXFULL | XUARTPS_IXR_RXOVR; if (uart.Platform == XPLAT_ZYNQ_ULTRA_MP) { IntrMask |= XUARTPS_IXR_RBRK; } XUartPs_SetInterruptMask(&uart, IntrMask); //XUartPs_SetOperMode(UartInstPtr, XUARTPS_OPER_MODE_LOCAL_LOOP); /* Set the UART in Normal Mode */ XUartPs_SetOperMode(&uart, XUARTPS_OPER_MODE_NORMAL); /* * Set the receiver timeout. If it is not set, and the last few bytes * of data do not trigger the over-water or full interrupt, the bytes * will not be received. By default it is disabled. * * The setting of 8 will timeout after 8 x 4 = 32 character times. * Increase the time out value if baud rate is high, decrease it if * baud rate is low. */ //XUartPs_SetRecvTimeout(&uart, 8); /* Run the UartPs Interrupt example, specify the the Device ID */ //currently sets up some of uart.Need to pull out what is needed Status = UartPsIntrExample(&intc, &uart,UART_DEVICE_ID, UART_INT_IRQ_ID); /* if (Status != XST_SUCCESS) { xil_printf("UART Interrupt Example Test Failed\r\n"); return XST_FAILURE; } */ xil_printf("Successfully ran UART Interrupt Example Test\r\n"); xil_printf("count = %i\r\n", count); return XST_SUCCESS; cleanup_platform(); return 0; }