/** * * Get the sector ID of the CompactFlash sector being used for configuration of * the target FPGA chain. This sector ID (or logical block address) only affects * transfers between the ACE configuration logic and the CompactFlash card. * This function is typically used for debug purposes to determine which sector * was being accessed when an error occurred. * * @param InstancePtr is a pointer to the XSysAce instance to be worked on. * * @return * * The sector ID (logical block address) being used for data transfers between * the ACE configuration logic and the CompactFlash. Sector IDs range from 0 * to 0x10000000. * * @note * * None. * ******************************************************************************/ u32 XSysAce_GetCfgSector(XSysAce * InstancePtr) { XASSERT_NONVOID(InstancePtr != NULL); XASSERT_NONVOID(InstancePtr->IsReady == XCOMPONENT_IS_READY); return XSysAce_RegRead32(InstancePtr->BaseAddress + XSA_CLR_OFFSET); }
/** * * Get the options for the specified timer counter. * * @param InstancePtr is a pointer to the XTmrCtr instance. * @param TmrCtrNumber is the timer counter of the device to operate on * Each device may contain multiple timer counters. The timer * number is a zero based number with a range of * 0 - (XTC_DEVICE_TIMER_COUNT - 1). * * @return * * The currently set options. An option which is set to a '1' is enabled and * set to a '0' is disabled. The options are bit masks such that multiple * options may be set or cleared. The options are described in xtmrctr.h. * * @note None. * ******************************************************************************/ u32 XTmrCtr_GetOptions(XTmrCtr * InstancePtr, u8 TmrCtrNumber) { u32 Options = 0; u32 CounterControlReg; u32 Index; XASSERT_NONVOID(InstancePtr != NULL); XASSERT_NONVOID(TmrCtrNumber < XTC_DEVICE_TIMER_COUNT); XASSERT_NONVOID(InstancePtr->IsReady == XCOMPONENT_IS_READY); /* * Read the current contents of the control status register to allow * the current options to be determined */ CounterControlReg = XTimerCtr_mReadReg(InstancePtr->BaseAddress, TmrCtrNumber, XTC_TCSR_OFFSET); /* * Loop through the Options table, turning the enable on or off * depending on whether the bit is set in the current register settings. */ for (Index = 0; Index < XTC_NUM_OPTIONS; Index++) { if (CounterControlReg & OptionsTable[Index].Mask) { Options |= OptionsTable[Index].Option; /* turn it on */ } else { Options &= ~OptionsTable[Index].Option; /* turn it off */ } } return Options; }
/** * * Get Ethernet driver/device options. The 32-bit value returned is a bit-mask * representing the options. A one (1) in the bit-mask means the option is on, * and a zero (0) means the option is off. * * @param InstancePtr is a pointer to the XEmac instance to be worked on. * * @return * * The 32-bit value of the Ethernet options. The value is a bit-mask * representing all options that are currently enabled. See xemac.h for a * description of the available options. * * @note * * None. * ******************************************************************************/ u32 XEmac_GetOptions(XEmac * InstancePtr) { u32 OptionsFlag = 0; u32 ControlReg; u32 Index; XASSERT_NONVOID(InstancePtr != NULL); XASSERT_NONVOID(InstancePtr->IsReady == XCOMPONENT_IS_READY); /* * Get the control register to determine which options are currently set. */ ControlReg = XIo_In32(InstancePtr->BaseAddress + XEM_ECR_OFFSET); /* * Loop through the options table to determine which options are set */ for (Index = 0; Index < XEM_NUM_OPTIONS; Index++) { if (ControlReg & OptionsTable[Index].Mask) { OptionsFlag |= OptionsTable[Index].Option; } } if (InstancePtr->IsPolled) { OptionsFlag |= XEM_POLLED_OPTION; } if (InstancePtr->IsSgEndDisable) { OptionsFlag |= XEM_NO_SGEND_INT_OPTION; } return OptionsFlag; }
/** * * Starts the interrupt controller by enabling the output from the controller * to the processor. Interrupts may be generated by the interrupt controller * after this function is called. * * It is necessary for the caller to connect the interrupt handler of this * component to the proper interrupt source. * * @param InstancePtr is a pointer to the XIntc instance to be worked on. * @param Mode determines if software is allowed to simulate interrupts or * real interrupts are allowed to occur. Note that these modes are * mutually exclusive. The interrupt controller hardware resets in * a mode that allows software to simulate interrupts until this * mode is exited. It cannot be reentered once it has been exited. * * One of the following values should be used for the mode. * - XIN_SIMULATION_MODE enables simulation of interrupts only * - XIN_REAL_MODE enables hardware interrupts only * * @return * - XST_SUCCESS if the device was started successfully * - XST_FAILURE if simulation mode was specified and it could not * be set because real mode has already been entered. * * @note Must be called after XIntc initialization is completed. * ******************************************************************************/ int XIntc_Start(XIntc * InstancePtr, u8 Mode) { u32 MasterEnable = XIN_INT_MASTER_ENABLE_MASK; /* * Assert the arguments */ XASSERT_NONVOID(InstancePtr != NULL); XASSERT_NONVOID((Mode == XIN_SIMULATION_MODE) || (Mode == XIN_REAL_MODE)) XASSERT_NONVOID(InstancePtr->IsReady == XCOMPONENT_IS_READY); /* * Check for simulation mode */ if (Mode == XIN_SIMULATION_MODE) { if (MasterEnable & XIN_INT_HARDWARE_ENABLE_MASK) { return XST_FAILURE; } } else { MasterEnable |= XIN_INT_HARDWARE_ENABLE_MASK; } /* * Indicate the instance is ready to be used and is started before we * enable the device. */ InstancePtr->IsStarted = XCOMPONENT_IS_STARTED; XIntc_Out32(InstancePtr->BaseAddress + XIN_MER_OFFSET, MasterEnable); return XST_SUCCESS; }
/** * * This function will attempt to receive a specified number of bytes of data * from PS/2 and store it into the specified buffer. This function is * designed for either polled or interrupt driven modes. It is non-blocking * such that it will return if no data has already received by the PS/2 port. * * In a polled mode, this function will only receive 1 byte which is as much * data as the receiver can buffer. The application may need to call it * repeatedly to receive a buffer. Polled mode is the default mode of * operation for the driver. * * In interrupt mode, this function will start receiving and then the interrupt * handler of the driver will continue receiving data until the buffer has been * received. A callback function, as specified by the application, will be called * to indicate the completion of receiving the buffer or when any receive errors * or timeouts occur. Interrupt mode must be enabled. * * @param InstancePtr is a pointer to the XPs2 instance to be worked on. * @param BufferPtr is pointer to buffer for data to be received into * @param NumBytes is the number of bytes to be received. A value of zero will * stop a previous receive operation that is in progress in interrupt mode. * * @return * * The number of bytes received. * * @note * * The number of bytes is not asserted so that this function may be called with * a value of zero to stop an operation that is already in progress. * *****************************************************************************/ unsigned int XPs2_Recv(XPs2 *InstancePtr, Xuint8 *BufferPtr, unsigned int NumBytes) { unsigned int ReceivedCount; /* * Assert validates the input arguments */ XASSERT_NONVOID(InstancePtr != XNULL); XASSERT_NONVOID(BufferPtr != XNULL); XASSERT_NONVOID(InstancePtr->IsReady == XCOMPONENT_IS_READY); /* * Setup the specified buffer to be sent by setting the instance * variables so it can be sent with polled or interrupt mode */ InstancePtr->ReceiveBuffer.RequestedBytes = NumBytes; InstancePtr->ReceiveBuffer.RemainingBytes = NumBytes; InstancePtr->ReceiveBuffer.NextBytePtr = BufferPtr; /* * Receive the data from PS/2 and return the number of bytes * received */ ReceivedCount = XPs2_ReceiveBuffer(InstancePtr); return ReceivedCount; }
/** * * Check to see if the CompactFlash is ready for a command. The CompactFlash * may delay after one operation before it is ready for the next. This function * helps the user determine when it is ready before invoking a CompactFlash * operation such as XSysAce_SectorRead() or XSysAce_SectorWrite(); * * @param InstancePtr is a pointer to the XSysAce instance to be worked on. * * @return * * TRUE if the CompactFlash is ready for a command, and FALSE otherwise. * * @note * * None. * ******************************************************************************/ u32 XSysAce_IsCFReady(XSysAce * InstancePtr) { XASSERT_NONVOID(InstancePtr != NULL); XASSERT_NONVOID(InstancePtr->IsReady == XCOMPONENT_IS_READY); return XSysAce_mIsReadyForCmd(InstancePtr->BaseAddress); }
/** * * Get the packet wait bound timer for this driver/device. The packet wait bound * is used during interrupt coalescing to trigger an interrupt when not enough * packets have been received to reach the packet count threshold. A packet is a * generic term used by the scatter-gather DMA engine, and is equivalent to an * Ethernet frame in our case. The timer is in milliseconds. * * @param InstancePtr is a pointer to the XEmac instance to be worked on. * @param Direction indicates the channel, send or receive, from which the * threshold register is read. * @param WaitPtr is a pointer to the byte into which the current value of the * packet wait bound register will be copied. An output parameter. Units * are in milliseconds in the range 0 - 1023. A value of 0 indicates the * packet wait bound timer is disabled. * * @return * * - XST_SUCCESS if the packet wait bound was retrieved successfully * - XST_NOT_SGDMA if the MAC is not configured for scatter-gather DMA * - XST_INVALID_PARAM if the Direction parameter is invalid. Turning on * asserts would also catch this error. * * @note * * None. * ******************************************************************************/ XStatus XEmac_GetPktWaitBound(XEmac * InstancePtr, u32 Direction, u32 * WaitPtr) { XASSERT_NONVOID(InstancePtr != NULL); XASSERT_NONVOID(Direction == XEM_SEND || Direction == XEM_RECV); XASSERT_NONVOID(WaitPtr != NULL); XASSERT_NONVOID(InstancePtr->IsReady == XCOMPONENT_IS_READY); if (!XEmac_mIsSgDma(InstancePtr)) { return XST_NOT_SGDMA; } /* * Based on the direction, return the packet wait bound set in the * corresponding DMA channel component. Default to the value in * the receive channel wait bound register (if an invalid Direction * is passed). */ switch (Direction) { case XEM_SEND: *WaitPtr = XDmaChannel_GetPktWaitBound(&InstancePtr->SendChannel); break; case XEM_RECV: *WaitPtr = XDmaChannel_GetPktWaitBound(&InstancePtr->RecvChannel); break; default: return XST_INVALID_PARAM; } return XST_SUCCESS; }
/** * * Runs a self-test on the device hardware. Since there is no way to perform a * loopback in the hardware, this test can only check the state of the status * register to verify it is correct. This test assumes that the hardware * device is still in its reset state, but has been initialized with the * Initialize function. * * @param InstancePtr is a pointer to the XUartLite instance. * * @return * - XST_SUCCESS if the self-test was successful. * - XST_FAILURE if the self-test failed, the status register * value was not correct * * @note None. * ******************************************************************************/ int XUartLite_SelfTest(XUartLite *InstancePtr) { u32 StatusRegister; /* * Assert validates the input arguments */ XASSERT_NONVOID(InstancePtr != NULL); XASSERT_NONVOID(InstancePtr->IsReady == XCOMPONENT_IS_READY); /* * Read the Status register value to check if it is the correct value * after a reset */ StatusRegister = XUartLite_mReadReg(InstancePtr->RegBaseAddress, XUL_STATUS_REG_OFFSET); /* * If the status register is any other value other than * XUL_SR_TX_FIFO_EMPTY then the test is a failure since this is * the not the value after reset */ if (StatusRegister != XUL_SR_TX_FIFO_EMPTY) { return XST_FAILURE; } return XST_SUCCESS; }
/** * * Reset the CompactFlash device. This function does not reset the System ACE * controller. An ATA soft-reset of the CompactFlash is performed. * * An MPU lock, obtained using XSysAce_Lock(), must be granted before calling * this function. If a lock has not been granted, no action is taken and an * error is returned. * * @param InstancePtr is a pointer to the XSysAce instance to be worked on. * * @return * * - XST_SUCCESS if the reset was done successfully * - XST_SYSACE_NO_LOCK if no MPU lock has yet been granted * - XST_DEVICE_BUSY if the CompactFlash is not ready for a command * * @note * * None. * ******************************************************************************/ int XSysAce_ResetCF(XSysAce * InstancePtr) { XASSERT_NONVOID(InstancePtr != NULL); XASSERT_NONVOID(InstancePtr->IsReady == XCOMPONENT_IS_READY); /* If a lock has not been granted, return an error */ if (!XSysAce_mIsMpuLocked(InstancePtr->BaseAddress)) { return XST_SYSACE_NO_LOCK; } /* See if the CF is ready for a command */ if (!XSysAce_mIsReadyForCmd(InstancePtr->BaseAddress)) { return XST_DEVICE_BUSY; } /* * If interrupts are enabled, enable the error interrupt. A reset clears * the error status, so we're going to re-enable the interrupt here so any * new errors will be caught. */ if (XSysAce_mIsIntrEnabled(InstancePtr->BaseAddress)) { XSysAce_mOrControlReg(InstancePtr->BaseAddress, XSA_CR_ERRORIRQ_MASK); } /* * Send the reset command */ XSysAce_RegWrite16(InstancePtr->BaseAddress + XSA_SCCR_OFFSET, XSA_SCCR_RESET_MASK); return XST_SUCCESS; }
/** * Retrieve the number of free bytes in the packet FIFOs. * * For the transmit packet FIFO, the number returned is the number of bytes * that can be written by XTemac_FifoWrite(). If a non-zero number is returned, * then at least 1 packet of that size can be transmitted. * * For the receive packet FIFO, the number returned is the number of bytes that * can arrive from an external Ethernet device. This number does not reflect * the state of the receive length FIFO. If this FIFO is full, then arriving * packets will get dropped by the HW if there is no place to store the length. * * @param InstancePtr is a pointer to the instance to be worked on. * @param Direction selects which packet FIFO to examine. If XTE_SEND, then * the transmit packet FIFO is selected. If XTE_RECV, then the receive * packet FIFO is selected. * * @return * Number of bytes available in the selected packet FIFO. * ******************************************************************************/ u32 XTemac_FifoGetFreeBytes(XTemac * InstancePtr, u32 Direction) { u32 RegIPISR; u32 Count; XASSERT_NONVOID(InstancePtr != NULL); XASSERT_NONVOID(InstancePtr->IsReady == XCOMPONENT_IS_READY); XASSERT_NONVOID(!(Direction & ~(XTE_SEND | XTE_RECV))); /* For the send direction, even though there may be room in the * packet FIFO, the length FIFO may be full. When this is the case, * another packet cannot be transmiited so return 0. */ if (Direction == XTE_SEND) { /* Check length FIFO */ RegIPISR = XTemac_mGetIpifReg(XTE_IPISR_OFFSET); if (RegIPISR & XTE_IPXR_XMIT_LFIFO_FULL_MASK) { return (0); } /* Get FIFO entries */ Count = XPF_V200A_GET_COUNT(&InstancePtr->SendFifo.Fifo); } /* Handle receive direction */ else { Count = XPF_V200A_COUNT_MASK - XPF_V200A_GET_COUNT(&InstancePtr->RecvFifo.Fifo); } /* Multiply free entries by the width of the packet FIFO to arrive at * bytes */ return (Count * InstancePtr->RecvFifo.Width); }
/** * Copy data from the receive packet FIFO into a user buffer. The number of * bytes to copy is derived from XTemac_FifoRecv(). The packet data may be * copied out of the FIFO all at once or with multiple calls to this function. * The latter method supports systems that keep packet data in non-contiguous * memory regions. For example: * <pre> * if (XTemac_FifoRecv(Tptr, &PacketLength) == XST_SUCCESS) * { * if (PacketLength > 14) * { * HeaderLength = 14; * PayloadLength = PacketLength - HeaderLength; * * Status = XTemac_FifoRead(Tptr, UserHeaderBuf, HeaderLength, * XTE_PARTIAL_PACKET); * Status |= XTemac_FifoRead(Tptr, UserPayloadBuf, PayloadLength, * XTE_END_OF_PACKET); * * if (Status != XST_SUCCESS) * { * // handle error * } * } * } * </pre> * * If the user's buffer is not aligned on a 4 byte boundary, then the transfer * may take longer to complete. * * @param InstancePtr is a pointer to the instance to be worked on. * @param BufPtr is the user buffer that will recieve packet data from the FIFO. * The buffer may be on any alignment. * @param ByteCount is the number of bytes to transfer * @param Eop specifies whether the last byte read is the last byte of a packet. * If set to XTE_END_OF_PACKET, then any partial bytes being buffered by * the driver at the end of the transfer are discarded. These discarded * bytes are filler provided by the hardware and have no meaning. If set * to XTE_PARTIAL_PACKET, then more packet data is expected to be read * through more calls to this function. Failure to use this parameter * properly will result in undefined filler bytes being copied into * BufPtr. * * @return * - XST_SUCCESS if the data was transferred to the user buffer * - XST_DEVICE_IS_STOPPED if the device has not been started. * - XST_NO_DATA if there was not enough data in the packet FIFO to satisfy the * request. * * @note * Do not attempt to read more than one packets worth of data at a time with * this function. ******************************************************************************/ XStatus XTemac_FifoRead(XTemac * InstancePtr, void *BufPtr, u32 ByteCount, int Eop) { XStatus Status; XASSERT_NONVOID(InstancePtr != NULL); XASSERT_NONVOID(InstancePtr->IsReady == XCOMPONENT_IS_READY); XASSERT_NONVOID(! ((Eop != XTE_END_OF_PACKET) && (Eop != XTE_PARTIAL_PACKET))); /* Make sure device is ready for this operation */ if (InstancePtr->IsStarted != XCOMPONENT_IS_STARTED) { return (XST_DEVICE_IS_STOPPED); } /* Transfer the data using the best/fastest method */ Status = InstancePtr->RecvFifo.XferFn(&InstancePtr->RecvFifo, BufPtr, ByteCount, Eop); /* Return correct status */ if (Status == XST_NO_DATA) { return (XST_NO_DATA); } else { return (XST_SUCCESS); } }
/** * Return the length of a received packet. If a packet is waiting in the * receive packet FIFO, then it may be copied to a user buffer with * XTemac_FifoRead(). * * @param InstancePtr is a pointer to the instance to be worked on. * @param ByteCountPtr is the length of the next received packet if the return * status is XST_SUCCESS. * * @return * - XST_SUCCESS if a packet has been received and a value has been written to * ByteCountPtr. * - XST_DEVICE_IS_STOPPED if the device has been stopped. * - XST_NO_DATA if no packet length is available. ByteCountPtr is not modified. * ******************************************************************************/ XStatus XTemac_FifoRecv(XTemac * InstancePtr, u32 * ByteCountPtr) { u32 RegIPISR; volatile u32 RegRSR; XASSERT_NONVOID(InstancePtr != NULL); XASSERT_NONVOID(InstancePtr->IsReady == XCOMPONENT_IS_READY); XASSERT_NONVOID(ByteCountPtr != NULL); /* Make sure device is ready for this operation */ if (InstancePtr->IsStarted != XCOMPONENT_IS_STARTED) { return (XST_DEVICE_IS_STOPPED); } /* If the receive length FIFO is empty, then there's no packet waiting */ RegIPISR = XTemac_mGetIpifReg(XTE_IPISR_OFFSET); if (!(RegIPISR & XTE_IPXR_RECV_DONE_MASK)) { return (XST_NO_DATA); } /* Get the length */ *ByteCountPtr = XTemac_mGetIpifReg(XTE_RPLR_OFFSET); /* The IPXR_RECV_DONE_MASK status bit is tied to the RSR register. To clear * this condition, read from the RSR (which has no information) then write * to the IPISR register to ack the status. */ RegRSR = XTemac_mGetIpifReg(XTE_RSR_OFFSET); XTemac_mSetIpifReg(XTE_IPISR_OFFSET, XTE_IPXR_RECV_DONE_MASK); /* Return sucess */ return (XST_SUCCESS); }
/** * * Abort the CompactFlash operation currently in progress. * * An MPU lock, obtained using XSysAce_Lock(), must be granted before calling * this function. If a lock has not been granted, no action is taken and an * error is returned. * * @param InstancePtr is a pointer to the XSysAce instance to be worked on. * * @return * * - XST_SUCCESS if the abort was done successfully * - XST_SYSACE_NO_LOCK if no MPU lock has yet been granted * - XST_DEVICE_BUSY if the CompactFlash is not ready for a command * * @note * * According to the ASIC designer, the abort command has not been well tested. * ******************************************************************************/ int XSysAce_AbortCF(XSysAce * InstancePtr) { XASSERT_NONVOID(InstancePtr != NULL); XASSERT_NONVOID(InstancePtr->IsReady == XCOMPONENT_IS_READY); /* If a lock has not been granted, return an error */ if (!XSysAce_mIsMpuLocked(InstancePtr->BaseAddress)) { return XST_SYSACE_NO_LOCK; } /* * See if the CF is ready for a command * * TODO: make sure this check works, or possibly the abort can be done * if it is not ready for a command (e.g., that's what we're aborting)? */ if (!XSysAce_mIsReadyForCmd(InstancePtr->BaseAddress)) { return XST_DEVICE_BUSY; } /* * Send the abort command */ XSysAce_RegWrite16(InstancePtr->BaseAddress + XSA_SCCR_OFFSET, XSA_SCCR_ABORT_MASK); return XST_SUCCESS; }
/****************************************************************************** * * FUNCTION: * * XDmaChannel_CommitPuts * * DESCRIPTION: * * This function commits the buffer descriptors which have been put into the * scatter list for the DMA channel since the last commit operation was * performed. This enables the calling functions to put several buffer * descriptors into the list (e.g.,a packet's worth) before allowing the scatter * gather operations to start. This prevents the DMA channel hardware from * starting to use the buffer descriptors in the list before they are ready * to be used (multiple buffer descriptors for a single packet). * * ARGUMENTS: * * InstancePtr contains a pointer to the DMA channel to operate on. The DMA * channel should be configured to use scatter gather in order for this function * to be called. * * RETURN VALUE: * * A status indicating XST_SUCCESS if the buffer descriptors of the list were * successfully committed. * * A value of XST_DMA_SG_NOTHING_TO_COMMIT indicates that the buffer descriptors * were not committed because there was nothing to commit in the list. All the * buffer descriptors which are in the list are commited. * * NOTES: * * None. * ******************************************************************************/ XStatus XDmaChannel_CommitPuts(XDmaChannel * InstancePtr) { /* assert to verify input arguments */ XASSERT_NONVOID(InstancePtr != NULL); XASSERT_NONVOID(InstancePtr->IsReady == XCOMPONENT_IS_READY); /* if the buffer descriptor to be committed is already committed or * the list is empty (none have been put in), then indicate an error */ if ((InstancePtr->CommitPtr == NULL) || XDmaChannel_IsSgListEmpty(InstancePtr)) { return XST_DMA_SG_NOTHING_TO_COMMIT; } /* last descriptor in the list must have scatter gather disabled so the end * of the list is hit by h/w, if descriptor to commit is not last in list, * commit descriptors by enabling scatter gather in the descriptor */ if (InstancePtr->CommitPtr != InstancePtr->LastPtr) { u32 Control; Control = XBufDescriptor_GetControl(InstancePtr->CommitPtr); XBufDescriptor_SetControl(InstancePtr->CommitPtr, Control & ~XDC_DMACR_SG_DISABLE_MASK); } /* Update the commit pointer to indicate that there is nothing to be * committed, this state is used by start processing to know that the * buffer descriptor to start is not waiting to be committed */ InstancePtr->CommitPtr = NULL; return XST_SUCCESS; }
/***************************************************************************** * * Determines if two versions are equal. * * @param InstancePtr points to the first version to be compared. * @param VersionPtr points to a second version to be compared. * * @return * * TRUE if the versions are equal, FALSE otherwise. * * @note * * None. * ******************************************************************************/ u32 XVersion_IsEqual(XVersion * InstancePtr, XVersion * VersionPtr) { u8 *Version1 = (u8 *) InstancePtr; u8 *Version2 = (u8 *) VersionPtr; int Index; /* assert to verify input arguments */ XASSERT_NONVOID(InstancePtr != NULL); XASSERT_NONVOID(VersionPtr != NULL); /* check each byte of the versions to see if they are the same, * return at any point a byte differs between them */ for (Index = 0; Index < sizeof (XVersion); Index++) { if (Version1[Index] != Version2[Index]) { return FALSE; } } /* No byte was found to be different between the versions, so indicate * the versions are equal */ return TRUE; }
/** * * Set the packet count threshold for this device. The device must be stopped * before setting the threshold. The packet count threshold is used for interrupt * coalescing, which reduces the frequency of interrupts from the device to the * processor. In this case, the scatter-gather DMA engine only interrupts when * the packet count threshold is reached, instead of interrupting for each packet. * A packet is a generic term used by the scatter-gather DMA engine, and is * equivalent to an Ethernet frame in our case. * * @param InstancePtr is a pointer to the XEmac instance to be worked on. * @param Direction indicates the channel, send or receive, from which the * threshold register is read. * @param Threshold is the value of the packet threshold count used during * interrupt coalescing. A value of 0 disables the use of packet threshold * by the hardware. * * @return * * - XST_SUCCESS if the threshold was successfully set * - XST_NOT_SGDMA if the MAC is not configured for scatter-gather DMA * - XST_DEVICE_IS_STARTED if the device has not been stopped * - XST_INVALID_PARAM if the Direction parameter is invalid. Turning on * asserts would also catch this error. * * @note * * The packet threshold could be set to larger than the number of descriptors * allocated to the DMA channel. In this case, the wait bound will take over * and always indicate data arrival. There was a check in this function that * returned an error if the treshold was larger than the number of descriptors, * but that was removed because users would then have to set the threshold * only after they set descriptor space, which is an order dependency that * caused confustion. * ******************************************************************************/ XStatus XEmac_SetPktThreshold(XEmac * InstancePtr, u32 Direction, u8 Threshold) { XASSERT_NONVOID(InstancePtr != NULL); XASSERT_NONVOID(Direction == XEM_SEND || Direction == XEM_RECV); XASSERT_NONVOID(InstancePtr->IsReady == XCOMPONENT_IS_READY); /* * Be sure device is configured for scatter-gather DMA and has been stopped */ if (!XEmac_mIsSgDma(InstancePtr)) { return XST_NOT_SGDMA; } if (InstancePtr->IsStarted == XCOMPONENT_IS_STARTED) { return XST_DEVICE_IS_STARTED; } /* * Based on the direction, set the packet threshold in the * corresponding DMA channel component. Default to the receive * channel threshold register (if an invalid Direction is passed). */ switch (Direction) { case XEM_SEND: return XDmaChannel_SetPktThreshold(&InstancePtr->SendChannel, Threshold); case XEM_RECV: return XDmaChannel_SetPktThreshold(&InstancePtr->RecvChannel, Threshold); default: return XST_INVALID_PARAM; } }
/** * Free a set of BDs that had been retrieved by XTemac_SgGetProcessed(). If BDs * are not freed, then eventually the channel will run out of BDs to * XTemac_SgAlloc(). * * This function and XTemac_SgGetProcessed() must be called in the correct * order. See xtemac.h for more information on the SGDMA use model. * * @param InstancePtr is a pointer to the instance to be worked on. * @param Direction is the channel to address (XTE_SEND or XTE_RECV). * @param BdPtr is the first BD in the set to free. This is typically the same * value returned by XTemac_SgGetProcessed(). * @param NumBd is the number of BDs to free. This is typically the same value * returned by XTemac_SgGetProcessed(). * * @return * - XST_SUCCESS if the requested number of BDs was returned. * - XST_INVALID_PARAM if Direction did not specify a valid channel. * - XST_DMA_SG_LIST_ERROR if BdPtr parameter does not reflect the correct * insertion point within the internally maintained BD ring. This error occurs * when this function and XTemac_SgGetProcessed() are called out of order. * * @note * This function is not thread-safe. The user must provide mutually exclusive * access to this function if there are to be multiple threads that can call it. * ******************************************************************************/ XStatus XTemac_SgFree(XTemac * InstancePtr, u32 Direction, unsigned NumBd, XDmaBdV2 * BdPtr) { u32 DgieReg; XDmaV2 *DmaPtr; XStatus Status; XASSERT_NONVOID(InstancePtr != NULL); XASSERT_NONVOID(InstancePtr->IsReady == XCOMPONENT_IS_READY); /* Which channel to address */ if (Direction == XTE_RECV) { DmaPtr = &InstancePtr->RecvDma; } else if (Direction == XTE_SEND) { DmaPtr = &InstancePtr->SendDma; } else { return (XST_INVALID_PARAM); } /* This is a critical section. Prevent interrupts from the device while * the BD ring is being modified. */ DgieReg = XTemac_mGetIpifReg(XTE_DGIE_OFFSET); XTemac_mSetIpifReg(XTE_DGIE_OFFSET, 0); Status = XDmaV2_SgBdFree(DmaPtr, NumBd, BdPtr); XTemac_mSetIpifReg(XTE_DGIE_OFFSET, DgieReg); return (Status); }
/** * * Add a descriptor, with an attached empty buffer, into the receive descriptor * list. The buffer attached to the descriptor must be 32-bit aligned if using * the OPB Ethernet core and 64-bit aligned if using the PLB Ethernet core. * This function is used by the upper layer software during initialization when * first setting up the receive descriptors, and also during reception of frames * to replace filled buffers with empty buffers. This function can be called * when the device is started or stopped. Note that it does start the scatter- * gather DMA engine. Although this is not necessary during initialization, it * is not a problem during initialization because the MAC receiver is not yet * started. * * The buffer attached to the descriptor must be aligned on both the front end * and the back end. * * Notification of received frames are done asynchronously through the receive * callback function. * * @param InstancePtr is a pointer to the XEmac instance to be worked on. * @param BdPtr is a pointer to the buffer descriptor that will be added to the * descriptor list. * * @return * * - XST_SUCCESS if a descriptor was successfully returned to the driver * - XST_NOT_SGDMA if the device is not in scatter-gather DMA mode * - XST_DMA_SG_LIST_FULL if the receive descriptor list is full * - XST_DMA_SG_BD_LOCKED if the DMA channel cannot insert the descriptor into * the list because a locked descriptor exists at the insert point. * - XST_DMA_SG_NOTHING_TO_COMMIT if even after inserting a descriptor into the * list, the DMA channel believes there are no new descriptors to commit. * * @internal * * A status that should never be returned from this function, although * the code is set up to handle it, is XST_DMA_SG_NO_LIST. Starting the device * requires a list to be created, and this function requires the device to be * started. * ******************************************************************************/ XStatus XEmac_SgRecv(XEmac * InstancePtr, XBufDescriptor * BdPtr) { XStatus Result; u32 BdControl; XASSERT_NONVOID(InstancePtr != NULL); XASSERT_NONVOID(BdPtr != NULL); XASSERT_NONVOID(InstancePtr->IsReady == XCOMPONENT_IS_READY); /* * Be sure the device is configured for scatter-gather DMA */ if (!XEmac_mIsSgDma(InstancePtr)) { return XST_NOT_SGDMA; } /* * Set some descriptor control word defaults (destination address increment * and local source address) and the source address (the FIFO). These are * the same for every receive descriptor. */ BdControl = XBufDescriptor_GetControl(BdPtr); XBufDescriptor_SetControl(BdPtr, BdControl | XEM_DFT_RECV_BD_MASK); XBufDescriptor_SetSrcAddress(BdPtr, InstancePtr->PhysAddress + XEM_PFIFO_RXDATA_OFFSET); /* * Put the descriptor into the channel's descriptor list and commit. * Although this function is likely called within interrupt context, there * is the possibility that the upper layer software queues it to a task. * In this case, a critical section is needed here to protect shared data * in the DMA component. */ XIIF_V123B_GINTR_DISABLE(InstancePtr->BaseAddress); Result = XDmaChannel_PutDescriptor(&InstancePtr->RecvChannel, BdPtr); if (Result != XST_SUCCESS) { XIIF_V123B_GINTR_ENABLE(InstancePtr->BaseAddress); return Result; } Result = XDmaChannel_CommitPuts(&InstancePtr->RecvChannel); if (Result != XST_SUCCESS) { XIIF_V123B_GINTR_ENABLE(InstancePtr->BaseAddress); return Result; } /* * Start the DMA channel. Ignore the return status since we know the list * exists and has at least one entry and we don't care if the channel is * already started. The DMA component accesses data here that can be * modified at interrupt or task levels, so a critical section is required. */ (void)XDmaChannel_SgStart(&InstancePtr->RecvChannel); XIIF_V123B_GINTR_ENABLE(InstancePtr->BaseAddress); return XST_SUCCESS; }
/** * * Get all outstanding errors. Errors include the inability to read or write * CompactFlash and the inability to successfully configure FPGA devices along * the target FPGA chain. * * @param InstancePtr is a pointer to the XSysAce instance to be worked on. * * @return * * A 32-bit mask of error values. See xsysace_l.h for a description of possible * values. The error identifiers are prefixed with XSA_ER_*. * * @note * * None. * ******************************************************************************/ u32 XSysAce_GetErrors(XSysAce * InstancePtr) { XASSERT_NONVOID(InstancePtr != NULL); XASSERT_NONVOID(InstancePtr->IsReady == XCOMPONENT_IS_READY); return XSysAce_mGetErrorReg(InstancePtr->BaseAddress); }
/** * Commit a set of BDs to the SGDMA engine that had been allocated by * XTemac_SgAlloc() and prepared by the user to describe SGDMA transaction(s). * * This function and XTemac_SgAlloc() must be called in the correct order. See * xtemac.h for more information on the SGDMA use model. * * Upon return, the committed BDs go under hardware control. Do not modify BDs * after they have been committed. Doing so may cause data corruption and system * instability. * * This function may be called if the TEMAC device is started or stopped. If * started (see XTemac_Start()), then the BDs may be processed by HW at any * time. * * This function is non-blocking. Notification of error or successful * transmission/reception is done asynchronously through callback functions. * * For transmit (XTE_SEND): * * It is assumed that the upper layer software supplies a correctly formatted * Ethernet frame, including the destination and source addresses, the * type/length field, and the data field. * * For receive (XTE_RECV): * * It is assumed that BDs have an appropriately sized frame buffer attached * that corresponds to the network MTU. * * @param InstancePtr is a pointer to the instance to be worked on. * @param Direction is the channel to address (XTE_SEND or XTE_RECV). * @param NumBd is the number of BDs to commit. This is typically the same * value used when the BDs were allocated with XTemac_SgAlloc(). * @param BdPtr is the first BD in the set to commit and is typically the * same value returned by XTemac_SgAlloc(). * * @return * - XST_SUCCESS if the requested number of BDs was returned. * - XST_INVALID_PARAM if Direction did not specify a valid channel. * - XST_FAILURE if the last BD in the set does not have its "last" bit * set (see XDmaBdV2_mSetLast()). * - XST_DMA_SG_LIST_ERROR if BdPtr parameter does not reflect the correct * insertion point within the internally maintained BD ring. This error occurs * when this function and XTemac_SgAlloc() are called out of order. * * @note * This function is not thread-safe. The user must provide mutually exclusive * access to this function if there are to be multiple threads that can call it. * ******************************************************************************/ XStatus XTemac_SgCommit(XTemac * InstancePtr, u32 Direction, unsigned NumBd, XDmaBdV2 * BdPtr) { XStatus Status; XDmaV2 *DmaPtr; u32 DgieReg; XASSERT_NONVOID(InstancePtr != NULL); XASSERT_NONVOID(InstancePtr->IsReady == XCOMPONENT_IS_READY); /* Which channel to address */ if (Direction == XTE_RECV) { DmaPtr = &InstancePtr->RecvDma; } else if (Direction == XTE_SEND) { DmaPtr = &InstancePtr->SendDma; } else { return (XST_INVALID_PARAM); } /* XDmaV2_SgToHw() will return either XST_SUCCESS, XST_FAILURE, or * XST_DMA_SG_LIST_ERROR * * This is a critical section, prevent interrupts from the device while * the BD ring is being modified. */ DgieReg = XTemac_mGetIpifReg(XTE_DGIE_OFFSET); XTemac_mSetIpifReg(XTE_DGIE_OFFSET, 0); Status = XDmaV2_SgBdToHw(DmaPtr, NumBd, BdPtr); XTemac_mSetIpifReg(XTE_DGIE_OFFSET, DgieReg); return (Status); }
/** * Read byte from the IO Bus memory mapped IO * * @param InstancePtr is a pointer to an XIOModule instance to be * worked on. * @param ByteOffset is a byte offset from the beginning of the * IO Bus address area * * @return Value read from the IO Bus - 8-bit byte * *****************************************************************************/ u8 XIOModule_IoReadByte(XIOModule * InstancePtr, u32 ByteOffset) { XASSERT_NONVOID(InstancePtr != NULL); XASSERT_NONVOID(InstancePtr->IsReady == XCOMPONENT_IS_READY); return XIomodule_In8((InstancePtr->IoBaseAddress + ByteOffset)); }
XStatus XDmaChannel_SelfTest(XDmaChannel * InstancePtr) { u32 ControlReg; /* assert to verify input arguments */ XASSERT_NONVOID(InstancePtr != NULL); XASSERT_NONVOID(InstancePtr->IsReady == XCOMPONENT_IS_READY); /* reset the DMA channel such that it's in a known state before the test * it resets to no interrupts enabled, the desired state for the test */ XDmaChannel_Reset(InstancePtr); /* this should be the first test to help prevent a lock up with the polling * loop that occurs later in the test, check the reset value of the DMA * control register to make sure it's correct, return with an error if not */ ControlReg = XDmaChannel_GetControl(InstancePtr); if (ControlReg != XDC_CONTROL_REG_RESET_MASK) { return XST_DMA_RESET_REGISTER_ERROR; } return XST_SUCCESS; }
/** * * This function gets the options for the SPI device. The options control how * the device behaves relative to the SPI bus. * * @param InstancePtr is a pointer to the XSpi instance to be worked on. * * @return * * Options contains the specified options to be set. This is a bit mask where a * 1 means to turn the option on, and a 0 means to turn the option off. One or * more bit values may be contained in the mask. See the bit definitions named * XSP_*_OPTIONS in the file xspi.h. * * @note None. * ******************************************************************************/ u32 XSpi_GetOptions(XSpi * InstancePtr) { u32 OptionsFlag = 0; u16 ControlReg; u32 Index; XASSERT_NONVOID(InstancePtr != NULL); XASSERT_NONVOID(InstancePtr->IsReady == XCOMPONENT_IS_READY); /* * Get the control register to determine which options are currently * set. */ ControlReg = XSpi_mGetControlReg(InstancePtr); /* * Loop through the options table to determine which options are set */ for (Index = 0; Index < XSP_NUM_OPTIONS; Index++) { if (ControlReg & OptionsTable[Index].Mask) { OptionsFlag |= OptionsTable[Index].Option; } } return OptionsFlag; }
/** * Initiate a transmit of one packet of data previously written with * XTemac_FifoWrite(). The given length in bytes is written to the transmit * length FIFO. There should be at least this many bytes in the packet FIFO * ready for transmit. * * If FIFO interrupts are enabled (see XTemac_IntrFifoEnable()), then upon * completion of the transmit, the registered XTemac_FifoSendHandler() is * invoked. * * If more bytes that are in the packet FIFO are specified in the TxByteCount * parameter, then a packet FIFO underrun error will result. * * @param InstancePtr is a pointer to the instance to be worked on. * @param TxByteCount is the number of bytes to transmit. Range is 1 to the * total number of bytes available in the packet FIFO to be transmitted. * * @return * - XST_SUCCESS if transmit was initiated. * - XST_DEVICE_IS_STOPPED if the device has not been started. * - XST_FIFO_NO_ROOM if the transmit was not initiated because the transmit * length FIFO was full. This is not a fatal condition. The user may need to * wait for other packets to transmit before this condition clears itself. * ******************************************************************************/ XStatus XTemac_FifoSend(XTemac * InstancePtr, u32 TxByteCount) { u32 RegIPISR; XASSERT_NONVOID(InstancePtr != NULL); XASSERT_NONVOID(InstancePtr->IsReady == XCOMPONENT_IS_READY); XASSERT_NONVOID(TxByteCount != 0); /* Make sure device is ready for this operation */ if (InstancePtr->IsStarted != XCOMPONENT_IS_STARTED) { return (XST_DEVICE_IS_STOPPED); } /* See if transmit length FIFO is full. If it is, try to clear the * status. If it the status remains, then return an error */ RegIPISR = XTemac_mGetIpifReg(XTE_IPISR_OFFSET); if (RegIPISR & XTE_IPXR_XMIT_LFIFO_FULL_MASK) { XTemac_mSetIpifReg(XTE_IPISR_OFFSET, XTE_IPXR_XMIT_LFIFO_FULL_MASK); RegIPISR = XTemac_mGetIpifReg(XTE_IPISR_OFFSET); if (RegIPISR & XTE_IPXR_XMIT_LFIFO_FULL_MASK) { XTemac_mBumpStats(FifoErrors, 1); return (XST_FIFO_NO_ROOM); } } /* Start transmit */ XTemac_mSetIpifReg(XTE_TPLR_OFFSET, TxByteCount); /* Return sucess */ return (XST_SUCCESS); }
/** * * Get the status of the FAT filesystem on the first valid partition of the * CompactFlash device such as the boot record and FAT types found. * * @param InstancePtr is a pointer to the XSysAce instance to be worked on. * * @return * * A 16-bit mask of status values. These values are defined in xsysace_l.h * with the prefix XSA_FAT_*. * * @note * * None. * ******************************************************************************/ u16 XSysAce_GetFatStatus(XSysAce * InstancePtr) { XASSERT_NONVOID(InstancePtr != NULL); XASSERT_NONVOID(InstancePtr->IsReady == XCOMPONENT_IS_READY); return XSysAce_RegRead16(InstancePtr->BaseAddress + XSA_FSR_OFFSET); }
/** * * Write data to the specified PHY register. The Ethernet driver does not * require the device to be stopped before writing to the PHY. Although it is * probably a good idea to stop the device, it is the responsibility of the * application to deem this necessary. The MAC provides the driver with the * ability to talk to a PHY that adheres to the Media Independent Interface * (MII) as defined in the IEEE 802.3 standard. * * @param InstancePtr is a pointer to the XEmac instance to be worked on. * @param PhyAddress is the address of the PHY to be written (supports multiple * PHYs) * @param RegisterNum is the register number, 0-31, of the specific PHY register * to write * @param PhyData is the 16-bit value that will be written to the register * * @return * * - XST_SUCCESS if the PHY was written to successfully. Since there is no error * status from the MAC on a write, the user should read the PHY to verify the * write was successful. * - XST_NO_FEATURE if the device is not configured with MII support * - XST_EMAC_MII_BUSY if there is another PHY operation in progress * * @note * * This function is not thread-safe. The user must provide mutually exclusive * access to this function if there are to be multiple threads that can call it. * <br><br> * There is the possibility that this function will not return if the hardware * is broken (i.e., it never sets the status bit indicating that the write is * done). If this is of concern to the user, the user should provide protection * from this problem - perhaps by using a different timer thread to monitor the * PhyWrite thread. * ******************************************************************************/ XStatus XEmac_PhyWrite(XEmac * InstancePtr, u32 PhyAddress, u32 RegisterNum, u16 PhyData) { u32 MiiControl; XASSERT_NONVOID(InstancePtr != NULL); XASSERT_NONVOID(PhyAddress < XEM_MAX_PHY_ADDR); XASSERT_NONVOID(RegisterNum < XEM_MAX_PHY_REG); XASSERT_NONVOID(InstancePtr->IsReady == XCOMPONENT_IS_READY); /* * Make sure the device has the management interface */ if (!InstancePtr->HasMii) { return XST_NO_FEATURE; } /* * Verify that there is no operation in progress already */ MiiControl = XIo_In32(InstancePtr->BaseAddress + XEM_MGTCR_OFFSET); if (MiiControl & XEM_MGTCR_START_MASK) { /* operation in progress */ return XST_EMAC_MII_BUSY; } /* * Set up the MII data register first. Write the 16-bit input * value to the 32-bit data register. */ XIo_Out32(InstancePtr->BaseAddress + XEM_MGTDR_OFFSET, (u32) PhyData); /* * Now set up the MII control register. We set up a control * word with the PHY address and register number, then indicate * the direction (write), then start the operation. */ MiiControl = PhyAddress << XEM_MGTCR_PHY_ADDR_SHIFT; MiiControl |= (RegisterNum << XEM_MGTCR_REG_ADDR_SHIFT); MiiControl |= (XEM_MGTCR_START_MASK | XEM_MGTCR_MII_ENABLE_MASK); XIo_Out32(InstancePtr->BaseAddress + XEM_MGTCR_OFFSET, MiiControl); /* * Wait for the operation to complete */ do { MiiControl = XIo_In32(InstancePtr->BaseAddress + XEM_MGTCR_OFFSET); } while (MiiControl & XEM_MGTCR_START_MASK); /* * There is no status indicating whether the operation was * successful or not. */ return XST_SUCCESS; }
/****************************************************************************** * * FUNCTION: * * XDmaChannel_SgStop * * DESCRIPTION: * * This function stops a scatter gather operation for a scatter gather * DMA channel. This function starts the process of stopping a scatter * gather operation that is in progress and waits for the stop to be completed. * Since it waits for the operation to stopped before returning, this function * could take an amount of time relative to the size of the DMA scatter gather * operation which is in progress. The scatter gather list of the DMA channel * is not modified by this function such that starting the scatter gather * channel after stopping it will cause it to resume. This operation is * considered to be a graceful stop in that the scatter gather operation * completes the current buffer descriptor before stopping. * * If the interrupt is enabled, an interrupt will be generated when the * operation is stopped and the caller is responsible for handling the * interrupt. * * ARGUMENTS: * * InstancePtr contains a pointer to the DMA channel to operate on. The DMA * channel should be configured to use scatter gather in order for this function * to be called. * * BufDescriptorPtr is also a return value which contains a pointer to the * buffer descriptor which the scatter gather operation completed when it * was stopped. * * RETURN VALUE: * * A status containing XST_SUCCESS if scatter gather was stopped successfully * for the DMA channel. * * A value of XST_DMA_SG_IS_STOPPED indicates scatter gather was not stoppped * because the scatter gather is not started, but was already stopped. * * BufDescriptorPtr contains a pointer to the buffer descriptor which was * completed when the operation was stopped. * * NOTES: * * This function implements a loop which polls the hardware for an infinite * amount of time. If the hardware is not operating correctly, this function * may never return. * ******************************************************************************/ XStatus XDmaChannel_SgStop(XDmaChannel * InstancePtr, XBufDescriptor ** BufDescriptorPtr) { u32 Register; /* assert to verify input arguments */ XASSERT_NONVOID(InstancePtr != NULL); XASSERT_NONVOID(BufDescriptorPtr != NULL); XASSERT_NONVOID(InstancePtr->IsReady == XCOMPONENT_IS_READY); /* get the contents of the software control register, if scatter gather is not * enabled (started), then return a status because the disable acknowledge * would not be generated */ Register = XIo_In32(InstancePtr->RegBaseAddress + XDC_SWCR_REG_OFFSET); if ((Register & XDC_SWCR_SG_ENABLE_MASK) == 0) { return XST_DMA_SG_IS_STOPPED; } /* Ensure the interrupt status for the scatter gather is cleared such * that this function will wait til the disable has occurred, writing * a 1 to only that bit in the register will clear only it */ XIo_Out32(InstancePtr->RegBaseAddress + XDC_IS_REG_OFFSET, XDC_IXR_SG_DISABLE_ACK_MASK); /* disable scatter gather by writing to the software control register * without modifying any other bits of the register */ XIo_Out32(InstancePtr->RegBaseAddress + XDC_SWCR_REG_OFFSET, Register & ~XDC_SWCR_SG_ENABLE_MASK); /* scatter gather does not disable immediately, but after the current * buffer descriptor is complete, so wait for the DMA channel to indicate * the disable is complete */ do { Register = XIo_In32(InstancePtr->RegBaseAddress + XDC_IS_REG_OFFSET); } while ((Register & XDC_IXR_SG_DISABLE_ACK_MASK) == 0); /* Ensure the interrupt status for the scatter gather disable is cleared, * writing a 1 to only that bit in the register will clear only it */ XIo_Out32(InstancePtr->RegBaseAddress + XDC_IS_REG_OFFSET, XDC_IXR_SG_DISABLE_ACK_MASK); /* set the specified buffer descriptor pointer to point to the buffer * descriptor that the scatter gather DMA channel was processing */ *BufDescriptorPtr = (XBufDescriptor *) XIo_In32(InstancePtr->RegBaseAddress + XDC_BDA_REG_OFFSET); return XST_SUCCESS; }
/** * * Set Ethernet driver/device options. The device must be stopped before * calling this function. The options are contained within a bit-mask with each * bit representing an option (i.e., you can OR the options together). A one (1) * in the bit-mask turns an option on, and a zero (0) turns the option off. * * @param InstancePtr is a pointer to the XEmac instance to be worked on. * @param OptionsFlag is a bit-mask representing the Ethernet options to turn on * or off. See xemac.h for a description of the available options. * * @return * * - XST_SUCCESS if the options were set successfully * - XST_DEVICE_IS_STARTED if the device has not yet been stopped * * @note * * This function is not thread-safe and makes use of internal resources that are * shared between the Start, Stop, and SetOptions functions, so if one task * might be setting device options while another is trying to start the device, * protection of this shared data (typically using a semaphore) is required. * ******************************************************************************/ int XEmac_SetOptions(XEmac * InstancePtr, u32 OptionsFlag) { u32 ControlReg; u32 Index; XASSERT_NONVOID(InstancePtr != NULL); XASSERT_NONVOID(InstancePtr->IsReady == XCOMPONENT_IS_READY); if (InstancePtr->IsStarted == XCOMPONENT_IS_STARTED) { return XST_DEVICE_IS_STARTED; } ControlReg = XIo_In32(InstancePtr->BaseAddress + XEM_ECR_OFFSET); /* * Loop through the options table, turning the option on or off * depending on whether the bit is set in the incoming options flag. */ for (Index = 0; Index < XEM_NUM_OPTIONS; Index++) { if (OptionsFlag & OptionsTable[Index].Option) { ControlReg |= OptionsTable[Index].Mask; /* turn it on */ } else { ControlReg &= ~OptionsTable[Index].Mask; /* turn it off */ } } /* * TODO: need to validate addr-overwrite only if addr-insert? */ /* * Now write the control register. Leave it to the upper layers * to restart the device. */ XIo_Out32(InstancePtr->BaseAddress + XEM_ECR_OFFSET, ControlReg); /* * Check the polled option */ if (OptionsFlag & XEM_POLLED_OPTION) { InstancePtr->IsPolled = TRUE; } else { InstancePtr->IsPolled = FALSE; } /* * Check the No SGEND option */ if (OptionsFlag & XEM_NO_SGEND_INT_OPTION) { InstancePtr->IsSgEndDisable = TRUE; } else { InstancePtr->IsSgEndDisable = FALSE; } return XST_SUCCESS; }
/** * Read state of discretes for the specified GPI channnel. * * @param InstancePtr is a pointer to an XIOModule instance to be * worked on. * @param Channel contains the channel of the GPI (1, 2, 3 or 4) to * operate on. * * @return Current copy of the discretes register. * *****************************************************************************/ u32 XIOModule_DiscreteRead(XIOModule * InstancePtr, unsigned Channel) { XASSERT_NONVOID(InstancePtr != NULL); XASSERT_NONVOID(InstancePtr->IsReady == XCOMPONENT_IS_READY); XASSERT_VOID((Channel >= 1) && (Channel <= XGPI_DEVICE_COUNT)); return XIOModule_ReadReg(InstancePtr->BaseAddress, ((Channel - 1) * XGPI_CHAN_OFFSET) + XGPI_DATA_OFFSET); }
/** * * Makes the connection between the Id of the interrupt source and the * associated handler that is to run when the interrupt is recognized. * * @param InstancePtr is a pointer to the XIOModule instance. * @param Id contains the ID of the interrupt source and should be in the * range of 0 to XPAR_INTC_MAX_NUM_INTR_INPUTS - 1 with 0 being the * highest priority interrupt. * @param Handler to the handler for that interrupt. * * @return * - XST_SUCCESS if the handler was connected correctly. * * @note Only used with fast interrupt mode. * * WARNING: The handler provided as an argument will overwrite any handler * that was previously connected. * ****************************************************************************/ int XIOModule_ConnectFastHandler(XIOModule *InstancePtr, u8 Id, XFastInterruptHandler Handler) { u32 CurrentIER, NewIMR; u32 Mask; /* * Assert the arguments */ XASSERT_NONVOID(InstancePtr != NULL); XASSERT_NONVOID(Id < XPAR_IOMODULE_INTC_MAX_INTR_SIZE); XASSERT_NONVOID(Handler != NULL); XASSERT_NONVOID(InstancePtr->IsReady == XIL_COMPONENT_IS_READY); XASSERT_NONVOID(InstancePtr->CfgPtr->FastIntr == TRUE); /* * The Id is used to create the appropriate mask for the * desired bit position. Id currently limited to 0 - 31 */ Mask = XIOModule_BitPosMask[Id]; /* * Get the Enabled Interrupts and disable the Interrupt if it was * enabled before calling this function */ CurrentIER = InstancePtr->CurrentIER; if (CurrentIER & Mask) { XIomodule_Out32(InstancePtr->BaseAddress + XIN_IER_OFFSET, CurrentIER & ~Mask); } /* * Assign the handler information and set the hardware vector */ InstancePtr->CfgPtr->HandlerTable[Id].Handler = NULL; InstancePtr->CfgPtr->HandlerTable[Id].CallBackRef = InstancePtr; XIomodule_Out32(InstancePtr->BaseAddress + XIN_IVAR_OFFSET + (Id * 4), (u32) Handler); /* * Set the selected interrupt source to use fast interrupt */ NewIMR = InstancePtr->CurrentIMR | Mask; XIomodule_Out32(InstancePtr->BaseAddress + XIN_IMR_OFFSET, NewIMR); InstancePtr->CurrentIMR = NewIMR; /* * Enable Interrupt if it was enabled before calling this function */ if (CurrentIER & Mask) { XIomodule_Out32(InstancePtr->BaseAddress + XIN_IER_OFFSET, CurrentIER); } return XST_SUCCESS; }